summaryrefslogtreecommitdiffstats
path: root/mbbsd
diff options
context:
space:
mode:
Diffstat (limited to 'mbbsd')
-rw-r--r--mbbsd/Makefile136
-rw-r--r--mbbsd/admin.c1172
-rw-r--r--mbbsd/aids.c290
-rw-r--r--mbbsd/alloc.c254
-rw-r--r--mbbsd/announce.c1558
-rw-r--r--mbbsd/args.c73
-rw-r--r--mbbsd/assess.c268
-rw-r--r--mbbsd/bbs.c3986
-rw-r--r--mbbsd/bbslua.c1801
-rw-r--r--mbbsd/bbsluaext.c83
-rw-r--r--mbbsd/board.c1960
-rw-r--r--mbbsd/brc.c596
-rw-r--r--mbbsd/cache.c1215
-rw-r--r--mbbsd/cal.c630
-rw-r--r--mbbsd/calendar.c362
-rw-r--r--mbbsd/card.c672
-rw-r--r--mbbsd/chat.c597
-rw-r--r--mbbsd/chc.c1012
-rw-r--r--mbbsd/chc_tab.c106
-rw-r--r--mbbsd/chess.c1762
-rw-r--r--mbbsd/chicken.c1138
-rw-r--r--mbbsd/convert.c123
-rw-r--r--mbbsd/crypt.c647
-rw-r--r--mbbsd/dark.c565
-rw-r--r--mbbsd/edit.c3886
-rw-r--r--mbbsd/emaildb.c244
-rw-r--r--mbbsd/fav.c1320
-rw-r--r--mbbsd/file.c186
-rw-r--r--mbbsd/friend.c572
-rw-r--r--mbbsd/gamble.c388
-rw-r--r--mbbsd/go.c1118
-rw-r--r--mbbsd/gomo.c590
-rw-r--r--mbbsd/guess.c369
-rw-r--r--mbbsd/io.c1050
-rw-r--r--mbbsd/kaede.c165
-rw-r--r--mbbsd/lovepaper.c114
-rw-r--r--mbbsd/mail.c2092
-rw-r--r--mbbsd/mbbsd.c1832
-rw-r--r--mbbsd/menu.c718
-rw-r--r--mbbsd/merge.c237
-rw-r--r--mbbsd/more.c77
-rw-r--r--mbbsd/name.c1067
-rw-r--r--mbbsd/osdep.c643
-rw-r--r--mbbsd/othello.c577
-rw-r--r--mbbsd/passwd.c171
-rw-r--r--mbbsd/pfterm.c2502
-rw-r--r--mbbsd/pmore.c3732
-rw-r--r--mbbsd/random.c711
-rw-r--r--mbbsd/read.c1371
-rw-r--r--mbbsd/record.c666
-rw-r--r--mbbsd/register.c3040
-rw-r--r--mbbsd/reversi.c513
-rw-r--r--mbbsd/screen.c819
-rw-r--r--mbbsd/stuff.c828
-rw-r--r--mbbsd/syspost.c146
-rw-r--r--mbbsd/talk.c3654
-rw-r--r--mbbsd/telnet.c338
-rw-r--r--mbbsd/term.c118
-rw-r--r--mbbsd/time.c20
-rw-r--r--mbbsd/topsong.c72
-rw-r--r--mbbsd/user.c1452
-rw-r--r--mbbsd/var.c628
-rw-r--r--mbbsd/vice.c153
-rw-r--r--mbbsd/vote.c1088
-rw-r--r--mbbsd/voteboard.c400
-rw-r--r--mbbsd/xyz.c338
66 files changed, 0 insertions, 61011 deletions
diff --git a/mbbsd/Makefile b/mbbsd/Makefile
deleted file mode 100644
index a33301c6..00000000
--- a/mbbsd/Makefile
+++ /dev/null
@@ -1,136 +0,0 @@
-# $Id$
-
-SRCROOT= ..
-.include "$(SRCROOT)/pttbbs.mk"
-
-#######################################################################
-# common modules
-#######################################################################
-
-PROG= mbbsd
-CHESSOBJS= chc.o chc_tab.o chess.o go.o gomo.o dark.o reversi.o
-GAMEOBJS = card.o guess.o chicken.o othello.o
-SYSOBJS = args.o crypt.o osdep.o
-COREOBJS = bbs.o announce.o read.o board.o cache.o brc.o mail.o record.o fav.o
-ACCOBJS = user.o register.o passwd.o
-TALKOBJS = talk.o chat.o friend.o
-NETOBJS = mbbsd.o io.o term.o
-UTILOBJS = stuff.o file.o kaede.o convert.o name.o
-PLUGOBJS = lovepaper.o calendar.o topsong.o vice.o
-OBJS= admin.o assess.o cal.o edit.o menu.o more.o gamble.o \
- xyz.o syspost.o vote.o var.o voteboard.o \
- pmore.o telnet.o \
- $(COREOBJS) $(ACCOBJS) $(NETOBJS) $(TALKOBJS) $(UTILOBJS) \
- $(SYSOBJS) $(PLUGOBJS) $(CHESSOBJS) $(GAMEOBJS)
-
-#######################################################################
-# conditional configurations and optional modules
-#######################################################################
-
-.if !defined(WITHOUT_BLOG) && defined(WITH_BLOG)
-CFLAGS+= -DBLOG
-LDFLAGS+= -L/usr/local/lib/mysql
-LIBS+= -lmysqlclient
-.endif
-
-.if !defined(WITHOUT_LOG_CRAWLER) && defined(WITH_LOG_CRAWLER)
-CFLAGS+= -DLOG_CRAWLER
-.endif
-
-.if !defined(WITHOUT_EMAILDB) && defined(WITH_EMAILDB)
-OBJS+= emaildb.o
-CFLAGS+= -DUSE_EMAILDB
-LIBS+= -lsqlite3
-.endif
-
-.if !defined(WITHOUT_BBSLUA_USAGE) && defined(WITH_BBSLUA_USAGE)
-CFLAGS+= -DBBSLUA_USAGE
-.endif
-
-.if !defined(WITHOUT_BBSLUA) && defined(WITH_BBSLUA)
-OBJS+= bbslua.o bbsluaext.o
-CFLAGS+= -DUSE_BBSLUA
-# MODIFY THESE ENVIRONMENT SETTINGS TO FIT YOUR CONFIGURATION
-CFLAGS+= -I/usr/include/lua5.1
-CFLAGS_FreeBSD += -I/usr/local/include/lua51
-LDFLAGS_FreeBSD+= -L/usr/local/lib/lua51
-# modify the lib name below to fit your configuration
-# usually you'd try "-llua" instead of "-llua5.1".
-LIBS+= -llua5.1 -lm
-#LIBS+= -llua -lm
-.endif
-
-.if !defined(WITHOUT_PFTERM) && defined(WITH_PFTERM)
-OBJS+= pfterm.o
-CFLAGS+= -DUSE_PFTERM
-#CFLAGS+= -DDBG_OUTRPT
-.else
-OBJS+= screen.o
-.endif
-
-#######################################################################
-# special library (DIET) configuration
-#######################################################################
-
-.if defined(DIET)
-OBJS+= random.o time.o alloc.o
-DIETCC= diet -Os
-.endif
-#CFLAGS+=-g
-#CFLAGS+=-std=c99
-
-# reduce .bss align overhead
-.if !defined(DEBUG)
-LDFLAGS+=-Wl,--sort-common
-.endif
-
-.if defined(MERGEBBS)
-CFLAGS+= -DMERGEBBS
-OBJS+= merge.o
-.endif
-LIBS+= $(SRCROOT)/src/libbbsutil/libbbsutil.a \
- $(SRCROOT)/src/libbbs/libbbs.a
-
-#######################################################################
-# Make Rules
-#######################################################################
-
-.SUFFIXES: .c .o
-.c.o: $(SRCROOT)/include/var.h
- $(CCACHE) $(DIETCC) $(CC) $(CFLAGS) -c $*.c
-
-all: $(PROG)
-
-$(PROG): $(OBJS)
- sh $(SRCROOT)/util/newvers.sh
- $(DIETCC) $(CC) $(LDFLAGS) -o $(PROG) $(OBJS) $(LIBS) $(EXT_LIBS) vers.c
-
-$(SRCROOT)/include/var.h: var.c
- perl $(SRCROOT)/util/parsevar.pl < var.c > $(SRCROOT)/include/var.h
-
-$(SRCROOT)/include/banip.h: $(SRCROOT)/util/banip.pl
- perl $(SRCROOT)/util/banip.pl > $@
-
-mbbsd.o: mbbsd.c $(SRCROOT)/include/var.h $(SRCROOT)/include/banip.h
- $(CCACHE) $(DIETCC) $(CC) $(CFLAGS) -c $<
-
-initemaildb: emaildb.c
- $(CC) -DINIT_MAIN $(CFLAGS) $(LDFLAGS) -o initemaildb emaildb.c $(LIBS)
-
-ctags:
- ctags *.c ../include/*.h ../src/libbbs/*.c ../src/libbbsutil/*.c
-
-test: $(PROG)
- killall -9 testmbbsd || true
- cp mbbsd testmbbsd
- ./testmbbsd 9000
- rm -f testmbbsd
-
-install: $(PROG)
- install -d $(BBSHOME)/bin/
- install -c -m 755 $(PROG) $(BBSHOME)/bin/
- mv -f $(BBSHOME)/bin/mbbsd $(BBSHOME)/bin/mbbsd.`date '+%m%d%H%M'`
- ln -sv $(BBSHOME)/bin/mbbsd.`date '+%m%d%H%M'` $(BBSHOME)/bin/mbbsd
-
-clean:
- rm -f $(OBJS) $(PROG)
diff --git a/mbbsd/admin.c b/mbbsd/admin.c
deleted file mode 100644
index d0efa3e1..00000000
--- a/mbbsd/admin.c
+++ /dev/null
@@ -1,1172 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-/* ¶i¯¸¤ô²y«Å¶Ç */
-int
-m_loginmsg(void)
-{
- char msg[100];
- move(21,0);
- clrtobot();
- if(SHM->loginmsg.pid && SHM->loginmsg.pid != currutmp->pid)
- {
- outs("¥Ø«e¤w¸g¦³¥H¤Uªº ¶i¯¸¤ô²y³]©w½Ð¥ý¨ó½Õ¦n¦A³]©w..");
- getmessage(SHM->loginmsg);
- }
- getdata(22, 0,
- "¶i¯¸¤ô²y:¥»¯¸¬¡°Ê,¤£¤zÂZ¨Ï¥ÎªÌ¬°­­,³]©wªÌÂ÷¯¸¦Û°Ê¨ú®ø,½T©w­n³]?(y/N)",
- msg, 3, LCECHO);
-
- if(msg[0]=='y' &&
-
- getdata_str(23, 0, "³]©w¶i¯¸¤ô²y:", msg, 56, DOECHO, SHM->loginmsg.last_call_in))
- {
- SHM->loginmsg.pid=currutmp->pid; /*¯¸ªø¤£¦h ´N¤£ºÞrace condition */
- strcpy(SHM->loginmsg.last_call_in, msg);
- strcpy(SHM->loginmsg.userid, cuser.userid);
- }
- return 0;
-}
-
-/* ¨Ï¥ÎªÌºÞ²z */
-int
-m_user(void)
-{
- userec_t xuser;
- int id;
- char genbuf[200];
-
- stand_title("¨Ï¥ÎªÌ³]©w");
- usercomplete(msg_uid, genbuf);
- if (*genbuf) {
- move(2, 0);
- if ((id = getuser(genbuf, &xuser))) {
- user_display(&xuser, 1);
- if( HasUserPerm(PERM_ACCOUNTS) )
- uinfo_query(&xuser, 1, id);
- else
- pressanykey();
- } else {
- outs(err_uid);
- clrtoeol();
- pressanykey();
- }
- }
- return 0;
-}
-
-static int retrieve_backup(userec_t *user)
-{
- int uid;
- char src[PATHLEN], dst[PATHLEN];
- char ans;
-
- if ((uid = searchuser(user->userid, user->userid))) {
- userec_t orig;
- passwd_query(uid, &orig);
- strlcpy(user->passwd, orig.passwd, sizeof(orig.passwd));
- setumoney(uid, user->money);
- passwd_update(uid, user);
- return 0;
- }
-
- ans = getans("¥Ø«eªº PASSWD ÀɨS¦³¦¹ ID¡A·s¼W¶Ü¡H[y/N]");
-
- if (ans != 'y') {
- vmsg("¥Ø«eªº PASSWDS ÀɨS¦³¦¹ ID¡A½Ð¥ý·s¼W¦¹±b¸¹");
- return -1;
- }
-
- if (setupnewuser((const userec_t *)user) >= 0) {
- sethomepath(dst, user->userid);
- if (!dashd(dst)) {
- snprintf(src, sizeof(src), "tmp/%s", user->userid);
- if (!dashd(src) || !Rename(src, dst))
- mkuserdir(user->userid);
- }
- return 0;
- }
- return -1;
-}
-
-static int
-search_key_user(const char *passwdfile, int mode)
-{
- userec_t user;
- int ch;
- int unum = 0;
- FILE *fp1 = fopen(passwdfile, "r");
- char friendfile[128]="", key[22], *keymatch;
- int keytype = 0;
- char isCurrentPwd = 0;
-
- isCurrentPwd = (strcmp(passwdfile, FN_PASSWD) == 0) ? 1 : 0;
- assert(fp1);
- clear();
- if (!mode)
- {
- getdata(0, 0, "½Ð¿é¤Jid :", key, sizeof(key), DOECHO);
- } else {
- // improved search
- getdata(0, 0, "·j´M­þºØÄæ¦ì?"
- "([0]¥þ³¡ 1.ID 2.©m¦W 3.¼ÊºÙ 4.¦a§} 5.email 6.IP 7.»{ÃÒ/¹q¸Ü) ",
- key, 2, DOECHO);
- if (isascii(key[0]) && isdigit(key[0]))
- keytype = key[0] - '0';
- if (keytype < 0 || keytype > 7)
- keytype = 0;
- getdata(0, 0, "½Ð¿é¤JÃöÁä¦r: ", key, sizeof(key), DOECHO);
- }
-
- if(!key[0]) {
- fclose(fp1);
- return 0;
- }
- while ((fread(&user, sizeof(user), 1, fp1)) > 0 && unum++ < MAX_USERS) {
-
- // skip empty records
- if (!user.userid[0])
- continue;
-
- if (!(unum & 0xFF)) {
- move(1, 0);
- prints("²Ä [%d] µ§¸ê®Æ\n", unum);
- refresh();
- }
-
- keymatch = NULL;
-
- if (!mode)
- {
- // only verify id
- if (!strcasecmp(user.userid, key))
- keymatch = user.userid;
- } else {
- // search by keytype
- if ((!keytype || keytype == 1) &&
- strcasestr(user.userid, key))
- keymatch = user.userid;
- else if ((!keytype || keytype == 2) &&
- strcasestr(user.realname, key))
- keymatch = user.realname;
- else if ((!keytype || keytype == 3) &&
- strcasestr(user.nickname, key))
- keymatch = user.nickname;
- else if ((!keytype || keytype == 4) &&
- strcasestr(user.address, key))
- keymatch = user.address;
- else if ((!keytype || keytype == 5) &&
- strcasestr(user.email, key))
- keymatch = user.email;
- else if ((!keytype || keytype == 6) &&
- strcasestr(user.lasthost, key))
- keymatch = user.lasthost;
- else if ((!keytype || keytype == 7) &&
- strcasestr(user.justify, key))
- keymatch = user.justify;
- }
-
- if(keymatch) {
- move(1, 0);
- prints("²Ä [%d] µ§¸ê®Æ\n", unum);
- refresh();
-
- user_display(&user, 1);
- // user_display does not have linefeed in tail.
-
- if (isCurrentPwd && HasUserPerm(PERM_ACCOUNTS))
- uinfo_query(&user, 1, unum);
- else
- outs("\n");
-
- outs(ANSI_COLOR(44) " ªÅ¥ÕÁä" \
- ANSI_COLOR(37) ":·j´M¤U¤@­Ó " \
- ANSI_COLOR(33)" Q" ANSI_COLOR(37)": Â÷¶}");
- outs(mode ?
- " A: add to namelist " ANSI_RESET " " :
- " S: ¨ú¥Î³Æ¥÷¸ê®Æ " ANSI_RESET " ");
- while (1) {
- while ((ch = igetch()) == 0);
- if (ch == 'a' || ch=='A' )
- {
- if(!friendfile[0])
- {
- friend_special();
- setfriendfile(friendfile, FRIEND_SPECIAL);
- }
- friend_add(user.userid, FRIEND_SPECIAL, keymatch);
- break;
- }
- if (ch == ' ')
- break;
- if (ch == 'q' || ch == 'Q') {
- fclose(fp1);
- return 0;
- }
- if (ch == 's' && !mode) {
- if (retrieve_backup(&user) >= 0) {
- fclose(fp1);
- return 0;
- }
- }
- }
- }
- }
-
- fclose(fp1);
- return 0;
-}
-
-/* ¥H¥ô·N key ´M§ä¨Ï¥ÎªÌ */
-int
-search_user_bypwd(void)
-{
- search_key_user(FN_PASSWD, 1);
- return 0;
-}
-
-/* ´M§ä³Æ¥÷ªº¨Ï¥ÎªÌ¸ê®Æ */
-int
-search_user_bybakpwd(void)
-{
- char *choice[] = {
- "PASSWDS.NEW1", "PASSWDS.NEW2", "PASSWDS.NEW3",
- "PASSWDS.NEW4", "PASSWDS.NEW5", "PASSWDS.NEW6",
- "PASSWDS.BAK"
- };
- int ch;
-
- clear();
- move(1, 1);
- outs("½Ð¿é¤J§A­n¥Î¨Ó´M§ä³Æ¥÷ªºÀÉ®× ©Î«ö 'q' Â÷¶}\n");
- outs(" [" ANSI_COLOR(1;31) "1" ANSI_RESET "]¤@¤Ñ«e,"
- " [" ANSI_COLOR(1;31) "2" ANSI_RESET "]¨â¤Ñ«e,"
- " [" ANSI_COLOR(1;31) "3" ANSI_RESET "]¤T¤Ñ«e\n");
- outs(" [" ANSI_COLOR(1;31) "4" ANSI_RESET "]¥|¤Ñ«e,"
- " [" ANSI_COLOR(1;31) "5" ANSI_RESET "]¤­¤Ñ«e,"
- " [" ANSI_COLOR(1;31) "6" ANSI_RESET "]¤»¤Ñ«e\n");
- outs(" [7]³Æ¥÷ªº\n");
- do {
- move(5, 1);
- outs("¿ï¾Ü => ");
- ch = igetch();
- if (ch == 'q' || ch == 'Q')
- return 0;
- } while (ch < '1' || ch > '7');
- ch -= '1';
- if( access(choice[ch], R_OK) != 0 )
- vmsg("Àɮפ£¦s¦b");
- else
- search_key_user(choice[ch], 0);
- return 0;
-}
-
-static void
-bperm_msg(const boardheader_t * board)
-{
- prints("\n³]©w [%s] ¬ÝªO¤§(%s)Åv­­¡G", board->brdname,
- board->brdattr & BRD_POSTMASK ? "µoªí" : "¾\\Ū");
-}
-
-unsigned int
-setperms(unsigned int pbits, const char * const pstring[])
-{
- register int i;
-
- move(4, 0);
- for (i = 0; i < NUMPERMS / 2; i++) {
- prints("%c. %-20s %-15s %c. %-20s %s\n",
- 'A' + i, pstring[i],
- ((pbits >> i) & 1 ? "£¾" : "¢æ"),
- i < 10 ? 'Q' + i : '0' + i - 10,
- pstring[i + 16],
- ((pbits >> (i + 16)) & 1 ? "£¾" : "¢æ"));
- }
- clrtobot();
- while (
- (i = getkey("½Ð«ö [A-5] ¤Á´«³]©w¡A«ö [Return] µ²§ô¡G"))!='\r')
- {
- if (isdigit(i))
- i = i - '0' + 26;
- else if (isalpha(i))
- i = tolower(i) - 'a';
- else {
- bell();
- continue;
- }
-
- pbits ^= (1 << i);
- move(i % 16 + 4, i <= 15 ? 24 : 64);
- outs((pbits >> i) & 1 ? "£¾" : "¢æ");
- }
- return pbits;
-}
-
-#ifdef CHESSCOUNTRY
-static void
-AddingChessCountryFiles(const char* apath)
-{
- char filename[PATHLEN];
- char symbolicname[PATHLEN];
- char adir[PATHLEN];
- FILE* fp;
- fileheader_t fh;
-
- setadir(adir, apath);
-
- /* creating chess country regalia */
- snprintf(filename, sizeof(filename), "%s/chess_ensign", apath);
- close(open(filename, O_CREAT | O_WRONLY, 0644));
-
- strlcpy(symbolicname, apath, sizeof(symbolicname));
- stampfile(symbolicname, &fh);
- symlink("chess_ensign", symbolicname);
-
- strcpy(fh.title, "¡º ´Ñ°ê°êÀ² (¤£¯à§R°£¡A¨t²Î»Ý­n)");
- strcpy(fh.owner, str_sysop);
- append_record(adir, &fh, sizeof(fileheader_t));
-
- /* creating member list */
- snprintf(filename, sizeof(filename), "%s/chess_list", apath);
- if (!dashf(filename)) {
- fp = fopen(filename, "w");
- assert(fp);
- fputs("´Ñ°ê°ê¦W\n"
- "±b¸¹ ¶¥¯Å ¥[¤J¤é´Á µ¥¯Å©Î³Q½Ö«R¸¸\n"
- "¢w¢w¢w¢w¢w¢w ¢w¢w¢w ¢w¢w¢w¢w¢w ¢w¢w¢w¢w¢w¢w¢w\n",
- fp);
- fclose(fp);
- }
-
- strlcpy(symbolicname, apath, sizeof(symbolicname));
- stampfile(symbolicname, &fh);
- symlink("chess_list", symbolicname);
-
- strcpy(fh.title, "¡º ´Ñ°ê¦¨­ûªí (¤£¯à§R°£¡A¨t²Î»Ý­n)");
- strcpy(fh.owner, str_sysop);
- append_record(adir, &fh, sizeof(fileheader_t));
-
- /* creating profession photos' dir */
- snprintf(filename, sizeof(filename), "%s/chess_photo", apath);
- mkdir(filename, 0755);
-
- strlcpy(symbolicname, apath, sizeof(symbolicname));
- stampfile(symbolicname, &fh);
- symlink("chess_photo", symbolicname);
-
- strcpy(fh.title, "¡» ´Ñ°ê·Ó¤ùÀÉ (¤£¯à§R°£¡A¨t²Î»Ý­n)");
- strcpy(fh.owner, str_sysop);
- append_record(adir, &fh, sizeof(fileheader_t));
-}
-#endif /* defined(CHESSCOUNTRY) */
-
-/* ¦Û°Ê³]¥ßºëµØ°Ï */
-void
-setup_man(const boardheader_t * board, const boardheader_t * oldboard)
-{
- char genbuf[200];
-
- setapath(genbuf, board->brdname);
- mkdir(genbuf, 0755);
-
-#ifdef CHESSCOUNTRY
- if (oldboard == NULL || oldboard->chesscountry != board->chesscountry)
- if (board->chesscountry != CHESSCODE_NONE)
- AddingChessCountryFiles(genbuf);
- // else // doesn't remove files..
-#endif
-}
-
-void delete_symbolic_link(boardheader_t *bh, int bid)
-{
- assert(0<=bid-1 && bid-1<MAX_BOARD);
- memset(bh, 0, sizeof(boardheader_t));
- substitute_record(fn_board, bh, sizeof(boardheader_t), bid);
- reset_board(bid);
- sort_bcache();
- log_usies("DelLink", bh->brdname);
-}
-
-int dir_cmp(const void *a, const void *b)
-{
- return (atoi( &((fileheader_t *)a)->filename[2] ) -
- atoi( &((fileheader_t *)b)->filename[2] ));
-}
-
-void merge_dir(const char *dir1, const char *dir2, int isoutter)
-{
- int i, pn, sn;
- fileheader_t *fh;
- char *p1, *p2, bakdir[128], file1[128], file2[128];
- strcpy(file1,dir1);
- strcpy(file2,dir2);
- if((p1=strrchr(file1,'/')))
- p1 ++;
- else
- p1 = file1;
- if((p2=strrchr(file2,'/')))
- p2 ++;
- else
- p2 = file2;
-
- pn=get_num_records(dir1, sizeof(fileheader_t));
- sn=get_num_records(dir2, sizeof(fileheader_t));
- if(!sn) return;
- fh= (fileheader_t *)malloc( (pn+sn)*sizeof(fileheader_t));
- get_records(dir1, fh, sizeof(fileheader_t), 1, pn);
- get_records(dir2, fh+pn, sizeof(fileheader_t), 1, sn);
- if(isoutter)
- {
- for(i=0; i<sn; i++)
- if(fh[pn+i].owner[0])
- strcat(fh[pn+i].owner, ".");
- }
- qsort(fh, pn+sn, sizeof(fileheader_t), dir_cmp);
- sprintf(bakdir,"%s.bak", dir1);
- Rename(dir1, bakdir);
- for(i=1; i<=pn+sn; i++ )
- {
- if(!fh[i-1].filename[0]) continue;
- if(i == pn+sn || strcmp(fh[i-1].filename, fh[i].filename))
- {
- fh[i-1].recommend =0;
- fh[i-1].filemode |= 1;
- append_record(dir1, &fh[i-1], sizeof(fileheader_t));
- strcpy(p1, fh[i-1].filename);
- if(!dashf(file1))
- {
- strcpy(p2, fh[i-1].filename);
- Copy(file2, file1);
- }
- }
- else
- fh[i].filemode |= fh[i-1].filemode;
- }
-
- free(fh);
-}
-
-int
-m_mod_board(char *bname)
-{
- boardheader_t bh, newbh;
- int bid;
- char genbuf[256], ans[4];
-
- bid = getbnum(bname);
- if (!bid || !bname[0] || get_record(fn_board, &bh, sizeof(bh), bid) == -1) {
- vmsg(err_bid);
- return -1;
- }
- assert(0<=bid-1 && bid-1<MAX_BOARD);
- prints("¬ÝªO¦WºÙ¡G%s\n¬ÝªO»¡©ú¡G%s\n¬ÝªObid¡G%d\n¬ÝªOGID¡G%d\n"
- "ªO¥D¦W³æ¡G%s", bh.brdname, bh.title, bid, bh.gid, bh.BM);
- bperm_msg(&bh);
-
- /* Ptt ³oÃäÂ_¦æ·|Àɨì¤U­± */
- move(9, 0);
- snprintf(genbuf, sizeof(genbuf), "(E)³]©w (V)¹Hªk/¸Ñ°£%s%s [Q]¨ú®ø¡H",
- HasUserPerm(PERM_SYSOP |
- PERM_BOARD) ? " (B)Vote (S)±Ï¦^ (C)¦X¨Ö (G)½ä½L¸Ñ¥d" : "",
- HasUserPerm(PERM_SYSSUBOP | PERM_SYSSUPERSUBOP | PERM_BOARD) ? " (D)§R°£" : "");
- getdata(10, 0, genbuf, ans, 3, LCECHO);
-
- switch (*ans) {
- case 'g':
- if (HasUserPerm(PERM_SYSOP | PERM_BOARD)) {
- char path[PATHLEN];
- setbfile(genbuf, bname, FN_TICKET_LOCK);
- setbfile(path, bname, FN_TICKET_END);
- rename(genbuf, path);
- }
- break;
- case 's':
- if (HasUserPerm(PERM_SYSOP | PERM_BOARD)) {
- snprintf(genbuf, sizeof(genbuf),
- BBSHOME "/bin/buildir boards/%c/%s &",
- bh.brdname[0], bh.brdname);
- system(genbuf);
- }
- break;
- case 'c':
- if (HasUserPerm(PERM_SYSOP)) {
- char frombname[20], fromdir[256];
-#ifdef MERGEBBS
- if(getans("¬O§_¶×¤JSOB¬ÝªO? (y/N)")=='y')
- {
- setbdir(genbuf, bname);
- m_sob_brd(bname, fromdir);
- if(!fromdir[0]) break;
- merge_dir(genbuf, fromdir, 1);
- }
- else{
-#endif
- CompleteBoard(MSG_SELECT_BOARD, frombname);
- if (frombname[0] == '\0' || !getbnum(frombname) ||
- !strcmp(frombname,bname))
- break;
- setbdir(genbuf, bname);
- setbdir(fromdir, frombname);
- merge_dir(genbuf, fromdir, 0);
-#ifdef MERGEBBS
- }
-#endif
- touchbtotal(bid);
- }
- break;
- case 'b':
- if (HasUserPerm(PERM_SYSOP | PERM_BOARD)) {
- char bvotebuf[10];
-
- memcpy(&newbh, &bh, sizeof(bh));
- snprintf(bvotebuf, sizeof(bvotebuf), "%d", newbh.bvote);
- move(20, 0);
- prints("¬ÝªO %s ­ì¨Óªº BVote¡G%d", bh.brdname, bh.bvote);
- getdata_str(21, 0, "·sªº Bvote¡G", genbuf, 5, LCECHO, bvotebuf);
- newbh.bvote = atoi(genbuf);
- assert(0<=bid-1 && bid-1<MAX_BOARD);
- substitute_record(fn_board, &newbh, sizeof(newbh), bid);
- reset_board(bid);
- log_usies("SetBoardBvote", newbh.brdname);
- break;
- } else
- break;
- case 'v':
- memcpy(&newbh, &bh, sizeof(bh));
- outs("¬ÝªO¥Ø«e¬°");
- outs((bh.brdattr & BRD_BAD) ? "¹Hªk" : "¥¿±`");
- getdata(21, 0, "½T©w§ó§ï¡H", genbuf, 5, LCECHO);
- if (genbuf[0] == 'y') {
- if (newbh.brdattr & BRD_BAD)
- newbh.brdattr = newbh.brdattr & (!BRD_BAD);
- else
- newbh.brdattr = newbh.brdattr | BRD_BAD;
- assert(0<=bid-1 && bid-1<MAX_BOARD);
- substitute_record(fn_board, &newbh, sizeof(newbh), bid);
- reset_board(bid);
- log_usies("ViolateLawSet", newbh.brdname);
- }
- break;
- case 'd':
- if (!(HasUserPerm(PERM_SYSOP | PERM_BOARD) ||
- (HasUserPerm(PERM_SYSSUPERSUBOP) && GROUPOP())))
- break;
- getdata_str(9, 0, msg_sure_ny, genbuf, 3, LCECHO, "N");
- if (genbuf[0] != 'y' || !bname[0])
- outs(MSG_DEL_CANCEL);
- else if (bh.brdattr & BRD_SYMBOLIC) {
- delete_symbolic_link(&bh, bid);
- }
- else {
- strlcpy(bname, bh.brdname, sizeof(bh.brdname));
- snprintf(genbuf, sizeof(genbuf),
- "/bin/tar zcvf tmp/board_%s.tgz boards/%c/%s man/boards/%c/%s >/dev/null 2>&1;"
- "/bin/rm -fr boards/%c/%s man/boards/%c/%s",
- bname, bname[0], bname, bname[0],
- bname, bname[0], bname, bname[0], bname);
- system(genbuf);
- memset(&bh, 0, sizeof(bh));
- snprintf(bh.title, sizeof(bh.title),
- " %s ¬ÝªO %s §R°£", bname, cuser.userid);
- post_msg(GLOBAL_SECURITY, bh.title, "½Ðª`·N§R°£ªº¦Xªk©Ê", "[¨t²Î¦w¥þ§½]");
- assert(0<=bid-1 && bid-1<MAX_BOARD);
- substitute_record(fn_board, &bh, sizeof(bh), bid);
- reset_board(bid);
- sort_bcache();
- log_usies("DelBoard", bh.title);
- outs("§RªO§¹²¦");
- }
- break;
- case 'e':
- if( bh.brdattr & BRD_SYMBOLIC ){
- vmsg("¸T¤î§ó°Ê³sµ²¬ÝªO¡A½Ðª½±µ­×¥¿­ì¬ÝªO");
- break;
- }
- move(8, 0);
- outs("ª½±µ«ö [Return] ¤£­×§ï¸Ó¶µ³]©w");
- memcpy(&newbh, &bh, sizeof(bh));
-
- while (getdata(9, 0, "·s¬ÝªO¦WºÙ¡G", genbuf, IDLEN + 1, DOECHO)) {
- if (getbnum(genbuf)) {
- move(3, 0);
- outs("¿ù»~! ªO¦W¹p¦P");
- } else if ( !invalid_brdname(genbuf) ){
- strlcpy(newbh.brdname, genbuf, sizeof(newbh.brdname));
- break;
- }
- }
-
- do {
- getdata_str(12, 0, "¬ÝªOÃþ§O¡G", genbuf, 5, DOECHO, bh.title);
- if (strlen(genbuf) == 4)
- break;
- } while (1);
-
- strcpy(newbh.title, genbuf);
-
- newbh.title[4] = ' ';
-
- getdata_str(14, 0, "¬ÝªO¥DÃD¡G", genbuf, BTLEN + 1, DOECHO,
- bh.title + 7);
- if (genbuf[0])
- strlcpy(newbh.title + 7, genbuf, sizeof(newbh.title) - 7);
- if (getdata_str(15, 0, "·sªO¥D¦W³æ¡G", genbuf, IDLEN * 3 + 3, DOECHO,
- bh.BM)) {
- trim(genbuf);
- strlcpy(newbh.BM, genbuf, sizeof(newbh.BM));
- }
-#ifdef CHESSCOUNTRY
- if (HasUserPerm(PERM_SYSOP)) {
- snprintf(genbuf, sizeof(genbuf), "%d", bh.chesscountry);
- if (getdata_str(16, 0, "³]©w´Ñ°ê (0)µL (1)¤­¤l´Ñ (2)¶H´Ñ (3)³ò´Ñ", ans,
- sizeof(ans), LCECHO, genbuf)){
- newbh.chesscountry = atoi(ans);
- if (newbh.chesscountry > CHESSCODE_MAX ||
- newbh.chesscountry < CHESSCODE_NONE)
- newbh.chesscountry = bh.chesscountry;
- }
- }
-#endif /* defined(CHESSCOUNTRY) */
- if (HasUserPerm(PERM_SYSOP|PERM_BOARD)) {
- move(1, 0);
- clrtobot();
- newbh.brdattr = setperms(newbh.brdattr, str_permboard);
- move(1, 0);
- clrtobot();
- }
- {
- const char* brd_symbol;
- if (newbh.brdattr & BRD_GROUPBOARD)
- brd_symbol = "£U";
- else if (newbh.brdattr & BRD_NOTRAN)
- brd_symbol = "¡·";
- else
- brd_symbol = "¡´";
-
- newbh.title[5] = brd_symbol[0];
- newbh.title[6] = brd_symbol[1];
- }
-
- if (HasUserPerm(PERM_SYSOP|PERM_BOARD) && !(newbh.brdattr & BRD_HIDE)) {
- getdata_str(14, 0, "³]©wŪ¼gÅv­­(Y/N)¡H", ans, sizeof(ans), LCECHO, "N");
- if (*ans == 'y') {
- getdata_str(15, 0, "­­¨î [R]¾\\Ū (P)µoªí¡H", ans, sizeof(ans), LCECHO,
- "R");
- if (*ans == 'p')
- newbh.brdattr |= BRD_POSTMASK;
- else
- newbh.brdattr &= ~BRD_POSTMASK;
-
- move(1, 0);
- clrtobot();
- bperm_msg(&newbh);
- newbh.level = setperms(newbh.level, str_permid);
- clear();
- }
- }
-
- getdata(b_lines - 1, 0, "½Ð±z½T©w(Y/N)¡H[Y]", genbuf, 4, LCECHO);
-
- if ((*genbuf != 'n') && memcmp(&newbh, &bh, sizeof(bh))) {
- char buf[64];
-
- if (strcmp(bh.brdname, newbh.brdname)) {
- char src[60], tar[60];
-
- setbpath(src, bh.brdname);
- setbpath(tar, newbh.brdname);
- Rename(src, tar);
-
- setapath(src, bh.brdname);
- setapath(tar, newbh.brdname);
- Rename(src, tar);
- }
- setup_man(&newbh, &bh);
- assert(0<=bid-1 && bid-1<MAX_BOARD);
- substitute_record(fn_board, &newbh, sizeof(newbh), bid);
- reset_board(bid);
- sort_bcache();
- log_usies("SetBoard", newbh.brdname);
-
- snprintf(buf, sizeof(buf), "[¬ÝªOÅܧó] %s (by %s)", bh.brdname, cuser.userid);
- snprintf(genbuf, sizeof(genbuf),
- "ªO¦W: %s => %s\n"
- "ªO¥D: %s => %s\n",
- bh.brdname, newbh.brdname, bh.BM, newbh.BM);
- post_msg(GLOBAL_SECURITY, buf, genbuf, "[¨t²Î¦w¥þ§½]");
- }
- }
- return 0;
-}
-
-/* ³]©w¬ÝªO */
-int
-m_board(void)
-{
- char bname[32];
-
- stand_title("¬ÝªO³]©w");
- CompleteBoardAndGroup(msg_bid, bname);
- if (!*bname)
- return 0;
- m_mod_board(bname);
- return 0;
-}
-
-/* ³]©w¨t²ÎÀÉ®× */
-int
-x_file(void)
-{
- int aborted, num;
- char ans[4], *fpath, buf[256];
-
- move(b_lines - 7, 0);
- /* Ptt */
- outs("³]©w (1)¨­¥÷½T»{«H (4)postª`·N¨Æ¶µ (5)¿ù»~µn¤J°T®§ (6)µù¥U½d¨Ò (7)³q¹L½T»{³qª¾\n");
- outs(" (8)email post³qª¾ (9)¨t²Î¥\\¯àºëÆF (A)¯ù¼Ó (B)¯¸ªø¦W³æ (C)email³q¹L½T»{\n");
- outs(" (D)·s¨Ï¥ÎªÌ»Ýª¾ (E)¨­¥÷½T»{¤èªk (F)Åwªïµe­± (G)¶i¯¸µe­± "
-#ifdef MULTI_WELCOME_LOGIN
- "(X)§R°£¶i¯¸µe­±"
-#endif
- "\n");
- outs(" (H)¬ÝªO´Á­­ (I)¬G¶m (J)¥X¯¸µe­± (K)¥Í¤é¥d (L)¸`¤é (M)¥~Äy¨Ï¥ÎªÌ»{ÃÒ³qª¾\n");
- outs(" (N)¥~Äy¨Ï¥ÎªÌ¹L´Áĵ§i³qª¾ (O)¬ÝªO¦Cªí help (P)¤å³¹¦Cªí help\n");
-#ifdef PLAY_ANGEL
- outs(" (R)¤p¤Ñ¨Ï»{ÃÒ³qª¾ (S)¤p¤Ñ¨Ï¥\\¯à»¡©ú\n");
-#endif
- getdata(b_lines - 1, 0, "[Q]¨ú®ø[1-9 A-P]¡H", ans, sizeof(ans), LCECHO);
-
- switch (ans[0]) {
- case '1':
- fpath = "etc/confirm";
- break;
- case '4':
- fpath = "etc/post.note";
- break;
- case '5':
- fpath = "etc/goodbye";
- break;
- case '6':
- fpath = "etc/register";
- break;
- case '7':
- fpath = "etc/registered";
- break;
- case '8':
- fpath = "etc/emailpost";
- break;
- case '9':
- fpath = "etc/hint";
- break;
- case 'b':
- fpath = "etc/sysop";
- break;
- case 'c':
- fpath = "etc/bademail";
- break;
- case 'd':
- fpath = "etc/newuser";
- break;
- case 'e':
- fpath = "etc/justify";
- break;
- case 'f':
- fpath = "etc/Welcome";
- break;
- case 'g':
-#ifdef MULTI_WELCOME_LOGIN
- getdata(b_lines - 1, 0, "²Ä´X­Ó¶i¯¸µe­±[0-4]", ans, sizeof(ans), LCECHO);
- if (ans[0] == '1') {
- fpath = "etc/Welcome_login.1";
- } else if (ans[0] == '2') {
- fpath = "etc/Welcome_login.2";
- } else if (ans[0] == '3') {
- fpath = "etc/Welcome_login.3";
- } else if (ans[0] == '4') {
- fpath = "etc/Welcome_login.4";
- } else {
- fpath = "etc/Welcome_login.0";
- }
-#else
- fpath = "etc/Welcome_login";
-#endif
- break;
-
-#ifdef MULTI_WELCOME_LOGIN
- case 'x':
- getdata(b_lines - 1, 0, "²Ä´X­Ó¶i¯¸µe­±[1-4]", ans, sizeof(ans), LCECHO);
- if (ans[0] == '1') {
- unlink("etc/Welcome_login.1");
- vmsg("ok");
- } else if (ans[0] == '2') {
- unlink("etc/Welcome_login.2");
- vmsg("ok");
- } else if (ans[0] == '3') {
- unlink("etc/Welcome_login.3");
- vmsg("ok");
- } else if (ans[0] == '4') {
- unlink("etc/Welcome_login.4");
- vmsg("ok");
- } else {
- vmsg("©Ò«ü©wªº¶i¯¸µe­±µLªk§R°£");
- }
- return FULLUPDATE;
-
-#endif
-
- case 'h':
- fpath = "etc/expire.conf";
- break;
- case 'i':
- fpath = "etc/domain_name_query.cidr";
- break;
- case 'j':
- fpath = "etc/Logout";
- break;
- case 'k':
- mouts(b_lines - 3, 0, "1.¼¯½~ 2.¤ô²~ 3.Âù³½ 4.¨d¦Ï 5.ª÷¤û 6.Âù¤l");
- mouts(b_lines - 2, 0, "7.¥¨ÃÉ 8.·à¤l 9.³B¤k 10.¤Ñ¯¯ 11.¤ÑÃÈ 12.®g¤â");
- getdata(b_lines - 1, 0, "½Ð¿ï¾Ü [1-12]", ans, sizeof(ans), LCECHO);
- num = atoi(ans);
- if (num <= 0 || num > 12)
- return FULLUPDATE;
- snprintf(buf, sizeof(buf), "etc/Welcome_birth.%d", num);
- fpath = buf;
- break;
- case 'l':
- fpath = "etc/feast";
- break;
- case 'm':
- fpath = "etc/foreign_welcome";
- break;
- case 'n':
- fpath = "etc/foreign_expired_warn";
- break;
- case 'o':
- fpath = "etc/boardlist.help";
- break;
- case 'p':
- fpath = "etc/board.help";
- break;
-
-#ifdef PLAY_ANGEL
- case 'r':
- fpath = "etc/angel_notify";
- break;
-
- case 's':
- fpath = "etc/angel_usage";
- break;
-#endif
-
- default:
- return FULLUPDATE;
- }
- aborted = vedit(fpath, NA, NULL);
- vmsgf("\n\n¨t²ÎÀÉ®×[%s]: %s", fpath,
- (aborted == -1) ? "¥¼§ïÅÜ" : "§ó·s§¹²¦");
- return FULLUPDATE;
-}
-
-static int add_board_record(const boardheader_t *board)
-{
- int bid;
- if ((bid = getbnum("")) > 0) {
- assert(0<=bid-1 && bid-1<MAX_BOARD);
- substitute_record(fn_board, board, sizeof(boardheader_t), bid);
- reset_board(bid);
- sort_bcache();
- } else if (append_record(fn_board, (fileheader_t *)board, sizeof(boardheader_t)) == -1) {
- return -1;
- } else {
- addbrd_touchcache();
- }
- return 0;
-}
-
-/**
- * open a new board
- * @param whatclass In which sub class
- * @param recover Forcely open a new board, often used for recovery.
- * @return -1 if failed
- */
-int
-m_newbrd(int whatclass, int recover)
-{
- boardheader_t newboard;
- char ans[4];
- char genbuf[200];
-
- stand_title("«Ø¥ß·sªO");
- memset(&newboard, 0, sizeof(newboard));
-
- newboard.gid = whatclass;
- if (newboard.gid == 0) {
- vmsg("½Ð¥ý¿ï¾Ü¤@­ÓÃþ§O¦A¶}ªO!");
- return -1;
- }
- do {
- if (!getdata(3, 0, msg_bid, newboard.brdname,
- sizeof(newboard.brdname), DOECHO))
- return -1;
- } while (invalid_brdname(newboard.brdname));
-
- do {
- getdata(6, 0, "¬ÝªOÃþ§O¡G", genbuf, 5, DOECHO);
- if (strlen(genbuf) == 4)
- break;
- } while (1);
-
- strcpy(newboard.title, genbuf);
-
- newboard.title[4] = ' ';
-
- getdata(8, 0, "¬ÝªO¥DÃD¡G", genbuf, BTLEN + 1, DOECHO);
- if (genbuf[0])
- strlcpy(newboard.title + 7, genbuf, sizeof(newboard.title) - 7);
- setbpath(genbuf, newboard.brdname);
-
- if (!recover &&
- (getbnum(newboard.brdname) > 0 || mkdir(genbuf, 0755) == -1)) {
- vmsg("¦¹¬ÝªO¤w¸g¦s¦b! ½Ð¨ú¤£¦P­^¤åªO¦W");
- return -1;
- }
- newboard.brdattr = BRD_NOTRAN;
-#ifdef DEFAULT_AUTOCPLOG
- newboard.brdattr |= BRD_CPLOG;
-#endif
-
- if (HasUserPerm(PERM_SYSOP)) {
- move(1, 0);
- clrtobot();
- newboard.brdattr = setperms(newboard.brdattr, str_permboard);
- move(1, 0);
- clrtobot();
- }
- getdata(9, 0, "¬O¬ÝªO? (N:¥Ø¿ý) (Y/n)¡G", genbuf, 3, LCECHO);
- if (genbuf[0] == 'n')
- {
- newboard.brdattr |= BRD_GROUPBOARD;
- newboard.brdattr &= ~BRD_CPLOG;
- }
-
- {
- const char* brd_symbol;
- if (newboard.brdattr & BRD_GROUPBOARD)
- brd_symbol = "£U";
- else if (newboard.brdattr & BRD_NOTRAN)
- brd_symbol = "¡·";
- else
- brd_symbol = "¡´";
-
- newboard.title[5] = brd_symbol[0];
- newboard.title[6] = brd_symbol[1];
- }
-
- newboard.level = 0;
- getdata(11, 0, "ªO¥D¦W³æ¡G", newboard.BM, sizeof(newboard.BM), DOECHO);
-#ifdef CHESSCOUNTRY
- if (getdata_str(12, 0, "³]©w´Ñ°ê (0)µL (1)¤­¤l´Ñ (2)¶H´Ñ (3)³ò´Ñ", ans,
- sizeof(ans), LCECHO, "0")){
- newboard.chesscountry = atoi(ans);
- if (newboard.chesscountry > CHESSCODE_MAX ||
- newboard.chesscountry < CHESSCODE_NONE)
- newboard.chesscountry = CHESSCODE_NONE;
- }
-#endif /* defined(CHESSCOUNTRY) */
-
- if (HasUserPerm(PERM_SYSOP) && !(newboard.brdattr & BRD_HIDE)) {
- getdata_str(14, 0, "³]©wŪ¼gÅv­­(Y/N)¡H", ans, sizeof(ans), LCECHO, "N");
- if (*ans == 'y') {
- getdata_str(15, 0, "­­¨î [R]¾\\Ū (P)µoªí¡H", ans, sizeof(ans), LCECHO, "R");
- if (*ans == 'p')
- newboard.brdattr |= BRD_POSTMASK;
- else
- newboard.brdattr &= (~BRD_POSTMASK);
-
- move(1, 0);
- clrtobot();
- bperm_msg(&newboard);
- newboard.level = setperms(newboard.level, str_permid);
- clear();
- }
- }
-
- add_board_record(&newboard);
- getbcache(whatclass)->childcount = 0;
- pressanykey();
- setup_man(&newboard, NULL);
- outs("\n·sªO¦¨¥ß");
- post_newboard(newboard.title, newboard.brdname, newboard.BM);
- log_usies("NewBoard", newboard.title);
- pressanykey();
- return 0;
-}
-
-int make_symbolic_link(const char *bname, int gid)
-{
- boardheader_t newboard;
- int bid;
-
- bid = getbnum(bname);
- if(bid==0) return -1;
- assert(0<=bid-1 && bid-1<MAX_BOARD);
- memset(&newboard, 0, sizeof(newboard));
-
- /*
- * known issue:
- * These two stuff will be used for sorting. But duplicated brdnames
- * may cause wrong binary-search result. So I replace the last
- * letters of brdname to '~'(ascii code 126) in order to correct the
- * resuilt, thought I think it's a dirty solution.
- *
- * Duplicate entry with same brdname may cause wrong result, if
- * searching by key brdname. But people don't need to know a board
- * is symbolic, so just let SYSOP know it. You may want to read
- * board.c:load_boards().
- */
-
- strlcpy(newboard.brdname, bname, sizeof(newboard.brdname));
- newboard.brdname[strlen(bname) - 1] = '~';
- strlcpy(newboard.title, bcache[bid - 1].title, sizeof(newboard.title));
- strcpy(newboard.title + 5, "¢I¬ÝªO³sµ²");
-
- newboard.gid = gid;
- BRD_LINK_TARGET(&newboard) = bid;
- newboard.brdattr = BRD_NOTRAN | BRD_SYMBOLIC;
-
- if (add_board_record(&newboard) < 0)
- return -1;
- return bid;
-}
-
-int make_symbolic_link_interactively(int gid)
-{
- char buf[32];
-
- CompleteBoard(msg_bid, buf);
- if (!buf[0])
- return -1;
-
- stand_title("«Ø¥ß¬ÝªO³sµ²");
-
- if (make_symbolic_link(buf, gid) < 0) {
- vmsg("¬ÝªO³sµ²«Ø¥ß¥¢±Ñ");
- return -1;
- }
- log_usies("NewSymbolic", buf);
- return 0;
-}
-
-static void
-give_id_money(const char *user_id, int money, const char *mail_title)
-{
- char tt[TTLEN + 1] = {0};
-
- if (deumoney(searchuser(user_id, NULL), money) < 0) { // TODO if searchuser() return 0
- move(12, 0);
- clrtoeol();
- prints("id:%s money:%d ¤£¹ï§a!!", user_id, money);
- pressanykey();
- } else {
- snprintf(tt, sizeof(tt), "%s : %d " MONEYNAME " ¹ô", mail_title, money);
- mail_id(user_id, tt, "etc/givemoney.why", "[PTT »È¦æ]");
- }
-}
-
-int
-give_money(void)
-{
- FILE *fp, *fp2;
- char *ptr, *id, *mn;
- char buf[200] = "", reason[100], tt[TTLEN + 1] = "";
- int to_all = 0, money = 0;
- int total_money=0, count=0;
-
- getdata(0, 0, "«ü©w¨Ï¥ÎªÌ(S) ¥þ¯¸¨Ï¥ÎªÌ(A) ¨ú®ø(Q)¡H[S]", buf, 3, LCECHO);
- if (buf[0] == 'q')
- return 1;
- else if (buf[0] == 'a') {
- to_all = 1;
- getdata(1, 0, "µo¦h¤Ö¿ú©O?", buf, 20, DOECHO);
- money = atoi(buf);
- if (money <= 0) {
- move(2, 0);
- vmsg("¿é¤J¿ù»~!!");
- return 1;
- }
- } else {
- if (vedit("etc/givemoney.txt", NA, NULL) < 0)
- return 1;
- }
-
- clear();
-
- unlink("etc/givemoney.log");
- if (!(fp2 = fopen("etc/givemoney.log", "w")))
- return 1;
-
- getdata(0, 0, "°Ê¥Î°ê®w!½Ð¿é¤J¥¿·í²z¥Ñ(¦p¬¡°Ê¦WºÙ):", reason, 40, LCECHO);
- fprintf(fp2,"\n¨Ï¥Î²z¥Ñ: %s\n", reason);
-
- getdata(1, 0, "­nµo¿ú¤F¶Ü(Y/N)[N]", buf, 3, LCECHO);
- if (buf[0] != 'y')
- {
- fclose(fp2);
- return 1;
- }
-
- getdata(1, 0, "¬õ¥]³U¼ÐÃD ¡G", tt, TTLEN, DOECHO);
- fprintf(fp2,"\n¬õ¥]³U¼ÐÃD: %s\n", tt);
- move(2, 0);
-
- vmsg("½s¬õ¥]³U¤º®e");
- if (vedit("etc/givemoney.why", NA, NULL) < 0) {
- fclose(fp2);
- return 1;
- }
-
- stand_title("µo¿ú¤¤...");
- if (to_all) {
- int i, unum;
- for (unum = SHM->number, i = 0; i < unum; i++) {
- if (bad_user_id(SHM->userid[i]))
- continue;
- id = SHM->userid[i];
- give_id_money(id, money, tt);
- fprintf(fp2,"µ¹ %s : %d\n", id, money);
- count++;
- }
- sprintf(buf, "(%d¤H:%d"MONEYNAME"¹ô)", count, count*money);
- strcat(reason, buf);
- } else {
- if (!(fp = fopen("etc/givemoney.txt", "r+"))) {
- fclose(fp2);
- return 1;
- }
- while (fgets(buf, sizeof(buf), fp)) {
- clear();
- if (!(ptr = strchr(buf, ':')))
- continue;
- *ptr = '\0';
- id = buf;
- mn = ptr + 1;
- money = atoi(mn);
- give_id_money(id, money, tt);
- fprintf(fp2,"µ¹ %s : %d\n", id, money);
- total_money += money;
- count++;
- }
- fclose(fp);
- sprintf(buf, "(%d¤H:%d"MONEYNAME"¹ô)", count, total_money);
- strcat(reason, buf);
-
- }
-
- fclose(fp2);
-
- sprintf(buf, "%s ¬õ¥]¾÷: %s", cuser.userid, reason);
- post_file(GLOBAL_SECURITY, buf, "etc/givemoney.log", "[¬õ¥]¾÷³ø§i]");
- pressanykey();
- return FULLUPDATE;
-}
diff --git a/mbbsd/aids.c b/mbbsd/aids.c
deleted file mode 100644
index 56d19378..00000000
--- a/mbbsd/aids.c
+++ /dev/null
@@ -1,290 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-#error "Not complete yet"
-
-aidu_t fn2aidu(char *fn)
-{
- aidu_t aidu = 0;
- aidu_t type = 0;
- aidu_t v1 = 0;
- aidu_t v2 = 0;
- char *sp = fn;
-
- if(fn == NULL)
- return 0;
-
- switch(*(sp ++))
- {
- case 'M':
- type = 0;
- break;
- case 'G':
- type = 1;
- break;
- default:
- return 0;
- break;
- }
-
- if(*(sp ++) != '.')
- return 0;
- v1 = strtoul(sp, &sp, 10);
- if(sp == NULL)
- return 0;
- if(*sp != '.' || *(sp + 1) != 'A')
- return 0;
- sp += 2;
- if(*(sp ++) == '.')
- {
- v2 = strtoul(sp, &sp, 16);
- if(sp == NULL)
- return 0;
- }
- aidu = ((type & 0xf) << 44) | ((v1 & 0xffffffff) << 12) | (v2 & 0xfff);
-
- return aidu;
-}
-
-/* IMPORTANT:
- * size of buf must be at least 8+1 bytes
- */
-char *aidu2aidc(char *buf, aidu_t aidu)
-{
- const char aidu2aidc_table[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_";
- const int aidu2aidc_tablesize = sizeof(aidu2aidc_table) - 1;
- char *sp = buf + 8;
- aidu_t v;
-
- *(sp --) = '\0';
- while(sp >= buf)
- {
- /* FIXME: ¯à«OÃÒ aidu2aidc_tablesize ¬O 2 ªº¾­¦¸ªº¸Ü¡A
- ³o¸Ì¥i¥H§ï¥Î bitwise operation °µ */
- v = aidu % aidu2aidc_tablesize;
- aidu = aidu / aidu2aidc_tablesize;
- *(sp --) = aidu2aidc_table[v];
- }
- return buf;
-}
-
-/* IMPORTANT:
- * size of fn must be at least FNLEN bytes
- */
-char *aidu2fn(char *fn, aidu_t aidu)
-{
- aidu_t type = ((aidu >> 44) & 0xf);
- aidu_t v1 = ((aidu >> 12) & 0xffffffff);
- aidu_t v2 = (aidu & 0xfff);
-
- if(fn == NULL)
- return NULL;
- snprintf(fn, FNLEN, "%c.%d.A.%03X", ((type == 0) ? 'M' : 'G'), (unsigned int)v1, (unsigned int)v2);
- return fn;
-}
-
-aidu_t aidc2aidu(char *aidc)
-{
- char *sp = aidc;
- aidu_t aidu = 0;
-
- if(aidc == NULL)
- return 0;
-
- while(*sp != '\0' && /* ignore trailing spaces */ *sp != ' ')
- {
- aidu_t v = 0;
- /* FIXME: ¬dªíªk·|¤£·|¤ñ¸û§Ö¡H */
- if(*sp >= '0' && *sp <= '9')
- v = *sp - '0';
- else if(*sp >= 'A' && *sp <= 'Z')
- v = *sp - 'A' + 10;
- else if(*sp >= 'a' && *sp <= 'z')
- v = *sp - 'a' + 36;
- else if(*sp == '-')
- v = 62;
- else if(*sp == '_')
- v = 63;
- else if(*sp == '@')
- break;
- else
- return 0;
- aidu <<= 6;
- aidu |= (v & 0x3f);
- sp ++;
- }
-
- return aidu;
-}
-
-int search_aidu_in_bfile(char *bfile, aidu_t aidu)
-{
- char fn[FNLEN];
- int fd;
- fileheader_t fhs[64];
- int len, i;
- int pos = 0;
- int found = 0;
- int lastpos = 0;
-
- if(aidu2fn(fn, aidu) == NULL)
- return -1;
- if((fd = open(bfile, O_RDONLY, 0)) < 0)
- return -1;
-
- while(!found && (len = read(fd, fhs, sizeof(fhs))) > 0)
- {
- len /= sizeof(fileheader_t);
- for(i = 0; i < len; i ++)
- {
- int l;
- if(strcmp(fhs[i].filename, fn) == 0 ||
- ((aidu & 0xfff) == 0 && (l = strlen(fhs[i].filename)) > 6 &&
- strncmp(fhs[i].filename, fn, l) == 0))
- {
- if(fhs[i].filemode & FILE_BOTTOM)
- {
- lastpos = pos;
- }
- else
- {
- found = 1;
- break;
- }
- }
- pos ++;
- }
- }
- close(fd);
-
- return (found ? pos : (lastpos ? lastpos : -1));
-}
-
-SearchAIDResult_t search_aidu_in_board(char *bname, aidu_t aidu)
-{
- SearchAIDResult_t r = {AIDR_BOARD, -1}:
- int n = -1;
- char dirfile[PATHLEN];
-
- {
- char bf[FNLEN];
-
- snprintf(bf, FNLEN, "%s.bottom", FN_DIR);
- setbfile(dirfile, bname, bf);
- if((n = search_aidu_in_bfile(dirfile, aidu)) >= 0)
- {
- r.where = AIDR_BOTTOM;
- r.n = n;
- }
- }
- if(r.n < 0)
- {
- setbfile(dirfile, bname, FN_DIR);
- if((n = search_aidu_in_bfile(dirfile, aidu)) >= 0)
- {
- r.where = AIDR_BOARD;
- r.n = n;
- }
- }
- if(r.n < 0)
- {
- setbfile(dirfile, bname, fn_mandex);
- if((n = search_aidu_in_bfile(dirfile, aidu)) >= 0)
- {
- r.where = AIDR_DIGEST;
- r.n = n;
- }
- }
- return r;
-}
-
-SearchAIDResult_t do_search_aid(void)
-{
- SearchAIDResult_t r = {AIDR_BOARD, -1};
- char aidc[100];
- char bname[IDLEN + 1] = "";
- aidu_t aidu = 0;
- char *sp;
- char *sp2;
- char *emsg = NULL;
-
- if(!getdata(b_lines, 0, "·j´M" AID_DISPLAYNAME ": #", aidc, 15 + IDLEN, LCECHO))
- {
- move(b_lines, 0);
- clrtorol();
- r.n = -1;
- return r;
- }
-
- if(currstat == RMAIL)
- {
- move(21, 0);
- clrtobot();
- move(22, 0);
- prints("¦¹ª¬ºA¤UµLªk·j´M" AID_DISPLAYNAME);
- pressanykey();
- r.n = -1;
- return r;
- }
-
- sp = aidc;
- while(*sp == ' ')
- sp ++;
- while(*sp == '#')
- sp ++;
- aidu = aidc2aidu(sp);
- if((sp2 = strchr(sp, '@')) != NULL)
- {
- // assert(sizeof(bname) > IDLEN);
- strlcpy(bname, sp2 + 1, IDLEN+1);
- *sp2 = '\0';
- }
- else
- bname[0] = '\0';
-
- if(aidu > 0)
- {
- if(bname[0] != '\0')
- {
- if(!HasBoardPerm_bn(bname))
- return FULLUPDATE;
- r = search_aidu_in_board(bname, aidu);
- if(r.n >= 0)
- {
- if(enter_board(bname) < 0)
- {
- r.n = -1;
- emsg = "¿ù»~¡GµLªk¶i¤J«ü©wªº¬ÝªO %s";
- }
- }
- }
- else
- {
- r = search_aidu_in_board(currboard, aidu);
- }
- }
-
- if(r.n < 0)
- {
- if(aidu == 0)
- emsg = "¤£¦Xªkªº" AID_DISPLAYNAME "¡A½Ð½T©w¿é¤J¬O¥¿½Tªº";
- else if(emsg == NULL)
- {
- if(bname[0] != '\0')
- emsg = "¬ÝªO %s ¤º§ä¤£¨ì³o­Ó" AID_DISPLAYNAME "¡A¥i¯à¬O¤å³¹¤w¸g®ø¥¢¡A©Î¬O§ä¿ù¬ÝªO¤F";
- else
- emsg = "§ä¤£¨ì³o­Ó" AID_DISPLAYNAME "¡A¥i¯à¬O¤å³¹¤w¸g®ø¥¢¡A©Î¬O§ä¿ù¬ÝªO¤F";
- }
- move(21, 0);
- clrtoeol();
- move(22, 0);
- prints(emsg, bname);
- pressanykey();
- r.n = -1;
- return r;
- }
- else
- {
- return r;
- }
-}
diff --git a/mbbsd/alloc.c b/mbbsd/alloc.c
deleted file mode 100644
index de676ce4..00000000
--- a/mbbsd/alloc.c
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * malloc/free by O.Dreesen
- *
- * first TRY:
- * lists w/magics
- * and now the second TRY
- * let the kernel map all the stuff (if there is something to do)
- */
-
-#include <unistd.h>
-#include <sys/mman.h>
-#include <errno.h>
-
-#include <sys/cdefs.h>
-#include <sys/types.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <sys/shm.h> /* for PAGE_SIZE */
-
-
-/* -- HELPER CODE --------------------------------------------------------- */
-
-#ifndef MAP_FAILED
-#define MAP_FAILED ((void*)-1)
-#endif
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
-typedef struct {
- void* next;
- size_t size;
-} __alloc_t;
-
-#define BLOCK_START(b) (((void*)(b))-sizeof(__alloc_t))
-#define BLOCK_RET(b) (((void*)(b))+sizeof(__alloc_t))
-
-#define MEM_BLOCK_SIZE PAGE_SIZE
-#define PAGE_ALIGN(s) (((s)+MEM_BLOCK_SIZE-1)&(unsigned long)(~(MEM_BLOCK_SIZE-1)))
-
-/* a simple mmap :) */
-#if defined(__i386__)
-#define REGPARM(x) __attribute__((regparm(x)))
-#else
-#define REGPARM(x)
-#endif
-
-static void REGPARM(1) *do_mmap(size_t size) {
- return mmap(0, size, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, (size_t)0);
-}
-
-/* -- SMALL MEM ----------------------------------------------------------- */
-
-static __alloc_t* __small_mem[8];
-
-static int smallalloc[8];
-static int smallalloc_max[8];
-
-#define __SMALL_NR(i) (MEM_BLOCK_SIZE/(i))
-
-#define __MIN_SMALL_SIZE __SMALL_NR(256) /* 16 / 32 */
-#define __MAX_SMALL_SIZE __SMALL_NR(2) /* 2048 / 4096 */
-
-#define GET_SIZE(s) (__MIN_SMALL_SIZE<<get_index((s)))
-
-#define FIRST_SMALL(p) (((unsigned long)(p))&(~(MEM_BLOCK_SIZE-1)))
-
-static inline int __ind_shift() { return (MEM_BLOCK_SIZE==4096)?4:5; }
-
-static size_t REGPARM(1) get_index(size_t _size) {
- register size_t idx=0;
-// if (_size) { /* we already check this in the callers */
- register size_t size=((_size-1)&(MEM_BLOCK_SIZE-1))>>__ind_shift();
- while(size) { size>>=1; ++idx; }
-// }
- return idx;
-}
-
-/* small mem */
-static void __small_free(void*_ptr,size_t _size) REGPARM(2);
-
-static void REGPARM(2) __small_free(void*_ptr,size_t _size) {
- __alloc_t* ptr=BLOCK_START(_ptr);
- size_t size=_size;
- size_t idx=get_index(size);
-
- memset(ptr,0,size); /* allways zero out small mem */
-
- ptr->next=__small_mem[idx];
- __small_mem[idx]=ptr;
-
- smallalloc[idx]--;
-
- if (MEM_BLOCK_SIZE == PAGE_SIZE &&
- smallalloc[idx] == 0 &&
- smallalloc_max[idx] < __SMALL_NR(size)) {
- __alloc_t* p = __small_mem[idx];
- __alloc_t* ph = p - (size_t)p%PAGE_SIZE;
- munmap(ph, MEM_BLOCK_SIZE);
- __small_mem[idx] = 0;
- }
-}
-
-static void* REGPARM(1) __small_malloc(size_t _size) {
- __alloc_t *ptr;
- size_t size=_size;
- size_t idx;
-
- idx=get_index(size);
- ptr=__small_mem[idx];
-
- if (ptr==0) { /* no free blocks ? */
- register int i,nr;
- ptr=do_mmap(MEM_BLOCK_SIZE);
- if (ptr==MAP_FAILED) return MAP_FAILED;
-
- __small_mem[idx]=ptr;
-
- nr=__SMALL_NR(size)-1;
- for (i=0;i<nr;i++) {
- ptr->next=(((void*)ptr)+size);
- ptr=ptr->next;
- }
- ptr->next=0;
-
- ptr=__small_mem[idx];
- }
-
- /* get a free block */
- __small_mem[idx]=ptr->next;
- ptr->next=0;
-
- smallalloc[idx]++;
- if(smallalloc[idx] > smallalloc_max[idx])
- smallalloc_max[idx] = smallalloc[idx];
-
- return ptr;
-}
-
-/* -- PUBLIC FUNCTIONS ---------------------------------------------------- */
-
-static void _alloc_libc_free(void *ptr) {
- register size_t size;
- if (ptr) {
- size=((__alloc_t*)BLOCK_START(ptr))->size;
- if (size) {
- if (size<=__MAX_SMALL_SIZE)
- __small_free(ptr,size);
- else
- munmap(BLOCK_START(ptr),size);
- }
- }
-}
-void __libc_free(void *ptr) __attribute__((alias("_alloc_libc_free")));
-void free(void *ptr) __attribute__((weak,alias("_alloc_libc_free")));
-void if_freenameindex(void* ptr) __attribute__((alias("free")));
-
-#ifdef WANT_MALLOC_ZERO
-static __alloc_t zeromem[2];
-#endif
-
-static void* _alloc_libc_malloc(size_t size) {
- __alloc_t* ptr;
- size_t need;
-#ifdef WANT_MALLOC_ZERO
- if (!size) return BLOCK_RET(zeromem);
-#else
- if (!size) goto err_out;
-#endif
- size+=sizeof(__alloc_t);
- if (size<sizeof(__alloc_t)) goto err_out;
- if (size<=__MAX_SMALL_SIZE) {
- need=GET_SIZE(size);
- ptr=__small_malloc(need);
- }
- else {
- need=PAGE_ALIGN(size);
- if (!need) ptr=MAP_FAILED; else ptr=do_mmap(need);
- }
- if (ptr==MAP_FAILED) goto err_out;
- ptr->size=need;
- return BLOCK_RET(ptr);
-err_out:
- (*__errno_location())=ENOMEM;
- return 0;
-}
-void* __libc_malloc(size_t size) __attribute__((alias("_alloc_libc_malloc")));
-void* malloc(size_t size) __attribute__((weak,alias("_alloc_libc_malloc")));
-
-void* __libc_calloc(size_t nmemb, size_t _size);
-void* __libc_calloc(size_t nmemb, size_t _size) {
- register size_t size=_size*nmemb;
- if (nmemb && size/nmemb!=_size) {
- (*__errno_location())=ENOMEM;
- return 0;
- }
- return malloc(size);
-}
-void* calloc(size_t nmemb, size_t _size) __attribute__((weak,alias("__libc_calloc")));
-
-void* __libc_realloc(void* ptr, size_t _size);
-void* __libc_realloc(void* ptr, size_t _size) {
- register size_t size=_size;
- if (ptr) {
- if (size) {
- __alloc_t* tmp=BLOCK_START(ptr);
- size+=sizeof(__alloc_t);
- if (size<sizeof(__alloc_t)) goto retzero;
- size=(size<=__MAX_SMALL_SIZE)?GET_SIZE(size):PAGE_ALIGN(size);
- if (tmp->size!=size) {
- if ((tmp->size<=__MAX_SMALL_SIZE)) {
- void *new=_alloc_libc_malloc(_size);
- if (new) {
- register __alloc_t* foo=BLOCK_START(new);
- size=foo->size;
- if (size>tmp->size) size=tmp->size;
- if (size) memcpy(new,ptr,size-sizeof(__alloc_t));
- _alloc_libc_free(ptr);
- }
- ptr=new;
- }
- else {
- register __alloc_t* foo;
- size=PAGE_ALIGN(size);
- foo=mremap(tmp,tmp->size,size,MREMAP_MAYMOVE);
- if (foo==MAP_FAILED) {
-retzero:
- (*__errno_location())=ENOMEM;
- ptr=0;
- }
- else {
- foo->size=size;
- ptr=BLOCK_RET(foo);
- }
- }
- }
- }
- else { /* size==0 */
- _alloc_libc_free(ptr);
- ptr = NULL;
- }
- }
- else { /* ptr==0 */
- if (size) {
- ptr=_alloc_libc_malloc(size);
- }
- }
- return ptr;
-}
-void* realloc(void* ptr, size_t size) __attribute__((weak,alias("__libc_realloc")));
-
diff --git a/mbbsd/announce.c b/mbbsd/announce.c
deleted file mode 100644
index fb7db427..00000000
--- a/mbbsd/announce.c
+++ /dev/null
@@ -1,1558 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-// XXX piaip 2007/12/29
-// ³Ìªñµo²{«Ü¦h code ³£¦º¦b announce
-// ¦]¬°¶i¨Ó­n¬Ý lastlevel ¦Ó«D currbid
-// user ¥i¯à¤@¶i BBS ª½±þ¶l¥ó->mail_cite->¶iºëµØ°Ï
-// ©ó¬O´NÃz¬µ
-// ¦P²z currboard ¤]¤£¸Ó¥Î
-// ½Ð§ï¥Î me.bid (ª`·N me.bid ¥i¯à¬° 0, ªí¥Ü¶i¨Óªº«D¬ÝªO¡C)
-//
-// XXX 9999 ³Â·Ð·Q­Ó¤è¦¡§ï±¼
-
-// for max file size limitation here, see edit.c
-#define MAX_FILE_SIZE (32768*1024)
-
-/* copy temp queue operation -------------------------------------- */
-
-/* TODO
- * change this to char* instead of char[]
- */
-typedef struct {
- char copyfile[PATHLEN];
- char copytitle[TTLEN + 1];
- char copyowner[IDLEN + 2];
-} CopyQueue ;
-
-#define COPYQUEUE_COMMON_SIZE (10)
-
-static CopyQueue *copyqueue;
-static int allocated_copyqueue = 0, used_copyqueue = 0, head_copyqueue = 0;
-
-int copyqueue_testin(CopyQueue *pcq)
-{
- int i = 0;
- for (i = head_copyqueue; i < used_copyqueue; i++)
- if (strcmp(pcq->copyfile, copyqueue[i].copyfile) == 0)
- return 1;
- return 0;
-}
-
-int copyqueue_locate(CopyQueue *pcq)
-{
- int i = 0;
- for (i = head_copyqueue; i < used_copyqueue; i++)
- if (strcmp(pcq->copyfile, copyqueue[i].copyfile) == 0)
- return i;
- return -1;
-}
-
-int copyqueue_fileinqueue(const char *fn)
-{
- int i = 0;
- for (i = head_copyqueue; i < used_copyqueue; i++)
- if (strcmp(fn, copyqueue[i].copyfile) == 0)
- return 1;
- return 0;
-}
-
-void copyqueue_reset()
-{
- allocated_copyqueue = 0;
- used_copyqueue = 0;
- head_copyqueue = 0;
-}
-
-int copyqueue_append(CopyQueue *pcq)
-{
- if(copyqueue_testin(pcq))
- return 0;
- if(head_copyqueue == used_copyqueue)
- {
- // empty queue, happy happy reset
- if(allocated_copyqueue > COPYQUEUE_COMMON_SIZE)
- {
- // let's reduce it
- allocated_copyqueue = COPYQUEUE_COMMON_SIZE;
- copyqueue = (CopyQueue*)realloc( copyqueue,
- allocated_copyqueue * sizeof(CopyQueue));
- }
- head_copyqueue = used_copyqueue = 0;
- }
- used_copyqueue ++;
-
- if(used_copyqueue > allocated_copyqueue)
- {
- allocated_copyqueue =
- used_copyqueue + COPYQUEUE_COMMON_SIZE; // half page
- copyqueue = (CopyQueue*) realloc (copyqueue,
- sizeof(CopyQueue) * allocated_copyqueue);
- if(!copyqueue)
- {
- vmsg("°O¾ÐÅ餣¨¬¡A«þ¨©¥¢±Ñ");
- // try to reset
- copyqueue_reset();
- if(copyqueue) free(copyqueue);
- copyqueue = NULL;
- return 0;
- }
- }
- memcpy(&(copyqueue[used_copyqueue-1]), pcq, sizeof(CopyQueue));
- return 1;
-}
-
-int copyqueue_toggle(CopyQueue *pcq)
-{
- int i = copyqueue_locate(pcq);
- if(i >= 0)
- {
-#if 0
- if (getans("¤w¼Ð°O¹L¦¹ÀÉ¡A­n¨ú®ø¼Ð°O¶Ü [y/N]: ") != 'y')
- return 1;
-#endif
- /* remove it */
- used_copyqueue --;
- if(head_copyqueue > used_copyqueue)
- head_copyqueue =used_copyqueue;
- if (i < used_copyqueue)
- {
- memcpy(copyqueue + i, copyqueue+i+1,
- sizeof(CopyQueue) * (used_copyqueue - i));
- }
- return 0;
- } else {
- copyqueue_append(pcq);
- }
- return 1;
-}
-
-CopyQueue *copyqueue_gethead()
-{
- if( used_copyqueue <= 0 ||
- head_copyqueue >= used_copyqueue)
- return NULL;
- return &(copyqueue[head_copyqueue++]);
-}
-
-int copyqueue_querysize()
-{
- if( used_copyqueue <= 0 ||
- head_copyqueue >= used_copyqueue)
- return 0;
- return (used_copyqueue - head_copyqueue);
-}
-
-/* end copy temp queue operation ----------------------------------- */
-
-void
-a_copyitem(const char *fpath, const char *title, const char *owner, int mode)
-{
- CopyQueue cq;
- static int flFirstAlert = 1;
-
- memset(&cq, 0, sizeof(CopyQueue));
- strcpy(cq.copyfile, fpath);
- strcpy(cq.copytitle, title);
- if (owner)
- strcpy(cq.copyowner, owner);
-
- //copyqueue_append(&cq);
- copyqueue_toggle(&cq);
- if (mode && flFirstAlert) {
-#if 0
- move(b_lines-2, 0); clrtoeol();
- prints("¥Ø«e¤w¼Ð°O %d ­ÓÀɮסC[ª`·N] «þ¨©«á¤~¯à§R°£­ì¤å!",
- copyqueue_querysize());
-#else
- vmsg("[ª`·N] ´£¿ô±z½Æ»s/¼Ð°O«á­n¶K¤W(p)©Îªþ¥[(a)«á¤~¯à§R°£­ì¤å!");
- flFirstAlert = 0;
-#endif
- }
-}
-
-#define FHSZ sizeof(fileheader_t)
-
-static int
-a_loadname(menu_t * pm)
-{
- char buf[PATHLEN];
- int len;
-
- if(p_lines != pm->header_size) {
- pm->header_size = p_lines;
- pm->header = (fileheader_t *) realloc(pm->header, pm->header_size*FHSZ);
- assert(pm->header);
- }
-
- setadir(buf, pm->path);
- len = get_records(buf, pm->header, FHSZ, pm->page + 1, pm->header_size); // XXX if get_records() return -1
-
- // if len < 0, the directory is not valid anymore.
- if (len < 0)
- return 0;
-
- if (len < pm->header_size)
- bzero(&pm->header[len], FHSZ * (pm->header_size - len));
- return 1;
-}
-
-static void
-a_timestamp(char *buf, const time4_t *time)
-{
- struct tm *pt = localtime4(time);
-
- sprintf(buf, "%02d/%02d/%02d", pt->tm_mon + 1, pt->tm_mday, (pt->tm_year + 1900) % 100);
-}
-
-static int
-a_showmenu(menu_t * pm)
-{
- char *title, *editor;
- int n;
- fileheader_t *item;
- time4_t dtime;
-
- showtitle("ºëµØ¤å³¹", pm->mtitle);
- prints(" " ANSI_COLOR(1;36) "½s¸¹ ¼Ð ÃD%56s" ANSI_COLOR(0),
- "½s ¿ï ¤é ´Á");
-
- if (!pm->num)
- {
- outs("\n ¡mºëµØ°Ï¡n©|¦b§l¨ú¤Ñ¦a¶¡ªº¤é¤ëºëµØ¤¤... :)");
- }
- else
- {
- char buf[PATHLEN];
-
- // determine if path is valid.
- if (!a_loadname(pm))
- return 0;
-
- for (n = 0; n < p_lines && pm->page + n < pm->num; n++) {
- int flTagged = 0;
- item = &pm->header[n];
- title = item->title;
- editor = item->owner;
- /*
- * Ptt §â®É¶¡§ï¬°¨úÀɮ׮ɶ¡ dtime = atoi(&item->filename[2]);
- */
- snprintf(buf, sizeof(buf), "%s/%s", pm->path, item->filename);
- if(copyqueue_querysize() > 0 && copyqueue_fileinqueue(buf))
- {
- flTagged = 1;
- }
- dtime = dasht(buf);
- a_timestamp(buf, &dtime);
- prints("\n%6d%c%c%-47.46s%-13s[%s]", pm->page + n + 1,
- (item->filemode & FILE_BM) ? 'X' :
- (item->filemode & FILE_HIDE) ? ')' : '.',
- flTagged ? 'c' : ' ',
- title, editor,
- buf);
- }
- }
-
- move(b_lines, 0);
- if(copyqueue_querysize() > 0)
- { // something in queue
- prints(
- ANSI_COLOR(37;44) "¡i¤w¼Ð°O(½Æ»s) %d ¶µ¡j"
- ANSI_COLOR(31;47) " (c)" ANSI_COLOR(30) "¼Ð°O/½Æ»s "
- , copyqueue_querysize());
-
- if(pm->level == 0)
- outs(" - µLºÞ²zÅv­­¡AµLªk¶K¤W " ANSI_RESET);
- else
- outs( ANSI_COLOR(31) "(p)" ANSI_COLOR(30) "¶K¤W/¨ú®ø/­«³]¼Ð°O "
- ANSI_COLOR(31) "(a)" ANSI_COLOR(30) "ªþ¥[¦Ü¤å³¹«á "
- ANSI_RESET);
- }
- else if(pm->level)
- { // BM
- outs(
- ANSI_COLOR(34;46) " ¡iªO ¥D¡j "
- ANSI_COLOR(31;47) " (h)" ANSI_COLOR(30) "»¡©ú "
- ANSI_COLOR(31) "(q/¡ö)" ANSI_COLOR(30) "Â÷¶} "
- ANSI_COLOR(31) "(n)" ANSI_COLOR(30) "·s¼W¤å³¹ "
- ANSI_COLOR(31) "(g)" ANSI_COLOR(30) "·s¼W¥Ø¿ý "
- ANSI_COLOR(31) "(e)" ANSI_COLOR(30) "½s¿èÀÉ®× " ANSI_RESET
- );
- }
- else
- { // normal user
- outs(
- ANSI_COLOR(34;46) " ¡i¥\\¯àÁä¡j "
- ANSI_COLOR(31;47) " (h)" ANSI_COLOR(30) "»¡©ú "
- ANSI_COLOR(31) "(q/¡ö)" ANSI_COLOR(30) "Â÷¶} "
- ANSI_COLOR(31) "(k¡ôj¡õ)" ANSI_COLOR(30) "²¾°Ê´å¼Ð "
- ANSI_COLOR(31) "(enter/¡÷)" ANSI_COLOR(30) "Ū¨ú¸ê®Æ " ANSI_RESET);
- }
- return 1;
-}
-
-static int
-a_searchtitle(menu_t * pm, int rev)
-{
- static char search_str[40] = "";
- int pos;
-
- getdata(b_lines - 1, 1, "[·j´M]ÃöÁä¦r:", search_str, sizeof(search_str), DOECHO);
-
- if (!*search_str)
- return pm->now;
-
- str_lower(search_str, search_str);
-
- rev = rev ? -1 : 1;
- pos = pm->now;
- do {
- pos += rev;
- if (pos == pm->num)
- pos = 0;
- else if (pos < 0)
- pos = pm->num - 1;
- if (pos < pm->page || pos >= pm->page + p_lines) {
- pm->page = pos - pos % p_lines;
-
- if (!a_loadname(pm))
- return pm->now;
- }
- if (strcasestr(pm->header[pos - pm->page].title, search_str))
- return pos;
- } while (pos != pm->now);
- return pm->now;
-}
-
-enum {
- NOBODY, MANAGER, SYSOP
-};
-
-static void
-a_showhelp(int level)
-{
- clear();
- outs(ANSI_COLOR(36) "¡i " BBSNAME "¤½§GÄæ¨Ï¥Î»¡©ú ¡j" ANSI_RESET "\n\n"
- "[¡ö][q] Â÷¶}¨ì¤W¤@¼h¥Ø¿ý\n"
- "[¡ô][k] ¤W¤@­Ó¿ï¶µ\n"
- "[¡õ][j] ¤U¤@­Ó¿ï¶µ\n"
- "[¡÷][r][enter] ¶i¤J¥Ø¿ý¡þŪ¨ú¤å³¹\n"
- "[^B][PgUp] ¤W­¶¿ï³æ\n"
- "[^F][PgDn][Spc] ¤U­¶¿ï³æ\n"
- "[##] ²¾¨ì¸Ó¿ï¶µ\n"
- "[F][U] ±N¤å³¹±H¦^ Internet ¶l½c/"
- "±N¤å³¹ uuencode «á±H¦^¶l½c\n");
- if (level >= MANAGER) {
- outs("\n" ANSI_COLOR(36) "¡i ªO¥D±M¥ÎÁä ¡j" ANSI_RESET "\n"
- "[H] ¤Á´«¬° ¤½¶}/·|­û/ªO¥D ¤~¯à¾\\Ū\n"
- "[n/g/G] ¦¬¿ýºëµØ¤å³¹/¶}ÅP¥Ø¿ý/«Ø¥ß³s½u\n"
- "[m/d/D] ²¾°Ê/§R°£¤å³¹/§R°£¤@­Ó½d³òªº¤å³¹\n"
- "[f/T/e] ½s¿è¼ÐÃD²Å¸¹/­×§ï¤å³¹¼ÐÃD/¤º®e\n"
- "[c/p/a] ºëµØ°Ï¤º ¼Ð°O(½Æ»s)/¶K¤W(¥i¦h½g)/ªþ¥[³æ½g¤å³¹\n"
- "[^P/^A] ¶K¤W/ªþ¥[ºëµØ°Ï¥~¤w¥Î't'¼Ð°O¤å³¹\n");
- }
- if (level >= SYSOP) {
- outs("\n" ANSI_COLOR(36) "¡i ¯¸ªø±M¥ÎÁä ¡j" ANSI_RESET "\n"
- "[l] «Ø symbolic link\n"
- "[N] ¬d¸ßÀɦW\n");
- }
- pressanykey();
-}
-
-static void
-a_forward(const char *path, const fileheader_t * pitem, int mode)
-{
- fileheader_t fhdr;
-
- strlcpy(fhdr.filename, pitem->filename, sizeof(fhdr.filename));
- strlcpy(fhdr.title, pitem->title, sizeof(fhdr.title));
- switch (doforward(path, &fhdr, mode)) {
- case 0:
- outmsg(msg_fwd_ok);
- break;
- case -1:
- outmsg(msg_fwd_err1);
- break;
- case -2:
- outmsg(msg_fwd_err2);
- break;
- }
-}
-
-static void
-a_additem(menu_t * pm, const fileheader_t * myheader)
-{
- char buf[PATHLEN];
-
- setadir(buf, pm->path);
- if (append_record(buf, myheader, FHSZ) == -1)
- return;
- pm->now = pm->num++;
-
- if (pm->now >= pm->page + p_lines) {
- pm->page = pm->now - ((pm->page == 10000 && pm->now > p_lines / 2) ?
- (p_lines / 2) : (pm->now % p_lines));
- }
- /* Ptt */
- strlcpy(pm->header[pm->now - pm->page].filename,
- myheader->filename,
- sizeof(pm->header[pm->now - pm->page].filename));
-}
-
-#define ADDITEM 0
-#define ADDGROUP 1
-
-static void
-a_newitem(menu_t * pm, int mode)
-{
- char *mesg[3] = {
- "[·s¼W¤å³¹] ½Ð¿é¤J¼ÐÃD¡G", /* ADDITEM */
- "[·s¼W¥Ø¿ý] ½Ð¿é¤J¼ÐÃD¡G", /* ADDGROUP */
- };
-
- char fpath[PATHLEN];
- fileheader_t item;
-
- strlcpy(fpath, pm->path, sizeof(fpath));
- if (strlen(pm->path) + FNLEN*2 >= PATHLEN)
- return;
-
- switch (mode) {
- case ADDITEM:
- stampfile(fpath, &item);
- strlcpy(item.title, "¡º ", sizeof(item.title)); /* A1BA */
- break;
-
- case ADDGROUP:
- stampdir(fpath, &item);
- strlcpy(item.title, "¡» ", sizeof(item.title)); /* A1BB */
- break;
- }
-
- if (!getdata(b_lines - 1, 1, mesg[mode], &item.title[3], 55, DOECHO)) {
- if (mode == ADDGROUP)
- rmdir(fpath);
- else
- unlink(fpath);
- return;
- }
- switch (mode) {
- case ADDITEM:
- {
- int edflags = 0;
-# ifdef GLOBAL_BBSMOVIE
- if (pm && pm->bid &&
- strcmp(getbcache(pm->bid)->brdname,
- GLOBAL_BBSMOVIE) == 0)
- {
- edflags |= EDITFLAG_UPLOAD;
- edflags |= EDITFLAG_ALLOWLARGE;
- }
-# endif // GLOBAL_BBSMOVIE
- if (vedit2(fpath, 0, NULL, edflags) == -1) {
- unlink(fpath);
- pressanykey();
- return;
- }
- }
- break;
- case ADDGROUP:
- // do nothing
- break;
- }
-
- strlcpy(item.owner, cuser.userid, sizeof(item.owner));
- a_additem(pm, &item);
-}
-
-void
-a_pasteitem(menu_t * pm, int mode)
-{
- char newpath[PATHLEN];
- char buf[PATHLEN];
- char ans[2], skipAll = 0, multiple = 0;
- int i, copied = 0;
- fileheader_t item;
-
- CopyQueue *cq;
-
- move(b_lines - 1, 0);
- if(copyqueue_querysize() <= 0)
- {
- vmsg("½Ð¥ý°õ¦æ½Æ»s(copy)©R¥O«á¦A¶K¤W(paste)");
- return;
- }
- if(mode && copyqueue_querysize() > 1)
- {
- multiple = 1;
- move(b_lines-2, 0); clrtobot();
- outs("c: ¹ï¦U¶µ¥Ø­Ó§O½T»{¬O§_­n¶K¤W, z: ¥þ³¡¤£¶K¡A¦P®É­«³]¨Ã¨ú®ø¥þ³¡¼Ð°O\n");
- snprintf(buf, sizeof(buf),
- "½T©w­n¶K¤W¥þ³¡¦@ %d ­Ó¶µ¥Ø¶Ü (c/z/y/N)¡H ",
- copyqueue_querysize());
- getdata(b_lines - 1, 0, buf, ans, sizeof(ans), LCECHO);
- if(ans[0] == 'y')
- skipAll = 1;
- else if(ans[0] == 'z')
- {
- copyqueue_reset();
- vmsg("¤w­«³]½Æ»s°O¿ý¡C");
- return;
- }
- else if (ans[0] != 'c')
- return;
- clear();
- }
- while (copyqueue_querysize() > 0)
- {
- cq = copyqueue_gethead();
- if(!cq->copyfile[0])
- continue;
- if(mode && multiple)
- {
- scroll();
- move(b_lines-2, 0); clrtobot();
- prints("%d. %s\n", ++copied,cq->copytitle);
-
- }
-
- if (dashd(cq->copyfile)) {
- for (i = 0; cq->copyfile[i] && cq->copyfile[i] == pm->path[i]; i++);
- if (!cq->copyfile[i]) {
- vmsg("±N¥Ø¿ý«þ¶i¦Û¤vªº¤l¥Ø¿ý¤¤¡A·|³y¦¨µL½a°j°é¡I");
- continue;
- }
- }
- if (mode && !skipAll) {
- snprintf(buf, sizeof(buf),
- "½T©w­n«þ¨©[%s]¶Ü(Y/N)¡H[N] ", cq->copytitle);
- getdata(b_lines - 1, 0, buf, ans, sizeof(ans), LCECHO);
- } else
- ans[0] = 'y';
- if (ans[0] == 'y') {
- strlcpy(newpath, pm->path, sizeof(newpath));
-
- if (*cq->copyowner) {
- char *fname = strrchr(cq->copyfile, '/');
-
- if (fname)
- strcat(newpath, fname);
- else
- return;
- if (access(pm->path, X_OK | R_OK | W_OK))
- mkdir(pm->path, 0755);
- memset(&item, 0, sizeof(fileheader_t));
- strlcpy(item.filename, fname + 1, sizeof(item.filename));
- memcpy(cq->copytitle, "¡·", 2);
- Copy(cq->copyfile, newpath);
- } else if (dashf(cq->copyfile)) {
- stampfile(newpath, &item);
- memcpy(cq->copytitle, "¡º", 2);
- Copy(cq->copyfile, newpath);
- } else if (dashd(cq->copyfile)) {
- stampdir(newpath, &item);
- memcpy(cq->copytitle, "¡»", 2);
- copy_file(cq->copyfile, newpath);
- } else {
- copyqueue_reset();
- vmsg("µLªk«þ¨©¡I");
- return;
- }
- strlcpy(item.owner, *cq->copyowner ? cq->copyowner : cuser.userid,
- sizeof(item.owner));
- strlcpy(item.title, cq->copytitle, sizeof(item.title));
- a_additem(pm, &item);
- cq->copyfile[0] = '\0';
- }
- }
-}
-
-static void
-a_appenditem(const menu_t * pm, int isask)
-{
- char fname[PATHLEN];
- char buf[ANSILINELEN];
- char ans[2] = "y";
- FILE *fp, *fin;
-
- move(b_lines - 1, 0);
- if(copyqueue_querysize() <= 0)
- {
- vmsg("½Ð¥ý°õ¦æ copy ©R¥O«á¦A append");
- copyqueue_reset();
- return;
- }
- else
- {
- CopyQueue *cq = copyqueue_gethead();
- off_t sz;
-
- if (!dashf(cq->copyfile)) {
- vmsg("¥Ø¿ý¤£±oªþ¥[©óÀɮ׫á¡I");
- return;
- }
-
- snprintf(fname, sizeof(fname), "%s/%s", pm->path,
- pm->header[pm->now - pm->page].filename);
-
- if (!dashf(fname)) {
- vmsg("Àɮפ£±oªþ¥[©ó¦¹¡I");
- return;
- }
-
- sz = dashs(fname);
- if (sz >= MAX_FILE_SIZE)
- {
- vmsg("Àɮפw¶W¹L³Ì¤j­­¨î¡AµLªk¦Aªþ¥[");
- return;
- }
-
- if (isask) {
- snprintf(buf, sizeof(buf),
- "½T©w­n±N[%s]ªþ¥[©ó¦¹¶Ü(Y/N)¡H[N] ", cq->copytitle);
- getdata(b_lines - 2, 1, buf, ans, sizeof(ans), LCECHO);
- }
-
- if (ans[0] != 'y' || !(fp = fopen(fname, "a+")))
- return;
-
- if (!(fin = fopen(cq->copyfile, "r"))) {
- fclose(fp);
- return;
- }
-
- memset(buf, '-', 74);
- buf[74] = '\0';
- fprintf(fp, "\n> %s <\n\n", buf);
- if (isask)
- getdata(b_lines - 1, 1,
- "¬O§_¦¬¿ýñ¦WÀɳ¡¥÷(Y/N)¡H[Y] ",
- ans, sizeof(ans), LCECHO);
-
- while (fgets(buf, sizeof(buf), fin)) {
- if ((ans[0] == 'n') &&
- !strcmp(buf, "--\n"))
- break;
- fputs(buf, fp);
- }
- fclose(fin);
- fclose(fp);
- cq->copyfile[0] = '\0';
- }
-}
-
-static int
-a_pastetagpost(menu_t * pm, int mode)
-{
- fileheader_t fhdr;
- boardheader_t *bh = NULL;
- int ans = 0, ent = 0, tagnum;
- char title[TTLEN + 1] = "¡º ";
- char dirname[PATHLEN], buf[PATHLEN];
-
- if (TagBoard == 0){
- sethomedir(dirname, cuser.userid);
- }
- else{
- bh = getbcache(TagBoard);
- setbdir(dirname, bh->brdname);
- }
- tagnum = TagNum;
-
- // prevent if anything wrong
- if (tagnum > MAXTAGS || tagnum < 0)
- {
- vmsg("¤º³¡¿ù»~¡C½Ð§â§A­è­è¶i¦æªº§¹¾ã¨BÆJ¶K¨ì "
- GLOBAL_BUGREPORT " ªO¡C");
- return ans;
- }
-
- if (tagnum < 1)
- return ans;
-
- /* since we use different tag features,
- * copyqueue is not required/used. */
- copyqueue_reset();
-
- while (tagnum-- > 0) {
- memset(&fhdr, 0, sizeof(fhdr));
- EnumTagFhdr(&fhdr, dirname, ent++);
-
- // XXX many process crashed here as fhdr.filename[0] == 0
- // let's workaround it? or trace?
- // if (!fhdr->filename[0])
- // continue;
-
- if (!fhdr.filename[0])
- {
- grayout(0, b_lines-2, GRAYOUT_DARK);
- move(b_lines-1, 0); clrtobot();
- prints("²Ä %d ¶µ³B²zµo¥Í¿ù»~¡C ½Ð§â§A­è­è¶i¦æªº§¹¾ã¨BÆJ¶K¨ì "
- GLOBAL_BUGREPORT " ªO¡C\n", ent);
- vmsg("©¿²¤¿ù»~¨ÃÄ~Äò¶i¦æ¡C");
- continue;
- }
-
- if (TagBoard == 0)
- sethomefile(buf, cuser.userid, fhdr.filename);
- else
- setbfile(buf, bh->brdname, fhdr.filename);
-
- if (dashf(buf)) {
- strlcpy(title + 3, fhdr.title, sizeof(title) - 3);
- a_copyitem(buf, title, 0, 0);
- if (mode) {
- mode--;
- a_pasteitem(pm, 0);
- } else
- a_appenditem(pm, 0);
- ++ans;
- UnTagger(tagnum);
- }
- }
-
- return ans;
-}
-
-static void
-a_moveitem(menu_t * pm)
-{
- fileheader_t *tmp;
- char newnum[5];
- int num, max, min;
- char buf[PATHLEN];
- int fail;
-
- snprintf(buf, sizeof(buf), "½Ð¿é¤J²Ä %d ¿ï¶µªº·s¦¸§Ç¡G", pm->now + 1);
- if (!getdata(b_lines - 1, 1, buf, newnum, sizeof(newnum), DOECHO))
- return;
- num = (newnum[0] == '$') ? 9999 : atoi(newnum) - 1;
- if (num >= pm->num)
- num = pm->num - 1;
- else if (num < 0)
- num = 0;
- setadir(buf, pm->path);
- min = num < pm->now ? num : pm->now;
- max = num > pm->now ? num : pm->now;
- tmp = (fileheader_t *) calloc(max + 1, FHSZ);
-
- fail = 0;
- if (get_records(buf, tmp, FHSZ, 1, min) != min)
- fail = 1;
- if (num > pm->now) {
- if (get_records(buf, &tmp[min], FHSZ, pm->now + 2, max - min) != max - min)
- fail = 1;
- if (get_records(buf, &tmp[max], FHSZ, pm->now + 1, 1) != 1)
- fail = 1;
- } else {
- if (get_records(buf, &tmp[min], FHSZ, pm->now + 1, 1) != 1)
- fail = 1;
- if (get_records(buf, &tmp[min + 1], FHSZ, num + 1, max - min) != max - min)
- fail = 1;
- }
- if (!fail)
- substitute_record(buf, tmp, FHSZ * (max + 1), 1);
- pm->now = num;
- free(tmp);
-}
-
-static void
-a_delrange(menu_t * pm)
-{
- char fname[PATHLEN];
-
- snprintf(fname, sizeof(fname), "%s/" FN_DIR, pm->path);
- del_range(0, NULL, fname);
- pm->num = get_num_records(fname, FHSZ);
-}
-
-static void
-a_delete(menu_t * pm)
-{
- char fpath[PATHLEN], buf[PATHLEN], cmd[PATHLEN];
- char ans[4];
- fileheader_t backup;
-
- snprintf(fpath, sizeof(fpath),
- "%s/%s", pm->path, pm->header[pm->now - pm->page].filename);
- setadir(buf, pm->path);
-
- if (pm->header[pm->now - pm->page].filename[0] == 'H' &&
- pm->header[pm->now - pm->page].filename[1] == '.') {
- getdata(b_lines - 1, 1, "±z½T©w­n§R°£¦¹ºëµØ°Ï³s½u¶Ü(Y/N)¡H[N] ",
- ans, sizeof(ans), LCECHO);
- if (ans[0] != 'y')
- return;
- if (delete_record(buf, FHSZ, pm->now + 1) == -1)
- return;
- } else if (dashl(fpath)) {
- getdata(b_lines - 1, 1, "±z½T©w­n§R°£¦¹ symbolic link ¶Ü(Y/N)¡H[N] ",
- ans, sizeof(ans), LCECHO);
- if (ans[0] != 'y')
- return;
- if (delete_record(buf, FHSZ, pm->now + 1) == -1)
- return;
- unlink(fpath);
- } else if (dashf(fpath)) {
- getdata(b_lines - 1, 1, "±z½T©w­n§R°£¦¹Àɮ׶Ü(Y/N)¡H[N] ", ans,
- sizeof(ans), LCECHO);
- if (ans[0] != 'y')
- return;
- if (delete_record(buf, FHSZ, pm->now + 1) == -1)
- return;
-
- setbpath(buf, "deleted");
- stampfile(buf, &backup);
- strlcpy(backup.owner, cuser.userid, sizeof(backup.owner));
- strlcpy(backup.title,
- pm->header[pm->now - pm->page].title + 2,
- sizeof(backup.title));
-
- snprintf(cmd, sizeof(cmd),
- "mv -f %s %s", fpath, buf);
- system(cmd);
- setbdir(buf, "deleted");
- append_record(buf, &backup, sizeof(backup));
- } else if (dashd(fpath)) {
- getdata(b_lines - 1, 1, "±z½T©w­n§R°£¾ã­Ó¥Ø¿ý¶Ü(Y/N)¡H[N] ", ans,
- sizeof(ans), LCECHO);
- if (ans[0] != 'y')
- return;
- if (delete_record(buf, FHSZ, pm->now + 1) == -1)
- return;
-
- setapath(buf, "deleted");
- stampdir(buf, &backup);
-
- snprintf(cmd, sizeof(cmd),
- "rm -rf %s;/bin/mv -f %s %s", buf, fpath, buf);
- system(cmd);
-
- strlcpy(backup.owner, cuser.userid, sizeof(backup.owner));
- strcpy(backup.title, "¡»");
- strlcpy(backup.title + 2,
- pm->header[pm->now - pm->page].title + 2,
- sizeof(backup.title) - 3);
-
- /* merge setapath(buf, "deleted"); setadir(buf, buf); */
- snprintf(buf, sizeof(buf), "man/boards/%c/%s/" FN_DIR,
- 'd', "deleted");
- append_record(buf, &backup, sizeof(backup));
- } else { /* Ptt ·l·´ªº¶µ¥Ø */
- getdata(b_lines - 1, 1, "±z½T©w­n§R°£¦¹·l·´ªº¶µ¥Ø¶Ü(Y/N)¡H[N] ",
- ans, sizeof(ans), LCECHO);
- if (ans[0] != 'y')
- return;
- if (delete_record(buf, FHSZ, pm->now + 1) == -1)
- return;
- }
- pm->num--;
-}
-
-static void
-a_newtitle(const menu_t * pm)
-{
- char buf[PATHLEN];
- fileheader_t item;
-
- memcpy(&item, &pm->header[pm->now - pm->page], FHSZ);
- strlcpy(buf, item.title + 3, sizeof(buf));
- if (getdata_buf(b_lines - 1, 1, "·s¼ÐÃD¡G", buf, 60, DOECHO)) {
- strlcpy(item.title + 3, buf, sizeof(item.title) - 3);
- setadir(buf, pm->path);
- substitute_record(buf, &item, FHSZ, pm->now + 1);
- }
-}
-static void
-a_hideitem(const menu_t * pm)
-{
- fileheader_t *item = &pm->header[pm->now - pm->page];
- char buf[PATHLEN];
- if (item->filemode & FILE_BM) {
- item->filemode &= ~FILE_BM;
- item->filemode &= ~FILE_HIDE;
- } else if (item->filemode & FILE_HIDE)
- item->filemode |= FILE_BM;
- else
- item->filemode |= FILE_HIDE;
- setadir(buf, pm->path);
- substitute_record(buf, item, FHSZ, pm->now + 1);
-}
-static void
-a_editsign(const menu_t * pm)
-{
- char buf[PATHLEN];
- fileheader_t item;
-
- memcpy(&item, &pm->header[pm->now - pm->page], FHSZ);
- snprintf(buf, sizeof(buf), "%c%c", item.title[0], item.title[1]);
- if (getdata_buf(b_lines - 1, 1, "²Å¸¹", buf, 5, DOECHO)) {
- item.title[0] = buf[0] ? buf[0] : ' ';
- item.title[1] = buf[1] ? buf[1] : ' ';
- item.title[2] = buf[2] ? buf[2] : ' ';
- setadir(buf, pm->path);
- substitute_record(buf, &item, FHSZ, pm->now + 1);
- }
-}
-
-static void
-a_showname(const menu_t * pm)
-{
- char buf[PATHLEN];
- int len;
- int i;
- int sym;
-
- move(b_lines - 1, 0);
- snprintf(buf, sizeof(buf),
- "%s/%s", pm->path, pm->header[pm->now - pm->page].filename);
- if (dashl(buf)) {
- prints("¦¹ symbolic link ¦WºÙ¬° %s\n",
- pm->header[pm->now - pm->page].filename);
- if ((len = readlink(buf, buf, PATHLEN - 1)) >= 0) {
- buf[len] = '\0';
- for (i = 0; BBSHOME[i] && buf[i] == BBSHOME[i]; i++);
- if (!BBSHOME[i] && buf[i] == '/') {
- if (HasUserPerm(PERM_BBSADM))
- sym = 1;
- else {
- sym = 0;
- for (i++; BBSHOME "/man"[i] && buf[i] == BBSHOME "/man"[i];
- i++);
- if (!BBSHOME "/man"[i] && buf[i] == '/')
- sym = 1;
- }
- if (sym) {
- vmsgf("¦¹ symbolic link «ü¦V %s\n", &buf[i + 1]);
- }
- }
- }
- } else if (dashf(buf))
- prints("¦¹¤å³¹¦WºÙ¬° %s", pm->header[pm->now - pm->page].filename);
- else if (dashd(buf))
- prints("¦¹¥Ø¿ý¦WºÙ¬° %s", pm->header[pm->now - pm->page].filename);
- else
- outs("¦¹¶µ¥Ø¤w·l·´, «Øij±N¨ä§R°£¡I");
- pressanykey();
-}
-#ifdef CHESSCOUNTRY
-static void
-a_setchesslist(const menu_t * me)
-{
- char buf[4];
- char buf_list[PATHLEN];
- char buf_photo[PATHLEN];
- char buf_this[PATHLEN];
- char buf_real[PATHLEN];
- int list_exist, photo_exist;
- fileheader_t* fhdr = me->header + me->now - me->page;
- int n;
-
- snprintf(buf_this, sizeof(buf_this), "%s/%s", me->path, fhdr->filename);
- if((n = readlink(buf_this, buf_real, sizeof(buf_real) - 1)) == -1)
- strcpy(buf_real, fhdr->filename);
- else
- // readlink doesn't garentee zero-ended
- buf_real[n] = 0;
-
- if (strcmp(buf_real, "chess_list") == 0
- || strcmp(buf_real, "chess_photo") == 0) {
- vmsg("¤£»Ý­«³]¡I");
- return;
- }
-
- snprintf(buf_list, sizeof(buf_list), "%s/chess_list", me->path);
- snprintf(buf_photo, sizeof(buf_photo), "%s/chess_photo", me->path);
-
- list_exist = dashf(buf_list);
- photo_exist = dashd(buf_photo);
-
- if (!list_exist && !photo_exist) {
- vmsg("¦¹¬ÝªO«D´Ñ°ê¡I");
- return;
- }
-
- getdata(b_lines, 0, "±N¦¹¶µ¥Ø³]©w¬° (1) ´Ñ°ê¦W³æ (2) ´Ñ°ê·Ó¤ùÀɥؿý¡G",
- buf, sizeof(buf), 1);
- if (buf[0] == '1') {
- if (list_exist)
- getdata(b_lines, 0, "­ì¦³¤§´Ñ°ê¦W³æ±N³Q¨ú¥N¡A½Ð½T»{ (y/N)",
- buf, sizeof(buf), 1);
- else
- buf[0] = 'y';
-
- if (buf[0] == 'y' || buf[0] == 'Y') {
- Rename(buf_this, buf_list);
- symlink("chess_list", buf_this);
- }
- } else if (buf[0] == '2') {
- if (photo_exist)
- getdata(b_lines, 0, "­ì¦³¤§´Ñ°ê·Ó¤ù±N³Q¨ú¥N¡A½Ð½T»{ (y/N)",
- buf, sizeof(buf), 1);
- else
- buf[0] = 'y';
-
- if (buf[0] == 'y' || buf[0] == 'Y') {
- if(strncmp(buf_photo, "man/boards/", 11) == 0 && // guarding
- buf_photo[11] && buf_photo[12] == '/' && // guarding
- snprintf(buf_list, sizeof(buf_list), "rm -rf %s", buf_photo)
- == strlen(buf_photo) + 7)
- system(buf_list);
- Rename(buf_this, buf_photo);
- symlink("chess_photo", buf_this);
- }
- }
-}
-#endif /* defined(CHESSCOUNTRY) */
-
-static int
-isvisible_man(const menu_t * me)
-{
- fileheader_t *fhdr = &me->header[me->now - me->page];
- /* board friend only effact when in board reading mode */
- if (me->level >= MANAGER)
- return 1;
- if (fhdr->filemode & FILE_BM)
- return 0;
- if (fhdr->filemode & FILE_HIDE)
- {
- if (currstat == ANNOUNCE ||
- !is_hidden_board_friend(me->bid, currutmp->uid))
- return 0;
- }
- return 1;
-}
-int
-a_menu(const char *maintitle, const char *path,
- int lastlevel, int lastbid,
- char *trans_buffer)
-{
- static char Fexit; // ¥Î¨Ó¸õ¥X recursion
- menu_t me;
- char fname[PATHLEN];
- int ch, returnvalue = FULLUPDATE;
-
- // prevent deep resursive directories
- if (strlen(path) + FNLEN >= PATHLEN)
- {
- // it is not save to enter such directory.
- return returnvalue;
- }
-
- if(trans_buffer)
- trans_buffer[0] = '\0';
-
- memset(&me, 0, sizeof(me));
- Fexit = 0;
- me.header_size = p_lines;
- me.header = (fileheader_t *) calloc(me.header_size, FHSZ);
- me.path = path;
- strlcpy(me.mtitle, maintitle, sizeof(me.mtitle));
- setadir(fname, me.path);
- me.num = get_num_records(fname, FHSZ);
- me.bid = lastbid;
-
- /* ºëµØ°Ï-tree ¤¤³¡¥÷µ²ºcÄÝ©ó cuser ==> BM */
-
- if (!(me.level = lastlevel)) {
- char *ptr;
-
- if ((ptr = strrchr(me.mtitle, '[')))
- me.level = is_BM(ptr + 1);
- }
- me.page = 9999;
- me.now = 0;
- for (;;) {
- if (me.now >= me.num)
- me.now = me.num - 1;
- if (me.now < 0)
- me.now = 0;
-
- if (me.now < me.page || me.now >= me.page + me.header_size) {
- me.page = me.now - ((me.page == 10000 && me.now > p_lines / 2) ?
- (p_lines / 2) : (me.now % p_lines));
- if (!a_showmenu(&me))
- {
- // some directories are invalid, restart!
- Fexit = 1;
- break;
- }
- }
- ch = cursor_key(2 + me.now - me.page, 0);
-
- if (ch == 'q' || ch == 'Q' || ch == KEY_LEFT)
- break;
-
- if (ch >= '1' && ch <= '9') {
- if ((ch = search_num(ch, me.num)) != -1)
- me.now = ch;
- me.page = 10000;
- continue;
- }
- switch (ch) {
- case KEY_UP:
- case 'k':
- if (--me.now < 0)
- me.now = me.num - 1;
- break;
-
- case KEY_DOWN:
- case 'j':
- if (++me.now >= me.num)
- me.now = 0;
- break;
-
- case KEY_PGUP:
- case Ctrl('B'):
- if (me.now >= p_lines)
- me.now -= p_lines;
- else if (me.now > 0)
- me.now = 0;
- else
- me.now = me.num - 1;
- break;
-
- case ' ':
- case KEY_PGDN:
- case Ctrl('F'):
- if (me.now < me.num - p_lines)
- me.now += p_lines;
- else if (me.now < me.num - 1)
- me.now = me.num - 1;
- else
- me.now = 0;
- break;
-
- case '0':
- me.now = 0;
- break;
- case '?':
- case '/':
- if(me.num) {
- me.now = a_searchtitle(&me, ch == '?');
- me.page = 9999;
- }
- break;
- case '$':
- me.now = me.num - 1;
- break;
- case 'h':
- a_showhelp(me.level);
- me.page = 9999;
- break;
-
- case Ctrl('I'):
- t_idle();
- me.page = 9999;
- break;
-
- case 'e':
- case 'E':
- snprintf(fname, sizeof(fname),
- "%s/%s", path, me.header[me.now - me.page].filename);
- if (dashf(fname) && me.level >= MANAGER) {
- int edflags = 0;
- *quote_file = 0;
-
-# ifdef GLOBAL_BBSMOVIE
- if (me.bid && strcmp(getbcache(me.bid)->brdname,
- GLOBAL_BBSMOVIE) == 0)
- {
- edflags |= EDITFLAG_UPLOAD;
- edflags |= EDITFLAG_ALLOWLARGE;
- }
-# endif // GLOBAL_BBSMOVIE
-
- if (vedit2(fname, NA, NULL, edflags) != -1) {
- char fpath[PATHLEN];
- fileheader_t fhdr;
- strlcpy(fpath, path, sizeof(fpath));
- stampfile(fpath, &fhdr);
- unlink(fpath);
- strlcpy(fhdr.filename,
- me.header[me.now - me.page].filename,
- sizeof(fhdr.filename));
- strlcpy(me.header[me.now - me.page].owner,
- cuser.userid,
- sizeof(me.header[me.now - me.page].owner));
- setadir(fpath, path);
- substitute_record(fpath, me.header + me.now - me.page,
- sizeof(fhdr), me.now + 1);
-
- }
- me.page = 9999;
- }
- break;
-
- case 't':
- case 'c':
- if (me.now < me.num) {
- if (!isvisible_man(&me))
- break;
-
- snprintf(fname, sizeof(fname), "%s/%s", path,
- me.header[me.now - me.page].filename);
-
- /* XXX: dirty fix
- À³¸Ó­n§ï¦¨¦pªGµo²{¸Ó¥Ø¿ý¸Ì­±¦³Áô§Î¥Ø¿ýªº¸Ü¤~©Úµ´.
- ¤£¹L³o¼Ëªº¸Ü¶·­n¾ã­Ó·j¤@¹M, ¦Ó¥B¥Ø«e§PÂ_¸Ó¸ê®Æ¬O¥Ø¿ý
- ÁÙ¬OÀɮ׳ºµM¬O¥Î fstat(2) ¦Ó¤£¬Oª½±µ¦s¦b .DIR ¤º |||b
- ¶·µ¥¸Ó¸ê®Æ¼g¤J .DIR ¤º¦A implement¤~¦³®Ä²v.
- */
- if( !lastlevel && !HasUserPerm(PERM_SYSOP) &&
- (me.bid==0 || !is_BM_cache(me.bid)) && dashd(fname) )
- vmsg("¥u¦³ªO¥D¤~¥i¥H«þ¨©¥Ø¿ý­ò!");
- else
- a_copyitem(fname, me.header[me.now - me.page].title, 0, 1);
- me.page = 9999;
- /* move down */
- if (++me.now >= me.num)
- me.now = 0;
- break;
- }
- case '\n':
- case '\r':
- case KEY_RIGHT:
- case 'r':
- if (me.now < me.num) {
- fileheader_t *fhdr = &me.header[me.now - me.page];
- if (!isvisible_man(&me))
- break;
-#ifdef DEBUG
- vmsgf("%s/%s", &path[11], fhdr->filename);;
-#endif
- snprintf(fname, sizeof(fname), "%s/%s", path, fhdr->filename);
- if (*fhdr->filename == 'H' && fhdr->filename[1] == '.') {
- vmsg("¤£¦A¤ä´© gopher mode, ½Ð¨Ï¥ÎÂsÄý¾¹ª½±µÂsÄý");
- vmsgf("gopher://%s/1/",fhdr->filename+2);
- } else if (dashf(fname)) {
- int more_result;
-
- while ((more_result = more(fname, YEA))) {
- /* Ptt ½d¥»ºëÆF plugin */
- if (trans_buffer &&
- (currstat == EDITEXP || currstat == OSONG)) {
- char ans[4];
-
- move(22, 0);
- clrtoeol();
- getdata(22, 1,
- currstat == EDITEXP ?
- "­n§â½d¨Ò Plugin ¨ì¤å³¹¶Ü?[y/N]" :
- "½T©w­nÂI³o­ººq¶Ü?[y/N]",
- ans, sizeof(ans), LCECHO);
- if (ans[0] == 'y') {
- strlcpy(trans_buffer, fname, PATHLEN);
- Fexit = 1;
- if (currstat == OSONG) {
- log_filef(FN_USSONG, LOG_CREAT, "%s\n", fhdr->title);
- }
- free(me.header);
- return FULLUPDATE;
- }
- }
- if (more_result == READ_PREV) {
- if (--me.now < 0) {
- me.now = 0;
- break;
- }
- } else if (more_result == READ_NEXT) {
- if (++me.now >= me.num) {
- me.now = me.num - 1;
- break;
- }
- /* we only load me.header_size pages */
- if (me.now - me.page >= me.header_size)
- break;
- } else
- break;
- if (!isvisible_man(&me))
- break;
- snprintf(fname, sizeof(fname), "%s/%s", path,
- me.header[me.now - me.page].filename);
- if (!dashf(fname))
- break;
- }
- } else if (dashd(fname)) {
- a_menu(me.header[me.now - me.page].title, fname,
- me.level, me.bid, trans_buffer);
- /* Ptt ±j¤O¸õ¥Xrecursive */
- if (Fexit) {
- free(me.header);
- return FULLUPDATE;
- }
- }
- me.page = 9999;
- }
- break;
-
- case 'F':
- case 'U':
- if (me.now < me.num) {
- fileheader_t *fhdr = &me.header[me.now - me.page];
- if (!isvisible_man(&me))
- break;
- snprintf(fname, sizeof(fname),
- "%s/%s", path, fhdr->filename);
- if (HasUserPerm(PERM_LOGINOK) && dashf(fname)) {
- a_forward(path, fhdr, ch /* == 'U' */ );
- /* By CharlieL */
- } else
- vmsg("µLªkÂà±H¦¹¶µ¥Ø");
- me.page = 9999;
- }
-
- break;
-
- }
-
- if (me.level >= MANAGER) {
- switch (ch) {
- case 'n':
- a_newitem(&me, ADDITEM);
- me.page = 9999;
- break;
- case 'g':
- a_newitem(&me, ADDGROUP);
- me.page = 9999;
- break;
- case 'p':
- a_pasteitem(&me, 1);
- me.page = 9999;
- break;
- case 'f':
- a_editsign(&me);
- me.page = 9999;
- break;
- case Ctrl('P'):
- a_pastetagpost(&me, -1);
- returnvalue = DIRCHANGED;
- me.page = 9999;
- break;
- case Ctrl('A'):
- a_pastetagpost(&me, 1);
- returnvalue = DIRCHANGED;
- me.page = 9999;
- break;
- case 'a':
- a_appenditem(&me, 1);
- me.page = 9999;
- break;
-#ifdef BLOG
- case 'b':
- if (me.bid)
- {
- char genbuf[128];
- char *bname = getbcache(me.bid)->brdname;
- snprintf(genbuf, sizeof(genbuf),
- "bin/builddb.pl -f -n %d %s", me.now, bname);
- system(genbuf);
- vmsg("¸ê®Æ§ó·s§¹¦¨");
- }
- me.page = 9999;
- break;
-
- case 'B':
- if (me.bid && me.bid == currbid)
- {
- BlogMain(me.now);
- };
- me.page = 9999;
- break;
-#endif
- }
-
- if (me.num)
- switch (ch) {
- case 'm':
- a_moveitem(&me);
- me.page = 9999;
- break;
-
- case 'D':
- /* Ptt me.page = -1; */
- a_delrange(&me);
- me.page = 9999;
- break;
- case 'd':
- a_delete(&me);
- me.page = 9999;
- break;
- case 'H':
- a_hideitem(&me);
- me.page = 9999;
- break;
- case 'T':
- a_newtitle(&me);
- me.page = 9999;
- break;
-#ifdef CHESSCOUNTRY
- case 'L':
- a_setchesslist(&me);
- break;
-#endif
- }
- }
- if (me.level >= SYSOP) {
- switch (ch) {
- case 'N':
- a_showname(&me);
- me.page = 9999;
- break;
- }
- }
- }
- free(me.header);
- return returnvalue;
-}
-
-int
-Announce(void)
-{
- setutmpmode(ANNOUNCE);
- a_menu(BBSNAME "§G§iÄæ", "man",
- ((HasUserPerm(PERM_SYSOP) ) ? SYSOP : NOBODY),
- 0,
- NULL);
- return 0;
-}
-
-#ifdef BLOG
-#include <mysql/mysql.h>
-void BlogMain(int num)
-{
- int oldmode = currutmp->mode;
- char genbuf[128], exit = 0;
-
- // WARNING: ­n½T»{ currboard/currbid ¤w¥¿½T³]©w¤~¯à¥Î¦¹API¡C
-
- //setutmpmode(BLOGGING); /* will crash someone using old program */
- sprintf(genbuf, "%sªº³¡¸¨®æ", currboard);
- showtitle("³¡¸¨®æ", genbuf);
- while( !exit ){
- move(1, 0);
- outs("½Ð¿ï¾Ü±z­n°õ¦æªº­«§@:\n"
- "0.¦^¨ì¤W¤@¼h\n"
- "1.»s§@³¡¸¨®æ¼ËªO®æ¦¡\n"
- " ¨Ï¥Î·sªº config ¥Ø¿ý¤U¼ËªO¸ê®Æ\n"
- " ³q±`¦b²Ä¤@¦¸¨Ï¥Î³¡¸¨®æ©Î¼ËªO§ó·sªº®É­Ô¨Ï¥Î\n"
- "\n"
- "2.­«·s»s§@³¡¸¨®æ\n"
- " ¥u¦b³¡¸¨®æ¸ê®Æ¾ã­Ó¶Ã±¼ªº®É­Ô¤~¨Ï¥Î\n"
- "\n"
- "3.±N¥»¤å¥[¤J³¡¸¨®æ\n"
- " ±N´å¼Ð©Ò¦b¦ì¸mªº¤å³¹¥[¤J³¡¸¨®æ\n"
- "\n"
- "4.§R°£°jÅT\n"
- "\n"
- "5.§R°£¤@½g³¡¸¨®æ\n"
- "\n"
- "C.«Ø¥ß³¡¸¨®æ¥Ø¿ý (±z¥u¦³²Ä¤@¦¸®É»Ý­n)\n"
- );
- switch( getans("½Ð¿ï¾Ü(0-5,C)¡H[0]") ){
- case '1':
- snprintf(genbuf, sizeof(genbuf),
- "bin/builddb.pl -c %s", currboard);
- system(genbuf);
- break;
- case '2':
- snprintf(genbuf, sizeof(genbuf),
- "bin/builddb.pl -a %s", currboard);
- system(genbuf);
- break;
- case '3':
- snprintf(genbuf, sizeof(genbuf),
- "bin/builddb.pl -f -n %d %s", num, currboard);
- system(genbuf);
- break;
- case '4':{
- char hash[33];
- int i;
- getdata(16, 0, "½Ð¿é¤J¸Ó½gªºÂø´ê­È: ",
- hash, sizeof(hash), DOECHO);
- for( i = 0 ; hash[i] != 0 ; ++i ) /* «e­±¥Î getdata() «OÃÒ¦³ \0 */
- if( !islower(hash[i]) && !isdigit(hash[i]) )
- break;
- if( i != 32 ){
- vmsg("¿é¤J¿ù»~");
- break;
- }
- if( hash[0] != 0 &&
- getans("½Ð½T©w§R°£(Y/N)?[N] ") == 'y' ){
- MYSQL mysql;
- char cmd[256];
-
- snprintf(cmd, sizeof(cmd), "delete from comment where "
- "hash='%s'&&brdname='%s'", hash, currboard);
-#ifdef DEBUG
- vmsg(cmd);
-#endif
- if( !(!mysql_init(&mysql) ||
- !mysql_real_connect(&mysql, BLOGDB_HOST, BLOGDB_USER,
- BLOGDB_PASSWD, BLOGDB_DB,
- BLOGDB_PORT, BLOGDB_SOCK, 0) ||
- mysql_query(&mysql, cmd)) )
- vmsg("¸ê®Æ§R°£§¹¦¨");
- else
- vmsg(
-#ifdef DEBUG
- mysql_error(&mysql)
-#else
- "database internal error"
-#endif
- );
- mysql_close(&mysql);
- }
- }
- break;
-
- case '5': {
- char date[9];
- int i;
- getdata(16, 0, "½Ð¿é¤J¸Ó½gªº¤é´Á(yyyymmdd): ",
- date, sizeof(date), DOECHO);
- for( i = 0 ; i < 9 ; ++i )
- if( !isdigit(date[i]) )
- break;
- if( i != 8 ){
- vmsg("¿é¤J¿ù»~");
- break;
- }
- snprintf(genbuf, sizeof(genbuf),
- "bin/builddb.pl -D %s %s", date, currboard);
- system(genbuf);
- }
- break;
-
- case 'C': case 'c': {
- fileheader_t item;
- char fpath[PATHLEN], adir[PATHLEN], buf[256];
- setapath(fpath, currboard);
- stampdir(fpath, &item);
- strlcpy(item.title, "¡» Blog", sizeof(item.title));
- strlcpy(item.owner, cuser.userid, sizeof(item.owner));
-
- setapath(adir, currboard);
- strcat(adir, "/" FN_DIR);
- append_record(adir, &item, FHSZ);
-
- snprintf(buf, sizeof(buf),
- "cp -R etc/Blog.Default/" FN_DIR " etc/Blog.Default/* %s/",
- fpath);
- system(buf);
-
- more("etc/README.BLOG", YEA);
- }
- break;
-
- default:
- exit = 1;
- break;
- }
- if( !exit )
- vmsg("³¡¸¨®æ§¹¦¨");
- }
- currutmp->mode = oldmode;
- pressanykey();
-}
-#endif
diff --git a/mbbsd/args.c b/mbbsd/args.c
deleted file mode 100644
index bbd6be21..00000000
--- a/mbbsd/args.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-#ifdef HAVE_SETPROCTITLE
-
-void
-initsetproctitle(int argc, char **argv, char **envp)
-{
-}
-
-#else
-
-
-static char **Argv = NULL; /* pointer to argument vector */
-static int argv_size; /* end of argv */
-
-extern char **environ;
-
-void
-initsetproctitle(int argc, char **argv, char **envp)
-{
- register int i;
- int len=0,nenv=0;
-
-
- /*
- * Move the environment so setproctitle can use the space at the top of
- * memory.
- */
- for (i = 0; envp[i]; i++)
- len+=strlen(envp[i])+1;
- nenv=i+1;
- len+=sizeof(char*)*nenv;
- environ = malloc(len);
- len=0;
- for (i = 0; envp[i]; i++) {
- environ[i] = (char*)environ+nenv*sizeof(char*)+len;
- strcpy(environ[i], envp[i]);
- len+=strlen(envp[i])+1;
- }
- environ[i] = NULL;
-
- /* Save start and extent of argv for setproctitle. */
- Argv = argv;
- if (i > 0)
- argv_size = envp[i - 1] + strlen(envp[i - 1]) - Argv[0];
- else
- argv_size = argv[argc - 1] + strlen(argv[argc - 1]) - Argv[0];
-}
-
-static void
-do_setproctitle(const char *cmdline)
-{
- int len;
-
- len = strlen(cmdline) + 1; // +1 for '\0'
- if(len > argv_size - 2) // 2 ??
- len = argv_size - 2;
- memset(Argv[0], 0, argv_size);
- strlcpy(Argv[0], cmdline, len);
- Argv[1] = NULL;
-}
-
-void
-setproctitle(const char *format,...)
-{
- char buf[256];
- va_list args;
- va_start(args, format);
- vsnprintf(buf, sizeof(buf), format, args);
- do_setproctitle(buf);
- va_end(args);
-}
-#endif
diff --git a/mbbsd/assess.c b/mbbsd/assess.c
deleted file mode 100644
index 4d63a8d8..00000000
--- a/mbbsd/assess.c
+++ /dev/null
@@ -1,268 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-#ifdef ASSESS
-
-/* do (*num) + n, n is integer. */
-inline static void inc(unsigned char *num, int n)
-{
- if (n >= 0 && SALE_MAXVALUE - *num <= n)
- (*num) = SALE_MAXVALUE;
- else if (n < 0 && *num < -n)
- (*num) = 0;
- else
- (*num) += n;
-}
-
-#define modify_column(_attr) \
-int inc_##_attr(const char *userid, int num) \
-{ \
- userec_t xuser; \
- int uid = getuser(userid, &xuser);\
- if( uid > 0 ){ \
- inc(&xuser._attr, num); \
- passwd_update(uid, &xuser); \
- return xuser._attr; }\
- return 0;\
-}
-
-modify_column(goodpost); /* inc_goodpost */
-modify_column(badpost); /* inc_badpost */
-modify_column(goodsale); /* inc_goodsale */
-modify_column(badsale); /* inc_badsale */
-
-#if 0 //unused function
-void set_assess(const char *userid, unsigned char num, int type)
-{
- userec_t xuser;
- int uid = getuser(userid, &xuser);
- if(uid<=0) return;
- switch (type){
- case GOODPOST:
- xuser.goodpost = num;
- break;
- case BADPOST:
- xuser.badpost = num;
- break;
- case GOODSALE:
- xuser.goodsale = num;
- break;
- case BADSALE:
- xuser.badsale = num;
- break;
- }
- passwd_update(uid, &xuser);
-}
-#endif
-
-// how long is AID? see read.c...
-#ifndef AIDC_LEN
-#define AIDC_LEN (20)
-#endif // AIDC_LEN
-
-// #define MAXGP (100)
-#define MAXGP (SALE_MAXVALUE)
-
-int
-u_fixgoodpost(void)
-{
- char endinput = 0;
- unsigned int newgp = 0;
- int bid;
- char bname[IDLEN+1];
- char xaidc[AIDC_LEN+1];
-
- aidu_t gpaids[MAXGP+1];
- int gpbids[MAXGP+1];
- int cgps = 0;
-
- clear();
- stand_title("¦Û°ÊÀu¤å­×¥¿µ{¦¡");
-
- outs("¶}©l­×¥¿Àu¤å¤§«e¡A¦³¨Ç¥\\½Ò­n³Â·Ð±z¥ý¬d¦n¡G\n\n"
- "½Ð¥ý§ä¨ì§A©Ò¦³ªºÀu¤å¤å³¹ªº¬ÝªO»P" AID_DISPLAYNAME "\n"
- AID_DISPLAYNAME "ªº¬d¸ß¤èªk¬O¦b¸Ó½g¤å³¹«e­±«ö¤U¤j¼g Q ¡C\n"
- "¬d¦n«á½Ð§â³o¨Ç¸ê®Æ©ñ¦b¤âÃä¡Aµ¥¤U·|½Ð±z¿é¤J¡C\n"
- "¥t¥~¡A­Y¦³¦h­«µn¤J½Ð¥ýÃö³¬¨ä¥¦³s½u¡C\n"
- "\n");
- outs("¦pªG¤@¤Á³£·Ç³Æ¦n¤F¡A½Ð«ö¤U y ¶}©l¡A©Î¨ä¥¦¥ô·NÁä¸õ¥X¡C\n\n");
- if (getans("Àu¤åªº¸ê®Æ³£¬d¦n¤F¶Ü¡H") != 'y')
- {
- vmsg("¸õ¥X­×¥¿µ{¦¡¡C");
- return 0;
- }
- while (!endinput && newgp < MAXGP)
- {
- int y, x = 0;
- boardheader_t *bh = NULL;
-
- move(1, 0); clrtobot();
- outs("½Ð¨Ì§Ç¿é¤JÀu¤å¸ê°T¡A¥þ³¡§¹¦¨«á«ö ENTER §Y¥i°±¤î¡C\n");
-
- move(b_lines-2, 0); clrtobot();
- prints("¥Ø«e¤w½T»{Àu¤å¼Æ¥Ø: %d" ANSI_RESET "\n\n", newgp);
-
- if (!getdata(5, 0, "½Ð¿é¤JÀu¤å¤å³¹©Ò¦b¬ÝªO¦WºÙ: ",
- bname, sizeof(bname), DOECHO))
- {
- move(5, 0);
- if (getans(ANSI_COLOR(1;33)"½T©w¥þ³¡¿é¤J§¹¦¨¤F¶Ü¡H "
- ANSI_RESET "[y/N]: ") != 'y')
- continue;
- endinput = 1; break;
- }
- move (6, 0);
- outs("½T»{¬ÝªO... ");
- if (bname[0] == '\0' || !(bid = getbnum(bname)))
- {
- outs(ANSI_COLOR(1;31) "¬ÝªO¤£¦s¦b¡I");
- vmsg("½Ð­«·s¿é¤J¡C");
- continue;
- }
- assert(0<=bid-1 && bid-1<MAX_BOARD);
- bh = getbcache(bid);
- strlcpy(bname, bh->brdname, sizeof(bname));
- prints("¤w§ä¨ì¬ÝªO --> %s\n", bname);
- getyx(&y, &x);
-
- // loop AID query
- while (newgp < MAXGP)
- {
- int n;
- int fd;
- char dirfile[PATHLEN];
- char *sp;
- aidu_t aidu = 0;
- fileheader_t fh;
-
- move(y, 0); clrtobot();
- move(b_lines-2, 0); clrtobot();
- prints("¥Ø«e¤w½T»{Àu¤å¼Æ¥Ø: %d" ANSI_RESET "\n\n", newgp);
-
- if (getdata(y, 0, "½Ð¿é¤J" AID_DISPLAYNAME ": #",
- xaidc, AIDC_LEN, DOECHO) == 0)
- break;
-
- sp = xaidc;
- while(*sp == ' ') sp ++;
- if(*sp == '#') sp ++;
-
- if((aidu = aidc2aidu(sp)) <= 0)
- {
- outs(ANSI_COLOR(1;31) AID_DISPLAYNAME "®æ¦¡¤£¥¿½T¡I");
- vmsg("½Ð­«·s¿é¤J¡C");
- continue;
- }
-
- // check repeated input of same board+AID.
- for (n = 0; n < cgps; n++)
- {
- if (gpaids[n] == aidu && gpbids[n] == bid)
- {
- vmsg("±z¤w¿é¤J¹L¦¹Àu¤å¤F¡A½Ð­«·s¿é¤J¡C");
- aidu = 0;
- break;
- }
- }
-
- if (aidu <= 0)
- continue;
-
- // find aidu in board
- n = -1;
- // see read.c, search .bottom first.
- if (n < 0)
- {
- outs("·j´M¸m©³¤å³¹...");
- setbfile(dirfile, bname, FN_DIR ".bottom");
- n = search_aidu(dirfile, aidu);
- }
- if (n < 0) {
- // search board
- outs("¥¼§ä¨ì¡C\n·j´M¬ÝªO¤å³¹..");
- setbfile(dirfile, bname, FN_DIR);
- n = search_aidu(dirfile, aidu);
- }
- if (n < 0)
- {
- // search digest
- outs("¥¼§ä¨ì¡C\n·j´M¤åºK..");
- setbfile(dirfile, currboard, fn_mandex);
- n = search_aidu(dirfile, aidu);
- }
- if (n < 0)
- {
- // search failed...
- outs("¥¼§ä¨ì\n" ANSI_COLOR(1;31) "§ä¤£¨ì¤å³¹¡I");
- vmsg("½Ð½T»{«á­«·s¿é¤J¡C");
- continue;
- }
-
- // found something
- fd = open(dirfile, O_RDONLY);
- if (fd < 0)
- {
- outs(ANSI_COLOR(1;31) "¨t²Î¿ù»~¡C ½Ðµy­Ô¦A­«¸Õ¡C\n");
- vmsg("­Y«ùÄòµo¥Í½Ð¦Ü" GLOBAL_BUGREPORT "³ø§i¡C");
- continue;
- }
-
- lseek(fd, n*sizeof(fileheader_t), SEEK_SET);
- memset(&fh, 0, sizeof(fh));
- read(fd, &fh, sizeof(fh));
- outs("\n¶}©l®Ö¹ï¸ê®Æ...\n");
- n = 1;
- if (strcmp(fh.owner, cuser.userid) != 0)
- n = 0;
- prints("§@ªÌ: %s (%s)\n", fh.owner, n ? "¥¿½T" :
- ANSI_COLOR(1;31) "¿ù»~" ANSI_RESET);
- if (!(fh.filemode & FILE_MARKED))
- n = 0;
- prints("¢Û¤å: %s\n", (fh.filemode & FILE_MARKED) ? "¥¿½T" :
- ANSI_COLOR(1;31) "¿ù»~" ANSI_RESET);
- prints("±ÀÂË: %d\n", fh.recommend);
- close(fd);
- if (!n)
- {
- vmsg("¿é¤Jªº¤å³¹¨Ã«DÀu¤å¡A½Ð­«·s¿é¤J¡C");
- continue;
- }
- n = fh.recommend / 10;
- prints("­pºâÀu¤å¼Æ­È: %+d\n", n);
-
- if (n > 0)
- {
- // log new data
- newgp += n;
- gpaids[cgps] = aidu;
- gpbids[cgps] = bid;
- cgps ++;
- }
-
- clrtobot();
-
-
- vmsg("Àu¤å¤w½T»{¡C­Y­n¿é¤J¨ä¥¦¬ÝªO¤å³¹½Ð¦bAIDÄæªÅ¥Õ«ö ENTER");
- }
- vmsgf("%s ¬ÝªO¿é¤J§¹¦¨¡C", bname);
- }
- if (newgp > MAXGP)
- newgp = MAXGP;
- if (newgp <= cuser.goodpost)
- {
- vmsg("½T»{Àu¤å¼Æ¥Ø¥¼°ª©ó¤w¦³Àu¤å¼Æ¡A¤£½Õ¾ã¡C");
- } else {
- log_filef("log/fixgoodpost.log", LOG_CREAT,
- "%s %s ¦Û°Ê­×¥¿Àu¤å¼Æ: ¥Ñ %d Åܬ° %d\n", Cdate(&now), cuser.userid,
- cuser.goodpost, newgp);
- cuser.goodpost = newgp;
- // update passwd file here?
- passwd_force_update(ALERT_PWD_GOODPOST);
- passwd_update(usernum, &cuser);
- vmsgf("§ó·sÀu¤å¼Æ¥Ø¬°%d¡C", newgp);
- }
-
- return 0;
-}
-
-#endif
diff --git a/mbbsd/bbs.c b/mbbsd/bbs.c
deleted file mode 100644
index 83cdb5c0..00000000
--- a/mbbsd/bbs.c
+++ /dev/null
@@ -1,3986 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-#ifdef EDITPOST_SMARTMERGE
-
-#include "fnv_hash.h"
-#define SMHASHLEN (64/8)
-
-#endif // EDITPOST_SMARTMERGE
-
-#define WHEREAMI_LEVEL 16
-
-static int recommend(int ent, fileheader_t * fhdr, const char *direct);
-static int do_add_recommend(const char *direct, fileheader_t *fhdr,
- int ent, const char *buf, int type);
-static int view_postinfo(int ent, const fileheader_t * fhdr, const char *direct, int crs_ln);
-
-#ifdef ASSESS
-static char * const badpost_reason[] = {
- "¼s§i", "¤£·í¥ÎÃã", "¤H¨­§ðÀ»"
-};
-#endif
-
-/* TODO multi.money is a mess.
- * please help verify and finish these.
- */
-/* modes to invalid multi.money */
-#define INVALIDMONEY_MODES (FILE_ANONYMOUS | FILE_BOTTOM | FILE_DIGEST | FILE_BID)
-
-/* query money by fileheader pointer.
- * return <0 if money is not valid.
- */
-int
-query_file_money(const fileheader_t *pfh)
-{
- fileheader_t hdr;
-
- if( (currmode & MODE_SELECT) &&
- (pfh->multi.refer.flag) &&
- (pfh->multi.refer.ref > 0)) // really? not sure, copied from other's code
- {
- char genbuf[MAXPATHLEN];
-
- /* it is assumed that in MODE_SELECT, currboard is selected. */
- setbfile(genbuf, currboard, FN_DIR);
- get_record(genbuf, &hdr, sizeof(hdr), pfh->multi.refer.ref);
- pfh = &hdr;
- }
-
- if(pfh->filemode & INVALIDMONEY_MODES || pfh->multi.money > MAX_POST_MONEY)
- return -1;
-
- return pfh->multi.money;
-}
-
-// lite weight version to update dir files
-static int
-modify_dir_lite(
- const char *direct, int ent, const char *fhdr_name,
- time4_t modified, const char *title, char recommend)
-{
- // since we want to do 'modification'...
- int fd;
- off_t sz = dashs(direct);
- fileheader_t fhdr;
-
- // TODO lock?
- // PttLock(fd, offset, size, F_WRLCK);
- // write(fd, rptr, size);
- // PttLock(fd, offset, size, F_UNLCK);
-
- // prevent black holes
- if (sz < sizeof(fileheader_t) * (ent) ||
- (fd = open(direct, O_RDWR)) < 0 )
- return -1;
-
- // also check if fhdr->filename is same.
- // let sz = base offset
- sz = (sizeof(fileheader_t) * (ent-1));
- if (lseek(fd, sz, SEEK_SET) < 0 ||
- read(fd, &fhdr, sizeof(fhdr)) != sizeof(fhdr) ||
- strcmp(fhdr.filename, fhdr_name) != 0)
- {
- close(fd);
- return -1;
- }
-
- // update records
- if (modified > 0)
- fhdr.modified = modified;
-
- if (title && *title)
- strcpy(fhdr.title, title);
-
- if (recommend)
- {
- recommend += fhdr.recommend;
- if (recommend > MAX_RECOMMENDS) recommend = MAX_RECOMMENDS;
- else if (recommend < -MAX_RECOMMENDS) recommend = -MAX_RECOMMENDS;
- fhdr.recommend = recommend;
- }
-
- if (lseek(fd, sz, SEEK_SET) >= 0)
- write(fd, &fhdr, sizeof(fhdr));
-
- close(fd);
-
- return 0;
-}
-
-static void
-check_locked(fileheader_t *fhdr)
-{
- boardheader_t *bp = NULL;
-
- if (currstat == RMAIL)
- return;
- if (!currboard[0] || currbid <= 0)
- return;
- bp = getbcache(currbid);
- if (!bp)
- return;
- if (!(fhdr->filemode & FILE_SOLVED))
- return;
- if (!(fhdr->filemode & FILE_MARKED))
- return;
- syncnow();
- bp->SRexpire = now;
-}
-
-/* hack for listing modes */
-enum LISTMODES {
- LISTMODE_DATE = 0,
- LISTMODE_MONEY,
-};
-static char *listmode_desc[] = {
- "¤é ´Á",
- "»ù ®æ",
-};
-static int currlistmode = LISTMODE_DATE;
-
-#define IS_LISTING_MONEY \
- (currlistmode == LISTMODE_MONEY || \
- ((currmode & MODE_SELECT) && (currsrmode & RS_MONEY)))
-
-void
-anticrosspost(void)
-{
- log_filef("etc/illegal_money", LOG_CREAT,
- ANSI_COLOR(1;33;46) "%s "
- ANSI_COLOR(37;45) "cross post ¤å³¹ "
- ANSI_COLOR(37) " %s" ANSI_RESET "\n",
- cuser.userid, ctime4(&now));
- post_violatelaw(cuser.userid, BBSMNAME "¨t²Îĵ¹î",
- "Cross-post", "»@³æ³B¥÷");
- cuser.userlevel |= PERM_VIOLATELAW;
- cuser.timeviolatelaw = now;
- cuser.vl_count++;
- mail_id(cuser.userid, "Cross-Post»@³æ",
- "etc/crosspost.txt", BBSMNAME "ĵ¹î³¡¶¤");
- if ((now - cuser.firstlogin) / 86400 < 14)
- delete_allpost(cuser.userid);
- kick_all(cuser.userid); // XXX: in2: wait for testing
- u_exit("Cross Post");
- exit(0);
-}
-
-/* Heat CharlieL */
-int
-save_violatelaw(void)
-{
- char buf[128], ok[3];
- int day;
-
- setutmpmode(VIOLATELAW);
- clear();
- stand_title("ú»@³æ¤¤¤ß");
-
- if (!(cuser.userlevel & PERM_VIOLATELAW)) {
- vmsg("§A¨S¦³³Q¶}»@³æ~~");
- return 0;
- }
-
- day = cuser.vl_count*3 - (now - cuser.timeviolatelaw)/86400;
- if (day > 0) {
- vmsgf("¨Ì·Ó¹H³W¦¸¼Æ, §AÁٻݭn¤Ï¬Ù %d ¤Ñ¤~¯àú»@³æ", day);
- return 0;
- }
- reload_money();
- if (cuser.money < (int)cuser.vl_count * 1000) {
- snprintf(buf, sizeof(buf),
- ANSI_COLOR(1;31) "³o¬O§A²Ä %d ¦¸¹H¤Ï¥»¯¸ªk³W"
- "¥²¶·Ãº¥X %d $Ptt ,§A¥u¦³ %d ¤¸, ¿ú¤£°÷°Õ!!" ANSI_RESET,
- (int)cuser.vl_count, (int)cuser.vl_count * 1000, cuser.money);
- mouts(22, 0, buf);
- pressanykey();
- return 0;
- }
- move(5, 0);
- prints("³o¬O§A²Ä %d ¦¸¹Hªk ¥²¶·Ãº¥X %d $Ptt\n\n",
- cuser.vl_count, cuser.vl_count * 1000);
- outs(ANSI_COLOR(1;37) "§Aª¾¹D¶Ü? ¦]¬°§Aªº¹Hªk "
- "¤w¸g³y¦¨«Ü¦h¤Hªº¤£«K" ANSI_RESET "\n");
- outs(ANSI_COLOR(1;37) "§A¬O§_½T©w¥H«á¤£·|¦A¥Ç¤F¡H" ANSI_RESET "\n");
-
- if (!getdata(10, 0, "½T©w¶Ü¡H[y/N]:", ok, sizeof(ok), LCECHO) ||
- ok[0] != 'y')
- {
- move(15, 0);
- outs( ANSI_COLOR(1;31) "¤£·Q¥I¿ú¶Ü¡H ÁÙ¬O¤£ª¾¹D­n«ö y ¡H\n"
- "½Ð¾i¦¨¬Ý²M·¡¨t²Î°T®§ªº¦n²ßºD¡C\n"
- "µ¥§A·Q³q¤F¦A¨Ó§a!! §Ú¬Û«H§A¤£·|ª¾¿ù¤£§ïªº~~~" ANSI_RESET);
- pressanykey();
- return 0;
- }
-
- //Ptt:check one more time
- reload_money();
- if (cuser.money < (int)cuser.vl_count * 1000)
- {
- log_filef("log/violation", LOG_CREAT,
- "%24.24s %s pay-violation error: race-conditionn hack?\n",
- ctime4(&now), cuser.userid);
- vmsg("¿ú«ç»ò©¿µM¤£°÷¤F¡H ¸Õ¹Ï´ÛÄF¨t²Î³Q¬d¨ì±N¬å±b¸¹¡I");
- return 0;
- }
-
- demoney(-1000 * cuser.vl_count);
- cuser.userlevel &= (~PERM_VIOLATELAW);
- // force overriding alerts
- if(currutmp)
- currutmp->alerts &= ~ALERT_PWD_PERM;
- passwd_update(usernum, &cuser);
- sendalert(cuser.userid, ALERT_PWD_PERM);
- log_filef("log/violation", LOG_CREAT,
- "%24.24s %s pay-violation: $%d complete.\n",
- ctime4(&now), cuser.userid, (int)cuser.vl_count*1000);
-
- vmsg("»@³æ¤w¥I¡A½ÐºÉ³t­«·sµn¤J¡C");
- return 0;
-}
-
-/*
- * void make_blist() { CreateNameList(); apply_boards(g_board_names); }
- */
-
-static time4_t *board_note_time = NULL;
-
-void
-set_board(void)
-{
- boardheader_t *bp;
-
- bp = getbcache(currbid);
- if( !HasBoardPerm(bp) ){
- vmsg("access control violation, exit");
- u_exit("access control violation!");
- exit(-1);
- }
-
- if( HasUserPerm(PERM_SYSOP) &&
- (bp->brdattr & BRD_HIDE) &&
- !is_BM_cache(bp - bcache + 1) &&
- !is_hidden_board_friend((int)(bp - bcache) + 1, currutmp->uid) )
- vmsg("¶i¤J¥¼¸g±ÂÅv¬ÝªO");
-
- board_note_time = &bp->bupdate;
-
- if(bp->BM[0] <= ' ')
- strcpy(currBM, "¼x¨D¤¤");
- else
- {
- /* calculate with other title information */
- int l = 0;
-
- snprintf(currBM, sizeof(currBM), "ªO¥D:%s", bp->BM);
- /* title has +7 leading symbols */
- l += strlen(bp->title);
- if(l >= 7)
- l -= 7;
- else
- l = 0;
- l += 8 + strlen(currboard); /* trailing stuff */
- l += strlen(bp->brdname);
- l = t_columns - l -strlen(currBM);
-
-#ifdef _DEBUG
- {
- char buf[MAXPATHLEN];
- sprintf(buf, "title=%d, brdname=%d, currBM=%d, t_c=%d, l=%d",
- strlen(bp->title), strlen(bp->brdname),
- strlen(currBM), t_columns, l);
- vmsg(buf);
- }
-#endif
-
- if(l < 0 && ((l += strlen(currBM)) > 7))
- {
- currBM[l] = 0;
- currBM[l-1] = currBM[l-2] = '.';
- }
- }
-
- /* init basic perm, but post perm is checked on demand */
- currmode = (currmode & (MODE_DIRTY | MODE_GROUPOP)) | MODE_STARTED;
- if (!HasUserPerm(PERM_NOCITIZEN) &&
- (HasUserPerm(PERM_ALLBOARD) || is_BM_cache(currbid))) {
- currmode = currmode | MODE_BOARD | MODE_POST | MODE_POSTCHECKED;
- }
-}
-
-int IsFreeBoardName(const char *brdname)
-{
- if (strcmp(currboard, GLOBAL_TEST) == 0)
- return 1;
- if (strcmp(currboard, ALLPOST) == 0)
- return 1;
- return 0;
-}
-
-/* check post perm on demand, no double checks in current board
- * currboard MUST be defined!
- * XXX can we replace currboard with currbid ? */
-int
-CheckPostPerm(void)
-{
- static time4_t last_chk_time = 0x0BAD0BB5; /* any magic number */
- static int last_board_index = 0; /* for speed up */
- int valid_index = 0;
- boardheader_t *bp = NULL;
-
- if (currmode & MODE_DIGEST)
- return 0;
-
- if (currmode & MODE_POSTCHECKED)
- {
- /* checked? let's check if perm reloaded */
- if (last_board_index < 1 || last_board_index > SHM->Bnumber)
- {
- /* invalid board index, refetch. */
- last_board_index = getbnum(currboard);
- valid_index = 1;
- }
- assert(0<=last_board_index-1 && last_board_index-1<MAX_BOARD);
- bp = getbcache(last_board_index);
-
- if(bp->perm_reload != last_chk_time)
- currmode &= ~MODE_POSTCHECKED;
- }
-
- if (!(currmode & MODE_POSTCHECKED))
- {
- if(!valid_index)
- {
- last_board_index = getbnum(currboard);
- bp = getbcache(last_board_index);
- }
- last_chk_time = bp->perm_reload;
- currmode |= MODE_POSTCHECKED;
-
- // vmsg("reload board postperm");
-
- if (haspostperm(currboard)) {
- currmode |= MODE_POST;
- return 1;
- }
- currmode &= ~MODE_POST;
- return 0;
- }
- return (currmode & MODE_POST);
-}
-
-int CheckPostRestriction(int bid)
-{
- boardheader_t *bp;
- if ((currmode & MODE_BOARD) || HasUserPerm(PERM_SYSOP))
- return 1;
- assert(0<=bid-1 && bid-1<MAX_BOARD);
- bp = getbcache(bid);
-
- // check first-login
- if (cuser.firstlogin > (now - (time4_t)bp->post_limit_regtime * 2592000))
- return 0;
- if (cuser.numlogins / 10 < (unsigned int)bp->post_limit_logins)
- return 0;
- if (cuser.numposts / 10 < (unsigned int)bp->post_limit_posts)
- return 0;
- if (cuser.badpost > (255 - (unsigned int)bp->post_limit_badpost))
- return 0;
-
- return 1;
-}
-
-static void
-readtitle(void)
-{
- boardheader_t *bp;
- char *brd_title;
-
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- bp = getbcache(currbid);
- if(bp->bvote != 2 && bp->bvote)
- brd_title = "¥»¬ÝªO¶i¦æ§ë²¼¤¤";
- else
- brd_title = bp->title + 7;
-
- showtitle(currBM, brd_title);
- outs("[¡ö]Â÷¶} [¡÷]¾\\Ū [^P]µoªí¤å³¹ [b]³Æ§Ñ¿ý [d]§R°£ [z]ºëµØ°Ï [TAB]¤åºK [h]»¡©ú\n");
- prints(ANSI_COLOR(7) " ½s¸¹ %s §@ ªÌ ¤å ³¹ ¼Ð ÃD",
- IS_LISTING_MONEY ? listmode_desc[LISTMODE_MONEY] : listmode_desc[currlistmode]);
-
-#ifdef USE_COOLDOWN
- if ( bp->brdattr & BRD_COOLDOWN &&
- !((currmode & MODE_BOARD) || HasUserPerm(PERM_SYSOP)))
- outslr("", 44, ANSI_RESET, 0);
- else
-#endif
- {
- char buf[32];
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- sprintf(buf, "¤H®ð:%d ",
- SHM->bcache[currbid - 1].nuser);
- outslr("", 44, buf, -1);
- outs(ANSI_RESET);
- }
-}
-
-static void
-readdoent(int num, fileheader_t * ent)
-{
- int type = ' ';
- char *mark, *title,
- color, special = 0, isonline = 0, recom[8];
- char *typeattr = "";
- char isunread = 0, oisunread = 0;
-
- oisunread = isunread =
- brc_unread(currbid, ent->filename, ent->modified);
-
- // modified tag
- if (isunread == 2)
- {
- // ignore unread, if user doesn't want to show it.
- if (cuser.uflag & NO_MODMARK_FLAG)
- {
- oisunread = isunread = 0;
- }
- // if user wants colored marks, use 'read' marks
- else if (cuser.uflag & COLORED_MODMARK)
- {
- isunread = 0;
- typeattr = ANSI_COLOR(36);
- }
- }
-
- type = isunread ? '+' : ' ';
- if (isunread == 2) type = '~';
-
- // handle 'type"
- if ((currmode & MODE_BOARD) && (ent->filemode & FILE_DIGEST))
- type = (type == ' ') ? '*' : '#';
- else if (currmode & MODE_BOARD || HasUserPerm(PERM_LOGINOK))
- {
- if (ent->filemode & FILE_MARKED)
- {
- if(ent->filemode & FILE_SOLVED)
- type = '!';
- else if (isunread == 0)
- type = 'm';
- else if (isunread == 1)
- type = 'M';
- else if (isunread == 2)
- type = '=';
- } else if (TagNum && !Tagger(atoi(ent->filename + 2), 0, TAG_NIN))
- type = 'D';
- else if (ent->filemode & FILE_SOLVED)
- type = (type == ' ') ? 's': 'S';
- }
-
- // the only special case: ' ' with isunread == 2,
- // change to '+' with gray attribute.
- if (type == ' ' && oisunread == 2)
- {
- typeattr = ANSI_COLOR(1;30);
- type = '+';
- }
-
- title = ent->filename[0]!='L' ? subject(ent->title) : "<¥»¤åÂê©w>";
- if (ent->filemode & FILE_VOTE)
- color = '2', mark = "£¾";
- else if (ent->filemode & FILE_BID)
- color = '6', mark = "¢C";
- else if (title == ent->title)
- color = '1', mark = "¡¼";
- else
- color = '3', mark = "R:";
-
- /* §â¹Lªøªº title ¬å±¼¡C «e­±¬ù¦³ 33 ­Ó¦r¤¸¡C */
- {
- int l = t_columns - 34; /* 33+1, for trailing one more space */
- unsigned char *p = (unsigned char*)title;
-
- /* strlen ¶¶«K°µ safe print checking */
- while (*p && l > 0)
- {
- /* ¥»¨ÓÀ³¸Ó°µ DBCS checking, Ãi±o¼g¤F */
- if(*p < ' ')
- *p = ' ';
- p++, l--;
- }
-
- if (*p && l <= 0)
- strcpy((char*)p-3, " ¡K");
- }
-
- if (!strncmp(title, "[¤½§i]", 6))
- special = 1;
-
- isonline = query_online(ent->owner);
-
- if(ent->recommend >= MAX_RECOMMENDS)
- strcpy(recom,"1mÃz");
- else if(ent->recommend>9)
- sprintf(recom,"3m%2d",ent->recommend);
- else if(ent->recommend>0)
- sprintf(recom,"2m%2d",ent->recommend);
- else if(ent->recommend <= -MAX_RECOMMENDS)
- sprintf(recom,"0mXX");
- else if(ent->recommend<-10)
- sprintf(recom,"0mX%d",-ent->recommend);
- else strcpy(recom,"0m ");
-
- /* start printing */
- if (ent->filemode & FILE_BOTTOM)
- outs(" " ANSI_COLOR(1;33) " ¡¹ " ANSI_RESET);
- else
- /* recently we found that many boards have >10k articles,
- * so it's better to use 5+2 (2 for cursor marker) here.
- * XXX if we are in big term, enlarge here.
- */
- prints("%7d", num);
-
- prints(" %s%c" ESC_STR "[0;1;3%4.4s" ANSI_RESET,
- typeattr, type, recom);
-
- if(IS_LISTING_MONEY)
- {
- int m = query_file_money(ent);
- if(m < 0)
- outs(" ---- ");
- else
- prints("%5d ", m);
- }
- else // LISTMODE_DATE
- {
-#ifdef COLORDATE
- prints(ANSI_COLOR(%d) "%-6.5s" ANSI_RESET,
- (ent->date[3] + ent->date[4]) % 7 + 31, ent->date);
-#else
- prints("%-6.5s", ent->date);
-#endif
- }
-
- // print author
- if(isonline) outs(ANSI_COLOR(1));
- prints("%-13.12s", ent->owner);
- if(isonline) outs(ANSI_RESET);
-
- if (strncmp(currtitle, title, TTLEN))
- prints("%s " ANSI_COLOR(1) "%.*s" ANSI_RESET "%s\n",
- mark, special ? 6 : 0, title, special ? title + 6 : title);
- else
- prints(ANSI_COLOR(1;3%c) "%s %s" ANSI_RESET "\n",
- color, mark, title);
-}
-
-int
-whereami(void)
-{
- boardheader_t *bh, *p[WHEREAMI_LEVEL];
- int i, j;
- int bid = currbid;
-
- if (!bid)
- return 0;
-
- move(1, 0);
- clrtobot();
- assert(0<=bid-1 && bid-1<MAX_BOARD);
- bh = getbcache(bid);
- p[0] = bh;
- for (i = 0; i+1 < WHEREAMI_LEVEL && p[i]->parent>1 && p[i]->parent < numboards; i++)
- p[i + 1] = getbcache(p[i]->parent);
- j = i;
- prints("§Ú¦b­þ?\n%-40.40s %.13s\n", p[j]->title + 7, p[j]->BM);
- for (j--; j >= 0; j--)
- prints("%*s %-13.13s %-37.37s %.13s\n", (i - j) * 2, "",
- p[j]->brdname, p[j]->title,
- p[j]->BM);
-
- pressanykey();
- return FULLUPDATE;
-}
-
-
-static int
-do_select(void)
-{
- char bname[20];
-
- setutmpmode(SELECT);
- move(0, 0);
- clrtoeol();
- CompleteBoard(MSG_SELECT_BOARD, bname);
-
- if(enter_board(bname) < 0)
- return FULLUPDATE;
-
- move(1, 0);
- clrtoeol();
- return NEWDIRECT;
-}
-
-/* ----------------------------------------------------- */
-/* §ï¨} innbbsd Âà¥X«H¥ó¡B³s½u¬å«H¤§³B²zµ{§Ç */
-/* ----------------------------------------------------- */
-void
-outgo_post(const fileheader_t *fh, const char *board, const char *userid, const char *nickname)
-{
- FILE *foo;
-
- if ((foo = fopen("innd/out.bntp", "a"))) {
- fprintf(foo, "%s\t%s\t%s\t%s\t%s\n",
- board, fh->filename, userid, nickname, fh->title);
- fclose(foo);
- }
-}
-
-static void
-cancelpost(const fileheader_t *fh, int by_BM, char *newpath)
-{
- FILE *fin, *fout;
- char *ptr, *brd;
- fileheader_t postfile;
- char genbuf[200];
- char nick[STRLEN], fn1[MAXPATHLEN];
- int len = 42-strlen(currboard);
- struct tm *ptime = localtime4(&now);
-
- if(!fh->filename[0]) return;
- setbfile(fn1, currboard, fh->filename);
- if ((fin = fopen(fn1, "r"))) {
- brd = by_BM ? "deleted" : "junk";
-
- memcpy(&postfile, fh, sizeof(fileheader_t));
- setbpath(newpath, brd);
- stampfile_u(newpath, &postfile);
-
- nick[0] = '\0';
- while (fgets(genbuf, sizeof(genbuf), fin)) {
- if (!strncmp(genbuf, str_author1, LEN_AUTHOR1) ||
- !strncmp(genbuf, str_author2, LEN_AUTHOR2)) {
- if ((ptr = strrchr(genbuf, ')')))
- *ptr = '\0';
- if ((ptr = (char *)strchr(genbuf, '(')))
- strlcpy(nick, ptr + 1, sizeof(nick));
- break;
- }
- }
- if(!strncasecmp(postfile.title, str_reply, 3))
- len=len+4;
- sprintf(postfile.title, "%-*.*s.%sªO", len, len, fh->title, currboard);
-
- if ((fout = fopen("innd/cancel.bntp", "a"))) {
- fprintf(fout, "%s\t%s\t%s\t%s\t%s\n", currboard, fh->filename,
- cuser.userid, nick, fh->title);
- fclose(fout);
- }
- fclose(fin);
- log_filef(fn1, LOG_CREAT, "\n¡° Deleted by: %s (%s) %d/%d",
- cuser.userid, fromhost, ptime->tm_mon + 1, ptime->tm_mday);
- Rename(fn1, newpath);
- setbdir(genbuf, brd);
- append_record(genbuf, &postfile, sizeof(postfile));
- setbtotal(getbnum(brd));
- }
-}
-
-static void
-do_deleteCrossPost(const fileheader_t *fh, char bname[])
-{
- char bdir[MAXPATHLEN]="", file[MAXPATHLEN]="";
- fileheader_t newfh;
- if(!bname || !fh) return;
-
- int i, bid = getbnum(bname);
- if(bid <=0 || !fh->filename[0]) return;
-
- boardheader_t *bp = getbcache(bid);
- if(!bp) return;
-
- setbdir(bdir, bname);
- setbfile(file, bname, fh->filename);
- memcpy(&newfh, fh, sizeof(fileheader_t));
- // Ptt: protect original fh
- // because getindex safe_article_delete will change fh in some case
- if( (i=getindex(bdir, &newfh, 0))>0)
- {
-#ifdef SAFE_ARTICLE_DELETE
- if(bp && !(currmode & MODE_DIGEST) && bp->nuser > 30 )
- safe_article_delete(i, &newfh, bdir);
- else
-#endif
- delete_record(bdir, sizeof(fileheader_t), i);
- setbtotal(bid);
- unlink(file);
- }
-}
-
-static void
-deleteCrossPost(const fileheader_t *fh, char *bname)
-{
- if(!fh || !fh->filename[0]) return;
-
- if(!strcmp(bname, ALLPOST) || !strcmp(bname, "NEWIDPOST") ||
- !strcmp(bname, ALLHIDPOST) || !strcmp(bname, "UnAnonymous"))
- {
- int len=0;
- char xbname[TTLEN + 1], *po = strrchr(fh->title, '.');
- if(!po) return;
- po++;
- len = (int) strlen(po)-2;
-
- if(len > TTLEN) return;
- sprintf(xbname, "%.*s", len, po);
- do_deleteCrossPost(fh, xbname);
- }
- else
- {
- do_deleteCrossPost(fh, ALLPOST);
- }
-}
-
-void
-delete_allpost(const char *userid)
-{
- fileheader_t fhdr;
- int fd, i;
- char bdir[MAXPATHLEN]="", file[MAXPATHLEN]="";
-
- if(!userid) return;
-
- setbdir(bdir, ALLPOST);
- if( (fd = open(bdir, O_RDWR)) != -1)
- {
- for(i=0; read(fd, &fhdr, sizeof(fileheader_t)) >0; i++){
- if(strcmp(fhdr.owner, userid))
- continue;
- deleteCrossPost(&fhdr, ALLPOST);
- setbfile(file, ALLPOST, fhdr.filename);
- unlink(file);
-
- sprintf(fhdr.title, "(¥»¤å¤w³Q§R°£)");
- strcpy(fhdr.filename, ".deleted");
- strcpy(fhdr.owner, "-");
- lseek(fd, sizeof(fileheader_t) * i, SEEK_SET);
- write(fd, &fhdr, sizeof(fileheader_t));
- }
- close(fd);
- }
-}
-
-/* ----------------------------------------------------- */
-/* µoªí¡B¦^À³¡B½s¿è¡BÂà¿ý¤å³¹ */
-/* ----------------------------------------------------- */
-static int
-solveEdFlagByBoard(const char *bn, int flags)
-{
- if (
-#ifdef GLOBAL_BBSMOVIE
- strcmp(bn, GLOBAL_BBSMOVIE) == 0 ||
-#endif
-#ifdef GLOBAL_TEST
- strcmp(bn, GLOBAL_TEST) == 0 ||
-#endif
- 0
- )
- {
- flags |= EDITFLAG_UPLOAD | EDITFLAG_ALLOWLARGE;
- }
- return flags;
-}
-
-void
-do_reply_title(int row, const char *title)
-{
- char genbuf[200];
- char genbuf2[4];
- char tmp_title[STRLEN];
-
- if (strncasecmp(title, str_reply, 4))
- snprintf(tmp_title, sizeof(tmp_title), "Re: %s", title);
- else
- strlcpy(tmp_title, title, sizeof(tmp_title));
- tmp_title[TTLEN - 1] = '\0';
- snprintf(genbuf, sizeof(genbuf), "±Ä¥Î­ì¼ÐÃD¡m%.60s¡n¶Ü?[Y] ", tmp_title);
- getdata(row, 0, genbuf, genbuf2, 4, LCECHO);
- if (genbuf2[0] == 'n' || genbuf2[0] == 'N')
- getdata(++row, 0, "¼ÐÃD¡G", tmp_title, TTLEN, DOECHO);
- // don't getdata() on non-local variable save_title directly, to avoid reentrant crash.
- strlcpy(save_title, tmp_title, sizeof(save_title));
-}
-
-void
-do_crosspost(const char *brd, fileheader_t *postfile, const char *fpath,
- int isstamp)
-{
- char genbuf[200];
- int len = 42-strlen(currboard);
- fileheader_t fh;
- int bid = getbnum(brd);
-
- if(bid <= 0 || bid > MAX_BOARD) return;
-
- if(!strncasecmp(postfile->title, str_reply, 3))
- len=len+4;
-
- memcpy(&fh, postfile, sizeof(fileheader_t));
- if(isstamp)
- {
- setbpath(genbuf, brd);
- stampfile(genbuf, &fh);
- }
- else
- setbfile(genbuf, brd, postfile->filename);
-
- if(!strcmp(brd, "UnAnonymous"))
- strcpy(fh.owner, cuser.userid);
-
- sprintf(fh.title,"%-*.*s.%sªO", len, len, postfile->title, currboard);
- unlink(genbuf);
- Copy((char *)fpath, genbuf);
- postfile->filemode = FILE_LOCAL;
- setbdir(genbuf, brd);
- if (append_record(genbuf, &fh, sizeof(fileheader_t)) != -1) {
- SHM->lastposttime[bid - 1] = now;
- touchbpostnum(bid, 1);
- }
-}
-static void
-setupbidinfo(bid_t *bidinfo)
-{
- char buf[PATHLEN];
- bidinfo->enddate = gettime(20, now+86400,"µ²§ô¼Ð®×©ó");
- do{
- getdata_str(21, 0, "©³»ù:", buf, 8, LCECHO, "1");
- } while( (bidinfo->high = atoi(buf)) <= 0 );
- do{
- getdata_str(21, 20, "¨C¼Ð¦Ü¤Ö¼W¥[¦h¤Ö:", buf, 5, LCECHO, "1");
- } while( (bidinfo->increment = atoi(buf)) <= 0 );
- getdata(21,44, "ª½±µÁʶR»ù(¥i¤£³]):",buf, 10, LCECHO);
- bidinfo->buyitnow = atoi(buf);
-
- getdata_str(22,0,
- "¥I´Ú¤è¦¡: 1." MONEYNAME "¹ô 2.¶l§½©Î»È¦æÂà±b"
- "3.¤ä²¼©Î¹q¶× 4.¶l§½³f¨ì¥I´Ú [1]:",
- buf, 3, LCECHO,"1");
- bidinfo->payby = (buf[0] - '1');
- if( bidinfo->payby < 0 || bidinfo->payby > 3)
- bidinfo->payby = 0;
- getdata_str(23, 0, "¹B¶O(0:§K¹B¶O©Î¤å¤¤»¡©ú)[0]:", buf, 6, LCECHO, "0");
- bidinfo->shipping = atoi(buf);
- if( bidinfo->shipping < 0 )
- bidinfo->shipping = 0;
-}
-static void
-print_bidinfo(FILE *io, bid_t bidinfo)
-{
- char *payby[4]={MONEYNAME "¹ô", "¶l§½©Î»È¦æÂà±b",
- "¤ä²¼©Î¹q¶×", "¶l§½³f¨ì¥I´Ú"};
- if(io){
- if( !bidinfo.userid[0] )
- fprintf(io, "°_¼Ð»ù: %-20d\n", bidinfo.high);
- else
- fprintf(io, "¥Ø«e³Ì°ª»ù:%-20d¥X»ùªÌ:%-16s\n",
- bidinfo.high, bidinfo.userid);
- fprintf(io, "¥I´Ú¤è¦¡: %-20sµ²§ô©ó:%-16s\n",
- payby[bidinfo.payby % 4], Cdate(& bidinfo.enddate));
- if(bidinfo.buyitnow)
- fprintf(io, "ª½±µÁʶR»ù:%-20d", bidinfo.buyitnow);
- if(bidinfo.shipping)
- fprintf(io, "¹B¶O:%d", bidinfo.shipping);
- fprintf(io, "\n");
- }
- else{
- if(!bidinfo.userid[0])
- prints("°_¼Ð»ù: %-20d\n", bidinfo.high);
- else
- prints("¥Ø«e³Ì°ª»ù:%-20d¥X»ùªÌ:%-16s\n",
- bidinfo.high, bidinfo.userid);
- prints("¥I´Ú¤è¦¡: %-20sµ²§ô©ó:%-16s\n",
- payby[bidinfo.payby % 4], Cdate(& bidinfo.enddate));
- if(bidinfo.buyitnow)
- prints("ª½±µÁʶR»ù:%-20d", bidinfo.buyitnow);
- if(bidinfo.shipping)
- prints("¹B¶O:%d", bidinfo.shipping);
- outc('\n');
- }
-}
-
-static int
-do_general(int isbid)
-{
- bid_t bidinfo;
- fileheader_t postfile;
- char fpath[PATHLEN], buf[STRLEN];
- int aborted, defanony, ifuseanony, i;
- char genbuf[PATHLEN], *owner;
- char ctype[8][5] = {"°ÝÃD", "«Øij", "°Q½×", "¤ß±o",
- "¶¢²á", "½Ð¯q", "¤½§i", "±¡³ø"};
- boardheader_t *bp;
- int islocal, posttype=-1, edflags = 0;
-
- ifuseanony = 0;
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- bp = getbcache(currbid);
-
- if( !CheckPostPerm()
-#ifdef FOREIGN_REG
- // ¤£¬O¥~Äy¨Ï¥ÎªÌ¦b PttForeign ªO
- && !((cuser.uflag2 & FOREIGN) &&
- strcmp(bp->brdname, GLOBAL_FOREIGN) == 0)
-#endif
- ) {
- vmsg("¹ï¤£°_¡A±z¥Ø«eµLªk¦b¦¹µoªí¤å³¹¡I");
- return READ_REDRAW;
- }
-
-#ifndef DEBUG
- if ( !CheckPostRestriction(currbid) )
- {
- vmsg("§A¤£°÷¸ê²`³á¡I (¥i«ö i ¬d¬Ý­­¨î)");
- return FULLUPDATE;
- }
-#ifdef USE_COOLDOWN
- if(check_cooldown(bp))
- return READ_REDRAW;
-#endif
-#endif
- clear();
-
- if(likely(!isbid))
- setbfile(genbuf, currboard, FN_POST_NOTE);
- else
- setbfile(genbuf, currboard, FN_POST_BID);
-
- if (more(genbuf, NA) == -1) {
- if(!isbid)
- more("etc/" FN_POST_NOTE, NA);
- else
- more("etc/" FN_POST_BID, NA);
- }
- move(19, 0);
- prints("%s©ó¡i" ANSI_COLOR(33) " %s" ANSI_RESET " ¡j "
- ANSI_COLOR(32) "%s" ANSI_RESET " ¬ÝªO\n",
- isbid?"¤½¶}©Û¼Ð":"µoªí¤å³¹",
- currboard, bp->title + 7);
-
- if (unlikely(isbid)) {
- memset(&bidinfo,0,sizeof(bidinfo));
- setupbidinfo(&bidinfo);
- postfile.multi.money=bidinfo.high;
- move(20,0);
- clrtobot();
- }
- if (quote_file[0])
- do_reply_title(20, currtitle);
- else {
- char tmp_title[STRLEN]="";
- if (!isbid) {
- move(21,0);
- outs("ºØÃþ¡G");
- for(i=0; i<8 && bp->posttype[i*4]; i++)
- strlcpy(ctype[i],bp->posttype+4*i,5);
- if(i==0) i=8;
- for(aborted=0; aborted<i; aborted++)
- prints("%d.%4.4s ", aborted+1, ctype[aborted]);
- sprintf(buf,"(1-%d©Î¤£¿ï)",i);
- getdata(21, 6+7*i, buf, tmp_title, 3, LCECHO);
- posttype = tmp_title[0] - '1';
- if (posttype >= 0 && posttype < i)
- snprintf(tmp_title, sizeof(tmp_title),
- "[%s] ", ctype[posttype]);
- else
- {
- tmp_title[0] = '\0';
- posttype=-1;
- }
- }
- getdata_buf(22, 0, "¼ÐÃD¡G", tmp_title, TTLEN, DOECHO);
- strip_ansi(tmp_title, tmp_title, STRIP_ALL);
- if( strcmp(tmp_title, "[711iB] ¼W¥[¤W¯¸¦¸¼Æµ{¦¡") == 0 ){
- cuser.userlevel |= PERM_VIOLATELAW;
- sleep(60);
- u_exit("bad program");
- }
- strlcpy(save_title, tmp_title, sizeof(save_title));
- }
- if (save_title[0] == '\0')
- return FULLUPDATE;
-
- curredit &= ~EDIT_MAIL;
- curredit &= ~EDIT_ITEM;
- setutmpmode(POSTING);
- /* ¥¼¨ã³Æ Internet Åv­­ªÌ¡A¥u¯à¦b¯¸¤ºµoªí¤å³¹ */
- /* ªO¥D¹w³]¯¸¤º¦sÀÉ */
- if (HasUserPerm(PERM_INTERNET) && !(bp->brdattr & BRD_LOCALSAVE))
- local_article = 0;
- else
- local_article = 1;
-
- /* build filename */
- setbpath(fpath, currboard);
- stampfile(fpath, &postfile);
- if(isbid) {
- FILE *fp;
- if( (fp = fopen(fpath, "w")) != NULL ){
- print_bidinfo(fp, bidinfo);
- fclose(fp);
- }
- }
- else if(posttype!=-1 && ((1<<posttype) & bp->posttype_f)) {
- setbnfile(genbuf, bp->brdname, "postsample", posttype);
- Copy(genbuf, fpath);
- }
-
- edflags = EDITFLAG_ALLOWTITLE;
- edflags = solveEdFlagByBoard(currboard, edflags);
-
- aborted = vedit2(fpath, YEA, &islocal, edflags);
- if (aborted == -1) {
- unlink(fpath);
- pressanykey();
- return FULLUPDATE;
- }
- /* set owner to Anonymous for Anonymous board */
-
-#ifdef HAVE_ANONYMOUS
- /* Ptt and Jaky */
- defanony = currbrdattr & BRD_DEFAULTANONYMOUS;
- if ((currbrdattr & BRD_ANONYMOUS) &&
- ((strcmp(real_name, "r") && defanony) || (real_name[0] && !defanony))
- ) {
- strcat(real_name, ".");
- owner = real_name;
- ifuseanony = 1;
- } else
- owner = cuser.userid;
-#else
- owner = cuser.userid;
-#endif
-
- /* ¿ú */
- if (aborted > MAX_POST_MONEY * 2)
- aborted = MAX_POST_MONEY;
- else
- aborted /= 2;
-
- if(ifuseanony) {
- postfile.filemode |= FILE_ANONYMOUS;
- postfile.multi.anon_uid = currutmp->uid;
- }
- else if(!isbid)
- {
- /* general article */
- postfile.modified = dasht(fpath);
- postfile.multi.money = aborted;
- }
-
- strlcpy(postfile.owner, owner, sizeof(postfile.owner));
- strlcpy(postfile.title, save_title, sizeof(postfile.title));
- if (islocal) /* local save */
- postfile.filemode |= FILE_LOCAL;
-
- setbdir(buf, currboard);
-
- // Ptt: stamp file again to make it order
- // fix the bug that search failure in getindex
- // stampfile_u is used when you don't want to clear other fields
- strcpy(genbuf, fpath);
- setbpath(fpath, currboard);
- stampfile_u(fpath, &postfile);
-
- // warning: filename should be retrieved from new fpath.
- if(isbid) {
- char bidfn[PATHLEN] = "";
- sprintf(bidfn, "%s.bid", fpath);
- append_record(bidfn,(void*) &bidinfo, sizeof(bidinfo));
- postfile.filemode |= FILE_BID ;
- }
-
- if (append_record(buf, &postfile, sizeof(postfile)) == -1)
- {
- unlink(genbuf);
- }
- else
- {
- char addPost = 0;
- rename(genbuf, fpath);
-#ifdef LOGPOST
- {
- FILE *fp = fopen("log/post", "a");
- fprintf(fp, "%d %s boards/%c/%s/%s\n",
- now, cuser.userid, currboard[0], currboard,
- postfile.filename);
- fclose(fp);
- }
-#endif
- setbtotal(currbid);
-
- if( currmode & MODE_SELECT )
- append_record(currdirect, &postfile, sizeof(postfile));
- if( !islocal && !(bp->brdattr & BRD_NOTRAN) ){
-#ifdef HAVE_ANONYMOUS
- if( ifuseanony )
- outgo_post(&postfile, currboard, owner, "Anonymous.");
- else
-#endif
- outgo_post(&postfile, currboard, cuser.userid, cuser.nickname);
- }
- brc_addlist(postfile.filename, postfile.modified);
-
- if( !bp->level || (currbrdattr & BRD_POSTMASK))
- {
- if ((now - cuser.firstlogin) / 86400 < 14)
- do_crosspost("NEWIDPOST", &postfile, fpath, 0);
-
- if (!(currbrdattr & BRD_HIDE) )
- do_crosspost(ALLPOST, &postfile, fpath, 0);
- else
- do_crosspost(ALLHIDPOST, &postfile, fpath, 0);
- }
- outs("¶¶§Q¶K¥X§G§i¡A");
-
-#ifdef MAX_POST_MONEY
- if (aborted > MAX_POST_MONEY)
- aborted = MAX_POST_MONEY;
-#endif
- if (!IsFreeBoardName(currboard) && !ifuseanony &&
- !(currbrdattr&BRD_BAD)) {
-
- if(postfile.filemode&FILE_BID)
- outs("©Û¼Ð¤å³¹¨S¦³½Z¹S¡C");
- else if (aborted > 0)
- {
- demoney(aborted);
- addPost = 1;
- prints("³o¬O±zªº²Ä %d ½g¤å³¹¡A½Z¹S %d »È¡C",
- ++cuser.numposts, aborted);
- } else {
- // no money, no record.
- outs("¥»½g¤£¦C¤J°O¿ý¡A·q½Ð¥]²[¡C");
- }
- } else
- outs("¤£¦C¤J°O¿ý¡A·q½Ð¥]²[¡C");
-
- /* ¦^À³¨ì­ì§@ªÌ«H½c */
-
- if (curredit & EDIT_BOTH) {
- char *str, *msg = "¦^À³¦Ü§@ªÌ«H½c";
-
- genbuf[0] = 0;
- // XXX quote_user may contain invalid user, like '-' (deleted).
- if (is_validuserid(quote_user))
- {
- sethomepath(genbuf, quote_user);
- if (!dashd(genbuf))
- {
- genbuf[0] = 0;
- msg = err_uid;
- }
- }
-
- // now, genbuf[0] = "if user exists".
- if (genbuf[0])
- {
- stampfile(genbuf, &postfile);
- unlink(genbuf);
- Copy(fpath, genbuf);
-
- strlcpy(postfile.owner, cuser.userid, sizeof(postfile.owner));
- strlcpy(postfile.title, save_title, sizeof(postfile.title));
- sethomedir(genbuf, quote_user);
- if (append_record(genbuf, &postfile, sizeof(postfile)) == -1)
- msg = err_uid;
- else
- sendalert(quote_user, ALERT_NEW_MAIL);
- } else if ((str = strchr(quote_user, '.'))) {
- if (
-#ifndef USE_BSMTP
- bbs_sendmail(fpath, save_title, str + 1)
-#else
- bsmtp(fpath, save_title, str + 1)
-#endif
- < 0)
- msg = "§@ªÌµLªk¦¬«H";
- } else {
- // unknown user id
- msg = "§@ªÌµLªk¦¬«H";
- }
- outs(msg);
- curredit ^= EDIT_BOTH;
- } // if (curredit & EDIT_BOTH)
- if (currbrdattr & BRD_ANONYMOUS)
- do_crosspost("UnAnonymous", &postfile, fpath, 0);
-#ifdef USE_COOLDOWN
- if(bp->nuser>30)
- {
- if (cooldowntimeof(usernum)<now)
- add_cooldowntime(usernum, 5);
- }
- add_posttimes(usernum, 1);
-#endif
- // Notify all logins
- if (addPost)
- {
-
- }
- }
- pressanykey();
- return FULLUPDATE;
-}
-
-int
-do_post(void)
-{
- boardheader_t *bp;
- STATINC(STAT_DOPOST);
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- bp = getbcache(currbid);
- if (bp->brdattr & BRD_VOTEBOARD)
- return do_voteboard(0);
- else if (!(bp->brdattr & BRD_GROUPBOARD))
- return do_general(0);
- return 0;
-}
-
-int
-do_post_vote(void)
-{
- return do_voteboard(1);
-}
-
-int
-do_post_openbid(void)
-{
- char ans[4];
- boardheader_t *bp;
-
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- bp = getbcache(currbid);
- if (!(bp->brdattr & BRD_VOTEBOARD))
- {
- getdata(b_lines - 1, 0,
- "½T©w­n¤½¶}©Û¼Ð¶Ü¡H [y/N] ",
- ans, sizeof(ans), LCECHO);
- if(ans[0] != 'y')
- return FULLUPDATE;
-
- return do_general(1);
- }
- return 0;
-}
-
-static void
-do_generalboardreply(/*const*/ fileheader_t * fhdr)
-{
- char genbuf[3];
-
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- if (!CheckPostRestriction(currbid))
- {
- getdata(b_lines - 1, 0, "¡¶ ¦^À³¦Ü (M)§@ªÌ«H½c (Q)¨ú®ø¡H[M] ",
- genbuf, sizeof(genbuf), LCECHO);
- switch (genbuf[0]) {
- case 'q':
- break;
- default:
- mail_reply(0, fhdr, 0);
- }
- }
- else {
- getdata(b_lines - 1, 0,
- "¡¶ ¦^À³¦Ü (F)¬ÝªO (M)§@ªÌ«H½c (B)¤GªÌ¬Ò¬O (Q)¨ú®ø¡H[F] ",
- genbuf, sizeof(genbuf), LCECHO);
- switch (genbuf[0]) {
- case 'm':
- mail_reply(0, fhdr, 0);
- case 'q':
- break;
-
- case 'b':
- curredit = EDIT_BOTH;
- default:
- strlcpy(currtitle, fhdr->title, sizeof(currtitle));
- strlcpy(quote_user, fhdr->owner, sizeof(quote_user));
- do_post();
- curredit &= ~EDIT_BOTH;
- }
- }
- *quote_file = 0;
-}
-
-
-int
-invalid_brdname(const char *brd)
-{
- register char ch, rv=0;
-
- ch = *brd++;
- if (!isalpha((int)ch))
- rv = 2;
- while ((ch = *brd++)) {
- if (not_alnum(ch) && ch != '_' && ch != '-' && ch != '.')
- return (1|rv);
- }
- return rv;
-}
-
-int
-b_call_in(int ent, const fileheader_t * fhdr, const char *direct)
-{
- userinfo_t *u = search_ulist(searchuser(fhdr->owner, NULL));
- if (u) {
- int fri_stat;
- fri_stat = friend_stat(currutmp, u);
- if (isvisible_stat(currutmp, u, fri_stat) && call_in(u, fri_stat))
- return FULLUPDATE;
- }
- return DONOTHING;
-}
-
-
-static int
-do_reply(/*const*/ fileheader_t * fhdr)
-{
- boardheader_t *bp;
- if (!fhdr || !fhdr->filename[0])
- return DONOTHING;
-
- if (!CheckPostPerm() ) return DONOTHING;
- if (fhdr->filemode &FILE_SOLVED)
- {
- if(fhdr->filemode & FILE_MARKED)
- {
- vmsg("«Ü©êºp, ¦¹¤å³¹¤wµ²®×¨Ã¼Ð°O, ¤£±o¦^À³.");
- return FULLUPDATE;
- }
- if(getkey("¦¹½g¤å³¹¤wµ²®×, ¬O§_¯uªº­n¦^À³?(y/N)")!='y')
- return FULLUPDATE;
- }
-
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- bp = getbcache(currbid);
- if (bp->brdattr & BRD_NOREPLY) {
- // try to reply by mail.
- // vmsg("«Ü©êºp, ¥»ªO¤£¶}©ñ¦^ÂФ峹.");
- // return FULLUPDATE;
- return mail_reply(0, fhdr, 0);
- }
-
- setbfile(quote_file, bp->brdname, fhdr->filename);
- if (bp->brdattr & BRD_VOTEBOARD || (fhdr->filemode & FILE_VOTE))
- do_voteboardreply(fhdr);
- else
- do_generalboardreply(fhdr);
- *quote_file = 0;
- return FULLUPDATE;
-}
-
-static int
-reply_post(int ent, /*const*/ fileheader_t * fhdr, const char *direct)
-{
- return do_reply(fhdr);
-}
-
-#ifdef EDITPOST_SMARTMERGE
-
-#define HASHPF_RET_OK (0)
-
-// return: 0 - ok; otherwise - fail.
-static int
-hash_partial_file( char *path, size_t sz, unsigned char output[SMHASHLEN] )
-{
- int fd;
- size_t n;
- unsigned char buf[1024];
-
- Fnv64_t fnvseed = FNV1_64_INIT;
- assert(SMHASHLEN == sizeof(fnvseed));
-
- fd = open(path, O_RDONLY);
- if (fd < 0)
- return 1;
-
- while( sz > 0 &&
- (n = read(fd, buf, sizeof(buf))) > 0 )
- {
- if (n > sz) n = sz;
- fnvseed = fnv_64_buf(buf, (int) n, fnvseed);
- sz -= n;
- }
- close(fd);
-
- if (sz > 0) // file is different
- return 2;
-
- memcpy(output, (void*) &fnvseed, sizeof(fnvseed));
- return HASHPF_RET_OK;
-}
-#endif // EDITPOST_SMARTMERGE
-
-int
-edit_post(int ent, fileheader_t * fhdr, const char *direct)
-{
- char fpath[80];
- char genbuf[200];
- fileheader_t postfile;
- boardheader_t *bp = getbcache(currbid);
- // int recordTouched = 0;
- time4_t oldmt, newmt;
- off_t oldsz;
- int edflags = 0;
-
-#ifdef EDITPOST_SMARTMERGE
- char canDoSmartMerge = 1;
-#endif // EDITPOST_SMARTMERGE
-
-#ifdef EXP_EDITPOST_TEXTONLY
- // experimental: "text only" editing
- edflags |= EXP_EDITPOST_TEXTONLY;
-#endif
-
- assert(0<=currbid-1 && currbid-1<MAX_BOARD && bp);
-
- // special modes (plus MODE_DIGEST?)
- if( currmode & MODE_SELECT )
- return DONOTHING;
-
- // board check
- if (strcmp(bp->brdname, GLOBAL_SECURITY) == EQUSTR ||
- (bp->brdattr & BRD_VOTEBOARD))
- return DONOTHING;
-
- // file check
- if (fhdr->filemode & FILE_VOTE)
- return DONOTHING;
-
-#ifdef SAFE_ARTICLE_DELETE
- if( fhdr->filename[0] == '.' )
- return DONOTHING;
-#endif
-
- // user check
- if (!HasUserPerm(PERM_BASIC) || // includeing guests
- !CheckPostPerm() )
- return DONOTHING;
-
- if (strcmp(fhdr->owner, cuser.userid) != EQUSTR)
- {
- if (!HasUserPerm(PERM_SYSOP))
- return DONOTHING;
-
- // admin edit!
- log_filef("log/security", LOG_CREAT,
- "%d %24.24s %d %s admin edit (board) file=%s\n",
- (int)now, ctime4(&now), getpid(), cuser.userid, fpath);
- }
-
- edflags = EDITFLAG_ALLOWTITLE;
- edflags = solveEdFlagByBoard(bp->brdname, edflags);
-
- setutmpmode(REEDIT);
-
-
- // XXX ¤£ª¾¦ó®É°_¡A edit_post ¤w¸g¤£·|¦³ + ¸¹¤F...
- // ¥þ³¡³£¬O Sysop Edit ªº­ì¦a§Î¦¡¡C
- // ­þ¤Ñ¦³ªÅ§ä­Ó¤H¼g­Ó mode ¬O§ï¦W edit §a
- //
- // TODO ¥Ñ©ó²{¦bÀɮ׳£¬Oª½±µ»\¦^­ìÀÉ¡A
- // ¦b­ì¬ÝªO¥Ø¿ý¶}¤w¨S¦³«Ü¤j·N¸q¡C (®Ä²vµy°ª¤@ÂI)
- // ¥i¥H¦Ò¼{§ï¶}¦b user home dir
- // ¦n³B¬O¬ÝªOªºÀɮ׼Ƥ£·|¨g¦¨ªø¡C (when someone crashed)
- // sethomedir(fpath, cuser.userid);
- // XXX ¦pªG§Aªº¨t²Î¦³©w´Á¬ÝªO²M©t¨àÀÉ¡A¨º´N¤£¥Î©ñ user home¡C
- setbpath(fpath, currboard);
-
- // XXX ¥H²{¦bªº¼Ò¦¡¡A³o¬O­Ó temp file
- stampfile(fpath, &postfile);
- setdirpath(genbuf, direct, fhdr->filename);
- local_article = fhdr->filemode & FILE_LOCAL;
-
- // copying takes long time, add some visual effect
- grayout(0, b_lines-2, GRAYOUT_DARK);
- move(b_lines-1, 0); clrtoeol();
- outs("¥¿¦b¸ü¤JÀÉ®×...");
- refresh();
-
- Copy(genbuf, fpath);
- strlcpy(save_title, fhdr->title, sizeof(save_title));
-
- // so far this is what we copied now...
- oldmt = dasht(genbuf);
- oldsz = dashs(fpath); // should be equal to genbuf(src).
- // use fpath (dest) in case some
- // modification was made.
- do {
-#ifdef EDITPOST_SMARTMERGE
-
- unsigned char oldsum[SMHASHLEN] = {0}, newsum[SMHASHLEN] = {0};
-
- // make checksum of file genbuf
- if (canDoSmartMerge &&
- hash_partial_file(fpath, oldsz, oldsum) != HASHPF_RET_OK)
- canDoSmartMerge = 0;
-
-#endif // EDITPOST_SMARTMERGE
-
-
- if (vedit2(fpath, 0, NULL, edflags) == -1)
- break;
-
- newmt = dasht(genbuf);
-
-#ifdef EDITPOST_SMARTMERGE
-
- // only merge if file is enlarged and modified
- if (newmt == oldmt || dashs(genbuf) < oldsz)
- canDoSmartMerge = 0;
-
- // make checksum of new file [by oldsz]
- if (canDoSmartMerge &&
- hash_partial_file(genbuf, oldsz, newsum) != HASHPF_RET_OK)
- canDoSmartMerge = 0;
-
- // verify checksum
- if (canDoSmartMerge &&
- memcmp(oldsum, newsum, sizeof(newsum)) != 0)
- canDoSmartMerge = 0;
-
- if (canDoSmartMerge)
- {
- canDoSmartMerge = 0; // only try merge once
-
- move(b_lines-7, 0);
- clrtobot();
- outs(ANSI_COLOR(1;33) "¡¶ Àɮפw³Q­×§ï¹L! ¡¶" ANSI_RESET "\n\n");
- outs("¶i¦æ¦Û°Ê¦X¨Ö [Smart Merge]...\n");
-
- // smart merge
- if (AppendTail(genbuf, fpath, oldsz) == 0)
- {
- // merge ok
- oldmt = newmt;
- outs(ANSI_COLOR(1)
- "¦X¨Ö¦¨¥\\¡A·s­×§ï(©Î±À¤å)¤w¥[¤J±zªº¤å³¹¤¤¡C\n"
- "±z¨S¦³»\\±¼¥ô¦ó±À¤å©Î­×§ï¡A½Ð¤Å¾á¤ß¡C"
- ANSI_RESET "\n");
-
-#ifdef WARN_EXP_SMARTMERGE
- outs(ANSI_COLOR(1;33)
- "¦Û°Ê¦X¨Ö (Smart Merge) ¬O¹êÅ礤ªº·s¥\\¯à¡A"
- "½ÐÀˬd¤@¤U±zªº¤å³¹¦X¨Ö«á¬O§_¥¿±`¡C" ANSI_RESET "\n"
- "­Y¦³°ÝÃD½Ð¦Ü " GLOBAL_BUGREPORT " ªO³ø§i¡AÁÂÁ¡C");
-#endif
- vmsg("¦X¨Ö§¹¦¨");
- } else {
- outs(ANSI_COLOR(31)
- "¦Û°Ê¦X¨Ö¥¢±Ñ¡C ½Ð§ï¥Î¤H¤u¤â°Ê½s¿è¦X¨Ö¡C" ANSI_RESET);
- vmsg("¦X¨Ö¥¢±Ñ");
- }
- }
-
-#endif // EDITPOST_SMARTMERGE
-
- if (oldmt != newmt)
- {
- int c = 0;
-
- move(b_lines-7, 0);
- clrtobot();
- outs(ANSI_COLOR(1;31) "¡¶ Àɮפw³Q­×§ï¹L! ¡¶" ANSI_RESET "\n\n");
-
- outs("¥i¯à¬O±z¦b½s¿èªº¹Lµ{¤¤¦³¤H¶i¦æ±À¤å©Î­×¤å¡C\n"
- "±z¥i¥H¿ï¾Üª½±µÂл\\ÀÉ®×(y)¡B©ñ±ó(n)¡A\n"
- " ©Î¬O" ANSI_COLOR(1)"­«·s½s¿è" ANSI_RESET
- "(·s¤å·|³Q¶K¨ì­è½sªºÀɮ׫᭱)(e)¡C\n");
- c = tolower(getans("­nª½±µÂл\\ÀÉ®×/¨ú®ø/­«½s¶Ü [Y/n/e]¡H"));
-
- if (c == 'n')
- break;
-
- if (c == 'e')
- {
- FILE *fp, *src;
-
- /* merge new and old stuff */
- fp = fopen(fpath, "at");
- src = fopen(genbuf, "rt");
-
- if(!fp)
- {
- vmsg("©êºp¡AÀɮפw·l·´¡C");
- if(src) fclose(src);
- unlink(fpath); // fpath is a temp file
- return FULLUPDATE;
- }
-
- if(src)
- {
- int c = 0;
- struct tm *ptime;
-
- fprintf(fp, MSG_SEPERATOR "\n");
- fprintf(fp, "¥H¤U¬°³Q­×§ï¹Lªº³Ì·s¤º®e: ");
- ptime = localtime4(&newmt);
- fprintf(fp,
- " (%02d/%02d %02d:%02d)\n",
- ptime->tm_mon + 1, ptime->tm_mday,
- ptime->tm_hour, ptime->tm_min);
- fprintf(fp, MSG_SEPERATOR "\n");
- while ((c = fgetc(src)) >= 0)
- fputc(c, fp);
- fclose(src);
-
- // update oldsz, old mt records
- oldmt = dasht(genbuf);
- oldsz = dashs(genbuf);
- }
- fclose(fp);
- continue;
- }
- }
-
- // OK to save file.
-
- // piaip Wed Jan 9 11:11:33 CST 2008
- // in order to prevent calling system 'mv' all the
- // time, it is better to unlink() first, which
- // increased the chance of succesfully using rename().
- // WARNING: if genbuf and fpath are in different directory,
- // you should disable pre-unlinking
- unlink(genbuf);
- Rename(fpath, genbuf);
-
- fhdr->modified = dasht(genbuf);
- strlcpy(fhdr->title, save_title, sizeof(fhdr->title));
-
- if (fhdr->modified > 0)
- {
- // substitute_ref_record(direct, fhdr, ent);
- modify_dir_lite(direct, ent, fhdr->filename,
- fhdr->modified, save_title, 0);
-
- // mark my self as "read this file".
- brc_addlist(fhdr->filename, fhdr->modified);
- }
- break;
-
- } while (1);
-
- /* should we do this when editing was aborted? */
- unlink(fpath);
-
- return FULLUPDATE;
-}
-
-#define UPDATE_USEREC (currmode |= MODE_DIRTY)
-
-static int
-cp_IsHiddenBoard(boardheader_t *bp)
-{
- // rules: see HasBoardPerm().
- if ((bp->brdattr & BRD_HIDE) && (bp->brdattr & BRD_POSTMASK))
- return 1;
- if (bp->level && !(bp->brdattr & BRD_POSTMASK))
- return 1;
- return 0;
-}
-
-static int
-cross_post(int ent, fileheader_t * fhdr, const char *direct)
-{
- char xboard[20], fname[80], xfpath[80], xtitle[80];
- char inputbuf[10], genbuf[200], genbuf2[4];
- fileheader_t xfile;
- FILE *xptr;
- int author, xbid, hashPost;
- boardheader_t *bp;
-
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- bp = getbcache(currbid);
-
- if (bp && (bp->brdattr & BRD_VOTEBOARD) )
- return FULLUPDATE;
-
-#ifdef USE_AUTOCPLOG
- // anti-crosspost spammers
- //
- // some spammers try to cross-post to other boards without
- // restriction (see pakkei0712* events on 2007/12)
- // for (1) increase numpost (2) flood target board
- // (3) flood original post
- // You must have post permission on current board
- //
- if( (bp->brdattr & BRD_CPLOG) &&
- (!CheckPostPerm() || !CheckPostRestriction(currbid)))
- {
- vmsg("¥Ñ¥»ªOÂà¿ý¤å³¹»Ý¦³µo¤åÅv­­(¥i«ö i ¬d¬Ý­­¨î)");
- return FULLUPDATE;
- }
-#endif // USE_AUTOCPLOG
-
- move(2, 0);
- clrtoeol();
- if (postrecord.times > 1)
- {
- outs(ANSI_COLOR(1;31)
- "½Ðª`·N: ­Y¹L¶q­«½ÆÂà¿ý±Nµø¬°¬~ªO¡A¾É­P³Q¶}»@³æ°±Åv¡C\n" ANSI_RESET
- "­Y¦³¯S§O»Ý¨D½Ð¬¢¦UªO¥D¡A½Ð¥L­ÌÀ°§AÂà¤å¡C\n\n");
- }
- move(1, 0);
-
- CompleteBoard("Âà¿ý¥»¤å³¹©ó¬ÝªO¡G", xboard);
- if (*xboard == '\0')
- return FULLUPDATE;
-
- if (!haspostperm(xboard))
- {
- vmsg("¬ÝªO¤£¦s¦b©Î¸Ó¬ÝªO¸T¤î±zµoªí¤å³¹¡I");
- return FULLUPDATE;
- }
-
- /* ¤£­n­É¥ÎÅܼơA°O¾ÐÅé¨S¨º»ò¯Ê¡A¤H¸£²V¶Ãªº¥N»ù¤ñ¸û°ª */
-
- // XXX cross-posting a series of articles should not be cross-post?
- // so let's use filename instead of title.
- // hashPost = StringHash(fhdr->title); // why use title?
- hashPost = StringHash(fhdr->filename); // let's try filename
- xbid = getbnum(xboard);
- assert(0<=xbid-1 && xbid-1<MAX_BOARD);
-
- // check target postperm
- if (!CheckPostRestriction(xbid))
- {
- vmsg("§A¤£°÷¸ê²`³á¡I (¥i¦b¥Øªº¬ÝªO¤º«ö i ¬d¬Ý­­¨î)");
- return FULLUPDATE;
- }
-
- if (xbid == currbid)
- {
- vmsg("¦PªO¤£»ÝÂà¿ý¡C");
- return FULLUPDATE;
- }
-
- // quick check: if already cross-posted, reject.
- if (hashPost == postrecord.checksum[0])
- {
- if (xbid == postrecord.last_bid)
- {
- vmsg("³o½g¤å³¹¤w¸gÂà¿ý¹L¤F¡C");
- return FULLUPDATE;
- }
- else if (postrecord.times >= MAX_CROSSNUM)
- {
- anticrosspost();
- return FULLUPDATE;
- }
- }
-
-#ifdef USE_COOLDOWN
- if(check_cooldown(getbcache(xbid)))
- {
- vmsg("¸Ó¬ÝªO²{¦bµLªkÂà¿ý¡C");
- return FULLUPDATE;
- }
-#endif
-
- ent = 1;
- author = 0;
- if (HasUserPerm(PERM_SYSOP) || !strcmp(fhdr->owner, cuser.userid)) {
- getdata(2, 0, "(1)­ì¤åÂà¸ü (2)ÂÂÂà¿ý®æ¦¡¡H[1] ",
- genbuf, 3, DOECHO);
- if (genbuf[0] != '2') {
- ent = 0;
- getdata(2, 0, "«O¯d­ì§@ªÌ¦WºÙ¶Ü?[Y] ", inputbuf, 3, DOECHO);
- if (inputbuf[0] != 'n' && inputbuf[0] != 'N')
- author = '1';
- }
- }
- if (ent)
- snprintf(xtitle, sizeof(xtitle), "[Âà¿ý]%.66s", fhdr->title);
- else
- strlcpy(xtitle, fhdr->title, sizeof(xtitle));
-
- snprintf(genbuf, sizeof(genbuf), "±Ä¥Î­ì¼ÐÃD¡m%.60s¡n¶Ü?[Y] ", xtitle);
- getdata(2, 0, genbuf, genbuf2, 4, LCECHO);
- if (genbuf2[0] == 'n' || genbuf2[0] == 'N') {
- if (getdata_str(2, 0, "¼ÐÃD¡G", genbuf, TTLEN, DOECHO, xtitle))
- strlcpy(xtitle, genbuf, sizeof(xtitle));
- }
-
- getdata(2, 0, "(S)¦sÀÉ (L)¯¸¤º (Q)¨ú®ø¡H[Q] ", genbuf, 3, LCECHO);
-
- if (genbuf[0] == 'l' || genbuf[0] == 's') {
- int currmode0 = currmode;
- const char *save_currboard;
-
- currmode = 0;
- setbpath(xfpath, xboard);
- stampfile(xfpath, &xfile);
- if (author)
- strlcpy(xfile.owner, fhdr->owner, sizeof(xfile.owner));
- else
- strlcpy(xfile.owner, cuser.userid, sizeof(xfile.owner));
- strlcpy(xfile.title, xtitle, sizeof(xfile.title));
- if (genbuf[0] == 'l') {
- xfile.filemode = FILE_LOCAL;
- }
- setbfile(fname, currboard, fhdr->filename);
- xptr = fopen(xfpath, "w");
-
- strlcpy(save_title, xfile.title, sizeof(save_title));
- save_currboard = currboard;
- currboard = xboard;
- write_header(xptr, save_title);
- currboard = save_currboard;
-
- if (cp_IsHiddenBoard(bp))
- {
- /* invisible board */
- fprintf(xptr, "¡° [¥»¤åÂà¿ý¦Û¬YÁô§Î¬ÝªO]\n\n");
- b_suckinfile_invis(xptr, fname, currboard);
- } else {
- /* public board */
- fprintf(xptr, "¡° [¥»¤åÂà¿ý¦Û %s ¬ÝªO]\n\n", currboard);
- b_suckinfile(xptr, fname);
- }
-
- addsignature(xptr, 0);
- fclose(xptr);
-
-#ifdef USE_AUTOCPLOG
- /* add cp log. bp is currboard now. */
- if(bp->brdattr & BRD_CPLOG)
- {
- char buf[MAXPATHLEN], tail[STRLEN];
- char bname[STRLEN] = "";
- struct tm *ptime = localtime4(&now);
- int maxlength = 51 +2 - 6;
- int bid = getbnum(xboard);
-
- assert(0<=bid-1 && bid-1<MAX_BOARD);
- bp = getbcache(bid);
- if (cp_IsHiddenBoard(bp))
- {
- strcpy(bname, "¬YÁô§Î¬ÝªO");
- } else {
- sprintf(bname, "¬ÝªO %s", xboard);
- }
-
- maxlength -= (strlen(cuser.userid) + strlen(bname));
-
-#ifdef GUESTRECOMMEND
- snprintf(tail, sizeof(tail),
- "%15s %02d/%02d",
- fromhost,
- ptime->tm_mon + 1, ptime->tm_mday);
-#else
- maxlength += (15 - 6);
- snprintf(tail, sizeof(tail),
- " %02d/%02d %02d:%02d",
- ptime->tm_mon + 1, ptime->tm_mday,
- ptime->tm_hour, ptime->tm_min);
-#endif
- snprintf(buf, sizeof(buf),
- // ANSI_COLOR(32) <- system will add green
- "¡° " ANSI_COLOR(1;32) "%s"
- ANSI_COLOR(0;32) ":Âà¿ý¦Ü"
- "%s" ANSI_RESET "%*s%s\n" ,
- cuser.userid, bname, maxlength, "",
- tail);
-
- do_add_recommend(direct, fhdr, ent, buf, 2);
- } else
-#endif
- {
- /* now point bp to new bord */
- xbid = getbnum(xboard);
- assert(0<=xbid-1 && xbid-1<MAX_BOARD);
- bp = getbcache(xbid);
- }
-
- /*
- * Cross fs¦³°ÝÃD else { unlink(xfpath); link(fname, xfpath); }
- */
- setbdir(fname, xboard);
- append_record(fname, &xfile, sizeof(xfile));
- if (!xfile.filemode && !(bp->brdattr & BRD_NOTRAN))
- outgo_post(&xfile, xboard, cuser.userid, cuser.nickname);
-#ifdef USE_COOLDOWN
- if(bp->nuser>30)
- {
- if (cooldowntimeof(usernum)<now)
- add_cooldowntime(usernum, 5);
- }
- add_posttimes(usernum, 1);
-#endif
- setbtotal(getbnum(xboard));
- outs("¤å³¹Âà¿ý§¹¦¨¡C(Âà¿ý¤£¼W¥[¤å³¹¼Æ¡A·q½Ð¥]²[) ");
-
- // update crosspost record
- if (hashPost == postrecord.checksum[0])
- // && xbid != postrecord.last_bid)
- {
- ++postrecord.times; // check will be done next time.
-
- if (postrecord.times == MAX_CROSSNUM)
- {
- outs(ANSI_COLOR(1;31) " ĵ§i: §Y±N¹F¨ìÂà¿ý¦¸¼Æ¤W­­¡A"
- "¤U¦¸±N¶}»@³æ!" ANSI_RESET);
- }
- } else {
- // reset cross-post record
- postrecord.times = 0;
- postrecord.last_bid = xbid;
- postrecord.checksum[0] = hashPost;
- }
-
- pressanykey();
- currmode = currmode0;
- }
-
- return FULLUPDATE;
-}
-
-static int
-read_post(int ent, fileheader_t * fhdr, const char *direct)
-{
- char genbuf[100];
- int more_result;
-
- if (fhdr->owner[0] == '-' || fhdr->filename[0] == 'L' || !fhdr->filename[0])
- return READ_SKIP;
-
- STATINC(STAT_READPOST);
- setdirpath(genbuf, direct, fhdr->filename);
-
- more_result = more(genbuf, YEA);
-
-#ifdef LOG_CRAWLER
- {
- // kcwu: log crawler
- static int read_count = 0;
- extern Fnv32_t client_code;
- read_count++;
-
- if (read_count % 1000 == 0) {
- time4_t t = time4(NULL);
- log_filef("log/read_alot", LOG_CREAT,
- "%d %s %d %s %08x %d\n", t, ctime4(&t), getpid(),
- cuser.userid, client_code, read_count);
- }
- }
-#endif // LOG_CRAWLER
-
- {
- int posttime=atoi(fhdr->filename+2);
- if(posttime>now-12*3600)
- STATINC(STAT_READPOST_12HR);
- else if(posttime>now-1*86400)
- STATINC(STAT_READPOST_1DAY);
- else if(posttime>now-3*86400)
- STATINC(STAT_READPOST_3DAY);
- else if(posttime>now-7*86400)
- STATINC(STAT_READPOST_7DAY);
- else
- STATINC(STAT_READPOST_OLD);
- }
- brc_addlist(fhdr->filename, fhdr->modified);
- strlcpy(currtitle, subject(fhdr->title), sizeof(currtitle));
-
- switch(more_result)
- {
- case -1:
- clear();
- vmsg("¦¹¤å³¹µL¤º®e");
- return FULLUPDATE;
- case RET_DOREPLY:
- case RET_DOREPLYALL:
- do_reply(fhdr);
- return FULLUPDATE;
- case RET_DORECOMMEND:
- recommend(ent, fhdr, direct);
- return FULLUPDATE;
- case RET_DOQUERYINFO:
- view_postinfo(ent, fhdr, direct, b_lines-3);
- return FULLUPDATE;
- }
- if(more_result)
- return more_result;
- return FULLUPDATE;
-}
-
-void
-editLimits(unsigned char *pregtime, unsigned char *plogins,
- unsigned char *pposts, unsigned char *pbadpost)
-{
- char genbuf[STRLEN];
- int temp;
-
- // load var
- unsigned char
- regtime = *pregtime,
- logins = *plogins,
- posts = *pposts,
- badpost = *pbadpost;
-
- // query UI
- sprintf(genbuf, "%u", regtime);
- do {
- getdata_buf(b_lines - 1, 0,
- "µù¥U®É¶¡­­¨î (¥H'¤ë'¬°³æ¦ì¡A0~255)¡G", genbuf, 4, LCECHO);
- temp = atoi(genbuf);
- } while (temp < 0 || temp > 255);
- regtime = (unsigned char)temp;
-
- sprintf(genbuf, "%u", logins*10);
- do {
- getdata_buf(b_lines - 1, 0,
- "¤W¯¸¦¸¼Æ¤U­­ (0~2550,¥H10¬°³æ¦ì,­Ó¦ì¼Æ¦r±N¦Û°Ê±Ë¥h)¡G", genbuf, 5, LCECHO);
- temp = atoi(genbuf);
- } while (temp < 0 || temp > 2550);
- logins = (unsigned char)(temp / 10);
-
- sprintf(genbuf, "%u", posts*10);
- do {
- getdata_buf(b_lines - 1, 0,
- "¤å³¹½g¼Æ¤U­­ (0~2550,¥H10¬°³æ¦ì,­Ó¦ì¼Æ¦r±N¦Û°Ê±Ë¥h)¡G", genbuf, 5, LCECHO);
- temp = atoi(genbuf);
- } while (temp < 0 || temp > 2550);
- posts = (unsigned char)(temp / 10);
-
- sprintf(genbuf, "%u", 255 - badpost);
- do {
- getdata_buf(b_lines - 1, 0,
- "¦H¤å½g¼Æ¤W­­ (0~255)¡G", genbuf, 5, LCECHO);
- temp = atoi(genbuf);
- } while (temp < 0 || temp > 255);
- badpost = (unsigned char)(255 - temp);
-
- // save var
- *pregtime = regtime;
- *plogins = logins;
- *pposts = posts;
- *pbadpost = badpost;
-}
-
-int
-do_limitedit(int ent, fileheader_t * fhdr, const char *direct)
-{
- char buf[STRLEN];
- boardheader_t *bp = getbcache(currbid);
-
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- if (!((currmode & MODE_BOARD) || HasUserPerm(PERM_SYSOP) ||
- (HasUserPerm(PERM_SYSSUPERSUBOP) && GROUPOP())))
- return DONOTHING;
-
- strcpy(buf, "§ó§ï ");
- if (HasUserPerm(PERM_SYSOP) || (HasUserPerm(PERM_SYSSUPERSUBOP) && GROUPOP()))
- strcat(buf, "(A)¥»ªOµoªí­­¨î ");
- strcat(buf, "(B)¥»ªO¹w³]");
- if (fhdr->filemode & FILE_VOTE)
- strcat(buf, " (C)¥»½g");
- strcat(buf, "³s¸p­­¨î (Q)¨ú®ø¡H[Q]");
- buf[0] = getans(buf);
-
- if ((HasUserPerm(PERM_SYSOP) || (HasUserPerm(PERM_SYSSUPERSUBOP) && GROUPOP())) && buf[0] == 'a') {
-
- editLimits(
- &bp->post_limit_regtime,
- &bp->post_limit_logins,
- &bp->post_limit_posts,
- &bp->post_limit_badpost);
-
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- substitute_record(fn_board, bp, sizeof(boardheader_t), currbid);
- log_usies("SetBoard", bp->brdname);
- vmsg("­×§ï§¹¦¨¡I");
- return FULLUPDATE;
- }
- else if (buf[0] == 'b') {
-
- editLimits(
- &bp->vote_limit_regtime,
- &bp->vote_limit_logins,
- &bp->vote_limit_posts,
- &bp->vote_limit_badpost);
-
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- substitute_record(fn_board, bp, sizeof(boardheader_t), currbid);
- log_usies("SetBoard", bp->brdname);
- vmsg("­×§ï§¹¦¨¡I");
- return FULLUPDATE;
- }
- else if ((fhdr->filemode & FILE_VOTE) && buf[0] == 'c') {
-
- editLimits(
- &fhdr->multi.vote_limits.regtime,
- &fhdr->multi.vote_limits.logins,
- &fhdr->multi.vote_limits.posts,
- &fhdr->multi.vote_limits.badpost);
-
- substitute_ref_record(direct, fhdr, ent);
- vmsg("­×§ï§¹¦¨¡I");
- return FULLUPDATE;
- }
- vmsg("¨ú®ø­×§ï");
- return FULLUPDATE;
-}
-
-/* ----------------------------------------------------- */
-/* ±Ä¶°ºëµØ°Ï */
-/* ----------------------------------------------------- */
-static int
-b_man(void)
-{
- char buf[PATHLEN];
-
- setapath(buf, currboard);
- if ((currmode & MODE_BOARD) || HasUserPerm(PERM_SYSOP)) {
- char genbuf[128];
- int fd;
- snprintf(genbuf, sizeof(genbuf), "%s/.rebuild", buf);
- if ((fd = open(genbuf, O_CREAT, 0640)) > 0)
- close(fd);
- }
- return a_menu(currboard, buf, HasUserPerm(PERM_ALLBOARD) ? 2 :
- (currmode & MODE_BOARD ? 1 : 0),
- currbid, // getbnum(currboard)?
- NULL);
-}
-
-#ifndef NO_GAMBLE
-static int
-stop_gamble(void)
-{
- boardheader_t *bp = getbcache(currbid);
- char fn_ticket[128], fn_ticket_end[128];
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- if (!bp->endgamble || bp->endgamble > now)
- return 0;
-
- setbfile(fn_ticket, currboard, FN_TICKET);
- setbfile(fn_ticket_end, currboard, FN_TICKET_END);
-
- rename(fn_ticket, fn_ticket_end);
- if (bp->endgamble) {
- bp->endgamble = 0;
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- substitute_record(fn_board, bp, sizeof(boardheader_t), currbid);
- }
- return 1;
-}
-static int
-join_gamble(int ent, const fileheader_t * fhdr, const char *direct)
-{
- if (!HasUserPerm(PERM_LOGINOK))
- return DONOTHING;
- if (stop_gamble()) {
- vmsg("¥Ø«e¥¼Á|¿ì½ä½L©Î½ä½L¤w¶}¼ú");
- return DONOTHING;
- }
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- ticket(currbid);
- return FULLUPDATE;
-}
-static int
-hold_gamble(void)
-{
- char fn_ticket[128], fn_ticket_end[128], genbuf[128], msg[256] = "",
- yn[10] = "";
- char tmp[128];
- boardheader_t *bp = getbcache(currbid);
- int i;
- FILE *fp = NULL;
-
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- if (!(currmode & MODE_BOARD))
- return 0;
- if (bp->brdattr & BRD_BAD )
- {
- vmsg("¹Hªk¬ÝªO¸T¤î¨Ï¥Î½ä½L");
- return 0;
- }
-
- setbfile(fn_ticket, currboard, FN_TICKET);
- setbfile(fn_ticket_end, currboard, FN_TICKET_END);
- setbfile(genbuf, currboard, FN_TICKET_LOCK);
-
- if (dashf(fn_ticket)) {
- getdata(b_lines - 1, 0, "¤w¸g¦³Á|¿ì½ä½L, "
- "¬O§_­n [°±¤î¤Uª`]?(N/y)¡G", yn, 3, LCECHO);
- if (yn[0] != 'y')
- return FULLUPDATE;
- rename(fn_ticket, fn_ticket_end);
- if (bp->endgamble) {
- bp->endgamble = 0;
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- substitute_record(fn_board, bp, sizeof(boardheader_t), currbid);
-
- }
- return FULLUPDATE;
- }
- if (dashf(fn_ticket_end)) {
- getdata(b_lines - 1, 0, "¤w¸g¦³Á|¿ì½ä½L, "
- "¬O§_­n¶}¼ú [§_/¬O]?(N/y)¡G", yn, 3, LCECHO);
- if (yn[0] != 'y')
- return FULLUPDATE;
- if(cpuload(NULL) > MAX_CPULOAD/4)
- {
- vmsg("­t²ü¹L°ª ½Ð©ó¨t²Î­t²ü§C®É¶}¼ú..");
- return FULLUPDATE;
- }
- openticket(currbid);
- return FULLUPDATE;
- } else if (dashf(genbuf)) {
- vmsg(" ¥Ø«e¨t²Î¥¿¦b³B²z¶}¼ú¨Æ©y, ½Ðµ²ªG¥XÄl«á¦AÁ|¿ì.......");
- return FULLUPDATE;
- }
- getdata(b_lines - 2, 0, "­nÁ|¿ì½ä½L (N/y):", yn, 3, LCECHO);
- if (yn[0] != 'y')
- return FULLUPDATE;
- getdata(b_lines - 1, 0, "½ä¤°»ò? ½Ð¿é¤J¥DÃD (¿é¤J«á½s¿è¤º®e):",
- msg, 20, DOECHO);
- if (msg[0] == 0 ||
- vedit(fn_ticket_end, NA, NULL) < 0)
- return FULLUPDATE;
-
- clear();
- showtitle("Á|¿ì½ä½L", BBSNAME);
- setbfile(tmp, currboard, FN_TICKET_ITEMS ".tmp");
-
- //sprintf(genbuf, "%s/" FN_TICKET_ITEMS, direct);
-
- if (!(fp = fopen(tmp, "w")))
- return FULLUPDATE;
- do {
- getdata(2, 0, "¿é¤J±m²¼»ù®æ (»ù®æ:10-10000):", yn, 6, LCECHO);
- i = atoi(yn);
- } while (i < 10 || i > 10000);
- fprintf(fp, "%d\n", i);
- if (!getdata(3, 0, "³]©w¦Û°Ê«Ê½L®É¶¡?(Y/n)", yn, 3, LCECHO) || yn[0] != 'n') {
- bp->endgamble = gettime(4, now, "«Ê½L©ó");
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- substitute_record(fn_board, bp, sizeof(boardheader_t), currbid);
- }
- move(6, 0);
- snprintf(genbuf, sizeof(genbuf),
- "\n½Ð¨ì %s ªO «ö'f'°Ñ»P½ä³Õ!\n\n"
- "¤@±i %d " MONEYNAME "¹ô, ³o¬O%sªº½ä³Õ\n%s%s\n",
- currboard,
- i, i < 100 ? "¤p½ä¦¡" : i < 500 ? "¥­¥Á¯Å" :
- i < 1000 ? "¶Q±Ú¯Å" : i < 5000 ? "´I»¨¯Å" : "¶É®a¿º²£",
- bp->endgamble ? "½ä½Lµ²§ô®É¶¡: " : "",
- bp->endgamble ? Cdate(&bp->endgamble) : ""
- );
- strcat(msg, genbuf);
- outs("½Ð¨Ì¦¸¿é¤J±m²¼¦WºÙ, »Ý´£¨Ñ2~8¶µ. (¥¼º¡¤K¶µ, ¿é¤Jª½±µ«öEnter)\n");
- //outs(ANSI_COLOR(1;33) "ª`·N¿é¤J«áµLªk­×§ï¡I\n");
- for( i = 0 ; i < 8 ; ++i ){
- snprintf(yn, sizeof(yn), " %d)", i + 1);
- getdata(7 + i, 0, yn, genbuf, 9, DOECHO);
- if (!genbuf[0] && i > 1)
- break;
- fprintf(fp, "%s\n", genbuf);
- }
- fclose(fp);
-
- setbfile(genbuf, currboard, FN_TICKET_RECORD);
- unlink(genbuf); // Ptt: ¨¾°ô§Q¥Î¤£¦Pid¦P®ÉÁ|¿ì½ä³õ
- setbfile(genbuf, currboard, FN_TICKET_USER);
- unlink(genbuf); // Ptt: ¨¾°ô§Q¥Î¤£¦Pid¦P®ÉÁ|¿ì½ä³õ
-
- setbfile(genbuf, currboard, FN_TICKET_ITEMS);
- setbfile(tmp, currboard, FN_TICKET_ITEMS ".tmp");
- if(!dashf(fn_ticket))
- Rename(tmp, genbuf);
-
- snprintf(genbuf, sizeof(genbuf), "[¤½§i] %s ªO ¶}©l½ä³Õ!", currboard);
- post_msg(currboard, genbuf, msg, cuser.userid);
- post_msg("Record", genbuf + 7, msg, "[°¨¸ô±´¤l]");
- /* Tim ±±¨îCS, ¥H§K¥¿¦bª±ªºuser§â¸ê®Æ¤w¸g¼g¶i¨Ó */
- rename(fn_ticket_end, fn_ticket);
- /* ³]©w§¹¤~§âÀɦW§ï¹L¨Ó */
-
- vmsg("½ä½L³]©w§¹¦¨");
- return FULLUPDATE;
-}
-#endif
-
-static int
-cite_post(int ent, const fileheader_t * fhdr, const char *direct)
-{
- char fpath[PATHLEN];
- char title[TTLEN + 1];
-
- setbfile(fpath, currboard, fhdr->filename);
- strlcpy(title, "¡º ", sizeof(title));
- strlcpy(title + 3, fhdr->title, TTLEN - 3);
- title[TTLEN] = '\0';
- a_copyitem(fpath, title, 0, 1);
- b_man();
- return FULLUPDATE;
-}
-
-int
-edit_title(int ent, fileheader_t * fhdr, const char *direct)
-{
- char genbuf[200] = "";
- fileheader_t tmpfhdr = *fhdr;
- int dirty = 0;
- int allow = 0;
-
- // should we allow edit-title here?
- if (currstat == RMAIL)
- allow = 0;
- else if (HasUserPerm(PERM_SYSOP))
- allow = 2;
- else if (currmode & MODE_BOARD ||
- strcmp(cuser.userid, fhdr->owner) == 0)
- allow = 1;
-
- if (!allow)
- return DONOTHING;
-
- if (fhdr && fhdr->title[0])
- strlcpy(genbuf, fhdr->title, TTLEN+1);
-
- if (getdata_buf(b_lines - 1, 0, "¼ÐÃD¡G", genbuf, TTLEN, DOECHO)) {
- strlcpy(tmpfhdr.title, genbuf, sizeof(tmpfhdr.title));
- dirty++;
- }
-
- if (allow >= 2)
- {
- if (getdata(b_lines - 1, 0, "§@ªÌ¡G", genbuf, IDLEN + 2, DOECHO)) {
- strlcpy(tmpfhdr.owner, genbuf, sizeof(tmpfhdr.owner));
- dirty++;
- }
- if (getdata(b_lines - 1, 0, "¤é´Á¡G", genbuf, 6, DOECHO)) {
- snprintf(tmpfhdr.date, sizeof(tmpfhdr.date), "%.5s", genbuf);
- dirty++;
- }
- }
-
- if (dirty)
- {
- getdata(b_lines - 1, 0, "½T©w(Y/N)?[n] ", genbuf, 3, DOECHO);
- if ((genbuf[0] == 'y' || genbuf[0] == 'Y') && dirty) {
- // TODO verify if record is still valid
- fileheader_t curr;
- memset(&curr, 0, sizeof(curr));
- if (get_record(direct, &curr, sizeof(curr), ent) < 0 ||
- strcmp(curr.filename, fhdr->filename) != 0)
- {
- // modified...
- vmsg("©êºp¡A¨t²Î¦£¸L¤¤¡A½Ðµy«á¦A¸Õ¡C");
- return FULLUPDATE;
- }
- *fhdr = tmpfhdr;
- substitute_ref_record(direct, fhdr, ent);
- }
- return FULLUPDATE;
- }
- return DONOTHING;
-}
-
-static int
-solve_post(int ent, fileheader_t * fhdr, const char *direct)
-{
- if ((currmode & MODE_BOARD)) {
- fhdr->filemode ^= FILE_SOLVED;
- substitute_ref_record(direct, fhdr, ent);
- check_locked(fhdr);
- return PART_REDRAW;
- }
- return DONOTHING;
-}
-
-
-static int
-recommend_cancel(int ent, fileheader_t * fhdr, const char *direct)
-{
- char yn[5];
- if (!(currmode & MODE_BOARD))
- return DONOTHING;
- getdata(b_lines - 1, 0, "½T©w­n±ÀÂËÂk¹s[y/N]? ", yn, 5, LCECHO);
- if (yn[0] != 'y')
- return FULLUPDATE;
-#ifdef ASSESS
- // to save resource
- if (fhdr->recommend > 9)
- {
- inc_goodpost(fhdr->owner, -1 * (fhdr->recommend / 10));
- sendalert(fhdr->owner, ALERT_PWD_GOODPOST);
- }
-#endif
- fhdr->recommend = 0;
-
- substitute_ref_record(direct, fhdr, ent);
- return FULLUPDATE;
-}
-
-static int
-do_add_recommend(const char *direct, fileheader_t *fhdr,
- int ent, const char *buf, int type)
-{
- char path[PATHLEN];
- int update = 0;
- /*
- race here:
- ¬°¤F´î¤Ö system calls , ²{¦bª½±µ¥Î·í«eªº±À¤å¼Æ +1 ¼g¤J .DIR ¤¤.
- ³y¦¨
- 1.­Y¸Ó¤åÀɦW³Q´«±¼ªº¸Ü, ±À¤å±N¼g¦ÜÂÂÀɦW¤¤ (³y¦¨«ÕÆFÀÉ)
- 2.¨S¦³­«·sŪ¤@¦¸, ©Ò¥H±À¤å¼Æ¥i¯à³Q¤Öºâ
- 3.­Y±Àªº®É­Ô«e¤å³Q§R, ±N¥[¨ì«á¤åªº±À¤å¼Æ
-
- */
- setdirpath(path, direct, fhdr->filename);
- if( log_file(path, 0, buf) == -1 ){ // ¤£ CREATE
- vmsg("±ÀÂË/Äv¼Ð¥¢±Ñ");
- return -1;
- }
-
- // XXX do lock some day!
-
- /* This is a solution to avoid most racing (still some), but cost four
- * system calls. */
-
- if(type == 0 && fhdr->recommend < MAX_RECOMMENDS )
- update = 1;
- else if(type == 1 && fhdr->recommend > -MAX_RECOMMENDS)
- update = -1;
- fhdr->recommend += update;
-
- // since we want to do 'modification'...
- fhdr->modified = dasht(path);
-
- if (fhdr->modified > 0)
- {
- if (modify_dir_lite(direct, ent, fhdr->filename,
- fhdr->modified, NULL, update) < 0)
- return -1;
- // mark my self as "read this file".
- brc_addlist(fhdr->filename, fhdr->modified);
- }
-
- return 0;
-}
-
-static int
-do_bid(int ent, fileheader_t * fhdr, const boardheader_t *bp,
- const char *direct, const struct tm *ptime)
-{
- char genbuf[200], fpath[PATHLEN],say[30],*money;
- bid_t bidinfo;
- int mymax, next;
-
- setdirpath(fpath, direct, fhdr->filename);
- strcat(fpath, ".bid");
- memset(&bidinfo, 0, sizeof(bidinfo));
- if (get_record(fpath, &bidinfo, sizeof(bidinfo), 1) < 0)
- {
- vmsg("¨t²Î¿ù»~: Äv¼Ð¸ê°T¤w¿ò¥¢¡A½Ð­«¶}·s¼Ð¡C");
- return FULLUPDATE;
- }
-
- move(18,0);
- clrtobot();
- prints("Äv¼Ð¥DÃD: %s\n", fhdr->title);
- print_bidinfo(0, bidinfo);
- money = bidinfo.payby ? " NT$ " : MONEYNAME "$ ";
- if( now > bidinfo.enddate || bidinfo.high == bidinfo.buyitnow ){
- outs("¦¹Äv¼Ð¤w¸gµ²§ô,");
- if( bidinfo.userid[0] ) {
- /*if(!payby && bidinfo.usermax!=-1)
- {¥HPtt¹ô¦Û°Ê¦©´Ú
- }*/
- prints("®¥³ß %s ¥H %d ±o¼Ð!", bidinfo.userid, bidinfo.high);
-#ifdef ASSESS
- if (!(bidinfo.flag & SALE_COMMENTED) && strcmp(bidinfo.userid, currutmp->userid) == 0){
- char tmp = getans("±z¹ï©ó³o¦¸¥æ©öªºµû»ù¦p¦ó? 1:¨Î 2:¤í¨Î 3:´¶³q[Q]");
- if ('1' <= tmp && tmp <= '3'){
- switch(tmp){
- case 1:
- inc_goodsale(bidinfo.userid, 1);
- break;
- case 2:
- inc_badsale(bidinfo.userid, 1);
- break;
- }
- bidinfo.flag |= SALE_COMMENTED;
-
- substitute_record(fpath, &bidinfo, sizeof(bidinfo), 1);
- }
- }
-#endif
- }
- else outs("µL¤H±o¼Ð!");
- pressanykey();
- return FULLUPDATE;
- }
-
- if( bidinfo.userid[0] ){
- prints("¤U¦¸¥X»ù¦Ü¤Ö­n:%s%d", money,bidinfo.high + bidinfo.increment);
- if( bidinfo.buyitnow )
- prints(" (¿é¤J %d µ¥©ó¥Hª½±µÁʶRµ²§ô)",bidinfo.buyitnow);
- next = bidinfo.high + bidinfo.increment;
- }
- else{
- prints("°_¼Ð»ù: %d", bidinfo.high);
- next=bidinfo.high;
- }
- if( !strcmp(cuser.userid,bidinfo.userid) ){
- outs("§A¬O³Ì°ª±o¼ÐªÌ!");
- pressanykey();
- return FULLUPDATE;
- }
- if( strcmp(cuser.userid, fhdr->owner) == 0 ){
- vmsg("ĵ§i! ¥»¤H¤£¯à¥X»ù!");
- getdata_str(23, 0, "¬O§_­n´£¦­µ²¼Ð? (y/N)", genbuf, 3, LCECHO,"n");
- if( genbuf[0] != 'y' )
- return FULLUPDATE;
- snprintf(genbuf, sizeof(genbuf),
- ANSI_COLOR(1;31) "¡÷ "
- ANSI_COLOR(33) "½æ¤è%s´£¦­µ²¼Ð"
- ANSI_RESET "%*s"
- "¼Ð%15s %02d/%02d\n",
- cuser.userid, (int)(45 - strlen(cuser.userid) - strlen(money)),
- " ", fromhost, ptime->tm_mon + 1, ptime->tm_mday);
- do_add_recommend(direct, fhdr, ent, genbuf, 0);
- bidinfo.enddate = now;
- substitute_record(fpath, &bidinfo, sizeof(bidinfo), 1);
- vmsg("´£¦­µ²¼Ð§¹¦¨");
- return FULLUPDATE;
- }
- getdata_str(23, 0, "¬O§_­n¤U¼Ð? (y/N)", genbuf, 3, LCECHO,"n");
- if( genbuf[0] != 'y' )
- return FULLUPDATE;
-
- getdata(23, 0, "±zªº³Ì°ª¤U¼Ðª÷ÃB(0:¨ú®ø):", genbuf, 10, LCECHO);
- mymax = atoi(genbuf);
- if( mymax <= 0 ){
- vmsg("¨ú®ø¤U¼Ð");
- return FULLUPDATE;
- }
-
- getdata(23,0,"¤U¼Ð·P¨¥:",say,12,DOECHO);
- get_record(fpath, &bidinfo, sizeof(bidinfo), 1);
-
- if( bidinfo.buyitnow && mymax > bidinfo.buyitnow )
- mymax = bidinfo.buyitnow;
- else if( !bidinfo.userid[0] )
- next = bidinfo.high;
- else
- next = bidinfo.high + bidinfo.increment;
-
- if( mymax< next || (bidinfo.payby == 0 && cuser.money < mymax) ){
- vmsg("¼Ðª÷¤£¨¬·m¼Ð");
- return FULLUPDATE;
- }
-
- snprintf(genbuf, sizeof(genbuf),
- ANSI_COLOR(1;31) "¡÷ " ANSI_COLOR(33) "%s" ANSI_RESET ANSI_COLOR(33) ":%s" ANSI_RESET "%*s"
- "%s%-15d¼Ð%15s %02d/%02d\n",
- cuser.userid, say,
- (int)(31 - strlen(cuser.userid) - strlen(say)), " ",
- money,
- next, fromhost,
- ptime->tm_mon + 1, ptime->tm_mday);
- do_add_recommend(direct, fhdr, ent, genbuf, 0);
- if( next > bidinfo.usermax ){
- bidinfo.usermax = mymax;
- bidinfo.high = next;
- strcpy(bidinfo.userid, cuser.userid);
- }
- else if( mymax > bidinfo.usermax ) {
- bidinfo.high = bidinfo.usermax + bidinfo.increment;
- if( bidinfo.high > mymax )
- bidinfo.high = mymax;
- bidinfo.usermax = mymax;
- strcpy(bidinfo.userid, cuser.userid);
-
- snprintf(genbuf, sizeof(genbuf),
- ANSI_COLOR(1;31) "¡÷ " ANSI_COLOR(33) "¦Û°ÊÄv¼Ð%s³Ó¥X" ANSI_RESET
- ANSI_COLOR(33) ANSI_RESET "%*s%s%-15d¼Ð %02d/%02d\n",
- cuser.userid,
- (int)(20 - strlen(cuser.userid)), " ", money,
- bidinfo.high,
- ptime->tm_mon + 1, ptime->tm_mday);
- do_add_recommend(direct, fhdr, ent, genbuf, 0);
- }
- else {
- if( mymax + bidinfo.increment < bidinfo.usermax )
- bidinfo.high = mymax + bidinfo.increment;
- else
- bidinfo.high=bidinfo.usermax; /*³oÃä©Ç©Çªº*/
- snprintf(genbuf, sizeof(genbuf),
- ANSI_COLOR(1;31) "¡÷ " ANSI_COLOR(33) "¦Û°ÊÄv¼Ð%s³Ó¥X"
- ANSI_RESET ANSI_COLOR(33) ANSI_RESET "%*s%s%-15d¼Ð %02d/%02d\n",
- bidinfo.userid,
- (int)(20 - strlen(bidinfo.userid)), " ", money,
- bidinfo.high,
- ptime->tm_mon + 1, ptime->tm_mday);
- do_add_recommend(direct, fhdr, ent, genbuf, 0);
- }
- substitute_record(fpath, &bidinfo, sizeof(bidinfo), 1);
- vmsg("®¥³ß±z! ¥H³Ì°ª»ù·m¼Ð§¹¦¨!");
- return FULLUPDATE;
-}
-
-static int
-recommend(int ent, fileheader_t * fhdr, const char *direct)
-{
- struct tm *ptime = localtime4(&now);
- char buf[PATHLEN], msg[STRLEN];
-#ifndef OLDRECOMMEND
- static const char *ctype[3] = {
- "±À", "¼N", "¡÷"
- };
- static const char *ctype_attr[3] = {
- ANSI_COLOR(1;33),
- ANSI_COLOR(1;31),
- ANSI_COLOR(1;37),
- }, *ctype_attr2[3] = {
- ANSI_COLOR(1;37),
- ANSI_COLOR(1;31),
- ANSI_COLOR(1;31),
- }, *ctype_long[3] = {
- "­È±o±ÀÂË",
- "µ¹¥¦¼NÁn",
- "¥u¥[¡÷µù¸Ñ"
- };
-#endif
- int type, maxlength;
- boardheader_t *bp;
- static time4_t lastrecommend = 0;
- static int lastrecommend_bid = -1;
- static char lastrecommend_fname[FNLEN] = "";
- int isGuest = (strcmp(cuser.userid, STR_GUEST) == EQUSTR);
- int logIP = 0;
- int ymsg = b_lines -1;
-#ifdef ASSESS
- char oldrecom = fhdr->recommend;
-#endif // ASSESS
-
- if (!fhdr || !fhdr->filename[0])
- return DONOTHING;
-
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- bp = getbcache(currbid);
- if (bp->brdattr & BRD_NORECOMMEND || fhdr->filename[0] == 'L' ||
- ((fhdr->filemode & FILE_MARKED) && (fhdr->filemode & FILE_SOLVED))) {
- vmsg("©êºp, ¸T¤î±ÀÂË©ÎÄv¼Ð");
- return FULLUPDATE;
- }
-
- if ( !CheckPostPerm() ||
- bp->brdattr & BRD_VOTEBOARD ||
-#ifndef GUESTRECOMMEND
- isGuest ||
-#endif
- fhdr->filemode & FILE_VOTE) {
- vmsg("±zÅv­­¤£¨¬, µLªk±ÀÂË!"); // "(¥i«ö¤j¼g I ¬d¬Ý­­¨î)"
- return FULLUPDATE;
- }
-
-#ifdef SAFE_ARTICLE_DELETE
- if (fhdr->filename[0] == '.') {
- vmsg("¥»¤å¤w§R°£");
- return FULLUPDATE;
- }
-#endif
-
- if( fhdr->filemode & FILE_BID){
- return do_bid(ent, fhdr, bp, direct, ptime);
- }
-
-#ifndef DEBUG
- if (!CheckPostRestriction(currbid))
- {
- vmsg("§A¤£°÷¸ê²`³á¡I (¥i«ö i ¬d¬Ý­­¨î)");
- return FULLUPDATE;
- }
-#endif
-
- if((currmode & MODE_BOARD) || HasUserPerm(PERM_SYSOP))
- {
- /* I'm BM or SYSOP. */
- }
- else if (bp->brdattr & BRD_NOFASTRECMD)
- {
- int d = (int)bp->fastrecommend_pause - (now - lastrecommend);
- if (d > 0)
- {
- vmsgf("¥»ªO¸T¤î§Ö³t³sÄò±À¤å¡A½Ð¦Aµ¥ %d ¬í", d);
- return FULLUPDATE;
- }
- }
- {
- // kcwu
- static unsigned char lastrecommend_minute = 0;
- static unsigned short recommend_in_minute = 0;
- unsigned char now_in_minute = (unsigned char)(now / 60);
- if(now_in_minute != lastrecommend_minute) {
- recommend_in_minute = 0;
- lastrecommend_minute = now_in_minute;
- }
- recommend_in_minute++;
- if(recommend_in_minute>60) {
- vmsg("¨t²Î¸T¤îµu®É¶¡¤º¤j¶q±À¤å");
- return FULLUPDATE;
- }
- }
- {
- // kcwu
- char path[PATHLEN];
- off_t size;
- setdirpath(path, direct, fhdr->filename);
- size = dashs(path);
- if (size > 5*1024*1024) {
- vmsg("ÀɮפӤj, µLªkÄ~Äò±À¤å, ½Ð¥t¼¶¤åµoªí");
- return FULLUPDATE;
- }
-
- if (size > 100*1024) {
- int d = 10 - (now - lastrecommend);
- if (d > 0) {
- vmsgf("¥»¤å¤w¹Lªø, ¸T¤î§Ö³t³sÄò±À¤å, ½Ð¦Aµ¥ %d ¬í", d);
- return FULLUPDATE;
- }
- }
- }
-
-
-#ifdef USE_COOLDOWN
- if(check_cooldown(bp))
- return FULLUPDATE;
-#endif
-
- type = 0;
-
- // why "recommend == 0" here?
- // some users are complaining that they like to fxck up system
- // with lots of recommend one-line text.
- // since we don't support recognizing update of recommends now,
- // they tend to use the counter to identify whether an arcitle
- // has new recommends or not.
- // so, make them happy here.
-#ifndef OLDRECOMMEND
- // no matter it is first time or not.
- if (strcmp(cuser.userid, fhdr->owner) == 0)
-#else
- // old format is one way counter, so let's relax.
- if (fhdr->recommend == 0 && strcmp(cuser.userid, fhdr->owner) == 0)
-#endif
- {
- // owner recommend
- type = 2;
- move(ymsg--, 0); clrtoeol();
-#ifndef OLDRECOMMEND
- outs("§@ªÌ¥»¤H, ¨Ï¥Î ¡÷ ¥[µù¤è¦¡\n");
-#else
- outs("§@ªÌ¥»¤H­º±À, ¨Ï¥Î ¡÷ ¥[µù¤è¦¡\n");
-#endif
-
- }
-#ifndef DEBUG
- else if (!(currmode & MODE_BOARD) &&
- (now - lastrecommend) < (
-#if 0
- /* i'm not sure whether this is better or not */
- (bp->brdattr & BRD_NOFASTRECMD) ?
- bp->fastrecommend_pause :
-#endif
- 90))
- {
- // too close
- type = 2;
- move(ymsg--, 0); clrtoeol();
- outs("®É¶¡¤Óªñ, ¨Ï¥Î ¡÷ ¥[µù¤è¦¡\n");
- }
-#endif
-
-#ifndef OLDRECOMMEND
- else if (!(bp->brdattr & BRD_NOBOO))
- {
- /* most people use recommendation just for one-line reply.
- * so we change default to (2)= comment only now.
-#define RECOMMEND_DEFAULT_VALUE (2)
- */
-#define RECOMMEND_DEFAULT_VALUE (0) /* current user behavior */
-
- move(b_lines, 0); clrtoeol();
- outs(ANSI_COLOR(1) "±zı±o³o½g¤å³¹ ");
- prints("%s1.%s %s2.%s %s3.%s " ANSI_RESET "[%d]? ",
- ctype_attr[0], ctype_long[0],
- ctype_attr[1], ctype_long[1],
- ctype_attr[2], ctype_long[2],
- RECOMMEND_DEFAULT_VALUE+1);
-
- // poor BBS term has problem positioning with ANSI.
- move(b_lines, 55);
- type = igetch() - '1';
- if(type < 0 || type > 2)
- type = RECOMMEND_DEFAULT_VALUE;
- move(b_lines, 0); clrtoeol();
- }
-#endif
-
- // warn if article is outside post
- if (strchr(fhdr->owner, '.') != NULL)
- {
- move(ymsg--, 0); clrtoeol();
- outs(ANSI_COLOR(1;31)
- "¡»³o½g¤å³¹¨Ó¦Û¼Ê¦WªO©Î¥~¯¸Âà«HªO¡A­ì§@ªÌ¥i¯àµLªk¬Ý¨ì±À¤å¡C"
- ANSI_RESET "\n");
- }
-
- // warn if in non-standard mode
- {
- char *p = strrchr(direct, '/');
- // allow .DIR or .DIR.bottom
- if (!p || strncmp(p+1, FN_DIR, strlen(FN_DIR)) != 0)
- {
- ymsg --;
- move(ymsg--, 0); clrtoeol();
- outs(ANSI_COLOR(1;33)
- "¡»±z¥¿¦b·j´M(¼ÐÃD¡B§@ªÌ...)©Î¨ä¥¦¯S®í¦Cªí¼Ò¦¡¡A"
- "±À¤å­p¼Æ»P­×§ï°O¿ý±N·|¤À¶}­pºâ¡C"
- ANSI_RESET "\n"
- " ­Y·Q¥¿±`­p¼Æ½Ð¥ý¥ªÁä°h¦^¥¿±`¦Cªí¼Ò¦¡¡C\n");
- }
- }
-
- if(type > 2 || type < 0)
- type = 0;
-
- maxlength = 78 -
- 3 /* lead */ -
- 6 /* date */ -
- 1 /* space */ -
- 6 /* time */;
-
- if (bp->brdattr & BRD_IPLOGRECMD || isGuest)
- {
- maxlength -= 15 /* IP */;
- logIP = 1;
- }
-
-#ifdef OLDRECOMMEND
- maxlength -= 2; /* '±À' */
- maxlength -= strlen(cuser.userid);
- sprintf(buf, "%s %s:", "¡÷" , cuser.userid);
-
-#else // !OLDRECOMMEND
- maxlength -= strlen(cuser.userid);
- sprintf(buf, "%s%s%s %s:",
- ctype_attr[type], ctype[type], ANSI_RESET,
- cuser.userid);
-#endif // !OLDRECOMMEND
-
- move(b_lines, 0);
- clrtoeol();
-
- if (!getdata(b_lines, 0, buf, msg, maxlength, DOECHO))
- return FULLUPDATE;
-
- // make sure to do modification
- {
- char ans[3];
- sprintf(buf+strlen(buf), ANSI_COLOR(7) "%-*s"
- ANSI_RESET " ½T©w[y/N]:", maxlength, msg);
- if(!getdata(b_lines, 0, buf, ans, sizeof(ans), LCECHO) ||
- ans[0] != 'y')
- return FULLUPDATE;
- }
-
- // log if you want
-#ifdef LOG_PUSH
- {
- static int tolog = 0;
- if( tolog == 0 )
- tolog =
- (cuser.numlogins < 50 || (now - cuser.firstlogin) < 86400 * 7)
- ? 1 : 2;
- if( tolog == 1 ){
- FILE *fp;
- if( (fp = fopen("log/push", "a")) != NULL ){
- fprintf(fp, "%s %d %s %s %s\n", cuser.userid, now, currboard, fhdr->filename, msg);
- fclose(fp);
- }
- sleep(1);
- }
- }
-#endif // LOG_PUSH
-
- STATINC(STAT_RECOMMEND);
-
- {
- /* build tail first. */
- char tail[STRLEN];
-
- if(logIP)
- {
- snprintf(tail, sizeof(tail),
- "%15s %02d/%02d %02d:%02d",
- fromhost,
- ptime->tm_mon+1, ptime->tm_mday,
- ptime->tm_hour, ptime->tm_min);
- } else {
- snprintf(tail, sizeof(tail),
- " %02d/%02d %02d:%02d",
- ptime->tm_mon+1, ptime->tm_mday,
- ptime->tm_hour, ptime->tm_min);
- }
-
-#ifdef OLDRECOMMEND
- snprintf(buf, sizeof(buf),
- ANSI_COLOR(1;31) "¡÷ " ANSI_COLOR(33) "%s"
- ANSI_RESET ANSI_COLOR(33) ":%-*s" ANSI_RESET
- "±À%s\n",
- cuser.userid, maxlength, msg, tail);
-#else
- snprintf(buf, sizeof(buf),
- "%s%s " ANSI_COLOR(33) "%s" ANSI_RESET ANSI_COLOR(33)
- ":%-*s" ANSI_RESET "%s\n",
- ctype_attr2[type], ctype[type], cuser.userid,
- maxlength, msg, tail);
-#endif // OLDRECOMMEND
- }
-
- do_add_recommend(direct, fhdr, ent, buf, type);
-
-#ifdef ASSESS
- /* ¨C 10 ¦¸±À¤å ¥[¤@¦¸ goodpost */
- // TODO Âà¨Óªº«ç»ò¿ì¡H
- // when recommend reaches MAX_RECOMMENDS...
- if (type ==0 && (fhdr->filemode & FILE_MARKED) &&
- (fhdr->recommend != oldrecom) &&
- fhdr->recommend % 10 == 0)
- {
- inc_goodpost(fhdr->owner, 1);
- sendalert(fhdr->owner, ALERT_PWD_GOODPOST);
- }
-#endif
-
- lastrecommend = now;
- lastrecommend_bid = currbid;
- strlcpy(lastrecommend_fname, fhdr->filename, sizeof(lastrecommend_fname));
- return FULLUPDATE;
-}
-
-static int
-mark_post(int ent, fileheader_t * fhdr, const char *direct)
-{
- char buf[STRLEN], fpath[STRLEN];
-
- if (!(currmode & MODE_BOARD))
- return DONOTHING;
-
- setbpath(fpath, currboard);
- sprintf(buf, "%s/%s", fpath, fhdr->filename);
-
- if( !(fhdr->filemode & FILE_MARKED) && /* ­Y¥Ø«eÁÙ¨S¦³ mark ¤~­n check */
- access(buf, F_OK) < 0 )
- return DONOTHING;
-
- fhdr->filemode ^= FILE_MARKED;
-
-#ifdef ASSESS
- if (!(fhdr->filemode & FILE_BID)){
- if (fhdr->filemode & FILE_MARKED) {
- if (!(currbrdattr & BRD_BAD) && fhdr->recommend >= 10)
- {
- inc_goodpost(fhdr->owner, fhdr->recommend / 10);
- sendalert(fhdr->owner, ALERT_PWD_GOODPOST);
- }
- }
- else if (fhdr->recommend > 9)
- {
- inc_goodpost(fhdr->owner, -1 * (fhdr->recommend / 10));
- sendalert(fhdr->owner, ALERT_PWD_GOODPOST);
- }
- }
-#endif
-
- substitute_ref_record(direct, fhdr, ent);
- check_locked(fhdr);
- return PART_REDRAW;
-}
-
-int
-del_range(int ent, const fileheader_t *fhdr, const char *direct)
-{
- char num1[8], num2[8];
- int inum1, inum2;
- boardheader_t *bp = NULL;
-
- /* ¦³¤TºØ±¡ªp·|¶i³o¸Ì, «H¥ó, ¬ÝªO, ºëµØ°Ï */
-
- if( direct[0] != 'h' && currbid) /* «H¥ó¤£¥Î check */
- {
- // «Ü¤£©¯ªº¬O¦³¤@ºØ¬O«H¥ó->mail_cite->ºëµØ°Ï
- bp = getbcache(currbid);
- if (strcmp(bp->brdname, GLOBAL_SECURITY) == 0)
- return DONOTHING;
- }
-
- /* rocker.011018: ¦ê±µ¼Ò¦¡¤UÁÙ¬O¤£¤¹³\§R°£¤ñ¸û¦n */
- if (currmode & MODE_SELECT) {
- vmsg("½Ð¥ý¦^¨ì¥¿±`¼Ò¦¡«á¦A¶i¦æ§R°£...");
- return FULLUPDATE;
- }
-
- if ((currstat != READING) || (currmode & MODE_BOARD)) {
- getdata(1, 0, "[³]©w§R°£½d³ò] °_ÂI¡G", num1, 6, DOECHO);
- inum1 = atoi(num1);
- if (inum1 <= 0) {
- vmsg("°_ÂI¦³»~");
- return FULLUPDATE;
- }
- getdata(1, 28, "²×ÂI¡G", num2, 6, DOECHO);
- inum2 = atoi(num2);
- if (inum2 < inum1) {
- vmsg("²×ÂI¦³»~");
- return FULLUPDATE;
- }
- getdata(1, 48, msg_sure_ny, num1, 3, LCECHO);
- if (*num1 == 'y') {
- outmsg("³B²z¤¤,½Ðµy«á...");
- refresh();
-#ifdef SAFE_ARTICLE_DELETE
- if(bp && !(currmode & MODE_DIGEST) && bp->nuser > 30 )
- safe_article_delete_range(direct, inum1, inum2);
- else
- delete_range(direct, inum1, inum2);
-#else
- delete_range(direct, inum1, inum2);
-#endif
- fixkeep(direct, inum1);
-
- if ((curredit & EDIT_MAIL)==0 && (currmode & MODE_BOARD)) // Ptt:update cache
- setbtotal(currbid);
- else if(currstat == RMAIL)
- setupmailusage();
-
- return DIRCHANGED;
- }
- return FULLUPDATE;
- }
- return DONOTHING;
-}
-
-static int
-del_post(int ent, fileheader_t * fhdr, char *direct)
-{
- char genbuf[100], newpath[PATHLEN];
- int not_owned, tusernum;
- boardheader_t *bp;
-
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- bp = getbcache(currbid);
-
- if (strcmp(bp->brdname, GLOBAL_SECURITY) == 0)
- return DONOTHING;
-
- /* TODO recursive lookup */
- if (currmode & MODE_SELECT) {
- vmsg("½Ð¦^¨ì¤@¯ë¼Ò¦¡¦A§R°£¤å³¹");
- return DONOTHING;
- }
-
- if ((fhdr->filemode & FILE_BOTTOM) ||
- (fhdr->filemode & FILE_MARKED) || (fhdr->filemode & FILE_DIGEST) ||
- (fhdr->owner[0] == '-'))
- return DONOTHING;
-
- if(fhdr->filemode & FILE_ANONYMOUS)
- /* When the file is anonymous posted, fhdr->multi.anon_uid is author.
- * see do_general() */
- tusernum = fhdr->multi.anon_uid;
- else
- tusernum = searchuser(fhdr->owner, NULL);
-
- not_owned = (tusernum == usernum ? 0: 1);
- if ((!(currmode & MODE_BOARD) && not_owned) ||
- ((bp->brdattr & BRD_VOTEBOARD) && !HasUserPerm(PERM_SYSOP)) ||
- !strcmp(cuser.userid, STR_GUEST))
- return DONOTHING;
-
- if (fhdr->filename[0]=='L') fhdr->filename[0]='M';
-
- getdata(1, 0, msg_del_ny, genbuf, 3, LCECHO);
- if (genbuf[0] == 'y') {
- if(
-#ifdef SAFE_ARTICLE_DELETE
- (bp->nuser > 30 && !(currmode & MODE_DIGEST) &&
- !safe_article_delete(ent, fhdr, direct)) ||
-#endif
- !delete_record(direct, sizeof(fileheader_t), ent)
- ) {
-
- cancelpost(fhdr, not_owned, newpath);
- deleteCrossPost(fhdr, bp->brdname);
-#ifdef ASSESS
-#define SIZE sizeof(badpost_reason) / sizeof(char *)
-
- // TODO not_owned ®É¤]­n§ïÅÜ numpost?
- if (not_owned && tusernum > 0 && !(currmode & MODE_DIGEST)) {
- if (now - atoi(fhdr->filename + 2) > 7 * 24 * 60 * 60)
- /* post older than a week */
- genbuf[0] = 'n';
- else
- getdata(1, 40, "´c¦H¤å³¹?(y/N)", genbuf, 3, LCECHO);
-
- if (genbuf[0]=='y') {
- int i;
- char *userid=getuserid(tusernum);
- int rpt_bid;
-
- move(b_lines - 2, 0);
- clrtobot();
- for (i = 0; i < SIZE; i++)
- prints("%d.%s ", i + 1, badpost_reason[i]);
- prints("%d.%s", i + 1, "¨ä¥L");
- getdata(b_lines - 1, 0, "½Ð¿ï¾Ü[0:¨ú®ø¦H¤å]:", genbuf, 3, LCECHO);
- i = genbuf[0] - '1';
- if (i >= 0 && i < SIZE)
- sprintf(genbuf,"¦H¤å°h¦^(%s)", badpost_reason[i]);
- else if(i==SIZE)
- {
- strcpy(genbuf,"¦H¤å°h¦^(");
- getdata_buf(b_lines, 0, "½Ð¿é¤J­ì¦]", genbuf+9,
- 50, DOECHO);
- strcat(genbuf,")");
- }
- if(i>=0 && i <= SIZE)
- {
- strncat(genbuf, fhdr->title, 64-strlen(genbuf));
-
-#ifdef USE_COOLDOWN
- add_cooldowntime(tusernum, 60);
- add_posttimes(tusernum, 15); //Ptt: ­áµ² post for 1 hour
-#endif
-
- if (!(inc_badpost(userid, 1) % 5)){
- userec_t xuser;
- post_violatelaw(userid, BBSMNAME " ¨t²Îĵ¹î",
- "¦H¤å²Ö­p 5 ½g", "»@³æ¤@±i");
- mail_violatelaw(userid, BBSMNAME " ¨t²Îĵ¹î",
- "¦H¤å²Ö­p 5 ½g", "»@³æ¤@±i");
- kick_all(userid);
- passwd_query(tusernum, &xuser);
- xuser.money = moneyof(tusernum);
- xuser.vl_count++;
- xuser.userlevel |= PERM_VIOLATELAW;
- xuser.timeviolatelaw = now;
- passwd_update(tusernum, &xuser);
- }
- sendalert(userid, ALERT_PWD_BADPOST);
- mail_id(userid, genbuf, newpath, cuser.userid);
-
-#ifdef BAD_POST_RECORD
- rpt_bid = getbnum(BAD_POST_RECORD);
- if (rpt_bid > 0) {
- fileheader_t report_fh;
- char report_path[PATHLEN];
-
- setbpath(report_path, BAD_POST_RECORD);
- stampfile(report_path, &report_fh);
-
- strcpy(report_fh.owner, "[" BBSMNAME "ĵ¹î§½]");
- snprintf(report_fh.title, sizeof(report_fh.title),
- "%s ªO %s ªO¥Dµ¹¤© %s ¤@½g¦H¤å",
- currboard, cuser.userid, userid);
- Copy(newpath, report_path);
-
- setbdir(report_path, BAD_POST_RECORD);
- append_record(report_path, &report_fh, sizeof(report_fh));
-
- touchbtotal(rpt_bid);
- }
-#endif /* defined(BAD_POST_RECORD) */
- }
- }
- }
-#undef SIZE
-#endif
-
- setbtotal(currbid);
- if (fhdr->multi.money < 0 || fhdr->filemode & FILE_ANONYMOUS)
- fhdr->multi.money = 0;
- if (not_owned && tusernum && fhdr->multi.money > 0 &&
- !IsFreeBoardName(currboard))
- {
- deumoney(tusernum, -fhdr->multi.money);
-#ifdef USE_COOLDOWN
- if (bp->brdattr & BRD_COOLDOWN)
- add_cooldowntime(tusernum, 15);
-#endif
- }
-
- // owner case.
-
- if (!not_owned && !IsFreeBoardName(currboard)) {
-
- // digest ¤£¥ÎºÞ
- // new rule: only articles with money need updating
- // numpost (to solve deleting cross-posts).
- if (!(currmode & MODE_DIGEST) && (fhdr->multi.money > 0))
- {
- if (cuser.numposts)
- cuser.numposts--;
- demoney(-fhdr->multi.money);
-
- vmsgf("±zªº¤å³¹´î¬° %d ½g¡A¤ä¥I²M¼ä¶O %d »È",
- cuser.numposts, fhdr->multi.money);
- }
- }
- return DIRCHANGED;
- } // delete_record
- } // genbuf[0] == 'y'
- return FULLUPDATE;
-}
-
-static int // Ptt: ­×¥ÛÀY¤å
-show_filename(int ent, const fileheader_t * fhdr, const char *direct)
-{
- if(!HasUserPerm(PERM_SYSOP)) return DONOTHING;
- vmsgf("ÀɮצWºÙ: %s ", fhdr->filename);
- return PART_REDRAW;
-}
-
-static int
-lock_post(int ent, fileheader_t * fhdr, const char *direct)
-{
- char fn1[MAXPATHLEN];
- char genbuf[256] = {'\0'};
- int i;
- boardheader_t *bp = NULL;
-
- if (currstat == RMAIL)
- return DONOTHING;
-
- if (!(currmode & MODE_BOARD) && !HasUserPerm(PERM_SYSOP | PERM_POLICE))
- return DONOTHING;
-
- bp = getbcache(currbid);
- assert(bp);
-
- if (fhdr->filename[0]=='M') {
- if (!HasUserPerm(PERM_SYSOP | PERM_POLICE))
- return DONOTHING;
-
- getdata(b_lines - 1, 0, "½Ð¿é¤JÂê©w²z¥Ñ¡G", genbuf, 50, DOECHO);
-
- if (getans("­n±N¤å³¹Âê©w¶Ü(y/N)?") != 'y')
- return FULLUPDATE;
- setbfile(fn1, currboard, fhdr->filename);
- fhdr->filename[0] = 'L';
- syncnow();
- bp->SRexpire = now;
- }
- else if (fhdr->filename[0]=='L') {
- if (getans("­n±N¤å³¹Âê©w¸Ñ°£¶Ü(y/N)?") != 'y')
- return FULLUPDATE;
- fhdr->filename[0] = 'M';
- setbfile(fn1, currboard, fhdr->filename);
- syncnow();
- bp->SRexpire = now;
- }
- substitute_ref_record(direct, fhdr, ent);
- post_policelog(currboard, fhdr->title, "Âê¤å", genbuf, fhdr->filename[0] == 'L' ? 1 : 0);
- if (fhdr->filename[0] == 'L') {
- fhdr->filename[0] = 'M';
- do_crosspost("PoliceLog", fhdr, fn1, 0);
- fhdr->filename[0] = 'L';
- snprintf(genbuf, sizeof(genbuf), "%s ªO¾DÂê©w¤å³¹ - %s", currboard, fhdr->title);
- for (i = 0; i < MAX_BMs && SHM->BMcache[currbid-1][i] != -1; i++)
- mail_id(SHM->userid[SHM->BMcache[currbid-1][i] - 1], genbuf, fn1, "[¨t²Î]");
- }
- return FULLUPDATE;
-}
-
-static int
-view_postinfo(int ent, const fileheader_t * fhdr, const char *direct, int crs_ln)
-{
- aidu_t aidu = 0;
- int l = crs_ln + 3; /* line of cursor */
- int area_l = l + 1;
- const int area_lines = 4;
-
- if(!fhdr || fhdr->filename[0] == '.' || !fhdr->filename[0])
- return DONOTHING;
-
- if((area_l + area_lines > b_lines) || /* ¤U­±©ñ¤£¤U */
- (l >= (b_lines * 2 / 3))) /* ²¤¶W¹Lµe­± 2/3 */
- area_l -= (area_lines + 1);
-
- grayout(0, MIN(l - 1, area_l)-1, GRAYOUT_DARK);
- grayout(MAX(l + 1 + 1, area_l + area_lines), b_lines-1, GRAYOUT_DARK);
- grayout(l, l, GRAYOUT_BOLD);
-
- /* ²M°£¤å³¹ªº«e¤@¦æ©Î«á¤@¦æ */
- if(area_l > l)
- move(l - 1, 0);
- else
- move(l + 1, 0);
- clrtoeol();
-
- move(area_l-(area_l < l), 0);
- clrtoln(area_l -(area_l < l) + area_lines+1);
- outc(' '); outs(ANSI_CLRTOEND);
- move(area_l -(area_l < l) + area_lines, 0);
- outc(' '); outs(ANSI_CLRTOEND);
- move(area_l, 0);
-
- prints("¢z¢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");
-
- aidu = fn2aidu((char *)fhdr->filename);
- if(aidu > 0)
- {
- char aidc[10];
- int y, x;
-
- aidu2aidc(aidc, aidu);
- prints("¢x " AID_DISPLAYNAME ": "
- ANSI_COLOR(1) "#%s" ANSI_RESET " (%s) [%s] ",
- aidc, currboard && currboard[0] ? currboard : "¥¼ª¾",
- MYHOSTNAME);
- getyx_ansi(&y, &x);
- x = 75 - x;
- if (x > 1)
- prints("%.*s ", x, fhdr->title);
- outs("\n");
- }
- else
- {
- prints("¢x\n");
- }
-
- if(fhdr->filemode & FILE_ANONYMOUS)
- /* When the file is anonymous posted, fhdr->multi.anon_uid is author.
- * see do_general() */
- prints("¢x °Î¦WºÞ²z½s¸¹: %d (¦P¤@¤H¸¹½X·|¤@¼Ë)",
- fhdr->multi.anon_uid + (int)currutmp->pid);
- else {
- int m = query_file_money(fhdr);
-
- if(m < 0)
- prints("¢x ¯S®í¤å³¹¡AµL»ù®æ°O¿ý");
- else
- prints("¢x ³o¤@½g¤å³¹­È %d »È", m);
-
- }
- prints("\n");
- prints("¢|¢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");
-
- /* ¦L¹ï¸Ü®Øªº¥kÃä¬É */
- {
- int i;
-
- for(i = 1; i < area_lines - 1; i ++)
- {
- move_ansi(area_l + i , 76);
- prints("¢x");
- }
- }
- {
- int r = pressanykey();
- /* TODO: ¦h¥[¤@­Ó LISTMODE_AID¡H */
- /* QQ: enable money listing mode */
- if (r == 'Q')
- {
- currlistmode = (currlistmode == LISTMODE_MONEY) ?
- LISTMODE_DATE : LISTMODE_MONEY;
- vmsg((currlistmode == LISTMODE_MONEY) ?
- "¶}±Ò¤å³¹»ù®æ¦Cªí¼Ò¦¡" : "°±¤î¦C¥X¤å³¹»ù®æ");
- }
- }
-
- return FULLUPDATE;
-}
-
-#ifdef OUTJOBSPOOL
-/* ¬ÝªO³Æ¥÷ */
-static int
-tar_addqueue(void)
-{
- char email[60], qfn[80], ans[2];
- FILE *fp;
- char bakboard, bakman;
- clear();
- showtitle("¬ÝªO³Æ¥÷", BBSNAME);
- move(2, 0);
- if (!((currmode & MODE_BOARD) || HasUserPerm(PERM_SYSOP))) {
- move(5, 10);
- outs("©p­n¬OªO¥D©Î¬O¯¸ªø¤~¯àÂæÂæ°Ú -.-\"\"");
- pressanykey();
- return FULLUPDATE;
- }
- snprintf(qfn, sizeof(qfn), BBSHOME "/jobspool/tarqueue.%s", currboard);
- if (access(qfn, 0) == 0) {
- outs("¤w¸g±Æ©w¦æµ{, µy«á·|¶i¦æ³Æ¥÷");
- pressanykey();
- return FULLUPDATE;
- }
-#ifdef TARQUEUE_SENDURL
- move (3,0); outs("½Ð¿é¤J³qª¾«H½c (¹w³]¬°¦¹ BBS ±b¸¹«H½c): ");
- if (!getdata_str(4, 2, "",
- email, sizeof(email), DOECHO, cuser.userid))
- return FULLUPDATE;
- if (strstr(email, "@") == NULL)
- {
- strcat(email, ".bbs@");
- strcat(email, MYHOSTNAME);
- }
- move(4,0); clrtoeol();
- outs(email);
-#else
- if (!getdata(4, 0, "½Ð¿é¤J¥Øªº«H½c¡G", email, sizeof(email), DOECHO))
- return FULLUPDATE;
-
- /* check email -.-"" */
- if (strstr(email, "@") == NULL || strstr(email, ".bbs@") != NULL) {
- move(6, 0);
- outs("±z«ü©wªº«H½c¤£¥¿½T! ");
- pressanykey();
- return FULLUPDATE;
- }
-#endif
- getdata(6, 0, "­n³Æ¥÷¬ÝªO¤º®e¶Ü(Y/N)?[Y]", ans, sizeof(ans), LCECHO);
- bakboard = (ans[0] == 'n' || ans[0] == 'N') ? 0 : 1;
- getdata(7, 0, "­n³Æ¥÷ºëµØ°Ï¤º®e¶Ü(Y/N)?[N]", ans, sizeof(ans), LCECHO);
- bakman = (ans[0] == 'y' || ans[0] == 'Y') ? 1 : 0;
- if (!bakboard && !bakman) {
- move(8, 0);
- outs("¥i¬O§Ú­Ì¥u¯à³Æ¥÷¬ÝªO©ÎºëµØ°Ïªº­C ^^\"\"\"");
- pressanykey();
- return FULLUPDATE;
- }
- fp = fopen(qfn, "w");
- fprintf(fp, "%s\n", cuser.userid);
- fprintf(fp, "%s\n", email);
- fprintf(fp, "%d,%d\n", bakboard, bakman);
- fclose(fp);
-
- move(10, 0);
- outs("¨t²Î¤w¸g±N±zªº³Æ¥÷±Æ¤J¦æµ{, \n");
- outs("µy«á±N·|¦b¨t²Î­t²ü¸û§Cªº®É­Ô±N¸ê®Æ±Hµ¹±z~ :) ");
- pressanykey();
- return FULLUPDATE;
-}
-#endif
-
-/* ----------------------------------------------------- */
-/* ¬ÝªO³Æ§Ñ¿ý¡B¤åºK¡BºëµØ°Ï */
-/* ----------------------------------------------------- */
-int
-b_note_edit_bname(int bid)
-{
- char buf[PATHLEN];
- int aborted;
- boardheader_t *fh = getbcache(bid);
- assert(0<=bid-1 && bid-1<MAX_BOARD);
- setbfile(buf, fh->brdname, fn_notes);
- aborted = vedit(buf, NA, NULL);
- if (aborted == -1) {
- clear();
- outs(msg_cancel);
- pressanykey();
- } else {
- if (!getdata(2, 0, "³]©w¦³®Ä´Á­­¤Ñ¡H(n/Y)", buf, 3, LCECHO)
- || buf[0] != 'n')
- fh->bupdate = gettime(3, fh->bupdate ? fh->bupdate : now,
- "¦³®Ä¤é´Á¦Ü");
- else
- fh->bupdate = 0;
- assert(0<=bid-1 && bid-1<MAX_BOARD);
- substitute_record(fn_board, fh, sizeof(boardheader_t), bid);
- }
- return 0;
-}
-
-static int
-b_notes_edit(void)
-{
- if (currmode & MODE_BOARD) {
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- b_note_edit_bname(currbid);
- return FULLUPDATE;
- }
- return 0;
-}
-
-static int
-bh_title_edit(void)
-{
- boardheader_t *bp;
-
- if (currmode & MODE_BOARD) {
- char genbuf[BTLEN];
-
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- bp = getbcache(currbid);
- move(1, 0);
- clrtoeol();
- getdata_str(1, 0, "½Ð¿é¤J¬ÝªO·s¤¤¤å±Ô­z:", genbuf,
- BTLEN - 16, DOECHO, bp->title + 7);
-
- if (!genbuf[0])
- return 0;
- strip_ansi(genbuf, genbuf, STRIP_ALL);
- strlcpy(bp->title + 7, genbuf, sizeof(bp->title) - 7);
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- substitute_record(fn_board, bp, sizeof(boardheader_t), currbid);
- log_usies("SetBoard", currboard);
- return FULLUPDATE;
- }
- return 0;
-}
-
-static int
-b_notes(void)
-{
- char buf[PATHLEN];
- int mr = 0;
-
- setbfile(buf, currboard, fn_notes);
- mr = more(buf, NA);
-
- if (mr == -1)
- {
- clear();
- move(4, 20);
- outs("¥»¬ÝªO©|µL¡u³Æ§Ñ¿ý¡v¡C");
- }
- if(mr != READ_NEXT)
- pressanykey();
- return FULLUPDATE;
-}
-
-int
-board_select(void)
-{
- currmode &= ~MODE_SELECT;
- currsrmode = 0;
- if (currstat == RMAIL)
- sethomedir(currdirect, cuser.userid);
- else
- setbdir(currdirect, currboard);
- return NEWDIRECT;
-}
-
-int
-board_digest(void)
-{
- if (currmode & MODE_SELECT)
- board_select();
- currmode ^= MODE_DIGEST;
-
- // MODE_POST may be changed if board is modified.
- // do not change post perm here. use other instead.
-
- setbdir(currdirect, currboard);
- return NEWDIRECT;
-}
-
-
-static int
-push_bottom(int ent, fileheader_t *fhdr, const char *direct)
-{
- int num;
- char buf[256];
- if ((currmode & MODE_DIGEST) || !(currmode & MODE_BOARD)
- || fhdr->filename[0]=='L')
- return DONOTHING;
- setbottomtotal(currbid); // <- Ptt : will be remove when stable
- num = getbottomtotal(currbid);
- if( getans(fhdr->filemode & FILE_BOTTOM ?
- "¨ú®ø¸m©³¤½§i?(y/N)":
- "¥[¤J¸m©³¤½§i?(y/N)") != 'y' )
- return READ_REDRAW;
- if(!(fhdr->filemode & FILE_BOTTOM) ){
- sprintf(buf, "%s.bottom", direct);
- if(num >= 5){
- vmsg("¤£±o¶W¹L 5 ½g­«­n¤½§i ½Ðºë²!");
- return READ_REDRAW;
- }
- fhdr->filemode ^= FILE_BOTTOM;
- fhdr->multi.refer.flag = 1;
- fhdr->multi.refer.ref = ent;
- append_record(buf, fhdr, sizeof(fileheader_t));
- }
- else{
- fhdr->filemode ^= FILE_BOTTOM;
- num = delete_record(direct, sizeof(fileheader_t), ent);
- }
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- setbottomtotal(currbid);
- return DIRCHANGED;
-}
-
-static int
-good_post(int ent, fileheader_t * fhdr, const char *direct)
-{
- char genbuf[200];
- char genbuf2[200];
- int delta = 0;
-
- if ((currmode & MODE_DIGEST) || !(currmode & MODE_BOARD))
- return DONOTHING;
-
- if(getans(fhdr->filemode & FILE_DIGEST ?
- "¨ú®ø¬ÝªO¤åºK?(Y/n)" : "¦¬¤J¬ÝªO¤åºK?(Y/n)") == 'n')
- return READ_REDRAW;
-
- if (fhdr->filemode & FILE_DIGEST) {
- fhdr->filemode = (fhdr->filemode & ~FILE_DIGEST);
- if (!strcmp(currboard, GLOBAL_NOTE) ||
-#ifdef GLOBAL_ARTDSN
- !strcmp(currboard, GLOBAL_ARTDSN) ||
-#endif
- !strcmp(currboard, GLOBAL_BUGREPORT) ||
- !strcmp(currboard, GLOBAL_LAW)
- )
- {
- deumoney(searchuser(fhdr->owner, NULL), -1000); // TODO if searchuser() return 0
- if (!(currmode & MODE_SELECT))
- fhdr->multi.money -= 1000;
- else
- delta = -1000;
- }
- } else {
- fileheader_t digest;
- char *ptr, buf[PATHLEN];
-
- memcpy(&digest, fhdr, sizeof(digest));
- digest.filename[0] = 'G';
- strlcpy(buf, direct, sizeof(buf));
- ptr = strrchr(buf, '/');
- assert(ptr);
- ptr++;
- ptr[0] = '\0';
- snprintf(genbuf, sizeof(genbuf), "%s%s", buf, digest.filename);
-
- if (dashf(genbuf))
- unlink(genbuf);
-
- digest.filemode = 0;
- snprintf(genbuf2, sizeof(genbuf2), "%s%s", buf, fhdr->filename);
- Copy(genbuf2, genbuf);
- strcpy(ptr, fn_mandex);
- append_record(buf, &digest, sizeof(digest));
-
-#ifdef GLOBAL_DIGEST
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- if(!(getbcache(currbid)->brdattr & BRD_HIDE)) {
- getdata(1, 0, "¦n¤å­È±o¥Xª©¨ì¥þ¯¸¤åºK?(N/y)", genbuf2, 3, LCECHO);
- if(genbuf2[0] == 'y')
- do_crosspost(GLOBAL_DIGEST, &digest, genbuf, 1);
- }
-#endif
-
- fhdr->filemode = (fhdr->filemode & ~FILE_MARKED) | FILE_DIGEST;
- if (!strcmp(currboard, GLOBAL_NOTE) ||
-#ifdef GLOBAL_ARTDSN
- !strcmp(currboard, GLOBAL_ARTDSN) ||
-#endif
- !strcmp(currboard, GLOBAL_BUGREPORT) ||
- !strcmp(currboard, GLOBAL_LAW)
- )
- {
- deumoney(searchuser(fhdr->owner, NULL), 1000); // TODO if searchuser() return 0
- if (!(currmode & MODE_SELECT))
- fhdr->multi.money += 1000;
- else
- delta = 1000;
- }
- }
- substitute_ref_record(direct, fhdr, ent);
- return FULLUPDATE;
-}
-
-static int
-b_help(void)
-{
- show_helpfile(fn_boardhelp);
- return FULLUPDATE;
-}
-
-#ifdef USE_COOLDOWN
-
-int check_cooldown(boardheader_t *bp)
-{
- int diff = cooldowntimeof(usernum) - now;
- int i, limit[8] = {4000,1,2000,2,1000,3,-1,10};
-
- if(diff<0)
- SHM->cooldowntime[usernum - 1] &= 0xFFFFFFF0;
- else if( !((currmode & MODE_BOARD) || HasUserPerm(PERM_SYSOP)))
- {
- if( bp->brdattr & BRD_COOLDOWN )
- {
- vmsgf("§NÀR¤@¤U§a¡I (­­¨î %d ¤À %d ¬í)", diff/60, diff%60);
- return 1;
- }
- else if(posttimesof(usernum)==0xf)
- {
- vmsgf("¹ï¤£°_¡A±z³Q³]¦H¤å¡I (­­¨î %d ¤À %d ¬í)", diff/60, diff%60);
- return 1;
- }
-#ifdef NO_WATER_POST
- else
- {
- for(i=0; i<4; i++)
- if(bp->nuser>limit[i*2] && posttimesof(usernum)>=limit[i*2+1])
- {
- vmsgf("¹ï¤£°_¡A±zªº¤å³¹©Î±À¤å¶¡¹j¤ÓªñÅo¡I (­­¨î %d ¤À %d ¬í)",
- diff/60, diff%60);
- return 1;
- }
- }
-#endif // NO_WATER_POST
- }
- return 0;
-}
-/**
- * ³]©w¬ÝªO§NÀR¥\¯à, ­­¨î¨Ï¥ÎªÌµo¤å®É¶¡
- */
-static int
-change_cooldown(void)
-{
- char genbuf[256] = {'\0'};
- boardheader_t *bp = getbcache(currbid);
-
- if (!(HasUserPerm(PERM_SYSOP | PERM_POLICE) ||
- (HasUserPerm(PERM_SYSSUPERSUBOP) && GROUPOP())))
- return DONOTHING;
-
- if (bp->brdattr & BRD_COOLDOWN) {
- if (getans("¥Ø«e­°·Å¤¤, ­n¶}©ñ¶Ü(y/N)?") != 'y')
- return FULLUPDATE;
- bp->brdattr &= ~BRD_COOLDOWN;
- outs("¤j®a³£¥i¥H post ¤å³¹¤F¡C\n");
- } else {
- getdata(b_lines - 1, 0, "½Ð¿é¤J§NÀR²z¥Ñ¡G", genbuf, 50, DOECHO);
- if (getans("­n­­¨î post ÀW²v, ­°·Å¶Ü(y/N)?") != 'y')
- return FULLUPDATE;
- bp->brdattr |= BRD_COOLDOWN;
- outs("¶}©l§NÀR¡C\n");
- }
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- substitute_record(fn_board, bp, sizeof(boardheader_t), currbid);
- post_policelog(bp->brdname, NULL, "§NÀR", genbuf, bp->brdattr & BRD_COOLDOWN);
- pressanykey();
- return FULLUPDATE;
-}
-#endif
-
-static int
-b_moved_to_config()
-{
- if ((currmode & MODE_BOARD) || HasUserPerm(PERM_SYSOP))
- {
- vmsg("³o­Ó¥\\¯à¤w²¾¤J¬ÝªO³]©w (i) ¥h¤F¡I");
- return FULLUPDATE;
- }
- return DONOTHING;
-}
-
-/* ----------------------------------------------------- */
-/* ¬ÝªO¥\¯àªí */
-/* ----------------------------------------------------- */
-/* onekey_size was defined in ../include/pttstruct.h, as ((int)'z') */
-const onekey_t read_comms[] = {
- { 1, show_filename }, // Ctrl('A')
- { 0, NULL }, // Ctrl('B')
- { 0, NULL }, // Ctrl('C')
- { 0, NULL }, // Ctrl('D')
- { 1, lock_post }, // Ctrl('E')
- { 0, NULL }, // Ctrl('F')
-#ifdef NO_GAMBLE
- { 0, NULL }, // Ctrl('G')
-#else
- { 0, hold_gamble }, // Ctrl('G')
-#endif
- { 0, NULL }, // Ctrl('H')
- { 0, board_digest }, // Ctrl('I') KEY_TAB 9
- { 0, NULL }, // Ctrl('J')
- { 0, NULL }, // Ctrl('K')
- { 0, NULL }, // Ctrl('L')
- { 0, NULL }, // Ctrl('M')
- { 0, NULL }, // Ctrl('N')
- { 0, do_post_openbid }, // Ctrl('O') // BETTER NOT USE ^O - UNIX not work
- { 0, do_post }, // Ctrl('P')
- { 0, NULL }, // Ctrl('Q')
- { 0, NULL }, // Ctrl('R')
- { 0, NULL }, // Ctrl('S')
- { 0, NULL }, // Ctrl('T')
- { 0, NULL }, // Ctrl('U')
- { 0, do_post_vote }, // Ctrl('V')
- { 0, whereami }, // Ctrl('W')
- { 0, NULL }, // Ctrl('X')
- { 0, NULL }, // Ctrl('Y')
- { 1, push_bottom }, // Ctrl('Z') 26
- { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL },
- { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL },
- { 1, recommend }, // '%' (m3itoc style)
- { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL },
- { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL },
- { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL },
- { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL },
- { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL },
- { 0, NULL }, { 0, NULL }, { 0, NULL },
- { 0, NULL }, // 'A' 65
- { 0, bh_title_edit }, // 'B'
- { 1, do_limitedit }, // 'C'
- { 1, del_range }, // 'D'
- { 1, edit_post }, // 'E'
- { 0, NULL }, // 'F'
- { 0, NULL }, // 'G'
- { 0, b_moved_to_config }, // 'H'
- { 0, b_config }, // 'I'
-#ifdef USE_COOLDOWN
- { 0, change_cooldown }, // 'J'
-#else
- { 0, NULL }, // 'J'
-#endif
- { 0, b_moved_to_config }, // 'K'
- { 1, solve_post }, // 'L'
- { 0, b_moved_to_config }, // 'M'
- { 0, NULL }, // 'N'
- { 0, NULL }, // 'O'
- { 0, NULL }, // 'P'
- { 1, view_postinfo }, // 'Q'
- { 0, b_results }, // 'R'
- { 0, NULL }, // 'S'
- { 1, edit_title }, // 'T'
- { 0, NULL }, // 'U'
- { 0, b_vote }, // 'V'
- { 0, b_notes_edit }, // 'W'
- { 1, recommend }, // 'X'
- { 1, recommend_cancel }, // 'Y'
- { 0, NULL }, // 'Z' 90
- { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL },
- { 0, NULL }, // 'a' 97
- { 0, b_notes }, // 'b'
- { 1, cite_post }, // 'c'
- { 1, del_post }, // 'd'
- { 0, NULL }, // 'e'
-#ifdef NO_GAMBLE
- { 0, NULL }, // 'f'
-#else
- { 0, join_gamble }, // 'f'
-#endif
- { 1, good_post }, // 'g'
- { 0, b_help }, // 'h'
- { 0, b_config }, // 'i'
- { 0, NULL }, // 'j'
- { 0, NULL }, // 'k'
- { 0, NULL }, // 'l'
- { 1, mark_post }, // 'm'
- { 0, NULL }, // 'n'
- { 0, NULL }, // 'o'
- { 0, NULL }, // 'p'
- { 0, NULL }, // 'q'
- { 1, read_post }, // 'r'
- { 0, do_select }, // 's'
- { 0, NULL }, // 't'
-#ifdef OUTJOBSPOOL
- { 0, tar_addqueue }, // 'u'
-#else
- { 0, NULL }, // 'u'
-#endif
- { 0, b_moved_to_config }, // 'v'
- { 1, b_call_in }, // 'w'
- { 1, cross_post }, // 'x'
- { 1, reply_post }, // 'y'
- { 0, b_man }, // 'z' 122
-};
-
-int
-Read(void)
-{
- int mode0 = currutmp->mode;
- int stat0 = currstat, tmpbid = currutmp->brc_id;
- static int lastbid = -1;
- char buf[PATHLEN];
-#ifdef LOG_BOARD
- time4_t usetime = now;
-#endif
-
- const char *bname = currboard[0] ? currboard : DEFAULT_BOARD;
- if (enter_board(bname) < 0)
- return 0;
-
- setutmpmode(READING);
-
- if (currbid != lastbid &&
- board_note_time && board_visit_time < *board_note_time) {
- int mr;
-
- setbfile(buf, currboard, fn_notes);
- mr = more(buf, NA);
- if(mr == -1)
- *board_note_time=0;
- else if (mr != READ_NEXT)
- pressanykey();
- }
- lastbid = currbid;
- i_read(READING, currdirect, readtitle, readdoent, read_comms,
- currbid);
- currmode &= ~MODE_POSTCHECKED;
-#ifdef LOG_BOARD
- log_board(currboard, now - usetime);
-#endif
- brc_update();
- setutmpbid(tmpbid);
- currutmp->mode = mode0;
- currstat = stat0;
- return 0;
-}
-
-void
-ReadSelect(void)
-{
- int mode0 = currutmp->mode;
- int stat0 = currstat;
-
- currstat = SELECT;
- if (do_select() == NEWDIRECT)
- Read();
- setutmpbid(0);
- currutmp->mode = mode0;
- currstat = stat0;
-}
-
-#ifdef LOG_BOARD
-static void
-log_board(iconst char *mode, time4_t usetime)
-{
- if (usetime > 30) {
- log_file(FN_USEBOARD, LOG_CREAT | LOG_VF,
- "USE %-20.20s Stay: %5ld (%s) %s\n",
- mode, usetime, cuser.userid, ctime4(&now));
- }
-}
-#endif
-
-int
-Select(void)
-{
- return do_select();
-}
-
-#ifdef HAVEMOBILE
-void
-mobile_message(const char *mobile, char *message)
-{
- bsmtp(fpath, title, rcpt);
-}
-#endif
diff --git a/mbbsd/bbslua.c b/mbbsd/bbslua.c
deleted file mode 100644
index 0305bd78..00000000
--- a/mbbsd/bbslua.c
+++ /dev/null
@@ -1,1801 +0,0 @@
-//////////////////////////////////////////////////////////////////////////
-// BBS-Lua Project
-//
-// Author: Hung-Te Lin(piaip), Jan. 2008.
-// <piaip@csie.ntu.edu.tw>
-// Create: 2008-01-04 22:02:58
-// $Id$
-//
-// This source is released in MIT License, same as Lua 5.0
-// http://www.lua.org/license.html
-//
-// Copyright 2008 Hung-Te Lin <piaip@csie.ntu.edu.tw>
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-//
-// TODO:
-// BBSLUA 1.0
-// 1. add quick key/val conversion [deprecated]
-// 2. add key values (UP/DOWN/...) [done]
-// 3. remove i/o libraries [done]
-// 4. add system break key (Ctrl-C) [done]
-// 5. add version string and script tags [done]
-// 6. standalone w32 sdk [done]
-// 7. syntax highlight in editor [done]
-// 8. prevent loadfile, dofile [done]
-// 9. provide local storage
-// ?. modify bbs user data (eg, money)
-// ?. os.date(), os.exit(), abort(), os.time()
-// ?. memory free issue in C library level?
-// ?. add digital signature
-//
-// BBSLUA 2.0
-// 1. 2 people communication
-//
-// BBSLUA 3.0
-// 1. n people communication
-//////////////////////////////////////////////////////////////////////////
-
-#include "bbs.h"
-#include "fnv_hash.h"
-
-#include <lua.h>
-#include <lualib.h>
-#include <lauxlib.h>
-
-//////////////////////////////////////////////////////////////////////////
-// CONST DEFINITION
-//////////////////////////////////////////////////////////////////////////
-
-#define BBSLUA_INTERFACE_VER 0.119 // (0.201)
-#define BBSLUA_SIGNATURE "--#BBSLUA"
-
-// BBS-Lua script format:
-// $BBSLUA_SIGNATURE
-// -- Interface: $interface
-// -- Title: $title
-// -- Notes: $notes
-// -- Author: $author <email@domain>
-// -- Version: $version
-// -- Date: $date
-// -- LatestRef: #AID board
-// [... script ...]
-// $BBSLUA_SIGNATURE
-
-//////////////////////////////////////////////////////////////////////////
-// CONFIGURATION VARIABLES
-//////////////////////////////////////////////////////////////////////////
-#define BLAPI_PROTO int
-
-#define BLCONF_BREAK_KEY Ctrl('C')
-#define BLCONF_EXEC_COUNT (5000)
-#define BLCONF_PEEK_TIME (0.01)
-#define BLCONF_KBHIT_TMIN (BLCONF_PEEK_TIME)
-#define BLCONF_KBHIT_TMAX (60*10)
-#define BLCONF_SLEEP_TMIN (BLCONF_PEEK_TIME)
-#define BLCONF_SLEEP_TMAX (BLCONF_KBHIT_TMAX)
-#define BLCONF_U_SECOND (1000000L)
-#define BLCONF_PRINT_TOC_INDEX (2)
-
-#define BLCONF_MMAP_ATTACH
-#define BLCONF_CURRENT_USERID cuser.userid
-#define BLCONF_CURRENT_USERNICK cuser.nickname
-
-// BBS-Lua Storage
-enum {
- BLS_INVALID= 0,
- BLS_GLOBAL = 1,
- BLS_USER,
-};
-
-// #define BLSCONF_ENABLED
-#define BLSCONF_GLOBAL_VAL "global"
-#define BLSCONF_USER_VAL "user"
-#define BLSCONF_GMAXSIZE (16*1024) // should be aligned to block size
-#define BLSCONF_UMAXSIZE (16*1024) // should be aligned to block size
-#define BLSCONF_GPATH BBSHOME "/luastore"
-#define BLSCONF_UPATH ".luastore"
-#define BLSCONF_PREFIX "v1_"
-#define BLSCONF_MAXIO 32 // prevent bursting system
-
-// #define BBSLUA_USAGE
-
-#ifdef _WIN32
-# undef BLCONF_MMAP_ATTACH
-# undef BLCONF_CURRENT_USERID
-# define BLCONF_CURRENT_USERID "guest"
-# undef BLCONF_CURRENT_USERNICK
-# define BLCONF_CURRENT_USERNICK "´ú¸Õ±b¸¹"
-#endif
-
-//////////////////////////////////////////////////////////////////////////
-// GLOBAL VARIABLES
-//////////////////////////////////////////////////////////////////////////
-typedef struct {
- char running; // prevent re-entrant
- char abort; // system break key hit
- char iocounter; // prevent bursting i/o
- Fnv32_t storename; // storage filename
-} BBSLuaRT;
-
-// runtime information
-// static
-BBSLuaRT blrt = {0};
-
-#define BL_INIT_RUNTIME() { \
- memset(&blrt, 0, sizeof(blrt)); \
- blrt.storename = FNV1_32_INIT; \
-}
-
-#define BL_END_RUNTIME() { \
- memset(&blrt, 0, sizeof(blrt)); \
-}
-
-#ifdef BBSLUA_USAGE
-static int bbslua_count;
-#endif
-
-//////////////////////////////////////////////////////////////////////////
-// UTILITIES
-//////////////////////////////////////////////////////////////////////////
-
-static void
-bl_double2tv(double d, struct timeval *tv)
-{
- tv->tv_sec = d;
- tv->tv_usec = (d - tv->tv_sec) * BLCONF_U_SECOND;
-}
-
-static double
-bl_tv2double(const struct timeval *tv)
-{
- double d = tv->tv_sec;
- d += tv->tv_usec / (double)BLCONF_U_SECOND;
- return d;
-}
-
-static int
-bl_peekbreak(float f)
-{
- if (input_isfull())
- drop_input();
- if (peek_input(f, BLCONF_BREAK_KEY))
- {
- drop_input();
- blrt.abort = 1;
- return 1;
- }
- return 0;
-}
-
-static void
-bl_k2s(lua_State* L, int v)
-{
- if (v <= 0)
- lua_pushnil(L);
- else if (v == KEY_TAB)
- lua_pushstring(L, "TAB");
- else if (v == '\b' || v == 0x7F)
- lua_pushstring(L, "BS");
- else if (v == '\n' || v == '\r' || v == Ctrl('M'))
- lua_pushstring(L, "ENTER");
- else if (v < ' ')
- lua_pushfstring(L, "^%c", v-1+'A');
- else if (v < 0x100)
- lua_pushfstring(L, "%c", v);
- else if (v >= KEY_F1 && v <= KEY_F12)
- lua_pushfstring(L, "F%d", v - KEY_F1 +1);
- else switch(v)
- {
- case KEY_UP: lua_pushstring(L, "UP"); break;
- case KEY_DOWN: lua_pushstring(L, "DOWN"); break;
- case KEY_RIGHT: lua_pushstring(L, "RIGHT"); break;
- case KEY_LEFT: lua_pushstring(L, "LEFT"); break;
- case KEY_HOME: lua_pushstring(L, "HOME"); break;
- case KEY_END: lua_pushstring(L, "END"); break;
- case KEY_INS: lua_pushstring(L, "INS"); break;
- case KEY_DEL: lua_pushstring(L, "DEL"); break;
- case KEY_PGUP: lua_pushstring(L, "PGUP"); break;
- case KEY_PGDN: lua_pushstring(L, "PGDN"); break;
- default: lua_pushnil(L); break;
- }
-}
-
-BLAPI_PROTO
-bl_newwin(int rows, int cols, const char *title)
-{
- // input: (rows, cols, title)
- int y = 0, x = 0, n = 0;
- int oy = 0, ox = 0;
-
- if (rows <= 0 || cols <= 0)
- return 0;
-
- getyx(&oy, &ox);
- // now, draw the window
- newwin(rows, cols, oy, ox);
-
- if (!title || !*title)
- return 0;
-
- // draw center-ed title
- n = strlen_noansi(title);
- x = ox + (cols - n)/2;
- y = oy + (rows)/2;
- move(y, x);
- outs(title);
-
- move(oy, ox);
- return 0;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// BBSLUA API IMPLEMENTATION
-//////////////////////////////////////////////////////////////////////////
-
-BLAPI_PROTO
-bl_getyx(lua_State* L)
-{
- int y, x;
- getyx(&y, &x);
- lua_pushinteger(L, y);
- lua_pushinteger(L, x);
- return 2;
-}
-
-BLAPI_PROTO
-bl_getmaxyx(lua_State* L)
-{
- lua_pushinteger(L, t_lines);
- lua_pushinteger(L, t_columns);
- return 2;
-}
-
-BLAPI_PROTO
-bl_move(lua_State* L)
-{
- int n = lua_gettop(L);
- int y = 0, x = 0;
- if (n > 0)
- y = lua_tointeger(L, 1);
- if (n > 1)
- x = lua_tointeger(L, 2);
- move_ansi(y, x);
- return 0;
-}
-
-BLAPI_PROTO
-bl_moverel(lua_State* L)
-{
- int n = lua_gettop(L);
- int y = 0, x = 0;
- getyx(&y, &x);
- if (n > 0)
- y += lua_tointeger(L, 1);
- if (n > 1)
- x += lua_tointeger(L, 2);
- move(y, x);
- getyx(&y, &x);
- lua_pushinteger(L, y);
- lua_pushinteger(L, x);
- return 2;
-}
-
-BLAPI_PROTO
-bl_clear(lua_State* L)
-{
- (void)L; /* to avoid warnings */
- clear();
- return 0;
-}
-
-BLAPI_PROTO
-bl_clrtoeol(lua_State* L)
-{
- (void)L; /* to avoid warnings */
- clrtoeol();
- return 0;
-}
-
-BLAPI_PROTO
-bl_clrtobot(lua_State* L)
-{
- (void)L; /* to avoid warnings */
- clrtobot();
- return 0;
-}
-
-BLAPI_PROTO
-bl_refresh(lua_State* L)
-{
- (void)L; /* to avoid warnings */
- // refresh();
- // Seems like that most people don't understand the relationship
- // between refresh() and input queue, so let's force update here.
- doupdate();
- return 0;
-}
-
-BLAPI_PROTO
-bl_addstr(lua_State* L)
-{
- int n = lua_gettop(L);
- int i = 1;
- for (i = 1; i <= n; i++)
- {
- const char *s = lua_tostring(L, i);
- if(s)
- outs(s);
- }
- return 0;
-}
-
-BLAPI_PROTO
-bl_rect(lua_State *L)
-{
- // input: (rows, cols, title)
- int rows = 1, cols = 1;
- int n = lua_gettop(L);
- const char *title = NULL;
-
- if (n > 0)
- rows = lua_tointeger(L, 1);
- if (n > 1)
- cols = lua_tointeger(L, 2);
- if (n > 2)
- title = lua_tostring(L, 3);
- if (rows <= 0 || cols <= 0)
- return 0;
-
- // now, draw the rectangle
- bl_newwin(rows, cols, title);
- return 0;
-}
-
-BLAPI_PROTO
-bl_print(lua_State* L)
-{
- bl_addstr(L);
- outc('\n');
- return 0;
-}
-
-BLAPI_PROTO
-bl_getch(lua_State* L)
-{
- int c = igetch();
- if (c == BLCONF_BREAK_KEY)
- {
- drop_input();
- blrt.abort = 1;
- return lua_yield(L, 0);
- }
- bl_k2s(L, c);
- return 1;
-}
-
-
-BLAPI_PROTO
-bl_getstr(lua_State* L)
-{
- int y, x;
- // TODO not using fixed length here?
- char buf[PATHLEN] = "";
- int len = 2, echo = 1;
- int n = lua_gettop(L);
- const char *pmsg = NULL;
-
- if (n > 0)
- len = lua_tointeger(L, 1);
- if (n > 1)
- echo = lua_tointeger(L, 2);
- if (n > 2)
- pmsg = lua_tostring(L, 3);
-
- if (len < 2)
- len = 2;
- if (len >= sizeof(buf))
- len = sizeof(buf)-1;
- /*
- * this part now done in getdata_str
- if (pmsg && *pmsg)
- {
- strlcpy(buf, pmsg, sizeof(buf));
- }
- */
-
- // TODO process Ctrl-C here
- getyx(&y, &x);
- if (!pmsg) pmsg = "";
- len = getdata_str(y, x, NULL, buf, len, echo, pmsg);
- if (len <= 0)
- {
- len = 0;
- // check if we got Ctrl-C? (workaround in getdata)
- // TODO someday write 'ungetch()' in io.c to prevent
- // such workaround.
- if (buf[1] == Ctrl('C'))
- {
- drop_input();
- blrt.abort = 1;
- return lua_yield(L, 0);
- }
- lua_pushstring(L, "");
- }
- else
- {
- lua_pushstring(L, buf);
- }
- // return len ? 1 : 0;
- return 1;
-}
-
-BLAPI_PROTO
-bl_kbhit(lua_State *L)
-{
- int n = lua_gettop(L);
- double f = 0.1f;
-
- if (n > 0)
- f = (double)lua_tonumber(L, 1);
-
- if (f < BLCONF_KBHIT_TMIN) f = BLCONF_KBHIT_TMIN;
- if (f > BLCONF_KBHIT_TMAX) f = BLCONF_KBHIT_TMAX;
-
- refresh();
- if (num_in_buf() || wait_input(f, 0))
- lua_pushboolean(L, 1);
- else
- lua_pushboolean(L, 0);
- return 1;
-}
-
-BLAPI_PROTO
-bl_kbreset(lua_State *L)
-{
- // peek input queue first!
- if (bl_peekbreak(BLCONF_PEEK_TIME))
- return lua_yield(L, 0);
-
- drop_input();
- return 0;
-}
-
-BLAPI_PROTO
-bl_sleep(lua_State *L)
-{
- int n = lua_gettop(L);
- double us = 0, nus = 0;
-
- // update screen first.
- bl_refresh(L);
-
- if (n > 0)
- us = lua_tonumber(L, 1);
- if (us < BLCONF_SLEEP_TMIN) us = BLCONF_SLEEP_TMIN;
- if (us > BLCONF_SLEEP_TMAX) us = BLCONF_SLEEP_TMAX;
- nus = us;
-
-#ifdef _WIN32
-
- Sleep(us * 1000);
-
-#else // !_WIN32
- {
- struct timeval tp, tdest;
-
- gettimeofday(&tp, NULL);
-
- // nus is the destination time
- nus = bl_tv2double(&tp) + us;
- bl_double2tv(nus, &tdest);
-
- while ( (tp.tv_sec < tdest.tv_sec) ||
- ((tp.tv_sec == tdest.tv_sec) && (tp.tv_usec < tdest.tv_usec)))
- {
- // calculate new peek time
- us = nus - bl_tv2double(&tp);
-
- // check if input key is system break key.
- if (bl_peekbreak(us))
- return lua_yield(L, 0);
-
- // check time
- gettimeofday(&tp, NULL);
- }
- }
-#endif // !_WIN32
-
- return 0;
-}
-
-BLAPI_PROTO
-bl_kball(lua_State *L)
-{
- // first, sleep by given seconds
- int r = 0, oldr = 0, i = 0;
-
- r = bl_sleep(L);
- if (blrt.abort)
- return r;
-
- // pop all arguments
- lua_pop(L, lua_gettop(L));
-
-
-#ifdef _WIN32
- while (peekch(0))
- {
- bl_k2s(L, igetch());
- i++;
- }
-#else
- // next, collect all input and return.
- if (num_in_buf() < 1)
- return 0;
-
- oldr = num_in_buf() +1;
- i = 0;
-
- while ( i < LUA_MINSTACK &&
- (r = num_in_buf()) > 0 && oldr > r)
- {
- oldr = r;
- bl_k2s(L, igetch());
- i++;
- }
-#endif
-
- return i;
-}
-
-
-BLAPI_PROTO
-bl_pause(lua_State* L)
-{
- int n = lua_gettop(L);
- const char *s = NULL;
- if (n > 0)
- s = lua_tostring(L, 1);
-
- n = vmsg(s);
- if (n == BLCONF_BREAK_KEY)
- {
- drop_input();
- blrt.abort = 1;
- return lua_yield(L, 0);
- }
- bl_k2s(L, n);
- return 1;
-}
-
-BLAPI_PROTO
-bl_title(lua_State* L)
-{
- int n = lua_gettop(L);
- const char *s = NULL;
- if (n > 0)
- s = lua_tostring(L, 1);
- if (s == NULL)
- return 0;
-
- stand_title(s);
- return 0;
-}
-
-BLAPI_PROTO
-bl_ansi_color(lua_State *L)
-{
- char buf[PATHLEN] = ESC_STR "[";
- char *p = buf + strlen(buf);
- int i = 1;
- int n = lua_gettop(L);
- if (n >= 10) n = 10;
- for (i = 1; i <= n; i++)
- {
- if (i > 1) *p++ = ';';
- sprintf(p, "%d", (int)lua_tointeger(L, i));
- p += strlen(p);
- }
- *p++ = 'm';
- *p = 0;
- lua_pushstring(L, buf);
- return 1;
-}
-
-BLAPI_PROTO
-bl_strip_ansi(lua_State *L)
-{
- int n = lua_gettop(L);
- const char *s = NULL;
- char *s2 = NULL;
- size_t os2 = 0;
-
- if (n < 1 || (s = lua_tostring(L, 1)) == NULL ||
- *s == 0)
- {
- lua_pushstring(L, "");
- return 1;
- }
-
- os2 = strlen(s)+1;
- s2 = (char*) lua_newuserdata(L, os2);
- strip_ansi(s2, s, STRIP_ALL);
- lua_pushstring(L, s2);
- lua_remove(L, -2);
- return 1;
-}
-
-BLAPI_PROTO
-bl_attrset(lua_State *L)
-{
- char buf[PATHLEN] = ESC_STR "[";
- char *p = buf + strlen(buf);
- int i = 1;
- int n = lua_gettop(L);
- if (n == 0)
- outs(ANSI_RESET);
- for (i = 1; i <= n; i++)
- {
- sprintf(p, "%dm",(int)lua_tointeger(L, i));
- outs(buf);
- }
- return 0;
-}
-
-BLAPI_PROTO
-bl_time(lua_State *L)
-{
- syncnow();
- lua_pushinteger(L, now);
- return 1;
-}
-
-BLAPI_PROTO
-bl_ctime(lua_State *L)
-{
- syncnow();
- lua_pushstring(L, ctime4(&now));
- return 1;
-}
-
-BLAPI_PROTO
-bl_clock(lua_State *L)
-{
- double d = 0;
-
-#ifdef _WIN32
-
- // XXX this is a fast hack because we don't want to do 64bit calculation.
- SYSTEMTIME st;
- GetSystemTime(&st);
- syncnow();
- // XXX the may be some latency between our GetSystemTime and syncnow.
- // So build again the "second" part.
- d = (int)((now / 60) * 60);
- d += st.wSecond;
- d += (st.wMilliseconds / 1000.0f);
-
-#else // !_WIN32
-
- struct timeval tp;
- gettimeofday(&tp, NULL);
- d = bl_tv2double(&tp);
-
-#endif // !_WIN32
-
- lua_pushnumber(L, d);
- return 1;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// BBS-Lua Storage System
-//////////////////////////////////////////////////////////////////////////
-static int
-bls_getcat(const char *s)
-{
- if (!s || !*s)
- return BLS_INVALID;
- if (strcmp(s, BLSCONF_GLOBAL_VAL) == 0)
- return BLS_GLOBAL;
- else if (strcmp(s, BLSCONF_USER_VAL) == 0)
- return BLS_USER;
- return BLS_INVALID;
-}
-
-static int
-bls_getlimit(const char *p)
-{
- switch(bls_getcat(p))
- {
- case BLS_GLOBAL:
- return BLSCONF_GMAXSIZE;
- case BLS_USER:
- return BLSCONF_UMAXSIZE;
- }
- return 0;
-}
-
-static int
-bls_setfn(char *fn, size_t sz, const char *p)
-{
- *fn = 0;
- switch(bls_getcat(p))
- {
- case BLS_GLOBAL:
- snprintf(fn, sz, "%s/" BLSCONF_PREFIX "U%08x",
- BLSCONF_GPATH, blrt.storename);
- return 1;
-
- case BLS_USER:
- setuserfile(fn, BLSCONF_UPATH);
- mkdir(fn, 0755);
- assert(strlen(fn) +8 <= sz);
- snprintf(fn + strlen(fn),
- sz - strlen(fn),
- "/" BLSCONF_PREFIX "G%08x", blrt.storename);
- return 1;
- }
- return 0;
-}
-
-BLAPI_PROTO
-bls_iolimit(lua_State *L)
-{
- lua_pushinteger(L, BLSCONF_MAXIO);
- return 1;
-}
-
-BLAPI_PROTO
-bls_limit(lua_State *L)
-{
- int n = lua_gettop(L);
- const char *s = NULL;
- if (n > 0)
- s = lua_tostring(L, 1);
- lua_pushinteger(L, bls_getlimit(s));
- return 1;
-}
-
-BLAPI_PROTO
-bls_load(lua_State *L)
-{
- int n = lua_gettop(L);
- const char *cat = NULL;
- char fn[PATHLEN];
-
- if (blrt.iocounter >= BLSCONF_MAXIO)
- {
- lua_pushnil(L);
- return 1;
- }
-
- if (n != 1)
- {
- lua_pushnil(L);
- return 1;
- }
- cat = lua_tostring(L, 1); // category
- if (!cat)
- {
- lua_pushnil(L);
- return 1;
- }
-
- blrt.iocounter++;
- // read file!
- if (bls_setfn(fn, sizeof(fn), cat))
- {
- int fd = open(fn, O_RDONLY);
- if (fd >= 0)
- {
- char buf[2048];
- luaL_Buffer b;
-
- luaL_buffinit(L, &b);
- while ((n = read(fd, buf, sizeof(buf))) > 0)
- luaL_addlstring(&b, buf, n);
- close(fd);
- luaL_pushresult(&b);
- } else {
- lua_pushnil(L);
- }
- } else {
- lua_pushnil(L);
- }
- return 1;
-}
-
-BLAPI_PROTO
-bls_save(lua_State *L)
-{
- int n = lua_gettop(L), fd = -1;
- int limit = 0, slen = 0;
- const char *s = NULL, *cat = NULL;
- char fn[PATHLEN] = "", ret = 0;
-
- if (blrt.iocounter >= BLSCONF_MAXIO)
- {
- lua_pushboolean(L, 0);
- return 1;
- }
-
- if (n != 2) { lua_pushboolean(L, 0); return 1; }
-
- cat = lua_tostring(L, 1); // category
- s = lua_tostring(L, 2); // data
- limit = bls_getlimit(cat);
-
- if (!cat || !s || limit < 1)
- {
- lua_pushboolean(L, 0);
- return 1;
- }
-
- slen = lua_objlen(L, 2);
- if (slen >= limit) slen = limit;
-
- blrt.iocounter++;
- // write file!
- if (bls_setfn(fn, sizeof(fn), cat))
- {
- fd = open(fn, O_WRONLY|O_CREAT, 0644);
- if (fd >= 0)
- {
- write(fd, s, slen);
- close(fd);
- ret = 1;
- }
- }
-
- lua_pushboolean(L, ret);
- return 1;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// BBSLUA LIBRARY
-//////////////////////////////////////////////////////////////////////////
-
-static const struct luaL_reg lib_bbslua [] = {
- /* curses output */
- { "getyx", bl_getyx },
- { "getmaxyx", bl_getmaxyx },
- { "move", bl_move },
- { "moverel", bl_moverel },
- { "clear", bl_clear },
- { "clrtoeol", bl_clrtoeol },
- { "clrtobot", bl_clrtobot },
- { "refresh", bl_refresh },
- { "addstr", bl_addstr },
- { "outs", bl_addstr },
- { "print", bl_print },
- /* input */
- { "getch", bl_getch },
- { "getdata", bl_getstr },
- { "getstr", bl_getstr },
- { "kbhit", bl_kbhit },
- { "kbreset", bl_kbreset },
- { "kball", bl_kball },
- /* advanced output */
- { "rect", bl_rect },
- /* BBS utilities */
- { "pause", bl_pause },
- { "title", bl_title },
- /* time */
- { "time", bl_time },
- { "now", bl_time },
- { "clock", bl_clock },
- { "ctime", bl_ctime },
- { "sleep", bl_sleep },
- /* ANSI helpers */
- { "ANSI_COLOR", bl_ansi_color },
- { "color", bl_attrset },
- { "attrset", bl_attrset },
- { "strip_ansi", bl_strip_ansi },
- { NULL, NULL},
-};
-
-static const struct luaL_reg lib_store [] = {
- { "load", bls_load },
- { "save", bls_save },
- { "limit", bls_limit },
- { "iolimit", bls_iolimit },
- { NULL, NULL},
-};
-
-// non-standard modules in bbsluaext.c
-LUALIB_API int luaopen_bit (lua_State *L);
-
-static const luaL_Reg bbslualibs[] = {
- // standard modules
- {"", luaopen_base},
-
- // {LUA_LOADLIBNAME, luaopen_package},
- {LUA_TABLIBNAME, luaopen_table},
- // {LUA_IOLIBNAME, luaopen_io},
- // {LUA_OSLIBNAME, luaopen_os},
- {LUA_STRLIBNAME, luaopen_string},
- {LUA_MATHLIBNAME, luaopen_math},
- // {LUA_DBLIBNAME, luaopen_debug},
-
- // bbslua-ext modules
- {"bit", luaopen_bit},
-
- {NULL, NULL}
-};
-
-
-LUALIB_API void bbsluaL_openlibs (lua_State *L) {
- const luaL_Reg *lib = bbslualibs;
- for (; lib->func; lib++) {
- lua_pushcfunction(L, lib->func);
- lua_pushstring(L, lib->name);
- lua_call(L, 1, 0);
- }
-}
-
-
-// Constant registration
-
-typedef struct bbsluaL_RegStr {
- const char *name;
- const char *val;
-} bbsluaL_RegStr;
-
-typedef struct bbsluaL_RegNum {
- const char *name;
- lua_Number val;
-} bbsluaL_RegNum;
-
-static const bbsluaL_RegStr bbsluaStrs[] = {
- {"ESC", ESC_STR},
- {"ANSI_RESET", ANSI_RESET},
- {"sitename", BBSNAME},
- {NULL, NULL},
-};
-
-static const bbsluaL_RegNum bbsluaNums[] = {
- {"interface", BBSLUA_INTERFACE_VER},
- {NULL, 0},
-};
-
-static void
-bbsluaRegConst(lua_State *L)
-{
- int i = 0;
-
- // unbind unsafe API
- lua_pushnil(L); lua_setglobal(L, "dofile");
- lua_pushnil(L); lua_setglobal(L, "loadfile");
-
- // global
- lua_pushcfunction(L, bl_print);
- lua_setglobal(L, "print");
-
- // bbs.*
- lua_getglobal(L, "bbs");
- for (i = 0; bbsluaStrs[i].name; i++)
- {
- lua_pushstring(L, bbsluaStrs[i].val);
- lua_setfield(L, -2, bbsluaStrs[i].name);
- }
-
- for (i = 0; bbsluaNums[i].name; i++)
- {
- lua_pushnumber(L, bbsluaNums[i].val);
- lua_setfield(L, -2, bbsluaNums[i].name);
- }
- // dynamic info
- lua_pushstring(L, BLCONF_CURRENT_USERID);
- lua_setfield(L, -2, "userid");
- lua_pushstring(L, BLCONF_CURRENT_USERNICK);
- lua_setfield(L, -2, "usernick");
-
- lua_pop(L, 1);
-
-#ifdef BLSCONF_ENABLED
- // store.*
- lua_getglobal(L, "store");
- lua_pushstring(L, BLSCONF_USER_VAL);
- lua_setfield(L, -2, "USER");
- lua_pushstring(L, BLSCONF_GLOBAL_VAL);
- lua_setfield(L, -2, "GLOBAL");
- lua_pop(L, 1);
-#endif // BLSCONF_ENABLED
-}
-
-//////////////////////////////////////////////////////////////////////////
-// BBSLUA ENGINE UTILITIES
-//////////////////////////////////////////////////////////////////////////
-
-static void
-bbsluaHook(lua_State *L, lua_Debug* ar)
-{
- // vmsg("bbslua HOOK!");
- if (blrt.abort)
- {
- drop_input();
- lua_yield(L, 0);
- return;
- }
-
- if (ar->event != LUA_HOOKCOUNT)
- return;
-#ifdef BBSLUA_USAGE
- bbslua_count += BLCONF_EXEC_COUNT;
-#endif
-
- // now, peek and check
- if (input_isfull())
- drop_input();
-
- // refresh();
-
- // check if input key is system break key.
- if (bl_peekbreak(BLCONF_PEEK_TIME))
- {
- lua_yield(L, 0);
- return;
- }
-}
-
-static char *
-bbslua_attach(const char *fpath, size_t *plen)
-{
- char *buf = NULL;
-
-#ifdef BLCONF_MMAP_ATTACH
- struct stat st;
- int fd = open(fpath, O_RDONLY);
-
- *plen = 0;
-
- if (fd < 0) return buf;
- if (fstat(fd, &st) || ((*plen = st.st_size) < 1) || S_ISDIR(st.st_mode))
- {
- close(fd);
- return buf;
- }
- *plen = *plen +1;
-
- buf = mmap(NULL, *plen, PROT_READ, MAP_SHARED, fd, 0);
- close(fd);
-
- if (buf == NULL || buf == MAP_FAILED)
- {
- *plen = 0;
- return NULL;
- }
- madvise(buf, *plen, MADV_SEQUENTIAL);
-
-#else // !BLCONF_MMAP_ATTACH
-
- FILE *fp = fopen(fpath, "rt");
- *plen = 0;
- if (!fp)
- return NULL;
- fseek(fp, 0, SEEK_END);
- *plen = ftell(fp);
- buf = (char*) malloc (*plen);
- rewind(fp);
- fread(buf, *plen, 1, fp);
-
-#endif // !BLCONF_MMAP_ATTACH
-
- return buf;
-}
-
-static void
-bbslua_detach(char *p, int len)
-{
-#ifdef BLCONF_MMAP_ATTACH
- munmap(p, len);
-#else // !BLCONF_MMAP_ATTACH
- free(p);
-#endif // !BLCONF_MMAP_ATTACH
-}
-
-int
-bbslua_isHeader(const char *ps, const char *pe)
-{
- int szsig = strlen(BBSLUA_SIGNATURE);
- if (ps + szsig > pe)
- return 0;
- if (strncmp(ps, BBSLUA_SIGNATURE, szsig) == 0)
- return 1;
- return 0;
-}
-
-static int
-bbslua_detect_range(char **pbs, char **pbe, int *lineshift)
-{
- int szsig = strlen(BBSLUA_SIGNATURE);
- char *bs, *be, *ps, *pe;
- int line = 0;
-
- bs = ps = *pbs;
- be = pe = *pbe;
-
- // find start
- while (ps + szsig < pe)
- {
- if (strncmp(ps, BBSLUA_SIGNATURE, szsig) == 0)
- break;
- // else, skip to next line
- while (ps + szsig < pe && *ps++ != '\n');
- line++;
- }
- *lineshift = line;
-
- if (!(ps + szsig < pe))
- return 0;
-
- *pbs = ps;
- *pbe = be;
-
- // find tail by SIGNATURE
- pe = ps + 1;
- while (pe + szsig < be)
- {
- if (strncmp(pe, BBSLUA_SIGNATURE, szsig) == 0)
- break;
- // else, skip to next line
- while (pe + szsig < be && *pe++ != '\n');
- }
-
- if (pe + szsig < be)
- {
- // found sig, end at such line.
- pe--;
- *pbe = pe;
- } else {
- // abort.
- *pbe = NULL;
- *pbs = NULL;
- return 0;
- }
-
- // prevent trailing zeros
- pe = *pbe;
- while (pe > ps && !*pe)
- pe--;
- *pbe = pe;
-
- return 1;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// BBSLUA TOC Processing
-//////////////////////////////////////////////////////////////////////////
-
-static const char *bbsluaTocTags[] =
-{
- "interface",
- "latestref",
-
- // BLCONF_PRINT_TOC_INDEX
- "title",
- "notes",
- "author",
- "version",
- "date",
- NULL
-};
-
-static const char *bbsluaTocPrompts[] =
-{
- "¬É­±ª©¥»",
- "³Ì·sª©¥»",
-
- // BLCONF_PRINT_TOC_INDEX
- "¦WºÙ",
- "»¡©ú",
- "§@ªÌ",
- "ª©¥»",
- "¤é´Á",
- NULL
-};
-
-int
-bbslua_load_TOC(lua_State *L, const char *bs, const char *be, char **ppc)
-{
- unsigned char *ps = NULL, *pe = NULL;
- int i = 0;
-
- lua_newtable(L);
- *ppc = NULL;
-
- while (bs < be)
- {
- // find stripped line start, end
- ps = pe = (unsigned char *) bs;
- while (pe < (unsigned char*)be && *pe != '\n' && *pe != '\r')
- pe ++;
- bs = (char*)pe+1;
- while (ps < pe && *ps <= ' ') ps++;
- while (pe > ps && *(pe-1) <= ' ') pe--;
- // at least "--"
- if (pe < ps+2)
- break;
- if (*ps++ != '-' || *ps++ != '-')
- break;
- while (ps < pe && *ps <= ' ') ps++;
- // empty entry?
- if (ps >= pe)
- continue;
- // find pattern
- for (i = 0; bbsluaTocTags[i]; i++)
- {
- int l = strlen(bbsluaTocTags[i]);
- if (ps + l > pe)
- continue;
- if (strncasecmp((char*)ps, bbsluaTocTags[i], l) != 0)
- continue;
- ps += l;
- // found matching pattern, now find value
- while (ps < pe && *ps <= ' ') ps++;
- if (ps >= pe || *ps++ != ':')
- break;
- while (ps < pe && *ps <= ' ') ps++;
- // finally, (ps, pe) is the value!
- if (ps >= pe)
- break;
-
- lua_pushlstring(L, (char*)ps, pe-ps);
-
- // accept only real floats for interface ([0])
- if (i == 0 && lua_tonumber(L, -1) <= 0)
- {
- lua_pop(L, 1);
- }
- else
- {
- lua_setfield(L, -2, bbsluaTocTags[i]);
- }
- break;
- }
- }
-
- if (ps >= (unsigned char*)bs && ps < (unsigned char*)be)
- *ppc = (char*)ps;
- lua_setglobal(L, "toc");
- return 0;
-}
-
-static void
-fullmsg(const char *s)
-{
- clrtoeol();
- prints("%-*.*s\n", t_columns-1, t_columns-1, s);
-}
-
-void
-bbslua_logo(lua_State *L)
-{
- int y, by = b_lines -1; // print - back from bottom
- int i = 0;
- double tocinterface = 0;
- int tocs = 0;
- char msg[STRLEN];
-
- // get toc information
- lua_getglobal(L, "toc");
- lua_getfield(L, -1, bbsluaTocTags[0]);
- tocinterface = lua_tonumber(L, -1); lua_pop(L, 1);
-
- // query print-able toc tags
- for (i = BLCONF_PRINT_TOC_INDEX; bbsluaTocTags[i]; i++)
- {
- lua_getfield(L, -1, bbsluaTocTags[i]);
- if (lua_tostring(L, -1))
- tocs++;
- lua_pop(L, 1);
- }
-
- // prepare logo window
- grayout(0, b_lines, GRAYOUT_DARK);
-
- // print compatibility test
- // now (by) is the base of new information
- if (tocinterface == 0)
- {
- by -= 4; y = by+2;
- move(y-1, 0);
- outs(ANSI_COLOR(0;31;47));
- fullmsg("");
- fullmsg(" ¡¶ ¦¹µ{¦¡¯Ê¤Ö¬Û®e©Ê¸ê°T¡A±z¥i¯àµLªk¥¿±`°õ¦æ");
- fullmsg(" ­Y°õ¦æ¥X²{¿ù»~¡A½Ð¦V­ì§@ªÌ¨ú±o·sª©");
- fullmsg("");
- }
- else if (tocinterface > BBSLUA_INTERFACE_VER)
- {
- by -= 4; y = by+2;
- move(y-1, 0);
- outs(ANSI_COLOR(0;1;37;41));
- fullmsg("");
- snprintf(msg, sizeof(msg),
- " ¡¶ ¦¹µ{¦¡¨Ï¥Î·sª©ªº BBS-Lua ³W®æ (%0.3f)¡A±z¥i¯àµLªk¥¿±`°õ¦æ",
- tocinterface);
- fullmsg(msg);
- fullmsg(" ­Y°õ¦æ¥X²{¿ù»~¡A«Øij±z­«·sµn¤J BBS «á¦A­«¸Õ");
- fullmsg("");
- }
- else if (tocinterface == BBSLUA_INTERFACE_VER)
- {
- // do nothing!
- }
- else
- {
- // should be comtaible
- // prints("¬Û®e (%.03f)", tocinterface);
- }
-
- // print toc, if any.
- if (tocs)
- {
- y = by - 1 - tocs;
- by = y-1;
-
- move(y, 0); outs(ANSI_COLOR(0;1;30;47));
- fullmsg("");
-
- // now try to print all TOC infos
- for (i = BLCONF_PRINT_TOC_INDEX; bbsluaTocTags[i]; i++)
- {
- lua_getfield(L, -1, bbsluaTocTags[i]);
- if (!lua_isstring(L, -1))
- {
- lua_pop(L, 1);
- continue;
- }
- move(++y, 0);
- snprintf(msg, sizeof(msg), " %s: %-.*s",
- bbsluaTocPrompts[i], STRLEN-12, lua_tostring(L, -1));
- msg[sizeof(msg)-1] = 0;
- fullmsg(msg);
- lua_pop(L, 1);
- }
- fullmsg("");
- }
-
- // print caption
- move(by-2, 0); outc('\n');
- outs(ANSI_COLOR(0;1;37;44));
- snprintf(msg, sizeof(msg),
- " ¡½ BBS-Lua %.03f (Build " __DATE__ " " __TIME__") ",
- (double)BBSLUA_INTERFACE_VER);
- fullmsg(msg);
-
- // system break key prompt
- {
- int sz = t_columns -1;
- const char
- *prompt1 = " ´£¿ô±z°õ¦æ¤¤ÀH®É¥i«ö ",
- *prompt2 = "[Ctrl-C]",
- *prompt3 = " ±j¨î¤¤Â_ BBS-Lua µ{¦¡";
- sz -= strlen(prompt1);
- sz -= strlen(prompt2);
- sz -= strlen(prompt3);
- outs(ANSI_COLOR(22;37)); outs(prompt1);
- outs(ANSI_COLOR(1;31)); outs(prompt2);
- outs(ANSI_COLOR(0;37;44));outs(prompt3);
- prints("%*s", sz, "");
- outs(ANSI_RESET);
- }
- lua_pop(L, 1);
-}
-
-//////////////////////////////////////////////////////////////////////////
-// BBSLUA Script Loader
-//////////////////////////////////////////////////////////////////////////
-
-typedef struct LoadS {
- const char *s;
- size_t size;
- int lineshift;
-} LoadS;
-
-static const char* bbslua_reader(lua_State *L, void *ud, size_t *size)
-{
- LoadS *ls = (LoadS *)ud;
- (void)L;
- if (ls->size == 0) return NULL;
- if (ls->lineshift > 0) {
- const char *linefeed = "\n";
- *size = 1;
- ls->lineshift--;
- return linefeed;
- }
- *size = ls->size;
- ls->size = 0;
- return ls->s;
-}
-
-static int bbslua_loadbuffer (lua_State *L, const char *buff, size_t size,
- const char *name, int lineshift) {
- LoadS ls;
- ls.s = buff;
- ls.size = size;
- ls.lineshift = lineshift;
- return lua_load(L, bbslua_reader, &ls, name);
-}
-
-typedef struct AllocData {
- size_t alloc_size;
- size_t max_alloc_size;
- size_t alloc_limit;
-} AllocData;
-
-static void alloc_init(AllocData *ad)
-{
- memset(ad, 0, sizeof(*ad));
- // real limit is not determined yet, just assign a big value
- ad->alloc_limit = 20*1048576;
-}
-
-static void *allocf (void *ud, void *ptr, size_t osize, size_t nsize) {
- /* TODO use our own allocator, for better memory control, avoid fragment and leak */
- AllocData *ad = (AllocData*)ud;
-
- if (ad->alloc_size + nsize - osize > ad->alloc_limit) {
- return NULL;
- }
- ad->alloc_size += nsize - osize;
- if (ad->alloc_size > ad->max_alloc_size) {
- ad->max_alloc_size = ad->alloc_size;
- }
- if (nsize == 0) {
- free(ptr);
- return NULL;
- }
- else
- return realloc(ptr, nsize);
-}
-static int panic (lua_State *L) {
- (void)L; /* to avoid warnings */
- fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n",
- lua_tostring(L, -1));
- return 0;
-}
-
-void bbslua_loadLatest(lua_State *L,
- char **pbs, char **pps, char **ppe, char **ppc, int *psz,
- int *plineshift, char *bfpath, const char **pfpath)
-{
- int r = 1; // max redirect for one article only.
-
- do {
- char *xbs = NULL, *xps = NULL, *xpe = NULL, *xpc = NULL;
- int xlineshift = 0;
- size_t xsz;
- const char *lastref = NULL;
- char loadnext = 0, isnewver = 0;
-
- // detect file
- xbs = bbslua_attach(bfpath, &xsz);
- if (!xbs)
- break;
-
- xps = xbs;
- xpe = xps + xsz;
-
- if(!bbslua_detect_range(&xps, &xpe, &xlineshift))
- {
- // not detected
- bbslua_detach(xbs, xsz);
- break;
- }
-
- // detect and verify TOC meta data
- lua_getglobal(L, "toc"); // stack 1
- if (lua_istable(L, -1))
- {
- const char *oref, *otitle, *nref, *ntitle;
- // load and verify tocinfo
- lua_getfield(L, -1, "latestref"); // stack 2
- oref = lua_tostring(L, -1);
- lua_getfield(L, -2, "title"); // stack 3
- otitle = lua_tostring(L, -1);
- bbslua_load_TOC(L, xps, xpe, &xpc);
- lua_getglobal(L, "toc"); // stack 4
- lua_getfield(L, -1, "latestref"); // stack 5
- nref = lua_tostring(L, -1);
- lua_getfield(L, -2, "title"); // stack 6
- ntitle = lua_tostring(L, -1);
-
- if (oref && nref && otitle && ntitle &&
- strcmp(oref, nref) == 0 &&
- strcmp(otitle, ntitle) == 0)
- isnewver = 1;
-
- // pop all
- lua_pop(L, 5); // stack = 1 (old toc)
- if (!isnewver)
- lua_setglobal(L, "toc");
- else
- lua_pop(L, 1);
- } else {
- lua_pop(L, 1);
- bbslua_load_TOC(L, xps, xpe, &xpc);
- }
-
- if (*pbs && !isnewver)
- {
- // different.
- bbslua_detach(xbs, xsz);
- break;
- }
-
- // now, apply current buffer
- if (*pbs)
- {
- bbslua_detach(*pbs, *psz);
- // XXX fpath=bfpath, supporting only one level redirection now.
- *pfpath = bfpath;
- }
- *pbs = xbs; *pps = xps; *ppe = xpe; *psz = xsz;
- *ppc = xpc;
- *plineshift = xlineshift;
-
-#ifdef AID_DISPLAYNAME
- // quick exit
- if (r <= 0)
- break;
-
- // LatestRef only works if system supports AID.
- // try to load next reference.
- lua_getglobal(L, "toc"); // stack 1
- lua_getfield(L, -1, "latestref"); // stack 2
- lastref = lua_tostring(L, -1);
-
- while (lastref && *lastref)
- {
- // try to load by AID
- char bn[IDLEN+1] = "";
- aidu_t aidu = 0;
- unsigned char *p = (unsigned char*)bn;
-
- if (*lastref == '#') lastref++;
- aidu = aidc2aidu((char*)lastref);
- if (aidu <= 0) break;
-
- while (*lastref > ' ') lastref ++; // lastref points to zero of space
- while (*lastref && *lastref <= ' ') lastref++; // lastref points to zero or board name
- if (*lastref == '(') lastref ++;
-
- if (!*lastref) break;
- strlcpy(bn, lastref, sizeof(bn));
- // truncate board name
- // (not_alnum(ch) && ch != '_' && ch != '-' && ch != '.')
- while (*p &&
- (isalnum(*p) || *p == '_' || *p == '-' || *p == '.')) p++;
- *p = 0;
- if (bn[0])
- {
- bfpath[0] = 0;
- setaidfile(bfpath, bn, aidu);
- }
-
- if (bfpath[0])
- loadnext = 1;
- break;
- }
- lua_pop(L, 2);
-
- if (loadnext) continue;
-#endif // AID_DISPLAYNAME
- break;
-
- } while (r-- > 0);
-}
-
-//////////////////////////////////////////////////////////////////////////
-// BBSLUA Hash
-//////////////////////////////////////////////////////////////////////////
-
-#if 0
-static int
-bbslua_hashWriter(lua_State *L, const void *p, size_t sz, void *ud)
-{
- Fnv32_t *phash = (Fnv32_t*) ud;
- *phash = fnv_32_buf(p, sz, *phash);
- return 0;
-}
-
-static Fnv32_t
-bbslua_f2hash(lua_State *L)
-{
- Fnv32_t fnvseed = FNV1_32_INIT;
- lua_dump(L, bbslua_hashWriter, &fnvseed);
- return fnvseed;
-}
-
-static Fnv32_t
-bbslua_str2hash(const char *str)
-{
- if (!str)
- return 0;
- return fnv_32_str(str, FNV1_32_INIT);
-}
-#endif
-
-static Fnv32_t
-bbslua_path2hash(const char *path)
-{
- Fnv32_t seed = FNV1_32_INIT;
- if (!path)
- return 0;
- if (path[0] != '/') // relative, append BBSHOME
- seed = fnv_32_str(BBSHOME "/", seed);
- return fnv_32_str(path, seed);
-}
-
-//////////////////////////////////////////////////////////////////////////
-// BBSLUA Main
-//////////////////////////////////////////////////////////////////////////
-
-int
-bbslua(const char *fpath)
-{
- int r = 0;
- lua_State *L;
- char *bs = NULL, *ps = NULL, *pe = NULL, *pc = NULL;
- char bfpath[PATHLEN] = "";
- int sz = 0;
- int lineshift = 0;
- AllocData ad;
-#ifdef BBSLUA_USAGE
- struct rusage rusage_begin, rusage_end;
- struct timeval lua_begintime, lua_endtime;
- gettimeofday(&lua_begintime, NULL);
- getrusage(0, &rusage_begin);
-#endif
-
-#ifdef UMODE_BBSLUA
- unsigned int prevmode = getutmpmode();
-#endif
-
- // re-entrant not supported!
- if (blrt.running)
- return 0;
-
- // initialize runtime
- BL_INIT_RUNTIME();
-
-#ifdef BBSLUA_USAGE
- bbslua_count = 0;
-#endif
-
- // init lua
- alloc_init(&ad);
- L = lua_newstate(allocf, &ad);
- if (!L)
- return 0;
- lua_atpanic(L, &panic);
-
- strlcpy(bfpath, fpath, sizeof(bfpath));
-
- // load file
- bbslua_loadLatest(L, &ps, &ps, &pe, &pc, &sz, &lineshift, bfpath, &fpath);
-
- if (!ps || !pe || ps >= pe)
- {
- if (bs)
- bbslua_detach(bs, sz);
- lua_close(L);
- vmsg("BBS-Lua ¸ü¤J¿ù»~: ¥¼§t BBS-Lua µ{¦¡");
- return 0;
- }
-
- // init library
- bbsluaL_openlibs(L);
- luaL_openlib(L, "bbs", lib_bbslua, 0);
-
-#ifdef BLSCONF_ENABLED
- luaL_openlib(L, "store", lib_store, 0);
-#endif // BLSCONF_ENABLED
-
- bbsluaRegConst(L);
-
- // load script
- r = bbslua_loadbuffer(L, ps, pe-ps, "BBS-Lua", lineshift);
-
- // build hash or store name
- blrt.storename = bbslua_path2hash(fpath);
- // vmsgf("BBS-Lua Hash: %08X", blrt.storename);
-
- // unmap
- bbslua_detach(bs, sz);
-
- if (r != 0)
- {
- const char *errmsg = lua_tostring(L, -1);
- lua_close(L);
- outs(ANSI_RESET);
- move(b_lines-3, 0); clrtobot();
- outs("\n");
- outs(errmsg);
- vmsg("BBS-Lua ¸ü¤J¿ù»~: ½Ð³qª¾§@ªÌ­×¥¿µ{¦¡½X¡C");
- return 0;
- }
-
-#ifdef UMODE_BBSLUA
- setutmpmode(UMODE_BBSLUA);
-#endif
-
- bbslua_logo(L);
- vmsgf("´£¿ô±z°õ¦æ¤¤ÀH®É¥i«ö [Ctrl-C] ±j¨î¤¤Â_ BBS-Lua µ{¦¡");
-
- // ready for running
- clear();
- blrt.running =1;
- lua_sethook(L, bbsluaHook, LUA_MASKCOUNT, BLCONF_EXEC_COUNT );
-
- refresh();
- // check is now done inside hook
- r = lua_resume(L, 0);
-
- // even if r == yield, let's abort - you cannot yield main thread.
-
- if (r != 0)
- {
- const char *errmsg = lua_tostring(L, -1);
- move(b_lines-3, 0); clrtobot();
- outs("\n");
- if (errmsg) outs(errmsg);
- }
-
- lua_close(L);
- blrt.running =0;
- drop_input();
-#ifdef BBSLUA_USAGE
- {
- double cputime;
- double load;
- double walltime;
- getrusage(0, &rusage_end);
- gettimeofday(&lua_endtime, NULL);
- cputime = bl_tv2double(&rusage_end.ru_utime) - bl_tv2double(&rusage_begin.ru_utime);
- walltime = bl_tv2double(&lua_endtime) - bl_tv2double(&lua_begintime);
- load = cputime / walltime;
- log_filef("log/bbslua.log", LOG_CREAT,
- "maxalloc=%d leak=%d op=%d cpu=%.3f Mop/s=%.1f load=%f file=%s\n",
- (int)ad.max_alloc_size, (int)ad.alloc_size,
- bbslua_count, cputime, bbslua_count / cputime / 1000000.0, load * 100,
- fpath);
- }
-#endif
-
- // grayout(0, b_lines, GRAYOUT_DARK);
- move(b_lines, 0); clrtoeol();
- vmsgf("BBS-Lua °õ¦æµ²§ô%s¡C",
- blrt.abort ? " (¨Ï¥ÎªÌ¤¤Â_)" : r ? " (µ{¦¡¿ù»~)" : "");
- BL_END_RUNTIME();
- clear();
-
-#ifdef UMODE_BBSLUA
- setutmpmode(prevmode);
-#endif
-
- return 0;
-}
-
-// vim:ts=4:sw=4:expandtab
diff --git a/mbbsd/bbsluaext.c b/mbbsd/bbsluaext.c
deleted file mode 100644
index ee3521ea..00000000
--- a/mbbsd/bbsluaext.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/* This file contains non-standard modules which
- * are fundamental in BBSLua framework.
- */
-
-/* Bitwise operations library */
-/* (c) Reuben Thomas 2000-2007 */
-/*
- bitlib release 24
- -----------------
- by Reuben Thomas <rrt@sc3d.org>
- http://luaforge.net/projects/bitlib
-
-
-bitlib is a C library for Lua 5.x that provides bitwise operations. It
-is copyright Reuben Thomas 2000-2007, and is released under the MIT
-license, like Lua (see http://www.lua.org/copyright.html; it's
-basically the same as the BSD license). There is no warranty.
-
-Please report bugs and make suggestions to the email address above, or
-use the LuaForge trackers.
-
-Thanks to John Passaniti for his bitwise operations library, some of
-whose ideas I used, to Shmuel Zeigerman for the test suite, to
-Thatcher Ulrich for portability fixes, and to John Stiles for a bug
-fix.
-*/
-
-#include <inttypes.h>
-#include <lauxlib.h>
-#include <lua.h>
-
-typedef int32_t Integer;
-typedef uint32_t UInteger;
-
-#define checkUInteger(L, n) ((UInteger)luaL_checknumber((L), (n)))
-
-#define TDYADIC(name, op, type1, type2) \
- static int bit_ ## name(lua_State* L) { \
- lua_pushnumber(L, (Integer)((type1)checkUInteger(L, 1) op (type2)checkUInteger(L, 2))); \
- return 1; \
- }
-
-#define MONADIC(name, op, type) \
- static int bit_ ## name(lua_State* L) { \
- lua_pushnumber(L, (Integer)(op (type)checkUInteger(L, 1))); \
- return 1; \
- }
-
-#define VARIADIC(name, op, type) \
- static int bit_ ## name(lua_State *L) { \
- int n = lua_gettop(L), i; \
- Integer w = (type)checkUInteger(L, 1); \
- for (i = 2; i <= n; i++) \
- w op (type)checkUInteger(L, i); \
- lua_pushnumber(L, (Integer)w); \
- return 1; \
- }
-
-MONADIC(cast, +, Integer)
-MONADIC(bnot, ~, Integer)
-VARIADIC(band, &=, Integer)
-VARIADIC(bor, |=, Integer)
-VARIADIC(bxor, ^=, Integer)
-TDYADIC(lshift, <<, Integer, UInteger)
-TDYADIC(rshift, >>, UInteger, UInteger)
-TDYADIC(arshift, >>, Integer, UInteger)
-
-static const struct luaL_reg bitlib[] = {
- {"cast", bit_cast},
- {"bnot", bit_bnot},
- {"band", bit_band},
- {"bor", bit_bor},
- {"bxor", bit_bxor},
- {"lshift", bit_lshift},
- {"rshift", bit_rshift},
- {"arshift", bit_arshift},
- {NULL, NULL}
-};
-
-LUALIB_API int luaopen_bit (lua_State *L) {
- luaL_openlib(L, "bit", bitlib, 0);
- return 1;
-}
diff --git a/mbbsd/board.c b/mbbsd/board.c
deleted file mode 100644
index f5cfe0de..00000000
--- a/mbbsd/board.c
+++ /dev/null
@@ -1,1960 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-/* personal board state
- * ¬Û¹ï©ó¬ÝªOªº attr (BRD_* in ../include/pttstruct.h),
- * ³o¨Ç¬O¥Î¦b user interface ªº flag */
-#define NBRD_FAV 1
-#define NBRD_BOARD 2
-#define NBRD_LINE 4
-#define NBRD_FOLDER 8
-#define NBRD_TAG 16
-#define NBRD_UNREAD 32
-#define NBRD_SYMBOLIC 64
-
-#define TITLE_MATCH(bptr, key) ((key)[0] && !strcasestr((bptr)->title, (key)))
-
-
-#define B_TOTAL(bptr) (SHM->total[(bptr)->bid - 1])
-#define B_LASTPOSTTIME(bptr) (SHM->lastposttime[(bptr)->bid - 1])
-#define B_BH(bptr) (&bcache[(bptr)->bid - 1])
-
-#define HasFavEditPerm() HasUserPerm(PERM_BASIC)
-
-typedef struct {
- int bid;
- unsigned char myattr;
-} __attribute__ ((packed)) boardstat_t;
-
-/**
- * class_bid ªº·N¸q
- * class_bid < 0 ¼öªù¬ÝªO
- * class_bid = 0 §Úªº³Ì·R
- * class_bid = 1 ¤ÀÃþ¬ÝªO
- * class_bid > 1 ¨ä¥L¥Ø¿ý
- */
-#define IN_HOTBOARD() (class_bid < 0)
-#define IN_FAVORITE() (class_bid == 0)
-#define IN_CLASSROOT() (class_bid == 1)
-#define IN_SUBCLASS() (class_bid > 1)
-#define IN_CLASS() (class_bid > 0)
-static int class_bid = 0;
-
-static int nbrdsize = 0;
-static boardstat_t *nbrd = NULL;
-static char choose_board_depth = 0;
-static int brdnum;
-static char yank_flag = 1;
-
-static time4_t last_save_fav_and_brc;
-
-/* These are all the states yank_flag may be. */
-// XXX IS_LISTING_FAV() does not mean we are in favorite.
-// That is controlled by IN_FAVORITE().
-#define LIST_FAV() (yank_flag = 0)
-#define LIST_BRD() (yank_flag = 1)
-#define IS_LISTING_FAV() (yank_flag == 0)
-#define IS_LISTING_BRD() (yank_flag == 1)
-
-inline int getbid(const boardheader_t *fh)
-{
- return (fh - bcache);
-}
-inline boardheader_t *getparent(const boardheader_t *fh)
-{
- if(fh->parent>0)
- return getbcache(fh->parent);
- else
- return NULL;
-}
-
-/**
- * @param[in] boardname board name, case insensitive
- * @return 0 if success
- * -1 if not found
- * -2 permission denied
- * -3 error
- * @note enter board:
- * 1. setup brc (currbid, currboard, currbrdattr)
- * 2. set currbid, currBM, currmode, currdirect
- * 3. utmp brc_id
- */
-int enter_board(const char *boardname)
-{
- boardheader_t *bh;
- int bid;
- char bname[IDLEN+1];
- char bpath[60];
- struct stat st;
-
- /* checking ... */
- if (boardname[0] == '\0' || !(bid = getbnum(boardname)))
- return -1;
- assert(0<=bid-1 && bid-1<MAX_BOARD);
- bh = getbcache(bid);
- if (!HasBoardPerm(bh))
- return -2;
-
- strlcpy(bname, bh->brdname, sizeof(bname));
- if (bname[0] == '\0')
- return -3;
-
- setbpath(bpath, bname);
- if (stat(bpath, &st) == -1) {
- return -3;
- }
-
- /* really enter board */
- brc_update();
- brc_initial_board(bname);
- setutmpbid(currbid);
-
- set_board();
- setbdir(currdirect, currboard);
- curredit &= ~EDIT_MAIL;
-
- return 0;
-}
-
-
-void imovefav(int old)
-{
- char buf[5];
- int new;
-
- getdata(b_lines - 1, 0, "½Ð¿é¤J·s¦¸§Ç:", buf, sizeof(buf), DOECHO);
- new = atoi(buf) - 1;
- if (new < 0 || brdnum <= new){
- vmsg("¿é¤J½d³ò¦³»~!");
- return;
- }
- move_in_current_folder(old, new);
-}
-
-void
-init_brdbuf(void)
-{
- if (brc_initialize())
- return;
-}
-
-void
-save_brdbuf(void)
-{
- fav_save();
- fav_free();
-}
-
-int
-HasBoardPerm(boardheader_t *bptr)
-{
- register int level, brdattr;
-
- level = bptr->level;
- brdattr = bptr->brdattr;
-
- if (HasUserPerm(PERM_SYSOP))
- return 1;
-
- /* ªO¥D */
- if( is_BM_cache(bptr - bcache + 1) ) /* XXXbid */
- return 1;
-
- /* ¯¦±K¬ÝªO¡G®Ö¹ï­º®uªO¥Dªº¦n¤Í¦W³æ */
- if (brdattr & BRD_HIDE) { /* ÁôÂÃ */
- if (!is_hidden_board_friend((int)(bptr - bcache) + 1, currutmp->uid)) {
- if (brdattr & BRD_POSTMASK)
- return 0;
- else
- return 2;
- } else
- return 1;
- }
-
- /* ¤Q¤K¸T¬ÝªO */
- if( (brdattr & BRD_OVER18) && !over18 )
- return 0;
-
- /* ­­¨î¾\ŪÅv­­ */
- if (level && !(brdattr & BRD_POSTMASK) && !HasUserPerm(level))
- return 0;
-
- return 1;
-}
-
-// board configuration utilities
-
-static int
-b_post_note(void)
-{
- char buf[200], yn[3];
-
- // if(!(currmode & MODE_BOARD)) return DONOTHING;
- stand_title("¦Û­qª`·N¨Æ¶µ");
-
- setbfile(buf, currboard, FN_POST_NOTE);
- move(b_lines-2, 0); clrtobot();
-
- if (more(buf, NA) == -1)
- more("etc/" FN_POST_NOTE, NA);
- getdata(b_lines - 2, 0, "¬O§_­n¥Î¦Û­qµo¤åª`·N¨Æ¶µ? [y/N]",
- yn, sizeof(yn), LCECHO);
- if (yn[0] == 'y')
- vedit(buf, NA, NULL);
- else
- unlink(buf);
-
- setbfile(buf, currboard, FN_POST_BID);
- if (more(buf, NA) == -1)
- more("etc/" FN_POST_BID, NA);
- getdata(b_lines - 2, 0, "¬O§_­n¥Î¦Û­qÄv¼Ð¤å³¹ª`·N¨Æ¶µ? [y/N]",
- yn, sizeof(yn), LCECHO);
- if (yn[0] == 'y')
- vedit(buf, NA, NULL);
- else
- unlink(buf);
-
- return FULLUPDATE;
-}
-
-static int
-b_posttype()
-{
- boardheader_t *bp;
- int i, aborted;
- char filepath[PATHLEN], genbuf[60], title[5], posttype_f, posttype[33]="";
-
- // if(!(currmode & MODE_BOARD)) return DONOTHING;
-
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- bp = getbcache(currbid);
- stand_title("³]©w¤å³¹Ãþ§O");
-
- move(2,0);
- clrtobot();
- posttype_f = bp->posttype_f;
- for( i = 0 ; i < 8 ; ++i ){
- move(2+i,0);
- outs("¤å³¹ºØÃþ: ");
- strlcpy(genbuf, bp->posttype + i * 4, 5);
- sprintf(title, "%d.", i + 1);
- if( !getdata_buf(2+i, 11, title, genbuf, 5, DOECHO) )
- break;
- sprintf(posttype + i * 4, "%-4.4s", genbuf);
- if( posttype_f & (1<<i) ){
- if( getdata(2+i, 20, "³]©w½d¥»®æ¦¡¡H(Y/n)", genbuf, 3, LCECHO) &&
- genbuf[0]=='n' ){
- posttype_f &= ~(1<<i);
- continue;
- }
- }
- else if ( !getdata(2+i, 20, "³]©w½d¥»®æ¦¡¡H(y/N)", genbuf, 3, LCECHO) ||
- genbuf[0] != 'y' )
- continue;
-
- setbnfile(filepath, bp->brdname, "postsample", i);
- aborted = vedit(filepath, NA, NULL);
- if (aborted == -1) {
- clear();
- posttype_f &= ~(1<<i);
- continue;
- }
- posttype_f |= (1<<i);
- }
- bp->posttype_f = posttype_f;
- strlcpy(bp->posttype, posttype, sizeof(bp->posttype)); /* ³oÃäÀ³¸Ó­n¨¾race condition */
-
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- substitute_record(fn_board, bp, sizeof(boardheader_t), currbid);
- return FULLUPDATE;
-}
-
-// integrated board config
-int
-b_config(void)
-{
- boardheader_t *bp=NULL;
- int touched = 0, finished = 0;
- bp = getbcache(currbid);
- int i = 0, attr = 0, ipostres;
- char isBM = (currmode & MODE_BOARD) || HasUserPerm(PERM_SYSOP);
-
-#define LNBOARDINFO (17)
-#define LNPOSTRES (12)
-#define COLPOSTRES (50)
-
- int ytitle = b_lines - LNBOARDINFO;
-
-#ifdef OLDRECOMMEND
- ytitle ++;
-#endif // OLDRECOMMEND
-
- grayout(0, ytitle-2, GRAYOUT_DARK);
-
- // available hotkeys yet:
- // a b d j k p q z
- // 2 3 4 5 6 7 9
- // better not: l 0
-
- while(!finished) {
- move(ytitle-1, 0); clrtobot();
- // outs(MSG_SEPERATOR); // deprecated by grayout
- move(ytitle, 0);
- outs(ANSI_COLOR(7) " " ); outs(bp->brdname); outs(" ¬ÝªO³]©w");
- i = t_columns - strlen(bp->brdname) - strlen(" ¬ÝªO³]©w") - 2;
- for (; i>0; i--)
- outc(' ');
- outs(ANSI_RESET);
-
- move(ytitle +2, 0);
- clrtobot();
-
- prints(" ¤¤¤å±Ô­z: %s\n", bp->title);
- prints(" ªO¥D¦W³æ: %s\n", (bp->BM[0] > ' ')? bp->BM : "(µL)");
-
- outs(" \n"); // at least one character, for move_ansi.
-
- prints( " " ANSI_COLOR(1;36) "h" ANSI_RESET
- " - ¤½¶}ª¬ºA(¬O§_Áô§Î): %s " ANSI_RESET "\n",
- (bp->brdattr & BRD_HIDE) ?
- ANSI_COLOR(1)"Áô§Î":"¤½¶}");
-
- prints( " " ANSI_COLOR(1;36) "g" ANSI_RESET
- " - ÁôªO®É %s ¶i¤J¤Q¤j±Æ¦æº]" ANSI_RESET "\n",
- (bp->brdattr & BRD_BMCOUNT) ?
- ANSI_COLOR(1)"¥i¥H" ANSI_RESET:
- "¤£¥i");
-
- prints( " " ANSI_COLOR(1;36) "r" ANSI_RESET
- " - %s " ANSI_RESET "±ÀÂˤ峹\n",
- (bp->brdattr & BRD_NORECOMMEND) ?
- ANSI_COLOR(31)"¤£¥i":"¥i¥H");
-
-#ifndef OLDRECOMMEND
- prints( " " ANSI_COLOR(1;36) "b" ANSI_RESET
- " - %s " ANSI_RESET "¼N¤å\n",
- ((bp->brdattr & BRD_NORECOMMEND) || (bp->brdattr & BRD_NOBOO))
- ? ANSI_COLOR(1)"¤£¥i":"¥i¥H");
-#endif
- {
- int d = 0;
-
- if(bp->brdattr & BRD_NORECOMMEND)
- {
- d = -1;
- } else {
- if ((bp->brdattr & BRD_NOFASTRECMD) &&
- (bp->fastrecommend_pause > 0))
- d = bp->fastrecommend_pause;
- }
-
- prints( " " ANSI_COLOR(1;36) "f" ANSI_RESET
- " - %s " ANSI_RESET "§Ö³t³s±À¤å³¹",
- d != 0 ?
- ANSI_COLOR(1)"­­¨î": "¥i¥H");
- if(d > 0)
- prints(", ³Ì§C¶¡¹j®É¶¡: %d ¬í", d);
- outs("\n");
- }
-
- prints( " " ANSI_COLOR(1;36) "i" ANSI_RESET
- " - ±À¤å®É %s" ANSI_RESET " °O¿ý¨Ó·½ IP\n",
- (bp->brdattr & BRD_IPLOGRECMD) ?
- ANSI_COLOR(1)"­n":"¤£¥Î");
-
-#ifdef USE_AUTOCPLOG
- prints( " " ANSI_COLOR(1;36) "x" ANSI_RESET
- " - Âà¿ý¤å³¹ %s " ANSI_RESET "¦Û°Ê°O¿ý¡A¥B %s "
- ANSI_RESET "µo¤åÅv­­\n",
- (bp->brdattr & BRD_CPLOG) ?
- ANSI_COLOR(1)"·|" : "¤£·|" ,
- (bp->brdattr & BRD_CPLOG) ?
- ANSI_COLOR(1)"»Ý­n" : "¤£»Ý"
- );
-#endif
-
- prints( " " ANSI_COLOR(1;36) "L" ANSI_RESET
- " - ­Y¦³Âà«H«hµo¤å®É¹w³] %s " ANSI_RESET "\n",
- (bp->brdattr & BRD_LOCALSAVE) ?
- "¯¸¤º¦sÀÉ(¤£Âà¥X)" : ANSI_COLOR(1)"¯¸»Ú¦sÀÉ(Âà¥X)" );
-
- // use '8' instead of '1', to prevent 'l'/'1' confusion
- prints( " " ANSI_COLOR(1;36) "8" ANSI_RESET
- " - ¥¼º¡¤Q¤K·³ %s " ANSI_RESET
- "¶i¤J\n", (bp->brdattr & BRD_OVER18) ?
- ANSI_COLOR(1) "¤£¥i¥H" : "¥i¥H" );
-
- prints( " " ANSI_COLOR(1;36) "y" ANSI_RESET
- " - %s" ANSI_RESET
- " ¦^¤å\n",
- (bp->brdattr & BRD_NOREPLY) ?
- ANSI_COLOR(1)"¤£¥i¥H" : "¥i¥H" );
-
- prints( " " ANSI_COLOR(1;36) "e" ANSI_RESET
- " - µo¤åÅv­­: %s" ANSI_RESET "\n",
- (bp->brdattr & BRD_RESTRICTEDPOST) ?
- ANSI_COLOR(1)"¥u¦³ªO¤Í¤~¥iµo¤å" : "µL¯S§O³]©w" );
-
- ipostres = b_lines - LNPOSTRES;
- move_ansi(ipostres++, COLPOSTRES-2);
-
- if (CheckPostPerm() && CheckPostRestriction(currbid))
- outs(ANSI_COLOR(1;32));
- else
- outs(ANSI_COLOR(1;31));
- outs("µo¤å»P±À¤å­­¨î" ANSI_RESET);
-
-#define POSTRESTRICTION(msg,utag) \
- prints(msg, attr ? ANSI_COLOR(1) : "", i, attr ? ANSI_RESET : "")
-
- if (bp->post_limit_logins)
- {
- move_ansi(ipostres++, COLPOSTRES);
- i = (int)bp->post_limit_logins * 10;
- attr = (cuser.numlogins < i) ? 1 : 0;
- if (attr) outs(ANSI_COLOR(31));
- prints("¤W¯¸¦¸¼Æ %d ¦¸¥H¤W", i);
- if (attr) outs(ANSI_RESET);
- }
-
- if (bp->post_limit_posts)
- {
- move_ansi(ipostres++, COLPOSTRES);
- i = (int)bp->post_limit_posts * 10;
- attr = (cuser.numposts < i) ? 1 : 0;
- if (attr) outs(ANSI_COLOR(31));
- prints("¤å³¹½g¼Æ %d ½g¥H¤W", i);
- if (attr) outs(ANSI_RESET);
- }
-
- if (bp->post_limit_regtime)
- {
- move_ansi(ipostres++, COLPOSTRES);
- i = bp->post_limit_regtime;
- attr = (cuser.firstlogin >
- (now - (time4_t)bp->post_limit_regtime * 2592000)) ? 1 : 0;
- if (attr) outs(ANSI_COLOR(31));
- prints("µù¥U®É¶¡ %d ­Ó¤ë¥H¤W",i);
- if (attr) outs(ANSI_RESET);
- }
-
- // if (bp->post_limit_badpost)
- {
- move_ansi(ipostres++, COLPOSTRES);
- i = 255 - bp->post_limit_badpost;
- attr = (cuser.badpost > i) ? 1 : 0;
- if (attr) outs(ANSI_COLOR(31));
- prints("¦H¤å½g¼Æ %d ½g¥H¤U", i);
- if (attr) outs(ANSI_RESET);
- }
-
- if (!CheckPostPerm())
- {
- const char *msg = postperm_msg(bp->brdname);
- if (msg) // some reasons
- {
- move_ansi(ipostres++, COLPOSTRES);
- outs(ANSI_COLOR(1;31));
- outs(msg);
- outs(ANSI_RESET);
- }
- }
-
- // show BM commands
- {
- const char *aCat = ANSI_COLOR(1;32);
- const char *aHot = ANSI_COLOR(1;36);
- const char *aRst = ANSI_RESET;
-
- if (!isBM)
- {
- aCat = ANSI_COLOR(1;30;40);
- aHot = "";
- aRst = "";
- }
-
- ipostres ++;
- move_ansi(ipostres++, COLPOSTRES-2);
- outs(aCat);
- outs("¦W³æ½s¿è»P¨ä¥¦:");
- if (!isBM) outs(" (»ÝªO¥DÅv­­)");
- outs(aRst);
- move_ansi(ipostres++, COLPOSTRES);
- prints("%sv%s)¥i¨£¦W³æ %sw%s)¤ô±í¦W³æ ",
- aHot, aRst, aHot, aRst);
- move_ansi(ipostres++, COLPOSTRES);
- prints("%sm%s)Á|¿ì§ë²¼ %so%s)§ë²¼¦W³æ ",
- aHot, aRst, aHot, aRst);
- move_ansi(ipostres++, COLPOSTRES);
- prints("%sc%s)¤å³¹Ãþ§O %sn%s)µo¤åª`·N¨Æ¶µ ",
- aHot, aRst, aHot, aRst);
- outs(ANSI_RESET);
- }
-
- move(b_lines, 0);
- if (!isBM)
- {
- vmsg("±z¹ï¦¹ªOµLºÞ²zÅv­­");
- return FULLUPDATE;
- }
-
- switch(tolower(getans("½Ð¿é¤J­n§ïÅܪº³]©w, ¨ä¥¦Áäµ²§ô: ")))
- {
-#ifdef USE_AUTOCPLOG
- case 'x':
- bp->brdattr ^= BRD_CPLOG;
- touched = 1;
- break;
-#endif
- case 'l':
- bp->brdattr ^= BRD_LOCALSAVE;
- touched = 1;
- break;
-
- case 'e':
- if(HasUserPerm(PERM_SYSOP))
- {
- bp->brdattr ^= BRD_RESTRICTEDPOST;
- touched = 1;
- } else {
- vmsg("¦¹¶µ³]©w»Ý­n¯¸ªøÅv­­");
- }
- break;
-
- case 'h':
-#ifndef BMCHS
- if (!HasUserPerm(PERM_SYSOP))
- {
- vmsg("¦¹¶µ³]©w»Ý­n¯¸ªøÅv­­");
- break;
- }
-#endif
- if(bp->brdattr & BRD_HIDE)
- {
- bp->brdattr &= ~BRD_HIDE;
- bp->brdattr &= ~BRD_POSTMASK;
- hbflreload(currbid);
- } else {
- bp->brdattr |= BRD_HIDE;
- bp->brdattr |= BRD_POSTMASK;
- }
- touched = 1;
- break;
-
- case 'g':
-#ifndef BMCHS
- if (!HasUserPerm(PERM_SYSOP))
- {
- vmsg("¦¹¶µ³]©w»Ý­n¯¸ªøÅv­­");
- break;
- }
-#endif
- bp->brdattr ^= BRD_BMCOUNT;
- touched = 1;
- break;
-
- case 'r':
- bp->brdattr ^= BRD_NORECOMMEND;
- touched = 1;
- break;
-
- case 'i':
- bp->brdattr ^= BRD_IPLOGRECMD;
- touched = 1;
- break;
-
- case 'f':
- bp->brdattr &= ~BRD_NORECOMMEND;
- bp->brdattr ^= BRD_NOFASTRECMD;
- touched = 1;
-
- if(bp->brdattr & BRD_NOFASTRECMD)
- {
- char buf[8] = "";
-
- if(bp->fastrecommend_pause > 0)
- sprintf(buf, "%d", bp->fastrecommend_pause);
- getdata_str(b_lines-1, 0,
- "½Ð¿é¤J³s±À®É¶¡­­¨î(³æ¦ì: ¬í) [5~240]: ",
- buf, 4, ECHO, buf);
- if(buf[0] >= '0' && buf[0] <= '9')
- bp->fastrecommend_pause = atoi(buf);
-
- if( bp->fastrecommend_pause < 5 ||
- bp->fastrecommend_pause > 240)
- {
- if(buf[0])
- {
- vmsg("¿é¤J®É¶¡µL®Ä¡A½Ð¨Ï¥Î 5~240 ¤§¶¡ªº¼Æ¦r¡C");
- }
- bp->fastrecommend_pause = 0;
- bp->brdattr &= ~BRD_NOFASTRECMD;
- }
- }
- break;
-#ifndef OLDRECOMMEND
- case 'b':
- if(bp->brdattr & BRD_NORECOMMEND)
- bp->brdattr |= BRD_NOBOO;
- bp->brdattr ^= BRD_NOBOO;
- touched = 1;
- if (!(bp->brdattr & BRD_NOBOO))
- bp->brdattr &= ~BRD_NORECOMMEND;
- break;
-#endif
- case '8':
- if (!over18)
- {
- vmsg("ªO¥D¥»¨­¥¼º¡ 18 ·³¡C");
- } else {
- bp->brdattr ^= BRD_OVER18;
- touched = 1;
- }
- break;
-
- case 'v':
- clear();
- friend_edit(BOARD_VISABLE);
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- hbflreload(currbid);
- clear();
- break;
-
- case 'w':
- clear();
- friend_edit(BOARD_WATER);
- clear();
- break;
-
- case 'o':
- clear();
- friend_edit(FRIEND_CANVOTE);
- clear();
-
- case 'm':
- clear();
- b_vote_maintain();
- clear();
- break;
-
- case 'n':
- clear();
- b_post_note();
- clear();
- break;
-
- case 'c':
- clear();
- b_posttype();
- clear();
- break;
-
- case 'y':
- if (!(HasUserPerm(PERM_SYSOP) || (HasUserPerm(PERM_SYSSUPERSUBOP) && GROUPOP()) ) ) {
- vmsg("¦¹¶µ³]©w»Ý­n¸s²Õªø©Î¯¸ªøÅv­­");
- break;
- }
- bp->brdattr ^= BRD_NOREPLY;
- touched = 1;
- break;
-
- default:
- finished = 1;
- break;
- }
- }
- if(touched)
- {
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- substitute_record(fn_board, bp, sizeof(boardheader_t), currbid);
- log_usies("SetBoard", bp->brdname);
- vmsg("¤wÀx¦s·s³]©w");
- }
- else
- vmsg("¥¼§ïÅÜ¥ô¦ó³]©w");
-
- return FULLUPDATE;
-}
-
-static int
-check_newpost(boardstat_t * ptr)
-{ /* Ptt §ï */
- time4_t ftime;
-
- ptr->myattr &= ~NBRD_UNREAD;
- if (B_BH(ptr)->brdattr & (BRD_GROUPBOARD | BRD_SYMBOLIC))
- return 0;
-
- if (B_TOTAL(ptr) == 0)
- {
- setbtotal(ptr->bid);
- setbottomtotal(ptr->bid);
- }
- if (B_TOTAL(ptr) == 0)
- return 0;
- ftime = B_LASTPOSTTIME(ptr);
-
- /* ¦³¨Ç util, ¤×¨ä¬O innbbsd, ·|¥Î¨ì¤ñ¸û·sªº time stamp,
- * ¥u­n¤£¤Ó¸Ø±i´N ok */
- if (ftime > now + 10)
- ftime = B_LASTPOSTTIME(ptr) = now - 1;
-
- if ( brc_unread_time(ptr->bid, ftime, 0) )
- ptr->myattr |= NBRD_UNREAD;
-
- return 1;
-}
-
-static void
-load_uidofgid(const int gid, const int type)
-{
- boardheader_t *bptr, *currbptr, *parent;
- int bid, n, childcount = 0;
- assert(0<=type && type<2);
- assert(0<= gid-1 && gid-1<MAX_BOARD);
- currbptr = parent = &bcache[gid - 1];
- assert(0<=numboards && numboards<=MAX_BOARD);
- for (n = 0; n < numboards; ++n) {
- bid = SHM->bsorted[type][n]+1;
- if( bid<=0 || !(bptr = getbcache(bid))
- || bptr->brdname[0] == '\0' )
- continue;
- if (bptr->gid == gid) {
- if (currbptr == parent)
- currbptr->firstchild[type] = bid;
- else {
- currbptr->next[type] = bid;
- currbptr->parent = gid;
- }
- childcount++;
- currbptr = bptr;
- }
- }
- parent->childcount = childcount;
- if (currbptr == parent) // no child
- currbptr->firstchild[type] = -1;
- else // the last child
- currbptr->next[type] = -1;
-}
-
-static boardstat_t *
-addnewbrdstat(int n, int state)
-{
- boardstat_t *ptr;
-
- // ptt 2 local modification
- // XXX maybe some developer discovered signed short issue?
- assert(n != -32769);
-
- assert(0<=n && n<MAX_BOARD);
- assert(0<=brdnum && brdnum<nbrdsize);
- ptr = &nbrd[brdnum++];
- //boardheader_t *bptr = &bcache[n];
- //ptr->total = &(SHM->total[n]);
- //ptr->lastposttime = &(SHM->lastposttime[n]);
-
- ptr->bid = n + 1;
- ptr->myattr = state;
- if ((B_BH(ptr)->brdattr & BRD_HIDE) && state == NBRD_BOARD)
- B_BH(ptr)->brdattr |= BRD_POSTMASK;
- if (!IS_LISTING_FAV())
- ptr->myattr &= ~NBRD_FAV;
- check_newpost(ptr);
- return ptr;
-}
-
-#if !HOTBOARDCACHE
-static int
-cmpboardfriends(const void *brd, const void *tmp)
-{
-#ifdef USE_COOLDOWN
- if ((B_BH((boardstat_t*)tmp)->brdattr & BRD_COOLDOWN) &&
- (B_BH((boardstat_t*)brd)->brdattr & BRD_COOLDOWN))
- return 0;
- else if ( B_BH((boardstat_t*)tmp)->brdattr & BRD_COOLDOWN ) {
- if (B_BH((boardstat_t*)brd)->nuser == 0)
- return 0;
- else
- return 1;
- }
- else if ( B_BH((boardstat_t*)brd)->brdattr & BRD_COOLDOWN ) {
- if (B_BH((boardstat_t*)tmp)->nuser == 0)
- return 0;
- else
- return -1;
- }
-#endif
- return ((B_BH((boardstat_t*)tmp)->nuser) -
- (B_BH((boardstat_t*)brd)->nuser));
-}
-#endif
-
-static void
-load_boards(char *key)
-{
- int type = cuser.uflag & BRDSORT_FLAG ? 1 : 0;
- int i;
- int state;
-
- brdnum = 0;
- if (nbrd) {
- free(nbrd);
- nbrdsize = 0;
- nbrd = NULL;
- }
- if (!IN_CLASS()) {
- if(IS_LISTING_FAV()){
- fav_t *fav = get_current_fav();
- int nfav = get_data_number(fav);
- if( nfav == 0 ) {
- nbrdsize = 1;
- nbrd = (boardstat_t *)malloc(sizeof(boardstat_t) * 1);
- addnewbrdstat(0, 0); // dummy
- return;
- }
- nbrdsize = nfav;
- nbrd = (boardstat_t *)malloc(sizeof(boardstat_t) * nfav);
- for( i = 0 ; i < fav->DataTail; ++i ){
- int state;
- if (!(fav->favh[i].attr & FAVH_FAV))
- continue;
-
- if ( !key[0] ){
- if (get_item_type(&fav->favh[i]) == FAVT_LINE )
- state = NBRD_LINE;
- else if (get_item_type(&fav->favh[i]) == FAVT_FOLDER )
- state = NBRD_FOLDER;
- else {
- state = NBRD_BOARD;
- if (is_set_attr(&fav->favh[i], FAVH_UNREAD))
- state |= NBRD_UNREAD;
- }
- } else {
- if (get_item_type(&fav->favh[i]) == FAVT_LINE )
- continue;
- else if (get_item_type(&fav->favh[i]) == FAVT_FOLDER ){
- if( strcasestr(
- get_folder_title(fav_getid(&fav->favh[i])),
- key)
- )
- state = NBRD_FOLDER;
- else
- continue;
- }else{
- boardheader_t *bptr = getbcache(fav_getid(&fav->favh[i]));
- assert(0<=fav_getid(&fav->favh[i])-1 && fav_getid(&fav->favh[i])-1<MAX_BOARD);
- if (strcasestr(bptr->title, key))
- state = NBRD_BOARD;
- else
- continue;
- if (is_set_attr(&fav->favh[i], FAVH_UNREAD))
- state |= NBRD_UNREAD;
- }
- }
-
- if (is_set_attr(&fav->favh[i], FAVH_TAG))
- state |= NBRD_TAG;
- if (is_set_attr(&fav->favh[i], FAVH_ADM_TAG))
- state |= NBRD_TAG;
- // ¦³¨Ç¤H ¬Y¨Ç bid < 0 Orzz // ptt2 local modification
- if (fav_getid(&fav->favh[i]) < 1)
- continue;
- addnewbrdstat(fav_getid(&fav->favh[i]) - 1, NBRD_FAV | state);
- }
- }
-#if HOTBOARDCACHE
- else if(IN_HOTBOARD()){
- nbrdsize = SHM->nHOTs;
- if(nbrdsize == 0) {
- nbrdsize = 1;
- nbrd = (boardstat_t *)malloc(sizeof(boardstat_t) * 1);
- addnewbrdstat(0, 0); // dummy
- return;
- }
- assert(0<nbrdsize);
- nbrd = (boardstat_t *)malloc(sizeof(boardstat_t) * nbrdsize);
- for( i = 0 ; i < nbrdsize; ++i ) {
- if(SHM->HBcache[i] == -1)
- continue;
- addnewbrdstat(SHM->HBcache[i], HasBoardPerm(&bcache[SHM->HBcache[i]]));
- }
- }
-#endif
- else { // general case
- nbrdsize = numboards;
- assert(0<nbrdsize && nbrdsize<=MAX_BOARD);
- nbrd = (boardstat_t *) malloc(sizeof(boardstat_t) * nbrdsize);
- for (i = 0; i < nbrdsize; i++) {
- int n = SHM->bsorted[type][i];
- boardheader_t *bptr;
- if (n < 0)
- continue;
- bptr = &bcache[n];
- if (bptr == NULL)
- continue;
- if (!bptr->brdname[0] ||
- (bptr->brdattr & (BRD_GROUPBOARD | BRD_SYMBOLIC)) ||
- !((state = HasBoardPerm(bptr)) || GROUPOP()) ||
- TITLE_MATCH(bptr, key)
-#if ! HOTBOARDCACHE
- || (IN_HOTBOARD() && bptr->nuser < 5)
-#endif
- )
- continue;
- addnewbrdstat(n, state);
- }
- }
-#if ! HOTBOARDCACHE
- if (IN_HOTBOARD())
- qsort(nbrd, brdnum, sizeof(boardstat_t), cmpboardfriends);
-#endif
- } else { /* load boards of a subclass */
- boardheader_t *bptr = getbcache(class_bid);
- int childcount;
- int bid;
-
- assert(0<=class_bid-1 && class_bid-1<MAX_BOARD);
- if (bptr->firstchild[type] == 0 || bptr->childcount==0)
- load_uidofgid(class_bid, type);
-
- childcount = bptr->childcount; // Ptt: child count after load_uidofgid
-
- nbrdsize = childcount + 5;
- nbrd = (boardstat_t *) malloc((childcount+5) * sizeof(boardstat_t));
- // ¹w¯d¨â­Ó¥H§K¤j¶q¶}ªO®É±¾½Õ
- for (bid = bptr->firstchild[type]; bid > 0 &&
- brdnum < childcount+5; bid = bptr->next[type]) {
- assert(0<=bid-1 && bid-1<MAX_BOARD);
- bptr = getbcache(bid);
- state = HasBoardPerm(bptr);
- if ( !(state || GROUPOP()) || TITLE_MATCH(bptr, key) )
- continue;
-
- if (bptr->brdattr & BRD_SYMBOLIC) {
- /* Only SYSOP knows a board is symbolic */
- if (HasUserPerm(PERM_SYSOP) || HasUserPerm(PERM_SYSSUPERSUBOP))
- state |= NBRD_SYMBOLIC;
- else {
- bid = BRD_LINK_TARGET(bptr);
- if (bcache[bid - 1].brdname[0] == 0) {
- vmsg("³sµ²¤w·l·´¡A½Ð¦Ü SYSOP ¦^³ø¦¹°ÝÃD¡C");
- continue;
- }
- }
- }
- assert(0<=bid-1 && bid-1<MAX_BOARD);
- addnewbrdstat(bid-1, state);
- }
- if(childcount < brdnum) {
- //Ptt: dirty fix fix soon
- getbcache(class_bid)->childcount = 0;
- }
-
-
- }
-}
-
-static int
-search_board(void)
-{
- int num;
- char genbuf[IDLEN + 2];
- struct NameList namelist;
-
- move(0, 0);
- clrtoeol();
- NameList_init(&namelist);
- assert(brdnum<=nbrdsize);
- NameList_resizefor(&namelist, brdnum);
- for (num = 0; num < brdnum; num++)
- if (!IS_LISTING_FAV() ||
- (nbrd[num].myattr & NBRD_BOARD && HasBoardPerm(B_BH(&nbrd[num]))) )
- NameList_add(&namelist, B_BH(&nbrd[num])->brdname);
- namecomplete2(&namelist, MSG_SELECT_BOARD, genbuf);
- NameList_delete(&namelist);
-
-#ifdef DEBUG
- vmsg(genbuf);
-#endif
-
- for (num = 0; num < brdnum; num++)
- if (!strcasecmp(B_BH(&nbrd[num])->brdname, genbuf))
- return num;
- return -1;
-}
-
-static int
-unread_position(char *dirfile, boardstat_t * ptr)
-{
- fileheader_t fh;
- char fname[FNLEN];
- register int num, fd, step, total;
-
- total = B_TOTAL(ptr);
- num = total + 1;
- if ((ptr->myattr & NBRD_UNREAD) && (fd = open(dirfile, O_RDWR)) > 0) {
- if (!brc_initial_board(B_BH(ptr)->brdname)) {
- num = 1;
- } else {
- num = total - 1;
- step = 4;
- while (num > 0) {
- lseek(fd, (off_t) (num * sizeof(fh)), SEEK_SET);
- if (read(fd, fname, FNLEN) <= 0 ||
- !brc_unread(ptr->bid, fname, 0))
- break;
- num -= step;
- if (step < 32)
- step += step >> 1;
- }
- if (num < 0)
- num = 0;
- while (num < total) {
- lseek(fd, (off_t) (num * sizeof(fh)), SEEK_SET);
- if (read(fd, fname, FNLEN) <= 0 ||
- brc_unread(ptr->bid, fname, 0))
- break;
- num++;
- }
- }
- close(fd);
- }
- if (num < 0)
- num = 0;
- return num;
-}
-
-static char
-get_fav_type(boardstat_t *ptr)
-{
- if (ptr->myattr & NBRD_FOLDER)
- return FAVT_FOLDER;
- else if (ptr->myattr & NBRD_BOARD)
- return FAVT_BOARD;
- else if (ptr->myattr & NBRD_LINE)
- return FAVT_LINE;
- return 0;
-}
-
-static void
-brdlist_foot(void)
-{
- outs( ANSI_COLOR(34;46) " ¿ï¾Ü¬ÝªO "
- ANSI_COLOR(31;47) " (c)" ANSI_COLOR(30) "·s¤å³¹¼Ò¦¡ "
- ANSI_COLOR(31) "(v/V)" ANSI_COLOR(30) "¼Ð¬°¤wŪ/¥¼Åª "
- ANSI_COLOR(31) "(y)" ANSI_COLOR(30));
- if(IS_LISTING_FAV())
- outs("¦C¥X¥þ³¡");
- else if (IS_LISTING_BRD())
- outs("¿z¿ï¦Cªí");
- else outs("¿z¿ï¦Cªí"); // never reach here?
-
- outslr(" " ANSI_COLOR(31) "(m)" ANSI_COLOR(30) "¤Á´«³Ì·R",
- 73, ANSI_RESET, 0);
-}
-
-
-static inline char *
-make_class_color(char *name)
-{
- /* 34 is too dark */
- char *colorset[8] = {"", ANSI_COLOR(32),
- ANSI_COLOR(33), ANSI_COLOR(36), ANSI_COLOR(1;34),
- ANSI_COLOR(1), ANSI_COLOR(1;32), ANSI_COLOR(1;33)};
-
- return colorset[(unsigned int)
- (name[0] + name[1] +
- name[2] + name[3]) & 0x7];
-}
-
-#define HILIGHT_COLOR ANSI_COLOR(1;36)
-
-static void
-show_brdlist(int head, int clsflag, int newflag)
-{
- int myrow = 2;
- if (unlikely(IN_CLASSROOT())) {
- currstat = CLASS;
- myrow = 6;
- showtitle("¤ÀÃþ¬ÝªO", BBSName);
- movie(0);
- move(1, 0);
- // TODO remove ascii art here
- outs(
- " "
- "¢© ¢~¡X" ANSI_COLOR(33) "¡´\n"
- " ùá¡X " ANSI_RESET " "
- "¢¨¢i" ANSI_COLOR(47) "¡ó" ANSI_COLOR(40) "¢i¢i¢©ùç\n"
- " " ANSI_COLOR(44) " ¡s¡s¡s¡s¡s¡s¡s¡s "
- ANSI_COLOR(33) "ùø" ANSI_RESET ANSI_COLOR(44) " ¢©¢¨¢i¢i¢i¡¿¡¿¡¿ùø " ANSI_RESET "\n"
- " " ANSI_COLOR(44) " "
- ANSI_COLOR(33) " " ANSI_RESET ANSI_COLOR(44) " ¢«¢ª¢i¢i¢i¡¶¡¶¡¶ ùø" ANSI_RESET "\n"
- " ¡s¡s¡s¡s¡s¡s¡s¡s " ANSI_COLOR(33)
- "¢x" ANSI_RESET " ¢ª¢i¢i¢i¢i¢« ùø\n"
- " " ANSI_COLOR(33) "ùó"
- "¡X¡X" ANSI_RESET " ¢« ¡X¡Ï" ANSI_RESET);
- } else if (clsflag) {
- showtitle("¬ÝªO¦Cªí", BBSName);
- // [m]¥[¤J©Î²¾¥X§Úªº³Ì·R
- outs("[¡ö][q]¥D¿ï³æ [¡÷][r]¾\\Ū [¡ô¡õ]¿ï¾Ü [PgUp][PgDn]½­¶ [S]±Æ§Ç [/]·j´M [h]¨D§U\n");
- outs(ANSI_COLOR(7));
-
- // boards in Ptt series are very, very large.
- // let's create more space for board numbers,
- // and less space for BM.
- //
- // newflag is not so different now because we use all 5 digits.
-
- outs( newflag ? " Á`¼Æ" : " ½s¸¹");
- outs(" ¬Ý ªO Ãþ§O Âà«H ¤¤ ¤å ±Ô ­z ¤H®ð ªO ¥D");
- outslr("", 74, ANSI_RESET, 0);
- move(b_lines, 0);
- brdlist_foot();
- }
- if (brdnum > 0) {
- boardstat_t *ptr;
- char *unread[2] = {ANSI_COLOR(37) " " ANSI_RESET, ANSI_COLOR(1;31) "£¾" ANSI_RESET};
-
- if (IS_LISTING_FAV() && brdnum == 1 && get_fav_type(&nbrd[0]) == 0) {
-
- // (a) or (i) needs HasUserPerm(PERM_LOGINOK)).
- // 3 = first line of empty area
- if (!HasFavEditPerm())
- {
- // TODO actually we cannot use 's' (for PTT)...
- mouts(3, 10,
- "--- µù¥Uªº¨Ï¥ÎªÌ¤~¯à·s¼W¬ÝªO³á (¥i«ö s ¤â°Ê¿ï¨ú) ---");
- } else {
- // normal user. tell him what to do.
- mouts(3, 10,
- "--- ªÅ¥Ø¿ý¡A½Ð«ö a ·s¼W©Î¥Î y ¦C¥X¥þ³¡¬ÝªO«á«ö z ¼W§R ---");
- }
- return;
- }
-
- while (++myrow < b_lines) {
-
- move(myrow, 0);
- clrtoeol();
-
- if (head < brdnum) {
- assert(0<=head && head<nbrdsize);
- ptr = &nbrd[head++];
- if (ptr->myattr & NBRD_LINE){
- if( !newflag )
- prints("%7d %c ", head, ptr->myattr & NBRD_TAG ? 'D' : ' ');
- else
- prints("%7s ", "");
-
- if (!(ptr->myattr & NBRD_FAV))
- outs(ANSI_COLOR(1;30));
-
- outs("------------"
- " "
- // "------"
- "------------------------------------------"
- ANSI_RESET "\n");
- continue;
- }
- else if (ptr->myattr & NBRD_FOLDER){
- char *title = get_folder_title(ptr->bid);
- prints("%7d %c ",
- newflag ?
- get_data_number(get_fav_folder(getfolder(ptr->bid))) :
- head, ptr->myattr & NBRD_TAG ? 'D' : ' ');
-
- // well, what to print with myfav folders?
- // this style is too long and we don't want to
- // fight with users...
- // think about new way some otherday.
- prints("%sMyFavFolder" ANSI_RESET " ¥Ø¿ý ¡¼%-34s",
- !(cuser.uflag2 & FAVNOHILIGHT)?HILIGHT_COLOR : "",
- title);
- /*
- if (!(cuser.uflag2 & FAVNOHILIGHT))
- outs(HILIGHT_COLOR);
- prints("%-12s", "[Folder]");
- outs(ANSI_RESET);
- prints(" ¥Ø¿ý £U%-34s", title);
- */
- /*
- outs(ANSI_COLOR(0;36));
- prints("£U%-70.70s", title);
- outs(ANSI_RESET);
- */
- continue;
- }
-
- if (IN_CLASSROOT())
- outs(" ");
- else {
- if (!GROUPOP() && !HasBoardPerm(B_BH(ptr))) {
- if (newflag) prints("%7s", "");
- else prints("%7d", head);
- prints(" %c Unknown?? ÁôªO ¡H³o­ÓªO¬OÁôªO",
- ptr->myattr & NBRD_TAG ? 'D' : ' ');
- continue;
- }
- }
-
- if (newflag && B_BH(ptr)->brdattr & BRD_GROUPBOARD)
- outs(" ");
- else
- prints("%7d%c%s",
- newflag ? (int)(B_TOTAL(ptr)) : head,
- !(B_BH(ptr)->brdattr & BRD_HIDE) ? ' ' :
- (B_BH(ptr)->brdattr & BRD_POSTMASK) ? ')' : '-',
- (ptr->myattr & NBRD_TAG) ? "D " :
- (B_BH(ptr)->brdattr & BRD_GROUPBOARD) ? " " :
- unread[ptr->myattr & NBRD_UNREAD ? 1 : 0]);
-
- if (!IN_CLASSROOT()) {
- prints("%s%-13s" ANSI_RESET "%s%5.5s" ANSI_COLOR(0;37)
- "%2.2s" ANSI_RESET "%-34.34s",
- ((!(cuser.uflag2 & FAVNOHILIGHT) &&
- getboard(ptr->bid) != NULL))? HILIGHT_COLOR : "",
- B_BH(ptr)->brdname,
- make_class_color(B_BH(ptr)->title),
- B_BH(ptr)->title, B_BH(ptr)->title + 5, B_BH(ptr)->title + 7);
-
-#ifdef USE_COOLDOWN
- if (B_BH(ptr)->brdattr & BRD_COOLDOWN)
- outs("ÀR ");
- else if (B_BH(ptr)->brdattr & BRD_BAD)
-#else
- if (B_BH(ptr)->brdattr & BRD_BAD)
-#endif
- outs(" X ");
-
- else if (B_BH(ptr)->nuser <= 0)
- prints(" %c ", B_BH(ptr)->bvote ? 'V' : ' ');
- else if (B_BH(ptr)->nuser <= 10)
- prints("%2d ", B_BH(ptr)->nuser);
- else if (B_BH(ptr)->nuser <= 50)
- prints(ANSI_COLOR(1;33) "%2d" ANSI_RESET " ", B_BH(ptr)->nuser);
-#ifdef EXTRA_HOTBOARD_COLORS
- // piaip 2008/02/04: new colors
- else if (B_BH(ptr)->nuser >= 100000)
- outs(ANSI_COLOR(1;35) "Ãz!" ANSI_RESET);
- else if (B_BH(ptr)->nuser >= 60000)
- outs(ANSI_COLOR(1;33) "Ãz!" ANSI_RESET);
- else if (B_BH(ptr)->nuser >= 30000)
- outs(ANSI_COLOR(1;32) "Ãz!" ANSI_RESET);
- else if (B_BH(ptr)->nuser >= 10000)
- outs(ANSI_COLOR(1;36) "Ãz!" ANSI_RESET);
-#endif
- else if (B_BH(ptr)->nuser >= 5000)
- outs(ANSI_COLOR(1;34) "Ãz!" ANSI_RESET);
- else if (B_BH(ptr)->nuser >= 2000)
- outs(ANSI_COLOR(1;31) "Ãz!" ANSI_RESET);
- else if (B_BH(ptr)->nuser >= 1000)
- outs(ANSI_COLOR(1) "Ãz!" ANSI_RESET);
- else if (B_BH(ptr)->nuser >= 100)
- outs(ANSI_COLOR(1) "HOT" ANSI_RESET);
- else //if (B_BH(ptr)->nuser > 50)
- prints(ANSI_COLOR(1;31) "%2d" ANSI_RESET " ", B_BH(ptr)->nuser);
- prints("%.*s" ANSI_CLRTOEND, t_columns - 68, B_BH(ptr)->BM);
- } else {
- prints("%-40.40s %.*s", B_BH(ptr)->title + 7,
- t_columns - 68, B_BH(ptr)->BM);
- }
- }
- clrtoeol();
- }
- }
-}
-
-static void
-set_menu_BM(char *BM)
-{
- if (!HasUserPerm(PERM_NOCITIZEN) && (HasUserPerm(PERM_ALLBOARD) || is_BM(BM))) {
- currmode |= MODE_GROUPOP;
- cuser.userlevel |= PERM_SYSSUBOP;
- }
-}
-
-static void replace_link_by_target(boardstat_t *board)
-{
- assert(0<=board->bid-1 && board->bid-1<MAX_BOARD);
- board->bid = BRD_LINK_TARGET(getbcache(board->bid));
- board->myattr &= ~NBRD_SYMBOLIC;
-}
-static int
-paste_taged_brds(int gid)
-{
- fav_t *fav;
- int bid, tmp;
-
- if (gid == 0 || ! (HasUserPerm(PERM_SYSOP) || GROUPOP()) ||
- getans("¶K¤W¼Ð°Oªº¬ÝªO?(y/N)")!='y') return 0;
- fav = get_fav_root();
- for (tmp = 0; tmp < fav->DataTail; tmp++) {
- boardheader_t *bh;
- bid = fav_getid(&fav->favh[tmp]);
- assert(0<=bid-1 && bid-1<MAX_BOARD);
- bh = getbcache(bid);
- if( !is_set_attr(&fav->favh[tmp], FAVH_ADM_TAG))
- continue;
- set_attr(&fav->favh[tmp], FAVH_ADM_TAG, FALSE);
- if (bh->gid != gid) {
- bh->gid = gid;
- assert(0<=bid-1 && bid-1<MAX_BOARD);
- substitute_record(FN_BOARD, bh,
- sizeof(boardheader_t), bid);
- reset_board(bid);
- log_usies("SetBoardGID", bh->brdname);
- }
- }
- sort_bcache();
- return 1;
-}
-
-static void
-choose_board(int newflag)
-{
- static int num = 0;
- boardstat_t *ptr;
- int head = -1, ch = 0, currmodetmp, tmp, tmp1, bidtmp;
- char keyword[13] = "", buf[PATHLEN];
-
- setutmpmode(newflag ? READNEW : READBRD);
- if( get_fav_root() == NULL )
- fav_load();
- ++choose_board_depth;
- brdnum = 0;
- if (!cuser.userlevel) /* guest yank all boards */
- LIST_BRD();
-
- do {
- if (brdnum <= 0) {
- load_boards(keyword);
- if (brdnum <= 0) {
- if (keyword[0] != 0) {
- vmsg("¨S¦³¥ô¦ó¬ÝªO¼ÐÃD¦³¦¹ÃöÁä¦r");
- keyword[0] = 0;
- brdnum = -1;
- continue;
- }
- if (IS_LISTING_BRD()) {
- if (HasUserPerm(PERM_SYSOP) || GROUPOP()) {
- if (paste_taged_brds(class_bid) ||
- m_newbrd(class_bid, 0) == -1)
- break;
- brdnum = -1;
- continue;
- } else
- break;
- }
- }
- head = -1;
- }
-
- /* reset the cursor when out of range */
- if (num < 0)
- num = 0;
- else if (num >= brdnum)
- num = brdnum - 1;
-
- if (head < 0) {
- if (newflag) {
- tmp = num;
- assert(brdnum<=nbrdsize);
- while (num < brdnum) {
- ptr = &nbrd[num];
- if (ptr->myattr & NBRD_UNREAD)
- break;
- num++;
- }
- if (num >= brdnum)
- num = tmp;
- }
- head = (num / p_lines) * p_lines;
- show_brdlist(head, 1, newflag);
- } else if (num < head || num >= head + p_lines) {
- head = (num / p_lines) * p_lines;
- show_brdlist(head, 0, newflag);
- }
- if (IN_CLASSROOT())
- ch = cursor_key(7 + num - head, 10);
- else
- ch = cursor_key(3 + num - head, 0);
-
- switch (ch) {
-
- ///////////////////////////////////////////////////////
- // General Hotkeys
- ///////////////////////////////////////////////////////
-
- case 'h':
- show_helpfile(fn_boardlisthelp);
- show_brdlist(head, 1, newflag);
- break;
- case Ctrl('W'):
- whereami();
- head = -1;
- break;
-
- case 'c':
- show_brdlist(head, 1, newflag ^= 1);
- break;
- case Ctrl('I'):
- t_idle();
- show_brdlist(head, 1, newflag);
- break;
-
- case 'e':
- case KEY_LEFT:
- case EOF:
- ch = 'q';
- case 'q':
- if (keyword[0]) {
- keyword[0] = 0;
- brdnum = -1;
- ch = ' ';
- }
- break;
- case KEY_PGUP:
- case 'P':
- case 'b':
- case Ctrl('B'):
- if (num) {
- num -= p_lines;
- break;
- }
- case KEY_END:
- case '$':
- num = brdnum - 1;
- break;
- case ' ':
- case KEY_PGDN:
- case 'N':
- case Ctrl('F'):
- if (num == brdnum - 1)
- num = 0;
- else
- num += p_lines;
- break;
- case KEY_UP:
- case 'p':
- case 'k':
- if (num-- <= 0)
- num = brdnum - 1;
- break;
- case '*':
- if (IS_LISTING_FAV()) {
- int i = 0;
- assert(brdnum<=nbrdsize);
- for (i = 0; i < brdnum; i++)
- {
- ptr = &nbrd[i];
- if (IS_LISTING_FAV()){
- assert(nbrdsize>0);
- if(get_fav_type(&nbrd[0]) != 0)
- fav_tag(ptr->bid, get_fav_type(ptr), 2);
- }
- ptr->myattr ^= NBRD_TAG;
- }
- head = 9999;
- }
- break;
- case 't':
- assert(0<=num && num<nbrdsize);
- ptr = &nbrd[num];
- if (IS_LISTING_FAV()){
- assert(nbrdsize>0);
- if(get_fav_type(&nbrd[0]) != 0)
- fav_tag(ptr->bid, get_fav_type(ptr), EXCH);
- }
- else if (HasUserPerm(PERM_SYSOP) ||
- HasUserPerm(PERM_SYSSUPERSUBOP) ||
- HasUserPerm(PERM_SYSSUBOP) ||
- HasUserPerm(PERM_BOARD)) {
- /* ¯¸ªøºÞ²z¥Îªº tag */
- if (ptr->myattr & NBRD_TAG)
- set_attr(getadmtag(ptr->bid), FAVH_ADM_TAG, FALSE);
- else
- fav_add_admtag(ptr->bid);
- }
- ptr->myattr ^= NBRD_TAG;
- head = 9999;
- case KEY_DOWN:
- case 'n':
- case 'j':
- if (++num < brdnum)
- break;
- case '0':
- case KEY_HOME:
- num = 0;
- break;
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- if ((tmp = search_num(ch, brdnum)) >= 0)
- num = tmp;
- brdlist_foot();
- break;
-
- case '/':
- getdata_buf(b_lines - 1, 0, "½Ð¿é¤J¬ÝªO¤¤¤åÃöÁä¦r:",
- keyword, sizeof(keyword), DOECHO);
- brdnum = -1;
- break;
- case 'S':
- if(IS_LISTING_FAV()){
- move(b_lines - 2, 0); clrtobot();
- outs("­«·s±Æ§Ç¬ÝªO "
- ANSI_COLOR(1;33) "(ª`·N, ³o­Ó°Ê§@·|Âмg­ì¨Ó³]©w)" ANSI_RESET " \n");
- tmp = getans("±Æ§Ç¤è¦¡ (1)«ö·ÓªO¦W±Æ§Ç (2)«ö·ÓÃþ§O±Æ§Ç ==> [0]¨ú®ø ");
- if( tmp == '1' )
- fav_sort_by_name();
- else if( tmp == '2' )
- fav_sort_by_class();
- }
- else
- cuser.uflag ^= BRDSORT_FLAG;
- brdnum = -1;
- break;
-
-
- case 'v':
- case 'V':
- assert(0<=num && num<nbrdsize);
- ptr = &nbrd[num];
- if(nbrd[num].bid < 0 || !HasBoardPerm(B_BH(ptr)))
- break;
- if (ch == 'v') {
- ptr->myattr &= ~NBRD_UNREAD;
- brc_toggle_all_read(ptr->bid, 1);
- } else {
- brc_toggle_all_read(ptr->bid, 0);
- ptr->myattr |= NBRD_UNREAD;
- }
- show_brdlist(head, 0, newflag);
- break;
- case 's':
- if ((tmp = search_board()) != -1) {
- head = -1;
- num = tmp;
- break;
- }
- // TODO try global search?
- // TODO entering boards is now too complex...
- // please refine the code.
- //
- // if (Select() != NEWDIRECT) {
- // }
-
- // update screen
- head = -1;
- num = tmp;
- break;
-
- case KEY_RIGHT:
- case '\n':
- case '\r':
- case 'r':
- {
- if (IS_LISTING_FAV()) {
- assert(nbrdsize>0);
- if (get_fav_type(&nbrd[0]) == 0)
- break;
- assert(0<=num && num<nbrdsize);
- ptr = &nbrd[num];
- if (ptr->myattr & NBRD_LINE)
- break;
- if (ptr->myattr & NBRD_FOLDER){
- int t = num;
- num = 0;
- fav_folder_in(ptr->bid);
- choose_board(0);
- fav_folder_out();
- num = t;
- LIST_FAV(); // XXX press 'y' in fav makes yank_flag = LIST_BRD
- brdnum = -1;
- head = 9999;
- break;
- }
- } else {
- assert(0<=num && num<nbrdsize);
- ptr = &nbrd[num];
- if (ptr->myattr & NBRD_SYMBOLIC) {
- replace_link_by_target(ptr);
- }
- }
-
- assert(0<=ptr->bid-1 && ptr->bid-1<MAX_BOARD);
- if (!(B_BH(ptr)->brdattr & BRD_GROUPBOARD)) { /* «Dsub class */
- if (HasBoardPerm(B_BH(ptr))) {
- brc_initial_board(B_BH(ptr)->brdname);
-
- if (newflag) {
- setbdir(buf, currboard);
- tmp = unread_position(buf, ptr);
- head = tmp - t_lines / 2;
- getkeep(buf, head > 1 ? head : 1, tmp + 1);
- }
- Read();
- check_newpost(ptr);
- head = -1;
- setutmpmode(newflag ? READNEW : READBRD);
- }
- } else { /* sub class */
- move(12, 1);
- bidtmp = class_bid;
- currmodetmp = currmode;
- tmp1 = num;
- num = 0;
- if (!(B_BH(ptr)->brdattr & BRD_TOP))
- class_bid = ptr->bid;
- else
- class_bid = -1; /* ¼öªù¸s²Õ¥Î */
-
- if (!GROUPOP()) /* ¦pªGÁÙ¨S¦³¤p²ÕªøÅv­­ */
- set_menu_BM(B_BH(ptr)->BM);
-
- if (now < B_BH(ptr)->bupdate) {
- int mr = 0;
-
- setbfile(buf, B_BH(ptr)->brdname, fn_notes);
- mr = more(buf, NA);
- if (mr != -1 && mr != READ_NEXT)
- pressanykey();
- }
- tmp = currutmp->brc_id;
- setutmpbid(ptr->bid);
- free(nbrd);
- nbrd = NULL;
- nbrdsize = 0;
- if (IS_LISTING_FAV()) {
- LIST_BRD();
- choose_board(0);
- LIST_FAV();
- }
- else
- choose_board(0);
- currmode = currmodetmp; /* Â÷¶}ªOªO«á´N§âÅv­­®³±¼³á */
- num = tmp1;
- class_bid = bidtmp;
- setutmpbid(tmp);
- brdnum = -1;
- }
- }
- break;
- ///////////////////////////////////////////////////////
- // MyFav Functionality (Require PERM_BASIC)
- ///////////////////////////////////////////////////////
- case 'y':
- if (HasFavEditPerm() && !(IN_CLASS())) {
- if (get_current_fav() != NULL || !IS_LISTING_FAV()){
- yank_flag ^= 1; /* FAV <=> BRD */
- }
- brdnum = -1;
- }
- break;
- case Ctrl('D'):
- if (HasFavEditPerm()) {
- if (getans("§R°£©Ò¦³¼Ð°O[N]?") == 'y'){
- fav_remove_all_tagged_item();
- brdnum = -1;
- }
- }
- break;
- case Ctrl('A'):
- if (HasFavEditPerm()) {
- fav_add_all_tagged_item();
- brdnum = -1;
- }
- break;
- case Ctrl('T'):
- if (HasFavEditPerm()) {
- fav_remove_all_tag();
- brdnum = -1;
- }
- break;
- case Ctrl('P'):
- if (paste_taged_brds(class_bid))
- brdnum = -1;
- break;
-
- case 'L':
- if ((HasUserPerm(PERM_SYSOP) ||
- (HasUserPerm(PERM_SYSSUPERSUBOP) && GROUPOP())) && IN_CLASS()) {
- // TODO XXX why need symlink here? Can we remove it?
- if (make_symbolic_link_interactively(class_bid) < 0)
- break;
- brdnum = -1;
- head = 9999;
- }
- else if (HasFavEditPerm() && IS_LISTING_FAV()) {
- if (fav_add_line() == NULL) {
- vmsg("·s¼W¥¢±Ñ¡A¤À¹j½u/Á`³Ì·R ¼Æ¶q¹F³Ì¤j­È¡C");
- break;
- }
- /* done move if it's the first item. */
- assert(nbrdsize>0);
- if (get_fav_type(&nbrd[0]) != 0)
- move_in_current_folder(brdnum, num);
- brdnum = -1;
- head = 9999;
- }
- break;
-
- case 'd': // why don't we enable 'd'?
- case 'z':
- case 'm':
- if (HasFavEditPerm()) {
- assert(0<=num && num<nbrdsize);
- ptr = &nbrd[num];
- if (IS_LISTING_FAV()) {
- if (ptr->myattr & NBRD_FAV) {
- if (getans("§A½T©w§R°£¶Ü? [N/y]") != 'y')
- break;
- fav_remove_item(ptr->bid, get_fav_type(ptr));
- ptr->myattr &= ~NBRD_FAV;
- }
- }
- else
- {
- if (getboard(ptr->bid) != NULL) {
- fav_remove_item(ptr->bid, FAVT_BOARD);
- ptr->myattr &= ~NBRD_FAV;
- }
- else if (ch != 'd') // 'd' only deletes something.
- {
- if (fav_add_board(ptr->bid) == NULL)
- vmsg("§Aªº³Ì·R¤Ó¦h¤F°Õ ¯uªá¤ß");
- else
- ptr->myattr |= NBRD_FAV;
- }
- }
- brdnum = -1;
- head = 9999;
- }
- break;
- case 'M':
- if (HasFavEditPerm()){
- if (IN_FAVORITE() && IS_LISTING_FAV()){
- imovefav(num);
- brdnum = -1;
- head = 9999;
- }
- }
- break;
- case 'g':
- if (HasFavEditPerm() && IS_LISTING_FAV()) {
- fav_type_t *ft;
- if (fav_stack_full()){
- vmsg("¥Ø¿ý¤w¹F³Ì¤j¼h¼Æ!!");
- break;
- }
- if ((ft = fav_add_folder()) == NULL) {
- vmsg("·s¼W¥¢±Ñ¡A¥Ø¿ý/Á`³Ì·R ¼Æ¶q¹F³Ì¤j­È¡C");
- break;
- }
- fav_set_folder_title(ft, "·sªº¥Ø¿ý");
- /* don't move if it's the first item */
- assert(nbrdsize>0);
- if (get_fav_type(&nbrd[0]) != 0)
- move_in_current_folder(brdnum, num);
- brdnum = -1;
- head = 9999;
- }
- break;
- case 'T':
- assert(0<=num && num<nbrdsize);
- if (HasFavEditPerm() && nbrd[num].myattr & NBRD_FOLDER) {
- fav_type_t *ft = getfolder(nbrd[num].bid);
- strlcpy(buf, get_item_title(ft), sizeof(buf));
- getdata_buf(b_lines-1, 0, "½Ð­×§ï¦WºÙ: ", buf, BTLEN+1, DOECHO);
- fav_set_folder_title(ft, buf);
- brdnum = -1;
- }
- break;
- case 'K':
- if (HasFavEditPerm()) {
- char c, fname[80];
- if (get_current_fav() != get_fav_root()) {
- vmsg("½Ð¨ì§Úªº³Ì·R³Ì¤W¼h°õ¦æ¥»¥\\¯à");
- break;
- }
-
- c = getans("½Ð¿ï¾Ü 2)³Æ¥÷§Úªº³Ì·R 3)¨ú¦^³Ì·R³Æ¥÷ [Q]");
- if(!c)
- break;
- if(getans("½T©w¶Ü [y/N] ") != 'y')
- break;
- switch(c){
- case '2':
- fav_save();
- setuserfile(fname, FAV);
- sprintf(buf, "%s.bak", fname);
- Copy(fname, buf);
- break;
- case '3':
- setuserfile(fname, FAV);
- sprintf(buf, "%s.bak", fname);
- if (!dashf(buf)){
- vmsg("§A¨S¦³³Æ¥÷§Aªº³Ì·R³á");
- break;
- }
- Copy(buf, fname);
- fav_free();
- fav_load();
- break;
- }
- brdnum = -1;
- }
- break;
-
- case 'a':
- case 'i':
- if(IN_FAVORITE() && HasFavEditPerm()){
- char bname[IDLEN + 1];
- int bid;
- move(0, 0);
- clrtoeol();
- /* use CompleteBoard or CompleteBoardAndGroup ? */
- CompleteBoard(ANSI_COLOR(7) "¡i ¼W¥[§Úªº³Ì·R ¡j" ANSI_RESET "\n"
- "½Ð¿é¤J±ý¥[¤Jªº¬ÝªO¦WºÙ(«öªÅ¥ÕÁä¦Û°Ê·j´M)¡G",
- bname);
-
- if (bname[0] && (bid = getbnum(bname)) &&
- HasBoardPerm(getbcache(bid))) {
- fav_type_t * ptr = getboard(bid);
- if (ptr != NULL) { // already in fav list
- // move curser to item
- for (num = 0; num<nbrdsize && bid != nbrd[num].bid; ++num);
- assert(bid==nbrd[num].bid);
- } else {
- ptr = fav_add_board(bid);
-
- if (ptr == NULL)
- vmsg("§Aªº³Ì·R¤Ó¦h¤F°Õ ¯uªá¤ß");
- else {
- ptr->attr |= NBRD_FAV;
-
- if (ch == 'i' && get_data_number(get_current_fav()) > 1)
- move_in_current_folder(brdnum, num);
- else
- num = brdnum;
- }
- }
- }
- }
- brdnum = -1;
- head = 9999;
- break;
-
- case 'w':
- /* allowing save BRC/fav once per 10 minutes */
- if (now - last_save_fav_and_brc > 10 * 60) {
- fav_save();
- brc_finalize();
-
- last_save_fav_and_brc = now;
- }
- break;
-
- ///////////////////////////////////////////////////////
- // Administrator Only
- ///////////////////////////////////////////////////////
-
- case 'F':
- case 'f':
- if (HasUserPerm(PERM_SYSOP)) {
- getbcache(class_bid)->firstchild[cuser.uflag & BRDSORT_FLAG ? 1 : 0] = 0;
- brdnum = -1;
- }
- break;
- case 'D':
- if (HasUserPerm(PERM_SYSOP) ||
- (HasUserPerm(PERM_SYSSUPERSUBOP) && GROUPOP())) {
- assert(0<=num && num<nbrdsize);
- ptr = &nbrd[num];
- if (ptr->myattr & NBRD_SYMBOLIC) {
- if (getans("½T©w§R°£³sµ²¡H[N/y]") == 'y')
- delete_symbolic_link(getbcache(ptr->bid), ptr->bid);
- }
- brdnum = -1;
- }
- break;
- case 'E':
- if (HasUserPerm(PERM_SYSOP | PERM_BOARD) || GROUPOP()) {
- assert(0<=num && num<nbrdsize);
- ptr = &nbrd[num];
- move(1, 1);
- clrtobot();
- m_mod_board(B_BH(ptr)->brdname);
- brdnum = -1;
- }
- break;
- case 'R':
- if (HasUserPerm(PERM_SYSOP) || GROUPOP()) {
- m_newbrd(class_bid, 1);
- brdnum = -1;
- }
- break;
- case 'B':
- if (HasUserPerm(PERM_SYSOP) || GROUPOP()) {
- m_newbrd(class_bid, 0);
- brdnum = -1;
- }
- break;
- case 'W':
- if (IN_SUBCLASS() &&
- (HasUserPerm(PERM_SYSOP) || GROUPOP())) {
- setbpath(buf, getbcache(class_bid)->brdname);
- mkdir(buf, 0755); /* Ptt:¶}¸s²Õ¥Ø¿ý */
- b_note_edit_bname(class_bid);
- brdnum = -1;
- }
- break;
-
- }
- } while (ch != 'q');
- free(nbrd);
- nbrd = NULL;
- nbrdsize = 0;
- --choose_board_depth;
-}
-
-int
-Class(void)
-{
- init_brdbuf();
- class_bid = 1;
- LIST_BRD();
- choose_board(0);
- return 0;
-}
-
-int
-Favorite(void)
-{
- init_brdbuf();
- class_bid = 0;
- LIST_FAV();
- choose_board(0);
- return 0;
-}
-
-
-int
-New(void)
-{
- int mode0 = currutmp->mode;
- int stat0 = currstat;
-
- class_bid = 0;
- init_brdbuf();
- choose_board(1);
- currutmp->mode = mode0;
- currstat = stat0;
- return 0;
-}
diff --git a/mbbsd/brc.c b/mbbsd/brc.c
deleted file mode 100644
index 4317dfd1..00000000
--- a/mbbsd/brc.c
+++ /dev/null
@@ -1,596 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-/**
- * Ãö©ó¥»Àɮתº²Ó¸`¡A½Ð¨£ docs/brc.txt¡C
- * v3: add last modified time for comment system. double max size.
- * original time_t as 'create'.
- */
-
-// WARNING: Check ../pttbbs.conf, you may have overide these value there
-// TODO MAXSIZE may be better smaller to fit into memory page.
-#ifndef BRC_MAXNUM
-#define BRC_MAXSIZE 49152 /* Effective size of brc rc file, 8192 * 3 * 2 */
-#define BRC_MAXNUM 80 /* Upper bound of brc_num, size of brc_list */
-#endif
-
-#define BRC_BLOCKSIZE 1024
-
-// Note: BRC v3 should already support MAX_BOARD > 65535 and BRC_MAXSIZE > 65535,
-// but not widely tested yet.
-#if MAX_BOARD > 65535 || BRC_MAXSIZE > 65535
-#error Max number of boards or BRC_MAXSIZE cannot fit in unsigned short, \
-please rewrite brc.c (v2)
-#endif
-
-typedef uint32_t brcbid_t;
-typedef uint16_t brcnbrd_t;
-
-typedef struct {
- time4_t create;
- time4_t modified;
-} brc_rec;
-
-/* old brc rc file form:
- * board_name 15 bytes
- * brc_num 1 byte, binary integer
- * brc_list brc_num * sizeof(brc_rec) bytes */
-
-static char brc_initialized = 0;
-static time4_t brc_expire_time;
- /* Will be set to the time one year before login. All the files created
- * before then will be recognized read. */
-
-static int brc_changed = 0; /**< brc_list/brc_num changed */
-/* The below two will be filled by read_brc_buf() and brc_update() */
-static char *brc_buf = NULL;
-static int brc_size;
-static int brc_alloc;
-
-// read records for currbid
-static int brc_currbid;
-static int brc_num;
-static brc_rec brc_list[BRC_MAXNUM];
-
-static char * const fn_brc2= ".brc2";
-static char * const fn_brc = ".brc3";
-
-/**
- * find read records of bid in given buffer region
- *
- * @param[in] begin
- * @param[in] endp
- * @param bid
- * @param[out] num number of records, which could be written for \a bid
- * = brc_num if found
- * = 0 or dangling size if not found
- *
- * @return address of record. \a begin <= addr < \a endp.
- * 0 if not found
- */
-/* Returns the address of the record strictly between begin and endp with
- * bid equal to the parameter. Returns 0 if not found.
- * brcnbrd_t *num is an output parameter which will filled with brc_num
- * if the record is found. If not found the record, *num will be the number
- * of dangling bytes. */
-static char *
-brc_findrecord_in(char *begin, char *endp, brcbid_t bid, brcnbrd_t *num)
-{
- char *tmpp, *ptr = begin;
- brcbid_t tbid;
- while (ptr + sizeof(brcbid_t) + sizeof(brcnbrd_t) < endp) {
- /* for each available records */
- tmpp = ptr;
- tbid = *(brcbid_t*)tmpp;
- tmpp += sizeof(brcbid_t);
- *num = *(brcnbrd_t*)tmpp;
- tmpp += sizeof(brcnbrd_t) + *num * sizeof(brc_rec); /* end of record */
-
- if ( tmpp > endp ){
- /* dangling, ignore the trailing data */
- *num = (brcnbrd_t)(endp - ptr); /* for brc_insert_record() */
- return 0;
- }
- if ( tbid == bid )
- return ptr;
- ptr = tmpp;
- }
-
- *num = 0;
- return 0;
-}
-
-static brc_rec *
-brc_find_record(int bid, int *num)
-{
- char *p;
- brcnbrd_t tnum;
- p = brc_findrecord_in(brc_buf, brc_buf + brc_size, bid, &tnum);
- *num = tnum;
- if (p)
- return (brc_rec*)(p + sizeof(brcbid_t) + sizeof(brcnbrd_t));
- *num = 0;
- return 0;
-}
-
-static char *
-brc_putrecord(char *ptr, char *endp, brcbid_t bid,
- brcnbrd_t num, const brc_rec *list)
-{
- char * tmp;
- if (num > 0 && list[0].create > brc_expire_time &&
- ptr + sizeof(brcbid_t) + sizeof(brcnbrd_t) < endp) {
- if (num > BRC_MAXNUM)
- num = BRC_MAXNUM;
-
- if (num == 0) return ptr;
-
- *(brcbid_t*)ptr = bid; /* write in bid */
- ptr += sizeof(brcbid_t);
- *(brcnbrd_t*)ptr = num; /* write in brc_num */
- ptr += sizeof(brcnbrd_t);
- tmp = ptr + num * sizeof(brc_rec);
- if (tmp <= endp)
- memcpy(ptr, list, num * sizeof(brc_rec)); /* write in brc_list */
- ptr = tmp;
- }
- return ptr;
-}
-
-static inline int
-brc_enlarge_buf(void)
-{
- char *buffer;
- if (brc_alloc >= BRC_MAXSIZE)
- return 0;
-
-#ifdef CRITICAL_MEMORY
-#define THE_MALLOC(X) MALLOC(X)
-#define THE_FREE(X) FREE(X)
-#else
-#define THE_MALLOC(X) alloca(X)
-#define THE_FREE(X) (void)(X)
- /* alloca get memory from stack and automatically freed when
- * function returns. */
-#endif
-
- buffer = (char*)THE_MALLOC(brc_alloc);
- assert(buffer);
-
- memcpy(buffer, brc_buf, brc_alloc);
- free(brc_buf);
- brc_alloc += BRC_BLOCKSIZE;
- brc_buf = (char*)malloc(brc_alloc);
- assert(brc_buf);
- memcpy(brc_buf, buffer, brc_alloc - BRC_BLOCKSIZE);
-
-#ifdef DEBUG
- vmsgf("brc enlarged to %d bytes", brc_alloc);
-#endif
-
- THE_FREE(buffer);
- return 1;
-
-#undef THE_MALLOC
-#undef THE_FREE
-}
-
-static inline void
-brc_get_buf(int size){
- if (!size)
- brc_alloc = BRC_BLOCKSIZE;
- else
- brc_alloc = (size + BRC_BLOCKSIZE - 1) / BRC_BLOCKSIZE * BRC_BLOCKSIZE;
- if (brc_alloc > BRC_MAXSIZE)
- brc_alloc = BRC_MAXSIZE;
- brc_buf = (char*)malloc(brc_alloc);
- assert(brc_buf);
-}
-
-static inline void
-brc_insert_record(brcbid_t bid, brcnbrd_t num, const brc_rec* list)
-{
- char *ptr;
- int new_size, end_size;
- brcnbrd_t tnum;
-
- ptr = brc_findrecord_in(brc_buf, brc_buf + brc_size, bid, &tnum);
-
- while (num > 0 && list[num - 1].create < brc_expire_time)
- num--; /* don't write the times before brc_expire_time */
-
- if (!ptr) {
- brc_size -= (int)tnum;
-
- /* put on the beginning */
- if (num){
- new_size = sizeof(brcbid_t) + sizeof(brcnbrd_t)
- + num * sizeof(brc_rec);
- brc_size += new_size;
- if (brc_size > brc_alloc && !brc_enlarge_buf())
- brc_size = BRC_MAXSIZE;
- if (brc_size > new_size)
- memmove(brc_buf + new_size, brc_buf, brc_size - new_size);
- brc_putrecord(brc_buf, brc_buf + new_size, bid, num, list);
- }
- } else {
- /* ptr points to the old current brc list.
- * tmpp is the end of it (exclusive). */
- int len = sizeof(brcbid_t) + sizeof(brcnbrd_t) + tnum * sizeof(brc_rec);
- char *tmpp = ptr + len;
- end_size = brc_buf + brc_size - tmpp;
- if (num) {
- int sindex = ptr - brc_buf;
- new_size = (sizeof(brcbid_t) + sizeof(brcnbrd_t)
- + num * sizeof(brc_rec));
- brc_size += new_size - len;
- if (brc_size > brc_alloc) {
- if (brc_enlarge_buf()) {
- ptr = brc_buf + sindex;
- tmpp = ptr + len;
- } else {
- end_size -= brc_size - BRC_MAXSIZE;
- brc_size = BRC_MAXSIZE;
- }
- }
- if (end_size > 0 && ptr + new_size != tmpp)
- memmove(ptr + new_size, tmpp, end_size);
- brc_putrecord(ptr, brc_buf + brc_alloc, bid, num, list);
- } else { /* deleting record */
- memmove(ptr, tmpp, end_size);
- brc_size -= len;
- }
- }
-
- brc_changed = 0;
-}
-
-/**
- * write \a brc_num and \a brc_list back to \a brc_buf.
- */
-void
-brc_update(){
- if (brc_currbid && brc_changed && cuser.userlevel && brc_num > 0) {
- brc_initialize();
- brc_insert_record(brc_currbid, brc_num, brc_list);
- }
-}
-
-void
-read_brc2(void)
-{
- char brcfile[STRLEN];
- int fd;
- size_t sz2 = 0, sz3 = 0;
- char *cvt = NULL, *cvthead = NULL;
-
- // brc v2 is using 16 bit for brcbid_t and brcnbrd_t.
- uint16_t bid2, num2;
-
- brcbid_t bid;
- brcnbrd_t num;
- time4_t create;
- brc_rec rec;
-
- setuserfile(brcfile, fn_brc2);
-
- if ((fd = open(brcfile, O_RDONLY)) == -1)
- return;
-
- sz2 = dashs(brcfile);
- sz3 = sz2 * 2; // max double size
-
- cvthead = cvt = malloc (sz3);
- memset(cvthead, 0, sz3);
- // now calculate real sz3
-
- while (read(fd, &bid2, sizeof(bid2)) > 0)
- {
- if (read(fd, &num2, sizeof(num2)) < 1)
- break;
-
- bid = bid2;
- num = num2;
-
- // some brc v2 contains bad structure.
- // check pointer here.
- if (cvt + sizeof(brcbid_t) + sizeof(brcnbrd_t) - cvthead >= sz3)
- break;
-
- *(brcbid_t*) cvt = bid; cvt += sizeof(brcbid_t);
- *(brcnbrd_t*)cvt = num; cvt += sizeof(brcnbrd_t);
-
- // some brc v2 contains bad structure.
- // check pointer here.
- for (; num > 0 && (cvt + sizeof(brc_rec) - cvthead) <= sz3 ; num--)
- {
- if (read(fd, &create, sizeof(create)) < 1)
- break;
-
- rec.create = create;
- rec.modified = create;
-
- *(brc_rec*)cvt = rec; cvt += sizeof(brc_rec);
- }
- }
- close(fd);
-
- // now cvthead is ready for v3.
- sz3 = cvt - cvthead;
- brc_get_buf(sz3);
- // new size maybe smaller, check brc_alloc instead
- if (sz3 > brc_alloc)
- sz3 = brc_alloc;
- brc_size = sz3;
- memcpy(brc_buf, cvthead, sz3);
-
- free(cvthead);
-}
-
-inline static void
-read_brc_buf(void)
-{
- char brcfile[STRLEN];
- int fd;
- struct stat brcstat;
-
- if (brc_buf != NULL)
- return;
-
- brc_size = 0;
- setuserfile(brcfile, fn_brc);
-
- if ((fd = open(brcfile, O_RDONLY)) == -1)
- {
- read_brc2();
- return;
- }
-
- fstat(fd, &brcstat);
- brc_get_buf(brcstat.st_size);
- brc_size = read(fd, brc_buf, brc_alloc);
- close(fd);
-}
-
-/* release allocated memory
- *
- * Do not destory brc_currbid, brc_num, brc_list.
- */
-void
-brc_release()
-{
- if (brc_buf) {
- free(brc_buf);
- brc_buf = NULL;
- }
- brc_changed = 0;
- brc_size = brc_alloc = 0;
-}
-
-void
-brc_finalize(){
- char brcfile[STRLEN];
- char tmpfile[STRLEN];
-
- if(!brc_initialized)
- return;
-
- brc_update();
- setuserfile(brcfile, fn_brc);
- snprintf(tmpfile, sizeof(tmpfile), "%s.tmp.%x", brcfile, getpid());
- if (brc_buf != NULL) {
- int fd = open(tmpfile, O_WRONLY | O_CREAT | O_TRUNC, 0644);
- if (fd != -1) {
- int ok=0;
- if(write(fd, brc_buf, brc_size)==brc_size)
- ok=1;
- close(fd);
- if(ok)
- Rename(tmpfile, brcfile);
- else
- unlink(tmpfile);
- }
- }
-
- brc_release();
- brc_initialized = 0;
-}
-
-int
-brc_initialize(){
- if (brc_initialized)
- return 1;
- brc_initialized = 1;
- brc_expire_time = login_start_time - 365 * 86400;
- read_brc_buf();
- return 0;
-}
-
-/**
- * get the read records for bid
- *
- * @param bid
- * @param[out] num number of record for \a bid. 1 <= \a num <= \a BRC_MAXNUM
- * \a num = 1 if no records.
- * @param[out] list the list of records, length \a num
- *
- * @return number of read record, 0 if no records
- */
-static int
-brc_read_record(int bid, int *num, brc_rec *list){
- char *ptr;
- brcnbrd_t tnum;
- ptr = brc_findrecord_in(brc_buf, brc_buf + brc_size, bid, &tnum);
- *num = tnum;
- if ( ptr ){
- assert(0 <= *num && *num <= BRC_MAXNUM);
- memcpy(list, ptr + sizeof(brcbid_t) + sizeof(brcnbrd_t),
- *num * sizeof(brc_rec));
- return *num;
- }
- list[0].create = *num = 1;
- return 0;
-}
-
-/**
- * @return number of records in \a boardname
- */
-int
-brc_initial_board(const char *boardname)
-{
- brc_initialize();
-
- if (strcmp(currboard, boardname) == 0) {
- assert(currbid == brc_currbid);
- return brc_num;
- }
-
- brc_update(); /* write back first */
- currbid = getbnum(boardname);
- if( currbid == 0 )
- currbid = getbnum(DEFAULT_BOARD);
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- brc_currbid = currbid;
- currboard = bcache[currbid - 1].brdname;
- currbrdattr = bcache[currbid - 1].brdattr;
-
- return brc_read_record(brc_currbid, &brc_num, brc_list);
-}
-
-static void
-brc_trunc(int bid, time4_t ftime){
- brc_rec r;
-
- r.create = ftime;
- r.modified = ftime;
- brc_insert_record(bid, 1, &r);
- if ( bid == brc_currbid ){
- brc_num = 1;
- brc_list[0] = r;
- brc_changed = 0;
- }
-}
-
-void
-brc_toggle_all_read(int bid, int is_all_read)
-{
- brc_initialize();
- if (is_all_read)
- brc_trunc(bid, now);
- else
- brc_trunc(bid, 1);
-}
-
-void
-brc_addlist(const char *fname, time4_t modified)
-{
- int n, i;
- brc_rec frec;
-
- assert(currbid == brc_currbid);
- if (!cuser.userlevel)
- return;
- brc_initialize();
-
- frec.create = atoi(&fname[2]);
- frec.modified = modified;
-
- if (frec.create <= brc_expire_time /* too old, don't do any thing */
- /* || fname[0] != 'M' || fname[1] != '.' */ ) {
- return;
- }
- if (brc_num <= 0) { /* uninitialized */
- brc_list[0] = frec;
- brc_num = 1;
- brc_changed = 1;
- return;
- }
- if ((brc_num == 1) && (frec.create < brc_list[0].create)) /* most when after 'v' */
- return;
- for (n = 0; n < brc_num; n++) { /* using linear search */
- if (frec.create == brc_list[n].create) {
- // check if we got bad value.
- if (modified == (time4_t)-1)
- return;
-
- if (brc_list[n].modified == (time4_t)-1)
- brc_list[n].modified = 0;
-
- // special case here:
- // in order to support special system like 'always bottom',
- // they may share same create time and different time.
- if (brc_list[n].modified < modified)
- {
- brc_list[n].modified = modified;
- brc_changed = 1;
- }
- return;
- } else if (frec.create > brc_list[n].create) {
- if (brc_num < BRC_MAXNUM)
- brc_num++;
- /* insert frec into brc_list */
- for (i = brc_num - 1; --i >= n; brc_list[i + 1] = brc_list[i]);
- brc_list[n] = frec;
- brc_changed = 1;
- return;
- }
- }
-}
-
-// return:
-// 0 - read
-// 1 - unread (by create)
-// 2 - unread (by modified)
-int
-brc_unread_time(int bid, time4_t ftime, time4_t modified)
-{
- int i;
- int bnum;
- const brc_rec *blist;
-
- brc_initialize();
- if (ftime <= brc_expire_time) /* too old */
- return 0;
-
- if (brc_currbid && bid == brc_currbid) {
- blist = brc_list;
- bnum = brc_num;
- } else {
- blist = brc_find_record(bid, &bnum);
- }
-
- if (bnum <= 0)
- return 1;
-
- for (i = 0; i < bnum; i++) { /* using linear search */
- if (ftime > blist[i].create)
- return 1;
- else if (ftime == blist[i].create)
- {
- time4_t brcm = blist[i].modified;
- if (modified == 0 || brcm == 0)
- return 0;
-
- // bad case... seems like that someone is making -1.
- if (modified == (time4_t)-1 || brcm == (time4_t)-1)
- return 0;
-
- // one case is, some special file headers (ex,
- // always bottom) may cause issue. They share create
- // time (filename) and apply different modify time.
- // so let's back to 'greater'.
- return modified > brcm ? 2 : 0;
- }
- }
- return 0;
-}
-
-int
-brc_unread(int bid, const char *fname, time4_t modified)
-{
- int ftime;
-
- ftime = atoi(&fname[2]); /* this will get the time of the file created */
-
- return brc_unread_time(bid, ftime, modified);
-}
diff --git a/mbbsd/cache.c b/mbbsd/cache.c
deleted file mode 100644
index 5a30c24f..00000000
--- a/mbbsd/cache.c
+++ /dev/null
@@ -1,1215 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-#ifdef _BBS_UTIL_C_
-# define log_usies(a, b) ;
-# define abort_bbs(a) exit(1)
-#endif
-/*
- * 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 int retv;
- log_usies("SAFE_SLEEP ", "avoid hang");
- sigemptyset(&set);
- sigaddset(&set, SIGALRM);
- sigprocmask(SIG_UNBLOCK, &set, NULL);
- retv = sleep(seconds);
- sigprocmask(SIG_BLOCK, &set, NULL);
- return retv;
- }
- return sleep(seconds);
-}
-
-/*
- * section - SHM
- */
-static void
-attach_err(int shmkey, const 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 = (void *)NULL;
- int shmid;
-
- shmid = shmget(shmkey, shmsize,
-#ifdef USE_HUGETLB
- SHM_HUGETLB |
-#endif
- 0);
- if (shmid < 0) {
- // SHM should be created by uhash_loader, NOT mbbsd or other utils
- attach_err(shmkey, "shmget");
- } else {
- shmptr = (void *)shmat(shmid, NULL, 0);
- if (shmptr == (void *)-1)
- attach_err(shmkey, "shmat");
- }
-
- return shmptr;
-}
-
-void
-attach_SHM(void)
-{
- SHM = attach_shm(SHM_KEY, SHMSIZE);
- if(SHM->version != SHM_VERSION) {
- fprintf(stderr, "Error: SHM->version(%d) != SHM_VERSION(%d)\n", SHM->version, SHM_VERSION);
- fprintf(stderr, "Please use the source code version corresponding to SHM,\n"
- "or use ipcrm(1) command to clean share memory.\n");
- exit(1);
- }
- if (!SHM->loaded) /* (uhash) assume fresh shared memory is
- * zeroed */
- exit(1);
- if (SHM->Btouchtime == 0)
- SHM->Btouchtime = 1;
- bcache = SHM->bcache;
- numboards = SHM->Bnumber;
-
- if (SHM->Ptouchtime == 0)
- SHM->Ptouchtime = 1;
-
- if (SHM->Ftouchtime == 0)
- SHM->Ftouchtime = 1;
-}
-
-/* ----------------------------------------------------- */
-/* semaphore : for critical section */
-/* ----------------------------------------------------- */
-#define SEM_FLG 0600 /* semaphore mode */
-
-#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
-
-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;
- if (semop(semid, &sops, 1)) {
- perror("semop");
- exit(1);
- }
-}
-
-/*
- * section - user cache(including uhash)
- */
-/* 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.
- */
-
-void
-add_to_uhash(int n, const char *id)
-{
- int *p, h = StringHash(id)%(1<<HASH_BITS);
- int times;
- strlcpy(SHM->userid[n], id, sizeof(SHM->userid[n]));
-
- p = &(SHM->hash_head[h]);
-
- for (times = 0; times < MAX_USERS && *p != -1; ++times)
- p = &(SHM->next_in_hash[*p]);
-
- if (times == MAX_USERS)
- abort_bbs(0);
-
- SHM->next_in_hash[*p = n] = -1;
-}
-
-void
-remove_from_uhash(int n)
-{
-/*
- * note: after remove_from_uhash(), you should add_to_uhash() (likely with a
- * different name)
- */
- int h = StringHash(SHM->userid[n])%(1<<HASH_BITS);
- int *p = &(SHM->hash_head[h]);
- int times;
-
- for (times = 0; times < MAX_USERS && (*p != -1 && *p != n); ++times)
- p = &(SHM->next_in_hash[*p]);
-
- if (times == MAX_USERS)
- abort_bbs(0);
-
- if (*p == n)
- *p = SHM->next_in_hash[n];
-}
-
-#if (1<<HASH_BITS)*10 < MAX_USERS
-#warning "Suggest to use bigger HASH_BITS for better searchuser() performance,"
-#warning "searchuser() average chaining MAX_USERS/(1<<HASH_BITS) times."
-#endif
-int
-dosearchuser(const char *userid, char *rightid)
-{
- int h, p, times;
- STATINC(STAT_SEARCHUSER);
- h = StringHash(userid)%(1<<HASH_BITS);
- p = SHM->hash_head[h];
-
- for (times = 0; times < MAX_USERS && p != -1 && p < MAX_USERS ; ++times) {
- if (strcasecmp(SHM->userid[p], userid) == 0) {
- if(userid[0] && rightid) strcpy(rightid, SHM->userid[p]);
- return p + 1;
- }
- p = SHM->next_in_hash[p];
- }
-
- return 0;
-}
-
-int
-searchuser(const char *userid, char *rightid)
-{
- if(userid[0]=='\0')
- return 0;
- return dosearchuser(userid, rightid);
-}
-
-int
-getuser(const char *userid, userec_t *xuser)
-{
- int uid;
-
- if ((uid = searchuser(userid, NULL))) {
- passwd_query(uid, xuser);
- xuser->money = moneyof(uid);
- }
- return uid;
-}
-
-char *
-getuserid(int num)
-{
- if (--num >= 0 && num < MAX_USERS)
- return ((char *)SHM->userid[num]);
- return NULL;
-}
-
-void
-setuserid(int num, const char *userid)
-{
- if (num > 0 && num <= MAX_USERS) {
-/* Ptt: it may cause problems
- if (num > SHM->number)
- SHM->number = num;
- else
-*/
- remove_from_uhash(num - 1);
- add_to_uhash(num - 1, userid);
- }
-}
-
-#ifndef _BBS_UTIL_C_
-char *
-u_namearray(char buf[][IDLEN + 1], int *pnum, char *tag)
-{
- register char *ptr, tmp;
- register int n, total;
- char tagbuf[STRLEN];
- int ch, ch2, num;
-
- if (*tag == '\0') {
- *pnum = SHM->number;
- return SHM->userid[0];
- }
- for (n = 0; tag[n]; n++)
- tagbuf[n] = chartoupper(tag[n]);
- tagbuf[n] = '\0';
- ch = tagbuf[0];
- ch2 = ch - 'A' + 'a';
- total = SHM->number;
- for (n = num = 0; n < total; n++) {
- ptr = SHM->userid[n];
- tmp = *ptr;
- if (tmp == ch || tmp == ch2) {
- if (chkstr(tag, tagbuf, ptr))
- strcpy(buf[num++], ptr);
- }
- }
- *pnum = num;
- return buf[0];
-}
-#endif
-
-void
-getnewutmpent(const userinfo_t * up)
-{
-/* Ptt:³o¸Ì¥[¤W hash Æ[©À§äªÅªº utmp */
- register int i;
- register userinfo_t *uentp;
- unsigned int p = StringHash(up->userid) % USHM_SIZE;
- for (i = 0; i < USHM_SIZE; i++, p++) {
- if (p == USHM_SIZE)
- p = 0;
- uentp = &(SHM->uinfo[p]);
- if (!(uentp->pid)) {
- memcpy(uentp, up, sizeof(userinfo_t));
- currutmp = uentp;
- return;
- }
- }
- exit(1);
-}
-
-int
-apply_ulist(int (*fptr) (const userinfo_t *))
-{
- register userinfo_t *uentp;
- register int i, state;
-
- for (i = 0; i < USHM_SIZE; i++) {
- uentp = &(SHM->uinfo[i]);
- if (uentp->pid && (PERM_HIDE(currutmp) || !PERM_HIDE(uentp)))
- if ((state = (*fptr) (uentp)))
- return state;
- }
- return 0;
-}
-
-userinfo_t *
-search_ulist_pid(int pid)
-{
- register int i = 0, j, start = 0, end = SHM->UTMPnumber - 1;
- int *ulist;
- register userinfo_t *u;
- if (end == -1)
- return NULL;
- ulist = SHM->sorted[SHM->currsorted][8];
- for (i = ((start + end) / 2);; i = (start + end) / 2) {
- u = &SHM->uinfo[ulist[i]];
- j = pid - u->pid;
- if (!j) {
- return u;
- }
- if (end == start) {
- break;
- } else if (i == start) {
- i = end;
- start = end;
- } else if (j > 0)
- start = i;
- else
- end = i;
- }
- return 0;
-}
-
-userinfo_t *
-search_ulistn(int uid, int unum)
-{
- register int i = 0, j, start = 0, end = SHM->UTMPnumber - 1;
- int *ulist;
- register userinfo_t *u;
- if (end == -1)
- return NULL;
- ulist = SHM->sorted[SHM->currsorted][7];
- for (i = ((start + end) / 2);; i = (start + end) / 2) {
- u = &SHM->uinfo[ulist[i]];
- j = uid - u->uid;
- if (j == 0) {
- for (; i > 0 && uid == SHM->uinfo[ulist[i - 1]].uid; --i)
- ;/* «ü¨ì²Ä¤@µ§ */
- // piaip Tue Jan 8 09:28:03 CST 2008
- // many people bugged about that their utmp have invalid
- // entry on record.
- // we found them caused by crash process (DEBUGSLEEPING) which
- // may occupy utmp entries even after process was killed.
- // because the memory is invalid, it is not safe for those process
- // to wipe their utmp entry. it should be done by some external
- // daemon.
- // however, let's make a little workaround here...
- for (; unum > 0 && i >= 0 && ulist[i] >= 0 &&
- SHM->uinfo[ulist[i]].uid == uid; unum--, i++)
- {
- if (SHM->uinfo[ulist[i]].mode == DEBUGSLEEPING)
- unum ++;
- }
- if (unum == 0 && i > 0 && ulist[i-1] >= 0 &&
- SHM->uinfo[ulist[i-1]].uid == uid)
- return &SHM->uinfo[ulist[i-1]];
- /*
- if ( i + unum - 1 >= 0 &&
- (ulist[i + unum - 1] >= 0 &&
- uid == SHM->uinfo[ulist[i + unum - 1]].uid ) )
- return &SHM->uinfo[ulist[i + unum - 1]];
- */
- break; /* ¶W¹L½d³ò */
- }
- if (end == start) {
- break;
- } else if (i == start) {
- i = end;
- start = end;
- } else if (j > 0)
- start = i;
- else
- end = i;
- }
- return 0;
-}
-
-userinfo_t *
-search_ulist_userid(const char *userid)
-{
- register int i = 0, j, start = 0, end = SHM->UTMPnumber - 1;
- int *ulist;
- register userinfo_t * u;
- if (end == -1)
- return NULL;
- ulist = SHM->sorted[SHM->currsorted][0];
- for (i = ((start + end) / 2);; i = (start + end) / 2) {
- u = &SHM->uinfo[ulist[i]];
- j = strcasecmp(userid, u->userid);
- if (!j) {
- return u;
- }
- if (end == start) {
- break;
- } else if (i == start) {
- i = end;
- start = end;
- } else if (j > 0)
- start = i;
- else
- end = i;
- }
- return 0;
-}
-
-#ifndef _BBS_UTIL_C_
-int
-count_logins(int uid, int show)
-{
- register int i = 0, j, start = 0, end = SHM->UTMPnumber - 1, count;
- int *ulist;
- userinfo_t *u;
- if (end == -1)
- return 0;
- ulist = SHM->sorted[SHM->currsorted][7];
- for (i = ((start + end) / 2);; i = (start + end) / 2) {
- u = &SHM->uinfo[ulist[i]];
- j = uid - u->uid;
- if (!j) {
- for (; i > 0 && uid == SHM->uinfo[ulist[i - 1]].uid; i--);
- /* «ü¨ì²Ä¤@µ§ */
- for (count = 0; (ulist[i + count] &&
- (u = &SHM->uinfo[ulist[i + count]]) &&
- uid == u->uid); count++) {
- if (show)
- prints("(%d) ¥Ø«eª¬ºA¬°: %-17.16s(¨Ó¦Û %s)\n",
- count + 1, modestring(u, 0),
- u->from);
- }
- return count;
- }
- if (end == start) {
- break;
- } else if (i == start) {
- i = end;
- start = end;
- } else if (j > 0)
- start = i;
- else
- end = i;
- }
- return 0;
-}
-
-void
-purge_utmp(userinfo_t * uentp)
-{
- logout_friend_online(uentp);
- memset(uentp, 0, sizeof(userinfo_t));
- SHM->UTMPneedsort = 1;
-}
-#endif
-
-/*
- * section - money cache
- */
-int
-setumoney(int uid, int money)
-{
- SHM->money[uid - 1] = money;
- passwd_update_money(uid);
- return SHM->money[uid - 1];
-}
-
-int
-deumoney(int uid, int money)
-{
- if (uid <= 0 || uid > MAX_USERS){
-#if defined(_BBS_UTIL_C_)
- printf("internal error: deumoney(%d, %d)\n", uid, money);
-#else
- vmsg("internal error");
-#endif
- return -1;
- }
-
- if (money < 0 && moneyof(uid) < -money)
- return setumoney(uid, 0);
- else
- return setumoney(uid, SHM->money[uid - 1] + money);
-}
-
-/*
- * section - utmp
- */
-#if !defined(_BBS_UTIL_C_) /* _BBS_UTIL_C_ ¤£·|¦³ utmp */
-void
-setutmpmode(unsigned int mode)
-{
- if (currstat != mode)
- currutmp->mode = currstat = mode;
- /* °lÂÜ¨Ï¥ÎªÌ */
- if (HasUserPerm(PERM_LOGUSER)) {
- log_user("setutmpmode to %s(%d)\n", modestring(currutmp, 0), mode);
- }
-}
-
-unsigned int
-getutmpmode(void)
-{
- if (currutmp)
- return currutmp->mode;
- return currstat;
-}
-#endif
-
-/*
- * section - board cache
- */
-void touchbtotal(int bid) {
- assert(0<=bid-1 && bid-1<MAX_BOARD);
- SHM->total[bid - 1] = 0;
- SHM->lastposttime[bid - 1] = 0;
-}
-
-
-/**
- * qsort comparison function - ·ÓªO¦W±Æ§Ç
- */
-static int
-cmpboardname(const void * i, const void * j)
-{
- return strcasecmp(bcache[*(int*)i].brdname, bcache[*(int*)j].brdname);
-}
-
-/**
- * qsort comparison function - ¥ý·Ó¸s²Õ±Æ§Ç¡B¦P¤@­Ó¸s²Õ¤º¨ÌªO¦W±Æ
- */
-static int
-cmpboardclass(const void * i, const void * j)
-{
- boardheader_t *brd1 = &bcache[*(int*)i], *brd2 = &bcache[*(int*)j];
- int cmp;
-
- cmp=strncmp(brd1->title, brd2->title, 4);
- if(cmp!=0) return cmp;
- return strcasecmp(brd1->brdname, brd2->brdname);
-}
-
-
-void
-sort_bcache(void)
-{
- int i;
- /* critical section ºÉ¶q¤£­n©I¥s */
- /* ¥u¦³·s¼W ©Î²¾°£¬ÝªO »Ý­n©I¥s¨ì */
- if(SHM->Bbusystate) {
- sleep(1);
- return;
- }
- SHM->Bbusystate = 1;
- for (i = 0; i < SHM->Bnumber; i++) {
- SHM->bsorted[0][i] = SHM->bsorted[1][i] = i;
- }
- qsort(SHM->bsorted[0], SHM->Bnumber, sizeof(int), cmpboardname);
- qsort(SHM->bsorted[1], SHM->Bnumber, sizeof(int), cmpboardclass);
-
- for (i = 0; i < SHM->Bnumber; i++) {
- bcache[i].firstchild[0] = 0;
- bcache[i].firstchild[1] = 0;
- }
- SHM->Bbusystate = 0;
-}
-
-#ifdef _BBS_UTIL_C_
-void
-reload_bcache(void)
-{
- int i, fd;
- pid_t pid;
- for( i = 0 ; i < 10 && SHM->Bbusystate ; ++i ){
- printf("SHM->Bbusystate is currently locked (value: %d). "
- "please wait... ", SHM->Bbusystate);
- sleep(1);
- }
-
- SHM->Bbusystate = 1;
- if ((fd = open(fn_board, O_RDONLY)) > 0) {
- SHM->Bnumber =
- read(fd, bcache, MAX_BOARD * sizeof(boardheader_t)) /
- sizeof(boardheader_t);
- close(fd);
- }
- memset(SHM->lastposttime, 0, MAX_BOARD * sizeof(time4_t));
- memset(SHM->total, 0, MAX_BOARD * sizeof(int));
-
- /* µ¥©Ò¦³ boards ¸ê®Æ§ó·s«á¦A³]©w uptime */
- SHM->Buptime = SHM->Btouchtime;
- log_usies("CACHE", "reload bcache");
- SHM->Bbusystate = 0;
- sort_bcache();
-
- printf("load bottom in background");
- if( (pid = fork()) > 0 )
- return;
- setproctitle("loading bottom");
- for( i = 0 ; i < MAX_BOARD ; ++i )
- if( SHM->bcache[i].brdname[0] ){
- char fn[128];
- int n;
- sprintf(fn, "boards/%c/%s/" FN_DIR ".bottom",
- SHM->bcache[i].brdname[0],
- SHM->bcache[i].brdname);
- n = get_num_records(fn, sizeof(fileheader_t));
- if( n > 5 )
- n = 5;
- SHM->n_bottom[i] = n;
- }
- printf("load bottom done");
- if( pid == 0 )
- exit(0);
- // if pid == -1 should be returned
-}
-
-void resolve_boards(void)
-{
- while (SHM->Buptime < SHM->Btouchtime) {
- reload_bcache();
- }
- numboards = SHM->Bnumber;
-}
-#endif /* defined(_BBS_UTIL_C_)*/
-
-#if 0
-/* Unused */
-void touch_boards(void)
-{
- SHM->Btouchtime = COMMON_TIME;
- numboards = -1;
- resolve_boards();
-}
-#endif
-
-void addbrd_touchcache(void)
-{
- SHM->Bnumber++;
- numboards = SHM->Bnumber;
- reset_board(numboards);
- sort_bcache();
-}
-
-void
-reset_board(int bid) /* XXXbid: from 1 */
-{ /* Ptt: ³o¼Ë´N¤£¥Î¦Ñ¬Otouch board¤F */
- int fd;
- boardheader_t *bhdr;
-
- if (--bid < 0)
- return;
- assert(0<=bid && bid<MAX_BOARD);
- if (SHM->Bbusystate || COMMON_TIME - SHM->busystate_b[bid] < 10) {
- safe_sleep(1);
- } else {
- SHM->busystate_b[bid] = COMMON_TIME;
-
- bhdr = bcache;
- bhdr += bid;
- if ((fd = open(fn_board, O_RDONLY)) > 0) {
- lseek(fd, (off_t) (bid * sizeof(boardheader_t)), SEEK_SET);
- read(fd, bhdr, sizeof(boardheader_t));
- close(fd);
- }
- SHM->busystate_b[bid] = 0;
-
- buildBMcache(bid + 1); /* XXXbid */
- }
-}
-
-#ifndef _BBS_UTIL_C_ /* because of HasBoardPerm() in board.c */
-int
-apply_boards(int (*func) (boardheader_t *))
-{
- register int i;
- register boardheader_t *bhdr;
-
- for (i = 0, bhdr = bcache; i < numboards; i++, bhdr++) {
- if (!(bhdr->brdattr & BRD_GROUPBOARD) && HasBoardPerm(bhdr) &&
- (*func) (bhdr) == QUIT)
- return QUIT;
- }
- return 0;
-}
-#endif
-
-void
-setbottomtotal(int bid)
-{
- boardheader_t *bh = getbcache(bid);
- char fname[PATHLEN];
- int n;
-
- assert(0<=bid-1 && bid-1<MAX_BOARD);
- if(!bh->brdname[0]) return;
- setbfile(fname, bh->brdname, FN_DIR ".bottom");
- n = get_num_records(fname, sizeof(fileheader_t));
- if(n>5)
- {
-#ifdef DEBUG_BOTTOM
- log_file("fix_bottom", LOG_CREAT | LOG_VF, "%s n:%d\n", fname, n);
-#endif
- unlink(fname);
- SHM->n_bottom[bid-1]=0;
- }
- else
- SHM->n_bottom[bid-1]=n;
-}
-void
-setbtotal(int bid)
-{
- boardheader_t *bh = getbcache(bid);
- struct stat st;
- char genbuf[256];
- int num, fd;
-
- assert(0<=bid-1 && bid-1<MAX_BOARD);
- setbfile(genbuf, bh->brdname, FN_DIR);
- if ((fd = open(genbuf, O_RDWR)) < 0)
- return; /* .DIR±¾¤F */
- fstat(fd, &st);
- num = st.st_size / sizeof(fileheader_t);
- assert(0<=bid-1 && bid-1<MAX_BOARD);
- SHM->total[bid - 1] = num;
-
- if (num > 0) {
- lseek(fd, (off_t) (num - 1) * sizeof(fileheader_t), SEEK_SET);
- if (read(fd, genbuf, FNLEN) >= 0) {
- SHM->lastposttime[bid - 1] = (time4_t) atoi(&genbuf[2]);
- }
- } else
- SHM->lastposttime[bid - 1] = 0;
- close(fd);
-}
-
-void
-touchbpostnum(int bid, int delta)
-{
- int *total = &SHM->total[bid - 1];
- assert(0<=bid-1 && bid-1<MAX_BOARD);
- if (*total)
- *total += delta;
-}
-
-int
-getbnum(const char *bname)
-{
- register int i = 0, j, start = 0, end = SHM->Bnumber - 1;
- int *blist = SHM->bsorted[0];
- if(SHM->Bbusystate)
- sleep(1);
- for (i = ((start + end) / 2);; i = (start + end) / 2) {
- if (!(j = strcasecmp(bname, bcache[blist[i]].brdname)))
- return (int)(blist[i] + 1);
- if (end == start) {
- break;
- } else if (i == start) {
- i = end;
- start = end;
- } else if (j > 0)
- start = i;
- else
- end = i;
- }
- return 0;
-}
-
-const char *
-postperm_msg(const char *bname)
-{
- register int i;
- char buf[PATHLEN];
- boardheader_t *bp = NULL;
-
- setbfile(buf, bname, fn_water);
- if (belong(buf, cuser.userid))
- return "¨Ï¥ÎªÌ¤ô±í¤¤";
-
- if (!strcasecmp(bname, DEFAULT_BOARD))
- return NULL;
-
- if (!(i = getbnum(bname)))
- return "¬ÝªO¤£¦s¦b";
-
- assert(0<=i-1 && i-1<MAX_BOARD);
- bp = getbcache(i);
-
- if (bp->brdattr & BRD_GUESTPOST)
- return NULL;
-
- if (!HasUserPerm(PERM_POST))
- return "µLµo¤åÅv­­";
-
- /* ¯µ±K¬ÝªO¯S§O³B²z */
- if (bp->brdattr & BRD_HIDE)
- return NULL;
- else if (bp->brdattr & BRD_RESTRICTEDPOST &&
- !is_hidden_board_friend(i, usernum))
- return "¬ÝªO­­¨îµo¤å";
-
- if (HasUserPerm(PERM_VIOLATELAW) && (bp->level & PERM_VIOLATELAW))
- return NULL;
- else if (HasUserPerm(PERM_VIOLATELAW))
- return "»@³æ¥¼Ãº";
-
- if (!(bp->level & ~PERM_POST))
- return NULL;
- if (!HasUserPerm(bp->level & ~PERM_POST))
- return "¥¼¹F¬ÝªO­n¨DÅv­­";
- return NULL;
-}
-
-int
-haspostperm(const char *bname)
-{
- return postperm_msg(bname) == NULL ? 1 : 0;
-}
-
-void buildBMcache(int bid) /* bid starts from 1 */
-{
- char s[IDLEN * 3 + 3], *ptr;
- int i, uid;
- char *strtok_pos;
-
- assert(0<=bid-1 && bid-1<MAX_BOARD);
- strlcpy(s, getbcache(bid)->BM, sizeof(s));
- for( i = 0 ; s[i] != 0 ; ++i )
- if( !isalpha((int)s[i]) && !isdigit((int)s[i]) )
- s[i] = ' ';
-
- for( ptr = strtok_r(s, " ", &strtok_pos), i = 0 ;
- i < MAX_BMs && ptr != NULL ;
- ptr = strtok_r(NULL, " ", &strtok_pos), ++i )
- if( (uid = searchuser(ptr, NULL)) != 0 )
- SHM->BMcache[bid-1][i] = uid;
- for( ; i < MAX_BMs ; ++i )
- SHM->BMcache[bid-1][i] = -1;
-}
-
-int is_BM_cache(int bid) /* bid starts from 1 */
-{
- assert(0<=bid-1 && bid-1<MAX_BOARD);
- --bid;
- // XXX hard coded MAX_BMs=4
- if( currutmp->uid == SHM->BMcache[bid][0] ||
- currutmp->uid == SHM->BMcache[bid][1] ||
- currutmp->uid == SHM->BMcache[bid][2] ||
- currutmp->uid == SHM->BMcache[bid][3] ){
- cuser.userlevel |= PERM_BM;
- return 1;
- }
- return 0;
-}
-
-/*-------------------------------------------------------*/
-/* PTT cache */
-/*-------------------------------------------------------*/
-int
-filter_aggressive(const char*s)
-{
- if (
- /*
- strstr(s, "¦¹³B©ñ¸û¤£¾A·íªºª§Ä³©Ê¦r¥y") != NULL ||
- */
- 0
- )
- return 1;
- return 0;
-}
-
-int
-filter_dirtywords(const char*s)
-{
- if (
- strstr(s, "·F§A®Q") != NULL ||
- 0)
- return 1;
- return 0;
-}
-
-#define AGGRESSIVE_FN ".aggressive"
-static char drop_aggressive = 0;
-
-void
-load_aggressive_state()
-{
- if (dashf(AGGRESSIVE_FN))
- drop_aggressive = 1;
- else
- drop_aggressive = 0;
-}
-
-void
-set_aggressive_state(int s)
-{
- FILE *fp = NULL;
- if (s)
- {
- fp = fopen(AGGRESSIVE_FN, "wb");
- fclose(fp);
- } else {
- remove(AGGRESSIVE_FN);
- }
-}
-
-/* cache for °ÊºA¬ÝªO */
-void
-reload_pttcache(void)
-{
- if (SHM->Pbusystate)
- safe_sleep(1);
- else { /* jochang: temporary workaround */
- fileheader_t item, subitem;
- char pbuf[256], buf[256], *chr;
- FILE *fp, *fp1, *fp2;
- int id, aggid, rawid;
-
- SHM->Pbusystate = 1;
- SHM->last_film = 0;
- bzero(SHM->notes, sizeof(SHM->notes));
- setapath(pbuf, GLOBAL_NOTE);
- setadir(buf, pbuf);
-
- load_aggressive_state();
- id = aggid = rawid = 0; // effective count, aggressive count, total (raw) count
-
- if ((fp = fopen(buf, "r"))) {
- // .DIR loop
- while (fread(&item, sizeof(item), 1, fp)) {
-
- int chkagg = 0; // should we check aggressive?
-
- if (item.title[3] != '<' || item.title[8] != '>')
- continue;
-
-#ifdef GLOBAL_NOTE_AGGCHKDIR
- // TODO aggressive: only count '<ÂIºq>' section
- if (strcmp(item.title+3, GLOBAL_NOTE_AGGCHKDIR) == 0)
- chkagg = 1;
-#endif
-
- snprintf(buf, sizeof(buf), "%s/%s/" FN_DIR,
- pbuf, item.filename);
-
- if (!(fp1 = fopen(buf, "r")))
- continue;
-
- // file loop
- while (fread(&subitem, sizeof(subitem), 1, fp1)) {
-
- snprintf(buf, sizeof(buf),
- "%s/%s/%s", pbuf, item.filename,
- subitem.filename);
-
- if (!(fp2 = fopen(buf, "r")))
- continue;
-
- fread(SHM->notes[id], sizeof(char), sizeof(SHM->notes[0]), fp2);
- SHM->notes[id][sizeof(SHM->notes[0]) - 1] = 0;
- rawid ++;
-
- // filtering
- if (filter_dirtywords(SHM->notes[id]))
- {
- memset(SHM->notes[id], 0, sizeof(SHM->notes[0]));
- rawid --;
- }
- else if (chkagg && filter_aggressive(SHM->notes[id]))
- {
- aggid++;
- // handle aggressive notes by last detemined state
- if (drop_aggressive)
- memset(SHM->notes[id], 0, sizeof(SHM->notes[0]));
- else
- id++;
-#ifdef _BBS_UTIL_C_
- // Debug purpose
- // printf("found aggressive: %s\n", buf);
-#endif
- }
- else
- {
- id++;
- }
-
- fclose(fp2);
- if (id >= MAX_MOVIE)
- break;
-
- } // end of file loop
- fclose(fp1);
-
- if (id >= MAX_MOVIE)
- break;
- } // end of .DIR loop
- fclose(fp);
-
- // decide next aggressive state
- if (rawid && aggid*3 >= rawid) // if aggressive exceed 1/3
- set_aggressive_state(1);
- else
- set_aggressive_state(0);
-
-#ifdef _BBS_UTIL_C_
- printf("id(%d)/agg(%d)/raw(%d)\n",
- id, aggid, rawid);
-#endif
- }
- SHM->last_film = id - 1;
-
- fp = fopen("etc/today_is", "r");
- if (fp) {
- fgets(SHM->today_is, 15, fp);
- if ((chr = strchr(SHM->today_is, '\n')))
- *chr = 0;
- SHM->today_is[15] = 0;
- fclose(fp);
- }
- /* µ¥©Ò¦³¸ê®Æ§ó·s«á¦A³]©w uptime */
-
- SHM->Puptime = SHM->Ptouchtime;
- log_usies("CACHE", "reload pttcache");
- SHM->Pbusystate = 0;
- }
-}
-
-void
-resolve_garbage(void)
-{
- int count = 0;
-
- while (SHM->Puptime < SHM->Ptouchtime) { /* ¤£¥Îwhileµ¥ */
- reload_pttcache();
- if (count++ > 10 && SHM->Pbusystate) {
- /*
- * Ptt: ³oÃä·|¦³°ÝÃD load¶W¹L10 ¬í·|©Ò¦³¶iloopªºprocess tate = 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
- */
- SHM->Pbusystate = 0;
-#ifndef _BBS_UTIL_C_
- log_usies("CACHE", "refork Ptt dead lock");
-#endif
- }
- }
-}
-
-/*-------------------------------------------------------*/
-/* PTT's cache */
-/*-------------------------------------------------------*/
-/* cache for from host »P³Ì¦h¤W½u¤H¼Æ */
-void
-reload_fcache(void)
-{
- if (SHM->Fbusystate)
- safe_sleep(1);
- else {
- FILE *fp;
-
- SHM->Fbusystate = 1;
- bzero(SHM->home_ip, sizeof(SHM->home_ip));
- if ((fp = fopen("etc/domain_name_query.cidr", "r"))) {
- char buf[256], *ip, *mask;
- char *strtok_pos;
-
- SHM->home_num = 0;
- while (fgets(buf, sizeof(buf), fp)) {
- if (!buf[0] || buf[0] == '#' || buf[0] == ' ' || buf[0] == '\n')
- continue;
-
- if (buf[0] == '@') {
- SHM->home_ip[0] = 0;
- SHM->home_mask[0] = 0xFFFFFFFF;
- SHM->home_num++;
- continue;
- }
-
- ip = strtok_r(buf, " \t", &strtok_pos);
- if ((mask = strchr(ip, '/')) != NULL) {
- int shift = 32 - atoi(mask + 1);
- SHM->home_ip[SHM->home_num] = ipstr2int(ip);
- SHM->home_mask[SHM->home_num] = (0xFFFFFFFF >> shift ) << shift;
- }
- else {
- SHM->home_ip[SHM->home_num] = ipstr2int(ip);
- SHM->home_mask[SHM->home_num] = 0xFFFFFFFF;
- }
- ip = strtok_r(NULL, " \t", &strtok_pos);
- if (ip == NULL) {
- strcpy(SHM->home_desc[SHM->home_num], "¶³²`¤£ª¾³B");
- }
- else {
- strlcpy(SHM->home_desc[SHM->home_num], ip,
- sizeof(SHM->home_desc[SHM->home_num]));
- chomp(SHM->home_desc[SHM->home_num]);
- }
- (SHM->home_num)++;
- if (SHM->home_num == MAX_FROM)
- break;
- }
- fclose(fp);
- }
- SHM->max_user = 0;
-
- /* µ¥©Ò¦³¸ê®Æ§ó·s«á¦A³]©w uptime */
- SHM->Fuptime = SHM->Ftouchtime;
-#if !defined(_BBS_UTIL_C_)
- log_usies("CACHE", "reload fcache");
-#endif
- SHM->Fbusystate = 0;
- }
-}
-
-void
-resolve_fcache(void)
-{
- while (SHM->Fuptime < SHM->Ftouchtime)
- reload_fcache();
-}
-
-/*
- * section - hbfl (hidden board friend list)
- */
-void
-hbflreload(int bid)
-{
- int hbfl[MAX_FRIEND + 1], i, num, uid;
- char buf[128];
- FILE *fp;
-
- assert(0<=bid-1 && bid-1<MAX_BOARD);
- memset(hbfl, 0, sizeof(hbfl));
- setbfile(buf, bcache[bid - 1].brdname, fn_visable);
- if ((fp = fopen(buf, "r")) != NULL) {
- for (num = 1; num <= MAX_FRIEND; ++num) {
- if (fgets(buf, sizeof(buf), fp) == NULL)
- break;
- for (i = 0; buf[i] != 0; ++i)
- if (buf[i] == ' ') {
- buf[i] = 0;
- break;
- }
- if (strcasecmp(STR_GUEST, buf) == 0 ||
- (uid = searchuser(buf, NULL)) == 0) {
- --num;
- continue;
- }
- hbfl[num] = uid;
- }
- fclose(fp);
- }
- hbfl[0] = COMMON_TIME;
- memcpy(SHM->hbfl[bid-1], hbfl, sizeof(hbfl));
-}
-
-/* ¬O§_³q¹LªO¤Í´ú¸Õ. ¦pªG¦bªO¤Í¦W³æ¤¤ªº¸Ü¶Ç¦^ 1, §_«h¬° 0 */
-int
-is_hidden_board_friend(int bid, int uid)
-{
- int i;
-
- assert(0<=bid-1 && bid-1<MAX_BOARD);
- if (SHM->hbfl[bid-1][0] < login_start_time - HBFLexpire)
- hbflreload(bid);
- for (i = 1; SHM->hbfl[bid-1][i] != 0 && i <= MAX_FRIEND; ++i) {
- if (SHM->hbfl[bid-1][i] == uid)
- return 1;
- }
- return 0;
-}
-
-#ifdef USE_COOLDOWN
-void add_cooldowntime(int uid, int min)
-{
- // Ptt: I will use the number below 15 seconds.
- time4_t base= now > SHM->cooldowntime[uid - 1]?
- now : SHM->cooldowntime[uid - 1];
- base += min*60;
- base &= 0xFFFFFFF0;
-
- SHM->cooldowntime[uid - 1] = base;
-}
-void add_posttimes(int uid, int times)
-{
- if((SHM->cooldowntime[uid - 1] & 0xF) + times <0xF)
- SHM->cooldowntime[uid - 1] += times;
- else
- SHM->cooldowntime[uid - 1] |= 0xF;
-}
-#endif
diff --git a/mbbsd/cal.c b/mbbsd/cal.c
deleted file mode 100644
index 1f6f9d9d..00000000
--- a/mbbsd/cal.c
+++ /dev/null
@@ -1,630 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-/* ¨¾°ô Multi play */
-static int
-is_playing(int unmode)
-{
- register int i;
- register userinfo_t *uentp;
- unsigned int p = StringHash(cuser.userid) % USHM_SIZE;
-
- for (i = 0; i < USHM_SIZE; i++, p++) { // XXX linear search
- if (p == USHM_SIZE)
- p = 0;
- uentp = &(SHM->uinfo[p]);
- if (uentp->uid == usernum)
- if (uentp->lockmode == unmode)
- return 1;
- }
- return 0;
-}
-
-int
-lockutmpmode(int unmode, int state)
-{
- int errorno = 0;
-
- if (currutmp->lockmode)
- errorno = LOCK_THIS;
- else if (state == LOCK_MULTI && is_playing(unmode))
- errorno = LOCK_MULTI;
-
- if (errorno) {
- clear();
- move(10, 20);
- if (errorno == LOCK_THIS)
- prints("½Ð¥ýÂ÷¶} %s ¤~¯à¦A %s ",
- ModeTypeTable[currutmp->lockmode],
- ModeTypeTable[unmode]);
- else
- prints("©êºp! ±z¤w¦³¨ä¥L½u¬Û¦PªºID¥¿¦b%s",
- ModeTypeTable[unmode]);
- pressanykey();
- return errorno;
- }
- setutmpmode(unmode);
- currutmp->lockmode = unmode;
- return 0;
-}
-
-int
-unlockutmpmode(void)
-{
- currutmp->lockmode = 0;
- return 0;
-}
-
-/* ¨Ï¥Î¿úªº¨ç¼Æ */
-#define VICE_NEW "vice.new"
-
-/* Heat:µo²¼ */
-int
-vice(int money, const char *item)
-{
- char buf[128];
- unsigned int viceserial = (currutmp->lastact % 10000) * 10000 +
- random() % 10000;
-
- // new logic: do not send useless vice tickets
- demoney(-money);
- if (money < VICE_MIN)
- return 0;
-
- setuserfile(buf, VICE_NEW);
- log_filef(buf, LOG_CREAT, "%8.8d\n", viceserial);
- snprintf(buf, sizeof(buf),
- "%s ªá¤F$%d ½s¸¹[%08d]", item, money, viceserial);
- mail_id(cuser.userid, buf, "etc/vice.txt", BBSMNAME "¸gÀÙ³¡");
- return 0;
-}
-
-#define lockreturn(unmode, state) if(lockutmpmode(unmode, state)) return
-#define lockreturn0(unmode, state) if(lockutmpmode(unmode, state)) return 0
-#define lockbreak(unmode, state) if(lockutmpmode(unmode, state)) break
-#define SONGBOOK "etc/SONGBOOK"
-#define OSONGPATH "etc/SONGO"
-
-static int
-osong(void)
-{
- char sender[IDLEN + 1], receiver[IDLEN + 1], buf[200],
- genbuf[200], filename[256], say[51];
- char trans_buffer[PATHLEN];
- char address[45];
- FILE *fp, *fp1;
- //*fp2;
- fileheader_t mail;
- int nsongs;
-
- strlcpy(buf, Cdatedate(&now), sizeof(buf));
-
- lockreturn0(OSONG, LOCK_MULTI);
-
- /* Jaky ¤@¤H¤@¤ÑÂI¤@­º */
- if (!strcmp(buf, Cdatedate(&cuser.lastsong)) && !HasUserPerm(PERM_SYSOP)) {
- move(22, 0);
- vmsg("§A¤µ¤Ñ¤w¸gÂI¹LÅo¡A©ú¤Ñ¦AÂI§a....");
- unlockutmpmode();
- return 0;
- }
-
- while (1) {
- char ans[4];
- move(12, 0);
- clrtobot();
- prints("¿Ë·Rªº %s Åwªï¨Ó¨ì¼Ú®á¦Û°ÊÂIºq¨t²Î\n\n", cuser.userid);
- outs(ANSI_COLOR(1) "ª`·NÂIºq¤º®e½Ð¤Å¯A¤Îðã½| ¤H¨­§ðÀ» µTÁ¶"
- "¤½µM«V°d ½ÚÁ½\n"
- "­Y¦³¤W­z¹H³W±¡§Î¡A¯¸¤è±N«O¯d¨M©w¬O§_¤½¶}¼½©ñªºÅv§Q\n"
- "¦p¤£¦P·N½Ð«ö (3) Â÷¶}¡C" ANSI_RESET "\n");
- getdata(18, 0, "½Ð¿ï¾Ü " ANSI_COLOR(1) "1)" ANSI_RESET " ¶}©lÂIºq¡B"
- ANSI_COLOR(1) "2)" ANSI_RESET " ¬Ýºq¥»¡B"
- "©Î¬O " ANSI_COLOR(1) "3)" ANSI_RESET " Â÷¶}: ",
- ans, sizeof(ans), DOECHO);
-
- if (ans[0] == '1')
- break;
- else if (ans[0] == '2') {
- a_menu("ÂIºqºq¥»", SONGBOOK, 0, 0, NULL);
- clear();
- }
- else if (ans[0] == '3') {
- vmsg("ÁÂÁÂ¥úÁ{ :)");
- unlockutmpmode();
- return 0;
- }
- }
-
- if (cuser.money < 200) {
- move(22, 0);
- vmsg("ÂIºq­n200»È­ò!....");
- unlockutmpmode();
- return 0;
- }
-
- getdata_str(19, 0, "ÂIºqªÌ(¥i°Î¦W): ", sender, sizeof(sender), DOECHO, cuser.userid);
- getdata(20, 0, "ÂIµ¹(¥i°Î¦W): ", receiver, sizeof(receiver), DOECHO);
-
- getdata_str(21, 0, "·Q­n­n¹ï¥L(¦o)»¡..:", say,
- sizeof(say), DOECHO, "§Ú·R©p..");
- snprintf(save_title, sizeof(save_title),
- "%s:%s", sender, say);
- getdata_str(22, 0, "±H¨ì½Öªº«H½c(¯u¹ê ID ©Î E-mail)?",
- address, sizeof(address), LCECHO, receiver);
- vmsg("±µµÛ­n¿ïºqÅo..¶i¤Jºq¥»¦n¦nªº¿ï¤@­ººq§a..^o^");
- a_menu("ÂIºqºq¥»", SONGBOOK, 0, 0, trans_buffer);
- if (!trans_buffer[0] || strstr(trans_buffer, "home") ||
- strstr(trans_buffer, "boards") || !(fp = fopen(trans_buffer, "r"))) {
- unlockutmpmode();
- return 0;
- }
- strlcpy(filename, OSONGPATH, sizeof(filename));
-
- stampfile(filename, &mail);
-
- unlink(filename);
-
- if (!(fp1 = fopen(filename, "w"))) {
- fclose(fp);
- unlockutmpmode();
- return 0;
- }
- strlcpy(mail.owner, "ÂIºq¾÷", sizeof(mail.owner));
- snprintf(mail.title, sizeof(mail.title), "¡º %s ÂIµ¹ %s ", sender, receiver);
-
- while (fgets(buf, sizeof(buf), fp)) {
- char *po;
- if (!strncmp(buf, "¼ÐÃD: ", 6)) {
- clear();
- move(10, 10);
- outs(buf);
- pressanykey();
- fclose(fp);
- fclose(fp1);
- unlockutmpmode();
- return 0;
- }
- while ((po = strstr(buf, "<~Src~>"))) {
- const char *dot = "";
- if (is_validuserid(sender) && strcmp(sender, cuser.userid) != 0)
- dot = ".";
- po[0] = 0;
- snprintf(genbuf, sizeof(genbuf), "%s%s%s%s", buf, sender, dot, po + 7);
- strlcpy(buf, genbuf, sizeof(buf));
- }
- while ((po = strstr(buf, "<~Des~>"))) {
- po[0] = 0;
- snprintf(genbuf, sizeof(genbuf), "%s%s%s", buf, receiver, po + 7);
- strlcpy(buf, genbuf, sizeof(buf));
- }
- while ((po = strstr(buf, "<~Say~>"))) {
- po[0] = 0;
- snprintf(genbuf, sizeof(genbuf), "%s%s%s", buf, say, po + 7);
- strlcpy(buf, genbuf, sizeof(buf));
- }
- fputs(buf, fp1);
- }
- fclose(fp1);
- fclose(fp);
-
- log_filef("etc/osong.log", LOG_CREAT, "id: %-12s ¡º %s ÂIµ¹ %s : \"%s\", Âà±H¦Ü %s\n", cuser.userid, sender, receiver, say, address);
-
- if (append_record(OSONGPATH "/" FN_DIR, &mail, sizeof(mail)) != -1) {
- cuser.lastsong = now;
- /* Jaky ¶W¹L MAX_MOVIE ­ººq´N¶}©l¬å */
- nsongs = get_num_records(OSONGPATH "/" FN_DIR, sizeof(mail));
- if (nsongs > MAX_MOVIE) {
- // XXX race condition
- delete_range(OSONGPATH "/" FN_DIR, 1, nsongs - MAX_MOVIE);
- }
- snprintf(genbuf, sizeof(genbuf), "%s says \"%s\" to %s.", sender, say, receiver);
- log_usies("OSONG", genbuf);
- /* §â²Ä¤@­º®³±¼ */
- vice(200, "ÂIºq");
- }
- snprintf(save_title, sizeof(save_title), "%s:%s", sender, say);
- hold_mail(filename, receiver);
-
- if (address[0]) {
-#ifndef USE_BSMTP
- bbs_sendmail(filename, save_title, address);
-#else
- bsmtp(filename, save_title, address);
-#endif
- }
- clear();
- outs(
- "\n\n ®¥³ß±zÂIºq§¹¦¨Åo..\n"
- " ¤@¤p®É¤º°ÊºA¬ÝªO·|¦Û°Ê­«·s§ó·s\n"
- " ¤j®a´N¥i¥H¬Ý¨ì±zÂIªººqÅo\n\n"
- " ÂIºq¦³¥ô¦ó°ÝÃD¥i¥H¨ìNoteªOªººëµØ°Ï§äµª®×\n"
- " ¤]¥i¦bNoteªOºëµØ°Ï¬Ý¨ì¦Û¤vªºÂIºq°O¿ý\n"
- " ¦³¥ô¦ó«O¶Qªº·N¨£¤]Åwªï¨ìNoteªO¯d¸Ü\n"
- " Åý¿Ë¤ÁªºªO¥D¬°±zªA°È\n");
- pressanykey();
- sortsong();
- topsong();
-
- unlockutmpmode();
- return 1;
-}
-
-int
-ordersong(void)
-{
- osong();
- return 0;
-}
-
-static int
-inmailbox(int m)
-{
- userec_t xuser;
- passwd_query(usernum, &xuser);
- cuser.exmailbox = xuser.exmailbox + m;
- passwd_update(usernum, &cuser);
- return cuser.exmailbox;
-}
-
-
-#if !HAVE_FREECLOAK
-/* ªá¿ú¿ï³æ */
-int
-p_cloak(void)
-{
- if (getans(currutmp->invisible ? "½T©w­n²{¨­?[y/N]" : "½T©w­nÁô¨­?[y/N]") != 'y')
- return 0;
- if (cuser.money >= 19) {
- vice(19, "¥I¶OÁô¨­");
- currutmp->invisible %= 2;
- vmsg((currutmp->invisible ^= 1) ? MSG_CLOAKED : MSG_UNCLOAK);
- }
- return 0;
-}
-#endif
-
-int
-p_from(void)
-{
- char tmp_from[sizeof(currutmp->from)];
- if (getans("½T©w­n§ï¬G¶m?[y/N]") != 'y')
- return 0;
- reload_money();
- if (cuser.money < 49)
- return 0;
- if (getdata_buf(b_lines - 1, 0, "½Ð¿é¤J·s¬G¶m:",
- tmp_from, sizeof(tmp_from), DOECHO)) {
- vice(49, "§ó§ï¬G¶m");
- strlcpy(currutmp->from, tmp_from, sizeof(currutmp->from));
- currutmp->from_alias = 0;
- }
- return 0;
-}
-
-int
-p_exmail(void)
-{
- char ans[4], buf[200];
- int n;
-
- if (cuser.exmailbox >= MAX_EXKEEPMAIL) {
- vmsgf("®e¶q³Ì¦h¼W¥[ %d «Ê¡A¤£¯à¦A¶R¤F¡C", MAX_EXKEEPMAIL);
- return 0;
- }
- snprintf(buf, sizeof(buf),
- "±z´¿¼WÁÊ %d «Ê®e¶q¡AÁÙ­n¦A¶R¦h¤Ö? ", cuser.exmailbox);
-
- // no need to create default prompt.
- // and people usually come this this by accident...
- getdata(b_lines - 2, 0, buf, ans, sizeof(ans), LCECHO);
-
- n = atoi(ans);
- if (!ans[0] || n<=0)
- return 0;
-
- if (n + cuser.exmailbox > MAX_EXKEEPMAIL)
- n = MAX_EXKEEPMAIL - cuser.exmailbox;
- reload_money();
- if (cuser.money < n * 1000)
- {
- vmsg("§Aªº¿ú¤£°÷¡C");
- return 0;
- }
-
- if (vmsgf("§A·QÁʶR %d «Ê«H½c (­nªá %d ¤¸), ½T©w¶Ü¡H[y/N] ",
- n, n*1000) != 'y')
- return 0;
-
- vice(n * 1000, "ÁʶR«H½c");
- inmailbox(n);
- vmsgf("¤wÁʶR«H½c¡C·s®e¶q¤W­­: %d", cuser.exmailbox);
- return 0;
-}
-
-void
-mail_redenvelop(const char *from, const char *to, int money, char mode)
-{
- char genbuf[200];
- fileheader_t fhdr;
- FILE *fp;
-
- sethomepath(genbuf, to);
- stampfile(genbuf, &fhdr);
- if (!(fp = fopen(genbuf, "w")))
- return;
- fprintf(fp, "§@ªÌ: %s\n"
- "¼ÐÃD: ©Û°]¶iÄ_\n"
- "®É¶¡: %s\n"
- ANSI_COLOR(1;33) "¿Ë·Rªº %s ¡G\n\n" ANSI_RESET
- ANSI_COLOR(1;31) " §Ú¥]µ¹§A¤@­Ó %d ¤¸ªº¤j¬õ¥]³á ^_^\n\n"
- " §»´±¡·N­«¡A½Ð¯º¯Ç...... ^_^" ANSI_RESET "\n",
- from, ctime4(&now), to, money);
- fclose(fp);
- snprintf(fhdr.title, sizeof(fhdr.title), "©Û°]¶iÄ_");
- strlcpy(fhdr.owner, from, sizeof(fhdr.owner));
-
- if (mode == 'y')
- vedit(genbuf, NA, NULL);
- sethomedir(genbuf, to);
- append_record(genbuf, &fhdr, sizeof(fhdr));
-}
-
-
-int do_give_money(char *id, int uid, int money)
-{
- int tax;
-#ifdef PLAY_ANGEL
- userec_t xuser;
-#endif
-
- reload_money();
- if (money > 0 && cuser.money >= money) {
- tax = give_tax(money);
- if (money - tax <= 0)
- return -1; /* ú§¹µ|´N¨S¿úµ¹¤F */
- deumoney(uid, money - tax);
- demoney(-money);
- log_filef(FN_MONEY, LOG_CREAT, "%-12s µ¹ %-12s %d\t(µ|«á %d)\t%s",
- cuser.userid, id, money, money - tax, ctime4(&now));
-#ifdef PLAY_ANGEL
- getuser(id, &xuser);
- if (!strcmp(xuser.myangel, cuser.userid)){
- mail_redenvelop(
- getkey("¥L¬O§Aªº¤p¥D¤H¡A¬O§_°Î¦W¡H[Y/n]") == 'n' ?
- cuser.userid : "¤p¤Ñ¨Ï", id, money - tax,
- getans("­n¦Û¦æ®Ñ¼g¬õ¥]³U¶Ü¡H[y/N]"));
- } else
-#endif
- mail_redenvelop(cuser.userid, id, money - tax,
- getans("­n¦Û¦æ®Ñ¼g¬õ¥]³U¶Ü¡H[y/N]"));
- if (money < 50) {
- usleep(2000000);
- } else if (money < 200) {
- usleep(500000);
- } else {
- usleep(100000);
- }
- return 0;
- }
- return -1;
-}
-
-int
-p_give(void)
-{
- give_money_ui(NULL);
- return -1;
-}
-
-int
-give_money_ui(const char *userid)
-{
- int uid;
- char id[IDLEN + 1], money_buf[20];
- char passbuf[PASSLEN];
- int m = 0, tries = 3, skipauth = 0;
- static time4_t lastauth = 0;
-
- // TODO prevent macros, we should check something here,
- // like user pw/id/...
- clear();
- stand_title("µ¹¤©ª÷¿ú");
- if (!userid || !*userid)
- usercomplete("³o¦ì©¯¹B¨àªºid: ", id);
- else {
- strlcpy(id, userid, sizeof(id));
- prints("³o¦ì©¯¹B¨àªºid: %s\n", id);
- }
- move(2, 0); clrtobot();
-
- if (!id[0] || !strcasecmp(cuser.userid, id))
- {
- vmsg("¥æ©ö¨ú®ø!");
- return -1;
- }
- if (!getdata(2, 0, "­nµ¹¥L¦h¤Ö¿ú©O: ", money_buf, 7, LCECHO) ||
- ((m = atoi(money_buf)) <= 0))
- {
- vmsg("¥æ©ö¨ú®ø!");
- return -1;
- }
- if ((uid = searchuser(id, id)) == 0) {
- vmsg("¬dµL¦¹¤H!");
- return -1;
- }
- move(4, 0);
- prints("¥æ©ö¤º®e: %s ±Nµ¹¤© %s : %d ¤¸ (­n¦A¦©µ|ª÷ %d ¤¸)\n",
- cuser.userid, id, m, give_tax(m));
-
- if (now - lastauth >= 15*60) // valid through 15 minutes
- {
- outs(ANSI_COLOR(1;31) "¬°¤FÁקK»~«ö©Î¬O´c·N¶BÄF¡A"
- "¦b§¹¦¨¥æ©ö«e­n­«·s½T»{±zªº¨­¥÷¡C" ANSI_RESET);
- } else {
- outs("§Aªº»{ÃÒ©|¥¼¹L´Á¡A¥i¼È®É¸õ¹L±K½X»{ÃÒµ{§Ç¡C\n");
- // auth is valid.
- if (getans("½T©w¶i¦æ¥æ©ö¶Ü¡H (y/N): ") == 'y')
- skipauth = 1;
- else
- tries = -1;
- }
-
- while (!skipauth && tries-- > 0)
- {
- getdata(6, 0, MSG_PASSWD,
- passbuf, sizeof(passbuf), NOECHO);
- passbuf[8] = '\0';
- if (checkpasswd(cuser.passwd, passbuf))
- {
- lastauth = now;
- break;
- }
- if (tries > 0)
- vmsgf("±K½X¿ù»~¡AÁÙ¦³ %d ¦¸¾÷·|¡C", tries);
- }
- if (tries < 0)
- {
- vmsg("¥æ©ö¨ú®ø!");
- return -1;
- }
- // vmsg("·Ç³Æ¥æ©ö¡C");
- // return -1;
- return do_give_money(id, uid, m);
-}
-
-void
-resolve_over18(void)
-{
- /* get local time */
- struct tm ptime = *localtime4(&now);
-
- over18 = 0;
- /* check if over18 */
- // ·Ó¹ê·³­pºâ¡A¨S¥Í¤éªº·í§@¥¼º¡ 18
- if (cuser.year < 1 || cuser.month < 1)
- over18 = 0;
- else if( (ptime.tm_year - cuser.year) > 18)
- over18 = 1;
- else if (ptime.tm_year - cuser.year < 18)
- over18 = 0;
- else if ((ptime.tm_mon+1) > cuser.month)
- over18 = 1;
- else if ((ptime.tm_mon+1) < cuser.month)
- over18 = 0;
- else if (ptime.tm_mday >= cuser.day )
- over18 = 1;
-}
-
-int
-p_sysinfo(void)
-{
- char *cpuloadstr;
- int load;
- extern char *compile_time;
-#ifdef DETECT_CLIENT
- extern Fnv32_t client_code;
-#endif
-
- load = cpuload(NULL);
- cpuloadstr = (load < 5 ? "¨}¦n" : (load < 20 ? "©|¥i" : "¹L­«"));
-
- clear();
- showtitle("¨t²Î¸ê°T", BBSNAME);
- move(2, 0);
- prints("±z²{¦b¦ì©ó " TITLE_COLOR BBSNAME ANSI_RESET " (" MYIP ")\n"
- "¨t²Î­t¸ü±¡ªp: %s\n"
- "½u¤WªA°È¤H¼Æ: %d/%d\n"
-#ifdef DETECT_CLIENT
- "client code: %8.8X\n"
-#endif
- "½sĶ®É¶¡: %s\n"
- "°_©l®É¶¡: %s\n",
- cpuloadstr, SHM->UTMPnumber,
-#ifdef DYMAX_ACTIVE
- SHM->GV2.e.dymaxactive > 2000 ? SHM->GV2.e.dymaxactive : MAX_ACTIVE,
-#else
- MAX_ACTIVE,
-#endif
-#ifdef DETECT_CLIENT
- client_code,
-#endif
- compile_time, ctime4(&start_time));
-
-#ifdef REPORT_PIAIP_MODULES
- outs("\n" ANSI_COLOR(1;30)
- "Modules powered by piaip:\n"
- "\ttelnet protocol, ALOHA fixer, BRC v3\n"
-#if defined(USE_PIAIP_MORE) || defined(USE_PMORE)
- "\tpmore (piaip's more) 2007 w/Movie\n"
-#endif
-#ifdef HAVE_GRAYOUT
- "\tGrayout Advanced Control ²H¤J²H¥X¯S®Ä¨t²Î\n"
-#endif
-#ifdef EDITPOST_SMARTMERGE
- "\tSmart Merge ­×¤å¦Û°Ê¦X¨Ö\n"
-#endif
-#ifdef EXP_EDIT_UPLOAD
- "\t(EXP) Editor Uploader ªø¤å¤W¶Ç\n"
-#endif
-#if defined(USE_PFTERM)
- "\t(EXP) pfterm (piaip's flat terminal, Perfect Term)\n"
-#endif
-#if defined(USE_BBSLUA)
- "\t(EXP) BBS-Lua\n"
-#endif
- ANSI_RESET
- );
-#endif // REPORT_PIAIP_MODULES
-
- if (HasUserPerm(PERM_SYSOP)) {
- struct rusage ru;
-#ifdef __linux__
- int vmdata=0, vmstk=0;
- FILE * fp;
- char buf[128];
- if ((fp = fopen("/proc/self/status", "r"))) {
- while (fgets(buf, 128, fp)) {
- sscanf(buf, "VmData: %d", &vmdata);
- sscanf(buf, "VmStk: %d", &vmstk);
- }
- fclose(fp);
- }
-#endif
- getrusage(RUSAGE_SELF, &ru);
- prints("°O¾ÐÅé¥Î¶q: "
-#ifdef IA32
- "sbrk: %u KB, "
-#endif
-#ifdef __linux__
- "VmData: %d KB, VmStk: %d KB, "
-#endif
- "idrss: %d KB, isrss: %d KB\n",
-#ifdef IA32
- ((unsigned int)sbrk(0) - 0x8048000) / 1024,
-#endif
-#ifdef __linux__
- vmdata, vmstk,
-#endif
- (int)ru.ru_idrss, (int)ru.ru_isrss);
- prints("CPU ¥Î¶q: %ld.%06ldu %ld.%06lds",
- (long int)ru.ru_utime.tv_sec,
- (long int)ru.ru_utime.tv_usec,
- (long int)ru.ru_stime.tv_sec,
- (long int)ru.ru_stime.tv_usec);
-#ifdef CPULIMIT
- prints(" (limit %d secs)", (int)(CPULIMIT * 60));
-#endif
- outs("\n¯S§O°Ñ¼Æ:"
-#ifdef CRITICAL_MEMORY
- " CRITICAL_MEMORY"
-#endif
-#ifdef OUTTACACHE
- " OUTTACACHE"
-#endif
- );
- }
- pressanykey();
- return 0;
-}
-
diff --git a/mbbsd/calendar.c b/mbbsd/calendar.c
deleted file mode 100644
index b87c774a..00000000
--- a/mbbsd/calendar.c
+++ /dev/null
@@ -1,362 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-typedef struct event_t {
- int year, month, day, days;
- int color;
- char *content;
- struct event_t *next;
-} event_t;
-
-static int
-MonthDay(int m, int leap)
-{
- int day[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-
- assert(1<=m && m<=12);
- return leap && m == 2 ? 29 : day[m - 1];
-}
-
-static int
-Days(int y, int m, int d)
-{
- int i, w;
-
- w = 1 + 365 * (y - 1)
- + ((y - 1) / 4) - ((y - 1) / 100) + ((y - 1) / 400)
- + d - 1;
- for (i = 1; i < m; i++)
- w += MonthDay(i, is_leap_year(y));
- return w;
-}
-
-/**
- * return 1 if date is invalid
- */
-int ParseDate(const char *date, int *year, int *month, int *day)
-{
- char *y, *m, *d;
- char buf[128];
- char *strtok_pos;
-
- strlcpy(buf, date, sizeof(buf));
- y = strtok_r(buf, "/", &strtok_pos); if (!y) return 1;
- m = strtok_r(NULL, "/", &strtok_pos);if (!m) return 1;
- d = strtok_r(NULL, "", &strtok_pos); if (!d) return 1;
-
- *year = atoi(y);
- *month = atoi(m);
- *day = atoi(d);
- if (*year < 1 || *month < 1 || *month > 12 ||
- *day < 1 || *day > MonthDay(*month, is_leap_year(*year)))
- return 1;
- return 0;
-}
-
-/**
- * return 1 if date is invalid
- */
-static int
-ParseEventDate(const char *date, event_t * t)
-{
- int retval = ParseDate(date, &t->year, &t->month, &t->day);
- if (retval)
- return retval;
- t->days = Days(t->year, t->month, t->day);
- return retval;
-}
-
-static int
-ParseColor(const char *color)
-{
- struct {
- char *str;
- int val;
- } c[] = {
- {
- "black", 0
- },
- {
- "red", 1
- },
- {
- "green", 2
- },
- {
- "yellow", 3
- },
- {
- "blue", 4
- },
- {
- "magenta", 5
- },
- {
- "cyan", 6
- },
- {
- "white", 7
- }
- };
- int i;
-
- for (i = 0; (unsigned)i < sizeof(c) / sizeof(c[0]); i++)
- if (strcasecmp(color, c[i].str) == 0)
- return c[i].val;
- return 7;
-}
-
-static void
-InsertEvent(event_t * head, event_t * t)
-{
- event_t *p;
-
- for (p = head; p->next && p->next->days < t->days; p = p->next);
- t->next = p->next;
- p->next = t;
-}
-
-static void
-FreeEvent(event_t * e)
-{
- event_t *n;
-
- while (e) {
- n = e->next;
- free(e->content); /* from strdup() */
- free(e);
- e = n;
- }
-}
-
-static event_t *
-ReadEvent(int today)
-{
- FILE *fp;
- char buf[256];
- static event_t head;
-
- head.next = NULL;
- sethomefile(buf, cuser.userid, "calendar");
- fp = fopen(buf, "r");
- if (fp) {
- while (fgets(buf, sizeof(buf), fp)) {
- char *date, *color, *content;
- event_t *t;
- char *strtok_pos;
-
- if (buf[0] == '#')
- continue;
-
- date = strtok_r(buf, " \t\n", &strtok_pos);
- color = strtok_r(NULL, " \t\n", &strtok_pos);
- content = strtok_r(NULL, "\n", &strtok_pos);
- if (!date || !color || !content)
- continue;
-
- t = malloc(sizeof(event_t));
- if (ParseEventDate(date, t) || t->days < today) {
- free(t);
- continue;
- }
- t->color = ParseColor(color) + 30;
- for (; *content == ' ' || *content == '\t'; content++);
- t->content = strdup(content);
- InsertEvent(&head, t);
- }
- fclose(fp);
- }
- return head.next;
-}
-
-static char **
-AllocCalBuffer(int line, int len)
-{
- int i;
- char **p;
-
- p = malloc(sizeof(char *) * line);
- p[0] = malloc(sizeof(char) * line * len);
- for (i = 1; i < line; i++)
- p[i] = p[i - 1] + len;
- return p;
-}
-
-static void
-FreeCalBuffer(char **buf)
-{
- free(buf[0]);
- free(buf);
-}
-
-#define CALENDAR_COLOR ANSI_COLOR(0;30;47)
-#define HEADER_COLOR ANSI_COLOR(1;44)
-#define HEADER_SUNDAY_COLOR ANSI_COLOR(31)
-#define HEADER_DAY_COLOR ANSI_COLOR(33)
-
-static int
-GenerateCalendar(char **buf, int y, int m, int today, event_t * e)
-{
- char *week_str[7] = {"¤é", "¤@", "¤G", "¤T", "¥|", "¤­", "¤»"};
- char *month_color[12] = {
- ANSI_COLOR(1;32), ANSI_COLOR(1;33), ANSI_COLOR(1;35), ANSI_COLOR(1;36),
- ANSI_COLOR(1;32), ANSI_COLOR(1;33), ANSI_COLOR(1;35), ANSI_COLOR(1;36),
- ANSI_COLOR(1;32), ANSI_COLOR(1;33), ANSI_COLOR(1;35), ANSI_COLOR(1;36)
- };
- char *month_str[12] = {
- "¤@¤ë ", "¤G¤ë ", "¤T¤ë ", "¥|¤ë ", "¤­¤ë ", "¤»¤ë ",
- "¤C¤ë ", "¤K¤ë ", "¤E¤ë ", "¤Q¤ë ", "¤Q¤@¤ë", "¤Q¤G¤ë"
- };
-
- char *p, attr1[16], *attr2;
- int i, d, w, line = 0, first_day = Days(y, m, 1);
-
-
- /* week day banner */
- p = buf[line];
- p += sprintf(p, " %s%s%s%s", HEADER_COLOR, HEADER_SUNDAY_COLOR,
- week_str[0], HEADER_DAY_COLOR);
- for (i = 1; i < 7; i++)
- p += sprintf(p, " %s", week_str[i]);
- p += sprintf(p, ANSI_RESET);
-
- /* indent for first line */
- p = buf[++line];
- p += sprintf(p, " %s", CALENDAR_COLOR);
- for (i = 0, w = first_day % 7; i < w; i++)
- p += sprintf(p, " ");
-
- /* initial event */
- for (; e && e->days < first_day; e = e->next);
-
- d = MonthDay(m, is_leap_year(y));
- for (i = 1; i <= d; i++, w = (w + 1) % 7) {
- attr1[0] = 0;
- attr2 = "";
- while (e && e->days == first_day + i - 1) {
- sprintf(attr1, ANSI_COLOR(1;%d), e->color);
- attr2 = CALENDAR_COLOR;
- e = e->next;
- }
- if (today == first_day + i - 1) {
- strlcpy(attr1, ANSI_COLOR(1;37;42), sizeof(attr1));
- attr2 = CALENDAR_COLOR;
- }
- p += sprintf(p, "%s%2d%s", attr1, i, attr2);
-
- if (w == 6) {
- p += sprintf(p, ANSI_RESET);
- p = buf[++line];
- /* show month */
- if (line >= 2 && line <= 4)
- p += sprintf(p, "%s%2.2s\33[m %s", month_color[m - 1],
- month_str[m - 1] + (line - 2) * 2,
- CALENDAR_COLOR);
- else if (i < d)
- p += sprintf(p, " %s", CALENDAR_COLOR);
- } else
- *p++ = ' ';
- }
-
- /* fill up the last line */
- if (w) {
- for (w = 7 - w; w; w--)
- p += sprintf(p, w == 1 ? " " : " ");
- p += sprintf(p, ANSI_RESET);
- }
- return line + 1;
-}
-
-int
-u_editcalendar(void)
-{
- char genbuf[200];
-
- getdata(b_lines - 1, 0, "¦æ¨Æ¾ä (D)§R°£ (E)½s¿è (H)»¡©ú [Q]¨ú®ø¡H[Q] ",
- genbuf, 3, LCECHO);
-
- if (genbuf[0] == 'e') {
- int aborted;
-
- setutmpmode(EDITPLAN);
- sethomefile(genbuf, cuser.userid, "calendar");
- aborted = vedit(genbuf, NA, NULL);
- if (aborted != -1)
- vmsg("¦æ¨Æ¾ä§ó·s§¹²¦");
- return 0;
- } else if (genbuf[0] == 'd') {
- sethomefile(genbuf, cuser.userid, "calendar");
- unlink(genbuf);
- vmsg("¦æ¨Æ¾ä§R°£§¹²¦");
- } else if (genbuf[0] == 'h') {
- move(1, 0);
- clrtoln(b_lines);
- move(3, 0);
- prints("¦æ¨Æ¾ä®æ¦¡»¡©ú:\n½s¿è®É¥H¤@¦æ¬°³æ¦ì¡A¦p:\n\n# ¤«¸¹¶}ÀYªº¬Oµù¸Ñ\n2006/05/04 red ¤W§å½ð½ð!\n\n¨ä¤¤ªº red ¬O«üªí¥ÜªºÃC¦â¡C");
- pressanykey();
- }
- return 0;
-}
-
-int
-calendar(void)
-{
- char **buf;
- struct tm snow;
- int i, y, m, today, lines = 0;
- event_t *head = NULL, *e = NULL;
-
- /* initialize date */
- memcpy(&snow, localtime4(&now), sizeof(struct tm));
- today = Days(snow.tm_year + 1900, snow.tm_mon + 1, snow.tm_mday);
- y = snow.tm_year + 1900, m = snow.tm_mon + 1;
-
- /* read event */
- head = e = ReadEvent(today);
-
- /* generate calendar */
- buf = AllocCalBuffer(22, 256);
- for (i = 0; i < 22; i++)
- sprintf(buf[i], "%24s", "");
- for (i = 0; i < 3; i++) {
- lines += GenerateCalendar(buf + lines, y, m, today, e) + 1;
- if (m == 12)
- y++, m = 1;
- else
- m++;
- }
-
- /* output */
- clear();
- outc('\n');
- for (i = 0; i < 22; i++) {
- outs(buf[i]);
- if (i == 0) {
- prints("\t" ANSI_COLOR(1;37)
- "²{¦b¬O %d.%02d.%02d %2d:%02d:%02d%cm" ANSI_RESET,
- snow.tm_year + 1900, snow.tm_mon + 1, snow.tm_mday,
- (snow.tm_hour == 0 || snow.tm_hour == 12) ?
- 12 : snow.tm_hour % 12, snow.tm_min, snow.tm_sec,
- snow.tm_hour >= 12 ? 'p' : 'a');
- } else if (i >= 2 && e) {
- prints("\t" ANSI_COLOR(1;37)
- "(©|¦³ " ANSI_COLOR(%d) "%3d"
- ANSI_COLOR(37) " ¤Ñ)"
- ANSI_RESET " %02d/%02d %s",
- e->color, e->days - today,
- e->month, e->day, e->content);
- e = e->next;
- }
- outc('\n');
- }
- FreeEvent(head);
- FreeCalBuffer(buf);
- i = vmsg("½Ð«ö e ½s¿è¦æ¨Æ¾ä¡A©Î¨ä¥¦¥ô·NÁäÂ÷¶}¡C");
- i = tolower(((unsigned char)i) & 0xFF);
- if (i == 'e')
- {
- u_editcalendar();
- }
- return 0;
-}
-
diff --git a/mbbsd/card.c b/mbbsd/card.c
deleted file mode 100644
index 5f5a1530..00000000
--- a/mbbsd/card.c
+++ /dev/null
@@ -1,672 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-enum CardSuit {
- Spade, Heart, Diamond, Club
-};
-static int
-card_remain(int cards[])
-{
- int i, temp = 0;
-
- for (i = 0; i < 52; i++)
- temp += cards[i];
- if (temp == 52)
- return 1;
- return 0;
-}
-
-static enum CardSuit
-card_flower(int card)
-{
- return (card / 13);
-}
-
-/* 1...13 */
-static int
-card_number(int card)
-{
- return (card % 13 + 1);
-}
-
-static int
-card_isblackjack(int card1, int card2)
-{
- return
- (card_number(card1)==1 && (10<=card_number(card2) && card_number(card2)<=13)) ||
- (card_number(card2)==1 && (10<=card_number(card1) && card_number(card1)<=13));
-}
-
-static int
-card_select(int *now)
-{
- char *cc[2] = {ANSI_COLOR(44) " " ANSI_RESET,
- ANSI_COLOR(1;33;41) " ¡µ " ANSI_RESET};
-
- while (1) {
- move(20, 0);
- clrtoeol();
- prints("%s%s%s%s%s", (*now == 0) ? cc[1] : cc[0],
- (*now == 1) ? cc[1] : cc[0],
- (*now == 2) ? cc[1] : cc[0],
- (*now == 3) ? cc[1] : cc[0],
- (*now == 4) ? cc[1] : cc[0]);
- switch (igetch()) {
- case 'Q':
- case 'q':
- return 0;
- case '+':
- case ',':
- return 1;
- case '\r':
- return -1;
- case KEY_LEFT:
- *now = (*now + 4) % 5;
- break;
- case KEY_RIGHT:
- *now = (*now + 1) % 5;
- break;
- case '1':
- *now = 0;
- break;
- case '2':
- *now = 1;
- break;
- case '3':
- *now = 2;
- break;
- case '4':
- *now = 3;
- break;
- case '5':
- *now = 4;
- break;
- }
- }
-}
-
-static void
-card_display(int cline, int number, enum CardSuit flower, int show)
-{
- int color = 31;
- char *cn[13] = {"¢Ï", "¢±", "¢²", "¢³", "¢´", "¢µ",
- "¢¶", "¢·", "¢¸", "10", "¢Ø", "¢ß", "¢Ù"};
- if (flower == 0 || flower == 3)
- color = 36;
- if ((show < 0) && (cline > 1 && cline < 8))
- outs("¢x" ANSI_COLOR(1;33;42) "¡°¡°¡°¡°" ANSI_RESET "¢x");
- else
- switch (cline) {
- case 1:
- outs("¢~¢w¢w¢w¢w¢¡");
- break;
- case 2:
- prints("¢x" ANSI_COLOR(1;%d) "%s" ANSI_RESET " ¢x", color, cn[number - 1]);
- break;
- case 3:
- if (flower == 1)
- prints("¢x" ANSI_COLOR(1;%d) "¢¨¢©¢¨¢©" ANSI_RESET "¢x", color);
- else
- prints("¢x" ANSI_COLOR(1;%d) " ¢¨¢© " ANSI_RESET "¢x", color);
- break;
- case 4:
- if (flower == 1)
- prints("¢x" ANSI_COLOR(1;%d) "¢i¢i¢i¢i" ANSI_RESET "¢x", color);
- else if (flower == 3)
- prints("¢x" ANSI_COLOR(1;%d) "¢©¢i¢i¢¨" ANSI_RESET "¢x", color);
- else
- prints("¢x" ANSI_COLOR(1;%d) "¢¨¢i¢i¢©" ANSI_RESET "¢x", color);
- break;
- case 5:
- if (flower == 0)
- prints("¢x" ANSI_COLOR(1;%d) "¢i¢i¢i¢i" ANSI_RESET "¢x", color);
- else if (flower == 3)
- prints("¢x" ANSI_COLOR(1;%d) "¢i¢ª¢«¢i" ANSI_RESET "¢x", color);
- else
- prints("¢x" ANSI_COLOR(1;%d) "¢ª¢i¢i¢«" ANSI_RESET "¢x", color);
- break;
- case 6:
- if (flower == 0)
- prints("¢x" ANSI_COLOR(1;%d) " ¢¨¢© " ANSI_RESET "¢x", color);
- else if (flower == 3)
- prints("¢x" ANSI_COLOR(1;%d) "¢ª¢¨¢©¢«" ANSI_RESET "¢x", color);
- else
- prints("¢x" ANSI_COLOR(1;%d) " ¢ª¢« " ANSI_RESET "¢x", color);
- break;
- case 7:
- prints("¢x " ANSI_COLOR(1;%d) "%s" ANSI_RESET "¢x", color, cn[number - 1]);
- break;
- case 8:
- outs("¢¢¢w¢w¢w¢w¢£");
- break;
- }
-}
-
-static void
-card_show(int maxncard, int cpu[], int c[], int me[], int m[])
-{
- int i, j;
-
- for (j = 0; j < 8; j++) {
- move(2 + j, 0);
- clrtoeol();
- for (i = 0; i < maxncard && cpu[i] >= 0; i++)
- card_display(j + 1, card_number(cpu[i]),
- card_flower(cpu[i]), c[i]);
- }
-
- for (j = 0; j < 8; j++) {
- move(11 + j, 0);
- clrtoeol();
- for (i = 0; i < maxncard && me[i] >= 0; i++)
- card_display(j + 1, card_number(me[i]), card_flower(me[i]), m[i]);
- }
-}
-static void
-card_new(int cards[])
-{
- memset(cards, 0, sizeof(int) * 52);
-}
-
-static int
-card_give(int cards[])
-{
- int i;
- int freecard[52];
- int nfreecard = 0;
-
- for(i=0; i<52; i++)
- if(cards[i]==0)
- freecard[nfreecard++]=i;
-
- assert(nfreecard>0); /* caller ­n­t³d½T«OÁÙ¦³³ÑµP */
-
- i=freecard[random()%nfreecard];
- cards[i] = 1;
- return i;
-}
-
-static void
-card_start(char name[])
-{
- clear();
- stand_title(name);
- move(1, 0);
- outs(" " ANSI_COLOR(1;33;41) " ¹q ¸£ " ANSI_RESET);
- move(10, 0);
- outs(ANSI_COLOR(1;34;44) "¡»¡ã¡»¡ã¡»¡ã¡»¡ã¡»¡ã¡»¡ã¡»¡ã¡»¡ã¡»¡ã¡»¡ã¡»¡ã¡»¡ã"
- "¡»¡ã¡»¡ã¡»¡ã¡»¡ã¡»¡ã¡»¡ã¡»¡ã¡»" ANSI_RESET);
- move(19, 0);
- outs(" " ANSI_COLOR(1;37;42) " ¦Û ¤v " ANSI_RESET);
-}
-
-static int
-card_99_add(int i, int aom, int count)
-{
- if (i == 4 || i == 5 || i == 11)
- return count;
- else if (i == 12)
- return count + 20 * aom;
- else if (i == 10)
- return count + 10 * aom;
- else if (i == 13)
- return 99;
- else
- return count + i;
-}
-
-static int
-card_99_cpu(int cpu[], int *count)
-{
- int stop = -1;
- int twenty = -1;
- int ten = -1;
- int kill = -1;
- int temp, num[10];
- int other = -1;
- int think = 99 - (*count);
- int i, j;
-
- for (i = 0; i < 10; i++)
- num[i] = -1;
- for (i = 0; i < 5; i++) {
- temp = card_number(cpu[i]);
- if (temp == 4 || temp == 5 || temp == 11)
- stop = i;
- else if (temp == 12)
- twenty = i;
- else if (temp == 10)
- ten = i;
- else if (temp == 13)
- kill = i;
- else {
- other = i;
- num[temp] = i;
- }
- }
- for (j = 9; j > 0; j--)
- if (num[j] >= 0 && j != 4 && j != 5 && think >= j) {
- (*count) += j;
- return num[j];
- }
- if ((think >= 20) && (twenty >= 0)) {
- (*count) += 20;
- return twenty;
- } else if ((think >= 10) && (ten >= 0)) {
- (*count) += 10;
- return ten;
- } else if (stop >= 0)
- return stop;
- else if (kill >= 0) {
- (*count) = 99;
- return kill;
- } else if (ten >= 0) {
- (*count) -= 10;
- return ten;
- } else if (twenty >= 0) {
- (*count) -= 20;
- return twenty;
- } else {
- (*count) += card_number(cpu[0]);
- return 0;
- }
-}
-
-int
-card_99(void)
-{
- int i, j, turn;
- int cpu[5], c[5], me[5], m[5];
- int cards[52];
- int count = 0;
- char *ff[4] = {ANSI_COLOR(1;36) "¶Â®ç", ANSI_COLOR(1;31) "¬õ¤ß",
- ANSI_COLOR(1;31) "¤è¶ô", ANSI_COLOR(1;36) "¶Âªá"};
- char *cn[13] = {"¢Ï", "¢±", "¢²", "¢³", "¢´", "¢µ",
- "¢¶", "¢·", "¢¸", "10", "¢Ø", "¢ß", "¢Ù"};
- for (i = 0; i < 5; i++)
- cpu[i] = c[i] = me[i] = m[i] = -1;
- setutmpmode(CARD_99);
- card_start("¤Ñªø¦a¤[");
- card_new(cards);
- for (i = 0; i < 5; i++) {
- cpu[i] = card_give(cards);
- me[i] = card_give(cards);
- m[i] = 1;
- }
- card_show(5, cpu, c, me, m);
- j = 0;
- turn = 1;
- move(21, 0);
- clrtoeol();
- prints("[0]¥Ø«e %d , ´Ý %d ÂI\n", count, 99 - count);
- outs("¥ª¥kÁä²¾°Ê´å¼Ð, [Enter]½T©w, [ + ]ªí¥[¤G¤Q(¥[¤Q), [Q/q]©ñ±ó¹CÀ¸");
- while (1) {
- i = card_select(&j);
- if (i == 0) /* ©ñ±ó¹CÀ¸ */
- return 0;
- count = card_99_add(card_number(me[j]), i, count);
- move(21 + (turn / 2) % 2, 0);
- clrtoeol();
- prints("[%d]±z¥X %s%s" ANSI_RESET " ¥Ø«e " ANSI_COLOR(1;31) "%d/" ANSI_COLOR(34) "%d" ANSI_RESET " ÂI",
- turn, ff[card_flower(me[j])],
- cn[card_number(me[j]) - 1], count, 99 - count);
- me[j] = card_give(cards);
- turn++;
- if (count < 0)
- count = 0;
- card_show(5, cpu, c, me, m);
- pressanykey();
- if (count > 99) {
- move(22, 0);
- clrtoeol();
- prints("[%d]µ²ªG..YOU LOSS..¥Ø«e " ANSI_COLOR(1;31) "%d/" ANSI_COLOR(34) "%d" ANSI_RESET " ÂI",
- turn, count, 99 - count);
- pressanykey();
- return 0;
- }
- i = card_99_cpu(cpu, &count);
- move(21 + (turn / 2 + 1) % 2, 40);
- prints("[%d]¹q¸£¥X %s%s" ANSI_RESET " ¥Ø«e " ANSI_COLOR(1;31) "%d/" ANSI_COLOR(34) "%d" ANSI_RESET " ÂI",
- turn, ff[card_flower(cpu[i])],
- cn[card_number(cpu[i]) - 1], count, 99 - count);
- cpu[i] = card_give(cards);
- turn++;
- if (count < 0)
- count = 0;
- if (count > 99) {
- move(22, 0);
- clrtoeol();
- prints("[%d]µ²ªG..YOU WIN!..¥Ø«e " ANSI_COLOR(1;31) "%d/" ANSI_COLOR(34) "%d" ANSI_RESET " ÂI",
- turn, count, 99 - count);
- pressanykey();
- return 0;
- }
- if (!card_remain(cards)) {
- card_new(cards);
- for (i = 0; i < 5; i++) {
- cards[me[i]] = 1;
- cards[cpu[i]] = 1;
- }
- }
- }
-}
-
-#define PMONEY (10)
-#define TEN_HALF (5) /* ¤QÂI¥bªºTicket */
-#define JACK (10) /* ¶Â³Ç§JªºTicket */
-#define NINE99 (99) /* 99 ªºTicket */
-
-static int
-game_log(int type, int money)
-{
- FILE *fp;
-
- if (money > 0)
- demoney(money);
-
- switch (type) {
- case JACK:
- fp = fopen(BBSHOME "/etc/card/jack.log", "a");
- if (!fp)
- return 0;
- fprintf(fp, "%s win:%d\n", cuser.userid, money);
- fclose(fp);
- break;
- case TEN_HALF:
- fp = fopen(BBSHOME "/etc/card/tenhalf.log", "a");
- if (!fp)
- return 0;
- fprintf(fp, "%s win:%d\n", cuser.userid, money);
- fclose(fp);
- break;
- }
- usleep(100000); // sleep 0.1s
- return 0;
-}
-
-static int
-card_double_ask(void)
-{
- char buf[100], buf2[3];
-
- snprintf(buf, sizeof(buf),
- "[ %s ]±z²{¦b¦@¦³ %d ¤¸, ²{¦b­n¤À²Õ(¥[¦¬ %d ¤¸)¶Ü? [y/N]",
- cuser.userid, cuser.money, JACK);
- reload_money();
- if (cuser.money < JACK)
- return 0;
- getdata(20, 0, buf, buf2, sizeof(buf2), LCECHO);
- if (buf2[0] == 'y' || buf2[0] == 'Y')
- return 1;
- return 0;
-}
-
-static int
-card_ask(void)
-{
- char buf[100], buf2[3];
-
- snprintf(buf, sizeof(buf), "[ %s ]±z²{¦b¦@¦³ %d ¤¸, ÁÙ­n¥[µP¶Ü? [y/N]",
- cuser.userid, cuser.money);
- getdata(20, 0, buf, buf2, sizeof(buf2), LCECHO);
- if (buf2[0] == 'y' || buf2[0] == 'Y')
- return 1;
- return 0;
-}
-
-static int
-card_alls_lower(int all[])
-{
- int i, count = 0;
- for (i = 0; i < 6 && all[i] >= 0; i++)
- if (card_number(all[i]) <= 10)
- count += card_number(all[i]);
- else
- count += 10;
- return count;
-}
-
-static int
-card_alls_upper(int all[])
-{
- int i, count;
-
- count = card_alls_lower(all);
- for (i = 0; i < 6 && all[i] >= 0 && count <= 11; i++)
- if (card_number(all[i]) == 1)
- count += 10;
- return count;
-}
-
-static int
-card_jack(int *db)
-{
- int i, j;
- int cpu[6], c[6], me[6], m[6];
- int cards[52];
-
- for (i = 0; i < 6; i++)
- cpu[i] = c[i] = me[i] = m[i] = -1;
-
- if ((*db) < 0) {
- card_new(cards);
- card_start("¶Â³Ç§J");
- for (i = 0; i < 2; i++) {
- cpu[i] = card_give(cards);
- me[i] = card_give(cards);
- }
- } else {
- card_new(cards);
- cards[*db]=1;
- card_start("¶Â³Ç§JDOUBLE°l¥[§½");
- cpu[0] = card_give(cards);
- cpu[1] = card_give(cards);
- me[0] = *db;
- me[1] = card_give(cards);
- *db = -1;
- }
- c[1] = m[0] = m[1] = 1;
- card_show(6, cpu, c, me, m);
-
- /* black jack */
- if (card_isblackjack(me[0],me[1])) {
- if(card_isblackjack(cpu[0],cpu[1])) {
- c[0]=1;
- card_show(6, cpu, c, me, m);
- game_log(JACK, JACK);
- vmsgf("§A¸ò¹q¸£³£®³¨ì¶Â³Ç§J, °hÁÙ %d ¤¸", JACK);
- return 0;
- }
- game_log(JACK, JACK * 5/2);
- vmsgf("«Ü¤£¿ù­ò! (¶Â³Ç§J!! ¥[ %d ¤¸)", JACK * 5/2);
- return 0;
- } else if(card_isblackjack(cpu[0],cpu[1])) {
- c[0] = 1;
- card_show(6, cpu, c, me, m);
- game_log(JACK, 0);
- vmsg("¼K¼K...¤£¦n·N«ä....¶Â³Ç§J!!");
- return 0;
- }
-
- /* double ©îµP */
- if ((card_number(me[0]) == card_number(me[1])) &&
- (card_double_ask())) {
- *db = me[1];
- me[1] = card_give(cards);
- card_show(6, cpu, c, me, m);
- }
-
- i = 2;
- while (i < 6 && card_ask()) {
- me[i] = card_give(cards);
- m[i] = 1;
- card_show(6, cpu, c, me, m);
- if (card_alls_lower(me) > 21) {
- game_log(JACK, 0);
- vmsg("¶ã¶ã...Ãz±¼¤F!");
- return 0;
- }
- i++;
- }
- if (i == 6) { /* µe­±¥u¯àÂ\¤»±iµP, ¦]¦¹ª½±µºâª±®aĹ. ¶Â³Ç§J¹ê»Ú¤W¨S³o³W«h */
- game_log(JACK, JACK * 10);
- vmsgf("¦n¼F®`­ò! ¤»±iµPÁÙ¨SÃz! ¥[ %d ¤¸!", 5 * JACK);
- return 0;
- }
-
- j = 2;
- c[0] = 1;
- while (j<6 && card_alls_upper(cpu)<=16) {
- cpu[j] = card_give(cards);
- c[j] = 1;
- if (card_alls_lower(cpu) > 21) {
- card_show(6, cpu, c, me, m);
- game_log(JACK, JACK * 2);
- vmsgf("¨þ¨þ...¹q¸£Ãz±¼¤F! §AŤF! ¥i±o %d ¤¸", JACK * 2);
- return 0;
- }
- j++;
- }
- card_show(6, cpu, c, me, m);
- if(card_alls_upper(cpu)==card_alls_upper(me)) {
- game_log(JACK, JACK);
- vmsgf("¥­§½¡A°h¦^ %d ¤¸!", JACK);
- return 0;
- }
- if(card_alls_upper(cpu)<card_alls_upper(me)) {
- game_log(JACK, JACK * 2);
- vmsgf("¨þ¨þ...¹q¸£¤ñ¸û¤p! §AŤF! ¥i±o %d ¤¸", JACK * 2);
- return 0;
- }
- game_log(JACK, 0);
- vmsg("«z«z...¹q¸£Ä¹¤F!");
- return 0;
-}
-
-int
-g_card_jack(void)
-{
- int db;
- char buf[3];
-
- setutmpmode(JACK_CARD);
- while (1) {
- reload_money();
- if (cuser.money < JACK) {
- outs("±zªº¿ú¤£°÷­ò!¥h¦hµoªí¨Ç¦³·N¸qªº¤å³¹¦A¨Ó~~~");
- return 0;
- }
- getdata(b_lines - 1, 0, "½T©w­nª±¶Â³Ç§J¶Ü ¤@¦¸¤Q¤¸­ò?(Y/N)?[N]",
- buf, 3, LCECHO);
- if ((*buf != 'y') && (*buf != 'Y'))
- break;
- else {
- db = -1;
- vice(PMONEY, "¶Â³Ç§J");
- do {
- card_jack(&db);
- } while(db>=0);
- }
- }
- return 0;
-}
-
-static int
-card_all(int all[])
-{
- int i, count = 0;
-
- for (i = 0; i < 5 && all[i] >= 0; i++)
- if (card_number(all[i]) <= 10)
- count += 2 * card_number(all[i]);
- else
- count += 1;
- return count;
-}
-
-static int
-ten_helf(void)
-{
- int i, j;
- int cpu[5], c[5], me[5], m[5];
- int cards[52];
-
- card_start("¤QÂI¥b");
- card_new(cards);
- for (i = 0; i < 5; i++)
- cpu[i] = c[i] = me[i] = m[i] = -1;
-
- cpu[0] = card_give(cards);
- me[0] = card_give(cards);
- m[0] = 1;
- card_show(5, cpu, c, me, m);
- i = 1;
- while (i < 5 && card_ask()) {
- me[i] = card_give(cards);
- m[i] = 1;
- card_show(5, cpu, c, me, m);
- if (card_all(me) > 21) {
- game_log(TEN_HALF, 0);
- vmsg("¶ã¶ã...Ãz±¼¤F!");
- return 0;
- }
- i++;
- }
- if (i == 5) { /* ¹L¤­Ãö */
- game_log(TEN_HALF, PMONEY * 5);
- vmsgf("¦n¼F®`­ò! ¹L¤­Ãö¹Æ! ¥[ %d ¤¸!", 5 * PMONEY);
- return 0;
- }
- j = 1;
- c[0] = 1;
- while (j < 5 && ((card_all(cpu) < card_all(me)) ||
- (card_all(cpu) == card_all(me) && j < i))) {
- cpu[j] = card_give(cards);
- c[j] = 1;
- if (card_all(cpu) > 21) {
- card_show(5, cpu, c, me, m);
- game_log(TEN_HALF, PMONEY * 2);
- vmsgf("¨þ¨þ...¹q¸£Ãz±¼¤F! §AŤF! ¥i±o %d ¤¸", PMONEY * 2);
- return 0;
- }
- j++;
- }
- card_show(5, cpu, c, me, m);
- game_log(TEN_HALF, 0);
- vmsg("«z«z...¹q¸£Ä¹¤F!");
- return 0;
-}
-
-int
-g_ten_helf(void)
-{
- char buf[3];
- int times = 0;
-
- setutmpmode(TENHALF);
- while (1) {
- reload_money();
- if (cuser.money < TEN_HALF) {
- outs("±zªº¿ú¤£°÷­ò!¥h¦hµoªí¨Ç¦³·N¸qªº¤å³¹¦A¨Ó~~~");
- return 0;
- }
-
- if (times++ % 5 == 0)
- {
- move(b_lines-2, 0); clrtoeol();
- outs(ANSI_COLOR(1;31)
- "ĵ§i: ¥»¹CÀ¸¥Ñ PttGames ¬ÝªOµûŲ¬°·¥«×¶Â©±¡A½Ð¤p¤ß¡I" ANSI_RESET);
- }
-
- getdata(b_lines - 1, 0,
- ANSI_COLOR(1;37) "½T©w­nª±¤QÂI¥b¶Ü ¤@¦¸¤Q¤¸­ò?(Y/N)?[N]" ANSI_RESET,
- buf, 3, LCECHO);
- if (buf[0] != 'y' && buf[0] != 'Y')
- return 0;
- else {
- vice(PMONEY, "¤QÂI¥b");
- ten_helf();
- }
- }
- return 0;
-}
diff --git a/mbbsd/chat.c b/mbbsd/chat.c
deleted file mode 100644
index 6623fbc2..00000000
--- a/mbbsd/chat.c
+++ /dev/null
@@ -1,597 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-#ifndef DBCSAWARE
-#define dbcs_off (1)
-#endif
-
-#define STOP_LINE (t_lines-3)
-static int chatline;
-static FILE *flog;
-static void
-printchatline(const char *str)
-{
- move(chatline, 0);
- if (*str == '>' && !PERM_HIDE(currutmp))
- return;
- else if (chatline < STOP_LINE - 1)
- chatline++;
- else {
- region_scroll_up(2, STOP_LINE - 2);
- move(STOP_LINE - 2, 0);
- }
- outs(str);
- outc('\n');
- outs("¡÷");
-
- if (flog)
- fprintf(flog, "%s\n", str);
-}
-
-static void
-chat_clear(char*unused)
-{
- for (chatline = 2; chatline < STOP_LINE; chatline++) {
- move(chatline, 0);
- clrtoeol();
- }
- move(b_lines, 0);
- clrtoeol();
- move(chatline = 2, 0);
- outs("¡÷");
-}
-
-static void
-print_chatid(const char *chatid)
-{
- move(b_lines - 1, 0);
- clrtoeol();
- outs(chatid);
- outc(':');
-}
-
-static int
-chat_send(int fd, const char *buf)
-{
- int len;
- char genbuf[200];
-
- len = snprintf(genbuf, sizeof(genbuf), "%s\n", buf);
- return (send(fd, genbuf, len, 0) == len);
-}
-
-struct ChatBuf {
- char buf[128];
- int bufstart;
-};
-
-static int
-chat_recv(struct ChatBuf *cb, int fd, char *chatroom, char *chatid, size_t chatid_size)
-{
- int c, len;
- char *bptr;
-
- len = sizeof(cb->buf) - cb->bufstart - 1;
- if ((c = recv(fd, cb->buf + cb->bufstart, len, 0)) <= 0)
- return -1;
- c += cb->bufstart;
-
- bptr = cb->buf;
- while (c > 0) {
- len = strlen(bptr) + 1;
- if (len > c && (unsigned)len < (sizeof(cb->buf)/ 2) )
- break;
-
- if (*bptr == '/') {
- switch (bptr[1]) {
- case 'c':
- chat_clear(NULL);
- break;
- case 'n':
- strlcpy(chatid, bptr + 2, chatid_size);
- print_chatid(chatid);
- clrtoeol();
- break;
- case 'r':
- strlcpy(chatroom, bptr + 2, IDLEN);
- break;
- case 't':
- move(0, 0);
- clrtoeol();
- prints(ANSI_COLOR(1;37;46) " ½Í¤Ñ«Ç [%-12s] " ANSI_COLOR(45) " ¸ÜÃD¡G%-48s" ANSI_RESET,
- chatroom, bptr + 2);
- }
- } else
- printchatline(bptr);
-
- c -= len;
- bptr += len;
- }
-
- if (c > 0) {
- memmove(cb->buf, bptr, sizeof(cb->buf)-(bptr-cb->buf));
- cb->bufstart = len - 1;
- } else
- cb->bufstart = 0;
- return 0;
-}
-
-static void
-chathelp(const char *cmd, const char *desc)
-{
- char buf[STRLEN];
-
- snprintf(buf, sizeof(buf), " %-20s- %s", cmd, desc);
- printchatline(buf);
-}
-
-static void
-chat_help(char *arg)
-{
- if (strstr(arg, " op")) {
- printchatline("½Í¤Ñ«ÇºÞ²z­û±M¥Î«ü¥O");
- chathelp("[/f]lag [+-][ls]", "³]©wÂê©w¡B¯µ±Kª¬ºA");
- chathelp("[/i]nvite <id>", "ÁܽР<id> ¥[¤J½Í¤Ñ«Ç");
- chathelp("[/k]ick <id>", "±N <id> ½ð¥X½Í¤Ñ«Ç");
- chathelp("[/o]p <id>", "±N Op ªºÅv¤OÂಾµ¹ <id>");
- chathelp("[/t]opic <text>", "´«­Ó¸ÜÃD");
- chathelp("[/w]all", "¼s¼½ (¯¸ªø±M¥Î)");
- } else {
- // chathelp("[/.]help", "chicken °«Âû¥Î«ü¥O");
- chathelp(" /help op", "½Í¤Ñ«ÇºÞ²z­û±M¥Î«ü¥O");
- chathelp("[//]help", "MUD-like ªÀ¥æ°Êµü");
- chathelp("[/a]ct <msg>", "°µ¤@­Ó°Ê§@");
- chathelp("[/b]ye [msg]", "¹D§O");
- chathelp("[/c]lear", "²M°£¿Ã¹õ");
- chathelp("[/j]oin <room>", "«Ø¥ß©Î¥[¤J½Í¤Ñ«Ç");
- chathelp("[/l]ist [room]", "¦C¥X½Í¤Ñ«Ç¨Ï¥ÎªÌ");
- chathelp("[/m]sg <id> <msg>", "¸ò <id> »¡®¨®¨¸Ü");
- chathelp("[/n]ick <id>", "±N½Í¤Ñ¥N¸¹´«¦¨ <id>");
- chathelp("[/p]ager", "¤Á´«©I¥s¾¹");
- chathelp("[/q]uery <id>", "¬d¸ßºô¤Í");
- chathelp("[/r]oom ", "¦C¥X¤@¯ë½Í¤Ñ«Ç");
- chathelp("[/w]ho", "¦C¥X¥»½Í¤Ñ«Ç¨Ï¥ÎªÌ");
- chathelp(" /whoin <room>", "¦C¥X½Í¤Ñ«Ç<room> ªº¨Ï¥ÎªÌ");
- chathelp(" /ignore <userid>", "©¿²¤«ü©w¨Ï¥ÎªÌªº°T®§");
- chathelp(" /unignore <userid>", "°±¤î©¿²¤«ü©w¨Ï¥ÎªÌªº°T®§");
- }
-}
-
-static void
-chat_date(char *unused)
-{
- char genbuf[200];
-
- snprintf(genbuf, sizeof(genbuf),
- "¡» " BBSNAME "¼Ð·Ç®É¶¡: %s", Cdate(&now));
- printchatline(genbuf);
-}
-
-static void
-chat_pager(char *unused)
-{
- char genbuf[200];
-
- char *msgs[PAGER_MODES] = {
- /* Ref: please match PAGER* in modes.h */
- "Ãö³¬", "¥´¶}", "©Þ±¼", "¨¾¤ô", "¦n¤Í"
- };
-
- snprintf(genbuf, sizeof(genbuf), "¡» ±zªº©I¥s¾¹:[%s]",
- msgs[currutmp->pager = (currutmp->pager + 1) % PAGER_MODES]);
- printchatline(genbuf);
-}
-
-static void
-chat_query(char *arg)
-{
- char *uid;
- int tuid;
- userec_t xuser;
- char *strtok_pos;
-
- printchatline("");
- strtok_r(arg, str_space, &strtok_pos);
- if ((uid = strtok_r(NULL, str_space, &strtok_pos)) && (tuid = getuser(uid, &xuser))) {
- char buf[128], *ptr;
- FILE *fp;
-
- snprintf(buf, sizeof(buf), "%s(%s) ¦@¤W¯¸ %d ¦¸¡Aµoªí¹L %d ½g¤å³¹",
- xuser.userid, xuser.nickname,
- xuser.numlogins, xuser.numposts);
- printchatline(buf);
-
- snprintf(buf, sizeof(buf),
- "³Ìªñ(%s)±q[%s]¤W¯¸", Cdate(&xuser.lastlogin),
- (xuser.lasthost[0] ? xuser.lasthost : "(¤£¸Ô)"));
- printchatline(buf);
-
- sethomefile(buf, xuser.userid, fn_plans);
- if ((fp = fopen(buf, "r"))) {
- tuid = 0;
- while (tuid++ < MAX_QUERYLINES && fgets(buf, 128, fp)) {
- if ((ptr = strchr(buf, '\n')))
- ptr[0] = '\0';
- printchatline(buf);
- }
- fclose(fp);
- }
- } else
- printchatline(err_uid);
-}
-
-typedef struct chat_command_t {
- char *cmdname; /* Chatroom command length */
- void (*cmdfunc) (char *); /* Pointer to function */
-} chat_command_t;
-
-static const chat_command_t chat_cmdtbl[] = {
- {"help", chat_help},
- {"clear", chat_clear},
- {"date", chat_date},
- {"pager", chat_pager},
- {"query", chat_query},
- {NULL, NULL}
-};
-
-static int
-chat_cmd_match(const char *buf, const char *str)
-{
- while (*str && *buf && !isspace((int)*buf))
- if (tolower(*buf++) != *str++)
- return 0;
- return 1;
-}
-
-static int
-chat_cmd(char *buf, int fd)
-{
- int i;
-
- if (*buf++ != '/')
- return 0;
-
- for (i = 0; chat_cmdtbl[i].cmdname; i++) {
- if (chat_cmd_match(buf, chat_cmdtbl[i].cmdname)) {
- chat_cmdtbl[i].cmdfunc(buf);
- return 1;
- }
- }
- return 0;
-}
-
-#define MAXLASTCMD 6
-static int chatid_len = 10;
-static time4_t lastEnter = 0;
-
-int
-t_chat(void)
-{
- char chatroom[IDLEN];/* Chat-Room Name */
- char inbuf[80], chatid[20], lastcmd[MAXLASTCMD][80], *ptr = "";
- struct sockaddr_in sin;
- int cfd, cmdpos, ch;
- int currchar;
- int chatting = YEA;
- char fpath[80];
- struct ChatBuf chatbuf;
-
- if(HasUserPerm(PERM_VIOLATELAW))
- {
- vmsg("½Ð¥ýú»@³æ¤~¯à¨Ï¥Î²á¤Ñ«Ç!");
- return -1;
- }
-
- syncnow();
-
-#ifdef CHAT_GAPMINS
- if ((now - lastEnter)/60 < CHAT_GAPMINS)
- {
- vmsg("±z¤~­èÂ÷¶}²á¤Ñ«Ç¡A¸Ì­±¥¿¦b¾ã²z¤¤¡C½Ðµy«á¦A¸Õ¡C");
- return 0;
- }
-#endif
-
-#ifdef CHAT_REGDAYS
- if ((now - cuser.firstlogin)/86400 < CHAT_REGDAYS)
- {
- int i = CHAT_REGDAYS - (now-cuser.firstlogin)/86400 +1;
- vmsgf("±zÁÙ¤£°÷¸ê²`³á (¦Aµ¥ %d ¤Ñ§a)", i);
- return 0;
- }
-#endif
-
- memset(&chatbuf, 0, sizeof(chatbuf));
- outs(" ÅX¨®«e©¹ ½Ð±é­Ô........ ");
-
- memset(&sin, 0, sizeof sin);
-#ifdef __FreeBSD__
- sin.sin_len = sizeof(sin);
-#endif
- sin.sin_family = PF_INET;
- sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- sin.sin_port = htons(NEW_CHATPORT);
- cfd = socket(sin.sin_family, SOCK_STREAM, 0);
- if (connect(cfd, (struct sockaddr *) & sin, sizeof sin) != 0) {
- outs("\n "
- "«z! ¨S¤H¦b¨ºÃä­C...­n¦³¨º¦a¤èªº¤H¥ý¥h¶}ªù°Õ!...");
- system("bin/xchatd");
- pressanykey();
- close(cfd);
- return -1;
- }
-
- while (1) {
- getdata(b_lines - 1, 0, "½Ð¿é¤J²á¤Ñ¥N¸¹¡G", chatid, 9, DOECHO);
- if(!chatid[0])
- strlcpy(chatid, cuser.userid, sizeof(chatid));
- chatid[8] = '\0';
- /*
- * ·s®æ¦¡: /! UserID ChatID Password
- */
- snprintf(inbuf, sizeof(inbuf), "/! %s %s %s",
- cuser.userid, chatid, cuser.passwd);
- chat_send(cfd, inbuf);
- if (recv(cfd, inbuf, 3, 0) != 3) {
- close(cfd);
- vmsg("¨t²Î¿ù»~¡C");
- return 0;
- }
- if (!strcmp(inbuf, CHAT_LOGIN_OK))
- break;
- else if (!strcmp(inbuf, CHAT_LOGIN_EXISTS))
- ptr = "³o­Ó¥N¸¹¤w¸g¦³¤H¥Î¤F";
- else if (!strcmp(inbuf, CHAT_LOGIN_INVALID))
- ptr = "³o­Ó¥N¸¹¬O¿ù»~ªº";
- else if (!strcmp(inbuf, CHAT_LOGIN_BOGUS))
- ptr = "½Ð¤Å¬£»º¤À¨­¶i¤J²á¤Ñ«Ç !!";
-
- move(b_lines - 2, 0);
- outs(ptr);
- clrtoeol();
- bell();
- }
- syncnow();
- lastEnter = now;
-
- add_io(cfd, 0);
-
- currchar = 0;
- cmdpos = -1;
- memset(lastcmd, 0, sizeof(lastcmd));
-
- setutmpmode(CHATING);
- currutmp->in_chat = YEA;
- strlcpy(currutmp->chatid, chatid, sizeof(currutmp->chatid));
-
- clear();
- chatline = 2;
-
- move(STOP_LINE, 0);
- outs(msg_seperator);
- move(STOP_LINE, 56);
- outs(" /h ¬d¸ß«ü¥O /b Â÷¶} ");
- move(1, 0);
- outs(msg_seperator);
- print_chatid(chatid);
- memset(inbuf, 0, sizeof(inbuf));
-
- setuserfile(fpath, "chat_XXXXXX");
- flog = fdopen(mkstemp(fpath), "w");
-
- while (chatting) {
- move(b_lines - 1, currchar + chatid_len);
- ch = igetch();
-
- switch (ch) {
- case KEY_DOWN:
- cmdpos += MAXLASTCMD - 2;
- case KEY_UP:
- cmdpos++;
- cmdpos %= MAXLASTCMD;
- strlcpy(inbuf, lastcmd[cmdpos], sizeof(inbuf));
- move(b_lines - 1, chatid_len);
- clrtoeol();
- outs(inbuf);
- currchar = strlen(inbuf);
- continue;
- case KEY_LEFT:
- if (currchar)
- {
- --currchar;
-#ifdef DBCSAWARE
- if(currchar > 0 &&
- ISDBCSAWARE() &&
- getDBCSstatus((unsigned char*)inbuf, currchar) == DBCS_TRAILING)
- currchar --;
-#endif
- }
- continue;
- case KEY_RIGHT:
- if (inbuf[currchar])
- {
- ++currchar;
-#ifdef DBCSAWARE
- if(inbuf[currchar] &&
- ISDBCSAWARE() &&
- getDBCSstatus((unsigned char*)inbuf, currchar) == DBCS_TRAILING)
- currchar++;
-#endif
- }
- continue;
- case KEY_UNKNOWN:
- continue;
- }
-
- if (ISNEWMAIL(currutmp)) {
- printchatline("¡» ¾´¡I¶l®t¤S¨Ó¤F...");
- }
- if (ch == I_OTHERDATA) {/* incoming */
- if (chat_recv(&chatbuf, cfd, chatroom, chatid, 9) == -1) {
- chatting = chat_send(cfd, "/b");
- break;
- }
- } else if (isprint2(ch)) {
- if (currchar < 68) {
- if (inbuf[currchar]) { /* insert */
- int i;
-
- for (i = currchar; inbuf[i] && i < 68; i++);
- inbuf[i + 1] = '\0';
- for (; i > currchar; i--)
- inbuf[i] = inbuf[i - 1];
- } else /* append */
- inbuf[currchar + 1] = '\0';
- inbuf[currchar] = ch;
- move(b_lines - 1, currchar + chatid_len);
- outs(&inbuf[currchar++]);
- }
- } else if (ch == '\n' || ch == '\r') {
- if (*inbuf) {
-
-#ifdef EXP_ANTIFLOOD
- // prevent flooding */
- static time4_t lasttime = 0;
- static int flood = 0;
-
- /* // debug anti flodding
- move(b_lines-3, 0); clrtoeol();
- prints("lasttime=%d, now=%d, flood=%d\n",
- lasttime, now, flood);
- refresh();
- */
- syncnow();
- if (now - lasttime < 3 )
- {
- // 3 ¬í¤º¬~¥b­±¬O¤£¦æªº ((25-5)/2)
- if( ++flood > 10 ){
- // flush all input!
- drop_input();
- while (wait_input(1, 0))
- {
- if (num_in_buf())
- drop_input();
- else
- tty_read((unsigned char*)inbuf, sizeof(inbuf));
- }
- drop_input();
- vmsg("½Ð¤Å¤j¶q°Å¶K©Î³y¦¨¬~ªO­±ªº®ÄªG¡C");
- // log?
- sleep(2);
- continue;
- }
- } else {
- lasttime = now;
- flood = 0;
- }
-#endif // anti-flood
-
- chatting = chat_cmd(inbuf, cfd);
- if (chatting == 0)
- chatting = chat_send(cfd, inbuf);
- if (!strncmp(inbuf, "/b", 2))
- break;
-
- for (cmdpos = MAXLASTCMD - 1; cmdpos; cmdpos--)
- strlcpy(lastcmd[cmdpos],
- lastcmd[cmdpos - 1], sizeof(lastcmd[cmdpos]));
- strlcpy(lastcmd[0], inbuf, sizeof(lastcmd[0]));
-
- inbuf[0] = '\0';
- currchar = 0;
- cmdpos = -1;
- }
- print_chatid(chatid);
- move(b_lines - 1, chatid_len);
- } else if (ch == Ctrl('H') || ch == '\177') {
- if (currchar) {
-#ifdef DBCSAWARE
- int dbcs_off = 1;
- if (ISDBCSAWARE() &&
- getDBCSstatus((unsigned char*)inbuf, currchar-1) == DBCS_TRAILING)
- dbcs_off = 2;
-#endif
- currchar -= dbcs_off;
- inbuf[69] = '\0';
- memcpy(&inbuf[currchar], &inbuf[currchar + dbcs_off],
- 69 - currchar);
- move(b_lines - 1, currchar + chatid_len);
- clrtoeol();
- outs(&inbuf[currchar]);
- }
- } else if (ch == Ctrl('Z') || ch == Ctrl('Y')) {
- inbuf[0] = '\0';
- currchar = 0;
- print_chatid(chatid);
- move(b_lines - 1, chatid_len);
- } else if (ch == Ctrl('C')) {
- chat_send(cfd, "/b");
- break;
- } else if (ch == Ctrl('D')) {
- if ((size_t)currchar < strlen(inbuf)) {
-#ifdef DBCSAWARE
- int dbcs_off = 1;
- if (ISDBCSAWARE() && inbuf[currchar+1] &&
- getDBCSstatus((unsigned char*)inbuf, currchar+1) == DBCS_TRAILING)
- dbcs_off = 2;
-#endif
- inbuf[69] = '\0';
- memcpy(&inbuf[currchar], &inbuf[currchar + dbcs_off],
- 69 - currchar);
- move(b_lines - 1, currchar + chatid_len);
- clrtoeol();
- outs(&inbuf[currchar]);
- }
- } else if (ch == Ctrl('K')) {
- inbuf[currchar] = 0;
- move(b_lines - 1, currchar + chatid_len);
- clrtoeol();
- } else if (ch == Ctrl('A')) {
- currchar = 0;
- } else if (ch == Ctrl('E')) {
- currchar = strlen(inbuf);
- } else if (ch == Ctrl('I')) {
- screen_backup_t old_screen;
-
- scr_dump(&old_screen);
- add_io(0, 0);
- t_idle();
- scr_restore(&old_screen);
- add_io(cfd, 0);
- } else if (ch == Ctrl('Q')) {
- print_chatid(chatid);
- move(b_lines - 1, chatid_len);
- outs(inbuf);
- continue;
- }
- }
-
- close(cfd);
- add_io(0, 0);
- currutmp->in_chat = currutmp->chatid[0] = 0;
-
- if (flog) {
- char ans[4];
-
- fclose(flog);
- more(fpath, NA);
- getdata(b_lines - 1, 0, "²M°£(C) ²¾¦Ü³Æ§Ñ¿ý(M) (C/M)?[C]",
- ans, sizeof(ans), LCECHO);
- if (*ans == 'm') {
- fileheader_t mymail;
- char title[128];
- char genbuf[200];
-
- sethomepath(genbuf, cuser.userid);
- stampfile(genbuf, &mymail);
- mymail.filemode = FILE_READ ;
- strlcpy(mymail.owner, "[³Æ.§Ñ.¿ý]", sizeof(mymail.owner));
- strlcpy(mymail.title, "·|ij" ANSI_COLOR(1;33) "°O¿ý" ANSI_RESET, sizeof(mymail.title));
- sethomedir(title, cuser.userid);
- append_record(title, &mymail, sizeof(mymail));
- Rename(fpath, genbuf);
- } else
- unlink(fpath);
- }
- return 0;
-}
diff --git a/mbbsd/chc.c b/mbbsd/chc.c
deleted file mode 100644
index 602fc37e..00000000
--- a/mbbsd/chc.c
+++ /dev/null
@@ -1,1012 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-#include "chc.h"
-
-#define assert_not_reached() assert(!"Should never be here!!!")
-
-extern const double elo_exp_tab[1000];
-
-enum Turn {
- BLK = 0,
- RED
-};
-
-enum Kind {
- KIND_K=1,
- KIND_A,
- KIND_E,
- KIND_R,
- KIND_H,
- KIND_C,
- KIND_P,
-};
-#define CENTER(a, b) (((a) + (b)) >> 1)
-#define CHC_TIMEOUT 300
-
-#define PHOTO_LINE 15
-#define PHOTO_COLUMN (256 + 25)
-
-typedef struct drc_t {
- ChessStepType type; /* necessary one */
- rc_t from, to;
-} drc_t;
-
-typedef struct {
- rc_t select;
- char selected;
-} chc_tag_data_t;
-
-/* chess framework action functions */
-static void chc_init_user(const userinfo_t *uinfo, ChessUser *user);
-static void chc_init_user_userec(const userec_t *urec, ChessUser *user);
-static void chc_init_board(board_t board);
-static void chc_drawline(const ChessInfo* info, int line);
-static void chc_movecur(int r, int c);
-static int chc_prepare_play(ChessInfo* info);
-static int chc_select(ChessInfo* info, rc_t scrloc, ChessGameResult* result);
-static void chc_prepare_step(ChessInfo* info, const void* step);
-static ChessGameResult chc_movechess(board_t board, const drc_t* move);
-static void chc_drawstep(ChessInfo* info, const drc_t* move);
-static void chc_gameend(ChessInfo* info, ChessGameResult result);
-static void chc_genlog(ChessInfo* info, FILE* fp, ChessGameResult result);
-
-
-static const char * const turn_color[2]={BLACK_COLOR, RED_COLOR};
-
-/* some constant variable definition */
-
-static const char * const turn_str[2] = {"¶Âªº", "¬õªº"};
-
-static const char * const num_str[2][10] = {
- {"", "¢°", "¢±", "¢²", "¢³", "¢´", "¢µ", "¢¶", "¢·", "¢¸"},
- {"", "¤@", "¤G", "¤T", "¥|", "¤­", "¤»", "¤C", "¤K", "¤E"},
-};
-
-static const char * const chess_str[2][8] = {
- /* 0 1 2 3 4 5 6 7 */
- {" ", "±N", "¤h", "¶H", "¨®", "°¨", "¥]", "¨ò"},
- {" ", "«Ó", "¥K", "¬Û", "¨®", "ØX", "¬¶", "§L"}
-};
-
-static const char * const chess_brd[BRD_ROW * 2 - 1] = {
- /* 0 1 2 3 4 5 6 7 8 */
- "¢z¢w¢s¢w¢s¢w¢s¢w¢s¢w¢s¢w¢s¢w¢s¢w¢{", /* 0 */
- "¢x ¢x ¢x ¢x¢@¢x¡þ¢x ¢x ¢x ¢x",
- "¢u¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢t", /* 1 */
- "¢x ¢x ¢x ¢x¡þ¢x¢@¢x ¢x ¢x ¢x",
- "¢u¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢t", /* 2 */
- "¢x ¢x ¢x ¢x ¢x ¢x ¢x ¢x ¢x",
- "¢u¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢t", /* 3 */
- "¢x ¢x ¢x ¢x ¢x ¢x ¢x ¢x ¢x",
- "¢u¢w¢r¢w¢r¢w¢r¢w¢r¢w¢r¢w¢r¢w¢r¢w¢t", /* 4 */
- "¢x ·¡ ªe º~ ¬É ¢x",
- "¢u¢w¢s¢w¢s¢w¢s¢w¢s¢w¢s¢w¢s¢w¢s¢w¢t", /* 5 */
- "¢x ¢x ¢x ¢x ¢x ¢x ¢x ¢x ¢x",
- "¢u¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢t", /* 6 */
- "¢x ¢x ¢x ¢x ¢x ¢x ¢x ¢x ¢x",
- "¢u¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢t", /* 7 */
- "¢x ¢x ¢x ¢x¢@¢x¡þ¢x ¢x ¢x ¢x",
- "¢u¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢t", /* 8 */
- "¢x ¢x ¢x ¢x¡þ¢x¢@¢x ¢x ¢x ¢x",
- "¢|¢w¢r¢w¢r¢w¢r¢w¢r¢w¢r¢w¢r¢w¢r¢w¢}" /* 9 */
-};
-
-static char * const hint_str[] = {
- " q »{¿éÂ÷¶}",
- " p ­n¨D©M´Ñ",
- "¤è¦VÁä ²¾°Ê¹C¼Ð",
- "Enter ¿ï¾Ü/²¾°Ê"
-};
-
-static const ChessActions chc_actions = {
- &chc_init_user,
- &chc_init_user_userec,
- (void (*) (void*)) &chc_init_board,
- &chc_drawline,
- &chc_movecur,
- &chc_prepare_play,
- NULL, /* process_key */
- &chc_select,
- &chc_prepare_step,
- (ChessGameResult (*) (void*, const void*)) &chc_movechess,
- (void (*)(ChessInfo*, const void*)) &chc_drawstep,
- NULL, /* post_game */
- &chc_gameend,
- &chc_genlog
-};
-
-static const ChessConstants chc_constants = {
- sizeof(drc_t),
- CHC_TIMEOUT,
- BRD_ROW,
- BRD_COL,
- 0,
- "·¡ªeº~¬É",
- "photo_cchess",
-#ifdef GLOBAL_CCHESS_LOG
- GLOBAL_CCHESS_LOG,
-#else
- NULL,
-#endif
- { BLACK_COLOR, RED_COLOR },
- {"¶Âªº", "¬õªº"}
-};
-
-/*
- * Start of the drawing function.
- */
-static void
-chc_movecur(int r, int c)
-{
- move(r * 2 + 3, c * 4 + 4);
-}
-
-static char *
-getstep(board_t board, const rc_t *from, const rc_t *to, char buf[])
-{
- int turn, fc, tc;
- char *dir;
- int twin = 0, twin_r = 0;
- int len = 0;
-
- turn = CHE_O(board[from->r][from->c]);
- if(CHE_P(board[from->r][from->c] != KIND_P)) { // TODO ¥Ø«e¤£ºÞ§L¨ò«e«á
- int i;
- for(i=0;i<10;i++)
- if(board[i][from->c]==board[from->r][from->c]) {
- if(i!=from->r) {
- twin=1;
- twin_r=i;
- }
- }
- }
- fc = (turn == BLK ? from->c + 1 : 9 - from->c);
- tc = (turn == BLK ? to->c + 1 : 9 - to->c);
- if (from->r == to->r)
- dir = "¥­";
- else {
- if (from->c == to->c)
- tc = from->r - to->r;
- if (tc < 0)
- tc = -tc;
-
- if ((turn == BLK && to->r > from->r) ||
- (turn == RED && to->r < from->r))
- dir = "¶i";
- else
- dir = "°h";
- }
-
-
- len=sprintf(buf, "%s", turn_color[turn]);
- /* ØX¤G|«eØX */
- if(twin) {
- len+=sprintf(buf+len, "%s%s",
- ((from->r>twin_r)==(turn==(BLK)))?"«e":"«á",
- chess_str[turn][CHE_P(board[from->r][from->c])]);
- } else {
- len+=sprintf(buf+len, "%s%s",
- chess_str[turn][CHE_P(board[from->r][from->c])],
- num_str[turn][fc]);
- }
- /* ¶i¤T */
- len+=sprintf(buf+len, "%s%s" ANSI_RESET, dir, num_str[turn][tc]);
- /* ¡G¶H */
- if(board[to->r][to->c]) {
- len+=sprintf(buf+len,"¡G%s%s" ANSI_RESET,
- turn_color[turn^1],
- chess_str[turn^1][CHE_P(board[to->r][to->c])]);
- }
- return buf;
-}
-
-inline static const char*
-chc_timestr(int second)
-{
- static char str[10];
- snprintf(str, sizeof(str), "%d:%02d", second / 60, second % 60);
- return str;
-}
-
-static void
-chc_drawline(const ChessInfo* info, int line)
-{
- int i, j;
- board_p board = (board_p) info->board;
- chc_tag_data_t *tag = info->tag;
-
- if (line == 0) {
- prints(ANSI_COLOR(1;46) " ¶H´Ñ¹ï¾Ô " ANSI_COLOR(45)
- "%30s VS %-20s%10s" ANSI_RESET,
- info->user1.userid, info->user2.userid,
- info->mode == CHESS_MODE_WATCH ? "[Æ[´Ñ¼Ò¦¡]" : "");
- } else if (line >= 3 && line <= 21) {
- outs(" ");
- for (i = 0; i < 9; i++) {
- j = board[RTL(info,line)][CTL(info,i)];
- if ((line & 1) == 1 && j) {
- if (tag->selected &&
- tag->select.r == RTL(info,line) && tag->select.c == CTL(info,i)) {
- prints("%s%s" ANSI_RESET,
- CHE_O(j) == BLK ? BLACK_REVERSE : RED_REVERSE,
- chess_str[CHE_O(j)][CHE_P(j)]);
- }
- else {
- prints("%s%s" ANSI_RESET,
- turn_color[CHE_O(j)],
- chess_str[CHE_O(j)][CHE_P(j)]);
- }
- } else
- prints("%c%c", chess_brd[line - 3][i * 4],
- chess_brd[line - 3][i * 4 + 1]);
- if (i != 8)
- prints("%c%c", chess_brd[line - 3][i * 4 + 2],
- chess_brd[line - 3][i * 4 + 3]);
- }
- } else if (line == 2 || line == 22) {
- outs(" ");
- if (line == 2)
- for (i = 1; i <= 9; i++)
- prints("%s ", num_str[REDDOWN(info)?0:1][i]);
- else
- for (i = 9; i >= 1; i--)
- prints("%s ", num_str[REDDOWN(info)?1:0][i]);
- }
-
- ChessDrawExtraInfo(info, line, 8);
-}
-/*
- * End of the drawing function.
- */
-
-
-/*
- * Start of the log function.
- */
-
-static void
-chc_log_machine_step(FILE* fp, board_t board, const drc_t *step)
-{
- const static char chess_char[8] = {
- 0, 'K', 'A', 'B', 'R', 'N', 'C', 'P'
- };
- /* We have black at bottom in rc_t but the standard is
- * the red side at bottom, so that a rotation is needed. */
- fprintf(fp, "%c%c%d%c%c%d ",
- chess_char[CHE_P(board[step->from.r][step->from.c])],
- step->from.c + 'a', BRD_ROW - step->from.r - 1,
- board[step->to.r][step->to.c] ? 'x' : '-',
- step->to.c + 'a', BRD_ROW - step->to.r - 1
- );
-}
-
-static int
-#if defined(__linux__)
-chc_filter(const struct dirent *dir)
-#else
-chc_filter(struct dirent *dir)
-#endif
-{
- if (strcmp(dir->d_name, ".") == 0 || strcmp(dir->d_name, "..") == 0 )
- return 0;
- return strstr(dir->d_name, ".poem") != NULL;
-}
-
-static int
-chc_log_poem(FILE* outfp)
-{
- struct dirent **namelist;
- int n;
-
- // TODO use readdir(), don't use lots of memory
- n = scandir(BBSHOME"/etc/chess", &namelist, chc_filter, alphasort);
- if (n < 0)
- perror("scandir");
- else {
- char buf[80];
- FILE *fp;
- sprintf(buf, BBSHOME"/etc/chess/%s", namelist[random() % n]->d_name);
- if ((fp = fopen(buf, "r")) == NULL)
- return -1;
-
- while(fgets(buf, sizeof(buf), fp) != NULL)
- fputs(buf, outfp);
- while(n--)
- free(namelist[n]);
- free(namelist);
- fclose(fp);
- }
- return 0;
-}
-
-static void
-chc_genlog(ChessInfo* info, FILE* fp, ChessGameResult result)
-{
- const int nStep = info->history.used;
- board_t board;
- int i;
-
- fprintf(fp, "«ö z ¥i¶i¤J¥´ÃмҦ¡\n");
- fprintf(fp, "\n");
-
- if (info->myturn == RED)
- fprintf(fp, "%s(%d) V.S. %s(%d)\n",
- info->user1.userid, info->user1.orig_rating,
- info->user2.userid, info->user2.orig_rating);
- else
- fprintf(fp, "%s(%d) V.S. %s(%d)\n",
- info->user2.userid, info->user2.orig_rating,
- info->user1.userid, info->user1.orig_rating);
-
- chc_init_board(board);
- /* format: "%3d. %8.8s %8.8s %3d. %8.8s %8.8s\n" */
- for (i = 0; i < nStep; i++) {
- char buf[80];
- const drc_t *move = (const drc_t*) ChessHistoryRetrieve(info, i);
- buf[0]='\0';
- if (move->type == CHESS_STEP_NORMAL) {
- getstep(board, &move->from, &move->to, buf);
- chc_movechess(board, move);
- if(i%2==0) fprintf(fp, "%3d. ",i/2+1);
- strip_ansi(buf, buf, STRIP_ALL);
- fprintf(fp, "%8.8s ", buf);
- if(i%4==3 || i==nStep-1) fputc('\n', fp);
- }
- }
-
- if (result == CHESS_RESULT_TIE)
- fprintf(fp, "=> ©M§½\n");
- else if (result == CHESS_RESULT_WIN || result == CHESS_RESULT_LOST)
- fprintf(fp, "=> %s ³Ó\n",
- (info->myturn == RED) == (result== CHESS_RESULT_WIN) ?
- "¬õ" : "¶Â");
-
- /* generate machine readable log.
- * http://www.elephantbase.net/protocol/cchess_pgn.htm */
- {
- /* machine readable header */
- time_t temp = (time_t) now;
- struct tm *mytm = localtime(&temp);
-
- fprintf(fp,
- "\n\n<chclog>\n"
- "[Game \"Chinese Chess\"]\n"
- "[Date \"%d.%d.%d\"]\n"
- "[Red \"%s\"]\n"
- "[Black \"%s\"]\n",
- mytm->tm_year + 1900, mytm->tm_mon + 1, mytm->tm_mday,
- info->myturn == RED ? info->user1.userid : info->user2.userid,
- info->myturn == RED ? info->user2.userid : info->user1.userid
- );
-
- if (result == CHESS_RESULT_TIE || result == CHESS_RESULT_WIN ||
- result == CHESS_RESULT_LOST)
- fprintf(fp, "[Result \"%s\"]\n",
- result == CHESS_RESULT_TIE ? "0.5-0.5" :
- (info->myturn == RED) == (result== CHESS_RESULT_WIN) ?
- "1-0" : "0-1");
- else
- fprintf(fp, "[Result \"*\"]\n");
-
- fprintf(fp,
- "[Notation \"Coord\"]\n"
- "[FEN \"rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR"
- " r - - 0 1\"]\n");
- }
- chc_init_board(board);
- for (i = 0; i < nStep - 1; i += 2) {
- const drc_t *move = (const drc_t*) ChessHistoryRetrieve(info, i);
- fprintf(fp, "%2d. ", i / 2 + 1);
- if (move->type == CHESS_STEP_NORMAL) {
- chc_log_machine_step(fp, board, move);
- chc_movechess(board, move);
- }
-
- fputs(" ", fp);
-
- move = (const drc_t*) ChessHistoryRetrieve(info, i + 1);
- if (move->type == CHESS_STEP_NORMAL) {
- chc_log_machine_step(fp, board, move);
- chc_movechess(board, move);
- }
-
- fputc('\n', fp);
- }
- if (i < nStep) {
- const drc_t *move = (const drc_t*) ChessHistoryRetrieve(info, i);
- if (move->type == CHESS_STEP_NORMAL) {
- fprintf(fp, "%2d. ", i / 2 + 1);
- chc_log_machine_step(fp, board, move);
- fputc('\n', fp);
- }
- }
-
- fputs("</chclog>\n\n--\n\n", fp);
- chc_log_poem(fp);
-}
-/*
- * End of the log function.
- */
-
-
-/*
- * Start of the rule function.
- */
-static void
-chc_init_board(board_t board)
-{
- memset(board, 0, sizeof(board_t));
- board[0][4] = CHE(KIND_K, BLK); /* ±N */
- board[0][3] = board[0][5] = CHE(KIND_A, BLK); /* ¤h */
- board[0][2] = board[0][6] = CHE(KIND_E, BLK); /* ¶H */
- board[0][0] = board[0][8] = CHE(KIND_R, BLK); /* ¨® */
- board[0][1] = board[0][7] = CHE(KIND_H, BLK); /* °¨ */
- board[2][1] = board[2][7] = CHE(KIND_C, BLK); /* ¥] */
- board[3][0] = board[3][2] = board[3][4] =
- board[3][6] = board[3][8] = CHE(KIND_P, BLK); /* ¨ò */
-
- board[9][4] = CHE(KIND_K, RED); /* «Ó */
- board[9][3] = board[9][5] = CHE(KIND_A, RED); /* ¥K */
- board[9][2] = board[9][6] = CHE(KIND_E, RED); /* ¬Û */
- board[9][0] = board[9][8] = CHE(KIND_R, RED); /* ¨® */
- board[9][1] = board[9][7] = CHE(KIND_H, RED); /* ØX */
- board[7][1] = board[7][7] = CHE(KIND_C, RED); /* ¦ */
- board[6][0] = board[6][2] = board[6][4] =
- board[6][6] = board[6][8] = CHE(KIND_P, RED); /* §L */
-}
-
-static void
-chc_prepare_step(ChessInfo* info, const void* step)
-{
- const drc_t* move = (const drc_t*) step;
- getstep((board_p) info->board,
- &move->from, &move->to, info->last_movestr);
-}
-
-static ChessGameResult
-chc_movechess(board_t board, const drc_t* move)
-{
- int end = (CHE_P(board[move->to.r][move->to.c]) == KIND_K);
-
- board[move->to.r][move->to.c] = board[move->from.r][move->from.c];
- board[move->from.r][move->from.c] = 0;
-
- return end ? CHESS_RESULT_WIN : CHESS_RESULT_CONTINUE;
-}
-
-static void
-chc_drawstep(ChessInfo* info, const drc_t* move)
-{
- ChessDrawLine(info, LTR(info, move->from.r));
- ChessDrawLine(info, LTR(info, move->to.r));
-}
-
-/* ¨D¨â®y¼Ð¦æ©Î¦C(rowcol)ªº¶ZÂ÷ */
-static int
-dist(rc_t from, rc_t to, int rowcol)
-{
- int d;
-
- d = rowcol ? from.c - to.c : from.r - to.r;
- return d > 0 ? d : -d;
-}
-
-/* ¨â®y¼Ð(¦æ©Î¦Crowcol)¤¤¶¡¦³´XÁû´Ñ¤l */
-static int
-between(board_t board, rc_t from, rc_t to, int rowcol)
-{
- int i, rtv = 0;
-
- if (rowcol) {
- if (from.c > to.c)
- i = from.c, from.c = to.c, to.c = i;
- for (i = from.c + 1; i < to.c; i++)
- if (board[to.r][i])
- rtv++;
- } else {
- if (from.r > to.r)
- i = from.r, from.r = to.r, to.r = i;
- for (i = from.r + 1; i < to.r; i++)
- if (board[i][to.c])
- rtv++;
- }
- return rtv;
-}
-
-static int
-chc_canmove(board_t board, rc_t from, rc_t to)
-{
- int i;
- int rd, cd, turn;
-
- if(0 ||
- !(0<=from.r && from.r<BRD_ROW) ||
- !(0<=from.c && from.c<BRD_COL) ||
- !(0<=to.r && to.r<BRD_ROW) ||
- !(0<=to.c && to.c<BRD_COL))
- return 0;
-
- rd = dist(from, to, 0);
- cd = dist(from, to, 1);
- turn = CHE_O(board[from.r][from.c]);
-
- /* general check */
- if (board[to.r][to.c] && CHE_O(board[to.r][to.c]) == turn)
- return 0;
-
- /* individual check */
- switch (CHE_P(board[from.r][from.c])) {
- case KIND_K: /* ±N «Ó */
- if (!(rd == 1 && cd == 0) &&
- !(rd == 0 && cd == 1))
- return 0;
- if ((turn == BLK && to.r > 2) ||
- (turn == RED && to.r < 7) ||
- to.c < 3 || to.c > 5)
- return 0;
- break;
- case KIND_A: /* ¤h ¥K */
- if (!(rd == 1 && cd == 1))
- return 0;
- if ((turn == BLK && to.r > 2) ||
- (turn == RED && to.r < 7) ||
- to.c < 3 || to.c > 5)
- return 0;
- break;
- case KIND_E: /* ¶H ¬Û */
- if (!(rd == 2 && cd == 2))
- return 0;
- if ((turn == BLK && to.r > 4) ||
- (turn == RED && to.r < 5))
- return 0;
- /* ©ä¶H»L */
- if (board[CENTER(from.r, to.r)][CENTER(from.c, to.c)])
- return 0;
- break;
- case KIND_R: /* ¨® */
- if (!(rd > 0 && cd == 0) &&
- !(rd == 0 && cd > 0))
- return 0;
- if (between(board, from, to, rd == 0))
- return 0;
- break;
- case KIND_H: /* °¨ ØX */
- if (!(rd == 2 && cd == 1) &&
- !(rd == 1 && cd == 2))
- return 0;
- /* ©ä°¨¸} */
- if (rd == 2) {
- if (board[CENTER(from.r, to.r)][from.c])
- return 0;
- } else {
- if (board[from.r][CENTER(from.c, to.c)])
- return 0;
- }
- break;
- case KIND_C: /* ¥] ¬¶ */
- if (!(rd > 0 && cd == 0) &&
- !(rd == 0 && cd > 0))
- return 0;
- i = between(board, from, to, rd == 0);
- if ((i > 1) ||
- (i == 1 && !board[to.r][to.c]) ||
- (i == 0 && board[to.r][to.c]))
- return 0;
- break;
- case KIND_P: /* ¨ò §L */
- if (!(rd == 1 && cd == 0) &&
- !(rd == 0 && cd == 1))
- return 0;
- if (((turn == BLK && to.r < 5) ||
- (turn == RED && to.r > 4)) &&
- cd != 0)
- return 0;
- if ((turn == BLK && to.r < from.r) ||
- (turn == RED && to.r > from.r))
- return 0;
- break;
- }
- return 1;
-}
-
-/* §ä turn's king ªº®y¼Ð */
-static int
-findking(board_t board, int turn, rc_t * buf)
-{
- int i, r, c;
-
- r = (turn == BLK ? 0 : 7);
- for (i = 0; i < 3; r++, i++)
- for (c = 3; c < 6; c++)
- if (CHE_P(board[r][c]) == KIND_K &&
- CHE_O(board[r][c]) == turn) {
- buf->r = r, buf->c = c;
- return 1;
- }
- /* one's king may be eaten */
- return 0;
-}
-
-static int
-chc_iskfk(board_t board)
-{
- rc_t from, to;
-
- if (!findking(board, BLK, &to)) return 0;
- if (!findking(board, RED, &from)) return 0;
- if (from.c == to.c && between(board, from, to, 0) == 0)
- return 1;
- return 0;
-}
-
-static int
-chc_ischeck(board_t board, int turn)
-{
- rc_t from, to;
-
- if (!findking(board, turn, &to)) return 0;
- for (from.r = 0; from.r < BRD_ROW; from.r++)
- for (from.c = 0; from.c < BRD_COL; from.c++)
- if (board[from.r][from.c] &&
- CHE_O(board[from.r][from.c]) != turn)
- if (chc_canmove(board, from, to))
- return 1;
- return 0;
-}
-/*
- * End of the rule function.
- */
-
-static void
-chcusr_put(userec_t* userec, const ChessUser* user)
-{
- userec->chc_win = user->win;
- userec->chc_lose = user->lose;
- userec->chc_tie = user->tie;
- userec->chess_elo_rating = user->rating;
-}
-
-static void
-chc_init_user(const userinfo_t *uinfo, ChessUser *user)
-{
- strlcpy(user->userid, uinfo->userid, sizeof(user->userid));
- user->win = uinfo->chc_win;
- user->lose = uinfo->chc_lose;
- user->tie = uinfo->chc_tie;
- user->rating = uinfo->chess_elo_rating;
- if(user->rating == 0)
- user->rating = 1500; /* ELO initial value */
- user->orig_rating = user->rating;
-}
-
-static void
-chc_init_user_userec(const userec_t *urec, ChessUser *user)
-{
- strlcpy(user->userid, urec->userid, sizeof(user->userid));
- user->win = urec->chc_win;
- user->lose = urec->chc_lose;
- user->tie = urec->chc_tie;
- user->rating = urec->chess_elo_rating;
- if(user->rating == 0)
- user->rating = 1500; /* ELO initial value */
- user->orig_rating = user->rating;
-}
-
-static int
-chc_prepare_play(ChessInfo* info)
-{
- if (chc_ischeck((board_p) info->board, info->turn)) {
- strlcpy(info->warnmsg, ANSI_COLOR(1;31) "±N­x!" ANSI_RESET,
- sizeof(info->warnmsg));
- bell();
- } else
- info->warnmsg[0] = 0;
-
- return 0;
-}
-
-static int
-chc_select(ChessInfo* info, rc_t scrloc, ChessGameResult* result)
-{
- chc_tag_data_t* tag = (chc_tag_data_t*) info->tag;
- board_p board = (board_p) info->board;
- rc_t loc;
-
- assert(tag);
-
- /* transform from screen to internal coordinate */
- if(REDDOWN(info)) {
- loc = scrloc;
- } else {
- loc.r = BRD_ROW-scrloc.r-1;
- loc.c = BRD_COL-scrloc.c-1;
- }
-
- if (!tag->selected) {
- /* trying to pick something */
- if (board[loc.r][loc.c] &&
- CHE_O(board[loc.r][loc.c]) == info->turn) {
- /* they can pick up this */
- tag->selected = 1;
- tag->select = loc;
- ChessDrawLine(info, LTR(info, loc.r));
- }
- return 0;
- } else if (tag->select.r == loc.r && tag->select.c == loc.c) {
- /* cancel selection */
- tag->selected = 0;
- ChessDrawLine(info, LTR(info, loc.r));
- return 0;
- } else if (chc_canmove(board, tag->select, loc)) {
- /* moving the chess */
- drc_t moving = { CHESS_STEP_NORMAL, tag->select, loc };
- board_t tmpbrd;
- int valid_step = 1;
-
- if (CHE_P(board[loc.r][loc.c]) == KIND_K)
- /* ²¾¨ì¹ï¤è±N«Ó */
- *result = CHESS_RESULT_WIN;
- else {
- memcpy(tmpbrd, board, sizeof(board_t));
- chc_movechess(tmpbrd, &moving);
- valid_step = !chc_iskfk(tmpbrd);
- }
-
- if (valid_step) {
- getstep(board, &moving.from, &moving.to, info->last_movestr);
-
- chc_movechess(board, &moving);
- ChessDrawLine(info, LTR(info, moving.from.r));
- ChessDrawLine(info, LTR(info, moving.to.r));
-
- ChessHistoryAppend(info, &moving);
- ChessStepSend(info, &moving);
-
- tag->selected = 0;
- return 1;
- } else {
- /* ¤ý¨£¤ý */
- strlcpy(info->warnmsg,
- ANSI_COLOR(1;33) "¤£¥i¥H¤ý¨£¤ý" ANSI_RESET,
- sizeof(info->warnmsg));
- bell();
- ChessDrawLine(info, CHESS_DRAWING_WARN_ROW);
- return 0;
- }
- } else
- /* nothing happened */
- return 0;
-}
-
-int round_to_int(double x)
-{
- /* assume that double cast to int will drop fraction parts */
- if(x>=0)
- return (int)(x+0.5);
- return (int)(x-0.5);
-}
-
-/*
- * ELO rating system
- * see http://www.wordiq.com/definition/ELO_rating_system
- */
-static void
-count_chess_elo_rating(ChessUser* user1, const ChessUser* user2, double myres)
-{
- double k;
- double exp_res;
- int diff;
- int newrating;
-
- if(user1->rating < 1800)
- k = 30;
- else if(user1->rating < 2000)
- k = 25;
- else if(user1->rating < 2200)
- k = 20;
- else if(user1->rating < 2400)
- k = 15;
- else
- k = 10;
-
- //exp_res = 1.0/(1.0 + pow(10.0, (user2->rating-user1->rating)/400.0));
- //user1->rating += (int)floor(k*(myres-exp_res)+0.5);
- diff=(int)user2->rating-(int)user1->rating;
- if(diff<=-1000 || diff>=1000)
- exp_res=diff>0?0.0:1.0;
- else if(diff>=0)
- exp_res=elo_exp_tab[diff];
- else
- exp_res=1.0-elo_exp_tab[-diff];
- newrating = (int)user1->rating + round_to_int(k*(myres-exp_res));
- if(newrating > 3000) newrating = 3000;
- if(newrating < 1) newrating = 1;
- user1->rating = newrating;
-}
-
-
-/* ¶H´Ñ¥\¯à¶i¤JÂI:
- * chc_main: ¹ï«³
- * chc_personal: ¥´ÃÐ
- * chc_watch: Æ[´Ñ
- * talk.c: ¹ï«³
- */
-void
-chc(int s, ChessGameMode mode)
-{
- ChessInfo* info = NewChessInfo(&chc_actions, &chc_constants, s, mode);
- board_t board;
- chc_tag_data_t tag;
-
- chc_init_board(board);
- tag.selected = 0;
-
- info->board = board;
- info->tag = &tag;
-
- if (info->mode == CHESS_MODE_VERSUS) {
- /* Assume that info->user1 is me. */
- info->user1.lose++;
- count_chess_elo_rating(&info->user1, &info->user2, 0.0);
- passwd_query(usernum, &cuser);
- chcusr_put(&cuser, &info->user1);
- passwd_update(usernum, &cuser);
- }
-
- if (mode == CHESS_MODE_WATCH)
- setutmpmode(CHESSWATCHING);
- else
- setutmpmode(CHC);
- currutmp->sig = SIG_CHC;
-
- ChessPlay(info);
-
- DeleteChessInfo(info);
-}
-
-static void
-chc_gameend(ChessInfo* info, ChessGameResult result)
-{
- ChessUser* const user1 = &info->user1;
- ChessUser* const user2 = &info->user2;
-
- if (info->mode == CHESS_MODE_VERSUS) {
- if (info->myturn == RED) {
- /* ¥Ñ¬õ¤è§@ log. °Oªº¬O¤U´Ñ«eªº­ì©l¤À¼Æ */
- /* NOTE, ­Y¬õ¤èÂ_½u«hµL log */
- time_t t = time(NULL);
- char buf[100];
- sprintf(buf, "%s %s(%d,W%d/D%d/L%d) %s %s(%d,W%d/D%d/L%d)\n",
- ctime(&t),
- user1->userid, user1->rating, user1->win,
- user1->tie, user1->lose - 1,
- (result == CHESS_RESULT_TIE ? "©M" :
- result == CHESS_RESULT_WIN ? "³Ó" : "­t"),
- user2->userid, user2->rating, user2->win,
- user2->tie, user2->lose - 1);
- buf[24] = ' '; // replace '\n'
- log_file(BBSHOME "/log/chc.log", LOG_CREAT, buf);
- }
-
- user1->rating = user1->orig_rating;
- user1->lose--;
- if (result == CHESS_RESULT_WIN) {
- count_chess_elo_rating(user1, user2, 1.0);
- user1->win++;
- currutmp->chc_win++;
- } else if (result == CHESS_RESULT_LOST) {
- count_chess_elo_rating(user1, user2, 0.0);
- user1->lose++;
- currutmp->chc_lose++;
- } else {
- count_chess_elo_rating(user1, user2, 0.5);
- user1->tie++;
- currutmp->chc_tie++;
- }
- currutmp->chess_elo_rating = user1->rating;
- chcusr_put(&cuser, user1);
- passwd_update(usernum, &cuser);
- } else if (info->mode == CHESS_MODE_REPLAY) {
- free(info->board);
- free(info->tag);
- }
-}
-
-int
-chc_main(void)
-{
- return ChessStartGame('c', SIG_CHC, "·¡ªeº~¬É¤§ª§");
-}
-
-int
-chc_personal(void)
-{
- chc(0, CHESS_MODE_PERSONAL);
- return 0;
-}
-
-int
-chc_watch(void)
-{
- return ChessWatchGame(&chc, CHC, "·¡ªeº~¬É¤§ª§");
-}
-
-ChessInfo*
-chc_replay(FILE* fp)
-{
- ChessInfo *info;
- char buf[256];
-
- info = NewChessInfo(&chc_actions, &chc_constants,
- 0, CHESS_MODE_REPLAY);
-
- while (fgets(buf, sizeof(buf), fp)) {
- if (strcmp("</chclog>\n", buf) == 0)
- break;
- if (buf[0] == '[') {
- if (strncmp(buf + 1, "Red", 3) == 0 ||
- strncmp(buf + 1, "Black", 5) == 0) {
- /* /\[(Red|Black) "([a-zA-Z0-9]+)"\]/; $2 */
- userec_t rec;
- char *userid;
- char *strtok_pos = NULL;
- ChessUser *user =
- (buf[1] == 'R' ? &info->user1 : &info->user2);
-
- strtok_r(buf, "\"", &strtok_pos);
- userid = strtok_r(NULL, "\"", &strtok_pos);
- if (userid != NULL && getuser(userid, &rec))
- chc_init_user_userec(&rec, user);
- }
- } else {
- /* " 1. Ch2-e2 Nb9-c7" */
- drc_t step = { CHESS_STEP_NORMAL };
- const char *p = strchr(buf, '.');
-
- if (p == NULL) continue;
-
- ++p; /* skip '.' */
- while (*p && isspace(*p)) ++p;
- if (!*p) continue;
-
- /* p -> "Ch2-e2 ...." */
- step.from.c = p[1] - 'a';
- step.from.r = BRD_ROW - 1 - (p[2] - '0');
- step.to.c = p[4] - 'a';
- step.to.r = BRD_ROW - 1 - (p[5] - '0');
-
-#define INVALID_ROW(R) ((R) < 0 || (R) >= BRD_ROW)
-#define INVALID_COL(C) ((C) < 0 || (C) >= BRD_COL)
-#define INVALID_LOC(S) (INVALID_ROW(S.r) || INVALID_COL(S.c))
- if (INVALID_LOC(step.from) || INVALID_LOC(step.to))
- continue;
- ChessHistoryAppend(info, &step);
-
- p += 6;
- while (*p && isspace(*p)) ++p;
- if (!*p) continue;
-
- /* p -> "Nb9-c7\n" */
- step.from.c = p[1] - 'a';
- step.from.r = BRD_ROW - 1 - (p[2] - '0');
- step.to.c = p[4] - 'a';
- step.to.r = BRD_ROW - 1 - (p[5] - '0');
-
- if (INVALID_LOC(step.from) || INVALID_LOC(step.to))
- continue;
- ChessHistoryAppend(info, &step);
-
-#undef INVALID_ROW
-#undef INVALID_COL
-#undef INVALID_LOC
- }
- }
-
- info->board = malloc(sizeof(board_t));
- info->tag = malloc(sizeof(chc_tag_data_t));
-
- chc_init_board(info->board);
- ((chc_tag_data_t*) info->tag)->selected = 0;
-
- return info;
-}
diff --git a/mbbsd/chc_tab.c b/mbbsd/chc_tab.c
deleted file mode 100644
index 4bed88ab..00000000
--- a/mbbsd/chc_tab.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/* $Id$ */
-
-/* generated by perl -le 'print 1/(1+10**($_/400)),"," for 0 ..999' */
-/* TODO reduce table size */
-const double elo_exp_tab[1000]={
-0.5, 0.498560888290847, 0.497121800425189, 0.49568276024494, 0.494243791588855, 0.492804918290949, 0.491366164178917, 0.489927553072562, 0.488489108782208, 0.487050855107136,
-0.485612815834001, 0.484175014735265, 0.482737475567624, 0.481300222070441, 0.479863277964184, 0.478426666948855, 0.476990412702438, 0.475554538879339, 0.474119069108831, 0.472684026993507,
-0.471249436107731, 0.469815319996098, 0.468381702171893, 0.466948606115559, 0.465516055273168, 0.464084073054898, 0.462652682833507, 0.461221907942828, 0.459791771676254, 0.458362297285237,
-0.456933507977788, 0.455505426916992, 0.454078077219516, 0.452651481954135, 0.451225664140258, 0.449800646746463, 0.448376452689039, 0.446953104830538, 0.445530625978324, 0.444109038883147,
-0.442688366237707, 0.441268630675239, 0.439849854768097, 0.438432061026354, 0.437015271896404, 0.435599509759579, 0.434184796930767, 0.432771155657048, 0.431358608116332, 0.429947176416012,
-0.428536882591619, 0.427127748605496, 0.425719796345476, 0.42431304762357, 0.422907524174671, 0.421503247655257, 0.420100239642119, 0.418698521631085, 0.41729811503577, 0.415899041186322,
-0.414501321328191, 0.4131049766209, 0.411710028136837, 0.41031649686005, 0.408924403685057, 0.407533769415668, 0.406144614763822, 0.404756960348428, 0.403370826694226, 0.401986234230656,
-0.400603203290743, 0.399221754109989, 0.397841906825283, 0.396463681473822, 0.395087097992043, 0.393712176214572, 0.39233893587318, 0.39096739659576, 0.389597577905311, 0.388229499218936,
-0.386863179846857, 0.385498638991442, 0.384135895746244, 0.382774969095054, 0.381415877910969, 0.380058640955477, 0.378703276877545, 0.377349804212738, 0.375998241382333, 0.374648606692463,
-0.373300918333268, 0.371955194378058, 0.370611452782498, 0.369269711383798, 0.367929987899926, 0.366592299928832, 0.365256664947683, 0.363923100312118, 0.362591623255515, 0.361262250888275,
-0.359935000197115, 0.358609888044382, 0.35728693116738, 0.355966146177707, 0.354647549560618, 0.353331157674385, 0.352016986749694, 0.350705052889036, 0.349395372066127, 0.348087960125336,
-0.34678283278113, 0.345480005617534, 0.344179494087605, 0.342881313512921, 0.341585479083087, 0.340292005855252, 0.339000908753642, 0.337712202569111, 0.336425901958705, 0.335142021445235,
-0.333860575416878, 0.332581578126777, 0.331305043692668, 0.330030986096517, 0.328759419184168, 0.327490356665015, 0.326223812111678, 0.324959798959701, 0.323698330507263, 0.322439419914899,
-0.321183080205243, 0.319929324262779, 0.318678164833606, 0.317429614525228, 0.316183685806341, 0.31494039100665, 0.313699742316688, 0.312461751787658, 0.311226431331287, 0.309993792719686,
-0.308763847585237, 0.307536607420482, 0.306312083578035, 0.305090287270497, 0.3038712295704, 0.302654921410147, 0.301441373581977, 0.300230596737942, 0.299022601389892, 0.297817397909479,
-0.296614996528171, 0.295415407337279, 0.294218640287997, 0.293024705191459, 0.291833611718799, 0.290645369401237, 0.289459987630162, 0.288277475657245, 0.287097842594546, 0.28592109741465,
-0.284747248950801, 0.283576305897061, 0.282408276808469, 0.281243170101218, 0.280080994052848, 0.27892175680244, 0.277765466350829, 0.276612130560829, 0.275461757157464, 0.274314353728213,
-0.273169927723269, 0.272028486455804, 0.270890037102247, 0.269754586702576, 0.268622142160612, 0.267492710244332, 0.266366297586193, 0.265242910683453, 0.264122555898524, 0.263005239459311,
-0.261890967459581, 0.260779745859332, 0.25967158048517, 0.2585664770307, 0.25746444105693, 0.256365477992672, 0.255269593134965, 0.254176791649501, 0.253087078571057, 0.252000458803946,
-0.250916937122464, 0.249836518171358, 0.248759206466289, 0.247685006394318, 0.246613922214385, 0.245545958057814, 0.244481117928803, 0.243419405704947, 0.242360825137748, 0.241305379853144,
-0.240253073352042, 0.239203909010858, 0.238157890082064, 0.237115019694746, 0.236075300855161, 0.235038736447311, 0.234005329233511, 0.232975081854979, 0.231947996832416, 0.230924076566607,
-0.229903323339018, 0.228885739312403, 0.227871326531416, 0.226860086923233, 0.225852022298169, 0.224847134350316, 0.223845424658169, 0.222846894685274, 0.221851545780868, 0.22085937918053,
-0.219870396006841, 0.218884597270038, 0.217901983868681, 0.216922556590324, 0.215946316112185, 0.214973263001828, 0.214003397717843, 0.213036720610531, 0.212073231922598, 0.211112931789845,
-0.210155820241869, 0.209201897202762, 0.208251162491816, 0.207303615824231, 0.206359256811831, 0.205418084963771, 0.204480099687258, 0.203545300288274, 0.202613685972296, 0.201685255845022,
-0.200760008913102, 0.199837944084864, 0.198919060171054, 0.198003355885567, 0.197090829846184, 0.196181480575316, 0.195275306500741, 0.19437230595635, 0.193472477182892, 0.192575818328721,
-0.191682327450541, 0.190792002514162, 0.189904841395243, 0.189020841880052, 0.188140001666213, 0.187262318363465, 0.186387789494413, 0.185516412495288, 0.184648184716699, 0.183783103424397,
-0.182921165800026, 0.182062368941884, 0.181206709865685, 0.180354185505311, 0.179504792713577, 0.178658528262988, 0.177815388846498, 0.176975371078268, 0.176138471494428, 0.175304686553832,
-0.174474012638818, 0.173646446055968, 0.17282198303686, 0.17200061973883, 0.171182352245724, 0.170367176568657, 0.169555088646763, 0.168746084347953, 0.167940159469667, 0.167137309739621,
-0.166337530816562, 0.165540818291017, 0.164747167686039, 0.163956574457953, 0.163169033997105, 0.162384541628603, 0.161603092613057, 0.160824682147324, 0.160049305365247, 0.159276957338385,
-0.158507633076758, 0.157741327529574, 0.156978035585964, 0.156217752075707, 0.155460471769965, 0.154706189382, 0.153954899567905, 0.153206596927319, 0.15246127600415, 0.151718931287288,
-0.150979557211323, 0.150243148157254, 0.149509698453197, 0.148779202375097, 0.148051654147426, 0.147327047943889, 0.146605377888118, 0.145886638054376, 0.14517082246824, 0.144457925107303,
-0.14374793990185, 0.143040860735552, 0.142336681446143, 0.141635395826102, 0.140936997623326, 0.140241480541804, 0.139548838242288, 0.138859064342957, 0.138172152420082, 0.137488096008689,
-0.13680688860321, 0.136128523658142, 0.135452994588696, 0.134780294771442, 0.134110417544956, 0.13344335621046, 0.132779104032456, 0.132117654239364, 0.131459000024148, 0.130803134544946,
-0.130150050925691, 0.12949974225673, 0.128852201595444, 0.128207421966856, 0.12756539636424, 0.12692611774973, 0.126289579054919, 0.125655773181454, 0.125024693001636, 0.124396331359007,
-0.123770681068935, 0.123147734919203, 0.12252748567058, 0.121909926057404, 0.121295048788149, 0.120682846545992, 0.120073311989383, 0.119466437752599, 0.118862216446302, 0.118260640658093,
-0.117661702953059, 0.117065395874318, 0.116471711943561, 0.115880643661586, 0.115292183508836, 0.114706323945921, 0.11412305741415, 0.113542376336049, 0.112964273115878, 0.112388740140145,
-0.111815769778117, 0.111245354382322, 0.110677486289053, 0.110112157818867, 0.109549361277075, 0.108989088954235, 0.108431333126633, 0.107876086056773, 0.107323339993846, 0.106773087174209,
-0.106225319821854, 0.105680030148872, 0.10513721035592, 0.104596852632671, 0.104058949158278, 0.103523492101814, 0.102990473622727, 0.102459885871276, 0.101931720988974, 0.101405971109018,
-0.100882628356723, 0.100361684849949, 0.0998431326995192, 0.0993269640096439, 0.0988131708783323, 0.098301745397805, 0.0977926796549003, 0.0972859657314782, 0.0967815957048192, 0.0962795616480201,
-0.095779855630386, 0.0952824697178176, 0.0947873959731961, 0.0942946264567625, 0.0938041532264949, 0.0933159683384805, 0.0928300638472852, 0.092346431806318, 0.091865064268193, 0.0913859532850863,
-0.0909090909090909, 0.090434469192566, 0.0899620801884838, 0.0894919159507723, 0.0890239685346547, 0.0885582299969842, 0.0880946923965764, 0.087633347794537, 0.0871741882545869, 0.0867172058433825,
-0.0862623926308338, 0.0858097406904174, 0.0853592420994873, 0.0849108889395813, 0.0844646732967243, 0.0840205872617279, 0.0835786229304866, 0.0831387724042701, 0.0827010277900133, 0.0822653812006012,
-0.081831824755152, 0.0814003505792954, 0.0809709508054486, 0.0805436175730883, 0.0801183430290193, 0.0796951193276405, 0.0792739386312066, 0.0788547931100871, 0.0784376749430217, 0.0780225763173731,
-0.0776094894293755, 0.0771984064843805, 0.0767893196971002, 0.0763822212918461, 0.0759771035027654, 0.0755739585740745, 0.0751727787602884, 0.0747735563264481, 0.0743762835483439, 0.0739809527127362,
-0.0735875561175735, 0.0731960860722064, 0.0728065348975995, 0.0724188949265399, 0.0720331585038426, 0.0716493179865537, 0.0712673657441495, 0.0708872941587333, 0.0705090956252296, 0.070132762551575,
-0.0697582873589063, 0.0693856624817454, 0.0690148803681826, 0.0686459334800556, 0.0682788142931266, 0.0679135152972565, 0.0675500289965762, 0.0671883479096555, 0.0668284645696687, 0.0664703715245584,
-0.0661140613371956, 0.0657595265855382, 0.065406759862786, 0.0650557537775339, 0.0647065009539218, 0.0643589940317823, 0.064013225666786, 0.063669188530584, 0.0633268753109479, 0.0629862787119077,
-0.0626473914538869, 0.062310206273835, 0.061974715925358, 0.0616409131788465, 0.0613087908216012, 0.0609783416579556, 0.0606495585093978, 0.0603224342146881, 0.059996961629976, 0.0596731336289135,
-0.0593509431027676, 0.059030382960529, 0.05871144612902, 0.0583941255529991, 0.0580784141952641, 0.057764305036753, 0.0574517910766422, 0.0571408653324433, 0.0568315208400973, 0.0565237506540668,
-0.0562175478474267, 0.0559129055119519, 0.0556098167582034, 0.055308274715613, 0.0550082725325648, 0.0547098033764762, 0.0544128604338752, 0.0541174369104776, 0.0538235260312609, 0.0535311210405369,
-0.0532402152020224, 0.0529508017989083, 0.0526628741339259, 0.0523764255294125, 0.0520914493273749, 0.0518079388895503, 0.0515258875974668, 0.0512452888525009, 0.0509661360759343, 0.0506884227090081,
-0.0504121422129759, 0.0501372880691551, 0.0498638537789762, 0.0495918328640312, 0.0493212188661195, 0.0490520053472927, 0.048784185889898, 0.0485177540966194, 0.0482527035905178, 0.0479890280150698,
-0.0477267210342039, 0.0474657763323368, 0.0472061876144066, 0.0469479486059058, 0.0466910530529121, 0.0464354947221181, 0.0461812674008591, 0.0459283648971404, 0.0456767810396624, 0.0454265096778444,
-0.0451775446818476, 0.0449298799425962, 0.0446835093717973, 0.0444384269019598, 0.0441946264864115, 0.0439521020993153, 0.043710847735684, 0.0434708574113939, 0.0432321251631971, 0.0429946450487326,
-0.0427584111465361, 0.0425234175560489, 0.0422896583976254, 0.0420571278125395, 0.0418258199629894, 0.0415957290321026, 0.0413668492239378, 0.0411391747634878, 0.0409126998966793, 0.0406874188903736,
-0.0404633260323643, 0.0402404156313758, 0.0400186820170589, 0.0397981195399872, 0.0395787225716511, 0.0393604855044517, 0.039143402751693, 0.0389274687475736, 0.0387126779471775, 0.0384990248264637,
-0.0382865038822547, 0.0380751096322249, 0.0378648366148868, 0.0376556793895778, 0.0374476325364447, 0.0372406906564285, 0.0370348483712476, 0.0368301003233803, 0.0366264411760469, 0.0364238656131903,
-0.0362223683394563, 0.0360219440801729, 0.035822587581329, 0.0356242936095519, 0.0354270569520846, 0.035230872416762, 0.0350357348319863, 0.0348416390467019, 0.0346485799303695, 0.0344565523729396,
-0.034265551284825, 0.0340755715968728, 0.0338866082603359, 0.0336986562468435, 0.0335117105483713, 0.0333257661772106, 0.0331408181659374, 0.0329568615673801, 0.0327738914545875, 0.0325919029207952,
-0.0324108910793922, 0.0322308510638868, 0.0320517780278711, 0.0318736671449865, 0.0316965136088869, 0.0315203126332028, 0.0313450594515039, 0.0311707493172619, 0.030997377503812, 0.0308249393043144,
-0.0306534300317155, 0.0304828450187082, 0.0303131796176917, 0.0301444292007309, 0.029976589159516, 0.0298096549053202, 0.0296436218689585, 0.0294784855007451, 0.0293142412704504, 0.0291508846672584,
-0.0289884111997226, 0.0288268163957223, 0.0286660958024179, 0.0285062449862065, 0.0283472595326764, 0.0281891350465617, 0.0280318671516965, 0.0278754514909685, 0.0277198837262722, 0.0275651595384624,
-0.0274112746273065, 0.027258224711437, 0.0271060055283037, 0.0269546128341251, 0.0268040424038402, 0.0266542900310593, 0.0265053515280152, 0.0263572227255133, 0.0262098994728823, 0.0260633776379237,
-0.0259176531068621, 0.0257727217842942, 0.0256285795931381, 0.0254852224745825, 0.0253426463880351, 0.0252008473110712, 0.0250598212393821, 0.0249195641867229, 0.0247800721848603, 0.0246413412835205,
-0.024503367550336, 0.0243661470707936, 0.0242296759481806, 0.0240939503035322, 0.0239589662755777, 0.0238247200206873, 0.023691207712818, 0.0235584255434599, 0.0234263697215824, 0.0232950364735793,
-0.0231644220432153, 0.0230345226915706, 0.022905334696987, 0.0227768543550127, 0.0226490779783474, 0.0225220018967874, 0.0223956224571704, 0.0222699360233201, 0.0221449389759909, 0.0220206277128122,
-0.0218969986482334, 0.0217740482134672, 0.0216517728564348, 0.0215301690417093, 0.0214092332504601, 0.0212889619803967, 0.0211693517457127, 0.0210503990770294, 0.0209321005213396, 0.0208144526419513,
-0.0206974520184315, 0.0205810952465492, 0.0204653789382196, 0.0203502997214468, 0.020235854240268, 0.0201220391546963, 0.0200088511406639, 0.0198962868899661, 0.0197843431102039, 0.0196730165247275,
-0.0195623038725795, 0.0194522019084381, 0.0193427074025603, 0.0192338171407248, 0.0191255279241757, 0.0190178365695651, 0.0189107399088966, 0.0188042347894684, 0.0186983180738161, 0.0185929866396565,
-0.0184882373798301, 0.018384067202245, 0.0182804730298193, 0.018177451800425, 0.0180750004668308, 0.0179731159966456, 0.0178717953722618, 0.0177710355907984, 0.0176708336640446, 0.0175711866184031,
-0.0174720914948334, 0.0173735453487957, 0.0172755452501937, 0.0171780882833188, 0.0170811715467935, 0.0169847921535149, 0.0168889472305988, 0.0167936339193229, 0.0166988493750711, 0.0166045907672773,
-0.0165108552793692, 0.0164176401087122, 0.016324942466554, 0.0162327595779682, 0.0161410886817987, 0.0160499270306043, 0.0159592718906025, 0.0158691205416144, 0.015779470277009, 0.0156903184036477,
-0.0156016622418296, 0.0155134991252354, 0.0154258264008728, 0.0153386414290214, 0.0152519415831777, 0.0151657242500001, 0.0150799868292543, 0.0149947267337584, 0.0149099413893287, 0.0148256282347247,
-0.0147417847215951, 0.0146584083144236, 0.0145754964904743, 0.0144930467397378, 0.0144110565648775, 0.0143295234811753, 0.0142484450164782, 0.0141678187111446, 0.0140876421179904, 0.0140079128022362,
-0.0139286283414535, 0.0138497863255119, 0.0137713843565254, 0.0136934200488004, 0.0136158910287821, 0.0135387949350018, 0.0134621294180251, 0.0133858921403984, 0.0133100807765973, 0.013234693012974,
-0.0131597265477055, 0.0130851790907414, 0.0130110483637521, 0.0129373321000772, 0.012864028044674, 0.0127911339540658, 0.0127186475962907, 0.0126465667508506, 0.0125748892086599, 0.0125036127719948,
-0.0124327352544424, 0.0123622544808501, 0.0122921682872752, 0.0122224745209343, 0.0121531710401534, 0.0120842557143176, 0.0120157264238212, 0.011947581060018, 0.0118798175251715, 0.0118124337324056,
-0.011745427605655, 0.011678797079616, 0.0116125400996976, 0.0115466546219725, 0.0114811386131282, 0.0114159900504184, 0.0113512069216147, 0.0112867872249579, 0.0112227289691102, 0.0111590301731066,
-0.0110956888663077, 0.0110327030883515, 0.0109700708891056, 0.0109077903286204, 0.0108458594770813, 0.0107842764147616, 0.0107230392319756, 0.0106621460290318, 0.010601594916186, 0.0105413840135952,
-0.0104815114512704, 0.0104219753690314, 0.0103627739164598, 0.0103039052528536, 0.0102453675471813, 0.0101871589780362, 0.010129277733591, 0.0100717220115526, 0.0100144900191167, 0.00995757997292287,
-0.0099009900990099, 0.00984471863277092, 0.00978876381890891, 0.00973312391139234, 0.00967779717341093, 0.00962278187733161, 0.0095680763046546, 0.00951367874596964, 0.00945958750091243, 0.00940580087812116,
-0.00935231719519326, 0.00929913477864222, 0.00924625196385471, 0.0091936670950477, 0.00914137852522583, 0.00908938461613893, 0.00903768373823964, 0.00898627427064129, 0.0089351546010758, 0.0088843231258519,
-0.00883377824981334, 0.0087835183862974, 0.00873354195709348, 0.00868384739240183, 0.0086344331307925, 0.00858529761916441, 0.00853643931270459, 0.00848785667484757, 0.00843954817723491, 0.00839151229967492,
-0.00834374753010252, 0.00829625236453928, 0.00824902530705355, 0.00820206486972079, 0.00815536957258412, 0.0081089379436149, 0.00806276851867354, 0.0080168598414705, 0.00797121046352733, 0.00792581894413801,
-0.00788068385033028, 0.00783580375682733, 0.00779117724600942, 0.00774680290787585, 0.00770267934000696, 0.00765880514752633, 0.00761517894306313, 0.00757179934671464, 0.0075286649860089, 0.00748577449586748,
-0.00744312651856853, 0.00740071970370979, 0.00735855270817197, 0.0073166241960821, 0.00727493283877711, 0.00723347731476759, 0.00719225630970166, 0.00715126851632898, 0.00711051263446494, 0.00706998737095503,
-0.00702969143963924, 0.0069896235613168, 0.00694978246371089, 0.00691016688143358, 0.00687077555595097, 0.00683160723554835, 0.00679266067529564, 0.00675393463701289, 0.00671542788923597, 0.0066771392071824,
-0.00663906737271731, 0.00660121117431959, 0.00656356940704816, 0.00652614087250834, 0.00648892437881847, 0.00645191874057659, 0.00641512277882729, 0.00637853532102875, 0.00634215520101984, 0.00630598125898744,
-0.00627001234143384, 0.00623424730114438, 0.00619868499715511, 0.0061633242947207, 0.00612816406528242, 0.0060932031864363, 0.00605844054190145, 0.00602387502148844, 0.00598950552106793, 0.00595533094253937,
-0.00592135019379986, 0.00588756218871312, 0.00585396584707868, 0.00582056009460114, 0.00578734386285955, 0.00575431608927702, 0.00572147571709038, 0.00568882169532006, 0.00565635297873998, 0.00562406852784773,
-0.00559196730883478, 0.00556004829355687, 0.00552831045950453, 0.00549675278977371, 0.00546537427303661, 0.00543417390351256, 0.00540315068093909, 0.00537230361054314, 0.00534163170301236, 0.00531113397446655,
-0.00528080944642931, 0.0052506571457997, 0.00522067610482413, 0.00519086536106833, 0.00516122395738946, 0.00513175094190839, 0.00510244536798201, 0.00507330629417583, 0.00504433278423651, 0.00501552390706472,
-0.00498687873668797, 0.00495839635223365, 0.00493007583790219, 0.00490191628294032, 0.00487391678161447, 0.00484607643318431, 0.00481839434187639, 0.00479086961685795, 0.00476350137221078, 0.00473628872690529,
-0.00470923080477461, 0.00468232673448895, 0.00465557564952992, 0.00462897668816509, 0.00460252899342262, 0.00457623171306605, 0.00455008399956917, 0.00452408501009101, 0.00449823390645103, 0.00447252985510432,
-0.00444697202711696, 0.00442155959814155, 0.00439629174839279, 0.00437116766262323, 0.00434618653009909, 0.00432134754457622, 0.0042966499042762, 0.00427209281186252, 0.0042476754744169, 0.00422339710341572,
-0.00419925691470652, 0.00417525412848474, 0.0041513879692704, 0.00412765766588505, 0.00410406245142876, 0.00408060156325719, 0.00405727424295889, 0.00403407973633253, 0.00401101729336447, 0.00398808616820623,
-0.0039652856191522, 0.00394261490861742, 0.00392007330311544, 0.00389766007323639, 0.00387537449362501, 0.00385321584295892, 0.00383118340392695, 0.00380927646320752, 0.00378749431144725, 0.00376583624323957,
-0.00374430155710349, 0.00372288955546247, 0.00370159954462335, 0.00368043083475547, 0.00365938273986982, 0.00363845457779834, 0.00361764567017327, 0.0035969553424067, 0.0035763829236701, 0.00355592774687406,
-0.00353558914864806, 0.00351536646932039, 0.00349525905289814, 0.0034752662470473, 0.00345538740307297, 0.00343562187589965, 0.00341596902405165, 0.00339642820963361, 0.00337699879831106, 0.00335768015929115,
-0.00333847166530343, 0.00331937269258077, 0.00330038262084031, 0.00328150083326457, 0.00326272671648265, 0.00324405966055149, 0.00322549905893724, 0.00320704430849675, 0.00318869480945912, 0.00317044996540738,
-};
diff --git a/mbbsd/chess.c b/mbbsd/chess.c
deleted file mode 100644
index a86ca766..00000000
--- a/mbbsd/chess.c
+++ /dev/null
@@ -1,1762 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-#include "chess.h"
-#include <setjmp.h>
-
-#define assert_not_reached() assert(!"Should never be here!!!")
-#define dim(x) (sizeof(x) / sizeof(x[0]))
-
-#define CHESS_HISTORY_INITIAL_BUFFER_SIZE 300
-#define CHESS_HISTORY_BUFFER_INCREMENT 50
-
-#define CHESS_DRAWING_SIDE_ROW 7
-#define CHESS_DRAWING_REAL_TURN_ROW 8
-#define CHESS_DRAWING_REAL_STEP_ROW 9
-#define CHESS_DRAWING_REAL_TIME_ROW1 10
-#define CHESS_DRAWING_REAL_TIME_ROW2 11
-#define CHESS_DRAWING_REAL_WARN_ROW 13
-#define CHESS_DRAWING_MYWIN_ROW 17
-#define CHESS_DRAWING_HISWIN_ROW 18
-#define CHESS_DRAWING_PHOTOED_STEP_ROW 18
-#define CHESS_DRAWING_PHOTOED_TURN_ROW 19
-#define CHESS_DRAWING_PHOTOED_TIME_ROW1 20
-#define CHESS_DRAWING_PHOTOED_TIME_ROW2 21
-#define CHESS_DRAWING_PHOTOED_WARN_ROW 22
-
-#define CONNECT_PEER() add_io(info->sock, 0)
-#define IGNORE_PEER() add_io(0, 0)
-
-#define DO_WITHOUT_PEER(TIMEOUT,ACT,ELSE) \
- do { \
- void (*orig_alarm_handler)(int) = \
- Signal(SIGALRM, &SigjmpEnv); \
- IGNORE_PEER(); \
- if(sigsetjmp(sigjmpEnv, 1)) \
- ELSE; \
- else { \
- alarm(TIMEOUT); \
- ACT; \
- } \
- CONNECT_PEER(); \
- Signal(SIGALRM, orig_alarm_handler); \
- } while(0)
-
-static const char * const ChessHintStr[] = {
- " q »{¿éÂ÷¶}",
- " p ­n¨D©M´Ñ",
- "¤è¦VÁä ²¾°Ê¹C¼Ð",
- "Enter ¿ï¾Ü/²¾°Ê"
-};
-
-static const struct {
- const char* name;
- int name_len;
- ChessInfo* (*func)(FILE* fp);
-} ChessReplayMap[] = {
- { "gomoku", 6, &gomoku_replay },
- { "chc", 3, &chc_replay },
- { "go", 2, &gochess_replay },
- { "reversi",7, &reversi_replay },
- { NULL }
-};
-
-static ChessInfo * CurrentPlayingGameInfo;
-static sigjmp_buf sigjmpEnv;
-
-/* XXX: This is a BAD way to pass information.
- * Fix this by handling chess request ourselves.
- */
-static ChessTimeLimit * _current_time_limit;
-
-static void SigjmpEnv(int sig) { siglongjmp(sigjmpEnv, 1); }
-
-#define CHESS_HISTORY_ENTRY(INFO,N) \
- ((INFO)->history.body + (N) * (INFO)->constants->step_entry_size)
-static void
-ChessHistoryInit(ChessHistory* history, int entry_size)
-{
- history->size = CHESS_HISTORY_INITIAL_BUFFER_SIZE;
- history->used = 0;
- history->body =
- calloc(CHESS_HISTORY_INITIAL_BUFFER_SIZE,
- entry_size);
-}
-
-const void*
-ChessHistoryRetrieve(ChessInfo* info, int n)
-{
- assert(n >= 0 && n < info->history.used);
- return CHESS_HISTORY_ENTRY(info, n);
-}
-
-void
-ChessHistoryAppend(ChessInfo* info, void* step)
-{
- if (info->history.used == info->history.size)
- info->history.body = realloc(info->history.body,
- (info->history.size += CHESS_HISTORY_BUFFER_INCREMENT)
- * info->constants->step_entry_size);
-
- memmove(CHESS_HISTORY_ENTRY(info, info->history.used),
- step, info->constants->step_entry_size);
- info->history.used++;
-}
-
-static void
-ChessBroadcastListInit(ChessBroadcastList* list)
-{
- list->head.next = NULL;
-}
-
-static void
-ChessBroadcastListClear(ChessBroadcastList* list)
-{
- ChessBroadcastListNode* p = list->head.next;
- while (p) {
- ChessBroadcastListNode* t = p->next;
- close(p->sock);
- free(p);
- p = t;
- }
-}
-
-static ChessBroadcastListNode*
-ChessBroadcastListInsert(ChessBroadcastList* list)
-{
- ChessBroadcastListNode* p =
- (ChessBroadcastListNode*) malloc(sizeof(ChessBroadcastListNode));
-
- p->next = list->head.next;
- list->head.next = p;
- return p;
-}
-
-static void
-ChessDrawHelpLine(const ChessInfo* info)
-{
- const static char* const HelpStr[] =
- {
- /* CHESS_MODE_VERSUS, ¹ï«³ */
- ANSI_COLOR(1;33;42) " ¤U´Ñ "
- ANSI_COLOR(;31;47) " (¡ö¡ô¡õ¡÷)" ANSI_COLOR(30) " ²¾°Ê "
- ANSI_COLOR(31) "(ªÅ¥ÕÁä/ENTER)" ANSI_COLOR(30) " ¤U¤l "
- ANSI_COLOR(31) "(q)" ANSI_COLOR(30) "»{¿é "
- ANSI_COLOR(31) "(p)" ANSI_COLOR(30) "µê¤â/©M´Ñ "
- ANSI_COLOR(31) "(u)" ANSI_COLOR(30) "®¬´Ñ "
- ANSI_RESET,
-
- /* CHESS_MODE_WATCH, Æ[´Ñ */
- ANSI_COLOR(1;33;42) " Æ[´Ñ "
- ANSI_COLOR(;31;47) " (¡ö¡÷)" ANSI_COLOR(30) " «e«á¤@¨B "
- ANSI_COLOR(31) "(¡ô¡õ)" ANSI_COLOR(30) " «e«á¤Q¨B "
- ANSI_COLOR(31) "(PGUP/PGDN)" ANSI_COLOR(30) " ³Ìªì/¥Ø«e½L­± "
- ANSI_COLOR(31) "(q)" ANSI_COLOR(30) "Â÷¶} "
- ANSI_RESET,
-
- /* CHESS_MODE_PERSONAL, ¥´ÃÐ */
- ANSI_COLOR(1;33;42) " ¥´ÃÐ "
- ANSI_COLOR(;31;47) " (¡ö¡ô¡õ¡÷)" ANSI_COLOR(30) " ²¾°Ê "
- ANSI_COLOR(31) "(ªÅ¥ÕÁä/ENTER)" ANSI_COLOR(30) " ¤U¤l "
- ANSI_COLOR(31) "(q)" ANSI_COLOR(30) "Â÷¶} "
- ANSI_COLOR(31) "(u)" ANSI_COLOR(30) "®¬´Ñ "
- ANSI_RESET,
-
- /* CHESS_MODE_REPLAY, ¬ÝÃÐ */
- ANSI_COLOR(1;33;42) " ¬ÝÃÐ "
- ANSI_COLOR(;31;47) " (¡ö¡÷)" ANSI_COLOR(30) " «e«á¤@¨B "
- ANSI_COLOR(31) "(¡ô¡õ)" ANSI_COLOR(30) " «e«á¤Q¨B "
- ANSI_COLOR(31) "(PGUP/PGDN)" ANSI_COLOR(30) " ³Ìªì/¥Ø«e½L­± "
- ANSI_COLOR(31) "(q)" ANSI_COLOR(30) "Â÷¶} "
- ANSI_RESET,
- };
-
- mouts(b_lines, 0, HelpStr[info->mode]);
- info->actions->drawline(info, b_lines);
-}
-
-void
-ChessDrawLine(const ChessInfo* info, int line)
-{
-#define DRAWLINE(LINE) \
- do { \
- move((LINE), 0); \
- clrtoeol(); \
- info->actions->drawline(info, (LINE)); \
- } while (0)
-
- if (line == b_lines) {
- ChessDrawHelpLine(info);
- return;
- } else if (line == CHESS_DRAWING_TURN_ROW)
- line = info->photo ?
- CHESS_DRAWING_PHOTOED_TURN_ROW :
- CHESS_DRAWING_REAL_TURN_ROW;
- else if (line == CHESS_DRAWING_TIME_ROW) {
- if(info->photo) {
- DRAWLINE(CHESS_DRAWING_PHOTOED_TIME_ROW1);
- DRAWLINE(CHESS_DRAWING_PHOTOED_TIME_ROW2);
- } else {
- DRAWLINE(CHESS_DRAWING_REAL_TIME_ROW1);
- DRAWLINE(CHESS_DRAWING_REAL_TIME_ROW2);
- }
- return;
- } else if (line == CHESS_DRAWING_WARN_ROW)
- line = info->photo ?
- CHESS_DRAWING_PHOTOED_WARN_ROW :
- CHESS_DRAWING_REAL_WARN_ROW;
- else if (line == CHESS_DRAWING_STEP_ROW)
- line = info->photo ?
- CHESS_DRAWING_PHOTOED_STEP_ROW :
- CHESS_DRAWING_REAL_STEP_ROW;
-
- DRAWLINE(line);
-
-#undef DRAWLINE
-}
-
-void
-ChessRedraw(const ChessInfo* info)
-{
- int i;
- clear();
- for (i = 0; i <= b_lines; ++i)
- ChessDrawLine(info, i);
-}
-
-inline static int
-ChessTimeCountDownCalc(ChessInfo* info, int who, int length)
-{
- info->lefttime[who] -= length;
-
- if (!info->timelimit) /* traditional mode, only left time is considered */
- return info->lefttime[who] < 0;
-
- if (info->lefttime[who] < 0) { /* only allowed when in free time */
- if (info->lefthand[who])
- return 1;
- info->lefttime[who] += info->timelimit->limit_time;
- info->lefthand[who] = info->timelimit->limit_hand;
-
- return (info->lefttime[who] < 0);
- }
-
- return 0;
-}
-
-int
-ChessTimeCountDown(ChessInfo* info, int who, int length)
-{
- int result = ChessTimeCountDownCalc(info, who, length);
- ChessDrawLine(info, CHESS_DRAWING_TIME_ROW);
- return result;
-}
-
-void
-ChessStepMade(ChessInfo* info, int who)
-{
- if (!info->timelimit)
- info->lefttime[who] = info->constants->traditional_timeout;
- else if (
- (info->lefthand[who] && (--(info->lefthand[who]) == 0) &&
- info->timelimit->time_mode == CHESS_TIMEMODE_COUNTING)
- ||
- (info->lefthand[who] == 0 && info->lefttime[who] <= 0)
- ) {
- info->lefthand[who] = info->timelimit->limit_hand;
- info->lefttime[who] = info->timelimit->limit_time;
- }
-}
-
-/*
- * Start of the network communication function.
- */
-inline static ChessStepType
-ChessRecvMove(ChessInfo* info, int sock, void *step)
-{
- if (read(sock, step, info->constants->step_entry_size)
- != info->constants->step_entry_size)
- return CHESS_STEP_FAILURE;
- return *(ChessStepType*) step;
-}
-
-inline static int
-ChessSendMove(ChessInfo* info, int sock, const void *step)
-{
- if (write(sock, step, info->constants->step_entry_size)
- != info->constants->step_entry_size)
- return 0;
- return 1;
-}
-
-inline static int
-ChessStepSendOpposite(ChessInfo* info, const void* step)
-{
- void (*orig_handler)(int);
- int result = 1;
-
- /* fd 0 is the socket to user, it means no oppisite available.
- * (Might be personal play) */
- if (info->sock == 0)
- return 1;
-
- orig_handler = Signal(SIGPIPE, SIG_IGN);
-
- if (!ChessSendMove(info, info->sock, step))
- result = 0;
-
- Signal(SIGPIPE, orig_handler);
- return result;
-}
-
-inline static void
-ChessStepBroadcast(ChessInfo* info, const void *step)
-{
- ChessBroadcastListNode *p = &(info->broadcast_list.head);
- void (*orig_handler)(int);
-
- orig_handler = Signal(SIGPIPE, SIG_IGN);
-
- while(p->next){
- if (!ChessSendMove(info, p->next->sock, step)) {
- /* remove viewer */
- ChessBroadcastListNode *tmp = p->next->next;
- free(p->next);
- p->next = tmp;
- } else
- p = p->next;
- }
-
- Signal(SIGPIPE, orig_handler);
-}
-
-int
-ChessStepSend(ChessInfo* info, const void* step)
-{
- /* send to opposite... */
- if (!ChessStepSendOpposite(info, step))
- return 0;
-
- /* and watchers */
- ChessStepBroadcast(info, step);
-
- return 1;
-}
-
-int
-ChessMessageSend(ChessInfo* info, ChessStepType type)
-{
- return ChessStepSend(info, &type);
-}
-
-static inline int
-ChessCheckAlive(ChessInfo* info)
-{
- ChessStepType type = CHESS_STEP_NOP;
- return ChessStepSendOpposite(info, &type);
-}
-
-ChessStepType
-ChessStepReceive(ChessInfo* info, void* step)
-{
- ChessStepType result = ChessRecvMove(info, info->sock, step);
-
- /* automatical routing */
- if (result != CHESS_STEP_FAILURE)
- ChessStepBroadcast(info, step);
-
- /* and logging */
- if (result == CHESS_STEP_NORMAL || result == CHESS_STEP_PASS)
- ChessHistoryAppend(info, step);
-
- return result;
-}
-
-inline static void
-ChessReplayUntil(ChessInfo* info, int n)
-{
- const void* step;
-
- if (n <= info->current_step)
- return;
-
- while (info->current_step < n - 1) {
- info->actions->apply_step(info->board,
- ChessHistoryRetrieve(info, info->current_step));
- info->current_step++;
- }
-
- /* spcial for last one to maintian information correct */
- step = ChessHistoryRetrieve(info, info->current_step);
-
- if (info->mode == CHESS_MODE_WATCH || info->mode == CHESS_MODE_REPLAY)
- info->turn = info->current_step & 1;
- info->actions->prepare_step(info, step);
- info->actions->apply_step(info->board, step);
- info->current_step++;
-}
-
-static int
-ChessAnswerRequest(ChessInfo* info, const char* req_name)
-{
- char buf[4];
- char msg[64];
-
- snprintf(info->warnmsg, sizeof(info->warnmsg),
- ANSI_COLOR(1;31) "­n¨D%s!" ANSI_RESET, req_name);
- ChessDrawLine(info, CHESS_DRAWING_WARN_ROW);
- bell();
-
- snprintf(msg, sizeof(msg),
- "¹ï¤è­n¨D%s¡A¬O§_±µ¨ü?(y/N)", req_name);
- DO_WITHOUT_PEER(30,
- getdata(b_lines, 0, msg, buf, sizeof(buf), DOECHO),
- buf[0] = 'n');
- ChessDrawHelpLine(info);
-
- info->warnmsg[0] = 0;
- ChessDrawLine(info, CHESS_DRAWING_WARN_ROW);
-
- if (buf[0] == 'y' || buf[0] == 'Y')
- return 1;
- else
- return 0;
-}
-
-ChessGameResult
-ChessPlayFuncMy(ChessInfo* info)
-{
- int last_time = now;
- int endturn = 0;
- ChessGameResult game_result = CHESS_RESULT_CONTINUE;
- int ch;
-#ifdef DBCSAWARE
- int move_count = 0;
-#endif
-
- info->pass[(int) info->turn] = 0;
- bell();
-
- while (!endturn) {
- ChessStepType result;
-
- ChessDrawLine(info, CHESS_DRAWING_TIME_ROW);
- info->actions->movecur(info->cursor.r, info->cursor.c);
- oflush();
-
- ch = igetch();
- if (ChessTimeCountDown(info, 0, now - last_time)) {
- /* ran out of time */
- game_result = CHESS_RESULT_LOST;
- endturn = 1;
- break;
- }
- last_time = now;
-
- switch (ch) {
- case I_OTHERDATA:
- result = ChessStepReceive(info, &info->step_tmp);
-
- if (result == CHESS_STEP_FAILURE ||
- result == CHESS_STEP_DROP) {
- game_result = CHESS_RESULT_WIN;
- endturn = 1;
- } else if (result == CHESS_STEP_TIE_ACC) {
- game_result = CHESS_RESULT_TIE;
- endturn = 1;
- } else if (result == CHESS_STEP_TIE_REJ) {
- strcpy(info->warnmsg, ANSI_COLOR(1;31) "¨D©M³Q©Ú!" ANSI_RESET);
- ChessDrawLine(info, CHESS_DRAWING_WARN_ROW);
- } else if (result == CHESS_STEP_UNDO) {
- if (ChessAnswerRequest(info, "®¬´Ñ")) {
- ChessMessageSend(info, CHESS_STEP_UNDO_ACC);
-
- info->actions->init_board(info->board);
- info->current_step = 0;
- ChessReplayUntil(info, info->history.used - 1);
- info->history.used--;
-
- ChessRedraw(info);
-
- endturn = 1;
- } else
- ChessMessageSend(info, CHESS_STEP_UNDO_REJ);
- } else if (result == CHESS_STEP_NORMAL ||
- result == CHESS_STEP_SPECIAL) {
- info->actions->prepare_step(info, &info->step_tmp);
- game_result =
- info->actions->apply_step(info->board,
- &info->step_tmp);
- info->actions->drawstep(info, &info->step_tmp);
- endturn = 1;
- ChessStepMade(info, 0);
- }
- break;
-
- case KEY_UP:
- info->cursor.r--;
- if (info->cursor.r < 0)
- info->cursor.r = info->constants->board_height - 1;
- break;
-
- case KEY_DOWN:
- info->cursor.r++;
- if (info->cursor.r >= info->constants->board_height)
- info->cursor.r = 0;
- break;
-
- case KEY_LEFT:
-#ifdef DBCSAWARE
- if (!ISDBCSAWARE()) {
- if (++move_count >= 2)
- move_count = 0;
- else
- break;
- }
-#endif /* defined(DBCSAWARE) */
-
- info->cursor.c--;
- if (info->cursor.c < 0)
- info->cursor.c = info->constants->board_width - 1;
- break;
-
- case KEY_RIGHT:
-#ifdef DBCSAWARE
- if (!ISDBCSAWARE()) {
- if (++move_count >= 2)
- move_count = 0;
- else
- break;
- }
-#endif /* defined(DBCSAWARE) */
-
- info->cursor.c++;
- if (info->cursor.c >= info->constants->board_width)
- info->cursor.c = 0;
- break;
-
- case 'q':
- {
- char buf[4];
-
- DO_WITHOUT_PEER(30,
- getdata(b_lines, 0,
- info->mode == CHESS_MODE_PERSONAL ?
- "¬O§_¯uªº­nÂ÷¶}?(y/N)" :
- "¬O§_¯uªº­n»{¿é?(y/N)",
- buf, sizeof(buf), DOECHO),
- buf[0] = 'n');
- ChessDrawHelpLine(info);
-
- if (buf[0] == 'y' || buf[0] == 'Y') {
- game_result = CHESS_RESULT_LOST;
- endturn = 1;
- }
- }
- break;
-
- case 'p':
- if (info->constants->pass_is_step) {
- ChessStepType type = CHESS_STEP_PASS;
- ChessHistoryAppend(info, &type);
- strcpy(info->last_movestr, "µê¤â");
-
- info->pass[(int) info->turn] = 1;
- ChessMessageSend(info, CHESS_STEP_PASS);
- endturn = 1;
- } else if (info->mode != CHESS_MODE_PERSONAL) {
- char buf[4];
-
- DO_WITHOUT_PEER(30,
- getdata(b_lines, 0, "¬O§_¯uªº­n©M´Ñ?(y/N)",
- buf, sizeof(buf), DOECHO),
- buf[0] = 'n');
- ChessDrawHelpLine(info);
-
- if (buf[0] == 'y' || buf[1] == 'Y') {
- ChessMessageSend(info, CHESS_STEP_TIE);
- strlcpy(info->warnmsg,
- ANSI_COLOR(1;33) "­n¨D©M´Ñ!" ANSI_RESET,
- sizeof(info->warnmsg));
- ChessDrawLine(info, CHESS_DRAWING_WARN_ROW);
- bell();
- }
- }
- break;
-
- case 'u':
- if (info->mode == CHESS_MODE_PERSONAL && info->history.used > 0) {
- ChessMessageSend(info, CHESS_STEP_UNDO_ACC);
-
- info->actions->init_board(info->board);
- info->current_step = 0;
- ChessReplayUntil(info, info->history.used - 1);
- info->history.used--;
-
- ChessRedraw(info);
-
- endturn = 1;
- }
- break;
-
- case '\r':
- case '\n':
- case ' ':
- endturn = info->actions->select(info, info->cursor, &game_result);
- break;
-
- case I_TIMEOUT:
- break;
-
- case KEY_UNKNOWN:
- break;
-
- default:
- if (info->actions->process_key) {
- DO_WITHOUT_PEER(30,
- endturn =
- info->actions->process_key(info, ch, &game_result),
- );
- }
- }
- }
- ChessTimeCountDown(info, 0, now - last_time);
- ChessStepMade(info, 0);
- ChessDrawLine(info, CHESS_DRAWING_TIME_ROW);
- ChessDrawLine(info, CHESS_DRAWING_STEP_ROW);
- return game_result;
-}
-
-static ChessGameResult
-ChessPlayFuncHis(ChessInfo* info)
-{
- int last_time = now;
- int endturn = 0;
- ChessGameResult game_result = CHESS_RESULT_CONTINUE;
-
- while (!endturn) {
- ChessStepType result;
- int ch;
-
- if (ChessTimeCountDown(info, 1, now - last_time)) {
- info->lefttime[1] = 0;
-
- /* to make him break out igetch() */
- ChessMessageSend(info, CHESS_STEP_NOP);
- }
- last_time = now;
-
- ChessDrawLine(info, CHESS_DRAWING_TIME_ROW);
- move(1, 0);
- oflush();
-
- switch (ch = igetch()) {
- case 'q':
- {
- char buf[4];
- DO_WITHOUT_PEER(30,
- getdata(b_lines, 0, "¬O§_¯uªº­n»{¿é?(y/N)",
- buf, sizeof(buf), DOECHO),
- buf[0] = 'n');
- ChessDrawHelpLine(info);
-
- if (buf[0] == 'y' || buf[0] == 'Y') {
- game_result = CHESS_RESULT_LOST;
- endturn = 1;
- }
- }
- break;
-
- case 'u':
- if (info->history.used > 0) {
- strcpy(info->warnmsg, ANSI_COLOR(1;31) "­n¨D®¬´Ñ!" ANSI_RESET);
- ChessDrawLine(info, CHESS_DRAWING_WARN_ROW);
-
- ChessMessageSend(info, CHESS_STEP_UNDO);
- }
- break;
-
- case I_OTHERDATA:
- result = ChessStepReceive(info, &info->step_tmp);
-
- if (result == CHESS_STEP_FAILURE ||
- result == CHESS_STEP_DROP) {
- game_result = CHESS_RESULT_WIN;
- endturn = 1;
- } else if (result == CHESS_STEP_PASS) {
- strcpy(info->last_movestr, "µê¤â");
-
- info->pass[(int) info->turn] = 1;
- endturn = 1;
- } else if (result == CHESS_STEP_TIE) {
- if (ChessAnswerRequest(info, "©M´Ñ")) {
- ChessMessageSend(info, CHESS_STEP_TIE_ACC);
-
- game_result = CHESS_RESULT_TIE;
- endturn = 1;
- } else
- ChessMessageSend(info, CHESS_STEP_TIE_REJ);
- } else if (result == CHESS_STEP_NORMAL ||
- result == CHESS_STEP_SPECIAL) {
- info->actions->prepare_step(info, &info->step_tmp);
- switch (info->actions->apply_step(info->board, &info->step_tmp)) {
- case CHESS_RESULT_LOST:
- game_result = CHESS_RESULT_WIN;
- break;
-
- case CHESS_RESULT_WIN:
- game_result = CHESS_RESULT_LOST;
- break;
-
- default:
- game_result = CHESS_RESULT_CONTINUE;
- }
- endturn = 1;
- info->pass[(int) info->turn] = 0;
- ChessStepMade(info, 1);
- info->actions->drawstep(info, &info->step_tmp);
- } else if (result == CHESS_STEP_UNDO_ACC) {
- strcpy(info->warnmsg, ANSI_COLOR(1;31) "±µ¨ü®¬´Ñ!" ANSI_RESET);
-
- info->actions->init_board(info->board);
- info->current_step = 0;
- ChessReplayUntil(info, info->history.used - 1);
- info->history.used--;
-
- ChessRedraw(info);
- bell();
-
- endturn = 1;
- } else if (result == CHESS_STEP_UNDO_REJ) {
- strcpy(info->warnmsg, ANSI_COLOR(1;31) "®¬´Ñ³Q©Ú!" ANSI_RESET);
- ChessDrawLine(info, CHESS_DRAWING_WARN_ROW);
- }
-
- case I_TIMEOUT:
- break;
-
- case KEY_UNKNOWN:
- break;
-
- default:
- if (info->actions->process_key) {
- DO_WITHOUT_PEER(30,
- endturn =
- info->actions->process_key(info, ch, &game_result),
- );
- }
- }
- }
- ChessTimeCountDown(info, 1, now - last_time);
- ChessDrawLine(info, CHESS_DRAWING_TIME_ROW);
- ChessDrawLine(info, CHESS_DRAWING_STEP_ROW);
- return game_result;
-}
-
-static ChessGameResult
-ChessPlayFuncWatch(ChessInfo* info)
-{
- int end_watch = 0;
-
- while (!end_watch) {
- ChessStepType result;
-
- info->actions->prepare_play(info);
- if (info->sock == -1)
- strlcpy(info->warnmsg, ANSI_COLOR(1;33) "´Ñ§½¤wµ²§ô" ANSI_RESET,
- sizeof(info->warnmsg));
-
- ChessDrawLine(info, CHESS_DRAWING_WARN_ROW);
- ChessDrawLine(info, CHESS_DRAWING_STEP_ROW);
- move(1, 0);
-
- switch (igetch()) {
- case I_OTHERDATA: /* new step */
- result = ChessStepReceive(info, &info->step_tmp);
-
- if (result == CHESS_STEP_FAILURE) {
- IGNORE_PEER();
- info->sock = -1;
- break;
- } else if (result == CHESS_STEP_UNDO_ACC) {
- if (info->current_step == info->history.used) {
- /* at head but redo-ed */
- info->actions->init_board(info->board);
- info->current_step = 0;
- ChessReplayUntil(info, info->history.used - 1);
- ChessRedraw(info);
- }
- info->history.used--;
- } else if (result == CHESS_STEP_NORMAL ||
- result == CHESS_STEP_SPECIAL) {
- if (info->current_step == info->history.used - 1) {
- /* was watching up-to-date board */
- info->turn = info->current_step++ & 1;
- info->actions->prepare_step(info, &info->step_tmp);
- info->actions->apply_step(info->board, &info->step_tmp);
- info->actions->drawstep(info, &info->step_tmp);
- }
- } else if (result == CHESS_STEP_PASS)
- strcpy(info->last_movestr, "µê¤â");
-
- break;
-
- case KEY_LEFT: /* ©¹«e¤@¨B */
- if (info->current_step == 0)
- bell();
- else {
- /* TODO: implement without re-apply all steps */
- int current = info->current_step;
-
- info->actions->init_board(info->board);
- info->current_step = 0;
-
- ChessReplayUntil(info, current - 1);
- ChessRedraw(info);
- }
- break;
-
- case KEY_RIGHT: /* ©¹«á¤@¨B */
- if (info->current_step == info->history.used)
- bell();
- else {
- const void* step =
- ChessHistoryRetrieve(info, info->current_step);
- info->turn = info->current_step++ & 1;
- info->actions->prepare_step(info, step);
- info->actions->apply_step(info->board, step);
- info->actions->drawstep(info, step);
- }
- break;
-
- case KEY_UP: /* ©¹«e¤Q¨B */
- if (info->current_step == 0)
- bell();
- else {
- /* TODO: implement without re-apply all steps */
- int current = info->current_step;
-
- info->actions->init_board(info->board);
- info->current_step = 0;
-
- ChessReplayUntil(info, current - 10);
-
- ChessRedraw(info);
- }
- break;
-
- case KEY_DOWN: /* ©¹«á¤Q¨B */
- if (info->current_step == info->history.used)
- bell();
- else {
- ChessReplayUntil(info,
- MIN(info->current_step + 10, info->history.used));
- ChessRedraw(info);
- }
- break;
-
- case KEY_PGUP: /* °_©l½L­± */
- if (info->current_step == 0)
- bell();
- else {
- info->actions->init_board(info->board);
- info->current_step = 0;
- ChessRedraw(info);
- }
- break;
-
- case KEY_PGDN: /* ³Ì·s½L­± */
- if (info->current_step == info->history.used)
- bell();
- else {
- ChessReplayUntil(info, info->history.used);
- ChessRedraw(info);
- }
- break;
-
- case 'q':
- end_watch = 1;
- }
- }
-
- return CHESS_RESULT_END;
-}
-
-static void
-ChessWatchRequest(int sig)
-{
- int sock = establish_talk_connection(&SHM->uinfo[currutmp->destuip]);
- ChessBroadcastListNode* node;
-
- if (sock < 0 || !CurrentPlayingGameInfo)
- return;
-
- node = ChessBroadcastListInsert(&CurrentPlayingGameInfo->broadcast_list);
- node->sock = sock;
-
-#define SEND(X) write(sock, &(X), sizeof(X))
- SEND(CurrentPlayingGameInfo->myturn);
- SEND(CurrentPlayingGameInfo->turn);
-
- if (!CurrentPlayingGameInfo->timelimit)
- write(sock, "T", 1);
- else {
- write(sock, "L", 1);
- SEND(*(CurrentPlayingGameInfo->timelimit));
- }
-
- SEND(CurrentPlayingGameInfo->history.used);
- write(sock, CurrentPlayingGameInfo->history.body,
- CurrentPlayingGameInfo->constants->step_entry_size
- * CurrentPlayingGameInfo->history.used);
-#undef SEND
-}
-
-static void
-ChessReceiveWatchInfo(ChessInfo* info)
-{
- char time_mode;
-#define RECV(X) read(info->sock, &(X), sizeof(X))
- RECV(info->myturn);
- RECV(info->turn);
-
- RECV(time_mode);
- if (time_mode == 'L') {
- info->timelimit = (ChessTimeLimit*) malloc(sizeof(ChessTimeLimit));
- RECV(*(info->timelimit));
- }
-
- RECV(info->history.used);
- for (info->history.size = CHESS_HISTORY_INITIAL_BUFFER_SIZE;
- info->history.size < info->history.used;
- info->history.size += CHESS_HISTORY_BUFFER_INCREMENT);
- info->history.body =
- calloc(info->history.size, info->constants->step_entry_size);
- read(info->sock, info->history.body,
- info->history.used * info->constants->step_entry_size);
-#undef RECV
-}
-
-static void
-ChessGenLogGlobal(ChessInfo* info, ChessGameResult result)
-{
- fileheader_t log_header;
- FILE *fp;
- char fname[PATHLEN];
- int bid;
-
- if ((bid = getbnum(info->constants->log_board)) == 0)
- return;
-
- setbpath(fname, info->constants->log_board);
- stampfile(fname, &log_header);
-
- fp = fopen(fname, "w");
- if (fp != NULL) {
- strlcpy(log_header.owner, "[´ÑÃо÷¾¹¤H]", sizeof(log_header.owner));
- snprintf(log_header.title, sizeof(log_header.title), "[´ÑÃÐ] %s VS %s",
- info->user1.userid, info->user2.userid);
-
- fprintf(fp, "§@ªÌ: %s ¬ÝªO: %s\n¼ÐÃD: %s \n", log_header.owner, info->constants->log_board, log_header.title);
- fprintf(fp, "®É¶¡: %s\n", ctime4(&now));
-
- info->actions->genlog(info, fp, result);
- fclose(fp);
-
- setbdir(fname, info->constants->log_board);
- append_record(fname, &log_header, sizeof(log_header));
-
- setbtotal(bid);
- }
-}
-
-static void
-ChessGenLogUser(ChessInfo* info, ChessGameResult result)
-{
- fileheader_t log_header;
- FILE *fp;
- char fname[PATHLEN];
-
- sethomepath(fname, cuser.userid);
- stampfile(fname, &log_header);
-
- fp = fopen(fname, "w");
- if (fp != NULL) {
- info->actions->genlog(info, fp, result);
- fclose(fp);
-
- snprintf(log_header.owner, sizeof(log_header.owner), "[%s]",
- info->constants->chess_name);
- if(info->myturn == 0)
- sprintf(log_header.title, "%s V.S. %s",
- info->user1.userid, info->user2.userid);
- else
- sprintf(log_header.title, "%s V.S. %s",
- info->user2.userid, info->user1.userid);
- log_header.filemode = 0;
-
- sethomedir(fname, cuser.userid);
- append_record_forward(fname, &log_header, sizeof(log_header),
- cuser.userid);
- }
-}
-
-static void
-ChessGenLog(ChessInfo* info, ChessGameResult result)
-{
- char a = 0;
- if (info->mode == CHESS_MODE_VERSUS && info->myturn == 0 &&
- info->constants->log_board) {
- ChessGenLogGlobal(info, result);
- }
-
- a = getans((cuser.uflag & DEFBACKUP_FLAG) ?
- "¬O§_±N´ÑÃбH¦^«H½c¡H [Y/n]" :
- "¬O§_±N´ÑÃбH¦^«H½c¡H [y/N]");
-
- if (TOBACKUP(a))
- ChessGenLogUser(info, result);
-}
-
-void
-ChessPlay(ChessInfo* info)
-{
- ChessGameResult game_result;
- void (*old_handler)(int);
- const char* game_result_str = 0;
- sigset_t old_sigset;
-
- if (info == NULL)
- return;
-
- if (!ChessCheckAlive(info)) {
- if (info->sock)
- close(info->sock);
- return;
- }
-
- /* XXX */
- if (!info->timelimit) {
- info->timelimit = _current_time_limit;
- _current_time_limit = NULL;
- }
-
- CurrentPlayingGameInfo = info;
-
- {
- char buf[4] = "";
- sigset_t sigset;
-
- if(info->mode == CHESS_MODE_VERSUS)
- getdata(b_lines, 0, "¬O§_±µ¨üÆ[´Ñ? (Y/n)", buf, sizeof(buf), DOECHO);
- if(buf[0] == 'n' || buf[0] == 'N')
- old_handler = Signal(SIGUSR1, SIG_IGN);
- else
- old_handler = Signal(SIGUSR1, &ChessWatchRequest);
-
- sigemptyset(&sigset);
- sigaddset(&sigset, SIGUSR1);
- sigprocmask(SIG_UNBLOCK, &sigset, &old_sigset);
- }
-
- if (info->mode == CHESS_MODE_WATCH) {
- int i;
- for (i = 0; i < info->history.used; ++i)
- info->actions->apply_step(info->board,
- ChessHistoryRetrieve(info, i));
- info->current_step = info->history.used;
- }
-
- /* playing initialization */
- ChessRedraw(info);
- info->turn = 1;
- info->lefttime[0] = info->lefttime[1] = info->timelimit ?
- info->timelimit->free_time : info->constants->traditional_timeout;
- info->lefthand[0] = info->lefthand[1] = 0;
-
- /* main loop */
- CONNECT_PEER();
- for (game_result = CHESS_RESULT_CONTINUE;
- game_result == CHESS_RESULT_CONTINUE;
- info->turn ^= 1) {
- if (info->actions->prepare_play(info))
- info->pass[(int) info->turn] = 1;
- else {
- ChessDrawLine(info, CHESS_DRAWING_TURN_ROW);
- ChessDrawLine(info, CHESS_DRAWING_WARN_ROW);
- game_result = info->play_func[(int) info->turn](info);
- }
-
- if (info->pass[0] && info->pass[1])
- game_result = CHESS_RESULT_END;
- }
-
- if (game_result == CHESS_RESULT_END &&
- info->actions->post_game &&
- (info->mode == CHESS_MODE_VERSUS ||
- info->mode == CHESS_MODE_PERSONAL))
- game_result = info->actions->post_game(info);
-
- IGNORE_PEER();
-
- if (info->sock)
- close(info->sock);
-
- /* end processing */
- if (info->mode == CHESS_MODE_VERSUS) {
- switch (game_result) {
- case CHESS_RESULT_WIN:
- game_result_str = "¹ï¤è»{¿é¤F!";
- break;
-
- case CHESS_RESULT_LOST:
- game_result_str = "§A»{¿é¤F!";
- break;
-
- case CHESS_RESULT_TIE:
- game_result_str = "©M´Ñ";
- break;
-
- default:
- assert_not_reached();
- }
- } else if (info->mode == CHESS_MODE_WATCH)
- game_result_str = "µ²§ôÆ[´Ñ";
- else if (info->mode == CHESS_MODE_PERSONAL)
- game_result_str = "µ²§ô¥´ÃÐ";
- else if (info->mode == CHESS_MODE_REPLAY)
- game_result_str = "µ²§ô¬ÝÃÐ";
-
- if (game_result_str) {
- strlcpy(info->warnmsg, game_result_str, sizeof(info->warnmsg));
- ChessDrawLine(info, CHESS_DRAWING_WARN_ROW);
- }
-
- info->actions->gameend(info, game_result);
-
- if (info->mode != CHESS_MODE_REPLAY)
- ChessGenLog(info, game_result);
-
- // currutmp->sig = -1;
- sigprocmask(SIG_SETMASK, &old_sigset, NULL);
- Signal(SIGUSR1, old_handler);
-
- CurrentPlayingGameInfo = NULL;
-}
-
-static userinfo_t*
-ChessSearchUser(int sig, const char* title)
-{
- char uident[16];
- userinfo_t *uin;
-
- stand_title(title);
- CompleteOnlineUser(msg_uid, uident);
- if (uident[0] == '\0')
- return NULL;
-
- if ((uin = search_ulist_userid(uident)) == NULL)
- return NULL;
-
- if (sig >= 0)
- uin->sig = sig;
- return uin;
-}
-
-int
-ChessStartGame(char func_char, int sig, const char* title)
-{
- userinfo_t *uin;
- char buf[4];
-
- if ((uin = ChessSearchUser(sig, title)) == NULL)
- return -1;
- uin->turn = 1;
- currutmp->turn = 0;
- strlcpy(uin->mateid, currutmp->userid, sizeof(uin->mateid));
- strlcpy(currutmp->mateid, uin->userid, sizeof(currutmp->mateid));
-
- stand_title(title);
- buf[0] = 0;
- getdata(2, 0, "¨Ï¥Î¶Ç²Î¼Ò¦¡ (T), ­­®É­­¨B¼Ò¦¡ (L) ©Î¬O Ū¬í¼Ò¦¡ (C)? (T/l/c)",
- buf, 3, DOECHO);
-
- if (buf[0] == 'l' || buf[0] == 'L' ||
- buf[0] == 'c' || buf[0] == 'C') {
-
- _current_time_limit = (ChessTimeLimit*) malloc(sizeof(ChessTimeLimit));
- if (buf[0] == 'l' || buf[0] == 'L')
- _current_time_limit->time_mode = CHESS_TIMEMODE_MULTIHAND;
- else
- _current_time_limit->time_mode = CHESS_TIMEMODE_COUNTING;
-
- do {
- getdata_str(3, 0, "½Ð³]©w§½®É (¦Û¥Ñ®É¶¡) ¥H¤ÀÄÁ¬°³æ¦ì:",
- buf, 3, DOECHO, "30");
- _current_time_limit->free_time = atoi(buf);
- } while (_current_time_limit->free_time < 0 || _current_time_limit->free_time > 90);
- _current_time_limit->free_time *= 60; /* minute -> second */
-
- if (_current_time_limit->time_mode == CHESS_TIMEMODE_MULTIHAND) {
- char display_buf[128];
-
- do {
- getdata_str(4, 0, "½Ð³]©w¨B®É, ¥H¤ÀÄÁ¬°³æ¦ì:",
- buf, 3, DOECHO, "5");
- _current_time_limit->limit_time = atoi(buf);
- } while (_current_time_limit->limit_time < 0 || _current_time_limit->limit_time > 30);
- _current_time_limit->limit_time *= 60; /* minute -> second */
-
- snprintf(display_buf, sizeof(display_buf),
- "½Ð³]©w­­¨B (¨C %d ¤ÀÄÁ»Ý¨«´X¨B):",
- _current_time_limit->limit_time / 60);
- do {
- getdata_str(5, 0, display_buf, buf, 3, DOECHO, "10");
- _current_time_limit->limit_hand = atoi(buf);
- } while (_current_time_limit->limit_hand < 1);
- } else {
- _current_time_limit->limit_hand = 1;
-
- do {
- getdata_str(4, 0, "½Ð³]©wŪ¬í, ¥H¬í¬°³æ¦ì",
- buf, 3, DOECHO, "60");
- _current_time_limit->limit_time = atoi(buf);
- } while (_current_time_limit->limit_time < 0);
- }
- } else
- _current_time_limit = NULL;
-
- my_talk(uin, friend_stat(currutmp, uin), func_char);
- return 0;
-}
-
-int
-ChessWatchGame(void (*play)(int, ChessGameMode), int game, const char* title)
-{
- int sock, msgsock;
- userinfo_t *uin;
-
- if ((uin = ChessSearchUser(-1, title)) == NULL)
- return -1;
-
- if (uin->uid == currutmp->uid || uin->mode != game) {
- vmsg("µLªk«Ø¥ß³s½u");
- return -1;
- }
-
- if (getans("¬O§_¶i¦æÆ[´Ñ? [N/y]") != 'y')
- return 0;
-
- if ((sock = make_connection_to_somebody(uin, 10)) < 0) {
- vmsg("µLªk«Ø¥ß³s½u");
- return -1;
- }
-#if defined(Solaris) && __OS_MAJOR_VERSION__ == 5 && __OS_MINOR_VERSION__ < 7
- msgsock = accept(sock, (struct sockaddr *) 0, 0);
-#else
- msgsock = accept(sock, (struct sockaddr *) 0, (socklen_t *) 0);
-#endif
- close(sock);
- if (msgsock < 0)
- return -1;
-
- strlcpy(currutmp->mateid, uin->userid, sizeof(currutmp->mateid));
- play(msgsock, CHESS_MODE_WATCH);
- close(msgsock);
- return 0;
-}
-
-int
-ChessReplayGame(const char* fname)
-{
- ChessInfo *info;
- FILE *fp = fopen(fname, "r");
- int found = -1;
- char buf[256];
- screen_backup_t oldscreen;
-
- if(fp == NULL) {
- vmsg("ÀÉ®×µLªk¶}±Ò, ¥i¯à³Q§R°£¤F");
- return -1;
- }
-
- while (found == -1 && fgets(buf, sizeof(buf), fp)) {
- if (buf[0] == '<') {
- const int line_len = strlen(buf);
- if (strcmp(buf + line_len - 5, "log>\n") == 0) {
- int i;
- for (i = 0; ChessReplayMap[i].name; ++i)
- if (ChessReplayMap[i].name_len == line_len - 6 &&
- strncmp(buf + 1, ChessReplayMap[i].name,
- ChessReplayMap[i].name_len) == 0) {
- found = i;
- break;
- }
- }
- }
- }
-
- if (found == -1) {
- fclose(fp);
- return -1;
- }
-
- info = ChessReplayMap[found].func(fp);
- fclose(fp);
-
- if (info) {
- scr_dump(&oldscreen);
- ChessPlay(info);
- scr_restore(&oldscreen);
-
- DeleteChessInfo(info);
- }
-
- return 0;
-}
-
-static void
-ChessInitUser(ChessInfo* info)
-{
- char userid[2][IDLEN + 1];
- const userinfo_t* uinfo;
- userec_t urec;
-
- switch (info->mode) {
- case CHESS_MODE_PERSONAL:
- strlcpy(userid[0], cuser.userid, sizeof(userid[0]));
- strlcpy(userid[1], cuser.userid, sizeof(userid[1]));
- break;
-
- case CHESS_MODE_WATCH:
- uinfo = search_ulist_userid(currutmp->mateid);
- if (uinfo) {
- strlcpy(userid[0], uinfo->userid, sizeof(userid[0]));
- strlcpy(userid[1], uinfo->mateid, sizeof(userid[1]));
- } else {
- strlcpy(userid[0], currutmp->mateid, sizeof(userid[0]));
- userid[1][0] = 0;
- }
- break;
-
- case CHESS_MODE_VERSUS:
- strlcpy(userid[0], cuser.userid, sizeof(userid[0]));
- strlcpy(userid[1], currutmp->mateid, sizeof(userid[1]));
- break;
-
- case CHESS_MODE_REPLAY:
- return;
- }
-
- uinfo = search_ulist_userid(userid[0]);
- if (uinfo)
- info->actions->init_user(uinfo, &info->user1);
- else if (getuser(userid[0], &urec))
- info->actions->init_user_rec(&urec, &info->user1);
-
- uinfo = search_ulist_userid(userid[1]);
- if (uinfo)
- info->actions->init_user(uinfo, &info->user2);
- else if (getuser(userid[1], &urec))
- info->actions->init_user_rec(&urec, &info->user2);
-}
-
-#ifdef CHESSCOUNTRY
-static char*
-ChessPhotoInitial(ChessInfo* info)
-{
- char genbuf[256];
- int line;
- FILE* fp;
- static const char * const blank_photo[6] = {
- "¢z¢w¢w¢w¢w¢w¢w¢{",
- "¢x ªÅ ¢x",
- "¢x ¥Õ ¢x",
- "¢x ·Ó ¢x",
- "¢x ¤ù¢x",
- "¢|¢w¢w¢w¢w¢w¢w¢}"
- };
- char country[5], level[11];
- userec_t xuser;
- char* photo;
- int hasphoto = 0;
-
- if (info->mode == CHESS_MODE_REPLAY)
- return NULL;
-
- if(is_validuserid(info->user1.userid)) {
- sethomefile(genbuf, info->user1.userid, info->constants->photo_file_name);
- if (dashf(genbuf))
- hasphoto++;
- }
- if(is_validuserid(info->user2.userid)) {
- sethomefile(genbuf, info->user2.userid, info->constants->photo_file_name);
- if (dashf(genbuf))
- hasphoto++;
- }
- if(hasphoto==0)
- return NULL;
-
- photo = (char*) calloc(
- CHESS_PHOTO_LINE * CHESS_PHOTO_COLUMN, sizeof(char));
-
- /* simulate photo as two dimensional array */
-#define PHOTO(X) (photo + (X) * CHESS_PHOTO_COLUMN)
-
- fp = NULL;
- if(getuser(info->user2.userid, &xuser)) {
- sethomefile(genbuf, info->user2.userid, info->constants->photo_file_name);
- fp = fopen(genbuf, "r");
- }
-
- if (fp == NULL) {
- strcpy(country, "µL");
- level[0] = 0;
- } else {
- int i, j;
- for (line = 1; line < 8; ++line)
- fgets(genbuf, sizeof(genbuf), fp);
-
- fgets(genbuf, sizeof(genbuf), fp);
- chomp(genbuf);
- strip_ansi(genbuf + 11, genbuf + 11,
- STRIP_ALL); /* country name may have color */
- for (i = 11, j = 0; genbuf[i] && j < 4; ++i)
- if (genbuf[i] != ' ') /* and spaces */
- country[j++] = genbuf[i];
- country[j] = 0; /* two chinese words */
-
- fgets(genbuf, sizeof(genbuf), fp);
- chomp(genbuf);
- strlcpy(level, genbuf + 11, 11); /* five chinese words*/
- rewind(fp);
- }
-
- for (line = 0; line < 6; ++line) {
- if (fp != NULL) {
- if (fgets(genbuf, sizeof(genbuf), fp)) {
- chomp(genbuf);
- sprintf(PHOTO(line), "%s", genbuf);
- } else
- strcpy(PHOTO(line), " ");
- } else
- strcpy(PHOTO(line), blank_photo[line]);
-
- switch (line) {
- case 0: sprintf(genbuf, " <¥N¸¹> %s", xuser.userid); break;
- case 1: sprintf(genbuf, " <¼ÊºÙ> %.16s", xuser.nickname); break;
- case 2: sprintf(genbuf, " <¤W¯¸> %d", xuser.numlogins); break;
- case 3: sprintf(genbuf, " <¤å³¹> %d", xuser.numposts); break;
- case 4: sprintf(genbuf, " <¾¦ì> %-4s %s", country, level); break;
- case 5: sprintf(genbuf, " <¨Ó·½> %.16s", xuser.lasthost); break;
- default: genbuf[0] = 0;
- }
- strcat(PHOTO(line), genbuf);
- }
- if (fp != NULL)
- fclose(fp);
-
- sprintf(PHOTO(6), " %s%2.2s´Ñ" ANSI_RESET,
- info->constants->turn_color[(int) info->myturn ^ 1],
- info->constants->turn_str[(int) info->myturn ^ 1]);
- strcpy(PHOTO(7), " ¢ä.¢á ");
- sprintf(PHOTO(8), " %s%2.2s´Ñ" ANSI_RESET,
- info->constants->turn_color[(int) info->myturn],
- info->constants->turn_str[(int) info->myturn]);
-
- fp = NULL;
- if(getuser(info->user1.userid, &xuser)) {;
- sethomefile(genbuf, info->user1.userid, info->constants->photo_file_name);
- fp = fopen(genbuf, "r");
- }
-
- if (fp == NULL) {
- strcpy(country, "µL");
- level[0] = 0;
- } else {
- int i, j;
- for (line = 1; line < 8; ++line)
- fgets(genbuf, sizeof(genbuf), fp);
-
- fgets(genbuf, sizeof(genbuf), fp);
- chomp(genbuf);
- strip_ansi(genbuf + 11, genbuf + 11,
- STRIP_ALL); /* country name may have color */
- for (i = 11, j = 0; genbuf[i] && j < 4; ++i)
- if (genbuf[i] != ' ') /* and spaces */
- country[j++] = genbuf[i];
- country[j] = 0; /* two chinese words */
-
- fgets(genbuf, sizeof(genbuf), fp);
- chomp(genbuf);
- strlcpy(level, genbuf + 11, 11); /* five chinese words*/
- rewind(fp);
- }
-
- for (line = 9; line < 15; ++line) {
- move(line, 37);
- switch (line - 9) {
- case 0: sprintf(PHOTO(line), "<¥N¸¹> %-16.16s ", xuser.userid); break;
- case 1: sprintf(PHOTO(line), "<¼ÊºÙ> %-16.16s ", xuser.nickname); break;
- case 2: sprintf(PHOTO(line), "<¤W¯¸> %-16d ", xuser.numlogins); break;
- case 3: sprintf(PHOTO(line), "<¤å³¹> %-16d ", xuser.numposts); break;
- case 4: sprintf(PHOTO(line), "<¾¦ì> %-4s %-10s ", country, level); break;
- case 5: sprintf(PHOTO(line), "<¨Ó·½> %-16.16s ", xuser.lasthost); break;
- }
-
- if (fp != NULL) {
- if (fgets(genbuf, 200, fp)) {
- chomp(genbuf);
- strcat(PHOTO(line), genbuf);
- } else
- strcat(PHOTO(line), " ");
- } else
- strcat(PHOTO(line), blank_photo[line - 9]);
- }
- if (fp != NULL)
- fclose(fp);
-#undef PHOTO
-
- return photo;
-}
-#endif /* defined(CHESSCOUNTRY) */
-
-static void
-ChessInitPlayFunc(ChessInfo* info)
-{
- switch (info->mode) {
- case CHESS_MODE_VERSUS:
- info->play_func[(int) info->myturn] = &ChessPlayFuncMy;
- info->play_func[info->myturn ^ 1] = &ChessPlayFuncHis;
- break;
-
- case CHESS_MODE_WATCH:
- case CHESS_MODE_REPLAY:
- info->play_func[0] = info->play_func[1] = &ChessPlayFuncWatch;
- break;
-
- case CHESS_MODE_PERSONAL:
- info->play_func[0] = info->play_func[1] = &ChessPlayFuncMy;
- break;
- }
-}
-
-ChessInfo*
-NewChessInfo(const ChessActions* actions, const ChessConstants* constants,
- int sock, ChessGameMode mode)
-{
- /* allocate memory for the structure and extra space for temporary
- * steping information storage (step_tmp[0]). */
- ChessInfo* info =
- (ChessInfo*) calloc(1, sizeof(ChessInfo) + constants->step_entry_size);
-
- if (mode == CHESS_MODE_PERSONAL)
- strcpy(currutmp->mateid, cuser.userid);
-
- /* compiler don't know it's actually const... */
- info->actions = (ChessActions*) actions;
- info->constants = (ChessConstants*) constants;
- info->mode = mode;
- info->sock = sock;
-
- if (mode == CHESS_MODE_VERSUS)
- info->myturn = currutmp->turn;
- else if (mode == CHESS_MODE_PERSONAL)
- info->myturn = 1;
- else if (mode == CHESS_MODE_REPLAY)
- info->myturn = 1;
- else if (mode == CHESS_MODE_WATCH)
- ChessReceiveWatchInfo(info);
-
- ChessInitUser(info);
-
-#ifdef CHESSCOUNTRY
- info->photo = ChessPhotoInitial(info);
-#endif
-
- if (mode != CHESS_MODE_WATCH)
- ChessHistoryInit(&info->history, constants->step_entry_size);
-
- ChessBroadcastListInit(&info->broadcast_list);
- ChessInitPlayFunc(info);
-
- return info;
-}
-
-void
-DeleteChessInfo(ChessInfo* info)
-{
-#define NULL_OR_FREE(X) if (X) free(X); else (void) 0
- NULL_OR_FREE(info->timelimit);
- NULL_OR_FREE(info->photo);
- NULL_OR_FREE(info->history.body);
-
- ChessBroadcastListClear(&info->broadcast_list);
-#undef NULL_OR_FREE
-}
-
-void
-ChessEstablishRequest(int sock)
-{
- /* XXX */
- if (!_current_time_limit)
- write(sock, "T", 1); /* traditional */
- else {
- write(sock, "L", 1); /* limited */
- write(sock, _current_time_limit, sizeof(ChessTimeLimit));
- }
-}
-
-void
-ChessAcceptingRequest(int sock)
-{
- /* XXX */
- char mode;
- read(sock, &mode, 1);
- if (mode == 'T')
- _current_time_limit = NULL;
- else {
- _current_time_limit = (ChessTimeLimit*) malloc(sizeof(ChessTimeLimit));
- read(sock, _current_time_limit, sizeof(ChessTimeLimit));
- }
-}
-
-void
-ChessShowRequest(void)
-{
- /* XXX */
- if (!_current_time_limit)
- mouts(10, 5, "¨Ï¥Î¶Ç²Î­p®É¤è¦¡, ³æ¨B­­®É¤­¤ÀÄÁ");
- else if (_current_time_limit->time_mode == CHESS_TIMEMODE_MULTIHAND) {
- mouts(10, 5, "¨Ï¥Î­­®É­­¨B³W«h:");
- move(12, 8);
- prints("§½®É (¦Û¥Ñ®É¶¡): %2d ¤À %02d ¬í",
- _current_time_limit->free_time / 60,
- _current_time_limit->free_time % 60);
- move(13, 8);
- prints("­­®É¨B®É: %2d ¤À %02d ¬í / %2d ¤â",
- _current_time_limit->limit_time / 60,
- _current_time_limit->limit_time % 60,
- _current_time_limit->limit_hand);
- } else if (_current_time_limit->time_mode == CHESS_TIMEMODE_COUNTING) {
- mouts(10, 5, "¨Ï¥ÎŪ¬í³W«h:");
- move(12, 8);
- prints("§½®É (¦Û¥Ñ®É¶¡): %2d ¤À %02d ¬í",
- _current_time_limit->free_time / 60,
- _current_time_limit->free_time % 60);
- move(13, 8);
- prints("Ū¬í®É¶¡: ¨C¤â %2d ¬í", _current_time_limit->limit_time);
- }
-}
-
-inline static const char*
-ChessTimeStr(int second)
-{
- static char buf[10];
- snprintf(buf, sizeof(buf), "%d:%02d", second / 60, second % 60);
- return buf;
-}
-
-void
-ChessDrawExtraInfo(const ChessInfo* info, int line, int space)
-{
- if (line == b_lines || line == 0)
- return;
-
- if (info->photo) {
- if (line >= 3 && line < 3 + CHESS_PHOTO_LINE) {
- if (space > 3)
- outs(" ");
- outs(info->photo + (line - 3) * CHESS_PHOTO_COLUMN);
- } else if (line >= CHESS_DRAWING_PHOTOED_STEP_ROW &&
- line <= CHESS_DRAWING_PHOTOED_WARN_ROW) {
- prints("%*s", space, "");
- if (line == CHESS_DRAWING_PHOTOED_STEP_ROW)
- outs(info->last_movestr);
- else if (line == CHESS_DRAWING_PHOTOED_TURN_ROW)
- prints(ANSI_COLOR(1;33) "%s" ANSI_RESET,
- info->myturn == info->turn ? "½ü¨ì§A¤U´Ñ¤F" : "µ¥«Ý¹ï¤è¤U´Ñ");
- else if (line == CHESS_DRAWING_PHOTOED_TIME_ROW1) {
- if (info->mode == CHESS_MODE_WATCH) {
- if (!info->timelimit)
- prints("¨C¤â­­®É¤­¤ÀÄÁ");
- else
- prints("§½®É: %5s",
- ChessTimeStr(info->timelimit->free_time));
- } else if (info->lefthand[0])
- prints("§Ú¤è³Ñ¾l®É¶¡ %s / %2d ¨B",
- ChessTimeStr(info->lefttime[0]),
- info->lefthand[0]);
- else
- prints("§Ú¤è³Ñ¾l®É¶¡ %s",
- ChessTimeStr(info->lefttime[0]));
- } else if (line == CHESS_DRAWING_PHOTOED_TIME_ROW2) {
- if (info->mode == CHESS_MODE_WATCH) {
- if (info->timelimit) {
- if (info->timelimit->time_mode ==
- CHESS_TIMEMODE_MULTIHAND)
- prints("¨B®É: %s / %2d ¨B",
- ChessTimeStr(info->timelimit->limit_time),
- info->timelimit->limit_hand);
- else
- prints("Ū¬í: %5d ¬í",
- info->timelimit->limit_time);
- }
- } else if (info->lefthand[1])
- prints("¹ï¤è³Ñ¾l®É¶¡ %s / %2d ¨B",
- ChessTimeStr(info->lefttime[1]),
- info->lefthand[1]);
- else
- prints("¹ï¤è³Ñ¾l®É¶¡ %s",
- ChessTimeStr(info->lefttime[1]));
- } else if (line == CHESS_DRAWING_PHOTOED_WARN_ROW)
- outs(info->warnmsg);
- }
- } else if (line >= 3 && line <= CHESS_DRAWING_HISWIN_ROW) {
- prints("%*s", space, "");
- if (line >= 3 && line < 3 + (int)dim(ChessHintStr)) {
- outs(ChessHintStr[line - 3]);
- } else if (line == CHESS_DRAWING_SIDE_ROW) {
- prints(ANSI_COLOR(1) "§A¬O%s%s" ANSI_RESET,
- info->constants->turn_color[(int) info->myturn],
- info->constants->turn_str[(int) info->myturn]);
- } else if (line == CHESS_DRAWING_REAL_TURN_ROW) {
- prints(ANSI_COLOR(1;33) "%s" ANSI_RESET,
- info->myturn == info->turn ?
- "½ü¨ì§A¤U´Ñ¤F" : "µ¥«Ý¹ï¤è¤U´Ñ");
- } else if (line == CHESS_DRAWING_REAL_STEP_ROW && info->last_movestr) {
- outs(info->last_movestr);
- } else if (line == CHESS_DRAWING_REAL_TIME_ROW1) {
- if (info->lefthand[0])
- prints("§Ú¤è³Ñ¾l®É¶¡ %s / %2d ¨B",
- ChessTimeStr(info->lefttime[0]),
- info->lefthand[0]);
- else
- prints("§Ú¤è³Ñ¾l®É¶¡ %s",
- ChessTimeStr(info->lefttime[0]));
- } else if (line == CHESS_DRAWING_REAL_TIME_ROW2) {
- if (info->lefthand[1])
- prints("¹ï¤è³Ñ¾l®É¶¡ %s / %2d ¨B",
- ChessTimeStr(info->lefttime[1]),
- info->lefthand[1]);
- else
- prints("¹ï¤è³Ñ¾l®É¶¡ %s",
- ChessTimeStr(info->lefttime[1]));
- } else if (line == CHESS_DRAWING_REAL_WARN_ROW) {
- outs(info->warnmsg);
- } else if (line == CHESS_DRAWING_MYWIN_ROW) {
- prints(ANSI_COLOR(1;33) "%12.12s "
- ANSI_COLOR(1;31) "%2d" ANSI_COLOR(37) "³Ó "
- ANSI_COLOR(34) "%2d" ANSI_COLOR(37) "±Ñ "
- ANSI_COLOR(36) "%2d" ANSI_COLOR(37) "©M" ANSI_RESET,
- info->user1.userid,
- info->user1.win, info->user1.lose - 1, info->user1.tie);
- } else if (line == CHESS_DRAWING_HISWIN_ROW) {
- prints(ANSI_COLOR(1;33) "%12.12s "
- ANSI_COLOR(1;31) "%2d" ANSI_COLOR(37) "³Ó "
- ANSI_COLOR(34) "%2d" ANSI_COLOR(37) "±Ñ "
- ANSI_COLOR(36) "%2d" ANSI_COLOR(37) "©M" ANSI_RESET,
- info->user2.userid,
- info->user2.win, info->user2.lose, info->user2.tie);
- }
- }
-}
diff --git a/mbbsd/chicken.c b/mbbsd/chicken.c
deleted file mode 100644
index 4de2bb85..00000000
--- a/mbbsd/chicken.c
+++ /dev/null
@@ -1,1138 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-// TODO pull chicken out of userec.
-// remove chickenpk.
-
-#define NUM_KINDS 15 /* ¦³¦h¤ÖºØ°Êª« */
-#define CHICKENLOG "etc/chicken"
-
-// enable if you want to run live upgrade
-// #define CHICKEN_LIVE_UPGRADE
-
-static const char * const cage[17] = {
- "½Ï¥Í", "¶g·³", "¥®¦~", "¤Ö¦~", "«C¬K", "«C¦~",
- "«C¦~", "¬¡¤O", "§§¦~", "§§¦~", "§§¦~", "¤¤¦~",
- "¤¤¦~", "¦Ñ¦~", "¦Ñ¦~", "¦Ñáàáà", "¥j§Æ"};
-static const char * const chicken_type[NUM_KINDS] = {
- "¤pÂû", "¬ü¤Ö¤k", "«i¤h", "»jµï",
- "®£Às", "¦ÑÆN", "¿ß", "Äúµ§¤p·s",
- "ª¯ª¯", "´cÅ]", "§ÔªÌ", "£««ó",
- "°¨­^¤E", "´N¥i¤H", "ÅÚ²ú"};
-static const char * const chicken_food[NUM_KINDS] = {
- "Âû¹}®Æ", "Àç¾i«p¤ù", "Âû±Æ«K·í", "¦º½¹½º",
- "«ÍÅé", "¤pÂû", "¿ß»æ°®", "¤pºµ»æ°®",
- "Ä_¿ý", "ÆF®ð", "¶º¹Î", "«K·í",
- "Âû»L", "¯º¸Ü¤å³¹", "¤ôªG¨F©Ô"};
-static const int egg_price[NUM_KINDS] = {
- 5, 25, 30, 40,
- 80, 50, 15, 35,
- 17, 100, 85, 200,
- 200, 100, 77};
-static const int food_price[NUM_KINDS] = {
- 4, 6, 8, 10,
- 12, 12, 5, 6,
- 5, 20, 15, 23,
- 23, 10, 19};
-static const char * const attack_type[NUM_KINDS] = {
- "°Ö", "Ã@¥´", "ºl", "«r",
- "¼²À»", "°Ö", "§ì", "½ð",
- "«r", "¿U¿N", "·tÀ»", "´Ò¥´",
- "¼CÀ»", "§N­á¥ú½u", "­»§k¤@ªT"};
-
-static const char * const damage_degree[] = {
- "°A¤l¦üªº", "ÄÌÄo¦üªº", "¤p¤Oªº", "»´·Lªº",
- "¦³ÂI¯kªº", "¨Ï¤Oªº", "¶Ë¤Hªº", "­«­«ªº",
- "¨Ï¥þ¤Oªº", "´c¬½¬½ªº", "¦MÀIªº", "ºÆ¨gªº",
- "²r¯Pªº", "¨g­·¼É«B¦üªº", "Åå¤Ñ°Ê¦aªº",
- "­P©Rªº", NULL};
-
-enum {
- OO, FOOD, WEIGHT, CLEAN, RUN, ATTACK, BOOK, HAPPY, SATIS,
- TEMPERAMENT, TIREDSTRONG, SICK, HP_MAX, MM_MAX
-};
-
-static const short time_change[NUM_KINDS][14] =
-/* ¸É«~ ­¹ª« Åé­« °®²b ±Ó±¶ §ðÀ»¤O ª¾ÃÑ §Ö¼Ö º¡·N ®ð½è ¯h³Ò ¯f®ð º¡¦å º¡ªk */
-{
- /* Âû */
- {1, 1, 30, 3, 8, 3, 3, 40, 9, 1, 7, 3, 30, 1},
- /* ¬ü¤Ö¤k */
- {1, 1, 110, 1, 4, 7, 41, 20, 9, 25, 25, 7, 110, 15},
- /* «i¤h */
- {1, 1, 200, 5, 4, 10, 33, 20, 15, 10, 27, 1, 200, 9},
- /* »jµï */
- {1, 1, 10, 5, 8, 1, 1, 5, 3, 1, 4, 1, 10, 30},
- /* ®£Às */
- {1, 1, 1000, 9, 1, 13, 4, 12, 3, 1, 200, 1, 1000, 3},
- /* ¦ÑÆN */
- {1, 1, 90, 7, 10, 7, 4, 12, 3, 30, 20, 5, 90, 20},
- /* ¿ß */
- {1, 1, 30, 5, 5, 6, 4, 8, 3, 15, 7, 4, 30, 21},
- /* Äúµ§¤p·s */
- {1, 1, 100, 9, 7, 7, 20, 50, 10, 8, 24, 4, 100, 9},
- /* ª¯ */
- {1, 1, 45, 8, 7, 9, 3, 40, 20, 3, 9, 5, 45, 1},
- /* ´cÅ] */
- {1, 1, 45, 10, 11, 11, 5, 21, 11, 1, 9, 5, 45, 25},
- /* §ÔªÌ */
- {1, 1, 45, 2, 12, 10, 25, 1, 1, 10, 9, 5, 45, 26},
- /* ªü«ó */
- {1, 1, 150, 4, 8, 13, 95, 25, 7, 10, 25, 5, 175, 85},
- /* °¨­^¤E */
- {1, 1, 147, 2, 10, 10, 85, 20, 4, 25, 25, 5, 145, 95},
- /* ´N¥i¤H */
- {1, 1, 200, 3, 15, 15, 50, 50, 10, 5, 10, 2, 300, 0},
- /* ù§Q */
- {1, 1, 80, 2, 9, 10, 2, 5, 7, 8, 12, 1, 135, 5},
-};
-
-static void time_diff(chicken_t * thechicken);
-static int isdeadth(const chicken_t * thechicken, chicken_t *mychicken);
-
-chicken_t * load_live_chicken(const char *uid)
-{
- char fn[PATHLEN];
- int fd = 0;
- chicken_t *p = NULL;
-
- if (!uid || !uid[0]) return NULL;
- sethomefile(fn, uid, FN_CHICKEN);
- if (!dashf(fn)) return NULL;
- fd = open(fn, O_RDWR);
- if (fd < 0) return NULL;
-
- // now fd is valie. open and mmap.
- p = mmap(NULL, sizeof(chicken_t), PROT_READ|PROT_WRITE, MAP_SHARED,
- fd, 0);
- close(fd);
- return p;
-}
-
-int load_chicken(const char *uid, chicken_t *mychicken)
-{
- char fn[PATHLEN];
- int fd = 0;
-
- memset(mychicken, 0, sizeof(chicken_t));
- if (!uid || !uid[0]) return 0;
- sethomefile(fn, uid, FN_CHICKEN);
- if (!dashf(fn)) return 0;
- fd = open(fn, O_RDONLY);
- if (fd < 0) return 0;
- if (read(fd, mychicken, sizeof(chicken_t)) > 0 && mychicken->name[0])
- return 1;
- return 0;
-}
-
-void free_live_chicken(chicken_t *p)
-{
- if (!p) return;
- munmap(p, sizeof(chicken_t));
-}
-
-void
-chicken_query(const char *userid)
-{
- chicken_t xchicken;
-
-#ifdef CHICKEN_LIVE_UPGRADE
- // live update
- vmsg("PTT ¨t²Î¶i¦æ§ó·s¡A¥»¶g¼È°±¶}©ñÃdª«¬d¸ß¡C");
- return;
-#endif
-
- if (!load_chicken(userid, &xchicken))
- {
- move(1, 0);
- clrtobot();
- prints("\n\n%s ¨Ã¨S¦³¾iÃdª«..", userid);
- } else {
- time_diff(&xchicken);
- if (!isdeadth(&xchicken, NULL))
- {
- show_chicken_data(&xchicken, NULL);
- prints("\n\n¥H¤W¬O %s ªºÃdª«¸ê®Æ..", userid);
- } else {
- move(1, 0);
- clrtobot();
- prints("\n\n%s ªºÃdª«¦º±¼¤F...", userid);
- }
- }
-
- pressanykey();
-}
-
-static int
-new_chicken(void)
-{
- chicken_t mychicken;
- int price, i;
- int fd;
- char fn[PATHLEN];
-
- memset(&mychicken, 0, sizeof(chicken_t));
-
- clear();
- move(2, 0);
- outs("Åwªï¥úÁ{ " ANSI_COLOR(33) "¡·" ANSI_COLOR(37;44) " "
- BBSMNAME "Ãdª«¥«³õ " ANSI_COLOR(33;40) "¡·" ANSI_RESET ".. "
- "¥Ø«e³J»ù¡G\n"
- "(a)¤pÂû $5 (b)¬ü¤Ö¤k $25 (c)«i¤h $30 (d)»jµï $40 "
- "(e)®£Às $80\n"
- "(f)¦ÑÆN $50 (g)¿ß $15 (h)Äúµ§¤p·s$35 (i)ª¯ª¯ $17 "
- "(j)´cÅ] $100\n"
- "(k)§ÔªÌ $85 (n)´N¥i¤H$100 (m)ÅÚ²ú $77\n"
- "[0]¤£·Q¶R¤F $0\n");
- i = getans("½Ð¿ï¾Ü§A­n¾iªº°Êª«¡G");
-
- // since (o) is confusing to some people, we alias 'm' to 'o'.
- if (i == 'm') i = 'o';
-
- // (m, l) were political person.
- // do not make them in a BBS system...
- if (i == 'm' || i == 'l')
- return 0;
-
- i -= 'a';
- if (i < 0 || i > NUM_KINDS - 1)
- return 0;
-
- mychicken.type = i;
-
- price = egg_price[(int)mychicken.type];
- reload_money();
- if (cuser.money < price) {
- vmsgf("¿ú¤£°÷¶R³J³J,³J³J­n %d ¤¸", price);
- return 0;
- }
-
- while (strlen(mychicken.name) < 3)
- {
- getdata(8, 0, "À°¨e¨ú­Ó¦n¦W¦r¡G", mychicken.name,
- sizeof(mychicken.name), DOECHO);
- }
-
- mychicken.lastvisit = mychicken.birthday = mychicken.cbirth = now;
- mychicken.food = 0;
- mychicken.weight = time_change[(int)mychicken.type][WEIGHT] / 3;
- mychicken.clean = 0;
- mychicken.run = time_change[(int)mychicken.type][RUN];
- mychicken.attack = time_change[(int)mychicken.type][ATTACK];
- mychicken.book = time_change[(int)mychicken.type][BOOK];
- mychicken.happy = time_change[(int)mychicken.type][HAPPY];
- mychicken.satis = time_change[(int)mychicken.type][SATIS];
- mychicken.temperament = time_change[(int)mychicken.type][TEMPERAMENT];
- mychicken.tiredstrong = 0;
- mychicken.sick = 0;
- mychicken.hp = time_change[(int)mychicken.type][WEIGHT];
- mychicken.hp_max = time_change[(int)mychicken.type][WEIGHT];
- mychicken.mm = 0;
- mychicken.mm_max = 0;
-
- reload_money();
- if (cuser.money < price)
- {
- vmsg("¿ú¤£°÷¤F¡C");
- return 0;
- }
- vice(price, "Ãdª«³J");
-
- // flush it
- setuserfile(fn, FN_CHICKEN);
- fd = open(fn, O_WRONLY|O_CREAT, 0666);
- if (fd < 0)
- {
- vmsg("¨t²Î¿ù»~: µLªk«Ø¥ß¸ê®Æ¡A½Ð¦Ü " GLOBAL_BUGREPORT " ³ø§i¡C");
- return 0;
- }
-
- write(fd, &mychicken, sizeof(chicken_t));
- close(fd);
-
- // log data
- log_filef(CHICKENLOG, LOG_CREAT,
- ANSI_COLOR(31) "%s " ANSI_RESET "¾i¤F¤@°¦¥s" ANSI_COLOR(33) " %s " ANSI_RESET "ªº "
- ANSI_COLOR(32) "%s" ANSI_RESET " ©ó %s\n", cuser.userid,
- mychicken.name, chicken_type[(int)mychicken.type], ctime4(&now));
- return 1;
-}
-
-static void
-show_chicken_stat(const chicken_t * thechicken, int age)
-{
- struct tm *ptime;
-
- ptime = localtime4(&thechicken->birthday);
- prints(" Name :" ANSI_COLOR(33) "%s" ANSI_RESET " (" ANSI_COLOR(32) "%s" ANSI_RESET ")%*s¥Í¤é "
- ":" ANSI_COLOR(31) "%02d" ANSI_RESET "¦~" ANSI_COLOR(31) "%2d" ANSI_RESET "¤ë" ANSI_COLOR(31) "%2d" ANSI_RESET "¤é "
- "(" ANSI_COLOR(32) "%s %d·³" ANSI_RESET ")\n"
- " Åé:" ANSI_COLOR(33) "%5d/%-5d" ANSI_RESET " ªk:" ANSI_COLOR(33) "%5d/%-5d" ANSI_RESET " §ðÀ»¤O:"
- ANSI_COLOR(33) "%-7d" ANSI_RESET " ±Ó±¶ :" ANSI_COLOR(33) "%-7d" ANSI_RESET " ª¾ÃÑ :" ANSI_COLOR(33) "%-7d"
- ANSI_RESET " \n"
- " §Ö¼Ö :" ANSI_COLOR(33) "%-7d " ANSI_RESET " º¡·N :" ANSI_COLOR(33) "%-7d " ANSI_RESET " ¯h³Ò :"
- ANSI_COLOR(33) "%-7d" ANSI_RESET " ®ð½è :" ANSI_COLOR(33) "%-7d " ANSI_RESET "Åé­« :"
- ANSI_COLOR(33) "%-5.2f" ANSI_RESET " \n"
- " ¯f®ð :" ANSI_COLOR(33) "%-7d " ANSI_RESET " °®²b :" ANSI_COLOR(33) "%-7d " ANSI_RESET " ­¹ª« :"
- ANSI_COLOR(33) "%-7d" ANSI_RESET " ¤j¸É¤Y:" ANSI_COLOR(33) "%-7d" ANSI_RESET " ÃÄ«~ :" ANSI_COLOR(33) "%-7d"
- ANSI_RESET " \n",
- thechicken->name, chicken_type[(int)thechicken->type],
- strlen(thechicken->name) >= 15 ? 0 : (int)(15 - strlen(thechicken->name)), "",
- ptime->tm_year % 100, ptime->tm_mon + 1, ptime->tm_mday,
- cage[age > 16 ? 16 : age], age, thechicken->hp, thechicken->hp_max,
- thechicken->mm, thechicken->mm_max,
- thechicken->attack, thechicken->run, thechicken->book,
- thechicken->happy, thechicken->satis, thechicken->tiredstrong,
- thechicken->temperament,
- ((float)(thechicken->hp_max + (thechicken->weight / 50))) / 100,
- thechicken->sick, thechicken->clean, thechicken->food,
- thechicken->oo, thechicken->medicine);
-}
-
-#define CHICKEN_PIC "etc/chickens"
-
-static void
-show_chicken_picture(const char *fpath)
-{
- show_file(fpath, 5, 14, SHOWFILE_ALLOW_ALL);
-}
-
-void
-show_chicken_data(chicken_t * thechicken, chicken_t * pkchicken)
-{
- char buf[1024];
- int age = ((now - thechicken->cbirth) / (60 * 60 * 24));
- if (age < 0) {
- thechicken->birthday = thechicken->cbirth = now - 10 * (60 * 60 * 24);
- age = 10;
- }
- /* Ptt:debug */
- thechicken->type %= NUM_KINDS;
- clear();
- showtitle(pkchicken ? BBSMNAME2 "°«Âû³õ" : BBSMNAME2 "¾iÂû³õ", BBSName);
- move(1, 0);
-
- show_chicken_stat(thechicken, age);
-
- snprintf(buf, sizeof(buf), CHICKEN_PIC "/%c%d", thechicken->type + 'a',
- age > 16 ? 16 : age);
-
- show_chicken_picture(buf);
-
- move(18, 0);
-
- if (thechicken->sick)
- outs("¥Í¯f¤F...");
- if (thechicken->sick > thechicken->hp / 5)
- outs(ANSI_COLOR(5;31) "¾á¤ß...¯f­«!!" ANSI_RESET);
-
- if (thechicken->clean > 150)
- outs(ANSI_COLOR(31) "¤S¯ä¤Sżªº.." ANSI_RESET);
- else if (thechicken->clean > 80)
- outs("¦³ÂIż..");
- else if (thechicken->clean < 20)
- outs(ANSI_COLOR(32) "«Ü°®²b.." ANSI_RESET);
-
- if (thechicken->weight > thechicken->hp_max * 4)
- outs(ANSI_COLOR(31) "§Ö¹¡¦º¤F!." ANSI_RESET);
- else if (thechicken->weight > thechicken->hp_max * 3)
- outs(ANSI_COLOR(32) "¹¡¹Ê¹Ê.." ANSI_RESET);
- else if (thechicken->weight < (thechicken->hp_max / 4))
- outs(ANSI_COLOR(31) "§Ö¾j¦º¤F!.." ANSI_RESET);
- else if (thechicken->weight < (thechicken->hp_max / 2))
- outs("¾j¤F..");
-
- if (thechicken->tiredstrong > thechicken->hp * 1.7)
- outs(ANSI_COLOR(31) "²Ö±o©ü°g¤F..." ANSI_RESET);
- else if (thechicken->tiredstrong > thechicken->hp)
- outs("²Ö¤F..");
- else if (thechicken->tiredstrong < thechicken->hp / 4)
- outs(ANSI_COLOR(32) "ºë¤O©ô²±..." ANSI_RESET);
-
- if (thechicken->hp < thechicken->hp_max / 4)
- outs(ANSI_COLOR(31) "Åé¤O¥ÎºÉ..©a©a¤@®§.." ANSI_RESET);
- if (thechicken->happy > 500)
- outs(ANSI_COLOR(32) "«Ü§Ö¼Ö.." ANSI_RESET);
- else if (thechicken->happy < 100)
- outs("¤£§Ö¼Ö..");
- if (thechicken->satis > 500)
- outs(ANSI_COLOR(32) "«Üº¡¨¬.." ANSI_RESET);
- else if (thechicken->satis < 50)
- outs("¤£º¡¨¬..");
-
- if (pkchicken) {
- outc('\n');
- show_chicken_stat(pkchicken, age);
- outs("[¥ô·NÁä] §ðÀ»¹ï¤è [q] ¸¨¶] [o] ¦Y¤j¸É¤Y");
- }
-}
-
-static void
-ch_eat(chicken_t *mychicken)
-{
- if (mychicken->food) {
- mychicken->weight += time_change[(int)mychicken->type][WEIGHT] +
- mychicken->hp_max / 5;
- mychicken->tiredstrong +=
- time_change[(int)mychicken->type][TIREDSTRONG] / 2;
- mychicken->hp_max++;
- mychicken->happy += 5;
- mychicken->satis += 7;
- mychicken->food--;
- move(10, 10);
-
- show_chicken_picture(CHICKEN_PIC "/eat");
- pressanykey();
- }
-}
-
-static void
-ch_clean(chicken_t *mychicken)
-{
- mychicken->clean = 0;
- mychicken->tiredstrong +=
- time_change[(int)mychicken->type][TIREDSTRONG] / 3;
- show_chicken_picture(CHICKEN_PIC "/clean");
- pressanykey();
-}
-
-static void
-ch_guess(chicken_t *mychicken)
-{
- char *guess[3] = {"°Å¤M", "¥ÛÀY", "¥¬"}, me, ch, win;
-
- mychicken->happy += time_change[(int)mychicken->type][HAPPY] * 1.5;
- mychicken->satis += time_change[(int)mychicken->type][SATIS];
- mychicken->tiredstrong += time_change[(int)mychicken->type][TIREDSTRONG];
- mychicken->attack += time_change[(int)mychicken->type][ATTACK] / 4;
- move(20, 0);
- clrtobot();
- outs("§A­n¥X[" ANSI_COLOR(32) "1" ANSI_RESET "]" ANSI_COLOR(33) "°Å¤M" ANSI_RESET "(" ANSI_COLOR(32) "2" ANSI_RESET ")"
- ANSI_COLOR(33) "¥ÛÀY" ANSI_RESET "(" ANSI_COLOR(32) "3" ANSI_RESET ")" ANSI_COLOR(33) "¥¬" ANSI_RESET ":\n");
- me = igetch();
- me -= '1';
- if (me > 2 || me < 0)
- me = 0;
- win = (int)(3.0 * random() / (RAND_MAX + 1.0)) - 1;
- ch = (me + win + 3) % 3;
- prints("%s:%s ! %s:%s !.....%s",
- cuser.userid, guess[(int)me], mychicken->name, guess[(int)ch],
- win == 0 ? "¥­¤â" : win < 0 ? "­C..ŤF :D!!" : "¶ã..§Ú¿é¤F :~");
- pressanykey();
-}
-
-static void
-ch_book(chicken_t *mychicken)
-{
- mychicken->book += time_change[(int)mychicken->type][BOOK];
- mychicken->tiredstrong += time_change[(int)mychicken->type][TIREDSTRONG];
- show_chicken_picture(CHICKEN_PIC "/read");
- pressanykey();
-}
-
-static void
-ch_kiss(chicken_t *mychicken)
-{
- mychicken->happy += time_change[(int)mychicken->type][HAPPY];
- mychicken->satis += time_change[(int)mychicken->type][SATIS];
- mychicken->tiredstrong +=
- time_change[(int)mychicken->type][TIREDSTRONG] / 2;
- show_chicken_picture(CHICKEN_PIC "/kiss");
- pressanykey();
-}
-
-static void
-ch_hit(chicken_t *mychicken)
-{
- mychicken->attack += time_change[(int)mychicken->type][ATTACK];
- mychicken->run += time_change[(int)mychicken->type][RUN];
- mychicken->mm_max += time_change[(int)mychicken->type][MM_MAX] / 15;
- mychicken->weight -= mychicken->hp_max / 15;
- mychicken->hp -= (int)((float)time_change[(int)mychicken->type][HP_MAX] *
- random() / (RAND_MAX + 1.0)) / 2 + 1;
-
- if (mychicken->book > 2)
- mychicken->book -= 2;
- if (mychicken->happy > 2)
- mychicken->happy -= 2;
- if (mychicken->satis > 2)
- mychicken->satis -= 2;
- mychicken->tiredstrong += time_change[(int)mychicken->type][TIREDSTRONG];
- show_chicken_picture(CHICKEN_PIC "/hit");
- pressanykey();
-}
-
-void
-ch_buyitem(int money, const char *picture, int *item, int haveticket)
-{
- int num = 0;
- char buf[5];
-
- getdata_str(b_lines - 1, 0, "­n¶R¦h¤Ö¥÷©O:",
- buf, sizeof(buf), DOECHO, "1");
- num = atoi(buf);
- if (num < 1)
- return;
- reload_money();
- if (cuser.money/money >= num) {
- *item += num;
- if( haveticket )
- vice(money * num, "ÁʶRÃdª«,½ä½L¶µ¥Ø");
- else
- demoney(-money * num);
- show_chicken_picture(picture);
- pressanykey();
- } else {
- vmsg("²{ª÷¤£°÷ !!!");
- }
- usleep(100000); // sleep 0.1s
-}
-
-static void
-ch_eatoo(chicken_t *mychicken)
-{
- if (mychicken->oo > 0) {
- mychicken->oo--;
- mychicken->tiredstrong = 0;
- if (mychicken->happy > 5)
- mychicken->happy -= 5;
- show_chicken_picture(CHICKEN_PIC "/oo");
- pressanykey();
- }
-}
-
-static void
-ch_eatmedicine(chicken_t *mychicken)
-{
- if (mychicken->medicine > 0) {
- mychicken->medicine--;
- mychicken->sick = 0;
- if (mychicken->hp_max > 10)
- mychicken->hp_max -= 3;
- mychicken->hp = mychicken->hp_max;
- if (mychicken->happy > 10)
- mychicken->happy -= 10;
- show_chicken_picture(CHICKEN_PIC "/medicine");
- pressanykey();
- }
-}
-
-static void
-ch_kill(chicken_t *mychicken)
-{
- int ans;
-
- ans = getans("±ó¾i­n³Q»@ 100 ¤¸, ¬O§_­n±ó¾i?(y/N)");
- if (ans == 'y') {
-
- vice(100, "±ó¾iÃdª«¶O");
- more(CHICKEN_PIC "/deadth", YEA);
- log_filef(CHICKENLOG, LOG_CREAT,
- ANSI_COLOR(31) "%s " ANSI_RESET "§â " ANSI_COLOR(33) "%s" ANSI_RESET ANSI_COLOR(32) " %s "
- ANSI_RESET "®_¤F ©ó %s\n", cuser.userid, mychicken->name,
- chicken_type[(int)mychicken->type], ctime4(&now));
- mychicken->name[0] = 0;
- }
-}
-
-static void
-geting_old(int *hp, int *weight, int diff, int age)
-{
- float ex = 0.9;
-
- if (age > 70)
- ex = 0.1;
- else if (age > 30)
- ex = 0.5;
- else if (age > 20)
- ex = 0.7;
-
- diff /= 60 * 6;
- while (diff--) {
- *hp *= ex;
- *weight *= ex;
- }
-}
-
-/* ¨Ì®É¶¡Åܰʪº¸ê®Æ */
-static void
-time_diff(chicken_t * thechicken)
-{
- int diff;
- int theage = ((now - thechicken->cbirth) / (60 * 60 * 24));
-
- thechicken->type %= NUM_KINDS;
- diff = (now - thechicken->lastvisit) / 60;
-
- if ((diff) < 1)
- return;
-
- if (theage > 13) /* ¦Ñ¦º */
- geting_old(&thechicken->hp_max, &thechicken->weight, diff, theage);
-
- thechicken->lastvisit = now;
- thechicken->weight -= thechicken->hp_max * diff / 540; /* Åé­« */
- if (thechicken->weight < 1) {
- thechicken->sick -= thechicken->weight / 10; /* ¾j±o¯f®ð¤W¤É */
- thechicken->weight = 1;
- }
- /* ²M¼ä«× */
- thechicken->clean += diff * time_change[(int)thechicken->type][CLEAN] / 30;
-
- /* §Ö¼Ö«× */
- thechicken->happy -= diff / 60;
- if (thechicken->happy < 0)
- thechicken->happy = 0;
- thechicken->attack -=
- time_change[(int)thechicken->type][ATTACK] * diff / (60 * 32);
- if (thechicken->attack < 0)
- thechicken->attack = 0;
- /* §ðÀ»¤O */
- thechicken->run -= time_change[(int)thechicken->type][RUN] * diff / (60 * 32);
- /* ±Ó±¶ */
- if (thechicken->run < 0)
- thechicken->run = 0;
- thechicken->book -= time_change[(int)thechicken->type][BOOK] * diff / (60 * 32);
- /* ª¾ÃÑ */
- if (thechicken->book < 0)
- thechicken->book = 0;
- /* ®ð½è */
- thechicken->temperament++;
-
- thechicken->satis -= diff / 60 / 3 * time_change[(int)thechicken->type][SATIS];
- /* º¡·N«× */
- if (thechicken->satis < 0)
- thechicken->satis = 0;
-
- /* ż¯fªº */
- if (thechicken->clean > 1000)
- thechicken->sick += (thechicken->clean - 400) / 10;
-
- if (thechicken->weight > 1)
- thechicken->sick -= diff / 60;
- /* ¯f®ð«ìÅ@ */
- if (thechicken->sick < 0)
- thechicken->sick = 0;
- thechicken->tiredstrong -= diff *
- time_change[(int)thechicken->type][TIREDSTRONG] / 4;
- /* ¯h³Ò */
- if (thechicken->tiredstrong < 0)
- thechicken->tiredstrong = 0;
- /* hp_max */
- if (thechicken->hp >= thechicken->hp_max / 2)
- thechicken->hp_max +=
- time_change[(int)thechicken->type][HP_MAX] * diff / (60 * 12);
- /* hp«ìÅ@ */
- if (!thechicken->sick)
- thechicken->hp +=
- time_change[(int)thechicken->type][HP_MAX] * diff / (60 * 6);
- if (thechicken->hp > thechicken->hp_max)
- thechicken->hp = thechicken->hp_max;
- /* mm_max */
- if (thechicken->mm >= thechicken->mm_max / 2)
- thechicken->mm_max +=
- time_change[(int)thechicken->type][MM_MAX] * diff / (60 * 8);
- /* mm«ìÅ@ */
- if (!thechicken->sick)
- thechicken->mm += diff;
- if (thechicken->mm > thechicken->mm_max)
- thechicken->mm = thechicken->mm_max;
-}
-
-static void
-check_sick(chicken_t *mychicken)
-{
- /* ż¯fªº */
- if (mychicken->tiredstrong > mychicken->hp * 0.3 && mychicken->clean > 150)
- mychicken->sick += (mychicken->clean - 150) / 10;
- /* ²Ö¯fªº */
- if (mychicken->tiredstrong > mychicken->hp * 1.3)
- mychicken->sick += time_change[(int)mychicken->type][SICK];
- /* ¯f®ð¤Ó­«ÁÙ°µ¨Æ´îhp */
- if (mychicken->sick > mychicken->hp / 5) {
- mychicken->hp -= (mychicken->sick - mychicken->hp / 5) / 4;
- if (mychicken->hp < 0)
- mychicken->hp = 0;
- }
-}
-
-static int
-deadtype(const chicken_t * thechicken, chicken_t *mychicken)
-{
- int i;
-
- if (thechicken->hp <= 0) /* hp¥ÎºÉ */
- i = 1;
- else if (thechicken->tiredstrong > thechicken->hp * 3) /* ¾Þ³Ò¹L«× */
- i = 2;
- else if (thechicken->weight > thechicken->hp_max * 5) /* ªÎ­D¹L«× */
- i = 3;
- else if (thechicken->weight == 1 &&
- thechicken->sick > thechicken->hp_max / 4)
- i = 4; /* ¾j¦º¤F */
- else if (thechicken->satis <= 0) /* «Ü¤£º¡·N */
- i = 5;
- else
- return 0;
-
- if (thechicken == mychicken) {
- log_filef(CHICKENLOG, LOG_CREAT,
- ANSI_COLOR(31) "%s" ANSI_RESET " ©Ò¯k·Rªº" ANSI_COLOR(33) " %s" ANSI_COLOR(32) " %s "
- ANSI_RESET "±¾¤F ©ó %s\n", cuser.userid, thechicken->name,
- chicken_type[(int)thechicken->type], ctime4(&now));
- mychicken->name[0] = 0;
- }
- return i;
-}
-
-int
-showdeadth(int type)
-{
- switch (type) {
- case 1:
- more(CHICKEN_PIC "/nohp", YEA);
- break;
- case 2:
- more(CHICKEN_PIC "/tootired", YEA);
- break;
- case 3:
- more(CHICKEN_PIC "/toofat", YEA);
- break;
- case 4:
- more(CHICKEN_PIC "/nofood", YEA);
- break;
- case 5:
- more(CHICKEN_PIC "/nosatis", YEA);
- break;
- default:
- return 0;
- }
- more(CHICKEN_PIC "/deadth", YEA);
- return type;
-}
-
-static int
-isdeadth(const chicken_t * thechicken, chicken_t *mychicken)
-{
- int i;
-
- if (!(i = deadtype(thechicken, mychicken)))
- return 0;
- return showdeadth(i);
-}
-
-static void
-ch_changename(chicken_t *mychicken)
-{
- char newname[20] = "";
-
- getdata_str(b_lines - 1, 0, "¶â..§ï­Ó¦n¦W¦r§a:", newname, 18, DOECHO,
- mychicken->name);
-
- if (strlen(newname) >= 3 && strcmp(newname, mychicken->name)) {
- strlcpy(mychicken->name, newname, sizeof(mychicken->name));
- log_filef(CHICKENLOG, LOG_CREAT,
- ANSI_COLOR(31) "%s" ANSI_RESET " §â¯k·Rªº" ANSI_COLOR(33) " %s" ANSI_COLOR(32) " %s "
- ANSI_RESET "§ï¦W¬°" ANSI_COLOR(33) " %s" ANSI_RESET " ©ó %s\n",
- cuser.userid, mychicken->name,
- chicken_type[(int)mychicken->type], newname, ctime4(&now));
- }
-}
-
-static int
-select_menu(int age, chicken_t *mychicken)
-{
- char ch;
-
- reload_money();
- move(19, 0);
- prints(ANSI_COLOR(44;37) " ¿ú :" ANSI_COLOR(33) " %-10d "
- " " ANSI_RESET "\n"
- ANSI_COLOR(33) "(" ANSI_COLOR(37) "1" ANSI_COLOR(33) ")²M²z (" ANSI_COLOR(37) "2" ANSI_COLOR(33) ")¦Y¶º "
- "(" ANSI_COLOR(37) "3" ANSI_COLOR(33) ")²q®± (" ANSI_COLOR(37) "4" ANSI_COLOR(33) ")°á®Ñ "
- "(" ANSI_COLOR(37) "5" ANSI_COLOR(33) ")¿Ë¥L (" ANSI_COLOR(37) "6" ANSI_COLOR(33) ")¥´¥L "
- "(" ANSI_COLOR(37) "7" ANSI_COLOR(33) ")¶R%s$%d (" ANSI_COLOR(37) "8" ANSI_COLOR(33) ")¦Y¸É¤Y\n"
- "(" ANSI_COLOR(37) "9" ANSI_COLOR(33) ")¦Y¯fÃÄ (" ANSI_COLOR(37) "o" ANSI_COLOR(33) ")¶R¤j¸É¤Y$100 "
- "(" ANSI_COLOR(37) "m" ANSI_COLOR(33) ")¶RÃÄ$10 (" ANSI_COLOR(37) "k" ANSI_COLOR(33) ")±ó¾i "
- "(" ANSI_COLOR(37) "n" ANSI_COLOR(33) ")§ï¦W "
- "(" ANSI_COLOR(37) "q" ANSI_COLOR(33) ")Â÷¶}:" ANSI_RESET,
- cuser.money,
- /*
- * chicken_food[(int)mychicken->type],
- * chicken_type[(int)mychicken->type],
- * chicken_type[(int)mychicken->type],
- */
- chicken_food[(int)mychicken->type],
- food_price[(int)mychicken->type]);
- do {
- switch (ch = igetch()) {
- case '1':
- ch_clean(mychicken);
- check_sick(mychicken);
- break;
- case '2':
- ch_eat(mychicken);
- check_sick(mychicken);
- break;
- case '3':
- ch_guess(mychicken);
- check_sick(mychicken);
- break;
- case '4':
- ch_book(mychicken);
- check_sick(mychicken);
- break;
- case '5':
- ch_kiss(mychicken);
- break;
- case '6':
- ch_hit(mychicken);
- check_sick(mychicken);
- break;
- case '7':
- ch_buyitem(food_price[(int)mychicken->type], CHICKEN_PIC "/food",
- &mychicken->food, 1);
- break;
- case '8':
- ch_eatoo(mychicken);
- break;
- case '9':
- ch_eatmedicine(mychicken);
- break;
- case 'O':
- case 'o':
- ch_buyitem(100, CHICKEN_PIC "/buyoo", &mychicken->oo, 1);
- break;
- case 'M':
- case 'm':
- ch_buyitem(10, CHICKEN_PIC "/buymedicine", &mychicken->medicine, 1);
- break;
- case 'N':
- case 'n':
- ch_changename(mychicken);
- break;
- case 'K':
- case 'k':
- ch_kill(mychicken);
- return 0;
- case 'Q':
- case 'q':
- return 0;
- }
- } while (ch < ' ' || ch > 'z');
- return 1;
-}
-
-static int
-recover_chicken(chicken_t * thechicken)
-{
- char buf[200];
- int price = egg_price[(int)thechicken->type];
- int money = price + (random() % price);
- price *= 2;
- // money is a little less than price.
-
- if (now - thechicken->lastvisit > (60 * 60 * 24 * 7))
- return 0;
- outmsg(ANSI_COLOR(33;44) "¡¹ÆF¬É¦u½Ã" ANSI_COLOR(37;45) " §O®`©È §Ú¬O¨ÓÀ°§Aªº " ANSI_RESET);
- bell();
- igetch();
- outmsg(ANSI_COLOR(33;44) "¡¹ÆF¬É¦u½Ã" ANSI_COLOR(37;45) " §AµLªk¥á¨ì§Ú¤ô²y ¦]¬°§Ú¬O¸tÆF, "
- "³Ìªñ¯Ê¿ú·QÁÈ¥~§Ö " ANSI_RESET);
- bell();
- igetch();
- snprintf(buf, sizeof(buf), ANSI_COLOR(33;44) "¡¹ÆF¬É¦u½Ã" ANSI_COLOR(37;45) " "
- "§A¦³¤@­Ó­è¨«¤£¤[ªº%s­n©Û´«¦^¨Ó¶Ü? ¥u­n %d ¤¸­ò " ANSI_RESET,
- chicken_type[(int)thechicken->type], price);
- outmsg(buf);
- bell();
- getdata_str(21, 0, " ¿ï¾Ü¡G(N:§|¤H¹À/y:½ÐÀ°À°§Ú)", buf, 3, LCECHO, "N");
- if (buf[0] == 'y' || buf[0] == 'Y') {
- reload_money();
- if (cuser.money < price) {
- outmsg(ANSI_COLOR(33;44) "¡¹ÆF¬É¦u½Ã" ANSI_COLOR(37;45) " ¤°»ò ¿ú¨S±a°÷ "
- "¨S¿úªº¤p°­ §Ö¥hÄw¿ú§a " ANSI_RESET);
- bell();
- igetch();
- return 0;
- }
- strlcpy(thechicken->name, "[¾ß¦^¨Óªº]", sizeof(thechicken->name));
- thechicken->hp = thechicken->hp_max;
- thechicken->sick = 0;
- thechicken->satis = 2;
- thechicken->tiredstrong = 0;
- thechicken->weight = thechicken->hp;
- // thechicken->lastvisit = now; // really need so?
- vice(money, "ÆF¬É¦u½Ã");
- snprintf(buf, sizeof(buf),
- ANSI_COLOR(33;44) "¡¹ÆF¬É¦u½Ã" ANSI_COLOR(37;45)
- " OK¤F °O±oÁý¥LÂIªF¦è ¤£µM¥i¯à¥¢®Ä¡C"
- "¤µ¤Ñ¤ß±¡¦n¡A®³§A$%d´N¦n " ANSI_RESET, money);
- outmsg(buf);
- bell();
- igetch();
- return 1;
- }
- outmsg(ANSI_COLOR(33;44) "¡¹ÆF¬É¦u½Ã" ANSI_COLOR(37;45)
- " ³ºµM»¡§Ú§|¤H! ³o¦~ÀY©R¯u¤£­È¿ú "
- "°£«D§Ú¦A¨Ó§ä§A §A¦A¤]¨S¾÷·|¤F " ANSI_RESET);
- bell();
- igetch();
- thechicken->lastvisit = 0;
- return 0;
-}
-
-void
-chicken_toggle_death(const char *uid)
-{
- chicken_t *mychicken = load_live_chicken(uid);
-
-#ifdef CHICKEN_LIVE_UPGRADE
- // live update
- vmsg("PTT ¨t²Î¶i¦æ§ó·s¡A¥»¶g¼È°±¶}©ñÃdª«³]©w¡C");
- return;
-#endif
-
- if (!uid)
- return;
- if (!mychicken)
- {
- vmsgf("%s ¨S¾iÃdª«¡C", uid);
- }
- else if (mychicken->name[0])
- {
- mychicken->name[0] = 0;
- vmsgf("%s ªºÃdª«³Q±þ¦º¤F", uid);
- }
- else
- {
- strlcpy(mychicken->name, "[¦º]", sizeof(mychicken->name));
- vmsgf("%s ªºÃdª«´_¬¡¤F", uid);
- }
- free_live_chicken(mychicken);
-}
-
-#define lockreturn0(unmode, state) if(lockutmpmode(unmode, state)) return 0
-
-#ifdef CHICKEN_LIVE_UPGRADE
-static void
-chicken_live_upgrade()
-{
- char fn[PATHLEN];
- FILE *fp = NULL;
- setuserfile(fn, FN_CHICKEN);
-
- if (dashf(fn))
- return;
-
- if (!cuser.old_chicken.name[0] &&
- !cuser.old_chicken.cbirth &&
- !cuser.old_chicken.hp_max)
- return;
-
- // write to data.
- fp = fopen(fn, "wb");
- fwrite(&cuser.old_chicken, sizeof(chicken_t), 1, fp);
- fclose(fp);
-#if 0 // enable if you want logs
- log_filef("log/chicken_live_upgrade", LOG_CREAT,
- "%s upgrade chicken at %s",
- cuser.userid, ctime4(&now));
-#endif
-}
-#endif // CHICKEN_LIVE_UPGRADE
-
-int
-chicken_main(void)
-{
- int age;
- chicken_t *mychicken = load_live_chicken(cuser.userid);
-
-#ifdef CHICKEN_LIVE_UPGRADE
- if (mychicken == NULL)
- {
- chicken_live_upgrade();
- mychicken = load_live_chicken(cuser.userid);
- }
-#endif
-
- lockreturn0(CHICKEN, LOCK_MULTI);
- if (mychicken && !mychicken->name[0])
- {
- // possible for recovery
- recover_chicken(mychicken);
- }
- if (!mychicken || !mychicken->name[0])
- {
- free_live_chicken(mychicken);
- mychicken = NULL;
-
- // create new?
- if (new_chicken())
- mychicken = load_live_chicken(cuser.userid);
-
- // exit if still no valid data.
- if (!mychicken || !mychicken->name[0])
- {
- unlockutmpmode();
- free_live_chicken(mychicken);
- return 0;
- }
- }
- assert(mychicken);
- age = ((now - mychicken->cbirth) / (60 * 60 * 24));
- do {
- time_diff(mychicken);
- if (isdeadth(mychicken, mychicken))
- break;
- show_chicken_data(mychicken, NULL);
- } while (select_menu(age, mychicken));
- unlockutmpmode();
- free_live_chicken(mychicken);
- return 0;
-}
-
-#ifdef USE_CHICKEN_PK
-int
-chickenpk(int fd)
-{
- chicken_t *mychicken = load_live_chicken(cuser.userid);
- chicken_t *ochicken = load_live_chicken(currutmp->mateid);
-
- char mateid[IDLEN + 1], data[200], buf[200];
- int ch = 0;
-
- userinfo_t *uin = &SHM->uinfo[currutmp->destuip];
- int r, attmax, i, datac, catched = 0,
- count = 0;
-
- lockreturn0(CHICKEN, LOCK_MULTI);
- /* §â¹ï¤âªºid¥Îlocal buffer°O¦í */
- strlcpy(mateid, currutmp->mateid, sizeof(mateid));
-
- if (!mychicken || !ochicken ||
- !ochicken->name[0] || !mychicken->name[0]) {
- free_live_chicken(mychicken);
- free_live_chicken(ochicken);
- bell();
- vmsg("¦³¤@¤è¨S¦³Ãdª«"); /* Ptt:§«¤îpage®É§âÃdª«½æ±¼ */
- add_io(0, 0);
- close(fd);
- unlockutmpmode();
- return 0;
- }
-
- show_chicken_data(ochicken, mychicken);
- add_io(fd, 3); /* §âfd¥[¨ìigetchºÊµø */
-
- while (1) {
- r = random();
- ch = igetch();
- show_chicken_data(ochicken, mychicken);
- time_diff(mychicken);
-
- i = mychicken->attack * mychicken->hp / mychicken->hp_max;
- for (attmax = 2; (i = i * 9 / 10); attmax++);
-
- if (ch == I_OTHERDATA) {
- count = 0;
- datac = recv(fd, data, sizeof(data), 0);
- if (datac <= 1)
- break;
- move(17, 0);
- outs(data + 1);
- switch (data[0]) {
- case 'c':
- catched = 1;
- move(16, 0);
- outs("­n©ñ¥L¨«¶Ü?(y/N)");
- break;
- case 'd':
- move(16, 0);
- outs("ªü~­Ë¤U¤F!!");
- break;
- }
- if (data[0] == 'd' || data[0] == 'q' || data[0] == 'l')
- break;
- continue;
- } else if (currutmp->turn) {
- count = 0;
- currutmp->turn = 0;
- uin->turn = 1;
- mychicken->tiredstrong++;
- switch (ch) {
- case 'y':
- if (catched == 1) {
- snprintf(data, sizeof(data),
- "lÅý %s ¸¨¶]¤F\n", ochicken->name);
- }
- break;
- case 'n':
- catched = 0;
- default:
- case 'k':
- r = r % (attmax + 2);
- if (r) {
- snprintf(data, sizeof(data),
- "M%s %s%s %s ¶Ë¤F %d ÂI\n", mychicken->name,
- damage_degree[r / 3 > 15 ? 15 : r / 3],
- attack_type[(int)mychicken->type],
- ochicken->name, r);
- ochicken->hp -= r;
- } else
- snprintf(data, sizeof(data),
- "M%s ı±o¤â³n¥XÀ»µL®Ä\n", mychicken->name);
- break;
- case 'o':
- if (mychicken->oo > 0) {
- mychicken->oo--;
- mychicken->hp += 300;
- if (mychicken->hp > mychicken->hp_max)
- mychicken->hp = mychicken->hp_max;
- mychicken->tiredstrong = 0;
- snprintf(data, sizeof(data), "M%s ¦Y¤FÁû¤j¸É¤Y¸É¥RÅé¤O\n",
- mychicken->name);
- } else
- snprintf(data, sizeof(data),
- "M%s ·Q¦Y¤j¸É¤Y, ¥i¬O¨S¦³¤j¸É¤Y¥i¦Y\n",
- mychicken->name);
- break;
- case 'q':
- if (r % (mychicken->run + 1) > r % (ochicken->run + 1))
- snprintf(data, sizeof(data), "q%s ¸¨¶]¤F\n",
- mychicken->name);
- else
- snprintf(data, sizeof(data),
- "c%s ·Q¸¨¶], ¦ý³Q %s §ì¨ì¤F\n",
- mychicken->name, ochicken->name);
- break;
- }
- if (deadtype(ochicken, mychicken)) {
- char *p = strchr(data, '\n');
- if(p) *p = '\0';
- strlcpy(buf, data, sizeof(buf));
- snprintf(data, sizeof(data), "d%s , %s ³Q %s ¥´¦º¤F\n",
- buf + 1, ochicken->name, mychicken->name);
- }
- move(17, 0);
- outs(data + 1);
- i = strlen(data) + 1;
- send(fd, data, i, 0);
- if (data[0] == 'q' || data[0] == 'd')
- break;
- } else {
- move(17, 0);
- if (count++ > 30)
- break;
- }
- }
- add_io(0, 0); /* §âigetch«ì´_¦^ */
- pressanykey();
- close(fd);
- showdeadth(deadtype(mychicken, mychicken));
- unlockutmpmode();
- free_live_chicken(mychicken);
- free_live_chicken(ochicken);
- return 0;
-}
-#endif // USE_CHICKEN_PK
diff --git a/mbbsd/convert.c b/mbbsd/convert.c
deleted file mode 100644
index e5d0f07b..00000000
--- a/mbbsd/convert.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-#ifdef CONVERT
-
-extern unsigned char *gb2big(unsigned char *, int *, int);
-extern unsigned char *big2gb(unsigned char *, int *, int);
-extern unsigned char *utf8_uni(unsigned char *, int *, int);
-extern unsigned char *uni_utf8(unsigned char *, int *, int);
-extern unsigned char *uni2big(unsigned char *, int *, int);
-extern unsigned char *big2uni(unsigned char *, int *, int);
-
-static ssize_t
-gb_input(void *buf, ssize_t icount)
-{
- /* is sizeof(ssize_t) == sizeof(int)? not sure */
- int ic = (int) icount;
- gb2big((unsigned char *)buf, &ic, 0);
- return (ssize_t)ic;
-}
-
-static ssize_t
-gb_read(int fd, void *buf, size_t count)
-{
- ssize_t icount = read(fd, buf, count);
- if (icount > 0)
- icount = gb_input(buf, icount);
- return icount;
-}
-
-static ssize_t
-gb_write(int fd, void *buf, size_t count)
-{
- int icount = (int)count;
- big2gb((unsigned char *)buf, &icount, 0);
- if(icount > 0)
- return write(fd, buf, (size_t)icount);
- else
- return count; /* fake */
-}
-
-static ssize_t
-utf8_input (void *buf, ssize_t icount)
-{
- /* is sizeof(ssize_t) == sizeof(int)? not sure */
- int ic = (int) icount;
- utf8_uni(buf, &ic, 0);
- uni2big(buf, &ic, 0);
- return (ssize_t)ic;
-}
-
-static ssize_t
-utf8_read(int fd, void *buf, size_t count)
-{
- ssize_t icount = read(fd, buf, count);
- if (icount > 0)
- icount = utf8_input(buf, icount);
- return icount;
-}
-
-static ssize_t
-utf8_write(int fd, void *buf, size_t count)
-{
- int icount = (int)count;
- static unsigned char *mybuf = NULL;
- static int cmybuf = 0;
-
- /* utf8 output is a special case because
- * we need larger buffer which can be
- * tripple or more in size.
- * Current implementation uses 128 for each block.
- */
-
- if(cmybuf < count * 4) {
- cmybuf = (count*4+0x80) & (~0x7f) ;
- mybuf = (unsigned char*) realloc (mybuf, cmybuf);
- }
- memcpy(mybuf, buf, count);
- big2uni(mybuf, &icount, 0);
- uni_utf8(mybuf, &icount, 0);
- if(icount > 0)
- return write(fd, mybuf, (size_t)icount);
- else
- return count; /* fake */
-}
-
-static ssize_t
-norm_input(void *buf, ssize_t icount)
-{
- return icount;
-}
-
-/* global function pointers */
-read_write_type write_type = (read_write_type)write;
-read_write_type read_type = read;
-convert_type input_type = norm_input;
-
-// enable this in case some day we want to detect
-// current type. but right now disable for less memory cost
-// int bbs_convert_type = CONV_NORMAL;
-
-void set_converting_type(int which)
-{
- if (which == CONV_NORMAL) {
- read_type = read;
- write_type = (read_write_type)write;
- /* for speed up, NULL is better.. */
- input_type = NULL; /* norm_input; */
- }
- else if (which == CONV_GB) {
- read_type = gb_read;
- write_type = gb_write;
- input_type = gb_input;
- }
- else if (which == CONV_UTF8) {
- read_type = utf8_read;
- write_type = utf8_write;
- input_type = utf8_input;
- }
- // bbs_convert_type = which;
-}
-
-#endif
diff --git a/mbbsd/crypt.c b/mbbsd/crypt.c
deleted file mode 100644
index 7283c8a6..00000000
--- a/mbbsd/crypt.c
+++ /dev/null
@@ -1,647 +0,0 @@
-/* $Id */
-/* This file is crypt.c taken from ssh 1.2.33, only modified for compile */
-/**
- * FreeBSD ¤Î Linux glibc ªþªº crypt() ³£·|¥Î¨ì¤j table ¥[³t¦h¦¸ crypt().
- * ¦ý bbs ¶È¤W¯¸Àˬd±K½X®É¨Ï¥Î¤@¦¸, ¤£­È±o¬°¦¹ªá 100kb memory. (non-const memory)
- * libdes ªº crypt() ¶È»Ý 4kb ªº constant lookup table.
- *
- * ¤£¹L­nª`·N libdes 4.01 ªº license ¸ò GPL ¤£¦X, ¦]¦¹¦¹³B±Ä¥Î ssh 1.2.33 ¸ÌÀY
- * ªþªº crypt.c derived from libdes 3.06, ¸Óª©ªº libdes ¬O GPL ªº.
- */
-#define PROTO
-/* This file is fcrypt.c taken from SSLeay-0.4.3a. This file is only compiled
- in on those systems that don't have crypt() in the system libraries.
- //ylo */
-
-/* fcrypt.c */
-/* Copyright (C) 1995 Eric Young (eay@mincom.oz.au).
- * All rights reserved.
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * See the COPYRIGHT file in the libdes distribution for more details.
- */
-
-#include <stdio.h>
-#define _LIBC
-
-/* Eric Young.
- * This version of crypt has been developed from my MIT compatable
- * DES library.
- * The library is available at pub/Crypto/DES at ftp.psy.uq.oz.au
- * eay@mincom.oz.au or eay@psych.psy.uq.oz.au
- */
-
-#if !defined(_LIBC) || defined(NOCONST)
-#define const
-#endif
-
-typedef unsigned char des_cblock[8];
-
-typedef struct des_ks_struct
- {
- union {
- des_cblock _;
- /* make sure things are correct size on machines with
- * 8 byte longs */
- unsigned long pad[2];
- } ks;
-#define _ ks._
- } des_key_schedule[16];
-
-#define DES_KEY_SZ (sizeof(des_cblock))
-#define DES_ENCRYPT 1
-#define DES_DECRYPT 0
-
-#define ITERATIONS 16
-#define HALF_ITERATIONS 8
-
-#define c2l(c,l) (l =((unsigned long)(*((c)++))) , \
- l|=((unsigned long)(*((c)++)))<< 8, \
- l|=((unsigned long)(*((c)++)))<<16, \
- l|=((unsigned long)(*((c)++)))<<24)
-
-#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
- *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
- *((c)++)=(unsigned char)(((l)>>16)&0xff), \
- *((c)++)=(unsigned char)(((l)>>24)&0xff))
-
-static const unsigned long SPtrans[8][64]={
-/* nibble 0 */
-{
-0x00820200, 0x00020000, 0x80800000, 0x80820200,
-0x00800000, 0x80020200, 0x80020000, 0x80800000,
-0x80020200, 0x00820200, 0x00820000, 0x80000200,
-0x80800200, 0x00800000, 0x00000000, 0x80020000,
-0x00020000, 0x80000000, 0x00800200, 0x00020200,
-0x80820200, 0x00820000, 0x80000200, 0x00800200,
-0x80000000, 0x00000200, 0x00020200, 0x80820000,
-0x00000200, 0x80800200, 0x80820000, 0x00000000,
-0x00000000, 0x80820200, 0x00800200, 0x80020000,
-0x00820200, 0x00020000, 0x80000200, 0x00800200,
-0x80820000, 0x00000200, 0x00020200, 0x80800000,
-0x80020200, 0x80000000, 0x80800000, 0x00820000,
-0x80820200, 0x00020200, 0x00820000, 0x80800200,
-0x00800000, 0x80000200, 0x80020000, 0x00000000,
-0x00020000, 0x00800000, 0x80800200, 0x00820200,
-0x80000000, 0x80820000, 0x00000200, 0x80020200,
-},
-/* nibble 1 */
-{
-0x10042004, 0x00000000, 0x00042000, 0x10040000,
-0x10000004, 0x00002004, 0x10002000, 0x00042000,
-0x00002000, 0x10040004, 0x00000004, 0x10002000,
-0x00040004, 0x10042000, 0x10040000, 0x00000004,
-0x00040000, 0x10002004, 0x10040004, 0x00002000,
-0x00042004, 0x10000000, 0x00000000, 0x00040004,
-0x10002004, 0x00042004, 0x10042000, 0x10000004,
-0x10000000, 0x00040000, 0x00002004, 0x10042004,
-0x00040004, 0x10042000, 0x10002000, 0x00042004,
-0x10042004, 0x00040004, 0x10000004, 0x00000000,
-0x10000000, 0x00002004, 0x00040000, 0x10040004,
-0x00002000, 0x10000000, 0x00042004, 0x10002004,
-0x10042000, 0x00002000, 0x00000000, 0x10000004,
-0x00000004, 0x10042004, 0x00042000, 0x10040000,
-0x10040004, 0x00040000, 0x00002004, 0x10002000,
-0x10002004, 0x00000004, 0x10040000, 0x00042000,
-},
-/* nibble 2 */
-{
-0x41000000, 0x01010040, 0x00000040, 0x41000040,
-0x40010000, 0x01000000, 0x41000040, 0x00010040,
-0x01000040, 0x00010000, 0x01010000, 0x40000000,
-0x41010040, 0x40000040, 0x40000000, 0x41010000,
-0x00000000, 0x40010000, 0x01010040, 0x00000040,
-0x40000040, 0x41010040, 0x00010000, 0x41000000,
-0x41010000, 0x01000040, 0x40010040, 0x01010000,
-0x00010040, 0x00000000, 0x01000000, 0x40010040,
-0x01010040, 0x00000040, 0x40000000, 0x00010000,
-0x40000040, 0x40010000, 0x01010000, 0x41000040,
-0x00000000, 0x01010040, 0x00010040, 0x41010000,
-0x40010000, 0x01000000, 0x41010040, 0x40000000,
-0x40010040, 0x41000000, 0x01000000, 0x41010040,
-0x00010000, 0x01000040, 0x41000040, 0x00010040,
-0x01000040, 0x00000000, 0x41010000, 0x40000040,
-0x41000000, 0x40010040, 0x00000040, 0x01010000,
-},
-/* nibble 3 */
-{
-0x00100402, 0x04000400, 0x00000002, 0x04100402,
-0x00000000, 0x04100000, 0x04000402, 0x00100002,
-0x04100400, 0x04000002, 0x04000000, 0x00000402,
-0x04000002, 0x00100402, 0x00100000, 0x04000000,
-0x04100002, 0x00100400, 0x00000400, 0x00000002,
-0x00100400, 0x04000402, 0x04100000, 0x00000400,
-0x00000402, 0x00000000, 0x00100002, 0x04100400,
-0x04000400, 0x04100002, 0x04100402, 0x00100000,
-0x04100002, 0x00000402, 0x00100000, 0x04000002,
-0x00100400, 0x04000400, 0x00000002, 0x04100000,
-0x04000402, 0x00000000, 0x00000400, 0x00100002,
-0x00000000, 0x04100002, 0x04100400, 0x00000400,
-0x04000000, 0x04100402, 0x00100402, 0x00100000,
-0x04100402, 0x00000002, 0x04000400, 0x00100402,
-0x00100002, 0x00100400, 0x04100000, 0x04000402,
-0x00000402, 0x04000000, 0x04000002, 0x04100400,
-},
-/* nibble 4 */
-{
-0x02000000, 0x00004000, 0x00000100, 0x02004108,
-0x02004008, 0x02000100, 0x00004108, 0x02004000,
-0x00004000, 0x00000008, 0x02000008, 0x00004100,
-0x02000108, 0x02004008, 0x02004100, 0x00000000,
-0x00004100, 0x02000000, 0x00004008, 0x00000108,
-0x02000100, 0x00004108, 0x00000000, 0x02000008,
-0x00000008, 0x02000108, 0x02004108, 0x00004008,
-0x02004000, 0x00000100, 0x00000108, 0x02004100,
-0x02004100, 0x02000108, 0x00004008, 0x02004000,
-0x00004000, 0x00000008, 0x02000008, 0x02000100,
-0x02000000, 0x00004100, 0x02004108, 0x00000000,
-0x00004108, 0x02000000, 0x00000100, 0x00004008,
-0x02000108, 0x00000100, 0x00000000, 0x02004108,
-0x02004008, 0x02004100, 0x00000108, 0x00004000,
-0x00004100, 0x02004008, 0x02000100, 0x00000108,
-0x00000008, 0x00004108, 0x02004000, 0x02000008,
-},
-/* nibble 5 */
-{
-0x20000010, 0x00080010, 0x00000000, 0x20080800,
-0x00080010, 0x00000800, 0x20000810, 0x00080000,
-0x00000810, 0x20080810, 0x00080800, 0x20000000,
-0x20000800, 0x20000010, 0x20080000, 0x00080810,
-0x00080000, 0x20000810, 0x20080010, 0x00000000,
-0x00000800, 0x00000010, 0x20080800, 0x20080010,
-0x20080810, 0x20080000, 0x20000000, 0x00000810,
-0x00000010, 0x00080800, 0x00080810, 0x20000800,
-0x00000810, 0x20000000, 0x20000800, 0x00080810,
-0x20080800, 0x00080010, 0x00000000, 0x20000800,
-0x20000000, 0x00000800, 0x20080010, 0x00080000,
-0x00080010, 0x20080810, 0x00080800, 0x00000010,
-0x20080810, 0x00080800, 0x00080000, 0x20000810,
-0x20000010, 0x20080000, 0x00080810, 0x00000000,
-0x00000800, 0x20000010, 0x20000810, 0x20080800,
-0x20080000, 0x00000810, 0x00000010, 0x20080010,
-},
-/* nibble 6 */
-{
-0x00001000, 0x00000080, 0x00400080, 0x00400001,
-0x00401081, 0x00001001, 0x00001080, 0x00000000,
-0x00400000, 0x00400081, 0x00000081, 0x00401000,
-0x00000001, 0x00401080, 0x00401000, 0x00000081,
-0x00400081, 0x00001000, 0x00001001, 0x00401081,
-0x00000000, 0x00400080, 0x00400001, 0x00001080,
-0x00401001, 0x00001081, 0x00401080, 0x00000001,
-0x00001081, 0x00401001, 0x00000080, 0x00400000,
-0x00001081, 0x00401000, 0x00401001, 0x00000081,
-0x00001000, 0x00000080, 0x00400000, 0x00401001,
-0x00400081, 0x00001081, 0x00001080, 0x00000000,
-0x00000080, 0x00400001, 0x00000001, 0x00400080,
-0x00000000, 0x00400081, 0x00400080, 0x00001080,
-0x00000081, 0x00001000, 0x00401081, 0x00400000,
-0x00401080, 0x00000001, 0x00001001, 0x00401081,
-0x00400001, 0x00401080, 0x00401000, 0x00001001,
-},
-/* nibble 7 */
-{
-0x08200020, 0x08208000, 0x00008020, 0x00000000,
-0x08008000, 0x00200020, 0x08200000, 0x08208020,
-0x00000020, 0x08000000, 0x00208000, 0x00008020,
-0x00208020, 0x08008020, 0x08000020, 0x08200000,
-0x00008000, 0x00208020, 0x00200020, 0x08008000,
-0x08208020, 0x08000020, 0x00000000, 0x00208000,
-0x08000000, 0x00200000, 0x08008020, 0x08200020,
-0x00200000, 0x00008000, 0x08208000, 0x00000020,
-0x00200000, 0x00008000, 0x08000020, 0x08208020,
-0x00008020, 0x08000000, 0x00000000, 0x00208000,
-0x08200020, 0x08008020, 0x08008000, 0x00200020,
-0x08208000, 0x00000020, 0x00200020, 0x08008000,
-0x08208020, 0x00200000, 0x08200000, 0x08000020,
-0x00208000, 0x00008020, 0x08008020, 0x08200000,
-0x00000020, 0x08208000, 0x00208020, 0x00000000,
-0x08000000, 0x08200020, 0x00008000, 0x00208020}};
-static const unsigned long skb[8][64]={
-/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
-{
-0x00000000,0x00000010,0x20000000,0x20000010,
-0x00010000,0x00010010,0x20010000,0x20010010,
-0x00000800,0x00000810,0x20000800,0x20000810,
-0x00010800,0x00010810,0x20010800,0x20010810,
-0x00000020,0x00000030,0x20000020,0x20000030,
-0x00010020,0x00010030,0x20010020,0x20010030,
-0x00000820,0x00000830,0x20000820,0x20000830,
-0x00010820,0x00010830,0x20010820,0x20010830,
-0x00080000,0x00080010,0x20080000,0x20080010,
-0x00090000,0x00090010,0x20090000,0x20090010,
-0x00080800,0x00080810,0x20080800,0x20080810,
-0x00090800,0x00090810,0x20090800,0x20090810,
-0x00080020,0x00080030,0x20080020,0x20080030,
-0x00090020,0x00090030,0x20090020,0x20090030,
-0x00080820,0x00080830,0x20080820,0x20080830,
-0x00090820,0x00090830,0x20090820,0x20090830,
-},
-/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
-{
-0x00000000,0x02000000,0x00002000,0x02002000,
-0x00200000,0x02200000,0x00202000,0x02202000,
-0x00000004,0x02000004,0x00002004,0x02002004,
-0x00200004,0x02200004,0x00202004,0x02202004,
-0x00000400,0x02000400,0x00002400,0x02002400,
-0x00200400,0x02200400,0x00202400,0x02202400,
-0x00000404,0x02000404,0x00002404,0x02002404,
-0x00200404,0x02200404,0x00202404,0x02202404,
-0x10000000,0x12000000,0x10002000,0x12002000,
-0x10200000,0x12200000,0x10202000,0x12202000,
-0x10000004,0x12000004,0x10002004,0x12002004,
-0x10200004,0x12200004,0x10202004,0x12202004,
-0x10000400,0x12000400,0x10002400,0x12002400,
-0x10200400,0x12200400,0x10202400,0x12202400,
-0x10000404,0x12000404,0x10002404,0x12002404,
-0x10200404,0x12200404,0x10202404,0x12202404,
-},
-/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
-{
-0x00000000,0x00000001,0x00040000,0x00040001,
-0x01000000,0x01000001,0x01040000,0x01040001,
-0x00000002,0x00000003,0x00040002,0x00040003,
-0x01000002,0x01000003,0x01040002,0x01040003,
-0x00000200,0x00000201,0x00040200,0x00040201,
-0x01000200,0x01000201,0x01040200,0x01040201,
-0x00000202,0x00000203,0x00040202,0x00040203,
-0x01000202,0x01000203,0x01040202,0x01040203,
-0x08000000,0x08000001,0x08040000,0x08040001,
-0x09000000,0x09000001,0x09040000,0x09040001,
-0x08000002,0x08000003,0x08040002,0x08040003,
-0x09000002,0x09000003,0x09040002,0x09040003,
-0x08000200,0x08000201,0x08040200,0x08040201,
-0x09000200,0x09000201,0x09040200,0x09040201,
-0x08000202,0x08000203,0x08040202,0x08040203,
-0x09000202,0x09000203,0x09040202,0x09040203,
-},
-/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
-{
-0x00000000,0x00100000,0x00000100,0x00100100,
-0x00000008,0x00100008,0x00000108,0x00100108,
-0x00001000,0x00101000,0x00001100,0x00101100,
-0x00001008,0x00101008,0x00001108,0x00101108,
-0x04000000,0x04100000,0x04000100,0x04100100,
-0x04000008,0x04100008,0x04000108,0x04100108,
-0x04001000,0x04101000,0x04001100,0x04101100,
-0x04001008,0x04101008,0x04001108,0x04101108,
-0x00020000,0x00120000,0x00020100,0x00120100,
-0x00020008,0x00120008,0x00020108,0x00120108,
-0x00021000,0x00121000,0x00021100,0x00121100,
-0x00021008,0x00121008,0x00021108,0x00121108,
-0x04020000,0x04120000,0x04020100,0x04120100,
-0x04020008,0x04120008,0x04020108,0x04120108,
-0x04021000,0x04121000,0x04021100,0x04121100,
-0x04021008,0x04121008,0x04021108,0x04121108,
-},
-/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
-{
-0x00000000,0x10000000,0x00010000,0x10010000,
-0x00000004,0x10000004,0x00010004,0x10010004,
-0x20000000,0x30000000,0x20010000,0x30010000,
-0x20000004,0x30000004,0x20010004,0x30010004,
-0x00100000,0x10100000,0x00110000,0x10110000,
-0x00100004,0x10100004,0x00110004,0x10110004,
-0x20100000,0x30100000,0x20110000,0x30110000,
-0x20100004,0x30100004,0x20110004,0x30110004,
-0x00001000,0x10001000,0x00011000,0x10011000,
-0x00001004,0x10001004,0x00011004,0x10011004,
-0x20001000,0x30001000,0x20011000,0x30011000,
-0x20001004,0x30001004,0x20011004,0x30011004,
-0x00101000,0x10101000,0x00111000,0x10111000,
-0x00101004,0x10101004,0x00111004,0x10111004,
-0x20101000,0x30101000,0x20111000,0x30111000,
-0x20101004,0x30101004,0x20111004,0x30111004,
-},
-/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
-{
-0x00000000,0x08000000,0x00000008,0x08000008,
-0x00000400,0x08000400,0x00000408,0x08000408,
-0x00020000,0x08020000,0x00020008,0x08020008,
-0x00020400,0x08020400,0x00020408,0x08020408,
-0x00000001,0x08000001,0x00000009,0x08000009,
-0x00000401,0x08000401,0x00000409,0x08000409,
-0x00020001,0x08020001,0x00020009,0x08020009,
-0x00020401,0x08020401,0x00020409,0x08020409,
-0x02000000,0x0A000000,0x02000008,0x0A000008,
-0x02000400,0x0A000400,0x02000408,0x0A000408,
-0x02020000,0x0A020000,0x02020008,0x0A020008,
-0x02020400,0x0A020400,0x02020408,0x0A020408,
-0x02000001,0x0A000001,0x02000009,0x0A000009,
-0x02000401,0x0A000401,0x02000409,0x0A000409,
-0x02020001,0x0A020001,0x02020009,0x0A020009,
-0x02020401,0x0A020401,0x02020409,0x0A020409,
-},
-/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
-{
-0x00000000,0x00000100,0x00080000,0x00080100,
-0x01000000,0x01000100,0x01080000,0x01080100,
-0x00000010,0x00000110,0x00080010,0x00080110,
-0x01000010,0x01000110,0x01080010,0x01080110,
-0x00200000,0x00200100,0x00280000,0x00280100,
-0x01200000,0x01200100,0x01280000,0x01280100,
-0x00200010,0x00200110,0x00280010,0x00280110,
-0x01200010,0x01200110,0x01280010,0x01280110,
-0x00000200,0x00000300,0x00080200,0x00080300,
-0x01000200,0x01000300,0x01080200,0x01080300,
-0x00000210,0x00000310,0x00080210,0x00080310,
-0x01000210,0x01000310,0x01080210,0x01080310,
-0x00200200,0x00200300,0x00280200,0x00280300,
-0x01200200,0x01200300,0x01280200,0x01280300,
-0x00200210,0x00200310,0x00280210,0x00280310,
-0x01200210,0x01200310,0x01280210,0x01280310,
-},
-/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
-{
-0x00000000,0x04000000,0x00040000,0x04040000,
-0x00000002,0x04000002,0x00040002,0x04040002,
-0x00002000,0x04002000,0x00042000,0x04042000,
-0x00002002,0x04002002,0x00042002,0x04042002,
-0x00000020,0x04000020,0x00040020,0x04040020,
-0x00000022,0x04000022,0x00040022,0x04040022,
-0x00002020,0x04002020,0x00042020,0x04042020,
-0x00002022,0x04002022,0x00042022,0x04042022,
-0x00000800,0x04000800,0x00040800,0x04040800,
-0x00000802,0x04000802,0x00040802,0x04040802,
-0x00002800,0x04002800,0x00042800,0x04042800,
-0x00002802,0x04002802,0x00042802,0x04042802,
-0x00000820,0x04000820,0x00040820,0x04040820,
-0x00000822,0x04000822,0x00040822,0x04040822,
-0x00002820,0x04002820,0x00042820,0x04042820,
-0x00002822,0x04002822,0x00042822,0x04042822,
-}
-};
-
-/* See ecb_encrypt.c for a pseudo description of these macros. */
-#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
- (b)^=(t),\
- (a)^=((t)<<(n)))
-
-#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
- (a)=(a)^(t)^(t>>(16-(n))))\
-
-static const char shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
-
-#ifdef PROTO
-static int body(unsigned long *out0, unsigned long *out1, des_key_schedule ks, unsigned long Eswap0, unsigned long Eswap1);
-static int des_set_key(des_cblock (*key), struct des_ks_struct *schedule);
-#else
-static int body();
-static int des_set_key();
-#endif
-
-static int des_set_key(key, schedule)
-des_cblock (*key);
-struct des_ks_struct *schedule;
- {
- register unsigned long c,d,t,s;
- register unsigned char *in;
- register unsigned long *k;
- register int i;
-
- k=(unsigned long *)schedule;
- in=(unsigned char *)key;
-
- c2l(in,c);
- c2l(in,d);
-
- /* I now do it in 47 simple operations :-)
- * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
- * for the inspiration. :-) */
- PERM_OP (d,c,t,4,0x0f0f0f0f);
- HPERM_OP(c,t,-2,0xcccc0000);
- HPERM_OP(d,t,-2,0xcccc0000);
- PERM_OP (d,c,t,1,0x55555555);
- PERM_OP (c,d,t,8,0x00ff00ff);
- PERM_OP (d,c,t,1,0x55555555);
- d= (((d&0x000000ff)<<16)| (d&0x0000ff00) |
- ((d&0x00ff0000)>>16)|((c&0xf0000000)>>4));
- c&=0x0fffffff;
-
- for (i=0; i<ITERATIONS; i++)
- {
- if (shifts2[i])
- { c=((c>>2)|(c<<26)); d=((d>>2)|(d<<26)); }
- else
- { c=((c>>1)|(c<<27)); d=((d>>1)|(d<<27)); }
- c&=0x0fffffff;
- d&=0x0fffffff;
- /* could be a few less shifts but I am to lazy at this
- * point in time to investigate */
- s= skb[0][ (c )&0x3f ]|
- skb[1][((c>> 6)&0x03)|((c>> 7)&0x3c)]|
- skb[2][((c>>13)&0x0f)|((c>>14)&0x30)]|
- skb[3][((c>>20)&0x01)|((c>>21)&0x06) |
- ((c>>22)&0x38)];
- t= skb[4][ (d )&0x3f ]|
- skb[5][((d>> 7)&0x03)|((d>> 8)&0x3c)]|
- skb[6][ (d>>15)&0x3f ]|
- skb[7][((d>>21)&0x0f)|((d>>22)&0x30)];
-
- /* table contained 0213 4657 */
- *(k++)=((t<<16)|(s&0x0000ffff))&0xffffffff;
- s= ((s>>16)|(t&0xffff0000));
-
- s=(s<<4)|(s>>28);
- *(k++)=s&0xffffffff;
- }
- return(0);
- }
-
-/******************************************************************
- * modified stuff for crypt.
- ******************************************************************/
-
-/* The changes to this macro may help or hinder, depending on the
- * compiler and the achitecture. gcc2 always seems to do well :-).
- * Inspired by Dana How <how@isl.stanford.edu>
- * DO NOT use the alternative version on machines with 8 byte longs.
- */
-#ifdef ALT_ECB
-#define D_ENCRYPT(L,R,S) \
- t=(R^(R>>16)); \
- u=(t&E0); \
- t=(t&E1); \
- u=((u^(u<<16))^R^s[S ])<<2; \
- t=(t^(t<<16))^R^s[S+1]; \
- t=(t>>2)|(t<<30); \
- L^= \
- *(unsigned long *)(des_SP+0x0100+((t )&0xfc))+ \
- *(unsigned long *)(des_SP+0x0300+((t>> 8)&0xfc))+ \
- *(unsigned long *)(des_SP+0x0500+((t>>16)&0xfc))+ \
- *(unsigned long *)(des_SP+0x0700+((t>>24)&0xfc))+ \
- *(unsigned long *)(des_SP+ ((u )&0xfc))+ \
- *(unsigned long *)(des_SP+0x0200+((u>> 8)&0xfc))+ \
- *(unsigned long *)(des_SP+0x0400+((u>>16)&0xfc))+ \
- *(unsigned long *)(des_SP+0x0600+((u>>24)&0xfc));
-#else /* original version */
-#define D_ENCRYPT(L,R,S) \
- t=(R^(R>>16)); \
- u=(t&E0); \
- t=(t&E1); \
- u=(u^(u<<16))^R^s[S ]; \
- t=(t^(t<<16))^R^s[S+1]; \
- t=(t>>4)|(t<<28); \
- L^= SPtrans[1][(t )&0x3f]| \
- SPtrans[3][(t>> 8)&0x3f]| \
- SPtrans[5][(t>>16)&0x3f]| \
- SPtrans[7][(t>>24)&0x3f]| \
- SPtrans[0][(u )&0x3f]| \
- SPtrans[2][(u>> 8)&0x3f]| \
- SPtrans[4][(u>>16)&0x3f]| \
- SPtrans[6][(u>>24)&0x3f];
-#endif
-
-static unsigned const char con_salt[128]={
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
-0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
-0x0A,0x0B,0x05,0x06,0x07,0x08,0x09,0x0A,
-0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,
-0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,
-0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,
-0x23,0x24,0x25,0x20,0x21,0x22,0x23,0x24,
-0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,
-0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,
-0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,
-0x3D,0x3E,0x3F,0x00,0x00,0x00,0x00,0x00,
-};
-
-static unsigned const char cov_2char[64]={
-0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,
-0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,
-0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,
-0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,
-0x55,0x56,0x57,0x58,0x59,0x5A,0x61,0x62,
-0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,
-0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72,
-0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A
-};
-
-#ifdef PERL5
-char *des_crypt(buf,salt)
-#else
-char *crypt(buf, salt)
-char *buf;
-char *salt;
-
-
-#endif
-
-
- {
- unsigned int i,j,x,y;
- unsigned long Eswap0=0,Eswap1=0;
- unsigned long out[2],ll;
- des_cblock key;
- des_key_schedule ks;
- static unsigned char buff[20];
- unsigned char bb[9];
- unsigned char *b=bb;
- unsigned char c,u;
-
- /* eay 25/08/92
- * If you call crypt("pwd","*") as often happens when you
- * have * as the pwd field in /etc/passwd, the function
- * returns *\0XXXXXXXXX
- * The \0 makes the string look like * so the pwd "*" would
- * crypt to "*". This was found when replacing the crypt in
- * our shared libraries. People found that the disbled
- * accounts effectivly had no passwd :-(. */
- x=buff[0]=((salt[0] == '\0')?'A':salt[0]);
- Eswap0=con_salt[x];
- x=buff[1]=((salt[1] == '\0')?'A':salt[1]);
- Eswap1=con_salt[x]<<4;
-
- for (i=0; i<8; i++)
- {
- c= *(buf++);
- if (!c) break;
- key[i]=(c<<1);
- }
- for (; i<8; i++)
- key[i]=0;
-
- des_set_key((des_cblock *)(key),ks);
- body(&(out[0]),&(out[1]),ks,Eswap0,Eswap1);
-
- ll=out[0]; l2c(ll,b);
- ll=out[1]; l2c(ll,b);
- y=0;
- u=0x80;
- bb[8]=0;
- for (i=2; i<13; i++)
- {
- c=0;
- for (j=0; j<6; j++)
- {
- c<<=1;
- if (bb[y] & u) c|=1;
- u>>=1;
- if (!u)
- {
- y++;
- u=0x80;
- }
- }
- buff[i]=cov_2char[c];
- }
- buff[13]='\0';
- return((char *)buff);
- }
-
-static int body(out0, out1, ks, Eswap0, Eswap1)
-unsigned long *out0;
-unsigned long *out1;
-des_key_schedule ks;
-unsigned long Eswap0;
-unsigned long Eswap1;
- {
- register unsigned long l,r,t,u;
-#ifdef ALT_ECB
- register unsigned char *des_SP=(unsigned char *)SPtrans;
-#endif
- register unsigned long *s;
- register int i,j;
- register unsigned long E0,E1;
-
- l=0;
- r=0;
-
- s=(unsigned long *)ks;
- E0=Eswap0;
- E1=Eswap1;
-
- for (j=0; j<25; j++)
- {
- for (i=0; i<(ITERATIONS*2); i+=4)
- {
- D_ENCRYPT(l,r, i); /* 1 */
- D_ENCRYPT(r,l, i+2); /* 2 */
- }
- t=l;
- l=r;
- r=t;
- }
- t=r;
- r=(l>>1)|(l<<31);
- l=(t>>1)|(t<<31);
- /* clear the top bits on machines with 8byte longs */
- l&=0xffffffff;
- r&=0xffffffff;
-
- PERM_OP(r,l,t, 1,0x55555555);
- PERM_OP(l,r,t, 8,0x00ff00ff);
- PERM_OP(r,l,t, 2,0x33333333);
- PERM_OP(l,r,t,16,0x0000ffff);
- PERM_OP(r,l,t, 4,0x0f0f0f0f);
-
- *out0=l;
- *out1=r;
- return(0);
- }
-
diff --git a/mbbsd/dark.c b/mbbsd/dark.c
deleted file mode 100644
index f19184dc..00000000
--- a/mbbsd/dark.c
+++ /dev/null
@@ -1,565 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-#define RED 1
-#define BLACK 0
-typedef short int sint;
-
-typedef struct item {
- short int color, value, die, out;
-} item;
-
-typedef struct cur {
- short int y, x, end;
-} cur;
-
-struct DarkData {
- item brd[4][8];
- cur curr;
- sint rcount, bcount, cont, fix; /* cont:¬O§_¥i³s¦Y */
- sint my, mx, mly, mlx; /* ²¾°Êªº®y¼Ð ¼Ð */
-
- sint cur_eaty, cur_eatx; /* ¦Y±¼¹ï¤è¨ä¤lªº¨q¥X®y¼Ð */
-};
-
-static char * const rname[] = {"§L", "¬¶", "ØX", "¨®", "¬Û", "¥K", "«Ó"};
-static char * const bname[] = {"¨ò", "¥]", "°¨", "¨®", "¶H", "¤h", "±N"};
-
-static const sint cury[] = {3, 5, 7, 9}, curx[] = {5, 9, 13, 17, 21, 25, 29, 33};
-
-static void
-brdswap(struct DarkData *dd, sint y, sint x, sint ly, sint lx)
-{
- memcpy(&dd->brd[y][x], &dd->brd[ly][lx], sizeof(item));
- dd->brd[ly][lx].die = 1;
- dd->brd[ly][lx].color = -1; /* ¨S³o­Ócolor */
- dd->brd[ly][lx].value = -1;
-}
-
-static sint
-Is_win(struct DarkData *dd, item att, item det, sint y, sint x, sint ly, sint lx)
-{
- sint i, c = 0, min, max;
- if (att.value == 1) { /* ¯¥ */
- if (y != ly && x != lx)
- return 0;
- if ((abs(ly - y) == 1 && dd->brd[y][x].die == 0) ||
- (abs(lx - x) == 1 && dd->brd[y][x].die == 0))
- return 0;
- if (y == ly) {
- if (x > lx) {
- max = x;
- min = lx;
- } else {
- max = lx;
- min = x;
- }
- for (i = min + 1; i < max; i++)
- if (dd->brd[y][i].die == 0)
- c++;
- } else if (x == lx) {
- if (y > ly) {
- max = y;
- min = ly;
- } else {
- max = ly;
- min = y;
- }
- for (i = min + 1; i < max; i++)
- if (dd->brd[i][x].die == 0)
- c++;
- }
- if (c != 1)
- return 0;
- if (det.die == 1)
- return 0;
- return 1;
- }
- /* «D¯¥ */
- if (((abs(ly - y) == 1 && x == lx) || (abs(lx - x) == 1 && ly == y)) && dd->brd[y][x].out == 1) {
- if (att.value == 0 && det.value == 6)
- return 1;
- else if (att.value == 6 && det.value == 0)
- return 0;
- else if (att.value >= det.value)
- return 1;
- else
- return 0;
- }
- return 0;
-}
-
-static sint
-Is_move(struct DarkData *dd, sint y, sint x, sint ly, sint lx)
-{
- if (dd->brd[y][x].die == 1 && ((abs(ly - y) == 1 && x == lx) || (abs(lx - x) == 1 && ly == y)))
- return 1;
- return 0;
-}
-
-static void
-brd_rand(struct DarkData *dd)
-{
- sint y, x, index;
- sint tem[32];
- sint value[32] = {
- 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6,
- 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6
- };
-
- bzero(dd->brd, sizeof(dd->brd));
- bzero(tem, sizeof(tem));
- bzero(&dd->curr, sizeof(dd->curr));
- for (y = 0; y < 4; y++)
- for (x = 0; x < 8; x++)
- while (1) {
- index = random() % 32;
- if (tem[index])
- continue;
- dd->brd[y][x].color = (index > 15) ? 0 : 1;
- dd->brd[y][x].value = value[index];
- tem[index] = 1;
- break;
- }
-}
-
-static void
-brd_prints(void)
-{
- clear();
- move(1, 0);
- outs("\n"
- " " ANSI_COLOR(43;30) "¢~¢w¢s¢w¢s¢w¢s¢w¢s¢w¢s¢w¢s¢w¢s¢w¢¡" ANSI_RESET "\n"
- " " ANSI_COLOR(43;30) "¢x¡´¢x¡´¢x¡´¢x¡´¢x¡´¢x¡´¢x¡´¢x¡´¢x" ANSI_RESET "\n"
- " " ANSI_COLOR(43;30) "¢u¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢t" ANSI_RESET "\n"
- " " ANSI_COLOR(43;30) "¢x¡´¢x¡´¢x¡´¢x¡´¢x¡´¢x¡´¢x¡´¢x¡´¢x" ANSI_RESET "\n"
- " " ANSI_COLOR(43;30) "¢u¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢t" ANSI_RESET "\n"
- " " ANSI_COLOR(43;30) "¢x¡´¢x¡´¢x¡´¢x¡´¢x¡´¢x¡´¢x¡´¢x¡´¢x" ANSI_RESET "\n"
- " " ANSI_COLOR(43;30) "¢u¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢t" ANSI_RESET "\n"
- " " ANSI_COLOR(43;30) "¢x¡´¢x¡´¢x¡´¢x¡´¢x¡´¢x¡´¢x¡´¢x¡´¢x" ANSI_RESET "\n"
- " " ANSI_COLOR(43;30) "¢¢¢w¢r¢w¢r¢w¢r¢w¢r¢w¢r¢w¢r¢w¢r¢w¢£" ANSI_RESET "\n"
- " ");
-}
-
-static void
-draw_line(struct DarkData *dd, sint y, sint f)
-{
- sint i;
- char buf[1024], tmp[256];
-
- *buf = 0;
- *tmp = 0;
- strlcpy(buf, ANSI_COLOR(43;30), sizeof(buf));
- for (i = 0; i < 8; i++) {
- if (dd->brd[y][i].die == 1)
- snprintf(tmp, sizeof(tmp), "¢x ");
- else if (dd->brd[y][i].out == 0)
- snprintf(tmp, sizeof(tmp), "¢x¡´");
- else {
- snprintf(tmp, sizeof(tmp), "¢x" ANSI_COLOR(%s1;%d) "%s" ANSI_RESET ANSI_COLOR(43;30) "",
- (f == i) ? "1;47;" : "", (dd->brd[y][i].color) ? 31 : 34,
- (dd->brd[y][i].color) ? rname[dd->brd[y][i].value] :
- bname[dd->brd[y][i].value]);
- }
- strcat(buf, tmp);
- }
- strcat(buf, "¢x" ANSI_RESET);
-
- move(cury[y], 3);
- clrtoeol();
- outs(buf);
-}
-
-static void
-redraw(struct DarkData *dd)
-{
- sint i = 0;
- for (; i < 4; i++)
- draw_line(dd, i, -1);
-}
-
-static sint
-playing(struct DarkData *dd, sint fd, sint color, sint ch, sint * b, userinfo_t * uin)
-{
- dd->curr.end = 0;
- move(cury[dd->my], curx[dd->mx]);
-
- if (dd->fix) {
- if (ch == 's') {
- dd->fix = 0;
- *b = 0;
- return 0;
- } else {
- draw_line(dd, dd->mly, -1);
- }
- }
- switch (ch) {
- case KEY_LEFT:
- if (dd->mx == 0)
- dd->mx = 7;
- else
- dd->mx--;
- move(cury[dd->my], curx[dd->mx]);
- *b = -1;
- break;
- case KEY_RIGHT:
- if (dd->mx == 7)
- dd->mx = 0;
- else
- dd->mx++;
- move(cury[dd->my], curx[dd->mx]);
- *b = -1;
- break;
- case KEY_UP:
- if (dd->my == 0)
- dd->my = 3;
- else
- dd->my--;
- move(cury[dd->my], curx[dd->mx]);
- *b = -1;
- break;
- case KEY_DOWN:
- if (dd->my == 3)
- dd->my = 0;
- else
- dd->my++;
- move(cury[dd->my], curx[dd->mx]);
- *b = -1;
- break;
- case 'q':
- case 'Q':
- if (!color)
- dd->bcount = 0;
- else
- dd->rcount = 0;
- *b = 0;
- return -2;
- case 'p':
- case 'P':
- return -3;
- case 'c':
- return -4;
- case 'g':
- return -5;
- case 's': /* ½¶}´Ñ¤l ©Î¬O¿ï¾Ü´Ñ¤l */
- /* ¿ï¾Ü´Ñ¤l */
- if (dd->brd[dd->my][dd->mx].out == 1) {
- if (dd->brd[dd->my][dd->mx].color != color) {
- *b = -1;
- break;
- }
- if (dd->mly < 0) { /* ¥i¥H¿ï¾Ü */
- dd->mly = dd->my;
- dd->mlx = dd->mx;
- draw_line(dd, dd->my, dd->mx);
- *b = -1;
- break;
- } else if (dd->mly == dd->my && dd->mlx == dd->mx) { /* ¤£¿ï¤F */
- dd->mly = -1;
- dd->mlx = -1;
- draw_line(dd, dd->my, -1);
- } else {
- draw_line(dd, dd->mly, -1);
- dd->mly = dd->my;
- dd->mlx = dd->mx;
- if (dd->brd[dd->mly][dd->mlx].value == 1)
- dd->fix = 1;
- draw_line(dd, dd->my, dd->mx);
- }
- *b = -1;
- break;
- }
- /* ½¶}´Ñ¤l */
- if (dd->mly >= 0) {
- *b = -1;
- break;
- } /* ¥»¨Ó´N¬O½¶}ªº */
- /* ¨M©w¤@¶}©lªºÃC¦â */
- if (currutmp->color == '.') {
- if (uin->color != '1' && uin->color != '0')
- currutmp->color = (dd->brd[dd->my][dd->mx].color) ? '1' : '0';
- else
- currutmp->color = (uin->color == '0') ? '1' : '0';
- }
- dd->brd[dd->my][dd->mx].out = 1;
- draw_line(dd, dd->my, -1);
- move(cury[dd->my], curx[dd->mx]);
- *b = 0;
- break;
- case 'u':
- move(0, 0);
- clrtoeol();
- prints("%s¦â%s cont=%d",
- (dd->brd[dd->my][dd->mx].color == RED) ? "¬õ" : "¶Â",
- rname[dd->brd[dd->my][dd->mx].value], dd->cont);
- *b = -1;
- break;
- case '\r': /* ¦Y or ²¾°Ê ly¸òlx¥²¶·¤j©ó0 */
- case '\n':
- if (
- dd->mly >= 0 /* ­n¥ý¿ï¤l */
- &&
- dd->brd[dd->mly][dd->mlx].color != dd->brd[dd->my][dd->mx].color /* ¦P¦â¤£¯à²¾°Ê¤]¤£¯à¦Y */
- &&
- (Is_move(dd, dd->my, dd->mx, dd->mly, dd->mlx) ||
- Is_win(dd, dd->brd[dd->mly][dd->mlx], dd->brd[dd->my][dd->mx], dd->my, dd->mx, dd->mly, dd->mlx))
- ) {
- if (dd->fix && dd->brd[dd->my][dd->mx].value < 0) {
- *b = -1;
- return 0;
- }
- if (dd->brd[dd->my][dd->mx].value >= 0 && dd->brd[dd->my][dd->mx].die == 0) {
- if (!color)
- dd->bcount--;
- else
- dd->rcount--;
- move(dd->cur_eaty, dd->cur_eatx);
- if(color)
- outs(bname[dd->brd[dd->my][dd->mx].value]);
- else
- outs(rname[dd->brd[dd->my][dd->mx].value]);
- if (dd->cur_eatx >= 26) {
- dd->cur_eatx = 5;
- dd->cur_eaty++;
- } else
- dd->cur_eatx += 3;
- }
- brdswap(dd, dd->my, dd->mx, dd->mly, dd->mlx);
- draw_line(dd, dd->mly, -1);
- draw_line(dd, dd->my, -1);
- if (dd->fix == 1)
- *b = -1;
- else {
- dd->mly = -1;
- dd->mlx = -1;
- *b = 0;
- }
- } else
- *b = -1;
- break;
- default:
- *b = -1;
- }
-
- if (!dd->rcount)
- return -1;
- else if (!dd->bcount)
- return -1;
- if (*b == -1)
- return 0;
- dd->curr.y = dd->my;
- dd->curr.x = dd->mx;
- dd->curr.end = (!*b) ? 1 : 0;
- send(fd, &dd->curr, sizeof(dd->curr), 0);
- send(fd, &dd->brd, sizeof(dd->brd), 0);
- return 0;
-}
-
-int
-main_dark(int fd, userinfo_t * uin)
-{
- sint end = 0, ch = 1, i = 0;
- char buf[16];
- struct DarkData dd;
-
- memset(&dd, 0, sizeof(dd));
- dd.my=dd.mx=0;
- dd.mly=dd.mlx=-1;
-
- *buf = 0;
- dd.fix = 0;
- currutmp->color = '.';
- /* '.' ªí¥ÜÁÙ¨S¨M©wÃC¦â */
- dd.rcount = 16;
- dd.bcount = 16;
- //initialize
- dd.cur_eaty = 18, dd.cur_eatx = 5;
- setutmpmode(DARK);
- brd_prints();
- if (currutmp->turn) {
- brd_rand(&dd);
- send(fd, &dd.brd, sizeof(dd.brd), 0);
- mouts(21, 0, " " ANSI_COLOR(1;37) ANSI_COLOR(1;33) "¡»" ANSI_COLOR(1;37) "§A¬O¥ý¤â" ANSI_RESET);
- mouts(22, 0, " " ANSI_COLOR(1;33) "¡»" ANSI_COLOR(5;35) "½ü¨ì§A¤U¤F" ANSI_RESET);
- } else {
- recv(fd, &dd.brd, sizeof(dd.brd), 0);
- mouts(21, 0, " " ANSI_COLOR(1;33) "¡»" ANSI_COLOR(1;37) "§A¬O«á¤â" ANSI_RESET);
- }
- move(12, 3);
- prints("%s[0³Ó0±Ñ]" ANSI_COLOR(5;31) "¢þ¢û" ANSI_COLOR(1;37) "." ANSI_RESET "%s[0³Ó0±Ñ]", currutmp->userid, currutmp->mateid);
- outs("\n"
- " " ANSI_COLOR(1;36) "¢®¢¬" ANSI_COLOR(1;31) "¥\\¯àªí" ANSI_COLOR(1;36) "¢­¢®¢­¢¬¢®¢­" ANSI_RESET "\n"
- " " ANSI_COLOR(1;36) "¢¬" ANSI_COLOR(1;33) " ¡ô¡ö¡õ¡÷" ANSI_COLOR(1;37) ": " ANSI_COLOR(1;35) "²¾°Ê" ANSI_RESET "\n"
- " " ANSI_COLOR(1;36) "¢®" ANSI_COLOR(1;33) " ¢û" ANSI_COLOR(1;37) ": " ANSI_COLOR(1;35) " ¿ï¤l,½¤l" ANSI_RESET "\n"
- " " ANSI_COLOR(1;36) "¢¬" ANSI_COLOR(1;33) " enter" ANSI_COLOR(1;37) ": " ANSI_COLOR(1;35) " ¦Y´Ñ,©ñ´Ñ" ANSI_RESET "\n"
- "¡@" ANSI_COLOR(1;33) "¤w¸g¸Ñ¨Mªº" ANSI_COLOR(1;37) ":" ANSI_COLOR(1;36) "¡@¡@ ¢®" ANSI_COLOR(1;33) " ¢ø" ANSI_COLOR(1;37) ": " ANSI_COLOR(1;35) " ¦X´Ñ" ANSI_RESET "\n"
- " ¡@¡@ " ANSI_COLOR(1;36) "¢¬" ANSI_COLOR(1;33) " ¢ù" ANSI_COLOR(1;37) ": " ANSI_COLOR(1;35) " »{¿é" ANSI_RESET "\n"
- " " ANSI_COLOR(1;36) "¢®" ANSI_COLOR(1;33) " ¢ë" ANSI_COLOR(1;37) ": " ANSI_COLOR(1;35) " ´«Ãä" ANSI_RESET);
-
- if (currutmp->turn)
- move(cury[0], curx[0]);
-
- add_io(fd, 0);
- while (end <= 0) {
- if (uin->turn == 'w' || currutmp->turn == 'w') {
- end = -1;
- break;
- }
- ch = igetch();
- if (ch == I_OTHERDATA) {
- ch = recv(fd, &dd.curr, sizeof(dd.curr), 0);
- if (ch != sizeof(dd.curr)) {
- if (uin->turn == 'e') {
- end = -3;
- break;
- } else if (uin->turn != 'w') {
- end = -1;
- currutmp->turn = 'w';
- break;
- }
- end = -1;
- break;
- }
- if (dd.curr.end == -3)
- mouts(23, 30, ANSI_COLOR(33) "­n¨D¦X´Ñ" ANSI_RESET);
- else if (dd.curr.end == -4)
- mouts(23, 30, ANSI_COLOR(33) "­n¨D´«Ãä" ANSI_RESET);
- else if (dd.curr.end == -5)
- mouts(23, 30, ANSI_COLOR(33) "­n¨D³s¦Y" ANSI_RESET);
- else
- mouts(23, 30, "");
-
- recv(fd, &dd.brd, sizeof(dd.brd), 0);
- dd.my = dd.curr.y;
- dd.mx = dd.curr.x;
- redraw(&dd);
- if (dd.curr.end)
- mouts(22, 0, " " ANSI_COLOR(1;33) "¡»" ANSI_COLOR(5;35) "½ü¨ì§A¤U¤F" ANSI_RESET);
- move(cury[dd.my], curx[dd.mx]);
- } else {
- if (currutmp->turn == 'p') {
- if (ch == 'y') {
- end = -3;
- currutmp->turn = 'e';
- break;
- } else {
- mouts(23, 30, "");
- *buf = 0;
- currutmp->turn = (uin->turn) ? 0 : 1;
- }
- } else if (currutmp->turn == 'c') {
- if (ch == 'y') {
- currutmp->color = (currutmp->color == '1') ? '0' : '1';
- uin->color = (uin->color == '1') ? '0' : '1';
- mouts(21, 0, (currutmp->color == '1') ? " " ANSI_COLOR(1;33) "¡»" ANSI_COLOR(1;31) "§A«ù¬õ¦â´Ñ" ANSI_RESET : " " ANSI_COLOR(1;33) "¡»" ANSI_COLOR(1;36) "§A«ù¶Â¦â´Ñ" ANSI_RESET);
- } else {
- mouts(23, 30, "");
- currutmp->turn = (uin->turn) ? 0 : 1;
- }
- } else if (currutmp->turn == 'g') {
- if (ch == 'y') {
- dd.cont = 1;
- mouts(21, 0, " " ANSI_COLOR(1;33) "¡»" ANSI_COLOR(1;31) "§A«ù¬õ¦â´Ñ" ANSI_RESET " ¥i³s¦Y");
- } else {
- mouts(23, 30, "");
- currutmp->turn = (uin->turn) ? 0 : 1;
- }
- }
- if (currutmp->turn == 1) {
- sint go_on = 0;
- if (uin->turn == 'g') {
- dd.cont = 1;
- uin->turn = (currutmp->turn) ? 0 : 1;
- mouts(21, 10, "¥i³s¦Y");
- }
- end = playing(&dd, fd, currutmp->color - '0', ch, &go_on, uin);
-
- if (end == -1) {
- currutmp->turn = 'w';
- break;
- } else if (end == -2) {
- uin->turn = 'w';
- break;
- } else if (end == -3) {
- uin->turn = 'p';
- dd.curr.end = -3;
- send(fd, &dd.curr, sizeof(dd.curr), 0);
- send(fd, &dd.brd, sizeof(buf), 0);
- continue;
- } else if (end == -4) {
- if (currutmp->color != '1' && currutmp->color != '0')
- continue;
- uin->turn = 'c';
- i = 0;
- dd.curr.end = -4;
- send(fd, &dd.curr, sizeof(dd.curr), 0);
- send(fd, &dd.brd, sizeof(buf), 0);
- continue;
- } else if (end == -5) {
- uin->turn = 'g';
- dd.curr.end = -5;
- send(fd, &dd.curr, sizeof(dd.curr), 0);
- send(fd, &dd.brd, sizeof(buf), 0);
- continue;
- }
- if (!i && currutmp->color == '1') {
- mouts(21, 0, " " ANSI_COLOR(1;33) "¡»" ANSI_COLOR(1;31) "§A«ù¬õ¦â´Ñ" ANSI_RESET);
- i++;
- move(cury[dd.my], curx[dd.mx]);
- }
- if (!i && currutmp->color == '0') {
- mouts(21, 0, " " ANSI_COLOR(1;33) "¡»" ANSI_COLOR(1;36) "§A«ù¶Â¦â´Ñ" ANSI_RESET);
- i++;
- move(cury[dd.my], curx[dd.mx]);
- }
- if (uin->turn == 'e') {
- end = -3;
- break;
- }
- if (go_on < 0)
- continue;
-
- move(22, 0);
- clrtoeol();
- prints(" " ANSI_COLOR(1;33) "¡»" ANSI_COLOR(1;37) "½ü¨ì%s¤U §O©È§O©È ¥LºâÔ£¦Ì" ANSI_RESET, currutmp->mateid);
- currutmp->turn = 0;
- uin->turn = 1;
- } else {
- if (ch == 'q') {
- uin->turn = 'w';
- break;
- }
- move(22, 0);
- clrtoeol();
- prints(" " ANSI_COLOR(1;33) "¡»" ANSI_COLOR(1;37) "½ü¨ì%s¤U §O©È§O©È ¥LºâÔ£¦Ì" ANSI_RESET, currutmp->mateid);
- }
- }
- }
-
- switch (end) {
- case -1:
- case -2:
- if (currutmp->turn == 'w') {
- move(22, 0);
- clrtoeol();
- outs(ANSI_COLOR(1;31) "§AŤF.. ¯u¬O®¥³ß~~" ANSI_RESET);
- } else {
- move(22, 0);
- clrtoeol();
- outs(ANSI_COLOR(1;31) "¿é±¼¤F°Õ.....¤U¦¸Åý¥L¦n¬Ý!!" ANSI_RESET);
- }
- break;
- case -3:
- mouts(22, 0, ANSI_COLOR(1;31) "¦X´Ñ­ò!! ¤U¦¸¦b¤À°ª¤U§a ^_^" ANSI_RESET);
- break;
- default:
- add_io(0, 0);
- close(fd);
- pressanykey();
- return 0;
- }
- add_io(0, 0);
- close(fd);
- pressanykey();
- return 0;
-}
diff --git a/mbbsd/edit.c b/mbbsd/edit.c
deleted file mode 100644
index c6b3a544..00000000
--- a/mbbsd/edit.c
+++ /dev/null
@@ -1,3886 +0,0 @@
-/* $Id$ */
-/**
- * edit.c, ¥Î¨Ó´£¨Ñ bbs¤Wªº¤å¦r½s¿è¾¹, §Y ve.
- * ²{¦b³o¤@­Ó¬O´c·d¹Lªºª©¥», ¤ñ¸û¤£Ã­©w, ¥Î¤ñ¸û¦hªº cpu, ¦ý¬O¥i¥H¬Ù¤U³\¦h
- * ªº°O¾ÐÅé (¥H Ptt¬°¨Ò, ¦b¤E¤d¤H¤W¯¸ªº®É­Ô, ¬ù¥i¬Ù¤U 50MB ªº°O¾ÐÅé)
- * ¦pªG±z»{¬°¡u®³ cpu´«°O¾ÐÅé¡v¨Ã¤£¦X¥G±zªº¶·¨D, ±z¥i¥H¦Ò¼{§ï¨Ï¥Î­×¥¿«eªº
- * ª©¥» (Revision 782)
- *
- * ­ì¥» ve ªº°µªk¬O, ¦]¬°¨C¤@¦æ³Ì¤j¥i¥H¿é¤J WRAPMARGIN ­Ó¦r, ©ó¬O´N´À¨C¤@
- * ¦æ«O¯d¤F WRAPMARGIN ³o»ò¤jªºªÅ¶¡ (¬ù 512 bytes) . ¦ý¬O¹ê»Ú¤W, ¯¸¦b­×¥¿
- * ¦¨¥»³Ì¤pªº¦Ò¶q¤W, §Ú­Ì¥u¶·­n¨Ï±o´å¼Ð©Ò¦b³o¤@¦æºû«ù WRAPMARGIN ³o»ò¤j,
- * ¨ä¥L¨C¤@¦æ¨ä¹ê¤£¶·­n³o»ò¦hªºªÅ¶¡. ©ó¬O³o­Ó patch´N¦b¨C¦¸´å¼Ð¦b¦æ¶¡²¾°Ê
- * ªº®É­Ô, ±N­ì¥»ªº¨º¦æ°O¾ÐÅéÁY¤p, ¦A±N·s²¾¨ìªº¨º¦æ­«·s¥[¤j, ¥H¹F¦¨³Ì¤pªº
- * °O¾ÐÅé¥Î¶q.
- * ¥H¤W»¡ªº³o­Ó°Ê§@¦b adjustline() ¤¤§¹¦¨, adjustline()¥t¥~¥]¬A­×¥¿¼Æ­Ó
- * global pointer, ¥HÁקK dangling pointer .
- * ¥t¥~­Y©w¸q DEBUG, ¦b textline_t µ²ºc¤¤±N¥[¤J mlength, ªí¥Ü¸Ó¦æ¹ê»Ú¦ûªº
- * °O¾ÐÅé¤j¤p. ¥H¤è«K´ú¸Õµ²ªG.
- * ³o­Óª©¥»¦ü¥GÁÙ¦³¦a¤è¨S¦³­×¥¿¦n, ¥i¯à¾É­P segmentation fault .
- *
- * FIXME ¦b°Ï¶ô¼Ð°O¼Ò¦¡(blockln>=0)¤¤¹ï¼W§R­×§ï¥i¯à·|³y¦¨ blockln, blockpnt,
- * and/or blockline ¿ù»~. ¬Æ¦Ü§â blockline ¬å±¼·| access ¨ì¤w³Q free ±¼ªº
- * memory. ¥i¯à­n§ï¦¨¼Ð°O¼Ò¦¡ readonly, ©Î¬O°µ¬Y¨Ç°Ê§@®É¦Û°Ê¨ú®ø¼Ð°O¼Ò¦¡
- * (blockln=-1)
- *
- * FIXME 20071201 piaip
- * block selection ¤£ª¾¦ó®É¤wÅܬ° line level ¦Ó«D character level ¤F¡A
- * ³o¼Ë¤]¤ñ¸û¦n¼g¡A©Ò¥H§â blockpnt ®³±¼§a¡I
- *
- * 20071230 piaip
- * BBSmovie ¦³¤H§@¥X¤F 1.9G ªºÀÉ®×, ¬Ý¨Ó­n¤À hard limit ¸ò soft limit
- * [²Ä 7426572/7426572 ­¶ (100%) ¥Ø«eÅã¥Ü: ²Ä 163384551~163384573 ¦æ]
- * ·í¤é½Õ¬d BBSmovie ¬ÝªO»PºëµØ°Ï¡A¥­§¡Àɮ׬Ҧb 5M ¥H¤U
- * ³Ì¤jªº¬° 16M ªº Haruhi OP (avi ÂàÀÉ with massive ANSI)
- * [²Ä 2953/2953 ­¶ (100%) ¥Ø«eÅã¥Ü: ²Ä 64942~64964 ¦æ]
- * ¥t¥~¤¬°Ê°g®cªº¤j¤p¬°
- * [²Ä 1408/1408 ­¶ (100%) ¥Ø«eÅã¥Ü: ²Ä 30940~30962 ¦æ]
- * ¬O¥H©w¸q:
- * 32M ¬° size limit
- * 1M ¬° line limit
- * ¤S¡A©¿µMµo²{¤§«e totaln ¤§Ãþ³£¬O short... ©Ò¥H 65536 ´N°÷¤F?
- * «áµù: ¦ü¥G¬O¥Î announce ªº append §@¥X¨Óªº¡A¦³¬Ý¨ì > --- <- mark¡C
- */
-#include "bbs.h"
-
-#define EDIT_SIZE_LIMIT (32768*1024)
-#define EDIT_LINE_LIMIT (65530) // (1048576)
-
-#if 0
-#define register
-#define DEBUG
-#define inline
-#endif
-
-/**
- * data Äæ¦ìªº¥Îªk:
- * ¨C¦¸ allocate ¤@­Ó textline_t ®É¡A·|°tµ¹¥L (sizeof(textline_t) + string
- * length - 1) ªº¤j¤p¡C¦p¦¹¥iª½±µ¦s¨ú data ¦Ó¤£»ÝÃB¥~ªº malloc¡C
- */
-typedef struct textline_t {
- struct textline_t *prev;
- struct textline_t *next;
- short len;
-#ifdef DEBUG
- short mlength;
-#endif
- char data[1];
-} textline_t;
-
-#define KEEP_EDITING -2
-
-enum {
- NOBODY, MANAGER, SYSOP
-};
-
-
-/**
- * ³o­Ó»¡©ú·|±N¾ã­Ó edit.c ¹B§@ªº·§©À±a¹L¡A¥D­n·|±q editor_internal_t ªº
- * data structure ½Í°_¡C¹ï©ó¨C¤@­Ó data member ªº¸Ô²Ó¥\¯à¡A½Ð¨£ sturcture
- * ¤¤ªºµù¸Ñ¡C
- *
- * ¤å³¹ªº¤º®e (¥H¤UºÙ content) ¥H¡u¦æ¡v¬°³æ¦ì¡A¥D­n¥H firstline, lastline,
- * totaln ¨Ó°O¿ý¡C
- *
- * User ¦bµe­±¤¤¬Ý¨ìªºµe­±¡A¸m©ó¤@­Ó¡u window ¡v¤¤¡A³o­Ó window ·|¦b
- * content ¤W²¾°Ê¡Awindow ¸Ì­±ªº½d³ò§Y¬°­n show ¥X¨Óªº½d³ò¡C¥¦¥Î¤F¤£¤Ö
- * Äæ¦ì¨Ó°O¿ý¡A¥]¬A currline, top_of_win, currln, currpnt, curr_window_line,
- * edit_margin¡CÅã¥Ü¥X¨Óªº®ÄªG·íµM¤£¥u¬O¾a³o´X­Ó¸ê®Æ¡AÁÙ·|¸ò¨ä¥LÄæ¦ì¦³¥æ¤¬
- * §@¥Î¡A¨Ò¦p ±m¦â½s¿è¼Ò¦¡¡B¯S®í²Å¸¹½s¿è µ¥µ¥¡C¨ä¤¤³Ì½ÆÂøªº³¡¤À¬O¦b¿ï¨ú block
- * ¡]¨£«á¡^ªº®É­Ô¡C¤ñ¸û¤£ª½Ä±ªº¦æ¬°¬O¡G°£«D´å¼Ð¦b¶}©l¿ï¨ú¸ò¥Ø«e¡]µ²§ô¡^ªº¦ì¸m
- * ¬O¦P¤@­Ó¡]¦¹®É³o­Ó½d³ò¬O¿ï¨úªº½d³ò¡^¡A§_«h´N¬O±q¶}©l¨º¤@¦C¤@ª½¨ì¥Ø«e¡]µ²§ô¡^
- * ³o¤@¦C¡C
- *
- * editor ªº¨Ï¥Î¤W¥Ø«e¦³¤­ºØ inclusive ªº mode¡G
- * insert mode:
- * ´¡¤J/¨ú¥N
- * ansi mode:
- * ±m¦â½s¿è
- * indent mode:
- * ¦Û°ÊÁY±Æ
- * phone mode:
- * ¯S®í²Å¸¹½s¿è
- * raw mode:
- * ignore Ctrl('S'), Ctrl('Q'), Ctrl('T')
- * ÃÙ¤ê: ³o¦³¤°»ò¥Î? ¬Ý°_¨Ó¬O modem ¤W¶Ç¥Î (¨S¤H¦b¥Î³o­Ó¤F§a)
- * ®³¨Ó·í dbcs option §a
- *
- * editor ¤ä´©¤F°Ï¶ô¿ï¾Üªº¥\¯à¡]¦h¦æ¿ï¨ú ©Î ³æ¦æ¤¤ªº¤ù¬q¡^¡A¹ï©ó¤@­Ó selected
- * block¡A¥i¥H cut, copy, cancel, ©ÎªÌ¦s¨ì¼È¨úÀÉ¡A¬Æ¦Ü¬O©¹¥ª/¥k shift¡C¸Ô¨£
- * block_XXX¡C
- *
- * ¥Î Ctrl('Y') §R°£ªº¨º¤@¦æ·|³Q°O¨ì deleted_line ³o­ÓÄæ¦ì¤¤¡Cundelete_line()
- * ¥i¥H°µ undelete ªº°Ê§@¡C deleted_line ªì©l­È¬° NULL¡A¨C¦¸¥u¤¹³\¦s¤@¦æ¡A©Ò¥H
- * ¦b¦s¤U¨Ó®É¡Aµo²{­È¤£¬° NULL ·|¥ý°µ free ªº°Ê§@¡Ceditor µ²§ô®É¡A¦b
- * edit_buffer_destructor() ¤¤¦pªGµo²{¦³ deleted_line¡A·|¦b³oÃäÄÀ©ñ±¼¡C¨ä¥L¦a
- * ¤è¤]¦³¬Û¦Pªº§@ªk¡A¨Ò¦p searched_string¡Csearched_string ¬O¦b·j´M¤å³¹¤º®e
- * ®É¡A­n´M§äªº key word¡C
- *
- * ÁÙ¦³¤@­Ó¦³½ìªº¯SÂI¡A¡u¬A¸¹¤Ç°t¡v¡I¦æ¬°´N¦p¦P¦b vim ¸Ì­±¤@¼Ë¡C§c¡A·íµM¨S¨º
- * »ò±j°Õ¡A¦ý¦Ü¤Ö¦b§t¦³ c-style comment ¸ò c-style string ®É¬O¹ïªº³á¡C³o­Ó°Ê
- * §@©w¸q©ó match_paren() ¤¤¡C
- *
- * ¥t¥~¡A¦pªG¦³»Ý­n·s¼W·sªºÄæ¦ì¡A½Ð±Nªì©l¤Æ¡]¦³»Ý­nªº¸Ü¡^ªº°Ê§@¼g¦b
- * edit_buffer_constructor ¤¤¡C·íµM¤]¦³­Ó edit_buffer_destructor ¥i¥H¨Ï¥Î¡C
- *
- * ¦¹¥~¡A¬°¤F´£¨Ñ¤@­Ó reentrant ªº editor¡Aprev «ü¦V«e¤@­Ó editor ªº
- * editor_internal_t¡Center_edit_buffer ¸ò exit_edit_buffer ´£¨Ñ¶i¥Xªº¤¶­±¡A
- * ¸Ì­±¤À§O·|©I¥s constructor ¸ò destructor¡C
- *
- * TODO
- * vedit ¸Ì­±¦³­Ó curr_buf->oldcurrline¡A¥Î¨Ó°O¤W¤@¦¸ªº currline¡C¥Ñ©ó¥u¦³ currline ¾Ö
- * ¦³ WRAPMARGIN ªºªÅ¶¡¡A©Ò¥H¥Ø«eªº§@ªk¬O·í curr_buf->oldcurrline != currline ®É¡A´N
- * resize curr_buf->oldcurrline ¸ò currline¡C¦ý¬OÁV¿|ªº¬O¥Ø«e¥²¶·¤H¤u°lÂÜ currline ªº¦æ
- * ¬°¡A¦Ó¥B­Y¤£©¯¹J¨ì curr_buf->oldcurrline «ü¨ìªº¨º¤@¦æ¤w¸g³Q free ±¼¡A´N§¹¤F¡C³Ì¦n¬O
- * §â³o¨ÇªF¦è¥]°_¨Ó¡C¤£¹L§Ú¨SªÅ°µ¤F¡Apatch is welcome :P
- *
- * Victor Hsieh <victor@csie.org>
- * Thu, 03 Feb 2005 15:18:00 +0800
- */
-typedef struct editor_internal_t {
-
- textline_t *firstline; /* first line of the article. */
- textline_t *lastline; /* last line of the article. */
-
- textline_t *currline; /* current line of the article(window). */
- textline_t *blockline; /* the first selected line of the block. */
- textline_t *top_of_win; /* top line of the article in the window. */
-
- textline_t *deleted_line; /* deleted line. Just keep one deleted line. */
- textline_t *oldcurrline;
-
- int currln; /* current line of the article. */
- short currpnt; /* current column of the article. */
- int totaln; /* total lines of the article. */
- int curr_window_line; /* current line to the window. */
- short last_margin;
- short edit_margin; /* when the cursor moves out of range (say,
- t_columns), shift this length of the string
- so you won't see the first edit_margin-th
- character. */
- short lastindent;
- int blockln; /* the row you started to select block. */
- char insert_c; /* insert this character when shift something
- in order to compensate the new space. */
- char last_phone_mode;
-
- char ifuseanony :1;
- char redraw_everything :1;
-
- char insert_mode :1;
- char ansimode :1;
- char indent_mode :1;
- char phone_mode :1;
- char raw_mode :1;
-
- char *searched_string;
- char *sitesig_string;
- char *(*substr_fp) ();
-
- char synparser; // syntax parser
-
- struct editor_internal_t *prev;
-
-} editor_internal_t;
-// } __attribute__ ((packed))
-
-static editor_internal_t *curr_buf = NULL;
-
-static const char fp_bak[] = "bak";
-
-static const char * const BIG5[13] = {
- "¡A¡F¡G¡B¡N¡C¡H¡I¡E¡T¡]¡^¡©¡ª¡«¡¬",
- "¢b¢c¢d¢e¢f¢g¢h¢i¢j¢k¢l¢m¢n¢o¢pùþ ",
- "¡³¡ó¡·¡´¡¸¡¹¡¼¡½¡¿¡¶¡¾¡µ¡º¡»¡ð¡ñ",
- "¡Ë¡\\¡[¡Â¡Ä¡X¡ü¡ý¢y¡þ¢@¢®¢¬¢­¢A¢B",
- "¡Ï¡Ð¡Ñ¡Ò¡Ô¡Ó¡×¡Ý¡Ú¡Ü¡Ø¡Ù¡Õ¡Ö¡î¡ï",
- "¡Û¡ã¡ä¡å¡ì¡í¡®¡æ¡ç¡è¡é¡Þ¡ß¡à¡á¡â",
- "¡ô¡õ¡ö¡÷¡ø¡ù¡ú¡û",
- "¡i¡j¡u¡v¡y¡z¡q¡r¡m¡n¡e¡f¡a¡b¡_¡`",
- "¡g¡h¡c¡d¡k¡l¡s¡t¡o¡p¡w¡x¡{¡|",
- "¢¨¢©¢ª¢«¡Î¡¯¡°¡±¢I¡ò¡À¡K¡L¡Æ¡È",
- "£\\£]£^£_£`£a£b£c£d£e£f£g£h£i£j£k",
- "£l£m£n£o£p£q£r£s£G£K£N£S£U£X£Z£[",
- "¢¹¢º¢»¢¼¢½¢¾¢¿¢À¢Á¢Â"
-};
-
-static const char * const BIG_mode[13] = {
- "¼ÐÂI",
- "¹Ï¶ô",
- "¼Ð°O",
- "¼Ð½u",
- "¼Æ¤@",
- "¼Æ¤G",
- "½bÀY",
- "¬A¤@",
- "¬A¤G",
- "¨ä¥L",
- "§Æ¤@",
- "§Æ¤G",
- "¼Æ¦r"
-};
-
-static const char *table[8] = {
- "¢x¢w¢|¢r¢}¢u¢q¢t¢z¢s¢{",
- "ùø¢¤ùãùäùåùàùáùâùÝùÞùß",
- "ùø¢wùõùöù÷ùòùóùôùïùðùñ",
- "¢x¢¤ùìùíù¢¦¢§ùæùçùè",
- "¢x¢w¢¢¢r¢£¢u¢q¢t¢~¢s¢¡",
- "ùø¢¤¢¢ù䢣ùàùáùâ¢~ùÞ¢¡",
- "ùø¢wùõùöù÷ùòùóùôùïùðùñ",
- "¢x¢¤ùìùíù¢¦¢§ùæùçùè"
-};
-
-static const char *table_mode[6] = {
- "ª½¨¤",
- "Ås©·",
- "¢q",
- "ùá",
- "ùó",
- "¢¦"
-};
-
-#ifdef DBCSAWARE
-static char mbcs_mode =1;
-
-#define IS_BIG5_HI(x) (0x81 <= (x) && (x) <= 0xfe)
-#define IS_BIG5_LOS(x) (0x40 <= (x) && (x) <= 0x7e)
-#define IS_BIG5_LOE(x) (0x80 <= (x) && (x) <= 0xfe)
-#define IS_BIG5_LO(x) (IS_BIG5_LOS(x) || IS_BIG5_LOE(x))
-#define IS_BIG5(hi,lo) (IS_BIG5_HI(hi) && IS_BIG5_LO(lo))
-
-int mchar_len(unsigned char *str)
-{
- return ((str[0] != '\0' && str[1] != '\0' && IS_BIG5(str[0], str[1])) ?
- 2 :
- 1);
-}
-
-#define FC_RIGHT (0)
-#define FC_LEFT (~FC_RIGHT)
-
-int fix_cursor(char *str, int pos, unsigned int dir)
-{
- int newpos, w;
-
- for(newpos = 0;
- *str != '\0' &&
- (w = mchar_len((unsigned char*)str),
- newpos + 1 + (dir & (w - 1))) <= pos;
- str += w, newpos += w)
- ;
-
- return newpos;
-}
-
-#endif
-
-/* °O¾ÐÅéºÞ²z»P½s¿è³B²z */
-static void
-indigestion(int i)
-{
- vmsgf("ÄY­«¤º¶Ë (%d)\n", i);
- u_exit("EDITOR FAILED");
- assert(0);
- exit(0);
-}
-
-static inline void
-edit_buffer_constructor(editor_internal_t *buf)
-{
- /* all unspecified columns are 0 */
- buf->blockln = -1;
- buf->insert_c = ' ';
- buf->insert_mode = 1;
- buf->redraw_everything = 1;
- buf->lastindent = -1;
-}
-
-static inline void
-enter_edit_buffer(void)
-{
- editor_internal_t *p = curr_buf;
- curr_buf = (editor_internal_t *)malloc(sizeof(editor_internal_t));
- memset(curr_buf, 0, sizeof(editor_internal_t));
- curr_buf->prev = p;
- edit_buffer_constructor(curr_buf);
-}
-
-static inline void
-free_line(textline_t *p)
-{
- p->next = (textline_t*)0x12345678;
- p->prev = (textline_t*)0x87654321;
- p->len = -12345;
- free(p);
-}
-
-static inline void
-edit_buffer_destructor(void)
-{
- if (curr_buf->deleted_line != NULL)
- free_line(curr_buf->deleted_line);
-
- if (curr_buf->searched_string != NULL)
- free(curr_buf->searched_string);
- if (curr_buf->sitesig_string != NULL)
- free(curr_buf->sitesig_string);
-}
-
-static inline void
-exit_edit_buffer(void)
-{
- editor_internal_t *p = curr_buf;
-
- edit_buffer_destructor();
- curr_buf = p->prev;
- free(p);
-}
-
-/**
- * transform position ansix in an ansi string of textline_t to the same
- * string without escape code.
- * @return position in the string without escape code.
- */
-static int
-ansi2n(int ansix, textline_t * line)
-{
- register char *data, *tmp;
- register char ch;
-
- data = tmp = line->data;
-
- while (*tmp) {
- if (*tmp == KEY_ESC) {
- while ((ch = *tmp) && !isalpha((int)ch))
- tmp++;
- if (ch)
- tmp++;
- continue;
- }
- if (ansix <= 0)
- break;
- tmp++;
- ansix--;
- }
- return tmp - data;
-}
-
-/**
- * opposite to ansi2n, according to given textline_t.
- * @return position in the string with escape code.
- */
-static short
-n2ansi(short nx, textline_t * line)
-{
- register short ansix = 0;
- register char *tmp, *nxp;
- register char ch;
-
- tmp = nxp = line->data;
- nxp += nx;
-
- while (*tmp) {
- if (*tmp == KEY_ESC) {
- while ((ch = *tmp) && !isalpha((int)ch))
- tmp++;
- if (ch)
- tmp++;
- continue;
- }
- if (tmp >= nxp)
- break;
- tmp++;
- ansix++;
- }
- return ansix;
-}
-
-/* ¿Ã¹õ³B²z¡G»²§U°T®§¡BÅã¥Ü½s¿è¤º®e */
-
-static inline void
-show_phone_mode_panel(void)
-{
- int i;
-
- move(b_lines - 1, 0);
- clrtoeol();
-
- if (curr_buf->last_phone_mode < 20) {
- int len;
- prints(ANSI_COLOR(1;46) "¡i%s¿é¤J¡j ", BIG_mode[curr_buf->last_phone_mode - 1]);
- len = strlen(BIG5[curr_buf->last_phone_mode - 1]) / 2;
- for (i = 0; i < len; i++)
- prints(ANSI_COLOR(37) "%c" ANSI_COLOR(34) "%2.2s",
- i + 'A', BIG5[curr_buf->last_phone_mode - 1] + i * 2);
- for (i = 0; i < 16 - len; i++)
- outs(" ");
- outs(ANSI_COLOR(37) " `1~9-=¤Á´« Zªí®æ" ANSI_RESET);
- }
- else {
- prints(ANSI_COLOR(1;46) "¡iªí®æø»s¡j /=%s *=%s§Î ",
- table_mode[(curr_buf->last_phone_mode - 20) / 4],
- table_mode[(curr_buf->last_phone_mode - 20) % 4 + 2]);
- for (i = 0;i < 11;i++)
- prints(ANSI_COLOR(37) "%c" ANSI_COLOR(34) "%2.2s", i ? i + '/' : '.',
- table[curr_buf->last_phone_mode - 20] + i * 2);
- outs(ANSI_COLOR(37) " Z¤º½X " ANSI_RESET);
- }
-}
-
-/**
- * Show the bottom status/help bar, and BIG5/table in phone_mode.
- */
-static void
-edit_msg(void)
-{
- int n = curr_buf->currpnt;
-
- if (curr_buf->ansimode) /* Thor: §@ ansi ½s¿è */
- n = n2ansi(n, curr_buf->currline);
-
- if (curr_buf->phone_mode)
- show_phone_mode_panel();
-
- move(b_lines, 0);
- clrtoeol();
- outs( ANSI_COLOR(37;44) " ½s¿è¤å³¹ "
- ANSI_COLOR(31;47) " (^Z/F1)" ANSI_COLOR(30) "»¡©ú "
- ANSI_COLOR(31;47) "(^P/^G)" ANSI_COLOR(30) "´¡¤J²Å¸¹/¹Ï¤ù "
- ANSI_COLOR(31) "(^X/^Q)" ANSI_COLOR(30) "Â÷¶}");
-
- prints( "ùø%s¢x%c%c%c%cùø %3d:%3d ",
- curr_buf->insert_mode ? "´¡¤J" : "¨ú¥N",
- curr_buf->ansimode ? 'A' : 'a',
- curr_buf->indent_mode ? 'I' : 'i',
- curr_buf->phone_mode ? 'P' : 'p',
- curr_buf->raw_mode ? 'R' : 'r',
- curr_buf->currln + 1, n + 1);
- outslr("", 78, ANSI_RESET, 0);
-}
-
-/**
- * return the middle line of the window.
- */
-static inline int
-middle_line(void)
-{
- return p_lines / 2 + 1;
-}
-
-/**
- * Return the previous 'num' line. Stop at the first line if there's
- * not enough lines.
- */
-static textline_t *
-back_line(textline_t * pos, int num)
-{
- while (num-- > 0) {
- register textline_t *item;
-
- if (pos && (item = pos->prev)) {
- pos = item;
- curr_buf->currln--;
- }
- else
- break;
- }
- return pos;
-}
-
-/* calculate if cursor is at bottom, scroll required?
- * currently vedit does NOT handle if curr_window_line > b_lines,
- * take care if you changed curr_window_line!
- */
-static inline int
-cursor_at_bottom_line(void)
-{
- return curr_buf->curr_window_line == b_lines ||
- (curr_buf->phone_mode && curr_buf->curr_window_line == b_lines - 1);
-}
-
-
-/**
- * Return the next 'num' line. Stop at the last line if there's not
- * enough lines.
- */
-static textline_t *
-forward_line(textline_t * pos, int num)
-{
- while (num-- > 0) {
- register textline_t *item;
-
- if (pos && (item = pos->next)) {
- pos = item;
- curr_buf->currln++;
- }
- else
- break;
- }
- return pos;
-}
-
-/**
- * move the cursor to the next line with ansimode fixed.
- */
-static inline void
-cursor_to_next_line(void)
-{
- short pos;
-
- if (curr_buf->currline->next == NULL)
- return;
-
- curr_buf->currline = curr_buf->currline->next;
- curr_buf->curr_window_line++;
- curr_buf->currln++;
-
- if (curr_buf->ansimode) {
- pos = n2ansi(curr_buf->currpnt, curr_buf->currline->prev);
- curr_buf->currpnt = ansi2n(pos, curr_buf->currline);
- }
- else {
- curr_buf->currpnt = (curr_buf->currline->len > curr_buf->lastindent)
- ? curr_buf->lastindent : curr_buf->currline->len;
- }
-}
-
-/**
- * opposite to cursor_to_next_line.
- */
-static inline void
-cursor_to_prev_line(void)
-{
- short pos;
-
- if (curr_buf->currline->prev == NULL)
- return;
-
- curr_buf->curr_window_line--;
- curr_buf->currln--;
- curr_buf->currline = curr_buf->currline->prev;
-
- if (curr_buf->ansimode) {
- pos = n2ansi(curr_buf->currpnt, curr_buf->currline->next);
- curr_buf->currpnt = ansi2n(pos, curr_buf->currline);
- }
- else {
- curr_buf->currpnt = (curr_buf->currline->len > curr_buf->lastindent)
- ? curr_buf->lastindent : curr_buf->currline->len;
- }
-}
-
-static inline void
-window_scroll_down(void)
-{
- curr_buf->curr_window_line = 0;
-
- if (!curr_buf->top_of_win->prev)
- indigestion(6);
- else {
- curr_buf->top_of_win = curr_buf->top_of_win->prev;
- rscroll();
- }
-}
-
-static inline void
-window_scroll_up(void)
-{
- curr_buf->curr_window_line = b_lines - (curr_buf->phone_mode ? 2 : 1);
-
- if (unlikely(!curr_buf->top_of_win->next))
- indigestion(7);
- else {
- curr_buf->top_of_win = curr_buf->top_of_win->next;
- if(curr_buf->phone_mode)
- move(b_lines-1, 0);
- else
- move(b_lines, 0);
- clrtoeol();
- scroll();
- }
-}
-
-/**
- * Get the current line number in the window now.
- */
-static int
-get_lineno_in_window(void)
-{
- int cnt = 0;
- textline_t *p = curr_buf->currline;
-
- while (p && (p != curr_buf->top_of_win)) {
- cnt++;
- p = p->prev;
- }
- return cnt;
-}
-
-/**
- * shift given raw data s with length len to left by one byte.
- */
-static void
-raw_shift_left(char *s, int len)
-{
- int i;
- for (i = 0; i < len && s[i] != 0; ++i)
- s[i] = s[i + 1];
-}
-
-/**
- * shift given raw data s with length len to right by one byte.
- */
-static void
-raw_shift_right(char *s, int len)
-{
- int i;
- for (i = len - 1; i >= 0; --i)
- s[i + 1] = s[i];
-}
-
-/**
- * Return the pointer to the next non-space position.
- */
-static char *
-next_non_space_char(char *s)
-{
- while (*s == ' ')
- s++;
- return s;
-}
-
-/**
- * allocate a textline_t with length length.
- */
-static textline_t *
-alloc_line(short length)
-{
- textline_t *p;
-
- if ((p = (textline_t *) malloc(length + sizeof(textline_t)))) {
- memset(p, 0, length + sizeof(textline_t));
-#ifdef DEBUG
- p->mlength = length;
-#endif
- return p;
- }
- indigestion(13);
- abort_bbs(0);
- return NULL;
-}
-
-/**
- * Insert p after line in list. Keeps up with last line
- */
-static void
-insert_line(textline_t *line, textline_t *p)
-{
- textline_t *n;
-
- if ((p->next = n = line->next))
- n->prev = p;
- else
- curr_buf->lastline = p;
- line->next = p;
- p->prev = line;
-}
-
-/**
- * delete_line deletes 'line' from the line list.
- * @param saved true if you want to keep the line in deleted_line
- */
-static void
-delete_line(textline_t * line, int saved)
-{
- register textline_t *p = line->prev;
- register textline_t *n = line->next;
-
- if (!p && !n) {
- line->data[0] = line->len = 0;
- return;
- }
- assert(line != curr_buf->top_of_win);
- if (n)
- n->prev = p;
- else
- curr_buf->lastline = p;
- if (p)
- p->next = n;
- else
- curr_buf->firstline = n;
-
- curr_buf->totaln--;
-
- if (saved) {
- if (curr_buf->deleted_line != NULL)
- free_line(curr_buf->deleted_line);
- curr_buf->deleted_line = line;
- curr_buf->deleted_line->next = NULL;
- curr_buf->deleted_line->prev = NULL;
- }
- else {
- free_line(line);
- }
-}
-
-/**
- * Return the indent space number according to CURRENT line and the FORMER
- * line. It'll be the first line contains non-space character.
- * @return space number from the beginning to the first non-space character,
- * return 0 if non or not in indent mode.
- */
-static int
-indent_space(void)
-{
- textline_t *p;
- int spcs;
-
- if (!curr_buf->indent_mode)
- return 0;
-
- for (p = curr_buf->currline; p; p = p->prev) {
- for (spcs = 0; p->data[spcs] == ' '; ++spcs);
- /* empty loop */
- if (p->data[spcs])
- return spcs;
- }
- return 0;
-}
-
-/**
- * adjustline(oldp, len);
- * ¥Î¨Ó±N oldp «ü¨ìªº¨º¤@¦æ, ­«·s­×¥¿¦¨ len³o»òªø.
- *
- * ©I¥s¤F adjustline «á°O±oÀˬd¦³°Ê¨ì currline, ¦pªG¬Oªº¸Ü oldcurrline ¤]­n°Ê
- *
- * In FreeBSD:
- * ¦b³oÃä¤@¦@°µ¤F¨â¦¸ªº memcpy() , ²Ä¤@¦¸±q heap «þ¨ì stack ,
- * §â­ì¨Ó°O¾ÐÅé free() «á, ¤S­«·s¦b stack¤W malloc() ¤@¦¸,
- * µM«á¦A«þ¨©¦^¨Ó.
- * ¥D­n¬O¥Î sbrk() Æ[¹î¨ìªºµ²ªG, ³o¼Ë¤l¤~¯uªº¯àÁY´î°O¾ÐÅé¥Î¶q.
- * ¸Ô¨£ /usr/share/doc/papers/malloc.ascii.gz (in FreeBSD)
- */
-static textline_t *
-adjustline(textline_t *oldp, short len)
-{
- // XXX write a generic version ?
- char tmpl[sizeof(textline_t) + WRAPMARGIN];
- textline_t *newp;
-
-#ifdef deBUG
- if(oldp->len > WRAPMARGIN || oldp->len < 0) {
- kill(currpid, SIGSEGV);
- }
-#endif
-
- memcpy(tmpl, oldp, oldp->len + sizeof(textline_t));
- free_line(oldp);
-
- newp = alloc_line(len);
- memcpy(newp, tmpl, len + sizeof(textline_t));
-#ifdef DEBUG
- newp->mlength = len;
-#endif
- if( oldp == curr_buf->firstline ) curr_buf->firstline = newp;
- if( oldp == curr_buf->lastline ) curr_buf->lastline = newp;
- if( oldp == curr_buf->currline ) curr_buf->currline = newp;
- if( oldp == curr_buf->blockline ) curr_buf->blockline = newp;
- if( oldp == curr_buf->top_of_win) curr_buf->top_of_win= newp;
- if( newp->prev != NULL ) newp->prev->next = newp;
- if( newp->next != NULL ) newp->next->prev = newp;
- // vmsg("adjust %x to %x, length: %d", (int)oldp, (int)newp, len);
- return newp;
-}
-
-/**
- * split 'line' right before the character pos
- *
- * @return the latter line after splitting
- */
-static textline_t *
-split(textline_t * line, int pos)
-{
- if (pos <= line->len) {
- register textline_t *p = alloc_line(WRAPMARGIN);
- register char *ptr;
- int spcs = indent_space();
-
- curr_buf->totaln++;
-
- p->len = line->len - pos + spcs;
- line->len = pos;
-
- memset(p->data, ' ', spcs);
- p->data[spcs] = 0;
-
- ptr = line->data + pos;
- if (curr_buf->indent_mode)
- ptr = next_non_space_char(ptr);
- strcat(p->data + spcs, ptr);
- ptr[0] = '\0';
-
- if (line == curr_buf->currline && pos <= curr_buf->currpnt) {
- line = adjustline(line, line->len);
- insert_line(line, p);
- // because p is allocated with fullsize, we can skip adjust.
- // curr_buf->oldcurrline = line;
- curr_buf->oldcurrline = curr_buf->currline = p;
- if (pos == curr_buf->currpnt)
- curr_buf->currpnt = spcs;
- else
- curr_buf->currpnt -= pos;
- curr_buf->curr_window_line++;
- curr_buf->currln++;
-
- /* split may cause cursor hit bottom */
- if (cursor_at_bottom_line())
- window_scroll_up();
- } else {
- p = adjustline(p, p->len);
- insert_line(line, p);
- }
- curr_buf->redraw_everything = YEA;
- }
- return line;
-}
-
-/**
- * Insert a character ch to current line.
- *
- * The line will be split if the length is >= WRAPMARGIN. It'll be split
- * from the last space if any, or start a new line after the last character.
- */
-static void
-insert_char(int ch)
-{
- register textline_t *p = curr_buf->currline;
- register int i = p->len;
- register char *s;
- int wordwrap = YEA;
-
- if (curr_buf->currpnt > i) {
- indigestion(1);
- return;
- }
- if (curr_buf->currpnt < i && !curr_buf->insert_mode) {
- p->data[curr_buf->currpnt++] = ch;
- /* Thor: ansi ½s¿è, ¥i¥Hoverwrite, ¤£»\¨ì ansi code */
- if (curr_buf->ansimode)
- curr_buf->currpnt = ansi2n(n2ansi(curr_buf->currpnt, p), p);
- } else {
- raw_shift_right(p->data + curr_buf->currpnt, i - curr_buf->currpnt + 1);
- p->data[curr_buf->currpnt++] = ch;
- i = ++(p->len);
- }
- if (i < WRAPMARGIN)
- return;
- s = p->data + (i - 1);
- while (s != p->data && *s == ' ')
- s--;
- while (s != p->data && *s != ' ')
- s--;
- if (s == p->data) {
- wordwrap = NA;
- s = p->data + (i - 2);
- }
- p = split(p, (s - p->data) + 1);
- p = p->next;
- i = p->len;
- if (wordwrap && i >= 1) {
- if (p->data[i - 1] != ' ') {
- p->data[i] = ' ';
- p->data[i + 1] = '\0';
- p->len++;
- }
- }
-}
-
-/**
- * insert_char twice.
- */
-static void
-insert_dchar(const char *dchar)
-{
- insert_char(*dchar);
- insert_char(*(dchar+1));
-}
-
-static void
-insert_tab(void)
-{
- do {
- insert_char(' ');
- } while (curr_buf->currpnt & 0x7);
-}
-
-/**
- * Insert a string.
- *
- * All printable and ESC_CHR will be directly printed out.
- * '\t' will be printed to align every 8 byte.
- * '\n' will split the line.
- * The other character will be ignore.
- */
-static void
-insert_string(const char *str)
-{
- char ch;
-
- while ((ch = *str++)) {
- if (isprint2(ch) || ch == ESC_CHR)
- insert_char(ch);
- else if (ch == '\t')
- insert_tab();
- else if (ch == '\n')
- split(curr_buf->currline, curr_buf->currpnt);
- }
-}
-
-/**
- * undelete the deleted line.
- *
- * return NULL if there's no deleted_line, otherwise, return currline.
- */
-static textline_t *
-undelete_line(void)
-{
- editor_internal_t tmp;
-
- if (!curr_buf->deleted_line)
- return NULL;
-
- tmp.top_of_win = curr_buf->top_of_win;
- tmp.indent_mode = curr_buf->indent_mode;
- tmp.curr_window_line = curr_buf->curr_window_line;
-
- curr_buf->indent_mode = 0;
- curr_buf->currpnt = 0;
- curr_buf->currln++;
- insert_string(curr_buf->deleted_line->data);
- insert_string("\n");
-
- curr_buf->top_of_win = tmp.top_of_win;
- curr_buf->indent_mode = tmp.indent_mode;
- curr_buf->curr_window_line = tmp.curr_window_line;
-
- assert(curr_buf->currline->prev);
- curr_buf->currline = adjustline(curr_buf->currline, curr_buf->currline->len);
- curr_buf->currline = curr_buf->currline->prev;
- curr_buf->currline = adjustline(curr_buf->currline, WRAPMARGIN);
- curr_buf->oldcurrline = curr_buf->currline;
-
- if (curr_buf->currline->prev == NULL) {
- curr_buf->top_of_win = curr_buf->currline;
- curr_buf->currln = 0;
- }
- return curr_buf->currline;
-}
-
-/*
- * join $line and $line->next
- *
- * line: A1 A2
- * next: B1 B2
- * ....: C1 C2
- *
- * case B=empty:
- * return YEA
- *
- * case A+B < WRAPMARGIN:
- * line: A1 A2 B1 B2
- * next: C1 C2
- * return YEA
- * NOTE It assumes $line has allocated WRAPMARGIN length of data buffer.
- *
- * case A+B1+B2 > WRAPMARGIN, A+B1<WRAPMARGIN
- * line: A1 A2 B1
- * next: B2 " "
- * call join($next)
- */
-static int
-join(textline_t * line)
-{
- register textline_t *n;
- register int ovfl;
-
- if (!(n = line->next))
- return YEA;
- if (!*next_non_space_char(n->data))
- return YEA;
-
- ovfl = line->len + n->len - WRAPMARGIN;
- if (ovfl < 0) {
- strcat(line->data, n->data);
- line->len += n->len;
- delete_line(n, 0);
- return YEA;
- } else {
- register char *s; /* the split point */
-
- s = n->data + n->len - ovfl - 1;
- while (s != n->data && *s == ' ')
- s--;
- while (s != n->data && *s != ' ')
- s--;
- if (s == n->data)
- return YEA;
- split(n, (s - n->data) + 1);
- if (line->len + line->next->len >= WRAPMARGIN) {
- indigestion(0);
- return YEA;
- }
- join(line);
- n = line->next;
- ovfl = n->len - 1;
- if (ovfl >= 0 && ovfl < WRAPMARGIN - 2) {
- s = &(n->data[ovfl]);
- if (*s != ' ') {
- strcpy(s, " ");
- n->len++;
- }
- }
- line->next=adjustline(line->next, WRAPMARGIN);
- join(line->next);
- line->next=adjustline(line->next, line->next->len);
- return NA;
- }
-}
-
-static void
-delete_char(void)
-{
- register int len;
-
- if ((len = curr_buf->currline->len)) {
- if (unlikely(curr_buf->currpnt >= len)) {
- indigestion(1);
- return;
- }
- raw_shift_left(curr_buf->currline->data + curr_buf->currpnt, curr_buf->currline->len - curr_buf->currpnt + 1);
- curr_buf->currline->len--;
- }
-}
-
-static void
-load_file(FILE * fp, off_t offSig)
-{
- char buf[WRAPMARGIN + 2];
- int indent_mode0 = curr_buf->indent_mode;
- size_t szread = 0;
-
- assert(fp);
- curr_buf->indent_mode = 0;
- while (fgets(buf, sizeof(buf), fp))
- {
- szread += strlen(buf);
- if (offSig < 0 || szread <= offSig)
- {
- insert_string(buf);
- }
- else
- {
- // this is the site sig
- break;
- }
- }
- curr_buf->indent_mode = indent_mode0;
-}
-
-/* ¼È¦sÀÉ */
-char *
-ask_tmpbuf(int y)
-{
- static char fp_buf[10] = "buf.0";
- static char msg[] = "½Ð¿ï¾Ü¼È¦sÀÉ (0-9)[0]: ";
-
- msg[19] = fp_buf[4];
- do {
- if (!getdata(y, 0, msg, fp_buf + 4, 4, DOECHO))
- fp_buf[4] = msg[19];
- } while (fp_buf[4] < '0' || fp_buf[4] > '9');
- return fp_buf;
-}
-
-static void
-read_tmpbuf(int n)
-{
- FILE *fp;
- char fp_tmpbuf[80];
- char tmpfname[] = "buf.0";
- char *tmpf;
- char ans[4] = "y";
-
- if (curr_buf->totaln >= EDIT_LINE_LIMIT)
- {
- vmsg("Àɮפw¶W¹L³Ì¤j­­¨î¡AµLªk¦AŪ¤J¼È¦sÀÉ¡C");
- return;
- }
-
- if (0 <= n && n <= 9) {
- tmpfname[4] = '0' + n;
- tmpf = tmpfname;
- } else {
- tmpf = ask_tmpbuf(3);
- n = tmpf[4] - '0';
- }
-
- setuserfile(fp_tmpbuf, tmpf);
- if (n != 0 && n != 5 && more(fp_tmpbuf, NA) != -1)
- getdata(b_lines - 1, 0, "½T©wŪ¤J¶Ü(Y/N)?[Y]", ans, sizeof(ans), LCECHO);
- if (*ans != 'n' && (fp = fopen(fp_tmpbuf, "r"))) {
- load_file(fp, -1);
- fclose(fp);
- while (curr_buf->curr_window_line >= b_lines) {
- curr_buf->curr_window_line--;
- curr_buf->top_of_win = curr_buf->top_of_win->next;
- }
- }
-}
-
-static void
-write_tmpbuf(void)
-{
- FILE *fp;
- char fp_tmpbuf[80], ans[4];
- textline_t *p;
- off_t sz = 0;
-
- setuserfile(fp_tmpbuf, ask_tmpbuf(3));
- if (dashf(fp_tmpbuf)) {
- more(fp_tmpbuf, NA);
- getdata(b_lines - 1, 0, "¼È¦sÀɤw¦³¸ê®Æ (A)ªþ¥[ (W)Âмg (Q)¨ú®ø¡H[A] ",
- ans, sizeof(ans), LCECHO);
-
- if (ans[0] == 'q')
- return;
- }
- if (ans[0] != 'w') // 'a'
- {
- sz = dashs(fp_tmpbuf);
- if (sz > EDIT_SIZE_LIMIT)
- {
- vmsg("¼È¦sÀɤw¶W¹L¤j¤p­­¨î¡AµLªk¦Aªþ¥[¡C");
- return;
- }
- }
- if ((fp = fopen(fp_tmpbuf, (ans[0] == 'w' ? "w" : "a+")))) {
- for (p = curr_buf->firstline; p; p = p->next) {
- if (p->next || p->data[0])
- fprintf(fp, "%s\n", p->data);
- }
- fclose(fp);
- }
-}
-
-static void
-erase_tmpbuf(void)
-{
- char fp_tmpbuf[80];
- char ans[4] = "n";
-
- setuserfile(fp_tmpbuf, ask_tmpbuf(3));
- if (more(fp_tmpbuf, NA) != -1)
- getdata(b_lines - 1, 0, "½T©w§R°£¶Ü(Y/N)?[N]",
- ans, sizeof(ans), LCECHO);
- if (*ans == 'y')
- unlink(fp_tmpbuf);
-}
-
-/**
- * ½s¿è¾¹¦Û°Ê³Æ¥÷
- *(³Ì¦h³Æ¥÷ 512 ¦æ (?))
- */
-void
-auto_backup(void)
-{
- if (curr_buf == NULL)
- return;
-
- if (curr_buf->currline) {
- FILE *fp;
- textline_t *p, *v;
- char bakfile[PATHLEN];
- int count = 0;
-
- setuserfile(bakfile, fp_bak);
- if ((fp = fopen(bakfile, "w"))) {
- for (p = curr_buf->firstline; p != NULL && count < 512; p = v, count++) {
- v = p->next;
- fprintf(fp, "%s\n", p->data);
- free_line(p);
- }
- fclose(fp);
- }
- curr_buf->currline = NULL;
- }
-}
-
-/**
- * ¨ú¦^½s¿è¾¹³Æ¥÷
- */
-void
-restore_backup(void)
-{
- char bakfile[80], buf[80];
-
- setuserfile(bakfile, fp_bak);
- if (dashf(bakfile)) {
- stand_title("½s¿è¾¹¦Û°Ê´_­ì");
- getdata(1, 0, "±z¦³¤@½g¤å³¹©|¥¼§¹¦¨¡A(S)¼g¤J¼È¦sÀÉ (Q)ºâ¤F¡H[S] ",
- buf, 4, LCECHO);
- if (buf[0] != 'q') {
- setuserfile(buf, ask_tmpbuf(3));
- Rename(bakfile, buf);
- } else
- unlink(bakfile);
- }
-}
-
-/* ¤Þ¥Î¤å³¹ */
-
-static int
-garbage_line(const char *str)
-{
- int qlevel = 0;
-
- while (*str == ':' || *str == '>') {
- if (*(++str) == ' ')
- str++;
- if (qlevel++ >= 1)
- return 1;
- }
- while (*str == ' ' || *str == '\t')
- str++;
- if (qlevel >= 1) {
- if (!strncmp(str, "¡° ", 3) || !strncmp(str, "==>", 3) ||
- strstr(str, ") ´£¨ì:\n"))
- return 1;
- }
- return (*str == '\n');
-}
-
-static void
-quote_strip_ansi_inline(unsigned char *is)
-{
- unsigned char *os = is;
-
- while (*is)
- {
- if(*is != ESC_CHR)
- *os++ = *is;
- else
- {
- is ++;
- if(*is == '*')
- {
- /* ptt prints, keep it as normal */
- *os++ = '*';
- *os++ = '*';
- }
- else
- {
- /* normal ansi, strip them out. */
- while (*is && ANSI_IN_ESCAPE(*is))
- is++;
- }
- }
- is++;
-
- }
-
- *os = 0;
-}
-
-static void
-do_quote(void)
-{
- int op;
- char buf[512];
-
- getdata(b_lines - 1, 0, "½Ð°Ý­n¤Þ¥Î­ì¤å¶Ü(Y/N/All/Repost)¡H[Y] ",
- buf, 3, LCECHO);
- op = buf[0];
-
- if (op != 'n') {
- FILE *inf;
-
- if ((inf = fopen(quote_file, "r"))) {
- char *ptr;
- int indent_mode0 = curr_buf->indent_mode;
-
- fgets(buf, sizeof(buf), inf);
- if ((ptr = strrchr(buf, ')')))
- ptr[1] = '\0';
- else if ((ptr = strrchr(buf, '\n')))
- ptr[0] = '\0';
-
- if ((ptr = strchr(buf, ':'))) {
- char *str;
-
- while (*(++ptr) == ' ');
-
- /* ¶¶¤â²o¦Ï¡A¨ú±o author's address */
- if ((curredit & EDIT_BOTH) && (str = strchr(quote_user, '.'))) {
- strcpy(++str, ptr);
- str = strchr(str, ' ');
- assert(str);
- str[0] = '\0';
- }
- } else
- ptr = quote_user;
-
- curr_buf->indent_mode = 0;
- insert_string("¡° ¤Þ­z¡m");
- insert_string(ptr);
- insert_string("¡n¤§»Ê¨¥¡G\n");
-
- if (op != 'a') /* ¥h±¼ header */
- while (fgets(buf, sizeof(buf), inf) && buf[0] != '\n');
- /* FIXME by MH:
- ¦pªG header ¨ì¤º¤å¤¤¶¡¨S¦³ªÅ¦æ¤À¹j¡A·|³y¦¨ All ¥H¥~ªº¼Ò¦¡
- ³£¤Þ¤£¨ì¤º¤å¡C
- */
-
- if (op == 'a')
- while (fgets(buf, sizeof(buf), inf)) {
- insert_char(':');
- insert_char(' ');
- quote_strip_ansi_inline((unsigned char *)buf);
- insert_string(buf);
- }
- else if (op == 'r')
- while (fgets(buf, sizeof(buf), inf)) {
- /* repost, keep anything */
- // quote_strip_ansi_inline((unsigned char *)buf);
- insert_string(buf);
- }
- else {
- if (curredit & EDIT_LIST) /* ¥h±¼ mail list ¤§ header */
- while (fgets(buf, sizeof(buf), inf) && (!strncmp(buf, "¡° ", 3)));
- while (fgets(buf, sizeof(buf), inf)) {
- if (!strcmp(buf, "--\n"))
- break;
- if (!garbage_line(buf)) {
- insert_char(':');
- insert_char(' ');
- quote_strip_ansi_inline((unsigned char *)buf);
- insert_string(buf);
- }
- }
- }
- curr_buf->indent_mode = indent_mode0;
- fclose(inf);
- }
- }
-}
-
-/**
- * ¼f¬d user ¤Þ¨¥ªº¨Ï¥Î
- */
-static int
-check_quote(void)
-{
- register textline_t *p = curr_buf->firstline;
- register char *str;
- int post_line;
- int included_line;
-
- post_line = included_line = 0;
- while (p) {
- if (!strcmp(str = p->data, "--"))
- break;
- if (str[1] == ' ' && ((str[0] == ':') || (str[0] == '>')))
- included_line++;
- else {
- while (*str == ' ' || *str == '\t')
- str++;
- if (*str)
- post_line++;
- }
- p = p->next;
- }
-
- if ((included_line >> 2) > post_line) {
- move(4, 0);
- outs("¥»½g¤å³¹ªº¤Þ¨¥¤ñ¨Ò¶W¹L 80%¡A½Ð±z°µ¨Ç·Lªº­×¥¿¡G\n\n"
- ANSI_COLOR(1;33) "1) ¼W¥[¤@¨Ç¤å³¹ ©Î 2) §R°£¤£¥²­n¤§¤Þ¨¥" ANSI_RESET);
- {
- char ans[4];
-
- getdata(12, 12, "(E)Ä~Äò½s¿è (W)±j¨î¼g¤J¡H[E] ",
- ans, sizeof(ans), LCECHO);
- if (ans[0] == 'w')
- return 0;
- }
- return 1;
- }
- return 0;
-}
-
-/* Àɮ׳B²z¡GŪÀÉ¡B¦sÀÉ¡B¼ÐÃD¡Bñ¦WÀÉ */
-off_t loadsitesig(const char *fname);
-
-static void
-read_file(const char *fpath, int splitSig)
-{
- FILE *fp;
- off_t offSig = -1;
-
- if (splitSig)
- offSig = loadsitesig(fpath);
-
- if ((fp = fopen(fpath, "r")) == NULL) {
- int fd;
- if ((fd = creat(fpath, 0600)) >= 0) {
- close(fd);
- return;
- }
- indigestion(4);
- abort_bbs(0);
- }
- load_file(fp, offSig);
- fclose(fp);
-}
-
-void
-write_header(FILE * fp, char *mytitle) // FIXME unused
-{
-
- if (curredit & EDIT_MAIL || curredit & EDIT_LIST) {
- fprintf(fp, "%s %s (%s)\n", str_author1, cuser.userid,
- cuser.nickname
- );
- } else {
- char *ptr = mytitle;
- struct {
- char author[IDLEN + 1];
- char board[IDLEN + 1];
- char title[66];
- time4_t date; /* last post's date */
- int number; /* post number */
- } postlog;
-
- memset(&postlog, 0, sizeof(postlog));
- strlcpy(postlog.author, cuser.userid, sizeof(postlog.author));
- if (curr_buf)
- curr_buf->ifuseanony = 0;
-#ifdef HAVE_ANONYMOUS
- if (currbrdattr & BRD_ANONYMOUS) {
- int defanony = (currbrdattr & BRD_DEFAULTANONYMOUS);
- if (defanony)
- getdata(3, 0, "½Ð¿é¤J§A·Q¥ÎªºID¡A¤]¥iª½±µ«ö[Enter]¡A"
- "©Î¬O«ö[r]¥Î¯u¦W¡G", real_name, sizeof(real_name), DOECHO);
- else
- getdata(3, 0, "½Ð¿é¤J§A·Q¥ÎªºID¡A¤]¥iª½±µ«ö[Enter]¨Ï¥Î­ìID¡G",
- real_name, sizeof(real_name), DOECHO);
- if (!real_name[0] && defanony) {
- strlcpy(real_name, "Anonymous", sizeof(real_name));
- strlcpy(postlog.author, real_name, sizeof(postlog.author));
- if (curr_buf)
- curr_buf->ifuseanony = 1;
- } else {
- if (!strcmp("r", real_name) || (!defanony && !real_name[0]))
- strlcpy(postlog.author, cuser.userid, sizeof(postlog.author));
- else {
- snprintf(postlog.author, sizeof(postlog.author),
- "%s.", real_name);
- if (curr_buf)
- curr_buf->ifuseanony = 1;
- }
- }
- }
-#endif
- strlcpy(postlog.board, currboard, sizeof(postlog.board));
- if (!strncmp(ptr, str_reply, 4))
- ptr += 4;
- strlcpy(postlog.title, ptr, sizeof(postlog.title));
- postlog.date = now;
- postlog.number = 1;
- append_record(".post", (fileheader_t *) & postlog, sizeof(postlog));
-#ifdef HAVE_ANONYMOUS
- if (currbrdattr & BRD_ANONYMOUS) {
- int defanony = (currbrdattr & BRD_DEFAULTANONYMOUS);
-
- fprintf(fp, "%s %s (%s) %s %s\n", str_author1, postlog.author,
- (((!strcmp(real_name, "r") && defanony) ||
- (!real_name[0] && (!defanony))) ? cuser.nickname :
- "²q²q§Ú¬O½Ö ? ^o^"),
- local_article ? str_post2 : str_post1, currboard);
- } else {
- fprintf(fp, "%s %s (%s) %s %s\n", str_author1, cuser.userid,
- cuser.nickname,
- local_article ? str_post2 : str_post1, currboard);
- }
-#else /* HAVE_ANONYMOUS */
- fprintf(fp, "%s %s (%s) %s %s\n", str_author1, cuser.userid,
- cuser.nickname,
- local_article ? str_post2 : str_post1, currboard);
-#endif /* HAVE_ANONYMOUS */
-
- }
- mytitle[72] = '\0';
- fprintf(fp, "¼ÐÃD: %s\n®É¶¡: %s\n", mytitle, ctime4(&now));
-}
-
-off_t
-loadsitesig(const char *fname)
-{
- int fd = 0;
- off_t sz = 0, ret = -1;
- char *start, *sp;
-
- sz = dashs(fname);
- if (sz < 1)
- return -1;
- fd = open(fname, O_RDONLY);
- if (fd < 0)
- return -1;
- start = (char*)mmap(NULL, sz, PROT_READ, MAP_SHARED, fd, 0);
- if (start)
- {
- sp = start + sz - 4 - 1; // 4 = \n--\n
- while (sp > start)
- {
- if ((*sp == '\n' && strncmp(sp, "\n--\n", 4) == 0) ||
- (*sp == '\r' && strncmp(sp, "\r--\r", 4) == 0) )
- {
- size_t szSig = sz - (sp-start+1);
- ret = sp - start + 1;
- // allocate string
- curr_buf->sitesig_string = (char*) malloc (szSig + 1);
- if (curr_buf->sitesig_string)
- {
- memcpy(curr_buf->sitesig_string, sp+1, szSig);
- curr_buf->sitesig_string[szSig] = 0;
- }
- break;
- }
- sp --;
- }
- munmap(start, sz);
- }
-
- close(fd);
- return ret;
-}
-
-void
-addsignature(FILE * fp, int ifuseanony)
-{
- FILE *fs;
- int i;
- char buf[WRAPMARGIN + 1];
- char fpath[STRLEN];
-
- char ch;
-
- if (!strcmp(cuser.userid, STR_GUEST)) {
- fprintf(fp, "\n--\n¡° µo«H¯¸ :" BBSNAME "(" MYHOSTNAME
- ") \n¡» From: %s\n", fromhost);
- return;
- }
- if (!ifuseanony) {
-
- int browsing = 0;
- SigInfo si;
- memset(&si, 0, sizeof(si));
-
-browse_sigs:
- showsignature(fpath, &i, &si);
-
- if (si.total > 0){
- char msg[64];
-
- ch = isdigit(cuser.signature) ? cuser.signature : 'x';
- sprintf(msg,
- (browsing || (si.max > si.show_max)) ?
- "½Ð¿ï¾Üñ¦WÀÉ (1-9, 0=¤£¥[ n=½­¶ x=ÀH¾÷)[%c]: ":
- "½Ð¿ï¾Üñ¦WÀÉ (1-9, 0=¤£¥[ x=ÀH¾÷)[%c]: ",
- ch);
- getdata(0, 0, msg, buf, 4, LCECHO);
-
- if(buf[0] == 'n')
- {
- si.show_start = si.show_max + 1;
- if(si.show_start > si.max)
- si.show_start = 0;
- browsing = 1;
- goto browse_sigs;
- }
-
- if (!buf[0])
- buf[0] = ch;
-
- if (isdigit((int)buf[0]))
- ch = buf[0];
- else
- ch = '1' + random() % (si.max+1);
- cuser.signature = buf[0];
-
- if (ch != '0') {
- fpath[i] = ch;
- do
- {
- if ((fs = fopen(fpath, "r"))) {
- fputs("\n--\n", fp);
- for (i = 0; i < MAX_SIGLINES &&
- fgets(buf, sizeof(buf), fs); i++)
- fputs(buf, fp);
- fclose(fs);
- fpath[i] = ch;
- }
- else
- fpath[i] = '1' + (fpath[i] - '1' + 1) % (si.max+1);
- } while (!isdigit((int)buf[0]) && si.max > 0 && ch != fpath[i]);
- }
- }
- }
-#ifdef HAVE_ORIGIN
-#ifdef HAVE_ANONYMOUS
- if (ifuseanony)
- fprintf(fp, "\n--\n¡° µo«H¯¸: " BBSNAME "(" MYHOSTNAME
- ") \n¡» From: %s\n", "°Î¦W¤Ñ¨Ïªº®a");
- else
-#endif
- {
- char temp[33];
-
- strlcpy(temp, fromhost, sizeof(temp));
- fprintf(fp, "\n--\n¡° µo«H¯¸: " BBSNAME "(" MYHOSTNAME
- ") \n¡» From: %s\n", temp);
- }
-#endif
-}
-
-#ifdef EXP_EDIT_UPLOAD
-static void upload_file(void);
-#endif // EXP_EDIT_UPLOAD
-
-static int
-write_file(char *fpath, int saveheader, int *islocal, char *mytitle, int upload, int chtitle)
-{
- struct tm *ptime;
- FILE *fp = NULL;
- textline_t *p, *v;
- char ans[TTLEN], *msg;
- int aborted = 0, line = 0, checksum[3], sum = 0, po = 1;
-
- stand_title("Àɮ׳B²z");
- move(1,0);
-
-#ifdef EDIT_UPLOAD_ALLOWALL
- upload = 1;
-#endif // EDIT_UPLOAD_ALLOWALL
-
- // common trail
-
- if (currstat == SMAIL)
- outs("[S]Àx¦s");
- else if (local_article)
- outs("[L]¯¸¤º«H¥ó (S)Àx¦s");
- else
- outs("[S]Àx¦s (L)¯¸¤º«H¥ó");
-
-#ifdef EXP_EDIT_UPLOAD
- if (upload)
- outs(" (U)¤W¶Ç¸ê®Æ");
-#endif // EXP_EDIT_UPLOAD
-
- if (chtitle)
- outs(" (T)§ï¼ÐÃD");
-
- outs(" (A)©ñ±ó (E)Ä~Äò (R/W/D)Ū¼g§R¼È¦sÀÉ");
-
- getdata(2, 0, "½T©w­nÀx¦sÀɮ׶ܡH ", ans, 2, LCECHO);
-
- // avoid lots pots
- sleep(1);
-
- switch (ans[0]) {
- case 'a':
- outs("¤å³¹" ANSI_COLOR(1) " ¨S¦³ " ANSI_RESET "¦s¤J");
- aborted = -1;
- break;
- case 'e':
- return KEEP_EDITING;
-#ifdef EXP_EDIT_UPLOAD
- case 'u':
- if (upload)
- upload_file();
- return KEEP_EDITING;
-#endif // EXP_EDIT_UPLOAD
- case 'r':
- read_tmpbuf(-1);
- return KEEP_EDITING;
- case 'w':
- write_tmpbuf();
- return KEEP_EDITING;
- case 'd':
- erase_tmpbuf();
- return KEEP_EDITING;
- case 't':
- if (!chtitle)
- return KEEP_EDITING;
- move(3, 0);
- prints("¼ÐÃD¡G%s", mytitle);
- strlcpy(ans, mytitle, sizeof(ans));
- if (getdata_buf(4, 0, "·s¼ÐÃD¡G", ans, sizeof(ans), DOECHO))
- strlcpy(mytitle, ans, STRLEN);
- return KEEP_EDITING;
- case 's':
- if (!HasUserPerm(PERM_LOGINOK)) {
- local_article = 1;
- move(2, 0);
- outs("±z©|¥¼³q¹L¨­¥÷½T»{¡A¥u¯à Local Save¡C\n");
- pressanykey();
- } else
- local_article = 0;
- break;
- case 'l':
- local_article = 1;
- }
-
- if (!aborted) {
-
- if (saveheader && !(curredit & EDIT_MAIL) && check_quote())
- return KEEP_EDITING;
-
- if (!(*fpath))
- setuserfile(fpath, "ve_XXXXXX");
- if ((fp = fopen(fpath, "w")) == NULL) {
- indigestion(5);
- abort_bbs(0);
- }
- if (saveheader)
- write_header(fp, mytitle);
- }
- for (p = curr_buf->firstline; p; p = v) {
- v = p->next;
- if (!aborted) {
- assert(fp);
- msg = p->data;
- if (v || msg[0]) {
- trim(msg);
-
- line++;
-
- /* check crosspost */
- if (currstat == POSTING && po ) {
- int msgsum = StringHash(msg);
- if (msgsum) {
- if (postrecord.last_bid != currbid &&
- postrecord.checksum[po] == msgsum) {
- po++;
- if (po > 3) {
- postrecord.times++;
- postrecord.last_bid = currbid;
- po = 0;
- }
- } else
- po = 1;
- if (line >= curr_buf->totaln / 2 && sum < 3) {
- checksum[sum++] = msgsum;
- }
- }
- }
- fprintf(fp, "%s\n", msg);
- }
- }
- free_line(p);
- }
- curr_buf->currline = NULL;
-
- // what if currbid == 0? add currstat checking.
- if (currstat == POSTING &&
- postrecord.times > MAX_CROSSNUM-1 &&
- !is_hidden_board_friend(currbid, currutmp->uid))
- anticrosspost();
-
- if (po && sum == 3) {
- memcpy(&postrecord.checksum[1], checksum, sizeof(int) * 3);
- if(postrecord.last_bid != currbid)
- postrecord.times = 0;
- }
-
- if (aborted)
- return aborted;
-
- if (islocal)
- *islocal = local_article;
-
- if (curr_buf->sitesig_string)
- fprintf(fp, curr_buf->sitesig_string);
-
- if (currstat == POSTING || currstat == SMAIL)
- {
- addsignature(fp, curr_buf->ifuseanony);
- }
- else if (currstat == REEDIT)
- {
-#ifndef ALL_REEDIT_LOG
- // why force signature in SYSOP board?
- if(strcmp(currboard, GLOBAL_SYSOP) == 0)
-#endif
- {
- ptime = localtime4(&now);
- fprintf(fp,
- "¡° ½s¿è: %-15s ¨Ó¦Û: %-20s (%02d/%02d %02d:%02d)\n",
- cuser.userid, fromhost,
- ptime->tm_mon + 1, ptime->tm_mday,
- ptime->tm_hour, ptime->tm_min);
- }
- }
-
- fclose(fp);
- return 0;
-}
-
-static inline int
-has_block_selection(void)
-{
- return curr_buf->blockln >= 0;
-}
-
-/**
- * a block is continual lines of the article.
- */
-
-/**
- * stop the block selection.
- */
-static void
-block_cancel(void)
-{
- if (has_block_selection()) {
- curr_buf->blockln = -1;
- curr_buf->redraw_everything = YEA;
- }
-}
-
-static inline void
-setup_block_begin_end(textline_t **begin, textline_t **end)
-{
- if (curr_buf->currln >= curr_buf->blockln) {
- *begin = curr_buf->blockline;
- *end = curr_buf->currline;
- } else {
- *begin = curr_buf->currline;
- *end = curr_buf->blockline;
- }
-}
-
-#define BLOCK_TRUNCATE 0
-#define BLOCK_APPEND 1
-/**
- * save the selected block to file 'fname.'
- * mode: BLOCK_TRUNCATE truncate mode
- * BLOCK_APPEND append mode
- */
-static void
-block_save_to_file(const char *fname, int mode)
-{
- textline_t *begin, *end;
- char fp_tmpbuf[80];
- FILE *fp;
-
- if (!has_block_selection())
- return;
-
- setup_block_begin_end(&begin, &end);
-
- setuserfile(fp_tmpbuf, fname);
- if ((fp = fopen(fp_tmpbuf, mode == BLOCK_APPEND ? "a+" : "w+"))) {
-
- textline_t *p;
-
- for (p = begin; p != end; p = p->next)
- fprintf(fp, "%s\n", p->data);
- fprintf(fp, "%s\n", end->data);
- fclose(fp);
- }
-}
-
-/**
- * delete selected block
- */
-static void
-block_delete(void)
-{
- textline_t *begin, *end;
- textline_t *p;
-
- if (!has_block_selection())
- return;
-
- setup_block_begin_end(&begin, &end);
-
- // the block region is (currln, block) or (blockln, currln).
-
- if (curr_buf->currln > curr_buf->blockln) {
- // case (blockln, currln)
- // piaip 2007/1201 ¦b³o¸Ì­ì¦³ offset-by-one issue
- // ¦pªG¤S¹J¨ì¡A½ÐÀˬd³oªþªñ¡C
- curr_buf->curr_window_line -= (curr_buf->currln - curr_buf->blockln);
-
- if (curr_buf->curr_window_line <= 0) {
- curr_buf->curr_window_line = 0;
- if (end->next)
- (curr_buf->top_of_win = end->next)->prev = begin->prev;
- else
- curr_buf->top_of_win = (curr_buf->lastline = begin->prev);
- }
- curr_buf->currln -= (curr_buf->currln - curr_buf->blockln);
- } else {
- // case (currln, blockln)
- }
-
- // adjust buffer after delete
- if (begin->prev)
- begin->prev->next = end->next;
- else if (end->next)
- curr_buf->top_of_win = curr_buf->firstline = end->next;
- else {
- curr_buf->currline = curr_buf->top_of_win = curr_buf->firstline = curr_buf->lastline = alloc_line(WRAPMARGIN);
- curr_buf->currln = curr_buf->curr_window_line = curr_buf->edit_margin = 0;
- }
-
- // adjust current line
- if (end->next) {
- curr_buf->currline = end->next;
- curr_buf->currline->prev = begin->prev;
- }
- else if (begin->prev) {
- curr_buf->currline = (curr_buf->lastline = begin->prev);
- curr_buf->currln--;
- if (curr_buf->curr_window_line > 0)
- curr_buf->curr_window_line--;
- }
-
- // remove buffer
- for (p = begin; p != end; curr_buf->totaln--)
- free_line((p = p->next)->prev);
-
- free_line(end);
- curr_buf->totaln--;
-
- curr_buf->currpnt = 0;
-}
-
-static void
-block_cut(void)
-{
- if (!has_block_selection())
- return;
-
- block_save_to_file("buf.0", BLOCK_TRUNCATE);
- block_delete();
-
- curr_buf->blockln = -1;
- curr_buf->redraw_everything = YEA;
-}
-
-static void
-block_copy(void)
-{
- if (!has_block_selection())
- return;
-
- block_save_to_file("buf.0", BLOCK_TRUNCATE);
-
- curr_buf->blockln = -1;
- curr_buf->redraw_everything = YEA;
-}
-
-static void
-block_prompt(void)
-{
- char fp_tmpbuf[80];
- char tmpfname[] = "buf.0";
- char mode[2];
-
- move(b_lines - 1, 0);
- clrtoeol();
-
- if (!getdata(b_lines - 1, 0, "§â°Ï¶ô²¾¦Ü¼È¦sÀÉ (0:Cut, 5:Copy, 6-9, q: Cancel)[0] ", tmpfname + 4, 4, LCECHO))
- tmpfname[4] = '0';
-
- if (tmpfname[4] < '0' || tmpfname[4] > '9')
- goto cancel_block;
-
- if (tmpfname[4] == '0') {
- block_cut();
- return;
- }
- else if (tmpfname[4] == '5') {
- block_copy();
- return;
- }
-
- setuserfile(fp_tmpbuf, tmpfname);
- if (dashf(fp_tmpbuf)) {
- more(fp_tmpbuf, NA);
- getdata(b_lines - 1, 0, "¼È¦sÀɤw¦³¸ê®Æ (A)ªþ¥[ (W)Âмg (Q)¨ú®ø¡H[W] ", mode, sizeof(mode), LCECHO);
- if (mode[0] == 'q')
- goto cancel_block;
- else if (mode[0] != 'a')
- mode[0] = 'w';
- }
-
- if (getans("§R°£°Ï¶ô(Y/N)?[N] ") != 'y')
- goto cancel_block;
-
- block_save_to_file(tmpfname, mode[0] == 'a' ? BLOCK_APPEND : BLOCK_TRUNCATE);
-
-cancel_block:
- curr_buf->blockln = -1;
- curr_buf->redraw_everything = YEA;
-}
-
-static void
-block_select(void)
-{
- curr_buf->blockln = curr_buf->currln;
- curr_buf->blockline = curr_buf->currline;
-}
-
-enum {
- EOATTR_NORMAL = 0x00,
- EOATTR_SELECTED = 0x01, // selected (reverse)
- EOATTR_MOVIECODE= 0x02, // pmore movie
- EOATTR_BBSLUA = 0x04, // BBS Lua (header)
- EOATTR_COMMENT = 0x08, // comment syntax
-
-};
-
-static const char *luaKeywords[] = {
- "and", "break", "do", "else", "elseif",
- "end", "for", "if", "in", "not", "or",
- "repeat","return","then","until","while",
- NULL
-};
-
-static const char *luaDataKeywords[] = {
- "false", "function", "local", "nil", "true",
- NULL
-};
-
-static const char *luaFunctions[] = {
- "assert", "print", "tonumber", "tostring", "type",
- NULL
-};
-
-static const char *luaMath[] = {
- "abs", "acos", "asin", "atan", "atan2", "ceil", "cos", "cosh", "deg",
- "exp", "floor", "fmod", "frexp", "ldexp", "log", "log10", "max", "min",
- "modf", "pi", "pow", "rad", "random", "randomseed", "sin", "sinh",
- "sqrt", "tan", "tanh",
- NULL
-};
-
-static const char *luaTable[] = {
- "concat", "insert", "maxn", "remove", "sort",
- NULL
-};
-
-static const char *luaString[] = {
- "byte", "char", "dump", "find", "format", "gmatch", "gsub", "len",
- "lower", "match", "rep", "reverse", "sub", "upper", NULL
-};
-
-static const char *luaBbs[] = {
- "ANSI_COLOR", "ANSI_RESET", "ESC", "addstr", "clear", "clock",
- "clrtobot", "clrtoeol", "color", "ctime", "getch","getdata",
- "getmaxyx", "getstr", "getyx", "interface", "kball", "kbhit", "kbreset",
- "move", "moverel", "now", "outs", "pause", "print", "rect", "refresh",
- "setattr", "sitename", "sleep", "strip_ansi", "time", "title",
- "userid", "usernick",
- NULL
-};
-
-static const char *luaToc[] = {
- "author", "date", "interface", "latestref",
- "notes", "title", "version",
- NULL
-};
-
-static const char *luaBit[] = {
- "arshift", "band", "bnot", "bor", "bxor", "cast", "lshift", "rshift",
- NULL
-};
-
-static const char *luaStore[] = {
- "USER", "GLOBAL", "iolimit", "limit", "load", "save",
- NULL
-};
-
-static const char *luaLibs[] = {
- "bbs", "bit", "math", "store", "string", "table", "toc",
- NULL
-};
-static const char**luaLibAPI[] = {
- luaBbs, luaBit, luaMath, luaStore, luaString, luaTable, luaToc,
- NULL
-};
-
-int synLuaKeyword(const char *text, int n, char *wlen)
-{
- int i = 0;
- const char **tbl = NULL;
- if (*text >= 'A' && *text <= 'Z')
- {
- // normal identifier
- while (n-- > 0 && (isalnum(*text) || *text == '_'))
- {
- text++;
- (*wlen) ++;
- }
- return 0;
- }
- if (*text >= '0' && *text <= '9')
- {
- // digits
- while (n-- > 0 && (isdigit(*text) || *text == '.' || *text == 'x'))
- {
- text++;
- (*wlen) ++;
- }
- return 5;
- }
- if (*text == '#')
- {
- text++;
- (*wlen) ++;
- // length of identifier
- while (n-- > 0 && (isalnum(*text) || *text == '_'))
- {
- text++;
- (*wlen) ++;
- }
- return -2;
- }
-
- // ignore non-identifiers
- if (!(*text >= 'a' && *text <= 'z'))
- return 0;
-
- // 1st, try keywords
- for (i = 0; luaKeywords[i] && *text >= *luaKeywords[i]; i++)
- {
- int l = strlen(luaKeywords[i]);
- if (n < l)
- continue;
- if (isalnum(text[l]))
- continue;
- if (strncmp(text, luaKeywords[i], l) == 0)
- {
- *wlen = l;
- return 3;
- }
- }
- for (i = 0; luaDataKeywords[i] && *text >= *luaDataKeywords[i]; i++)
- {
- int l = strlen(luaDataKeywords[i]);
- if (n < l)
- continue;
- if (isalnum(text[l]))
- continue;
- if (strncmp(text, luaDataKeywords[i], l) == 0)
- {
- *wlen = l;
- return 2;
- }
- }
- for (i = 0; luaFunctions[i] && *text >= *luaFunctions[i]; i++)
- {
- int l = strlen(luaFunctions[i]);
- if (n < l)
- continue;
- if (isalnum(text[l]))
- continue;
- if (strncmp(text, luaFunctions[i], l) == 0)
- {
- *wlen = l;
- return 6;
- }
- }
- for (i = 0; luaLibs[i]; i++)
- {
- int l = strlen(luaLibs[i]);
- if (n < l)
- continue;
- if (text[l] != '.' && text[l] != ':')
- continue;
- if (strncmp(text, luaLibs[i], l) == 0)
- {
- *wlen = l+1;
- text += l; text ++;
- n -= l; n--;
- break;
- }
- }
-
- tbl = luaLibAPI[i];
- if (!tbl)
- {
- // calcualte wlen
- while (n-- > 0 && (isalnum(*text) || *text == '_'))
- {
- text++;
- (*wlen) ++;
- }
- return 0;
- }
-
- for (i = 0; tbl[i]; i++)
- {
- int l = strlen(tbl[i]);
- if (n < l)
- continue;
- if (isalnum(text[l]))
- continue;
- if (strncmp(text, tbl[i], l) == 0)
- {
- *wlen += l;
- return 6;
- }
- }
- // luaLib. only
- return -6;
-}
-
-/**
- * Just like outs, but print out '*' instead of 27(decimal) in the given string.
- *
- * FIXME column could not start from 0
- */
-
-static void
-edit_outs_attr_n(const char *text, int n, int attr)
-{
- int column = 0;
- register unsigned char inAnsi = 0;
- register unsigned char ch;
- int doReset = 0;
- const char *reset = ANSI_RESET;
-
- // syntax attributes
- char fComment = 0,
- fSingleQuote = 0,
- fDoubleQuote = 0,
- fSquareQuote = 0,
- fWord = 0;
-
-#ifdef COLORED_SELECTION
- if ((attr & EOATTR_SELECTED) &&
- (attr & ~EOATTR_SELECTED))
- {
- reset = ANSI_COLOR(0;7;36);
- doReset = 1;
- outs(reset);
- }
- else
-#endif // if not defined, color by priority - selection first
- if (attr & EOATTR_SELECTED)
- {
- reset = ANSI_COLOR(0;7);
- doReset = 1;
- outs(reset);
- }
- else if (attr & EOATTR_MOVIECODE)
- {
- reset = ANSI_COLOR(0;36);
- doReset = 1;
- outs(reset);
- }
- else if (attr & EOATTR_BBSLUA)
- {
- reset = ANSI_COLOR(0;1;31);
- doReset = 1;
- outs(reset);
- }
- else if (attr & EOATTR_COMMENT)
- {
- reset = ANSI_COLOR(0;1;34);
- doReset = 1;
- outs(reset);
- }
-
-#ifdef DBCSAWARE
- /* 0 = N/A, 1 = leading byte printed, 2 = ansi in middle */
- register unsigned char isDBCS = 0;
-#endif
-
- while ((ch = *text++) && (++column < t_columns) && n-- > 0)
- {
- if(inAnsi == 1)
- {
- if(ch == ESC_CHR)
- outc('*');
- else
- {
- outc(ch);
-
- if(!ANSI_IN_ESCAPE(ch))
- {
- inAnsi = 0;
- outs(reset);
- }
- }
-
- }
- else if(ch == ESC_CHR)
- {
- inAnsi = 1;
-#ifdef DBCSAWARE
- if(isDBCS == 1)
- {
- isDBCS = 2;
- outs(ANSI_COLOR(1;33) "?");
- outs(reset);
- }
-#endif
- outs(ANSI_COLOR(1) "*");
- }
- else
- {
-#ifdef DBCSAWARE
- if(isDBCS == 1)
- isDBCS = 0;
- else if (isDBCS == 2)
- {
- /* ansi in middle. */
- outs(ANSI_COLOR(0;33) "?");
- outs(reset);
- isDBCS = 0;
- continue;
- }
- else
- if(IS_BIG5_HI(ch))
- {
- isDBCS = 1;
- // peak next char
- if(n > 0 && *text == ESC_CHR)
- continue;
- }
-#endif
- // Lua Parser!
- if (!attr && curr_buf->synparser && !fComment)
- {
- // syntax highlight!
- if (fSquareQuote) {
- if (ch == ']' && n > 0 && *(text) == ']')
- {
- fSquareQuote = 0;
- doReset = 0;
- // directly print quotes
- outc(ch); outc(ch);
- text++, n--;
- outs(ANSI_RESET);
- continue;
- }
- } else if (fSingleQuote) {
- if (ch == '\'')
- {
- fSingleQuote = 0;
- doReset = 0;
- // directly print quotes
- outc(ch);
- outs(ANSI_RESET);
- continue;
- }
- } else if (fDoubleQuote) {
- if (ch == '"')
- {
- fDoubleQuote = 0;
- doReset = 0;
- // directly print quotes
- outc(ch);
- outs(ANSI_RESET);
- continue;
- }
- } else if (ch == '-' && n > 0 && *(text) == '-') {
- fComment = 1;
- doReset = 1;
- outs(ANSI_COLOR(0;1;34));
- } else if (ch == '[' && n > 0 && *(text) == '[') {
- fSquareQuote = 1;
- doReset = 1;
- fWord = 0;
- outs(ANSI_COLOR(1;35));
- } else if (ch == '\'' || ch == '"') {
- if (ch == '"')
- fDoubleQuote = 1;
- else
- fSingleQuote = 1;
- doReset = 1;
- fWord = 0;
- outs(ANSI_COLOR(1;35));
- } else {
- // normal words
- if (fWord)
- {
- // inside a word.
- if (--fWord <= 0){
- fWord = 0;
- doReset = 0;
- outc(ch);
- outs(ANSI_RESET);
- continue;
- }
- } else if (isalnum(tolower(ch)) || ch == '#') {
- char attr[] = ANSI_COLOR(0;1;37);
- int x = synLuaKeyword(text-1, n+1, &fWord);
- if (fWord > 0)
- fWord --;
- if (x != 0)
- {
- // sorry, fixed string here.
- // 7 = *[0;1;3?
- if (x<0) { attr[4] = '0'; x= -x; }
- attr[7] = '0' + x;
- prints(attr);
- doReset = 1;
- }
- if (!fWord)
- {
- outc(ch);
- outs(ANSI_RESET);
- doReset = 0;
- continue;
- }
- }
- }
- }
- outc(ch);
- }
- }
-
- // this must be ANSI_RESET, not "reset".
- if(inAnsi || doReset)
- outs(ANSI_RESET);
-}
-
-static void
-edit_outs_attr(const char *text, int attr)
-{
- edit_outs_attr_n(text, scr_cols, attr);
-}
-
-static void
-edit_ansi_outs_n(const char *str, int n, int attr)
-{
- char c;
- while (n-- > 0 && (c = *str++)) {
- if(c == ESC_CHR && *str == '*')
- {
- // ptt prints
- /* Because moving within ptt_prints is too hard
- * let's just display it as-is.
- */
- outc('*');
- } else {
- outc(c);
- }
- }
-}
-
-static void
-edit_ansi_outs(const char *str, int attr)
-{
- return edit_ansi_outs_n(str, strlen(str), attr);
-}
-
-// old compatible API
-void
-edit_outs(const char *text)
-{
- edit_outs_attr(text, 0);
-}
-
-void
-edit_outs_n(const char *text, int n)
-{
- edit_outs_attr_n(text, n, 0);
-}
-
-
-#define PMORE_USE_ASCII_MOVIE // disable this if you don't enable ascii movie
-
-#ifdef PMORE_USE_ASCII_MOVIE
-// pmore movie header support
-unsigned char *
- mf_movieFrameHeader(unsigned char *p, unsigned char *end);
-
-#endif // PMORE_USE_ASCII_MOVIE
-
-static int
-detect_attr(const char *ps, size_t len)
-{
- int attr = 0;
-
-#ifdef PMORE_USE_ASCII_MOVIE
- if (mf_movieFrameHeader((unsigned char*)ps, (unsigned char*)ps+len))
- attr |= EOATTR_MOVIECODE;
-#endif
-#ifdef USE_BBSLUA
- if (bbslua_isHeader(ps, ps + len))
- {
- attr |= EOATTR_BBSLUA;
- if (!curr_buf->synparser)
- {
- curr_buf->synparser = 1;
- // if you need indent, toggle by hotkey.
- // enabling indent by default may cause trouble to copy pasters
- // curr_buf->indent_mode = 1;
- }
- }
-#endif
- return attr;
-}
-
-static inline void
-display_textline_internal(textline_t *p, int i)
-{
- short tmp;
- void (*output)(const char *, int) = edit_outs_attr;
- void (*output_n)(const char *, int, int)= edit_outs_attr_n;
-
- int attr = EOATTR_NORMAL;
-
- move(i, 0);
- clrtoeol();
-
- if (!p) {
- outc('~');
- outs(ANSI_CLRTOEND);
- return;
- }
-
- if (curr_buf->ansimode) {
- output = edit_ansi_outs;
- output_n = edit_ansi_outs_n;
- }
-
- tmp = curr_buf->currln - curr_buf->curr_window_line + i;
-
- // parse attribute of line
-
- // selected attribute?
- if (has_block_selection() &&
- ( (curr_buf->blockln <= curr_buf->currln &&
- curr_buf->blockln <= tmp && tmp <= curr_buf->currln) ||
- (curr_buf->currln <= tmp && tmp <= curr_buf->blockln)) )
- {
- // outs(ANSI_COLOR(7)); // remove me when EOATTR is ready...
- attr |= EOATTR_SELECTED;
- }
-
- attr |= detect_attr(p->data, p->len);
-
-#ifdef DBCSAWARE
- if(mbcs_mode && curr_buf->edit_margin > 0)
- {
- if(curr_buf->edit_margin >= p->len)
- {
- (*output)("", attr);
- } else {
-
- int newpnt = curr_buf->edit_margin;
- unsigned char *pdata = (unsigned char*)
- (&p->data[0] + curr_buf->edit_margin);
-
- if(mbcs_mode)
- newpnt = fix_cursor(p->data, newpnt, FC_LEFT);
-
- if(newpnt == curr_buf->edit_margin-1)
- {
- /* this should be always 'outs'? */
- // (*output)(ANSI_COLOR(1) "<" ANSI_RESET);
- outs(ANSI_COLOR(1) "<" ANSI_RESET);
- pdata++;
- }
- (*output)((char*)pdata, attr);
- }
-
- } else
-#endif
- (*output)((curr_buf->edit_margin < p->len) ?
- &p->data[curr_buf->edit_margin] : "", attr);
-
- if (attr)
- outs(ANSI_RESET);
-
- // workaround poor terminal
- outs(ANSI_CLRTOEND);
-}
-
-static void
-refresh_window(void)
-{
- register textline_t *p;
- register int i;
-
- for (p = curr_buf->top_of_win, i = 0; i < b_lines; i++) {
- display_textline_internal(p, i);
-
- if (p)
- p = p->next;
- }
- edit_msg();
-}
-
-static void
-goto_line(int lino)
-{
- if (lino > 0 && lino <= curr_buf->totaln + 1) {
- textline_t *p;
-
- p = curr_buf->firstline;
- curr_buf->currln = lino - 1;
-
- while (--lino && p->next)
- p = p->next;
-
- if (p)
- curr_buf->currline = p;
- else {
- curr_buf->currln = curr_buf->totaln;
- curr_buf->currline = curr_buf->lastline;
- }
-
- curr_buf->currpnt = 0;
-
- /* move window */
- if (curr_buf->currln < middle_line()) {
- curr_buf->top_of_win = curr_buf->firstline;
- curr_buf->curr_window_line = curr_buf->currln;
- } else {
- int i;
- curr_buf->curr_window_line = middle_line();
- for (i = curr_buf->curr_window_line; i; i--)
- p = p->prev;
- curr_buf->top_of_win = p;
- }
- }
- curr_buf->redraw_everything = YEA;
-}
-
-static void
-prompt_goto_line(void)
-{
- char buf[10];
-
- if (getdata(b_lines - 1, 0, "¸õ¦Ü²Ä´X¦æ:", buf, sizeof(buf), DOECHO))
- goto_line(atoi(buf));
-}
-
-/**
- * search string interactively.
- * @param mode 0: prompt
- * 1: forward
- * -1: backward
- */
-static void
-search_str(int mode)
-{
- const int max_keyword = 65;
- char *str;
- char ans[4] = "n";
-
- if (curr_buf->searched_string == NULL) {
- if (mode != 0)
- return;
- curr_buf->searched_string = (char *)malloc(max_keyword * sizeof(char));
- curr_buf->searched_string[0] = 0;
- }
-
- str = curr_buf->searched_string;
-
- if (!mode) {
- if (getdata_buf(b_lines - 1, 0, "[·j´M]ÃöÁä¦r:",
- str, max_keyword, DOECHO))
- if (*str) {
- if (getdata(b_lines - 1, 0, "°Ï¤À¤j¤p¼g(Y/N/Q)? [N] ",
- ans, sizeof(ans), LCECHO) && *ans == 'y')
- curr_buf->substr_fp = strstr;
- else
- curr_buf->substr_fp = strcasestr;
- }
- }
- if (*str && *ans != 'q') {
- textline_t *p;
- char *pos = NULL;
- int lino;
-
- if (mode >= 0) {
- for (lino = curr_buf->currln, p = curr_buf->currline; p; p = p->next, lino++)
- if ((pos = (*curr_buf->substr_fp)(p->data + (lino == curr_buf->currln ? curr_buf->currpnt + 1 : 0),
- str)) && (lino != curr_buf->currln ||
- pos - p->data != curr_buf->currpnt))
- break;
- } else {
- for (lino = curr_buf->currln, p = curr_buf->currline; p; p = p->prev, lino--)
- if ((pos = (*curr_buf->substr_fp)(p->data, str)) &&
- (lino != curr_buf->currln || pos - p->data != curr_buf->currpnt))
- break;
- }
- if (pos) {
- /* move window */
- curr_buf->currline = p;
- curr_buf->currln = lino;
- curr_buf->currpnt = pos - p->data;
- if (lino < middle_line()) {
- curr_buf->top_of_win = curr_buf->firstline;
- curr_buf->curr_window_line = curr_buf->currln;
- } else {
- int i;
-
- curr_buf->curr_window_line = middle_line();
- for (i = curr_buf->curr_window_line; i; i--)
- p = p->prev;
- curr_buf->top_of_win = p;
- }
- curr_buf->redraw_everything = YEA;
- }
- }
- if (!mode)
- curr_buf->redraw_everything = YEA;
-}
-
-/**
- * move the cursor from bracket to corresponding bracket.
- */
-static void
-match_paren(void)
-{
- char *parens = "()[]{}";
- int type;
- int parenum = 0;
- char *ptype;
- textline_t *p;
- int lino;
- int c, i = 0;
-
- if (!(ptype = strchr(parens, curr_buf->currline->data[curr_buf->currpnt])))
- return;
-
- type = (ptype - parens) / 2;
- parenum = ((ptype - parens) % 2) ? -1 : 1;
-
- /* FIXME CRASH */
- /* FIXME refactoring */
- if (parenum > 0) {
- for (lino = curr_buf->currln, p = curr_buf->currline; p; p = p->next, lino++) {
- int len = strlen(p->data);
- for (i = (lino == curr_buf->currln) ? curr_buf->currpnt + 1 : 0; i < len; i++) {
- if (p->data[i] == '/' && p->data[++i] == '*') {
- ++i;
- while (1) {
- while (i < len &&
- !(p->data[i] == '*' && p->data[i + 1] == '/')) {
- i++;
- }
- if (i >= len && p->next) {
- p = p->next;
- len = strlen(p->data);
- ++lino;
- i = 0;
- } else
- break;
- }
- } else if ((c = p->data[i]) == '\'' || c == '"') {
- while (1) {
- while (i < len - 1) {
- if (p->data[++i] == '\\' && (size_t)i < len - 2)
- ++i;
- else if (p->data[i] == c)
- goto end_quote;
- }
- if ((size_t)i >= len - 1 && p->next) {
- p = p->next;
- len = strlen(p->data);
- ++lino;
- i = -1;
- } else
- break;
- }
- end_quote:
- ;
- } else if ((ptype = strchr(parens, p->data[i])) &&
- (ptype - parens) / 2 == type) {
- if (!(parenum += ((ptype - parens) % 2) ? -1 : 1))
- goto p_outscan;
- }
- }
- }
- } else {
- for (lino = curr_buf->currln, p = curr_buf->currline; p; p = p->prev, lino--) {
- int len = strlen(p->data);
- for (i = ((lino == curr_buf->currln) ? curr_buf->currpnt - 1 : len - 1); i >= 0; i--) {
- if (p->data[i] == '/' && p->data[--i] == '*' && i > 0) {
- --i;
- while (1) {
- while (i > 0 &&
- !(p->data[i] == '*' && p->data[i - 1] == '/')) {
- i--;
- }
- if (i <= 0 && p->prev) {
- p = p->prev;
- len = strlen(p->data);
- --lino;
- i = len - 1;
- } else
- break;
- }
- } else if ((c = p->data[i]) == '\'' || c == '"') {
- while (1) {
- while (i > 0)
- if (i > 1 && p->data[i - 2] == '\\')
- i -= 2;
- else if ((p->data[--i]) == c)
- goto begin_quote;
- if (i <= 0 && p->prev) {
- p = p->prev;
- len = strlen(p->data);
- --lino;
- i = len;
- } else
- break;
- }
-begin_quote:
- ;
- } else if ((ptype = strchr(parens, p->data[i])) &&
- (ptype - parens) / 2 == type) {
- if (!(parenum += ((ptype - parens) % 2) ? -1 : 1))
- goto p_outscan;
- }
- }
- }
- }
-p_outscan:
- if (!parenum) {
- int top = curr_buf->currln - curr_buf->curr_window_line;
- int bottom = curr_buf->currln - curr_buf->curr_window_line + b_lines - 1;
-
- curr_buf->currpnt = i;
- curr_buf->currline = p;
- curr_buf->curr_window_line += lino - curr_buf->currln;
- curr_buf->currln = lino;
-
- if (lino < top || lino > bottom) {
- if (lino < middle_line()) {
- curr_buf->top_of_win = curr_buf->firstline;
- curr_buf->curr_window_line = curr_buf->currln;
- } else {
- int i;
-
- curr_buf->curr_window_line = middle_line();
- for (i = curr_buf->curr_window_line; i; i--)
- p = p->prev;
- curr_buf->top_of_win = p;
- }
- curr_buf->redraw_everything = YEA;
- }
- }
-}
-
-static void
-currline_shift_left(void)
-{
- int currpnt0;
-
- if (curr_buf->currline->len <= 0)
- return;
-
- currpnt0 = curr_buf->currpnt;
- curr_buf->currpnt = 0;
- delete_char();
- curr_buf->currpnt = (currpnt0 <= curr_buf->currline->len) ? currpnt0 : currpnt0 - 1;
- if (curr_buf->ansimode)
- curr_buf->currpnt = ansi2n(n2ansi(curr_buf->currpnt, curr_buf->currline), curr_buf->currline);
-}
-
-static void
-currline_shift_right(void)
-{
- int currpnt0;
-
- if (curr_buf->currline->len >= WRAPMARGIN - 1)
- return;
-
- currpnt0 = curr_buf->currpnt;
- curr_buf->currpnt = 0;
- insert_char(' ');
- curr_buf->currpnt = currpnt0;
-}
-
-static void
-cursor_to_next_word(void)
-{
- while (curr_buf->currpnt < curr_buf->currline->len &&
- isalnum((int)curr_buf->currline->data[++curr_buf->currpnt]));
- while (curr_buf->currpnt < curr_buf->currline->len &&
- isspace((int)curr_buf->currline->data[++curr_buf->currpnt]));
-}
-
-static void
-cursor_to_prev_word(void)
-{
- while (curr_buf->currpnt && isspace((int)curr_buf->currline->data[--curr_buf->currpnt]));
- while (curr_buf->currpnt && isalnum((int)curr_buf->currline->data[--curr_buf->currpnt]));
- if (curr_buf->currpnt > 0)
- curr_buf->currpnt++;
-}
-
-static void
-delete_current_word(void)
-{
- while (curr_buf->currpnt < curr_buf->currline->len) {
- delete_char();
- if (!isalnum((int)curr_buf->currline->data[curr_buf->currpnt]))
- break;
- }
- while (curr_buf->currpnt < curr_buf->currline->len) {
- delete_char();
- if (!isspace((int)curr_buf->currline->data[curr_buf->currpnt]))
- break;
- }
-}
-
-/**
- * transform every "*[" in given string to KEY_ESC "["
- */
-static void
-transform_to_color(char *line)
-{
- while (line[0] && line[1])
- if (line[0] == '*' && line[1] == '[') {
- line[0] = KEY_ESC;
- line += 2;
- } else
- ++line;
-}
-
-static void
-block_color(void)
-{
- textline_t *begin, *end, *p;
-
- setup_block_begin_end(&begin, &end);
-
- p = begin;
- while (1) {
- // FIXME CRASH p will be NULL here.
- assert(p);
- transform_to_color(p->data);
- if (p == end)
- break;
- else
- p = p->next;
- }
- block_cancel();
-}
-
-/**
- * insert ansi code
- */
-static void
-insert_ansi_code(void)
-{
- int ch = curr_buf->insert_mode;
- curr_buf->insert_mode = curr_buf->redraw_everything = YEA;
- if (!curr_buf->ansimode)
- insert_string(reset_color);
- else {
- char ans[4];
- move(b_lines - 2, 55);
- outs(ANSI_COLOR(1;33;40) "B" ANSI_COLOR(41) "R" ANSI_COLOR(42) "G" ANSI_COLOR(43) "Y" ANSI_COLOR(44) "L"
- ANSI_COLOR(45) "P" ANSI_COLOR(46) "C" ANSI_COLOR(47) "W" ANSI_RESET);
- if (getdata(b_lines - 1, 0,
- "½Ð¿é¤J «G«×/«e´º/­I´º[¥¿±`¥Õ¦r¶Â©³][0wb]¡G",
- ans, sizeof(ans), LCECHO))
- {
- const char t[] = "BRGYLPCW";
- char color[15];
- char *tmp, *apos = ans;
- int fg, bg;
-
- strcpy(color, ESC_STR "[");
- if (isdigit((int)*apos)) {
- sprintf(color,"%s%c", color, *(apos++));
- if (*apos)
- strcat(color, ";");
- }
- if (*apos) {
- if ((tmp = strchr(t, toupper(*(apos++)))))
- fg = tmp - t + 30;
- else
- fg = 37;
- sprintf(color, "%s%d", color, fg);
- }
- if (*apos) {
- if ((tmp = strchr(t, toupper(*(apos++)))))
- bg = tmp - t + 40;
- else
- bg = 40;
- sprintf(color, "%s;%d", color, bg);
- }
- strcat(color, "m");
- insert_string(color);
- } else
- insert_string(reset_color);
- }
- curr_buf->insert_mode = ch;
-}
-
-static inline void
-phone_mode_switch(void)
-{
- if (curr_buf->phone_mode)
- curr_buf->phone_mode = 0;
- else {
- curr_buf->phone_mode = 1;
- if (!curr_buf->last_phone_mode)
- curr_buf->last_phone_mode = 2;
- }
-}
-
-/**
- * return coresponding phone char of given key c
- */
-static const char*
-phone_char(char c)
-{
- if (curr_buf->last_phone_mode > 0 && curr_buf->last_phone_mode < 20) {
- if (tolower(c)<'a'||(tolower(c)-'a') >= strlen(BIG5[curr_buf->last_phone_mode - 1]) / 2)
- return 0;
- return BIG5[curr_buf->last_phone_mode - 1] + (tolower(c) - 'a') * 2;
- }
- else if (curr_buf->last_phone_mode >= 20) {
- if (c == '.') c = '/';
-
- if (c < '/' || c > '9')
- return 0;
-
- return table[curr_buf->last_phone_mode - 20] + (c - '/') * 2;
- }
- return 0;
-}
-
-/**
- * When get the key for phone mode, handle it (e.g. edit_msg) and return the
- * key. Otherwise return 0.
- */
-static inline char
-phone_mode_filter(char ch)
-{
- if (!curr_buf->phone_mode)
- return 0;
-
- switch (ch) {
- case 'z':
- case 'Z':
- if (curr_buf->last_phone_mode < 20)
- curr_buf->last_phone_mode = 20;
- else
- curr_buf->last_phone_mode = 2;
- edit_msg();
- return ch;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- if (curr_buf->last_phone_mode < 20) {
- curr_buf->last_phone_mode = ch - '0' + 1;
- curr_buf->redraw_everything = YEA;
- return ch;
- }
- break;
- case '-':
- if (curr_buf->last_phone_mode < 20) {
- curr_buf->last_phone_mode = 11;
- curr_buf->redraw_everything = YEA;
- return ch;
- }
- break;
- case '=':
- if (curr_buf->last_phone_mode < 20) {
- curr_buf->last_phone_mode = 12;
- curr_buf->redraw_everything = YEA;
- return ch;
- }
- break;
- case '`':
- if (curr_buf->last_phone_mode < 20) {
- curr_buf->last_phone_mode = 13;
- curr_buf->redraw_everything = YEA;
- return ch;
- }
- break;
- case '/':
- if (curr_buf->last_phone_mode >= 20) {
- curr_buf->last_phone_mode += 4;
- if (curr_buf->last_phone_mode > 27)
- curr_buf->last_phone_mode -= 8;
- curr_buf->redraw_everything = YEA;
- return ch;
- }
- break;
- case '*':
- if (curr_buf->last_phone_mode >= 20) {
- curr_buf->last_phone_mode++;
- if ((curr_buf->last_phone_mode - 21) % 4 == 3)
- curr_buf->last_phone_mode -= 4;
- curr_buf->redraw_everything = YEA;
- return ch;
- }
- break;
- }
-
- return 0;
-}
-
-#ifdef EXP_EDIT_UPLOAD
-
-static void
-upload_file(void)
-{
- size_t szdata = 0;
- int c = 1;
- char promptmsg = 0;
-
- clear();
- block_cancel();
- stand_title("¤W¶Ç¤å¦rÀÉ®×");
- move(3,0);
- outs("§Q¥Î¥»ªA°È±z¥i¥H¤W¶Ç¸û¤jªº¤å¦rÀÉ (¦ý¤£­p¤J½Z¶O)¡C\n"
- "\n"
- "¤W¶Ç´Á¶¡±z¥´ªº¦r¼È®É¤£·|¥X²{¦b¿Ã¹õ¤W¡A°£¤F Ctrl-U ·|³QÂà´«¬° ANSI \n"
- "±±¨î½Xªº ESC ¥~¡A¨ä¥¦¯S®íÁä¤@«ß¨S¦³§@¥Î¡C\n"
- "\n"
- "½Ð¦b±zªº¹q¸£¥»¾÷ºÝ½Æ»s¦n¤º®e«á¶K¤W§Y¥i¶}©l¶Ç°e¡C\n");
-
- do {
- if (!num_in_buf())
- {
- move(10, 0); clrtobot();
- prints("\n\n¸ê®Æ±µ¦¬¤¤... %u ¦ì¤¸²Õ¡C\n", (unsigned int)szdata);
- outs(ANSI_COLOR(1)
- "¡»¥þ³¡§¹¦¨«á«ö¤U End ©Î ^X/^Q/^C §Y¥i¦^¨ì½s¿èµe­±¡C"
- ANSI_RESET "\n");
- promptmsg = 0;
- }
-
- c = igetch();
- if (c < 0x100 && isprint2(c))
- {
- insert_char(c);
- szdata ++;
- }
- else if (c == Ctrl('U') || c == ESC_CHR)
- {
- insert_char(ESC_CHR);
- szdata ++;
- }
- else if (c == Ctrl('I'))
- {
- insert_tab();
- szdata ++;
- }
- else if (c == '\r' || c == '\n')
- {
- split(curr_buf->currline, curr_buf->currpnt);
- curr_buf->oldcurrline = curr_buf->currline;
- szdata ++;
- promptmsg = 1;
- }
-
- if (!promptmsg)
- promptmsg = (szdata && szdata % 1024 == 0);
-
- // all other keys are ignored.
- } while (c != KEY_END && c != Ctrl('X') &&
- c != Ctrl('C') && c != Ctrl('Q') &&
- curr_buf->totaln <= EDIT_LINE_LIMIT &&
- szdata <= EDIT_SIZE_LIMIT);
-
- move(12, 0);
- prints("¶Ç°eµ²§ô: ¦¬¨ì %u ¦ì¤¸²Õ¡C", (unsigned int)szdata);
- vmsgf("¦^¨ì½s¿èµe­±");
-}
-
-#endif // EXP_EDIT_UPLOAD
-
-
-/* ½s¿è³B²z¡G¥Dµ{¦¡¡BÁä½L³B²z */
-int
-vedit2(char *fpath, int saveheader, int *islocal, int flags)
-{
- char last = 0; /* the last key you press */
- int ch, tmp;
-
- int mode0 = currutmp->mode;
- int destuid0 = currutmp->destuid;
- int money = 0;
- int interval = 0;
- time4_t th = now;
- int count = 0, tin = 0, quoted = 0;
- char trans_buffer[256];
- char mytitle[STRLEN];
-
- STATINC(STAT_VEDIT);
- currutmp->mode = EDITING;
- currutmp->destuid = currstat;
-
- strlcpy(mytitle, save_title, sizeof(mytitle));
-
-#ifdef DBCSAWARE
- mbcs_mode = (cuser.uflag & DBCSAWARE_FLAG) ? 1 : 0;
-#endif
-
- enter_edit_buffer();
-
- curr_buf->oldcurrline = curr_buf->currline = curr_buf->top_of_win =
- curr_buf->firstline = curr_buf->lastline = alloc_line(WRAPMARGIN);
-
- if (*fpath) {
- read_file(fpath, (flags & EDITFLAG_TEXTONLY) ? 1 : 0);
- }
-
- if (*quote_file) {
- do_quote();
- *quote_file = '\0';
- quoted = 1;
- }
-
- if( curr_buf->oldcurrline != curr_buf->firstline ||
- curr_buf->currline != curr_buf->firstline) {
- /* we must adjust because cursor (currentline) moved. */
- curr_buf->oldcurrline = curr_buf->currline = curr_buf->top_of_win =
- curr_buf->firstline= adjustline(curr_buf->firstline, WRAPMARGIN);
- }
-
- /* No matter you quote or not, just start the cursor from (0,0) */
- curr_buf->currpnt = curr_buf->currln = curr_buf->curr_window_line =
- curr_buf->edit_margin = curr_buf->last_margin = 0;
-
- /* if quote, move to end of file. */
- if(quoted)
- {
- /* maybe do this in future. */
- }
-
- while (1) {
- if (curr_buf->redraw_everything || has_block_selection()) {
- refresh_window();
- curr_buf->redraw_everything = NA;
- }
- if( curr_buf->oldcurrline != curr_buf->currline ){
- curr_buf->oldcurrline = adjustline(curr_buf->oldcurrline, curr_buf->oldcurrline->len);
- curr_buf->oldcurrline = curr_buf->currline = adjustline(curr_buf->currline, WRAPMARGIN);
- }
-
- if (curr_buf->ansimode)
- ch = n2ansi(curr_buf->currpnt, curr_buf->currline);
- else
- ch = curr_buf->currpnt - curr_buf->edit_margin;
- move(curr_buf->curr_window_line, ch);
-
-#if 0 // DEPRECATED, it's really not a well known expensive feature
- if (!curr_buf->line_dirty && strcmp(editline, curr_buf->currline->data))
- strcpy(editline, curr_buf->currline->data);
-#endif
-
- ch = igetch();
- /* jochang debug */
- if ((interval = (now - th))) {
- th = now;
- if ((char)ch != last) {
- money++;
- last = (char)ch;
- }
- }
- if (interval && interval == tin)
- { // Ptt : +- 1 ¬í¤]ºâ
- count++;
- if(count>60)
- {
- money = 0;
- count = 0;
-/*
- log_file("etc/illegal_money", LOG_CREAT | LOG_VF,
- ANSI_COLOR(1;33;46) "%s " ANSI_COLOR(37;45) " ¥Î¾÷¾¹¤Hµoªí¤å³¹ " ANSI_COLOR(37) " %s" ANSI_RESET "\n",
- cuser.userid, ctime4(&now));
- post_violatelaw(cuser.userid, BBSMNAME "¨t²Îĵ¹î",
- "¥Î¾÷¾¹¤Hµoªí¤å³¹", "±j¨îÂ÷¯¸");
- abort_bbs(0);
-*/
- }
- }
- else if(interval){
- count = 0;
- tin = interval;
- }
-#ifndef DBCSAWARE
- /* this is almost useless! */
- if (curr_buf->raw_mode) {
- switch (ch) {
- case Ctrl('S'):
- case Ctrl('Q'):
- case Ctrl('T'):
- continue;
- }
- }
-#endif
-
- if (phone_mode_filter(ch))
- continue;
-
- if (ch < 0x100 && isprint2(ch)) {
- const char *pstr;
- if(curr_buf->phone_mode && (pstr=phone_char(ch)))
- insert_dchar(pstr);
- else
- insert_char(ch);
- curr_buf->lastindent = -1;
- } else {
- if (ch == KEY_UP || ch == KEY_DOWN ){
- if (curr_buf->lastindent == -1)
- curr_buf->lastindent = curr_buf->currpnt;
- } else
- curr_buf->lastindent = -1;
- if (ch == KEY_ESC)
- switch (KEY_ESC_arg) {
- case ',':
- ch = Ctrl(']');
- break;
- case '.':
- ch = Ctrl('T');
- break;
- case 'v':
- ch = KEY_PGUP;
- break;
- case 'a':
- case 'A':
- ch = Ctrl('V');
- break;
- case 'X':
- ch = Ctrl('X');
- break;
- case 'q':
- ch = Ctrl('Q');
- break;
- case 'o':
- ch = Ctrl('O');
- break;
-#if 0 // DEPRECATED, it's really not a well known expensive feature
- case '-':
- ch = Ctrl('_');
- break;
-#endif
- case 's':
- ch = Ctrl('S');
- break;
- }
-
- switch (ch) {
- case KEY_F10:
- case Ctrl('X'): /* Save and exit */
- tmp = write_file(fpath, saveheader, islocal, mytitle,
- (flags & EDITFLAG_UPLOAD) ? 1 : 0,
- (flags & EDITFLAG_ALLOWTITLE) ? 1 : 0);
- if (tmp != KEEP_EDITING) {
- strlcpy(save_title, mytitle, sizeof(save_title));
- save_title[STRLEN-1] = 0;
- currutmp->mode = mode0;
- currutmp->destuid = destuid0;
-
- exit_edit_buffer();
- if (!tmp)
- return money;
- else
- return tmp;
- }
- curr_buf->oldcurrline = curr_buf->currline;
- curr_buf->redraw_everything = YEA;
- break;
- case KEY_F5:
- prompt_goto_line();
- curr_buf->redraw_everything = YEA;
- break;
- case KEY_F8:
- t_users();
- curr_buf->redraw_everything = YEA;
- break;
- case Ctrl('W'):
- block_cut();
- // curr_buf->oldcurrline is freed in block_cut, and currline is
- // well adjusted now. This will avoid re-adjusting later.
- // It's not a good implementation, try to find a better
- // solution!
- curr_buf->oldcurrline = curr_buf->currline;
- break;
- case Ctrl('Q'): /* Quit without saving */
- grayout(0, b_lines-1, GRAYOUT_DARK);
- ch = vmsg("µ²§ô¦ý¤£Àx¦s [y/N]? ");
- if (ch == 'y' || ch == 'Y') {
- currutmp->mode = mode0;
- currutmp->destuid = destuid0;
- exit_edit_buffer();
- return -1;
- }
- curr_buf->redraw_everything = YEA;
- break;
- case Ctrl('C'):
- insert_ansi_code();
- break;
- case KEY_ESC:
- switch (KEY_ESC_arg) {
- case 'U':
- t_users();
- curr_buf->redraw_everything = YEA;
- break;
- case 'i':
- t_idle();
- curr_buf->redraw_everything = YEA;
- break;
- case 'n':
- search_str(1);
- break;
- case 'p':
- search_str(-1);
- break;
- case 'L':
- case 'J':
- prompt_goto_line();
- curr_buf->redraw_everything = YEA;
- break;
- case ']':
- match_paren();
- break;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- read_tmpbuf(KEY_ESC_arg - '0');
- curr_buf->oldcurrline = curr_buf->currline;
- curr_buf->redraw_everything = YEA;
- break;
- case 'l': /* block delete */
- case ' ':
- if (has_block_selection()) {
- block_prompt();
- // curr_buf->oldcurrline is freed in block_cut, and currline is
- // well adjusted now. This will avoid re-adjusting later.
- // It's not a good implementation, try to find a better
- // solution!
- curr_buf->oldcurrline = curr_buf->currline;
- }
- else
- block_select();
- break;
- case 'u':
- block_cancel();
- break;
- case 'c':
- block_copy();
- break;
- case 'y':
- curr_buf->oldcurrline = undelete_line();
- if (curr_buf->oldcurrline == NULL)
- curr_buf->oldcurrline = curr_buf->currline;
- break;
- case 'R':
-#ifdef DBCSAWARE
- case 'r':
- mbcs_mode =! mbcs_mode;
-#endif
- curr_buf->raw_mode ^= 1;
- break;
- case 'I':
- curr_buf->indent_mode ^= 1;
- break;
- case 'j':
- currline_shift_left();
- break;
- case 'k':
- currline_shift_right();
- break;
- case 'f':
- cursor_to_next_word();
- break;
- case 'b':
- cursor_to_prev_word();
- break;
- case 'd':
- delete_current_word();
- break;
- }
- break;
- case Ctrl('S'):
- case KEY_F3:
- search_str(0);
- break;
- case Ctrl('U'):
- insert_char(ESC_CHR);
- break;
- case Ctrl('V'): /* Toggle ANSI color */
- curr_buf->ansimode ^= 1;
- if (curr_buf->ansimode && has_block_selection())
- block_color();
- clear();
- curr_buf->redraw_everything = YEA;
- break;
- case Ctrl('I'):
- insert_tab();
- break;
- case '\r':
- case '\n':
- block_cancel();
- if (curr_buf->totaln >= EDIT_LINE_LIMIT)
- {
- vmsg("Àɮפw¶W¹L³Ì¤j­­¨î¡AµLªk¦A¼W¥[¦æ¼Æ¡C");
- break;
- }
-
-#ifdef MAX_EDIT_LINE
- if(curr_buf->totaln ==
- ((flags & EDITFLAG_ALLOWLARGE) ?
- MAX_EDIT_LINE_LARGE : MAX_EDIT_LINE))
- {
- vmsg("¤w¨ì¹F³Ì¤j¦æ¼Æ­­¨î¡C");
- break;
- }
-#endif
- split(curr_buf->currline, curr_buf->currpnt);
- curr_buf->oldcurrline = curr_buf->currline;
- break;
- case Ctrl('G'):
- {
- unsigned int currstat0 = currstat;
- setutmpmode(EDITEXP);
- a_menu("½s¿è»²§U¾¹", "etc/editexp",
- (HasUserPerm(PERM_SYSOP) ? SYSOP : NOBODY),
- 0,
- trans_buffer);
- currstat = currstat0;
- }
- if (trans_buffer[0]) {
- FILE *fp1;
- if ((fp1 = fopen(trans_buffer, "r"))) {
- int indent_mode0 = curr_buf->indent_mode;
- char buf[WRAPMARGIN + 2];
-
- curr_buf->indent_mode = 0;
- while (fgets(buf, sizeof(buf), fp1)) {
- if (!strncmp(buf, "§@ªÌ:", 5) ||
- !strncmp(buf, "¼ÐÃD:", 5) ||
- !strncmp(buf, "®É¶¡:", 5))
- continue;
- insert_string(buf);
- }
- fclose(fp1);
- curr_buf->indent_mode = indent_mode0;
- while (curr_buf->curr_window_line >= b_lines) {
- curr_buf->curr_window_line--;
- curr_buf->top_of_win = curr_buf->top_of_win->next;
- }
- }
- }
- curr_buf->redraw_everything = YEA;
- break;
- case Ctrl('P'):
- phone_mode_switch();
- curr_buf->redraw_everything = YEA;
- break;
-
- case KEY_F1:
- case Ctrl('Z'): /* Help */
- more("etc/ve.hlp", YEA);
- curr_buf->redraw_everything = YEA;
- break;
- case Ctrl('L'):
- clear();
- curr_buf->redraw_everything = YEA;
- break;
- case KEY_LEFT:
- if (curr_buf->currpnt) {
- if (curr_buf->ansimode)
- curr_buf->currpnt = n2ansi(curr_buf->currpnt, curr_buf->currline);
- curr_buf->currpnt--;
- if (curr_buf->ansimode)
- curr_buf->currpnt = ansi2n(curr_buf->currpnt, curr_buf->currline);
-#ifdef DBCSAWARE
- if(mbcs_mode)
- curr_buf->currpnt = fix_cursor(curr_buf->currline->data, curr_buf->currpnt, FC_LEFT);
-#endif
- } else if (curr_buf->currline->prev) {
- curr_buf->curr_window_line--;
- curr_buf->currln--;
- curr_buf->currline = curr_buf->currline->prev;
- curr_buf->currpnt = curr_buf->currline->len;
- }
- break;
- case KEY_RIGHT:
- if (curr_buf->currline->len != curr_buf->currpnt) {
- if (curr_buf->ansimode)
- curr_buf->currpnt = n2ansi(curr_buf->currpnt, curr_buf->currline);
- curr_buf->currpnt++;
- if (curr_buf->ansimode)
- curr_buf->currpnt = ansi2n(curr_buf->currpnt, curr_buf->currline);
-#ifdef DBCSAWARE
- if(mbcs_mode)
- curr_buf->currpnt = fix_cursor(curr_buf->currline->data, curr_buf->currpnt, FC_RIGHT);
-#endif
- } else if (curr_buf->currline->next) {
- curr_buf->currpnt = 0;
- curr_buf->curr_window_line++;
- curr_buf->currln++;
- curr_buf->currline = curr_buf->currline->next;
- }
- break;
- case KEY_UP:
- cursor_to_prev_line();
- break;
- case KEY_DOWN:
- cursor_to_next_line();
- break;
-
- case Ctrl('B'):
- case KEY_PGUP: {
- short tmp = curr_buf->currln;
- curr_buf->top_of_win = back_line(curr_buf->top_of_win, t_lines - 2);
- curr_buf->currln = tmp;
- curr_buf->currline = back_line(curr_buf->currline, t_lines - 2);
- curr_buf->curr_window_line = get_lineno_in_window();
- if (curr_buf->currpnt > curr_buf->currline->len)
- curr_buf->currpnt = curr_buf->currline->len;
- curr_buf->redraw_everything = YEA;
- break;
- }
-
- case Ctrl('F'):
- case KEY_PGDN: {
- short tmp = curr_buf->currln;
- curr_buf->top_of_win = forward_line(curr_buf->top_of_win, t_lines - 2);
- curr_buf->currln = tmp;
- curr_buf->currline = forward_line(curr_buf->currline, t_lines - 2);
- curr_buf->curr_window_line = get_lineno_in_window();
- if (curr_buf->currpnt > curr_buf->currline->len)
- curr_buf->currpnt = curr_buf->currline->len;
- curr_buf->redraw_everything = YEA;
- break;
- }
-
- case KEY_END:
- case Ctrl('E'):
- curr_buf->currpnt = curr_buf->currline->len;
- break;
- case Ctrl(']'): /* start of file */
- curr_buf->currline = curr_buf->top_of_win = curr_buf->firstline;
- curr_buf->currpnt = curr_buf->currln = curr_buf->curr_window_line = 0;
- curr_buf->redraw_everything = YEA;
- break;
- case Ctrl('T'): /* tail of file */
- curr_buf->top_of_win = back_line(curr_buf->lastline, t_lines - 1);
- curr_buf->currline = curr_buf->lastline;
- curr_buf->curr_window_line = get_lineno_in_window();
- curr_buf->currln = curr_buf->totaln;
- curr_buf->redraw_everything = YEA;
- curr_buf->currpnt = 0;
- break;
- case KEY_HOME:
- case Ctrl('A'):
- curr_buf->currpnt = 0;
- break;
- case Ctrl('O'): // better not use ^O - UNIX not sending.
- case KEY_INS: /* Toggle insert/overwrite */
- if (has_block_selection() && curr_buf->insert_mode) {
- char ans[4];
-
- getdata(b_lines - 1, 0,
- "°Ï¶ô·L½Õ¥k²¾´¡¤J¦r¤¸(¹w³]¬°ªÅ¥Õ¦r¤¸)",
- ans, sizeof(ans), LCECHO);
- curr_buf->insert_c = ans[0] ? ans[0] : ' ';
- }
- curr_buf->insert_mode ^= 1;
- break;
- case Ctrl('H'):
- case '\177': /* backspace */
- block_cancel();
- if (curr_buf->ansimode) {
- curr_buf->ansimode = 0;
- clear();
- curr_buf->redraw_everything = YEA;
- } else {
- if (curr_buf->currpnt == 0) {
- if (!curr_buf->currline->prev)
- break;
- curr_buf->curr_window_line--;
- curr_buf->currln--;
-
- curr_buf->currline = adjustline(curr_buf->currline, curr_buf->currline->len);
- curr_buf->currline = curr_buf->currline->prev;
- curr_buf->currline = adjustline(curr_buf->currline, WRAPMARGIN);
- curr_buf->oldcurrline = curr_buf->currline;
-
- curr_buf->currpnt = curr_buf->currline->len;
- curr_buf->redraw_everything = YEA;
- if (curr_buf->currline->next == curr_buf->top_of_win) {
- curr_buf->top_of_win = curr_buf->currline;
- curr_buf->curr_window_line = 0;
- }
- if (*next_non_space_char(curr_buf->currline->next->data) == '\0') {
- delete_line(curr_buf->currline->next, 0);
- break;
- }
- join(curr_buf->currline);
- break;
- }
-#ifndef DBCSAWARE
- curr_buf->currpnt--;
- delete_char();
-#else
- {
- int newpnt = curr_buf->currpnt - 1;
-
- if(mbcs_mode)
- newpnt = fix_cursor(curr_buf->currline->data, newpnt, FC_LEFT);
-
- for(; curr_buf->currpnt > newpnt;)
- {
- curr_buf->currpnt --;
- delete_char();
- }
- }
-#endif
- }
- break;
- case Ctrl('D'):
- case KEY_DEL: /* delete current character */
- block_cancel();
- if (curr_buf->currline->len == curr_buf->currpnt) {
- join(curr_buf->currline);
- curr_buf->redraw_everything = YEA;
- } else {
-#ifndef DBCSAWARE
- delete_char();
-#else
- {
- int w = 1;
-
- if(mbcs_mode)
- w = mchar_len((unsigned char*)(curr_buf->currline->data + curr_buf->currpnt));
-
- for(; w > 0; w --)
- delete_char();
- }
-#endif
- if (curr_buf->ansimode)
- curr_buf->currpnt = ansi2n(n2ansi(curr_buf->currpnt, curr_buf->currline), curr_buf->currline);
- }
- break;
- case Ctrl('Y'): /* delete current line */
- curr_buf->currline->len = curr_buf->currpnt = 0;
- case Ctrl('K'): /* delete to end of line */
- block_cancel();
- if (curr_buf->currline->len == 0) {
- textline_t *p = curr_buf->currline->next;
- if (!p) {
- p = curr_buf->currline->prev;
- if (!p) {
- curr_buf->currline->data[0] = 0;
- break;
- }
- if (curr_buf->curr_window_line > 0) {
- curr_buf->curr_window_line--;
- }
- curr_buf->currln--;
- }
- if (curr_buf->currline == curr_buf->top_of_win)
- curr_buf->top_of_win = p;
-
- delete_line(curr_buf->currline, 1);
- curr_buf->currline = p;
- curr_buf->redraw_everything = YEA;
- curr_buf->oldcurrline = curr_buf->currline = adjustline(curr_buf->currline, WRAPMARGIN);
- break;
- }
- else if (curr_buf->currline->len == curr_buf->currpnt) {
- join(curr_buf->currline);
- curr_buf->redraw_everything = YEA;
- break;
- }
- curr_buf->currline->len = curr_buf->currpnt;
- curr_buf->currline->data[curr_buf->currpnt] = '\0';
- break;
- }
-
- if (curr_buf->currln < 0)
- curr_buf->currln = 0;
-
- if (curr_buf->curr_window_line < 0)
- window_scroll_down();
- else if (cursor_at_bottom_line())
- window_scroll_up();
-#ifdef DBCSAWARE
- if(mbcs_mode)
- curr_buf->currpnt = fix_cursor(curr_buf->currline->data, curr_buf->currpnt, FC_LEFT);
-#endif
- }
-
- if (curr_buf->ansimode)
- tmp = n2ansi(curr_buf->currpnt, curr_buf->currline);
- else
- tmp = curr_buf->currpnt;
-
- if (tmp < t_columns - 1)
- curr_buf->edit_margin = 0;
- else
- curr_buf->edit_margin = tmp / (t_columns - 8) * (t_columns - 8);
-
- if (!curr_buf->redraw_everything) {
- if (curr_buf->edit_margin != curr_buf->last_margin) {
- curr_buf->last_margin = curr_buf->edit_margin;
- curr_buf->redraw_everything = YEA;
- } else {
- move(curr_buf->curr_window_line, 0);
- clrtoeol();
- if (curr_buf->ansimode)
- outs(curr_buf->currline->data);
- else
- {
- int attr = EOATTR_NORMAL;
- attr |= detect_attr(curr_buf->currline->data, curr_buf->currline->len);
- edit_outs_attr(&curr_buf->currline->data[curr_buf->edit_margin], attr);
- }
- outs(ANSI_RESET ANSI_CLRTOEND);
- edit_msg();
- }
- } /* redraw */
- } /* main event loop */
-
- exit_edit_buffer();
-}
-
-int
-vedit(char *fpath, int saveheader, int *islocal)
-{
- return vedit2(fpath, saveheader, islocal, EDITFLAG_ALLOWTITLE);
-}
-
-/* vim:sw=4:nofoldenable
- */
diff --git a/mbbsd/emaildb.c b/mbbsd/emaildb.c
deleted file mode 100644
index fa057102..00000000
--- a/mbbsd/emaildb.c
+++ /dev/null
@@ -1,244 +0,0 @@
-/* $Id$ */
-#include <sqlite3.h>
-#include "bbs.h"
-
-#define EMAILDB_PATH BBSHOME "/emaildb.db"
-
-// define FORK model to minimize memory usage.
-#define FORK_MODEL
-
-static int emaildb_open(sqlite3 **Db) {
- int rc;
-
- if ((rc = sqlite3_open(EMAILDB_PATH, Db)) != SQLITE_OK)
- return rc;
-
- // create table if it doesn't exist
- rc = sqlite3_exec(*Db, "CREATE TABLE IF NOT EXISTS emaildb (userid TEXT, email TEXT, PRIMARY KEY (userid));"
- "CREATE INDEX IF NOT EXISTS email ON emaildb (email);",
- NULL, NULL, NULL);
-
- return rc;
-}
-
-#ifndef INIT_MAIN
-int emaildb_check_email(char * email, int email_len)
-{
- int count = -1;
- pid_t pid = -1;
- sqlite3 *Db = NULL;
- sqlite3_stmt *Stmt = NULL;
-
-#ifdef FORK_MODEL
- switch((pid = fork()))
- {
- case -1: // error
- break;
-
- case 0: // child
- break;
-
- default:
- waitpid(pid, &count, 0);
- count = WEXITSTATUS(count);
- // vmsgf(ANSI_RESET "found %d emails", count);
- return count;
- }
-#endif
-
- if (emaildb_open(&Db) != SQLITE_OK)
- goto end;
-
- if (sqlite3_prepare(Db, "SELECT userid FROM emaildb WHERE email LIKE lower(?);",
- -1, &Stmt, NULL) != SQLITE_OK)
- goto end;
-
- if (sqlite3_bind_text(Stmt, 1, email, email_len, SQLITE_STATIC) != SQLITE_OK)
- goto end;
-
- count = 0;
- while (sqlite3_step(Stmt) == SQLITE_ROW) {
- char *result;
- userec_t u;
-
- if ((result = (char*)sqlite3_column_text(Stmt, 0)) == NULL)
- break;
-
- // ignore my self, because I may be the one going to
- // use mail.
- if (strcasecmp(result, cuser.userid) == 0)
- continue;
-
- // force update
- u.email[0] = 0;
-
- if (getuser(result, &u))
- if (strcasecmp(email, u.email) == 0)
- count++;
- }
-
-end:
- if (Stmt != NULL)
- if (sqlite3_finalize(Stmt) != SQLITE_OK)
- count = -1;
-
- if (Db != NULL)
- sqlite3_close(Db);
-
- if (pid == 0)
- exit(count);
-
- return count;
-}
-#endif
-
-int emaildb_update_email(char * userid, int userid_len, char * email, int email_len)
-{
- int ret = -1;
- pid_t pid = -1;
-
-#ifdef FORK_MODEL
- switch((pid = fork()))
- {
- case -1: // error
- break;
-
- case 0: // child
- break;
-
- default:
- waitpid(pid, &ret, 0);
- ret = WEXITSTATUS(ret);
- return ret;
- }
-#endif
-
- sqlite3 *Db = NULL;
- sqlite3_stmt *Stmt = NULL;
-
- if (emaildb_open(&Db) != SQLITE_OK)
- goto end;
-
- if (sqlite3_prepare(Db, "REPLACE INTO emaildb (userid, email) VALUES (lower(?),lower(?));",
- -1, &Stmt, NULL) != SQLITE_OK)
- goto end;
-
- if (sqlite3_bind_text(Stmt, 1, userid, userid_len, SQLITE_STATIC) != SQLITE_OK)
- goto end;
-
- if (sqlite3_bind_text(Stmt, 2, email, email_len, SQLITE_STATIC) != SQLITE_OK)
- goto end;
-
- if (sqlite3_step(Stmt) == SQLITE_DONE)
- ret = 0;
-
-end:
- if (Stmt != NULL)
- sqlite3_finalize(Stmt);
- if (Db != NULL)
- sqlite3_close(Db);
-
- if (pid == 0)
- exit(ret);
-
- return ret;
-}
-
-#ifdef INIT_MAIN
-
-// standalone initialize builder
-
-#define TRANSCATION_PERIOD (4096)
-int main()
-{
- int fd = 0;
- userec_t xuser;
- off_t sz = 0, i = 0, valids = 0;
- sqlite3 *Db = NULL;
- sqlite3_stmt *Stmt = NULL, *tranStart = NULL, *tranEnd = NULL;
-
- // init passwd
- sz = dashs(FN_PASSWD);
- fd = open(FN_PASSWD, O_RDONLY);
- if (fd < 0 || sz <= 0)
- {
- fprintf(stderr, "cannot open ~/.PASSWDS.\n");
- return 0;
- }
- sz /= sizeof(userec_t);
-
- // init emaildb
- if (emaildb_open(&Db) != SQLITE_OK)
- {
- fprintf(stderr, "cannot initialize emaildb.\n");
- return 0;
- }
-
- if (sqlite3_prepare(Db, "REPLACE INTO emaildb (userid, email) VALUES (lower(?),lower(?));",
- -1, &Stmt, NULL) != SQLITE_OK ||
- sqlite3_prepare(Db, "BEGIN TRANSACTION;", -1, &tranStart, NULL) != SQLITE_OK ||
- sqlite3_prepare(Db, "COMMIT;", -1, &tranEnd, NULL) != SQLITE_OK)
- {
- fprintf(stderr, "SQLite 3 internal error.\n");
- return 0;
- }
-
- sqlite3_step(tranStart);
- sqlite3_reset(tranStart);
- while (read(fd, &xuser, sizeof(xuser)) == sizeof(xuser))
- {
- i++;
- // got a record
- if (strlen(xuser.userid) < 2 || strlen(xuser.userid) > IDLEN)
- continue;
- if (strlen(xuser.email) < 5)
- continue;
-
- if (sqlite3_bind_text(Stmt, 1, xuser.userid, strlen(xuser.userid),
- SQLITE_STATIC) != SQLITE_OK)
- {
- fprintf(stderr, "\ncannot prepare userid param.\n");
- break;
- }
- if (sqlite3_bind_text(Stmt, 2, xuser.email, strlen(xuser.email),
- SQLITE_STATIC) != SQLITE_OK)
- {
- fprintf(stderr, "\ncannot prepare email param.\n");
- break;
- }
-
- if (sqlite3_step(Stmt) != SQLITE_DONE)
- {
- fprintf(stderr, "\ncannot execute statement.\n");
- break;
- }
- sqlite3_reset(Stmt);
-
- valids ++;
- if (valids % 10 == 0)
- fprintf(stderr, "%d/%d (valid: %d)\r",
- (int)i, (int)sz, (int)valids);
- if (valids % TRANSCATION_PERIOD == 0)
- {
- sqlite3_step(tranEnd);
- sqlite3_step(tranStart);
- sqlite3_reset(tranEnd);
- sqlite3_reset(tranStart);
- }
- }
-
- if (valids % TRANSCATION_PERIOD)
- sqlite3_step(tranEnd);
-
- if (Stmt != NULL)
- sqlite3_finalize(Stmt);
-
- if (Db != NULL)
- sqlite3_close(Db);
-
- close(fd);
- return 0;
-}
-#endif
-
-// vim: sw=4
diff --git a/mbbsd/fav.c b/mbbsd/fav.c
deleted file mode 100644
index 8a6c1e2f..00000000
--- a/mbbsd/fav.c
+++ /dev/null
@@ -1,1320 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-/**
- * Structure
- * =========
- * fav Àɪº«e¨â­Ó byte ¬Oª©¸¹¡A±µ¤U¨Ó¤~¬O¯u¥¿ªº data¡C
- *
- * fav ªº¥D­n¬[ºc¦p¤U¡G
- *
- * fav_t - ¥Î¨Ó¸Ë¦UºØ entry(fav_type_t) ªº directory
- * ¶i¤J§Úªº³Ì·R®É¡A¬Ý¨ìªºªF¦è´N¬O®Ú¾Ú fav_t ¥Í¥X¨Óªº¡C
- * ¸Ì­±¬ö¿ýªÌ¡A³o¤@­Ó level ¤¤¦³¦h¤Ö­Ó¬ÝªO¡B¥Ø¿ý¡B¤À¹j½u¡C(favh)
- * ¬O¤@­Ó array (with pre-allocated buffer)
- *
- * fav_type_t - fav entry ªº base class
- * ¦s¨ú®É³z¹L type Åܼƨӱoª¾¥¿½Tªº«¬ºA¡C
- *
- * fav_board_t / fav_line_t / fav_folder_t - derived class
- * ¸Ô²Ó±¡§Î½Ð°Ñ¦Ò fav.h ¤¤ªº©w¸q¡C
- * ¥H cast_(board|line|folder)_t ¨Ó±N¤@­Ó fav_type_t §@°ÊºAÂ૬¡C
- *
- * Policy
- * ======
- * ¬°¤FÁקK¹L«×ªº¸ê®Æ·h²¾¡A·í±N¤@­Ó item ±q§Úªº³Ì·R¤¤²¾°£®É¡A¥u±N¥Lªº
- * FAVH_FAV flag ²¾°£¡C¦Ó¨S¦³³o­Ó flag ªº item ¤]¤£³Qµø¬°§Úªº³Ì·R¡C
- *
- * §Úªº³Ì·R¤¤¡A¨S³] FAVH_FAV ªº¸ê®Æ¡A±N¦b¬Y¨Ç®É­Ô¡A¦p¼g¤JÀɮ׮ɡA©I¥s
- * rebuild_fav ²M°£°®²b¡C
- *
- * Others
- * ======
- * ¯¸ªø·h²¾¬ÝªO©Ò¥Îªº t ¡A¦]¬°¤£¯à¥u¦s¦b nbrd ¸Ì­±¡A¤S¤£µM¦A§Ë¥XÃB¥~ªºªÅ¶¡¡A
- * ©Ò¥H·í¯¸ªø¤£¦b§Úªº³Ì·R«ö¤F t ¡A·|§â³o­Ó°O¿ý¼È¦s¦b fav ¤¤
- * (FAVH_ADM_TAG == 1, FAVH_FAV == 0)¡C
- */
-
-
-/* the total number of items, every level. */
-static int fav_number;
-
-/* definition of fav stack, the top one is in use now. */
-static int fav_stack_num = 0;
-static fav_t *fav_stack[FAV_MAXDEPTH] = {0};
-
-static char dirty = 0;
-
-/* fav_tmp is for recordinge while copying, moving, etc. */
-static fav_t *fav_tmp;
-//static int fav_tmp_snum; /* the sequence number in favh in fav_t */
-
-#if 1 // DEPRECATED
-static void fav4_read_favrec(FILE *frp, fav_t *fp);
-#endif
-
-static void fav_free_branch(fav_t *fp);
-
-/**
- * cast_(board|line|folder) ¤@±Ú¥Î©ó±N base class §@Â૬
- * (¤£Àˬd¹ê»Ú data type)
- */
-inline static fav_board_t *cast_board(fav_type_t *p){
- return (fav_board_t *)p->fp;
-}
-
-inline static fav_line_t *cast_line(fav_type_t *p){
- return (fav_line_t *)p->fp;
-}
-
-inline static fav_folder_t *cast_folder(fav_type_t *p){
- return (fav_folder_t *)p->fp;
-}
-
-/**
- * ¶Ç¦^«ü©wªº fp(dir) ¤¤ªº fp->DataTail, ²Ä¤@­Ó¨S¥Î¹Lªº¦ì¸mªº index
- */
-inline static int get_data_tail(fav_t *fp){
- return fp->DataTail;
-}
-
-/**
- * ¶Ç¦^«ü©w dir ¤¤©Ò¥Îªº entry ªºÁ`¼Æ (¥uºâ¯uªº¦b¸Ì­±¡A¦Ó¤£ºâ¤w³Q²¾°£ªº)
- */
-inline int get_data_number(fav_t *fp){
- return fp->nBoards + fp->nLines + fp->nFolders;
-}
-
-/**
- * ¶Ç¦^¥Ø«e©Ò¦bªº dir pointer
- */
-inline fav_t *get_current_fav(void){
- if (fav_stack_num == 0)
- return NULL;
- return fav_stack[fav_stack_num - 1];
-}
-
-/**
- * ±N ft(entry) cast ¦¨¤@­Ó dir
- */
-inline fav_t *get_fav_folder(fav_type_t *ft){
- return cast_folder(ft)->this_folder;
-}
-
-inline int get_item_type(fav_type_t *ft){
- return ft->type;
-}
-
-/**
- * ±N¤@­Ó«ü©wªº dir pointer ¦s¤U¨Ó¡A¤§«á¥i¥Î fav_get_tmp_fav ¨Ó¦s¥Î
- */
-inline static void fav_set_tmp_folder(fav_t *fp){
- fav_tmp = fp;
-}
-
-inline static fav_t *fav_get_tmp_fav(void){
- return fav_tmp;
-}
-
-/**
- * ±N fp(dir) °Oªº¼Æ¶q¤¤¡A¦©°£¤@³æ¦ì ft(entry)
- */
-static void fav_decrease(fav_t *fp, fav_type_t *ft)
-{
- dirty = 1;
-
- switch (get_item_type(ft)){
- case FAVT_BOARD:
- fp->nBoards--;
- break;
- case FAVT_LINE:
- fp->nLines--;
- break;
- case FAVT_FOLDER:
- fp->nFolders--;
- break;
- }
- fav_number--;
-}
-
-/**
- * ±N fp(dir) °Oªº¼Æ¶q¤¤¡A¼W¥[¤@³æ¦ì ft(entry)
- */
-static void fav_increase(fav_t *fp, fav_type_t *ft)
-{
- dirty = 1;
-
- switch (get_item_type(ft)){
- case FAVT_BOARD:
- fp->nBoards++;
- break;
- case FAVT_LINE:
- fp->nLines++;
- cast_line(ft)->lid = ++fp->lineID;
- break;
- case FAVT_FOLDER:
- fp->nFolders++;
- cast_folder(ft)->fid = ++fp->folderID;
- break;
- }
- fav_number++;
- fp->DataTail++;
-}
-
-inline static int get_folder_num(fav_t *fp) {
- return fp->nFolders;
-}
-
-/**
- * get_(folder|line)_id ¶Ç¦^ fp ¤¤¤@­Ó·sªº folder/line id
- */
-inline static int get_folder_id(fav_t *fp) {
- return fp->folderID;
-}
-
-inline static int get_line_id(fav_t *fp) {
- return fp->lineID;
-}
-
-inline static int get_line_num(fav_t *fp) {
- return fp->nLines;
-}
-
-/**
- * ³]©w¬Y­Ó flag¡C
- * @bit: ¥Ø«e©Ò¦³ flags ¦³: FAVH_FAV, FAVH_TAG, FAVH_UNREAD, FAVH_ADM_TAG
- * @param cmd: FALSE: unset, TRUE: set, EXCH: opposite
- */
-void set_attr(fav_type_t *ft, int bit, char cmd){
- if (ft == NULL)
- return;
- if (cmd == EXCH)
- ft->attr ^= bit;
- else if (cmd == TRUE)
- ft->attr |= bit;
- else
- ft->attr &= ~bit;
- dirty = 1;
-}
-
-inline int is_set_attr(fav_type_t *ft, char bit){
- return ft->attr & bit;
-}
-
-char *get_item_title(fav_type_t *ft)
-{
- switch (get_item_type(ft)){
- case FAVT_BOARD:
- assert(0<=cast_board(ft)->bid-1 && cast_board(ft)->bid-1<MAX_BOARD);
- return bcache[cast_board(ft)->bid - 1].brdname;
- case FAVT_FOLDER:
- return cast_folder(ft)->title;
- case FAVT_LINE:
- return "----";
- }
- return NULL;
-}
-
-static char *get_item_class(fav_type_t *ft)
-{
- switch (get_item_type(ft)){
- case FAVT_BOARD:
- assert(0<=cast_board(ft)->bid-1 && cast_board(ft)->bid-1<MAX_BOARD);
- return bcache[cast_board(ft)->bid - 1].title;
- case FAVT_FOLDER:
- return "¥Ø¿ý";
- case FAVT_LINE:
- return "----";
- }
- return NULL;
-}
-
-
-static int get_type_size(int type)
-{
- switch (type){
- case FAVT_BOARD:
- return sizeof(fav_board_t);
- case FAVT_FOLDER:
- return sizeof(fav_folder_t);
- case FAVT_LINE:
- return sizeof(fav_line_t);
- }
- assert(0);
- return 0;
-}
-
-inline static void* fav_malloc(int size){
- void *p;
- assert(size>0);
- p = (void *)malloc(size);
- assert(p);
- memset(p, 0, size);
- return p;
-}
-
-/**
- * ¥u½Æ»s fav_type_t
- */
-inline static void
-fav_item_copy(fav_type_t *target, const fav_type_t *source){
- target->type = source->type;
- target->attr = source->attr;
- target->fp = source->fp;
-}
-
-inline fav_t *get_fav_root(void){
- return fav_stack[0];
-}
-
-/**
- * ¬O§_¬°¦³®Äªº entry
- */
-inline int valid_item(fav_type_t *ft){
- return ft->attr & FAVH_FAV;
-}
-
-static int is_need_rebuild_fav(fav_t *fp)
-{
- int i, nData;
- fav_type_t *ft;
-
- nData = fp->DataTail;
-
- for (i = 0; i < nData; i++){
- if (!valid_item(&fp->favh[i]))
- return 1;
-
- ft = &fp->favh[i];
- switch (get_item_type(ft)){
- case FAVT_BOARD:
- case FAVT_LINE:
- break;
- case FAVT_FOLDER:
- if(is_need_rebuild_fav(get_fav_folder(&fp->favh[i])))
- return 1;
- break;
- default:
- return 1;
- }
- }
- return 0;
-}
-/**
- * ²M°£ fp(dir) ¤¤µL®Äªº entry/dir¡C¡uµL®Ä¡v«üªº¬O¨S¦³ FAVH_FAV flag¡A©Ò¥H
- * ¤£¥]§t¤£¦s¦bªº¬ÝªO¡C
- */
-static void rebuild_fav(fav_t *fp)
-{
- int i, j, nData;
- fav_type_t *ft;
-
- fav_number -= get_data_number(fp);
- fp->lineID = fp->folderID = 0;
- fp->nLines = fp->nFolders = fp->nBoards = 0;
- nData = fp->DataTail;
- fp->DataTail = 0;
-
- for (i = 0, j = 0; i < nData; i++){
- if (!valid_item(&fp->favh[i]))
- continue;
-
- ft = &fp->favh[i];
- switch (get_item_type(ft)){
- case FAVT_BOARD:
- case FAVT_LINE:
- break;
- case FAVT_FOLDER:
- rebuild_fav(get_fav_folder(&fp->favh[i]));
- break;
- default:
- continue;
- }
- fav_increase(fp, &fp->favh[i]);
- if (i != j)
- fav_item_copy(&fp->favh[j], &fp->favh[i]);
- j++;
- }
- fp->DataTail = get_data_number(fp);
-}
-
-inline void fav_cleanup(void)
-{
- if (is_need_rebuild_fav(get_fav_root()))
- rebuild_fav(get_fav_root());
-}
-
-/* sort the fav */
-static int favcmp_by_name(const void *a, const void *b)
-{
- return strcasecmp(get_item_title((fav_type_t *)a), get_item_title((fav_type_t *)b));
-}
-
-void fav_sort_by_name(void)
-{
- fav_t *fp = get_current_fav();
-
- if (fp == NULL)
- return;
-
- dirty = 1;
- rebuild_fav(fp);
- qsort(fp->favh, get_data_number(fp), sizeof(fav_type_t), favcmp_by_name);
-}
-
-static int favcmp_by_class(const void *a, const void *b)
-{
- fav_type_t *f1, *f2;
- int cmp;
-
- f1 = (fav_type_t *)a;
- f2 = (fav_type_t *)b;
- if (get_item_type(f1) == FAVT_FOLDER)
- return -1;
- if (get_item_type(f2) == FAVT_FOLDER)
- return 1;
- if (get_item_type(f1) == FAVT_LINE)
- return 1;
- if (get_item_type(f2) == FAVT_LINE)
- return -1;
-
- cmp = strncasecmp(get_item_class(f1), get_item_class(f2), 4);
- if (cmp)
- return cmp;
- return strcasecmp(get_item_title(f1), get_item_title(f2));
-}
-
-void fav_sort_by_class(void)
-{
- fav_t *fp = get_current_fav();
-
- if (fp == NULL)
- return;
-
- dirty = 1;
- rebuild_fav(fp);
- qsort(fp->favh, get_data_number(fp), sizeof(fav_type_t), favcmp_by_class);
-}
-
-/**
- * The following is the movement operations in the user interface.
- */
-
-/**
- * ¥Ø¿ý¼h¼Æ¬O§_¹F¨ì³Ì¤j­È FAV_MAXDEPTH
- */
-inline int fav_stack_full(void){
- return fav_stack_num >= FAV_MAXDEPTH;
-}
-
-inline static int fav_stack_push_fav(fav_t *fp){
- if (fav_stack_full())
- return -1;
- fav_stack[fav_stack_num++] = fp;
- return 0;
-}
-
-inline static int fav_stack_push(fav_type_t *ft){
-// if (ft->type != FAVT_FOLDER)
-// return -1;
- return fav_stack_push_fav(get_fav_folder(ft));
-}
-
-inline static void fav_stack_pop(void){
- fav_stack[--fav_stack_num] = NULL;
-}
-
-void fav_folder_in(int fid)
-{
- fav_type_t *tmp = getfolder(fid);
- if (get_item_type(tmp) == FAVT_FOLDER){
- fav_stack_push(tmp);
- }
-}
-
-void fav_folder_out(void)
-{
- fav_stack_pop();
-}
-
-static int is_valid_favtype(int type)
-{
- switch (type){
- case FAVT_BOARD:
- case FAVT_FOLDER:
- case FAVT_LINE:
- return 1;
- }
- return 0;
-}
-
-/**
- * @return 0 if success, -1 if failed
- */
-static int read_favrec(FILE *frp, fav_t *fp)
-{
- /* TODO handle read errors */
- int i;
- fav_type_t *ft;
-
- fread(&fp->nBoards, sizeof(fp->nBoards), 1, frp);
- fread(&fp->nLines, sizeof(fp->nLines), 1, frp);
- fread(&fp->nFolders, sizeof(fp->nFolders), 1, frp);
- fp->DataTail = get_data_number(fp);
- fp->nAllocs = fp->DataTail + FAV_PRE_ALLOC;
- fp->lineID = fp->folderID = 0;
- fp->favh = (fav_type_t *)fav_malloc(sizeof(fav_type_t) * fp->nAllocs);
- fav_number += get_data_number(fp);
-
- for(i = 0; i < fp->DataTail; i++){
- ft = &fp->favh[i];
- fread(&ft->type, sizeof(ft->type), 1, frp);
- if(!is_valid_favtype(ft->type)) {
- ft->type = 0;
- return -1;
- }
- fread(&ft->attr, sizeof(ft->attr), 1, frp);
- ft->fp = (void *)fav_malloc(get_type_size(ft->type));
-
- switch (ft->type) {
- case FAVT_FOLDER:
- fread(&cast_folder(ft)->fid, sizeof(char), 1, frp);
- fread(&cast_folder(ft)->title, BTLEN + 1, 1, frp);
- break;
- case FAVT_BOARD:
- case FAVT_LINE:
- fread(ft->fp, get_type_size(ft->type), 1, frp);
- break;
- }
- }
-
- for(i = 0; i < fp->DataTail; i++){
- ft = &fp->favh[i];
- switch (ft->type) {
- case FAVT_FOLDER: {
- fav_t *p = (fav_t *)fav_malloc(sizeof(fav_t));
- if(read_favrec(frp, p)<0) {
- fav_free_branch(p);
- return -1;
- }
- cast_folder(ft)->this_folder = p;
- cast_folder(ft)->fid = ++(fp->folderID);
- break;
- }
- case FAVT_LINE:
- cast_line(ft)->lid = ++(fp->lineID);
- break;
- }
- }
- return 0;
-}
-
-/**
- * ±q°O¿ýÀɤ¤ load ¥X§Úªº³Ì·R¡C
- * TODO create default fav, and add SYSOP/PttNewHand (see reginit_fav)
- */
-int fav_load(void)
-{
- FILE *frp;
- char buf[PATHLEN];
- unsigned short version;
- fav_t *fp;
- if (fav_stack_num > 0)
- return -1;
- setuserfile(buf, FAV);
-
- if (!dashf(buf)) {
-#if 1 // DEPRECATED
- char old[PATHLEN];
- setuserfile(old, FAV4);
- if (dashf(old)) {
- if ((frp = fopen(old, "r")) == NULL)
- return -1;
- fp = (fav_t *)fav_malloc(sizeof(fav_t));
- fav_number = 0;
- fav4_read_favrec(frp, fp);
- fav_stack_push_fav(fp);
- fclose(frp);
-
- fav_save();
- setuserfile(old, FAV ".bak");
- Copy(buf, old);
- }
- else
-#endif
- {
- fp = (fav_t *)fav_malloc(sizeof(fav_t));
- fav_number = 0;
- fav_stack_push_fav(fp);
- }
- return 0;
- }
-
- if ((frp = fopen(buf, "r")) == NULL)
- return -1;
-#ifdef CRITICAL_MEMORY
- // kcwu: dirty hack, avoid 64byte slot. use 128 instead.
- fp = (fav_t *)fav_malloc(sizeof(fav_t)+64);
-#else
- fp = (fav_t *)fav_malloc(sizeof(fav_t));
-#endif
- fav_number = 0;
- fread(&version, sizeof(version), 1, frp);
- // if (version != FAV_VERSION) { ... }
- if(read_favrec(frp, fp)<0) {
- // load fail
- fav_free_branch(fp);
- fav_number = 0;
- fp = (fav_t *)fav_malloc(sizeof(fav_t));
- }
- fav_stack_push_fav(fp);
- fclose(frp);
- dirty = 0;
- return 0;
-}
-
-/* write to the rec file */
-static void write_favrec(FILE *fwp, fav_t *fp)
-{
- int i;
- fav_type_t *ft;
-
- if (fp == NULL)
- return;
-
- fwrite(&fp->nBoards, sizeof(fp->nBoards), 1, fwp);
- fwrite(&fp->nLines, sizeof(fp->nLines), 1, fwp);
- fwrite(&fp->nFolders, sizeof(fp->nFolders), 1, fwp);
- fp->DataTail = get_data_number(fp);
-
- for(i = 0; i < fp->DataTail; i++){
- ft = &fp->favh[i];
- fwrite(&ft->type, sizeof(ft->type), 1, fwp);
- fwrite(&ft->attr, sizeof(ft->attr), 1, fwp);
-
- switch (ft->type) {
- case FAVT_FOLDER:
- fwrite(&cast_folder(ft)->fid, sizeof(char), 1, fwp);
- fwrite(&cast_folder(ft)->title, BTLEN + 1, 1, fwp);
- break;
- case FAVT_BOARD:
- case FAVT_LINE:
- fwrite(ft->fp, get_type_size(ft->type), 1, fwp);
- break;
- }
- }
-
- for(i = 0; i < fp->DataTail; i++){
- if (fp->favh[i].type == FAVT_FOLDER)
- write_favrec(fwp, get_fav_folder(&fp->favh[i]));
- }
-}
-
-/**
- * §â°O¿ýÀÉ save ¶i§Úªº³Ì·R¡C
- * @note fav_cleanup() ·|¥ý³Q©I¥s¡C
- */
-int fav_save(void)
-{
- FILE *fwp;
- char buf[PATHLEN], buf2[PATHLEN];
- unsigned short version = FAV_VERSION;
- fav_t *fp = get_fav_root();
- if (fp == NULL)
- return -1;
-
- fav_cleanup();
- if (!dirty)
- return 0;
-
- setuserfile(buf2, FAV);
- snprintf(buf, sizeof(buf), "%s.tmp.%x",buf2, getpid());
- fwp = fopen(buf, "w");
- if(fwp == NULL)
- return -1;
- fwrite(&version, sizeof(version), 1, fwp);
- write_favrec(fwp, fp);
-
- if(fclose(fwp)==0)
- Rename(buf, buf2);
-
- return 0;
-}
-
-/**
- * remove ft (³]¬° invalid¡A¹ê»Ú¤W·|µ¥¨ì save ®É¤~²M°£)
- */
-static inline void fav_free_item(fav_type_t *ft)
-{
- set_attr(ft, 0xFFFF, FALSE);
-}
-
-/**
- * delete ft from fp
- */
-static int fav_remove(fav_t *fp, fav_type_t *ft)
-{
- if (fp == NULL || ft == NULL)
- return -1;
- fav_free_item(ft);
- fav_decrease(fp, ft);
- return 0;
-}
-
-/**
- * free the mem of fp recursively
- */
-static void fav_free_branch(fav_t *fp)
-{
- int i;
- fav_type_t *ft;
- if (fp == NULL)
- return;
- for(i = 0; i < fp->DataTail; i++){
- ft = &fp->favh[i];
- switch(get_item_type(ft)){
- case FAVT_FOLDER:
- fav_free_branch(cast_folder(ft)->this_folder);
- break;
- case FAVT_BOARD:
- case FAVT_LINE:
- if (ft->fp)
- free(ft->fp);
- break;
- }
- }
- free(fp->favh);
- free(fp);
- fp = NULL;
-}
-
-/**
- * free the mem of the whole fav tree recursively
- */
-void fav_free(void)
-{
- fav_free_branch(get_fav_root());
-
- /* reset the stack */
- fav_stack_num = 0;
-}
-
-/**
- * ±q¥Ø«eªº dir ¤¤§ä¥X¯S©wÃþ§O (type)¡Bid ¬° id ªº entry¡C
- * §ä¤£¨ì¶Ç¦^ NULL
- */
-static fav_type_t *get_fav_item(int id, int type)
-{
- int i;
- fav_type_t *ft;
- fav_t *fp = get_current_fav();
-
- if (fp == NULL)
- return NULL;
-
- for(i = 0; i < fp->DataTail; i++){
- ft = &fp->favh[i];
- if (!valid_item(ft) || get_item_type(ft) != type)
- continue;
- if (fav_getid(ft) == id)
- return ft;
- }
- return NULL;
-}
-
-/**
- * ±q¥Ø«eªº dir ¤¤ remove ¯S©wÃþ§O (type)¡Bid ¬° id ªº entry¡C
- */
-void fav_remove_item(int id, char type)
-{
- fav_remove(get_current_fav(), get_fav_item(id, type));
-}
-
-/**
- * get*(bid) ¶Ç¦^¥Ø«eªº dir ¤¤¸ÓÃþ§O id == bid ªº entry¡C
- */
-fav_type_t *getadmtag(int bid)
-{
- int i;
- fav_t *fp = get_fav_root();
- fav_type_t *ft;
- assert(0<=bid-1 && bid-1<MAX_BOARD);
- for (i = 0; i < fp->DataTail; i++) {
- ft = &fp->favh[i];
- if (get_item_type(ft) == FAVT_BOARD && cast_board(ft)->bid == bid && is_set_attr(ft, FAVH_ADM_TAG))
- return ft;
- }
- return NULL;
-}
-
-fav_type_t *getboard(int bid)
-{
- assert(0<=bid-1 && bid-1<MAX_BOARD);
- return get_fav_item(bid, FAVT_BOARD);
-}
-
-fav_type_t *getfolder(int fid)
-{
- return get_fav_item(fid, FAVT_FOLDER);
-}
-
-char *get_folder_title(int fid)
-{
- return get_item_title(get_fav_item(fid, FAVT_FOLDER));
-}
-
-
-char getbrdattr(int bid)
-{
- fav_type_t *fb = getboard(bid);
- if (!fb)
- return 0;
- return fb->attr;
-}
-
-int fav_getid(fav_type_t *ft)
-{
- switch(get_item_type(ft)){
- case FAVT_FOLDER:
- return cast_folder(ft)->fid;
- case FAVT_LINE:
- return cast_line(ft)->lid;
- case FAVT_BOARD:
- return cast_board(ft)->bid;
- }
- return -1;
-}
-
-inline static int is_maxsize(void){
- return fav_number >= MAX_FAV;
-}
-
-/**
- * ¨C¦¸¤@­Ó dir º¡®É¡A³o­Ó function ·|±N buffer ¤j¤p½Õ¤j FAV_PRE_ALLOC ­Ó¡A
- * ª½¨ì¤W­­¬°¤î¡C
- */
-static int enlarge_if_full(fav_t *fp)
-{
- fav_type_t * p;
- /* enlarge the volume if need. */
- if (is_maxsize())
- return -1;
- if (fp->DataTail < fp->nAllocs)
- return 1;
-
- /* realloc and clean the tail */
- p = (fav_type_t *)realloc(fp->favh, sizeof(fav_type_t) * (fp->nAllocs + FAV_PRE_ALLOC));
- if( p == NULL )
- return -1;
-
- fp->favh = p;
- memset(fp->favh + fp->nAllocs, 0, sizeof(fav_type_t) * FAV_PRE_ALLOC);
- fp->nAllocs += FAV_PRE_ALLOC;
- return 0;
-}
-
-/**
- * pre-append an item, and return the reference back.
- */
-static fav_type_t *fav_preappend(fav_t *fp, int type)
-{
- fav_type_t *item;
- if (enlarge_if_full(fp) < 0)
- return NULL;
- item = &fp->favh[fp->DataTail];
- item->fp = fav_malloc(get_type_size(type));
- item->attr = FAVH_FAV;
- item->type = type;
- fav_increase(fp, item);
- return item;
-}
-
-static void move_in_folder(fav_t *fav, int src, int dst)
-{
- int i, count;
- fav_type_t tmp;
-
- if (fav == NULL)
- return;
- count = get_data_number(fav);
- if (src >= fav->DataTail)
- src = count;
- if (dst >= fav->DataTail)
- dst = count;
- if (src == dst)
- return;
-
- dirty = 1;
-
- /* Find real locations of src and dst in fav->favh[] */
- for(count = i = 0; count <= src && i < fav->DataTail; i++)
- if (valid_item(&fav->favh[i]))
- count++;
- if (count != src + 1) return;
- src = i - 1;
- for(count = i = 0; count <= dst && i < fav->DataTail; i++)
- if (valid_item(&fav->favh[i]))
- count++;
- if (count != dst + 1) return;
- dst = i - 1;
-
- fav_item_copy(&tmp, &fav->favh[src]);
-
- if (src < dst) {
- for(i = src; i < dst; i++)
- fav_item_copy(&fav->favh[i], &fav->favh[i + 1]);
- }
- else { // dst < src
- for(i = src; i > dst; i--)
- fav_item_copy(&fav->favh[i], &fav->favh[i - 1]);
- }
- fav_item_copy(&fav->favh[dst], &tmp);
-}
-
-/**
- * ±N¥Ø«e¥Ø¿ý¤¤²Ä src ­Ó entry ²¾¨ì dst¡C
- * @note src/dst ¬O user ¹ê»Ú¤W¬Ý¨ìªº¦ì¸m¡A¤]´N¬O¤£¥]§t invalid entry¡C
- */
-void move_in_current_folder(int from, int to)
-{
- move_in_folder(get_current_fav(), from, to);
-}
-
-/**
- * the following defines the interface of add new fav_XXX
- */
-
-/**
- * allocate ¤@­Ó folder entry
- */
-inline static fav_t *alloc_folder_item(void){
- fav_t *fp = (fav_t *)fav_malloc(sizeof(fav_t));
- fp->nAllocs = FAV_PRE_ALLOC;
- fp->favh = (fav_type_t *)fav_malloc(sizeof(fav_type_t) * FAV_PRE_ALLOC);
- return fp;
-}
-
-/**
- * ·s¼W¤@¤À¹j½u
- * @return ¥[¤Jªº entry «ü¼Ð
- */
-fav_type_t *fav_add_line(void)
-{
- fav_t *fp = get_current_fav();
- if (is_maxsize())
- return NULL;
- if (fp == NULL || get_line_num(fp) >= MAX_LINE)
- return NULL;
- return fav_preappend(fp, FAVT_LINE);
-}
-
-/**
- * ·s¼W¤@¥Ø¿ý
- * @return ¥[¤Jªº entry «ü¼Ð
- */
-fav_type_t *fav_add_folder(void)
-{
- fav_t *fp = get_current_fav();
- fav_type_t *ft;
- if (is_maxsize() || fav_stack_full())
- return NULL;
- if (fp == NULL || get_folder_num(fp) >= MAX_FOLDER)
- return NULL;
- ft = fav_preappend(fp, FAVT_FOLDER);
- if (ft == NULL)
- return NULL;
- cast_folder(ft)->this_folder = alloc_folder_item();
- return ft;
-}
-
-/**
- * ±N«ü©w¬ÝªO¥[¤J¥Ø«eªº¥Ø¿ý¡C
- * @return ¥[¤Jªº entry «ü¼Ð
- * @note ¤£¤¹³\¦P¤@­ÓªO³Q¥[¤J¨â¦¸
- */
-fav_type_t *fav_add_board(int bid)
-{
- fav_t *fp = get_current_fav();
- fav_type_t *ft = getboard(bid);
-
- if (fp == NULL)
- return NULL;
- if (ft != NULL)
- return ft;
-
- if (is_maxsize())
- return NULL;
- ft = fav_preappend(fp, FAVT_BOARD);
- if (ft == NULL)
- return NULL;
- cast_board(ft)->bid = bid;
- return ft;
-}
-
-/**
- * for administrator to move/administrate board
- */
-fav_type_t *fav_add_admtag(int bid)
-{
- fav_t *fp = get_fav_root();
- fav_type_t *ft;
- if (is_maxsize())
- return NULL;
- ft = fav_preappend(fp, FAVT_BOARD);
- set_attr(ft, FAVH_FAV, FALSE);
- cast_board(ft)->bid = bid;
- // turn on FAVH_ADM_TAG
- set_attr(ft, FAVH_ADM_TAG, TRUE);
- return ft;
-}
-
-
-/* everything about the tag in fav mode.
- * I think we don't have to implement the function 'cross-folder' tag.*/
-
-/**
- * ±N¥Ø«e¥Ø¿ý¤U¡A¥Ñ type & id «ü©wªº entry ¼Ð¤W/¨ú®ø tag
- * @param bool ¦P set_attr
- * @note ­Y¦P¤@­Ó¥Ø¿ý¤£©¯¦³¦P¼ËªºªF¦è¡A¥u¦³²Ä¤@­Ó·|§@¥Î¡C
- */
-void fav_tag(int id, char type, char bool) {
- fav_type_t *ft = get_fav_item(id, type);
- if (ft != NULL)
- set_attr(ft, FAVH_TAG, bool);
-}
-
-static void fav_dosomething_tagged_item(fav_t *fp, int (*act)(fav_t *, fav_type_t *))
-{
- int i;
- for(i = 0; i < fp->DataTail; i++){
- if (valid_item(&fp->favh[i]) && is_set_attr(&fp->favh[i], FAVH_TAG))
- if ((*act)(fp, &fp->favh[i]) < 0)
- break;
- }
-}
-
-static int remove_tagged_item(fav_t *fp, fav_type_t *ft)
-{
- // do not remove the folder if it's on the stack
- if (get_item_type(ft) == FAVT_FOLDER) {
- int i;
- for(i = 0; i < FAV_MAXDEPTH && fav_stack[i] != NULL; i++) {
- if (fav_stack[i] == get_fav_folder(ft)){
- set_attr(ft, FAVH_TAG, FALSE);
- return 0;
- }
- }
- }
- return fav_remove(fp, ft);
-}
-
-inline static int fav_remove_tagged_item(fav_t *fp){
- fav_dosomething_tagged_item(fp, remove_tagged_item);
- return 0;
-}
-
-/* add an item into a fav_t.
- * here we must give the line and foler a new id to prevent an old one is exist.
- */
-static int add_and_remove_tag(fav_t *fp, fav_type_t *ft)
-{
- fav_type_t *tmp;
- // do not remove the folder if it's on the stack
- if (get_item_type(ft) == FAVT_FOLDER) {
- int i;
- for(i = 0; i < FAV_MAXDEPTH && fav_stack[i] != NULL; i++) {
- if (fav_stack[i] == get_fav_folder(ft)){
- set_attr(ft, FAVH_TAG, FALSE);
- return 0;
- }
- }
- }
- tmp = fav_preappend(fav_get_tmp_fav(), ft->type);
- if (ft->type == FAVT_FOLDER) {
- strlcpy(cast_folder(tmp)->title, cast_folder(ft)->title, BTLEN + 1);
- cast_folder(tmp)->this_folder = cast_folder(ft)->this_folder;
- }
- else {
- memcpy(tmp->fp, ft->fp, get_type_size(ft->type));
- }
-
-
- free(ft->fp);
- ft->fp = NULL;
- set_attr(tmp, FAVH_TAG, FALSE);
- fav_remove(fp, ft);
- return 0;
-}
-
-inline static int fav_add_tagged_item(fav_t *fp){
- if (fp == fav_get_tmp_fav())
- return -1;
- fav_dosomething_tagged_item(fp, add_and_remove_tag);
- return 0;
-}
-
-static void fav_do_recursively(fav_t *fp, int (*act)(fav_t *))
-{
- int i;
- fav_type_t *ft;
- for(i = 0; i < fp->DataTail; i++){
- ft = &fp->favh[i];
- if (!valid_item(ft))
- continue;
- if (get_item_type(ft) == FAVT_FOLDER && get_fav_folder(ft) != NULL){
- fav_do_recursively(get_fav_folder(ft), act);
- }
- }
- (*act)(fp);
-}
-
-static void fav_dosomething_all_tagged_item(int (*act)(fav_t *))
-{
- fav_do_recursively(get_fav_root(), act);
-}
-
-/**
- * fav_*_all_tagged_item ¦b¾ã­Ó§Úªº³Ì·R¤W¹ï¤w¼Ð¤W tag ªº entry °µ¬Y¥ó¨Æ¡C
- */
-void fav_remove_all_tagged_item(void)
-{
- fav_dosomething_all_tagged_item(fav_remove_tagged_item);
-}
-
-void fav_add_all_tagged_item(void)
-{
- fav_set_tmp_folder(get_current_fav());
- fav_dosomething_all_tagged_item(fav_add_tagged_item);
-}
-
-inline static int remove_tag(fav_t *fp, fav_type_t *ft)
-{
- set_attr(ft, FAVH_TAG, FALSE);
- return 0;
-}
-
-inline static int remove_tags(fav_t *fp)
-{
- fav_dosomething_tagged_item(fp, remove_tag);
- return 0;
-}
-
-/**
- * ²¾°£§Úªº³Ì·R©Ò¦³ªº tags
- */
-void fav_remove_all_tag(void)
-{
- fav_dosomething_all_tagged_item(remove_tags);
-}
-
-/**
- * ³]©w folder ªº¤¤¤å¦WºÙ
- */
-void fav_set_folder_title(fav_type_t *ft, char *title)
-{
- if (get_item_type(ft) != FAVT_FOLDER)
- return;
- dirty = 1;
- strlcpy(cast_folder(ft)->title, title, sizeof(cast_folder(ft)->title));
-}
-
-#define BRD_OLD 0
-#define BRD_NEW 1
-#define BRD_END 2
-/**
- * ¦pªG user ¶}±Ò FAVNEW_FLAG ªº¥\¯à:
- * mode == 1: update ¬ÝªO¡A¨Ã±N·s¬ÝªO¥[¤J§Úªº³Ì·R¡C
- * mode == 0: update ¸ê°T¦ý¤£¥[¤J¡C
- *
- * @return ¥[¤Jªº¬ÝªO¼Æ
- * PS. count ´NÅý¥¦¼Æ§¹¡A¤~¤£·|¦b¤U¤@¦¸ login ¤S±q¤@¥b¶}©l¼Æ¡C
- */
-int updatenewfav(int mode)
-{
- /* mode: 0: don't write to fav 1: write to fav */
- int i, fd, brdnum;
- int count = 0;
- char fname[80], *brd;
-
- if(!(cuser.uflag2 & FAVNEW_FLAG))
- return 0;
-
- setuserfile(fname, FAVNB);
-
- if( (fd = open(fname, O_RDWR | O_CREAT, 0600)) != -1 ){
-
- assert(numboards>=0);
- brdnum = numboards; /* avoid race */
-
- if ((brd = (char *)malloc((brdnum + 1) * sizeof(char))) == NULL)
- return -1;
- memset(brd, 0, (brdnum + 1) * sizeof(char));
-
- i = read(fd, brd, brdnum * sizeof(char));
- if (i < 0) {
- free(brd);
- close(fd);
- vmsg("favorite subscription error");
- return -1;
- }
-
- brd[i] = BRD_END;
-
- for(i = 0; i < brdnum && brd[i] != BRD_END; i++){
- if(brd[i] == BRD_NEW){
- /* check the permission if the board exsits */
- if(bcache[i].brdname[0] && HasBoardPerm(&bcache[i])){
- if(mode && !(bcache[i].brdattr & BRD_SYMBOLIC)) {
- fav_add_board(i + 1);
- count++;
- }
- brd[i] = BRD_OLD;
- }
- }
- else{
- if(!bcache[i].brdname[0])
- brd[i] = BRD_NEW;
- }
- }
-
- if( i < brdnum) { // the board number may change
- for(; i < brdnum; ++i){
- if(bcache[i].brdname[0] && HasBoardPerm(&bcache[i])){
- if(mode && !(bcache[i].brdattr & BRD_SYMBOLIC)) {
- fav_add_board(i + 1);
- count++;
- }
- brd[i] = BRD_OLD;
- }
- else
- brd[i] = BRD_NEW;
- }
- }
-
- brd[i] = BRD_END;
-
- lseek(fd, 0, SEEK_SET);
- write(fd, brd, (brdnum + 1) * sizeof(char));
-
- free(brd);
- close(fd);
- }
-
- return count;
-}
-
-void subscribe_newfav(void)
-{
- updatenewfav(0);
-}
-
-// create defaults for new user
-void reginit_fav(void)
-{
- int bid = 0;
-
- fav_load(); // for creating root
-
-#ifdef GLOBAL_NEWBIE
- bid = getbnum(GLOBAL_NEWBIE);
- if (bid > 0) fav_add_board(bid);
-#endif
-
-#ifdef GLOBAL_TEST
- bid = getbnum(GLOBAL_TEST);
- if (bid > 0) fav_add_board(bid);
-#endif
-
-#ifdef GLOBAL_ASKBOARD
- bid = getbnum(GLOBAL_ASKBOARD);
- if (bid > 0) fav_add_board(bid);
-#endif
-
-#ifdef GLOBAL_SYSOP
- bid = getbnum(GLOBAL_SYSOP);
- if (bid > 0) fav_add_board(bid);
-#endif
-
- fav_save();
-}
-
-#if 1 // DEPRECATED
-typedef struct {
- char fid;
- char title[BTLEN + 1];
- int this_folder;
-} fav_folder4_t;
-
-typedef struct {
- int bid;
- time4_t lastvisit; /* UNUSED */
- char attr;
-} fav4_board_t;
-
-static int fav4_get_type_size(int type)
-{
- switch (type){
- case FAVT_BOARD:
- return sizeof(fav4_board_t);
- case FAVT_FOLDER:
- return sizeof(fav_folder_t);
- case FAVT_LINE:
- return sizeof(fav_line_t);
- }
- return 0;
-}
-
-static void fav4_read_favrec(FILE *frp, fav_t *fp)
-{
- int i;
- fav_type_t *ft;
-
- fread(&fp->nBoards, sizeof(fp->nBoards), 1, frp);
- fread(&fp->nLines, sizeof(fp->nLines), 1, frp);
- fread(&fp->nFolders, sizeof(fp->nFolders), 1, frp);
- fp->DataTail = get_data_number(fp);
- fp->nAllocs = fp->DataTail + FAV_PRE_ALLOC;
- fp->lineID = fp->folderID = 0;
- fp->favh = (fav_type_t *)fav_malloc(sizeof(fav_type_t) * fp->nAllocs);
- fav_number += get_data_number(fp);
-
- for(i = 0; i < fp->DataTail; i++){
- ft = &fp->favh[i];
- fread(&ft->type, sizeof(ft->type), 1, frp);
- fread(&ft->attr, sizeof(ft->attr), 1, frp);
- ft->fp = (void *)fav_malloc(fav4_get_type_size(ft->type));
-
- /* TODO A pointer has different size between 32 and 64-bit arch.
- * But the pointer in fav_folder_t is irrelevant here.
- * In order not to touch the current .fav4, fav_folder4_t is used
- * here. It should be FIXED in the next version. */
- switch (ft->type) {
- case FAVT_FOLDER:
- fread(ft->fp, sizeof(fav_folder4_t), 1, frp);
- break;
- case FAVT_BOARD:
- case FAVT_LINE:
- fread(ft->fp, fav4_get_type_size(ft->type), 1, frp);
- break;
- }
- }
-
- for(i = 0; i < fp->DataTail; i++){
- ft = &fp->favh[i];
- switch (ft->type) {
- case FAVT_FOLDER: {
- fav_t *p = (fav_t *)fav_malloc(sizeof(fav_t));
- fav4_read_favrec(frp, p);
- cast_folder(ft)->this_folder = p;
- cast_folder(ft)->fid = ++(fp->folderID);
- break;
- }
- case FAVT_LINE:
- cast_line(ft)->lid = ++(fp->lineID);
- break;
- }
- }
-}
-#endif
-
-// vim:ts=8:sw=4
diff --git a/mbbsd/file.c b/mbbsd/file.c
deleted file mode 100644
index 3b657acc..00000000
--- a/mbbsd/file.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/* $Id$ */
-
-#include "bbs.h"
-
-/**
- * file.c ¬O°w¹ï¥H"¦æ"¬°³æ¦ìªºÀɮשҩw¸qªº¤@¨Ç operation¡C
- */
-
-/**
- * ¶Ç¦^ file Àɪº¦æ¼Æ
- * @param file
- */
-int file_count_line(const char *file)
-{
- FILE *fp;
- int count = 0;
- char buf[200];
-
- if ((fp = fopen(file, "r"))) {
- while (fgets(buf, sizeof(buf), fp)) {
- if (strchr(buf, '\n') == NULL)
- continue;
- count++;
- }
- fclose(fp);
- }
- return count;
-}
-
-/**
- * ±N string append ¨ìÀÉ®× file «áºÝ (¤£¥[´«¦æ)
- * @param file ­n³Q append ªºÀÉ
- * @param string
- * @return ¦¨¥\¶Ç¦^ 0¡A¥¢±Ñ¶Ç¦^ -1¡C
- */
-int file_append_line(const char *file, const char *string)
-{
- FILE *fp;
- if ((fp = fopen(file, "a")) == NULL)
- return -1;
- flock(fileno(fp), LOCK_EX);
- fputs(string, fp);
- flock(fileno(fp), LOCK_UN);
- fclose(fp);
- return 0;
-}
-
-/**
- * ±N "$key\n" append ¨ìÀÉ®× file «áºÝ
- * @param file ­n³Q append ªºÀÉ
- * @param key ¨S¦³´«¦æªº¦r¦ê
- * @return ¦¨¥\¶Ç¦^ 0¡A¥¢±Ñ¶Ç¦^ -1¡C
- */
-int file_append_record(const char *file, const char *key)
-{
- FILE *fp;
- if (!key || !*key) return -1;
- if ((fp = fopen(file, "a")) == NULL)
- return -1;
- flock(fileno(fp), LOCK_EX);
- fputs(key, fp);
- fputs("\n", fp);
- flock(fileno(fp), LOCK_UN);
- fclose(fp);
- return 0;
-}
-
-/**
- * ¶Ç¦^ÀÉ®× file ¤¤ key ©Ò¦b¦æ¼Æ
- */
-int file_find_record(const char *file, const char *key)
-{
- FILE *fp;
- char buf[STRLEN], *ptr;
- int i = 0;
-
- if ((fp = fopen(file, "r")) == NULL)
- return 0;
-
- while (fgets(buf, STRLEN, fp)) {
- char *strtok_pos;
- i++;
- if ((ptr = strtok_r(buf, str_space, &strtok_pos)) && !strcasecmp(ptr, key)) {
- fclose(fp);
- return i;
- }
- }
- fclose(fp);
- return 0;
-}
-
-/**
- * ¶Ç¦^ÀÉ®× file ¤¤¬O§_¦³ key
- */
-int file_exist_record(const char *file, const char *key)
-{
- return file_find_record(file, key) > 0 ? 1 : 0;
-}
-
-/**
- * §R°£ÀÉ®× file ¤¤¥H string ¶}ÀYªº¦æ
- * @param file ­n³B²zªºÀÉ®×
- * @param string ´M§äªº key name
- * @param case_sensitive ¬O§_­n³B²z¤j¤p¼g
- * @return ¦¨¥\¶Ç¦^ 0¡A¥¢±Ñ¶Ç¦^ -1¡C
- */
-int
-file_delete_record(const char *file, const char *string, int case_sensitive)
-{
- // TODO nfp ¥Î tmpfile() ¤ñ¸û¦n¡H ¤£¹L Rename ·|ÅܺC...
- FILE *fp = NULL, *nfp = NULL;
- char fnew[PATHLEN];
- char buf[STRLEN + 1];
- int ret = -1, i = 0;
- const size_t toklen = strlen(string);
-
- if (!toklen)
- return 0;
-
- do {
- snprintf(fnew, sizeof(fnew), "%s.%3.3X", file, (unsigned int)(random() & 0xFFF));
- if (access(fnew, 0) != 0)
- break;
- } while (i++ < 10); // max tries = 10
-
- if (access(fnew, 0) == 0) return -1; // cannot create temp file.
-
- i = 0;
- if ((fp = fopen(file, "r")) && (nfp = fopen(fnew, "w"))) {
- while (fgets(buf, sizeof(buf), fp))
- {
- size_t klen = strcspn(buf, str_space);
- if (toklen == klen)
- {
- if (((case_sensitive && strncmp(buf, string, toklen) == 0) ||
- (!case_sensitive && strncasecmp(buf, string, toklen) == 0)))
- {
- // found line. skip it.
- i++;
- continue;
- }
- }
- // other wise, keep the line.
- fputs(buf, nfp);
- }
- fclose(nfp); nfp = NULL;
- if (i > 0)
- {
- if(Rename(fnew, file) < 0)
- ret = -1;
- else
- ret = 0;
- } else {
- unlink(fnew);
- ret = 0;
- }
- }
- if(fp)
- fclose(fp);
- if(nfp)
- fclose(nfp);
- return ret;
-}
-
-/**
- * ¹ï¨C¤@µ§ record °µ func ³o¥ó¨Æ¡C
- * @param file
- * @param func ³B²z¨Cµ§ record ªº handler¡A¬°¤@ function pointer¡C
- * ²Ä¤@­Ó°Ñ¼Æ¬OÀɮפ¤ªº¤@¦æ¡A²Ä¤G­Ó°Ñ¼Æ¬° info¡C
- * @param info ¤@­ÓÃB¥~ªº°Ñ¼Æ¡C
- */
-int file_foreach_entry(const char *file, int (*func)(char *, int), int info)
-{
- char line[80];
- FILE *fp;
-
- if ((fp = fopen(file, "r")) == NULL)
- return -1;
-
- while (fgets(line, sizeof(line), fp)) {
- (*func)(line, info);
- }
-
- fclose(fp);
- return 0;
-}
diff --git a/mbbsd/friend.c b/mbbsd/friend.c
deleted file mode 100644
index 4fbc0be3..00000000
--- a/mbbsd/friend.c
+++ /dev/null
@@ -1,572 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-/* ------------------------------------- */
-/* ¯S§O¦W³æ */
-/* ------------------------------------- */
-
-/* Ptt ¨ä¥L¯S§O¦W³æªºÀɦW */
-char special_list[] = "list.0";
-char special_des[] = "ldes.0";
-
-/* ¯S§O¦W³æªº¤W­­ */
-static const unsigned int friend_max[8] = {
- MAX_FRIEND, /* FRIEND_OVERRIDE */
- MAX_REJECT, /* FRIEND_REJECT */
- MAX_LOGIN_INFO, /* FRIEND_ALOHA */
- MAX_POST_INFO, /* FRIEND_POST */
- MAX_NAMELIST, /* FRIEND_SPECIAL */
- MAX_FRIEND, /* FRIEND_CANVOTE */
- MAX_FRIEND, /* BOARD_WATER */
- MAX_FRIEND, /* BOARD_VISABLE */
-};
-/* ÁöµM¦n¤Í¸òÃa¤H¦W³æ³£¬O * 2 ¦ý¬O¤@¦¸³Ì¦hload¨ìshm¥u¯à¦³128 */
-
-
-/* Ptt ¦UºØ¯S§O¦W³æªº¸É­z */
-static char * const friend_desc[8] = {
- "¤Í½Ë´y­z¡G",
- "´c§Î´cª¬¡G",
- "",
- "",
- "´y­z¤@¤U¡G",
- "§ë²¼ªÌ´y­z¡G",
- "´c§Î´cª¬¡G",
- "¬ÝªO¦n¤Í´y­z"
-};
-
-/* Ptt ¦UºØ¯S§O¦W³æªº¤¤¤å±Ô­z */
-static char * const friend_list[8] = {
- "¦n¤Í¦W³æ",
- "Ãa¤H¦W³æ",
- "¤W½u³qª¾",
- "·s¤å³¹³qª¾",
- "¨ä¥¦¯S§O¦W³æ",
- "¨p¤H§ë²¼¦W³æ",
- "¬ÝªO¸TÁn¦W³æ",
- "¬ÝªO¦n¤Í¦W³æ"
-};
-
-void
-setfriendfile(char *fpath, int type)
-{
- if (type <= 4) /* user list Ptt */
- setuserfile(fpath, friend_file[type]);
- else /* board list */
- setbfile(fpath, currboard, friend_file[type]);
-}
-
-inline static int
-friend_count(const char *fname)
-{
- return file_count_line(fname);
-}
-
-void
-friend_add(const char *uident, int type, const char* des)
-{
- char fpath[80];
-
- setfriendfile(fpath, type);
- if (friend_count(fpath) > friend_max[type])
- return;
-
- if ((uident[0] > ' ') && !belong(fpath, uident)) {
- char buf[40] = "", buf2[256];
- char t_uident[IDLEN + 1];
-
- /* Thor: avoid uident run away when get data */
- strlcpy(t_uident, uident, sizeof(t_uident));
-
- if (type != FRIEND_ALOHA && type != FRIEND_POST){
- if(!des)
- getdata(2, 0, friend_desc[type], buf, sizeof(buf), DOECHO);
- else
- getdata_str(2, 0, friend_desc[type], buf, sizeof(buf), DOECHO, des);
- }
-
- sprintf(buf2, "%-13s%s\n", t_uident, buf);
- file_append_line(fpath, buf2);
- }
-}
-
-void
-friend_special(void)
-{
- char genbuf[70], i, fname[70];
- FILE *fp;
- friend_file[FRIEND_SPECIAL] = special_list;
- for (i = 0; i <= 9; i++) {
- snprintf(genbuf, sizeof(genbuf), " (" ANSI_COLOR(36) "%d" ANSI_RESET ") .. ", i);
- special_des[5] = i + '0';
- setuserfile(fname, special_des);
- if( (fp = fopen(fname, "r")) != NULL ){
- fgets(genbuf + 15, 40, fp);
- genbuf[47] = 0;
- fclose(fp);
- }
- move(i + 12, 0);
- clrtoeol();
- outs(genbuf);
- }
- getdata(22, 0, "½Ð¿ï¾Ü²Ä´X¸¹¯S§O¦W³æ (0~9)[0]?", genbuf, 3, LCECHO);
- if (genbuf[0] >= '0' && genbuf[0] <= '9') {
- special_list[5] = genbuf[0];
- special_des[5] = genbuf[0];
- } else {
- special_list[5] = '0';
- special_des[5] = '0';
- }
-}
-
-static void
-friend_append(int type, int count)
-{
- char fpath[80], i, j, buf[80], sfile[80];
- FILE *fp, *fp1;
- char myboard[IDLEN+1] = "";
- int boardChanged = 0;
-
- setfriendfile(fpath, type);
-
- if (currboard && *currboard)
- strcpy(myboard, currboard);
-
- do {
- move(2, 0);
- clrtobot();
- outs("­n¤Þ¤J­þ¤@­Ó¦W³æ?\n");
- for (j = i = 0; i <= 4; i++)
- if (i != type) {
- ++j;
- prints(" (%d) %-s\n", j, friend_list[(int)i]);
- }
- if (HasUserPerm(PERM_SYSOP) || currmode & MODE_BOARD)
- for (; i < 8; ++i)
- if (i != type) {
- ++j;
- prints(" (%d) %s ªOªº %s\n", j, currboard,
- friend_list[(int)i]);
- }
- if (HasUserPerm(PERM_SYSOP))
- outs(" (S) ¿ï¾Ü¨ä¥L¬ÝªOªº¯S§O¦W³æ");
-
- getdata(11, 0, "½Ð¿ï¾Ü ©Î ª½±µ[Enter] ©ñ±ó:", buf, 3, LCECHO);
- if (!buf[0])
- return;
-
- if (HasUserPerm(PERM_SYSOP) && buf[0] == 's')
- {
- Select();
- boardChanged = 1;
- }
-
- j = buf[0] - '1';
- if (j >= type)
- j++;
- if (!(HasUserPerm(PERM_SYSOP) || currmode & MODE_BOARD) && j >= 5)
- {
- if (boardChanged)
- enter_board(myboard);
- return;
- }
- } while (buf[0] < '1' || buf[0] > '9');
-
- if (j == FRIEND_SPECIAL)
- friend_special();
-
- setfriendfile(sfile, j);
-
- if ((fp = fopen(sfile, "r")) != NULL) {
- while (fgets(buf, 80, fp) && (unsigned)count <= friend_max[type]) {
- char the_id[IDLEN + 1];
-
- sscanf(buf, "%" toSTR(IDLEN) "s", the_id);
- if (!file_exist_record(fpath, the_id)) {
- if ((fp1 = fopen(fpath, "a"))) {
- flock(fileno(fp1), LOCK_EX);
- fputs(buf, fp1);
- flock(fileno(fp1), LOCK_UN);
- fclose(fp1);
- }
- }
- }
- fclose(fp);
- }
- if (boardChanged)
- enter_board(myboard);
-}
-
-static int
-delete_friend_from_file(const char *file, const char *string, int case_sensitive)
-{
- FILE *fp = NULL, *nfp = NULL;
- char fnew[PATHLEN];
- char genbuf[STRLEN + 1];
- int ret = 0;
-
- sprintf(fnew, "%s.%3.3X", file, (unsigned int)(random() & 0xFFF));
- if ((fp = fopen(file, "r")) && (nfp = fopen(fnew, "w"))) {
- while (fgets(genbuf, sizeof(genbuf), fp))
- if ((genbuf[0] > ' ')) {
- char buf[32];
- sscanf(genbuf, " %s", buf);
- if (((case_sensitive && strcmp(buf, string)) ||
- (!case_sensitive && strcasecmp(buf, string))))
- fputs(genbuf, nfp);
- else
- ret = 1;
- }
- Rename(fnew, file);
- }
- if(fp)
- fclose(fp);
- if(nfp)
- fclose(nfp);
- return ret;
-}
-
-void
-friend_delete(const char *uident, int type)
-{
- char fn[STRLEN];
- setfriendfile(fn, type);
- delete_friend_from_file(fn, uident, 0);
-}
-
-static void
-delete_user_friend(const char *uident, const char *thefriend, int type)
-{
- char fn[PATHLEN];
- sethomefile(fn, uident, "aloha");
- delete_friend_from_file(fn, thefriend, 0);
-}
-
-void
-friend_delete_all(const char *uident, int type)
-{
- char buf[PATHLEN], line[PATHLEN];
- FILE *fp;
-
- sethomefile(buf, uident, friend_file[type]);
-
- if ((fp = fopen(buf, "r")) == NULL)
- return;
-
- while (fgets(line, sizeof(line), fp)) {
- sscanf(line, "%s", buf);
- delete_user_friend(buf, uident, type);
- }
-
- fclose(fp);
-}
-
-static void
-friend_editdesc(const char *uident, int type)
-{
- FILE *fp=NULL, *nfp=NULL;
- char fnnew[200], genbuf[STRLEN], fn[200];
- setfriendfile(fn, type);
- snprintf(fnnew, sizeof(fnnew), "%s-", fn);
- if ((fp = fopen(fn, "r")) && (nfp = fopen(fnnew, "w"))) {
- int length = strlen(uident);
-
- while (fgets(genbuf, STRLEN, fp)) {
- if ((genbuf[0] > ' ') && strncmp(genbuf, uident, length))
- fputs(genbuf, nfp);
- else if (!strncmp(genbuf, uident, length)) {
- char buf[50] = "";
- getdata(2, 0, "­×§ï´y­z¡G", buf, 40, DOECHO);
- fprintf(nfp, "%-13s%s\n", uident, buf);
- }
- }
- Rename(fnnew, fn);
- }
- if(fp)
- fclose(fp);
- if(nfp)
- fclose(nfp);
-}
-
-inline void friend_load_real(int tosort, int maxf,
- short *destn, int *destar, const char *fn)
-{
- char genbuf[200];
- FILE *fp;
- short nFriends = 0;
- int uid, *tarray;
- char *p;
-
- setuserfile(genbuf, fn);
- if( (fp = fopen(genbuf, "r")) == NULL ){
- destar[0] = 0;
- if( destn )
- *destn = 0;
- }
- else{
- char *strtok_pos;
- tarray = (int *)malloc(sizeof(int) * maxf);
- --maxf; /* ¦]¬°³Ì«á¤@­Ó­n¶ñ 0, ©Ò¥H¥ý¦©¤@­Ó¦^¨Ó */
- while( fgets(genbuf, STRLEN, fp) && nFriends < maxf )
- if( (p = strtok_r(genbuf, str_space, &strtok_pos)) &&
- (uid = searchuser(p, NULL)) )
- tarray[nFriends++] = uid;
- fclose(fp);
-
- if( tosort )
- qsort(tarray, nFriends, sizeof(int), cmp_int);
- if( destn )
- *destn = nFriends;
- tarray[nFriends] = 0;
- memcpy(destar, tarray, sizeof(int) * (nFriends + 1));
- free(tarray);
- }
-}
-
-/* type == 0 : load all */
-void friend_load(int type)
-{
- if (!type || type & FRIEND_OVERRIDE)
- friend_load_real(1, MAX_FRIEND, &currutmp->nFriends,
- currutmp->myfriend, fn_overrides);
-
- if (!type || type & FRIEND_REJECT)
- friend_load_real(0, MAX_REJECT, NULL, currutmp->reject, fn_reject);
-
- if (currutmp->friendtotal)
- logout_friend_online(currutmp);
-
- login_friend_online();
-}
-
-static void
-friend_water(const char *message, int type)
-{ /* ¸sÅé¤ô²y added by Ptt */
- char fpath[80], line[80], userid[IDLEN + 1];
- FILE *fp;
-
- setfriendfile(fpath, type);
- if ((fp = fopen(fpath, "r"))) {
- while (fgets(line, 80, fp)) {
- userinfo_t *uentp;
- int tuid;
-
- sscanf(line, "%" toSTR(IDLEN) "s", userid);
- if ((tuid = searchuser(userid, NULL)) && tuid != usernum &&
- (uentp = (userinfo_t *) search_ulist(tuid)) &&
- isvisible_uid(tuid))
- my_write(uentp->pid, message, uentp->userid, WATERBALL_PREEDIT, NULL);
- }
- fclose(fp);
- }
-}
-
-void
-friend_edit(int type)
-{
- char fpath[80], line[80], uident[IDLEN + 1];
- int count, column, dirty;
- FILE *fp;
- char genbuf[200];
-
- if (type == FRIEND_SPECIAL)
- friend_special();
- setfriendfile(fpath, type);
-
- if (type == FRIEND_ALOHA || type == FRIEND_POST) {
- if (dashf(fpath)) {
- sprintf(genbuf,"%s.old",fpath);
- Copy(fpath, genbuf);
- }
- }
- dirty = 0;
- while (1) {
- stand_title(friend_list[type]);
- /* TODO move (0, 40) just won't really work as it hints.
- * The ANSI secapes will change x coordinate. */
- move(0, 40);
- prints("(¦W³æ¤W­­: %d ¤H)", friend_max[type]);
- count = 0;
- CreateNameList();
-
- if ((fp = fopen(fpath, "r"))) {
- move(3, 0);
- column = 0;
- while (fgets(genbuf, STRLEN, fp)) {
- char *space;
- if (genbuf[0] <= ' ')
- continue;
- space = strpbrk(genbuf, str_space);
- if (space) *space = '\0';
- AddNameList(genbuf);
- prints("%-13s", genbuf);
- count++;
- if (++column > 5) {
- column = 0;
- outc('\n');
- }
- }
- fclose(fp);
- }
- getdata(1, 0, (count ?
- "(A)¼W¥[(D)§R°£(E)­×§ï(P)¤Þ¤J(L)¸Ô²Ó¦C¥X"
- "(K)§R°£¾ã­Ó¦W³æ(W)¥á¤ô²y(Q)µ²§ô?[Q] " :
- "(A)¼W¥[ (P)¤Þ¤J¨ä¥L¦W³æ (Q)µ²§ô?[Q] "),
- uident, 3, LCECHO);
- if (uident[0] == 'a') {
- move(1, 0);
- usercomplete(msg_uid, uident);
- if (uident[0] && searchuser(uident, uident) && !InNameList(uident)) {
- friend_add(uident, type, NULL);
- dirty = 1;
- }
- } else if (uident[0] == 'p') {
- friend_append(type, count);
- dirty = 1;
- } else if (uident[0] == 'e' && count) {
- move(1, 0);
- namecomplete(msg_uid, uident);
- if (uident[0] && InNameList(uident)) {
- friend_editdesc(uident, type);
- }
- } else if (uident[0] == 'd' && count) {
- move(1, 0);
- namecomplete(msg_uid, uident);
- if (uident[0] && InNameList(uident)) {
- friend_delete(uident, type);
- dirty = 1;
- }
- } else if (uident[0] == 'l' && count)
- more(fpath, YEA);
- else if (uident[0] == 'k' && count) {
- getdata(2, 0, "§R°£¾ã¥÷¦W³æ,½T©w¶Ü (a/N)?", uident, 3,
- LCECHO);
- if (uident[0] == 'a')
- unlink(fpath);
- dirty = 1;
- } else if (uident[0] == 'w' && count) {
- char wall[60];
- if (!getdata(0, 0, "¸sÅé¤ô²y:", wall, sizeof(wall), DOECHO))
- continue;
- if (getdata(0, 0, "½T©w¥á¥X¸sÅé¤ô²y? [Y]", line, 4, LCECHO) &&
- *line == 'n')
- continue;
- friend_water(wall, type);
- } else
- break;
- }
- if (dirty) {
- move(2, 0);
- outs("§ó·s¸ê®Æ¤¤..½Ðµy­Ô.....");
- refresh();
- if (type == FRIEND_ALOHA || type == FRIEND_POST) {
- snprintf(genbuf, sizeof(genbuf), "%s.old", fpath);
- if ((fp = fopen(genbuf, "r"))) {
- while (fgets(line, 80, fp)) {
- sscanf(line, "%" toSTR(IDLEN) "s", uident);
- sethomefile(genbuf, uident,
- type == FRIEND_ALOHA ? "aloha" : "postnotify");
- del_distinct(genbuf, cuser.userid, 0);
- }
- fclose(fp);
- }
- strlcpy(genbuf, fpath, sizeof(genbuf));
- if ((fp = fopen(genbuf, "r"))) {
- while (fgets(line, 80, fp)) {
- sscanf(line, "%" toSTR(IDLEN) "s", uident);
- sethomefile(genbuf, uident,
- type == FRIEND_ALOHA ? "aloha" : "postnotify");
- add_distinct(genbuf, cuser.userid);
- }
- fclose(fp);
- }
- } else if (type == FRIEND_SPECIAL) {
- genbuf[0] = 0;
- setuserfile(line, special_des);
- if ((fp = fopen(line, "r"))) {
- fgets(genbuf, 30, fp);
- fclose(fp);
- }
- getdata_buf(2, 0, " ½Ð¬°¦¹¯S§O¦W³æ¨ú¤@­Ó²µu¦WºÙ:", genbuf, 30,
- DOECHO);
- if ((fp = fopen(line, "w"))) {
- fputs(genbuf, fp);
- fclose(fp);
- }
- } else if (type == BOARD_WATER) {
- boardheader_t *bp = NULL;
- currbid = getbnum(currboard);
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- bp = getbcache(currbid);
- bp->perm_reload = now;
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- substitute_record(fn_board, bp, sizeof(boardheader_t), currbid);
- // log_usies("SetBoard", bp->brdname);
- }
- friend_load(0);
- }
-}
-
-int
-t_override(void)
-{
- friend_edit(FRIEND_OVERRIDE);
- return 0;
-}
-
-int
-t_reject(void)
-{
- friend_edit(FRIEND_REJECT);
- return 0;
-}
-
-int
-t_fix_aloha()
-{
- char xid[IDLEN+1] = "";
- char fn[PATHLEN] = "";
-
- clear();
- stand_title("­×¥¿¤W¯¸³qª¾");
-
- outs("³o¬O¥Î¨Ó­×¥¿¬Y¨Ç¨Ï¥ÎªÌ¹J¨ì¿ù»~ªº¤W¯¸³qª¾ªº°ÝÃD¡C\n"
- ANSI_COLOR(1) "¦pªG§A¨S¹J¨ì¦¹Ãþ°ÝÃD¥iª½±µÂ÷¶}¡C" ANSI_RESET "\n\n"
- "¡¿¦pªG§A¹J¨ì¦³¤H¨S¦b§Aªº¤W¯¸³qª¾¦W³æ¤º¦ý¤S·|¥á¤W¯¸³qª¾¤ô²yµ¹§A¡A\n"
- " ½Ð¿é¤J¥Lªº ID¡C\n");
-
- move(7, 0);
- usercomplete("¦³½Ö¤£¦b§Aªº³qª¾¦W³æ¤º¦ý¤S·|°e¤W¯¸³qª¾¤ô²yµ¹±z©O¡H ", xid);
-
- if (!xid[0])
- {
- vmsg("­×¥¿µ²§ô¡C");
- return 0;
- }
-
- // check by xid
- move(9, 0);
- outs("Àˬd¤¤...\n");
-
- // xid in my override list?
- setuserfile(fn, "alohaed");
- if (belong(fn, xid))
- {
- prints(ANSI_COLOR(1;32) "[%s] ½T¹ê¦b§Aªº¤W¯¸³qª¾¦W³æ¤º¡C"
- "½Ð½s¿è [¤W¯¸³qª¾¦W³æ]¡C" ANSI_RESET "\n", xid);
- vmsg("¤£»Ý­×¥¿¡C");
- return 0;
- }
-
- sethomefile(fn, xid, "aloha");
- if (delete_friend_from_file(fn, cuser.userid, 0))
- {
- outs(ANSI_COLOR(1;33) "¤w§ä¨ì¿ù»~¨Ã­×´_§¹¦¨¡C" ANSI_RESET "\n");
- } else {
- outs(ANSI_COLOR(1;31) "§ä¤£¨ì¿ù»~... ¥´¿ù ID ¤F¡H" ANSI_RESET "\n");
- }
-
- vmsg("­Y¤W¯¸³qª¾¿ù»~¤´«ùÄòµo¥Í½Ð³qª¾¯¸¤è³B²z¡C");
- return 0;
-}
-
diff --git a/mbbsd/gamble.c b/mbbsd/gamble.c
deleted file mode 100644
index 2f3e2dd7..00000000
--- a/mbbsd/gamble.c
+++ /dev/null
@@ -1,388 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-#define MAX_ITEM 8 //³Ì¤j ½ä¶µ(item) ­Ó¼Æ
-#define MAX_ITEM_LEN 30 //³Ì¤j ¨C¤@½ä¶µ¦W¦rªø«×
-#define MAX_SUBJECT_LEN 650 //8*81 = 648 ³Ì¤j ¥DÃDªø«×
-
-static int
-load_ticket_record(const char *direct, int ticket[])
-{
- char buf[256];
- int i, total = 0;
- FILE *fp;
- snprintf(buf, sizeof(buf), "%s/" FN_TICKET_RECORD, direct);
- if (!(fp = fopen(buf, "r")))
- return 0;
- for (i = 0; i < MAX_ITEM && fscanf(fp, "%9d ", &ticket[i])==1; i++)
- total = total + ticket[i];
- fclose(fp);
- return total;
-}
-
-static int
-show_ticket_data(char betname[MAX_ITEM][MAX_ITEM_LEN],const char *direct, int *price, const boardheader_t * bh)
-{
- int i, count, total = 0, end = 0, ticket[MAX_ITEM] = {0, 0, 0, 0, 0, 0, 0, 0};
- FILE *fp;
- char genbuf[256], t[25];
-
- clear();
- if (bh) {
- snprintf(genbuf, sizeof(genbuf), "%s ½ä½L", bh->brdname);
- if (bh->endgamble && now < bh->endgamble &&
- bh->endgamble - now < 3600) {
- snprintf(t, sizeof(t),
- "«Ê½L­Ë¼Æ %d ¬í", (int)(bh->endgamble - now));
- showtitle(genbuf, t);
- } else
- showtitle(genbuf, BBSNAME);
- } else
- showtitle(BBSMNAME "½ä½L", BBSNAME);
- move(2, 0);
- snprintf(genbuf, sizeof(genbuf), "%s/" FN_TICKET_ITEMS, direct);
- if (!(fp = fopen(genbuf, "r"))) {
- outs("\n¥Ø«e¨Ã¨S¦³Á|¿ì½ä½L\n");
- snprintf(genbuf, sizeof(genbuf), "%s/" FN_TICKET_OUTCOME, direct);
- more(genbuf, NA);
- return 0;
- }
- fgets(genbuf, MAX_ITEM_LEN, fp);
- *price = atoi(genbuf);
- for (count = 0; fgets(betname[count], MAX_ITEM_LEN, fp) && count < MAX_ITEM; count++) {
- chomp(betname[count]);
- }
- fclose(fp);
-
- prints(ANSI_COLOR(32) "¯¸³W:" ANSI_RESET " 1.¥iÁʶR¥H¤U¤£¦PÃþ«¬ªº±m²¼¡C¨C±i­nªá " ANSI_COLOR(32) "%d" ANSI_RESET " ¤¸¡C\n"
- " 2.%s\n"
- " 3.¶}¼ú®É¥u¦³¤@ºØ±m²¼¤¤¼ú, ¦³ÁʶR¸Ó±m²¼ªÌ, «h¥i¨ÌÁʶRªº±i¼Æ§¡¤ÀÁ`½äª÷¡C\n"
- " 4.¨Cµ§¼úª÷¥Ñ¨t²Î©â¨ú 5%% ¤§µ|ª÷%s¡C\n\n"
- ANSI_COLOR(32) "%s:" ANSI_RESET, *price,
- bh ? "¦¹½ä½L¥ÑªO¥D­t³dÁ|¿ì¨Ã¥B¨M©w¶}¼ú®É¶¡µ²ªG, ¯¸ªø¤£ºÞ, Ä@½äªA¿é¡C" :
- "¨t²Î¨C¤Ñ 2:00 11:00 16:00 21:00 ¶}¼ú¡C",
- bh ? ", ¨ä¤¤ 2% ¤Àµ¹¶}¼úªO¥D" : "",
- bh ? "ªO¥D¦Û­q³W«h¤Î»¡©ú" : "«e´X¦¸¶}¼úµ²ªG");
-
-
- snprintf(genbuf, sizeof(genbuf), "%s/" FN_TICKET, direct);
- if (!dashf(genbuf)) {
- snprintf(genbuf, sizeof(genbuf), "%s/" FN_TICKET_END, direct);
- end = 1;
- }
- show_file(genbuf, 8, -1, SHOWFILE_ALLOW_ALL);
- move(15, 0);
- outs(ANSI_COLOR(1;32) "¥Ø«e¤Uª`ª¬ªp:" ANSI_RESET "\n");
-
- total = load_ticket_record(direct, ticket);
-
- outs(ANSI_COLOR(33));
- for (i = 0; i < count; i++) {
- prints("%d.%-8s: %-7d", i + 1, betname[i], ticket[i]);
- if (i == 3)
- outc('\n');
- }
- prints(ANSI_RESET "\n" ANSI_COLOR(42) " ¤Uª`Á`ª÷ÃB:" ANSI_COLOR(31) " %d ¤¸ " ANSI_RESET, total * (*price));
- if (end) {
- outs("\n½ä½L¤w¸g°±¤î¤Uª`\n");
- return -count;
- }
- return count;
-}
-
-static int
-append_ticket_record(const char *direct, int ch, int n, int count)
-{
- FILE *fp;
- int ticket[8] = {0, 0, 0, 0, 0, 0, 0, 0}, i;
- char genbuf[256];
-
- snprintf(genbuf, sizeof(genbuf), "%s/" FN_TICKET, direct);
- if (!dashf(genbuf))
- return -1;
-
- snprintf(genbuf, sizeof(genbuf), "%s/" FN_TICKET_USER, direct);
- if ((fp = fopen(genbuf, "a"))) {
- fprintf(fp, "%s %d %d\n", cuser.userid, ch, n);
- fclose(fp);
- }
-
- snprintf(genbuf, sizeof(genbuf), "%s/" FN_TICKET_RECORD, direct);
-
- if (!dashf(genbuf)) {
- creat(genbuf, S_IRUSR | S_IWUSR);
- }
-
- if ((fp = fopen(genbuf, "r+"))) {
-
- flock(fileno(fp), LOCK_EX);
-
- for (i = 0; i < MAX_ITEM; i++)
- if (fscanf(fp, "%9d ", &ticket[i]) != 1)
- break;
- ticket[ch] += n;
-
- ftruncate(fileno(fp), 0);
- rewind(fp);
- for (i = 0; i < count; i++)
- fprintf(fp, "%d ", ticket[i]);
- fflush(fp);
-
- flock(fileno(fp), LOCK_UN);
- fclose(fp);
- }
- return 0;
-}
-
-#define lockreturn0(unmode, state) if(lockutmpmode(unmode, state)) return 0
-int
-ticket(int bid)
-{
- int ch, end = 0;
- int n, price, count; /* ÁʶR±i¼Æ¡B³æ»ù¡B¿ï¶µ¼Æ */
- char path[128], fn_ticket[128];
- char betname[MAX_ITEM][MAX_ITEM_LEN];
- boardheader_t *bh = NULL;
-
- STATINC(STAT_GAMBLE);
- if (bid) {
- bh = getbcache(bid);
- setbpath(path, bh->brdname);
- setbfile(fn_ticket, bh->brdname, FN_TICKET);
- currbid = bid;
- } else
- strcpy(path, "etc/");
-
- lockreturn0(TICKET, LOCK_MULTI);
- while (1) {
- count = show_ticket_data(betname, path, &price, bh);
- if (count <= 0) {
- pressanykey();
- break;
- }
- move(20, 0);
- reload_money();
- prints(ANSI_COLOR(44) "¿ú: %-10d " ANSI_RESET "\n" ANSI_COLOR(1) "½Ð¿ï¾Ü­nÁʶRªººØÃþ(1~%d)"
- "[Q:Â÷¶}]" ANSI_RESET ":", cuser.money, count);
- ch = igetch();
- /*--
- Tim011127
- ¬°¤F±±¨îCS°ÝÃD ¦ý¬O³oÃäÁÙ¤£¯à§¹¥þ¸Ñ¨M³o°ÝÃD,
- ­Yuser³q¹LÀˬd¤U¥h, ­è¦nªO¥D¶}¼ú, ÁÙ¬O·|³y¦¨userªº³o¦¸¬ö¿ý
- «Ü¦³¥i¯à¶]¨ì¤U¦¸½ä½Lªº¬ö¿ý¥h, ¤]«Ü¦³¥i¯à³QªO¥D·s¶}½ä½L®É¬~±¼
- ¤£¹L³oÃä¦Ü¤Ö¥i¥H°µ¨ìªº¬O, ³»¦h¥u·|¦³¤@µ§¸ê®Æ¬O¿ùªº
- --*/
- if (ch == 'q' || ch == 'Q')
- break;
- ch -= '1';
- if (end || ch >= count || ch < 0)
- continue;
- n = 0;
- ch_buyitem(price, "etc/buyticket", &n, 0);
-
- if (bid && !dashf(fn_ticket))
- goto doesnt_catch_up;
-
- if (n > 0) {
- if (append_ticket_record(path, ch, n, count) < 0)
- goto doesnt_catch_up;
- }
- }
- unlockutmpmode();
- return 0;
-
-doesnt_catch_up:
-
- price = price * n;
- if (price > 0)
- deumoney(currutmp->uid, price);
- vmsg("ªO¥D¤w¸g°±¤î¤Uª`¤F ¤£¯à½äÂP");
- unlockutmpmode();
- return -1;
-}
-
-int
-openticket(int bid)
-{
- char path[MAXPATHLEN], buf[MAXPATHLEN], outcome[MAXPATHLEN];
- int i, money = 0, count, bet, price, total = 0,
- ticket[8] = {0, 0, 0, 0, 0, 0, 0, 0};
- boardheader_t *bh = getbcache(bid);
- FILE *fp, *fp1;
- char betname[MAX_ITEM][MAX_ITEM_LEN];
-
- setbpath(path, bh->brdname);
- count = -show_ticket_data(betname, path, &price, bh);
- if (count == 0) {
- setbfile(buf, bh->brdname, FN_TICKET_END);
- unlink(buf);
-//Ptt: ¦³bug
- return 0;
- }
- lockreturn0(TICKET, LOCK_MULTI);
- do {
- do {
- getdata(20, 0,
- ANSI_COLOR(1) "¿ï¾Ü¤¤¼úªº¸¹½X(0:¤£¶}¼ú 99:¨ú®ø°h¿ú)" ANSI_RESET ":", buf, 3, LCECHO);
- bet = atoi(buf);
- move(0, 0);
- clrtoeol();
- } while ((bet < 0 || bet > count) && bet != 99);
- if (bet == 0) {
- unlockutmpmode();
- return 0;
- }
- getdata(21, 0, ANSI_COLOR(1) "¦A¦¸½T»{¿é¤J¸¹½X" ANSI_RESET ":", buf, 3, LCECHO);
- } while (bet != atoi(buf));
-
- // before we fork to process,
- // confirm lock status is correct.
- setbfile(buf, bh->brdname, FN_TICKET_END);
- setbfile(outcome, bh->brdname, FN_TICKET_LOCK);
-
- if(access(outcome, 0) == 0)
- {
- unlockutmpmode();
- vmsg("¤w¥t¦³¤H¶}¼ú¡A¨t²Îµy«á±N¦Û°Ê¤½§G¤¤¼úµ²ªG©ó¬ÝªO");
- return 0;
- }
- if(rename(buf, outcome) != 0)
- {
- unlockutmpmode();
- vmsg("µLªk·Ç³Æ¶}¼ú... ½Ð¦Ü " GLOBAL_BUGREPORT " ³ø§i¨Ãªþ¤WªO¦W¡C");
- return 0;
-
- }
-
- if (fork()) {
- /* Ptt: ¥Î fork() ¨¾¤î¤£¥¿±`Â_½u¬~¿ú */
- unlockutmpmode();
- vmsg("¨t²Îµy«á±N¦Û°Ê¤½§G©ó¤¤¼úµ²ªG¬ÝªO(°Ñ¥[ªÌ¦h®É­n¼Æ¤ÀÄÁ)..");
- return 0;
- }
- close(0);
- close(1);
- setproctitle("open ticket");
-#ifdef CPULIMIT
- {
- struct rlimit rml;
- rml.rlim_cur = RLIM_INFINITY;
- rml.rlim_max = RLIM_INFINITY;
- setrlimit(RLIMIT_CPU, &rml);
- }
-#endif
-
-
- bet--; /* Âন¯x°}ªºindex */
-
- total = load_ticket_record(path, ticket);
- setbfile(buf, bh->brdname, FN_TICKET_LOCK);
- if (!(fp1 = fopen(buf, "r")))
- exit(1);
-
- /* ÁÙ¨S¶}§¹¼ú¤£¯à½ä³Õ ¥u­nmv¤@¶µ´N¦n */
- if (bet != 98) {
- money = total * price;
- demoney(money * 0.02);
- mail_redenvelop("[½ä³õ©âÀY]", cuser.userid, money * 0.02, 'n');
- money = ticket[bet] ? money * 0.95 / ticket[bet] : 9999999;
- } else {
- vice(price * 10, "½ä½L°h¿ú¤âÄò¶O");
- money = price;
- }
- setbfile(outcome, bh->brdname, FN_TICKET_OUTCOME);
- if ((fp = fopen(outcome, "w"))) {
- fprintf(fp, "½ä½L»¡©ú\n");
- while (fgets(buf, sizeof(buf), fp1)) {
- buf[sizeof(buf)-1] = 0;
- fputs(buf, fp);
- }
- fprintf(fp, "¤Uª`±¡ªp\n");
-
- fprintf(fp, ANSI_COLOR(33));
- for (i = 0; i < count; i++) {
- fprintf(fp, "%d.%-8s: %-7d", i + 1, betname[i], ticket[i]);
- if (i == 3)
- fprintf(fp, "\n");
- }
- fprintf(fp, ANSI_RESET "\n");
-
- if (bet != 98) {
- fprintf(fp, "\n\n¶}¼ú®É¶¡¡G %s \n\n"
- "¶}¼úµ²ªG¡G %s \n\n"
- "©Ò¦³ª÷ÃB¡G %d ¤¸ \n"
- "¤¤¼ú¤ñ¨Ò¡G %d±i/%d±i (%f)\n"
- "¨C±i¤¤¼ú±m²¼¥i±o %d " MONEYNAME "¹ô \n\n",
- Cdatelite(&now), betname[bet], total * price, ticket[bet], total,
- (float)ticket[bet] / total, money);
-
- fprintf(fp, "%s ½ä½L¶}¥X:%s ©Ò¦³ª÷ÃB:%d ¤¸ ¼úª÷/±i:%d ¤¸ ¾÷²v:%1.2f\n\n",
- Cdatelite(&now), betname[bet], total * price, money,
- total ? (float)ticket[bet] / total : 0);
- } else
- fprintf(fp, "\n\n½ä½L¨ú®ø°h¿ú¡G %s \n\n", Cdatelite(&now));
-
- } // XXX somebody may use fp even fp==NULL
- fclose(fp1);
- /*
- * ¥H¤U¬Oµ¹¿ú°Ê§@
- */
- setbfile(buf, bh->brdname, FN_TICKET_USER);
- if ((bet == 98 || ticket[bet]) && (fp1 = fopen(buf, "r"))) {
- int mybet, uid;
- char userid[IDLEN + 1];
-
- while (fscanf(fp1, "%s %d %d\n", userid, &mybet, &i) != EOF) {
- if (bet == 98 && mybet >= 0 && mybet < count) {
- if (fp)
- fprintf(fp, "%s ¶R¤F %d ±i %s, °h¦^ %d ªT" MONEYNAME "¹ô\n"
- ,userid, i, betname[mybet], money * i);
- snprintf(buf, sizeof(buf),
- "%s ½ä³õ°h¿ú! $ %d", bh->brdname, money * i);
- } else if (mybet == bet) {
- if (fp)
- fprintf(fp, "®¥³ß %s ¶R¤F%d ±i %s, Àò±o %d ªT" MONEYNAME "¹ô\n"
- ,userid, i, betname[mybet], money * i);
- snprintf(buf, sizeof(buf), "%s ¤¤¼ú«¨! $ %d", bh->brdname, money * i);
- } else
- continue;
- if ((uid = searchuser(userid, userid)) == 0)
- continue;
- deumoney(uid, money * i);
- mail_id(userid, buf, "etc/ticket.win", BBSMNAME "½ä³õ");
- }
- fclose(fp1);
- }
- if (fp) {
- fprintf(fp, "\n--\n¡° ¶}¼ú¯¸ :" BBSNAME "(" MYHOSTNAME
- ") \n¡» From: %s\n", fromhost);
- fclose(fp);
- }
-
- if (bet != 98)
- snprintf(buf, sizeof(buf), "[¤½§i] %s ½ä½L¶}¼ú", bh->brdname);
- else
- snprintf(buf, sizeof(buf), "[¤½§i] %s ½ä½L¨ú®ø", bh->brdname);
- post_file(bh->brdname, buf, outcome, "[½ä¯«]");
- post_file("Record", buf + 7, outcome, "[°¨¸ô±´¤l]");
- post_file(GLOBAL_SECURITY, buf + 7, outcome, "[°¨¸ô±´¤l]");
-
- setbfile(buf, bh->brdname, FN_TICKET_RECORD);
- unlink(buf);
-
- setbfile(buf, bh->brdname, FN_TICKET_USER);
- post_file(GLOBAL_SECURITY, bh->brdname, buf, "[¤Uª`¬ö¿ý]");
- unlink(buf);
-
- setbfile(buf, bh->brdname, FN_TICKET_LOCK);
- unlink(buf);
- exit(1);
- return 0;
-}
-
-int
-ticket_main(void)
-{
- ticket(0);
- return 0;
-}
diff --git a/mbbsd/go.c b/mbbsd/go.c
deleted file mode 100644
index 44cf9cc8..00000000
--- a/mbbsd/go.c
+++ /dev/null
@@ -1,1118 +0,0 @@
-/* $Id$ */
-
-#include "bbs.h"
-#include <sys/socket.h>
-
-#define BBLANK (-1) /* ªÅ¥Õ */
-#define BWHITE (0) /* ¥Õ¤l, «á¤â */
-#define BBLACK (1) /* ¶Â¤l, ¥ý¤â */
-#define LWHITE (2) /* ¥ÕªÅ */
-#define LBLACK (3) /* ¶ÂªÅ */
-
-/* only used for communicating */
-#define SETHAND (5) /* Åý¤l */
-#define CLEAN (6) /* ²M°£¦º¤l */
-#define UNCLEAN (7) /* ²M°£¿ù¤l¡A­«·s¨Ó¹L*/
-#define CLEANDONE (8) /* ¶}©l­p¦a */
-
-#define MAX_TIME (300)
-
-#define BOARD_LINE_ON_SCREEN(X) ((X) + 2)
-
-#define BRDSIZ (19) /* ´Ñ½L³æÃä¤j¤p */
-
-static const char* turn_color[] = { ANSI_COLOR(37;43), ANSI_COLOR(30;43) };
-
-static const rc_t SetHandPoints[] =
-{
- /* 1 */ { 0, 0},
- /* 2 */ { 3, 3}, {15, 15},
- /* 3 */ { 3, 3}, { 3, 15}, {15, 15},
- /* 4 */ { 3, 3}, { 3, 15}, {15, 3}, {15, 15},
- /* 5 */ { 3, 3}, { 3, 15}, { 9, 9}, {15, 3}, {15, 15},
- /* 6 */ { 3, 3}, { 3, 15}, { 9, 3}, { 9, 15}, {15, 3}, {15, 15},
- /* 7 */ { 3, 3}, { 3, 15}, { 9, 3}, { 9, 9}, { 9, 15}, {15, 3},
- {15, 15},
- /* 8 */ { 3, 3}, { 3, 9}, { 3, 15}, { 9, 3}, { 9, 15}, {15, 3},
- {15, 9}, {15, 15},
- /* 9 */ { 3, 3}, { 3, 9}, { 3, 15}, { 9, 3}, { 9, 9}, { 9, 15},
- {15, 3}, {15, 9}, {15, 15},
-};
-
-typedef char board_t[BRDSIZ][BRDSIZ];
-typedef char (*board_p)[BRDSIZ];
-
-typedef struct {
- ChessStepType type; /* necessary one */
- int color;
- rc_t loc;
-} go_step_t;
-#define RC_T_EQ(X,Y) ((X).r == (Y).r && (X).c == (Y).c)
-
-typedef struct {
- board_t backup_board;
- char game_end;
- char clean_end; /* bit 1 => I, bit 2 => he */
- char need_redraw;
- float feed_back; /* ¶KÁÙ */
- int eaten[2];
- int backup_eaten[2];
- rc_t forbidden[2]; /* ¥´§T¤§¸T¤â */
-} go_tag_t;
-#define GET_TAG(INFO) ((go_tag_t*)(INFO)->tag)
-
-static char * const locE = "ABCDEFGHJKLMNOPQRST";
-
-static void go_init_user(const userinfo_t* uinfo, ChessUser* user);
-static void go_init_user_userec(const userec_t* urec, ChessUser* user);
-static void go_init_board(board_t board);
-static void go_drawline(const ChessInfo* info, int line);
-static void go_movecur(int r, int c);
-static int go_prepare_play(ChessInfo* info);
-static int go_process_key(ChessInfo* info, int key, ChessGameResult* result);
-static int go_select(ChessInfo* info, rc_t location,
- ChessGameResult* result);
-static void go_prepare_step(ChessInfo* info, const go_step_t* step);
-static ChessGameResult go_apply_step(board_t board, const go_step_t* step);
-static void go_drawstep(ChessInfo* info, const go_step_t* step);
-static ChessGameResult go_post_game(ChessInfo* info);
-static void go_gameend(ChessInfo* info, ChessGameResult result);
-static void go_genlog(ChessInfo* info, FILE* fp, ChessGameResult result);
-
-const static ChessActions go_actions = {
- &go_init_user,
- &go_init_user_userec,
- (void (*)(void*)) &go_init_board,
- &go_drawline,
- &go_movecur,
- &go_prepare_play,
- &go_process_key,
- &go_select,
- (void (*)(ChessInfo*, const void*)) &go_prepare_step,
- (ChessGameResult (*)(void*, const void*)) &go_apply_step,
- (void (*)(ChessInfo*, const void*)) &go_drawstep,
- &go_post_game,
- &go_gameend,
- &go_genlog
-};
-
-const static ChessConstants go_constants = {
- sizeof(go_step_t),
- MAX_TIME,
- BRDSIZ,
- BRDSIZ,
- 1,
- "³ò´Ñ",
- "photo_go",
-#ifdef GLOBAL_GOCHESS_LOG
- GLOBAL_GOCHESS_LOG,
-#else
- NULL,
-#endif
- { ANSI_COLOR(37;43), ANSI_COLOR(30;43) },
- { "¥Õ´Ñ", "¶Â´Ñ" },
-};
-
-static void
-go_sethand(board_t board, int n)
-{
- if (n >= 2 && n <= 9) {
- const int lower = n * (n - 1) / 2;
- const int upper = lower + n;
- int i;
- for (i = lower; i < upper; ++i)
- board[SetHandPoints[i].r][SetHandPoints[i].c] = BBLACK;
- }
-}
-
-/* ­pºâ¬Y¤lªº®ð¼Æ, recursion part of go_countlib() */
-static int
-go_count(board_t board, board_t mark, int x, int y, int color)
-{
- const static int diff[][2] = {
- {1, 0}, {-1, 0}, {0, 1}, {0, -1}
- };
- int i;
- int total = 0;
-
- mark[x][y] = 0;
-
- for (i = 0; i < 4; ++i) {
- int xx = x + diff[i][0];
- int yy = y + diff[i][1];
-
- if (xx >= 0 && xx < BRDSIZ && yy >= 0 && yy < BRDSIZ) {
- if (board[xx][yy] == BBLANK && mark[xx][yy]) {
- ++total;
- mark[xx][yy] = 0;
- } else if (board[xx][yy] == color && mark[xx][yy])
- total += go_count(board, mark, xx, yy, color);
- }
- }
-
- return total;
-}
-
-/* ­pºâ¬Y¤lªº®ð¼Æ */
-static int
-go_countlib(board_t board, int x, int y, char color)
-{
- int i, j;
- board_t mark;
-
- for (i = 0; i < BRDSIZ; i++)
- for (j = 0; j < BRDSIZ; j++)
- mark[i][j] = 1;
-
- return go_count(board, mark, x, y, color);
-}
-
-/* ­pºâ½L­±¤W¨C­Ó¤lªº®ð¼Æ */
-static void
-go_eval(board_t board, int lib[][BRDSIZ], char color)
-{
- int i, j;
-
- for (i = 0; i < 19; i++)
- for (j = 0; j < 19; j++)
- if (board[i][j] == color)
- lib[i][j] = go_countlib(board, i, j, color);
-}
-
-/* Àˬd¤@¨B¬O§_¦Xªk */
-static int
-go_check(ChessInfo* info, const go_step_t* step)
-{
- board_p board = (board_p) info->board;
- int lib = go_countlib(board, step->loc.r, step->loc.c, step->color);
-
- if (lib == 0) {
- int i, j;
- int board_lib[BRDSIZ][BRDSIZ];
- go_tag_t* tag = (go_tag_t*) info->tag;
-
- board[step->loc.r][step->loc.c] = step->color;
- go_eval(board, board_lib, !step->color);
- board[step->loc.r][step->loc.c] = BBLANK; /* restore to open */
-
- lib = 0;
- for (i = 0; i < BRDSIZ; i++)
- for (j = 0; j < BRDSIZ; j++)
- if (board[i][j] == !step->color && !board_lib[i][j])
- ++lib;
-
- if (lib == 0 ||
- (lib == 1 && RC_T_EQ(step->loc, tag->forbidden[step->color])))
- return 0;
- else
- return 1;
- } else
- return 1;
-}
-
-/* Clean up the dead chess of color `color,' summarize number of
- * eaten chesses and set the forbidden point.
- *
- * `info' might be NULL which means no forbidden point check is
- * needed and don't have to count the number of eaten chesses.
- *
- * Return: 1 if any chess of color `color' was eaten; 0 otherwise. */
-static int
-go_examboard(board_t board, int color, ChessInfo* info)
-{
- int i, j, n;
- int lib[BRDSIZ][BRDSIZ];
-
- rc_t dummy_rc;
- rc_t *forbidden;
- int dummy_eaten;
- int *eaten;
-
- if (info) {
- go_tag_t* tag = (go_tag_t*) info->tag;
- forbidden = &tag->forbidden[color];
- eaten = &tag->eaten[!color];
- } else {
- forbidden = &dummy_rc;
- eaten = &dummy_eaten;
- }
-
- go_eval(board, lib, color);
-
- forbidden->r = -1;
- forbidden->c = -1;
-
- n = 0;
- for (i = 0; i < BRDSIZ; i++)
- for (j = 0; j < BRDSIZ; j++)
- if (board[i][j] == color && lib[i][j] == 0) {
- board[i][j] = BBLANK;
- forbidden->r = i;
- forbidden->c = j;
- ++*eaten;
- ++n;
- }
-
- if ( n != 1 ) {
- /* No or more than one chess were eaten,
- * no forbidden points, then. */
- forbidden->r = -1;
- forbidden->c = -1;
- }
-
- return (n > 0);
-}
-
-static int
-go_clean(board_t board, int mark[][BRDSIZ], int x, int y, int color)
-{
- const static int diff[][2] = {
- {1, 0}, {-1, 0}, {0, 1}, {0, -1}
- };
- int i;
- int total = 1;
-
- mark[x][y] = 0;
- board[x][y] = BBLANK;
-
- for (i = 0; i < 4; ++i) {
- int xx = x + diff[i][0];
- int yy = y + diff[i][1];
-
- if (xx >= 0 && xx < BRDSIZ && yy >= 0 && yy < BRDSIZ) {
- if ((board[xx][yy] == color) && mark[xx][yy])
- total += go_clean(board, mark, xx, yy, color);
- }
- }
-
- return total;
-}
-
-static int
-go_cleandead(board_t board, int x, int y)
-{
- int mark[BRDSIZ][BRDSIZ];
- int i, j;
-
- if (board[x][y] == BBLANK)
- return 0;
-
- for (i = 0; i < BRDSIZ; i++)
- for (j = 0; j < BRDSIZ; j++)
- mark[i][j] = 1;
-
- return go_clean(board, mark, x, y, board[x][y]);
-}
-
-static int
-go_findcolor(board_p board, int x, int y)
-{
- int k, result = 0, color[4];
-
- if (board[x][y] != BBLANK)
- return BBLANK;
-
- if (x > 0)
- {
- k = x;
- do --k;
- while ((board[k][y] == BBLANK) && (k > 0));
- color[0] = board[k][y];
- }
- else
- color[0] = board[x][y];
-
- if (x < 18)
- {
- k = x;
- do ++k;
- while ((board[k][y] == BBLANK) && (k < 18));
- color[1] = board[k][y];
- }
- else
- color[1] = board[x][y];
-
- if (y > 0)
- {
- k = y;
- do --k;
- while ((board[x][k] == BBLANK) && (k > 0));
- color[2] = board[x][k];
- }
- else color[2] = board[x][y];
-
- if (y < 18)
- {
- k = y;
- do ++k;
- while ((board[x][k] == BBLANK) && (k < 18));
- color[3] = board[x][k];
- }
- else
- color[3] = board[x][y];
-
- for (k = 0; k < 4; k++)
- {
- if (color[k] == BBLANK)
- continue;
- else
- {
- result = color[k];
- break;
- }
- }
- if (k == 4)
- return BBLANK;
-
- for (k = 0; k < 4; k++)
- {
- if ((color[k] != BBLANK) && (color[k] != result))
- return BBLANK;
- }
-
- return result;
-}
-
-static int
-go_result(ChessInfo* info)
-{
- int i, j;
- int count[2];
- board_p board = (board_p) info->board;
- go_tag_t *tag = (go_tag_t*) info->tag;
- board_t result_board;
-
- memcpy(result_board, board, sizeof(result_board));
- count[0] = count[1] = 0;
-
- for (i = 0; i < 19; i++)
- for (j = 0; j < 19; j++)
- if (board[i][j] == BBLANK)
- {
- int result = go_findcolor(board, i, j);
- if (result != BBLANK) {
- count[result]++;
-
- /* BWHITE => LWHITE, BBLACK => LBLACK */
- result_board[i][j] = result + 2;
- }
- }
- else
- count[(int) board[i][j]]++;
-
- memcpy(board, result_board, sizeof(result_board));
-
- /* ¦º¤l¦^¶ñ */
- count[0] -= tag->eaten[1];
- count[1] -= tag->eaten[0];
-
- tag->eaten[0] = count[0];
- tag->eaten[1] = count[1];
-
- if (tag->feed_back < 0.01 && tag->eaten[0] == tag->eaten[1])
- return BBLANK; /* tie */
- else
- return tag->eaten[0] + tag->feed_back > tag->eaten[1] ?
- BWHITE : BBLACK;
-}
-
-static char*
-go_getstep(const go_step_t* step, char buf[])
-{
- const static char* const ColName = "¢Ï¢Ð¢Ñ¢Ò¢Ó¢Ô¢Õ¢Ö¢Ø¢Ù¢Ú¢Û¢Ü¢Ý¢Þ¢ß¢à¢á¢â";
- const static char* const RawName = "19181716151413121110¢¸¢·¢¶¢µ¢´¢³¢²¢±¢°";
- const static int ansi_length = sizeof(ANSI_COLOR(30;43)) - 1;
-
- strcpy(buf, turn_color[step->color]);
- buf[ansi_length ] = ColName[step->loc.c * 2];
- buf[ansi_length + 1] = ColName[step->loc.c * 2 + 1];
- buf[ansi_length + 2] = RawName[step->loc.r * 2];
- buf[ansi_length + 3] = RawName[step->loc.r * 2 + 1];
- strcpy(buf + ansi_length + 4, ANSI_RESET " ");
-
- return buf;
-}
-
-static void
-go_init_tag(go_tag_t* tag)
-{
- tag->game_end = 0;
- tag->need_redraw = 0;
- tag->feed_back = 5.5;
- tag->eaten[0] = 0;
- tag->eaten[1] = 0;
- tag->forbidden[0].r = -1;
- tag->forbidden[0].c = -1;
- tag->forbidden[1].r = -1;
- tag->forbidden[1].c = -1;
-}
-
-static void
-go_init_user(const userinfo_t* uinfo, ChessUser* user)
-{
- strlcpy(user->userid, uinfo->userid, sizeof(user->userid));
- user->win = uinfo->go_win;
- user->lose = uinfo->go_lose;
- user->tie = uinfo->go_tie;
-}
-
-static void
-go_init_user_userec(const userec_t* urec, ChessUser* user)
-{
- strlcpy(user->userid, urec->userid, sizeof(user->userid));
- user->win = urec->go_win;
- user->lose = urec->go_lose;
- user->tie = urec->go_tie;
-}
-
-static void
-go_init_board(board_t board)
-{
- memset(board, BBLANK, sizeof(board_t));
-}
-
-static void
-go_drawline(const ChessInfo* info, int line)
-{
- const static char* const BoardPic[] = {
- "ùÝ", "ùç", "ùç", "ùß",
- "ùò", "¢q", "¢q", "ùô",
- "ùò", "¢q", "¡Ï", "ùô",
- "ùã", "ùí", "ùí", "ùå",
- };
- const static int BoardPicIndex[] =
- { 0, 1, 1, 2, 1,
- 1, 1, 1, 1, 2,
- 1, 1, 1, 1, 1,
- 2, 1, 1, 3 };
-
- board_p board = (board_p) info->board;
- go_tag_t* tag = (go_tag_t*) info->tag;
-
- if (line == 0) {
- prints(ANSI_COLOR(1;46) " ³ò´Ñ¹ï¾Ô " ANSI_COLOR(45)
- "%30s VS %-20s%10s" ANSI_RESET,
- info->user1.userid, info->user2.userid,
- info->mode == CHESS_MODE_WATCH ? "[Æ[´Ñ¼Ò¦¡]" : "");
- } else if (line == 1) {
- outs(" A B C D E F G H J K L M N O P Q R S T");
- } else if (line >= 2 && line <= 20) {
- const int board_line = line - 2;
- const char* const* const pics =
- &BoardPic[BoardPicIndex[board_line] * 4];
- int i;
-
- prints("%2d" ANSI_COLOR(30;43), 21 - line);
-
- for (i = 0; i < BRDSIZ; ++i)
- if (board[board_line][i] == BBLANK)
- outs(pics[BoardPicIndex[i]]);
- else
- outs(bw_chess[(int) board[board_line][i]]);
-
- outs(ANSI_RESET);
- } else if (line >= 21 && line < b_lines)
- prints("%40s", "");
- else if (line == b_lines) {
- if (info->mode == CHESS_MODE_VERSUS ||
- info->mode == CHESS_MODE_PERSONAL) {
- if (tag->game_end)
- outs(ANSI_COLOR(31;47) "(w)" ANSI_COLOR(30) "­p¦a" ANSI_RESET);
- else if (info->history.used == 0 && (info->myturn == BWHITE
- || info->mode == CHESS_MODE_PERSONAL))
- outs(ANSI_COLOR(31;47) "(x)" ANSI_COLOR(30) "±Â¤l" ANSI_RESET);
- }
- }
-
- if (line == 1 || line == 2) {
- int color = line - 1; /* BWHITE or BBLACK */
-
- if (tag->game_end && tag->clean_end == 3)
- prints(" " ANSI_COLOR(30;43) "%s" ANSI_RESET
- " ¤è¤lªÅ¡G%3.1f", bw_chess[color],
- tag->eaten[color] +
- (color == BWHITE ? tag->feed_back : 0.0));
- else
- prints(" " ANSI_COLOR(30;43) "%s" ANSI_RESET
- " ¤è´£¤l¼Æ¡G%3d", bw_chess[color], tag->eaten[color]);
- } else
- ChessDrawExtraInfo(info, line, 3);
-}
-
-static void
-go_movecur(int r, int c)
-{
- move(r + 2, c * 2 + 3);
-}
-
-static int
-go_prepare_play(ChessInfo* info)
-{
- if (((go_tag_t*) info->tag)->game_end) {
- strlcpy(info->warnmsg, "½Ð²M°£¦º¤l¡A¥H«K­pºâ³Ó­t",
- sizeof(info->warnmsg));
- if (info->last_movestr[0] != ' ')
- strcpy(info->last_movestr, " ");
- }
-
- if (info->history.used == 1)
- ChessDrawLine(info, b_lines); /* clear the 'x' instruction */
-
- return 0;
-}
-
-static int
-go_process_key(ChessInfo* info, int key, ChessGameResult* result)
-{
- go_tag_t* tag = (go_tag_t*) info->tag;
- if (tag->game_end) {
- if (key == 'w') {
- if (!(tag->clean_end & 1)) {
- go_step_t step = { CHESS_STEP_SPECIAL, CLEANDONE };
- ChessStepSend(info, &step);
- tag->clean_end |= 1;
- }
-
- if (tag->clean_end & 2 || info->mode == CHESS_MODE_PERSONAL) {
- /* both sides agree */
- int winner = go_result(info);
-
- tag->clean_end = 3;
-
- if (winner == BBLANK)
- *result = CHESS_RESULT_TIE;
- else
- *result = (winner == info->myturn ?
- CHESS_RESULT_WIN : CHESS_RESULT_LOST);
-
- ChessRedraw(info);
- return 1;
- }
- } else if (key == 'u') {
- char buf[4];
- getdata(b_lines, 0, "¬O§_¯uªº­n­«·sÂI¦º¤l? (y/N)",
- buf, sizeof(buf), DOECHO);
- ChessDrawLine(info, b_lines);
-
- if (buf[0] == 'y' || buf[0] == 'Y') {
- go_step_t step = { CHESS_STEP_SPECIAL, UNCLEAN };
- ChessStepSend(info, &step);
-
- memcpy(info->board, tag->backup_board, sizeof(tag->backup_board));
- tag->eaten[0] = tag->backup_eaten[0];
- tag->eaten[1] = tag->backup_eaten[1];
- }
- }
- } else if (key == 'x' && info->history.used == 0 &&
- ((info->mode == CHESS_MODE_VERSUS && info->myturn == BWHITE) ||
- info->mode == CHESS_MODE_PERSONAL)) {
- char buf[4];
- int n;
-
- getdata(22, 43, "­n±Â¦h¤Ö¤l©O(2 - 9)¡H ", buf, sizeof(buf), DOECHO);
- n = atoi(buf);
-
- if (n >= 2 && n <= 9) {
- go_step_t step = { CHESS_STEP_NORMAL, SETHAND, {n, 0} };
-
- ChessStepSend(info, &step);
- ChessHistoryAppend(info, &step);
-
- go_sethand(info->board, n);
- ((go_tag_t*)info->tag)->feed_back = 0.0;
-
- snprintf(info->last_movestr, sizeof(info->last_movestr),
- ANSI_COLOR(1) "±Â %d ¤l" ANSI_RESET, n);
- ChessRedraw(info);
- return 1;
- } else
- ChessDrawLine(info, 22);
- }
- return 0;
-}
-
-static int
-go_select(ChessInfo* info, rc_t location, ChessGameResult* result)
-{
- board_p board = (board_p) info->board;
-
- if (GET_TAG(info)->game_end) {
- go_step_t step = { CHESS_STEP_SPECIAL, CLEAN, location };
- if (board[location.r][location.c] == BBLANK)
- return 0;
-
- GET_TAG(info)->eaten[!board[location.r][location.c]] +=
- go_cleandead(board, location.r, location.c);
-
- ChessStepSend(info, &step);
- ChessRedraw(info);
- return 0; /* don't have to return from ChessPlayFuncMy() */
- } else {
- go_step_t step = { CHESS_STEP_NORMAL, info->turn, location };
-
- if (board[location.r][location.c] != BBLANK)
- return 0;
-
- if (go_check(info, &step)) {
- board[location.r][location.c] = info->turn;
- ChessStepSend(info, &step);
- ChessHistoryAppend(info, &step);
-
- go_getstep(&step, info->last_movestr);
- if (go_examboard(board, !info->myturn, info))
- ChessRedraw(info);
- else
- ChessDrawLine(info, BOARD_LINE_ON_SCREEN(location.r));
- return 1;
- } else
- return 0;
- }
-}
-
-static void
-go_prepare_step(ChessInfo* info, const go_step_t* step)
-{
- go_tag_t* tag = GET_TAG(info);
- if (tag->game_end) {
- /* some actions need tag so are done here */
- if (step->color == CLEAN) {
- board_p board = (board_p) info->board;
- tag->eaten[!board[step->loc.r][step->loc.c]] +=
- go_cleandead(board, step->loc.r, step->loc.c);
- } else if (step->color == UNCLEAN) {
- memcpy(info->board, tag->backup_board, sizeof(tag->backup_board));
- tag->eaten[0] = tag->backup_eaten[0];
- tag->eaten[1] = tag->backup_eaten[1];
- } else if (step->color == CLEANDONE) {
- if (tag->clean_end & 1) {
- /* both sides agree */
- int winner = go_result(info);
-
- tag->clean_end = 3;
-
- if (winner == BBLANK)
- ((go_step_t*)step)->loc.r = (int) CHESS_RESULT_TIE;
- else
- ((go_step_t*)step)->loc.r = (int)
- (winner == info->myturn ?
- CHESS_RESULT_WIN : CHESS_RESULT_LOST);
-
- ChessRedraw(info);
- } else {
- ((go_step_t*)step)->color = BBLANK; /* tricks apply */
- tag->clean_end |= 2;
- }
- }
- } else if (step->type == CHESS_STEP_NORMAL) {
- if (step->color != SETHAND) {
- go_getstep(step, info->last_movestr);
-
- memcpy(tag->backup_board, info->board, sizeof(board_t));
- tag->backup_board[step->loc.r][step->loc.c] = step->color;
-
- /* if any chess was eaten, wholely redraw is needed */
- tag->need_redraw =
- go_examboard(tag->backup_board, !step->color, info);
- } else {
- snprintf(info->last_movestr, sizeof(info->last_movestr),
- ANSI_COLOR(1) "±Â %d ¤l" ANSI_RESET, step->loc.r);
- tag->need_redraw = 1;
- ((go_tag_t*)info->tag)->feed_back = 0.0;
- }
- } else if (step->type == CHESS_STEP_PASS)
- strcpy(info->last_movestr, "µê¤â");
-}
-
-static ChessGameResult
-go_apply_step(board_t board, const go_step_t* step)
-{
- if (step->type != CHESS_STEP_NORMAL)
- return CHESS_RESULT_CONTINUE;
-
- switch (step->color) {
- case BWHITE:
- case BBLACK:
- board[step->loc.r][step->loc.c] = step->color;
- go_examboard(board, !step->color, NULL);
- break;
-
- case SETHAND:
- go_sethand(board, step->loc.r);
- break;
-
- case CLEAN:
- go_cleandead(board, step->loc.r, step->loc.c);
- break;
-
- case CLEANDONE:
- /* should be agreed by both sides, [see go_prepare_step()] */
- return (ChessGameResult) step->loc.r;
- }
- return CHESS_RESULT_CONTINUE;
-}
-
-static void
-go_drawstep(ChessInfo* info, const go_step_t* step)
-{
- go_tag_t* tag = GET_TAG(info);
- if (tag->game_end || tag->need_redraw)
- ChessRedraw(info);
- else
- ChessDrawLine(info, BOARD_LINE_ON_SCREEN(step->loc.r));
-}
-
-static ChessGameResult
-go_post_game(ChessInfo* info)
-{
- extern ChessGameResult ChessPlayFuncMy(ChessInfo* info);
-
- go_tag_t *tag = (go_tag_t*) info->tag;
- ChessTimeLimit *orig_limit = info->timelimit;
- ChessGameResult result;
-
- info->timelimit = NULL;
- info->turn = info->myturn;
- strcpy(info->warnmsg, "½ÐÂI°£¦º¤l");
- ChessDrawLine(info, CHESS_DRAWING_WARN_ROW);
-
- memcpy(tag->backup_board, info->board, sizeof(tag->backup_board));
- tag->game_end = 1;
- tag->clean_end = 0;
- tag->backup_eaten[0] = tag->eaten[0];
- tag->backup_eaten[1] = tag->eaten[1];
-
- ChessDrawLine(info, b_lines); /* 'w' instruction */
-
- while ((result = ChessPlayFuncMy(info)) == CHESS_RESULT_CONTINUE);
-
- ChessRedraw(info);
-
- info->timelimit = orig_limit;
-
- return result;
-}
-
-static void
-go_gameend(ChessInfo* info, ChessGameResult result)
-{
- if (info->mode == CHESS_MODE_VERSUS) {
- ChessUser* const user1 = &info->user1;
- /* ChessUser* const user2 = &info->user2; */
-
- user1->lose--;
- if (result == CHESS_RESULT_WIN) {
- user1->win++;
- currutmp->go_win++;
- } else if (result == CHESS_RESULT_LOST) {
- user1->lose++;
- currutmp->go_lose++;
- } else {
- user1->tie++;
- currutmp->go_tie++;
- }
-
- cuser.go_win = user1->win;
- cuser.go_lose = user1->lose;
- cuser.go_tie = user1->tie;
-
- passwd_update(usernum, &cuser);
- } else if (info->mode == CHESS_MODE_REPLAY) {
- free(info->board);
- free(info->tag);
- }
-}
-
-static void
-go_genlog(ChessInfo* info, FILE* fp, ChessGameResult result)
-{
- const static char ColName[] = "ABCDEFGHJKLMNOPQRST";
- const int nStep = info->history.used;
- char buf[ANSILINELEN] = "";
- int i, x, y;
- int sethand = 0;
-
- if (nStep > 0) {
- const go_step_t* const step =
- (const go_step_t*) ChessHistoryRetrieve(info, 0);
- if (step->color == SETHAND)
- sethand = step->loc.r;
- }
-
- getyx(&y, &x);
- for (i = 1; i <= 22; i++)
- {
- move(i, 0);
- inansistr(buf, sizeof(buf)-1);
- fprintf(fp, "%s\n", buf);
- }
- move(y, x);
-
- fprintf(fp, "\n");
- fprintf(fp, "«ö z ¥i¶i¤J¥´ÃмҦ¡\n");
- fprintf(fp, "\n");
-
- if (sethand) {
- fprintf(fp, "[ 1] ±Â %d ¤l\n ", sethand);
- i = 1;
- } else
- i = 0;
-
- for (; i < nStep; ++i) {
- const go_step_t* const step =
- (const go_step_t*) ChessHistoryRetrieve(info, i);
- if (step->type == CHESS_STEP_NORMAL)
- fprintf(fp, "[%3d]%s => %c%-4d", i + 1, bw_chess[step->color],
- ColName[step->loc.c], 19 - step->loc.r);
- else if (step->type == CHESS_STEP_PASS)
- fprintf(fp, "[%3d]%s => µê¤â ", i + 1, bw_chess[(i + 1) % 2]);
- else
- break;
- if (i % 5 == 4)
- fputc('\n', fp);
- }
-
- fprintf(fp,
- "\n\n¡m¥H¤U¬° sgf ®æ¦¡´ÑÃСn\n<golog>\n(;GM[1]"
- "GN[%s-%s(W) Ptt]\n"
- "SZ[19]HA[%d]PB[%s]PW[%s]\n"
- "PC[FPG BBS/Ptt BBS: ptt.cc]\n",
- info->user1.userid, info->user2.userid,
- sethand,
- info->user1.userid, info->user2.userid);
-
- if (sethand) {
- const int lower = sethand * (sethand - 1) / 2;
- const int upper = lower + sethand;
- int j;
- fputs("AB", fp);
- for (j = lower; j < upper; ++j)
- fprintf(fp, "[%c%c]",
- SetHandPoints[j].c + 'a',
- SetHandPoints[j].r + 'a');
- fputc('\n', fp);
- }
-
- for (i = (sethand ? 1 : 0); i < nStep; ++i) {
- const go_step_t* const step =
- (const go_step_t*) ChessHistoryRetrieve(info, i);
- if (step->type == CHESS_STEP_NORMAL)
- fprintf(fp, ";%c[%c%c]",
- step->color == BWHITE ? 'W' : 'B',
- step->loc.c + 'a',
- step->loc.r + 'a');
- else if (step->type == CHESS_STEP_PASS)
- fprintf(fp, ";%c[] ", i % 2 ? 'W' : 'B');
- else
- break;
- if (i % 10 == 9)
- fputc('\n', fp);
- }
- fprintf(fp, ";)\n<golog>\n\n");
-}
-
-void
-gochess(int s, ChessGameMode mode)
-{
- ChessInfo* info = NewChessInfo(&go_actions, &go_constants, s, mode);
- board_t board;
- go_tag_t tag;
-
- go_init_board(board);
- go_init_tag(&tag);
-
- info->board = board;
- info->tag = &tag;
-
- info->cursor.r = 9;
- info->cursor.c = 9;
-
- if (mode == CHESS_MODE_WATCH)
- setutmpmode(CHESSWATCHING);
- else
- setutmpmode(UMODE_GO);
- currutmp->sig = SIG_GO;
-
- ChessPlay(info);
-
- DeleteChessInfo(info);
-}
-
-int
-gochess_main(void)
-{
- return ChessStartGame('g', SIG_GO, "³ò´Ñ");
-}
-
-int
-gochess_personal(void)
-{
- gochess(0, CHESS_MODE_PERSONAL);
- return 0;
-}
-
-int
-gochess_watch(void)
-{
- return ChessWatchGame(&gochess, UMODE_GO, "³ò´Ñ");
-}
-
-static int
-mygetc(FILE* fp, char* buf, int* idx, int len)
-{
- for (;;) {
- while (buf[*idx] && isspace(buf[*idx])) ++*idx;
-
- if (buf[*idx]) {
- ++*idx;
- return buf[*idx - 1];
- }
-
- if (fgets(buf, len, fp) == NULL)
- return EOF;
-
- if (strcmp(buf, "<golog>\n") == 0)
- return EOF;
-
- *idx = 0;
- }
-}
-
-ChessInfo*
-gochess_replay(FILE* fp)
-{
- ChessInfo *info;
- int ch;
- char userid[2][IDLEN + 1] = { "", "" };
- char sethand_str[4] = "";
- char *recording = NULL;
- char *record_end = NULL;
- go_step_t step;
-
- /* for mygetc */
- char buf[512] = "";
- int idx = 0;
-
-#define GETC() mygetc(fp, buf, &idx, sizeof(buf))
-
- /* sgf file started with "(;" */
- if (GETC() != '(' || GETC() != ';')
- return NULL;
-
- /* header info */
- while ((ch = GETC()) != EOF && ch != ';') {
- if (ch == '[') {
- if (recording) {
- while ((ch = GETC()) != EOF && ch != ']')
- if (recording < record_end)
- *recording++ = ch;
- *recording = 0;
- recording = NULL;
- } else
- while ((ch = GETC()) != EOF && ch != ']')
- continue;
-
- if (ch == EOF)
- break;
- } else if (ch == ';') /* next stage */
- break;
- else {
- int ch2 = GETC();
-
- if (ch2 == EOF) {
- ch = EOF;
- break;
- }
-
- if (ch == 'P') {
- if (ch2 == 'B') {
- recording = userid[BBLACK];
- record_end = userid[BBLACK] + IDLEN;
- } else if (ch2 == 'W') {
- recording = userid[BWHITE];
- record_end = userid[BWHITE] + IDLEN;
- }
- } else if (ch == 'H') {
- if (ch2 == 'A') {
- recording = sethand_str;
- record_end = sethand_str + sizeof(sethand_str) - 1;
- }
- }
- }
- }
-
- if (ch == EOF)
- return NULL;
-
- info = NewChessInfo(&go_actions, &go_constants,
- 0, CHESS_MODE_REPLAY);
-
- /* filling header information to info */
- if (userid[BBLANK][0]) {
- userec_t rec;
- if (getuser(userid[BBLANK], &rec))
- go_init_user_userec(&rec, &info->user1);
- }
-
- if (userid[BWHITE][0]) {
- userec_t rec;
- if (getuser(userid[BWHITE], &rec))
- go_init_user_userec(&rec, &info->user2);
- }
-
- if (sethand_str[0]) {
- int sethand = atoi(sethand_str);
- if (sethand >= 2 && sethand <= 9) {
- step.type = CHESS_STEP_NORMAL;
- step.color = SETHAND;
- step.loc.r = sethand;
- ChessHistoryAppend(info, &step);
- }
- }
-
- /* steps, ends with ")" */
- while ((ch = GETC()) != EOF && ch != ')') {
- if (ch == ';')
- ChessHistoryAppend(info, &step);
- else if (ch == 'B')
- step.color = BBLACK;
- else if (ch == 'W')
- step.color = BWHITE;
- else if (ch == '[') {
- ch = GETC();
- if (ch == EOF)
- break;
- else if (ch == ']') {
- step.type = CHESS_STEP_PASS;
- continue;
- } else
- step.loc.c = ch - 'a';
-
- ch = GETC();
- if (ch == EOF)
- break;
- else if (ch == ']') {
- step.type = CHESS_STEP_PASS;
- continue;
- } else
- step.loc.r = ch - 'a';
-
- while ((ch = GETC()) != EOF && ch != ']');
-
- if (step.loc.r < 0 || step.loc.r >= BRDSIZ ||
- step.loc.c < 0 || step.loc.c >= BRDSIZ)
- step.type = CHESS_STEP_PASS;
- else
- step.type = CHESS_STEP_NORMAL;
- }
- }
-
- info->board = malloc(sizeof(board_t));
- info->tag = malloc(sizeof(go_tag_t));
-
- go_init_board(info->board);
- go_init_tag(info->tag);
-
- return info;
-
-#undef GETC
-}
diff --git a/mbbsd/gomo.c b/mbbsd/gomo.c
deleted file mode 100644
index 90f72c63..00000000
--- a/mbbsd/gomo.c
+++ /dev/null
@@ -1,590 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-#include "gomo.h"
-
-#define QCAST int (*)(const void *, const void *)
-#define BOARD_LINE_ON_SCREEN(X) ((X) + 2)
-
-static const char* turn_color[] = { ANSI_COLOR(37;43), ANSI_COLOR(30;43) };
-
-enum Turn {
- WHT = 0,
- BLK
-};
-
-typedef struct {
- ChessStepType type; /* necessary one */
- int color;
- rc_t loc;
-} gomo_step_t;
-
-typedef char board_t[BRDSIZ][BRDSIZ];
-typedef char (*board_p)[BRDSIZ];
-
-static void gomo_init_user(const userinfo_t* uinfo, ChessUser* user);
-static void gomo_init_user_userec(const userec_t* urec, ChessUser* user);
-static void gomo_init_board(board_t board);
-static void gomo_drawline(const ChessInfo* info, int line);
-static void gomo_movecur(int r, int c);
-static int gomo_prepare_play(ChessInfo* info);
-static int gomo_select(ChessInfo* info, rc_t location,
- ChessGameResult* result);
-static void gomo_prepare_step(ChessInfo* info, const gomo_step_t* step);
-static ChessGameResult gomo_apply_step(board_t board, const gomo_step_t* step);
-static void gomo_drawstep(ChessInfo* info, const gomo_step_t* step);
-static void gomo_gameend(ChessInfo* info, ChessGameResult result);
-static void gomo_genlog(ChessInfo* info, FILE* fp, ChessGameResult result);
-
-const static ChessActions gomo_actions = {
- &gomo_init_user,
- &gomo_init_user_userec,
- (void (*)(void*)) &gomo_init_board,
- &gomo_drawline,
- &gomo_movecur,
- &gomo_prepare_play,
- NULL, /* process_key */
- &gomo_select,
- (void (*)(ChessInfo*, const void*)) &gomo_prepare_step,
- (ChessGameResult (*)(void*, const void*)) &gomo_apply_step,
- (void (*)(ChessInfo*, const void*)) &gomo_drawstep,
- NULL, /* post_game */
- &gomo_gameend,
- &gomo_genlog
-};
-
-const static ChessConstants gomo_constants = {
- sizeof(gomo_step_t),
- MAX_TIME,
- BRDSIZ,
- BRDSIZ,
- 0,
- "¤­¤l´Ñ",
- "photo_fivechess",
-#ifdef GLOBAL_FIVECHESS_LOG
- GLOBAL_FIVECHESS_LOG,
-#else
- NULL,
-#endif
- { ANSI_COLOR(37;43), ANSI_COLOR(30;43) },
- { "¥Õ´Ñ", "¶Â´Ñ, ¦³¸T¤â" },
-};
-
-/* pattern and advance map */
-
-static int
-intrevcmp(const void *a, const void *b)
-{
- return (*(int *)b - *(int *)a);
-}
-
-// ¥H (x,y) ¬°°_ÂI, ¤è¦V (dx,dy), ¶Ç¦^¥H bit ªí¥Ü¬Û¾F­þ´X®æ¦³¤l
-// ¦p 10111 ªí¥Ü¸Ó¤è¦V¬Û¾F 1,2,3 ¦³¤l, 4 ªÅ¦a
-// ³Ì°ª¦ì 1 ªí¥Ü¹ï¤èªº¤l, ©Î¬OÀð
-/* x,y: 0..BRDSIZ-1 ; color: CBLACK,CWHITE ; dx,dy: -1,0,+1 */
-static int
-gomo_getindex(board_t ku, int x, int y, int color, int dx, int dy)
-{
- int i, k, n;
- for (n = -1, i = 0, k = 1; i < 5; i++, k*=2) {
- x += dx;
- y += dy;
-
- if ((x < 0) || (x >= BRDSIZ) || (y < 0) || (y >= BRDSIZ)) {
- n += k;
- break;
- } else if (ku[x][y] != BBLANK) {
- n += k;
- if (ku[x][y] != color)
- break;
- }
- }
-
- if (i >= 5)
- n += k;
-
- return n;
-}
-
-ChessGameResult
-chkwin(int style, int limit)
-{
- if (style == 0x0c)
- return CHESS_RESULT_WIN;
- else if (limit == 0) {
- if (style == 0x0b)
- return CHESS_RESULT_WIN;
- return CHESS_RESULT_CONTINUE;
- }
- if ((style < 0x0c) && (style > 0x07))
- return CHESS_RESULT_LOST;
- return CHESS_RESULT_CONTINUE;
-}
-
-static int getstyle(board_t ku, int x, int y, int color, int limit);
-/* x,y: 0..BRDSIZ-1 ; color: CBLACK,CWHITE ; limit:1,0 ; dx,dy: 0,1 */
-static int
-dirchk(board_t ku, int x, int y, int color, int limit, int dx, int dy)
-{
- int le, ri, loc, style = 0;
-
- le = gomo_getindex(ku, x, y, color, -dx, -dy);
- ri = gomo_getindex(ku, x, y, color, dx, dy);
-
- loc = (le > ri) ? (((le * (le + 1)) >> 1) + ri) :
- (((ri * (ri + 1)) >> 1) + le);
-
- style = pat_gomoku[loc];
-
- if (limit == 0)
- return (style & 0x0f);
-
- style >>= 4;
-
- if ((style == 3) || (style == 2)) {
- int i, n = 0, tmp, nx, ny;
-
- n = adv_gomoku[loc / 2];
-
- if(loc%2==0)
- n/=16;
- else
- n%=16;
-
- ku[x][y] = color;
-
- for (i = 0; i < 2; i++) {
- if ((tmp = (i == 0) ? (-(n >> 2)) : (n & 3)) != 0) {
- nx = x + (le > ri ? 1 : -1) * tmp * dx;
- ny = y + (le > ri ? 1 : -1) * tmp * dy;
-
- if ((dirchk(ku, nx, ny, color, 0, dx, dy) == 0x06) &&
- (chkwin(getstyle(ku, nx, ny, color, limit), limit) >= 0))
- break;
- }
- }
- if (i >= 2)
- style = 0;
- ku[x][y] = BBLANK;
- }
- return style;
-}
-
-/* ¨Ò¥~=F ¿ù»~=E ¦³¤l=D ³s¤­=C ³s¤»=B Âù¥|=A ¥|¥|=9 ¤T¤T=8 */
-/* ¥|¤T=7 ¬¡¥|=6 Â_¥|=5 ¦º¥|=4 ¬¡¤T=3 Â_¤T=2 «O¯d=1 µL®Ä=0 */
-
-/* x,y: 0..BRDSIZ-1 ; color: CBLACK,CWHITE ; limit: 1,0 */
-static int
-getstyle(board_t ku, int x, int y, int color, int limit)
-{
- int i, j, dir[4], style;
-
- if ((x < 0) || (x >= BRDSIZ) || (y < 0) || (y >= BRDSIZ))
- return 0x0f;
- if (ku[x][y] != BBLANK)
- return 0x0d;
-
- // (-1,1), (0,1), (1,0), (1,1)
- for (i = 0; i < 4; i++)
- dir[i] = dirchk(ku, x, y, color, limit, i ? (i >> 1) : -1, i ? (i & 1) : 1);
-
- qsort(dir, 4, sizeof(int), (QCAST)intrevcmp);
-
- if ((style = dir[0]) >= 2) {
- for (i = 1, j = 6 + (limit ? 1 : 0); i < 4; i++) {
- if ((style > j) || (dir[i] < 2))
- break;
- if (dir[i] > 3)
- style = 9;
- else if ((style < 7) && (style > 3))
- style = 7;
- else
- style = 8;
- }
- }
- return style;
-}
-
-static char*
-gomo_move_warn(int style, char buf[])
-{
- char *xtype[] = {
- ANSI_COLOR(1;31) "¸õ¤T" ANSI_RESET,
- ANSI_COLOR(1;31) "¬¡¤T" ANSI_RESET,
- ANSI_COLOR(1;31) "¦º¥|" ANSI_RESET,
- ANSI_COLOR(1;31) "¸õ¥|" ANSI_RESET,
- ANSI_COLOR(1;31) "¬¡¥|" ANSI_RESET,
- ANSI_COLOR(1;31) "¥|¤T" ANSI_RESET,
- ANSI_COLOR(1;31) "Âù¤T" ANSI_RESET,
- ANSI_COLOR(1;31) "Âù¥|" ANSI_RESET,
- ANSI_COLOR(1;31) "Âù¥|" ANSI_RESET,
- ANSI_COLOR(1;31) "³s¤»" ANSI_RESET,
- ANSI_COLOR(1;31) "³s¤­" ANSI_RESET
- };
- if (style > 1 && style < 13)
- return strcpy(buf, xtype[style - 2]);
- else
- return NULL;
-}
-
-static void
-gomoku_usr_put(userec_t* userec, const ChessUser* user)
-{
- userec->five_win = user->win;
- userec->five_lose = user->lose;
- userec->five_tie = user->tie;
-}
-
-static char*
-gomo_getstep(const gomo_step_t* step, char buf[])
-{
- const static char* const ColName = "¢Ï¢Ð¢Ñ¢Ò¢Ó¢Ô¢Õ¢Ö¢×¢Ø¢Ù¢Ú¢Û¢Ü";
- const static char* const RawName = "151413121110¢¸¢·¢¶¢µ¢´¢³¢²¢±¢°";
- const static int ansi_length = sizeof(ANSI_COLOR(30;43)) - 1;
-
- strcpy(buf, turn_color[step->color]);
- buf[ansi_length ] = ColName[step->loc.c * 2];
- buf[ansi_length + 1] = ColName[step->loc.c * 2 + 1];
- buf[ansi_length + 2] = RawName[step->loc.r * 2];
- buf[ansi_length + 3] = RawName[step->loc.r * 2 + 1];
- strcpy(buf + ansi_length + 4, ANSI_RESET);
-
- return buf;
-}
-
-static void
-gomo_init_user(const userinfo_t* uinfo, ChessUser* user)
-{
- strlcpy(user->userid, uinfo->userid, sizeof(user->userid));
- user->win = uinfo->five_win;
- user->lose = uinfo->five_lose;
- user->tie = uinfo->five_tie;
-}
-
-static void
-gomo_init_user_userec(const userec_t* urec, ChessUser* user)
-{
- strlcpy(user->userid, urec->userid, sizeof(user->userid));
- user->win = urec->five_win;
- user->lose = urec->five_lose;
- user->tie = urec->five_tie;
-}
-
-static void
-gomo_init_board(board_t board)
-{
- memset(board, BBLANK, sizeof(board_t));
-}
-
-static void
-gomo_drawline(const ChessInfo* info, int line)
-{
- const static char* const BoardPic[] = {
- "ùÝ", "ùç", "ùç", "ùß",
- "ùò", "¢q", "¢q", "ùô",
- "ùò", "¢q", "¡Ï", "ùô",
- "ùã", "ùí", "ùí", "ùå",
- };
- const static int BoardPicIndex[] =
- { 0, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 3 };
-
- board_p board = (board_p) info->board;
-
- if (line == 0) {
- prints(ANSI_COLOR(1;46) " ¤­¤l´Ñ¹ï¾Ô " ANSI_COLOR(45)
- "%30s VS %-20s%10s" ANSI_RESET,
- info->user1.userid, info->user2.userid,
- info->mode == CHESS_MODE_WATCH ? "[Æ[´Ñ¼Ò¦¡]" : "");
- } else if (line == 1) {
- outs(" A B C D E F G H I J K L M N");
- } else if (line >= 2 && line <= 16) {
- const int board_line = line - 2;
- const char* const* const pics =
- &BoardPic[BoardPicIndex[board_line] * 4];
- int i;
-
- prints("%3d" ANSI_COLOR(30;43), 17 - line);
-
- for (i = 0; i < BRDSIZ; ++i)
- if (board[board_line][i] == -1)
- outs(pics[BoardPicIndex[i]]);
- else
- outs(bw_chess[(int) board[board_line][i]]);
-
- outs(ANSI_RESET);
- } else if (line >= 17 && line < b_lines)
- prints("%33s", "");
-
- ChessDrawExtraInfo(info, line, 8);
-}
-
-static void
-gomo_movecur(int r, int c)
-{
- move(r + 2, c * 2 + 3);
-}
-
-static int
-gomo_prepare_play(ChessInfo* info)
-{
- if (!gomo_move_warn(*(int*) info->tag, info->warnmsg))
- info->warnmsg[0] = 0;
-
- return 0;
-}
-
-static int
-gomo_select(ChessInfo* info, rc_t location, ChessGameResult* result)
-{
- board_p board = (board_p) info->board;
- gomo_step_t step;
-
- if(board[location.r][location.c] != BBLANK)
- return 0;
-
- *(int*) info->tag = getstyle(board, location.r, location.c,
- info->turn, info->turn == BLK);
- *result = chkwin(*(int*) info->tag, info->turn == BLK);
-
- board[location.r][location.c] = info->turn;
-
- step.type = CHESS_STEP_NORMAL;
- step.color = info->turn;
- step.loc = location;
- gomo_getstep(&step, info->last_movestr);
-
- ChessHistoryAppend(info, &step);
- ChessStepSend(info, &step);
- gomo_drawstep(info, &step);
-
- return 1;
-}
-
-static void
-gomo_prepare_step(ChessInfo* info, const gomo_step_t* step)
-{
- if (step->type == CHESS_STEP_NORMAL) {
- gomo_getstep(step, info->last_movestr);
- *(int*) info->tag = getstyle(info->board, step->loc.r, step->loc.c,
- step->color, step->color == BLK);
- info->cursor = step->loc;
- }
-}
-
-static ChessGameResult
-gomo_apply_step(board_t board, const gomo_step_t* step)
-{
- int style;
-
- style = getstyle(board, step->loc.r, step->loc.c,
- step->color, step->color == BLK);
- board[step->loc.r][step->loc.c] = step->color;
- return chkwin(style, step->color == BLK);
-}
-
-static void
-gomo_drawstep(ChessInfo* info, const gomo_step_t* step)
-{
- ChessDrawLine(info, BOARD_LINE_ON_SCREEN(step->loc.r));
-}
-
-static void
-gomo_gameend(ChessInfo* info, ChessGameResult result)
-{
- if (info->mode == CHESS_MODE_VERSUS) {
- ChessUser* const user1 = &info->user1;
- /* ChessUser* const user2 = &info->user2; */
-
- user1->lose--;
- if (result == CHESS_RESULT_WIN) {
- user1->win++;
- currutmp->five_win++;
- } else if (result == CHESS_RESULT_LOST) {
- user1->lose++;
- currutmp->five_lose++;
- } else {
- user1->tie++;
- currutmp->five_tie++;
- }
-
- cuser.five_win = user1->win;
- cuser.five_lose = user1->lose;
- cuser.five_tie = user1->tie;
-
- passwd_update(usernum, &cuser);
- } else if (info->mode == CHESS_MODE_REPLAY) {
- free(info->board);
- free(info->tag);
- }
-}
-
-static void
-gomo_genlog(ChessInfo* info, FILE* fp, ChessGameResult result)
-{
- char buf[ANSILINELEN] = "";
- const int nStep = info->history.used;
- int i, x, y;
-
- getyx(&y, &x);
- for (i = 1; i <= 18; i++)
- {
- move(i, 0);
- inansistr(buf, sizeof(buf)-1);
- fprintf(fp, "%s\n", buf);
- }
- move(y, x);
-
- fprintf(fp, "\n");
- fprintf(fp, "«ö z ¥i¶i¤J¥´ÃмҦ¡\n");
- fprintf(fp, "\n");
-
- fprintf(fp, "<gomokulog>\nblack:%s\nwhite:%s\n",
- info->myturn ? info->user1.userid : info->user2.userid,
- info->myturn ? info->user2.userid : info->user1.userid);
-
- for (i = 0; i < nStep; ++i) {
- const gomo_step_t* const step =
- (const gomo_step_t*) ChessHistoryRetrieve(info, i);
- if (step->type == CHESS_STEP_NORMAL)
- fprintf(fp, "[%2d]%s ==> %c%-5d", i + 1, bw_chess[step->color],
- 'A' + step->loc.c, 15 - step->loc.r);
- else
- break;
- if (i % 2)
- fputc('\n', fp);
- }
-
- if (i % 2)
- fputc('\n', fp);
- fputs("</gomokulog>\n", fp);
-}
-
-static int gomo_loadlog(FILE *fp, ChessInfo *info)
-{
- char buf[256];
-
-#define INVALID_ROW(R) ((R) < 0 || (R) >= BRDSIZ)
-#define INVALID_COL(C) ((C) < 0 || (C) >= BRDSIZ)
- while (fgets(buf, sizeof(buf), fp)) {
- if (strcmp("</gomokulog>\n", buf) == 0)
- return 1;
- else if (strncmp("black:", buf, 6) == 0 ||
- strncmp("white:", buf, 6) == 0) {
- /* /(black|white):([a-zA-Z0-9]+)/; $2 */
- userec_t rec;
- ChessUser *user = (buf[0] == 'b' ? &info->user1 : &info->user2);
-
- chomp(buf);
- if (getuser(buf + 6, &rec))
- gomo_init_user_userec(&rec, user);
- } else if (buf[0] == '[') {
- /* "[ 1]¡´ ==> H8 [ 2]¡³ ==> H9" */
- gomo_step_t step = { CHESS_STEP_NORMAL };
- int c, r;
- const char *p = buf;
- int i;
-
- for(i=0; i<2; i++) {
- p = strchr(p, '>');
-
- if (p == NULL) break;
-
- ++p; /* skip '>' */
- while (*p && isspace(*p)) ++p;
- if (!*p) break;
-
- /* i=0, p -> "H8 ..." */
- /* i=1, p -> "H9\n" */
- c = p[0] - 'A';
- r = BRDSIZ - atoi(p + 1);
-
- if (INVALID_COL(c) || INVALID_ROW(r))
- break;
-
- step.color = i==0? BLK : WHT;
- step.loc.r = r;
- step.loc.c = c;
- ChessHistoryAppend(info, &step);
- }
- }
- }
-#undef INVALID_ROW
-#undef INVALID_COL
- return 0;
-}
-
-
-void
-gomoku(int s, ChessGameMode mode)
-{
- ChessInfo* info = NewChessInfo(&gomo_actions, &gomo_constants, s, mode);
- board_t board;
- int tag;
-
- gomo_init_board(board);
- tag = 0;
-
- info->board = board;
- info->tag = &tag;
-
- info->cursor.r = 7;
- info->cursor.c = 7;
-
- if (info->mode == CHESS_MODE_VERSUS) {
- /* Assume that info->user1 is me. */
- info->user1.lose++;
- passwd_query(usernum, &cuser);
- gomoku_usr_put(&cuser, &info->user1);
- passwd_update(usernum, &cuser);
- }
-
- if (mode == CHESS_MODE_WATCH)
- setutmpmode(CHESSWATCHING);
- else
- setutmpmode(M_FIVE);
- currutmp->sig = SIG_GOMO;
-
- ChessPlay(info);
-
- DeleteChessInfo(info);
-}
-
-int
-gomoku_main(void)
-{
- return ChessStartGame('f', SIG_GOMO, "¤­¤l´Ñ");
-}
-
-int
-gomoku_personal(void)
-{
- gomoku(0, CHESS_MODE_PERSONAL);
- return 0;
-}
-
-int
-gomoku_watch(void)
-{
- return ChessWatchGame(&gomoku, M_FIVE, "¤­¤l´Ñ");
-}
-
-ChessInfo*
-gomoku_replay(FILE* fp)
-{
- ChessInfo *info;
-
- info = NewChessInfo(&gomo_actions, &gomo_constants,
- 0, CHESS_MODE_REPLAY);
-
- if(!gomo_loadlog(fp, info)) {
- DeleteChessInfo(info);
- return NULL;
- }
-
- info->board = malloc(sizeof(board_t));
- info->tag = malloc(sizeof(int));
-
- gomo_init_board(info->board);
- *(int*)(info->tag) = 0;
-
- return info;
-}
diff --git a/mbbsd/guess.c b/mbbsd/guess.c
deleted file mode 100644
index c5408b88..00000000
--- a/mbbsd/guess.c
+++ /dev/null
@@ -1,369 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-#define LOGPASS BBSHOME "/etc/winguess.log"
-
-static void
-show_table(char TABLE[], char ifcomputer)
-{
- int i;
-
- move(0, 35);
- outs(ANSI_COLOR(1;44;33) " ¡i ²q¼Æ¦r ¡j " ANSI_RESET);
- move(8, 1);
- outs(ANSI_COLOR(1;44;36) "¥Ø «e ­¿ ²v" ANSI_RESET "\n");
- outs(ANSI_COLOR(1;33) "=================" ANSI_RESET "\n");
- if (ifcomputer) {
- outs("Ĺ¹q¸£: 2 ­¿\n");
- outs("¿é¹q¸£: 0 ­¿\n");
- } else {
- for (i = 1; i <= 6; i++)
- prints("²Ä%d¦¸, %02d­¿\n", i, TABLE[i]);
- }
- outs(ANSI_COLOR(33) "=================" ANSI_RESET);
-}
-
-static int
-get_money(void)
-{
- int money, i;
- char data[20];
-
- move(1, 0);
- prints("±z¥Ø«e¦³:%d " MONEYNAME "$", cuser.money);
- do {
- getdata(2, 0, "­n½ä¦h¤Ö(5-10©Î«öqÂ÷¶}): ", data, 9, LCECHO);
- money = 0;
- if (data[0] == 'q' || data[0] == 'Q') {
- unlockutmpmode();
- return 0;
- }
- for (i = 0; data[i]; i++)
- if (data[i] < '0' || data[i] > '9') {
- money = -1;
- break;
- }
- if (money != -1) {
- money = atoi(data);
- reload_money();
- if (money > cuser.money || money <= 4 || money > 10 ||
- money < 1)
- money = -1;
- }
- } while (money == -1);
- move(1, 0);
- clrtoeol();
- reload_money();
- prints("±z¥Ø«e¦³:%d " MONEYNAME "$", cuser.money - money);
- return money;
-}
-
-static int
-check_data(const char *str)
-{
- int i, j;
-
- if (strlen(str) != 4)
- return -1;
- for (i = 0; i < 4; i++)
- if (str[i] < '0' || str[i] > '9')
- return -1;
- for (i = 0; i < 4; i++)
- for (j = i + 1; j < 4; j++)
- if (str[i] == str[j])
- return -1;
- return 1;
-}
-
-static char *
-get_data(char data[5], int count)
-{
- while (1) {
- getdata(6, 0, "¿é¤J¥|¦ì¼Æ¦r(¤£­«½Æ): ", data, 5, LCECHO);
- if (check_data(data) == 1)
- break;
- }
- return data;
-}
-
-static int
-guess_play(const char *data, const char *answer, int count)
-{
- int A_num = 0, B_num = 0;
- int i, j;
-
- for (i = 0; i < 4; i++) {
- if (data[i] == answer[i])
- A_num++;
- for (j = 0; j < 4; j++)
- if (i == j)
- continue;
- else if (data[i] == answer[j]) {
- B_num++;
- break;
- }
- }
- if (A_num == 4)
- return 1;
- move(count + 8, 55);
- prints("%s => " ANSI_COLOR(1;32) "%dA %dB" ANSI_RESET, data, A_num, B_num);
- return 0;
-}
-
-static int
-result(int correct, int number)
-{
- char a = 0, b = 0, i, j;
- char n1[5], n2[5];
-
- snprintf(n1, sizeof(n1), "%04d", correct);
- snprintf(n2, sizeof(n2), "%04d", number);
- for (i = 0; i < 4; i++)
- for (j = 0; j < 4; j++)
- if (n1[(int)i] == n2[(int)j])
- b++;
- for (i = 0; i < 4; i++)
- if (n1[(int)i] == n2[(int)i]) {
- b--;
- a++;
- }
- return 10 * a + b;
-}
-
-static int
-legal(int number)
-{
- char i, j;
- char temp[5];
-
- snprintf(temp, sizeof(temp), "%04d", number);
- for (i = 0; i < 4; i++)
- for (j = i + 1; j < 4; j++)
- if (temp[(int)i] == temp[(int)j])
- return 0;
- return 1;
-}
-
-static void
-initcomputer(char flag[])
-{
- int i;
-
- for (i = 0; i < 10000; i++)
- if (legal(i))
- flag[i] = 1;
- else
- flag[i] = 0;
-}
-
-static int
-computer(int correct, int total, char flag[], int n[])
-{
- int guess;
- static int j;
- int k, i;
- char data[5];
-
- if (total == 1) {
- do {
- guess = random() % 10000;
- } while (!legal(guess));
- } else
- guess = n[random() % j];
- k = result(correct, guess);
- if (k == 40) {
- move(total + 8, 25);
- snprintf(data, sizeof(data), "%04d", guess);
- prints("%s => ²q¤¤¤F!!", data);
- return 1;
- } else {
- move(total + 8, 25);
- snprintf(data, sizeof(data), "%04d", guess);
- prints("%s => " ANSI_COLOR(1;32) "%dA %dB" ANSI_RESET, data, k / 10, k % 10);
- }
- j = 0;
- for (i = 0; i < 10000; i++)
- if (flag[i]) {
- if (result(i, guess) != k)
- flag[i] = 0;
- else
- n[j++] = i;
- }
- return 0;
-}
-
-static void
-Diff_Random(char *answer)
-{
- register int i = 0, j, k;
-
- while (i < 4) {
- k = random() % 10 + '0';
- for (j = 0; j < i; j++)
- if (k == answer[j])
- break;
- if (j == i) {
- answer[j] = k;
- i++;
- }
- }
- answer[4] = 0;
-}
-
-#define lockreturn0(unmode, state) if(lockutmpmode(unmode, state)) return 0
-
-int
-guess_main(void)
-{
- char data[5];
- int money;
- char computerwin = 0, youwin = 0;
- int count = 0, c_count = 0;
- char ifcomputer[2];
- char answer[5];
- int *n = NULL;
- char yournum[5];
- char *flag = NULL;
- char TABLE[] = {0, 10, 8, 4, 2, 1, 0, 0, 0, 0, 0};
- FILE *file;
-
- clear();
- showtitle("²q¼Æ¦r", BBSName);
- lockreturn0(GUESSNUM, LOCK_MULTI);
-
- reload_money();
- if (cuser.money < 5) {
- clear();
- move(12, 35);
- unlockutmpmode();
- vmsg("¿ú¤£°÷°Õ ¦Ü¤Ö­n 5 " MONEYNAME "$");
- return 1;
- }
- if ((money = get_money()) == 0)
- return 1;
- vice(money, "²q¼Æ¦r");
-
- Diff_Random(answer);
- move(2, 0);
- clrtoeol();
- prints("±z¤Uª` :%d " MONEYNAME "$", money);
-
- getdata_str(4, 0, "±z­n©M¹q¸£¤ñÁɶÜ? <y/n>[y]:",
- ifcomputer, sizeof(ifcomputer), LCECHO, "y");
- if (ifcomputer[0] == 'y') {
- ifcomputer[0] = 1;
- show_table(TABLE, 1);
- } else {
- ifcomputer[0] = 0;
- show_table(TABLE, 0);
- }
- if (ifcomputer[0]) {
- do {
- getdata(5, 0, "½Ð¿é¤J±z­nÅý¹q¸£²qªº¼Æ¦r: ",
- yournum, sizeof(yournum), LCECHO);
- } while (!legal(atoi(yournum)));
- move(8, 25);
- outs("¹q¸£²q");
- flag = malloc(sizeof(char) * 10000);
- n = malloc(sizeof(int) * 1500);
- initcomputer(flag);
- }
- move(8, 55);
- outs("§A²q");
- while (((!computerwin || !youwin) && count < 10 && (ifcomputer[0])) ||
- (!ifcomputer[0] && count < 10 && !youwin)) {
- if (!computerwin && ifcomputer[0]) {
- ++c_count;
- if (computer(atoi(yournum), c_count, flag, n))
- computerwin = 1;
- }
- move(20, 55);
- prints("²Ä %d ¦¸¾÷·| ", count + 1);
- if (!youwin) {
- ++count;
- if (guess_play(get_data(data, count), answer, count))
- youwin = 1;
- }
- }
- move(17, 35);
- free(flag);
- free(n);
- if (ifcomputer[0]) {
- if (count > c_count) {
- outs("§A¿éµ¹¹q¸£¤F");
- move(18, 35);
- prints("§A½ß¤F %d ", money);
- if ((file = fopen(LOGPASS, "a"))) {
- fprintf(file, "¹q¸£²Ä%d¦¸²q¤¤, ", c_count);
- if (youwin)
- fprintf(file, "%s ²Ä%d¦¸²q¤¤, ", cuser.userid, count);
- else
- fprintf(file, "%s ¨S²q¤¤, ", cuser.userid);
- fprintf(file, "¹q¸£ÁȨ«¤F%s %d " MONEYNAME "$\n", cuser.userid, money);
- fclose(file);
- }
- } else if (count < c_count) {
- outs("¯u¼F®`, Åý§AÁȨìÅo");
- move(18, 35);
- prints("§AÁȨ«¤F %d ", money * 2);
- demoney(money * 2);
- if ((file = fopen(LOGPASS, "a"))) {
- fprintf(file, "id: %s, ²Ä%d¦¸²q¤¤, ¹q¸£²Ä%d¦¸²q¤¤, "
- "ŤF¹q¸£ %d " MONEYNAME "$\n", cuser.userid, count,
- c_count, money * 2);
- fclose(file);
- }
- } else {
- prints("¯u¼F®`, ©M¹q¸£¥´¦¨¥­¤â¤F, ®³¦^¥»¿ú%d\n", money);
- demoney(money);
- if ((file = fopen(LOGPASS, "a"))) {
- fprintf(file, "id: %s ©M¹q¸£¥´¦¨¤F¥­¤â\n", cuser.userid);
- fclose(file);
- }
- }
- unlockutmpmode();
- pressanykey();
- return 1;
- }
- if (youwin) {
- demoney(TABLE[count] * money);
- if (count < 5) {
- outs("¯u¼F®`, ¿ú³Q§AÁȨ«¤F");
- if ((file = fopen(LOGPASS, "a"))) {
- fprintf(file, "id: %s, ²Ä%d¦¸²q¤¤, ŤF %d " MONEYNAME "$\n",
- cuser.userid, count, TABLE[count] * money);
- fclose(file);
- }
- } else if (count > 5) {
- outs("­ü, ¤Ó¦h¦¸¤~²q¥X¨Ó¤F");
- if ((file = fopen(LOGPASS, "a"))) {
- fprintf(file, "id: %s, ²Ä%d¦¸¤~²q¤¤, ½ß¤F %d " MONEYNAME "$\n",
- cuser.userid, count, money);
- fclose(file);
- }
- } else {
- outs("¤­¦¸²q¥X¨Ó, ÁÙ§A¥»¿ú§a");
- move(18, 35);
- clrtoeol();
- prints("§A®³¦^¤F%d " MONEYNAME "$\n", money);
- if ((file = fopen(LOGPASS, "a"))) {
- fprintf(file, "id: %s, ²Ä%d¦¸²q¤¤, ®³¦^¤F¥»¿ú %d " MONEYNAME "$\n",
- cuser.userid, count, money);
- fclose(file);
- }
- }
- unlockutmpmode();
- pressanykey();
- return 1;
- }
- move(17, 35);
- prints("¼K¼K ¼Ð·Çµª®×¬O %s ", answer);
- move(18, 35);
- outs("¤U¦¸¦A¨Ó§a");
- if ((file = fopen(BBSHOME "/etc/loseguess.log", "a"))) {
- fprintf(file, "id: %s ½ä¤F %d " MONEYNAME "$\n", cuser.userid, money);
- fclose(file);
- }
- unlockutmpmode();
- pressanykey();
- return 1;
-}
diff --git a/mbbsd/io.c b/mbbsd/io.c
deleted file mode 100644
index ae78bbcd..00000000
--- a/mbbsd/io.c
+++ /dev/null
@@ -1,1050 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-//kcwu: 80x24 ¤@¯ë¨Ï¥ÎªÌ¦W³æ 1.9k, §t header 2.4k
-// ¤@¯ë¤å³¹±À¤å­¶¬ù 2590 bytes
-#define OBUFSIZE 3072
-#define IBUFSIZE 128
-
-/* realXbuf is Xbuf+3 because hz convert library requires buf[-2]. */
-#define CVTGAP (3)
-
-#ifdef DEBUG
-#define register
-#endif
-
-static unsigned char real_outbuf[OBUFSIZE + CVTGAP*2] = " ",
- real_inbuf [IBUFSIZE + CVTGAP*2] = " ";
-
-// use defines instead - it is discovered that sometimes the input/output buffer was overflow,
-// without knowing why.
-// static unsigned char *outbuf = real_outbuf + 3, *inbuf = real_inbuf + 3;
-#define inbuf (real_inbuf +CVTGAP)
-#define outbuf (real_outbuf+CVTGAP)
-
-static int obufsize = 0, ibufsize = 0;
-static int icurrchar = 0;
-
-#ifdef DBG_OUTRPT
-// output counter
-static unsigned long szTotalOutput = 0, szLastOutput = 0;
-extern unsigned char fakeEscape;
-unsigned char fakeEscape = 0;
-
-unsigned char fakeEscFilter(unsigned char c)
-{
- if (!fakeEscape) return c;
- if (c == ESC_CHR) return '*';
- else if (c == '\n') return 'N';
- else if (c == '\r') return 'R';
- else if (c == '\b') return 'B';
- else if (c == '\t') return 'I';
- return c;
-}
-#endif // DBG_OUTRPT
-
-/* ----------------------------------------------------- */
-/* convert routines */
-/* ----------------------------------------------------- */
-#ifdef CONVERT
-
-extern read_write_type write_type;
-extern read_write_type read_type;
-extern convert_type input_type;
-
-inline static ssize_t input_wrapper(void *buf, ssize_t count) {
- /* input_wrapper is a special case.
- * because we may do nothing,
- * a if-branch is better than a function-pointer call.
- */
- if(input_type) return (*input_type)(buf, count);
- else return count;
-}
-
-inline static int read_wrapper(int fd, void *buf, size_t count) {
- return (*read_type)(fd, buf, count);
-}
-
-inline static int write_wrapper(int fd, void *buf, size_t count) {
- return (*write_type)(fd, buf, count);
-}
-#endif
-
-/* ----------------------------------------------------- */
-/* output routines */
-/* ----------------------------------------------------- */
-void
-oflush(void)
-{
- if (obufsize) {
- STATINC(STAT_SYSWRITESOCKET);
-#ifdef CONVERT
- write_wrapper(1, outbuf, obufsize);
-#else
- write(1, outbuf, obufsize);
-#endif
- obufsize = 0;
- }
-
-#ifdef DBG_OUTRPT
- // if (0)
- {
- static char xbuf[128];
- sprintf(xbuf, ESC_STR "[s" ESC_STR "[H" " [%lu/%lu] " ESC_STR "[u",
- szLastOutput, szTotalOutput);
- write(1, xbuf, strlen(xbuf));
- szLastOutput = 0;
- }
-#endif // DBG_OUTRPT
-
- fsync(1);
-}
-
-void
-output(const char *s, int len)
-{
-#ifdef DBG_OUTRPT
- int i = 0;
- if (fakeEscape)
- for (i = 0; i < obufsize; i++)
- outbuf[i] = fakeEscFilter(outbuf[i]);
-
- szTotalOutput += len;
- szLastOutput += len;
-#endif // DBG_OUTRPT
-
- /* Invalid if len >= OBUFSIZE */
- assert(len<OBUFSIZE);
-
- if (obufsize + len > OBUFSIZE) {
- STATINC(STAT_SYSWRITESOCKET);
-#ifdef CONVERT
- write_wrapper(1, outbuf, obufsize);
-#else
- write(1, outbuf, obufsize);
-#endif
- obufsize = 0;
- }
- memcpy(outbuf + obufsize, s, len);
- obufsize += len;
-}
-
-int
-ochar(int c)
-{
-
-#ifdef DBG_OUTRPT
- c = fakeEscFilter(c);
- szTotalOutput ++;
- szLastOutput ++;
-#endif // DBG_OUTRPT
-
- if (obufsize > OBUFSIZE - 1) {
- STATINC(STAT_SYSWRITESOCKET);
- /* suppose one byte data doesn't need to be converted. */
- write(1, outbuf, obufsize);
- obufsize = 0;
- }
- outbuf[obufsize++] = c;
- return 0;
-}
-
-/* ----------------------------------------------------- */
-/* input routines */
-/* ----------------------------------------------------- */
-
-static int i_newfd = 0;
-static struct timeval i_to, *i_top = NULL;
-static int (*flushf) () = NULL;
-
-void
-add_io(int fd, int timeout)
-{
- i_newfd = fd;
- if (timeout) {
- i_to.tv_sec = timeout;
- i_to.tv_usec = 16384; /* Ptt: §ï¦¨16384 ÁקK¤£«ö®Éfor loop¦Ycpu
- * time 16384 ¬ù¨C¬í64¦¸ */
- i_top = &i_to;
- } else
- i_top = NULL;
-}
-
-int
-num_in_buf(void)
-{
- if (ibufsize <= icurrchar)
- return 0;
- return ibufsize - icurrchar;
-}
-
-int
-input_isfull(void)
-{
- return ibufsize >= IBUFSIZE;
-}
-
-/*
- * dogetch() is not reentrant-safe. SIGUSR[12] might happen at any time, and
- * dogetch() might be called again, and then ibufsize/icurrchar/inbuf might
- * be inconsistent. We try to not segfault here...
- */
-
-static int
-dogetch(void)
-{
- ssize_t len;
- static time4_t lastact;
- if (ibufsize <= icurrchar) {
-
- if (flushf)
- (*flushf) ();
-
- refresh();
-
- if (i_newfd) {
-
- struct timeval timeout;
- fd_set readfds;
-
- if (i_top)
- timeout = *i_top; /* copy it because select() might
- * change it */
-
- FD_ZERO(&readfds);
- FD_SET(0, &readfds);
- FD_SET(i_newfd, &readfds);
-
- /* jochang: modify first argument of select from FD_SETSIZE */
- /* since we are only waiting input from fd 0 and i_newfd(>0) */
-
- STATINC(STAT_SYSSELECT);
- while ((len = select(i_newfd + 1, &readfds, NULL, NULL,
- i_top ? &timeout : NULL)) < 0) {
- if (errno != EINTR)
- abort_bbs(0);
- /* raise(SIGHUP); */
- }
-
- if (len == 0){
- syncnow();
- return I_TIMEOUT;
- }
-
- if (i_newfd && FD_ISSET(i_newfd, &readfds)){
- syncnow();
- return I_OTHERDATA;
- }
- }
-
-#ifdef NOKILLWATERBALL
- if( currutmp && currutmp->msgcount && !reentrant_write_request )
- write_request(1);
-#endif
-
- STATINC(STAT_SYSREADSOCKET);
-
- do {
- len = tty_read(inbuf, IBUFSIZE);
- /* tty_read will handle abort_bbs.
- * len <= 0: read more */
-#ifdef CONVERT
- if(len > 0)
- len = input_wrapper(inbuf, len);
-#endif
-#ifdef DBG_OUTRPT
- // if (0)
- {
- static char xbuf[128];
- sprintf(xbuf, ESC_STR "[s" ESC_STR "[2;1H [%ld] "
- ESC_STR "[u", len);
- write(1, xbuf, strlen(xbuf));
- fsync(1);
- }
-#endif // DBG_OUTRPT
-
- } while (len <= 0);
-
- ibufsize = len;
- icurrchar = 0;
- }
-
- if (currutmp) {
- syncnow();
- /* 3 ¬í¤º¶W¹L¨â byte ¤~ºâ active, anti-antiidle.
- * ¤£¹L¤è¦VÁäµ¥²Õ¦XÁ䤣¤î 1 byte */
- if (now - lastact < 3)
- currutmp->lastact = now;
- lastact = now;
- }
-
- // CR LF are treated as one.
- if (inbuf[icurrchar] == Ctrl('M'))
- {
- if (++icurrchar < ibufsize &&
- inbuf[icurrchar] == Ctrl('J'))
- icurrchar ++;
- return Ctrl('M');
- }
- return (unsigned char)inbuf[icurrchar++];
-}
-
-#ifdef DEBUG
-/*
- * These are for terminal keys debug
- */
-void
-_debug_print_ibuffer()
-{
- static int y = 0;
- int i = 0;
-
- move(y % b_lines, 0);
- for (i = 0; i < t_columns; i++)
- outc(' ');
- move(y % b_lines, 0);
- prints("%d. Current Buffer: %d/%d, ", y+1, icurrchar, ibufsize);
- outs(ANSI_COLOR(1) "[" ANSI_RESET);
- for (i = 0; i < ibufsize; i++)
- {
- int c = (unsigned char)inbuf[i];
- if(c < ' ')
- {
- prints(ANSI_COLOR(1;33) "0x%02x" ANSI_RESET, c);
- } else {
- outc(c);
- }
- }
- outs(ANSI_COLOR(1) "]" ANSI_RESET);
- y++;
- move(y % b_lines, 0);
- for (i = 0; i < t_columns; i++)
- outc(' ');
-}
-
-int
-_debug_check_keyinput()
-{
- int dbcsaware = 0;
- int flExit = 0;
-
- clear();
- while(!flExit)
- {
- int i = 0;
- move(b_lines, 0);
- for(i=0; i<t_columns; i++)
- outc(' ');
- move(b_lines, 0);
- if(dbcsaware)
- {
- outs( ANSI_COLOR(7) "´å¼Ð¦b¦¹" ANSI_RESET
- " ´ú¸Õ¤¤¤å¼Ò¦¡·|¤£·|¶Ã°eÁä¡C 'q' Â÷¶}, 'd' ¦^­^¤å¼Ò¦¡ ");
- move(b_lines, 4);
- } else {
- outs("Waiting for key input. 'q' to exit, 'd' to try dbcs-aware");
- }
- refresh();
- wait_input(-1, 0);
- switch(dogetch())
- {
- case 'd':
- dbcsaware = !dbcsaware;
- break;
- case 'q':
- flExit = 1;
- break;
- }
- _debug_print_ibuffer();
- while(num_in_buf() > 0)
- dogetch();
- }
- return 0;
-}
-
-#endif
-
-static int water_which_flag = 0;
-
-int
-igetch(void)
-{
- register int ch, mode = 0, last = 0;
- while (1) {
- ch = dogetch();
-
- /* for escape codes, check
- * http://support.dell.com/support/edocs/systems/pe2650/en/ug/5g387ad0.htm
- */
- if (mode == 0 && ch == KEY_ESC)
- mode = 1;
- else if (mode == 1) {
-
- /* Escape sequence */
-
- if (ch == '[' || ch == 'O')
- { mode = 2; last = ch; }
-#if 0
- /* some user complained about this since they wanna
- * do Esc-N paste in vedit.
- * Before anyone to explain what this is for,
- * this will be commented.
- */
- else if (ch == '1' || ch == '4') /* what is this!? */
- { mode = 3; last = ch; }
-#endif
- else {
- KEY_ESC_arg = ch;
- return KEY_ESC;
- }
-
- }
- else if (mode == 2)
- {
- /* ^[ or ^O,
- * ordered by frequency */
-
- if(ch >= 'A' && ch <= 'D') /* Cursor key */
- {
- return KEY_UP + (ch - 'A');
- }
- else if (ch >= '1' && ch <= '6') /* Ins Del Home End PgUp PgDn */
- {
- mode = 3; last = ch;
- continue;
- }
- else if(ch == 'O')
- {
- mode = 4;
- continue;
- }
- else if(ch == 'Z')
- {
- return KEY_STAB;
- }
- else if (ch == '0')
- {
- if (dogetch() == 'Z')
- return KEY_STAB;
- else
- return KEY_UNKNOWN;
- }
- else if (last == 'O') {
- /* ^[O ... */
- if (ch >= 'A' && ch <= 'D')
- return KEY_UP + (ch - 'A');
- if (ch >= 'P' && ch <= 'S') // vt100 k1-4
- return KEY_F1 + (ch - 'P');
- if (ch >= 'T' && ch <= '[') // putty vt100+ F5-F12
- return KEY_F5 + (ch - 'T');
- if (ch >= 't' && ch <= 'z') // vt100 F5-F11
- return KEY_F5 + (ch - 't');
- if (ch >= 'p' && ch <= 's') // Old (num or fn)kbd 4 keys
- return KEY_F1 + (ch - 'p');
- else if (ch == 'a') // DELL spec
- return KEY_F12;
- }
- else return KEY_UNKNOWN;
- }
- else if (mode == 3)
- {
- /* ^[[1-6] */
-
- /* ~: Ins Del Home End PgUp PgDn */
- if(ch == '~')
- {
- // vt220 style
- if (last >= '1' && last <= '6')
- return KEY_HOME + (last - '1');
- // else, unknown.
- return KEY_UNKNOWN;
- }
- else if (last == '1')
- {
- if (ch >= '1' && ch <= '6')
- {
- // use num_in_buf() to prevent waiting keys
- if (num_in_buf() && dogetch() == '~') /* must be '~' */
- return KEY_F1 + ch - '1';
- }
- else if (ch >= '7' && ch <= '9')
- {
- // use num_in_buf() to prevent waiting keys
- if (num_in_buf() && dogetch() == '~') /* must be '~' */
- return KEY_F6 + ch - '7';
- }
- return KEY_UNKNOWN;
- }
- else if (last == '2')
- {
- if (ch >= '0' && ch <= '4')
- {
- // use inbuf() to prevent waiting keys
- if (num_in_buf() && dogetch() == '~') /* hope you are '~' */
- return KEY_F9 + ch - '0';
- }
- return KEY_UNKNOWN;
- }
- // if fall here, then escape sequence is broken.
- return KEY_UNKNOWN;
- }
- else // here is switch for default keys
- switch (ch) { // XXX: indent error
-#ifdef DEBUG
- case Ctrl('Q'):{
- struct rusage ru;
- getrusage(RUSAGE_SELF, &ru);
- vmsgf("sbrk: %d KB, idrss: %d KB, isrss: %d KB",
- ((int)sbrk(0) - 0x8048000) / 1024,
- (int)ru.ru_idrss, (int)ru.ru_isrss);
- }
- continue;
-#endif
- case Ctrl('L'):
- redrawwin();
- refresh();
- continue;
-
- case Ctrl('U'):
- if (currutmp != NULL && currutmp->mode != EDITING
- && currutmp->mode != LUSERS && currutmp->mode) {
-
- screen_backup_t old_screen;
- int oldroll = roll;
- int my_newfd;
-
- scr_dump(&old_screen);
- my_newfd = i_newfd;
- i_newfd = 0;
-
- t_users();
-
- i_newfd = my_newfd;
- roll = oldroll;
- scr_restore(&old_screen);
- continue;
- }
- return ch;
- case KEY_TAB:
- if (WATERMODE(WATER_ORIG) || WATERMODE(WATER_NEW))
- if (currutmp != NULL && watermode > 0) {
- check_water_init();
- watermode = (watermode + water_which->count)
- % water_which->count + 1;
- t_display_new();
- continue;
- }
- return ch;
-
- case Ctrl('R'):
- if (currutmp == NULL)
- return (ch);
-
- if (currutmp->msgs[0].pid &&
- WATERMODE(WATER_OFO) && wmofo == NOTREPLYING) {
- int my_newfd;
- screen_backup_t old_screen;
-
- scr_dump(&old_screen);
-
- my_newfd = i_newfd;
- i_newfd = 0;
- my_write2();
- scr_restore(&old_screen);
- i_newfd = my_newfd;
- continue;
- } else if (!WATERMODE(WATER_OFO)) {
- check_water_init();
- if (watermode > 0) {
- watermode = (watermode + water_which->count)
- % water_which->count + 1;
- t_display_new();
- continue;
- } else if (currutmp->mode == 0 &&
- (currutmp->chatid[0] == 2 || currutmp->chatid[0] == 3) &&
- water_which->count != 0 && watermode == 0) {
- /* ²Ä¤G¦¸«ö Ctrl-R */
- watermode = 1;
- t_display_new();
- continue;
- } else if (watermode == -1 && currutmp->msgs[0].pid) {
- /* ²Ä¤@¦¸«ö Ctrl-R (¥²¶·¥ý³Q¥á¹L¤ô²y) */
- screen_backup_t old_screen;
- int my_newfd;
- scr_dump(&old_screen);
-
- /* ¦pªG¥¿¦btalkªº¸Ü¥ý¤£³B²z¹ï¤è°e¹L¨Óªº«Ê¥] (¤£¥hselect) */
- my_newfd = i_newfd;
- i_newfd = 0;
- show_call_in(0, 0);
- watermode = 0;
-#ifndef PLAY_ANGEL
- my_write(currutmp->msgs[0].pid, "¤ô²y¥á¹L¥h¡G ",
- currutmp->msgs[0].userid, WATERBALL_GENERAL, NULL);
-#else
- switch (currutmp->msgs[0].msgmode) {
- case MSGMODE_TALK:
- case MSGMODE_WRITE:
- my_write(currutmp->msgs[0].pid, "¤ô²y¥á¹L¥h¡G ",
- currutmp->msgs[0].userid, WATERBALL_GENERAL, NULL);
- break;
- case MSGMODE_FROMANGEL:
- my_write(currutmp->msgs[0].pid, "¦A°Ý¥L¤@¦¸¡G ",
- currutmp->msgs[0].userid, WATERBALL_ANGEL, NULL);
- break;
- case MSGMODE_TOANGEL:
- my_write(currutmp->msgs[0].pid, "¦^µª¤p¥D¤H¡G ",
- currutmp->msgs[0].userid, WATERBALL_ANSWER, NULL);
- break;
- }
-#endif
- i_newfd = my_newfd;
-
- /* ÁÙ­ì¿Ã¹õ */
- scr_restore(&old_screen);
- continue;
- }
- }
- return ch;
-
- case Ctrl('T'):
- if (WATERMODE(WATER_ORIG) || WATERMODE(WATER_NEW)) {
- if (watermode > 0) {
- check_water_init();
- if (watermode > 1)
- watermode--;
- else
- watermode = water_which->count;
- t_display_new();
- continue;
- }
- }
- return ch;
-
- case Ctrl('F'):
- if (WATERMODE(WATER_NEW)) {
- if (watermode > 0) {
- check_water_init();
- if (water_which_flag == (int)water_usies)
- water_which_flag = 0;
- else
- water_which_flag =
- (water_which_flag + 1) % (int)(water_usies + 1);
- if (water_which_flag == 0)
- water_which = &water[0];
- else
- water_which = swater[water_which_flag - 1];
- watermode = 1;
- t_display_new();
- continue;
- }
- }
- return ch;
-
- case Ctrl('G'):
- if (WATERMODE(WATER_NEW)) {
- if (watermode > 0) {
- check_water_init();
- water_which_flag = (water_which_flag + water_usies) % (water_usies + 1);
- if (water_which_flag == 0)
- water_which = &water[0];
- else
- water_which = swater[water_which_flag - 1];
- watermode = 1;
- t_display_new();
- continue;
- }
- }
- return ch;
-
- // try to do this in getch() level.
-#if 0
- case Ctrl('J'): /* Ptt §â \n ®³±¼ */
-#ifdef PLAY_ANGEL
- /* Seams some telnet client still send CR LF when changing lines.
- CallAngel();
- */
-#endif
- continue;
-#endif
-
- default:
- return ch;
- }
- }
- // should not reach here. just to make compiler happy.
- return 0;
-}
-
-/*
- * wait user input anything for f seconds.
- * if f < 0, then wait forever.
- * Return 1 if anything available.
- */
-int
-wait_input(float f, int bIgnoreBuf)
-{
- int sel = 0;
- fd_set readfds;
- struct timeval tv, *ptv = &tv;
-
- if(!bIgnoreBuf && num_in_buf() > 0)
- return 1;
-
- FD_ZERO(&readfds);
- FD_SET(0, &readfds);
-
- if(f > 0)
- {
- tv.tv_sec = (long) f;
- tv.tv_usec = (f - (long)f) * 1000000L;
- } else
- ptv = NULL;
-
-#ifdef STATINC
- STATINC(STAT_SYSSELECT);
-#endif
-
- do {
- if(!bIgnoreBuf && num_in_buf() > 0)
- return 1;
- sel = select(1, &readfds, NULL, NULL, ptv);
- } while (sel < 0 && errno == EINTR);
- /* EINTR, interrupted. I don't care! */
-
- if(sel == 0)
- return 0;
-
- return 1;
-}
-
-void
-drop_input(void)
-{
- icurrchar = ibufsize = 0;
-}
-
-int
-peek_input(float f, int c)
-{
- int i = 0;
- assert (c > 0 && c < ' '); // only ^x keys are safe to be detected.
- // other keys may fall into escape sequence.
-
- if (wait_input(f, 1) && (IBUFSIZE > ibufsize))
- {
- int len = tty_read(inbuf + ibufsize, IBUFSIZE - ibufsize);
-#ifdef CONVERT
- if(len > 0)
- len = input_wrapper(inbuf+ibufsize, len);
-#endif
- if (len > 0)
- ibufsize += len;
- }
- for (i = icurrchar; i < ibufsize; i++)
- {
- if (inbuf[i] == c)
- return 1;
- }
- return 0;
-}
-
-
-#ifdef DBCSAWARE
-
-int getDBCSstatus(unsigned char *s, int pos)
-{
- int sts = DBCS_ASCII;
- while(pos >= 0)
- {
- if(sts == DBCS_LEADING)
- sts = DBCS_TRAILING;
- else if (*s >= 0x80)
- {
- sts = DBCS_LEADING;
- } else {
- sts = DBCS_ASCII;
- }
- s++, pos--;
- }
- return sts;
-}
-
-#else
-
-#define dbcs_off (1)
-
-#endif
-
-#define MAXLASTCMD 12
-int
-oldgetdata(int line, int col, const char *prompt, char *buf, int len, int echo)
-{
- register int ch, i;
- int clen, lprompt = 0;
- int cx = col, cy = line;
- static char lastcmd[MAXLASTCMD][80];
- unsigned char occupy_msg = 0;
-
-#ifdef DBCSAWARE
- unsigned int dbcsincomplete = 0;
-#endif
-
- strip_ansi(buf, buf, STRIP_ALL);
- if (prompt)
- {
- lprompt = strlen_noansi(prompt);
- cx += lprompt;
- }
-
- if(line == b_lines-msg_occupied)
- occupy_msg=1, msg_occupied ++;
-
- // workaround poor terminal
- move_ansi(line, col);
- getyx(&line, &col);
- clrtoeol();
-
- // (line, col) are real starting address
-
- if (!echo) {
- if (prompt) outs(prompt);
- len--;
- clen = 0;
- while ((ch = igetch()) != '\r') {
- if (ch == Ctrl('C'))
- {
- // abort
- clen = 0;
- if (len > 1)
- buf[1] = ch; // workaround for BBS-Lua
- break;
- }
- if (ch == '\177' || ch == Ctrl('H')) {
- if (!clen) {
- bell();
- continue;
- }
- clen--;
- continue;
- }
- if (ch>=0x100 || !isprint(ch)) {
- bell();
- continue;
- }
- if (clen >= len) {
- bell();
- continue;
- }
- buf[clen++] = ch;
- }
- buf[clen] = '\0';
- outc('\n');
- oflush();
- } else {
- int cmdpos = 0;
- int currchar = 0;
-
- len--;
- buf[len] = '\0';
- clen = currchar = strlen(buf);
-
- while (1) {
- // refresh from prompt
- move(line, col); outc(' '); move(line, col); clrtoeol();
- if (prompt) outs(prompt);
-
- outs(ANSI_COLOR(7));
- outs(buf);
- for(i=clen; i<=len; i++)
- outc(' ');
- outs(ANSI_RESET);
- move(cy, cx + currchar);
-
- if ((ch = igetch()) == '\r')
- break;
-
- if (ch == Ctrl('C'))
- {
- // abort
- clen = currchar = 0;
- if (len > 1)
- buf[1] = ch; // workaround for BBS-Lua
- break;
- }
-
- switch (ch) {
- case Ctrl('A'):
- case KEY_HOME:
- currchar = 0;
- break;
-
- case Ctrl('E'):
- case KEY_END:
- currchar = clen;
- break;
-
- case KEY_UNKNOWN:
- break;
-
- case KEY_LEFT:
- if (currchar <= 0)
- break;
- --currchar;
-#ifdef DBCSAWARE
- if(currchar > 0 && ISDBCSAWARE() &&
- getDBCSstatus((unsigned char*)buf, currchar) == DBCS_TRAILING)
- currchar --;
-#endif
- break;
-
- case KEY_RIGHT:
- if (!buf[currchar])
- break;
- ++currchar;
-#ifdef DBCSAWARE
- if(buf[currchar] && ISDBCSAWARE() &&
- getDBCSstatus((unsigned char*)buf, currchar) == DBCS_TRAILING)
- currchar++;
-#endif
- break;
-
- case Ctrl('Y'):
- currchar = 0;
- case Ctrl('K'):
- /* we shoud be able to avoid DBCS issues in ^K mode */
- buf[currchar] = '\0';
- clen = currchar;
- break;
-
- case KEY_DOWN: case Ctrl('N'):
- case KEY_UP: case Ctrl('P'):
- strlcpy(lastcmd[cmdpos], buf, sizeof(lastcmd[0]));
- if (ch == KEY_UP || ch == Ctrl('P'))
- cmdpos++;
- else
- cmdpos += MAXLASTCMD - 1;
- cmdpos %= MAXLASTCMD;
- strlcpy(buf, lastcmd[cmdpos], len+1);
- clen = currchar = strlen(buf);
- break;
-
- case '\177':
- case Ctrl('H'):
- if (!currchar)
- break;
-#ifdef DBCSAWARE
- if (ISDBCSAWARE() && getDBCSstatus((unsigned char*)buf,
- currchar-1) == DBCS_TRAILING)
- {
- memmove(buf+currchar-1, buf+currchar, clen-currchar+1);
- currchar--, clen--;
- }
-#endif
- memmove(buf+currchar-1, buf+currchar, clen-currchar+1);
- currchar--, clen--;
- break;
-
- case Ctrl('D'):
- case KEY_DEL:
- if (!buf[currchar])
- break;
-#ifdef DBCSAWARE
- if (ISDBCSAWARE() && buf[currchar+1] && getDBCSstatus(
- (unsigned char*)buf, currchar+1) == DBCS_TRAILING)
- {
- memmove(buf+currchar, buf+currchar+1, clen-currchar);
- clen --;
- }
-#endif
- memmove(buf+currchar, buf+currchar+1, clen-currchar);
- clen --;
- break;
-
- default:
- if (echo == NUMECHO && !isdigit(ch))
- {
- bell();
- break;
- }
- if (isprint2(ch) && clen < len && cx + clen < scr_cols) {
-#ifdef DBCSAWARE
- if(ISDBCSAWARE())
- {
- /* to prevent single byte input */
- if(dbcsincomplete)
- {
- dbcsincomplete = 0;
- }
- else if (ch >= 0x80)
- {
- dbcsincomplete = 1;
- if(clen + 2 > len)
- {
- /* we can't print this. ignore and eat key. */
- igetch();
- dbcsincomplete = 0;
- break;
- }
- } else {
- /* nothing, normal key. */
- }
- }
-#endif
- for (i = clen + 1; i > currchar; i--)
- buf[i] = buf[i - 1];
- buf[currchar] = ch;
- currchar++;
- clen++;
- }
- break;
- } /* end case */
- assert(0<=clen);
- } /* end while */
- buf[clen] = '\0';
-
- if (clen > 1) {
- strlcpy(lastcmd[0], buf, sizeof(lastcmd[0]));
- memmove(lastcmd+1, lastcmd, (MAXLASTCMD-1)*sizeof(lastcmd[0]));
- }
- /* why return here? because some code then outs.*/
- // outc('\n');
- move(line+1, 0);
- refresh();
-
- assert(0<=currchar && currchar<=clen);
- assert(0<=clen && clen<=len);
- }
-
- if ((echo == LCECHO) && isupper((int)buf[0]))
- buf[0] = tolower(buf[0]);
-
- if(occupy_msg) msg_occupied --;
- return clen;
-}
-
-/* Ptt */
-int
-getdata_buf(int line, int col, const char *prompt, char *buf, int len, int echo)
-{
- return oldgetdata(line, col, prompt, buf, len, echo);
-}
-
-
-int
-getdata_str(int line, int col, const char *prompt, char *buf, int len, int echo, const char *defaultstr)
-{
- strlcpy(buf, defaultstr, len);
-
- return oldgetdata(line, col, prompt, buf, len, echo);
-}
-
-int
-getdata(int line, int col, const char *prompt, char *buf, int len, int echo)
-{
- buf[0] = 0;
- return oldgetdata(line, col, prompt, buf, len, echo);
-}
-
-/* vim:sw=4
- */
diff --git a/mbbsd/kaede.c b/mbbsd/kaede.c
deleted file mode 100644
index b3d9c0ae..00000000
--- a/mbbsd/kaede.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-// TODO move stuff to libbbs(or util)/string.c, ...
-// this file can be removed (or not?)
-
-char *
-Ptt_prints(char *str, size_t size, int mode)
-{
- char *strbuf = alloca(size);
- int r, w;
- for( r = w = 0 ; str[r] != 0 && w < (size - 1) ; ++r )
- if( str[r] != ESC_CHR )
- strbuf[w++] = str[r];
- else{
- if( str[++r] != '*' ){
- if(w+2>=size-1) break;
- strbuf[w++] = ESC_CHR;
- strbuf[w++] = str[r];
- }
- else{
- /* Note, w will increased by copied length after */
- switch( str[++r] ){
-
- // secure content
-
- case 't': // current time
- strlcpy(strbuf+w, Cdate(&now), size-w);
- w += strlen(strbuf+w);
- break;
- case 'u': // current online users
- w += snprintf(&strbuf[w], size - w,
- "%d", SHM->UTMPnumber);
- break;
-
- // insecure content
-
- case 's': // current user id
- strlcpy(strbuf+w, cuser.userid, size-w);
- w += strlen(strbuf+w);
- break;
- case 'n': // current user nickname
- strlcpy(strbuf+w, cuser.nickname, size-w);
- w += strlen(strbuf+w);
- break;
- case 'l': // current user logins
- w += snprintf(&strbuf[w], size - w,
- "%d", cuser.numlogins);
- break;
- case 'p': // current user posts
- w += snprintf(&strbuf[w], size - w,
- "%d", cuser.numposts);
- break;
-
- /* It's saver not to send these undefined escape string.
- default:
- strbuf[w++] = ESC_CHR;
- strbuf[w++] = '*';
- strbuf[w++] = str[r];
- */
- }
- }
- }
- strbuf[w] = 0;
- strip_ansi(str, strbuf, mode);
- return str;
-}
-
-// utility from screen.c
-void
-outs_n(const char *str, int n)
-{
- while (*str && n--) {
- outc(*str++);
- }
-}
-
-// XXX left-right (for large term)
-// TODO someday please add ANSI detection version
-void
-outslr(const char *left, int leftlen, const char *right, int rightlen)
-{
- if (left == NULL)
- left = "";
- if (right == NULL)
- right = "";
- if(*left && leftlen < 0)
- leftlen = strlen(left);
- if(*right && rightlen < 0)
- rightlen = strlen(right);
- // now calculate padding
- rightlen = t_columns - leftlen - rightlen;
- outs(left);
-
- // ignore right msg if we need to.
- if(rightlen >= 0)
- {
- while(--rightlen > 0)
- outc(' ');
- outs(right);
- } else {
- rightlen = t_columns - leftlen;
- while(--rightlen > 0)
- outc(' ');
- }
-}
-
-
-/* Jaky */
-void
-out_lines(const char *str, int line)
-{
- int y, x;
- getyx(&y, &x);
- while (*str && line) {
- if (*str == '\n')
- {
- move(++y, 0);
- line--;
- } else
- {
- outc(*str);
- }
- str++;
- }
-}
-
-void
-outmsg(const char *msg)
-{
- move(b_lines - msg_occupied, 0);
- clrtoeol();
- outs(msg);
-}
-
-void
-outmsglr(const char *msg, int llen, const char *rmsg, int rlen)
-{
- move(b_lines - msg_occupied, 0);
- clrtoeol();
- outslr(msg, llen, rmsg, rlen);
- outs(ANSI_RESET ANSI_CLRTOEND);
-}
-
-void
-prints(const char *fmt,...)
-{
- va_list args;
- char buff[1024];
-
- va_start(args, fmt);
- vsnprintf(buff, sizeof(buff), fmt, args);
- va_end(args);
- outs(buff);
-}
-
-void
-mouts(int y, int x, const char *str)
-{
- move(y, x);
- clrtoeol();
- outs(str);
-}
-
-// vim:ts=4
diff --git a/mbbsd/lovepaper.c b/mbbsd/lovepaper.c
deleted file mode 100644
index 50c643bb..00000000
--- a/mbbsd/lovepaper.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-#define DATA "etc/lovepaper.dat"
-
-int
-x_love(void)
-{
- char buf1[200], title[TTLEN + 1];
- char receiver[61], path[STRLEN] = "home/";
- int x, y = 0, tline = 0, poem = 0;
- FILE *fp, *fpo;
- struct tm *gtime;
- fileheader_t mhdr;
-
- setutmpmode(LOVE);
- gtime = localtime4(&now);
- snprintf(buf1, sizeof(buf1), "%c/%s/love%d%d",
- cuser.userid[0], cuser.userid, gtime->tm_sec, gtime->tm_min);
- strcat(path, buf1);
- move(1, 0);
- clrtobot();
-
- outs("\nÅwªï¨Ï¥Î±¡®Ñ²£¥Í¾¹ v0.00 ªO \n");
- outs("¦³¦óÃø¥H±Ò¾¦ªº¸Ü,¥æ¥Ñ¨t²ÎÀ°§A»¡§a.\nª¨ª¨»¡ : Àݱ¡¤£¥Çªk.\n");
-
- if (!getdata(7, 0, "¦¬«H¤H¡G", receiver, sizeof(receiver), DOECHO))
- return 0;
- if (receiver[0] && !(searchuser(receiver, receiver) &&
- getdata(8, 0, "¥D ÃD¡G", title,
- sizeof(title), DOECHO))) {
- move(10, 0);
- vmsg("¦¬«H¤H©Î¥DÃD¤£¥¿½T,±¡®ÑµLªk¶Ç»¼");
- return 0;
- }
- fpo = fopen(path, "w");
- assert(fpo);
- fprintf(fpo, "\n");
- if ((fp = fopen(DATA, "r"))) {
- while (fgets(buf1, 100, fp)) {
- switch (buf1[0]) {
- case '#':
- break;
- case '@':
- if (!strncmp(buf1, "@begin", 6) || !strncmp(buf1, "@end", 4))
- tline = 3;
- else if (!strncmp(buf1, "@poem", 5)) {
- poem = 1;
- tline = 1;
- fprintf(fpo, "\n\n");
- } else
- tline = 2;
- break;
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- sscanf(buf1, "%d", &x);
- y = (random() % (x - 1)) * tline;
- break;
- default:
- if (!poem) {
- if (y > 0)
- y = y - 1;
- else {
- if (tline > 0) {
- fputs(buf1, fpo);
- tline--;
- }
- }
- } else {
- if (buf1[0] == '$')
- y--;
- else if (y == 0)
- fputs(buf1, fpo);
- }
- }
-
- }
-
- fclose(fp);
- fclose(fpo);
- strlcpy(save_title, title, sizeof(save_title));
- curredit |= EDIT_MAIL;
- if (vedit(path, YEA, NULL) == -1) {
- curredit &= ~EDIT_MAIL;
- unlink(path);
- clear();
- outs("\n\n ©ñ±ó±H±¡®Ñ\n");
- pressanykey();
- return -2;
- }
- curredit &= ~EDIT_MAIL;
- sethomepath(buf1, receiver);
- stampfile(buf1, &mhdr);
- Rename(path, buf1);
- strlcpy(mhdr.title, save_title, sizeof(mhdr.title));
- strlcpy(mhdr.owner, cuser.userid, sizeof(mhdr.owner));
- sethomedir(path, receiver);
- if (append_record(path, &mhdr, sizeof(mhdr)) == -1)
- return -1;
- sendalert(receiver, ALERT_NEW_MAIL);
- hold_mail(buf1, receiver);
- return 1;
- } else {
- vmsg("¥»¯¸¥Ø«eµL±¡®Ñ¸ê®Æ®w¡A½Ð¦V¯¸ªø¤ÏÀ³¡C");
- }
- fclose(fpo);
- return 0;
-}
diff --git a/mbbsd/mail.c b/mbbsd/mail.c
deleted file mode 100644
index 38e19619..00000000
--- a/mbbsd/mail.c
+++ /dev/null
@@ -1,2092 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-static int mailkeep = 0, mailsum = 0;
-static int mailsumlimit = 0, mailmaxkeep = 0;
-static char currmaildir[32];
-static char msg_cc[] = ANSI_COLOR(32) "[¸s²Õ¦W³æ]" ANSI_RESET "\n";
-static char listfile[] = "list.0";
-
-// check only 20 mails (one page) is enough.
-// #define NEWMAIL_CHECK_RANGE (1)
-// checking only 1 mail works more like brc style.
-#define NEWMAIL_CHECK_RANGE (5)
-
-enum SHOWMAIL_MODES {
- SHOWMAIL_NORM = 0,
- SHOWMAIL_SUM,
- SHOWMAIL_RANGE,
-};
-static int showmail_mode = SHOWMAIL_NORM;
-
-int
-setforward(void)
-{
- char buf[80], ip[50] = "", yn[4];
- FILE *fp;
- int flIdiotSent2Self = 0;
- int oidlen = strlen(cuser.userid);
-
- sethomepath(buf, cuser.userid);
- strcat(buf, "/.forward");
- if ((fp = fopen(buf, "r"))) {
- fscanf(fp, "%" toSTR(sizeof(ip)) "s", ip);
- fclose(fp);
- }
- getdata_buf(b_lines - 1, 0, "½Ð¿é¤J¦Û°ÊÂà±HªºEmail: ",
- ip, sizeof(ip), DOECHO);
-
- /* anti idiots */
- if (strncasecmp(ip, cuser.userid, oidlen) == 0)
- {
- int addrlen = strlen(ip);
- if( addrlen == oidlen ||
- (addrlen > oidlen &&
- strcasecmp(ip + oidlen, str_mail_address) == 0))
- flIdiotSent2Self = 1;
- }
-
- if (ip[0] && ip[0] != ' ' && !flIdiotSent2Self) {
- getdata(b_lines, 0, "½T©w¶}±Ò¦Û°ÊÂà«H¥\\¯à?(Y/n)", yn, sizeof(yn),
- LCECHO);
- if (yn[0] != 'n' && (fp = fopen(buf, "w"))) {
- fputs(ip, fp);
- fclose(fp);
- vmsg("³]©w§¹¦¨!");
- return 0;
- }
- }
- unlink(buf);
- if(flIdiotSent2Self)
- vmsg("¦Û°ÊÂà±H¬O¤£·|³]©wµ¹¦Û¤vªº¡A·Q¨ú®ø¥ÎªÅ¥Õ´N¥i¥H¤F¡C");
- else
- vmsg("¨ú®ø¦Û°ÊÂà«H!");
- return 0;
-}
-
-int
-toggle_showmail_mode(void)
-{
- showmail_mode ++;
- showmail_mode %= SHOWMAIL_RANGE;
- return FULLUPDATE;
-}
-
-int
-built_mail_index(void)
-{
- char genbuf[128];
-
- move(b_lines - 4, 0);
- outs("¥»¥\\¯à¥u¦b«H½cÀÉ·´·l®É¨Ï¥Î¡A" ANSI_COLOR(1;33) "µLªk" ANSI_RESET "±Ï¦^³Q§R°£ªº«H¥ó¡C\n"
- "°£«D±z²M·¡³o­Ó¥\\¯àªº§@¥Î¡A§_«h" ANSI_COLOR(1;33) "½Ð¤£­n¨Ï¥Î" ANSI_RESET "¡C\n"
- "ĵ§i¡G¥ô·Nªº¨Ï¥Î±N¾É­P" ANSI_COLOR(1;33) "¤£¥i¹w´Áªºµ²ªG" ANSI_RESET "¡I\n");
- getdata(b_lines - 1, 0,
- "½T©w­««Ø«H½c?(y/N)", genbuf, 3,
- LCECHO);
- if (genbuf[0] != 'y')
- return 0;
-
- snprintf(genbuf, sizeof(genbuf),
- BBSHOME "/bin/buildir " BBSHOME "/home/%c/%s > /dev/null",
- cuser.userid[0], cuser.userid);
- mouts(b_lines - 1, 0, ANSI_COLOR(1;31) "¤w¸g³B²z§¹²¦!! ½Ñ¦h¤£«K ·q½Ð­ì½Ì~" ANSI_RESET);
- system(genbuf);
- pressanykey();
- return 0;
-}
-
-int
-sendalert(const char *userid, int alert)
-{
- userinfo_t *uentp = NULL;
- int n, tuid, i;
-
- if ((tuid = searchuser(userid, NULL)) == 0)
- return -1;
-
- n = count_logins(tuid, 0);
- for (i = 1; i <= n; i++)
- if ((uentp = (userinfo_t *) search_ulistn(tuid, i)))
- uentp->alerts |= alert;
- return 0;
-}
-
-int
-mail_muser(userec_t muser, const char *title, const char *filename)
-{
- return mail_id(muser.userid, title, filename, cuser.userid);
-}
-
-int
-mail_id(const char *id, const char *title, const char *src, const char *owner)
-{
- fileheader_t mhdr;
- char dst[128], dirf[128];
- sethomepath(dst, id);
- if (stampfile(dst, &mhdr))
- return 0;
- strlcpy(mhdr.owner, owner, sizeof(mhdr.owner));
- strlcpy(mhdr.title, title, sizeof(mhdr.title));
- mhdr.filemode = 0;
- Copy(src, dst);
-
- sethomedir(dirf, id);
- append_record_forward(dirf, &mhdr, sizeof(mhdr), id);
- sendalert(id, ALERT_NEW_MAIL);
- return 0;
-}
-
-int
-invalidaddr(const char *addr)
-{
-#ifdef DEBUG_FWDADDRERR
- const char *origaddr = addr;
- char errmsg[PATHLEN];
-#endif
-
- if (*addr == '\0')
- return 1; /* blank */
-
- while (*addr) {
-#ifdef DEBUG_FWDADDRERR
- if (not_alnum(*addr) && !strchr("[].@-_+", *addr))
- {
- int c = (*addr) & 0xff;
- clear();
- move(2,0);
- outs(
- "±z¿é¤Jªº¦ì§}¿ù»~ (address error)¡C \n\n"
- "¥Ñ©ó³Ìªñ³\\¦h¤H¤ÏÀ³¥´¤J¥¿½Tªº¦ì§}(id©Îemail)«á¨t²Î·|§PÂ_¿ù»~\n"
- "¦ýÀˬd¤£¥X­ì¦]¡A©Ò¥H§Ú­Ì»Ý­n¥¿½Tªº¿ù»~¦^³ø¡C\n\n"
- "¦pªG§A½T¹ê¥´¿ù¤F¡A½Ðª½±µ²¤¹L¤U­±ªº»¡©ú¡C\n"
- "¦pªG§A»{¬°§A¿é¤Jªº¦ì§}½T¹ê¬O¹ïªº¡A½Ð§â¤U­±ªº°T®§½Æ»s°_¨Ó\n"
- "¨Ã¶K¨ì " GLOBAL_BUGREPORT " ªO¡C¥»¯¸¬°³y¦¨¤£«K²`·P©êºp¡C\n\n"
- ANSI_COLOR(1;33));
- sprintf(errmsg, "­ì©l¿é¤J¦ì§}: [%s]\n"
- "¿ù»~¦ì¸m: ²Ä %d ¦r¤¸: 0x%02X [ %c ]\n",
- origaddr, (int)(addr - origaddr+1), c, c);
- outs(errmsg);
- outs(ANSI_RESET);
- vmsg("½Ð«ö¥ô·NÁäÄ~Äò");
- clear();
- return 1;
- }
-#else
- if (not_alnum(*addr) && !strchr("[].@-_", *addr))
- return 1;
-#endif
- addr++;
- }
- return 0;
-}
-
-int
-m_internet(void)
-{
- char receiver[60];
- char title[STRLEN];
-
- getdata(20, 0, "¦¬«H¤H¡G", receiver, sizeof(receiver), DOECHO);
- trim(receiver);
- if (strchr(receiver, '@') && !invalidaddr(receiver) &&
- getdata(21, 0, "¥D ÃD¡G", title, sizeof(title), DOECHO))
- do_send(receiver, title);
- else {
- vmsg("¦¬«H¤H©Î¥DÃD¤£¥¿½T,½Ð­«·s¿ï¨ú«ü¥O");
- }
- return 0;
-}
-
-void
-m_init(void)
-{
- sethomedir(currmaildir, cuser.userid);
-}
-
-static void
-loadmailusage(void)
-{
- mailkeep=get_num_records(currmaildir,sizeof(fileheader_t));
- mailsum =get_sum_records(currmaildir, sizeof(fileheader_t));
-}
-
-void
-setupmailusage(void)
-{ // Ptt: get_sum_records is a bad function
- int max_keepmail = MAX_KEEPMAIL;
-#ifdef PLAY_ANGEL
- if (HasUserPerm(PERM_SYSSUPERSUBOP | PERM_ANGEL))
-#else
- if (HasUserPerm(PERM_SYSSUPERSUBOP))
-#endif
- {
- mailsumlimit = 900;
- max_keepmail = 700;
- }
- else if (HasUserPerm(PERM_SYSSUBOP | PERM_ACCTREG | PERM_PRG |
- PERM_ACTION | PERM_PAINT)) {
- mailsumlimit = 700;
- max_keepmail = 500;
- } else if (HasUserPerm(PERM_BM)) {
- mailsumlimit = 500;
- max_keepmail = 300;
- } else if (HasUserPerm(PERM_LOGINOK))
- mailsumlimit = 200;
- else
- mailsumlimit = 50;
- mailsumlimit += (cuser.exmailbox + ADD_EXMAILBOX) * 10;
- mailmaxkeep = max_keepmail + cuser.exmailbox;
- loadmailusage();
-}
-
-#define MAILBOX_LIM_OK 0
-#define MAILBOX_LIM_KEEP 1
-#define MAILBOX_LIM_SUM 2
-static int
-chk_mailbox_limit(void)
-{
- if (HasUserPerm(PERM_SYSOP) || HasUserPerm(PERM_MAILLIMIT))
- return MAILBOX_LIM_OK;
-
- if (!mailkeep)
- setupmailusage();
-
- if (mailkeep > mailmaxkeep)
- return MAILBOX_LIM_KEEP;
- if (mailsum > mailsumlimit)
- return MAILBOX_LIM_SUM;
- return MAILBOX_LIM_OK;
-}
-
-int
-chkmailbox(void)
-{
- m_init();
-
- switch (chk_mailbox_limit()) {
- case MAILBOX_LIM_KEEP:
- bell();
- bell();
- vmsgf("±z«O¦s«H¥ó¼Æ¥Ø %d ¶W¥X¤W­­ %d, ½Ð¾ã²z", mailkeep, mailmaxkeep);
- return mailkeep;
-
- case MAILBOX_LIM_SUM:
- bell();
- bell();
- vmsgf("«H½c®e¶q(¤j¤p,«D¥ó¼Æ) %d ¶W¥X¤W­­ %d, "
- "½Ð¬å¹Lªøªº¤ô²y°O¿ý©Î«H¥ó", mailsum, mailsumlimit);
- if(showmail_mode != SHOWMAIL_SUM)
- {
- showmail_mode = SHOWMAIL_SUM;
- vmsg("«H½cÅã¥Ü¼Ò¦¡¤w¦Û°Ê§ï¬°Åã¥Ü¤j¤p¡A½ÐºÉ³t¾ã²z");
- }
- return mailsum;
-
- default:
- return 0;
- }
-}
-
-static void
-do_hold_mail(const char *fpath, const char *receiver, const char *holder)
-{
- char buf[80], title[128];
-
- fileheader_t mymail;
-
- sethomepath(buf, holder);
- stampfile(buf, &mymail);
-
- mymail.filemode = FILE_READ ;
- strlcpy(mymail.owner, "[³Æ.§Ñ.¿ý]", sizeof(mymail.owner));
- if (receiver) {
- snprintf(title, sizeof(title), "(%s) %s", receiver, save_title);
- strlcpy(mymail.title, title, sizeof(mymail.title));
- } else
- strlcpy(mymail.title, save_title, sizeof(mymail.title));
-
- sethomedir(title, holder);
-
- unlink(buf);
- Copy(fpath, buf);
- append_record_forward(title, &mymail, sizeof(mymail), holder);
-}
-
-void
-hold_mail(const char *fpath, const char *receiver)
-{
- char buf[4];
-
- getdata(b_lines - 1, 0,
- (cuser.uflag & DEFBACKUP_FLAG) ?
- "¤w¶¶§Q±H¥X¡A¬O§_¦Û¦s©³½Z(Y/N)¡H[Y] " :
- "¤w¶¶§Q±H¥X¡A¬O§_¦Û¦s©³½Z(Y/N)¡H[N] ",
- buf, sizeof(buf), LCECHO);
-
- if (TOBACKUP(buf[0]))
- do_hold_mail(fpath, receiver, cuser.userid);
-}
-
-int
-do_send(const char *userid, const char *title)
-{
- fileheader_t mhdr;
- char fpath[STRLEN];
- char receiver[IDLEN + 1];
- char genbuf[200];
- int internet_mail, i;
- userec_t xuser;
-
- STATINC(STAT_DOSEND);
- if (strchr(userid, '@'))
- internet_mail = 1;
- else {
- internet_mail = 0;
- if (!getuser(userid, &xuser))
- return -1;
- if (!(xuser.userlevel & PERM_READMAIL))
- return -3;
-
- curredit |= EDIT_MAIL;
- curredit &= ~EDIT_ITEM;
- }
- /* process title */
- if (title)
- strlcpy(save_title, title, sizeof(save_title));
- else {
- char tmp_title[STRLEN-20];
- getdata(2, 0, "¥DÃD¡G", tmp_title, sizeof(tmp_title), DOECHO);
- strlcpy(save_title, tmp_title, sizeof(save_title));
- }
-
- setutmpmode(SMAIL);
-
- fpath[0] = '\0';
-
- if (internet_mail) {
- int res, ch;
-
- if (vedit(fpath, NA, NULL) == -1) {
- unlink(fpath);
- clear();
- return -2;
- }
- clear();
- prints("«H¥ó§Y±N±Hµ¹ %s\n¼ÐÃD¬°¡G%s\n½T©w­n±H¥X¶Ü? (Y/N) [Y]",
- userid, save_title);
- ch = igetch();
- switch (ch) {
- case 'N':
- case 'n':
- outs("N\n«H¥ó¤w¨ú®ø");
- res = -2;
- break;
- default:
- outs("Y\n½Ðµy­Ô, «H¥ó¶Ç»¼¤¤...\n");
- res =
-#ifndef USE_BSMTP
- bbs_sendmail(fpath, save_title, userid);
-#else
- bsmtp(fpath, save_title, userid);
-#endif
- hold_mail(fpath, userid);
- }
- unlink(fpath);
- return res;
- } else {
- strlcpy(receiver, userid, sizeof(receiver));
- sethomepath(genbuf, userid);
- stampfile(genbuf, &mhdr);
- strlcpy(mhdr.owner, cuser.userid, sizeof(mhdr.owner));
- if (vedit(genbuf, YEA, NULL) == -1) {
- unlink(genbuf);
- clear();
- return -2;
- }
- /* why not make title here? */
- strlcpy(mhdr.title, save_title, sizeof(mhdr.title));
- clear();
- sethomefile(fpath, userid, FN_OVERRIDES);
- i = belong(fpath, cuser.userid);
- sethomefile(fpath, userid, FN_REJECT);
-
- if (i || !belong(fpath, cuser.userid)) {/* Ptt: ¥Îbelong¦³ÂI°Q¹½ */
- sethomedir(fpath, userid);
- if (append_record_forward(fpath, &mhdr, sizeof(mhdr), userid) == -1)
- return -1;
- sendalert(userid,ALERT_NEW_MAIL);
- }
- hold_mail(genbuf, userid);
- return 0;
- }
-}
-
-void
-my_send(const char *uident)
-{
- switch (do_send(uident, NULL)) {
- case -1:
- outs(err_uid);
- break;
- case -2:
- outs(msg_cancel);
- break;
- case -3:
- prints("¨Ï¥ÎªÌ [%s] µLªk¦¬«H", uident);
- break;
- }
- pressanykey();
-}
-
-int
-m_send(void)
-{
- char uident[40];
-
- stand_title("¥BÅ¥­·ªº¸Ü");
- usercomplete(msg_uid, uident);
- showplans(uident);
- if (uident[0])
- my_send(uident);
- return 0;
-}
-
-/* ¸s²Õ±H«H¡B¦^«H : multi_send, multi_reply */
-static void
-multi_list(int *reciper)
-{
- char uid[16];
- char genbuf[200];
-
- while (1) {
- stand_title("¸s²Õ±H«H¦W³æ");
- ShowNameList(3, 0, msg_cc);
- move(1, 0);
- outs("(I)¤Þ¤J¦n¤Í (O)¤Þ¤J¤W½u³qª¾ (N)¤Þ¤J·s¤å³¹³qª¾ (0-9)¤Þ¤J¨ä¥L¯S§O¦W³æ");
- getdata(2, 0,
- "(A)¼W¥[ (D)§R°£ (M)½T»{±H«H¦W³æ (Q)¨ú®ø ¡H[M]",
- genbuf, 4, LCECHO);
- switch (genbuf[0]) {
- case 'a':
- while (1) {
- move(1, 0);
- usercomplete("½Ð¿é¤J­n¼W¥[ªº¥N¸¹(¥u«ö ENTER µ²§ô·s¼W): ", uid);
- if (uid[0] == '\0')
- break;
-
- move(2, 0);
- clrtoeol();
-
- if (!searchuser(uid, uid))
- outs(err_uid);
- else if (!InNameList(uid)) {
- AddNameList(uid);
- (*reciper)++;
- }
- ShowNameList(3, 0, msg_cc);
- }
- break;
- case 'd':
- while (*reciper) {
- move(1, 0);
- namecomplete("½Ð¿é¤J­n§R°£ªº¥N¸¹(¥u«ö ENTER µ²§ô§R°£): ", uid);
- if (uid[0] == '\0')
- break;
- if (RemoveNameList(uid))
- (*reciper)--;
- ShowNameList(3, 0, msg_cc);
- }
- break;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- listfile[5] = genbuf[0];
- genbuf[0] = '1';
- case 'i':
- setuserfile(genbuf, genbuf[0] == '1' ? listfile : fn_overrides);
- ToggleNameList(reciper, genbuf, msg_cc);
- break;
- case 'o':
- setuserfile(genbuf, "alohaed");
- ToggleNameList(reciper, genbuf, msg_cc);
- break;
- case 'n':
- setuserfile(genbuf, "postlist");
- ToggleNameList(reciper, genbuf, msg_cc);
- break;
- case 'q':
- *reciper = 0;
- return;
- default:
- return;
- }
- }
-}
-
-static void
-multi_send(char *title)
-{
- FILE *fp;
- struct word_t *p = NULL;
- fileheader_t mymail;
- char fpath[TTLEN], *ptr;
- int reciper, listing;
- char genbuf[256];
-
- CreateNameList();
- listing = reciper = 0;
- if (*quote_file) {
- AddNameList(quote_user);
- reciper = 1;
- fp = fopen(quote_file, "r");
- assert(fp);
- while (fgets(genbuf, sizeof(genbuf), fp)) {
- if (strncmp(genbuf, "¡° ", 3)) {
- if (listing)
- break;
- } else {
- if (listing) {
- char *strtok_pos;
- ptr = genbuf + 3;
- for (ptr = strtok_r(ptr, " \n\r", &strtok_pos);
- ptr;
- ptr = strtok_r(NULL, " \n\r", &strtok_pos)) {
- if (searchuser(ptr, ptr) && !InNameList(ptr) &&
- strcmp(cuser.userid, ptr)) {
- AddNameList(ptr);
- reciper++;
- }
- }
- } else if (!strncmp(genbuf + 3, "[³q§i]", 6))
- listing = 1;
- }
- }
- fclose(fp);
- ShowNameList(3, 0, msg_cc);
- }
- multi_list(&reciper);
- move(1, 0);
- clrtobot();
-
- if (reciper) {
- setutmpmode(SMAIL);
- if (title)
- do_reply_title(2, title);
- else {
- getdata(2, 0, "¥DÃD¡G", fpath, sizeof(fpath), DOECHO);
- snprintf(save_title, sizeof(save_title), "[³q§i] %s", fpath);
- }
-
- setuserfile(fpath, fn_notes);
-
- if ((fp = fopen(fpath, "w"))) {
- fprintf(fp, "¡° [³q§i] ¦@ %d ¤H¦¬¥ó", reciper);
- listing = 80;
-
- for (p = toplev; p; p = p->next) {
- reciper = strlen(p->word) + 1;
- if (listing + reciper > 75) {
- listing = reciper;
- fprintf(fp, "\n¡°");
- } else
- listing += reciper;
-
- fprintf(fp, " %s", p->word);
- }
- memset(genbuf, '-', 75);
- genbuf[75] = '\0';
- fprintf(fp, "\n%s\n\n", genbuf);
- fclose(fp);
- }
- curredit |= EDIT_LIST;
-
- if (vedit(fpath, YEA, NULL) == -1) {
- unlink(fpath);
- curredit = 0;
- vmsg(msg_cancel);
- return;
- }
- listing = 80;
-
- for (p = toplev; p; p = p->next) {
- reciper = strlen(p->word) + 1;
- if (listing + reciper > 75) {
- listing = reciper;
- outc('\n');
- } else {
- listing += reciper;
- outc(' ');
- }
- outs(p->word);
- if (searchuser(p->word, p->word) && strcmp(STR_GUEST, p->word)) {
- sethomefile(genbuf, p->word, FN_OVERRIDES);
- if (!belong(genbuf, cuser.userid)) { // not friend, check if rejected
- sethomefile(genbuf, p->word, FN_REJECT);
- if (belong(genbuf, cuser.userid))
- continue;
- }
- sethomepath(genbuf, p->word);
- } else
- continue;
- stampfile(genbuf, &mymail);
- unlink(genbuf);
- Copy(fpath, genbuf);
-
- strlcpy(mymail.owner, cuser.userid, sizeof(mymail.owner));
- strlcpy(mymail.title, save_title, sizeof(mymail.title));
- mymail.filemode |= FILE_MULTI; /* multi-send flag */
- sethomedir(genbuf, p->word);
- if (append_record_forward(genbuf, &mymail, sizeof(mymail), p->word) == -1)
- vmsg(err_uid);
- sendalert(p->word, ALERT_NEW_MAIL);
- }
- hold_mail(fpath, NULL);
- unlink(fpath);
- curredit = 0;
- } else
- vmsg(msg_cancel);
-}
-
-static int
-multi_reply(int ent, fileheader_t * fhdr, const char *direct)
-{
- if (!fhdr || !fhdr->filename[0])
- return DONOTHING;
-
- if (!(fhdr->filemode & FILE_MULTI))
- return mail_reply(ent, fhdr, direct);
-
- stand_title("¸s²Õ¦^«H");
- strlcpy(quote_user, fhdr->owner, sizeof(quote_user));
- setuserfile(quote_file, fhdr->filename);
- if (!dashf(quote_file))
- {
- vmsg("­ìÀɮפw®ø¥¢¡C");
- return FULLUPDATE;
- }
- multi_send(fhdr->title);
- quote_user[0]='\0';
- quote_file[0]='\0';
- return FULLUPDATE;
-}
-
-int
-mail_list(void)
-{
- stand_title("¸s²Õ§@·~");
- multi_send(NULL);
- return 0;
-}
-
-int
-mail_all(void)
-{
- FILE *fp;
- fileheader_t mymail;
- char fpath[TTLEN];
- char genbuf[200];
- int i, unum;
- char *userid;
-
- stand_title("µ¹©Ò¦³¨Ï¥ÎªÌªº¨t²Î³q§i");
- setutmpmode(SMAIL);
- getdata(2, 0, "¥DÃD¡G", fpath, sizeof(fpath), DOECHO);
- snprintf(save_title, sizeof(save_title),
- "[¨t²Î³q§i]" ANSI_COLOR(1;32) " %s" ANSI_RESET, fpath);
-
- setuserfile(fpath, fn_notes);
-
- if ((fp = fopen(fpath, "w"))) {
- fprintf(fp, "¡° [" ANSI_COLOR(1) "¨t²Î³q§i" ANSI_RESET "] ³o¬O«Êµ¹©Ò¦³¨Ï¥ÎªÌªº«H\n");
- fprintf(fp, "-----------------------------------------------------"
- "----------------------\n");
- fclose(fp);
- }
- *quote_file = 0;
-
- curredit |= EDIT_MAIL;
- curredit &= ~EDIT_ITEM;
- if (vedit(fpath, YEA, NULL) == -1) {
- curredit = 0;
- unlink(fpath);
- outs(msg_cancel);
- pressanykey();
- return 0;
- }
- curredit = 0;
-
- setutmpmode(MAILALL);
- stand_title("±H«H¤¤...");
-
- sethomepath(genbuf, cuser.userid);
- stampfile(genbuf, &mymail);
- unlink(genbuf);
- Copy(fpath, genbuf);
- unlink(fpath);
- strcpy(fpath, genbuf);
-
- strlcpy(mymail.owner, cuser.userid, sizeof(mymail.owner)); /* ¯¸ªø ID */
- strlcpy(mymail.title, save_title, sizeof(mymail.title));
-
- sethomedir(genbuf, cuser.userid);
- if (append_record_forward(genbuf, &mymail, sizeof(mymail), cuser.userid) == -1)
- outs(err_uid);
-
- for (unum = SHM->number, i = 0; i < unum; i++) {
- if (bad_user_id(SHM->userid[i]))
- continue; /* Ptt */
-
- userid = SHM->userid[i];
- if (strcmp(userid, STR_GUEST) && strcmp(userid, "new") &&
- strcmp(userid, cuser.userid)) {
- sethomepath(genbuf, userid);
- stampfile(genbuf, &mymail);
- unlink(genbuf);
- Copy(fpath, genbuf);
-
- strlcpy(mymail.owner, cuser.userid, sizeof(mymail.owner));
- strlcpy(mymail.title, save_title, sizeof(mymail.title));
- /* mymail.filemode |= FILE_MARKED; Ptt ¤½§i§ï¦¨¤£·|mark */
- sethomedir(genbuf, userid);
- if (append_record_forward(genbuf, &mymail, sizeof(mymail), userid) == -1)
- outs(err_uid);
- vmsgf("%*s %5d / %5d", IDLEN + 1, userid, i + 1, unum);
- }
- }
- return 0;
-}
-
-int
-mail_mbox(void)
-{
- char cmd[100];
- fileheader_t fhdr;
-
- snprintf(cmd, sizeof(cmd), "/tmp/%s.uu", cuser.userid);
- snprintf(fhdr.title, sizeof(fhdr.title), "%s ¨p¤H¸ê®Æ", cuser.userid);
- doforward(cmd, &fhdr, 'Z');
- return 0;
-}
-
-static int
-m_forward(int ent, fileheader_t * fhdr, const char *direct)
-{
- char uid[STRLEN];
-
- stand_title("Âà¹F«H¥ó");
- usercomplete(msg_uid, uid);
- if (uid[0] == '\0')
- return FULLUPDATE;
-
- strlcpy(quote_user, fhdr->owner, sizeof(quote_user));
- setuserfile(quote_file, fhdr->filename);
- snprintf(save_title, sizeof(save_title), "%.64s (fwd)", fhdr->title);
- move(1, 0);
- clrtobot();
- prints("Âà«Hµ¹: %s\n¼Ð ÃD: %s\n", uid, save_title);
-
- switch (do_send(uid, save_title)) {
- case -1:
- outs(err_uid);
- break;
- case -2:
- outs(msg_cancel);
- break;
- case -3:
- prints("¨Ï¥ÎªÌ [%s] µLªk¦¬«H", uid);
- break;
- }
- pressanykey();
- quote_user[0]='\0';
- quote_file[0]='\0';
- if (strcasecmp(uid, cuser.userid) == 0)
- return DIRCHANGED;
- return FULLUPDATE;
-}
-
-struct ReadNewMailArg {
- int idc;
- int *delmsgs;
- int delcnt;
- int mrd;
-};
-
-static int
-read_new_mail(void * voidfptr, void *optarg)
-{
- fileheader_t *fptr=(fileheader_t*)voidfptr;
- struct ReadNewMailArg *arg=(struct ReadNewMailArg*)optarg;
- char done = NA, delete_it;
- char fname[PATHLEN];
- char genbuf[4];
-
- arg->idc++;
- // XXX fptr->filename may be invalid.
- if (fptr->filemode || !fptr->filename[0])
- return 0;
- clear();
- move(10, 0);
- prints("±z­nŪ¨Ó¦Û[%s]ªº°T®§(%s)¶Ü¡H", fptr->owner, fptr->title);
- getdata(11, 0, "½Ð±z½T©w(Y/N/Q)?[Y] ", genbuf, 3, DOECHO);
- if (genbuf[0] == 'q')
- return QUIT;
- if (genbuf[0] == 'n')
- return 0;
-
- setuserfile(fname, fptr->filename);
- fptr->filemode |= FILE_READ;
- if (substitute_record(currmaildir, fptr, sizeof(*fptr), arg->idc))
- return -1;
-
- arg->mrd = 1;
- delete_it = NA;
- while (!done) {
- int more_result = more(fname, YEA);
-
- switch (more_result) {
- case RET_DOREPLY:
- mail_reply(arg->idc, fptr, currmaildir);
- return FULLUPDATE;
- case RET_DOREPLYALL:
- multi_reply(arg->idc, fptr, currmaildir);
- return FULLUPDATE;
- case RET_DORECOMMEND: // we don't accept this.
- return FULLUPDATE;
- case -1:
- return READ_SKIP;
- case 0:
- break;
- default:
- return more_result;
- }
-
- outmsglr(MSG_MAILER, MSG_MAILER_LEN, "", 0);
-
- switch (igetch()) {
- case 'r':
- case 'R':
- mail_reply(arg->idc, fptr, currmaildir);
- break;
- case 'y':
- multi_reply(arg->idc, fptr, currmaildir);
- break;
- case 'x':
- m_forward(arg->idc, fptr, currmaildir);
- break;
- case 'd':
- case 'D':
- delete_it = YEA;
- default:
- done = YEA;
- }
- }
- if (delete_it) {
- if(arg->delcnt==1000) {
- vmsg("¤@¦¸³Ì¦h§R 1000 «Ê«H");
- return 0;
- }
- clear();
- prints("§R°£«H¥ó¡m%s¡n", fptr->title);
- getdata(1, 0, msg_sure_ny, genbuf, 2, LCECHO);
- if (genbuf[0] == 'y') {
- if(arg->delmsgs==NULL) {
- arg->delmsgs=(int*)malloc(sizeof(int)*1000);
- if(arg->delmsgs==NULL) {
- vmsg("¥¢±Ñ, ½Ð¬¢¯¸ªø");
- return 0;
- }
- }
- unlink(fname);
- arg->delmsgs[arg->delcnt++] = arg->idc;
-
- loadmailusage();
- }
- }
- clear();
- return 0;
-}
-
-void setmailalert()
-{
- if(load_mailalert(cuser.userid))
- currutmp->alerts |= ALERT_NEW_MAIL;
- else
- currutmp->alerts &= ~ALERT_NEW_MAIL;
-}
-int
-m_new(void)
-{
- struct ReadNewMailArg arg;
- clear();
- setutmpmode(RMAIL);
- memset(&arg, 0, sizeof(arg));
- clear();
- curredit |= EDIT_MAIL;
- curredit &= ~EDIT_ITEM;
- if (apply_record(currmaildir, read_new_mail, sizeof(fileheader_t), &arg) == -1) {
- if(arg.delmsgs)
- free(arg.delmsgs);
- vmsg("¨S¦³·s«H¥ó¤F");
- return -1;
- }
- curredit = 0;
- setmailalert();
- while (arg.delcnt--)
- delete_record(currmaildir, sizeof(fileheader_t), arg.delmsgs[arg.delcnt]);
- if(arg.delmsgs)
- free(arg.delmsgs);
- vmsg(arg.mrd ? "«H¤w¾\\²¦" : "¨S¦³·s«H¥ó¤F");
- return -1;
-}
-
-static void
-mailtitle(void)
-{
- char buf[STRLEN];
- int msglen = 0;
-
- showtitle("¶l¥ó¿ï³æ", BBSName);
- prints("[¡ö]Â÷¶}[¡ô¡õ]¿ï¾Ü[¡÷]¾\\Ū«H¥ó [X]Âà¿ý¬ÝªO[F]Âà±H¯¸¥~ "
- " [O]¯¸¥~«H:%s [h]¨D§U\n"
- ANSI_COLOR(7) " ½s¸¹ %s §@ ªÌ «H ¥ó ¼Ð ÃD"
- "",
- REJECT_OUTTAMAIL ? ANSI_COLOR(31) "Ãö" ANSI_RESET : "¶}",
- (showmail_mode == SHOWMAIL_SUM) ? "¤j ¤p":"¤é ´Á");
-
- /* 43 columns in length, used later. */
- buf[0] = 0;
-
- if (mailsumlimit)
- {
- /* warning: snprintf returns length "if not limited".
- * however if this case, they should be the same. */
-
- msglen = snprintf(buf, sizeof(buf),
- ANSI_COLOR(32)
- " (®e¶q:%d/%dk %d/%d½g) ",
- mailsum, mailsumlimit,
- mailkeep, mailmaxkeep);
- msglen -= strlen(ANSI_COLOR(32));
- }
- outslr("", 44, buf, msglen);
- outs(ANSI_RESET);
-}
-
-static void
-maildoent(int num, fileheader_t * ent)
-{
- char *title, *mark, *color = NULL, type = ' ';
- char datepart[6];
- char isonline = 0;
-
- if (ent->filemode & FILE_MARKED)
- {
- type = (ent->filemode & FILE_READ) ?
- 'm' : 'M';
- }
- else if (ent->filemode & FILE_REPLIED)
- {
- type = (ent->filemode & FILE_READ) ?
- 'r' : 'R';
- }
- else
- {
- type = (ent->filemode & FILE_READ) ?
- ' ' : '+';
- }
-
- if (TagNum && !Tagger(atoi(ent->filename + 2), 0, TAG_NIN))
- type = 'D';
-
- title = subject(mark = ent->title);
- if (title == mark) {
- color = ANSI_COLOR(1;31);
- mark = "¡º";
- } else {
- color = ANSI_COLOR(1;33);
- mark = "R:";
- }
-
- strlcpy(datepart, ent->date, sizeof(datepart));
-
- isonline = query_online(ent->owner);
-
- switch(showmail_mode)
- {
- case SHOWMAIL_SUM:
- {
- /* evaluate size */
- size_t filesz = 0;
- char ut = 'k';
- char buf[MAXPATHLEN];
- struct stat st;
-
- if( !ent->filename[0] ){
- filesz = 0;
- } else {
- setuserfile(buf, ent->filename);
- if (stat(buf, &st) >= 0) {
- filesz = st.st_size;
- /* find printing unit */
- filesz = (filesz + 1023) / 1024;
- if(filesz > 9999){
- filesz = (filesz+512) / 1024;
- ut = 'M';
- }
- if(filesz > 9999) {
- filesz = (filesz+512) / 1024;
- ut = 'G';
- }
- }
- }
- sprintf(datepart, "%4lu%c", (unsigned long)filesz, ut);
- }
- break;
- default:
- break;
- }
-
- /* print out */
- if (strncmp(currtitle, title, TTLEN) != 0)
- {
- /* is title. */
- color = "";
- }
-
- prints("%6d %c %-6s%s%-15.14s%s%s %s%-*.*s%s\n",
- num, type, datepart,
- isonline ? ANSI_COLOR(1) : "",
- ent->owner,
- isonline ? ANSI_RESET : "",
- mark, color,
- t_columns - 34, t_columns - 34,
- title,
- *color ? ANSI_RESET : "");
-}
-
-
-static int
-mail_del(int ent, const fileheader_t * fhdr, const char *direct)
-{
- char genbuf[200];
-
- if (fhdr->filemode & FILE_MARKED)
- return DONOTHING;
-
- if (currmode & MODE_SELECT) {
- vmsg("½Ð¥ý¦^¨ì¥¿±`¼Ò¦¡«á¦A¶i¦æ§R°£...");
- return READ_REDRAW;
- }
-
- if (getans(msg_del_ny) == 'y') {
- if (!delete_record(direct, sizeof(*fhdr), ent)) {
- setupmailusage();
- setdirpath(genbuf, direct, fhdr->filename);
-#ifdef USE_RECYCLE
- RcyAddFile(fhdr, 0, genbuf);
-#endif // USE_RECYCLE
- unlink(genbuf);
- loadmailusage();
- return DIRCHANGED;
- }
- }
- return READ_REDRAW;
-}
-
-int b_call_in(int ent, const fileheader_t * fhdr, const char *direct);
-
-static int
-mail_read(int ent, fileheader_t * fhdr, const char *direct)
-{
- char buf[PATHLEN];
- char done, delete_it, replied;
-
- clear();
- setdirpath(buf, direct, fhdr->filename);
- strlcpy(currtitle, subject(fhdr->title), sizeof(currtitle));
- done = delete_it = replied = NA;
- while (!done) {
- int more_result = more(buf, YEA);
-
- /* whether success or not, update flag.
- * or users may bug about "black-hole" mails
- * and blinking notification */
- if( !(fhdr->filemode & FILE_READ))
- {
- fhdr->filemode |= FILE_READ;
- substitute_ref_record(direct, fhdr, ent);
- }
- switch (more_result) {
- case -1:
- /* no such file */
- clear();
- vmsg("¦¹«Ê«HµL¤º®e¡C");
- return FULLUPDATE;
- case RET_DOREPLY:
- mail_reply(ent, fhdr, direct);
- return FULLUPDATE;
- case RET_DOREPLYALL:
- multi_reply(ent, fhdr, direct);
- return FULLUPDATE;
- case RET_DORECOMMEND: // we don't accept this.
- return FULLUPDATE;
- case 0:
- break;
- default:
- return more_result;
- }
- outmsglr(MSG_MAILER, MSG_MAILER_LEN, "", 0);
-
- switch (igetch()) {
- case 'r':
- case 'R':
- replied = YEA;
- mail_reply(ent, fhdr, direct);
- break;
- case 'y':
- multi_reply(ent, fhdr, direct);
- break;
- case 'x':
- m_forward(ent, fhdr, direct);
- break;
- case 'd':
- delete_it = YEA;
- default:
- done = YEA;
- }
- }
- if (delete_it)
- mail_del(ent, fhdr, direct);
- else {
- fhdr->filemode |= FILE_READ;
- substitute_ref_record(direct, fhdr, ent);
- }
- return FULLUPDATE;
-}
-
-static int
-mail_read_all(int ent, fileheader_t * fhdr, const char *direct)
-{
- off_t i = 0, num = 0;
- int fd = 0;
- fileheader_t xfhdr;
-
- currutmp->alerts &= ~ALERT_NEW_MAIL;
- if ((fd = open(currmaildir, O_RDWR)) < 0)
- return DONOTHING;
-
- if ((num = lseek(fd, 0, SEEK_END)) < 0)
- num = 0;
- num /= sizeof(fileheader_t);
-
- i = num - NEWMAIL_CHECK_RANGE;
- if (i < 0) i = 0;
-
- if (lseek(fd, i * (off_t)sizeof(fileheader_t), SEEK_SET) < 0)
- i = num;
-
- for (; i < num; i++)
- {
- if (read(fd, &xfhdr, sizeof(xfhdr)) <= 0)
- break;
- if (xfhdr.filemode & FILE_READ)
- continue;
- xfhdr.filemode |= FILE_READ;
- if (lseek(fd, i * (off_t)sizeof(fileheader_t), SEEK_SET) < 0)
- break;
- write(fd, &xfhdr, sizeof(xfhdr));
- }
-
- close(fd);
- return DIRCHANGED;
-}
-
-static int
-mail_unread(int ent, fileheader_t * fhdr, const char *direct)
-{
- // this function may cause arguments, so please specify
- // if you want this to be enabled.
-#ifdef USE_USER_MAIL_UNREAD
- if (fhdr && fhdr->filemode & FILE_READ)
- {
- fhdr->filemode &= ~FILE_READ;
- substitute_record(direct, fhdr, ent);
- return FULLUPDATE;
- }
-#endif // USE_USER_MAIL_UNREAD
- return DONOTHING;
-}
-
-/* in boards/mail ¦^«Hµ¹­ì§@ªÌ¡AÂà«H¯¸¥ç¥i */
-int
-mail_reply(int ent, fileheader_t * fhdr, const char *direct)
-{
- char uid[STRLEN];
- FILE *fp;
- char genbuf[512];
- int oent = ent;
-
- if (!fhdr || !fhdr->filename[0])
- return DONOTHING;
-
- stand_title("¦^ «H");
-
- /* §PÂ_¬O boards ©Î mail */
- if (curredit & EDIT_MAIL)
- setuserfile(quote_file, fhdr->filename);
- else
- setbfile(quote_file, currboard, fhdr->filename);
-
- /* find the author */
- strlcpy(quote_user, fhdr->owner, sizeof(quote_user));
- if (strchr(quote_user, '.')) {
- char *t;
- char *strtok_pos;
- genbuf[0] = '\0';
- if ((fp = fopen(quote_file, "r"))) {
- fgets(genbuf, sizeof(genbuf), fp);
- fclose(fp);
- }
- t = strtok_r(genbuf, str_space, &strtok_pos);
- if (t && (strcmp(t, str_author1)==0 || strcmp(t, str_author2)==0)
- && (t=strtok_r(NULL, str_space, &strtok_pos)) != NULL)
- strlcpy(uid, t, sizeof(uid));
- else {
- vmsg("¿ù»~: §ä¤£¨ì§@ªÌ¡C");
- quote_user[0]='\0';
- quote_file[0]='\0';
- return FULLUPDATE;
- }
- } else
- strlcpy(uid, quote_user, sizeof(uid));
-
- /* make the title */
- do_reply_title(3, fhdr->title);
- prints("\n¦¬«H¤H: %s\n¼Ð ÃD: %s\n", uid, save_title);
-
- /* edit, then send the mail */
- ent = curredit;
- switch (do_send(uid, save_title)) {
- case -1:
- outs(err_uid);
- break;
- case -2:
- outs(msg_cancel);
- break;
- case -3:
- prints("¨Ï¥ÎªÌ [%s] µLªk¦¬«H", uid);
- break;
-
- case 0:
- /* success */
- if ( direct && /* for board, no direct */
- (curredit & EDIT_MAIL) &&
- !(fhdr->filemode & FILE_REPLIED))
- {
- fhdr->filemode |= FILE_REPLIED;
- substitute_ref_record(direct, fhdr, oent);
- }
- break;
- }
- curredit = ent;
- pressanykey();
- quote_user[0]='\0';
- quote_file[0]='\0';
- if (strcasecmp(uid, cuser.userid) == 0)
- return DIRCHANGED;
- return FULLUPDATE;
-}
-
-static int
-mail_edit(int ent, fileheader_t * fhdr, const char *direct)
-{
- char genbuf[200];
-
- if (!HasUserPerm(PERM_SYSOP))
- return DONOTHING;
-
- setdirpath(genbuf, direct, fhdr->filename);
- vedit(genbuf, NA, NULL);
- return FULLUPDATE;
-}
-
-static int
-mail_nooutmail(int ent, fileheader_t * fhdr, const char *direct)
-{
- cuser.uflag2 ^= REJ_OUTTAMAIL;
- passwd_update(usernum, &cuser);
- return FULLUPDATE;
-
-}
-
-static int
-mail_mark(int ent, fileheader_t * fhdr, const char *direct)
-{
- fhdr->filemode ^= FILE_MARKED;
-
- substitute_ref_record(direct, fhdr, ent);
- return PART_REDRAW;
-}
-
-/* help for mail reading */
-static const char * const mail_help[] = {
- "\0¹q¤l«H½c¾Þ§@»¡©ú",
- "\01°ò¥»©R¥O",
- "(p/¡ô)(n/¡õ) «e¤@½g/¤U¤@½g¤å³¹",
- "(P)(PgUp) «e¤@­¶",
- "(N)(PgDn) ¤U¤@­¶",
- "(¼Æ¦rÁä) ¸õ¨ì²Ä ## µ§",
- "($) ¸õ¨ì³Ì«á¤@µ§",
- "(r)(¡÷) Ū«H",
- "(R)/(y) ¦^«H / ¸s²Õ¦^«H",
- "\01¶i¶¥©R¥O",
- "(TAB) ¤Á´«Åã¥Ü¼Ò¦¡(¥Ø«e¦³¤@¯ë¤ÎÅã¥Ü¤j¤p)",
- "(O) Ãö³¬/¶}±Ò ¯¸¥~«H¥óÂà¤J",
- "(c)/(z) ¦¹«H¥ó¦¬¤J¨p¤H«H¥ó§¨/¶i¤J¨p¤H«H¥ó§¨",
- "(x)/(X) Âà«Hµ¹¨ä¥¦¨Ï¥ÎªÌ/Âà¿ý¤å³¹¨ì¨ä¥L¬ÝªO",
- "(F)/(u) ±N«H¶Ç°e¦^±zªº¹q¤l«H½c/¤ô²y¾ã²z±H¦^«H½c",
- "(d) ±þ±¼¦¹«H",
- "(D) ±þ±¼«ü©w½d³òªº«H",
- "(m) ±N«H¼Ð°O¡A¥H¨¾³Q²M°£",
- "(^G) ¥ß§Y­««Ø«H½c («H½c·´·l®É¥Î)",
- "(t) ¼Ð°O±ý§R°£«H¥ó",
- "(^D) §R°£¤w¼Ð°O«H¥ó",
- NULL
-};
-
-static int
-m_help(void)
-{
- show_help(mail_help);
- return FULLUPDATE;
-}
-
-static int
-mail_cross_post(int ent, fileheader_t * fhdr, const char *direct)
-{
- char xboard[20], fname[80], xfpath[80], xtitle[80], inputbuf[10];
- fileheader_t xfile;
- FILE *xptr;
- int author = 0;
- char genbuf[200];
- char genbuf2[4];
-
-#if 0
- // °£«D¦³¤H©ú¥Õ¬°¦ó­n¥ý ChekPostPerm ¨Ã­×´_¡A
- // §_«h¥ý disable ³o¬q code - ¥Ø«e±`³y¦¨ crash¡C
- //
- // XXX (will crash sometimes because currborad is not defined yet)
- // ³Â·Ð in2 ¨Ó­×´_³o¸Ì: ½T»{Âà¿ý¬°¦ó­n¥ý CheckPostPerm
- if (!currboard || currboard[0] == 0)
- {
- enter_board(DEFAULT_BOARD);
- }
- assert(0<=ent-1 && ent-1<MAX_BOARD);
-
- if (!CheckPostPerm()) {
- vmsg("¹ï¤£°_¡A±z¥Ø«eµLªkÂà¿ý¤å³¹¡I");
- return FULLUPDATE;
- }
-#endif
-
- move(2, 0);
- clrtoeol();
- if (postrecord.times > 1)
- {
- outs(ANSI_COLOR(1;31)
- "½Ðª`·N: ­Y¹L¶q­«½ÆÂà¿ý±Nµø¬°¬~ªO¡A¾É­P³Q¶}»@³æ°±Åv¡C\n" ANSI_RESET
- "­Y¦³¯S§O»Ý¨D½Ð¬¢¦UªO¥D¡A½Ð¥L­ÌÀ°§AÂà¤å¡C\n\n");
- }
- move(1, 0);
- CompleteBoard("Âà¿ý¥»¤å³¹©ó¬ÝªO¡G", xboard);
-
- if (*xboard == '\0' || !haspostperm(xboard))
- {
- vmsg("µLªkÂà¿ý");
- return FULLUPDATE;
- }
-
- /* ­É¥ÎÅÜ¼Æ */
- ent = StringHash(fhdr->title);
- /* ¦P¼Ë title ¤£ºÞ¹ï­þ­ÓªO³£ºâ cross post , ©Ò¥H¤£¥ÎÀˬd author */
-
- if ((ent != 0 && ent == postrecord.checksum[0])) {
- /* Àˬd cross post ¦¸¼Æ */
- if (postrecord.times++ > MAX_CROSSNUM)
- anticrosspost();
- } else {
- postrecord.times = 0;
- postrecord.last_bid = 0;
- postrecord.checksum[0] = ent;
- }
-
- ent = getbnum(xboard);
- assert(0<=ent-1 && ent-1<MAX_BOARD);
- if (!CheckPostRestriction(ent))
- {
- vmsg("§A¤£°÷¸ê²`³á¡I (¥i¦b¬ÝªO¤º«ö i ¬d¬Ý­­¨î)");
- return FULLUPDATE;
- }
-
-#ifdef USE_COOLDOWN
- if(check_cooldown(&bcache[ent - 1]))
- return READ_REDRAW;
-#endif
-
- ent = 1;
- if (HasUserPerm(PERM_SYSOP) || !strcmp(fhdr->owner, cuser.userid)) {
- getdata(2, 0, "(1)­ì¤åÂà¸ü (2)ÂÂÂà¿ý®æ¦¡¡H[1] ",
- genbuf, 3, DOECHO);
- if (genbuf[0] != '2') {
- ent = 0;
- getdata(2, 0, "«O¯d­ì§@ªÌ¦WºÙ¶Ü?[Y] ", inputbuf, 3, DOECHO);
- if (inputbuf[0] != 'n' && inputbuf[0] != 'N')
- author = 1;
- }
- }
- if (ent)
- snprintf(xtitle, sizeof(xtitle), "[Âà¿ý]%.66s", fhdr->title);
- else
- strlcpy(xtitle, fhdr->title, sizeof(xtitle));
-
- snprintf(genbuf, sizeof(genbuf), "±Ä¥Î­ì¼ÐÃD¡m%.60s¡n¶Ü?[Y] ", xtitle);
- getdata(2, 0, genbuf, genbuf2, sizeof(genbuf2), LCECHO);
- if (*genbuf2 == 'n')
- if (getdata(2, 0, "¼ÐÃD¡G", genbuf, TTLEN, DOECHO))
- strlcpy(xtitle, genbuf, sizeof(xtitle));
-
- getdata(2, 0, "(S)¦sÀÉ (L)¯¸¤º (Q)¨ú®ø¡H[Q] ", genbuf, 3, LCECHO);
- if (genbuf[0] == 'l' || genbuf[0] == 's') {
- int currmode0 = currmode;
-
- currmode = 0;
- setbpath(xfpath, xboard);
- stampfile(xfpath, &xfile);
- if (author)
- strlcpy(xfile.owner, fhdr->owner, sizeof(xfile.owner));
- else
- strlcpy(xfile.owner, cuser.userid, sizeof(xfile.owner));
- strlcpy(xfile.title, xtitle, sizeof(xfile.title));
- if (genbuf[0] == 'l') {
- xfile.filemode = FILE_LOCAL;
- }
- setuserfile(fname, fhdr->filename);
- {
- const char *save_currboard;
- xptr = fopen(xfpath, "w");
- assert(xptr);
-
- strlcpy(save_title, xfile.title, sizeof(save_title));
- save_currboard = currboard;
- currboard = xboard;
- write_header(xptr, save_title);
- currboard = save_currboard;
-
- fprintf(xptr, "¡° [¥»¤åÂà¿ý¦Û %s «H½c]\n\n", cuser.userid);
-
- b_suckinfile(xptr, fname);
- addsignature(xptr, 0);
- fclose(xptr);
- }
-
- setbdir(fname, xboard);
- append_record(fname, &xfile, sizeof(xfile));
- setbtotal(getbnum(xboard));
-
- if (!xfile.filemode)
- outgo_post(&xfile, xboard, cuser.userid, cuser.nickname);
-#ifdef USE_COOLDOWN
- if (bcache[getbnum(xboard) - 1].brdattr & BRD_COOLDOWN)
- add_cooldowntime(usernum, 5);
- add_posttimes(usernum, 1);
-#endif
-
- // cross-post does not add numpost.
- outs("Âà¿ý«H¥ó¤£¼W¥[¤å³¹¼Æ¡A·q½Ð¥]²[¡C");
-
- vmsg("¤å³¹Âà¿ý§¹¦¨");
- currmode = currmode0;
- }
- return FULLUPDATE;
-}
-
-int
-mail_man(void)
-{
- char buf[PATHLEN], buf1[64];
- int mode0 = currutmp->mode;
- int stat0 = currstat;
-
- // TODO if someday we put things in user man...?
- sethomeman(buf, cuser.userid);
-
- // if user already has man directory or permission,
- // allow entering mail-man folder.
-
- if (!dashd(buf) && !HasUserPerm(PERM_MAILLIMIT))
- return DONOTHING;
-
- snprintf(buf1, sizeof(buf1), "%s ªº«H¥ó§¨", cuser.userid);
- a_menu(buf1, buf, HasUserPerm(PERM_MAILLIMIT) ? 1 : 0, 0, NULL);
- currutmp->mode = mode0;
- currstat = stat0;
- return FULLUPDATE;
-}
-
-// XXX BUG mail_cite ¦³¥i¯à·|¸õ¶i a_menu, ¦Ó a_menu ·| check
-// currbid¡C ¤@¾ã­ÓÁV¿|ªºÅÞ¿è¿ù»~...
-static int
-mail_cite(int ent, fileheader_t * fhdr, const char *direct)
-{
- char fpath[PATHLEN];
- char title[TTLEN + 1];
- static char xboard[20] = "";
- char buf[20];
- int bid;
-
- setuserfile(fpath, fhdr->filename);
- strlcpy(title, "¡º ", sizeof(title));
- strlcpy(title + 3, fhdr->title, sizeof(title) - 3);
- a_copyitem(fpath, title, 0, 1);
-
- if (cuser.userlevel >= PERM_BM) {
- move(2, 0);
- clrtoeol();
- move(3, 0);
- clrtoeol();
- move(1, 0);
-
- CompleteBoard(
- HasUserPerm(PERM_MAILLIMIT) ?
- "¿é¤J¬ÝªO¦WºÙ (ª½±µEnter¶i¤J¨p¤H«H¥ó§¨)¡G" :
- "¿é¤J¬ÝªO¦WºÙ¡G",
- buf);
- if (*buf)
- strlcpy(xboard, buf, sizeof(xboard));
- if (*xboard && ((bid = getbnum(xboard)) > 0)){ /* XXXbid */
- setapath(fpath, xboard);
- setutmpmode(ANNOUNCE);
- a_menu(xboard, fpath,
- HasUserPerm(PERM_ALLBOARD) ? 2 : is_BM_cache(bid) ? 1 : 0,
- bid,
- NULL);
- } else {
- mail_man();
- }
- return FULLUPDATE;
- } else {
- mail_man();
- return FULLUPDATE;
- }
-}
-
-static int
-mail_save(int ent, fileheader_t * fhdr, const char *direct)
-{
- char fpath[PATHLEN];
- char title[TTLEN + 1];
-
- if (HasUserPerm(PERM_MAILLIMIT)) {
- setuserfile(fpath, fhdr->filename);
- strlcpy(title, "¡º ", sizeof(title));
- strlcpy(title + 3, fhdr->title, sizeof(title) - 3);
- a_copyitem(fpath, title, fhdr->owner, 1);
- sethomeman(fpath, cuser.userid);
- a_menu(cuser.userid, fpath, 1, 0, NULL);
- return FULLUPDATE;
- }
- return DONOTHING;
-}
-
-#ifdef OUTJOBSPOOL
-static int
-mail_waterball(int ent, fileheader_t * fhdr, const char *direct)
-{
- static char address[60] = "", cmode = 1;
- char fname[500], genbuf[200];
- FILE *fp;
-
- if (!(strstr(fhdr->title, "¼ö½u") && strstr(fhdr->title, "°O¿ý"))) {
- vmsg("¥²¶·¬O ¼ö½u°O¿ý ¤~¯à¨Ï¥Î¤ô²y¾ã²zªº­ò!");
- return 1;
- }
-
- if (!address[0])
- strlcpy(address, cuser.email, sizeof(address));
-
- move(b_lines - 8, 0); clrtobot();
- outs(ANSI_COLOR(1;33;45) "¡¹¤ô²y¾ã²zµ{¦¡ " ANSI_RESET "\n"
- "¨t²Î±N·|«ö·Ó©M¤£¦P¤H¥áªº¤ô²y¦U¦Û¿W¥ß\n"
- "©ó¾ãÂIªº®É­Ô (¦y®p®É¬q°£¥~) ±N¸ê®Æ¾ã²z¦n±H°eµ¹±z\n\n\n");
-
- if (address[0]) {
- snprintf(genbuf, sizeof(genbuf), "±H©¹ [%s] ¶Ü[Y/n/q]¡H ", address);
- getdata(b_lines - 5, 0, genbuf, fname, 3, LCECHO);
- if (fname[0] == 'q') {
- outmsg("¨ú®ø³B²z");
- return 1;
- }
- if (fname[0] == 'n')
- address[0] = '\0';
- }
- if (!address[0]) {
- move(b_lines-4, 0);
- prints( "½Ðª`·N¥Ø«e¥u¤ä´©±H©¹¼Ð·Ç e-mail ¦a§}¡C\n"
- "­Y·Q±H¦^¦¹«H½c½Ð¥Î¿é¤J %s.bbs@" MYHOSTNAME "\n", cuser.userid);
-
- getdata(b_lines - 5, 0, "½Ð¿é¤J¶l¥ó¦a§}¡G", fname, 60, DOECHO);
- if (fname[0] && strchr(fname, '.')) {
- strlcpy(address, fname, sizeof(address));
- } else {
- vmsg("¦a§}®æ¦¡¤£¥¿½T¡A¨ú®ø³B²z");
- return 1;
- }
- }
- trim(address);
- if (invalidaddr(address))
- return -2;
- move(b_lines-4, 0); clrtobot();
-
- if( strstr(address, ".bbs") && REJECT_OUTTAMAIL ){
- outs("\n±z¥²¶·­n¥´¶}±µ¨ü¯¸¥~«H, ¤ô²y¾ã²z¨t²Î¤~¯à±H¤Jµ²ªG\n"
- "½Ð³Â·Ð¨ì¡i¶l¥ó¿ï³æ¡j«ö¤j¼g O§ï¦¨±µ¨ü¯¸¥~«H (¦b¥k¤W¨¤)\n"
- "¦A­«·s°õ¦æ¥»¥\\¯à :)\n");
- vmsg("½Ð¥´¶}¯¸¥~«H, ¦A­«·s°õ¦æ¥»¥\\¯à");
- return FULLUPDATE;
- }
-
- //snprintf(fname, sizeof(fname), "%d\n", cmode);
- outs("¨t²Î´£¨Ñ¨âºØ¼Ò¦¡: \n"
- "¼Ò¦¡ 0: ºë²¼Ò¦¡, ±N¤£§tÃC¦â±±¨î½X, ¤è«K¥H¯Â¤å¦r½s¿è¾¹¾ã²z¦¬ÂÃ\n"
- "¼Ò¦¡ 1: µØÄR¼Ò¦¡, ¥]§tÃC¦â±±¨î½Xµ¥, ¤è«K¦b bbs¤Wª½±µ½s¿è¦¬ÂÃ\n");
- getdata(b_lines - 1, 0, "¨Ï¥Î¼Ò¦¡(0/1/Q)? [1]", fname, 3, LCECHO);
- if (fname[0] == 'Q' || fname[0] == 'q') {
- outmsg("¨ú®ø³B²z");
- return FULLUPDATE;
- }
- cmode = (fname[0] != '0' && fname[0] != '1') ? 1 : fname[0] - '0';
-
- snprintf(fname, sizeof(fname), BBSHOME "/jobspool/water.src.%s-%d",
- cuser.userid, (int)now);
- snprintf(genbuf, sizeof(genbuf), "cp " BBSHOME "/home/%c/%s/%s %s",
- cuser.userid[0], cuser.userid, fhdr->filename, fname);
- system(genbuf);
- /* dirty code ;x */
- snprintf(fname, sizeof(fname), BBSHOME "/jobspool/water.des.%s-%d",
- cuser.userid, (int)now);
- fp = fopen(fname, "wt");
- assert(fp);
- fprintf(fp, "%s\n%s\n%d\n", cuser.userid, address, cmode);
- fclose(fp);
- vmsg("³]©w§¹¦¨, ¨t²Î±N¦b¤U¤@­Ó¾ãÂI(¦y®p®É¬q°£¥~)±N¸ê®Æ±Hµ¹±z");
- return FULLUPDATE;
-}
-#endif
-static const onekey_t mail_comms[] = {
- { 0, NULL }, // Ctrl('A')
- { 0, NULL }, // Ctrl('B')
- { 0, NULL }, // Ctrl('C')
- { 0, NULL }, // Ctrl('D')
- { 0, NULL }, // Ctrl('E')
- { 0, NULL }, // Ctrl('F')
- { 0, built_mail_index }, // Ctrl('G')
- { 0, NULL }, // Ctrl('H')
- { 0, toggle_showmail_mode }, // Ctrl('I')
- { 0, NULL }, // Ctrl('J')
- { 0, NULL }, // Ctrl('K')
- { 0, NULL }, // Ctrl('L')
- { 0, NULL }, // Ctrl('M')
- { 0, NULL }, // Ctrl('N')
- { 0, NULL }, // Ctrl('O') // DO NOT USE THIS KEY - UNIX not sending
- { 0, NULL }, // Ctrl('P')
- { 0, NULL }, // Ctrl('Q')
- { 0, NULL }, // Ctrl('R')
- { 0, NULL }, // Ctrl('S')
- { 0, NULL }, // Ctrl('T')
- { 0, NULL }, // Ctrl('U')
- { 0, NULL }, // Ctrl('V')
- { 0, NULL }, // Ctrl('W')
- { 0, NULL }, // Ctrl('X')
- { 0, NULL }, // Ctrl('Y')
- { 0, NULL }, // Ctrl('Z') 26
- { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL },
- { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL },
- { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL },
- { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL },
- { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL },
- { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL },
- { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL },
- { 0, NULL }, { 0, NULL }, { 0, NULL },
- { 0, NULL }, // 'A' 65
- { 0, NULL }, // 'B'
- { 0, NULL }, // 'C'
- { 1, del_range }, // 'D'
- { 1, mail_edit }, // 'E'
- { 0, NULL }, // 'F'
- { 0, NULL }, // 'G'
- { 0, NULL }, // 'H'
- { 0, NULL }, // 'I'
- { 0, NULL }, // 'J'
- { 0, NULL }, // 'K'
- { 0, NULL }, // 'L'
- { 0, NULL }, // 'M'
- { 0, NULL }, // 'N'
- { 1, mail_nooutmail }, // 'O'
- { 0, NULL }, // 'P'
- { 0, NULL }, // 'Q'
- { 1, mail_reply }, // 'R'
- { 0, NULL }, // 'S'
- { 1, edit_title }, // 'T'
- { 0, NULL }, // 'U'
- { 1, mail_unread }, // 'V'
- { 0, NULL }, // 'W'
- { 1, mail_cross_post }, // 'X'
- { 0, NULL }, // 'Y'
- { 0, NULL }, // 'Z' 90
- { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL },
- { 0, NULL }, // 'a' 97
- { 0, NULL }, // 'b'
- { 1, mail_cite }, // 'c'
- { 1, mail_del }, // 'd'
- { 0, NULL }, // 'e'
- { 0, NULL }, // 'f'
- { 0, NULL }, // 'g'
- { 0, m_help }, // 'h'
- { 0, NULL }, // 'i'
- { 0, NULL }, // 'j'
- { 0, NULL }, // 'k'
- { 0, NULL }, // 'l'
- { 1, mail_mark }, // 'm'
- { 0, NULL }, // 'n'
- { 0, NULL }, // 'o'
- { 0, NULL }, // 'p'
- { 0, NULL }, // 'q'
- { 1, mail_read }, // 'r'
- { 1, mail_save }, // 's'
- { 0, NULL }, // 't'
-#ifdef OUTJOBSPOOL
- { 1, mail_waterball }, // 'u'
-#else
- { 0, NULL }, // 'u'
-#endif
- { 0, mail_read_all }, // 'v'
- { 1, b_call_in }, // 'w'
- { 1, m_forward }, // 'x'
- { 1, multi_reply }, // 'y'
- { 0, mail_man }, // 'z' 122
-};
-
-int
-m_read(void)
-{
- int back_bid;
- if (get_num_records(currmaildir, sizeof(fileheader_t))) {
- curredit = EDIT_MAIL;
- curredit &= ~EDIT_ITEM;
- back_bid = currbid;
- currbid = 0;
- i_read(RMAIL, currmaildir, mailtitle, maildoent, mail_comms, -1);
- currbid = back_bid;
- curredit = 0;
- setmailalert();
- return 0;
- } else {
- outs("±z¨S¦³¨Ó«H");
- return XEASY;
- }
-}
-
-/* ±H¯¸¤º«H */
-static int
-send_inner_mail(const char *fpath, const char *title, const char *receiver)
-{
- char fname[PATHLEN];
- fileheader_t mymail;
- char rightid[IDLEN+1];
-
- if (!searchuser(receiver, rightid))
- return -2;
-
- /* to avoid DDOS of disk */
- sethomedir(fname, rightid);
- if (strcmp(rightid, cuser.userid) == 0) {
- if (chk_mailbox_limit())
- return -4;
- }
-
- sethomepath(fname, rightid);
- stampfile(fname, &mymail);
- if (!strcmp(rightid, cuser.userid)) {
- /* Using BBSNAME may be too loooooong. */
- strlcpy(mymail.owner, "[¯¸¤º]", sizeof(mymail.owner));
- mymail.filemode = FILE_READ;
- } else
- strlcpy(mymail.owner, cuser.userid, sizeof(mymail.owner));
- strlcpy(mymail.title, title, sizeof(mymail.title));
- unlink(fname);
- Copy(fpath, fname);
- sethomedir(fname, rightid);
- append_record_forward(fname, &mymail, sizeof(mymail), rightid);
- sendalert(receiver, ALERT_NEW_MAIL);
- return 0;
-}
-
-#include <netdb.h>
-#include <pwd.h>
-#include <time.h>
-
-#ifndef USE_BSMTP
-static int
-bbs_sendmail(const char *fpath, const char *title, char *receiver)
-{
- char *ptr;
- char genbuf[256];
- FILE *fin, *fout;
-
- /* ¤¤³~ÄdºI */
- if ((ptr = strchr(receiver, ';'))) {
- *ptr = '\0';
- }
- if ((ptr = strstr(receiver, str_mail_address)) || !strchr(receiver, '@')) {
- char hacker[20];
- int len;
-
- if (strchr(receiver, '@')) {
- len = ptr - receiver;
- memcpy(hacker, receiver, len);
- hacker[len] = '\0';
- } else
- strlcpy(hacker, receiver, sizeof(hacker));
- return send_inner_mail(fpath, title, hacker);
- }
- /* Running the sendmail */
- if (fpath == NULL) {
- snprintf(genbuf, sizeof(genbuf),
- "/usr/sbin/sendmail %s > /dev/null", receiver);
- fin = fopen("etc/confirm", "r");
- } else {
- snprintf(genbuf, sizeof(genbuf),
- "/usr/sbin/sendmail -f %s%s %s > /dev/null",
- cuser.userid, str_mail_address, receiver);
- fin = fopen(fpath, "r");
- }
- if (fin == NULL)
- return -1;
- fout = popen(genbuf, "w");
- if (fout == NULL) {
- fclose(fin);
- return -1;
- }
-
- if (fpath)
- fprintf(fout, "Reply-To: %s%s\nFrom: %s <%s%s>\n",
- cuser.userid, str_mail_address,
- cuser.nickname,
- cuser.userid, str_mail_address);
- fprintf(fout,"To: %s\nSubject: %s\n"
- "Mime-Version: 1.0\r\n"
- "Content-Type: text/plain; charset=\"big5\"\r\n"
- "Content-Transfer-Encoding: 8bit\r\n"
- "X-Disclaimer: " BBSNAME "¹ï¥»«H¤º®e®¤¤£­t³d¡C\n\n",
- receiver, title);
-
- while (fgets(genbuf, sizeof(genbuf), fin)) {
- if (genbuf[0] == '.' && genbuf[1] == '\n')
- fputs(". \n", fout);
- else
- fputs(genbuf, fout);
- }
- fclose(fin);
- fprintf(fout, ".\n");
- pclose(fout);
- return 0;
-}
-#else /* USE_BSMTP */
-
-int
-bsmtp(const char *fpath, const char *title, const char *rcpt)
-{
- char buf[80], *ptr;
- time4_t chrono;
- MailQueue mqueue;
-
- /* check if the mail is a inner mail */
- if ((ptr = strstr(rcpt, str_mail_address)) || !strchr(rcpt, '@')) {
- char hacker[20];
- int len;
-
- if (strchr(rcpt, '@')) {
- len = ptr - rcpt;
- memcpy(hacker, rcpt, len);
- hacker[len] = '\0';
- } else
- strlcpy(hacker, rcpt, sizeof(hacker));
- return send_inner_mail(fpath, title, hacker);
- }
- chrono = now;
-
- /* stamp the queue file */
- strlcpy(buf, "out/", sizeof(buf));
- for (;;) {
- snprintf(buf + 4, sizeof(buf) - 4, "M.%d.%d.A", (int)++chrono, getpid());
- if (!dashf(buf)) {
- Copy(fpath, buf);
- break;
- }
- }
-
- fpath = buf;
-
- /* setup mail queue */
- mqueue.mailtime = chrono;
- // XXX (unused) mqueue.method = method;
- strlcpy(mqueue.filepath, fpath, sizeof(mqueue.filepath));
- strlcpy(mqueue.subject, title, sizeof(mqueue.subject));
- strlcpy(mqueue.sender, cuser.userid, sizeof(mqueue.sender));
- strlcpy(mqueue.username, cuser.nickname, sizeof(mqueue.username));
- strlcpy(mqueue.rcpt, rcpt, sizeof(mqueue.rcpt));
-
- if (append_record("out/" FN_DIR, (fileheader_t *) & mqueue, sizeof(mqueue)) < 0)
- return 0;
- return chrono;
-}
-#endif /* USE_BSMTP */
-
-int
-doforward(const char *direct, const fileheader_t * fh, int mode)
-{
- static char address[STRLEN] = "";
- char fname[PATHLEN];
- char genbuf[PATHLEN];
- int return_no;
-
- if (!address[0] && strcmp(cuser.email, "x") != 0)
- strlcpy(address, cuser.email, sizeof(address));
-
- if( mode == 'U' ){
- vmsg("±N¶i¦æ uuencode ¡C­Y±z¤£²M·¡¤°»ò¬O uuencode ½Ð§ï¥Î FÂà±H¡C");
- }
- trim(address);
-
- // if user has address and not the default 'x' (no-email)...
- if (address[0]) {
- snprintf(genbuf, sizeof(genbuf),
- "½T©wÂà±Hµ¹ [%s] ¶Ü(Y/N/Q)¡H[Y] ", address);
- getdata(b_lines, 0, genbuf, fname, 3, LCECHO);
-
- if (fname[0] == 'q') {
- outmsg("¨ú®øÂà±H");
- return 1;
- }
- if (fname[0] == 'n')
- address[0] = '\0';
- }
- if (!address[0]) {
- do {
- getdata(b_lines - 1, 0, "½Ð¿é¤JÂà±H¦a§}¡G", fname, 60, DOECHO);
- if (fname[0]) {
- if (strchr(fname, '.'))
- strlcpy(address, fname, sizeof(address));
- else
- snprintf(address, sizeof(address),
- "%s.bbs@%s", fname, MYHOSTNAME);
- } else {
- vmsg("¨ú®øÂà±H");
- return 1;
- }
- } while (mode == 'Z' && strstr(address, MYHOSTNAME));
- }
- /* according to our experiment, many users leave blanks */
- trim(address);
- if (invalidaddr(address))
- return -2;
-
- outmsg("¥¿Âà±H½Ðµy­Ô...");
- refresh();
-
- /* °lÂÜ¨Ï¥ÎªÌ */
- if (HasUserPerm(PERM_LOGUSER))
- log_user("mailforward to %s ",address);
- if (mode == 'Z') {
- snprintf(fname, sizeof(fname),
- TAR_PATH " cfz /tmp/home.%s.tgz home/%c/%s; "
- MUTT_PATH " -a /tmp/home.%s.tgz -s 'home.%s.tgz' '%s' </dev/null;"
- "rm /tmp/home.%s.tgz",
- cuser.userid, cuser.userid[0], cuser.userid,
- cuser.userid, cuser.userid, address, cuser.userid);
- system(fname);
- return 0;
- snprintf(fname, sizeof(fname), TAR_PATH " cfz - home/%c/%s | "
- "/usr/bin/uuencode %s.tgz > %s",
- cuser.userid[0], cuser.userid, cuser.userid, direct);
- system(fname);
- strlcpy(fname, direct, sizeof(fname));
- } else if (mode == 'U') {
- char tmp_buf[128];
-
- snprintf(fname, sizeof(fname), "/tmp/bbs.uu%05d", (int)currpid);
- snprintf(tmp_buf, sizeof(tmp_buf),
- "/usr/bin/uuencode %s/%s uu.%05d > %s",
- direct, fh->filename, (int)currpid, fname);
- system(tmp_buf);
- } else if (mode == 'F') {
- char tmp_buf[128];
-
- snprintf(fname, sizeof(fname), "/tmp/bbs.f%05d", (int)currpid);
- snprintf(tmp_buf, sizeof(tmp_buf), "%s/%s", direct, fh->filename);
- Copy(tmp_buf, fname);
- } else
- return -1;
-
- return_no =
-#ifndef USE_BSMTP
- bbs_sendmail(fname, fh->title, address);
-#else
- bsmtp(fname, fh->title, address);
-#endif
- unlink(fname);
- return (return_no);
-}
-
-int
-load_mailalert(const char *userid)
-{
- struct stat st;
- char maildir[MAXPATHLEN];
- int fd;
- register int num;
- fileheader_t my_mail;
-
- sethomedir(maildir, userid);
- if (!HasUserPerm(PERM_BASIC))
- return 0;
- if (stat(maildir, &st) < 0)
- return 0;
- num = st.st_size / sizeof(fileheader_t);
- if (num <= 0)
- return 0;
- if (num > NEWMAIL_CHECK_RANGE)
- num = NEWMAIL_CHECK_RANGE;
-
- /* ¬Ý¬Ý¦³¨S¦³«H¥óÁÙ¨SŪ¹L¡H±qÀɧÀ¦^ÀYÀˬd¡A®Ä²v¸û°ª */
- if ((fd = open(maildir, O_RDONLY)) > 0) {
- lseek(fd, st.st_size - sizeof(fileheader_t), SEEK_SET);
- while (num--) {
- read(fd, &my_mail, sizeof(fileheader_t));
- if (!(my_mail.filemode & FILE_READ)) {
- close(fd);
- return ALERT_NEW_MAIL;
- }
- lseek(fd, -(off_t) 2 * sizeof(fileheader_t), SEEK_CUR);
- }
- close(fd);
- }
- return 0;
-}
diff --git a/mbbsd/mbbsd.c b/mbbsd/mbbsd.c
deleted file mode 100644
index 0c561ed1..00000000
--- a/mbbsd/mbbsd.c
+++ /dev/null
@@ -1,1832 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-#include "banip.h"
-
-#ifdef __linux__
-# ifdef CRITICAL_MEMORY
-# include <malloc.h>
-# endif
-# ifdef DEBUG
-# include <mcheck.h>
-# endif
-#endif
-
-
-#define SOCKET_QLEN 4
-
-static void do_aloha(const char *hello);
-static void getremotename(const struct sockaddr_in * from, char *rhost, char *rname);
-
-#ifdef CONVERT
-void big2gb_init(void*);
-void gb2big_init(void*);
-void big2uni_init(void*);
-void uni2big_init(void*);
-#endif
-
-//////////////////////////////////////////////////////////////////
-// Site Optimization
-// override these macro if you need more optimization,
-// based on OS/lib/package...
-#ifndef OPTIMIZE_LISTEN_SOCKET
-#define OPTIMIZE_LISTEN_SOCKET(sock,sz)
-#endif
-
-#ifndef XAUTH_HOST
-#define XAUTH_HOST(x) x
-#endif
-
-#ifndef XAUTH_GETREMOTENAME
-#define XAUTH_GETREMOTENAME(x) x
-#endif
-
-#ifndef XAUTH_TRYREMOTENAME
-#define XAUTH_TRYREMOTENAME()
-#endif
-
-#if 0
-static jmp_buf byebye;
-#endif
-
-static char remoteusername[40] = "?";
-static unsigned char enter_uflag;
-static int use_shell_login_mode = 0;
-static int listen_port = 23;
-
-#ifdef DETECT_CLIENT
-Fnv32_t client_code=FNV1_32_INIT;
-
-void UpdateClientCode(unsigned char c)
-{
- FNV1A_CHAR(c, client_code);
-}
-#endif
-
-#ifdef USE_RFORK
-#define fork() rfork(RFFDG | RFPROC | RFNOWAIT)
-#endif
-
-/* set signal handler, which won't be reset once signal comes */
-static void
-signal_restart(int signum, void (*handler) (int))
-{
- struct sigaction act;
- act.sa_handler = handler;
- memset(&(act.sa_mask), 0, sizeof(sigset_t));
- act.sa_flags = 0;
- sigaction(signum, &act, NULL);
-}
-
-static void
-start_daemon(void)
-{
- int n, fd;
-
- /*
- * 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_t dummy = time(NULL);
- struct tm *dummy_time = localtime(&dummy);
- char buf[32];
-
- strftime(buf, sizeof(buf), "%d/%b/%Y:%H:%M:%S", dummy_time);
-
-#ifndef NO_FORK
- if ((n = fork())) {
- exit(0);
- }
-#endif
-
- /* rocker.011018: it's a good idea to close all unexcept fd!! */
-#ifndef VALGRIND
- n = getdtablesize();
- while (n)
- close(--n);
-
- if( ((fd = open("log/stderr", O_WRONLY | O_CREAT | O_APPEND, 0644)) >= 0) && fd != 2 ){
- dup2(fd, 2);
- close(fd);
- }
-#endif
-
- if(getenv("SSH_CLIENT"))
- unsetenv("SSH_CLIENT");
-
- /*
- * rocker.011018: we don't need to remember original tty, so request a
- * new session id
- */
- setsid();
-
- /*
- * rocker.011018: after new session, we should insure the process is
- * clean daemon
- */
-#ifndef NO_FORK
- if ((n = fork())) {
- exit(0);
- }
-#endif
-}
-
-static void
-reapchild(int sig)
-{
- int state, pid;
-
- while ((pid = waitpid(-1, &state, WNOHANG | WUNTRACED)) > 0);
-}
-
-void
-log_usies(const char *mode, const char *mesg)
-{
- now = time(NULL);
- if (!mesg)
- log_filef(FN_USIES, LOG_CREAT,
- "%s %s %-12s Stay:%d (%s)\n",
- Cdate(&now), mode, cuser.userid ,
- (int)(now - login_start_time) / 60, cuser.nickname);
- else
- log_filef(FN_USIES, LOG_CREAT,
- "%s %s %-12s %s\n",
- Cdate(&now), mode, cuser.userid, mesg);
-
- /* °lÂÜ¨Ï¥ÎªÌ */
- if (HasUserPerm(PERM_LOGUSER))
- log_user("logout");
-}
-
-
-static void
-setflags(int mask, int value)
-{
- if (value)
- cuser.uflag |= mask;
- else
- cuser.uflag &= ~mask;
-}
-
-void
-u_exit(const char *mode)
-{
- int diff = (time(0) - login_start_time) / 60;
- int dirty = currmode & MODE_DIRTY;
-
- currmode = 0;
-
- /* close fd 0 & 1 to terminate network */
- close(0);
- close(1);
-
- assert(strncmp(currutmp->userid,cuser.userid, IDLEN)==0);
- if(strncmp(currutmp->userid,cuser.userid, IDLEN)!=0)
- return;
-
- reload_money();
- /*
- cuser.goodpost = currutmp->goodpost;
- cuser.badpost = currutmp->badpost;
- cuser.goodsale = currutmp->goodsale;
- cuser.badsale = currutmp->badsale;
- */
-
- auto_backup();
- setflags(PAGER_FLAG, currutmp->pager != PAGER_ON);
- setflags(CLOAK_FLAG, currutmp->invisible);
- save_brdbuf();
- brc_finalize();
-
- cuser.invisible = currutmp->invisible;
- cuser.withme = currutmp->withme;
- cuser.pager = currutmp->pager;
- memcpy(cuser.mind, currutmp->mind, 4);
- setutmpbid(0);
-
- if (!SHM->GV2.e.shutdown) {
- if (!(HasUserPerm(PERM_SYSOP) && HasUserPerm(PERM_SYSOPHIDE)) &&
- !currutmp->invisible)
- do_aloha("<<¤U¯¸³qª¾>> -- §Ú¨«Åo¡I");
- }
-
-
- if ((cuser.uflag != enter_uflag) || dirty || diff) {
- if (!diff && cuser.numlogins)
- cuser.numlogins = --cuser.numlogins;
- /* Leeym ¤W¯¸°±¯d®É¶¡­­¨î¦¡ */
- }
- passwd_update(usernum, &cuser);
- purge_utmp(currutmp);
- log_usies(mode, NULL);
-}
-
-void
-abort_bbs(int sig)
-{
- /* ignore normal signals */
- Signal(SIGALRM, SIG_IGN);
- Signal(SIGUSR1, SIG_IGN);
- Signal(SIGUSR2, SIG_IGN);
- Signal(SIGHUP, SIG_IGN);
- Signal(SIGTERM, SIG_IGN);
- Signal(SIGPIPE, SIG_IGN);
- if (currmode)
- u_exit("ABORTED");
- exit(0);
-}
-
-#ifdef GCC_NORETURN
-static void abort_bbs_debug(int sig) GCC_NORETURN;
-#endif
-
-/* NOTE: It's better to use signal-safe functions. Avoid to call
- * functions with global/static variable -- data may be corrupted */
-static void
-abort_bbs_debug(int sig)
-{
- int i;
- sigset_t sigset;
-
- switch(sig) {
- case SIGINT: STATINC(STAT_SIGINT); break;
- case SIGQUIT: STATINC(STAT_SIGQUIT); break;
- case SIGILL: STATINC(STAT_SIGILL); break;
- case SIGABRT: STATINC(STAT_SIGABRT); break;
- case SIGFPE: STATINC(STAT_SIGFPE); break;
- case SIGBUS: STATINC(STAT_SIGBUS); break;
- case SIGSEGV: STATINC(STAT_SIGSEGV); break;
- case SIGXCPU: STATINC(STAT_SIGXCPU); break;
- }
- /* ignore normal signals */
- Signal(SIGALRM, SIG_IGN);
- Signal(SIGUSR1, SIG_IGN);
- Signal(SIGUSR2, SIG_IGN);
- Signal(SIGHUP, SIG_IGN);
- Signal(SIGTERM, SIG_IGN);
- Signal(SIGPIPE, SIG_IGN);
-
- /* unblock */
- sigemptyset(&sigset);
- sigaddset(&sigset, SIGINT);
- sigaddset(&sigset, SIGQUIT);
- sigaddset(&sigset, SIGILL);
- sigaddset(&sigset, SIGABRT);
- sigaddset(&sigset, SIGFPE);
- sigaddset(&sigset, SIGBUS);
- sigaddset(&sigset, SIGSEGV);
- sigaddset(&sigset, SIGXCPU);
- sigprocmask(SIG_UNBLOCK, &sigset, NULL);
-
-#define CRASH_MSG ANSI_COLOR(0) \
- "\r\nµ{¦¡²§±`, ¥ß¨èÂ_½u. \r\n" \
- "½Ð¬¢ " GLOBAL_BUGREPORT " ªO¸Ô­z°ÝÃDµo¥Í¸g¹L¡C\r\n"
-
-#define XCPU_MSG ANSI_COLOR(0) \
- "\r\nµ{¦¡¯Ó¥Î¹L¦h­pºâ¸ê·½, ¥ß¨èÂ_½u¡C\r\n" \
- "¥i¯à¬O (a)°õ¦æ¤Ó¦h¯Ó¥Î¸ê·½ªº°Ê§@ ©Î (b)µ{¦¡±¼¤JµL½a°j°é. "\
- "½Ð¬¢ " GLOBAL_BUGREPORT " ªO¸Ô­z°ÝÃDµo¥Í¸g¹L¡C\r\n"
-
- if(sig==SIGXCPU)
- write(1, XCPU_MSG, sizeof(XCPU_MSG));
- else
- write(1, CRASH_MSG, sizeof(CRASH_MSG));
-
- /* close all file descriptors (including the network connection) */
- for (i = 0; i < 256; ++i)
- close(i);
-
- /* log */
- /* assume vsnprintf() in log_file() is signal-safe, is it? */
- log_filef("log/crash.log", LOG_CREAT,
- "%d %d %d %.12s\n", time4(NULL), getpid(), sig, cuser.userid);
-
- /* try logout... not a good idea, maybe crash again. now disabled */
- /*
- if (currmode) {
- currmode = 0;
- u_exit("AXXED");
- }
- */
-
-#ifdef DEBUGSLEEP
-
-#ifndef VALGRIND
- setproctitle("debug me!(%d)(%s,%d)", sig, cuser.userid, currstat);
-#endif
- /* do this manually to prevent broken stuff */
- /* will broken currutmp cause problems here? hope not... */
- if(currutmp && strncmp(cuser.userid, currutmp->userid, IDLEN) == EQUSTR)
- currutmp->mode = DEBUGSLEEPING;
-
- sleep(DEBUGSLEEP_SECONDS);
-#endif
-
- exit(0);
-}
-
-/* µn¿ý BBS µ{¦¡ */
-static void
-mysrand(void)
-{
- srandom(time(NULL) + getpid()); /* ®É¶¡¸ò pid ·í rand ªº seed */
-}
-
-void
-talk_request(int sig)
-{
- STATINC(STAT_TALKREQUEST);
- bell();
- bell();
- if (currutmp->msgcount) {
- char timebuf[100];
-
- syncnow();
- move(0, 0);
- clrtoeol();
- prints(ANSI_COLOR(33;41) "¡¹%s" ANSI_COLOR(34;47) " [%s] %s " ANSI_COLOR(0) "",
- SHM->uinfo[currutmp->destuip].userid, my_ctime(&now,timebuf,sizeof(timebuf)),
- (currutmp->sig == 2) ? "­«­n®ø®§¼s¼½¡I(½ÐCtrl-U,l¬d¬Ý¼ö°T°O¿ý)"
- : "©I¥s¡B©I¥s¡AÅ¥¨ì½Ð¦^µª");
- refresh();
- } else {
- unsigned char mode0 = currutmp->mode;
- char c0 = currutmp->chatid[0];
- screen_backup_t old_screen;
-
- currutmp->mode = 0;
- currutmp->chatid[0] = 1;
- scr_dump(&old_screen);
- talkreply();
- currutmp->mode = mode0;
- currutmp->chatid[0] = c0;
- scr_restore(&old_screen);
- }
-}
-
-void
-show_call_in(int save, int which)
-{
- char buf[200];
-#ifdef PLAY_ANGEL
- if (currutmp->msgs[which].msgmode == MSGMODE_TOANGEL)
- snprintf(buf, sizeof(buf), ANSI_COLOR(1;37;46) "¡¹%s" ANSI_COLOR(37;45) " %s " ANSI_RESET,
- currutmp->msgs[which].userid, currutmp->msgs[which].last_call_in);
- else
-#endif
- snprintf(buf, sizeof(buf), ANSI_COLOR(1;33;46) "¡¹%s" ANSI_COLOR(37;45) " %s " ANSI_RESET,
- currutmp->msgs[which].userid, currutmp->msgs[which].last_call_in);
- outmsg(buf);
-
- if (save) {
- char genbuf[200];
- if (!fp_writelog) {
- sethomefile(genbuf, cuser.userid, fn_writelog);
- fp_writelog = fopen(genbuf, "a");
- }
- if (fp_writelog) {
- fprintf(fp_writelog, "%s [%s]\n", buf, Cdatelite(&now));
- }
- }
-}
-
-static int
-add_history_water(water_t * w, const msgque_t * msg)
-{
- memcpy(&w->msg[w->top], msg, sizeof(msgque_t));
- w->top++;
- w->top %= WATERMODE(WATER_OFO) ? 5 : MAX_REVIEW;
-
- if (w->count < MAX_REVIEW)
- w->count++;
-
- return w->count;
-}
-
-static int
-add_history(const msgque_t * msg)
-{
- int i = 0, j, waterinit = 0;
- water_t *tmp;
- check_water_init();
- if (WATERMODE(WATER_ORIG) || WATERMODE(WATER_NEW))
- add_history_water(&water[0], msg);
- if (WATERMODE(WATER_NEW) || WATERMODE(WATER_OFO)) {
- for (i = 0; i < 5 && swater[i]; i++)
- if (swater[i]->pid == msg->pid
-#ifdef PLAY_ANGEL
- && swater[i]->msg[0].msgmode == msg->msgmode
- /* When throwing waterball to angel directly */
-#endif
- )
- break;
- if (i == 5) {
- waterinit = 1;
- i = 4;
- memset(swater[4], 0, sizeof(water_t));
- } else if (!swater[i]) {
- water_usies = i + 1;
- swater[i] = &water[i + 1];
- waterinit = 1;
- }
- tmp = swater[i];
-
- if (waterinit) {
- memcpy(swater[i]->userid, msg->userid, sizeof(swater[i]->userid));
- swater[i]->pid = msg->pid;
- }
- if (!swater[i]->uin)
- swater[i]->uin = currutmp;
-
- for (j = i; j > 0; j--)
- swater[j] = swater[j - 1];
- swater[0] = tmp;
- add_history_water(swater[0], msg);
- }
- if (WATERMODE(WATER_ORIG) || WATERMODE(WATER_NEW)) {
- if (watermode > 0 &&
- (water_which == swater[0] || water_which == &water[0])) {
- if (watermode < water_which->count)
- watermode++;
- t_display_new();
- }
- }
- return i;
-}
-
-void
-write_request(int sig)
-{
- int i, msgcount;
-
- STATINC(STAT_WRITEREQUEST);
-#ifdef NOKILLWATERBALL
- if( reentrant_write_request ) /* kill again by shmctl */
- return;
- reentrant_write_request = 1;
-#endif
- syncnow();
- check_water_init();
- if (WATERMODE(WATER_OFO)) {
- /* ¦pªG¥Ø«e¥¿¦b¦^¤ô²y¼Ò¦¡ªº¸Ü, ´N¤£¯à¶i¦æ add_history() ,
- ¦]¬°·|§ï¼g water[], ¦Ó¨Ï¦^¤ô²y¥ØªºÄê±¼, ©Ò¥H¤À¦¨´XºØ±¡ªp¦Ò¼{.
- sig != 0ªí¯uªº¦³¤ô²y¶i¨Ó, ¬GÅã¥Ü.
- sig == 0ªí¥Ü¨S¦³¤ô²y¶i¨Ó, ¤£¹L¤§«e©|¦³¤ô²yÁÙ¨S¼g¨ì water[].
- */
- static int alreadyshow = 0;
-
- if( sig ){ /* ¯uªº¦³¤ô²y¶i¨Ó */
-
- /* ­Y­ì¨Ó¥¿¦b REPLYING , «h§ï¦¨ RECVINREPLYING,
- ³o¼Ë¦b¦^¤ô²yµ²§ô«á, ·|¦A©I¥s¤@¦¸ write_request(0) */
- if( wmofo == REPLYING )
- wmofo = RECVINREPLYING;
-
- /* Åã¥Ü */
- for( ; alreadyshow < currutmp->msgcount && alreadyshow < MAX_MSGS
- ; ++alreadyshow ){
- bell();
- show_call_in(1, alreadyshow);
- refresh();
- }
- }
-
- /* ¬Ý¬Ý¬O¤£¬O­n§â currutmp->msg ®³¦^ water[] (by add_history())
- ¶·­n¬O¤£¦b¦^¤ô²y¤¤ (NOTREPLYING) */
- if( wmofo == NOTREPLYING &&
- (msgcount = currutmp->msgcount) > 0 ){
- for( i = 0 ; i < msgcount ; ++i )
- add_history(&currutmp->msgs[i]);
- if( (currutmp->msgcount -= msgcount) < 0 )
- currutmp->msgcount = 0;
- alreadyshow = 0;
- }
- } else {
- if (currutmp->mode != 0 &&
- currutmp->pager != PAGER_OFF &&
- cuser.userlevel != 0 &&
- currutmp->msgcount != 0 &&
- currutmp->mode != TALK &&
- currutmp->mode != EDITING &&
- currutmp->mode != CHATING &&
- currutmp->mode != PAGE &&
- currutmp->mode != IDLE &&
- currutmp->mode != MAILALL && currutmp->mode != MONITOR) {
- char c0 = currutmp->chatid[0];
- int currstat0 = currstat;
- unsigned char mode0 = currutmp->mode;
-
- currutmp->mode = 0;
- currutmp->chatid[0] = 2;
- currstat = HIT;
-
-#ifdef NOKILLWATERBALL
- currutmp->wbtime = 0;
-#endif
- if( (msgcount = currutmp->msgcount) > 0 ){
- for( i = 0 ; i < msgcount ; ++i ){
- bell();
- show_call_in(1, 0);
- add_history(&currutmp->msgs[0]);
-
- if( (--currutmp->msgcount) < 0 )
- i = msgcount; /* force to exit for() */
- else if( currutmp->msgcount > 0 )
- memmove(&currutmp->msgs[0],
- &currutmp->msgs[1],
- sizeof(msgque_t) * currutmp->msgcount);
- igetch();
- }
- }
-
- currutmp->chatid[0] = c0;
- currutmp->mode = mode0;
- currstat = currstat0;
- } else {
- bell();
- show_call_in(1, 0);
- add_history(&currutmp->msgs[0]);
-
- refresh();
- currutmp->msgcount = 0;
- }
- }
-#ifdef NOKILLWATERBALL
- reentrant_write_request = 0;
- currutmp->wbtime = 0; /* race */
-#endif
-}
-
-static userinfo_t*
-getotherlogin(int num)
-{
- userinfo_t *ui;
- do {
- if (!(ui = (userinfo_t *) search_ulistn(usernum, num)))
- return NULL; /* user isn't logged in */
-
- /* skip sleeping process, this is slow if lots */
- if(ui->mode == DEBUGSLEEPING)
- num++;
- else if(ui->pid <= 0)
- num++;
- else if(kill(ui->pid, 0) < 0)
- num++;
- else
- break;
- } while (1);
-
- return ui;
-}
-
-static void
-multi_user_check(void)
-{
- register userinfo_t *ui;
- char genbuf[3];
-
- if (HasUserPerm(PERM_SYSOP))
- return; /* don't check sysops */
-
- srandom(getpid());
- // race condition here, sleep may help..?
- if (cuser.userlevel) {
- usleep(random()%1000000); // 0~1s
- ui = getotherlogin(1);
- if(ui == NULL)
- return;
-
- getdata(b_lines - 1, 0, "±z·Q§R°£¨ä¥L­«½Æªº login ¶Ü¡H[Y/n] ",
- genbuf, 3, LCECHO);
-
- usleep(random()%1000000);
- if (genbuf[0] != 'n') {
- do {
- // scan again, old ui may be invalid
- ui = getotherlogin(1);
- if(ui==NULL)
- return;
- if (ui->pid > 0) {
- if(kill(ui->pid, SIGHUP)<0) {
- perror("kill SIGHUP fail");
- break;
- }
- log_usies("KICK ", cuser.nickname);
- } else {
- fprintf(stderr, "id=%s ui->pid=0\n", cuser.userid);
- }
- usleep(random()%2000000+1000000); // 1~3s
- } while(getotherlogin(3) != NULL);
- } else {
- /* deny login if still have 3 */
- if (getotherlogin(3) != NULL)
- abort_bbs(0); /* Goodbye(); */
- }
- } else {
- /* allow multiple guest user */
- if (search_ulistn(usernum, MAX_GUEST) != NULL) {
- vmsg("©êºp¡A¥Ø«e¤w¦³¤Ó¦h guest ¦b¯¸¤W, ½Ð¥Înewµù¥U¡C");
- exit(1);
- }
- }
-}
-
-/* bad login */
-static char * const str_badlogin = "logins.bad";
-
-static void
-logattempt(const char *uid, char type)
-{
- char fname[40];
- int fd, len;
- char genbuf[200];
-
- snprintf(genbuf, sizeof(genbuf), "%c%-12s[%s] %s@%s\n", type, uid,
- Cdate(&login_start_time), remoteusername, fromhost);
- len = strlen(genbuf);
- if ((fd = open(str_badlogin, O_WRONLY | O_CREAT | O_APPEND, 0644)) > 0) {
- write(fd, genbuf, len);
- close(fd);
- }
- if (type == '-') {
- snprintf(genbuf, sizeof(genbuf),
- "[%s] %s\n", Cdate(&login_start_time), fromhost);
- len = strlen(genbuf);
- sethomefile(fname, uid, str_badlogin);
- if ((fd = open(fname, O_WRONLY | O_CREAT | O_APPEND, 0644)) > 0) {
- write(fd, genbuf, len);
- close(fd);
- }
- }
-}
-
-void mkuserdir(const char *userid)
-{
- char genbuf[200];
- sethomepath(genbuf, userid);
- // assume it is a dir, so just check if it is exist
- if (access(genbuf, F_OK) != 0)
- mkdir(genbuf, 0755);
-}
-
-static void
-login_query(void)
-{
-#ifdef CONVERT
- /* uid ¥[¤@¦ì, for gb login */
- char uid[IDLEN + 2], passbuf[PASSLEN];
- int attempts, len;
-#else
- char uid[IDLEN + 1], passbuf[PASSLEN];
- int attempts;
-#endif
- resolve_garbage();
- now = time(0);
-
-#ifdef DEBUG
- move(1, 0);
- prints("debugging mode\ncurrent pid: %d\n", getpid());
-#else
- show_file("etc/Welcome", 1, -1, SHOWFILE_ALLOW_ALL);
-#endif
- // XXX why output("1", 1); here?
- // this output has been here since rev 1...
- // output("1", 1);
-
- attempts = 0;
- while (1) {
- if (attempts++ >= LOGINATTEMPTS) {
- more("etc/goodbye", NA);
- pressanykey();
- exit(1);
- }
- bzero(&cuser, sizeof(cuser));
-
-#ifdef DEBUG
- move(19, 0);
- prints("current pid: %d ", getpid());
-#endif
-
- if (getdata(20, 0, "½Ð¿é¤J¥N¸¹¡A©Î¥H[guest]°ÑÆ[¡A¥H[new]µù¥U: ",
- uid, sizeof(uid), DOECHO) < 1)
- {
- // got nothing
- outs("½Ð­«·s¿é¤J¡C\n");
- continue;
- }
-
-#ifdef CONVERT
- /* switch to gb mode if uid end with '.' */
- len = strlen(uid);
- if (uid[0] && uid[len - 1] == '.') {
- set_converting_type(CONV_GB);
- uid[len - 1] = 0;
- redrawwin();
- }
- else if (uid[0] && uid[len - 1] == ',') {
- set_converting_type(CONV_UTF8);
- uid[len - 1] = 0;
- redrawwin();
- }
- else if (len >= IDLEN + 1)
- uid[IDLEN] = 0;
-#endif
-
- if (strcasecmp(uid, str_new) == 0) {
-#ifdef LOGINASNEW
- new_register();
- mkuserdir(cuser.userid);
- reginit_fav();
- break;
-#else
- outs("¥»¨t²Î¥Ø«eµLªk¥H new µù¥U, ½Ð¥Î guest ¶i¤J\n");
- continue;
-#endif
- } else if (!is_validuserid(uid)) {
-
- outs(err_uid);
-
- } else if (strcasecmp(uid, STR_GUEST) == 0) { /* guest */
-
- if (initcuser(uid)< 1) exit (0) ;
- cuser.userlevel = 0;
- cuser.uflag = PAGER_FLAG | BRDSORT_FLAG | MOVIE_FLAG;
- cuser.uflag2= 0; // we don't need FAVNEW_FLAG or anything else.
-
-#ifdef GUEST_DEFAULT_DBCS_NOINTRESC
- cuser.uflag |= DBCS_NOINTRESC;
-#endif
- // can we prevent mkuserdir() here?
- mkuserdir(cuser.userid);
- break;
-
- } else {
-
- /* normal user */
- getdata(21, 0, MSG_PASSWD,
- passbuf, sizeof(passbuf), NOECHO);
- passbuf[8] = '\0';
-
- move (22, 0); clrtoeol();
- outs("¥¿¦bÀˬd±K½X...");
- move(22, 0); refresh();
- /* prepare for later */
- clrtoeol();
-
- if( initcuser(uid) < 1 || !cuser.userid[0] ||
- !checkpasswd(cuser.passwd, passbuf) ){
-
- if(is_validuserid(cuser.userid))
- logattempt(cuser.userid , '-');
- outs(ERR_PASSWD);
-
- } else {
-
- logattempt(cuser.userid, ' ');
- outs("±K½X¥¿½T¡I ¶}©lµn¤J¨t²Î...");
- move(22, 0); refresh();
- clrtoeol();
-
- if (strcasecmp(str_sysop, cuser.userid) == 0){
-#ifdef NO_SYSOP_ACCOUNT
- exit(0);
-#else /* ¦Û°Ê¥[¤W¦U­Ó¥D­nÅv­­ */
- cuser.userlevel = PERM_BASIC | PERM_CHAT | PERM_PAGE |
- PERM_POST | PERM_LOGINOK | PERM_MAILLIMIT |
- PERM_CLOAK | PERM_SEECLOAK | PERM_XEMPT |
- PERM_SYSOPHIDE | PERM_BM | PERM_ACCOUNTS |
- PERM_CHATROOM | PERM_BOARD | PERM_SYSOP | PERM_BBSADM;
-#endif
- }
- /* ¦­¸Ó¦³ home ¤F, ¤£ª¾¹D¬°¦ó¦³ªº±b¸¹·|¨S¦³, ³Q¬å±¼¤F? */
- mkuserdir(cuser.userid);
- break;
- }
- }
- }
- multi_user_check();
-#ifdef DETECT_CLIENT
- {
- int fd = open("log/client_code",O_WRONLY | O_CREAT | O_APPEND, 0644);
- if(fd>=0) {
- write(fd, &client_code, sizeof(client_code));
- close(fd);
- }
- }
-#endif
-}
-
-void
-add_distinct(const char *fname, const char *line)
-{
- FILE *fp;
- int n = 0;
-
- if ((fp = fopen(fname, "a+"))) {
- char buffer[80];
- char tmpname[100];
- FILE *fptmp;
-
- strlcpy(tmpname, fname, sizeof(tmpname));
- strcat(tmpname, "_tmp");
- if (!(fptmp = fopen(tmpname, "w"))) {
- fclose(fp);
- return;
- }
- rewind(fp);
- while (fgets(buffer, 80, fp)) {
- char *p = buffer + strlen(buffer) - 1;
-
- if (p[-1] == '\n' || p[-1] == '\r')
- p[-1] = 0;
- if (!strcmp(buffer, line))
- break;
- sscanf(buffer + strlen(buffer) + 2, "%d", &n);
- fprintf(fptmp, "%s%c#%d\n", buffer, 0, n);
- }
-
- if (feof(fp))
- fprintf(fptmp, "%s%c#1\n", line, 0);
- else {
- sscanf(buffer + strlen(buffer) + 2, "%d", &n);
- fprintf(fptmp, "%s%c#%d\n", buffer, 0, n + 1);
- while (fgets(buffer, 80, fp)) {
- sscanf(buffer + strlen(buffer) + 2, "%d", &n);
- fprintf(fptmp, "%s%c#%d\n", buffer, 0, n);
- }
- }
- fclose(fp);
- fclose(fptmp);
- rename(tmpname, fname);
- }
-}
-
-void
-del_distinct(const char *fname, const char *line, int casesensitive)
-{
- FILE *fp;
- int n = 0;
-
- if ((fp = fopen(fname, "r"))) {
- char buffer[80];
- char tmpname[100];
- FILE *fptmp;
-
- strlcpy(tmpname, fname, sizeof(tmpname));
- strcat(tmpname, "_tmp");
- if (!(fptmp = fopen(tmpname, "w"))) {
- fclose(fp);
- return;
- }
- rewind(fp);
- while (fgets(buffer, 80, fp)) {
- char *p = buffer + strlen(buffer) - 1;
-
- if (p[-1] == '\n' || p[-1] == '\r')
- p[-1] = 0;
- if(casesensitive)
- {
- if (!strcmp(buffer, line))
- break;
- } else {
- if (!strcasecmp(buffer, line))
- break;
- }
- sscanf(buffer + strlen(buffer) + 2, "%d", &n);
- fprintf(fptmp, "%s%c#%d\n", buffer, 0, n);
- }
-
- if (!feof(fp))
- while (fgets(buffer, 80, fp)) {
- sscanf(buffer + strlen(buffer) + 2, "%d", &n);
- fprintf(fptmp, "%s%c#%d\n", buffer, 0, n);
- }
- fclose(fp);
- fclose(fptmp);
- rename(tmpname, fname);
- }
-}
-
-#ifdef WHERE
-static int
-where(const char *from)
-{
- int i;
-
- for (i = 0; i < SHM->home_num; i++) {
- if ((SHM->home_ip[i] & SHM->home_mask[i]) == (ipstr2int(from) & SHM->home_mask[i])) {
- return i;
- }
- }
- return 0;
-}
-#endif
-
-static void
-check_BM(void)
-{
- /* XXX: -_- */
- int i;
-
- cuser.userlevel &= ~PERM_BM;
- for( i = 0 ; i < numboards ; ++i )
- if( is_BM_cache(i + 1) ) /* XXXbid */
- return;
- //for (i = 0, bhdr = bcache; i < numboards && !is_BM(bhdr->BM); i++, bhdr++);
-}
-
-static void
-setup_utmp(int mode)
-{
- /* NOTE, ¦b getnewutmpent ¤§«e¤£À³¸Ó¦³¥ô¦ó slow/blocking function */
- userinfo_t uinfo;
- memset(&uinfo, 0, sizeof(uinfo));
- uinfo.pid = currpid = getpid();
- uinfo.uid = usernum;
- uinfo.mode = currstat = mode;
-
- uinfo.userlevel = cuser.userlevel;
- uinfo.sex = cuser.sex % 8;
- uinfo.lastact = time(NULL);
- strlcpy(uinfo.userid, cuser.userid, sizeof(uinfo.userid));
- //strlcpy(uinfo.realname, cuser.realname, sizeof(uinfo.realname));
- strlcpy(uinfo.nickname, cuser.nickname, sizeof(uinfo.nickname));
- strip_nonebig5((unsigned char *)uinfo.nickname, sizeof(uinfo.nickname));
- strlcpy(uinfo.from, fromhost, sizeof(uinfo.from));
- uinfo.five_win = cuser.five_win;
- uinfo.five_lose = cuser.five_lose;
- uinfo.five_tie = cuser.five_tie;
- uinfo.chc_win = cuser.chc_win;
- uinfo.chc_lose = cuser.chc_lose;
- uinfo.chc_tie = cuser.chc_tie;
- uinfo.chess_elo_rating = cuser.chess_elo_rating;
- uinfo.go_win = cuser.go_win;
- uinfo.go_lose = cuser.go_lose;
- uinfo.go_tie = cuser.go_tie;
- uinfo.invisible = cuser.invisible % 2;
- uinfo.pager = cuser.pager % PAGER_MODES;
- /*
- uinfo.goodpost = cuser.goodpost;
- uinfo.badpost = cuser.badpost;
- uinfo.goodsale = cuser.goodsale;
- uinfo.badsale = cuser.badsale;
- */
- if(cuser.withme & (cuser.withme<<1) & (WITHME_ALLFLAG<<1))
- cuser.withme = 0; /* unset all if contradict */
- uinfo.withme = cuser.withme & ~WITHME_ALLFLAG;
- memcpy(uinfo.mind, cuser.mind, 4);
- strip_nonebig5((unsigned char *)uinfo.mind, 4);
-#ifdef WHERE
- uinfo.from_alias = where(fromhost);
-#endif
-#ifndef FAST_LOGIN
- setuserfile(buf, "remoteuser");
-
- strlcpy(remotebuf, fromhost, sizeof(fromhost));
- strcat(remotebuf, ctime4(&now));
- chomp(remotebuf);
- add_distinct(buf, remotebuf);
-#endif
- if (enter_uflag & CLOAK_FLAG)
- uinfo.invisible = YEA;
-
-#ifdef PLAY_ANGEL
- if (REJECT_QUESTION)
- uinfo.angel = 1;
- uinfo.angel |= ANGEL_STATUS() << 1;
-#endif
-
- getnewutmpent(&uinfo);
- currmode = MODE_STARTED;
- SHM->UTMPneedsort = 1;
- // XXX ¤£¥Î¨C 20 ¤~Àˬd§a
- if (!(cuser.numlogins % 20) && cuser.userlevel & PERM_BM)
- check_BM(); /* Ptt ¦Û°Ê¨ú¤UÂ÷¾ªO¥DÅv¤O */
-
-#ifndef _BBS_UTIL_C_
- /* Very, very slow friend_load. */
- if( strcmp(cuser.userid, STR_GUEST) != 0 ) // guest ¤£³B²z¦n¤Í
- friend_load(0);
- nice(3);
-#endif
-}
-
-inline static void welcome_msg(void)
-{
- prints(ANSI_RESET " Åwªï±z²Ä "
- ANSI_COLOR(1;33) "%d" ANSI_COLOR(0;37) " «×«ô³X¥»¯¸¡A¤W¦¸±z¬O±q "
- ANSI_COLOR(1;33) "%s" ANSI_COLOR(0;37) " ³s©¹¥»¯¸¡A"
- ANSI_CLRTOEND "\n"
- " §Ú°O±o¨º¤Ñ¬O " ANSI_COLOR(1;33) "%s" ANSI_COLOR(0;37) "¡C"
- ANSI_CLRTOEND "\n"
- ANSI_CLRTOEND "\n"
- ,
- ++cuser.numlogins, cuser.lasthost, Cdate(&(cuser.lastlogin)));
- pressanykey();
-}
-
-inline static void check_bad_login(void)
-{
- char genbuf[200];
- setuserfile(genbuf, str_badlogin);
- if (more(genbuf, NA) != -1) {
- move(b_lines - 3, 0);
- outs("³q±`¨Ã¨S¦³¿ìªkª¾¹D¸Óip¬O½Ö©Ò¦³, "
- "¥H¤Î¨ä·N¹Ï(¬O¤£¤p¤ß«ö¿ù©Î¦³·N´ú±z±K½X)\n"
- "­Y±z¦³±b¸¹³Qµs¥ÎºÃ¼{, ½Ð¸g±`§ó§ï±zªº±K½X©Î¨Ï¥Î¥[±K³s½u");
- if (getans("±z­n§R°£¥H¤W¿ù»~¹Á¸Õªº°O¿ý¶Ü? [y/N] ") == 'y')
- unlink(genbuf);
- }
-}
-
-inline static void birthday_make_a_wish(const struct tm *ptime, const struct tm *tmp)
-{
- if (tmp->tm_mday != ptime->tm_mday) {
- more("etc/birth.post", YEA);
- if (enter_board("WhoAmI")==0) {
- do_post();
- }
- }
-}
-
-inline static void record_lasthost(const char *fromhost)
-{
- strlcpy(cuser.lasthost, fromhost, sizeof(cuser.lasthost));
-}
-
-inline static void check_mailbox_quota(void)
-{
- if (chkmailbox())
- m_read();
-}
-
-static void init_guest_info(void)
-{
- int i;
- char *nick[13] = {
- "·¦¤l", "¨©´ß", "¤º¦ç", "Ä_¯S²~", "½¨®³½",
- "¾ð¸­", "¯BµÓ", "¾c¤l", "¼ç¤ô¸¥", "Å]¤ý",
- "ÅKÅø", "¦Ò¨÷", "¤j¬ü¤k"
- };
- char *name[13] = {
- "¤j¤ý·¦¤l", "ÆxÄMÁ³", "¤ñ°ò¥§", "¥i¤f¥i¼Ö", "¥õªaªº³½",
- "¾Ð", "°ª©£«Î", "AIR Jordon", "¬õ¦â¤Q¤ë¸¹", "§å½ð½ð",
- "SASAYA·¦¥¤", "Àn³J", "¥¬¾|§J÷«³½­»µ·"
- };
- char *addr[13] = {
- "¤Ñ°ó¼Ö¶é", "¤j®ü", "ºñ®q¤p©]¦±", "¬ü°ê", "ºñ¦â¬À·äÁG",
- "»·¤è", "­ì¥»®ü", "NIKE", "ĬÁp", "¨k¤K618«Ç",
- "·R¤§¨ý", "¤Ñ¤W", "ÂŦâ¬À·äÁG"
- };
- i = login_start_time % 13;
- snprintf(cuser.nickname, sizeof(cuser.nickname),
- "®üÃäº}¨Óªº%s", nick[(int)i]);
- strlcpy(currutmp->nickname, cuser.nickname,
- sizeof(currutmp->nickname));
- strlcpy(cuser.realname, name[(int)i], sizeof(cuser.realname));
- strlcpy(cuser.address, addr[(int)i], sizeof(cuser.address));
- cuser.sex = i % 8;
- currutmp->pager = PAGER_DISABLE;
-}
-
-#if FOREIGN_REG_DAY > 0
-inline static void foreign_warning(void){
- if ((cuser.uflag2 & FOREIGN) && !(cuser.uflag2 & LIVERIGHT)){
- if (login_start_time - cuser.firstlogin > (FOREIGN_REG_DAY - 5) * 24 * 3600){
- mail_muser(cuser, "[¥X¤J¹ÒºÞ²z§½]", "etc/foreign_expired_warn");
- }
- else if (login_start_time - cuser.firstlogin > FOREIGN_REG_DAY * 24 * 3600){
- cuser.userlevel &= ~(PERM_LOGINOK | PERM_POST);
- vmsg("ĵ§i¡G½Ð¦Ü¥X¤J¹ÒºÞ²z§½¥Ó½Ð¥Ã¤[©~¯d");
- }
- }
-}
-#endif
-
-
-static void
-user_login(void)
-{
- struct tm ptime, lasttime;
- int nowusers, ifbirth = 0, i;
-
- /* NOTE! ¦b setup_utmp ¤§«e, ¤£À³¸Ó¦³¥ô¦ó blocking/slow function,
- * §_«h¥iÂǾ÷ race condition ¹F¨ì multi-login */
-
- /* get local time */
- ptime = *localtime4(&now);
-
- /* ªì©l¤Æ: random number ¼W¥[user¸ò®É¶¡ªº®t²§ */
- mysrand();
-
- log_usies("ENTER", fromhost);
-#ifndef VALGRIND
- setproctitle("%s: %s", margs, cuser.userid);
-#endif
- resolve_fcache();
- /* resolve_boards(); */
- numboards = SHM->Bnumber;
-
- if(getenv("SSH_CLIENT") != NULL){
- struct sockaddr_in xsin;
- char frombuf[50];
- sscanf(getenv("SSH_CLIENT"), "%s", frombuf);
- xsin.sin_family = AF_INET;
- xsin.sin_port = htons(23);
- if (strrchr(frombuf, ':'))
- inet_pton(AF_INET, strrchr(frombuf, ':') + 1, &xsin.sin_addr);
- else
- inet_pton(AF_INET, frombuf, &xsin.sin_addr);
- getremotename(&xsin, fromhost, remoteusername); /* RFC931 */
- }
-
- /* ªì©l¤Æ uinfo¡Bflag¡Bmode */
- setup_utmp(LOGIN);
- enter_uflag = cuser.uflag;
- lasttime = *localtime4(&cuser.lastlogin);
- redrawwin();
-
- /* show welcome_login */
- if( (ifbirth = (ptime.tm_mday == cuser.day &&
- ptime.tm_mon + 1 == cuser.month)) ){
- char buf[PATHLEN];
- snprintf(buf, sizeof(buf), "etc/Welcome_birth.%d", getHoroscope(cuser.month, cuser.day));
- more(buf, NA);
- }
- else {
-#ifndef MULTI_WELCOME_LOGIN
- more("etc/Welcome_login", NA);
-#else
- if( SHM->GV2.e.nWelcomes ){
- char buf[80];
- snprintf(buf, sizeof(buf), "etc/Welcome_login.%d",
- (int)login_start_time % SHM->GV2.e.nWelcomes);
- more(buf, NA);
- }
-#endif
- }
- refresh();
- currutmp->alerts |= load_mailalert(cuser.userid);
-
- if ((nowusers = SHM->UTMPnumber) > SHM->max_user) {
- SHM->max_user = nowusers;
- SHM->max_time = now;
- }
-
- if (!(HasUserPerm(PERM_SYSOP) && HasUserPerm(PERM_SYSOPHIDE)) &&
- !currutmp->invisible)
- {
- /* do_aloha is costly. do it later? */
- do_aloha("<<¤W¯¸³qª¾>> -- §Ú¨Ó°Õ¡I");
- }
-
- if (SHM->loginmsg.pid){
- if(search_ulist_pid(SHM->loginmsg.pid))
- getmessage(SHM->loginmsg);
- else
- SHM->loginmsg.pid=0;
- }
-
- if (cuser.userlevel) { /* not guest */
- move(t_lines - 4, 0);
- clrtobot();
- welcome_msg();
- resolve_over18();
-
- if( ifbirth ){
- birthday_make_a_wish(&ptime, &lasttime);
- if( getans("¬O§_­nÅã¥Ü¡u¹Ø¬P¡v©ó¨Ï¥ÎªÌ¦W³æ¤W¡H(y/N)") == 'y' )
- currutmp->birth = 1;
- }
- check_bad_login();
- check_mailbox_quota();
- check_register();
- record_lasthost(fromhost);
- restore_backup();
-
- } else if (strcmp(cuser.userid, STR_GUEST) == 0) { /* guest */
-
- init_guest_info();
-#if 0 // def DBCSAWARE
- u_detectDBCSAwareEvilClient();
-#else
- pressanykey();
-#endif
- } else {
- // XXX no userlevel, no guest - what is this?
- // clear();
- // outs("¦¹±b¸¹°±Åv¤¤");
- // pressanykey();
- // exit(1);
-
- check_mailbox_quota();
- }
-
- if(ptime.tm_yday!=lasttime.tm_yday)
- STATINC(STAT_TODAYLOGIN_MAX);
-
- if (!PERM_HIDE(currutmp)) {
- /* If you wanna do incremental upgrade
- * (like, added a function/flag that wants user to confirm againe)
- * put it here.
- */
-
-#if defined(DBCSAWARE) && defined(DBCSAWARE_UPGRADE_STARTTIME)
- // define the real time you upgraded in your pttbbs.conf
- if(cuser.lastlogin < DBCSAWARE_UPGRADE_STARTTIME)
- {
- if (u_detectDBCSAwareEvilClient())
- cuser.uflag &= ~DBCSAWARE_FLAG;
- else
- cuser.uflag |= DBCSAWARE_FLAG;
- }
-#endif
- /* login time update */
-
- if(ptime.tm_yday!=lasttime.tm_yday)
- STATINC(STAT_TODAYLOGIN_MIN);
-
-
- cuser.lastlogin = login_start_time;
-
- }
-
-#if FOREIGN_REG_DAY > 0
- foreign_warning();
-#endif
-
- passwd_update(usernum, &cuser);
-
- if(cuser.uflag2 & FAVNEW_FLAG) {
- fav_load();
- if (get_fav_root() != NULL) {
- int num;
- num = updatenewfav(1);
- if (num > NEW_FAV_THRESHOLD &&
- getans("§ä¨ì %d ­Ó·s¬ÝªO¡A½T©w­n¥[¤J§Úªº³Ì·R¶Ü¡H[Y/n]", num) == 'n') {
- fav_free();
- fav_load();
- }
- }
- }
-
- for (i = 0; i < NUMVIEWFILE; i++)
- if ((cuser.loginview >> i) & 1)
- more(loginview_file[(int)i][0], YEA);
-}
-
-static void
-do_aloha(const char *hello)
-{
- FILE *fp;
- char userid[80];
- char genbuf[200];
-
- setuserfile(genbuf, "aloha");
- if ((fp = fopen(genbuf, "r"))) {
- while (fgets(userid, 80, fp)) {
- userinfo_t *uentp;
- if ((uentp = (userinfo_t *) search_ulist_userid(userid)) &&
- isvisible(uentp, currutmp)) {
- my_write(uentp->pid, hello, uentp->userid, WATERBALL_ALOHA, uentp);
- }
- }
- fclose(fp);
- }
-}
-
-static void
-do_term_init(void)
-{
- term_init();
- initscr();
- if(use_shell_login_mode)
- raise(SIGWINCH);
-}
-
-inline static void
-start_client(void)
-{
-#ifdef CPULIMIT
- struct rlimit rml;
- rml.rlim_cur = CPULIMIT * 60 - 5;
- rml.rlim_max = CPULIMIT * 60;
- setrlimit(RLIMIT_CPU, &rml);
-#endif
-
- STATINC(STAT_LOGIN);
- /* system init */
- nice(2); /* Ptt: lower priority */
- login_start_time = time(0);
- currmode = 0;
-
- Signal(SIGHUP, abort_bbs);
- Signal(SIGTERM, abort_bbs);
- Signal(SIGPIPE, abort_bbs);
-
- Signal(SIGINT, abort_bbs_debug);
- Signal(SIGQUIT, abort_bbs_debug);
- Signal(SIGILL, abort_bbs_debug);
- Signal(SIGABRT, abort_bbs_debug);
- Signal(SIGFPE, abort_bbs_debug);
- Signal(SIGBUS, abort_bbs_debug);
- Signal(SIGSEGV, abort_bbs_debug);
- Signal(SIGXCPU, abort_bbs_debug);
-
- signal_restart(SIGUSR1, talk_request);
- signal_restart(SIGUSR2, write_request);
-
- dup2(0, 1);
-
- do_term_init();
- Signal(SIGALRM, abort_bbs);
- alarm(600);
-
- login_query(); /* Ptt ¥[¤Wlogin time out */
- m_init(); /* init the user mail path */
- user_login();
- auto_close_polls(); /* ¦Û°Ê¶}²¼ */
-
- Signal(SIGALRM, SIG_IGN);
- main_menu();
-}
-
-/* ¨ú±o remote user name ¥H§P©w¨­¥÷ */
-/*
- * rfc931() speaks a common subset of the RFC 931, AUTH, TAP, IDENT and RFC
- * 1413 protocols. It queries an RFC 931 etc. compatible daemon on a remote
- * host to look up the owner of a connection. The information should not be
- * used for authentication purposes. This routine intercepts alarm signals.
- *
- * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
- */
-
-#define RFC931_TIMEOUT 10
-#define RFC931_PORT 113 /* Semi-well-known port */
-#define ANY_PORT 0 /* Any old port will do */
-
-#if 0
-/* timeout - handle timeouts */
-static void
-timeout(int sig)
-{
- longjmp(byebye, sig);
-}
-#endif
-
-static void
-getremotename(const struct sockaddr_in * from, char *rhost, char *rname)
-{
-
- /* get remote host name */
-
-#ifdef FAST_LOGIN
- XAUTH_HOST(strcpy(rhost, (char *)inet_ntoa(from->sin_addr)));
-#else
- struct sockaddr_in our_sin;
- struct sockaddr_in rmt_sin;
- unsigned rmt_port, rmt_pt;
- unsigned our_port, our_pt;
- FILE *fp;
- char buffer[512], user[80], *cp;
- int s;
- static struct hostent *hp;
-
-
- hp = NULL;
- if (setjmp(byebye) == 0) {
- Signal(SIGALRM, timeout);
- alarm(3);
- hp = gethostbyaddr((char *)&from->sin_addr, sizeof(struct in_addr),
- from->sin_family);
- alarm(0);
- }
- strcpy(rhost, hp ? hp->h_name : (char *)inet_ntoa(from->sin_addr));
-
- /*
- * Use one unbuffered stdio stream for writing to and for reading from
- * the RFC931 etc. server. This is done because of a bug in the SunOS
- * 4.1.x stdio library. The bug may live in other stdio implementations,
- * too. When we use a single, buffered, bidirectional stdio stream ("r+"
- * or "w+" mode) we read our own output. Such behaviour would make sense
- * with resources that support random-access operations, but not with
- * sockets.
- */
-
- s = sizeof(our_sin);
- if (getsockname(0, (struct sockaddr *) & our_sin, &s) < 0)
- return;
-
- if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
- return;
-
- if (!(fp = fdopen(s, "r+"))) {
- close(s);
- return;
- }
- /* Set up a timer so we won't get stuck while waiting for the server. */
- if (setjmp(byebye) == 0) {
- Signal(SIGALRM, timeout);
- alarm(RFC931_TIMEOUT);
-
- /*
- * Bind the local and remote ends of the query socket to the same IP
- * addresses as the connection under investigation. We go through all
- * this trouble because the local or remote system might have more
- * than one network address. The RFC931 etc. client sends only port
- * numbers; the server takes the IP addresses from the query socket.
- */
- our_pt = ntohs(our_sin.sin_port);
- our_sin.sin_port = htons(ANY_PORT);
-
- rmt_sin = *from;
- rmt_pt = ntohs(rmt_sin.sin_port);
- rmt_sin.sin_port = htons(RFC931_PORT);
-
- setbuf(fp, (char *)0);
- s = fileno(fp);
-
- if (bind(s, (struct sockaddr *) & our_sin, sizeof(our_sin)) >= 0 &&
- connect(s, (struct sockaddr *) & rmt_sin, sizeof(rmt_sin)) >= 0) {
- /*
- * Send query to server. Neglect the risk that a 13-byte write
- * would have to be fragmented by the local system and cause
- * trouble with buggy System V stdio libraries.
- */
- fprintf(fp, "%u,%u\r\n", rmt_pt, our_pt);
- fflush(fp);
- /*
- * Read response from server. Use fgets()/sscanf() so we can work
- * around System V stdio libraries that incorrectly assume EOF
- * when a read from a socket returns less than requested.
- */
- if (fgets(buffer, sizeof(buffer), fp) && !ferror(fp)
- && !feof(fp)
- && sscanf(buffer, "%u , %u : USERID :%*[^:]:%79s", &rmt_port,
- &our_port, user) == 3 && rmt_pt == rmt_port
- && our_pt == our_port) {
-
- /*
- * Strip trailing carriage return. It is part of the
- * protocol, not part of the data.
- */
- if ((cp = (char *)strchr(user, '\r')))
- *cp = 0;
- strlcpy(rname, user, sizeof(user));
- }
- }
- alarm(0);
- }
- fclose(fp);
-#endif
-}
-
-static int
-bind_port(int port)
-{
- int sock, on, sz;
- struct linger lin;
- struct sockaddr_in xsin;
-
- sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-
- on = 1;
- setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));
- setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&on, sizeof(on));
-
- lin.l_onoff = 0;
- setsockopt(sock, SOL_SOCKET, SO_LINGER, &lin, sizeof(lin));
-
- sz = 1024;
- setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void*)&sz, sizeof(sz));
- sz = 4096;
- setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (void*)&sz, sizeof(sz));
-
- OPTIMIZE_LISTEN_SOCKET(sock, sz);
-
- xsin.sin_family = AF_INET;
- xsin.sin_addr.s_addr = htonl(INADDR_ANY);
- xsin.sin_port = htons(port);
- if (bind(sock, (struct sockaddr *) & xsin, sizeof xsin) < 0) {
- syslog(LOG_INFO, "bbsd bind_port can't bind to %d", port);
- exit(1);
- }
- if (listen(sock, SOCKET_QLEN) < 0) {
- syslog(LOG_INFO, "bbsd bind_port can't listen to %d", port);
- exit(1);
- }
- return sock;
-}
-
-
-/*******************************************************/
-
-
-static int shell_login(int argc, char *argv[], char *envp[]);
-static int daemon_login(int argc, char *argv[], char *envp[]);
-static int check_ban_and_load(int fd);
-static int check_banip(char *host);
-
-int
-main(int argc, char *argv[], char *envp[])
-{
- start_time = time(NULL);
-
- /* avoid SIGPIPE */
- Signal(SIGPIPE, SIG_IGN);
-
- /* avoid erroneous signal from other mbbsd */
- Signal(SIGUSR1, SIG_IGN);
- Signal(SIGUSR2, SIG_IGN);
-
-#if defined(__GLIBC__) && defined(CRITICAL_MEMORY)
- #define MY__MMAP_THRESHOLD (1024 * 8)
- #define MY__MMAP_MAX (0)
- #define MY__TRIM_THRESHOLD (1024 * 8)
- #define MY__TOP_PAD (0)
-
- mallopt (M_MMAP_THRESHOLD, MY__MMAP_THRESHOLD);
- mallopt (M_MMAP_MAX, MY__MMAP_MAX);
- mallopt (M_TRIM_THRESHOLD, MY__TRIM_THRESHOLD);
- mallopt (M_TOP_PAD, MY__TOP_PAD);
-#endif
-
- attach_SHM();
- if( (argc == 3 && shell_login(argc, argv, envp)) ||
- (argc != 3 && daemon_login(argc, argv, envp)) )
- start_client();
-
- return 0;
-}
-
-static int
-shell_login(int argc, char *argv[], char *envp[])
-{
- int fd;
-
- STATINC(STAT_SHELLLOGIN);
- /* Give up root privileges: no way back from here */
- setgid(BBSGID);
- setuid(BBSUID);
- chdir(BBSHOME);
-
-#if defined(linux) && defined(DEBUG)
-// mtrace();
-#endif
-
- use_shell_login_mode = 1;
- initsetproctitle(argc, argv, envp);
-
- snprintf(margs, sizeof(margs), "%s ssh ", argv[0]);
- /*
- * copy fromindent: Standard input:1138: Error:Unexpected end of file the
- * original "bbs"
- */
- if (argc > 1) {
- strcpy(fromhost, argv[1]);
- if (argc > 3)
- strlcpy(remoteusername, argv[3], sizeof(remoteusername));
- }
- close(2);
- /* don't close fd 1, at least init_tty need it */
- if( ((fd = open("log/stderr", O_WRONLY | O_CREAT | O_APPEND, 0644)) >= 0) && fd != 2 ){
- dup2(fd, 2);
- close(fd);
- }
-
- init_tty();
- if (check_ban_and_load(0)) {
- sleep(10);
- return 0;
- }
-#ifdef DETECT_CLIENT
- FNV1A_CHAR(123, client_code);
-#endif
- return 1;
-}
-
-static int
-daemon_login(int argc, char *argv[], char *envp[])
-{
- int msock, csock; /* socket for Master and Child */
- FILE *fp;
- int len_of_sock_addr, overloading = 0, i;
- char buf[256];
-#if OVERLOADBLOCKFDS
- int blockfd[OVERLOADBLOCKFDS];
- int nblocked = 0;
-#endif
- struct sockaddr_in xsin;
- xsin.sin_family = AF_INET;
-
- /* setup standalone */
- start_daemon();
- signal_restart(SIGCHLD, reapchild);
-
- /* choose port */
- if( argc < 2 )
- listen_port = 3006;
- else{
-#ifdef NO_FORK
- listen_port = atoi(argv[1]);
-#else
- for( i = 1 ; i < (argc - 1) ; ++i )
- switch( fork() ){
- case -1:
- perror("fork()");
- break;
- case 0:
- goto out;
- default:
- break;
- }
- out:
- listen_port = atoi(argv[i]);
-#endif
- }
-
- /* port binding */
- if( (msock = bind_port(listen_port)) < 0 ){
- syslog(LOG_INFO, "mbbsd bind_port failed.\n");
- exit(1);
- }
-
- /* Give up root privileges: no way back from here */
- setgid(BBSGID);
- setuid(BBSUID);
- chdir(BBSHOME);
-
- /* proctitle */
- initsetproctitle(argc, argv, envp);
-#ifndef VALGRIND
- snprintf(margs, sizeof(margs), "%s %d ", argv[0], listen_port);
- setproctitle("%s: listening ", margs);
-#endif
-
- /* It's better to do something before fork */
-#ifdef CONVERT
- big2gb_init(NULL);
- gb2big_init(NULL);
- big2uni_init(NULL);
- uni2big_init(NULL);
-#endif
-
-#ifndef NO_FORK
-#ifdef PRE_FORK
- if( listen_port == 23 ){ // only pre-fork in port 23
- for( i = 0 ; i < PRE_FORK ; ++i )
- if( fork() <= 0 )
- break;
- }
-#endif
-#endif
-
- snprintf(buf, sizeof(buf),
- "run/mbbsd.%d.%d.pid", listen_port, (int)getpid());
- if ((fp = fopen(buf, "w"))) {
- fprintf(fp, "%d\n", (int)getpid());
- fclose(fp);
- }
-
- /* main loop */
- while( 1 ){
- len_of_sock_addr = sizeof(xsin);
- if(
-#if defined(Solaris) && __OS_MAJOR_VERSION__ == 5 && __OS_MINOR_VERSION__ < 7
- (csock = accept(msock, (struct sockaddr *)&xsin,
- &len_of_sock_addr)) < 0
-#else
- (csock = accept(msock, (struct sockaddr *)&xsin,
- (socklen_t *)&len_of_sock_addr)) < 0
-#endif
- ) {
- if (errno != EINTR)
- sleep(1);
- continue;
- }
-
- XAUTH_TRYREMOTENAME();
-
- overloading = check_ban_and_load(csock);
-#if OVERLOADBLOCKFDS
- if( (!overloading && nblocked) ||
- (overloading && nblocked == OVERLOADBLOCKFDS) ){
- for( i = 0 ; i < OVERLOADBLOCKFDS ; ++i )
- if( blockfd[i] != csock && blockfd[i] != msock )
- /* blockfd[i] should not be msock, but it happened */
- close(blockfd[i]);
- nblocked = 0;
- }
-#endif
-
- if( overloading ){
-#if OVERLOADBLOCKFDS
- blockfd[nblocked++] = csock;
-#else
- close(csock);
-#endif
- continue;
- }
-
-#ifdef NO_FORK
- break;
-#else
- if (fork() == 0)
- break;
- else
- close(csock);
-#endif
- }
- /* here is only child running */
-
-#ifndef VALGRIND
- setproctitle("%s: ...login wait... ", margs);
-#endif
- close(msock);
- dup2(csock, 0);
- close(csock);
-
- XAUTH_GETREMOTENAME(getremotename(&xsin, fromhost, remoteusername));
-
- if( check_banip(fromhost) ){
- sleep(10);
- exit(0);
- }
- telnet_init();
- return 1;
-}
-
-/*
- * check if we're banning login and if the load is too high. if login is
- * permitted, return 0; else return -1; approriate message is output to fd.
- */
-static int
-check_ban_and_load(int fd)
-{
- FILE *fp;
- static time4_t chkload_time = 0;
- static int overload = 0; /* overload or banned, update every 1
- * sec */
- static int banned = 0;
-
-#ifdef INSCREEN
- write(fd, INSCREEN, sizeof(INSCREEN));
-#else
-#define BANNER \
-"¡i" BBSNAME "¡j¡· ¥x¤j¬y¦æºô ¡·(" MYHOSTNAME ") ½Õ´T(" MYIP ") \r\n"
- write(fd, BANNER, sizeof(BANNER));
-#endif
-
- if ((time(0) - chkload_time) > 1) {
- overload = 0;
- banned = 0;
-
- if(cpuload(NULL) > MAX_CPULOAD)
- overload = 1;
- else if (SHM->UTMPnumber >= MAX_ACTIVE
-#ifdef DYMAX_ACTIVE
- || (SHM->GV2.e.dymaxactive > 2000 &&
- SHM->UTMPnumber >= SHM->GV2.e.dymaxactive)
-#endif
- ) {
- ++SHM->GV2.e.toomanyusers;
- overload = 2;
- } else if(!access(BBSHOME "/" BAN_FILE, R_OK))
- banned = 1;
-
- chkload_time = time(0);
- }
-
- if(overload == 1)
- write(fd, "¨t²Î¹L¸ü, ½Ðµy«á¦A¨Ó\r\n", 22);
- else if(overload == 2)
- write(fd, "¥Ñ©ó¤H¼Æ¹L¦h¡A½Ð±zµy«á¦A¨Ó¡C", 28);
- else if (banned && (fp = fopen(BBSHOME "/" BAN_FILE, "r"))) {
- char buf[256];
- while (fgets(buf, sizeof(buf), fp))
- write(fd, buf, strlen(buf));
- fclose(fp);
- }
-
- if (banned || overload)
- return -1;
-
- return 0;
-}
-
-static int check_banip(char *host)
-{
- unsigned int thisip = 0;
- char *ptr, *myhost = strdup(host);
- char *strtok_pos = NULL;
-
- for( ptr = strtok_r(myhost, ".", &strtok_pos) ; ptr != NULL ; ptr = strtok_r(NULL, ".", &strtok_pos) )
- thisip = thisip * 256 + atoi(ptr);
- free(myhost);
-
- return uintbsearch(thisip, &banip[1], banip[0]) ? 1 : 0;
-}
-
-/* vim: sw=4
- */
diff --git a/mbbsd/menu.c b/mbbsd/menu.c
deleted file mode 100644
index 6aaf3399..00000000
--- a/mbbsd/menu.c
+++ /dev/null
@@ -1,718 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-#define CheckMenuPerm(x) \
- ( (x == MENU_UNREGONLY)? \
- ((cuser.userlevel == 0 ||HasUserPerm(PERM_LOGINOK))?0:1) :\
- ((x) ? HasUserPerm(x) : 1))
-
-/* help & menu processring */
-static int refscreen = NA;
-extern char *boardprefix;
-extern struct utmpfile_t *utmpshm;
-
-static const char *title_tail_msgs[] = {
- "¬ÝªO",
- "¨t¦C",
- "¤åºK",
-};
-static const char *title_tail_attrs[] = {
- ANSI_COLOR(37),
- ANSI_COLOR(32),
- ANSI_COLOR(36),
-};
-enum {
- TITLE_TAIL_BOARD = 0,
- TITLE_TAIL_SELECT,
- TITLE_TAIL_DIGEST,
-};
-
-void
-showtitle(const char *title, const char *mid)
-{
- /* we have to...
- * - display title in left, cannot truncate.
- * - display mid message, cannot truncate
- * - display tail (board info), if possible.
- */
- int llen, rlen, mlen, mpos = 0;
- int pos = 0;
- int tail_type;
- const char *mid_attr = ANSI_COLOR(33);
- int is_currboard_special = 0;
- char buf[64];
-
-
- /* prepare mid */
-#ifdef DEBUG
- {
- sprintf(buf, " current pid: %6d ", getpid());
- mid = buf;
- mid_attr = ANSI_COLOR(41;5);
- }
-#else
- if (ISNEWMAIL(currutmp)) {
- mid = " §A¦³·s«H¥ó ";
- mid_attr = ANSI_COLOR(41;5);
- } else if ( HasUserPerm(PERM_ACCTREG) ) {
- int nreg = dashs((char *)fn_register) / 163;
- if(nreg > 100)
- {
- sprintf(buf, " ¦³ %03d ¥¼¼f®Ö ", nreg);
- mid_attr = ANSI_COLOR(41;5);
- mid = buf;
- }
- }
-#endif
-
- /* prepare tail */
- if (currmode & MODE_SELECT)
- tail_type = TITLE_TAIL_SELECT;
- else if (currmode & MODE_DIGEST)
- tail_type = TITLE_TAIL_DIGEST;
- else
- tail_type = TITLE_TAIL_BOARD;
-
- if(currbid > 0)
- {
- assert(0<=currbid-1 && currbid-1<MAX_BOARD);
- is_currboard_special = (
- (getbcache(currbid)->brdattr & BRD_HIDE) &&
- (getbcache(currbid)->brdattr & BRD_POSTMASK));
- }
-
- /* now, calculate real positioning info */
- llen = strlen(title);
- mlen = strlen(mid);
- mpos = (t_columns -1 - mlen)/2;
-
- /* first, print left. */
- clear();
- outs(TITLE_COLOR "¡i");
- outs(title);
- outs("¡j");
- pos = llen + 4;
-
- /* print mid */
- while(pos++ < mpos)
- outc(' ');
- outs(mid_attr);
- outs(mid);
- pos += mlen;
- outs(TITLE_COLOR);
-
- /* try to locate right */
- rlen = strlen(currboard) + 4 + 4;
- if(currboard[0] && pos+rlen < t_columns)
- {
- // print right stuff
- while(pos++ < t_columns-rlen)
- outc(' ');
- outs(title_tail_attrs[tail_type]);
- outs(title_tail_msgs[tail_type]);
- outs("¡m");
-
- if (is_currboard_special)
- outs(ANSI_COLOR(32));
- outs(currboard);
- outs(title_tail_attrs[tail_type]);
- outs("¡n" ANSI_RESET "\n");
- } else {
- // just pad it.
- while(pos++ < t_columns)
- outc(' ');
- outs(ANSI_RESET "\n");
- }
-
-}
-
-/* °Êµe³B²z */
-#define FILMROW 11
-static const unsigned char menu_row = 12;
-static const unsigned char menu_column = 20;
-
-static void
-show_status(void)
-{
- int i;
- struct tm *ptime = localtime4(&now);
- char mystatus[160];
- char *myweek = "¤Ñ¤@¤G¤T¥|¤­¤»";
- const char *msgs[] = {"Ãö³¬", "¥´¶}", "©Þ±¼", "¨¾¤ô", "¦n¤Í"};
-
- i = ptime->tm_wday << 1;
- snprintf(mystatus, sizeof(mystatus),
- ANSI_COLOR(34;46) "[%d/%d ¬P´Á%c%c %d:%02d]"
- ANSI_COLOR(1;33;45) "%-14s"
- ANSI_COLOR(30;47) " ½u¤W" ANSI_COLOR(31)
- "%d" ANSI_COLOR(30) "¤H, §Ú¬O" ANSI_COLOR(31) "%s"
- ANSI_COLOR(30) ,
- ptime->tm_mon + 1, ptime->tm_mday, myweek[i], myweek[i + 1],
- ptime->tm_hour, ptime->tm_min, currutmp->birth ?
- "¥Í¤é­n½Ð«È­ò" : SHM->today_is,
- SHM->UTMPnumber, cuser.userid);
- outmsg(mystatus);
- i = strlen(mystatus) - (3*7+25); // 3 = ANSI_COLOR, 25 = stuff inside
- sprintf(mystatus, "[¦©¾÷]" ANSI_COLOR(31) "%s ",
- msgs[currutmp->pager]);
- outslr("", i, mystatus, strlen(msgs[currutmp->pager]) + 7);
- outs(ANSI_RESET);
-}
-
-/*
- * current caller of movie:
- * board.c: movie(0); // called when IN_CLASSROOT()
- * // with currstat = CLASS -> don't show movies
- * xyz.c: movie(999999); // logout
- * menu.c: movie(cmdmode); // ...
- */
-void
-movie(int cmdmode)
-{
- // movie «e´Xµ§¬O Note ªOºëµØ°Ï¡u<¨t²Î> °ÊºA¬ÝªO¡v(SYS) ¥Ø¿ý¤Uªº¤å³¹
- // movie_map ¬O¥Î¨Ó¨Ì cmdmode ¬D¥X¯S©wªº°ÊºA¬ÝªO¡Aindex ¸ò mode_map ¤@¼Ë¡C
- const int movie_map[] = {
- 2, 10, 11, -1, 3, -1, 12,
- 7, 9, 8, 4, 5, 6,
- };
-
-#define N_SYSMOVIE (sizeof(movie_map) / sizeof(movie_map[0]))
- int i;
- if ((currstat != CLASS) && (cuser.uflag & MOVIE_FLAG) &&
- !SHM->Pbusystate && SHM->last_film > 0) {
- if (cmdmode < N_SYSMOVIE &&
- 0 < movie_map[cmdmode] && movie_map[cmdmode] <= SHM->last_film) {
- i = movie_map[cmdmode];
- } else if (cmdmode == 999999) { /* Goodbye my friend */
- i = 0;
- } else {
- i = N_SYSMOVIE + (int)(((float)SHM->last_film - N_SYSMOVIE + 1) * (random() / (RAND_MAX + 1.0)));
- }
-#undef N_SYSMOVIE
-
- move(1, 0);
- clrtoln(1 + FILMROW); /* ²M±¼¤W¦¸ªº */
- out_lines(SHM->notes[i], 11); /* ¥u¦L11¦æ´N¦n */
- outs(reset_color);
- }
- show_status();
- refresh();
-}
-
-typedef struct {
- int (*cmdfunc)();
- int level;
- char *desc; /* next/key/description */
-} commands_t;
-
-static int
-show_menu(int moviemode, const commands_t * p)
-{
- register int n = 0;
- register char *s;
-
- movie(moviemode);
-
- move(menu_row, 0);
- while ((s = p[n].desc)) {
- if (CheckMenuPerm(p[n].level)) {
- prints("%*s (" ANSI_COLOR(1;36) "%c" ANSI_COLOR(0) ")%s\n", menu_column, "", s[1],
- s+2);
- }
- n++;
- }
- return n - 1;
-}
-
-
-enum {
- M_ADMIN = 0, M_AMUSE, M_CHC, M_JCEE, M_MAIL, M_MMENU, M_NMENU,
- M_PMENU, M_PSALE, M_SREG, M_TMENU, M_UMENU, M_XMENU, M_XMAX
-};
-
-static const int mode_map[] = {
- ADMIN, AMUSE, CHC, JCEE, MAIL, MMENU, NMENU,
- PMENU, PSALE, SREG, TMENU, UMENU, XMENU,
-};
-
-static void
-domenu(int cmdmode, const char *cmdtitle, int cmd, const commands_t cmdtable[])
-{
- int lastcmdptr, moviemode;
- int n, pos, total, i;
- int err;
-
- moviemode = cmdmode;
- assert(cmdmode < M_XMAX);
- cmdmode = mode_map[cmdmode];
-
- setutmpmode(cmdmode);
-
- showtitle(cmdtitle, BBSName);
-
- total = show_menu(moviemode, cmdtable);
-
- show_status();
- lastcmdptr = pos = 0;
-
- do {
- i = -1;
- switch (cmd) {
- case Ctrl('I'):
- t_idle();
- refscreen = YEA;
- i = lastcmdptr;
- break;
- case Ctrl('N'):
- New();
- refscreen = YEA;
- i = lastcmdptr;
- break;
- case Ctrl('A'):
- if (mail_man() == FULLUPDATE)
- refscreen = YEA;
- i = lastcmdptr;
- break;
- case KEY_DOWN:
- i = lastcmdptr;
- case KEY_HOME:
- case KEY_PGUP:
- do {
- if (++i > total)
- i = 0;
- } while (!CheckMenuPerm(cmdtable[i].level));
- break;
- case KEY_END:
- case KEY_PGDN:
- i = total;
- break;
- case KEY_UP:
- i = lastcmdptr;
- do {
- if (--i < 0)
- i = total;
- } while (!CheckMenuPerm(cmdtable[i].level));
- break;
- case KEY_LEFT:
- case 'e':
- case 'E':
- if (cmdmode == MMENU)
- cmd = 'G';
- else if ((cmdmode == MAIL) && chkmailbox())
- cmd = 'R';
- else
- return;
- default:
- if ((cmd == 's' || cmd == 'r') &&
- (currstat == MMENU || currstat == TMENU || currstat == XMENU)) {
- if (cmd == 's')
- ReadSelect();
- else
- Read();
- refscreen = YEA;
- i = lastcmdptr;
- break;
- }
- if (cmd == '\n' || cmd == '\r' || cmd == KEY_RIGHT) {
- move(b_lines, 0);
- clrtoeol();
-
- currstat = XMODE;
-
- if ((err = (*cmdtable[lastcmdptr].cmdfunc) ()) == QUIT)
- return;
- currutmp->mode = currstat = cmdmode;
-
- if (err == XEASY) {
- refresh();
- safe_sleep(1);
- } else if (err != XEASY + 1 || err == FULLUPDATE)
- refscreen = YEA;
-
- if (err != -1)
- cmd = cmdtable[lastcmdptr].desc[0];
- else
- cmd = cmdtable[lastcmdptr].desc[1];
- }
- if (cmd >= 'a' && cmd <= 'z')
- cmd &= ~0x20;
- while (++i <= total)
- if (cmdtable[i].desc[1] == cmd)
- break;
-
- if (!CheckMenuPerm(cmdtable[i].level)) {
- for (i = 0; cmdtable[i].desc; i++)
- if (CheckMenuPerm(cmdtable[i].level))
- break;
- if (!cmdtable[i].desc)
- return;
- }
-
- if (cmd == 'H' && i > total){
- /* TODO: Add menu help */
- }
- }
-
- if (i > total || !CheckMenuPerm(cmdtable[i].level))
- continue;
-
- if (refscreen) {
- showtitle(cmdtitle, BBSName);
-
- show_menu(moviemode, cmdtable);
-
- show_status();
- refscreen = NA;
- }
- cursor_clear(menu_row + pos, menu_column);
- n = pos = -1;
- while (++n <= (lastcmdptr = i))
- if (CheckMenuPerm(cmdtable[n].level))
- pos++;
-
- cursor_show(menu_row + pos, menu_column);
- } while (((cmd = igetch()) != EOF) || refscreen);
-
- abort_bbs(0);
-}
-/* INDENT OFF */
-
-/* administrator's maintain menu */
-static const commands_t adminlist[] = {
- {m_user, PERM_SYSOP, "UUser ¨Ï¥ÎªÌ¸ê®Æ"},
- {search_user_bypwd, PERM_ACCOUNTS|PERM_POLICE_MAN,
- "SSearch User ¯S®í·j´M¨Ï¥ÎªÌ"},
- {search_user_bybakpwd,PERM_ACCOUNTS,"OOld User data ¬d¾\\³Æ¥÷¨Ï¥ÎªÌ¸ê®Æ"},
- {m_board, PERM_SYSOP|PERM_BOARD, "BBoard ³]©w¬ÝªO"},
- {m_register, PERM_ACCOUNTS|PERM_ACCTREG,
- "RRegister ¼f®Öµù¥Uªí³æ"},
- {cat_register, PERM_SYSOP, "CCatregister µLªk¼f®Ö®É¥Îªº"},
- {x_file, PERM_SYSOP|PERM_VIEWSYSOP,
- "XXfile ½s¿è¨t²ÎÀÉ®×"},
- {give_money, PERM_SYSOP|PERM_VIEWSYSOP,
- "GGivemoney ¬õ¥]Âû"},
- {m_loginmsg, PERM_SYSOP, "MMessage Login ¶i¯¸¤ô²y"},
- {NULL, 0, NULL}
-};
-
-/* mail menu */
-static const commands_t maillist[] = {
- {m_new, PERM_READMAIL, "RNew ¾\\Ū·s¶i¶l¥ó"},
- {m_read, PERM_READMAIL, "RRead ¦h¥\\¯àŪ«H¿ï³æ"},
- {m_send, PERM_LOGINOK, "RSend ¯¸¤º±H«H"},
- {mail_list, PERM_LOGINOK, "RMail List ¸s²Õ±H«H"},
- {x_love, PERM_LOGINOK, "PPaper ±¡®Ñ²£¥Í¾¹"},
- {setforward, PERM_LOGINOK, "FForward " ANSI_COLOR(1;32)
- "³]©w«H½c¦Û°ÊÂà±H" ANSI_RESET},
- {m_sysop, 0, "YYes, sir! ¼g«Hµ¹¯¸ªø"},
- {m_internet, PERM_INTERNET, "RInternet ±H«H¨ì¯¸¥~"},
- {mail_mbox, PERM_INTERNET, "RZip UserHome §â©Ò¦³¨p¤H¸ê®Æ¥´¥]¦^¥h"},
- {built_mail_index, PERM_LOGINOK, "SSavemail ­««Ø«H½c¯Á¤Þ"},
- {mail_all, PERM_SYSOP, "RAll ±H«Hµ¹©Ò¦³¨Ï¥ÎªÌ"},
- {NULL, 0, NULL}
-};
-
-/* Talk menu */
-static const commands_t talklist[] = {
- {t_users, 0, "UUsers §¹¥þ²á¤Ñ¤â¥U"},
- {t_pager, PERM_BASIC, "PPager ¤Á´«©I¥s¾¹"},
- {t_idle, 0, "IIdle µo§b"},
- {t_query, 0, "QQuery ¬d¸ßºô¤Í"},
- {t_qchicken, 0, "WWatch Pet ¬d¸ßÃdª«"},
- // PERM_PAGE - ¤ô²y³£­n PERM_LOGIN ¤F
- // ¨S¹D²z¥i¥H talk ¤£¯à¤ô²y¡C
- {t_talk, PERM_LOGINOK, "TTalk §ä¤H²á²á"},
- // PERM_CHAT «D login ¤]¦³¡A·|¦³¤H¥Î¦¹§n§O¤H¡C
- {t_chat, PERM_LOGINOK, "CChat §ä®a¯ù§{³ð¯ù¥h"},
-#ifdef PLAY_ANGEL
- {t_changeangel, PERM_LOGINOK, "UAChange Angel §ó´«¤p¤Ñ¨Ï"},
- {t_angelmsg, PERM_ANGEL, "LLeave message ¯d¨¥µ¹¤p¥D¤H"},
-#endif
- {t_display, 0, "DDisplay Åã¥Ü¤W´X¦¸¼ö°T"},
- {NULL, 0, NULL}
-};
-
-/* name menu */
-static int t_aloha() {
- friend_edit(FRIEND_ALOHA);
- return 0;
-}
-
-static int t_special() {
- friend_edit(FRIEND_SPECIAL);
- return 0;
-}
-
-static const commands_t namelist[] = {
- {t_override, PERM_LOGINOK,"OOverRide ¦n¤Í¦W³æ"},
- {t_reject, PERM_LOGINOK, "BBlack Ãa¤H¦W³æ"},
- {t_aloha,PERM_LOGINOK, "AALOHA ¤W¯¸³qª¾¦W³æ"},
- {t_fix_aloha,PERM_LOGINOK,"XXFixALOHA ­×¥¿¤W¯¸³qª¾"},
- {t_special,PERM_LOGINOK, "SSpecial ¨ä¥L¯S§O¦W³æ"},
- {NULL, 0, NULL}
-};
-
-void Customize(); // user.c
-int u_customize()
-{
- Customize();
- return 0;
-}
-
-int u_fixgoodpost(void); // assess.c
-/* User menu */
-static const commands_t userlist[] = {
- {u_customize, PERM_BASIC, "UUCustomize ­Ó¤H¤Æ³]©w"},
- {u_info, PERM_LOGINOK, "IInfo ³]©w­Ó¤H¸ê®Æ»P±K½X"},
- {calendar, PERM_LOGINOK, "CCalendar ­Ó¤H¦æ¨Æ¾ä"},
- {u_loginview, PERM_BASIC, "LLogin View ¿ï¾Ü¶i¯¸µe­±"},
- {u_editplan, PERM_LOGINOK, "QQueryEdit ½s¿è¦W¤ùÀÉ"},
- {u_editsig, PERM_LOGINOK, "SSignature ½s¿èñ¦WÀÉ"},
-#if HAVE_FREECLOAK
- {u_cloak, PERM_LOGINOK, "KKCloak Áô¨­³N"},
-#else
- {u_cloak, PERM_CLOAK, "KKCloak Áô¨­³N"},
-#endif
- {u_register, MENU_UNREGONLY, "RRegister ¶ñ¼g¡mµù¥U¥Ó½Ð³æ¡n"},
-#ifdef ASSESS
- {u_cancelbadpost, PERM_LOGINOK, "BBye BadPost ¥Ó½Ð§R°£¦H¤å"},
- {u_fixgoodpost, PERM_LOGINOK, "FFix GoodPost ­×´_Àu¤å"},
-#endif // ASSESS
- {u_list, PERM_SYSOP, "XUsers ¦C¥Xµù¥U¦W³æ"},
-#ifdef MERGEBBS
-// {m_sob, PERM_LOGUSER|PERM_SYSOP, "SSOB Import ¨FÅyÅܨ­³N"},
- {m_sob, PERM_BASIC, "SSOB Import ¨FÅyÅܨ­³N"},
-#endif
- {NULL, 0, NULL}
-};
-
-#ifdef DEBUG
-int _debug_check_keyinput();
-int _debug_testregcode();
-int _debug_reportstruct()
-{
- clear();
- prints("boardheader_t:\t%d\n", sizeof(boardheader_t));
- prints("fileheader_t:\t%d\n", sizeof(fileheader_t));
- prints("userinfo_t:\t%d\n", sizeof(userinfo_t));
- prints("screenline_t:\t%d\n", sizeof(screenline_t));
- prints("SHM_t:\t%d\n", sizeof(SHM_t));
- prints("bid_t:\t%d\n", sizeof(bid_t));
- prints("userec_t:\t%d\n", sizeof(userec_t));
- pressanykey();
- return 0;
-}
-
-#endif
-
-/* XYZ tool menu */
-static const commands_t xyzlist[] = {
-#ifndef DEBUG
- /* All these are useless in debug mode. */
-#ifdef HAVE_LICENSE
- {x_gpl, 0, "LLicense GNU ¨Ï¥Î°õ·Ó"},
-#endif
-#ifdef HAVE_INFO
- {x_program, 0, "PProgram ¥»µ{¦¡¤§ª©¥»»Pª©Åv«Å§i"},
-#endif
- {x_boardman,0, "MMan Boards ¡m¬ÝªOºëµØ°Ï±Æ¦æº]¡n"},
-// {x_boards,0, "HHot Boards ¡m¬ÝªO¤H®ð±Æ¦æº]¡n"},
- {x_history, 0, "HHistory ¡m§Ú­Ìªº¦¨ªø¡n"},
- {x_note, 0, "NNote ¡m»Ä²¢­W»¶¬y¨¥ªO¡n"},
- {x_login,0, "SSystem ¡m¨t²Î­«­n¤½§i¡n"},
- {x_week, 0, "WWeek ¡m¥»¶g¤­¤Q¤j¼öªù¸ÜÃD¡n"},
- {x_issue, 0, "IIssue ¡m¤µ¤é¤Q¤j¼öªù¸ÜÃD¡n"},
- {x_today, 0, "TToday ¡m¤µ¤é¤W½u¤H¦¸²Î­p¡n"},
- {x_yesterday, 0, "YYesterday ¡m¬Q¤é¤W½u¤H¦¸²Î­p¡n"},
- {x_user100 ,0, "UUsers ¡m¨Ï¥ÎªÌ¦Ê¤j±Æ¦æº]¡n"},
-#else
- {_debug_check_keyinput, 0,
- "MMKeycode Àˬd«öÁä±±¨î½X¤u¨ã"},
- {_debug_testregcode, 0,
- "RRegcode Àˬdµù¥U½X¤½¦¡"},
- {_debug_reportstruct, 0,
- "RReportStruct ³ø§i¦UºØµ²ºcªº¤j¤p"},
-#endif
-
- {p_sysinfo, 0, "XXinfo ¡m¬d¬Ý¨t²Î¸ê°T¡n"},
- {NULL, 0, NULL}
-};
-
-/* Ptt money menu */
-static const commands_t moneylist[] = {
- {p_give, 0, "00Give µ¹¨ä¥L¤H¿ú"},
- {save_violatelaw, 0,"11ViolateLaw ú»@³æ"},
-#if !HAVE_FREECLOAK
- {p_cloak, 0, "22Cloak ¤Á´« Áô¨­/²{¨­ $19 /¦¸"},
-#endif
- {p_from, 0, "33From ¼È®É­×§ï¬G¶m $49 /¦¸"},
- {ordersong,0, "44OSong ¼Ú®á°ÊºAÂIºq¾÷ $200 /¦¸"},
- {p_exmail, 0, "55Exmail ÁʶR«H½c $1000/«Ê"},
- {NULL, 0, NULL}
-};
-
-static const commands_t cmdlist[] = {
- {admin, PERM_SYSOP|PERM_ACCOUNTS|PERM_BOARD|PERM_VIEWSYSOP|PERM_ACCTREG|PERM_POLICE_MAN,
- "00Admin ¡i ¨t²ÎºûÅ@°Ï ¡j"},
- {Announce, 0, "AAnnounce ¡i ºëµØ¤½§GÄæ ¡j"},
-#ifdef DEBUG
- {Favorite, 0, "FFavorite ¡i §Úªº³Ì¤£·R ¡j"},
-#else
- {Favorite, 0, "FFavorite ¡i §Ú ªº ³Ì·R ¡j"},
-#endif
- {Class, 0, "CClass ¡i ¤À²Õ°Q½×°Ï ¡j"},
- {Mail, PERM_BASIC, "MMail ¡i ¨p¤H«H¥ó°Ï ¡j"},
- {Talk, 0, "TTalk ¡i ¥ð¶¢²á¤Ñ°Ï ¡j"},
- {User, PERM_BASIC, "UUser ¡i ­Ó¤H³]©w°Ï ¡j"},
- {Xyz, 0, "XXyz ¡i ¨t²Î¸ê°T°Ï ¡j"},
- {Play_Play, PERM_LOGINOK, "PPlay ¡i ®T¼Ö»P¥ð¶¢ ¡j"},
- {Name_Menu, PERM_LOGINOK, "NNamelist ¡i ½s¯S§O¦W³æ ¡j"},
-#ifdef DEBUG
- {Goodbye, 0, "GGoodbye ¦A¨£¦A¨£¦A¨£¦A¨£"},
-#else
- {Goodbye, 0, "GGoodbye Â÷¶}¡A¦A¨£¡K "},
-#endif
- {NULL, 0, NULL}
-};
-
-int main_menu(void) {
- domenu(M_MMENU, "¥D¥\\¯àªí", (ISNEWMAIL(currutmp) ? 'M' : 'C'), cmdlist);
- return 0;
-}
-
-static int p_money() {
- domenu(M_PSALE, BBSMNAME2 "¶q³c©±", '0', moneylist);
- return 0;
-};
-
-// static int forsearch();
-static int playground();
-static int chessroom();
-
-/* Ptt Play menu */
-static const commands_t playlist[] = {
- {note, PERM_LOGINOK, "NNote ¡i ¨è¨è¬y¨¥ªO ¡j"},
- /* // useless.
- {forsearch,PERM_LOGINOK, "SSearchEngine¡i" ANSI_COLOR(1;35) " "
- BBSMNAME2 "·j´M¾¹ " ANSI_RESET "¡j"},
- */
- {topsong,PERM_LOGINOK, "TTop Songs ¡i" ANSI_COLOR(1;32) " ÂIºq±Æ¦æº] " ANSI_RESET "¡j"},
- {p_money,PERM_LOGINOK, "PPay ¡i" ANSI_COLOR(1;31) " "
- BBSMNAME2 "¶q³c©± " ANSI_RESET "¡j"},
- {chicken_main,PERM_LOGINOK, "CChicken "
- "¡i" ANSI_COLOR(1;34) " " BBSMNAME2 "¾iÂû³õ " ANSI_RESET "¡j"},
- {playground,PERM_LOGINOK, "AAmusement ¡i" ANSI_COLOR(1;33) " "
- BBSMNAME2 "¹C¼Ö³õ " ANSI_RESET "¡j"},
- {chessroom, PERM_LOGINOK, "BBChess ¡i" ANSI_COLOR(1;34) " "
- BBSMNAME2 "´Ñ°| " ANSI_RESET "¡j"},
- {NULL, 0, NULL}
-};
-
-static const commands_t chesslist[] = {
- {chc_main, PERM_LOGINOK, "11CChessFight ¡i" ANSI_COLOR(1;33) " ¶H´ÑÁܧ½ " ANSI_RESET "¡j"},
- {chc_personal, PERM_LOGINOK, "22CChessSelf ¡i" ANSI_COLOR(1;34) " ¶H´Ñ¥´ÃÐ " ANSI_RESET "¡j"},
- {chc_watch, PERM_LOGINOK, "33CChessWatch ¡i" ANSI_COLOR(1;35) " ¶H´ÑÆ[´Ñ " ANSI_RESET "¡j"},
- {gomoku_main, PERM_LOGINOK, "44GomokuFight ¡i" ANSI_COLOR(1;33) "¤­¤l´ÑÁܧ½" ANSI_RESET "¡j"},
- {gomoku_personal, PERM_LOGINOK, "55GomokuSelf ¡i" ANSI_COLOR(1;34) "¤­¤l´Ñ¥´ÃÐ" ANSI_RESET "¡j"},
- {gomoku_watch, PERM_LOGINOK, "66GomokuWatch ¡i" ANSI_COLOR(1;35) "¤­¤l´ÑÆ[´Ñ" ANSI_RESET "¡j"},
- {gochess_main, PERM_LOGINOK, "77GoChessFight ¡i" ANSI_COLOR(1;33) " ³ò´ÑÁܧ½ " ANSI_RESET "¡j"},
- {gochess_personal, PERM_LOGINOK, "88GoChessSelf ¡i" ANSI_COLOR(1;34) " ³ò´Ñ¥´ÃÐ " ANSI_RESET "¡j"},
- {gochess_watch, PERM_LOGINOK, "99GoChessWatch ¡i" ANSI_COLOR(1;35) " ³ò´ÑÆ[´Ñ " ANSI_RESET "¡j"},
- {NULL, 0, NULL}
-};
-
-static int chessroom() {
- domenu(M_CHC, BBSMNAME2 "´Ñ°|", '1', chesslist);
- return 0;
-}
-
-static const commands_t plist[] = {
-
-/* {p_ticket_main, PERM_LOGINOK,"00Pre ¡i Á`²Î¾÷ ¡j"},
- {alive, PERM_LOGINOK, "00Alive ¡i ­q²¼Âû ¡j"},
-*/
- {ticket_main, PERM_LOGINOK, "11Gamble ¡i " BBSMNAME2 "½ä³õ ¡j"},
- {guess_main, PERM_LOGINOK, "22Guess number¡i ²q¼Æ¦r ¡j"},
- {othello_main, PERM_LOGINOK, "33Othello ¡i ¶Â¥Õ´Ñ ¡j"},
-// {dice_main, PERM_LOGINOK, "44Dice ¡i ª±»ë¤l ¡j"},
- {vice_main, PERM_LOGINOK, "44Vice ¡i µo²¼¹ï¼ú ¡j"},
- {g_card_jack, PERM_LOGINOK, "55Jack ¡i ¶Â³Ç§J ¡j"},
- {g_ten_helf, PERM_LOGINOK, "66Tenhalf ¡i ¤QÂI¥b ¡j"},
- {card_99, PERM_LOGINOK, "77Nine ¡i ¤E¤Q¤E ¡j"},
- {NULL, 0, NULL}
-};
-
-static int playground() {
- domenu(M_AMUSE, BBSMNAME2 "¹C¼Ö³õ",'1',plist);
- return 0;
-}
-
-static const commands_t slist[] = {
- /*
- // x_dict: useless
- {x_dict,0, "11Dictionary "
- "¡i" ANSI_COLOR(1;33) " ½ì¨ý¤j¦r¨å " ANSI_RESET "¡j"},
- */
- {x_mrtmap, 0, "22MRTmap "
- "¡i" ANSI_COLOR(1;34) " ±¶¹B¦a¹Ï " ANSI_RESET "¡j"},
- {NULL, 0, NULL}
-};
-
-/* // nothing to search...
-static int forsearch() {
- domenu(M_SREG, BBSMNAME2 "·j´M¾¹", '1', slist);
- return 0;
-}
-*/
-
-/* main menu */
-
-int
-admin(void)
-{
- domenu(M_ADMIN, "¨t²ÎºûÅ@", 'X', adminlist);
- return 0;
-}
-
-int
-Mail(void)
-{
- domenu(M_MAIL, "¹q¤l¶l¥ó", 'R', maillist);
- return 0;
-}
-
-int
-Talk(void)
-{
- domenu(M_TMENU, "²á¤Ñ»¡¸Ü", 'U', talklist);
- return 0;
-}
-
-int
-User(void)
-{
- domenu(M_UMENU, "­Ó¤H³]©w", 'U', userlist);
- return 0;
-}
-
-int
-Xyz(void)
-{
- domenu(M_XMENU, "¤u¨ãµ{¦¡", 'M', xyzlist);
- return 0;
-}
-
-int
-Play_Play(void)
-{
- domenu(M_PMENU, "ºô¸ô¹C¼Ö³õ", 'A', playlist);
- return 0;
-}
-
-int
-Name_Menu(void)
-{
- domenu(M_NMENU, "¥Õ¦â®£©Æ", 'O', namelist);
- return 0;
-}
-
diff --git a/mbbsd/merge.c b/mbbsd/merge.c
deleted file mode 100644
index 913f94f5..00000000
--- a/mbbsd/merge.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/* $Id$ */
-#define _XOPEN_SOURCE
-#define _ISOC99_SOURCE
-/* this is a interface provided when we merge BBS */
-#include "bbs.h"
-#include "fpg.h"
-
-int
-m_sob(void)
-{
- char genbuf[256], buf[256], userid[25], passbuf[24], msg[2048]="";
- int count=0, i, isimported=0, corrected;
- FILE *fp;
- sobuserec man;
- time4_t d;
-
- clear();
- move(1,0);
-
- outs(
- " ½Ðª`·N ³o¬O¥uµ¹¶§¥ú¨FÅy¨Ï¥ÎªÌ!\n"
- " Åý¨FÅyªº¨Ï¥ÎªÌÂಾ­Ó¤H¸ê²£¥H¤Î­«­n«H¥Î¸ê®Æ, ¨É¦³¥­µ¥¦w¥þªºÀô¹Ò.\n"
- " ¦pªG±z¤£»Ý­n, ½Ðª½Â÷¶}.\n"
- " -----------------------------------------------------------------\n"
- " ¯S§O¥mÀ{:\n"
- " ¬°¤F±b¸¹¦w¥þ,±z¥u¦³³sÄò¤Q¦¸±K½X¿ù»~ªº¾÷·|,½Ð¤p¤ß¿é¤J.\n"
- " ³sÄò¦¸¿ù»~±zªºÅܨ­¥\\¯à´N·|³Q¶}»@³æ¨Ãª½±µ³qª¾¯¸ªø.\n"
- " ½Ð¤£­n¦bÅܨ­¹Lµ{¤¤¤£¥¿±`Â_½u, ¨è·NÂ_½uÅÜ¥bÃ~¤H¯¸ªø¤£±Ï­ò.\n"
- );
-
- if(getkey("¬O§_­nÄ~Äò?(y/N)")!='y') return 0;
- if(search_ulistn(usernum,2))
- {vmsg("½Ðµn¥X¨ä¥Lµøµ¡, ¥H§KÅܨ­¥¢±Ñ"); return 0;}
- do
- {
- if(!getdata(10,0, " ¨FÅyªºID [¤j¤p¼g­n§¹¥þ¥¿½T]:", userid, 20,
- DOECHO)) return 0;
- if(bad_user_id(userid)) continue;
- sprintf(genbuf, "sob/passwd/%c/%s.inf",userid[0], userid);
- if(!(fp=fopen(genbuf, "r")))
- {
- isimported = 1;
- strcat(genbuf, ".done");
- if(!(fp=fopen(genbuf, "r")))
- {
- vmsg("¬dµL¦¹¤H©Î¤w¸g¶×¤J¹L..½Ðª`·N¤j¤p¼g ");
- isimported = 0;
- continue;
- }
- }
- count = fread(&man, sizeof(man), 1, fp);
- fclose(fp);
- }while(!count);
- count = 0;
- do{
- if(!getdata(11,0, " ¨FÅyªº±K½X:", passbuf, sizeof(passbuf),
- NOECHO)) return 0;
- if(++count>=10)
- {
- cuser.userlevel |= PERM_VIOLATELAW;
- cuser.vl_count++;
- passwd_update(usernum, &cuser);
- post_violatelaw(cuser.userid, "[PTTĵ¹î]", "´ú¸Õ±b¸¹¿ù»~¤Q¦¸",
- "¹HªkÆ[¹î");
- mail_violatelaw(cuser.userid, "[PTTĵ¹î]", "´ú¸Õ±b¸¹¿ù»~¤Q¦¸",
- "¹HªkÆ[¹î");
-
- return 0;
- }
- if(!(corrected = checkpasswd(man.passwd, passbuf)))
- vmsg("±K½X¿ù»~");
- } while(!corrected);
- move(12,0);
- clrtobot();
-
- if(!isimported)
- {
- if(!dashf(genbuf)) // avoid multi-login
- {
- vmsg("½Ð¤£­n¹Á¸Õ¦h­«id¿å¶×¤J");
- return 0;
- }
- sprintf(buf,"%s.done",genbuf);
- rename(genbuf,buf);
-#ifdef MERGEMONEY
-
- reload_money();
-
- sprintf(buf,
- "±zªº¨FÅyÆxÄMÁ³ %10d ´«ºâ¦¨ " MONEYNAME " ¹ô¬° %9d (¶×²v 22:1), \n"
- " ¨FÅy¨©´ß¦³ %10d ´«ºâ¬° " MONEYNAME " ¹ô¬° %9d (¶×²v 222105:1), \n"
- " ­ì¦³ %10d ¶×¤J«á¦@¦³ %d\n",
- (int)man.goldmoney, (int)man.goldmoney/22,
- (int)man.silvermoney, (int)man.silvermoney/222105,
- cuser.money,
- (int)(cuser.money + man.goldmoney/22 + man.silvermoney/222105));
- demoney(man.goldmoney/22 + man.silvermoney/222105 );
- strcat(msg, buf);
-#endif
-
- i = cuser.exmailbox + man.exmailbox + man.exmailboxk/2000;
- if (i > MAX_EXKEEPMAIL) i = MAX_EXKEEPMAIL;
- sprintf(buf, "±zªº¨FÅy«H½c¦³ %d (%dk), ­ì¦³ %d ¶×¤J«á¦@¦³ %d\n",
- man.exmailbox, man.exmailboxk, cuser.exmailbox, i);
- strcat(msg, buf);
- cuser.exmailbox = i;
-
- if(man.userlevel & PERM_MAILLIMIT)
- {
- sprintf(buf, "¶}±Ò«H½cµL¤W­­\n");
- strcat(msg, buf);
- cuser.userlevel |= PERM_MAILLIMIT;
- }
-
- if (cuser.firstlogin > man.firstlogin)
- d = man.firstlogin;
- else
- d = cuser.firstlogin;
- cuser.firstlogin = d;
-
- if (cuser.numlogins < man.numlogins)
- i = man.numlogins;
- else
- i = cuser.numlogins;
-
- sprintf(buf, "¨FÅy¶i¯¸¦¸¼Æ %d ¦¹±b¸¹ %d ±N¨ú %d \n", man.numlogins,
- cuser.numlogins, i);
- strcat(msg,buf);
- cuser.numlogins = i;
-
- if (cuser.numposts < man.numposts )
- i = man.numposts;
- else
- i = cuser.numposts;
- sprintf(buf, "¨FÅy¤å³¹¦¸¼Æ %d ¦¹±b¸¹ %d ±N¨ú %d\n",
- man.numposts,cuser.numposts,i);
- strcat(msg,buf);
- cuser.numposts = i;
- outs(msg);
- while (search_ulistn(usernum,2))
- {vmsg("½Ð±N­«ÂФW¯¸¨ä¥L½uÃö³¬! ¦AÄ~Äò");}
- passwd_update(usernum, &cuser);
- }
- sethomeman(genbuf, cuser.userid);
- mkdir(genbuf, 0600);
- sprintf(buf, "tar zxvf %c/%s.tar.gz>/dev/null",
- userid[0], userid);
- chdir("sob/home");
- system(buf);
- chdir(BBSHOME);
-
- if (getans("¬O§_¶×¤J­Ó¤H«H½c? (Y/n)")!='n')
- {
- sethomedir(buf, cuser.userid);
- sprintf(genbuf, "sob/home/%c/%s/.DIR",
- userid[0], userid);
- merge_dir(buf, genbuf, 1);
- strcat(msg, "¶×¤J­Ó¤H«H½c\n");
- }
- if(getans("¬O§_¶×¤J­Ó¤H«H½cºëµØ°Ï(­Ó¤H§@«~¶°)? (·|Âл\\²{¦³³]©w) (y/N)")=='y')
- {
- fileheader_t fh;
- sprintf(buf,
- "rm -rd home/%c/%s/man>/dev/null ; "
- "mv sob/home/%c/%s/man home/%c/%s>/dev/null;"
- "mv sob/home/%c/%s/gem home/%c/%s/man>/dev/null",
- cuser.userid[0], cuser.userid,
- userid[0], userid,
- cuser.userid[0], cuser.userid,
- userid[0], userid,
- cuser.userid[0], cuser.userid);
- system(buf);
- strcat(msg, "¶×¤J­Ó¤H«H½cºëµØ°Ï(­Ó¤H§@«~¶°)\n");
- sprintf(buf,"home/%c/%s/man/gem", cuser.userid[0], cuser.userid);
- if(dashd(buf))
- {
- strcat(fh.title, "¡» ­Ó¤H§@«~¶°");
- strcat(fh.filename, "gem");
- sprintf(fh.owner, cuser.userid);
- sprintf(buf, "home/%c/%s/man/.DIR", cuser.userid[0], cuser.userid);
- append_record(buf, &fh, sizeof(fh));
- }
- }
- if(getans("¬O§_¶×¤J¦n¤Í¦W³æ? (·|Âл\\²{¦³³]©w, ID¥i¯à¬O¤£¦P¤H)? (y/N)")=='y')
- {
- sethomefile(genbuf, cuser.userid, "overrides");
- sprintf(buf, "sob/home/%c/%s/overrides",userid[0],userid);
- Copy(buf, genbuf);
- strcat(buf, genbuf);
- friend_load(FRIEND_OVERRIDE);
- strcat(msg, "¶×¤J¦n¤Í¦W³æ\n");
- }
- sprintf(buf, "±b¸¹¶×¤J³ø§i %s -> %s ", userid, cuser.userid);
- post_msg(GLOBAL_SECURITY, buf, msg, "[¨t²Î¦w¥þ§½]");
-
- vmsg("®¥³ß±z§¹¦¨±b¸¹Åܨ­..");
- return 0;
-}
-
-void
-m_sob_brd(char *bname, char *fromdir)
-{
- char fbname[25], buf[256];
- fileheader_t fh;
-
- fromdir[0]=0;
- do{
-
- if(!getdata(20,0, "SOBªºªO¦W [­^¤å¤j¤p¼g­n§¹¥þ¥¿½T]:", fbname, 20,
- DOECHO)) return;
- }
- while((invalid_brdname(fbname)&1));
-
- sprintf(buf, "sob/man/%s.tar.gz", fbname);
- if(!dashf(buf))
- {
- vmsg("µL¦¹¬ÝªO");
- return;
- }
- chdir(BBSHOME"/sob/boards");
- sprintf(buf, "tar zxf %s.tar.gz >/dev/null",fbname);
- system(buf);
- chdir(BBSHOME"/sob/man");
- sprintf(buf, "tar zxf %s.tar.gz >/dev/null", fbname);
- system(buf);
- chdir(BBSHOME);
- sprintf(buf, "mv sob/man/%s man/boards/%c/%s", fbname,
- bname[0], bname);
- system(buf);
- sprintf(fh.title, "¡» %s ºëµØ°Ï", fbname);
- sprintf(fh.filename, fbname);
- sprintf(fh.owner, cuser.userid);
- sprintf(buf, "man/boards/%c/%s/.DIR", bname[0], bname);
- append_record(buf, &fh, sizeof(fh));
- sprintf(fromdir, "sob/boards/%s/.DIR", fbname);
- vmsgf("§Y±N¶×¤J %s ªO¸ê®Æ..«öÁä«á»Ý­n¤@ÂI®É¶¡",fbname);
-}
diff --git a/mbbsd/more.c b/mbbsd/more.c
deleted file mode 100644
index d506754a..00000000
--- a/mbbsd/more.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-/* use new pager: piaip's more. */
-int more(char *fpath, int promptend)
-{
- int r = pmore(fpath, promptend);
-
- switch(r)
- {
-
- case RET_DOSYSOPEDIT:
- r = FULLUPDATE;
-
- if (!HasUserPerm(PERM_SYSOP) ||
- strcmp(fpath, "etc/ve.hlp") == 0)
- break;
-
-#ifdef GLOBAL_SECURITY
- if (strcmp(currboard, GLOBAL_SECURITY) == 0)
- break;
-#endif // GLOBAL_SECURITY
-
- log_filef("log/security", LOG_CREAT,
- "%u %24.24s %d %s admin edit file=%s\n",
- (int)now, ctime4(&now), getpid(), cuser.userid, fpath);
-
- // no need to allow anything...
- // at least, no need to change title.
- vedit2(fpath, NA, NULL, 0);
- break;
-
- case RET_SELECTBRD:
- r = FULLUPDATE;
- if (HasUserPerm(PERM_BASIC))
- {
- if (currstat == READING)
- return Select();
- }
- break;
-
- case RET_COPY2TMP:
- r = FULLUPDATE;
- if (HasUserPerm(PERM_BASIC))
- {
- char buf[PATHLEN];
- getdata(b_lines - 1, 0, "§â³o½g¤å³¹¦¬¤J¨ì¼È¦sÀÉ¡H[y/N] ",
- buf, 4, LCECHO);
- if (buf[0] != 'y')
- break;
- setuserfile(buf, ask_tmpbuf(b_lines - 1));
- Copy(fpath, buf);
- }
- break;
-
- case RET_DOCHESSREPLAY:
- r = FULLUPDATE;
- if (HasUserPerm(PERM_BASIC))
- {
- ChessReplayGame(fpath);
- }
- break;
-
-#if defined(USE_BBSLUA)
- case RET_DOBBSLUA:
- r = FULLUPDATE;
- if (HasUserPerm(PERM_BASIC))
- {
- bbslua(fpath);
- }
- break;
-#endif
- }
-
- return r;
-}
-
diff --git a/mbbsd/name.c b/mbbsd/name.c
deleted file mode 100644
index 4e9d7134..00000000
--- a/mbbsd/name.c
+++ /dev/null
@@ -1,1067 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-static word_t *current = NULL;
-static char * const msg_more = "-- More --";
-
-typedef char (*arrptr)[];
-/* name complete for user ID */
-
-//-----------------------------------------------------------------------
-
-void NameList_init(struct NameList *self)
-{
- self->size = 0;
- self->capacity = 0;
- self->base = NULL;
-}
-
-void NameList_delete(struct NameList *self)
-{
- self->size = 0;
- self->capacity = 0;
- if(self->base)
- free(self->base);
- self->base = NULL;
-}
-
-void NameList_clear(struct NameList *self)
-{
- NameList_delete(self);
- NameList_init(self);
-}
-
-void NameList_resizefor(struct NameList *self, int size)
-{
- int capacity = size * (IDLEN+1);
-#define MIN_CAPACITY 4096
- if (capacity == 0) {
- if(self->base) free(self->base);
- self->base = NULL;
- self->capacity = 0;
- } else {
- int old_capacity = self->capacity;
- assert(capacity > 0);
- if (self->capacity == 0)
- self->capacity = MIN_CAPACITY;
- //if (self->capacity > capacity && self->capacity > MIN_CAPACITY)
- // self->capacity /= 2;
- if (self->capacity < capacity)
- self->capacity *= 2;
-
- if(old_capacity != self->capacity || self->base == NULL) {
- char (*tmp)[IDLEN+1] = (char(*)[IDLEN+1])malloc((IDLEN+1)*self->capacity);
- assert(tmp);
- if (self->size)
- memcpy(tmp, self->base, (IDLEN+1)*self->size);
- if (self->base)
- free(self->base);
- self->base = tmp;
- }
- }
-}
-
-void NameList_add(struct NameList *self, const char *name)
-{
- NameList_resizefor(self, self->size+1);
- strlcpy(self->base[self->size], name, IDLEN+1);
- self->size++;
-}
-
-const char* NameList_get(struct NameList *self, int idx)
-{
- assert(0<=idx && idx<self->size);
- return self->base[idx];
-}
-
-static int NameList_MaxLen(const struct NameList *list, int offset, int count)
-{
- int i;
- int maxlen = 0;
-
- for(i=offset; i<list->size; i++) {
- int len = strlen(list->base[i]);
- if (len > maxlen)
- maxlen = len;
- }
- assert(maxlen <= IDLEN);
- return maxlen;
-}
-
-int NameList_match(const struct NameList *src, struct NameList *dst, int key, int pos)
-{
- int uckey, lckey;
- int i;
-
- NameList_clear(dst);
-
- uckey = chartoupper(key);
- if (key >= 'A' && key <= 'Z')
- lckey = key | 0x20;
- else
- lckey = key;
-
- for(i=0; i<src->size; i++) {
- int ch = src->base[i][pos];
- if (ch == lckey || ch == uckey)
- NameList_add(dst, src->base[i]);
- }
-
- return dst->size;
-}
-
-int NameList_length(struct NameList *self)
-{
- return self->size;
-}
-
-void NameList_sublist(struct NameList *src, struct NameList *dst, char *tag)
-{
- int i;
- int len;
- NameList_clear(dst);
-
- len = strlen(tag);
- for(i=0; i<src->size; i++)
- if(len==0 || strncasecmp(src->base[i], tag, len)==0)
- NameList_add(dst, src->base[i]);
-}
-
-int NameList_remove(struct NameList *self, const char *name)
-{
- int i;
- for(i=0; i<self->size; i++)
- if(strcasecmp(self->base[i], name)==0) {
- strcpy(self->base[i], self->base[self->size-1]);
-
- self->size--;
- NameList_resizefor(self, self->size);
- return 1;
- }
- return 0;
-}
-
-int NameList_search(const struct NameList *self, const char *name)
-{
- int i;
- for(i=0; i<self->size; i++)
- if (strcasecmp(self->base[i], name)==0)
- return 1;
- return 0;
-}
-
-//-----------------------------------------------------------------------
-
-static int
-UserMaxLen(char cwlist[][IDLEN + 1], int cwnum, int morenum,
- int count)
-{
- int len, max = 0;
-
- while (count-- > 0 && morenum < cwnum) {
- len = strlen(cwlist[morenum++]);
- if (len > max)
- max = len;
- }
- /* assert max IDLEN */
- if(max > IDLEN)
- max = IDLEN+1;
- return max;
-}
-
-static int
-UserSubArray(char cwbuf[][IDLEN + 1], char cwlist[][IDLEN + 1],
- int cwnum, int key, int pos)
-{
- int key2, num = 0;
- int n, ch;
-
- key = chartoupper(key);
-
- if (key >= 'A' && key <= 'Z')
- key2 = key | 0x20;
- else
- key2 = key;
-
- for (n = 0; n < cwnum; n++) {
- ch = cwlist[n][pos];
- if (ch == key || ch == key2)
- strlcpy(cwbuf[num++], cwlist[n], sizeof(cwbuf[num]));
- }
- return num;
-}
-
-void
-FreeNameList(void)
-{
- word_t *p, *temp;
-
- for (p = toplev; p; p = temp) {
- temp = p->next;
- free(p->word);
- free(p);
- }
-}
-
-void
-CreateNameList(void)
-{
- if (toplev)
- FreeNameList();
- toplev = current = NULL;
-}
-
-void
-AddNameList(const char *name)
-{
- word_t *node;
-
- node = (word_t *) malloc(sizeof(word_t));
- node->next = NULL;
- node->word = (char *)malloc(strlen(name) + 1);
- strcpy(node->word, name);
-
- if (toplev)
- current = current->next = node;
- else
- current = toplev = node;
-}
-
-int
-RemoveNameList(const char *name)
-{
- word_t *curr, *prev = NULL;
-
- for (curr = toplev; curr; curr = curr->next) {
- if (!strcmp(curr->word, name)) {
- if (prev == NULL)
- toplev = curr->next;
- else
- prev->next = curr->next;
-
- if (curr == current)
- current = prev;
- free(curr->word);
- free(curr);
- return 1;
- }
- prev = curr;
- }
- return 0;
-}
-
-static inline int
-InList(const word_t * list, const char *name)
-{
- const word_t *p;
-
- for (p = list; p; p = p->next)
- if (!strcasecmp(p->word, name))
- return 1;
- return 0;
-}
-
-int
-InNameList(const char *name)
-{
- return InList(toplev, name);
-}
-
-void
-ShowNameList(int row, int column, const char *prompt)
-{
- word_t *p;
-
- move(row, column);
- clrtobot();
- outs(prompt);
-
- column = 80;
- for (p = toplev; p; p = p->next) {
- row = strlen(p->word) + 1;
- if (column + row > 76) {
- column = row;
- outc('\n');
- } else {
- column += row;
- outc(' ');
- }
- outs(p->word);
- }
-}
-
-void
-ToggleNameList(int *reciper, const char *listfile, const char *msg)
-{
- FILE *fp;
- char genbuf[200];
-
- if ((fp = fopen(listfile, "r"))) {
- while (fgets(genbuf, STRLEN, fp)) {
- char *space = strpbrk(genbuf, str_space);
- if (space) *space = '\0';
- if (!genbuf[0])
- continue;
- if (!InNameList(genbuf)) {
- AddNameList(genbuf);
- (*reciper)++;
- } else {
- RemoveNameList(genbuf);
- (*reciper)--;
- }
- }
- fclose(fp);
- ShowNameList(3, 0, msg);
- }
-}
-
-static int
-NumInList(const word_t * list)
-{
- register int i;
-
- for (i = 0; list; i++)
- list = list->next;
- return i;
-}
-
-int
-chkstr(char *otag, const char *tag, const char *name)
-{
- char ch;
- const char *oname = name;
-
- while (*tag) {
- ch = *name++;
- if (*tag != chartoupper(ch))
- return 0;
- tag++;
- }
- if (*tag && *name == '\0')
- strcpy(otag, oname);
- return 1;
-}
-
-static word_t *
-GetSubList(char *tag, word_t * list)
-{
- word_t *wlist, *wcurr;
- char tagbuf[STRLEN];
- int n;
-
- wlist = wcurr = NULL;
- for (n = 0; tag[n]; n++)
- tagbuf[n] = chartoupper(tag[n]);
- tagbuf[n] = '\0';
-
- while (list) {
- if (chkstr(tag, tagbuf, list->word)) {
- register word_t *node;
-
- node = (word_t *) malloc(sizeof(word_t));
- node->word = list->word;
- node->next = NULL;
- if (wlist)
- wcurr->next = node;
- else
- wlist = node;
- wcurr = node;
- }
- list = list->next;
- }
- return wlist;
-}
-
-static void
-ClearSubList(word_t * list)
-{
- struct word_t *tmp_list;
-
- while (list) {
- tmp_list = list->next;
- free(list);
- list = tmp_list;
- }
-}
-
-static int
-MaxLen(const word_t * list, int count)
-{
- int len = strlen(list->word);
- int t;
-
- while (list && count) {
- if ((t = strlen(list->word)) > len)
- len = t;
- list = list->next;
- count--;
- }
- return len;
-}
-
-/* TODO use namecomplete2() instead */
-void
-namecomplete(const char *prompt, char *data)
-{
- char *temp;
- word_t *cwlist, *morelist;
- int x, y, origx, scrx;
- int ch;
- int count = 0;
- int clearbot = NA;
-
- if (toplev == NULL)
- AddNameList("");
- cwlist = GetSubList("", toplev);
- morelist = NULL;
- temp = data;
-
- outs(prompt);
- clrtoeol();
- getyx(&y, &x);
- scrx = origx = x;
- data[count] = 0;
-
- while (1)
- {
- // print input field again
- move(y, scrx); outc(' '); clrtoeol(); move(y, scrx);
- outs(ANSI_COLOR(7));
- prints("%-*s", IDLEN + 1, data);
- outs(ANSI_RESET);
- move(y, scrx + count);
-
- // get input
- if ((ch = igetch()) == EOF)
- break;
-
- if (ch == '\n' || ch == '\r') {
- *temp = '\0';
- // outc('\n');
- if (NumInList(cwlist) == 1)
- strcpy(data, cwlist->word);
- else if (!InList(cwlist, data))
- data[0] = '\0';
- ClearSubList(cwlist);
- break;
- }
- if (ch == ' ') {
- int col, len;
-
- if (NumInList(cwlist) == 1) {
- strcpy(data, cwlist->word);
- count = strlen(data);
- temp = data + count;
- continue;
- }
- clearbot = YEA;
- col = 0;
- if (!morelist)
- morelist = cwlist;
- len = MaxLen(morelist, p_lines);
- move(2, 0);
- clrtobot();
- printdash("¬ÛÃö¸ê°T¤@Äýªí", 0);
- while (len + col < t_columns) {
- int i;
-
- for (i = p_lines; (morelist) && (i > 0); i--) {
- move(3 + (p_lines - i), col);
- outs(morelist->word);
- morelist = morelist->next;
- }
- col += len + 2;
- if (!morelist)
- break;
- len = MaxLen(morelist, p_lines);
- }
- if (morelist) {
- vmsg(msg_more);
- }
- continue;
- }
- if (ch == '\177' || ch == '\010') {
- if (temp == data)
- continue;
- temp--;
- count--;
- *temp = '\0';
- ClearSubList(cwlist);
- cwlist = GetSubList(data, toplev);
- morelist = NULL;
- continue;
- }
- if (count < STRLEN && isprint(ch)) {
- word_t *node;
-
- *temp++ = ch;
- count++;
- *temp = '\0';
- node = GetSubList(data, cwlist);
- if (node == NULL) {
- temp--;
- *temp = '\0';
- count--;
- continue;
- }
- ClearSubList(cwlist);
- cwlist = node;
- morelist = NULL;
- }
- }
- if (ch == EOF)
- /* longjmp(byebye, -1); */
- raise(SIGHUP); /* jochang: don't know if this is
- * necessary... */
- outc('\n');
- if (clearbot) {
- move(2, 0);
- clrtobot();
- }
- if (*data) {
- move(y, origx);
- outs(data);
- outc('\n');
- }
-}
-
-void
-namecomplete2(struct NameList *namelist, const char *prompt, char *data)
-{
- char *temp;
- int x, y, origx, scrx;
- int ch;
- int count = 0;
- int clearbot = NA;
- struct NameList sublist;
- int viewoffset = 0;
-
- NameList_init(&sublist);
-
- NameList_sublist(namelist, &sublist, "");
- temp = data;
-
- outs(prompt);
- clrtoeol();
- getyx(&y, &x);
- scrx = origx = x;
- data[count] = 0;
- viewoffset = 0;
-
- while (1)
- {
- // print input field
- move(y, scrx); outc(' '); clrtoeol(); move(y, scrx);
- outs(ANSI_COLOR(7));
- prints("%-*s", IDLEN + 1, data);
- outs(ANSI_RESET);
- move(y, scrx + count);
-
- // get input
- if ((ch = igetch()) == EOF)
- break;
-
- if (ch == '\n' || ch == '\r') {
- *temp = '\0';
- if (NameList_length(&sublist)==1)
- strcpy(data, NameList_get(&sublist, 0));
- else if (!NameList_search(&sublist, data))
- data[0] = '\0';
- NameList_delete(&sublist);
- break;
- }
- if (ch == ' ') {
- int col, len;
-
- if (NameList_length(&sublist) == 1) {
- strcpy(data, NameList_get(&sublist, 0));
- count = strlen(data);
- temp = data + count;
- continue;
- }
- clearbot = YEA;
- col = 0;
- len = NameList_MaxLen(&sublist, viewoffset, p_lines);
- move(2, 0);
- clrtobot();
- printdash("¬ÛÃö¸ê°T¤@Äýªí", 0);
- while (len + col < t_columns) {
- int i;
-
- for (i = p_lines; viewoffset < NameList_length(&sublist) && (i > 0); i--) {
- move(3 + (p_lines - i), col);
- outs(NameList_get(&sublist, viewoffset));
- viewoffset++;
- }
- col += len + 2;
- if (viewoffset == NameList_length(&sublist)) {
- viewoffset = 0;
- break;
- }
- len = NameList_MaxLen(&sublist, viewoffset, p_lines);
- }
- if (viewoffset < NameList_length(&sublist)) {
- vmsg(msg_more);
- }
- continue;
- }
- if (ch == '\177' || ch == '\010') {
- if (temp == data)
- continue;
- temp--;
- count--;
- *temp = '\0';
- NameList_sublist(namelist, &sublist, data);
- viewoffset = 0;
- continue;
- }
- if (count < STRLEN && isprint(ch)) {
- struct NameList tmplist;
- NameList_init(&tmplist);
-
- *temp++ = ch;
- count++;
- *temp = '\0';
-
- NameList_sublist(&sublist, &tmplist, data);
- if (NameList_length(&tmplist)==0) {
- NameList_delete(&tmplist);
- temp--;
- *temp = '\0';
- count--;
- continue;
- }
- NameList_delete(&sublist);
- sublist = tmplist;
- viewoffset = 0;
- }
- }
- if (ch == EOF)
- /* longjmp(byebye, -1); */
- raise(SIGHUP); /* jochang: don't know if this is
- * necessary... */
- outc('\n');
- if (clearbot) {
- move(2, 0);
- clrtobot();
- }
- if (*data) {
- move(y, origx);
- outs(data);
- outc('\n');
- }
-}
-
-void
-usercomplete(const char *prompt, char *data)
-{
- char *temp;
- char *cwbuf, *cwlist;
- int cwnum, x, y, origx, scrx;
- int clearbot = NA, count = 0, morenum = 0;
- char ch;
- int dashdirty = 0;
-
- /* TODO ¸`¬Ù°O¾ÐÅé. (¤£¹L³o­Ó function ¤£±`¥e°O¾ÐÅé...) */
- cwbuf = malloc(MAX_USERS * (IDLEN + 1));
- cwlist = u_namearray((arrptr) cwbuf, &cwnum, "");
- temp = data;
-
- outs(prompt);
- clrtoeol();
- getyx(&y, &x);
- scrx = origx = x;
- data[count] = 0;
-
- while (1)
- {
- // print input field again
- move(y, scrx); outc(' '); clrtoeol(); move(y, scrx);
- outs(ANSI_COLOR(7));
- prints("%-*s", IDLEN + 1, data);
- outs(ANSI_RESET);
- move(y, scrx + count);
-
- // get input
- if ((ch = igetch()) == EOF)
- break;
-
- if (ch == '\n' || ch == '\r') {
- int i;
- char *ptr;
-
- *temp = '\0';
- outc('\n');
- ptr = cwlist;
- for (i = 0; i < cwnum; i++) {
- if (strncasecmp(data, ptr, IDLEN + 1) == 0) {
- strcpy(data, ptr);
- break;
- }
- ptr += IDLEN + 1;
- }
- if (i == cwnum)
- data[0] = '\0';
- break;
-
- } else if (ch == '\177' || ch == '\010') {
- if (temp == data)
- continue;
- temp--;
- count--;
- *temp = '\0';
- cwlist = u_namearray((arrptr) cwbuf, &cwnum, data);
- morenum = 0;
- continue;
-
- } else if (!(count <= IDLEN && isprint((int)ch))) {
-
- /* invalid input */
- continue;
-
- } else if (ch != ' ') {
-
- int n;
-
- *temp++ = ch;
- *temp = '\0';
- n = UserSubArray((arrptr) cwbuf, (arrptr) cwlist, cwnum, ch, count);
-
- if (n > 0) {
- /* found something */
- cwlist = cwbuf;
- count++;
- cwnum = n;
- morenum = 0;
- continue;
- }
- /* no break, no continue, list later. */
- }
-
- /* finally, list available users. */
- {
- int col, len;
-
- if (ch == ' ' && cwnum == 1) {
- if(dashdirty)
- {
- move(2,0);
- clrtoeol();
- printdash(cwlist, 0);
- }
- strcpy(data, cwlist);
- count = strlen(data);
- temp = data + count;
- continue;
- }
-
- clearbot = YEA;
- col = 0;
-
- len = UserMaxLen((arrptr) cwlist, cwnum, morenum, p_lines);
- move(2, 0);
- clrtobot();
- printdash("¨Ï¥ÎªÌ¥N¸¹¤@Äýªí", 0);
- dashdirty = 0;
-
- if(ch != ' ')
- {
- /* no such user */
- move(2,0);
- outs("- ¥Ø«eµL¨Ï¥ÎªÌ ");
- outs(data);
- outs(" ");
- temp--;
- *temp = '\0';
- dashdirty = 1;
- }
-
- while (len + col < t_columns-1) {
-
- int i;
-
- for (i = 0; morenum < cwnum && i < p_lines; i++) {
- move(3 + i, col);
- prints("%.*s ", IDLEN,
- cwlist + (IDLEN + 1) * morenum++);
- }
- col += len + 2;
- if (morenum >= cwnum)
- break;
- len = UserMaxLen((arrptr) cwlist, cwnum, morenum, p_lines);
- }
- if (morenum < cwnum) {
- move(b_lines, 0); clrtoeol();
- outs(msg_more);
- // vmsg(msg_more);
- } else
- morenum = 0;
-
- continue;
- }
- }
- free(cwbuf);
- if (ch == EOF)
- /* longjmp(byebye, -1); */
- raise(SIGHUP); /* jochang: don't know if this is necessary */
- outc('\n');
- if (clearbot) {
- move(2, 0);
- clrtobot();
- }
- if (*data) {
- move(y, origx);
- outs(data);
- outc('\n');
- }
-}
-
-static int
-gnc_findbound(char *str, int *START, int *END,
- size_t nmemb, gnc_comp_func compar)
-{
- int start, end, mid, cmp, strl;
- strl = strlen(str);
-
- start = -1, end = nmemb - 1;
- /* The first available element is always in the half-open interval
- * (start, end]. (or `end'-th it self if start == end) */
- while (end > start + 1) {
- mid = (start + end) / 2;
- cmp = (*compar)(mid, str, strl);
- if (cmp >= 0)
- end = mid;
- else
- start = mid;
- }
- if ((*compar)(end, str, strl) != 0) {
- *START = *END = -1;
- return -1;
- }
- *START = end;
-
- start = end;
- end = nmemb;
- /* The last available element is always in the half-open interval
- * [start, end). (or `start'-th it self if start == end) */
- while (end > start + 1) {
- mid = (start + end) / 2;
- cmp = (*compar)(mid, str, strl);
- if (cmp <= 0)
- start = mid;
- else
- end = mid;
- }
- *END = start;
- return 0;
-}
-
-static int
-gnc_complete(char *data, int *start, int *end,
- gnc_perm_func permission, gnc_getname_func getname)
-{
- int i, count, first = -1, last = *end;
- if (*start < 0 || *end < 0)
- return 0;
- for (i = *start, count = 0; i <= *end; ++i)
- if ((*permission)(i)) {
- if (first == -1)
- first = i;
- last = i;
- ++count;
- }
- if (count == 1)
- strcpy(data, (*getname)(first));
-
- *start = first;
- *end = last;
- return count;
-}
-
-
-int
-generalnamecomplete(const char *prompt, char *data, int len, size_t nmemb,
- gnc_comp_func compar, gnc_perm_func permission,
- gnc_getname_func getname)
-{
- int x, y, origx, scrx, ch, i, morelist = -1, col, ret = -1;
- int start, end, ptr;
- int clearbot = NA;
-
- outs(prompt);
- clrtoeol();
- getyx(&y, &x);
- scrx = origx = x;
-
- ptr = 0;
- data[ptr] = 0;
-
- start = 0; end = nmemb - 1;
- while (1)
- {
- // print input field again
- move(y, scrx); outc(' '); clrtoeol(); move(y, scrx);
- outs(ANSI_COLOR(7));
- // data[ptr] = 0;
- prints("%-*s", len, data);
- outs(ANSI_RESET);
- move(y, scrx + ptr);
-
- // get input
- if ((ch = igetch()) == EOF)
- break;
-
- if (ch == '\n' || ch == '\r') {
- data[ptr] = 0;
- outc('\n');
- if (ptr != 0) {
- gnc_findbound(data, &start, &end, nmemb, compar);
- if (gnc_complete(data, &start, &end, permission, getname)
- == 1 || (*compar)(start, data, len) == 0) {
- strcpy(data, (*getname)(start));
- ret = start;
- } else {
- data[0] = '\n';
- ret = -1;
- }
- } else
- ptr = -1;
- break;
- } else if (ch == ' ') {
- if (morelist == -1) {
- if (gnc_findbound(data, &start, &end, nmemb, compar) == -1)
- continue;
- i = gnc_complete(data, &start, &end, permission, getname);
- if (i == 1) {
- ptr = strlen(data);
- continue;
- } else {
- char* first = (*getname)(start);
- i = ptr;
- while (first[i] && (*compar)(end, first, i + 1) == 0) {
- data[i] = first[i];
- ++i;
- }
- data[i] = '\0';
-
- if (i != ptr) { /* did complete several words */
- ptr = i;
- }
- }
- morelist = start;
- } else if (morelist > end)
- continue;
- clearbot = YEA;
- move(2, 0);
- clrtobot();
- printdash("¬ÛÃö¸ê°T¤@Äýªí", 0);
-
- col = 0;
- while (len + col < t_columns-1) {
- for (i = 0; morelist <= end && i < p_lines; ++morelist) {
- if ((*permission)(morelist)) {
- move(3 + i, col);
- prints("%s ", (*getname)(morelist));
- ++i;
- }
- }
-
- col += len + 2;
- }
- if (morelist != end + 1) {
- vmsg(msg_more);
- }
- continue;
-
- } else if (ch == '\177' || ch == '\010') { /* backspace */
- if (ptr == 0)
- continue;
- morelist = -1;
- --ptr;
- data[ptr] = 0;
- continue;
- } else if (isprint(ch) && ptr <= (len - 2)) {
- morelist = -1;
- data[ptr] = ch;
- ++ptr;
- data[ptr] = 0;
- if (gnc_findbound(data, &start, &end, nmemb, compar) < 0)
- data[--ptr] = 0;
- else {
- for (i = start; i <= end; ++i)
- if ((*permission)(i))
- break;
- if (i == end + 1)
- data[--ptr] = 0;
- }
- }
- }
-
- outc('\n');
- if (clearbot) {
- move(2, 0);
- clrtobot();
- }
- if (*data) {
- move(y, origx);
- outs(data);
- outc('\n');
- }
- return ret;
-}
-
-/* general complete functions (brdshm) */
-int
-completeboard_compar(int where, const char *str, int len)
-{
- boardheader_t *bh = &bcache[SHM->bsorted[0][where]];
- return strncasecmp(bh->brdname, str, len);
-}
-
-int
-completeboard_permission(int where)
-{
- boardheader_t *bptr = &bcache[SHM->bsorted[0][where]];
- return (!(bptr->brdattr & BRD_SYMBOLIC) &&
- (GROUPOP() || HasBoardPerm(bptr)) &&
- !(bptr->brdattr & BRD_GROUPBOARD));
-}
-
-int
-complete_board_and_group_permission(int where)
-{
- boardheader_t *bptr = &bcache[SHM->bsorted[0][where]];
- return (!(bptr->brdattr & BRD_SYMBOLIC) &&
- (GROUPOP() || HasBoardPerm(bptr)));
-
-}
-
-char *
-completeboard_getname(int where)
-{
- return bcache[SHM->bsorted[0][where]].brdname;
-}
-
-/* general complete functions (utmpshm) */
-int
-completeutmp_compar(int where, const char *str, int len)
-{
- userinfo_t *u = &SHM->uinfo[SHM->sorted[SHM->currsorted][0][where]];
- return strncasecmp(u->userid, str, len);
-}
-
-int
-completeutmp_permission(int where)
-{
- userinfo_t *u = &SHM->uinfo[SHM->sorted[SHM->currsorted][0][where]];
- return (unlikely(HasUserPerm(PERM_SYSOP)) ||
- unlikely(HasUserPerm(PERM_SEECLOAK)) ||
-// !SHM->sorted[SHM->currsorted][0][where]->invisible);
- isvisible(currutmp, u));
-}
-
-char *
-completeutmp_getname(int where)
-{
- return SHM->uinfo[SHM->sorted[SHM->currsorted][0][where]].userid;
-}
diff --git a/mbbsd/osdep.c b/mbbsd/osdep.c
deleted file mode 100644
index f4a9bd85..00000000
--- a/mbbsd/osdep.c
+++ /dev/null
@@ -1,643 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-#ifdef NEED_STRLCAT
-
-#include <sys/types.h>
-#include <string.h>
-
-/* size_t
- * strlcat(char *dst, const char *src, size_t size);
- */
-/*
- * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
- * All rights reserved.
- *
- * 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.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``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 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.
- */
-
-/*
- * Appends src to string dst of size siz (unlike strncat, siz is the
- * full size of dst, not space left). At most siz-1 characters
- * will be copied. Always NUL terminates (unless siz <= strlen(dst)).
- * Returns strlen(src) + MIN(siz, strlen(initial dst)).
- * If retval >= siz, truncation occurred.
- */
-size_t
-strlcat(dst, src, siz)
- char *dst;
- const char *src;
- size_t siz;
-{
- char *d = dst;
- const char *s = src;
- size_t n = siz;
- size_t dlen;
-
- /* Find the end of dst and adjust bytes left but don't go past end */
- while (n-- != 0 && *d != '\0')
- d++;
- dlen = d - dst;
- n = siz - dlen;
-
- if (n == 0)
- return(dlen + strlen(s));
- while (*s != '\0') {
- if (n != 1) {
- *d++ = *s;
- n--;
- }
- s++;
- }
- *d = '\0';
-
- return(dlen + (s - src)); /* count does not include NUL */
-}
-
-#endif
-
-#ifdef NEED_TIMEGM
-
-#include <time.h>
-#include <stdlib.h>
-
-time_t timegm (struct tm *tm)
-{
- time_t ret;
- char *tz;
-
- tz = getenv("TZ");
- putenv("TZ=");
- tzset();
- ret = mktime(tm);
-
- if (tz){
- char *buff = malloc( strlen(tz) + 10);
- sprintf( buff, "TZ=%s", tz);
- putenv(buff);
- free(buff);
- }
- else
- unsetenv("TZ");
- tzset();
-
- return ret;
-}
-
-#endif
-
-#ifdef NEED_STRLCPY
-
-/* ------------------------------------------------------------------------ */
-
-/* size_t
- * strlcpy(char *dst, const char *src, size_t size);
- */
-
-/*
- * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
- * All rights reserved.
- *
- * 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.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``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 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.
- */
-
-/*
- * Copy src to string dst of size siz. At most siz-1 characters
- * will be copied. Always NUL terminates (unless siz == 0).
- * Returns strlen(src); if retval >= siz, truncation occurred.
- */
-size_t strlcpy(dst, src, siz)
- char *dst;
- const char *src;
- size_t siz;
-{
- char *d = dst;
- const char *s = src;
- size_t n = siz;
-
- /* Copy as many bytes as will fit */
- if (n != 0 && --n != 0) {
- do {
- if ((*d++ = *s++) == 0)
- break;
- } while (--n != 0);
- }
-
- /* Not enough room in dst, add NUL and traverse rest of src */
- if (n == 0) {
- if (siz != 0)
- *d = '\0'; /* NUL-terminate dst */
- while (*s++)
- ;
- }
-
- return(s - src - 1); /* count does not include NUL */
-}
-
-#endif
-
-#ifdef NEED_STRCASESTR
-
-char *
-strcasestr(const char *big, const char *little)
-{
- char *ans = (char *)big;
- int len = strlen(little);
- char *endptr = (char *)big + strlen(big) - len;
-
- while (ans <= endptr)
- if (!strncasecmp(ans, little, len))
- return ans;
- else
- ans++;
- return 0;
-}
-
-#endif
-
-#ifdef NEED_SCANDIR
-
-/*
- * Scan the directory dirname calling select to make a list of selected
- * directory entries then sort using qsort and compare routine dcomp.
- * Returns the number of entries and a pointer to a list of pointers to
- * struct dirent (through namelist). Returns -1 if there were any errors.
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <stdlib.h>
-#include <string.h>
-
-/*
- * The DIRSIZ macro is the minimum record length which will hold the directory
- * entry. This requires the amount of space in struct dirent without the
- * d_name field, plus enough space for the name and a terminating nul byte
- * (dp->d_namlen + 1), rounded up to a 4 byte boundary.
- */
-#undef DIRSIZ
-#define DIRSIZ(dp) \
- ((sizeof(struct dirent) - sizeof(dp)->d_name) + \
- ((strlen((dp)->d_name) + 1 + 3) &~ 3))
-#if 0
-((sizeof(struct dirent) - sizeof(dp)->d_name) + \
- (((dp)->d_namlen + 1 + 3) &~ 3))
-#endif
-
-int
-scandir(dirname, namelist, select, dcomp)
- const char *dirname;
- struct dirent ***namelist;
- int (*select) (struct dirent *);
- int (*dcomp) (const void *, const void *);
-{
- register struct dirent *d, *p, **names;
- register size_t nitems;
- struct stat stb;
- long arraysz;
- DIR *dirp;
-
- if ((dirp = opendir(dirname)) == NULL)
- return(-1);
- if (fstat(dirp->dd_fd, &stb) < 0)
- return(-1);
-
- /*
- * estimate the array size by taking the size of thedirectory file
- * and dividing it by a multiple of the minimum sizeentry.
- */
- arraysz = (stb.st_size / 24);
- names = (struct dirent **)malloc(arraysz * sizeof(struct dirent *));
- if (names == NULL)
- return(-1);
-
- nitems = 0;
- while ((d = readdir(dirp)) != NULL) {
- if (select != NULL && !(*select)(d))
- continue; /* just selected names */
- /*
- * Make a minimum size copy of the data
- */
- p = (struct dirent *)malloc(DIRSIZ(d));
- if (p == NULL)
- return(-1);
- p->d_ino = d->d_ino;
- p->d_off = d->d_off;
- p->d_reclen = d->d_reclen;
- memcpy(p->d_name, d->d_name, strlen(d->d_name) +1);
-#if 0
- p->d_fileno = d->d_fileno;
- p->d_type = d->d_type;
- p->d_reclen = d->d_reclen;
- p->d_namlen = d->d_namlen;
- bcopy(d->d_name, p->d_name, p->d_namlen + 1);
-#endif
- /*
- * Check to make sure the array has space left and
- * realloc the maximum size.
- */
- if (++nitems >= arraysz) {
- if (fstat(dirp->dd_fd, &stb) < 0)
- return(-1); /* just might have grown */
- arraysz = stb.st_size / 12;
- names = (struct dirent **)realloc((char*)names,
- arraysz * sizeof(struct dirent*));
- if (names == NULL)
- return(-1);
- }
- names[nitems-1] = p;
- }
- closedir(dirp);
- if (nitems && dcomp != NULL)
- qsort(names, nitems, sizeof(struct dirent *),dcomp);
- *namelist = names;
- return(nitems);
-}
-
-/*
- * Alphabetic order comparison routine for those who want it.
- */
-int
-alphasort(d1, d2)
- const void *d1;
- const void *d2;
-{
- return(strcmp((*(struct dirent **)d1)->d_name,
- (*(struct dirent **)d2)->d_name));
-}
-
-#endif
-
-#ifdef NEED_FLOCK
-
-int
-flock (int fd, int f)
-{
- if( f == LOCK_EX )
- return lockf(fd, F_LOCK, 0L);
-
- if( f == LOCK_UN )
- return lockf(fd, F_ULOCK, 0L);
-
- return -1;
-}
-
-#endif
-
-#ifdef NEED_UNSETENV
-
-void
-unsetenv(name)
- char *name;
-{
- extern char **environ;
- register char **pp;
- int len = strlen(name);
-
- for (pp = environ; *pp != NULL; pp++)
- {
- if (strncmp(name, *pp, len) == 0 &&
- ((*pp)[len] == '=' || (*pp)[len] == '\0'))
- break;
- }
-
- for (; *pp != NULL; pp++)
- *pp = pp[1];
-}
-
-#endif
-
-#ifdef NEED_INET_PTON
-
-#include <arpa/nameser.h>
-
-/*
- * Copyright (c) 1996 by Internet Software Consortium.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
- * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
-int
-inet_pton(int af, const char *src, void *dst)
-{
- static const char digits[] = "0123456789";
- int saw_digit, octets, ch;
- u_char tmp[INADDRSZ], *tp;
-
- saw_digit = 0;
- octets = 0;
- *(tp = tmp) = 0;
- while ((ch = *src++) != '\0') {
- const char *pch;
-
- if ((pch = strchr(digits, ch)) != NULL) {
- u_int new = *tp * 10 + (pch - digits);
-
- if (new > 255)
- return (0);
- *tp = new;
- if (! saw_digit) {
- if (++octets > 4)
- return (0);
- saw_digit = 1;
- }
- } else if (ch == '.' && saw_digit) {
- if (octets == 4)
- return (0);
- *++tp = 0;
- saw_digit = 0;
- } else
- return (0);
- }
- if (octets < 4)
- return (0);
-
- memcpy(dst, tmp, INADDRSZ);
-
- return (1);
-}
-#endif
-
-#ifdef NEED_BSD_SIGNAL
-
-void (*bsd_signal(int sig, void (*func)(int)))(int)
-{
- struct sigaction act, oact;
-
- act.sa_handler = func;
- act.sa_flags = SA_RESTART;
- sigemptyset(&act.sa_mask);
- sigaddset(&act.sa_mask, sig);
- if (sigaction(sig, &act, &oact) == -1)
- return(SIG_ERR);
- return(oact.sa_handler);
-}
-
-
-#endif
-
-
-#ifdef Solaris
-
-#include <sys/stat.h>
-#include <sys/swap.h>
-
-
-double swapused(int *total, int *used)
-{
- double percent = -1;
- register int cnt, i;
- register int free;
- struct swaptable *swt;
- struct swapent *ste;
- static char path[256]; // does it really need 'static' ?
- cnt = swapctl(SC_GETNSWP, 0);
- swt = (struct swaptable *)malloc(sizeof(int) +
- cnt * sizeof(struct swapent));
- if (swt == NULL)
- {
- return 0;
- }
- swt->swt_n = cnt;
-
- /* fill in ste_path pointers: we don't care about the paths, so we point
- them all to the same buffer */
- ste = &(swt->swt_ent[0]);
- i = cnt;
- while (--i >= 0)
- {
- ste++->ste_path = path;
- }
- /* grab all swap info */
- swapctl(SC_LIST, swt);
-
- /* walk thru the structs and sum up the fields */
- *total = free = 0;
- ste = &(swt->swt_ent[0]);
- i = cnt;
- while (--i >= 0)
- {
- /* dont count slots being deleted */
- if (!(ste->ste_flags & ST_INDEL) &&
- !(ste->ste_flags & ST_DOINGDEL))
- {
- *total += ste->ste_pages;
- free += ste->ste_free;
- }
- ste++;
- }
-
- *used = *total - free;
- if( total != 0)
- percent = (double)*used / (double)*total;
- else
- percent = 0;
-
- return percent;
-}
-#endif
-
-#if __FreeBSD__
-
-#include <kvm.h>
-
-
-double
-swapused(int *total, int *used)
-{
- double percent = -1;
- kvm_t *kd;
- struct kvm_swap swapinfo;
- int pagesize;
-
- kd = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL);
- if (kd) {
- if (kvm_getswapinfo(kd, &swapinfo, 1, 0) == 0) {
- pagesize = getpagesize();
- *total = swapinfo.ksw_total * pagesize;
- *used = swapinfo.ksw_used * pagesize;
- if (*total != 0)
- percent = (double)*used / (double)*total;
- }
- kvm_close(kd);
- }
- return percent;
-}
-
-#endif
-
-#if __FreeBSD__
-
-int
-cpuload(char *str)
-{
- double l[3] = {-1, -1, -1};
- if (getloadavg(l, 3) != 3)
- l[0] = -1;
-
- if (str) {
- if (l[0] != -1)
- sprintf(str, " %.2f %.2f %.2f", l[0], l[1], l[2]);
- else
- strcpy(str, " (unknown) ");
- }
- return (int)l[0];
-}
-#endif
-
-
-#ifdef Solaris
-
-#include <kstat.h>
-#include <sys/param.h>
-
-#define loaddouble(la) ((double)(la) / FSCALE)
-
-int
-cpuload(char *str)
-{
- kstat_ctl_t *kc;
- kstat_t *ks;
- kstat_named_t *kn;
- double l[3] = {-1, -1, -1};
-
- kc = kstat_open();
-
- if( !kc ){
- strcpy(str, "(unknown) ");
- return -1;
- }
-
- ks = kstat_lookup( kc, "unix", 0, "system_misc");
-
- if( kstat_read( kc, ks, 0) == -1){
- strcpy( str, "( unknown ");
- return -1;
- }
-
- kn = kstat_data_lookup( ks, "avenrun_1min" );
-
- if( kn ) {
- l[0] = loaddouble(kn->value.ui32);
- }
-
- kn = kstat_data_lookup( ks, "avenrun_5min" );
-
- if( kn ) {
- l[1] = loaddouble(kn->value.ui32);
- }
-
- kn = kstat_data_lookup( ks, "avenrun_15min" );
-
- if( kn ) {
- l[2] = loaddouble(kn->value.ui32);
- }
-
- if (str) {
-
- if (l[0] != -1)
- sprintf(str, " %.2f %.2f %.2f", l[0], l[1], l[2]);
- else
- strcpy(str, " (unknown) ");
- }
-
- kstat_close(kc);
- return (int)l[0];
-}
-
-#endif
-
-#ifdef __linux__
-int
-cpuload(char *str)
-{
- double l[3] = {-1, -1, -1};
- FILE *fp;
-
- if ((fp = fopen("/proc/loadavg", "r"))) {
- if (fscanf(fp, "%lf %lf %lf", &l[0], &l[1], &l[2]) != 3)
- l[0] = -1;
- fclose(fp);
- }
- if (str) {
- if (l[0] != -1)
- sprintf(str, " %.2f %.2f %.2f", l[0], l[1], l[2]);
- else
- strcpy(str, " (unknown) ");
- }
- return (int)l[0];
-}
-
-double
-swapused(int *total, int *used)
-{
- double percent = -1;
- char buf[101];
- FILE *fp;
-
- if ((fp = fopen("/proc/meminfo", "r"))) {
- while (fgets(buf, 100, fp) && strstr(buf, "SwapTotal:") == NULL);
- sscanf(buf, "%*s %d", total);
- fgets(buf, 100, fp);
- sscanf(buf, "%*s %d", used);
- *used = *total - *used;
- if (*total != 0)
- percent = (double)*used / (double)*total;
- fclose(fp);
- }
- return percent;
-}
-
-#endif
diff --git a/mbbsd/othello.c b/mbbsd/othello.c
deleted file mode 100644
index 99dd4794..00000000
--- a/mbbsd/othello.c
+++ /dev/null
@@ -1,577 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-#define LOGFILE "etc/othello.log"
-#define SECRET "etc/othello.secret"
-#define NR_TABLE 2
-
-#define true 1
-#define false 0
-#define STARTX 3
-#define STARTY 20
-#define NONE_CHESS " "
-#define WHITE_CHESS "¡´"
-#define BLACK_CHESS "¡³"
-#define HINT_CHESS "¡­"
-#define NONE 0
-#define HINT 1
-#define BLACK 2
-#define WHITE 3
-
-#define INVERT(COLOR) (((COLOR))==WHITE?BLACK:WHITE)
-
-struct OthelloData {
- char nowx, nowy;
- char number[2];
-
- char pass;
- char if_hint;
- int think, which_table;
-
- char nowboard[10][10];
- char evaltable[NR_TABLE + 1][10][10];
-};
-
-static const char *CHESS_TYPE[] = {NONE_CHESS, HINT_CHESS, BLACK_CHESS, WHITE_CHESS};
-static const char DIRX[] = {-1, -1, -1, 0, 1, 1, 1, 0};
-static const char DIRY[] = {-1, 0, 1, 1, 1, 0, -1, -1};
-static const char init_table[NR_TABLE + 1][5][5] = {
- {{0, 0, 0, 0, 0},
- {0, 30, -3, 2, 2},
- {0, -3, -3, -1, -1},
- {0, 2, -1, 1, 1},
- {0, 2, -1, 1, 0}},
-
- {{0, 0, 0, 0, 0},
- {0, 70, 5, 20, 30},
- {0, 5, -5, 3, 3},
- {0, 20, 3, 5, 5},
- {0, 30, 3, 5, 5}},
-
- {{0, 0, 0, 0, 0},
- {0, 5, 2, 2, 2},
- {0, 2, 1, 1, 1},
- {0, 2, 1, 1, 1},
- {0, 2, 1, 1, 1}}
-};
-
-static void
-print_chess(struct OthelloData *od, int x, int y, char chess)
-{
- move(STARTX - 1 + x * 2, STARTY - 2 + y * 4);
- if (chess != HINT || od->if_hint == 1)
- outs(CHESS_TYPE[(int)chess]);
- else
- outs(CHESS_TYPE[NONE]);
- refresh();
-}
-
-static void
-printboard(struct OthelloData *od)
-{
- int i;
-
- move(STARTX, STARTY);
- outs("¢z¢w¢s¢w¢s¢w¢s¢w¢s¢w¢s¢w¢s¢w¢s¢w¢{");
- for (i = 0; i < 7; i++) {
- move(STARTX + 1 + i * 2, STARTY);
- outs("¢x ¢x ¢x ¢x ¢x ¢x ¢x ¢x ¢x");
- move(STARTX + 2 + i * 2, STARTY);
- outs("¢u¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢t");
- }
- move(STARTX + 1 + i * 2, STARTY);
- outs("¢x ¢x ¢x ¢x ¢x ¢x ¢x ¢x ¢x");
- move(STARTX + 2 + i * 2, STARTY);
- outs("¢|¢w¢r¢w¢r¢w¢r¢w¢r¢w¢r¢w¢r¢w¢r¢w¢}");
- print_chess(od, 4, 4, WHITE);
- print_chess(od, 5, 5, WHITE);
- print_chess(od, 4, 5, BLACK);
- print_chess(od, 5, 4, BLACK);
- move(3, 56);
- prints("(¶Â)%s", cuser.userid);
- move(3, 72);
- outs(": 02");
- move(4, 56);
- outs("(¥Õ)¹q¸£ : 02");
- move(6, 56);
- outs("¡­ ¥i¥H¤U¤§³B");
- move(7, 56);
- outs("[q] °h¥X");
- move(8, 56);
- outs("[h] ¶}±Ò/Ãö³¬ ´£¥Ü");
- move(9, 56);
- outs("[Enter][Space] ¤U´Ñ");
- move(10, 56);
- outs("¤W:¡ô, i");
- move(11, 56);
- outs("¤U:¡õ, k");
- move(12, 56);
- outs("¥ª:¡ö, j");
- move(13, 56);
- outs("¥k:¡÷, l");
-}
-
-static int
-get_key(struct OthelloData *od, int x, int y)
-{
- int ch;
-
- move(STARTX - 1 + x * 2, STARTY - 1 + y * 4);
- ch = igetch();
- move(STARTX - 1 + x * 2, STARTY - 2 + y * 4);
- if (od->nowboard[x][y] != HINT || od->if_hint == 1)
- outs(CHESS_TYPE[(int)od->nowboard[x][y]]);
- else
- outs(CHESS_TYPE[NONE]);
- return ch;
-}
-
-static int
-eatline(int i, int j, char color, int dir, char chessboard[][10])
-{
- int tmpx, tmpy;
- char tmpchess;
-
- tmpx = i + DIRX[dir];
- tmpy = j + DIRY[dir];
- tmpchess = chessboard[tmpx][tmpy];
- if (tmpchess == -1)
- return false;
- if (tmpchess != INVERT(color))
- return false;
-
- tmpx += DIRX[dir];
- tmpy += DIRY[dir];
- tmpchess = chessboard[tmpx][tmpy];
- while (tmpchess != -1) {
- if (tmpchess < BLACK)
- return false;
- if (tmpchess == color) {
- while (i != tmpx || j != tmpy) {
- chessboard[i][j] = color;
- i += DIRX[dir];
- j += DIRY[dir];
- }
- return true;
- }
- tmpx += DIRX[dir];
- tmpy += DIRY[dir];
- tmpchess = chessboard[tmpx][tmpy];
- }
- return false;
-}
-
-static int
-if_can_put(int x, int y, char color, char chessboard[][10])
-{
- int i, temp, checkx, checky;
-
- if (chessboard[x][y] < BLACK)
- for (i = 0; i < 8; i++) {
- checkx = x + DIRX[i];
- checky = y + DIRY[i];
- temp = chessboard[checkx][checky];
- if (temp < BLACK)
- continue;
- if (temp != color)
- while (chessboard[checkx += DIRX[i]][checky += DIRY[i]] > HINT)
- if (chessboard[checkx][checky] == color)
- return true;
- }
- return false;
-}
-
-static int
-get_hint(struct OthelloData *od, char color)
-{
- int i, j, temp = 0;
-
- for (i = 1; i <= 8; i++)
- for (j = 1; j <= 8; j++) {
- if (od->nowboard[i][j] == HINT)
- od->nowboard[i][j] = NONE;
- if (if_can_put(i, j, color, od->nowboard)) {
- od->nowboard[i][j] = HINT;
- temp++;
- }
- print_chess(od, i, j, od->nowboard[i][j]);
- }
- return temp;
-}
-
-static void
-eat(int x, int y, int color, char chessboard[][10])
-{
- int k;
-
- for (k = 0; k < 8; k++)
- eatline(x, y, color, k, chessboard);
-}
-
-static void
-end_of_game(struct OthelloData *od, int quit)
-{
- FILE *fp, *fp1;
- char *opponent[] = {"", "CD-65", "", "À¦¨à", "¤p«Ä", "", "¤j¤H", "±M®a"};
-
- move(STARTX - 1, 30);
- outs(" ");
- move(22, 35);
- fp = fopen(LOGFILE, "a");
- if (!quit) {
- fp1 = fopen(SECRET, "a");
- if (fp1) {
- fprintf(fp1, "%d,%d,%s,%02d,%02d\n", od->think, od->which_table,
- cuser.userid, od->number[0], od->number[1]);
- fclose(fp1);
- }
- }
- if (quit) {
- if (od->number[0] == 2 && od->number[1] == 2) {
- if (fp)
- fclose(fp);
- return;
- }
- fprintf(fp, "¦b%s¯Å¤¤, %sÁ{°}²æ°k\n", opponent[od->think], cuser.userid);
- if (fp)
- fclose(fp);
- return;
- }
- if (od->number[0] > od->number[1]) {
- prints("§AŤF¹q¸£%02d¤l", od->number[0] - od->number[1]);
- if (od->think == 6 && od->number[0] - od->number[1] >= 50)
- demoney(200);
- if (od->think == 7 && od->number[0] - od->number[1] >= 40)
- demoney(200);
- if (fp)
- fprintf(fp, "¦b%s¯Å¤¤, %s¥H %02d:%02d ŤF¹q¸£%02d¤l\n",
- opponent[od->think], cuser.userid, od->number[0], od->number[1],
- od->number[0] - od->number[1]);
- } else if (od->number[1] > od->number[0]) {
- prints("¹q¸£Ä¹¤F§A%02d¤l", od->number[1] - od->number[0]);
- if (fp) {
- fprintf(fp, "¦b%s¯Å¤¤, ", opponent[od->think]);
- if (od->number[1] - od->number[0] > 20)
- fprintf(fp, "¹q¸£¥H %02d:%02d ºG¹q%s %02d¤l\n", od->number[1],
- od->number[0], cuser.userid, od->number[1] - od->number[0]);
- else
- fprintf(fp, "¹q¸£¥H %02d:%02d ŤF%s %02d¤l\n", od->number[1],
- od->number[0], cuser.userid, od->number[1] - od->number[0]);
- }
- } else {
- outs("§A©M¹q¸£¥´¦¨¥­¤â!!");
- if (fp)
- fprintf(fp, "¦b%s¯Å¤¤, %s©M¹q¸£¥H %02d:%02d ¥´¦¨¤F¥­¤â\n",
- opponent[od->think], cuser.userid, od->number[1], od->number[0]);
- }
- if (fp)
- fclose(fp);
- move(1, 1);
- igetch();
-}
-
-static void
-othello_redraw(struct OthelloData *od)
-{
- int i, j;
-
- for (i = 1; i <= 8; i++)
- for (j = 1; j <= 8; j++)
- print_chess(od, i, j, od->nowboard[i][j]);
-}
-
-static int
-player(struct OthelloData *od, char color)
-{
- int ch;
-
- if (get_hint(od, color)) {
- while (true) {
- ch = get_key(od, od->nowx, od->nowy);
- switch (ch) {
- case 'J':
- case 'j':
- case KEY_LEFT:
- od->nowy--;
- break;
- case 'L':
- case 'l':
- case KEY_RIGHT:
- od->nowy++;
- break;
- case 'I':
- case 'i':
- case KEY_UP:
- od->nowx--;
- break;
- case 'K':
- case 'k':
- case KEY_DOWN:
- od->nowx++;
- break;
- case ' ':
- case '\r':
- if (od->nowboard[(int)od->nowx][(int)od->nowy] != HINT)
- break;
- od->pass = 0;
- od->nowboard[(int)od->nowx][(int)od->nowy] = color;
- eat(od->nowx, od->nowy, color, od->nowboard);
- print_chess(od, od->nowx, od->nowy, color);
- return true;
- case 'q':
- end_of_game(od, 1);
- return false;
- case 'H':
- case 'h':
- od->if_hint = od->if_hint ^ 1;
- othello_redraw(od);
- break;
- }
- if (od->nowx == 9)
- od->nowx = 1;
- if (od->nowx == 0)
- od->nowx = 8;
- if (od->nowy == 9)
- od->nowy = 1;
- if (od->nowy == 0)
- od->nowy = 8;
- }
- } else {
- od->pass++;
- if (od->pass == 1) {
- move(23, 34);
- outs("§A¥²»Ý©ñ±ó³o¤@¨B!!");
- igetch();
- move(28, 23);
- outs(" ");
- } else {
- end_of_game(od,0);
- return false;
- }
- }
- return 0;
-}
-
-static void
-init(struct OthelloData *od)
-{
- int i, j, i1, j1;
-
- memset(od, 0, sizeof(struct OthelloData));
- od->nowx = 4;
- od->nowy = 4;
- od->number[0] = od->number[1] = 2;
- for (i = 1; i <= 8; i++)
- for (j = 1; j <= 8; j++) {
- i1 = 4.5 - abs(4.5 - i);
- j1 = 4.5 - abs(4.5 - j);
- od->evaltable[0][i][j] = init_table[0][i1][j1];
- od->evaltable[1][i][j] = init_table[1][i1][j1];
- }
- memset(od->nowboard, NONE, sizeof(od->nowboard));
- for(i=0;i<10;i++)
- od->nowboard[i][0]=od->nowboard[0][i]=od->nowboard[i][9]=od->nowboard[9][i]=-1;
- od->nowboard[4][4] = od->nowboard[5][5] = WHITE;
- od->nowboard[4][5] = od->nowboard[5][4] = BLACK;
-}
-
-static void
-report(struct OthelloData *od)
-{
- int i, j;
-
- od->number[0] = od->number[1] = 0;
- for (i = 1; i <= 8; i++)
- for (j = 1; j <= 8; j++)
- if (od->nowboard[i][j] == BLACK)
- od->number[0]++;
- else if (od->nowboard[i][j] == WHITE)
- od->number[1]++;
- move(3, 60);
- outs(cuser.userid);
- move(3, 72);
- prints(": %02d", od->number[0]);
- move(4, 60);
- prints("¹q¸£ : %02d", od->number[1]);
-}
-
-static int
-EVL(struct OthelloData *od, char chessboard[][10], int color, int table_number)
-{
- int points = 0, a, b;
- for (a = 1; a <= 8; a++)
- for (b = 1; b <= 8; b++)
- if (chessboard[a][b] > HINT) {
- if (chessboard[a][b] == BLACK)
- points += od->evaltable[table_number][a][b];
- else
- points -= od->evaltable[table_number][a][b];
- }
- return ((color == BLACK) ? points : -points);
-}
-
-static int
-alphabeta(struct OthelloData *od, int alpha, int beta, int level, char chessboard[][10],
- int thinkstep, int color, int table)
-{
- int i, j, k, flag = 1;
- char tempboard[10][10];
- if (level == thinkstep + 1)
- return EVL(od, chessboard, (level & 1 ? color : ((color - 2) ^ 1) + 2),
- table);
- for (i = 1; i <= 8; i++) {
- for (j = 1; j <= 8; j++) {
- if (if_can_put(i, j, color, chessboard)) {
- flag = 0;
- memcpy(tempboard, chessboard, sizeof(char) * 100);
- eat(i, j, color, tempboard);
-
- k = alphabeta(od, alpha, beta, level + 1, tempboard, thinkstep,
- ((color - 2) ^ 1) + 2, table);
- if (((level & 1) && k > alpha))
- alpha = k;
- else if (!(level & 1) && k < beta)
- beta = k;
- if (alpha >= beta)
- break;
- }
- }
- }
- if (flag)
- return EVL(od, chessboard, color, table);
- return ((level & 1) ? alpha : beta);
-}
-
-static int
-Computer(struct OthelloData *od, int thinkstep, int table)
-{
- int i, j, maxi = 0, maxj = 0, level = 1;
- char chessboard[10][10];
- int alpha = -10000, k;
- if ((od->number[0] + od->number[1]) > 44)
- table = NR_TABLE;
- for (i = 1; i <= 8; i++)
- for (j = 1; j <= 8; j++) {
- if (if_can_put(i, j, WHITE, od->nowboard)) {
- memcpy(chessboard, od->nowboard, sizeof(char) * 100);
- eat(i, j, WHITE, chessboard);
- k = alphabeta(od, alpha, 10000, level + 1, chessboard, thinkstep,
- BLACK, table);
- if (k > alpha) {
- alpha = k;
- maxi = i;
- maxj = j;
- }
- }
- }
- if (alpha != -10000) {
- eat(maxi, maxj, WHITE, od->nowboard);
- od->pass = 0;
- od->nowx = maxi;
- od->nowy = maxj;
- } else {
- move(23, 30);
- outs("¹q¸£©ñ±ó³o¤@¨B´Ñ!!");
- od->pass++;
- if (od->pass == 2) {
- move(23, 24);
- outs(" ");
- end_of_game(od, 0);
- return false;
- }
- igetch();
- move(23, 24);
- outs(" ");
- }
- return true;
-}
-
-static int
-choose(void)
-{
- char thinkstep[2];
-
- move(2, 0);
- outs("½Ð¿ï¾ÜÃø«×:");
- move(5, 0);
- outs("[0] Â÷¶}\n");
- outs("(1) CD-65\n");/* ·Q 1 ¨B */
- outs("(2) À¦¨à\n"); /* ·Q 3 ¨B */
- outs("(3) ¤p«Ä\n"); /* ·Q 4 ¨B */
- do {
- if (getdata(4, 0, "½Ð¿ï¾Ü¤@­Ó¹ï¶H©M±z¹ï¥´:(1~3)",
- thinkstep, sizeof(thinkstep), LCECHO) == 0 ||
- thinkstep[0] == '0')
- return 0;
-
- } while (thinkstep[0] < '1' || thinkstep[0] > '3');
- clear();
- switch (thinkstep[0]) {
- case '2':
- thinkstep[0] = '3';
- break;
- case '3':
- thinkstep[0] = '4';
- break;
- default:
- thinkstep[0] = '1';
- break;
- }
- return atoi(thinkstep);
-}
-
-#define lockreturn0(unmode, state) if(lockutmpmode(unmode, state)) return 0
-
-int
-othello_main(void)
-{
- struct OthelloData *od;
-
- lockreturn0(OTHELLO, LOCK_MULTI);
-
- od=(struct OthelloData*)malloc(sizeof(struct OthelloData));
- if(od==NULL) {
- unlockutmpmode();
- return 0;
- }
-
- clear();
- init(od);
- od->think = choose();
- if (!od->think)
- {
- unlockutmpmode();
- free(od);
- return 0;
- }
- showtitle("³æ¤H¶Â¥Õ´Ñ", BBSName);
- printboard(od);
- od->which_table = random() % NR_TABLE;
- while (true) {
- move(STARTX - 1, 30);
- outs("½ü¨ì§A¤U¤F...");
- if (!player(od, BLACK))
- break;
- report(od);
- othello_redraw(od);
- if (od->number[0] + od->number[1] == 64) {
- end_of_game(od, 0);
- break;
- }
- move(STARTX - 1, 30);
- outs("¹q¸£«ä¦Ò¤¤...");
- refresh();
- if (!Computer(od, od->think, od->which_table))
- break;
- report(od);
- othello_redraw(od);
- if (od->number[0] + od->number[1] == 64) {
- end_of_game(od, 0);
- break;
- }
- }
- more(LOGFILE, YEA);
- unlockutmpmode();
- free(od);
- return 1;
-}
diff --git a/mbbsd/passwd.c b/mbbsd/passwd.c
deleted file mode 100644
index d0dd4015..00000000
--- a/mbbsd/passwd.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-static int semid = -1;
-
-#ifndef SEM_R
-#define SEM_R 0400
-#endif
-
-#ifndef SEM_A
-#define SEM_A 0200
-#endif
-
-#ifndef __FreeBSD__
-#include <sys/sem.h>
-union semun {
- int val; /* value for SETVAL */
- struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */
- unsigned short *array; /* array for GETALL & SETALL */
- struct seminfo *__buf; /* buffer for IPC_INFO */
-};
-#endif
-
-int
-passwd_init(void)
-{
- 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);
- }
- }
-
- return 0;
-}
-
-int
-passwd_update_money(int num)
-/* update money only
- Ptt: don't call it directly, call deumoney() */
-{
- int pwdfd;
- int money=moneyof(num);
- userec_t u;
- if (num < 1 || num > MAX_USERS)
- return -1;
-
- if ((pwdfd = open(fn_passwd, O_WRONLY)) < 0)
- exit(1);
- lseek(pwdfd, sizeof(userec_t) * (num - 1) +
- ((char *)&u.money - (char *)&u), SEEK_SET);
- write(pwdfd, &money, sizeof(int));
- close(pwdfd);
- return 0;
-}
-
-void
-passwd_force_update(int flag)
-{
- if(!currutmp || (currutmp->alerts & ALERT_PWD) == 0)
- return;
- currutmp->alerts &= ~flag;
-}
-
-int
-passwd_update(int num, userec_t * buf)
-{
- int pwdfd;
- if (num < 1 || num > MAX_USERS)
- return -1;
- buf->money = moneyof(num);
- if(usernum == num && currutmp && ((pwdfd = currutmp->alerts) & ALERT_PWD))
- {
- userec_t u;
- passwd_query(num, &u);
- if(pwdfd & ALERT_PWD_BADPOST)
- cuser.badpost = buf->badpost = u.badpost;
- if(pwdfd & ALERT_PWD_GOODPOST)
- cuser.goodpost = buf->goodpost = u.goodpost;
- if(pwdfd & ALERT_PWD_PERM)
- cuser.userlevel = buf->userlevel = u.userlevel;
- if(pwdfd & ALERT_PWD_JUSTIFY)
- {
- memcpy(buf->justify, u.justify, sizeof(u.justify));
- memcpy(cuser.justify, u.justify, sizeof(u.justify));
- memcpy(buf->email, u.email, sizeof(u.email));
- memcpy(cuser.email, u.email, sizeof(u.email));
- }
- currutmp->alerts &= ~ALERT_PWD;
- }
- if ((pwdfd = open(fn_passwd, O_WRONLY)) < 0)
- exit(1);
- lseek(pwdfd, sizeof(userec_t) * (num - 1), SEEK_SET);
- write(pwdfd, buf, sizeof(userec_t));
- close(pwdfd);
- return 0;
-}
-
-int
-passwd_query(int num, userec_t * buf)
-{
- int pwdfd;
- if (num < 1 || num > MAX_USERS)
- return -1;
- if ((pwdfd = open(fn_passwd, O_RDONLY)) < 0)
- exit(1);
- lseek(pwdfd, sizeof(userec_t) * (num - 1), SEEK_SET);
- read(pwdfd, buf, sizeof(userec_t));
- close(pwdfd);
- return 0;
-}
-
-int initcuser(const char *userid)
-{
- // Ptt: setup cuser and usernum here
- if(userid[0]=='\0' ||
- !(usernum = searchuser(userid, NULL)) || usernum > MAX_USERS)
- return -1;
- passwd_query(usernum, &cuser);
- return usernum;
-}
-
-int
-passwd_apply(void *ctx, int (*fptr) (void *ctx, int, userec_t *))
-{
- int i;
- userec_t user;
- for (i = 0; i < MAX_USERS; i++) {
- passwd_query(i + 1, &user);
- if ((*fptr) (ctx, i, &user) < 0)
- return -1;
- }
- return 0;
-}
-
-void
-passwd_lock(void)
-{
- struct sembuf buf = {0, -1, SEM_UNDO};
-
- if (semop(semid, &buf, 1)) {
- perror("semop");
- exit(1);
- }
-}
-
-void
-passwd_unlock(void)
-{
- struct sembuf buf = {0, 1, SEM_UNDO};
-
- if (semop(semid, &buf, 1)) {
- perror("semop");
- exit(1);
- }
-}
diff --git a/mbbsd/pfterm.c b/mbbsd/pfterm.c
deleted file mode 100644
index 65a09a62..00000000
--- a/mbbsd/pfterm.c
+++ /dev/null
@@ -1,2502 +0,0 @@
-//////////////////////////////////////////////////////////////////////////
-// pfterm environment settings
-//////////////////////////////////////////////////////////////////////////
-#ifdef _PFTERM_TEST_MAIN
-
-#define USE_PFTERM
-#define EXP_PFTERM
-#define DBCSAWARE
-#define FT_DBCS_NOINTRESC 1
-#define DBG_TEXT_FD
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <assert.h>
-
-#else
-
-#define HAVE_GRAYOUT
-#include "bbs.h"
-
-#ifdef DBCS_NOINTRESC
-// # ifdef CONVERT
-// extern int bbs_convert_type;
-// # define FT_DBCS_NOINTRESC (
-// (cuser.uflag & DBCS_NOINTRESC) ||
-// (bbs_convert_type == CONV_UTF8))
-// # else
-# define FT_DBCS_NOINTRESC (cuser.uflag & DBCS_NOINTRESC)
-// # endif
-#else
-# define FT_DBCS_NOINTRESC 0
-#endif
-
-#endif
-
-//////////////////////////////////////////////////////////////////////////
-// pfterm debug settings
-//////////////////////////////////////////////////////////////////////////
-
-// #define DBG_SHOW_DIRTY
-// #define DBG_SHOW_REPRINT // will not work if you enable SHOW_DIRTY.
-// #define DBG_DISABLE_OPTMOVE
-// #define DBG_DISABLE_REPRINT
-
-//////////////////////////////////////////////////////////////////////////
-// pmore style ansi
-// #include "ansi.h"
-//////////////////////////////////////////////////////////////////////////
-
-#ifndef PMORE_STYLE_ANSI
-#define ESC_CHR '\x1b'
-#define ESC_STR "\x1b"
-#define ANSI_COLOR(x) ESC_STR "[" #x "m"
-#define ANSI_RESET ESC_STR "[m"
-#endif // PMORE_STYLE_ANSI
-
-#ifndef ANSI_IS_PARAM
-#define ANSI_IS_PARAM(c) (c == ';' || (c >= '0' && c <= '9'))
-#endif // ANSI_IS_PARAM
-
-//////////////////////////////////////////////////////////////////////////
-// grayout advanced control
-// #include "grayout.h"
-//////////////////////////////////////////////////////////////////////////
-#ifndef GRAYOUT_DARK
-#define GRAYOUT_COLORBOLD (-2)
-#define GRAYOUT_BOLD (-1)
-#define GRAYOUT_DARK (0)
-#define GRAYOUT_NORM (1)
-#define GRAYOUT_COLORNORM (+2)
-#endif // GRAYOUT_DARK
-
-//////////////////////////////////////////////////////////////////////////
-// Typeahead
-//////////////////////////////////////////////////////////////////////////
-#ifndef TYPEAHEAD_NONE
-#define TYPEAHEAD_NONE (-1)
-#define TYPEAHEAD_STDIN (0)
-#endif // TYPEAHEAD
-
-//////////////////////////////////////////////////////////////////////////
-// pfterm: piaip's flat terminal system, a new replacement for 'screen'.
-// pfterm can also be read as "Perfect Term"
-//
-// piaip's new implementation of terminal system (term/screen) with dirty
-// map, designed and optimized for ANSI based output.
-//
-// "pfterm" is "piaip's flat terminal" or "perfect term", not "PTT's term"!!!
-// pfterm is designed for general maple-family BBS systems, not
-// specific to any branch.
-//
-// Author: Hung-Te Lin (piaip), Dec. 2007.
-//
-// Copyright(c) 2007-2008 Hung-Te Lin <piaip@csie.ntu.edu.tw>
-// All Rights Reserved.
-// You are free to use, modify, redistribute this program in any
-// non-commercial usage (including network service).
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// MAJOR IMPROVEMENTS:
-// - Interpret ANSI code and maintain a virtual terminal
-// - Dual buffer for dirty map and optimized output
-//
-// TODO AND DONE:
-// - DBCS aware and prevent interrupting DBCS [done]
-// - optimization with relative movement [done]
-// - optimization with ENTER/clrtoeol [done]
-// - ncurses-like API [done]
-// - inansistr to output escaped string [done]
-// - handle incomplete DBCS characters [done]
-// - optimization with reprint ability [done]
-// - add auto wrap control
-//
-// DEPRECATED:
-// - standout() [rework getdata() and namecomplete()]
-// - talk.c (big_picture) [rework talk.c]
-//
-//////////////////////////////////////////////////////////////////////////
-// Reference:
-// http://en.wikipedia.org/wiki/ANSI_escape_code
-// http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-048.pdf
-//////////////////////////////////////////////////////////////////////////
-
-// Experimental now
-#if defined(EXP_PFTERM) || defined(USE_PFTERM)
-
-//////////////////////////////////////////////////////////////////////////
-// pfterm Configurations
-//////////////////////////////////////////////////////////////////////////
-
-// Prevent invalid DBCS characters
-#define FTCONF_PREVENT_INVALID_DBCS
-
-// Some terminals use current attribute to erase background
-#define FTCONF_CLEAR_SETATTR
-
-// Some terminals (NetTerm, PacketSite) have bug in bolding attribute.
-#define FTCONF_WORKAROUND_BOLD
-
-// Some terminals prefer VT100 style scrolling, including Win/DOS telnet
-#undef FTCONF_USE_ANSI_SCROLL
-#undef FTCONF_USE_VT100_SCROLL
-
-// Few poor terminals do not have relative move (ABCD).
-#undef FTCONF_USE_ANSI_RELMOVE
-
-// Handling ANSI commands with 2 parameters (ex, ESC[m;nH)
-// 2: Good terminals can accept any omit format (ESC[;nH)
-// 1: Poor terminals (eg, Win/DOS telnet) can only omit 2nd (ESC[mH)
-// 0: Very few poor terminals (eg, CrazyTerm/BBMan) cannot omit any parameters
-#define FTCONF_ANSICMD2_OMIT (0)
-
-//////////////////////////////////////////////////////////////////////////
-// Flat Terminal Definition
-//////////////////////////////////////////////////////////////////////////
-
-#define FTSZ_DEFAULT_ROW (24)
-#define FTSZ_DEFAULT_COL (80)
-#define FTSZ_MIN_ROW (24)
-#define FTSZ_MAX_ROW (100)
-#define FTSZ_MIN_COL (80)
-#define FTSZ_MAX_COL (320)
-
-#define FTCHAR_ERASE (' ')
-#define FTATTR_ERASE (0x07)
-#define FTCHAR_BLANK (' ')
-#define FTATTR_DEFAULT (FTATTR_ERASE)
-#define FTCHAR_INVALID_DBCS ('?')
-// #define FTATTR_TRANSPARENT (0x80)
-
-#define FTDIRTY_CHAR (0x01)
-#define FTDIRTY_ATTR (0x02)
-#define FTDIRTY_DBCS (0x04)
-#define FTDIRTY_INVALID_DBCS (0x08)
-#define FTDIRTY_RAWMOVE (0x10)
-
-#define FTDBCS_SAFE (0) // standard DBCS
-#define FTDBCS_UNSAFE (1) // not on all systems (better do rawmove)
-#define FTDBCS_INVALID (2) // invalid
-
-#define FTCMD_MAXLEN (63) // max escape command sequence length
-#define FTATTR_MINCMD (16)
-
-#ifndef FTCONF_USE_ANSI_RELMOVE
-# define FTMV_COST (8) // always ESC[m;nH will costs avg 8 bytes
-#else
-# define FTMV_COST (5) // ESC[ABCD with ESC[m;nH costs avg 4+ bytes
-#endif
-
-//////////////////////////////////////////////////////////////////////////
-// Flat Terminal Data Type
-//////////////////////////////////////////////////////////////////////////
-
-typedef unsigned char ftchar; // primitive character type
-typedef unsigned char ftattr; // primitive attribute type
-
-//////////////////////////////////////////////////////////////////////////
-// Flat Terminal Structure
-//////////////////////////////////////////////////////////////////////////
-
-typedef struct
-{
- ftchar **cmap[2]; // character map
- ftattr **amap[2]; // attribute map
- ftchar *dmap; // dirty map
- ftchar *dcmap; // processed display map
- ftattr attr;
- int rows, cols;
- int y, x;
- int sy,sx; // stored cursor
- int mi; // map index, mi = current map and (1-mi) = old map
- int dirty;
- int scroll;
-
- // memory allocation
- int mrows, mcols;
-
- // raw terminal status
- int ry, rx;
- ftattr rattr;
-
- // typeahead
- char typeahead;
-
- // escape command
- ftchar cmd[FTCMD_MAXLEN+1];
- int szcmd;
-
-} FlatTerm;
-
-static FlatTerm ft;
-
-#ifdef _WIN32
- // sorry, we support only 80x24 on Windows now.
- HANDLE hStdout;
- COORD coordBufSize = {80, 24}, coordBufCoord = {0, 0};
- SMALL_RECT winrect = {0, 0, 79, 23};
- CHAR_INFO winbuf[80*24];
-#endif
-
-//////////////////////////////////////////////////////////////////////////
-// Flat Terminal Utility Macro
-//////////////////////////////////////////////////////////////////////////
-
-// ftattr: 0| FG(3) | BOLD(1) | BG(3) | BLINK(1) |8
-#define FTATTR_FGSHIFT (0)
-#define FTATTR_BGSHIFT (4)
-#define FTATTR_GETFG(x) ((x >> FTATTR_FGSHIFT) & 0x7)
-#define FTATTR_GETBG(x) ((x >> FTATTR_BGSHIFT) & 0x7)
-#define FTATTR_FGMASK ((ftattr)(0x7 << FTATTR_FGSHIFT))
-#define FTATTR_BGMASK ((ftattr)(0x7 << FTATTR_BGSHIFT))
-#define FTATTR_BOLD (0x08)
-#define FTATTR_BLINK (0x80)
-#define FTATTR_DEFAULT_FG (FTATTR_GETFG(FTATTR_DEFAULT))
-#define FTATTR_DEFAULT_BG (FTATTR_GETBG(FTATTR_DEFAULT))
-#define FTATTR_MAKE(f,b) (((f)<<FTATTR_FGSHIFT)|((b)<<FTATTR_BGSHIFT))
-#define FTCHAR_ISBLANK(x) ((x) == (FTCHAR_BLANK))
-
-#define FTCMAP ft.cmap[ft.mi]
-#define FTAMAP ft.amap[ft.mi]
-#define FTCROW FTCMAP[ft.y]
-#define FTAROW FTAMAP[ft.y]
-#define FTC FTCROW[ft.x]
-#define FTA FTAROW[ft.x]
-#define FTD ft.dmap
-#define FTDC ft.dcmap
-#define FTPC (FTCROW+ft.x)
-#define FTPA (FTAROW+ft.x)
-#define FTOCMAP ft.cmap[1-ft.mi]
-#define FTOAMAP ft.amap[1-ft.mi]
-
-
-// for fast checking, we use reduced range here.
-// Big5: LEAD = 0x81-0xFE, TAIL = 0x40-0x7E/0xA1-0xFE
-#define FTDBCS_ISLEAD(x) (((unsigned char)(x))>=(0x80))
-#define FTDBCS_ISTAIL(x) (((unsigned char)(x))>=(0x40))
-
-// - 0xFF is used as telnet IAC, don't use it!
-// - 0x80 is invalid for Big5.
-#define FTDBCS_ISBADLEAD(x) ((((unsigned char)(x)) == 0x80) || (((unsigned char)(x)) == 0xFF))
-
-// even faster:
-// #define FTDBCS_ISLEAD(x) (((unsigned char)(x)) & 0x80)
-// #define FTDBCS_ISTAIL(x) (((unsigned char)(x)) & ((unsigned char)~0x3F))
-
-#define FTDBCS_ISSBCSPRINT(x) \
- (((unsigned char)(x))>=' ' && ((unsigned char)(x))<0x80)
-
-#ifndef min
-#define min(x,y) (((x)<(y))?(x):(y))
-#endif
-
-#ifndef max
-#define max(x,y) (((x)>(y))?(x):(y))
-#endif
-
-#ifndef abs
-#define abs(x) (((x)>0)?(x):-(x))
-#endif
-
-#define ranged(x,vmin,vmax) (max(min(x,vmax),vmin))
-
-
-//////////////////////////////////////////////////////////////////////////
-// Flat Terminal API
-//////////////////////////////////////////////////////////////////////////
-
-//// common ncurse-like library interface
-
-// initialization
-void initscr (void);
-int resizeterm (int rows, int cols);
-int endwin (void);
-
-// attributes
-ftattr attrget (void);
-void attrset (ftattr attr);
-void attrsetfg (ftattr attr);
-void attrsetbg (ftattr attr);
-
-// cursor
-void getyx (int *y, int *x);
-void getmaxyx (int *y, int *x);
-void move (int y, int x);
-
-// clear
-void clear (void); // clrscr + move(0,0)
-void clrtoeol (void); // end of line
-void clrtobot (void);
-// clear (non-ncurses)
-void clrtoln (int ln); // clear down to ln ( excluding ln, as [y,ln) )
-void clrcurln (void); // whole line
-void clrtobeg (void); // begin of line
-void clrtohome (void);
-void clrscr (void); // clear and keep cursor untouched
-void clrregion (int r1, int r2); // clear [r1,r2], bi-directional.
-
-// window control
-void newwin (int nlines, int ncols, int y, int x);
-
-// flushing
-void refresh (void); // optimized refresh
-void doupdate (void); // optimized refresh, ignore input queue
-void redrawwin (void); // invalidate whole screen
-int typeahead (int fd);// prevent refresh if input queue is not empty
-
-// scrolling
-void scroll (void); // scroll up
-void rscroll (void); // scroll down
-void scrl (int rows);
-
-// output (ncurses flavor)
-void addch (unsigned char c); // equivalent to outc()
-void addstr (const char *s); // equivalent to outs()
-void addnstr (const char *s, int n);
-
-// output (non-ncurses)
-void outc (unsigned char c);
-void outs (const char *s);
-void outns (const char *s, int n);
-void outstr (const char *str); // prepare and print a complete string.
-void addstring (const char *str); // ncurses-like of outstr().
-
-// readback
-int instr (char *str);
-int innstr (char *str, int n); // n includes \0
-int inansistr (char *str, int n); // n includes \0
-
-// deprecated
-void standout (void);
-void standend (void);
-
-// grayout advanced control
-void grayout (int y, int end, int level);
-
-//// flat-term internal processor
-
-int fterm_inbuf (void); // raw input adapter
-void fterm_rawc (int c); // raw output adapter
-void fterm_rawnewline(void); // raw output adapter
-void fterm_rawflush (void); // raw output adapter
-void fterm_raws (const char *s);
-void fterm_rawnc (int c, int n);
-void fterm_rawnum (int arg);
-void fterm_rawcmd (int arg, int defval, char c);
-void fterm_rawcmd2 (int arg1, int arg2, int defval, char c);
-void fterm_rawattr (ftattr attr); // optimized changing attribute
-void fterm_rawclear (void);
-void fterm_rawclreol (void);
-void fterm_rawhome (void);
-void fterm_rawscroll (int dy);
-void fterm_rawcursor (void);
-void fterm_rawmove (int y, int x);
-void fterm_rawmove_opt(int y, int x);
-void fterm_rawmove_rel(int dy, int dx);
-
-int fterm_chattr (char *s, ftattr oa, ftattr na); // size(s) > FTATTR_MINCMD
-void fterm_exec (void); // execute ft.cmd
-void fterm_flippage (void);
-void fterm_dupe2bk (void);
-void fterm_markdirty (void); // mark as dirty
-int fterm_strdlen (const char *s); // length of string for display
-int fterm_prepare_str(int len);
-
-// DBCS supporting
-int fterm_DBCS_Big5(unsigned char c1, unsigned char c2);
-
-//////////////////////////////////////////////////////////////////////////
-// Flat Terminal Implementation
-//////////////////////////////////////////////////////////////////////////
-
-#define fterm_markdirty() { ft.dirty = 1; }
-
-// initialization
-
-void
-initscr(void)
-{
-#ifdef _WIN32
- hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
- SetConsoleScreenBufferSize(hStdout, coordBufSize);
- SetConsoleCursorPosition(hStdout, coordBufCoord);
-#endif
-
- memset(&ft, sizeof(ft), 0);
- ft.attr = ft.rattr = FTATTR_DEFAULT;
- resizeterm(FTSZ_DEFAULT_ROW, FTSZ_DEFAULT_COL);
-
- // clear both pages
- ft.mi = 0; clrscr();
- ft.mi = 1; clrscr();
- ft.mi = 0;
-
- // typeahead
- ft.typeahead = 1;
-
- fterm_rawclear();
- move(0, 0);
-}
-
-int
-endwin(void)
-{
- int r, mi = 0;
-
- // fterm_rawclear();
-
- for (mi = 0; mi < 2; mi++)
- {
- for (r = 0; r < ft.mrows; r++)
- {
- free(ft.cmap[mi][r]);
- free(ft.amap[mi][r]);
- }
- }
- free(ft.dmap);
- free(ft.dcmap);
- memset(&ft, sizeof(ft), 0);
- return 0;
-}
-
-int
-resizeterm(int rows, int cols)
-{
- int dirty = 0, mi = 0, i = 0;
-
- rows = ranged(rows, FTSZ_MIN_ROW, FTSZ_MAX_ROW);
- cols = ranged(cols, FTSZ_MIN_COL, FTSZ_MAX_COL);
-
- // adjust memory only for increasing buffer
- if (rows > ft.mrows || cols > ft.mcols)
- {
- for (mi = 0; mi < 2; mi++)
- {
- // allocate rows
- if (rows > ft.mrows)
- {
- ft.cmap[mi] = (ftchar**)realloc(ft.cmap[mi],
- sizeof(ftchar*) * rows);
- ft.amap[mi] = (ftattr**)realloc(ft.amap[mi],
- sizeof(ftattr*) * rows);
-
- // allocate new columns
- for (i = ft.mrows; i < rows; i++)
- {
- ft.cmap[mi][i] = (ftchar*)malloc((cols+1) * sizeof(ftchar));
- ft.amap[mi][i] = (ftattr*)malloc((cols+1) * sizeof(ftattr));
- // zero at end to prevent over-run
- ft.cmap[mi][i][cols] = 0;
- ft.amap[mi][i][cols] = 0;
- }
- }
-
- // resize cols
- if (cols > ft.mcols)
- {
- for (i = 0; i < ft.mrows; i++)
- {
- ft.cmap[mi][i] = (ftchar*)realloc(ft.cmap[mi][i],
- (cols+1) * sizeof(ftchar));
- ft.amap[mi][i] = (ftattr*)realloc(ft.amap[mi][i],
- (cols+1) * sizeof(ftattr));
- // zero at end to prevent over-run
- ft.cmap[mi][i][cols] = 0;
- ft.amap[mi][i][cols] = 0;
- }
- } else {
- // we have to deal one case:
- // expand x, shrink x, expand y ->
- // now new allocated lines will have small x(col) instead of mcol.
- // the solution is to modify mcols here, or change the malloc above
- // to max(ft.mcols, cols).
- ft.mcols = cols;
- }
- }
-
- // adjusts dirty and display map.
- // no need to initialize anyway.
- if (cols > ft.mcols)
- {
- ft.dmap = (ftchar*) realloc(ft.dmap,
- (cols+1) * sizeof(ftchar));
- ft.dcmap = (ftchar*) realloc(ft.dcmap,
- (cols+1) * sizeof(ftchar));
- }
-
- // do mrows/mcols assignment here, because we had 2 maps running loop above.
- if (cols > ft.mcols) ft.mcols = cols;
- if (rows > ft.mrows) ft.mrows = rows;
- dirty = 1;
- }
-
- // clear new exposed buffer after resized
- // because we will redawwin(), so need to change front buffer only.
- for (i = ft.rows; i < rows; i++)
- {
- memset(FTCMAP[i], FTCHAR_ERASE,
- (cols) * sizeof(ftchar));
- memset(FTAMAP[i], FTATTR_ERASE,
- (cols) * sizeof(ftattr));
- }
- if (cols > ft.cols)
- {
- for (i = 0; i < ft.rows; i++)
- {
- memset(FTCMAP[i]+ft.cols, FTCHAR_ERASE,
- (cols-ft.cols) * sizeof(ftchar));
- memset(FTAMAP[i]+ft.cols, FTATTR_ERASE,
- (cols-ft.cols) * sizeof(ftattr));
- }
- }
-
- if (ft.rows != rows || ft.cols != cols)
- {
- ft.rows = rows;
- ft.cols = cols;
- redrawwin();
- }
-
- ft.x = ranged(ft.x, 0, ft.cols-1);
- ft.y = ranged(ft.y, 0, ft.rows-1);
-
- return dirty;
-}
-
-// attributes
-
-ftattr
-attrget(void)
-{
- return ft.attr;
-}
-
-void
-attrset(ftattr attr)
-{
- ft.attr = attr;
-}
-
-void
-attrsetfg(ftattr attr)
-{
- ft.attr &= (~FTATTR_FGMASK);
- ft.attr |= ((attr & FTATTR_FGMASK) << FTATTR_FGSHIFT);
-}
-
-void
-attrsetbg(ftattr attr)
-{
- ft.attr &= (~FTATTR_BGMASK);
- ft.attr |= ((attr & FTATTR_FGMASK) << FTATTR_BGSHIFT);
-}
-
-// clear
-
-void
-clrscr(void)
-{
- int r;
- for (r = 0; r < ft.rows; r++)
- memset(FTCMAP[r], FTCHAR_ERASE, ft.cols * sizeof(ftchar));
- for (r = 0; r < ft.rows; r++)
- memset(FTAMAP[r], FTATTR_ERASE, ft.cols * sizeof(ftattr));
- fterm_markdirty();
-}
-
-void
-clear(void)
-{
- clrscr();
- move(0,0);
-}
-
-void
-clrtoeol(void)
-{
- ft.x = ranged(ft.x, 0, ft.cols-1);
- ft.y = ranged(ft.y, 0, ft.rows-1);
- memset(FTPC, FTCHAR_ERASE, ft.cols - ft.x);
- memset(FTPA, FTATTR_ERASE, ft.cols - ft.x);
- fterm_markdirty();
-}
-
-void
-clrtobeg(void)
-{
- ft.x = ranged(ft.x, 0, ft.cols-1);
- ft.y = ranged(ft.y, 0, ft.rows-1);
- memset(FTCROW, FTCHAR_ERASE, ft.x+1);
- memset(FTAROW, FTATTR_ERASE, ft.x+1);
- fterm_markdirty();
-}
-
-void
-clrcurrline(void)
-{
- ft.y = ranged(ft.y, 0, ft.rows-1);
- memset(FTCROW, FTCHAR_ERASE, ft.cols);
- memset(FTAROW, FTATTR_ERASE, ft.cols);
- fterm_markdirty();
-}
-
-void
-clrtoln(int line)
-{
- if (line <= ft.y)
- return;
- clrregion(ft.y, line-1);
-}
-
-void
-clrregion(int r1, int r2)
-{
- // bi-direction
- if (r1 > r2)
- {
- int r = r1;
- r1 = r2; r2 = r;
- }
-
- // check r1, r2 range
- r1 = ranged(r1, 0, ft.rows-1);
- r2 = ranged(r2, 0, ft.rows-1);
-
- for (; r1 <= r2; r1++)
- {
- memset(FTCMAP[r1], FTCHAR_ERASE, ft.cols);
- memset(FTAMAP[r1], FTATTR_ERASE, ft.cols);
- }
- fterm_markdirty();
-}
-
-void
-clrtobot(void)
-{
- clrtoeol();
- clrregion(ft.y+1, ft.rows-1);
-}
-
-void
-clrtohome(void)
-{
- clrtobeg();
- clrregion(ft.y-1, 0);
-}
-
-void newwin (int nlines, int ncols, int y, int x)
-{
- int oy, ox;
- // check range
-
- x = ranged(x, 0, ft.cols-1);
- y = ranged(y, 0, ft.rows-1);
- ncols = ranged(x+ncols-1, x, ft.cols-1);
- nlines = ranged(y+nlines-1, y, ft.rows-1);
- ncols = ncols - x + 1;
- nlines= nlines- y + 1;
-
- if (nlines <= 0 || ncols <= 0)
- return;
- getyx(&oy, &ox);
-
- while (nlines-- > 0)
- {
- move(y++, x);
- // use prepare_str to erase character
- fterm_prepare_str(ncols);
- // memset(FTAMAP[y]+x, ft.attr, ncols);
- // memset(FTCMAP[y]+x, FTCHAR_ERASE, ncols);
- }
- move(oy, ox);
-}
-
-// dirty and flushing
-
-void
-redrawwin(void)
-{
- // flip page
- fterm_flippage();
- clrscr();
-
- // clear raw terminal
- fterm_rawclear();
-
- // flip page again
- fterm_flippage();
-
- // mark for refresh.
- fterm_markdirty();
-}
-
-int
-typeahead(int fd)
-{
- switch(fd)
- {
- case TYPEAHEAD_NONE:
- ft.typeahead = 0;
- break;
- case TYPEAHEAD_STDIN:
- ft.typeahead = 1;
- break;
- default: // shall never reach here
- assert(NULL);
- break;
- }
- return 0;
-}
-
-void
-refresh(void)
-{
- // prevent passive update
- if(fterm_inbuf() && ft.typeahead)
- return;
- doupdate();
-}
-
-void
-doupdate(void)
-{
- int y, x;
- char touched = 0;
-
- if (!ft.dirty)
- {
- fterm_rawcursor();
- return;
- }
-
-#ifdef _WIN32
-
- assert(ft.rows == coordBufSize.Y);
- assert(ft.cols == coordBufSize.X);
-
- for (y = 0; y < ft.rows; y++)
- {
- for (x = 0; x < ft.cols; x++)
- {
- WORD xAttr = FTAMAP[y][x], xxAttr;
- // w32 attribute: bit swap (0,2) and (4, 6)
- xxAttr = xAttr & 0xAA;
- if (xAttr & 0x01) xxAttr |= 0x04;
- if (xAttr & 0x04) xxAttr |= 0x01;
- if (xAttr & 0x10) xxAttr |= 0x40;
- if (xAttr & 0x40) xxAttr |= 0x10;
-
- winbuf[y*ft.cols + x].Attributes= xxAttr;
- winbuf[y*ft.cols + x].Char.AsciiChar = FTCMAP[y][x];
- }
- }
- WriteConsoleOutputA(hStdout, winbuf, coordBufSize, coordBufCoord, &winrect);
-
-#else // !_WIN32
-
- // if scroll, do it first
- if (ft.scroll)
- fterm_rawscroll(ft.scroll);
-
- // calculate and optimize dirty
- for (y = 0; y < ft.rows; y++)
- {
- int len = ft.cols, ds = 0, derase = 0;
- char dbcs = 0, odbcs = 0; // 0: none, 1: lead, 2: tail
-
- // reset dirty and display map
- memset(FTD, 0, ft.cols * sizeof(ftchar));
- memcpy(FTDC,FTCMAP[y], ft.cols * sizeof(ftchar));
-
- // first run: character diff
- for (x = 0; x < len; x++)
- {
- // build base dirty information
- if (FTCMAP[y][x] != FTOCMAP[y][x])
- FTD[x] |= FTDIRTY_CHAR, ds++;
- if (FTAMAP[y][x] != FTOAMAP[y][x])
- FTD[x] |= FTDIRTY_ATTR, ds++;
-
- // determine DBCS status
- if (dbcs == 1)
- {
-#ifdef FTCONF_PREVENT_INVALID_DBCS
- switch(fterm_DBCS_Big5(FTCMAP[y][x-1], FTCMAP[y][x]))
- {
- case FTDBCS_SAFE:
- // safe to print
- FTD[x-1] &= ~FTDIRTY_INVALID_DBCS;
- FTDC[x-1] = FTCMAP[y][x-1];
- break;
-
- case FTDBCS_UNSAFE:
- // ok to print, but need to rawmove.
- FTD[x-1] &= ~FTDIRTY_INVALID_DBCS;
- FTDC[x-1] = FTCMAP[y][x-1];
- FTD[x-1] |= FTDIRTY_CHAR;
- FTD[x] |= FTDIRTY_RAWMOVE;
- break;
-
- case FTDBCS_INVALID:
- // only SBCS safe characters can be print.
- if (!FTDBCS_ISSBCSPRINT(FTCMAP[y][x]))
- {
- FTD[x] |= FTDIRTY_INVALID_DBCS;
- FTDC[x] = FTCHAR_INVALID_DBCS;
- }
- break;
- }
-#endif // FTCONF_PREVENT_INVALID_DBCS
-
- dbcs = 2;
- // TAIL: dirty prev and me if any is dirty.
- if (FTD[x] || FTD[x-1])
- {
- FTD[x] |= FTDIRTY_DBCS;
- FTD[x-1]|= FTDIRTY_CHAR;
- }
- }
- else if (FTDBCS_ISLEAD(FTCMAP[y][x]))
- {
- // LEAD: clear dirty when tail was found.
- dbcs = 1;
-#ifdef FTCONF_PREVENT_INVALID_DBCS
- FTD[x] |= FTDIRTY_INVALID_DBCS;
- FTDC[x] = FTCHAR_INVALID_DBCS;
-#endif // FTCONF_PREVENT_INVALID_DBCS
- }
- else
- {
- // NON-DBCS
- dbcs = 0;
- }
-
- if (odbcs == 1)
- {
- // TAIL: dirty prev and me if any is dirty.
- odbcs = 2;
- if (FTD[x] || FTD[x-1])
- {
- FTD[x] |= FTDIRTY_CHAR;
- FTD[x-1]|= FTDIRTY_CHAR;
- }
- }
- else if (FTDBCS_ISLEAD(FTOCMAP[y][x]))
- {
- // LEAD: dirty next?
- odbcs = 1;
- }
- else
- {
- odbcs = 0;
- }
- }
-
-#ifndef DBG_SHOW_DIRTY
- if (!ds)
- continue;
-#endif // DBG_SHOW_DIRTY
-
- // Optimization: calculate ERASE section
- // TODO ERASE takes 3 bytes (ESC [ K), so enable only if derase >= 3?
- // TODO ERASE then print can avoid lots of space, optimize in future.
- for (x = ft.cols - 1; x >= 0; x--)
- if (FTCMAP[y][x] != FTCHAR_ERASE ||
- FTAMAP[y][x] != FTATTR_ERASE)
- break;
- else if (FTD[x])
- derase++;
-
- len = x+1;
-
- for (x = 0; x < len; x++)
- {
-#ifndef DBG_SHOW_DIRTY
- if (!FTD[x])
- continue;
-#endif // !DBG_SHOW_DIRTY
-
- // Optimization: re-print or move?
-#ifndef DBG_DISABLE_REPRINT
- while (ft.ry == y && x > ft.rx && abs(x-ft.rx) < FTMV_COST)
- {
- int i;
- // Special case: we may be in position of DBCS tail...
- // Inside a refresh() loop, this will never happen.
- // However it may occur for the first print entering refresh.
- // So enable only space if this is the first run (!touched).
-
- // if we don't need to change attributes,
- // just print remaining characters
- for (i = ft.rx; i < x; i++)
- {
- // if same attribute, simply accept.
- if (FTAMAP[y][i] == ft.rattr && touched)
- continue;
- // XXX spaces may accept (BG=rBG),
- // but that will also change cached attribute.
- if (!FTCHAR_ISBLANK(FTCMAP[y][i]))
- break;
- if (FTATTR_GETBG(FTAMAP[y][i]) != FTATTR_GETBG(ft.rattr))
- break;
- }
- if (i != x)
- break;
-
- // safe to print all!
- // printf("[re-print %d chars]", i-ft.rx);
-
-#ifdef DBG_SHOW_REPRINT
- // reverse to hint this is a re-print
- fterm_rawattr(FTATTR_MAKE(0, 7) | FTATTR_BOLD);
-#endif // DBG_SHOW_REPRINT
-
- for (i = ft.rx; i < x; i++)
- {
- fterm_rawc(FTDC[i]);
- FTAMAP[y][i] = FTOAMAP[y][i]; // spaces may change attr...
- ft.rx++;
- }
-
- break;
- }
-#endif // !DBG_DISABLE_REPRINT
-
- if (y != ft.ry || x != ft.rx)
- fterm_rawmove_opt(y, x);
-
-#ifdef DBCSAWARE
- if ((FTD[x] & FTDIRTY_DBCS) && (FT_DBCS_NOINTRESC))
- {
- // prevent changing attributes inside DBCS
- }
- else
-#endif // DBCSAWARE
-#ifdef DBG_SHOW_DIRTY
- fterm_rawattr(FTD[x] ?
- (FTAMAP[y][x] | FTATTR_BOLD) : (FTAMAP[y][x] & ~FTATTR_BOLD));
-#else // !DBG_SHOW_DIRTY
- fterm_rawattr(FTAMAP[y][x]);
-#endif // !DBG_SHOW_DIRTY
-
- fterm_rawc(FTDC[x]);
- ft.rx++;
- touched = 1;
-
- if (FTD[x] & FTDIRTY_RAWMOVE)
- {
- fterm_rawcmd2(ft.ry+1, ft.rx+1, 1, 'H');
- }
- }
-
- if (derase)
- {
- fterm_rawmove_opt(y, len);
- fterm_rawclreol();
- }
- }
-
-#endif // !_WIN32
-
- // doing fterm_rawcursor() earlier to enable max display time
- fterm_rawcursor();
- fterm_dupe2bk();
- ft.dirty = 0;
-}
-
-// cursor management
-
-void
-getyx(int *y, int *x)
-{
- if (y)
- *y = ft.y;
- if (x)
- *x = ft.x;
-}
-
-void
-getmaxyx(int *y, int *x)
-{
- if (y)
- *y = ft.rows;
- if (x)
- *x = ft.cols;
-}
-
-void
-move(int y, int x)
-{
- ft.y = ranged(y, 0, ft.rows-1);
- ft.x = ranged(x, 0, ft.cols-1);
-}
-
-// scrolling
-
-void
-scrl(int rows)
-{
- if (!rows)
- return;
- if (rows > 0)
- {
- for (; rows > 0; rows--)
- scroll();
- } else {
- for (; rows < 0; rows++)
- rscroll();
- }
-}
-
-void
-scroll()
-{
- // scroll up
- int y;
- ftchar *c0 = FTCMAP[0], *oc0 = FTOCMAP[0];
- ftattr *a0 = FTAMAP[0], *oa0 = FTOAMAP[0];
-
- // prevent mixing buffered scroll up+down
- if (ft.scroll < 0)
- fterm_rawscroll(ft.scroll);
-
- // smart scroll: move pointers
- for (y = 0; y < ft.rows-1; y++)
- {
- FTCMAP[y] = FTCMAP[y+1];
- FTAMAP[y] = FTAMAP[y+1];
- FTOCMAP[y]= FTOCMAP[y+1];
- FTOAMAP[y]= FTOAMAP[y+1];
- }
- FTCMAP[y] = c0;
- FTAMAP[y] = a0;
- FTOCMAP[y]= oc0;
- FTOAMAP[y]= oa0;
-
- // XXX also clear backup buffer
- // must carefully consider if up then down scrolling.
- fterm_flippage();
- clrregion(ft.rows-1, ft.rows-1);
- fterm_flippage();
- clrregion(ft.rows-1, ft.rows-1);
-
- ft.scroll ++;
- // fterm_markdirty(); // should be already dirty
-}
-
-void
-rscroll()
-{
- // scroll down
- int y;
- ftchar *c0 = FTCMAP[ft.rows -1], *oc0 = FTOCMAP[ft.rows -1];
- ftattr *a0 = FTAMAP[ft.rows -1], *oa0 = FTOAMAP[ft.rows -1];
-
- // prevent mixing buffered scroll up+down
- if (ft.scroll > 0)
- fterm_rawscroll(ft.scroll);
-
- // smart scroll: move pointers
- for (y = ft.rows -1; y > 0; y--)
- {
- FTCMAP[y] = FTCMAP[y-1];
- FTAMAP[y] = FTAMAP[y-1];
- FTOCMAP[y]= FTOCMAP[y-1];
- FTOAMAP[y]= FTOAMAP[y-1];
- }
- FTCMAP[y] = c0;
- FTAMAP[y] = a0;
- FTOCMAP[y]= oc0;
- FTOAMAP[y]= oa0;
-
- // XXX also clear backup buffer
- // must carefully consider if up then down scrolling.
- fterm_flippage();
- clrregion(0, 0);
- fterm_flippage();
- clrregion(0, 0);
-
- ft.scroll --;
- // fterm_markdirty(); // should be already dirty
-}
-
-// output
-
-void
-addch (unsigned char c)
-{
- outc(c);
-}
-
-void
-addstr (const char *s)
-{
- outs(s);
-}
-
-void
-addnstr(const char *s, int n)
-{
- outns(s, n);
-}
-
-void
-addstring(const char *s)
-{
- outstr(s);
-}
-
-void
-outs(const char *s)
-{
- if (!s)
- return;
- while (*s)
- outc(*s++);
-}
-
-void
-outns(const char *s, int n)
-{
- if (!s)
- return;
- while (*s && n-- > 0)
- outc(*s++);
-}
-
-void
-outstr(const char *str)
-{
- if (!str)
- {
- fterm_prepare_str(0);
- return;
- }
-
- // calculate real length of str (stripping escapes)
- // TODO only print by the returned size
-
- fterm_prepare_str(fterm_strdlen(str));
-
- outs(str);
-
- // maybe the source string itself is broken...
- // basically this check should be done by clients, not term library.
-#if 0
- {
- int isdbcs = 0;
- while (*str)
- {
- if (isdbcs == 1) isdbcs = 2;
- else if (FTDBCS_ISLEAD(*str)) isdbcs = 1;
- else isdbcs = 0;
- str++;
- }
-
- if (isdbcs == 1) // incomplete string!
- outs("\b?");
- }
-#endif
-}
-
-void
-outc(unsigned char c)
-{
- // 0xFF is invalid for most cases (even DBCS),
- if (c == 0xFF || c == 0x00)
- return;
-
- fterm_markdirty();
- if (ft.szcmd)
- {
- // collecting commands
- ft.cmd[ft.szcmd++] = c;
-
- if ((ft.szcmd == 2 && c == '[') ||
- (ANSI_IS_PARAM(c) && ft.szcmd < FTCMD_MAXLEN))
- return;
-
- // process as command
- fterm_exec();
- ft.szcmd = 0;
- }
- else if (c == ESC_CHR)
- {
- // start of escaped commands
- ft.cmd[ft.szcmd++] = c;
- }
- else if (c == '\t')
- {
- // tab: move by 8, and erase the moved range
- int x = ft.x;
- if (x % 8 == 0)
- x += 8;
- else
- x += (8-(x%8));
- x = ranged(x, 0, ft.cols-1);
- // erase the characters between
- if (x > ft.x)
- {
- memset(FTCROW+ft.x, FTCHAR_ERASE, x - ft.x);
- memset(FTAROW+ft.x, ft.attr, x-ft.x);
- }
- ft.x = x;
- }
- else if (c == '\b')
- {
- ft.x = ranged(ft.x-1, 0, ft.cols-1);
- }
- else if (c == '\r' || c == '\n')
- {
- // new line: cursor movement, and do not print anything
- // XXX old screen.c also calls clrtoeol() for newlins.
- clrtoeol();
- ft.x = 0;
- ft.y ++;
- while (ft.y >= ft.rows)
- {
- // XXX scroll at next dirty?
- // screen.c ignored such scroll.
- // scroll();
- ft.y --;
- }
- }
- else if (iscntrl((unsigned char)c))
- {
- // unknown control characters: ignore
- }
- else // normal characters
- {
- assert (ft.x >= 0 && ft.x < ft.cols);
-
- // normal characters
- FTC = c;
-#ifdef FTATTR_TRANSPARENT
- if (ft.attr != FTATTR_TRANSPARENT)
-#endif // FTATTR_TRANSPARENT
- FTA = ft.attr;
-
- ft.x++;
- // XXX allow x == ft.cols?
- if (ft.x >= ft.cols)
- {
- ft.x = 0;
- ft.y ++;
- while (ft.y >= ft.rows)
- {
- // XXX scroll at next dirty?
- // screen.c ignored such scroll.
- // scroll();
- ft.y --;
- }
- }
- }
-}
-
-// readback
-int
-instr (char *str)
-{
- int x = ft.cols -1;
- *str = 0;
- if (ft.y < 0 || ft.y >= ft.rows || ft.x < 0 || ft.x >= ft.cols)
- return 0;
-
- // determine stopping location
- while (x >= ft.x && FTCROW[x] == FTCHAR_ERASE)
- x--;
- if (x < ft.x) return 0;
- x = x - ft.x + 1;
- memcpy(str, FTCROW+ft.x, x);
- str[x] = 0;
- return x;
-}
-
-int
-innstr (char *str, int n)
-{
- int on = n;
- int x = ranged(ft.x + n-1, 0, ft.cols-1);
- *str = 0;
- n = x - ft.x+1;
- if (on < 1 || ft.y < 0 || ft.y >= ft.rows || ft.x < 0 || ft.x >= ft.cols)
- return 0;
-
- // determine stopping location
- while (x >= ft.x && FTCROW[x] == FTCHAR_ERASE)
- x--;
- if (x < ft.x) return 0;
- n = x - ft.x + 1;
- if (n >= on) n = on-1;
- memcpy(str, FTCROW+ft.x, n);
- str[n] = 0;
- return n;
-}
-
-int
-inansistr (char *str, int n)
-{
- int x = ft.cols -1, i = 0, szTrail = 0;
- char *ostr = str;
- char cmd[FTATTR_MINCMD*2] = "";
-
- ftattr a = FTATTR_DEFAULT;
- *str = 0;
- if (ft.y < 0 || ft.y >= ft.rows || ft.x < 0 || ft.x >= ft.cols)
- return 0;
-
- if (n < 1)
- return 0;
- n--; // preserve last zero
-
- // determine stopping location
- while (x >= ft.x && FTCROW[x] == FTCHAR_ERASE && FTAROW[x] == FTATTR_ERASE)
- x--;
-
- // retrieve [rt.x, x]
- if (x < ft.x) return 0;
-
- // preserve some bytes if last attribute is not FTATTR_DEFAULT
- for (i = ft.x; n > szTrail && i <= x; i++)
- {
- *str = 0;
-
- if (a != FTAROW[i])
- {
- fterm_chattr(cmd, a, FTAROW[i]);
- a = FTAROW[i];
-
- if (a != FTATTR_DEFAULT)
- szTrail = 3; // ESC [ m
- else
- szTrail = 0;
-
- if (strlen(cmd) >= n-szTrail)
- break;
-
- strcpy(str, cmd);
- n -= strlen(cmd);
- str += strlen(cmd);
- }
-
- // n should > szTrail
- *str ++ = FTCROW[i];
- n--;
- }
-
- if (szTrail && n >= szTrail)
- {
- *str++ = ESC_CHR; *str++ = '['; *str++ = 'm';
- }
-
- *str = 0;
- return (str - ostr);
-}
-
-// internal core of piaip's flat-term
-
-void
-fterm_flippage (void)
-{
- // we have only 2 pages now.
- ft.mi = 1 - ft.mi;
-}
-
-#ifndef fterm_markdirty
-void
-fterm_markdirty (void)
-{
- ft.dirty = 1;
-}
-#endif
-
-void fterm_dupe2bk(void)
-{
- int r = 0;
-
- for (r = 0; r < ft.rows; r++)
- {
- memcpy(FTOCMAP[r], FTCMAP[r], ft.cols * sizeof(ftchar));
- memcpy(FTOAMAP[r], FTAMAP[r], ft.cols * sizeof(ftattr));
- }
-}
-
-int
-fterm_DBCS_Big5(unsigned char c1, unsigned char c2)
-{
- // ref: http://www.cns11643.gov.tw/web/word/big5/index.html
- // High byte: 0xA1-0xFE, 0x8E-0xA0, 0x81-0x8D
- // Low byte: 0x40-0x7E, 0xA1-0xFE
- // C1: 0x80-0x9F
- if (FTDBCS_ISBADLEAD(c1))
- return FTDBCS_INVALID;
- if (!FTDBCS_ISTAIL(c2))
- return FTDBCS_INVALID;
- if (c1 >= 0x80 && c1 <= 0x9F)
- return FTDBCS_UNSAFE;
- return FTDBCS_SAFE;
-}
-
-int
-fterm_prepare_str(int len)
-{
- // clear and make (cursor, +len) as DBCS-ready.
- int x = ranged(ft.x, 0, ft.cols-1);
- int y = ranged(ft.y, 0, ft.rows-1);
- int dbcs = 0, sdbcs = 0;
-
- // TODO what if x+len is outside range?
-
- // check if (x,y) is in valid range
- if (x != ft.x || y != ft.y)
- return -1;
-
- len = ranged(x+len, x, ft.cols);
-
- for (x = 0; x < len; x++)
- {
- // determine DBCS status
- if (dbcs == 1)
- dbcs = 2; // TAIL
- else if (FTDBCS_ISLEAD(FTCROW[x]))
- dbcs = 1; // LEAD
- else
- dbcs = 0;
- if (x == ft.x) sdbcs = dbcs;
- }
-
- x = ft.x;
- // fix start and end
- if(sdbcs == 2 && x > 0) // TAIL, remove word
- x--;
- if (dbcs == 1 && len < ft.cols) // LEAD, remove word
- len ++;
- len = ranged(len, 0, ft.cols);
- len -= x;
- if (len < 0) len = 0;
-
- memset(FTCROW + x, FTCHAR_ERASE, len);
- memset(FTAROW + x, ft.attr, len);
- return len;
-}
-
-
-void
-fterm_exec(void)
-{
- ftchar cmd = ft.cmd[ft.szcmd-1];
- char *p = (char*)ft.cmd + 2; // ESC [
- int n = -1, x = -1, y;
-
- ft.cmd[ft.szcmd] = 0;
-
- if (isdigit(*p))
- {
- n = atoi(p);
-
- while (*p && isdigit(*p))
- p++;
-
- if (*p == ';')
- p++;
- // p points to next param now
- }
-
- switch(cmd)
- {
- // Cursor Movement
-
- case 'A': // CUU: CSI n A
- case 'B': // CUD: CSI n B
- case 'C': // CUF: CSI n C
- case 'D': // CUB: CSI n D
- // Moves the cursor n (default 1) cells in the given direction.
- // If the cursor is already at the edge of the screen, this has no effect.
- if (n < 1)
- n = 1;
- getyx(&y, &x);
- if (cmd == 'A') { y -= n; }
- else if (cmd == 'B') { y += n; }
- else if (cmd == 'C') { x += n; }
- else if (cmd == 'D') { x -= n; }
- move(y, x);
- break;
-
- case 'E': // CNL: CSI n E
- case 'F': // CPL: CSI n F
- // Moves cursor to beginning of the line
- // n (default 1) lines up/down (next/previous line).
- if (n < 1)
- n = 1;
- getyx(&y, &x);
- if (cmd == 'E') { y -= n; }
- else if (cmd == 'F') { y += n; }
- move(y, 0);
- break;
-
- case 'G': // CHA: CSI n G
- // Moves the cursor to column n.
- if (n < 1)
- n = 1;
- getyx(&y, &x);
- move(y, n-1);
- break;
-
- case 'H': // CUP: CSI n ; m H
- case 'f': // HVP: CSI n ; m f
- // Moves the cursor to row n, column m.
- // The values are 1-based, and default to 1 (top left corner) if omitted.
- // A sequence such as CSI ;5H is a synonym for CSI 1;5H as well as
- // CSI 17;H is the same as CSI 17H and CSI 17;1H
- y = n;
- if (y >= 0 && isdigit(*p))
- x = atoi((char*)p);
- if (y < 0) y = 1;
- if (x < 0) x = 1;
- move(y-1, x-1);
- break;
-
- // Clear
-
- case 'J': // ED: CSI n J
- // Clears part of the screen.
- // If n is zero (or missing), clear from cursor to end of screen.
- // If n is one, clear from cursor to beginning of the screen.
- // If n is two, clear entire screen
- if (n == 0 || n < 0)
- clrtobot();
- else if (n == 1)
- clrtohome();
- else if (n == 2)
- {
- clrregion(0, ft.rows-1);
- }
- break;
-
- case 'K': // EL: CSI n K
- // Erases part of the line.
- // If n is zero (or missing), clear from cursor to the end of the line.
- // If n is one, clear from cursor to beginning of the line.
- // If n is two, clear entire line. Cursor position does not change.
- if (n == 0 || n < 0)
- clrtoeol();
- else if (n == 1)
- clrtobeg();
- else if (n == 2)
- clrcurrline();
- break;
-
- case 's': // SCP: CSI s
- // Saves the cursor position.
- getyx(&ft.sy, &ft.sx);
- break;
-
- case 'u': // RCP: CSI u
- // Restores the cursor position.
- move(ft.sy, ft.sx);
- break;
-
- case 'S': // SU: CSI n S
- // Scroll whole page up by n (default 1) lines.
- // New lines are added at the bottom.
- if (n < 1)
- n = 1;
- scrl(n);
- break;
-
- case 'T': // SD: CSI n T
- // Scroll whole page down by n (default 1) lines.
- // New lines are added at the top.
- if (n < 1)
- n = 1;
- scrl(-n);
- break;
-
- case 'm': // SGR: CSI n [;k] m
- // Sets SGR (Select Graphic Rendition) parameters.
- // After CSI can be zero or more parameters separated with ;.
- // With no parameters, CSI m is treated as CSI 0 m (reset / normal),
- // which is typical of most of the ANSI codes.
- // ---------------------------------------------------------
- // SGR implementation:
- // SGR 0 (reset/normal) is supported.
- // SGR 1 (intensity: bold) is supported.
- // SGR 2 (intensity: faint) is not supported.
- // SGR 3 (italic: on) is not supported. (converted to inverse?)
- // SGR 4 (underline: single) is not supported.
- // SGR 5 (blink: slow) is supported.
- // SGR 6 (blink: rapid) is converted to (blink: slow)
- // SGR 7 (image: negative) is partially supported (not a really attribute).
- // SGR 8 (conceal) is not supported.
- // SGR 21(underline: double) is not supported.
- // SGR 22(intensity: normal) is supported.
- // SGR 24(underline: none) is not supported.
- // SGR 25(blink: off) is supported.
- // SGR 27(image: positive) is not supported.
- // SGR 28(reveal) is not supported.
- // SGR 30-37 (FG) is supported.
- // SGR 39 (FG-reset) is supported.
- // SGR 40-47 (BG) is supported.
- // SGR 49 (BG-reset) is supported.
- if (n == -1) // first param
- n = 0;
- while (n > -1)
- {
- if (n >= 30 && n <= 37)
- {
- // set foreground
- attrsetfg(n - 30);
- }
- else if (n >= 40 && n <= 47)
- {
- // set background
- attrsetbg(n - 40);
- }
- else switch(n)
- {
- case 0:
- attrset(FTATTR_DEFAULT);
- break;
- case 1:
- attrset(attrget() | FTATTR_BOLD);
- break;
- case 22:
- attrset(attrget() & ~FTATTR_BOLD);
- break;
- case 5:
- case 6:
- attrset(attrget() | FTATTR_BLINK);
- break;
- case 25:
- attrset(attrget() & ~FTATTR_BLINK);
- break;
- case 3:
- case 7:
- {
- ftattr a = attrget();
- attrsetfg(FTATTR_GETBG(a));
- attrsetbg(FTATTR_GETFG(a));
- }
- break;
- case 39:
- attrsetfg(FTATTR_DEFAULT_FG);
- break;
- case 49:
- attrsetbg(FTATTR_DEFAULT_BG);
- break;
- }
-
- // parse next command
- n = -1;
- if (*p == ';')
- {
- n = 0;
- p++;
- }
- else if (isdigit(*p))
- {
- n = atoi(p);
- while (isdigit(*p)) p++;
- if (*p == ';')
- p++;
- }
- }
- break;
-
- default: // unknown command.
- break;
- }
-}
-
-int
-fterm_chattr(char *s, ftattr oattr, ftattr nattr)
-{
- ftattr
- fg, bg, bold, blink,
- ofg, obg, obold, oblink;
- char lead = 1;
-
- if (oattr == nattr)
- return 0;
-
- *s++ = ESC_CHR;
- *s++ = '[';
-
- // optimization: reset as default
- if (nattr == FTATTR_DEFAULT)
- {
- *s++ = 'm';
- *s++ = 0;
- return 1;
- }
-
- fg = FTATTR_GETFG(nattr);
- bg = FTATTR_GETBG(nattr);
- bold = (nattr & FTATTR_BOLD) ? 1 : 0;
- blink = (nattr & FTATTR_BLINK)? 1 : 0;
-
- ofg = FTATTR_GETFG(oattr);
- obg = FTATTR_GETBG(oattr);
- obold = (oattr & FTATTR_BOLD) ? 1 : 0;
- oblink = (oattr & FTATTR_BLINK)? 1 : 0;
-
- // we dont use "disable blink/bold" commands,
- // so if these settings are changed then we must reset.
- // another case is changing background to default background -
- // better use "RESET" to override it.
- // Same for foreground.
- // Possible optimization: when blink/bold on, don't RESET
- // for background change?
- if ((oblink != blink && !blink) ||
- (obold != bold && !bold) ||
- (bg == FTATTR_DEFAULT_BG && obg != bg) ||
- (fg == FTATTR_DEFAULT_FG && ofg != fg) )
- {
- if (lead) lead = 0; else *s++ = ';';
- *s++ = '0';
-
- ofg = FTATTR_DEFAULT_FG;
- obg = FTATTR_DEFAULT_BG;
- obold = 0; oblink = 0;
- }
-
- if (bold && !obold)
- {
- if (lead) lead = 0; else *s++ = ';';
- *s++ = '1';
-
-#ifdef FTCONF_WORKAROUND_BOLD
- // Issue here:
- // PacketSite does not understand ESC[1m. It needs ESC[1;37m
- // NetTerm defaults bold color to yellow.
- // As a result, we use ESC[1;37m for the case.
- if (fg == FTATTR_DEFAULT_FG)
- ofg = ~ofg;
-#endif // FTCONF_WORKAROUND_BOLD
-
- }
- if (blink && !oblink)
- {
- if (lead) lead = 0; else *s++ = ';';
- *s++ = '5'; // XXX 5(slow) or 6(fast)?
- }
- if (ofg != fg)
- {
- if (lead) lead = 0; else *s++ = ';';
- *s++ = '3';
- *s++ = '0' + fg;
- }
- if (obg != bg)
- {
- if (lead) lead = 0; else *s++ = ';';
- *s++ = '4';
- *s++ = '0' + bg;
- }
- *s++ = 'm';
- *s++ = 0;
- return 1;
-}
-
-int
-fterm_strdlen(const char *s)
-{
- char ansi = 0;
- int sz = 0;
-
- // the logic should match outc().
-
- while (s && *s)
- {
- if (!ansi) // ansi == 0
- {
- switch(*s)
- {
- case ESC_CHR:
- ansi++;
- break;
-
- case '\r':
- case '\n':
- break;
-
- case '\b':
- if (sz) sz--;
- break;
-
- case '\t':
- // XXX how to deal with this?
- sz ++;
- break;
-
- default:
- if (!iscntrl((unsigned char)*s))
- sz++;
- break;
- }
- }
- else if (ansi == 1)
- {
- if (*s == '[')
- ansi++;
- else
- ansi = 0;
- }
- else if (!ANSI_IS_PARAM(*s)) // ansi == 2
- {
- // TODO outc() take max to FTCMD_MAXLEN now...
- ansi = 0;
- }
- s++;
- }
- return sz;
-}
-
-void
-fterm_rawattr(ftattr rattr)
-{
- static char cmd[FTATTR_MINCMD*2];
- if (!fterm_chattr(cmd, ft.rattr, rattr))
- return;
-
- fterm_raws(cmd);
- ft.rattr = rattr;
-}
-
-void
-fterm_rawnum(int arg)
-{
- if (arg < 0 || arg > 99)
- {
- // complex. use printf.
- char sarg[16]; // max int
- sprintf(sarg, "%d", arg);
- fterm_raws(sarg);
- } else if (arg < 10) {
- // 0 .. 10
- fterm_rawc('0' + arg);
- } else {
- fterm_rawc('0' + arg/10);
- fterm_rawc('0' + arg%10);
- }
-}
-void
-fterm_rawcmd(int arg, int defval, char c)
-{
- fterm_rawc(ESC_CHR);
- fterm_rawc('[');
- if (arg != defval)
- fterm_rawnum(arg);
- fterm_rawc(c);
-}
-
-void
-fterm_rawcmd2(int arg1, int arg2, int defval, char c)
-{
- fterm_rawc(ESC_CHR);
- fterm_rawc('[');
-
- // See FTCONF_ANSICMD2_OMIT
- // XXX Win/DOS telnet does now accept omitting first value
- // ESC[nX and ESC[n;X works, but ESC[;mX does not work.
- if (arg1 != defval || arg2 != defval)
- {
-#if (FTCONF_ANSICMD2_OMIT >= 2)
- if (arg1 != defval)
-#endif
- fterm_rawnum(arg1);
-
-#if (FTCONF_ANSICMD2_OMIT >= 1)
- if (arg2 != defval)
-#endif
- {
- fterm_rawc(';');
- fterm_rawnum(arg2);
- }
- }
- fterm_rawc(c);
-}
-
-void
-fterm_rawclear(void)
-{
- fterm_rawhome();
- // ED: CSI n J, 0 = cursor to bottom, 2 = whole
- fterm_raws(ESC_STR "[2J");
-}
-
-void
-fterm_rawclreol(void)
-{
-#ifdef FTCONF_CLEAR_SETATTR
- // ftattr oattr = ft.rattr;
- // XXX If we skip with "backround only" here, future updating
- // may get wrong attributes. Or not? (consider DBCS...)
- // if (FTATTR_GETBG(oattr) != FTATTR_GETBG(FTATTR_ERASE))
- fterm_rawattr(FTATTR_ERASE);
-#endif
-
- // EL: CSI n K, n = 0
- fterm_raws(ESC_STR "[K");
-
-#ifdef FTCONF_CLEAR_SETATTR
- // No need to do so? because we will always reset attribute...
- // fterm_rawattr(oattr);
-#endif
-}
-
-void
-fterm_rawhome(void)
-{
- // CUP: CSI n ; m H
- fterm_raws(ESC_STR "[H");
- ft.rx = ft.ry = 0;
-}
-
-void
-fterm_rawmove_rel(int dy, int dx)
-{
-#ifndef FTCONF_USE_ANSI_RELMOVE
- // Old BBS system does not output relative moves (ESC[ABCD) .
- // Poor terminals (ex, pcman-1.0.5-FF20.xpi)
- // do not support relmoves
- fterm_rawmove(ft.ry + dy, ft.rx + dx);
-#else
- if (!dx)
- {
- int y = ranged(dy + ft.ry, 0, ft.rows-1);
- dy = y - ft.ry;
- if (!dy)
- return;
-
- fterm_rawcmd(abs(dy), 1, dy < 0 ? 'A' : 'B');
- ft.ry = y;
- }
- else if (!dy)
- {
- int x = ranged(dx + ft.rx, 0, ft.cols-1);
- dx = x - ft.rx;
- if (!dx)
- return;
-
- fterm_rawcmd(abs(dx), 1, dx < 0 ? 'D' : 'C');
- ft.rx = x;
- }
- else
- {
- // (dy, dx) are given - use fterm_move.
- fterm_rawmove(ft.ry + dy, ft.rx + dx);
- }
-#endif
-}
-
-void
-fterm_rawmove(int y, int x)
-{
- y = ranged(y, 0, ft.rows-1);
- x = ranged(x, 0, ft.cols-1);
-
- if (y == ft.ry && x == ft.rx)
- return;
-
- // CUP: CSI n ; m H
- fterm_rawcmd2(y+1, x+1, 1, 'H');
-
- ft.ry = y;
- ft.rx = x;
-}
-
-void
-fterm_rawmove_opt(int y, int x)
-{
- // optimized move
- int ady = abs(y-ft.ry), adx=abs(x-ft.rx);
-
- if (!adx && !ady)
- return;
-
-#ifdef DBG_DISABLE_OPTMOVE
- return fterm_rawmove(y, x);
-#endif
-
- // known hacks: \r = (x=0), \b=(x--), \n = (y++)
- //
- // Warning: any optimization here should not change displayed content,
- // because we don't have information about content variation information
- // (eg, invalid DBCS bytes will become special marks) here.
- // Any hacks which will try to display data from FTCMAP should be done
- // inside dirty-map calculation, for ex, using spaces to move right,
- // or re-print content.
-
-#ifndef DBG_TEXT_FD
- // x=0: the cheapest output. However not work for text mode fd output.
- // a special case is "if we have to move y to up".
- // and FTCONF_ANSICMD2_OMIT < 1 (cannot omit x).
-#if FTCONF_ANSICMD2_OMIT < 1
- if (y >= ft.ry)
-#endif
- if (adx && x == 0)
- {
- fterm_rawc('\r');
- ft.rx = x = adx = 0;
- }
-
-#endif // !DBG_TEXT_FD
-
- // x--: compare with FTMV_COST: ESC[m;nH costs 5-8 bytes
- if (x < ft.rx && y >= ft.ry && (adx+ady) < FTMV_COST)
- {
- while (adx > 0)
- fterm_rawc('\b'), adx--;
- ft.rx = x;
- }
-
- // finishing movement
- if (y > ft.ry && ady < FTMV_COST && adx == 0)
- {
- while (ft.ry++ < y)
- fterm_rawc('\n');
- ft.ry = y;
- }
- else if (ady && adx)
- {
- fterm_rawmove(y, x);
- }
- else if (ady)
- {
- fterm_rawmove_rel(y-ft.ry, 0);
- }
- else if (adx)
- {
- fterm_rawmove_rel(0, x-ft.rx);
- }
-}
-
-void
-fterm_rawcursor(void)
-{
-#ifdef _WIN32
- COORD cursor;
- cursor.X = ft.x;
- cursor.Y = ft.y;
- SetConsoleCursorPosition(hStdout, cursor);
-#else
- // fterm_rawattr(FTATTR_DEFAULT);
- fterm_rawattr(ft.attr);
- fterm_rawmove_opt(ft.y, ft.x);
- fterm_rawflush();
-#endif // !_WIN32
-}
-
-void
-fterm_rawscroll (int dy)
-{
-#ifdef FTCONF_USE_ANSI_SCROLL
- // SU: CSI n S (up)
- // SD: CSI n T (down)
-
- char cmd = (dy > 0) ? 'S' : 'T';
- int ady = abs(dy);
- if (ady == 0)
- return;
- if (ady >= ft.rows) ady = ft.rows;
- fterm_rawcmd(ady, 1, cmd);
- ft.scroll -= dy;
-
-#else
- // VT100 flavor:
- // * ESC D: scroll down
- // * ESC M: scroll up
- //
- // Elder BBS systems works in a mixed way:
- // \n at (rows-1) as scroll()
- // and ESC-M at(0) as rscoll().
- //
- // SCP: CSI s / RCP: CSI u
- // Warning: cannot use SCP/RCP here, because on Win/DOS telnet
- // the position will change after scrolling (ex, (25,0)->(24,0).
- //
- // Since scroll does not happen very often, let's relax and not
- // optimize these commands here...
-
- int ady = abs(dy);
- if (ady == 0)
- return;
- if (ady >= ft.rows) ady = ft.rows;
-
- // we are not going to preserve (rx,ry)
- // so don't use fterm_move*.
- if (dy > 0)
- fterm_rawcmd2(ft.rows, 1, 1, 'H');
- else
- fterm_rawcmd2(1, 1, 1, 'H');
-
- for (; ady > 0; ady--)
- {
- if (dy >0)
- {
- // Win/DOS telnet may have extra text in new line,
- // because of the IME line.
-#ifdef FTCONF_USE_VT100_SCROLL
- fterm_raws(ESC_STR "D" ESC_STR "[K"); // ESC_STR "[K");
-#else
- fterm_raws("\n" ESC_STR "[K");
-#endif
- } else {
- fterm_raws(ESC_STR "M"); // ESC_STR "[K");
- }
- }
-
- // Do not use optimized move here, because in poor terminals
- // the coordinates are already out of sync.
- fterm_rawcmd2(ft.ry+1, ft.rx+1, 1, 'H');
- ft.scroll -= dy;
-#endif
-}
-
-void
-fterm_raws(const char *s)
-{
- while (*s)
- fterm_rawc(*s++);
-}
-
-void
-fterm_rawnc(int c, int n)
-{
- while (n-- > 0)
- fterm_rawc(c);
-}
-
-//////////////////////////////////////////////////////////////////////////
-// grayout advanced control
-//////////////////////////////////////////////////////////////////////////
-void
-grayout(int y, int end, int level)
-{
- char grattr = FTATTR_DEFAULT;
-
- y = ranged(y, 0, ft.rows-1);
- end = ranged(end, 0, ft.rows-1);
-
- if (level == GRAYOUT_COLORBOLD)
- {
- int x = 0;
- for (; y < end; y++)
- {
- for (x = 0; x < ft.cols-1; x++)
- FTAMAP[y][x] |= FTATTR_BOLD;
- }
- return;
- }
-
- if (level == GRAYOUT_COLORNORM)
- {
- int x = 0;
- for (; y < end; y++)
- {
- for (x = 0; x < ft.cols-1; x++)
- FTAMAP[y][x] &= ~(FTATTR_BLINK | FTATTR_BOLD);
- }
- return;
- }
-
- if (level == GRAYOUT_BOLD)
- {
- grattr |= FTATTR_BOLD;
- }
- else if (level == GRAYOUT_DARK)
- {
- grattr = FTATTR_MAKE(0,0);
- grattr |= FTATTR_BOLD;
- }
- else if (level == GRAYOUT_NORM)
- {
- // normal text
- }
- else
- {
- // not supported yet
- }
-
- for (; y <= end; y++)
- {
- memset(FTAMAP[y], grattr, ft.cols);
- }
-}
-
-//////////////////////////////////////////////////////////////////////////
-// deprecated api
-//////////////////////////////////////////////////////////////////////////
-
-void
-standout(void)
-{
- outs(ANSI_COLOR(7));
-}
-
-void
-standend(void)
-{
- outs(ANSI_RESET);
-}
-
-#ifndef _PFTERM_TEST_MAIN
-
-void
-scr_dump(screen_backup_t *psb)
-{
- int y = 0;
- char *p = NULL;
-
- psb->row= ft.rows;
- psb->col= ft.cols;
- psb->y = ft.y;
- psb->x = ft.x;
- p = psb->raw_memory =
- malloc (ft.rows * ft.cols * (sizeof(ftchar) + sizeof(ftattr)));
-
- for (y = 0; y < ft.rows; y++)
- {
- memcpy(p, FTCMAP[y], ft.cols * sizeof(ftchar));
- p += ft.cols * sizeof(ftchar);
- memcpy(p, FTAMAP[y], ft.cols * sizeof(ftattr));
- p += ft.cols * sizeof(ftattr);
- }
-}
-
-void
-scr_restore(const screen_backup_t *psb)
-{
- int y = 0;
- char *p = NULL;
- int c = ft.cols, r = ft.rows;
- if (!psb || !psb->raw_memory)
- return;
-
- p = psb->raw_memory;
- c = ranged(c, 0, psb->col);
- r = ranged(r, 0, psb->row);
-
- ft.y = ranged(psb->y, 0, ft.rows-1);
- ft.x = ranged(psb->x, 0, ft.cols-1);
- clrscr();
-
- for (y = 0; y < r; y++)
- {
- memcpy(FTCMAP[y], p, c * sizeof(ftchar));
- p += psb->col * sizeof(ftchar);
- memcpy(FTAMAP[y], p, c * sizeof(ftattr));
- p += psb->col * sizeof(ftattr);
- }
-
- free(psb->raw_memory);
- ft.dirty = 1;
- refresh();
-}
-
-void
-move_ansi(int y, int x)
-{
- move(y, x);
-}
-
-void
-getyx_ansi(int *y, int *x)
-{
- getyx(y, x);
-}
-
-void
-region_scroll_up(int top, int bottom)
-{
- int i;
- ftchar *c0;
- ftattr *a0;
-
- // logic same with old screen.c
- if (top > bottom) {
- i = top;
- top = bottom;
- bottom = i;
- }
- if (top < 0 || bottom >= ft.rows)
- return;
-
- c0 = FTCMAP[top];
- a0 = FTAMAP[top];
-
- for (i = top; i < bottom; i++)
- {
- FTCMAP[i] = FTCMAP[i+1];
- FTAMAP[i] = FTAMAP[i+1];
- }
- FTCMAP[bottom] = c0;
- FTAMAP[bottom] = a0;
-
- clrregion(bottom, bottom);
- fterm_markdirty();
-}
-
-#endif
-
-//////////////////////////////////////////////////////////////////////////
-// adapter
-//////////////////////////////////////////////////////////////////////////
-
-int
-fterm_inbuf(void)
-{
-#ifdef _PFTERM_TEST_MAIN
- return 0;
-#else
- return num_in_buf();
-#endif
-}
-
-void
-fterm_rawc(int c)
-{
-#ifdef _PFTERM_TEST_MAIN
- // if (c == ESC_CHR) putchar('*'); else
- putchar(c);
-#else
- ochar(c);
-#endif
-}
-
-void
-fterm_rawnewline(void)
-{
-#ifdef _PFTERM_TEST_MAIN
- putchar('\n');
-#else
- ochar('\r');
- ochar('\n');
-#endif
-}
-
-void
-fterm_rawflush(void)
-{
-#ifdef _PFTERM_TEST_MAIN
- fflush(stdout);
-#else
- oflush();
-#endif
-}
-
-//////////////////////////////////////////////////////////////////////////
-// test
-//////////////////////////////////////////////////////////////////////////
-
-#ifdef _PFTERM_TEST_MAIN
-int main(int argc, char* argv[])
-{
- char buf[512];
- initscr();
-
- if (argc < 2)
- {
-#if 0
- // DBCS test
- char *a1 = ANSI_COLOR(1;33) "´ú¸Õ" ANSI_COLOR(34) "¤¤¤å"
- ANSI_COLOR(7) "´ú¸Õ" ANSI_RESET "´ú¸Õ"
- "´ú¸Õa" ANSI_RESET "\n";
- outstr(a1);
- move(0, 2);
- outstr("¤¤¤å1");
- outstr(ANSI_COLOR(1;33)"¤¤¤å2");
- outstr(" ¤¤\x85");
- outstr("okok herer\x8a");
-
- move(0, 8);
- inansistr(buf, sizeof(buf)-1);
-
- move(3,5); outs(ANSI_RESET "(From inansistr:) "); outs(buf);
- move(7, 3);
- sprintf(buf, "strlen()=%d\n", fterm_strdlen(a1));
- outstr(buf);
- refresh();
- getchar();
-
- outs(ANSI_COLOR(1;33) "test " ANSI_COLOR(34) "x"
- ANSI_RESET "te" ANSI_COLOR(43;0;1;35) " st"
- ANSI_COLOR(0) "testx\n");
- refresh();
- getchar();
-
- clear();
- outs("¤¤¤å¤¤¤å¤¤¤å¤¤¤å¤¤¤å¤¤¤å¤¤¤å¤¤¤å¤¤¤å¤¤¤å¤¤¤å¤¤¤å");
- move(0, 0);
- outs(" this\xFF (ff)is te.(80 tail)->\x80 (80)");
- refresh();
- getchar();
-#endif
-
-#if 1
- // test resize
- clear(); move(1, 0); outs("test resize\n");
- doupdate(); getchar();
- // expand X
- resizeterm(25,200);
- clear(); move(20, 0); clrtoeol(); outs("200x25");
- doupdate(); getchar();
- // resize back
- resizeterm(25,80);
- clear(); move(20, 0); clrtoeol(); outs("80x25");
- doupdate(); getchar();
- // expand Y
- resizeterm(60,80);
- clear(); move(20, 0); clrtoeol(); outs("80x60");
- doupdate(); getchar();
- // see if you crash here.
- resizeterm(60,200);
- clear(); move(20, 0); clrtoeol(); outs("200x60");
- doupdate(); getchar();
-#endif
-
-#if 0
- // test optimization
- clear();
- move(1, 0);
- outs("x++ optimization test\n");
- outs("1 2 3 4 5 6 7 8 9 0\n");
- outs("1122233334444455555566666667777777788888888899999999990\n");
- refresh();
- getchar();
-
- move(2, 0);
- outs("1122233334444455555566666667777777788888888899999999990\n");
- outs("1 2 3 4 5 6 7 8 9 0\n");
- refresh();
- getchar();
-
- rscroll();
- refresh();
- getchar();
-#endif
- } else {
- FILE *fp = fopen(argv[1], "r");
- int c = 0;
-
- while (fp && (c=getc(fp)) > 0)
- {
- outc(c);
- }
- fclose(fp);
- refresh();
- }
-
- endwin();
- printf("\ncomplete. enter to exit.\n");
- getchar();
- return 0;
-}
-#endif // _PFTERM_TEST_MAIN
-
-#endif // defined(EXP_PFTERM) || defined(USE_PFTERM)
-
-// vim:ts=4:sw=4:expandtab
diff --git a/mbbsd/pmore.c b/mbbsd/pmore.c
deleted file mode 100644
index fde26f3a..00000000
--- a/mbbsd/pmore.c
+++ /dev/null
@@ -1,3732 +0,0 @@
-/* $Id$ */
-
-/*
- * pmore: piaip's more, a new replacement for traditional pager
- *
- * piaip's new implementation of pager(more) with mmap,
- * designed for unlimilited length(lines).
- *
- * "pmore" is "piaip's more", NOT "PTT's more"!!!
- * pmore is designed for general maple-family BBS systems, not
- * specific to any branch.
- *
- * Author: Hung-Te Lin (piaip), June 2005.
- *
- * Copyright(c) 2005-2008 Hung-Te Lin <piaip@csie.ntu.edu.tw>
- * All Rights Reserved.
- * You are free to use, modify, redistribute this program in any
- * non-commercial usage (including network service).
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * MAJOR IMPROVEMENTS:
- * - Clean source code, and more readable for mortal
- * - Correct navigation
- * - Excellent search ability (for correctness and user behavior)
- * - Less memory consumption (mmap is not considered anyway)
- * - Better support for large terminals
- * - Unlimited file length and line numbers
- *
- * TODO AND DONE:
- * - [2005, Initial Release]
- * - Optimized speed up with Scroll supporting [done]
- * - Wrap long lines [done]
- * - Left-right wide navigation [done]
- * - DBCS friendly wrap [done]
- * - Reenrtance for main procedure [done]
- * - Support PTT_PRINTS [done]
- * - ASCII Art movie support [done]
- * - ASCII Art movie navigation keys [pending]
- * - A new optimized terminal base system (piterm) [dropped]
- * -
- * - [2007, Interactive Movie Enhancement]
- * - New Invisible Frame Header Code [done]
- * - Playback Control (pause, stop, skip) [done]
- * - Interactive Movie (Hyper-text) [done]
- * - Preference System (like board-conf) [done]
- * - Traditional Movie Compatible Mode [done]
- * - movie: Optimization on relative frame numbers [done]
- * - movie: Optimization on named frames (by hash)
- * -
- * - Support Anti-anti-idle (ex, PCMan sends up-down)
- * - Better help system [pending]
- * - Virtual Contatenate [pending]
- * - Drop ANSI between DBCS words if outputing UTF8 [drop, done by term]
- */
-
-// --------------------------------------------------------------- <FEATURES>
-/* These are default values.
- * You may override them in your bbs.h or config.h etc etc.
- */
-#define PMORE_PRELOAD_SIZE (64*1024L) // on busy system set smaller or undef
-
-#define PMORE_USE_PTT_PRINTS // support PTT or special printing
-#define PMORE_USE_OPT_SCROLL // optimized scroll
-#define PMORE_USE_DBCS_WRAP // safe wrap for DBCS.
-#define PMORE_USE_ASCII_MOVIE // support ascii movie
-//#define PMORE_RESTRICT_ANSI_MOVEMENT // user cannot use ANSI escapes to move
-#define PMORE_ACCURATE_WRAPEND // try more harder to find file end in wrap mode
-#define PMORE_TRADITIONAL_PROMPTEND // when prompt=NA, show only page 1
-#define PMORE_TRADITIONAL_FULLCOL // to work with traditional ascii arts
-#define PMORE_LOG_SYSOP_EDIT // log whenever sysop uses E
-#define PMORE_OVERRIDE_TIME // override time format if possible
-
-// if you are working with a terminal without ANSI control,
-// you are using a poor term (define PMORE_USING_POOR_TERM).
-#ifndef USE_PFTERM // pfterm is a good terminal system.
-#define PMORE_USING_POOR_TERM
-#define PMORE_WORKAROUND_CLRTOEOL // try to work with poor terminal sys
-#endif // USE_PFTERM
-// -------------------------------------------------------------- </FEATURES>
-
-// ----------------------------------------------------------- <LOCALIZATION>
-// Messages for localization are listed here.
-#define PMORE_MSG_PREF_TITLE \
- " pmore 2007 ³]©w¿ï¶µ "
-#define PMORE_MSG_PREF_TITLE_QRAW \
- " pmore 2007 §Ö³t³]©w¿ï¶µ - ¦â±m(ANSI½X)Åã¥Ü¼Ò¦¡ "
-#define PMORE_MSG_WARN_FAKEUSERINFO \
- " ¡¶¦¹­¶¤º®e·|¨Ì¾\\ŪªÌ¤£¦P,­ì¤å¥¼¥²¦³±zªº¸ê®Æ "
-#define PMORE_MSG_WARN_MOVECMD \
- " ¡¶¦¹­¶¤º®e§t²¾¦ì½X,¥i¯à·|Åã¥Ü°°³yªº¨t²Î°T®§ "
-#define PMORE_MSG_SEARCH_KEYWORD \
- "[·j´M]ÃöÁä¦r:"
-
-#define PMORE_MSG_MOVIE_DETECTED \
- " ¡¹ ³o¥÷¤å¥ó¬O¥i¼½©ñªº¤å¦r°Êµe¡A­n¶}©l¼½©ñ¶Ü¡H [Y/n]"
-#define PMORE_MSG_MOVIE_PLAYOLD_GETTIME \
- "³o¥i¯à¬O¶Ç²Î°ÊµeÀÉ, ­Y­nª½±µ¼½©ñ½Ð¿é¤J³t«×(¬í): "
-#define PMORE_MSG_MOVIE_PLAYOLD_AS24L \
- "¶Ç²Î°Êµe¬O¥H 24 ¦æ¬°³æ¦ì³]­pªº, ­n¼ÒÀÀ 24 ¦æ¶Ü? (§_«h·|¥Î²{¦bªº¦æ¼Æ)[Yn] "
-#define PMORE_MSG_MOVIE_PAUSE \
- " >>> ¼È°±¼½©ñ°Êµe¡A½Ð«ö¥ô·NÁäÄ~Äò©Î q ¤¤Â_¡C <<<"
-#define PMORE_MSG_MOVIE_PLAYING \
- " >>> °Êµe¼½©ñ¤¤... ¥i«ö q, Ctrl-C ©Î¨ä¥¦¥ô·NÁä°±¤î";
-#define PMORE_MSG_MOVIE_INTERACTION_PLAYING \
- " >>> ¤¬°Ê¦¡°Êµe¼½©ñ¤¤... ¥i«ö q ©Î Ctrl-C °±¤î";
-#define PMORE_MSG_MOVIE_INTERACTION_STOPPED \
- "¤w±j¨î¤¤Â_¤¬°Ê¦¡¨t²Î"
-
-// ----------------------------------------------------------- <LOCALIZATION>
-
-#include "bbs.h"
-
-#include <unistd.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <ctype.h>
-#include <string.h>
-
-// Platform Related. NoSync is faster but if we don't have it...
-// Experimental: POPULATE should work faster?
-#ifdef MAP_NOSYNC
-#define MF_MMAP_OPTION (MAP_NOSYNC|MAP_SHARED)
-#elif defined(MAP_POPULATE)
-#define MF_MMAP_OPTION (MAP_POPULATE|MAP_SHARED)
-#else
-#define MF_MMAP_OPTION (MAP_SHARED)
-#endif
-
-/* Developer's Guide
- *
- * OVERVIEW
- * - pmore is designed as a line-oriented pager. After you load (mf_attach)
- * a file, you can move current display window by lines (mf_forward and
- * mf_backward) and then display a page(mf_display).
- * And please remember to delete allocated resources (mf_detach)
- * when you exit.
- * - Functions are designed to work with global variables.
- * However you can overcome re-entrance problem by backuping up variables
- * or replace all "." to "->" with little modification and add pointer as
- * argument passed to each function.
- * (This is really tested and it works, however then using global variables
- * is considered to be faster and easier to maintain, at lease shorter in
- * time to key-in and for filelength).
- * - Basically this file should only export one function, "pmore".
- * Using any other functions here may be dangerous because they are not
- * coded for external reentrance rightnow.
- * - mf_* are operation functions to work with file buffer.
- * Usually these function assumes "mf" can be accessed.
- * - pmore_* are utility functions
- *
- * DETAIL
- * - The most tricky part of pmore is the design of "maxdisps" and "maxlinenoS".
- * What do they mean? "The pointer and its line number of last page".
- * - Because pmore is designed to work with very large files, it's costly to
- * calculate the total line numbers (and not necessary). But if we don't
- * know about how many lines left can we display then when navigating by
- * pages may result in a page with single line conent (if you set display
- * starting pointer to the real last line).
- * - To overcome this issue, maxdisps is introduced. It tries to go backward
- * one page from end of file (this operation is lighter than visiting
- * entire file content for line number calculation). Then we can set this
- * as boundary of forward navigation.
- * - maxlinenoS is the line number of maxdisps. It's NOT the real number of
- * total line in current file (You have to add the last page). That's why
- * it has a strange name of trailing "S", to hint you that it's not
- * "maxlineno" which is easily considered as "max(total) line number".
- *
- * HINTS:
- * - Remember mmap pointers are NOT null terminated strings.
- * You have to use strn* APIs and make sure not exceeding mmap buffer.
- * DO NOT USE strcmp, strstr, strchr, ...
- * - Scroll handling is painful. If you displayed anything on screen,
- * remember to MFDISP_DIRTY();
- * - To be portable between most BBS systems, pmore is designed to
- * workaround most BBS bugs inside itself.
- * - Basically pmore considered the 'outc' output system as unlimited buffer.
- * However on most BBS implementation, outc used a buffer with ANSILINELEN
- * in length. And for some branches they even used unsigned byte for index.
- * So if user complained about output truncated or blanked, increase buffer.
- */
-
-#ifdef DEBUG
-int debug = 0;
-# define MFPROTO
-#else
-# define MFPROTO inline static
-#endif
-
-/* DBCS users tend to write unsigned char. let's make compiler happy */
-#define ustrlen(x) strlen((char*)x)
-#define ustrchr(x,y) (unsigned char*)strchr((char*)x, y)
-#define ustrrchr(x,y) (unsigned char*)strrchr((char*)x, y)
-
-
-// --------------------------------------------- <Defines and constants>
-
-// --------------------------- <Display>
-
-/* ANSI COMMAND SYSTEM */
-/* On some systems with pmore style ANSI system applied,
- * we don't have to define these again.
- */
-#ifndef PMORE_STYLE_ANSI
-#define PMORE_STYLE_ANSI
-
-// Escapes. I don't like \033 everywhere.
-#define ESC_NUM (0x1b)
-#define ESC_STR "\x1b"
-#define ESC_CHR '\x1b'
-
-// Common ANSI commands.
-#define ANSI_RESET ESC_STR "[m"
-#define ANSI_COLOR(x) ESC_STR "[" #x "m"
-#define ANSI_CLRTOEND ESC_STR "[K"
-#define ANSI_MOVETO(y,x) ESC_STR "[" #y ";" #x "H"
-
-#define ANSI_IN_ESCAPE(x) (((x) >= '0' && (x) <= '9') || \
- (x) == ';' || (x) == ',' || (x) == '[')
-
-#endif /* PMORE_STYLE_ANSI */
-
-#define ANSI_IN_MOVECMD(x) (strchr("ABCDfjHJRu", x) != NULL)
-#define PMORE_DBCS_LEADING(c) (c >= 0x80)
-
-// Poor BBS terminal system Workarounds
-// - Most BBS implements clrtoeol() as fake command
-// and usually messed up when output ANSI quoted string.
-// - A workaround is suggested by kcwu:
-// https://opensvn.csie.org/traccgi/pttbbs/trac.cgi/changeset/519
-#define FORCE_CLRTOEOL() outs(ANSI_CLRTOEND)
-
-/* Again, if you have a BBS system which optimized out* without recognizing
- * ANSI escapes, scrolling with ANSI text may result in melformed text (because
- * ANSI escapes were "optimized" ). So here we provide a method to overcome
- * with this situation. However your should increase your I/O buffer to prevent
- * flickers.
- */
-MFPROTO void
-pmore_clrtoeol(int y, int x)
-{
-#ifdef PMORE_WORKAROUND_CLRTOEOL
- int i;
- move(y, x);
- for (i = x; i < t_columns; i++)
- outc(' ');
- clrtoeol();
- move(y, x); // this is required, due to outc().
-#else
- move(y, x);
- clrtoeol();
-#endif
-}
-
-// --------------------------- </Display>
-
-// --------------------------- <Main Navigation>
-typedef struct
-{
- unsigned char
- *start, *end, // file buffer
- *disps, *dispe, // displayed content start/end
- *maxdisps; // a very special pointer,
- // consider as "disps of last page"
- off_t len; // file total length
- long lineno, // lineno of disps
- oldlineno, // last drawn lineno, < 0 means full update
- xpos, // starting x position
- //
- wraplines, // wrapped lines in last display
- trunclines, // truncated lines in last display
- dispedlines, // how many different lines displayed
- // usually dispedlines = PAGE-wraplines,
- // but if last line is incomplete(wrapped),
- // dispedlines = PAGE-wraplines + 1
- lastpagelines,// lines of last page to show
- // this indicates how many lines can
- // maxdisps(maxlinenoS) display.
- maxlinenoS; // lineno of maxdisps, "S"!
- // What does the magic "S" mean?
- // Just trying to notify you that it's
- // NOT REAL MAX LINENO NOR FILELENGTH!!!
- // You may consider "S" of "Start" (disps).
-} MmappedFile;
-
-MmappedFile mf = {
- 0, 0, 0, 0, 0, 0L,
- 0, -1L, 0, 0, -1L, -1L, -1L,-1L
-}; // current file
-
-/* mf_* navigation commands return value meanings */
-enum MF_NAV_COMMANDS {
- MFNAV_OK, // navigation ok
- MFNAV_EXCEED, // request exceeds buffer
-};
-
-/* Navigation units (dynamic, so not in enum const) */
-#define MFNAV_PAGE (t_lines-2) // when navigation, how many lines in a page to move
-
-/* Display system */
-enum MF_DISP_CONST {
- /* newline method (because of poor BBS implementation) */
- MFDISP_NEWLINE_CLEAR = 0, // \n and cleartoeol
- MFDISP_NEWLINE_SKIP,
- MFDISP_NEWLINE_MOVE, // use move to simulate newline.
-
- MFDISP_OPT_CLEAR = 0,
- MFDISP_OPT_OPTIMIZED,
- MFDISP_OPT_FORCEDIRTY,
-
- // prefs
-
- MFDISP_WRAP_TRUNCATE = 0,
- MFDISP_WRAP_WRAP,
- MFDISP_WRAP_MODES,
-
- MFDISP_SEP_NONE = 0x00,
- MFDISP_SEP_LINE = 0x01,
- MFDISP_SEP_WRAP = 0x02,
- MFDISP_SEP_OLD = MFDISP_SEP_LINE | MFDISP_SEP_WRAP,
- MFDISP_SEP_MODES= 0x04,
-
- MFDISP_RAW_NA = 0x00,
- MFDISP_RAW_NOANSI,
- MFDISP_RAW_PLAIN,
- MFDISP_RAW_MODES,
-
-};
-
-#define MFDISP_PAGE (t_lines-1) // the real number of lines to be shown.
-#define MFDISP_DIRTY() { mf.oldlineno = -1; }
-
-/* Indicators */
-#define MFDISP_TRUNC_INDICATOR ANSI_COLOR(0;1;37) ">" ANSI_RESET
-#define MFDISP_WRAP_INDICATOR ANSI_COLOR(0;1;37) "\\" ANSI_RESET
-#define MFDISP_WNAV_INDICATOR ANSI_COLOR(0;1;37) "<" ANSI_RESET
-// --------------------------- </Main Navigation>
-
-// --------------------------- <Aux. Structures>
-/* browsing preference */
-typedef struct
-{
- /* mode flags */
- unsigned char
- wrapmode, // wrap?
- separator, // separator style
- wrapindicator, // show wrap indicators
-
- oldwrapmode, // traditional wrap
- oldstatusbar, // traditional statusbar
- rawmode; // show file as-is.
-} MF_BrowsingPreference;
-
-MF_BrowsingPreference bpref =
-{ MFDISP_WRAP_WRAP, MFDISP_SEP_OLD, 1,
- 0, 0, 0, };
-
-/* pretty format header */
-#define FH_HEADERS (4) // how many headers do we know?
-#define FH_HEADER_LEN (4) // strlen of each heads
-#define FH_FLOATS (2) // right floating, name and val
-static const char *_fh_disp_heads[FH_HEADERS] =
- {"§@ªÌ", "¼ÐÃD", "®É¶¡", "Âà«H"};
-
-typedef struct
-{
- int lines; // header lines
- unsigned char *headers[FH_HEADERS];
- unsigned char *floats [FH_FLOATS];
-} MF_PrettyFormattedHeader;
-
-MF_PrettyFormattedHeader fh = { 0, {0,0,0,0}, {0, 0}};
-
-/* search records */
-typedef struct
-{
- int len;
- int (*cmpfunc) (const char *, const char *, size_t);
- unsigned char *search_str; // maybe we can change to dynamic allocation
-} MF_SearchRecord;
-
-MF_SearchRecord sr = { 0, strncmp, NULL};
-
-enum MFSEARCH_DIRECTION {
- MFSEARCH_FORWARD,
- MFSEARCH_BACKWARD,
-};
-
-// Reset structures
-#define RESETMF() { memset(&mf, 0, sizeof(mf)); \
- mf.lastpagelines = mf.maxlinenoS = mf.oldlineno = -1; }
-#define RESETFH() { memset(&fh, 0, sizeof(fh)); \
- fh.lines = -1; }
-
-// Artwork
-#define OPTATTR_NORMAL ANSI_COLOR(0;34;47)
-#define OPTATTR_NORMAL_KEY ANSI_COLOR(0;31;47)
-#define OPTATTR_SELECTED ANSI_COLOR(0;1;37;46)
-#define OPTATTR_SELECTED_KEY ANSI_COLOR(0;31;46)
-#define OPTATTR_BAR ANSI_COLOR(0;1;30;47)
-
-// --------------------------- </Aux. Structures>
-
-// --------------------------------------------- </Defines and constants>
-
-// --------------------------------------------- <Optional Modules>
-#ifdef PMORE_USE_ASCII_MOVIE
-enum _MFDISP_MOVIE_MODES {
- MFDISP_MOVIE_UNKNOWN= 0,
- MFDISP_MOVIE_DETECTED,
- MFDISP_MOVIE_YES,
- MFDISP_MOVIE_NO,
- MFDISP_MOVIE_PLAYING,
- MFDISP_MOVIE_PLAYING_OLD,
-};
-
-typedef struct {
- struct timeval frameclk;
- struct timeval synctime;
- unsigned char *options,
- *optkeys;
- unsigned char mode,
- compat24,
- interactive,
- pause;
-} MF_Movie;
-
-MF_Movie mfmovie;
-
-#define STOP_MOVIE() { \
- mfmovie.options = NULL; \
- mfmovie.pause = 0; \
- if (mfmovie.mode == MFDISP_MOVIE_PLAYING) \
- mfmovie.mode = MFDISP_MOVIE_YES; \
- if (mfmovie.mode == MFDISP_MOVIE_PLAYING_OLD) \
- mfmovie.mode = MFDISP_MOVIE_NO; \
- mf_determinemaxdisps(MFNAV_PAGE, 0); \
- mf_forward(0); \
-}
-
-#define RESET_MOVIE() { \
- mfmovie.mode = MFDISP_MOVIE_UNKNOWN; \
- mfmovie.options = NULL; \
- mfmovie.optkeys = NULL; \
- mfmovie.compat24 = 1; \
- mfmovie.pause = 0; \
- mfmovie.interactive = 0; \
- mfmovie.synctime.tv_sec = mfmovie.synctime.tv_usec = 0; \
- mfmovie.frameclk.tv_sec = 1; mfmovie.frameclk.tv_usec = 0; \
-}
-
-#define MOVIE_IS_PLAYING() \
- ((mfmovie.mode == MFDISP_MOVIE_PLAYING) || \
- (mfmovie.mode == MFDISP_MOVIE_PLAYING_OLD))
-
-unsigned char *
- mf_movieFrameHeader(unsigned char *p, unsigned char *end);
-
-int pmore_wait_key(struct timeval *ptv, int dorefresh);
-int mf_movieNextFrame();
-int mf_movieSyncFrame();
-int mf_moviePromptPlaying(int type);
-int mf_movieMaskedInput(int c);
-
-void mf_float2tv(float f, struct timeval *ptv);
-
-#define MOVIE_MIN_FRAMECLK (0.1f)
-#define MOVIE_MAX_FRAMECLK (3600.0f)
-#define MOVIE_SECOND_U (1000000L)
-#define MOVIE_ANTI_ANTI_IDLE
-
-// some magic value that your igetch() will never return
-#define MOVIE_KEY_ANY (0x4d464b41)
-
-#ifndef MOVIE_KEY_BS2
-#define MOVIE_KEY_BS2 (0x7f)
-#endif
-
-#endif
-// --------------------------------------------- </Optional Modules>
-
-// used by mf_attach
-void mf_parseHeaders();
-void mf_freeHeaders();
-void mf_determinemaxdisps(int, int);
-
-/*
- * mmap basic operations
- */
-int
-mf_attach(const char *fn)
-{
- struct stat st;
- int fd = open(fn, O_RDONLY, 0600);
-
- if(fd < 0)
- return 0;
-
- if (fstat(fd, &st) || ((mf.len = st.st_size) <= 0) || S_ISDIR(st.st_mode))
- {
- mf.len = 0;
- close(fd);
- return 0;
- }
-
- /*
- mf.len = lseek(fd, 0L, SEEK_END);
- lseek(fd, 0, SEEK_SET);
- */
-
- mf.start = mmap(NULL, mf.len, PROT_READ,
- MF_MMAP_OPTION, fd, 0);
- close(fd);
-
- if(mf.start == MAP_FAILED)
- {
- RESETMF();
- return 0;
- }
-
- // BSD mmap advise. comment if your OS does not support this.
- madvise(mf.start, mf.len, MADV_SEQUENTIAL);
-
- mf.end = mf.start + mf.len;
- mf.disps = mf.dispe = mf.start;
- mf.lineno = 0;
-
- mf_determinemaxdisps(MFNAV_PAGE, 0);
-
- mf.disps = mf.dispe = mf.start;
- mf.lineno = 0;
-
- /* reset and parse article header */
- mf_parseHeaders();
-
- /* a workaround for wrapped separators */
- if(mf.maxlinenoS > 0 &&
- fh.lines >= mf.maxlinenoS &&
- bpref.separator & MFDISP_SEP_WRAP)
- {
- mf_determinemaxdisps(+1, 1);
- }
-
- return 1;
-}
-
-void
-mf_detach()
-{
- mf_freeHeaders();
- if(mf.start) {
- munmap(mf.start, mf.len);
- RESETMF();
- }
-}
-
-/*
- * lineno calculation, and moving
- */
-void
-mf_sync_lineno()
-{
- unsigned char *p;
-
- if(mf.disps == mf.maxdisps && mf.maxlinenoS >= 0)
- {
- mf.lineno = mf.maxlinenoS;
- } else {
- mf.lineno = 0;
- for (p = mf.start; p < mf.disps; p++)
- if(*p == '\n')
- mf.lineno ++;
-
- if(mf.disps == mf.maxdisps && mf.maxlinenoS < 0)
- mf.maxlinenoS = mf.lineno;
- }
-}
-
-MFPROTO int mf_backward(int); // used by mf_buildmaxdisps
-MFPROTO int mf_forward(int); // used by mf_buildmaxdisps
-
-void
-mf_determinemaxdisps(int backlines, int update_by_offset)
-{
- unsigned char *pbak = mf.disps, *mbak = mf.maxdisps;
- long lbak = mf.lineno;
-
- if(update_by_offset)
- {
- if(backlines > 0)
- {
- /* tricky way because usually
- * mf_forward checks maxdisps.
- */
- mf.disps = mf.maxdisps;
- mf.maxdisps = mf.end-1;
- mf_forward(backlines);
- mf_backward(0);
- } else
- mf_backward(backlines);
- } else {
- mf.lineno = backlines;
- mf.disps = mf.end - 1;
- backlines = mf_backward(backlines);
- }
-
- if(mf.disps != mbak)
- {
- mf.maxdisps = mf.disps;
- if(update_by_offset)
- mf.lastpagelines -= backlines;
- else
- mf.lastpagelines = backlines;
-
- mf.maxlinenoS = -1;
-#ifdef PMORE_PRELOAD_SIZE
- if(mf.len <= PMORE_PRELOAD_SIZE)
- mf_sync_lineno(); // maxlinenoS will be automatically updated
-#endif
- }
- mf.disps = pbak;
- mf.lineno = lbak;
-}
-
-/*
- * mf_backwards is also used for maxno determination,
- * so we cannot change anything in mf except these:
- * mf.disps
- * mf.lineno
- */
-MFPROTO int
-mf_backward(int lines)
-{
- int real_moved = 0;
-
- /* backward n lines means to find n times of '\n'. */
-
- /* if we're already in a line break, add one mark. */
- if (mf.disps < mf.end && *mf.disps == '\n')
- lines++, real_moved --;
-
- while (1)
- {
- if (mf.disps < mf.start || *mf.disps == '\n')
- {
- real_moved ++;
- if(lines-- <= 0 || mf.disps < mf.start)
- break;
- }
- mf.disps --;
- }
-
- /* now disps points to previous 1 byte of new address */
- mf.disps ++;
- real_moved --;
- mf.lineno -= real_moved;
-
- return real_moved;
-}
-
-MFPROTO int
-mf_forward(int lines)
-{
- int real_moved = 0;
-
- while(mf.disps <= mf.maxdisps && lines > 0)
- {
- while (mf.disps <= mf.maxdisps && *mf.disps++ != '\n');
-
- if(mf.disps <= mf.maxdisps)
- mf.lineno++, lines--, real_moved++;
- }
-
- if(mf.disps > mf.maxdisps)
- mf.disps = mf.maxdisps;
-
- /* please make sure you have lineno synced. */
- if(mf.disps == mf.maxdisps && mf.maxlinenoS < 0)
- mf.maxlinenoS = mf.lineno;
-
- return real_moved;
- /*
- if(lines > 0)
- return MFNAV_OK;
- else
- return MFNAV_EXCEED;
- */
-}
-
-int
-mf_goTop()
-{
- if(mf.disps == mf.start && mf.xpos > 0)
- mf.xpos = 0;
- mf.disps = mf.start;
- mf.lineno = 0;
- return MFNAV_OK;
-}
-
-int
-mf_goBottom()
-{
- mf.disps = mf.maxdisps;
- mf_sync_lineno();
-
- return MFNAV_OK;
-}
-
-MFPROTO int
-mf_goto(int lineno)
-{
- mf.disps = mf.start;
- mf.lineno = 0;
- return mf_forward(lineno);
-}
-
-MFPROTO int
-mf_viewedNone()
-{
- return (mf.disps <= mf.start);
-}
-
-MFPROTO int
-mf_viewedAll()
-{
- return (mf.dispe >= mf.end);
-}
-/*
- * search!
- */
-int
-mf_search(int direction)
-{
- unsigned char *s = sr.search_str;
- int l = sr.len;
- int flFound = 0;
-
- if(!s || !*s)
- return 0;
-
- if(direction == MFSEARCH_FORWARD)
- {
- mf_forward(1);
- while(mf.disps < mf.end - l)
- {
- if(sr.cmpfunc((char*)mf.disps, (char*)s, l) == 0)
- {
- flFound = 1;
- break;
- } else {
- /* DBCS check here. */
- if(PMORE_DBCS_LEADING(*mf.disps++))
- mf.disps++;
- }
- }
- mf_backward(0);
- if(mf.disps > mf.maxdisps)
- mf.disps = mf.maxdisps;
- mf_sync_lineno();
- }
- else if(direction == MFSEARCH_BACKWARD)
- {
- mf_backward(1);
- while (!flFound && mf.disps > mf.start)
- {
- while(!flFound && mf.disps < mf.end-l && *mf.disps != '\n')
- {
- if(sr.cmpfunc((char*)mf.disps, (char*)s, l) == 0)
- {
- flFound = 1;
- } else
- {
- /* DBCS check here. */
- if(PMORE_DBCS_LEADING(*mf.disps++))
- mf.disps++;
- }
- }
- if(!flFound)
- mf_backward(1);
- }
- mf_backward(0);
- if(mf.disps < mf.start)
- mf.disps = mf.start;
- mf_sync_lineno();
- }
- if(flFound)
- MFDISP_DIRTY();
- return flFound;
-}
-
-/* String Processing
- *
- * maybe you already have your string processors (or not).
- * whether yes or no, here we provides some.
- */
-
-#define ISSPACE(x) (x <= ' ')
-
-MFPROTO void
-pmore_str_strip_ansi(unsigned char *p) // warning: p is NULL terminated
-{
- unsigned char *pb = p;
- while (*p != 0)
- {
- if (*p == ESC_CHR)
- {
- // ansi code sequence, ignore them.
- pb = p++;
- while (ANSI_IN_ESCAPE(*p))
- p++;
- memmove(pb, p, ustrlen(p)+1);
- p = pb;
- }
- else if (*p < ' ' || *p == 0xff)
- {
- // control codes, ignore them.
- // what is 0xff? old BBS does not handle telnet protocol
- // so IACs were inserted.
- memmove(p, p+1, ustrlen(p+1)+1);
- }
- else
- p++;
- }
-}
-
-/* this chomp is a little different:
- * it kills starting and trailing spaces.
- */
-MFPROTO void
-pmore_str_chomp(unsigned char *p)
-{
- unsigned char *pb = p + ustrlen(p)-1;
-
- while (pb >= p)
- if(ISSPACE(*pb))
- *pb-- = 0;
- else
- break;
- pb = p;
- while (*pb && ISSPACE(*pb))
- pb++;
-
- if(pb != p)
- memmove(p, pb, ustrlen(pb)+1);
-}
-
-#if 0
-int
-pmore_str_safe_big5len(unsigned char *p)
-{
- return 0;
-}
-#endif
-
-/*
- * Format Related
- */
-
-void
-mf_freeHeaders()
-{
- if(fh.lines > 0)
- {
- int i;
-
- for (i = 0; i < FH_HEADERS; i++)
- free(fh.headers[i]);
- for (i = 0; i < FH_FLOATS; i++)
- free(fh.floats[i]);
- RESETFH();
- }
-}
-
-void
-mf_parseHeaders()
-{
- /* file format:
- * AUTHOR: author BOARD: blah <- headers[0], floats[0], floats[1]
- * XXX: xxx <- headers[1]
- * XXX: xxx <- headers[n]
- * [blank, fill with separator] <- lines
- *
- * #define STR_AUTHOR1 "§@ªÌ:"
- * #define STR_AUTHOR2 "µo«H¤H:"
- */
- unsigned char *pmf = mf.start;
- int i = 0;
-
- RESETFH();
-
- if(mf.len < LEN_AUTHOR2)
- return;
-
- if (strncmp((char*)mf.start, STR_AUTHOR1, LEN_AUTHOR1) == 0)
- {
- fh.lines = 3; // local
- }
- else if (strncmp((char*)mf.start, STR_AUTHOR2, LEN_AUTHOR2) == 0)
- {
- fh.lines = 4;
- }
- else
- return;
-
- for (i = 0; i < fh.lines; i++)
- {
- unsigned char *p = pmf, *pb = pmf;
- int l;
-
- /* first, go to line-end */
- while(pmf < mf.end && *pmf != '\n')
- pmf++;
- if(pmf >= mf.end)
- break;
- p = pmf;
- pmf ++; // move to next line.
-
- // p is pointing at a new line. (\n)
- l = (int)(p - pb);
-#ifdef CRITICAL_MEMORY
- // kcwu: dirty hack, avoid 64byte slot. use 128byte slot instead.
- if (l<100) {
- p = (unsigned char*) malloc (100+1);
- } else {
- p = (unsigned char*) malloc (l+1);
- }
-#else
- p = (unsigned char*) malloc (l+1);
-#endif
- fh.headers[i] = p;
- memcpy(p, pb, l);
- p[l] = 0;
-
- // now, postprocess p.
- pmore_str_strip_ansi(p);
-
-#ifdef PMORE_OVERRIDE_TIME
- // (deprecated: too many formats for newsgroup)
- // try to see if this is a valid time line
- // use strptime to convert
-#endif // PMORE_OVERRIDE_TIME
-
- // strip to quotes[+1 space]
- if((pb = ustrchr((char*)p, ':')) != NULL)
- {
- if(*(pb+1) == ' ') pb++;
- memmove(p, pb, ustrlen(pb)+1);
- }
-
- // kill staring and trailing spaces
- pmore_str_chomp(p);
-
- // special case, floats are in line[0].
- if(i == 0 && (pb = ustrrchr(p, ':')) != NULL && *(pb+1))
- {
- unsigned char *np = (unsigned char*)strdup((char*)(pb+1));
-
- fh.floats[1] = np;
- pmore_str_chomp(np);
- // remove quote and traverse back
- *pb-- = 0;
- while (pb > p && *pb != ',' && !(ISSPACE(*pb)))
- pb--;
-
- if (pb > p) {
- fh.floats[0] = (unsigned char*)strdup((char*)(pb+1));
- pmore_str_chomp(fh.floats[0]);
- *pb = 0;
- pmore_str_chomp(fh.headers[0]);
- } else {
- fh.floats[0] = (unsigned char*)strdup("");
- }
- }
- }
-}
-
-/*
- * mf_display utility macros
- */
-MFPROTO void
-MFDISP_SKIPCURLINE()
-{
- while (mf.dispe < mf.end && *mf.dispe != '\n')
- mf.dispe++;
-}
-
-MFPROTO int
-MFDISP_PREDICT_LINEWIDTH(unsigned char *p)
-{
- /* predict from p to line-end, without ANSI seq.
- */
- int off = 0;
- int inAnsi = 0;
-
- while (p < mf.end && *p != '\n')
- {
- if(inAnsi)
- {
- if(!ANSI_IN_ESCAPE(*p))
- inAnsi = 0;
- } else {
- if(*p == ESC_CHR)
- inAnsi = 1;
- else
- off ++;
- }
- p++;
- }
- return off;
-}
-
-MFPROTO int
-MFDISP_DBCS_HEADERWIDTH(int originalw)
-{
- return originalw - (originalw %2);
-// return (originalw >> 1) << 1;
-}
-
-#define MFDISP_FORCEUPDATE2TOP() { startline = 0; }
-#define MFDISP_FORCEUPDATE2BOT() { endline = MFDISP_PAGE - 1; }
-#define MFDISP_FORCEDIRTY2BOT() \
- if(optimized == MFDISP_OPT_OPTIMIZED) { \
- optimized = MFDISP_OPT_FORCEDIRTY; \
- MFDISP_FORCEUPDATE2BOT(); \
- }
-
-static char *override_msg = NULL;
-static char *override_attr = NULL;
-
-#define RESET_OVERRIDE_MSG() { override_attr = override_msg = NULL; }
-
-/*
- * display mf content from disps for MFDISP_PAGE
- */
-
-void
-mf_display()
-{
- int lines = 0, col = 0, currline = 0, wrapping = 0;
- int startline, endline;
- int needMove2bot = 0;
-
- int optimized = MFDISP_OPT_CLEAR;
-
- /* why t_columns-1 here?
- * because BBS systems usually have a poor terminal system
- * and many stupid clients behave differently.
- * So we try to avoid using the last column, leave it for
- * BBS to place '\n' and CLRTOEOL.
- */
- const int headerw = MFDISP_DBCS_HEADERWIDTH(t_columns-1);
- const int dispw = headerw - (t_columns - headerw < 2);
- const int maxcol = dispw - 1;
- int newline_default = MFDISP_NEWLINE_CLEAR;
-
- if(mf.wraplines || mf.trunclines)
- MFDISP_DIRTY(); // we can't scroll with wrapped lines.
-
- mf.wraplines = 0;
- mf.trunclines = 0;
- mf.dispedlines = 0;
-
- MFDISP_FORCEUPDATE2TOP();
- MFDISP_FORCEUPDATE2BOT();
-
-#ifdef PMORE_USE_OPT_SCROLL
-
-#if defined(PMORE_USE_ASCII_MOVIE) && !defined(PMORE_USING_POOR_TERM)
- // For movies, maybe clear() is better.
- // Let's enable for good terminals (which does not need workarounds)
- if (MOVIE_IS_PLAYING())
- {
- clear(); move(0, 0);
- } else
-#endif // PMORE_USE_ASCII_MOVIE && (!PMORE_USING_POOR_TERM)
-
- /* process scrolling */
- if (mf.oldlineno >= 0 && mf.oldlineno != mf.lineno)
- {
- int scrll = mf.lineno - mf.oldlineno, i;
- int reverse = (scrll > 0 ? 0 : 1);
-
- if(reverse)
- scrll = -scrll;
- else
- {
- /* because bottom status line is also scrolled,
- * we have to erase it here.
- */
- pmore_clrtoeol(b_lines, 0);
- // move(b_lines, 0);
- // clrtoeol();
- }
-
- if(scrll > MFDISP_PAGE)
- scrll = MFDISP_PAGE;
-
- i = scrll;
-
-#if defined(USE_PFTERM)
- // In fact, pfterm will flash black screen when scrolling pages...
- // So it may work better if we refresh whole screen.
- if (i >= b_lines / 2)
- {
- clear(); move(0, 0);
- scrll = MFDISP_PAGE;
- } else
-#endif // defined(USE_PFTERM)
-
- while(i-- > 0)
- if (reverse)
- rscroll(); // v
- else
- scroll(); // ^
-
- if(reverse)
- {
- endline = scrll-1; // v
- // clear the line which will be scrolled
- // to bottom (status line position).
- pmore_clrtoeol(b_lines, 0);
- // move(b_lines, 0);
- // clrtoeol();
- }
- else
- {
- startline = MFDISP_PAGE - scrll; // ^
- }
- move(startline, 0);
- optimized = MFDISP_OPT_OPTIMIZED;
- // return; // uncomment if you want to observe scrolling
- }
- else
-#endif
- clear(), move(0, 0);
-
- mf.dispe = mf.disps;
- while (lines < MFDISP_PAGE)
- {
- int inAnsi = 0;
- int newline = newline_default;
- int predicted_linewidth = -1;
- int xprefix = mf.xpos;
-
-#ifdef PMORE_USE_DBCS_WRAP
- unsigned char *dbcs_incomplete = NULL;
-#endif
-
- currline = mf.lineno + lines;
- col = 0;
-
- if(!wrapping && mf.dispe < mf.end)
- mf.dispedlines++;
-
- if(optimized == MFDISP_OPT_FORCEDIRTY)
- {
- /* btw, apparently this line should be visible.
- * if not, maybe something wrong.
- */
- pmore_clrtoeol(lines, 0);
- }
-
-#ifdef PMORE_USE_ASCII_MOVIE
- if(mfmovie.mode == MFDISP_MOVIE_PLAYING_OLD &&
- mfmovie.compat24)
- {
- if(mf.dispedlines == 23)
- return;
- }
- else if (mfmovie.mode == MFDISP_MOVIE_DETECTED)
- {
- // detected only applies for first page.
- // since this is not very often, let's prevent
- // showing control codes.
- if(mf_movieFrameHeader(mf.dispe, mf.end))
- MFDISP_SKIPCURLINE();
- }
- else if(mfmovie.mode == MFDISP_MOVIE_UNKNOWN ||
- mfmovie.mode == MFDISP_MOVIE_PLAYING)
- {
- if(mf_movieFrameHeader(mf.dispe, mf.end))
- switch(mfmovie.mode)
- {
-
- case MFDISP_MOVIE_UNKNOWN:
- mfmovie.mode = MFDISP_MOVIE_DETECTED;
- /* let's remove the first control sequence. */
- MFDISP_SKIPCURLINE();
- break;
-
- case MFDISP_MOVIE_PLAYING:
- /*
- * maybe we should do clrtobot() here,
- * but it's even better if we do clear()
- * all time. so we set dirty here for
- * next frame, and please set dirty before
- * playing.
- */
- MFDISP_DIRTY();
- return;
- }
- }
-#endif
-
- /* Is currentline visible? */
- if (lines < startline || lines > endline)
- {
- MFDISP_SKIPCURLINE();
- newline = MFDISP_NEWLINE_SKIP;
- }
- /* Now, consider what kind of line
- * (header, separator, or normal text)
- * is current line.
- */
- else if (currline == fh.lines && bpref.rawmode == MFDISP_RAW_NA)
- {
- /* case 1, header separator line */
- if (bpref.separator & MFDISP_SEP_LINE)
- {
- outs(ANSI_COLOR(36));
- for(col = 0; col < headerw; col+=2)
- {
- // prints("%02d", col);
- outs("¢w");
- }
- outs(ANSI_RESET);
- }
-
- /* Traditional 'more' adds separator as a newline.
- * This is buggy, however we can support this
- * by using wrapping features.
- * Anyway I(piaip) don't like this. And using wrap
- * leads to slow display (we cannt speed it up with
- * optimized scrolling.
- */
- if(bpref.separator & MFDISP_SEP_WRAP)
- {
- /* we have to do all wrapping stuff
- * in normal text section.
- * make sure this is updated.
- */
- wrapping = 1;
- mf.wraplines ++;
- MFDISP_FORCEDIRTY2BOT();
- if(mf.dispe > mf.start &&
- mf.dispe < mf.end &&
- *mf.dispe == '\n')
- mf.dispe --;
- }
- else
- MFDISP_SKIPCURLINE();
- }
- else if (currline < fh.lines && bpref.rawmode == MFDISP_RAW_NA )
- {
- /* case 2, we're printing headers */
- const char *val = (const char*)fh.headers[currline];
- const char *name = _fh_disp_heads[currline];
- int w = headerw - FH_HEADER_LEN - 3;
-
- outs(ANSI_COLOR(47;34) " ");
- outs(name);
- outs(" " ANSI_COLOR(44;37) " ");
-
- /* right floating stuff? */
- if (currline == 0 && fh.floats[0])
- {
- w -= ustrlen(fh.floats[0]) + ustrlen(fh.floats[1]) + 4;
- }
-
- prints("%-*.*s", w, w,
- (val ? val : ""));
-
- if (currline == 0 && fh.floats[0])
- {
- outs(ANSI_COLOR(47;34) " ");
- outs((const char*)fh.floats[0]);
- outs(" " ANSI_COLOR(44;37) " ");
- outs((const char*)fh.floats[1]);
- outs(" ");
- }
-
- outs(ANSI_RESET);
- MFDISP_SKIPCURLINE();
- }
- else if(mf.dispe < mf.end)
- {
- /* case 3, normal text */
- long dist = mf.end - mf.dispe;
- long flResetColor = 0;
- int srlen = -1;
- int breaknow = 0;
-
- unsigned char c;
-
- if(xprefix > 0 && !bpref.oldwrapmode && bpref.wrapindicator)
- {
- outs(MFDISP_WNAV_INDICATOR);
- col++;
- }
-
- // first check quote
- if(bpref.rawmode == MFDISP_RAW_NA)
- {
- if(dist > 1 &&
- (*mf.dispe == ':' || *mf.dispe == '>') &&
- *(mf.dispe+1) == ' ')
- {
- outs(ANSI_COLOR(36));
- flResetColor = 1;
- } else if (dist > 2 &&
- (!strncmp((char*)mf.dispe, "¡°", 2) ||
- !strncmp((char*)mf.dispe, "==>", 3)))
- {
- outs(ANSI_COLOR(32));
- flResetColor = 1;
- }
- }
-
- while(!breaknow && mf.dispe < mf.end && (c = *mf.dispe) != '\n')
- {
- if(inAnsi)
- {
- if (!ANSI_IN_ESCAPE(c))
- inAnsi = 0;
- /* whatever this is, output! */
- mf.dispe ++;
- switch(bpref.rawmode)
- {
- case MFDISP_RAW_NOANSI:
- /* TODO
- * col++ here may be buggy. */
- if(col < t_columns)
- {
- /* we tried our best to determine */
- if(xprefix > 0)
- xprefix --;
- else
- {
- outc(c);
- col++;
- }
- }
- if(!inAnsi)
- outs(ANSI_RESET);
- break;
- case MFDISP_RAW_PLAIN:
- break;
-
- default:
- if(ANSI_IN_MOVECMD(c))
- {
-#ifdef PMORE_RESTRICT_ANSI_MOVEMENT
- c = 's'; // "save cursor pos"
-#else // PMORE_RESTRICT_ANSI_MOVEMENT
- // some user cannot live without this.
- // make them happy.
- newline_default = newline = MFDISP_NEWLINE_MOVE;
-#ifdef PMORE_USE_ASCII_MOVIE
- // relax for movies
- if (!MOVIE_IS_PLAYING())
-#endif // PMORE_USE_ASCII_MOVIE
- {
- override_attr = ANSI_COLOR(1;37;41);
- override_msg = PMORE_MSG_WARN_MOVECMD;
- }
-#endif // PMORE_RESTRICT_ANSI_MOVEMENT
- needMove2bot = 1;
- }
- outc(c);
- break;
- }
- continue;
-
- } else {
-
- if(c == ESC_CHR)
- {
- inAnsi = 1;
- /* we can't output now because maybe
- * ptt_prints wants to do something.
- */
- }
- else if(sr.search_str && srlen < 0 && // support search
-#ifdef PMORE_USE_DBCS_WRAP
- dbcs_incomplete == NULL &&
-#endif
- mf.end - mf.dispe > sr.len &&
- sr.cmpfunc((char*)mf.dispe, (char*)sr.search_str, sr.len) == 0)
- {
- outs(ANSI_COLOR(7));
- srlen = sr.len-1;
- flResetColor = 1;
- }
-
-#ifdef PMORE_USE_PTT_PRINTS
- /* special case to resolve dirty Ptt_prints */
- if(inAnsi &&
- mf.end - mf.dispe > 2 &&
- *(mf.dispe+1) == '*')
- {
- int i;
- char buf[64]; // make sure ptt_prints will not exceed
-
- memset(buf, 0, sizeof(buf));
- memcpy(buf, mf.dispe, 3); // ^[*s
- mf.dispe += 2;
-
- if(bpref.rawmode)
- buf[0] = '*';
- else
- {
-#ifdef LOW_SECURITY
-# define PTTPRINT_WARN_PATTERN "slpnbm"
-#else
-# define PTTPRINT_WARN_PATTERN "slpn"
-#endif // LOW_SECURITY
- if(strchr(PTTPRINT_WARN_PATTERN, buf[2]) != NULL)
- {
- override_attr = ANSI_COLOR(1;37;41);
- override_msg = PMORE_MSG_WARN_FAKEUSERINFO;
- }
- Ptt_prints(buf, sizeof(buf), NO_RELOAD); // result in buf
- }
- i = strlen(buf);
-
- if (col + i > maxcol)
- i = maxcol - col;
- if(i > 0)
- {
- buf[i] = 0;
- col += i;
- outs(buf);
- }
- inAnsi = 0;
- } else
-#endif
- if(inAnsi)
- {
- switch(bpref.rawmode)
- {
- case MFDISP_RAW_NOANSI:
- /* TODO
- * col++ here may be buggy. */
- if(col < t_columns)
- {
- /* we tried our best to determine */
- if(xprefix > 0)
- xprefix --;
- else
- {
- outs(ANSI_COLOR(1) "*");
- col++;
- }
- }
- break;
- case MFDISP_RAW_PLAIN:
- break;
- default:
- outc(ESC_CHR);
- break;
- }
- } else {
- int canOutput = 0;
- /* if col > maxcol,
- * because we have the space for
- * "indicators" (one byte),
- * so we can tolerate one more byte.
- */
- if(col <= maxcol) // normal case
- canOutput = 1;
- else if (bpref.oldwrapmode && // oldwrapmode
- col < t_columns)
- {
- canOutput = 1;
- newline = MFDISP_NEWLINE_MOVE;
- } else {
- int off = 0;
- // put more efforts to determine
- // if we can use indicator space
- // determine real offset between \n
- if(predicted_linewidth < 0)
- predicted_linewidth = col + 1 +
- MFDISP_PREDICT_LINEWIDTH(mf.dispe+1);
- off = predicted_linewidth - (col + 1);
-
- if (col + off <= (maxcol+1))
- {
- canOutput = 1; // indicator space
- }
-#ifdef PMORE_TRADITIONAL_FULLCOL
- else if (col + off < t_columns)
- {
- canOutput = 1;
- newline = MFDISP_NEWLINE_MOVE;
- }
-#endif
- }
-
- if(canOutput)
- {
- /* the real place to output text
- */
-#ifdef PMORE_USE_DBCS_WRAP
- if(mf.xpos > 0 && dbcs_incomplete && col < 2)
- {
- /* col = 0 or 1 only */
- if(col == 0) /* no indicators */
- c = ' ';
- else if(!bpref.oldwrapmode && bpref.wrapindicator)
- c = ' ';
- }
-
- if (dbcs_incomplete)
- dbcs_incomplete = NULL;
- else if(PMORE_DBCS_LEADING(c))
- dbcs_incomplete = mf.dispe;
-#endif
- if(xprefix > 0)
- xprefix --;
- else
- {
- outc(c);
- col++;
- }
-
- if (srlen == 0)
- outs(ANSI_RESET);
- if(srlen >= 0)
- srlen --;
- }
- else
- /* wrap modes */
- if(mf.xpos > 0 || bpref.wrapmode == MFDISP_WRAP_TRUNCATE)
- {
- breaknow = 1;
- mf.trunclines ++;
- MFDISP_SKIPCURLINE();
- wrapping = 0;
- }
- else if (bpref.wrapmode == MFDISP_WRAP_WRAP)
- {
- breaknow = 1;
- wrapping = 1;
- mf.wraplines ++;
-#ifdef PMORE_USE_DBCS_WRAP
- if(dbcs_incomplete)
- {
- mf.dispe = dbcs_incomplete;
- dbcs_incomplete = NULL;
- /* to be more dbcs safe,
- * use the followings to
- * erase printed character.
- */
- if(col > 0) {
- /* TODO BUG BUGGY
- * using move is maybe actually non-sense
- * because BBS terminal system cannot
- * display this when ANSI escapes were used
- * in same line. However, on most
- * situation this works.
- * So we used an alternative, forced ANSI
- * move command.
- */
- // move(lines, col-1);
- char ansicmd[16];
- sprintf(ansicmd, ANSI_MOVETO(%d,%d),
- lines+1, col-1+1);
- /* to preven ANSI ESCAPE being tranlated as
- * DBCS trailing byte. */
- outc(' ');
- /* move back one column */
- outs(ansicmd);
- /* erase it (previous leading byte)*/
- outc(' ');
- /* go to correct position */
- outs(ansicmd);
- }
- }
-#endif
- }
- }
- }
- if(!breaknow)
- mf.dispe ++;
- }
- if(flResetColor)
- outs(ANSI_RESET);
-
- /* "wrapping" should be only in normal text section.
- * We don't support wrap within scrolling,
- * so if we have to wrap, invalidate all lines.
- */
- if(breaknow)
- {
- if(wrapping)
- MFDISP_FORCEDIRTY2BOT();
-
- if(!bpref.oldwrapmode && bpref.wrapindicator && col < t_columns)
- {
- if(wrapping)
- outs(MFDISP_WRAP_INDICATOR);
- else
- outs(MFDISP_TRUNC_INDICATOR);
- } else {
- outs(ANSI_RESET);
- }
- }
- else
- wrapping = 0;
- }
-
- if(mf.dispe < mf.end && *mf.dispe == '\n')
- mf.dispe ++;
- // else, we're in wrap mode.
-
- switch(newline)
- {
- case MFDISP_NEWLINE_SKIP:
- break;
- case MFDISP_NEWLINE_CLEAR:
- FORCE_CLRTOEOL();
- outc('\n');
- break;
- case MFDISP_NEWLINE_MOVE:
- move(lines+1, 0);
- break;
- }
- lines ++;
- }
- /*
- * we've displayed the file.
- * but if we got wrapped lines in last page,
- * mf.maxdisps may be required to be larger.
- */
- if(mf.disps == mf.maxdisps && mf.dispe < mf.end)
- {
- /*
- * never mind if that's caused by separator
- * however this code is rarely used now.
- * only if no preload file.
- */
- if (bpref.separator & MFDISP_SEP_WRAP &&
- mf.wraplines == 1 &&
- mf.lineno < fh.lines)
- {
- /*
- * o.k, now we know maxline should be one line forward.
- */
- mf_determinemaxdisps(+1, 1);
- } else
- {
- /* not caused by separator?
- * ok, then it's by wrapped lines.
- *
- * old flavor: go bottom:
- * mf_determinemaxdisps(0)
- * however we have "update" method now,
- * so we can achieve more user friendly behavior.
- */
- mf_determinemaxdisps(+mf.wraplines, 1);
- }
- }
- mf.oldlineno = mf.lineno;
-
- if (needMove2bot)
- move(b_lines, 0);
-}
-
-/* --------------------- MAIN PROCEDURE ------------------------- */
-void pmore_Preference();
-void pmore_QuickRawModePref();
-void pmore_Help();
-
-static const char * const pmore_help[] = {
- "\0¾\\Ū¤å³¹¥\\¯àÁä¨Ï¥Î»¡©ú",
- "\01´å¼Ð²¾°Ê¥\\¯àÁä",
- "(k/¡ô) (j/¡õ/Enter) ¤W±²/¤U±²¤@¦æ",
- "(^B/PgUp/BackSpace) ¤W±²¤@­¶",
- "(^F/PgDn/Space/¡÷) ¤U±²¤@­¶",
- "(,/</S-TAB)(./>/TAB) ¥ª/¥k±²°Ê",
- "(0/g/Home) ($/G/End) Àɮ׶}ÀY/µ²§À",
- "¼Æ¦rÁä 1-9 (;/:) ¸õ¦Ü¿é¤Jªº­¶¼Æ©Î¦æ¼Æ",
- "\01¶i¶¥¥\\¯àÁä",
- "(/) (s) ·j´MÃöÁä¦r/¤Á´«¦Ü¨ä¥¦¬ÝªO",
- "(n/N) ­«½Æ¥¿/¤Ï¦V·j´M",
- "(f/b) ¸õ¦Ü¤U/¤W½g",
- "(a/A) ¸õ¦Ü¦P¤@§@ªÌ¤U/¤W½g",
- "(t/[-/]+) ¥DÃD¦¡¾\\Ū:´`§Ç/«e/«á½g",
- "\01¨ä¥L¥\\¯àÁä",
-
- // the line below is already aligned, because of the backslash.
- "(o)/(\\) ¿ï¶µ³]©w/¦â±mÅã¥Ü¼Ò¦¡",
-
-#if defined (PMORE_USE_ASCII_MOVIE) || defined(RET_DOCHESSREPLAY)
- "(p)/(z) ¼½©ñ°Êµe/´Ñ§½¥´ÃÐ",
-#endif // defined(PMORE_USE_ASCII_MOVIE) || defined(RET_DOCHESSREPLAY)
-#ifdef RET_COPY2TMP
- "(Ctrl-T) ¦s¤J¼È¦sÀÉ",
-#endif
- "(q/¡ö) (h/H/?/F1) µ²§ô/¥»»¡©úµe­±",
-#ifdef DEBUG
- "(d) ¤Á´«°£¿ù(debug)¼Ò¦¡",
-#endif
- /* You don't have to delete this copyright line.
- * It will be located in bottom of screen and overrided by
- * status line. Only user with big terminals will see this :)
- */
- "\01¥»¨t²Î¨Ï¥Î piaip ªº·s¦¡ÂsÄýµ{¦¡: pmore 2007, piaip's more",
- NULL
-};
-/*
- * pmore utility macros
- */
-MFPROTO void
-PMORE_UINAV_FORWARDPAGE()
-{
- /* Usually, a forward is just mf_forward(MFNAV_PAGE);
- * but because of wrapped lines...
- * This function is used when user tries to nagivate
- * with page request.
- * If you want to a real page forward, don't use this.
- * That's why we have this special function.
- */
- int i = mf.dispedlines - 1;
-
- if(mf_viewedAll())
- return;
-
- if(i < 1)
- i = 1;
- mf_forward(i);
-}
-
-MFPROTO void
-PMORE_UINAV_FORWARDLINE()
-{
- if(mf_viewedAll())
- return;
- mf_forward(1);
-}
-
-#define REENTRANT_RESTORE() { mf = bkmf; fh = bkfh; }
-
-/*
- * piaip's more, a replacement for old more
- */
-int
-pmore(char *fpath, int promptend)
-{
- int flExit = 0, retval = 0;
- int ch = 0;
- int invalidate = 1;
-
- /* simple re-entrant hack
- * I don't want to write pointers everywhere,
- * and pmore should be simple enough (inside itself)
- * so we can do so.
- */
-
- MmappedFile bkmf;
- MF_PrettyFormattedHeader bkfh;
-
-#ifdef PMORE_USE_ASCII_MOVIE
- RESET_MOVIE();
-#endif
-
- bkmf = mf; /* simple re-entrant hack */
- bkfh = fh;
- RESETFH();
- RESETMF();
-
- override_msg = NULL; /* elimiate pending errors */
-
- STATINC(STAT_MORE);
- if(!mf_attach(fpath))
- {
- REENTRANT_RESTORE();
- return -1;
- }
-
- clear();
- while(!flExit)
- {
- if(invalidate)
- {
- mf_display();
- invalidate = 0;
- }
-
- /* in current implementation,
- * we want to invalidate for each keypress.
- */
- invalidate = 1;
-
-#ifdef PMORE_TRADITIONAL_PROMPTEND
-
- if(promptend == NA)
- {
-#ifdef PMORE_USE_ASCII_MOVIE
- if(mfmovie.mode == MFDISP_MOVIE_DETECTED)
- {
- /* quick auto play */
- mfmovie.mode = MFDISP_MOVIE_YES;
- RESET_MOVIE();
- mfmovie.mode = MFDISP_MOVIE_PLAYING;
- mf_determinemaxdisps(0, 0); // display until last line
- mf_movieNextFrame();
- MFDISP_DIRTY();
- continue;
- } else if (mfmovie.mode != MFDISP_MOVIE_PLAYING)
-#endif
- break;
- }
-#else
- if(promptend == NA && mf_viewedAll())
- break;
-#endif
- move(b_lines, 0);
- // clrtoeol(); // this shall be done in mf_display to speed up.
-
-#ifdef USE_BBSLUA
- // TODO prompt BBS Lua status here.
-#endif // USE_BBSLUA
-
-#ifdef PMORE_USE_ASCII_MOVIE
- switch (mfmovie.mode)
- {
- case MFDISP_MOVIE_UNKNOWN:
- mfmovie.mode = MFDISP_MOVIE_NO;
- break;
-
- case MFDISP_MOVIE_DETECTED:
- mfmovie.mode = MFDISP_MOVIE_YES;
- {
- // query if user wants to play movie.
-
- int w = t_columns-1;
- const char *s = PMORE_MSG_MOVIE_DETECTED;
-
- outs(ANSI_RESET ANSI_COLOR(1;33;44));
- w -= strlen(s); outs(s);
-
- while(w-- > 0) outc(' '); outs(ANSI_RESET ANSI_CLRTOEND);
- w = tolower(igetch());
-
- if( w != 'n' &&
- w != KEY_UP && w != KEY_LEFT &&
- w != 'q')
- {
- RESET_MOVIE();
- mfmovie.mode = MFDISP_MOVIE_PLAYING;
- mf_determinemaxdisps(0, 0); // display until last line
- mf_movieNextFrame();
- MFDISP_DIRTY();
- // remove override messages
- RESET_OVERRIDE_MSG();
- continue;
- }
- /* else, we have to clean up. */
- move(b_lines, 0);
- clrtoeol();
- }
- break;
-
- case MFDISP_MOVIE_PLAYING_OLD:
- case MFDISP_MOVIE_PLAYING:
-
- mf_moviePromptPlaying(0);
-
- // doing refresh() here is better,
- // to prevent that we forgot to refresh
- // in SyncFrame.
- refresh();
-
- if(mf_movieSyncFrame())
- {
- /* user did not hit anything.
- * play next frame.
- */
- if(mfmovie.mode == MFDISP_MOVIE_PLAYING)
- {
- if(!mf_movieNextFrame())
- {
- STOP_MOVIE();
-
- if(promptend == NA)
- {
- /* if we played to end,
- * no need to prevent pressanykey().
- */
- flExit = 1, retval = 0;
- }
- }
- }
- else if(mfmovie.mode == MFDISP_MOVIE_PLAYING_OLD)
- {
- if(mf_viewedAll())
- {
- mfmovie.mode = MFDISP_MOVIE_NO;
- mf_determinemaxdisps(MFNAV_PAGE, 0);
- mf_forward(0);
- }
- else
- {
- if(!mfmovie.compat24)
- PMORE_UINAV_FORWARDPAGE();
- else
- mf_forward(22);
- }
- }
- } else {
- /* TODO simple navigation here? */
-
- /* stop playing */
- if(mfmovie.mode == MFDISP_MOVIE_PLAYING)
- {
- STOP_MOVIE();
- if(promptend == NA)
- {
- flExit = 1, retval = READ_NEXT;
- }
- }
- else if(mfmovie.mode == MFDISP_MOVIE_PLAYING_OLD)
- {
- mfmovie.mode = MFDISP_MOVIE_NO;
- mf_determinemaxdisps(MFNAV_PAGE, 0);
- mf_forward(0);
- }
- }
- continue;
- }
-#endif
-
- /* PRINT BOTTOM STATUS BAR */
-#ifdef DEBUG
- if(debug)
- {
- /* in debug mode don't print ANSI codes
- * because themselves are buggy.
- */
- prints("L#%ld(w%ld,lp%ld) pmt=%d Dsp:%08X/%08X/%08X, "
- "F:%08X/%08X(%d) tScr(%dx%d)",
- mf.lineno, mf.wraplines, mf.lastpagelines,
- promptend,
- (unsigned int)mf.disps,
- (unsigned int)mf.maxdisps,
- (unsigned int)mf.dispe,
- (unsigned int)mf.start, (unsigned int)mf.end,
- (int)mf.len,
- t_columns,
- t_lines
- );
- }
- else
-#endif
- {
- char *printcolor;
-
- char buf[256]; // orz
- int prefixlen = 0;
- int barlen = 0;
- int postfix1len = 0, postfix2len = 0;
-
- int progress =
- (int)((unsigned long)(mf.dispe-mf.start) * 100 / mf.len);
- /*
- * page determination is hard.
- * should we use starting line, or finishing line?
- */
- int nowpage =
- (int)((mf.lineno + mf.dispedlines/2) / MFNAV_PAGE)+1;
- int allpages = -1; /* unknown yet */
- if (mf.maxlinenoS >= 0)
- {
- allpages =
- (int)((mf.maxlinenoS + mf.lastpagelines -
- ((bpref.separator & MFDISP_SEP_WRAP) &&
- (fh.lines >= 0) ? 0:1)) / MFNAV_PAGE)+1;
- if (mf.lineno >= mf.maxlinenoS || nowpage > allpages)
- nowpage = allpages;
- /*
- nowpage =
- (int)((mf.lineno + mf.dispedlines-2) / MFNAV_PAGE)+1 ;
- */
- }
- /* why -2 and -1?
- * because we want to determine by nav_page,
- * and mf.dispedlines is based on disp_page (nav_page+1)
- * mf.lastpagelines is based on nav_page
- */
-
- if(mf_viewedAll())
- printcolor = ANSI_COLOR(37;44);
- else if (mf_viewedNone())
- printcolor = ANSI_COLOR(33;45);
- else
- printcolor = ANSI_COLOR(34;46);
-
- outs(ANSI_RESET);
- outs(printcolor);
-
- if(bpref.oldstatusbar)
- {
-
- prints(" ÂsÄý P.%d(%d%%) %s %-30.30s%s",
- nowpage,
- progress,
- ANSI_COLOR(31;47),
- "(h)"
- ANSI_COLOR(30) "¨D§U "
- ANSI_COLOR(31) "¡÷¡õ[PgUp][",
- "PgDn][Home][End]"
- ANSI_COLOR(30) "´å¼Ð²¾°Ê "
- ANSI_COLOR(31) "¡ö[q]"
- ANSI_COLOR(30) "µ²§ô ");
-
- } else {
-
- if(allpages >= 0)
- sprintf(buf,
- " ÂsÄý ²Ä %1d/%1d ­¶ (%3d%%) ",
- nowpage,
- allpages,
- progress
- );
- else
- sprintf(buf,
- " ÂsÄý ²Ä %1d ­¶ (%3d%%) ",
- nowpage,
- progress
- );
- outs(buf); prefixlen += strlen(buf);
-
- outs(ANSI_COLOR(1;30;47));
-
- if(override_msg)
- {
- buf[0] = 0;
- if(override_attr) outs(override_attr);
- snprintf(buf, sizeof(buf), override_msg);
- RESET_OVERRIDE_MSG();
- }
- else
- if(mf.xpos > 0)
- {
- snprintf(buf, sizeof(buf),
- " Åã¥Ü½d³ò: %d~%d Äæ¦ì, %02d~%02d ¦æ",
- (int)mf.xpos+1,
- (int)(mf.xpos + t_columns-(mf.trunclines ? 2 : 1)),
- (int)(mf.lineno + 1),
- (int)(mf.lineno + mf.dispedlines)
- );
- } else {
- snprintf(buf, sizeof(buf),
- " ¥Ø«eÅã¥Ü: ²Ä %02d~%02d ¦æ",
- (int)(mf.lineno + 1),
- (int)(mf.lineno + mf.dispedlines)
- );
- }
-
- outs(buf); prefixlen += strlen(buf);
-
- postfix1len = 12; // check msg below
- postfix2len = 10;
- if(mf_viewedAll()) postfix1len = 17;
-
- if (prefixlen + postfix1len + postfix2len + 1 > t_columns)
- {
- postfix1len = 0;
- if (prefixlen + postfix1len + postfix2len + 1 > t_columns)
- postfix2len = 0;
- }
- barlen = t_columns - 1 - postfix1len - postfix2len - prefixlen;
-
- while(barlen-- > 0)
- outc(' ');
-
- if(postfix1len > 0)
- outs(
- mf_viewedAll() ?
- ANSI_COLOR(0;31;47)"(y)" ANSI_COLOR(30) "¦^«H"
- ANSI_COLOR(31) "(X/%)" ANSI_COLOR(30) "±À¤å "
- :
- ANSI_COLOR(0;31;47) "(h)"
- ANSI_COLOR(30) "«öÁ仡©ú "
- );
- if(postfix2len > 0)
- outs(
- ANSI_COLOR(0;31;47) "¡ö[q]"
- ANSI_COLOR(30) "Â÷¶} "
- );
- }
- outs(ANSI_RESET);
- FORCE_CLRTOEOL();
- }
-
- /* igetch() will do refresh(); */
- ch = igetch();
- switch (ch) {
- /* -------------- NEW EXITING KEYS ------------------ */
-#ifdef RET_DOREPLY
- case 'r': case 'R':
- flExit = 1, retval = RET_DOREPLY;
- break;
- case 'Y': case 'y':
- flExit = 1, retval = RET_DOREPLYALL;
- break;
-#endif
-#ifdef RET_DORECOMMEND
- // recommend
- case '%':
- case 'X':
- flExit = 1, retval = RET_DORECOMMEND;
- break;
-#endif
-#ifdef RET_DOQUERYINFO
- case 'Q': // info query interface
- flExit = 1, retval = RET_DOQUERYINFO;
- break;
-#endif
-#ifdef RET_DOSYSOPEDIT
- case 'E':
- flExit = 1, retval = RET_DOSYSOPEDIT;
- break;
-#endif
-#ifdef RET_DOCHESSREPLAY
- case 'z':
- flExit = 1, retval = RET_DOCHESSREPLAY;
- break;
-#endif
-#ifdef RET_COPY2TMP
- case Ctrl('T'):
- flExit = 1, retval = RET_COPY2TMP;
- break;
-#endif
-#ifdef RET_SELECTBRD
- case 's':
- flExit = 1, retval = RET_SELECTBRD;
- break;
-#endif
- /* ------------------ EXITING KEYS ------------------ */
- case 'A':
- flExit = 1, retval = AUTHOR_PREV;
- break;
- case 'a':
- flExit = 1, retval = AUTHOR_NEXT;
- break;
- case 'F': case 'f':
- flExit = 1, retval = READ_NEXT;
- break;
- case 'B': case 'b':
- flExit = 1, retval = READ_PREV;
- break;
- case KEY_LEFT:
- flExit = 1, retval = FULLUPDATE;
- break;
- case 'q':
- flExit = 1, retval = FULLUPDATE;
- break;
-
- /* from Kaede, thread reading */
- case ']':
- case '+':
- flExit = 1, retval = RELATE_NEXT;
- break;
- case '[':
- case '-':
- flExit = 1, retval = RELATE_PREV;
- break;
- case '=':
- flExit = 1, retval = RELATE_FIRST;
- break;
- /* ------------------ NAVIGATION KEYS ------------------ */
- /* Simple Navigation */
- case 'k': case 'K':
- mf_backward(1);
- break;
- case 'j': case 'J':
- PMORE_UINAV_FORWARDLINE();
- break;
-
- case Ctrl('F'):
- case KEY_PGDN:
- PMORE_UINAV_FORWARDPAGE();
- break;
- case Ctrl('B'):
- case KEY_PGUP:
- mf_backward(MFNAV_PAGE);
- break;
-
- case '0':
- case 'g':
- case KEY_HOME:
- mf_goTop();
- break;
- case '$':
- case 'G':
- case KEY_END:
- mf_goBottom();
-
-#ifdef PMORE_ACCURATE_WRAPEND
- /* allright. in design of pmore,
- * it's possible that when user navigates to file end,
- * a wrapped line made nav not 100%.
- */
- mf_display();
- invalidate = 0;
-
- if(!mf_viewedAll())
- {
- /* one more try. */
- mf_goBottom();
- invalidate = 1;
- }
-#endif
- break;
-
- /* Compound Navigation */
- case '.':
- if(mf.xpos == 0)
- mf.xpos ++;
- mf.xpos ++;
- break;
- case ',':
- if(mf.xpos > 0)
- mf.xpos --;
- break;
- case '\t':
- case '>':
- //if(mf.xpos == 0 || mf.trunclines)
- mf.xpos = (mf.xpos/8+1)*8;
- break;
- /* acronym form shift-tab, ^[[Z */
- /* however some terminals does not send that. */
- case KEY_STAB:
- case '<':
- mf.xpos = (mf.xpos/8-1)*8;
- if(mf.xpos < 0) mf.xpos = 0;
- break;
- case '\r':
- case '\n':
- case KEY_DOWN:
- if (mf_viewedAll() ||
- (promptend == 2 && (ch == '\r' || ch == '\n')))
- flExit = 1, retval = READ_NEXT;
- else
- PMORE_UINAV_FORWARDLINE();
- break;
-
- case ' ':
- if (mf_viewedAll())
- flExit = 1, retval = READ_NEXT;
- else
- PMORE_UINAV_FORWARDPAGE();
- break;
- case KEY_RIGHT:
- if(mf_viewedAll())
- promptend = 0, flExit = 1, retval = 0;
- else
- {
- /* if mf.xpos > 0, widenav mode. */
- /* because we have other keys to do so,
- * disable it now.
- */
- /*
- if(mf.trunclines > 0)
- {
- if(mf.xpos == 0)
- mf.xpos++;
- mf.xpos++;
- }
- else if (mf.xpos == 0)
- */
- PMORE_UINAV_FORWARDPAGE();
- }
- break;
-
- case KEY_UP:
- if(mf_viewedNone())
- flExit = 1, retval = READ_PREV;
- else
- mf_backward(1);
- break;
- case Ctrl('H'):
- if(mf_viewedNone())
- flExit = 1, retval = READ_PREV;
- else
- mf_backward(MFNAV_PAGE);
- break;
-
- case 't':
- if (mf_viewedAll())
- flExit = 1, retval = RELATE_NEXT;
- else
- PMORE_UINAV_FORWARDPAGE();
- break;
- /* ------------------ SEARCH KEYS ------------------ */
- case '/':
- {
- char sbuf[81] = "";
- char ans[4] = "n";
-
- if(sr.search_str) {
- free(sr.search_str);
- sr.search_str = NULL;
- }
-
- getdata(b_lines - 1, 0, PMORE_MSG_SEARCH_KEYWORD, sbuf,
- 40, DOECHO);
-
- if (sbuf[0]) {
- if (getdata(b_lines - 1, 0, "°Ï¤À¤j¤p¼g(Y/N/Q)? [N] ",
- ans, sizeof(ans), LCECHO) && *ans == 'y')
- sr.cmpfunc = strncmp;
- else if (*ans == 'q')
- sbuf[0] = 0;
- else
- sr.cmpfunc = strncasecmp;
- }
- sr.len = strlen(sbuf);
- if(sr.len) sr.search_str = (unsigned char*)strdup(sbuf);
- mf_search(MFSEARCH_FORWARD);
- MFDISP_DIRTY();
- }
- break;
- case 'n':
- mf_search(MFSEARCH_FORWARD);
- break;
- case 'N':
- mf_search(MFSEARCH_BACKWARD);
- break;
- /* ------------------ SPECIAL KEYS ------------------ */
- case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
- case ';': case ':':
- {
- char buf[16] = "";
- int i = 0;
- int pageMode = (ch != ':');
- if (ch >= '1' && ch <= '9')
- buf[0] = ch, buf[1] = 0;
-
- pmore_clrtoeol(b_lines-1, 0);
- getdata_buf(b_lines-1, 0,
- (pageMode ?
- "¸õ¦Ü¦¹­¶(­Y­n§ï«ü©w¦æ¼Æ½Ð¦bµ²§À¥[.): " :
- "¸õ¦Ü¦¹¦æ: "),
- buf, 8, DOECHO);
- if(buf[0]) {
- i = atoi(buf);
- if(buf[strlen(buf)-1] == '.')
- pageMode = 0;
- if(i-- > 0)
- mf_goto(i * (pageMode ? MFNAV_PAGE : 1));
- }
- MFDISP_DIRTY();
- }
- break;
-
- case 'h': case 'H': case KEY_F1:
- case '?':
- // help
- show_help(pmore_help);
- MFDISP_DIRTY();
- break;
-
-#ifdef PMORE_NOTIFY_NEWPREF
- //let's be backward compatible!
- case 'l':
- case 'w':
- case 'W':
- case '|':
- vmsg("³o­Ó«öÁä¤w¾ã¦X¶i·sªº³]©w (o) ¤F");
- break;
-
-#endif // PMORE_NOTIFY_NEWPREF
-
- case '\\': // everyone loves backslash, let's keep it.
- pmore_QuickRawModePref();
- MFDISP_DIRTY();
- break;
-
- case 'o':
- pmore_Preference();
- MFDISP_DIRTY();
- break;
-
-#if defined(USE_BBSLUA) && defined(RET_DOBBSLUA)
- case 'P':
- vmsg("«D±`©êºp¡ABBS-Lua ªº¼öÁä¤w§ï¬° L ¡A½Ð§ï«ö L");
- break;
-
- case 'L':
- case 'l':
- flExit = 1, retval = RET_DOBBSLUA;
- break;
-#endif
-
-#ifdef PMORE_USE_ASCII_MOVIE
- case 'p':
- /* play ascii movie again
- */
- if(mfmovie.mode == MFDISP_MOVIE_YES)
- {
- RESET_MOVIE();
- mfmovie.mode = MFDISP_MOVIE_PLAYING;
- mf_determinemaxdisps(0, 0); // display until last line
- /* it is said that it's better not to go top. */
- // mf_goTop();
- mf_movieNextFrame();
- MFDISP_DIRTY();
- }
- else if (mfmovie.mode == MFDISP_MOVIE_NO)
- {
- static char buf[10]="1";
- //move(b_lines-1, 0);
-
- /*
- * TODO scan current page to confirm if this is a new style movie
- */
- pmore_clrtoeol(b_lines-1, 0);
- getdata_buf(b_lines - 1, 0,
- PMORE_MSG_MOVIE_PLAYOLD_GETTIME,
- buf, 8, LCECHO);
-
- if(buf[0])
- {
- float nf = 0;
- nf = atof(buf); // sscanf(buf, "%f", &nf);
- RESET_MOVIE();
-
- mfmovie.mode = MFDISP_MOVIE_PLAYING_OLD;
- mf_float2tv(nf, &mfmovie.frameclk);
- mfmovie.compat24 = 0;
- /* are we really going to start? check termsize! */
- if (t_lines != 24)
- {
- char ans[4];
- pmore_clrtoeol(b_lines-1, 0);
- getdata(b_lines - 1, 0,
- PMORE_MSG_MOVIE_PLAYOLD_AS24L,
- ans, 3, LCECHO);
- if(ans[0] == 'n')
- mfmovie.compat24 = 0;
- else
- mfmovie.compat24 = 1;
- }
- mf_determinemaxdisps(0, 0); // display until last line
- MFDISP_DIRTY();
- }
- }
- break;
-#endif
-
-#ifdef DEBUG
- case 'd':
- debug = !debug;
- MFDISP_DIRTY();
- break;
-#endif
-
- }
- /* DO NOT DO ANYTHING HERE. NOT SAFE RIGHT NOW. */
- }
-
- mf_detach();
- if (retval == 0 && promptend) {
- pressanykey();
- clear();
- } else
- outs(reset_color);
-
- REENTRANT_RESTORE();
- return retval;
-}
-
-// ---------------------------------------------------- Preference and Help
-
-static void
-pmore_prefEntry(
- int isel,
- const char *key, int szKey,
- const char *text,int szText,
- const char* options)
-{
- int i = 23;
- // print key/text
- outs(" " ANSI_COLOR(1;31)); //OPTATTR_NORMAL_KEY);
- if (szKey < 0) szKey = strlen(key);
- if (szKey > 0) outs_n(key, szKey);
- outs(ANSI_RESET " ");
- if (szText < 0) szText = strlen(text);
- if (szText > 0) outs_n(text, szText);
-
- i -= szKey + szText;
- if (i < 0) i+= 20; // one more chance
- while (i-- > 0) outc(' ');
-
- // print options
- i = 0;
- while (*options)
- {
- if (*options == '\t')
- {
- // blank option, skip it.
- i++, options++;
- continue;
- }
-
- if (i > 0)
- outs(ANSI_COLOR(1;30) " |" ANSI_RESET); //OPTATTR_BAR " | " ANSI_RESET);
-
- // test if option has hotkey
- if (*options && *options != '\t' &&
- *(options+1) && *(options+1) == '.')
- {
- // found hotkey
- outs(ANSI_COLOR(1;31)); //OPTATTR_NORMAL_KEY);
- outc(*options);
- outs(ANSI_RESET);
- options +=2;
- }
-
- if (i == isel)
- {
- outs(ANSI_COLOR(1;36) "*");// OPTATTR_SELECTED);
- }
- else
- outc(' ');
-
- while (*options && *options != '\t')
- outc(*options++);
-
- outs(ANSI_RESET);
-
- if (*options)
- i++, options ++;
- }
- outc('\n');
-}
-
-void
-pmore_PromptBar(const char *caption, int shadow)
-{
- int i = 0;
-
- if (shadow)
- {
- outs(ANSI_COLOR(0;1;30));
- for(i = 0; i+2 < t_columns ; i+=2)
- outs("¢b");
- outs(ANSI_RESET "\n");
- }
- else
- i = t_columns -2;
-
- outs(ANSI_COLOR(7));
- outs(caption);
- for(i -= strlen(caption); i > 0; i--)
- outs(" ");
- outs(ANSI_RESET "\n");
-}
-
-void
-pmore_QuickRawModePref()
-{
- int ystart = b_lines -2;
-
-#ifdef HAVE_GRAYOUT
- grayout(0, ystart-1, GRAYOUT_DARK);
-#endif // HAVE_GRAYOUT
-
- while(1)
- {
- move(ystart, 0);
- clrtobot();
- pmore_PromptBar(PMORE_MSG_PREF_TITLE_QRAW, 0);
-
- // list options
- pmore_prefEntry(bpref.rawmode,
- "\\", 1, "¦â±mÅã¥Ü¤è¦¡:", -1,
- "1.¹w³]®æ¦¡¤Æ¤º®e\t2.­ì©lANSI±±¨î½X\t3.¯Â¤å¦r");
-
- switch(vmsg("½Ð½Õ¾ã³]©w (1-3 ¥iª½±µ¿ï©w¡A\\¥i¤Á´«) ©Î¨ä¥¦¥ô·NÁäµ²§ô¡C"))
- {
- case '\\':
- bpref.rawmode = (bpref.rawmode+1) % MFDISP_RAW_MODES;
- break;
- case '1':
- bpref.rawmode = MFDISP_RAW_NA;
- return;
- case '2':
- bpref.rawmode = MFDISP_RAW_NOANSI;
- return;
- case '3':
- bpref.rawmode = MFDISP_RAW_PLAIN;
- return;
- case KEY_LEFT:
- if (bpref.rawmode > 0) bpref.rawmode --;
- break;
- case KEY_RIGHT:
- if (bpref.rawmode < MFDISP_RAW_MODES-1) bpref.rawmode ++;
- break;
- default:
- return;
- }
- }
-}
-
-void
-pmore_Preference()
-{
- int ystart = b_lines - 9;
- // TODO even better pref navigation, like arrow keys
- // static int lastkey = '\\'; // default key
-
-#ifdef HAVE_GRAYOUT
- grayout(0, ystart-1, GRAYOUT_DARK);
-#endif // HAVE_GRAYOUT
-
- while (1)
- {
- move(ystart, 0);
- clrtobot();
- pmore_PromptBar(PMORE_MSG_PREF_TITLE, 1);
- outs("\n");
-
- // list options
- pmore_prefEntry(bpref.rawmode,
- "\\", 1, "¦â±mÅã¥Ü¤è¦¡:", -1,
- "¹w³]®æ¦¡¤Æ¤º®e\t­ì©lANSI±±¨î½X\t¯Â¤å¦r");
-
- pmore_prefEntry(bpref.wrapmode,
- "w", 1, "Â_¦æ¤è¦¡:", -1,
- "ª½±µºI¦æ\t¦Û°ÊÂ_¦æ");
-
- pmore_prefEntry(bpref.wrapindicator,
- "m", 1, "Â_¦æ²Å¸¹:", -1,
- "¤£Åã¥Ü\tÅã¥Ü");
-
- pmore_prefEntry(bpref.separator,
- "l", 1, "¤å³¹¼ÐÀY¤À¹j½u:", -1,
- "µL\t³æ¦æ\t\t¶Ç²Î¤À¹j½u¥[ªÅ¦æ");
-
- pmore_prefEntry(bpref.oldstatusbar,
- "t", 1, "¶Ç²Îª¬ºA¦C»PÂ_¦æ¤è¦¡: ", -1,
- "°±¥Î\t±Ò¥Î");
-
- switch(vmsg("½Ð½Õ¾ã³]©w©Î¨ä¥¦¥ô·NÁäµ²§ô¡C"))
- {
- case '\\':
- case '|':
- bpref.rawmode = (bpref.rawmode+1) % MFDISP_RAW_MODES;
- break;
- case 'w':
- bpref.wrapmode = (bpref.wrapmode+1) % MFDISP_WRAP_MODES;
- break;
- case 'm':
- bpref.wrapindicator = !bpref.wrapindicator;
- break;
- case 'l':
- // there's no MFDISP_SEP_WRAP only mode.
- if (++bpref.separator == MFDISP_SEP_WRAP)
- bpref.separator ++;
- bpref.separator %= MFDISP_SEP_MODES;
- break;
- case 't':
- bpref.oldwrapmode = !bpref.oldwrapmode;
- bpref.oldstatusbar = !bpref.oldstatusbar;
- break;
-
- default:
- // finished settings
- return;
- }
- }
-}
-
-void
-pmore_Help()
-{
- clear();
- stand_title("pmore ¨Ï¥Î»¡©ú");
- vmsg("");
-}
-
-// ---------------------------------------------------- Extra modules
-
-#ifdef PMORE_USE_ASCII_MOVIE
-void
-mf_float2tv(float f, struct timeval *ptv)
-{
- if(f < MOVIE_MIN_FRAMECLK)
- f = MOVIE_MIN_FRAMECLK;
- if (f > MOVIE_MAX_FRAMECLK)
- f = MOVIE_MAX_FRAMECLK;
-
- ptv->tv_sec = (long) f;
- ptv->tv_usec = (f - (long)f) * MOVIE_SECOND_U;
-}
-
-int
-mf_str2float(unsigned char *p, unsigned char *end, float *pf)
-{
- char buf[16] = {0};
- int cbuf = 0;
-
- /* process time */
- while ( p < end &&
- cbuf < sizeof(buf)-1 &&
- (isdigit(*p) || *p == '.' || *p == '+' || *p == '-'))
- buf[cbuf++] = *p++;
-
- if (!cbuf)
- return 0;
-
- buf[cbuf] = 0;
- *pf = atof(buf);
-
- return 1;
-}
-
-/*
- * maybe you can use add_io or you have other APIs in
- * your I/O system, but we'll do it here.
- * override if you have better methods.
- */
-int
-pmore_wait_key(struct timeval *ptv, int dorefresh)
-{
- int sel = 0;
- fd_set readfds;
- int c = 0;
-
- if (dorefresh)
- refresh();
-
- do {
- // if already something in queue,
- // detemine if ok to break.
- while ( num_in_buf() > 0)
- {
- if (!mf_movieMaskedInput((c = igetch())))
- return c;
- }
-
- // wait for real user interaction
- FD_ZERO(&readfds);
- FD_SET(0, &readfds);
-
-#ifdef STATINC
- STATINC(STAT_SYSSELECT);
-#endif
- sel = select(1, &readfds, NULL, NULL, ptv);
-
- // if select() stopped by other interrupt,
- // do it again.
- if (sel < 0 && errno == EINTR)
- continue;
-
- // if (sel > 0), try to read.
- // note: there may be more in queue.
- // will be processed at next loop.
- if (sel > 0 && !mf_movieMaskedInput((c = igetch())))
- return c;
-
- } while (sel > 0);
-
- // now, maybe something for read (sel > 0)
- // or time out (sel == 0)
- // or weird error (sel < 0)
-
- // sync clock(now) if timeout.
- if (sel == 0)
- syncnow();
-
- return (sel == 0) ? 0 : 1;
-}
-
-// type : 1 = option selection, 0 = normal
-int
-mf_moviePromptPlaying(int type)
-{
- int w = t_columns - 1;
- // s may change to anykey...
- const char *s = PMORE_MSG_MOVIE_PLAYING;
-
- if (override_msg)
- {
- // we must warn user about something...
- move(type ? b_lines-2 : b_lines-1, 0); // clrtoeol?
- outs(ANSI_RESET);
- if (override_attr) outs(override_attr);
- w -= strlen(override_msg);
- outs(override_msg);
- while(w-- > 0) outc(' ');
-
- outs(ANSI_RESET ANSI_CLRTOEND);
- RESET_OVERRIDE_MSG();
- w = t_columns -1;
- }
-
- move(type ? b_lines-1 : b_lines, 0); // clrtoeol?
-
- if (type)
- {
- outs(ANSI_RESET ANSI_COLOR(1;34;47));
- s = " >> ½Ð¿é¤J¿ï¶µ: (¤¬°Ê¦¡°Êµe¼½©ñ¤¤¡A¥i«ö q ©Î Ctrl-C ¤¤Â_)";
- }
- else if (mfmovie.interactive)
- {
- outs(ANSI_RESET ANSI_COLOR(1;34;47));
- s = PMORE_MSG_MOVIE_INTERACTION_PLAYING;
- } else {
- outs(ANSI_RESET ANSI_COLOR(1;30;47));
- }
-
- w -= strlen(s); outs(s);
-
- while(w-- > 0) outc(' '); outs(ANSI_RESET ANSI_CLRTOEND);
- if (type)
- {
- move(b_lines, 0);
- clrtoeol();
- }
-
- return 1;
-}
-
-// return = printed characters
-int
-mf_moviePromptOptions(
- int isel, int maxsel,
- int key,
- unsigned char *text, unsigned int szText)
-{
- unsigned char *s = text;
- int printlen = 0;
- // determine if we need separator
- if (maxsel)
- {
- outs(OPTATTR_BAR "|" );
- printlen += 1;
- }
-
- // highlight if is selected
- if (isel == maxsel)
- outs(OPTATTR_SELECTED_KEY);
- else
- outs(OPTATTR_NORMAL_KEY);
-
- outc(' '); printlen ++;
-
- if (key > ' ' && key < 0x80) // isprint(key))
- {
- outc(key);
- printlen += 1;
- } else {
- // named keys
- printlen += 2;
-
- if (key == KEY_UP) outs("¡ô");
- else if (key == KEY_LEFT) outs("¡ö");
- else if (key == KEY_DOWN) outs("¡õ");
- else if (key == KEY_RIGHT) outs("¡÷");
- else if (key == KEY_PGUP) { outs("PgUp"); printlen += 2; }
- else if (key == KEY_PGDN) { outs("PgDn"); printlen += 2; }
- else if (key == KEY_HOME) { outs("Home"); printlen += 2; }
- else if (key == KEY_END) { outs("End"); printlen ++; }
- else if (key == KEY_INS) { outs("Ins"); printlen ++; }
- else if (key == KEY_DEL) { outs("Del"); printlen ++; }
- else if (key == '\b') { outs("¡öBS"); printlen += 2; }
- // else if (key == MOVIE_KEY_ANY) // same as default
- else printlen -= 2;
- }
-
- // check text: we don't allow special char.
- if (text && szText && text[0])
- {
- while (s < text + szText && *s > ' ')
- {
- s++;
- }
- szText = s - text;
- }
- else
- {
- // default option text
- text = (unsigned char*)"¡¸";
- szText = ustrlen(text);
- }
-
- if (szText)
- {
- if (isel == maxsel)
- outs(OPTATTR_SELECTED);
- else
- outs(OPTATTR_NORMAL);
- outs_n((char*)text, szText);
- printlen += szText;
- }
-
- outc(' '); printlen ++;
-
- // un-highlight
- if (isel == maxsel)
- outs(OPTATTR_NORMAL);
-
- return printlen;
-}
-
-int
-mf_movieNamedKey(int c)
-{
- switch (c)
- {
- case 'u': return KEY_UP;
- case 'd': return KEY_DOWN;
- case 'l': return KEY_LEFT;
- case 'r': return KEY_RIGHT;
-
- case 'b': return '\b';
-
- case 'H': return KEY_HOME;
- case 'E': return KEY_END;
- case 'I': return KEY_INS;
- case 'D': return KEY_DEL;
- case 'P': return KEY_PGUP;
- case 'N': return KEY_PGDN;
-
- case 'a': return MOVIE_KEY_ANY;
- default:
- break;
- }
- return 0;
-}
-
-int mf_movieIsSystemBreak(int c)
-{
- return (c == 'q' || c == 'Q' || c == Ctrl('C'))
- ? 1 : 0;
-}
-
-int
-mf_movieMaskedInput(int c)
-{
- unsigned char *p = mfmovie.optkeys;
-
- if (!p)
- return 0;
-
- // some keys cannot be masked
- if (mf_movieIsSystemBreak(c))
- return 0;
-
- // treat BS and DEL as same one
- if (c == MOVIE_KEY_BS2)
- c = '\b';
-
- // general look up
- while (p < mf.end && *p && *p != '\n' && *p != '#')
- {
- if (*p == '@' && mf.end - p > 1
- && isalnum(*(p+1))) // named key
- {
- p++;
-
- // special: 'a' masks all
- if (*p == 'a' || mf_movieNamedKey(*p) == c)
- return 1;
- } else {
- if ((int)*p == c)
- return 1;
- }
- p++;
- }
- return 0;
-}
-
-unsigned char *
-mf_movieFrameHeader(unsigned char *p, unsigned char *end)
-{
- // ANSI has ESC_STR [8m as "Conceal" but
- // not widely supported, even PieTTY.
- // So let's go back to fixed format...
- static char *patHeader = "==" ESC_STR "[30;40m^L";
- static char *patHeader2= ESC_STR "[30;40m^L"; // patHeader + 2; // "=="
- // static char *patHeader3= ESC_STR "[m^L";
- static size_t szPatHeader = 12; // strlen(patHeader);
- static size_t szPatHeader2 = 10; // strlen(patHeader2);
- // static size_t szPatHeader3 = 5; // strlen(patHeader3);
-
- size_t sz = end - p;
-
- if (sz < 1) return NULL;
- if(*p == 12) // ^L
- return p+1;
-
- if (sz < 2) return NULL;
- if( *p == '^' &&
- *(p+1) == 'L')
- return p+2;
-
- // Add more frame headers
-
- /* // *[m seems not so common, skip.
- if (sz < szPatHeader3) return NULL;
- if (memcmp(p, patHeader3, szPatHeader3) == 0)
- return p + szPatHeader3;
- */
-
- if (sz < szPatHeader2) return NULL;
- if (memcmp(p, patHeader2, szPatHeader2) == 0)
- return p + szPatHeader2;
-
- if (sz < szPatHeader) return NULL;
- if (memcmp(p, patHeader, szPatHeader) == 0)
- return p + szPatHeader;
-
- return NULL;
-}
-
-int
-mf_movieGotoNamedFrame(const unsigned char *name, const unsigned char *end)
-{
- const unsigned char *p = name;
- size_t sz = 0;
-
- // resolve name first
- while (p < end && isalnum(*p))
- p++;
- sz = p - name;
-
- if (sz < 1) return 0;
-
- // now search entire file for frame
-
- mf_goTop();
-
- do
- {
- if ((p = mf_movieFrameHeader(mf.disps, mf.end)) == NULL ||
- *p != ':')
- continue;
-
- // got some frame. let's check the name
- p++;
- if (mf.end - p < sz)
- continue;
-
- // check: target of p must end.
- if (mf.end -p > sz &&
- isalnum(*(p+sz)))
- continue;
-
- if (memcmp(p, name, sz) == 0)
- return 1;
-
- } while (mf_forward(1) > 0);
- return 0;
-}
-
-int
-mf_movieGotoFrame(int fno, int relative)
-{
- if (!relative)
- mf_goTop();
- else if (fno > 0)
- mf_forward(1);
- // for absolute, fno = 1..N
-
- if (fno > 0)
- {
- // move forward
- do {
- while (mf_movieFrameHeader(mf.disps, mf.end) == NULL)
- {
- if (mf_forward(1) < 1)
- return 0;
- }
- // found frame.
- if (--fno > 0)
- mf_forward(1);
- } while (fno > 0);
- } else {
- // backward
- // XXX check if we reached head?
- while (fno < 0)
- {
- do {
- if (mf_backward(1) < 1)
- return 0;
- } while (mf_movieFrameHeader(mf.disps, mf.end) == NULL);
- fno ++;
- }
- }
- return 1;
-}
-
-int
-mf_parseOffsetCmd(
- unsigned char *s, unsigned char *end,
- int base)
-{
- // return is always > 0, or base.
- int v = 0;
-
- if (s >= end)
- return base;
-
- v = atoi((char*)s);
-
- if (*s == '+' || *s == '-')
- {
- // relative format
- v = base + v;
- } else if (isdigit(*s)) {
- // absolute format
- } else {
- // error format?
- v = 0;
- }
-
- if (v <= 0)
- v = base;
- return v;
-}
-
-int
-mf_movieExecuteOffsetCmd(unsigned char *s, unsigned char *end)
-{
- // syntax: type[+-]offset
- //
- // type: l(line), f(frame), p(page).
- // +-: if empty, absolute. if assigned, relative.
- // offset: is 1 .. N for all cases
-
- int curr = 0, newno = 0;
-
- switch(*s)
- {
- case 'p':
- // by page
- curr = (mf.lineno / MFDISP_PAGE) + 1;
- newno = mf_parseOffsetCmd(s+1, end, curr);
-#ifdef DEBUG
- vmsgf("page: %d -> %d\n", curr, newno);
-#endif // DEBUG
- // prevent endless loop
- if (newno == curr)
- return 0;
-
- return mf_goto((newno -1) * MFDISP_PAGE);
-
- case 'l':
- // by lines
- curr = mf.lineno + 1;
- newno = mf_parseOffsetCmd(s+1, end, curr);
-#ifdef DEBUG
- vmsgf("line: %d -> %d\n", curr, newno);
-#endif // DEBUG
- // prevent endless loop
- if (newno == curr)
- return 0;
-
- return mf_goto(newno-1);
-
- case 'f':
- // by frame [optimized]
- if (++s >= end)
- return 0;
-
- curr = 0;
- newno = atoi((char*)s);
- if (*s == '+' || *s == '-') // relative
- {
- curr = 1;
- if (newno == 0)
- return 0;
- } else {
- // newno starts from 1
- if (newno <= 0)
- return 0;
- }
- return mf_movieGotoFrame(newno, curr);
-
- case ':':
- // by names
- return mf_movieGotoNamedFrame(s+1, end);
-
- default:
- // not supported yet
- break;
- }
- return 0;
-}
-
-
-int
-mf_movieOptionHandler(unsigned char *opt, unsigned char *end)
-{
- // format: #time#key1,cmd,text1#key2,cmd,text2#
- // if key is empty, use auto-increased key.
- // if cmd is empty, invalid.
- // if text is empty, display key only or hide if time is assigned.
-
- int ient = 0;
- unsigned char *pkey = NULL, *cmd = NULL, *text = NULL;
- unsigned int szCmd = 0, szText = 0;
- unsigned char *p = opt;
- int key = 0;
- float optclk = -1.0f; // < 0 means infinite wait
- struct timeval tv;
-
- int isel = 0, c = 0, maxsel = 0, selected = 0;
- int newOpt = 1;
- int hideOpts = 0;
- int promptlen = 0;
-
- // TODO handle line length
- // TODO restrict option size
-
- // set up timer (opt points to optional time now)
- do {
- p = opt;
- while ( p < end &&
- (isdigit(*p) || *p == '+' || *p == '-' || *p == '.') )
- p++;
-
- // if no number, abort.
- if (p == opt || (p < end && *p != '#')) break;
-
- // p looks like valid timer now
- if (mf_str2float(opt, p, &optclk))
- {
- // conversion failed.
- if (optclk == 0)
- optclk = -1.0f;
- }
-
- // point opt to new var after #.
- opt = p + 1;
- break;
-
- } while (1);
-
- // UI Selection
- do {
- // do c test here because we need parser to help us
- // finding the selection
- if (c == '\r' || c == '\n' || c == ' ')
- {
- selected = 1;
- }
-
- newOpt = 1;
- promptlen = 0;
-
- // parse (key,frame,text)
- for ( p = opt, ient = 0, maxsel = 0,
- key = '0'; // default command
- p < end && *p != '\n'; p++)
- {
- if (newOpt)
- {
- // prepare for next loop
- pkey = p;
- cmd = text = NULL;
- szCmd = szText = 0;
- ient = 0;
- newOpt = 0;
- }
-
- // calculation of fields
- if (*p == ',' || *p == '#')
- {
- switch (++ient)
- {
- // case 0 is already processed.
- case 1:
- cmd = p+1;
- break;
-
- case 2:
- text = p+1;
- szCmd = p - cmd;
- break;
-
- case 3:
- szText = p - text;
-
- default:
- // unknown parameters
- break;
- }
- }
-
- // ready to parse one option
- if (*p == '#')
- {
- newOpt = 1;
-
- // first, fix pointers
- if (szCmd == 0 || *cmd == ',' || *cmd == '#')
- { cmd = NULL; szCmd = 0; }
-
- // quick abort if option is invalid.
- if (!cmd)
- continue;
-
- if (szText == 0 || *text == ',' || *text == '#')
- { text = NULL; szText = 0; }
-
- // assign key
- if (*pkey == ',' || *pkey == '#')
- key++;
- else
- {
- // named key?
- int nk = 0;
-
- // handle special case @a (all) here
-
- if (*pkey == '@' &&
- ++ pkey < end &&
- (nk = mf_movieNamedKey(*pkey)))
- {
- key = nk;
- } else {
- key = *pkey;
- }
- // warning: pkey may be changed after this.
- }
-
- // calculation complete.
-
- // print option
- if (!hideOpts && maxsel == 0 && text == NULL)
- {
- hideOpts = 1;
- mf_moviePromptPlaying(0);
- // prevent more hideOpt test
- }
-
- if (!hideOpts)
- {
- // print header
- if (maxsel == 0)
- {
- pmore_clrtoeol(b_lines-1, 0);
- mf_moviePromptPlaying(1);
- }
-
- promptlen += mf_moviePromptOptions(
- isel, maxsel, key,
- text, szText);
- }
-
- // handle selection
- if (c == key ||
- (key == MOVIE_KEY_ANY && c != 0))
- {
- // hotkey pressed
- selected = 1;
- isel = maxsel;
- }
-
- maxsel ++;
-
- // parse complete.
- // test if this item is selected.
- if (selected && isel == maxsel - 1)
- break;
- }
- }
-
- if (selected || maxsel == 0)
- break;
-
- // finish the selection bar
- if (!hideOpts && maxsel > 0)
- {
- int iw = 0;
- for (iw = 0; iw + promptlen < t_columns-1; iw++)
- outc(' ');
- outs(ANSI_RESET ANSI_CLRTOEND);
- }
-
- // wait for input
- if (optclk > 0)
- {
- // timed interaction
-
- // disable optkeys to allow masked input
- unsigned char *tmpopt = mfmovie.optkeys;
- mfmovie.optkeys = NULL;
-
- mf_float2tv(optclk, &tv);
- c = pmore_wait_key(&tv, 1);
- mfmovie.optkeys = tmpopt;
-
- // if timeout, drop.
- if (!c)
- return 0;
- } else {
- // infinite wait
- c = igetch();
- }
-
- // parse keyboard input
- if (mf_movieIsSystemBreak(c))
- {
- // cannot be masked,
- // also force stop of playback
- STOP_MOVIE();
- vmsg(PMORE_MSG_MOVIE_INTERACTION_STOPPED);
- return 0;
- }
-
- // treat BS and DEL as same one
- if (c == MOVIE_KEY_BS2)
- c = '\b';
-
- // standard navigation keys.
- if (mf_movieMaskedInput(c))
- continue;
-
- // these keys can be masked
- if (c == KEY_LEFT || c == KEY_UP)
- {
- if (isel > 0) isel --;
- }
- else if (c == KEY_RIGHT || c == KEY_TAB || c == KEY_DOWN)
- {
- if (isel < maxsel-1) isel ++;
- }
- else if (c == KEY_HOME)
- {
- isel = 0;
- }
- else if (c == KEY_END)
- {
- isel = maxsel -1;
- }
-
- } while ( !selected );
-
- // selection is made now.
- outs(ANSI_RESET); // required because options bar may be not closed
- pmore_clrtoeol(b_lines, 0);
-
-#ifdef DEBUG
- prints("selection: %d\n", isel);
- igetch();
-#endif
-
- // Execute Selection
- if (!cmd || !szCmd)
- return 0;
-
- return mf_movieExecuteOffsetCmd(cmd, cmd+szCmd);
-}
-
-/*
- * mf_movieSyncFrame:
- * wait until synchronization, and flush break key (if any).
- * return meaning:
- * I've got synchronized.
- * If no (user breaks), return 0
- */
-int mf_movieSyncFrame()
-{
- if (mfmovie.pause)
- {
- int c = 0;
- mfmovie.pause = 0;
- c = vmsg(PMORE_MSG_MOVIE_PAUSE);
- if (mf_movieIsSystemBreak(c))
- return 0;
- return 1;
- }
- else if (mfmovie.options)
- {
- unsigned char *opt = mfmovie.options;
- mfmovie.options = NULL;
- mf_movieOptionHandler(opt, mf.end);
- return 1;
- }
- else if (mfmovie.synctime.tv_sec > 0)
- {
- /* synchronize world timeline model */
- struct timeval dv;
- gettimeofday(&dv, NULL);
- dv.tv_sec = mfmovie.synctime.tv_sec - dv.tv_sec;
- if(dv.tv_sec < 0)
- return 1;
- dv.tv_usec = mfmovie.synctime.tv_usec - dv.tv_usec;
- if(dv.tv_usec < 0) {
- dv.tv_sec --;
- dv.tv_usec += MOVIE_SECOND_U;
- }
- if(dv.tv_sec < 0)
- return 1;
-
- return !pmore_wait_key(&dv, 0);
- } else {
- /* synchronize each frame clock model */
- /* because Linux will change the timeval passed to select,
- * let's use a temp value here.
- */
- struct timeval dv = mfmovie.frameclk;
- return !pmore_wait_key(&dv, 0);
- }
-}
-
-#define MOVIECMD_SKIP_ALL(p,end) \
- while (p < end && *p && *p != '\n') \
- { p++; } \
-
-unsigned char *
-mf_movieProcessCommand(unsigned char *p, unsigned char *end)
-{
- for (; p < end && *p != '\n'; p++)
- {
- if (*p == 'S') {
- // SYNCHRONIZATION
- gettimeofday(&mfmovie.synctime, NULL);
- // S can take other commands
- }
- else if (*p == 'E')
- {
- // END
- STOP_MOVIE();
- // MFDISP_SKIPCURLINE();
- MOVIECMD_SKIP_ALL(p,end);
- return p;
- }
- else if (*p == 'P')
- {
- // PAUSE
- mfmovie.pause = 1;
- // MFDISP_SKIPCURLINE();
- MOVIECMD_SKIP_ALL(p,end);
- return p;
-
- }
- else if (*p == 'G')
- {
- // GOTO
- // Gt+-n,t+-n,t+-n (random select one)
- // jump +-n of type(l,p,f)
-
- // random select, if multiple
- unsigned char *pe = p;
- unsigned int igs = 0;
-
- for (pe = p ; pe < end && *pe &&
- *pe > ' ' && *pe < 0x80
- ; pe ++)
- if (*pe == ',') igs++;
-
- if (igs)
- {
- // make random
- igs = random() % (igs+1);
-
- for (pe = p ; igs > 0 && pe < end && *pe &&
- *pe > ' ' && *pe < 0x80
- ; pe ++)
- if (*pe == ',') igs--;
-
- if (pe != p)
- p = pe-1;
- }
-
- mf_movieExecuteOffsetCmd(p+1, end);
- MOVIECMD_SKIP_ALL(p,end);
- return p;
- }
- else if (*p == ':')
- {
- // NAMED
- // :name:
- // name allows alnum only
- p++;
- // TODO check isalnum p?
-
- // :name can accept trailing commands
- while (p < end && *p != '\n' && *p != ':')
- p++;
-
- if (*p == ':') p++;
-
- // continue will increase p
- p--;
- continue;
- }
- else if (*p == 'K')
- {
- // Reserve Key for interactive usage.
- // Currently only K#...# format is supported.
- if (p+2 < end && *(p+1) == '#')
- {
- p += 2;
- mfmovie.optkeys = p;
- mfmovie.interactive = 1;
-
- // K#..# can accept trailing commands
- while (p < end && *p != '\n' && *p != '#')
- p++;
-
- // if empty, set optkeys to NULL?
- if (mfmovie.optkeys == p)
- mfmovie.optkeys = NULL;
-
- if (*p == '#') p++;
-
- // continue will increase p
- p--;
- continue;
- }
- MOVIECMD_SKIP_ALL(p,end);
- return p;
- }
- else if (*p == '#')
- {
- // OPTIONS
- // #key1,frame1,text1#key2,frame2,text2#
- mfmovie.options = p+1;
- mfmovie.interactive = 1;
- // MFDISP_SKIPCURLINE();
- MOVIECMD_SKIP_ALL(p,end);
- return p;
- }
- else if (*p == 'O')
- {
- // OLD compatible mode
- // = -> compat24
- // - -> ?
- // == -> ?
- p++;
- if (p >= end)
- return end;
- if (*p == '=')
- {
- mfmovie.mode = MFDISP_MOVIE_PLAYING_OLD;
- mfmovie.compat24 = 1;
- p++;
- }
- // MFDISP_SKIPCURLINE();
- return p+1;
- }
- else if (*p == 'L')
- {
- // LOOP
- // Lm,n
- // m times to backward n
- break;
- }
- else
- {
- // end of known control codes
- break;
- }
- }
- return p;
-}
-
-int
-mf_movieNextFrame()
-{
- while (1)
- {
- unsigned char *p = mf_movieFrameHeader(mf.disps, mf.end);
-
- if(p)
- {
- float nf = 0;
- unsigned char *odisps = mf.disps;
-
- /* process leading */
- p = mf_movieProcessCommand(p, mf.end);
-
- // disps may change after commands
- if (mf.disps != odisps)
- {
- // commands changing location must
- // support at least one frame pause
- // to allow user break
- struct timeval tv;
- mf_float2tv(MOVIE_MIN_FRAMECLK, &tv);
-
- if (pmore_wait_key(&tv, 0))
- {
- STOP_MOVIE();
- return 0;
- }
- continue;
- }
-
- /* process time */
- if (mf_str2float(p, mf.end, &nf))
- {
- mf_float2tv(nf, &mfmovie.frameclk);
- }
-
- if(mfmovie.synctime.tv_sec > 0)
- {
- mfmovie.synctime.tv_usec += mfmovie.frameclk.tv_usec;
- mfmovie.synctime.tv_sec += mfmovie.frameclk.tv_sec;
- mfmovie.synctime.tv_sec += mfmovie.synctime.tv_usec / MOVIE_SECOND_U;
- mfmovie.synctime.tv_usec %= MOVIE_SECOND_U;
- }
-
- if (mfmovie.mode != MFDISP_MOVIE_PLAYING_OLD)
- mf_forward(1);
-
- return 1;
- }
-
- if (mf_forward(1) <= 0)
- break;
- }
-
- return 0;
-}
-#endif
-
-/* vim:sw=4:ts=8:expandtab:nofoldenable
- */
diff --git a/mbbsd/random.c b/mbbsd/random.c
deleted file mode 100644
index dd369c41..00000000
--- a/mbbsd/random.c
+++ /dev/null
@@ -1,711 +0,0 @@
-#ifdef __dietlibc__
-/*
- Copyright (C) 1995 Free Software Foundation
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
-
-/*
- Copyright (C) 1983 Regents of the University of California.
- All rights reserved.
-
- 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 University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.*/
-
-/*
- * This is derived from the Berkeley source:
- * @(#)random.c 5.5 (Berkeley) 7/6/88
- * It was reworked for the GNU C Library by Roland McGrath.
- * Rewritten to be reentrant by Ulrich Drepper, 1995
- */
-
-#include <errno.h>
-#include <limits.h>
-#include <stddef.h>
-#include <stdlib.h>
-struct random_data
- {
- int32_t *fptr; /* Front pointer. */
- int32_t *rptr; /* Rear pointer. */
- int32_t *state; /* Array of state values. */
- int rand_type; /* Type of random number generator. */
- int rand_deg; /* Degree of random number generator. */
- int rand_sep; /* Distance between front and rear. */
- int32_t *end_ptr; /* Pointer behind state table. */
- };
-int __random_r (struct random_data *buf, int32_t *result);
-
-
-
-/* An improved random number generation package. In addition to the standard
- rand()/srand() like interface, this package also has a special state info
- interface. The initstate() routine is called with a seed, an array of
- bytes, and a count of how many bytes are being passed in; this array is
- then initialized to contain information for random number generation with
- that much state information. Good sizes for the amount of state
- information are 32, 64, 128, and 256 bytes. The state can be switched by
- calling the setstate() function with the same array as was initialized
- with initstate(). By default, the package runs with 128 bytes of state
- information and generates far better random numbers than a linear
- congruential generator. If the amount of state information is less than
- 32 bytes, a simple linear congruential R.N.G. is used. Internally, the
- state information is treated as an array of longs; the zeroth element of
- the array is the type of R.N.G. being used (small integer); the remainder
- of the array is the state information for the R.N.G. Thus, 32 bytes of
- state information will give 7 longs worth of state information, which will
- allow a degree seven polynomial. (Note: The zeroth word of state
- information also has some other information stored in it; see setstate
- for details). The random number generation technique is a linear feedback
- shift register approach, employing trinomials (since there are fewer terms
- to sum up that way). In this approach, the least significant bit of all
- the numbers in the state table will act as a linear feedback shift register,
- and will have period 2^deg - 1 (where deg is the degree of the polynomial
- being used, assuming that the polynomial is irreducible and primitive).
- The higher order bits will have longer periods, since their values are
- also influenced by pseudo-random carries out of the lower bits. The
- total period of the generator is approximately deg*(2**deg - 1); thus
- doubling the amount of state information has a vast influence on the
- period of the generator. Note: The deg*(2**deg - 1) is an approximation
- only good for large deg, when the period of the shift register is the
- dominant factor. With deg equal to seven, the period is actually much
- longer than the 7*(2**7 - 1) predicted by this formula. */
-
-
-
-/* For each of the currently supported random number generators, we have a
- break value on the amount of state information (you need at least this many
- bytes of state info to support this random number generator), a degree for
- the polynomial (actually a trinomial) that the R.N.G. is based on, and
- separation between the two lower order coefficients of the trinomial. */
-
-/* Linear congruential. */
-#define TYPE_0 0
-#define BREAK_0 8
-#define DEG_0 0
-#define SEP_0 0
-
-/* x**7 + x**3 + 1. */
-#define TYPE_1 1
-#define BREAK_1 32
-#define DEG_1 7
-#define SEP_1 3
-
-/* x**15 + x + 1. */
-#define TYPE_2 2
-#define BREAK_2 64
-#define DEG_2 15
-#define SEP_2 1
-
-/* x**31 + x**3 + 1. */
-#define TYPE_3 3
-#define BREAK_3 128
-#define DEG_3 31
-#define SEP_3 3
-
-/* x**63 + x + 1. */
-#define TYPE_4 4
-#define BREAK_4 256
-#define DEG_4 63
-#define SEP_4 1
-
-
-/* Array versions of the above information to make code run faster.
- Relies on fact that TYPE_i == i. */
-
-#define MAX_TYPES 5 /* Max number of types above. */
-
-struct random_poly_info
-{
- int seps[MAX_TYPES];
- int degrees[MAX_TYPES];
-};
-
-static const struct random_poly_info random_poly_info =
-{
- { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 },
- { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 }
-};
-
-
-
-
-/* Initialize the random number generator based on the given seed. If the
- type is the trivial no-state-information type, just remember the seed.
- Otherwise, initializes state[] based on the given "seed" via a linear
- congruential generator. Then, the pointers are set to known locations
- that are exactly rand_sep places apart. Lastly, it cycles the state
- information a given number of times to get rid of any initial dependencies
- introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
- for default usage relies on values produced by this routine. */
-int
-__srandom_r (seed, buf)
- unsigned int seed;
- struct random_data *buf;
-{
- int type;
- int32_t *state;
- long int i;
- long int word;
- int32_t *dst;
- int kc;
-
- if (buf == NULL)
- goto fail;
- type = buf->rand_type;
- if ((unsigned int) type >= MAX_TYPES)
- goto fail;
-
- state = buf->state;
- /* We must make sure the seed is not 0. Take arbitrarily 1 in this case. */
- if (seed == 0)
- seed = 1;
- state[0] = seed;
- if (type == TYPE_0)
- goto done;
-
- dst = state;
- word = seed;
- kc = buf->rand_deg;
- for (i = 1; i < kc; ++i)
- {
- /* This does:
- state[i] = (16807 * state[i - 1]) % 2147483647;
- but avoids overflowing 31 bits. */
- long int hi = word / 127773;
- long int lo = word % 127773;
- word = 16807 * lo - 2836 * hi;
- if (word < 0)
- word += 2147483647;
- *++dst = word;
- }
-
- buf->fptr = &state[buf->rand_sep];
- buf->rptr = &state[0];
- kc *= 10;
- while (--kc >= 0)
- {
- int32_t discard;
- (void) __random_r (buf, &discard);
- }
-
- done:
- return 0;
-
- fail:
- return -1;
-}
-
-
-/* Initialize the state information in the given array of N bytes for
- future random number generation. Based on the number of bytes we
- are given, and the break values for the different R.N.G.'s, we choose
- the best (largest) one we can and set things up for it. srandom is
- then called to initialize the state information. Note that on return
- from srandom, we set state[-1] to be the type multiplexed with the current
- value of the rear pointer; this is so successive calls to initstate won't
- lose this information and will be able to restart with setstate.
- Note: The first thing we do is save the current state, if any, just like
- setstate so that it doesn't matter when initstate is called.
- Returns a pointer to the old state. */
-int
-__initstate_r (seed, arg_state, n, buf)
- unsigned int seed;
- char *arg_state;
- size_t n;
- struct random_data *buf;
-{
- int type;
- int degree;
- int separation;
- int32_t *state;
-
- if (buf == NULL)
- goto fail;
-
- if (n >= BREAK_3)
- type = n < BREAK_4 ? TYPE_3 : TYPE_4;
- else if (n < BREAK_1)
- {
- if (n < BREAK_0)
- {
- __set_errno (EINVAL);
- goto fail;
- }
- type = TYPE_0;
- }
- else
- type = n < BREAK_2 ? TYPE_1 : TYPE_2;
-
- degree = random_poly_info.degrees[type];
- separation = random_poly_info.seps[type];
-
- buf->rand_type = type;
- buf->rand_sep = separation;
- buf->rand_deg = degree;
- state = &((int32_t *) arg_state)[1]; /* First location. */
- /* Must set END_PTR before srandom. */
- buf->end_ptr = &state[degree];
-
- buf->state = state;
-
- __srandom_r (seed, buf);
-
- state[-1] = TYPE_0;
- if (type != TYPE_0)
- state[-1] = (buf->rptr - state) * MAX_TYPES + type;
-
- return 0;
-
- fail:
- __set_errno (EINVAL);
- return -1;
-}
-
-
-/* Restore the state from the given state array.
- Note: It is important that we also remember the locations of the pointers
- in the current state information, and restore the locations of the pointers
- from the old state information. This is done by multiplexing the pointer
- location into the zeroth word of the state information. Note that due
- to the order in which things are done, it is OK to call setstate with the
- same state as the current state
- Returns a pointer to the old state information. */
-int
-__setstate_r (arg_state, buf)
- char *arg_state;
- struct random_data *buf;
-{
- int32_t *new_state = 1 + (int32_t *) arg_state;
- int type;
- int old_type;
- int32_t *old_state;
- int degree;
- int separation;
-
- if (arg_state == NULL || buf == NULL)
- goto fail;
-
- old_type = buf->rand_type;
- old_state = buf->state;
- if (old_type == TYPE_0)
- old_state[-1] = TYPE_0;
- else
- old_state[-1] = (MAX_TYPES * (buf->rptr - old_state)) + old_type;
-
- type = new_state[-1] % MAX_TYPES;
- if (type < TYPE_0 || type > TYPE_4)
- goto fail;
-
- buf->rand_deg = degree = random_poly_info.degrees[type];
- buf->rand_sep = separation = random_poly_info.seps[type];
- buf->rand_type = type;
-
- if (type != TYPE_0)
- {
- int rear = new_state[-1] / MAX_TYPES;
- buf->rptr = &new_state[rear];
- buf->fptr = &new_state[(rear + separation) % degree];
- }
- buf->state = new_state;
- /* Set end_ptr too. */
- buf->end_ptr = &new_state[degree];
-
- return 0;
-
- fail:
- __set_errno (EINVAL);
- return -1;
-}
-
-
-/* If we are using the trivial TYPE_0 R.N.G., just do the old linear
- congruential bit. Otherwise, we do our fancy trinomial stuff, which is the
- same in all the other cases due to all the global variables that have been
- set up. The basic operation is to add the number at the rear pointer into
- the one at the front pointer. Then both pointers are advanced to the next
- location cyclically in the table. The value returned is the sum generated,
- reduced to 31 bits by throwing away the "least random" low bit.
- Note: The code takes advantage of the fact that both the front and
- rear pointers can't wrap on the same call by not testing the rear
- pointer if the front one has wrapped. Returns a 31-bit random number. */
-
-int
-__random_r (buf, result)
- struct random_data *buf;
- int32_t *result;
-{
- int32_t *state;
-
- if (buf == NULL || result == NULL)
- goto fail;
-
- state = buf->state;
-
- if (buf->rand_type == TYPE_0)
- {
- int32_t val = state[0];
- val = ((state[0] * 1103515245) + 12345) & 0x7fffffff;
- state[0] = val;
- *result = val;
- }
- else
- {
- int32_t *fptr = buf->fptr;
- int32_t *rptr = buf->rptr;
- int32_t *end_ptr = buf->end_ptr;
- int32_t val;
-
- val = *fptr += *rptr;
- /* Chucking least random bit. */
- *result = (val >> 1) & 0x7fffffff;
- ++fptr;
- if (fptr >= end_ptr)
- {
- fptr = state;
- ++rptr;
- }
- else
- {
- ++rptr;
- if (rptr >= end_ptr)
- rptr = state;
- }
- buf->fptr = fptr;
- buf->rptr = rptr;
- }
- return 0;
-
- fail:
- __set_errno (EINVAL);
- return -1;
-}
-
-/* Copyright (C) 1995 Free Software Foundation
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
-
-/*
- * This is derived from the Berkeley source:
- * @(#)random.c 5.5 (Berkeley) 7/6/88
- * It was reworked for the GNU C Library by Roland McGrath.
- * Rewritten to use reentrant functions by Ulrich Drepper, 1995.
- */
-
-/*
- Copyright (C) 1983 Regents of the University of California.
- All rights reserved.
-
- 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 University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.*/
-
-#include <limits.h>
-#include <stddef.h>
-#include <stdlib.h>
-
-
-/* An improved random number generation package. In addition to the standard
- rand()/srand() like interface, this package also has a special state info
- interface. The initstate() routine is called with a seed, an array of
- bytes, and a count of how many bytes are being passed in; this array is
- then initialized to contain information for random number generation with
- that much state information. Good sizes for the amount of state
- information are 32, 64, 128, and 256 bytes. The state can be switched by
- calling the setstate() function with the same array as was initialized
- with initstate(). By default, the package runs with 128 bytes of state
- information and generates far better random numbers than a linear
- congruential generator. If the amount of state information is less than
- 32 bytes, a simple linear congruential R.N.G. is used. Internally, the
- state information is treated as an array of longs; the zeroth element of
- the array is the type of R.N.G. being used (small integer); the remainder
- of the array is the state information for the R.N.G. Thus, 32 bytes of
- state information will give 7 longs worth of state information, which will
- allow a degree seven polynomial. (Note: The zeroth word of state
- information also has some other information stored in it; see setstate
- for details). The random number generation technique is a linear feedback
- shift register approach, employing trinomials (since there are fewer terms
- to sum up that way). In this approach, the least significant bit of all
- the numbers in the state table will act as a linear feedback shift register,
- and will have period 2^deg - 1 (where deg is the degree of the polynomial
- being used, assuming that the polynomial is irreducible and primitive).
- The higher order bits will have longer periods, since their values are
- also influenced by pseudo-random carries out of the lower bits. The
- total period of the generator is approximately deg*(2**deg - 1); thus
- doubling the amount of state information has a vast influence on the
- period of the generator. Note: The deg*(2**deg - 1) is an approximation
- only good for large deg, when the period of the shift register is the
- dominant factor. With deg equal to seven, the period is actually much
- longer than the 7*(2**7 - 1) predicted by this formula. */
-
-
-
-/* For each of the currently supported random number generators, we have a
- break value on the amount of state information (you need at least this many
- bytes of state info to support this random number generator), a degree for
- the polynomial (actually a trinomial) that the R.N.G. is based on, and
- separation between the two lower order coefficients of the trinomial. */
-
-/* Linear congruential. */
-#define TYPE_0 0
-#define BREAK_0 8
-#define DEG_0 0
-#define SEP_0 0
-
-/* x**7 + x**3 + 1. */
-#define TYPE_1 1
-#define BREAK_1 32
-#define DEG_1 7
-#define SEP_1 3
-
-/* x**15 + x + 1. */
-#define TYPE_2 2
-#define BREAK_2 64
-#define DEG_2 15
-#define SEP_2 1
-
-/* x**31 + x**3 + 1. */
-#define TYPE_3 3
-#define BREAK_3 128
-#define DEG_3 31
-#define SEP_3 3
-
-/* x**63 + x + 1. */
-#define TYPE_4 4
-#define BREAK_4 256
-#define DEG_4 63
-#define SEP_4 1
-
-
-/* Array versions of the above information to make code run faster.
- Relies on fact that TYPE_i == i. */
-
-#define MAX_TYPES 5 /* Max number of types above. */
-
-
-/* Initially, everything is set up as if from:
- initstate(1, randtbl, 128);
- Note that this initialization takes advantage of the fact that srandom
- advances the front and rear pointers 10*rand_deg times, and hence the
- rear pointer which starts at 0 will also end up at zero; thus the zeroth
- element of the state information, which contains info about the current
- position of the rear pointer is just
- (MAX_TYPES * (rptr - state)) + TYPE_3 == TYPE_3. */
-
-static int32_t randtbl[DEG_3 + 1] =
- {
- TYPE_3,
-
- -1726662223, 379960547, 1735697613, 1040273694, 1313901226,
- 1627687941, -179304937, -2073333483, 1780058412, -1989503057,
- -615974602, 344556628, 939512070, -1249116260, 1507946756,
- -812545463, 154635395, 1388815473, -1926676823, 525320961,
- -1009028674, 968117788, -123449607, 1284210865, 435012392,
- -2017506339, -911064859, -370259173, 1132637927, 1398500161,
- -205601318,
- };
-
-
-static struct random_data unsafe_state =
- {
-/* FPTR and RPTR are two pointers into the state info, a front and a rear
- pointer. These two pointers are always rand_sep places aparts, as they
- cycle through the state information. (Yes, this does mean we could get
- away with just one pointer, but the code for random is more efficient
- this way). The pointers are left positioned as they would be from the call:
- initstate(1, randtbl, 128);
- (The position of the rear pointer, rptr, is really 0 (as explained above
- in the initialization of randtbl) because the state table pointer is set
- to point to randtbl[1] (as explained below).) */
-
- .fptr = &randtbl[SEP_3 + 1],
- .rptr = &randtbl[1],
-
-/* The following things are the pointer to the state information table,
- the type of the current generator, the degree of the current polynomial
- being used, and the separation between the two pointers.
- Note that for efficiency of random, we remember the first location of
- the state information, not the zeroth. Hence it is valid to access
- state[-1], which is used to store the type of the R.N.G.
- Also, we remember the last location, since this is more efficient than
- indexing every time to find the address of the last element to see if
- the front and rear pointers have wrapped. */
-
- .state = &randtbl[1],
-
- .rand_type = TYPE_3,
- .rand_deg = DEG_3,
- .rand_sep = SEP_3,
-
- .end_ptr = &randtbl[sizeof (randtbl) / sizeof (randtbl[0])]
-};
-
-/* POSIX.1c requires that there is mutual exclusion for the `rand' and
- `srand' functions to prevent concurrent calls from modifying common
- data. */
-
-/* Initialize the random number generator based on the given seed. If the
- type is the trivial no-state-information type, just remember the seed.
- Otherwise, initializes state[] based on the given "seed" via a linear
- congruential generator. Then, the pointers are set to known locations
- that are exactly rand_sep places apart. Lastly, it cycles the state
- information a given number of times to get rid of any initial dependencies
- introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
- for default usage relies on values produced by this routine. */
-void
-__srandom (x)
- unsigned int x;
-{
- (void) __srandom_r (x, &unsafe_state);
-}
-
-
-/* Initialize the state information in the given array of N bytes for
- future random number generation. Based on the number of bytes we
- are given, and the break values for the different R.N.G.'s, we choose
- the best (largest) one we can and set things up for it. srandom is
- then called to initialize the state information. Note that on return
- from srandom, we set state[-1] to be the type multiplexed with the current
- value of the rear pointer; this is so successive calls to initstate won't
- lose this information and will be able to restart with setstate.
- Note: The first thing we do is save the current state, if any, just like
- setstate so that it doesn't matter when initstate is called.
- Returns a pointer to the old state. */
-char *
-__initstate (seed, arg_state, n)
- unsigned int seed;
- char *arg_state;
- size_t n;
-{
- int32_t *ostate;
-
-
- ostate = &unsafe_state.state[-1];
-
- __initstate_r (seed, arg_state, n, &unsafe_state);
-
-
- return (char *) ostate;
-}
-
-
-/* Restore the state from the given state array.
- Note: It is important that we also remember the locations of the pointers
- in the current state information, and restore the locations of the pointers
- from the old state information. This is done by multiplexing the pointer
- location into the zeroth word of the state information. Note that due
- to the order in which things are done, it is OK to call setstate with the
- same state as the current state
- Returns a pointer to the old state information. */
-char *
-__setstate (arg_state)
- char *arg_state;
-{
- int32_t *ostate;
-
-
- ostate = &unsafe_state.state[-1];
-
- if (__setstate_r (arg_state, &unsafe_state) < 0)
- ostate = NULL;
-
-
- return (char *) ostate;
-}
-
-
-/* If we are using the trivial TYPE_0 R.N.G., just do the old linear
- congruential bit. Otherwise, we do our fancy trinomial stuff, which is the
- same in all the other cases due to all the global variables that have been
- set up. The basic operation is to add the number at the rear pointer into
- the one at the front pointer. Then both pointers are advanced to the next
- location cyclically in the table. The value returned is the sum generated,
- reduced to 31 bits by throwing away the "least random" low bit.
- Note: The code takes advantage of the fact that both the front and
- rear pointers can't wrap on the same call by not testing the rear
- pointer if the front one has wrapped. Returns a 31-bit random number. */
-
-long int
-__random (void)
-{
- int32_t retval;
-
-
- (void) __random_r (&unsafe_state, &retval);
-
-
- return retval;
-}
-
-long int glibc_random(void) { return __random(); }
-void glibc_srandom(unsigned int seed) { __srandom(seed); }
-char *glibc_initstate(unsigned int seed, char *state, size_t n) { return __initstate(seed,state,n); }
-char *glibc_setstate(char *state) { return __setstate(state); }
-#endif
diff --git a/mbbsd/read.c b/mbbsd/read.c
deleted file mode 100644
index 97621725..00000000
--- a/mbbsd/read.c
+++ /dev/null
@@ -1,1371 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-static int headers_size = 0;
-static fileheader_t *headers = NULL;
-static int last_line; // PTT: last_line ´å¼Ð¥i«üªº³Ì«á¤@­Ó
-
-#include <sys/mman.h>
-
-/* ----------------------------------------------------- */
-/* Tag List ¼ÐÅÒ */
-/* ----------------------------------------------------- */
-static TagItem *TagList = NULL; /* ascending list */
-
-/**
- * @param locus
- * @return void
- */
-void
-UnTagger(int locus)
-{
- if (locus > TagNum || TagNum <= 0)
- return;
-
- TagNum--;
-
- if (TagNum > locus)
- memmove(&TagList[locus], &TagList[locus + 1],
- (TagNum - locus) * sizeof(TagItem));
-}
-
-int
-Tagger(time4_t chrono, int recno, int mode)
-{
- int head, tail, posi = 0, comp;
-
- if(TagList == NULL) {
- TagList = malloc(sizeof(TagItem)*(MAXTAGS+1));
- }
-
- for (head = 0, tail = TagNum - 1, comp = 1; head <= tail;) {
- posi = (head + tail) >> 1;
- comp = TagList[posi].chrono - chrono;
- if (!comp) {
- break;
- } else if (comp < 0) {
- head = posi + 1;
- } else {
- tail = posi - 1;
- }
- }
-
- if (mode == TAG_NIN) {
- if (!comp && recno) /* µ´¹ïÄYÂÔ¡G³s recno ¤@°_¤ñ¹ï */
- comp = recno - TagList[posi].recno;
- return comp;
-
- }
- if (!comp) {
- if (mode != TAG_TOGGLE || TagNum <= 0)
- return NA;
-
- TagNum--;
- memmove(&TagList[posi], &TagList[posi + 1],
- (TagNum - posi) * sizeof(TagItem));
- } else if (TagNum < MAXTAGS) {
- TagItem *tagp;
-
- memmove(&TagList[head+1], &TagList[head], sizeof(TagItem)*(TagNum-head));
- tagp = &TagList[head];
- tagp->chrono = chrono;
- tagp->recno = recno;
- TagNum++;
- } else {
- bell();
- return 0; /* full */
- }
- return YEA;
-}
-
-#if 0
-static void
-EnumTagName(char *fname, int locus) /* unused */
-{
- snprintf(fname, sizeof(fname), "M.%d.A", (int)TagList[locus].chrono);
-}
-#endif
-
-void
-EnumTagFhdr(fileheader_t * fhdr, char *direct, int locus)
-{
- get_record(direct, fhdr, sizeof(fileheader_t), TagList[locus].recno);
-}
-
-/* -1 : ¨ú®ø */
-/* 0 : single article */
-/* ow: whole tag list */
-
-int
-AskTag(const char *msg)
-{
- int num;
-
- num = TagNum;
- switch (getans("¡» %s A)¤å³¹ T)¼Ð°O Q)uit?", msg)) {
- case 'q':
- num = -1;
- break;
- case 'a':
- num = 0;
- }
- return num;
-}
-
-
-#include <sys/mman.h>
-
-#define BATCH_SIZE 65536
-
-static char *
-f_map(const char *fpath, int *fsize)
-{
- int fd, size;
- struct stat st;
- char *map;
-
- if ((fd = open(fpath, O_RDONLY)) < 0)
- return (char *)-1;
-
- if (fstat(fd, &st) || !S_ISREG(st.st_mode) || (size = st.st_size) <= 0) {
- close(fd);
- return (char *)-1;
- }
- map = (char *)mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
- close(fd);
- *fsize = size;
- return map;
-}
-
-
-static int
-TagThread(const char *direct)
-{
- int fsize, count;
- char *title, *fimage;
- fileheader_t *head, *tail;
-
- fimage = f_map(direct, &fsize);
- if (fimage == (char *)-1)
- return DONOTHING;
-
- head = (fileheader_t *) fimage;
- tail = (fileheader_t *) (fimage + fsize);
- count = 0;
- do {
- count++;
- title = subject(head->title);
- if (!strncmp(currtitle, title, TTLEN)) {
- if (!Tagger(atoi(head->filename + 2), count, TAG_INSERT))
- break;
- }
- } while (++head < tail);
-
- munmap(fimage, fsize);
- return FULLUPDATE;
-}
-
-
-int
-TagPruner(int bid)
-{
- boardheader_t *bp=NULL;
- assert(bid >= 0); /* bid == 0 means in mailbox */
- if (bid){
- bp = getbcache(bid);
- if (strcmp(bp->brdname, GLOBAL_SECURITY) == 0)
- return DONOTHING;
- }
- if (TagNum && ((currstat != READING) || (currmode & MODE_BOARD))) {
- if (getans("§R°£©Ò¦³¼Ð°O[N]?") != 'y')
- return READ_REDRAW;
-#ifdef SAFE_ARTICLE_DELETE
- if(bp && !(currmode & MODE_DIGEST) && bp->nuser>30 )
- safe_delete_range(currdirect, 0, 0);
- else
-#endif
- delete_range(currdirect, 0, 0);
- TagNum = 0;
- if (bid)
- setbtotal(bid);
- else if(currstat == RMAIL)
- setupmailusage();
-
- return NEWDIRECT;
- }
- return DONOTHING;
-}
-
-
-/* ----------------------------------------------------- */
-/* cursor & reading record position control */
-/* ----------------------------------------------------- */
-keeploc_t *
-getkeep(const char *s, int def_topline, int def_cursline)
-{
- /* ¬°¬Ù°O¾ÐÅé, ¥BÁקK malloc/free ¤£¦¨¹ï, getkeep ³Ì¦n¤£­n malloc,
- * ¥u°O s ªº hash ­È,
- * fvn1a-32bit collision ¾÷²v¬ù¤p©ó¤Q¸U¤À¤§¤@ */
- /* ­ì¥»¨Ï¥Î link list, ¥i¬O¤@¤è­±·|³y¦¨ malloc/free ¤£¦¨¹ï,
- * ¤@¤è­± size ¤p, malloc space overhead ´N°ª, ¦]¦¹§ï¦¨ link block,
- * ¥H KEEPSLOT ¬°¤@­Ó block ªº link list.
- * ¥u¦³²Ä¤@­Ó block ¥i¯à¨Sº¡. */
- /* TODO LRU recycle? ³Â·Ð¦b©ó§O³B¥i¯à§â keeploc_t pointer °OµÛ... */
-#define KEEPSLOT 10
- struct keepsome {
- unsigned char used;
- keeploc_t arr[KEEPSLOT];
- struct keepsome *next;
- };
- static struct keepsome preserv_keepblock;
- static struct keepsome *keeplist = &preserv_keepblock;
- struct keeploc_t *p;
- unsigned key=StringHash(s);
- int i;
-
- if (def_cursline >= 0) {
- struct keepsome *kl=keeplist;
- while(kl) {
- for(i=0; i<kl->used; i++)
- if(key == kl->arr[i].hashkey) {
- p = &kl->arr[i];
- if (p->crs_ln < 1)
- p->crs_ln = 1;
- return p;
- }
- kl=kl->next;
- }
- } else
- def_cursline = -def_cursline;
-
- if(keeplist->used==KEEPSLOT) {
- struct keepsome *kl;
- kl = (struct keepsome*)malloc(sizeof(struct keepsome));
- memset(kl, 0, sizeof(struct keepsome));
- kl->next = keeplist;
- keeplist = kl;
- }
- p = &keeplist->arr[keeplist->used];
- keeplist->used++;
- p->hashkey = key;
- p->top_ln = def_topline;
- p->crs_ln = def_cursline;
- return p;
-}
-
-void
-fixkeep(const char *s, int first)
-{
- keeploc_t *k;
-
- k = getkeep(s, 1, 1);
- if (k->crs_ln >= first) {
- k->crs_ln = (first == 1 ? 1 : first - 1);
- k->top_ln = (first < 11 ? 1 : first - 10);
- }
-}
-
-/* calc cursor pos and show cursor correctly */
-static int
-cursor_pos(keeploc_t * locmem, int val, int from_top, int isshow)
-{
- int top=locmem->top_ln;
- if (!last_line){
- cursor_show(3 , 0);
- return DONOTHING;
- }
- if (val > last_line)
- val = last_line;
- if (val <= 0)
- val = 1;
- if (val >= top && val < top + headers_size) {
- if(isshow){
- if(locmem->crs_ln >= top)
- cursor_clear(3 + locmem->crs_ln - top, 0);
- cursor_show(3 + val - top, 0);
- }
- locmem->crs_ln = val;
- return DONOTHING;
- }
- locmem->top_ln = val - from_top;
- if (locmem->top_ln <= 0)
- locmem->top_ln = 1;
- locmem->crs_ln = val;
- return isshow ? PARTUPDATE : HEADERS_RELOAD;
-}
-
-/**
- * ®Ú¾Ú stypen ¿ï¾Ü¤W/¤U¤@½g¤å³¹
- *
- * @param locmem ¥Î¨Ó¦s¦b¬Y¬ÝªO´å¼Ð¦ì¸mªº structure¡C
- * @param stypen ´å¼Ð²¾°Êªº¤èªk
- * CURSOR_FIRST, CURSOR_NEXT, CURSOR_PREV:
- * »P´å¼Ð¥Ø«e¦ì¸mªº¤å³¹¦P¼ÐÃD ªº ²Ä¤@½g/¤U¤@½g/«e¤@½g ¤å³¹¡C
- * RELATE_FIRST, RELATE_NEXT, RELATE_PREV:
- * »P¥Ø«e¥¿¾\Ūªº¤å³¹¦P¼ÐÃD ªº ²Ä¤@½g/¤U¤@½g/«e¤@½g ¤å³¹¡C
- * NEWPOST_NEXT, NEWPOST_PREV:
- * ¤U¤@­Ó/«e¤@­Ó thread ªº²Ä¤@½g¡C
- * AUTHOR_NEXT, AUTHOR_PREV:
- * XXX ³o¥\¯à¥Ø«e¦n¹³¨S¥Î¨ì?
- *
- * @return ·sªº´å¼Ð¦ì¸m
- */
-static int
-thread(const keeploc_t * locmem, int stypen)
-{
- fileheader_t fh;
- int pos = locmem->crs_ln, jump = THREAD_SEARCH_RANGE, new_ln;
- int fd = -1, amatch = -1;
- int step = (stypen & RS_FORWARD) ? 1 : -1;
- char *key;
-
- if(locmem->crs_ln==0)
- return locmem->crs_ln;
-
- STATINC(STAT_THREAD);
- if (stypen & RS_AUTHOR)
- key = headers[pos - locmem->top_ln].owner;
- else if (stypen & RS_CURRENT)
- key = subject(currtitle);
- else
- key = subject(headers[pos - locmem->top_ln].title );
-
- for( new_ln = pos + step ;
- new_ln > 0 && new_ln <= last_line && --jump > 0;
- new_ln += step ) {
-
- int rk =
- get_record_keep(currdirect, &fh, sizeof(fileheader_t), new_ln, &fd);
-
- if(fd < 0 || rk < 0)
- {
- new_ln = pos;
- break;
- }
-
- if( stypen & RS_TITLE ){
- if( stypen & RS_FIRST ){
- if( !strncmp(fh.title, key, PROPER_TITLE_LEN) )
- break;
- else if( !strncmp(&fh.title[4], key, PROPER_TITLE_LEN) ) {
- amatch = new_ln;
- jump = THREAD_SEARCH_RANGE;
- /* ·í·j´M¦P¥DÃD²Ä¤@½g, ³sÄò§ä¤£¨ì¦h¤Ö½g¤~°± */
- }
- }
- else if( !strncmp(subject(fh.title), key, PROPER_TITLE_LEN) )
- break;
- }
- else if( stypen & RS_NEWPOST ){
- if( strncmp(fh.title, "Re:", 3) )
- break;
- }
- else{ // RS_AUTHOR
- if( strcmp(subject(fh.owner), key) == EQUSTR )
- break;
- }
- }
-
- if( fd != -1 )
- close(fd);
-
- if( jump <= 0 || new_ln <= 0 || new_ln > last_line )
- new_ln = (amatch == -1 ? pos : amatch); //didn't find
-
- return new_ln;
-}
-
-#ifdef INTERNET_EMAIL
-static void
-mail_forward(const fileheader_t * fhdr, const char *direct, int mode)
-{
- int i;
- char buf[STRLEN];
- char *p;
-
- strlcpy(buf, direct, sizeof(buf));
- if ((p = strrchr(buf, '/')))
- *p = '\0';
- switch (i = doforward(buf, fhdr, mode)) {
- case 0:
- vmsg(msg_fwd_ok);
- break;
- case -1:
- vmsg(msg_fwd_err1);
- break;
- case -2:
-#ifndef DEBUG_FWDADDRERR
- vmsg(msg_fwd_err2);
-#endif
- break;
- case -4:
- vmsg("«H½c¤wº¡");
- break;
- default:
- break;
- }
-}
-#endif
-
-// return: 1 - found, 0 - fail.
-inline static int
-dbcs_strcasestr(const char* pool, const char *ptr)
-{
-#if 0
- // old method
- int len = strlen(ptr);
-
- while(*pool)
- {
- // FIXME ¥Î strncasecmp ÁÙ¬O·|¿ù
- if(strncasecmp(pool, ptr, len) == 0)
- return 1;
- /* else */
- if(*pool < 0)
- {
- pool ++;
- if(*pool == 0)
- return 0;
- }
- pool ++;
- }
- return 0;
-
-#endif
-
- int i = 0, i2 = 0, found = 0,
- szpool = strlen(pool),
- szptr = strlen(ptr);
-
- for (i = 0; i <= szpool-szptr; i++)
- {
- found = 1;
-
- // compare szpool[i..szptr] with ptr
- for (i2 = 0; i2 < szptr; i2++)
- {
- if (pool[i + i2] > 0)
- {
- // ascii
- if (ptr[i2] < 0 ||
- tolower(ptr[i2]) != tolower(pool[i+i2]))
- {
- // printf("break on ascii (i=%d, i2=%d).\n", i, i2);
- found = 0;
- break;
- }
- } else {
- // non-ascii
- if (ptr[i2] != pool[i+i2] ||
- ptr[i2+1] != pool[i+i2+1])
- {
- // printf("break on non-ascii (i=%d, i2=%d).\n", i, i2);
- found = 0;
- break;
- }
- i2 ++;
- }
- }
-
- if (found) break;
-
- // next iteration: if target is DBCS, skip one more byte.
- if (pool[i] < 0)
- i++;
- }
- return found;
-}
-
-static int
-select_read(const keeploc_t * locmem, int sr_mode)
-{
-#define READSIZE 64 // 8192 / sizeof(fileheader_t)
- time4_t filetime;
- fileheader_t fhs[READSIZE];
- char newdirect[MAXPATHLEN];
- int first_select;
- char genbuf[MAXPATHLEN], *p = strstr(currdirect, "SR.");
- static int _mode = 0;
- int reload, inc;
- int len, fd, fr, i, count = 0, reference = 0;
- int filemode;
- /* selection condition */
- char keyword[TTLEN + 1] = "";
- int n_recommend = 0, n_money = 0;
-
-
- if(locmem->crs_ln == 0)
- return locmem->crs_ln;
-
- first_select = p==NULL;
-
- STATINC(STAT_SELECTREAD);
- if(sr_mode & RS_AUTHOR)
- {
- if(!getdata(b_lines, 0,
- currmode & MODE_SELECT ? "¼W¥[±ø¥ó §@ªÌ: ":"·j´M§@ªÌ: ",
- keyword, IDLEN+1, LCECHO))
- return READ_REDRAW;
- }
- else if(sr_mode & RS_KEYWORD)
- {
- if(!getdata(b_lines, 0,
- currmode & MODE_SELECT ? "¼W¥[±ø¥ó ¼ÐÃD: ":"·j´M¼ÐÃD: ",
- keyword, TTLEN, DOECHO))
- return READ_REDRAW;
-#ifdef KEYWORD_LOG
- log_file("keyword_search_log", LOG_CREAT | LOG_VF,
- "%s:%s\n", currboard, keyword);
-#endif
- }
- else if(sr_mode & RS_KEYWORD_EXCLUDE)
- {
- if(!(currmode & MODE_SELECT) ||
- !getdata(b_lines, 0, "¼W¥[±ø¥ó ±Æ°£¼ÐÃD: ",
- keyword, TTLEN, DOECHO))
- return READ_REDRAW;
- }
- else if (sr_mode & RS_RECOMMEND)
- {
- if(currstat == RMAIL || (
- !getdata(b_lines, 0,
- (currmode & MODE_SELECT) ?
- "¼W¥[±ø¥ó ±À¤å¼Æ: ":
- "·j´M±À¤å¼Æ°ª©ó¦h¤Ö"
-#ifndef OLDRECOMMEND
- " (<0«h·j¼N¤å¼Æ) "
-#endif // OLDRECOMMEND
- "ªº¤å³¹: ",
- keyword, 7, LCECHO) || (n_recommend = atoi(keyword)) == 0 ))
- return READ_REDRAW;
- }
- else if (sr_mode & RS_MONEY)
- {
- if(currstat == RMAIL || (
- !getdata(b_lines, 0,
- (currmode & MODE_SELECT) ?
- "¼W¥[±ø¥ó ¤å³¹»ù®æ: ":"·j´M»ù®æ°ª©ó¦h¤Öªº¤å³¹: ",
- keyword, 7, LCECHO) || (n_money = atoi(keyword)) <= 0 ))
- return READ_REDRAW;
- strcat(keyword, "M");
- }
- else {
- // Ptt: only once for these modes.
- if(!first_select && _mode & sr_mode & (RS_TITLE | RS_NEWPOST | RS_MARK))
- return DONOTHING;
-
- if(sr_mode & RS_TITLE) {
- fileheader_t *fh = &headers[locmem->crs_ln - locmem->top_ln];
- strcpy(keyword, subject(fh->title));
- }
- }
-
- if(first_select)
- _mode = sr_mode;
- else
- _mode |= sr_mode;
-
- snprintf(genbuf, sizeof(genbuf), "%s%X.%X.%X",
- first_select ? "SR.":p,
- sr_mode, (int)strlen(keyword), DBCS_StringHash(keyword));
- if( strlen(genbuf) > MAXPATHLEN - 50 )
- return READ_REDRAW; // avoid overflow
-
- if (currstat == RMAIL)
- sethomefile(newdirect, cuser.userid, genbuf);
- else
- setbfile(newdirect, currboard, genbuf);
-
- filetime = dasht(newdirect);
- count = dashs(newdirect) / sizeof(fileheader_t);
-
- if (currstat != RMAIL && currboard[0] && currbid > 0)
- {
- time4_t filecreate = dashc(newdirect);
- boardheader_t *bp = getbcache(currbid);
- assert(bp);
-
- if (bp->SRexpire)
- {
- if (bp->SRexpire > now) // invalid expire time.
- bp->SRexpire = now;
-
- if (bp->SRexpire > filecreate)
- filetime = -1;
- }
- }
-
- if(filetime<0 || now-filetime>60*60) {
- reload = 1;
- inc = 0;
- } else if(now-filetime > 3*60) {
- reload = 1;
- inc = 1;
- } else {
- /* use cached data */
- reload = 0;
- inc = 0;
- }
-
- /* mark and recommend shouldn't incremental select */
- if(sr_mode & (RS_MARK | RS_RECOMMEND))
- inc = 0;
-
- if(reload) {
- if( (fr = open(currdirect, O_RDONLY, 0)) != -1 ) {
- if(inc) {
- /* find incremental selection start point */
- int idx;
- sprintf(fhs[0].filename, "X.%d", (int)filetime);
- idx = getindex(currdirect, &fhs[0], 0);
- if(idx<0) {
- reference = -idx;
- } else if(idx==0) {
- inc = 0;
- } else {
- reference = idx;
- }
- }
- if(inc) {
- filemode = O_APPEND | O_RDWR;
- } else {
- filemode = O_CREAT | O_RDWR;
- count = 0;
- reference = 0;
- }
-
- if( (fd = open(newdirect, filemode, 0600)) == -1 ) {
- close(fr);
- return READ_REDRAW;
- }
-
- if(reference>0)
- lseek(fr, reference*sizeof(fileheader_t), SEEK_SET);
-
-#ifdef DEBUG
- vmsgf("search: %s", currdirect);
-#endif
- while( (len = read(fr, fhs, sizeof(fhs))) > 0 ){
- len /= sizeof(fileheader_t);
- for( i = 0 ; i < len ; ++i ){
- reference++;
- if( (sr_mode & RS_MARK) &&
- !(fhs[i].filemode & FILE_MARKED) )
- continue;
- else if((sr_mode & RS_NEWPOST) &&
- !strncmp(fhs[i].title, "Re:", 3))
- continue;
- else if((sr_mode & RS_AUTHOR) &&
- !dbcs_strcasestr(fhs[i].owner, keyword))
- continue;
- else if((sr_mode & RS_KEYWORD) &&
- !dbcs_strcasestr(fhs[i].title, keyword))
- continue;
- else if(sr_mode & RS_KEYWORD_EXCLUDE &&
- dbcs_strcasestr(fhs[i].title, keyword))
- continue;
- else if((sr_mode & RS_TITLE) &&
- strcasecmp(subject(fhs[i].title), keyword))
- continue;
- else if ((sr_mode & RS_RECOMMEND) &&
- (n_recommend > 0 ?
- (fhs[i].recommend < n_recommend) :
- (fhs[i].recommend > n_recommend) ))
- continue;
- /* please put money test in last */
- else if ((sr_mode & RS_MONEY) &&
- query_file_money(fhs+i) < n_money)
- continue;
-
- if(first_select) {
- fhs[i].multi.refer.flag = 1;
- fhs[i].multi.refer.ref = reference;
- }
- ++count;
- write(fd, &fhs[i], sizeof(fileheader_t));
- }
- } // end while
- close(fr);
- ftruncate(fd, count*sizeof(fileheader_t));
- close(fd);
- }
- }
-
- if(count) {
- strlcpy(currdirect, newdirect, sizeof(currdirect));
- currmode |= MODE_SELECT;
- currsrmode |= sr_mode;
- return NEWDIRECT;
- }
- return READ_REDRAW;
-}
-
-static int newdirect_new_ln = -1;
-
-static int
-i_read_key(const onekey_t * rcmdlist, keeploc_t * locmem,
- int bid, int bottom_line)
-{
- int mode = DONOTHING, num, new_top=10;
- int ch, new_ln = locmem->crs_ln, lastmode = DONOTHING;
- char direct[60];
- static char default_ch = 0;
-
- do {
- if( (mode = cursor_pos(locmem, new_ln, new_top, default_ch ? 0 : 1))
- != DONOTHING )
- return mode;
-
- if( !default_ch )
- ch = igetch();
- else{
- if(new_ln != locmem->crs_ln) {// move fault
- default_ch=0;
- return FULLUPDATE;
- }
- ch = default_ch;
- }
-
- new_top = 10; // default 10
- switch (ch) {
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- if( (num = search_num(ch, last_line)) != -1 )
- new_ln = num + 1;
- break;
- case 'q':
- case 'e':
- case KEY_LEFT:
- if(currmode & MODE_SELECT && locmem->crs_ln>0){
- char genbuf[PATHLEN];
- fileheader_t *fhdr = &headers[locmem->crs_ln - locmem->top_ln];
- board_select();
- setbdir(genbuf, currboard);
- locmem = getkeep(genbuf, 0, 1);
- locmem->crs_ln = fhdr->multi.refer.ref;
- num = locmem->crs_ln - p_lines + 1;
- locmem->top_ln = num < 1 ? 1 : num;
- mode = NEWDIRECT;
- }
- else
- mode =
- (currmode & MODE_DIGEST) ? board_digest() : DOQUIT;
- break;
- case '#':
- {
- char aidc[100];
- aidu_t aidu = 0;
- char dirfile[PATHLEN];
- char *sp;
- int n = -1;
-
- if(!getdata(b_lines, 0, "·j´M" AID_DISPLAYNAME ": #", aidc, 20, LCECHO))
- {
- move(b_lines, 0);
- clrtoeol();
- mode = FULLUPDATE;
- break;
- }
-
- if((currmode & MODE_SELECT) ||
- (currstat == RMAIL))
- {
- move(21, 0);
- clrtobot();
- move(22, 0);
- prints("¦¹ª¬ºA¤UµLªk¨Ï¥Î·j´M" AID_DISPLAYNAME "¥\\¯à");
- pressanykey();
- mode = FULLUPDATE;
- break;
- }
-
- /* strip leading spaces and '#' */
- sp = aidc;
- while(*sp == ' ')
- sp ++;
- if(*sp == '#')
- sp ++;
-
- if((aidu = aidc2aidu(sp)) > 0)
- {
- /* search bottom */
- /* FIXME: ¸m©³¤å¦ý¨S¦C¦b .DIR.bottom ªº¦b³o¬q·|·j¤£¨ì¡A
- ¦b¤U¤@¬q search board ®É¤~·|·j¨ì¥»Åé¡CÃø¸Ñ¡C */
- {
- char buf[FNLEN];
-
- snprintf(buf, FNLEN, "%s.bottom", FN_DIR);
- setbfile(dirfile, currboard, buf);
- if((n = search_aidu(dirfile, aidu)) >= 0)
- {
- n += getbtotal(currbid);
- /* ¤£¥i¥Î bottom_line¡A¦]¬°¦pªG¬O¦b digest mode¡A
- bottom_line ·|¬O¤åºKªº¼Æ¥Ø¡A¦Ó¤£¬O¯u¥¿ªº¤å³¹¼Æ */
- if(currmode & MODE_DIGEST)
- {
- newdirect_new_ln = n;
-
- new_ln = locmem->crs_ln;
- /* dirty hack for crs_ln = 1, then HOME pressed */
-
- default_ch = KEY_TAB;
- mode = DONOTHING;
- break;
- }
- }
- }
- if(n < 0)
- /* search board */
- {
- setbfile(dirfile, currboard, FN_DIR);
- n = search_aidu(dirfile, aidu);
- if(n >= 0 && (currmode & MODE_DIGEST))
- /* switch to normal read mode */
- {
- newdirect_new_ln = n;
-
- new_ln = locmem->crs_ln;
- /* dirty hack for crs_ln = 1, then HOME pressed */
-
- default_ch = KEY_TAB;
- mode = DONOTHING;
- break;
- }
- }
- if(n < 0)
- /* search digest */
- {
- setbfile(dirfile, currboard, fn_mandex);
- n = search_aidu(dirfile, aidu);
- if(n >= 0 && !(currmode & MODE_DIGEST))
- /* switch to digest mode */
- {
- newdirect_new_ln = n;
-
- new_ln = locmem->crs_ln;
- /* dirty hack for crs_ln = 1, then HOME pressed */
-
- default_ch = KEY_TAB;
- mode = DONOTHING;
- break;
- }
- }
- } /* if(aidu > 0) */
- if(n < 0)
- {
- move(21, 0);
- clrtobot();
- move(22, 0);
- if(aidu <= 0)
- prints("¤£¦Xªkªº" AID_DISPLAYNAME "¡A½Ð½T©w¿é¤J¬O¥¿½Tªº");
- else
- prints("§ä¤£¨ì³o­Ó" AID_DISPLAYNAME "¡A¥i¯à¬O¤å³¹¤w®ø¥¢¡A©Î¬O§A§ä¿ù¬ÝªO¤F");
- pressanykey();
- mode = FULLUPDATE;
- } /* if(n < 0) */
- else
- {
- new_ln = n + 1;
- move(b_lines, 0);
- clrtoeol();
- mode = DONOTHING;
- }
- }
- break;
- case Ctrl('L'):
- redrawwin();
- refresh();
- break;
-
- case Ctrl('H'):
- mode = select_read(locmem, RS_NEWPOST);
- break;
-
- case 'Z':
- mode = select_read(locmem, RS_RECOMMEND);
- break;
-
- case 'a':
- mode = select_read(locmem, RS_AUTHOR);
- break;
-
- case 'A':
- mode = select_read(locmem, RS_MONEY);
- break;
-
- case 'G':
- mode = select_read(locmem, RS_MARK);
- break;
-
- case '/':
- case '?':
- mode = select_read(locmem, RS_KEYWORD);
- break;
-
- case 'S':
- mode = select_read(locmem, RS_TITLE);
- break;
-
- case '!':
- mode = select_read(locmem, RS_KEYWORD_EXCLUDE);
- break;
-
- case '=':
- new_ln = thread(locmem, RELATE_FIRST);
- break;
-
- case '\\':
- new_ln = thread(locmem, CURSOR_FIRST);
- break;
-
- case ']':
- new_ln = thread(locmem, RELATE_NEXT);
- break;
-
- case '+':
- new_ln = thread(locmem, CURSOR_NEXT);
- break;
-
- case '[':
- new_ln = thread(locmem, RELATE_PREV);
- break;
-
- case '-':
- new_ln = thread(locmem, CURSOR_PREV);
- break;
-
- case '<':
- case ',':
- new_ln = thread(locmem, NEWPOST_PREV);
- break;
-
- case '.':
- case '>':
- new_ln = thread(locmem, NEWPOST_NEXT);
- break;
-
- case 'p':
- case 'k':
- case KEY_UP:
- if (locmem->crs_ln <= 1) {
- new_ln = last_line;
- new_top = p_lines-1;
- } else {
- new_ln = locmem->crs_ln - 1;
- new_top = p_lines - 2;
- }
- break;
-
- case 'n':
- case 'j':
- case KEY_DOWN:
- new_ln = locmem->crs_ln + 1;
- new_top = 1;
- break;
-
- case ' ':
- case KEY_PGDN:
- case 'N':
- case Ctrl('F'):
- new_ln = locmem->top_ln + p_lines;
- new_top = 0;
- break;
-
- case KEY_PGUP:
- case Ctrl('B'):
- case 'P':
- new_ln = locmem->top_ln - p_lines;
- new_top = 0;
- break;
-
- /* add home(top entry) support? */
- case KEY_HOME:
- new_ln = 0;
- new_top = 0;
- break;
-
- case KEY_END:
- case '$':
- new_ln = last_line;
- new_top = p_lines-1;
- break;
-
- case 'F':
- case 'U':
- if (HasUserPerm(PERM_FORWARD) && locmem->crs_ln>0) {
- mail_forward(&headers[locmem->crs_ln - locmem->top_ln],
- currdirect, ch /* == 'U' */ );
- /* by CharlieL */
- // mode = READ_REDRAW;
- return FULLUPDATE;
- }
- break;
-
- case Ctrl('Q'):
- if(locmem->crs_ln>0)
- mode = my_query(headers[locmem->crs_ln - locmem->top_ln].owner);
- break;
-
- case Ctrl('S'):
- if (HasUserPerm(PERM_ACCOUNTS|PERM_SYSOP) && locmem->crs_ln>0) {
- int id;
- userec_t muser;
-
- strlcpy(currauthor,
- headers[locmem->crs_ln - locmem->top_ln].owner,
- sizeof(currauthor));
- stand_title("¨Ï¥ÎªÌ³]©w");
- move(1, 0);
- if ((id = getuser(headers[locmem->crs_ln - locmem->top_ln].owner, &muser))) {
- user_display(&muser, 1);
- if( HasUserPerm(PERM_ACCOUNTS) )
- uinfo_query(&muser, 1, id);
- else
- pressanykey();
- }
- mode = FULLUPDATE;
- }
- break;
-
- /* rocker.011018: ±Ä¥Î·sªºtag¼Ò¦¡ */
- case 't':
- if(locmem->crs_ln == 0)
- break;
- /* ±N­ì¥»¦b Read() ¸Ì­±ªº "TagNum = 0" ²¾¦Ü¦¹³B */
- if ((currstat & RMAIL && TagBoard != 0) ||
- (!(currstat & RMAIL) && TagBoard != bid)) {
- if (currstat & RMAIL)
- TagBoard = 0;
- else
- TagBoard = bid;
- TagNum = 0;
- }
- /* rocker.011112: ¸Ñ¨M¦Aselect mode¼Ð°O¤å³¹ªº°ÝÃD */
- if (Tagger(atoi(headers[locmem->crs_ln - locmem->top_ln].filename + 2),
- (currmode & MODE_SELECT) ?
- (headers[locmem->crs_ln - locmem->top_ln].multi.refer.ref) :
- locmem->crs_ln, TAG_TOGGLE))
- {
-// (*doentry) (locmem->crs_ln, &headers[locmem->crs_ln-locmem->top_ln]);
- locmem->crs_ln ++;
- // new_ln = locmem->crs_ln + 1;
- // new_top = 1;
- // mode = FULLUPDATE;
- // mode = PART_REDRAW;
- mode = PARTUPDATE;
- }
- break;
-
- case Ctrl('C'):
- if (TagNum) {
- TagNum = 0;
- mode = FULLUPDATE;
- }
- break;
-
- case Ctrl('T'):
- /* XXX duplicated code, copy from case 't' */
- if ((currstat & RMAIL && TagBoard != 0) ||
- (!(currstat & RMAIL) && TagBoard != bid)) {
- if (currstat & RMAIL)
- TagBoard = 0;
- else
- TagBoard = bid;
- TagNum = 0;
- }
- mode = TagThread(currdirect);
- break;
-
- case Ctrl('D'):
- mode = TagPruner(bid);
- break;
-
- case '\n':
- case '\r':
- case 'l':
- case KEY_RIGHT:
- ch = 'r';
- default:
- if( ch == 'h' && currmode & (MODE_DIGEST) )
- break;
- if (ch > 0 && ch <= onekey_size) {
- int (*func)() = rcmdlist[ch - 1].func;
- if(rcmdlist[ch - 1].needitem && locmem->crs_ln == 0)
- break;
- if (func != NULL){
- num = locmem->crs_ln - bottom_line;
-
- if(!rcmdlist[ch - 1].needitem)
- mode = (*func)();
- else if( num > 0 ){
- sprintf(direct,"%s.bottom", currdirect);
- mode= (*func)(num, &headers[locmem->crs_ln-locmem->top_ln],
- direct, locmem->crs_ln - locmem->top_ln);
- }
- else
- mode = (*func)(locmem->crs_ln,
- &headers[locmem->crs_ln - locmem->top_ln],
- currdirect, locmem->crs_ln - locmem->top_ln);
- if(mode == READ_SKIP)
- mode = lastmode;
-
- // ¥H¤U³o´XºØ mode ­n¦A³B²z´å¼Ð
- if(mode == READ_PREV || mode == READ_NEXT ||
- mode == RELATE_PREV || mode == RELATE_FIRST ||
- mode == AUTHOR_NEXT || mode == AUTHOR_PREV ||
- mode == RELATE_NEXT){
- lastmode = mode;
-
- switch(mode){
- case READ_PREV:
- new_ln = locmem->crs_ln - 1;
- break;
- case READ_NEXT:
- new_ln = locmem->crs_ln + 1;
- break;
- case RELATE_PREV:
- new_ln = thread(locmem, RELATE_PREV);
- break;
- case RELATE_NEXT:
- new_ln = thread(locmem, RELATE_NEXT);
- /* XXX: Ū¨ì³Ì«á¤@½g­n¸õ¥X¨Ó */
- if( new_ln == locmem->crs_ln ){
- default_ch = 0;
- return FULLUPDATE;
- }
- break;
- case RELATE_FIRST:
- new_ln = thread(locmem, RELATE_FIRST);
- break;
- case AUTHOR_PREV:
- new_ln = thread(locmem, AUTHOR_PREV);
- break;
- case AUTHOR_NEXT:
- new_ln = thread(locmem, AUTHOR_NEXT);
- break;
- }
- mode = DONOTHING; default_ch = 'r';
- }
- else {
- default_ch = 0;
- lastmode = DONOTHING;
- }
- } //end if (func != NULL)
- } // ch > 0 && ch <= onekey_size
- break;
- } // end switch
- } while (mode == DONOTHING);
- return mode;
-}
-
-// recbase: Åã¥Ü¦ì¸mªº¶}ÀY
-// headers_size:­nÅã¥Ü´X¦æ
-// last_line: ¥þªO .DIR + ¸m©³ ªº¦³®Ä¼Æ¥Ø
-// bottom_line: ¥þªO .DIR (µL¸m©³) ªº¦³®Ä¼Æ¥Ø
-
-// XXX never return -1!
-
-static int
-get_records_and_bottom(char *direct, fileheader_t* headers,
- int recbase, int headers_size, int last_line, int bottom_line)
-{
- // n: ¸m©³°£¥~ªº¥iÅã¥Ü¼Æ¥Ø
- int n = bottom_line - recbase + 1, rv = 0;
-
- if( last_line < 1) // §¹¥þ¨SªF¦è
- return 0;
-
- // ¤£Åã¥Ü¸m©³ªº±¡§Î
- if( n >= headers_size || (currmode & (MODE_SELECT | MODE_DIGEST)) )
- {
- rv = get_records(direct, headers, sizeof(fileheader_t),
- recbase, headers_size);
- return rv > 0 ? rv : 0;
- }
-
- //////// Åã¥Ü¥»¤å+¸m©³: ////////
-
- // Ū¨ú .DIR ¥»¤å
- if (n > 0)
- {
- n = get_records(direct, headers, sizeof(fileheader_t), recbase, n);
- if (n < 0) n = 0;
- rv += n; // rv ¬°¦³®Ä¥»¤å¼Æ
-
- recbase = 1;
- } else {
- // n <= 0
- recbase = 1 + (-n);
- }
-
- // Ū¨ú¸m©³ (ª`·N recbase ¥i¯à¶W¹L bottom_line, ¤]´N¬O¥H¸m©³²Ä n ­Ó¶}©l)
- n = last_line - bottom_line +1 - (recbase-1);
- if (rv + n > headers_size)
- n = headers_size - rv;
-
- if (n > 0) {
- char directbottom[PATHLEN];
- snprintf(directbottom, sizeof(directbottom), "%s.bottom", direct);
- n = get_records(directbottom, headers+rv, sizeof(fileheader_t), recbase, n);
- if (n < 0) n = 0;
- rv += n;
- }
-
- return rv;
-}
-
-void
-i_read(int cmdmode, const char *direct, void (*dotitle) (),
- void (*doentry) (), const onekey_t * rcmdlist, int bidcache)
-{
- keeploc_t *locmem = NULL;
- int recbase = 0, mode;
- int entries = 0;
- char currdirect0[PATHLEN];
- int last_line0 = last_line;
- int bottom_line = 0;
- fileheader_t *headers0 = headers;
- int headers_size0 = headers_size;
-
- strlcpy(currdirect0, currdirect, sizeof(currdirect0));
-#define FHSZ sizeof(fileheader_t)
- /* Ptt: ³oÃä headers ¥i¥H°w¹ï¬ÝªOªº³Ì«á 60 ½g°µ cache */
- headers_size = p_lines;
- headers = (fileheader_t *) calloc(headers_size, FHSZ);
- assert(headers != NULL);
- strlcpy(currdirect, direct, sizeof(currdirect));
- mode = NEWDIRECT;
-
- do {
- /* ¨Ì¾Ú mode Åã¥Ü fileheader */
- setutmpmode(cmdmode);
- switch (mode) {
- case DONOTHING:
- break;
-
- case NEWDIRECT: /* ²Ä¤@¦¸¸ü¤J¦¹¥Ø¿ý */
- case DIRCHANGED:
- if (bidcache > 0 && !(currmode & (MODE_SELECT | MODE_DIGEST))){
- if( (last_line = getbtotal(currbid)) == 0 ){
- setbtotal(currbid);
- setbottomtotal(currbid);
- last_line = getbtotal(currbid);
- }
- bottom_line = last_line;
- last_line += getbottomtotal(currbid);
- }
- else
- bottom_line = last_line = get_num_records(currdirect, FHSZ);
-
- if (mode == NEWDIRECT) {
- int num;
- num = last_line - p_lines + 1;
- locmem = getkeep(currdirect, num < 1 ? 1 : num,
- bottom_line ? bottom_line : last_line);
- if(newdirect_new_ln >= 0)
- {
- locmem->crs_ln = newdirect_new_ln + 1;
- newdirect_new_ln = -1;
- }
- }
- recbase = -1;
- /* no break */
-
- default: // for any unknown keys
- case FULLUPDATE:
- (*dotitle) ();
- /* no break */
-
- case PARTUPDATE:
- if (headers_size != p_lines) {
- headers_size = p_lines;
- headers = (fileheader_t *) realloc(headers, headers_size*FHSZ);
- assert(headers);
- }
-
- /* In general, records won't be reloaded in PARTUPDATE state.
- * But since a board is often changed and cached, it is always
- * reloaded here. */
- if (bidcache > 0 && !(currmode & (MODE_SELECT | MODE_DIGEST))) {
- int rec_num;
- bottom_line = getbtotal(currbid);
- rec_num = bottom_line + getbottomtotal(currbid);
- if (last_line != rec_num) {
- last_line = rec_num;
- recbase = -1;
- }
- }
-
- if (recbase != locmem->top_ln) { //headers reload
- recbase = locmem->top_ln;
- if (recbase > last_line) {
- recbase = last_line - headers_size + 1;
- if (recbase < 1)
- recbase = 1;
- locmem->top_ln = recbase;
- }
- /* XXX if entries return -1 or black-hole */
- entries = get_records_and_bottom(currdirect,
- headers, recbase, headers_size, last_line, bottom_line);
- }
- if (locmem->crs_ln > last_line)
- locmem->crs_ln = last_line;
- move(3, 0);
- clrtobot();
- /* no break */
- case PART_REDRAW:
- move(3, 0);
- if( last_line == 0 )
- outs(" ¨S¦³¤å³¹...");
- else {
- int i;
- for( i = 0; i < entries ; i++ )
- (*doentry) (locmem->top_ln + i, &headers[i]);
- }
- /* no break */
- case READ_REDRAW:
- if(curredit & EDIT_ITEM)
- outmsglr(ANSI_COLOR(44) " ¨p¤H¦¬Âà " ANSI_COLOR(30;47), 10,
- " Ä~Äò? ", 7);
- else if (curredit & EDIT_MAIL)
- outmsglr(MSG_MAILER, MSG_MAILER_LEN, "", 0);
- else
- outmsglr(MSG_POSTER, MSG_POSTER_LEN, "", 0);
- break;
-
- case TITLE_REDRAW:
- (*dotitle) ();
- break;
-
- case HEADERS_RELOAD:
- if (recbase != locmem->top_ln) {
- recbase = locmem->top_ln;
- if (recbase > last_line) {
- recbase = last_line - p_lines + 1;
- if (recbase < 1)
- recbase = 1;
- locmem->top_ln = recbase;
- }
- if(headers_size != p_lines) {
- headers_size = p_lines;
- headers = (fileheader_t *) realloc(headers, headers_size*FHSZ);
- assert(headers);
- }
- /* XXX if entries return -1 */
- entries =
- get_records_and_bottom(currdirect, headers, recbase,
- headers_size, last_line, bottom_line);
- }
- break;
- } //end switch
- mode = i_read_key(rcmdlist, locmem, currbid, bottom_line);
- } while (mode != DOQUIT);
-#undef FHSZ
-
- free(headers);
- last_line = last_line0;
- headers = headers0;
- headers_size = headers_size0;
- strlcpy(currdirect, currdirect0, sizeof(currdirect));
- return;
-}
diff --git a/mbbsd/record.c b/mbbsd/record.c
deleted file mode 100644
index d50df1d9..00000000
--- a/mbbsd/record.c
+++ /dev/null
@@ -1,666 +0,0 @@
-/* $Id$ */
-
-#include "bbs.h"
-
-#undef HAVE_MMAP
-#define BUFSIZE 512
-
-#define safewrite write
-
-int
-get_num_records(const char *fpath, int size)
-{
- struct stat st;
- if (stat(fpath, &st) == -1)
- {
- /* TODO: delete this entry, or mark as read */
- return 0;
- }
- return st.st_size / size;
-}
-
-int
-get_sum_records(const char *fpath, int size)
-{
- struct stat st;
- int ans = 0;
- FILE *fp;
- fileheader_t fhdr;
- char buf[200], *p;
-
- // Ptt : should avoid big loop
- if ((fp = fopen(fpath, "r"))==NULL)
- return -1;
-
- strlcpy(buf, fpath, sizeof(buf));
- p = strrchr(buf, '/');
- assert(p);
- p++;
-
- while (fread(&fhdr, size, 1, fp)==1) {
- strlcpy(p, fhdr.filename, sizeof(buf) - (p - buf));
- 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_keep(const char *fpath, void *rptr, int size, int id, int *fd)
-{
- /* ©M get_record() ¤@¼Ë. ¤£¹LÂÇ¥Ñ *fd, ¥i¨Ï¦P¤@­ÓÀɮפ£­n¤@ª½­«½Æ¶}Ãö */
- if (id >= 1 &&
- (*fd > 0 ||
- ((*fd = open(fpath, O_RDONLY, 0)) > 0))){ // FIXME leak if *fd==0
- if (lseek(*fd, (off_t) (size * (id - 1)), SEEK_SET) != -1) {
- if (read(*fd, rptr, size) == size) {
- return 0;
- }
- }
- }
- return -1;
-}
-
-int
-get_record(const char *fpath, void *rptr, int size, int id)
-{
- int fd = -1;
- /* TODO merge with get_records() */
-
- 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(const 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(const char *fpath, const void *rptr, int size, int id)
-{
- int fd;
- int offset=size * (id - 1);
- if (id < 1 || (fd = open(fpath, O_WRONLY | O_CREAT, 0644)) == -1)
- return -1;
-
- lseek(fd, (off_t) (offset), SEEK_SET);
- PttLock(fd, offset, size, F_WRLCK);
- write(fd, rptr, size);
- PttLock(fd, offset, size, F_UNLCK);
- close(fd);
-
- return 0;
-}
-
-/* return index>0 if thisstamp==stamp[index],
- * return -index<0 if stamp[index-1]<thisstamp<stamp[index+1], XXX thisstamp ?<>? stamp[index]
- * or XXX filename[index]=""
- * return 0 if error
- */
-int
-getindex_m(const char *direct, fileheader_t *fhdr, int end, int isloadmoney)
-{ // Ptt: ±q«e­±§ä«Ü¶O¤O ¤Ó¼É¤O
- int fd = -1, begin = 1, i, s, times, stamp;
- fileheader_t fh;
-
- int n = get_num_records(direct, sizeof(fileheader_t));
- if( end > n || end<=0 )
- end = n;
- stamp = atoi(fhdr->filename + 2);
- for( i = (begin + end ) / 2, times = 0 ;
- end >= begin && times < 20 ; /* ³Ì¦h¥u§ä 20 ¦¸ */
- i = (begin + end ) / 2, ++times ){
- if( get_record_keep(direct, &fh, sizeof(fileheader_t), i, &fd)==-1 ||
- !fh.filename[0] )
- break;
- s = atoi(fh.filename + 2);
- if( s > stamp )
- end = i - 1;
- else if( s == stamp ){
- close(fd);
- if(isloadmoney)
- fhdr->multi.money = fh.multi.money;
- return i;
- }
- else
- begin = i + 1;
- }
-
- if( times < 20) // Not forever loop. It any because of deletion.
- {
- close(fd);
- return -i;
- }
- if( fd != -1 )
- close(fd);
- return 0;
-}
-
-inline int
-getindex(const char *direct, fileheader_t *fhdr, int end)
-{
- return getindex_m(direct, fhdr, end, 0);
-}
-
-int
-substitute_ref_record(const char *direct, fileheader_t * fhdr, int ent)
-{
- fileheader_t hdr;
- char fname[PATHLEN];
- int num = 0;
-
- /* rocker.011018: ¦ê±µ¼Ò¦¡¥Îreference¼W¶i®Ä²v */
- if (!(fhdr->filemode & FILE_BOTTOM) && (fhdr->multi.refer.flag) &&
- (num = fhdr->multi.refer.ref)){
- setdirpath(fname, direct, FN_DIR);
- get_record(fname, &hdr, sizeof(hdr), num);
- if (strcmp(hdr.filename, fhdr->filename)) {
- if((num = getindex_m(fname, fhdr, num, 1))>0) {
- substitute_record(fname, fhdr, sizeof(*fhdr), num);
- }
- }
- else if(num>0) {
- fhdr->multi.money = hdr.multi.money;
- substitute_record(fname, fhdr, sizeof(*fhdr), num);
- }
- fhdr->multi.refer.flag = 1;
- fhdr->multi.refer.ref = num; // Ptt: update now!
- }
- substitute_record(direct, fhdr, sizeof(*fhdr), ent);
- return num;
-}
-
-
-/* rocker.011022: ÁקKlockÀɶ}±Ò®É¤£¥¿±`Â_½u,³y¦¨¥Ã¤[lock */
-#ifndef _BBS_UTIL_C_
-static int
-force_open(const char *fname)
-{
- int fd;
- time4_t expire;
-
- expire = now - 3600; /* lock ¦s¦b¶W¹L¤@­Ó¤p®É´N¬O¦³°ÝÃD! */
-
- if (dasht(fname) < expire)
- return -1;
- unlink(fname);
- fd = open(fname, O_WRONLY | O_TRUNC, 0644);
-
- return fd;
-}
-#endif
-
-/* new/old/lock file processing */
-typedef struct nol_t {
- char newfn[256];
- char oldfn[256];
- char lockfn[256];
-} nol_t;
-
-#ifndef _BBS_UTIL_C_
-static void
-nolfilename(nol_t * n, const char *fpath)
-{
- snprintf(n->newfn, sizeof(n->newfn), "%s.new", fpath);
- snprintf(n->oldfn, sizeof(n->oldfn), "%s.old", fpath);
- snprintf(n->lockfn, sizeof(n->lockfn), "%s.lock", fpath);
-}
-#endif
-
-int
-delete_records(const char *fpath, int size, int id, int num)
-{
- char abuf[BUFSIZE];
- int fi, fo, locksize=0, readsize=0, offset = size * (id - 1), c, d=0;
- struct stat st;
-
-
- if ((fi=open(fpath, O_RDONLY, 0)) == -1)
- return -1;
-
- if ((fo=open(fpath, O_WRONLY, 0)) == -1)
- {
- close(fi);
- return -1;
- }
-
- if(fstat(fi, &st)==-1)
- { close(fo); close(fi); return -1;}
-
- locksize = st.st_size - offset;
- readsize = locksize - size*num;
- if (locksize < 0 )
- { close(fo); close(fi); return -1;}
-
- PttLock(fo, offset, locksize, F_WRLCK);
- if(readsize>0)
- {
- lseek(fi, offset+size, SEEK_SET);
- lseek(fo, offset, SEEK_SET);
- while( d<readsize && (c = read(fi, abuf, BUFSIZE))>0)
- {
- write(fo, abuf, c);
- d=d+c;
- }
- }
- close(fi);
- ftruncate(fo, st.st_size - size*num);
- PttLock(fo, offset, locksize, F_UNLCK);
- close(fo);
- return 0;
-
-}
-
-
-int delete_record(const char *fpath, int size, int id)
-{
- return delete_records(fpath, size, id, 1);
-}
-
-
-#ifndef _BBS_UTIL_C_
-#ifdef SAFE_ARTICLE_DELETE
-void safe_delete_range(const char *fpath, int id1, int id2)
-{
- int fd, i;
- fileheader_t fhdr;
- char fullpath[STRLEN], *t;
- strlcpy(fullpath, fpath, sizeof(fullpath));
- t = strrchr(fullpath, '/');
- assert(t);
- t++;
- if( (fd = open(fpath, O_RDONLY)) == -1 )
- return;
- for( i = 1 ; (read(fd, &fhdr, sizeof(fileheader_t)) ==
- sizeof(fileheader_t)) ; ++i ){
- strcpy(t, fhdr.filename);
- /* rocker.011018: add new tag delete */
- if (!((fhdr.filemode & FILE_MARKED) || /* ¼Ð°O */
- (fhdr.filemode & FILE_DIGEST) || /* ¤åºK */
- (id1 && (i < id1 || i > id2)) || /* range */
- (!id1 && Tagger(atoi(t + 2), i, TAG_NIN)))) /* TagList */
- safe_article_delete(i, &fhdr, fpath);
- }
- close(fd);
-}
-#endif
-
-int
-delete_range(const char *fpath, int id1, int id2)
-{
- fileheader_t fhdr;
- nol_t my;
- char fullpath[STRLEN], *t;
- int fdr, fdw, fd;
- int count, dcount=0;
-
- nolfilename(&my, fpath);
-
- if ((fd = open(my.lockfn, O_RDWR | O_CREAT | O_APPEND, 0644)) == -1)
- return -1;
-
- flock(fd, LOCK_EX);
-
- if ((fdr = open(fpath, O_RDONLY, 0)) == -1) {
- flock(fd, LOCK_UN);
- close(fd);
- return -1;
- }
- if (
- ((fdw = open(my.newfn, O_WRONLY | O_CREAT | O_EXCL, 0644)) == -1) &&
- ((fdw = force_open(my.newfn)) == -1)) {
- close(fdr);
- flock(fd, LOCK_UN);
- close(fd);
- return -1;
- }
- count = 1;
- strlcpy(fullpath, fpath, sizeof(fullpath));
- t = strrchr(fullpath, '/');
- assert(t);
- t++;
-
- while (read(fdr, &fhdr, sizeof(fileheader_t)) == sizeof(fileheader_t)) {
- strcpy(t, fhdr.filename);
-
- /* rocker.011018: add new tag delete */
- if (
- (fhdr.filemode & FILE_MARKED) || /* ¼Ð°O */
- ((fhdr.filemode & FILE_DIGEST) && (currstat != RMAIL) )||
- /* ¤åºK , FILE_DIGEST is used as REPLIED in mail menu.*/
- (id1 && (count < id1 || count > id2)) || /* range */
- (!id1 && Tagger(atoi(t + 2), count, TAG_NIN))) { /* TagList */
- if ((safewrite(fdw, &fhdr, sizeof(fileheader_t)) == -1)) {
- close(fdr);
- close(fdw);
- unlink(my.newfn);
- flock(fd, LOCK_UN);
- close(fd);
- return -1;
- }
- } else {
- //if (dashd(fullpath))
- unlink(fullpath);
- dcount++;
- }
- ++count;
- }
- close(fdr);
- close(fdw);
- if (Rename(fpath, my.oldfn) == -1 || Rename(my.newfn, fpath) == -1) {
- flock(fd, LOCK_UN);
- close(fd);
- return -1;
- }
- flock(fd, LOCK_UN);
- close(fd);
- return dcount;
-}
-#endif
-
-
-#ifdef SAFE_ARTICLE_DELETE
-int
-safe_article_delete(int ent, const fileheader_t *fhdr, const char *direct)
-{
- fileheader_t newfhdr;
- memcpy(&newfhdr, fhdr, sizeof(fileheader_t));
- sprintf(newfhdr.title, "(¥»¤å¤w³Q§R°£)");
- strcpy(newfhdr.filename, ".deleted");
- strcpy(newfhdr.owner, "-");
- substitute_record(direct, &newfhdr, sizeof(newfhdr), ent);
- return 0;
-}
-
-int
-safe_article_delete_range(const char *direct, int from, int to)
-{
- fileheader_t newfhdr;
- int fd;
- char fn[128], *ptr;
-
- strlcpy(fn, direct, sizeof(fn));
- if( (ptr = rindex(fn, '/')) == NULL )
- return 0;
-
- ++ptr;
- if( (fd = open(direct, O_RDWR)) != -1 &&
- lseek(fd, sizeof(fileheader_t) * (from - 1), SEEK_SET) != -1 ){
-
- for( ; from <= to ; ++from ){
- read(fd, &newfhdr, sizeof(fileheader_t));
- if( newfhdr.filemode & (FILE_MARKED | FILE_DIGEST) )
- continue;
- if(newfhdr.filename[0]=='L') newfhdr.filename[0]='M';
- strlcpy(ptr, newfhdr.filename, sizeof(newfhdr.filename));
- unlink(fn);
-
- sprintf(newfhdr.title, "(¥»¤å¤w³Q§R°£)");
- strcpy(newfhdr.filename, ".deleted");
- strcpy(newfhdr.owner, "-");
- // because off_t is unsigned, we could NOT seek backward.
- lseek(fd, sizeof(fileheader_t) * (from - 1), SEEK_SET);
- write(fd, &newfhdr, sizeof(fileheader_t));
- }
- close(fd);
- }
- return 0;
-}
-
-
-#endif
-
-int
-apply_record(const char *fpath, int (*fptr) (void *item, void *optarg), int size, void *arg){
- char abuf[BUFSIZE];
- int fp;
-
- if((fp=open(fpath, O_RDONLY, 0)) == -1)
- return -1;
-
- assert(size<=sizeof(abuf));
- while (read(fp, abuf, size) == (size_t)size)
- if ((*fptr) (abuf, arg) == QUIT) {
- close(fp);
- return QUIT;
- }
- close(fp);
- return 0;
-}
-
-/* mail / post ®É¡A¨Ì¾Ú®É¶¡«Ø¥ßÀɮסA¥[¤W¶lÂW */
-int
-stampfile_u(char *fpath, fileheader_t * fh)
- // Ptt: stampfile_u: won't clear fileheader
- // stampfile: will clear fileheader
-{
- register char *ip = fpath;
- time4_t dtime = COMMON_TIME;
- struct tm *ptime;
-#ifdef _BBS_UTIL_C_
- int fp = 0; //Ptt: don't need to check
- // for utils, the time may be the same between several runs, by scw
-#endif
-
- if (access(fpath, X_OK | R_OK | W_OK))
- mkdir(fpath, 0755);
-
- while (*(++ip));
- *ip++ = '/';
-#ifdef _BBS_UTIL_C_
- do {
-#endif
- sprintf(ip, "M.%d.A.%3.3X", (int)(++dtime), (unsigned int)(random() & 0xFFF));
-#ifdef _BBS_UTIL_C_
- if (fp == -1 && errno != EEXIST)
- return -1;
- } while ((fp = open(fpath, O_CREAT | O_EXCL | O_WRONLY, 0644)) == -1);
- close(fp);
-#endif
- strlcpy(fh->filename, ip, sizeof(fh->filename));
- ptime = localtime4(&dtime);
- snprintf(fh->date, sizeof(fh->date),
- "%2d/%02d", ptime->tm_mon + 1, ptime->tm_mday);
- return 0;
-}
-
-inline int
-stampfile(char *fpath, fileheader_t * fh)
-{
- memset(fh, 0, sizeof(fileheader_t));
- return stampfile_u(fpath, fh);
-}
-
-void
-stampdir(char *fpath, fileheader_t * fh)
-{
- register char *ip = fpath;
- time4_t dtime = COMMON_TIME;
- struct tm *ptime;
-
- if (access(fpath, X_OK | R_OK | W_OK))
- mkdir(fpath, 0755);
-
- while (*(++ip));
- *ip++ = '/';
- do {
- sprintf(ip, "D%X", (int)++dtime & 07777);
- } while (mkdir(fpath, 0755) == -1);
- memset(fh, 0, sizeof(fileheader_t));
- strlcpy(fh->filename, ip, sizeof(fh->filename));
- ptime = localtime4(&dtime);
- snprintf(fh->date, sizeof(fh->date),
- "%2d/%02d", ptime->tm_mon + 1, ptime->tm_mday);
-}
-
-void
-stamplink(char *fpath, fileheader_t * fh)
-{
- register char *ip = fpath;
- time4_t dtime = COMMON_TIME;
- struct tm *ptime;
-
- if (access(fpath, X_OK | R_OK | W_OK))
- mkdir(fpath, 0755);
-
- while (*(++ip));
- *ip++ = '/';
- do {
- sprintf(ip, "S%X", (int)++dtime);
- } while (symlink("temp", fpath) == -1);
- memset(fh, 0, sizeof(fileheader_t));
- strlcpy(fh->filename, ip, sizeof(fh->filename));
- ptime = localtime4(&dtime);
- snprintf(fh->date, sizeof(fh->date),
- "%2d/%02d", ptime->tm_mon + 1, ptime->tm_mday);
-}
-
-int
-append_record(const char *fpath, const fileheader_t * record, int size)
-{
- int fd, fsize=0, index;
- struct stat st;
-
- if ((fd = open(fpath, O_WRONLY | O_CREAT, 0644)) == -1) {
- char buf[STRLEN];
- assert(errno != EISDIR);
- sprintf(buf, "id(%s), open(%s)", cuser.userid, fpath);
- perror(buf);
- return -1;
- }
- flock(fd, LOCK_EX);
-
- if(fstat(fd, &st)!=-1)
- fsize = st.st_size;
-
- index = fsize / size;
- lseek(fd, index * size, SEEK_SET); // avoid offset
-
- safewrite(fd, record, size);
-
- flock(fd, LOCK_UN);
- close(fd);
- return index + 1;
-}
-
-int
-append_record_forward(char *fpath, fileheader_t * record, int size, const char *origid)
-{
-#if !defined(_BBS_UTIL_C_)
- if (get_num_records(fpath, sizeof(fileheader_t)) <= MAX_KEEPMAIL * 2) {
- FILE *fp;
- char buf[512];
- int n;
-
- for (n = strlen(fpath) - 1; fpath[n] != '/' && n > 0; n--);
- if (n + sizeof(".forward") > sizeof(buf))
- return -1;
- memcpy(buf, fpath, n+1);
- strcpy(buf + n + 1, ".forward");
- if ((fp = fopen(buf, "r"))) {
-
- char address[64];
- int flIdiotSent2Self = 0;
- int oidlen = origid ? strlen(origid) : 0;
-
- address[0] = 0;
- fscanf(fp, "%63s", address);
- fclose(fp);
- /* some idiots just set forwarding to themselves.
- * and even after we checked "sameid", some still
- * set STUPID_ID.bbs@host <- "¦Û¥H¬°Áo©ú"
- * damn it, we have a complex rule now.
- */
- if(oidlen > 0) {
- if (strncasecmp(address, origid, oidlen) == 0)
- {
- int addrlen = strlen(address);
- if( addrlen == oidlen ||
- (addrlen > oidlen &&
- strcasecmp(address + oidlen, str_mail_address) == 0))
- flIdiotSent2Self = 1;
- }
- }
-
- if (buf[0] && buf[0] != ' ' && !flIdiotSent2Self) {
- buf[n + 1] = 0;
- strcat(buf, record->filename);
- append_record(fpath, record, size);
-#ifndef USE_BSMTP
- bbs_sendmail(buf, record->title, address);
-#else
- bsmtp(buf, record->title, address);
-#endif
- return 0;
- }
- }
- }
-#endif
-
- append_record(fpath, record, size);
-
- return 0;
-}
-
-#ifndef _BBS_UTIL_C_
-void
-setaidfile(char *buf, const char *bn, aidu_t aidu)
-{
- // try to load by AID
- int bid = 0;
- int n = 0, fd = 0;
- char bfpath[PATHLEN] = "";
- boardheader_t *bh = NULL;
- fileheader_t fh;
-
- buf[0] = 0;
- bid = getbnum(bn);
-
- if (bid <= 0) return;
- assert(0<=bid-1 && bid-1<MAX_BOARD);
- bh = getbcache(bid);
- if (!HasBoardPerm(bh)) return;
-
- setbfile(bfpath, bh->brdname, FN_DIR);
- n = search_aidu(bfpath, aidu);
-
- if (n < 0) return;
- fd = open(bfpath, O_RDONLY);
- if (fd < 0) return;
-
- lseek(fd, n*sizeof(fileheader_t), SEEK_SET);
- memset(&fh, 0, sizeof(fh));
- if (read(fd, &fh, sizeof(fh)) > 0)
- {
- setbfile(buf, bh->brdname, fh.filename);
- if (!dashf(buf))
- buf[0] = 0;
- }
- close(fd);
-}
-#endif
diff --git a/mbbsd/register.c b/mbbsd/register.c
deleted file mode 100644
index e0db7d37..00000000
--- a/mbbsd/register.c
+++ /dev/null
@@ -1,3040 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-#define FN_REGISTER_LOG "register.log" // global registration history
-#define FN_JUSTIFY "justify"
-#define FN_JUSTIFY_WAIT "justify.wait"
-#define FN_REJECT_NOTIFY "justify.reject"
-
-// New style (Regform2) file names:
-#define FN_REGFORM "regform" // registration form in user home
-#define FN_REGFORM_LOG "regform.log" // regform history in user home
-#define FN_REQLIST "reg.wait" // request list file, in global directory (replacing fn_register)
-
-////////////////////////////////////////////////////////////////////////////
-// Password Hash
-////////////////////////////////////////////////////////////////////////////
-
-// prototype of crypt()
-char *crypt(const char *key, const char *salt);
-
-char *
-genpasswd(char *pw)
-{
- if (pw[0]) {
- char saltc[2], c;
- int i;
-
- i = 9 * getpid();
- saltc[0] = i & 077;
- saltc[1] = (i >> 6) & 077;
-
- for (i = 0; i < 2; i++) {
- c = saltc[i] + '.';
- if (c > '9')
- c += 7;
- if (c > 'Z')
- c += 6;
- saltc[i] = c;
- }
- return crypt(pw, saltc);
- }
- return "";
-}
-
-// NOTE it will clean string in "plain"
-int
-checkpasswd(const char *passwd, char *plain)
-{
- int ok;
- char *pw;
-
- ok = 0;
- pw = crypt(plain, passwd);
- if(pw && strcmp(pw, passwd)==0)
- ok = 1;
- memset(plain, 0, strlen(plain));
-
- return ok;
-}
-
-////////////////////////////////////////////////////////////////////////////
-// Value Validation
-////////////////////////////////////////////////////////////////////////////
-static int
-HaveRejectStr(const char *s, const char **rej)
-{
- int i;
- char *ptr, *rejectstr[] =
- {"·F", "ªü", "¤£", "§A¶ý", "¬Y", "²Â", "§b", "..", "xx",
- "§AºÞ", "ºÞ§Ú", "²q", "¤Ñ¤~", "¶W¤H",
- "£t", "£u", "£v", "£w", "£x", "£y", "£z", "£{", "£|", "£}", "£~",
- "£¡", "£¢", "££", "£¤",/*"£¥",*/ "£¦", "£§", "£¨", "£©", "£ª",
- "£¸", "£¹", "£º", "£«", "£¬", "£­", "£®", "£¯", "£°", "£±", "£²",
- "£³", "£´", "£µ", "£¶", "£·", NULL};
-
- if( rej != NULL )
- for( i = 0 ; rej[i] != NULL ; ++i )
- if( strstr(s, rej[i]) )
- return 1;
-
- for( i = 0 ; rejectstr[i] != NULL ; ++i )
- if( strstr(s, rejectstr[i]) )
- return 1;
-
- if( (ptr = strstr(s, "£¥")) != NULL ){
- if( ptr != s && strncmp(ptr - 1, "³£¥«", 4) == 0 )
- return 0;
- return 1;
- }
- return 0;
-}
-
-static int
-removespace(char *s)
-{
- int i, index;
-
- for (i = 0, index = 0; s[i]; i++) {
- if (s[i] != ' ')
- s[index++] = s[i];
- }
- s[index] = '\0';
- return index;
-}
-
-int
-bad_user_id(const char *userid)
-{
- if(!is_validuserid(userid))
- return 1;
-
- if (strcasecmp(userid, str_new) == 0)
- return 1;
-
-#ifdef NO_GUEST_ACCOUNT_REG
- if (strcasecmp(userid, STR_GUEST) == 0)
- return 1;
-#endif
-
- /* in2: ­ì¥»¬O¥Îstrcasestr,
- ¤£¹L¦³¨Ç¤H¤¤¶¡­è­è¦n¥X²{³o­Ó¦rÀ³¸ÓÁÙºâ¦X²z§a? */
- if( strncasecmp(userid, "fuck", 4) == 0 ||
- strncasecmp(userid, "shit", 4) == 0 )
- return 1;
-
- /*
- * while((ch = *(++userid))) if(not_alnum(ch)) return 1;
- */
- return 0;
-}
-
-static char *
-isvalidname(char *rname)
-{
-#ifdef FOREIGN_REG
- return NULL;
-#else
- const char *rejectstr[] =
- {"ªÎ", "­D", "½ÞÀY", "¤p¥Õ", "¤p©ú", "¸ô¤H", "¦Ñ¤ý", "¦Ñ§õ", "Ä_¨©",
- "¥ý¥Í", "«Ó­ô", "¦ÑÀY", "¤p©n", "¤p©j", "¬ü¤k", "¤p©f", "¤jÀY",
- "¤½¥D", "¦P¾Ç", "Ä_Ä_", "¤½¤l", "¤jÀY", "¤p¤p", "¤p§Ì", "¤p©f",
- "©f©f", "¼K", "¶â", "·Ý·Ý", "¤j­ô", "µL",
- NULL};
- if( removespace(rname) && rname[0] < 0 &&
- strlen(rname) >= 4 &&
- !HaveRejectStr(rname, rejectstr) &&
- strncmp(rname, "¤p", 2) != 0 && //°_ÀY¬O¡u¤p¡v
- strncmp(rname, "§Ú¬O", 4) != 0 && //°_ÀY¬O¡u§Ú¬O¡v
- !(strlen(rname) == 4 && strncmp(&rname[2], "¨à", 2) == 0) &&
- !(strlen(rname) >= 4 && strncmp(&rname[0], &rname[2], 2) == 0))
- return NULL;
- return "±zªº¿é¤J¤£¥¿½T";
-#endif
-
-}
-
-static char *
-isvalidcareer(char *career)
-{
-#ifndef FOREIGN_REG
- const char *rejectstr[] = {NULL};
- if (!(removespace(career) && career[0] < 0 && strlen(career) >= 6) ||
- strcmp(career, "®a¸Ì") == 0 || HaveRejectStr(career, rejectstr) )
- return "±zªº¿é¤J¤£¥¿½T";
- if (strcmp(&career[strlen(career) - 2], "¤j") == 0 ||
- strcmp(&career[strlen(career) - 4], "¤j¾Ç") == 0 ||
- strcmp(career, "¾Ç¥Í¤j¾Ç") == 0)
- return "³Â·Ð½Ð¥[¾Ç®Õ¨t©Ò";
- if (strcmp(career, "¾Ç¥Í°ª¤¤") == 0)
- return "³Â·Ð¿é¤J¾Ç®Õ¦WºÙ";
-#else
- if( strlen(career) < 6 )
- return "±zªº¿é¤J¤£¥¿½T";
-#endif
- return NULL;
-}
-
-static char *
-isvalidaddr(char *addr)
-{
- const char *rejectstr[] =
- {"¦a²y", "»Èªe", "¤õ¬P", NULL};
-
- // addr[0] > 0: check if address is starting by Chinese.
- if (!removespace(addr) || strlen(addr) < 15)
- return "³o­Ó¦a§}¦ü¥G¨Ã¤£§¹¾ã";
- if (strstr(addr, "«H½c") != NULL || strstr(addr, "¶l¬F") != NULL)
- return "©êºp§Ú­Ì¤£±µ¨ü¶l¬F«H½c";
- if ((strstr(addr, "¥«") == NULL && strstr(addr, "É]") == NULL &&
- strstr(addr, "¿¤") == NULL && strstr(addr, "«Ç") == NULL) ||
- HaveRejectStr(addr, rejectstr) ||
- strcmp(&addr[strlen(addr) - 2], "¬q") == 0 ||
- strcmp(&addr[strlen(addr) - 2], "¸ô") == 0 ||
- strcmp(&addr[strlen(addr) - 2], "«Ñ") == 0 ||
- strcmp(&addr[strlen(addr) - 2], "§Ë") == 0 ||
- strcmp(&addr[strlen(addr) - 2], "°Ï") == 0 ||
- strcmp(&addr[strlen(addr) - 2], "¥«") == 0 ||
- strcmp(&addr[strlen(addr) - 2], "µó") == 0 )
- return "³o­Ó¦a§}¦ü¥G¨Ã¤£§¹¾ã";
- return NULL;
-}
-
-static char *
-isvalidphone(char *phone)
-{
- int i;
- for( i = 0 ; phone[i] != 0 ; ++i )
- if( !isdigit((int)phone[i]) )
- return "½Ð¤£­n¥[¤À¹j²Å¸¹";
- if (!removespace(phone) ||
- strlen(phone) < 9 ||
- strstr(phone, "00000000") != NULL ||
- strstr(phone, "22222222") != NULL ) {
- return "³o­Ó¹q¸Ü¸¹½X¨Ã¤£¥¿½T(½Ð§t°Ï½X)" ;
- }
- return NULL;
-}
-
-
-////////////////////////////////////////////////////////////////////////////
-// Account Expiring
-////////////////////////////////////////////////////////////////////////////
-
-/* -------------------------------- */
-/* New policy for allocate new user */
-/* (a) is the worst user currently */
-/* (b) is the object to be compared */
-/* -------------------------------- */
-static int
-compute_user_value(const userec_t * urec, time4_t clock)
-{
- int value;
-
- /* if (urec) has XEMPT permission, don't kick it */
- if ((urec->userid[0] == '\0') || (urec->userlevel & PERM_XEMPT)
- /* || (urec->userlevel & PERM_LOGINOK) */
- || !strcmp(STR_GUEST, urec->userid))
- return 999999;
- value = (clock - urec->lastlogin) / 60; /* minutes */
-
- /* new user should register in 30 mins */
- // XXX ¥Ø«e new acccount ¨Ã¤£·|¦b utmp ¸Ì©ñ str_new...
- if (strcmp(urec->userid, str_new) == 0)
- return 30 - value;
-
-#if 0
- if (!urec->numlogins) /* ¥¼ login ¦¨¥\ªÌ¡A¤£«O¯d */
- return -1;
- if (urec->numlogins <= 3) /* #login ¤Ö©ó¤TªÌ¡A«O¯d 20 ¤Ñ */
- return 20 * 24 * 60 - value;
-#endif
- /* ¥¼§¹¦¨µù¥UªÌ¡A«O¯d 15 ¤Ñ */
- /* ¤@¯ë±¡ªp¡A«O¯d 120 ¤Ñ */
- return (urec->userlevel & PERM_LOGINOK ? 120 : 15) * 24 * 60 - value;
-}
-
-int
-check_and_expire_account(int uid, const userec_t * urec, int expireRange)
-{
- char genbuf[200];
- int val;
- if ((val = compute_user_value(urec, now)) < 0) {
- snprintf(genbuf, sizeof(genbuf), "#%d %-12s %15.15s %d %d %d",
- uid, urec->userid, ctime4(&(urec->lastlogin)) + 4,
- urec->numlogins, urec->numposts, val);
-
- // ­Y¶W¹L expireRange «h¬å¤H¡A
- // ¤£µM´N return 0
- if (-val > expireRange)
- {
- log_usies("DATED", genbuf);
- // log_usies("CLEAN", genbuf);
- kill_user(uid, urec->userid);
- } else val = 0;
- }
- return val;
-}
-
-////////////////////////////////////////////////////////////////////////////
-// Regcode Support
-////////////////////////////////////////////////////////////////////////////
-
-#define REGCODE_INITIAL "v6" // always 2 characters
-
-static char *
-getregfile(char *buf)
-{
- // not in user's home because s/he could zip his/her home
- snprintf(buf, PATHLEN, "jobspool/.regcode.%s", cuser.userid);
- return buf;
-}
-
-static char *
-makeregcode(char *buf)
-{
- char fpath[PATHLEN];
- int fd, i;
- // prevent ambigious characters: oOlI
- const char *alphabet = "qwertyuipasdfghjkzxcvbnmoQWERTYUPASDFGHJKLZXCVBNM";
-
- /* generate a new regcode */
- buf[13] = 0;
- buf[0] = REGCODE_INITIAL[0];
- buf[1] = REGCODE_INITIAL[1];
- for( i = 2 ; i < 13 ; ++i )
- buf[i] = alphabet[random() % strlen(alphabet)];
-
- getregfile(fpath);
- if( (fd = open(fpath, O_WRONLY | O_CREAT, 0600)) == -1 ){
- perror("open");
- exit(1);
- }
- write(fd, buf, 13);
- close(fd);
-
- return buf;
-}
-
-static char *
-getregcode(char *buf)
-{
- int fd;
- char fpath[PATHLEN];
-
- getregfile(fpath);
- if( (fd = open(fpath, O_RDONLY)) == -1 ){
- buf[0] = 0;
- return buf;
- }
- read(fd, buf, 13);
- close(fd);
- buf[13] = 0;
- return buf;
-}
-
-void
-delregcodefile(void)
-{
- char fpath[PATHLEN];
- getregfile(fpath);
- unlink(fpath);
-}
-
-////////////////////////////////////////////////////////////////////////////
-// Justify Utilities
-////////////////////////////////////////////////////////////////////////////
-
-static void
-justify_wait(char *userid, char *phone, char *career,
- char *rname, char *addr, char *mobile)
-{
- char buf[PATHLEN];
- sethomefile(buf, userid, FN_JUSTIFY_WAIT);
- if (phone[0] != 0) {
- FILE* fn = fopen(buf, "w");
- assert(fn);
- fprintf(fn, "%s\n%s\ndummy\n%s\n%s\n%s\n",
- phone, career, rname, addr, mobile);
- fclose(fn);
- }
-}
-
-static void
-email_justify(const userec_t *muser)
-{
- char tmp[IDLEN + 1], buf[256], genbuf[256];
- /*
- * It is intended to use BBSENAME instead of BBSNAME here.
- * Because recently many poor users with poor mail clients
- * (or evil mail servers) cannot handle/decode Chinese
- * subjects (BBSNAME) correctly, so we'd like to use
- * BBSENAME here to prevent subject being messed up.
- * And please keep BBSENAME short or it may be truncated
- * by evil mail servers.
- */
- snprintf(buf, sizeof(buf),
- " " BBSENAME " - [ %s ]", makeregcode(genbuf));
-
- strlcpy(tmp, cuser.userid, sizeof(tmp));
- // XXX dirty, set userid=SYSOP
- strlcpy(cuser.userid, str_sysop, sizeof(cuser.userid));
-#ifdef HAVEMOBILE
- if (strcmp(muser->email, "m") == 0 || strcmp(muser->email, "M") == 0)
- mobile_message(mobile, buf);
- else
-#endif
- bsmtp("etc/registermail", buf, muser->email);
- strlcpy(cuser.userid, tmp, sizeof(cuser.userid));
- move(20,0);
- clrtobot();
- outs("§Ú­Ì§Y±N±H¥X»{ÃÒ«H (±zÀ³¸Ó·|¦b 10 ¤ÀÄÁ¤º¦¬¨ì)\n"
- "¦¬¨ì«á±z¥i¥H®Ú¾Ú»{ÃÒ«H¼ÐÃDªº»{ÃÒ½X\n"
- "¿é¤J¨ì (U)ser -> (R)egister «á´N¥i¥H§¹¦¨µù¥U");
- pressanykey();
- return;
-}
-
-
-/* ¨Ï¥ÎªÌ¶ñ¼gµù¥Uªí®æ */
-static void
-getfield(int line, const char *info, const char *desc, char *buf, int len)
-{
- char prompt[STRLEN];
- char genbuf[200];
-
- // clear first
- move(line+1, 0); clrtoeol();
- move(line, 0); clrtoeol();
- prints(" ­ì¥ý³]©w¡G%-30.30s (%s)", buf, info);
- snprintf(prompt, sizeof(prompt), " %s¡G", desc);
- if (getdata_str(line + 1, 0, prompt, genbuf, len, DOECHO, buf))
- strcpy(buf, genbuf);
- move(line+1, 0); clrtoeol();
- move(line, 0); clrtoeol();
- prints(" %s¡G%s", desc, buf);
-}
-
-
-int
-setupnewuser(const userec_t *user)
-{
- char genbuf[50];
- char *fn_fresh = ".fresh";
- userec_t utmp;
- time_t clock;
- struct stat st;
- int fd, uid;
-
- clock = now;
-
- // XXX race condition...
- if (dosearchuser(user->userid, NULL))
- {
- vmsg("¤â¸}¤£°÷§Ö¡A§O¤H¤w¸g·m¨«¤F¡I");
- exit(1);
- }
-
- /* Lazy method : ¥ý§ä´M¤w¸g²M°£ªº¹L´Á±b¸¹ */
- if ((uid = dosearchuser("", NULL)) == 0) {
- /* ¨C 1 ­Ó¤p®É¡A²M²z user ±b¸¹¤@¦¸ */
- if ((stat(fn_fresh, &st) == -1) || (st.st_mtime < clock - 3600)) {
- if ((fd = open(fn_fresh, O_RDWR | O_CREAT, 0600)) == -1)
- return -1;
- write(fd, ctime(&clock), 25);
- close(fd);
- log_usies("CLEAN", "dated users");
-
- fprintf(stdout, "´M§ä·s±b¸¹¤¤, ½Ðµy«Ý¤ù¨è...\n\r");
-
- if ((fd = open(fn_passwd, O_RDWR | O_CREAT, 0600)) == -1)
- return -1;
-
- /* ¤£¾å±o¬°¤°»ò­n±q 2 ¶}©l... Ptt:¦]¬°SYSOP¦b1 */
- for (uid = 2; uid <= MAX_USERS; uid++) {
- passwd_query(uid, &utmp);
- // tolerate for one year.
- check_and_expire_account(uid, &utmp, 365*12*60);
- }
- }
- }
-
- /* initialize passwd semaphores */
- if (passwd_init())
- exit(1);
-
- passwd_lock();
-
- uid = dosearchuser("", NULL);
- if ((uid <= 0) || (uid > MAX_USERS)) {
- passwd_unlock();
- vmsg("©êºp¡A¨Ï¥ÎªÌ±b¸¹¤w¸gº¡¤F¡AµLªkµù¥U·sªº±b¸¹");
- exit(1);
- }
-
- setuserid(uid, user->userid);
- snprintf(genbuf, sizeof(genbuf), "uid %d", uid);
- log_usies("APPLY", genbuf);
-
- SHM->money[uid - 1] = user->money;
-
- if (passwd_update(uid, (userec_t *)user) == -1) {
- passwd_unlock();
- vmsg("«Èº¡¤F¡A¦A¨£¡I");
- exit(1);
- }
-
- passwd_unlock();
-
- return uid;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// New Registration (Phase 1)
-/////////////////////////////////////////////////////////////////////////////
-
-void
-new_register(void)
-{
- userec_t newuser;
- char passbuf[STRLEN];
- int try, id, uid;
- char *errmsg = NULL;
-
-#ifdef HAVE_USERAGREEMENT
- more(HAVE_USERAGREEMENT, YEA);
- while( 1 ){
- getdata(b_lines, 0, "½Ð°Ý±z±µ¨ü³o¥÷¨Ï¥ÎªÌ±ø´Ú¶Ü? (yes/no) ",
- passbuf, 4, LCECHO);
- if( passbuf[0] == 'y' )
- break;
- if( passbuf[0] == 'n' ){
- vmsg("©êºp, ±z¶·­n±µ¨ü¨Ï¥ÎªÌ±ø´Ú¤~¯àµù¥U±b¸¹¨É¨ü§Ú­ÌªºªA°È­ò!");
- exit(1);
- }
- vmsg("½Ð¿é¤J yªí¥Ü±µ¨ü, nªí¥Ü¤£±µ¨ü");
- }
-#endif
-
- // setup newuser
- memset(&newuser, 0, sizeof(newuser));
- newuser.version = PASSWD_VERSION;
- newuser.userlevel = PERM_DEFAULT;
- newuser.uflag = BRDSORT_FLAG | MOVIE_FLAG;
- newuser.uflag2 = 0;
- newuser.firstlogin = newuser.lastlogin = now;
- newuser.money = 0;
- newuser.pager = PAGER_ON;
- strlcpy(newuser.lasthost, fromhost, sizeof(newuser.lasthost));
-
-#ifdef DBCSAWARE
- if(u_detectDBCSAwareEvilClient())
- newuser.uflag &= ~DBCSAWARE_FLAG;
- else
- newuser.uflag |= DBCSAWARE_FLAG;
-#endif
-
- more("etc/register", NA);
- try = 0;
- while (1) {
- userec_t xuser;
- int minute;
-
- if (++try >= 6) {
- vmsg("±z¹Á¸Õ¿ù»~ªº¿é¤J¤Ó¦h¡A½Ð¤U¦¸¦A¨Ó§a");
- exit(1);
- }
- getdata(17, 0, msg_uid, newuser.userid,
- sizeof(newuser.userid), DOECHO);
- strcpy(passbuf, newuser.userid);
-
- if (bad_user_id(passbuf))
- outs("µLªk±µ¨ü³o­Ó¥N¸¹¡A½Ð¨Ï¥Î­^¤å¦r¥À¡A¨Ã¥B¤£­n¥]§tªÅ®æ\n");
- else if ((id = getuser(passbuf, &xuser)) &&
- // >=: see check_and_expire_account definition
- (minute = check_and_expire_account(id, &xuser, 0)) >= 0)
- {
- if (minute == 999999) // XXX magic number. It should be greater than MAX_USERS at least.
- outs("¦¹¥N¸¹¤w¸g¦³¤H¨Ï¥Î ¬O¤£¦º¤§¨­");
- else {
- prints("¦¹¥N¸¹¤w¸g¦³¤H¨Ï¥Î ÁÙ¦³ %d ¤Ñ¤~¹L´Á \n",
- minute / (60 * 24) + 1);
- }
- } else
- break;
- }
-
- // XXX °O±o³Ì«á create account «eÁÙ­n¦AÀˬd¤@¦¸ acc
-
- try = 0;
- while (1) {
- if (++try >= 6) {
- vmsg("±z¹Á¸Õ¿ù»~ªº¿é¤J¤Ó¦h¡A½Ð¤U¦¸¦A¨Ó§a");
- exit(1);
- }
- move(19, 0); clrtoeol();
- outs(ANSI_COLOR(1;33)
- "¬°ÁקK³Q°½¬Ý¡A±zªº±K½X¨Ã¤£·|Åã¥Ü¦bµe­±¤W¡Aª½±µ¿é¤J§¹«á«ö Enter Áä§Y¥i¡C\n"
- "¥t¥~½Ðª`·N±K½X¥u¦³«e¤K­Ó¦r¤¸¦³®Ä¡A¶W¹Lªº±N¦Û°Ê©¿²¤¡C"
- ANSI_RESET);
- if ((getdata(18, 0, "½Ð³]©w±K½X¡G", passbuf,
- sizeof(passbuf), NOECHO) < 3) ||
- !strcmp(passbuf, newuser.userid)) {
- outs("±K½X¤Ó²³æ¡A©ö¾D¤J«I¡A¦Ü¤Ö­n 4 ­Ó¦r¡A½Ð­«·s¿é¤J\n");
- continue;
- }
- strlcpy(newuser.passwd, passbuf, PASSLEN);
- getdata(19, 0, "½ÐÀˬd±K½X¡G", passbuf, sizeof(passbuf), NOECHO);
- if (strncmp(passbuf, newuser.passwd, PASSLEN)) {
- outs("±K½X¿é¤J¿ù»~, ½Ð­«·s¿é¤J±K½X.\n");
- continue;
- }
- passbuf[8] = '\0';
- strlcpy(newuser.passwd, genpasswd(passbuf), PASSLEN);
- break;
- }
- // set-up more information.
-
- // warning: because currutmp=NULL, we can simply pass newuser.* to getdata.
- // DON'T DO THIS IF YOUR currutmp != NULL.
- try = 0;
- while (strlen(newuser.nickname) < 2)
- {
- if (++try > 10) {
- vmsg("±z¹Á¸Õ¿ù»~ªº¿é¤J¤Ó¦h¡A½Ð¤U¦¸¦A¨Ó§a");
- exit(1);
- }
- getdata(19, 0, "ºï¸¹¼ÊºÙ¡G", newuser.nickname,
- sizeof(newuser.nickname), DOECHO);
- }
-
- try = 0;
- while (strlen(newuser.realname) < 4)
- {
- if (++try > 10) {
- vmsg("±z¹Á¸Õ¿ù»~ªº¿é¤J¤Ó¦h¡A½Ð¤U¦¸¦A¨Ó§a");
- exit(1);
- }
- getdata(20, 0, "¯u¹ê©m¦W¡G", newuser.realname,
- sizeof(newuser.realname), DOECHO);
-
- if ((errmsg = isvalidname(newuser.realname)))
- {
- memset(newuser.realname, 0, sizeof(newuser.realname));
- vmsg(errmsg);
- }
- }
-
- try = 0;
- while (strlen(newuser.address) < 8)
- {
- // do not use isvalidaddr to check,
- // because that requires foreign info.
- if (++try > 10) {
- vmsg("±z¹Á¸Õ¿ù»~ªº¿é¤J¤Ó¦h¡A½Ð¤U¦¸¦A¨Ó§a");
- exit(1);
- }
- getdata(21, 0, "Ápµ¸¦a§}¡G", newuser.address,
- sizeof(newuser.address), DOECHO);
- }
-
- try = 0;
- while (newuser.year < 40) // magic number 40: see user.c
- {
- char birthday[sizeof("mmmm/yy/dd ")];
- int y, m, d;
-
- if (++try > 20) {
- vmsg("±z¹Á¸Õ¿ù»~ªº¿é¤J¤Ó¦h¡A½Ð¤U¦¸¦A¨Ó§a");
- exit(1);
- }
- getdata(22, 0, "¥Í¤é (¦è¤¸¦~/¤ë/¤é, ¦p 1984/02/29)¡G", birthday,
- sizeof(birthday), DOECHO);
-
- if (ParseDate(birthday, &y, &m, &d)) {
- vmsg("¤é´Á®æ¦¡¤£¥¿½T");
- continue;
- } else if (y < 1940) {
- vmsg("§A¯uªº¦³¨º»ò¦Ñ¶Ü¡H");
- continue;
- }
- newuser.year = (unsigned char)(y-1900);
- newuser.month = (unsigned char)m;
- newuser.day = (unsigned char)d;
- }
-
- setupnewuser(&newuser);
-
- if( (uid = initcuser(newuser.userid)) < 0) {
- vmsg("µLªk«Ø¥ß±b¸¹");
- exit(1);
- }
- log_usies("REGISTER", fromhost);
-}
-
-void
-check_birthday(void)
-{
- // check birthday
- int changed = 0;
- time_t t = (time_t)now;
- struct tm tm;
-
- localtime_r(&t, &tm);
- while ( cuser.year < 40 || // magic number 40: see user.c
- cuser.year+3 > tm.tm_year)
- {
- char birthday[sizeof("mmmm/yy/dd ")];
- int y, m, d;
-
- clear();
- stand_title("¿é¤J¥Í¤é");
- move(2,0);
- outs("¥»¯¸¬°°t¦X¹ê¦æ¤º®e¤À¯Å¨î«×¡A½Ð±z¿é¤J¥¿½Tªº¥Í¤é¸ê°T¡C");
-
- getdata(5, 0, "¥Í¤é (¦è¤¸¦~/¤ë/¤é, ¦p 1984/02/29)¡G", birthday,
- sizeof(birthday), DOECHO);
-
- if (ParseDate(birthday, &y, &m, &d)) {
- vmsg("¤é´Á®æ¦¡¤£¥¿½T");
- continue;
- } else if (y < 1940) {
- vmsg("§A¯uªº¦³¨º»ò¦Ñ¶Ü¡H");
- continue;
- } else if (y+3 > tm.tm_year+1900) {
- vmsg("À¦¨à/¥¼¥X¥ÍÀ³¸ÓµLªk¨Ï¥Î BBS...");
- continue;
- }
- cuser.year = (unsigned char)(y-1900);
- cuser.month = (unsigned char)m;
- cuser.day = (unsigned char)d;
- changed = 1;
- }
-
- if (changed) {
- clear();
- resolve_over18();
- }
-}
-
-void
-check_register(void)
-{
- char fn[PATHLEN];
-
- check_birthday();
-
- if (HasUserPerm(PERM_LOGINOK))
- return;
-
- setuserfile(fn, FN_REJECT_NOTIFY);
-
- /*
- * ÁקK¨Ï¥ÎªÌ³Q°h¦^µù¥U³æ«á¡A¦bª¾¹D°h¦^ªº­ì¦]¤§«e¡A
- * ¤S°e¥X¤@¦¸µù¥U³æ¡C
- */
- if (dashf(fn))
- {
- more(fn, NA);
- move(b_lines-3, 0);
- outs("¤W¦¸µù¥U³æ¼f¬d¥¢±Ñ¡C\n"
- "½Ð­«·s¥Ó½Ð¨Ã·Ó¤W­±«ü¥Ü¥¿½T¶ñ¼gµù¥U³æ¡C");
- while(getans("½Ð¿é¤J y Ä~Äò: ") != 'y');
- unlink(fn);
- } else
- if (ISNEWMAIL(currutmp))
- m_read();
-
- if (!HasUserPerm(PERM_SYSOP)) {
- /* ¦^ÂйL¨­¥÷»{ÃÒ«H¨ç¡A©Î´¿¸g E-mail post ¹L */
- clear();
- move(9, 3);
- outs("½Ð¸Ô¶ñ¼g" ANSI_COLOR(32) "µù¥U¥Ó½Ð³æ" ANSI_RESET "¡A"
- "³q§i¯¸ªø¥HÀò±o¶i¶¥¨Ï¥ÎÅv¤O¡C\n\n\n\n");
- u_register();
-
-#ifdef NEWUSER_LIMIT
- if (cuser.lastlogin - cuser->firstlogin < 3 * 86400)
- cuser.userlevel &= ~PERM_POST;
- more("etc/newuser", YEA);
-#endif
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// User Registration (Phase 2)
-/////////////////////////////////////////////////////////////////////////////
-
-static void
-toregister(char *email, char *phone, char *career,
- char *rname, char *addr, char *mobile)
-{
- FILE *fn = NULL;
-
- justify_wait(cuser.userid, phone, career, rname, addr, mobile);
-
- clear();
- stand_title("»{ÃÒ³]©w");
- if (cuser.userlevel & PERM_NOREGCODE){
- strcpy(email, "x");
- goto REGFORM2;
- }
- move(1, 0);
- outs("±z¦n, ¥»¯¸»{ÃÒ»{ÃÒªº¤è¦¡¦³:\n"
- " 1.­Y±z¦³ E-Mail (¥»¯¸¤£±µ¨ü yahoo, kimoµ¥§K¶Oªº E-Mail)\n"
- " ½Ð¿é¤J±zªº E-Mail , §Ú­Ì·|±Hµo§t¦³»{ÃÒ½Xªº«H¥óµ¹±z\n"
- " ¦¬¨ì«á½Ð¨ì (U)ser => (R)egister ¿é¤J»{ÃÒ½X, §Y¥i³q¹L»{ÃÒ\n"
- "\n"
- " 2.­Y±z¨S¦³ E-Mail ©Î¬O¤@ª½µLªk¦¬¨ì»{ÃÒ«H, ½Ð¿é¤J x \n"
- " ·|¦³¯¸ªø¿Ë¦Û¤H¤u¼f®Öµù¥U¸ê®Æ¡A" ANSI_COLOR(1;33)
- "¦ýª`·N³o¥i¯à·|ªá¤W¼Æ¶g©Î§ó¦h®É¶¡¡C" ANSI_RESET "\n"
- "**********************************************************\n"
- "* ª`·N! *\n"
- "* ³q±`À³¸Ó·|¦b¿é¤J§¹¦¨«á¤Q¤ÀÄÁ¤º¦¬¨ì»{ÃÒ«H, ­Y¹L¤[¥¼¦¬¨ì *\n"
- "* ½Ð¨ì¶l¥ó©U§£±íÀˬd¬O§_³Q·í§@©U§£«H(SPAM)¤F¡A¥t¥~­Y¬O *\n"
- "* ¿é¤J«áµo¥Í»{ÃÒ½X¿ù»~½Ð­«¶ñ¤@¦¸ E-Mail *\n"
- "**********************************************************\n");
-
-#ifdef HAVEMOBILE
- outs(" 3.­Y±z¦³¤â¾÷ªù¸¹¥B·Q±Ä¨ú¤â¾÷²°T»{ÃÒªº¤è¦¡ , ½Ð¿é¤J m \n"
- " §Ú­Ì±N·|±Hµo§t¦³»{ÃÒ½XªºÂ²°Tµ¹±z \n"
- " ¦¬¨ì«á½Ð¨ì(U)ser => (R)egister ¿é¤J»{ÃÒ½X, §Y¥i³q¹L»{ÃÒ\n");
-#endif
-
- while (1) {
- email[0] = 0;
- getfield(15, "¨­¤À»{ÃÒ¥Î", "E-Mail Address", email, 50);
- if (strcmp(email, "x") == 0 || strcmp(email, "X") == 0)
- break;
-#ifdef HAVEMOBILE
- else if (strcmp(email, "m") == 0 || strcmp(email, "M") == 0) {
- if (isvalidmobile(mobile)) {
- char yn[3];
- getdata(16, 0, "½Ð¦A¦¸½T»{±z¿é¤Jªº¤â¾÷¸¹½X¥¿½T¹À? [y/N]",
- yn, sizeof(yn), LCECHO);
- if (yn[0] == 'Y' || yn[0] == 'y')
- break;
- } else {
- move(15, 0); clrtobot();
- move(17, 0);
- outs("«ü©wªº¤â¾÷¸¹½X¤£¥¿½T,"
- "­Y±zµL¤â¾÷ªù¸¹½Ð¿ï¾Ü¨ä¥L¤è¦¡»{ÃÒ");
- }
-
- }
-#endif
- else if (isvalidemail(email)) {
- char yn[3];
-#ifdef USE_EMAILDB
- int email_count = emaildb_check_email(email, strlen(email));
-
- if (email_count < 0) {
- move(15, 0); clrtobot();
- move(17, 0);
- outs("¼È®É¤£¤¹³\\ email »{ÃÒµù¥U, ½Ðµy«á¦A¸Õ\n");
- pressanykey();
- return;
- } else if (email_count >= EMAILDB_LIMIT) {
- move(15, 0); clrtobot();
- move(17, 0);
- outs("«ü©wªº E-Mail ¤wµù¥U¹L¦h±b¸¹, ½Ð¨Ï¥Î¨ä¥L E-Mail, ©Î¿é¤J x ±Ä¤â°Ê»{ÃÒ\n");
- outs("¦ýª`·N¤â°Ê»{ÃÒ³q±`·|ªá¤W¼Æ¶g¥H¤Wªº®É¶¡¡C\n");
- } else {
-#endif
- getdata(16, 0, "½Ð¦A¦¸½T»{±z¿é¤Jªº E-Mail ¦ì¸m¥¿½T¹À? [y/N]",
- yn, sizeof(yn), LCECHO);
- if (yn[0] == 'Y' || yn[0] == 'y')
- break;
-#ifdef USE_EMAILDB
- }
-#endif
- } else {
- move(15, 0); clrtobot();
- move(17, 0);
- outs("«ü©wªº E-Mail ¤£¥¿½T, ­Y±zµL E-Mail ½Ð¿é¤J x ¥Ñ¯¸ªø¤â°Ê»{ÃÒ\n");
- outs("¦ýª`·N¤â°Ê»{ÃÒ³q±`·|ªá¤W¼Æ¶g¥H¤Wªº®É¶¡¡C\n");
- }
- }
-#ifdef USE_EMAILDB
- if (emaildb_update_email(cuser.userid, strlen(cuser.userid),
- email, strlen(email)) < 0) {
- move(15, 0); clrtobot();
- move(17, 0);
- outs("¼È®É¤£¤¹³\\ email »{ÃÒµù¥U, ½Ðµy«á¦A¸Õ\n");
- pressanykey();
- return;
- }
-#endif
- strlcpy(cuser.email, email, sizeof(cuser.email));
- REGFORM2:
- if (strcasecmp(email, "x") == 0) { /* ¤â°Ê»{ÃÒ */
- if ((fn = fopen(fn_register, "a"))) {
- fprintf(fn, "num: %d, %s", usernum, ctime4(&now));
- fprintf(fn, "uid: %s\n", cuser.userid);
- fprintf(fn, "name: %s\n", rname);
- fprintf(fn, "career: %s\n", career);
- fprintf(fn, "addr: %s\n", addr);
- fprintf(fn, "phone: %s\n", phone);
- fprintf(fn, "mobile: %s\n", mobile);
- fprintf(fn, "email: %s\n", email);
- fprintf(fn, "----\n");
- fclose(fn);
- // save justify information
- snprintf(cuser.justify, sizeof(cuser.justify),
- "%s:%s:<Manual>", phone, career);
- }
- // XXX what if we cannot open register form?
- } else {
- // register by mail of phone
- snprintf(cuser.justify, sizeof(cuser.justify),
- "%s:%s:<Email>", phone, career);
-#ifdef HAVEMOBILE
- if (phone != NULL && email[1] == 0 && tolower(email[0]) == 'm')
- sprintf(cuser.justify, sizeof(cuser.justify),
- "%s:%s:<Mobile>", phone, career);
-#endif
- email_justify(&cuser);
- }
-}
-
-
-int
-u_register(void)
-{
- char rname[20], addr[50], mobile[16];
-#ifdef FOREIGN_REG
- char fore[2];
-#endif
- char phone[20], career[40], email[50], birthday[11], sex_is[2];
- unsigned char year, mon, day;
- char inregcode[14], regcode[50];
- char ans[3], *ptr, *errcode;
- char genbuf[200];
- FILE *fn;
-
- if (cuser.userlevel & PERM_LOGINOK) {
- outs("±zªº¨­¥÷½T»{¤w¸g§¹¦¨¡A¤£»Ý¶ñ¼g¥Ó½Ðªí");
- return XEASY;
- }
- if ((fn = fopen(fn_register, "r"))) {
- int i =0;
- while (fgets(genbuf, STRLEN, fn)) {
- if ((ptr = strchr(genbuf, '\n')))
- *ptr = '\0';
- if (strncmp(genbuf, "uid: ", 5) != 0)
- continue;
- i++;
- if(strcmp(genbuf + 5, cuser.userid) != 0)
- continue;
- fclose(fn);
- /* idiots complain about this, so bug them */
- clear();
- move(3, 0);
- prints(" ±zªºµù¥U¥Ó½Ð³æ©|¦b³B²z¤¤(³B²z¶¶¦ì: %d)¡A½Ð­@¤ßµ¥­Ô\n\n", i);
- outs(" ¦pªG±z¤w¦¬¨ìµù¥U½X«o¬Ý¨ì³o­Óµe­±¡A¨º¥Nªí±z¦b¨Ï¥Î Email µù¥U«á\n");
- outs(" " ANSI_COLOR(1;31) "¤S¥t¥~¥Ó½Ð¤F¯¸ªøª½±µ¤H¤u¼f®Öªºµù¥U¥Ó½Ð³æ¡C"
- ANSI_RESET "\n\n");
- // outs("¸Ó¦º¡A³£¤£¬Ý»¡©úªº...\n");
- outs(" ¶i¤J¤H¤u¼f®Öµ{§Ç«á Email µù¥U¦Û°Ê¥¢®Ä¡A¦³µù¥U½X¤]¨S¥Î¡A\n");
- outs(" ­nµ¥¨ì¼f®Ö§¹¦¨ (·|¦hªá«Ü¦h®É¶¡¡A³q±`°_½X¼Æ¤Ñ) ¡A©Ò¥H½Ð­@¤ßµ¥­Ô¡C\n\n");
-
- /* ¤U­±¬O°ê¤ýªº code ©Ò»Ý­nªº message */
-#if 0
- outs(" ¥t¥~½Ðª`·N¡A­Y¯¸ªø¼fµù¥U³æ®É±z¥¿¦b¯¸¤W«h·|µLªk¼f®Ö¡B¦Û°Ê¸õ¹L¡C\n");
- outs(" ©Ò¥Hµ¥­Ô¼f®Ö®É½Ð¤Å±¾¯¸¡C­Y¶W¹L¨â¤T¤Ñ¤´¥¼³Q¼f¨ì¡A³q±`´N¬O³o­Ó­ì¦]¡C\n");
-#endif
-
- vmsg("±zªºµù¥U¥Ó½Ð³æ©|¦b³B²z¤¤");
- return FULLUPDATE;
- }
- fclose(fn);
- }
- strlcpy(rname, cuser.realname, sizeof(rname));
- strlcpy(addr, cuser.address, sizeof(addr));
- strlcpy(email, cuser.email, sizeof(email));
- if (cuser.mobile)
- snprintf(mobile, sizeof(mobile), "0%09d", cuser.mobile);
- else
- mobile[0] = 0;
- if (cuser.month == 0 && cuser.day == 0 && cuser.year == 0)
- birthday[0] = 0;
- else
- snprintf(birthday, sizeof(birthday), "%04i/%02i/%02i",
- 1900 + cuser.year, cuser.month, cuser.day);
- sex_is[0] = (cuser.sex % 8) + '1';
- sex_is[1] = 0;
- career[0] = phone[0] = '\0';
- sethomefile(genbuf, cuser.userid, FN_JUSTIFY_WAIT);
- if ((fn = fopen(genbuf, "r"))) {
- fgets(genbuf, sizeof(genbuf), fn);
- chomp(genbuf);
- strlcpy(phone, genbuf, sizeof(phone));
-
- fgets(genbuf, sizeof(genbuf), fn);
- chomp(genbuf);
- strlcpy(career, genbuf, sizeof(career));
-
- fgets(genbuf, sizeof(genbuf), fn); // old version compatible
-
- fgets(genbuf, sizeof(genbuf), fn);
- chomp(genbuf);
- strlcpy(rname, genbuf, sizeof(rname));
-
- fgets(genbuf, sizeof(genbuf), fn);
- chomp(genbuf);
- strlcpy(addr, genbuf, sizeof(addr));
-
- fgets(genbuf, sizeof(genbuf), fn);
- chomp(genbuf);
- strlcpy(mobile, genbuf, sizeof(mobile));
-
- fclose(fn);
- }
-
- if (cuser.userlevel & PERM_NOREGCODE) {
- vmsg("±z¤£³Q¤¹³\\¨Ï¥Î»{ÃÒ½X»{ÃÒ¡C½Ð¶ñ¼gµù¥U¥Ó½Ð³æ");
- goto REGFORM;
- }
-
- // getregcode(regcode);
-
- // XXX why check by year?
- // birthday is moved to earlier, so let's check email instead.
- if (cuser.email[0] && // cuser.year != 0 && /* ¤w¸g²Ä¤@¦¸¶ñ¹L¤F~ ^^" */
- strcmp(cuser.email, "x") != 0 && /* ¤W¦¸¤â°Ê»{ÃÒ¥¢±Ñ */
- strcmp(cuser.email, "X") != 0)
- {
- clear();
- stand_title("EMail»{ÃÒ");
- move(2, 0);
-
- prints("½Ð¿é¤J±zªº»{ÃÒ½X¡C(¥Ñ %s ¶}ÀYµLªÅ¥Õªº¤Q¤T½X)\n"
- "©Î¿é¤J x ¨Ó­«·s¶ñ¼g E-Mail ©Î§ï¥Ñ¯¸ªø¤â°Ê»{ÃÒ\n", REGCODE_INITIAL);
- inregcode[0] = 0;
-
- do{
- getdata(10, 0, "±zªº»{ÃÒ½X¡G",
- inregcode, sizeof(inregcode), DOECHO);
- if( strcmp(inregcode, "x") == 0 || strcmp(inregcode, "X") == 0 )
- break;
- if( strlen(inregcode) != 13 || inregcode[0] == ' ')
- vmsg("»{ÃÒ½X¿é¤J¤£§¹¾ã¡AÁ`¦@À³¦³¤Q¤T½X¡A¨S¦³ªÅ¥Õ¦r¤¸¡C");
- else if( inregcode[0] != REGCODE_INITIAL[0] || inregcode[1] != REGCODE_INITIAL[1] ) {
- /* old regcode */
- vmsg("¿é¤Jªº»{ÃÒ½X¿ù»~¡A" // "©Î¦]¨t²Îª@¯Å¤w¥¢®Ä¡A"
- "½Ð¿é¤J x ­«¶ñ¤@¦¸ E-Mail");
- }
- else
- break;
- } while( 1 );
-
- // make it case insensitive.
- if (strcasecmp(inregcode, getregcode(regcode)) == 0) {
- int unum;
- delregcodefile();
- if ((unum = searchuser(cuser.userid, NULL)) == 0) {
- vmsg("¨t²Î¿ù»~¡A¬dµL¦¹¤H¡I");
- u_exit("getuser error");
- exit(0);
- }
- mail_muser(cuser, "[µù¥U¦¨¥\\Åo]", "etc/registeredmail");
-#if FOREIGN_REG_DAY > 0
- if(cuser.uflag2 & FOREIGN)
- mail_muser(cuser, "[¥X¤J¹ÒºÞ²z§½]", "etc/foreign_welcome");
-#endif
- cuser.userlevel |= (PERM_LOGINOK | PERM_POST);
- outs("\nµù¥U¦¨¥\\, ­«·s¤W¯¸«á±N¨ú±o§¹¾ãÅv­­\n"
- "½Ð«ö¤U¥ô¤@Áä¸õÂ÷«á­«·s¤W¯¸~ :)");
- sethomefile(genbuf, cuser.userid, FN_JUSTIFY_WAIT);
- unlink(genbuf);
- snprintf(cuser.justify, sizeof(cuser.justify),
- "%s:%s:email", phone, career);
- sethomefile(genbuf, cuser.userid, FN_JUSTIFY);
- log_file(genbuf, LOG_CREAT, cuser.justify);
- pressanykey();
- u_exit("registed");
- exit(0);
- return QUIT;
- } else if (strcasecmp(inregcode, "x") != 0) {
- if (regcode[0])
- {
- vmsg("»{ÃÒ½X¿ù»~¡I");
- return FULLUPDATE;
- }
- else
- {
- vmsg("»{ÃÒ½X¤w¹L´Á¡A½Ð­«·sµù¥U¡C");
- toregister(email, phone, career, rname, addr, mobile);
- return FULLUPDATE;
- }
- } else {
- toregister(email, phone, career, rname, addr, mobile);
- return FULLUPDATE;
- }
- }
-
- REGFORM:
- getdata(b_lines - 1, 0, "±z½T©w­n¶ñ¼gµù¥U³æ¶Ü(Y/N)¡H[N] ",
- ans, 3, LCECHO);
- if (ans[0] != 'y')
- return FULLUPDATE;
-
- move(2, 0);
- clrtobot();
- while (1) {
- clear();
- move(1, 0);
- prints("%s(%s) ±z¦n¡A½Ð¾Ú¹ê¶ñ¼g¥H¤Uªº¸ê®Æ:",
- cuser.userid, cuser.nickname);
-#ifdef FOREIGN_REG
- fore[0] = 'y';
- fore[1] = 0;
- getfield(2, "Y/n", "¬O§_²{¦b¦í¦b¥xÆW", fore, 2);
- if (fore[0] == 'n')
- fore[0] |= FOREIGN;
- else
- fore[0] = 0;
-#endif
- while (1) {
- getfield(8,
-#ifdef FOREIGN_REG
- "½Ð¥Î¥»¦W",
-#else
- "½Ð¥Î¤¤¤å",
-#endif
- "¯u¹ê©m¦W", rname, 20);
- if( (errcode = isvalidname(rname)) == NULL )
- break;
- else
- vmsg(errcode);
- }
-
- move(11, 0);
- outs(" ½ÐºÉ¶q¸Ô²Óªº¶ñ¼g±zªºªA°È³æ¦ì¡A¤j±M°|®Õ½Ð³Â·Ð"
- "¥[" ANSI_COLOR(1;33) "¨t©Ò" ANSI_RESET "¡A¤½¥q³æ¦ì½Ð¥[" ANSI_COLOR(1;33) "¾ºÙ" ANSI_RESET "¡A\n"
- " ¼ÈµL¤u§@½Ð³Â·Ð¶ñ¼g" ANSI_COLOR(1;33) "²¦·~¾Ç®Õ" ANSI_RESET "¡C\n");
- while (1) {
- getfield(9, "(²¦·~)¾Ç®Õ(§t" ANSI_COLOR(1;33) "¨t©Ò¦~¯Å" ANSI_RESET ")©Î³æ¦ì¾ºÙ",
- "ªA°È³æ¦ì", career, 40);
- if( (errcode = isvalidcareer(career)) == NULL )
- break;
- else
- vmsg(errcode);
- }
- move(10, 0); clrtobot();
- while (1) {
- getfield(10, "§t" ANSI_COLOR(1;33) "¿¤¥«" ANSI_RESET "¤Îªù¹ì¸¹½X"
- "(¥x¥_½Ð¥[" ANSI_COLOR(1;33) "¦æ¬F°Ï" ANSI_RESET ")",
- "¥Ø«e¦í§}", addr, sizeof(addr));
- if( (errcode = isvalidaddr(addr)) == NULL
-#ifdef FOREIGN_REG
- || fore[0]
-#endif
- )
- break;
- else
- vmsg(errcode);
- }
- while (1) {
- getfield(11, "¤£¥[-(), ¥]¬Aªø³~°Ï¸¹", "³sµ¸¹q¸Ü", phone, 11);
- if( (errcode = isvalidphone(phone)) == NULL )
- break;
- else
- vmsg(errcode);
- }
- getfield(12, "¥u¿é¤J¼Æ¦r ¦p:0912345678 (¥i¤£¶ñ)",
- "¤â¾÷¸¹½X", mobile, 20);
- while (1) {
- getfield(13, "¦è¤¸/¤ë¤ë/¤é¤é ¦p:1984/02/29", "¥Í¤é", birthday, sizeof(birthday));
- if (birthday[0] == 0) {
- snprintf(birthday, sizeof(birthday), "%04i/%02i/%02i",
- 1900 + cuser.year, cuser.month, cuser.day);
- mon = cuser.month;
- day = cuser.day;
- year = cuser.year;
- } else {
- int y, m, d;
- if (ParseDate(birthday, &y, &m, &d)) {
- vmsg("±zªº¿é¤J¤£¥¿½T");
- continue;
- }
- mon = (unsigned char)m;
- day = (unsigned char)d;
- year = (unsigned char)(y - 1900);
- }
- if (year < 40) {
- vmsg("±zªº¿é¤J¤£¥¿½T");
- continue;
- }
- break;
- }
- getfield(14, "1.¸¯®æ 2.©j±µ ", "©Ê§O", sex_is, 2);
- getdata(20, 0, "¥H¤W¸ê®Æ¬O§_¥¿½T(Y/N)¡H(Q)¨ú®øµù¥U [N] ",
- ans, 3, LCECHO);
- if (ans[0] == 'q')
- return 0;
- if (ans[0] == 'y')
- break;
- }
- strlcpy(cuser.realname, rname, sizeof(cuser.realname));
- strlcpy(cuser.address, addr, sizeof(cuser.address));
- strlcpy(cuser.email, email, sizeof(cuser.email));
- cuser.mobile = atoi(mobile);
- cuser.sex = (sex_is[0] - '1') % 8;
- cuser.month = mon;
- cuser.day = day;
- cuser.year = year;
-#ifdef FOREIGN_REG
- if (fore[0])
- cuser.uflag2 |= FOREIGN;
- else
- cuser.uflag2 &= ~FOREIGN;
-#endif
- trim(career);
- trim(addr);
- trim(phone);
-
- toregister(email, phone, career, rname, addr, mobile);
-
- // update cuser
- passwd_update(usernum, &cuser);
-
- return FULLUPDATE;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// Administration (SYSOP Validation)
-/////////////////////////////////////////////////////////////////////////////
-
-#define REJECT_REASONS (6)
-#define REASON_LEN (60)
-static const char *reasonstr[REJECT_REASONS] = {
- "¿é¤J¯u¹ê©m¦W",
- "¸Ô¶ñ(²¦·~)¾Ç®Õ¡y¨t¡z¡y¯Å¡z©ÎªA°È³æ¦ì(§t©ÒÄÝ¿¤¥«¤Î¾ºÙ)",
- "¶ñ¼g§¹¾ãªº¦í§}¸ê®Æ (§t¿¤¥«¦WºÙ, ¥x¥_¥«½Ð§t¦æ¬F°Ï°ì)",
- "¸Ô¶ñ³sµ¸¹q¸Ü (§t°Ï½X, ¤¤¶¡¤£¥[ '-', '(', ')' µ¥²Å¸¹)",
- "ºë½T¨Ã§¹¾ã¶ñ¼gµù¥U¥Ó½Ðªí",
- "¥Î¤¤¤å¶ñ¼g¥Ó½Ð³æ",
-};
-
-#define REASON_FIRSTABBREV '0'
-#define REASON_IN_ABBREV(x) \
- ((x) >= REASON_FIRSTABBREV && (x) - REASON_FIRSTABBREV < REJECT_REASONS)
-#define REASON_EXPANDABBREV(x) reasonstr[(x) - REASON_FIRSTABBREV]
-
-void
-regform_accept(const char *userid, const char *justify)
-{
- char buf[PATHLEN];
- int unum = 0;
- userec_t muser;
-
- unum = getuser(userid, &muser);
- if (unum == 0)
- return; // invalid user
-
- muser.userlevel |= (PERM_LOGINOK | PERM_POST);
- strlcpy(muser.justify, justify, sizeof(muser.justify));
- // manual accept sets email to 'x'
- strlcpy(muser.email, "x", sizeof(muser.email));
-
- // handle files
- sethomefile(buf, muser.userid, FN_JUSTIFY_WAIT);
- unlink(buf);
- sethomefile(buf, muser.userid, FN_REJECT_NOTIFY);
- unlink(buf);
- sethomefile(buf, muser.userid, FN_JUSTIFY);
- log_filef(buf, LOG_CREAT, "%s\n", muser.justify);
-
- // update password file
- passwd_update(unum, &muser);
-
- // alert online users?
- sendalert(muser.userid, ALERT_PWD_PERM|ALERT_PWD_JUSTIFY); // force to reload perm
-
-#if FOREIGN_REG_DAY > 0
- if(muser.uflag2 & FOREIGN)
- mail_muser(muser, "[¥X¤J¹ÒºÞ²z§½]", "etc/foreign_welcome");
- else
-#endif
- // last: send notification mail
- mail_muser(muser, "[µù¥U¦¨¥\\Åo]", "etc/registered");
-}
-
-void
-regform_reject(const char *userid, const char *reason)
-{
- char buf[PATHLEN];
- FILE *fp = NULL;
- int unum = 0;
- userec_t muser;
-
- unum = getuser(userid, &muser);
- if (unum == 0)
- return; // invalid user
-
- muser.userlevel &= ~(PERM_LOGINOK | PERM_POST);
-
- // handle files
- sethomefile(buf, muser.userid, FN_JUSTIFY_WAIT);
- unlink(buf);
-
- // update password file
- passwd_update(unum, &muser);
-
- // alert notify users?
- sendalert(muser.userid, ALERT_PWD_PERM); // force to reload perm
-
- // last: send notification
- mkuserdir(muser.userid);
- sethomefile(buf, muser.userid, FN_REJECT_NOTIFY);
- fp = fopen(buf, "wt");
- assert(fp);
- syncnow();
- fprintf(fp, "%s µù¥U¥¢±Ñ¡C\n", Cdate(&now));
-
- // multiple abbrev loop
- if (REASON_IN_ABBREV(reason[0]))
- {
- int i = 0;
- for (i = 0; i < REASON_LEN && REASON_IN_ABBREV(reason[i]); i++)
- fprintf(fp, "[°h¦^­ì¦]] ½Ð%s\n", REASON_EXPANDABBREV(reason[i]));
- } else {
- fprintf(fp, "[°h¦^­ì¦]] %s\n", reason);
- }
- fclose(fp);
- mail_muser(muser, "[µù¥U¥¢±Ñ]", buf);
-}
-
-// Regform v1 API
-// read count entries from regsrc to a temp buffer
-FILE *
-pull_regform(const char *regfile, char *workfn, int count)
-{
- FILE *fp = NULL;
-
- snprintf(workfn, PATHLEN, "%s.tmp", regfile);
- if (dashf(workfn)) {
- vmsg("¨ä¥L SYSOP ¤]¦b¼f®Öµù¥U¥Ó½Ð³æ");
- return NULL;
- }
-
- // count < 0 means unlimited pulling
- Rename(regfile, workfn);
- if ((fp = fopen(workfn, "r")) == NULL) {
- vmsgf("¨t²Î¿ù»~¡AµLªkŪ¨úµù¥U¸ê®ÆÀÉ: %s", workfn);
- return NULL;
- }
- return fp;
-}
-
-// write all left in "remains" to regfn.
-void
-pump_regform(const char *regfn, FILE *remains)
-{
- // restore trailing tickets
- char buf[PATHLEN];
- FILE *fout = fopen(regfn, "at");
- if (!fout)
- return;
-
- while (fgets(buf, sizeof(buf), remains))
- fputs(buf, fout);
- fclose(fout);
-}
-
-// New Regform UI
-static void
-prompt_regform_ui()
-{
- move(b_lines, 0);
- outs(ANSI_COLOR(30;47) " "
- ANSI_COLOR(31) "y" ANSI_COLOR(30) "±µ¨ü "
- ANSI_COLOR(31) "n" ANSI_COLOR(30) "©Úµ´ "
- ANSI_COLOR(31) "d" ANSI_COLOR(30) "§R°£ "
- ANSI_COLOR(31) "s" ANSI_COLOR(30) "¸õ¹L "
- ANSI_COLOR(31) "u" ANSI_COLOR(30) "´_­ì "
- " "
- ANSI_COLOR(31) "0-9jk¡ô¡õ" ANSI_COLOR(30) "²¾°Ê "
- ANSI_COLOR(31) "ªÅ¥Õ/PgDn" ANSI_COLOR(30) "Àx¦s+¤U­¶ "
- " "
- ANSI_COLOR(31) "q/END" ANSI_COLOR(30) "µ²§ô "
- ANSI_RESET);
-}
-
-static void
-resolve_reason(char *s, int y)
-{
- // should start with REASON_FIRSTABBREV
- const char *reason_prompt =
- " (0)¯u¹ê©m¦W (1)¸Ô¶ñ¨t¯Å (2)§¹¾ã¦í§}"
- " (3)¸Ô¶ñ¹q¸Ü (4)½T¹ê¶ñ¼g (5)¤¤¤å¶ñ¼g";
-
- s[0] = 0;
- move(y, 0);
- outs(reason_prompt); outs("\n");
-
- do {
- getdata(y+1, 0,
- "°h¦^­ì¦]: ", s, REASON_LEN, DOECHO);
-
- // convert abbrev reasons (format: single digit, or multiple digites)
- if (REASON_IN_ABBREV(s[0]))
- {
- if (s[1] == 0) // simple replace ment
- {
- strlcpy(s+2, REASON_EXPANDABBREV(s[0]),
- REASON_LEN-2);
- s[0] = 0xbd; // '½Ð'[0];
- s[1] = 0xd0; // '½Ð'[1];
- } else {
- // strip until all digites
- char *p = s;
- while (*p)
- {
- if (!REASON_IN_ABBREV(*p))
- *p = ' ';
- p++;
- }
- strip_blank(s, s);
- strlcat(s, " [¦h­«­ì¦]]", REASON_LEN);
- }
- }
-
- if (strlen(s) < 4)
- {
- if (vmsg("­ì¦]¤Óµu¡C ­n¨ú®ø°h¦^¶Ü¡H (y/N): ") == 'y')
- {
- *s = 0;
- return;
- }
- }
- } while (strlen(s) < 4);
-}
-
-////////////////////////////////////////////////////////////////////////////
-// Regform Utilities
-////////////////////////////////////////////////////////////////////////////
-
-// TODO define and use structure instead, even in reg request file.
-typedef struct {
- // current format:
- // (optional) num: unum, date
- // [0] uid: xxxxx (IDLEN=12)
- // [1] name: RRRRRR (20)
- // [2] career: YYYYYYYYYYYYYYYYYYYYYYYYYY (40)
- // [3] addr: TTTTTTTTT (50)
- // [4] phone: 02DDDDDDDD (20)
- // [5] email: x (50) (deprecated)
- // [6] mobile: (deprecated)
- // [7] ----
- // lasthost: 16
- char userid[IDLEN+1];
-
- char exist;
- char online;
- char pad [ 5]; // IDLEN(12)+1+1+1+5=20
-
- char name [20];
- char career[40];
- char addr [50];
- char phone [20];
-} RegformEntry;
-
-// regform format utilities
-int
-load_regform_entry(RegformEntry *pre, FILE *fp)
-{
- char buf[STRLEN];
- char *v;
-
- memset(pre, 0, sizeof(RegformEntry));
- while (fgets(buf, sizeof(buf), fp))
- {
- if (buf[0] == '-')
- break;
- buf[sizeof(buf)-1] = 0;
- v = strchr(buf, ':');
- if (v == NULL)
- continue;
- *v++ = 0;
- if (*v == ' ') v++;
- chomp(v);
-
- if (strcmp(buf, "uid") == 0)
- strlcpy(pre->userid, v, sizeof(pre->userid));
- else if (strcmp(buf, "name") == 0)
- strlcpy(pre->name, v, sizeof(pre->name));
- else if (strcmp(buf, "career") == 0)
- strlcpy(pre->career, v, sizeof(pre->career));
- else if (strcmp(buf, "addr") == 0)
- strlcpy(pre->addr, v, sizeof(pre->addr));
- else if (strcmp(buf, "phone") == 0)
- strlcpy(pre->phone, v, sizeof(pre->phone));
- }
- return pre->userid[0] ? 1 : 0;
-}
-
-int
-print_regform_entry(const RegformEntry *pre, FILE *fp, int close)
-{
- fprintf(fp, "uid: %s\n", pre->userid);
- fprintf(fp, "name: %s\n", pre->name);
- fprintf(fp, "career: %s\n", pre->career);
- fprintf(fp, "addr: %s\n", pre->addr);
- fprintf(fp, "phone: %s\n", pre->phone);
- if (close)
- fprintf(fp, "----\n");
- return 1;
-}
-
-int
-append_regform(const RegformEntry *pre, const char *logfn,
- const char *varname, const char *varval1, const char *varval2)
-{
- FILE *fout = fopen(logfn, "at");
- if (!fout)
- return 0;
-
- print_regform_entry(pre, fout, 0);
- if (varname && *varname)
- {
- syncnow();
- fprintf(fout, "Date: %s\n", Cdate(&now));
- if (!varval1) varval1 = "";
- fprintf(fout, "%s: %s", varname, varval1);
- if (varval2) fprintf(fout, " %s", varval2);
- fprintf(fout, "\n");
- }
- // close it
- fprintf(fout, "----\n");
- fclose(fout);
- return 1;
-}
-
-////////////////////////////////////////////////////////////////////////////
-// Regform2 API
-////////////////////////////////////////////////////////////////////////////
-
-// registration queue
-int
-regq_append(const char *userid)
-{
- if (file_append_record(FN_REQLIST, userid) < 0)
- return 0;
- return 1;
-}
-
-int
-regq_find(const char *userid)
-{
- return file_find_record(FN_REQLIST, userid);
-}
-
-int
-regq_delete(const char *userid)
-{
- return file_delete_record(FN_REQLIST, userid, 0);
-}
-
-// user home regform operation
-int
-regfrm_exist(const char *userid)
-{
- char fn[PATHLEN];
- sethomefile(fn, userid, FN_REGFORM);
- return dashf(fn) ? 1 : 0;
-}
-
-int
-regfrm_load(const char *userid, RegformEntry *pre)
-{
- FILE *fp = NULL;
- char fn[PATHLEN];
- int ret = 0;
- sethomefile(fn, userid, FN_REGFORM);
- if (!dashf(fn))
- return 0;
-
- fp = fopen(fn, "rt");
- if (!fp)
- return 0;
- ret = load_regform_entry(pre, fp);
- fclose(fp);
- return ret;
-}
-
-int
-regfrm_save(const char *userid, const RegformEntry *pre)
-{
- FILE *fp = NULL;
- char fn[PATHLEN];
- int ret = 0;
- sethomefile(fn, userid, FN_REGFORM);
-
- fp = fopen(fn, "wt");
- if (!fp)
- return 0;
- ret = print_regform_entry(pre, fp, 1);
- fclose(fp);
- return ret;
-}
-
-int
-regfrm_trylock(const char *userid)
-{
- int fd = 0;
- char fn[PATHLEN];
- sethomefile(fn, userid, FN_REGFORM);
- if (!dashf(fn)) return 0;
- fd = open(fn, O_RDONLY);
- if (fd < 0) return 0;
- if (flock(fd, LOCK_EX|LOCK_NB) == 0)
- return fd;
- close(fd);
- return 0;
-}
-
-int
-regfrm_unlock(int lockfd)
-{
- int fd = lockfd;
- if (lockfd <= 0)
- return 0;
- lockfd = flock(fd, LOCK_UN) == 0 ? 1 : 0;
- close(fd);
- return lockfd;
-}
-
-// regform processors
-int
-regfrm_accept(RegformEntry *pre)
-{
- char justify[REGLEN+1], buf[STRLEN*2];
- char fn[PATHLEN], fnlog[PATHLEN];
-
- // dry run!
- vmsg("regfrm_accept");
- return 1;
-
- sethomefile(fn, pre->userid, FN_REGFORM);
-
- // build justify string
- removespace(pre->phone);
- removespace(pre->career);
- snprintf(justify, sizeof(justify),
- "%s:%s:%s", pre->phone, pre->career, cuser.userid);
-
- // call handler
- regform_accept(pre->userid, justify);
-
- // append current form to history.
- sethomefile(fnlog, pre->userid, FN_REGFORM_LOG);
- AppendTail(fn, fnlog, 0);
- // global history
- snprintf(buf, sizeof(buf), "Approved: %s -> %s\nDate: %s\n",
- cuser.userid, pre->userid, Cdate(&now));
- file_append_line(FN_REGISTER_LOG, buf);
- AppendTail(fn, FN_REGISTER_LOG, 0);
-
- // remove from queue
- unlink(fn);
- regq_delete(pre->userid);
- return 1;
-}
-
-int
-regfrm_reject(RegformEntry *pre, const char *reason)
-{
- char buf[STRLEN*2];
- char fn[PATHLEN];
-
- // dry run!
- vmsg("regfrm_reject");
- return 1;
-
- sethomefile(fn, pre->userid, FN_REGFORM);
-
- // call handler
- regform_reject(pre->userid, reason);
-
- // log it
- snprintf(buf, sizeof(buf), "Rejected: %s -> %s [%s]\nDate: %s\n",
- cuser.userid, pre->userid, reason, Cdate(&now));
- file_append_line(FN_REGISTER_LOG, buf);
- AppendTail(fn, FN_REGISTER_LOG, 0);
-
- // remove from queue
- unlink(fn);
- regq_delete(pre->userid);
- return 1;
-}
-
-int
-regfrm_delete(const char *userid)
-{
- char fn[PATHLEN];
- sethomefile(fn, userid, FN_REGFORM);
-
- // dry run!
- vmsgf("regfrm_delete (%s)", userid);
- return 1;
-
- // directly delete.
- unlink(fn);
-
- // remove from queue
- regq_delete(userid);
- return 1;
-}
-
-// working queue
-FILE *
-regq_init_pull()
-{
- FILE *fp = tmpfile(), *src =NULL;
- char buf[STRLEN];
- if (!fp) return NULL;
- src = fopen(FN_REQLIST, "rt");
- if (!src) { fclose(fp); return NULL; }
- while (fgets(buf, sizeof(buf), src))
- fputs(buf, fp);
- fclose(src);
- rewind(fp);
- return fp;
-}
-
-int
-regq_pull(FILE *fp, char *uid)
-{
- char buf[STRLEN];
- size_t idlen = 0;
- uid[0] = 0;
- if (fgets(buf, sizeof(buf), fp) == NULL)
- return 0;
- idlen = strcspn(buf, str_space);
- if (idlen < 1) return 0;
- if (idlen > IDLEN) idlen = IDLEN;
- strlcpy(uid, buf, idlen+1);
- return 1;
-}
-
-int
-regq_end_pull(FILE *fp)
-{
- // no need to unlink because fp is a tmpfile.
- if (!fp) return 0;
- fclose(fp);
- return 1;
-}
-
-// UI part
-int
-ui_display_regform_single(
- const userec_t *xuser,
- const RegformEntry *pre,
- int tid, char *reason)
-{
- int c;
-
- while (1)
- {
- move(1, 0);
- user_display(xuser, 1);
- move(14, 0);
- prints(ANSI_COLOR(1;32)
- "--------------- ³o¬O²Ä %2d ¥÷µù¥U³æ ------------------"
- ANSI_RESET "\n", tid);
- prints(" %-12s: %s\n", "±b¸¹", pre->userid);
- prints("0.%-12s: %s%s\n", "¯u¹ê©m¦W", pre->name,
- xuser->uflag2 & FOREIGN ? " (¥~Äy)" :
- "");
- prints("1.%-12s: %s\n", "ªA°È³æ¦ì", pre->career);
- prints("2.%-12s: %s\n", "¥Ø«e¦í§}", pre->addr);
- prints("3.%-12s: %s\n", "³sµ¸¹q¸Ü", pre->phone);
-
- move(b_lines, 0);
- outs("¬O§_±µ¨ü¦¹¸ê®Æ(Y/N/Q/Del/Skip)¡H[S] ");
-
- c = tolower(igetch() & 0xFF); // round to ASCII
- if (c == 'y' || c == 'q' || c == 'd' || c == 's')
- return c;
- if (c == 'n')
- {
- int n = 0;
- move(3, 0);
- outs("\n" ANSI_COLOR(1;31)
- "½Ð´£¥X°h¦^¥Ó½Ðªí­ì¦]¡A«ö <Enter> ¨ú®ø:\n" ANSI_RESET);
- for (n = 0; n < REJECT_REASONS; n++)
- prints("%d) ½Ð%s\n", n, reasonstr[n]);
- outs("\n\n\n"); // preserved for prompt
-
- getdata(3+2+REJECT_REASONS+1, 0,"°h¦^­ì¦]: ",
- reason, REASON_LEN, DOECHO);
- if (reason[0] == 0)
- continue;
- // interprete reason
- return 'n';
- }
- else if (REASON_IN_ABBREV(c))
- {
- // quick set
- sprintf(reason, "%c", c);
- return 'n';
- }
- return 's';
- }
- // shall never reach here
- return 's';
-}
-
-// sample validator
-void
-regform2_validate_single()
-{
- int lfd = 0;
- int tid = 0;
- char uid[IDLEN+1];
- char rsn[REASON_LEN];
- FILE *fpregq = regq_init_pull();
- RegformEntry re;
-
- if (!fpregq)
- return;
-
- while (regq_pull(fpregq, uid))
- {
- userec_t muser;
- int unum = 0;
- int abort = 0;
-
- // check if user exists.
- memset(&muser, 0, sizeof(muser));
- unum = getuser(uid, &muser);
-
- if (unum < 1)
- {
- regq_delete(uid);
- continue;
- }
-
- // check if regform exists.
- if (!regfrm_exist(uid))
- {
- // TODO delete here?
- regq_delete(uid);
- continue;
- }
-
- // TODO check if user is already registered
-#if 0
- if (muser.userlevel & PERM_LOGINOK)
- {
- regfrm_delete(uid);
- continue;
- }
-#endif
-
- // try to lock
- lfd = regfrm_trylock(uid);
- if (lfd <= 0)
- continue;
-
- // load it
- if (!regfrm_load(uid, &re))
- {
- regfrm_delete(uid);
- regfrm_unlock(lfd);
- // regq_delete(uid); // done in regfrm_delete
- continue;
- }
-
- tid ++;
- // display regform and process
- switch(ui_display_regform_single(&muser, &re, tid, rsn))
- {
- case 'a': // accept
- regfrm_accept(&re);
- break;
-
- case 'd': // delete
- regfrm_delete(uid);
- break;
-
- case 'q': // quit
- abort = 1;
- break;
-
- case 'n': // reject
- regfrm_reject(&re, rsn);
- break;
-
- case 's': // skip
- // do nothing.
- break;
-
- default: // shall never reach here
- assert(0);
- break;
- }
-
- // final processing
- regfrm_unlock(lfd);
-
- if (abort)
- break;
- }
- regq_end_pull(fpregq);
-
- // finishing
- clear(); move(5, 0);
- prints("±z¼f¤F %d ¥÷µù¥U³æ¥÷¡C", tid);
- pressanykey();
-}
-
-#define FORMS_IN_PAGE (10)
-
-int
-regform2_validate_page(int dryrun)
-{
- int unum = 0;
- int yMsg = FORMS_IN_PAGE*2+1;
- userec_t muser;
- RegformEntry forms [FORMS_IN_PAGE];
- char ans [FORMS_IN_PAGE];
- int lfds [FORMS_IN_PAGE];
- char rejects[FORMS_IN_PAGE][REASON_LEN]; // reject reason length
- char rsn [REASON_LEN];
- int cforms = 0, // current loaded forms
- ci = 0, // cursor index
- ch = 0, // input key
- i;
- int tid = 0;
- char uid[IDLEN+1];
- FILE *fpregq = regq_init_pull();
-
- if (!fpregq)
- return 0;
-
- while (ch != 'q')
- {
- // initialize and prepare
- memset(ans, 0, sizeof(ans));
- memset(rejects, 0, sizeof(rejects));
- memset(forms, 0, sizeof(forms));
- memset(lfds, 0, sizeof(lfds));
- cforms = 0;
- clear();
-
- // load forms
- while (cforms < FORMS_IN_PAGE)
- {
- if (!regq_pull(fpregq, uid))
- break;
- i = cforms; // align index
-
- // check if user exists.
- memset(&muser, 0, sizeof(muser));
- unum = getuser(uid, &muser);
- if (unum < 1)
- {
- regq_delete(uid);
- continue;
- }
-
- // check if regform exists.
- if (!regfrm_exist(uid))
- {
- // TODO delete here?
- regq_delete(uid);
- continue;
- }
- // try to lock
- lfds[i] = regfrm_trylock(uid);
- if (lfds[i] <= 0)
- continue;
-
- // load it
- if (!regfrm_load(uid, &forms[i]))
- {
- regfrm_delete(uid);
- regfrm_unlock(lfds[i]);
- // regq_delete(uid); // done in regfrm_delete
- continue;
- }
-
- forms[i].exist = 1;
- forms[i].online = search_ulist(unum) ? 1 : 0;
-
- // assign default answers
- if (muser.userlevel & PERM_LOGINOK)
- ans[i] = 'd';
-#ifdef REGFORM_DISABLE_ONLINE_USER
- else if (forms[i].online)
- ans[i] = 's';
-#endif // REGFORM_DISABLE_ONLINE_USER
-
-
- // display
- move(i*2, 0);
- prints(" %2d%s %s%-12s " ANSI_RESET,
- i+1,
- (unum == 0) ? ANSI_COLOR(1;31) "D" :
- ( (muser.userlevel & PERM_LOGINOK) ?
- ANSI_COLOR(1;33) "Y" :
-#ifdef REGFORM_DISABLE_ONLINE_USER
- forms[i].online ? "s" :
-#endif
- "."),
- forms[i].online ? ANSI_COLOR(1;35) : ANSI_COLOR(1),
- forms[i].userid);
-
- prints( ANSI_COLOR(1;31) "%19s "
- ANSI_COLOR(1;32) "%-40s" ANSI_RESET"\n",
- forms[i].name, forms[i].career);
-
- move(i*2+1, 0);
- prints(" %s %-50s%20s\n",
- (muser.userlevel & PERM_NOREGCODE) ?
- ANSI_COLOR(1;31) "T" ANSI_RESET : " ",
- forms[i].addr, forms[i].phone);
-
- cforms++, tid ++;
- }
-
- // if no more forms then leave.
- if (cforms < 1)
- break;
-
- // adjust cursor if required
- if (ci >= cforms)
- ci = cforms-1;
-
- // display page info
- {
- char msg[STRLEN];
- snprintf(msg, sizeof(msg),
- "%s ¤wÅã¥Ü %d ¥÷µù¥U³æ ", // "(%2d%%) ",
- dryrun? "(´ú¸Õ¼Ò¦¡)" : "",
- tid);
- prints(ANSI_COLOR(7) "\n%78s" ANSI_RESET "\n", msg);
- }
-
- // handle user input
- prompt_regform_ui();
- ch = 0;
- while (ch != 'q' && ch != ' ') {
- ch = cursor_key(ci*2, 0);
- switch (ch)
- {
- // nav keys
- case KEY_UP:
- case 'k':
- if (ci > 0) ci--;
- break;
-
- case KEY_DOWN:
- case 'j':
- ch = 'j'; // go next
- break;
-
- // quick nav (assuming to FORMS_IN_PAGE=10)
- case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
- ci = ch - '1';
- if (ci >= cforms) ci = cforms-1;
- break;
- case '0':
- ci = 10-1;
- if (ci >= cforms) ci = cforms-1;
- break;
-
- /*
- case KEY_HOME: ci = 0; break;
- case KEY_END: ci = cforms-1; break;
- */
-
- // abort
- case KEY_END:
- case 'q':
- ch = 'q';
- if (getans("½T©w­nÂ÷¶}¤F¶Ü¡H (¥»­¶Åܧó±N¤£·|Àx¦s) [y/N]: ") != 'y')
- {
- prompt_regform_ui();
- ch = 0;
- continue;
- }
- break;
-
- // prepare to go next page
- case KEY_PGDN:
- case ' ':
- ch = ' ';
-
- {
- int blanks = 0;
- // solving blank (undecided entries)
- for (i = 0, blanks = 0; i < cforms; i++)
- if (ans[i] == 0) blanks ++;
-
- if (!blanks)
- break;
-
- // have more blanks
- ch = getans("©|¥¼«ü©wªº %d ­Ó¶µ¥Ø­n: (S¸õ¹L/y³q¹L/n©Úµ´/eÄ~Äò½s¿è): ",
- blanks);
- }
-
- if (ch == 'e')
- {
- prompt_regform_ui();
- ch = 0;
- continue;
- }
- if (ch == 'y') {
- // do nothing.
- } else if (ch == 'n') {
- // query reject reason
- resolve_reason(rsn, yMsg);
- if (*rsn == 0)
- ch = 's';
- } else ch = 's';
-
- // filling answers
- for (i = 0; i < cforms; i++)
- {
- if (ans[i] != 0)
- continue;
- ans[i] = ch;
- if (ch != 'n')
- continue;
- strlcpy(rejects[i], rsn, REASON_LEN);
- }
-
- ch = ' '; // go to page mode!
- break;
-
- // function keys
- case 'y': // accept
-#ifdef REGFORM_DISABLE_ONLINE_USER
- if (forms[ci].online)
- {
- vmsg("¼È¤£¶}©ñ¼f®Ö¦b½u¤W¨Ï¥ÎªÌ¡C");
- break;
- }
-#endif
- case 's': // skip
- case 'd': // delete
- case KEY_DEL: //delete
- if (ch == KEY_DEL) ch = 'd';
-
- grayout(ci*2, ci*2+1, GRAYOUT_DARK);
- move_ansi(ci*2, 4); outc(ch);
- ans[ci] = ch;
- ch = 'j'; // go next
- break;
-
- case 'u': // undo
-#ifdef REGFORM_DISABLE_ONLINE_USER
- if (forms[ci].online)
- {
- vmsg("¼È¤£¶}©ñ¼f®Ö¦b½u¤W¨Ï¥ÎªÌ¡C");
- break;
- }
-#endif
- grayout(ci*2, ci*2+1, GRAYOUT_NORM);
- move_ansi(ci*2, 4); outc('.');
- ans[ci] = 0;
- ch = 'j'; // go next
- break;
-
- case 'n': // reject
-#ifdef REGFORM_DISABLE_ONLINE_USER
- if (forms[ci].online)
- {
- vmsg("¼È¤£¶}©ñ¼f®Ö¦b½u¤W¨Ï¥ÎªÌ¡C");
- break;
- }
-#endif
- // query for reason
- resolve_reason(rejects[ci], yMsg);
- prompt_regform_ui();
-
- if (!rejects[ci][0])
- break;
-
- move(yMsg, 0);
- prints("°h¦^ %s µù¥U³æ­ì¦]:\n %s\n", forms[ci].userid, rejects[ci]);
-
- // do reject
- grayout(ci*2, ci*2+1, GRAYOUT_DARK);
- move_ansi(ci*2, 4); outc(ch);
- ans[ci] = ch;
- ch = 'j'; // go next
-
- break;
- } // switch(ch)
-
- // change cursor
- if (ch == 'j' && ++ci >= cforms)
- ci = cforms -1;
- } // while(ch != QUIT/SAVE)
-
- // if exit, we still need to skip all read forms
- if (ch == 'q')
- {
- for (i = 0; i < cforms; i++)
- ans[i] = 's';
- }
-
- // page complete (save).
- assert(ch == ' ' || ch == 'q');
-
- // save/commit if required.
- if (dryrun)
- {
- // prmopt for debug
- clear();
- stand_title("´ú¸Õ¼Ò¦¡");
- outs("±z¥¿¦b°õ¦æ´ú¸Õ¼Ò¦¡¡A©Ò¥H­è¼fªºµù¥U³æ¨Ã¤£·|¥Í®Ä¡C\n"
- "¤U­±¦C¥Xªº¬O­è¤~±z¼f§¹ªºµ²ªG:\n\n");
-
- for (i = 0; i < cforms; i++)
- {
- char justify[REGLEN];
- if (ans[i] == 'y')
- snprintf(justify, sizeof(justify), // build justify string
- "%s:%s:%s", forms[i].phone, forms[i].career, cuser.userid);
-
- prints("%2d. %-12s - %c %s\n", i+1, forms[i].userid, ans[i],
- ans[i] == 'n' ? rejects[i] :
- ans[i] == 'y' ? justify : "");
- }
- if (ch != 'q')
- pressanykey();
- }
- else
- {
- // real functionality
- for (i = 0; i < cforms; i++)
- {
- switch(ans[i])
- {
- case 'a': // accept
- regfrm_accept(&forms[i]);
- break;
-
- case 'd': // delete
- regfrm_delete(uid);
- break;
-
- case 'n': // reject
- regfrm_reject(&forms[i], rsn);
- break;
-
- case 's': // skip
- // do nothing.
- break;
-
- default:
- assert(0);
- break;
- }
- }
- } // !dryrun
-
- // unlock all forms
- for (i = 0; i < cforms; i++)
- regfrm_unlock(lfds[i]);
-
- } // while (ch != 'q')
-
- regq_end_pull(fpregq);
-
- // finishing
- clear(); move(5, 0);
- prints("±z¼f¤F %d ¥÷µù¥U³æ¥÷¡C", tid);
- pressanykey();
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// Regform UI
-// ³B²z Register Form
-/////////////////////////////////////////////////////////////////////////////
-
-/* Auto-Regform-Scan
- * FIXME ¯u¬O¤@¹Î©U§£
- *
- * fdata ¥Î¤F¤Ó¦h magic number
- * return value À³¸Ó¬O«ü reason (return index + 1)
- * ans[0] «üªº¬O±bºÞ¿ï¾Üªº¡u¿ù»~ªºÄæ¦ì¡v (Register ¿ï³æ¸Ì¬Ý¨ìªº¨º¨Ç)
- */
-static int
-auto_scan(char fdata[][STRLEN], char ans[])
-{
- int good = 0;
- int count = 0;
- int i;
- char temp[10];
-
- if (!strncmp(fdata[1], "¤p", 2) || strstr(fdata[1], "¤X")
- || strstr(fdata[1], "½Ö") || strstr(fdata[1], "¤£")) {
- ans[0] = '0';
- return 1;
- }
- strlcpy(temp, fdata[1], 3);
-
- /* Å|¦r */
- if (!strncmp(temp, &(fdata[1][2]), 2)) {
- ans[0] = '0';
- return 1;
- }
- if (strlen(fdata[1]) >= 6) {
- if (strstr(fdata[1], "³¯¤ô«ó")) {
- ans[0] = '0';
- return 1;
- }
- if (strstr("»¯¿ú®]§õ©P§d¾G¤ý", temp))
- good++;
- else if (strstr("§ùÃC¶ÀªL³¯©x§E¨¯¼B", temp))
- good++;
- else if (strstr("Ĭ¤è§d§f§õªò±i¹ùÀ³Ä¬", temp))
- good++;
- else if (strstr("®}ÁÂ¥Û¿c¬IÀ¹¯Î­ð", temp))
- good++;
- }
- if (!good)
- return 0;
-
- if (!strcmp(fdata[2], fdata[3]) ||
- !strcmp(fdata[2], fdata[4]) ||
- !strcmp(fdata[3], fdata[4])) {
- ans[0] = '4';
- return 5;
- }
- if (strstr(fdata[2], "¤j")) {
- if (strstr(fdata[2], "¥x") || strstr(fdata[2], "²H") ||
- strstr(fdata[2], "¥æ") || strstr(fdata[2], "¬F") ||
- strstr(fdata[2], "²M") || strstr(fdata[2], "ĵ") ||
- strstr(fdata[2], "®v") || strstr(fdata[2], "»Ê¶Ç") ||
- strstr(fdata[2], "¤¤¥¡") || strstr(fdata[2], "¦¨") ||
- strstr(fdata[2], "»²") || strstr(fdata[2], "ªF§d"))
- good++;
- } else if (strstr(fdata[2], "¤k¤¤"))
- good++;
-
- if (strstr(fdata[3], "¦a²y") || strstr(fdata[3], "¦t©z") ||
- strstr(fdata[3], "«H½c")) {
- ans[0] = '2';
- return 3;
- }
- if (strstr(fdata[3], "¥«") || strstr(fdata[3], "¿¤")) {
- if (strstr(fdata[3], "¸ô") || strstr(fdata[3], "µó")) {
- if (strstr(fdata[3], "¸¹"))
- good++;
- }
- }
- for (i = 0; fdata[4][i]; i++) {
- if (isdigit((int)fdata[4][i]))
- count++;
- }
-
- if (count <= 4) {
- ans[0] = '3';
- return 4;
- } else if (count >= 7)
- good++;
-
- if (good >= 3) {
- ans[0] = 'y';
- return -1;
- } else
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// Traditional Regform UI
-/////////////////////////////////////////////////////////////////////////////
-// TODO XXX process someone directly, according to target_uid.
-int
-scan_register_form(const char *regfile, int automode, const char *target_uid)
-{
- char genbuf[200];
- char *field[] = {
- "uid", "name", "career", "addr", "phone", "email", NULL
- };
- char *finfo[] = {
- "±b¸¹", "¯u¹ê©m¦W", "ªA°È³æ¦ì", "¥Ø«e¦í§}",
- "³sµ¸¹q¸Ü", "¹q¤l¶l¥ó«H½c", NULL
- };
- char *reason[REJECT_REASONS+1] = {
- "¿é¤J¯u¹ê©m¦W",
- "¸Ô¶ñ¡u(²¦·~)¾Ç®Õ¤Î¡y¨t¡z¡y¯Å¡z¡v©Î¡uªA°È³æ¦ì(§t©ÒÄÝ¿¤¥«¤Î¾ºÙ)¡v",
- "¶ñ¼g§¹¾ãªº¦í§}¸ê®Æ (§t¿¤¥«¦WºÙ, ¥x¥_¥«½Ð§t¦æ¬F°Ï°ì¡^",
- "¸Ô¶ñ³sµ¸¹q¸Ü (§t°Ï°ì½X, ¤¤¶¡¤£¥Î¥[ '-', '(', ')'µ¥²Å¸¹",
- "ºë½T¨Ã§¹¾ã¶ñ¼gµù¥U¥Ó½Ðªí",
- "¥Î¤¤¤å¶ñ¼g¥Ó½Ð³æ",
- NULL
- };
- char *autoid = "AutoScan";
- userec_t muser;
- FILE *fn, *fout, *freg;
- char fdata[6][STRLEN];
- char fname[STRLEN] = "", buf[STRLEN];
- char ans[4], *ptr, *uid;
- int n = 0, unum = 0, tid = 0;
- int nSelf = 0, nAuto = 0;
-
- uid = cuser.userid;
- move(2, 0);
-
- fn = pull_regform(regfile, fname, -1);
- if (!fn)
- return -1;
-
- while( fgets(genbuf, STRLEN, fn) ){
- memset(fdata, 0, sizeof(fdata));
- do {
- if( genbuf[0] == '-' )
- break;
- if ((ptr = (char *)strstr(genbuf, ": "))) {
- *ptr = '\0';
- for (n = 0; field[n]; n++) {
- if (strcmp(genbuf, field[n]) == 0) {
- strlcpy(fdata[n], ptr + 2, sizeof(fdata[n]));
- if ((ptr = (char *)strchr(fdata[n], '\n')))
- *ptr = '\0';
- }
- }
- }
- } while( fgets(genbuf, STRLEN, fn) );
- tid ++;
-
- if ((unum = getuser(fdata[0], &muser)) == 0) {
- move(2, 0);
- clrtobot();
- outs("¨t²Î¿ù»~¡A¬dµL¦¹¤H\n\n");
- for (n = 0; field[n]; n++)
- prints("%s : %s\n", finfo[n], fdata[n]);
- pressanykey();
- } else {
- if (automode)
- uid = autoid;
-
- if ((!automode || !auto_scan(fdata, ans))) {
- uid = cuser.userid;
-
- move(1, 0);
- clrtobot();
- prints("±b¸¹¦ì¸m : %d\n", unum);
- user_display(&muser, 1);
- move(14, 0);
- prints(ANSI_COLOR(1;32) "------------- "
- "½Ð¯¸ªøÄY®æ¼f®Ö¨Ï¥ÎªÌ¸ê®Æ¡A³o¬O²Ä %d ¥÷"
- "------------" ANSI_RESET "\n", tid);
- prints(" %-12s: %s\n", finfo[0], fdata[0]);
-#ifdef FOREIGN_REG
- prints("0.%-12s: %s%s\n", finfo[1], fdata[1],
- muser.uflag2 & FOREIGN ? " (¥~Äy)" : "");
-#else
- prints("0.%-12s: %s\n", finfo[1], fdata[1]);
-#endif
- for (n = 2; field[n]; n++) {
- prints("%d.%-12s: %s\n", n - 1, finfo[n], fdata[n]);
- }
- if (muser.userlevel & PERM_LOGINOK) {
- ans[0] = getkey("¦¹±b¸¹¤w¸g§¹¦¨µù¥U, "
- "§ó·s(Y/N/Skip)¡H[N] ");
- if (ans[0] != 'y' && ans[0] != 's')
- ans[0] = 'd';
- } else {
- if (search_ulist(unum) == NULL)
- {
- move(b_lines, 0); clrtoeol();
- outs("¬O§_±µ¨ü¦¹¸ê®Æ(Y/N/Q/Del/Skip)¡H[S] ");
- // FIXME if the user got online here
- ans[0] = igetch();
- }
- else
- ans[0] = 's';
- ans[0] = tolower(ans[0]);
- if (ans[0] != 'y' && ans[0] != 'n' &&
- ans[0] != 'q' && ans[0] != 'd' &&
- !('0' <= ans[0] && ans[0] < ('0' + REJECT_REASONS)))
- ans[0] = 's';
- ans[1] = 0;
- }
- nSelf++;
- } else
- nAuto++;
-
- switch (ans[0]) {
- case 'q':
- if ((freg = fopen(regfile, "a"))) {
- for (n = 0; field[n]; n++)
- fprintf(freg, "%s: %s\n", field[n], fdata[n]);
- fprintf(freg, "----\n");
- while (fgets(genbuf, STRLEN, fn))
- fputs(genbuf, freg);
- fclose(freg);
- }
- case 'd':
- break;
-
- case '0': case '1': case '2':
- case '3': case '4': case '5':
- /* please confirm match REJECT_REASONS here */
- case 'n':
- if (ans[0] == 'n') {
- int nf = 0;
- move(8, 0);
- clrtobot();
- outs("½Ð´£¥X°h¦^¥Ó½Ðªí­ì¦]¡A«ö <enter> ¨ú®ø\n");
- for (n = 0; n < REJECT_REASONS; n++)
- prints("%d) ½Ð%s\n", n, reason[n]);
- outs("\n"); // preserved for prompt
- for (nf = 0; field[nf]; nf++)
- prints("%s: %s\n", finfo[nf], fdata[nf]);
- } else
- buf[0] = ans[0];
-
- if (ans[0] != 'n' ||
- getdata(9 + n, 0, "°h¦^­ì¦]: ", buf, 60, DOECHO))
- if ((buf[0] - '0') >= 0 && (buf[0] - '0') < n) {
- int i;
- fileheader_t mhdr;
- char title[128], buf1[80];
- FILE *fp;
-
- sethomepath(buf1, muser.userid);
- stampfile(buf1, &mhdr);
- strlcpy(mhdr.owner, cuser.userid, sizeof(mhdr.owner));
- strlcpy(mhdr.title, "[µù¥U¥¢±Ñ]", TTLEN);
- mhdr.filemode = 0;
- sethomedir(title, muser.userid);
- if (append_record(title, &mhdr, sizeof(mhdr)) != -1) {
- char rejfn[PATHLEN];
- fp = fopen(buf1, "w");
-
- for(i = 0; buf[i] && i < sizeof(buf); i++){
- if (buf[i] >= '0' && buf[i] < '0'+n)
- {
- fprintf(fp, "[°h¦^­ì¦]] ½Ð%s\n",
- reason[buf[i] - '0']);
- }
- }
-
- fclose(fp);
-
- // build reject file
- sethomefile(rejfn, muser.userid, FN_REJECT_NOTIFY);
- Copy(buf1, rejfn);
- }
- if ((fout = fopen(FN_REGISTER_LOG, "a"))) {
- for (n = 0; field[n]; n++)
- fprintf(fout, "%s: %s\n", field[n], fdata[n]);
- fprintf(fout, "Date: %s\n", Cdate(&now));
- fprintf(fout, "Rejected: %s [%s]\n----\n",
- uid, buf);
- fclose(fout);
- }
- break;
- }
- move(10, 0);
- clrtobot();
- outs("¨ú®ø°h¦^¦¹µù¥U¥Ó½Ðªí");
- /* no break? */
-
- case 's':
- if ((freg = fopen(regfile, "a"))) {
- for (n = 0; field[n]; n++)
- fprintf(freg, "%s: %s\n", field[n], fdata[n]);
- fprintf(freg, "----\n");
- fclose(freg);
- }
- break;
-
- default:
- outs("¥H¤U¨Ï¥ÎªÌ¸ê®Æ¤w¸g§ó·s:\n");
- mail_muser(muser, "[µù¥U¦¨¥\\Åo]", "etc/registered");
-
-#if FOREIGN_REG_DAY > 0
- if(muser.uflag2 & FOREIGN)
- mail_muser(muser, "[¥X¤J¹ÒºÞ²z§½]", "etc/foreign_welcome");
-#endif
-
- muser.userlevel |= (PERM_LOGINOK | PERM_POST);
- strlcpy(muser.realname, fdata[1], sizeof(muser.realname));
- strlcpy(muser.address, fdata[3], sizeof(muser.address));
- strlcpy(muser.email, fdata[5], sizeof(muser.email));
- snprintf(genbuf, sizeof(genbuf), "%s:%s:%s",
- fdata[4], fdata[2], uid);
- strlcpy(muser.justify, genbuf, sizeof(muser.justify));
-
- passwd_update(unum, &muser);
- // XXX TODO notify users?
- sendalert(muser.userid, ALERT_PWD_PERM); // force to reload perm
-
- sethomefile(buf, muser.userid, FN_JUSTIFY);
- log_file(buf, LOG_CREAT, genbuf);
-
- if ((fout = fopen(FN_REGISTER_LOG, "a"))) {
- for (n = 0; field[n]; n++)
- fprintf(fout, "%s: %s\n", field[n], fdata[n]);
- fprintf(fout, "Date: %s\n", Cdate(&now));
- fprintf(fout, "Approved: %s\n", uid);
- fprintf(fout, "----\n");
- fclose(fout);
- }
- sethomefile(genbuf, muser.userid, FN_JUSTIFY_WAIT);
- unlink(genbuf);
- break;
- }
- }
- }
-
- fclose(fn);
- unlink(fname);
-
- clear(); move(5, 0);
- prints("±z¼f¤F %d ¥÷µù¥U³æ¡AAutoScan ¼f¤F %d ¥÷", nSelf, nAuto);
- pressanykey();
- return (0);
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// New Regform UI
-/////////////////////////////////////////////////////////////////////////////
-
-// #define REGFORM_DISABLE_ONLINE_USER
-// #define FORMS_IN_PAGE (10)
-
-int
-handle_register_form(const char *regfile, int dryrun)
-{
- int unum = 0;
- int yMsg = FORMS_IN_PAGE*2+1;
- FILE *fp = NULL;
- userec_t muser;
- RegformEntry forms [FORMS_IN_PAGE];
- char ans [FORMS_IN_PAGE];
- char rejects[FORMS_IN_PAGE][REASON_LEN]; // reject reason length
- char fname [PATHLEN] = "";
- char justify[REGLEN+1];
- char rsn [REASON_LEN];
- int cforms = 0, // current loaded forms
- parsed = 0, // total parsed forms
- ci = 0, // cursor index
- ch = 0, // input key
- i, blanks;
- long fsz = 0, fpos = 0;
-
- // prepare reg tickets
- if (dryrun)
- {
- // directly open regfile to try
- fp = fopen(regfile, "rt");
- } else {
- fp = pull_regform(regfile, fname, -1);
- }
-
- if (!fp)
- return 0;
-
- // retreieve file info
- fpos = ftell(fp);
- fseek(fp, 0, SEEK_END);
- fsz = ftell(fp);
- fseek(fp, fpos, SEEK_SET);
- if (!fsz) fsz = 1;
-
- while (ch != 'q')
- {
- // initialize and prepare
- memset(ans, 0, sizeof(ans));
- memset(rejects, 0, sizeof(rejects));
- memset(forms, 0, sizeof(forms));
- cforms = 0;
-
- // load forms
- while (cforms < FORMS_IN_PAGE && load_regform_entry(&forms[cforms], fp))
- cforms++, parsed ++;
-
- // if no more forms then leave.
- // TODO what if regform error?
- if (cforms < 1)
- break;
-
- // adjust cursor if required
- if (ci >= cforms)
- ci = cforms-1;
-
- // display them all.
- clear();
- for (i = 0; i < cforms; i++)
- {
- // fetch user information
- memset(&muser, 0, sizeof(muser));
- unum = getuser(forms[i].userid, &muser);
- forms[i].exist = unum ? 1 : 0;
- if (unum) forms[i].online = search_ulist(unum) ? 1 : 0;
-
- // if already got login level, delete by default.
- if (!unum)
- ans[i] = 'd';
- else {
- if (muser.userlevel & PERM_LOGINOK)
- ans[i] = 'd';
-#ifdef REGFORM_DISABLE_ONLINE_USER
- else if (forms[i].online)
- ans[i] = 's';
-#endif // REGFORM_DISABLE_ONLINE_USER
- }
-
- // print
- move(i*2, 0);
- prints(" %2d%s %s%-12s " ANSI_RESET,
- i+1,
- (unum == 0) ? ANSI_COLOR(1;31) "D" :
- ( (muser.userlevel & PERM_LOGINOK) ?
- ANSI_COLOR(1;33) "Y" :
-#ifdef REGFORM_DISABLE_ONLINE_USER
- forms[i].online ? "s" :
-#endif
- "."),
- forms[i].online ? ANSI_COLOR(1;35) : ANSI_COLOR(1),
- forms[i].userid);
-
- prints( ANSI_COLOR(1;31) "%19s "
- ANSI_COLOR(1;32) "%-40s" ANSI_RESET"\n",
- forms[i].name, forms[i].career);
-
- move(i*2+1, 0);
- prints(" %s %-50s%20s\n",
- (muser.userlevel & PERM_NOREGCODE) ?
- ANSI_COLOR(1;31) "T" ANSI_RESET : " ",
- forms[i].addr, forms[i].phone);
- }
-
- // display page info
- {
- char msg[STRLEN];
- fpos = ftell(fp);
- if (fpos > fsz) fsz = fpos*10;
- snprintf(msg, sizeof(msg),
- "%s ¤wÅã¥Ü %d ¥÷µù¥U³æ (%2d%%) ",
- dryrun? "(´ú¸Õ¼Ò¦¡)" : "",
- parsed, (int)(fpos*100/fsz));
- prints(ANSI_COLOR(7) "\n%78s" ANSI_RESET "\n", msg);
- }
-
- // handle user input
- prompt_regform_ui();
- ch = 0;
- while (ch != 'q' && ch != ' ') {
- ch = cursor_key(ci*2, 0);
- switch (ch)
- {
- // nav keys
- case KEY_UP:
- case 'k':
- if (ci > 0) ci--;
- break;
-
- case KEY_DOWN:
- case 'j':
- ch = 'j'; // go next
- break;
-
- // quick nav (assuming to FORMS_IN_PAGE=10)
- case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
- ci = ch - '1';
- if (ci >= cforms) ci = cforms-1;
- break;
- case '0':
- ci = 10-1;
- if (ci >= cforms) ci = cforms-1;
- break;
-
- /*
- case KEY_HOME: ci = 0; break;
- case KEY_END: ci = cforms-1; break;
- */
-
- // abort
- case KEY_END:
- case 'q':
- ch = 'q';
- if (getans("½T©w­nÂ÷¶}¤F¶Ü¡H (¥»­¶Åܧó±N¤£·|Àx¦s) [y/N]: ") != 'y')
- {
- prompt_regform_ui();
- ch = 0;
- continue;
- }
- break;
-
- // prepare to go next page
- case KEY_PGDN:
- case ' ':
- ch = ' ';
-
- // solving blank (undecided entries)
- for (i = 0, blanks = 0; i < cforms; i++)
- if (ans[i] == 0) blanks ++;
-
- if (!blanks)
- break;
-
- // have more blanks
- ch = getans("©|¥¼«ü©wªº %d ­Ó¶µ¥Ø­n: (S¸õ¹L/y³q¹L/n©Úµ´/eÄ~Äò½s¿è): ",
- blanks);
-
- if (ch == 'e')
- {
- prompt_regform_ui();
- ch = 0;
- continue;
- }
- if (ch == 'y') {
- // do nothing.
- } else if (ch == 'n') {
- // query reject reason
- resolve_reason(rsn, yMsg);
- if (*rsn == 0)
- ch = 's';
- } else ch = 's';
-
- // filling answers
- for (i = 0; i < cforms; i++)
- {
- if (ans[i] != 0)
- continue;
- ans[i] = ch;
- if (ch != 'n')
- continue;
- strlcpy(rejects[i], rsn, REASON_LEN);
- }
-
- ch = ' '; // go to page mode!
- break;
-
- // function keys
- case 'y': // accept
-#ifdef REGFORM_DISABLE_ONLINE_USER
- if (forms[ci].online)
- {
- vmsg("¼È¤£¶}©ñ¼f®Ö¦b½u¤W¨Ï¥ÎªÌ¡C");
- break;
- }
-#endif
- case 's': // skip
- case 'd': // delete
- case KEY_DEL: //delete
- if (ch == KEY_DEL) ch = 'd';
-
- grayout(ci*2, ci*2+1, GRAYOUT_DARK);
- move_ansi(ci*2, 4); outc(ch);
- ans[ci] = ch;
- ch = 'j'; // go next
- break;
-
- case 'u': // undo
-#ifdef REGFORM_DISABLE_ONLINE_USER
- if (forms[ci].online)
- {
- vmsg("¼È¤£¶}©ñ¼f®Ö¦b½u¤W¨Ï¥ÎªÌ¡C");
- break;
- }
-#endif
- grayout(ci*2, ci*2+1, GRAYOUT_NORM);
- move_ansi(ci*2, 4); outc('.');
- ans[ci] = 0;
- ch = 'j'; // go next
- break;
-
- case 'n': // reject
-#ifdef REGFORM_DISABLE_ONLINE_USER
- if (forms[ci].online)
- {
- vmsg("¼È¤£¶}©ñ¼f®Ö¦b½u¤W¨Ï¥ÎªÌ¡C");
- break;
- }
-#endif
- // query for reason
- resolve_reason(rejects[ci], yMsg);
- prompt_regform_ui();
-
- if (!rejects[ci][0])
- break;
-
- move(yMsg, 0);
- prints("°h¦^ %s µù¥U³æ­ì¦]:\n %s\n", forms[ci].userid, rejects[ci]);
-
- // do reject
- grayout(ci*2, ci*2+1, GRAYOUT_DARK);
- move_ansi(ci*2, 4); outc(ch);
- ans[ci] = ch;
- ch = 'j'; // go next
-
- break;
- } // switch(ch)
-
- // change cursor
- if (ch == 'j' && ++ci >= cforms)
- ci = cforms -1;
- } // while(ch != QUIT/SAVE)
-
- // if exit, we still need to skip all read forms
- if (ch == 'q')
- {
- for (i = 0; i < cforms; i++)
- ans[i] = 's';
- }
-
- // page complete (save).
- assert(ch == ' ' || ch == 'q');
-
- // save/commit if required.
- if (dryrun)
- {
- // prmopt for debug
- clear();
- stand_title("´ú¸Õ¼Ò¦¡");
- outs("±z¥¿¦b°õ¦æ´ú¸Õ¼Ò¦¡¡A©Ò¥H­è¼fªºµù¥U³æ¨Ã¤£·|¥Í®Ä¡C\n"
- "¤U­±¦C¥Xªº¬O­è¤~±z¼f§¹ªºµ²ªG:\n\n");
-
- for (i = 0; i < cforms; i++)
- {
- if (ans[i] == 'y')
- snprintf(justify, sizeof(justify), // build justify string
- "%s:%s:%s", forms[i].phone, forms[i].career, cuser.userid);
-
- prints("%2d. %-12s - %c %s\n", i+1, forms[i].userid, ans[i],
- ans[i] == 'n' ? rejects[i] :
- ans[i] == 'y' ? justify : "");
- }
- if (ch != 'q')
- pressanykey();
- }
- else
- {
- // real functionality
- for (i = 0; i < cforms; i++)
- {
- if (ans[i] == 'y')
- {
- // build justify string
- snprintf(justify, sizeof(justify),
- "%s:%s:%s", forms[i].phone, forms[i].career, cuser.userid);
-
- regform_accept(forms[i].userid, justify);
- // log form to FN_REGISTER_LOG
- append_regform(&forms[i], FN_REGISTER_LOG,
- "Approved", cuser.userid, NULL);
- }
- else if (ans[i] == 'n')
- {
- regform_reject(forms[i].userid, rejects[i]);
- // log form to FN_REGISTER_LOG
- append_regform(&forms[i], FN_REGISTER_LOG,
- "Rejected", cuser.userid, rejects[i]);
- }
- else if (ans[i] == 's')
- {
- // append form back to fn_register
- append_regform(&forms[i], fn_register,
- NULL, NULL, NULL);
- }
- }
- } // !dryrun
-
- } // while (ch != 'q')
-
- // cleaning left regforms
- if (!dryrun)
- {
- pump_regform(regfile, fp);
- fclose(fp);
- unlink(fname);
- } else {
- // directly close file should be OK.
- fclose(fp);
- }
-
- return 0;
-}
-
-int
-m_register(void)
-{
- FILE *fn;
- int x, y, wid, len;
- char ans[4];
- char genbuf[200];
-
- if ((fn = fopen(fn_register, "r")) == NULL) {
- outs("¥Ø«e¨ÃµL·sµù¥U¸ê®Æ");
- return XEASY;
- }
- stand_title("¼f®Ö¨Ï¥ÎªÌµù¥U¸ê®Æ");
- y = 2;
- x = wid = 0;
-
- while (fgets(genbuf, STRLEN, fn) && x < 65) {
- if (strncmp(genbuf, "uid: ", 5) == 0) {
- move(y++, x);
- outs(genbuf + 5);
- len = strlen(genbuf + 5);
- if (len > wid)
- wid = len;
- if (y >= t_lines - 3) {
- y = 2;
- x += wid + 2;
- }
- }
- }
- fclose(fn);
- getdata(b_lines - 1, 0,
- "¶}©l¼f®Ö¶Ü(Auto¦Û°Ê/Yes¤â°Ê/No¤£¼f/Exp·s¬É­±)¡H[N] ",
- ans, sizeof(ans), LCECHO);
- if (ans[0] == 'a')
- scan_register_form(fn_register, 1, NULL);
- else if (ans[0] == 'y')
- scan_register_form(fn_register, 0, NULL);
- else if (ans[0] == 'e')
- {
-#ifdef EXP_ADMIN_REGFORM_DRYRUN
- int dryrun = 0;
- if (getans("§A­n¶i¦æ¯Â´ú¸Õ(T)ÁÙ¬O¯uªº°õ¦æ¼f®Ö(y)¡H") == 'y')
- {
- vmsg("¶i¤J¹ê»Ú°õ¦æ¼Ò¦¡¡A©Ò¦³¼f®Ö°Ê§@³£¬O¯uªº¡C");
- dryrun = 0;
- } else {
- vmsg("´ú¸Õ¼Ò¦¡¡C");
- dryrun = 1;
- }
- handle_register_form(fn_register, dryrun);
-#else
- // run directly.
- handle_register_form(fn_register, 0);
-#endif
- }
-
- return 0;
-}
-
-int
-cat_register(void)
-{
- if (system("cat register.new.tmp >> register.new") == 0 &&
- unlink("register.new.tmp") == 0)
- vmsg("OK ÂP~~ Ä~Äò¥h¾Ä°«§a!!");
- else
- vmsg("¨S¿ìªkCAT¹L¥h©O ¥hÀˬd¤@¤U¨t²Î§a!!");
- return 0;
-}
-
-/* vim:sw=4
- */
diff --git a/mbbsd/reversi.c b/mbbsd/reversi.c
deleted file mode 100644
index ea64f35a..00000000
--- a/mbbsd/reversi.c
+++ /dev/null
@@ -1,513 +0,0 @@
-/* $Id$ */
-
-#include "bbs.h"
-
-#define MAX_TIME (300)
-#define BRDSIZ (8) /* ´Ñ½L³æÃä¤j¤p */
-
-#define NONE_CHESS " "
-#define WHITE_CHESS "¡´"
-#define BLACK_CHESS "¡³"
-#define HINT_CHESS "¡­"
-#define NONE 0
-#define HINT 1
-#define BLACK 2
-#define WHITE 3
-
-#define STARTY 10
-
-#define INVERT(COLOR) (((COLOR))==WHITE?BLACK:WHITE)
-
-#define IS_BLANK(COLOR) ((COLOR) < BLACK) /* NONE or HINT */
-#define IS_CHESS(COLOR) ((COLOR) >= BLACK)
-#define TURN_TO_COLOR(TURN) (WHITE - (TURN))
-#define COLOR_TO_TURN(COLOR) (WHITE - (COLOR))
-
-typedef char color_t;
-typedef color_t board_t[BRDSIZ + 2][BRDSIZ + 2];
-typedef color_t (*board_p)[BRDSIZ + 2];
-/* [0] & [9] are dummy */
-
-typedef struct {
- ChessStepType type; /* necessary one */
- color_t color;
- rc_t loc;
-} reversi_step_t;
-
-typedef struct {
- int number[2];
-} reversi_tag_t;
-
-/* chess framework action functions */
-static void reversi_init_user(const userinfo_t *uinfo, ChessUser *user);
-static void reversi_init_user_userec(const userec_t *urec, ChessUser *user);
-static void reversi_init_board(board_t board);
-static void reversi_drawline(const ChessInfo* info, int line);
-static void reversi_movecur(int r, int c);
-static int reversi_prepare_play(ChessInfo* info);
-static int reversi_select(ChessInfo* info, rc_t scrloc, ChessGameResult* result);
-static void reversi_prepare_step(ChessInfo* info, const reversi_step_t* step);
-static ChessGameResult reversi_apply_step(board_t board, const reversi_step_t* step);
-static void reversi_drawstep(ChessInfo* info, const void* move);
-static ChessGameResult reversi_post_game(ChessInfo* info);
-static void reversi_gameend(ChessInfo* info, ChessGameResult result);
-static void reversi_genlog(ChessInfo* info, FILE* fp, ChessGameResult result);
-
-static const char *CHESS_TYPE[] = {NONE_CHESS, HINT_CHESS, BLACK_CHESS, WHITE_CHESS};
-static const char DIRX[] = {-1, -1, -1, 0, 1, 1, 1, 0};
-static const char DIRY[] = {-1, 0, 1, 1, 1, 0, -1, -1};
-
-static const ChessActions reversi_actions = {
- &reversi_init_user,
- &reversi_init_user_userec,
- (void (*) (void*)) &reversi_init_board,
- &reversi_drawline,
- &reversi_movecur,
- &reversi_prepare_play,
- NULL, /* process_key */
- &reversi_select,
- (void (*)(ChessInfo*, const void*)) &reversi_prepare_step,
- (ChessGameResult (*)(void*, const void*)) &reversi_apply_step,
- &reversi_drawstep,
- &reversi_post_game,
- &reversi_gameend,
- &reversi_genlog
-};
-
-const static ChessConstants reversi_constants = {
- sizeof(reversi_step_t),
- MAX_TIME,
- BRDSIZ,
- BRDSIZ,
- 0,
- "¶Â¥Õ´Ñ",
- "photo_reversi",
-#ifdef GLOBAL_REVERSI_LOG
- GLOBAL_REVERSI_LOG,
-#else
- NULL,
-#endif
- { "", "" },
- { "¥Õ´Ñ", "¶Â´Ñ" },
-};
-
-static int
-can_put(board_t board, color_t who, int x, int y)
-{
- int i, temp, checkx, checky;
-
- if (IS_BLANK(board[x][y]))
- for (i = 0; i < 8; ++i) {
- checkx = x + DIRX[i];
- checky = y + DIRY[i];
- temp = board[checkx][checky];
- if (IS_BLANK(temp))
- continue;
- if (temp != who) {
- while (board[checkx += DIRX[i]][checky += DIRY[i]] == temp);
- if (board[checkx][checky] == who)
- return 1;
- }
- }
- return 0;
-}
-
-static int
-caculate_hint(board_t board, color_t who)
-{
- int i, j, count = 0;
-
- for (i = 1; i <= 8; i++)
- for (j = 1; j <= 8; j++) {
- if (board[i][j] == HINT)
- board[i][j] = NONE;
- if (can_put(board, who, i, j)) {
- board[i][j] = HINT;
- ++count;
- }
- }
- return count;
-}
-
-static void
-reversi_init_user(const userinfo_t* uinfo, ChessUser* user)
-{
- strlcpy(user->userid, uinfo->userid, sizeof(user->userid));
- user->win =
- user->lose =
- user->tie = 0;
-}
-
-static void
-reversi_init_user_userec(const userec_t* urec, ChessUser* user)
-{
- strlcpy(user->userid, urec->userid, sizeof(user->userid));
- user->win =
- user->lose =
- user->tie = 0;
-}
-
-static void
-reversi_init_board(board_t board)
-{
- memset(board, NONE, sizeof(board_t));
- board[4][4] = board[5][5] = WHITE;
- board[4][5] = board[5][4] = BLACK;
-
- caculate_hint(board, BLACK);
-}
-
-static void
-reversi_drawline(const ChessInfo* info, int line){
- static const char* num_str[] =
- {"", "¢°", "¢±", "¢²", "¢³", "¢´", "¢µ", "¢¶", "¢·"};
- if(line)
- move(line, STARTY);
-
- if (line == 0) {
- prints(ANSI_COLOR(1;46) " ¶Â¥Õ´Ñ¹ï¾Ô " ANSI_COLOR(45)
- "%30s VS %-20s%10s" ANSI_RESET,
- info->user1.userid, info->user2.userid,
- info->mode == CHESS_MODE_WATCH ? "[Æ[´Ñ¼Ò¦¡]" : "");
- } else if (line == 2)
- outs(" ¢Ï ¢Ð ¢Ñ ¢Ò ¢Ó ¢Ô ¢Õ ¢Ö");
- else if (line == 3)
- outs("¢z¢w¢s¢w¢s¢w¢s¢w¢s¢w¢s¢w¢s¢w¢s¢w¢{");
- else if (line == 19)
- outs("¢|¢w¢r¢w¢r¢w¢r¢w¢r¢w¢r¢w¢r¢w¢r¢w¢}");
- else if (line == 20)
- prints(" (" BLACK_CHESS ") %-15s%2d%*s",
- info->myturn ? info->user1.userid : info->user2.userid,
- ((reversi_tag_t*)info->tag)->number[COLOR_TO_TURN(BLACK)],
- 34 - 24, "");
- else if (line == 21)
- prints(" (" WHITE_CHESS ") %-15s%2d%*s",
- info->myturn ? info->user2.userid : info->user1.userid,
- ((reversi_tag_t*)info->tag)->number[COLOR_TO_TURN(WHITE)],
- 34 - 24, "");
- else if (line > 3 && line < 19) {
- if ((line & 1) == 1)
- outs("¢u¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢t");
- else {
- int x = line / 2 - 1;
- int y;
- board_p board = (board_p) info->board;
-
- move(line, STARTY - 2);
- prints("%s¢x", num_str[x]);
- for(y = 1; y <= 8; ++y)
- prints("%s¢x", CHESS_TYPE[(int) board[x][y]]);
- }
- }
-
- ChessDrawExtraInfo(info, line, 4);
-}
-
-static void
-reversi_movecur(int r, int c)
-{
- move(r * 2 + 4, c * 4 + STARTY + 2);
-}
-
-static int
-reversi_prepare_play(ChessInfo* info)
-{
- int x, y;
- int result;
- board_p board = (board_p) info->board;
- reversi_tag_t* tag = (reversi_tag_t*) info->tag;
-
- tag->number[0] = tag->number[1] = 0;
- for(x = 1; x <= 8; ++x)
- for(y = 1; y <= 8; ++y)
- if (IS_CHESS(board[x][y]))
- ++tag->number[COLOR_TO_TURN(board[x][y])];
-
- result = !caculate_hint(board, TURN_TO_COLOR(info->turn));
- if (result) {
- reversi_step_t step = { CHESS_STEP_SPECIAL, TURN_TO_COLOR(info->turn) };
- if (info->turn == info->myturn) {
- ChessStepSend(info, &step);
- ChessHistoryAppend(info, &step);
- strcpy(info->last_movestr, "§A¥²¶·©ñ±ó³o¤@¨B!!");
- } else {
- ChessStepReceive(info, &step);
- strcpy(info->last_movestr, "¹ï¤è¥²¶·©ñ±ó³o¤@¨B!!");
- }
- }
-
- ChessRedraw(info);
- return result;
-}
-
-static int
-reversi_select(ChessInfo* info, rc_t loc, ChessGameResult* result)
-{
- board_p board = (board_p) info->board;
-
- ++loc.r; ++loc.c;
- if (can_put(board, TURN_TO_COLOR(info->turn), loc.r, loc.c)) {
- reversi_step_t step = { CHESS_STEP_NORMAL,
- TURN_TO_COLOR(info->turn), loc };
- reversi_apply_step(board, &step);
-
- snprintf(info->last_movestr, sizeof(info->last_movestr),
- "%c%d", step.loc.c - 1 + 'A', step.loc.r);
-
- ChessStepSend(info, &step);
- ChessHistoryAppend(info, &step);
-
- return 1;
- } else
- return 0;
-}
-
-static ChessGameResult
-reversi_apply_step(board_t board, const reversi_step_t* step)
-{
- int i;
- color_t opposite = INVERT(step->color);
-
- if (step->type != CHESS_STEP_NORMAL)
- return CHESS_RESULT_CONTINUE;
-
- for (i = 0; i < 8; ++i) {
- int x = step->loc.r;
- int y = step->loc.c;
-
- while (board[x += DIRX[i]][y += DIRY[i]] == opposite);
-
- if (board[x][y] == step->color) {
- x = step->loc.r;
- y = step->loc.c;
-
- while (board[x += DIRX[i]][y += DIRY[i]] == opposite)
- board[x][y] = step->color;
- }
- }
- board[step->loc.r][step->loc.c] = step->color;
-
- return CHESS_RESULT_CONTINUE;
-}
-
-static void
-reversi_prepare_step(ChessInfo* info, const reversi_step_t* step)
-{
- if (step->type == CHESS_STEP_NORMAL)
- snprintf(info->last_movestr, sizeof(info->last_movestr),
- "%c%d", step->loc.c - 1 + 'A', step->loc.r);
- else if (step->color == TURN_TO_COLOR(info->myturn))
- strcpy(info->last_movestr, "§A¥²¶·©ñ±ó³o¤@¨B!!");
- else
- strcpy(info->last_movestr, "¹ï¤è¥²¶·©ñ±ó³o¤@¨B!!");
-}
-
-static void
-reversi_drawstep(ChessInfo* info, const void* move)
-{
- ChessRedraw(info);
-}
-
-static ChessGameResult
-reversi_post_game(ChessInfo* info)
-{
- int x, y;
- board_p board = (board_p) info->board;
- reversi_tag_t* tag = (reversi_tag_t*) info->tag;
-
- tag->number[0] = tag->number[1] = 0;
- for(x = 1; x <= 8; ++x)
- for(y = 1; y <= 8; ++y)
- if (board[x][y] == HINT)
- board[x][y] = NONE;
- else if (IS_CHESS(board[x][y]))
- ++tag->number[COLOR_TO_TURN(board[x][y])];
-
- ChessRedraw(info);
-
- if (tag->number[0] == tag->number[1])
- return CHESS_RESULT_TIE;
- else if (tag->number[(int) info->myturn] < tag->number[info->myturn ^ 1])
- return CHESS_RESULT_LOST;
- else
- return CHESS_RESULT_WIN;
-}
-
-static void
-reversi_gameend(ChessInfo* info, ChessGameResult result)
-{
- /* nothing to do now
- * TODO game record */
-}
-
-static void
-reversi_genlog(ChessInfo* info, FILE* fp, ChessGameResult result)
-{
- char buf[ANSILINELEN] = "";
- const int nStep = info->history.used;
- int i, x, y;
-
- getyx(&y, &x);
- for (i = 2; i <= 21; i++)
- {
- move(i, 0);
- inansistr(buf, sizeof(buf)-1);
- fprintf(fp, "%s\n", buf);
- }
- move(y, x);
-
- fprintf(fp, "\n");
- fprintf(fp, "«ö z ¥i¶i¤J¥´ÃмҦ¡\n");
- fprintf(fp, "\n");
-
- fprintf(fp, "<reversilog>\nblack:%s\nwhite:%s\n",
- info->myturn ? info->user1.userid : info->user2.userid,
- info->myturn ? info->user2.userid : info->user1.userid);
-
- for (i = 0; i < nStep; ++i) {
- const reversi_step_t* const step =
- (const reversi_step_t*) ChessHistoryRetrieve(info, i);
- if (step->type == CHESS_STEP_NORMAL)
- fprintf(fp, "[%2d]%s ==> %c%-5d", i + 1,
- CHESS_TYPE[(int) step->color],
- 'A' + step->loc.c - 1, step->loc.r);
- else
- fprintf(fp, "[%2d]%s ==> pass ", i + 1,
- CHESS_TYPE[(int) step->color]);
- if (i % 2)
- fputc('\n', fp);
- }
-
- if (i % 2)
- fputc('\n', fp);
- fputs("</reversilog>\n", fp);
-}
-
-static int
-reversi_loadlog(FILE *fp, ChessInfo *info)
-{
- char buf[256];
-
-#define INVALID_ROW(R) ((R) <= 0 || (R) > 8)
-#define INVALID_COL(C) ((C) <= 0 || (C) > 8)
- while (fgets(buf, sizeof(buf), fp)) {
- if (strcmp("</reversilog>\n", buf) == 0)
- return 1;
- else if (strncmp("black:", buf, 6) == 0 ||
- strncmp("white:", buf, 6) == 0) {
- /* /(black|white):([a-zA-Z0-9]+)/; $2 */
- userec_t rec;
- ChessUser *user = (buf[0] == 'b' ? &info->user1 : &info->user2);
-
- chomp(buf);
- if (getuser(buf + 6, &rec))
- reversi_init_user_userec(&rec, user);
- } else if (buf[0] == '[') {
- /* "[ 1]¡´ ==> C4 [ 2]¡³ ==> C5" */
- reversi_step_t step = { CHESS_STEP_NORMAL };
- int c, r;
- const char *p = buf;
- int i;
-
- for(i=0; i<2; i++) {
- p = strchr(p, '>');
-
- if (p == NULL) break;
-
- ++p; /* skip '>' */
- while (*p && isspace(*p)) ++p;
- if (!*p) break;
-
- /* i=0, p -> "C4 ..." */
- /* i=1, p -> "C5\n" */
-
- if (strncmp(p, "pass", 4) == 0)
- /* [..] .. => pass */
- step.type = CHESS_STEP_SPECIAL;
- else {
- c = p[0] - 'A' + 1;
- r = atoi(p + 1);
-
- if (INVALID_COL(c) || INVALID_ROW(r))
- break;
-
- step.loc.r = r;
- step.loc.c = c;
- }
-
- step.color = i==0 ? BLACK : WHITE;
- ChessHistoryAppend(info, &step);
- }
- }
- }
-#undef INVALID_ROW
-#undef INVALID_COL
- return 0;
-}
-
-void
-reversi(int s, ChessGameMode mode)
-{
- ChessInfo* info = NewChessInfo(&reversi_actions, &reversi_constants, s, mode);
- board_t board;
- reversi_tag_t tag = { { 2, 2 } }; /* will be overridden */
-
- reversi_init_board(board);
-
- info->board = board;
- info->tag = &tag;
-
- info->cursor.r = 3;
- info->cursor.c = 3;
-
- if (mode == CHESS_MODE_WATCH)
- setutmpmode(CHESSWATCHING);
- else
- setutmpmode(REVERSI);
- currutmp->sig = SIG_REVERSI;
-
- ChessPlay(info);
-
- DeleteChessInfo(info);
-}
-
-int
-reversi_main(void)
-{
- return ChessStartGame('r', SIG_REVERSI, "¶Â¥Õ´Ñ");
-}
-
-int
-reversi_personal(void)
-{
- reversi(0, CHESS_MODE_PERSONAL);
- return 0;
-}
-
-int
-reversi_watch(void)
-{
- return ChessWatchGame(&reversi, REVERSI, "¶Â¥Õ´Ñ");
-}
-
-ChessInfo*
-reversi_replay(FILE* fp)
-{
- ChessInfo *info;
-
- info = NewChessInfo(&reversi_actions, &reversi_constants,
- 0, CHESS_MODE_REPLAY);
-
- if(!reversi_loadlog(fp, info)) {
- DeleteChessInfo(info);
- return NULL;
- }
-
- info->board = malloc(sizeof(board_t));
- info->tag = malloc(sizeof(reversi_tag_t));
-
- reversi_init_board(info->board);
- /* tag will be initialized later */
-
- return info;
-}
diff --git a/mbbsd/screen.c b/mbbsd/screen.c
deleted file mode 100644
index 8b518070..00000000
--- a/mbbsd/screen.c
+++ /dev/null
@@ -1,819 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-#if !defined(USE_PFTERM)
-
-#define o_clear() output(clearbuf,clearbuflen)
-#define o_cleol() output(cleolbuf,cleolbuflen)
-#define o_scrollrev() output(scrollrev,scrollrevlen)
-#define o_standup() output(strtstandout,strtstandoutlen)
-#define o_standdown() output(endstandout,endstandoutlen)
-
-static unsigned short cur_ln = 0, cur_col = 0;
-static unsigned char docls;
-static unsigned char standing = NA;
-static int scrollcnt, tc_col, tc_line;
-static unsigned char _typeahead = 1;
-
-#define MODIFIED (1) /* if line has been modifed, screen output */
-#define STANDOUT (2) /* if this line has a standout region */
-
-void
-initscr(void)
-{
- if (!big_picture) {
- big_picture = (screenline_t *) calloc(scr_lns, sizeof(screenline_t));
- docls = YEA;
- }
-}
-
-int
-resizeterm(int w, int h)
-{
- screenline_t *new_picture;
-
- /* make sure reasonable size */
- h = MAX(24, MIN(100, h));
- w = MAX(80, MIN(200, w));
-
- if (h > t_lines && big_picture) {
- new_picture = (screenline_t *)
- calloc(h, sizeof(screenline_t));
- if (new_picture == NULL) {
- syslog(LOG_ERR, "calloc(): %m");
- return 0;
- }
- memcpy(new_picture, big_picture, t_lines * sizeof(screenline_t));
- free(big_picture);
- big_picture = new_picture;
- return 1;
- }
- return 0;
-}
-
-void
-move(int y, int x)
-{
- if (y < 0) y = 0;
- if (y >= t_lines) y = t_lines -1;
- if (x < 0) x = 0;
- if (x >= ANSILINELEN) x = ANSILINELEN -1;
- // assert(y>=0);
- // assert(x>=0);
- cur_col = x;
- cur_ln = y;
-}
-
-void
-move_ansi(int y, int x)
-{
- // take ANSI length in consideration
- register screenline_t *slp;
- if (y < 0) y = 0;
- if (y >= t_lines) y = t_lines -1;
- if (x < 0) x = 0;
- if (x >= ANSILINELEN) x = ANSILINELEN -1;
-
- cur_ln = y;
- cur_col = x;
-
- if (y >= scr_lns || x < 1)
- return;
-
- slp = &big_picture[y];
- if (slp->len < 1)
- return;
-
- slp->data[slp->len] = 0;
- x += (strlen((char*)slp->data) - strlen_noansi((char*)slp->data));
- cur_col = x;
-}
-
-void
-getyx(int *y, int *x)
-{
- *y = cur_ln;
- *x = cur_col;
-}
-
-void
-getyx_ansi(int *py, int *px)
-{
- // take ANSI length in consideration
- register screenline_t *slp;
- int y = cur_ln, x = cur_col;
- char c = 0;
-
- if (y < 0) y = 0;
- if (y >= t_lines) y = t_lines -1;
- if (x < 0) x = 0;
- if (x >= ANSILINELEN) x = ANSILINELEN -1;
-
- *py = y; *px = x;
-
- if (y >= scr_lns || x < 1)
- return;
-
- slp = &big_picture[y];
- if (slp->len < 1)
- return;
- c = slp->data[x];
- *px += (strlen((char*)slp->data) - strlen_noansi((char*)slp->data));
- slp->data[x] = c;
-}
-
-static inline
-screenline_t* GetCurrentLine(){
- register int i = cur_ln + roll;
- if(i >= scr_lns)
- i %= scr_lns;
- return &big_picture[i];
-}
-
-static void
-rel_move(int was_col, int was_ln, int new_col, int new_ln)
-{
- if (new_ln >= t_lines || new_col >= t_columns)
- return;
-
- tc_col = new_col;
- tc_line = new_ln;
- if (new_col == 0) {
- if (new_ln == was_ln) {
- if (was_col)
- ochar('\r');
- return;
- } else if (new_ln == was_ln + 1) {
- ochar('\n');
- if (was_col)
- ochar('\r');
- return;
- }
- }
- if (new_ln == was_ln) {
- if (was_col == new_col)
- return;
-
- if (new_col == was_col - 1) {
- ochar(Ctrl('H'));
- return;
- }
- }
- do_move(new_col, new_ln);
-}
-
-static void
-standoutput(const char *buf, int ds, int de, int sso, int eso)
-{
- int st_start, st_end;
-
- if (eso <= ds || sso >= de) {
- output(buf + ds, de - ds);
- } else {
- st_start = MAX(sso, ds);
- st_end = MIN(eso, de);
- if (sso > ds)
- output(buf + ds, sso - ds);
- o_standup();
- output(buf + st_start, st_end - st_start);
- o_standdown();
- if (de > eso)
- output(buf + eso, de - eso);
- }
-}
-
-void
-redrawwin(void)
-{
- register screenline_t *bp;
- register int i, j;
- int len;
-
- o_clear();
- for (tc_col = tc_line = i = 0, j = roll; i < scr_lns; i++, j++) {
- if (j >= scr_lns)
- j = 0;
- bp = &big_picture[j];
- if ((len = bp->len)) {
- rel_move(tc_col, tc_line, 0, i);
-
-#ifdef DBCSAWARE
- if (!(bp->mode & STANDOUT) &&
- (cuser.uflag & DBCS_NOINTRESC) &&
- DBCS_RemoveIntrEscape(bp->data, &len))
- {
- // if anything changed, dirty whole line.
- bp->len = len;
- }
-#endif // DBCSAWARE
-
- if (bp->mode & STANDOUT) {
- standoutput((char *)bp->data, 0, len, bp->sso, bp->eso);
- }
- else
- output((char *)bp->data, len);
- tc_col += len;
- if (tc_col >= t_columns) {
- if (automargins)
- tc_col = t_columns - 1;
- else {
- tc_col -= t_columns;
- tc_line++;
- if (tc_line >= t_lines)
- tc_line = b_lines;
- }
- }
- bp->mode &= ~(MODIFIED);
- bp->oldlen = len;
- }
- }
- rel_move(tc_col, tc_line, cur_col, cur_ln);
- docls = scrollcnt = 0;
- oflush();
-}
-
-int
-typeahead(int fd)
-{
- switch(fd)
- {
- case TYPEAHEAD_NONE:
- _typeahead = 0;
- break;
- case TYPEAHEAD_STDIN:
- _typeahead = 1;
- break;
- default: // shall never reach here
- assert(NULL);
- break;
- }
- return 0;
-}
-
-void
-refresh(void)
-{
- if (num_in_buf() && _typeahead)
- return;
- doupdate();
-}
-
-void
-doupdate(void)
-{
- /* TODO remove unnecessary refresh() call, to save CPU time */
- register screenline_t *bp = big_picture;
- register int i, j;
- int len;
- if ((docls) || (abs(scrollcnt) >= (scr_lns - 3))) {
- redrawwin();
- return;
- }
- if (scrollcnt < 0) {
- if (!scrollrevlen) {
- redrawwin();
- return;
- }
- rel_move(tc_col, tc_line, 0, 0);
- do {
- o_scrollrev();
- } while (++scrollcnt);
- } else if (scrollcnt > 0) {
- rel_move(tc_col, tc_line, 0, b_lines);
- do {
- ochar('\n');
- } while (--scrollcnt);
- }
- for (i = 0, j = roll; i < scr_lns; i++, j++) {
- if (j >= scr_lns)
- j = 0;
- bp = &big_picture[j];
- len = bp->len;
-
- if (bp->mode & MODIFIED && bp->smod < len)
- {
- bp->mode &= ~(MODIFIED);
-
-#ifdef DBCSAWARE
- if (!(bp->mode & STANDOUT) &&
- (cuser.uflag & DBCS_NOINTRESC) &&
- DBCS_RemoveIntrEscape(bp->data, &len))
- {
- // if anything changed, dirty whole line.
- bp->len = len;
- bp->smod = 0; bp->emod = len;
- }
-#endif // DBCSAWARE
-
-#if 0
- // disabled now, bugs:
- // (1) input number (goto) in bbs list (search_num)
- // (2) some empty lines becomes weird (eg, b_config)
- //
- // more effort to determine ANSI smod
- if (bp->smod > 0)
- {
- int iesc;
- for (iesc = bp->smod-1; iesc >= 0; iesc--)
- {
- if (bp->data[iesc] == ESC_CHR)
- {
- bp->smod = 0;// iesc;
- bp->emod =len -1;
- break;
- }
- }
- }
-#endif
-
- if (bp->emod >= len)
- bp->emod = len - 1;
- rel_move(tc_col, tc_line, bp->smod, i);
-
- if (bp->mode & STANDOUT)
- standoutput((char *)bp->data, bp->smod, bp->emod + 1,
- bp->sso, bp->eso);
- else
- output((char *)&bp->data[bp->smod], bp->emod - bp->smod + 1);
- tc_col = bp->emod + 1;
- if (tc_col >= t_columns) {
- if (automargins)
- tc_col = t_columns - 1;
- else {
- tc_col -= t_columns;
- tc_line++;
- if (tc_line >= t_lines)
- tc_line = b_lines;
- }
- }
- }
- if (bp->oldlen > len) {
- /* XXX len/oldlen also count the length of escape sequence,
- * before we fix it, we must print ANSI_CLRTOEND everywhere */
- rel_move(tc_col, tc_line, len, i);
- o_cleol();
- }
- bp->oldlen = len;
- }
-
- rel_move(tc_col, tc_line, cur_col, cur_ln);
-
- oflush();
-}
-
-void
-clear(void)
-{
- register screenline_t *slp;
-
- register int i;
-
- docls = YEA;
- cur_col = cur_ln = roll = 0;
- for(i=0; i<scr_lns; i++) {
- slp = &big_picture[i];
- slp->mode = slp->len = slp->oldlen = 0;
- }
-}
-
-void
-clrtoeol(void)
-{
- register screenline_t *slp = GetCurrentLine();
- register int ln;
-
- standing = NA;
-
- if (cur_col <= slp->sso)
- slp->mode &= ~STANDOUT;
-
- /*
- if (cur_col == 0) // TODO and contains ANSI
- {
- // workaround poor ANSI issue
- size_t sz = (slp->len > slp->oldlen) ? slp->len : slp->oldlen;
- sz = (sz < ANSILINELEN) ? sz : ANSILINELEN;
- memset(slp->data, ' ', sz);
- slp->len = 0;
- return;
- }
- */
-
- if (cur_col > slp->oldlen) {
- for (ln = slp->len; ln <= cur_col; ln++)
- slp->data[ln] = ' ';
- }
- if (cur_col < slp->oldlen) {
- for (ln = slp->len; ln >= cur_col; ln--)
- slp->data[ln] = ' ';
- }
- slp->len = cur_col;
-}
-
-
-void newwin (int nlines, int ncols, int y, int x)
-{
- int i=0, oy, ox;
- getyx(&oy, &ox);
-
- while (nlines-- > 0)
- {
- move_ansi(y++, x);
- for (i = 0; i < ncols; i++)
- outc(' ');
- }
- move(oy, ox);
-}
-
-/**
- * ±q¥Ø«eªº¦æ¼Æ(scr_ln) clear ¨ì²Ä line ¦æ
- */
-void
-clrtoln(int line)
-{
- register screenline_t *slp;
- register int i, j;
-
- for (i = cur_ln, j = i + roll; i < line; i++, j++) {
- if (j >= scr_lns)
- j -= scr_lns;
- slp = &big_picture[j];
- slp->mode = slp->len = 0;
- if (slp->oldlen)
- slp->oldlen = scr_cols;
- }
-}
-
-/**
- * ±q¥Ø«eªº¦æ¼Æ(scr_ln) clear ¨ì©³
- */
-inline void
-clrtobot(void)
-{
- clrtoln(scr_lns);
-}
-
-void
-outc(unsigned char c)
-{
- register screenline_t *slp = GetCurrentLine();
- register int i;
-
- // 0xFF is invalid for most cases (even DBCS),
- if (c == 0xFF || c == 0x00)
- return;
-
- if (c == '\n' || c == '\r') {
- if (standing) {
- slp->eso = MAX(slp->eso, cur_col);
- standing = NA;
- }
- if ((i = cur_col - slp->len) > 0)
- memset(&slp->data[slp->len], ' ', i + 1);
- slp->len = cur_col;
- cur_col = 0;
- if (cur_ln < scr_lns)
- cur_ln++;
- return;
- }
- /*
- * else if(c != ESC_CHR && !isprint2(c)) { c = '*'; //substitute a '*' for
- * non-printable }
- */
- if (cur_col >= slp->len) {
- for (i = slp->len; i < cur_col; i++)
- slp->data[i] = ' ';
- slp->data[cur_col] = '\0';
- slp->len = cur_col + 1;
- }
-
- if (slp->data[cur_col] != c) {
- slp->data[cur_col] = c;
- if (!(slp->mode & MODIFIED))
- slp->smod = slp->emod = cur_col;
- slp->mode |= MODIFIED;
- if (cur_col > slp->emod)
- slp->emod = cur_col;
- if (cur_col < slp->smod)
- slp->smod = cur_col;
- }
-#if 1
- if(cur_col < scr_cols)
- cur_col++;
-#else
- /* vvv commented by piaip: but SCR_COLS is 511 > unsigned char! */
- /* this comparison is always false (cur_col is unsigned char and scr_cols
- * is 511). */
- if (++cur_col >= scr_cols) {
- if (standing && (slp->mode & STANDOUT)) {
- standing = 0;
- slp->eso = MAX(slp->eso, cur_col);
- }
- cur_col = 0;
- if (cur_ln < scr_lns)
- cur_ln++;
- }
-#endif
-}
-
-void
-outs(const char *str)
-{
- if (!str)
- return;
- while (*str) {
- outc(*str++);
- }
-}
-
-void
-outns(const char *str, int n)
-{
- if (!str)
- return;
- while (*str && n-- > 0) {
- outc(*str++);
- }
-}
-
-void
-outstr(const char *str)
-{
- // XXX TODO cannot prepare DBCS-ready environment?
-
- outs(str);
-}
-
-void
-addch(unsigned char c)
-{
- outc(c);
-}
-
-void
-addstr(const char *s)
-{
- outs(s);
-}
-
-void
-addnstr(const char *s, int n)
-{
- outns(s, n);
-}
-
-void
-addstring(const char *s)
-{
- outs(s);
-}
-
-
-void
-scroll(void)
-{
- scrollcnt++;
- if (++roll >= scr_lns)
- roll = 0;
- move(b_lines, 0);
- clrtoeol();
-}
-
-void
-rscroll(void)
-{
- scrollcnt--;
- if (--roll < 0)
- roll = b_lines;
- move(0, 0);
- clrtoeol();
-}
-
-void
-region_scroll_up(int top, int bottom)
-{
- int i;
-
- if (top > bottom) {
- i = top;
- top = bottom;
- bottom = i;
- }
- if (top < 0 || bottom >= scr_lns)
- return;
-
- for (i = top; i < bottom; i++)
- big_picture[i] = big_picture[i + 1];
- memset(big_picture + i, 0, sizeof(*big_picture));
- memset(big_picture[i].data, ' ', scr_cols);
- save_cursor();
- change_scroll_range(top, bottom);
- do_move(0, bottom);
- scroll_forward();
- change_scroll_range(0, scr_lns - 1);
- restore_cursor();
- refresh();
-}
-
-void
-standout(void)
-{
- if (!standing && strtstandoutlen) {
- register screenline_t *slp;
-
- slp = GetCurrentLine();
- standing = YEA;
- slp->sso = slp->eso = cur_col;
- slp->mode |= STANDOUT;
- }
-}
-
-void
-standend(void)
-{
- if (standing && strtstandoutlen) {
- register screenline_t *slp;
-
- slp = GetCurrentLine();
- standing = NA;
- slp->eso = MAX(slp->eso, cur_col);
- }
-}
-
-// readback
-int
-instr(char *str)
-{
- register screenline_t *slp = GetCurrentLine();
- *str = 0;
- if (!slp)
- return 0;
- slp->data[slp->len] = 0;
- strip_ansi(str, (char*)slp->data, STRIP_ALL);
- return strlen(str);
-}
-
-int
-innstr(char *str, int n)
-{
- register screenline_t *slp = GetCurrentLine();
- char buf[ANSILINELEN];
- *str = 0;
- if (!slp)
- return 0;
- slp->data[slp->len] = 0;
- strip_ansi(buf, (char*)slp->data, STRIP_ALL);
- buf[ANSILINELEN] = 0;
- strlcpy(str, buf, n);
- return strlen(str);
-}
-
-int
-inansistr(char *str, int n)
-{
- register screenline_t *slp = GetCurrentLine();
- *str = 0;
- if (!slp)
- return 0;
- slp->data[slp->len] = 0;
- strlcpy(str, (char*)slp->data, n);
- return strlen(str);
-}
-
-// level:
-// -1 - bold out
-// 0 - dark text
-// 1 - text
-// 2 - no highlight (not implemented)
-void
-grayout(int y, int end, int level)
-{
- register screenline_t *slp = NULL;
- char buf[ANSILINELEN];
- int i = 0;
-
- if (y < 0) y = 0;
- if (end > b_lines) end = b_lines;
-
- // TODO change to y <= end someday
- // loop lines
- for (; y <= end; y ++)
- {
- // modify by scroll
- i = y + roll;
- if (i < 0)
- i += scr_lns;
- else if (i >= scr_lns)
- i %= scr_lns;
-
- slp = &big_picture[i];
-
- if (slp->len < 1)
- continue;
-
- if (slp->len >= ANSILINELEN)
- slp->len = ANSILINELEN -1;
-
- // tweak slp
- slp->data[slp->len] = 0;
- slp->mode &= ~STANDOUT;
- slp->mode |= MODIFIED;
- slp->oldlen = 0;
- slp->sso = slp->eso = 0;
- slp->smod = 0;
-
- // make slp->data a pure string
- for (i=0; i<slp->len; i++)
- {
- if (!slp->data[i])
- slp->data[i] = ' ';
- }
-
- slp->len = strip_ansi(buf, (char*)slp->data, STRIP_ALL);
- buf[slp->len] = 0;
-
- switch(level)
- {
- case GRAYOUT_DARK: // dark text
- case GRAYOUT_BOLD:// bold text
- // basically, in current system slp->data will
- // not exceed t_columns. buffer overflow is impossible.
- // but to make it more robust, let's quick check here.
- // of course, t_columns should always be far smaller.
- if (strlen((char*)slp->data) > t_columns)
- slp->data[t_columns] = 0;
- strcpy((char*)slp->data,
- level < 0 ? ANSI_COLOR(1) : ANSI_COLOR(1;30;40));
- strcat((char*)slp->data, buf);
- strcat((char*)slp->data, ANSI_RESET ANSI_CLRTOEND);
- slp->len = strlen((char*)slp->data);
- break;
-
- case GRAYOUT_NORM: // Plain text
- memcpy(slp->data, buf, slp->len + 1);
- break;
- }
- slp->emod = slp->len -1;
- }
-}
-
-static size_t screen_backupsize(int len, const screenline_t *bp)
-{
- int i;
- size_t sum = 0;
- for(i = 0; i < len; i++)
- sum += ((char*)&bp[i].data - (char*)&bp[i]) + bp[i].len;
- return sum;
-}
-
-void scr_dump(screen_backup_t *old)
-{
- int i;
- size_t offset = 0;
- void *buf;
- screenline_t* bp = big_picture;
-
- buf = old->raw_memory = malloc(screen_backupsize(t_lines, big_picture));
-
- old->col = t_columns;
- old->row = t_lines;
- getyx(&old->y, &old->x);
-
- for(i = 0; i < t_lines; i++) {
- /* backup header */
- memcpy((char*)buf + offset, &bp[i], ((char*)&bp[i].data - (char*)&bp[i]));
- offset += ((char*)&bp[i].data - (char*)&bp[i]);
-
- /* backup body */
- memcpy((char*)buf + offset, &bp[i].data, bp[i].len);
- offset += bp[i].len;
- }
-}
-
-void scr_restore(const screen_backup_t *old)
-{
- int i;
- size_t offset=0;
- void *buf = old->raw_memory;
- screenline_t* bp = big_picture;
- const int len = MIN(old->row, t_lines);
-
- for(i = 0; i < len; i++) {
- /* restore header */
- memcpy(&bp[i], (char*)buf + offset, ((char*)&bp[i].data - (char*)&bp[i]));
- offset += ((char*)&bp[i].data - (char*)&bp[i]);
-
- /* restore body */
- memcpy(&bp[i].data, (char*)buf + offset, bp[i].len);
- offset += bp[i].len;
- }
-
- free(old->raw_memory);
- move(old->y, old->x);
- redrawwin();
-}
-
-#endif // !defined(USE_PFTERM)
-
-/* vim:sw=4
- */
diff --git a/mbbsd/stuff.c b/mbbsd/stuff.c
deleted file mode 100644
index 2349a68d..00000000
--- a/mbbsd/stuff.c
+++ /dev/null
@@ -1,828 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-/* ----------------------------------------------------- */
-/* set file path for boards/user home */
-/* ----------------------------------------------------- */
-static const char * const str_home_file = "home/%c/%s/%s";
-static const char * const str_board_file = "boards/%c/%s/%s";
-static const char * const str_board_n_file = "boards/%c/%s/%s.%d";
-
-
-static const char * const str_dotdir = FN_DIR;
-
-/* XXX set*() all assume buffer size = PATHLEN */
-void
-sethomepath(char *buf, const char *userid)
-{
- assert(is_validuserid(userid));
- snprintf(buf, PATHLEN, "home/%c/%s", userid[0], userid);
-}
-
-void
-sethomedir(char *buf, const char *userid)
-{
- assert(is_validuserid(userid));
- snprintf(buf, PATHLEN, str_home_file, userid[0], userid, str_dotdir);
-}
-
-void
-sethomeman(char *buf, const char *userid)
-{
- assert(is_validuserid(userid));
- snprintf(buf, PATHLEN, str_home_file, userid[0], userid, "man");
-}
-
-
-void
-sethomefile(char *buf, const char *userid, const char *fname)
-{
- assert(is_validuserid(userid));
- assert(fname[0]);
- snprintf(buf, PATHLEN, str_home_file, userid[0], userid, fname);
-}
-
-void
-setuserfile(char *buf, const char *fname)
-{
- assert(is_validuserid(cuser.userid));
- assert(fname[0]);
- snprintf(buf, PATHLEN, str_home_file, cuser.userid[0], cuser.userid, fname);
-}
-
-void
-setapath(char *buf, const char *boardname)
-{
- //assert(boardname[0]);
- snprintf(buf, PATHLEN, "man/boards/%c/%s", boardname[0], boardname);
-}
-
-void
-setadir(char *buf, const char *path)
-{
- //assert(path[0]);
- snprintf(buf, PATHLEN, "%s/%s", path, str_dotdir);
-}
-
-void
-setbpath(char *buf, const char *boardname)
-{
- //assert(boardname[0]);
- snprintf(buf, PATHLEN, "boards/%c/%s", boardname[0], boardname);
-}
-
-void
-setbdir(char *buf, const char *boardname)
-{
- //assert(boardname[0]);
- snprintf(buf, PATHLEN, str_board_file, boardname[0], boardname,
- (currmode & MODE_DIGEST ? fn_mandex : str_dotdir));
-}
-
-void
-setbfile(char *buf, const char *boardname, const char *fname)
-{
- //assert(boardname[0]);
- assert(fname[0]);
- snprintf(buf, PATHLEN, str_board_file, boardname[0], boardname, fname);
-}
-
-void
-setbnfile(char *buf, const char *boardname, const char *fname, int n)
-{
- //assert(boardname[0]);
- assert(fname[0]);
- snprintf(buf, PATHLEN, str_board_n_file, boardname[0], boardname, fname, n);
-}
-
-/*
- * input direct
- * output buf: copy direct
- * fname: direct ªºÀɦW³¡¤À
- */
-void
-setdirpath(char *buf, const char *direct, const char *fname)
-{
- char *p;
- strcpy(buf, direct);
- p = strrchr(buf, '/');
- assert(p);
- strlcpy(p + 1, fname, PATHLEN-(p+1-buf));
-}
-
-/**
- * µ¹©w¤å³¹¼ÐÃD title¡A¶Ç¦^«ü¨ì¥DÃDªº³¡¤Àªº«ü¼Ð¡C
- * @param title
- */
-char *
-subject(char *title)
-{
- if (!strncasecmp(title, str_reply, 3)) {
- title += 3;
- if (*title == ' ')
- title++;
- }
- return title;
-}
-
-int is_validuserid(const char *id)
-{
- int len, i;
- if(id==NULL)
- return 0;
- len = strlen(id);
-
- if (len < 2 || len>IDLEN)
- return 0;
-
- if (!isalpha(id[0]))
- return 0;
- for (i = 1; i < len; i++)
- if (!isalnum(id[i]))
- return 0;
- return 1;
-}
-
-int
-is_uBM(const char *list, const char *id)
-{
- register int len;
-
- if (list[0] == '[')
- list++;
- if (list[0] > ' ') {
- len = strlen(id);
- do {
- if (!strncasecmp(list, id, len)) {
- list += len;
- if ((*list == 0) || (*list == '/') ||
- (*list == ']') || (*list == ' '))
- return 1;
- }
- if ((list = strchr(list, '/')) != NULL)
- list++;
- else
- break;
- } while (1);
- }
- return 0;
-}
-
-int
-is_BM(const char *list)
-{
- if (is_uBM(list, cuser.userid)) {
- cuser.userlevel |= PERM_BM; /* Ptt ¦Û°Ê¥[¤WBMªºÅv§Q */
- return 1;
- }
- return 0;
-}
-
-int
-userid_is_BM(const char *userid, const char *list)
-{
- register int ch, len;
-
- // TODO merge with is_uBM
- ch = list[0];
- if ((ch > ' ') && (ch < 128)) {
- len = strlen(userid);
- do {
- if (!strncasecmp(list, userid, len)) {
- ch = list[len];
- if ((ch == 0) || (ch == '/') || (ch == ']'))
- return 1;
- }
- while ((ch = *list++)) {
- if (ch == '/')
- break;
- }
- } while (ch);
- }
- return 0;
-}
-
-int
-belong(const char *filelist, const char *key)
-{
- return file_exist_record(filelist, key);
-}
-
-
-#ifndef _BBS_UTIL_C_ /* getdata_buf */
-time4_t
-gettime(int line, time4_t dt, const char*head)
-{
- char yn[7];
- int i;
- struct tm *ptime = localtime4(&dt), endtime;
- time_t t;
-
- memcpy(&endtime, ptime, sizeof(struct tm));
- snprintf(yn, sizeof(yn), "%4d", ptime->tm_year + 1900);
- move(line, 0); outs(head);
- i=strlen(head);
- do {
- getdata_buf(line, i, " ¦è¤¸¦~:", yn, 5, LCECHO);
- // signed: limited on (2037, ...)
- // unsigned: limited on (..., 1970)
- // let's restrict inside the boundary.
- } while ((endtime.tm_year = atoi(yn) - 1900) < 70 || endtime.tm_year > 135);
- snprintf(yn, sizeof(yn), "%d", ptime->tm_mon + 1);
- do {
- getdata_buf(line, i+15, "¤ë:", yn, 3, LCECHO);
- } while ((endtime.tm_mon = atoi(yn) - 1) < 0 || endtime.tm_mon > 11);
- snprintf(yn, sizeof(yn), "%d", ptime->tm_mday);
- do {
- getdata_buf(line, i+24, "¤é:", yn, 3, LCECHO);
- } while ((endtime.tm_mday = atoi(yn)) < 1 || endtime.tm_mday > 31);
- snprintf(yn, sizeof(yn), "%d", ptime->tm_hour);
- do {
- getdata_buf(line, i+33, "®É(0-23):", yn, 3, LCECHO);
- } while ((endtime.tm_hour = atoi(yn)) < 0 || endtime.tm_hour > 23);
- t = mktime(&endtime);
- /* saturation check */
- if(t < 0)
- t = 1;
- if(t > INT_MAX)
- t = INT_MAX;
- return t;
-}
-
-// synchronize 'now'
-void syncnow(void)
-{
-#ifdef OUTTA_TIMER
- now = SHM->GV2.e.now;
-#else
- now = time(0);
-#endif
-}
-
-#endif
-
-
-#ifndef _BBS_UTIL_C_
-/* ³o¤@°Ï³£¬O¦³Ãö©óµe­±³B²zªº, ¬G _BBS_UTIL_C_ ¤£¶·­n */
-
-#ifdef PLAY_ANGEL
-void
-pressanykey_or_callangel(){
- int ch;
-
- outmsg(
- ANSI_COLOR(1;34;44) " ¢e¢e¢e¢e "
- ANSI_COLOR(32) "H " ANSI_COLOR(36) "©I¥s¤p¤Ñ¨Ï" ANSI_COLOR(34)
- " ¢e¢e¢e¢e" ANSI_COLOR(37;44) " ½Ð«ö " ANSI_COLOR(36) "ªÅ¥ÕÁä "
- ANSI_COLOR(37) "Ä~Äò " ANSI_COLOR(1;34)
- "¢e¢e¢e¢e¢e¢e¢e¢e¢e¢e¢e¢e¢e¢e " ANSI_RESET);
- do {
- ch = igetch();
- if (ch == 'h' || ch == 'H'){
- CallAngel();
- break;
- }
- } while ((ch != ' ') && (ch != KEY_LEFT) && (ch != '\r') && (ch != '\n'));
- move(b_lines, 0);
- clrtoeol();
- refresh();
-}
-#endif
-
-/**
- * µ¹ printf format ªº°Ñ¼Æ¡A¦L¨ì³Ì©³¤U¤@¦æ¡C
- * ¶Ç¦^¨Ï¥ÎªÌªº¿ï¾Ü(char)¡C
- */
-char
-getans(const char *fmt,...)
-{
- char msg[256];
- char ans[3];
- va_list ap;
- va_start(ap, fmt);
- vsnprintf(msg , sizeof(msg), fmt, ap);
- va_end(ap);
-
- getdata(b_lines, 0, msg, ans, sizeof(ans), LCECHO);
- return ans[0];
-}
-
-int
-getkey(const char *fmt,...)
-{
- char msg[256], i;
- va_list ap;
- va_start(ap, fmt);
- i = vsnprintf(msg , sizeof(msg), fmt, ap);
- va_end(ap);
- return vmsg(msg);
-}
-
-static const char *msg_pressanykey_full =
- ANSI_COLOR(37;44) " ½Ð«ö" ANSI_COLOR(36) " ¥ô·NÁä " ANSI_COLOR(37) "Ä~Äò " ANSI_COLOR(34);
-#define msg_pressanykey_full_len (18)
-
- // what is 200/1431/506/201?
-static const char* msg_pressanykey_trail =
- ANSI_COLOR(33;46) " [«ö¥ô·NÁäÄ~Äò] " ANSI_RESET;
-#define msg_pressanykey_trail_len (16+1+4) /* 4 for head */
-
-int
-vmsg(const char *msg)
-{
- int len = msg ? strlen(msg) : 0;
- int i = 0;
-
- if(len == 0) msg = NULL;
-
- move(b_lines, 0);
- clrtoeol();
-
- if(!msg)
- {
- /* msg_pressanykey_full */
- int w = (t_columns - msg_pressanykey_full_len - 8) / 2;
- int pad = 0;
-
- outs(ANSI_COLOR(1;34;44) " ");
- pad += 1;
- for (i = 0; i < w; i += 2)
- outs("¢e"), pad+=2;
- outs(msg_pressanykey_full), pad+= msg_pressanykey_full_len;
- /* pad now points to position of current cursor. */
- pad = t_columns - pad -2 ;
- /* pad is now those left . */
- if (pad > 0)
- {
- for (i = 0; i <= pad-2; i += 2)
- outs("¢e");
- if (i == pad-1)
- outs(" ");
- }
- outs(ANSI_RESET);
- } else {
- /* msg_pressanykey_trail */
- outs(ANSI_COLOR(1;36;44) " ¡» ");
- if(len >= t_columns - msg_pressanykey_trail_len)
- len = t_columns - msg_pressanykey_trail_len;
- while (i++ < len)
- outc(*msg++);
- i--;
- while (i++ < t_columns - msg_pressanykey_trail_len)
- outc(' ');
- outs(msg_pressanykey_trail);
- }
-
- do {
- i = igetch();
- } while( i == 0 );
-
- move(b_lines, 0);
- clrtoeol();
- return i;
-}
-
-int
-vmsgf(const char *fmt,...)
-{
- char msg[256];
- va_list ap;
- va_start(ap, fmt);
- vsnprintf(msg, sizeof(msg), fmt, ap);
- va_end(ap);
- msg[sizeof(msg)-1] = 0;
- return vmsg(msg);
-}
-
-/**
- * ±q²Ä y ¦C¶}©l show ¥X filename Àɮפ¤ªº«e lines ¦æ¡C
- * mode ¬° output ªº¼Ò¦¡¡A°Ñ¼Æ¦P strip_ansi¡C
- * @param filename
- * @param x
- * @param lines
- * @param mode: SHOWFILE_*, see modes.h
- * @return ¥¢±Ñ¶Ç¦^ 0¡A§_«h¬° 1¡C
- * 2 ªí¥Ü¦³ PttPrints ½X
- */
-int
-show_file(const char *filename, int y, int lines, int mode)
-{
- FILE *fp;
- char buf[1024];
- int ret = 1;
- int strpmode = STRIP_ALL;
-
- if (mode & SHOWFILE_ALLOW_COLOR)
- strpmode = ONLY_COLOR;
- if (mode & SHOWFILE_ALLOW_MOVE)
- strpmode = NO_RELOAD;
-
- if (y >= 0)
- move(y, 0);
- clrtoln(lines + y);
- if ((fp = fopen(filename, "r"))) {
- while (fgets(buf, sizeof(buf), fp) && lines--)
- {
- move(y++, 0);
- if (mode == SHOWFILE_RAW)
- {
- outs(buf);
- }
- else if ((mode & SHOWFILE_ALLOW_STAR) && (strstr(buf, ESC_STR "*") != NULL))
- {
- // because Ptt_prints escapes are not so often,
- // let's try harder to detect it.
- outs(Ptt_prints(buf, sizeof(buf), strpmode));
- ret = 2;
- } else {
- // ESC is very common...
- strip_ansi(buf, buf, strpmode);
- outs(buf);
- }
- }
- fclose(fp);
- outs(ANSI_RESET); // prevent some broken Welcome file
- } else
- return 0;
- return ret;
-}
-
-void
-bell(void)
-{
- char c;
-
- c = Ctrl('G');
- write(1, &c, 1);
-}
-
-int
-search_num(int ch, int max)
-{
- int clen = 1, y = b_lines - msg_occupied;
- char genbuf[10];
-
- genbuf[0] = ch; genbuf[1] = 0;
- clen = getdata_buf(y, 0,
- " ¸õ¦Ü²Ä´X¶µ: ", genbuf, sizeof(genbuf)-1, NUMECHO);
-
- move(y, 0); clrtoeol();
- genbuf[clen] = '\0';
- if (genbuf[0] == '\0')
- return -1;
- clen = atoi(genbuf);
- if (clen == 0)
- return 0;
- if (clen > max)
- return max;
- return clen - 1;
-}
-
-/**
- * ¦b¿Ã¹õ¥ª¤W¨¤ show ¥X "¡ititle¡j"
- * @param title
- */
-void
-stand_title(const char *title)
-{
- clear();
- prints(ANSI_COLOR(1;37;46) "¡i %s ¡j" ANSI_RESET "\n", title);
-}
-
-void
-cursor_show(int row, int column)
-{
- move(row, column);
- outs(STR_CURSOR);
- move(row, column + 1);
-}
-
-void
-cursor_clear(int row, int column)
-{
- move(row, column);
- outs(STR_UNCUR);
-}
-
-int
-cursor_key(int row, int column)
-{
- int ch;
-
- cursor_show(row, column);
- ch = igetch();
- move(row, column);
- outs(STR_UNCUR);
- return ch;
-}
-
-void
-printdash(const char *mesg, int msglen)
-{
- int head = 0, tail;
-
- if(msglen <= 0)
- msglen = strlen(mesg);
-
- if (mesg)
- head = (msglen + 1) >> 1;
-
- tail = head;
-
- while (head++ < t_columns/2-2)
- outc('-');
-
- if (tail) {
- outc(' ');
- if(mesg) outs(mesg);
- outc(' ');
- }
- while (tail++ < t_columns/2-2)
- outc('-');
-
- outc('\n');
-}
-
-int
-log_user(const char *fmt, ...)
-{
- char msg[256], filename[256];
- va_list ap;
-
- va_start(ap, fmt);
- vsnprintf(msg , sizeof(msg), fmt, ap);
- va_end(ap);
-
- sethomefile(filename, cuser.userid, "USERLOG");
- return log_filef(filename, LOG_CREAT, "%s: %s %s", cuser.userid, msg, Cdate(&now));
-}
-
-void
-show_help(const char * const helptext[])
-{
- const char *str;
- int i;
-
- clear();
- for (i = 0; (str = helptext[i]); i++) {
- if (*str == '\0')
- prints(ANSI_COLOR(1) "¡i %s ¡j" ANSI_COLOR(0) "\n", str + 1);
- else if (*str == '\01')
- prints("\n" ANSI_COLOR(36) "¡i %s ¡j" ANSI_RESET "\n", str + 1);
- else
- prints(" %s\n", str);
- }
-#ifdef PLAY_ANGEL
- if (HasUserPerm(PERM_LOGINOK))
- pressanykey_or_callangel();
- else
-#endif
- pressanykey();
-}
-
-void
-show_helpfile(const char *helpfile)
-{
- clear();
- show_file((char *)helpfile, 0, b_lines, SHOWFILE_ALLOW_ALL);
-#ifdef PLAY_ANGEL
- if (HasUserPerm(PERM_LOGINOK))
- pressanykey_or_callangel();
- else
-#endif
- pressanykey();
-}
-
-#endif // _BBS_UTIL_C_
-
-/* ----------------------------------------------------- */
-/* use mmap() to malloc large memory in CRITICAL_MEMORY */
-/* ----------------------------------------------------- */
-#ifdef CRITICAL_MEMORY
-void *MALLOC(int size)
-{
- int *p;
- p = (int *)mmap(NULL, (size + 4), PROT_READ | PROT_WRITE,
- MAP_ANON | MAP_PRIVATE, -1, 0);
- p[0] = size;
-#if defined(DEBUG) && !defined(_BBS_UTIL_C_)
- vmsgf("critical malloc %d bytes", size);
-#endif
- return (void *)&p[1];
-}
-
-void FREE(void *ptr)
-{
- int size = ((int *)ptr)[-1];
- munmap((void *)(&(((int *)ptr)[-1])), size);
-#if defined(DEBUG) && !defined(_BBS_UTIL_C_)
- vmsgf("critical free %d bytes", size);
-#endif
-}
-#endif
-
-
-unsigned
-DBCS_StringHash(const char *s)
-{
- return fnv1a_32_dbcs_strcase(s, FNV1_32_INIT);
-}
-
-inline int *intbsearch(int key, const int *base0, int nmemb)
-{
- /* §ï¦Û /usr/src/lib/libc/stdlib/bsearch.c ,
- ±Mµ¹·j int array ¥Îªº, ¤£³z¹L compar function ¬G¸û§Ö¨Ç */
- const char *base = (const char *)base0;
- size_t lim;
- int *p;
-
- for (lim = nmemb; lim != 0; lim >>= 1) {
- p = (int *)(base + (lim >> 1) * 4);
- if( key == *p )
- return p;
- if( key > *p ){/* key > p: move right */
- base = (char *)p + 4;
- lim--;
- } /* else move left */
- }
- return (NULL);
-}
-
-inline unsigned int *
-uintbsearch(const unsigned int key, const unsigned int *base0, const int nmemb)
-{
- /* §ï¦Û /usr/src/lib/libc/stdlib/bsearch.c ,
- ±Mµ¹·j int array ¥Îªº, ¤£³z¹L compar function ¬G¸û§Ö¨Ç */
- const char *base = (const char *)base0;
- size_t lim;
- unsigned int *p;
-
- for (lim = nmemb; lim != 0; lim >>= 1) {
- p = (unsigned int *)(base + (lim >> 1) * 4);
- if( key == *p )
- return p;
- if( key > *p ){/* key > p: move right */
- base = (char *)p + 4;
- lim--;
- } /* else move left */
- }
- return (NULL);
-}
-
-/* AIDS */
-aidu_t fn2aidu(char *fn)
-{
- aidu_t aidu = 0;
- aidu_t type = 0;
- aidu_t v1 = 0;
- aidu_t v2 = 0;
- char *sp = fn;
-
- if(fn == NULL)
- return 0;
-
- switch(*(sp ++))
- {
- case 'M':
- type = 0;
- break;
- case 'G':
- type = 1;
- break;
- default:
- return 0;
- break;
- }
-
- if(*(sp ++) != '.')
- return 0;
- v1 = strtoul(sp, &sp, 10);
- if(sp == NULL)
- return 0;
- if(*sp != '.' || *(sp + 1) != 'A')
- return 0;
- sp += 2;
- if(*(sp ++) == '.')
- {
- v2 = strtoul(sp, &sp, 16);
- if(sp == NULL)
- return 0;
- }
- aidu = ((type & 0xf) << 44) | ((v1 & 0xffffffff) << 12) | (v2 & 0xfff);
-
- return aidu;
-}
-
-/* IMPORTANT:
- * size of buf must be at least 8+1 bytes
- */
-char *aidu2aidc(char *buf, aidu_t aidu)
-{
- const char aidu2aidc_table[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_";
- const int aidu2aidc_tablesize = sizeof(aidu2aidc_table) - 1;
- char *sp = buf + 8;
- aidu_t v;
-
- *(sp --) = '\0';
- while(sp >= buf)
- {
- /* FIXME: ¯à«OÃÒ aidu2aidc_tablesize ¬O 2 ªº¾­¦¸ªº¸Ü¡A
- ³o¸Ì¥i¥H§ï¥Î bitwise operation °µ */
- v = aidu % aidu2aidc_tablesize;
- aidu = aidu / aidu2aidc_tablesize;
- *(sp --) = aidu2aidc_table[v];
- }
- return buf;
-}
-
-/* IMPORTANT:
- * size of fn must be at least FNLEN bytes
- */
-char *aidu2fn(char *fn, aidu_t aidu)
-{
- aidu_t type = ((aidu >> 44) & 0xf);
- aidu_t v1 = ((aidu >> 12) & 0xffffffff);
- aidu_t v2 = (aidu & 0xfff);
-
- if(fn == NULL)
- return NULL;
- snprintf(fn, FNLEN - 1, "%c.%d.A.%03X", ((type == 0) ? 'M' : 'G'), (unsigned int)v1, (unsigned int)v2);
- fn[FNLEN - 1] = '\0';
- return fn;
-}
-
-aidu_t aidc2aidu(char *aidc)
-{
- char *sp = aidc;
- aidu_t aidu = 0;
-
- if(aidc == NULL)
- return 0;
-
- while(*sp != '\0' && /* ignore trailing spaces */ *sp != ' ')
- {
- aidu_t v = 0;
- /* FIXME: ¬dªíªk·|¤£·|¤ñ¸û§Ö¡H */
- if(*sp >= '0' && *sp <= '9')
- v = *sp - '0';
- else if(*sp >= 'A' && *sp <= 'Z')
- v = *sp - 'A' + 10;
- else if(*sp >= 'a' && *sp <= 'z')
- v = *sp - 'a' + 36;
- else if(*sp == '-')
- v = 62;
- else if(*sp == '_')
- v = 63;
- else
- return 0;
- aidu <<= 6;
- aidu |= (v & 0x3f);
- sp ++;
- }
-
- return aidu;
-}
-
-int search_aidu(char *bfile, aidu_t aidu)
-{
- char fn[FNLEN];
- int fd;
- fileheader_t fhs[64];
- int len, i;
- int pos = 0;
- int found = 0;
- int lastpos = 0;
-
- if(aidu2fn(fn, aidu) == NULL)
- return -1;
- if((fd = open(bfile, O_RDONLY, 0)) < 0)
- return -1;
-
- while(!found && (len = read(fd, fhs, sizeof(fhs))) > 0)
- {
- len /= sizeof(fileheader_t);
- for(i = 0; i < len; i ++)
- {
- int l;
- if(strcmp(fhs[i].filename, fn) == 0 ||
- ((aidu & 0xfff) == 0 && (l = strlen(fhs[i].filename)) > 6 &&
- strncmp(fhs[i].filename, fn, l) == 0))
- {
- if(fhs[i].filemode & FILE_BOTTOM)
- {
- lastpos = pos;
- }
- else
- {
- found = 1;
- break;
- }
- }
- pos ++;
- }
- }
- close(fd);
-
- return (found ? pos : (lastpos ? lastpos : -1));
-}
-/* end of AIDS */
diff --git a/mbbsd/syspost.c b/mbbsd/syspost.c
deleted file mode 100644
index 9ced9918..00000000
--- a/mbbsd/syspost.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-int
-post_msg(const char *bname, const char *title, const char *msg, const char *author)
-{
- FILE *fp;
- int bid;
- fileheader_t fhdr;
- char fname[PATHLEN];
-
- /* ¦b bname ªOµoªí·s¤å³¹ */
- setbpath(fname, bname);
- stampfile(fname, &fhdr);
- fp = fopen(fname, "w");
-
- if (!fp)
- return -1;
-
- fprintf(fp, "§@ªÌ: %s ¬ÝªO: %s\n¼ÐÃD: %s \n", author, bname, title);
- fprintf(fp, "®É¶¡: %s\n", ctime4(&now));
-
- /* ¤å³¹ªº¤º®e */
- fputs(msg, fp);
- fclose(fp);
-
- /* ±NÀÉ®×¥[¤J¦Cªí */
- strlcpy(fhdr.title, title, sizeof(fhdr.title));
- strlcpy(fhdr.owner, author, sizeof(fhdr.owner));
- setbdir(fname, bname);
- if (append_record(fname, &fhdr, sizeof(fhdr)) != -1)
- if ((bid = getbnum(bname)) > 0)
- setbtotal(bid);
- return 0;
-}
-
-int
-post_file(const char *bname, const char *title, const char *filename, const char *author)
-{
- int size = dashs(filename);
- char *msg;
- FILE *fp;
-
- if (size <= 0)
- return -1;
- if (!(fp = fopen(filename, "r")))
- return -1;
- msg = (char *)malloc(size + 1);
- size = fread(msg, 1, size, fp);
- msg[size] = 0;
- size = post_msg(bname, title, msg, author);
- fclose(fp);
- free(msg);
- return size;
-}
-
-void
-post_change_perm(int oldperm, int newperm, const char *sysopid, const char *userid)
-{
- char genbuf[(NUMPERMS+1) * STRLEN*2] = "", reason[30] = "";
- char title[TTLEN+1];
- char *s = genbuf;
- int i, flag = 0;
-
- // generate log (warning: each line should <= STRLEN*2)
- for (i = 0; i < NUMPERMS; i++) {
- if (((oldperm >> i) & 1) != ((newperm >> i) & 1)) {
- sprintf(s, " ¯¸ªø" ANSI_COLOR(1;32) "%s%s%s%s" ANSI_RESET "ªºÅv­­\n",
- sysopid,
- (((oldperm >> i) & 1) ? ANSI_COLOR(1;33) "Ãö³¬" : ANSI_COLOR(1;33) "¶}±Ò"),
- userid, str_permid[i]);
- s += strlen(s);
- flag++;
- }
- }
-
- if (!flag) // nothing changed
- return;
-
- clrtobot();
- clear();
- while (!getdata(5, 0, "½Ð¿é¤J²z¥Ñ¥H¥Ü­t³d¡G",
- reason, sizeof(reason), DOECHO));
- sprintf(s, "\n " ANSI_COLOR(1;37) "¯¸ªø%s­×§ïÅv­­²z¥Ñ¬O¡G%s" ANSI_RESET,
- cuser.userid, reason);
-
- snprintf(title, sizeof(title), "[¤½¦w³ø§i] ¯¸ªø%s­×§ï%sÅv­­³ø§i",
- cuser.userid, userid);
-
- post_msg(GLOBAL_SECURITY, title, genbuf, "[¨t²Î¦w¥þ§½]");
-}
-
-void
-post_violatelaw(const char *crime, const char *police, const char *reason, const char *result)
-{
- char title[TTLEN+1];
- char msg[200];
-
- snprintf(title, sizeof(title), "[³ø§i] %s:%-*s §P¨M", crime,
- (int)(37 - strlen(reason) - strlen(crime)), reason);
-
- snprintf(msg, sizeof(msg),
- ANSI_COLOR(1;32) "%s" ANSI_RESET "§P¨M¡G\n"
- " " ANSI_COLOR(1;32) "%s" ANSI_RESET "¦]" ANSI_COLOR(1;35) "%s" ANSI_RESET "¦æ¬°¡A\n"
- "¹H¤Ï¥»¯¸¯¸³W¡A³B¥H" ANSI_COLOR(1;35) "%s" ANSI_RESET "¡A¯S¦¹¤½§i\n",
- police, crime, reason, result);
-
- if (!strstr(police, "ĵ¹î")) {
- post_msg("PoliceLog", title, msg, "[" BBSMNAME "ªk°|]");
-
- snprintf(msg, sizeof(msg),
- ANSI_COLOR(1;32) "%s" ANSI_RESET "§P¨M¡G\n"
- " " ANSI_COLOR(1;32) "%s" ANSI_RESET "¦]" ANSI_COLOR(1;35) "%s" ANSI_RESET "¦æ¬°¡A\n"
- "¹H¤Ï¥»¯¸¯¸³W¡A³B¥H" ANSI_COLOR(1;35) "%s" ANSI_RESET "¡A¯S¦¹¤½§i\n",
- "¯¸°Èĵ¹î", crime, reason, result);
- }
-
- post_msg("ViolateLaw", title, msg, "[" BBSMNAME "ªk°|]");
-}
-
-void
-post_newboard(const char *bgroup, const char *bname, const char *bms)
-{
- char genbuf[256], title[TTLEN+1];
-
- snprintf(title, sizeof(title), "[·sªO¦¨¥ß] %s", bname);
- snprintf(genbuf, sizeof(genbuf),
- "%s ¶}¤F¤@­Ó·sªO %s : %s\n\n·s¥ôªO¥D¬° %s\n\n®¥³ß*^_^*\n",
- cuser.userid, bname, bgroup, bms);
-
- post_msg("Record", title, genbuf, "[¨t²Î]");
-}
-
-void
-post_policelog(const char *bname, const char *atitle, const char *action, const char *reason, const int toggle)
-{
- char genbuf[256], title[TTLEN+1];
-
- snprintf(title, sizeof(title), "[%s][%s] %s by %s", action, toggle ? "¶}±Ò" : "Ãö³¬", bname, cuser.userid);
- snprintf(genbuf, sizeof(genbuf),
- "%s (%s) %s %s ¬ÝªO %s ¥\\¯à\n­ì¦] : %s\n%s%s\n",
- cuser.userid, fromhost, toggle ? "¶}±Ò" : "Ãö³¬", bname, action,
- reason, atitle ? "¤å³¹¼ÐÃD : " : "", atitle ? atitle : "");
-
- post_msg("PoliceLog", title, genbuf, "[¨t²Î]");
-}
diff --git a/mbbsd/talk.c b/mbbsd/talk.c
deleted file mode 100644
index 70bcdb97..00000000
--- a/mbbsd/talk.c
+++ /dev/null
@@ -1,3654 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-#define QCAST int (*)(const void *, const void *)
-
-static char * const IdleTypeTable[] = {
- "°¸¦bªá§b°Õ", "±¡¤H¨Ó¹q", "³V­¹¤¤", "«ô¨£©P¤½", "°²¦ºª¬ºA", "§Ú¦b«ä¦Ò"
-};
-static char * const sig_des[] = {
- "°«Âû", "²á¤Ñ", "", "¤U´Ñ", "¶H´Ñ", "·t´Ñ", "¤U³ò´Ñ", "¤U¶Â¥Õ´Ñ",
-};
-static char * const withme_str[] = {
- "½Í¤Ñ", "¤U¤­¤l´Ñ", "°«Ãdª«", "¤U¶H´Ñ", "¤U·t´Ñ", "¤U³ò´Ñ", "¤U¶Â¥Õ´Ñ", NULL
-};
-
-#define MAX_SHOW_MODE 6
-#define M_INT 15 /* monitor mode update interval */
-#define P_INT 20 /* interval to check for page req. in
- * talk/chat */
-#define BOARDFRI 1
-
-#define TALK_MAXCOL (78)
-#define TALK_BUFLEN (TALK_MAXCOL+2)
-typedef struct twpic {
- unsigned short len;
- unsigned char data[TALK_BUFLEN]; // bound to specific size
-} twpic_t;
-
-typedef struct talkwin_t {
- int curcol, curln;
- int sline, eline;
- twpic_t *big_picture;
-} talkwin_t;
-
-typedef struct pickup_t {
- userinfo_t *ui;
- int friend, uoffset;
-} pickup_t;
-
-/* °O¿ý friend ªº user number */
-//
-#define PICKUP_WAYS 8
-
-static char * const fcolor[11] = {
- "", ANSI_COLOR(36), ANSI_COLOR(32), ANSI_COLOR(1;32),
- ANSI_COLOR(33), ANSI_COLOR(1;33), ANSI_COLOR(1;37), ANSI_COLOR(1;37),
- ANSI_COLOR(31), ANSI_COLOR(1;35), ANSI_COLOR(1;36)
-};
-static char save_page_requestor[40];
-static char page_requestor[40];
-
-userinfo_t *uip;
-
-int
-iswritable_stat(const userinfo_t * uentp, int fri_stat)
-{
- if (uentp == currutmp)
- return 0;
-
- if (HasUserPerm(PERM_SYSOP))
- return 1;
-
- if (!HasUserPerm(PERM_LOGINOK) || HasUserPerm(PERM_VIOLATELAW))
- return 0;
-
- return (uentp->pager != PAGER_ANTIWB &&
- (fri_stat & HFM || uentp->pager != PAGER_FRIENDONLY));
-}
-
-int
-isvisible_stat(const userinfo_t * me, const userinfo_t * uentp, int fri_stat)
-{
- if (!uentp || uentp->userid[0] == 0)
- return 0;
-
- /* to avoid paranoid users get crazy*/
- if (uentp->mode == DEBUGSLEEPING)
- return 0;
-
- if (PERM_HIDE(uentp) && !(PERM_HIDE(me))) /* ¹ï¤èµµ¦âÁô§Î¦Ó§A¨S¦³ */
- return 0;
- else if ((me->userlevel & PERM_SYSOP) ||
- ((fri_stat & HRM) && (fri_stat & HFM)))
- /* ¯¸ªø¬Ýªº¨£¥ô¦ó¤H */
- return 1;
-
- if (uentp->invisible && !(me->userlevel & PERM_SEECLOAK))
- return 0;
-
- return !(fri_stat & HRM);
-}
-
-int query_online(const char *userid)
-{
- userinfo_t *uentp;
-
- if (!userid || !*userid)
- return 0;
-
- if (!isalnum(*userid))
- return 0;
-
- if (strchr(userid, '.') || SHM->GV2.e.noonlineuser)
- return 0;
-
- uentp = search_ulist_userid(userid);
-
- if (!uentp ||!isvisible(currutmp, uentp))
- return 0;
-
- return 1;
-}
-
-const char *
-modestring(const userinfo_t * uentp, int simple)
-{
- static char modestr[40];
- static char *const notonline = "¤£¦b¯¸¤W";
- register int mode = uentp->mode;
- register char *word;
- int fri_stat;
-
- /* for debugging */
- if (mode >= MAX_MODES) {
- syslog(LOG_WARNING, "what!? mode = %d", mode);
- word = ModeTypeTable[mode % MAX_MODES];
- } else
- word = ModeTypeTable[mode];
-
- fri_stat = friend_stat(currutmp, uentp);
- if (!(HasUserPerm(PERM_SYSOP) || HasUserPerm(PERM_SEECLOAK)) &&
- ((uentp->invisible || (fri_stat & HRM)) &&
- !((fri_stat & HFM) && (fri_stat & HRM))))
- return notonline;
- else if (mode == EDITING) {
- snprintf(modestr, sizeof(modestr), "E:%s",
- ModeTypeTable[uentp->destuid < EDITING ? uentp->destuid :
- EDITING]);
- word = modestr;
- } else if (!mode && *uentp->chatid == 1) {
- if (!simple)
- snprintf(modestr, sizeof(modestr), "¦^À³ %s",
- isvisible_uid(uentp->destuid) ?
- getuserid(uentp->destuid) : "ªÅ®ð");
- else
- snprintf(modestr, sizeof(modestr), "¦^À³©I¥s");
- }
- else if (!mode && *uentp->chatid == 3)
- snprintf(modestr, sizeof(modestr), "¤ô²y·Ç³Æ¤¤");
- else if (
-#ifdef NOKILLWATERBALL
- uentp->msgcount > 0
-#else
- (!mode) && *uentp->chatid == 2
-#endif
- )
- if (uentp->msgcount < 10) {
- const char *cnum[10] =
- {"", "¤@", "¨â", "¤T", "¥|", "¤­",
- "¤»", "¤C", "¤K", "¤E"};
- snprintf(modestr, sizeof(modestr),
- "¤¤%sÁû¤ô²y", cnum[(int)(uentp->msgcount)]);
- } else
- snprintf(modestr, sizeof(modestr), "¤£¦æ¤F @_@");
- else if (!mode)
- return (uentp->destuid == 6) ? uentp->chatid :
- IdleTypeTable[(0 <= uentp->destuid && uentp->destuid < 6) ?
- uentp->destuid : 0];
- else if (simple)
- return word;
- else if (uentp->in_chat && mode == CHATING)
- snprintf(modestr, sizeof(modestr), "%s (%s)", word, uentp->chatid);
- else if (mode == TALK || mode == M_FIVE || mode == CHC || mode == UMODE_GO
- || mode == DARK) {
- if (!isvisible_uid(uentp->destuid)) /* Leeym ¹ï¤è(µµ¦â)Áô§Î */
- snprintf(modestr, sizeof(modestr), "%s ªÅ®ð", word);
- /* Leeym * ¤j®a¦Û¤vµo´§§a¡I */
- else
- snprintf(modestr, sizeof(modestr),
- "%s %s", word, getuserid(uentp->destuid));
- } else if (mode == CHESSWATCHING) {
- snprintf(modestr, sizeof(modestr), "Æ[´Ñ");
- } else if (mode != PAGE && mode != TQUERY)
- return word;
- else
- snprintf(modestr, sizeof(modestr),
- "%s %s", word, getuserid(uentp->destuid));
-
- return (modestr);
-}
-
-int
-set_friend_bit(const userinfo_t * me, const userinfo_t * ui)
-{
- int unum, hit = 0;
- const int *myfriends;
-
- /* §PÂ_¹ï¤è¬O§_¬°§ÚªºªB¤Í ? */
- if( intbsearch(ui->uid, me->myfriend, me->nFriends) )
- hit = IFH;
-
- /* §PÂ_§Ú¬O§_¬°¹ï¤èªºªB¤Í ? */
- if( intbsearch(me->uid, ui->myfriend, ui->nFriends) )
- hit |= HFM;
-
- /* §PÂ_¹ï¤è¬O§_¬°§Úªº¤³¤H ? */
- myfriends = me->reject;
- while ((unum = *myfriends++)) {
- if (unum == ui->uid) {
- hit |= IRH;
- break;
- }
- }
-
- /* §PÂ_§Ú¬O§_¬°¹ï¤èªº¤³¤H ? */
- myfriends = ui->reject;
- while ((unum = *myfriends++)) {
- if (unum == me->uid) {
- hit |= HRM;
- break;
- }
- }
- return hit;
-}
-
-inline int
-he_reject_me(userinfo_t * uin){
- int* iter = uin->reject;
- int unum;
- while ((unum = *iter++)) {
- if (unum == currutmp->uid) {
- return 1;
- }
- }
- return 0;
-}
-
-int
-reverse_friend_stat(int stat)
-{
- int stat1 = 0;
- if (stat & IFH)
- stat1 |= HFM;
- if (stat & IRH)
- stat1 |= HRM;
- if (stat & HFM)
- stat1 |= IFH;
- if (stat & HRM)
- stat1 |= IRH;
- if (stat & IBH)
- stat1 |= IBH;
- return stat1;
-}
-
-#ifdef OUTTACACHE
-int sync_outta_server(int sfd)
-{
- int i;
- int offset = (int)(currutmp - &SHM->uinfo[0]);
-
- int cmd, res;
- int nfs;
- ocfs_t fs[MAX_FRIEND*2];
-
- cmd = -2;
- if(towrite(sfd, &cmd, sizeof(cmd))<0 ||
- towrite(sfd, &offset, sizeof(offset))<0 ||
- towrite(sfd, &currutmp->uid, sizeof(currutmp->uid)) < 0 ||
- towrite(sfd, currutmp->myfriend, sizeof(currutmp->myfriend))<0 ||
- towrite(sfd, currutmp->reject, sizeof(currutmp->reject))<0)
- return -1;
-
- if(toread(sfd, &res, sizeof(res))<0)
- return -1;
-
- if(res<0)
- return -1;
- if(res==2) {
- close(sfd);
- outs("µn¤J¤ÓÀWÁc, ¬°ÁקK¨t²Î­t²ü¹L­«, ½Ðµy«á¦A¸Õ\n");
- refresh();
- sleep(30);
- log_usies("REJECTLOGIN", NULL);
- memset(currutmp, 0, sizeof(userinfo_t));
- exit(0);
- }
-
- if(toread(sfd, &nfs, sizeof(nfs))<0)
- return -1;
- if(nfs<0 || nfs>MAX_FRIEND*2) {
- fprintf(stderr, "invalid nfs=%d\n",nfs);
- return -1;
- }
-
- if(toread(sfd, fs, sizeof(fs[0])*nfs)<0)
- return -1;
-
- close(sfd);
-
- for(i=0; i<nfs; i++) {
- if( SHM->uinfo[fs[i].index].uid != fs[i].uid )
- continue; // double check, server may not know user have logout
- currutmp->friend_online[currutmp->friendtotal++]
- = fs[i].friendstat;
- /* XXX: race here */
- if( SHM->uinfo[fs[i].index].friendtotal < MAX_FRIEND )
- SHM->uinfo[fs[i].index].friend_online[ SHM->uinfo[fs[i].index].friendtotal++ ] = fs[i].rfriendstat;
- }
-
- if(res==1) {
- vmsg("½Ð¤ÅÀWÁcµn¤J¥H§K³y¦¨¨t²Î¹L«×­t²ü");
- }
- return 0;
-}
-#endif
-
-void login_friend_online(void)
-{
- userinfo_t *uentp;
- int i, stat, stat1;
- int offset = (int)(currutmp - &SHM->uinfo[0]);
-
-#ifdef OUTTACACHE
- int sfd;
- /* OUTTACACHE is TOO slow, let's prompt user here. */
- move(b_lines-2, 0); clrtobot();
- outs("\n¥¿¦b§ó·s»P¦P¨B½u¤W¨Ï¥ÎªÌ¤Î¦n¤Í¦W³æ¡A¨t²Î­t²ü¶q¤j®É·|»Ý®É¸û¤[...\n");
- refresh();
-
- sfd = toconnect(OUTTACACHEHOST, OUTTACACHEPORT);
- if(sfd>=0) {
- int res=sync_outta_server(sfd);
- if(res==0) // sfd will be closed if return 0
- return;
- close(sfd);
- }
-#endif
-
- for (i = 0; i < SHM->UTMPnumber && currutmp->friendtotal < MAX_FRIEND; i++) {
- uentp = (&SHM->uinfo[SHM->sorted[SHM->currsorted][0][i]]);
- if (uentp && uentp->uid && (stat = set_friend_bit(currutmp, uentp))) {
- stat1 = reverse_friend_stat(stat);
- stat <<= 24;
- stat |= (int)(uentp - &SHM->uinfo[0]);
- currutmp->friend_online[currutmp->friendtotal++] = stat;
- if (uentp != currutmp && uentp->friendtotal < MAX_FRIEND) {
- stat1 <<= 24;
- stat1 |= offset;
- uentp->friend_online[uentp->friendtotal++] = stat1;
- }
- }
- }
- return;
-}
-
-/* TODO merge with util/shmctl.c logout_friend_online() */
-int
-logout_friend_online(userinfo_t * utmp)
-{
- int my_friend_idx, thefriend;
- int k;
- int offset = (int)(utmp - &SHM->uinfo[0]);
- userinfo_t *ui;
- for(; utmp->friendtotal>0; utmp->friendtotal--) {
- if( !(0 <= utmp->friendtotal && utmp->friendtotal < MAX_FRIEND) )
- return 1;
- my_friend_idx=utmp->friendtotal-1;
- thefriend = (utmp->friend_online[my_friend_idx] & 0xFFFFFF);
- utmp->friend_online[my_friend_idx]=0;
-
- if( !(0 <= thefriend && thefriend < USHM_SIZE) )
- continue;
-
- ui = &SHM->uinfo[thefriend];
- if(ui->pid==0 || ui==utmp)
- continue;
- if(ui->friendtotal > MAX_FRIEND || ui->friendtotal<0)
- continue;
- for (k = 0; k < ui->friendtotal && k < MAX_FRIEND &&
- (int)(ui->friend_online[k] & 0xFFFFFF) != offset; k++);
- if (k < ui->friendtotal && k < MAX_FRIEND) {
- ui->friendtotal--;
- ui->friend_online[k] = ui->friend_online[ui->friendtotal];
- ui->friend_online[ui->friendtotal] = 0;
- }
- }
- return 0;
-}
-
-
-int
-friend_stat(const userinfo_t * me, const userinfo_t * ui)
-{
- int i, j, hit = 0;
- /* ¬ÝªO¦n¤Í */
- if (me->brc_id && ui->brc_id == me->brc_id) {
- hit = IBH;
- }
- for (i = 0; me->friend_online[i] && i < MAX_FRIEND; i++) {
- j = (me->friend_online[i] & 0xFFFFFF);
- if (VALID_USHM_ENTRY(j) && ui == &SHM->uinfo[j]) {
- hit |= me->friend_online[i] >> 24;
- break;
- }
- }
- if (PERM_HIDE(ui))
- return hit & ST_FRIEND;
- return hit;
-}
-
-int
-isvisible_uid(int tuid)
-{
- userinfo_t *uentp;
-
- if (!tuid || !(uentp = search_ulist(tuid)))
- return 1;
- return isvisible(currutmp, uentp);
-}
-
-/* ¯u¹ê°Ê§@ */
-static void
-my_kick(userinfo_t * uentp)
-{
- char genbuf[200];
-
- getdata(1, 0, msg_sure_ny, genbuf, 4, LCECHO);
- clrtoeol();
- if (genbuf[0] == 'y') {
- snprintf(genbuf, sizeof(genbuf),
- "%s (%s)", uentp->userid, uentp->nickname);
- log_usies("KICK ", genbuf);
- if ((uentp->pid <= 0 || kill(uentp->pid, SIGHUP) == -1) && (errno == ESRCH))
- purge_utmp(uentp);
- outs("½ð¥X¥hÅo");
- } else
- outs(msg_cancel);
- pressanykey();
-}
-
-int
-my_query(const char *uident)
-{
- userec_t muser;
- int tuid, fri_stat = 0;
- userinfo_t *uentp;
- const char *sex[8] =
- {MSG_BIG_BOY, MSG_BIG_GIRL,
- MSG_LITTLE_BOY, MSG_LITTLE_GIRL,
- MSG_MAN, MSG_WOMAN, MSG_PLANT, MSG_MIME};
- static time_t last_query;
-
- STATINC(STAT_QUERY);
- if ((tuid = getuser(uident, &muser))) {
- move(1, 0);
- clrtobot();
- move(1, 0);
- setutmpmode(TQUERY);
- currutmp->destuid = tuid;
-
- if ((uentp = (userinfo_t *) search_ulist(tuid)))
- fri_stat = friend_stat(currutmp, uentp);
-
- prints("¡m¢×¢Ò¼ÊºÙ¡n%s(%s)%*s¡m¸gÀÙª¬ªp¡n%s",
- muser.userid,
- muser.nickname,
- strlen(muser.userid) + strlen(muser.nickname) >= 26 ? 0 :
- (int)(26 - strlen(muser.userid) - strlen(muser.nickname)), "",
- money_level(muser.money));
- if (uentp && ((fri_stat & HFM && !uentp->invisible) || strcmp(muser.userid,cuser.userid) == 0))
- prints(" ($%d)", muser.money);
- outc('\n');
-
- prints("¡m¤W¯¸¦¸¼Æ¡n%d¦¸", muser.numlogins);
- move(2, 40);
-#ifdef ASSESS
- prints("¡m¤å³¹½g¼Æ¡n%d½g (Àu:%d/¦H:%d)\n", muser.numposts, muser.goodpost, muser.badpost);
-#else
- prints("¡m¤å³¹½g¼Æ¡n%d½g\n", muser.numposts);
-#endif
-
- prints(ANSI_COLOR(1;33) "¡m¥Ø«e°ÊºA¡n%-28.28s" ANSI_RESET,
- (uentp && isvisible_stat(currutmp, uentp, fri_stat)) ?
- modestring(uentp, 0) : "¤£¦b¯¸¤W");
-
- outs(((uentp && ISNEWMAIL(uentp)) || load_mailalert(muser.userid))
- ? "¡m¨p¤H«H½c¡n¦³·s¶i«H¥óÁÙ¨S¬Ý\n" :
- "¡m¨p¤H«H½c¡n©Ò¦³«H¥ó³£¬Ý¹L¤F\n");
- prints("¡m¤W¦¸¤W¯¸¡n%-28.28s¡m¤W¦¸¬G¶m¡n%s\n",
- Cdate(&muser.lastlogin),
- (muser.lasthost[0] ? muser.lasthost : "(¤£¸Ô)"));
- prints("¡m¤­¤l´Ñ¾ÔÁZ¡n%3d ³Ó %3d ±Ñ %3d ©M "
- "¡m¶H´Ñ¾ÔÁZ¡n%3d ³Ó %3d ±Ñ %3d ©M\n",
- muser.five_win, muser.five_lose, muser.five_tie,
- muser.chc_win, muser.chc_lose, muser.chc_tie);
-#ifdef ASSESS
- prints("¡mÄv¼Ðµû¤ñ¡n Àu %d / ¦H %d", muser.goodsale, muser.badsale);
- move(6, 40);
-#endif
- if ((uentp && ((fri_stat & HFM) || strcmp(muser.userid,cuser.userid) == 0) && !uentp->invisible))
- prints("¡m ©Ê §O ¡n%-28.28s\n", sex[muser.sex % 8]);
-
- showplans_userec(&muser);
- if(HasUserPerm(PERM_SYSOP|PERM_POLICE) )
- {
- if(vmsg("T: ¶}¥ß»@³æ")=='T')
- violate_law(&muser, tuid);
- }
- else
- pressanykey();
- if(now-last_query<1)
- sleep(2);
- else if(now-last_query<2)
- sleep(1);
- last_query=now;
- return FULLUPDATE;
- }
- return DONOTHING;
-}
-
-static char t_last_write[80];
-
-void check_water_init(void)
-{
- if(water==NULL) {
- water = (water_t*)malloc(sizeof(water_t)*6);
- memset(water, 0, sizeof(water_t)*6);
- water_which = &water[0];
-
- strlcpy(water[0].userid, " ¥þ³¡ ", sizeof(water[0].userid));
- }
-}
-
-static void
-water_scr(const water_t * tw, int which, char type)
-{
- if (type == 1) {
- int i;
- const int colors[] = {33, 37, 33, 37, 33};
- move(8 + which, 28);
- outc(' ');
- move(8 + which, 28);
- prints(ANSI_COLOR(1;37;45) " %c %-14s " ANSI_COLOR(0) "",
- tw->uin ? ' ' : 'x',
- tw->userid);
- for (i = 0; i < 5; ++i) {
- move(16 + i, 4);
- outc(' ');
- move(16 + i, 4);
- if (tw->msg[(tw->top - i + 4) % 5].last_call_in[0] != 0)
- prints(ANSI_COLOR(0) " " ANSI_COLOR(1;%d;44) "¡¹%-64s" ANSI_COLOR(0) " \n",
- colors[i],
- tw->msg[(tw->top - i + 4) % 5].last_call_in);
- else
- outs(ANSI_COLOR(0) "¡@\n");
- }
-
- move(21, 4);
- outc(' ');
- move(21, 4);
- prints(ANSI_COLOR(0) " " ANSI_COLOR(1;37;46) "%-66s" ANSI_COLOR(0) " \n",
- tw->msg[5].last_call_in);
-
- move(0, 0);
- outc(' ');
- move(0, 0);
-#ifdef PLAY_ANGEL
- if (tw->msg[0].msgmode == MSGMODE_TOANGEL)
- outs(ANSI_COLOR(0) "¦^µª¤p¥D¤H:");
- else
-#endif
- prints(ANSI_COLOR(0) "¤ÏÀ» %s:", tw->userid);
- clrtoeol();
- move(0, strlen(tw->userid) + 6);
- } else {
-
-#ifndef USE_PFTERM
- // workaround poor terminal, made by in2.
- move(8 + which, 28);
- outs("123456789012345678901234567890");
-#endif // !USE_PFTERM
-
- move(8 + which, 28);
- prints(ANSI_COLOR(1;37;44) " %c %-13s¡@" ANSI_COLOR(0) "",
- tw->uin ? ' ' : 'x',
- tw->userid);
- }
-}
-
-void
-my_write2(void)
-{
- int i, ch, currstat0;
- char genbuf[256], msg[80], done = 0, c0, which;
- water_t *tw;
- unsigned char mode0;
-
- check_water_init();
- if (swater[0] == NULL)
- return;
- wmofo = REPLYING;
- currstat0 = currstat;
- c0 = currutmp->chatid[0];
- mode0 = currutmp->mode;
- currutmp->mode = 0;
- currutmp->chatid[0] = 3;
- currstat = DBACK;
-
- //init screen
- move(WB_OFO_USER_TOP, WB_OFO_USER_LEFT);
- outs(ANSI_COLOR(1;33;46) " ¡ô ¤ô²y¤ÏÀ»¹ï¶H ¡õ" ANSI_COLOR(0) "");
- for (i = 0; i < WB_OFO_USER_HEIGHT;++i)
- if (swater[i] == NULL || swater[i]->pid == 0)
- break;
- else {
- if (swater[i]->uin &&
- (swater[i]->pid != swater[i]->uin->pid ||
- swater[i]->userid[0] != swater[i]->uin->userid[0]))
- swater[i]->uin = search_ulist_pid(swater[i]->pid);
- water_scr(swater[i], i, 0);
- }
- move(WB_OFO_MSG_TOP, WB_OFO_MSG_LEFT);
- outs(ANSI_COLOR(0) " " ANSI_COLOR(1;35) "¡º" ANSI_COLOR(1;36) "¢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" ANSI_COLOR(1;35) "¡º" ANSI_COLOR(0) " ");
- move(WB_OFO_MSG_BOTTOM, WB_OFO_MSG_LEFT);
- outs(" " ANSI_COLOR(1;35) "¡º" ANSI_COLOR(1;36) "¢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" ANSI_COLOR(1;35) "¡º" ANSI_COLOR(0) " ");
- water_scr(swater[0], 0, 1);
- refresh();
-
- which = 0;
- do {
- switch ((ch = igetch())) {
- case Ctrl('T'):
- case KEY_UP:
- if (water_usies != 1) {
- water_scr(swater[(int)which], which, 0);
- which = (which - 1 + water_usies) % water_usies;
- water_scr(swater[(int)which], which, 1);
- refresh();
- }
- break;
-
- case KEY_DOWN:
- case Ctrl('R'):
- if (water_usies != 1) {
- water_scr(swater[(int)which], which, 0);
- which = (which + 1 + water_usies) % water_usies;
- water_scr(swater[(int)which], which, 1);
- refresh();
- }
- break;
-
- case KEY_LEFT:
- done = 1;
- break;
-
- case KEY_UNKNOWN:
- break;
-
- default:
- done = 1;
- tw = swater[(int)which];
-
- if (!tw->uin)
- break;
-
- if (ch != '\r' && ch != '\n') {
- msg[0] = ch, msg[1] = 0;
- } else
- msg[0] = 0;
- move(0, 0);
- outs(ANSI_RESET);
- clrtoeol();
-#ifndef PLAY_ANGEL
- snprintf(genbuf, sizeof(genbuf), "§ðÀ» %s:", tw->userid);
- i = WATERBALL_CONFIRM;
-#else
- if (tw->msg[0].msgmode == MSGMODE_WRITE) {
- snprintf(genbuf, sizeof(genbuf), "§ðÀ» %s:", tw->userid);
- i = WATERBALL_CONFIRM;
- } else if (tw->msg[0].msgmode == MSGMODE_TOANGEL) {
- strcpy(genbuf, "¦^µª¤p¥D¤H:");
- i = WATERBALL_CONFIRM_ANSWER;
- } else { /* tw->msg[0].msgmode == MSGMODE_FROMANGEL */
- strcpy(genbuf, "¦A°Ý¥L¤@¦¸¡G");
- i = WATERBALL_CONFIRM_ANGEL;
- }
-#endif
- if (!oldgetdata(0, 0, genbuf, msg,
- 80 - strlen(tw->userid) - 6, DOECHO))
- break;
-
- if (my_write(tw->pid, msg, tw->userid, i, tw->uin))
- strlcpy(tw->msg[5].last_call_in, t_last_write,
- sizeof(tw->msg[5].last_call_in));
- break;
- }
- } while (!done);
-
- currstat = currstat0;
- currutmp->chatid[0] = c0;
- currutmp->mode = mode0;
- if (wmofo == RECVINREPLYING) {
- wmofo = NOTREPLYING;
- write_request(0);
- }
- wmofo = NOTREPLYING;
-}
-
-/*
- * ³Q©I¥sªº®É¾÷:
- * 1. ¥á¸s²Õ¤ô²y flag = WATERBALL_PREEDIT, 1 (pre-edit)
- * 2. ¦^¤ô²y flag = WATERBALL_GENERAL, 0
- * 3. ¤W¯¸aloha flag = WATERBALL_ALOHA, 2 (pre-edit)
- * 4. ¼s¼½ flag = WATERBALL_SYSOP, 3 if SYSOP
- * flag = WATERBALL_PREEDIT, 1 otherwise
- * 5. ¥á¤ô²y flag = WATERBALL_GENERAL, 0
- * 6. my_write2 flag = WATERBALL_CONFIRM, 4 (pre-edit but confirm)
- * 7. (when defined PLAY_ANGEL)
- * ©I¥s¤p¤Ñ¨Ï flag = WATERBALL_ANGEL, 5 (id = "¤p¤Ñ¨Ï")
- * 8. (when defined PLAY_ANGEL)
- * ¦^µª¤p¥D¤H flag = WATERBALL_ANSWER, 6 (ÁôÂà id)
- * 9. (when defined PLAY_ANGEL)
- * ©I¥s¤p¤Ñ¨Ï flag = WATERBALL_CONFIRM_ANGEL, 7 (pre-edit)
- * 10. (when defined PLAY_ANGEL)
- * ¦^µª¤p¥D¤H flag = WATERBALL_CONFIRM_ANSWER, 8 (pre-edit)
- */
-int
-my_write(pid_t pid, const char *prompt, const char *id, int flag, userinfo_t * puin)
-{
- int len, currstat0 = currstat, fri_stat = -1;
- char msg[80], destid[IDLEN + 1];
- char genbuf[200], buf[200], c0 = currutmp->chatid[0];
- unsigned char mode0 = currutmp->mode;
- userinfo_t *uin;
- uin = (puin != NULL) ? puin : (userinfo_t *) search_ulist_pid(pid);
- strlcpy(destid, id, sizeof(destid));
- check_water_init();
-
- /* what if uin is NULL but other conditions are not true?
- * will this situation cause SEGV?
- * should this "!uin &&" replaced by "!uin ||" ?
- */
- if ((!uin || !uin->userid[0]) && !((flag == WATERBALL_GENERAL
-#ifdef PLAY_ANGEL
- || flag == WATERBALL_ANGEL || flag == WATERBALL_ANSWER
-#endif
- )
- && water_which->count > 0)) {
- vmsg("ÁV¿|! ¹ï¤è¤w¸¨¶]¤F(¤£¦b¯¸¤W)! ");
- watermode = -1;
- return 0;
- }
- currutmp->mode = 0;
- currutmp->chatid[0] = 3;
- currstat = DBACK;
-
- if (flag == WATERBALL_GENERAL
-#ifdef PLAY_ANGEL
- || flag == WATERBALL_ANGEL || flag == WATERBALL_ANSWER
-#endif
- ) {
- /* ¤@¯ë¤ô²y */
- watermode = 0;
-
- /* should we alert if we're in disabled mode? */
- switch(currutmp->pager)
- {
- case PAGER_DISABLE:
- case PAGER_ANTIWB:
- move(1, 0); clrtoeol();
- outs(ANSI_COLOR(1;31) "§Aªº©I¥s¾¹¥Ø«e¤£±µ¨ü§O¤H¥á¤ô²y¡A¹ï¤è¥i¯àµLªk¦^¸Ü¡C" ANSI_RESET);
- break;
-
- case PAGER_FRIENDONLY:
-#if 0
- // ¦pªG¹ï¤è¥¿¦b¤U¯¸¡A³o­Ó¦n¹³¤£¤Óí·| crash (?) */
- if (uin && uin->userid[0])
- {
- fri_stat = friend_stat(currutmp, uin);
- if(fri_stat & HFM)
- break;
- }
-#endif
- move(1, 0); clrtoeol();
- outs(ANSI_COLOR(1;31) "§Aªº©I¥s¾¹¥Ø«e¥u±µ¨ü¦n¤Í¥á¤ô²y¡A­Y¹ï¤è«D¦n¤Í«h¥i¯àµLªk¦^¸Ü¡C" ANSI_RESET);
- break;
- }
-
- if (!(len = getdata(0, 0, prompt, msg, 56, DOECHO))) {
- currutmp->chatid[0] = c0;
- currutmp->mode = mode0;
- currstat = currstat0;
- watermode = -1;
- return 0;
- }
-
- if (watermode > 0) {
- int i;
-
- i = (water_which->top - watermode + MAX_REVIEW) % MAX_REVIEW;
- uin = (userinfo_t *) search_ulist_pid(water_which->msg[i].pid);
-#ifdef PLAY_ANGEL
- if (water_which->msg[i].msgmode == MSGMODE_FROMANGEL)
- flag = WATERBALL_ANGEL;
- else if (water_which->msg[i].msgmode == MSGMODE_TOANGEL)
- flag = WATERBALL_ANSWER;
- else
- flag = WATERBALL_GENERAL;
-#endif
- strlcpy(destid, water_which->msg[i].userid, sizeof(destid));
- }
- } else {
- /* pre-edit ªº¤ô²y */
- strlcpy(msg, prompt, sizeof(msg));
- len = strlen(msg);
- }
-
- strip_ansi(msg, msg, STRIP_ALL);
- if (uin && *uin->userid &&
- (flag == WATERBALL_GENERAL || flag == WATERBALL_CONFIRM
-#ifdef PLAY_ANGEL
- || flag == WATERBALL_ANGEL || flag == WATERBALL_ANSWER
- || flag == WATERBALL_CONFIRM_ANGEL
- || flag == WATERBALL_CONFIRM_ANSWER
-#endif
- ))
- {
- snprintf(buf, sizeof(buf), "¥áµ¹ %s : %s [Y/n]?", destid, msg);
-
- getdata(0, 0, buf, genbuf, 3, LCECHO);
- if (genbuf[0] == 'n') {
- currutmp->chatid[0] = c0;
- currutmp->mode = mode0;
- currstat = currstat0;
- watermode = -1;
- return 0;
- }
- }
- watermode = -1;
- if (!uin || !*uin->userid || (strcasecmp(destid, uin->userid)
-#ifdef PLAY_ANGEL
- && flag != WATERBALL_ANGEL && flag != WATERBALL_CONFIRM_ANGEL) ||
- ((flag == WATERBALL_ANGEL || flag == WATERBALL_CONFIRM_ANGEL)
- && strcasecmp(cuser.myangel, uin->userid)
-#endif
- )) {
- vmsg("ÁV¿|! ¹ï¤è¤w¸¨¶]¤F(¤£¦b¯¸¤W)! ");
- currutmp->chatid[0] = c0;
- currutmp->mode = mode0;
- currstat = currstat0;
- return 0;
- }
- if(fri_stat < 0)
- fri_stat = friend_stat(currutmp, uin);
- // else, fri_stat was already calculated. */
-
- if (flag != WATERBALL_ALOHA) { /* aloha ªº¤ô²y¤£¥Î¦s¤U¨Ó */
- /* ¦s¨ì¦Û¤vªº¤ô²yÀÉ */
- if (!fp_writelog) {
- sethomefile(genbuf, cuser.userid, fn_writelog);
- fp_writelog = fopen(genbuf, "a");
- }
- if (fp_writelog) {
- fprintf(fp_writelog, "To %s: %s [%s]\n",
- destid, msg, Cdatelite(&now));
- snprintf(t_last_write, 66, "To %s: %s", destid, msg);
- }
- }
- if (flag == WATERBALL_SYSOP && uin->msgcount) {
- /* ¤£À´ */
- uin->destuip = currutmp - &SHM->uinfo[0];
- uin->sig = 2;
- if (uin->pid > 0)
- kill(uin->pid, SIGUSR1);
- } else if ((flag != WATERBALL_ALOHA &&
-#ifdef PLAY_ANGEL
- flag != WATERBALL_ANGEL &&
- flag != WATERBALL_ANSWER &&
- flag != WATERBALL_CONFIRM_ANGEL &&
- flag != WATERBALL_CONFIRM_ANSWER &&
- /* Angel accept or not is checked outside.
- * Avoiding new users don't know what pager is. */
-#endif
- !HasUserPerm(PERM_SYSOP) &&
- (uin->pager == PAGER_ANTIWB ||
- uin->pager == PAGER_DISABLE ||
- (uin->pager == PAGER_FRIENDONLY &&
- !(fri_stat & HFM))))
-#ifdef PLAY_ANGEL
- || ((flag == WATERBALL_ANGEL || flag == WATERBALL_CONFIRM_ANGEL)
- && he_reject_me(uin))
-#endif
- ) {
- outmsg(ANSI_COLOR(1;33;41) "ÁV¿|! ¹ï¤è¨¾¤ô¤F! " ANSI_COLOR(37) "~>_<~" ANSI_RESET);
- } else {
- int write_pos = uin->msgcount; /* try to avoid race */
- if ( write_pos < (MAX_MSGS - 1) ) { /* race here */
- unsigned char pager0 = uin->pager;
-
- uin->msgcount = write_pos + 1;
- uin->pager = PAGER_DISABLE;
- uin->msgs[write_pos].pid = currpid;
-#ifdef PLAY_ANGEL
- if (flag == WATERBALL_ANSWER || flag == WATERBALL_CONFIRM_ANSWER)
- strlcpy(uin->msgs[write_pos].userid, "¤p¤Ñ¨Ï",
- sizeof(uin->msgs[write_pos].userid));
- else
-#endif
- strlcpy(uin->msgs[write_pos].userid, cuser.userid,
- sizeof(uin->msgs[write_pos].userid));
- strlcpy(uin->msgs[write_pos].last_call_in, msg,
- sizeof(uin->msgs[write_pos].last_call_in));
-#ifndef PLAY_ANGEL
- uin->msgs[write_pos].msgmode = MSGMODE_WRITE;
-#else
- switch (flag) {
- case WATERBALL_ANGEL:
- case WATERBALL_CONFIRM_ANGEL:
- uin->msgs[write_pos].msgmode = MSGMODE_TOANGEL;
- break;
- case WATERBALL_ANSWER:
- case WATERBALL_CONFIRM_ANSWER:
- uin->msgs[write_pos].msgmode = MSGMODE_FROMANGEL;
- break;
- default:
- uin->msgs[write_pos].msgmode = MSGMODE_WRITE;
- }
-#endif
- uin->pager = pager0;
- } else if (flag != WATERBALL_ALOHA)
- outmsg(ANSI_COLOR(1;33;41) "ÁV¿|! ¹ï¤è¤£¦æ¤F! (¦¬¨ì¤Ó¦h¤ô²y) " ANSI_COLOR(37) "@_@" ANSI_RESET);
-
- if (uin->msgcount >= 1 &&
-#ifdef NOKILLWATERBALL
- !(uin->wbtime = now) /* race */
-#else
- (uin->pid <= 0 || kill(uin->pid, SIGUSR2) == -1)
-#endif
- && flag != WATERBALL_ALOHA)
- outmsg(ANSI_COLOR(1;33;41) "ÁV¿|! ¨S¥´¤¤! " ANSI_COLOR(37) "~>_<~" ANSI_RESET);
- else if (uin->msgcount == 1 && flag != WATERBALL_ALOHA)
- outmsg(ANSI_COLOR(1;33;44) "¤ô²y¯{¹L¥h¤F! " ANSI_COLOR(37) "*^o^*" ANSI_RESET);
- else if (uin->msgcount > 1 && uin->msgcount < MAX_MSGS &&
- flag != WATERBALL_ALOHA)
- outmsg(ANSI_COLOR(1;33;44) "¦A¸É¤W¤@²É! " ANSI_COLOR(37) "*^o^*" ANSI_RESET);
-
-#if defined(NOKILLWATERBALL) && defined(PLAY_ANGEL)
- /* Questioning and answering should better deliver immediately. */
- if ((flag == WATERBALL_ANGEL || flag == WATERBALL_ANSWER ||
- flag == WATERBALL_CONFIRM_ANGEL ||
- flag == WATERBALL_CONFIRM_ANSWER) && uin->pid)
- kill(uin->pid, SIGUSR2);
-#endif
- }
-
- clrtoeol();
-
- currutmp->chatid[0] = c0;
- currutmp->mode = mode0;
- currstat = currstat0;
- return 1;
-}
-
-void
-getmessage(msgque_t msg)
-{
- int write_pos = currutmp->msgcount;
- if ( write_pos < (MAX_MSGS - 1) ) {
- unsigned char pager0 = currutmp->pager;
- currutmp->msgcount = write_pos+1;
- memcpy(&currutmp->msgs[write_pos], &msg, sizeof(msgque_t));
- currutmp->pager = pager0;
- write_request(SIGUSR1);
- }
-}
-
-void
-t_display_new(void)
-{
- static int t_display_new_flag = 0;
- int i, off = 2;
- if (t_display_new_flag)
- return;
- else
- t_display_new_flag = 1;
-
- check_water_init();
- if (WATERMODE(WATER_ORIG))
- water_which = &water[0];
- else
- off = 3;
-
- if (water[0].count && watermode > 0) {
- move(1, 0);
- outs("¢w¢w¢w¢w¢w¢w¢w¤ô¢w²y¢w¦^¢wÅU¢w¢w¢w");
- outs(WATERMODE(WATER_ORIG) ?
- "¢w¢w¢w¢w¢w¢w¥Î[Ctrl-R Ctrl-T]Áä¤Á´«¢w¢w¢w¢w¢w" :
- "¥Î[Ctrl-R Ctrl-T Ctrl-F Ctrl-G ]Áä¤Á´«¢w¢w¢w¢w");
- if (WATERMODE(WATER_NEW)) {
- move(2, 0);
- clrtoeol();
- for (i = 0; i < 6; i++) {
- if (i > 0)
- if (swater[i - 1]) {
-
- if (swater[i - 1]->uin &&
- (swater[i - 1]->pid != swater[i - 1]->uin->pid ||
- swater[i - 1]->userid[0] != swater[i - 1]->uin->userid[0]))
- swater[i - 1]->uin = (userinfo_t *) search_ulist_pid(swater[i - 1]->pid);
- prints("%s%c%-13.13s" ANSI_RESET,
- swater[i - 1] != water_which ? "" :
- swater[i - 1]->uin ? ANSI_COLOR(1;33;47) :
- ANSI_COLOR(1;33;45),
- !swater[i - 1]->uin ? '#' : ' ',
- swater[i - 1]->userid);
- } else
- outs(" ");
- else
- prints("%s ¥þ³¡ " ANSI_RESET,
- water_which == &water[0] ? ANSI_COLOR(1;33;47) " " :
- " "
- );
- }
- }
- for (i = 0; i < water_which->count; i++) {
- int a = (water_which->top - i - 1 + MAX_REVIEW) % MAX_REVIEW;
- int len = 75 - strlen(water_which->msg[a].last_call_in)
- - strlen(water_which->msg[a].userid);
- if (len < 0)
- len = 0;
-
- move(i + (WATERMODE(WATER_ORIG) ? 2 : 3), 0);
- clrtoeol();
- if (watermode - 1 != i)
- prints(ANSI_COLOR(1;33;46) " %s " ANSI_COLOR(37;45) " %s " ANSI_RESET "%*s",
- water_which->msg[a].userid,
- water_which->msg[a].last_call_in, len,
- "");
- else
- prints(ANSI_COLOR(1;44) ">" ANSI_COLOR(1;33;47) "%s "
- ANSI_COLOR(37;45) " %s " ANSI_RESET "%*s",
- water_which->msg[a].userid,
- water_which->msg[a].last_call_in,
- len, "");
- }
-
- if (t_last_write[0]) {
- move(i + off, 0);
- clrtoeol();
- outs(t_last_write);
- i++;
- }
- move(i + off, 0);
- outs("¢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¢w");
- if (WATERMODE(WATER_NEW))
- while (i++ <= water[0].count) {
- move(i + off, 0);
- clrtoeol();
- }
- }
- t_display_new_flag = 0;
-}
-
-int
-t_display(void)
-{
- char genbuf[200], ans[4];
- if (fp_writelog) {
- fclose(fp_writelog);
- fp_writelog = NULL;
- }
- setuserfile(genbuf, fn_writelog);
- if (more(genbuf, YEA) != -1) {
- grayout(0, b_lines-5, GRAYOUT_DARK);
- move(b_lines - 4, 0);
- clrtobot();
- outs(ANSI_COLOR(1;33;45) "¡¹¤ô²y¾ã²zµ{¦¡ " ANSI_RESET "\n"
- "´£¿ô±z: ¥i±N¤ô²y¦s¤J«H½c(M)«á, ¨ì¡i¶l¥ó¿ï³æ¡j¸Ó«H¥ó«e«ö u,\n"
- "¨t²Î·|±N¤ô²y¬ö¿ý­«·s¾ã²z«á±H°eµ¹±z­ò! " ANSI_RESET "\n");
-
- getdata(b_lines - 1, 0, "²M°£(C) ¦s¤J«H½c(M) «O¯d(R) (C/M/R)?[R]",
- ans, sizeof(ans), LCECHO);
- if (*ans == 'm') {
- fileheader_t mymail;
- char title[128], buf[80];
-
- sethomepath(buf, cuser.userid);
- stampfile(buf, &mymail);
-
- mymail.filemode = FILE_READ ;
- strlcpy(mymail.owner, "[³Æ.§Ñ.¿ý]", sizeof(mymail.owner));
- strlcpy(mymail.title, "¼ö½u°O¿ý", sizeof(mymail.title));
- sethomedir(title, cuser.userid);
- Rename(genbuf, buf);
- append_record(title, &mymail, sizeof(mymail));
- } else if (*ans == 'c')
- unlink(genbuf);
- return FULLUPDATE;
- }
- return DONOTHING;
-}
-
-static void
-do_talk_nextline(talkwin_t * twin)
-{
- twin->curcol = 0;
- if (twin->curln < twin->eline)
- ++(twin->curln);
- else
- {
- int i, iend = twin->eline - twin->sline;
- region_scroll_up(twin->sline, twin->eline);
- // also scroll up our buffer
- for (i = 0; i < iend; i++)
- {
- memcpy(&twin->big_picture[i], &twin->big_picture[i+1],
- sizeof(twpic_t));
- }
- // zero last line
- memset(&twin->big_picture[iend], 0, sizeof(twpic_t));
- }
- move(twin->curln, twin->curcol);
-}
-
-static int
-iscompletedbcs(const unsigned char* str)
-{
- int isdbcs = 0;
- while (*str)
- {
- if (isdbcs == 1) isdbcs = 2;
- else if ((unsigned char)*str > 0x80) isdbcs = 1;
- else isdbcs = 0;
- str++;
- }
-
- return (isdbcs == 1) ? 0 : 1;
-}
-
-static void
-talk_refreshline(talkwin_t *twin)
-{
- // dirty screen
- twpic_t *line = twin->big_picture + (twin->curln - twin->sline);
- int iscomplete = iscompletedbcs(line->data);
- int len = strlen((char*)line->data);
-
- move(twin->curln, 0);
- clrtoeol();
- if (!iscomplete) len--;
- outs_n((char*)line->data, len);
- if (!iscomplete) outc('?');
- move(twin->curln, twin->curcol);
-}
-
-static void
-do_talk_char(talkwin_t * twin, int ch, FILE *flog)
-{
- twpic_t *line;
- char buf[TALK_BUFLEN] = "";
-
- line = twin->big_picture+(twin->curln - twin->sline);
-
- if (isprint2(ch)) {
-
-
- if (line->len < TALK_MAXCOL)
- move(twin->curln, twin->curcol);
- else
- do_talk_nextline(twin);
-
- // do_talk_nextline may change current line
- line = twin->big_picture + (twin->curln -twin->sline);
- memmove(line->data + twin->curcol+1, line->data + twin->curcol,
- line->len - twin->curcol +1);
- line->data[twin->curcol++] = ch;
- line->data[++line->len] = 0;
-
- // dirty screen
- talk_refreshline(twin);
-
- if (line->len < TALK_MAXCOL)
- return;
-
- // max buffer, log it.
- strlcpy(buf, (char *)line->data, line->len + 1);
-
- } else switch (ch) {
-
- case Ctrl('G'):
- bell();
- return;
-
- case Ctrl('A'):
- twin->curcol = 0;
- move(twin->curln, twin->curcol);
- return;
- case Ctrl('E'):
- twin->curcol = line->len;
- move(twin->curln, twin->curcol);
- return;
-
-
- case Ctrl('K'):
- line->len = twin->curcol;
- memset(line->data+line->len, 0, TALK_MAXCOL - line->len);
- move(twin->curln, twin->curcol);
- clrtoeol();
- return;
- case Ctrl('Y'):
- twin->curcol = 0;
- line->len = 0;
- memset(line->data, 0, TALK_MAXCOL);
- move(twin->curln, twin->curcol);
- clrtoeol();
- return;
-
- case Ctrl('M'):
- case Ctrl('J'):
- strlcpy(buf, (char *)line->data, line->len + 1);
- buf[line->len] = 0;
- do_talk_nextline(twin);
- break;
-
- case Ctrl('B'):
- if (twin->curcol > 0) {
- --(twin->curcol);
-#ifdef DBCSAWARE
- if(twin->curcol > 0 && twin->curcol < line->len && ISDBCSAWARE())
- {
- if(getDBCSstatus(line->data, twin->curcol) == DBCS_TRAILING)
- twin->curcol --;
- }
-#endif
- move(twin->curln, twin->curcol);
- }
- return;
-
- case Ctrl('F'):
- if (twin->curcol < line->len) {
- ++(twin->curcol);
-#ifdef DBCSAWARE
- if(twin->curcol < TALK_MAXCOL && twin->curcol < line->len && ISDBCSAWARE())
- {
- if(getDBCSstatus(line->data, twin->curcol) == DBCS_TRAILING)
- twin->curcol++;
- }
-#endif
- move(twin->curln, twin->curcol);
- }
- return;
-
-
- case Ctrl('P'):
- strlcpy(buf, (char *)line->data, line->len + 1);
- if (twin->curln > twin->sline) {
- --twin->curln;
- line = twin->big_picture + (twin->curln -twin->sline);
- }
- if (twin->curcol > line->len)
- twin->curcol = line->len;
-
-#ifdef DBCSAWARE
- // curln may be changed.
- if(twin->curcol > 0 && twin->curcol < line->len &&
- getDBCSstatus(line->data, twin->curcol) == DBCS_TRAILING)
- twin->curcol--;
-#endif
- move(twin->curln, twin->curcol);
- // XXX break here (for log)?
- break;
-
- case Ctrl('N'):
- strlcpy(buf, (char *)line->data, line->len + 1);
- if (twin->curln < twin->eline) {
- ++twin->curln;
- line = twin->big_picture + (twin->curln -twin->sline);
- }
- if (twin->curcol > line->len)
- twin->curcol = line->len;
-
-#ifdef DBCSAWARE
- // curln may be changed.
- line = twin->big_picture + (twin->curln -twin->sline);
- if(twin->curcol > 0 && twin->curcol < line->len &&
- getDBCSstatus(line->data, twin->curcol) == DBCS_TRAILING)
- twin->curcol--;
-#endif
- move(twin->curln, twin->curcol);
- // XXX break here (for log)?
- break;
-
- // complex data change
- case Ctrl('H'):
- case '\177':
- if (twin->curcol > 0)
- {
- int delta = 1;
-
-#ifdef DBCSAWARE
- if (twin->curcol > 1 && ISDBCSAWARE() &&
- getDBCSstatus(line->data, twin->curcol-1) == DBCS_TRAILING)
- delta++;
-#endif
- memmove(line->data + twin->curcol-delta, line->data + twin->curcol,
- line->len - twin->curcol +1);
- line->len -= delta;
- twin->curcol -= delta;
- // dirty screen
- talk_refreshline(twin);
- }
- return;
-
- case Ctrl('D'):
- if (twin->curcol < line->len)
- {
- int delta = 1;
-
-#ifdef DBCSAWARE
- if (ISDBCSAWARE() &&
- getDBCSstatus(line->data, twin->curcol) == DBCS_LEADING)
- delta++;
-#endif
- memmove(line->data + twin->curcol, line->data + twin->curcol+delta,
- line->len - twin->curcol -delta+1);
- line->len -= delta;
- memset(line->data + line->len, 0, TALK_MAXCOL - line->len);
- // dirty screen
- talk_refreshline(twin);
- }
- return;
- }
-
- trim(buf);
- if (*buf)
- fprintf(flog, "%s%s: %s%s\n",
- (twin->eline == b_lines - 1) ? ANSI_COLOR(1;35) : "",
- (twin->eline == b_lines - 1) ?
- getuserid(currutmp->destuid) : cuser.userid, buf,
- (ch == Ctrl('P')) ? ANSI_COLOR(37;45) "(Up)" ANSI_RESET : ANSI_RESET);
-}
-
-static void
-do_talk(int fd)
-{
- struct talkwin_t mywin, itswin;
- char mid_line[128], data[200];
- int i, datac, ch;
- int im_leaving = 0;
- FILE *log, *flog;
- struct tm *ptime;
- char genbuf[200], fpath[100];
-
- STATINC(STAT_DOTALK);
- ptime = localtime4(&now);
-
- setuserfile(fpath, "talk_XXXXXX");
- flog = fdopen(mkstemp(fpath), "w");
-
- setuserfile(genbuf, fn_talklog);
-
- if ((log = fopen(genbuf, "w")))
- fprintf(log, "[%d/%d %d:%02d] & %s\n",
- ptime->tm_mon + 1, ptime->tm_mday, ptime->tm_hour,
- ptime->tm_min, save_page_requestor);
- setutmpmode(TALK);
-
- ch = 58 - strlen(save_page_requestor);
- snprintf(genbuf, sizeof(genbuf), "%s¡i%s", cuser.userid, cuser.nickname);
- i = ch - strlen(genbuf);
- if (i >= 0)
- i = (i >> 1) + 1;
- else {
- genbuf[ch] = '\0';
- i = 1;
- }
- memset(data, ' ', i);
- data[i] = '\0';
-
- snprintf(mid_line, sizeof(mid_line),
- ANSI_COLOR(1;46;37) " ½Í¤Ñ»¡¦a " ANSI_COLOR(45) "%s%s¡j"
- " »P %s%s" ANSI_COLOR(0) "",
- data, genbuf, save_page_requestor, data);
-
- memset(&mywin, 0, sizeof(mywin));
- memset(&itswin, 0, sizeof(itswin));
-
- i = b_lines >> 1;
- mywin.eline = i - 1;
- itswin.curln = itswin.sline = i + 1;
- itswin.eline = b_lines - 1;
-
- // memory allocation
- mywin.big_picture = (twpic_t*) malloc (
- sizeof(twpic_t) * (mywin.eline - mywin.sline +1));
- itswin.big_picture = (twpic_t*) malloc (
- sizeof(twpic_t) * (itswin.eline- itswin.sline +1));
-
- // reset buffer
- for (i = mywin.sline; i <= mywin.eline; i++)
- {
- mywin.big_picture[i - mywin.sline].len = 0;
- memset(mywin.big_picture[i-mywin.sline].data, 0, TALK_BUFLEN);
- }
- for (i = itswin.sline; i <= itswin.eline; i++)
- {
- itswin.big_picture[i - itswin.sline].len = 0;
- memset(itswin.big_picture[i-itswin.sline].data, 0, TALK_BUFLEN);
- }
-
- clear();
- move(mywin.eline+1, 0);
- outs(mid_line);
- move(0, 0);
-
- add_io(fd, 0);
-
- while (1) {
- ch = igetch();
- if (ch == I_OTHERDATA) {
- // getyx(&y, &x);
- datac = recv(fd, data, sizeof(data), 0);
- if (datac <= 0)
- break;
- for (i = 0; i < datac; i++)
- do_talk_char(&itswin, data[i], flog);
- // move(y, x);
- } else if (ch == KEY_UNKNOWN) {
- // skip
- } else {
- if (ch == Ctrl('C')) {
- if (im_leaving)
- break;
- move(b_lines, 0);
- clrtoeol();
- outs("¦A«ö¤@¦¸ Ctrl-C ´N¥¿¦¡¤¤¤î½Í¸ÜÅo¡I");
- im_leaving = 1;
- continue;
- }
- if (im_leaving) {
- move(b_lines, 0);
- clrtoeol();
- im_leaving = 0;
- }
- switch (ch) {
- case KEY_LEFT: /* §â2byteªºÁä§ï¬°¤@byte */
- ch = Ctrl('B');
- break;
- case KEY_RIGHT:
- ch = Ctrl('F');
- break;
- case KEY_UP:
- ch = Ctrl('P');
- break;
- case KEY_DOWN:
- ch = Ctrl('N');
- break;
- }
- data[0] = (char)ch;
- if (send(fd, data, 1, 0) != 1)
- break;
- if (log)
- fputc((ch == Ctrl('M')) ? '\n' : (char)*data, log);
- do_talk_char(&mywin, *data, flog);
- }
- }
- if (log)
- fclose(log);
-
- add_io(0, 0);
- close(fd);
-
- if (flog) {
- char ans[4];
- int i;
-
- fprintf(flog, "\n" ANSI_COLOR(33;44) "Â÷§Oµe­± [%s] ... " ANSI_RESET "\n",
- Cdatelite(&now));
-
- fprintf(flog, "[%s]:\n", cuser.userid);
- for (i = 0; i < mywin.eline - mywin.sline +1; i++)
- if (mywin.big_picture[i].len)
- fprintf(flog, "%.*s\n", mywin.big_picture[i].len, mywin.big_picture[i].data);
-
- fprintf(flog, "[%s]:\n", getuserid(currutmp->destuid));
- for (i = 0; i < itswin.eline - itswin.sline +1; i++)
- if (itswin.big_picture[i].len)
- fprintf(flog, "%.*s\n", itswin.big_picture[i].len, itswin.big_picture[i].data);
-
- fclose(flog);
- redrawwin();
- more(fpath, NA);
-
- // force user decide how to deal with the log
- while (1) {
- getdata(b_lines - 1, 0, "²M°£(C) ²¾¦Ü³Æ§Ñ¿ý(M). (c/m)? ",
- ans, sizeof(ans), LCECHO);
- if (ans[0] == 'c' || ans[0] == 'm')
- break;
- move(b_lines-2, 0);
- prints(ANSI_COLOR(0;1;3%d) "½Ð¥¿½T¿é¤J c ©Î m ªº«ü¥O¡C" ANSI_RESET,
- (now % 7)+1);
- if (ans[0] == 0) outs("¬°ÁקK»~«ö©Ò¥H¥u ENTER ¬O¤£¦æªº¡C");
- }
-
- if (*ans == 'm') {
- fileheader_t mymail;
- char title[128];
-
- sethomepath(genbuf, cuser.userid);
- stampfile(genbuf, &mymail);
- mymail.filemode = FILE_READ ;
- strlcpy(mymail.owner, "[³Æ.§Ñ.¿ý]", sizeof(mymail.owner));
- snprintf(mymail.title, sizeof(mymail.title),
- "¹ï¸Ü°O¿ý " ANSI_COLOR(1;36) "(%s)" ANSI_RESET,
- getuserid(currutmp->destuid));
- sethomedir(title, cuser.userid);
- Rename(fpath, genbuf);
- append_record(title, &mymail, sizeof(mymail));
- } else
- unlink(fpath);
- flog = 0;
- }
-
- // free memory
- free(mywin.big_picture);
- free(itswin.big_picture);
- setutmpmode(XINFO);
- redrawwin();
-}
-
-#define lockreturn(unmode, state) if(lockutmpmode(unmode, state)) return
-
-int make_connection_to_somebody(userinfo_t *uin, int timeout){
- int sock, length, pid, ch;
- struct sockaddr_in server;
-
- sock = socket(AF_INET, SOCK_STREAM, 0);
- if (sock < 0) {
- perror("sock err");
- unlockutmpmode();
- return -1;
- }
- server.sin_family = PF_INET;
- server.sin_addr.s_addr = INADDR_ANY;
- server.sin_port = 0;
- if (bind(sock, (struct sockaddr *) & server, sizeof(server)) < 0) {
- close(sock);
- perror("bind err");
- unlockutmpmode();
- return -1;
- }
- length = sizeof(server);
-#if defined(Solaris) && __OS_MAJOR_VERSION__ == 5 && __OS_MINOR_VERSION__ < 7
- if (getsockname(sock, (struct sockaddr *) & server, & length) < 0) {
-#else
- if (getsockname(sock, (struct sockaddr *) & server, (socklen_t *) & length) < 0) {
-#endif
- close(sock);
- perror("sock name err");
- unlockutmpmode();
- return -1;
- }
- currutmp->sockactive = YEA;
- currutmp->sockaddr = server.sin_port;
- currutmp->destuid = uin->uid;
- setutmpmode(PAGE);
- uin->destuip = currutmp - &SHM->uinfo[0];
- pid = uin->pid;
- if (pid > 0)
- kill(pid, SIGUSR1);
- clear();
- prints("¥¿©I¥s %s.....\nÁä¤J Ctrl-D ¤¤¤î....", uin->userid);
-
- if(listen(sock, 1)<0) {
- close(sock);
- return -1;
- }
- add_io(sock, timeout);
-
- while (1) {
- ch = igetch();
- if (ch == I_TIMEOUT) {
- ch = uin->mode;
- if (!ch && uin->chatid[0] == 1 &&
- uin->destuip == currutmp - &SHM->uinfo[0]) {
- bell();
- outmsg("¹ï¤è¦^À³¤¤...");
- refresh();
- } else if (ch == EDITING || ch == TALK || ch == CHATING ||
- ch == PAGE || ch == MAILALL || ch == MONITOR ||
- ch == M_FIVE || ch == CHC ||
- (!ch && (uin->chatid[0] == 1 ||
- uin->chatid[0] == 3))) {
- add_io(0, 0);
- close(sock);
- currutmp->sockactive = currutmp->destuid = 0;
- vmsg("¤H®a¦b¦£°Õ");
- unlockutmpmode();
- return -1;
- } else {
- // change to longer timeout
- add_io(sock, 20);
- move(0, 0);
- outs("¦A");
- bell();
-
- uin->destuip = currutmp - &SHM->uinfo[0];
- if (pid <= 0 || kill(pid, SIGUSR1) == -1) {
- close(sock);
- currutmp->sockactive = currutmp->destuid = 0;
- add_io(0, 0);
- vmsg(msg_usr_left);
- unlockutmpmode();
- return -1;
- }
- continue;
- }
- }
- if (ch == I_OTHERDATA)
- break;
-
- if (ch == '\004') {
- add_io(0, 0);
- close(sock);
- currutmp->sockactive = currutmp->destuid = 0;
- unlockutmpmode();
- return -1;
- }
- }
- return sock;
-}
-
-void
-my_talk(userinfo_t * uin, int fri_stat, char defact)
-{
- int sock, msgsock, ch;
- pid_t pid;
- char c;
- char genbuf[4];
- unsigned char mode0 = currutmp->mode;
-
- genbuf[0] = defact;
- ch = uin->mode;
- strlcpy(currauthor, uin->userid, sizeof(currauthor));
-
- if (ch == EDITING || ch == TALK || ch == CHATING || ch == PAGE ||
- ch == MAILALL || ch == MONITOR || ch == M_FIVE || ch == CHC ||
- ch == DARK || ch == UMODE_GO || ch == CHESSWATCHING || ch == REVERSI ||
- (!ch && (uin->chatid[0] == 1 || uin->chatid[0] == 3)) ||
- uin->lockmode == M_FIVE || uin->lockmode == CHC) {
- if (ch == CHC || ch == M_FIVE || ch == UMODE_GO ||
- ch == CHESSWATCHING || ch == REVERSI) {
- sock = make_connection_to_somebody(uin, 20);
- if (sock < 0)
- vmsg("µLªk«Ø¥ß³s½u");
- else {
-#if defined(Solaris) && __OS_MAJOR_VERSION__ == 5 && __OS_MINOR_VERSION__ < 7
- msgsock = accept(sock, (struct sockaddr *) 0, 0);
-#else
- msgsock = accept(sock, (struct sockaddr *) 0, (socklen_t *) 0);
-#endif
- if (msgsock == -1) {
- perror("accept");
- close(sock);
- return;
- }
- close(sock);
- strlcpy(currutmp->mateid, uin->userid, sizeof(currutmp->mateid));
-
- switch (uin->sig) {
- case SIG_CHC:
- chc(msgsock, CHESS_MODE_WATCH);
- break;
-
- case SIG_GOMO:
- gomoku(msgsock, CHESS_MODE_WATCH);
- break;
-
- case SIG_GO:
- gochess(msgsock, CHESS_MODE_WATCH);
- break;
-
- case SIG_REVERSI:
- reversi(msgsock, CHESS_MODE_WATCH);
- break;
- }
- }
- }
- else
- outs("¤H®a¦b¦£°Õ");
- } else if (!HasUserPerm(PERM_SYSOP) &&
- (((fri_stat & HRM) && !(fri_stat & HFM)) ||
- ((!uin->pager) && !(fri_stat & HFM)))) {
- outs("¹ï¤èÃö±¼©I¥s¾¹¤F");
- } else if (!HasUserPerm(PERM_SYSOP) &&
- (((fri_stat & HRM) && !(fri_stat & HFM)) || uin->pager == PAGER_DISABLE)) {
- outs("¹ï¤è©Þ±¼©I¥s¾¹¤F");
- } else if (!HasUserPerm(PERM_SYSOP) &&
- !(fri_stat & HFM) && uin->pager == PAGER_FRIENDONLY) {
- outs("¹ï¤è¥u±µ¨ü¦n¤Íªº©I¥s");
- } else if (!(pid = uin->pid) /* || (kill(pid, 0) == -1) */ ) {
- //resetutmpent();
- outs(msg_usr_left);
- } else {
- int i,j;
-
- if (!defact) {
- showplans(uin->userid);
- move(2, 0);
- for(i=0;i<2;i++) {
- if(uin->withme & (WITHME_ALLFLAG<<i)) {
- if(i==0)
- outs("Åwªï¸ò§Ú¡G");
- else
- outs("½Ð§O§ä§Ú¡G");
- for(j=0; j<32 && withme_str[j/2]; j+=2)
- if(uin->withme & (1<<(j+i)))
- if(withme_str[j/2]) {
- outs(withme_str[j/2]);
- outc(' ');
- }
- outc('\n');
- }
- }
- move(4, 0);
- outs("­n©M¥L(¦o) (T)½Í¤Ñ(F)¤U¤­¤l´Ñ"
-#ifdef USE_CHICKEN_PK
- "(P)°«Ãdª«"
-#endif // USE_CHICKEN_PK
- "(C)¤U¶H´Ñ(D)¤U·t´Ñ(G)¤U³ò´Ñ(R)¤U¶Â¥Õ´Ñ");
- getdata(5, 0, " (N)¨S¨Æ§ä¿ù¤H¤F?[N] ", genbuf, 4, LCECHO);
- }
-
- switch (*genbuf) {
- case 'y':
- case 't':
- uin->sig = SIG_TALK;
- break;
- case 'f':
- lockreturn(M_FIVE, LOCK_THIS);
- uin->sig = SIG_GOMO;
- break;
- case 'c':
- lockreturn(CHC, LOCK_THIS);
- uin->sig = SIG_CHC;
- break;
- case 'd':
- uin->sig = SIG_DARK;
- break;
- case 'g':
- uin->sig = SIG_GO;
- break;
- case 'r':
- uin->sig = SIG_REVERSI;
- break;
-#ifdef USE_CHICKEN_PK
- case 'p':
- {
- userec_t xuser;
- chicken_t xchk;
- int error = 0;
-
- getuser(uin->userid, &xuser);
- if (uin->lockmode == CHICKEN || currutmp->lockmode == CHICKEN)
- error = 1;
- else if (!load_chicken(cuser.userid, &xchk) ||
- !load_chicken(xuser.userid, &xchk))
- error = 2;
-
- if (error) {
- vmsg(error == 2 ? "¨Ã«D¨â¤H³£¾iÃdª«" :
- "¦³¤@¤èªºÃdª«¥¿¦b¨Ï¥Î¤¤");
- return;
- }
- uin->sig = SIG_PK;
- }
- break;
-#endif // USE_CHICKEN_PK
- default:
- return;
- }
-
- uin->turn = 1;
- currutmp->turn = 0;
- strlcpy(uin->mateid, currutmp->userid, sizeof(uin->mateid));
- strlcpy(currutmp->mateid, uin->userid, sizeof(currutmp->mateid));
-
- sock = make_connection_to_somebody(uin, 5);
- if(sock==-1) {
- vmsg("µLªk«Ø¥ß³s½u");
- return;
- }
-
-#if defined(Solaris) && __OS_MAJOR_VERSION__ == 5 && __OS_MINOR_VERSION__ < 7
- msgsock = accept(sock, (struct sockaddr *) 0, 0);
-#else
- msgsock = accept(sock, (struct sockaddr *) 0, (socklen_t *) 0);
-#endif
- if (msgsock == -1) {
- perror("accept");
- close(sock);
- unlockutmpmode();
- return;
- }
- add_io(0, 0);
- close(sock);
- currutmp->sockactive = NA;
-
- if (uin->sig == SIG_CHC || uin->sig == SIG_GOMO ||
- uin->sig == SIG_GO || uin->sig == SIG_REVERSI)
- ChessEstablishRequest(msgsock);
-
- add_io(msgsock, 0);
- while ((ch = igetch()) != I_OTHERDATA) {
- if (ch == Ctrl('D')) {
- add_io(0, 0);
- close(msgsock);
- unlockutmpmode();
- return;
- }
- }
-
- if (read(msgsock, &c, sizeof(c)) != sizeof(c))
- c = 'n';
- add_io(0, 0);
-
- if (c == 'y') {
- snprintf(save_page_requestor, sizeof(save_page_requestor),
- "%s (%s)", uin->userid, uin->nickname);
- switch (uin->sig) {
- case SIG_DARK:
- main_dark(msgsock, uin);
- break;
-#ifdef USE_CHICKEN_PK
- case SIG_PK:
- chickenpk(msgsock);
- break;
-#endif
- case SIG_GOMO:
- gomoku(msgsock, CHESS_MODE_VERSUS);
- break;
- case SIG_CHC:
- chc(msgsock, CHESS_MODE_VERSUS);
- break;
- case SIG_GO:
- gochess(msgsock, CHESS_MODE_VERSUS);
- break;
- case SIG_REVERSI:
- reversi(msgsock, CHESS_MODE_VERSUS);
- break;
- case SIG_TALK:
- default:
- do_talk(msgsock);
- }
- } else {
- move(9, 9);
- outs("¡i¦^­µ¡j ");
- switch (c) {
- case 'a':
- outs("§Ú²{¦b«Ü¦£¡A½Ðµ¥¤@·|¨à¦A call §Ú¡A¦n¶Ü¡H");
- break;
- case 'b':
- prints("¹ï¤£°_¡A§Ú¦³¨Æ±¡¤£¯à¸ò§A %s....", sig_des[uin->sig]);
- break;
- case 'd':
- outs("§Ú­nÂ÷¯¸Åo..¤U¦¸¦A²á§a..........");
- break;
- case 'c':
- outs("½Ð¤£­n§n§Ú¦n¶Ü¡H");
- break;
- case 'e':
- outs("§ä§Ú¦³¨Æ¶Ü¡H½Ð¥ý¨Ó«H­ò....");
- break;
- case 'f':
- {
- char msgbuf[60];
-
- read(msgsock, msgbuf, 60);
- prints("¹ï¤£°_¡A§Ú²{¦b¤£¯à¸ò§A %s¡A¦]¬°\n", sig_des[uin->sig]);
- move(10, 18);
- outs(msgbuf);
- }
- break;
- case '1':
- prints("%s¡H¥ý®³100»È¨â¨Ó..", sig_des[uin->sig]);
- break;
- case '2':
- prints("%s¡H¥ý®³1000»È¨â¨Ó..", sig_des[uin->sig]);
- break;
- default:
- prints("§Ú²{¦b¤£·Q %s °Õ.....:)", sig_des[uin->sig]);
- }
- close(msgsock);
- }
- }
- currutmp->mode = mode0;
- currutmp->destuid = 0;
- unlockutmpmode();
- pressanykey();
-}
-
-/* ¿ï³æ¦¡²á¤Ñ¤¶­± */
-#define US_PICKUP 1234
-#define US_RESORT 1233
-#define US_ACTION 1232
-#define US_REDRAW 1231
-
-static void
-t_showhelp(void)
-{
- clear();
-
- outs(ANSI_COLOR(36) "¡i ¥ð¶¢²á¤Ñ¨Ï¥Î»¡©ú ¡j" ANSI_RESET "\n\n"
- "(¡ö)(e) µ²§ôÂ÷¶} (h) ¬Ý¨Ï¥Î»¡©ú\n"
- "(¡ô)/(¡õ)(n) ¤W¤U²¾°Ê (TAB) ¤Á´«±Æ§Ç¤è¦¡\n"
- "(PgUp)(^B) ¤W­¶¿ï³æ ( )(PgDn)(^F) ¤U­¶¿ï³æ\n"
- "(Hm)/($)(Ed) ­º/§À (S) ¨Ó·½/¦n¤Í´y­z/¾ÔÁZ ¤Á´«\n"
- "(m) ±H«H (q/c) ¬d¸ßºô¤Í/Ãdª«\n"
- "(r) ¾\\Ū«H¥ó (l/C) ¬Ý¤W¦¸¼ö°T/¤Á´«Áô¨­\n"
- "(f) ¥þ³¡/¦n¤Í¦Cªí (¼Æ¦r) ¸õ¦Ü¸Ó¨Ï¥ÎªÌ\n"
- "(p) ¤Á´«©I¥s¾¹ (g/i) µ¹¿ú/¤Á´«¤ß±¡\n"
- "(a/d/o) ¦n¤Í ¼W¥[/§R°£/­×§ï (s) ºô¤Í ID ·j´M\n"
- "(N) ­×§ï¼ÊºÙ (y) §Ú·Q§ä¤H²á¤Ñ¡B¤U´Ñ¡K\n");
-
- if (HasUserPerm(PERM_PAGE)) {
- outs("\n" ANSI_COLOR(36) "¡i ¥æ½Í±M¥ÎÁä ¡j" ANSI_RESET "\n"
- "(¡÷)(t)(Enter) ¸ò¥L¡þ¦o²á¤Ñ\n"
- "(w) ¼ö½u Call in\n"
- "(^W)¤Á´«¤ô²y¤è¦¡ ¤@¯ë / ¶i¶¥ / ¥¼¨Ó\n"
- "(b) ¹ï¦n¤Í¼s¼½ (¤@©w­n¦b¦n¤Í¦Cªí¤¤)\n"
- "(^R) §Y®É¦^À³ (¦³¤H Call in §A®É)\n");
- }
- if (HasUserPerm(PERM_SYSOP)) {
- outs("\n" ANSI_COLOR(36) "¡i ¯¸ªø±M¥ÎÁä ¡j" ANSI_RESET "\n\n");
- outs("(u)/(H) ³]©w¨Ï¥ÎªÌ¸ê®Æ/¤Á´«Áô§Î¼Ò¦¡\n");
- outs("(K) §âÃa³J½ð¥X¥h\n");
-#if defined(SHOWBOARD) && defined(DEBUG)
- outs("(Y) Åã¥Ü¥¿¦b¬Ý¤°»òªO\n");
-#endif
- }
-#ifdef PLAY_ANGEL
- if (HasUserPerm(PERM_LOGINOK))
- pressanykey_or_callangel();
- else
-#endif
- pressanykey();
-}
-
-/* Kaede show friend description */
-static char *
-friend_descript(const userinfo_t * uentp, char *desc_buf, int desc_buflen)
-{
- char *space_buf = "", *flag;
- char fpath[80], name[IDLEN + 2], *desc, *ptr;
- int len;
- FILE *fp;
- char genbuf[STRLEN];
-
- STATINC(STAT_FRIENDDESC);
- if((set_friend_bit(currutmp,uentp)&IFH)==0)
- return space_buf;
-
- setuserfile(fpath, friend_file[0]);
-
- STATINC(STAT_FRIENDDESC_FILE);
- if ((fp = fopen(fpath, "r"))) {
- snprintf(name, sizeof(name), "%s ", uentp->userid);
- len = strlen(name);
- desc = genbuf + 13;
-
- /* TODO maybe none linear search, or fread, or cache */
- while ((flag = fgets(genbuf, STRLEN, fp))) {
- if (!memcmp(genbuf, name, len)) {
- if ((ptr = strchr(desc, '\n')))
- ptr[0] = '\0';
- break;
- }
- }
- fclose(fp);
- if (flag)
- strlcpy(desc_buf, desc, desc_buflen);
- else
- return space_buf;
-
- return desc_buf;
- } else
- return space_buf;
-}
-
-static const char *
-descript(int show_mode, const userinfo_t * uentp, int diff)
-{
- static char description[30];
- switch (show_mode) {
- case 1:
- return friend_descript(uentp, description, sizeof(description));
- case 0:
- return (((uentp->pager != PAGER_DISABLE && uentp->pager != PAGER_ANTIWB && diff) ||
- HasUserPerm(PERM_SYSOP)) ?
-#ifdef WHERE
- uentp->from_alias ? SHM->home_desc[uentp->from_alias] :
- uentp->from
-#else
- uentp->from
-#endif
- : "*");
- case 2:
- snprintf(description, sizeof(description),
- "%4d/%4d/%2d %c", uentp->five_win,
- uentp->five_lose, uentp->five_tie,
- (uentp->withme&WITHME_FIVE)?'o':(uentp->withme&WITHME_NOFIVE)?'x':' ');
- return description;
- case 3:
- snprintf(description, sizeof(description),
- "%4d/%4d/%2d %c", uentp->chc_win,
- uentp->chc_lose, uentp->chc_tie,
- (uentp->withme&WITHME_CHESS)?'o':(uentp->withme&WITHME_NOCHESS)?'x':' ');
- return description;
- case 4:
- snprintf(description, sizeof(description),
- "%4d %s", uentp->chess_elo_rating,
- (uentp->withme&WITHME_CHESS)?"§ä§Ú¤U´Ñ":(uentp->withme&WITHME_NOCHESS)?"§O§ä§Ú":"");
- return description;
- case 5:
- snprintf(description, sizeof(description),
- "%4d/%4d/%2d %c", uentp->go_win,
- uentp->go_lose, uentp->go_tie,
- (uentp->withme&WITHME_GO)?'o':(uentp->withme&WITHME_NOGO)?'x':' ');
- return description;
- default:
- syslog(LOG_WARNING, "damn!!! what's wrong?? show_mode = %d",
- show_mode);
- return "";
- }
-}
-
-/*
- * userlist
- *
- * ¦³§O©ó¨ä¥L¤j³¡¥÷ bbs¦b¹ê§@¨Ï¥ÎªÌ¦W³æ®É, ³£¬O±N©Ò¦³ online users ¨ú¤@¥÷¨ì
- * local space ¤¤, «ö·Ó©Ò¶·­nªº¤è¦¡ sort ¦n (¦p«ö·Ó userid , ¤­¤l´Ñ, ¨Ó·½µ¥
- * µ¥) . ³o±N³y¦¨¤j¶qªº®ö¶O: ¬°¤°»ò¨C­Ó¤H³£­n¬°¤F²£¥Í³o¤@­¶¶È 20 ­Ó¤Hªº¸ê®Æ
- * ¦Ó¥h sort ¨ä¥L¤@¸U¤Hªº¸ê®Æ?
- *
- * ¤@¯ë¨Ó»¡, ¤@¥÷§¹¾ãªº¨Ï¥ÎªÌ¦W³æ¥i¥H¤À¦¨¡u¦n¤Í°Ï¡v©M¡u«D¦n¤Í°Ï¡v. ¤£¦P¤Hªº
- * ¡u¦n¤Í°Ï¡vÀ³¸Ó·|ªøªº¤£¤@¼Ë, ¤£¹L¡u«D¦n¤Í°Ï¡vÀ³¸Ó¬Oªøªº¤@¼Ëªº. °w¹ï³o¶µ¯S
- * ©Ê, ¨â°Ï¦³¤£¦Pªº¹ê§@¤è¦¡.
- *
- * + ¦n¤Í°Ï
- * ¦n¤Í°Ï¥u¦³¦b±Æ¦C¤è¦¡¬° [¶Ù! ªB¤Í] ªº®É­Ô¡u¥i¯à¡v·|¥Î¨ì.
- * ¨C­Ó process¥i¥H³z¹L currutmp->friend_online[]±o¨ì¤¬¬Û¶¡¦³¦n¤ÍÃö«Yªº¸ê
- * ®Æ (¤£¥]¬AªO¤Í, ªO¤Í¬O¥t¥~¥Í¥X¨Óªº) ¤£¹L friend_online[]¬O unorderªº.
- * ©Ò¥H¶·­n¥ý§â©Ò¦³ªº¤H®³¥X¨Ó, ­«·s sort ¤@¦¸.
- * ¦n¤Í°Ï (¤¬¬Û¥ô¤@¤è¦³³]¦n¤Í+ ªO¤Í) ³Ì¦h¥u·|¦³ MAX_FRIENDS­Ó
- * ¦]¬°²£¥Í¦n¤Í°Ïªº cost ¬Û·í°ª, "¯à¤£²£¥Í´N¤£­n²£¥Í"
- *
- * + «D¦n¤Í°Ï
- * ³z¹L shmctl utmpsortd , ©w´Á (³q±`¤@¬í¤@¦¸) ±N¥þ¯¸ªº¤H«ö·Ó¦UºØ¤£¦Pªº¤è
- * ¦¡ sort ¦n, ©ñ¸m¦b SHM->sorted¤¤.
- *
- * ±µ¤U¨Ó, §Ú­Ì¨C¦¸¥u±q½T©wªº°_©l¦ì¸m®³, ¯S§O¬O°£«D¦³¶·­n, ¤£µM¤£·|¥h²£¥Í¦n
- * ¤Í°Ï.
- *
- * ¦U­Ó function ºK­n
- * sort_cmpfriend() sort function, key: friend type
- * pickup_maxpages() # pages of userlist
- * pickup_myfriend() ²£¥Í¦n¤Í°Ï
- * pickup_bfriend() ²£¥ÍªO¤Í
- * pickup() ²£¥Í¬Y¤@­¶¨Ï¥ÎªÌ¦W³æ
- * draw_pickup() §âµe­±¿é¥X
- * userlist() ¥D¨ç¦¡, ­t³d©I¥s pickup()/draw_pickup() ¥H¤Î«öÁä³B²z
- *
- * SEE ALSO
- * include/pttstruct.h
- *
- * BUGS
- * ·j´Mªº®É­Ô¨S¦³¿ìªk²¾¨ì¸Ó¤H¤W­±
- *
- * AUTHOR
- * in2 <in2@in2home.org>
- */
-char nPickups;
-
-static int
-sort_cmpfriend(const void *a, const void *b)
-{
- if (((((pickup_t *) a)->friend) & ST_FRIEND) ==
- ((((pickup_t *) b)->friend) & ST_FRIEND))
- return strcasecmp(((pickup_t *) a)->ui->userid,
- ((pickup_t *) b)->ui->userid);
- else
- return (((pickup_t *) b)->friend & ST_FRIEND) -
- (((pickup_t *) a)->friend & ST_FRIEND);
-}
-
-int
-pickup_maxpages(int pickupway, int nfriends)
-{
- int number;
- if (cuser.uflag & FRIEND_FLAG)
- number = nfriends;
- else
- number = SHM->UTMPnumber +
- (pickupway == 0 ? nfriends : 0);
- return (number - 1) / nPickups + 1;
-}
-
-static int
-pickup_myfriend(pickup_t * friends,
- int *myfriend, int *friendme, int *badfriend)
-{
- userinfo_t *uentp;
- int i, where, frstate, ngets = 0;
-
- STATINC(STAT_PICKMYFRIEND);
- *badfriend = 0;
- *myfriend = *friendme = 1;
- for (i = 0; currutmp->friend_online[i] && i < MAX_FRIEND; ++i) {
- where = currutmp->friend_online[i] & 0xFFFFFF;
- if (VALID_USHM_ENTRY(where) &&
- (uentp = &SHM->uinfo[where]) && uentp->pid &&
- uentp != currutmp &&
- isvisible_stat(currutmp, uentp,
- frstate =
- currutmp->friend_online[i] >> 24)){
- if( frstate & IRH )
- ++*badfriend;
- if( !(frstate & IRH) || ((frstate & IRH) && (frstate & IFH)) ){
- friends[ngets].ui = uentp;
- friends[ngets].uoffset = where;
- friends[ngets++].friend = frstate;
- if (frstate & IFH)
- ++* myfriend;
- if (frstate & HFM)
- ++* friendme;
- }
- }
- }
- /* §â¦Û¤v¥[¤J¦n¤Í°Ï */
- friends[ngets].ui = currutmp;
- friends[ngets++].friend = (IFH | HFM);
- return ngets;
-}
-
-static int
-pickup_bfriend(pickup_t * friends, int base)
-{
- userinfo_t *uentp;
- int i, ngets = 0;
- int currsorted = SHM->currsorted, number = SHM->UTMPnumber;
-
- STATINC(STAT_PICKBFRIEND);
- friends = friends + base;
- for (i = 0; i < number && ngets < MAX_FRIEND - base; ++i) {
- uentp = &SHM->uinfo[SHM->sorted[currsorted][0][i]];
- /* TODO isvisible() ­«½Æ¥Î¨ì¤F friend_stat() */
- if (uentp && uentp->pid && uentp->brc_id == currutmp->brc_id &&
- currutmp != uentp && isvisible(currutmp, uentp) &&
- (base || !(friend_stat(currutmp, uentp) & (IFH | HFM)))) {
- friends[ngets].ui = uentp;
- friends[ngets++].friend = IBH;
- }
- }
- return ngets;
-}
-
-static void
-pickup(pickup_t * currpickup, int pickup_way, int *page,
- int *nfriend, int *myfriend, int *friendme, int *bfriend, int *badfriend)
-{
- /* avoid race condition */
- int currsorted = SHM->currsorted;
- int utmpnumber = SHM->UTMPnumber;
- int friendtotal = currutmp->friendtotal;
-
- int *ulist;
- userinfo_t *u;
- int which, sorted_way, size = 0, friend;
-
- if (friendtotal == 0)
- *myfriend = *friendme = 1;
-
- /* ²£¥Í¦n¤Í°Ï */
- which = *page * nPickups;
- if( (cuser.uflag & FRIEND_FLAG) || /* ¥uÅã¥Ü¦n¤Í¼Ò¦¡ */
- ((pickup_way == 0) && /* [¶Ù! ªB¤Í] mode */
- (
- /* §tªO¤Í, ¦n¤Í°Ï³Ì¦h¥u·|¦³ (friendtotal + ªO¤Í) ­Ó*/
- (currutmp->brc_id && which < (friendtotal + 1 +
- getbcache(currutmp->brc_id)->nuser)) ||
-
- /* ¤£§tªO¤Í, ³Ì¦h¥u·|¦³ friendtotal­Ó */
- (!currutmp->brc_id && which < friendtotal + 1)
- ))) {
- pickup_t friends[MAX_FRIEND];
-
- /* TODO ·í friendtotal<which ®É¥u»ÝÅã¥ÜªO¤Í, ¤£»Ý pickup_myfriend */
- *nfriend = pickup_myfriend(friends, myfriend, friendme, badfriend);
-
- if (pickup_way == 0 && currutmp->brc_id != 0
-#ifdef USE_COOLDOWN
- && !(getbcache(currutmp->brc_id)->brdattr & BRD_COOLDOWN)
-#endif
- ){
- /* TODO ¥u»Ý­n which+nPickups-*nfriend ­ÓªO¤Í, ¤£¤@©w­n¾ã­Ó±½¤@¹M */
- *nfriend += pickup_bfriend(friends, *nfriend);
- *bfriend = SHM->bcache[currutmp->brc_id - 1].nuser;
- }
- else
- *bfriend = 0;
- if (*nfriend > which) {
- /* ¥u¦³¦b­n¨q¥X¤~¦³¥²­n sort */
- /* TODO ¦n¤Í¸òªO¤Í¥i¥H¤À¶} sort, ¥i¯à¥u»Ý­n¨ä¤@ */
- /* TODO ¦n¤Í¤W¤U¯¸¤~»Ý­n sort ¤@¦¸, ¤£»Ý­n¨C¦¸ sort.
- * ¥iºûÅ@¤@­Ó dirty bit ªí¥Ü¬O§_ sort ¹L.
- * suggested by WYchuang@ptt */
- qsort(friends, *nfriend, sizeof(pickup_t), sort_cmpfriend);
- size = *nfriend - which;
- if (size > nPickups)
- size = nPickups;
- memcpy(currpickup, friends + which, sizeof(pickup_t) * size);
- }
- } else
- *nfriend = 0;
-
- if (!(cuser.uflag & FRIEND_FLAG) && size < nPickups) {
- sorted_way = ((pickup_way == 0) ? 7 : (pickup_way - 1));
- ulist = SHM->sorted[currsorted][sorted_way];
- which = *page * nPickups - *nfriend;
- if (which < 0)
- which = 0;
-
- for (; which < utmpnumber && size < nPickups; which++) {
- u = &SHM->uinfo[ulist[which]];
-
- friend = friend_stat(currutmp, u);
- /* TODO isvisible() ­«½Æ¥Î¨ì¤F friend_stat() */
- if ((pickup_way ||
- (currutmp != u && !(friend & ST_FRIEND))) &&
- isvisible(currutmp, u)) {
- currpickup[size].ui = u;
- currpickup[size++].friend = friend;
- }
- }
- }
-
- for (; size < nPickups; ++size)
- currpickup[size].ui = 0;
-}
-
-static void
-draw_pickup(int drawall, pickup_t * pickup, int pickup_way,
- int page, int show_mode, int show_uid, int show_board,
- int show_pid, int myfriend, int friendme, int bfriend, int badfriend)
-{
- char *msg_pickup_way[PICKUP_WAYS] = {
- "¶Ù! ªB¤Í", "ºô¤Í¥N¸¹", "ºô¤Í°ÊºA", "µo§b®É¶¡", "¨Ó¦Û¦ó¤è", " ¤­¤l´Ñ ", " ¶H´Ñ ", " ³ò´Ñ ",
- };
- char *MODE_STRING[MAX_SHOW_MODE] = {
- "¬G¶m", "¦n¤Í´y­z", "¤­¤l´Ñ¾ÔÁZ", "¶H´Ñ¾ÔÁZ", "¶H´Ñµ¥¯Å¤À", "³ò´Ñ¾ÔÁZ",
- };
- char pagerchar[5] = "* -Wf";
-
- userinfo_t *uentp;
- int i, ch, state, friend;
- char mind[5];
-
-#ifdef SHOW_IDLE_TIME
- char idlestr[32];
- int idletime;
-#endif
-
- /* wide screen support */
- int wNick = 17, wMode = 12; //13; , one byte give number for ptt always > 10000 online.
-
- if (t_columns > 80)
- {
- int d = t_columns - 80;
-
- /* rule: try to give extra space to both nick and mode,
- * because nick is smaller, try nick first then mode. */
- if (d >= sizeof(cuser.nickname) - wNick)
- {
- d -= (sizeof(cuser.nickname) - wNick);
- wNick = sizeof(cuser.nickname);
- wMode += d;
- } else {
- wNick += d;
- }
- }
-
- if (drawall) {
- showtitle((cuser.uflag & FRIEND_FLAG) ? "¦n¤Í¦Cªí" : "¥ð¶¢²á¤Ñ",
- BBSName);
- prints("\n"
- ANSI_COLOR(7) " %s P%c¥N¸¹ %-*s%-17s%-*s%10s"
- ANSI_RESET "\n",
- show_uid ? "UID " : "½s¸¹",
- (HasUserPerm(PERM_SEECLOAK) || HasUserPerm(PERM_SYSOP)) ?
- 'C' : ' ',
- wNick, "¼ÊºÙ",
- MODE_STRING[show_mode],
- wMode, show_board ? "Board" : "°ÊºA",
- show_pid ? " PID" : "¤ß±¡ "
-#ifdef SHOW_IDLE_TIME
- "µo§b"
-#else
- " "
-#endif
- );
- move(b_lines, 0);
- outslr(
- ANSI_COLOR(34;46) " ¥ð¶¢²á¤Ñ "
- ANSI_COLOR(31;47) " (TAB/f)" ANSI_COLOR(30) "±Æ§Ç/¦n¤Í "
- ANSI_COLOR(31) "(a/o)" ANSI_COLOR(30) "¥æ¤Í "
- ANSI_COLOR(31) "(q/w)" ANSI_COLOR(30) "¬d¸ß/¥á¤ô²y "
- ANSI_COLOR(31) "(t/m)" ANSI_COLOR(30) "²á¤Ñ/¼g«H ",
- 80-10,
- ANSI_COLOR(31) "(h)" ANSI_COLOR(30) "»¡©ú " ANSI_RESET,
- 8);
- }
- move(1, 0);
- prints(" ±Æ§Ç:[%s] ¤W¯¸¤H¼Æ:%-4d "
- ANSI_COLOR(1;32) "§ÚªºªB¤Í:%-3d "
- ANSI_COLOR(33) "»P§Ú¬°¤Í:%-3d "
- ANSI_COLOR(36) "ªO¤Í:%-4d "
- ANSI_COLOR(31) "Ãa¤H:%-2d"
- ANSI_RESET "\n",
- msg_pickup_way[pickup_way], SHM->UTMPnumber,
- myfriend, friendme, currutmp->brc_id ? bfriend : 0, badfriend);
-
- for (i = 0, ch = page * nPickups + 1; i < nPickups; ++i, ++ch) {
- move(i + 3, 0);
- outc('a');
- move(i + 3, 0);
- uentp = pickup[i].ui;
- friend = pickup[i].friend;
- if (uentp == NULL) {
- outc('\n');
- continue;
- }
- if (!uentp->pid) {
- prints("%5d < Â÷¯¸¤¤..>\n", ch);
- continue;
- }
- if (PERM_HIDE(uentp))
- state = 9;
- else if (currutmp == uentp)
- state = 10;
- else if (friend & IRH && !(friend & IFH))
- state = 8;
- else
- state = (friend & ST_FRIEND) >> 2;
-
-#ifdef SHOW_IDLE_TIME
- idletime = (now - uentp->lastact);
- if (idletime > 86400)
- strlcpy(idlestr, " -----", sizeof(idlestr));
- else if (idletime >= 3600)
- snprintf(idlestr, sizeof(idlestr), "%3dh%02d",
- idletime / 3600, (idletime / 60) % 60);
- else if (idletime > 0)
- snprintf(idlestr, sizeof(idlestr), "%3d'%02d",
- idletime / 60, idletime % 60);
- else
- strlcpy(idlestr, " ", sizeof(idlestr));
-#endif
-
- if ((uentp->userlevel & PERM_VIOLATELAW))
- memcpy(mind, "³q½r", 4);
- else if (uentp->birth)
- memcpy(mind, "¹Ø¬P", 4);
- else
- memcpy(mind, uentp->mind, 4);
- mind[4] = 0;
-
- /* TODO
- * will this be faster if we use pure outc/outs?
- */
- prints("%7d %c%c%s%-13s%-*.*s " ANSI_RESET "%-16.16s %-*.*s"
- ANSI_COLOR(33) "%-4.4s" ANSI_RESET "%s\n",
-
- /* list number or uid */
-#ifdef SHOWUID
- show_uid ? uentp->uid :
-#endif
- ch,
-
- /* super friend or pager */
- (friend & HRM) ? 'X' : pagerchar[uentp->pager % 5],
-
- /* visibility */
- (uentp->invisible ? ')' : ' '),
-
- /* color of userid, userid */
- fcolor[state], uentp->userid,
-
- /* nickname */
- wNick-1, wNick-1, uentp->nickname,
-
- /* from */
- descript(show_mode, uentp,
- uentp->pager & !(friend & HRM)),
-
- /* board or mode */
- wMode, wMode,
-#if defined(SHOWBOARD) && defined(DEBUG)
- show_board ? (uentp->brc_id == 0 ? "" :
- getbcache(uentp->brc_id)->brdname) :
-#endif
- modestring(uentp, 0),
-
- /* memo */
- mind,
-
- /* idle */
-#ifdef SHOW_IDLE_TIME
- idlestr
-#else
- ""
-#endif
- );
-
- //refresh();
- }
-}
-
-void set_withme_flag(void)
-{
- int i;
- char genbuf[20];
- int line;
-
- move(1, 0);
- clrtobot();
-
- do {
- move(1, 0);
- line=1;
- for(i=0; i<16 && withme_str[i]; i++) {
- clrtoeol();
- if(currutmp->withme&(1<<(i*2)))
- prints("[%c] §Ú«Ü·Q¸ò¤H%s, Åwªï¥ô¦ó¤H§ä§Ú\n",'a'+i, withme_str[i]);
- else if(currutmp->withme&(1<<(i*2+1)))
- prints("[%c] §Ú¤£¤Ó·Q%s\n",'a'+i, withme_str[i]);
- else
- prints("[%c] (%s)¨S·N¨£\n",'a'+i, withme_str[i]);
- line++;
- }
- getdata(line,0,"¥Î¦r¥À¤Á´« [·Q/¤£·Q/¨S·N¨£]",genbuf, sizeof(genbuf), DOECHO);
- for(i=0;genbuf[i];i++) {
- int ch=genbuf[i];
- ch=tolower(ch);
- if('a'<=ch && ch<'a'+16) {
- ch-='a';
- if(currutmp->withme&(1<<ch*2)) {
- currutmp->withme&=~(1<<ch*2);
- currutmp->withme|=1<<(ch*2+1);
- } else if(currutmp->withme&(1<<(ch*2+1))) {
- currutmp->withme&=~(1<<(ch*2+1));
- } else {
- currutmp->withme|=1<<(ch*2);
- }
- }
- }
- } while(genbuf[0]!='\0');
-}
-
-int
-call_in(const userinfo_t * uentp, int fri_stat)
-{
- if (iswritable_stat(uentp, fri_stat)) {
- char genbuf[60];
- snprintf(genbuf, sizeof(genbuf), "¥á %s ¤ô²y: ", uentp->userid);
- my_write(uentp->pid, genbuf, uentp->userid, WATERBALL_GENERAL, NULL);
- return 1;
- }
- return 0;
-}
-
-inline static void
-userlist(void)
-{
- pickup_t *currpickup;
- userinfo_t *uentp;
- static char show_mode = 0;
- static char show_uid = 0;
- static char show_board = 0;
- static char show_pid = 0;
- static int pickup_way = 0;
- char skippickup = 0, redraw, redrawall;
- int page, offset, ch, leave, fri_stat;
- int nfriend, myfriend, friendme, bfriend, badfriend, i;
- time4_t lastupdate;
-
- nPickups = b_lines - 3;
- currpickup = (pickup_t *)malloc(sizeof(pickup_t) * nPickups);
- page = offset = 0 ;
- nfriend = myfriend = friendme = bfriend = badfriend = 0;
- leave = 0;
- redrawall = 1;
- /*
- * ¦U­Ó flag :
- * redraw: ­«·s pickup(), draw_pickup() (¶È¤¤¶¡°Ï, ¤£§t¼ÐÃD¦Cµ¥µ¥)
- * redrawall: ¥þ³¡­«µe (§t¼ÐÃD¦Cµ¥µ¥, ¶·¦A«ü©w redraw ¤~·|¦³®Ä)
- * leave: Â÷¶}¨Ï¥ÎªÌ¦W³æ
- */
- while (!leave) {
- if( !skippickup )
- pickup(currpickup, pickup_way, &page,
- &nfriend, &myfriend, &friendme, &bfriend, &badfriend);
- draw_pickup(redrawall, currpickup, pickup_way, page,
- show_mode, show_uid, show_board, show_pid,
- myfriend, friendme, bfriend, badfriend);
-
- /*
- * ¦pªG¦]¬°´«­¶ªº®É­Ô, ³o¤@­¶¦³ªº¤H¼Æ¤ñ¸û¤Ö,
- * (³q±`³£¬O³Ì«á¤@­¶¤H¼Æ¤£º¡ªº®É­Ô) ¨º­n­«·s­pºâ offset
- * ¥H§K«ü¨ì¨S¦³¤Hªº¦a¤è
- */
- if (offset == -1 || currpickup[offset].ui == NULL) {
- for (offset = (offset == -1 ? nPickups - 1 : offset);
- offset >= 0; --offset)
- if (currpickup[offset].ui != NULL)
- break;
- if (offset == -1) {
- if (--page < 0)
- page = pickup_maxpages(pickup_way, nfriend) - 1;
- offset = 0;
- continue;
- }
- }
- skippickup = redraw = redrawall = 0;
- lastupdate = now;
- while (!redraw) {
- ch = cursor_key(offset + 3, 0);
- uentp = currpickup[offset].ui;
- fri_stat = currpickup[offset].friend;
-
- switch (ch) {
- case KEY_LEFT:
- case 'e':
- case 'E':
- redraw = leave = 1;
- break;
-
- case KEY_TAB:
- pickup_way = (pickup_way + 1) % PICKUP_WAYS;
- redraw = 1;
- redrawall = 1;
- break;
-
- case KEY_DOWN:
- case 'n':
- case 'j':
- if (++offset == nPickups || currpickup[offset].ui == NULL) {
- redraw = 1;
- if (++page >= pickup_maxpages(pickup_way,
- nfriend))
- offset = page = 0;
- else
- offset = 0;
- }
- break;
-
- case '0':
- case KEY_HOME:
- page = offset = 0;
- redraw = 1;
- break;
-
- case 'H':
- if (HasUserPerm(PERM_SYSOP)||HasUserPerm(PERM_OLDSYSOP)) {
- currutmp->userlevel ^= PERM_SYSOPHIDE;
- redrawall = redraw = 1;
- }
- break;
-
- case 'C':
-#if !HAVE_FREECLOAK
- if (HasUserPerm(PERM_CLOAK))
-#endif
- {
- currutmp->invisible ^= 1;
- redrawall = redraw = 1;
- }
- break;
-
- case ' ':
- case KEY_PGDN:
- case Ctrl('F'):{
- int newpage;
- if ((newpage = page + 1) >= pickup_maxpages(pickup_way,
- nfriend))
- newpage = offset = 0;
- if (newpage != page) {
- page = newpage;
- redraw = 1;
- } else if (now >= lastupdate + 2)
- redrawall = redraw = 1;
- }
- break;
-
- case KEY_UP:
- case 'k':
- if (--offset == -1) {
- offset = nPickups - 1;
- if (--page == -1)
- page = pickup_maxpages(pickup_way, nfriend)
- - 1;
- redraw = 1;
- }
- break;
-
- case KEY_PGUP:
- case Ctrl('B'):
- case 'P':
- if (--page == -1)
- page = pickup_maxpages(pickup_way, nfriend) - 1;
- offset = 0;
- redraw = 1;
- break;
-
- case KEY_END:
- case '$':
- page = pickup_maxpages(pickup_way, nfriend) - 1;
- offset = -1;
- redraw = 1;
- break;
-
- case '/':
- /*
- * getdata_buf(b_lines-1,0,"½Ð¿é¤J¼ÊºÙÃöÁä¦r:", keyword,
- * sizeof(keyword), DOECHO); state = US_PICKUP;
- */
- break;
-
- case 's':
- if (!(cuser.uflag & FRIEND_FLAG)) {
- int si; /* utmpshm->sorted[X][0][si] */
- int fi; /* allpickuplist[fi] */
- char swid[IDLEN + 1];
- move(1, 0);
- si = CompleteOnlineUser(msg_uid, swid);
- if (si >= 0) {
- pickup_t friends[MAX_FRIEND + 1];
- int nGots, i;
- int *ulist =
- SHM->sorted[SHM->currsorted]
- [((pickup_way == 0) ? 0 : (pickup_way - 1))];
-
- fi = ulist[si];
- nGots = pickup_myfriend(friends, &myfriend,
- &friendme, &badfriend);
- for (i = 0; i < nGots; ++i)
- if (friends[i].uoffset == fi)
- break;
-
- fi = 0;
- offset = 0;
- if( i != nGots ){
- page = i / nPickups;
- for( ; i < nGots && fi < nPickups ; ++i )
- if( isvisible(currutmp, friends[i].ui) )
- currpickup[fi++] = friends[i];
- i = 0;
- }
- else{
- page = (si + nGots) / nPickups;
- i = si;
- }
-
- for( ; fi < nPickups && i < SHM->UTMPnumber ; ++i )
- {
- userinfo_t *u;
- u = &SHM->uinfo[ulist[i]];
- if( isvisible(currutmp, u) ){
- currpickup[fi].ui = u;
- currpickup[fi++].friend = 0;
- }
- }
- skippickup = 1;
- }
- redrawall = redraw = 1;
- }
- /*
- * if ((i = search_pickup(num, actor, pklist)) >= 0) num = i;
- * state = US_ACTION;
- */
- break;
-
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- { /* Thor: ¥i¥H¥´¼Æ¦r¸õ¨ì¸Ó¤H */
- int tmp;
- if ((tmp = search_num(ch, SHM->UTMPnumber)) >= 0) {
- if (tmp / nPickups == page) {
- /*
- * in2:¥Øªº¦b¥Ø«e³o¤@­¶, ª½±µ §ó·s offset ,
- * ¤£¥Î­«µeµe­±
- */
- offset = tmp % nPickups;
- } else {
- page = tmp / nPickups;
- offset = tmp % nPickups;
- }
- redrawall = redraw = 1;
- }
- }
- break;
-
-#ifdef SHOWUID
- case 'U':
- if (HasUserPerm(PERM_SYSOP)) {
- show_uid ^= 1;
- redrawall = redraw = 1;
- }
- break;
-#endif
-#if defined(SHOWBOARD) && defined(DEBUG)
- case 'Y':
- if (HasUserPerm(PERM_SYSOP)) {
- show_board ^= 1;
- redrawall = redraw = 1;
- }
- break;
-#endif
-#ifdef SHOWPID
- case '#':
- if (HasUserPerm(PERM_SYSOP)) {
- show_pid ^= 1;
- redrawall = redraw = 1;
- }
- break;
-#endif
-
- case 'b': /* broadcast */
- if (cuser.uflag & FRIEND_FLAG || HasUserPerm(PERM_SYSOP)) {
- char genbuf[60]="[¼s¼½]";
- char ans[4];
-
- if (!getdata(0, 0, "¼s¼½°T®§:", genbuf+6, 54, DOECHO))
- break;
-
- if (!getdata(0, 0, "½T©w¼s¼½? [N]",
- ans, sizeof(ans), LCECHO) ||
- ans[0] != 'y')
- break;
- if (!(cuser.uflag & FRIEND_FLAG) && HasUserPerm(PERM_SYSOP)) {
- msgque_t msg;
- getdata(1, 0, "¦A¦¸½T©w¯¸ªø¼s¼½? [N]",
- ans, sizeof(ans), LCECHO);
- if( ans[0] != 'y' && ans[0] != 'Y' ){
- vmsg("abort");
- break;
- }
-
- msg.pid = currpid;
- strlcpy(msg.userid, cuser.userid, sizeof(msg.userid));
- snprintf(msg.last_call_in, sizeof(msg.last_call_in),
- "[¼s¼½]%s", genbuf);
- for (i = 0; i < SHM->UTMPnumber; ++i) {
- // XXX why use sorted list?
- // can we just scan uinfo with proper checking?
- uentp = &SHM->uinfo[
- SHM->sorted[SHM->currsorted][0][i]];
- if (uentp->pid && kill(uentp->pid, 0) != -1){
- int write_pos = uentp->msgcount;
- if( write_pos < (MAX_MSGS - 1) ){
- uentp->msgcount = write_pos + 1;
- memcpy(&uentp->msgs[write_pos], &msg,
- sizeof(msg));
-#ifdef NOKILLWATERBALL
- uentp->wbtime = now;
-#else
- kill(uentp->pid, SIGUSR2);
-#endif
- }
- }
- }
- } else {
- userinfo_t *uentp;
- int where, frstate;
- for (i = 0; currutmp->friend_online[i] &&
- i < MAX_FRIEND; ++i) {
- where = currutmp->friend_online[i] & 0xFFFFFF;
- if (VALID_USHM_ENTRY(where) &&
- (uentp = &SHM->uinfo[where]) &&
- uentp->pid &&
- isvisible_stat(currutmp, uentp,
- frstate =
- currutmp->friend_online[i] >> 24)
- && kill(uentp->pid, 0) != -1 &&
- uentp->pager != PAGER_ANTIWB &&
- (uentp->pager != PAGER_FRIENDONLY || frstate & HFM) &&
- !(frstate & IRH)) {
- my_write(uentp->pid, genbuf, uentp->userid,
- WATERBALL_PREEDIT, NULL);
- }
- }
- }
- redrawall = redraw = 1;
- }
- break;
-
- case 'S': /* Åã¥Ü¦n¤Í´y­z */
- show_mode = (show_mode+1) % MAX_SHOW_MODE;
-#ifdef CHESSCOUNTRY
- if (show_mode == 2)
- user_query_mode = 1;
- else if (show_mode == 3 || show_mode == 4)
- user_query_mode = 2;
- else if (show_mode == 5)
- user_query_mode = 3;
- else
- user_query_mode = 0;
-#endif /* defined(CHESSCOUNTRY) */
- redrawall = redraw = 1;
- break;
-
- case 'u': /* ½u¤W­×§ï¸ê®Æ */
- if (HasUserPerm(PERM_ACCOUNTS|PERM_SYSOP)) {
- int id;
- userec_t muser;
- strlcpy(currauthor, uentp->userid, sizeof(currauthor));
- stand_title("¨Ï¥ÎªÌ³]©w");
- move(1, 0);
- if ((id = getuser(uentp->userid, &muser)) > 0) {
- user_display(&muser, 1);
- if( HasUserPerm(PERM_ACCOUNTS) )
- uinfo_query(&muser, 1, id);
- else
- pressanykey();
- }
- redrawall = redraw = 1;
- }
- break;
-
- case 'i':{
- char mindbuf[5];
- getdata(b_lines - 1, 0, "²{¦bªº¤ß±¡? ",
- mindbuf, sizeof(mindbuf), DOECHO);
- if (strcmp(mindbuf, "³q½r") == 0)
- vmsg("¤£¥i¥H§â¦Û¤v³]³q½r°Õ!");
- else if (strcmp(mindbuf, "¹Ø¬P") == 0)
- vmsg("§A¤£¬O¤µ¤Ñ¥Í¤éÕÙ!");
- else
- memcpy(currutmp->mind, mindbuf, 4);
- }
- redrawall = redraw = 1;
- break;
-
- case Ctrl('S'):
- break;
-
- case KEY_RIGHT:
- case '\n':
- case '\r':
- case 't':
- if (HasUserPerm(PERM_LOGINOK)) {
- if (uentp->pid != currpid &&
- strcmp(uentp->userid, cuser.userid) != 0) {
- move(1, 0);
- clrtobot();
- move(3, 0);
- my_talk(uentp, fri_stat, 0);
- redrawall = redraw = 1;
- }
- }
- break;
- case 'K':
- if (HasUserPerm(PERM_ACCOUNTS|PERM_SYSOP)) {
- my_kick(uentp);
- redrawall = redraw = 1;
- }
- break;
- case 'w':
- if (call_in(uentp, fri_stat))
- redrawall = redraw = 1;
- break;
- case 'a':
- if (HasUserPerm(PERM_LOGINOK) && !(fri_stat & IFH)) {
- if (getans("½T©w­n¥[¤J¦n¤Í¶Ü [N/y]") == 'y') {
- friend_add(uentp->userid, FRIEND_OVERRIDE,uentp->nickname);
- friend_load(FRIEND_OVERRIDE);
- }
- redrawall = redraw = 1;
- }
- break;
-
- case 'd':
- if (HasUserPerm(PERM_LOGINOK) && (fri_stat & IFH)) {
- if (getans("½T©w­n§R°£¦n¤Í¶Ü [N/y]") == 'y') {
- friend_delete(uentp->userid, FRIEND_OVERRIDE);
- friend_load(FRIEND_OVERRIDE);
- }
- redrawall = redraw = 1;
- }
- break;
-
- case 'o':
- if (HasUserPerm(PERM_LOGINOK)) {
- t_override();
- redrawall = redraw = 1;
- }
- break;
-
- case 'f':
- if (HasUserPerm(PERM_LOGINOK)) {
- cuser.uflag ^= FRIEND_FLAG;
- redrawall = redraw = 1;
- }
- break;
-
- case 'g':
- if (HasUserPerm(PERM_LOGINOK) &&
- strcmp(uentp->userid, cuser.userid) != 0) {
- give_money_ui(uentp->userid);
- redrawall = redraw = 1;
- }
- break;
-
- case 'm':
- if (HasUserPerm(PERM_LOGINOK)) {
- char userid[IDLEN + 1];
- strlcpy(userid, uentp->userid, sizeof(userid));
- stand_title("±H «H");
- prints("[±H«H] ¦¬«H¤H¡G%s", userid);
- my_send(userid);
- setutmpmode(LUSERS);
- redrawall = redraw = 1;
- }
- break;
-
- case 'q':
- strlcpy(currauthor, uentp->userid, sizeof(currauthor));
- my_query(uentp->userid);
- setutmpmode(LUSERS);
- redrawall = redraw = 1;
- break;
-
- case 'c':
- if (HasUserPerm(PERM_LOGINOK)) {
- chicken_query(uentp->userid);
- redrawall = redraw = 1;
- }
- break;
-
- case 'l':
- if (HasUserPerm(PERM_LOGINOK)) {
- t_display();
- redrawall = redraw = 1;
- }
- break;
-
- case 'h':
- t_showhelp();
- redrawall = redraw = 1;
- break;
-
- case 'p':
- if (HasUserPerm(PERM_BASIC)) {
- t_pager();
- redrawall = redraw = 1;
- }
- break;
-
- case Ctrl('W'):
- if (HasUserPerm(PERM_LOGINOK)) {
- int tmp;
- char *wm[3] = {"¤@¯ë", "¶i¶¥", "¥¼¨Ó"};
- tmp = cuser.uflag2 & WATER_MASK;
- cuser.uflag2 -= tmp;
- tmp = (tmp + 1) % 3;
- cuser.uflag2 |= tmp;
- /* vmsg cannot support multi lines */
- move(b_lines - 4, 0);
- clrtobot();
- move(b_lines - 3, 0);
- outs("¨t²Î´£¨Ñ ¤@¯ë ¶i¶¥ ¥¼¨Ó ¤TºØ¼Ò¦¡\n"
- "¦b¤Á´««á½Ð¥¿±`¤U½u¦A­«·sµn¤J, ¥H½T«Oµ²ºc¥¿½T\n");
- vmsgf( "¥Ø«e¤Á´«¨ì %s ¤ô²y¼Ò¦¡", wm[tmp]);
- redrawall = redraw = 1;
- }
- break;
-
- case 'r':
- if (HasUserPerm(PERM_LOGINOK)) {
- if (curredit & EDIT_MAIL) {
- /* deny reentrance, which may cause many problems */
- vmsg("§A¶i¤J¨Ï¥ÎªÌ¦Cªí«e´N¤w¸g¦b¾\\Ū«H¥ó¤F");
- } else {
- // XXX in fact we should check size here...
- // chkmailbox();
- m_read();
- setutmpmode(LUSERS);
- }
- redrawall = redraw = 1;
- }
- break;
-
- case 'N':
- if (HasUserPerm(PERM_LOGINOK)) {
- char tmp_nick[sizeof(cuser.nickname)];
- // XXX why do so many copy here?
- // why not just use cuser.nickname?
- // XXX old code forget to initialize.
- // will changing to init everytime cause user
- // complain?
-
- strlcpy(tmp_nick, currutmp->nickname, sizeof(cuser.nickname));
-
- if (oldgetdata(1, 0, "·sªº¼ÊºÙ: ",
- tmp_nick, sizeof(tmp_nick), DOECHO) > 0)
- {
- strlcpy(cuser.nickname, tmp_nick, sizeof(cuser.nickname));
- strcpy(currutmp->nickname, cuser.nickname);
- }
- redrawall = redraw = 1;
- }
- break;
-
- case 'y':
- set_withme_flag();
- redrawall = redraw = 1;
- break;
-
- default:
- if (now >= lastupdate + 2)
- redraw = 1;
- }
- }
- }
- free(currpickup);
-}
-
-int
-t_users(void)
-{
- int destuid0 = currutmp->destuid;
- int mode0 = currutmp->mode;
- int stat0 = currstat;
-
- assert(strncmp(cuser.userid, currutmp->userid, IDLEN)==0);
- if( strncmp(cuser.userid , currutmp->userid, IDLEN) != 0 ){
- abort_bbs(0);
- }
-
- setutmpmode(LUSERS);
- userlist();
- currutmp->mode = mode0;
- currutmp->destuid = destuid0;
- currstat = stat0;
- return 0;
-}
-
-int
-t_pager(void)
-{
- currutmp->pager = (currutmp->pager + 1) % PAGER_MODES;
- return 0;
-}
-
-int
-t_idle(void)
-{
- int destuid0 = currutmp->destuid;
- int mode0 = currutmp->mode;
- int stat0 = currstat;
- char genbuf[20];
- char passbuf[PASSLEN];
- int idle_type;
- char idle_reason[sizeof(currutmp->chatid)];
-
-
- setutmpmode(IDLE);
- getdata(b_lines - 1, 0, "²z¥Ñ¡G[0]µo§b (1)±µ¹q¸Ü (2)³V­¹ (3)¥´½OºÎ "
- "(4)¸Ë¦º (5)ù¤¦ (6)¨ä¥L (Q)¨S¨Æ¡H", genbuf, 3, DOECHO);
- if (genbuf[0] == 'q' || genbuf[0] == 'Q') {
- currutmp->mode = mode0;
- currstat = stat0;
- return 0;
- } else if (genbuf[0] >= '1' && genbuf[0] <= '6')
- idle_type = genbuf[0] - '0';
- else
- idle_type = 0;
-
- if (idle_type == 6) {
- if (cuser.userlevel && getdata(b_lines - 1, 0, "µo§bªº²z¥Ñ¡G", idle_reason, sizeof(idle_reason), DOECHO)) {
- strlcpy(currutmp->chatid, idle_reason, sizeof(currutmp->chatid));
- } else {
- idle_type = 0;
- }
- }
- currutmp->destuid = idle_type;
- do {
- move(b_lines - 2, 0);
- clrtobot();
- prints("(Âê©w¿Ã¹õ)µo§b­ì¦]: %s", (idle_type != 6) ?
- IdleTypeTable[idle_type] : idle_reason);
- refresh();
- getdata(b_lines - 1, 0, MSG_PASSWD, passbuf, sizeof(passbuf), NOECHO);
- passbuf[8] = '\0';
- }
- while (!checkpasswd(cuser.passwd, passbuf) &&
- strcmp(STR_GUEST, cuser.userid));
-
- currutmp->mode = mode0;
- currutmp->destuid = destuid0;
- currstat = stat0;
-
- return 0;
-}
-
-int
-t_qchicken(void)
-{
- char uident[STRLEN];
-
- stand_title("¬d¸ßÃdª«");
- usercomplete(msg_uid, uident);
- if (uident[0])
- chicken_query(uident);
- return 0;
-}
-
-int
-t_query(void)
-{
- char uident[STRLEN];
-
- stand_title("¬d¸ßºô¤Í");
- usercomplete(msg_uid, uident);
- if (uident[0])
- my_query(uident);
- return 0;
-}
-
-int
-t_talk(void)
-{
- char uident[16];
- int tuid, unum, ucount;
- userinfo_t *uentp;
- char genbuf[4];
- /*
- * if (count_ulist() <= 1){ outs("¥Ø«e½u¤W¥u¦³±z¤@¤H¡A§ÖÁܽЪB¤Í¨Ó¥úÁ{¡i"
- * BBSNAME "¡j§a¡I"); return XEASY; }
- */
- stand_title("¥´¶}¸Ü§X¤l");
- CompleteOnlineUser(msg_uid, uident);
- if (uident[0] == '\0')
- return 0;
-
- move(3, 0);
- if (!(tuid = searchuser(uident, uident)) || tuid == usernum) {
- outs(err_uid);
- pressanykey();
- return 0;
- }
- /* multi-login check */
- unum = 1;
- while ((ucount = count_logins(tuid, 0)) > 1) {
- outs("(0) ¤£·Q talk ¤F...\n");
- count_logins(tuid, 1);
- getdata(1, 33, "½Ð¿ï¾Ü¤@­Ó²á¤Ñ¹ï¶H [0]¡G", genbuf, 4, DOECHO);
- unum = atoi(genbuf);
- if (unum == 0)
- return 0;
- move(3, 0);
- clrtobot();
- if (unum > 0 && unum <= ucount)
- break;
- }
-
- if ((uentp = (userinfo_t *) search_ulistn(tuid, unum)))
- my_talk(uentp, friend_stat(currutmp, uentp), 0);
-
- return 0;
-}
-
-int
-reply_connection_request(const userinfo_t *uip)
-{
- char buf[4], genbuf[200];
-
- if (uip->mode != PAGE) {
- snprintf(genbuf, sizeof(genbuf),
- "%s¤w°±¤î©I¥s¡A«öEnterÄ~Äò...", page_requestor);
- getdata(0, 0, genbuf, buf, sizeof(buf), LCECHO);
- return -1;
- }
- return establish_talk_connection(uip);
-}
-
-int
-establish_talk_connection(const userinfo_t *uip)
-{
- int a;
- struct sockaddr_in sin;
-
- currutmp->msgcount = 0;
- strlcpy(save_page_requestor, page_requestor, sizeof(save_page_requestor));
- memset(page_requestor, 0, sizeof(page_requestor));
- memset(&sin, 0, sizeof(sin));
- sin.sin_family = PF_INET;
- sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- sin.sin_port = uip->sockaddr;
- if ((a = socket(sin.sin_family, SOCK_STREAM, 0)) < 0) {
- perror("socket err");
- return -1;
- }
- if ((connect(a, (struct sockaddr *) & sin, sizeof(sin)))) {
- //perror("connect err");
- return -1;
- }
- return a;
-}
-
-/* ¦³¤H¨Ó¦êªù¤l¤F¡A¦^À³©I¥s¾¹ */
-void
-talkreply(void)
-{
- char buf[4];
- char genbuf[200];
- int a, sig = currutmp->sig;
- int currstat0 = currstat;
- int r;
- int is_chess;
- userec_t xuser;
- void (*sig_pipe_handle)(int);
-
- uip = &SHM->uinfo[currutmp->destuip];
- currutmp->destuid = uip->uid;
- currstat = REPLY; /* ÁקK¥X²{°Êµe */
-
- is_chess = (sig == SIG_CHC || sig == SIG_GOMO || sig == SIG_GO || sig == SIG_REVERSI);
-
- a = reply_connection_request(uip);
- if (a < 0) {
- clear();
- currstat = currstat0;
- return;
- }
- if (is_chess)
- ChessAcceptingRequest(a);
-
- clear();
-
- outs("\n\n");
- // FIXME CRASH here
- assert(sig>=0 && sig<sizeof(sig_des)/sizeof(sig_des[0]));
- prints(" (Y) Åý§Ú­Ì %s §a¡I"
- " (A) §Ú²{¦b«Ü¦£¡A½Ðµ¥¤@·|¨à¦A call §Ú\n", sig_des[sig]);
- prints(" (N) §Ú²{¦b¤£·Q %s"
- " (B) ¹ï¤£°_¡A§Ú¦³¨Æ±¡¤£¯à¸ò§A %s\n",
- sig_des[sig], sig_des[sig]);
- prints(" (C) ½Ð¤£­n§n§Ú¦n¶Ü¡H"
- " (D) §Ú­nÂ÷¯¸Åo..¤U¦¸¦A²á§a.......\n");
- prints(" (E) ¦³¨Æ¶Ü¡H½Ð¥ý¨Ó«H"
- " (F) " ANSI_COLOR(1;33) "§Ú¦Û¤v¿é¤J²z¥Ñ¦n¤F..." ANSI_RESET "\n");
- prints(" (1) %s¡H¥ý®³100»È¨â¨Ó"
- " (2) %s¡H¥ý®³1000»È¨â¨Ó..\n\n", sig_des[sig], sig_des[sig]);
-
- snprintf(page_requestor, sizeof(page_requestor),
- "%s (%s)", uip->userid, uip->nickname);
- getuser(uip->userid, &xuser);
- currutmp->msgs[0].pid = uip->pid;
- strlcpy(currutmp->msgs[0].userid, uip->userid, sizeof(currutmp->msgs[0].userid));
- strlcpy(currutmp->msgs[0].last_call_in, "©I¥s¡B©I¥s¡AÅ¥¨ì½Ð¦^µª (Ctrl-R)",
- sizeof(currutmp->msgs[0].last_call_in));
- currutmp->msgs[0].msgmode = MSGMODE_TALK;
- prints("¹ï¤è¨Ó¦Û [%s]¡A¦@¤W¯¸ %d ¦¸¡A¤å³¹ %d ½g\n",
- uip->from, xuser.numlogins, xuser.numposts);
-
- if (is_chess)
- ChessShowRequest();
- else {
- showplans(uip->userid);
- show_call_in(0, 0);
- }
-
- snprintf(genbuf, sizeof(genbuf),
- "§A·Q¸ò %s %s°Ú¡H½Ð¿ï¾Ü(Y/N/A/B/C/D/E/F/1/2)[N] ",
- page_requestor, sig_des[sig]);
- getdata(0, 0, genbuf, buf, sizeof(buf), LCECHO);
-
- if (!buf[0] || !strchr("yabcdef12", buf[0]))
- buf[0] = 'n';
-
- sig_pipe_handle = Signal(SIGPIPE, SIG_IGN);
- r = write(a, buf, 1);
- if (buf[0] == 'f' || buf[0] == 'F') {
- if (!getdata(b_lines, 0, "¤£¯àªº­ì¦]¡G", genbuf, 60, DOECHO))
- strlcpy(genbuf, "¤£§i¶D§A«¨ !! ^o^", sizeof(genbuf));
- r = write(a, genbuf, 60);
- }
- Signal(SIGPIPE, sig_pipe_handle);
-
- if (r == -1) {
- snprintf(genbuf, sizeof(genbuf),
- "%s¤w°±¤î©I¥s¡A«öEnterÄ~Äò...", page_requestor);
- getdata(0, 0, genbuf, buf, sizeof(buf), LCECHO);
- clear();
- currstat = currstat0;
- return;
- }
-
- uip->destuip = currutmp - &SHM->uinfo[0];
- if (buf[0] == 'y')
- switch (sig) {
- case SIG_DARK:
- main_dark(a, uip);
- break;
-#ifdef USE_CHICKEN_PK
- case SIG_PK:
- chickenpk(a);
- break;
-#endif // USE_CHICKEN_PK
- case SIG_GOMO:
- gomoku(a, CHESS_MODE_VERSUS);
- break;
- case SIG_CHC:
- chc(a, CHESS_MODE_VERSUS);
- break;
- case SIG_GO:
- gochess(a, CHESS_MODE_VERSUS);
- break;
- case SIG_REVERSI:
- reversi(a, CHESS_MODE_VERSUS);
- break;
- case SIG_TALK:
- default:
- do_talk(a);
- }
- else
- close(a);
- clear();
- currstat = currstat0;
-}
-
-#ifdef PLAY_ANGEL
-/* ¤p¤Ñ¨Ï¤p¥D¤H³B²z¨ç¦¡ */
-int
-t_changeangel(){
- char buf[4];
-
- /* cuser.myangel == "-" means banned for calling angel */
- if (cuser.myangel[0] == '-' || cuser.myangel[1] == 0) return 0;
-
- getdata(b_lines - 1, 0,
- "§ó´«¤p¤Ñ¨Ï«á´NµLªk´«¦^¤F³á¡I ¬O§_­n§ó´«¤p¤Ñ¨Ï¡H [y/N]",
- buf, 3, LCECHO);
- if (buf[0] == 'y' || buf[0] == 'Y') {
- char buf[100];
- snprintf(buf, sizeof(buf), "%s¤p¥D¤H %s ´«±¼ %s ¤p¤Ñ¨Ï\n",
- ctime4(&now), cuser.userid, cuser.myangel);
- buf[24] = ' '; // replace '\n'
- log_file(BBSHOME "/log/changeangel.log", LOG_CREAT, buf);
-
- cuser.myangel[0] = 0;
- outs("¤p¤Ñ¨Ï§ó·s§¹¦¨¡A¤U¦¸©I¥s®É·|¿ï¥X·sªº¤p¤Ñ¨Ï");
- }
- return XEASY;
-}
-
-int t_angelmsg(){
- char msg[3][74] = { "", "", "" };
- char nick[10] = "";
- char buf[512];
- int i;
- FILE* fp;
-
- setuserfile(buf, "angelmsg");
- fp = fopen(buf, "r");
- if (fp) {
- i = 0;
- if (fgets(msg[0], sizeof(msg[0]), fp)) {
- chomp(msg[0]);
- if (strncmp(msg[0], "%%[", 3) == 0) {
- strlcpy(nick, msg[0] + 3, 7);
- move(4, 0);
- prints("­ì¦³¼ÊºÙ¡G%s", nick);
- msg[0][0] = 0;
- } else
- i = 1;
- } else
- msg[0][0] = 0;
-
- move(5, 0);
- outs("­ì¦³¯d¨¥¡G\n");
- if(msg[0][0])
- outs(msg[0]);
- for (; i < 3; ++i) {
- if(fgets(msg[i], sizeof(msg[0]), fp)) {
- outs(msg[i]);
- chomp(msg[i]);
- } else
- break;
- }
- fclose(fp);
- }
-
- getdata_buf(11, 0, "¼ÊºÙ¡G", nick, 7, 1);
- do {
- move(12, 0);
- clrtobot();
- outs("¤£¦bªº®É­Ô­n¸ò¤p¥D¤H»¡¤°»ò©O¡H"
- "³Ì¦h¤T¦æ¡A«ö[Enter]µ²§ô");
- for (i = 0; i < 3 &&
- getdata_buf(14 + i, 0, "¡G", msg[i], sizeof(msg[i]), DOECHO);
- ++i);
- getdata(b_lines - 2, 0, "(S)Àx¦s (E)­«·s¨Ó¹L (Q)¨ú®ø¡H[S]",
- buf, 4, LCECHO);
- } while (buf[0] == 'E' || buf[0] == 'e');
- if (buf[0] == 'Q' || buf[0] == 'q')
- return 0;
- setuserfile(buf, "angelmsg");
- if (msg[0][0] == 0)
- unlink(buf);
- else {
- FILE* fp = fopen(buf, "w");
- if(nick[0])
- fprintf(fp, "%%%%[%s\n", nick);
- for (i = 0; i < 3 && msg[i][0]; ++i) {
- fputs(msg[i], fp);
- fputc('\n', fp);
- }
- fclose(fp);
- }
- return 0;
-}
-
-static int
-FindAngel(void){
- int nAngel;
- int i, j;
- int choose;
- int trial = 0;
- int mask;
-
- if (cuser.sex < 6) /* ¥¿±`©Ê§O */
- mask = 1 | (2 << (cuser.sex & 1));
- else
- mask = 7;
-
- do{
- nAngel = 0;
- j = SHM->currsorted;
- for (i = 0; i < SHM->UTMPnumber; ++i)
- if ((SHM->uinfo[SHM->sorted[j][0][i]].userlevel & PERM_ANGEL)
- && (SHM->uinfo[SHM->sorted[j][0][i]].angel & mask) == 0)
- ++nAngel;
-
- if (nAngel == 0)
- return 0;
-
- choose = random() % nAngel + 1;
- j = SHM->currsorted;
- for (i = 0; i < SHM->UTMPnumber && choose; ++i)
- if ((SHM->uinfo[SHM->sorted[j][0][i]].userlevel & PERM_ANGEL)
- && (SHM->uinfo[SHM->sorted[j][0][i]].angel & mask) == 0)
- --choose;
-
- if (choose == 0 && SHM->uinfo[SHM->sorted[j][0][i - 1]].uid != currutmp->uid
- && (SHM->uinfo[SHM->sorted[j][0][i - 1]].userlevel & PERM_ANGEL)
- && ((SHM->uinfo[SHM->sorted[j][0][i - 1]].angel & mask) == 0)
- && !he_reject_me(&SHM->uinfo[SHM->sorted[j][0][i - 1]]) ){
- strlcpy(cuser.myangel, SHM->uinfo[SHM->sorted[j][0][i - 1]].userid, IDLEN + 1);
- passwd_update(usernum, &cuser);
- return 1;
- }
- }while(++trial < 5);
- return 0;
-}
-
-static inline void
-GotoNewHand(){
- char old_board[IDLEN + 1] = "";
- int canRead = 1;
-
- if (currutmp && currutmp->mode == EDITING)
- return;
-
- // usually crashed as 'assert(currbid == brc_currbid)'
- if (currboard[0]) {
- strlcpy(old_board, currboard, IDLEN + 1);
- currboard = "";// force enter_board
- }
-
- if (enter_board(GLOBAL_NEWBIE) == 0)
- canRead = 1;
-
- if (canRead)
- Read();
-
- if (canRead && old_board[0])
- enter_board(old_board);
-}
-
-
-static inline void
-NoAngelFound(const char* msg){
- move(b_lines, 0);
- outs(msg);
- if (currutmp == NULL || currutmp->mode != EDITING)
- outs("¡A½Ð¥ý¦b·s¤âªO¤W´M§äµª®×©Î«ö Ctrl-P µo°Ý");
- clrtoeol();
- refresh();
- sleep(1);
- GotoNewHand();
- return;
-}
-
-static inline void
-AngelNotOnline(){
- char buf[256];
- const static char* const not_online_message = "±zªº¤p¤Ñ¨Ï²{¦b¤£¦b½u¤W";
- if (cuser.myangel[0] != '-')
- sethomefile(buf, cuser.myangel, "angelmsg");
- if (cuser.myangel[0] == '-' || !dashf(buf))
- NoAngelFound(not_online_message);
- else {
- FILE* fp = fopen(buf, "r");
- clear();
- showtitle("¤p¤Ñ¨Ï¯d¨¥", BBSNAME);
- move(4, 0);
- clrtobot();
-
- buf[0] = 0;
- fgets(buf, sizeof(buf), fp);
- if (strncmp(buf, "%%[", 3) == 0) {
- chomp(buf);
- prints("±zªº%s¤p¤Ñ¨Ï²{¦b¤£¦b½u¤W", buf + 3);
- fgets(buf, sizeof(buf), fp);
- } else
- outs(not_online_message);
-
- outs("\nÍ¢¯d¨¥µ¹§A¡G\n");
- outs(ANSI_COLOR(1;31;44) "¡ó¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢t" ANSI_COLOR(37) ""
- "¤p¤Ñ¨Ï¯d¨¥" ANSI_COLOR(31) "¢u¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¡ó" ANSI_RESET "\n");
- outs(ANSI_COLOR(1;31) "¢~¢t" ANSI_COLOR(32) " ¤p¤Ñ¨Ï "
- " " ANSI_COLOR(31) "¢u¢¡" ANSI_RESET "\n");
-
- do {
- chomp(buf);
- prints(ANSI_COLOR(1;31) "¢x" ANSI_RESET "%-74.74s" ANSI_COLOR(1;31) "¢x" ANSI_RESET "\n", buf);
- } while (fgets(buf, sizeof(buf), fp));
-
- outs(ANSI_COLOR(1;31) "¢¢¢s¢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¢s¢£" ANSI_RESET "\n");
- outs(ANSI_COLOR(1;31;44) "¡ó¢r¢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¢r¡ó" ANSI_RESET "\n");
-
- move(b_lines - 4, 0);
- outs("¤p¥D¤H¨Ï¥Î¤W°ÝÃD§ä¤£¨ì¤p¤Ñ¨Ï½Ð¨ì·s¤âª©(" GLOBAL_NEWBIE ")\n"
- " ·Q¯d¨¥µ¹¤p¤Ñ¨Ï½Ð¨ì³\\Ä@ª©(AngelPray)\n"
- " ·Q§ä¬ÝªO¦b­þªº¸Ü¥i¨ì(AskBoard)\n"
- "½Ð¥ý¦b¦UªO¤W´M§äµª®×©Î«ö Ctrl-P µo°Ý");
- pressanykey();
-
- GotoNewHand();
- }
-}
-
-static void
-TalkToAngel(){
- static int AngelPermChecked = 0;
- userinfo_t* uent;
- userec_t xuser;
-
- if (strcmp(cuser.myangel, "-") == 0){
- AngelNotOnline();
- return;
- }
-
- if (cuser.myangel[0] && !AngelPermChecked) {
- getuser(cuser.myangel, &xuser); // XXX if user doesn't exist
- if (!(xuser.userlevel & PERM_ANGEL))
- cuser.myangel[0] = 0;
- }
- AngelPermChecked = 1;
-
- if (cuser.myangel[0] == 0 && ! FindAngel()){
- NoAngelFound("²{¦b¨S¦³¤p¤Ñ¨Ï¦b½u¤W");
- return;
- }
-
- uent = search_ulist_userid(cuser.myangel);
- if (uent == 0 || (uent->angel & 1) || he_reject_me(uent)){
- AngelNotOnline();
- return;
- }
-
- more("etc/angel_usage", NA);
-
- /* ³o¬q¸Ü©Î³\¥i¥H¦b¤p¤Ñ¨Ï¦^µª°ÝÃD®É show ¥X¨Ó
- move(b_lines - 1, 0);
- outs("²{¦b§Aªºid¨ü¨ì«O±K¡A¦^µª§A°ÝÃDªº¤p¤Ñ¨Ï¨Ã¤£ª¾¹D§A¬O½Ö \n"
- "§A¥i¥H¿ï¾Ü¤£¦V¹ï¤è³zÅS¦Û¤v¨­¥÷¨Ó«OÅ@¦Û¤v ");
- */
-
- my_write(uent->pid, "°Ý¤p¤Ñ¨Ï¡G ", "¤p¤Ñ¨Ï", WATERBALL_ANGEL, uent);
- return;
-}
-
-void
-CallAngel(){
- static int entered = 0;
- screen_backup_t old_screen;
-
- if (!HasUserPerm(PERM_LOGINOK) || entered)
- return;
- entered = 1;
-
- scr_dump(&old_screen);
-
- TalkToAngel();
-
- scr_restore(&old_screen);
-
- entered = 0;
-}
-
-void
-SwitchBeingAngel(){
- cuser.uflag2 ^= REJ_QUESTION;
- currutmp->angel ^= 1;
-}
-
-void
-SwitchAngelSex(int newmode){
- ANGEL_SET(newmode);
- currutmp->angel = (currutmp->angel & ~0x6) | ((newmode & 3) << 1);
-}
-
-int
-t_switchangel(){
- SwitchBeingAngel();
- outs(REJECT_QUESTION ? "¥ð®§¤@·|¨à" : "¶}©ñ¤p¥D¤H°Ý°ÝÃD");
- return XEASY;
-}
-#endif
diff --git a/mbbsd/telnet.c b/mbbsd/telnet.c
deleted file mode 100644
index 332b3f3a..00000000
--- a/mbbsd/telnet.c
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * piaip's simplified implementation of TELNET protocol
- */
-#ifdef DEBUG
-#define TELOPTS
-#define TELCMDS
-#endif
-
-#include "bbs.h"
-
-#ifdef DETECT_CLIENT
-void UpdateClientCode(unsigned char c); // see mbbsd.c
-#endif
-
-unsigned int telnet_handler(unsigned char c) ;
-void telnet_init(void);
-ssize_t tty_read(unsigned char *buf, size_t max);
-
-enum TELNET_IAC_STATES {
- IAC_NONE,
- IAC_COMMAND,
- IAC_WAIT_OPT,
- IAC_WAIT_SE,
- IAC_PROCESS_OPT,
- IAC_ERROR
-};
-
-static unsigned char iac_state = 0; /* as byte to reduce memory */
-
-#define TELNET_IAC_MAXLEN (16)
-/* We don't reply to most commands, so this maxlen can be minimal.
- * Warning: if you want to support ENV passing or other long commands,
- * remember to increase this value. Howver, some poorly implemented
- * terminals like xxMan may not follow the protocols and user will hang
- * on those terminals when IACs were sent.
- */
-
-void
-telnet_init(void)
-{
- /* We are the boss. We don't respect to client.
- * It's client's responsibility to follow us.
- * Please write these codes in i-dont-care opt handlers.
- */
- const char telnet_init_cmds[] = {
- /* retrieve terminal type and throw away.
- * why? because without this, clients enter line mode.
- */
- IAC, DO, TELOPT_TTYPE,
- IAC, SB, TELOPT_TTYPE, TELQUAL_SEND, IAC, SE,
-
- /* i'm a smart term with resize ability. */
- IAC, DO, TELOPT_NAWS,
-
- /* i will echo. */
- IAC, WILL, TELOPT_ECHO,
- /* supress ga. */
- IAC, WILL, TELOPT_SGA,
- /* 8 bit binary. */
- IAC, WILL, TELOPT_BINARY,
- IAC, DO, TELOPT_BINARY,
- };
-
- raw_connection = 1;
- write(0, telnet_init_cmds, sizeof(telnet_init_cmds));
-}
-
-/* tty_read
- * read from tty, process telnet commands if raw connection.
- * return: >0 = length, <=0 means read more, abort/eof is automatically processed.
- */
-ssize_t
-tty_read(unsigned char *buf, size_t max)
-{
- ssize_t l = read(0, buf, max);
-
- if(l == 0 || (l < 0 && !(errno == EINTR || errno == EAGAIN)))
- abort_bbs(0);
-
- if(!raw_connection)
- return l;
-
- /* process buffer */
- if (l > 0) {
- unsigned char *buf2 = buf;
- size_t i = 0, i2 = 0;
-
- /* prescan. because IAC is rare,
- * this cost is worthy. */
- if (iac_state == IAC_NONE && memchr(buf, IAC, l) == NULL)
- return l;
-
- /* we have to look into the buffer. */
- for (i = 0; i < l; i++, buf++)
- if(telnet_handler(*buf) == 0)
- *(buf2++) = *buf;
- else
- i2 ++;
- l = (i2 == l) ? -1L : l - i2;
- }
- return l;
-}
-
-#ifdef DBG_OUTRPT
-extern unsigned char fakeEscape;
-#endif // DBG_OUTRPT
-
-/* input: raw character
- * output: telnet command if c was handled, otherwise zero.
- */
-unsigned int
-telnet_handler(unsigned char c)
-{
- static unsigned char iac_quote = 0; /* as byte to reduce memory */
- static unsigned char iac_opt_req = 0;
-
- static unsigned char iac_buf[TELNET_IAC_MAXLEN];
- static unsigned int iac_buflen = 0;
-
- /* we have to quote all IACs. */
- if(c == IAC && !iac_quote) {
- iac_quote = 1;
- return NOP;
- }
-
-#ifdef DETECT_CLIENT
- /* hash client telnet sequences */
- if(cuser.userid[0]==0) {
- if(iac_state == IAC_WAIT_SE) {
- // skip suboption
- } else {
- if(iac_quote)
- UpdateClientCode(IAC);
- UpdateClientCode(c);
- }
- }
-#endif
-
- /* a special case is the top level iac. otherwise, iac is just a quote. */
- if (iac_quote) {
- if(iac_state == IAC_NONE)
- iac_state = IAC_COMMAND;
- if(iac_state == IAC_WAIT_SE && c == SE)
- iac_state = IAC_PROCESS_OPT;
- iac_quote = 0;
- }
-
- /* now, let's process commands by state */
- switch(iac_state) {
-
- case IAC_NONE:
- return 0;
-
- case IAC_COMMAND:
-#if 0 // def DEBUG
- {
- int cx = c; /* to make compiler happy */
- write(0, "-", 1);
- if(TELCMD_OK(cx))
- write(0, TELCMD(c), strlen(TELCMD(c)));
- write(0, " ", 1);
- }
-#endif
- iac_state = IAC_NONE; /* by default we restore state. */
- switch(c) {
- case IAC:
- // return 0;
- // we don't want to allow IACs as input.
- return 1;
-
- /* we don't want to process these. or maybe in future. */
- case BREAK: /* break */
-#ifdef DBG_OUTRPT
- fakeEscape = !fakeEscape;
- return NOP;
-#endif
-
- case ABORT: /* Abort process */
- case SUSP: /* Suspend process */
- case AO: /* abort output--but let prog finish */
- case IP: /* interrupt process--permanently */
- case EOR: /* end of record (transparent mode) */
- case DM: /* data mark--for connect. cleaning */
- case xEOF: /* End of file: EOF is already used... */
- return NOP;
-
- case NOP: /* nop */
- return NOP;
-
- /* we should process these, but maybe in future. */
- case GA: /* you may reverse the line */
- case EL: /* erase the current line */
- case EC: /* erase the current character */
- return NOP;
-
- /* good */
- case AYT: /* are you there */
- {
- const char *alive = "I'm still alive, loading: ";
- char buf[STRLEN];
-
- /* respond as fast as we can */
- write(0, alive, strlen(alive));
- cpuload(buf);
- write(0, buf, strlen(buf));
- write(0, "\r\n", 2);
- }
- return NOP;
-
- case DONT: /* you are not to use option */
- case DO: /* please, you use option */
- case WONT: /* I won't use option */
- case WILL: /* I will use option */
- iac_opt_req = c;
- iac_state = IAC_WAIT_OPT;
- return NOP;
-
- case SB: /* interpret as subnegotiation */
- iac_state = IAC_WAIT_SE;
- iac_buflen = 0;
- return NOP;
-
- case SE: /* end sub negotiation */
- default:
- return NOP;
- }
- return 1;
-
- case IAC_WAIT_OPT:
-#if 0 // def DEBUG
- write(0, "-", 1);
- if(TELOPT_OK(c))
- write(0, TELOPT(c), strlen(TELOPT(c)));
- write(0, " ", 1);
-#endif
- iac_state = IAC_NONE;
- /*
- * According to RFC, there're some tricky steps to prevent loop.
- * However because we have a poor term which does not allow
- * most abilities, let's be a strong boss here.
- *
- * Although my old imeplementation worked, it's even better to follow this:
- * http://www.tcpipguide.com/free/t_TelnetOptionsandOptionNegotiation-3.htm
- */
- switch(c) {
- /* i-dont-care: i don't care about what client is.
- * these should be clamed in init and
- * client must follow me. */
- case TELOPT_TTYPE: /* termtype or line. */
- case TELOPT_NAWS: /* resize terminal */
- case TELOPT_SGA: /* supress GA */
- case TELOPT_ECHO: /* echo */
- case TELOPT_BINARY: /* we are CJK. */
- break;
-
- /* i-dont-agree: i don't understand/agree these.
- * according to RFC, saying NO stopped further
- * requests so there'll not be endless loop. */
- case TELOPT_RCP: /* prepare to reconnect */
- default:
- if (iac_opt_req == WILL || iac_opt_req == DO)
- {
- /* unknown option, reply with won't */
- unsigned char cmd[3] = { IAC, DONT, 0 };
- if(iac_opt_req == DO) cmd[1] = WONT;
- cmd[2] = c;
- write(0, cmd, sizeof(cmd));
- }
- break;
- }
- return 1;
-
- case IAC_WAIT_SE:
- iac_buf[iac_buflen++] = c;
- /* no need to convert state because previous quoting will do. */
-
- if(iac_buflen == TELNET_IAC_MAXLEN) {
- /* may be broken protocol?
- * whether finished or not, break for safety
- * or user may be frozen.
- */
- iac_state = IAC_NONE;
- return 0;
- }
- return 1;
-
- case IAC_PROCESS_OPT:
- iac_state = IAC_NONE;
-#if 0 // def DEBUG
- write(0, "-", 1);
- if(TELOPT_OK(iac_buf[0]))
- write(0, TELOPT(iac_buf[0]), strlen(TELOPT(iac_buf[0])));
- write(0, " ", 1);
-#endif
- switch(iac_buf[0]) {
-
- /* resize terminal */
- case TELOPT_NAWS:
- {
- int w = (iac_buf[1] << 8) + (iac_buf[2]);
- int h = (iac_buf[3] << 8) + (iac_buf[4]);
- term_resize(w, h);
-#ifdef DETECT_CLIENT
- if(cuser.userid[0]==0) {
- UpdateClientCode(iac_buf[0]);
- if(w==80 && h==24)
- UpdateClientCode(1);
- else if(w==80)
- UpdateClientCode(2);
- else if(h==24)
- UpdateClientCode(3);
- else
- UpdateClientCode(4);
- UpdateClientCode(IAC);
- UpdateClientCode(SE);
- }
-#endif
- }
- break;
-
- default:
-#ifdef DETECT_CLIENT
- if(cuser.userid[0]==0) {
- int i;
- for(i=0;i<iac_buflen;i++)
- UpdateClientCode(iac_buf[i]);
- UpdateClientCode(IAC);
- UpdateClientCode(SE);
- }
-#endif
- break;
- }
- return 1;
- }
- return 1; /* never reached */
-}
-
-// vim: sw=4
diff --git a/mbbsd/term.c b/mbbsd/term.c
deleted file mode 100644
index 4868415a..00000000
--- a/mbbsd/term.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-/* ----------------------------------------------------- */
-/* basic tty control */
-/* ----------------------------------------------------- */
-void
-init_tty(void)
-{
- struct termios tty_state, tty_new;
-
- if (tcgetattr(1, &tty_state) < 0) {
- syslog(LOG_ERR, "tcgetattr(): %m");
- return;
- }
- memcpy(&tty_new, &tty_state, sizeof(tty_new));
- tty_new.c_lflag &= ~(ICANON | ECHO | ISIG);
- /*
- * tty_new.c_cc[VTIME] = 0; tty_new.c_cc[VMIN] = 1;
- */
- tcsetattr(1, TCSANOW, &tty_new);
- system("stty raw -echo");
-}
-
-/* ----------------------------------------------------- */
-/* init tty control code */
-/* ----------------------------------------------------- */
-
-
-#define TERMCOMSIZE (40)
-
-static void
-sig_term_resize(int sig)
-{
- struct winsize newsize;
- Signal(SIGWINCH, SIG_IGN); /* Don't bother me! */
- ioctl(0, TIOCGWINSZ, &newsize);
- term_resize(newsize.ws_col, newsize.ws_row);
-}
-
-void term_resize(int w, int h)
-{
- int dorefresh = 0;
- Signal(SIGWINCH, SIG_IGN); /* Don't bother me! */
-
-
- /* make sure reasonable size */
- h = MAX(24, MIN(100, h));
- w = MAX(80, MIN(200, w));
-
- if (w != t_columns || h != t_lines)
- {
- // invoke terminal system resize
- resizeterm(h, w);
-
- t_lines = h;
- t_columns = w;
- dorefresh = 1;
- }
- scr_lns = t_lines; /* XXX: scr_lns ¸ò t_lines ¦³¤°»ò¤£¦P, ¬°¦ó¤À¦¨¨â­Ó */
- b_lines = t_lines - 1;
- p_lines = t_lines - 4;
-
- Signal(SIGWINCH, sig_term_resize);
- if (dorefresh)
- {
- redrawwin();
- refresh();
- }
-}
-
-int
-term_init(void)
-{
- Signal(SIGWINCH, sig_term_resize);
- return YEA;
-}
-
-void
-do_move(int destcol, int destline)
-{
- char buf[16], *p;
-
- snprintf(buf, sizeof(buf), ANSI_MOVETO(%d,%d), destline + 1, destcol + 1);
- for (p = buf; *p; p++)
- ochar(*p);
-}
-
-void
-save_cursor(void)
-{
- ochar(ESC_CHR);
- ochar('7');
-}
-
-void
-restore_cursor(void)
-{
- ochar(ESC_CHR);
- ochar('8');
-}
-
-void
-change_scroll_range(int top, int bottom)
-{
- char buf[16], *p;
-
- snprintf(buf, sizeof(buf), ESC_STR "[%d;%dr", top + 1, bottom + 1);
- for (p = buf; *p; p++)
- ochar(*p);
-}
-
-void
-scroll_forward(void)
-{
- ochar(ESC_CHR);
- ochar('D');
-}
diff --git a/mbbsd/time.c b/mbbsd/time.c
deleted file mode 100644
index 11f963c3..00000000
--- a/mbbsd/time.c
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifdef __dietlibc__
-#include <time.h>
-#warning "hardcoded time zone as GMT+8!"
-extern void __maplocaltime(void);
-extern time_t __tzfile_map(time_t t, int *isdst, int forward);
-extern time_t timegm(struct tm *const t);
-
-time_t mktime(register struct tm* const t) {
- time_t x=timegm(t);
- x-=8*3600;
- return x;
-}
-
-struct tm* localtime_r(const time_t* t, struct tm* r) {
- time_t tmp;
- tmp=*t;
- tmp+=8*3600;
- return gmtime_r(&tmp,r);
-}
-#endif
diff --git a/mbbsd/topsong.c b/mbbsd/topsong.c
deleted file mode 100644
index 906dadbf..00000000
--- a/mbbsd/topsong.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-#define MAX_SONGS 300
-#define QCAST int (*)(const void *, const void *)
-
-typedef struct songcmp_t {
- char name[100];
- char cname[100];
- int count;
-} songcmp_t;
-
-static int totalcount = 0;
-
-static int
-count_cmp(songcmp_t * b, songcmp_t * a)
-{
- return (a->count - b->count);
-}
-
-int
-topsong(void)
-{
- more(FN_TOPSONG, YEA);
- return 0;
-}
-
-
-void
-sortsong(void)
-{
- FILE *fo, *fp = fopen(BBSHOME "/" FN_USSONG, "r");
- songcmp_t songs[MAX_SONGS + 1];
- int n;
- char buf[256], cbuf[256];
-
- memset(songs, 0, sizeof(songs));
- if (!fp)
- return;
- if (!(fo = fopen(FN_TOPSONG, "w"))) {
- fclose(fp);
- return;
- }
- totalcount = 0;
- /* XXX: °£¤F«e MAX_SONGS ­º, ³Ñ¤U¤£·|±Æ§Ç */
- while (fgets(buf, 200, fp)) {
- chomp(buf);
- strip_blank(cbuf, buf);
- if (!cbuf[0] || !isprint2((int)cbuf[0]))
- continue;
-
- for (n = 0; n < MAX_SONGS && songs[n].name[0]; n++)
- if (!strcmp(songs[n].cname, cbuf))
- break;
- strlcpy(songs[n].name, buf, sizeof(songs[n].name));
- strlcpy(songs[n].cname, cbuf, sizeof(songs[n].cname));
- songs[n].count++;
- totalcount++;
- }
- qsort(songs, MAX_SONGS, sizeof(songcmp_t), (QCAST) count_cmp);
- fprintf(fo,
- " " ANSI_COLOR(36) "¢w¢w" ANSI_COLOR(37) "¦W¦¸" ANSI_COLOR(36) "¢w¢w¢w¢w¢w¢w" ANSI_COLOR(37) "ºq"
- " ¦W" ANSI_COLOR(36) "¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w" ANSI_COLOR(37) "¦¸¼Æ" ANSI_COLOR(36) ""
- "¢w¢w" ANSI_COLOR(32) "¦@%d¦¸" ANSI_COLOR(36) "¢w¢w" ANSI_RESET "\n", totalcount);
- for (n = 0; n < 100 && songs[n].name[0]; n++) {
- fprintf(fo, " %5d. %-38.38s %4d " ANSI_COLOR(32) "[%.2f]" ANSI_RESET "\n", n + 1,
- songs[n].name, songs[n].count,
- (float)songs[n].count / totalcount);
- }
- fclose(fp);
- fclose(fo);
-}
diff --git a/mbbsd/user.c b/mbbsd/user.c
deleted file mode 100644
index d235d01f..00000000
--- a/mbbsd/user.c
+++ /dev/null
@@ -1,1452 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-static char * const sex[8] = {
- MSG_BIG_BOY, MSG_BIG_GIRL, MSG_LITTLE_BOY, MSG_LITTLE_GIRL,
- MSG_MAN, MSG_WOMAN, MSG_PLANT, MSG_MIME
-};
-
-#ifdef CHESSCOUNTRY
-static const char * const chess_photo_name[3] = {
- "photo_fivechess", "photo_cchess", "photo_go",
-};
-
-static const char * const chess_type[3] = {
- "¤­¤l´Ñ", "¶H´Ñ", "³ò´Ñ",
-};
-#endif
-
-int
-kill_user(int num, const char *userid)
-{
- userec_t u;
- char src[256], dst[256];
-
- if(!userid || num<=0 ) return -1;
- sethomepath(src, userid);
- snprintf(dst, sizeof(dst), "tmp/%s", userid);
- friend_delete_all(userid, FRIEND_ALOHA);
- delete_allpost(userid);
- if (dashd(src) && Rename(src, dst) == 0) {
- snprintf(src, sizeof(src), "/bin/rm -fr home/%c/%s >/dev/null 2>&1", userid[0], userid);
- system(src);
- }
-
- memset(&u, 0, sizeof(userec_t));
- log_usies("KILL", getuserid(num));
- setuserid(num, "");
- passwd_update(num, &u);
- return 0;
-}
-int
-u_loginview(void)
-{
- int i, in;
- unsigned int pbits = cuser.loginview;
-
- clear();
- move(4, 0);
- for (i = 0; i < NUMVIEWFILE && loginview_file[i][0]; i++)
- prints(" %c. %-20s %-15s \n", 'A' + i,
- loginview_file[i][1], ((pbits >> i) & 1 ? "£¾" : "¢æ"));
- in = i;
-
- clrtobot();
- while ((i = getkey("½Ð«ö [A-N] ¤Á´«³]©w¡A«ö [Return] µ²§ô¡G"))!='\r')
- {
- i = i - 'a';
- if (i >= in || i < 0)
- bell();
- else {
- pbits ^= (1 << i);
- move(i + 4, 28);
- outs((pbits >> i) & 1 ? "£¾" : "¢æ");
- }
- }
-
- if (pbits != cuser.loginview) {
- cuser.loginview = pbits;
- passwd_update(usernum, &cuser);
- }
- return 0;
-}
-int u_cancelbadpost(void)
-{
- int day;
- if(cuser.badpost==0)
- {vmsg("§A¨Ã¨S¦³¦H¤å."); return 0;}
-
- if(search_ulistn(usernum,2))
- {vmsg("½Ðµn¥X¨ä¥Lµøµ¡, §_«h¤£¨ü²z."); return 0;}
-
- passwd_query(usernum, &cuser);
- if (currutmp && (currutmp->alerts & ALERT_PWD))
- currutmp->alerts &= ~ALERT_PWD;
-
- day = 180 - (now - cuser.timeremovebadpost ) / 86400;
- if(day>0 && day<=180)
- {
- vmsgf("¨C 180 ¤Ñ¤~¯à¥Ó½Ð¤@¦¸, ÁÙ³Ñ %d ¤Ñ.", day);
- vmsg("±z¤]¥i¥Hª`·N¯¸¤è¬O§_¦³³Ò°ÊªA°È¤è¦¡§R°£¦H¤å.");
- return 0;
- }
-
- if(
- getkey("§ÚÄ@·N´L¦u¯¸¤è³W©w,²Õ³W,¥H¤ÎªO³W[y/N]?")!='y' ||
- getkey("§ÚÄ@·N´L­«¤£ª[µø±Ú¸s,¤£¾xªO,´L­«¦UªO¥DÅv¤O[y/N]?")!='y' ||
- getkey("§ÚÄ@·NÂÔ·Vµoªí¦³·N¸q¨¥½×,¤£ðã½|§ðÀ»,¤£¸óªO¼s§i[y/N]?")!='y' )
-
- {vmsg("½Ð±z«ä¦Ò²M·¡«á¦A¨Ó¥Ó½Ð§R°£."); return 0;}
-
- if(search_ulistn(usernum,2))
- {vmsg("½Ðµn¥X¨ä¥Lµøµ¡, §_«h¤£¨ü²z."); return 0;}
- if(cuser.badpost)
- {
- int prev = cuser.badpost--;
- cuser.timeremovebadpost = now;
- passwd_update(usernum, &cuser);
- log_filef("log/cancelbadpost.log", LOG_CREAT,
- "%s %s §R°£¤@½g¦H¤å (%d -> %d ½g)\n",
- Cdate(&now), cuser.userid, prev, cuser.badpost);
- }
- vmsg("®¥³ß±z¤w¸g¦¨¥\\§R°£¤@½g¦H¤å.");
- return 0;
-}
-
-void
-user_display(const userec_t * u, int adminmode)
-{
- int diff = 0;
- char genbuf[200];
-
- clrtobot();
- prints(
- " " ANSI_COLOR(30;41) "¢r¢s¢r¢s¢r¢s" ANSI_RESET " " ANSI_COLOR(1;30;45) " ¨Ï ¥Î ªÌ"
- " ¸ê ®Æ "
- " " ANSI_RESET " " ANSI_COLOR(30;41) "¢r¢s¢r¢s¢r¢s" ANSI_RESET "\n");
- prints(" ¥N¸¹¼ÊºÙ: %s(%s)\n"
- " ¯u¹ê©m¦W: %s"
-#if FOREIGN_REG_DAY > 0
- " %s%s"
-#elif defined(FOREIGN_REG)
- " %s"
-#endif
- "\n"
- " ©~¦í¦í§}: %s\n"
- " ¹q¤l«H½c: %s\n"
- " ©Ê §O: %s\n"
- " »È¦æ±b¤á: %d »È¨â\n",
- u->userid, u->nickname, u->realname,
-#if FOREIGN_REG_DAY > 0
- u->uflag2 & FOREIGN ? "(¥~Äy: " : "",
- u->uflag2 & FOREIGN ?
- (u->uflag2 & LIVERIGHT) ? "¥Ã¤[©~¯d)" : "¥¼¨ú±o©~¯dÅv)"
- : "",
-#elif defined(FOREIGN_REG)
- u->uflag2 & FOREIGN ? "(¥~Äy)" : "",
-#endif
- u->address, u->email,
- sex[u->sex % 8], u->money);
-
- sethomedir(genbuf, u->userid);
- prints(" ¨p¤H«H½c: %d «Ê (ÁʶR«H½c: %d «Ê)\n"
- " ¤â¾÷¸¹½X: %010d\n"
- " ¥Í ¤é: %04i/%02i/%02i (%sº¡18·³)\n",
- get_num_records(genbuf, sizeof(fileheader_t)),
- u->exmailbox, u->mobile,
- u->year + 1900, u->month, u->day, over18 ? "¤w" : "¥¼"
- );
-
-#ifdef ASSESS
- prints(" Àu ¦H ¤å: Àu:%d / ¦H:%d\n",
- u->goodpost, u->badpost);
-#endif // ASSESS
-
- prints(" ¤W¯¸¦ì¸m: %s\n", u->lasthost);
-
-#ifdef PLAY_ANGEL
- if (adminmode)
- prints(" ¤p ¤Ñ ¨Ï: %s\n",
- u->myangel[0] ? u->myangel : "µL");
-#endif
- prints(" µù¥U¤é´Á: %s", ctime4(&u->firstlogin));
- prints(" «e¦¸¥úÁ{: %s", ctime4(&u->lastlogin));
- prints(" ¤W¯¸¤å³¹: %d ¦¸ / %d ½g\n",
- u->numlogins, u->numposts);
-
-#ifdef CHESSCOUNTRY
- {
- int i, j;
- FILE* fp;
- for(i = 0; i < 2; ++i){
- sethomefile(genbuf, u->userid, chess_photo_name[i]);
- fp = fopen(genbuf, "r");
- if(fp != NULL){
- for(j = 0; j < 11; ++j)
- fgets(genbuf, 200, fp);
- fgets(genbuf, 200, fp);
- prints("%12s´Ñ°ê¦Û§Ú´y­z: %s", chess_type[i], genbuf + 11);
- fclose(fp);
- }
- }
- }
-#endif
-
- if (adminmode) {
- strcpy(genbuf, "bTCPRp#@XWBA#VSM0123456789ABCDEF");
- for (diff = 0; diff < 32; diff++)
- if (!(u->userlevel & (1 << diff)))
- genbuf[diff] = '-';
- prints(" »{ÃÒ¸ê®Æ: %s\n"
- " userÅv­­: %s\n",
- u->justify, genbuf);
- } else {
- diff = (now - login_start_time) / 60;
- prints(" °±¯d´Á¶¡: %d ¤p®É %2d ¤À\n",
- diff / 60, diff % 60);
- }
-
- /* Thor: ·Q¬Ý¬Ý³o­Ó user ¬O¨º¨ÇªOªºªO¥D */
- if (u->userlevel >= PERM_BM) {
- int i;
- boardheader_t *bhdr;
-
- outs(" ¾á¥ôªO¥D: ");
-
- for (i = 0, bhdr = bcache; i < numboards; i++, bhdr++) {
- if (is_uBM(bhdr->BM, u->userid)) {
- outs(bhdr->brdname);
- outc(' ');
- }
- }
- outc('\n');
- }
- outs(" " ANSI_COLOR(30;41) "¢r¢s¢r¢s¢r¢s¢r¢s¢r¢s¢r¢s¢r¢s¢r¢s¢r¢s¢r¢s¢r¢s¢r"
- "¢s¢r¢s¢r¢s¢r¢s" ANSI_RESET);
-
- outs((u->userlevel & PERM_LOGINOK) ?
- "\n±zªºµù¥Uµ{§Ç¤w¸g§¹¦¨¡AÅwªï¥[¤J¥»¯¸" :
- "\n¦pªG­n´£ª@Åv­­¡A½Ð°Ñ¦Ò¥»¯¸¤½§GÄæ¿ì²zµù¥U");
-
-#ifdef NEWUSER_LIMIT
- if ((u->lastlogin - u->firstlogin < 3 * 86400) && !HasUserPerm(PERM_POST))
- outs("\n·s¤â¤W¸ô¡A¤T¤Ñ«á¶}©ñÅv­­");
-#endif
-}
-
-void
-mail_violatelaw(const char *crime, const char *police, const char *reason, const char *result)
-{
- char genbuf[200];
- fileheader_t fhdr;
- FILE *fp;
-
- sendalert(crime, ALERT_PWD_PERM);
-
- sethomepath(genbuf, crime);
- stampfile(genbuf, &fhdr);
- if (!(fp = fopen(genbuf, "w")))
- return;
- fprintf(fp, "§@ªÌ: [" BBSMNAME "ĵ¹î§½]\n"
- "¼ÐÃD: [³ø§i] ¹Hªk³ø§i\n"
- "®É¶¡: %s\n"
- ANSI_COLOR(1;32) "%s" ANSI_RESET "§P¨M¡G\n " ANSI_COLOR(1;32) "%s" ANSI_RESET
- "¦]" ANSI_COLOR(1;35) "%s" ANSI_RESET "¦æ¬°¡A\n"
- "¹H¤Ï¥»¯¸¯¸³W¡A³B¥H" ANSI_COLOR(1;35) "%s" ANSI_RESET "¡A¯S¦¹³qª¾\n\n"
- "½Ð¨ì " GLOBAL_LAW " ¬d¸ß¬ÛÃöªk³W¸ê°T¡A¨Ã±q¥D¿ï³æ¶i¤J:\n"
- "(P)lay¡i®T¼Ö»P¥ð¶¢¡j=>(P)ay¡i¢Þtt¶q³c©± ¡j=> (1)ViolateLaw ú»@³æ\n"
- "¥Hú¥æ»@³æ¡C\n",
- ctime4(&now), police, crime, reason, result);
- fclose(fp);
- strcpy(fhdr.title, "[³ø§i] ¹Hªk§P¨M³ø§i");
- strcpy(fhdr.owner, "[" BBSMNAME "ĵ¹î§½]");
- sethomedir(genbuf, crime);
- append_record(genbuf, &fhdr, sizeof(fhdr));
-}
-
-void
-kick_all(char *user)
-{
- userinfo_t *ui;
- int num = searchuser(user, NULL), i=1;
- while((ui = (userinfo_t *) search_ulistn(num, i)) != NULL)
- {
- if(ui == currutmp) i++;
- if ((ui->pid <= 0 || kill(ui->pid, SIGHUP) == -1))
- purge_utmp(ui);
- log_usies("KICK ALL", user);
- }
-}
-
-void
-violate_law(userec_t * u, int unum)
-{
- char ans[4], ans2[4];
- char reason[128];
- move(1, 0);
- clrtobot();
- move(2, 0);
- outs("(1)Cross-post (2)¶Ãµo¼s§i«H (3)¶Ãµo³sÂê«H\n");
- outs("(4)ÄÌÂZ¯¸¤W¨Ï¥ÎªÌ (8)¨ä¥L¥H»@³æ³B¸m¦æ¬°\n(9)¬å id ¦æ¬°\n");
- getdata(5, 0, "(0)µ²§ô", ans, 3, DOECHO);
- switch (ans[0]) {
- case '1':
- strcpy(reason, "Cross-post");
- break;
- case '2':
- strcpy(reason, "¶Ãµo¼s§i«H");
- break;
- case '3':
- strcpy(reason, "¶Ãµo³sÂê«H");
- break;
- case '4':
- while (!getdata(7, 0, "½Ð¿é¤J³QÀËÁ|²z¥Ñ¥H¥Ü­t³d¡G", reason, 50, DOECHO));
- strcat(reason, "[ÄÌÂZ¯¸¤W¨Ï¥ÎªÌ]");
- break;
- case '8':
- case '9':
- while (!getdata(6, 0, "½Ð¿é¤J²z¥Ñ¥H¥Ü­t³d¡G", reason, 50, DOECHO));
- break;
- default:
- return;
- }
- getdata(7, 0, msg_sure_ny, ans2, 3, LCECHO);
- if (*ans2 != 'y')
- return;
- if (ans[0] == '9') {
- if (HasUserPerm(PERM_POLICE) && (u->numlogins > 100 || u->numposts > 100))
- return;
-
- kill_user(unum, u->userid);
- post_violatelaw(u->userid, cuser.userid, reason, "¬å°£ ID");
- } else {
- kick_all(u->userid);
- u->userlevel |= PERM_VIOLATELAW;
- u->timeviolatelaw = now;
- u->vl_count++;
- passwd_update(unum, u);
- post_violatelaw(u->userid, cuser.userid, reason, "»@³æ³B¥÷");
- mail_violatelaw(u->userid, "¯¸°Èĵ¹î", reason, "»@³æ³B¥÷");
- }
- pressanykey();
-}
-
-void Customize(void)
-{
- char done = 0;
- int dirty = 0;
- int key;
-
- /* cuser.uflag settings */
- static const unsigned int masks1[] = {
- MOVIE_FLAG,
- NO_MODMARK_FLAG ,
- COLORED_MODMARK,
-#ifdef DBCSAWARE
- DBCSAWARE_FLAG,
- DBCS_NOINTRESC,
-#endif
- DEFBACKUP_FLAG,
- 0,
- };
-
- static const char* desc1[] = {
- "°ÊºA¬ÝªO",
- "ÁôÂä峹­×§ï²Å¸¹(±À¤å/­×¤å) (~)",
- "§ï¥Î¦â±m¥N´À­×§ï²Å¸¹ (+)",
-#ifdef DBCSAWARE
- "¦Û°Ê°»´úÂù¦ì¤¸¦r¶°(¦p¥þ«¬¤¤¤å)",
- "¸T¤î¦bÂù¦ì¤¸¤¤¨Ï¥Î¦â½X(¥h¤@¦rÂù¦â)",
-#endif
- "¹w³]³Æ¥÷«H¥ó»P¨ä¥¦°O¿ý", //"»P²á¤Ñ°O¿ý",
- 0,
- };
-
- /* cuser.uflag2 settings */
- static const unsigned int masks2[] = {
- REJ_OUTTAMAIL,
- FAVNEW_FLAG,
- FAVNOHILIGHT,
- 0,
- };
-
- static const char* desc2[] = {
- "©Ú¦¬¯¸¥~«H",
- "·sªO¦Û°Ê¶i§Úªº³Ì·R",
- "³æ¦âÅã¥Ü§Úªº³Ì·R",
- 0,
- };
-
- while ( !done ) {
- int i = 0, ia = 0, ic = 0; /* general uflags */
- int iax = 0; /* extended flags */
-
- clear();
- showtitle("­Ó¤H¤Æ³]©w", "­Ó¤H¤Æ³]©w");
- move(2, 0);
- outs("±z¥Ø«eªº­Ó¤H¤Æ³]©w: ");
- move(4, 0);
-
- /* print uflag options */
- for (i = 0; masks1[i]; i++, ia++)
- {
- clrtoeol();
- prints( ANSI_COLOR(1;36) "%c" ANSI_RESET
- ". %-40s%s\n",
- 'a' + ia, desc1[i],
- (cuser.uflag & masks1[i]) ?
- ANSI_COLOR(1;36) "¬O" ANSI_RESET : "§_");
- }
- ic = i;
- /* print uflag2 options */
- for (i = 0; masks2[i]; i++, ia++)
- {
- clrtoeol();
- prints( ANSI_COLOR(1;36) "%c" ANSI_RESET
- ". %-40s%s" ANSI_RESET "\n",
- 'a' + ia, desc2[i],
- (cuser.uflag2 & masks2[i]) ?
- ANSI_COLOR(1;36) "¬O" ANSI_RESET : "§_");
- }
- /* extended stuff */
- {
- char mindbuf[5];
- static const char *wm[] =
- {"¤@¯ë", "¶i¶¥", "¥¼¨Ó", ""};
-
- prints("%c. %-40s%s\n",
- '1' + iax++,
- "¤ô²y¼Ò¦¡",
- wm[(cuser.uflag2 & WATER_MASK)]);
- memcpy(mindbuf, &currutmp->mind, 4);
- mindbuf[4] = 0;
- prints("%c. %-40s%s\n",
- '1' + iax++,
- "¥Ø«eªº¤ß±¡",
- mindbuf);
-#ifdef PLAY_ANGEL
- /* damn it, dirty stuff here */
- if( HasUserPerm(PERM_ANGEL) )
- {
- const char *am[4] =
- {"¨k¤k¬Ò¥i", "­­¤k¥Í", "­­¨k¥Í", "¼È¤£±µ¨ü·sªº¤p¥D¤H"};
- prints("%c. %-40s%10s\n",
- '1' + iax++,
- "¶}©ñ¤p¥D¤H¸ß°Ý",
- (REJECT_QUESTION ? "§_" : "¬O"));
- prints("%c. %-40s%10s\n",
- '1' + iax++,
- "±µ¨üªº¤p¥D¤H©Ê§O",
- am[ANGEL_STATUS()]);
- }
-#endif
- }
-
- /* input */
- key = getkey("½Ð«ö [a-%c,1-%c] ¤Á´«³]©w¡A¨ä¥¦¥ô·NÁäµ²§ô: ",
- 'a' + ia-1, '1' + iax -1);
-
- if (key >= 'a' && key < 'a' + ia)
- {
- /* normal pref */
- key -= 'a';
- dirty = 1;
-
- if(key < ic)
- {
- cuser.uflag ^= masks1[key];
- } else {
- key -= ic;
- cuser.uflag2 ^= masks2[key];
- }
- continue;
- }
-
- if (key < '1' || key >= '1' + iax)
- {
- done = 1; continue;
- }
- /* extended keys */
- key -= '1';
-
- switch(key)
- {
- case 0:
- {
- int currentset = cuser.uflag2 & WATER_MASK;
- currentset = (currentset + 1) % 3;
- cuser.uflag2 &= ~WATER_MASK;
- cuser.uflag2 |= currentset;
- vmsg("­×¥¿¤ô²y¼Ò¦¡«á½Ð¥¿±`Â÷½u¦A­«·s¤W½u");
- dirty = 1;
- }
- continue;
- case 1:
- {
- char mindbuf[6] = "";
- getdata(b_lines - 1, 0, "²{¦bªº¤ß±¡? ",
- mindbuf, 5, DOECHO);
- if (strcmp(mindbuf, "³q½r") == 0)
- vmsg("¤£¥i¥H§â¦Û¤v³]³q½r°Õ!");
- else if (strcmp(mindbuf, "¹Ø¬P") == 0)
- vmsg("§A¤£¬O¤µ¤Ñ¥Í¤éÕÙ!");
- else
- memcpy(currutmp->mind, mindbuf, 4);
- dirty = 1;
- }
- continue;
- }
-#ifdef PLAY_ANGEL
- if( HasUserPerm(PERM_ANGEL) ){
- if (key == iax-2)
- {
- SwitchBeingAngel();
- dirty = 1; continue;
- }
- else if (key == iax-1)
- {
- SwitchAngelSex(ANGEL_STATUS() + 1);
- dirty = 1; continue;
- }
- }
-#endif
-
- }
-
- grayout(1, b_lines-2, GRAYOUT_DARK);
- move(b_lines-1, 0); clrtoeol();
-
- if(dirty)
- {
- passwd_update(usernum, &cuser);
- outs("³]©w¤wÀx¦s¡C\n");
- } else {
- outs("µ²§ô³]©w¡C\n");
- }
-
- redrawwin(); // in case we changed output pref (like DBCS)
- vmsg("³]©w§¹¦¨");
-}
-
-
-void
-uinfo_query(userec_t *u, int adminmode, int unum)
-{
- userec_t x;
- int i = 0, fail;
- int ans;
- char buf[STRLEN];
- char genbuf[200];
- int y = 0;
- int perm_changed;
- int mail_changed;
- int money_changed;
- int tokill = 0;
- int changefrom = 0;
-
- fail = 0;
- mail_changed = money_changed = perm_changed = 0;
-
- {
- // verify unum
- int xuid = getuser(u->userid, &x);
- if (xuid != unum)
- {
- vmsg("¨t²Î¿ù»~: ¨Ï¥ÎªÌ¸ê®Æ¸¹½X (unum) ¤£¦X¡C½Ð¦Ü " GLOBAL_BUGREPORT "³ø§i¡C");
- return;
- }
- }
-
- memcpy(&x, u, sizeof(userec_t));
- ans = getans(adminmode ?
- "(1)§ï¸ê®Æ(2)±K½X(3)Åv­­(4)¬å±b¸¹(5)§ïID(6)Ãdª«(7)¼f§P(M)«H½c [0]µ²§ô " :
- "½Ð¿ï¾Ü (1)­×§ï¸ê®Æ (2)³]©w±K½X (M)­×§ï«H½c (C) ­Ó¤H¤Æ³]©w ==> [0]µ²§ô ");
-
- if (ans > '2' && ans != 'm' && ans != 'c' && !adminmode)
- ans = '0';
-
- if (ans == '1' || ans == '3' || ans == 'm') {
- clear();
- y = 1;
- move(y++, 0);
- outs(msg_uid);
- outs(x.userid);
- }
- switch (ans) {
- case 'c':
- Customize();
- return;
-
- case 'm':
- do {
- getdata_str(y, 0, "¹q¤l«H½c [ÅÜ°Ê­n­«·s»{ÃÒ]¡G", buf,
- sizeof(x.email), DOECHO, x.email);
- // TODO ³o¸Ì¤]­n emaildb_check
-#ifdef USE_EMAILDB
- if (isvalidemail(buf))
- {
- int email_count = emaildb_check_email(buf, strlen(buf));
- if (email_count < 0)
- vmsg("¼È®É¤£¤¹³\\ email »{ÃÒ, ½Ðµy«á¦A¸Õ");
- else if (email_count >= EMAILDB_LIMIT)
- vmsg("«ü©wªº E-Mail ¤wµù¥U¹L¦h±b¸¹, ½Ð¨Ï¥Î¨ä¥L E-Mail");
- else // valid
- break;
- }
- continue;
-#endif
- } while (!isvalidemail(buf) && vmsg("»{ÃÒ«H½c¤£¯à¥Î¨Ï¥Î§K¶O«H½c"));
- y++;
- // admins may want to use special names
- if (strcmp(buf, x.email) &&
- (strchr(buf, '@') || adminmode)) {
-
- // TODO ³o¸Ì¤]­n emaildb_check
-#ifdef USE_EMAILDB
- if (emaildb_update_email(cuser.userid, strlen(cuser.userid),
- buf, strlen(buf)) < 0) {
- vmsg("¼È®É¤£¤¹³\\ email »{ÃÒ, ½Ðµy«á¦A¸Õ");
- break;
- }
-#endif
- strlcpy(x.email, buf, sizeof(x.email));
- mail_changed = 1;
- delregcodefile();
- }
- break;
-
- case '7':
- violate_law(&x, unum);
- return;
- case '1':
- move(0, 0);
- outs("½Ð³v¶µ­×§ï¡C");
-
- getdata_buf(y++, 0, " ¼Ê ºÙ ¡G", x.nickname,
- sizeof(x.nickname), DOECHO);
- if (adminmode) {
- getdata_buf(y++, 0, "¯u¹ê©m¦W¡G",
- x.realname, sizeof(x.realname), DOECHO);
- getdata_buf(y++, 0, "©~¦í¦a§}¡G",
- x.address, sizeof(x.address), DOECHO);
- }
- buf[0] = 0;
- if (x.mobile)
- snprintf(buf, sizeof(buf), "%010d", x.mobile);
- getdata_buf(y++, 0, "¤â¾÷¸¹½X¡G", buf, 11, LCECHO);
- x.mobile = atoi(buf);
- snprintf(genbuf, sizeof(genbuf), "%d", (u->sex + 1) % 8);
- getdata_str(y++, 0, "©Ê§O (1)¸¯®æ (2)©j±µ (3)©³­} (4)¬ü¬Ü (5)Á¦¨û "
- "(6)ªü«¼ (7)´Óª« (8)Äqª«¡G",
- buf, 3, DOECHO, genbuf);
- if (buf[0] >= '1' && buf[0] <= '8')
- x.sex = (buf[0] - '1') % 8;
- else
- x.sex = u->sex % 8;
-
- while (1) {
- snprintf(genbuf, sizeof(genbuf), "%04i/%02i/%02i",
- u->year + 1900, u->month, u->day);
- if (getdata_str(y, 0, "¥Í¤é ¦è¤¸/¤ë¤ë/¤é¤é¡G", buf, 11, DOECHO, genbuf) == 0) {
- x.month = u->month;
- x.day = u->day;
- x.year = u->year;
- } else {
- int y, m, d;
- if (ParseDate(buf, &y, &m, &d))
- continue;
- x.month = (unsigned char)m;
- x.day = (unsigned char)d;
- x.year = (unsigned char)(y - 1900);
- }
- if (!adminmode && x.year < 40)
- continue;
- y++;
- break;
- }
-
-#ifdef PLAY_ANGEL
- if (adminmode) {
- const char* prompt;
- userec_t the_angel;
- if (x.myangel[0] == 0 || x.myangel[0] == '-' ||
- (getuser(x.myangel, &the_angel) &&
- the_angel.userlevel & PERM_ANGEL))
- prompt = "¤p¤Ñ¨Ï¡G";
- else
- prompt = "¤p¤Ñ¨Ï¡]¦¹±b¸¹¤wµL¤p¤Ñ¨Ï¸ê®æ¡^¡G";
- while (1) {
- userec_t xuser;
- getdata_str(y, 0, prompt, buf, IDLEN + 1, DOECHO,
- x.myangel);
- if(buf[0] == 0 || strcmp(buf, "-") == 0 ||
- (getuser(buf, &xuser) &&
- (xuser.userlevel & PERM_ANGEL)) ||
- strcmp(x.myangel, buf) == 0){
- strlcpy(x.myangel, xuser.userid, IDLEN + 1);
- ++y;
- break;
- }
-
- prompt = "¤p¤Ñ¨Ï¡G";
- }
- }
-#endif
-
-#ifdef CHESSCOUNTRY
- {
- int j, k;
- FILE* fp;
- for(j = 0; j < 2; ++j){
- sethomefile(genbuf, u->userid, chess_photo_name[j]);
- fp = fopen(genbuf, "r");
- if(fp != NULL){
- FILE* newfp;
- char mybuf[200];
- for(k = 0; k < 11; ++k)
- fgets(genbuf, 200, fp);
- fgets(genbuf, 200, fp);
- chomp(genbuf);
-
- snprintf(mybuf, 200, "%s´Ñ°ê¦Û§Ú´y­z¡G", chess_type[j]);
- getdata_buf(y, 0, mybuf, genbuf + 11, 80 - 11, DOECHO);
- ++y;
-
- sethomefile(mybuf, u->userid, chess_photo_name[j]);
- strcat(mybuf, ".new");
- if((newfp = fopen(mybuf, "w")) != NULL){
- rewind(fp);
- for(k = 0; k < 11; ++k){
- fgets(mybuf, 200, fp);
- fputs(mybuf, newfp);
- }
- fputs(genbuf, newfp);
- fputc('\n', newfp);
-
- fclose(newfp);
-
- sethomefile(genbuf, u->userid, chess_photo_name[j]);
- sethomefile(mybuf, u->userid, chess_photo_name[j]);
- strcat(mybuf, ".new");
-
- Rename(mybuf, genbuf);
- }
- fclose(fp);
- }
- }
- }
-#endif
-
- if (adminmode) {
- int tmp;
- if (HasUserPerm(PERM_BBSADM)) {
- snprintf(genbuf, sizeof(genbuf), "%d", x.money);
- if (getdata_str(y++, 0, "»È¦æ±b¤á¡G", buf, 10, DOECHO, genbuf))
- if ((tmp = atol(buf)) != 0) {
- if (tmp != x.money) {
- money_changed = 1;
- changefrom = x.money;
- x.money = tmp;
- }
- }
- }
- snprintf(genbuf, sizeof(genbuf), "%d", x.exmailbox);
- if (getdata_str(y++, 0, "ÁʶR«H½c¼Æ¡G", buf, 6,
- DOECHO, genbuf))
- if ((tmp = atoi(buf)) != 0)
- x.exmailbox = (int)tmp;
-
- getdata_buf(y++, 0, "»{ÃÒ¸ê®Æ¡G", x.justify,
- sizeof(x.justify), DOECHO);
- getdata_buf(y++, 0, "³Ìªñ¥úÁ{¾÷¾¹¡G",
- x.lasthost, sizeof(x.lasthost), DOECHO);
-
- snprintf(genbuf, sizeof(genbuf), "%d", x.numlogins);
- if (getdata_str(y++, 0, "¤W½u¦¸¼Æ¡G", buf, 10, DOECHO, genbuf))
- if ((tmp = atoi(buf)) >= 0)
- x.numlogins = tmp;
- snprintf(genbuf, sizeof(genbuf), "%d", u->numposts);
- if (getdata_str(y++, 0, "¤å³¹¼Æ¥Ø¡G", buf, 10, DOECHO, genbuf))
- if ((tmp = atoi(buf)) >= 0)
- x.numposts = tmp;
- snprintf(genbuf, sizeof(genbuf), "%d", u->goodpost);
- if (getdata_str(y++, 0, "Àu¨}¤å³¹¼Æ:", buf, 10, DOECHO, genbuf))
- if ((tmp = atoi(buf)) >= 0)
- x.goodpost = tmp;
- snprintf(genbuf, sizeof(genbuf), "%d", u->badpost);
- if (getdata_str(y++, 0, "´c¦H¤å³¹¼Æ:", buf, 10, DOECHO, genbuf))
- if ((tmp = atoi(buf)) >= 0)
- x.badpost = tmp;
- snprintf(genbuf, sizeof(genbuf), "%d", u->vl_count);
- if (getdata_str(y++, 0, "¹Hªk°O¿ý¡G", buf, 10, DOECHO, genbuf))
- if ((tmp = atoi(buf)) >= 0)
- x.vl_count = tmp;
-
- snprintf(genbuf, sizeof(genbuf),
- "%d/%d/%d", u->five_win, u->five_lose, u->five_tie);
- if (getdata_str(y++, 0, "¤­¤l´Ñ¾ÔÁZ ³Ó/±Ñ/©M¡G", buf, 16, DOECHO,
- genbuf))
- while (1) {
- char *p;
- char *strtok_pos;
- p = strtok_r(buf, "/\r\n", &strtok_pos);
- if (!p)
- break;
- x.five_win = atoi(p);
- p = strtok_r(NULL, "/\r\n", &strtok_pos);
- if (!p)
- break;
- x.five_lose = atoi(p);
- p = strtok_r(NULL, "/\r\n", &strtok_pos);
- if (!p)
- break;
- x.five_tie = atoi(p);
- break;
- }
- snprintf(genbuf, sizeof(genbuf),
- "%d/%d/%d", u->chc_win, u->chc_lose, u->chc_tie);
- if (getdata_str(y++, 0, "¶H´Ñ¾ÔÁZ ³Ó/±Ñ/©M¡G", buf, 16, DOECHO,
- genbuf))
- while (1) {
- char *p;
- char *strtok_pos;
- p = strtok_r(buf, "/\r\n", &strtok_pos);
- if (!p)
- break;
- x.chc_win = atoi(p);
- p = strtok_r(NULL, "/\r\n", &strtok_pos);
- if (!p)
- break;
- x.chc_lose = atoi(p);
- p = strtok_r(NULL, "/\r\n", &strtok_pos);
- if (!p)
- break;
- x.chc_tie = atoi(p);
- break;
- }
-#ifdef FOREIGN_REG
- if (getdata_str(y++, 0, "¦í¦b 1)¥xÆW 2)¨ä¥L¡G", buf, 2, DOECHO, x.uflag2 & FOREIGN ? "2" : "1"))
- if ((tmp = atoi(buf)) > 0){
- if (tmp == 2){
- x.uflag2 |= FOREIGN;
- }
- else
- x.uflag2 &= ~FOREIGN;
- }
- if (x.uflag2 & FOREIGN)
- if (getdata_str(y++, 0, "¥Ã¤[©~¯dÅv 1)¬O 2)§_¡G", buf, 2, DOECHO, x.uflag2 & LIVERIGHT ? "1" : "2")){
- if ((tmp = atoi(buf)) > 0){
- if (tmp == 1){
- x.uflag2 |= LIVERIGHT;
- x.userlevel |= (PERM_LOGINOK | PERM_POST);
- }
- else{
- x.uflag2 &= ~LIVERIGHT;
- x.userlevel &= ~(PERM_LOGINOK | PERM_POST);
- }
- }
- }
-#endif
- }
- break;
-
- case '2':
- y = 19;
- if (!adminmode) {
- if (!getdata(y++, 0, "½Ð¿é¤J­ì±K½X¡G", buf, PASSLEN, NOECHO) ||
- !checkpasswd(u->passwd, buf)) {
- outs("\n\n±z¿é¤Jªº±K½X¤£¥¿½T\n");
- fail++;
- break;
- }
- } else {
- FILE *fp;
- char witness[3][32], title[100];
- int uid;
- for (i = 0; i < 3; i++) {
- if (!getdata(19 + i, 0, "½Ð¿é¤J¨ó§UÃÒ©ú¤§¨Ï¥ÎªÌ¡G",
- witness[i], sizeof(witness[i]), DOECHO)) {
- outs("\n¤£¿é¤J«hµLªk§ó§ï\n");
- fail++;
- break;
- } else if (!(uid = searchuser(witness[i], NULL))) {
- outs("\n¬dµL¦¹¨Ï¥ÎªÌ\n");
- fail++;
- break;
- } else {
- userec_t atuser;
- passwd_query(uid, &atuser);
- if (now - atuser.firstlogin < 6 * 30 * 24 * 60 * 60) {
- outs("\nµù¥U¥¼¶W¹L¥b¦~¡A½Ð­«·s¿é¤J\n");
- i--;
- }
- strcpy(witness[i], atuser.userid);
- // Adjust upper or lower case
- }
- }
- if (i < 3)
- break;
-
- sprintf(title, "%s ªº±K½X­«³]³qª¾ (by %s)",u->userid, cuser.userid);
- unlink("etc/updatepwd.log");
- if(! (fp = fopen("etc/updatepwd.log", "w")))
- break;
-
- fprintf(fp, "%s ­n¨D±K½X­«³]:\n"
- "¨£ÃÒ¤H¬° %s, %s, %s",
- u->userid, witness[0], witness[1], witness[2] );
- fclose(fp);
-
- post_file(GLOBAL_SECURITY, title, "etc/updatepwd.log", "[¨t²Î¦w¥þ§½]");
- mail_id(u->userid, title, "etc/updatepwd.log", cuser.userid);
- for(i=0; i<3; i++)
- {
- mail_id(witness[i], title, "etc/updatepwd.log", cuser.userid);
- }
- y = 20;
- }
-
- if (!getdata(y++, 0, "½Ð³]©w·s±K½X¡G", buf, PASSLEN, NOECHO)) {
- outs("\n\n±K½X³]©w¨ú®ø, Ä~Äò¨Ï¥Î±K½X\n");
- fail++;
- break;
- }
- strlcpy(genbuf, buf, PASSLEN);
-
- move(y+1, 0);
- outs("½Ðª`·N³]©w±K½X¥u¦³«e¤K­Ó¦r¤¸¦³®Ä¡A¶W¹Lªº±N¦Û°Ê©¿²¤¡C");
-
- getdata(y++, 0, "½ÐÀˬd·s±K½X¡G", buf, PASSLEN, NOECHO);
- if (strncmp(buf, genbuf, PASSLEN)) {
- outs("\n\n·s±K½X½T»{¥¢±Ñ, µLªk³]©w·s±K½X\n");
- fail++;
- break;
- }
- buf[8] = '\0';
- strlcpy(x.passwd, genpasswd(buf), sizeof(x.passwd));
- break;
-
- case '3':
- {
- int tmp = setperms(x.userlevel, str_permid);
- if (tmp == x.userlevel)
- fail++;
- else {
- perm_changed = 1;
- changefrom = x.userlevel;
- x.userlevel = tmp;
- }
- }
- break;
-
- case '4':
- tokill = 1;
- break;
-
- case '5':
- if (getdata_str(b_lines - 3, 0, "·sªº¨Ï¥ÎªÌ¥N¸¹¡G", genbuf, IDLEN + 1,
- DOECHO, x.userid)) {
- if (searchuser(genbuf, NULL)) {
- outs("¿ù»~! ¤w¸g¦³¦P¼Ë ID ªº¨Ï¥ÎªÌ");
- fail++;
- } else
- strlcpy(x.userid, genbuf, sizeof(x.userid));
- }
- break;
- case '6':
- chicken_toggle_death(x.userid);
- break;
- default:
- return;
- }
-
- if (fail) {
- pressanykey();
- return;
- }
- if (getans(msg_sure_ny) == 'y') {
- if (perm_changed) {
- post_change_perm(changefrom, x.userlevel, cuser.userid, x.userid);
-#ifdef PLAY_ANGEL
- if (x.userlevel & ~changefrom & PERM_ANGEL)
- mail_id(x.userid, "¯Í»Hªø¥X¨Ó¤F¡I", "etc/angel_notify", "[¤W«Ò]");
-#endif
- }
- if (strcmp(u->userid, x.userid)) {
- char src[STRLEN], dst[STRLEN];
-
- sethomepath(src, u->userid);
- sethomepath(dst, x.userid);
- Rename(src, dst);
- setuserid(unum, x.userid);
- }
- if (mail_changed && !adminmode) {
- // wait registration.
- x.userlevel &= ~(PERM_LOGINOK | PERM_POST);
- }
- memcpy(u, &x, sizeof(x));
- if (tokill) {
- kill_user(unum, x.userid);
- return;
- } else
- log_usies("SetUser", x.userid);
- if (money_changed) {
- char title[TTLEN+1];
- char msg[200];
- char reason[50];
- clrtobot();
- clear();
- while (!getdata(5, 0, "½Ð¿é¤J²z¥Ñ¥H¥Ü­t³d¡G",
- reason, sizeof(reason), DOECHO));
-
- snprintf(msg, sizeof(msg),
- " ¯¸ªø" ANSI_COLOR(1;32) "%s" ANSI_RESET "§â" ANSI_COLOR(1;32) "%s" ANSI_RESET "ªº¿ú"
- "±q" ANSI_COLOR(1;35) "%d" ANSI_RESET "§ï¦¨" ANSI_COLOR(1;35) "%d" ANSI_RESET "\n"
- " " ANSI_COLOR(1;37) "¯¸ªø%s­×§ï¿ú²z¥Ñ¬O¡G%s" ANSI_RESET,
- cuser.userid, x.userid, changefrom, x.money,
- cuser.userid, reason);
- snprintf(title, sizeof(title),
- "[¤½¦w³ø§i] ¯¸ªø%s­×§ï%s¿ú³ø§i", cuser.userid,
- x.userid);
- post_msg(GLOBAL_SECURITY, title, msg, "[¨t²Î¦w¥þ§½]");
- setumoney(unum, x.money);
- }
- passwd_update(unum, &x);
- if(perm_changed)
- sendalert(x.userid, ALERT_PWD_PERM); // force to reload perm
-
- // resolve_over18 only works for cuser
- if (!adminmode)
- resolve_over18();
- }
-}
-
-int
-u_info(void)
-{
- move(2, 0);
- user_display(&cuser, 0);
- uinfo_query(&cuser, 0, usernum);
- strlcpy(currutmp->nickname, cuser.nickname, sizeof(currutmp->nickname));
- return 0;
-}
-
-int
-u_cloak(void)
-{
- outs((currutmp->invisible ^= 1) ? MSG_CLOAKED : MSG_UNCLOAK);
- return XEASY;
-}
-
-void
-showplans_userec(userec_t *user)
-{
- char genbuf[200];
-
- if(user->userlevel & PERM_VIOLATELAW)
- {
- outs(" " ANSI_COLOR(1;31) "¦¹¤H¹H³W ©|¥¼Ãº¥æ»@³æ" ANSI_RESET);
- return;
- }
-
-#ifdef CHESSCOUNTRY
- if (user_query_mode) {
- int i = 0;
- FILE *fp;
-
- sethomefile(genbuf, user->userid, chess_photo_name[user_query_mode - 1]);
- if ((fp = fopen(genbuf, "r")) != NULL)
- {
- char photo[6][256];
- int kingdom_bid = 0;
- int win = 0, lost = 0;
-
- move(7, 0);
- while (i < 12 && fgets(genbuf, 256, fp))
- {
- chomp(genbuf);
- if (i < 6) /* Ū·Ó¤ùÀÉ */
- strcpy(photo[i], genbuf);
- else if (i == 6)
- kingdom_bid = atoi(genbuf);
- else
- prints("%s %s\n", photo[i - 7], genbuf);
-
- i++;
- }
- fclose(fp);
-
- if (user_query_mode == 1) {
- win = user->five_win;
- lost = user->five_lose;
- } else if(user_query_mode == 2) {
- win = user->chc_win;
- lost = user->chc_lose;
- }
- prints("%s <Á`¦@¾ÔÁZ> %d ³Ó %d ±Ñ\n", photo[5], win, lost);
-
-
- /* ´Ñ°ê°êÀ² */
- setapath(genbuf, bcache[kingdom_bid - 1].brdname);
- strlcat(genbuf, "/chess_ensign", sizeof(genbuf));
- show_file(genbuf, 13, 10, SHOWFILE_ALLOW_COLOR);
- return;
- }
- }
-#endif /* defined(CHESSCOUNTRY) */
-
- sethomefile(genbuf, user->userid, fn_plans);
- if (!show_file(genbuf, 7, MAX_QUERYLINES, SHOWFILE_ALLOW_COLOR))
- prints("¡m­Ó¤H¦W¤ù¡n%s ¥Ø«e¨S¦³¦W¤ù", user->userid);
-}
-
-void
-showplans(const char *uid)
-{
- userec_t user;
- if(getuser(uid, &user))
- showplans_userec(&user);
-}
-/*
- * return value: how many items displayed */
-int
-showsignature(char *fname, int *j, SigInfo *si)
-{
- FILE *fp;
- char buf[256];
- int i, lines = scr_lns;
- char ch;
-
- clear();
- move(2, 0);
- lines -= 3;
-
- setuserfile(fname, "sig.0");
- *j = strlen(fname) - 1;
- si->total = 0;
- si->max = 0;
-
- for (ch = '1'; ch <= '9'; ch++) {
- fname[*j] = ch;
- if ((fp = fopen(fname, "r"))) {
- si->total ++;
- si->max = ch - '1';
- if(lines > 0 && si->max >= si->show_start)
- {
- prints(ANSI_COLOR(36) "¡i ñ¦WÀÉ.%c ¡j" ANSI_RESET "\n", ch);
- lines--;
- if(lines > MAX_SIGLINES/2)
- si->show_max = si->max;
- for (i = 0; lines > 0 && i < MAX_SIGLINES &&
- fgets(buf, sizeof(buf), fp) != NULL; i++)
- outs(buf), lines--;
- }
- fclose(fp);
- }
- }
- if(lines > 0)
- si->show_max = si->max;
- return si->max;
-}
-
-int
-u_editsig(void)
-{
- int aborted;
- char ans[4];
- int j, browsing = 0;
- char genbuf[MAXPATHLEN];
- SigInfo si;
-
- memset(&si, 0, sizeof(si));
-
-browse_sigs:
-
- showsignature(genbuf, &j, &si);
- getdata(0, 0, (browsing || (si.max > si.show_max)) ?
- "ñ¦WÀÉ (E)½s¿è (D)§R°£ (N)½­¶ (Q)¨ú®ø¡H[Q] ":
- "ñ¦WÀÉ (E)½s¿è (D)§R°£ (Q)¨ú®ø¡H[Q] ",
- ans, sizeof(ans), LCECHO);
-
- if(ans[0] == 'n')
- {
- si.show_start = si.show_max + 1;
- if(si.show_start > si.max)
- si.show_start = 0;
- browsing = 1;
- goto browse_sigs;
- }
-
- aborted = 0;
- if (ans[0] == 'd')
- aborted = 1;
- else if (ans[0] == 'e')
- aborted = 2;
-
- if (aborted) {
- if (!getdata(1, 0, "½Ð¿ï¾Üñ¦WÀÉ(1-9)¡H[1] ", ans, sizeof(ans), DOECHO))
- ans[0] = '1';
- if (ans[0] >= '1' && ans[0] <= '9') {
- genbuf[j] = ans[0];
- if (aborted == 1) {
- unlink(genbuf);
- outs(msg_del_ok);
- } else {
- setutmpmode(EDITSIG);
- aborted = vedit(genbuf, NA, NULL);
- if (aborted != -1)
- outs("ñ¦WÀɧó·s§¹²¦");
- }
- }
- pressanykey();
- }
- return 0;
-}
-
-int
-u_editplan(void)
-{
- char genbuf[200];
-
- getdata(b_lines - 1, 0, "¦W¤ù (D)§R°£ (E)½s¿è [Q]¨ú®ø¡H[Q] ",
- genbuf, 3, LCECHO);
-
- if (genbuf[0] == 'e') {
- int aborted;
-
- setutmpmode(EDITPLAN);
- setuserfile(genbuf, fn_plans);
- aborted = vedit(genbuf, NA, NULL);
- if (aborted != -1)
- outs("¦W¤ù§ó·s§¹²¦");
- pressanykey();
- return 0;
- } else if (genbuf[0] == 'd') {
- setuserfile(genbuf, fn_plans);
- unlink(genbuf);
- outmsg("¦W¤ù§R°£§¹²¦");
- }
- return 0;
-}
-
-int
-isvalidemail(const char *email)
-{
- FILE *fp;
- char buf[128], *c;
- if (!strstr(email, "@"))
- return 0;
- for (c = strstr(email, "@"); *c != 0; ++c)
- if ('A' <= *c && *c <= 'Z')
- *c += 32;
-
- if ((fp = fopen("etc/banemail", "r"))) {
- while (fgets(buf, sizeof(buf), fp)) {
- if (buf[0] == '#')
- continue;
- chomp(buf);
- if (buf[0] == 'A' && strcasecmp(&buf[1], email) == 0)
- return 0;
- if (buf[0] == 'P' && strcasestr(email, &buf[1]))
- return 0;
- if (buf[0] == 'S' && strcasecmp(strstr(email, "@") + 1, &buf[1]) == 0)
- return 0;
- }
- fclose(fp);
- }
- return 1;
-}
-
-/* ¦C¥X©Ò¦³µù¥U¨Ï¥ÎªÌ */
-struct ListAllUsetCtx {
- int usercounter;
- int totalusers;
- unsigned short u_list_special;
- int y;
-};
-
-static int
-u_list_CB(void *data, int num, userec_t * uentp)
-{
- char permstr[8], *ptr;
- register int level;
- struct ListAllUsetCtx *ctx = (struct ListAllUsetCtx*) data;
- (void)num;
-
- if (uentp == NULL) {
- move(2, 0);
- clrtoeol();
- prints(ANSI_COLOR(7) " ¨Ï¥ÎªÌ¥N¸¹ %-25s ¤W¯¸ ¤å³¹ %s "
- "³Ìªñ¥úÁ{¤é´Á " ANSI_COLOR(0) "\n",
- "ºï¸¹¼ÊºÙ",
- HasUserPerm(PERM_SEEULEVELS) ? "µ¥¯Å" : "");
- ctx->y = 3;
- return 0;
- }
- if (bad_user_id(uentp->userid))
- return 0;
-
- if ((uentp->userlevel & ~(ctx->u_list_special)) == 0)
- return 0;
-
- if (ctx->y == b_lines) {
- int ch;
- prints(ANSI_COLOR(34;46) " ¤wÅã¥Ü %d/%d ¤H(%d%%) " ANSI_COLOR(31;47) " "
- "(Space)" ANSI_COLOR(30) " ¬Ý¤U¤@­¶ " ANSI_COLOR(31) "(Q)" ANSI_COLOR(30) " Â÷¶} " ANSI_RESET,
- ctx->usercounter, ctx->totalusers, ctx->usercounter * 100 / ctx->totalusers);
- ch = igetch();
- if (ch == 'q' || ch == 'Q')
- return -1;
- ctx->y = 3;
- }
- if (ctx->y == 3) {
- move(3, 0);
- clrtobot();
- }
- level = uentp->userlevel;
- strlcpy(permstr, "----", 8);
- if (level & PERM_SYSOP)
- permstr[0] = 'S';
- else if (level & PERM_ACCOUNTS)
- permstr[0] = 'A';
- else if (level & PERM_SYSOPHIDE)
- permstr[0] = 'p';
-
- if (level & (PERM_BOARD))
- permstr[1] = 'B';
- else if (level & (PERM_BM))
- permstr[1] = 'b';
-
- if (level & (PERM_XEMPT))
- permstr[2] = 'X';
- else if (level & (PERM_LOGINOK))
- permstr[2] = 'R';
-
- if (level & (PERM_CLOAK | PERM_SEECLOAK))
- permstr[3] = 'C';
-
- ptr = (char *)Cdate(&uentp->lastlogin);
- ptr[18] = '\0';
- prints("%-14s %-27.27s%5d %5d %s %s\n",
- uentp->userid,
- uentp->nickname,
- uentp->numlogins, uentp->numposts,
- HasUserPerm(PERM_SEEULEVELS) ? permstr : "", ptr);
- ctx->usercounter++;
- ctx->y++;
- return 0;
-}
-
-int
-u_list(void)
-{
- char genbuf[3];
- struct ListAllUsetCtx data, *ctx = &data;
-
- setutmpmode(LAUSERS);
- ctx->u_list_special = ctx->usercounter = 0;
- ctx->totalusers = SHM->number;
- if (HasUserPerm(PERM_SEEULEVELS)) {
- getdata(b_lines - 1, 0, "Æ[¬Ý [1]¯S®íµ¥¯Å (2)¥þ³¡¡H",
- genbuf, 3, DOECHO);
- if (genbuf[0] != '2')
- ctx->u_list_special = PERM_BASIC | PERM_CHAT | PERM_PAGE | PERM_POST | PERM_LOGINOK | PERM_BM;
- }
- u_list_CB(ctx, 0, NULL);
- passwd_apply(ctx, u_list_CB);
- move(b_lines, 0);
- clrtoeol();
- prints(ANSI_COLOR(34;46) " ¤wÅã¥Ü %d/%d ªº¨Ï¥ÎªÌ(¨t²Î®e¶qµL¤W­­) "
- ANSI_COLOR(31;47) " (½Ð«ö¥ô·NÁäÄ~Äò) " ANSI_RESET, ctx->usercounter, ctx->totalusers);
- igetch();
- return 0;
-}
-
-#ifdef DBCSAWARE
-
-/* detect if user is using an evil client that sends double
- * keys for DBCS data.
- * True if client is evil.
- */
-
-int u_detectDBCSAwareEvilClient()
-{
- int ret = 0;
-
- clear();
- stand_title("³]©w¦Û°Ê°»´úÂù¦ì¤¸¦r¶° (¥þ«¬¤¤¤å)");
- move(2, 0);
- outs(ANSI_RESET
- "* ¥»¯¸¤ä´©¦Û°Ê°»´ú¤¤¤å¦rªº²¾°Ê»P½s¿è¡A¦ý¦³¨Ç³s½uµ{¦¡ (¦pxxMan)\n"
- " ¤]·|¦Û¦æ¸Õ¹Ï°»´ú¡B¦h°e«öÁä¡A©ó¬O«K·|³y¦¨" ANSI_COLOR(1;37)
- "¤@¦¸²¾°Ê¨â­Ó¤¤¤å¦rªº²{¶H¡C" ANSI_RESET "\n\n"
- "* Åý³s½uµ{¦¡³B²z²¾°Ê®e©ö³y¦¨Åã¥Ü¤Î²¾°Ê¤W»~§Pªº°ÝÃD¡A©Ò¥H§Ú­Ì«Øij±z\n"
- " Ãö³¬¸Óµ{¦¡¤Wªº³]©w¡]³q±`¥s¡u°»´ú(¥þ«¬©ÎÂù¦ì¤¸²Õ)¤¤¤å¡v¡^¡A\n"
- " Åý BBS ¨t²Î¥i¥H¥¿½Tªº±±¨î§Aªºµe­±¡C\n\n"
- ANSI_COLOR(1;33)
- "* ¦pªG±z¬Ý¤£À´¤W­±ªº»¡©ú¤]µL©Ò¿×¡A§Ú­Ì·|¦Û°Ê°»´ú¾A¦X±zªº³]©w¡C"
- ANSI_RESET "\n"
- " ½Ð¦b³]©w¦n³s½uµ{¦¡¦¨±z°¾¦nªº¼Ò¦¡«á«ö" ANSI_COLOR(1;33)
- "¤@¤U" ANSI_RESET "±zÁä½L¤Wªº" ANSI_COLOR(1;33)
- "¡ö" ANSI_RESET "\n" ANSI_COLOR(1;36)
- " (¥ª¥k¤è¦VÁä©Î¼g BS/Backspace ªº­Ë°hÁä»P Del §R°£Á䧡¥i)\n"
- ANSI_RESET);
-
- /* clear buffer */
- peek_input(0.1, Ctrl('C'));
- drop_input();
-
- while (1)
- {
- int ch = 0;
-
- move(14, 0);
- outs("³o¬O°»´ú°Ï¡A±zªº´å¼Ð·|¥X²{¦b"
- ANSI_COLOR(7) "³o¸Ì" ANSI_RESET);
- move(14, 15*2);
- ch = igetch();
- if(ch != KEY_LEFT && ch != KEY_RIGHT &&
- ch != Ctrl('H') && ch != '\177')
- {
- move(16, 0);
- bell();
- outs("½Ð«ö¤@¤U¤W­±«ü©wªºÁä¡I §A«ö¨ì§OªºÁä¤F¡I");
- } else {
- move(16, 0);
- /* Actually you may also use num_in_buf here. those clients
- * usually sends doubled keys together in one packet.
- * However when I was writing this, a bug (existed for more than 3
- * years) of num_in_buf forced me to write new wait_input.
- * Anyway it is fixed now.
- */
- refresh();
- if(wait_input(0.1, 0))
- // if(igetch() == ch)
- // if (num_in_buf() > 0)
- {
- /* evil dbcs aware client */
- outs("°»´ú¨ì±zªº³s½uµ{¦¡·|¦Û¦æ³B²z´å¼Ð²¾°Ê¡C\n"
- // "­Y¤é«á¦]¦¹³y¦¨ÂsÄý¤Wªº°ÝÃD¥»¯¸®¤¤£³B²z¡C\n\n"
- "¤w³]©w¬°¡uÅý±zªº³s½uµ{¦¡³B²z´å¼Ð²¾°Ê¡v\n");
- ret = 1;
- } else {
- /* good non-dbcs aware client */
- outs("±zªº³s½uµ{¦¡¦ü¥G¤£·|¦h°e«öÁä¡A"
- "³o¼Ë BBS ¥i¥H§óºë·Çªº±±¨îµe­±¡C\n"
- "¤w³]©w¬°¡uÅý BBS ¦øªA¾¹ª½±µ³B²z´å¼Ð²¾°Ê¡v\n");
- ret = 0;
- }
- outs( "\n­Y·Q§ïÅܳ]©w½Ð¦Ü ­Ó¤H³]©w°Ï ¡÷ ­Ó¤H¤Æ³]©w ¡÷ \n"
- " ½Õ¾ã¡u¦Û°Ê°»´úÂù¦ì¤¸¦r¶°(¦p¥þ«¬¤¤¤å)¡v¤§³]©w");
- while(num_in_buf())
- igetch();
- break;
- }
- }
- drop_input();
- pressanykey();
- return ret;
-}
-#endif
-
-/* vim:sw=4
- */
diff --git a/mbbsd/var.c b/mbbsd/var.c
deleted file mode 100644
index ca50824c..00000000
--- a/mbbsd/var.c
+++ /dev/null
@@ -1,628 +0,0 @@
-/* $Id$ */
-#define INCLUDE_VAR_H
-#include "bbs.h"
-
-const char * const str_permid[] = {
- "°ò¥»Åv¤O", /* PERM_BASIC */
- "¶i¤J²á¤Ñ«Ç", /* PERM_CHAT */
- "§ä¤H²á¤Ñ", /* PERM_PAGE */
- "µoªí¤å³¹", /* PERM_POST */
- "µù¥Uµ{§Ç»{ÃÒ", /* PERM_LOGINOK */
- "«H¥óµL¤W­­", /* PERM_MAILLIMIT */
- "Áô¨­³N", /* PERM_CLOAK */
- "¬Ý¨£§ÔªÌ", /* PERM_SEECLOAK */
- "¥Ã¤[«O¯d±b¸¹", /* PERM_XEMPT */
- "¯¸ªøÁô¨­³N", /* PERM_DENYPOST */
- "ªO¥D", /* PERM_BM */
- "±b¸¹Á`ºÞ", /* PERM_ACCOUNTS */
- "²á¤Ñ«ÇÁ`ºÞ", /* PERM_CHATCLOAK */
- "¬ÝªOÁ`ºÞ", /* PERM_BOARD */
- "¯¸ªø", /* PERM_SYSOP */
- "BBSADM", /* PERM_POSTMARK */
- "¤£¦C¤J±Æ¦æº]", /* PERM_NOTOP */
- "¹Hªk³q½r¤¤", /* PERM_VIOLATELAW */
-#ifdef PLAY_ANGEL
- "¥i¾á¥ô¤p¤Ñ¨Ï", /* PERM_ANGEL */
-#else
- "¥¼¨Ï¥Î",
-#endif
- "¤£¤¹³\\»{ÃÒ½Xµù¥U", /* PERM_NOREGCODE */
- "µøı¯¸ªø", /* PERM_VIEWSYSOP */
- "Æ[¹î¨Ï¥ÎªÌ¦æÂÜ", /* PERM_LOGUSER */
- "æ͹ܤ½Åv", /* PERM_NOCITIZEN */
- "¸s²Õªø", /* PERM_SYSSUPERSUBOP */
- "±b¸¹¼f®Ö²Õ", /* PERM_ACCTREG */
- "µ{¦¡²Õ", /* PERM_PRG */
- "¬¡°Ê²Õ", /* PERM_ACTION */
- "¬ü¤u²Õ", /* PERM_PAINT */
- "ĵ¹îÁ`ºÞ", /* PERM_POLICE_MAN */
- "¤p²Õªø", /* PERM_SYSSUBOP */
- "°h¥ð¯¸ªø", /* PERM_OLDSYSOP */
- "ĵ¹î" /* PERM_POLICE */
-};
-
-const char * const str_permboard[] = {
- "¤£¥i Zap", /* BRD_NOZAP */
- "¤£¦C¤J²Î­p", /* BRD_NOCOUNT */
- "¤£Âà«H", /* BRD_NOTRAN */
- "¸s²ÕªO", /* BRD_GROUPBOARD */
- "ÁôÂêO", /* BRD_HIDE */
- "­­¨î(¤£»Ý³]©w)", /* BRD_POSTMASK */
- "°Î¦WªO", /* BRD_ANONYMOUS */
- "¹w³]°Î¦WªO", /* BRD_DEFAULTANONYMOUS */
- "¹Hªk§ï¶i¤¤¬ÝªO", /* BRD_BAD */
- "³s¸p±M¥Î¬ÝªO", /* BRD_VOTEBOARD */
- "¤wĵ§i­n¼o°£", /* BRD_WARNEL */
- "¼öªù¬ÝªO¸s²Õ", /* BRD_TOP */
- "¤£¥i±ÀÂË", /* BRD_NORECOMMEND */
- "¥¬¸¨®æ", /* BRD_BLOG */
- "ªO¥D³]©w¦C¤J°O¿ý", /* BRD_BMCOUNT */
- "³sµ²¬ÝªO", /* BRD_SYMBOLIC */
- "¤£¥i¼N", /* BRD_NOBOO */
- "¹w³] Local Save", /* BRD_LOCALSAVE */
- "­­ªO¤Íµo¤å", /* BRD_RESTRICTEDPOST */
- "Guest¥i¥Hµoªí", /* BRD_GUESTPOST */
-#ifdef USE_COOLDOWN
- "§NÀR", /* BRD_COOLDOWN */
-#else
- "§NÀR(¥»¯¸µL®Ä)", /* BRD_COOLDOWN */
-#endif
-#ifdef USE_AUTOCPLOG
- "¦Û°Ê¯dÂà¿ý°O¿ý", /* BRD_CPLOG */
-#else
- "Âà¿ý°O¿ý(¥»¯¸µL®Ä)", /* BRD_CPLOG */
-#endif
- "¸T¤î§Ö³t±À¤å", /* BRD_NOFASTRECMD */
- "±À¤å°O¿ý IP", /* BRD_IPLOGRECMD */
- "¤Q¤K¸T", /* BRD_OVER18 */
- "¨S·Q¨ì",
- "¨S·Q¨ì",
- "¨S·Q¨ì",
- "¨S·Q¨ì",
- "¨S·Q¨ì",
- "¨S·Q¨ì",
- "¨S·Q¨ì",
-};
-
-int usernum;
-int currmode = 0;
-int currsrmode = 0;
-int curredit = 0;
-int paste_level;
-int currbid;
-char quote_file[80] = "\0";
-char quote_user[80] = "\0";
-char currtitle[TTLEN + 1] = "\0";
-char currauthor[IDLEN + 2] = "\0";
-const char *currboard = "\0";
-char currBM[IDLEN * 3 + 10];
-const char reset_color[4] = ANSI_RESET;
-char margs[64] = "\0"; /* main argv list */
-pid_t currpid; /* current process ID */
-time4_t login_start_time;
-time4_t start_time;
-userec_t cuser; /* current user structure */
-crosspost_t postrecord; /* anti cross post */
-unsigned int currbrdattr;
-unsigned int currstat;
-unsigned char currfmode; /* current file mode */
-
-/* global string variables */
-/* filename */
-
-char * const fn_passwd = FN_PASSWD;
-char * const fn_board = FN_BOARD;
-char * const fn_register = "register.new";
-char * const fn_note_ans = FN_NOTE_ANS;
-const char * const fn_plans = "plans";
-const char * const fn_writelog = "writelog";
-const char * const fn_talklog = "talklog";
-const char * const fn_overrides = FN_OVERRIDES;
-const char * const fn_reject = FN_REJECT;
-const char * const fn_canvote = FN_CANVOTE;
-const char * const fn_notes = "notes";
-const char * const fn_water = FN_WATER;
-const char * const fn_visable = FN_VISABLE;
-const char * const fn_mandex = "/.Names";
-const char * const fn_boardlisthelp = FN_BRDLISTHELP;
-const char * const fn_boardhelp = FN_BOARDHELP;
-
-/* are descript in userec.loginview */
-
-char * const loginview_file[NUMVIEWFILE][2] = {
- {FN_NOTE_ANS, "»Ä²¢­W»¶¬y¨¥ªO"},
- {FN_TOPSONG, "ÂIºq±Æ¦æº]"},
- {"etc/topusr", "¤Q¤j±Æ¦æº]"},
- {"etc/topusr100", "¦Ê¤j±Æ¦æº]"},
- {"etc/weather.tmp", "¤Ñ®ð§Ö³ø"},
- {"etc/stock.tmp", "ªÑ¥«§Ö³ø"},
- {"etc/day", "¤µ¤é¤Q¤j¸ÜÃD"},
- {"etc/week", "¤@¶g¤­¤Q¤j¸ÜÃD"},
- {"etc/today", "¤µ¤Ñ¤W¯¸¤H¦¸"},
- {"etc/yesterday", "¬Q¤é¤W¯¸¤H¦¸"},
- {"etc/history", "¾ú¥v¤Wªº¤µ¤Ñ"},
- {"etc/topboardman", "ºëµØ°Ï±Æ¦æº]"},
- {"etc/topboard.tmp", "¬ÝªO¤H®ð±Æ¦æº]"},
- {NULL, NULL}
-};
-
-/* message */
-char * const msg_seperator = MSG_SEPERATOR;
-
-char * const msg_cancel = MSG_CANCEL;
-char * const msg_usr_left = MSG_USR_LEFT;
-char * const msg_nobody = MSG_NOBODY;
-
-char * const msg_sure_ny = MSG_SURE_NY;
-char * const msg_sure_yn = MSG_SURE_YN;
-
-char * const msg_bid = MSG_BID;
-char * const msg_uid = MSG_UID;
-
-char * const msg_del_ok = MSG_DEL_OK;
-char * const msg_del_ny = MSG_DEL_NY;
-
-char * const msg_fwd_ok = MSG_FWD_OK;
-char * const msg_fwd_err1 = MSG_FWD_ERR1;
-char * const msg_fwd_err2 = MSG_FWD_ERR2;
-
-char * const err_board_update = ERR_BOARD_UPDATE;
-char * const err_bid = ERR_BID;
-char * const err_uid = ERR_UID;
-char * const err_filename = ERR_FILENAME;
-
-char * const str_mail_address = "." BBSUSER "@" MYHOSTNAME;
-char * const str_new = "new";
-char * const str_reply = "Re: ";
-char * const str_space = " \t\n\r";
-char * const str_sysop = "SYSOP";
-char * const str_author1 = STR_AUTHOR1;
-char * const str_author2 = STR_AUTHOR2;
-char * const str_post1 = STR_POST1;
-char * const str_post2 = STR_POST2;
-char * const BBSName = BBSNAME;
-
-/* MAX_MODES is defined in common.h */
-
-char * const ModeTypeTable[] = {
- "µo§b", /* IDLE */
- "¥D¿ï³æ", /* MMENU */
- "¨t²ÎºûÅ@", /* ADMIN */
- "¶l¥ó¿ï³æ", /* MAIL */
- "¥æ½Í¿ï³æ", /* TMENU */
- "¨Ï¥ÎªÌ¿ï³æ", /* UMENU */
- "XYZ ¿ï³æ", /* XMENU */
- "¤ÀÃþ¬ÝªO", /* CLASS */
- "Play¿ï³æ", /* PMENU */
- "½s¯S§O¦W³æ", /* NMENU */
- BBSMNAME2 "¶q³c©±", /* PSALE */
- "µoªí¤å³¹", /* POSTING */
- "¬ÝªO¦Cªí", /* READBRD */
- "¾\\Ū¤å³¹", /* READING */
- "·s¤å³¹¦Cªí", /* READNEW */
- "¿ï¾Ü¬ÝªO", /* SELECT */
- "Ū«H", /* RMAIL */
- "¼g«H", /* SMAIL */
- "²á¤Ñ«Ç", /* CHATING */
- "¨ä¥L", /* XMODE */
- "´M§ä¦n¤Í", /* FRIEND */
- "¤W½u¨Ï¥ÎªÌ", /* LAUSERS */
- "¨Ï¥ÎªÌ¦W³æ", /* LUSERS */
- "°lÂܯ¸¤Í", /* MONITOR */
- "©I¥s", /* PAGE */
- "¬d¸ß", /* TQUERY */
- "¥æ½Í", /* TALK */
- "½s¦W¤ùÀÉ", /* EDITPLAN */
- "½sñ¦WÀÉ", /* EDITSIG */
- "§ë²¼¤¤", /* VOTING */
- "³]©w¸ê®Æ", /* XINFO */
- "±Hµ¹¯¸ªø", /* MSYSOP */
- "¨L¨L¨L", /* WWW */
- "¥´¤j¦Ñ¤G", /* BIG2 */
- "¦^À³", /* REPLY */
- "³Q¤ô²y¥´¤¤", /* HIT */
- "¤ô²y·Ç³Æ¤¤", /* DBACK */
- "µ§°O¥»", /* NOTE */
- "½s¿è¤å³¹", /* EDITING */
- "µo¨t²Î³q§i", /* MAILALL */
- "ºN¨â°é", /* MJ */
- "¹q¸£¾Ü¤Í", /* P_FRIEND */
- "¤W¯¸³~¤¤", /* LOGIN */
- "¬d¦r¨å", /* DICT */
- "¥´¾ôµP", /* BRIDGE */
- "§äÀÉ®×", /* ARCHIE */
- "¥´¦a¹«", /* GOPHER */
- "¬ÝNews", /* NEWS */
- "±¡®Ñ²£¥Í¾¹", /* LOVE */
- "½s¿è»²§U¾¹", /* EDITEXP */
- "¥Ó½ÐIP¦ì§}", /* IPREG */
- "ºôºÞ¿ì¤½¤¤", /* NetAdm */
- "µêÀÀ¹ê·~§{", /* DRINK */
- "­pºâ¾÷", /* CAL */
- "½s¿è®y¥k»Ê", /* PROVERB */
- "¤½§GÄæ", /* ANNOUNCE */
- "¨è¬y¨¥ªO", /* EDNOTE */
- "­^º~½Ķ¾÷", /* CDICT */
- "À˵ø¦Û¤vª««~", /* LOBJ */
- "ÂIºq", /* OSONG */
- "¥¿¦bª±¤pÂû", /* CHICKEN */
- "ª±±m¨é", /* TICKET */
- "²q¼Æ¦r", /* GUESSNUM */
- "¹C¼Ö³õ", /* AMUSE */
- "³æ¤H¶Â¥Õ´Ñ", /* OTHELLO */
- "ª±»ë¤l", /* DICE */
- "µo²¼¹ï¼ú", /* VICE */
- "¹G¹Gáàing", /* BBCALL */
- "ú»@³æ", /* CROSSPOST */
- "¤­¤l´Ñ", /* M_FIVE */
- "21ÂIing", /* JACK_CARD */
- "10ÂI¥bing", /* TENHALF */
- "¶W¯Å¤E¤Q¤E", /* CARD_99 */
- "¤õ¨®¬d¸ß", /* RAIL_WAY */
- "·j´M¿ï³æ", /* SREG */
- "¤U¶H´Ñ", /* CHC */
- "¤U·t´Ñ", /* DARK */
- "NBA¤j²q´ú", /* TMPJACK */
- BBSMNAME2 "¬dº]¨t²Î", /* JCEE */
- "­«½s¤å³¹", /* REEDIT */
- "³¡¸¨®æ", /* BLOGGING */
- "¬Ý´Ñ", /* CHESSWATCHING */
- "¤U³ò´Ñ", /* UMODE_GO */
- "[¨t²Î¿ù»~]", /* DEBUGSLEEPING */
- "³s¤»´Ñ", /* UMODE_CONN6 */
- "¶Â¥Õ´Ñ", /* REVERSI */
- "BBS-Lua", /* UMODE_BBSLUA */
- "¼½©ñ°Êµe", /* UMODE_ASCIIMOVIE */
- "",
- "",
- "", // 90
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "", // 100
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "", // 110
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "", // 120
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- ""
-};
-
-/* term.c */
-int b_lines = 23; // bottom line of screen
-int t_lines = 24; // term lines
-int p_lines = 20;
-int t_columns = 80;
-
-/* refer to ansi.h for *len */
-char * const strtstandout = ANSI_COLOR(7);
-const int strtstandoutlen = 4;
-char * const endstandout = ANSI_RESET;
-const int endstandoutlen = 3;
-char * const clearbuf = ESC_STR "[H" ESC_STR "[J";
-const int clearbuflen = 6;
-char * const cleolbuf = ESC_STR "[K";
-const int cleolbuflen = 3;
-char * const scrollrev = ESC_STR "M";
-const int scrollrevlen = 2;
-int automargins = 1;
-
-/* io.c */
-time4_t now;
-int KEY_ESC_arg;
-int watermode = -1;
-int wmofo = NOTREPLYING;
-/*
- * WATERMODE(WATER_ORIG) | WATERMODE(WATER_NEW):
- * ????????????????????
- * Ptt ¤ô²y¦^ÅU (FIXME: guessed by scw)
- * watermode = -1 ¨S¦b¦^¤ô²y
- * = 0 ¦b¦^¤W¤@Áû¤ô²y (Ctrl-R)
- * > 0 ¦b¦^«e n Áû¤ô²y (Ctrl-R Ctrl-R)
- *
- * WATERMODE(WATER_OFO) by in2
- * wmofo = NOTREPLYING ¨S¦b¦^¤ô²y
- * = REPLYING ¥¿¦b¦^¤ô²y
- * = RECVINREPLYING ¦^¤ô²y¶¡¤S±µ¨ì¤ô²y
- *
- * wmofo >=0 ®É¦¬¨ì¤ô²y±N¥uÅã¥Ü, ¤£·|¨ìwater[]¸Ì,
- * «Ý¦^§¹¤ô²yªº®É­Ô¤@¦¸¼g¤J.
- */
-
-
-/* cache.c */
-int numboards = -1;
-SHM_t *SHM;
-boardheader_t *bcache;
-userinfo_t *currutmp;
-
-/* read.c */
-int TagNum = 0; /* tag's number */
-int TagBoard = -1; /* TagBoard = 0 : user's mailbox */
- /* TagBoard > 0 : bid where last taged */
-char currdirect[64];
-
-/* edit.c */
-char save_title[STRLEN];
-
-/* bbs.c */
-time4_t board_visit_time = 0;
-char real_name[IDLEN + 1];
-char local_article;
-
-/* mbbsd.c */
-char raw_connection = 0;
-char fromhost[STRLEN] = "\0";
-char water_usies = 0;
-FILE *fp_writelog = NULL;
-water_t *water, *swater[6], *water_which;
-char over18 = 0;
-
-/* chc_play.c */
-
-/* user.c */
-#ifdef CHESSCOUNTRY
-int user_query_mode;
-/*
- * user_query_mode = 0 simple data
- * = 1 gomoku chess country data
- * = 2 chc chess country data
- * = 3 go chess country data
- */
-#endif /* defined(CHESSCOUNTRY) */
-
-/* screen.c */
-#define scr_lns t_lines
-#define scr_cols ANSILINELEN
-screenline_t *big_picture = NULL;
-char roll = 0;
-char msg_occupied = 0;
-
-/* gomo.c */
-const char * const bw_chess[] = {"¡³", "¡´", "¡C", "¡E"};
-const unsigned char * const pat_gomoku /* [1954] */ =(unsigned char*)
- /* 0 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 16 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x55\xcc\x00\x00\x00\x00"
- /* 32 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x33\x00\x44\x00\x33\x00\x00\x00"
- /* 48 */ "\x00\x22\x00\x55\x00\x22\x00\x00\x00\x44\x33\x66\x55\xcc\x33\x66"
- /* 64 */ "\x55\xcc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00"
- /* 80 */ "\x55\x00\x55\x00\x05\x00\x55\x02\x46\x00\xaa\x00\x00\x55\x00\x55"
- /* 96 */ "\x00\x05\x00\x55\x00\x05\x00\x55\x00\x00\x44\xcc\x44\xcc\x05\xbb"
- /* 112 */ "\x44\xcc\x05\xbb\x44\xcc\x05\xbb\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 128 */ "\x00\x00\x33\x00\x00\x00\x44\x00\x00\x00\x00\x00\x33\x00\x44\x00"
- /* 144 */ "\x33\x22\x66\x00\x55\x55\xcc\x00\x33\x00\x00\x00\x00\x22\x00\x55"
- /* 160 */ "\x00\x22\x00\x55\x00\x02\x00\x05\x00\x22\x00\x00\x33\x44\x33\x66"
- /* 176 */ "\x55\xcc\x33\x66\x55\xcc\x33\x46\x05\xbb\x33\x66\x55\xcc\x00\x00"
- /* 192 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x44\x00\x00\x00"
- /* 208 */ "\x33\x00\x00\x22\x55\x22\x55\x02\x05\x22\x55\x02\x46\x22\xaa\x55"
- /* 224 */ "\xcc\x22\x55\x02\x46\x22\xaa\x00\x22\x55\x22\x55\x02\x05\x22\x55"
- /* 240 */ "\x02\x05\x22\x55\x02\x05\x22\x55\x02\x05\x22\x55\x02\x44\x66\xcc"
- /* 256 */ "\x66\xcc\x46\xbb\x66\xcc\x46\xbb\x66\xcc\x46\xbb\x66\xcc\x46\xbb"
- /* 272 */ "\x66\xcc\x46\xbb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x33\x00"
- /* 288 */ "\x00\x00\x44\x00\x00\x00\x33\x00\x22\x22\x66\x00\x00\x00\x00\x00"
- /* 304 */ "\x03\x00\x44\x00\x33\x22\x66\x00\x55\x55\xcc\x00\x33\x22\x66\x00"
- /* 320 */ "\x55\x55\xcc\x00\x03\x00\x00\x00\x00\x02\x00\x55\x00\x02\x00\x55"
- /* 336 */ "\x00\x02\x00\x05\x00\x02\x00\x55\x00\x02\x02\x46\x00\x02\x00\x55"
- /* 352 */ "\x55\x05\x55\x46\xaa\xcc\x55\x46\xaa\xcc\x55\x06\x5a\xbb\x55\x46"
- /* 368 */ "\xaa\xcc\x55\x06\x5a\xbb\x55\x46\xaa\xcc\x00\x00\x00\x00\x00\x00"
- /* 384 */ "\x00\x00\x00\x00\x03\x00\x00\x00\x44\x00\x00\x00\x33\x00\x22\x22"
- /* 400 */ "\x66\x00\x00\x00\x55\x00\x55\x55\x05\x55\x05\x55\x05\x55\x05\x55"
- /* 416 */ "\x46\x55\x5a\xaa\xcc\x55\x05\x55\x46\x55\x5a\xaa\xcc\x55\x05\x55"
- /* 432 */ "\x06\x55\x0a\x55\x55\x05\x55\x05\x55\x05\x55\x05\x55\x05\x55\x05"
- /* 448 */ "\x55\x05\x55\x05\x55\x05\x55\x05\x55\x46\x55\x05\x55\x5a\x55\x5a"
- /* 464 */ "\xaa\xcc\xcc\xbb\xcc\xbb\xcc\xbb\xcc\xbb\xcc\xbb\xcc\xbb\xcc\xbb"
- /* 480 */ "\xcc\xbb\xcc\xbb\xcc\xbb\xcc\xbb\xcc\xbb\xcc\xbb\xcc\xbb\xcc\xbb"
- /* 496 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x33\x00\x00\x00\x44\x00"
- /* 512 */ "\x00\x00\x33\x00\x22\x22\x66\x00\x00\x00\x55\x00\x55\x55\xcc\x00"
- /* 528 */ "\x00\x00\x00\x00\x33\x00\x44\x00\x33\x22\x66\x00\x55\x55\xcc\x00"
- /* 544 */ "\x33\x22\x66\x00\x55\x55\xcc\x00\x33\x02\x46\x00\x05\x05\xbb\x00"
- /* 560 */ "\x33\x00\x00\x00\x00\x22\x00\x55\x00\x22\x00\x55\x00\x02\x00\x05"
- /* 576 */ "\x00\x22\x00\x55\x00\x02\x02\x46\x00\x22\x00\xaa\x00\x55\x55\xcc"
- /* 592 */ "\x00\x22\x00\x00\x33\x44\x33\x66\x55\xcc\x33\x66\x55\xcc\x33\x46"
- /* 608 */ "\x05\xbb\x33\x66\x55\xcc\x33\x46\x05\xbb\x33\x66\x55\xcc\x33\x46"
- /* 624 */ "\x05\xbb\x33\x66\x55\xcc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 640 */ "\x03\x00\x00\x00\x44\x00\x00\x00\x33\x00\x22\x22\x66\x00\x00\x00"
- /* 656 */ "\x55\x00\x55\x55\xcc\x00\x00\x00\x33\x00\x00\x22\x55\x22\x55\x02"
- /* 672 */ "\x05\x22\x55\x02\x46\x22\xaa\x55\xcc\x22\x55\x02\x46\x22\xaa\x55"
- /* 688 */ "\xcc\x22\x55\x02\x06\x22\x5a\x05\xbb\x22\x55\x02\x46\x22\xaa\x00"
- /* 704 */ "\x22\x55\x22\x55\x02\x05\x22\x55\x02\x05\x22\x55\x02\x05\x22\x55"
- /* 720 */ "\x02\x05\x22\x55\x02\x46\x22\x55\x02\x5a\x22\xaa\x55\xcc\x22\x55"
- /* 736 */ "\x02\x05\x22\x55\x02\x44\x66\xcc\x66\xcc\x46\xbb\x66\xcc\x46\xbb"
- /* 752 */ "\x66\xcc\x46\xbb\x66\xcc\x46\xbb\x66\xcc\x46\xbb\x66\xcc\x46\xbb"
- /* 768 */ "\x66\xcc\x46\xbb\x66\xcc\x46\xbb\x66\xcc\x46\xbb\x00\x00\x00\x00"
- /* 784 */ "\x00\x00\x00\x00\x00\x00\x33\x00\x00\x00\x44\x00\x00\x00\x33\x00"
- /* 800 */ "\x22\x22\x66\x00\x00\x00\x55\x00\x55\x55\xcc\x00\x00\x00\x33\x00"
- /* 816 */ "\x22\x22\x66\x00\x00\x00\x00\x00\x03\x00\x44\x00\x33\x22\x66\x00"
- /* 832 */ "\x55\x55\xcc\x00\x33\x22\x66\x00\x55\x55\xcc\x00\x03\x02\x46\x00"
- /* 848 */ "\x05\x05\xbb\x00\x33\x22\x66\x00\x55\x55\xcc\x00\x03\x00\x00\x00"
- /* 864 */ "\x00\x02\x00\x55\x00\x02\x00\x55\x00\x02\x00\x05\x00\x02\x00\x55"
- /* 880 */ "\x00\x02\x02\x46\x00\x02\x00\xaa\x00\x55\x55\xcc\x00\x02\x00\x55"
- /* 896 */ "\x00\x02\x02\x46\x00\x02\x00\x55\x55\x05\x55\x46\xaa\xcc\x55\x46"
- /* 912 */ "\xaa\xcc\x55\x06\x5a\xbb\x55\x46\xaa\xcc\x55\x06\x5a\xbb\x55\x46"
- /* 928 */ "\xaa\xcc\x55\x06\x5a\xbb\x55\x46\xaa\xcc\x55\x06\x5a\xbb\x55\x46"
- /* 944 */ "\xaa\xcc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00"
- /* 960 */ "\x44\x00\x00\x00\x33\x00\x22\x22\x66\x00\x00\x00\x55\x00\x55\x55"
- /* 976 */ "\xcc\x00\x00\x00\x33\x00\x22\x22\x66\x00\x00\x00\x55\x00\x55\x55"
- /* 992 */ "\x05\x55\x05\x55\x05\x55\x05\x55\x46\x55\x5a\xaa\xcc\x55\x05\x55"
- /* 1008 */ "\x46\x55\x5a\xaa\xcc\x55\x05\x55\x06\x55\x0a\x5a\xbb\x55\x05\x55"
- /* 1024 */ "\x46\x55\x5a\xaa\xcc\x55\x05\x55\x06\x55\x0a\x55\x55\x05\x55\x05"
- /* 1040 */ "\x55\x05\x55\x05\x55\x05\x55\x05\x55\x05\x55\x05\x55\x05\x55\x05"
- /* 1056 */ "\x55\x46\x55\x05\x55\x5a\x55\x5a\xaa\xcc\x55\x05\x55\x05\x55\x05"
- /* 1072 */ "\x55\x46\x55\x05\x55\x5a\x55\x5a\xaa\xcc\xcc\xbb\xcc\xbb\xcc\xbb"
- /* 1088 */ "\xcc\xbb\xcc\xbb\xcc\xbb\xcc\xbb\xcc\xbb\xcc\xbb\xcc\xbb\xcc\xbb"
- /* 1104 */ "\xcc\xbb\xcc\xbb\xcc\xbb\xcc\xbb\xcc\xbb\xcc\xbb\xcc\xbb\xcc\xbb"
- /* 1120 */ "\xcc\xbb\xcc\xbb\xcc\xbb\xcc\xbb\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 1136 */ "\x00\x00\x33\x00\x00\x00\x44\x00\x00\x00\x33\x00\x22\x22\x66\x00"
- /* 1152 */ "\x00\x00\x55\x00\x55\x55\xcc\x00\x00\x00\x33\x00\x22\x22\x66\x00"
- /* 1168 */ "\x00\x00\x55\x00\x55\x55\xcc\x00\x00\x00\x00\x00\x33\x00\x44\x00"
- /* 1184 */ "\x33\x22\x66\x00\x55\x55\xcc\x00\x33\x22\x66\x00\x55\x55\xcc\x00"
- /* 1200 */ "\x33\x02\x46\x00\x05\x05\xbb\x00\x33\x22\x66\x00\x55\x55\xcc\x00"
- /* 1216 */ "\x33\x02\x46\x00\x05\x05\xbb\x00\x33\x00\x00\x00\x00\x22\x00\x55"
- /* 1232 */ "\x00\x22\x00\x55\x00\x02\x00\x05\x00\x22\x00\x55\x00\x02\x02\x46"
- /* 1248 */ "\x00\x22\x00\xaa\x00\x55\x55\xcc\x00\x22\x00\x55\x00\x02\x02\x46"
- /* 1264 */ "\x00\x22\x00\xaa\x00\x55\x55\xcc\x00\x22\x00\x00\x03\x44\x33\x66"
- /* 1280 */ "\x55\xcc\x33\x66\x55\xcc\x03\x46\x05\xbb\x33\x66\x55\xcc\x03\x46"
- /* 1296 */ "\x05\xbb\x33\x66\x55\xcc\x03\x46\x05\xbb\x33\x66\x55\xcc\x03\x46"
- /* 1312 */ "\x05\xbb\x33\x66\x55\xcc\x03\x46\x05\xbb\x33\x66\x55\xcc\x00\x00"
- /* 1328 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x44\x00\x00\x00"
- /* 1344 */ "\x33\x00\x22\x22\x66\x00\x00\x00\x55\x00\x55\x55\xcc\x00\x00\x00"
- /* 1360 */ "\x33\x00\x22\x22\x66\x00\x00\x00\x55\x00\x55\x55\xcc\x00\x00\x00"
- /* 1376 */ "\x03\x00\x00\x02\x55\x02\x55\x02\x05\x02\x55\x02\x46\x02\xaa\x55"
- /* 1392 */ "\xcc\x02\x55\x02\x46\x02\xaa\x55\xcc\x02\x55\x02\x06\x02\x5a\x05"
- /* 1408 */ "\xbb\x02\x55\x02\x46\x02\xaa\x55\xcc\x02\x55\x02\x06\x02\x5a\x05"
- /* 1424 */ "\xbb\x02\x55\x02\x46\x02\xaa\x00\x02\x55\x02\x55\x02\x05\x02\x55"
- /* 1440 */ "\x02\x05\x02\x55\x02\x05\x02\x55\x02\x05\x02\x55\x02\x46\x02\x55"
- /* 1456 */ "\x02\x5a\x02\xaa\x55\xcc\x02\x55\x02\x05\x02\x55\x02\x46\x02\x55"
- /* 1472 */ "\x02\x5a\x02\xaa\x55\xcc\x02\x55\x02\x05\x02\x55\x02\x05\x46\xcc"
- /* 1488 */ "\x46\xcc\x06\xbb\x46\xcc\x06\xbb\x46\xcc\x06\xbb\x46\xcc\x06\xbb"
- /* 1504 */ "\x46\xcc\x06\xbb\x46\xcc\x06\xbb\x46\xcc\x06\xbb\x46\xcc\x06\xbb"
- /* 1520 */ "\x46\xcc\x06\xbb\x46\xcc\x06\xbb\x46\xcc\x06\xbb\x46\xcc\x06\xbb"
- /* 1536 */ "\x46\xcc\x06\xbb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x33\x00"
- /* 1552 */ "\x00\x00\x44\x00\x00\x00\x33\x00\x22\x22\x66\x00\x00\x00\x55\x00"
- /* 1568 */ "\x55\x55\xcc\x00\x00\x00\x33\x00\x22\x22\x66\x00\x00\x00\x55\x00"
- /* 1584 */ "\x55\x55\xcc\x00\x00\x00\x33\x00\x02\x02\x46\x00\x00\x00\x00\x00"
- /* 1600 */ "\x03\x00\x44\x00\x33\x22\x66\x00\x55\x55\xcc\x00\x33\x22\x66\x00"
- /* 1616 */ "\x55\x55\xcc\x00\x03\x02\x46\x00\x05\x05\xbb\x00\x33\x22\x66\x00"
- /* 1632 */ "\x55\x55\xcc\x00\x03\x02\x46\x00\x05\x05\xbb\x00\x33\x22\x66\x00"
- /* 1648 */ "\x55\x55\xcc\x00\x03\x00\x00\x00\x00\x02\x00\x55\x00\x02\x00\x55"
- /* 1664 */ "\x00\x02\x00\x05\x00\x02\x00\x55\x00\x02\x02\x46\x00\x02\x00\xaa"
- /* 1680 */ "\x00\x55\x55\xcc\x00\x02\x00\x55\x00\x02\x02\x46\x00\x02\x00\xaa"
- /* 1696 */ "\x00\x55\x55\xcc\x00\x02\x00\x55\x00\x02\x02\x06\x00\x02\x00\x05"
- /* 1712 */ "\x05\x05\x05\x46\x5a\xcc\x05\x46\x5a\xcc\x05\x06\x0a\xbb\x05\x46"
- /* 1728 */ "\x5a\xcc\x05\x06\x0a\xbb\x05\x46\x5a\xcc\x05\x06\x0a\xbb\x05\x46"
- /* 1744 */ "\x5a\xcc\x05\x06\x0a\xbb\x05\x46\x5a\xcc\x05\x06\x0a\xbb\x05\x46"
- /* 1760 */ "\x5a\xcc\x05\x06\x0a\xbb\x05\x46\x5a\xcc\x00\x00\x00\x00\x00\x00"
- /* 1776 */ "\x00\x00\x00\x00\x03\x00\x00\x00\x44\x00\x00\x00\x33\x00\x22\x22"
- /* 1792 */ "\x66\x00\x00\x00\x55\x00\x55\x55\xcc\x00\x00\x00\x33\x00\x22\x22"
- /* 1808 */ "\x66\x00\x00\x00\x55\x00\x55\x55\xcc\x00\x00\x00\x03\x00\x02\x02"
- /* 1824 */ "\x46\x00\x00\x00\x05\x00\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05"
- /* 1840 */ "\x46\x05\x5a\x5a\xcc\x05\x05\x05\x46\x05\x5a\x5a\xcc\x05\x05\x05"
- /* 1856 */ "\x06\x05\x0a\x0a\xbb\x05\x05\x05\x46\x05\x5a\x5a\xcc\x05\x05\x05"
- /* 1872 */ "\x06\x05\x0a\x0a\xbb\x05\x05\x05\x46\x05\x5a\x5a\xcc\x05\x05\x05"
- /* 1888 */ "\x06\x05\x0a\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05"
- /* 1904 */ "\x05\x05\x05\x05\x05\x05\x05\x05\x05\x46\x05\x05\x05\x5a\x05\x5a"
- /* 1920 */ "\x5a\xcc\x05\x05\x05\x05\x05\x05\x05\x46\x05\x05\x05\x5a\x05\x5a"
- /* 1936 */ "\x5a\xcc\x05\x05\x05\x05\x05\x05\x05\x06\x05\x05\x05\x0a\x05\x0a"
- /* 1952 */ "\x0a";
-
-const unsigned char * const adv_gomoku /* [978] */ = (unsigned char*)
- /* 0 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 16 */ "\x00\x00\x00\x00\xa0\x00\xa0\x00\x04\x00\x04\x00\x00\xd0\x00\xd0"
- /* 32 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 48 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 64 */ "\x00\x70\x00\x00\x00\x00\xa0\x00\xa1\x00\x00\x00\xa0\x00\x04\x00"
- /* 80 */ "\x04\x00\x00\x00\x04\x00\xd0\xd0\x00\xd0\x00\xd0\x00\xd0\x00\x00"
- /* 96 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x70\x08\x08\x00\x08\x00\x08\x00"
- /* 112 */ "\x08\x00\x08\x00\x40\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x00"
- /* 128 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70"
- /* 144 */ "\x00\x00\x00\x70\x21\x00\x00\x00\x00\x00\xa1\x00\x00\x00\xa1\x00"
- /* 160 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 176 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 192 */ "\x00\x00\x00\x00\x00\x00\x70\x21\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 208 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 224 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 240 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x00\x00"
- /* 256 */ "\x00\x70\x21\x00\x00\x00\x00\x00\x00\x00\xa0\x00\xa1\x00\x00\x00"
- /* 272 */ "\xa1\x00\x00\x00\xa0\x00\x00\x00\xa0\x00\x04\x00\x04\x00\x00\x00"
- /* 288 */ "\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\xd0\xd0\x00\xd0\x00\xd0"
- /* 304 */ "\x00\xd0\x00\xd0\x00\xd0\x00\xd0\x00\xd0\x00\x00\x00\x00\x00\x00"
- /* 320 */ "\x00\x00\x00\x00\x70\x21\x00\x00\x00\x00\x00\x00\x70\x08\x08\x00"
- /* 336 */ "\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00\x08\x00"
- /* 352 */ "\x40\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40"
- /* 368 */ "\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 384 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x00\x00\x00\x70"
- /* 400 */ "\x21\x00\x00\x00\x00\x00\x00\x70\x21\x00\x00\x00\x00\x00\xa1\x00"
- /* 416 */ "\x00\x00\xa1\x00\x00\x00\x00\x00\x00\x00\xa1\x00\x00\x00\x00\x00"
- /* 432 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 448 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 464 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 480 */ "\x00\x00\x70\x21\x00\x00\x00\x00\x00\x00\x70\x21\x00\x00\x00\x00"
- /* 496 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 512 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 528 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 544 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 560 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x00\x00\x00\x70\x21\x00"
- /* 576 */ "\x00\x00\x00\x00\x00\x70\x21\x00\x00\x00\x00\x00\x00\x00\xa0\x00"
- /* 592 */ "\xa1\x00\x00\x00\xa1\x00\x00\x00\xa0\x00\x00\x00\xa1\x00\x00\x00"
- /* 608 */ "\xa0\x00\x00\x00\xa0\x00\x04\x00\x04\x00\x00\x00\x04\x00\x00\x00"
- /* 624 */ "\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\xd0"
- /* 640 */ "\x00\xd0\x00\x00\x00\xd0\x00\x00\x00\xd0\x00\x00\x00\xd0\x00\x00"
- /* 656 */ "\x00\xd0\x00\x00\x00\xd0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 672 */ "\x70\x21\x00\x00\x00\x00\x00\x00\x70\x21\x00\x00\x00\x00\x00\x00"
- /* 688 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 704 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 720 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 736 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 752 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 768 */ "\x00\x00\x00\x00\x00\x00\x00\x70\x00\x00\x00\x70\x21\x00\x00\x00"
- /* 784 */ "\x00\x00\x00\x70\x21\x00\x00\x00\x00\x00\x00\x70\x00\x00\x00\x00"
- /* 800 */ "\x00\x00\xa1\x00\x00\x00\xa1\x00\x00\x00\x00\x00\x00\x00\xa1\x00"
- /* 816 */ "\x00\x00\x00\x00\x00\x00\xa1\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 832 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 848 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 864 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 880 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x21"
- /* 896 */ "\x00\x00\x00\x00\x00\x00\x70\x21\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 912 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 928 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 944 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 960 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- /* 976 */ "\x00";
-
-/* name.c */
-word_t *toplev;
-
-/* friend.c */
-/* Ptt ¦UºØ¯S§O¦W³æªºÀɦW */
-char *friend_file[8] = {
- FN_OVERRIDES,
- FN_REJECT,
- "alohaed",
- "postlist",
- "", /* may point to other filename */
- FN_CANVOTE,
- FN_WATER,
- FN_VISABLE
-};
-
-#ifdef NOKILLWATERBALL
-char reentrant_write_request = 0;
-#endif
-
-#ifdef PTTBBS_UTIL
- #ifdef OUTTA_TIMER
- #define COMMON_TIME (SHM->GV2.e.now)
- #else
- #define COMMON_TIME (time(0))
- #endif
-#else
- #define COMMON_TIME (now)
-#endif
diff --git a/mbbsd/vice.c b/mbbsd/vice.c
deleted file mode 100644
index 14e4e8f4..00000000
--- a/mbbsd/vice.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-#define VICE_PLAY BBSHOME "/etc/vice/vice.play"
-#define VICE_DATA "vice.new"
-#define VICE_BINGO BBSHOME "/etc/vice.bingo"
-#define VICE_SHOW BBSHOME "/etc/vice.show"
-#define VICE_LOST BBSHOME "/etc/vice/vice.lost"
-#define VICE_WIN BBSHOME "/etc/vice/vice.win"
-#define VICE_END BBSHOME "/etc/vice/vice.end"
-#define VICE_NO BBSHOME "/etc/vice/vice.no"
-#define MAX_NO_PICTURE 2
-#define MAX_WIN_PICTURE 2
-#define MAX_LOST_PICTURE 3
-#define MAX_END_PICTURE 5
-
-static int
-vice_load(char tbingo[6][15])
-{
- FILE *fb = fopen(VICE_BINGO, "r");
- char buf[16], *ptr;
- int i = 0;
- if (!fb)
- return -1;
- bzero((char *)tbingo, 6*15);
- while (i < 6 && fgets(buf, 15, fb)) {
- if ((ptr = strchr(buf, '\n')))
- *ptr = 0;
- strcpy(tbingo[i++], buf);
- }
- fclose(fb);
- return 0;
-}
-
-static int
-check(char tbingo[6][15], const char *data)
-{
- int i = 0, j;
-
- if (!strcmp(data, tbingo[0]))
- return 8;
-
- for (j = 8; j > 0; j--)
- for (i = 1; i < 6; i++)
- if (!strncmp(data + 8 - j, tbingo[i] + 8 - j, j))
- return j - 1;
- return 0;
-}
-/* TODO Ptt:showfile ran_showfile more ¤TªÌ­n¦X */
-static int
-ran_showfile(int y, int x, const char *filename, int maxnum)
-{
- FILE *fs;
- char buf[512];
-
- bzero(buf, sizeof(buf));
- snprintf(buf, sizeof(buf), "%s%d", filename, (int)(random() % maxnum + 1));
- if (!(fs = fopen(buf, "r"))) {
- move(10, 10);
- prints("can't open file: %s", buf);
- return 0;
- }
- move(y, x);
-
- while (fgets(buf, sizeof(buf), fs))
- outs(buf);
-
- fclose(fs);
- return 1;
-}
-
-static int
-ran_showmfile(const char *filename, int maxnum)
-{
- char buf[256];
-
- snprintf(buf, sizeof(buf), "%s%d", filename, (int)(random() % maxnum + 1));
- return more(buf, YEA);
-}
-
-
-int
-vice_main(void)
-{
- FILE *fd;
- char tbingo[6][15];
- char buf_data[256],
- serial[16], ch[2], *ptr;
- int TABLE[] = {0, 10, 200, 1000, 4000, 10000, 40000, 100000, 200000};
- int total = 0, money, i = 4, j = 0;
-
- setuserfile(buf_data, VICE_DATA);
- if (!dashf(buf_data)) {
- ran_showmfile(VICE_NO, MAX_NO_PICTURE);
- return 0;
- }
- if (vice_load(tbingo) < 0)
- return -1;
- clear();
- ran_showfile(0, 0, VICE_PLAY, 1);
- ran_showfile(10, 0, VICE_SHOW, 1);
-
- if (!(fd = fopen(buf_data, "r")))
- return 0;
- j = 0;
- i = 0;
- move(10, 24);
- clrtoeol();
- outs("³o¤@´Áªºµo²¼¸¹½X");
- // FIXME ·íµo²¼¦h©ó¤@¦æ, ¶}¼úªº¸¹½X´N·|³Q»\±¼
- while (fgets(serial, 15, fd)) {
- if ((ptr = strchr(serial, '\r')))
- *ptr = 0;
- if (j == 0)
- i++;
- if( i >= 14 )
- break;
- move(10 + i, 24 + j);
- outs(serial);
- j += 9;
- j %= 45;
- }
- getdata(8, 0, "«ö'c'¶}©l¹ï¼ú¤F(©Î¬O¥ô·NÁäÂ÷¶})): ",
- ch, sizeof(ch), LCECHO);
- if (ch[0] != 'c' || lockutmpmode(VICE, LOCK_MULTI)) {
- fclose(fd);
- return 0;
- }
- showtitle("µo²¼¹ï¼ú", BBSNAME);
- rewind(fd);
- while (fgets(serial, 15, fd)) {
- if ((ptr = strchr(serial, '\n')))
- *ptr = 0;
- money = TABLE[check(tbingo, serial)];
- total += money;
- prints("%s ¤¤¤F %d\n", serial, money);
- }
- pressanykey();
- if (total > 0) {
- ran_showmfile(VICE_WIN, MAX_WIN_PICTURE);
- move(22, 0);
- clrtoeol();
- prints("¥þ³¡ªºµo²¼¤¤¤F %d ¶ô¿ú\n", total);
- demoney(total);
- } else
- ran_showmfile(VICE_LOST, MAX_LOST_PICTURE);
-
- fclose(fd);
- unlink(buf_data);
- pressanykey();
- unlockutmpmode();
- return 0;
-}
diff --git a/mbbsd/vote.c b/mbbsd/vote.c
deleted file mode 100644
index 7562a7b8..00000000
--- a/mbbsd/vote.c
+++ /dev/null
@@ -1,1088 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-#define MAX_VOTE_NR 20
-#define MAX_VOTE_PAGE 5
-#define ITEM_PER_PAGE 30
-
-const char * const STR_bv_control = "control"; /* §ë²¼¤é´Á ¿ï¶µ */
-const char * const STR_bv_desc = "desc"; /* §ë²¼¥Øªº */
-const char * const STR_bv_ballots = "ballots"; /* §ëªº²¼ (per byte) */
-const char * const STR_bv_flags = "flags";
-const char * const STR_bv_comments = "comments"; /* §ë²¼ªÌªº«Øij */
-const char * const STR_bv_limited = "limited"; /* ¨p¤H§ë²¼ */
-const char * const STR_bv_limits = "limits"; /* §ë²¼¸ê®æ­­¨î */
-const char * const STR_bv_title = "vtitle";
-
-const char * const STR_bv_results = "results";
-
-typedef struct {
- char control[sizeof("controlXX\0")];
- char desc[sizeof("descXX\0")];
- char ballots[sizeof("ballotsXX\0")];
- char flags[sizeof("flagsXX\0")];
- char comments[sizeof("commentsXX\0")];
- char limited[sizeof("limitedXX\0")];
- char limits[sizeof("limitsXX\0")];
- char title[sizeof("vtitleXX\0")];
-} vote_buffer_t;
-
-void
-b_suckinfile(FILE * fp, char *fname)
-{
- FILE *sfp;
-
- if ((sfp = fopen(fname, "r"))) {
- char inbuf[256];
-
- while (fgets(inbuf, sizeof(inbuf), sfp))
- fputs(inbuf, fp);
- fclose(sfp);
- }
-}
-
-void
-b_suckinfile_invis(FILE * fp, char *fname, const char *boardname)
-{
- FILE *sfp;
-
- if ((sfp = fopen(fname, "r"))) {
- char inbuf[256];
- if(fgets(inbuf, sizeof(inbuf), sfp))
- {
- /* first time, try if boardname revealed. */
- char *post = strstr(inbuf, str_post1);
- if(!post) post = strstr(inbuf, str_post2);
- if(post)
- post = strstr(post, boardname);
- if(post) {
- /* found releaved stuff. */
- /*
- // mosaic method 1
- while(*boardname++)
- *post++ = '?';
- */
- // mosaic method 2
- strcpy(post, "(¬YÁô§Î¬ÝªO)\n");
- }
- fputs(inbuf, fp);
- while (fgets(inbuf, sizeof(inbuf), sfp))
- fputs(inbuf, fp);
- }
- fclose(sfp);
- }
-}
-
-static void
-b_count(const char *buf, int counts[], short item_num, int *total)
-{
- short choice;
- int fd;
-
- memset(counts, 0, item_num * sizeof(counts[0]));
- *total = 0;
- if ((fd = open(buf, O_RDONLY)) != -1) {
- flock(fd, LOCK_EX); /* Thor: ¨¾¤î¦h¤H¦P®Éºâ */
- while (read(fd, &choice, sizeof(short)) == sizeof(short)) {
- if (choice >= item_num)
- continue;
- counts[choice]++;
- (*total)++;
- }
- flock(fd, LOCK_UN);
- close(fd);
- }
-}
-
-
-static int
-b_nonzeroNum(const char *buf)
-{
- int i = 0;
- char inchar;
- int fd;
-
- if ((fd = open(buf, O_RDONLY)) != -1) {
- while (read(fd, &inchar, 1) == 1)
- if (inchar)
- i++;
- close(fd);
- }
- return i;
-}
-
-static void
-vote_report(const char *bname, const char *fname, char *fpath)
-{
- register char *ip;
- time4_t dtime;
- int fd, bid;
- fileheader_t header;
-
- ip = fpath;
- while (*(++ip));
- *ip++ = '/';
-
- /* get a filename by timestamp */
-
- dtime = now;
- for (;;) {
- sprintf(ip, "M.%d.A", (int)++dtime);
- fd = open(fpath, O_CREAT | O_EXCL | O_WRONLY, 0644);
- if (fd >= 0)
- break;
- dtime++;
- }
- close(fd);
-
- unlink(fpath);
- link(fname, fpath);
-
- /* append record to .DIR */
-
- memset(&header, 0, sizeof(fileheader_t));
- strlcpy(header.owner, "[°¨¸ô±´¤l]", sizeof(header.owner));
- snprintf(header.title, sizeof(header.title), "[%s] ¬ÝªO ¿ï±¡³ø¾É", bname);
- {
- register struct tm *ptime = localtime4(&dtime);
-
- snprintf(header.date, sizeof(header.date),
- "%2d/%02d", ptime->tm_mon + 1, ptime->tm_mday);
- }
- strlcpy(header.filename, ip, sizeof(header.filename));
-
- strcpy(ip, FN_DIR);
- if ((fd = open(fpath, O_WRONLY | O_CREAT, 0644)) >= 0) {
- flock(fd, LOCK_EX);
- lseek(fd, 0, SEEK_END);
- write(fd, &header, sizeof(fileheader_t));
- flock(fd, LOCK_UN);
- close(fd);
- if ((bid = getbnum(bname)) > 0)
- setbtotal(bid);
-
- }
-}
-
-static void
-b_result_one(vote_buffer_t *vbuf, boardheader_t * fh, int ind, int *total)
-{
- FILE *cfp, *tfp, *frp, *xfp;
- char *bname;
- char buf[STRLEN];
- char inbuf[80];
- int *counts;
- int people_num;
- short item_num, junk;
- char b_control[64];
- char b_newresults[64];
- char b_report[64];
- time4_t closetime;
-
- fh->bvote--;
-
- snprintf(vbuf->ballots, sizeof(vbuf->ballots), "%s%d", STR_bv_ballots, ind);
- snprintf(vbuf->control, sizeof(vbuf->control),"%s%d", STR_bv_control, ind);
- snprintf(vbuf->desc, sizeof(vbuf->desc), "%s%d", STR_bv_desc, ind);
- snprintf(vbuf->flags, sizeof(vbuf->flags), "%s%d", STR_bv_flags, ind);
- snprintf(vbuf->comments, sizeof(vbuf->comments), "%s%d", STR_bv_comments, ind);
- snprintf(vbuf->limited, sizeof(vbuf->limited), "%s%d", STR_bv_limited, ind);
- snprintf(vbuf->limits, sizeof(vbuf->limits), "%s%d", STR_bv_limits, ind);
- snprintf(vbuf->title, sizeof(vbuf->title), "%s%d", STR_bv_title, ind);
-
- bname = fh->brdname;
-
- setbfile(buf, bname, vbuf->control);
- cfp = fopen(buf, "r");
- assert(cfp);
- fscanf(cfp, "%hd,%hd\n%d\n", &item_num, &junk, &closetime);
- fclose(cfp);
-
- // prevent death caused by a bug, it should be remove later.
- if (item_num <= 0)
- return;
-
- counts = (int *)malloc(item_num * sizeof(int));
-
- setbfile(b_control, bname, "tmp");
- if (rename(buf, b_control) == -1)
- return;
- setbfile(buf, bname, vbuf->flags);
- people_num = b_nonzeroNum(buf);
- unlink(buf);
- setbfile(buf, bname, vbuf->ballots);
- b_count(buf, counts, item_num, total);
- unlink(buf);
-
- setbfile(b_newresults, bname, "newresults");
- if ((tfp = fopen(b_newresults, "w")) == NULL)
- return;
-
- setbfile(buf, bname, vbuf->title);
-
- if ((xfp = fopen(buf, "r"))) {
- fgets(inbuf, sizeof(inbuf), xfp);
- fprintf(tfp, "%s\n¡» §ë²¼¦WºÙ: %s\n\n", msg_seperator, inbuf);
- fclose(xfp);
- }
- fprintf(tfp, "%s\n¡» §ë²¼¤¤¤î©ó: %s\n\n¡» ²¼¿ïÃD¥Ø´y­z:\n\n",
- msg_seperator, ctime4(&closetime));
- fh->vtime = now;
-
- setbfile(buf, bname, vbuf->desc);
-
- b_suckinfile(tfp, buf);
- unlink(buf);
-
- if ((cfp = fopen(b_control, "r"))) {
- fgets(inbuf, sizeof(inbuf), cfp);
- fgets(inbuf, sizeof(inbuf), cfp);
- fprintf(tfp, "\n¡»§ë²¼µ²ªG:(¦@¦³ %d ¤H§ë²¼,¨C¤H³Ì¦h¥i§ë %hd ²¼)\n",
- people_num, junk);
- fprintf(tfp, " ¿ï ¶µ Á`²¼¼Æ ±o²¼²v ±o²¼¤À¥¬\n");
- for (junk = 0; junk < item_num; junk++) {
- fgets(inbuf, sizeof(inbuf), cfp);
- chomp(inbuf);
- fprintf(tfp, " %-42s %3d ²¼ %6.2f%% %6.2f%%\n", inbuf + 3, counts[junk],
- (float)(counts[junk] * 100) / (float)(people_num),
- (float)(counts[junk] * 100) / (float)(*total));
- }
- fclose(cfp);
- }
- unlink(b_control);
- free(counts);
-
- fprintf(tfp, "%s\n¡» ¨Ï¥ÎªÌ«Øij¡G\n\n", msg_seperator);
- setbfile(buf, bname, vbuf->comments);
- b_suckinfile(tfp, buf);
- unlink(buf);
-
- fprintf(tfp, "%s\n¡» Á`²¼¼Æ = %d ²¼\n\n", msg_seperator, *total);
- fclose(tfp);
-
- setbfile(b_report, bname, "report");
- if ((frp = fopen(b_report, "w"))) {
- b_suckinfile(frp, b_newresults);
- fclose(frp);
- }
- setbpath(inbuf, bname);
- vote_report(bname, b_report, inbuf);
- if (!(fh->brdattr & (BRD_NOCOUNT|BRD_HIDE))) { // from ptt2 local modification
- setbpath(inbuf, "Record");
- vote_report(bname, b_report, inbuf);
- }
- unlink(b_report);
-
- tfp = fopen(b_newresults, "a");
- setbfile(buf, bname, STR_bv_results);
- b_suckinfile(tfp, buf);
- fclose(tfp);
- Rename(b_newresults, buf);
-}
-
-static void
-b_result(vote_buffer_t *vbuf, boardheader_t * fh)
-{
- FILE *cfp;
- time4_t closetime;
- int i, total;
- char buf[STRLEN];
- char temp[STRLEN];
-
- for (i = 0; i < MAX_VOTE_NR; i++) {
- snprintf(vbuf->control, sizeof(vbuf->control), "%s%d", STR_bv_control, i);
-
- setbfile(buf, fh->brdname, vbuf->control);
- cfp = fopen(buf, "r");
- if (!cfp)
- continue;
- fgets(temp, sizeof(temp), cfp);
- fscanf(cfp, "%d\n", &closetime);
- fclose(cfp);
- if (closetime < now)
- b_result_one(vbuf, fh, i, &total);
- }
-}
-
-static int
-b_close(boardheader_t * fh, vote_buffer_t *vbuf)
-{
- b_result(vbuf, fh);
- return 1;
-}
-
-static int
-b_closepolls(void)
-{
- boardheader_t *fhp;
- int pos;
- vote_buffer_t vbuf;
-
-#ifndef BARRIER_HAS_BEEN_IN_SHM
- char *fn_vote_polling = ".polling";
- unsigned long last;
- FILE *cfp;
- /* XXX necessary to lock ? */
- if ((cfp = fopen(fn_vote_polling, "r"))) {
- char timebuf[100];
- fgets(timebuf, sizeof(timebuf), cfp);
- sscanf(timebuf, "%lu", &last);
- fclose(cfp);
- if (last + 3600 >= (unsigned long)now)
- return 0;
- }
- if ((cfp = fopen(fn_vote_polling, "w")) == NULL)
- return 0;
- fprintf(cfp, "%d\n%s\n", now, ctime4(&now));
- fclose(cfp);
-#endif
-
- for (fhp = bcache, pos = 1; pos <= numboards; fhp++, pos++) {
- if (fhp->bvote && b_close(fhp, &vbuf)) {
- if (substitute_record(fn_board, fhp, sizeof(*fhp), pos) == -1)
- outs(err_board_update);
- else
- reset_board(pos);
- }
- }
-
- return 0;
-}
-
-void
-auto_close_polls(void)
-{
- /* ³Ì¦h¤@¤Ñ¶}²¼¤@¦¸ */
- if (now - SHM->close_vote_time > 86400) {
- b_closepolls();
- SHM->close_vote_time = now;
- }
-}
-
-static int
-vote_view(vote_buffer_t *vbuf, const char *bname, int vote_index)
-{
- boardheader_t *fhp;
- FILE *fp;
- char buf[STRLEN], genbuf[STRLEN], inbuf[STRLEN];
- short item_num, i;
- int num = 0, pos, *counts, total;
- time4_t closetime;
-
- snprintf(vbuf->ballots, sizeof(vbuf->ballots),"%s%d", STR_bv_ballots, vote_index);
- snprintf(vbuf->control, sizeof(vbuf->control), "%s%d", STR_bv_control, vote_index);
- snprintf(vbuf->desc, sizeof(vbuf->desc), "%s%d", STR_bv_desc, vote_index);
- snprintf(vbuf->flags, sizeof(vbuf->flags), "%s%d", STR_bv_flags, vote_index);
- snprintf(vbuf->comments, sizeof(vbuf->comments), "%s%d", STR_bv_comments, vote_index);
- snprintf(vbuf->limited, sizeof(vbuf->limited), "%s%d", STR_bv_limited, vote_index);
- snprintf(vbuf->limits, sizeof(vbuf->limits), "%s%d", STR_bv_limits, vote_index);
- snprintf(vbuf->title, sizeof(vbuf->title), "%s%d", STR_bv_title, vote_index);
-
- setbfile(buf, bname, vbuf->ballots);
- if ((num = dashs(buf)) < 0) /* file size */
- num = 0;
-
- setbfile(buf, bname, vbuf->title);
- move(0, 0);
- clrtobot();
-
- if ((fp = fopen(buf, "r"))) {
- fgets(inbuf, sizeof(inbuf), fp);
- prints("\n§ë²¼¦WºÙ: %s", inbuf);
- fclose(fp);
- }
- setbfile(buf, bname, vbuf->control);
- fp = fopen(buf, "r");
-
- assert(fp);
- fscanf(fp, "%hd,%hd\n%d\n", &item_num, &i, &closetime);
- counts = (int *)malloc(item_num * sizeof(int));
-
- prints("\n¡» ¹wª¾§ë²¼¬ö¨Æ: ¨C¤H³Ì¦h¥i§ë %d ²¼,¥Ø«e¦@¦³ %d ²¼,\n"
- "¥»¦¸§ë²¼±Nµ²§ô©ó %s", atoi(inbuf), (int)(num / sizeof(short)),
- ctime4(&closetime));
-
- /* Thor: ¶}©ñ ²¼¼Æ ¹wª¾ */
- setbfile(buf, bname, vbuf->flags);
- prints("¦@¦³ %d ¤H§ë²¼\n", b_nonzeroNum(buf));
-
- setbfile(buf, bname, vbuf->ballots);
- b_count(buf, counts, item_num, &total);
-
- total = 0;
-
- for (i = num = 0; i < item_num; i++, num++) {
- fgets(inbuf, sizeof(inbuf), fp);
- chomp(inbuf);
- inbuf[30] = '\0'; /* truncate */
- move(num % 15 + 6, num / 15 * 40);
- prints(" %-32s%3d ²¼", inbuf, counts[i]);
- total += counts[i];
- if (num == 29) {
- num = -1;
- pressanykey();
- move(6, 0);
- clrtobot();
- }
- }
- fclose(fp);
- free(counts);
- pos = getbnum(bname);
- assert(0<=pos-1 && pos-1<MAX_BOARD);
- fhp = bcache + pos - 1;
- move(t_lines - 3, 0);
- prints("¡» ¥Ø«eÁ`²¼¼Æ = %d ²¼", total);
- getdata(b_lines - 1, 0, "(A)¨ú®ø§ë²¼ (B)´£¦­¶}²¼ (C)Ä~Äò¡H[C] ", genbuf,
- 4, LCECHO);
- if (genbuf[0] == 'a') {
- getdata(b_lines - 1, 0, "½Ð¦A¦¸½T»{¨ú®ø§ë²¼ (Y/N) [N] ", genbuf,
- 4, LCECHO);
- if (genbuf[0] == 'n')
- return FULLUPDATE;
-
- setbfile(buf, bname, vbuf->control);
- unlink(buf);
- setbfile(buf, bname, vbuf->flags);
- unlink(buf);
- setbfile(buf, bname, vbuf->ballots);
- unlink(buf);
- setbfile(buf, bname, vbuf->desc);
- unlink(buf);
- setbfile(buf, bname, vbuf->limited);
- unlink(buf);
- setbfile(buf, bname, vbuf->limits);
- unlink(buf);
- setbfile(buf, bname, vbuf->title);
- unlink(buf);
-
- fhp->bvote--;
-
- if (substitute_record(fn_board, fhp, sizeof(*fhp), pos) == -1)
- outs(err_board_update);
- reset_board(pos);
- } else if (genbuf[0] == 'b') {
- b_result_one(vbuf, fhp, vote_index, &total);
- if (substitute_record(fn_board, fhp, sizeof(*fhp), pos) == -1)
- outs(err_board_update);
-
- reset_board(pos);
- }
- return FULLUPDATE;
-}
-
-static int
-vote_view_all(vote_buffer_t *vbuf, const char *bname)
-{
- int i;
- int x = -1;
- FILE *fp, *xfp;
- char buf[STRLEN], genbuf[STRLEN];
- char inbuf[80];
-
- move(0, 0);
- for (i = 0; i < MAX_VOTE_NR; i++) {
- snprintf(vbuf->control, sizeof(vbuf->control), "%s%d", STR_bv_control, i);
- snprintf(vbuf->title, sizeof(vbuf->title), "%s%d", STR_bv_title, i);
- setbfile(buf, bname, vbuf->control);
- if ((fp = fopen(buf, "r"))) {
- prints("(%d) ", i);
- x = i;
- fclose(fp);
-
- setbfile(buf, bname, vbuf->title);
- if ((xfp = fopen(buf, "r"))) {
- fgets(inbuf, sizeof(inbuf), xfp);
- fclose(xfp);
- } else
- strlcpy(inbuf, "µL¼ÐÃD", sizeof(inbuf));
- prints("%s\n", inbuf);
- }
- }
-
- if (x < 0)
- return FULLUPDATE;
- snprintf(buf, sizeof(buf), "­n¬Ý´X¸¹§ë²¼ [%d] ", x);
-
- getdata(b_lines - 1, 0, buf, genbuf, 4, LCECHO);
-
-
- if (atoi(genbuf) < 0 || atoi(genbuf) > MAX_VOTE_NR)
- snprintf(genbuf, sizeof(genbuf), "%d", x);
- snprintf(vbuf->control, sizeof(vbuf->control), "%s%d", STR_bv_control, atoi(genbuf));
-
- setbfile(buf, bname, vbuf->control);
-
- if (dashf(buf)) {
- return vote_view(vbuf, bname, atoi(genbuf));
- } else
- return FULLUPDATE;
-}
-
-static int
-vote_maintain(const char *bname)
-{
- FILE *fp = NULL;
- char inbuf[STRLEN], buf[STRLEN];
- int num = 0, aborted, pos, x, i;
- time4_t closetime;
- boardheader_t *fhp;
- char genbuf[4];
- vote_buffer_t vbuf;
-
- if (!(currmode & MODE_BOARD))
- return 0;
- if ((pos = getbnum(bname)) <= 0)
- return 0;
-
- assert(0<=pos-1 && pos-1<MAX_BOARD);
- fhp = bcache + pos - 1;
-
- if (fhp->bvote != 0) {
-
-#if 0 // convert the filenames of first vote
- convert_first_vote(fhp);
-#endif
- getdata(b_lines - 1, 0,
- "(V)Æ[¹î¥Ø«e§ë²¼ (M)Á|¿ì·s§ë²¼ (A)¨ú®ø©Ò¦³§ë²¼ (Q)Ä~Äò [Q]",
- genbuf, 4, LCECHO);
- if (genbuf[0] == 'v')
- return vote_view_all(&vbuf, bname);
- else if (genbuf[0] == 'a') {
- fhp->bvote = 0;
-
- for (i = 0; i < MAX_VOTE_NR; i++) {
- int j;
- char buf2[64];
- const char *filename[] = {
- STR_bv_ballots, STR_bv_control, STR_bv_desc, STR_bv_desc,
- STR_bv_flags, STR_bv_comments, STR_bv_limited, STR_bv_limits,
- STR_bv_title, NULL
- };
- for (j = 0; filename[j] != NULL; j++) {
- snprintf(buf2, sizeof(buf2), "%s%d", filename[j], i);
- setbfile(buf, bname, buf2);
- unlink(buf);
- }
- }
- if (substitute_record(fn_board, fhp, sizeof(*fhp), pos) == -1)
- outs(err_board_update);
-
- return FULLUPDATE;
- } else if (genbuf[0] != 'm') {
- if (fhp->bvote >= MAX_VOTE_NR)
- vmsg("¤£±oÁ|¿ì¹L¦h§ë²¼");
- return FULLUPDATE;
- }
- }
-
- x = 1;
- do {
- snprintf(vbuf.control, sizeof(vbuf.control), "%s%d", STR_bv_control, x);
- setbfile(buf, bname, vbuf.control);
- x++;
- } while (dashf(buf) && x <= MAX_VOTE_NR);
-
- --x;
- if (x >= MAX_VOTE_NR)
- return FULLUPDATE;
-
- getdata(b_lines - 1, 0,
- "½T©w­nÁ|¿ì§ë²¼¶Ü¡H [y/N]: ",
- inbuf, 4, LCECHO);
- if (inbuf[0] != 'y')
- return FULLUPDATE;
-
- stand_title("Á|¿ì§ë²¼");
- snprintf(vbuf.ballots, sizeof(vbuf.ballots), "%s%d", STR_bv_ballots, x);
- snprintf(vbuf.control, sizeof(vbuf.control), "%s%d", STR_bv_control, x);
- snprintf(vbuf.desc, sizeof(vbuf.desc), "%s%d", STR_bv_desc, x);
- snprintf(vbuf.flags, sizeof(vbuf.flags), "%s%d", STR_bv_flags, x);
- snprintf(vbuf.comments, sizeof(vbuf.comments), "%s%d", STR_bv_comments, x);
- snprintf(vbuf.limited, sizeof(vbuf.limited), "%s%d", STR_bv_limited, x);
- snprintf(vbuf.limits, sizeof(vbuf.limits), "%s%d", STR_bv_limits, x);
- snprintf(vbuf.title, sizeof(vbuf.title), "%s%d", STR_bv_title, x);
-
- clear();
- move(0, 0);
- prints("²Ä %d ¸¹§ë²¼\n", x);
- setbfile(buf, bname, vbuf.title);
- getdata(4, 0, "½Ð¿é¤J§ë²¼¦WºÙ:", inbuf, 50, LCECHO);
- if (inbuf[0] == '\0')
- strlcpy(inbuf, "¤£ª¾¦Wªº", sizeof(inbuf));
- fp = fopen(buf, "w");
- assert(fp);
- fputs(inbuf, fp);
- fclose(fp);
-
- vmsg("«ö¥ô¦óÁä¶}©l½s¿è¦¹¦¸ [§ë²¼©v¦®]");
- setbfile(buf, bname, vbuf.desc);
- aborted = vedit(buf, NA, NULL);
- if (aborted == -1) {
- vmsg("¨ú®ø¦¹¦¸§ë²¼");
- return FULLUPDATE;
- }
- aborted = 0;
- setbfile(buf, bname, vbuf.flags);
- unlink(buf);
-
- getdata(4, 0,
- "¬O§_­­©w§ë²¼ªÌ¦W³æ¡G(y)½s¿è¥i§ë²¼¤H­û¦W³æ[n]¥ô¦ó¤H¬Ò¥i§ë²¼:[N]",
- inbuf, 2, LCECHO);
- setbfile(buf, bname, vbuf.limited);
- if (inbuf[0] == 'y') {
- fp = fopen(buf, "w");
- assert(fp);
- //fprintf(fp, "¦¹¦¸§ë²¼³]­­");
- fclose(fp);
- friend_edit(FRIEND_CANVOTE);
- } else {
- if (dashf(buf))
- unlink(buf);
- }
- getdata(5, 0,
- "¬O§_­­©w§ë²¼¸ê®æ¡G(y)­­¨î§ë²¼¸ê®æ[n]¤£³]­­:[N]",
- inbuf, 2, LCECHO);
- setbfile(buf, bname, vbuf.limits);
- if (inbuf[0] == 'y') {
- fp = fopen(buf, "w");
- assert(fp);
- do {
- getdata(6, 0, "µù¥U®É¶¡­­¨î (¥H'¤ë'¬°³æ¦ì¡A0~120)¡G", inbuf, 4, DOECHO);
- closetime = atoi(inbuf); // borrow variable
- } while (closetime < 0 || closetime > 120);
- fprintf(fp, "%d\n", now - (2592000 * closetime));
- do {
- getdata(6, 0, "¤W¯¸¦¸¼Æ¤U­­", inbuf, 6, DOECHO);
- closetime = atoi(inbuf); // borrow variable
- } while (closetime < 0);
- fprintf(fp, "%d\n", closetime);
- do {
- getdata(6, 0, "¤å³¹½g¼Æ¤U­­", inbuf, 6, DOECHO);
- closetime = atoi(inbuf); // borrow variable
- } while (closetime < 0);
- fprintf(fp, "%d\n", closetime);
- fclose(fp);
- } else {
- if (dashf(buf))
- unlink(buf);
- }
- clear();
- getdata(0, 0, "¦¹¦¸§ë²¼¶i¦æ´X¤Ñ (¤@¨ì¤T¤Q¤Ñ)¡H", inbuf, 4, DOECHO);
-
- closetime = atoi(inbuf);
- if (closetime <= 0)
- closetime = 1;
- else if (closetime > 30)
- closetime = 30;
-
- closetime = closetime * 86400 + now;
- setbfile(buf, bname, vbuf.control);
- fp = fopen(buf, "w");
- assert(fp);
- fprintf(fp, "000,000\n%d\n", closetime);
-
- outs("\n½Ð¨Ì§Ç¿é¤J¿ï¶µ, «ö ENTER §¹¦¨³]©w");
- num = 0;
- x = 0; /* x is the page number */
- while (!aborted) {
- if( num % 15 == 0 ){
- for( i = num ; i < num + 15 ; ++i ){
- move((i % 15) + 2, (i / 15) * 40);
- prints(ANSI_COLOR(1;30) "%c)" ANSI_RESET " ", i + 'A');
- }
- }
- snprintf(buf, sizeof(buf), "%c) ", num + 'A');
- getdata((num % 15) + 2, (num / 15) * 40, buf,
- inbuf, 37, DOECHO);
- if (*inbuf) {
- fprintf(fp, "%1c) %s\n", (num + 'A'), inbuf);
- num++;
- }
- if ((*inbuf == '\0' && num >= 1) || x == MAX_VOTE_PAGE)
- aborted = 1;
- if (num == ITEM_PER_PAGE) {
- x++;
- num = 0;
- }
- }
- snprintf(buf, sizeof(buf), "½Ð°Ý¨C¤H³Ì¦h¥i§ë´X²¼¡H([1]¡ã%d): ", x * ITEM_PER_PAGE + num);
-
- getdata(t_lines - 3, 0, buf, inbuf, 3, DOECHO);
-
- if (atoi(inbuf) <= 0 || atoi(inbuf) > (x * ITEM_PER_PAGE + num)) {
- inbuf[0] = '1';
- inbuf[1] = 0;
- }
-
- rewind(fp);
- fprintf(fp, "%3d,%3d\n", x * ITEM_PER_PAGE + num, MAX(1, atoi(inbuf)));
- fclose(fp);
-
- fhp->bvote++;
-
- if (substitute_record(fn_board, fhp, sizeof(*fhp), pos) == -1)
- outs(err_board_update);
- reset_board(pos);
- outs("¶}©l§ë²¼¤F¡I");
-
- return FULLUPDATE;
-}
-
-static int
-vote_flag(vote_buffer_t *vbuf, const char *bname, int index, char val)
-{
- char buf[256], flag;
- int fd, num, size;
-
- snprintf(vbuf->flags, sizeof(vbuf->flags), "%s%d", STR_bv_flags, index);
-
- num = usernum - 1;
- setbfile(buf, bname, vbuf->flags);
- if ((fd = open(buf, O_RDWR | O_CREAT, 0600)) == -1)
- return -1;
- size = lseek(fd, 0, SEEK_END);
- memset(buf, 0, sizeof(buf));
- while (size <= num) {
- write(fd, buf, sizeof(buf));
- size += sizeof(buf);
- }
- lseek(fd, num, SEEK_SET);
- read(fd, &flag, 1);
- if (flag == 0 && val != 0) {
- lseek(fd, num, SEEK_SET);
- write(fd, &val, 1);
- }
- close(fd);
- return flag;
-}
-
-static int
-user_vote_one(vote_buffer_t *vbuf, const char *bname, int ind)
-{
- FILE *cfp, *fcm;
- char buf[STRLEN], redo;
- boardheader_t *fhp;
- short count, tickets;
- short curr_page, item_num, max_page;
- char inbuf[80], choices[ITEM_PER_PAGE+1], vote[4], *chosen;
- time4_t closetime;
-
- // pos = boaord id, must be at least one int.
- // fd should be int.
- int pos = 0, i = 0;
- int fd = 0;
-
- snprintf(vbuf->ballots, sizeof(vbuf->ballots), "%s%d", STR_bv_ballots, ind);
- snprintf(vbuf->control, sizeof(vbuf->control), "%s%d", STR_bv_control, ind);
- snprintf(vbuf->desc, sizeof(vbuf->desc), "%s%d", STR_bv_desc, ind);
- snprintf(vbuf->flags, sizeof(vbuf->flags),"%s%d", STR_bv_flags, ind);
- snprintf(vbuf->comments, sizeof(vbuf->comments), "%s%d", STR_bv_comments, ind);
- snprintf(vbuf->limited, sizeof(vbuf->limited), "%s%d", STR_bv_limited, ind);
- snprintf(vbuf->limits, sizeof(vbuf->limits), "%s%d", STR_bv_limits, ind);
-
- setbfile(buf, bname, vbuf->control);
- cfp = fopen(buf, "r");
- if (!cfp)
- return FULLUPDATE;
-
- setbfile(buf, bname, vbuf->limited); /* Ptt */
- if (dashf(buf)) {
- setbfile(buf, bname, FN_CANVOTE);
- if (!belong(buf, cuser.userid)) {
- fclose(cfp);
- vmsg("¹ï¤£°_! ³o¬O¨p¤H§ë²¼..§A¨Ã¨S¦³¨üÁÜ­ò!");
- return FULLUPDATE;
- } else {
- vmsg("®¥³ß§A¨üÁܦ¹¦¸¨p¤H§ë²¼. <À˵ø¦¹¦¸¨üÁܦW³æ>");
- more(buf, YEA);
- }
- }
- setbfile(buf, bname, vbuf->limits);
- if (dashf(buf)) {
- int limits_logins, limits_posts;
- FILE * lfp = fopen(buf, "r");
- assert(lfp);
- fscanf(lfp, "%d", &closetime);
- fscanf(lfp, "%d", &limits_logins);
- fscanf(lfp, "%d", &limits_posts);
- fclose(lfp);
- if (cuser.firstlogin > closetime || cuser.numposts < limits_posts ||
- cuser.numlogins < limits_logins) {
- vmsg("§A¤£°÷¸ê²`³á¡I");
- return FULLUPDATE;
- }
- }
- if (vote_flag(vbuf, bname, ind, '\0')) {
- vmsg("¦¹¦¸§ë²¼¡A§A¤w§ë¹L¤F¡I");
- return FULLUPDATE;
- }
- setutmpmode(VOTING);
- setbfile(buf, bname, vbuf->desc);
- more(buf, YEA);
-
- stand_title("§ë²¼½c");
- if ((pos = getbnum(bname)) <= 0)
- return 0;
-
- assert(0<=pos-1 && pos-1<MAX_BOARD);
- fhp = bcache + pos - 1;
-
- assert(cfp);
- fscanf(cfp, "%hd,%hd\n%d\n", &item_num, &tickets, &closetime);
- chosen = (char *)malloc(item_num+100); // XXX dirty fix ªO¥D¼W¥[¿ï¶µªº°ÝÃD
- memset(chosen, 0, item_num+100);
- memset(choices, 0, sizeof(choices));
- max_page = (item_num - 1)/ ITEM_PER_PAGE + 1;
-
- outs("§ë²¼¤è¦¡¡G½T©w¦n±zªº¿ï¾Ü«á¡A¿é¤J¨ä¥N½X(A, B, C...)§Y¥i¡C\n");
- prints("¦¹¦¸§ë²¼§A¥i¥H§ë %1hd ²¼¡C«ö 0 ¨ú®ø§ë²¼, 1 §¹¦¨§ë²¼, "
- "> ¤U¤@­¶, < ¤W¤@­¶\n¦¹¦¸§ë²¼±Nµ²§ô©ó¡G%s \n",
- tickets, ctime4(&closetime));
-
-#define REDO_DRAW 1
-#define REDO_SCAN 2
- redo = REDO_DRAW;
- curr_page = 0;
- while (1) {
-
- if (redo) {
- int i, j;
- move(5, 0);
- clrtobot();
-
- /* ·Q¤£¨ì¦n¤èªk ¦]¬°¤£·Q¾ã­ÓŪ¶i memory
- * ¦Ó¥B¤j³¡¤Àªº§ë²¼¤£·|¶W¹L¤@­¶ ©Ò¥H¦A±qÀÉ®× scan */
- /* XXX §ë¨ì¤@¥bªO¥D¼W¥[¿ï¶µ«h chosen ¤Ó¤p */
- if (redo & REDO_SCAN) {
- for (i = 0; i < curr_page; i++)
- for (j = 0; j < ITEM_PER_PAGE; j++)
- fgets(inbuf, sizeof(inbuf), cfp);
- }
-
- count = 0;
- for (i = 0; i < ITEM_PER_PAGE && fgets(inbuf, sizeof(inbuf), cfp); i++) {
- chomp(inbuf);
- move((count % 15) + 5, (count / 15) * 40);
- prints("%c%s", chosen[curr_page * ITEM_PER_PAGE + i] ? '*' : ' ',
- inbuf);
- choices[count % ITEM_PER_PAGE] = inbuf[0];
- count++;
- }
- redo = 0;
- }
-
- vote[0] = vote[1] = '\0';
- move(t_lines - 2, 0);
- prints("§AÁÙ¥i¥H§ë %2d ²¼ [ ¥Ø«e©Ò¦b­¶¼Æ %2d / ¦@ %2d ­¶ (¥i¿é¤J '<' '>' ´«­¶) ]", tickets - i, curr_page + 1, max_page);
- getdata(t_lines - 4, 0, "¿é¤J±zªº¿ï¾Ü: ", vote, sizeof(vote), DOECHO);
- *vote = toupper(*vote);
-
-#define CURRENT_CHOICE \
- chosen[curr_page * ITEM_PER_PAGE + vote[0] - 'A']
- if (vote[0] == '0' || (!vote[0] && !i)) {
- outs("°O±o¦A¨Ó§ë³á!!");
- break;
- } else if (vote[0] == '1' && i);
- else if (!vote[0])
- continue;
- else if (vote[0] == '<' && max_page > 1) {
- curr_page = (curr_page + max_page - 1) % max_page;
- rewind(cfp);
- fgets(inbuf, sizeof(inbuf), cfp);
- fgets(inbuf, sizeof(inbuf), cfp);
- redo = REDO_DRAW | REDO_SCAN;
- continue;
- }
- else if (vote[0] == '>' && max_page > 1) {
- curr_page = (curr_page + 1) % max_page;
- if (curr_page == 0) {
- rewind(cfp);
- fgets(inbuf, sizeof(inbuf), cfp);
- fgets(inbuf, sizeof(inbuf), cfp);
- }
- redo = REDO_DRAW;
- continue;
- }
- else if (index(choices, vote[0]) == NULL) /* µL®Ä */
- continue;
- else if ( CURRENT_CHOICE ) { /* ¤w¿ï */
- move(((vote[0] - 'A') % 15) + 5, (((vote[0] - 'A')) / 15) * 40);
- outc(' ');
- CURRENT_CHOICE = 0;
- i--;
- continue;
- } else {
- if (i == tickets)
- continue;
- move(((vote[0] - 'A') % 15) + 5, (((vote[0] - 'A')) / 15) * 40);
- outc('*');
- CURRENT_CHOICE = 1;
- i++;
- continue;
- }
-
- if (vote_flag(vbuf, bname, ind, vote[0]) != 0)
- outs("­«½Æ§ë²¼! ¤£¤©­p²¼¡C");
- else {
- setbfile(buf, bname, vbuf->ballots);
- if ((fd = open(buf, O_WRONLY | O_CREAT | O_APPEND, 0600)) == 0)
- outs("µLªk§ë¤J²¼Ôo\n");
- else {
- struct stat statb;
- char buf[3], mycomments[3][74], b_comments[80];
-
- for (i = 0; i < 3; i++)
- strlcpy(mycomments[i], "\n", sizeof(mycomments[i]));
-
- flock(fd, LOCK_EX);
- for (count = 0; count < item_num; count++) {
- if (chosen[count])
- write(fd, &count, sizeof(short));
- }
- flock(fd, LOCK_UN);
- fstat(fd, &statb);
- close(fd);
- getdata(b_lines - 2, 0,
- "±z¹ï³o¦¸§ë²¼¦³¤°»òÄ_¶Qªº·N¨£¶Ü¡H(y/n)[N]",
- buf, 3, DOECHO);
- if (buf[0] == 'Y' || buf[0] == 'y') {
- do {
- move(5, 0);
- clrtobot();
- outs("½Ð°Ý±z¹ï³o¦¸§ë²¼¦³¤°»òÄ_¶Qªº·N¨£¡H"
- "³Ì¦h¤T¦æ¡A«ö[Enter]µ²§ô");
- for (i = 0; (i < 3) &&
- getdata(7 + i, 0, "¡G",
- mycomments[i], sizeof(mycomments[i]),
- DOECHO); i++);
- getdata(b_lines - 2, 0, "(S)Àx¦s (E)­«·s¨Ó¹L "
- "(Q)¨ú®ø¡H[S]", buf, 3, LCECHO);
- } while (buf[0] == 'E' || buf[0] == 'e');
- if (buf[0] == 'Q' || buf[0] == 'q')
- break;
- setbfile(b_comments, bname, vbuf->comments);
- if (mycomments[0][0])
- if ((fcm = fopen(b_comments, "a"))) {
- fprintf(fcm,
- ANSI_COLOR(36) "¡³¨Ï¥ÎªÌ" ANSI_COLOR(1;36) " %s "
- ANSI_COLOR(;36) "ªº«Øij¡G" ANSI_RESET "\n",
- cuser.userid);
- for (i = 0; i < 3; i++)
- fprintf(fcm, " %s\n", mycomments[i]);
- fprintf(fcm, "\n");
- fclose(fcm);
- }
- }
- move(b_lines - 1, 0);
- outs("¤w§¹¦¨§ë²¼¡I\n");
- }
- }
- break;
- }
- free(chosen);
- fclose(cfp);
- pressanykey();
- return FULLUPDATE;
-}
-
-static int
-user_vote(const char *bname)
-{
- int pos;
- boardheader_t *fhp;
- char buf[STRLEN];
- FILE *fp, *xfp;
- int i, x = -1;
- char genbuf[STRLEN];
- char inbuf[80];
- vote_buffer_t vbuf;
-
- if ((pos = getbnum(bname)) <= 0)
- return 0;
-
- assert(0<=pos-1 && pos-1<MAX_BOARD);
- fhp = bcache + pos - 1;
-
- move(0, 0);
- clrtobot();
-
- if (fhp->bvote == 0) {
- vmsg("¥Ø«e¨Ã¨S¦³¥ô¦ó§ë²¼Á|¦æ¡C");
- return FULLUPDATE;
- }
-#if 0 // convert the filenames of first vote
- convert_first_vote(fhp);
-#endif
- if (!HasUserPerm(PERM_LOGINOK)) {
- vmsg("¹ï¤£°_! ±z¥¼º¡¤G¤Q·³, ÁÙ¨S¦³§ë²¼Åv³á!");
- return FULLUPDATE;
- }
-
- move(0, 0);
- for (i = 0; i < MAX_VOTE_NR; i++) {
- snprintf(vbuf.control, sizeof(vbuf.control), "%s%d", STR_bv_control, i);
- snprintf(vbuf.title, sizeof(vbuf.title), "%s%d", STR_bv_title, i);
- setbfile(buf, bname, vbuf.control);
- if ((fp = fopen(buf, "r"))) {
- prints("(%d) ", i);
- x = i;
- fclose(fp);
-
- setbfile(buf, bname, vbuf.title);
- if ((xfp = fopen(buf, "r"))) {
- fgets(inbuf, sizeof(inbuf), xfp);
- fclose(xfp);
- } else
- strlcpy(inbuf, "µL¼ÐÃD", sizeof(inbuf));
- prints("%s\n", inbuf);
- }
- }
-
- if (x < 0)
- return FULLUPDATE;
-
- snprintf(buf, sizeof(buf), "­n§ë´X¸¹§ë²¼ [%d] ", x);
-
- getdata(b_lines - 1, 0, buf, genbuf, 4, LCECHO);
-
- if (atoi(genbuf) < 0 || atoi(genbuf) > MAX_VOTE_NR)
- snprintf(genbuf, sizeof(genbuf), "%d", x);
-
- snprintf(vbuf.control, sizeof(vbuf.control), "%s%d", STR_bv_control, atoi(genbuf));
-
- setbfile(buf, bname, vbuf.control);
-
- if (dashf(buf)) {
- return user_vote_one(&vbuf, bname, atoi(genbuf));
- } else
- return FULLUPDATE;
-}
-
-static int
-vote_results(const char *bname)
-{
- char buf[STRLEN];
-
- setbfile(buf, bname, STR_bv_results);
- if (more(buf, YEA) == -1)
- vmsg("¥Ø«e¨S¦³¥ô¦ó§ë²¼ªºµ²ªG¡C");
- return FULLUPDATE;
-}
-
-int
-b_vote_maintain(void)
-{
- return vote_maintain(currboard);
-}
-
-int
-b_vote(void)
-{
- return user_vote(currboard);
-}
-
-int
-b_results(void)
-{
- return vote_results(currboard);
-}
diff --git a/mbbsd/voteboard.c b/mbbsd/voteboard.c
deleted file mode 100644
index 81018da2..00000000
--- a/mbbsd/voteboard.c
+++ /dev/null
@@ -1,400 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-#define VOTEBOARD "NewBoard"
-
-// user
-int CheckVoteRestriction(int bid)
-{
- if ((currmode & MODE_BOARD) || HasUserPerm(PERM_SYSOP))
- return 1;
-
- // check first-login
- if (cuser.firstlogin > (now - (time4_t)bcache[bid - 1].vote_limit_regtime * 2592000))
- return 0;
- if (cuser.numlogins / 10 < (unsigned int)bcache[bid - 1].vote_limit_logins)
- return 0;
- if (cuser.numposts / 10 < (unsigned int)bcache[bid - 1].vote_limit_posts)
- return 0;
- if (cuser.badpost > (255 - (unsigned int)bcache[bid - 1].vote_limit_badpost))
- return 0;
-
- return 1;
-}
-
-// article
-int CheckVoteRestrictionFile(const fileheader_t * fhdr)
-{
- if ((currmode & MODE_BOARD) || HasUserPerm(PERM_SYSOP))
- return 1;
-
- // check first-login
- if (cuser.firstlogin > (now - (time4_t)fhdr->multi.vote_limits.regtime * 2592000))
- return 0;
- if (cuser.numlogins / 10 < (unsigned int)fhdr->multi.vote_limits.logins)
- return 0;
- if (cuser.numposts / 10 < (unsigned int)fhdr->multi.vote_limits.posts)
- return 0;
- if (cuser.badpost > (255 - (unsigned int)fhdr->multi.vote_limits.badpost))
- return 0;
-
- return 1;
-}
-
-void
-do_voteboardreply(const fileheader_t * fhdr)
-{
- char genbuf[256];
- char reason[36]="";
- char fpath[80];
- char oldfpath[80];
- char opnion[10];
- char *ptr;
- FILE *fo,*fi;
- fileheader_t votefile;
- int yes=0, no=0, len;
- int fd;
- unsigned long endtime=0;
-
-
- clear();
- if (!CheckPostPerm()||HasUserPerm(PERM_NOCITIZEN)) {
- move(5, 10);
- vmsg("¹ï¤£°_¡A±z¥Ø«eµLªk¦b¦¹µoªí¤å³¹¡I");
- return;
- }
-
- if (!CheckVoteRestrictionFile(fhdr))
- {
- move(5, 10); // why move (5, 10)?
- vmsg("§A¤£°÷¸ê²`³á¡I (¥i«ö i ¬d¬Ý­­¨î)");
- return;
- }
- setbpath(fpath, currboard);
- stampfile(fpath, &votefile);
-
- setbpath(oldfpath, currboard);
-
- strcat(oldfpath, "/");
- strcat(oldfpath, fhdr->filename);
-
- fi = fopen(oldfpath, "r");
- assert(fi);
-
- while (fgets(genbuf, sizeof(genbuf), fi)) {
- char *space;
-
- if (yes>=0)
- {
- if (!strncmp(genbuf, "----------",10))
- {yes=-1; continue;}
- else
- yes++;
- }
- if (yes>3) outs(genbuf);
-
- if (!strncmp(genbuf, "³s¸pµ²§ô®É¶¡", 12)) {
- ptr = strchr(genbuf, '(');
- assert(ptr);
- sscanf(ptr + 1, "%lu", &endtime);
- if (endtime < (unsigned long)now) {
- vmsg("³s¸p®É¶¡¤w¹L");
- fclose(fi);
- return;
- }
- }
- if(yes>=0) continue;
-
- space = strpbrk(genbuf+4, " \n");
- if(space) *space='\0';
- if (!strncmp(genbuf + 4, cuser.userid, IDLEN)) {
- move(5, 10);
- outs("±z¤w¸g³s¸p¹L¥»½g¤F");
- getdata(17, 0, "­n­×§ï±z¤§«eªº³s¸p¶Ü¡H(Y/N) [N]", opnion, 3, LCECHO);
- if (opnion[0] != 'y') {
- fclose(fi);
- return;
- }
- strlcpy(reason, genbuf + 19, 34);
- break;
- }
- }
- fclose(fi);
- do {
- if (!getdata(19, 0, "½Ð°Ý±z (Y)¤ä«ù (N)¤Ï¹ï ³o­ÓijÃD¡G", opnion, 3, LCECHO)) {
- return;
- }
- } while (opnion[0] != 'y' && opnion[0] != 'n');
- sprintf(genbuf, "½Ð°Ý±z»P³o­ÓijÃDªºÃö«Y©Î%s²z¥Ñ¬°¦ó¡G",
- opnion[0] == 'y' ? "¤ä«ù" : "¤Ï¹ï");
- if (!getdata_buf(20, 0, genbuf, reason, 35, DOECHO)) {
- return;
- }
- if ((fd = open(oldfpath, O_RDONLY)) == -1)
- return;
- if(flock(fd, LOCK_EX)==-1 )
- {close(fd); return;}
- if(!(fi = fopen(oldfpath, "r")))
- {flock(fd, LOCK_UN); close(fd); return;}
-
- if(!(fo = fopen(fpath, "w")))
- {
- flock(fd, LOCK_UN);
- close(fd);
- fclose(fi);
- return;
- }
-
- while (fgets(genbuf, sizeof(genbuf), fi)) {
- if (!strncmp("----------", genbuf, 10))
- break;
- fputs(genbuf, fo);
- }
- if (!endtime) {
- now += 14 * 24 * 60 * 60;
- fprintf(fo, "³s¸pµ²§ô®É¶¡: (%d)%s\n", now, ctime4(&now));
- now -= 14 * 24 * 60 * 60;
- }
- fputs(genbuf, fo);
- len = strlen(cuser.userid);
- for(yes=0; fgets(genbuf, sizeof(genbuf), fi);) {
- if (!strncmp("----------", genbuf, 10))
- break;
- if (strlen(genbuf)<30 || (genbuf[4+len]==' ' && !strncmp(genbuf + 4, cuser.userid, len)))
- continue;
- fprintf(fo, "%3d.%s", ++yes, genbuf + 4);
- }
- if (opnion[0] == 'y')
- fprintf(fo, "%3d.%-15s%-34s ¨Ó·½:%s\n", ++yes, cuser.userid, reason, cuser.lasthost);
- fputs(genbuf, fo);
-
- for(no=0; fgets(genbuf, sizeof(genbuf), fi);) {
- if (!strncmp("----------", genbuf, 10))
- break;
- if (strlen(genbuf)<30 || (genbuf[4+len]==' ' && !strncmp(genbuf + 4, cuser.userid, len)))
- continue;
- fprintf(fo, "%3d.%s", ++no, genbuf + 4);
- }
- if (opnion[0] == 'n')
- fprintf(fo, "%3d.%-15s%-34s ¨Ó·½:%s\n", ++no, cuser.userid, reason, cuser.lasthost);
- fprintf(fo, "----------Á`­p----------\n");
- fprintf(fo, "¤ä«ù¤H¼Æ:%-9d¤Ï¹ï¤H¼Æ:%-9d\n", yes, no);
- fprintf(fo, "\n--\n¡° µo«H¯¸ :" BBSNAME "(" MYHOSTNAME
- ") \n¡» From: ³s¸p¤å³¹\n");
-
- flock(fd, LOCK_UN);
- close(fd);
- fclose(fi);
- fclose(fo);
- unlink(oldfpath);
- rename(fpath, oldfpath);
-}
-
-int
-do_voteboard(int type)
-{
- fileheader_t votefile;
- char topic[100];
- char title[80];
- char genbuf[1024];
- char fpath[80];
- FILE *fp;
- int temp;
-
- clear();
- if (!CheckPostPerm()) {
- move(5, 10);
- vmsg("¹ï¤£°_¡A±z¥Ø«eµLªk¦b¦¹µoªí¤å³¹¡I");
- return FULLUPDATE;
- }
- if (!CheckVoteRestriction(currbid))
- {
- move(5, 10); // why move (5, 10)?
- vmsg("§A¤£°÷¸ê²`³á¡I (¥i«ö i ¬d¬Ý­­¨î)");
- return FULLUPDATE;
- }
- move(0, 0);
- clrtobot();
- outs("±z¥¿¦b¨Ï¥Î" BBSNAME "ªº³s¸p¨t²Î\n");
- outs("¥»³s¸p¨t²Î±N¸ß°Ý±z¤@¨Ç°ÝÃD¡A½Ð¤p¤ß¦^µª¤~¯à¶}©l³s¸p\n");
- outs("¥ô·N´£¥X³s¸p®×ªÌ¡A±N³Q¦C¤J¤£¨üÅwªï¨Ï¥ÎªÌ³á\n");
- move(4, 0);
- clrtobot();
- outs("(1)¬¡°Ê³s¸p (2)°O¦W¤½§ë ");
- if(type==0)
- outs("(3)¥Ó½Ð·sªO (4)¼o°£ÂªO (5)³s¸pªO¥D \n(6)½}§KªO¥D (7)³s¸p¤p²Õªø (8)½}§K¤p²Õªø (9)¥Ó½Ð·s¸s²Õ\n");
-
- do {
- getdata(6, 0, "½Ð¿é¤J³s¸pÃþ§O [0:¨ú®ø]¡G", topic, 3, DOECHO);
- temp = atoi(topic);
- } while (temp < 0 || temp > 9 || (type && temp>2));
- switch (temp) {
- case 0:
- return FULLUPDATE;
- case 1:
- if (!getdata(7, 0, "½Ð¿é¤J¬¡°Ê¥DÃD¡G", topic, 30, DOECHO))
- return FULLUPDATE;
- snprintf(title, sizeof(title), "%s %s", "[¬¡°Ê³s¸p]", topic);
- snprintf(genbuf, sizeof(genbuf),
- "%s\n\n%s%s\n", "¬¡°Ê³s¸p", "¬¡°Ê¥DÃD: ", topic);
- strcat(genbuf, "\n¬¡°Ê¤º®e: \n");
- break;
- case 2:
- if (!getdata(7, 0, "½Ð¿é¤J¤½§ë¥DÃD¡G", topic, 30, DOECHO))
- return FULLUPDATE;
- snprintf(title, sizeof(title), "%s %s", "[°O¦W¤½§ë]", topic);
- snprintf(genbuf, sizeof(genbuf),
- "%s\n\n%s%s\n", "°O¦W¤½§ë", "¤½§ë¥DÃD: ", topic);
- strcat(genbuf, "\n¤½§ë­ì¦]: \n");
- break;
- case 3:
- do {
- if (!getdata(7, 0, "½Ð¿é¤J¬ÝªO­^¤å¦WºÙ¡G", topic, IDLEN + 1, DOECHO))
- return FULLUPDATE;
- else if (invalid_brdname(topic))
- outs("¤£¬O¥¿½Tªº¬ÝªO¦WºÙ");
- else if (getbnum(topic) > 0)
- outs("¥»¦WºÙ¤w¸g¦s¦b");
- else
- break;
- } while (temp > 0);
- snprintf(title, sizeof(title), "[¥Ó½Ð·sªO] %s", topic);
- snprintf(genbuf, sizeof(genbuf),
- "%s\n\n%s%s\n%s", "¥Ó½Ð·sªO", "­^¤å¦WºÙ: ", topic, "¤¤¤å¦WºÙ: ");
-
- if (!getdata(8, 0, "½Ð¿é¤J¬ÝªO¤¤¤å¦WºÙ¡G", topic, BTLEN + 1, DOECHO))
- return FULLUPDATE;
- strcat(genbuf, topic);
- strcat(genbuf, "\n¬ÝªOÃþ§O: ");
- if (!getdata(9, 0, "½Ð¿é¤J¬ÝªOÃþ§O¡G", topic, 20, DOECHO))
- return FULLUPDATE;
- strcat(genbuf, topic);
- strcat(genbuf, "\nªO¥D¦W³æ: ");
- getdata(10, 0, "½Ð¿é¤JªO¥D¦W³æ¡G", topic, IDLEN * 3 + 3, DOECHO);
- strcat(genbuf, topic);
- strcat(genbuf, "\n¥Ó½Ð­ì¦]: \n");
- break;
- case 4:
- move(1,0); clrtobot();
- generalnamecomplete("½Ð¿é¤J¬ÝªO­^¤å¦WºÙ¡G",
- topic, IDLEN+1,
- SHM->Bnumber,
- &completeboard_compar,
- &completeboard_permission,
- &completeboard_getname);
- snprintf(title, sizeof(title), "[¼o°£ÂªO] %s", topic);
- snprintf(genbuf, sizeof(genbuf),
- "%s\n\n%s%s\n", "¼o°£ÂªO", "­^¤å¦WºÙ: ", topic);
- strcat(genbuf, "\n¼o°£­ì¦]: \n");
- break;
- case 5:
- move(1,0); clrtobot();
- generalnamecomplete("½Ð¿é¤J¬ÝªO­^¤å¦WºÙ¡G",
- topic, IDLEN+1,
- SHM->Bnumber,
- &completeboard_compar,
- &completeboard_permission,
- &completeboard_getname);
- snprintf(title, sizeof(title), "[³s¸pªO¥D] %s", topic);
- snprintf(genbuf, sizeof(genbuf), "%s\n\n%s%s\n%s%s", "³s¸pªO¥D", "­^¤å¦WºÙ: ", topic, "¥Ó½Ð ID : ", cuser.userid);
- strcat(genbuf, "\n¥Ó½Ð¬F¨£: \n");
- break;
- case 6:
- move(1,0); clrtobot();
- generalnamecomplete("½Ð¿é¤J¬ÝªO­^¤å¦WºÙ¡G",
- topic, IDLEN+1,
- SHM->Bnumber,
- &completeboard_compar,
- &completeboard_permission,
- &completeboard_getname);
- snprintf(title, sizeof(title), "[½}§KªO¥D] %s", topic);
- snprintf(genbuf, sizeof(genbuf),
- "%s\n\n%s%s\n%s", "½}§KªO¥D", "­^¤å¦WºÙ: ",
- topic, "ªO¥D ID : ");
- temp=getbnum(topic);
- assert(0<=temp-1 && temp-1<MAX_BOARD);
- do {
- if (!getdata(7, 0, "½Ð¿é¤JªO¥DID¡G", topic, IDLEN + 1, DOECHO))
- return FULLUPDATE;
- }while (!userid_is_BM(topic, bcache[temp - 1].BM));
- strcat(genbuf, topic);
- strcat(genbuf, "\n½}§K­ì¦]: \n");
- break;
- case 7:
- if (!getdata(7, 0, "½Ð¿é¤J¤p²Õ¤¤­^¤å¦WºÙ¡G", topic, 30, DOECHO))
- return FULLUPDATE;
- snprintf(title, sizeof(title), "[³s¸p¤p²Õªø] %s", topic);
- snprintf(genbuf, sizeof(genbuf),
- "%s\n\n%s%s\n%s%s", "³s¸p¤p²Õªø", "¤p²Õ¦WºÙ: ",
- topic, "¥Ó½Ð ID : ", cuser.userid);
- strcat(genbuf, "\n¥Ó½Ð¬F¨£: \n");
- break;
- case 8:
- if (!getdata(7, 0, "½Ð¿é¤J¤p²Õ¤¤­^¤å¦WºÙ¡G", topic, 30, DOECHO))
- return FULLUPDATE;
- snprintf(title, sizeof(title), "[½}§K¤p²Õªø] %s", topic);
- snprintf(genbuf, sizeof(genbuf), "%s\n\n%s%s\n%s",
- "½}§K¤p²Õªø", "¤p²Õ¦WºÙ: ", topic, "¤p²Õªø ID : ");
- if (!getdata(8, 0, "½Ð¿é¤J¤p²ÕªøID¡G", topic, IDLEN + 1, DOECHO))
- return FULLUPDATE;
- strcat(genbuf, topic);
- strcat(genbuf, "\n½}§K­ì¦]: \n");
- break;
- case 9:
- if (!getdata(7, 0, "½Ð¿é¤J¸s²Õ¤¤­^¤å¦WºÙ¡G", topic, 30, DOECHO))
- return FULLUPDATE;
- snprintf(title, sizeof(title), "[¥Ó½Ð·s¸s²Õ] %s", topic);
- snprintf(genbuf, sizeof(genbuf), "%s\n\n%s%s\n%s%s",
- "¥Ó½Ð¸s²Õ", "¸s²Õ¦WºÙ: ", topic, "¥Ó½Ð ID : ", cuser.userid);
- strcat(genbuf, "\n¥Ó½Ð¬F¨£: \n");
- break;
- default:
- return FULLUPDATE;
- }
- outs("½Ð¿é¤J²¤¶©Î¬F¨£(¦Ü¦h¤­¦æ)¡A­n²M·¡¶ñ¼g");
- for (temp = 12; temp < 17; temp++) {
- if (!getdata(temp, 0, "¡G", topic, 60, DOECHO))
- break;
- strcat(genbuf, topic);
- strcat(genbuf, "\n");
- }
- if (temp == 11)
- return FULLUPDATE;
- strcat(genbuf, "³s¸pµ²§ô®É¶¡: ");
- now += 14 * 24 * 60 * 60;
- snprintf(topic, sizeof(topic), "(%d)", now);
- strcat(genbuf, topic);
- strcat(genbuf, ctime4(&now));
- strcat(genbuf, "\n");
- now -= 14 * 24 * 60 * 60;
- strcat(genbuf, "----------¤ä«ù----------\n");
- strcat(genbuf, "----------¤Ï¹ï----------\n");
- outs("¶}©l³s¸p¹Æ");
- setbpath(fpath, currboard);
- stampfile(fpath, &votefile);
-
- if (!(fp = fopen(fpath, "w"))) {
- outs("¶}ÀÉ¥¢±Ñ¡A½Ðµy­Ô­«¨Ó¤@¦¸");
- return FULLUPDATE;
- }
- fprintf(fp, "%s%s %s%s\n%s%s\n%s%s\n", "§@ªÌ: ", cuser.userid,
- "¬ÝªO: ", currboard,
- "¼ÐÃD: ", title,
- "®É¶¡: ", ctime4(&now));
- fprintf(fp, "%s\n", genbuf);
- fclose(fp);
- strlcpy(votefile.owner, cuser.userid, sizeof(votefile.owner));
- strlcpy(votefile.title, title, sizeof(votefile.title));
- votefile.filemode |= FILE_VOTE;
- /* use lower 16 bits of 'money' to store limits */
- /* lower 8 bits are posts, higher 8 bits are logins */
- votefile.multi.vote_limits.regtime = bcache[currbid - 1].vote_limit_regtime;
- votefile.multi.vote_limits.logins = bcache[currbid - 1].vote_limit_logins;
- votefile.multi.vote_limits.posts = bcache[currbid - 1].vote_limit_posts;
- votefile.multi.vote_limits.badpost = bcache[currbid - 1].vote_limit_badpost;
- setbdir(genbuf, currboard);
- if (append_record(genbuf, &votefile, sizeof(votefile)) != -1)
- setbtotal(currbid);
- do_voteboardreply(&votefile);
- return FULLUPDATE;
-}
diff --git a/mbbsd/xyz.c b/mbbsd/xyz.c
deleted file mode 100644
index fd7d5f4e..00000000
--- a/mbbsd/xyz.c
+++ /dev/null
@@ -1,338 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-int
-x_boardman(void)
-{
- more("etc/topboardman", YEA);
- return 0;
-}
-
-int
-x_user100(void)
-{
- more("etc/topusr100", YEA);
- return 0;
-}
-
-int
-x_history(void)
-{
- more("etc/history", YEA);
- return 0;
-}
-
-#ifdef HAVE_X_BOARDS
-static int
-x_boards(void)
-{
- more("etc/topboard.tmp", YEA);
- return 0;
-}
-#endif
-
-int
-x_birth(void)
-{
- more("etc/birth.today", YEA);
- return 0;
-}
-
-int
-x_weather(void)
-{
- more("etc/weather.tmp", YEA);
- return 0;
-}
-
-int
-x_mrtmap(void)
-{
- more("etc/MRT.map", YEA);
- return 0;
-}
-
-int
-x_stock(void)
-{
- more("etc/stock.tmp", YEA);
- return 0;
-}
-
-int
-x_note(void)
-{
- more(fn_note_ans, YEA);
- return 0;
-}
-
-int
-x_issue(void)
-{
- more("etc/day", YEA);
- return 0;
-}
-
-int
-x_week(void)
-{
- more("etc/week", YEA);
- return 0;
-}
-
-int
-x_today(void)
-{
- more("etc/today", YEA);
- return 0;
-}
-
-int
-x_yesterday(void)
-{
- more("etc/yesterday", YEA);
- return 0;
-}
-
-int
-x_login(void)
-{
- more("etc/Welcome_login.0", YEA);
- return 0;
-}
-
-#ifdef HAVE_INFO
-static int
-x_program(void)
-{
- more("etc/version", YEA);
- return 0;
-}
-#endif
-
-#ifdef HAVE_LICENSE
-static int
-x_gpl(void)
-{
- more("etc/GPL", YEA);
- return 0;
-}
-#endif
-
-int
-note(void)
-{
- char *fn_note_tmp = "note.tmp";
- char *fn_note_dat = "note.dat";
- int total = 0, i, collect, len;
- struct stat st;
- char buf[256], buf2[80];
- int fd, fx;
- FILE *fp, *foo;
-
- typedef struct notedata_t {
- time4_t date;
- char userid[IDLEN + 1];
- char nickname[19];
- char buf[3][80];
- } notedata_t;
- notedata_t myitem;
-
- if (cuser.money < 5) {
- vmsg(ANSI_COLOR(1;41) " «u§r! ­n§ë¤­»È¤~¯à¯d¨¥...¨S¿ú­C.." ANSI_RESET);
- return 0;
- }
- setutmpmode(EDNOTE);
- do {
- myitem.buf[0][0] = myitem.buf[1][0] = myitem.buf[2][0] = '\0';
- move(12, 0);
- clrtobot();
- outs("\n§ë¤­»È... ¹Í... ½Ð¯d¨¥ (¦Ü¦h¤T¦æ)¡A«ö[Enter]µ²§ô");
- for (i = 0; (i < 3) && getdata(16 + i, 0, "¡G", myitem.buf[i],
- sizeof(myitem.buf[i]) - 5, DOECHO)
- && *myitem.buf[i]; i++);
- getdata(b_lines - 1, 0, "(S)Àx¦s (E)­«·s¨Ó¹L (Q)¨ú®ø¡H[S] ",
- buf, 3, LCECHO);
-
- if (buf[0] == 'q' || (i == 0 && *buf != 'e'))
- return 0;
- } while (buf[0] == 'e');
- demoney(-5);
- strcpy(myitem.userid, cuser.userid);
- strlcpy(myitem.nickname, cuser.nickname, sizeof(myitem.nickname));
- myitem.date = now;
-
- /* begin load file */
- if ((foo = fopen(".note", "a")) == NULL)
- return 0;
-
- unlink(fn_note_ans); // remove first to prevent mmap(pmore) crash
- if ((fp = fopen(fn_note_ans, "w")) == NULL) {
- fclose(fp);
- return 0;
- }
-
- if ((fx = open(fn_note_tmp, O_WRONLY | O_CREAT, 0644)) <= 0) {
- fclose(foo);
- fclose(fp);
- return 0;
- }
-
- if ((fd = open(fn_note_dat, O_RDONLY)) == -1)
- total = 1;
- else if (fstat(fd, &st) != -1) {
- total = st.st_size / sizeof(notedata_t) + 1;
- if (total > MAX_NOTE)
- total = MAX_NOTE;
- }
- fputs(ANSI_COLOR(1;31;44) "¡ó¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢t"
- ANSI_COLOR(37) "»Ä²¢­W»¶ªO" ANSI_COLOR(31) "¢u¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¡ó"
- ANSI_RESET "\n", fp);
- collect = 1;
-
- while (total) {
- snprintf(buf, sizeof(buf), ANSI_COLOR(1;31) "ùÝ¢t" ANSI_COLOR(32) " %s " ANSI_COLOR(37) "(%s)",
- myitem.userid, myitem.nickname);
- len = strlen(buf);
-
- for (i = len; i < 71; i++)
- strcat(buf, " ");
- snprintf(buf2, sizeof(buf2), " " ANSI_COLOR(1;36) "%.16s" ANSI_COLOR(31) " ¢uùß" ANSI_RESET "\n",
- Cdate(&(myitem.date)));
- strcat(buf, buf2);
- fputs(buf, fp);
- if (collect)
- fputs(buf, foo);
- for (i = 0; i < 3 && *myitem.buf[i]; i++) {
- fprintf(fp, ANSI_COLOR(1;31) "¢x" ANSI_RESET "%-74.74s" ANSI_COLOR(1;31) "¢x" ANSI_RESET "\n",
- myitem.buf[i]);
- if (collect)
- fprintf(foo, ANSI_COLOR(1;31) "¢x" ANSI_RESET "%-74.74s" ANSI_COLOR(1;31) "¢x" ANSI_RESET "\n",
- myitem.buf[i]);
- }
- fputs(ANSI_COLOR(1;31) "ùã¢s¢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¢sùå" ANSI_RESET "\n", fp);
-
- if (collect) {
- fputs(ANSI_COLOR(1;31) "ùã¢s¢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¢sùå" ANSI_RESET "\n", foo);
- fclose(foo);
- collect = 0;
- }
- write(fx, &myitem, sizeof(myitem));
-
- if (--total)
- read(fd, (char *)&myitem, sizeof(myitem));
- }
- fputs(ANSI_COLOR(1;31;44) "¡ó¢r¢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¢r¡ó" ANSI_RESET "\n", fp);
- fclose(fp);
- close(fd);
- close(fx);
- Rename(fn_note_tmp, fn_note_dat);
- more(fn_note_ans, YEA);
- return 0;
-}
-
-static void
-mail_sysop(void)
-{
- FILE *fp;
- char genbuf[200];
-
- if ((fp = fopen("etc/sysop", "r"))) {
- int i, j;
- char *ptr;
-
- typedef struct sysoplist_t {
- char userid[IDLEN + 1];
- char duty[40];
- } sysoplist_t;
- sysoplist_t sysoplist[9];
-
- j = 0;
- while (fgets(genbuf, 128, fp)) {
- if ((ptr = strchr(genbuf, '\n'))) {
- *ptr = '\0';
- if ((ptr = strchr(genbuf, ':'))) {
- *ptr = '\0';
- do {
- i = *++ptr;
- } while (i == ' ' || i == '\t');
- if (i) {
- strcpy(sysoplist[j].userid, genbuf);
- strcpy(sysoplist[j++].duty, ptr);
- }
- }
- }
- }
- fclose(fp);
-
- move(12, 0);
- clrtobot();
- outs(" ½s¸¹ ¯¸ªø ID Åv³d¹º¤À\n\n");
-
- for (i = 0; i < j; i++)
- prints("%15d. " ANSI_COLOR(1;%d) "%-16s%s" ANSI_COLOR(0) "\n",
- i + 1, 31 + i % 7, sysoplist[i].userid, sysoplist[i].duty);
- prints("%-14s0. " ANSI_COLOR(1;%d) "Â÷¶}" ANSI_COLOR(0) "", "", 31 + j % 7);
- getdata(b_lines - 1, 0, " ½Ð¿é¤J¥N½X[0]¡G",
- genbuf, 4, DOECHO);
- i = genbuf[0] - '0' - 1;
- if (i >= 0 && i < j) {
- char *suser = sysoplist[i].userid;
- clear();
- showplans(suser);
- do_send(suser, NULL);
- }
- }
-}
-
-int
-m_sysop(void)
-{
- setutmpmode(MSYSOP);
- mail_sysop();
- return 0;
-}
-
-int
-Goodbye(void)
-{
- char genbuf[100];
-
- getdata(b_lines - 1, 0, "±z½T©w­nÂ÷¶}¡i " BBSNAME " ¡j¶Ü(Y/N)¡H[N] ",
- genbuf, 3, LCECHO);
-
- if (*genbuf != 'y')
- return 0;
-
- movie(999999);
- if (cuser.userlevel) {
- getdata(b_lines - 1, 0,
- "(G)ÀH­·¦Ó³u (M)¦«¹Ú¯¸ªø (N)»Ä²¢­W»¶¬y¨¥ªO¡H[G] ",
- genbuf, 3, LCECHO);
- if (genbuf[0] == 'm')
- mail_sysop();
- else if (genbuf[0] == 'n')
- note();
- }
- clear();
-
-
- more("etc/Logout", NA);
-
- {
- int diff = (now - login_start_time) / 60;
- sprintf(genbuf, "¦¹¦¸°±¯d®É¶¡: %d ¤p®É %2d ¤À",
- diff / 60, diff % 60);
- }
- if(!(cuser.userlevel & PERM_LOGINOK))
- vmsg("©|¥¼§¹¦¨µù¥U¡C¦p­n´£ª@Åv­­½Ð°Ñ¦Ò¥»¯¸¤½§GÄæ¿ì²zµù¥U");
- else
- vmsg(genbuf);
- // pressanykey();
-
- u_exit("EXIT ");
- return QUIT;
-}