#include #include #include "bbs.h" extern void utmplogin(int uid, int index, const int like[MAX_FRIEND], const int hate[MAX_REJECT]); extern int genfriendlist(int uid, int index, ocfs_t *fs, int maxfs); extern void utmplogoutall(void); #ifdef FAKEDATA FILE *fp; #endif #ifdef UTMPLOG FILE *logfp; #endif #ifdef NOFLOODING #define MAXWAIT 1024 #define FLUSHTIME (3600*6) struct { time_t lasttime; int count; } flooding[MAX_USERS]; int nWaits, lastflushtime; struct { int uid; int fd; int index; } waitqueue[MAXWAIT]; void processlogin(int cfd, int uid, int index); void flushwaitqueue(void) { int i; for( i = 0 ; i < nWaits ; ++i ) { processlogin(waitqueue[i].fd, waitqueue[i].uid, waitqueue[i].index); close(waitqueue[i].fd); } lastflushtime = time(NULL); nWaits = 0; memset(flooding, 0, sizeof(flooding)); } #endif /* NOFLOODING */ void syncutmp(int cfd) { int i; int like[MAX_FRIEND]; int hate[MAX_REJECT]; #ifdef UTMPLOG int x=-1; if(logfp && ftell(logfp)> 500*(1<<20)) { fclose(logfp); logfp=NULL; } if(logfp) fwrite(&x, sizeof(x), 1, logfp); #endif printf("logout all\n"); utmplogoutall(); fprintf(stderr,"sync begin\n"); for(i=0; i 500*(1<<20)) { fclose(logfp); logfp=NULL; } #endif while( (ch = getopt(argc, argv, "p:i:h")) != -1 ) switch( ch ){ case 'p': port = atoi(optarg); break; case 'i': iface_ip = optarg; break; case 'h': default: fprintf(stderr, "usage: utmpserver [-i interface_ip] [-p port]\n"); return 1; } #ifdef FAKEDATA fp=fopen("utmp.data","rb"); #else if( (sfd = tobind(iface_ip, port)) < 0 ) return 1; #endif #ifdef NOFLOODING lastflushtime = time(NULL); #endif while(1) { #ifdef NOFLOODING if( lastflushtime < (time(NULL) - 1800) ) flushwaitqueue(); #endif #ifdef FAKEDATA if(fread(&cmd, sizeof(cmd), 1, fp)==0) break; #else len = sizeof(clientaddr); if( (cfd = accept(sfd, (struct sockaddr *)&clientaddr, &len)) < 0 ){ if( errno != EINTR ) sleep(1); continue; } toread(cfd, &cmd, sizeof(cmd)); #endif if(cmd==-1) { syncutmp(cfd); #ifndef FAKEDATA close(cfd); #endif continue; } fail=0; #ifdef FAKEDATA fread(&uid, sizeof(uid), 1, fp); fread(&index, sizeof(index), 1, fp); #else index=cmd; // bad protocol if(toread(cfd, &uid, sizeof(uid)) <= 0) fail=1; #endif if(index>=USHM_SIZE) { fprintf(stderr, "bad index=%d\n",index); fail=1; } if(fail) { #ifndef FAKEDATA close(cfd); #endif continue; } #ifdef NOFLOODING if( (time(NULL) - flooding[uid].lasttime) < 20 ) ++flooding[uid].count; if( flooding[uid].count > 10 ){ if( nWaits == MAXWAIT ) flushwaitqueue(); waitqueue[nWaits].uid = uid; waitqueue[nWaits].index = index; waitqueue[nWaits].fd = cfd; ++nWaits; continue; } flooding[uid].lasttime = time(NULL); #endif processlogin(cfd, uid, index); #ifndef FAKEDATA close(cfd); #endif } #ifdef FAKEDATA fclose(fp); #endif return 0; }