diff options
author | in2 <in2@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2002-03-07 23:13:44 +0800 |
---|---|---|
committer | in2 <in2@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2002-03-07 23:13:44 +0800 |
commit | ae31e19f92e717919ac8e3db9039eb38d2b89aae (patch) | |
tree | c70164d6a1852344f44b04a653ae2815043512af /util | |
download | pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.gz pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.bz2 pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.lz pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.xz pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.zst pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.zip |
Initial revision
git-svn-id: http://opensvn.csie.org/pttbbs/pttbbs/trunk/pttbbs@1 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
Diffstat (limited to 'util')
78 files changed, 13046 insertions, 0 deletions
diff --git a/util/.cvsignore b/util/.cvsignore new file mode 100644 index 00000000..e7408563 --- /dev/null +++ b/util/.cvsignore @@ -0,0 +1,42 @@ +bbsmail +BM_money +post +account +birth +deluserfile +expire +mandex +horoscope +openvice +parse_news +openticket +bmda +uhash_loader +poststat +showboard +topusr +yearsold +cutpasswd +inndBM +antispam +countalldice +webgrep +bbsrf +initbbs +outmail +xchatd +userlist +tunepasswd +buildir +reaper +shmsweep +merge_passwd +merge_board +cpdeadbrd +rmuid +buildAnnounce +toplazyBBM +toplazyBM +jungo +bbsctl +daymandex diff --git a/util/BM_money.c b/util/BM_money.c new file mode 100644 index 00000000..51e24c38 --- /dev/null +++ b/util/BM_money.c @@ -0,0 +1,117 @@ +/* $Id: BM_money.c,v 1.1 2002/03/07 15:13:45 in2 Exp $ */ + +/* µ¹ª©¥D¿úªºµ{¦¡ */ + +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/types.h> +#include "config.h" +#include "pttstruct.h" +#include "util.h" +#include "common.h" + +#define FUNCTION (2100 - c*5) + +extern int numboards; +extern boardheader_t *bcache; +extern struct UCACHE *uidshm; + +int c, n; +extern userec_t xuser; + + + +int Link(char *src, char *dst) { + char cmd[200]; + + if (link(src, dst) == 0) + return 0; + + sprintf(cmd, "/bin/cp -R %s %s", src, dst); + return system(cmd); +} + + +int main() { + FILE *fp = fopen(BBSHOME "/etc/topboardman", "r"); + char buf[201], bname[20], BM[90], *ch; + boardheader_t *bptr = NULL; + int nBM; + + resolve_boards(); + if(passwd_mmap()) + exit(1); + if (!fp) + return 0; + + c = 0; + fgets(buf, 200, fp); /* ²Ä¤@¦æ®³±¼ */ + + printf( + " \033[1;44m ¼úÀyÀu¨}ª©¥D ¨C¶gªáÁ~ ¨ÌºëµØ°Ï±Æ¦W¤À°t \033[m\n\n" + "\033[33m (±Æ¦W¤Ó«á±©Î´X¥G¨S¦³ºëµØ°ÏªÌ¤£¦C¤J)\033[m\n" + " ¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w\n" + "\n\n"); + + while (fgets(buf, 200, fp) != NULL) + { + buf[24] = 0; + sscanf(&buf[9], "%s", bname); + for (n = 0; n < numboards; n++) + { + bptr = &bcache[n]; + if (!strcmp(bptr->brdname, bname)) + break; + } + if (n == numboards) + continue; + strcpy(BM, bptr->BM); + printf(" (%d) %-15.15s %s \n", c + 1, bptr->brdname, bptr->title); + + if (BM[0] == 0 || BM[0] == ' ') + continue; + + ch = BM; + for (nBM = 1; (ch = strchr(ch, '/')) != NULL; nBM++) + { + ch++; + }; + ch = BM; + + if (FUNCTION <= 0) + break; + + printf(" ¼úª÷ \033[32m%6d \033[m ¤Àµ¹ \033[33m%s\033[m \n", + FUNCTION, bptr->BM); + + for (n = 0; n < nBM; n++) + { + fileheader_t mymail; + char *ch1,uid ; + if((ch1 = strchr(ch, '/'))) + *ch1 = 0; + if ((uid=getuser(ch))!=0) + { + + char genbuf[200]; + deumoney(uid,FUNCTION / nBM); + sprintf(genbuf, BBSHOME "/home/%c/%s", ch[0], ch); + stampfile(genbuf, &mymail); + + strcpy(mymail.owner, "[Á~¤ô³U]"); + sprintf(mymail.title, + "\033[32m %s \033[mª©ªºÁ~¤ô ¢C\033[33m%d\033![m", bptr->brdname, FUNCTION / nBM); + mymail.savemode = 0; + unlink(genbuf); + Link(BBSHOME "/etc/BM_money", genbuf); + sprintf(genbuf, BBSHOME "/home/%c/%s/.DIR", ch[0], ch); + append_record(genbuf, &mymail, sizeof(mymail)); + } + ch = ch1 + 1; + } + c++; + } + return 0; +} diff --git a/util/BM_money.sh b/util/BM_money.sh new file mode 100644 index 00000000..8bef4fc9 --- /dev/null +++ b/util/BM_money.sh @@ -0,0 +1,5 @@ +#!/bin/sh +# $Id: BM_money.sh,v 1.1 2002/03/07 15:13:45 in2 Exp $ + +bin/BM_money > etc/BM_money +bin/post Record ¬P´Á¤' 'ª©¥DµoÁ~¤é [°]ª÷®ø®§] etc/BM_money diff --git a/util/BOARDS.bid b/util/BOARDS.bid Binary files differnew file mode 100644 index 00000000..8d0312e5 --- /dev/null +++ b/util/BOARDS.bid diff --git a/util/DEADJOE b/util/DEADJOE new file mode 100644 index 00000000..a0793f05 --- /dev/null +++ b/util/DEADJOE @@ -0,0 +1,9 @@ + +*** Modified files in JOE when it aborted on Thu Nov 22 19:30:21 2001 +*** JOE was aborted by signal 1 + +*** Modified files in JOE when it aborted on Mon Nov 26 09:50:15 2001 +*** JOE was aborted because the terminal closed + +*** File '(Unnamed)' +BBSNAME diff --git a/util/LocalVars.pm.sample b/util/LocalVars.pm.sample new file mode 100644 index 00000000..67157009 --- /dev/null +++ b/util/LocalVars.pm.sample @@ -0,0 +1,22 @@ +#!/usr/bin/perl +package LocalVars; +require Exporter; +@ISA = qw/Exporter/; +@EXPORT = qw/ + $hostname $FQDN $SMTPSERVER + $BBSHOME $JOBSPOOL $TMP + $TAR/; + +# host +$hostname = 'ptt'; +$FQDN = 'ptt.csie.ntu.edu.tw'; +$SMTPSERVER = 'ptt2.csie.ntu.edu.tw'; + +# dir +$BBSHOME = '/home/bbs'; +$JOBSPOOL = "$BBSHOME/jobspool"; +$TMP = '/tmp'; + +# program +$TAR = '/bin/tar'; + diff --git a/util/Makefile b/util/Makefile new file mode 100644 index 00000000..eeacad38 --- /dev/null +++ b/util/Makefile @@ -0,0 +1,167 @@ +# $Id: Makefile,v 1.1 2002/03/07 15:13:45 in2 Exp $ + +BBSHOME?=$(HOME) +OSTYPE=linux + +# FreeBSD +CC_FreeBSD= gcc +CFLAGS_FreeBSD= -pipe -Wall -g -O3 -DHAVE_SETPROCTITLE -DBBSHOME='"$(BBSHOME)"' -I../include +LIBS_FreeBSD= +LIBMAIL_FreeBSD=-lutil +LIBCHAT_FreeBSD= + +# Linux +CC_linux= gcc +CFLAGS_linux= -pipe -Wall -g -O3 -DHAVE_DES_CRYPT -DBBSHOME='"$(BBSHOME)"' -I../include +LIBS_linux= -lresolv +LIBMAIL_linux= +LIBCHAT_linux= -lcrypt + +CC= $(CC_$(OSTYPE)) +CFLAGS= $(CFLAGS_$(OSTYPE)) +LDFLAGS=$(LDFLAGS_$(OSTYPE)) +LIBMAIL=$(LIBMAIL_$(OSTYPE)) +LIBCHAT=$(LIBCHAT_$(OSTYPE)) + +OBJS= util_cache.o util_record.o util_passwd.o + +CPROGS= bbsmail BM_money post account birth deluserfile expire mandex\ + horoscope openvice parse_news openticket topusr yearsold uhash_loader\ + poststat showboard antispam countalldice webgrep bbsrf\ + initbbs outmail xchatd userlist tunepasswd buildir reaper shmsweep\ + merge_passwd merge_board inndBM buildAnnounce rmuid cpdeadbrd \ + toplazyBM jungo toplazyBBM daymandex + +PROGS= $(CPROGS) BM_money.sh backpasswd.sh mailog.sh opendice.sh\ + openticket.sh stock.sh topsong.sh weather.sh stock.perl weather.perl\ + toplazyBM.sh toplazyBBM.sh dailybackup.pl tarqueue.pl waterball.pl + +all: $(PROGS) + +bbsmail: bbsmail.c $(OBJS) + $(CC) $(CFLAGS) -o $@ $@.c $(OBJS) + +BM_money: BM_money.c $(OBJS) + $(CC) $(CFLAGS) -o $@ $@.c $(OBJS) + +post: post.c $(OBJS) + $(CC) $(CFLAGS) -o $@ $@.c $(OBJS) + +jungo: jungo.c $(OBJS) + $(CC) $(CFLAGS) -o $@ $@.c $(OBJS) + +account: account.c $(OBJS) + $(CC) $(CFLAGS) -o $@ $@.c $(OBJS) + +birth: birth.c $(OBJS) + $(CC) $(CFLAGS) -o $@ $@.c $(OBJS) + +deluserfile: deluserfile.c $(OBJS) + $(CC) $(CFLAGS) -o $@ $@.c $(OBJS) + +expire: expire.c $(OBJS) + $(CC) $(CFLAGS) -o $@ $@.c $(OBJS) + +mandex: mandex.c $(OBJS) + $(CC) $(CFLAGS) -o $@ $@.c $(OBJS) + +daymandex: daymandex.c $(OBJS) + $(CC) $(CFLAGS) -o $@ $@.c $(OBJS) + +rmuid: rmuid.c $(OBJS) + $(CC) $(CFLAGS) -o $@ $@.c $(OBJS) + +cpdeadbrd: cpdeadbrd.c $(OBJS) + $(CC) $(CFLAGS) -o $@ $@.c $(OBJS) + +horoscope: horoscope.c $(OBJS) + $(CC) $(CFLAGS) -o $@ $@.c $(OBJS) + +openvice: openvice.c $(OBJS) + $(CC) $(CFLAGS) -o $@ $@.c $(OBJS) + +parse_news: parse_news.c $(OBJS) + $(CC) $(CFLAGS) -o $@ $@.c $(OBJS) + +openticket: openticket.c $(OBJS) + $(CC) $(CFLAGS) -o $@ $@.c $(OBJS) + +topusr: topusr.c $(OBJS) + $(CC) $(CFLAGS) -o $@ $@.c $(OBJS) + +yearsold: yearsold.c $(OBJS) + $(CC) $(CFLAGS) -o $@ $@.c $(OBJS) + +xchatd: xchatd.c $(OBJS) descrypt.c + $(CC) $(CFLAGS) -o $@ $@.c $(OBJS) descrypt.c $(LIBCHAT) + +toplazyBM: toplazyBM.c $(OBJS) + $(CC) $(CFLAGS) -o $@ $@.c $(OBJS) + +toplazyBBM: toplazyBBM.c $(OBJS) + $(CC) $(CFLAGS) -o $@ $@.c $(OBJS) + +smtest: smtest.c $(OBJS) + $(CC) $(CFLAGS) -o $@ $@.c $(OBJS) + +reaper: reaper.c $(OBJS) + $(CC) $(CFLAGS) -o $@ $@.c $(OBJS) + +buildAnnounce: buildAnnounce.c $(OBJS) + $(CC) $(CFLAGS) -o $@ $@.c $(OBJS) + +inndBM: inndBM.c $(OBJS) + $(CC) $(CFLAGS) -o $@ $@.c $(OBJS) + +shmsweep: shmsweep.c + $(CC) $(CFLAGS) -o $@ $@.c + +uhash_loader: uhash_loader.c + $(CC) $(CFLAGS) -o $@ $@.c + +showboard: showboard.c + $(CC) $(CFLAGS) -o $@ $@.c + +antispam: antispam.c + $(CC) $(CFLAGS) -o $@ $@.c + +countalldice: countalldice.c + $(CC) $(CFLAGS) -o $@ $@.c + +webgrep: webgrep.c + $(CC) $(CFLAGS) -o $@ $@.c + +bbsrf: bbsrf.c + $(CC) $(CFLAGS) -o $@ $@.c + +initbbs: initbbs.c + $(CC) $(CFLAGS) -o $@ $@.c + +outmail: outmail.c + $(CC) $(CFLAGS) -o $@ $@.c $(LIBMAIL) + +userlist: userlist.c + $(CC) $(CFLAGS) -o $@ $@.c + +tunepasswd: tunepasswd.c + $(CC) $(CFLAGS) -o $@ $@.c + +buildir: buildir.c + $(CC) $(CFLAGS) -o $@ $@.c + +merge_passwd: merge_passwd.c + $(CC) $(CFLAGS) -o $@ $@.c + +merge_board : merge_board.c + $(CC) $(CFLAGS) -o $@ $@.c + +bbsctl: bbsctl.c + $(CC) $(CFLAGS) -o $@ $@.c + +install: $(PROGS) + install -d $(BBSHOME)/bin/ + install -c -m 755 $(PROGS) $(BBSHOME)/bin/ + chmod 4755 $(BBSHOME)/bin/post + +clean: + rm -f *.o $(CPROGS) diff --git a/util/Makefile.save b/util/Makefile.save new file mode 100644 index 00000000..2d0651b1 --- /dev/null +++ b/util/Makefile.save @@ -0,0 +1,152 @@ +# $Id: Makefile.save,v 1.1 2002/03/07 15:13:45 in2 Exp $ + +BBSHOME?=$(HOME) +OSTYPE=linux + +# FreeBSD +CC_FreeBSD= gcc +CFLAGS_FreeBSD= -pipe -Wall -g -O3 -DHAVE_SETPROCTITLE -DBBSHOME='"$(BBSHOME)"' -I../include +LIBS_FreeBSD= +LIBMAIL_FreeBSD=-lutil +LIBCHAT_FreeBSD= + +# Linux +CC_linux= gcc +CFLAGS_linux= -pipe -Wall -g -O3 -DHAVE_DES_CRYPT -DBBSHOME='"$(BBSHOME)"' -I../include +LIBS_linux= -lresolv +LIBMAIL_linux= +LIBCHAT_linux= -lcrypt + +CC= $(CC_$(OSTYPE)) +CFLAGS= $(CFLAGS_$(OSTYPE)) +LDFLAGS=$(LDFLAGS_$(OSTYPE)) +LIBMAIL=$(LIBMAIL_$(OSTYPE)) +LIBCHAT=$(LIBCHAT_$(OSTYPE)) + +CPROGS= bbsmail BM_money post account birth deluserfile expire mandex\ + horoscope openvice parse_news openticket topusr yearsold uhash_loader\ + poststat showboard antispam countalldice webgrep bbsrf\ + initbbs outmail xchatd userlist tunepasswd buildir reaper shmsweep\ + merge_passwd merge_board inndBM buildAnnounce cpdeadbrd toplazyBM\ + jungo +PROGS= $(CPROGS) BM_money.sh backpasswd.sh mailog.sh opendice.sh\ + openticket.sh stock.sh topsong.sh weather.sh stock.perl weather.perl\ + cvslog.sh toplazyBM.sh + +all: $(PROGS) + +bbsmail: bbsmail.c util_cache.c util_record.c util_passwd.c + $(CC) $(CFLAGS) -o $@ $@.c util_cache.c util_record.c util_passwd.c + +BM_money: BM_money.c util_cache.c util_record.c util_passwd.c + $(CC) $(CFLAGS) -o $@ $@.c util_cache.c util_record.c util_passwd.c + +post: post.c util_cache.c util_record.c util_passwd.c + $(CC) $(CFLAGS) -o $@ $@.c util_cache.c util_record.c util_passwd.c + +account: account.c util_cache.c util_record.c util_passwd.c + $(CC) $(CFLAGS) -o $@ $@.c util_cache.c util_record.c util_passwd.c + +birth: birth.c util_cache.c util_record.c util_passwd.c + $(CC) $(CFLAGS) -o $@ $@.c util_cache.c util_record.c util_passwd.c + +deluserfile: deluserfile.c util_cache.c util_record.c util_passwd.c + $(CC) $(CFLAGS) -o $@ $@.c util_cache.c util_record.c util_passwd.c + +expire: expire.c util_cache.c util_record.c util_passwd.c + $(CC) $(CFLAGS) -o $@ $@.c util_cache.c util_record.c util_passwd.c + +mandex: mandex.c util_cache.c util_record.c util_passwd.c + $(CC) $(CFLAGS) -o $@ $@.c util_cache.c util_record.c util_passwd.c + +cpdeadbrd: cpdeadbrd.c util_cache.c util_record.c util_passwd.c + $(CC) $(CFLAGS) -o $@ $@.c util_cache.c util_record.c util_passwd.c + +horoscope: horoscope.c util_cache.c util_record.c util_passwd.c + $(CC) $(CFLAGS) -o $@ $@.c util_cache.c util_record.c util_passwd.c + +openvice: openvice.c util_cache.c util_record.c util_passwd.c + $(CC) $(CFLAGS) -o $@ $@.c util_cache.c util_record.c util_passwd.c + +parse_news: parse_news.c util_cache.c util_record.c util_passwd.c + $(CC) $(CFLAGS) -o $@ $@.c util_cache.c util_record.c util_passwd.c + +openticket: openticket.c util_cache.c util_record.c util_passwd.c + $(CC) $(CFLAGS) -o $@ $@.c util_cache.c util_record.c util_passwd.c + +topusr: topusr.c util_cache.c util_record.c util_passwd.c + $(CC) $(CFLAGS) -o $@ $@.c util_cache.c util_record.c util_passwd.c + +yearsold: yearsold.c util_cache.c util_record.c util_passwd.c + $(CC) $(CFLAGS) -o $@ $@.c util_cache.c util_record.c util_passwd.c + +xchatd: xchatd.c util_cache.c util_record.c util_passwd.c descrypt.c + $(CC) $(CFLAGS) -o $@ $@.c util_cache.c util_record.c util_passwd.c descrypt.c $(LIBCHAT) + +toplazyBM: toplazyBM.c util_cache.c util_record.c util_passwd.c + $(CC) $(CFLAGS) -o $@ $@.c util_cache.c util_record.c util_passwd.c + +jungo: jungo.c util_cache.c util_record.c util_passwd.c + $(CC) $(CFLAGS) -o $@ $@.c util_cache.c util_record.c util_passwd.c + +smtest: smtest.c util_cache.c util_record.c util_passwd.c + $(CC) $(CFLAGS) -o $@ $@.c util_cache.c util_record.c util_passwd.c + +reaper: reaper.c util_passwd.c + $(CC) $(CFLAGS) -o $@ $@.c util_passwd.c util_cache.c util_passwd.c + +buildAnnounce: buildAnnounce.c + $(CC) $(CFLAGS) -o $@ $@.c util_record.c util_cache.c util_passwd.c + +inndBM: inndBM.c + $(CC) $(CFLAGS) -o $@ $@.c util_record.c util_cache.c util_passwd.c + +shmsweep: shmsweep.c + $(CC) $(CFLAGS) -o $@ $@.c + +uhash_loader: uhash_loader.c + $(CC) $(CFLAGS) -o $@ $@.c + +showboard: showboard.c + $(CC) $(CFLAGS) -o $@ $@.c + +antispam: antispam.c + $(CC) $(CFLAGS) -o $@ $@.c + +countalldice: countalldice.c + $(CC) $(CFLAGS) -o $@ $@.c + +webgrep: webgrep.c + $(CC) $(CFLAGS) -o $@ $@.c + +bbsrf: bbsrf.c + $(CC) $(CFLAGS) -o $@ $@.c + +initbbs: initbbs.c + $(CC) $(CFLAGS) -o $@ $@.c + +outmail: outmail.c + $(CC) $(CFLAGS) -o $@ $@.c $(LIBMAIL) + +userlist: userlist.c + $(CC) $(CFLAGS) -o $@ $@.c + +tunepasswd: tunepasswd.c + $(CC) $(CFLAGS) -o $@ $@.c + +buildir: buildir.c + $(CC) $(CFLAGS) -o $@ $@.c + +merge_passwd: merge_passwd.c + $(CC) $(CFLAGS) -o $@ $@.c + +merge_board : merge_board.c + $(CC) $(CFLAGS) -o $@ $@.c + +install: $(PROGS) + install -d $(BBSHOME)/bin/ + install -c -m 755 $(PROGS) $(BBSHOME)/bin/ + chmod 4755 $(BBSHOME)/bin/post + +clean: + rm -f $(CPROGS) diff --git a/util/a.out b/util/a.out Binary files differnew file mode 100644 index 00000000..f4032dc4 --- /dev/null +++ b/util/a.out diff --git a/util/account.c b/util/account.c new file mode 100644 index 00000000..e4166092 --- /dev/null +++ b/util/account.c @@ -0,0 +1,414 @@ +/* $Id: account.c,v 1.1 2002/03/07 15:13:45 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <sys/types.h> +#include <sys/stat.h> +#include "config.h" +#include "pttstruct.h" +#include "util.h" + +#define MAX_LINE 16 +#define ADJUST_M 6 /* adjust back 5 minutes */ + +extern struct pttcache_t *ptt; + +void + reset_garbage() +{ + if (ptt == NULL) + { + ptt = attach_shm(PTTSHM_KEY, sizeof(*ptt)); + if (ptt->touchtime == 0) + ptt->touchtime = 1; + } + +/* ¤£¾ãÓreload? + for(n=0;n<=ptt->max_film;n++) + printf("\n**%d**\n %s \n",n,ptt->notes[n]); + */ + ptt->uptime = 0; + reload_pttcache(); + + printf("\n°ÊºA¬ÝªO¼Æ[%d]\n", ptt->max_film); +/* + for(n=0; n<MAX_MOVIE_SECTION; n++) + printf("sec%d=> °_ÂI:%d ¤U¦¸n´«ªº:%d\n ",n,ptt->n_notes[n], + ptt->next_refresh[n]); + printf("\n"); +*/ +} + +void +keeplog(fpath, board, title) + char *fpath; + char *board; + char *title; +{ + fileheader_t fhdr; + int bid; + char genbuf[256], buf[256]; + + if (!board) + board = "Record"; + + + sprintf(genbuf, "boards/%s", board); + stampfile(genbuf, &fhdr); + sprintf(buf, "mv %s %s", fpath, genbuf); + system(buf); +/* + printf("keep record:[%s][%s][%s][%s]\n",fpath, board, title,genbuf); +*/ + strcpy(fhdr.title, title); + strcpy(fhdr.owner, "[¾ú¥v¦Ñ®v]"); + sprintf(genbuf, "boards/%s/.DIR", board); + append_record(genbuf, &fhdr, sizeof(fhdr)); + if((bid = getbnum(board)) > 0)touchbtotal(bid); + +} + + +static void +my_outs(fp, buf, mode) + FILE *fp; + char buf[], mode; +{ + static char state = '0'; + + if (state != mode) + fprintf(fp, "[3%cm", state = mode); + if (buf[0]) + { + fprintf(fp, buf); + buf[0] = 0; + } +} + + +void gzip(source, target, stamp) + char *source, *target, *stamp; +{ + char buf[128]; + sprintf(buf, "gzip -f9n adm/%s%s", target, stamp); + rename(source, &buf[14]); + system(buf); +} + +extern struct fromcache_t *fcache; +extern uhash_t *uhash; + +int main() { + int hour, max, item, total, i, j, mo, da, max_user = 0, max_login = 0, + max_reg = 0, mahour = 0, k; + char *act_file = ".act"; + char *log_file = "usies"; + char buf[256], buf1[256], *p; + FILE *fp, *fp1; + int act[27]; /* ¦¸¼Æ/²Öp®É¶¡/pointer */ + time_t now; + struct tm *ptime; + + now = time(NULL) - ADJUST_M * 60; /* back to ancent */ + ptime = localtime(&now); + + memset(act, 0, sizeof(act)); + printf("¦¸¼Æ/²Öp®É¶¡\n"); + if ((ptime->tm_hour != 0) && (fp = fopen(act_file, "r"))) + { + fread(act, sizeof(act), 1, fp); + fclose(fp); + } + if ((fp = fopen(log_file, "r")) == NULL) + { + printf("cann't open usies\n"); + return 1; + } + if (act[26]) + fseek(fp, act[26], 0); + while (fgets(buf, 256, fp)) + { + buf[11+2]=0; + hour = atoi(buf + 11); + if (hour < 0 || hour > 23) + { + continue; + } +//"09/06/1999 17:44:58 Mon " +// 012345678901234567890123 + if (strstr(buf + 20, "ENTER")) + { + act[hour]++; + continue; + } + if ((p = (char *) strstr(buf + 40, "Stay:"))) + { + if((hour = atoi(p + 5))) { + act[24] += hour; + act[25]++; + } + continue; + } + } + act[26] = ftell(fp); + fclose(fp); + for (i = max = total = 0; i < 24; i++) + { + total += act[i]; + if (act[i] > max) + { + max_user = max = act[i]; + mahour = i; + } + } + item = max / MAX_LINE + 1; + + if (!ptime->tm_hour) + { + keeplog("etc/today", "Record", "¤W¯¸¤H¦¸²Îp"); + keeplog("etc/money", "Security", "¥»¤éª÷¿ú©¹¨Ó°O¿ý"); + keeplog("etc/illegal_money", "Security", "¥»¤é¹HªkÁÈ¿ú°O¿ý"); + keeplog("etc/chicken", "Record", "Âû³õ³ø§i"); + } + + printf("¤W¯¸¤H¦¸²Îp\n"); + if ((fp = fopen("etc/today", "w")) == NULL) + { + printf("cann't open etc/today\n"); + return 1; + } + fprintf(fp, "\t\t\t[1;33;46m ¨C¤p®É¤W¯¸¤H¦¸²Îp [%02d/%02d/%02d] [40m\n\n", ptime->tm_year % 100, ptime->tm_mon + 1, ptime->tm_mday); + for (i = MAX_LINE + 1; i > 0; i--) + { + strcpy(buf, " "); + for (j = 0; j < 24; j++) + { + max = item * i; + hour = act[j]; + if (hour && (max > hour) && (max - item <= hour)) + { + my_outs(fp, buf, '3'); + fprintf(fp, "%-3d", hour / 10); + } + else if (max <= hour) + { + my_outs(fp, buf, '4'); + fprintf(fp, "¢i "); + } + else + strcat(buf, " "); + } + fprintf(fp, "\n"); + } + fprintf(fp, " [32m" + "0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23\n\n" + "\t [34m³æ¦ì: [37m10[34m ¤H"); + fprintf(fp, " Á`¦@¤W¯¸¤H¦¸¡G[37m%-7d[34m¥§¡¨Ï¥Î¤H¼Æ¡G[37m%d\n", total, total / 24); + fclose(fp); + + if((fp = fopen(act_file, "w"))) { + fwrite(act, sizeof(act), 1, fp); + fclose(fp); + } + +/* -------------------------------------------------------------- */ + + sprintf(buf, "-%02d%02d%02d", + ptime->tm_year % 100, ptime->tm_mon + 1, ptime->tm_mday); + + now += ADJUST_M * 60; /* back to future */ + + + printf("¾ú¥v¨Æ¥ó³B²z\n"); +/* Ptt ¾ú¥v¨Æ¥ó³B²z */ + if((fp = fopen("etc/history.data", "r"))) { /*³Ì¦h¦P®É¤W½u */ + if (fscanf(fp, "%d %d %d %d", &max_login, &max, &max_reg, &k)) + { + int a; + resolve_fcache(); + printf("¦¹®É¬q³Ì¦h¦P®É¤W½u:%d ¹L¥h:%d\n", a = fcache->max_user, k); + fclose(fp); + if (a > k) + { + ptime = localtime(&fcache->max_time); + if((fp1 = fopen("etc/history", "a"))) + { + fprintf(fp1, + "¡· ¡i%02d/%02d/%02d %02d:%02d¡j" + "[32m¦P®É¦b§{¤º¤H¼Æ[mº¦¸¹F¨ì [1;36m%d[m ¤H¦¸\n", + ptime->tm_mon + 1, ptime->tm_mday, ptime->tm_year % 100, + ptime->tm_hour, ptime->tm_min, a); + fclose(fp1); + } + if((fp = fopen("etc/history.data", "w"))) + { + fprintf(fp, "%d %d %d %d", max_login, max, max_reg, a); + fclose(fp); + } + } + } + else + fclose(fp); + } + ptime = localtime(&now); + + if (ptime->tm_hour) + { + /* rotate one line in today_is */ + puts("¦hÓ¸`¤é³B²z"); + if((fp1 = fopen("etc/today_is", "r"))) { + char tod[100][20]; + + i = 0; + while(i < 100 && fgets(tod[i], sizeof(tod[0]), fp1)) + i++; + fclose(fp1); + + fp1 = fopen("etc/today_is", "w"); + for(j = 0; j < i; j++) + fputs(tod[j + 1 < i ? j + 1 : 0], fp1); + fclose(fp1); + } + } + + + if (!ptime->tm_hour) + { + keeplog(".note", "Record", "¤ß±¡¯d¨¥ª©"); + system("/bin/cp etc/today etc/yesterday"); +/* system("rm -f note.dat"); */ +/* Ptt */ + sprintf(buf1, "[¤½¦w³ø§i] ¨Ï¥ÎªÌ¤W½uºÊ±± [%02d/%02d:%02d]" + ,ptime->tm_mon + 1, ptime->tm_mday, ptime->tm_hour); + keeplog("usies", "Security", buf1); + printf("[¤½¦w³ø§i] ¨Ï¥ÎªÌ¤W½uºÊ±±\n"); + gzip(log_file, "usies", buf); + printf("À£ÁY¨Ï¥ÎªÌ¤W½uºÊ±±\n"); +/* Ptt ¾ú¥v¨Æ¥ó³B²z */ + now = time(NULL) - ADJUST_M * 60; /* back to ancent */ + ptime = localtime(&now); + + attach_uhash(); + if((fp = fopen("etc/history.data", "r"))) + { /* ³æ¤é³Ì¦h¦¸¤H¦¸,¦P®É¤W½u,µù¥U */ + if (fscanf(fp, "%d %d %d %d", &max_login, &max, &max_reg, &k)) + { + fp1 = fopen("etc/history", "r+"); + fseek(fp1, 0, 2); + if (max_user > max) + { + fprintf(fp1, "¡º ¡i%02d/%02d/%02d %02d¡j " + "[1;32m³æ¤@¤p®É¤W½u¤H¦¸[mº¦¸¹F¨ì [1;35m%d[m ¤H¦¸ \n" + ,ptime->tm_mon + 1, ptime->tm_mday, ptime->tm_year % 100, mahour, max_user); + max = max_user; + } + if (total > max_login) + { + fprintf(fp1, "¡» ¡i%02d/%02d/%02d¡j " + "[1;32m³æ¤é¤W½u¤H¦¸[mº¦¸¹F¨ì[1;33m %d[m ¤H¦¸ \n" + ,ptime->tm_mon + 1, ptime->tm_mday, ptime->tm_year % 100, total); + max_login = total; + } + + if (uhash->number > max_reg + max_reg / 10) + { + fprintf(fp1, "¡¹ ¡i%02d/%02d/%02d¡j " + "[1;32mÁ`µù¥U¤H¼Æ[m´£¤É¨ì[1;31m %d[m ¤H \n" + ,ptime->tm_mon + 1, ptime->tm_mday, ptime->tm_year % 100, uhash->number); + max_reg = uhash->number; + } + + fclose(fp1); + } + fclose(fp); + fp = fopen("etc/history.data", "w"); + fprintf(fp, "%d %d %d %d", max_login, max, max_reg, k); + fclose(fp); + } + now += ADJUST_M * 60; /* back to future */ + ptime = localtime(&now); + + /* Ptt ¸`¤é³B²z */ + printf("¸`¤é³B²z\n"); + if((fp1 = fopen("etc/today_is", "w"))) { + i = 0; + if((fp = fopen("etc/feast", "r"))) { + while(fgets(buf1, sizeof(buf1), fp)) { + if(buf[0] != '#' && + sscanf(buf1, "%d %d ", &mo, &da) == 2) { + if(ptime->tm_mday == da && ptime->tm_mon + 1 == mo) { + i = 1; + fprintf(fp1, "%-14.14s", &buf1[6]); + } + } + } + fclose(fp); + } + printf("¸`¤é³B²z1\n"); + if(i == 0) { + if((fp = fopen("etc/today_boring", "r"))) { + while(fgets(buf1, sizeof(buf1), fp)) + if(strlen(buf) > 3) + fprintf(fp1, "%s", buf1); + fclose(fp); + } else + fprintf(fp1, "¥»¤é¸`¤é¼x¨D¤¤"); + } + fclose(fp1); + } + + /* Ptt Åwªïµe±³B²z */ + printf("Åwªïµe±³B²z\n"); + + if((fp = fopen("etc/Welcome.date", "r"))) + { + char temp[50]; + while (fscanf(fp, "%d %d %s\n", &mo, &da, buf1) != EOF) + { + if (ptime->tm_mday == da && ptime->tm_mon + 1 == mo) + { + strcpy(temp, buf1); + sprintf(buf1, "cp -f etc/Welcomes/%s etc/Welcome", temp); + system(buf1); + break; + } + } + fclose(fp); + } + printf("Åwªïµe±³B²z\n"); + if (ptime->tm_wday == 0) + { + keeplog("etc/week", "Record", "¥»¶g¼öªù¸ÜÃD"); + + gzip("bbslog", "bntplink", buf); + gzip("innd/bbslog", "innbbsd", buf); + gzip("etc/mailog", "mailog", buf); + } + + if (ptime->tm_mday == 1) + keeplog("etc/month", "Record", "¥»¤ë¼öªù¸ÜÃD"); + + if (ptime->tm_yday == 1) + keeplog("etc/year", "Record", "¦~«×¼öªù¸ÜÃD"); + } + else if (ptime->tm_hour == 3 && ptime->tm_wday == 6) + { + char *fn1 = "tmp"; + char *fn2 = "suicide"; + rename(fn1, fn2); + mkdir(fn1, 0755); + sprintf(buf, "tar cfz adm/%s-%02d%02d%02d.tgz %s", + fn2, ptime->tm_year % 100, ptime->tm_mon + 1, ptime->tm_mday, fn2); + system(buf); + sprintf(buf, "/bin/rm -fr %s", fn2); + system(buf); + } +/* Ptt reset Ptt's share memory */ + printf("«³]Pttcache »Pfcache\n"); + + fcache->uptime = 0; + resolve_fcache(); + reset_garbage(); + return 0; +} diff --git a/util/antispam.c b/util/antispam.c new file mode 100644 index 00000000..f7b77569 --- /dev/null +++ b/util/antispam.c @@ -0,0 +1,122 @@ +/* $Id: antispam.c,v 1.1 2002/03/07 15:13:45 in2 Exp $ */ +/* §ì¼s§i«Hªºµ{¦¡ */ +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include "config.h" + +#define WINDOW 100 /* ¤@¦¸window¦h¤ÖÓserver */ +#define LEVEL 21 /* Y´X¦¸«´_´Nºâ¼s§i«H */ + +#define mailog BBSHOME "/etc/mailog" +#define spamlog BBSHOME "/etc/spam" + +typedef struct sendinfo +{ + char time[18]; + char from[50]; + char userid[20]; + int count; +} +sendinfo; + +int + main() +{ + char buf[200], *from, *userid; + int num = -1, numb = -1, n, nb; + FILE *fp = fopen(mailog, "r"), *fo; + sendinfo data[WINDOW]; + sendinfo bad[WINDOW]; + + unlink(spamlog); + fo = fopen(spamlog, "a"); + memset(data, 0, sizeof(data)); + memset(bad, 0, sizeof(bad)); + + if (!fp || !fo) + return 0; + + while (fgets(buf, 200, fp)) + { + strtok(buf, "\r\n"); + from = strchr(buf, '>') + 2; + userid = strstr(buf, " =>"); + + if (!from || !userid) + continue; + + *userid = 0; + userid += 4; + + if (strstr(from, "MAILER-DAEMON") + || strstr(from, userid)) + continue; /* °h«H³qª¾¤£ºÞ */ + /* ¬O§_¤w¬Obadhost */ + + for (nb = 0; nb < WINDOW && bad[nb].from[0]; nb++) + if (!strcmp(bad[nb].from, from)) + break; + + if (nb < WINDOW && bad[nb].from[0]) + { + bad[nb].count++; + continue; + } + + /* ²¬d¹L¥h°O¿ý */ + + for (n = 0; n < WINDOW && data[n].from[0]; n++) + if (!strcmp(data[n].from, from)) + break; + + if (n < WINDOW && data[n].from[0]) + { + if (!strncmp(data[n].userid, userid, 20)) + continue; + /* Â൹¦P¤@Ó¤H´N¤£ºÞ */ + strncpy(data[n].userid, userid, 20); + if (++data[n].count >= LEVEL) + { + /* Åܦ¨bad ²¾data¨ìbad ªÅ¯Ê¥Ñ«á¤@µ§¸ê®Æ¸É¤W */ + if (nb >= WINDOW) + { + numb = (numb + 1) % WINDOW; + nb = numb; + fprintf(fo, "%s %s «ÂбH %d ¦¸\n", + bad[nb].time, bad[nb].from, bad[nb].count); +/* printf(" %s send %d times\n", + bad[nb].from, bad[nb].count); */ + } + memcpy(&bad[nb], &data[n], sizeof(sendinfo)); + memcpy(&data[n], &data[n + 1], sizeof(sendinfo) * (WINDOW - n - 1)); + if (num > n) + num--; + } + } + else + { + if (n >= WINDOW) + { + num = (num + 1) % WINDOW; + n = num; + } +/* printf("[%s] to [%s]\n", from, userid); */ + buf[17] = 0; + strncpy(data[n].time, buf, 17); + strncpy(data[n].from, from, 50); + strncpy(data[n].userid, userid, 20); + } + } + + for (nb = 0; nb < WINDOW && bad[nb].from[0]; nb++) + { + fprintf(fo, "%s %s «ÂбH %d ¦¸\n", bad[nb].time, + bad[nb].from, bad[nb].count); +/* printf(" %s send %d times\n", bad[nb].from, bad[nb].count); */ + } + fclose(fp); + fclose(fo); + return 0; +} diff --git a/util/backpasswd.sh b/util/backpasswd.sh new file mode 100644 index 00000000..5ec11abd --- /dev/null +++ b/util/backpasswd.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# $Id: backpasswd.sh,v 1.1 2002/03/07 15:13:45 in2 Exp $ + +mv PASSWDS.NEW5 PASSWDS.NEW6 +mv PASSWDS.NEW4 PASSWDS.NEW5 +mv PASSWDS.NEW3 PASSWDS.NEW4 +mv PASSWDS.NEW2 PASSWDS.NEW3 +mv PASSWDS.NEW1 PASSWDS.NEW2 +mv PASSWDS.NEW PASSWDS.NEW1 +cp .PASSWDS PASSWDS.NEW + diff --git a/util/bbsctl.c b/util/bbsctl.c new file mode 100644 index 00000000..bf66df35 --- /dev/null +++ b/util/bbsctl.c @@ -0,0 +1,63 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <signal.h> +#include <sys/types.h> +void usage(void) +{ + printf("usage: bbsctl [start|stop|restart]\n"); + exit(0); +} + +void startbbs(void) +{ + if( setuid(0) < 0 ){ + perror("setuid(0)"); + exit(1); + } + puts("starting mbbsd: 23"); system("/home/bbs/bin/mbbsd 23"); + puts("starting mbbsd:3000"); system("/home/bbs/bin/mbbsd 3000"); + puts("starting mbbsd:3001"); system("/home/bbs/bin/mbbsd 3001"); + puts("starting mbbsd:3002"); system("/home/bbs/bin/mbbsd 3002"); + puts("starting mbbsd:3003"); system("/home/bbs/bin/mbbsd 3003"); + puts("starting mbbsd:3004"); system("/home/bbs/bin/mbbsd 3004"); + puts("starting mbbsd:3005"); system("/home/bbs/bin/mbbsd 3005"); + puts("starting mbbsd:3006"); system("/home/bbs/bin/mbbsd 3006"); + puts("starting mbbsd:3007"); system("/home/bbs/bin/mbbsd 3007"); + puts("starting mbbsd:3008"); system("/home/bbs/bin/mbbsd 3008"); + puts("starting mbbsd:3009"); system("/home/bbs/bin/mbbsd 3009"); + puts("starting mbbsd:3010"); system("/home/bbs/bin/mbbsd 3010"); +} + +void stopbbs(void) +{ + char buf[1024]; + int pid; + FILE *fp = popen("/bin/ps -ax | /usr/bin/grep mbbsd | " + "/usr/bin/grep listen", "r"); + while( fgets(buf, sizeof(buf), fp) != NULL ){ + sscanf(buf, "%d", &pid); + printf("stopping %d\n", pid); + kill(pid, 1); + } +} + +void restartbbs(void) +{ + stopbbs(); + startbbs(); +} + +int main(int argc, char **argv) +{ + if( argc == 1 ) + usage(); + if( strcmp(argv[1], "start") == 0 ) + startbbs(); + else if( strcmp(argv[1], "stop") == 0 ) + stopbbs(); + else if( strcmp(argv[1], "restart") == 0 ) + restartbbs(); + return 0; +} diff --git a/util/bbsmail.c b/util/bbsmail.c new file mode 100644 index 00000000..48f74c63 --- /dev/null +++ b/util/bbsmail.c @@ -0,0 +1,239 @@ +/* $Id: bbsmail.c,v 1.1 2002/03/07 15:13:45 in2 Exp $ */ + +#define _BBS_UTIL_C_ +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <time.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include "config.h" +#include "pttstruct.h" +#include "util.h" +#include "perm.h" +#include "common.h" + +#define LOG_FILE (BBSHOME "/etc/mailog") + +#ifdef HMM_USE_ANTI_SPAM +extern char *notitle[], *nofrom[], *nocont[]; +#endif + +extern userec_t xuser; + +int mailalertuid(int tuid) +{ + userinfo_t *uentp=NULL; + if(tuid>0 && (uentp = (userinfo_t *)search_ulist(tuid)) ) + uentp->mailalert=1; + return 0; +} + +void +mailog(msg) + char *msg; +{ + FILE *fp; + + if ((fp = fopen(LOG_FILE, "a"))) + { + time_t now; + struct tm *p; + + time(&now); + p = localtime(&now); + fprintf(fp, "%02d/%02d/%02d %02d:%02d:%02d <bbsmail> %s\n", + p->tm_year % 100, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, + msg); + fclose(fp); + } +} + + +int +mail2bbs(userid) + char *userid; +{ + int uid; + fileheader_t mymail; + char genbuf[256], title[80], sender[80], filename[80], *ip, *ptr; + time_t tmp_time; + struct stat st; + FILE *fout; +/* check if the userid is in our bbs now */ + if (!(uid=getuser(userid)) ) + { + sprintf(genbuf, "BBS user <%s> not existed", userid); + puts(genbuf); + mailog(genbuf); + return -1;//EX_NOUSER; + } + + if(xuser.userlevel&PERM_NOOUTMAIL) + return -1; + + sprintf(filename, BBSHOME "/home/%c/%s", userid[0], userid); + + if (stat(filename, &st) == -1) + { + if (mkdir(filename, 0755) == -1) + { + printf("mail box create error %s \n", filename); + return -1; + } + } + else if (!(st.st_mode & S_IFDIR)) + { + printf("mail box error\n"); + return -1; + } + + // printf("dir: %s\n", filename); + +/* allocate a file for the new mail */ + + stampfile(filename, &mymail); + // printf("file: %s\n", filename); + +/* copy the stdin to the specified file */ + +/* parse header */ + + while (fgets(genbuf, 255, stdin)) + { + if (!strncmp(genbuf, "From", 4)) + { + if ((ip = strchr(genbuf, '<')) && (ptr = strrchr(ip, '>'))) + { + *ptr = '\0'; + if (ip[-1] == ' ') + ip[-1] = '\0'; + ptr = (char *) strchr(genbuf, ' '); + while (*ptr == ' ') ptr++; + sprintf(sender, "%s (%s)", ip + 1, ptr); + } + else + { + strtok(genbuf, " \t\n\r"); + ptr= strtok(NULL, " \t\n\r"); + if(ptr) + strcpy(sender, ptr); + } + continue; + } + if (!strncmp(genbuf, "Subject: ", 9)) + { + strcpy(title, genbuf + 9); + continue; + } + if (genbuf[0] == '\n') + break; + } + + if ((ptr = strchr(sender, '\n'))) + *ptr = '\0'; + + if ((ptr = strchr(title, '\n'))) + *ptr = '\0'; + + if (strchr(sender, '@') == NULL) /* ¥Ñ local host ±H«H */ + { + strcat(sender, "@" MYHOSTNAME); + } + + time(&tmp_time); + +#ifdef HMM_USE_ANTI_SPAM + for (n = 0; notitle[n]; n++) + if (strstr(title, notitle[n])) + { + sprintf(genbuf, "Title <%s> not accepted", title); + puts(genbuf); + mailog(genbuf); + return -1; + } + for (n = 0; nofrom[n]; n++) + if (strstr(sender, nofrom[n])) + { + sprintf(genbuf, "From <%s> not accepted", sender); + puts(genbuf); + mailog(genbuf); + return -1; + } +#endif + + if ((fout = fopen(filename, "w")) == NULL) + { + printf("Cannot open %s\n", filename); + return -1; + } + + if (!title[0]) + sprintf(title, "¨Ó¦Û %.64s", sender); + title[TTLEN] = 0; + fprintf(fout, "§@ªÌ: %s\n¼ÐÃD: %s\n®É¶¡: %s\n", + sender, title, ctime(&tmp_time)); + + while (fgets(genbuf, 255, stdin)) + { +#ifdef HMM_USE_ANTI_SPAM + for (n = 0; nocont[n]; n++) + if (strstr(genbuf, nocont[n])) + { + fclose(fout); + unlink(filename); + sprintf(genbuf, "Content <%s> not accepted", nocont[n]); + puts(genbuf); + mailog(genbuf); + return -1; + } +#endif + fputs(genbuf, fout); + } + fclose(fout); + + sprintf(genbuf, "%s => %s", sender, userid); + mailog(genbuf); + +/* append the record to the MAIL control file */ + + strcpy(mymail.title, title); + + if (strtok(sender, " .@\t\n\r")) + strcat(sender, "."); + sender[IDLEN + 1] = '\0'; + strcpy(mymail.owner, sender); + + sprintf(genbuf, BBSHOME "/home/%c/%s/.DIR", userid[0], userid); + mailalertuid(uid); + return append_record(genbuf, &mymail, sizeof(mymail)); +} + + +int +main(int argc, char* argv[]) +{ + char receiver[256]; + +/* argv[1] is userid in bbs */ + + if (argc < 2) + { + printf("Usage:\t%s <bbs_uid>\n", argv[0]); + exit(-1); + } + (void) setgid(BBSGID); + (void) setuid(BBSUID); + + if(passwd_mmap()) exit(-1); + strcpy(receiver, argv[1]); + + strtok(receiver,"."); + if (mail2bbs(receiver)) + { + /* eat mail queue */ + while (fgets(receiver, sizeof(receiver), stdin)) ; + } + return 0; +} diff --git a/util/bbsrf.c b/util/bbsrf.c new file mode 100644 index 00000000..66f6cee0 --- /dev/null +++ b/util/bbsrf.c @@ -0,0 +1,148 @@ +/* $Id: bbsrf.c,v 1.1 2002/03/07 15:13:45 in2 Exp $ */ + +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/param.h> +#include <sys/types.h> +#include <utmp.h> +#include <pwd.h> +#include <syslog.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/uio.h> +#include "config.h" + +/* fill the hid with from hostname */ +void gethid(char *hid, char *tty) +{ + int fd; + char *tp; + struct utmp data; + + gethostname(hid, MAXHOSTNAMELEN); + hid[MAXHOSTNAMELEN] = '\0'; + tp = strrchr(tty, '/') + 1; + if (tp && strlen(tp) == 5) + { + fd = open(_PATH_UTMP, O_RDONLY); + if (fd < 0) + syslog(LOG_ERR, "%s: %m", _PATH_UTMP); + else + { + while (read(fd, &data, sizeof(data)) == sizeof(data)) + if (strcmp(data.ut_line, tp) == 0) + { + if (data.ut_host[0]) { +#if MAXHOSTNAMELEN < UT_HOSTSIZE + strncpy(hid, data.ut_host, MAXHOSTNAMELEN); + hid[MAXHOSTNAMELEN] = '\0'; +#else + strncpy(hid, data.ut_host, UT_HOSTSIZE); + hid[UT_HOSTSIZE] = '\0'; +#endif + } + break; + } + close(fd); + } + } +} + +/* + get system load averages + return 0 if success; otherwise, return -1. + */ +int getload(double load[3]) +{ + int rtv = -1; +#if defined(linux) + FILE *fp; + + fp = fopen(LOAD_FILE, "r"); + if (fp) + { + if (fscanf(fp, "%lf %lf %lf", &load[0], &load[1], &load[2]) == 3) + rtv = 0; + fclose(fp); + } +#elif defined(__FreeBSD__) + if (getloadavg(load, 3) == 3) + rtv = 0; +#endif + return rtv; +} + +/* + show ban file + if filename exist, print it out, sleep 1 second, and return 0; + otherwise, return -1. + */ +int showbanfile(char *filename) +{ + FILE *fp; + char buf[256]; + + fp = fopen(filename, "r"); + if (fp) + { + while (fgets(buf, sizeof(buf), fp)) + fputs(buf, stdout); + printf("\n=============================" + "=============================\n"); + fclose(fp); + sleep(1); + } + return fp ? 0 : -1; +} + +int main(void) +{ + int uid, rtv = 0; + char *tty, ttybuf[32], hid[MAXHOSTNAMELEN + 1]; + + openlog("bbsrf", LOG_PID | LOG_PERROR, LOG_USER); + chdir(BBSHOME); + uid = getuid(); + + while (1) + { + if (!showbanfile(BAN_FILE)) + { + rtv = 1; + break; + } + else if (uid != BBSUID) + { + syslog(LOG_ERR, "UID DOES NOT MATCH"); + rtv = -1; + break; + } + else if (!getpwuid(uid)) + { + syslog(LOG_ERR, "YOU DONT EXIST"); + rtv = -1; + break; + } + else + { + tty = ttyname(0); + if (tty) + { + strcpy(ttybuf, tty); + gethid(hid, ttybuf); + } + else + { + strcpy(ttybuf, "notty"); + strcpy(hid, "unknown"); + } + execl(BBSPROG, "mbbsd", hid, ttybuf, NULL); + syslog(LOG_ERR, "execl(): %m"); + rtv = -1; + } + break; + } + return rtv; +} diff --git a/util/birth.c b/util/birth.c new file mode 100644 index 00000000..899bf9ee --- /dev/null +++ b/util/birth.c @@ -0,0 +1,99 @@ +/* ¹Ø¬Pµ{¦¡ 96 10/11 */ + +#include <stdio.h> +#include <sys/types.h> +#include <ctype.h> +#include <unistd.h> +#include <stdlib.h> +#include <time.h> +#include "config.h" +#include "pttstruct.h" +#include "util.h" +#include "common.h" + +#define OUTFILE BBSHOME "/etc/birth.today" + +struct userec_t cuser; + +int bad_user_id() { + register char ch; + int j; + if (strlen(cuser.userid) < 2 || !isalpha(cuser.userid[0])) + return 1; + if (cuser.numlogins == 0 || cuser.numlogins > 15000) + return 1; + if (cuser.numposts > 15000) + return 1; + for (j = 1; (ch = cuser.userid[j]); j++) + { + if (!isalnum(ch)) + return 1; + } + return 0; +} + +int Link(char *src, char *dst) { + char cmd[200]; + + if (link(src, dst) == 0) + return 0; + + sprintf(cmd, "/bin/cp -R %s %s", src, dst); + return system(cmd); +} + +int main(argc, argv) + int argc; + char **argv; +{ + FILE *fp1; + fileheader_t mymail; + int i, day = 0; + time_t now; + struct tm *ptime; + int j; + + now = time(NULL); /* back to ancent */ + ptime = localtime(&now); + + if(passwd_mmap()) + exit(1); + + printf("*»sªí\n"); + fp1 = fopen(OUTFILE, "w"); + + fprintf(fp1, "\n " + "[1m¡¹[35m¡¹[34m¡¹[33m¡¹[32m¡¹[31m¡¹[45;33m ¹Ø¬P¤jÆ[ " + "[40m¡¹[32m¡¹[33m¡¹[34m¡¹[35m¡¹[1m¡¹[m \n\n"); + fprintf(fp1, "[33m¡i[1;45m¥»¤é¹Ø¬P[40;33m¡j[m \n"); + for(j = 1; j <= MAX_USERS; j++) { + passwd_query(j, &cuser); + if (bad_user_id()) + continue; + if (cuser.month == ptime->tm_mon + 1) + { + if (cuser.day == ptime->tm_mday) + { + char genbuf[200]; + sprintf(genbuf, BBSHOME "/home/%c/%s", cuser.userid[0], cuser.userid); + stampfile(genbuf, &mymail); + strcpy(mymail.owner, BBSNAME); + strcpy(mymail.title, "!! ¥Í¤é§Ö¼Ö !!"); + mymail.savemode = 0; + unlink(genbuf); + Link(BBSHOME "/etc/Welcome_birth", genbuf); + sprintf(genbuf, BBSHOME "/home/%c/%s/.DIR", cuser.userid[0], cuser.userid); + append_record(genbuf, &mymail, sizeof(mymail)); + if ((cuser.numlogins + cuser.numposts) < 20) + continue; + + fprintf(fp1, + " [33m[%2d/%-2d] %-14s[0m %-24s login:%-5d post:%-5d\n", + ptime->tm_mon + 1, ptime->tm_mday, cuser.userid, + cuser.username, cuser.numlogins, cuser.numposts); + } + } + } + fclose(fp1); + return 0; +} diff --git a/util/buildAnnounce.c b/util/buildAnnounce.c new file mode 100644 index 00000000..0e754f22 --- /dev/null +++ b/util/buildAnnounce.c @@ -0,0 +1,69 @@ +/* «Ø¥ß©Ò¦³¬ÝªOºëµØ°Ïªº³sµ² */ + +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/shm.h> +#include "config.h" +#include "pttstruct.h" +#define GROUPROOT BBSHOME"/man/group" + +extern bcache_t *brdshm; +extern boardheader_t *bcache; +extern void resolve_boards(); + +void buildchilds(int level,char *path,boardheader_t *bptr) +{ + char newpath[512]; + boardheader_t *ptr; + fileheader_t item; + + if(bptr->firstchild[1]==(boardheader_t*)~0 || bptr->firstchild[1]==NULL) + return; + for(ptr =(void*) bptr->firstchild[1]; + ptr!=(boardheader_t*)~0 ;ptr=ptr->next[1]) + { + + if( + (ptr->brdattr&(BRD_BAD | BRD_GROUPBOARD | BRD_NOCOUNT | BRD_HIDE))!=0 + || + (ptr->level && !(ptr->brdattr & BRD_POSTMASK))) continue; + printf("%*.*s+-%-14s %-s \n",level*2,level*2,"| | | | | | | | |", + ptr->brdname, ptr->title); + if(ptr->brdattr & BRD_GROUPBOARD) + { + sprintf(newpath,"%s/%s",path,ptr->brdname); + mkdir(newpath,0766); + buildchilds(level+1,newpath,ptr); + } + else + { + printf("%s4\n",ptr->brdname); + sprintf(newpath,"/bin/ln -s "BBSHOME"/man/boards/%s %s/%s", + ptr->brdname,path,ptr->brdname); + system(newpath); + } + printf("%s5\n",ptr->brdname); + sprintf(newpath,"%s/.DIR",path); + strcpy(item.owner,ptr->BM); + strtok(item.owner,"/"); + strcpy(item.title,ptr->title+7); + item.savemode = 'D'; + sprintf(item.filename,ptr->brdname); + append_record(newpath, &item, sizeof(item)); + } +} + + +int main() +{ + char path[512]; + setsid(); + strcpy(path,GROUPROOT); + system("rm -rf "GROUPROOT); + mkdir(GROUPROOT,0766); + resolve_boards(); + buildchilds(0,path,&bcache[0]); + return 0; +} diff --git a/util/buildAnnounce.sh b/util/buildAnnounce.sh new file mode 100644 index 00000000..d43f420b --- /dev/null +++ b/util/buildAnnounce.sh @@ -0,0 +1,5 @@ +#!/bin/sh +# $Id: buildAnnounce.sh,v 1.1 2002/03/07 15:13:45 in2 Exp $ +# +bin/buildAnnounce > etc/ALLBRDLIST +bin/post Record ¥þ¯¸¬ÝªO¦Cªí [¦Û°Ê¯¸ªø] etc/ALLBRDLIST diff --git a/util/buildir.c b/util/buildir.c new file mode 100644 index 00000000..381a657d --- /dev/null +++ b/util/buildir.c @@ -0,0 +1,124 @@ +/* $Id: buildir.c,v 1.1 2002/03/07 15:13:45 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <dirent.h> +#include <fcntl.h> +#include <time.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> +#include <sys/types.h> +#include <sys/stat.h> +#include "config.h" +#include "pttstruct.h" + +int dirselect(struct dirent *dir) { + return strchr("MDSGH", dir->d_name[0]) && dir->d_name[1] == '.'; +} + +int mysort(const struct dirent **a,const struct dirent **b) +{ + return atoi(((*a)->d_name+2))-atoi(((*b)->d_name+2)); +} + +int main(int argc, char **argv) { + int k; + + if(argc < 2) { + fprintf(stderr, "Usage: %s <path1> [<path2> ...]\n", argv[0]); + return 1; + } + + for(k = 1; k < argc; k++) { + int fdir, count, total; + char *ptr, path[MAXPATHLEN]; + struct dirent **dirlist; + + sprintf(path, "%s/.DIR", argv[k]); + if((fdir = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) { + perror(path); + continue; + } + + if((total = scandir(argv[k], &dirlist, dirselect, mysort)) == -1) { + fprintf(stderr, "scandir failed!\n"); + close(fdir); + continue; + } + + ptr = strrchr(path, '.'); + for(count = 0; count < total; count++) { + FILE *fp; + struct stat st; + + strcpy(ptr, dirlist[count]->d_name); + if(stat(path, &st) == 0 && st.st_size > 0 && + (fp = fopen(path, "r")) != NULL) { + char buf[512]; + time_t filetime; + fileheader_t fhdr; + + memset(&fhdr, 0, sizeof(fhdr)); + /* set file name */ + strcpy(fhdr.filename, dirlist[count]->d_name); + + /* set file time */ + filetime = atoi(dirlist[count]->d_name + 2); + if(filetime > 740000000) { + struct tm *ptime = localtime(&filetime); + sprintf(fhdr.date, "%2d/%02d", ptime->tm_mon + 1, + ptime->tm_mday); + } else + strcpy(fhdr.date, " "); + + /* set file mode */ + fhdr.filemode = FILE_READ; + + /* set article owner */ + fgets(buf, sizeof(buf), fp); + if(strncmp(buf, "§@ªÌ: ", 6) == 0 || + strncmp(buf, "µo«H¤H: ", 8) == 0) { + int i, j; + + for(i = 5; buf[i] != ' '; i++); + for(; buf[i] == ' '; i++); + for(j = i + 1; buf[j] != ' '; j++); + j -= i; + if(j > IDLEN + 1) + j = IDLEN + 1; + strncpy(fhdr.owner, buf + i, j); + fhdr.owner[IDLEN + 1] = '\0'; + strtok(fhdr.owner, " .@\t\n\r"); + if(strtok(NULL, " .@\t\n\r")) + strcat(fhdr.owner, "."); + + /* set article title */ + while(fgets(buf, sizeof(buf), fp)) + if(strncmp(buf, "¼ÐÃD: ", 6) == 0 || + strncmp(buf, "¼Ð ÃD: ", 8) == 0) { + for(i = 5; buf[i] != ' '; i++); + for(; buf[i] == ' '; i++); + strtok(buf + i-1, "\n"); + strncpy(fhdr.title, buf + i, TTLEN); + fhdr.title[TTLEN] = '\0'; + break; + } + } else if(strncmp(buf, "¡ó Åwªï¥úÁ{", 11) == 0) { + strcpy(fhdr.title, "·|ij°O¿ý"); + } else if(strncmp(buf, "\33[1;33;46m¡¹", 12) == 0|| + strncmp(buf, "To", 2) == 0) { + strcpy(fhdr.title, "¼ö½u°O¿ý"); + } +// if(!fhdr.title[0]) +// strcpy(fhdr.title, dirlist[count]->d_name); + fclose(fp); + write(fdir, &fhdr, sizeof(fhdr)); + } + } + close(fdir); + for(total--; total >= 0; total--) + free(dirlist[total]); + free(dirlist); + } + return 0; +} diff --git a/util/countalldice.c b/util/countalldice.c new file mode 100644 index 00000000..badd4bad --- /dev/null +++ b/util/countalldice.c @@ -0,0 +1,95 @@ +/* $Id: countalldice.c,v 1.1 2002/03/07 15:13:45 in2 Exp $ */ + +/**********************************************/ +/*³oÓµ{¦¡¬O¥Î¨Ópºâ½ä»ë¤lÁȱo¿ú¸ò½ßªº¿úªºµ{¦¡ */ +/*¥Îªk´N¬Oª½±µ¥´ countalldice ´N¥i¥H°w¹ï©Ò¦³¤H */ +/*¨Ópºâ¥LÁ`¦@ÁȤF¦h¤Ö ½ß¤F¦h¤Ö............... */ +/*§@ªÌ:Heat ©ó1997/10/2 */ +/**********************************************/ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <sys/types.h> +#include "config.h" + +#define DICE_WIN BBSHOME "/etc/windice.log" +#define DICE_LOST BBSHOME "/etc/lostdice.log" + +int total = 0; + +typedef struct dice +{ + char id[14]; + int win; + int lost; +} +dice; + +dice table[1024]; + +int find(char *name) +{ + int i = 0; + if (total == 0) + { + total++; + return 0; + } + for (i = 0; i < total; i++) + if (!strcmp(name, table[i].id)) + return i; + memset(&table[total++], 0, sizeof(dice)); + return total - 1; +} + +int main() { + int index, win = 0, lost = 0; + FILE *fpwin, *fplost; + char buf[256], *ptr, buf0[256], *name = (char *) malloc(15), *mon = (char *) malloc(5); + + fpwin = fopen(DICE_WIN, "r"); + fplost = fopen(DICE_LOST, "r"); + + if (!fpwin || !fplost) + perror("error open file"); + + while (fgets(buf, 255, fpwin)) + { + strcpy(buf0, buf); + name = strtok(buf, " "); + mon = strstr(buf0, "²bÁÈ:"); + if ((ptr = strchr(mon, '\n'))) + *ptr = 0; + index = find(name); + strcpy(table[index].id, name); + table[index].win += atoi(mon + 5); + } + fclose(fpwin); + + while (fgets(buf, 255, fplost)) + { + strcpy(buf0, buf); + name = strtok(buf, " "); + mon = strstr(buf0, "¿é¤F "); + if ((ptr = strchr(mon, '\n'))) + *ptr = 0; + if ((index = find(name)) == total - 1) + strcpy(table[index].id, name); + table[index].lost += atoi(mon + 5); + } + + for (index = 0; index < total; index++) + { + printf("%-15s ŤF %-8d ¶ô¿ú¡A ¿é±¼ %-8d ¶ô¿ú\n", table[index].id + ,table[index].win, table[index].lost); + win += table[index].win; + lost += table[index].lost; + } + index = win + lost; + printf("\n¤H¼Æ: %d\nÁ`Ĺ¿ú=%d Á`¿é¿ú=%d Á`ª÷ÃB:%d\n", total, win, lost, index); + printf("Ĺªº¤ñ¨Ò:%f ¿éªº¤ñ¨Ò:%f\n", (float) win / index, (float) lost / index); + printf("\n³Æµù¡G¿éŬO¥H¨Ï¥ÎªÌªºÆ[ÂI¨Ó¬Ý\n"); + fclose(fplost); + return 0; +} diff --git a/util/cpdeadbrd.c b/util/cpdeadbrd.c new file mode 100644 index 00000000..12c5827e --- /dev/null +++ b/util/cpdeadbrd.c @@ -0,0 +1,41 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <dirent.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include "config.h" +#include "pttstruct.h" +#include "util.h" + +extern int numboards; +extern boardheader_t *bcache; +int main(int argc, char* argv[]){ +struct stat st; +boardheader_t *bptr; + int n; + char pathname[1024]; + + resolve_boards(); + for (n=numboards-1;n>0;n--) + { + + bptr = &bcache[n]; + if(!strcmp(bptr->brdname,"ck53rd316"))continue; + sprintf(pathname,"/home/bbs/boards/%s/.DIR",bptr->brdname); + if(stat(pathname, &st) == -1) + { + printf("%s is dead\n",pathname); + sprintf (pathname,"cp -R /mnt/bbs/boards/%s /home/bbs/boards/%s",bptr->brdname,bptr->brdname); + } + } +} + + + + + + + diff --git a/util/dailybackup.pl b/util/dailybackup.pl new file mode 100644 index 00000000..76943887 --- /dev/null +++ b/util/dailybackup.pl @@ -0,0 +1,48 @@ +#!/usr/bin/perl +use lib '/home/bbs/bin/'; +use LocalVars; +use strict; +use vars qw/$BACKHOME $MANROOT $HOMEROOT $BOARDROOT/; + +$BACKHOME = "$BBSHOME/backup"; +$MANROOT = "man/boards"; +$HOMEROOT = "home"; +$BOARDROOT= "boards"; + +chdir $BBSHOME; +my @baktable = (['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'], + ['I', 'J', 'K', 'L', 'M', 'N', 'O', 'P'], + ['Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X'], + ['Y', 'Z', 'a', 'b', 'c', 'd', 'e'], + ['f', 'g', 'h', 'i', 'j', 'k', 'l'], + ['m', 'n', 'o', 'p', 'q', 'r', 's'], + ['t', 'u', 'v', 'w', 'x', 'y', 'z']); +my (undef,undef,undef,undef,undef,undef,$wday) = localtime(time); +my $week = defined($ARGV[0]) ? $ARGV[0] : $wday; + +no strict 'subs'; +setpriority(PRIO_PROCESS, $$, 20); +use strict subs; + +my($orig, $to); +foreach $orig ( <$BACKHOME/*new*> ){ + $to = $orig; + $to =~ s/\.new//g; + docmd("mv $orig $to"); +} + +foreach( @{$baktable[$week]} ){ + docmd("$TAR zcf $BACKHOME/man.$_.new.tgz $MANROOT/$_*"); + docmd("$TAR zcf $BACKHOME/home.$_.new.tgz $HOMEROOT/$_/*"); + docmd("$TAR zcf $BACKHOME/board.$_.new.tgz $BOARDROOT/$_*"); +} + +if( $week == 0 ){ + docmd("$TAR zcf $BACKHOME/general.new.tgz .act .crontab .note .polling .post bin cron etc innd note.ans note.dat out out.going pttbbs pttbbs.conf upgrade.sh usies ussong"); +} + +sub docmd +{ + print "@_\n"; + `@_`; +} diff --git a/util/daymandex.c b/util/daymandex.c new file mode 100644 index 00000000..d2921d07 --- /dev/null +++ b/util/daymandex.c @@ -0,0 +1,269 @@ +/* $Id: daymandex.c,v 1.1 2002/03/07 15:13:46 in2 Exp $ */ + +/* + target : ºëµØ°Ï¯Á¤Þµ{¦¡ (man index) + + syntax : mandex [board] + [board] ¦³È ==> ¥u¶]¸Ó board + ªÅªº ==> ©Ò¦³ªº boards ³£¶] +*/ + + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <dirent.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include "config.h" +#include "pttstruct.h" +#include "util.h" + +#ifndef MAXPATHLEN +#define MAXPATHLEN 1024 +#endif + +extern int numboards; +extern boardheader_t *bcache; + +char color[4][10] = +{"[1;33m", "[1;32m", "[1;36m", "[1;37m"}; +char fn_index[] = ".index"; +char fn_new[] = ".index.new"; +char index_title[] = "¡· ºëµØ°Ï¥Ø¿ý¯Á¤Þ"; +FILE *fndx; +int ndir; +int nfile; +int index_pos; +char topdir[128], pgem[512], pndx[512]; + +int nb = 0; /* board ¼Æ */ + +struct boardinfo +{ + char bname[40]; + int ndir; + int nfile; + int k; +}; +typedef struct boardinfo boardinfo; + +boardinfo +board[MAX_BOARD]; + +int k_cmp(b, a) + boardinfo *b, *a; +{ + return ((a->k / 100 + a->ndir + a->nfile) - (b->k / 100 + b->ndir + b->nfile)); +} + +int dashd(fname) + char *fname; +{ + struct stat st; + + return (stat(fname, &st) == 0 && S_ISDIR(st.st_mode)); +} + + +/* visit the hierarchy recursively */ + +void +mandex(level, num_header, fpath) + int level; + char *fpath, *num_header; +{ + FILE *fgem; + char *fname, buf[256]; + struct stat st; + int count; + fileheader_t fhdr; + + fgem = fopen(fpath, "r+"); + if (fgem == NULL) + return; + + fname = strrchr(fpath, '.'); + if (!level) + { + + printf("%s\r\n",fpath); + strcpy(pgem, fpath); + + strcpy(fname, fn_new); + fndx = fopen(fpath, "w"); + if (fndx == NULL) + { + fclose(fgem); + return; + } + fprintf(fndx, "[1;32m§Ç¸¹\t\t\tºëµØ°Ï¥DÃD[m\n" + "[36m¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w[m\n"); + strcpy(pndx, fpath); + ndir = nfile = 0; + index_pos = -1; + } + + count = 0; + while (fread(&fhdr, sizeof(fhdr), 1, fgem) == 1) + { + strcpy(fname, fhdr.filename); + if (!fname[0]) continue; + if (!level && !strncmp(fhdr.title, index_title, strlen(index_title)) + && index_pos < 0) + { + index_pos = count; + unlink(fpath); + } + st.st_size = 0; + stat(fpath, &st); + + sprintf(buf, "%.*s%s%3d. %s [m\n", + + 11 * level, num_header, color[level % 4], ++count, fhdr.title); /* Ptt */ + fputs(buf, fndx); + if (dashd(fpath)) + { + ++ndir; + if (*fhdr.title != '#' && level < 10) + { + strcat(fpath, "/.DIR"); + mandex(level + 1, buf, fpath); + } + } + else + ++nfile; + } + + if (!level) + { + char lpath[MAXPATHLEN]; + + fclose(fndx); + strcpy(fname, fn_index); + rename(pndx, fpath); + strcpy(pndx, fpath); + + sprintf(buf, "%s.new", pgem); + if (index_pos >= 0 || (fndx = fopen(buf, "w"))) + { + fname[-1] = 0; + stamplink(fpath, &fhdr); + unlink(fpath); + strcpy(fhdr.owner, "¨C¤Ñ¦Û°Ê§ó·s"); + sprintf(lpath, "%s/%s", topdir, pndx); + st.st_size = 0; + stat(lpath, &st); + sprintf(fhdr.title, "%s (%.1fk)", index_title, st.st_size / 1024.); + board[nb].k = st.st_size; /* Ptt */ + printf("(%d)[%dK]", nb, board[nb].k); + symlink(lpath, fpath); + if (index_pos < 0) + { + fwrite(&fhdr, sizeof(fhdr), 1, fndx); + rewind(fgem); + while (fread(&fhdr, sizeof(fhdr), 1, fgem) == 1) + fwrite(&fhdr, sizeof(fhdr), 1, fndx); + fclose(fndx); + fclose(fgem); + rename(buf, pgem); + } + else + { + fseek(fgem, index_pos * sizeof(fhdr), 0); + fwrite(&fhdr, sizeof(fhdr), 1, fgem); + fclose(fgem); + } + return; + } + } + fclose(fgem); +} + + +int main(int argc, char* argv[]){ + boardheader_t *bptr; + DIR *dirp; + struct dirent *de; + int ch, n; + int place = 0; + char *fname, fpath[MAXPATHLEN]; + + resolve_boards(); + nb = 0; + if(argc == 1){ + puts("Creating the whole index..."); + chdir(strcpy(topdir, BBSHOME)); + strcpy(fpath, "man/.DIR"); + mandex(0, "", fpath); + } + + + chdir(strcpy(topdir, BBSHOME "/man/boards")); + + if(argc > 1) { + sprintf(fpath, "%s/.DIR", argv[1]); + mandex(0, "", fpath); + exit(0); + } + + /* process all boards */ + + if(!(dirp = opendir(topdir))) { + printf("## unable to enter [man/boards]\n"); + exit(-1); + } + + while((de = readdir(dirp))){ + fname = de->d_name; + ch = fname[0]; + if (ch != '.'){ + board[nb].k = 0; + strcpy(board[nb].bname, fname); + sprintf(fpath, "%s/.rebuild", fname); + if( access(fpath, 0) >= 0 ){ + unlink(fpath); + + sprintf(fpath, "%s/.DIR", fname); + mandex(0, "", fpath); + printf("%-14sd: %d\tf: %d\n", fname, ndir, nfile); + /* report */ + board[nb].ndir = ndir; + board[nb].nfile = nfile; + if (board[nb].k) + nb++; + } + } + } + closedir(dirp); + + qsort(board, nb, sizeof(boardinfo), k_cmp); + + if (!(fndx = fopen(BBSHOME "/etc/topboardman", "w"))) + exit(0); + + fprintf(fndx, "[1;44m±Æ¦W[47;30m ¬Ý ª© ¥Ø¿ý¼Æ ÀÉ®×¼Æ" + " byte¼Æ [30m Á` ¤À ª© ¥D [m\n"); + + for (ch = 0; ch < nb; ch++){ + for (n = 0; n < numboards; n++){ + bptr = &bcache[n]; + if (!strcmp(bptr->brdname, board[ch].bname)) + break; + } + if (n >= numboards || + (bptr->brdattr & (BRD_BAD | BRD_NOCOUNT | BRD_HIDE))) + continue; + if (board[ch].ndir + board[ch].nfile < 5) + break; + fprintf(fndx, "%3d.[33m%15s[m %5d %7d %10d %6d [31m%-24.24s[m\n", + ++place, + board[ch].bname, + board[ch].ndir, board[ch].nfile, board[ch].k + ,board[ch].k / 100 + board[ch].nfile + board[ch].ndir + ,bptr->BM); + } + fclose(fndx); + exit(0); +} diff --git a/util/deluserfile.c b/util/deluserfile.c new file mode 100644 index 00000000..63cfefba --- /dev/null +++ b/util/deluserfile.c @@ -0,0 +1,147 @@ +/* $Id: deluserfile.c,v 1.1 2002/03/07 15:13:45 in2 Exp $ */ +/* ¦Û°Ê¬åuser¥Ø¿ýÀÉ®×µ{¦¡ */ + +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <dirent.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/types.h> +#include "config.h" +#include "pttstruct.h" +#include "util.h" + +#define HOLDWRITELOG +#define DELZEROFILE +#define USERHOME BBSHOME "/home" + +int bad_user_id(char *userid) +{ + register char ch; + + if (strlen(userid) < 2) + return 1; + + if (!isalpha(*userid)) + return 1; + + if (!strcasecmp(userid, "new")) + return 1; + + while ((ch = *(++userid))) + if (!isalnum(ch)) + return 1; + return 0; +} + +void del_file(char *userid) +{ + char buf[200], buf1[200]; + struct dirent *de; + DIR *dirp; + char *ptr; + + sprintf(buf, BBSHOME "/home/%c/%s", userid[0], userid); + + if (chdir(buf) == -1) + return; + + if (!(dirp = opendir(buf))) + return; + + while ((de = readdir(dirp))) + { + ptr = de->d_name; + if (ptr[0] > ' ' && ptr[0] != '.') + { + if (strstr(ptr, "writelog")) +#ifdef HOLDWRITELOG + { + fileheader_t mymail; + + stampfile(buf, &mymail); + mymail.savemode = 'H'; /* hold-mail flag */ + mymail.filemode = FILE_READ; + strcpy(mymail.owner, userid); + strcpy(mymail.title, "¼ö½u°O¿ý"); + sprintf(buf1, BBSHOME "/home/%c/%s/writelog", + userid[0], userid); + rename(buf1, buf); + sprintf(buf1, BBSHOME "/home/%c/%s/.DIR", userid[0], userid); + append_record(buf1, &mymail, sizeof(mymail)); + } +#else + unlink(ptr); +#endif + else if (strstr(ptr, "chat_")) + unlink(ptr); + else if (strstr(ptr, "ve_")) + unlink(ptr); + else if (strstr(ptr, "SR.")) + unlink(ptr); + else if (strstr(ptr, ".old")) + unlink(ptr); + else if (strstr(ptr, "talk_")) + unlink(ptr); + } + } + closedir(dirp); +} + +void mv_user_home(char *ptr) +{ + char buf[200]; + + printf("move user %s to tmp\n", ptr); + sprintf(buf, "cp -R " BBSHOME "/home/%c/%s " BBSHOME "/tmp", ptr[0], ptr); +// sprintf(buf,"rm -rf " BBSHOME "/home/%c/%s",ptr[0],ptr); + if (!system(buf)) + { //Copy success + + sprintf(buf, "rm -rf " BBSHOME "/home/%c/%s", ptr[0], ptr); + system(buf); + } +} + +int main(int argc, char **argv) +{ + struct dirent *de; + DIR *dirp; + char *ptr, buf[200], ch; + int count = 0; +/* visit all users */ + + printf("new version, deleting\n"); + + for (ch = 'A'; ch <= 'z'; ch++) + { + if(ch > 'Z' && ch < 'a') + continue; + printf("Cleaning %c\n", ch); + sprintf(buf, USERHOME "/%c", ch); + if (!(dirp = opendir(buf))) + { + printf("unable to open %s\n", buf); + continue; + } + + while ((de = readdir(dirp))) + { + ptr = de->d_name; + + /* ¹w¨¾¿ù»~ */ + if (!bad_user_id(ptr)) + { + if (!(count++ % 300)) + printf(".\n"); + if (!searchuser(ptr)) + mv_user_home(ptr); + else + del_file(ptr); + } + } + closedir(dirp); + } + return 0; +} diff --git a/util/descrypt.c b/util/descrypt.c new file mode 100644 index 00000000..97475c1a --- /dev/null +++ b/util/descrypt.c @@ -0,0 +1,616 @@ +/* $Id: descrypt.c,v 1.1 2002/03/07 15:13:45 in2 Exp $ */ + +/* + * FreeSec: libcrypt for NetBSD + * + * Copyright (c) 1994 David Burren + * All rights reserved. + * + * Adapted for FreeBSD-2.0 by Geoffrey M. Rehmet + * crypt.c should now *only* export crypt(), in order to make + * binaries of libcrypt exportable from the USA + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the author nor the names of other contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/secure/lib/libcrypt/crypt.c,v 1.11 1999/08/28 01:30:24 peter Exp $ + * + * This is an original implementation of the DES and the crypt(3) interfaces + * by David Burren <davidb@werj.com.au>. + * + * An excellent reference on the underlying algorithm (and related + * algorithms) is: + * + * B. Schneier, Applied Cryptography: protocols, algorithms, + * and source code in C, John Wiley & Sons, 1994. + * + * Note that in that book's description of DES the lookups for the initial, + * pbox, and final permutations are inverted (this has been brought to the + * attention of the author). A list of errata for this book has been + * posted to the sci.crypt newsgroup by the author and is available for FTP. + * + * ARCHITECTURE ASSUMPTIONS: + * This code assumes that u_longs are 32 bits. It will probably not + * operate on 64-bit machines without modifications. + * It is assumed that the 8-byte arrays passed by reference can be + * addressed as arrays of u_longs (ie. the CPU is not picky about + * alignment). + */ + +#ifndef HAVE_DES_CRYPT + +#include <sys/types.h> +#include <sys/param.h> +#include <pwd.h> +#include <string.h> + +static unsigned char IP[64] = { + 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, + 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, + 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, + 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7 +}; + +static unsigned char inv_key_perm[64]; +static unsigned char u_key_perm[56]; +static unsigned char key_perm[56] = { + 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, + 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, + 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, + 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4 +}; + +static unsigned char key_shifts[16] = { + 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 +}; + +static unsigned char inv_comp_perm[56]; +static unsigned char comp_perm[48] = { + 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, + 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, + 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, + 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32 +}; + +/* + * No E box is used, as it's replaced by some ANDs, shifts, and ORs. + */ + +static unsigned char u_sbox[8][64]; +static unsigned char sbox[8][64] = { + { + 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, + 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, + 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, + 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 + }, + { + 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, + 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, + 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, + 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 + }, + { + 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, + 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, + 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, + 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 + }, + { + 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, + 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, + 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, + 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 + }, + { + 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, + 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, + 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, + 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 + }, + { + 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, + 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, + 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, + 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 + }, + { + 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, + 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, + 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, + 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 + }, + { + 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, + 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, + 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, + 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 + } +}; + +static unsigned char un_pbox[32]; +static unsigned char pbox[32] = { + 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, + 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25 +}; + +static unsigned long bits32[32] = { + 0x80000000, 0x40000000, 0x20000000, 0x10000000, + 0x08000000, 0x04000000, 0x02000000, 0x01000000, + 0x00800000, 0x00400000, 0x00200000, 0x00100000, + 0x00080000, 0x00040000, 0x00020000, 0x00010000, + 0x00008000, 0x00004000, 0x00002000, 0x00001000, + 0x00000800, 0x00000400, 0x00000200, 0x00000100, + 0x00000080, 0x00000040, 0x00000020, 0x00000010, + 0x00000008, 0x00000004, 0x00000002, 0x00000001 +}; + +static unsigned char bits8[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; + +static unsigned long saltbits; +static long old_salt; +static unsigned long *bits28, *bits24; +static unsigned char init_perm[64], final_perm[64]; +static unsigned long en_keysl[16], en_keysr[16]; +static unsigned long de_keysl[16], de_keysr[16]; +static int des_initialised = 0; +static unsigned char m_sbox[4][4096]; +static unsigned long psbox[4][256]; +static unsigned long ip_maskl[8][256], ip_maskr[8][256]; +static unsigned long fp_maskl[8][256], fp_maskr[8][256]; +static unsigned long key_perm_maskl[8][128], key_perm_maskr[8][128]; +static unsigned long comp_maskl[8][128], comp_maskr[8][128]; +static unsigned long old_rawkey0, old_rawkey1; + +static unsigned char ascii64[] = +"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; +/* 0000000000111111111122222222223333333333444444444455555555556666 */ +/* 0123456789012345678901234567890123456789012345678901234567890123 */ + +static int ascii_to_bin(char ch) { + if(ch > 'z') + return 0; + if(ch >= 'a') + return ch - 'a' + 38; + if(ch > 'Z') + return 0; + if(ch >= 'A') + return ch - 'A' + 12; + if(ch > '9') + return 0; + if(ch >= '.') + return ch - '.'; + return 0; +} + +static void des_init() { + int i, j, b, k, inbit, obit; + unsigned long *p, *il, *ir, *fl, *fr; + + old_rawkey0 = old_rawkey1 = 0L; + saltbits = 0L; + old_salt = 0L; + bits24 = (bits28 = bits32 + 4) + 4; + + /* + * Invert the S-boxes, reordering the input bits. + */ + for(i = 0; i < 8; i++) + for(j = 0; j < 64; j++) { + b = (j & 0x20) | ((j & 1) << 4) | ((j >> 1) & 0xf); + u_sbox[i][j] = sbox[i][b]; + } + + /* + * Convert the inverted S-boxes into 4 arrays of 8 bits. + * Each will handle 12 bits of the S-box input. + */ + for(b = 0; b < 4; b++) + for(i = 0; i < 64; i++) + for(j = 0; j < 64; j++) + m_sbox[b][(i << 6) | j] = + (u_sbox[(b << 1)][i] << 4) | + u_sbox[(b << 1) + 1][j]; + + /* + * Set up the initial & final permutations into a useful form, and + * initialise the inverted key permutation. + */ + for(i = 0; i < 64; i++) { + init_perm[final_perm[i] = IP[i] - 1] = i; + inv_key_perm[i] = 255; + } + + /* + * Invert the key permutation and initialise the inverted key + * compression permutation. + */ + for(i = 0; i < 56; i++) { + u_key_perm[i] = key_perm[i] - 1; + inv_key_perm[key_perm[i] - 1] = i; + inv_comp_perm[i] = 255; + } + + /* + * Invert the key compression permutation. + */ + for(i = 0; i < 48; i++) { + inv_comp_perm[comp_perm[i] - 1] = i; + } + + /* + * Set up the OR-mask arrays for the initial and final permutations, + * and for the key initial and compression permutations. + */ + for(k = 0; k < 8; k++) { + for(i = 0; i < 256; i++) { + *(il = &ip_maskl[k][i]) = 0L; + *(ir = &ip_maskr[k][i]) = 0L; + *(fl = &fp_maskl[k][i]) = 0L; + *(fr = &fp_maskr[k][i]) = 0L; + for(j = 0; j < 8; j++) { + inbit = 8 * k + j; + if(i & bits8[j]) { + if((obit = init_perm[inbit]) < 32) + *il |= bits32[obit]; + else + *ir |= bits32[obit-32]; + if ((obit = final_perm[inbit]) < 32) + *fl |= bits32[obit]; + else + *fr |= bits32[obit - 32]; + } + } + } + for(i = 0; i < 128; i++) { + *(il = &key_perm_maskl[k][i]) = 0L; + *(ir = &key_perm_maskr[k][i]) = 0L; + for(j = 0; j < 7; j++) { + inbit = 8 * k + j; + if(i & bits8[j + 1]) { + if((obit = inv_key_perm[inbit]) == 255) + continue; + if(obit < 28) + *il |= bits28[obit]; + else + *ir |= bits28[obit - 28]; + } + } + *(il = &comp_maskl[k][i]) = 0L; + *(ir = &comp_maskr[k][i]) = 0L; + for(j = 0; j < 7; j++) { + inbit = 7 * k + j; + if(i & bits8[j + 1]) { + if((obit=inv_comp_perm[inbit]) == 255) + continue; + if(obit < 24) + *il |= bits24[obit]; + else + *ir |= bits24[obit - 24]; + } + } + } + } + + /* + * Invert the P-box permutation, and convert into OR-masks for + * handling the output of the S-box arrays setup above. + */ + for(i = 0; i < 32; i++) + un_pbox[pbox[i] - 1] = i; + + for(b = 0; b < 4; b++) + for(i = 0; i < 256; i++) { + *(p = &psbox[b][i]) = 0L; + for (j = 0; j < 8; j++) { + if (i & bits8[j]) + *p |= bits32[un_pbox[8 * b + j]]; + } + } + + des_initialised = 1; +} + +static void setup_salt(long salt) { + unsigned long obit, saltbit; + int i; + + if (salt == old_salt) + return; + old_salt = salt; + + saltbits = 0L; + saltbit = 1; + obit = 0x800000; + for (i = 0; i < 24; i++) { + if (salt & saltbit) + saltbits |= obit; + saltbit <<= 1; + obit >>= 1; + } +} + +static int des_setkey(const char *key) { + unsigned long k0, k1, rawkey0, rawkey1; + int shifts, round; + + if(!des_initialised) + des_init(); + + rawkey0 = ntohl(*(unsigned long *) key); + rawkey1 = ntohl(*(unsigned long *) (key + 4)); + + if((rawkey0 | rawkey1) + && rawkey0 == old_rawkey0 + && rawkey1 == old_rawkey1) { + /* + * Already setup for this key. + * This optimisation fails on a zero key (which is weak and + * has bad parity anyway) in order to simplify the starting + * conditions. + */ + return 0; + } + old_rawkey0 = rawkey0; + old_rawkey1 = rawkey1; + + /* + * Do key permutation and split into two 28-bit subkeys. + */ + k0 = key_perm_maskl[0][rawkey0 >> 25] + | key_perm_maskl[1][(rawkey0 >> 17) & 0x7f] + | key_perm_maskl[2][(rawkey0 >> 9) & 0x7f] + | key_perm_maskl[3][(rawkey0 >> 1) & 0x7f] + | key_perm_maskl[4][rawkey1 >> 25] + | key_perm_maskl[5][(rawkey1 >> 17) & 0x7f] + | key_perm_maskl[6][(rawkey1 >> 9) & 0x7f] + | key_perm_maskl[7][(rawkey1 >> 1) & 0x7f]; + k1 = key_perm_maskr[0][rawkey0 >> 25] + | key_perm_maskr[1][(rawkey0 >> 17) & 0x7f] + | key_perm_maskr[2][(rawkey0 >> 9) & 0x7f] + | key_perm_maskr[3][(rawkey0 >> 1) & 0x7f] + | key_perm_maskr[4][rawkey1 >> 25] + | key_perm_maskr[5][(rawkey1 >> 17) & 0x7f] + | key_perm_maskr[6][(rawkey1 >> 9) & 0x7f] + | key_perm_maskr[7][(rawkey1 >> 1) & 0x7f]; + /* + * Rotate subkeys and do compression permutation. + */ + shifts = 0; + for(round = 0; round < 16; round++) { + unsigned long t0, t1; + + shifts += key_shifts[round]; + + t0 = (k0 << shifts) | (k0 >> (28 - shifts)); + t1 = (k1 << shifts) | (k1 >> (28 - shifts)); + + de_keysl[15 - round] = + en_keysl[round] = comp_maskl[0][(t0 >> 21) & 0x7f] + | comp_maskl[1][(t0 >> 14) & 0x7f] + | comp_maskl[2][(t0 >> 7) & 0x7f] + | comp_maskl[3][t0 & 0x7f] + | comp_maskl[4][(t1 >> 21) & 0x7f] + | comp_maskl[5][(t1 >> 14) & 0x7f] + | comp_maskl[6][(t1 >> 7) & 0x7f] + | comp_maskl[7][t1 & 0x7f]; + + de_keysr[15 - round] = en_keysr[round] = + comp_maskr[0][(t0 >> 21) & 0x7f] + | comp_maskr[1][(t0 >> 14) & 0x7f] + | comp_maskr[2][(t0 >> 7) & 0x7f] + | comp_maskr[3][t0 & 0x7f] + | comp_maskr[4][(t1 >> 21) & 0x7f] + | comp_maskr[5][(t1 >> 14) & 0x7f] + | comp_maskr[6][(t1 >> 7) & 0x7f] + | comp_maskr[7][t1 & 0x7f]; + } + return 0; +} + +static int do_des(unsigned long l_in, unsigned long r_in, unsigned long *l_out, + unsigned long *r_out, int count) { + /* + * l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format. + */ + unsigned long l, r, *kl, *kr, *kl1, *kr1; + unsigned long f, r48l, r48r; + int round; + + if(count == 0) { + return 1; + } else if(count > 0) { + /* + * Encrypting + */ + kl1 = en_keysl; + kr1 = en_keysr; + } else { + /* + * Decrypting + */ + count = -count; + kl1 = de_keysl; + kr1 = de_keysr; + } + + /* + * Do initial permutation (IP). + */ + l = ip_maskl[0][l_in >> 24] + | ip_maskl[1][(l_in >> 16) & 0xff] + | ip_maskl[2][(l_in >> 8) & 0xff] + | ip_maskl[3][l_in & 0xff] + | ip_maskl[4][r_in >> 24] + | ip_maskl[5][(r_in >> 16) & 0xff] + | ip_maskl[6][(r_in >> 8) & 0xff] + | ip_maskl[7][r_in & 0xff]; + r = ip_maskr[0][l_in >> 24] + | ip_maskr[1][(l_in >> 16) & 0xff] + | ip_maskr[2][(l_in >> 8) & 0xff] + | ip_maskr[3][l_in & 0xff] + | ip_maskr[4][r_in >> 24] + | ip_maskr[5][(r_in >> 16) & 0xff] + | ip_maskr[6][(r_in >> 8) & 0xff] + | ip_maskr[7][r_in & 0xff]; + + while(count--) { + /* + * Do each round. + */ + kl = kl1; + kr = kr1; + round = 16; + while(round--) { + /* + * Expand R to 48 bits (simulate the E-box). + */ + r48l = ((r & 0x00000001) << 23) + | ((r & 0xf8000000) >> 9) + | ((r & 0x1f800000) >> 11) + | ((r & 0x01f80000) >> 13) + | ((r & 0x001f8000) >> 15); + + r48r = ((r & 0x0001f800) << 7) + | ((r & 0x00001f80) << 5) + | ((r & 0x000001f8) << 3) + | ((r & 0x0000001f) << 1) + | ((r & 0x80000000) >> 31); + /* + * Do salting for crypt() and friends, and + * XOR with the permuted key. + */ + f = (r48l ^ r48r) & saltbits; + r48l ^= f ^ *kl++; + r48r ^= f ^ *kr++; + /* + * Do sbox lookups (which shrink it back to 32 bits) + * and do the pbox permutation at the same time. + */ + f = psbox[0][m_sbox[0][r48l >> 12]] + | psbox[1][m_sbox[1][r48l & 0xfff]] + | psbox[2][m_sbox[2][r48r >> 12]] + | psbox[3][m_sbox[3][r48r & 0xfff]]; + /* + * Now that we've permuted things, complete f(). + */ + f ^= l; + l = r; + r = f; + } + r = l; + l = f; + } + /* + * Do final permutation (inverse of IP). + */ + *l_out = fp_maskl[0][l >> 24] + | fp_maskl[1][(l >> 16) & 0xff] + | fp_maskl[2][(l >> 8) & 0xff] + | fp_maskl[3][l & 0xff] + | fp_maskl[4][r >> 24] + | fp_maskl[5][(r >> 16) & 0xff] + | fp_maskl[6][(r >> 8) & 0xff] + | fp_maskl[7][r & 0xff]; + *r_out = fp_maskr[0][l >> 24] + | fp_maskr[1][(l >> 16) & 0xff] + | fp_maskr[2][(l >> 8) & 0xff] + | fp_maskr[3][l & 0xff] + | fp_maskr[4][r >> 24] + | fp_maskr[5][(r >> 16) & 0xff] + | fp_maskr[6][(r >> 8) & 0xff] + | fp_maskr[7][r & 0xff]; + return 0; +} + +char *crypt(char *key, char *setting) { + unsigned long count, salt, l, r0, r1, keybuf[2]; + unsigned char *p, *q; + static unsigned char output[21]; + + if(!des_initialised) + des_init(); + /* + * Copy the key, shifting each character up by one bit + * and padding with zeros. + */ + q = (unsigned char *)keybuf; + while(q - (unsigned char *)keybuf - 8) { + if((*q++ = *key << 1)) + key++; + } + if(des_setkey((unsigned char *)keybuf)) + return NULL; + + /* + * "old"-style: + * setting - 2 bytes of salt + * key - up to 8 characters + */ + count = 25; + + salt = (ascii_to_bin(setting[1]) << 6) + | ascii_to_bin(setting[0]); + + output[0] = setting[0]; + /* + * If the encrypted password that the salt was extracted from + * is only 1 character long, the salt will be corrupted. We + * need to ensure that the output string doesn't have an extra + * NUL in it! + */ + output[1] = setting[1] ? setting[1] : output[0]; + + p = output + 2; + + setup_salt(salt); + /* + * Do it. + */ + if(do_des(0L, 0L, &r0, &r1, count)) + return NULL; + /* + * Now encode the result... + */ + l = (r0 >> 8); + *p++ = ascii64[(l >> 18) & 0x3f]; + *p++ = ascii64[(l >> 12) & 0x3f]; + *p++ = ascii64[(l >> 6) & 0x3f]; + *p++ = ascii64[l & 0x3f]; + + l = (r0 << 16) | ((r1 >> 16) & 0xffff); + *p++ = ascii64[(l >> 18) & 0x3f]; + *p++ = ascii64[(l >> 12) & 0x3f]; + *p++ = ascii64[(l >> 6) & 0x3f]; + *p++ = ascii64[l & 0x3f]; + + l = r1 << 2; + *p++ = ascii64[(l >> 12) & 0x3f]; + *p++ = ascii64[(l >> 6) & 0x3f]; + *p++ = ascii64[l & 0x3f]; + *p = 0; + + return output; +} +#endif diff --git a/util/expire.c b/util/expire.c new file mode 100644 index 00000000..d6f3e2b9 --- /dev/null +++ b/util/expire.c @@ -0,0 +1,226 @@ +/* $Id: expire.c,v 1.1 2002/03/07 15:13:46 in2 Exp $ */ +/* ¦Û°Ê¬å«H¤u¨ãµ{¦¡ */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include <dirent.h> +#include <fcntl.h> +#include <unistd.h> +#include <time.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/file.h> +#include "config.h" +#include "pttstruct.h" +#include "util.h" + +#define QCAST int (*)(const void *, const void *) + +#define DEF_DAYS 50 +#define DEF_MAXP 2000 +#define DEF_MINP 300 + +#define EXPIRE_CONF BBSHOME "/etc/expire.conf" +extern boardheader_t *bcache; +char *bpath = BBSHOME "/boards"; + +struct life +{ + char bname[16]; /* board ID */ + int days; /* expired days */ + int maxp; /* max post */ + int minp; /* min post */ +}; +typedef struct life life; + + +void + expire(brd) +life *brd; +{ + fileheader_t head; + struct stat state; + char lockfile[128], tmpfile[128], bakfile[128]; + char fpath[128], index[128], *fname; + int total, bid; + int fd, fdr, fdw, done, keep; + int duetime, ftime; + + printf("%s\n", brd->bname); + if((bid = getbnum(brd->bname)) == 0 || + strcmp(brd->bname, bcache[bid-1].brdname)) + { + printf("no such board?: %s\n", brd->bname); + return; + } +#ifdef VERBOSE + if (brd->days < 1) + { + printf(":Err: expire time must more than 1 day.\n"); + return; + } + else if (brd->maxp < 100) + { + printf(":Err: maxmum posts number must more than 100.\n"); + return; + } +#endif + + sprintf(index, "%s/%s/.DIR", bpath, brd->bname); + sprintf(lockfile, "%s.lock", index); + if ((fd = open(lockfile, O_RDWR | O_CREAT | O_APPEND, 0644)) == -1) + return; + flock(fd, LOCK_EX); + + strcpy(fpath, index); + fname = (char *) strrchr(fpath, '.'); + + duetime = time(NULL) - brd->days * 24 * 60 * 60; + done = 0; + if ((fdr = open(index, O_RDONLY, 0)) > 0) + { + fstat(fdr, &state); + total = state.st_size / sizeof(head); + sprintf(tmpfile, "%s.new", index); + unlink(tmpfile); + if ((fdw = open(tmpfile, O_WRONLY | O_CREAT | O_EXCL, 0644)) > 0) + { + while (read(fdr, &head, sizeof head) == sizeof head) + { + done = 1; + ftime = atoi(head.filename + 2); + if (head.owner[0] == '-') + keep = 0; + else if (head.filemode & FILE_MARKED || total <= brd->minp) + keep = 1; + else if (ftime < duetime || total > brd->maxp) + keep = 0; + else + keep = 1; + + if (keep) + { + if (write(fdw, (char *)&head, sizeof head) == -1) + { + done = 0; + break; + } + } + else + { + strcpy(fname, head.filename); + unlink(fpath); + printf("\t%s\n", fname); + total--; + } + } + close(fdw); + } + close(fdr); + } + + if (done) + { + sprintf(bakfile, "%s.old", index); + if (rename(index, bakfile) != -1) + { + rename(tmpfile, index); + touchbtotal(bid); + } + } + flock(fd, LOCK_UN); + close(fd); +} + + +int main(argc, argv) +char *argv[]; +{ + FILE *fin; + int number, count; + life db, table[MAX_BOARD], *key; + struct dirent *de; + DIR *dirp; + char *ptr, *bname, buf[256]; + + resolve_boards(); + db.days = ((argc > 1) && (number = atoi(argv[1])) > 0) ? number : DEF_DAYS; + db.maxp = ((argc > 2) && (number = atoi(argv[2])) > 0) ? number : DEF_MAXP; + db.minp = ((argc > 3) && (number = atoi(argv[3])) > 0) ? number : DEF_MINP; + +/* --------------- */ +/* load expire.ctl */ +/* --------------- */ + + count = 0; + if((fin = fopen(EXPIRE_CONF, "r"))) + { + while (fgets(buf, 256, fin)) + { + if (buf[0] == '#') + continue; + + bname = (char *) strtok(buf, " \t\r\n"); + if (bname && *bname) + { + ptr = (char *) strtok(NULL, " \t\r\n"); + if (ptr && (number = atoi(ptr)) > 0) + { + key = &(table[count++]); + strcpy(key->bname, bname); + key->days = number; + key->maxp = db.maxp; + key->minp = db.minp; + + ptr = (char *) strtok(NULL, " \t\r\n"); + if (ptr && (number = atoi(ptr)) > 0) + { + key->maxp = number; + + ptr = (char *) strtok(NULL, " \t\r\n"); + if (ptr && (number = atoi(ptr)) > 0) + { + key->minp = number; + } + } + } + } + } + fclose(fin); + } + + if (count > 1) + { + qsort(table, count, sizeof(life), (QCAST)strcasecmp); + } + +/* ---------------- */ +/* visit all boards */ +/* ---------------- */ + + if (!(dirp = opendir(bpath))) + { + printf(":Err: unable to open %s\n", bpath); + return -1; + } + + while((de = readdir(dirp))) + { + ptr = de->d_name; + if (ptr[0] > ' ' && ptr[0] != '.') + { + if (count) + key = (life *) bsearch(ptr, table, count, sizeof(life), (QCAST)strcasecmp); + else + key = NULL; + if (!key) + key = &db; + strcpy(key->bname, ptr); + expire(key); + } + } + closedir(dirp); + return 0; +} diff --git a/util/horoscope.c b/util/horoscope.c new file mode 100644 index 00000000..c91db7cd --- /dev/null +++ b/util/horoscope.c @@ -0,0 +1,157 @@ +/* $Id: horoscope.c,v 1.1 2002/03/07 15:13:46 in2 Exp $ */ +#include <stdio.h> +#include <sys/types.h> +#include "config.h" +#include "pttstruct.h" +#include "util.h" +#include "common.h" + +struct userec_t cuser; + +int main() { + int i, j, k; + FILE *fp; + int max, item, maxhoroscope; + + int act[12]; + + char *name[13] = + {"¨d¦Ï", + "ª÷¤û", + "Âù¤l", + "¥¨ÃÉ", + "·à¤l", + "³B¤k", + "¤Ñ¯¯", + "¤ÑÃÈ", + "®g¤â", + "¼¯½~", + "¤ô²~", + "Âù³½", + "" + }; + char *blk[10] = + { + " ", "¢j", "¢k", "¢l", "¢m", + "¢n", "¢o", "¢p", "¢i", "¢i", + }; + + memset(act, 0, sizeof(act)); + if(passwd_mmap()) + exit(1); + for(k = 1; k <= MAX_USERS; k++) { + passwd_query(k, &cuser); + if(!cuser.userid[0]) + continue; + switch (cuser.month) + { + case 1: + if (cuser.day <= 19) + act[9]++; + else + act[10]++; + break; + case 2: + if (cuser.day <= 18) + act[10]++; + else + act[11]++; + break; + case 3: + if (cuser.day <= 20) + act[11]++; + else + act[0]++; + break; + case 4: + if (cuser.day <= 19) + act[0]++; + else + act[1]++; + break; + case 5: + if (cuser.day <= 20) + act[1]++; + else + act[2]++; + break; + case 6: + if (cuser.day <= 21) + act[2]++; + else + act[3]++; + break; + case 7: + if (cuser.day <= 22) + act[3]++; + else + act[4]++; + break; + case 8: + if (cuser.day <= 22) + act[4]++; + else + act[5]++; + break; + case 9: + if (cuser.day <= 22) + act[5]++; + else + act[6]++; + break; + case 10: + if (cuser.day <= 23) + act[6]++; + else + act[7]++; + break; + case 11: + if (cuser.day <= 22) + act[7]++; + else + act[8]++; + break; + case 12: + if (cuser.day <= 21) + act[8]++; + else + act[9]++; + break; + } + } + + for (i = max = maxhoroscope = 0; i < 12; i++) + { + if (act[i] > max) + { + max = act[i]; + maxhoroscope = i; + } + } + + item = max / 30 + 1; + + if ((fp = fopen(BBSHOME"/etc/horoscope", "w")) == NULL) + { + printf("cann't open etc/horoscope\n"); + return 1; + } + + for (i = 0; i < 12; i++) + { + fprintf(fp, " [1;37m%s®y [0;36m", name[i]); + for (j = 0; j < act[i] / item; j++) + { + fprintf(fp, "%2s", blk[9]); + } + /* ¬°¤Fè¦n¤@¶ */ + if (i != 11) + fprintf(fp, "%2s [1;37m%d[m\n\n", blk[(act[i] % item) * 10 / item], + act[i]); + else + fprintf(fp, "%2s [1;37m%d[m\n", blk[(act[i] % item) * 10 / item], + act[i]); + } + fclose(fp); + return 0; +} diff --git a/util/in2outmail b/util/in2outmail Binary files differnew file mode 100644 index 00000000..686944c1 --- /dev/null +++ b/util/in2outmail diff --git a/util/in2outmail.c b/util/in2outmail.c new file mode 100644 index 00000000..fce9cc59 --- /dev/null +++ b/util/in2outmail.c @@ -0,0 +1,288 @@ +/* $Id: in2outmail.c,v 1.1 2002/03/07 15:13:46 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <signal.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <sys/param.h> +#include <sys/file.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include "config.h" +#include "pttstruct.h" + + +#ifdef HAVE_SETPROCTITLE + +#include <sys/types.h> +#include <libutil.h> + +void initsetproctitle(int argc, char **argv, char **envp) { +} + +#else + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> + +char **Argv = NULL; /* pointer to argument vector */ +char *LastArgv = NULL; /* end of argv */ +extern char **environ; + +void initsetproctitle(int argc, char **argv, char **envp) { + register int i; + + /* Move the environment so setproctitle can use the space at + the top of memory. */ + for(i = 0; envp[i]; i++); + environ = malloc(sizeof(char *) * (i + 1)); + for(i = 0; envp[i]; i++) + environ[i] = strdup(envp[i]); + environ[i] = NULL; + + /* Save start and extent of argv for setproctitle. */ + Argv = argv; + if(i > 0) + LastArgv = envp[i - 1] + strlen(envp[i - 1]); + else + LastArgv = argv[argc - 1] + strlen(argv[argc - 1]); +} + +static void do_setproctitle(const char *cmdline) { + char buf[256], *p; + int i; + + strncpy(buf, cmdline, 256); + buf[255] = '\0'; + i = strlen(buf); + if(i > LastArgv - Argv[0] - 2) { + i = LastArgv - Argv[0] - 2; + } + strcpy(Argv[0], buf); + p = &Argv[0][i]; + while(p < LastArgv) + *p++='\0'; + Argv[1] = NULL; +} + +void setproctitle(const char* format, ...) { + char buf[256]; + + va_list args; + va_start(args, format); + vsprintf(buf, format,args); + do_setproctitle(buf); + va_end(args); +} +#endif + + + + + +#define SPOOL BBSHOME "/out" +#define INDEX SPOOL "/.DIR" +#define NEWINDEX SPOOL "/.DIR.sending" +#define FROM ".bbs@" MYHOSTNAME +#define SMTPPORT 25 + +int waitReply(int sock) { + char buf[256]; + + if(read(sock, buf, sizeof(buf)) <= 0) + return -1; + else + return buf[0] - '0'; +} + +int sendRequest(int sock, char *request) { + return write(sock, request, strlen(request)) < 0 ? -1 : 0; +} + +int connectMailServer(char *host) { + int sock; + struct sockaddr_in addr; + + if((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) { + perror("socket"); + return -1; + } + + memset(&addr, 0, sizeof(addr)); +#ifdef FreeBSD + addr.sin_len = sizeof(addr); +#endif + addr.sin_family = AF_INET; + addr.sin_port = htons(SMTPPORT); + addr.sin_addr.s_addr = inet_addr(host); + + if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + perror(RELAY_SERVER_IP); + close(sock); + return -1; + } + + if(waitReply(sock) != 2) { + close(sock); + return -1; + } + + if(sendRequest(sock, "helo " MYHOSTNAME "\n") || waitReply(sock) != 2) { + close(sock); + return -1; + } else + return sock; +} + +void disconnectMailServer(int sock) { + sendRequest(sock, "quit\n"); + /* drop the reply :p */ + close(sock); +} + +void doSendBody(int sock, FILE *fp, char *from, char *to, char *subject) { + int n; + char buf[2048]; + + n = snprintf(buf, sizeof(buf), "From: %s\nTo: %s\nSubject: %s\n\n", + from, to, subject); + write(sock, buf, n); + + while(fgets(buf, sizeof(buf), fp)) { + if(buf[0] == '.' && buf[1] == '\n') + strcpy(buf, "..\n"); + write(sock, buf, strlen(buf)); + } +} + +void doSendMail(int sock, FILE *fp, char *from, char *to, char *subject) { + char buf[256]; + + snprintf(buf, sizeof(buf), "mail from: %s\n", from); + if(sendRequest(sock, buf) || waitReply(sock) != 2) + return; + + snprintf(buf, sizeof(buf), "rcpt to: %s\n", to); + if(sendRequest(sock, buf) || waitReply(sock) != 2) + return; + + if(sendRequest(sock, "data\n") || waitReply(sock) != 3) + return; + + doSendBody(sock, fp, from, to, subject); + + if(sendRequest(sock, "\n.\n") || waitReply(sock) != 2) + return; +} + +void sendMail() { + int fd, sockPTT2, sockHinet; + MailQueue mq; + + if(access(NEWINDEX, R_OK | W_OK)) { + if(link(INDEX, NEWINDEX) || unlink(INDEX)) + /* nothing to do */ + return; + } + + if( (sockPTT2 = connectMailServer("140.112.30.143")) < 0 ){ + fprintf(stderr, "connect server failed...\n"); + return; + } + sockHinet = connectMailServer("61.218.59.183"); + + fd = open(NEWINDEX, O_RDONLY); + flock(fd, LOCK_EX); + while(read(fd, &mq, sizeof(mq)) > 0) { + FILE *fp; + char buf[256]; + + snprintf(buf, sizeof(buf), "%s%s", mq.sender, FROM); + if((fp = fopen(mq.filepath, "r"))) { + setproctitle("outmail: sending %s", mq.filepath); + if( strstr(mq.rcpt, ".edu.tw") || + strstr(mq.rcpt, ".twbbs.org") || + strstr(mq.rcpt, "ptt.cc") || + strstr(mq.rcpt, "ptt2.cc") ){ + printf("relay server: ptt2, to %s\n", mq.rcpt); + doSendMail(sockPTT2, fp, buf, mq.rcpt, mq.subject); + } + else{ + printf("relay server: ezmain, to %s\n", mq.rcpt); + doSendMail( (sockHinet > 0) ? sockHinet : sockPTT2, + fp, buf, mq.rcpt, mq.subject); + } + fclose(fp); + unlink(mq.filepath); + } else { + perror(mq.filepath); + } + } + flock(fd, LOCK_UN); + close(fd); + unlink(NEWINDEX); + + if( sockHinet > 0 ) + disconnectMailServer(sockHinet); + disconnectMailServer(sockPTT2); +} + +void listQueue() { + int fd; + + if((fd = open(INDEX, O_RDONLY)) >= 0) { + int counter = 0; + MailQueue mq; + + flock(fd, LOCK_EX); + while(read(fd, &mq, sizeof(mq)) > 0) { + printf("%s:%s -> %s:%s\n", mq.filepath, mq.username, mq.rcpt, + mq.subject); + counter++; + } + flock(fd, LOCK_UN); + close(fd); + printf("\nTotal: %d mails in queue\n", counter); + } else { + perror(INDEX); + } +} + +void usage() { + fprintf(stderr, "usage: outmail [-qh]\n"); +} + +void wakeup(int s) { +} + +int main(int argc, char **argv, char **envp) { + int ch; + + signal(SIGHUP, wakeup); + initsetproctitle(argc, argv, envp); + + if(chdir(BBSHOME)) + return 1; + while((ch = getopt(argc, argv, "qh")) != -1) { + switch(ch) { + case 'q': + listQueue(); + return 0; + default: + usage(); + return 0; + } + } + for(;;) { + sendMail(); + setproctitle("outmail: sleeping"); + sleep(60 * 3); /* send mail every 3 minute */ + } + return 0; +} diff --git a/util/initbbs.c b/util/initbbs.c new file mode 100644 index 00000000..ce6c4361 --- /dev/null +++ b/util/initbbs.c @@ -0,0 +1,223 @@ +/* $Id: initbbs.c,v 1.1 2002/03/07 15:13:46 in2 Exp $ */ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <time.h> +#include <sys/types.h> +#include <sys/stat.h> +#include "config.h" +#include "pttstruct.h" +#include "perm.h" + +static void initDir() { + mkdir("adm", 0755); + mkdir("boards", 0755); + mkdir("etc", 0755); + mkdir("man", 0755); + mkdir("man/boards", 0755); + mkdir("out", 0755); + mkdir("tmp", 0755); +} + +static void initHome() { + int i; + char buf[256]; + + mkdir("home", 0755); + strcpy(buf, "home/?"); + for(i = 0; i < 26; i++) { + buf[5] = 'A' + i; + mkdir(buf, 0755); + buf[5] = 'a' + i; + mkdir(buf, 0755); + } +} + +static void initPasswds() { + int i; + userec_t u; + FILE *fp = fopen(".PASSWDS", "w"); + + memset(&u, 0, sizeof(u)); + if(fp) { + for(i = 0; i < MAX_USERS; i++) + fwrite(&u, sizeof(u), 1, fp); + fclose(fp); + } +} + +static void newboard(FILE *fp, boardheader_t *b) { + char buf[256]; + + fwrite(b, sizeof(boardheader_t), 1, fp); + sprintf(buf, "boards/%s", b->brdname); + mkdir(buf, 0755); + sprintf(buf, "man/boards/%s", b->brdname); + mkdir(buf, 0755); +} + +static void initBoards() { + FILE *fp = fopen(".BOARDS", "w"); + boardheader_t b; + + if(fp) { + memset(&b, 0, sizeof(b)); + + strcpy(b.brdname, "SYSOP"); + strcpy(b.title, "¼Tù ¡·¯¸ªø¦n!"); + b.brdattr = BRD_POSTMASK | BRD_NOTRAN | BRD_NOZAP; + b.level = 0; + b.gid = 2; + + newboard(fp, &b); + strcpy(b.brdname, "1..........."); + strcpy(b.title, ".... £U¤¤¥¡¬F©² ¡m°ªÀ£¦MÀI,«D¤H¥i¼Ä¡n"); + b.brdattr = BRD_GROUPBOARD; + b.level = PERM_SYSOP; + b.gid = 1; + newboard(fp, &b); + + strcpy(b.brdname, "junk"); + strcpy(b.title, "µo¹q ¡·Âø¤CÂø¤Kªº©U§£"); + b.brdattr = BRD_NOTRAN; + b.level = PERM_SYSOP; + b.gid = 2; + newboard(fp, &b); + + strcpy(b.brdname, "Security"); + strcpy(b.title, "µo¹q ¡·¯¸¤º¨t²Î¦w¥þ"); + b.brdattr = BRD_NOTRAN; + b.level = PERM_SYSOP; + b.gid = 2; + newboard(fp, &b); + + strcpy(b.brdname, "2..........."); + strcpy(b.title, ".... £U¥«¥Á¼s³õ ³ø§i ¯¸ªø £¡I"); + b.brdattr = BRD_GROUPBOARD; + b.level = 0; + b.gid = 1; + newboard(fp, &b); + + strcpy(b.brdname, "ALLPOST"); + strcpy(b.title, "¼Tù ¡·¸óªO¦¡LOCAL·s¤å³¹"); + b.brdattr = BRD_POSTMASK | BRD_NOTRAN; + b.level = PERM_SYSOP; + b.gid = 5; + newboard(fp, &b); + + strcpy(b.brdname, "deleted"); + strcpy(b.title, "¼Tù ¡·¸ê·½¦^¦¬µ©"); + b.brdattr = BRD_NOTRAN; + b.level = PERM_BM; + b.gid = 5; + newboard(fp, &b); + + strcpy(b.brdname, "Note"); + strcpy(b.title, "¼Tù ¡·°ÊºA¬ÝªO¤Îºq¦±§ë½Z"); + b.brdattr = BRD_NOTRAN; + b.level = 0; + b.gid = 5; + newboard(fp, &b); + + strcpy(b.brdname, "Record"); + strcpy(b.title, "¼Tù ¡·§Ú̪º¦¨ªG"); + b.brdattr = BRD_NOTRAN | BRD_POSTMASK; + b.level = 0; + b.gid = 5; + newboard(fp, &b); + + + strcpy(b.brdname, "WhoAmI"); + strcpy(b.title, "¼Tù ¡·¨þ¨þ¡A²q²q§Ú¬O½Ö¡I"); + b.brdattr = BRD_NOTRAN; + b.level = 0; + b.gid = 5; + newboard(fp, &b); + + strcpy(b.brdname, "EditExp"); + strcpy(b.title, "¼Tù ¡·½d¥»ºëÆF§ë½Z°Ï"); + b.brdattr = BRD_NOTRAN; + b.level = 0; + b.gid = 5; + newboard(fp, &b); + + fclose(fp); + } +} + +static void initMan() { + FILE *fp; + fileheader_t f; + time_t t = time(NULL); + struct tm *tm = localtime(&t); + + memset(&f, 0, sizeof(f)); + f.savemode = 0; + strcpy(f.owner, "SYSOP"); + sprintf(f.date, "%2d/%02d", tm->tm_mon + 1, tm->tm_mday); + f.money = 0; + f.filemode = 0; + + if((fp = fopen("man/boards/Note/.DIR", "w"))) { + strcpy(f.filename, "SONGBOOK"); + strcpy(f.title, "¡» ¡iÂI ºq ºq ¥»¡j"); + fwrite(&f, sizeof(f), 1, fp); + mkdir("man/boards/Note/SONGBOOK", 0755); + + strcpy(f.filename, "SONGO"); + strcpy(f.title, "¡» <ÂIºq> °ÊºA¬ÝªO"); + fwrite(&f, sizeof(f), 1, fp); + mkdir("man/boards/Note/SONGO", 0755); + + strcpy(f.filename, "SYS"); + strcpy(f.title, "¡» <¨t²Î> °ÊºA¬ÝªO"); + fwrite(&f, sizeof(f), 1, fp); + mkdir("man/boards/Note/SYS", 0755); + + strcpy(f.filename, "AD"); + strcpy(f.title, "¡» <¼s§i> °ÊºA¬ÝªO"); + fwrite(&f, sizeof(f), 1, fp); + mkdir("man/boards/Note/AD", 0755); + + strcpy(f.filename, "NEWS"); + strcpy(f.title, "¡» <·s»D> °ÊºA¬ÝªO"); + fwrite(&f, sizeof(f), 1, fp); + mkdir("man/boards/Note/NEWS", 0755); + + fclose(fp); + } + +} + +static void initSymLink() { + symlink(BBSHOME "/man/boards/Note/SONGBOOK", BBSHOME "/etc/SONGBOOK"); + symlink(BBSHOME "/man/boards/Note/SONGO", BBSHOME "/etc/SONGO"); + symlink(BBSHOME "/man/boards/EditExp", BBSHOME "/etc/editexp"); +} + +static void initHistory() { + FILE *fp = fopen("etc/history.data", "w"); + + if(fp) { + fprintf(fp, "0 0 0 0"); + fclose(fp); + } +} + +int main() { + if(chdir(BBSHOME)) { + perror(BBSHOME); + exit(1); + } + + initDir(); + initHome(); + initPasswds(); + initBoards(); + initMan(); + initSymLink(); + initHistory(); + + return 0; +} diff --git a/util/inndBM.c b/util/inndBM.c new file mode 100644 index 00000000..426fa6f5 --- /dev/null +++ b/util/inndBM.c @@ -0,0 +1,194 @@ +/* ¨Ì¾Ú .BOARDÀÉ & newsfeeds.bbs ¦C¥X°Ñ»PÂà«Hªº©Ò¦³ªO¸ê®Æ */ + +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/shm.h> +#include "config.h" +#include "pttstruct.h" +#define INNDHOME BBSHOME"/innd" + +#define INND_NEWSFEED INNDHOME "/newsfeeds.bbs" +#define INND_NODELIST INNDHOME "/nodelist.bbs" +#define INND_SCRIPT INNDHOME "/bbsnnrpall.auto.sh" + +extern bcache_t *brdshm; +extern boardheader_t *bcache; +extern int numboards; +int istran[MAX_BOARD]; + +typedef +struct newssvr_t +{ + char name[30]; + char address[256]; + char type[10]; +}newssvr_t; + +typedef +struct newsfeed_t +{ + char group[128]; + char board[15]; + char server[30]; +}newsfeed_t; + +newssvr_t server[128]; +newsfeed_t feedline[MAX_BOARD]; +int servercount; +int feedcount; + +int newsfeed_cmp(newsfeed_t *a,newsfeed_t *b) +{ + int i; + i=strcasecmp(a->server,b->server); + if(i) return i; + return strcasecmp(a->board,b->board); +} + +int get_server(char *name) +{ + int i; + for(i=0;i<servercount;i++) + if(!strcasecmp(server[i].name,name)) + {return i;} + return -1; +} + +int load_server() +{ + FILE *fp; + char str[128]; + + if (!(fp = fopen(INND_NODELIST, "r"))) + { + return 0; + } + + for(servercount=0; fgets(str, 128, fp); servercount++) + { + if(str[0]=='#') continue; + sscanf(str,"%s %s %s",server[servercount].name, + server[servercount].address, + server[servercount].type); + } + fclose(fp); + return servercount; +} + +int load_newsfeeds() +{ + int bid; + FILE *fp; + char str[128]; + if (!(fp = fopen(INND_NEWSFEED, "r"))) + { + return 0; + } + + for(feedcount=0; fgets(str, 128, fp); feedcount++) + { + if(str[0]=='#') continue; + sscanf(str,"%s %s %s", + feedline[feedcount].group,feedline[feedcount].board, + feedline[feedcount].server); + bid=getbnum(feedline[feedcount].board); + if(!bid) {feedcount--;continue; /*²¾°£¨S¦³ªº¬ÝªOi*/} + strcpy(feedline[feedcount].board,bcache[bid-1].brdname); + /*®Õ¥¿¤j¤p¼g */ + + istran[bid-1]=1; + + } + fclose(fp); + qsort(feedline, feedcount, sizeof(newsfeed_t), newsfeed_cmp); + return feedcount; +} +int dobbsnnrp(char *serverstr, int serverid,FILE *fpscript) +{ + char buf[256]; + printf("set %s\r\n",serverstr); + strtok(serverstr,";\r\n"); + strtok(server[serverid].address,";\r\n"); //¨¾hack + sprintf(buf,INNDHOME"/bbsnnrp -c %s " + INNDHOME"/active/%s.auto.active >>" + INNDHOME"/log/inndBM.log 2>>" + INNDHOME"/log/inndBM.log.err &\r\n", + server[serverid].address, + serverstr); + system(buf); + if(fpscript) + fprintf(fpscript,INNDHOME"/bbsnnrp %s " + INNDHOME"/active/%s.auto.active >>" + INNDHOME"/log/inndBM.log 2>>" + INNDHOME"/log/inndBM.log.err &\r\n", + server[serverid].address,serverstr); + return 0; +} +int main() +{ + int i,serverid=0; + FILE *fp=NULL,*fpscript=fopen(INND_SCRIPT,"w"); + char buf[256],serverstr[30]=""; + resolve_boards(); + memset(istran,0,sizeof(int)*MAX_BOARD); + load_server(); + load_newsfeeds(); + + for(i=0;i<feedcount;i++) + { + if(strcasecmp(serverstr,feedline[i].server)) + { + if(get_server(feedline[i].server)==-1) continue; + if(fp) { + fclose(fp); + dobbsnnrp(serverstr,serverid,fpscript); + } + strcpy(serverstr,feedline[i].server); + serverid=get_server(feedline[i].server); + sprintf(buf,INNDHOME"/active/%s.auto.active",serverstr); + fp=fopen(buf,"w"); + } + if(fp) + fprintf(fp,"%-35s 0000000000 0000000000 y\r\n",feedline[i].group); + } + if(fp) + { + dobbsnnrp(serverstr,serverid,fpscript); + fclose(fp); + } + if(fpscript) + { + fclose(fpscript); + chmod(INND_SCRIPT,0700); + } + + // «³]Âà«H»P¤£Âà«Hª©¼Ð°O + for(i=0;i<numboards;i++) + { + if(bcache[i].brdname[0]=='\0' || + (bcache[i].brdattr & BRD_GROUPBOARD) ) continue; + if((bcache[i].brdattr & BRD_NOTRAN )&& istran[i]) + { + while(brdshm->busystate) {safe_sleep(1);} + brdshm->busystate = 1; + bcache[i].brdattr = bcache[i].brdattr & ~BRD_NOTRAN; + strncpy(bcache[i].title + 5, "¡´", 2); + brdshm->busystate = 0; + + substitute_record(BBSHOME"/.BOARDS", &bcache[i],sizeof(boardheader_t),i+1); + } + else if(!(bcache[i].brdattr & BRD_NOTRAN) && !istran[i]) + { + while(brdshm->busystate) {safe_sleep(1);} + brdshm->busystate = 1; + bcache[i].brdattr = bcache[i].brdattr | BRD_NOTRAN; + strncpy(bcache[i].title + 5, "¡·", 2); + brdshm->busystate = 0; + substitute_record(BBSHOME"/.BOARDS", &bcache[i],sizeof(boardheader_t),i+1); + } + + } + return 0; +} diff --git a/util/jungo.c b/util/jungo.c new file mode 100644 index 00000000..15096b30 --- /dev/null +++ b/util/jungo.c @@ -0,0 +1,202 @@ +#include <stdio.h> +#include <sys/types.h> +#include <unistd.h> +#include <string.h> +#include <stdlib.h> +#include <time.h> +#include <ctype.h> +#include "config.h" +#include "pttstruct.h" +#include "util.h" +#include "perm.h" +#include "common.h" + +#define OUTFILE BBSHOME "/etc/toplazyBBM" +#define FIREFILE BBSHOME "/etc/topfireBBM" + +extern boardheader_t *bcache; +extern int numboards; + +boardheader_t allbrd[MAX_BOARD]; +extern userec_t xuser; +typedef struct lostbm { + char *bmname; + char *title; + char *ctitle; + int lostdays; +} lostbm; +lostbm lostbms[MAX_BOARD]; + +typedef struct BMarray{ + char *bmname; + int flag; +} BMArray; +BMArray bms[3]; + +int bmlostdays_cmp(const void *va, const void *vb) +{ + lostbm *a=(lostbm *)va, *b=(lostbm *)vb; + if (a->lostdays > b->lostdays) return -1; + else if (a->lostdays == b->lostdays) return 0; + else return 1; +} + +int LINK(char* src, char* dst){ + char cmd[200]; + if(symlink(src,dst) == -1) + { + sprintf(cmd, "/bin/cp -R %s %s", src, dst); + return system(cmd); + } + return 0; +} + +int main(int argc, char *argv[]) +{ + int bmid, i, j=0; + FILE *inf, *firef; + + resolve_boards(); + + if(passwd_mmap()) + exit(1); + + memcpy(allbrd,bcache,numboards*sizeof(boardheader_t)); + + /* write out the target file */ + + inf = fopen(OUTFILE, "w+"); + if(inf == NULL){ + printf("open file error : %s\n", OUTFILE); + exit(1); + } + firef = fopen(FIREFILE, "w+"); + if(firef == NULL){ + printf("open file error : %s\n", FIREFILE); + fclose(inf); + exit(1); + } + + fprintf(inf, "ĵ§i: ¤p²ÕªøY©ó¤@Ӥ를¤W¯¸,±N¤©©ó§K¾\n"); + fprintf(inf, + "¬ÝªO¦WºÙ " + " ¤p²Õªø ´X¤Ñ¨S¨Ó°Õ\n" + "---------------------------------------------------" + "-------------------\n"); + + fprintf(firef, "§K¾¤p²Õªø\n"); + fprintf(firef, + "¬ÝªO¦WºÙ " + " ¤p²Õªø ´X¤Ñ¨S¨Ó°Õ\n" + "---------------------------------------------------" + "-------------------\n"); + + + j = 0 ; + for (i = 0; i < numboards; i++) { + char *p, bmbuf[IDLEN * 3 + 3]; + int index = 0, flag = 0, k, n; + p=strtok(allbrd[i].BM,"/ "); + if(p) + do + { + if(allbrd[i].brdname[0] == '\0' || (allbrd[i].brdattr & BRD_GROUPBOARD) ==0 ) continue; + if (*p == '[' ){p[strlen(p)-1]='\0'; p++;} + bmid=getuser(p); + bms[index].bmname = p; + bms[index].flag = 0; + if (((((int)time(NULL)-(int)xuser.lastlogin)/(60*60*24))>=7) + //&& isalpha(allbrd[i].brdname[0]) + && isalpha(allbrd[i].BM[0]) + && !(xuser.userlevel & PERM_SYSOP)) + { + lostbms[j].bmname = p; + lostbms[j].title = allbrd[i].brdname; + lostbms[j].ctitle = allbrd[i].title; + lostbms[j].lostdays = + ((int)time(NULL)-(int)xuser.lastlogin)/(60*60*24); + + printf("%s\n", lostbms[j].title); + //¶W¹L¤»¤Q¤Ñ §K¾ + if(lostbms[j].lostdays > 30){ + xuser.userlevel &= ~PERM_BM; + bms[index].flag = 1; + flag = 1; + } + j++; + } + index++; + } while((p=strtok(NULL,"/ "))!=NULL); + + //±qª©¥D¦W³æ®³±¼¦W¦r + + if(flag == 1){ + bmbuf[0] = '\0'; + for(k = 0 , n = 0; k < index; k++){ + if(!bms[k].flag){ + if( n++ != 0) strcat(bmbuf, "/"); + strcat(bmbuf, bms[k].bmname); + } + } + strcpy(bcache[i].BM, bmbuf); + } + + } + qsort(lostbms, j, sizeof(lostbm), bmlostdays_cmp); + + //write to the etc/toplazyBBM + for ( i=0; i<j; i++) + { + if( lostbms[i].lostdays > 7){ + fprintf(firef, "%-*.*s%-*.*s%-*.*s%3d¤Ñ¨S¤W¯¸\n", IDLEN, IDLEN, lostbms[i].title, + BTLEN-10, BTLEN-10, lostbms[i].ctitle, IDLEN,IDLEN, + lostbms[i].bmname,lostbms[i].lostdays); + }else{ + fprintf(inf, "%-*.*s%-*.*s%-*.*s%3d¤Ñ¨S¤W¯¸\n", IDLEN, IDLEN, lostbms[i].title, + BTLEN-10, BTLEN-10, lostbms[i].ctitle, IDLEN,IDLEN, + lostbms[i].bmname,lostbms[i].lostdays); + } + } + fclose(inf); + fclose(firef); + + //printf("Total %d boards.\n", count); + + //mail to the users + for( i=0; i<j; i++) + { + fileheader_t mymail; + char genbuf[200]; + int lostdays; + + lostdays = lostbms[i].lostdays; + + if( (lostdays != 14) || (lostdays != 21) ) // 14 21 ¤Ñ¤£µo«H + continue; + + sprintf(genbuf, BBSHOME "/home/%c/%s", lostbms[i].bmname[0], lostbms[i].bmname); + stampfile(genbuf, &mymail); + + strcpy(mymail.owner, "[PTTĵ¹î§½]"); + + if(lostdays <= 60){ + sprintf(mymail.title, + "\033[32m [¤p²Õªø§K¾ĵ§i³qª¾] \033[m %s BM %s", lostbms[i].title, lostbms[i].bmname); + }else{ + sprintf(mymail.title, + "\033[32m [¤p²Õªø§K¾³qª¾] \033[m %s BM %s", lostbms[i].title, lostbms[i].bmname); + } + mymail.savemode = 0 ; + unlink(genbuf); + if(lostdays <= 60){ + LINK(OUTFILE, genbuf); + }else{ + LINK(FIREFILE, genbuf); + } + + sprintf(genbuf, BBSHOME "/home/%c/%s/.DIR", lostbms[i].bmname[0], lostbms[i].bmname); + append_record(genbuf, &mymail, sizeof(mymail)); + } + + return 0; +} diff --git a/util/kenben.c b/util/kenben.c new file mode 100644 index 00000000..5733f4da --- /dev/null +++ b/util/kenben.c @@ -0,0 +1,44 @@ +#include <stdio.h> + + +void main() +{ + FILE * fin, * fout; + char line[255], line2[255]; + int i; + char genbuf[255], tok[20]; + fin = fopen("M.1006277896.A","r"); + while(!feof(fin)) + { + fgets(line,255,fin); + line[12] = '\0'; + + sprintf(genbuf, "cd ~/boards/%s;grep " + "¶W¹L¤@Ó¤ëµL¼s§i¥H¥~ªº¥»¯¸¤å³¹µoªí¡C" + " *.A > ~/pttbbs/util/kenken.txt",line); + system(genbuf); + + fout = fopen("kenken.txt","r"); + while(!feof(fout)) + { + line2[0] = '\0'; + fgets(line2,255,fout); + if(strlen(line2) <= 10) break; + sscanf(line2,"%s:",tok); + for(i = 0; i < 20;i++) + { + if(tok[i] == ':') + { + tok[i] = '\0'; + break; + } + } + sprintf(genbuf, "cd ~/boards/%s;rm %s",line, tok); +// printf("%s \n", genbuf); + system(genbuf); + } + } + + fclose(fin); + +} diff --git a/util/mailog.sh b/util/mailog.sh new file mode 100644 index 00000000..da89ae3d --- /dev/null +++ b/util/mailog.sh @@ -0,0 +1,9 @@ +#!/bin/sh +# $Id: mailog.sh,v 1.1 2002/03/07 15:13:46 in2 Exp $ +# +# ¾ã²z¥X¼s§i«H¦W³æ + +bin/antispam +bin/post Record ¤µ¤é¹Hªk¼s§i«H¦W³æ [Pttĵ¹î§½] etc/spam +bin/post Security ¯¸¥~¨Ó«H¬ö¿ýmailog [¨t²Î¦w¥þ§½] etc/mailog +rm etc/mailog diff --git a/util/mandex.c b/util/mandex.c new file mode 100644 index 00000000..9373f814 --- /dev/null +++ b/util/mandex.c @@ -0,0 +1,263 @@ +/* $Id: mandex.c,v 1.1 2002/03/07 15:13:46 in2 Exp $ */ + +/* + target : ºëµØ°Ï¯Á¤Þµ{¦¡ (man index) + + syntax : mandex [board] + [board] ¦³È ==> ¥u¶]¸Ó board + ªÅªº ==> ©Ò¦³ªº boards ³£¶] +*/ + + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <dirent.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include "config.h" +#include "pttstruct.h" +#include "util.h" + +#ifndef MAXPATHLEN +#define MAXPATHLEN 1024 +#endif + +extern int numboards; +extern boardheader_t *bcache; + +char color[4][10] = +{"[1;33m", "[1;32m", "[1;36m", "[1;37m"}; +char fn_index[] = ".index"; +char fn_new[] = ".index.new"; +char index_title[] = "¡· ºëµØ°Ï¥Ø¿ý¯Á¤Þ"; +FILE *fndx; +int ndir; +int nfile; +int index_pos; +char topdir[128], pgem[512], pndx[512]; + +int nb = 0; /* board ¼Æ */ + +struct boardinfo +{ + char bname[40]; + int ndir; + int nfile; + int k; +}; +typedef struct boardinfo boardinfo; + +boardinfo +board[MAX_BOARD]; + +int k_cmp(b, a) + boardinfo *b, *a; +{ + return ((a->k / 100 + a->ndir + a->nfile) - (b->k / 100 + b->ndir + b->nfile)); +} + +int dashd(fname) + char *fname; +{ + struct stat st; + + return (stat(fname, &st) == 0 && S_ISDIR(st.st_mode)); +} + + +/* visit the hierarchy recursively */ + +void +mandex(level, num_header, fpath) + int level; + char *fpath, *num_header; +{ + FILE *fgem; + char *fname, buf[256]; + struct stat st; + int count; + fileheader_t fhdr; + + fgem = fopen(fpath, "r+"); + if (fgem == NULL) + return; + + fname = strrchr(fpath, '.'); + if (!level) + { + + printf("%s\r\n",fpath); + strcpy(pgem, fpath); + + strcpy(fname, fn_new); + fndx = fopen(fpath, "w"); + if (fndx == NULL) + { + fclose(fgem); + return; + } + fprintf(fndx, "[1;32m§Ç¸¹\t\t\tºëµØ°Ï¥DÃD[m\n" + "[36m¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w[m\n"); + strcpy(pndx, fpath); + ndir = nfile = 0; + index_pos = -1; + } + + count = 0; + while (fread(&fhdr, sizeof(fhdr), 1, fgem) == 1) + { + strcpy(fname, fhdr.filename); + if (!fname[0]) continue; + if (!level && !strncmp(fhdr.title, index_title, strlen(index_title)) + && index_pos < 0) + { + index_pos = count; + unlink(fpath); + } + st.st_size = 0; + stat(fpath, &st); + + sprintf(buf, "%.*s%s%3d. %s [m\n", + + 11 * level, num_header, color[level % 4], ++count, fhdr.title); /* Ptt */ + fputs(buf, fndx); + if (dashd(fpath)) + { + ++ndir; + if (*fhdr.title != '#' && level < 10) + { + strcat(fpath, "/.DIR"); + mandex(level + 1, buf, fpath); + } + } + else + ++nfile; + } + + if (!level) + { + char lpath[MAXPATHLEN]; + + fclose(fndx); + strcpy(fname, fn_index); + rename(pndx, fpath); + strcpy(pndx, fpath); + + sprintf(buf, "%s.new", pgem); + if (index_pos >= 0 || (fndx = fopen(buf, "w"))) + { + fname[-1] = 0; + stamplink(fpath, &fhdr); + unlink(fpath); + strcpy(fhdr.owner, "¨C¤Ñ¦Û°Ê§ó·s"); + sprintf(lpath, "%s/%s", topdir, pndx); + st.st_size = 0; + stat(lpath, &st); + sprintf(fhdr.title, "%s (%.1fk)", index_title, st.st_size / 1024.); + board[nb].k = st.st_size; /* Ptt */ + printf("(%d)[%dK]", nb, board[nb].k); + symlink(lpath, fpath); + if (index_pos < 0) + { + fwrite(&fhdr, sizeof(fhdr), 1, fndx); + rewind(fgem); + while (fread(&fhdr, sizeof(fhdr), 1, fgem) == 1) + fwrite(&fhdr, sizeof(fhdr), 1, fndx); + fclose(fndx); + fclose(fgem); + rename(buf, pgem); + } + else + { + fseek(fgem, index_pos * sizeof(fhdr), 0); + fwrite(&fhdr, sizeof(fhdr), 1, fgem); + fclose(fgem); + } + return; + } + } + fclose(fgem); +} + + +int main(int argc, char* argv[]){ + boardheader_t *bptr; + DIR *dirp; + struct dirent *de; + int ch, n; + int place = 0; + char *fname, fpath[MAXPATHLEN]; + + resolve_boards(); + nb = 0; + if(argc == 1){ + puts("Creating the whole index..."); + chdir(strcpy(topdir, BBSHOME)); + strcpy(fpath, "man/.DIR"); + mandex(0, "", fpath); + } + + + chdir(strcpy(topdir, BBSHOME "/man/boards")); + + if(argc > 1) { + sprintf(fpath, "%s/.DIR", argv[1]); + mandex(0, "", fpath); + exit(0); + } + + /* process all boards */ + + if(!(dirp = opendir(topdir))) { + printf("## unable to enter [man/boards]\n"); + exit(-1); + } + + while((de = readdir(dirp))){ + fname = de->d_name; + ch = fname[0]; + if (ch != '.'){ + board[nb].k = 0; + strcpy(board[nb].bname, fname); + sprintf(fpath, "%s/.DIR", fname); + mandex(0, "", fpath); + printf("%-14sd: %d\tf: %d\n", fname, ndir, nfile); /* report */ + board[nb].ndir = ndir; + board[nb].nfile = nfile; + if (board[nb].k) + nb++; + } + } + closedir(dirp); + + qsort(board, nb, sizeof(boardinfo), k_cmp); + + if (!(fndx = fopen(BBSHOME "/etc/topboardman", "w"))) + exit(0); + + fprintf(fndx, "[1;44m±Æ¦W[47;30m ¬Ý ª© ¥Ø¿ý¼Æ ÀÉ®×¼Æ" + " byte¼Æ [30m Á` ¤À ª© ¥D [m\n"); + + for (ch = 0; ch < nb; ch++){ + for (n = 0; n < numboards; n++){ + bptr = &bcache[n]; + if (!strcmp(bptr->brdname, board[ch].bname)) + break; + } + if (n >= numboards || + (bptr->brdattr & (BRD_BAD | BRD_NOCOUNT | BRD_HIDE))) + continue; + if (board[ch].ndir + board[ch].nfile < 5) + break; + fprintf(fndx, "%3d.[33m%15s[m %5d %7d %10d %6d [31m%-24.24s[m\n", + ++place, + board[ch].bname, + board[ch].ndir, board[ch].nfile, board[ch].k + ,board[ch].k / 100 + board[ch].nfile + board[ch].ndir + ,bptr->BM); + } + fclose(fndx); + exit(0); +} diff --git a/util/merge_board.c b/util/merge_board.c new file mode 100644 index 00000000..743ffc14 --- /dev/null +++ b/util/merge_board.c @@ -0,0 +1,106 @@ +/* $Id: merge_board.c,v 1.1 2002/03/07 15:13:46 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include <string.h> +#include <sys/types.h> +#include "config.h" +#include "pttstruct.h" + +typedef struct hash_t { + char *brdname; + struct hash_t *next; +} hash_t; + +FILE *fout; +hash_t *hash_tbl[65536]; +int counter; + +void usage() { + fprintf(stderr, "Usage:\n\n" + "merge_board <output file> [input file1] [input file2] ...\n"); +} + +unsigned int string_hash(unsigned char *s) { + unsigned int v=0; + + while(*s) { + v = (v << 8) | (v >> 24); + v ^= toupper(*s++); /* note this is case insensitive */ + } + return (v * 2654435769UL) >> (32 - 16); +} + +int is_exist(char *brdname) { + int i; + hash_t *n; + + i = string_hash(brdname); + for(n = hash_tbl[i]; n != NULL; n = n->next) + if(strcasecmp(brdname, n->brdname) == 0) + return 1; + return 0; +} + +void add_hash(char *brdname) { + int i; + hash_t *n; + + i = string_hash(brdname); + + n = malloc(sizeof(*n)); + n->brdname = strdup(brdname); + n->next = hash_tbl[i]; + hash_tbl[i] = n; +} + +void merge_board(boardheader_t *b) { + if(!is_exist(b->brdname)) { + fwrite(b, sizeof(*b), 1, fout); + add_hash(b->brdname); + ++counter; + } +} + +void merge_file(char *fname) { + FILE *fin; + boardheader_t b; + + if((fin = fopen(fname, "r")) == NULL) { + perror(fname); + return; + } + + counter = 0; + while(fread(&b, sizeof(b), 1, fin) == 1) + if(b.brdname[0]) + merge_board(&b); + + printf("merge from %s: %d boards\n", fname, counter); + + fclose(fin); +} + +int main(int argc, char **argv) { + int i; + + if(argc < 2) { + usage(); + return 1; + } + + bzero(hash_tbl, sizeof(hash_tbl)); + + if((fout = fopen(argv[1], "w")) == NULL) { + perror(argv[1]); + return 2; + } + + for(i = 2; i < argc; ++i) + merge_file(argv[i]); + + fclose(fout); + printf("Done\n"); + + return 0; +} diff --git a/util/merge_passwd.c b/util/merge_passwd.c new file mode 100644 index 00000000..d27c473b --- /dev/null +++ b/util/merge_passwd.c @@ -0,0 +1,106 @@ +/* $Id: merge_passwd.c,v 1.1 2002/03/07 15:13:46 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include <string.h> +#include <sys/types.h> +#include "config.h" +#include "pttstruct.h" + +typedef struct hash_t { + char *userid; + struct hash_t *next; +} hash_t; + +FILE *fout; +hash_t *hash_tbl[65536]; +int counter; + +void usage() { + fprintf(stderr, "Usage:\n\n" + "merge_passwd <output file> [input file1] [input file2] ...\n"); +} + +unsigned int string_hash(unsigned char *s) { + unsigned int v=0; + + while(*s) { + v = (v << 8) | (v >> 24); + v ^= toupper(*s++); /* note this is case insensitive */ + } + return (v * 2654435769UL) >> (32 - 16); +} + +int is_exist(char *userid) { + int i; + hash_t *n; + + i = string_hash(userid); + for(n = hash_tbl[i]; n != NULL; n = n->next) + if(strcasecmp(userid, n->userid) == 0) + return 1; + return 0; +} + +void add_hash(char *userid) { + int i; + hash_t *n; + + i = string_hash(userid); + + n = malloc(sizeof(*n)); + n->userid = strdup(userid); + n->next = hash_tbl[i]; + hash_tbl[i] = n; +} + +void merge_user(userec_t *u) { + if(!is_exist(u->userid)) { + fwrite(u, sizeof(*u), 1, fout); + add_hash(u->userid); + ++counter; + } +} + +void merge_file(char *fname) { + FILE *fin; + userec_t u; + + if((fin = fopen(fname, "r")) == NULL) { + perror(fname); + return; + } + + counter = 0; + while(fread(&u, sizeof(u), 1, fin) == 1) + if(u.userid[0]) + merge_user(&u); + + printf("merge from %s: %d users\n", fname, counter); + + fclose(fin); +} + +int main(int argc, char **argv) { + int i; + + if(argc < 2) { + usage(); + return 1; + } + + bzero(hash_tbl, sizeof(hash_tbl)); + + if((fout = fopen(argv[1], "w")) == NULL) { + perror(argv[1]); + return 2; + } + + for(i = 2; i < argc; ++i) + merge_file(argv[i]); + + fclose(fout); + printf("Done\n"); + + return 0; +} diff --git a/util/opendice.sh b/util/opendice.sh new file mode 100644 index 00000000..767e213a --- /dev/null +++ b/util/opendice.sh @@ -0,0 +1,10 @@ +#!/bin/sh +# $Id: opendice.sh,v 1.1 2002/03/07 15:13:46 in2 Exp $ + +bin/countalldice > etc/dice.dis +bin/post Record "»ë¤l¤¤¼ú¦W³æ" "[»ë¤l³ø§i]" etc/windice.log +bin/post Security "»ë¤l¥¢±Ñ¦W³æ" "[»ë¤l³ø§i]" etc/lostdice.log +bin/post Security "»ë¤l´Á±æÈ" "[»ë¤l³ø§i]" etc/dice.dis +rm -f etc/windice.log +rm -f etc/lostdice.log +rm -f etc/dice.dis diff --git a/util/openticket.c b/util/openticket.c new file mode 100644 index 00000000..69b9ab2a --- /dev/null +++ b/util/openticket.c @@ -0,0 +1,198 @@ +/* $Id: openticket.c,v 1.1 2002/03/07 15:13:46 in2 Exp $ */ +/* ¶}¼úªº utility */ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <time.h> +#include <sys/types.h> +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "util.h" + + +static char *betname[8] = {"Ptt", "Jaky", "Action", "Heat", + "DUNK", "Jungo", "waiting", "wofe"}; + +#define MAX_DES 7 /* ³Ì¤j«O¯d¼ú¼Æ */ + +extern userec_t xuser; + +int Link(char *src, char *dst) +{ + char cmd[200]; + + if (link(src, dst) == 0) + return 0; + + sprintf(cmd, "/bin/cp -R %s %s", src, dst); + return system(cmd); +} + +char * + Cdatelite(clock) +time_t *clock; +{ + static char foo[18]; + struct tm *mytm = localtime(clock); + + strftime(foo, 18, "%D %T", mytm); + return (foo); +} + + +int main() +{ + int money, bet, n, total = 0, ticket[8] = + {0, 0, 0, 0, 0, 0, 0, 0}; + FILE *fp; + time_t now = time(NULL); + char des[MAX_DES][200] = + {"", "", "", ""}; + extern struct utmpfile_t *utmpshm; + + if(passwd_mmap()) + exit(1); + + rename(BBSHOME "/etc/" FN_TICKET_RECORD, + BBSHOME "/etc/" FN_TICKET_RECORD ".tmp"); + rename(BBSHOME "/etc/" FN_TICKET_USER, + BBSHOME "/etc/" FN_TICKET_USER ".tmp"); + + if (!(fp = fopen(BBSHOME "/etc/"FN_TICKET_RECORD ".tmp", "r"))) + return 0; + fscanf(fp, "%9d %9d %9d %9d %9d %9d %9d %9d\n", + &ticket[0], &ticket[1], &ticket[2], &ticket[3], + &ticket[4], &ticket[5], &ticket[6], &ticket[7]); + for (n = 0; n < 8; n++) + total += ticket[n]; + fclose(fp); + + if (!total) + return 0; + + if((fp = fopen(BBSHOME "/etc/" FN_TICKET , "r"))) + { + for (n = 0; n < MAX_DES && fgets(des[n], 200, fp); n++) ; + fclose(fp); + } + +/* + *srandom(33); // ©T©w¤@Ó seed ¦ýºÉ¶qnÁקK¸ò§O¤Hªºseed¦P + * + *for( n = (now / (60*60*3)) - 62820; n >0; n--) random(); + */ + +/* + * ¥¿½Tªºrandom number generatorªº¥Îªk + * ¬O¥Î¦P¤@Ó seed«á¨ú ²Ä¤@Ó ²Ä¤GÓ ¦a¤TÓ.... ¼Æ + * srand() ³]§¹seed«á + * ¨C©I¥s¤@¦¸rand()´N¨ú¤U¤@Ó¼Æ + * + * ¦ý¦]¬°§Ų́S¦³°O¿ý¤W¦¸¨ú¨ì²Ä´XÓ + * ©Ò¥H¥Î¨C¼W¥|¤p®É()´N¦h¨ú¤@¦¸ => now / (60*60*4) (¨C¤¤p®É¶}¤@¦¸¼ú) + * (´î 61820 ¬O´î¤Ö loop ¼Æ) + * + * ¥»¨Ó¬O¥Îsrand(time(0)) ¤£¬O¥¿½Tªº¥Îªk + * ¦]¬°¶}¼ú®É¶¡¦³³W²v ©Ò¥H·|³Q§ä¥X³W«ß + * + * ~Ptt + */ +/* + *bet=random() % 8; + */ + + resolve_utmp(); + bet = utmpshm->number % 8; + +/* + + * ¦bC¤¤ srand ¸ò srandom ¤@¼Ë rand ¸ò random ¤@¼Ë + * ¤£¦Pªº¬O rand ¬O¶Ç¦^¤@Ó double µ¹«D¾ã¼Æªº¶Ã¼Æ¥Î + * random ¬O¶Ç¦^¤@Ó int µ¹¾ã¼Æªº¶Ã¼Æ¥Î + * + * Yn¥Hrand inplement ¾ã¼Æªº¶Ã¼Æ nª`·N¥H¤U (man page¤¤¦³) + * + * In Numerical Recipes in C: The Art of Scientific Computing + * (William H. Press, Brian P. Flannery, Saul A. Teukolsky, + * William T. Vetterling; New York: Cambridge University + * Press, 1990 (1st ed, p. 207)), the following comments are + * made: + * "If you want to generate a random integer between 1 + * and 10, you should always do it by + * + * j=1+(int) (10.0*rand()/(RAND_MAX+1.0)); + * + * and never by anything resembling + * + * j=1+((int) (1000000.0*rand()) % 10); + * + * (which uses lower-order bits)." + * + * Random-number generation is a complex topic. The Numeri- + * cal Recipes in C book (see reference above) provides an + * excellent discussion of practical random-number generation + * issues in Chapter 7 (Random Numbers). + * ~ Ptt + */ + + + money = ticket[bet] ? total * 95 / ticket[bet] : 9999999; + + if((fp = fopen(BBSHOME "/etc/" FN_TICKET, "w"))) + { + if (des[MAX_DES - 1][0]) + n = 1; + else + n = 0; + + for (; n < MAX_DES && des[n][0] != 0; n++) + { + fprintf(fp, des[n]); + } + + printf("\n\n¶}¼ú®É¶¡¡G %s \n\n" + "¶}¼úµ²ªG¡G %s \n\n" + "¤Uª`Á`ª÷ÃB¡G %d00 ¤¸ \n" + "¤¤¼ú¤ñ¨Ò¡G %d±i/%d±i (%f)\n" + "¨C±i¤¤¼ú±m²¼¥i±o %d ªT¢Þ¹ô \n\n", + Cdatelite(&now), betname[bet], total, ticket[bet], total, + (float) ticket[bet] / total, money); + + fprintf(fp, "%s ½ä½L¶}¥X:%s Á`ª÷ÃB:%d00 ¤¸ ¼úª÷/±i:%d ¤¸ ¾÷²v:%1.2f\n", + Cdatelite(&now), betname[bet], total, money, + (float) ticket[bet] / total); + fclose(fp); + + } + + if (ticket[bet] && (fp = fopen(BBSHOME "/etc/" FN_TICKET_USER ".tmp", "r"))) + { + int mybet, num, uid; + char userid[20], genbuf[200]; + fileheader_t mymail; + + while (fscanf(fp, "%s %d %d\n", userid, &mybet, &num) != EOF) + { + if (mybet == bet) + { + printf("®¥³ß %-15s¶R¤F%9d ±i %s, Àò±o %d ªT¢Þ¹ô\n" + ,userid, num, betname[mybet], money * num); + if((uid=getuser(userid))==0) continue; + deumoney(uid, money * num); + sprintf(genbuf, BBSHOME "/home/%c/%s", userid[0], userid); + stampfile(genbuf, &mymail); + strcpy(mymail.owner, BBSNAME); + sprintf(mymail.title, "[%s] ¤¤¼úÅo! $ %d", Cdatelite(&now), money * num); + mymail.savemode = 0; + unlink(genbuf); + Link(BBSHOME "/etc/ticket", genbuf); + sprintf(genbuf, BBSHOME "/home/%c/%s/.DIR", userid[0], userid); + append_record(genbuf, &mymail, sizeof(mymail)); + } + } + } + unlink(BBSHOME "/etc/" FN_TICKET_RECORD ".tmp"); + unlink(BBSHOME "/etc/" FN_TICKET_USER ".tmp"); + return 0; +} diff --git a/util/openticket.sh b/util/openticket.sh new file mode 100644 index 00000000..8274e5c3 --- /dev/null +++ b/util/openticket.sh @@ -0,0 +1,10 @@ +#!/bin/sh +# $Id: openticket.sh,v 1.1 2002/03/07 15:13:46 in2 Exp $ + +bin/openticket > etc/jackpot +bin/post Record "±m¨é¤¤¼ú¦W³æ" "[½ä³õ³ø§i]" etc/jackpot +bin/post Record "²q¼Æ¦r¤¤¼ú¦W³æ" "[²q¼Æ¦r³ø§i]" etc/winguess.log +bin/post Record "¶Â¥Õ´Ñ¹ï¾Ô°O¿ý" "[²q¼Æ¦r³ø§i]" etc/othello.log +rm -f etc/winguess.log +rm -f etc/loseguess.log +rm -f etc/othello.log diff --git a/util/openvice.c b/util/openvice.c new file mode 100644 index 00000000..9b5e438f --- /dev/null +++ b/util/openvice.c @@ -0,0 +1,54 @@ +/* $Id: openvice.c,v 1.1 2002/03/07 15:13:46 in2 Exp $ */ +/* µo²¼¶}¼ú¤pµ{¦¡ */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include "config.h" +#include "pttstruct.h" +#include "util.h" + +#define VICE_SHOW BBSHOME "/etc/vice.show1" +#define VICE_BINGO BBSHOME "/etc/vice.bingo" +#define VICE_NEW "vice.new" +#define VICE_DATA "vice.data" +#define MAX_BINGO 99999999 + +int main() +{ + char TABLE[5][3] = + {"¤@", "¤G", "¤T", "¥|", "¤"}; + + int i = 0, bingo, base = 0; + + + FILE *fp = fopen(VICE_SHOW, "w"), *fb = fopen(VICE_BINGO, "w"); + + extern struct utmpfile_t *utmpshm; + resolve_utmp(); + + srand(utmpshm->number); + + if (!fp || !fb ) + perror("error open file"); + + + bingo = rand() % MAX_BINGO; + fprintf(fp, "%1c[1;33m²Î¤@µo²¼¤¤¼ú¸¹½X[m\n", ' '); + fprintf(fp, "%1c[1;37m================[m\n", ' '); + fprintf(fp, "%1c[1;31m¯S§O¼ú[m: [1;31m%08d[m\n\n", ' ', bingo); + fprintf(fb, "%d\n", bingo); + + while (i < 5) + { + bingo = (base + rand()) % MAX_BINGO; + fprintf(fp, "%1c[1;36m²Ä%s¼ú[m: [1;37m%08d[m\n", ' ', TABLE[i], bingo); + fprintf(fb, "%08d\n", bingo); + i++; + } + fclose(fp); + fclose(fb); + return 0; +} diff --git a/util/outmail.c b/util/outmail.c new file mode 100644 index 00000000..d6b19bb4 --- /dev/null +++ b/util/outmail.c @@ -0,0 +1,274 @@ +/* $Id: outmail.c,v 1.1 2002/03/07 15:13:46 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <signal.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <sys/param.h> +#include <sys/file.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include "config.h" +#include "pttstruct.h" + + +#ifdef HAVE_SETPROCTITLE + +#include <sys/types.h> +#include <libutil.h> + +void initsetproctitle(int argc, char **argv, char **envp) { +} + +#else + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> + +char **Argv = NULL; /* pointer to argument vector */ +char *LastArgv = NULL; /* end of argv */ +extern char **environ; + +void initsetproctitle(int argc, char **argv, char **envp) { + register int i; + + /* Move the environment so setproctitle can use the space at + the top of memory. */ + for(i = 0; envp[i]; i++); + environ = malloc(sizeof(char *) * (i + 1)); + for(i = 0; envp[i]; i++) + environ[i] = strdup(envp[i]); + environ[i] = NULL; + + /* Save start and extent of argv for setproctitle. */ + Argv = argv; + if(i > 0) + LastArgv = envp[i - 1] + strlen(envp[i - 1]); + else + LastArgv = argv[argc - 1] + strlen(argv[argc - 1]); +} + +static void do_setproctitle(const char *cmdline) { + char buf[256], *p; + int i; + + strncpy(buf, cmdline, 256); + buf[255] = '\0'; + i = strlen(buf); + if(i > LastArgv - Argv[0] - 2) { + i = LastArgv - Argv[0] - 2; + } + strcpy(Argv[0], buf); + p = &Argv[0][i]; + while(p < LastArgv) + *p++='\0'; + Argv[1] = NULL; +} + +void setproctitle(const char* format, ...) { + char buf[256]; + + va_list args; + va_start(args, format); + vsprintf(buf, format,args); + do_setproctitle(buf); + va_end(args); +} +#endif + + + + + +#define SPOOL BBSHOME "/out" +#define INDEX SPOOL "/.DIR" +#define NEWINDEX SPOOL "/.DIR.sending" +#define FROM ".bbs@" MYHOSTNAME +#define SMTPPORT 25 + +int waitReply(int sock) { + char buf[256]; + + if(read(sock, buf, sizeof(buf)) <= 0) + return -1; + else + return buf[0] - '0'; +} + +int sendRequest(int sock, char *request) { + return write(sock, request, strlen(request)) < 0 ? -1 : 0; +} + +int connectMailServer() { + int sock; + struct sockaddr_in addr; + + if((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) { + perror("socket"); + return -1; + } + + memset(&addr, 0, sizeof(addr)); +#ifdef FreeBSD + addr.sin_len = sizeof(addr); +#endif + addr.sin_family = AF_INET; + addr.sin_port = htons(SMTPPORT); + addr.sin_addr.s_addr = inet_addr(RELAY_SERVER_IP); + + if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + perror(RELAY_SERVER_IP); + close(sock); + return -1; + } + + if(waitReply(sock) != 2) { + close(sock); + return -1; + } + + if(sendRequest(sock, "helo " MYHOSTNAME "\n") || waitReply(sock) != 2) { + close(sock); + return -1; + } else + return sock; +} + +void disconnectMailServer(int sock) { + sendRequest(sock, "quit\n"); + /* drop the reply :p */ + close(sock); +} + +void doSendBody(int sock, FILE *fp, char *from, char *to, char *subject) { + int n; + char buf[2048]; + + n = snprintf(buf, sizeof(buf), "From: %s\nTo: %s\nSubject: %s\n\n", + from, to, subject); + write(sock, buf, n); + + while(fgets(buf, sizeof(buf), fp)) { + if(buf[0] == '.' && buf[1] == '\n') + strcpy(buf, "..\n"); + write(sock, buf, strlen(buf)); + } +} + +void doSendMail(int sock, FILE *fp, char *from, char *to, char *subject) { + char buf[256]; + + snprintf(buf, sizeof(buf), "mail from: %s\n", from); + if(sendRequest(sock, buf) || waitReply(sock) != 2) + return; + + snprintf(buf, sizeof(buf), "rcpt to: %s\n", to); + if(sendRequest(sock, buf) || waitReply(sock) != 2) + return; + + if(sendRequest(sock, "data\n") || waitReply(sock) != 3) + return; + + doSendBody(sock, fp, from, to, subject); + + if(sendRequest(sock, "\n.\n") || waitReply(sock) != 2) + return; +} + +void sendMail() { + int fd, sock; + MailQueue mq; + + if(access(NEWINDEX, R_OK | W_OK)) { + if(link(INDEX, NEWINDEX) || unlink(INDEX)) + /* nothing to do */ + return; + } + + if((sock = connectMailServer()) < 0) { + fprintf(stderr, "connect server failed...\n"); + return; + } + + fd = open(NEWINDEX, O_RDONLY); + flock(fd, LOCK_EX); + while(read(fd, &mq, sizeof(mq)) > 0) { + FILE *fp; + char buf[256]; + + snprintf(buf, sizeof(buf), "%s%s", mq.sender, FROM); + if((fp = fopen(mq.filepath, "r"))) { + setproctitle("outmail: sending %s", mq.filepath); + doSendMail(sock, fp, buf, mq.rcpt, mq.subject); + fclose(fp); + unlink(mq.filepath); + } else { + perror(mq.filepath); + } + } + flock(fd, LOCK_UN); + close(fd); + unlink(NEWINDEX); + + disconnectMailServer(sock); +} + +void listQueue() { + int fd; + + if((fd = open(INDEX, O_RDONLY)) >= 0) { + int counter = 0; + MailQueue mq; + + flock(fd, LOCK_EX); + while(read(fd, &mq, sizeof(mq)) > 0) { + printf("%s:%s -> %s:%s\n", mq.filepath, mq.username, mq.rcpt, + mq.subject); + counter++; + } + flock(fd, LOCK_UN); + close(fd); + printf("\nTotal: %d mails in queue\n", counter); + } else { + perror(INDEX); + } +} + +void usage() { + fprintf(stderr, "usage: outmail [-qh]\n"); +} + +void wakeup(int s) { +} + +int main(int argc, char **argv, char **envp) { + int ch; + + signal(SIGHUP, wakeup); + initsetproctitle(argc, argv, envp); + + if(chdir(BBSHOME)) + return 1; + while((ch = getopt(argc, argv, "qh")) != -1) { + switch(ch) { + case 'q': + listQueue(); + return 0; + default: + usage(); + return 0; + } + } + for(;;) { + sendMail(); + setproctitle("outmail: sleeping"); + sleep(60 * 3); /* send mail every 3 minute */ + } + return 0; +} diff --git a/util/parse_news.c b/util/parse_news.c new file mode 100644 index 00000000..bebed3f4 --- /dev/null +++ b/util/parse_news.c @@ -0,0 +1,78 @@ +/* $Id: parse_news.c,v 1.1 2002/03/07 15:13:46 in2 Exp $ */ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include "config.h" +#include "pttstruct.h" +#include "util.h" + +#define NEWSDIRECT BBSHOME "/boards/newspaper" +#define MOVIEDIRECT BBSHOME "/etc/NEWS" + +int main() { + int fd; + fileheader_t fh, news; + struct stat st; + register int numfiles, n; + FILE *fp = NULL; + char buf[200]; + + if (stat(NEWSDIRECT "/.DIR", &st) < 0) + return 0; + + system("rm -f " MOVIEDIRECT "/*"); + system("rm -f " MOVIEDIRECT "/.DIR"); + + numfiles = st.st_size / sizeof(fileheader_t); + n = 0; + if ((fd = open(NEWSDIRECT "/.DIR", O_RDONLY)) > 0) + { + lseek(fd, st.st_size - sizeof(fileheader_t), SEEK_SET); + while (numfiles-- && n < 100) + { + read(fd, &fh, sizeof(fileheader_t)); + if (!strcmp(fh.owner, "CNA-News.")) + { + if (!strstr(fh.title, "¬¡°Ê¹w§i") && !strstr(fh.title, "¤¤¥¡®ð¶H§½") + && !strstr(fh.title, "¾ú¥v¤Wªº¤µ¤Ñ") && !strstr(fh.title, "ÀY±ø·s»D¼ÐÃD") + && !strstr(fh.title, "Summary") && !strstr(fh.title, "¥þ²y®ð¶H¤@Äý") + && !strstr(fh.title, "®Õ¥¿¤½¹q")) + { + if (!(n % 10)) + { + if (n) + { + fclose(fp); + append_record(MOVIEDIRECT "/.DIR", &news, sizeof(news)); + } + strcpy(buf, MOVIEDIRECT); + stampfile(buf, &news); + sprintf(news.title, "¤¤¥¡ªÀ§Y®É·s»D %s", fh.date); + strcpy(news.owner, "CNA-News."); + news.savemode = 0; + if (!(fp = fopen(buf, "w"))) + return (0); + fprintf(fp, "[34m ¢w¢w¢w¢w¢w¢w¢w¢w¢w[47;30m ¤¤¥¡ªÀ§Y®É·s»D[31m (%s)[m[34m¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w\n", + fh.date); + } + fprintf(fp, " ¢w¢w¢w¢w¢w[33m¡º[m [1;3%dm%s [m[34m%.*s\n", + (n % 6 + 4) % 7 + 1, fh.title, + (int)(46 - strlen(fh.title)), + "¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w"); + n++; + printf("[%d]\n", n); + + } + } + lseek(fd, -(off_t) 2 * sizeof(fileheader_t), SEEK_CUR); + } + close(fd); + fclose(fp); + append_record(MOVIEDIRECT "/.DIR", &news, sizeof(news)); + } + return 0; +} diff --git a/util/post.c b/util/post.c new file mode 100644 index 00000000..efec797f --- /dev/null +++ b/util/post.c @@ -0,0 +1,61 @@ +/* $Id: post.c,v 1.1 2002/03/07 15:13:46 in2 Exp $ */ +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <time.h> +#include "config.h" +#include "pttstruct.h" +#include "util.h" + +void keeplog(FILE *fin, char *fpath, char *board, char *title, char *owner) { + fileheader_t fhdr; + char genbuf[256], buf[512]; + FILE *fout; + int bid; + + sprintf(genbuf, BBSHOME "/boards/%s", board); + stampfile(genbuf, &fhdr); + + if(!(fout = fopen(genbuf, "w"))) { + perror(genbuf); + return; + } + + while(fgets(buf, 512, fin)) + fputs(buf, fout); + + fclose(fin); + fclose(fout); + + strncpy(fhdr.title, title, sizeof(fhdr.title) - 1); + fhdr.title[sizeof(fhdr.title) - 1] = '\0'; + + strcpy(fhdr.owner, owner); + sprintf(genbuf, BBSHOME "/boards/%s/.DIR", board); + append_record(genbuf, &fhdr, sizeof(fhdr)); + if((bid = getbnum(board)) > 0) + touchbtotal(bid); + +} + +int main(int argc, char **argv) { + FILE *fp; + + resolve_boards(); + if(argc != 5) { + printf("usage: %s <board name> <title> <owner> <file>\n", argv[0]); + return 0; + } + + if(strcmp(argv[4], "-") == 0) + fp = stdin; + else { + fp = fopen(argv[4], "r"); + if(!fp) { + perror(argv[4]); + return 1; + } + } + keeplog(fp, argv[4], argv[1], argv[2], argv[3]); + return 0; +} diff --git a/util/poststat.c b/util/poststat.c new file mode 100644 index 00000000..3aa3cc94 --- /dev/null +++ b/util/poststat.c @@ -0,0 +1,497 @@ +/* $Id: poststat.c,v 1.1 2002/03/07 15:13:46 in2 Exp $ */ +/* ²Îp¤µ¤é¡B¶g¡B¤ë¡B¦~¼öªù¸ÜÃD */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <time.h> +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/shm.h> + +#ifdef __FreeBSD__ +#include <machine/param.h> +#endif + +#include "config.h" +#include "pttstruct.h" + +char *myfile[] = +{"day", "week", "month", "year"}; +int mycount[4] = +{7, 4, 12}; +int mytop[] = +{10, 50, 100, 100}; +char *mytitle[] = +{"¤é¤Q", "¶g¤¤Q", "¤ë¦Ê", "¦~«×¦Ê"}; + + +#define HASHSIZE 1024 +#define TOPCOUNT 200 + + +struct postrec +{ + char author[13]; /* author name */ + char board[13]; /* board name */ + char title[66]; /* title name */ + time_t date; /* last post's date */ + int number; /* post number */ + struct postrec *next; /* next rec */ +} +*bucket[HASHSIZE]; + + +/* 100 bytes */ +struct posttop +{ + char author[13]; /* author name */ + char board[13]; /* board name */ + char title[66]; /* title name */ + time_t date; /* last post's date */ + int number; /* post number */ +} +top[TOPCOUNT], *tp; + + + +/* + woju + Cross-fs rename() + */ + +int Rename(char *src, char *dst) +{ + + if (rename(src, dst) == 0) + return 0; +/* + sprintf(cmd, "/bin/mv %s %s", src, dst); + return system(cmd); +*/ + return 0; +} + + + +/*-------------------------------------------------------*/ +/* .BOARDS cache */ +/*-------------------------------------------------------*/ + +struct bcache_t *brdshm; +boardheader_t *bcache; +int numboards = -1; + + +static void +attach_err(shmkey, name) + int shmkey; + char *name; +{ + fprintf(stderr, "[%s error] key = %x\n", name, shmkey); + exit(1); +} + + +static void * +attach_shm(shmkey, shmsize) + int shmkey, shmsize; +{ + void *shmptr; + int shmid; + + shmid = shmget(shmkey, shmsize, 0); + if (shmid < 0) + { + shmid = shmget(shmkey, shmsize, IPC_CREAT | 0600); + if (shmid < 0) + attach_err(shmkey, "shmget"); + shmptr = (void *) shmat(shmid, NULL, 0); + if (shmptr == (void *) -1) + attach_err(shmkey, "shmat"); + memset(shmptr, 0, shmsize); + } + else + { + shmptr = (void *) shmat(shmid, NULL, 0); + if (shmptr == (void *) -1) + attach_err(shmkey, "shmat"); + } + return shmptr; +} + + + +void +resolve_boards() +{ + if (brdshm == NULL) + { + brdshm = attach_shm(BRDSHM_KEY, sizeof(*brdshm)); + if (brdshm->touchtime == 0) + brdshm->touchtime = 1; + bcache = brdshm->bcache; + } + + while (brdshm->uptime < brdshm->touchtime) + { + if (brdshm->busystate) + { + sleep(1); + } + else + { + int fd; + + brdshm->busystate = 1; + + if ((fd = open(".BOARDS", O_RDONLY)) > 0) + { + brdshm->number = read(fd, bcache, MAX_BOARD * sizeof(boardheader_t)) + / sizeof(boardheader_t); + close(fd); + } + + /* µ¥©Ò¦³ boards ¸ê®Æ§ó·s«á¦A³]©w uptime */ + + brdshm->uptime = brdshm->touchtime; + brdshm->busystate = 0; + } + } + numboards = brdshm->number; +} + + +int +ci_strcmp(s1, s2) + register char *s1, *s2; +{ + register int c1, c2, diff; + + do + { + c1 = *s1++; + c2 = *s2++; + if (c1 >= 'A' && c1 <= 'Z') + c1 |= 32; + if (c2 >= 'A' && c2 <= 'Z') + c2 |= 32; + if((diff = c1 - c2)) + return (diff); + } + while (c1); + return 0; +} + +int +get_record(fpath, rptr, size, id) + char *fpath; + char *rptr; + int size, id; +{ + int fd; + + if ((fd = open(fpath, O_RDONLY, 0)) != -1) + { + if (lseek(fd, size * (id - 1), SEEK_SET) != -1) + { + if (read(fd, rptr, size) == size) + { + close(fd); + return 0; + } + } + close(fd); + } + return -1; +} + + +int +getbnum(bname) + char *bname; +{ + register int i; + register boardheader_t *bhdr; + + resolve_boards(); + for (i = 0, bhdr = bcache; i++ < numboards; bhdr++) + /* if (Ben_Perm(bhdr)) */ + if (!ci_strcmp(bname, bhdr->brdname)) + return i; + return 0; +} + + +int +hash(key) + char *key; +{ + int i, value = 0; + + for (i = 0; key[i] && i < 80; i++) + value += key[i] < 0 ? -key[i] : key[i]; + + value = value % HASHSIZE; + return value; +} + + +/* ---------------------------------- */ +/* hash structure : array + link list */ +/* ---------------------------------- */ + + +void +search(t) + struct posttop *t; +{ + struct postrec *p, *q, *s; + int i, found = 0; + + i = hash(t->title); + q = NULL; + p = bucket[i]; + while (p && (!found)) + { + if (!strcmp(p->title, t->title) && !strcmp(p->board, t->board)) + found = 1; + else + { + q = p; + p = p->next; + } + } + if (found) + { + p->number += t->number; + if (p->date < t->date) /* ¨ú¸ûªñ¤é´Á */ + p->date = t->date; + } + else + { + s = (struct postrec *) malloc(sizeof(struct postrec)); + memcpy(s, t, sizeof(struct posttop)); + s->next = NULL; + if (q == NULL) + bucket[i] = s; + else + q->next = s; + } +} + + +int +sort(pp, count) + struct postrec *pp; +{ + int i, j; + + for (i = 0; i <= count; i++) + { + if (pp->number > top[i].number) + { + if (count < TOPCOUNT - 1) + count++; + for (j = count - 1; j >= i; j--) + memcpy(&top[j + 1], &top[j], sizeof(struct posttop)); + + memcpy(&top[i], pp, sizeof(struct posttop)); + break; + } + } + return count; +} + + +void +load_stat(fname) + char *fname; +{ + FILE *fp; + + if((fp = fopen(fname, "r"))) + { + int count = fread(top, sizeof(struct posttop), TOPCOUNT, fp); + fclose(fp); + while (count) + search(&top[--count]); + } +} + + +int +filter(board) + char *board; +{ + boardheader_t bh; + int bid; + + bid = getbnum(board); + if (get_record(".BOARDS", &bh, sizeof(bh), bid) == -1) + return 1; + if (bh.brdattr & BRD_NOCOUNT) + return 1; +/* + if (bh.brdattr & BRD_POSTMASK) + return 0; + return (bh.brdattr & ~BRD_POSTMASK) || + >= 32; +*/ + return 0; +} + + +void +poststat(mytype) + int mytype; +{ + static char *logfile = ".post"; + static char *oldfile = ".post.old"; + + FILE *fp; + char buf[40], curfile[40] = "etc/day.0", *p; + struct postrec *pp; + int i, j; + + if (mytype < 0) + { + /* --------------------------------------- */ + /* load .post and statictic processing */ + /* --------------------------------------- */ + + remove(oldfile); + Rename(logfile, oldfile); + if ((fp = fopen(oldfile, "r")) == NULL) + return; + mytype = 0; + load_stat(curfile); + + while (fread(top, sizeof(struct posttop), 1, fp)) + search(top); + fclose(fp); + } + else + { + /* ---------------------------------------------- */ + /* load previous results and statictic processing */ + /* ---------------------------------------------- */ + + i = mycount[mytype]; + p = myfile[mytype]; + while (i) + { + sprintf(buf, "etc/%s.%d", p, i); + sprintf(curfile, "etc/%s.%d", p, --i); + load_stat(curfile); + Rename(curfile, buf); + } + mytype++; + } + +/* ---------------------------------------------- */ +/* sort top 100 issue and save results */ +/* ---------------------------------------------- */ + + memset(top, 0, sizeof(top)); + for (i = j = 0; i < HASHSIZE; i++) + { + for (pp = bucket[i]; pp; pp = pp->next) + { +#ifdef DEBUG + printf("Title : %s, Board: %s\nPostNo : %d, Author: %s\n" + ,pp->title + ,pp->board + ,pp->number + ,pp->author); +#endif + + j = sort(pp, j); + } + } + + p = myfile[mytype]; + sprintf(curfile, "etc/%s.0", p); + if((fp = fopen(curfile, "w"))) + { + fwrite(top, sizeof(struct posttop), j, fp); + fclose(fp); + } + + sprintf(curfile, "etc/%s", p); + if((fp = fopen(curfile, "w"))) + { + int max, cnt; + + fprintf(fp, "\t\t[1;34m-----[37m=====[41m ¥»%s¤j¼öªù¸ÜÃD [40m=====[34m-----[0m\n\n", mytitle[mytype]); + + max = mytop[mytype]; + p = buf + 4; + for (i = cnt = 0; (cnt < max) && (i < j); i++) + { + tp = &top[i]; + if (filter(tp->board)) + continue; + + strcpy(buf, ctime(&(tp->date))); + buf[20] = 0; + fprintf(fp, + "[1;31m%3d. [33m¬ÝªO : [32m%-16s[35m¡m %s¡n[36m%4d ½g[33m%16s\n" + " [33m¼ÐÃD : [0;44;37m%-60.60s[40m\n" + ,++cnt, tp->board, p, tp->number, tp->author, tp->title); + } + fclose(fp); + } + +/* free statistics */ + + for (i = 0; i < HASHSIZE; i++) + { + struct postrec *pp0; + + pp = bucket[i]; + while (pp) + { + pp0 = pp; + pp = pp->next; + free(pp0); + } + + bucket[i] = NULL; + } +} + + +int main(argc, argv) + char *argv[]; +{ + time_t now; + struct tm *ptime; + + if (argc < 2) + { + printf("Usage:\t%s bbshome [day]\n", argv[0]); + return (-1); + } + chdir(argv[1]); + + if (argc == 3) + { + poststat(atoi(argv[2])); + return (0); + } + time(&now); + ptime = localtime(&now); + if (ptime->tm_hour == 0) + { + if (ptime->tm_mday == 1) + poststat(2); + + if (ptime->tm_wday == 0) + poststat(1); + poststat(0); + } + poststat(-1); + return 0; +} diff --git a/util/reaper.c b/util/reaper.c new file mode 100644 index 00000000..925ea11b --- /dev/null +++ b/util/reaper.c @@ -0,0 +1,69 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <time.h> +#include <syslog.h> +#include <unistd.h> +#include <ctype.h> +#include <sys/types.h> +#include "config.h" +#include "pttstruct.h" +#include "perm.h" +#include "util.h" + +time_t now; + +int invalid(char *userid) { + int i; + + if(!isalpha(userid[0])) + return 1; + + for(i = 1; i < IDLEN && userid[i]; i++) + if(!isalpha(userid[i]) && !isdigit(userid[i])) + return 1; + return 0; +} + +int check(int n, userec_t *u) { + time_t d; + char buf[256]; + + if(u->userid[0] != '\0') { + if(invalid(u->userid)) { + syslog(LOG_ERR, "bad userid(%d): %s", n, u->userid); + u->userid[0] = '\0'; + } else { + d = now - u->lastlogin; + if((d > MAX_GUEST_LIFE && (u->userlevel & PERM_LOGINOK) == 0) || + (d > MAX_LIFE && (u->userlevel & PERM_XEMPT) == 0)) { + /* expired */ + int unum; + + unum = searchuser(u->userid); + strcpy(buf, ctime(&u->lastlogin)); + strtok(buf, "\n"); + syslog(LOG_NOTICE, "kill user(%d): %s %s", unum, u->userid, buf); + sprintf(buf, "mv home/%c/%s tmp/", u->userid[0], u->userid); + if(system(buf)) + syslog(LOG_ERR, "can't move user home: %s", u->userid); + u->userid[0] = '\0'; + setuserid(unum, u->userid); + } + } + } + return 0; +} + +int main() { + now = time(NULL); + openlog("reaper", LOG_PID | LOG_PERROR, SYSLOG_FACILITY); + chdir(BBSHOME); + + if(passwd_mmap()) + exit(1); + passwd_apply2(check); + + return 0; +} diff --git a/util/rmuid.c b/util/rmuid.c new file mode 100644 index 00000000..cc6e12cb --- /dev/null +++ b/util/rmuid.c @@ -0,0 +1,50 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <dirent.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include "config.h" +#include "pttstruct.h" +#include "util.h" + +extern int numboards; +extern boardheader_t *bcache; + +int getbidofuid(int uid) +{ + register int n; boardheader_t *bh; + if(!uid) return 1; + for (n=0;n<numboards;n++) + { + bh = &bcache[n]; + if(bh->unused == uid) + return n+1; + } + return 1; +} + +int main(int argc, char* argv[]){ +struct stat st; + int n; + boardheader_t bh; + char pathname[1024]; + + resolve_boards(); + for (n=0;n<numboards;n++) + { + memcpy( &bh, &bcache[n], sizeof(bh)); + bh.gid=getbidofuid(bh.gid); + //printf("%14.14s%14.14s \r\n",bh.brdname, bh.title); + substitute_record("BOARDS.bid", &bh, sizeof(bh), n+1); + } +} + + + + + + + diff --git a/util/shmsweep.c b/util/shmsweep.c new file mode 100644 index 00000000..01acb26b --- /dev/null +++ b/util/shmsweep.c @@ -0,0 +1,43 @@ +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/shm.h> +#include <sys/stat.h> +#include "config.h" +#include "pttstruct.h" + +int main() { + int i, shm, counter; + struct utmpfile_t *utmpshm; + + + shm = shmget(UTMPSHM_KEY, USHM_SIZE, SHM_R | SHM_W); + if(shm == -1) { + perror("shmget"); + exit(0); + } + + utmpshm = shmat(shm, NULL, 0); + if(utmpshm == (struct utmpfile_t *)-1) { + perror("shmat"); + exit(0); + } + + for(i = counter = 0; i < USHM_SIZE; i++) + if(utmpshm->uinfo[i].pid) { + char buf[256]; + userinfo_t *f; + struct stat sb; + + f = &utmpshm->uinfo[i]; + sprintf(buf, "/proc/%d", f->pid); + if(stat(buf, &sb)) { + f->pid = 0; + utmpshm->number--; + counter++; + } + } + printf("clear %d slots\n", counter); + return 0; +} diff --git a/util/showboard.c b/util/showboard.c new file mode 100644 index 00000000..3801dbb1 --- /dev/null +++ b/util/showboard.c @@ -0,0 +1,70 @@ +/* $Id: showboard.c,v 1.1 2002/03/07 15:13:46 in2 Exp $ */ +/* ¬ÝªO¤@Äýªí(sorted) */ + +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <fcntl.h> +#include "config.h" +#include "pttstruct.h" + +boardheader_t allbrd[MAX_BOARD]; + +int +board_cmp(a, b) + boardheader_t *a, *b; +{ + return (strcasecmp(a->brdname, b->brdname)); +} + + +int main(argc, argv) + int argc; + char *argv[]; +{ + int inf, i, count; + + if (argc < 2) + { + printf("Usage:\t%s .BOARDS [MAXUSERS]\n", argv[0]); + exit(1); + } + + + inf = open(argv[1], O_RDONLY); + if (inf == -1) + { + printf("error open file\n"); + exit(1); + } + +/* read in all boards */ + + i = 0; + memset(allbrd, 0, MAX_BOARD * sizeof(boardheader_t)); + while (read(inf, &allbrd[i], sizeof(boardheader_t)) == sizeof(boardheader_t)) + { + if (allbrd[i].brdname[0] ) + { + i++; + } + } + close(inf); + +/* sort them by name */ + count = i; + qsort(allbrd, count, sizeof(boardheader_t), board_cmp); + +/* write out the target file */ + + printf( + "¬ÝªO¦WºÙ ªO¥D Ãþ§O ¤¤¤å±Ôz\n" + "----------------------------------------------------------------------\n"); + for (i = 0; i < count; i++) + { + printf("%-13s%-25.25s%s\n", allbrd[i].brdname, allbrd[i].BM, allbrd[i].title); + } + return 0; +} diff --git a/util/smtest.c b/util/smtest.c new file mode 100644 index 00000000..16a2360d --- /dev/null +++ b/util/smtest.c @@ -0,0 +1,296 @@ +#include <stdio.h> +#include <sys/types.h> +#include <unistd.h> +#include <string.h> +#include <stdlib.h> +#include <time.h> +#include <ctype.h> +#include "config.h" +#include "pttstruct.h" +#include "util.h" +#include "perm.h" +#include "common.h" +#include "proto.h" + +#define WARNFILE BBSHOME "/etc/DeleteBoard.warn" +#define EXECFILE BBSHOME"/etc/DeleteBoard.exec" +#define WARNLIST BBSHOME"/etc/DeleteBoardList.warn" +#define EXECLIST BBSHOME"/etc/DeleteBoardList.exec" + +extern boardheader_t *bcache; +extern int numboards; + +boardheader_t allbrd[MAX_BOARD]; +extern userec_t xuser; + + +int LINK(char* src, char* dst){ + char cmd[200]; + + if( link(src, dst) == 0){ + return 0; + } + + sprintf(cmd, "/bin/cp -R %s %s", src, dst); + return system(cmd); +} + +int outofdate(char *hdrdate, char thedate[], int *zf) +{ + int k = 0; + char *dd; + char latestdate[6]; + int date1[2], date2[2],datetemp; + *zf = 0; + + strcpy(latestdate, thedate); + + dd = strtok(hdrdate,"/"); + if(dd == NULL) return 2; + if(dd) + k = 0; + do{ + if (*dd == '[' ){dd[strlen(dd)-1]='\0'; dd++;} + date1[k] = atoi(dd); + k++; + } while((dd=strtok(NULL,"/ "))!=NULL); + + dd = strtok(latestdate,"/"); + if(dd) + k = 0; + do{ + if (*dd == '[' ){dd[strlen(dd)-1]='\0'; dd++;} + date2[k] = atoi(dd); + k++; + } while((dd=strtok(NULL,"/ "))!=NULL); + + if(date2[0] == date1[0] && date2[1] >= date1[1]) + return 0; + + datetemp = date2[0]; + + for(k = 1;k <= 5;k++) + { + datetemp -= 1; + if((datetemp) <= 0){ + datetemp = 12; + } + if(k < 3 && datetemp == date1[0]) return 0; + if(k == 3 && datetemp == date1[0] && date2[1] <= date1[1]) return 0; + if(k == 3 && datetemp == date1[0] && date2[1] > date1[1]) return 1; + if(k == 4 && datetemp == date1[0] && date2[1] > date1[1]) return 1; + } + *zf = 1; + return 1; +} + +void mailtouser(char *bmname, char *bname, int zf) +{ + fileheader_t mymail; + char genbuf[200]; + + sprintf(genbuf, BBSHOME "/home/%c/%s", bmname[0], bmname); + stampfile(genbuf, &mymail); + strcpy(mymail.owner, "[PTTĵ¹î§½]"); + + if(zf == 0){ + sprintf(mymail.title,"\033[32m [¼oª©Äµ§i³qª¾]" + "\033[m %sª©(BM:%s)",bname, bmname); + }else{ + sprintf(mymail.title,"\033[32m [¼oª©³qª¾] " + "\033[m %sª©(BM:%s)",bname, bmname); + } + mymail.savemode = 0 ; + unlink(genbuf); + if(zf == 0){ + LINK(WARNFILE, genbuf); + }else{ + LINK(EXECFILE, genbuf); + } + + sprintf(genbuf, BBSHOME "/home/%c/%s/.DIR", bmname[0], bmname); + append_record(genbuf, &mymail, sizeof(mymail)); +} + +int main() +{ + int bmid, i, j, k, rd, ood, flag, zapflag = 0,warncount = 0,execcount = 0; + char *p, *bmsname[3], fname[256], hdrdatetemp[6],thedate[6]; + char bname[32],genbuf[200]; + fileheader_t hdr; + FILE *inf, *def; + + ///// set date ////// + time_t t = time(NULL); + struct tm *tm = localtime(&t); + sprintf(thedate, "%2d/%02d", tm->tm_mon + 1, tm->tm_mday); + + ////// board ////// + + resolve_boards(); + if(passwd_mmap()) + exit(1); + memcpy(allbrd,bcache,numboards*sizeof(boardheader_t)); + + ////// write out the target file ////// + inf = fopen(WARNLIST, "w+"); + if(inf == NULL){ + printf("open file error : %s\n", WARNLIST); + exit(1); + } + + def = fopen(EXECLIST, "w+"); + if(def == NULL) + { + printf("open file error : %s\n", EXECLIST); + exit(1); + } + + ////// fprint table title ///// + fprintf(inf,"\n[¼oª©Äµ§i]§Y¤é°_¤@Ӥ뤺Y¬ÝªO" + "¨Ï¥Î²v¤´µM¹L§C¡A«h¤©¥H¼o°£¡C\n\n" + "^¤åª©¦W Ãþ§O ¤¤¤åª©¦W ¤é´Á " + " ª©¥D¦W³æ\n\n"); + + fprintf(def,"\n[¼oª©¤½§i]¤U¦C¬ÝªO¦]¨Ï¥Î²v¤´µM¹L§C¡A¬G¤©¥H¼o°£¡C\n\n" + "^¤åª©¦W Ãþ§O ¤¤¤åª©¦W ¤é´Á " + " ª©¥D¦W³æ\n\n"); + + ////// start process ///// + j = 0 ; + for (i = 0; i < numboards; i++) { + rd = 0; + if(allbrd[i].brdname[0] == '\0') continue; + if((allbrd[i].brdattr & BRD_NOZAP) || + (allbrd[i].brdattr & BRD_GROUPBOARD) || + (allbrd[i].brdattr & BRD_WARNDEL) || + (allbrd[i].brdattr & BRD_HIDE) || + (allbrd[i].brdattr & BRD_POSTMASK) || + (allbrd[i].brdattr & BRD_VOTEBOARD) || + (allbrd[i].brdattr & BRD_BAD) || + (allbrd[i].level != 0)) continue; + + sprintf(fname, BBSHOME "/boards/%s/.DIR",allbrd[i].brdname); + + /* get date to choose junk board */ + /* exception when ood == 2 */ + flag = 30; + rd = get_num_records(fname, sizeof(fileheader_t)); + if(rd <= 30) + { + get_record(fname, &hdr, sizeof (hdr), 1); + strcpy(hdrdatetemp, hdr.date); + ood = outofdate(hdrdatetemp,thedate, &zapflag); + } + else + { + do{ + if(rd == 0) + { + ood = 0; + break; + } + get_record(fname, &hdr, sizeof (hdr), rd - flag); + strcpy(hdrdatetemp, hdr.date); + ood = outofdate(hdrdatetemp,thedate, &zapflag); + flag += 5; + }while(ood == 2 && flag < 60); + } + if(ood == 0) continue; + + warncount++; + /* print to file */ + fprintf(inf,"%-*.*s%-*.*s %-*.*s%-*.*s\n", IDLEN, IDLEN, + allbrd[i].brdname, BTLEN-26, BTLEN-26, allbrd[i].title, + IDLEN - 5, IDLEN-5,hdr.date, IDLEN * 3, IDLEN * 3, allbrd[i].BM); + + /* post warn file to each board */ + sprintf(genbuf,"~/bin/post %s [¼oª©Äµ§i³qª¾]" + " [PTTĵ¹î§½] %s",allbrd[i].brdname,WARNFILE); + system(genbuf); + + /* user extract to mail */ + p=strtok(allbrd[i].BM,"/ "); + if(p){ + k = 0; + do + { + if (*p == '[' ){p[strlen(p)-1]='\0'; p++;} + bmid=getuser(p); + bmsname[k] = p; + if(isalpha(allbrd[i].BM[0])&& !(xuser.userlevel &PERM_SYSOP)) + { + mailtouser(bmsname[k],allbrd[i].title, zapflag); + } + k++; + } while((p=strtok(NULL,"/ "))!=NULL); + } + /* set attribute of DeleteBoardWarn Flag */ + bcache[i].brdattr = allbrd[i].brdattr | BRD_WARNDEL; + + /* zap boards */ + if (zapflag == 1) + { + execcount++; + /* print to file */ + fprintf(def,"%-*.*s%-*.*s %-*.*s%-*.*s\n", IDLEN, IDLEN, + allbrd[i].brdname, BTLEN-26, BTLEN-26, allbrd[i].title, + IDLEN - 5, IDLEN-5,hdr.date, IDLEN * 3, IDLEN * 3, allbrd[i].BM); + +// strcpy(bname, allbrd[i].brdname); +// sprintf(genbuf, +// "/bin/tar zcvf ~/tmp/board_%s.tgz boards/%s man/%s>/dev/null 2>&1;" +// "/bin/rm -fr ~/boards/%s man/%s",bname, bname, bname, bname,bname); +// system(genbuf); + +// memset(&allbrd[i], 0, sizeof(allbrd[i])); +// sprintf(allbrd[i].title, "[%s] deleted by System", bname); +// substitute_record(fn_board, &bh, sizeof(allbrd[i]), bid); +// reset_board(bid); + } + + } + + /* post to Record, ViolateLaw */ + if(warncount > 0){ + sprintf(genbuf,"~/bin/post Record [¼oª©Äµ§i³qª¾]" + " [PTTĵ¹î§½] %s",WARNLIST); + system(genbuf); + sprintf(genbuf,"~/bin/post ViolateLaw [¼oª©Äµ§i³qª¾]" + " [PTTĵ¹î§½] %s",WARNLIST); + system(genbuf); + } + if(execcount > 0){ + sprintf(genbuf,"~/bin/post Record [¼oª©¤½§i]" + " [PTTĵ¹î§½] %s",EXECLIST); + system(genbuf); + sprintf(genbuf,"~/bin/post ViolateLaw [¼oª©¤½§i]" + " [PTTĵ¹î§½] %s",EXECLIST); + system(genbuf); + } + + +/* Below is for test only */ +/* + mailtouser("Smile","test", 1); + mailtouser("Smile","test", 0); + + strcpy(bname, "Test"); + sprintf(genbuf,"~/bin/post %s test Smile ~/etc/test.fileaaa",bname); + system(genbuf); + + + bid = getbnum(bname); + strcpy(bname,"jourslamdunk"); + sprintf(genbuf, + "/bin/tar zcvf ~/tmp/board_%s.tgz boards/%s man/%s>/dev/null 2>&1;" + "/bin/rm -fr ~/boards/%s man/%s",bname, bname, bname,bname,bname); + system(genbuf); + + memset(&bh, 0, sizeof(bh)); + sprintf(bh.title, "[%s] deleted by %s", bname,cuser.userid); + substitute_record(fn_board, &bh, sizeof(bh), bid); + reset_board(bid); +*/ + return 0; +} diff --git a/util/smtest.c.save b/util/smtest.c.save new file mode 100644 index 00000000..7e678881 --- /dev/null +++ b/util/smtest.c.save @@ -0,0 +1,172 @@ +#include <stdio.h> +#include <sys/types.h> +#include <unistd.h> +#include <string.h> +#include <stdlib.h> +#include <time.h> +#include <ctype.h> +#include "config.h" +#include "pttstruct.h" +#include "util.h" +#include "perm.h" +#include "common.h" +#include "proto.h" + +#define OUTFILE BBSHOME "/pttbbs/util/smtest.result1" +#define FIREFILE BBSHOME "/pttbbs/util/smtest.result2" + +extern boardheader_t *bcache; +extern int numboards; + +boardheader_t allbrd[MAX_BOARD]; +struct userec_t xuser; + +int getuser(char *userid) { + int uid; + if((uid = searchuser(userid))) + passwd_query(uid, &xuser); + return uid; +} + +int LINK(char* src, char* dst){ + char cmd[200]; + + if( link(src, dst) == 0){ + return 0; + } + + sprintf(cmd, "/bin/cp -R %s %s", src, dst); + return system(cmd); +} + +int main() +{ + int bmid, i, j, k, rd; + char *p, *bmsname[3], bmbuf[IDLEN * 3 + 3], fname[256]; + fileheader_t hdr; + FILE *inf; + + resolve_boards(); + if(passwd_mmap()) + exit(1); + memcpy(allbrd,bcache,numboards*sizeof(boardheader_t)); + + /* write out the target file */ + inf = fopen(OUTFILE, "w+"); + if(inf == NULL){ + printf("open file error : %s\n", OUTFILE); + exit(1); + } + + /*the ouput table title*/ + fprintf(inf,"^¤åª©¦W Ãþ§O ¤¤¤åª©¦W ª©¥D¦W³æ" + " ¤é´Á ³Æµù \n"); + + j = 0 ; + for (i = 0; i < 30; i++) { + rd = 0; + if(allbrd[i].brdname[0] == '\0') continue; + + sprintf(fname, BBSHOME "/boards/%s/.DIR",allbrd[i].brdname); + + rd = get_num_records(fname, sizeof(fileheader_t)); + get_record(fname, &hdr, sizeof (hdr), rd - 30); +// printf(" %s %s\n",hdr.title,hdr.date); + + printf("%-*.*s%-*s%s", IDLEN, IDLEN, allbrd[i].brdname, BTLEN, + allbrd[i].title,allbrd[i].BM); + + p=strtok(allbrd[i].BM,"/ "); + if(p){ + int k = 0; + do + { + if (*p == '[' ){p[strlen(p)-1]='\0'; p++;} + bmid=getuser(p); + bmsname[k] = p; + if(isalpha(allbrd[i].BM[0])&& !(xuser.userlevel &PERM_SYSOP)) + { + // printf("%s", bmsname[k]); + } + k++; + } while((p=strtok(NULL,"/ "))!=NULL); + } + + printf("\n"); + +} + + +/* + + + + if(flag == 1){ + bmbuf[0] = '\0'; + for(k = 0 , n = 0; k < index; k++){ + if(!bms[k].flag){ + if( n++ != 0) strcat(bmbuf, "/"); + strcat(bmbuf, bms[k].bmname); + } + } + strcpy(bcache[i].BM, bmbuf); + } + } + qsort(lostbms, j, sizeof(lostbm), bmlostdays_cmp); + + //write to the etc/toplazyBM + for ( i=0; i<j; i++) + { + if( lostbms[i].lostdays > 60){ + fprintf(firef, "%-*.*s%-*.*s%-*.*s%3d¤Ñ¨S¤W¯¸\n", IDLEN, IDLEN, + lostbms[i].title, BTLEN-10, BTLEN-10, lostbms[i].ctitle, IDLEN,IDLEN, + lostbms[i].bmname,lostbms[i].lostdays); + }else{ + fprintf(inf, "%-*.*s%-*.*s%-*.*s%3d¤Ñ¨S¤W¯¸\n", IDLEN, IDLEN, lostbms[i].title, + BTLEN-10, BTLEN-10, lostbms[i].ctitle, IDLEN,IDLEN, + lostbms[i].bmname,lostbms[i].lostdays); + } + } + fclose(inf); + fclose(firef); + + //printf("Total %d boards.\n", count); + + //mail to the users + for( i=0; i<j; i++) + { + fileheader_t mymail; + char genbuf[200]; + int lostdays; + + lostdays = lostbms[i].lostdays; + + if( (lostdays != 30) && (lostdays != 45) && (lostdays <= 60)) + continue; + + sprintf(genbuf, BBSHOME "/home/%c/%s", lostbms[i].bmname[0], lostbms[i].bmname); + stampfile(genbuf, &mymail); + + strcpy(mymail.owner, "[PTTĵ¹î§½]"); + + if(lostdays <= 60){ + sprintf(mymail.title, + "\033[32m [ª©¥D§K¾ĵ§i³qª¾] \033[m %s BM %s", lostbms[i].title, lostbms[i].bmname); + }else{ + sprintf(mymail.title, + "\033[32m [ª©¥D§K¾³qª¾] \033[m %s BM %s", lostbms[i].title, lostbms[i].bmname); + } + mymail.savemode = 0 ; + unlink(genbuf); + if(lostdays <= 60){ + LINK(OUTFILE, genbuf); + }else{ + LINK(FIREFILE, genbuf); + } + + sprintf(genbuf, BBSHOME "/home/%c/%s/.DIR", lostbms[i].bmname[0], lostbms[i].bmname); + append_record(genbuf, &mymail, sizeof(mymail)); + } +*/ + return 0; +} diff --git a/util/smtest.result1 b/util/smtest.result1 new file mode 100644 index 00000000..6dee45ff --- /dev/null +++ b/util/smtest.result1 @@ -0,0 +1,191 @@ +^¤åª©¦W Ãþ§O ¤¤¤åª©¦W ¤é´Á ª©¥D¦W³æ +ck48th301 «Ø¤¤ ¡·¤jºjÀ°¤§§Ö¼Ö¤Ñ° 3/21 ching/carl/Prosecuted +Bowling ¹B°Ê ¡´¨«¹L2000,ÁÚ¦V30 7/18 Genson/chiche +NTUCH-89 ¤Æ¾Ç ¡·²¦·~°Õ¡I¡I 7/10 badora/furtwangler +SetupBBS BBS ¡·TEST://140.112. 8/08 Libra +Fei-cat ¹Ï¤å ¡·23:56 ·L»Ä¨ý 8/07 tears +CKAWE «Ø¤¤ ¡´«Ø¤¤®Õ¤ÍºÞ¼Ö¹Îª 7/04 ckb/papl/trumpet +jourslamdunk«Ý¼o ¡·¬F¤j·s»D¨tÄx²y¶ 7/04 ¼x¨D¤¤ +ck48th308 «Ø¤¤ ¡·¤Sn²¦·~¤F¡I 7/15 honest +CS84Her ¤¤¤s ¡·¦U©bªF¦è ¤]n©M 7/20 +VM ¬P°¨ ¡´¯k¥ú¨}«~«aªº³d¥ 7/20 zoo +E-Diagrams ®Õ¶é ¡·¤@°_¤K¨ö¤¤d¦~. 6/29 Benjamin +ck48th313 «Ø¤¤ ¡´ª©¥D¤£ºÞ¤F,¨ÓÄé 6/08 fantastic +ck48th324 «Ø¤¤ ¡·«¢«¢«¢... 7/10 +B853023XX ¬Fªv ¡·¤½¦æ·s¥@¬ö 8/15 FireKing +ck48th303 «Ø¤¤ ¡·§Lªº¥@¬É 6/05 Roses999/henrry/flyingdog +CS85ee ¤¤¤s ¡·¤j®a¸q°_©¯ºÖ 8/08 admin/MVPgirl +CS85simple ¤¤¤s ¡·Â²¯Z¤H-¤£Â²³æ 3/29 bbeellaa +TFG95TRUE ¥_¤@ ¡·¯u¯ZªGµæ¶é 3/29 deceanna +ck46th318 «Ø¤¤ ¡· ¯¬ ºÖ ¤j ® 3/16 FengX/barkjor +PTGS50th301 ¤¤¤k ¡·¤Ñ¤U²Ä¤@¯Z--¤¤¤ 8/09 cocoduck/youki +CS85ming ¤¤¤s ¡·"©ú"¤ß¤p¶é 8/08 shan/lovehook/JWR +ck47th333 «Ø¤¤ ¡·³o¼Ë·|¤£·|¼oª©? 7/17 diezoo/Express +TFG97SHOT ¥_¤@ ¡·¦Ì¨º®á¡@¾¾¥Ì°_¤ 8/07 chili/atlantis +Taichung ªA°È ¡·³Ì³Ì²M·s¥i·R°·± 8/09 Jahon +southdoor «nªù ¡·«nªù¤»¥Òªºµ£¨¥µ 8/09 happyjoy +ck47th301 «Ø¤¤ ¡·ÁٳѽְڡH¡H 5/22 huskie/flutii +hsntu ªþ¤¤ ¡´¥x¤jªþ¤Í·| ¨Ó 11/29 koku/Crony +JH23th301 °ê¤¤ ¡·§AÁÙ¬¡µÛ¶Ü? 7/25 momi/mvpman +money ¾Ç³N ¡´Show me the 5/02 kagh +HSNU_807 ªþ¤¤ ¡·®Ã¨Õ¹s¬m¯Z 7/16 yijean/joj +ntubbsops µo¹q ¡´¥x¤j³s½u¯¸°ÈªO 3/23 Ptt +ntuACCT90 ·|p ¡´³o¬O¥Ã»·ªº¥x¤j· 7/19 blackman/aathena +geography90 ¦a²z ¡· 5/23 cog/uray +TFG97Juang ¥_¤@ ¡·§ÚÌ·|¤£·|ª½¨ì± 8/09 seabreeze/notorious/Ving +JHArt10th °ê¤¤ ¡·¶Â¦âªº©ñ®öx 8/14 sadness/noyes +ChanAn26-303ªø¦w ¡·¥s§Ú²Ä¤@¦W 8/07 HunterX +FashionClub ¶h½ì ¡´¶W«lÃz¤§--¥x¤j¦ 1/17 demure/Woodywang/wiki +TFG97KIND ¥_¤@ ¡·³o¸Ì¥i¬O¤¯¶¡¤Ñ° 1/17 Channy +AADIA ¥xÆW ¡·¿Nºuºuªº³Ì¨Î¨kº 8/13 CATHYSHU/dyw +Sunrise12 ¹ÎÅé ¡·´Â¶§¦P¾Ç·|¤Q¤G© 8/14 waiting/doggy +cksh75th09 ¦¨¥\ ¡·¤Í½Ë¾ú"¤E"¤@¼Ë¿ 8/08 chiahei/WeThree/berserk +Evangelion ¤é¥» ¡´¸Û¼xª©¥D:) 6/15 ¼x¨D¤¤ +NTUba87 ¤uºÞ ¡·¤uºÞ¤@¥X ½Ö»P 8/09 ukj/littlewin +ck49th109 «Ø¤¤ ¡·ª©¥Dn¤W¤s«ô®v¥ 3/24 edvi +CS86Honest ¤¤¤s ¡·³o¸Ì¬O¸Û¯Z¡I¸Û¯ 5/24 Nakai/vicke +YP86-307 ©µ¥ ¡·¨È¬w²Ä¤@°Õ! 8/08 DRAGONS/longman +jackstudio µ¼Ö ¡·ªN§J·nºuµ¼Ö¾Ç 8/13 gigimusic +CS85MadWiser¤¤¤s ¡··¬¨g´¼¼z¤H 12/06 NED +LiZin ¸É²ß ¡·¥ß¤H¸É²ß¯Z 6/10 success/adket/foster +HP_86_310 ©M¥ ¡·©M¥°ª¤¤²Ä¤@©¡ 11/26 beautyegg/oops/kyte +Terry ¥xÆW ¡·ªL§Ó¬¯¡uÀ¿Án¦Ó¹ 8/10 jane +Julia ¥xÆW ¡· ¤@¥Í³Ì·Rªº´^¨Î 8/07 esa +PTGS50th305 ¤¤¤k ¡·¦³¹Ú¦³ªB¤Í---¤¤ 8/07 gm +ck49th111 «Ø¤¤ ¡´¥´À»§Å±C¯S§ð¶¤ 3/15 ERWILSON/firebat +ck49th131 «Ø¤¤ ¡·§Ṳ́S²¦·~¤F... 12/26 lanzi/Cliche +Wallace »´ä ¡·¤p¤Ó¶§Áéº~¨}--¥ 8/07 karencc +KJ25MC ¥ú¤¯ ¡·¥ú¤¯«lÃz¬ü¤kª© 7/09 pm +ADS ¨ä¥L ¡´¼s§i¯S°Ï 7/09 chwang/sourit/elixirs +TFSHS57th310¤@¤¤ ¡´§Ṳ́@®a³£¬O¤H 7/09 difficult/lpp/juwu +B84305XXX ªÀ·| ¡·84¯ÅªÀ·|¤H 7/12 ridley +Jeff ¥xÆW ¡·¤Q¤G¤ëªì--±¡ºq¤ 7/24 MisaTanaca/gambol +EricMoo ¬P°¨ ¡·§Å±Ò½åªº·P°Ê 11/27 piercec +NTUIB-PHD °ê¥ø ¡·¥x¤j°ê¥ø©Ò³Õ¤h¯ 5/22 yi03 +cksh75th19 ¦¨¥\ ¡·¤µ¤Ñªº§A,¹L±o¦n 8/17 shiii/eegg +MINGDAO ©ú¹D ¡·ªï±µ·s¥@¬öªº¨ì¨ 3/10 apache/kaening +NTUMBA-87 °Ó¬ã ¡·¥ø·~®aªººÛ 8/13 jonah +ck49th324 «Ø¤¤ ¡´¤@©u®L©]ªº¤ß°Ê 4/03 jase/uuuuuu/brita +TFG96Chung ¥_¤@ ¡·²{¦bµ²±B«Ü¤£¦Eº 8/12 astroboy +Kinmen ÒO¤Í ¡·¥x¤jÒO¤Í·| 4/26 spurs +BANYAN ¥_ªù ¡·¥_ªù°ª¤¤46TH 30 7/09 lusa/wangstar +BADTWINS ¤¤¤Í ¡·¤j¼w°ê¤¤ 7/16 Chilong/ggn/xlight +TFG96WILL ¥_¤@ ¡·¼Ý°ê·±¡ 8/17 because/Galong +HSNU_924 ªþ¤¤ ¡´ºÆ¨g´c¶Õ¤O 7/16 Dukedream +Cyndi ¥xÆW ¡·¨S¦³"¾ÖµØ"¡A´N¥ 1/11 Melinda +test2 +CS86Smile ¤¤¤s ¡´¯º¶Æ¤¤¤s 12/20 HsinYu/sunspring +JI3thN3-3 ¥¿¸q ¡·¥¿¸q°ª¤¤´¶¤T¤T 7/13 screamer/stingypig +CS87KUNG ¤¤¤s ¡·¤½¤§·¶³ 8/12 hayashi/yjiou +NTUBA-837011¥øºÞ ¡·ª©½Þ¬O°¦¤jÃi½Þ 3/10 eemil +TW-explorer ¼v¶° ¡·¤p¤ß³QÅQ¤ýÀs«r³ 8/06 honu +NTUIMA ªZ³N ¡·¤º®a®±ªÀ ³¯¤ó¤Ó 8/16 shadowpen/fu6xjp6 +NthuPhi õ¾Ç ¡·®µ²ø©P¥H¾C¹C 8/07 cerberus +FreeNight ¥xÆW ¡·TROUBLE ±i¾_À® 5/24 gonna/holybell +GlobalECON «Ý¼o ¡·¬F¸g¤K¦Ê(°]¸g°Ý 12/12 ali8/martinboy +cvslog µo¹q ¡·cvs commit mess 4/16 +Momentum «Ý¼o ¡·°Ê¶q¥\³õ¤u§@«Ç 12/03 adnova/chestnut +chess ®T¼Ö ¡·¤]¹ï ³£¬O³s±N 2/01 miserable +ChthoniC ¥xÆW ¡´°{ÆF¼Ö¹Îª© 8/07 Iverigma +shisong304 ¦èªQ ¡·¦èªQ304 5/15 JawTing/JSmoltz +NCCU97_MAT ·|¬ã ¡·¨Ó§a.....¦P¾Ç·| 5/15 kemling/A1997 +ck49th331 «Ø¤¤ ¡·¨g¨F³¥±æ¡C 7/12 MDP/den +HCGH-306 ¦Ë¤k ¡·¦³¤K¨ö¡I¡I¡I 4/19 jennywen/molly +Foolshome ¹ÎÅé ¡·CCC~~~¤dÁH¦~ 1/06 truth/citizen/nathon +MARIAH ¬ü°ê ¡· ¡¹¡¹DON'T STOP 8/11 woowa +KHCHS-87-306·s²ø ¡·³£¶]¨ìþ¸Ì¥h¤F 6/10 +Delphi µ{³] ¡·Delphi¨g·Q¦± 2/13 cying +ciacia_Her ¥xÆW ¡·ciacia¥Î¤å¦r¬D³ 7/26 sherbet +KS86-323 ¶¯¤¤ ¡´§Ú̬O¥Ã»·ªºªüµ 7/05 fayemimi/hanawa +test2 +KS86-322 ¶¯¤¤ ¡·¤j®a¦^¨ÓÄé¤ô§a¡ 8/10 Vygotsky/SpermTiger +35WHOteam ¹ÎÅé ¡·ÂåÀø¥~¥æÀç¤T¤¤ 5/12 winonamars +test2 +ck49th306 «Ø¤¤ ¡·ernesto¡G 306ª 7/18 pongo/dearyou +WuLing40-301«Ý¼o ¡·¦³¹Ú¦³ªB¤Í 10/ 8/11 quert +NTUACCT88 ·|p ¡·¤Ñ ¹D ¹S ¶Ô 6/12 Abbado/yenjui +NTUDRC ¬ã¨s ¡·©Î³\©p¬O¹ïªº 8/10 Kymco/plockock/Jimmyplus +NTUWRC ³°¤W ¡·¥x¤jºL¨¤¬ã¨sªÀ 8/07 BigRed +TFSHS59th318¤@¤¤ ¡´¹L¤F¤@¤Ñ¤S¤@¤Ñ 8/07 prodigy/kinoo/frisk +86literarts ¤å¾Ç ¡·86®v¤j¤åÃÀÀç 8/07 stupidbear/bengthek +NTPU-SOC87 ªÀ·| ¡·«z«¨...·sª©¦¨¥ß 8/12 nettaigyo +NTU94FLLD ¥~¤å ¡·B83102's Wonder 3/27 poppet +ToriAmos ¬ü°ê ¡·SLG¼ö½æ¤¤ 8/14 CornflakeBoy +Bjork ¬ü°ê ¡·¤å³¹³£¤£¨£¤F § 8/09 lunaticlace/sjon +SCU-BM-87C Æ[¹î ¡· ¤Í½Ë¾ú¤[¤@¼Ë¿@ 4/17 joeyoung/linging/YADY +CC-304 ¤¤¥¿ ¡·¤¤¥¿¶W´Î 304 8/14 betty0804/daystar +Robin-Willia«Ý¼o ¡·¥Ã»·¤£¦ÑªºÃ¹»«« 8/09 ¼x¨D¤¤ +NTUEEice ¹ÎÅé ¡·á -- µ² 8/10 hiei81/shouhou +tu-tuoz ¹ÎÅé ¡·¦R¼Ñ°ê¥Á¤p¾Ç 8/10 galilei/seethesky +WesleyS3H-32½Ã²z ¡·³Ì«á¤@Ó´»°²°Õ¡ 8/15 esm +Romi ¥xÆW ¡·§Qºö¡ã¡ãÅé¶K 8/16 flyawayhome/holina +EEacademic ¹q¾÷ ¡´n´Á¤¤¦ÒÅo¡I¡I 5/11 ccchen +ck-newboard ¥Ó½Ð ¡·«Ø¤¤²Õ±M¥Î³s¸pª 2/09 Pets +NTUspecial µLê ¡·¡¸¥xÆW¤j¾ÇµL»Ùà 4/28 t6768 +chienchen §@®a ¡·¤å¦rºëÆF¡X¡XÂ²Ø 8/09 curioussoul/ECOSEED +test2 +test2 +test2 +NTUmed-SC Âå¾Ç ¡·¡¸¤È¶¡µ¼Ö·|µ¥§ 8/13 Evan/boo24 +Visual_Basicµ{³] ¡·«z«z..§A¤£¯à¦Û¤ 8/14 glans +test2 +test2 +AngelicaLee ¬P°¨ ¡·¶W¥i·R§õ¤ß¼ä *^ 8/11 CaptainL +Jackie_Lui »´ä ¡´«L°©¤¯¤ß--§f¹|½ 8/14 pipo/YCJ +HSNU_888 ªþ¤¤ ¡´888¬¾¨ß²Ä¤G¸] 8/10 Viggeran/cidi +ClassicMusicµ¼Ö ¡´§ÚÌ£x°ê¼Ö 8/13 kuger/mml +CM34th03 ´º¬ü ¡·:) 8/13 Snorkel +CS88Jang ¤¤¤s ¡·§Ú̳£¬O¥¿ÂI¬ü¤ 8/08 YANIYANI/cfchien +TFG99JUANG ¥_¤@ ¡·µM«á¤S¬O¬î¤Ñ°Õ. 8/11 yumeko +SrcDiscuss ¯¸ªø ¡·PTT ¥¼¨Óµ{¦¡µo® 5/13 CharlieL/DavidYu +WL-AFFAIRS ¨Æ°È ¡·½Ð¦UªO¥Dª`·N¸s² 6/09 PaiBingTran +SMGJS-80-302¾å©ú ¡·¥Ã»·ªºªì¤T¤A 8/09 chifang +ck51st332 «Ø¤¤ ¡·±¥ Â÷§Ú̦ӥhªº 8/13 JeffreyS/jimmycat/Kampuchea/JIROO +HORT-90 ¶éÃÀ ¡´²¦·~¤F... 8/16 sorng +NCHUPPSB ¨tÂS ¡·«s«s«s «áÄ~µL¤H 4/14 LCUTE/AMDKX +TAE ®õ°ê ¡·¦A¨£,¥[¦{®üÅy 4/14 TulipChiu +LePoete ¥xÆW ¡·¥Ð¶é¸Ö¤H³¯©ú³¹( 4/14 doomcat +NTUPOD ¬ã¨s ¡· 8/16 Galong +ck53rd211 «Ø¤¤ ¡·´«Ó¦W¦r§a.. 8/07 shanvic/BBD +NCHU-SES ¤gÀô ¡·¤j®a¨Óªï·s³á~~ 4/18 yenjan +Tin-Tin ¥xÆW ¡´´@´@·Rªº³Ó§Q 8/09 shinoo +PTGS48th318 ¤¤¤k ¡·ºñ¦âÁ½¸ºÛ 8/15 yungfang +KF302 ¥ú´_ ¡·¶ë¨®¤¤ 8/15 ingela/cadillac +HuangLei ¤j³° ¡·¶À½U¤å¾Çµ¼Ö¤jº 8/09 ssr +NCCU99_EDU «Ý¼o ¡·~±Ð¨|Ä_Ä_ªº_§§ 8/14 ¼x¨D¤¤ +NCHU_zoo °Êª« ¡´¤£¨}¤û¤H¤ñ¸û¦h 4/24 sengir/GENETICS/velella +Bull ¾´Î ¡´¤G¤Q¤@¥@¬ö³Ì«i² 4/24 Nicky41/georgey +KS88-309 ¶¯¤¤ ¡´°¸§i¶D§A...§Ú§@ 4/24 daviy +cksh77th20 ¦¨¥\ ¡·§A§Ú³£¬O·Ï¤õ¤¤ª 8/06 bergee +TFG99Dance ¥_¤@ ¡·µL¬×Jazz«ax 8/07 Tinabear/hee +TFG99Love ¥_¤@ ¡· ¨ä ¹ê 8/07 kelala/SpiceB +Nedio ´CÅé ¡·§Ö¤Whttp://nedi 8/08 SpiceB/Sophia33 +TYHS88-306 ¥ªÀç ¡´¤T¤Ñ¤T©]¨ì¤T§ó¥ 8/09 niniway/Jey +BCT-88 ¬ì§Þ ¡·¤@¸s¦b¥Íª«§Þ³N¤ 8/15 physik/avkao +CARNEGIE0917¹ÎÅé ¡·***ªï±µ°{«Gªº21 8/07 blackmail/mistletoe/tsg +NCCU_PT ªÀ¹Î ¡·¨S¦³¬¡°Êªº«Ì¤Í· 8/11 mib345/randying +NCHU-SKATING·È¦B ¡·¨Ó¥h...¨Ó¥h...¤ 3/18 kaoasaki/littlehome +Tun-Hua-Elem´°¤Æ ¡·TunHua_²Ä32©¡_6 8/07 pup +CS88jing ¤¤¤s ¡·§Ö²¦·~¤FC ·Q 8/08 yianne +LeneMarlin ¬ü°ê ¡·µ¼ÖºëÆF--µY®¦º 8/08 janetwang +KS88-304 ¶¯¤¤ ¡·¤j®a¨ÓÄé¤ô³á~ 8/12 ahwa/oldya/BabyHam +Summer ¥xÆW ¡·§â¼v¤l¯d¤U¡A¦b® 8/08 powerpeople/FINNCHE +Slayers ¤é¥» ¡·¨q³rÅ]¾É¤h ²ú® 8/07 Zelgandes/marcal/Naga +NTU-SwimCamp¤ô¤W ¡·¥x¤j´åªaÀç 6/22 sunnyl +red-sun ªÀ¹Î ¡·¸¨¥Û¨ÓÅo 8/09 renaissance +1995-JH-325 ª÷µØ ¡·ª÷µØ°ê¤¤¤T¦~¤G¤ 8/13 ThisWayIn/Raistlin/ifq +X-game ¹B°Ê ¡··¥¹B°Ê 8/08 rbaggio +88leadercamp¹ÎÅé ¡´ ²×©ó¶}ª©ªº88ªÀ 8/12 elbert/aaati +Curse ¥xÆW ¡·¶A©G¼Ö¹Î(¤Q¤K¤~ 8/07 anticrist +Joi ¬P°¨ ¡·²E²b¨Îµ 8/08 leon19/crazykiller +SHENA-RINGO ¤é¥» ¡·´Õ¦WªLìþ ³Ó¶Dªº 8/08 MayMV +CCJH-FS-27th¤¤¥¿ ¡·£¯ §N²M²M..... 8/12 Ariyari/YehMay +PH-Service ¤½½Ã ¡·¥ÃÄò¸gÀ窺¤½½Ãª 8/07 piayyc/yuskay +1995-JH-309 «Ý¼o ¡·ª÷µØ309°ê¤¤¦P¾Ç 2/11 ¼x¨D¤¤ +Peter ¥xÆW ¡·¨C¦¸·Q¨ì"¦ó¼íªF 3/05 Haas +IPIS µá°ê ¡·Á½¸-§Ñ¤F§Ú¬O½Ö 5/30 +cksh76th22 ¦¨¥\ ¡·¦a²y«Ü¦MÀIªº!©p 8/15 lunasoul +Stella ¬P°¨ ¡·µ¼Ö²¢¤ß-¶À´ð©É 7/12 gutai309/crazykiller +Law-Skate ªk«ß ¡·ªkbª½±Æ½üªÀ ·È 6/12 Rainsalt/gwenlin +cksh78th08 ¦¨¥\ ¡·¤»¦rÀY 308 3/17 smilefacer +ntucomga ºÞ·| ¡·ºÞ°|¬ã¨s¥Í¾Ç¥Í· 5/08 handsome diff --git a/util/smtest.result2 b/util/smtest.result2 new file mode 100644 index 00000000..b84133c2 --- /dev/null +++ b/util/smtest.result2 @@ -0,0 +1,3 @@ +§K¾ª©¥D +¬ÝªO¦WºÙ ªO¥D ´X¤Ñ¨S¨Ó°Õ +---------------------------------------------------------------------- diff --git a/util/smtest.temp b/util/smtest.temp new file mode 100644 index 00000000..7daa12ce --- /dev/null +++ b/util/smtest.temp @@ -0,0 +1,231 @@ +#include <stdio.h> +#include <sys/types.h> +#include <unistd.h> +#include <string.h> +#include <stdlib.h> +#include <time.h> +#include <ctype.h> +#include "config.h" +#include "pttstruct.h" +#include "util.h" +#include "perm.h" +#include "common.h" +#include "proto.h" + +#define OUTFILE BBSHOME "/pttbbs/util/smtest.result1" +#define FIREFILE BBSHOME "/pttbbs/util/smtest.result2" + +extern boardheader_t *bcache; +extern int numboards; + +boardheader_t allbrd[MAX_BOARD]; +struct userec_t xuser; + +int getuser(char *userid) { + int uid; + if((uid = searchuser(userid))) + passwd_query(uid, &xuser); + return uid; +} + +int LINK(char* src, char* dst){ + char cmd[200]; + + if( link(src, dst) == 0){ + return 0; + } + + sprintf(cmd, "/bin/cp -R %s %s", src, dst); + return system(cmd); +} + +int outofdate(char *hdrdate, char latestdate[]) +{ + int k,rr; + char *dd; + + dd = strtok(hdrdate,"/"); + + if(dd){ + k = 0; + do + { + if (*dd == '[' ){dd[strlen(dd)-1]='\0'; dd++;} + rr = atoi(dd); + printf("%d/", rr); + } while((dd = strtok(NULL,"/")) != NULL); + } + + printf("\n"); + + if(1) + return 1; + else + return 0; +} + +int main() +{ + int bmid, i, j, k, rd,rr; + char *p, *bmsname[3], fname[256], *dd; + fileheader_t hdr; + FILE *inf; + + /* set date */ + char thedate[5]; + time_t t = time(NULL); + struct tm *tm = localtime(&t); + + sprintf(thedate, "%2d/%02d", tm->tm_mon + 1, tm->tm_mday); + + resolve_boards(); + if(passwd_mmap()) + exit(1); + memcpy(allbrd,bcache,numboards*sizeof(boardheader_t)); + /* write out the target file */ + inf = fopen(OUTFILE, "w+"); + if(inf == NULL){ + printf("open file error : %s\n", OUTFILE); + exit(1); + } + + /*the ouput table title*/ + fprintf(inf,"^¤åª©¦W Ãþ§O ¤¤¤åª©¦W ª©¥D¦W³æ" + " ¤é´Á ³Æµù \n"); + + j = 0 ; + for (i = 0; i < 30; i++) { + rd = 0; + if(allbrd[i].brdname[0] == '\0') continue; + if((allbrd[i].brdattr & BRD_NOZAP) == 1) continue; + + sprintf(fname, BBSHOME "/boards/%s/.DIR",allbrd[i].brdname); + + /* get date to choose junk board */ + + rd = get_num_records(fname, sizeof(fileheader_t)); + get_record(fname, &hdr, sizeof (hdr), rd - 30); + + + if(outofdate(hdr.date,thedate)) printf("yest\n"); + +/* + dd = strtok(hdr.date,"/"); + + if(dd){ + k = 0; + do + { + if (*dd == '[' ){dd[strlen(dd)-1]='\0'; dd++;} + rr = atoi(dd); + printf("%d/", rr); + + } while((dd = strtok(NULL,"/")) != NULL); + } + printf("\n"); +*/ + /* print to file */ + printf("%-*.*s%-*.*s%-*.*s%-*.*s", IDLEN, IDLEN, allbrd[i].brdname, + BTLEN-24, BTLEN-26, allbrd[i].title, IDLEN - 5, IDLEN-5,hdr.date, + IDLEN * 3, IDLEN * 3, allbrd[i].BM); + + /* post to board */ + + + + /* user extract to mail */ + + p=strtok(allbrd[i].BM,"/ "); + if(p){ + k = 0; + do + { + if (*p == '[' ){p[strlen(p)-1]='\0'; p++;} + bmid=getuser(p); + bmsname[k] = p; + if(isalpha(allbrd[i].BM[0])&& !(xuser.userlevel &PERM_SYSOP)) + { + // printf("%s", bmsname[k]); + } + k++; + } while((p=strtok(NULL,"/ "))!=NULL); + } + + printf("\n"); + +} + + +/* + + + + if(flag == 1){ + bmbuf[0] = '\0'; + for(k = 0 , n = 0; k < index; k++){ + if(!bms[k].flag){ + if( n++ != 0) strcat(bmbuf, "/"); + strcat(bmbuf, bms[k].bmname); + } + } + strcpy(bcache[i].BM, bmbuf); + } + } + qsort(lostbms, j, sizeof(lostbm), bmlostdays_cmp); + + //write to the etc/toplazyBM + for ( i=0; i<j; i++) + { + if( lostbms[i].lostdays > 60){ + fprintf(firef, "%-*.*s%-*.*s%-*.*s%3d¤Ñ¨S¤W¯¸\n", IDLEN, IDLEN, lostbms[i].title, + BTLEN-10, BTLEN-10, lostbms[i].ctitle, IDLEN,IDLEN, + lostbms[i].bmname,lostbms[i].lostdays); + }else{ + fprintf(inf, "%-*.*s%-*.*s%-*.*s%3d¤Ñ¨S¤W¯¸\n", IDLEN, IDLEN, lostbms[i].title, + BTLEN-10, BTLEN-10, lostbms[i].ctitle, IDLEN,IDLEN, + lostbms[i].bmname,lostbms[i].lostdays); + } + } + fclose(inf); + fclose(firef); + + //printf("Total %d boards.\n", count); + + //mail to the users + for( i=0; i<j; i++) + { + fileheader_t mymail; + char genbuf[200]; + int lostdays; + + lostdays = lostbms[i].lostdays; + + if( (lostdays != 30) && (lostdays != 45) && (lostdays <= 60)) + continue; + + sprintf(genbuf, BBSHOME "/home/%c/%s", lostbms[i].bmname[0], lostbms[i].bmname); + stampfile(genbuf, &mymail); + + strcpy(mymail.owner, "[PTTĵ¹î§½]"); + + if(lostdays <= 60){ + sprintf(mymail.title, + "\033[32m [ª©¥D§K¾ĵ§i³qª¾] \033[m %s BM %s", lostbms[i].title, lostbms[i].bmname); + }else{ + sprintf(mymail.title, + "\033[32m [ª©¥D§K¾³qª¾] \033[m %s BM %s", lostbms[i].title, lostbms[i].bmname); + } + mymail.savemode = 0 ; + unlink(genbuf); + if(lostdays <= 60){ + LINK(OUTFILE, genbuf); + }else{ + LINK(FIREFILE, genbuf); + } + + sprintf(genbuf, BBSHOME "/home/%c/%s/.DIR", lostbms[i].bmname[0], lostbms[i].bmname); + append_record(genbuf, &mymail, sizeof(mymail)); + } +*/ + return 0; +} diff --git a/util/stock.perl b/util/stock.perl new file mode 100644 index 00000000..568c2d86 --- /dev/null +++ b/util/stock.perl @@ -0,0 +1,31 @@ +#!/usr/bin/perl +# $Id: stock.perl,v 1.1 2002/03/07 15:13:46 in2 Exp $ +# +# ¤£¯à¶]ªº¸Ü¡A¬Ý¬Ý bbspost ªº¸ô®|¬O§_¥¿½T¡C +# ¦pªGµo¥Xªº post ¨S¦³®ð¶H³ø§i¦Ó¬O»¡ URL §ä¤£¨ì¡A«h½T©w¤@¤U¯à¤£¯à¬Ý¨ì +# ¤¤¥¡®ð¶H§½ªº WWW ¤Î URL ¬O§_¥¿½T¡C +# ²z½×¤W¾A¥Î©Ò¦³ Eagle BBS ¨t¦C¡C +# -- Beagle Apr 13 1997 +open(BBSPOST, "| bin/webgrep >etc/stock.tmp"); +# ¤é´Á +open(DATE, "date +'%a %b %d %T %Y' |"); +$date = <DATE>; +chop $date; +close DATE; + +# Header +# ¤º®e +#open(WEATHER, "/usr/local/bin/lynx -dump http://www.dashin.com.tw/bulletin_board/today_stock_price.htm |"); while (<WEATHER>) { +open(WEATHER, "/usr/bin/lynx -dump http://quotecenter.jpc.com.tw/today_stock_price.htm |"); while(<WEATHER>) { + print BBSPOST if ($_ ne "\n"); +} +close WEATHER; + +# ñ¦WÀÉ +print BBSPOST "\n--\n"; +print BBSPOST "§Ú¬Obeagle©Ò¦³¥i·Rªº¤p»æ°®...¸ó®ü¬°PttªA°È\n"; +print BBSPOST "--\n"; +print BBSPOST "¡¸ [Origin: ¡·ªGÂæ¤p¯¸¡·] [From: [ÂŲùÃP»æ«Î] ] "; + +close BBSPOST; + diff --git a/util/stock.sh b/util/stock.sh new file mode 100644 index 00000000..907ddb73 --- /dev/null +++ b/util/stock.sh @@ -0,0 +1,5 @@ +#!/bin/sh +# $Id: stock.sh,v 1.1 2002/03/07 15:13:46 in2 Exp $ +# +bin/stock.perl +bin/post Record ¤µ¤éªÑ²¼¦¬½L»ù [ªÑ¥«¤p©j] etc/stock.tmp diff --git a/util/tarqueue.pl b/util/tarqueue.pl new file mode 100644 index 00000000..20bda9f1 --- /dev/null +++ b/util/tarqueue.pl @@ -0,0 +1,75 @@ +#!/usr/bin/perl +use lib '/home/bbs/bin/'; +use LocalVars; +use strict; +use Mail::Sender; +use POSIX; + +no strict 'subs'; +setpriority(PRIO_PROCESS, $$, 20); +use strict subs; +chdir $BBSHOME; +open LOG, ">> log/tarqueue.log"; + +foreach my $board ( <$JOBSPOOL/tarqueue.*> ){ + $board =~ s/.*tarqueue\.//; + ProcessBoard($board); + unlink "$JOBSPOOL/tarqueue.$board"; +} +close DIR; +close LOG; + +sub ProcessBoard +{ + my($board)= @_; + my($cmd, $owner, $email, $bakboard, $bakman, $now); + + $now = substr(POSIX::ctime(time()), 0, -1); + open FH, "< $JOBSPOOL/tarqueue.$board"; + chomp($owner = <FH>); + chomp($email = <FH>); + chomp(($bakboard, $bakman) = split(/,/, <FH>)); + close FH; + + print LOG sprintf("%-28s %-12s %-12s %d %d %s\n", + $now, $owner, $board, $bakboard, $bakman, $email); + + MakeMail({tartarget => "$TMP/$board.tgz", + tarsource => "boards/$board/* boards/$board/.DIR", + mailto => "$boardªºª©¥D$owner <$email>", + subject => "$boardªº¬Ýª©³Æ¥÷", + body => + "\n\n\t $owner ±z¦n¡A¦¬¨ì³o«Ê«H¡Aªí¥Ü±z¤w¸g¦¬¨ì¬ÝªO³Æ¥÷¡C\n\n". + "\tÁÂÁ±zªº@¤ßµ¥«Ý¡A¥H¤Î¨Ï¥Î $hostnameªº¬ÝªO³Æ¥÷¨t²Î¡A\n\n". + "\t¦p¦³¥ô¦óºÃ°Ý¡AÅwªï±H«Hµ¹¯¸ªø¡A§ÚÌ·|«Ü¼Ö©óµ¹¤©¨ó§U¡C\n\n\n". + "\t³Ì«á¡A¯¬ $owner ¥¦w§Ö¼Ö¡I ^_^\n\n\n". + "\t $hostname¯¸ªø¸s. \n\t$now" + }) if( $bakboard ); + + MakeMail({tartarget => "$TMP/man.$board.tgz", + tarsource => "man/boards/$board/* man/boards/$board/.DIR", + mailto => "$boardªºª©¥D$owner <$email>", + subject => "$boardªººëµØ°Ï³Æ¥÷", + body => + "\n\n\t $owner ±z¦n¡A¦¬¨ì³o«Ê«H¡Aªí¥Ü±z¤w¸g¦¬¨ìºëµØ°Ï³Æ¥÷¡C\n\n". + "\tÁÂÁ±zªº@¤ßµ¥«Ý¡A¥H¤Î¨Ï¥Î $hostnameªº¬ÝªO³Æ¥÷¨t²Î¡A\n\n". + "\t¦p¦³¥ô¦óºÃ°Ý¡AÅwªï±H«Hµ¹¯¸ªø¡A§ÚÌ·|«Ü¼Ö©óµ¹¤©¨ó§U¡C\n\n\n". + "\t³Ì«á¡A¯¬ $owner ¥¦w§Ö¼Ö¡I ^_^\n\n\n". + "\t $hostname¯¸ªø¸s. \n\t$now" + }) if( $bakman ); + +} + +sub MakeMail +{ + my($arg) = @_; + my $sender; + `$TAR zcf $arg->{tartarget} $arg->{tarsource}`; + $sender = new Mail::Sender{smtp => $SMTPSERVER, + from => 'pttadmin <in2@ptt2.csie.ntu.edu.tw>'}; + $sender->MailFile({to => $arg->{mailto}, + subject => $arg->{subject}, + msg => $arg->{body}, + file => $arg->{tartarget}}); + unlink $arg->{tartarget}; +} diff --git a/util/testkenben.txt b/util/testkenben.txt new file mode 100644 index 00000000..df3893d3 --- /dev/null +++ b/util/testkenben.txt @@ -0,0 +1,11 @@ +HCGH-306 ¦Ë¤k ¡·¦³¤K¨ö¡I¡I¡I 7/24 jennywen/molly +Foolshome ¹ÎÅé ¡·CCC~~~¤dÁH¦~ 1/14 truth/citizen/nathon +KHCHS-87-306·s²ø ¡·³£¶]¨ìþ¸Ì¥h¤F 6/12 +TGHS8714 «n¤k ¡·²z©Ê¤Ñ®ð¡F·P©Ê¥ 8/07 grassflying/EPOCH +PttDoc ¼Tù ¡·Ptt Document Pr 8/07 +Delphi µ{³] ¡·Delphi¨g·Q¦± 3/09 cying +ciacia_Her ¥xÆW ¡·ciacia¥Î¤å¦r¬D³ 8/16 sherbet +CS87Love ¤¤¤s ¡··R©O! 8/08 sylna/fancydream +Wanfang ¥xÆW ¡·´Nȱo¤F·R¸UªÚ 8/07 zkkk +KS87-308 ¶¯¤¤ ¡´¶¯¤¤¤K±¾¯Z¡m¤@¤ 8/07 SBT/shouhou + diff --git a/util/toplazyBBM.c b/util/toplazyBBM.c new file mode 100644 index 00000000..08c07448 --- /dev/null +++ b/util/toplazyBBM.c @@ -0,0 +1,203 @@ +#include <stdio.h> +#include <sys/types.h> +#include <unistd.h> +#include <string.h> +#include <stdlib.h> +#include <time.h> +#include <ctype.h> +#include "config.h" +#include "pttstruct.h" +#include "util.h" +#include "perm.h" +#include "common.h" + +#define OUTFILE BBSHOME "/etc/toplazyBBM" +#define FIREFILE BBSHOME "/etc/topfireBBM" + +extern boardheader_t *bcache; +extern int numboards; + +boardheader_t allbrd[MAX_BOARD]; +extern userec_t xuser; +typedef struct lostbm { + char *bmname; + char *title; + char *ctitle; + int lostdays; +} lostbm; +lostbm lostbms[MAX_BOARD]; + +typedef struct BMarray{ + char *bmname; + int flag; +} BMArray; +BMArray bms[3]; + +int bmlostdays_cmp(const void *va, const void *vb) +{ + lostbm *a=(lostbm *)va, *b=(lostbm *)vb; + if (a->lostdays > b->lostdays) return -1; + else if (a->lostdays == b->lostdays) return 0; + else return 1; +} + + +int LINK(char* src, char* dst){ + char cmd[200]; + if(symlink(src,dst) == -1) + { + sprintf(cmd, "/bin/cp -R %s %s", src, dst); + return system(cmd); + } + return 0; +} + +int main(int argc, char *argv[]) +{ + int bmid, i, j=0; + FILE *inf, *firef; + + resolve_boards(); + + if(passwd_mmap()) + exit(1); + + memcpy(allbrd,bcache,numboards*sizeof(boardheader_t)); + + /* write out the target file */ + printf("Starting Checking\n"); + inf = fopen(OUTFILE, "w+"); + if(inf == NULL){ + printf("open file error : %s\n", OUTFILE); + exit(1); + } + firef = fopen(FIREFILE, "w+"); + if(firef == NULL){ + printf("open file error : %s\n", FIREFILE); + exit(1); + } + + fprintf(inf, "ĵ§i: ª©¥DY©ó¨âӤ를¤W¯¸,±N¤©©ó§K¾\n"); + fprintf(inf, + "¬ÝªO¦WºÙ " + " ªO¥D ´X¤Ñ¨S¨Ó°Õ\n" + "---------------------------------------------------" + "-------------------\n"); + + fprintf(firef, "§K¾ª©¥D\n"); + fprintf(firef, + "¬ÝªO¦WºÙ " + " ªO¥D ´X¤Ñ¨S¨Ó°Õ\n" + "---------------------------------------------------" + "-------------------\n"); + + + j = 0 ; + for (i = 0; i < numboards; i++) { + char *p, bmbuf[IDLEN * 3 + 3]; + int index = 0, flag = 0, k, n; + p=strtok(allbrd[i].BM,"/ "); + if(p) + do + { + if(allbrd[i].brdname[0] == '\0' || (allbrd[i].brdattr & BRD_GROUPBOARD) ==0 ) continue; + if (*p == '[' ){p[strlen(p)-1]='\0'; p++;} + bmid=getuser(p); + bms[index].bmname = p; + bms[index].flag = 0; + if (((((int)time(NULL)-(int)xuser.lastlogin)/(60*60*24))>=7) + //&& isalpha(allbrd[i].brdname[0]) + //&& isalpha(allbrd[i].BM[0]) + && !(xuser.userlevel & PERM_SYSOP)) + { + lostbms[j].bmname = p; + lostbms[j].title = allbrd[i].brdname; + lostbms[j].ctitle = allbrd[i].title; + lostbms[j].lostdays = + ((int)time(NULL)-(int)xuser.lastlogin)/(60*60*24); + + printf("%s\n", lostbms[j].title); + //¶W¹L¤»¤Q¤Ñ §K¾ + if(lostbms[j].lostdays > 30){ + xuser.userlevel &= ~PERM_BM; + bms[index].flag = 1; + flag = 1; + } + j++; + } + index++; + } while((p=strtok(NULL,"/ "))!=NULL); + + //±qª©¥D¦W³æ®³±¼¦W¦r + + if(flag == 1){ + bmbuf[0] = '\0'; + for(k = 0 , n = 0; k < index; k++){ + if(!bms[k].flag){ + if( n++ != 0) strcat(bmbuf, "/"); + strcat(bmbuf, bms[k].bmname); + } + } + strcpy(allbrd[i].BM, bmbuf); + } + + } + qsort(lostbms, j, sizeof(lostbm), bmlostdays_cmp); + + printf("Starting to mail\n"); + //write to the etc/toplazyBBM + for ( i=0; i<j; i++) + { + if( lostbms[i].lostdays > 30){ + fprintf(firef, "%-*.*s%-*.*s%-*.*s%3d¤Ñ¨S¤W¯¸\n", IDLEN, IDLEN, lostbms[i].title, + BTLEN-10, BTLEN-10, lostbms[i].ctitle, IDLEN,IDLEN, + lostbms[i].bmname,lostbms[i].lostdays); + }else{ + fprintf(inf, "%-*.*s%-*.*s%-*.*s%3d¤Ñ¨S¤W¯¸\n", IDLEN, IDLEN, lostbms[i].title, + BTLEN-10, BTLEN-10, lostbms[i].ctitle, IDLEN,IDLEN, + lostbms[i].bmname,lostbms[i].lostdays); + } + } + fclose(inf); + fclose(firef); + + printf("Total %d boards.\n", j); + + //mail to the users + for( i=0; i<j; i++) + { + fileheader_t mymail; + char genbuf[200]; + int lostdays; + + lostdays = lostbms[i].lostdays; + + if( (lostdays != 14) || (lostdays != 21) ) // 14 21 ¤Ñ¤£µo«H + continue; + + sprintf(genbuf, BBSHOME "/home/%c/%s", lostbms[i].bmname[0], lostbms[i].bmname); + stampfile(genbuf, &mymail); + + strcpy(mymail.owner, "[PTTĵ¹î§½]"); + + if(lostdays <= 30){ + sprintf(mymail.title, + "\033[32m [¤p²Õªø§K¾ĵ§i³qª¾] \033[m %s BM %s", lostbms[i].title, lostbms[i].bmname); + }else{ + sprintf(mymail.title, + "\033[32m [¤p²Õªø§K¾³qª¾] \033[m %s BM %s", lostbms[i].title, lostbms[i].bmname); + } + mymail.savemode = 0 ; + unlink(genbuf); + if(lostdays <= 30){ + LINK(OUTFILE, genbuf); + }else{ + LINK(FIREFILE, genbuf); + } + + sprintf(genbuf, BBSHOME "/home/%c/%s/.DIR", lostbms[i].bmname[0], lostbms[i].bmname); + append_record(genbuf, &mymail, sizeof(mymail)); + } + + return 0; +} diff --git a/util/toplazyBBM.sh b/util/toplazyBBM.sh new file mode 100644 index 00000000..d1d94229 --- /dev/null +++ b/util/toplazyBBM.sh @@ -0,0 +1,3 @@ +bin/toplazyBBM +bin/post Record Ãi´k¤p²Õªø±Æ¦æº] [Pttĵ¹î§½] etc/toplazyBBM +bin/post ViolateLaw ¤µ¤é§K¾¤p²Õªø [Pttªk°|] etc/firelazyBBM diff --git a/util/toplazyBM.c b/util/toplazyBM.c new file mode 100644 index 00000000..ec9319c2 --- /dev/null +++ b/util/toplazyBM.c @@ -0,0 +1,211 @@ +#include <stdio.h> +#include <sys/types.h> +#include <unistd.h> +#include <string.h> +#include <stdlib.h> +#include <time.h> +#include <ctype.h> +#include "config.h" +#include "pttstruct.h" +#include "util.h" +#include "perm.h" +#include "common.h" +#include "proto.h" +#include "modes.h" + + +#define OUTFILE BBSHOME "/etc/toplazyBM" +#define FIREFILE BBSHOME "/etc/firelazyBM" + +extern boardheader_t *bcache; +extern int numboards; + +boardheader_t allbrd[MAX_BOARD]; +extern userec_t xuser; +typedef struct lostbm { + char *bmname; + char *title; + char *ctitle; + int lostdays; +} lostbm; +lostbm lostbms[MAX_BOARD]; + +typedef struct BMarray{ + char *bmname; + int flag; +} BMArray; +BMArray bms[3]; + + +int bmlostdays_cmp(const void *va, const void *vb) +{ + lostbm *a=(lostbm *)va, *b=(lostbm *)vb; + if (a->lostdays > b->lostdays) return -1; + else if (a->lostdays == b->lostdays) return 0; + else return 1; +} + +int LINK(char* src, char* dst){ + char cmd[200]; + if(symlink(src,dst) == -1) + { + sprintf(cmd, "/bin/cp -R %s %s", src, dst); + return system(cmd); + } + return 0; +} + +int main(int argc, char *argv[]) +{ + int bmid, i, j=0; + FILE *inf, *firef; + + resolve_boards(); + + if(passwd_mmap()) + exit(1); + + memcpy(allbrd,bcache,numboards*sizeof(boardheader_t)); + + /* write out the target file */ + inf = fopen(OUTFILE, "w+"); + if(inf == NULL){ + printf("open file error : %s\n", OUTFILE); + exit(1); + } + + firef = fopen(FIREFILE, "w+"); + if(firef == NULL){ + printf("open file error : %s\n", FIREFILE); + exit(1); + } + + fprintf(inf, "ĵ§i: ª©¥DY©ó¨âӤ를¤W¯¸,±N¤©©ó§K¾\n"); + fprintf(inf, + "¬ÝªO¦WºÙ " + " ªO¥D ´X¤Ñ¨S¨Ó°Õ\n" + "---------------------------------------------------" + "-------------------\n"); + + fprintf(firef, "§K¾ª©¥D\n"); + fprintf(firef, + "¬ÝªO¦WºÙ " + " ªO¥D ´X¤Ñ¨S¨Ó°Õ\n" + "---------------------------------------------------" + "-------------------\n"); + + + j = 0 ; + for (i = 0; i < numboards; i++) { + char *p, bmbuf[IDLEN * 3 + 3]; + int index = 0, flag = 0, k, n; + p=strtok(allbrd[i].BM,"/ "); + if(p) + do + { + if(allbrd[i].brdname[0] == '\0') continue; + if (*p == '[' ){p[strlen(p)-1]='\0'; p++;} + bmid=getuser(p); + bms[index].bmname = p; + bms[index].flag = 0; + if (((((int)time(NULL)-(int)xuser.lastlogin)/(60*60*24))>=31) + && isalpha(allbrd[i].brdname[0]) + && isalpha(allbrd[i].BM[0]) + && !(xuser.userlevel & PERM_SYSOP)) + { + lostbms[j].bmname = p; + lostbms[j].title = allbrd[i].brdname; + lostbms[j].ctitle = allbrd[i].title; + lostbms[j].lostdays = + ((int)time(NULL)-(int)xuser.lastlogin)/(60*60*24); + + + //¶W¹L¤»¤Q¤Ñ §K¾ + if(lostbms[j].lostdays > 60){ + xuser.userlevel &= ~PERM_BM; + bms[index].flag = 1; + flag = 1; + passwd_update(bmid, &xuser); + } + j++; + } + index++; + } while((p=strtok(NULL,"/ "))!=NULL); + + if(flag == 1){ + boardheader_t *fhp = 0; + printf("%s %s\n", lostbms[j-1].title, lostbms[j-1].bmname); + bmbuf[0] = '\0'; + for(k = 0 , n = 0; k < index; k++){ + if(!bms[k].flag){ + if( n++ != 0) strcat(bmbuf, "/"); + strcat(bmbuf, bms[k].bmname); + } + } + + strcpy(allbrd[i].BM, bmbuf); + if( substitute_record(FN_BOARD, &allbrd[i], sizeof(boardheader_t), i) == -1){ + printf("Update Board Faile : %s\n", allbrd[i].brdname); + } + reset_board(i); + } + } + + qsort(lostbms, j, sizeof(lostbm), bmlostdays_cmp); + + //write to the etc/toplazyBM + for ( i=0; i<j; i++) + { + if( lostbms[i].lostdays > 60){ + fprintf(firef, "%-*.*s%-*.*s%-*.*s%3d¤Ñ¨S¤W¯¸\n", IDLEN, IDLEN, lostbms[i].title, + BTLEN-10, BTLEN-10, lostbms[i].ctitle, IDLEN,IDLEN, + lostbms[i].bmname,lostbms[i].lostdays); + }else{ + fprintf(inf, "%-*.*s%-*.*s%-*.*s%3d¤Ñ¨S¤W¯¸\n", IDLEN, IDLEN, lostbms[i].title, + BTLEN-10, BTLEN-10, lostbms[i].ctitle, IDLEN,IDLEN, + lostbms[i].bmname,lostbms[i].lostdays); + } + } + fclose(inf); + fclose(firef); + + //printf("Total %d boards.\n", count); + + //mail to the users + for( i=0; i<j; i++) + { + fileheader_t mymail; + char genbuf[200]; + int lostdays; + + lostdays = lostbms[i].lostdays; + + if( (lostdays != 30) && (lostdays != 45) && (lostdays <= 60)) + continue; + + sprintf(genbuf, BBSHOME "/home/%c/%s", lostbms[i].bmname[0], lostbms[i].bmname); + stampfile(genbuf, &mymail); + + strcpy(mymail.owner, "[PTTĵ¹î§½]"); + + if(lostdays <= 60){ + sprintf(mymail.title, + "\033[32m [ª©¥D§K¾ĵ§i³qª¾] \033[m %s BM %s", lostbms[i].title, lostbms[i].bmname); + }else{ + sprintf(mymail.title, + "\033[32m [ª©¥D§K¾³qª¾] \033[m %s BM %s", lostbms[i].title, lostbms[i].bmname); + } + mymail.savemode = 0 ; + unlink(genbuf); + if(lostdays <= 60){ + LINK(OUTFILE, genbuf); + }else{ + LINK(FIREFILE, genbuf); + } + + sprintf(genbuf, BBSHOME "/home/%c/%s/.DIR", lostbms[i].bmname[0], lostbms[i].bmname); + append_record(genbuf, &mymail, sizeof(mymail)); + } + + return 0; +} diff --git a/util/toplazyBM.sh b/util/toplazyBM.sh new file mode 100644 index 00000000..033e545f --- /dev/null +++ b/util/toplazyBM.sh @@ -0,0 +1,3 @@ +bin/toplazyBM +bin/post Record Ãi´kª©¥D±Æ¦æº] [Pttĵ¹î§½] etc/toplazyBM +bin/post ViolateLaw ¤µ¤é§K¾ª©¥D [Pttªk°'|'] etc/firelazyBM diff --git a/util/topsong.sh b/util/topsong.sh new file mode 100644 index 00000000..19e9663a --- /dev/null +++ b/util/topsong.sh @@ -0,0 +1,5 @@ +#!/bin/sh +# $Id: topsong.sh,v 1.1 2002/03/07 15:13:46 in2 Exp $ +# +bin/post Record "¤W¥bÓ¤ëÂIºq±Æ¦æº]" "[Ptt¬y¦æºô]" etc/topsong +mv ussong tmp diff --git a/util/topusr.c b/util/topusr.c new file mode 100644 index 00000000..22b95e94 --- /dev/null +++ b/util/topusr.c @@ -0,0 +1,205 @@ +/* $Id: topusr.c,v 1.1 2002/03/07 15:13:46 in2 Exp $ */ +/* ¨Ï¥ÎªÌ ¤W¯¸°O¿ý/¤å³¹½g¼Æ ±Æ¦æº] */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include "config.h" +#include "pttstruct.h" +#include "perm.h" +#include "common.h" +#include "util.h" + +#define REAL_INFO +struct manrec +{ + char userid[IDLEN + 1]; + char username[23]; + int values[3]; +}; +typedef struct manrec manrec; +struct manrec *allman[3]; + +userec_t aman; +manrec theman; +int num; +FILE *fp; + +#define TYPE_POST 0 +#define TYPE_LOGIN 1 +#define TYPE_MONEY 2 + + +void + top(type) +{ + static char *str_type[3] = + {"µoªí¦¸¼Æ", "¶i¯¸¦¸¼Æ", " ¤j´I¯Î "}; + int i, j, rows = (num + 1) / 2; + char buf1[80], buf2[80]; + + if (type != 2) + fprintf(fp, "\n\n"); + + fprintf(fp, "\ +[1;36m ¢~¢w¢w¢w¢w¢w¢¡ [%dm %8.8s±Æ¦æº] [36;40m ¢~¢w¢w¢w¢w¢w¢¡[m\n\ +[1;36m ¦W¦¸¢w¥N¸¹¢w¢w¢w¼ÊºÙ¢w¢w¢w¢w¢w¢w¼Æ¥Ø¢w¢w¦W¦¸¢w¥N¸¹¢w¢w¢w¼ÊºÙ¢w¢w¢w¢w¢w¢w¼Æ¥Ø[m\ +", type + 44, str_type[type]); + for (i = 0; i < rows; i++) + { + char ch=' '; + int value; + + if(allman[type][i].values[type] > 1000000000) + { value=allman[type][i].values[type]/1000000; ch='M';} + else if(allman[type][i].values[type] > 1000000) + { value=allman[type][i].values[type]/1000; ch='K';} + else {value=allman[type][i].values[type]; ch=' ';} + sprintf(buf1, "[%2d] %-11.11s%-16.16s%5d%c", + i + 1, allman[type][i].userid, allman[type][i].username, + value, ch); + j = i + rows; + if(allman[type][j].values[type] > 1000000000) + { value=allman[type][j].values[type]/1000000; ch='M';} + else if(allman[type][j].values[type] > 1000000) + { value=allman[type][j].values[type]/1000; ch='K';} + else {value=allman[type][j].values[type]; ch=' ';} + + sprintf(buf2, "[%2d] %-11.11s%-16.16s%4d%c", + j + 1, allman[type][j].userid, allman[type][j].username, + value, ch); + if (i < 3) + fprintf(fp, "\n [1;%dm%-40s[0;37m%s", 31 + i, buf1, buf2); + else + fprintf(fp, "\n %-40s%s", buf1, buf2); + } +} + + +#ifdef HAVE_TIN +int + post_in_tin(char *name) +{ + char buf[256]; + FILE *fh; + int counter = 0; + + sprintf(buf, "%s/home/%c/%s/.tin/posted", home_path, name[0], name); + fh = fopen(buf, "r"); + if (fh == NULL) + return 0; + else + { + while (fgets(buf, 255, fh) != NULL) + counter++; + fclose(fh); + return counter; + } +} +#endif /* HAVE_TIN */ +int + not_alpha(ch) +register char ch; +{ + return (ch < 'A' || (ch > 'Z' && ch < 'a') || ch > 'z'); +} + +int + not_alnum(ch) +register char ch; +{ + return (ch < '0' || (ch > '9' && ch < 'A') || + (ch > 'Z' && ch < 'a') || ch > 'z'); +} + +int + bad_user_id(userid) +char *userid; +{ + register char ch; + if (strlen(userid) < 2) + return 1; + if (not_alpha(*userid)) + return 1; + while((ch = *(++userid))) + { + if (not_alnum(ch)) + return 1; + } + return 0; +} + +int main(argc, argv) +int argc; +char **argv; +{ + int i, j; + + if (argc < 3) + { + printf("Usage: %s <num_top> <out-file>\n", argv[0]); + exit(1); + } + + num = atoi(argv[1]); + if (num == 0) + num = 30; + + if(passwd_mmap()) + { + printf("Sorry, the data is not ready.\n"); + exit(0); + } + for(i=0; i<3; i++) + { + allman[i]=malloc(sizeof(manrec) * num); + memset(allman[i],0,sizeof(manrec) * num); + } + for(j = 1; j <= MAX_USERS; j++) { + passwd_query(j, &aman); + aman.userid[IDLEN]=0; + aman.username[22]=0; + if((aman.userlevel & PERM_NOTOP) || !aman.userid[0] || + bad_user_id(aman.userid) || + strchr(aman.userid, '.')) + { + continue; + } + else { + strcpy(theman.userid, aman.userid); + strcpy(theman.username, aman.username); + theman.values[TYPE_LOGIN] = aman.numlogins; + theman.values[TYPE_POST] = aman.numposts; + theman.values[TYPE_MONEY] = aman.money; + for(i=0; i<3; i++) + { + int k,l; + for(k=num-1; k>=0 && allman[i][k].values[i]<theman.values[i]; + k--); + k++; + if(k<num) + { + for(l=num-1; l>k; l--) + memcpy(&allman[i][l], &allman[i][l-1], + sizeof(manrec)); + memcpy(&allman[i][k], &theman, sizeof(manrec)); + } + } + } + } + + + if ((fp = fopen(argv[2], "w")) == NULL) + { + printf("cann't open topusr\n"); + return 0; + } + + top(TYPE_MONEY); + top(TYPE_POST); + top(TYPE_LOGIN); + + fclose(fp); + return 0; +} diff --git a/util/tunepasswd.c b/util/tunepasswd.c new file mode 100644 index 00000000..15a3fe1f --- /dev/null +++ b/util/tunepasswd.c @@ -0,0 +1,77 @@ +/* $Id: tunepasswd.c,v 1.1 2002/03/07 15:13:46 in2 Exp $ */ +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/file.h> +#include "config.h" +#include "pttstruct.h" +#include "common.h" + +int tune(int num) { + int i, j, fin, fout; + userec_t u; + + if((fin = open(FN_PASSWD, O_RDONLY)) == -1) { + perror(FN_PASSWD); + return 1; + } + if(flock(fin, LOCK_EX)) { + printf("Lock failed!\n"); + return 1; + } + if((fout = open(FN_PASSWD ".tune" , O_WRONLY | O_CREAT, 0600)) == -1) { + perror(FN_PASSWD ".tune"); + flock(fin, LOCK_UN); + close(fin); + return 1; + } + + for(i = j = 0; i < num; i++) { + read(fin, &u, sizeof(u)); + if(u.userid[0]) { + if(j == MAX_USERS) { + printf("MAX_USERS is too small!\n"); + close(fout); + unlink(FN_PASSWD ".tune"); + flock(fin, LOCK_UN); + close(fin); + return 1; + } + write(fout, &u, sizeof(u)); + j++; + } + } + for(memset(&u, 0, sizeof(u)); j < MAX_USERS; j++) { + write(fout, &u, sizeof(u)); + } + close(fout); + + /* backup */ + unlink(FN_PASSWD "~"); + link(FN_PASSWD, FN_PASSWD "~"); + unlink(FN_PASSWD); + link(FN_PASSWD ".tune", FN_PASSWD); + unlink(FN_PASSWD ".tune"); + + flock(fin, LOCK_UN); + close(fin); + return 0; +} + +int main() { + struct stat sb; + + if(stat(FN_PASSWD, &sb)) { + perror("stat"); + return 1; + } + if(sb.st_size != sizeof(userec_t) * MAX_USERS) { + printf("size and MAX_USERS do not match!\n"); + if(tune(sb.st_size / sizeof(userec_t)) == 0) + printf(FN_PASSWD " has been tuned successfully!\n"); + } else + printf("Nothing to do.\n"); + return 0; +} diff --git a/util/uhash_loader.c b/util/uhash_loader.c new file mode 100644 index 00000000..2d88dd06 --- /dev/null +++ b/util/uhash_loader.c @@ -0,0 +1,129 @@ +/* $Id: uhash_loader.c,v 1.1 2002/03/07 15:13:47 in2 Exp $ */ +/* standalone uhash loader -- jochang */ +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> +#include <ctype.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/shm.h> + +#ifdef __FreeBSD__ +#include <machine/param.h> +#endif + +#include "config.h" +#include "pttstruct.h" +#include "common.h" + +unsigned string_hash(unsigned char *s); +void add_to_uhash(int n, userec_t *id); +void fill_uhash(void); +void load_uhash(void); + +uhash_t *uhash; + +int main() { + setgid(BBSGID); + setuid(BBSUID); + chdir(BBSHOME); + load_uhash(); + return 0; +} + +void load_uhash(void) { + int shmid; + shmid = shmget(UHASH_KEY, sizeof(uhash_t), IPC_CREAT | 0600); +/* note we didn't use IPC_EXCL here. + so if the loading fails, + (like .PASSWD doesn't exist) + we may try again later. +*/ + if (shmid < 0) + { + perror("shmget"); + exit(1); + } + + uhash = (void *) shmat(shmid, NULL, 0); + if (uhash == (void *) -1) + { + perror("shmat"); + exit(1); + } + +/* in case it's not assumed zero, this becomes a race... */ + uhash->loaded = 0; + + fill_uhash(); + +/* ok... */ + uhash->loaded = 1; +} + +void fill_uhash(void) +{ + int fd, usernumber; + usernumber = 0; + + for (fd = 0; fd < (1 << HASH_BITS); fd++) + uhash->hash_head[fd] = -1; + + if ((fd = open(FN_PASSWD, O_RDONLY)) > 0) + { + struct stat stbuf; + caddr_t fimage, mimage; + + fstat(fd, &stbuf); + fimage = mmap(NULL, stbuf.st_size, PROT_READ, MAP_SHARED, fd, 0); + if (fimage == (char *) -1) + { + perror("mmap"); + exit(1); + } + close(fd); + fd = stbuf.st_size / sizeof(userec_t); + if (fd > MAX_USERS) + fd = MAX_USERS; + + for (mimage = fimage; usernumber < fd; mimage += sizeof(userec_t)) + { + add_to_uhash(usernumber, mimage); + usernumber++; + } + munmap(fimage, stbuf.st_size); + } + else + { + perror("open"); + exit(1); + } + uhash->number = usernumber; + printf("total %d names loaded.\n", usernumber); +} +unsigned string_hash(unsigned char *s) +{ + unsigned int v = 0; + while (*s) + { + v = (v << 8) | (v >> 24); + v ^= toupper(*s++); /* note this is case insensitive */ + } + return (v * 2654435769UL) >> (32 - HASH_BITS); +} + +void add_to_uhash(int n, userec_t *user) +{ + int *p, h = string_hash(user->userid); + strcpy(uhash->userid[n], user->userid); + uhash->money[n] = user->money; + p = &(uhash->hash_head[h]); + + while (*p != -1) + p = &(uhash->next_in_hash[*p]); + + uhash->next_in_hash[*p = n] = -1; +} diff --git a/util/userlist.c b/util/userlist.c new file mode 100644 index 00000000..9a142926 --- /dev/null +++ b/util/userlist.c @@ -0,0 +1,48 @@ +/* $id:$ */ +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/shm.h> +#include "config.h" +#include "pttstruct.h" + +struct utmpfile_t *u; + +int main(int argc, char **argv) { + int i, shm, counter; + + shm = shmget(UTMPSHM_KEY, USHM_SIZE, SHM_R | SHM_W); + if(shm == -1) { + perror("shmget"); + exit(0); + } + + u = shmat(shm, NULL, 0); + if(u == (struct utmpfile_t *)-1) { + perror("shmat"); + exit(0); + } + + if(argc > 1) { + for(i = 1; i < argc; i++) + u->uinfo[atoi(argv[i])].pid = 0; + } else { + for(i = counter = 0; i < USHM_SIZE; i++) + if(u->uinfo[i].pid) { + userinfo_t *f; + + f = &u->uinfo[i]; + printf( + "%4d(%d) p[%d] i[%d] u[%s] n[%s] f[%s] m[%d] d[%d] t[%ld]\n", + ++counter, i, f->pager, f->invisible, f->userid, + f->username, f->from, f->mode, f->mind, f->lastact); + } + printf("\nTotal: %d(%d)\n", counter, u->number); + if(counter != u->number) { + u->number = counter; + printf("adjust user number!\n"); + } + } + return 0; +} diff --git a/util/util.h b/util/util.h new file mode 100644 index 00000000..9128e575 --- /dev/null +++ b/util/util.h @@ -0,0 +1,31 @@ +/* $Id: util.h,v 1.1 2002/03/07 15:13:46 in2 Exp $ */ +#ifndef INCLUDE_UTIL_H +#define INCLUDE_UTIL_H + +int searchuser(char *userid); +int stampfile(char *fpath, fileheader_t *fh); +int append_record(char *fpath, fileheader_t *record, int size); +int get_record(char *fpath, void *rptr, int size, int id); +int substitute_record(char *fpath, void *rptr, int size, int id); +void resolve_boards(); +int getbnum(char *bname); +void inbtotal(int bid, int add); +void *attach_shm(int shmkey, int shmsize); +void reload_pttcache(); +void resolve_fcache(); +void attach_uhash(); +void stamplink(char *fpath, fileheader_t *fh); +void resolve_utmp(); +void remove_from_uhash(int n); +void setuserid(int num, char *userid); + +int passwd_mmap(); +int passwd_update(int num, userec_t *buf); +int passwd_query(int num, userec_t *buf); +int passwd_apply(int (*fptr)(userec_t *)); +int passwd_apply2(int (*fptr)(int, userec_t *)); +void passwd_lock(); +void passwd_unlock(); + +#endif + diff --git a/util/util_cache.c b/util/util_cache.c new file mode 100644 index 00000000..12a01994 --- /dev/null +++ b/util/util_cache.c @@ -0,0 +1,518 @@ +/* $Id: util_cache.c,v 1.1 2002/03/07 15:13:46 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <signal.h> +#include <unistd.h> +#include <fcntl.h> +#include <ctype.h> +#include <errno.h> +#include <time.h> +#include <sys/types.h> +#include <sys/types.h> +#include <sys/mman.h> +#include <sys/ipc.h> +#include <sys/shm.h> +#include <sys/sem.h> + +#ifdef __FreeBSD__ +#include <machine/param.h> +#endif + +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "perm.h" +#include "modes.h" +#include "proto.h" + +int fcache_semid; + +/* the reason for "safe_sleep" is that we may call sleep during + SIGALRM handler routine, while SIGALRM is blocked. + if we use the original sleep, we'll never wake up. */ +unsigned int safe_sleep(unsigned int seconds) { + /* jochang sleep¦³°ÝÃD®É¥Î*/ + sigset_t set,oldset; + + sigemptyset(&set); + sigprocmask(SIG_BLOCK, &set, &oldset); + if(sigismember(&oldset, SIGALRM)) { + unsigned long retv; + sigemptyset(&set); + sigaddset(&set,SIGALRM); + sigprocmask(SIG_UNBLOCK,&set,NULL); + retv=sleep(seconds); + sigprocmask(SIG_BLOCK,&set,NULL); + return retv; + } + return sleep(seconds); +} + +void setapath(char *buf, char *boardname) { + sprintf(buf, "man/boards/%s", boardname); +} + +static char *str_dotdir = ".DIR"; + +void setadir(char *buf, char *path) { + sprintf(buf, "%s/%s", path, str_dotdir); +} + +static void attach_err(int shmkey, char *name) { + fprintf(stderr, "[%s error] key = %x\n", name, shmkey); + fprintf(stderr, "errno = %d: %s\n", errno, strerror(errno)); + exit(1); +} + +void *attach_shm(int shmkey, int shmsize) { + void *shmptr; + int shmid; + + char *empty_addr; + /* set up one page in-accessible -- jochang */ + { + int fd = open("/dev/zero",O_RDONLY); + int size = ((shmsize + 4095) / 4096) * 4096; + + munmap( + (empty_addr=mmap(0,4096+size,PROT_NONE,MAP_PRIVATE,fd,0))+4096 + ,size); + + close(fd); + } + + shmid = shmget(shmkey, shmsize, 0); + if(shmid < 0) { + shmid = shmget(shmkey, shmsize, IPC_CREAT | 0600); + if(shmid < 0) + attach_err(shmkey, "shmget"); + shmptr = (void *)shmat(shmid, NULL, 0); + if(shmptr == (void *)-1) + attach_err(shmkey, "shmat"); + } else { + shmptr = (void *)shmat(shmid, NULL, 0); + if(shmptr == (void *)-1) + attach_err(shmkey, "shmat"); + } + + /* unmap the page -- jochang */ + { + munmap(empty_addr,4096); + } + return shmptr; +} + +#ifndef __FreeBSD__ +/* according to X/OPEN we have to define it ourselves */ +union semun { + int val; /* value for SETVAL */ + struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */ + unsigned short int *array; /* array for GETALL, SETALL */ + struct seminfo *__buf; /* buffer for IPC_INFO */ +}; +#endif + +#define SEM_FLG 0600 /* semaphore mode */ + +/* ----------------------------------------------------- */ +/* semaphore : for critical section */ +/* ----------------------------------------------------- */ +void sem_init(int semkey,int *semid) { + union semun s; + + s.val=1; + *semid = semget(semkey, 1, 0); + if(*semid == -1) { + *semid = semget(semkey, 1, IPC_CREAT | SEM_FLG); + if(*semid == -1) + attach_err(semkey, "semget"); + semctl(*semid, 0, SETVAL, s); + } +} + +void sem_lock(int op,int semid) { + struct sembuf sops; + + sops.sem_num = 0; + sops.sem_flg = SEM_UNDO; + sops.sem_op = op; + semop(semid, &sops, 1); +} + +/* uhash *******************************************/ +/* the design is this: + we use another stand-alone program to create and load data into the hash. + (that program could be run in rc-scripts or something like that) + after loading completes, the stand-alone program sets loaded to 1 and exits. + + the bbs exits if it can't attach to the shared memory or + the hash is not loaded yet. +*/ +uhash_t *uhash; + +int setumoney(int uid, int money) { + uhash->money[uid-1]=money; + passwd_update_money(uid); + return uhash->money[uid-1]; +} + +int deumoney(int uid, int money) { + if(money<0 && uhash->money[uid-1]<-money) + return setumoney(uid,0); + else + return setumoney(uid,uhash->money[uid-1]+money); +} +int moneyof(int uid){ /* ptt §ï¶iª÷¿ú³B²z®Ä²v */ + return uhash->money[uid-1]; +} +/* attach_uhash should be called before using uhash */ +void attach_uhash() { + uhash = attach_shm(UHASH_KEY, sizeof(*uhash)); + if(!uhash->loaded) /* assume fresh shared memory is zeroed */ + exit(1); +} + + +static unsigned string_hash(unsigned char *s) { + unsigned int v=0; + while(*s) { + v = (v << 8) | (v >> 24); + v ^= toupper(*s++); /* note this is case insensitive */ + } + return (v * 2654435769UL) >> (32 - HASH_BITS); +} + +void add_to_uhash(int n, char *id) { + int *p, h = string_hash(id); + strcpy(uhash->userid[n], id); + + p = &(uhash->hash_head[h]); + + while(*p != -1) + p = &(uhash->next_in_hash[*p]); + + uhash->next_in_hash[*p = n] = -1; +} + +/* note: after remove_from_uhash(), you should add_to_uhash() + (likely with a different name) */ +void remove_from_uhash(int n) { + int h = string_hash(uhash->userid[n]); + int *p = &(uhash->hash_head[h]); + + while(*p != -1 && *p != n) + p = &(uhash->next_in_hash[*p]); + if(*p == n) + *p = uhash->next_in_hash[n]; +} + +int searchuser(char *userid) { + int h,p; + + if(uhash == NULL) + attach_uhash(); /* for sloopy util programs */ + + h = string_hash(userid); + p = uhash->hash_head[h]; + + while(p != -1) { + if(strcasecmp(uhash->userid[p],userid) == 0) { + strcpy(userid,uhash->userid[p]); + return p + 1; + } + p = uhash->next_in_hash[p]; + } + return 0; +} +userec_t xuser; + +int getuser(char *userid) { + int uid; + if((uid = searchuser(userid))) + passwd_query(uid, &xuser); + return uid; +} +void setuserid(int num, char *userid) { + if(num > 0 && num <= MAX_USERS) { + if(num > uhash->number) + uhash->number = num; + else + remove_from_uhash(num-1); + add_to_uhash(num-1,userid); + } +} + +/*-------------------------------------------------------*/ +/* .UTMP cache */ +/*-------------------------------------------------------*/ +struct utmpfile_t *utmpshm=NULL; + +void resolve_utmp() { + if(utmpshm == NULL) { + utmpshm = attach_shm(UTMPSHM_KEY, sizeof(*utmpshm)); + if(utmpshm->uptime == 0) + utmpshm->uptime = utmpshm->number = 1; + } +} + +userinfo_t *currutmp = NULL; + +void getnewutmpent(userinfo_t *up) { + extern int errno; + register int i; + register userinfo_t *uentp; + + resolve_utmp(); + + for(i = 0; i < USHM_SIZE; i++) { + uentp = &(utmpshm->uinfo[i]); + if(!(uentp->pid)) { + memcpy(uentp, up, sizeof(userinfo_t)); + currutmp = uentp; + utmpshm->number++; + return; + } + } + exit(1); +} + +int apply_ulist(int (*fptr)(userinfo_t *)) { + register userinfo_t *uentp; + register int i, state; + + resolve_utmp(); + for(i = 0; i < USHM_SIZE; i++) { + uentp = &(utmpshm->uinfo[i]); + if(uentp->pid && (PERM_HIDE(currutmp) || !PERM_HIDE(uentp))) + if((state = (*fptr) (uentp))) + return state; + } + return 0; +} + +userinfo_t *search_ulist(int uid) { + register int i; + register userinfo_t *uentp; + + resolve_utmp(); + for(i = 0; i < USHM_SIZE; i++) { + uentp = &(utmpshm->uinfo[i]); + if(uid==uentp->uid) + return uentp; + } + return 0; +} + +/*-------------------------------------------------------*/ +/* .BOARDS cache */ +/*-------------------------------------------------------*/ +char *fn_board=FN_BOARD; +bcache_t *brdshm; +boardheader_t *bcache; + +static void reload_bcache() { + if(brdshm->busystate) { + safe_sleep(1); + } +} + +int numboards = -1; + +void resolve_boards() { + if(brdshm == NULL) { + brdshm = attach_shm(BRDSHM_KEY, sizeof(*brdshm)); + if(brdshm->touchtime == 0) + brdshm->touchtime = 1; + bcache = brdshm->bcache; + } + + while(brdshm->uptime < brdshm->touchtime) + reload_bcache(); + numboards = brdshm->number; +} + +void touch_boards() { + time(&(brdshm->touchtime)); + numboards = -1; + resolve_boards(); +} +void reset_board(int bid) +{ + int fd; + if(--bid<0)return; + if(brdshm->busystate==0) + { + brdshm->busystate = 1; + if((fd = open(fn_board, O_RDONLY)) > 0) { + lseek(fd, (off_t)(bid * sizeof(boardheader_t)), SEEK_SET); + read(fd, &bcache[bid], sizeof(boardheader_t)); + close(fd); + } + brdshm->busystate = 0; + } +} +boardheader_t *getbcache(int bid) { /* Ptt§ï¼g */ + return bcache + bid - 1; +} + +void touchbtotal(int bid) { + brdshm->total[bid - 1] = 0; + brdshm->lastposttime[bid - 1] = 0; +} + + +int getbnum(char *bname) { + register int i; + register boardheader_t *bhdr; + + for(i = 0, bhdr = bcache; i++ < numboards; bhdr++) + if( + !strcasecmp(bname, bhdr->brdname)) + return i; + return 0; +} + +/*-------------------------------------------------------*/ +/* PTT cache */ +/*-------------------------------------------------------*/ +/* cachefor °ÊºA¬Ýª© */ +struct pttcache_t *ptt; + +void reload_pttcache() { + if(ptt->busystate) + safe_sleep(1); + else { /* jochang: temporary workaround */ + fileheader_t item, subitem; + char pbuf[256], buf[256], *chr; + FILE *fp, *fp1, *fp2; + int id, section = 0; + + ptt->busystate = 1; + ptt->max_film = 0; + bzero(ptt->notes, sizeof ptt->notes); + setapath(pbuf, "Note"); + setadir(buf, pbuf); + id = 0; + if((fp = fopen(buf, "r"))) { + while(fread(&item, sizeof(item), 1, fp)) { + if(item.title[3]=='<' && item.title[8]=='>') { + sprintf(buf,"%s/%s", pbuf, item.filename); + setadir(buf, buf); + if(!(fp1 = fopen(buf, "r"))) + continue; + ptt->next_refresh[section] = ptt->n_notes[section] = id; + section ++; + while(fread(&subitem, sizeof(subitem), 1, fp1)) { + sprintf(buf,"%s/%s/%s", pbuf, item.filename , + subitem.filename); + if(!(fp2=fopen(buf,"r"))) + continue; + fread(ptt->notes[id],sizeof(char), 200*11, fp2); + ptt->notes[id][200*11 - 1]=0; + id++; + fclose(fp2); + if(id >= MAX_MOVIE) + break; + } + fclose(fp1); + if(id >= MAX_MOVIE || section >= MAX_MOVIE_SECTION) + break; + } + } + fclose(fp); + } + ptt->next_refresh[section] = -1; + ptt->n_notes[section] = ptt->max_film = id-1; + ptt->max_history = ptt->max_film - 2; + if(ptt->max_history > MAX_HISTORY - 1) + ptt->max_history = MAX_HISTORY - 1; + if(ptt->max_history <0) ptt->max_history=0; + + fp = fopen("etc/today_is","r"); + if(fp) { + fgets(ptt->today_is,15,fp); + if((chr = strchr(ptt->today_is,'\n'))) + *chr = 0; + ptt->today_is[15] = 0; + fclose(fp); + } + + /* µ¥©Ò¦³¸ê®Æ§ó·s«á¦A³]©w uptime */ + + ptt->uptime = ptt->touchtime ; + ptt->busystate = 0; + } +} + +void resolve_garbage() { + int count=0; + + if(ptt == NULL) { + ptt = attach_shm(PTTSHM_KEY, sizeof(*ptt)); + if(ptt->touchtime == 0) + ptt->touchtime = 1; + } + while(ptt->uptime < ptt->touchtime) { /* ¤£¥Îwhileµ¥ */ + reload_pttcache(); + if(count ++ > 10 && ptt->busystate) { +/* Ptt: ³oÃä·|¦³°ÝÃD load¶W¹L10 ¬í·|©Ò¦³¶iloopªºprocess³£Åý busystate = 0 + ³o¼Ë·|©Ò¦³prcosee³£·|¦bload °ÊºA¬ÝªO ·|³y¦¨load¤j¼W + ¦ý¨S¦³¥Î³oÓfunctionªº¸Ü ¸U¤@load passwdÀɪºprocess¦º¤F ¤S¨S¦³¤H§â¥L + ¸Ñ¶} ¦P¼Ëªº°ÝÃDµo¥Í¦breload passwd +*/ + ptt->busystate = 0; + } + } +} + +/*-------------------------------------------------------*/ +/* PTT's cache */ +/*-------------------------------------------------------*/ +/* cachefor from host »P³Ì¦h¤W½u¤H¼Æ */ +struct fromcache_t *fcache; + +static void reload_fcache() { + if(fcache->busystate) + safe_sleep(1); + else { + FILE *fp; + + fcache->busystate = 1; + bzero(fcache->domain, sizeof fcache->domain); + if((fp = fopen("etc/domain_name_query","r"))) { + char buf[101],*po; + + fcache->top=0; + while(fgets(buf,100,fp)) { + if(buf[0] && buf[0] != '#' && buf[0] != ' ' && + buf[0] != '\n') { + sscanf(buf,"%s",fcache->domain[fcache->top]); + po = buf + strlen(fcache->domain[fcache->top]); + while(*po == ' ') + po++; + strncpy(fcache->replace[fcache->top],po,49); + fcache->replace[fcache->top] + [strlen(fcache->replace[fcache->top])-1] = 0; + (fcache->top)++; + } + } + } + + fcache->max_user=0; + + /* µ¥©Ò¦³¸ê®Æ§ó·s«á¦A³]©w uptime */ + fcache->uptime = fcache->touchtime; + fcache->busystate = 0; + } +} + +void resolve_fcache() { + if(fcache == NULL) { + fcache = attach_shm(FROMSHM_KEY, sizeof(*fcache)); + if(fcache->touchtime == 0) + fcache->touchtime = 1; + } + while(fcache->uptime < fcache->touchtime) + reload_fcache(); +} diff --git a/util/util_passwd.c b/util/util_passwd.c new file mode 100644 index 00000000..07a79351 --- /dev/null +++ b/util/util_passwd.c @@ -0,0 +1,139 @@ +/* $Id: util_passwd.c,v 1.1 2002/03/07 15:13:46 in2 Exp $ */ +#include <stdio.h> +#include <string.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/mman.h> +#include <sys/ipc.h> +#include <sys/sem.h> +#include "config.h" +#include "pttstruct.h" +#include "modes.h" +#include "common.h" + +#ifndef SEM_R +#define SEM_R 0400 +#endif + +#ifndef SEM_A +#define SEM_A 0200 +#endif + +#ifndef __FreeBSD__ +union semun { + int val; /* value for SETVAL */ + struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */ + u_short *array; /* array for GETALL & SETALL */ + struct seminfo *__buf; /* buffer for IPC_INFO */ +}; +#endif + +static userec_t *passwd_image = NULL; +static int passwd_image_size; +static int semid = -1; + +int passwd_mmap() { + int fd; + + if(passwd_image!=NULL) return 0; + fd = open(FN_PASSWD, O_RDWR); + if(fd > 0) { + struct stat st; + + fstat(fd, &st); + passwd_image_size = st.st_size; + passwd_image = mmap(NULL, passwd_image_size, + PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if(passwd_image == (userec_t *)-1) { + perror("mmap"); + return -1; + } + close(fd); + semid = semget(PASSWDSEM_KEY, 1, SEM_R | SEM_A | IPC_CREAT | IPC_EXCL); + if(semid == -1) { + if(errno == EEXIST) { + semid = semget(PASSWDSEM_KEY, 1, SEM_R | SEM_A); + if(semid == -1) { + perror("semget"); + exit(1); + } + } else { + perror("semget"); + exit(1); + } + } else { + union semun s; + + s.val = 1; + if(semctl(semid, 0, SETVAL, s) == -1) { + perror("semctl"); + exit(1); + } + } + } else { + perror(FN_PASSWD); + return -1; + } + return 0; +} +int passwd_update_money(int num) { + int money; + if(num < 1 || num > MAX_USERS) + return -1; + money = moneyof(num); + memcpy(&passwd_image[num - 1].money, &money, sizeof(int)); + return 0; +} + +int passwd_update(int num, userec_t *buf) { + if(num < 1 || num > MAX_USERS) + return -1; + buf->money = moneyof(num); + memcpy(&passwd_image[num - 1], buf, sizeof(userec_t)); + return 0; +} + +int passwd_query(int num, userec_t *buf) { + if(num < 1 || num > MAX_USERS) + return -1; + memcpy(buf, &passwd_image[num - 1], sizeof(userec_t)); + return 0; +} + +int passwd_apply(int (*fptr)(userec_t *)) { + int i; + + for(i = 0; i < MAX_USERS; i++) + if((*fptr)(&passwd_image[i]) == QUIT) + return QUIT; + return 0; +} + +int passwd_apply2(int (*fptr)(int, userec_t *)) { + int i; + + for(i = 0; i < MAX_USERS; i++) + if((*fptr)(i, &passwd_image[i]) == QUIT) + return QUIT; + return 0; +} + +void passwd_lock() { + struct sembuf buf = { 0, -1, SEM_UNDO }; + + if(semop(semid, &buf, 1)) { + perror("semop"); + exit(1); + } +} + +void passwd_unlock() { + struct sembuf buf = { 0, 1, SEM_UNDO }; + + if(semop(semid, &buf, 1)) { + perror("semop"); + exit(1); + } +} diff --git a/util/util_record.c b/util/util_record.c new file mode 100644 index 00000000..ad129638 --- /dev/null +++ b/util/util_record.c @@ -0,0 +1,245 @@ +/* $Id: util_record.c,v 1.1 2002/03/07 15:13:46 in2 Exp $ */ +#include <stdio.h> +#include <errno.h> +#include <string.h> +#include <unistd.h> +#include <time.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/file.h> +#include "config.h" +#include "pttstruct.h" +#include "modes.h" +#include "proto.h" + +#undef HAVE_MMAP +#define BUFSIZE 512 + +extern char *str_reply; + +static void PttLock(int fd, int size, int mode) { + static struct flock lock_it; + int ret; + + lock_it.l_whence = SEEK_CUR; /* from current point */ + lock_it.l_start = 0; /* -"- */ + lock_it.l_len = size; /* length of data */ + lock_it.l_type = mode; /* set exclusive/write lock */ + lock_it.l_pid = 0; /* pid not actually interesting */ + while((ret = fcntl(fd, F_SETLKW, &lock_it)) < 0 && errno == EINTR); +} + +#define safewrite write + +int get_num_records(char *fpath, int size) { + struct stat st; + if(stat(fpath, &st) == -1) + return 0; + return st.st_size / size; +} + +int get_sum_records(char* fpath, int size) { + struct stat st; + long ans = 0; + FILE* fp; + fileheader_t fhdr; + char buf[200], *p; + + if(!(fp = fopen(fpath, "r"))) + return -1; + + strcpy(buf, fpath); + p = strrchr(buf, '/') + 1; + + while(fread(&fhdr, size, 1, fp) == 1) { + strcpy(p, fhdr.filename); + if(stat(buf, &st) == 0 && S_ISREG(st.st_mode) && st.st_nlink == 1) + ans += st.st_size; + } + fclose(fp); + return ans / 1024; +} + +int get_record(char *fpath, void *rptr, int size, int id) { + int fd = -1; + + if(id < 1 || (fd = open(fpath, O_RDONLY, 0)) != -1) { + if(lseek(fd, (off_t)(size * (id - 1)), SEEK_SET) != -1) { + if(read(fd, rptr, size) == size) { + close(fd); + return 0; + } + } + close(fd); + } + return -1; +} + +int get_records(char *fpath, void *rptr, int size, int id, int number) { + int fd; + + if(id < 1 || (fd = open(fpath, O_RDONLY, 0)) == -1) + return -1; + + if(lseek(fd, (off_t)(size * (id - 1)), SEEK_SET) == -1) { + close(fd); + return 0; + } + if((id = read(fd, rptr, size * number)) == -1) { + close(fd); + return -1; + } + close(fd); + return id / size; +} + +int substitute_record(char *fpath, void *rptr, int size, int id) { + int fd; + +#ifdef POSTBUG + if(size == sizeof(fileheader) && (id > 1) && ((id - 1) % 4 == 0)) + saverecords(fpath, size, id); +#endif + + if(id < 1 || (fd = open(fpath, O_WRONLY | O_CREAT, 0644)) == -1) + return -1; + +#ifdef HAVE_REPORT + if(lseek(fd, (off_t)(size * (id - 1)), SEEK_SET) == -1) + report("substitute_record failed!!! (lseek)"); + PttLock(fd, size, F_WRLCK); + if(safewrite(fd, rptr, size) != size) + report("substitute_record failed!!! (safewrite)"); + PttLock(fd, size, F_UNLCK); +#else + lseek(fd, (off_t) (size * (id - 1)), SEEK_SET); + PttLock(fd, size, F_WRLCK); + safewrite(fd, rptr, size); + PttLock(fd, size, F_UNLCK); +#endif + close(fd); + +#ifdef POSTBUG + if(size == sizeof(fileheader) && (id > 1) && ((id - 1) % 4 == 0)) + restorerecords(fpath, size, id); +#endif + + return 0; +} + +int apply_record(char *fpath, int (*fptr)(), int size) { + char abuf[BUFSIZE]; + FILE* fp; + + if(!(fp = fopen(fpath, "r"))) + return -1; + + while(fread(abuf, 1, size, fp) == size) + if((*fptr) (abuf) == QUIT) { + fclose(fp); + return QUIT; + } + fclose(fp); + return 0; +} + +/* mail / post ®É¡A¨Ì¾Ú®É¶¡«Ø¥ßÀɮסA¥[¤W¶lÂW */ +int stampfile(char *fpath, fileheader_t *fh) { + register char *ip = fpath; + time_t dtime; + struct tm *ptime; + int fp = 0; + + if(access(fpath, X_OK | R_OK | W_OK)) + mkdir(fpath, 0755); + + time(&dtime); + while (*(++ip)); + *ip++ = '/'; + do { + sprintf(ip, "M.%ld.A", ++dtime ); + if(fp == -1 && errno != EEXIST) + return -1; + } while((fp = open(fpath, O_CREAT | O_EXCL | O_WRONLY, 0644)) == -1); + close(fp); + memset(fh, 0, sizeof(fileheader_t)); + strcpy(fh->filename, ip); + ptime = localtime(&dtime); + sprintf(fh->date, "%2d/%02d", ptime->tm_mon + 1, ptime->tm_mday); + return 0; +} + +void stampdir(char *fpath, fileheader_t *fh) { + register char *ip = fpath; + time_t dtime; + struct tm *ptime; + + if(access(fpath, X_OK | R_OK | W_OK)) + mkdir(fpath, 0755); + + time(&dtime); + while(*(++ip)); + *ip++ = '/'; + do { + sprintf(ip, "D%lX", ++dtime & 07777); + } while(mkdir(fpath, 0755) == -1); + memset(fh, 0, sizeof(fileheader_t)); + strcpy(fh->filename, ip); + ptime = localtime(&dtime); + sprintf(fh->date, "%2d/%02d", ptime->tm_mon + 1, ptime->tm_mday); +} + +void stamplink(char *fpath, fileheader_t *fh) { + register char *ip = fpath; + time_t dtime; + struct tm *ptime; + + if(access(fpath, X_OK | R_OK | W_OK)) + mkdir(fpath, 0755); + + time(&dtime); + while(*(++ip)); + *ip++ = '/'; + do { + sprintf(ip, "S%lX", ++dtime ); + } while(symlink("temp", fpath) == -1); + memset(fh, 0, sizeof(fileheader_t)); + strcpy(fh->filename, ip); + ptime = localtime(&dtime); + sprintf(fh->date, "%2d/%02d", ptime->tm_mon + 1, ptime->tm_mday); +} + +int do_append(char *fpath, fileheader_t *record, int size) { + int fd; + + if((fd = open(fpath, O_WRONLY | O_CREAT, 0644)) == -1) { + perror("open"); + return -1; + } + flock(fd, LOCK_EX); + lseek(fd, 0, SEEK_END); + + safewrite(fd, record, size); + + flock(fd, LOCK_UN); + close(fd); + return 0; +} + +int append_record(char *fpath, fileheader_t *record, int size) { +#ifdef POSTBUG + int numrecs = (int)get_num_records(fpath, size); + + bug_possible = 1; + if(size == sizeof(fileheader) && numrecs && (numrecs % 4 == 0)) + saverecords(fpath, size, numrecs + 1); +#endif + do_append(fpath,record,size); + +#ifdef POSTBUG + if(size == sizeof(fileheader) && numrecs && (numrecs % 4 == 0)) + restorerecords(fpath, size, numrecs + 1); + bug_possible = 0; +#endif + return 0; +} diff --git a/util/waterball.pl b/util/waterball.pl new file mode 100644 index 00000000..7f49d3c5 --- /dev/null +++ b/util/waterball.pl @@ -0,0 +1,149 @@ +#!/usr/bin/perl +use lib '/home/bbs/bin/'; +use LocalVars; +use Time::Local; +use POSIX; +use FileHandle; +use strict; +use Mail::Sender; + +my($fndes, $fnsrc, $userid, $mailto, $outmode); +foreach $fndes ( <$JOBSPOOL/water.des.*> ){ #des: userid, mailto, outmode + (open FH, "< $fndes") or next; + chomp($userid = <FH>); + chomp($mailto = <FH>); + chomp($outmode= <FH>); + close FH; + next if( !$userid ); + print "$userid, $mailto, $outmode\n"; + `rm -Rf $TMP/water`; + `mkdir $TMP/water`; + + $fnsrc = $fndes; + $fnsrc =~ s/\.des\./\.src\./; + eval{ + process($fnsrc, "$TMP/water/", $outmode, $userid); + }; + if( $@ ){ + print "$@\n"; + } + else{ + chdir "$TMP/water"; + if( $mailto eq '.' || $mailto =~ /\.bbs/ ){ + $mailto = "$userid.bbs\@$hostname" if( $mailto eq '.' ); + foreach my $fn ( <$TMP/water/*> ){ + my $who = substr($fn, rindex($fn, '/') + 1); + my $content = ''; + open FH, "< $fn";while( <FH> ){chomp;$content .= "$_\n";} + if( !MakeMail({mailto => $mailto, + subject => "©M $who ªº¤ô²y°O¿ý", + body => $content, + }) ){ print "fault\n"; } + } + unlink $fnsrc; + unlink $fndes; + } + else{ + if( MakeMail({tartarget => "$TMP/$userid.waterball.tgz", + tarsource => "*", + mailto => "$userid <$mailto>", + subject => "¤ô²y¬ö¿ý", + body => + "\n ptt2 ¯¸ªø¸s ". POSIX::ctime(time())} + ) ){ + unlink $fnsrc; + unlink $fndes; + } + } + } +} + +sub process +{ + my($fn, $outdir, $outmode, $me) = @_; + my($cmode, $who, $time, $say, $orig, %FH, %LAST, $len); + open DIN, "< $fn"; + while( <DIN> ){ + chomp; + next if( !(($cmode, $who, $time, $say, $orig) = parse($_)) ); + next if( !$who ); + + if( ! $FH{$who} ){ + $FH{$who} = new FileHandle "> $outdir/$who"; + } + if( $outmode == 0 ){ + next if( $say =~ /<<¤U¯¸³qª¾>> -- §Ú¨«Åo¡I/ || + $say =~ /<<¤W¯¸³qª¾>> -- §Ú¨Ó°Õ¡I/ ); + if( $time - $LAST{$who} > 1800 ){ + if( $LAST{$who} != 0 ){ + ($FH{$who})->print( POSIX::ctime($LAST{$who}) , "\n"); + } + ($FH{$who})->print( POSIX::ctime($time) ); + $LAST{$who} = $time; + } + $len = (length($who) > length($me) ? length($who) : length($me))+1; + ($FH{$who})->printf("%-${len}s %s\n", ($cmode?$who:$me).':', $say); + } + elsif( $outmode == 1 ){ + ($FH{$who})->print("$orig\n"); + } + } + if( $outmode == 0 ){ + foreach( keys %FH ){ + ($FH{$_})->print( POSIX::ctime($LAST{$_}) ); + } + } + foreach( keys %FH ){ + ($FH{$_})->close(); + } + close DIN; +} + +sub parse +{ + my $dat = $_[0]; + my($cmode, $who, $year, $month, $day, $hour, $min, $sec, $say); + if( $dat =~ /^To/ ){ + $cmode = 0; + ($who, $say, $month, $day, $year, $hour, $min, $sec) = + $dat =~ m|^To (\w+):\s*(.*)\[(\d+)/(\d+)/(\d+) (\d+):(\d+):(\d+)\]|; + } + else{ + $cmode = 1; + ($who, $say, $month, $day, $year, $hour, $min, $sec) = + $dat =~ m|¡¹(\w+?)\[37;45m\s*(.*)\[m \[0m\[(\w+)/(\w+)/(\w+) (\w+):(\w+):(\w+)\]|; + + } +# $time = timelocal($sec,$min,$hours,$mday,$mon,$year); + + return undef if( $month == 0 ); + return ($cmode, $who, timelocal($sec, $min, $hour, $day, $month - 1, $year), $say, $_[0]); +} + +sub MakeMail +{ + my($arg) = @_; + my $sender; + `$TAR zcf $arg->{tartarget} $arg->{tarsource}` + if( $arg->{tarsource} ); + $sender = new Mail::Sender{smtp => $SMTPSERVER, + from => "$hostname¤ô²y¾ã²zµ{¦¡ <in2\@ptt2.csie.ntu.edu.tw>"}; + foreach( 0..3 ){ + if( (!$arg->{tartarget} && + $sender->MailMsg({to => $arg->{mailto}, + subject => $arg->{subject}, + msg => $arg->{body} + }) ) || + ($arg->{tartarget} && + $sender->MailFile({to => $arg->{mailto}, + subject => $arg->{subject}, + msg => $arg->{body}, + file => $arg->{tartarget}})) ){ + unlink $arg->{tartarget} if( $arg->{tartarget} ); + return 1; + } + } + print "fault\n"; + unlink $arg->{tartarget} if( $arg->{tartarget} ); + return 0; +} diff --git a/util/weather.perl b/util/weather.perl new file mode 100644 index 00000000..c9a35406 --- /dev/null +++ b/util/weather.perl @@ -0,0 +1,31 @@ +#!/usr/bin/perl +# $Id: weather.perl,v 1.1 2002/03/07 15:13:46 in2 Exp $ +# +# ¤£¯à¶]ªº¸Ü¡A¬Ý¬Ý bbspost ªº¸ô®|¬O§_¥¿½T¡C +# ¦pªGµo¥Xªº post ¨S¦³®ð¶H³ø§i¦Ó¬O»¡ URL §ä¤£¨ì¡A«h½T©w¤@¤U¯à¤£¯à¬Ý¨ì +# ¤¤¥¡®ð¶H§½ªº WWW ¤Î URL ¬O§_¥¿½T¡C +# ²z½×¤W¾A¥Î©Ò¦³ Eagle BBS ¨t¦C¡C +# -- Beagle Apr 13 1997 +open(BBSPOST, "| bin/webgrep>etc/weather.tmp"); +# ¤é´Á +open(DATE, "date +'%a %b %d %T %Y' |"); +$date = <DATE>; +chop $date; +close DATE; + +# Header +# ¤º®e +open(WEATHER, "/usr/bin/lynx -dump http://www.cwb.gov.tw/V3.0/weather/text/Data/W03.txt |"); +while (<WEATHER>) { + print BBSPOST if ($_ ne "\n"); +} +close WEATHER; + +# ñ¦WÀÉ +print BBSPOST "\n--\n"; +print BBSPOST "§Ú¬Obeagle©Ò¦³¥i·Rªº¤p»æ°®...¸ó®ü¬°PttªA°È\n"; +print BBSPOST "--\n"; +print BBSPOST "¡¸ [Origin: ¡·ªGÂæ¤p¯¸¡·] [From: [ÂŲùÃP»æ«Î] ] "; + +close BBSPOST; + diff --git a/util/weather.sh b/util/weather.sh new file mode 100644 index 00000000..315b0ec3 --- /dev/null +++ b/util/weather.sh @@ -0,0 +1,5 @@ +#!/bin/sh +# $Id: weather.sh,v 1.1 2002/03/07 15:13:46 in2 Exp $ +# +bin/weather.perl +bin/post Record ¥þ¬Ù¦U¦a¤Ñ®ð¹w³ø [®ð¶H¤p©j] etc/weather.tmp diff --git a/util/webgrep.c b/util/webgrep.c new file mode 100644 index 00000000..07089bb6 --- /dev/null +++ b/util/webgrep.c @@ -0,0 +1,46 @@ +/* $Id: webgrep.c,v 1.1 2002/03/07 15:13:46 in2 Exp $ */ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +int main() +{ + char genbuf[256], *str, *buf; + while (fgets(genbuf, 255, stdin)) + { + register int ansi; + if (!strncmp(genbuf, "References", 10)) + break; + str = genbuf; + buf = genbuf; + if (!strncmp(genbuf, "lynx: Can't access", 18)) + { + printf("®ð¶H³ø¾É¤p©j¥ð°²¤¤,½Ð¨ìRecordª©Â½¹L¥h¸ê®Æ."); + break; + } + for (ansi = 0; *str; str++) + { + if (*str == '[' && strchr("0123456789", *(str + 1))) + { + ansi = 1; + } + else if (ansi) + { + if (!strchr("0123456789]", *str)) + { + ansi = 0; + if (str) + *buf++ = *str; + } + } + else + { + if (str) + *buf++ = *str; + } + } + *buf = 0; + printf(genbuf); + } + return 0; +} diff --git a/util/xchatd.c b/util/xchatd.c new file mode 100644 index 00000000..46fba147 --- /dev/null +++ b/util/xchatd.c @@ -0,0 +1,3504 @@ +/* $Id: xchatd.c,v 1.1 2002/03/07 15:13:46 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <netdb.h> +#include <fcntl.h> +#include <signal.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <sys/ioctl.h> +#include <sys/socket.h> +#include <time.h> +#include <sys/resource.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include "config.h" +#include "pttstruct.h" +#include "util.h" +#include "perm.h" +#include "common.h" +#include "xchatd.h" + +#define SERVER_USAGE +#define WATCH_DOG +#undef MONITOR /* ºÊ·þ chatroom ¬¡°Ê¥H¸Ñ¨MªÈ¯É */ +#undef DEBUG /* µ{¦¡°£¿ù¤§¥Î */ + +#ifdef DEBUG +#define MONITOR +#endif + +static int gline; + +#ifdef WATCH_DOG +#define MYDOG gline = __LINE__ +#else +#define MYDOG /* NOOP */ +#endif + + + +#define CHAT_PIDFILE "log/chat.pid" +#define CHAT_LOGFILE "log/chat.log" +#define CHAT_INTERVAL (60 * 30) +#define SOCK_QLEN 1 + + +/* name of the main room (always exists) */ + + +#define MAIN_NAME "main" +#define MAIN_TOPIC "²i¯ù¥i°^¦è¤Ñ¦ò" + + +#define ROOM_LOCKED 1 +#define ROOM_SECRET 2 +#define ROOM_OPENTOPIC 4 +#define ROOM_HANDUP 8 +#define ROOM_ALL (NULL) + + +#define LOCKED(room) (room->rflag & ROOM_LOCKED) +#define SECRET(room) (room->rflag & ROOM_SECRET) +#define OPENTOPIC(room) (room->rflag & ROOM_OPENTOPIC) +#define RHANDUP(room) (room->rflag & ROOM_HANDUP) + +#define RESTRICTED(usr) (usr->uflag == 0) /* guest */ +#define CHATSYSOP(usr) (usr->uflag & ( PERM_SYSOP | PERM_CHATROOM)) +/* Thor: SYSOP »P CHATROOM³£¬O chatÁ`ºÞ */ +#define PERM_ROOMOP PERM_CHAT /* Thor: É PERM_CHAT¬° PERM_ROOMOP */ +#define PERM_HANDUP PERM_BM /* É PERM_BM ¬°¦³¨S¦³Á|¤â¹L */ +#define PERM_SAY PERM_NOTOP /* É PERM_NOTOP ¬°¦³¨S¦³µoªíÅv */ + +/* ¶i¤J®É»Ý²MªÅ */ +/* Thor: ROOMOP¬°©Ð¶¡ºÞ²zû */ +#define ROOMOP(usr) (usr->uflag & ( PERM_ROOMOP | PERM_SYSOP | PERM_CHATROOM)) +#define CLOAK(usr) (usr->uflag & PERM_CLOAK) +#define HANDUP(usr) (usr->uflag & PERM_HANDUP) +#define SAY(usr) (usr->uflag & PERM_SAY) +/* Thor: ²á¤Ñ«ÇÁô¨³N */ + + +/* ----------------------------------------------------- */ +/* ChatRoom data structure */ +/* ----------------------------------------------------- */ + +typedef struct ChatRoom ChatRoom; +typedef struct ChatUser ChatUser; +typedef struct UserList UserList; +typedef struct ChatCmd ChatCmd; +typedef struct ChatAction ChatAction; + +struct ChatUser +{ + struct ChatUser *unext; + int sock; /* user socket */ + int talksock; /* talk socket */ + ChatRoom *room; + UserList *ignore; + int userno; + int uflag; + int clitype; /* Xshadow: client type. 1 for common client, + * 0 for bbs only client */ + time_t uptime; /* Thor: unused */ + char userid[IDLEN + 1]; /* real userid */ + char chatid[9]; /* chat id */ + char lasthost[30]; /* host address */ + char ibuf[80]; /* buffer for non-blocking receiving */ + int isize; /* current size of ibuf */ +}; + + +struct ChatRoom +{ + struct ChatRoom *next, *prev; + char name[IDLEN]; + char topic[48]; /* Let the room op to define room topic */ + int rflag; /* ROOM_LOCKED, ROOM_SECRET, ROOM_OPENTOPIC */ + int occupants; /* number of users in room */ + UserList *invite; +}; + + +struct UserList +{ + struct UserList *next; + int userno; + char userid[IDLEN + 1]; +}; + + +struct ChatCmd +{ + char *cmdstr; + void (*cmdfunc) (); + int exact; +}; + + +static ChatRoom mainroom; +static ChatUser *mainuser; +static fd_set mainfds; +static int maxfds; /* number of sockets to select on */ +static int totaluser; /* current number of connections */ +static struct timeval zerotv; /* timeval for selecting */ +static char chatbuf[256]; /* general purpose buffer */ +static int common_client_command; + +static char msg_not_op[] = "¡» ±z¤£¬O³o¶¡²á¤Ñ«Çªº Op"; +static char msg_no_such_id[] = "¡» ¥Ø«e¨S¦³¤H¨Ï¥Î [%s] ³oÓ²á¤Ñ¥N¸¹"; +static char msg_not_here[] = "¡» [%s] ¤£¦b³o¶¡²á¤Ñ«Ç"; + + +#define FUZZY_USER ((ChatUser *) -1) + + +typedef struct userec_t ACCT; + +/* ----------------------------------------------------- */ +/* acct_load for check acct */ +/* ----------------------------------------------------- */ + +int +acct_load(acct, userid) + ACCT *acct; + char *userid; +{ + int id; + if((id=searchuser(userid))<0) + { + return -1; + } + else + { + return get_record(FN_PASSWD, acct, sizeof(ACCT), id); + } +} + + +/* ----------------------------------------------------- */ +/* str_lower for check acct */ +/* ----------------------------------------------------- */ +void +str_lower(dst, src) + char *dst, *src; +{ + register int ch; + + do + { + ch = *src++; + if (ch >= 'A' && ch <= 'Z') + ch |= 0x20; + *dst++ = ch; + } while (ch); +} + +/* + * str_ncpy() - similar to strncpy(3) but terminates string always with '\0' + * if n != 0, and doesn't do padding + */ + +void +str_ncpy(dst, src, n) + char *dst; + char *src; + int n; +{ + char *end; + + end = dst + n; + + do + { + n = (dst == end) ? 0 : *src++; + *dst++ = n; + } while (n); +} + + +/* ----------------------------------------------------- */ +/* usr_fpath for check acct */ +/* ----------------------------------------------------- */ +char *str_home_file = "home/%c/%s/%s"; + +void +usr_fpath(buf, userid, fname) + char *buf, *userid, *fname; +{ + sprintf(buf, str_home_file, userid[0], userid, fname); +} + +/* ----------------------------------------------------- */ +/* chkpasswd for check passwd */ +/* ----------------------------------------------------- */ +char *crypt(); +static char pwbuf[PASSLEN]; + +int +chkpasswd(passwd, test) + char *passwd, *test; +{ + char *pw; + + str_ncpy(pwbuf, test, PASSLEN); + pw = crypt(pwbuf, passwd); + return (!strncmp(pw, passwd, PASSLEN)); +} + +/* ----------------------------------------------------- */ +/* operation log and debug information */ +/* ----------------------------------------------------- */ + + +static int flog; /* log file descriptor */ + + +static void +logit(key, msg) + char *key; + char *msg; +{ + time_t now; + struct tm *p; + char buf[512]; + + time(&now); + p = localtime(&now); + sprintf(buf, "%02d/%02d %02d:%02d:%02d %-13s%s\n", + p->tm_mon + 1, p->tm_mday, + p->tm_hour, p->tm_min, p->tm_sec, key, msg); + write(flog, buf, strlen(buf)); +} + + +static void +log_init() +{ + flog = open(CHAT_LOGFILE, O_WRONLY | O_CREAT | O_APPEND, 0644); + logit("START", "chat daemon"); +} + + +static void +log_close() +{ + close(flog); +} + + +#ifdef DEBUG +static void +debug_user() +{ + register ChatUser *user; + int i; + char buf[80]; + + i = 0; + for (user = mainuser; user; user = user->unext) + { + sprintf(buf, "%d) %s %s", ++i, user->userid, user->chatid); + logit("DEBUG_U", buf); + } +} + + +static void +debug_room() +{ + register ChatRoom *room; + int i; + char buf[80]; + + i = 0; + room = &mainroom; + + do + { + sprintf(buf, "%d) %s %d", ++i, room->name, room->occupants); + logit("DEBUG_R", buf); + } while (room = room->next); +} +#endif /* DEBUG */ + + +/* ----------------------------------------------------- */ +/* string routines */ +/* ----------------------------------------------------- */ + + +static int valid_chatid(register char *id) { + register int ch, len; + + for(len = 0; (ch = *id); id++) { + /* Thor: check for endless */ + MYDOG; + + if(ch == '/' || ch == '*' || ch == ':') + return 0; + if(++len > 8) + return 0; + } + return len; +} + +/* Case Independent strcmp : 1 ==> euqal */ + + +static int +str_equal(s1, s2) + register unsigned char *s1, *s2; /* Thor: ¥[¤W unsigned, + * ÁקK¤¤¤åªº°ÝÃD */ +{ + register int c1, c2; + + for (;;) + { /* Thor: check for endless */ + MYDOG; + + c1 = *s1; + if (c1 >= 'A' && c1 <= 'Z') + c1 |= 32; + + c2 = *s2; + if (c2 >= 'A' && c2 <= 'Z') + c2 |= 32; + + if (c1 != c2) + return 0; + + if (!c1) + return 1; + + s1++; + s2++; + } +} + + +/* ----------------------------------------------------- */ +/* match strings' similarity case-insensitively */ +/* ----------------------------------------------------- */ +/* str_match(keyword, string) */ +/* ----------------------------------------------------- */ +/* 0 : equal ("foo", "foo") */ +/* -1 : mismatch ("abc", "xyz") */ +/* ow : similar ("goo", "good") */ +/* ----------------------------------------------------- */ + + +static int +str_match(s1, s2) + register unsigned char *s1, *s2; /* Thor: ¥[¤W unsigned, + * ÁקK¤¤¤åªº°ÝÃD */ +{ + register int c1, c2; + + for (;;) + { /* Thor: check for endless */ + MYDOG; + + c2 = *s2; + c1 = *s1; + if (!c1) + { + return c2; + } + + if (c1 >= 'A' && c1 <= 'Z') + c1 |= 32; + + if (c2 >= 'A' && c2 <= 'Z') + c2 |= 32; + + if (c1 != c2) + return -1; + + s1++; + s2++; + } +} + + +/* ----------------------------------------------------- */ +/* search user/room by its ID */ +/* ----------------------------------------------------- */ + + +static ChatUser * +cuser_by_userid(userid) + char *userid; +{ + register ChatUser *cu; + + for (cu = mainuser; cu; cu = cu->unext) + { + MYDOG; + + if (str_equal(userid, cu->userid)) + break; + } + return cu; +} + + +static ChatUser * +cuser_by_chatid(chatid) + char *chatid; +{ + register ChatUser *cu; + + for (cu = mainuser; cu; cu = cu->unext) + { + MYDOG; + + if (str_equal(chatid, cu->chatid)) + break; + } + return cu; +} + + +static ChatUser * +fuzzy_cuser_by_chatid(chatid) + char *chatid; +{ + register ChatUser *cu, *xuser; + int mode; + + xuser = NULL; + + for (cu = mainuser; cu; cu = cu->unext) + { + MYDOG; + + mode = str_match(chatid, cu->chatid); + if (mode == 0) + return cu; + + if (mode > 0) + { + if (xuser == NULL) + xuser = cu; + else + return FUZZY_USER; /* ²Å¦XªÌ¤j©ó 2 ¤H */ + } + } + return xuser; +} + + +static ChatRoom *croom_by_roomid(char *roomid) { + register ChatRoom *room; + + room = &mainroom; + do { + MYDOG; + + if(str_equal(roomid, room->name)) + break; + } while((room = room->next)); + return room; +} + + +/* ----------------------------------------------------- */ +/* UserList routines */ +/* ----------------------------------------------------- */ + + +static void +list_free(list) + UserList *list; +{ + UserList *tmp; + + while (list) + { + MYDOG; + + tmp = list->next; + + free(list); + MYDOG; + list = tmp; + } +} + + +static void +list_add(list, user) + UserList **list; + ChatUser *user; +{ + UserList *node; + + MYDOG; + + if((node = (UserList *) malloc(sizeof(UserList)))) { + /* Thor: ¨¾¤îªÅ¶¡¤£°÷ */ + strcpy(node->userid, user->userid); + node->userno = user->userno; + node->next = *list; + *list = node; + } + MYDOG; +} + + +static int +list_delete(list, userid) + UserList **list; + char *userid; +{ + UserList *node; + + while((node = *list)) { + MYDOG; + + if (str_equal(node->userid, userid)) + { + *list = node->next; + MYDOG; + free(node); + MYDOG; + return 1; + } + list = &node->next; /* Thor: listn¸òµÛ«e¶i */ + } + + return 0; +} + + +static int +list_belong(list, userno) + UserList *list; + int userno; +{ + while (list) + { + MYDOG; + + if (userno == list->userno) + return 1; + list = list->next; + } + return 0; +} + + +/* ------------------------------------------------------ */ +/* non-blocking socket routines : send message to users */ +/* ------------------------------------------------------ */ + + +static void +do_send(nfds, wset, msg, number) + int nfds; + fd_set *wset; + char *msg; + int number; +{ + int sr; + + /* Thor: for future reservation bug */ + + zerotv.tv_sec = 0; + zerotv.tv_usec = 16384; /* Ptt: §ï¦¨16384 ÁקK¤£«ö®Éfor loop¦Ycpu time + 16384 ¬ù¨C¬í64¦¸ */ + + MYDOG; + + sr = select(nfds + 1, NULL, wset, NULL, &zerotv); + + MYDOG; + + if (sr > 0) + { + register int len; + + len = strlen(msg) + 1; + while (nfds >= 0) + { + MYDOG; + + if (FD_ISSET(nfds, wset)) + { + MYDOG; + send(nfds, msg, len, 0);/* Thor: ¦pªGbufferº¡¤F, ¤´·| block */ + MYDOG; + if (--sr <= 0) + return; + } + nfds--; + } + } +} + + +static void +send_to_room(room, msg, userno, number) + ChatRoom *room; + char *msg; + int userno; + int number; +{ + ChatUser *cu; + fd_set wset, *wptr; + int sock, max; + static char sendbuf[256]; + int clitype; /* ¤À¬° bbs client ¤Î common client ¨â¦¸³B²z */ + + for (clitype = (number == MSG_MESSAGE || !number) ? 0 : 1; clitype < 2; clitype++) + { + + FD_ZERO(wptr = &wset); + max = -1; + + for (cu = mainuser; cu; cu = cu->unext) + { + MYDOG; + + if (room == cu->room || room == ROOM_ALL) + { + if (cu->clitype == clitype && (!userno || !list_belong(cu->ignore, userno))) + { + sock = cu->sock; + FD_SET(sock, wptr); + if (max < sock) + max = sock; + } + } + } + + if (max < 0) + continue; + + if (clitype) + { + if (strlen(msg)) + sprintf(sendbuf, "%3d %s", number, msg); + else + sprintf(sendbuf, "%3d", number); + + do_send(max, wptr, sendbuf); + } + else + do_send(max, wptr, msg); + } +} + + +static void +send_to_user(user, msg, userno, number) + ChatUser *user; + char *msg; + int userno; + int number; +{ + if (!user->clitype && number && number != MSG_MESSAGE) + return; + + if (!userno || !list_belong(user->ignore, userno)) + { + fd_set wset, *wptr; + int sock; + static char sendbuf[256]; + + sock = user->sock; + FD_ZERO(wptr = &wset); + FD_SET(sock, wptr); + + if (user->clitype) + { + if (strlen(msg)) + sprintf(sendbuf, "%3d %s", number, msg); + else + sprintf(sendbuf, "%3d", number); + do_send(sock, wptr, sendbuf); + } + else + do_send(sock, wptr, msg); + } +} + +#if 0 +static void +send_to_sock(sock, msg) /* Thor: unused */ + int sock; + char *msg; +{ + fd_set wset, *wptr; + + FD_ZERO(wptr = &wset); + FD_SET(sock, wptr); + do_send(sock, wptr, msg); +} +#endif + +/* ----------------------------------------------------- */ + +static void +room_changed(room) + ChatRoom *room; +{ + if (!room) + return; + + sprintf(chatbuf, "= %s %d %d %s", room->name, room->occupants, room->rflag, room->topic); + send_to_room(ROOM_ALL, chatbuf, 0, MSG_ROOMNOTIFY); +} + +static void +user_changed(cu) + ChatUser *cu; +{ + if (!cu) + return; + + sprintf(chatbuf, "= %s %s %s %s", cu->userid, cu->chatid, cu->room->name, cu->lasthost); + if (ROOMOP(cu)) + strcat(chatbuf, " Op"); + send_to_room(cu->room, chatbuf, 0, MSG_USERNOTIFY); +} + +static void +exit_room(user, mode, msg) + ChatUser *user; + int mode; + char *msg; +{ + ChatRoom *room; + + if((room = user->room)) { + user->room = NULL; + user->uflag &= ~PERM_ROOMOP; + + if (--room->occupants > 0) + { + char *chatid; + + chatid = user->chatid; + switch (mode) + { + case EXIT_LOGOUT: + + sprintf(chatbuf, "¡» %s Â÷¶}¤F ...", chatid); + if (msg && *msg) + { + strcat(chatbuf, ": "); + msg[79] = 0; /* Thor:¨¾¤î¤Óªø */ + strncat(chatbuf, msg, 80); + } + break; + + case EXIT_LOSTCONN: + + sprintf(chatbuf, "¡» %s ¦¨¤FÂ_½uªº·ºåÅo", chatid); + break; + + case EXIT_KICK: + + sprintf(chatbuf, "¡» «¢«¢¡I%s ³Q½ð¥X¥h¤F", chatid); + break; + } + if (!CLOAK(user)) /* Thor: ²á¤Ñ«ÇÁô¨³N */ + send_to_room(room, chatbuf, 0, MSG_MESSAGE); + + sprintf(chatbuf, "- %s", user->userid); + send_to_room(room, chatbuf, 0, MSG_USERNOTIFY); + room_changed(room); + + return; + } + + else if (room != &mainroom) + { /* Thor: ¤H¼Æ¬°0®É,¤£¬Omainroom¤~free */ + register ChatRoom *next; + +#ifdef DEBUG + debug_room(); +#endif + + sprintf(chatbuf, "- %s", room->name); + send_to_room(ROOM_ALL, chatbuf, 0, MSG_ROOMNOTIFY); + + room->prev->next = room->next; + if((next = room->next)) + next->prev = room->prev; + list_free(room->invite); + + MYDOG; + free(room); + MYDOG; + +#ifdef DEBUG + debug_room(); +#endif + } + } +} + + +/* ----------------------------------------------------- */ +/* chat commands */ +/* ----------------------------------------------------- */ + +/* ----------------------------------------------------- */ +/* (.ACCT) ¨Ï¥ÎªÌ±b¸¹ (account) subroutines */ +/* ----------------------------------------------------- */ + +static char datemsg[32]; + +char * +Ctime(clock) + time_t *clock; +{ + struct tm *t = localtime(clock); + static char week[] = "¤é¤@¤G¤T¥|¤¤»"; + + sprintf(datemsg, "%d¦~%2d¤ë%2d¤é%3d:%02d:%02d ¬P´Á%.2s", + t->tm_year - 11, t->tm_mon + 1, t->tm_mday, + t->tm_hour, t->tm_min, t->tm_sec, &week[t->tm_wday << 1]); + return (datemsg); +} + +static void +chat_query(cu, msg) + ChatUser *cu; + char *msg; +{ + char str[256]; + int i; + ACCT xuser; + FILE *fp; + + if (acct_load(&xuser, msg) >= 0) + { + sprintf(chatbuf, "%s(%s) ¦@¤W¯¸ %d ¦¸¡A¤å³¹ %d ½g", + xuser.userid, xuser.username, xuser.numlogins, xuser.numposts); + send_to_user(cu, chatbuf, 0, MSG_MESSAGE); + + sprintf(chatbuf, "³Ìªñ(%s)±q(%s)¤W¯¸", Ctime(&xuser.lastlogin), + (xuser.lasthost[0] ? xuser.lasthost : "¥~¤ÓªÅ")); + send_to_user(cu, chatbuf, 0, MSG_MESSAGE); + + usr_fpath(chatbuf, xuser.userid, "plans"); + fp = fopen(chatbuf, "rt"); + i = 0; + while (fp && fgets(str, 256, fp)) + { + if (!strlen(str)) + continue; + + str[strlen(str) - 1] = 0; + send_to_user(cu, str, 0, MSG_MESSAGE); + if (++i >= MAX_QUERYLINES) + break; + } + fclose(fp); + } + else + { + sprintf(chatbuf, msg_no_such_id, msg); + send_to_user(cu, chatbuf, 0, MSG_MESSAGE); + } +} + +static void +chat_clear(cu, msg) + ChatUser *cu; + char *msg; +{ + if (cu->clitype) + send_to_user(cu, "", 0, MSG_CLRSCR); + else + send_to_user(cu, "/c", 0, MSG_MESSAGE); +} + +static void +chat_date(cu, msg) + ChatUser *cu; + char *msg; +{ + time_t thetime; + + time(&thetime); + sprintf(chatbuf, "¡» ¼Ð·Ç®É¶¡: %s", Ctime(&thetime)); + send_to_user(cu, chatbuf, 0, MSG_MESSAGE); +} + + +static void +chat_topic(cu, msg) + ChatUser *cu; + char *msg; +{ + ChatRoom *room; + char *topic; + + if (!ROOMOP(cu) && !OPENTOPIC(cu->room)) + { + send_to_user(cu, msg_not_op, 0, MSG_MESSAGE); + return; + } + + if (*msg == '\0') + { + send_to_user(cu, "¡° ½Ð«ü©w¸ÜÃD", 0, MSG_MESSAGE); + return; + } + + room = cu->room; + topic = room->topic; /* Thor: room ¦³¥i¯à NULL¶Ü?? */ + strncpy(topic, msg, 47); + topic[47] = '\0'; + + if (cu->clitype) + send_to_room(room, topic, 0, MSG_TOPIC); + else + { + sprintf(chatbuf, "/t%s", topic); + send_to_room(room, chatbuf, 0, 0); + } + + room_changed(room); + + sprintf(chatbuf, "¡» %s ±N¸ÜÃD§ï¬° [1;32m%s[m", cu->chatid, topic); + if (!CLOAK(cu)) /* Thor: ²á¤Ñ«ÇÁô¨³N */ + send_to_room(room, chatbuf, 0, MSG_MESSAGE); +} + + +static void +chat_version(cu, msg) + ChatUser *cu; + char *msg; +{ + sprintf(chatbuf, "%d %d", XCHAT_VERSION_MAJOR, XCHAT_VERSION_MINOR); + send_to_user(cu, chatbuf, 0, MSG_VERSION); +} + +static void +chat_nick(cu, msg) + ChatUser *cu; + char *msg; +{ + char *chatid, *str; + ChatUser *xuser; + + chatid = nextword(&msg); + chatid[8] = '\0'; + if (!valid_chatid(chatid)) + { + send_to_user(cu, "¡° ³oÓ²á¤Ñ¥N¸¹¬O¤£¥¿½Tªº", 0, MSG_MESSAGE); + return; + } + + xuser = cuser_by_chatid(chatid); + if (xuser != NULL && xuser != cu) + { + send_to_user(cu, "¡° ¤w¸g¦³¤H±¶¨¬¥ýµnÅo", 0, MSG_MESSAGE); + return; + } + + str = cu->chatid; + + sprintf(chatbuf, "¡° %s ±N²á¤Ñ¥N¸¹§ï¬° [1;33m%s[m", str, chatid); + if (!CLOAK(cu)) /* Thor: ²á¤Ñ«ÇÁô¨³N */ + send_to_room(cu->room, chatbuf, cu->userno, MSG_MESSAGE); + + strcpy(str, chatid); + + user_changed(cu); + + if (cu->clitype) + send_to_user(cu, chatid, 0, MSG_NICK); + else + { + sprintf(chatbuf, "/n%s", chatid); + send_to_user(cu, chatbuf, 0, 0); + } +} + +static void +chat_list_rooms(cuser, msg) + ChatUser *cuser; + char *msg; +{ + ChatRoom *cr, *room; + + if (RESTRICTED(cuser)) + { + send_to_user(cuser, "¡° ±z¨S¦³Åv¦C¥X²{¦³ªº²á¤Ñ«Ç", 0, MSG_MESSAGE); + return; + } + + if (common_client_command) + send_to_user(cuser, "", 0, MSG_ROOMLISTSTART); + else + send_to_user(cuser, "[7m ½Í¤Ñ«Ç¦WºÙ ¢x¤H¼Æ¢x¸ÜÃD [m", 0, MSG_MESSAGE); + + room = cuser->room; + cr = &mainroom; + do + { + MYDOG; + + + if (!SECRET(cr) || CHATSYSOP(cuser) || (cr == room && ROOMOP(cuser))) + { + if (common_client_command) + { + sprintf(chatbuf, "%s %d %d %s", cr->name, cr->occupants, cr->rflag, cr->topic); + send_to_user(cuser, chatbuf, 0, MSG_ROOMLIST); + } + else + { + sprintf(chatbuf, " %-12s¢x%4d¢x%s", cr->name, cr->occupants, cr->topic); + if (LOCKED(cr)) + strcat(chatbuf, " [Âê¦í]"); + if (SECRET(cr)) + strcat(chatbuf, " [¯µ±K]"); + if (OPENTOPIC(cr)) + strcat(chatbuf, " [¸ÜÃD]"); + send_to_user(cuser, chatbuf, 0, MSG_MESSAGE); + } + + } + } while((cr = cr->next)); + + if (common_client_command) + send_to_user(cuser, "", 0, MSG_ROOMLISTEND); +} + + +static void +chat_do_user_list(cu, msg, theroom) + ChatUser *cu; + char *msg; + ChatRoom *theroom; +{ + ChatRoom *myroom, *room; + ChatUser *user; + + int start, stop, curr = 0; + start = atoi(nextword(&msg)); + stop = atoi(nextword(&msg)); + + myroom = cu->room; + +#ifdef DEBUG + logit(cu->chatid, "do user list"); +#endif + + if (common_client_command) + send_to_user(cu, "", 0, MSG_USERLISTSTART); + else + send_to_user(cu, "[7m ²á¤Ñ¥N¸¹¢x¨Ï¥ÎªÌ¥N¸¹ ¢x²á¤Ñ«Ç [m", 0, MSG_MESSAGE); + + for (user = mainuser; user; user = user->unext) + { + MYDOG; + + + room = user->room; + if ((theroom != ROOM_ALL) && (theroom != room)) + continue; + + if (myroom != room) + { + if (RESTRICTED(cu) || + (room && SECRET(room) && !CHATSYSOP(cu))) + continue; + } + + if (CLOAK(user)) /* Thor: Áô¨³N */ + continue; + + + curr++; + if (start && curr < start) + continue; + else if (stop && (curr > stop)) + break; + + if (common_client_command) + { + if (!room) + continue; /* Xshadow: ÁÙ¨S¶i¤J¥ô¦ó©Ð¶¡ªº´N¤£¦C¥X */ + + sprintf(chatbuf, "%s %s %s %s", user->chatid, user->userid, room->name, user->lasthost); + if (ROOMOP(user)) + strcat(chatbuf, " Op"); + } + else + { + sprintf(chatbuf, " %-8s¢x%-12s¢x%s", user->chatid, user->userid, room ? room->name : "[¦bªù¤f±r«Þ]"); + if (ROOMOP(user)) + strcat(chatbuf, " [Op]"); + } + +#ifdef DEBUG + logit("list_U", chatbuf); +#endif + + send_to_user(cu, chatbuf, 0, common_client_command ? MSG_USERLIST : MSG_MESSAGE); + } + if (common_client_command) + send_to_user(cu, "", 0, MSG_USERLISTEND); +} + +static void +chat_list_by_room(cu, msg) + ChatUser *cu; + char *msg; +{ + ChatRoom *whichroom; + char *roomstr; + + roomstr = nextword(&msg); + if (*roomstr == '\0') + whichroom = cu->room; + else + { + if ((whichroom = croom_by_roomid(roomstr)) == NULL) + { + sprintf(chatbuf, "¡° ¨S¦³ [%s] ³oÓ²á¤Ñ«Ç", roomstr); + send_to_user(cu, chatbuf, 0, MSG_MESSAGE); + return; + } + + if (whichroom != cu->room && SECRET(whichroom) && !CHATSYSOP(cu)) + { /* Thor: n¤£n´ú¦P¤@roomÁöSECRET¦ý¥i¥H¦C? + * Xshadow: §Ú§ï¦¨¦P¤@ room ´N¥i¥H¦C */ + send_to_user(cu, "¡° µLªk¦C¥X¦b¯µ±K²á¤Ñ«Çªº¨Ï¥ÎªÌ", 0, MSG_MESSAGE); + return; + } + } + chat_do_user_list(cu, msg, whichroom); +} + + +static void +chat_list_users(cu, msg) + ChatUser *cu; + char *msg; +{ + chat_do_user_list(cu, msg, ROOM_ALL); +} + +static void +chat_chatroom(cu, msg) + ChatUser *cu; + char *msg; +{ + if (common_client_command) + send_to_user(cu, "§å½ð½ð¯ùÃÀÀ] 4 21", 0, MSG_CHATROOM); +} + +static void +chat_map_chatids(cu, whichroom) + ChatUser *cu; /* Thor: ÁÙ¨S¦³§@¤£¦P¶¡ªº */ + ChatRoom *whichroom; +{ + int c; + ChatRoom *myroom, *room; + ChatUser *user; + + /* myroom = cu->room; */ + myroom = whichroom; + send_to_user(cu, + "[7m ²á¤Ñ¥N¸¹ ¨Ï¥ÎªÌ¥N¸¹ ¢x ²á¤Ñ¥N¸¹ ¨Ï¥ÎªÌ¥N¸¹ ¢x ²á¤Ñ¥N¸¹ ¨Ï¥ÎªÌ¥N¸¹ [m", 0, MSG_MESSAGE); + + c = 0; + + for (user = mainuser; user; user = user->unext) + { + MYDOG; + + room = user->room; + MYDOG; + if (whichroom != ROOM_ALL && whichroom != room) + continue; + MYDOG; + if (myroom != room) + { + if (RESTRICTED(cu) || /* Thor: n¥ýcheck room ¬O¤£¬OªÅªº */ + (room && SECRET(room) && !CHATSYSOP(cu))) + continue; + } + MYDOG; + if (CLOAK(user)) /* Thor:Áô¨³N */ + continue; + sprintf(chatbuf + (c * 24), " %-8s%c%-12s%s", + user->chatid, ROOMOP(user) ? '*' : ' ', + user->userid, (c < 2 ? "¢x" : " ")); + MYDOG; + if (++c == 3) + { + send_to_user(cu, chatbuf, 0, MSG_MESSAGE); + c = 0; + } + MYDOG; + } + if (c > 0) + send_to_user(cu, chatbuf, 0, MSG_MESSAGE); +} + + +static void +chat_map_chatids_thisroom(cu, msg) + ChatUser *cu; + char *msg; +{ + chat_map_chatids(cu, cu->room); +} + + +static void +chat_setroom(cu, msg) + ChatUser *cu; + char *msg; +{ + char *modestr; + ChatRoom *room; + char *chatid; + int sign; + int flag; + char *fstr = NULL; + + if (!ROOMOP(cu)) + { + send_to_user(cu, msg_not_op, 0, MSG_MESSAGE); + return; + } + + modestr = nextword(&msg); + sign = 1; + if (*modestr == '+') + modestr++; + else if (*modestr == '-') + { + modestr++; + sign = 0; + } + if (*modestr == '\0') + { + send_to_user(cu, + "¡° ½Ð«ü©wª¬ºA: {[+(³]©w)][-(¨ú®ø)]}{[l(Âê¦í)][s(¯µ±K)][t(¶}©ñ¸ÜÃD)}", 0, MSG_MESSAGE); + return; + } + + room = cu->room; + chatid = cu->chatid; + + while (*modestr) + { + flag = 0; + switch (*modestr) + { + case 'l': + case 'L': + flag = ROOM_LOCKED; + fstr = "Âê¦í"; + break; + + case 's': + case 'S': + flag = ROOM_SECRET; + fstr = "¯µ±K"; + break; + + case 't': + case 'T': + flag = ROOM_OPENTOPIC; + fstr = "¶}©ñ¸ÜÃD"; + break; + case 'h': + case 'H': + flag = ROOM_OPENTOPIC; + fstr = "Á|¤âµo¨¥"; + break; + + default: + sprintf(chatbuf, "¡° ª¬ºA¿ù»~¡G[%c]", *modestr); + send_to_user(cu, chatbuf, 0, MSG_MESSAGE); + } + + /* Thor: check room ¬O¤£¬OªÅªº, À³¸Ó¤£¬OªÅªº */ + if (flag && (room->rflag & flag) != sign * flag) + { + room->rflag ^= flag; + sprintf(chatbuf, "¡° ¥»²á¤Ñ«Ç³Q %s %s [%s] ª¬ºA", + chatid, sign ? "³]©w¬°" : "¨ú®ø", fstr); + if (!CLOAK(cu)) /* Thor: ²á¤Ñ«ÇÁô¨³N */ + send_to_room(room, chatbuf, 0, MSG_MESSAGE); + } + modestr++; + } + room_changed(room); +} + +static char *chat_msg[] = +{ + "[//]help", "MUD-like ªÀ¥æ°Êµü", + "[/h]elp op", "½Í¤Ñ«ÇºÞ²zû±M¥Î«ü¥O", + "[/a]ct <msg>", "°µ¤@Ӱʧ@", + "[/b]ye [msg]", "¹D§O", + "[/c]lear [/d]ate", "²M°£¿Ã¹õ ¥Ø«e®É¶¡", + /* "[/d]ate", "¥Ø«e®É¶¡", *//* Thor: «ü¥O¤Ó¦h */ + +#if 0 + "[/f]ire <user> <msg>", "µo°e¼ö°T", /* Thor.0727: ©M flag ½Äkey */ +#endif + + "[/i]gnore [user]", "©¿²¤¨Ï¥ÎªÌ", + "[/j]oin <room>", "«Ø¥ß©Î¥[¤J½Í¤Ñ«Ç", + "[/l]ist [start [stop]]", "¦C¥X½Í¤Ñ«Ç¨Ï¥ÎªÌ", + "[/m]sg <id|user> <msg>", "¸ò <id> »¡®¨®¨¸Ü", + "[/n]ick <id>", "±N½Í¤Ñ¥N¸¹´«¦¨ <id>", + "[/p]ager", "¤Á´«©I¥s¾¹", + "[/q]uery <user>", "¬d¸ßºô¤Í", + "[/r]oom", "¦C¥X¤@¯ë½Í¤Ñ«Ç", + "[/t]ape", "¶}Ãö¿ýµ¾÷", + "[/u]nignore <user>", "¨ú®ø©¿²¤", + +#if 0 + "[/u]sers", "¦C¥X¯¸¤W¨Ï¥ÎªÌ", +#endif + + "[/w]ho", "¦C¥X¥»½Í¤Ñ«Ç¨Ï¥ÎªÌ", + "[/w]hoin <room>", "¦C¥X½Í¤Ñ«Ç<room> ªº¨Ï¥ÎªÌ", + NULL +}; + + +static char *room_msg[] = +{ + "[/f]lag [+-][lsth]", "³]©wÂê©w¡B¯µ±K¡B¶}©ñ¸ÜÃD¡BÁ|¤âµo¨¥", + "[/i]nvite <id>", "ÁܽР<id> ¥[¤J½Í¤Ñ«Ç", + "[/kick] <id>", "±N <id> ½ð¥X½Í¤Ñ«Ç", + "[/o]p <id>", "±N Op ªºÅv¤OÂಾµ¹ <id>", + "[/topic] <text>", "´«Ó¸ÜÃD", + "[/w]all", "¼s¼½ (¯¸ªø±M¥Î)", + NULL +}; + + +static void +chat_help(cu, msg) + ChatUser *cu; + char *msg; +{ + char **table, *str; + + if (str_equal(nextword(&msg), "op")) + { + send_to_user(cu, "½Í¤Ñ«ÇºÞ²zû±M¥Î«ü¥O", 0, MSG_MESSAGE); + table = room_msg; + } + else + { + table = chat_msg; + } + + while((str = *table++)) { + sprintf(chatbuf, " %-20s- %s", str, *table++); + send_to_user(cu, chatbuf, 0, MSG_MESSAGE); + } +} + + +static void +chat_private(cu, msg) + ChatUser *cu; + char *msg; +{ + char *recipient; + ChatUser *xuser; + int userno; + + userno = 0; + recipient = nextword(&msg); + xuser = (ChatUser *) fuzzy_cuser_by_chatid(recipient); + if (xuser == NULL) + { /* Thor.0724: ¥Î userid¤]¥i¶Ç®¨®¨¸Ü */ + xuser = cuser_by_userid(recipient); + } + if (xuser == NULL) + { + sprintf(chatbuf, msg_no_such_id, recipient); + } + else if (xuser == FUZZY_USER) + { /* ambiguous */ + strcpy(chatbuf, "¡° ½Ð«ü©ú²á¤Ñ¥N¸¹"); + } + else if (*msg) + { + userno = cu->userno; + sprintf(chatbuf, "[1m*%s*[m ", cu->chatid); + msg[79] = 0; /* Thor:¨¾¤î¤Óªø */ + strncat(chatbuf, msg, 80); + send_to_user(xuser, chatbuf, userno, MSG_MESSAGE); + + if (xuser->clitype) + { /* Xshadow: ¦pªG¹ï¤è¬O¥Î client ¤W¨Óªº */ + sprintf(chatbuf, "%s %s ", cu->userid, cu->chatid); + msg[79] = 0; + strncat(chatbuf, msg, 80); + send_to_user(xuser, chatbuf, userno, MSG_PRIVMSG); + } + if (cu->clitype) + { + sprintf(chatbuf, "%s %s ", xuser->userid, xuser->chatid); + msg[79] = 0; + strncat(chatbuf, msg, 80); + send_to_user(cu, chatbuf, 0, MSG_MYPRIVMSG); + } + + sprintf(chatbuf, "%s> ", xuser->chatid); + strncat(chatbuf, msg, 80); + } + else + { + sprintf(chatbuf, "¡° ±z·Q¹ï %s »¡¤°»ò¸Ü©O¡H", xuser->chatid); + } + send_to_user(cu, chatbuf, userno, MSG_MESSAGE); /* Thor: userno n§ï¦¨ 0 + * ¶Ü? */ +} + + +static void +chat_cloak(cu, msg) + ChatUser *cu; + char *msg; +{ + if (CHATSYSOP(cu)) + { + cu->uflag ^= PERM_CLOAK; + sprintf(chatbuf, "¡» %s", CLOAK(cu) ? MSG_CLOAKED : MSG_UNCLOAK); + send_to_user(cu, chatbuf, 0, MSG_MESSAGE); + } +} + + + +/* ----------------------------------------------------- */ + + +static void +arrive_room(cuser, room) + ChatUser *cuser; + ChatRoom *room; +{ + char *rname; + + /* Xshadow: ¤£¥²°eµ¹¦Û¤v, ¤Ï¥¿´«©Ð¶¡´N·|«·s build user list */ + sprintf(chatbuf, "+ %s %s %s %s", cuser->userid, cuser->chatid, room->name, cuser->lasthost); + if (ROOMOP(cuser)) + strcat(chatbuf, " Op"); + send_to_room(room, chatbuf, 0, MSG_USERNOTIFY); + + cuser->room = room; + room->occupants++; + rname = room->name; + + room_changed(room); + + if (cuser->clitype) + { + send_to_user(cuser, rname, 0, MSG_ROOM); + send_to_user(cuser, room->topic, 0, MSG_TOPIC); + } + else + { + sprintf(chatbuf, "/r%s", rname); + send_to_user(cuser, chatbuf, 0, 0); + sprintf(chatbuf, "/t%s", room->topic); + send_to_user(cuser, chatbuf, 0, 0); + } + + sprintf(chatbuf, "¡° [32;1m%s[m ¶i¤J [33;1m[%s][m ¥]´[", + cuser->chatid, rname); + if (!CLOAK(cuser)) /* Thor: ²á¤Ñ«ÇÁô¨³N */ + send_to_room(room, chatbuf, cuser->userno, MSG_MESSAGE); +} + + +static int +enter_room(cuser, rname, msg) + ChatUser *cuser; + char *rname; + char *msg; +{ + ChatRoom *room; + int create; + + create = 0; + room = croom_by_roomid(rname); + if (room == NULL) + { + /* new room */ + +#ifdef MONITOR + logit(cuser->userid, "create new room"); +#endif + + MYDOG; + + room = (ChatRoom *) malloc(sizeof(ChatRoom)); + MYDOG; + if (room == NULL) + { + send_to_user(cuser, "¡° µLªk¦A·sÅP¥]´[¤F", 0, MSG_MESSAGE); + return 0; + } + + memset(room, 0, sizeof(ChatRoom)); + memcpy(room->name, rname, IDLEN - 1); + strcpy(room->topic, "³o¬O¤@Ó·s¤Ñ¦a"); + + sprintf(chatbuf, "+ %s 1 0 %s", room->name, room->topic); + send_to_room(ROOM_ALL, chatbuf, 0, MSG_ROOMNOTIFY); + + if (mainroom.next != NULL) + mainroom.next->prev = room; + room->next = mainroom.next; + mainroom.next = room; + room->prev = &mainroom; + + create = 1; + } + else + { + if (cuser->room == room) + { + sprintf(chatbuf, "¡° ±z¥»¨Ó´N¦b [%s] ²á¤Ñ«ÇÅo :)", rname); + send_to_user(cuser, chatbuf, 0, MSG_MESSAGE); + return 0; + } + + if (!CHATSYSOP(cuser) && LOCKED(room) && !list_belong(room->invite, cuser->userno)) + { + send_to_user(cuser, "¡° ¤º¦³´c¤ü¡A«D½Ð²ö¤J", 0, MSG_MESSAGE); + return 0; + } + } + + exit_room(cuser, EXIT_LOGOUT, msg); + arrive_room(cuser, room); + + if (create) + cuser->uflag |= PERM_ROOMOP; + + return 0; +} + + +static void +logout_user(cuser) + ChatUser *cuser; +{ + int sock; + ChatUser *xuser, *prev; + +#ifdef DEBUG + logit("before", "logout"); + debug_user(); +#endif + + sock = cuser->sock; + shutdown(sock, 2); + close(sock); + + MYDOG; + + FD_CLR(sock, &mainfds); + +#if 0 /* Thor: ¤]³\¤£®t³o¤@Ó */ + if (sock >= maxfds) + maxfds = sock - 1; +#endif + + list_free(cuser->ignore); + +#ifdef DEBUG + debug_user(); +#endif + + xuser = mainuser; + if (xuser == cuser) + { + mainuser = cuser->unext; + } + else + { + do + { + prev = xuser; + xuser = xuser->unext; + if (xuser == cuser) + { + prev->unext = cuser->unext; + break; + } + } while (xuser); + } + + MYDOG; + +#ifdef DEBUG + sprintf(chatbuf, "%p", cuser); + logit("free cuser", chatbuf); +#endif + + free(cuser); + +#ifdef DEBUG + logit("after", "logout"); + debug_user(); +#endif + +#if 0 + next = cuser->next; + prev = cuser->prev; + prev->next = next; + if (next) + next->prev = prev; + + if (cuser) + free(cuser); + MYDOG; + +#endif + + totaluser--; +} + + +static void +print_user_counts(cuser) + ChatUser *cuser; +{ + ChatRoom *room; + int num, userc, suserc, roomc, number; + + userc = suserc = roomc = 0; + + room = &mainroom; + do + { + MYDOG; + + num = room->occupants; + if (SECRET(room)) + { + suserc += num; + if (CHATSYSOP(cuser)) + roomc++; + } + else + { + userc += num; + roomc++; + } + } while((room = room->next)); + + number = (cuser->clitype) ? MSG_MOTD : MSG_MESSAGE; + + sprintf(chatbuf, + "¡ó Åwªï¥úÁ{¡i§å½ð½ð¯ùÃÀÀ]¡j¡A¥Ø«e¶}¤F [1;31m%d[m ¶¡¥]´[", roomc); + send_to_user(cuser, chatbuf, 0, number); + + sprintf(chatbuf, "¡ó ¦@¦³ [1;36m%d[m ¤H¨ÓÂ\\Àsªù°}", userc); + if (suserc) + sprintf(chatbuf + strlen(chatbuf), " [%d ¤H¦b¯µ±K²á¤Ñ«Ç]", suserc); + send_to_user(cuser, chatbuf, 0, number); +} + + +static int +login_user(cu, msg) + ChatUser *cu; + char *msg; +{ + int utent; + + char *level; + char *userid; + char *chatid; + struct sockaddr_in from; + int fromlen; + struct hostent *hp; + + + ACCT acct; + char buf[20]; + + /* + * Thor.0819: SECURED_CHATROOM : /! userid chatid passwd , userno + * el ¦bcheck§¹passwd«á¨ú±o + */ + /* Xshadow.0915: common client support : /-! userid chatid password */ + + /* ¶Ç°Ñ¼Æ¡Guserlevel, userid, chatid */ + + /* client/server ª©¥»¨Ì¾Ú userid §ì .PASSWDS §PÂ_ userlevel */ + + userid = nextword(&msg); + chatid = nextword(&msg); + + +#ifdef DEBUG + logit("ENTER", userid); +#endif + /* Thor.0730: parse space before passwd */ + level = msg; + + /* Thor.0813: ¸õ¹L¤@ªÅ®æ§Y¥i, ¦]¬°¤Ï¥¿¦pªGchatid¦³ªÅ®æ, ±K½X¤]¤£¹ï */ + /* ´Nºâ±K½X¹ï, ¤]¤£·|«ç»ò¼Ë:p */ + /* ¥i¬O¦pªG±K½X²Ä¤@Ó¦r¬OªÅ®æ, ¨º¸õ¤Ó¦hªÅ®æ·|¶i¤£¨Ó... */ + if (*level == ' ') + level++; + + /* Thor.0729: load acct */ + if (!*userid || (acct_load(&acct, userid) < 0)) + { + +#ifdef DEBUG + logit("noexist", chatid); +#endif + + if (cu->clitype) + send_to_user(cu, "¿ù»~ªº¨Ï¥ÎªÌ¥N¸¹", 0, ERR_LOGIN_NOSUCHUSER); + else + send_to_user(cu, CHAT_LOGIN_INVALID, 0, 0); + + return -1; + } + else if(strncmp(level, acct.passwd, PASSLEN) && + !chkpasswd(acct.passwd, level)) + { + +#ifdef DEBUG + logit("fake", chatid); +#endif + + if (cu->clitype) + send_to_user(cu, "±K½X¿ù»~", 0, ERR_LOGIN_PASSERROR); + else + send_to_user(cu, CHAT_LOGIN_INVALID, 0, 0); + return -1; + } + else + { + /* Thor.0729: if ok, read level. */ + sprintf(buf, "%d", acct.userlevel); + level = buf; + /* Thor.0819: read userno for client/server bbs */ + utent = searchuser(acct.userid); + } + + /* Thor.0819: for client/server bbs */ +/* + for (xuser = mainuser; xuser; xuser = xuser->unext) + { + MYDOG; + + if (xuser->userno == utent) + { + + #ifdef DEBUG + logit("enter", "bogus"); + #endif + if (cu->clitype) + send_to_user(cu, "½Ð¤Å¬£»º¤À¨¶i¤J²á¤Ñ«Ç !!", 0, ERR_LOGIN_USERONLINE); + else + send_to_user(cu, CHAT_LOGIN_BOGUS, 0, 0); + return -1; + } + } +*/ + if (!valid_chatid(chatid)) + { + +#ifdef DEBUG + logit("enter", chatid); +#endif + + if (cu->clitype) + send_to_user(cu, "¤£¦Xªkªº²á¤Ñ«Ç¥N¸¹ !!", 0, ERR_LOGIN_NICKERROR); + else + send_to_user(cu, CHAT_LOGIN_INVALID, 0, 0); + return 0; + } + +#ifdef DEBUG + debug_user(); +#endif + + if (cuser_by_chatid(chatid) != NULL) + { + /* chatid in use */ + +#ifdef DEBUG + logit("enter", "duplicate"); +#endif + + if (cu->clitype) + send_to_user(cu, "³oÓ¥N¸¹¤w¸g¦³¤H¨Ï¥Î", 0, ERR_LOGIN_NICKINUSE); + else + send_to_user(cu, CHAT_LOGIN_EXISTS, 0, 0); + return 0; + } + + cu->userno = utent; + cu->uflag = atoi(level) & ~(PERM_ROOMOP | PERM_CLOAK | PERM_HANDUP | PERM_SAY); + /* Thor: ¶i¨Ó¥ý²MªÅROOMOP(¦PPERM_CHAT), CLOAK */ + strcpy(cu->userid, userid); + memcpy(cu->chatid, chatid, 8); + cu->chatid[8] = '\0'; + + /* Xshadow: ¨ú±o client ªº¨Ó·½ */ + fromlen = sizeof(from); + if (!getpeername(cu->sock, (struct sockaddr *) & from, &fromlen)) + { + if ((hp = gethostbyaddr((char *) &from.sin_addr, sizeof(struct in_addr), from.sin_family))) + { + strcpy(cu->lasthost, hp->h_name); + } + else + strcpy(cu->lasthost, (char *) inet_ntoa(from.sin_addr)); + + } + else + { + strcpy(cu->lasthost, "[¥~¤ÓªÅ]"); + } + + if (cu->clitype) + send_to_user(cu, "¶¶§Q", 0, MSG_LOGINOK); + else + send_to_user(cu, CHAT_LOGIN_OK, 0, 0); + + arrive_room(cu, &mainroom); + + send_to_user(cu, "", 0, MSG_MOTDSTART); + print_user_counts(cu); + send_to_user(cu, "", 0, MSG_MOTDEND); + +#ifdef DEBUG + logit("enter", "OK"); +#endif + + return 0; +} + + +static void +chat_act(cu, msg) + ChatUser *cu; + char *msg; +{ + if (*msg && (!RHANDUP(cu->room) || SAY(cu) || ROOMOP(cu))) + { + sprintf(chatbuf, "%s [36m%s[m", cu->chatid, msg); + send_to_room(cu->room, chatbuf, cu->userno, MSG_MESSAGE); + } +} + + +static void +chat_ignore(cu, msg) + ChatUser *cu; + char *msg; +{ + + if (RESTRICTED(cu)) + { + strcpy(chatbuf, "¡° ±z¨S¦³ ignore §O¤HªºÅv§Q"); + } + else + { + char *ignoree; + + ignoree = nextword(&msg); + if (*ignoree) + { + ChatUser *xuser; + + xuser = cuser_by_userid(ignoree); + + if (xuser == NULL) + { + + sprintf(chatbuf, msg_no_such_id, ignoree); + +#if 0 + sprintf(chatbuf, "¡» ½Í¤Ñ«Ç²{¦b¨S¦³ [%s] ³o¸¹¤Hª«", ignoree); +#endif + } + else if (xuser == cu || CHATSYSOP(xuser) || + (ROOMOP(xuser) && (xuser->room == cu->room))) + { + sprintf(chatbuf, "¡» ¤£¥i¥H ignore [%s]", ignoree); + } + else + { + + if (list_belong(cu->ignore, xuser->userno)) + { + sprintf(chatbuf, "¡° %s ¤w¸g³Qáµ²¤F", xuser->chatid); + } + else + { + list_add(&(cu->ignore), xuser); + sprintf(chatbuf, "¡» ±N [%s] ¥´¤J§N®c¤F :p", xuser->chatid); + } + } + } + else + { + UserList *list; + + if((list = cu->ignore)) + { + int len; + char buf[16]; + + send_to_user(cu, "¡» ³o¨Ç¤H³Q¥´¤J§N®c¤F¡G", 0, MSG_MESSAGE); + len = 0; + do + { + sprintf(buf, "%-13s", list->userid); + strcpy(chatbuf + len, buf); + len += 13; + if (len >= 78) + { + send_to_user(cu, chatbuf, 0, MSG_MESSAGE); + len = 0; + } + } while((list = list->next)); + + if (len == 0) + return; + } + else + { + strcpy(chatbuf, "¡» ±z¥Ø«e¨Ã¨S¦³ ignore ¥ô¦ó¤H"); + } + } + } + + send_to_user(cu, chatbuf, 0, MSG_MESSAGE); +} + + +static void +chat_unignore(cu, msg) + ChatUser *cu; + char *msg; +{ + char *ignoree; + + ignoree = nextword(&msg); + + if (*ignoree) + { + sprintf(chatbuf, (list_delete(&(cu->ignore), ignoree)) ? + "¡» [%s] ¤£¦A³Q§A§N¸¨¤F" : + "¡» ±z¨Ã¥¼ ignore [%s] ³o¸¹¤Hª«", ignoree); + } + else + { + strcpy(chatbuf, "¡» ½Ð«ü©ú user ID"); + } + send_to_user(cu, chatbuf, 0, MSG_MESSAGE); +} + + +static void +chat_join(cu, msg) + ChatUser *cu; + char *msg; +{ + if (RESTRICTED(cu)) + { + send_to_user(cu, "¡° ±z¨S¦³¥[¤J¨ä¥L²á¤Ñ«ÇªºÅv", 0, MSG_MESSAGE); + } + else + { + char *roomid = nextword(&msg); + + if (*roomid) + enter_room(cu, roomid, msg); + else + send_to_user(cu, "¡° ½Ð«ü©w²á¤Ñ«Çªº¦W¦r", 0, MSG_MESSAGE); + } +} + + +static void +chat_kick(cu, msg) + ChatUser *cu; + char *msg; +{ + char *twit; + ChatUser *xuser; + ChatRoom *room; + + if (!ROOMOP(cu)) + { + send_to_user(cu, msg_not_op, 0, MSG_MESSAGE); + return; + } + + twit = nextword(&msg); + xuser = cuser_by_chatid(twit); + + if (xuser == NULL) + { + sprintf(chatbuf, msg_no_such_id, twit); + send_to_user(cu, chatbuf, 0, MSG_MESSAGE); + return; + } + + room = cu->room; + if (room != xuser->room || CLOAK(xuser)) + { /* Thor: ²á¤Ñ«ÇÁô¨³N */ + sprintf(chatbuf, msg_not_here, twit); + send_to_user(cu, chatbuf, 0, MSG_MESSAGE); + return; + } + + if (CHATSYSOP(xuser)) + { /* Thor: ½ð¤£¨« CHATSYSOP */ + sprintf(chatbuf, "¡» ¤£¥i¥H kick [%s]", twit); + send_to_user(cu, chatbuf, 0, MSG_MESSAGE); + return; + } + + exit_room(xuser, EXIT_KICK, (char *) NULL); + + if (room == &mainroom) + logout_user(xuser); + else + enter_room(xuser, MAIN_NAME, (char *) NULL); +} + + +static void +chat_makeop(cu, msg) + ChatUser *cu; + char *msg; +{ + char *newop; + ChatUser *xuser; + ChatRoom *room; + + if (!ROOMOP(cu)) + { + send_to_user(cu, msg_not_op, 0, MSG_MESSAGE); + return; + } + + newop = nextword(&msg); + xuser = cuser_by_chatid(newop); + + if (xuser == NULL) + { + sprintf(chatbuf, msg_no_such_id, newop); + send_to_user(cu, chatbuf, 0, MSG_MESSAGE); + return; + } + + if (cu == xuser) + { + sprintf(chatbuf, "¡° ±z¦´N¤w¸g¬O Op ¤F°Ú"); + send_to_user(cu, chatbuf, 0, MSG_MESSAGE); + return; + } + + room = cu->room; + + if (room != xuser->room || CLOAK(xuser)) + { /* Thor: ²á¤Ñ«ÇÁô¨³N */ + sprintf(chatbuf, msg_not_here, xuser->chatid); + send_to_user(cu, chatbuf, 0, MSG_MESSAGE); + return; + } + + cu->uflag &= ~PERM_ROOMOP; + xuser->uflag |= PERM_ROOMOP; + + user_changed(cu); + user_changed(xuser); + + sprintf(chatbuf, "¡° %s ±N Op Åv¤OÂಾµ¹ %s", + cu->chatid, xuser->chatid); + if (!CLOAK(cu)) /* Thor: ²á¤Ñ«ÇÁô¨³N */ + send_to_room(room, chatbuf, 0, MSG_MESSAGE, MSG_MESSAGE); +} + + + +static void +chat_invite(cu, msg) + ChatUser *cu; + char *msg; +{ + char *invitee; + ChatUser *xuser; + ChatRoom *room; + UserList **list; + + if (!ROOMOP(cu)) + { + send_to_user(cu, msg_not_op, 0, MSG_MESSAGE); + return; + } + + invitee = nextword(&msg); + xuser = cuser_by_chatid(invitee); + if (xuser == NULL) + { + sprintf(chatbuf, msg_no_such_id, invitee); + send_to_user(cu, chatbuf, 0, MSG_MESSAGE); + return; + } + + room = cu->room; /* Thor: ¬O§_n check room ¬O§_ NULL ? */ + list = &(room->invite); + + if (list_belong(*list, xuser->userno)) + { + sprintf(chatbuf, "¡° %s ¤w¸g±µ¨ü¹LÁܽФF", xuser->chatid); + send_to_user(cu, chatbuf, 0, MSG_MESSAGE); + return; + } + list_add(list, xuser); + + sprintf(chatbuf, "¡° %s Áܽбz¨ì [%s] ²á¤Ñ«Ç", + cu->chatid, room->name); + send_to_user(xuser, chatbuf, 0, MSG_MESSAGE); /* Thor: n¤£n¥i¥H ignore? */ + sprintf(chatbuf, "¡° %s ¦¬¨ì±zªºÁܽФF", xuser->chatid); + send_to_user(cu, chatbuf, 0, MSG_MESSAGE); +} + + +static void +chat_broadcast(cu, msg) + ChatUser *cu; + char *msg; +{ + if (!CHATSYSOP(cu)) + { + send_to_user(cu, "¡° ±z¨S¦³¦b²á¤Ñ«Ç¼s¼½ªºÅv¤O!", 0, MSG_MESSAGE); + return; + } + if (*msg == '\0') + { + send_to_user(cu, "¡° ½Ð«ü©w¼s¼½¤º®e", 0, MSG_MESSAGE); + return; + } + sprintf(chatbuf, "[1m¡° " BBSNAME "½Í¤Ñ«Ç¼s¼½¤¤ [%s].....[m", + cu->chatid); + send_to_room(ROOM_ALL, chatbuf, 0, MSG_MESSAGE); + sprintf(chatbuf, "¡» %s", msg); + send_to_room(ROOM_ALL, chatbuf, 0, MSG_MESSAGE); +} + + +static void +chat_goodbye(cu, msg) + ChatUser *cu; + char *msg; +{ + exit_room(cu, EXIT_LOGOUT, msg); + /* Thor: n¤£n¥[ logout_user(cu) ? */ +} + + +/* --------------------------------------------- */ +/* MUD-like social commands : action */ +/* --------------------------------------------- */ + +struct ChatAction +{ + char *verb; /* °Êµü */ + char *chinese; /* ¤¤¤å½Ķ */ + char *part1_msg; /* ¤¶µü */ + char *part2_msg; /* °Ê§@ */ +}; + + +static ChatAction party_data[] = +{ + {"aluba", "ªü¾|¤Ú", "§â", "¬[¤W¬W¤lªü¾|¤Ú!!"}, + {"aodre", "´º¥õ", "¹ï", "ªº´º¥õ¦³¦p·Ê·Ê¦¿¤ô,³sºø¤£µ´¡K¡K"}, + {"bearhug", "¼ö¾Ö", "¼ö±¡ªº¾Ö©ê", ""}, + {"blade", "¤@¤M", "¤@¤M±Òµ{§â", "°e¤W¦è¤Ñ"}, + {"bless", "¯¬ºÖ", "¯¬ºÖ", "¤ß·Q¨Æ¦¨"}, + {"board", "¥D¾÷ªO", "§â", "§ì¥h¸÷¥D¾÷ªO"}, + {"bokan", "®ð¥\\", "Âù´x·L¦X¡A»W¶Õ«Ýµo¡K¡K¬ðµM¶¡¡A¹q¥ú¥E²{¡A¹ï", "¨Ï¥X¤F¢Ðo--¢Ùan¡I"}, + {"bow", "Áù°`", "²¦°`²¦·qªº¦V", "Áù°`"}, + {"box", "¹õ¤§¤º", "¶}©l½üÂ\\¦¡²¾¦ì¡A¹ï", "§@¨xŦ§ðÀ»"}, + {"boy", "¥©³Áç", "±qI«á®³¥X¤F¥©³Áç¡A§â", "ºV©ü¤F"}, + {"bye", "ÙTÙT", "¦V", "»¡ÙTÙT!!"}, + {"call", "©I³ê", "¤jÁnªº©I³ê,°Ú~~", "°Ú~~~§A¦bþ¸Ì°Ú°Ú°Ú°Ú~~~~"}, + {"caress", "»´¼¾", "»´»´ªº¼¾ºNµÛ", ""}, + {"clap", "¹ª´x", "¦V", "¼ö¯P¹ª´x"}, + {"claw", "§ì§ì", "±q¿ß«}¼Ö¶éɤF°¦¿ß¤ö¡A§â", "§ì±o¦º¥h¬¡¨Ó"}, + {"comfort", "¦w¼¢", "·Å¨¥¦w¼¢", ""}, + {"cong", "®¥³ß", "±qI«á®³¥X¤F©Ô¬¶¡AËé¡IËé¡I®¥³ß", ""}, + {"cpr", "¤f¹ï¤f", "¹ïµÛ", "°µ¤f¹ï¤f¤H¤u©I§l"}, + {"cringe", "¤^¼¦", "¦V", "¨õ°`©}½¥¡A·n§À¤^¼¦"}, + {"cry", "¤jú", "¦V", "Àz°Þ¤jú"}, + {"dance", "¸õ»R", "©Ô¤F", "ªº¤â½¡½¡°_»R" }, + {"destroy", "·´·À", "²½°_¤F¡y·¥¤j·´·À©G¤å¡z¡AÅF¦V", ""}, + {"dogleg", "ª¯»L", "¹ï", "ª¯»L"}, + {"drivel", "¬y¤f¤ô", "¹ïµÛ", "¬y¤f¤ô"}, + {"envy", "¸r¼}", "¦V", "¬yÅS¥X¸r¼}ªº²´¥ú"}, + {"eye", "°e¬îªi", "¹ï", "ÀW°e¬îªi"}, + {"fire", "¾R°Ý", "®³µÛ¤õ¬õªºÅK´Î¨«¦V", ""}, + {"forgive", "ì½Ì", "±µ¨ü¹Dºp¡Aì½Ì¤F", ""}, + {"french", "ªk¦¡§k", "§â¦ÞÀY¦ù¨ì", "³ïÄV¸Ì¡ã¡ã¡ã«z¡I¤@Ó®öº©ªºªk°ê¤ó²`§k"}, + {"giggle", "¶Ì¯º", "¹ïµÛ", "¶Ì¶Ìªº§b¯º"}, + {"glue", "¸É¤ß", "¥Î¤T¬í½¦¡A§â", "ªº¤ßÂH¤F°_¨Ó"}, + {"goodbye", "§i§O", "²\\²´¨L¨Lªº¦V", "§i§O"}, + {"grin", "¦l¯º", "¹ï", "ÅS¥X¨¸´cªº¯º®e"}, + {"growl", "©Hý", "¹ï", "©Hý¤£¤w"}, + {"hand", "´¤¤â", "¸ò", "´¤¤â"}, + {"hide", "¸ú", "¸ú¦b", "I«á"}, + {"hospitl", "°eÂå°|", "§â", "°e¶iÂå°|"}, + {"hug", "¾Ö©ê", "»´»´¦a¾Ö©ê", ""}, + {"hrk", "ª@Às®±", "¨IäF¨§Î¡A¶×»E¤F¤º«l¡A¹ï", "¨Ï¥X¤F¤@°O¢Öo--¢àyu--¢Ùan¡I¡I¡I"}, + {"jab", "ÂW¤H", "·Å¬XªºÂWµÛ", ""}, + {"judo", "¹LªÓºL", "§ì¦í¤F", "ªº¦çÃÌ¡AÂਡK¡K°Ú¡A¬O¤@°O¹LªÓºL¡I"}, + {"kickout", "½ð", "¥Î¤j¸}§â", "½ð¨ì¤s¤U¥h¤F"}, + {"kick", "½ð¤H", "§â", "½ðªº¦º¥h¬¡¨Ó"}, + {"kiss", "»´§k", "»´§k", "ªºÁyÀU"}, + {"laugh", "¼J¯º", "¤jÁn¼J¯º", ""}, + {"levis", "µ¹§Ú", "»¡¡Gµ¹§Ú", "¡I¨ä¾l§K½Í¡I"}, + {"lick", "»Q", "¨g»Q", ""}, + {"lobster", "À£¨î", "¬I®i°f½¼§Î©T©w¡A§â", "À£¨î¦b¦aªO¤W"}, + {"love", "ªí¥Õ", "¹ï", "²`±¡ªºªí¥Õ"}, + {"marry", "¨D±B", "±·µÛ¤E¦Ê¤E¤Q¤E¦·ª´ºÀ¦V", "¨D±B"}, + {"no", "¤£n°Ú", "«÷©R¹ïµÛ", "·nÀY~~~~¤£n°Ú~~~~"}, + {"nod", "ÂIÀY", "¦V", "ÂIÀYºÙ¬O"}, + {"nudge", "³»¨{¤l", "¥Î¤â¨y³»", "ªºªÎ¨{¤l"}, + {"pad", "©çªÓ»H", "»´©ç", "ªºªÓ»H"}, + {"pettish", "¼»¼b", "¸ò", "ÜÝÁnÜÝ®ð¦a¼»¼b"}, + {"pili", "ÅRÆE", "¨Ï¥X §g¤l· ¤Ñ¦a®Ú ¯ëYÄb ¤T¦¡¦X¤@¥´¦V", "~~~~~~"}, + {"pinch", "À¾¤H", "¥Î¤Oªº§â", "À¾ªº¶Â«C"}, + {"roll", "¥´ºu", "©ñ¥X¦hº¸³Oªºµ¼Ö,", "¦b¦a¤Wºu¨Óºu¥h"}, + {"protect", "«OÅ@", "«OÅ@µÛ", ""}, + {"pull", "©Ô", "¦º©R¦a©Ô¦í", "¤£©ñ"}, + {"punch", "´~¤H", "¬½¬½´~¤F", "¤@¹y"}, + {"rascal", "A¿à", "¸ò", "A¿à"}, + {"recline", "¤JÃh", "Æp¨ì", "ªºÃh¸ÌºÎµÛ¤F¡K¡K"}, + {"respond", "t³d", "¦w¼¢", "»¡¡G¡y¤£nú¡A§Ú·|t³dªº¡K¡K¡z"}, + {"shrug", "ÁqªÓ", "µL©`¦a¦V", "Áq¤FÁqªÓ»H"}, + {"sigh", "¼Û®ð", "¹ï", "¼Û¤F¤@¤f®ð"}, + {"slap", "¥´¦Õ¥ú", "°Ô°Ôªº¤Ú¤F", "¤@¹y¦Õ¥ú"}, + {"smooch", "¾Ö§k", "¾Ö§kµÛ", ""}, + {"snicker", "Åѯº", "¼K¼K¼K..ªº¹ï", "Åѯº"}, + {"sniff", "¤£®h", "¹ï", "¶á¤§¥H»ó"}, + {"spank", "¥´§¾§¾", "¥Î¤Ú´x¥´", "ªºÁv³¡"}, + {"squeeze", "ºò¾Ö", "ºòºò¦a¾Ö©êµÛ", ""}, + {"sysop", "¥l³ê", "¥s¥X¤F§å½ð½ð¡A§â", "½ò«ó¤F¡I"}, + {"thank", "·PÁÂ", "¦V", "·PÁ±o¤Åé§ë¦a"}, + {"tickle", "·kÄo", "©B¼T!©B¼T!·k", "ªºÄo"}, + {"wake", "·n¿ô", "»´»´¦a§â", "·n¿ô"}, + {"wave", "´§¤â", "¹ïµÛ", "«÷©Rªº·n¤â"}, + {"welcome", "Åwªï", "Åwªï", "¶i¨Ó¤K¨ö¤@¤U"}, + {"what", "¤°»ò", "»¡¡G¡y", "ù¤½½M±K«zÃ÷Å¥¬Y?¡H?¡S?¡z"}, + {"whip", "Ã@¤l", "¤â¤W®³µÛÄúÀë¡A¥ÎÃ@¤lµh¥´", ""}, + {"wink", "¯w²´", "¹ï", "¯«¯µªº¯w¯w²´·ú"}, + {"zap", "²r§ð", "¹ï", "ºÆ¨gªº§ðÀ»"}, + {NULL, NULL, NULL, NULL} +}; + +static int +chicken_action(cu, cmd, party) + ChatUser *cu; + char *cmd; + char *party; +{ +return 0; +} +static int +party_action(cu, cmd, party) + ChatUser *cu; + char *cmd; + char *party; +{ + ChatAction *cap; + char *verb; + + for (cap = party_data; (verb = cap->verb); cap++) + { + MYDOG; + + if (str_equal(cmd, verb)) + { + if (*party == '\0') + { + party = "¤j®a"; + } + else + { + ChatUser *xuser; + + xuser = fuzzy_cuser_by_chatid(party); + if (xuser == NULL) + { /* Thor.0724: ¥Î userid¤]¹À³q */ + xuser = cuser_by_userid(party); + } + + if (xuser == NULL) + { + sprintf(chatbuf, msg_no_such_id, party); + send_to_user(cu, chatbuf, 0, MSG_MESSAGE); + return 0; + } + else if (xuser == FUZZY_USER) + { + sprintf(chatbuf, "¡° ½Ð«ü©ú²á¤Ñ¥N¸¹"); + send_to_user(cu, chatbuf, 0, MSG_MESSAGE); + return 0; + } + else if (cu->room != xuser->room || CLOAK(xuser)) + { + sprintf(chatbuf, msg_not_here, party); + send_to_user(cu, chatbuf, 0, MSG_MESSAGE); + return 0; + } + else + { + party = xuser->chatid; + } + } + sprintf(chatbuf, "[1;32m%s [31m%s[33m %s [31m%s[m", + cu->chatid, cap->part1_msg, party, cap->part2_msg); + send_to_room(cu->room, chatbuf, cu->userno, MSG_MESSAGE); + return 0; /* Thor: cu->room ¬O§_¬° NULL? */ + } + } + return 1; +} + + +/* --------------------------------------------- */ +/* MUD-like social commands : speak */ +/* --------------------------------------------- */ + + +static ChatAction speak_data[] = +{ + + { + "ask", "¸ß°Ý", "°Ý", NULL + }, + { + "chant", "ºq¹|", "°ªÁnºq¹|", NULL + }, + { + "cheer", "³Üªö", "³Üªö", NULL + }, + { + "chuckle", "»´¯º", "»´¯º", NULL + }, + { + "curse", "·t·F", "·t·F", NULL + }, + /* {"curse", "©G½|", NULL}, */ + { + "demand", "n¨D", "n¨D", NULL + }, + { + "frown", "½K¬ÜÀY", "ÂÙ¬Ü", NULL + }, + { + "groan", "©D§u", "©D§u", NULL + }, + { + "grumble", "µo¨cÄÌ", "µo¨cÄÌ", NULL + }, + { + "guitar", "¼u°Û", "Ãä¼uµÛ¦N¥L¡AÃä°ÛµÛ", NULL + }, + /* {"helpme", "©I±Ï","¤jÁn©I±Ï",NULL}, */ + { + "hum", "³ä³ä", "³ä³ä¦Û»y", NULL + }, + { + "moan", "«è¹Ä", "«è¹Ä", NULL + }, + { + "notice", "±j½Õ", "±j½Õ", NULL + }, + { + "order", "©R¥O", "©R¥O", NULL + }, + { + "ponder", "¨H«ä", "¨H«ä", NULL + }, + { + "pout", "äþ¼L", "äþµÛ¼L»¡", NULL + }, + { + "pray", "¬èë", "¬èë", NULL + }, + { + "request", "Àµ¨D", "Àµ¨D", NULL + }, + { + "shout", "¤j½|", "¤j½|", NULL + }, + { + "sing", "°Ûºq", "°Ûºq", NULL + }, + { + "smile", "·L¯º", "·L¯º", NULL + }, + { + "smirk", "°²¯º", "°²¯º", NULL + }, + { + "swear", "µo»}", "µo»}", NULL + }, + { + "tease", "¼J¯º", "¼J¯º", NULL + }, + { + "whimper", "¶ã«|", "¶ã«|ªº»¡", NULL + }, + { + "yawn", "«¢¤í", "Ã䥴«¢¤íÃ仡", NULL + }, + { + "yell", "¤j³Û", "¤j³Û", NULL + }, + { + NULL, NULL, NULL, NULL + } +}; + + +static int +speak_action(cu, cmd, msg) + ChatUser *cu; + char *cmd; + char *msg; +{ + ChatAction *cap; + char *verb; + + for (cap = speak_data; (verb = cap->verb); cap++) + { + MYDOG; + + if (str_equal(cmd, verb)) + { + sprintf(chatbuf, "[1;32m%s [31m%s¡G[33m %s[m", + cu->chatid, cap->part1_msg, msg); + send_to_room(cu->room, chatbuf, cu->userno, MSG_MESSAGE); + return 0; /* Thor: cu->room ¬O§_¬° NULL? */ + } + } + return 1; +} + + +/* -------------------------------------------- */ +/* MUD-like social commands : condition */ +/* -------------------------------------------- */ + + +static ChatAction condition_data[] = +{ + { + "applaud", "©ç¤â", "°Ô°Ô°Ô°Ô°Ô°Ô°Ô....", NULL + }, + { + "ayo", "üËç³Þ", "üËç³Þ~~~", NULL + }, + { + "back", "§¤¦^¨Ó", "¦^¨Ó§¤¥¿Ä~Äò¾Ä¾Ô", NULL + }, + { + "blood", "¦b¦å¤¤", "˦b¦åªy¤§¤¤", NULL + }, + { + "blush", "Áy¬õ", "Áy³£¬õ¤F", NULL + }, + { + "broke", "¤ß¸H", "ªº¤ß¯}¸H¦¨¤@¤ù¤@¤ùªº", NULL + }, /* Thor.0731:À³Æ[²³n¨D */ + /* {"bokan", "Bo Kan! Bo Kan!", NULL}, */ + { + "careles", "¨S¤H²z", "¶ã¡ã¡ã³£¨S¦³¤H²z§Ú :~~~~", NULL + }, + { + "chew", "¶ß¥Ê¤l", "«Ü±y¶¢ªº¶ß°_¥Ê¤l¨Ó¤F", NULL + }, + { + "climb", "ª¦¤s", "¦Û¤vºCºCª¦¤W¤s¨Ó¡K¡K", NULL + }, + { + "cold", "·P«_¤F", "·P«_¤F,¶ý¶ý¤£Åý§Ú¥X¥hª± :~~~(", NULL + }, + { + "cough", "«y¹Â", "«y¤F´XÁn", NULL + }, + { + "die", "¼ÉÀÅ", "·í³õ¼ÉÀÅ", NULL + }, + { + "faint", "©üË", "·í³õ©üË", NULL + }, + { + "flop", "»¿¼¥Ö", "½ò¨ì»¿¼¥Ö... ·ÆË¡I", NULL + }, + { + "fly", "ÄÆÄƵM", "ÄÆÄƵM", NULL + }, + { + "frown", "ÂÙ¬Ü", "ÂÙ¬Ü", NULL + }, + { + "gold", "®³ª÷µP", "°ÛµÛ¡G¡yª÷£|£±£½ª÷£|£±£½ ¥X°ê¤ñÁÉ! ±o«ax¡A®³ª÷µP¡A¥úºa˾H¨Ó¡I¡z", NULL + }, + { + "gulu", "¨{¤l¾j", "ªº¨{¤lµo¥X©BÂP~~~©BÂP~~~ªºÁnµ", NULL + }, + { + "haha", "«z«¢«¢", "«z«¢«¢«¢.....^o^", NULL + }, + /* {"haha", "¤j¯º","«z«¢«¢«¢«¢«¢«¢«¢«¢~~~~!!!!!", NULL}, */ + { + "helpme", "¨D±Ï", "¤j³Û~~~±Ï©R°Ú~~~~", NULL + }, + { + "hoho", "¨þ¨þ¯º", "¨þ¨þ¨þ¯ºÓ¤£°±", NULL + }, + { + "happy", "°ª¿³", "°ª¿³±o¦b¦a¤W¥´ºu", NULL + }, + /* {"happy", "°ª¿³", "¢ç¢Ï¡I *^_^*", NULL}, */ + /* {"happy", "", "r-o-O-m....Å¥¤F¯u²n¡I", NULL}, */ + /* {"hurricane", "¢Ö¢÷---¢à£B¢ý--¢Ù¢é¢ö¡I¡I¡I", NULL}, */ + { + "idle", "§b¦í¤F", "§b¦í¤F", NULL + }, + { + "jacky", "®Ì®Ì", "µl¤l¯ëªº®Ì¨Ó®Ì¥h", NULL + }, + +#if 0 + /* Thor.0729: ¤£ª¾¨ä·N */ + { + "lag", "ºô¸ôºC", "lllllllaaaaaaaaaaaagggggggggggggg.................", NULL + }, +#endif + + { + "luck", "©¯¹B", "«z¡IºÖ®ð°Õ¡I", NULL + }, + { + "macarn", "¤@ºØ»R", "¶}©l¸õ°_¤F¢Ûa¢Ña¢àe¢Üa¡ã¡ã¡ã¡ã", NULL + }, + { + "miou", "ØpØp", "ØpØp¤f]¤f]¡ã¡ã¡ã¡ã¡ã", NULL + }, + { + "mouth", "«ó¼L", "«ó¼L¤¤!!", NULL + }, + { + "nani", "«ç»ò·|", "¡G©`£®°Ú®º??", NULL + }, + { + "nose", "¬y»ó¦å", "¬y»ó¦å", NULL + }, + { + "puke", "¹Ã¦R", "¹Ã¦R¤¤", NULL + }, + /* {"puke", "¯uäú¤ß¡A§ÚÅ¥¤F³£·Q¦R", NULL}, */ + { + "rest", "¥ð®§", "¥ð®§¤¤¡A½Ð¤Å¥´ÂZ", NULL + }, + { + "reverse", "½¨{", "½¨{", NULL + }, + { + "room", "¶}©Ð¶¡", "r-o-O-m-r-O-¢Ý-Mmm-rR¢à........", NULL + }, + { + "shake", "·nÀY", "·n¤F·nÀY", NULL + }, + { + "sleep", "ºÎµÛ", "w¦bÁä½L¤WºÎµÛ¤F¡A¤f¤ô¬y¶iÁä½L¡A³y¦¨·í¾÷¡I", NULL + }, + /* {"sleep", "Zzzzzzzzzz¡A¯uµL²á¡A³£§ÖºÎµÛ¤F", NULL}, */ + { + "so", "´NÂæ¤l", "´NÂæ¤l!!", NULL + }, + { + "sorry", "¹Dºp", "¶ã°Ú!!§Ú¹ï¤£°_¤j®a,§Ú¹ï¤£°_°ê®aªÀ·|~~~~~~¶ã°Ú~~~~~", NULL + }, + { + "story", "Á¿¥j", "¶}©lÁ¿¥j¤F", NULL + }, + { + "strut", "·nÂ\\¨«", "¤j·n¤jÂ\\¦a¨«", NULL + }, + { + "suicide", "¦Û±þ", "¦Û±þ", NULL + }, + { + "tea", "ªw¯ù", "ªw¤F³ý¦n¯ù", NULL + }, + { + "think", "«ä¦Ò", "¬nµÛÀY·Q¤F¤@¤U", NULL + }, + { + "tongue", "¦R¦Þ", "¦R¤F¦R¦ÞÀY", NULL + }, + { + "wall", "¼²Àð", "¶]¥h¼²Àð", NULL + }, + { + "wawa", "«z«z", "«z«z«z~~~~~!!!!! ~~~>_<~~~", NULL + }, + /* {"wawa","«z«z«z......>_<",NULL}, */ + { + "www", "¨L¨L", "¨L¨L¨L!!!", NULL + }, + { + "zzz", "¥´©I", "©IÂP~~~~ZZzZz£C¢èZZzzZzzzZZ...", NULL + }, + + { + NULL, NULL, NULL, NULL + } +}; + + +static int +condition_action(cu, cmd) + ChatUser *cu; + char *cmd; +{ + ChatAction *cap; + char *verb; + + for (cap = condition_data; (verb = cap->verb); cap++) + { + MYDOG; + + if (str_equal(cmd, verb)) + { + sprintf(chatbuf, "[1;32m%s [31m%s[m", + cu->chatid, cap->part1_msg); + send_to_room(cu->room, chatbuf, cu->userno, MSG_MESSAGE); + return 1; /* Thor: cu->room ¬O§_¬° NULL? */ + } + } + return 0; +} + + +/* --------------------------------------------- */ +/* MUD-like social commands : help */ +/* --------------------------------------------- */ + + +static char *dscrb[] = +{ + "[1;37m¡i Verb + Nick¡G °Êµü + ¹ï¤è¦W¦r ¡j[36m ¨Ò¡G//kick piggy[m", + "[1;37m¡i Verb + Message¡G°Êµü + n»¡ªº¸Ü ¡j[36m ¨Ò¡G//sing ¤Ñ¤Ñ¤ÑÂÅ[m", + "[1;37m¡i Verb¡G°Êµü ¡j ¡ô¡õ¡G¸ܫ´£[m", NULL +}; +ChatAction *catbl[] = +{ + party_data, speak_data, condition_data, NULL +}; + +static void +chat_partyinfo(cu, msg) + ChatUser *cu; + char *msg; +{ + if (!common_client_command) + return; /* only allow common client to retrieve it */ + + sprintf(chatbuf, "3 °Ê§@ ¥æ½Í ª¬ºA"); + send_to_user(cu, chatbuf, 0, MSG_PARTYINFO); +} + +static void +chat_party(cu, msg) + ChatUser *cu; + char *msg; +{ + int kind, i; + ChatAction *cap; + + if (!common_client_command) + return; + + kind = atoi(nextword(&msg)); + if (kind < 0 || kind > 2) + return; + + sprintf(chatbuf, "%d %s", kind, kind == 2 ? "I" : ""); + + /* Xshadow: ¥u¦³ condition ¤~¬O immediate mode */ + send_to_user(cu, chatbuf, 0, MSG_PARTYLISTSTART); + + cap = catbl[kind]; + for (i = 0; cap[i].verb; i++) + { + sprintf(chatbuf, "%-10s %-20s", cap[i].verb, cap[i].chinese); + /* for (j=0;j<1000000;j++); */ + send_to_user(cu, chatbuf, 0, MSG_PARTYLIST); + } + + sprintf(chatbuf, "%d", kind); + send_to_user(cu, chatbuf, 0, MSG_PARTYLISTEND); +} + + +#define SCREEN_WIDTH 80 +#define MAX_VERB_LEN 8 +#define VERB_NO 10 + +static void +view_action_verb(cu, cmd) /* Thor.0726: ·s¥[°Êµü¤ÀÃþÅã¥Ü */ + register ChatUser *cu; + char cmd; +{ + register int i; + register char *p, *q, *data, *expn; + register ChatAction *cap; + + send_to_user(cu, "/c", 0, MSG_CLRSCR); + + data = chatbuf; + + if (cmd < '1' || cmd > '3') + { /* Thor.0726: ¼g±o¤£¦n, ·Q¿ìªk§ï¶i... */ + for (i = 0; (p = dscrb[i]); i++) + { + sprintf(data, " [//]help %d - MUD-like ªÀ¥æ°Êµü ²Ä %d Ãþ", i + 1, i + 1); + MYDOG; + send_to_user(cu, data, 0, MSG_MESSAGE); + send_to_user(cu, p, 0, MSG_MESSAGE); + send_to_user(cu, " ", 0, MSG_MESSAGE); /* Thor.0726: ´«¦æ, »Ýn " " + * ¶Ü? */ + } + } + else + { + i = cmd - '1'; + + send_to_user(cu, dscrb[i], 0, MSG_MESSAGE); + + expn = chatbuf + 100; /* Thor.0726: À³¸Ó¤£·|overlap§a? */ + + *data = '\0'; + *expn = '\0'; + + cap = catbl[i]; + + for (i = 0; (p = cap[i].verb); i++) + { + MYDOG; + q = cap[i].chinese; + + strcat(data, p); + strcat(expn, q); + + if (((i + 1) % VERB_NO) == 0) + { + send_to_user(cu, data, 0, MSG_MESSAGE); + send_to_user(cu, expn, 0, MSG_MESSAGE); /* Thor.0726: Åã¥Ü¤¤¤åµù¸Ñ */ + *data = '\0'; + *expn = '\0'; + } + else + { + strncat(data, " ", MAX_VERB_LEN - strlen(p)); + strncat(expn, " ", MAX_VERB_LEN - strlen(q)); + } + } + if (i % VERB_NO) + { + send_to_user(cu, data, 0, MSG_MESSAGE); + send_to_user(cu, expn, 0, MSG_MESSAGE); /* Thor.0726: Åã¥Ü¤¤¤åµù¸Ñ */ + } + } + /* send_to_user(cu, " ",0); *//* Thor.0726: ´«¦æ, »Ýn " " ¶Ü? */ +} + +void view_chicken_help(cu) /* Ptt: °«Âûµ{¦¡ ªºhelp */ + register ChatUser *cu; +{ + +} + +/* ----------------------------------------------------- */ +/* chat user service routines */ +/* ----------------------------------------------------- */ + + +static ChatCmd chatcmdlist[] = +{ + {"act", chat_act, 0}, + {"bye", chat_goodbye, 0}, + {"chatroom", chat_chatroom, 1}, /* Xshadow: for common client */ + {"clear", chat_clear, 0}, + {"cloak", chat_cloak, 2}, + {"date", chat_date, 0}, + {"flags", chat_setroom, 0}, + {"help", chat_help, 0}, + {"ignore", chat_ignore, 1}, + {"invite", chat_invite, 0}, + {"join", chat_join, 0}, + {"kick", chat_kick, 1}, + {"msg", chat_private, 0}, + {"nick", chat_nick, 0}, + {"operator", chat_makeop, 0}, + {"party", chat_party, 1}, /* Xshadow: party data for common client */ + {"partyinfo", chat_partyinfo, 1}, /* Xshadow: party info for common + * client */ + + {"query", chat_query, 0}, + + {"room", chat_list_rooms, 0}, + {"unignore", chat_unignore, 1}, + {"whoin", chat_list_by_room, 1}, + {"wall", chat_broadcast, 2}, + + {"who", chat_map_chatids_thisroom, 0}, + {"list", chat_list_users, 0}, + {"topic", chat_topic, 1}, + {"version", chat_version, 1}, + + {NULL, NULL, 0} +}; + +/* Thor: 0 ¤£¥Î exact, 1 n exactly equal, 2 ¯µ±K«ü¥O */ + + +static int +command_execute(cu) + ChatUser *cu; +{ + char *cmd, *msg; + ChatCmd *cmdrec; + int match, ch; + + msg = cu->ibuf; + match = *msg; + + /* Validation routine */ + + if (cu->room == NULL) + { + /* MUST give special /! or /-! command if not in the room yet */ + + if (match == '/' && ((ch = msg[1]) == '!' || (ch == '-' && msg[2] == '!'))) + { + cu->clitype = (ch == '-') ? 1 : 0; + return (login_user(cu, msg + 2 + cu->clitype)); + } + else + return -1; + } + + /* If not a /-command, it goes to the room. */ + + if (match != '/') + { + if (match) + { + char buf[16]; + + sprintf(buf, "%s:", cu->chatid); + sprintf(chatbuf, "%-10s%s", buf, msg); + if (!CLOAK(cu)) /* Thor: ²á¤Ñ«ÇÁô¨³N */ + send_to_room(cu->room, chatbuf, cu->userno, MSG_MESSAGE); + /* Thor: n check cu->room NULL¶Ü? */ + + } + return 0; + } + + msg++; + cmd = nextword(&msg); + match = 0; + + if (*cmd == '/') + { + cmd++; + if (!*cmd || str_equal(cmd, "help")) + { + /* Thor.0726: °Êµü¤ÀÃþ */ + cmd = nextword(&msg); + view_action_verb(cu, *cmd); + match = 1; + } + else if (party_action(cu, cmd, msg) == 0) + match = 1; + else if (speak_action(cu, cmd, msg) == 0) + match = 1; + else + match = condition_action(cu, cmd); + } + else if(*cmd == '.') + { + cmd++; + if (!*cmd || str_equal(cmd, "help")) + { + view_chicken_help(cu); + match = 1; + } + else match = chicken_action(cu, cmd, msg); + } + else + { + char *str; + + common_client_command = 0; + if((*cmd == '-')) { + if(cu->clitype) { + cmd++; /* Xshadow: «ü¥O±q¤U¤@Ó¦r¤¸¤~¶}©l */ + common_client_command = 1; + } + } + for(cmdrec = chatcmdlist; (str = cmdrec->cmdstr); cmdrec++) + { + MYDOG; + + switch (cmdrec->exact) + { + case 1: /* exactly equal */ + match = str_equal(cmd, str); + break; + case 2: /* Thor: secret command */ + if (CHATSYSOP(cu)) + match = str_equal(cmd, str); + break; + default: /* not necessary equal */ + match = str_match(cmd, str) >= 0; + break; + } + + if (match) + { + cmdrec->cmdfunc(cu, msg); + break; + } + } + } + + if (!match) + { + sprintf(chatbuf, "¡» «ü¥O¿ù»~¡G/%s", cmd); + send_to_user(cu, chatbuf, 0, MSG_MESSAGE); + } + return 0; +} + + +/* ----------------------------------------------------- */ +/* serve chat_user's connection */ +/* ----------------------------------------------------- */ + + +static int +cuser_serve(cu) + ChatUser *cu; +{ + register int ch, len, isize; + register char *str, *cmd; + static char buf[80]; + + str = buf; + len = recv(cu->sock, str, sizeof(buf) - 1, 0); + if (len <= 0) + { + /* disconnected */ + + exit_room(cu, EXIT_LOSTCONN, (char *) NULL); + return -1; + } + +#if 0 + /* Xshadow: ±N°e¹Fªº¸ê®Æ©¾¹ê¬ö¿ý¤U¨Ó */ + memcpy(logbuf, buf, sizeof(buf)); + for (ch = 0; ch < sizeof(buf); ch++) + if (!logbuf[ch]) + logbuf[ch] = '$'; + + logbuf[len + 1] = '\0'; + logit("recv: ", logbuf); +#endif + +#if 0 + logit(cu->userid, str); +#endif + + isize = cu->isize; + cmd = cu->ibuf + isize; + while (len--) + { + MYDOG; + + ch = *str++; + + if (ch == '\r' || !ch) + continue; + if (ch == '\n') + { + *cmd = '\0'; + + isize = 0; + cmd = cu->ibuf; + + if (command_execute(cu) < 0) + return -1; + + continue; + } + if (isize < 79) + { + *cmd++ = ch; + isize++; + } + } + cu->isize = isize; + return 0; +} + + +/* ----------------------------------------------------- */ +/* chatroom server core routines */ +/* ----------------------------------------------------- */ + +static int +start_daemon() +{ + int fd, value; + char buf[80]; + struct sockaddr_in fsin; + struct linger ld; + struct rlimit limit; + time_t dummy; + struct tm *dummy_time; + + /* + * More idiot speed-hacking --- the first time conversion makes the C + * library open the files containing the locale definition and time zone. + * If this hasn't happened in the parent process, it happens in the + * children, once per connection --- and it does add up. + */ + + time(&dummy); + dummy_time = gmtime(&dummy); + dummy_time = localtime(&dummy); + strftime(buf, 80, "%d/%b/%Y:%H:%M:%S", dummy_time); + + /* --------------------------------------------------- */ + /* speed-hacking DNS resolve */ + /* --------------------------------------------------- */ + + gethostname(buf, sizeof(buf)); + + /* Thor: ¸U¤@server©|¥¼±µ¨üconnection, ´N¦^¥hªº¸Ü, client ²Ä¤@¦¸·|¶i¤J¥¢±Ñ */ + /* ©Ò¥H²¾¦Ü listen «á */ + + /* --------------------------------------------------- */ + /* detach daemon process */ + /* --------------------------------------------------- */ + + close(0); + close(1); + close(2); + + if (fork()) + exit(0); + + chdir(BBSHOME); + + setsid(); + + /* --------------------------------------------------- */ + /* adjust the resource limit */ + /* --------------------------------------------------- */ + + getrlimit(RLIMIT_NOFILE, &limit); + limit.rlim_cur = limit.rlim_max; + setrlimit(RLIMIT_NOFILE, &limit); + +#if 0 + while (fd) + { + close(--fd); + } + + value = getpid(); + setpgrp(0, value); + + if ((fd = open("/dev/tty", O_RDWR)) >= 0) + { + ioctl(fd, TIOCNOTTY, 0); /* Thor : ¬°¤°»òÁÙn¥Î tty? */ + close(fd); + } +#endif + + fd = open(CHAT_PIDFILE, O_WRONLY | O_CREAT | O_TRUNC, 0600); + if (fd >= 0) + { + /* sprintf(buf, "%5d\n", value); */ + sprintf(buf, "%5d\n", getpid()); + write(fd, buf, 6); + close(fd); + } + +#if 0 + /* ------------------------------ */ + /* trap signals */ + /* ------------------------------ */ + + for (fd = 1; fd < NSIG; fd++) + { + + signal(fd, SIG_IGN); + } +#endif + + fd = socket(PF_INET, SOCK_STREAM, 0); + +#if 0 + value = fcntl(fd, F_GETFL, 0); + fcntl(fd, F_SETFL, value | O_NDELAY); +#endif + + value = 1; + setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &value, sizeof(value)); + +#if 0 + setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *) &value, sizeof(value)); + + value = 81920; + setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *) &value, sizeof(value)); +#endif + + ld.l_onoff = ld.l_linger = 0; + setsockopt(fd, SOL_SOCKET, SO_LINGER, (char *) &ld, sizeof(ld)); + + memset((char *) &fsin, 0, sizeof(fsin)); + fsin.sin_family = AF_INET; + fsin.sin_port = htons(NEW_CHATPORT); + fsin.sin_addr.s_addr = htonl(INADDR_ANY); + + if (bind(fd, (struct sockaddr *) & fsin, sizeof(fsin)) < 0) + exit(1); + + listen(fd, SOCK_QLEN); + + return fd; +} + + +static void +free_resource(fd) + int fd; +{ + static int loop = 0; + register ChatUser *user; + register int sock, num; + + num = 0; + for (user = mainuser; user; user = user->unext) + { + MYDOG; + + num++; + sock = user->sock; + if (fd < sock) + fd = sock; + } + + sprintf(chatbuf, "%d, %d user (%d -> %d)", ++loop, num, maxfds, fd); + logit("LOOP", chatbuf); + + maxfds = fd + 1; +} + + +#ifdef SERVER_USAGE +static void +server_usage() +{ + struct rusage ru; + char buf[2048]; + + if (getrusage(RUSAGE_SELF, &ru)) + return; + + sprintf(buf, "\n[Server Usage]\n\n" + "user time: %.6f\n" + "system time: %.6f\n" + "maximum resident set size: %lu P\n" + "integral resident set size: %lu\n" + "page faults not requiring physical I/O: %ld\n" + "page faults requiring physical I/O: %ld\n" + "swaps: %ld\n" + "block input operations: %ld\n" + "block output operations: %ld\n" + "messages sent: %ld\n" + "messages received: %ld\n" + "signals received: %ld\n" + "voluntary context switches: %ld\n" + "involuntary context switches: %ld\n" + "gline: %d\n\n", + + (double) ru.ru_utime.tv_sec + (double) ru.ru_utime.tv_usec / 1000000.0, + (double) ru.ru_stime.tv_sec + (double) ru.ru_stime.tv_usec / 1000000.0, + ru.ru_maxrss, + ru.ru_idrss, + ru.ru_minflt, + ru.ru_majflt, + ru.ru_nswap, + ru.ru_inblock, + ru.ru_oublock, + ru.ru_msgsnd, + ru.ru_msgrcv, + ru.ru_nsignals, + ru.ru_nvcsw, + ru.ru_nivcsw, + gline); + + write(flog, buf, strlen(buf)); +} +#endif + + +static void +abort_server() +{ + log_close(); + exit(1); +} + + +static void +reaper() +{ + int state; + + while (waitpid(-1, &state, WNOHANG | WUNTRACED) > 0) + { + MYDOG; + } +} + + +int +main() +{ + register int msock, csock, nfds; + register ChatUser *cu; + register fd_set *rptr, *xptr; + fd_set rset, xset; + struct timeval tv; + time_t uptime, tmaintain; + + msock = start_daemon(); + + setgid(BBSGID); + setuid(BBSUID); + + log_init(); + + signal(SIGBUS, SIG_IGN); + signal(SIGSEGV, SIG_IGN); + signal(SIGPIPE, SIG_IGN); + signal(SIGURG, SIG_IGN); + + signal(SIGCHLD, reaper); + signal(SIGTERM, abort_server); + +#ifdef SERVER_USAGE + signal(SIGPROF, server_usage); +#endif + + /* ----------------------------- */ + /* init variable : rooms & users */ + /* ----------------------------- */ + + mainuser = NULL; + memset(&mainroom, 0, sizeof(mainroom)); + strcpy(mainroom.name, MAIN_NAME); + strcpy(mainroom.topic, MAIN_TOPIC); + + /* ----------------------------------- */ + /* main loop */ + /* ----------------------------------- */ + +#if 0 + /* Thor: ¦blisten «á¤~¦^client, ¨C¦¸¶i¨Ó´N·|¦¨¥\ */ + if (fork()) + exit(0); +#endif + + FD_ZERO(&mainfds); + FD_SET(msock, &mainfds); + rptr = &rset; + xptr = &xset; + maxfds = msock + 1; + + tmaintain = time(0) + CHAT_INTERVAL; + + for (;;) + { + uptime = time(0); + if (tmaintain < uptime) + { + tmaintain = uptime + CHAT_INTERVAL; + + /* client/server ª©¥»§Q¥Î ping-pong ¤èªk§PÂ_ user ¬O¤£¬OÁÙ¬¡µÛ */ + /* ¦pªG client ¤w¸gµ²§ô¤F¡A´NÄÀ©ñ¨ä resource */ + + free_resource(msock); + } + + MYDOG; + + memcpy(rptr, &mainfds, sizeof(fd_set)); + memcpy(xptr, &mainfds, sizeof(fd_set)); + + /* Thor: for future reservation bug */ + + tv.tv_sec = CHAT_INTERVAL; + tv.tv_usec = 0; + + MYDOG; + + nfds = select(maxfds, rptr, NULL, xptr, &tv); + + MYDOG; + /* free idle user & chatroom's resource when no traffic */ + + if (nfds == 0) + { + continue; + } + + /* check error condition */ + + if (nfds < 0) + { + csock = errno; + continue; + } + + /* accept new connection */ + + if (FD_ISSET(msock, rptr)) + { + for (;;) + { + MYDOG; /* Thor: check for endless */ + csock = accept(msock, NULL, NULL); + + if (csock >= 0) + { + MYDOG; + if((cu = (ChatUser *) malloc(sizeof(ChatUser)))) + { + memset(cu, 0, sizeof(ChatUser)); + cu->sock = csock; + + cu->unext = mainuser; + mainuser = cu; + +#if 0 + if (mainuser.next) + mainuser.next->prev = cu; + cu->next = mainuser.next; + mainuser.next = cu; + cu->prev = &mainuser; +#endif + + totaluser++; + FD_SET(csock, &mainfds); + if (csock >= maxfds) + maxfds = csock + 1; + +#ifdef DEBUG + logit("accept", "OK"); +#endif + } + else + { + close(csock); + logit("accept", "malloc fail"); + } + MYDOG; + + break; + } + + csock = errno; + if (csock != EINTR) + { + break; + } + } + + FD_CLR(msock, rptr); + + if (--nfds <= 0) + continue; + } + + for (cu = mainuser; cu; cu = cu->unext) + { + MYDOG; + + csock = cu->sock; + + if (FD_ISSET(csock, xptr)) + { + logout_user(cu); + FD_CLR(csock, xptr); + } + else if (FD_ISSET(csock, rptr)) + { + if (cuser_serve(cu) < 0) + logout_user(cu); + } + else + { + continue; + } + + FD_CLR(csock, rptr); + if (--nfds <= 0) + break; + } + + /* end of main loop */ + } +} diff --git a/util/xchatd.h b/util/xchatd.h new file mode 100644 index 00000000..d0a6e1e4 --- /dev/null +++ b/util/xchatd.h @@ -0,0 +1,111 @@ +/* $Id: xchatd.h,v 1.1 2002/03/07 15:13:46 in2 Exp $ */ + +#ifndef _XCHAT_H_ +#define _XCHAT_H_ + +#define XCHAT_VERSION_MAJOR 3 +#define XCHAT_VERSION_MINOR 0 + +/* ----------------------------------------------------- */ +/* XCHAT response code : RFI 3-digit */ +/* ----------------------------------------------------- */ +/* Response : */ +/* 1xx Informative message */ +/* 2xx Command ok */ +/* 3xx Command ok so far, send the rest of it */ +/* 4xx Command correct, but NG for some reason */ +/* 5xx Command unimplemented, incorrect, or serious */ +/* program error occurred */ +/* Function : */ +/* x0x Connection, setup, and miscellaneous messages */ +/* x1x Newsgroup selection */ +/* x2x Article selection */ +/* x3x Distribution functions */ +/* x4x Posting */ +/* x8x Nonstandard extensions (AUTHINFO, XGTITLE) */ +/* x9x Debugging output */ +/* Information : */ +/* No defined semantics */ +/* ----------------------------------------------------- */ + +/* ¨Ñ·sª© client ¨Ï¥Î */ + +#define MSG_LOGINOK 100 +#define MSG_VERSION 103 +#define MSG_MESSAGE 106 + +#define MSG_CHATROOM 110 +#define MSG_TOPIC 113 +#define MSG_ROOM 116 +#define MSG_NICK 118 +#define MSG_CLRSCR 120 + +#define MSG_MOTDSTART 130 +#define MSG_MOTD 330 +#define MSG_MOTDEND 230 + +#define MSG_ROOMLISTSTART 133 +#define MSG_ROOMLIST 333 +#define MSG_ROOMLISTEND 233 +#define MSG_ROOMNOTIFY 134 + +#define MSG_USERLISTSTART 136 +#define MSG_USERLIST 336 +#define MSG_USERLISTEND 236 +#define MSG_USERNOTIFY 137 + +#define MSG_PARTYINFO 140 +#define MSG_PARTYLISTSTART 340 +#define MSG_PARTYLIST 240 +#define MSG_PARTYLISTEND 141 + +#define MSG_PRIVMSG 145 +#define MSG_MYPRIVMSG 146 + +#define ERR_LOGIN_NICKINUSE 501 +#define ERR_LOGIN_NICKERROR 502 +#define ERR_LOGIN_USERONLINE 503 +#define ERR_LOGIN_NOSUCHUSER 504 +#define ERR_LOGIN_PASSERROR 505 + +static int +Isspace (ch) + int ch; +{ + return (ch == ' ' || ch == '\t' || ch == 10 || ch == 13); +} + +static char * +nextword (str) + char **str; +{ + char *head, *tail; + int ch; + + head = *str; + for (;;) { + + ch = *head; + if (!ch) { + *str = head; + return head; + } + if (!Isspace (ch)) + break; + head++; + } + + tail = head + 1; + while((ch = *tail)) { + if(Isspace (ch)) { + *tail++ = '\0'; + break; + } + tail++; + } + *str = tail; + + return head; +} + +#endif /* _XCHAT_H_ */ diff --git a/util/yearsold.c b/util/yearsold.c new file mode 100644 index 00000000..74e711ee --- /dev/null +++ b/util/yearsold.c @@ -0,0 +1,112 @@ +/* $Id: yearsold.c,v 1.1 2002/03/07 15:13:46 in2 Exp $ */ +/* ¯¸¤W¦~ÄÖ²Îp */ + +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <sys/types.h> +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "util.h" + +#define MAX_LINE 16 + +struct userec_t cuser; + +void + outs(fp, buf, mode) +FILE *fp; +char buf[], mode; +{ + static char state = '0'; + + if (state != mode) + fprintf(fp, "[3%cm", state = mode); + if (buf[0]) + { + fprintf(fp, buf); + buf[0] = 0; + } +} + +int main() +{ + int i, j, k; + char buf[256]; + FILE *fp; + int year, max, item, maxyear; + long totalyear; + int act[25]; + time_t now; + struct tm *ptime; + + now = time(NULL); + ptime = localtime(&now); + + if(passwd_mmap()) + exit(1); + + memset(act, 0, sizeof(act)); + for(k = 1; k <= MAX_USERS; k++) { + passwd_query(k, &cuser); + if (((ptime->tm_year - cuser.year) < 10) || ((ptime->tm_year - cuser.year) > + 33)) + continue; + + act[ptime->tm_year - cuser.year - 10]++; + act[24]++; + } + + for (i = max = totalyear = maxyear = 0; i < 24; i++) + { + totalyear += act[i] * (i + 10); + if (act[i] > max) + { + max = act[i]; + maxyear = i; + } + } + + item = max / MAX_LINE + 1; + + if ((fp = fopen(BBSHOME"/etc/yearsold", "w")) == NULL) + { + printf("cann't open etc/yearsold\n"); + return 1; + } + + fprintf(fp, "\t\t\t [1;33;45m " BBSNAME + " ¦~ÄÖ²Îp [%02d/%02d/%02d] [40m\n\n", + ptime->tm_year % 100, ptime->tm_mon, ptime->tm_mday); + for (i = MAX_LINE + 1; i > 0; i--) + { + strcpy(buf, " "); + for (j = 0; j < 24; j++) + { + max = item * i; + year = act[j]; + if (year && (max > year) && (max - item <= year)) + { + outs(fp, buf, '7'); + fprintf(fp, "%-3d", year); + } + else if (max <= year) + { + outs(fp, buf, '4'); + fprintf(fp, "¢i "); + } + else + strcat(buf, " "); + } + fprintf(fp, "\n"); + } + + + fprintf(fp, " [32m" + "10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33\n\n" + "\t\t [36m¦³®Ä²Îp¤H¦¸¡G[37m%-9d[36m¥§¡¦~ÄÖ¡G[37m%d[40;0m\n" + ,act[24], (int)totalyear / act[24]); + fclose(fp); + return 0; +} |