summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorin2 <in2@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2004-04-04 17:59:40 +0800
committerin2 <in2@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2004-04-04 17:59:40 +0800
commit983a7b8ef01b03cc7596751f431277ed7540c713 (patch)
tree9330d2b190001e4f884a8cf8fd58db84094ac39e
parenteb86d8ff553917f392c556ef3a4b846910b1a17a (diff)
downloadpttbbs-983a7b8ef01b03cc7596751f431277ed7540c713.tar
pttbbs-983a7b8ef01b03cc7596751f431277ed7540c713.tar.gz
pttbbs-983a7b8ef01b03cc7596751f431277ed7540c713.tar.bz2
pttbbs-983a7b8ef01b03cc7596751f431277ed7540c713.tar.lz
pttbbs-983a7b8ef01b03cc7596751f431277ed7540c713.tar.xz
pttbbs-983a7b8ef01b03cc7596751f431277ed7540c713.tar.zst
pttbbs-983a7b8ef01b03cc7596751f431277ed7540c713.zip
merge from outtacache branch
git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@1689 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
-rw-r--r--cacheserver/Makefile14
-rw-r--r--cacheserver/README1
-rw-r--r--cacheserver/utmpserver.c143
-rw-r--r--cacheserver/utmpsync.c27
-rw-r--r--include/proto.h8
-rw-r--r--include/pttstruct.h10
-rw-r--r--mbbsd/cal.c7
-rw-r--r--mbbsd/stuff.c69
-rw-r--r--mbbsd/talk.c25
9 files changed, 299 insertions, 5 deletions
diff --git a/cacheserver/Makefile b/cacheserver/Makefile
new file mode 100644
index 00000000..42b077b4
--- /dev/null
+++ b/cacheserver/Makefile
@@ -0,0 +1,14 @@
+# $Id$
+.include "../pttbbs.mk"
+
+PROGRAMS= utmpserver utmpsync
+
+all: ${PROGRAMS}
+
+.for fn in ${PROGRAMS}
+${fn}: ${fn}.c
+ ${CC} ${CFLAGS} ${LDFLAGS} -DPTTBBS_UTIL -o ${fn} ${fn}.c ../util/util_*.o
+.endfor
+
+clean:
+ rm -f *~ ${PROGRAMS}
diff --git a/cacheserver/README b/cacheserver/README
new file mode 100644
index 00000000..3bfeddbc
--- /dev/null
+++ b/cacheserver/README
@@ -0,0 +1 @@
+這是一個測試的東西. 除非確定你知道這個程式在幹什麼, 否則請不理會這個目錄 :P
diff --git a/cacheserver/utmpserver.c b/cacheserver/utmpserver.c
new file mode 100644
index 00000000..60cd02ad
--- /dev/null
+++ b/cacheserver/utmpserver.c
@@ -0,0 +1,143 @@
+/* $Id$ */
+#include "bbs.h"
+#include <err.h>
+
+struct {
+ int uid;
+ int nFriends, nRejects;
+ int friend[MAX_FRIEND];
+ int reject[MAX_REJECT];
+} utmp[USHM_SIZE];
+
+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);
+}
+
+int main(int argc, char **argv)
+{
+ struct sockaddr_in clientaddr;
+ int ch, port = 5120, sfd, cfd, len, index, i, uid;
+
+ while( (ch = getopt(argc, argv, "p:h")) != -1 )
+ switch( ch ){
+ case 'p':
+ port = atoi(optarg);
+ break;
+
+ case 'h':
+ default:
+ fprintf(stderr, "usage: utmpserver [-p port]\n");
+ return 1;
+ }
+
+ if( (sfd = tobind(port)) < 0 )
+ return 1;
+
+ while( 1 ){
+ 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 ){
+ int nSynced = 0;
+ 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);
+ continue;
+ }
+
+ if( toread(cfd, &uid, sizeof(uid)) > 0 &&
+ toread(cfd, utmp[index].friend, sizeof(utmp[index].friend)) > 0 &&
+ toread(cfd, utmp[index].reject, sizeof(utmp[index].reject)) > 0 ){
+#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);
+ }
+ return 0;
+}
diff --git a/cacheserver/utmpsync.c b/cacheserver/utmpsync.c
new file mode 100644
index 00000000..13ffcf4e
--- /dev/null
+++ b/cacheserver/utmpsync.c
@@ -0,0 +1,27 @@
+/* $Id$ */
+#include "bbs.h"
+#include <err.h>
+
+extern SHM_t *SHM;
+int towrite(int fd, void *buf, int len);
+int toconnect(char *host, int port);
+
+int main(int argc, char **argv)
+{
+ int sfd, index, i;
+ attach_SHM();
+ if( (sfd = toconnect(OUTTACACHEHOST, OUTTACACHEPORT)) < 0 )
+ 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].friend,
+ sizeof(SHM->uinfo[i].friend)) < 0 ||
+ towrite(sfd, SHM->uinfo[i].reject,
+ sizeof(SHM->uinfo[i].reject)) < 0 ){
+ fprintf(stderr, "sync error %d\n", i);
+ }
+ return 0;
+}
diff --git a/include/proto.h b/include/proto.h
index 2828a196..9851a9e0 100644
--- a/include/proto.h
+++ b/include/proto.h
@@ -523,6 +523,12 @@ int qsort_intcompar(const void *a, const void *b);
void *MALLOC(int size);
void FREE(void *ptr);
#endif
+#ifdef OUTTACACHE
+int tobind(int port);
+int toconnect(char *host, int port);
+int toread(int fd, void *buf, int len);
+int towrite(int fd, void *buf, int len);
+#endif
/* syspost */
int post_msg(char* bname, char* title, char *msg, char* author);
@@ -559,7 +565,7 @@ int t_talk();
int t_display();
int my_query(char *uident);
int logout_friend_online();
-int login_friend_online();
+void login_friend_online();
int isvisible_uid(int tuid);
int friend_stat(userinfo_t *me, userinfo_t * ui);
int call_in(userinfo_t *uentp, int fri_stat);
diff --git a/include/pttstruct.h b/include/pttstruct.h
index 9f950c92..5895c31d 100644
--- a/include/pttstruct.h
+++ b/include/pttstruct.h
@@ -477,4 +477,14 @@ typedef struct
time_t chrono;
int recno;
} TagItem;
+
+#ifdef OUTTACACHE
+typedef struct {
+ int index; // 在 SHM->uinfo[index]
+ int uid; // 避免在 cache server 上不同步, 再確認用.
+ int friendstat;
+ int rfriendstat;
+} ocfs_t;
+#endif
+
#endif
diff --git a/mbbsd/cal.c b/mbbsd/cal.c
index 462818de..43c0d2f5 100644
--- a/mbbsd/cal.c
+++ b/mbbsd/cal.c
@@ -431,9 +431,14 @@ p_sysinfo(void)
prints("記憶體用量: sbrk: %d KB, idrss: %d KB, isrss: %d KB\n",
((int)sbrk(0) - 0x8048000) / 1024,
(int)ru.ru_idrss, (int)ru.ru_isrss);
+ prints("特別參數:"
#ifdef CRITICAL_MEMORY
- prints("目前在 CRITICAL_MEMORY 模式下\n");
+ " CRITICAL_MEMORY"
#endif
+#ifdef OUTTACACHE
+ " OUTTACACHE"
+#endif
+ );
}
pressanykey();
return 0;
diff --git a/mbbsd/stuff.c b/mbbsd/stuff.c
index 767fdca1..008f18f9 100644
--- a/mbbsd/stuff.c
+++ b/mbbsd/stuff.c
@@ -694,3 +694,72 @@ int qsort_intcompar(const void *a, const void *b)
{
return *(int *)a - *(int *)b;
}
+
+#ifdef OUTTACACHE
+#include <err.h>
+int tobind(int port)
+{
+ int sockfd, val;
+ struct sockaddr_in servaddr;
+
+ if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
+ err(1, NULL);
+ setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
+ (char *)&val, sizeof(val));
+ bzero(&servaddr, sizeof(servaddr));
+ servaddr.sin_family = AF_INET;
+ servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ servaddr.sin_port = htons(port);
+ if( bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0 )
+ err(1, NULL);
+ if( listen(sockfd, 5) < 0 )
+ err(1, NULL);
+
+ return sockfd;
+}
+
+int toconnect(char *host, int port)
+{
+ int sock;
+ struct sockaddr_in serv_name;
+ if( (sock = socket(AF_INET, SOCK_STREAM, 0)) < 0 ){
+ perror("socket");
+ return -1;
+ }
+
+ serv_name.sin_family = AF_INET;
+ serv_name.sin_addr.s_addr = inet_addr(host);
+ serv_name.sin_port = htons(port);
+ if( connect(sock, (struct sockaddr*)&serv_name, sizeof(serv_name)) < 0 ){
+ close(sock);
+ return -1;
+ }
+ return sock;
+}
+
+int toread(int fd, void *buf, int len)
+{
+ int l;
+ for( l = 0 ; len > 0 ; )
+ if( (l = read(fd, buf, len)) <= 0 )
+ return -1;
+ else{
+ buf += l;
+ len -= l;
+ }
+ return l;
+}
+
+int towrite(int fd, void *buf, int len)
+{
+ int l;
+ for( l = 0 ; len > 0 ; )
+ if( (l = write(fd, buf, len)) <= 0 )
+ return -1;
+ else{
+ buf += l;
+ len -= l;
+ }
+ return l;
+}
+#endif
diff --git a/mbbsd/talk.c b/mbbsd/talk.c
index 8052ae5a..23a5a305 100644
--- a/mbbsd/talk.c
+++ b/mbbsd/talk.c
@@ -210,12 +210,31 @@ reverse_friend_stat(int stat)
return stat1;
}
-int
-login_friend_online(void)
+void login_friend_online(void)
{
userinfo_t *uentp;
int i, stat, stat1;
int offset = (int)(currutmp - &SHM->uinfo[0]);
+#ifdef OUTTACACHE
+ int sfd;
+ if( (sfd = toconnect(OUTTACACHEHOST, OUTTACACHEPORT)) > 0 ){
+ if( towrite(sfd, &offset, sizeof(offset)) > 0 &&
+ towrite(sfd, &currutmp->uid, sizeof(currutmp->uid)) > 0 &&
+ towrite(sfd, currutmp->friend, sizeof(currutmp->friend)) > 0 &&
+ towrite(sfd, currutmp->reject, sizeof(currutmp->reject)) > 0 ){
+ ocfs_t fs;
+ while( toread(sfd, &fs, sizeof(fs)) > 0 )
+ if( SHM->uinfo[fs.index].uid == fs.uid ){
+ currutmp->friend_online[currutmp->friendtotal++]
+ = fs.friendstat;
+ SHM->uinfo[fs.index].friend_online[ SHM->uinfo[fs.index].friendtotal++ ] = fs.rfriendstat;
+ }
+ close(sfd);
+ return;
+ }
+ close(sfd);
+ }
+#endif
for (i = 0; i < SHM->UTMPnumber && currutmp->friendtotal < MAX_FRIEND; i++) {
uentp = (SHM->sorted[SHM->currsorted][0][i]);
if (uentp && uentp->uid && (stat = set_friend_bit(currutmp, uentp))) {
@@ -230,7 +249,7 @@ login_friend_online(void)
}
}
}
- return 0;
+ return;
}
int