BLAPI_PROTO bl_ctime(lua_State *L) { syncnow(); lua_pushstring(L, ctime4(&now)); return 1; }
void mailUser(char *userid) { int count; FILE *fp, *fp2; time4_t t; fileheader_t header; struct stat st; char filename[512]; fp2 = fopen(mailfile, "r"); if (fp2 == NULL) { fprintf(stderr, "Cannot open file %s\n", mailfile); return; } sprintf(filename, BBSHOME "/home/%c/%s", userid[0], userid); if (stat(filename, &st) == -1) { if (Mkdir(filename) == -1) { fprintf(stderr, "mail box create error %s \n", filename); fclose(fp2); return; } } else if (!(st.st_mode & S_IFDIR)) { fprintf(stderr, "mail box error\n"); fclose(fp2); return; } stampfile(filename, &header); fp = fopen(filename, "w"); if (fp == NULL) { fprintf(stderr, "Cannot open file %s\n", filename); fclose(fp2); return; } t = time(NULL); fprintf(fp, "作者: 小天使系統\n" "標題: 給小天使的一封信\n" "時間: %s\n", ctime4(&t)); while ((count = fread(filename, 1, sizeof(filename), fp2))) { fwrite(filename, 1, count, fp); } fclose(fp); fclose(fp2); strcpy(header.title, "給小天使的一封信"); strcpy(header.owner, "小天使系統"); sprintf(filename, BBSHOME "/home/%c/%s/.DIR", userid[0], userid); append_record(filename, &header, sizeof(header)); mailalertuser(userid); printf("%s\n", userid); }
int main(){ int orig_fd, new_fd; userec_t u; int count = 0; orig_fd = open(BBSHOME "/.AngelTrans", O_WRONLY | O_CREAT | O_EXCL, 0644); if (orig_fd == -1) { if (errno == EEXIST) { char c; printf("It seems your .PASSWD file has been transfered, " "do it any way?[y/N] "); fflush(stdout); scanf("%c", &c); if (c != 'y' && c != 'Y') return 0; } else { perror("opening " BBSHOME "/.AngelTrans for marking"); return 0; } } else { time4_t t = (time4_t)time(NULL); char* str = ctime4(&t); write(orig_fd, str, strlen(str)); } orig_fd = open(BBSHOME "/.PASSWDS", O_RDONLY); if( orig_fd < 0 ){ perror("opening " BBSHOME "/.PASSWDS for reading"); return 1; } printf("Reading from " BBSHOME "/.PASSWDS\n"); new_fd = open(BBSHOME "/.PASSWDS.NEW", O_WRONLY | O_CREAT | O_TRUNC, 0644); if( new_fd < 0 ){ perror("opening " BBSHOME "/.PASSWDS.NEW for writing"); return 1; } printf("Writing to " BBSHOME "/.PASSWDS.NEW\n"); while(read(orig_fd, &u, sizeof(userec_t)) == sizeof(userec_t)){ // clear 0x400, 0x800, and 0x3000 u.uflag2 &= ~(0x400 | 0x800 | 0x3000); if( u.userlevel & OLD_PERM_NOOUTMAIL ) u.uflag2 |= REJ_OUTTAMAIL; u.userlevel &= ~000001000000; bzero(u.myangel, IDLEN + 1); write(new_fd, &u, sizeof(userec_t)); ++count; } close(orig_fd); close(new_fd); printf("Done, totally %d accounts translated\n", count); printf("Moving files....\n"); system("mv -i " BBSHOME "/.PASSWDS " BBSHOME "/.PASSWDS.old"); system("mv -i " BBSHOME "/.PASSWDS.NEW " BBSHOME "/.PASSWDS"); printf("Done, old password file is now at " BBSHOME "/.PASSWDS.old\n"); return 0; }
int utmpfix(int argc, char **argv) { int i, fast = 0, nownum = SHM->UTMPnumber; int which, nactive = 0, dofork = 1, daemonsleep = 0; time_t now; const char *clean; char buf[1024]; IDLE_t idle[USHM_SIZE]; char changeflag = 0; time_t idletimeout = IDLE_TIMEOUT; int lowerbound = 100, upperbound = 0; char ch; int killtop = 0; struct { pid_t pid; int where; } killlist[USHM_SIZE]; while( (ch = getopt(argc, argv, "nt:l:FD:u:")) != -1 ) switch( ch ){ case 'n': fast = 1; break; case 't': idletimeout = atoi(optarg); break; case 'l': lowerbound = atoi(optarg); break; case 'F': dofork = 0; break; case 'D': daemonsleep = atoi(optarg); break; case 'u': upperbound = atoi(optarg); break; default: printf("usage:\tshmctl\tutmpfix [-n] [-t timeout] [-F] [-D sleep]\n"); return 1; } if( daemonsleep ) switch( fork() ){ case -1: perror("fork()"); return 0; case 0: break; default: return 0; } if( daemonsleep || dofork ){ int times = 1000, status; pid_t pid; while( daemonsleep ? 1 : times-- ) switch( pid = fork() ){ case -1: sleep(1); break; case 0: #ifndef VALGRIND setproctitle("utmpfix"); #endif goto DoUtmpfix; default: #ifndef VALGRIND setproctitle(daemonsleep ? "utmpfixd(wait for %d)" : "utmpfix(wait for %d)", (int)pid); #endif waitpid(pid, &status, 0); if( WIFEXITED(status) && !daemonsleep ) return 0; if( !WIFEXITED(status) ){ /* last utmpfix fails, so SHM->UTMPbusystate is holded */ SHM->UTMPbusystate = 0; } } return 0; // never reach } DoUtmpfix: killtop=0; changeflag=0; for( i = 0 ; i < 5 ; ++i ) if( !SHM->UTMPbusystate ) break; else{ puts("utmpshm is busy...."); sleep(1); } SHM->UTMPbusystate = 1; printf("starting scaning... %s \n", (fast ? "(fast mode)" : "")); nownum = SHM->UTMPnumber; now = time(NULL); for( i = 0, nactive = 0 ; i < USHM_SIZE ; ++i ) if( SHM->uinfo[i].pid ){ idle[nactive].index = i; idle[nactive].idle = now - SHM->uinfo[i].lastact; ++nactive; } if( !fast ) qsort(idle, nactive, sizeof(IDLE_t), sfIDLE); #define addkilllist(a) \ do { \ pid_t pid=SHM->uinfo[(a)].pid; \ if(pid > 0) { \ killlist[killtop].where = (a); \ killlist[killtop++].pid = pid; \ } \ } while( 0 ) for( i = 0 ; i < nactive ; ++i ){ which = idle[i].index; clean = NULL; if( !isalpha(SHM->uinfo[which].userid[0]) ){ clean = "userid error"; addkilllist(which); } else if( memchr(SHM->uinfo[which].userid, '\0', IDLEN + 1) == NULL ){ clean = "userid without z"; addkilllist(which); } else if( SHM->uinfo[which].friendtotal > MAX_FRIEND || SHM->uinfo[which].friendtotal<0 ){ clean = "too many/less friend"; addkilllist(which); } else if( searchuser(SHM->uinfo[which].userid, NULL) == 0 ){ clean = "user not exist"; addkilllist(which); } else if( kill(SHM->uinfo[which].pid, 0) < 0 ){ /* 此條件應放最後; 其他欄位沒問題但 process 不存在才 purge_utmp */ clean = "process error"; purge_utmp(&SHM->uinfo[which]); } #ifdef DOTIMEOUT else if( (strcasecmp(SHM->uinfo[which].userid, STR_GUEST)==0 && idle[i].idle > 60*15) || (!fast && nownum > lowerbound && idle[i].idle > idletimeout ) ) { sprintf(buf, "timeout(%s", ctime4(&SHM->uinfo[which].lastact)); buf[strlen(buf) - 1] = 0; strcat(buf, ")"); clean = buf; addkilllist(which); purge_utmp(&SHM->uinfo[which]); printf("%s\n", buf); --nownum; continue; } #endif if( clean ){ printf("clean %06d(%s), userid: %s\n", i, clean, SHM->uinfo[which].userid); memset(&SHM->uinfo[which], 0, sizeof(userinfo_t)); --nownum; changeflag = 1; } } for( i = 0 ; i < killtop ; ++i ){ printf("sending SIGHUP to %d\n", (int)killlist[i].pid); kill(killlist[i].pid, SIGHUP); } sleep(3); for( i = 0 ; i < killtop ; ++i ) // FIXME 前面已經 memset 把 SHM->uinfo[which] 清掉了, 此處檢查 pid 無用 if( SHM->uinfo[killlist[i].where].pid == killlist[i].pid && kill(killlist[i].pid, 0) == 0 ){ // still alive printf("sending SIGKILL to %d\n", (int)killlist[i].pid); kill(killlist[i].pid, SIGKILL); purge_utmp(&SHM->uinfo[killlist[i].where]); } SHM->UTMPbusystate = 0; if( changeflag ) SHM->UTMPneedsort = 1; if( daemonsleep ){ do{ sleep(daemonsleep); } while( upperbound && SHM->UTMPnumber < upperbound ); goto DoUtmpfix; /* XXX: goto */ } return 0; }
char *CTIMEx(char *buf, time4_t t) { strcpy(buf, ctime4(&t)); buf[strlen(buf) - 1] = 0; return buf; }