int main(int argc, char *argv[]) { chdir(BBSHOME); setuid(BBSUID); setgid(BBSGID); setreuid(BBSUID, BBSUID); setregid(BBSGID, BBSGID); #ifndef CYGWIN #undef time bbssettime(time(0)); sleep(1); #define time(x) bbstime(x) #endif setpublicshmreadonly(0); #ifndef CYGWIN setpublicshmreadonly(1); #endif init_bbslog(); if (argc > 1) { if (strcasecmp(argv[1], "killuser") == 0) { //Added by Marvel resolve_utmp(); if (resolve_ucache() != 0) return -1; return dokilluser(); } if (strcasecmp(argv[1], "giveup") == 0) { if (resolve_ucache() != 0) return -1; return doupdategiveupuser(); } if (strcasecmp(argv[1], "allboards") == 0) return dokillalldir(); if (strcasecmp(argv[1], "daemon") == 0) return miscd_dodaemon(argv[1], argv[2]); if (strcasecmp(argv[1], "killdir") == 0) return dokilldir(argv[2]); if (strcasecmp(argv[1], "flush") == 0) { if (resolve_ucache() != 0) return -1; resolve_boards(); flushdata(); return 0; } return miscd_dodaemon(NULL, argv[1]); } printf("Usage : %s daemon: to run as a daemon (this is the most common use)\n", argv[0]); printf(" %s killuser: to kill old users\n", argv[0]); printf(" %s giveup: to unlock given-up users\n", argv[0]); printf(" %s killdir <BOARDNAME>: to delete old file in <BOARDNAME>\n", argv[0]); printf(" %s allboards: to delete old files in all boards\n", argv[0]); printf(" %s flush: to synchronize .PASSWDS and .BOARDS to disk\n", argv[0]); printf("That's all, folks. See doc/README.SYSOP for more details\n"); return 0; }
/* * 记录分区十大到文件 */ void writesechot(int secid) { FILE *fp; char curfile[256], buf[256]; char *p; int i; #ifdef READ_SEC_TOP struct top_header curr_sectop[10]; memset(curr_sectop,0,(10*sizeof(struct top_header))); #endif /* READ_SEC_TOP */ sprintf(curfile, "etc/posts/day_sec_%s", seccode[secid]); if ((fp = fopen(curfile, "w")) != NULL) { fprintf(fp, " \033[34m-----\033[37m=====\033[41m 本日%s区十大热门话题 \033[m=====\033[34m-----\033[m\n\n", seccode[secid]); for (i = 0; i < sectopnum[secid]; i++) { strcpy(buf, ctime(§op[secid][i].date)); buf[20] = NULL; p = buf + 4; fprintf(fp,"\033[37m第\033[31m%3d\033[37m 名 \033[37m信区 : \033[33m%-16s\033[37m【\033[32m%s\033[37m】" "\033[36m%4d \033[37m人\033[35m%16s\n \033[37m标题 : \033[44m\033[37m%-60.60s\033[m\n", (i+1),sectop[secid][i].board,p,sectop[secid][i].number, sectop[secid][i].userid,sectop[secid][i].title); #ifdef READ_SEC_TOP if (i<10) { curr_sectop[i].bid=getbid(sectop[secid][i].board,NULL); curr_sectop[i].gid=sectop[secid][i].groupid; } #endif /* READ_SEC_TOP */ } #ifdef READ_SEC_TOP /* 分区十大信息写入共享内存 */ if (1) { const struct boardheader *bh; char path[PATHLEN]; int k; for (k=0;k<10;k++) { if (!(bh=getboard(publicshm->sectop[secid][k].bid))) continue; snprintf(path,PATHLEN,"boards/%s/.TOP.%u",bh->filename,publicshm->sectop[secid][k].gid); unlink(path); } setpublicshmreadonly(0); memcpy(publicshm->sectop[secid],curr_sectop,(10*sizeof(struct top_header))); setpublicshmreadonly(1); } #endif /* READ_SEC_TOP */ fclose(fp); } }
void timed() { #ifndef CYGWIN setpublicshmreadonly(0); #endif while (1) { #undef time bbssettime(time(0)); sleep(1); #define time(x) bbstime(x) } }
void timed() { char line[20]; const char *path = "var/timed.pid"; int pidfd = open(path, O_RDWR | O_CREAT, 0660); if (write_lock(pidfd, 0, SEEK_SET, 0) < 0) { bbslog("3error", "timed had already been started!"); exit(-1); } snprintf(line, sizeof(line), "%ld\n", (long)getpid()); ftruncate(pidfd, 0); write(pidfd, line, strlen(line)); #ifndef CYGWIN setpublicshmreadonly(0); #endif while (1) { #undef time bbssettime(time(0)); sleep(1); #define time(x) bbstime(x) } }
int main(void){ char path[256]; struct stat st; time_t now; struct tm t; now = time(0); localtime_r( &now, &t); chdir(BBSHOME); if( stat( BONLINE_LOGDIR, &st) < 0 ){ if(mkdir(BONLINE_LOGDIR, 0755) < 0) exit(0); } sprintf(path, "%s/%d", BONLINE_LOGDIR, t.tm_year+1900); if( stat(path, &st) < 0){ if(mkdir(path, 0755) < 0) exit(0); } sprintf(path, "%s/%d/%d", BONLINE_LOGDIR, t.tm_year+1900, t.tm_mon+1); if( stat(path, &st) < 0){ if(mkdir(path, 0755) < 0) exit(0); } sprintf(path,"%s/%d/%d/%d_useronline",BONLINE_LOGDIR,t.tm_year+1900,t.tm_mon+1,t.tm_mday); if((fp=fopen(path, "a"))==NULL){ printf("cannot open log file\n"); exit(0); } sprintf(path, "%s/%d/%d/%d_login", BONLINE_LOGDIR, t.tm_year+1900, t.tm_mon+1, t.tm_mday); if((fp_login=fopen(path, "a"))==NULL){ printf("cannot open log file\n"); exit(0); } sprintf(path, "%s/lastcount", BONLINE_LOGDIR); if((fp_forcount=fopen(path, "w+"))==NULL){ printf("cannot open log file\n"); exit(0); } resolve_utmp(); get_publicshm(); resolve_guest_table(); wwwguestonline = getwwwguestcount(); totalonline = get_utmp_number() + wwwguestonline; apply_ulist_addr((APPLY_UTMP_FUNC)do_userlist, NULL); show_wwwguest(); logincount = get_publicshm()->logincount; logoutcount = get_publicshm()->logoutcount; wwwlogincount = get_publicshm()->wwwlogincount; wwwlogoutcount = get_publicshm()->wwwlogoutcount; wwwguestlogincount = get_publicshm()->wwwguestlogincount; wwwguestlogoutcount = get_publicshm()->wwwguestlogoutcount; staytime = get_publicshm()->staytime; wwwstaytime = get_publicshm()->wwwstaytime; wwwgueststaytime = get_publicshm()->wwwgueststaytime; setpublicshmreadonly(0); get_publicshm()->logincount=0; get_publicshm()->logoutcount=0; get_publicshm()->wwwlogincount=0; get_publicshm()->wwwlogoutcount=0; get_publicshm()->wwwguestlogincount=0; get_publicshm()->wwwguestlogoutcount=0; get_publicshm()->staytime=0; get_publicshm()->wwwstaytime=0; get_publicshm()->wwwgueststaytime=0; setpublicshmreadonly(1); /*格式: 时间 totalonline wwwguestonline wwwnotguestonline telnetonline wwwguestschool wwwnotguestschool telnetschool */ fprintf(fp, "%d.%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n", t.tm_hour, t.tm_min/6, totalonline, wwwguestonline, wwwnotguestonline, telnetonline, wwwguestschool, wwwnotguestschool, telnetschool); fprintf(fp_login, "%d.%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n", t.tm_hour, t.tm_min/6, logincount, logoutcount, (int)(logoutcount?(staytime/logoutcount)/10:0), wwwlogincount, wwwlogoutcount, wwwguestlogincount, wwwguestlogoutcount, (int)(wwwlogoutcount?(wwwstaytime/wwwlogoutcount)/10:0) , (int)(wwwguestlogoutcount?(wwwgueststaytime/wwwguestlogoutcount)/10:0)); fprintf(fp_forcount, "%d\n%d\n%d\n%d\n%d\n%d\n%d\n", totalonline, wwwguestonline, wwwnotguestonline, telnetonline, wwwguestschool, wwwnotguestschool, telnetschool); fclose(fp); fclose(fp_login); fclose(fp_forcount); return 0; }
void clear_utmp2(int uent) { int hashkey, find; struct user_info zeroinfo; struct userec* user; if (!uent) { bbslog("3system", "UTMP:clear uent == 0 entry"); #if 0 if (!CHECK_UENT(uinfo.uid)) return; uent = getSession()->utmpent; #endif return; } if (!utmpshm->uinfo[uent - 1].active) { //atppp 20051217 bbslog("3system", "UTMP:clear inactive entry [%d]", uent); // return; } user=getuserbynum(utmpshm->uinfo[uent-1].uid); do_after_logout(user,get_utmpent(uent),uent,0,true); do_after_logout(user,get_utmpent(uent),uent,0,false); hashkey = utmp_hash(utmpshm->uinfo[uent - 1].userid); find = utmphead->hashhead[hashkey]; if (find == uent) utmphead->hashhead[hashkey] = utmphead->next[uent - 1]; else { while (utmphead->next[find - 1] && utmphead->next[find - 1] != uent) find = utmphead->next[find - 1]; if (!utmphead->next[find - 1]) bbslog("3system", "UTMP:Can't find %s [%d]", utmpshm->uinfo[uent - 1].userid, uent); else utmphead->next[find - 1] = utmphead->next[uent - 1]; } /* remove from sorted list */ if (utmphead->listhead == uent) { utmphead->listhead = utmphead->list_next[uent - 1]; if (utmphead->listhead == uent) utmphead->listhead = 0; } utmphead->list_next[utmphead->list_prev[uent - 1] - 1] = utmphead->list_next[uent - 1]; utmphead->list_prev[utmphead->list_next[uent - 1] - 1] = utmphead->list_prev[uent - 1]; /* */ newbbslog(BBSLOG_USIES,"UTMP:clean %s(%d)", utmpshm->uinfo[uent - 1].userid, uent); utmphead->next[uent - 1] = utmphead->hashhead[0]; utmphead->hashhead[0] = uent; /* Delete the user's msglist entry from webmsgd, * if the user is login from web. */ /* if (utmpshm->uinfo[uent - 1].pid == 1) delfrom_msglist(uent, utmpshm->uinfo[uent - 1].userid); */ zeroinfo.active = false; zeroinfo.pid = 0; zeroinfo.invisible = true; zeroinfo.sockactive = false; zeroinfo.sockaddr = 0; zeroinfo.destuid = 0; if (utmpshm->uinfo[uent - 1].active != false) { utmphead->number--; setpublicshmreadonly(0); if (utmpshm->uinfo[uent-1].pid != 1) { get_publicshm()->logoutcount ++; get_publicshm()->staytime += time(NULL) - utmpshm->uinfo[uent-1].logintime; } else { get_publicshm()->wwwlogoutcount ++; get_publicshm()->wwwstaytime += time(NULL) - utmpshm->uinfo[uent-1].logintime; } setpublicshmreadonly(1); } utmpshm->uinfo[uent - 1] = zeroinfo; }
/* same as getnewutmpent() except no updating of utmpshm * only called in www */ int getnewutmpent2(struct user_info *up, int is_www) { int pos, i,ret; int utmpfd, hashkey; utmpfd = utmp_lock(); utmp_setreadonly(0); up->utmpkey = rand() % 100000000; pos = utmphead->hashhead[0] - 1; if (pos == -1) { ret=-1; } else { /* add to sorted list */ if (!utmphead->listhead) { /* init the list head */ utmphead->list_prev[pos] = pos + 1; utmphead->list_next[pos] = pos + 1; utmphead->listhead = pos + 1; } else { int i; i = utmphead->listhead; if (strcasecmp(utmpshm->uinfo[i - 1].userid, up->userid) >= 0) { /* add to head */ utmphead->list_prev[pos] = utmphead->list_prev[i - 1]; utmphead->list_next[pos] = i; utmphead->list_prev[i - 1] = pos + 1; utmphead->list_next[utmphead->list_prev[pos] - 1] = pos + 1; utmphead->listhead = pos + 1; } else { int count; count = 0; i = utmphead->list_next[i - 1]; while ((strcasecmp(utmpshm->uinfo[i - 1].userid, up->userid) < 0) && (i != utmphead->listhead)) { i = utmphead->list_next[i - 1]; count++; if (count > USHM_SIZE) { utmphead->listhead = 0; bbslog("3system", "UTMP:maybe loop rebuild..!"); apply_ulist((APPLY_UTMP_FUNC) rebuild_list, NULL); utmp_setreadonly(1); utmp_unlock(utmpfd); exit(-1); } } utmphead->list_prev[pos] = utmphead->list_prev[i - 1]; utmphead->list_next[pos] = i; utmphead->list_prev[i - 1] = pos + 1; utmphead->list_next[utmphead->list_prev[pos] - 1] = pos + 1; } } utmphead->hashhead[0] = utmphead->next[pos]; if (utmpshm->uinfo[pos].active) if (utmpshm->uinfo[pos].pid) { bbslog("3system", "utmp: alloc a active utmp! old:%s new:%s", utmpshm->uinfo[pos].userid, up->userid); kill(utmpshm->uinfo[pos].pid, SIGHUP); } utmpshm->uinfo[pos] = *up; hashkey = utmp_hash(up->userid); i = utmphead->hashhead[hashkey]; /* not need sort */ utmphead->next[pos] = i; utmphead->hashhead[hashkey] = pos + 1; utmphead->number++; setpublicshmreadonly(0); if (!is_www) { get_publicshm()->logincount ++; } else { get_publicshm()->wwwlogincount ++; } setpublicshmreadonly(1); ret=pos+1; } utmp_setreadonly(1); utmp_unlock(utmpfd); return ret; }
int getnewutmpent(struct user_info *up, int is_www) { struct user_info *uentp; time_t now; int pos, n, i,ret; int utmpfd, hashkey; utmpfd = utmp_lock(); utmp_setreadonly(0); up->utmpkey=rand() % 100000000; pos = utmphead->hashhead[0] - 1; if (pos == -1) { ret=-1; } else { /* add to sorted list */ if (!utmphead->listhead) { /* init the list head */ utmphead->list_prev[pos] = pos + 1; utmphead->list_next[pos] = pos + 1; utmphead->listhead = pos + 1; } else { int i; i = utmphead->listhead; if (strcasecmp(utmpshm->uinfo[i - 1].userid, up->userid) >= 0) { /* add to head */ utmphead->list_prev[pos] = utmphead->list_prev[i - 1]; utmphead->list_next[pos] = i; utmphead->list_prev[i - 1] = pos + 1; utmphead->list_next[utmphead->list_prev[pos] - 1] = pos + 1; utmphead->listhead = pos + 1; } else { int count; count = 0; i = utmphead->list_next[i - 1]; while ((strcasecmp(utmpshm->uinfo[i - 1].userid, up->userid) < 0) && (i != utmphead->listhead)) { i = utmphead->list_next[i - 1]; count++; if (count > USHM_SIZE) { utmphead->listhead = 0; bbslog("3system", "UTMP:maybe loop rebuild!"); apply_ulist((APPLY_UTMP_FUNC) rebuild_list, NULL); utmp_setreadonly(1); utmp_unlock(utmpfd); exit(-1); } } utmphead->list_prev[pos] = utmphead->list_prev[i - 1]; utmphead->list_next[pos] = i; utmphead->list_prev[i - 1] = pos + 1; utmphead->list_next[utmphead->list_prev[pos] - 1] = pos + 1; } } /* */ utmphead->hashhead[0] = utmphead->next[pos]; if (utmpshm->uinfo[pos].active) if (utmpshm->uinfo[pos].pid) { bbslog("3system", "utmp: alloc a active utmp! old:%s new:%s", utmpshm->uinfo[pos].userid, up->userid); kill(utmpshm->uinfo[pos].pid, SIGHUP); } utmpshm->uinfo[pos] = *up; hashkey = utmp_hash(up->userid); i = utmphead->hashhead[hashkey]; /* not need sort */ utmphead->next[pos] = i; utmphead->hashhead[hashkey] = pos + 1; utmphead->number++; setpublicshmreadonly(0); if (!is_www) { get_publicshm()->logincount ++; } else { get_publicshm()->wwwlogincount ++; } setpublicshmreadonly(1); if (get_utmp_number() + getwwwguestcount()>get_publicshm()->max_user) { setpublicshmreadonly(0); save_maxuser(); setpublicshmreadonly(1); } now = time(NULL); if ((now > utmphead->uptime + 120) || (now < utmphead->uptime - 120)) { utmphead->uptime = now; newbbslog(BBSLOG_USIES, "UTMP:Clean user utmp cache"); for (n = 0; n < USHM_SIZE; n++) { utmphead->uptime = now; uentp = &(utmpshm->uinfo[n]); if ((uentp->pid == 1) && ((now - uentp->freshtime) < IDLE_TIMEOUT)) { continue; } if (uentp->active && uentp->pid && kill(uentp->pid, 0) == -1) { /*uentp检查 */ char buf[STRLEN]; strncpy(buf, uentp->userid, IDLEN + 2); clear_utmp2(n + 1); /* 不需要再lock了 */ RemoveMsgCountFile(buf); } } } ret=pos+1; } utmp_setreadonly(1); utmp_unlock(utmpfd); return ret; }
/* * mytype 0 本日 * 1 本周 * 2 本月 * 3 本年 * 4 祝福榜 */ void writestat(int mytype) { int i; char buf[256]; char *p; char curfile[256]; FILE *fp; struct top_header curr_top[10]; sprintf(curfile, "etc/posts/%s", myfile[mytype]); if ((fp = fopen(curfile, "w")) != NULL) { #ifdef BLESS_BOARD if (mytype == 4) fprintf(fp, " \x1b[1;33m── \x1b[31m☆\x1b[33m☆\x1b[32m☆ \x1b[41;32m \x1b[33m本日十大衷心祝福 \x1b[m\x1b[1;32m ☆\x1b[31m☆\x1b[33m☆ ──\x1b[m\n" " %s\x1b[m\n", surfix_bless[1]); else #endif fprintf(fp, " \033[34m-----\033[37m=====\033[41m 本%s \033[m=====\033[34m-----\033[m\n\n", mytitle[mytype]); memset(curr_top,0,(10*sizeof(struct top_header))); for (i = 0; i < topnum; i++) { strcpy(buf, ctime(&top[i].date)); buf[20] = NULL; p = buf + 4; #ifdef BLESS_BOARD if (mytype == 4) fprintf(fp, " %s \x1b[1;31m%4d\x1b[0;37m人 %s\x1b[m\n" "\x1b[1m第\x1b[31m%2d \x1b[37m名 \x1b[4%dm %-51.51s\x1b[m \x1b[1;33m%-12s%s\x1b[m\n", p, top[i].number, surfix_bless[(i+1) * 2], i+1, (i) / 2 + 1, top[i].title, top[i].userid, surfix_bless[(i+1) * 2 + 1]); else #endif { fprintf(fp,"\033[37m第\033[31m%3d\033[37m 名 \033[37m信区 : \033[33m%-16s\033[37m【\033[32m%s\033[37m】" "\033[36m%4d \033[37m人\033[35m%16s\n \033[37m标题 : \033[44m\033[37m%-60.60s\033[m\n", (i+1),top[i].board,p,top[i].number,top[i].userid,top[i].title); /* etnlegend, 2006.05.28, 阅读十大 ... */ if(!mytype&&i<10){ curr_top[i].bid=getbid(top[i].board,NULL); curr_top[i].gid=top[i].groupid; } } } if(!mytype){ const struct boardheader *bh; char path[PATHLEN]; int k; for(k=0;k<10;k++){ if(!(bh=getboard(publicshm->top[k].bid))) continue; snprintf(path,PATHLEN,"boards/%s/.TOP.%u",bh->filename,publicshm->top[k].gid); unlink(path); } setpublicshmreadonly(0); memcpy(publicshm->top,curr_top,(10*sizeof(struct top_header))); publicshm->top_version++; setpublicshmreadonly(1); } #ifdef BLESS_BOARD if (mytype == 4) fprintf(fp, " %s\x1b[m", surfix_bless[22]); #endif fclose(fp); } }