summaryrefslogtreecommitdiffstats
path: root/cacheserver
diff options
context:
space:
mode:
Diffstat (limited to 'cacheserver')
-rw-r--r--cacheserver/Makefile30
-rw-r--r--cacheserver/README1
-rw-r--r--cacheserver/authserver.c236
-rw-r--r--cacheserver/friend.cpp350
-rw-r--r--cacheserver/utmpserver.c222
-rw-r--r--cacheserver/utmpserver2.c290
-rw-r--r--cacheserver/utmpserver3.c341
-rw-r--r--cacheserver/utmpsync.c27
8 files changed, 0 insertions, 1497 deletions
diff --git a/cacheserver/Makefile b/cacheserver/Makefile
deleted file mode 100644
index bdff3f08..00000000
--- a/cacheserver/Makefile
+++ /dev/null
@@ -1,30 +0,0 @@
-# $Id$
-SRCROOT= ..
-.include "$(SRCROOT)/pttbbs.mk"
-
-PROGRAMS= utmpserver utmpsync utmpserver2 utmpserver3 authserver
-UTILDIR= $(SRCROOT)/util
-UTILOBJ= $(UTILDIR)/util_stuff.o $(UTILDIR)/util_var.o $(UTILDIR)/util_file.o $(UTILDIR)/util_cache.o $(UTILDIR)/util_passwd.o $(UTILDIR)/util_record.o $(UTILDIR)/util_osdep.o $(UTILDIR)/util_args.o
-
-all: ${PROGRAMS}
-
-.SUFFIXES: .c .cpp .o
-.c.o:
- $(CCACHE) $(CC) $(CFLAGS) -c $*.c
-.cpp.o:
- $(CCACHE) $(CXX) $(CFLAGS) -c $*.cpp
-
-utmpserver: utmpserver.o $(UTILOBJ)
- ${CC} ${CFLAGS} ${LDFLAGS} -o $* $*.o $(UTILOBJ)
-utmpserver2: utmpserver2.o friend.o $(UTILOBJ)
- ${CXX} ${CFLAGS} ${LDFLAGS} -o $* $*.o $(UTILOBJ) friend.o
-utmpserver3: utmpserver3.o friend.o $(UTILOBJ)
- ${CXX} ${CFLAGS} ${LDFLAGS} -levent -o $* $*.o $(UTILOBJ) friend.o
-utmpsync: utmpsync.o $(UTILOBJ)
- ${CC} ${CFLAGS} ${LDFLAGS} -o $* $*.o $(UTILOBJ)
-
-authserver: authserver.o $(UTILOBJ)
- ${CC} ${CFLAGS} ${LDFLAGS} -lcrypt -levent -o $* $>
-
-clean:
- rm -f *~ ${PROGRAMS} friend.o utmpserver.o utmpserver2.o utmpserver3.o utmpsync.o authserver.o
diff --git a/cacheserver/README b/cacheserver/README
deleted file mode 100644
index 3bfeddbc..00000000
--- a/cacheserver/README
+++ /dev/null
@@ -1 +0,0 @@
-這是一個測試的東西. 除非確定你知道這個程式在幹什麼, 否則請不理會這個目錄 :P
diff --git a/cacheserver/authserver.c b/cacheserver/authserver.c
deleted file mode 100644
index 5fbba03a..00000000
--- a/cacheserver/authserver.c
+++ /dev/null
@@ -1,236 +0,0 @@
-/* $Id$ */
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <event.h>
-
-#include "bbs.h"
-
-struct timeval tv = {5, 0};
-struct event ev;
-int clients = 0;
-
-#define READ_BLOCK 256
-#define MAX_CLIENTS 10
-
-#define AUTH_PASSWDS BBSHOME "/.AUTH_PASSWDS"
-#define ENTRY_SIZE 64
-
-struct client_state {
- struct event ev;
- int state;
- int uid;
- int len;
- int response;
- struct evbuffer *evb;
-};
-
-enum {
- FSM_ENTER,
- FSM_AUTH,
- FSM_SETPASSWD,
- FSM_RESPOND,
- FSM_EXIT
-};
-
-/**
- * 瑼X亙蝣
- * @return 1 - 撖蝣潮航炊, 0 - 撖蝣潭迤蝣
- */
-int check_passwd(int uid, char *passwd)
-{
- char buf[ENTRY_SIZE];
- int i, result = 1;
-
- if ((i = open(AUTH_PASSWDS, O_WRONLY)) < 0)
- return result;
-
- if (lseek(i, uid * ENTRY_SIZE, SEEK_SET) < 0)
- goto end;
-
- if (read(i, buf, ENTRY_SIZE) < ENTRY_SIZE)
- goto end;
-
- if (!strcmp(buf, crypt(passwd, buf)))
- result = 0;
-end:
- memset(buf, 0, ENTRY_SIZE);
- close(i);
- return result;
-}
-
-/**
- * 閮剖啣蝣
- * DES crypt 撠勗末
- */
-void set_passwd(int uid, char *passwd)
-{
- char buf[ENTRY_SIZE];
- char saltc[3], c;
- int i;
-
- i = 9 * random();
- saltc[0] = i & 077;
- saltc[1] = (i >> 6) & 077;
-
- for (i = 0; i < 2; i++) {
- c = saltc[i] + '.';
- if (c > '9')
- c += 7;
- if (c > 'Z')
- c += 6;
- saltc[i] = c;
- }
- saltc[2] = '\0';
-
- memset(buf, 0, sizeof(buf));
- strlcpy(buf, crypt(passwd, saltc), sizeof(buf));
-
- if ((i = open(AUTH_PASSWDS, O_WRONLY)) < 0)
- return;
-
- if (lseek(i, uid * ENTRY_SIZE, SEEK_SET) < 0)
- goto close;
- write(i, buf, ENTRY_SIZE);
-close:
- close(i);
-}
-
-void connection_client(int cfd, short event, void *arg)
-{
- struct client_state *cs = arg;
- int cmd;
- static char buf[128];
-
- // ignore clients that timeout
- if (event & EV_TIMEOUT)
- cs->state = FSM_EXIT;
-
- if (event & EV_READ) {
- if (evbuffer_read(cs->evb, cfd, READ_BLOCK) < 0)
- cs->state = FSM_EXIT;
- }
-
- while (1) {
- switch (cs->state) {
- case FSM_ENTER:
- if (EVBUFFER_LENGTH(cs->evb) < sizeof(int))
- goto break_out;
- evbuffer_remove(cs->evb, &cmd, sizeof(cmd));
- cs->state = FSM_AUTH;
-
- case FSM_AUTH:
- if (EVBUFFER_LENGTH(cs->evb) < sizeof(int) * 2)
- goto break_out;
-
- evbuffer_remove(cs->evb, &cs->uid, sizeof(cs->uid));
- evbuffer_remove(cs->evb, &cs->len, sizeof(cs->len));
- if (EVBUFFER_LENGTH(cs->evb) < cs->len)
- goto break_out;
-
- memset(buf, 0, sizeof(buf));
- evbuffer_remove(cs->evb, buf, cs->len);
- cs->response = check_passwd(cs->uid, buf);
- memset(buf, 0, sizeof(buf));
-
- if (cmd == 2)
- cs->state = FSM_SETPASSWD;
- else {
- cs->state = FSM_RESPOND;
- goto break_out;
- }
-
- case FSM_SETPASSWD:
- if (EVBUFFER_LENGTH(cs->evb) < sizeof(int))
- goto break_out;
-
- evbuffer_remove(cs->evb, &cs->len, sizeof(cs->len));
- if (EVBUFFER_LENGTH(cs->evb) < cs->len)
- goto break_out;
-
- memset(buf, 0, sizeof(buf));
- evbuffer_remove(cs->evb, buf, cs->len);
- set_passwd(cs->uid, buf);
- memset(buf, 0, sizeof(buf));
-
- cs->state = FSM_RESPOND;
- goto break_out;
-
- case FSM_RESPOND:
- write(cfd, &cs->response, sizeof(cs->response));
- cs->state = FSM_EXIT;
-
- case FSM_EXIT:
- if (clients == MAX_CLIENTS)
- event_add(&ev, NULL);
- close(cfd);
- evbuffer_free(cs->evb);
- free(cs);
- clients--;
- return;
- }
- }
-
-break_out:
- if (cs->state == FSM_RESPOND)
- event_set(&cs->ev, cfd, EV_WRITE, (void *) connection_client, cs);
- event_add(&cs->ev, &tv);
-}
-
-void connection_accept(int fd, short event, void *arg)
-{
- struct sockaddr_in clientaddr;
- socklen_t len = sizeof(clientaddr);
- int cfd;
-
- if ((cfd = accept(fd, (struct sockaddr *)&clientaddr, &len)) < 0 )
- return;
-
- fcntl(cfd, F_SETFL, fcntl(cfd, F_GETFL, 0) | O_NONBLOCK);
-
- struct client_state *cs = calloc(1, sizeof(struct client_state));
- cs->state = 0;
- cs->evb = evbuffer_new();
-
- event_set(&cs->ev, cfd, EV_READ, (void *) connection_client, cs);
- event_add(&cs->ev, &tv);
- clients++;
-
- if (clients > MAX_CLIENTS)
- event_del(&ev);
-}
-
-int main(int argc, char *argv[])
-{
- int ch, port = 5121, sfd;
- char *iface_ip = NULL;
-
- Signal(SIGPIPE, SIG_IGN);
- 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: authserver [-i interface_ip] [-p port]\n");
- return 1;
- }
-
- if( (sfd = tobind(iface_ip, port)) < 0 )
- return 1;
-
- srandom(getpid() + time(NULL));
- event_init();
- event_set(&ev, sfd, EV_READ | EV_PERSIST, connection_accept, &ev);
- event_add(&ev, NULL);
- event_dispatch();
- return 0;
-}
diff --git a/cacheserver/friend.cpp b/cacheserver/friend.cpp
deleted file mode 100644
index e62a7198..00000000
--- a/cacheserver/friend.cpp
+++ /dev/null
@@ -1,350 +0,0 @@
-#define NDEBUG
-#include <algorithm>
-#include <cassert>
-
-// for some constant and type
-#include "bbs.h"
-
-/* for each login of user,
- * input: my index, friend[MAX_FRIEND] of uid, reject[MAX_REJECT] of uid,
- * for all my relation,
- * output: his index, his uid, relation to me, relation to him
- */
-/* 支 user utmp 銋憭, 券函 ref index 賣舫, 蝣箔 insert & delete O(1) */
-/* 嗆鈭 refer resource recycle */
-
-typedef int Uid;
-typedef int Idx;
-
-
-struct Relation {
- Uid him;
- short him_offset;
-
- Relation(Uid _him, short _him_offset=-1) :him(_him),him_offset(_him_offset) {}
-};
-
-template<class T>
-struct freelist {
- static const int KEEP = 64;
- static T* list[8][KEEP]; // 2^0~2^7
- static int tail[8];
-
-#define IS_2xxN(a) (a && (a&(a-1))==0)
- static T* alloc(int n) {
- assert(n>0);
- if(n<256 && IS_2xxN(n) && sizeof(T)*n<65536) {
- int t=n;
- int slot;
- for(slot=0; t>1; t/=2)
- slot++;
- assert(0<=slot && slot<8);
- if(tail[slot]) {
- return list[slot][--tail[slot]];
- }
- }
- return (T*)malloc(sizeof(T)*n);
- }
- static void free(T* p, int n) {
- assert(n>0);
- if(n<256 && IS_2xxN(n) && sizeof(T)*n<65536) {
- int t=n;
- int slot;
- for(slot=0; t>1; t/=2)
- slot++;
- assert(0<=slot && slot<8);
- if(tail[slot]<KEEP) {
- list[slot][tail[slot]++]=p;
- return;
- }
- }
- ::free(p);
- }
-};
-
-template<class T> T* freelist<T>::list[8][KEEP];
-template<class T> int freelist<T>::tail[8]={0};
-
-template<class T,int MIN_ROOM = 8, class S = int>
-struct myvector {
- // 憭扯港唾 STL vector, 雿 STL capacity 芣憓銝蝮桀
- // (敺靘潛, 隞 online friend 靘隤, capacity 銝蝮桀嗅祕瘝隞暻澆蔣)
- // 甇文, pointer 64bit 璈其閬 8bytes, basic overhead 8*3 bytes,
- // 雿鞈瘝暻澆之, 寧 S(int or short) 摮 size & capacity 瘥頛
- T *base;
- S room, n;
-
- myvector() :base(0),room(0),n(0) {}
- ~myvector() {
- clear();
- }
- S append(T data) {
- if(room<n+1)
- resizefor(n+1);
- base[n++]=data;
- return n-1;
- }
- void pop_back() {
- assert(n>0);
- n--;
- resizefor(n);
- }
- void clear() {
- n=0;
- resizefor(n);
- }
- /*
- T& operator[](int idx) {
- return base[idx];
- }
- */
-
- void resizefor(S size) {
- assert(size>=n);
- if(size==0) {
- if(base) freelist<T>::free(base, room);
- base=0;
- room=0;
- } else {
- S origroom=room;
- if(room==0)
- room=MIN_ROOM;
- while(room<size) room=S(room*2);
- if(size<MIN_ROOM) size=MIN_ROOM;
- while(room/2>size) room=S(room/2);
- if(room!=origroom || base==0) {
- //base=(T*)realloc(base, sizeof(T)*room);
- T* tmp=freelist<T>::alloc(room);
- assert(tmp);
- if(n>0)
- memcpy(tmp, base, sizeof(T)*n);
- if(base!=0)
- freelist<T>::free(base, origroom);
- base=tmp;
- }
- assert(base);
- }
- }
-};
-
-template<class R,class B>
-struct RelationList: public myvector<Relation, 8, short> {
- RelationList() :myvector<Relation, 8, short>() {}
- void add(Uid me, Uid him) {
- RelationList<B,R>& bl=R::backlist(him);
- short me_offset=append(Relation(him));
- short him_offset=bl.append(Relation(me,me_offset));
-
- setbackoffset(me_offset,him_offset);
- assert(bl.base[him_offset].him==me);
- assert(bl.base[him_offset].him_offset==me_offset);
- }
- void deleteall(Uid me) {
- for(int i=0; i<n; i++) {
- RelationList<B,R>& bl=R::backlist(base[i].him);
- assert(bl.base[base[i].him_offset].him==me);
- assert(bl.base[base[i].him_offset].him_offset==i);
- bl.delete_half(base[i].him_offset);
- //try_recycle(base[i].him); // dirty
- }
- clear();
- }
- private:
- void setbackoffset(short which,short offset) {
- assert(0<=which && which<n);
- base[which].him_offset=offset;
- }
- void delete_half(short offset) {
- assert(0<=offset && offset<n);
- if(offset<n-1) {
- base[offset]=base[n-1];
- R::backlist(base[offset].him).setbackoffset(base[offset].him_offset,offset);
- }
- pop_back();
- }
- friend class RelationList<B,R>;
-};
-
-struct Like;
-struct Likeby;
-struct Hate;
-struct Hateby;
-struct Like: public Relation {
- Like(Uid _him, short _him_offset=-1) :Relation(_him,_him_offset) {}
- static RelationList<Likeby,Like>& backlist(Uid him);
-};
-struct Likeby: public Relation {
- Likeby(Uid _him, short _him_offset=-1) :Relation(_him,_him_offset) {}
- static RelationList<Like,Likeby>& backlist(Uid him);
-};
-struct Hate: public Relation {
- Hate(Uid _him, short _him_offset=-1) :Relation(_him,_him_offset) {}
- static RelationList<Hateby,Hate>& backlist(Uid him);
-};
-struct Hateby: public Relation {
- Hateby(Uid _him, short _him_offset=-1) :Relation(_him,_him_offset) {}
- static RelationList<Hate,Hateby>& backlist(Uid him);
-};
-
-
-struct Utmp {
- Utmp() {
- for(int i=0; i<USHM_SIZE; i++)
- utmp[i]=-1;
- }
- /*
- Uid& operator[](int idx) {
- return utmp[idx];
- }
- */
- public:
- Uid utmp[USHM_SIZE];
-};
-static Utmp utmp;
-
-struct BBSUser {
- Uid me;
- int online;
- /* assume utmplist is short, so just use plain vector and linear search */
- myvector<int,2> utmplist;
-
- RelationList<Like,Likeby> like;
- RelationList<Hate,Hateby> hate;
- RelationList<Likeby,Like> likeby;
- RelationList<Hateby,Hate> hateby;
-
- BBSUser() :me(-1),online(0),utmplist(),like(),hate(),likeby(),hateby() {}
- BBSUser(Uid uid) :me(uid),online(0),utmplist(),like(),hate(),likeby(),hateby() {}
-
- void login(int utmpidx, const Uid likehim[MAX_FRIEND], const Uid hatehim[MAX_REJECT]) {
- if(online>0) {
- /* multiple login 閰, 隞交敺銝甈∠ like/hate 箸 */
- like.deleteall(me);
- hate.deleteall(me);
- }
- utmp.utmp[utmpidx]=me;
- utmplist.append(utmpidx);
- online++;
- assert(online==utmplist.n);
- for(int i=0; i<MAX_FRIEND && likehim[i]; i++)
- like.add(me, likehim[i]);
- for(int i=0; i<MAX_REJECT && hatehim[i]; i++)
- hate.add(me, hatehim[i]);
- }
-
- void logout(int utmpidx) {
- assert(utmp.utmp[utmpidx]==me);
- assert(online==utmplist.n);
- for(int i=0; i<utmplist.n; i++)
- if(utmplist.base[i]==utmpidx) {
- utmplist.base[i]=utmplist.base[utmplist.n-1];
- utmplist.pop_back();
- break;
- }
- utmp.utmp[utmpidx]=-1;
- online--;
- assert(online==utmplist.n);
- if(online==0) {
- like.deleteall(me);
- hate.deleteall(me);
- }
- }
- bool isfree() const {
- return online==0 && like.n==0 && hate.n==0 && likeby.n==0 && hateby.n==0;
- }
-};
-
-struct UserList {
- BBSUser users[MAX_USERS];
-
- UserList() {
- for(int i=0; i<MAX_USERS; i++)
- users[i].me=i;
- }
- void login(Uid uid, Idx idx, const Uid likehim[MAX_FRIEND], const Uid hatehim[MAX_REJECT]) {
- assert(uid<MAX_USERS);
- assert(idx<USHM_SIZE);
- /* 望潔嗅 logout event, 甇 logout 芰潛 utmp override */
- if(utmp.utmp[idx]!=-1) users[utmp.utmp[idx]].logout(idx);
- users[uid].login(idx, likehim, hatehim);
- }
-};
-
-struct UserList userlist;
-RelationList<Likeby,Like>& Like::backlist(Uid him) { return userlist.users[him].likeby; }
-RelationList<Like,Likeby>& Likeby::backlist(Uid him) { return userlist.users[him].like; }
-RelationList<Hateby,Hate>& Hate::backlist(Uid him) { return userlist.users[him].hateby; }
-RelationList<Hate,Hateby>& Hateby::backlist(Uid him) { return userlist.users[him].hate; }
-
-struct Result {
- Uid who;
- int bits;
- Result(Uid _who, int _bits) :who(_who),bits(_bits) {}
- bool operator<(const Result& b) const {
- return who<b.who;
- }
-};
-
-int reverse_friend_stat(int stat)
-{
- int stat1 = 0;
- if (stat & IFH) stat1 |= HFM;
- if (stat & IRH) stat1 |= HRM;
- if (stat & HFM) stat1 |= IFH;
- if (stat & HRM) stat1 |= IRH;
- return stat1;
-}
-
-extern "C" void utmplogin(int uid, int index, const int like[MAX_FRIEND], const int hate[MAX_REJECT])
-{
- /* login */
- userlist.login(uid, index, like, hate);
-}
-
-extern "C" int genfriendlist(int uid, int index, ocfs_t *fs, int maxfs)
-{
- /* collect data */
- BBSUser& u=userlist.users[uid];
- myvector<Result,64,short> work;
- for(int i=0; i<u.like.n; i++) work.append(Result(u.like.base[i].him, IFH));
- for(int i=0; i<u.hate.n; i++) work.append(Result(u.hate.base[i].him, IRH));
- for(int i=0; i<u.likeby.n; i++) work.append(Result(u.likeby.base[i].him, HFM));
- for(int i=0; i<u.hateby.n; i++) work.append(Result(u.hateby.base[i].him, HRM));
-
- /* sort */
- std::sort(work.base, work.base+work.n);
- /* merge */
- if(work.n>0) {
- int newn=1;
- for(int i=1; i<work.n; i++)
- if(work.base[i].who==work.base[newn-1].who) {
- work.base[newn-1].bits|=work.base[i].bits;
- } else {
- work.base[newn++]=work.base[i];
- }
- work.n=newn;
- }
- /* fill */
- int nfs=0;
- for(int i=0; i<work.n && nfs<maxfs; i++) {
- BBSUser& h=userlist.users[work.base[i].who];
- for(int j=0; j<h.utmplist.n && nfs<maxfs; j++) {
- int rstat=reverse_friend_stat(work.base[i].bits);
- if(h.utmplist.base[j]==index) continue;
- fs[nfs].index=h.utmplist.base[j];
- fs[nfs].uid=h.me;
- fs[nfs].friendstat=(work.base[i].bits<<24)|h.utmplist.base[j];
- fs[nfs].rfriendstat=(rstat<<24)|index;
- nfs++;
- }
- }
- return nfs;
-}
-
-extern "C" void utmplogoutall(void)
-{
- for(int i=0; i<USHM_SIZE; i++)
- if(utmp.utmp[i]!=-1)
- userlist.users[utmp.utmp[i]].logout(i);
-}
-
diff --git a/cacheserver/utmpserver.c b/cacheserver/utmpserver.c
deleted file mode 100644
index 85adf8c3..00000000
--- a/cacheserver/utmpserver.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-#include <err.h>
-
-struct {
- int uid;
- int nFriends, nRejects;
- int friend[MAX_FRIEND];
- int reject[MAX_REJECT];
-} utmp[USHM_SIZE];
-
-#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];
-#endif /* NOFLOODING */
-
-inline int countarray(int *s, int max)
-{
- int i;
- for( i = 0 ; i < max && s[i] ; ++i )
- ;
- return i;
-}
-
-int
-reverse_friend_stat(int stat)
-{
- int stat1 = 0;
- if (stat & IFH)
- stat1 |= HFM;
- if (stat & IRH)
- stat1 |= HRM;
- if (stat & HFM)
- stat1 |= IFH;
- if (stat & HRM)
- stat1 |= IRH;
- if (stat & IBH)
- stat1 |= IBH;
- return stat1;
-}
-
-int set_friend_bit(int me, int ui)
-{
- int hit = 0;
- /* 判斷對方是否為我的朋友 ? */
- if( intbsearch(utmp[ui].uid, utmp[me].friend, utmp[me].nFriends) )
- hit = IFH;
-
- /* 判斷我是否為對方的朋友 ? */
- if( intbsearch(utmp[me].uid, utmp[ui].friend, utmp[ui].nFriends) )
- hit |= HFM;
-
- /* 判斷對方是否為我的仇人 ? */
- if( intbsearch(utmp[ui].uid, utmp[me].reject, utmp[me].nRejects) )
- hit |= IRH;
-
- /* 判斷我是否為對方的仇人 ? */
- if( intbsearch(utmp[me].uid, utmp[ui].reject, utmp[ui].nRejects) )
- hit |= HRM;
-
- return hit;
-}
-
-void initdata(int index)
-{
- utmp[index].nFriends = countarray(utmp[index].friend, MAX_FRIEND);
- utmp[index].nRejects = countarray(utmp[index].reject, MAX_REJECT);
- if( utmp[index].nFriends > 0 )
- qsort(utmp[index].friend, utmp[index].nFriends,
- sizeof(int), qsort_intcompar);
- if( utmp[index].nRejects > 0 )
- qsort(utmp[index].reject, utmp[index].nRejects,
- sizeof(int), qsort_intcompar);
-}
-
-inline void syncutmp(int cfd)
-{
- int nSynced = 0, i;
- for( i = 0 ; i < USHM_SIZE ; ++i, ++nSynced )
- if( toread(cfd, &utmp[i].uid, sizeof(utmp[i].uid)) > 0 &&
- toread(cfd, utmp[i].friend, sizeof(utmp[i].friend)) > 0 &&
- toread(cfd, utmp[i].reject, sizeof(utmp[i].reject)) > 0 ){
- if( utmp[i].uid )
- initdata(i);
- }
- else
- for( ; i < USHM_SIZE ; ++i )
- utmp[i].uid = 0;
- close(cfd);
- fprintf(stderr, "%d users synced\n", nSynced);
-}
-
-void processlogin(int cfd, int uid, int index)
-{
- if( toread(cfd, utmp[index].friend, sizeof(utmp[index].friend)) > 0 &&
- toread(cfd, utmp[index].reject, sizeof(utmp[index].reject)) > 0 ){
- /* 因為 logout 的時候並不會通知 utmpserver , 可能會查到一些
- 已經 logout 的帳號。所以不能只取 MAX_FRIEND 而要多取一些 */
-#define MAX_FS (2 * MAX_FRIEND)
- int iu, nFrs, stat, rstat;
- ocfs_t fs[MAX_FS];
-
- utmp[index].uid = uid;
- initdata(index);
-
- for( nFrs = iu = 0 ; iu < USHM_SIZE && nFrs < MAX_FS ; ++iu )
- if( iu != index && utmp[iu].uid ){
- if( (stat = set_friend_bit(index, iu)) ){
- rstat = reverse_friend_stat(stat);
- fs[nFrs].index = iu;
- fs[nFrs].uid = utmp[iu].uid;
- fs[nFrs].friendstat = (stat << 24) + iu;
- fs[nFrs].rfriendstat = (rstat << 24) + index;
- ++nFrs;
- }
- }
-
- towrite(cfd, &fs, sizeof(ocfs_t) * nFrs);
- }
- close(cfd);
-}
-
-#ifdef NOFLOODING
-void flushwaitqueue(void)
-{
- int i;
- for( i = 0 ; i < nWaits ; ++i )
- processlogin(waitqueue[i].fd, waitqueue[i].uid, waitqueue[i].index);
- lastflushtime = time(NULL);
- nWaits = 0;
- memset(flooding, 0, sizeof(flooding));
-}
-#endif
-
-/* XXX 具有被 DoS 的可能, 請用 firewall 之類擋起來 */
-int main(int argc, char **argv)
-{
- struct sockaddr_in clientaddr;
- int ch, port = 5120, sfd, cfd, len, index, uid;
- char *iface_ip = NULL;
-
- Signal(SIGPIPE, SIG_IGN);
- 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;
- }
-
- if( (sfd = tobind(iface_ip, port)) < 0 )
- return 1;
-
-#ifdef NOFLOODING
- lastflushtime = time(NULL);
-#endif
- while( 1 ){
-#ifdef NOFLOODING
- if( lastflushtime < (time(NULL) - 1800) )
- flushwaitqueue();
-#endif
-
- len = sizeof(clientaddr);
- if( (cfd = accept(sfd, (struct sockaddr *)&clientaddr, &len)) < 0 ){
- if( errno != EINTR )
- sleep(1);
- continue;
- }
- toread(cfd, &index, sizeof(index));
- if( index == -1 ){
- syncutmp(cfd);
- continue;
- }
-
- if( toread(cfd, &uid, sizeof(uid)) > 0 ){
- if( !(0 < uid || uid > MAX_USERS) ){ /* for safety */
- close(cfd);
- 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
-
- /* cfd will be closed in processlogin() */
- processlogin(cfd, uid, index);
- } else {
- close(cfd);
- }
- }
- return 0;
-}
diff --git a/cacheserver/utmpserver2.c b/cacheserver/utmpserver2.c
deleted file mode 100644
index 12c3a299..00000000
--- a/cacheserver/utmpserver2.c
+++ /dev/null
@@ -1,290 +0,0 @@
-/* $Id$ */
-#include <stdio.h>
-#include <sys/time.h>
-
-#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
-
-clock_t begin_clock;
-time_t begin_time;
-int count_flooding, count_login;
-
-#ifdef NOFLOODING
-/* 0 ok, 1 delay action, 2 reject */
-int action_frequently(int uid)
-{
- int i;
- time_t now = time(NULL);
- time_t minute = now/60;
- time_t hour = minute/60;
-
- static time_t flood_base_minute;
- static time_t flood_base_hour;
- static struct {
- unsigned short lastlogin; // truncated time_t
- unsigned char minute_count;
- unsigned char hour_count;
- } flooding[MAX_USERS];
-
- if(minute!=flood_base_minute) {
- for(i=0; i<MAX_USERS; i++)
- flooding[i].minute_count=0;
- flood_base_minute=minute;
- }
- if(hour!=flood_base_hour) {
- for(i=0; i<MAX_USERS; i++)
- flooding[i].hour_count=0;
- flood_base_hour=hour;
- }
-
- if(abs(flooding[uid].lastlogin-(unsigned short)now)<=3 ||
- flooding[uid].minute_count>30 ||
- flooding[uid].hour_count>60) {
- count_flooding++;
- return 2;
- }
-
- flooding[uid].minute_count++;
- flooding[uid].hour_count++;
- flooding[uid].lastlogin=now;
-
- if(flooding[uid].minute_count>5 ||
- flooding[uid].hour_count>20) {
- count_flooding++;
- return 1;
- }
- return 0;
-}
-#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<USHM_SIZE; i++) {
- int uid;
-#ifdef FAKEDATA
- fread(&uid, sizeof(uid), 1, fp);
- if(uid==-2)
- break;
- fread(like, sizeof(like), 1, fp);
- fread(hate, sizeof(hate), 1, fp);
-#else
- if( toread(cfd, &uid, sizeof(uid)) <= 0 ||
- toread(cfd, like, sizeof(like)) <= 0 ||
- toread(cfd, hate, sizeof(hate)) <= 0)
- break;
-#endif
-#ifdef UTMPLOG
- if(logfp) {
- fwrite(&uid, sizeof(uid), 1, logfp);
- fwrite(like, sizeof(like), 1, logfp);
- fwrite(hate, sizeof(hate), 1, logfp);
- }
-#endif
-
- if(uid != 0)
- utmplogin(uid, i, like, hate);
- }
- if(i<USHM_SIZE) {
-#ifdef UTMPLOG
- int x=-2;
- if(logfp) fwrite(&x, sizeof(x), 1, logfp);
-#endif
- }
-
- fprintf(stderr,"sync end\n");
-}
-
-void processlogin(int cfd, int uid, int index)
-{
- int like[MAX_FRIEND];
- int hate[MAX_REJECT];
- /* logout 銝虫 utmpserver , 航賣亙唬鈭
- 撌脩 logout 撣唾隞乩賢芸 MAX_FRIEND 閬憭銝鈭 */
-#define MAX_FS (2 * MAX_FRIEND)
- int res;
- int nfs;
- ocfs_t fs[MAX_FS];
-
-#ifdef FAKEDATA
- fread(like, sizeof(like), 1, fp);
- fread(hate, sizeof(hate), 1, fp);
-#else
- if(toread(cfd, like, sizeof(like)) <= 0 ||
- toread(cfd, hate, sizeof(hate)) <= 0)
- return;
-#endif
-#ifdef UTMPLOG
- if(logfp) {
- int x=-3;
- fwrite(&x, sizeof(x), 1, logfp);
- fwrite(&uid, sizeof(uid), 1, logfp);
- fwrite(&index, sizeof(index), 1, logfp);
- fwrite(like, sizeof(like), 1, logfp);
- fwrite(hate, sizeof(hate), 1, logfp);
- }
-#endif
-
- utmplogin(uid, index, like, hate);
- nfs=genfriendlist(uid, index, fs, MAX_FS);
-#ifndef FAKEDATA
- res=0;
-#ifdef NOFLOODING
- res=action_frequently(uid);
-#endif
- towrite(cfd, &res, sizeof(res));
- towrite(cfd, &nfs, sizeof(nfs));
- towrite(cfd, fs, sizeof(ocfs_t) * nfs);
-#endif
-}
-
-void showstat(void)
-{
- clock_t now_clock=clock();
- time_t now_time=time(0);
-
- time_t used_time=now_time-begin_time;
- clock_t used_clock=now_clock-begin_clock;
-
- printf("%.24s : real %.0f cpu %.2f : %d login %d flood, %.2f login/sec, %.2f%% load.\n",
- ctime(&now_time), (double)used_time, (double)used_clock/CLOCKS_PER_SEC,
- count_login, count_flooding,
- (double)count_login/used_time, (double)used_clock/CLOCKS_PER_SEC/used_time*100);
-
- begin_time=now_time;
- begin_clock=now_clock;
- count_login=0;
- count_flooding=0;
-}
-
-int main(int argc, char *argv[])
-{
- struct sockaddr_in clientaddr;
- int ch, port = 5120, sfd, cfd, len;
- char *iface_ip = NULL;
- int cmd;
- int uid,index;
- int fail;
- int firstsync=0;
-
-#ifdef UTMPLOG
- logfp = fopen("utmp.log","a");
- if(logfp && ftell(logfp)> 500*(1<<20)) {
- fclose(logfp);
- logfp=NULL;
- }
-#endif
-
- Signal(SIGPIPE, SIG_IGN);
- 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
- while(1) {
-#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
- firstsync=1;
- continue;
- }
- if(!firstsync) {
- // don't accept client before first sync, to prevent incorrect friend data
- close(cfd);
- continue;
- }
-
- fail=0;
-#ifdef FAKEDATA
- fread(&uid, sizeof(uid), 1, fp);
- fread(&index, sizeof(index), 1, fp);
-#else
- if(cmd==-2) {
- if(toread(cfd, &index, sizeof(index)) <= 0)
- fail=1;
- if(toread(cfd, &uid, sizeof(uid)) <= 0)
- fail=1;
- } else if(cmd>=0) {
- // old client
- fail=1;
- } else {
- printf("unknown cmd=%d\n",cmd);
- }
-#endif
- if(index>=USHM_SIZE) {
- fprintf(stderr, "bad index=%d\n",index);
- fail=1;
- }
-
- if(fail) {
-#ifndef FAKEDATA
- close(cfd);
-#endif
- continue;
- }
-
- count_login++;
- processlogin(cfd, uid, index);
- if(count_login>=4000 || time(NULL)-begin_time>30*60)
- showstat();
-#ifndef FAKEDATA
- close(cfd);
-#endif
- }
-#ifdef FAKEDATA
- fclose(fp);
-#endif
- return 0;
-}
diff --git a/cacheserver/utmpserver3.c b/cacheserver/utmpserver3.c
deleted file mode 100644
index 0e1eef02..00000000
--- a/cacheserver/utmpserver3.c
+++ /dev/null
@@ -1,341 +0,0 @@
-/* $Id$ */
-#include <stdio.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <event.h>
-
-#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 UTMPLOG
-FILE *logfp;
-#endif
-
-clock_t begin_clock;
-time_t begin_time;
-int count_flooding, count_login;
-
-#ifdef NOFLOODING
-/* 0 ok, 1 delay action, 2 reject */
-int action_frequently(int uid)
-{
- int i;
- time_t now = time(NULL);
- time_t minute = now/60;
- time_t hour = minute/60;
-
- static time_t flood_base_minute;
- static time_t flood_base_hour;
- static struct {
- unsigned short lastlogin; // truncated time_t
- unsigned char minute_count;
- unsigned char hour_count;
- } flooding[MAX_USERS];
-
- if(minute!=flood_base_minute) {
- for(i=0; i<MAX_USERS; i++)
- flooding[i].minute_count=0;
- flood_base_minute=minute;
- }
- if(hour!=flood_base_hour) {
- for(i=0; i<MAX_USERS; i++)
- flooding[i].hour_count=0;
- flood_base_hour=hour;
- }
-
- if(abs(flooding[uid].lastlogin-(unsigned short)now)<=3 ||
- flooding[uid].minute_count>30 ||
- flooding[uid].hour_count>60) {
- count_flooding++;
- return 2;
- }
-
- flooding[uid].minute_count++;
- flooding[uid].hour_count++;
- flooding[uid].lastlogin=now;
-
- if(flooding[uid].minute_count>5 ||
- flooding[uid].hour_count>20) {
- count_flooding++;
- return 1;
- }
- return 0;
-}
-#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<USHM_SIZE; i++) {
- int uid;
- if( toread(cfd, &uid, sizeof(uid)) <= 0 ||
- toread(cfd, like, sizeof(like)) <= 0 ||
- toread(cfd, hate, sizeof(hate)) <= 0)
- break;
-#ifdef UTMPLOG
- if(logfp) {
- fwrite(&uid, sizeof(uid), 1, logfp);
- fwrite(like, sizeof(like), 1, logfp);
- fwrite(hate, sizeof(hate), 1, logfp);
- }
-#endif
-
- if(uid != 0)
- utmplogin(uid, i, like, hate);
- }
- if(i<USHM_SIZE) {
-#ifdef UTMPLOG
- int x=-2;
- if(logfp) fwrite(&x, sizeof(x), 1, logfp);
-#endif
- }
-
- fprintf(stderr,"sync end\n");
-}
-
-struct client_state {
- struct event ev;
- int state;
- struct evbuffer *evb;
-};
-
-void processlogin(struct client_state *cs, int uid, int index)
-{
- int like[MAX_FRIEND];
- int hate[MAX_REJECT];
- /* logout 銝虫 utmpserver , 航賣亙唬鈭
- 撌脩 logout 撣唾隞乩賢芸 MAX_FRIEND 閬憭銝鈭 */
-#define MAX_FS (2 * MAX_FRIEND)
- int res;
- int nfs;
- ocfs_t fs[MAX_FS];
-
- evbuffer_remove(cs->evb, like, sizeof(like));
- evbuffer_remove(cs->evb, hate, sizeof(hate));
-#ifdef UTMPLOG
- if(logfp) {
- int x=-3;
- fwrite(&x, sizeof(x), 1, logfp);
- fwrite(&uid, sizeof(uid), 1, logfp);
- fwrite(&index, sizeof(index), 1, logfp);
- fwrite(like, sizeof(like), 1, logfp);
- fwrite(hate, sizeof(hate), 1, logfp);
- }
-#endif
-
- utmplogin(uid, index, like, hate);
- nfs=genfriendlist(uid, index, fs, MAX_FS);
- res=0;
-#ifdef NOFLOODING
- res=action_frequently(uid);
-#endif
- evbuffer_drain(cs->evb, 2147483647);
- evbuffer_add(cs->evb, &res, sizeof(res));
- evbuffer_add(cs->evb, &nfs, sizeof(nfs));
- evbuffer_add(cs->evb, fs, sizeof(ocfs_t) * nfs);
-}
-
-void showstat(void)
-{
- clock_t now_clock=clock();
- time_t now_time=time(0);
-
- time_t used_time=now_time-begin_time;
- clock_t used_clock=now_clock-begin_clock;
-
- printf("%.24s : real %.0f cpu %.2f : %d login %d flood, %.2f login/sec, %.2f%% load.\n",
- ctime(&now_time), (double)used_time, (double)used_clock/CLOCKS_PER_SEC,
- count_login, count_flooding,
- (double)count_login/used_time, (double)used_clock/CLOCKS_PER_SEC/used_time*100);
-
- begin_time=now_time;
- begin_clock=now_clock;
- count_login=0;
- count_flooding=0;
-}
-
-enum {
- FSM_ENTER,
- FSM_SYNC,
- FSM_LOGIN,
- FSM_WRITEBACK,
- FSM_EXIT
-};
-
-static int firstsync=0;
-
-struct timeval tv = {5, 0};
-struct event ev;
-int clients = 0;
-
-#define READ_BLOCK 1024
-#define MAX_CLIENTS 10
-
-void connection_client(int cfd, short event, void *arg)
-{
- struct client_state *cs = arg;
- int cmd, break_out = 0;
- int uid = 0, index = 0;
-
- // ignore clients that timeout
- if (event & EV_TIMEOUT)
- cs->state = FSM_EXIT;
-
- if (event & EV_READ) {
- if (cs->state != FSM_ENTER) {
- if (evbuffer_read(cs->evb, cfd, READ_BLOCK) <= 0)
- cs->state = FSM_EXIT;
- }
- else {
- if (evbuffer_read(cs->evb, cfd, 4) <= 0)
- cs->state = FSM_EXIT;
- }
- }
-
- while (!break_out) {
- switch (cs->state) {
- case FSM_ENTER:
- if (EVBUFFER_LENGTH(cs->evb) < sizeof(int)) {
- break_out = 1;
- break;
- }
- evbuffer_remove(cs->evb, &cmd, sizeof(cmd));
- if (cmd == -1)
- cs->state = FSM_SYNC;
- else if (cmd == -2) {
- fcntl(cfd, F_SETFL, fcntl(cfd, F_GETFL, 0) | O_NONBLOCK);
- cs->state = FSM_LOGIN;
- }
- else if (cmd >= 0)
- cs->state = FSM_EXIT;
- else {
- printf("unknown cmd=%d\n",cmd);
- cs->state = FSM_EXIT;
- }
- break;
- case FSM_SYNC:
- syncutmp(cfd);
- firstsync = 1;
- cs->state = FSM_EXIT;
- break;
- case FSM_LOGIN:
- if (firstsync) {
- if (EVBUFFER_LENGTH(cs->evb) < (2 + MAX_FRIEND + MAX_REJECT) * sizeof(int)) {
- break_out = 1;
- break;
- }
- evbuffer_remove(cs->evb, &index, sizeof(index));
- evbuffer_remove(cs->evb, &uid, sizeof(uid));
- if (index >= USHM_SIZE) {
- fprintf(stderr, "bad index=%d\n", index);
- cs->state = FSM_EXIT;
- break;
- }
- count_login++;
- processlogin(cs, uid, index);
- if (count_login >= 4000 || (time(NULL) - begin_time) > 30*60)
- showstat();
- cs->state = FSM_WRITEBACK;
- break_out = 1;
- }
- else
- cs->state = FSM_EXIT;
- break;
- case FSM_WRITEBACK:
- if (event & EV_WRITE)
- if (evbuffer_write(cs->evb, cfd) <= 0 && EVBUFFER_LENGTH(cs->evb) > 0)
- break_out = 1;
- if (EVBUFFER_LENGTH(cs->evb) == 0)
- cs->state = FSM_EXIT;
- break;
- case FSM_EXIT:
- if (clients == MAX_CLIENTS)
- event_add(&ev, NULL);
- close(cfd);
- evbuffer_free(cs->evb);
- free(cs);
- clients--;
- return;
- break;
- }
- }
- if (cs->state == FSM_WRITEBACK)
- event_set(&cs->ev, cfd, EV_WRITE, (void *) connection_client, cs);
- event_add(&cs->ev, &tv);
-}
-
-void connection_accept(int fd, short event, void *arg)
-{
- struct sockaddr_in clientaddr;
- socklen_t len = sizeof(clientaddr);
- int cfd;
-
- if ((cfd = accept(fd, (struct sockaddr *)&clientaddr, &len)) < 0 )
- return;
-
- struct client_state *cs = calloc(1, sizeof(struct client_state));
- cs->state = FSM_ENTER;
- cs->evb = evbuffer_new();
-
- event_set(&cs->ev, cfd, EV_READ, (void *) connection_client, cs);
- event_add(&cs->ev, &tv);
- clients++;
-
- if (clients >= MAX_CLIENTS) {
- event_del(&ev);
- }
-}
-
-int main(int argc, char *argv[])
-{
- int ch, port = 5120, sfd;
- char *iface_ip = NULL;
-
-#ifdef UTMPLOG
- logfp = fopen("utmp.log","a");
- if(logfp && ftell(logfp)> 500*(1<<20)) {
- fclose(logfp);
- logfp=NULL;
- }
-#endif
-
- Signal(SIGPIPE, SIG_IGN);
- 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;
- }
-
- if( (sfd = tobind(iface_ip, port)) < 0 )
- return 1;
-
- event_init();
- event_set(&ev, sfd, EV_READ | EV_PERSIST, connection_accept, &ev);
- event_add(&ev, NULL);
- event_dispatch();
- return 0;
-}
diff --git a/cacheserver/utmpsync.c b/cacheserver/utmpsync.c
deleted file mode 100644
index 69d1c623..00000000
--- a/cacheserver/utmpsync.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-#include <err.h>
-
-extern SHM_t *SHM;
-
-int main(int argc, char **argv)
-{
- int sfd, index, i;
- attach_SHM();
- if( (sfd = toconnect(OUTTACACHEHOST, OUTTACACHEPORT)) < 0 ) {
- printf("connect fail\n");
- return 1;
- }
-
- index = -1;
- towrite(sfd, &index, sizeof(index));
- for( i = 0 ; i < USHM_SIZE ; ++i )
- if( towrite(sfd, &SHM->uinfo[i].uid, sizeof(SHM->uinfo[i].uid)) < 0 ||
- towrite(sfd, SHM->uinfo[i].myfriend,
- sizeof(SHM->uinfo[i].myfriend)) < 0 ||
- towrite(sfd, SHM->uinfo[i].reject,
- sizeof(SHM->uinfo[i].reject)) < 0 ){
- fprintf(stderr, "sync error %d\n", i);
- }
- return 0;
-}