diff options
author | in2 <in2@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2002-03-07 23:13:44 +0800 |
---|---|---|
committer | in2 <in2@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2002-03-07 23:13:44 +0800 |
commit | ae31e19f92e717919ac8e3db9039eb38d2b89aae (patch) | |
tree | c70164d6a1852344f44b04a653ae2815043512af /mbbsd | |
download | pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.gz pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.bz2 pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.lz pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.xz pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.zst pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.zip |
Initial revision
git-svn-id: http://opensvn.csie.org/pttbbs/pttbbs/trunk/pttbbs@1 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
Diffstat (limited to 'mbbsd')
-rw-r--r-- | mbbsd/.cvsignore | 2 | ||||
-rw-r--r-- | mbbsd/Makefile | 45 | ||||
-rw-r--r-- | mbbsd/admin.c | 1105 | ||||
-rw-r--r-- | mbbsd/announce.c | 1590 | ||||
-rw-r--r-- | mbbsd/args.c | 62 | ||||
-rw-r--r-- | mbbsd/bbcall.c | 268 | ||||
-rw-r--r-- | mbbsd/bbs.c | 1904 | ||||
-rw-r--r-- | mbbsd/board.c | 1098 | ||||
-rw-r--r-- | mbbsd/cache.c | 1053 | ||||
-rw-r--r-- | mbbsd/cal.c | 512 | ||||
-rw-r--r-- | mbbsd/calendar.c | 284 | ||||
-rw-r--r-- | mbbsd/card.c | 625 | ||||
-rw-r--r-- | mbbsd/chat.c | 623 | ||||
-rw-r--r-- | mbbsd/chc_draw.c | 187 | ||||
-rw-r--r-- | mbbsd/chc_net.c | 28 | ||||
-rw-r--r-- | mbbsd/chc_play.c | 277 | ||||
-rw-r--r-- | mbbsd/chc_rule.c | 186 | ||||
-rw-r--r-- | mbbsd/chicken.c | 989 | ||||
-rw-r--r-- | mbbsd/dark.c | 456 | ||||
-rw-r--r-- | mbbsd/descrypt.c | 616 | ||||
-rw-r--r-- | mbbsd/dice.c | 447 | ||||
-rw-r--r-- | mbbsd/edit.c | 2256 | ||||
-rw-r--r-- | mbbsd/friend.c | 509 | ||||
-rw-r--r-- | mbbsd/gamble.c | 361 | ||||
-rw-r--r-- | mbbsd/gomo.c | 417 | ||||
-rw-r--r-- | mbbsd/gomo1.c | 136 | ||||
-rw-r--r-- | mbbsd/guess.c | 364 | ||||
-rw-r--r-- | mbbsd/indict.c | 184 | ||||
-rw-r--r-- | mbbsd/io.c | 611 | ||||
-rw-r--r-- | mbbsd/kaede.c | 95 | ||||
-rw-r--r-- | mbbsd/lovepaper.c | 120 | ||||
-rw-r--r-- | mbbsd/mail.c | 1675 | ||||
-rw-r--r-- | mbbsd/mbbsd.c | 1465 | ||||
-rw-r--r-- | mbbsd/menu.c | 596 | ||||
-rw-r--r-- | mbbsd/more.c | 931 | ||||
-rw-r--r-- | mbbsd/name.c | 473 | ||||
-rw-r--r-- | mbbsd/osdep.c | 79 | ||||
-rw-r--r-- | mbbsd/othello.c | 541 | ||||
-rw-r--r-- | mbbsd/page.c | 130 | ||||
-rw-r--r-- | mbbsd/passwd.c | 138 | ||||
-rw-r--r-- | mbbsd/read.c | 998 | ||||
-rw-r--r-- | mbbsd/record.c | 536 | ||||
-rw-r--r-- | mbbsd/register.c | 339 | ||||
-rw-r--r-- | mbbsd/screen.c | 559 | ||||
-rw-r--r-- | mbbsd/stuff.c | 524 | ||||
-rw-r--r-- | mbbsd/syspost.c | 102 | ||||
-rw-r--r-- | mbbsd/talk.c | 2663 | ||||
-rw-r--r-- | mbbsd/term.c | 144 | ||||
-rw-r--r-- | mbbsd/toolkit.c | 14 | ||||
-rw-r--r-- | mbbsd/topsong.c | 79 | ||||
-rw-r--r-- | mbbsd/uptime | 23 | ||||
-rw-r--r-- | mbbsd/user.c | 980 | ||||
-rw-r--r-- | mbbsd/var.c | 268 | ||||
-rw-r--r-- | mbbsd/vice.c | 151 | ||||
-rw-r--r-- | mbbsd/vote.c | 1068 | ||||
-rw-r--r-- | mbbsd/voteboard.c | 447 | ||||
-rw-r--r-- | mbbsd/xyz.c | 448 |
57 files changed, 32781 insertions, 0 deletions
diff --git a/mbbsd/.cvsignore b/mbbsd/.cvsignore new file mode 100644 index 00000000..35f9f2d1 --- /dev/null +++ b/mbbsd/.cvsignore @@ -0,0 +1,2 @@ +*.o +mbbsd diff --git a/mbbsd/Makefile b/mbbsd/Makefile new file mode 100644 index 00000000..886944f3 --- /dev/null +++ b/mbbsd/Makefile @@ -0,0 +1,45 @@ +# $Id: Makefile,v 1.1 2002/03/07 15:13:48 in2 Exp $ + +BBSHOME?=$(HOME) +OSTYPE=FreeBSD + +# FreeBSD +CFLAGS_FreeBSD= -pipe -Wall -g -O3 -DHAVE_SETPROCTITLE -DBBSHOME='"$(BBSHOME)"' -DFreeBSD -I../include +LDFLAGS_FreeBSD=-pipe -Wall -g -O3 +LIBS_FreeBSD= -lutil -lkvm + +# Linux +CFLAGS_linux= -pipe -Wall -g -O3 -DHAVE_DES_CRYPT -DBBSHOME='"$(BBSHOME)"' -DLinux -I../include -s +LDFLAGS_linux= -pipe -Wall -g -O3 +LIBS_linux= -lcrypt + +CFLAGS= $(CFLAGS_$(OSTYPE)) +LDFLAGS=$(LDFLAGS_$(OSTYPE)) +LIBS= $(LIBS_$(OSTYPE)) + +CC= gcc +PROG= mbbsd +OBJS= admin.o announce.o args.o bbcall.o bbs.o board.o cache.o cal.o card.o\ + chat.o chc_draw.o chc_net.o chc_play.o chc_rule.o chicken.o dark.o\ + dice.o edit.o friend.o gamble.o gomo.o gomo1.o guess.o indict.o io.o\ + kaede.o lovepaper.o mail.o mbbsd.o menu.o more.o name.o osdep.o\ + othello.o page.o read.o record.o register.o screen.o stuff.o\ + talk.o term.o topsong.o user.o vice.o vote.o xyz.o\ + voteboard.o syspost.o var.o descrypt.o toolkit.o passwd.o\ + calendar.o + +.SUFFIXES: .c .o +.c.o: + $(CC) $(CFLAGS) -c $*.c + +all: $(PROG) + +$(PROG): $(OBJS) + $(CC) $(LDFLAGS) -o $(PROG) $(OBJS) $(LIBS) + +install: $(PROG) + install -d $(BBSHOME)/bin/ + install -c -m 755 $(PROG) $(BBSHOME)/bin/ + +clean: + rm -f $(OBJS) $(PROG) diff --git a/mbbsd/admin.c b/mbbsd/admin.c new file mode 100644 index 00000000..14bc9721 --- /dev/null +++ b/mbbsd/admin.c @@ -0,0 +1,1105 @@ +/* $Id: admin.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <ctype.h> +#include <time.h> +#include <sys/types.h> +#include <sys/stat.h> +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "perm.h" +#include "modes.h" +#include "proto.h" + +extern char *msg_uid; +extern userec_t xuser; +extern char *err_uid; +extern boardheader_t *bcache; + +/* ¨Ï¥ÎªÌºÞ²z */ +int m_user() { + userec_t muser; + int id; + char genbuf[200]; + + stand_title("¨Ï¥ÎªÌ³]©w"); + usercomplete(msg_uid, genbuf); + if(*genbuf) { + move(2, 0); + if((id = getuser(genbuf))) { + memcpy(&muser, &xuser, sizeof(muser)); + user_display(&muser, 1); + uinfo_query(&muser, 1, id); + } else { + outs(err_uid); + clrtoeol(); + pressanykey(); + } + } + return 0; +} + +extern int b_lines; + +static int search_key_user(char *passwdfile, int mode) { + userec_t user; + int ch; + int coun = 0; + FILE *fp1 = fopen(passwdfile, "r"); + char buf[128], key[22], genbuf[8]; + + clear(); + getdata(0, 0, mode ? "½Ð¿é¤J¨Ï¥ÎªÌÃöÁä¦r[¹q¸Ü|¦a§}|©m¦W|¤W¯¸¦aÂI|" + "email|¤pÂûid] :" : "½Ð¿é¤Jid :", key, 21, DOECHO); + while((fread(&user, sizeof(user), 1, fp1)) > 0 && coun < MAX_USERS) { + if(!(++coun & 15)) { + move(1, 0); + sprintf(buf, "²Ä [%d] µ§¸ê®Æ\n", coun); + outs(buf); + refresh(); + } + if(!strcasecmp(user.userid, key) || + (mode && ( + strstr(user.realname, key) || strstr(user.username, key) || + strstr(user.lasthost, key) || strstr(user.email, key) || + strstr(user.address, key) || strstr(user.justify, key) || + strstr(user.mychicken.name, key)))) { + move(1, 0); + sprintf(buf, "²Ä [%d] µ§¸ê®Æ\n", coun); + outs(buf); + refresh(); + + user_display(&user, 1); + uinfo_query(&user, 1, coun); + outs("\033[44m ªÅ¥ÕÁä\033[37m:·j´M¤U¤@Ó" + " \033[33m Q\033[37m: Â÷¶}"); + outs(mode ? " \033[m " : + " S: ¨ú¥Î³Æ¥÷¸ê®Æ \033[m "); + while(1) { + while((ch = igetch()) == 0); + if(ch == ' ') + break; + if(ch == 'q' || ch == 'Q') + return 0; + if(ch == 's' && !mode) { + if((ch = searchuser(user.userid))) { + setumoney(ch,user.money); + passwd_update(ch, &user); + return 0; + } else { + move(b_lines - 1, 0); + genbuf[0] = 'n'; + getdata(0, 0, + "¥Ø«eªº PASSWD ÀɨS¦³¦¹ ID¡A·s¼W¶Ü¡H[y/N]", + genbuf, 3, LCECHO); + if(genbuf[0] == 'n') { + outs("¥Ø«eªºPASSWDSÀɨS¦³¦¹id " + "½Ð¥ýnew¤@Ó³oÓidªº±b¸¹"); + } else { + int allocid = getnewuserid(); + + if(allocid > MAX_USERS || allocid <= 0) { + fprintf(stderr, "¥»¯¸¤H¤f¤w¹F¹¡©M¡I\n"); + exit(1); + } + + if(passwd_update(allocid, &user) == -1) { + fprintf(stderr, "«Èº¡¤F¡A¦A¨£¡I\n"); + exit(1); + } + setuserid(allocid, user.userid); + if(!searchuser(user.userid)) { + fprintf(stderr, "µLªk«Ø¥ß±b¸¹\n"); + exit(1); + } + return 0; + } + } + } + } + } + } + + fclose(fp1); + return 0; +} + +/* ¥H¥ô·N key ´M§ä¨Ï¥ÎªÌ */ +int search_user_bypwd() { + search_key_user(FN_PASSWD, 1); + return 0; +} + +/* ´M§ä³Æ¥÷ªº¨Ï¥ÎªÌ¸ê®Æ */ +int search_user_bybakpwd() { + char *choice[] = { + "PASSWDS.NEW1", "PASSWDS.NEW2", "PASSWDS.NEW3", + "PASSWDS.NEW4", "PASSWDS.NEW5", "PASSWDS.NEW6", + "PASSWDS.BAK" + }; + int ch; + + clear(); + move(1, 1); + outs("½Ð¿é¤J§An¥Î¨Ó´M§ä³Æ¥÷ªºÀÉ®× ©Î«ö 'q' Â÷¶}\n"); + outs(" [\033[1;31m1\033[m]¤@¤Ñ«e, [\033[1;31m2\033[m]¨â¤Ñ«e, " + "[\033[1;31m3\033[m]¤T¤Ñ«e\n"); + outs(" [\033[1;31m4\033[m]¥|¤Ñ«e, [\033[1;31m5\033[m]¤¤Ñ«e, " + "[\033[1;31m6\033[m]¤»¤Ñ«e\n"); + outs(" [7]³Æ¥÷ªº\n"); + do { + move(5, 1); + outs("¿ï¾Ü => "); + ch = igetch(); + if(ch == 'q' || ch == 'Q') + return 0; + } while (ch < '1' || ch > '8'); + ch -= '1'; + search_key_user(choice[ch], 0); + return 0; +} + +static void bperm_msg(boardheader_t *board) { + prints("\n³]©w [%s] ¬ÝªO¤§(%s)Åv¡G", board->brdname, + board->brdattr & BRD_POSTMASK ? "µoªí" : "¾\\Ū"); +} + +extern char* str_permboard[]; + +unsigned int setperms(unsigned int pbits, char *pstring[]) { + register int i; + char choice[4]; + + 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(getdata(b_lines - 1, 0, "½Ð«ö [A-5] ¤Á´«³]©w¡A«ö [Return] µ²§ô¡G", + choice, 3, LCECHO)) { + i = choice[0] - 'a'; + if(i < 0) + i = choice[0] - '0' + 26; + if(i >= NUMPERMS) + bell(); + else { + pbits ^= (1 << i); + move(i % 16 + 4, i <= 15 ? 24 : 64); + prints((pbits >> i) & 1 ? "£¾" : "¢æ"); + } + } + return pbits; +} + +/* ¦Û°Ê³]¥ßºëµØ°Ï */ +void setup_man(boardheader_t * board) { + char genbuf[200]; + + setapath(genbuf, board->brdname); + mkdir(genbuf, 0755); +} + +extern char *fn_board; +extern char *err_bid; +extern userec_t cuser; +extern char *msg_sure_ny; +extern char* str_permid[]; + +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) { + outs(err_bid); + pressanykey(); + return -1; + } + + 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); + sprintf(genbuf, "¬ÝªO (E)³]©w (V)¹Hªk/¸Ñ°£ %s (D)§R°£ [Q]¨ú®ø¡H", + HAS_PERM(PERM_SYSOP) ? + " (B)BVote (S)±Ï¦^¤å³¹" : ""); + getdata(10, 0, genbuf, ans, 3, LCECHO); + + switch(*ans) { + case 's': + if(HAS_PERM(PERM_SYSOP) ) { + char actionbuf[512]; + + sprintf(actionbuf, BBSHOME "/bin/buildir boards/%s &", + bh.brdname); + system(actionbuf); + } + break; + case 'b': + if(HAS_PERM(PERM_SYSOP)) { + char bvotebuf[10]; + + memcpy(&newbh, &bh, sizeof(bh)); + sprintf(bvotebuf, "%d", newbh.bvote); + move(20, 0); + prints("¬Ýª© %s ì¨Óªº BVote¡G%d", bh.brdname, bh.bvote); + getdata_str(21, 0, "·sªº Bvote¡G", genbuf, 5, LCECHO, bvotebuf); + newbh.bvote = atoi(genbuf); + 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("¬Ýª©¥Ø«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; + substitute_record(fn_board, &newbh, sizeof(newbh), bid); + reset_board(bid); + log_usies("ViolateLawSet", newbh.brdname); + } + break; + case 'd': + getdata_str(9, 0, msg_sure_ny, genbuf, 3, LCECHO, "N"); + if(genbuf[0] != 'y' || !bname[0]) + outs(MSG_DEL_CANCEL); + else { + strcpy(bname, bh.brdname); + sprintf(genbuf, + "/bin/tar zcvf tmp/board_%s.tgz boards/%s man/%s >/dev/null 2>&1;" + "/bin/rm -fr boards/%s man/%s", + bname, bname, bname, bname, bname); + system(genbuf); + memset(&bh, 0, sizeof(bh)); + sprintf(bh.title, "%s ¬ÝªO %s §R°£", bname, cuser.userid); + post_msg("Security", bh.title,"½Ðª`·N§R°£ªº¦Xªk©Ê","[¨t²Î¦w¥þ§½]"); + substitute_record(fn_board, &bh, sizeof(bh), bid); + reset_board(bid); + log_usies("DelBoard", bh.title); + outs("§RªO§¹²¦"); + } + break; + case 'e': + 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)) { + strcpy(newbh.brdname, genbuf); + break; + } + } + + do { + getdata_str(12, 0, "¬ÝªOÃþ§O¡G", genbuf, 5, DOECHO, bh.title); + if(strlen(genbuf) == 4) + break; + } while (1); + + if(strlen(genbuf) >= 4) + strncpy(newbh.title, genbuf, 4); + + newbh.title[4] = ' '; + + getdata_str(14, 0, "¬ÝªO¥DÃD¡G", genbuf, BTLEN + 1, DOECHO, + bh.title + 7); + if(genbuf[0]) + strcpy(newbh.title + 7, genbuf); + if(getdata_str(15, 0, "·sªO¥D¦W³æ¡G", genbuf, IDLEN * 3 + 3, DOECHO, + bh.BM)) { + trim(genbuf); + strcpy(newbh.BM, genbuf); + } + + if(HAS_PERM(PERM_SYSOP)) { + move(1, 0); + clrtobot(); + newbh.brdattr = setperms(newbh.brdattr, str_permboard); + move(1, 0); + clrtobot(); + } + + if(newbh.brdattr & BRD_GROUPBOARD) + strncpy(newbh.title + 5, "£U", 2); + else if(newbh.brdattr & BRD_NOTRAN) + strncpy(newbh.title + 5, "¡·", 2); + else + strncpy(newbh.title + 5, "¡´", 2); + + if(HAS_PERM(PERM_SYSOP) && !(newbh.brdattr & BRD_HIDE)) { + getdata_str(14, 0, "³]©wŪ¼gÅv(Y/N)¡H", ans, 4, LCECHO, "N"); + if(*ans == 'y') { + getdata_str(15, 0, "¨î [R]¾\\Ū (P)µoªí¡H", ans, 4, 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_str(b_lines - 1, 0, msg_sure_ny, genbuf, 4, LCECHO, "Y"); + + if((*genbuf == 'y') && memcmp(&newbh, &bh, sizeof(bh))) { + 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); + substitute_record(fn_board, &newbh, sizeof(newbh), bid); + reset_board(bid); + log_usies("SetBoard", newbh.brdname); + } + } + return 0; +} + +extern char *msg_bid; + +/* ³]©w¬Ýª© */ +int m_board() { + char bname[32]; + + stand_title("¬ÝªO³]©w"); + make_blist(); + namecomplete(msg_bid, bname); + if(!*bname) + return 0; + m_mod_board(bname); + return 0; +} + +/* ³]©w¨t²ÎÀÉ®× */ +int x_file() { + int aborted; + char ans[4], *fpath; + + move(b_lines - 4, 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"); + getdata(b_lines - 1, 0, " (H)¬ÝªO´Á (I)¬G¶m (J)¥X¯¸µe± (K)¥Í¤é¥d (L)¸`¤é [Q]¨ú®ø¡H", ans, 3, 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 'a': + fpath = "etc/teashop"; + 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, 3, 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, 3, LCECHO); + if( ans[0] == '1' ) { unlink("etc/Welcome_login.1"); outs("ok"); } + else if( ans[0] == '2' ){ unlink("etc/Welcome_login.2"); outs("ok"); } + else if( ans[0] == '3' ){ unlink("etc/Welcome_login.3"); outs("ok"); } + else if( ans[0] == '4' ){ unlink("etc/Welcome_login.4"); outs("ok"); } + else {outs("©Ò«ü©wªº¶i¯¸µe±µLªk§R°£"); } + pressanykey(); + return FULLUPDATE; + +#endif + + case 'h': + fpath = "etc/expire.conf"; + break; + case 'i': + fpath = "etc/domain_name_query"; + break; + case 'j': + fpath = "etc/Logout"; + break; + case 'k': + fpath = "etc/Welcome_birth"; + break; + case 'l': + fpath = "etc/feast"; + break; + default: + return FULLUPDATE; + } + aborted = vedit(fpath, NA, NULL); + prints("\n\n¨t²ÎÀÉ®×[%s]¡G%s", fpath, + (aborted == -1) ? "¥¼§ïÅÜ" : "§ó·s§¹²¦"); + pressanykey(); + return FULLUPDATE; +} + +extern int numboards; +extern int class_bid; + +int m_newbrd(int recover) { + boardheader_t newboard; + char ans[4]; + int bid; + char genbuf[200]; + + stand_title("«Ø¥ß·sªO"); + memset(&newboard, 0, sizeof(newboard)); + + newboard.gid = class_bid; + if (newboard.gid == 0) { + move(6, 0); + outs("½Ð¥ý¿ï¾Ü¤@ÓÃþ§O¦A¶}ªO!"); + pressanykey(); + return -1; + } + + do { + if(!getdata(3, 0, msg_bid, newboard.brdname, IDLEN + 1, 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); + + if(strlen(genbuf) >= 4) + strncpy(newboard.title, genbuf, 4); + + newboard.title[4] = ' '; + + getdata(8, 0, "¬ÝªO¥DÃD¡G", genbuf, BTLEN + 1, DOECHO); + if(genbuf[0]) + strcpy(newboard.title + 7, genbuf); + setbpath(genbuf, newboard.brdname); + + if(recover) { + struct stat sb; + + if(stat(genbuf, &sb) == -1 || !(sb.st_mode & S_IFDIR)) { + outs("¦¹¬ÝªO¤w¸g¦s¦b! ½Ð¨ú¤£¦P^¤åªO¦W"); + pressanykey(); + return -1; + } + } else if(getbnum(newboard.brdname) > 0 || mkdir(genbuf, 0755) == -1) { + outs("¦¹¬ÝªO¤w¸g¦s¦b! ½Ð¨ú¤£¦P^¤åªO¦W"); + pressanykey(); + return -1; + } + + newboard.brdattr = BRD_NOTRAN; + + if(HAS_PERM(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; + + if(newboard.brdattr & BRD_GROUPBOARD) + strncpy(newboard.title + 5, "£U", 2); + else if(newboard.brdattr & BRD_NOTRAN) + strncpy(newboard.title + 5, "¡·", 2); + else + strncpy(newboard.title + 5, "¡´", 2); + + newboard.level = 0; + getdata(11, 0, "ªO¥D¦W³æ¡G", newboard.BM, IDLEN * 3 + 3, DOECHO); + + if(HAS_PERM(PERM_SYSOP) && !(newboard.brdattr & BRD_HIDE)) { + getdata_str(14, 0, "³]©wŪ¼gÅv(Y/N)¡H", ans, 3, LCECHO, "N"); + if(*ans == 'y') { + getdata_str(15, 0, "¨î [R]¾\\Ū (P)µoªí¡H", ans, 4, 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(); + } + } + + if((bid = getbnum("")) > 0) + { + substitute_record(fn_board, &newboard, sizeof(newboard), bid); + reset_board(bid); + } + else if(append_record(fn_board, (fileheader_t *) & newboard, + sizeof(newboard)) == -1) { + pressanykey(); + return -1; + } + else + { + addbrd_touchcache(); + } + setup_man(&newboard); + + outs("\n·sªO¦¨¥ß"); + post_newboard(newboard.title, newboard.brdname, newboard.BM); + log_usies("NewBoard", newboard.title); + pressanykey(); + return 0; +} + +static int auto_scan(char fdata[][STRLEN], char ans[]) { + int good = 0; + int count = 0; + int i; + char temp[10]; + + if(!strncmp(fdata[2], "¤p", 2) || strstr(fdata[2], "¤X") + || strstr(fdata[2], "½Ö") || strstr(fdata[2], "¤£")) { + ans[0] = '0'; + return 1; + } + + strncpy(temp, fdata[2], 2); + temp[2] = '\0'; + + /* Å|¦r */ + if(!strncmp(temp, &(fdata[2][2]), 2)) { + ans[0] = '0'; + return 1; + } + + if(strlen(fdata[2]) >= 6) { + if(strstr(fdata[2], "³¯¤ô«ó")) { + 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[3], fdata[4]) || + !strcmp(fdata[3], fdata[5]) || + !strcmp(fdata[4], fdata[5])) { + ans[0] = '4'; + return 5; + } + + if(strstr(fdata[3], "¤j")) { + if (strstr(fdata[3], "¥x") || strstr(fdata[3], "²H") || + strstr(fdata[3], "¥æ") || strstr(fdata[3], "¬F") || + strstr(fdata[3], "²M") || strstr(fdata[3], "ĵ") || + strstr(fdata[3], "®v") || strstr(fdata[3], "»Ê¶Ç") || + strstr(fdata[3], "¤¤¥¡") || strstr(fdata[3], "¦¨") || + strstr(fdata[3], "»²") || strstr(fdata[3], "ªF§d")) + good++; + } else if(strstr(fdata[3], "¤k¤¤")) + good++; + + if(strstr(fdata[4], "¦a²y") || strstr(fdata[4], "¦t©z") || + strstr(fdata[4], "«H½c")) { + ans[0] = '2'; + return 3; + } + + if(strstr(fdata[4], "¥«") || strstr(fdata[4], "¿¤")) { + if(strstr(fdata[4], "¸ô") || strstr(fdata[4], "µó")) { + if(strstr(fdata[4], "¸¹")) + good++; + } + } + + for(i = 0; fdata[5][i]; i++) { + if(isdigit(fdata[5][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; +} + +/* ³B²z Register Form */ +int scan_register_form(char *regfile, int automode, int neednum) { + char genbuf[200]; + static char *logfile = "register.log"; + static char *field[] = { + "uid", "ident", "name", "career", "addr", "phone", "email", NULL + }; + static char *finfo[] = { + "±b¸¹", "¨¤ÀÃÒ¸¹", "¯u¹ê©m¦W", "ªA°È³æ¦ì", "¥Ø«e¦í§}", + "³sµ¸¹q¸Ü", "¹q¤l¶l¥ó«H½c", NULL + }; + static char *reason[] = { + "¿é¤J¯u¹ê©m¦W", "¸Ô¶ñ¾Ç®Õ¬ì¨t»P¦~¯Å", "¶ñ¼g§¹¾ãªº¦í§}¸ê®Æ", + "¸Ô¶ñ³sµ¸¹q¸Ü", "½T¹ê¶ñ¼gµù¥U¥Ó½Ðªí", "¥Î¤¤¤å¶ñ¼g¥Ó½Ð³æ", NULL + }; + static char *autoid = "AutoScan"; + userec_t muser; + FILE *fn, *fout, *freg; + char fdata[7][STRLEN]; + char fname[STRLEN], buf[STRLEN]; + char ans[4], *ptr, *uid; + int n, unum; + int nSelf = 0, nAuto = 0; + + uid = cuser.userid; + sprintf(fname, "%s.tmp", regfile); + move(2, 0); + if(dashf(fname)) { + if(neednum == 0) { /* ¦Û¤v¶i Admin ¨Ó¼fªº */ + outs("¨ä¥L SYSOP ¤]¦b¼f®Öµù¥U¥Ó½Ð³æ"); + pressanykey(); + } + return -1; + } + Rename(regfile, fname); + if((fn = fopen(fname, "r")) == NULL) { + prints("¨t²Î¿ù»~¡AµLªkŪ¨úµù¥U¸ê®ÆÀÉ: %s", fname); + pressanykey(); + return -1; + } + if(neednum) { /* ³Q±j¢¼fªº */ + move(1, 0); + clrtobot(); + prints("¦U¦ì¨ã¦³¯¸ªøÅvªº¤H¡Aµù¥U³æ²Ö¿n¶W¹L¤@¦Ê¥÷¤F¡A³Â·Ð±zÀ°¦£¼f %d ¥÷\n", neednum); + prints("¤]´N¬O¤j·§¤G¤Q¤À¤§¤@ªº¼Æ¶q¡A·íµM¡A±z¤]¥i¥H¦h¼f\n¨S¼f§¹¤§«e¡A¨t²Î¤£·|Åý§A¸õ¥X³é¡IÁÂÁÂ"); + pressanykey(); + } + memset(fdata, 0, sizeof(fdata)); + while(fgets(genbuf, STRLEN, fn)) { + if ((ptr = (char *) strstr(genbuf, ": "))) { + *ptr = '\0'; + for(n = 0; field[n]; n++) { + if(strcmp(genbuf, field[n]) == 0) { + strcpy(fdata[n], ptr + 2); + if((ptr = (char *) strchr(fdata[n], '\n'))) + *ptr = '\0'; + } + } + } else if ((unum = getuser(fdata[0])) == 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(); + neednum--; + } else { + neednum--; + memcpy(&muser, &xuser, sizeof(muser)); + if(automode) + uid = autoid; + + if(!automode || !auto_scan(fdata, ans)) { + uid = cuser.userid; + + move(1, 0); + prints("±b¸¹¦ì¸m ¡G%d\n", unum); + user_display(&muser, 1); + move(14, 0); + prints("\033[1;32m------------- ½Ð¯¸ªøÄY®æ¼f®Ö¨Ï¥ÎªÌ¸ê®Æ¡A±zÁÙ¦³ %d ¥÷---------------\033[m\n", neednum); + for(n = 0; field[n]; n++) { + if(n >= 2 && n <= 5) + prints("%d.", n - 2); + else + prints(" "); + prints("%-12s¡G%s\n", finfo[n], fdata[n]); + } + if(muser.userlevel & PERM_LOGINOK) { + getdata(b_lines - 1, 0, "\033[1;32m¦¹±b¸¹¤w¸g§¹¦¨µù¥U, " + "§ó·s(Y/N/Skip)¡H\033[m[N] ", ans, 3, LCECHO); + if(ans[0] != 'y' && ans[0] != 's') + ans[0] = 'd'; + } else { + getdata(b_lines - 1, 0, + "¬O§_±µ¨ü¦¹¸ê®Æ(Y/N/Q/Del/Skip)¡H[Y] ", + ans, 3, LCECHO); + } + nSelf++; + } else + nAuto++; + if(neednum > 0 && ans[0] == 'q') { + move(2, 0); + clrtobot(); + prints("¨S¼f§¹¤£¯à°h¥X"); + pressanykey(); + ans[0] = 's'; + } + + 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 'n': + if(ans[0] == 'n') { + for(n = 0; field[n]; n++) + prints("%s: %s\n", finfo[n], fdata[n]); + move(9, 0); + prints("½Ð´£¥X°h¦^¥Ó½Ðªíì¦]¡A«ö <enter> ¨ú®ø\n"); + for (n = 0; reason[n]; n++) + prints("%d) ½Ð%s\n", n, reason[n]); + } else + buf[0] = ans[0]; + if(ans[0] != 'n' || + getdata(10 + n, 0, "°h¦^ì¦]¡G", buf, 60, DOECHO)) + if((buf[0] - '0') >= 0 && (buf[0] - '0') < n) { + int i; + fileheader_t mhdr; + char title[128], buf1[80]; + FILE *fp; + + i = buf[0] - '0'; + strcpy(buf, reason[i]); + sprintf(genbuf, "[°h¦^ì¦]] ½Ð%s", buf); + + sethomepath(buf1, muser.userid); + stampfile(buf1, &mhdr); + strcpy(mhdr.owner, cuser.userid); + strncpy(mhdr.title, "[µù¥U¥¢±Ñ]", TTLEN); + mhdr.savemode = 0; + mhdr.filemode = 0; + sethomedir(title, muser.userid); + if(append_record(title, &mhdr, sizeof(mhdr)) != -1) { + fp = fopen(buf1, "w"); + fprintf(fp, "%s\n", genbuf); + fclose(fp); + } + if((fout = fopen(logfile, "a"))) { + for(n = 0; field[n]; n++) + fprintf(fout, "%s: %s\n", field[n], fdata[n]); + n = time(NULL); + fprintf(fout, "Date: %s\n", Cdate((time_t *) & n)); + fprintf(fout, "Rejected: %s [%s]\n----\n", + uid, buf); + fclose(fout); + } + break; + } + move(10, 0); + clrtobot(); + prints("¨ú®ø°h¦^¦¹µù¥U¥Ó½Ðªí"); + 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: + prints("¥H¤U¨Ï¥ÎªÌ¸ê®Æ¤w¸g§ó·s:\n"); + mail_muser(muser, "[µù¥U¦¨¥\\Åo]", "etc/registered"); + muser.userlevel |= (PERM_LOGINOK | PERM_POST); + strcpy(muser.realname, fdata[2]); + strcpy(muser.address, fdata[4]); + strcpy(muser.email, fdata[6]); + sprintf(genbuf, "%s:%s:%s", fdata[5], fdata[3], uid); + strncpy(muser.justify, genbuf, REGLEN); + sethomefile(buf, muser.userid, "justify"); + log_file(buf, genbuf); + passwd_update(unum, &muser); + + if((fout = fopen(logfile, "a"))) { + for(n = 0; field[n]; n++) + fprintf(fout, "%s: %s\n", field[n], fdata[n]); + n = time(NULL); + fprintf(fout, "Date: %s\n", Cdate((time_t *) & n)); + fprintf(fout, "Approved: %s\n", uid); + fprintf(fout, "----\n"); + fclose(fout); + } + break; + } + } + } + fclose(fn); + unlink(fname); + + move(0, 0); + clrtobot(); + + move(5, 0); + prints("±z¼f¤F %d ¥÷µù¥U³æ¡AAutoScan ¼f¤F %d ¥÷", nSelf, nAuto); + +/** DickG: ±N¼f¤F´X¥÷ªº¬ÛÃö¸ê®Æ post ¨ì Security ªO¤W ***********/ +/* DickG: ¦]À³·sªº¯¸ªø¤W¯¸»Ý¼f®Ö¤è®×¡A¬O¬G¨S¦³¥²n¯d¤U record ¦ÓÃö±¼ + strftime(buf, 200, "%Y/%m/%d/%H:%M", pt); + + strcpy(xboard, "Security"); + setbpath(xfpath, xboard); + stampfile(xfpath, &xfile); + strcpy(xfile.owner, "¨t²Î"); + strcpy(xfile.title, "[³ø§i] ¼f®Ö°O¿ý"); + xfile.savemode = 'S'; + xptr = fopen(xfpath, "w"); + fprintf(xptr, "\n®É¶¡¡G%s + %s ¼f¤F %d ¥÷µù¥U³æ\n + AutoScan ¼f¤F %d ¥÷µù¥U³æ\n + ¦@p %d ¥÷¡C", + buf, cuser.userid, nSelf, nAuto, nSelf+nAuto); + fclose(xptr); + setbdir(fname, xboard); + append_record(fname, &xfile, sizeof(xfile)); + outgo_post(&xfile, xboard); + touchbtotal(getbnum(xboard)); + cuser.numposts++; +*/ +/*********************************************/ + pressanykey(); + return (0); +} + +extern char* fn_register; +extern int t_lines; + +int m_register() { + 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)¡H[N] ", ans, 3, LCECHO); + if(ans[0] == 'a') + scan_register_form(fn_register, 1, 0); + else if(ans[0] == 'y') + scan_register_form(fn_register, 0, 0); + + return 0; +} + +int cat_register() { + if(system("cat register.new.tmp >> register.new") == 0 && + system("rm -f register.new.tmp") == 0) + mprints(22, 0, "OK ÂP~~ Ä~Äò¥h¾Ä°«§a!! "); + else + mprints(22, 0, "¨S¿ìªkCAT¹L¥h©O ¥hÀˬd¤@¤U¨t²Î§a!! "); + pressanykey(); + return 0; +} + +static void give_id_money(char *user_id, int money, FILE *log_fp, char *mail_title, time_t t) { + char tt[TTLEN + 1] = {0}; + + if(deumoney(searchuser(user_id), money) < 0) { + move(12, 0); + clrtoeol(); + prints("id:%s money:%d ¤£¹ï§a!!", user_id, money); + pressanykey(); + } else { + fprintf(log_fp, "%ld %s %d", t, user_id, money); + sprintf(tt, "%s : %d ptt ¹ô", mail_title, money); + mail_id(user_id, tt, "~bbs/etc/givemoney.why", "[PTT »È¦æ]"); + } +} + +int give_money() { + FILE *fp, *fp2; + char *ptr, *id, *mn; + char buf[200] = {0}, tt[TTLEN + 1] = {0}; + time_t t = time(NULL); + struct tm *pt = localtime(&t); + int to_all = 0, money = 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); + prints("¿é¤J¿ù»~!!"); + pressanykey(); + return 1; + } + } else { + if(vedit("etc/givemoney.txt", NA, NULL) < 0) + return 1; + } + + clear(); + getdata(0, 0, "nµo¿ú¤F¶Ü(Y/N)[N]", buf, 3, LCECHO); + if(buf[0] != 'y') + return 1; + + if(!(fp2 = fopen("etc/givemoney.log", "a"))) + return 1; + strftime(buf, 200, "%Y/%m/%d/%H:%M", pt); + fprintf(fp2, "%s\n", buf); + + getdata(1, 0, "¬õ¥]³U¼ÐÃD ¡G", tt, TTLEN, DOECHO); + move(2, 0); + + prints("½s¬õ¥]³U¤º®e"); + pressanykey(); + if(vedit("etc/givemoney.why", NA, NULL) < 0) + return 1; + + stand_title("µo¿ú¤¤..."); + if(to_all) { + extern struct uhash_t *uhash; + int i, unum; + for(unum = uhash->number, i=0; i<unum; i++) { + if(bad_user_id(uhash->userid[i])) + continue; + id = uhash->userid[i]; + give_id_money(id, money, fp2, tt, t); + } + } else { + if(!(fp = fopen("etc/givemoney.txt", "r+"))) { + fclose(fp2); + return 1; + } + while(fgets(buf, 255, fp)) { +// clear(); + if (!(ptr = strchr(buf, ':'))) + continue; + *ptr = '\0'; + id = buf; + mn = ptr + 1; + give_id_money(id, atoi(mn), fp2, tt, t); + } + fclose(fp); + } + + fclose(fp2); + pressanykey(); + return FULLUPDATE; +} diff --git a/mbbsd/announce.c b/mbbsd/announce.c new file mode 100644 index 00000000..960a45aa --- /dev/null +++ b/mbbsd/announce.c @@ -0,0 +1,1590 @@ +/* $Id: announce.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <syslog.h> +#include <netdb.h> +#include <unistd.h> +#include <setjmp.h> +#include <signal.h> +#include <time.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include "config.h" +#include "pttstruct.h" +#include "perm.h" +#include "common.h" +#include "modes.h" +#include "proto.h" + +extern int b_lines; +extern int p_lines; +extern int TagNum; +extern int currbid; +static void g_showmenu(gmenu_t *pm) { + static char *mytype = "½s ¿ï µ·¸ô¤§®È"; + char *title, ch; + int n, max; + item_t *item; + + showtitle("ºëµØ¤å³¹", pm->mtitle); + prints(" \033[1;36m½s¸¹ ¼Ð ÃD%56s\033[m", mytype); + + if(pm->num) { + n = pm->page; + max = n + p_lines; + if(max > pm->num) + max = pm->num; + while(n < max) { + item = pm->item[n++]; + title = item->title; + ch = title[1]; + prints("\n%5d. %-72.71s", n, title); + } + } else + outs("\n ¡mºëµØ°Ï¡n©|¦b§l¨ú¤Ñ¦a¶¡ªº¤éºë¤ëµØ :)"); + + move(b_lines, 1); + outs(pm->level ? + "\033[34;46m ¡iªO ¥D¡j \033[31;47m (h)\033[30m»¡©ú " + "\033[31m(q/¡ö)\033[30mÂ÷¶} \033[31m(n)\033[30m·s¼W¤å³¹ " + "\033[31m(g)\033[30m·s¼W¥Ø¿ý \033[31m(e)\033[30m½s¿èÀÉ®× \033[m" : + "\033[34;46m ¡i¥\\¯àÁä¡j \033[31;47m (h)\033[30m»¡©ú " + "\033[31m(q/¡ö)\033[30mÂ÷¶} \033[31m(k¡ôj¡õ)\033[30m²¾°Ê´å¼Ð " + "\033[31m(enter/¡÷)\033[30mŪ¨ú¸ê®Æ \033[m"); +} + +static FILE *go_cmd(item_t *node, int *sock) { + struct sockaddr_in sin; + struct hostent *host; + char *site; + FILE *fp; + + *sock = socket(AF_INET, SOCK_STREAM, 0); + + if(*sock < 0) { + syslog(LOG_ERR, "socket(): %m"); + return NULL; + } + memset((char *)&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = htons(node->X.G.port); + + host = gethostbyname(site = node->X.G.server); + if(host == NULL) + sin.sin_addr.s_addr = inet_addr(site); + else + memcpy(&sin.sin_addr.s_addr, host->h_addr, host->h_length); + + if(connect(*sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) { + syslog(LOG_ERR, "connect(): %m"); + return NULL; + } + fp = fdopen(*sock, "r+"); + if(fp != NULL) { + setbuf(fp, (char *) 0); + fprintf(fp, "%s\r\n", node->X.G.path); + fflush(fp); + } else + close(*sock); + return fp; +} + +static char *nextfield(char *data, char *field) { + register int ch; + + while((ch = *data)) { + data++; + if((ch == '\t') || (ch == '\r' && *data == '\n')) + break; + *field++ = ch; + } + *field = '\0'; + return data; +} + +extern char *str_author1; + +static FILE* my_open(char* path) { + FILE* ans = 0; + char buf[80]; + struct stat st; + time_t now = time(0); + + if(stat(path, &st) == 0 && st.st_mtime < now - 3600 * 24 * 7) { + return fopen(path, "w"); + } + + if((ans = fopen(path, "r+"))) { + fclose(ans); + return 0; + /* + return directly due to currutmp->pager > 1 mode (real copy) + */ + fgets(buf, 80, ans); + if(!strncmp(buf, str_author1, strlen(str_author1)) || + *buf == '0' || *buf == '1') { + fclose(ans); + return 0; + } + + rewind(ans); + } else + ans = fopen(path, "w"); + return ans; +} + +static jmp_buf jbuf; + +static void isig(int sig) { + longjmp(jbuf, 1); +} + +#define PROXY_HOME "proxy/" +extern userec_t cuser; +extern userinfo_t *currutmp; + +static void go_proxy(char* fpath, item_t *node, int update) { + char *ptr, *str, *server; + int ch; + static FILE *fo; + + strcpy(fpath, PROXY_HOME); + ptr = fpath + sizeof(PROXY_HOME) - 1; + str = server = node->X.G.server; + while((ch = *str)) { + str++; + if(ch == '.') { + if(!strcmp(str, "edu.tw")) + break; + } else if(ch >= 'A' && ch <= 'Z') { + ch |= 0x20; + } + *ptr++ = ch; + } + *ptr = '\0'; + mkdir(fpath, 0755); + + *ptr++ = '/'; + str = node->X.G.path; + while((ch = *str)) { + str++; + if(ch == '/') { + ch = '.'; + } + *ptr++ = ch; + } + *ptr = '\0'; + + /* expire proxy data */ + + if((fo = update ? fopen(fpath, "w") : my_open(fpath))) { + FILE *fp; + char buf[512]; + int sock; + + if(fo == NULL) + return; + + outmsg("¡¹ «Ø¥ß proxy ¸ê®Æ³s½u¤¤ ... "); + refresh(); + + sock = -1; + if(setjmp(jbuf)) { + if(sock != -1) + close(sock); + fseek(fo, 0, SEEK_SET); + fwrite("", 0, 0, fo); + fclose(fo); + alarm(0); + return; + } + + signal(SIGALRM, isig); + alarm(5); + fp = go_cmd(node, &sock); + alarm(0); + + str = node->title; + ch = str[1]; + if(ch == (char) 0xbc && + !(HAS_PERM(PERM_SYSOP) && currutmp->pager > 1)) { + time_t now; + + time(&now); + fprintf(fo, "§@ªÌ: %s (³s½uºëµØ°Ï)\n¼ÐÃD: %s\n®É¶¡: %s\n", + server, str + 3, ctime(&now) + ); + } + + while(fgets(buf, 511, fp)) { + if(!strcmp(buf, ".\r\n")) + break; + if((ptr = strstr(buf, "\r\n"))) + strcpy(ptr, "\n"); + fputs(buf, fo); + } + fclose(fo); + fclose(fp); + } +} + +static void g_additem(gmenu_t *pm, item_t *myitem) { + if(pm->num < MAX_ITEMS) { + item_t *newitem = (item_t *)malloc(sizeof(item_t)); + + memcpy(newitem, myitem, sizeof(item_t)); + pm->item[(pm->num)++] = newitem; + } +} + +static void go_menu(gmenu_t *pm, item_t *node, int update) { + FILE *fp; + char buf[512], *ptr, *title; + item_t item; + int ch; + + go_proxy(buf, node, update); + pm->num = 0; + if((fp = fopen(buf, "r"))) { + title = item.title; + while(fgets(buf, 511, fp)) { + ptr = buf; + ch = *ptr++; + if(ch != '0' && ch != '1') + continue; + + strcpy(title, "¡¼ "); + if(ch == '1') + title[1] = (char) 0xbd; + + ptr = nextfield(ptr, title + 3); + if(!*ptr) + continue; + title[sizeof(item.title) - 1] = '\0'; + + ptr = nextfield(ptr, item.X.G.path); + if(!*ptr) + continue; + + ptr = nextfield(ptr, item.X.G.server); + if(!*ptr) + continue; + + nextfield(ptr, buf); + item.X.G.port = atoi(buf); + + g_additem(pm, &item); + } + fclose(fp); + } +} + +static int g_searchtitle(gmenu_t* pm, int rev) { + static char search_str[30] = ""; + int pos; + + if(getdata(b_lines - 1, 1,"[·j´M]ÃöÁä¦r:", search_str, 40, 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(strstr_lower(pm->item[pos]->title, search_str)) + return pos; + } while(pos != pm->now); + return pm->now; +} + +static void g_showhelp() { + clear(); + outs("\033[36m¡i " BBSNAME "³s½uºëµØ°Ï¨Ï¥Î»¡©ú ¡j\033[m\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" + "[^S] ±N¤å³¹¦s¨ì«H½c\n" + "[R] §ó·s¸ê®Æ\n" + "[N] ¬d¸ßÀɦW\n" + "[c][C][^C] «þ¨©¤å³¹/¨Ã¸õ¦Ü¤W¦¸¶K¤å³¹ªº¦a¤è/" + "ª½±µ¶K¨ì¤W¦¸¶Kªº¦a¤è\n"); + pressanykey(); +} + +#define PATHLEN 256 + +static char paste_fname[200]; +extern time_t paste_time; +extern char paste_path[]; +extern char paste_title[]; +extern int paste_level; + +static void load_paste() { + struct stat st; + FILE *fp; + + if(!*paste_fname) + setuserfile(paste_fname, "paste_path"); + if(stat(paste_fname, &st) == 0 && st.st_mtime > paste_time && + (fp = fopen(paste_fname, "r"))) { + int i; + fgets(paste_path, PATHLEN, fp); + i = strlen(paste_path) - 1; + if(paste_path[i] == '\n') + paste_path[i] = 0; + fgets(paste_title, STRLEN, fp); + i = strlen(paste_title) - 1; + if(paste_title[i] == '\n') + paste_title[i] = 0; + fscanf(fp, "%d", &paste_level); + paste_time = st.st_mtime; + fclose(fp); + } +} + +static char copyfile[PATHLEN]; +static char copytitle[TTLEN+1]; +static char copyowner[IDLEN + 2]; + +void a_copyitem(char* fpath, char* title, char* owner, int mode) { + strcpy(copyfile, fpath); + strcpy(copytitle, title); + if(owner) + strcpy(copyowner, owner); + else + *copyowner = 0; + if(mode) { + outmsg("Àɮ׼аO§¹¦¨¡C[ª`·N] «þ¨©«á¤~¯à§R°£ì¤å!"); + igetch(); + } +} + +#define FHSZ sizeof(fileheader_t) + +static void a_loadname(menu_t *pm) { + char buf[PATHLEN]; + int len; + + setadir(buf, pm->path); + len = get_records(buf, pm->header, FHSZ, pm->page+1, p_lines); + if(len < p_lines) + bzero(&pm->header[len], FHSZ*(p_lines-len)); +} + +static void a_timestamp(char *buf, time_t *time) { + struct tm *pt = localtime(time); + + sprintf(buf, "%02d/%02d/%02d", pt->tm_mon + 1, pt->tm_mday, (pt->tm_year + 1900) % 100); +} + +static void a_showmenu(menu_t *pm) { + char *title, *editor; + int n; + fileheader_t *item; + char buf[PATHLEN]; + time_t dtime; + + showtitle("ºëµØ¤å³¹", pm->mtitle); + prints(" \033[1;36m½s¸¹ ¼Ð ÃD%56s\033[0m", + "½s ¿ï ¤é ´Á"); + + if(pm->num) { + setadir(buf, pm->path); + a_loadname(pm); + for(n = 0; n < p_lines && pm->page + n < pm->num; n++) { + item = &pm->header[n]; + title = item->title; + editor = item->owner; + /* Ptt §â®É¶¡§ï¬°¨úÀɮ׮ɶ¡ + dtime = atoi(&item->filename[2]); + */ + sprintf(buf,"%s/%s",pm->path,item->filename); + dtime = dasht(buf); + a_timestamp(buf, &dtime); + prints("\n%6d%c %-47.46s%-13s[%s]", pm->page+n+1, + (item->filemode & FILE_BM) ?'X': + (item->filemode & FILE_HIDE) ?')':'.', + title, editor, + buf); + } + } else + outs("\n ¡mºëµØ°Ï¡n©|¦b§l¨ú¤Ñ¦a¶¡ªº¤é¤ëºëµØ¤¤... :)"); + + move(b_lines, 1); + outs(pm->level ? + "\033[34;46m ¡iªO ¥D¡j \033[31;47m (h)\033[30m»¡©ú " + "\033[31m(q/¡ö)\033[30mÂ÷¶} \033[31m(n)\033[30m·s¼W¤å³¹ " + "\033[31m(g)\033[30m·s¼W¥Ø¿ý \033[31m(e)\033[30m½s¿èÀÉ®× \033[m" : + "\033[34;46m ¡i¥\\¯àÁä¡j \033[31;47m (h)\033[30m»¡©ú " + "\033[31m(q/¡ö)\033[30mÂ÷¶} \033[31m(k¡ôj¡õ)\033[30m²¾°Ê´å¼Ð " + "\033[31m(enter/¡÷)\033[30mŪ¨ú¸ê®Æ \033[m"); +} + +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, 40, 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; + a_loadname(pm); + } + if(strstr_lower(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("\033[36m¡i " BBSNAME "¤½§GÄæ¨Ï¥Î»¡©ú ¡j\033[m\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\033[36m¡i ªO¥D±M¥ÎÁä ¡j\033[m\n" + "[H] ¤Á´«¬° ¤½¶}/·|û/ª©¥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] «þ¨©/Ö߶K/ªþ¥[¤å³¹\n" + "[^P/^A] Ö߶K/ªþ¥[¤w¥Î't'¼Ð°O¤å³¹\n"); + } + + if(level >= SYSOP) { + outs("\n\033[36m¡i ¯¸ªø±M¥ÎÁä ¡j\033[m\n" + "[l] «Ø symbolic link\n" + "[N] ¬d¸ßÀɦW\n"); + } + pressanykey(); +} + +static int AnnounceSelect() { + static char xboard[20]; + char buf[20]; + char fpath[256]; + boardheader_t *bp; + + move(2, 0); + clrtoeol(); + move(3, 0); + clrtoeol(); + move(1, 0); + make_blist(); + namecomplete("¿ï¾ÜºëµØ°Ï¬ÝªO¡G", buf); + if(*buf) + strcpy(xboard, buf); + if(*xboard && (bp = getbcache(getbnum(xboard)))) { + setapath(fpath, xboard); + setutmpmode(ANNOUNCE); + a_menu(xboard, fpath, + (HAS_PERM(PERM_ALLBOARD) || + (HAS_PERM(PERM_BM) && is_BM(bp->BM))) ? 1 : 0); + } + return FULLUPDATE; +} + +extern char vetitle[]; + +void gem(char* maintitle, item_t* path, int update) { + gmenu_t me; + int ch; + char fname[PATHLEN]; + + strncpy(me.mtitle, maintitle, 40); + me.mtitle[40] = 0; + go_menu(&me, path, update); + + /* ºëµØ°Ï-tree ¤¤³¡¥÷µ²ºcÄÝ©ó cuser ==> BM */ + + me.level = 0; + me.page = 9999; + me.now = 0; + for(;;) { + if(me.now >= me.num && me.num > 0) + me.now = me.num - 1; + else if(me.now < 0) + me.now = 0; + + if(me.now < me.page || me.now >= me.page + p_lines) { + me.page = me.now - (me.now % p_lines); + g_showmenu(&me); + } + ch = cursor_key(2 + me.now - me.page, 0); + if(ch == 'q' || ch == 'Q' || ch == KEY_LEFT) + break; + + if(ch >= '0' && ch <= '9') { + if((ch = search_num(ch, me.num)) != -1) + me.now = ch; + me.page = 9999; + 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 '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 'h': + g_showhelp(); + me.page = 9999; + break; + case '?': + case '/': + me.now = g_searchtitle(&me, ch == '?'); + me.page = 9999; + break; + case 'N': + if(HAS_PERM(PERM_SYSOP)) { + go_proxy(fname, me.item[me.now], 0); + move(b_lines - 1, 0); + outs(fname); + pressanykey(); + me.page = 9999; + } + break; + case 'c': + case 'C': + case Ctrl('C'): + if(me.now < me.num) { + item_t *node = me.item[me.now]; + char *title = node->title; + int mode = title[1]; + + load_paste(); + if(mode == (char) 0xbc || ch == Ctrl('C')) { + if(mode == (char) 0xbc) + go_proxy(fname, node, 0); + if(ch == Ctrl('C') && *paste_path && paste_level) { + char newpath[PATHLEN]; + fileheader_t item; + + strcpy(newpath, paste_path); + if(mode == (char) 0xbc) { + stampfile(newpath, &item); + unlink(newpath); + Link(fname, newpath); + } else + stampdir(newpath, &item); + strcpy(item.owner, cuser.userid); + sprintf(item.title, "%s%.72s", + (currutmp->pager > 1) ? "" : + (mode == (char) 0xbc) ? "¡º " : "¡» ", + title + 3); + strcpy(strrchr(newpath, '/') + 1, ".DIR"); + append_record(newpath, &item, FHSZ); + if(++me.now >= me.num) + me.now = 0; + break; + } + if(mode == (char) 0xbc) { + a_copyitem(fname, + title + ((currutmp->pager > 1) ? 3 : 0), + 0, 1); + if(ch == 'C' && *paste_path) { + setutmpmode(ANNOUNCE); + a_menu(paste_title, paste_path, paste_level); + } + me.page = 9999; + } else + bell(); + } + } + break; + case Ctrl('B'): + m_read(); + me.page = 9999; + break; + case Ctrl('I'): + t_idle(); + me.page = 9999; + break; + case 's': + AnnounceSelect(); + me.page = 9999; + break; + case '\n': + case '\r': + case KEY_RIGHT: + case 'r': + case 'R': + if(me.now < me.num) { + item_t *node = me.item[me.now]; + char *title = node->title; + int mode = title[1]; + int update = (ch == 'R') ? 1 : 0; + + title += 3; + + if(mode == (char) 0xbc) { + int more_result; + + go_proxy(fname, node, update); + strcpy(vetitle, title); + while((more_result = more(fname, YEA))) { + if(more_result == 1) { + if(--me.now < 0) { + me.now = 0; + break; + } + } else if(more_result == 3) { + if(++me.now >= me.num) { + me.now = me.num - 1; + break; + } + } else + break; + node = me.item[me.now]; + if(node->title[1] != (char) 0xbc) + break; + go_proxy(fname, node, update); + strcpy(vetitle, title); + } + } else if(mode == (char) 0xbd) { + gem(title, node, update); + } + me.page = 9999; + } + break; + } + } + for(ch = 0; ch < me.num; ch++) + free(me.item[ch]); +} + +extern char *msg_fwd_ok; +extern char *msg_fwd_err1; +extern char *msg_fwd_err2; + +static void a_forward(char *path, fileheader_t *pitem, int mode) { + fileheader_t fhdr; + + strcpy(fhdr.filename, pitem->filename); + strcpy(fhdr.title, pitem->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, 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*/ + strcpy(pm->header[pm->now - pm->page].filename, myheader->filename); +} + +#define ADDITEM 0 +#define ADDGROUP 1 +#define ADDGOPHER 2 +#define ADDLINK 3 +extern char currboard[]; + +static void a_newitem(menu_t *pm, int mode) { + static char *mesg[4] = { + "[·s¼W¤å³¹] ½Ð¿é¤J¼ÐÃD¡G", /* ADDITEM */ + "[·s¼W¥Ø¿ý] ½Ð¿é¤J¼ÐÃD¡G", /* ADDGROUP */ + "[·s¼W³s½u] ½Ð¿é¤J¼ÐÃD¡G", /* ADDGOPHER */ + "½Ð¿é¤J¼ÐÃD¡G" /* ADDLINK */ + }; + + char fpath[PATHLEN], buf[PATHLEN], lpath[PATHLEN]; + fileheader_t item; + int d; + + strcpy(fpath, pm->path); + + switch(mode) { + case ADDITEM: + stampfile(fpath, &item); + strcpy(item.title, "¡º "); /* A1BA */ + break; + + case ADDGROUP: + stampdir(fpath, &item); + strcpy(item.title, "¡» "); /* A1BB */ + break; + case ADDGOPHER: + bzero(&item, sizeof(item)); + strcpy(item.title, "¡ó "); /* A1BB */ + if(!getdata(b_lines - 2, 1, "¿é¤JURL¦ì§}¡G", + item.filename+2,61, DOECHO)) + return; + break; + case ADDLINK: + stamplink(fpath, &item); + if (!getdata(b_lines - 2, 1, "·s¼W³s½u¡G", buf, 61, DOECHO)) + return; + if(invalid_pname(buf)) { + unlink(fpath); + outs("¥Øªº¦a¸ô®|¤£¦Xªk¡I"); + igetch(); + return; + } + + item.title[0] = 0; + for(d = 0; d <= 3; d++) { + switch(d) { + case 0: + sprintf(lpath, "%s%s%s/%s", + BBSHOME, "/man/boards/",currboard , buf); + break; + case 1: + sprintf(lpath, "%s%s%s", + BBSHOME, "/man/boards/" , buf); + break; + case 2: + sprintf(lpath, "%s%s%s", + BBSHOME, "/" , buf); + break; + case 3: + sprintf(lpath, "%s%s%s", + BBSHOME, "/etc/" , buf); + break; + } + if(dashf(lpath)) { + strcpy(item.title, "¡¸ "); /* A1B3 */ + break; + } else if (dashd(lpath)) { + strcpy(item.title, "¡¹ "); /* A1B4 */ + break; + } + if(!HAS_PERM(PERM_BBSADM) && d==1) + break; + } + + if(!item.title[0]) { + unlink(fpath); + outs("¥Øªº¦a¸ô®|¤£¦Xªk¡I"); + igetch(); + return; + } + } + + if(!getdata(b_lines - 1, 1, mesg[mode], &item.title[3], 55, DOECHO)) { + if(mode == ADDGROUP) + rmdir(fpath); + else if(mode != ADDGOPHER) + unlink(fpath); + return; + } + + switch(mode) { + case ADDITEM: + if(vedit(fpath, 0, NULL) == -1) { + unlink(fpath); + pressanykey(); + return; + } + break; + case ADDLINK: + unlink(fpath); + if(symlink(lpath, fpath) == -1) { + outs("µLªk«Ø¥ß symbolic link"); + igetch(); + return; + } + break; + case ADDGOPHER: + strcpy(item.date, "70"); + strncpy(item.filename, "H.",2); + break; + } + + strcpy(item.owner, cuser.userid); + a_additem(pm, &item); +} + +static void a_pasteitem(menu_t *pm, int mode) { + char newpath[PATHLEN]; + char buf[PATHLEN]; + char ans[2]; + int i; + fileheader_t item; + + move(b_lines - 1, 1); + if(copyfile[0]) { + if(dashd(copyfile)) { + for(i = 0; copyfile[i] && copyfile[i] == pm->path[i]; i++); + if(!copyfile[i]) { + outs("±N¥Ø¿ý«þ¶i¦Û¤vªº¤l¥Ø¿ý¤¤¡A·|³y¦¨µL½a°j°é¡I"); + igetch(); + return; + } + } + if(mode) { + sprintf(buf, "½T©wn«þ¨©[%s]¶Ü(Y/N)¡H[N] ", copytitle); + getdata(b_lines - 1, 1, buf, ans, 3, LCECHO); + } else + ans[0]='y'; + if(ans[0] == 'y') { + strcpy(newpath, pm->path); + + if(*copyowner) { + char* fname = strrchr(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)); + strcpy(item.filename, fname + 1); + memcpy(copytitle, "¡·", 2); + if(HAS_PERM(PERM_BBSADM)) + Link(copyfile, newpath); + else { + sprintf(buf, "/bin/cp %s %s", copyfile, newpath); + system(buf); + } + } else if(dashf(copyfile)) { + stampfile(newpath, &item); + memcpy(copytitle, "¡º", 2); + sprintf(buf, "/bin/cp %s %s", copyfile, newpath); + } else if(dashd(copyfile)) { + stampdir(newpath, &item); + memcpy(copytitle, "¡»", 2); + sprintf(buf, "/bin/cp -r %s/* %s/.D* %s", copyfile, copyfile, + newpath); + } else { + outs("µLªk«þ¨©¡I"); + igetch(); + return; + } + strcpy(item.owner, *copyowner ? copyowner : cuser.userid); + strcpy(item.title, copytitle); + if(!*copyowner) + system(buf); + a_additem(pm, &item); + copyfile[0] = '\0'; + } + } else { + outs("½Ð¥ý°õ¦æ copy ©R¥O«á¦A paste"); + igetch(); + } +} + +static void a_appenditem(menu_t *pm, int isask) { + char fname[PATHLEN]; + char buf[ANSILINELEN]; + char ans[2] = "y"; + FILE *fp, *fin; + + move(b_lines - 1, 1); + if(copyfile[0]) { + if(dashf(copyfile)) { + sprintf(fname, "%s/%s", pm->path, + pm->header[pm->now-pm->page].filename); + if(dashf(fname)) { + if(isask) { + sprintf(buf, "½T©wn±N[%s]ªþ¥[©ó¦¹¶Ü(Y/N)¡H[N] ", + copytitle); + getdata(b_lines - 2, 1, buf, ans, 3, LCECHO); + } + if(ans[0] == 'y') { + if((fp = fopen(fname, "a+"))) { + if((fin = fopen(copyfile, "r"))) { + 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, 3, LCECHO); + while(fgets(buf, sizeof(buf), fin)) { + if((ans[0] == 'n' ) && + !strcmp(buf, "--\n")) + break; + fputs(buf, fp); + } + fclose(fin); + copyfile[0] = '\0'; + } + fclose(fp); + } + } + } else { + outs("Àɮפ£±oªþ¥[©ó¦¹¡I"); + igetch(); + } + } else { + outs("¤£±oªþ¥[¾ãӥؿý©óÀɮ׫á¡I"); + igetch(); + } + } else { + outs("½Ð¥ý°õ¦æ copy ©R¥O«á¦A append"); + igetch(); + } +} + +static int a_pastetagpost(menu_t *pm, int mode) { + extern int TagNum; + extern void EnumTagFhdr(); + extern void UnTagger(int locus); + fileheader_t fhdr; + int ans = 0, ent=0, tagnum; + char title[TTLEN + 1]= "¡º "; + char dirname[200],buf[200]; + + setbdir(dirname, currboard); + tagnum = TagNum; + + if (!tagnum) return ans; + + while (tagnum--) + { + EnumTagFhdr (&fhdr, dirname, ent++); + setbfile (buf, currboard, fhdr.filename); + + if (dashf (buf)) + { + strncpy(title+3, fhdr.title, TTLEN-3); + title[TTLEN] = '\0'; + 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[4]; + int num, max, min; + char buf[PATHLEN]; + int fail; + + sprintf(buf, "½Ð¿é¤J²Ä %d ¿ï¶µªº·s¦¸§Ç¡G", pm->now + 1); + if(!getdata(b_lines - 1, 1, buf, newnum, 6, 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[256]; + + sprintf(fname,"%s/.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; + + sprintf(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©wn§R°£¦¹ºëµØ°Ï³s½u¶Ü(Y/N)¡H[N] ", + ans, 3, 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©wn§R°£¦¹ symbolic link ¶Ü(Y/N)¡H[N] ", + ans, 3, 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©wn§R°£¦¹Àɮ׶Ü(Y/N)¡H[N] ", ans, 3, + LCECHO); + if(ans[0] != 'y') + return; + if(delete_record(buf, FHSZ, pm->now + 1) == -1) + return; + + setbpath(buf, "deleted"); + stampfile(buf, &backup); + strcpy(backup.owner, cuser.userid); + strcpy(backup.title,pm->header[pm->now - pm->page].title + 2); + backup.savemode = 'D'; + + sprintf(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©wn§R°£¾ãӥؿý¶Ü(Y/N)¡H[N] ", ans, 3, + LCECHO); + if(ans[0] != 'y') + return; + if(delete_record(buf, FHSZ, pm->now + 1) == -1) + return; + + setapath(buf, "deleted"); + stampdir(buf, &backup); + + sprintf(cmd, "rm -rf %s;/bin/mv -f %s %s",buf,fpath,buf); + system(cmd); + + strcpy(backup.owner, cuser.userid); + strcpy(backup.title,pm->header[pm->now - pm->page].title +2); + setapath(buf, "deleted"); + setadir(buf,buf); + append_record(buf, &backup, sizeof(backup)); + } else { /* Ptt ·l·´ªº¶µ¥Ø */ + getdata(b_lines - 1, 1, "±z½T©wn§R°£¦¹·l·´ªº¶µ¥Ø¶Ü(Y/N)¡H[N] ", + ans, 3, LCECHO); + if(ans[0] != 'y') + return; + if(delete_record(buf, FHSZ, pm->now + 1) == -1) + return; + } + pm->num--; +} + +static void a_newtitle(menu_t *pm) { + char buf[PATHLEN]; + fileheader_t item; + + memcpy(&item, &pm->header[pm->now - pm->page], FHSZ); + strcpy(buf,item.title + 3); + if(getdata_buf(b_lines - 1, 1, "·s¼ÐÃD¡G", buf, 60, DOECHO)) { + strcpy(item.title + 3, buf); + setadir(buf, pm->path); + substitute_record(buf, &item, FHSZ, pm->now + 1); + } +} +static void a_hideitem(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(menu_t *pm) { + char buf[PATHLEN]; + fileheader_t item; + + memcpy(&item, &pm->header[pm->now - pm->page], FHSZ); + sprintf(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(menu_t *pm) { + char buf[PATHLEN]; + int len; + int i; + int sym; + + move(b_lines - 1, 1); + sprintf(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(HAS_PERM(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) { + pressanykey(); + move(b_lines - 1, 1); + prints("¦¹ 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(); +} + +static char *a_title; + +static void atitle() { + showtitle("ºëµØ¤å³¹", a_title); + outs("[¡ö]Â÷¶} [¡÷]¾\\Ū [^P]µoªí¤å³¹ [b]³Æ§Ñ¿ý [d]§R°£ [q]ºëµØ°Ï " + "[TAB]¤åºK [h]elp\n\033[7m ½s¸¹ ¤é ´Á §@ ªÌ " + "¤å ³¹ ¼Ð ÃD\033[m"); +} + +extern char currtitle[]; + +char trans_buffer[256]; +extern char quote_file[]; +extern unsigned int currstat; + +static int isvisible_man(menu_t *me) +{ + fileheader_t *fhdr = &me->header[me->now-me->page]; + if( me->level<MANAGER && ((fhdr->filemode & FILE_BM) || + ((fhdr->filemode & FILE_HIDE) && + hbflcheck(currbid, currutmp->uid)))) + return 0; + return 1; +} +int a_menu(char *maintitle, char *path, int lastlevel) { + static char Fexit; + menu_t me; + char fname[PATHLEN]; + int ch, returnvalue = FULLUPDATE; + + trans_buffer[0] = 0; + + Fexit = 0; + me.header = (fileheader_t *)calloc(p_lines, FHSZ); + me.path = path; + strcpy(me.mtitle, maintitle); + setadir(fname, me.path); + me.num = get_num_records(fname, FHSZ); + + /* ºëµØ°Ï-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 + p_lines) { + me.page = me.now - ((me.page == 10000 && me.now > p_lines / 2) ? + (p_lines / 2) : (me.now % p_lines)); + a_showmenu(&me); + } + + 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 '/': + 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('C'): + cal(); + me.page = 9999; + break; + + case Ctrl('I'): + t_idle(); + me.page = 9999; + break; + + case 's': + AnnounceSelect(); + me.page = 9999; + break; + + case 'e': + case 'E': + sprintf(fname, "%s/%s", path, me.header[me.now-me.page].filename); + if(dashf(fname) && me.level >= MANAGER) { + *quote_file = 0; + if(vedit(fname, NA, NULL) != -1) { + char fpath[200]; + fileheader_t fhdr; + + strcpy(fpath, path); + stampfile(fpath, &fhdr); + unlink(fpath); + Rename(fname, fpath); + strcpy(me.header[me.now-me.page].filename, fhdr.filename); + strcpy(me.header[me.now-me.page].owner, cuser.userid); + setadir(fpath, path); + substitute_record(fpath, me.header+me.now-me.page, + sizeof(fhdr), me.now + 1); + } + me.page = 9999; + } + break; + + case 'c': + if(me.now < me.num) { + if(!isvisible_man(&me)) break; + sprintf(fname, "%s/%s", path, + me.header[me.now-me.page].filename); + a_copyitem(fname, me.header[me.now-me.page].title, 0, 1); + me.page = 9999; + 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; + sprintf(fname, "%s/%s", path, fhdr->filename); + if(*fhdr->filename == 'H' && fhdr->filename[1] == '.') { + item_t item; + strcpy(item.X.G.server, fhdr->filename + 2); + strcpy(item.X.G.path, "1/"); + item.X.G.port = 70; + gem(fhdr->title, &item, (ch == 'R') ? 1 : 0); + } else if (dashf(fname)) { + int more_result; + + while((more_result = more(fname, YEA))) { + /* Ptt ½d¥»ºëÆF plugin */ + if(currstat == EDITEXP || currstat == OSONG) { + char ans[4]; + + move(22, 0); + clrtoeol(); + getdata(22, 1, + currstat == EDITEXP ? + "n§â½d¨Ò Plugin ¨ì¤å³¹¶Ü?[y/N]": + "½T©wnÂI³oººq¶Ü?[y/N]", + ans, 3, LCECHO); + if(ans[0]=='y') { + strcpy(trans_buffer,fname); + Fexit = 1; + free(me.header); + if(currstat == OSONG){ + log_file(FN_USSONG,fhdr->title); + } + return FULLUPDATE; + } + } + if(more_result == 1) { + if(--me.now < 0) { + me.now = 0; + break; + } + } else if(more_result == 3) { + if(++me.now >= me.num) { + me.now = me.num - 1; + break; + } + } else + break; + if(!isvisible_man(&me)) break; + sprintf(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); + /* Ptt ±j¤O¸õ¥Xrecursive */ + if(Fexit) { + free(me.header); + return FULLUPDATE; + } + } + me.page = 9999; + } + break; + + case 'F': + case 'U': + sprintf(fname, "%s/%s", path, me.header[me.now-me.page].filename); + if(me.now < me.num && HAS_PERM(PERM_BASIC) && dashf(fname)) { + a_forward(path, &me.header[me.now-me.page], ch /*== 'U'*/); + /*By CharlieL*/ + } else + outmsg("µLªkÂà±H¦¹¶µ¥Ø"); + + me.page = 9999; + refresh(); + sleep(1); + break; + } + + if(me.level >= MANAGER) { + int page0 = me.page; + + switch(ch) { + case 'n': + a_newitem(&me, ADDITEM); + me.page = 9999; + break; + case 'g': + a_newitem(&me, ADDGROUP); + me.page = 9999; + break; + case 'G': + a_newitem(&me, ADDGOPHER); + 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; + default: + me.page = page0; + break; + } + + 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; + } + } + + if(me.level == SYSOP) { + switch(ch) { + case 'l': + a_newitem(&me, ADDLINK); + me.page = 9999; + break; + case 'N': + a_showname(&me); + me.page = 9999; + break; + } + } + } + free(me.header); + return returnvalue; +} + +static char *mytitle = BBSNAME "§G§iÄæ"; + +int Announce() { + setutmpmode(ANNOUNCE); + a_menu(mytitle, "man", + ((HAS_PERM(PERM_SYSOP) || HAS_PERM(PERM_ANNOUNCE)) ? SYSOP : + NOBODY)); + return 0; +} diff --git a/mbbsd/args.c b/mbbsd/args.c new file mode 100644 index 00000000..4d1d6ceb --- /dev/null +++ b/mbbsd/args.c @@ -0,0 +1,62 @@ +/* $Id: args.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#ifdef HAVE_SETPROCTITLE + +void initsetproctitle(int argc, char **argv, char **envp) { +} + +#else + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> + +char **Argv = NULL; /* pointer to argument vector */ +char *LastArgv = NULL; /* end of argv */ +extern char **environ; + +void initsetproctitle(int argc, char **argv, char **envp) { + register int i; + + /* Move the environment so setproctitle can use the space at + the top of memory. */ + for(i = 0; envp[i]; i++); + environ = malloc(sizeof(char *) * (i + 1)); + for(i = 0; envp[i]; i++) + environ[i] = strdup(envp[i]); + environ[i] = NULL; + + /* Save start and extent of argv for setproctitle. */ + Argv = argv; + if(i > 0) + LastArgv = envp[i - 1] + strlen(envp[i - 1]); + else + LastArgv = argv[argc - 1] + strlen(argv[argc - 1]); +} + +static void do_setproctitle(const char *cmdline) { + char buf[256], *p; + int i; + + strncpy(buf, cmdline, 256); + buf[255] = '\0'; + i = strlen(buf); + if(i > LastArgv - Argv[0] - 2) { + i = LastArgv - Argv[0] - 2; + } + strcpy(Argv[0], buf); + p = &Argv[0][i]; + while(p < LastArgv) + *p++='\0'; + Argv[1] = NULL; +} + +void setproctitle(const char* format, ...) { + char buf[256]; + va_list args; + va_start(args, format); + vsprintf(buf, format,args); + do_setproctitle(buf); + va_end(args); +} +#endif diff --git a/mbbsd/bbcall.c b/mbbsd/bbcall.c new file mode 100644 index 00000000..d7b2d33b --- /dev/null +++ b/mbbsd/bbcall.c @@ -0,0 +1,268 @@ +/* $Id: bbcall.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <netdb.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "proto.h" + +#define SERVER_0941 "www.chips.com.tw" +#define SERVER_0943 "www.pager.com.tw" +#define SERVER_0948 "www.fitel.net.tw" +#define SERVER_0947 "www.hoyard.com.tw" +#define SERVER_0945 "203.73.181.254" + +#define CGI_0948 "/cgi-bin/Webpage.dll" +#define CGI_0941 "/cgi-bin/paging1.pl" +#define CGI_0947 "/scripts/fp_page1.dll" +#define CGI_0945 "/Scripts/fiss/PageForm.exe" +#define CGI_0943 "/tpn/tpnasp/dowebcall.asp" + +#define CGI_RAILWAY "http://www.railway.gov.tw/cgi-bin/timetk.cgi" + +#define REFER_0943 "http://www.pager.com.tw/tpn/webcall/webcall.asp" +#define REFER_0948 "http://www.fitel.net.tw/html/svc03.htm" +#define REFER_0941 "http://www.chips.com.tw:9100/WEB2P/page_1.htm" +#define REFER_0947 "http://web1.hoyard.com.tw/freeway/freewayi.html" +#define REFER_0945 "http://203.73.181.254/call.HTM" + +static void pager_msg_encode(char *field, char *buf) { + char *cc = field; + unsigned char *p; + + for(p = (unsigned char *)buf; *p; p++) { + if((*p >= '0' && *p <= '9') || + (*p >= 'A' && *p <= 'Z') || + (*p >= 'a' && *p <= 'z') || + *p == ' ') + *cc++ = *p == ' ' ? '+' : (char)*p; + else { + sprintf(cc, "%%%02X", (int)*p); + cc += 3; + } + } + *cc = 0; +} + +static void gettime(int flag, int *Year, int *Month, int *Day, int *Hour, + int *Minute) { + char ans[5]; + + do { + getdata(10, 0, "¦~[20-]:", ans, 3, LCECHO); + *Year = atoi(ans); + } while(*Year < 00 || *Year > 02); + do { + getdata(10, 15, "¤ë[1-12]:", ans, 3, LCECHO); + } while(!IsSNum(ans) || (*Month = atoi(ans)) > 12 || *Month < 1); + do { + getdata(10,30, "¤é[1-31]:", ans, 3, LCECHO); + } while(!IsSNum(ans) || (*Day = atoi(ans)) > 31 || *Day < 1); + do { + getdata(10,45, "®É[0-23]:", ans, 3, LCECHO); + } while(!IsSNum(ans) || (*Hour = atoi(ans)) > 23 || *Hour < 0); + do { + getdata(10,60, "¤À[0-59]:", ans, 3, LCECHO); + } while(!IsSNum(ans) || (*Minute=atoi(ans))>59 || *Minute<0); + if(flag == 1) + *Year-=11; +} + +#define hpressanykey(a) {move(22, 0); prints(a); pressanykey();} + +static int Connect(char *s, char *server) { + FILE *fp = fopen(BBSHOME "/log/bbcall.log", "a"); + int sockfd; + char result[2048]; + struct sockaddr_in serv_addr; + struct hostent *hp; + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + return 0; + + memset((char *)&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + + if((hp = gethostbyname(server)) == NULL) + return 0; + + memcpy(&serv_addr.sin_addr, hp->h_addr, hp->h_length); + + if(!strcmp(server, SERVER_0941)) + serv_addr.sin_port = htons(9100); + else + serv_addr.sin_port = htons(80); + + if(connect(sockfd, (struct sockaddr *) &serv_addr, sizeof serv_addr)) { + hpressanykey("µLªk»P¦øªA¾¹¨ú±o³sµ²¡A¶Ç©I¥¢±Ñ"); + return 0; + } else { + mprints(20, 0, "\033[1;33m¦øªA¾¹¤w¸g³s±µ¤W¡A½Ðµy«á" + ".....................\033[m"); + refresh(); + } + + write(sockfd, s, strlen(s)); + shutdown(sockfd, 1); + + while(read(sockfd, result, sizeof(result)) > 0) { + fprintf(fp, "%s\n", result); + fflush(fp); + if(strstr(result, "¥¿½T") || + strstr(result,"µ¥«Ý") || + strstr(result,"¦A«×") || + strstr(result,"§¹ ¦¨ ¦^ À³") || + strstr(result, "¹w¬ù¤¤") || + strstr(result,"¶Ç°e¤¤")) { + close(sockfd); + hpressanykey("¶¶§Q°e¥X¶Ç©I"); + return 0; + } + memset(result, 0, sizeof(result)); + } + fclose(fp); + close(sockfd); + hpressanykey("µLªk¶¶§Q°e¥X¶Ç©I"); + return 0; +} + +#define PARA \ +"Connection: Keep-Alive\r\n"\ +"User-Agent: Lynx/2.6 libwww-FM/2.14\r\n"\ +"Content-type: application/x-www-form-urlencoded\r\n"\ +"Accept: text/html, text/plain, application/x-wais-source, "\ +"application/html, */*;q=0.001\r\n"\ +"Accept-Encoding: gzip\r\n"\ +"Accept-Language: en\r\n"\ +"Accept-Charset: iso-8859-1,*,utf-8\r\n" + +static void halpha0943(char* CoId) { + char tmpbuf[64],ans[2]; + char ID[8]; + char Msg[64], atrn[512], sendform[1024]; + int Year = 99, Month = 1, Day = 15, Hour = 13, Minute = 8; + + sprintf(tmpbuf, "\033[1;37m½Ð¿é¤J±zn¶Ç©Iªº¸¹½X\033[m : %s-", CoId); + if(!getdata(7,0, tmpbuf, ID, 7, LCECHO) || + !getdata(8,0, "\033[1;37m½Ð¿é¤J¶Ç©I°T®§\033[m¡G", tmpbuf, 63, LCECHO)) { + hpressanykey("©ñ±ó¶Ç©I"); + return; + } + pager_msg_encode(Msg,tmpbuf); + getdata(9, 0, "\033[1;37m¦pªG§An°¨¤W°e½Ð«ö '1' " + "¦pªGn©w®É°e½Ð«ö '2': \033[m", ans, 2, LCECHO); + + if(ans[0] != '1') + gettime(0, &Year, &Month, &Day, &Hour, &Minute); + + sprintf(atrn, "CoId=%s&ID=%s&Year=19%02d&Month=%02d&Day=%02d" + "&Hour=%02d&Minute=%02d&Msg=%s", + CoId, ID,Year,Month,Day,Hour,Minute,Msg); + sprintf(sendform, "POST %s HTTP/1.0\nReferer: " + "%s\n%sContent-length:%d\n\n%s", + CGI_0943, REFER_0943, PARA, strlen(atrn), atrn); + Connect(sendform, SERVER_0943); + return ; +} + +static void hcall0941() { + char ans[2]; + char PAGER_NO[8], TRAN_MSG[18], TIME[8]; + char trn[512], sendform[512]; + int year = 98, month = 12, day = 4, hour = 13, min = 8; + + if(!getdata(7, 0, "\033[1;37 ½Ð±z¿é¤J±zn¶Ç©Iªº¸¹½X : 0941- \033[m", + PAGER_NO, 7, LCECHO) || + !getdata(8, 0, "\033[1;37m½Ð¿é¤J¶Ç©I°T®§\033[m¡G", trn, 17, LCECHO)) { + hpressanykey("©ñ±ó¶Ç©I"); + return; + } + pager_msg_encode(TRAN_MSG,trn); + getdata(9,0, "\033[1;37m¦pªG§An°¨¤W°e½Ð«ö '1' " + "¦pªGn©w®É°e½Ð«ö '2': \033[m", ans, 2, LCECHO); + if(ans[0] != '1') { + strcpy(TIME,"DELAY"); + gettime(0, &year, &month, &day, &hour, &min); + } else + strcpy(TIME,"NOW"); + sprintf(trn,"PAGER_NO=%s&TRAN_MSG=%s&MSG_TYPE=NUMERIC&%s=1" + "&year=19%02d&month=%02d&day=%02d&hour=%02d&min=%02d", + PAGER_NO, TRAN_MSG, TIME,year,month,day,hour,min); + + sprintf(sendform, "POST %s HTTP/1.0\nReferer: %s\n%s" + "Content-length:%d\n\n%s", + CGI_0941, REFER_0941, PARA, strlen(trn), trn); + + Connect(sendform, SERVER_0941); + return ; +} + +static void hcall0948() { + int year = 87, month = 12, day = 19, hour = 12, min = 0, ya = 0; + char svc_no[8], message[64], trn[256], sendform[512], ans[3]; + + move(7,0); + clrtoeol(); + + if(!getdata(7, 0, "\033[1;37m½Ð¿é¤J±zn¶Ç©Iªº¸¹½X\033[m¡G0948-", + svc_no, 7, LCECHO) || + !getdata(8, 0, "\033[1;37m½Ð¿é¤J¶Ç©I°T®§\033[m¡G", trn, 61, LCECHO)) { + hpressanykey("©ñ±ó¶Ç©I"); + return; + } + pager_msg_encode(message, trn); + getdata(9, 0, "\033[1;37m¦pªG§An°¨¤W°e½Ð«ö '1' " + "¦pªGn©w®É°e½Ð«ö '2'\033[m: ", ans, 2, LCECHO); + if(ans[0] != '1') { + gettime(1, &year, &month, &day, &hour, &min); + ya = 1; + } + + sprintf(trn, "MfcISAPICommand=SinglePage&svc_no=%s&reminder=%d" + "&year=%02d&month=%02d&day=%02d&hour=%02d&min=%02d&message=%s", + svc_no, ya, year, month, day, hour, min, message); + + sprintf(sendform, "GET %s?%s Http/1.0\n\n", CGI_0948, trn); + + Connect(sendform, SERVER_0948); + return; +} + +int main_bbcall() { + char ch[2]; + + clear(); + move(0, 30); + prints("\033[1;37;45m ¹G¹Gáà¾÷ \033[m"); + move(3, 0); + prints("\033[1;31m ¢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¢{\033[m\n"); + prints("\033[1;33m (1)0941 (2)0943 (3)0946 " + " (4)0948 \033[m\n"); + prints("\033[1;31m ¢|¢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¢}\033[m\n"); + getdata(7, 8, "\033[1;37m§Aªº¿ï¾Ü? [1-4]\033[m", ch, 2, LCECHO); + + switch(ch[0]) { + case '1': + hcall0941(); + break; + case '2': + halpha0943("0943"); + break; + case '3': + halpha0943("0946"); + break; + case '4': + hcall0948(); + break; + } + return 0; +} diff --git a/mbbsd/bbs.c b/mbbsd/bbs.c new file mode 100644 index 00000000..15db1c91 --- /dev/null +++ b/mbbsd/bbs.c @@ -0,0 +1,1904 @@ +/* $Id: bbs.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <time.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include "config.h" +#include "pttstruct.h" +#include "perm.h" +#include "modes.h" +#include "common.h" +#include "proto.h" + +static int g_board_names(boardheader_t *fhdr) { + AddNameList(fhdr->brdname); + return 0; +} + +extern userec_t cuser; +extern void touchdircache(int bid); +extern int TagNum; + +static void mail_by_link(char* owner, char* title, char* path) { + char genbuf[200]; + fileheader_t mymail; + + sprintf(genbuf,BBSHOME"/home/%c/%s", cuser.userid[0], cuser.userid); + stampfile(genbuf, &mymail); + strcpy(mymail.owner, owner); + sprintf(mymail.title, title); + mymail.savemode = 0; + unlink(genbuf); + Link(path, genbuf); + sprintf(genbuf,BBSHOME"/home/%c/%s/.DIR",cuser.userid[0],cuser.userid); + + append_record(genbuf, &mymail, sizeof(mymail)); +} + +extern int usernum; + +void anticrosspost() { + char buf[200]; + time_t now = time(NULL); + + sprintf(buf, + "\033[1;33;46m%s \033[37;45mcross post ¤å³¹ \033[37m %s\033[m", + cuser.userid, ctime(&now)); + log_file("etc/illegal_money", buf); + + post_violatelaw(cuser.userid, "Ptt¨t²Îĵ¹î", "Cross-post", "»@³æ³B¥÷"); + cuser.userlevel |= PERM_VIOLATELAW; + cuser.vl_count ++; + mail_by_link("Pttĵ¹î³¡¶¤", "Cross-Post»@³æ", + BBSHOME "/etc/crosspost.txt"); + passwd_update(usernum, &cuser); + exit(0); +} + +/* Heat CharlieL*/ +int save_violatelaw() { + char buf[128], ok[3]; + + setutmpmode(VIOLATELAW); + clear(); + stand_title("ú»@³æ¤¤¤ß"); + + if(!(cuser.userlevel & PERM_VIOLATELAW)) { + mprints(22, 0, "\033[1;31m§AµL²á°Ú? §A¤S¨S¦³³Q¶}»@³æ~~\033[m"); + pressanykey(); + return 0; + } + + reload_money(); + if(cuser.money < (int)cuser.vl_count*1000) { + sprintf(buf, "\033[1;31m³o¬O§A²Ä %d ¦¸¹H¤Ï¥»¯¸ªk³W" + "¥²¶·Ãº¥X %d $Ptt ,§A¥u¦³ %d ¤¸, ¿ú¤£°÷°Õ!!\033[m", + (int)cuser.vl_count, (int)cuser.vl_count * 1000, cuser.money); + mprints(22, 0, buf); + pressanykey(); + return 0; + } + + move(5,0); + prints("\033[1;37m§Aª¾¹D¶Ü? ¦]¬°§Aªº¹Hªk " + "¤w¸g³y¦¨«Ü¦h¤Hªº¤£«K\033[m\n"); + prints("\033[1;37m§A¬O§_½T©w¥H«á¤£·|¦A¥Ç¤F¡H\033[m\n"); + + if(!getdata(10,0,"½T©w¶Ü¡H[y/n]:", ok, 2, LCECHO) || + ok[0] == 'n' || ok[0] == 'N') { + mprints(22,0,"\033[1;31mµ¥§A·Q³q¤F¦A¨Ó§a!! " + "§Ú¬Û«H§A¤£·|ª¾¿ù¤£§ïªº~~~\033[m"); + pressanykey(); + return 0; + } + + sprintf(buf, "³o¬O§A²Ä %d ¦¸¹Hªk ¥²¶·Ãº¥X %d $Ptt", + cuser.vl_count, cuser.vl_count*1000); + mprints(11,0,buf); + + if(!getdata(10, 0, "n¥I¿ú[y/n]:", ok, 2, LCECHO) || + ok[0] == 'N' || ok[0] == 'n') { + + mprints(22,0, "\033[1;31m ¶â ¦s°÷¿ú ¦A¨Ó§a!!!\033[m"); + pressanykey(); + return 0; + } + + demoney(-1000*cuser.vl_count); + cuser.userlevel &= (~PERM_VIOLATELAW); + passwd_update(usernum, &cuser); + return 0; +} + +void make_blist() { + CreateNameList(); + apply_boards(g_board_names); +} + +extern int currbid; +extern char currBM[]; +extern int currmode; +extern char currboard[]; +static time_t board_note_time; +static char *brd_title; + +void set_board() { + boardheader_t *bp; + + bp = getbcache(currbid); + board_note_time = bp->bupdate; + brd_title = bp->BM; + if(brd_title[0] <= ' ') + brd_title = "¼x¨D¤¤"; + sprintf(currBM, "ªO¥D¡G%s", brd_title); + brd_title = ((bp->bvote != 2 && bp->bvote) ? "¥»¬ÝªO¶i¦æ§ë²¼¤¤" : + bp->title + 7); + currmode = (currmode & (MODE_DIRTY | MODE_MENU)) | MODE_STARTED ; + + if (HAS_PERM(PERM_ALLBOARD) || is_BM(bp->BM)) + currmode = currmode | MODE_BOARD | MODE_POST; + else if(haspostperm(currboard)) + currmode |= MODE_POST; +} + +static void readtitle() { + showtitle(currBM, brd_title); + outs("[¡ö]Â÷¶} [¡÷]¾\\Ū [^P]µoªí¤å³¹ [b]³Æ§Ñ¿ý [d]§R°£ [z]ºëµØ°Ï " + "[TAB]¤åºK [h]elp\n\033[7m ½s¸¹ ¤é ´Á §@ ªÌ ¤å ³¹ ¼Ð ÃD" + " \033[m"); +} + +extern int brc_num; +extern int brc_list[]; +extern char currtitle[]; + +extern int Tagger(); + +static void readdoent(int num, fileheader_t *ent) { + int type; + char *mark, *title, color; + + type = brc_unread(ent->filename,brc_num,brc_list) ? '+' : ' '; + + if((currmode & MODE_BOARD) && (ent->filemode & FILE_DIGEST)) + type = (type == ' ') ? '*' : '#'; + else if(currmode & MODE_BOARD || HAS_PERM(PERM_LOGINOK)) { + if(ent->filemode & FILE_MARKED) + type = (type == ' ') ? 'm' : 'M'; + + else if (TagNum && !Tagger(atoi(ent->filename + 2), 0, TAG_NIN)) + type = 'D'; + + else if (ent->filemode & FILE_SOLVED) + type = 's'; + } + + title = subject(mark = ent->title); + if(title == mark) + color = '1', mark = "¡¼"; + else + color = '3', mark = "R:"; + + if(title[47]) + strcpy(title + 44, " ¡K"); /* §â¦h¾lªº string ¬å±¼ */ + + if(strncmp(currtitle, title, 40)) + prints("%6d %c %-7s%-13.12s%s %s\n", num, type, + ent->date, ent->owner, mark, title); + else + prints("%6d %c %-7s%-13.12s\033[1;3%cm%s %s\033[m\n", num, type, + ent->date, ent->owner, color, mark, title); +} + +extern char currfile[]; + +int cmpfilename(fileheader_t *fhdr) { + return (!strcmp(fhdr->filename, currfile)); +} + +extern unsigned char currfmode; + +int cmpfmode(fileheader_t *fhdr) { + return (fhdr->filemode & currfmode); +} + +extern char currowner[]; + +int cmpfowner(fileheader_t *fhdr) { + return !strcasecmp(fhdr->owner, currowner); +} + +extern char *err_bid; +extern userinfo_t *currutmp; + +int whereami(int ent, fileheader_t *fhdr, char *direct) { + boardheader_t *bh, *p[32], *root; + int i,j; + + if(!currutmp->brc_id) return 0; + + move(1,0); + clrtobot(); + bh=getbcache(currutmp->brc_id); + root=getbcache(1); + p[0]=bh; + for(i=0;i<31 && p[i]->parent!=root && p[i]->parent;i++) + p[i+1]=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(int ent, fileheader_t *fhdr, char *direct) { + char bname[20]; + char bpath[60]; + boardheader_t *bh; + struct stat st; + int i; + + move(0, 0); + clrtoeol(); + make_blist(); + namecomplete(MSG_SELECT_BOARD, bname); + if(bname[0]=='\0' || !(i = getbnum(bname))) + return FULLUPDATE; + bh = getbcache(i); + if(!Ben_Perm(bh)) return FULLUPDATE; + strcpy(bname, bh->brdname); + currbid=i; + + setbpath(bpath, bname); + if((*bname == '\0') || (stat(bpath, &st) == -1)) { + move(2, 0); + clrtoeol(); + outs(err_bid); + return FULLUPDATE; + } + + currutmp->brc_id = currbid; + + brc_initial(bname); + set_board(); + setbdir(direct, currboard); + + move(1, 0); + clrtoeol(); + return NEWDIRECT; +} + +/* ----------------------------------------------------- */ +/* §ï¨} innbbsd Âà¥X«H¥ó¡B³s½u¬å«H¤§³B²zµ{§Ç */ +/* ----------------------------------------------------- */ +void outgo_post(fileheader_t *fh, char *board) { + FILE *foo; + + if((foo = fopen("innd/out.bntp", "a"))) { + fprintf(foo, "%s\t%s\t%s\t%s\t%s\n", board, + fh->filename, cuser.userid, cuser.username, fh->title); + fclose(foo); + } +} + +extern char *str_author1; +extern char *str_author2; + +static void cancelpost(fileheader_t *fh, int by_BM) { + FILE *fin, *fout; + char *ptr, *brd; + fileheader_t postfile; + char genbuf[200]; + char nick[STRLEN], fn1[STRLEN], fn2[STRLEN]; + + setbfile(fn1, currboard, fh->filename); + if((fin = fopen(fn1, "r"))) { + brd = by_BM ? "deleted" : "junk"; + + setbpath(fn2, brd); + stampfile(fn2, &postfile); + memcpy(postfile.owner, fh->owner, IDLEN + TTLEN + 10); + postfile.savemode = 'D'; + + if(fh->savemode == 'S') { + 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, '('))) + strcpy(nick, ptr + 1); + break; + } + } + + 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); + Rename(fn1, fn2); + setbdir(genbuf, brd); + append_record(genbuf, &postfile, sizeof(postfile)); + } +} + +extern char *str_reply; +extern char save_title[]; + +/* ----------------------------------------------------- */ +/* µoªí¡B¦^À³¡B½s¿è¡BÂà¿ý¤å³¹ */ +/* ----------------------------------------------------- */ +void do_reply_title(int row, char *title) { + char genbuf[200]; + char genbuf2[4]; + + if(strncasecmp(title, str_reply, 4)) + sprintf(save_title, "Re: %s", title); + else + strcpy(save_title, title); + save_title[TTLEN - 1] = '\0'; + sprintf(genbuf, "±Ä¥Îì¼ÐÃD¡m%.60s¡n¶Ü?[Y] ", save_title); + getdata(row, 0, genbuf, genbuf2, 4, LCECHO); + if(genbuf2[0] == 'n' || genbuf2[0] == 'N') + getdata(++row, 0, "¼ÐÃD¡G", save_title, TTLEN, DOECHO); +} + +static void do_unanonymous_post(char* fpath) { + fileheader_t mhdr; + char title[128]; + char genbuf[200]; + + setbpath(genbuf, "UnAnonymous"); + if(dashd(genbuf)) { + stampfile(genbuf, &mhdr); + unlink(genbuf); + Link(fpath, genbuf); + strcpy(mhdr.owner, cuser.userid); + strcpy(mhdr.title, save_title); + mhdr.savemode = 0; + mhdr.filemode = 0; + setbdir(title, "UnAnonymous"); + append_record(title, &mhdr, sizeof(mhdr)); + } +} + +extern char quote_file[]; +extern char quote_user[]; +extern int curredit; +extern unsigned int currbrdattr; +extern char currdirect[]; +extern char *err_uid; + +#ifdef NO_WATER_POST +static time_t last_post_time = 0; +static time_t water_counts = 0; +#endif +int local_article; +char real_name[20]; + +static int do_general() { + fileheader_t postfile; + char fpath[80], buf[80]; + int aborted, defanony, ifuseanony; + char genbuf[200],*owner; + boardheader_t *bp; + int islocal; + + ifuseanony = 0; + bp = getbcache(currbid); + + clear(); + if(!(currmode & MODE_POST)) { + move(5, 10); + outs("¹ï¤£°_¡A±z¥Ø«eµLªk¦b¦¹µoªí¤å³¹¡I"); + pressanykey(); + return FULLUPDATE; + } + +#ifdef NO_WATER_POST + /* ¤T¤ÀÄÁ¤º³Ì¦hµoªí¤½g¤å³¹ */ + if(currutmp->lastact - last_post_time < 60 * 3) { + if(water_counts >= 5) { + move(5, 10); + outs("¹ï¤£°_¡A±zªº¤å³¹¤Ó¤ôÅo¡A¦h«ä¦Ò¤@¤U¡A«Ý·|¦Apost§a¡I"); + pressanykey(); + return FULLUPDATE; + } + } else { + last_post_time = currutmp->lastact; + water_counts = 0; + } +#endif + + setbfile(genbuf, currboard, FN_POST_NOTE ); + + if(more(genbuf,NA) == -1) + more("etc/"FN_POST_NOTE , NA); + + move(19,0); + prints("µoªí¤å³¹©ó¡i\033[33m %s\033[m ¡j \033[32m%s\033[m ¬ÝªO\n\n", + currboard, bp->title + 7); + + if(quote_file[0]) + do_reply_title(20, currtitle); + else { + getdata(21, 0, "¼ÐÃD¡G", save_title, TTLEN, DOECHO); + strip_ansi(save_title,save_title,0); + } + if(save_title[0] == '\0') + return FULLUPDATE; + + curredit &= ~EDIT_MAIL; + curredit &= ~EDIT_ITEM; + setutmpmode(POSTING); + + /* ¥¼¨ã³Æ Internet ÅvªÌ¡A¥u¯à¦b¯¸¤ºµoªí¤å³¹ */ + if(HAS_PERM(PERM_INTERNET)) + local_article = 0; + else + local_article = 1; + + /* build filename */ + setbpath(fpath, currboard); + stampfile(fpath, &postfile); + + aborted = vedit(fpath, YEA, &islocal); + if(aborted == -1) { + unlink(fpath); + pressanykey(); + return FULLUPDATE; + } + water_counts++; /* po¦¨¥\ */ + + /* 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 + /* ¿ú */ + aborted = (aborted > MAX_POST_MONEY * 2) ? MAX_POST_MONEY : aborted / 2; + postfile.money = aborted; + strcpy(postfile.owner, owner); + strcpy(postfile.title, save_title); + if(islocal) { /* local save */ + postfile.savemode = 'L'; + postfile.filemode = FILE_LOCAL; + } else + postfile.savemode = 'S'; + + setbdir(buf, currboard); + if(append_record(buf, &postfile, sizeof(postfile)) != -1) { + setbtotal(currbid); + + if(currmode & MODE_SELECT) + append_record(currdirect,&postfile,sizeof(postfile)); + if(!islocal && !(bp->brdattr & BRD_NOTRAN)) + outgo_post(&postfile, currboard); + brc_addlist(postfile.filename); + + if(!(currbrdattr & BRD_HIDE) && + (!bp->level || (currbrdattr & BRD_POSTMASK))) { + setbpath(genbuf, ALLPOST); + stampfile(genbuf, &postfile); + unlink(genbuf); + + /* jochang: boards may spread across many disk */ + /* link doesn't work across device, + Link doesn't work if we have same-time-across-device posts, + we try symlink now */ + { + /* we need absolute path for symlink */ + char abspath[256]=BBSHOME"/"; + strcat(abspath,fpath); + symlink(abspath,genbuf); + } + strcpy(postfile.owner, owner); + strcpy(postfile.title, save_title); + postfile.savemode = 'L'; + setbdir(genbuf, ALLPOST); + if(append_record(genbuf, &postfile, sizeof(postfile)) != -1) { + setbtotal(getbnum(ALLPOST)); + } + } + + outs("¶¶§Q¶K¥X§G§i¡A"); + +#ifdef MAX_POST_MONEY + aborted = (aborted > MAX_POST_MONEY) ? MAX_POST_MONEY : aborted; +#endif + if(strcmp(currboard, "Test") && !ifuseanony) { + prints("³o¬O±zªº²Ä %d ½g¤å³¹¡C ½Z¹S %d »È¡C", + ++cuser.numposts, aborted ); + demoney(aborted); + passwd_update(usernum, &cuser); /* post ¼Æ */ + } else + outs("´ú¸Õ«H¥ó¤£¦C¤J¬ö¿ý¡A·q½Ð¥]²[¡C"); + + /* ¦^À³¨ìì§@ªÌ«H½c */ + + if(curredit & EDIT_BOTH) { + char *str, *msg = "¦^À³¦Ü§@ªÌ«H½c"; + + if((str = strchr(quote_user, '.'))) { + if( +#ifndef USE_BSMTP + bbs_sendmail(fpath, save_title, str + 1) +#else + bsmtp(fpath, save_title, str + 1 ,0) +#endif + < 0) + msg = "§@ªÌµLªk¦¬«H"; + } else { + sethomepath(genbuf, quote_user); + stampfile(genbuf, &postfile); + unlink(genbuf); + Link(fpath, genbuf); + + strcpy(postfile.owner, cuser.userid); + strcpy(postfile.title, save_title); + postfile.savemode = 'B';/* both-reply flag */ + sethomedir(genbuf, quote_user); + if(append_record(genbuf, &postfile, sizeof(postfile)) == -1) + msg = err_uid; + } + outs(msg); + curredit ^= EDIT_BOTH; + } + if(currbrdattr & BRD_ANONYMOUS) + do_unanonymous_post(fpath); + } + pressanykey(); + return FULLUPDATE; +} + +int do_post() { + boardheader_t *bp; + bp = getbcache(currbid); + if(bp->brdattr & BRD_VOTEBOARD) + return do_voteboard(); + else if(!(bp->brdattr & BRD_GROUPBOARD)) + return do_general(); + touchdircache(currbid); + return 0; +} + +extern int b_lines; +extern int curredit; + +static void do_generalboardreply(fileheader_t *fhdr){ + char genbuf[200]; + getdata(b_lines - 1, 0, + "¡¶ ¦^À³¦Ü (F)¬ÝªO (M)§@ªÌ«H½c (B)¤GªÌ¬Ò¬O (Q)¨ú®ø¡H[F] ", + genbuf, 3, LCECHO); + switch(genbuf[0]) { + case 'm': + mail_reply(0, fhdr, 0); + case 'q': + break; + + case 'b': + curredit = EDIT_BOTH; + default: + strcpy(currtitle, fhdr->title); + strcpy(quote_user, fhdr->owner); + quote_file[79] = fhdr->savemode; + do_post(); + } + *quote_file = 0; +} + +int getindex(char *fpath, char *fname, int size) { + int fd, now=0; + fileheader_t fhdr; + + if((fd = open(fpath, O_RDONLY, 0)) != -1) { + while((read(fd, &fhdr, size) == size)) { + now++; + if(!strcmp(fhdr.filename,fname)) { + close(fd); + return now; + } + } + close(fd); + } + return 0; +} + +int invalid_brdname(char *brd) { + register char ch; + + ch = *brd++; + if(not_alnum(ch)) + return 1; + while((ch = *brd++)) { + if(not_alnum(ch) && ch != '_' && ch != '-' && ch != '.') + return 1; + } + return 0; +} + +static void do_reply(fileheader_t *fhdr) { + boardheader_t *bp; + bp = getbcache(currbid); + if (bp->brdattr & BRD_VOTEBOARD) + do_voteboardreply(fhdr); + else + do_generalboardreply(fhdr); +} + +static int reply_post(int ent, fileheader_t *fhdr, char *direct) { + if(!(currmode & MODE_POST)) + return DONOTHING; + + setdirpath(quote_file, direct, fhdr->filename); + do_reply(fhdr); + *quote_file = 0; + return FULLUPDATE; +} + +static int edit_post(int ent, fileheader_t *fhdr, char *direct) { + char fpath[80], fpath0[80]; + char genbuf[200]; + fileheader_t postfile; + boardheader_t *bp; + bp = getbcache(currbid); + if (!HAS_PERM(PERM_SYSOP) && (bp->brdattr & BRD_VOTEBOARD)) + return DONOTHING; + + if ((!HAS_PERM(PERM_SYSOP)) && + strcmp(fhdr->owner, cuser.userid)) + return DONOTHING; + setutmpmode(REEDIT); + setdirpath(genbuf, direct, fhdr->filename); + local_article = fhdr->filemode & FILE_LOCAL; + strcpy(save_title, fhdr->title); + +/* rocker.011018: ³o¸Ì¬O¤£¬O¸ÓÀˬd¤@¤Uקï¤å³¹«áªºmoney©M즳ªº¤ñ¸û? */ + if(vedit(genbuf, 0, NULL) != -1) { + setbpath(fpath, currboard); + stampfile(fpath, &postfile); + unlink(fpath); + setbfile(fpath0, currboard, fhdr->filename); + + Rename(fpath0, fpath); + +/* rocker.011018: fix ¦ê±µ¼Ò¦¡§ï¤å³¹«á¤å³¹´N¤£¨£ªºbug */ + if ((currmode & MODE_SELECT) && (fhdr->money & FHR_REFERENCE)) + { + fileheader_t hdr; + int num; + + num = fhdr->money & ~FHR_REFERENCE; + setbdir(fpath0, currboard); + get_record(fpath0, &hdr, sizeof (hdr), num); + + /* ¦A³o¸Ìncheck¤@¤Uì¨Óªºdir¸Ì±¬O¤£¬O¦³³Q¤H°Ê¹L... */ + if (!strcmp (hdr.filename, fhdr->filename)) + { + strcpy(hdr.filename, postfile.filename); + strcpy(hdr.title, save_title); + substitute_record(fpath0, &hdr, sizeof(hdr), num); + } + } + + strcpy(fhdr->filename, postfile.filename); + strcpy(fhdr->title, save_title); + brc_addlist(postfile.filename); + substitute_record(direct, fhdr, sizeof(*fhdr), ent); +/* rocker.011018: ¶¶«K§ó·s¤@¤Ucache */ + touchdircache(currbid); + } + return FULLUPDATE; +} + +extern crosspost_t postrecord; +#define UPDATE_USEREC (currmode |= MODE_DIRTY) + +static int cross_post(int ent, fileheader_t *fhdr, 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]; + boardheader_t *bp; + make_blist(); + move(2, 0); + clrtoeol(); + move(3, 0); + clrtoeol(); + move(1, 0); + bp = getbcache(currbid); + if (bp && (bp->brdattr & BRD_VOTEBOARD)) + return FULLUPDATE; + namecomplete("Âà¿ý¥»¤å³¹©ó¬ÝªO¡G", xboard); + if(*xboard == '\0' || !haspostperm(xboard)) + return FULLUPDATE; + + if((ent = str_checksum(fhdr->title)) != 0 && + ent == postrecord.checksum[0]) { + /* Àˬd cross post ¦¸¼Æ */ + if(postrecord.times++ > MAX_CROSSNUM) + anticrosspost(); + } else { + postrecord.times = 0; + postrecord.checksum[0] = ent; + } + + ent = 1; + if(HAS_PERM(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) + sprintf(xtitle, "[Âà¿ý]%.66s", fhdr->title); + else + strcpy(xtitle, fhdr->title); + + sprintf(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)) + strcpy(xtitle, genbuf); + } + + 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) + strcpy(xfile.owner, fhdr->owner); + else + strcpy(xfile.owner, cuser.userid); + strcpy(xfile.title, xtitle); + if(genbuf[0] == 'l') { + xfile.savemode = 'L'; + xfile.filemode = FILE_LOCAL; + } else + xfile.savemode = 'S'; + + setbfile(fname, currboard, fhdr->filename); +// if(ent) { + xptr = fopen(xfpath, "w"); + + strcpy(save_title, xfile.title); + strcpy(xfpath, currboard); + strcpy(currboard, xboard); + write_header(xptr); + strcpy(currboard, xfpath); + + fprintf(xptr, "¡° [¥»¤åÂà¿ý¦Û %s ¬ÝªO]\n\n", currboard); + + b_suckinfile(xptr, fname); + addsignature(xptr,0); + fclose(xptr); +/* Cross fs¦³°ÝÃD + } else { + unlink(xfpath); + link(fname, xfpath); + } +*/ + setbdir(fname, xboard); + append_record(fname, &xfile, sizeof(xfile)); + bp = getbcache(getbnum(xboard)); + if(!xfile.filemode && !(bp->brdattr && BRD_NOTRAN)) + outgo_post(&xfile, xboard); + setbtotal(getbnum(xboard)); + cuser.numposts++; + UPDATE_USEREC; + outs("¤å³¹Âà¿ý§¹¦¨"); + pressanykey(); + currmode = currmode0; + } + return FULLUPDATE; +} + +static int read_post(int ent, fileheader_t *fhdr, char *direct) { + char genbuf[200]; + int more_result; + + if(fhdr->owner[0] == '-') + return DONOTHING; + + setdirpath(genbuf, direct, fhdr->filename); + + if((more_result = more(genbuf, YEA)) == -1) + return DONOTHING; + + brc_addlist(fhdr->filename); + strncpy(currtitle, subject(fhdr->title), 40); + strncpy(currowner, subject(fhdr->owner), IDLEN + 2); + + switch (more_result) { + case 1: + return READ_PREV; + case 2: + return RELATE_PREV; + case 3: + return READ_NEXT; + case 4: + return RELATE_NEXT; + case 5: + return RELATE_FIRST; + case 6: + return FULLUPDATE; + case 7: + case 8: + if((currmode & MODE_POST)) { + strcpy(quote_file, genbuf); + do_reply(fhdr); + *quote_file = 0; + } + return FULLUPDATE; + case 9: + return 'A'; + case 10: + return 'a'; + case 11: + return '/'; + case 12: + return '?'; + } + + + outmsg("\033[34;46m ¾\\Ū¤å³¹ \033[31;47m (R/Y)\033[30m¦^«H \033[31m" + "(=[]<>)\033[30m¬ÛÃö¥DÃD \033[31m(¡ô¡õ)\033[30m¤W¤U«Ê \033[31m(¡ö)" + "\033[30mÂ÷¶} \033[m"); + + switch(egetch()) { + case 'q': + case 'Q': + case KEY_LEFT: + break; + + case ' ': + case KEY_RIGHT: + case KEY_DOWN: + case KEY_PGDN: + case 'n': + case Ctrl('N'): + return READ_NEXT; + + case KEY_UP: + case 'p': + case Ctrl('P'): + case KEY_PGUP: + return READ_PREV; + + case '=': + return RELATE_FIRST; + + case ']': + case 't': + return RELATE_NEXT; + + case '[': + return RELATE_PREV; + + case '.': + case '>': + return THREAD_NEXT; + + case ',': + case '<': + return THREAD_PREV; + + case Ctrl('C'): + cal(); + return FULLUPDATE; + break; + + case Ctrl('I'): + t_idle(); + return FULLUPDATE; + case 'y': + case 'r': + case 'R': + case 'Y': + if((currmode & MODE_POST)) { + strcpy(quote_file, genbuf); + do_reply(fhdr); + *quote_file = 0; + } + } + return FULLUPDATE; +} + +/* ----------------------------------------------------- */ +/* ±Ä¶°ºëµØ°Ï */ +/* ----------------------------------------------------- */ +static int b_man() { + char buf[64]; + + setapath(buf, currboard); + if( (currmode & MODE_BOARD) || HAS_PERM(PERM_SYSOP) ){ + char genbuf[128]; + int fd; + sprintf(genbuf, "%s/.rebuild", buf); + if( (fd = open(genbuf, O_CREAT, 0640)) > 0 ) + close(fd); + } + return a_menu(currboard, buf, HAS_PERM(PERM_ALLBOARD) ? 2 : + (currmode & MODE_BOARD ? 1 : 0)); +} + +#ifndef NO_GAMBLE +static int join_gamble(int ent, fileheader_t *fhdr, char *direct) { + ticket(currbid); + return FULLUPDATE; +} +static int hold_gamble(int ent, fileheader_t *fhdr, char *direct) { + char fn_ticket[128],fn_ticket_end[128],genbuf[128], + msg[256]="",yn[10]=""; + int i; + FILE *fp=NULL; + + if(!(currmode & MODE_BOARD)) return 0; + setbfile(fn_ticket, currboard, FN_TICKET); + setbfile(fn_ticket_end, currboard, FN_TICKET_END); + 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); + return FULLUPDATE; + } + + if(dashf(fn_ticket_end)) + { + getdata(b_lines - 1, 0, "¤w¸g¦³Á|¿ì½ä½L, " + "¬O§_n [¶}¼ú]?(N/y)¡G", yn, 3, LCECHO); + if(yn[0]!='y') return FULLUPDATE; + openticket(currbid); + 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(genbuf, currboard, FN_TICKET_ITEMS); + +// sprintf(genbuf, "%s/"FN_TICKET_ITEMS, direct); + + if(!(fp=fopen(genbuf,"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); + move(3,0); + sprintf(genbuf,"½Ð¨ì %s ª© «ö'f'°Ñ»P½ä³Õ!\n\n¤@±i %d Ptt¹ô, ³o¬O%sªº½ä³Õ\n", + currboard, + i, i<100 ? "¤p½ä¦¡" : i<500 ? "¥¥Á¯Å": + i<1000 ?"¶Q±Ú¯Å" : i<5000 ?"´I»¨¯Å" : "¶É®a¿º²£"); + strcat(msg, genbuf); + prints("½Ð¨Ì¦¸¿é¤J±m²¼¦WºÙ, »Ý´£¨Ñ2~8¶µ. (¥¼º¡¤K¶µ, ¿é¤Jª½±µ«öenter)\n"); + for(i=0; i<8; i++) + { + sprintf(yn, " %d)",i+1); + getdata(6+i, 0, yn, genbuf, 9, DOECHO); + if(!genbuf[0] && i>1) + break; + fprintf(fp,"%s\n",genbuf); + } + fclose(fp); + move(8+i,0); + prints("½ä½L³]©w§¹¦¨"); + sprintf(genbuf,"[¤½§i] %s ª© ¶}©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¨Ó + + return FULLUPDATE; +} +#endif + +static int cite_post(int ent, fileheader_t *fhdr, char *direct) { + char fpath[256]; + char title[TTLEN + 1]; + + setbfile(fpath, currboard, fhdr->filename); + strcpy(title, "¡º "); + strncpy(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, char *direct) { + char genbuf[200]; + fileheader_t tmpfhdr = *fhdr; + int dirty = 0; + + if(currmode & MODE_BOARD || !strcmp(cuser.userid,fhdr->owner)) { + if(getdata(b_lines - 1, 0, "¼ÐÃD¡G", genbuf, TTLEN, DOECHO)) { + strcpy(tmpfhdr.title, genbuf); + dirty++; + } + } + + if(HAS_PERM(PERM_SYSOP)) { + if(getdata(b_lines - 1, 0, "§@ªÌ¡G", genbuf, IDLEN + 2, DOECHO)) { + strcpy(tmpfhdr.owner, genbuf); + dirty++; + } + + if(getdata(b_lines - 1, 0, "¤é´Á¡G", genbuf, 6, DOECHO)) { + sprintf(tmpfhdr.date, "%.5s", genbuf); + dirty++; + } + } + + if(currmode & MODE_BOARD || !strcmp(cuser.userid,fhdr->owner)) { + getdata(b_lines-1, 0, "½T©w(Y/N)?[n] ", genbuf, 3, DOECHO); + if((genbuf[0] == 'y' || genbuf[0] == 'Y') && dirty) { + *fhdr = tmpfhdr; + substitute_record(direct, fhdr, sizeof(*fhdr), ent); +/* rocker.011018: ³o¸ÌÀ³¸Ó§ï¦¨¥Îreferenceªº¤è¦¡¨ú±oì¨ÓªºÀÉ®× */ +#if 0 + if((currmode & MODE_SELECT)) { + int now; + + setbdir(genbuf, currboard); + now = getindex(genbuf, fhdr->filename, sizeof(fileheader_t)); + substitute_record(genbuf, fhdr, sizeof(*fhdr), now); + } +#else + if ((currmode & MODE_SELECT) && (fhdr->money & FHR_REFERENCE)) + { + fileheader_t hdr; + int num; + + num = fhdr->money & ~FHR_REFERENCE; + setbdir(genbuf, currboard); + get_record(genbuf, &hdr, sizeof (hdr), num); + + /* ¦A³o¸Ìncheck¤@¤Uì¨Óªºdir¸Ì±¬O¤£¬O¦³³Q¤H°Ê¹L... */ + if (strcmp (hdr.filename, fhdr->filename)) + num = getindex(genbuf, fhdr->filename, sizeof(fileheader_t)); + + substitute_record(genbuf, fhdr, sizeof(*fhdr), num); + } +#endif + touchdircache(currbid); + } + return FULLUPDATE; + } + return DONOTHING; +} + +extern unsigned int currstat; + +static int solve_post(int ent, fileheader_t * fhdr, char *direct){ + if (HAS_PERM(PERM_SYSOP)) { + fhdr->filemode ^= FILE_SOLVED; + substitute_record(direct, fhdr, sizeof(*fhdr), ent); + touchdircache(currbid); + return PART_REDRAW; + } + return DONOTHING; +} + +static int mark_post(int ent, fileheader_t *fhdr, char *direct) { + + if(!(currmode & MODE_BOARD)) return DONOTHING; + + fhdr->filemode ^= FILE_MARKED; + substitute_record(direct, fhdr, sizeof(*fhdr), ent); + + /* rocker.011018: ¦ê±µ¼Ò¦¡¥Îreference¼W¶i®Ä²v */ + if ((currmode & MODE_SELECT) && (fhdr->money & FHR_REFERENCE)) + { + fileheader_t hdr; + char genbuf[100]; + int num; + + num = fhdr->money & ~FHR_REFERENCE; + setbdir(genbuf, currboard); + get_record(genbuf, &hdr, sizeof (hdr), num); + + /* ¦A³o¸Ìncheck¤@¤Uì¨Óªºdir¸Ì±¬O¤£¬O¦³³Q¤H°Ê¹L... */ + if (strcmp (hdr.filename, fhdr->filename)) + num = getindex(genbuf, fhdr->filename, sizeof(fileheader_t)); + + substitute_record(genbuf, fhdr, sizeof(*fhdr), num); + } + touchdircache(currbid); + return PART_REDRAW; +} + +extern char *msg_sure_ny; + +int del_range(int ent, fileheader_t *fhdr, char *direct) { + char num1[8], num2[8]; + int inum1, inum2; + +/* rocker.011018: ¦ê±µ¼Ò¦¡¤UÁÙ¬O¤£¤¹³\§R°£¤ñ¸û¦n */ + if(currmode & MODE_SELECT) { + outmsg("½Ð¥ý¦^¨ì¥¿±`¼Ò¦¡«á¦A¶i¦æ§R°£..."); + refresh(); + /*safe_sleep(1);*/ + return FULLUPDATE; + } + + if((currstat != READING) || (currmode & MODE_BOARD)) { + getdata(1, 0, "[³]©w§R°£½d³ò] °_ÂI¡G", num1, 5, DOECHO); + inum1 = atoi(num1); + if(inum1 <= 0) { + outmsg("°_ÂI¦³»~"); + refresh(); + /*safe_sleep(1);*/ + return FULLUPDATE; + } + getdata(1, 28, "²×ÂI¡G", num2, 5, DOECHO); + inum2 = atoi(num2); + if(inum2 < inum1) { + outmsg("²×ÂI¦³»~"); + refresh(); + /*safe_sleep(1);*/ + return FULLUPDATE; + } + getdata(1, 48, msg_sure_ny, num1, 3, LCECHO); + if(*num1 == 'y') { + outmsg("³B²z¤¤,½Ðµy«á..."); + refresh(); + if(currmode & MODE_SELECT) { + int fd,size = sizeof(fileheader_t); + char genbuf[100]; + fileheader_t rsfh; + int i = inum1,now; + if(currstat == RMAIL) + sethomedir(genbuf, cuser.userid); + else + setbdir(genbuf,currboard); + if((fd = (open(direct, O_RDONLY, 0))) != -1) { + if(lseek(fd, (off_t)(size * (inum1 - 1)), SEEK_SET) != + -1) { + while(read(fd,&rsfh,size) == size) { + if(i > inum2) + break; + now = getindex(genbuf, rsfh.filename, size); + strcpy(currfile, rsfh.filename); + delete_file(genbuf, sizeof(fileheader_t), now, + cmpfilename); + i++; + } + } + close(fd); + } + } + + delete_range(direct, inum1, inum2); + fixkeep(direct, inum1); + + if(currmode & MODE_BOARD) + setbtotal(currbid); + + return DIRCHANGED; + } + return FULLUPDATE; + } + return DONOTHING; +} + +extern char *msg_del_ny; +extern char *msg_del_ok; + +static int del_post(int ent, fileheader_t *fhdr, char *direct) { + char genbuf[100]; + int not_owned; + boardheader_t *bp; + + bp = getbcache(currbid); + + if((fhdr->filemode & FILE_MARKED) || (fhdr->filemode & FILE_DIGEST) || + (fhdr->owner[0] == '-')) + return DONOTHING; + + not_owned = strcmp(fhdr->owner, cuser.userid); + if((!(currmode & MODE_BOARD) && not_owned) || + ((bp->brdattr & BRD_VOTEBOARD) && !HAS_PERM(PERM_SYSOP)) || + !strcmp(cuser.userid, STR_GUEST)) + return DONOTHING; + + getdata(1, 0, msg_del_ny, genbuf, 3, LCECHO); + if(genbuf[0] == 'y' || genbuf[0] == 'Y') { + strcpy(currfile, fhdr->filename); + + setbfile(genbuf,currboard,fhdr->filename); + if(!delete_file (direct, sizeof(fileheader_t), ent, cmpfilename)) { + + if(currmode & MODE_SELECT) + { + /* rocker.011018: §Q¥Îreference´î§Cloading */ + fileheader_t hdr; + int num; + + num = fhdr->money & ~FHR_REFERENCE; + setbdir(genbuf, currboard); + get_record(genbuf, &hdr, sizeof (hdr), num); + + /* ¦A³o¸Ìncheck¤@¤Uì¨Óªºdir¸Ì±¬O¤£¬O¦³³Q¤H°Ê¹L... */ + if (strcmp (hdr.filename, fhdr->filename)) + { + num=getindex(genbuf,fhdr->filename,sizeof(fileheader_t)); + get_record(genbuf, &hdr, sizeof (hdr), num); + } + + /* rocker.011018: ³o¸ÌnÁÙì³Q¯}Ãaªºmoney */ + fhdr->money = hdr.money; + delete_file (genbuf, sizeof(fileheader_t), num, cmpfilename); + } + +#if 0 + { + setbdir(genbuf,currboard); + now=getindex(genbuf,fhdr->filename,sizeof(fileheader_t)); + delete_file (genbuf, sizeof(fileheader_t),now,cmpfilename); + } +#endif + cancelpost(fhdr, not_owned); + + setbtotal(currbid); + if (fhdr->money < 0) + fhdr->money = 0; + if (not_owned && strcmp(currboard, "Test")){ + deumoney(searchuser(fhdr->owner), -fhdr->money); + } + if(!not_owned && strcmp(currboard, "Test")) { + if(cuser.numposts) + cuser.numposts--; + move(b_lines - 1, 0); + clrtoeol(); + demoney(-fhdr->money); + passwd_update(usernum, &cuser); /* post ¼Æ */ + prints("%s¡A±zªº¤å³¹´î¬° %d ½g¡A¤ä¥I²M¼ä¶O %d »È", msg_del_ok, + cuser.numposts,fhdr->money); + refresh(); + pressanykey(); + } + return DIRCHANGED; + } + } + return FULLUPDATE; +} + +static int view_postmoney(int ent, fileheader_t *fhdr, char *direct) { + move(b_lines - 1, 0); + clrtoeol(); + prints("³o¤@½g¤å³¹È %d »È", fhdr->money); + refresh(); + pressanykey(); + return FULLUPDATE; +} + +#ifdef OUTJOBSPOOL +/* ¬Ýª©³Æ¥÷ */ +static int tar_addqueue(int ent, fileheader_t *fhdr, char *direct) { + char email[60], qfn[80], ans[2]; + FILE *fp; + char bakboard, bakman; + clear(); + showtitle("¬Ýª©³Æ¥÷", BBSNAME); + move(2, 0); + if( !((currmode & MODE_BOARD) || HAS_PERM(PERM_SYSOP)) ) { + move(5, 10); + outs("©pn¬Oª©¥D©Î¬O¯¸ªø¤~¯àÂæÂæ°Ú -.-\"\""); + pressanykey(); + return FULLUPDATE; + } + + sprintf(qfn, BBSHOME "/jobspool/tarqueue.%s", currboard); + if( access(qfn, 0) == 0 ){ + outs("¤w¸g±Æ©w¦æµ{, µy«á·|¶i¦æ³Æ¥÷"); + pressanykey(); + return FULLUPDATE; + } + 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; + } + + getdata(6, 0, "n³Æ¥÷¬Ýª©¤º®e¶Ü(Y/N)?[Y]", ans, 2, LCECHO); + bakboard = (ans[0] == 'n' || ans[0] =='N') ? 0 : 1; + getdata(7, 0, "n³Æ¥÷ºëµØ°Ï¤º®e¶Ü(Y/N)?[N]", ans, 2, LCECHO); + bakman = (ans[0] == 'y' || ans[0] =='Y') ? 1 : 0; + if( !bakboard && !bakman ){ + move(8, 0); + outs("¥i¬O§ÚÌ¥u¯à³Æ¥÷¬Ýª©©ÎºëµØ°Ïªº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 + +static int sequent_ent; +static int continue_flag; + +/* ----------------------------------------------------- */ +/* ¨Ì§ÇŪ·s¤å³¹ */ +/* ----------------------------------------------------- */ +static int sequent_messages(fileheader_t *fptr) { + static int idc; + char genbuf[200]; + + if(fptr == NULL) + return (idc = 0); + + if(++idc < sequent_ent) + return 0; + + if(!brc_unread(fptr->filename,brc_num,brc_list)) + return 0; + + if(continue_flag) + genbuf[0] = 'y'; + else { + prints("Ū¨ú¤å³¹©ó¡G[%s] §@ªÌ¡G[%s]\n¼ÐÃD¡G[%s]", + currboard, fptr->owner, fptr->title); + getdata(3, 0, "(Y/N/Quit) [Y]: ", genbuf, 3, LCECHO); + } + + if(genbuf[0] != 'y' && genbuf[0]) { + clear(); + return (genbuf[0] == 'q' ? QUIT : 0); + } + + setbfile(genbuf, currboard, fptr->filename); + brc_addlist(fptr->filename); + + if(more(genbuf, YEA) == 0) + outmsg("\033[31;47m \033[31m(R)\033[30m¦^«H \033[31m(¡õ,n)" + "\033[30m¤U¤@«Ê \033[31m(¡ö,q)\033[30mÂ÷¶} \033[m"); + continue_flag = 0; + + switch(egetch()) { + case KEY_LEFT: + case 'e': + case 'q': + case 'Q': + break; + + case 'y': + case 'r': + case 'Y': + case 'R': + if(currmode & MODE_POST) { + strcpy(quote_file, genbuf); + do_reply(fptr); + *quote_file = 0; + } + break; + + case ' ': + case KEY_DOWN: + case '\n': + case 'n': + continue_flag = 1; + } + + clear(); + return 0; +} + +static int sequential_read(int ent, fileheader_t *fhdr, char *direct) { + char buf[40]; + + clear(); + sequent_messages((fileheader_t *) NULL); + sequent_ent = ent; + continue_flag = 0; + setbdir(buf, currboard); + apply_record(buf, sequent_messages, sizeof(fileheader_t)); + return FULLUPDATE; +} + +extern char *fn_notes; +extern char *msg_cancel; +extern char *fn_board; + +/* ----------------------------------------------------- */ +/* ¬ÝªO³Æ§Ñ¿ý¡B¤åºK¡BºëµØ°Ï */ +/* ----------------------------------------------------- */ +int b_note_edit_bname(int bid) { + char buf[64]; + int aborted; + boardheader_t *fh=getbcache(bid); + + setbfile(buf, fh->brdname, fn_notes); + aborted = vedit(buf, NA, NULL); + if(aborted == -1) { + clear(); + outs(msg_cancel); + pressanykey(); + } else { + aborted = (fh->bupdate - time(0)) / 86400 + 1; + sprintf(buf,"%d", aborted > 0 ? aborted : 0); + getdata_buf(3, 0, "½Ð³]©w¦³®Ä´Á(0 - 9999)¤Ñ¡H", buf, 5, DOECHO); + aborted = atoi(buf); + fh->bupdate = aborted ? time(0) + aborted * 86400 : 0; + substitute_record(fn_board, fh, sizeof(boardheader_t), bid); + } + return 0; +} + +static int b_notes_edit() { + if(currmode & MODE_BOARD) { + b_note_edit_bname(currbid); + return FULLUPDATE; + } + return 0; +} + +static int b_water_edit() { + if(currmode & MODE_BOARD) { + friend_edit(BOARD_WATER); + return FULLUPDATE; + } + return 0; +} + +static int visable_list_edit() { + if(currmode & MODE_BOARD) { + friend_edit(BOARD_VISABLE); + hbflreload(currbid); + return FULLUPDATE; + } + return 0; +} + +static int b_post_note() { + char buf[200], yn[3]; + + if(currmode & MODE_BOARD) { + setbfile(buf, currboard, FN_POST_NOTE ); + if(more(buf,NA) == -1) more("etc/"FN_POST_NOTE , NA); + getdata(b_lines - 2, 0, "¬O§_n¥Î¦Ûqpostª`·N¨Æ¶µ?", yn, 3, LCECHO); + if(yn[0] == 'y') + vedit(buf, NA, NULL); + else + unlink(buf); + return FULLUPDATE; + } + return 0; +} + +static int b_application() { + char buf[200]; + + if(currmode & MODE_BOARD) { + setbfile(buf, currboard, FN_APPLICATION); + vedit(buf, NA, NULL); + return FULLUPDATE; + } + return 0; +} + +static int can_vote_edit() { + if(currmode & MODE_BOARD) { + friend_edit(FRIEND_CANVOTE); + return FULLUPDATE; + } + return 0; +} + +static int bh_title_edit() { + boardheader_t *bp; + + if(currmode & MODE_BOARD) { + char genbuf[BTLEN]; + + 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,0); + strcpy(bp->title + 7,genbuf); + substitute_record(fn_board, bp, sizeof(boardheader_t), currbid); + log_usies("SetBoard", currboard); + return FULLUPDATE; + } + return 0; +} + +static int b_notes() { + char buf[64]; + + setbfile(buf, currboard, fn_notes); + if(more(buf, NA) == -1) { + clear(); + move(4, 20); + outs("¥»¬ÝªO©|µL¡u³Æ§Ñ¿ý¡v¡C"); + } + pressanykey(); + return FULLUPDATE; +} + +int board_select() { + char fpath[80]; + char genbuf[100]; + + currmode &= ~MODE_SELECT; + sprintf(fpath, "SR.%s", cuser.userid); + setbfile(genbuf, currboard, fpath); + unlink(genbuf); + if(currstat == RMAIL) + sethomedir(currdirect, cuser.userid); + else + setbdir(currdirect, currboard); + return NEWDIRECT; +} + +int board_digest() { + if(currmode & MODE_SELECT) + board_select(); + currmode ^= MODE_DIGEST; + if(currmode & MODE_DIGEST) + currmode &= ~MODE_POST; + else if (haspostperm(currboard)) + currmode |= MODE_POST; + + setbdir(currdirect, currboard); + return NEWDIRECT; +} + +int board_etc() { + if(!HAS_PERM(PERM_SYSOP)) + return DONOTHING; + currmode ^= MODE_ETC; + if(currmode & MODE_ETC) + currmode &= ~MODE_POST; + else if(haspostperm(currboard)) + currmode |= MODE_POST; + + setbdir(currdirect, currboard); + return NEWDIRECT; +} + +extern char *fn_mandex; + +static int good_post(int ent, fileheader_t *fhdr, char *direct) { + char genbuf[200]; + char genbuf2[200]; + int delta = 0; + + if((currmode & MODE_DIGEST) || !(currmode & MODE_BOARD)) + return DONOTHING; + + if(fhdr->filemode & FILE_DIGEST) { + fhdr->filemode = (fhdr->filemode & ~FILE_DIGEST); + if(!strcmp(currboard,"Note") || !strcmp(currboard,"PttBug") || + !strcmp(currboard,"Artdsn") || !strcmp(currboard, "PttLaw")) { + deumoney(searchuser(fhdr->owner),-1000); + if(!(currmode & MODE_SELECT)) + fhdr->money -= 1000; + else + delta = -1000; + } + } else { + fileheader_t digest; + char *ptr, buf[64]; + + memcpy(&digest, fhdr, sizeof(digest)); + digest.filename[0] = 'G'; + strcpy(buf, direct); + ptr = strrchr(buf, '/') + 1; + ptr[0] = '\0'; + sprintf(genbuf, "%s%s", buf, digest.filename); + + if(dashf(genbuf)) unlink (genbuf); + + digest.savemode = digest.filemode = 0; + sprintf(genbuf2, "%s%s", buf, fhdr->filename); + Link(genbuf2, genbuf); + strcpy(ptr, fn_mandex); + append_record(buf, &digest, sizeof(digest)); + + fhdr->filemode = (fhdr->filemode & ~FILE_MARKED) | FILE_DIGEST; + if(!strcmp(currboard, "Note") || !strcmp(currboard, "PttBug") || + !strcmp(currboard,"Artdsn") || !strcmp(currboard, "PttLaw")) { + deumoney(searchuser(fhdr->owner), 1000); + if(!(currmode & MODE_SELECT)) fhdr->money += 1000; + else delta = 1000; + } + } + substitute_record(direct, fhdr, sizeof(*fhdr), ent); + touchdircache(currbid); +/* rocker.011018: ¦ê±µ¼Ò¦¡¥Îreference¼W¶i®Ä²v */ + if ((currmode & MODE_SELECT) && (fhdr->money & FHR_REFERENCE)) + { + fileheader_t hdr; + char genbuf[100]; + int num; + + num = fhdr->money & ~FHR_REFERENCE; + setbdir(genbuf, currboard); + get_record(genbuf, &hdr, sizeof (hdr), num); + + /* ¦A³o¸Ìncheck¤@¤Uì¨Óªºdir¸Ì±¬O¤£¬O¦³³Q¤H°Ê¹L... */ + if (strcmp (hdr.filename, fhdr->filename)) + { + num = getindex(genbuf, fhdr->filename, sizeof(fileheader_t)); + get_record(genbuf, &hdr, sizeof (hdr), num); + } + fhdr->money = hdr.money + delta; + + substitute_record(genbuf, fhdr, sizeof(*fhdr), num); + } +#if 0 + if(currmode & MODE_SELECT) { + int now; + char genbuf[100]; + + setbdir(genbuf, currboard); + now=getindex(genbuf, fhdr->filename, sizeof(fileheader_t)); + substitute_record(genbuf, fhdr, sizeof(*fhdr), now); + } +#endif + return PART_REDRAW; +} + +/* help for board reading */ +static char *board_help[] = { + "\0¥þ¥\\¯à¬ÝªO¾Þ§@»¡©ú", + "\01°ò¥»©R¥O", + "(p)(¡ô) ¤W²¾¤@½g¤å³¹ (^P) µoªí¤å³¹", + "(n)(¡õ) ¤U²¾¤@½g¤å³¹ (d) §R°£¤å³¹", + "(P)(PgUp) ¤W²¾¤@¶ (S) ¦ê³s¬ÛÃö¤å³¹", + "(N)(PgDn) ¤U²¾¤@¶ (##) ¸õ¨ì ## ¸¹¤å³¹", + "(r)(¡÷) ¾\\Ū¦¹½g¤å³¹ ($) ¸õ¨ì³Ì«á¤@½g¤å³¹", + "\01¶i¶¥©R¥O", + "(tab)/z ¤åºK¼Ò¦¡/ºëµØ°Ï (a)(A) §ä´M§@ªÌ", + "(b/f) ®iŪ³Æ§Ñ¿ý/°Ñ»P½ä½L (?)(/) §ä´M¼ÐÃD", + "(V/R) §ë²¼/¬d¸ß§ë²¼µ²ªG (^W) §Ú¦bþ¸Ì¥i¬Ý¨ì¬ÝªOªº¤ÀÃþ", + "(x) Âà¿ý¤å³¹¨ì¨ä¥L¬ÝªO (=)/([]<>-+) §ä´Mº½g¤å³¹/¥DÃD¦¡¾\\Ū", +#ifdef INTERNET_EMAIL + "(F) ¤å³¹±H¦^Internet¶l½c (U) ±N¤å³¹ uuencode «á±H¦^¶l½c", +#endif + "(E) «½s¤å³¹ (^H) ¦C¥X©Ò¦³ªº New Post(s)", + "\01ªO¥D©R¥O", + "(G) Á|¿ì½ä½L/°±¤î¤Uª`/¶}¼ú(W/w/v) ½s¿è³Æ§Ñ¿ý/¤ô±í¦W³æ/¥i¬Ý¨£¦W³æ", + "(M/o) Á|¦æ§ë²¼/½s¨p§ë²¼¦W³æ (m/c/g) «O¯d¤å³¹/¿ï¿ýºëµØ/¤åºK", + "(D) §R°£¤@¬q½d³òªº¤å³¹ (T/B) «½s¤å³¹¼ÐÃD/«½s¬Ýª©¼ÐÃD", + "(i) ½s¿è¥Ó½Ð¤J·|ªí®æ (t/^D) ¼Ð°O¤å³¹/¬å°£¼Ð°Oªº¤å³¹", + "(O) ½s¿èPostª`·N¨Æ¶µ (H) ¬ÝªOÁôÂÃ/²{¨", + NULL +}; + +static int b_help() { + show_help(board_help); + return FULLUPDATE; +} + +/* ----------------------------------------------------- */ +/* ªO¥D³]©wÁô§Î/ ¸ÑÁô§Î */ +/* ----------------------------------------------------- */ +char board_hidden_status; +#ifdef BMCHS +extern char *fn_board; +static int change_hidden(int ent, fileheader_t *fhdr, char *direct) +{ + boardheader_t bh; + int bid; + char ans[4]; + + if( !((currmode & MODE_BOARD) || HAS_PERM(PERM_SYSOP)) || + currboard[0] == 0 || + (bid = getbnum(currboard)) < 0 || + get_record(fn_board, &bh, sizeof(bh), bid) == -1 ) + return DONOTHING; + + if( ((bh.brdattr & BRD_HIDE) && (bh.brdattr & BRD_POSTMASK)) ){ + getdata(1, 0, "¥Ø«eªO¦bÁô§Îª¬ºA, n¸ÑÁô§Î¹À(Y/N)?[N]", ans, 2, LCECHO); + if( ans[0] != 'y' && ans[0] != 'Y' ) + return FULLUPDATE; + getdata(2, 0, "¦A½T»{¤@¦¸, ¯uªºn§âªOªO¤½¶}¹À @____@(Y/N)?[N]", + ans, 2, LCECHO); + if( ans[0] != 'y' && ans[0] != 'Y' ) + return FULLUPDATE; + if( bh.brdattr & BRD_HIDE ) bh.brdattr -= BRD_HIDE; + if( bh.brdattr & BRD_POSTMASK ) bh.brdattr -= BRD_POSTMASK; + log_usies("OpenBoard", bh.brdname); + outs("§g¤ß¤µ¶Ç²³¤H¡AµL³B¤£»D©¶ºq¡C\n"); + board_hidden_status = 0; + hbflreload(bid); + } + else{ + getdata(1, 0, "¥Ø«eªO¦b²{§Îª¬ºA, nÁô§Î¹À(Y/N)?[N]", ans, 2, LCECHO); + if( ans[0] != 'y' && ans[0] != 'Y' ) + return FULLUPDATE; + bh.brdattr |= BRD_HIDE; + bh.brdattr |= BRD_POSTMASK; + log_usies("CloseBoard", bh.brdname); + outs("§g¤ß¤µ¤w±»§í¡A±©¬ßµ½¦Û¬Ã«¡C\n"); + board_hidden_status = 1; + } + setup_man(&bh); + substitute_record(fn_board, &bh, sizeof(bh), bid); + reset_board(bid); + log_usies("SetBoard", bh.brdname); + pressanykey(); + return FULLUPDATE; +} +#endif + +/* ----------------------------------------------------- */ +/* ¬ÝªO¥\¯àªí */ +/* ----------------------------------------------------- */ +struct onekey_t read_comms[] = { + {KEY_TAB, board_digest}, + {'C', board_etc}, + {'b', b_notes}, + {'c', cite_post}, + {'r', read_post}, + {'z', b_man}, + {'D', del_range}, + {'S', sequential_read}, + {'E', edit_post}, + {'T', edit_title}, + {'s', do_select}, + {'R', b_results}, + {'V', b_vote}, + {'M', b_vote_maintain}, + {'B', bh_title_edit}, + {'W', b_notes_edit}, + {'O', b_post_note}, + {'w', b_water_edit}, + {'v', visable_list_edit}, + {'i', b_application}, + {'o', can_vote_edit}, + {'x', cross_post}, + {'h', b_help}, +#ifndef NO_GAMBLE + {'f', join_gamble}, + {'G', hold_gamble}, +#endif + {'g', good_post}, + {'y', reply_post}, + {'d', del_post}, + {'m', mark_post}, + {'L', solve_post}, + {Ctrl('P'), do_post}, + {Ctrl('W'), whereami}, + {'Q', view_postmoney}, +#ifdef OUTJOBSPOOL + {'u', tar_addqueue}, +#endif +#ifdef BMCHS + {'H', change_hidden}, +#endif + {'\0', NULL} +}; + +time_t board_visit_time; + +int Read() { + int mode0 = currutmp->mode; + int stat0 = currstat, tmpbid=currutmp->brc_id; + char buf[40]; +#ifdef LOG_BOARD + time_t usetime = time(0); +#endif + + setutmpmode(READING); + set_board(); + + if(board_visit_time < board_note_time) { + setbfile(buf, currboard, fn_notes); + more(buf, NA); + pressanykey(); + } + currutmp->brc_id = currbid; + setbdir(buf, currboard); + curredit &= ~EDIT_MAIL; + i_read(READING, buf, readtitle, readdoent, read_comms, + currbid); +#ifdef LOG_BOARD + log_board(currboard, time(0) - usetime); +#endif + brc_update(); + + currutmp->brc_id =tmpbid; + currutmp->mode = mode0; + currstat = stat0; + return 0; +} + +void ReadSelect() { + int mode0 = currutmp->mode; + int stat0 = currstat; + char genbuf[200]; + + currstat = XMODE; + if(do_select(0, 0, genbuf) == NEWDIRECT) + Read(); + currutmp->brc_id=0; + currutmp->mode = mode0; + currstat = stat0; +} + +#ifdef LOG_BOARD +static void log_board(char *mode, time_t usetime) { + time_t now; + char buf[ 256 ]; + + if(usetime > 30) { + now = time(0); + sprintf(buf, "USE %-20.20s Stay: %5ld (%s) %s", + mode, usetime ,cuser.userid ,ctime(&now)); + log_file(FN_USEBOARD,buf); + } +} +#endif + +int Select() { + char genbuf[200]; + + setutmpmode(SELECT); + do_select(0, NULL, genbuf); + return 0; +} diff --git a/mbbsd/board.c b/mbbsd/board.c new file mode 100644 index 00000000..44b4b842 --- /dev/null +++ b/mbbsd/board.c @@ -0,0 +1,1098 @@ +/* $Id: board.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include "config.h" +#include "pttstruct.h" +#include "perm.h" +#include "modes.h" +#include "common.h" +#include "proto.h" + +#define BRC_STRLEN 15 /* Length of board name */ +#define BRC_MAXSIZE 24576 +#define BRC_ITEMSIZE (BRC_STRLEN + 1 + BRC_MAXNUM * sizeof( int )) +#define BRC_MAXNUM 80 + +extern userinfo_t *currutmp; +static char *brc_getrecord(char *ptr, char *name, int *pnum, int *list) { + int num; + char *tmp; + + strncpy(name, ptr, BRC_STRLEN); + ptr += BRC_STRLEN; + num = (*ptr++) & 0xff; + tmp = ptr + num * sizeof(int); + if (num > BRC_MAXNUM) + num = BRC_MAXNUM; + *pnum = num; + memcpy(list, ptr, num * sizeof(int)); + return tmp; +} + +static time_t brc_expire_time; + +static char *brc_putrecord(char *ptr, char *name, int num, int *list) { + if(num > 0 && list[0] > brc_expire_time) { + if (num > BRC_MAXNUM) + num = BRC_MAXNUM; + + while(num > 1 && list[num - 1] < brc_expire_time) + num--; + + strncpy(ptr, name, BRC_STRLEN); + ptr += BRC_STRLEN; + *ptr++ = num; + memcpy(ptr, list, num * sizeof(int)); + ptr += num * sizeof(int); + } + return ptr; +} + +extern userec_t cuser; +extern char currboard[]; /* name of currently selected board */ +static int brc_changed = 0; +static char brc_buf[BRC_MAXSIZE]; +int brc_num; +static char brc_name[BRC_STRLEN]; +int brc_list[BRC_MAXNUM]; +static char *fn_boardrc = ".boardrc"; +static int brc_size; + +void brc_update() { + if(brc_changed && cuser.userlevel) { + char dirfile[STRLEN], *ptr; + char tmp_buf[BRC_MAXSIZE - BRC_ITEMSIZE], *tmp; + char tmp_name[BRC_STRLEN]; + int tmp_list[BRC_MAXNUM], tmp_num; + int fd, tmp_size; + + ptr = brc_buf; + if(brc_num > 0) + ptr = brc_putrecord(ptr, brc_name, brc_num, brc_list); + + setuserfile(dirfile, fn_boardrc); + if((fd = open(dirfile, O_RDONLY)) != -1) { + tmp_size = read(fd, tmp_buf, sizeof(tmp_buf)); + close(fd); + } else { + tmp_size = 0; + } + + tmp = tmp_buf; + while(tmp < &tmp_buf[tmp_size] && (*tmp >= ' ' && *tmp <= 'z')) { + tmp = brc_getrecord(tmp, tmp_name, &tmp_num, tmp_list); + if(strncmp(tmp_name, currboard, BRC_STRLEN)) + ptr = brc_putrecord(ptr, tmp_name, tmp_num, tmp_list); + } + brc_size = (int)(ptr - brc_buf); + + if((fd = open(dirfile, O_WRONLY | O_CREAT, 0644)) != -1) { + ftruncate(fd, 0); + write(fd, brc_buf, brc_size); + close(fd); + } + brc_changed = 0; + } +} + +static void read_brc_buf() { + char dirfile[STRLEN]; + int fd; + + if(brc_buf[0] == '\0') { + setuserfile(dirfile, fn_boardrc); + if((fd = open(dirfile, O_RDONLY)) != -1) { + brc_size = read(fd, brc_buf, sizeof(brc_buf)); + close(fd); + } else { + brc_size = 0; + } + } +} + +extern int currbid; +extern unsigned int currbrdattr; +extern boardheader_t *bcache; + +int brc_initial(char *boardname) { + char *ptr; + if(strcmp(currboard, boardname) == 0) { + return brc_num; + } + brc_update(); + strcpy(currboard, boardname); + currbid = getbnum(currboard); + currbrdattr = bcache[currbid - 1].brdattr; + read_brc_buf(); + + ptr = brc_buf; + while(ptr < &brc_buf[brc_size] && (*ptr >= ' ' && *ptr <= 'z')) { + ptr = brc_getrecord(ptr, brc_name, &brc_num, brc_list); + if (strncmp(brc_name, currboard, BRC_STRLEN) == 0) + return brc_num; + } + strncpy(brc_name, boardname, BRC_STRLEN); + brc_num = brc_list[0] = 1; + return 0; +} + +void brc_addlist(char *fname) { + int ftime, n, i; + + if(!cuser.userlevel) + return; + + ftime = atoi(&fname[2]); + if(ftime <= brc_expire_time + /* || fname[0] != 'M' || fname[1] != '.' */ ) { + return; + } + if(brc_num <= 0) { + brc_list[brc_num++] = ftime; + brc_changed = 1; + return; + } + if((brc_num == 1) && (ftime < brc_list[0])) + return; + for(n = 0; n < brc_num; n++) { + if(ftime == brc_list[n]) { + return; + } else if(ftime > brc_list[n]) { + if(brc_num < BRC_MAXNUM) + brc_num++; + for(i = brc_num - 1; --i >= n; brc_list[i + 1] = brc_list[i]); + brc_list[n] = ftime; + brc_changed = 1; + return; + } + } + if(brc_num < BRC_MAXNUM) { + brc_list[brc_num++] = ftime; + brc_changed = 1; + } +} + +static int brc_unread_time(time_t ftime, int bnum, int *blist) { + int n; + + if(ftime <= brc_expire_time ) + return 0; + + if(brc_num <= 0) + return 1; + for(n = 0; n < bnum; n++) { + if(ftime > blist[n]) + return 1; + else if(ftime == blist[n]) + return 0; + } + return 0; +} + +int brc_unread(char *fname, int bnum, int *blist) { + int ftime, n; + + ftime = atoi(&fname[2]); + + if(ftime <= brc_expire_time ) + return 0; + + if(brc_num <= 0) + return 1; + for(n = 0; n < bnum; n++) { + if(ftime > blist[n]) + return 1; + else if(ftime == blist[n]) + return 0; + } + return 0; +} + +#define BRD_UNREAD 1 +#define BRD_FAV 2 +#define BRD_ZAP 4 +#define BRD_TAG 8 + +typedef struct { + int bid, *total; + time_t *lastposttime; + boardheader_t *bh; + unsigned int myattr; +} boardstat_t; + +extern time_t login_start_time; +extern int numboards; +static int *zapbuf=NULL,*favbuf; +static boardstat_t *nbrd; + +#define STR_BBSRC ".bbsrc" +#define STR_FAV ".fav" + +void init_brdbuf() { + register int n, size; + char fname[60]; + + /* MAXBOARDS ==> ¦Ü¦h¬Ý±o¨£ 4 Ó·sªO */ + n = numboards + 4; + size = n * sizeof(int); + zapbuf = (int *) malloc(size); + favbuf = (int *) malloc(size); + + memset(favbuf,0,size); + + while(n) + zapbuf[--n] = login_start_time; + setuserfile(fname, STR_BBSRC); + if((n = open(fname, O_RDONLY, 0600)) != -1) { + read(n, zapbuf, size); + close(n); + } + setuserfile(fname, STR_FAV); + if((n = open(fname, O_RDONLY, 0600)) != -1) { + read(n, favbuf, size); + close(n); + } + + if(!nbrd) + nbrd = (boardstat_t *)malloc(MAX_BOARD * sizeof(boardstat_t)); + brc_expire_time = login_start_time - 365 * 86400; +} + +void save_brdbuf() { + int fd, size; + char fname[60]; + + if(!zapbuf) return; + setuserfile(fname, STR_BBSRC); + if((fd = open(fname, O_WRONLY | O_CREAT, 0600)) != -1) { + size = numboards * sizeof(int); + write(fd, zapbuf, size); + close(fd); + } + setuserfile(fname, STR_FAV); + if((fd = open(fname, O_WRONLY | O_CREAT, 0600)) != -1) { + size = numboards * sizeof(int); + write(fd, favbuf, size); + close(fd); + } +} + +extern char *fn_visable; + +int Ben_Perm(boardheader_t *bptr) { + register int level,brdattr; + register char *ptr; + + level = bptr->level; + brdattr = bptr->brdattr; + + if(HAS_PERM(PERM_SYSOP)) + return 1; + + ptr = bptr->BM; + if(is_BM(ptr)) + return 1; + + /* ¯¦±K¬ÝªO¡G®Ö¹ïº®uªO¥Dªº¦n¤Í¦W³æ */ + + if(brdattr & BRD_HIDE) { /* ÁôÂà */ + if( hbflcheck((int)(bptr-bcache) + 1, currutmp->uid) ){ + if(brdattr & BRD_POSTMASK) + return 0; + else + return 2; + } else + return 1; + } + /* ¨î¾\ŪÅv */ + if(level && !(brdattr & BRD_POSTMASK) && !HAS_PERM(level)) + return 0; + + return 1; +} + +extern char currauthor[]; +extern int b_lines; +extern char currowner[]; + +static int have_author(char* brdname) { + char dirname[100]; + + sprintf(dirname, "¥¿¦b·j´M§@ªÌ[33m%s[m ¬ÝªO:[1;33m%s[0m.....", + currauthor,brdname); + move(b_lines, 0); + clrtoeol(); + outs(dirname); + refresh(); + + setbdir(dirname, brdname); + str_lower(currowner, currauthor); + + return search_rec(dirname, cmpfowner); +} + +static int check_newpost(boardstat_t *ptr) { /* Ptt §ï */ + int tbrc_list[BRC_MAXNUM], tbrc_num; + char bname[BRC_STRLEN]; + char *po; + time_t ftime; + + ptr->myattr &= ~BRD_UNREAD; + if(ptr->bh->brdattr & BRD_GROUPBOARD) + return 0; + + if(*(ptr->total) == 0) + setbtotal(ptr->bid); + if(*(ptr->total) == 0) return 0; + ftime = *(ptr->lastposttime); + read_brc_buf(); + po = brc_buf; + while(po < &brc_buf[brc_size] && (*po >= ' ' && *po <= 'z')) { + po = brc_getrecord(po, bname, &tbrc_num, tbrc_list); + if(strncmp(bname, ptr->bh->brdname, BRC_STRLEN) == 0) { + if(brc_unread_time(ftime,tbrc_num,tbrc_list)) { + ptr->myattr |= BRD_UNREAD; + } + return 1; + } + } + + ptr->myattr |= BRD_UNREAD; + return 1; +} + +extern int currmode; +extern struct bcache_t *brdshm; +static int brdnum; +int class_bid = 0; +static int yank_flag = 1; +static void load_uidofgid(const int gid, const int type){ + boardheader_t *bptr,*currbptr; + int n; + currbptr = &bcache[gid-1]; + for(n=0;n<numboards;n++) + { + bptr = brdshm->sorted[type][n]; + if(bptr->brdname[0]=='\0') continue; + if(bptr->gid == gid) + { + if(currbptr == &bcache[gid-1]) + currbptr->firstchild[type]=bptr; + else + { + currbptr->next[type]=bptr; + currbptr->parent=&bcache[gid-1]; + } + currbptr=bptr; + } + } + if(currbptr == &bcache[gid-1]) + currbptr->firstchild[type]=(boardheader_t *) ~0; + else + currbptr->next[type]=(boardheader_t *) ~0; +} +static boardstat_t * addnewbrdstat(int n, int state) +{ + boardstat_t *ptr=&nbrd[brdnum++]; + boardheader_t *bptr = &bcache[n]; + ptr->total = &(brdshm->total[n]); + ptr->lastposttime = &(brdshm->lastposttime[n]); + ptr->bid = n+1; + ptr->myattr=0; + ptr->myattr=(favbuf[n]&~BRD_ZAP); + if(zapbuf[n] == 0) + ptr->myattr|=BRD_ZAP; + ptr->bh = bptr; + if((bptr->brdattr & BRD_HIDE) && state == 1) + bptr->brdattr |= BRD_POSTMASK; + check_newpost(ptr); + return ptr; +} + +static void load_boards(char *key) { + boardheader_t *bptr = NULL; + int type=cuser.uflag & BRDSORT_FLAG?1:0; + register int i,n; + register int state ; + + if(class_bid>0) + { + bptr = &bcache[class_bid-1]; + if(bptr->firstchild[type]==NULL) + load_uidofgid(class_bid,type); + } + brdnum = 0; + if(class_bid==0) + for(i=0 ; i < numboards; i++) + { + + if( (bptr = brdshm->sorted[type][i]) == NULL ) + continue; + n = (int)( bptr - bcache); + if(!bptr->brdname[0] || bptr->brdattr & BRD_GROUPBOARD || + !((state = Ben_Perm(bptr)) || (currmode & MODE_MENU)) || + (yank_flag == 0 && !(favbuf[n]&BRD_FAV)) || + (yank_flag == 1 && !zapbuf[n]) || + (key[0] && !strcasestr(bptr->title, key)) + ) continue; + addnewbrdstat(n, state); + } + else + for(bptr=bptr->firstchild[type]; bptr!=(boardheader_t *)~0; + bptr=bptr->next[type]) + { + n = (int)( bptr - bcache); + if(!((state = Ben_Perm(bptr)) || (currmode & MODE_MENU)) + ||(yank_flag == 0 && !(favbuf[n]&BRD_FAV)) + ||(yank_flag == 1 && !zapbuf[n]) || + (key[0] && !strcasestr(bptr->title, key))) continue; + addnewbrdstat(n, state); + } +} + +static int search_board() { + int num; + char genbuf[IDLEN + 2]; + move(0, 0); + clrtoeol(); + CreateNameList(); + for(num = 0; num < brdnum; num++) + AddNameList(nbrd[num].bh->brdname); + namecomplete(MSG_SELECT_BOARD, genbuf); + + for (num = 0; num < brdnum; num++) + if (!strcasecmp(nbrd[num].bh->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 = *(ptr->total); + num = total + 1; + if((ptr->myattr&BRD_UNREAD) &&(fd = open(dirfile, O_RDWR)) > 0) { + if(!brc_initial(ptr->bh->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(fname,brc_num,brc_list)) + 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(fname,brc_num,brc_list)) + break; + num++; + } + } + close(fd); + } + if(num < 0) + num = 0; + return num; +} + +static void brdlist_foot() { + prints("\033[34;46m ¿ï¾Ü¬ÝªO \033[31;47m (c)\033[30m·s¤å³¹¼Ò¦¡ " + "\033[31m(v/V)\033[30m¼Ð°O¤wŪ/¥¼Åª \033[31m(y)\033[30m¿z¿ï%s" + " \033[31m(z)\033[30m¤Á´«¿ï¾Ü \033[m", + yank_flag==0 ? "³Ì·R" : yank_flag==1 ? "³¡¥÷" : "¥þ³¡"); +} + +extern unsigned int currstat; +extern char *BBSName; + +static void show_brdlist(int head, int clsflag, int newflag) { + int myrow = 2; + if(class_bid == 1) { + currstat = CLASS; + myrow = 6; + showtitle("¤ÀÃþ¬ÝªO", BBSName); + movie(0); + move(1, 0); + prints( + " " + "¢© ¢~¡X\033[33m¡´\n" + " ùá¡X \033[m " + "¢¨¢i\033[47m¡ó\033[40m¢i¢i¢©ùç\n"); + prints( + " \033[44m ¡s¡s¡s¡s¡s¡s¡s¡s " + "\033[33mùø\033[m\033[44m ¢©¢¨¢i¢i¢i¡¿¡¿¡¿ùø \033[m\n" + " \033[44m " + "\033[33m \033[m\033[44m ¢«¢ª¢i¢i¢i¡¶¡¶¡¶ ùø\033[m\n" + " ¡s¡s¡s¡s¡s¡s¡s¡s \033[33m" + "¢x\033[m ¢ª¢i¢i¢i¢i¢« ùø\n" + " \033[33mùó" + "¡X¡X\033[m ¢« ¡X¡Ï\033[m"); + } else if (clsflag) { + showtitle("¬ÝªO¦Cªí", BBSName); + prints("[¡ö]¥D¿ï³æ [¡÷]¾\\Ū [¡ô¡õ]¿ï¾Ü [y]¸ü¤J [S]±Æ§Ç [/]·j´M " + "[TAB]¤åºK¡E¬ÝªO [h]¨D§U\n" + "\033[7m%-20s Ãþ§O Âà«H%-31s§ë²¼ ªO ¥D \033[m", + newflag ? "Á`¼Æ ¥¼Åª ¬Ý ªO" : " ½s¸¹ ¬Ý ªO", + " ¤¤ ¤å ±Ô z"); + move(b_lines, 0); + brdlist_foot(); + } + + if(brdnum > 0) { + boardstat_t *ptr; + static char *color[8]={"","\033[32m", + "\033[33m","\033[36m","\033[34m","\033[1m", + "\033[1;32m","\033[1;33m"}; + static char *unread[2]={"\33[37m \033[m","\033[1;31m£¾\033[m"}; + + while(++myrow < b_lines) { + move(myrow, 0); + clrtoeol(); + if(head < brdnum) { + ptr = &nbrd[head++]; + if(class_bid == 1) + prints(" "); + if(!newflag) { + prints("%5d%c%s", head, + !(ptr->bh->brdattr & BRD_HIDE) ? ' ': + (ptr->bh->brdattr & BRD_POSTMASK) ? ')' : '-', + (ptr->myattr & BRD_TAG) ? "D " : + (ptr->myattr & BRD_ZAP) ? "- " : + (ptr->bh->brdattr & BRD_GROUPBOARD) ? " " : + unread[ptr->myattr&BRD_UNREAD]); + } else if(ptr->myattr&BRD_ZAP) { + ptr->myattr &= ~BRD_UNREAD; + prints(" ¡ß ¡ß"); + } else { + if(newflag) { + if((ptr->bh->brdattr & BRD_GROUPBOARD)) + prints(" "); + else + prints("%6d%s", (int)(*(ptr->total)), + unread[ptr->myattr&BRD_UNREAD]); + } + } + if(class_bid != 1) { + prints("%s%-13s\033[m%s%5.5s\033[0;37m%2.2s\033[m" + "%-35.35s%c %.13s", + (ptr->myattr & BRD_FAV)?"\033[1;36m":"", + ptr->bh->brdname, + color[(unsigned int) + (ptr->bh->title[1] + ptr->bh->title[2] + + ptr->bh->title[3] + ptr->bh->title[0]) & 07], + ptr->bh->title, ptr->bh->title+5, ptr->bh->title+7, + (ptr->bh->brdattr & BRD_BAD) ? 'X' : + " ARBCDEFGHI"[ptr->bh->bvote], + ptr->bh->BM); + refresh(); + } else { + prints("%-40.40s %.13s", ptr->bh->title + 7, ptr->bh->BM); + } + } + clrtoeol(); + } + } +} + +static char *choosebrdhelp[] = { + "\0¬ÝªO¿ï³æ»²§U»¡©ú", + "\01°ò¥»«ü¥O", + "(p)(¡ô)/(n)(¡õ)¤W¤@ӬݪO / ¤U¤@ӬݪO", + "(P)(^B)(PgUp) ¤W¤@¶¬ÝªO", + "(N)(^F)(PgDn) ¤U¤@¶¬ÝªO", + "($)/(s)/(/) ³Ì«á¤@ӬݪO / ·j´M¬ÝªO / ¥H¤¤¤å·j´M¬ÝªOÃöÁä¦r", + "(¼Æ¦r) ¸õ¦Ü¸Ó¶µ¥Ø", + "\01¶i¶¥«ü¥O", + "(^W) °g¸ô¤F §Ú¦bþ¸Ì", + "(r)(¡÷)(Rtn) ¶i¤J¦h¥\\¯à¾\\Ū¿ï³æ", + "(q)(¡ö) ¦^¨ì¥D¿ï³æ", + "(z)(Z) q¾\\/¤Ïq¾\\¬ÝªO q¾\\/¤Ïq¾\\©Ò¦³¬ÝªO", + "(y) §Úªº³Ì·R/q¾\\¬ÝªO/¥X©Ò¦³¬ÝªO", + "(v/V) ³q³q¬Ý§¹/¥þ³¡¥¼Åª", + "(S) «ö·Ó¦r¥À/¤ÀÃþ±Æ§Ç", + "(t/^T/^A/^D) ¼Ð°O¬ÝªO/¨ú®ø©Ò¦³¼Ð°O/¤w¼Ð°Oªº¥[¤J§Úªº³Ì·R/¨ú®ø§Úªº³Ì·R", + "(m) §â¬ÝªO¥[¤J§Úªº³Ì·R", + "\01¤p²Õªø«ü¥O", + "(E/W/B) ³]©w¬ÝªO/³]©w¤p²Õ³Æ§Ñ/¶}·s¬ÝªO", + "(^P) ²¾°Ê¤w¼Ð°O¬ÝªO¨ì¦¹¤ÀÃþ", + NULL +}; + + +static void set_menu_BM(char *BM) { + if(HAS_PERM(PERM_ALLBOARD) || is_BM(BM)) { + currmode |= MODE_MENU; + cuser.userlevel |= PERM_SYSSUBOP; + } +} + +extern int p_lines; /* a Page of Screen line numbers: tlines-4 */ +extern int t_lines; +extern char *fn_notes; +static char *privateboard = +"\n\n\n\n ¹ï¤£°_ ¦¹ªO¥Ø«e¥uã¬ÝªO¦n¤Í¶i¤J ½Ð¥ý¦VªO¥D¥Ó½Ð¤J¹Ò³\\¥i"; +static void dozap(int num){ + boardstat_t *ptr; + ptr = &nbrd[num]; + ptr->myattr ^= BRD_ZAP; + if(ptr->bh->brdattr & BRD_NOZAP) ptr->myattr &= ~BRD_ZAP; + if(!(ptr->myattr & BRD_ZAP) ) check_newpost(ptr); + zapbuf[ptr->bid-1] = (ptr->myattr&BRD_ZAP?0:login_start_time); +} +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]=""; +#if HAVE_SEARCH_ALL + char genbuf[200]; +#endif + extern time_t board_visit_time; + + setutmpmode(newflag ? READNEW : READBRD); + brdnum = 0; + if(!cuser.userlevel) /* guest yank all boards */ + yank_flag = 2; + + do { + if(brdnum <= 0) { + load_boards(keyword); + if(brdnum <= 0) { + if(keyword[0]!=0) + { + mprints(b_lines-1,0,"¨S¦³¥ô¦ó¬ÝªO¼ÐÃD¦³¦¹ÃöÁä¦r " + "(ª©¥DÀ³ª`·N¬ÝªO¼ÐÃD©R¦W)"); + pressanykey(); + keyword[0]=0; + brdnum = -1; + continue; + } + if(yank_flag<2) + { + brdnum = -1; + yank_flag++; + continue; + } + if(HAS_PERM(PERM_SYSOP) || (currmode & MODE_MENU)) { + if(m_newbrd(0) == -1) + break; + brdnum = -1; + continue; + } else + break; + } + head = -1; + } + + if(num < 0) + num = 0; + else if(num >= brdnum) + num = brdnum - 1; + + if(head < 0) { + if(newflag) { + tmp = num; + while(num < brdnum) { + ptr = &nbrd[num]; + if(ptr->myattr&BRD_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(class_bid == 1) + ch = cursor_key(7 + num - head, 10); + else + ch = cursor_key(3 + num - head, 0); + + switch(ch) { + case Ctrl('W'): + whereami(0,NULL,NULL); + head=-1; + break; + case 'e': + case KEY_LEFT: + case EOF: + ch = 'q'; + case 'q': + if(keyword[0]) + { + keyword[0]=0; + brdnum=-1; + ch=' '; + } + break; + case 'c': + show_brdlist(head, 1, newflag ^= 1); + 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 Ctrl('C'): + cal(); + show_brdlist(head, 1, newflag); + break; + case Ctrl('I'): + t_idle(); + show_brdlist(head, 1, newflag); + break; + case KEY_UP: + case 'p': + case 'k': + if (num-- <= 0) + num = brdnum - 1; + break; + case 't': + ptr = &nbrd[num]; + ptr->myattr ^= BRD_TAG; + favbuf[ptr->bid-1]=ptr->myattr; + 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 'F': + case 'f': + if(class_bid && HAS_PERM(PERM_SYSOP)) + { + bcache[class_bid-1].firstchild[cuser.uflag&BRDSORT_FLAG?1:0] + =NULL; + brdnum = -1; + } + break; + case 'h': + show_help(choosebrdhelp); + show_brdlist(head, 1, newflag); + break; + case '/': + getdata_buf(b_lines-1,0,"½Ð¿é¤J¬ÝªO¤¤¤åÃöÁä¦r:",keyword, 12, DOECHO); + brdnum=-1; + break; + case 'S': + cuser.uflag ^= BRDSORT_FLAG; + brdnum = -1; + break; + case 'y': + if(class_bid==0) + yank_flag = (yank_flag+1)%3; + else + yank_flag = yank_flag%2+1; + brdnum = -1; + break; + case Ctrl('D'): + for(tmp = 0; tmp < numboards; tmp++) + { + if(favbuf[tmp] & BRD_TAG) + { + favbuf[tmp] &= ~BRD_FAV; + favbuf[tmp] &= ~BRD_TAG; + } + } + brdnum = -1; + break; + case Ctrl('A'): + for(tmp = 0; tmp < numboards; tmp++) + { + if(favbuf[tmp] & BRD_TAG) + { + favbuf[tmp] |= BRD_FAV; + favbuf[tmp] &= ~BRD_TAG; + } + } + brdnum = -1; + break; + case Ctrl('T'): + for(tmp = 0; tmp < numboards; tmp++) + favbuf[tmp] &= ~BRD_TAG; + brdnum = -1; + break; + case Ctrl('P'): + if(class_bid!=0 && + (HAS_PERM(PERM_SYSOP) || (currmode & MODE_MENU))) { + for(tmp = 0; tmp < numboards; tmp++) { + boardheader_t *bh=&bcache[tmp]; + if(!(favbuf[tmp]&BRD_TAG) || bh->gid==class_bid) + continue; + favbuf[tmp] &= ~BRD_TAG; + if(bh->gid != class_bid) + { + bh->gid = class_bid; + substitute_record(FN_BOARD, bh, + sizeof(boardheader_t), tmp+1); + reset_board(tmp+1); + log_usies("SetBoardGID", bh->brdname); + } + } + brdnum = -1; + } + break; + case 'm': + if(HAS_PERM(PERM_BASIC)) { + ptr = &nbrd[num]; + ptr->myattr ^= BRD_FAV; + favbuf[ptr->bid-1]=ptr->myattr; + head = 9999; + } + break; + case 'z': + if(HAS_PERM(PERM_BASIC)) { + dozap(num); + head = 9999; + } + break; + case 'Z': /* Ptt */ + if(HAS_PERM(PERM_BASIC)) { + for(tmp = 0; tmp < brdnum; tmp++) { + dozap(tmp); + } + head = 9999; + } + break; + case 'v': + case 'V': + ptr = &nbrd[num]; + brc_initial(ptr->bh->brdname); + if(ch == 'v') { + ptr->myattr &= ~BRD_UNREAD; + zapbuf[ptr->bid-1] = time((time_t *) &brc_list[0]); + } else + { + zapbuf[ptr->bid-1] = brc_list[0] = 1; + ptr->myattr |= BRD_UNREAD; + } + brc_num = brc_changed = 1; + brc_update(); + show_brdlist(head, 0, newflag); + break; + case 's': + if((tmp = search_board()) == -1) { + show_brdlist(head, 1, newflag); + break; + } + num = tmp; + case 'E': + if(HAS_PERM(PERM_SYSOP) || (currmode & MODE_MENU)) { + ptr = &nbrd[num]; + move(1,1); + clrtobot(); + m_mod_board(ptr->bh->brdname); + brdnum = -1; + } + break; + case 'R': + if(HAS_PERM(PERM_SYSOP) || (currmode & MODE_MENU)) { + m_newbrd(1); + brdnum = -1; + } + break; + case 'B': + if(HAS_PERM(PERM_SYSOP) || (currmode & MODE_MENU)) { + m_newbrd(0); + brdnum = -1; + } + break; + case 'W': + if(class_bid > 0 && + (HAS_PERM(PERM_SYSOP) || (currmode & MODE_MENU))) { + b_note_edit_bname(class_bid); + brdnum = -1; + } + break; + case KEY_RIGHT: + case '\n': + case '\r': + case 'r': + { + char buf[STRLEN]; + + ptr = &nbrd[num]; + + if(!(ptr->bh->brdattr & BRD_GROUPBOARD)) { /* «Dsub class */ + if(!(ptr->bh->brdattr & BRD_HIDE) || + (ptr->bh->brdattr & BRD_POSTMASK)) { + brc_initial(ptr->bh->brdname); + + if(newflag) { + setbdir(buf, currboard); + tmp = unread_position(buf, ptr); + head = tmp - t_lines / 2; + getkeep(buf, head > 1 ? head : 1, tmp + 1); + } + board_visit_time = zapbuf[ptr->bid-1]; + if(!(ptr->myattr&BRD_ZAP)) + time((time_t *) &zapbuf[ptr->bid-1]); + Read(); + check_newpost(ptr); + head = -1; + setutmpmode(newflag ? READNEW : READBRD); + } else { + setbfile(buf, ptr->bh->brdname, FN_APPLICATION); + if(more(buf,YEA)==-1) { + move(1,0); + clrtobot(); + outs(privateboard); + pressanykey(); + } + head = -1; + } + } else { /* sub class */ + move(12,1); + bidtmp = class_bid; + currmodetmp =currmode; + tmp1=num; + num=0; + class_bid = ptr->bid; + if (!(currmode & MODE_MENU))/*¦pªGÁÙ¨S¦³¤p²ÕªøÅv */ + set_menu_BM(ptr->bh->BM); + + if(time(NULL) < ptr->bh->bupdate) { + setbfile(buf, ptr->bh->brdname, fn_notes); + if(more(buf, NA) != -1) + pressanykey(); + } + tmp=currutmp->brc_id; + currutmp->brc_id=ptr->bid; + choose_board(0); + currmode = currmodetmp; /* Â÷¶}ª©ª©«á´N§âÅv®³±¼³á */ + num=tmp1; + class_bid = bidtmp; + currutmp->brc_id=tmp; + brdnum = -1; + } + } + } + } while(ch != 'q'); + save_brdbuf(); +} + +int root_board() { + class_bid = 1; + yank_flag = 1; + choose_board(0); + return 0; +} + +int Boards() { + class_bid = 0; + yank_flag = 0; + choose_board(0); + return 0; +} + + +int New() { + int mode0 = currutmp->mode; + int stat0 = currstat; + + class_bid = 0; + choose_board(1); + currutmp->mode = mode0; + currstat = stat0; + return 0; +} + +/* +int v_favorite(){ + char fname[256]; + char inbuf[2048]; + FILE* fp; + int nGroup; + char* strtmp; + + setuserfile(fname,str_favorite); + + if (!(fp=fopen(fname,"r"))) + return -1; + move(0,0); + clrtobot(); + fgets(inbuf,sizeof(inbuf),fp); + nGroup=atoi(inbuf); + + currutmp->nGroup=0; + currutmp->ninRoot=0; + + while(nGroup!=currutmp->nGroup+1){ + fgets(inbuf,sizeof(inbuf),fp); + prints("%s\n",strtmp=strtok(inbuf," \n")); + strcpy(currutmp->gfavorite[currutmp->nGroup++],strtmp); + while((strtmp=strtok(NULL, " \n"))){ + prints(" %s %d\n",strtmp,getbnum(strtmp)); + } + currutmp->nGroup++; + } + prints("+++%d+++\n",currutmp->nGroup); + + fgets(inbuf,sizeof(inbuf),fp); + + for(strtmp=strtok(inbuf, " \n");strtmp;strtmp=strtok(NULL, " \n")){ + if (strtmp[0]!='#') + prints("*** %s %d\n",strtmp, getbnum(strtmp)); + else + prints("*** %s %d\n",strtmp+1, -1); + currutmp->ninRoot++; + } + + fclose(fp); + pressanykey(); + return 0; +} +*/ diff --git a/mbbsd/cache.c b/mbbsd/cache.c new file mode 100644 index 00000000..73f8ac5b --- /dev/null +++ b/mbbsd/cache.c @@ -0,0 +1,1053 @@ +/* $Id: cache.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <signal.h> +#include <unistd.h> +#include <fcntl.h> +#include <ctype.h> +#include <errno.h> +#include <time.h> +#include <sys/types.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <sys/ipc.h> +#include <sys/shm.h> +#include <sys/sem.h> + +#ifdef __FreeBSD__ +#include <machine/param.h> +#endif + +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "perm.h" +#include "modes.h" +#include "proto.h" + +#ifndef __FreeBSD__ +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 + +int fcache_semid; + +/* the reason for "safe_sleep" is that we may call sleep during + SIGALRM handler routine, while SIGALRM is blocked. + if we use the original sleep, we'll never wake up. */ +unsigned int safe_sleep(unsigned int seconds) { + /* jochang sleep¦³°ÝÃD®É¥Î*/ + sigset_t set,oldset; + + sigemptyset(&set); + sigprocmask(SIG_BLOCK, &set, &oldset); + if(sigismember(&oldset, SIGALRM)) { + unsigned long retv; +#if !defined(_BBS_UTIL_C_) + log_usies("SAFE_SLEEP ", "avoid hang"); +#endif + sigemptyset(&set); + sigaddset(&set,SIGALRM); + sigprocmask(SIG_UNBLOCK,&set,NULL); + retv=sleep(seconds); + sigprocmask(SIG_BLOCK,&set,NULL); + return retv; + } + return sleep(seconds); +} + +#if defined(_BBS_UTIL_C_) +static void setapath(char *buf, char *boardname) { + sprintf(buf, "man/boards/%s", boardname); +} + +static char *str_dotdir = ".DIR"; + +static void setadir(char *buf, char *path) { + sprintf(buf, "%s/%s", path, str_dotdir); +} +#endif + +static void attach_err(int shmkey, char *name) { + fprintf(stderr, "[%s error] key = %x\n", name, shmkey); + fprintf(stderr, "errno = %d: %s\n", errno, strerror(errno)); + exit(1); +} + +static void *attach_shm(int shmkey, int shmsize) { + void *shmptr; + int shmid; + + char *empty_addr; + /* set up one page in-accessible -- jochang */ + { + int fd = open("/dev/zero",O_RDONLY); + int size = ((shmsize + 4095) / 4096) * 4096; + + munmap( + (empty_addr=mmap(0,4096+size,PROT_NONE,MAP_PRIVATE,fd,0))+4096 + ,size); + + close(fd); + } + + shmid = shmget(shmkey, shmsize, 0); + if(shmid < 0) { + shmid = shmget(shmkey, shmsize, IPC_CREAT | 0600); + if(shmid < 0) + attach_err(shmkey, "shmget"); + shmptr = (void *)shmat(shmid, NULL, 0); + if(shmptr == (void *)-1) + attach_err(shmkey, "shmat"); + } else { + shmptr = (void *)shmat(shmid, NULL, 0); + if(shmptr == (void *)-1) + attach_err(shmkey, "shmat"); + } + + /* unmap the page -- jochang */ + { + munmap(empty_addr,4096); + } + return shmptr; +} + + +#define SEM_FLG 0600 /* semaphore mode */ + +/* ----------------------------------------------------- */ +/* semaphore : for critical section */ +/* ----------------------------------------------------- */ +void sem_init(int semkey,int *semid) { + union semun s; + + s.val=1; + *semid = semget(semkey, 1, 0); + if(*semid == -1) { + *semid = semget(semkey, 1, IPC_CREAT | SEM_FLG); + if(*semid == -1) + attach_err(semkey, "semget"); + semctl(*semid, 0, SETVAL, s); + } +} + +void sem_lock(int op,int semid) { + struct sembuf sops; + + sops.sem_num = 0; + sops.sem_flg = SEM_UNDO; + sops.sem_op = op; + semop(semid, &sops, 1); +} + +/* uhash *******************************************/ +/* the design is this: + we use another stand-alone program to create and load data into the hash. + (that program could be run in rc-scripts or something like that) + after loading completes, the stand-alone program sets loaded to 1 and exits. + + the bbs exits if it can't attach to the shared memory or + the hash is not loaded yet. +*/ +uhash_t *uhash; + +/* attach_uhash should be called before using uhash */ +void attach_uhash() { + uhash = attach_shm(UHASH_KEY, sizeof(*uhash)); + if(!uhash->loaded) /* assume fresh shared memory is zeroed */ + exit(1); +} + +void add_to_uhash(int n, char *id) { + int *p, h = StringHash(id); + strcpy(uhash->userid[n], id); + + p = &(uhash->hash_head[h]); + + while(*p != -1) + p = &(uhash->next_in_hash[*p]); + + uhash->next_in_hash[*p = n] = -1; +} + +/* note: after remove_from_uhash(), you should add_to_uhash() + (likely with a different name) */ +void remove_from_uhash(int n) { + int h = StringHash(uhash->userid[n]); + int *p = &(uhash->hash_head[h]); + + while(*p != -1 && *p != n) + p = &(uhash->next_in_hash[*p]); + if(*p == n) + *p = uhash->next_in_hash[n]; +} + +int setumoney(int uid, int money) { + uhash->money[uid-1]=money; + passwd_update_money(uid); + return uhash->money[uid-1]; +} + +int deumoney(int uid, int money) { + if(money<0 && uhash->money[uid-1]<-money) + return setumoney(uid,0); + else + return setumoney(uid,uhash->money[uid-1]+money); +} +int demoney(int money) { + extern int usernum; + return deumoney(usernum,money); +} +int moneyof(int uid){ /* ptt §ï¶iª÷¿ú³B²z®Ä²v */ + return uhash->money[uid-1]; +} +int searchuser(char *userid) { + int h,p; + + h = StringHash(userid); + p = uhash->hash_head[h]; + + while(p != -1) { + if(strcasecmp(uhash->userid[p],userid) == 0) { + strcpy(userid,uhash->userid[p]); + return p + 1; + } + p = uhash->next_in_hash[p]; + } + return 0; +} + +#if !defined(_BBS_UTIL_C_) +extern userec_t xuser; + +int getuser(char *userid) { + int uid; + + if((uid = searchuser(userid))) + passwd_query(uid, &xuser); + return uid; +} + +char *getuserid(int num) { + if(--num >= 0 && num < MAX_USERS) + return ((char *) uhash->userid[num]); + return NULL; +} + +void setuserid(int num, char *userid) { + if(num > 0 && num <= MAX_USERS) { + if(num > uhash->number) + uhash->number = num; + else + remove_from_uhash(num-1); + add_to_uhash(num-1,userid); + } +} + +/* 0 ==> §ä¹L´Á±b¸¹ */ +/* 1 ==> «Ø¥ß·s±b¸¹ */ +/* should do it by searching "" in the hash */ +int searchnewuser(int mode) { + register int i, num; + + num = uhash->number; + i = 0; + + /* ¬°¤°»ò³oÃ䤣¥Î hash table ¥h§ä¦Ón¥Î linear search? */ + while(i < num) { + if(!uhash->userid[i++][0]) + return i; + } + if(mode && (num < MAX_USERS)) + return num + 1; + return 0; +} + +char *u_namearray(char buf[][IDLEN + 1], int *pnum, char *tag) { + register struct uhash_t *reg_ushm = uhash; + register char *ptr, tmp; + register int n, total; + char tagbuf[STRLEN]; + int ch, ch2, num; + + if(*tag == '\0') { + *pnum = reg_ushm->number; + return reg_ushm->userid[0]; + } + for(n = 0; tag[n]; n++) + tagbuf[n] = chartoupper(tag[n]); + tagbuf[n] = '\0'; + ch = tagbuf[0]; + ch2 = ch - 'A' + 'a'; + total = reg_ushm->number; + for(n = num = 0; n < total; n++) { + ptr = reg_ushm->userid[n]; + tmp = *ptr; + if(tmp == ch || tmp == ch2) { + if(chkstr(tag, tagbuf, ptr)) + strcpy(buf[num++], ptr); + } + } + *pnum = num; + return buf[0]; +} +#endif + +/*-------------------------------------------------------*/ +/* .UTMP cache */ +/*-------------------------------------------------------*/ +struct utmpfile_t *utmpshm=NULL; + +void resolve_utmp() { + if(utmpshm == NULL) { + utmpshm = attach_shm(UTMPSHM_KEY, sizeof(*utmpshm)); + } +} + +userinfo_t *currutmp = NULL; + +#if !defined(_BBS_UTIL_C_) +extern unsigned int currstat; +extern userec_t cuser; + +void setutmpmode(int mode) { + if(currstat != mode) + currutmp->mode = currstat = mode; + + /* °lÂÜ¨Ï¥ÎªÌ */ + if(HAS_PERM(PERM_LOGUSER)) { + time_t now = time(NULL); + char msg[200]; + sprintf(msg, "%s setutmpmode to %s(%d) at %s", + cuser.userid, modestring(currutmp, 0), mode, Cdate(&now)); + log_user(msg); + } +} +#endif +/* +static int cmputmpuserid(userinfo_t ** i, userinfo_t ** j) { + return strcasecmp((*i)->userid, (*j)->userid); +} + +static int cmputmpmode(userinfo_t ** i, userinfo_t ** j) { + return (*i)->mode-(*j)->mode; +} + +static int cmputmpidle(userinfo_t ** i, userinfo_t ** j) { + return (*i)->lastact-(*j)->lastact; +} + +static int cmputmpfrom(userinfo_t ** i, userinfo_t ** j) { + return strcasecmp((*i)->from, (*j)->from); +} + +static int cmputmpfive(userinfo_t ** i, userinfo_t ** j) { + int type; + if((type=(*j)->five_win - (*i)->five_win)) + return type; + if((type=(*i)->five_lose - (*j)->five_lose)) + return type; + return (*i)->five_tie-(*j)->five_tie; +} +static int cmputmpsex(userinfo_t ** i, userinfo_t ** j) { + static int ladyfirst[]={1,0,1,0,1,0,3,3}; + return ladyfirst[(*i)->sex]-ladyfirst[(*j)->sex]; +} +static int cmputmppid(userinfo_t ** i, userinfo_t ** j) { + return (*i)->pid-(*j)->pid; +} +static int cmputmpuid(userinfo_t ** i, userinfo_t ** j) { + return (*i)->uid-(*j)->uid; +} +*/ +static int cmputmpuserid(const void *i, const void *j){ + return strcasecmp((*((userinfo_t**)i))->userid, (*((userinfo_t**)j))->userid); +} + +static int cmputmpmode(const void *i, const void *j){ + return (*((userinfo_t**)i))->mode-(*((userinfo_t**)j))->mode; +} + +static int cmputmpidle(const void *i, const void *j){ + return (*((userinfo_t**)i))->lastact-(*((userinfo_t**)j))->lastact; +} + +static int cmputmpfrom(const void *i, const void *j){ + return strcasecmp((*((userinfo_t**)i))->from, (*((userinfo_t**)j))->from); +} + +static int cmputmpfive(const void *i, const void *j){ + int type; + if((type=(*((userinfo_t**)j))->five_win - (*((userinfo_t**)i))->five_win)) + return type; + if((type=(*((userinfo_t**)i))->five_lose - (*((userinfo_t**)j))->five_lose)) + return type; + return (*((userinfo_t**)i))->five_tie-(*((userinfo_t**)j))->five_tie; +} + +static int cmputmpsex(const void *i, const void *j){ + static int ladyfirst[]={1,0,1,0,1,0,3,3}; + return ladyfirst[(*((userinfo_t**)i))->sex]-ladyfirst[(*((userinfo_t**)j))->sex]; +} +static int cmputmppid(const void *i, const void *j){ + return (*((userinfo_t**)i))->pid-(*((userinfo_t**)j))->pid; +} +static int cmputmpuid(const void *i, const void *j){ + return (*((userinfo_t**)i))->uid-(*((userinfo_t**)j))->uid; +} +void sort_utmp() +{ + time_t now=time(NULL); + int count, i, ns; + userinfo_t *uentp; + + if(now-utmpshm->uptime<60 && (now==utmpshm->uptime || utmpshm->busystate)) + return; /* lazy sort */ + utmpshm->busystate=1; + utmpshm->uptime = now; + ns=(utmpshm->currsorted?0:1); + + for(uentp = &utmpshm->uinfo[0], count=0, i=0; + i< USHM_SIZE; i++,uentp = &utmpshm->uinfo[i]) + if(uentp->pid) + { + utmpshm->sorted[ns][0][count++]= uentp; + } + utmpshm->number = count; + qsort(utmpshm->sorted[ns][0],count,sizeof(userinfo_t*),cmputmpuserid); + memcpy(utmpshm->sorted[ns][1],utmpshm->sorted[ns][0], + sizeof(userinfo_t *)*count); + memcpy(utmpshm->sorted[ns][2],utmpshm->sorted[ns][0], + sizeof(userinfo_t *)*count); + memcpy(utmpshm->sorted[ns][3],utmpshm->sorted[ns][0], + sizeof(userinfo_t *)*count); + memcpy(utmpshm->sorted[ns][4],utmpshm->sorted[ns][0], + sizeof(userinfo_t *)*count); + memcpy(utmpshm->sorted[ns][5],utmpshm->sorted[ns][0], + sizeof(userinfo_t *)*count); + memcpy(utmpshm->sorted[ns][6],utmpshm->sorted[ns][0], + sizeof(userinfo_t *)*count); + memcpy(utmpshm->sorted[ns][7],utmpshm->sorted[ns][0], + sizeof(userinfo_t *)*count); + qsort(utmpshm->sorted[ns][1], count, sizeof(userinfo_t *), cmputmpmode ); + qsort(utmpshm->sorted[ns][2], count, sizeof(userinfo_t *), cmputmpidle ); + qsort(utmpshm->sorted[ns][3], count, sizeof(userinfo_t *), cmputmpfrom ); + qsort(utmpshm->sorted[ns][4], count, sizeof(userinfo_t *), cmputmpfive ); + qsort(utmpshm->sorted[ns][5], count, sizeof(userinfo_t *), cmputmpsex ); + qsort(utmpshm->sorted[ns][6], count, sizeof(userinfo_t *), cmputmpuid ); + qsort(utmpshm->sorted[ns][7], count, sizeof(userinfo_t *), cmputmppid ); + utmpshm->currsorted=ns; + utmpshm->busystate=0; +} +// Ptt:³oÃä¥[¤JhashÆ[©À §äªÅªºutmp +void getnewutmpent(userinfo_t *up) { + extern int errno; + register int i, p ; + register userinfo_t *uentp; + for(i = 0, p=StringHash(up->userid)%USHM_SIZE; i < USHM_SIZE; i++, p++) { + if(p==USHM_SIZE) p=0; + uentp = &(utmpshm->uinfo[p]); + if(!(uentp->pid)) { + memcpy(uentp, up, sizeof(userinfo_t)); + currutmp = uentp; + sort_utmp(); + return; + } + } + exit(1); +} + +int apply_ulist(int (*fptr)(userinfo_t *)) { + register userinfo_t *uentp; + register int i, state; + + for(i = 0; i < USHM_SIZE; i++) { + uentp = &(utmpshm->uinfo[i]); + if(uentp->pid && (PERM_HIDE(currutmp) || !PERM_HIDE(uentp))) + if((state = (*fptr) (uentp))) + return state; + } + return 0; +} + +userinfo_t *search_ulist(int uid) { + return search_ulistn(uid,1); +} + +#if !defined(_BBS_UTIL_C_) +extern int usernum; + +userinfo_t *search_ulist_pid(int pid) { + register int i=0, j, start = 0, end = utmpshm->number - 1; + register userinfo_t **ulist; + ulist=utmpshm->sorted[utmpshm->currsorted][7]; + for(i=((start+end)/2); ;i=(start+end)/2) + { + j=pid-ulist[i]->pid; + if(!j) + { + return (userinfo_t *) (ulist[i]); + } + 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 = utmpshm->number - 1; + register userinfo_t **ulist; + ulist=utmpshm->sorted[utmpshm->currsorted][6]; + for(i=((start+end)/2); ;i=(start+end)/2) + { + j= uid - ulist[i]->uid; + if(!j) + { + for(;i>0 && uid==ulist[i-1]->uid;i--);/* «ü¨ì²Ä¤@µ§ */ + if(uid==ulist[i+unum-1]->uid) + return (userinfo_t *) (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; +} + +int count_logins(int uid, int show) { + register int i=0, j, start = 0, end = utmpshm->number - 1, count; + register userinfo_t **ulist; + ulist=utmpshm->sorted[utmpshm->currsorted][6]; + for(i=((start+end)/2); ;i=(start+end)/2) + { + j = uid-ulist[i]->uid; + if(!j) + { + for(;i>0 && uid==ulist[i-1]->uid;i--);/* «ü¨ì²Ä¤@µ§ */ + for(count=0;uid==ulist[i+count]->uid;count++) + { + if(show) + prints("(%d) ¥Ø«eª¬ºA¬°: %-17.16s(¨Ó¦Û %s)\n", + count+1, modestring(ulist[i+count], 0), + ulist[i+count]->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(); + memset(uentp, 0, sizeof(userinfo_t)); +} + +#endif + +/*-------------------------------------------------------*/ +/* .BOARDS cache */ +/*-------------------------------------------------------*/ +extern char *fn_board; +extern int currbid; +bcache_t *brdshm; +boardheader_t *bcache; + +void touchdircache(int bid) +{ + int *i= (int *)&brdshm->dircache[bid - 1][0].filename[0]; + *i=0; +} + +void load_fileheader_cache(int bid, char *direct) +{ + int num=getbtotal(bid); + int n = num-DIRCACHESIZE+1; + if (brdshm->busystate!=1) + { + brdshm->busystate = 1; + get_records(direct, brdshm->dircache[bid - 1] , + sizeof(fileheader_t),n<1?1:n, DIRCACHESIZE); + brdshm->cachetotal[bid-1]=num; // cachetotal¥ý³] ¥H«á¦A§ï¤£¥Î¥þ³¡load + brdshm->busystate = 0; + } + else + {safe_sleep(1);} +} + +int get_fileheader_cache(int bid, char *direct, fileheader_t *headers, + int recbase, int nlines) +{ + int ret, n,num; + + num=getbtotal(bid); + + ret = num-recbase+1, + n = (num - DIRCACHESIZE+1); + + + if(brdshm->dircache[bid - 1][0].filename[0]=='\0') + load_fileheader_cache(bid, direct); + if (n<1) + n=recbase-1; + else + n=recbase-n; + if(n<0) n=0; + if (ret>nlines) ret=nlines; + memcpy(headers, &(brdshm->dircache[bid - 1][n]),sizeof(fileheader_t)*ret); + return ret; +} +static int cmpboardname(boardheader_t **brd, boardheader_t **tmp) { + return strcasecmp((*brd)->brdname, (*tmp)->brdname); +} +static int cmpboardclass(boardheader_t **brd, boardheader_t **tmp) { + return (strncmp((*brd)->title, (*tmp)->title, 4)<<8)+ + strcasecmp((*brd)->brdname, (*tmp)->brdname); +} +static void sort_bcache(){ + int i;/*critical section ¤£¯à³æ¿W©I¥s ©I¥sreload_bcache or reset_board */ + for(i=0;i<brdshm->number;i++) + { + brdshm->sorted[1][i]=brdshm->sorted[0][i]=&bcache[i]; + } + qsort(brdshm->sorted[0], brdshm->number, sizeof(boardheader_t *), + (QCAST)cmpboardname); + qsort(brdshm->sorted[1], brdshm->number, sizeof(boardheader_t *), + (QCAST)cmpboardclass); +} +static void reload_bcache() { + if(brdshm->busystate) { + safe_sleep(1); + } +#if !defined(_BBS_UTIL_C_) + else { + int fd,i; + + brdshm->busystate = 1; + if((fd = open(fn_board, O_RDONLY)) > 0) { + brdshm->number = + read(fd, bcache, MAX_BOARD * sizeof(boardheader_t)) / + sizeof(boardheader_t); + close(fd); + } + memset(brdshm->lastposttime, 0, MAX_BOARD * sizeof(time_t)); + /* µ¥©Ò¦³ boards ¸ê®Æ§ó·s«á¦A³]©w uptime */ + brdshm->uptime = brdshm->touchtime; + log_usies("CACHE", "reload bcache"); + sort_bcache(); + for(i=0;i<brdshm->number;i++) + { + bcache[i].firstchild[0]=NULL; + bcache[i].firstchild[1]=NULL; + } + brdshm->busystate = 0; + } +#endif +} + +int numboards = -1; + +void resolve_boards() { + if(brdshm == NULL) { + brdshm = attach_shm(BRDSHM_KEY, sizeof(*brdshm)); + if(brdshm->touchtime == 0) + brdshm->touchtime = 1; + bcache = brdshm->bcache; + } + + while(brdshm->uptime < brdshm->touchtime) + {reload_bcache();} + numboards = brdshm->number; +} + +void touch_boards() { + time(&(brdshm->touchtime)); + numboards = -1; + resolve_boards(); +} +void addbrd_touchcache() +{ + brdshm->number++; + numboards=brdshm->number; + reset_board(numboards); +} +#if !defined(_BBS_UTIL_C_) +void reset_board(int bid) { /* Ptt: ³o¼Ë´N¤£¥Î¦Ñ¬Otouch board¤F */ + int fd,i; + boardheader_t *bhdr; + + if(--bid < 0) + return; + if(brdshm->busystate) { + safe_sleep(1); + } else { + brdshm->busystate = 1; + 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); + } + sort_bcache(); + for(i=0;i<brdshm->number;i++) + { + bcache[i].firstchild[0]=NULL; + bcache[i].firstchild[1]=NULL; + } + brdshm->busystate = 0; + } +} + +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) && Ben_Perm(bhdr) && + (*func)(bhdr) == QUIT) + return QUIT; + } + return 0; +} +#endif + +boardheader_t *getbcache(int bid) { /* Ptt§ï¼g */ + return bcache + bid - 1; +} +int getbtotal(int bid) +{ + return brdshm->total[bid - 1]; +} +void setbtotal(int bid) { + boardheader_t *bh = getbcache(bid); + struct stat st; + char genbuf[256]; + int num,fd; + + sprintf(genbuf, "boards/%s/.DIR", bh->brdname); + + if((fd = open(genbuf, O_RDWR)) < 0) + return; /* .DIR±¾¤F */ + fstat(fd, &st); + num = st.st_size / sizeof(fileheader_t); + brdshm->total[bid - 1] = num; + + if(num>0) + { + lseek(fd, (off_t) (num - 1) * sizeof(fileheader_t), SEEK_SET); + if(read(fd, genbuf, FNLEN)>=0) + { + brdshm->lastposttime[bid - 1]=(time_t) atoi(&genbuf[2]); + } + } + else + brdshm->lastposttime[bid - 1] = 0; + close(fd); + if(num) + touchdircache(bid); +} + +void +touchbpostnum(int bid, int delta) { + int *total = &brdshm->total[bid - 1]; + if (*total) *total += delta; +} + + +int getbnum(char *bname) { + register int i=0, j, start = 0, end = brdshm->number - 1; + register boardheader_t **bhdr; + bhdr=brdshm->sorted[0]; + for(i=((start+end)/2); ;i=(start+end)/2) + { + if(! (j=strcasecmp(bname,bhdr[i]->brdname))) + return (int) (bhdr[i] - bcache +1); + if(end==start) + { + break; + } + else if(i==start) + { + i=end; + start=end; + } + else if(j>0) start = i; + else end = i; + } + return 0; +} + +#if !defined(_BBS_UTIL_C_) +extern char *fn_water; +extern char *str_sysop; + +int haspostperm(char *bname) { + register int i; + char buf[200]; + + setbfile(buf, bname, fn_water); + if(belong(buf, cuser.userid)) + return 0; + + if(!strcasecmp(bname, DEFAULT_BOARD)) + return 1; + + if (!strcasecmp(bname, "PttLaw")) + return 1; + + if(!HAS_PERM(PERM_POST)) + return 0; + + if(!(i = getbnum(bname))) + return 0; + + /* ¯µ±K¬ÝªO¯S§O³B²z */ + if(bcache[i - 1].brdattr & BRD_HIDE) + return 1; + + i = bcache[i - 1].level; + + if (HAS_PERM(PERM_VIOLATELAW) && (i & PERM_VIOLATELAW)) + return 1; + else if (HAS_PERM(PERM_VIOLATELAW)) + return 0; + + return HAS_PERM(i & ~PERM_POST); +} +#endif + +/*-------------------------------------------------------*/ +/* PTT cache */ +/*-------------------------------------------------------*/ +/* cachefor °ÊºA¬Ýª© */ +struct pttcache_t *ptt; + +static void reload_pttcache() { + if(ptt->busystate) + safe_sleep(1); + else { /* jochang: temporary workaround */ + fileheader_t item, subitem; + char pbuf[256], buf[256], *chr; + FILE *fp, *fp1, *fp2; + int id, section = 0; + + ptt->busystate = 1; + ptt->max_film = 0; + bzero(ptt->notes, sizeof ptt->notes); + setapath(pbuf, "Note"); + setadir(buf, pbuf); + id = 0; + if((fp = fopen(buf, "r"))) { + while(fread(&item, sizeof(item), 1, fp)) { + if(item.title[3]=='<' && item.title[8]=='>') { + sprintf(buf,"%s/%s", pbuf, item.filename); + setadir(buf, buf); + if(!(fp1 = fopen(buf, "r"))) + continue; + ptt->next_refresh[section] = ptt->n_notes[section] = id; + section ++; + while(fread(&subitem, sizeof(subitem), 1, fp1)) { + sprintf(buf,"%s/%s/%s", pbuf, item.filename , + subitem.filename); + if(!(fp2=fopen(buf,"r"))) + continue; + fread(ptt->notes[id],sizeof(char), 200*11, fp2); + ptt->notes[id][200*11 - 1]=0; + id++; + fclose(fp2); + if(id >= MAX_MOVIE) + break; + } + fclose(fp1); + if(id >= MAX_MOVIE || section >= MAX_MOVIE_SECTION) + break; + } + } + fclose(fp); + } + ptt->next_refresh[section] = -1; + ptt->n_notes[section] = ptt->max_film = id-1; + ptt->max_history = ptt->max_film - 2; + if(ptt->max_history > MAX_HISTORY - 1) + ptt->max_history = MAX_HISTORY - 1; + if(ptt->max_history <0) ptt->max_history=0; + + fp = fopen("etc/today_is","r"); + if(fp) { + fgets(ptt->today_is,15,fp); + if((chr = strchr(ptt->today_is,'\n'))) + *chr = 0; + ptt->today_is[15] = 0; + fclose(fp); + } + + /* µ¥©Ò¦³¸ê®Æ§ó·s«á¦A³]©w uptime */ + + ptt->uptime = ptt->touchtime ; +#if !defined(_BBS_UTIL_C_) + log_usies("CACHE", "reload pttcache"); +#endif + ptt->busystate = 0; + } +} + +void resolve_garbage() { + int count=0; + + if(ptt == NULL) { + ptt = attach_shm(PTTSHM_KEY, sizeof(*ptt)); + if(ptt->touchtime == 0) + ptt->touchtime = 1; + } + while(ptt->uptime < ptt->touchtime) { /* ¤£¥Îwhileµ¥ */ + reload_pttcache(); + if(count ++ > 10 && ptt->busystate) { +/* Ptt: ³oÃä·|¦³°ÝÃD load¶W¹L10 ¬í·|©Ò¦³¶iloopªºprocess³£Åý busystate = 0 + ³o¼Ë·|©Ò¦³prcosee³£·|¦bload °ÊºA¬ÝªO ·|³y¦¨load¤j¼W + ¦ý¨S¦³¥Î³oÓfunctionªº¸Ü ¸U¤@load passwdÀɪºprocess¦º¤F ¤S¨S¦³¤H§â¥L + ¸Ñ¶} ¦P¼Ëªº°ÝÃDµo¥Í¦breload passwd +*/ + ptt->busystate = 0; +#ifndef _BBS_UTIL_C_ + log_usies("CACHE", "refork Ptt dead lock"); +#endif + } + } +} + +/*-------------------------------------------------------*/ +/* PTT's cache */ +/*-------------------------------------------------------*/ +/* cachefor from host »P³Ì¦h¤W½u¤H¼Æ */ +struct fromcache_t *fcache; + +static void reload_fcache() { + if(fcache->busystate) + safe_sleep(1); + else { + FILE *fp; + + fcache->busystate = 1; + bzero(fcache->domain, sizeof fcache->domain); + if((fp = fopen("etc/domain_name_query","r"))) { + char buf[256],*po; + + fcache->top=0; + while(fgets(buf, sizeof(buf),fp)) { + if(buf[0] && buf[0] != '#' && buf[0] != ' ' && + buf[0] != '\n') { + sscanf(buf,"%s",fcache->domain[fcache->top]); + po = buf + strlen(fcache->domain[fcache->top]); + while(*po == ' ') + po++; + strncpy(fcache->replace[fcache->top],po,49); + fcache->replace[fcache->top] + [strlen(fcache->replace[fcache->top])-1] = 0; + (fcache->top)++; + if(fcache->top == MAX_FROM) + break; + } + } + } + + fcache->max_user=0; + + /* µ¥©Ò¦³¸ê®Æ§ó·s«á¦A³]©w uptime */ + fcache->uptime = fcache->touchtime; +#if !defined(_BBS_UTIL_C_) + log_usies("CACHE", "reload fcache"); +#endif + fcache->busystate = 0; + } +} + +void resolve_fcache() { + if(fcache == NULL) { + fcache = attach_shm(FROMSHM_KEY, sizeof(*fcache)); + if(fcache->touchtime == 0) + fcache->touchtime = 1; + } + while(fcache->uptime < fcache->touchtime) + reload_fcache(); +} + +extern time_t login_start_time; +extern char *fn_visable; +FILE *DEBUG = NULL; + +void hbflreload(int bid) +{ + int hbfl[MAX_FRIEND + 1], i, num, uid; + char buf[128]; + FILE *fp; + + 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("guest", buf) == 0 || + (uid = searchuser(buf)) == 0 ) { + --num; + continue; + } + hbfl[num] = uid; + } + fclose(fp); + } + hbfl[0] = time(NULL); + memcpy(uhash->hbfl[bid], hbfl, sizeof(hbfl)); +} + +int hbflcheck(int bid, int uid) +{ + int i; + + if( uhash->hbfl[bid][0] < login_start_time - HBFLexpire ) + hbflreload(bid); + for( i = 1 ; uhash->hbfl[bid][i] != 0 && i <= MAX_FRIEND ; ++i ){ + if( uhash->hbfl[bid][i] == uid ) + return 0; + } + return 1; +} diff --git a/mbbsd/cal.c b/mbbsd/cal.c new file mode 100644 index 00000000..680ee9d6 --- /dev/null +++ b/mbbsd/cal.c @@ -0,0 +1,512 @@ +/* $Id: cal.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <time.h> +#include <sys/types.h> +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "modes.h" +#include "perm.h" +#include "proto.h" + +extern struct utmpfile_t *utmpshm; +extern int usernum; + +/* ¨¾°ô Multi play */ +static int count_multiplay(int unmode) { + register int i, j; + register userinfo_t *uentp; + extern struct utmpfile_t *utmpshm; + + for(i = j = 0; i < USHM_SIZE; i++) { + uentp = &(utmpshm->uinfo[i]); + if(uentp->uid == usernum) + if(uentp->lockmode == unmode) + j++; + } + return j; +} + +extern userinfo_t *currutmp; +extern char *ModeTypeTable[]; + +int lockutmpmode(int unmode, int state) { + int errorno = 0; + + if(currutmp->lockmode) + errorno = 1; + else if(count_multiplay(unmode)) + errorno = 2; + + if(errorno && !(state == LOCK_THIS && errorno == LOCK_MULTI)) { + clear(); + move(10,20); + if(errorno == 1) + 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() { + currutmp->lockmode = 0; + return 0; +} + +extern userec_t cuser; +extern userec_t xuser; + +/* ¨Ï¥Î¿úªº¨ç¼Æ */ +#define VICE_NEW "vice.new" + +/* Heat:µo²¼ */ +int vice(int money, char* item) { + char buf[128]; + unsigned int viceserial=(currutmp->lastact%1000000)*100+rand()%100; + FILE *fp; + demoney(-money); + sprintf(buf, BBSHOME"/home/%c/%s/%s", + cuser.userid[0], cuser.userid, VICE_NEW); + fp = fopen(buf, "a"); + if(!fp ) + {return 0;} + + fprintf(fp, "%08d\n", viceserial); + fclose(fp); + sprintf(buf, "%s ªá¤F%d$ ½s¸¹[%08d]",item, money, viceserial); + mail_id(cuser.userid, buf, "etc/vice.txt", "Ptt¸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" +extern char trans_buffer[]; +extern char save_title[]; + +static int osong(char *defaultid) { + char destid[IDLEN + 1],buf[200],genbuf[200],filename[256],say[51]; + char receiver[60],ano[2]; + FILE *fp,*fp1;// *fp2; + fileheader_t mail; + time_t now; + int nsongs; + + now = time(NULL); + strcpy(buf, Cdatedate(&now)); + + lockreturn0(OSONG, LOCK_MULTI); + + /* Jaky ¤@¤H¤@¤ÑÂI¤@º */ + if(!strcmp(buf, Cdatedate(&cuser.lastsong)) && !HAS_PERM(PERM_SYSOP)) { + move(22,0); + outs("§A¤µ¤Ñ¤w¸gÂI¹LÅo¡A©ú¤Ñ¦AÂI§a...."); + refresh(); + pressanykey(); + + unlockutmpmode(); + return 0; + } + + if(cuser.money < 200) { + move(22, 0); + outs("ÂIºqn200»Èò!...."); + refresh(); + pressanykey(); + unlockutmpmode(); + return 0; + } + move(12, 0); + clrtobot(); + sprintf(buf, "¿Ë·Rªº %s Åwªï¨Ó¨ì¼Ú®á¦Û°ÊÂIºq¨t²Î\n", cuser.userid); + outs(buf); + trans_buffer[0] = 0; + if(!defaultid){ + getdata(13, 0, "nÂIµ¹½Ö©O:[¥iª½±µ«ö Enter ¥ý¿ïºq]", destid, IDLEN + 1, DOECHO); + while (!destid[0]){ + a_menu("ÂIºqºq¥»", SONGBOOK,0 ); + clear(); + getdata(13, 0, "nÂIµ¹½Ö©O:[¥i«ö Enter «·s¿ïºq]", destid, IDLEN + 1, DOECHO); + } + } + else + strcpy(destid,defaultid); + + /* Heat:ÂIºqªÌ°Î¦W¥\¯à */ + getdata(14,0, "n°Î¦W¶Ü?[y/n]:", ano, 2, DOECHO); + + if(!destid[0]) { + unlockutmpmode(); + return 0; + } + + getdata_str(14, 0, "·Qnn¹ï¥L(¦o)»¡..:", say, 51, DOECHO, "§Ú·R©p.."); + sprintf(save_title, "%s:%s", (ano[0]=='y')?"°Î¦WªÌ":cuser.userid, say); + getdata_str(16, 0, "±H¨ì½Öªº«H½c(¥i¥ÎE-mail)?", receiver, 45, + LCECHO, destid); + + + + if (!trans_buffer[0]){ + outs("\n±µµÛn¿ïºqÅo..¶i¤Jºq¥»¦n¦nªº¿ï¤@ººq§a..^o^"); + pressanykey(); + a_menu("ÂIºqºq¥»", SONGBOOK,0 ); + } + if(!trans_buffer[0] || strstr(trans_buffer, "home") || + strstr(trans_buffer, "boards") || !(fp = fopen(trans_buffer, "r"))) { + unlockutmpmode(); + return 0; + } + + strcpy(filename, OSONGPATH); + + stampfile(filename, &mail); + + unlink(filename); + + if(!(fp1 = fopen(filename, "w"))) { + fclose(fp); + unlockutmpmode(); + return 0; + } + + strcpy(mail.owner, "ÂIºq¾÷"); + sprintf(mail.title, "¡º %s ÂIµ¹ %s ", (ano[0]=='y')?"°Î¦WªÌ":cuser.userid, destid); + mail.savemode = 0; + + while(fgets(buf, 200, fp)) { + char *po; + if(!strncmp(buf, "¼ÐÃD: ", 6)) { + clear(); + move(10,10);prints("%s", buf); + pressanykey(); + fclose(fp); + unlockutmpmode(); + return 0; + } + while((po = strstr(buf, "<~Src~>"))) { + po[0] = 0; + sprintf(genbuf,"%s%s%s",buf,(ano[0]=='y')?"°Î¦WªÌ":cuser.userid,po+7); + strcpy(buf,genbuf); + } + while((po = strstr(buf, "<~Des~>"))) { + po[0] = 0; + sprintf(genbuf,"%s%s%s",buf,destid,po+7); + strcpy(buf,genbuf); + } + while((po = strstr(buf, "<~Say~>"))) { + po[0] = 0; + sprintf(genbuf,"%s%s%s",buf,say,po+7); + strcpy(buf,genbuf); + } + fputs(buf,fp1); + } + fclose(fp1); + fclose(fp); + +// do_append(OSONGMAIL "/.DIR", &mail2, sizeof(mail2)); + + if(do_append(OSONGPATH "/.DIR", &mail, sizeof(mail)) != -1) { + cuser.lastsong = time(NULL); + /* Jaky ¶W¹L 500 ººq´N¶}©l¬å */ + nsongs=get_num_records(OSONGPATH "/.DIR", sizeof(mail)); + if (nsongs > 500){ + delete_range(OSONGPATH "/.DIR", 1, nsongs-500); + } + /* §â²Ä¤@º®³±¼ */ + vice(200, "ÂIºq"); + } + sprintf(save_title, "%s:%s", (ano[0]=='y')?"°Î¦WªÌ":cuser.userid, say); + hold_mail(filename, destid); + + if(receiver[0]) { +#ifndef USE_BSMTP + bbs_sendmail(filename, save_title, receiver); +#else + bsmtp(filename, save_title, receiver,0); +#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() { + osong(NULL); + return 0; +} + +static int inmailbox(int m) { + passwd_query(usernum, &xuser); + cuser.exmailbox = xuser.exmailbox + m; + passwd_update(usernum, &cuser); + return cuser.exmailbox; +} + + +extern int b_lines; + +#if !HAVE_FREECLOAK +/* ªá¿ú¿ï³æ */ +int p_cloak() { + char buf[4]; + getdata(b_lines-1, 0, + currutmp->invisible ? "½T©wn²{¨?[y/N]" : "½T©wnÁô¨?[y/N]", + buf, 3, LCECHO); + if(buf[0] != 'y') + return 0; + if(cuser.money >= 19) { + vice(19, "cloak"); + currutmp->invisible %= 2; + outs((currutmp->invisible ^= 1) ? MSG_CLOAKED : MSG_UNCLOAK); + refresh(); + safe_sleep(1); + } + return 0; +} +#endif + +int p_from() { + char ans[4]; + + getdata(b_lines-2, 0, "½T©wn§ï¬G¶m?[y/N]", ans, 3, LCECHO); + if(ans[0] != 'y') + return 0; + reload_money(); + if(cuser.money < 49) + return 0; + if(getdata_buf(b_lines-1, 0, "½Ð¿é¤J·s¬G¶m:", + currutmp->from, 17, DOECHO)) { + vice(49,"home"); + currutmp->from_alias=0; + } + return 0; +} + +int p_exmail() { + char ans[4],buf[200]; + int n; + + if(cuser.exmailbox >= MAX_EXKEEPMAIL) { + sprintf(buf,"®e¶q³Ì¦h¼W¥[ %d «Ê¡A¤£¯à¦A¶R¤F¡C", MAX_EXKEEPMAIL); + outs(buf); + refresh(); + return 0; + } + sprintf(buf,"±z´¿¼WÁÊ %d «Ê®e¶q¡AÁÙn¦A¶R¦h¤Ö?", + cuser.exmailbox); + + getdata_str(b_lines-2, 0, buf, ans, 3, LCECHO, "10"); + + n = atoi(ans); + if(!ans[0] || !n) + return 0; + if(n + cuser.exmailbox > MAX_EXKEEPMAIL) + n = MAX_EXKEEPMAIL - cuser.exmailbox; + reload_money(); + if(cuser.money < n * 1000) + return 0; + vice(n * 1000, "mail"); + inmailbox(n); + return 0; +} + +void mail_redenvelop(char* from, char* to, int money, char mode){ + char genbuf[200]; + fileheader_t fhdr; + time_t now; + FILE* fp; + sprintf(genbuf, "home/%c/%s", to[0], to); + stampfile(genbuf, &fhdr); + if (!(fp = fopen(genbuf, "w"))) + return; + now = time(NULL); + fprintf(fp, "§@ªÌ: %s\n" + "¼ÐÃD: ©Û°]¶iÄ_\n" + "®É¶¡: %s\n" + "\033[1;33m¿Ë·Rªº %s ¡G\n\n\033[m" + "\033[1;31m §Ú¥]µ¹§A¤@Ó %d ¤¸ªº¤j¬õ¥]³á ^_^\n\n" + " §»´±¡·N«¡A½Ð¯º¯Ç...... ^_^\033[m\n" + , from, ctime(&now), to, money); + fclose(fp); + sprintf(fhdr.title, "©Û°]¶iÄ_"); + strcpy(fhdr.owner, from); + + if (mode == 'y') + vedit(genbuf, NA, NULL); + sprintf(genbuf, "home/%c/%s/.DIR", to[0], to); + append_record(genbuf, &fhdr, sizeof(fhdr)); +} + +int p_give() { + int money; + char id[IDLEN + 1], genbuf[90]; + time_t now = time(0); + + move(1,0); + usercomplete("³o¦ì©¯¹B¨àªºid:", id); + if(!id[0] || !strcmp(cuser.userid,id) || + !getdata(2, 0, "nµ¹¦h¤Ö¿ú:", genbuf, 7, LCECHO)) + return 0; + money = atoi(genbuf); + reload_money(); + if(money > 0 && cuser.money >= money ) { + deumoney(searchuser(id), money); + demoney(-money); + now = time(NULL); + sprintf(genbuf,"%s\tµ¹%s\t%d\t%s", cuser.userid, id, money, + ctime(&now)); + log_file(FN_MONEY, genbuf); + genbuf[0] = 'n'; + getdata(3, 0, "n¦Û¦æ®Ñ¼g¬õ¥]³U¶Ü¡H[y/N]", genbuf, 2, LCECHO); + mail_redenvelop(cuser.userid, id, money, genbuf[0]); + } + return 0; +} + +int p_sysinfo() { + char buf[100]; + long int total,used; + float p; + + move(b_lines-1,0); + clrtoeol(); + cpuload(buf); + outs("CPU t²ü : "); + outs(buf); + + p = swapused(&total,&used); + sprintf(buf, " µêÀÀ°O¾ÐÅé: %.1f%%(¥þ³¡:%ldMB ¥Î±¼:%ldMB)\n", + p*100, total >> 20, used >> 20); + outs(buf); + pressanykey(); + return 0; +} + +/* ¤ppºâ¾÷ */ +static void ccount(float *a, float b, int cmode) { + switch(cmode) { + case 0: + case 1: + case 2: + *a += b; + break; + case 3: + *a -= b; + break; + case 4: + *a *= b; + break; + case 5: + *a /= b; + break; + } +} + +int cal() { + float a = 0; + char flo = 0, ch = 0; + char mode[6] = {' ','=','+','-','*','/'} , cmode = 0; + char buf[100] = "[ 0] [ ] ", b[20] = "0"; + + move(b_lines - 1, 0); + clrtoeol(); + outs(buf); + move(b_lines, 0); + clrtoeol(); + outs("\033[44m ¤ppºâ¾÷ \033[31;47m (0123456789+-*/=) " + "\033[30m¿é¤J \033[31m " + "(Q)\033[30m Â÷¶} \033[m"); + while(1) { + ch = igetch(); + switch(ch) { + case '\r': + ch = '='; + case '=': + case '+': + case '-': + case '*': + case '/': + ccount(&a, atof(b), cmode); + flo = 0; + b[0] = '0'; + b[1] = 0; + move(b_lines - 1, 0); + sprintf(buf, "[%13.2f] [%c] ", a, ch); + outs(buf); + break; + case '.': + if(!flo) + flo = 1; + else + break; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '0': + if(strlen(b) > 13) + break; + if(flo || b[0] != '0') + sprintf(b,"%s%c",b,ch); + else + b[0]=ch; + move(b_lines - 1, 0); + sprintf(buf, "[%13s] [%c]", b, mode[(int)cmode]); + outs(buf); + break; + case 'q': + return 0; + } + + switch(ch) { + case '=': + a = 0; + cmode = 0; + break; + case '+': + cmode = 2; + break; + case '-': + cmode = 3; + break; + case '*': + cmode = 4; + break; + case '/': + cmode = 5; + break; + } + } +} diff --git a/mbbsd/calendar.c b/mbbsd/calendar.c new file mode 100644 index 00000000..78ca46cf --- /dev/null +++ b/mbbsd/calendar.c @@ -0,0 +1,284 @@ +/* $Id: calendar.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <sys/types.h> +#include "config.h" +#include "pttstruct.h" +#include "proto.h" +#include "modes.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) { + static int day[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + + return leap && m == 2 ? 29 : day[m - 1]; +} + +static int IsLeap(int y) { + if(y % 400 == 0 || (y % 4 == 0 && y % 100 != 0)) + return 1; + else + return 0; +} + +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, IsLeap(y)); + return w; +} + +static int ParseDate(char *date, event_t *t) { + char *y, *m, *d; + + y = strtok(date, "/"); + m = strtok(NULL, "/"); + d = strtok(NULL, ""); + if(!y || !m || !d) + return 1; + + t->year = atoi(y); + t->month = atoi(m); + t->day = atoi(d); + if(t->year < 1 || t->month < 1 || t->month > 12 || + t->day < 1 || t->day > 31) + return 1; + t->days = Days(t->year, t->month, t->day); + return 0; +} + +static int ParseColor(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; 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); + e = n; + } +} + +extern userec_t cuser; + +static event_t *ReadEvent(int today) { + FILE *fp; + char buf[256]; + static event_t head; + + head.next = NULL; + setcalfile(buf, cuser.userid); + fp = fopen(buf, "r"); + if(fp) { + while(fgets(buf, sizeof(buf), fp)) { + char *date, *color, *content; + event_t *t; + + if(buf[0] == '#') + continue; + + date = strtok(buf, " \t\n"); + color = strtok(NULL, " \t\n"); + content = strtok(NULL, "\n"); + if(!date || !color || !content) + continue; + + t = malloc(sizeof(event_t)); + if(ParseDate(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 "\33[0;30;47m" +#define HEADER_COLOR "\33[1;44m" +#define HEADER_SUNDAY_COLOR "\33[31m" +#define HEADER_DAY_COLOR "\33[33m" + +static int GenerateCalendar(char **buf, int y, int m, int today, event_t *e) { + static char *week_str[7] = {"¤é", "¤@", "¤G", "¤T", "¥|", "¤", "¤»"}; + static char *month_color[12] = { + "\33[1;32m", "\33[1;33m", "\33[1;35m", "\33[1;36m", + "\33[1;32m", "\33[1;33m", "\33[1;35m", "\33[1;36m", + "\33[1;32m", "\33[1;33m", "\33[1;35m", "\33[1;36m" + }; + static 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, "\33[m"); + + /* 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, IsLeap(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, "\33[1;%dm", e->color); + attr2 = CALENDAR_COLOR; + e = e->next; + } + if(today == first_day + i - 1) { + strcpy(attr1, "\33[1;37;42m"); + attr2 = CALENDAR_COLOR; + } + p += sprintf(p, "%s%2d%s", attr1, i, attr2); + + if(w == 6) { + p += sprintf(p, "\33[m"); + 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, "\33[m"); + } + return line + 1; +} + +int calendar() { + char **buf; + time_t t; + struct tm now; + int i, y, m, today, lines = 0; + event_t *head = NULL, *e = NULL; + + /* initialize date */ + time(&t); + memcpy(&now, localtime(&t), sizeof(struct tm)); + today = Days(now.tm_year + 1900, now.tm_mon + 1, now.tm_mday); + y = now.tm_year + 1900, m = now.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\33[1;37m²{¦b¬O %d.%02d.%02d %2d:%02d:%02d%cm\33[m", + now.tm_year + 1900, now.tm_mon + 1, now.tm_mday, + (now.tm_hour == 0 || now.tm_hour == 12) ? + 12 : now.tm_hour % 12, now.tm_min, now.tm_sec, + now.tm_hour >= 12 ? 'p' : 'a'); + } else if(i >= 2 && e) { + prints("\t\33[1;37m(\33[%dm%3d\33[37m)\33[m %02d/%02d %s", + e->color, e->days - today, + e->month, e->day, e->content); + e = e->next; + } + outc('\n'); + } + FreeEvent(head); + FreeCalBuffer(buf); + pressanykey(); + return 0; +} diff --git a/mbbsd/card.c b/mbbsd/card.c new file mode 100644 index 00000000..cfa10b0c --- /dev/null +++ b/mbbsd/card.c @@ -0,0 +1,625 @@ +/* $Id: card.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "modes.h" +#include "proto.h" +extern int usernum; + +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; +} + +/* 0 Spare , 1 heart , ...3 dimon */ +static int card_flower(int card) { + return (card / 13); +} + +/* 1...13 */ +static int card_number(int card) { + return (card % 13 + 1); +} + +static int card_select(int *now) { + char *cc[2] = {"\033[44m \033[m", + "\033[1;33;41m ¡µ \033[m"}; + + 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(egetch()) { + 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, int flower, int show) { + int color = 31; + char *cn[13] = {"¢Ï", "¢±", "¢²", "¢³", "¢´", "¢µ", + "¢¶", "¢·", "¢¸", "10", "¢Ø", "¢ß", "¢Ù"}; + if(flower == 0 || flower == 3) + color = 36; + if((show < 0) && (cline > 1 && cline < 8)) + prints("¢x\033[1;33;42m¡°¡°¡°¡°\033[m¢x"); + else + switch(cline) { + case 1: + prints("¢~¢w¢w¢w¢w¢¡"); + break; + case 2: + prints("¢x\033[1;%dm%s\033[m ¢x", color, cn[number - 1]); + break; + case 3: + if(flower == 1) + prints("¢x\033[1;%dm¢¨¢©¢¨¢©\033[m¢x", color); + else + prints("¢x\033[1;%dm ¢¨¢© \033[m¢x", color); + break; + case 4: + if(flower == 1) + prints("¢x\033[1;%dm¢i¢i¢i¢i\033[m¢x", color); + else if (flower == 3) + prints("¢x\033[1;%dm¢©¢i¢i¢¨\033[m¢x", color); + else + prints("¢x\033[1;%dm¢¨¢i¢i¢©\033[m¢x", color); + break; + case 5: + if(flower == 0) + prints("¢x\033[1;%dm¢i¢i¢i¢i\033[m¢x", color); + else if (flower == 3) + prints("¢x\033[1;%dm¢i¢ª¢«¢i\033[m¢x", color); + else + prints("¢x\033[1;%dm¢ª¢i¢i¢«\033[m¢x", color); + break; + case 6: + if(flower == 0) + prints("¢x\033[1;%dm ¢¨¢© \033[m¢x", color); + else if (flower == 3) + prints("¢x\033[1;%dm¢ª¢¨¢©¢«\033[m¢x", color); + else + prints("¢x\033[1;%dm ¢ª¢« \033[m¢x", color); + break; + case 7: + prints("¢x \033[1;%dm%s\033[m¢x", color, cn[number - 1]); + break; + case 8: + prints("¢¢¢w¢w¢w¢w¢£"); + break; + } +} + +static void card_show(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 < 5 && 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 < 5 && 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, error; + for(error=0, i=rand()%52; cards[i] == 1 && error<52; error++, i=rand()%52); + if(error==52) card_new(cards); // Ptt:³oÃ䦳dead lock°ÝÃD + cards[i] = 1; + return i; +} + +static void card_start(char name[]) { + clear(); + stand_title(name); + move(1, 0); + prints(" \033[1;33;41m ¹q ¸£ \033[m"); + move(10, 0); + prints("\033[1;34;44m¡»¡ã¡»¡ã¡»¡ã¡»¡ã¡»¡ã¡»¡ã¡»¡ã¡»¡ã¡»¡ã¡»¡ã¡»¡ã¡»¡ã" + "¡»¡ã¡»¡ã¡»¡ã¡»¡ã¡»¡ã¡»¡ã¡»¡ã¡»\033[m"); + move(19, 0); + prints(" \033[1;37;42m ¦Û ¤v \033[m"); +} + +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() { + int i, j, turn; + int cpu[5], c[5], me[5], m[5]; + int cards[52]; + int count = 0; + char *ff[4] = {"\033[1;36m¶Â®ç", "\033[1;31m¬õ¤ß", + "\033[1;31m¤è¶ô", "\033[1;36m¶Âªá"}; + 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(cpu, c, me, m); + j = 0; + turn = 1; + move(21, 0); + clrtoeol(); + prints("[0]¥Ø«e %d , ´Ý %d ÂI\n", count, 99 - count); + prints("¥ª¥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\033[m ¥Ø«e \033[1;31m%d/\033[34m%d\033[m Â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(cpu, c, me, m); + pressanykey(); + if(count > 99) { + move(22, 0); + clrtoeol(); + prints("[%d]µ²ªG..YOU LOSS..¥Ø«e \033[1;31m%d/\033[34m%d\033[m Â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\033[m ¥Ø«e \033[1;31m%d/\033[34m%d\033[m Â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 \033[1;31m%d/\033[34m%d\033[m Â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*/ + +extern userec_t cuser; + +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; + } + return 0; +} + +static int card_double_ask() { + char buf[100], buf2[3]; + + sprintf(buf, "[ %s ]±z²{¦b¦@¦³ %d P¹ô, ²{¦bn¤À²Õ(¥[¦¬ %d ¤¸)¶Ü? [y/N]", + cuser.userid, cuser.money, JACK); + reload_money(); + if(cuser.money < JACK) + return 0; + getdata(20, 0, buf, buf2, 2, LCECHO); + if(buf2[0] == 'y' || buf2[0] == 'Y') + return 1; + return 0; +} + +static int card_ask() { + char buf[100], buf2[3]; + + sprintf(buf, "[ %s ]±z²{¦b¦@¦³ %d P¹ô, ÁÙn¥[µP¶Ü? [y/N]", + cuser.userid, cuser.money); + getdata(20, 0 , buf, buf2, 2, 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 < 5 && 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 < 5 && all[i] >= 0 && count <= 11; i++) + if (card_number(all[i]) == 1) + count += 10; + return count; +} + +extern int b_lines; + +static int card_jack(int *db) { + int i, j; + int cpu[5], c[5], me[5], m[5]; + int cards[52]; + + for(i = 0;i<5;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_start("¶Â³Ç§JDOUBLE°l¥[§½"); + cpu[0] = card_give(cards); + cpu[1] = card_give(cards); + me[0] = *db; + me[1] = card_give(cards); + } + c[1] = m[0] = m[1] = 1; + card_show(cpu, c, me, m); + if((card_number(me[0]) == 0 && card_number(me[1]) == 12) || + (card_number(me[1]) == 0 && card_number(me[0]) == 12)) { + if(card_flower(me[0]) == 0 && card_flower(me[1]) == 0) { + move(b_lines - 1, 0); + prints("«D±`¤£¿ùò! (¶W¯Å¶Â³Ç§J!! ¥[ %d ¤¸)", JACK * 10); + game_log(JACK, JACK * 10); + pressanykey(); + return 0; + } else { + move(b_lines - 1, 0); + prints("«Ü¤£¿ùò! (¶Â³Ç§J!! ¥[ %d ¤¸)", JACK * 5); + game_log(JACK, JACK * 5); + pressanykey(); + return 0; + } + } + if((card_number(cpu[0]) == 0 && card_number(cpu[1]) == 12) || + (card_number(cpu[1]) == 0 && card_number(cpu[0]) == 12)) { + c[0] = 1; + card_show(cpu, c, me, m); + move(b_lines - 1, 0); + prints("¼K¼K...¤£¦n·N«ä....¶Â³Ç§J!!"); + game_log(JACK, 0); + pressanykey(); + return 0; + } + if((*db < 0)&& (card_number(me[0]) == card_number(me[1])) && + (card_double_ask())) { + *db = me[1]; + me[1] = card_give(cards); + card_show(cpu, c, me, m); + } + i = 2; + while(i < 5 && card_ask()) { + me[i] = card_give(cards); + m[i] = 1; + card_show(cpu, c, me, m); + if(card_alls_lower(me) > 21) { + move(b_lines - 1, 0); + prints("¶ã¶ã...Ãz±¼¤F!"); + game_log(JACK, 0); + pressanykey(); + return 0; + } + i++; + if((i == 3) && (card_number(me[0]) == 7) && + (card_number(me[1]) == 7) && (card_number(me[2]) == 7)) { + move(b_lines - 1, 0); + prints("«Ü¤£¿ùò! (©¯¹B¤C¸¹!! ¥[ %d ¤¸)", JACK * 7); + game_log(JACK, JACK * 7); + pressanykey(); + return 0; + } + } + if(i == 5) {/*¹L¤Ãö*/ + move(b_lines - 1, 0); + prints("¦n¼F®`ò! ¹L¤Ãö¹Æ! ¥[P¹ô %d ¤¸!", 5 * JACK); + game_log(JACK, JACK * 5); + pressanykey(); + return 0; + } + j = 2; + c[0] = 1; + while((card_alls_upper(cpu) < card_alls_upper(me))|| + ((card_alls_upper(cpu) == card_alls_upper(me) && j < i ) && j < 5)) { + cpu[j] = card_give(cards); + c[j] = 1; + if(card_alls_lower(cpu) > 21) { + card_show(cpu, c, me, m); + move(b_lines - 1, 0); + prints("¨þ¨þ...¹q¸£Ãz±¼¤F! §AŤF! ¥i±oP¹ô %d ¤¸", JACK * 2); + game_log(JACK, JACK * 2); + pressanykey(); + return 0; + } + j++; + } + card_show(cpu, c, me, m); + move(b_lines - 1, 0); + prints("«z«z...¹q¸£Ä¹¤F!"); + game_log(JACK, 0); + pressanykey(); + return 0; +} + +int g_card_jack() { + 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©wnª±¶Â³Ç§J¶Ü ¤@¦¸¤Q¤¸ò?(Y/N)?[N]", + buf, 3, LCECHO); + if((*buf != 'y') && (*buf != 'Y')) + break; + else { + db = -1; + vice(PMONEY, "¶Â³Ç§J"); + card_jack(&db); + if(db >= 0) + card_jack(&db); + } + } + 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() { + 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(cpu, c, me, m); + i = 1; + while(i < 5 && card_ask()) { + me[i] = card_give(cards); + m[i] = 1; + card_show(cpu, c, me, m); + if(card_all(me) > 21) { + move(b_lines - 1, 0); + prints("¶ã¶ã...Ãz±¼¤F!"); + game_log(TEN_HALF, 0); + pressanykey(); + return 0; + } + i++; + } + if(i == 5) {/*¹L¤Ãö*/ + move(b_lines - 1, 0); + prints("¦n¼F®`ò! ¹L¤Ãö¹Æ! ¥[P¹ô %d ¤¸!", 5 * PMONEY); + game_log(TEN_HALF, PMONEY * 5); + pressanykey(); + 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(cpu, c, me, m); + move(b_lines - 1, 0); + prints("¨þ¨þ...¹q¸£Ãz±¼¤F! §AŤF! ¥i±oP¹ô %d ¤¸", PMONEY * 2); + game_log(TEN_HALF, PMONEY * 2); + pressanykey(); + return 0; + } + j++; + } + card_show(cpu, c, me, m); + move(b_lines - 1, 0); + prints("«z«z...¹q¸£Ä¹¤F!"); + game_log(TEN_HALF, 0); + pressanykey(); + return 0; +} + +int g_ten_helf() { + char buf[3]; + + setutmpmode(TENHALF); + while(1) { + reload_money(); + if(cuser.money < TEN_HALF) { + outs("±zªº¿ú¤£°÷ò!¥h¦hµoªí¨Ç¦³·N¸qªº¤å³¹¦A¨Ó~~~"); + return 0; + } + getdata(b_lines - 1, 0, + "\033[1;37m½T©wnª±¤QÂI¥b¶Ü ¤@¦¸¤Q¤¸ò?(Y/N)?[N]\033[m", + 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 new file mode 100644 index 00000000..f75383a8 --- /dev/null +++ b/mbbsd/chat.c @@ -0,0 +1,623 @@ +/* $Id: chat.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <ctype.h> +#include <netdb.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include "config.h" +#include "pttstruct.h" +#include "perm.h" +#include "common.h" +#include "modes.h" +#include "proto.h" + +extern userinfo_t *currutmp; +static int chatline; +static int stop_line; /* next line of bottom of message window area */ +static FILE *flog; + +static void printchatline(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); +} + +extern int b_lines; /* Screen bottom line number: t_lines-1 */ + +static void chat_clear() { + 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(char *chatid) { + move(b_lines - 1, 0); + clrtoeol(); + outs(chatid); + outc(':'); +} + +static int chat_send(int fd, char *buf) { + int len; + char genbuf[200]; + + sprintf(genbuf, "%s\n", buf); + len = strlen(genbuf); + return (send(fd, genbuf, len, 0) == len); +} + +static char chatroom[IDLEN]; /* Chat-Room Name */ + +static int chat_recv(int fd, char *chatid) { + static char buf[512]; + static int bufstart = 0; + char genbuf[200]; + int c, len; + char *bptr; + + len = sizeof(buf) - bufstart - 1; + if((c = recv(fd, buf + bufstart, len, 0)) <= 0) + return -1; + c += bufstart; + + bptr = buf; + while(c > 0) { + len = strlen(bptr) + 1; + if(len > c && len < (sizeof buf / 2)) + break; + + if(*bptr == '/') { + switch(bptr[1]) { + case 'c': + chat_clear(); + break; + case 'n': + strncpy(chatid, bptr + 2, 8); + print_chatid(chatid); + clrtoeol(); + break; + case 'r': + strncpy(chatroom, bptr + 2, IDLEN - 1); + break; + case 't': + move(0, 0); + clrtoeol(); + sprintf(genbuf, "½Í¤Ñ«Ç [%s]", chatroom); + prints("\033[1;37;46m %-21s \033[45m ¸ÜÃD¡G%-48s\033[m", + genbuf, bptr + 2); + } + } else + printchatline(bptr); + + c -= len; + bptr += len; + } + + if(c > 0) { + strcpy(genbuf, bptr); + strcpy(buf, genbuf); + bufstart = len - 1; + } else + bufstart = 0; + return 0; +} + +extern userec_t cuser; + +static int printuserent(userinfo_t *uentp) { + static char uline[80]; + static int cnt; + char pline[30]; + + if(!uentp) { + if(cnt) + printchatline(uline); + bzero(uline, 80); + cnt = 0; + return 0; + } + if(!HAS_PERM(PERM_SYSOP) && !HAS_PERM(PERM_SEECLOAK) && uentp->invisible) + return 0; + + sprintf(pline, "%-13s%c%-10s ", uentp->userid, + uentp->invisible ? '#' : ' ', + modestring(uentp, 1)); + if(cnt < 2) + strcat(pline, "¢x"); + strcat(uline, pline); + if(++cnt == 3) { + printchatline(uline); + memset(uline, 0, 80); + cnt = 0; + } + return 0; +} + +static void chathelp(char *cmd, char *desc) { + char buf[STRLEN]; + + sprintf(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", "MUD-like ªÀ¥æ°Êµü"); + chathelp("[/.]help", "chicken °«Âû¥Î«ü¥O"); + chathelp("[/h]elp op", "½Í¤Ñ«ÇºÞ²zû±M¥Î«ü¥O"); + 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", "¬d¸ßºô¤Í"); + chathelp("[/r]oom", "¦C¥X¤@¯ë½Í¤Ñ«Ç"); + chathelp("[/u]sers", "¦C¥X¯¸¤W¨Ï¥ÎªÌ"); + chathelp("[/w]ho", "¦C¥X¥»½Í¤Ñ«Ç¨Ï¥ÎªÌ"); + chathelp("[/w]hoin <room>", "¦C¥X½Í¤Ñ«Ç<room> ªº¨Ï¥ÎªÌ"); + } +} + +static void chat_date() { + time_t thetime; + char genbuf[200]; + + time(&thetime); + sprintf(genbuf, "¡» " BBSNAME "¼Ð·Ç®É¶¡: %s", Cdate(&thetime)); + printchatline(genbuf); +} + +static void chat_pager() { + char genbuf[200]; + + char *msgs[] = {"Ãö³¬", "¥´¶}", "©Þ±¼", "¨¾¤ô","¦n¤Í"}; + sprintf(genbuf, "¡» ±zªº©I¥s¾¹:[%s]", + msgs[currutmp->pager = (currutmp->pager+1)%5]); + printchatline(genbuf); +} + +extern char *str_space; +extern userec_t xuser; +extern char *fn_plans; +extern char *err_uid; + +static void chat_query(char *arg) { + char *uid; + int tuid; + + printchatline(""); + strtok(arg, str_space); + if((uid = strtok(NULL, str_space)) && (tuid = getuser(uid))) { + char buf[128], *ptr; + FILE *fp; + + sprintf(buf, "%s(%s) ¦@¤W¯¸ %d ¦¸¡Aµoªí¹L %d ½g¤å³¹", + xuser.userid, xuser.username, xuser.numlogins, xuser.numposts); + printchatline(buf); + + sprintf(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); +} + +extern char *msg_shortulist; + +static void chat_users() { + printchatline(""); + printchatline("¡i " BBSNAME "ªº¹C«È¦Cªí ¡j"); + printchatline(msg_shortulist); + + if(apply_ulist(printuserent) == -1) + printchatline("ªÅµL¤@¤H"); + printuserent(NULL); +} + +typedef struct chat_command_t { + char *cmdname; /* Chatroom command length */ + void (*cmdfunc) (); /* Pointer to function */ +} chat_command_t; + +static chat_command_t chat_cmdtbl[] = { + {"help", chat_help}, + {"clear", chat_clear}, + {"date", chat_date}, + {"pager", chat_pager}, + {"query", chat_query}, + {"users", chat_users}, + {NULL, NULL} +}; + +static int chat_cmd_match(char *buf, char *str) { + while(*str && *buf && !isspace(*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; +} + +extern char trans_buffer[256]; /* ¤@¯ë¶Ç»¼ÅÜ¼Æ add by Ptt */ + +#if 0 +static char *select_address() { + int c; + FILE *fp; + char nametab[25][90]; + char iptab[25][18], buf[80]; + + move(1, 0); + clrtobot(); + outs("\n \033[36m¡i§äÓ¦a¤è©ï©ïºb§a!¡j\033[m " + "¡· ¡i¥H¤U¬°¥»¯¸µn°O¦³®×ªº¯ù¼Ó¡j \n"); + trans_buffer[0]=0; + if((fp = fopen("etc/teashop", "r"))) { + for(c = 0; fscanf(fp, "%s%s", iptab[c], nametab[c]) != EOF; c++) { + sprintf(buf,"\n (\033[36m%d\033[0m) %-30s [%s]", + c + 1, nametab[c], iptab[c]); + outs(buf); + } + getdata(20, 10, "¡¹\033[32m ½Ð¿ï¾Ü¡A[0]Â÷¶}¡G\033[0m", buf, 3, + LCECHO); + if(buf[1]) + buf[0] = (buf[0] + 1) * 10 + (buf[1] - '1'); + else + buf[0] -= '1'; + if(buf[0] >= 0 && buf[0] < c) + strcpy(trans_buffer,iptab[(int)buf[0]]); + } else { + outs("¥»¯¸¨S¦³µn°O¥ô¦ó¦X®æ¯ù¼Ó"); + pressanykey(); + } + return trans_buffer; +} +#endif + +extern int usernum; +extern int t_lines; +extern char *msg_seperator; +#define MAXLASTCMD 6 +static int chatid_len = 10; + +int t_chat() { + char inbuf[80], chatid[20], lastcmd[MAXLASTCMD][80], *ptr = ""; + struct sockaddr_in sin; + struct hostent *h; + int cfd, cmdpos, ch; + int currchar; + int newmail; + int chatting = YEA; + char fpath[80]; + char genbuf[200]; + char roomtype; + + if(inbuf[0] == 0) + return -1; + + outs(" ÅX¨®«e©¹ ½Ð±éÔ........ "); + if(!(h = gethostbyname("localhost"))) { + perror("gethostbyname"); + return -1; + } + memset(&sin, 0, sizeof sin); +#ifdef FreeBSD + sin.sin_len = sizeof(sin); +#endif + sin.sin_family = PF_INET; + memcpy(&sin.sin_addr, h->h_addr, h->h_length); + sin.sin_port = htons(NEW_CHATPORT); + cfd = socket(sin.sin_family, SOCK_STREAM, 0); + if(!(connect(cfd, (struct sockaddr *) & sin, sizeof sin))) + roomtype = 1; + else { + sin.sin_port = CHATPORT; + cfd = socket(sin.sin_family, SOCK_STREAM, 0); + if(!(connect(cfd, (struct sockaddr *) & sin, sizeof sin))) + roomtype = 2; + else { + outs("\n " + "«z! ¨S¤H¦b¨ºÃäC...n¦³¨º¦a¤èªº¤H¥ý¥h¶}ªù°Õ!..."); + system("bin/xchatd"); + pressanykey(); + return -1; + } + } + + while(1) { + getdata(b_lines - 1, 0, "½Ð¿é¤J²á¤Ñ¥N¸¹¡G", inbuf, 9, DOECHO); + sprintf(chatid, "%s", (inbuf[0] ? inbuf : cuser.userid)); + chatid[8] = '\0'; +/* + ®榡: /! ¨Ï¥ÎªÌ½s¸¹ ¨Ï¥ÎªÌµ¥¯Å UserID ChatID + ·s®æ¦¡: /! UserID ChatID Password +*/ + if(roomtype == 1) + sprintf(inbuf, "/! %s %s %s", + cuser.userid, chatid, cuser.passwd); + else + sprintf(inbuf, "/! %d %d %s %s", + usernum, cuser.userlevel, cuser.userid, chatid); + chat_send(cfd, inbuf); + if(recv(cfd, inbuf, 3, 0) != 3) + 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(); + } + + add_io(cfd, 0); + + newmail = currchar = 0; + cmdpos = -1; + memset(lastcmd, 0, MAXLASTCMD * 80); + + setutmpmode(CHATING); + currutmp->in_chat = YEA; + strcpy(currutmp->chatid, chatid); + + clear(); + chatline = 2; + strcpy(inbuf, chatid); + stop_line = t_lines - 3; + + move(stop_line, 0); + outs(msg_seperator); + move(1, 0); + outs(msg_seperator); + print_chatid(chatid); + memset(inbuf, 0, 80); + + sethomepath(fpath, cuser.userid); + strcpy(fpath, tempnam(fpath, "chat_")); + flog = fopen(fpath, "w"); + + while(chatting) { + move(b_lines - 1, currchar + chatid_len); + ch = igetkey(); + + switch(ch) { + case KEY_DOWN: + cmdpos += MAXLASTCMD - 2; + case KEY_UP: + cmdpos++; + cmdpos %= MAXLASTCMD; + strcpy(inbuf, lastcmd[cmdpos]); + move(b_lines - 1, chatid_len); + clrtoeol(); + outs(inbuf); + currchar = strlen(inbuf); + continue; + case KEY_LEFT: + if(currchar) + --currchar; + continue; + case KEY_RIGHT: + if(inbuf[currchar]) + ++currchar; + continue; + } + + if(!newmail && currutmp->mailalert ) { + newmail = 1; + printchatline("¡» ¾´¡I¶l®t¤S¨Ó¤F..."); + } + + if(ch == I_OTHERDATA) { /* incoming */ + if(chat_recv(cfd, chatid) == -1) { + chatting = chat_send(cfd, "/b"); + break; + } + continue; + } + 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++]); + } + continue; + } + + if(ch == '\n' || ch == '\r') { + if(*inbuf) { + 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--) + strcpy(lastcmd[cmdpos], lastcmd[cmdpos - 1]); + strcpy(lastcmd[0], inbuf); + + inbuf[0] = '\0'; + currchar = 0; + cmdpos = -1; + } + print_chatid(chatid); + move(b_lines - 1, chatid_len); + continue; + } + + if(ch == Ctrl('H') || ch == '\177') { + if(currchar) { + currchar--; + inbuf[69] = '\0'; + memcpy(&inbuf[currchar], &inbuf[currchar + 1], 69 - currchar); + move(b_lines - 1, currchar + chatid_len); + clrtoeol(); + outs(&inbuf[currchar]); + } + continue; + } + if(ch == Ctrl('Z') || ch == Ctrl('Y')) { + inbuf[0] = '\0'; + currchar = 0; + print_chatid(chatid); + move(b_lines - 1, chatid_len); + continue; + } + + if(ch == Ctrl('C')) { + chat_send(cfd, "/b"); + break; + } + if(ch == Ctrl('D')) { + if(currchar < strlen(inbuf)) { + inbuf[69] = '\0'; + memcpy(&inbuf[currchar], &inbuf[currchar + 1], 69 - currchar); + move(b_lines - 1, currchar + chatid_len); + clrtoeol(); + outs(&inbuf[currchar]); + } + continue; + } + if(ch == Ctrl('K')) { + inbuf[currchar] = 0; + move(b_lines - 1, currchar + chatid_len); + clrtoeol(); + continue; + } + if(ch == Ctrl('A')) { + currchar = 0; + continue; + } + if(ch == Ctrl('E')) { + currchar = strlen(inbuf); + continue; + } + if(ch == Ctrl('I')) { + extern screenline_t *big_picture; + screenline_t *screen0 = calloc(t_lines, sizeof(screenline_t)); + + memcpy(screen0, big_picture, t_lines * sizeof(screenline_t)); + add_io(0, 0); + t_idle(); + memcpy(big_picture, screen0, t_lines * sizeof(screenline_t)); + free(screen0); + redoscr(); + add_io(cfd, 0); + continue; + } + 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, 4, LCECHO); + if (*ans == 'm') { + fileheader_t mymail; + char title[128]; + + sethomepath(genbuf, cuser.userid); + stampfile(genbuf, &mymail); + mymail.savemode = 'H'; /* hold-mail flag */ + mymail.filemode = FILE_READ; + strcpy(mymail.owner, "[³Æ.§Ñ.¿ý]"); + strcpy(mymail.title, "·|ij\033[1;33m°O¿ý\033[m"); + sethomedir(title, cuser.userid); + append_record(title, &mymail, sizeof(mymail)); + Rename(fpath, genbuf); + } else + unlink(fpath); + } + + return 0; +} +/* -------------------------------------------------- */ +#if 0 + +extern char page_requestor[]; +extern userinfo_t *currutmp; + +#endif diff --git a/mbbsd/chc_draw.c b/mbbsd/chc_draw.c new file mode 100644 index 00000000..b3bd216f --- /dev/null +++ b/mbbsd/chc_draw.c @@ -0,0 +1,187 @@ +/* $Id: chc_draw.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <sys/types.h> +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "proto.h" + +#define SIDE_ROW 10 +#define TURN_ROW 11 +#define STEP_ROW 12 +#define TIME_ROW 13 +#define WARN_ROW 15 +#define MYWIN_ROW 17 +#define HISWIN_ROW 18 + +extern char chc_warnmsg[64], *chc_mateid; +extern rc_t chc_from, chc_to, chc_select; +extern int chc_selected, chc_my, chc_turn, chc_firststep; +extern int chc_lefttime; +extern int chc_hiswin, chc_hislose, chc_histie; + +static char *turn_str[2] = {"¶Âªº", "¬õªº"}; + +static char *num_str[10] = { + "", "¤@", "¤G", "¤T", "¥|", "¤", "¤»", "¤C", "¤K", "¤E" +}; + +static char *chess_str[2][8] = { + /* 0 1 2 3 4 5 6 7 */ + {" ", "±N", "¤h", "¶H", "¨®", "°¨", "¥]", "¨ò"}, + {" ", "«Ó", "¥K", "¬Û", "¨®", "ØX", "¬¶", "§L"} +}; + +static char *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 *hint_str[] = { + " q »{¿éÂ÷¶}", + " p n¨D©M´Ñ", + "¤è¦VÁä ²¾°Ê¹C¼Ð", + "Enter ¿ï¾Ü/²¾°Ê" +}; + +void chc_movecur(int r, int c) { + move(r * 2 + 3, c * 4 + 4); +} + +#define BLACK_COLOR "\033[1;36m" +#define RED_COLOR "\033[1;31m" +#define BLACK_REVERSE "\033[1;37;46m" +#define RED_REVERSE "\033[1;37;41m" +#define TURN_COLOR "\033[1;33m" + +static void showstep(board_t board) { + int turn, fc, tc, eatten; + char *dir; + + turn = CHE_O(board[chc_from.r][chc_from.c]); + fc = (turn == (chc_my ^ 1) ? chc_from.c + 1 : 9 - chc_from.c); + tc = (turn == (chc_my ^ 1) ? chc_to.c + 1 : 9 - chc_to.c); + if(chc_from.r == chc_to.r) + dir = "¥"; + else { + if(chc_from.c == chc_to.c) + tc = chc_from.r - chc_to.r; + if(tc < 0) tc = -tc; + + if((turn == (chc_my ^ 1) && chc_to.r > chc_from.r) || + (turn == chc_my && chc_to.r < chc_from.r)) + dir = "¶i"; + else + dir = "°h"; + } + prints("%s%s%s%s%s", + turn == 0 ? BLACK_COLOR : RED_COLOR, + chess_str[turn][CHE_P(board[chc_from.r][chc_from.c])], + num_str[fc], dir, num_str[tc]); + eatten = board[chc_to.r][chc_to.c]; + if(eatten) + prints("¡G %s%s", + CHE_O(eatten) == 0 ? BLACK_COLOR : RED_COLOR, + chess_str[CHE_O(eatten)][CHE_P(eatten)]); + prints("\033[m"); +} + +extern userec_t cuser; + +void chc_drawline(board_t board, int line) { + int i, j; + + move(line, 0); + clrtoeol(); + if(line == 0) { + prints("\033[1;46m ¶H´Ñ¹ï¾Ô \033[45m%30s VS %-30s\033[m", + cuser.userid, chc_mateid); + } else if(line >= 3 && line <= 21) { + outs(" "); + for(i = 0; i < 9; i++) { + j = board[RTL(line)][i]; + if((line & 1) == 1 && j) { + if(chc_selected && + chc_select.r == RTL(line) && chc_select.c == i) + prints("%s%s\033[m", + CHE_O(j) == 0 ? BLACK_REVERSE : RED_REVERSE, + chess_str[CHE_O(j)][CHE_P(j)]); + else + prints("%s%s\033[m", + CHE_O(j) == 0 ? BLACK_COLOR : RED_COLOR, + 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]); + } + outs(" "); + + if(line >= 3 && line < 3 + dim(hint_str)) { + outs(hint_str[line - 3]); + } else if(line == SIDE_ROW) { + prints("\033[1m§A¬O%s%s\033[m", + chc_my == 0 ? BLACK_COLOR : RED_COLOR, + turn_str[chc_my]); + } else if(line == TURN_ROW) { + prints("%s%s\033[m", + TURN_COLOR, + chc_my == chc_turn ? "½ü¨ì§A¤U´Ñ¤F" : "µ¥«Ý¹ï¤è¤U´Ñ"); + } else if(line == STEP_ROW && !chc_firststep) { + showstep(board); + } else if(line == TIME_ROW) { + prints("³Ñ¾l®É¶¡ %d:%02d", chc_lefttime / 60, chc_lefttime % 60); + } else if(line == WARN_ROW) { + outs(chc_warnmsg); + } else if(line == MYWIN_ROW) { + prints("\033[1;33m%12.12s " + "\033[1;31m%2d\033[37m³Ó " + "\033[34m%2d\033[37m±Ñ " + "\033[36m%2d\033[37m©M\033[m", + cuser.userid, + cuser.chc_win, cuser.chc_lose - 1, cuser.chc_tie); + } else if(line == HISWIN_ROW) { + prints("\033[1;33m%12.12s " + "\033[1;31m%2d\033[37m³Ó " + "\033[34m%2d\033[37m±Ñ " + "\033[36m%2d\033[37m©M\033[m", + chc_mateid, + chc_hiswin, chc_hislose - 1, chc_histie); + } + } else if(line == 2 || line == 22) { + outs(" "); + if(line == 2) + for(i = 1; i <= 9; i++) + prints("%s ", num_str[i]); + else + for(i = 9; i >= 1; i--) + prints("%s ", num_str[i]); + } +} + +void chc_redraw(board_t board) { + int i; + + for(i = 0; i <= 22; i++) + chc_drawline(board, i); +} diff --git a/mbbsd/chc_net.c b/mbbsd/chc_net.c new file mode 100644 index 00000000..d094d5f2 --- /dev/null +++ b/mbbsd/chc_net.c @@ -0,0 +1,28 @@ +/* $Id: chc_net.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <sys/types.h> +#include <unistd.h> +#include "config.h" +#include "pttstruct.h" + +extern rc_t chc_from, chc_to; + +typedef struct drc_t { + rc_t from, to; +} drc_t; + +int chc_recvmove(int s) { + drc_t buf; + + if(read(s, &buf, sizeof(buf)) != sizeof(buf)) + return 1; + chc_from = buf.from, chc_to = buf.to; + return 0; +} + +void chc_sendmove(int s) { + drc_t buf; + + buf.from = chc_from, buf.to = chc_to; + write(s, &buf, sizeof(buf)); +} diff --git a/mbbsd/chc_play.c b/mbbsd/chc_play.c new file mode 100644 index 00000000..86c17fbc --- /dev/null +++ b/mbbsd/chc_play.c @@ -0,0 +1,277 @@ +/* $Id: chc_play.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <time.h> +#include <unistd.h> +#include <sys/types.h> +#include <string.h> +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "modes.h" +#include "proto.h" + +extern userinfo_t *currutmp; +extern int usernum; + +typedef int (*play_func_t)(int, board_t, board_t); + +static int chc_ipass = 0, chc_hepass = 0; +int chc_lefttime; +int chc_my, chc_turn, chc_selected, chc_firststep; +char chc_warnmsg[64], *chc_mateid; +rc_t chc_from, chc_to, chc_select, chc_cursor; +int chc_hiswin, chc_hislose, chc_histie; + +#define CHC_TIMEOUT 300 +#define SIDE_ROW 10 +#define TURN_ROW 11 +#define STEP_ROW 12 +#define TIME_ROW 13 +#define WARN_ROW 15 +#define MYWIN_ROW 17 +#define HISWIN_ROW 18 + +static int hisplay(int s, board_t board, board_t tmpbrd) { + int start_time; + int endgame = 0, endturn = 0; + + start_time = time(NULL); + while(!endturn) { + chc_lefttime = CHC_TIMEOUT - (time(NULL) - start_time); + if(chc_lefttime < 0) { + chc_lefttime = 0; + + /* to make him break out igetkey() */ + chc_from.r = -2; + chc_sendmove(s); + } + chc_drawline(board, TIME_ROW); + move(1, 0); + oflush(); + switch(igetkey()) { + case 'q': + endgame = 2; + endturn = 1; + break; + case 'p': + if(chc_hepass) { + chc_from.r = -1; + chc_sendmove(s); + endgame = 3; + endturn = 1; + } + break; + case I_OTHERDATA: + if(chc_recvmove(s)) { /* disconnect */ + endturn = 1; + endgame = 1; + } else { + if(chc_from.r == -1) { + chc_hepass = 1; + strcpy(chc_warnmsg, "\033[1;33mn¨D©M§½!\033[m"); + chc_drawline(board, WARN_ROW); + } else { + chc_from.r = 9 - chc_from.r, chc_from.c = 8 - chc_from.c; + chc_to.r = 9 - chc_to.r, chc_to.c = 8 - chc_to.c; + chc_cursor = chc_to; + if(CHE_P(board[chc_to.r][chc_to.c]) == 1) + endgame = 2; + endturn = 1; + chc_hepass = 0; + chc_drawline(board, STEP_ROW); + chc_movechess(board); + chc_drawline(board, LTR(chc_from.r)); + chc_drawline(board, LTR(chc_to.r)); + } + } + break; + } + } + return endgame; +} + +static int myplay(int s, board_t board, board_t tmpbrd) { + int ch, start_time; + int endgame = 0, endturn = 0; + + chc_ipass = 0, chc_selected = 0; + start_time = time(NULL); + chc_lefttime = CHC_TIMEOUT - (time(NULL) - start_time); + bell(); + while(!endturn) { + chc_drawline(board, TIME_ROW); + chc_movecur(chc_cursor.r, chc_cursor.c); + oflush(); + ch = igetkey(); + chc_lefttime = CHC_TIMEOUT - (time(NULL) - start_time); + if(chc_lefttime < 0) + ch = 'q'; + switch(ch) { + case I_OTHERDATA: + if(chc_recvmove(s)) { /* disconnect */ + endgame = 1; + endturn = 1; + } else if(chc_from.r == -1 && chc_ipass) { + endgame = 3; + endturn = 1; + } + break; + case KEY_UP: + chc_cursor.r--; + if(chc_cursor.r < 0) + chc_cursor.r = BRD_ROW - 1; + break; + case KEY_DOWN: + chc_cursor.r++; + if(chc_cursor.r >= BRD_ROW) + chc_cursor.r = 0; + break; + case KEY_LEFT: + chc_cursor.c--; + if(chc_cursor.c < 0) + chc_cursor.c = BRD_COL - 1; + break; + case KEY_RIGHT: + chc_cursor.c++; + if(chc_cursor.c >= BRD_COL) + chc_cursor.c = 0; + break; + case 'q': + endgame = 2; + endturn = 1; + break; + case 'p': + chc_ipass = 1; + chc_from.r = -1; + chc_sendmove(s); + strcpy(chc_warnmsg, "\033[1;33mn¨D©M´Ñ!\033[m"); + chc_drawline(board, WARN_ROW); + bell(); + break; + case '\r': + case '\n': + case ' ': + if(chc_selected) { + if(chc_cursor.r == chc_select.r && + chc_cursor.c == chc_select.c) { + chc_selected = 0; + chc_drawline(board, LTR(chc_cursor.r)); + } else if(chc_canmove(board, chc_select, chc_cursor)) { + if(CHE_P(board[chc_cursor.r][chc_cursor.c]) == 1) + endgame = 1; + chc_from = chc_select; + chc_to = chc_cursor; + if(!endgame) { + memcpy(tmpbrd, board, sizeof(board_t)); + chc_movechess(tmpbrd); + } + if(endgame || !chc_iskfk(tmpbrd)) { + chc_drawline(board, STEP_ROW); + chc_movechess(board); + chc_sendmove(s); + chc_selected = 0; + chc_drawline(board, LTR(chc_from.r)); + chc_drawline(board, LTR(chc_to.r)); + endturn = 1; + } else { + strcpy(chc_warnmsg, "\033[1;33m¤£¥i¥H¤ý¨£¤ý\033[m"); + bell(); + chc_drawline(board, WARN_ROW); + } + } + } else if(board[chc_cursor.r][chc_cursor.c] && + CHE_O(board[chc_cursor.r][chc_cursor.c]) == chc_turn) { + chc_selected = 1; + chc_select = chc_cursor; + chc_drawline(board, LTR(chc_cursor.r)); + } + break; + } + } + return endgame; +} + +extern userec_t cuser; + +static void mainloop(int s, board_t board) { + int endgame; + board_t tmpbrd; + play_func_t play_func[2]; + + play_func[chc_my] = myplay; + play_func[chc_my ^ 1] = hisplay; + for(chc_turn = 1, endgame = 0; !endgame; chc_turn ^= 1) { + chc_firststep = 0; + chc_drawline(board, TURN_ROW); + if(chc_ischeck(board, chc_turn)) { + strcpy(chc_warnmsg, "\033[1;31m±Nx!\033[m"); + bell(); + } else + chc_warnmsg[0] = 0; + chc_drawline(board, WARN_ROW); + endgame = play_func[chc_turn](s, board, tmpbrd); + } + + if(endgame == 1) { + strcpy(chc_warnmsg, "¹ï¤è»{¿é¤F!"); + cuser.chc_win++; + } else if(endgame == 2) { + strcpy(chc_warnmsg, "§A»{¿é¤F!"); + cuser.chc_lose++; + } else { + strcpy(chc_warnmsg, "©M´Ñ"); + cuser.chc_tie++; + } + cuser.chc_lose--; + passwd_update(usernum, &cuser); + chc_drawline(board, WARN_ROW); + bell(); + oflush(); +} + +extern userec_t xuser; + +static void chc_init(int s, board_t board) { + userinfo_t *my = currutmp; + + setutmpmode(CHC); + clear(); + chc_warnmsg[0] = 0; + chc_my = my->turn; + chc_mateid = my->mateid; + chc_firststep = 1; + chc_init_board(board); + chc_redraw(board); + chc_cursor.r = 9, chc_cursor.c = 0; + add_io(s, 0); + + if(my->turn) chc_recvmove(s); + passwd_query(usernum, &xuser); + cuser.chc_win = xuser.chc_win; + cuser.chc_lose = xuser.chc_lose + 1; + cuser.chc_tie = xuser.chc_tie; + cuser.money = xuser.money; + passwd_update(usernum, &cuser); + + getuser(chc_mateid); + chc_hiswin = xuser.chc_win; + chc_hislose = xuser.chc_lose; + chc_histie = xuser.chc_tie; + + if(!my->turn) { + chc_sendmove(s); + chc_hislose++; + } + + chc_redraw(board); +} + +void chc(int s) { + board_t board; + + chc_init(s, board); + mainloop(s, board); + close(s); + add_io(0, 0); + if(chc_my) pressanykey(); +} diff --git a/mbbsd/chc_rule.c b/mbbsd/chc_rule.c new file mode 100644 index 00000000..35d8fe6a --- /dev/null +++ b/mbbsd/chc_rule.c @@ -0,0 +1,186 @@ +/* $Id: chc_rule.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <sys/types.h> +#include <string.h> +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "proto.h" + +extern rc_t chc_from, chc_to; +extern int chc_my; + +#define CENTER(a, b) (((a) + (b)) >> 1) + +void chc_init_board(board_t board) { + memset(board, 0, sizeof(board_t)); + board[0][4] = CHE(1, chc_my ^ 1); /* ±N */ + board[0][3] = board[0][5] = CHE(2, chc_my ^ 1); /* ¤h */ + board[0][2] = board[0][6] = CHE(3, chc_my ^ 1); /* ¶H */ + board[0][0] = board[0][8] = CHE(4, chc_my ^ 1); /* ¨® */ + board[0][1] = board[0][7] = CHE(5, chc_my ^ 1); /* °¨ */ + board[2][1] = board[2][7] = CHE(6, chc_my ^ 1); /* ¥] */ + board[3][0] = board[3][2] = board[3][4] = + board[3][6] = board[3][8] = CHE(7, chc_my ^ 1); /* ¨ò */ + + board[9][4] = CHE(1, chc_my); /* «Ó */ + board[9][3] = board[9][5] = CHE(2, chc_my); /* ¥K */ + board[9][2] = board[9][6] = CHE(3, chc_my); /* ¬Û */ + board[9][0] = board[9][8] = CHE(4, chc_my); /* ¨® */ + board[9][1] = board[9][7] = CHE(5, chc_my); /* ØX */ + board[7][1] = board[7][7] = CHE(6, chc_my); /* ¬¶ */ + board[6][0] = board[6][2] = board[6][4] = + board[6][6] = board[6][8] = CHE(7, chc_my); /* §L */ +} + +void chc_movechess(board_t board) { + board[chc_to.r][chc_to.c] = board[chc_from.r][chc_from.c]; + board[chc_from.r][chc_from.c] = 0; +} + +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; +} + +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; +} + +int chc_canmove(board_t board, rc_t from, rc_t to) { + int i; + int rd, cd, turn; + + 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 1: /* ±N «Ó */ + if(!(rd == 1 && cd == 0) && + !(rd == 0 && cd == 1)) + return 0; + if((turn == (chc_my ^ 1) && to.r > 2) || + (turn == chc_my && to.r < 7) || + to.c < 3 || to.c > 5) + return 0; + break; + case 2: /* ¤h ¥K */ + if(!(rd == 1 && cd == 1)) + return 0; + if((turn == (chc_my ^ 1) && to.r > 2) || + (turn == chc_my && to.r < 7) || + to.c < 3 || to.c > 5) + return 0; + break; + case 3: /* ¶H ¬Û */ + if(!(rd == 2 && cd == 2)) + return 0; + if((turn == (chc_my ^ 1) && to.r > 4) || + (turn == chc_my && to.r < 5)) + return 0; + /* ©ä¶H»L */ + if(board[CENTER(from.r, to.r)][CENTER(from.c, to.c)]) + return 0; + break; + case 4: /* ¨® */ + if(!(rd > 0 && cd == 0) && + !(rd == 0 && cd > 0)) + return 0; + if(between(board, from, to, rd == 0)) + return 0; + break; + case 5: /* °¨ Ø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 6: /* ¥] ¬¶ */ + 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 7: /* ¨ò §L */ + if(!(rd == 1 && cd == 0) && + !(rd == 0 && cd == 1)) + return 0; + if(((turn == (chc_my ^ 1) && to.r < 5) || + (turn == chc_my && to.r > 4)) && + cd != 0) + return 0; + if((turn == (chc_my ^ 1) && to.r < from.r) || + (turn == chc_my && to.r > from.r)) + return 0; + break; + } + return 1; +} + +static void findking(board_t board, int turn, rc_t *buf) { + int i, r, c; + + r = (turn == (chc_my ^ 1)) ? 0 : 7; + for(i = 0; i < 3; r++, i++) + for(c = 3; c < 6; c++) + if(CHE_P(board[r][c]) == 1 && + CHE_O(board[r][c]) == turn) { + buf->r = r, buf->c = c; + return ; + } +} + +int chc_iskfk(board_t board) { + rc_t from, to; + + findking(board, 0, &to); + findking(board, 1, &from); + if(from.c == to.c && between(board, from, to, 0) == 0) + return 1; + return 0; +} + +int chc_ischeck(board_t board, int turn) { + rc_t from, to; + + findking(board, turn, &to); + 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; +} diff --git a/mbbsd/chicken.c b/mbbsd/chicken.c new file mode 100644 index 00000000..f789925f --- /dev/null +++ b/mbbsd/chicken.c @@ -0,0 +1,989 @@ +/* $Id: chicken.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/socket.h> +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "modes.h" +#include "proto.h" + +#define NUM_KINDS 13 /* ¦³¦h¤ÖºØ°Êª« */ + +static const char *cage[17] = { + "½Ï¥Í", "¶g·³", "¥®¦~", "¤Ö¦~", "«C¬K", "«C¦~", + "«C¦~", "¬¡¤O", "§§¦~", "§§¦~", "§§¦~", "¤¤¦~", + "¤¤¦~", "¦Ñ¦~", "¦Ñ¦~", "¦Ñáàáà", "¥j§Æ"}; +static const char *chicken_type[NUM_KINDS] = { + "¤pÂû", "¬ü¤Ö¤k", "«i¤h", "»jµï", + "®£Às", "¦ÑÆN", "¿ß", "Äúµ§¤p·s", + "ª¯ª¯", "´cÅ]", "§ÔªÌ", "£««ó", + "°¨^¤E"}; +static const char *chicken_food[NUM_KINDS] = { + "Âû¹}®Æ", "Àç¾i«p¤ù", "Âû±Æ«K·í", "¦º½¹½º", + "«ÍÅé", "¤pÂû", "¿ß»æ°®", "¤pºµ»æ°®", + "Ä_¿ý", "ÆF®ð", "¶º¹Î", "«K·í", + "Âû»L"}; +static const int egg_price[NUM_KINDS] = { + 5, 25, 30, 40, + 80, 50, 15, 35, + 17, 100, 85, 200, + 200}; +static const int food_price[NUM_KINDS] = { + 4, 6, 8, 10, + 12, 12, 5, 6, + 5, 20, 15, 23, + 23}; +static const char *attack_type[NUM_KINDS] = { + "°Ö", "Ã@¥´", "ºl", "«r", + "¼²À»", "°Ö", "§ì", "½ð", + "«r","¿U¿N","·tÀ»","´Ò¥´", + "¼CÀ»"}; + +static const char *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 +}; + +extern userec_t cuser; + +static chicken_t *mychicken = &cuser.mychicken; +static int age; + +static const int 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} +}; + +extern userec_t xuser; +extern int usernum; + +int reload_chicken() { + passwd_query(usernum, &xuser); + memcpy(mychicken, &xuser.mychicken, sizeof(chicken_t)); + if(!mychicken->name[0]) + return 0; + else return 1; +} + +#define CHICKENLOG "etc/chicken" + +static int new_chicken() { + char buf[150]; + int price; + time_t now; + + clear(); + move(2,0); + outs("ÅwªïÆ[Á{ \033[33m¡·\033[37;44m PttÃdª«¥«³õ \033[33;40m¡·\033[m.. " + "¥Ø«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 (l)ªü«ó $200 (m)°¨^¤E $200\n" + "[0]¦Û¤v $0\n"); + getdata_str(6, 0, "½Ð¿ï¾Ü§An¾iªº°Êª«¡G", buf, 3, LCECHO, "0"); + + buf[0] -= 'a'; + if(buf[0]<0 || buf[0]>NUM_KINDS-1) + return 0; + + mychicken->type = buf[0]; + + reload_money(); + price = egg_price[(int)mychicken->type]; + if(cuser.money < price) { + prints("\n ¿ú¤£°÷¶R³J³J,³J³Jn %d ¤¸", price); + refresh(); + return 0; + } + vice(price,"Ãdª«³J"); + while(strlen(mychicken->name)<3) + getdata(8, 0, "À°¨e¨úÓ¦n¦W¦r¡G", mychicken->name, 18, DOECHO); + + now = time(NULL); + sprintf(buf,"\033[31m%s \033[m¾i¤F¤@°¦¥s\033[33m %s \033[mªº " + "\033[32m%s\033[m ©ó %s",cuser.userid, + mychicken->name,chicken_type[(int)mychicken->type],ctime(&now)); + log_file(CHICKENLOG,buf); + 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; + return 1; +} + +int show_file(char *filename, int y, int lines, int mode) { + FILE *fp; + char buf[256]; + + if(y >= 0) + move(y,0); + clrtoline(lines + y); + if((fp=fopen(filename,"r"))) { + while(fgets(buf,256,fp) && lines--) + outs(Ptt_prints(buf,mode)); + fclose(fp); + } else + return 0; + return 1; +} + +static void show_chicken_stat(chicken_t *thechicken) { + struct tm *ptime; + + ptime = localtime(&thechicken->birthday); + prints(" Name :\033[33m%s\033[m (\033[32m%s\033[m)%*s¥Í¤é " + ":\033[31m%02d\033[m¦~\033[31m%2d\033[m¤ë\033[31m%2d\033[m¤é " + "(\033[32m%s %d·³\033[m)\n" + " Åé:\033[33m%5d/%-5d\033[m ªk:\033[33m%5d/%-5d\033[m §ðÀ»¤O:" + "\033[33m%-7d\033[m ±Ó±¶ :\033[33m%-7d\033[m ª¾ÃÑ :\033[33m%-7d" + "\033[m \n" + " §Ö¼Ö :\033[33m%-7d\033[m º¡·N :\033[33m%-7d\033[m ¯h³Ò :" + "\033[33m%-7d\033[m ®ð½è :\033[33m%-7d \033[mÅé« :" + "\033[33m%-5.2f\033[m \n" + " ¯f®ð :\033[33m%-7d\033[m °®²b :\033[33m%-7d\033[m ¹ª« :" + "\033[33m%-7d\033[m ¤j¸É¤Y:\033[33m%-7d\033[m ÃÄ«~ :\033[33m%-7d" + "\033[m \n", + thechicken->name, chicken_type[(int)thechicken->type], + 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" +extern char *BBSName; + +void show_chicken_data(chicken_t *thechicken, chicken_t *pkchicken) { + char buf[1024]; + age = ((time(NULL) - thechicken->cbirth)/ (60*60*24)); + if(age < 0) { + thechicken->birthday = thechicken->cbirth = time(NULL)-10*(60*60*24); + age = 10; + } + /*Ptt:debug*/ + thechicken->type %= NUM_KINDS; + clear(); + showtitle(pkchicken ? "¢Þtt°«Âû³õ" : "¢Þtt¾iÂû³õ", BBSName); + move(1,0); + + show_chicken_stat(thechicken); + + sprintf(buf, CHICKEN_PIC "/%c%d", thechicken->type + 'a', + age > 16 ? 16 : age); + show_file(buf, 5, 14, NO_RELOAD); + + move(18,0); + + if(thechicken->sick) + outs("¥Í¯f¤F..."); + if(thechicken->sick > thechicken->hp / 5) + outs("\033[5;31m¾á¤ß...¯f«!!\033[m"); + + if(thechicken->clean > 150) + outs("\033[31m¤S¯ä¤Sżªº..\033[m"); + else if(thechicken->clean > 80) + outs("¦³ÂIż.."); + else if(thechicken->clean < 20) + outs("\033[32m«Ü°®²b..\033[m"); + + if(thechicken->weight > thechicken->hp_max*4) + outs("\033[31m§Ö¹¡¦º¤F!.\033[m"); + else if(thechicken->weight > thechicken->hp_max*3) + outs("\033[32m¹¡¹Ê¹Ê..\033[m"); + else if(thechicken->weight < (thechicken->hp_max / 4)) + outs("\033[31m§Ö¾j¦º¤F!..\033[m"); + else if(thechicken->weight < (thechicken->hp_max / 2)) + outs("¾j¤F.."); + + if(thechicken->tiredstrong > thechicken->hp * 1.7) + outs("\033[31m²Ö±o©ü°g¤F...\033[m"); + else if(thechicken->tiredstrong > thechicken->hp) + outs("²Ö¤F.."); + else if(thechicken->tiredstrong < thechicken->hp / 4) + outs("\033[32mºë¤O©ô²±...\033[m"); + + if(thechicken->hp < thechicken->hp_max / 4) + outs("\033[31mÅé¤O¥ÎºÉ..©a©a¤@®§..\033[m"); + if(thechicken->happy > 500) + outs("\033[32m«Ü§Ö¼Ö..\033[m"); + else if(thechicken->happy < 100) + outs("¤£§Ö¼Ö.."); + if(thechicken->satis > 500) + outs("\033[32m«Üº¡¨¬..\033[m"); + else if(thechicken->satis < 50) + outs("¤£º¡¨¬.."); + + if(pkchicken) { + outs("\n"); + show_chicken_stat(pkchicken); + outs("[¥ô·NÁä] §ðÀ»¹ï¤è [q] ¸¨¶] [o] ¦Y¤j¸É¤Y"); + } +} + +static void ch_eat() { + 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_file(CHICKEN_PIC "/eat", 5, 14, NO_RELOAD); + pressanykey(); + } +} + +static void ch_clean() { + mychicken->clean = 0; + mychicken->tiredstrong += + time_change[(int)mychicken->type][TIREDSTRONG] / 3; + show_file(CHICKEN_PIC "/clean", 5, 14, NO_RELOAD); + pressanykey(); +} + +static void ch_guess() { + 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("§An¥X[\033[32m1\033[m]\033[33m°Å¤M\033[m(\033[32m2\033[m)" + "\033[33m¥ÛÀY\033[m(\033[32m3\033[m)\033[33m¥¬\033[m:\n"); + me = igetch(); + me -= '1'; + if(me > 2 || me < 0) + me = 0; + win = (int)(3.0 * rand()/(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() { + mychicken->book += time_change[(int)mychicken->type][BOOK]; + mychicken->tiredstrong += time_change[(int)mychicken->type][TIREDSTRONG]; + show_file(CHICKEN_PIC "/read", 5, 14, NO_RELOAD); + pressanykey(); +} + +static void ch_kiss() { + 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_file(CHICKEN_PIC "/kiss", 5, 14, NO_RELOAD); + pressanykey(); +} + +static void ch_hit() { + 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] * + rand()/(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_file(CHICKEN_PIC "/hit", 5, 14, NO_RELOAD); + pressanykey(); +} + +extern int b_lines; /* Screen bottom line number: t_lines-1 */ + +void ch_buyitem(int money, char *picture, int *item) { + int num = 0; + char buf[5]; + + getdata_str(b_lines - 1, 0, "n¶R¦h¤Ö¥÷©O:", buf, 4, DOECHO, "1"); + num = atoi(buf); + if(num < 1) + return; + reload_money(); + if(cuser.money > money*num) { + *item += num; + vice(money*num,"ÁʶRÃdª«,½ä½L¶µ¥Ø"); + show_file(picture, 5, 14, NO_RELOAD); + } else { + move(b_lines-1,0); + clrtoeol(); + outs("²{ª÷¤£°÷ !!!"); + } + pressanykey(); +} + +static void ch_eatoo() { + if(mychicken->oo > 0) { + mychicken->oo--; + mychicken->tiredstrong = 0; + if(mychicken->happy > 5) + mychicken->happy -= 5; + show_file(CHICKEN_PIC "/oo", 5, 14, NO_RELOAD); + pressanykey(); + } +} + +static void ch_eatmedicine() { + 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_file(CHICKEN_PIC "/medicine", 5, 14, NO_RELOAD); + pressanykey(); + } +} + +static void ch_kill() { + char buf[150],ans[4]; + + sprintf(buf, "±ó¾i³o%sn³Q»@ 100 ¤¸, ¬O§_n±ó¾i?(y/N)", + chicken_type[(int)mychicken->type]); + getdata_str(23, 0, buf, ans, 3, DOECHO, "N"); + if(ans[0] == 'y') { + time_t now = time(NULL); + + vice(100,"±ó¾iÃdª«¶O"); + more(CHICKEN_PIC "/deadth",YEA); + sprintf(buf, "\033[31m%s \033[m§â \033[33m%s\033[m\033[32m %s " + "\033[m®_¤F ©ó %s", cuser.userid, + mychicken->name, chicken_type[(int)mychicken->type], ctime(&now)); + log_file(CHICKENLOG, buf); + mychicken->name[0]=0; + } +} + +static int ch_sell() { +/* + int money = (mychicken->weight - time_change[(int)mychicken->type][WEIGHT]) + *(food_price[(int)mychicken->type])/4 + + ( + + ((mychicken->clean / time_change[(int)mychicken->type][CLEAN]) + + (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 / time_change[(int)mychicken->type][TIREDSTRONG]) + - (mychicken->sick / time_change[(int)mychicken->type][SICK]) + + (mychicken->hp / time_change[(int)mychicken->type][HP_MAX]) + + (mychicken->mm / time_change[(int)mychicken->type][MM_MAX]) + + 7 - abs(age - 7)) * 3 + ; +*/ + int money = (age * food_price[(int)mychicken->type] * 3 + + (mychicken->hp_max * 10 + mychicken->weight) / + time_change[(int)mychicken->type][HP_MAX]) * 3 / 2 - + mychicken->sick; + char buf[150],ans[4]; + time_t now = time(NULL); + + if(money < 0) + money =0 ; + else if(money > MAX_CHICKEN_MONEY) + money = MAX_CHICKEN_MONEY; //¨¾¤î©ÇÂû + if(mychicken->type == 1 || mychicken->type == 7) { + outs("\n\033[31m £..¿Ë·Rªº..³c½æ¤H¤f¬O·|¥Çªkªºò..\033[m"); + pressanykey(); + return 0; + } + if(age < 5) { + outs("\n ÁÙ¥¼¦¨¦~¤£¯à½æ"); + pressanykey(); + return 0; + } + if(age > 30) { + outs("\n\033[31m ³o..¤Ó¦Ñ¨S¤Hn¤F\033[m"); + pressanykey(); + return 0; + } + + sprintf(buf, "³o°¦%d·³%s¥i¥H½æ %d ¤¸, ¬O§_n½æ?(y/N)", age, + chicken_type[(int)mychicken->type], money); + getdata_str(23, 0, buf, ans, 3, DOECHO, "N"); + if(ans[0]=='y') { + sprintf(buf, "\033[31m%s\033[m §â \033[33m%s\033[m " + "\033[32m%s\033[m ¥Î \033[36m%d\033[m ½æ¤F ©ó %s", + cuser.userid, mychicken->name, + chicken_type[(int)mychicken->type],money,ctime(&now)); + log_file(CHICKENLOG, buf); + mychicken->lastvisit = mychicken->name[0]=0; + passwd_update(usernum, &cuser); + more(CHICKEN_PIC "/sell",YEA); + demoney(money); + return 1; + } + return 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; + } +} + +/* ¨Ì®É¶¡Åܰʪº¸ê®Æ */ +void time_diff(chicken_t *thechicken) { + int diff; + int theage = ((time(NULL) - thechicken->cbirth)/ (60 * 60 * 24)); + + thechicken->type %= NUM_KINDS ; + diff = (time(NULL)-thechicken->lastvisit)/60; + + if((diff) < 1) + return; + + if(theage > 13 ) /* ¦Ñ¦º */ + geting_old(&thechicken->hp_max, &thechicken->weight, diff, age); + + thechicken->lastvisit = time(NULL); + 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(mychicken->clean > 1000) + mychicken->sick += (mychicken->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() { + /* ż¯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(chicken_t *thechicken) { + int i; + char buf[150]; + time_t now = time(NULL); + + 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) { + sprintf(buf,"\033[31m%s\033[m ©Ò¯k·Rªº\033[33m %s\033[32m %s " + "\033[m±¾¤F ©ó %s", + cuser.userid, thechicken->name, + chicken_type[(int)thechicken->type], + ctime(&now)); + log_file(CHICKENLOG, buf); + mychicken->name[0] = 0; + passwd_update(usernum, &cuser); + } + 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; +} + +int isdeadth(chicken_t *thechicken) { + int i; + + if(!(i = deadtype(thechicken))) + return 0; + return showdeadth(i); +} + +static void ch_changename() { + char buf[150], newname[20] = ""; + time_t now = time(NULL); + + getdata_str(b_lines - 1, 0, "¶â..§ïÓ¦n¦W¦r§a:", newname, 18, DOECHO, + mychicken->name); + + if(strlen(newname) >= 3 && strcmp(newname,mychicken->name)) { + sprintf(buf, "\033[31m%s\033[m §â¯k·Rªº\033[33m %s\033[32m %s " + "\033[m§ï¦W¬°\033[33m %s\033[m ©ó %s", + cuser.userid, mychicken->name, + chicken_type[(int)mychicken->type], + newname, ctime(&now)); + strcpy(mychicken->name, newname); + log_file(CHICKENLOG,buf); + } +} + +static int select_menu() { + char ch; + + reload_money(); + move(19,0); + prints("\033[44;37m ¿ú :\033[33m %-10d " + " \033[m\n" + "\033[33m(\033[37m1\033[33m)²M²z (\033[37m2\033[33m)¦Y¶º " + "(\033[37m3\033[33m)²q®± (\033[37m4\033[33m)°á®Ñ " + "(\033[37m5\033[33m)¿Ë¥L (\033[37m6\033[33m)¥´¥L " + "(\033[37m7\033[33m)¶R%s$%d (\033[37m8\033[33m)¦Y¸É¤Y\n" + "(\033[37m9\033[33m)¦Y¯fÃÄ (\033[37mo\033[33m)¶R¤j¸É¤Y$100 " + "(\033[37mm\033[33m)¶RÃÄ$10 (\033[37mk\033[33m)±ó¾i " + "(\033[37ms\033[33m)½æ±¼ (\033[37mn\033[33m)§ï¦W " + "(\033[37mq\033[33m)Â÷¶}:\033[m", + 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(); + check_sick(); + break; + case '2': + ch_eat(); + check_sick(); + break; + case '3': + ch_guess(); + check_sick(); + break; + case '4': + ch_book(); + check_sick(); + break; + case '5': + ch_kiss(); + break; + case '6': + ch_hit(); + check_sick(); + break; + case '7': + ch_buyitem(food_price[(int)mychicken->type], CHICKEN_PIC "/food", + &mychicken->food); + break; + case '8': + ch_eatoo(); + break; + case '9': + ch_eatmedicine(); + break; + case 'O': + case 'o': + ch_buyitem(100, CHICKEN_PIC "/buyoo", &mychicken->oo); + break; + case 'M': + case 'm': + ch_buyitem(10, CHICKEN_PIC "/buymedicine", &mychicken->medicine); + break; + case 'N': + case 'n': + ch_changename(); + break; + case 'K': + case 'k': + ch_kill(); + return 0; + case 'S': + case 's': + if(!ch_sell()) break; + 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], + money = price + (rand() % price); + + if(time(NULL) - thechicken->lastvisit > (60 * 60 * 24 * 7)) + return 0; + outmsg("\033[33;44m¡¹ÆF¬É¦u½Ã\033[37;45m §O®`©È §Ú¬O¨ÓÀ°§Aªº \033[m"); + bell(); + igetch(); + outmsg("\033[33;44m¡¹ÆF¬É¦u½Ã\033[37;45m §AµLªk¥á¨ì§Ú¤ô²y ¦]¬°§Ú¬O¸tÆF, " + "³Ìªñ¯Ê¿ú·QÁÈ¥~§Ö \033[m"); + bell(); + igetch(); + sprintf(buf, "\033[33;44m¡¹ÆF¬É¦u½Ã\033[37;45m " + "§A¦³¤@Ó訫¤£¤[ªº%sn©Û´«¦^¨Ó¶Ü? ¥un%d¤¸ò \033[m", + chicken_type[(int)thechicken->type], price*2); + 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*2) { + outmsg("\033[33;44m¡¹ÆF¬É¦u½Ã\033[37;45m ¤°»ò ¿ú¨S±a°÷ " + "¨S¿úªº¤p° §Ö¥hÄw¿ú§a \033[m"); + bell(); + igetch(); + return 0; + } + strcpy(thechicken->name, "[¾ß¦^¨Óªº]"); + thechicken->hp = thechicken->hp_max; + thechicken->sick = 0; + thechicken->satis = 2; + vice(money,"ÆF¬É¦u½Ã"); + sprintf(buf, "\033[33;44m¡¹ÆF¬É¦u½Ã\033[37;45m OK¤F °O±oÁý¥LÂIªF¦è " + "¤£µM¥i¯à¥¢®Ä ©À¦b§Ú¤]¦³ª±Ptt ®³§A%d´N¦n \033[m", money); + outmsg(buf); + bell(); + igetch(); + return 1; + } + outmsg("\033[33;44m¡¹ÆF¬É¦u½Ã\033[37;45m ³ºµM»¡§Ú§|¤H! ³o¦~ÀY©R¯u¤£È¿ú " + "°£«D§Ú¦A¨Ó§ä§A §A¦A¤]¨S¾÷·|¤F \033[m"); + bell(); + igetch(); + thechicken->lastvisit = 0; + passwd_update(usernum, &cuser); + return 0; +} + +#define lockreturn0(unmode, state) if(lockutmpmode(unmode, state)) return 0 + +int chicken_main() { + lockreturn0(CHICKEN, LOCK_MULTI); + + reload_chicken(); + age = ((time(NULL) - mychicken->cbirth)/ (60*60*24)); + if(!mychicken->name[0] && !recover_chicken(mychicken) && !new_chicken()) { + unlockutmpmode(); + return 0; + } + + do { + time_diff(mychicken); + if(isdeadth(mychicken)) + break; + show_chicken_data(mychicken, NULL); + } while(select_menu()); + reload_money(); + passwd_update(usernum, &cuser); + unlockutmpmode(); + return 0; +} + +extern userinfo_t *currutmp; +extern struct utmpfile_t *utmpshm; + +int chickenpk(int fd) { + char mateid[IDLEN + 1], data[200], buf[200]; + int ch = 0; + + userinfo_t *uin = &utmpshm->uinfo[currutmp->destuip]; + userec_t ouser; + chicken_t *ochicken = &ouser.mychicken; + int r, attmax, i, datac, duid = currutmp->destuid, catched=0, count=0; + + lockreturn0(CHICKEN, LOCK_MULTI); + + strcpy(mateid, currutmp->mateid); /*§â¹ï¤âªºid¥Îlocal buffer°O¦í*/ + + getuser(mateid) ; + memcpy(&ouser, &xuser, sizeof(userec_t)); + reload_chicken(); + if(!ochicken->name[0] || !mychicken->name[0]) { + outmsg("¦³¤@¤è¨S¦³Ãdª«"); /* Ptt:§«¤îpage®É§âÃdª«½æ±¼ */ + bell(); + refresh(); + add_io(0, 0); + close(fd); + unlockutmpmode(); + sleep(1); + return 0; + } + + show_chicken_data(ochicken, mychicken); + add_io(fd, 3); /* §âfd¥[¨ìigetchºÊµø */ + while(1) { + r = rand(); + ch = igetkey(); + getuser(mateid) ; + memcpy(&ouser, &xuser, sizeof(userec_t)); + reload_chicken(); + 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) { + sprintf(data, "lÅý %s ¸¨¶]¤F\n", + ochicken->name); + } + break; + case 'n': + catched =0; + default: + case 'k': + r = r % (attmax + 2); + if(r) { + sprintf(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 + sprintf(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; + sprintf(data, "M%s ¦Y¤FÁû¤j¸É¤Y¸É¥RÅé¤O\n", + mychicken->name); + } else + sprintf(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)) + sprintf(data, "q%s ¸¨¶]¤F\n", + mychicken->name); + else + sprintf(data, "c%s ·Q¸¨¶], ¦ý³Q %s §ì¨ì¤F\n", + mychicken->name, ochicken->name); + break; + } + if(deadtype(ochicken)) { + strtok(data,"\n"); + strcpy(buf, data); + sprintf(data, "d%s , %s ³Q %s ¥´¦º¤F\n", + buf + 1, ochicken->name, mychicken->name); + } + move(17,0); + outs(data+1); + i = strlen(data) +1; + passwd_update(duid, &ouser); + passwd_update(usernum, &cuser); + 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); + if(!showdeadth(deadtype(mychicken))); + unlockutmpmode(); + return 0; +} diff --git a/mbbsd/dark.c b/mbbsd/dark.c new file mode 100644 index 00000000..52741617 --- /dev/null +++ b/mbbsd/dark.c @@ -0,0 +1,456 @@ +/* $Id: dark.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <time.h> +#include <sys/types.h> +#include <sys/socket.h> +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "proto.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; + +static item brd[4][8]; +static cur curr; /* 6 Ó bytes */ +extern userinfo_t *currutmp; + +static char *rname[]={"§L","¬¶","ØX","¨®","¬Û","¥K","«Ó"}; +static char *bname[]={"¨ò","¥]","°¨","¨®","¶H","¤h","±N"}; + +static sint cury[]={3,5,7,9}, curx[]={5,9,13,17,21,25,29,33}; +static sint rcount,bcount,cont,fix; /* cont:¬O§_¥i³s¦Y */ +static sint my=0,mx=0,mly=-1,mlx=-1; /* ²¾°Êªº®y¼Ð ¸ò ¿ï¤lªº®y¼Ð */ + +static sint cur_eaty,cur_eatx; /* ¦Y±¼¹ï¤è¨ä¤lªº¨q¥X®y¼Ð */ +static void brdswap(sint y,sint x,sint ly,sint lx) { + memcpy(&brd[y][x],&brd[ly][lx],sizeof(item)); + brd[ly][lx].die=1; + brd[ly][lx].color=-1; /* ¨S³oÓcolor */ + brd[ly][lx].value=-1; +} + +static void pprints(sint y,sint x,char* s) { + move(y,x); + clrtoeol(); + prints("%s",s); +} + +static sint Is_win(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 && brd[y][x].die==0)|| + (abs(lx-x)==1 && 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(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(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)) && 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(sint y,sint x, sint ly, sint lx) { + if(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() { + 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(brd, sizeof(brd)); + bzero(tem, sizeof(tem)); + bzero(&curr, sizeof(curr)); + srand(getpid()%2731+time(NULL)%3219); + for(y=0;y<4;y++) + for(x=0;x<8;x++) + while(1) { + index=rand()%32; + if(tem[index]) continue; + brd[y][x].color=(index>15)?0:1; + brd[y][x].value=value[index]; + tem[index]=1; + break; + } +} + +static void brd_prints() { + clear(); + move(1,0); + outs(" + [43;30m¢~¢w¢s¢w¢s¢w¢s¢w¢s¢w¢s¢w¢s¢w¢s¢w¢¡[m + [43;30m¢x¡´¢x¡´¢x¡´¢x¡´¢x¡´¢x¡´¢x¡´¢x¡´¢x[m + [43;30m¢u¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢t[m + [43;30m¢x¡´¢x¡´¢x¡´¢x¡´¢x¡´¢x¡´¢x¡´¢x¡´¢x[m + [43;30m¢u¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢t[m + [43;30m¢x¡´¢x¡´¢x¡´¢x¡´¢x¡´¢x¡´¢x¡´¢x¡´¢x[m + [43;30m¢u¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢t[m + [43;30m¢x¡´¢x¡´¢x¡´¢x¡´¢x¡´¢x¡´¢x¡´¢x¡´¢x[m + [43;30m¢¢¢w¢r¢w¢r¢w¢r¢w¢r¢w¢r¢w¢r¢w¢r¢w¢£[m + "); +} + +static void draw_line(sint y, sint f) { + sint i; + char buf[1024],tmp[256]; + + *buf = 0; + *tmp = 0; + strcpy(buf,"\033[43;30m"); + for(i=0; i<8; i++) + { + if(brd[y][i].die==1) + sprintf(tmp,"¢x "); + else if(brd[y][i].out==0) + sprintf(tmp,"¢x¡´"); + else { + sprintf(tmp, "¢x\033[%s1;%dm%s\033[m\033[43;30m", + (f==i)?"1;47;":"",(brd[y][i].color)?31:34, + (brd[y][i].color)?rname[brd[y][i].value]: + bname[brd[y][i].value]); + } + strcat(buf,tmp); + } + strcat(buf,"¢x\033[m"); + + move(cury[y],3); + clrtoeol(); + prints("%s",buf); +} + +static void redraw() { + sint i=0; + for(;i<4;i++) + draw_line(i,-1); +} + +static sint playing(sint fd, sint color,sint ch,sint *b, userinfo_t *uin) { + curr.end = 0; + move(cury[my],curx[mx]); + + if(fix) { + if(ch=='s') { + fix=0; *b=0; return 0; + } else { + draw_line(mly,-1); + } + } + + switch(ch) { + case KEY_LEFT: + if(mx == 0) mx=7; + else mx--; + move(cury[my],curx[mx]); + *b=-1; + break; + case KEY_RIGHT: + if(mx==7) mx=0; + else mx++; + move(cury[my],curx[mx]); + *b=-1; + break; + case KEY_UP: + if(my==0) my=3; + else my--; + move(cury[my],curx[mx]); + *b=-1; + break; + case KEY_DOWN: + if(my==3) my=0; + else my++; + move(cury[my],curx[mx]); + *b=-1; + break; + case 'q':case 'Q': + if(!color) bcount=0; + else 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(brd[my][mx].out==1) + { + if(brd[my][mx].color != color) + { + *b=-1; + break; + } + if(mly<0) /*¥i¥H¿ï¾Ü*/ + { + mly=my;mlx=mx; + draw_line(my,mx); + *b=-1; + break; + } + else if(mly == my && mlx == mx) /*¤£¿ï¤F*/ + { + mly=-1;mlx=-1; + draw_line(my,-1); + }else + { + draw_line(mly,-1); + mly=my;mlx=mx; + if(brd[mly][mlx].value == 1) fix=1; + draw_line(my,mx); + } + *b=-1; + break; + } + /* ½¶}´Ñ¤l */ + if(mly >=0 ){ *b=-1; break;} /*¥»¨Ó´N¬O½¶}ªº*/ + /* ¨M©w¤@¶}©lªºÃC¦â */ + if(currutmp->color=='.'){ + if(uin->color!='1' && uin->color!='0') + currutmp->color=(brd[my][mx].color)?'1':'0'; + else + currutmp->color=(uin->color=='0')?'1':'0';} + brd[my][mx].out=1; + draw_line(my,-1); + move(cury[my],curx[mx]); + *b=0; + break; + case 'u': + move(0,0);clrtoeol(); + prints("%s¦â%s cont=%d",(brd[my][mx].color == RED)?"¬õ":"¶Â",rname[brd[my][mx].value],cont); + *b=-1; + break; + case '\r': /* ¦Y or ²¾°Ê ly¸òlx¥²¶·¤j©ó0*/ + case '\n': + if( + mly >= 0 /* n¥ý¿ï¤l */ + && + brd[mly][mlx].color != brd[my][mx].color /* ¦P¦â¤£¯à²¾°Ê¤]¤£¯à¦Y */ + && + (Is_move(my,mx,mly,mlx) || Is_win(brd[mly][mlx],brd[my][mx],my,mx,mly,mlx)) + ) + { + if(fix && brd[my][mx].value<0) + { + *b=-1;return 0; + } + if(brd[my][mx].value>=0&&brd[my][mx].die==0) + { + if(!color) bcount--; + else rcount--; + move(cur_eaty,cur_eatx); + prints("%s",(color)?bname[brd[my][mx].value]:rname[brd[my][mx].value]); + if(cur_eatx>=26) + { cur_eatx=5;cur_eaty++; } + else + cur_eatx+=3; + } + brdswap(my,mx,mly,mlx); + draw_line(mly,-1); + draw_line( my,-1); + if(fix==1) *b=-1; + else { mly=-1;mlx=-1;*b=0; } + } + else *b=-1; + break; + default: + *b=-1; + } + + if(!rcount) + return -1; + else if(!bcount) + return -1; + if(*b == -1) return 0; + curr.y = my;curr.x = mx; curr.end=(!*b)?1:0; + send(fd,&curr,sizeof(curr),0); + send(fd,&brd,sizeof(brd),0); + return 0; +} + +int main_dark(int fd,userinfo_t *uin) { + sint end=0,ch=1,go_on,i=0,cont=0; + char buf[16]; + *buf=0;fix=0; + currutmp->color='.'; // '.' ªí¥ÜÁÙ¨S¨M©wÃC¦â + rcount=16;bcount=16; // initialize + cur_eaty=18,cur_eatx=5; + brd_prints(); + if(currutmp->turn) + { + brd_rand(); + send(fd,&brd,sizeof(brd),0); + pprints(21,0," [1;37m[1;33m¡»[1;37m§A¬O¥ý¤â[m"); + pprints(22,0," [1;33m¡»[5;35m½ü¨ì§A¤U¤F[m"); + }else + { + recv(fd,&brd,sizeof(brd),0); + pprints(21,0," [1;33m¡»[1;37m§A¬O«á¤â[m"); + } + move(12,3); + prints("%s[0³Ó0±Ñ][5;31m¢þ¢û[1;37m.[m%s[0³Ó0±Ñ]",currutmp->userid,currutmp->mateid); + outs(" + [1;36m¢®¢¬[1;31m¥\\¯àªí[1;36m¢¢®¢¢¬¢®¢[m + [1;36m¢¬[1;33m ¡ô¡ö¡õ¡÷[1;37m: [1;35m²¾°Ê[m + [1;36m¢®[1;33m ¢û[1;37m: [1;35m ¿ï¤l,½¤l[m + [1;36m¢¬[1;33m enter[1;37m: [1;35m ¦Y´Ñ,©ñ´Ñ[m +¡@[1;33m¤w¸g¸Ñ¨Mªº[1;37m:[1;36m¡@¡@ ¢®[1;33m ¢ø[1;37m: [1;35m ¦X´Ñ[m + ¡@¡@ [1;36m¢¬[1;33m ¢ù[1;37m: [1;35m »{¿é[m + [1;36m¢®[1;33m ¢ë[1;37m: [1;35m ´«Ãä[m"); + + 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 = igetkey(); + if(ch == I_OTHERDATA) + { + ch=recv(fd,&curr,sizeof(curr),0); + if(ch!=sizeof(curr)) + { + if(uin->turn=='e') { end=-3;break; } + else if(uin->turn!='w') { end=-1; currutmp->turn='w'; break; } + end=-1; break; + } + + if(curr.end==-3) pprints(23,30,"\033[33mn¨D¦X´Ñ\033[m"); + else if(curr.end==-4) pprints(23,30,"\033[33mn¨D´«Ãä\033[m"); + else if(curr.end==-5) pprints(23,30,"\033[33mn¨D³s¦Y\033[m"); + else pprints(23,30,""); + + recv(fd,&brd,sizeof(brd),0); + my=curr.y;mx=curr.x; + redraw(); + if(curr.end) + pprints(22,0," [1;33m¡»[5;35m½ü¨ì§A¤U¤F[m"); + move(cury[my],curx[mx]); + }else + { + if(currutmp->turn=='p') + { + if(ch=='y') { end=-3; currutmp->turn='e'; break; } + else { pprints(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'; + pprints(21,0,(currutmp->color=='1')?" \033[1;33m¡»[1;31m§A«ù¬õ¦â´Ñ\033[m":" \033[1;33m¡»[1;36m§A«ù¶Â¦â´Ñ\033[m"); + } + else { pprints(23,30,""); currutmp->turn=(uin->turn)?0:1; } + }else if(currutmp->turn=='g') + { + if(ch=='y') { + cont=1; + pprints(21,0," \033[1;33m¡»[1;31m§A«ù¬õ¦â´Ñ\033[m ¥i³s¦Y"); + } + else { pprints(23,30,""); currutmp->turn=(uin->turn)?0:1; } + } + + if(currutmp->turn==1) + { + if(uin->turn=='g') { cont=1;uin->turn=(currutmp->turn)?0:1; pprints(21,10,"¥i³s¦Y"); } + end=playing(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';curr.end=-3; + send(fd,&curr,sizeof(curr),0); + send(fd,&brd,sizeof(buf),0); + continue; + } + else if(end == -4) { + if(currutmp->color!='1'&&currutmp->color!='0') + continue; + uin->turn='c';i=0;curr.end=-4; + send(fd,&curr,sizeof(curr),0); + send(fd,&brd,sizeof(buf),0); + continue; + } + else if(end == -5) { + uin->turn='g';curr.end=-5; + send(fd,&curr,sizeof(curr),0); + send(fd,&brd,sizeof(buf),0); + continue; + } + if(!i && currutmp->color=='1') + { pprints(21,0," \033[1;33m¡»[1;31m§A«ù¬õ¦â´Ñ\033[m");i++;move(cury[my],curx[mx]); } + if(!i && currutmp->color=='0') + { pprints(21,0," \033[1;33m¡»[1;36m§A«ù¶Â¦â´Ñ\033[m");i++;move(cury[my],curx[mx]); } + + if(uin->turn == 'e') { end=-3; break; } + if(go_on < 0) continue; + + move(22,0);clrtoeol(); + prints(" [1;33m¡»[1;37m½ü¨ì%s¤U §O©È§O©È ¥LºâÔ£¦Ì[m",currutmp->mateid); + currutmp->turn = 0; + uin->turn = 1; + }else + { + if(ch == 'q'){uin->turn='w';break;} + move(22,0);clrtoeol(); + prints(" [1;33m¡»[1;37m½ü¨ì%s¤U §O©È§O©È ¥LºâÔ£¦Ì[m",currutmp->mateid); + } + } + } + + switch(end) + { + case -1: + case -2: + if(currutmp->turn=='w'){ move(22,0);clrtoeol();prints("[1;31m§AŤF.. ¯u¬O®¥³ß~~[m");} + else {move(22,0);clrtoeol();prints("[1;31m¿é±¼¤F°Õ.....¤U¦¸Åý¥L¦n¬Ý!![m");} + break; + case -3: + pprints(22,0,"[1;31m¦X´Ñò!! ¤U¦¸¦b¤À°ª¤U§a ^_^[m"); + break; + default: + add_io(0,0); + close(fd); + pressanykey(); + return 0; + } + add_io(0,0); + close(fd); + pressanykey(); + return 0; +} diff --git a/mbbsd/descrypt.c b/mbbsd/descrypt.c new file mode 100644 index 00000000..3bb0a5e5 --- /dev/null +++ b/mbbsd/descrypt.c @@ -0,0 +1,616 @@ +/* $Id: descrypt.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ + +/* + * FreeSec: libcrypt for NetBSD + * + * Copyright (c) 1994 David Burren + * All rights reserved. + * + * Adapted for FreeBSD-2.0 by Geoffrey M. Rehmet + * crypt.c should now *only* export crypt(), in order to make + * binaries of libcrypt exportable from the USA + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the author nor the names of other contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/secure/lib/libcrypt/crypt.c,v 1.11 1999/08/28 01:30:24 peter Exp $ + * + * This is an original implementation of the DES and the crypt(3) interfaces + * by David Burren <davidb@werj.com.au>. + * + * An excellent reference on the underlying algorithm (and related + * algorithms) is: + * + * B. Schneier, Applied Cryptography: protocols, algorithms, + * and source code in C, John Wiley & Sons, 1994. + * + * Note that in that book's description of DES the lookups for the initial, + * pbox, and final permutations are inverted (this has been brought to the + * attention of the author). A list of errata for this book has been + * posted to the sci.crypt newsgroup by the author and is available for FTP. + * + * ARCHITECTURE ASSUMPTIONS: + * This code assumes that u_longs are 32 bits. It will probably not + * operate on 64-bit machines without modifications. + * It is assumed that the 8-byte arrays passed by reference can be + * addressed as arrays of u_longs (ie. the CPU is not picky about + * alignment). + */ + +#ifndef HAVE_DES_CRYPT + +#include <sys/types.h> +#include <sys/param.h> +#include <pwd.h> +#include <string.h> + +static unsigned char IP[64] = { + 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, + 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, + 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, + 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7 +}; + +static unsigned char inv_key_perm[64]; +static unsigned char u_key_perm[56]; +static unsigned char key_perm[56] = { + 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, + 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, + 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, + 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4 +}; + +static unsigned char key_shifts[16] = { + 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 +}; + +static unsigned char inv_comp_perm[56]; +static unsigned char comp_perm[48] = { + 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, + 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, + 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, + 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32 +}; + +/* + * No E box is used, as it's replaced by some ANDs, shifts, and ORs. + */ + +static unsigned char u_sbox[8][64]; +static unsigned char sbox[8][64] = { + { + 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, + 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, + 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, + 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 + }, + { + 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, + 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, + 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, + 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 + }, + { + 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, + 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, + 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, + 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 + }, + { + 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, + 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, + 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, + 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 + }, + { + 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, + 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, + 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, + 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 + }, + { + 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, + 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, + 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, + 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 + }, + { + 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, + 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, + 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, + 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 + }, + { + 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, + 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, + 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, + 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 + } +}; + +static unsigned char un_pbox[32]; +static unsigned char pbox[32] = { + 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, + 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25 +}; + +static unsigned long bits32[32] = { + 0x80000000, 0x40000000, 0x20000000, 0x10000000, + 0x08000000, 0x04000000, 0x02000000, 0x01000000, + 0x00800000, 0x00400000, 0x00200000, 0x00100000, + 0x00080000, 0x00040000, 0x00020000, 0x00010000, + 0x00008000, 0x00004000, 0x00002000, 0x00001000, + 0x00000800, 0x00000400, 0x00000200, 0x00000100, + 0x00000080, 0x00000040, 0x00000020, 0x00000010, + 0x00000008, 0x00000004, 0x00000002, 0x00000001 +}; + +static unsigned char bits8[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; + +static unsigned long saltbits; +static long old_salt; +static unsigned long *bits28, *bits24; +static unsigned char init_perm[64], final_perm[64]; +static unsigned long en_keysl[16], en_keysr[16]; +static unsigned long de_keysl[16], de_keysr[16]; +static int des_initialised = 0; +static unsigned char m_sbox[4][4096]; +static unsigned long psbox[4][256]; +static unsigned long ip_maskl[8][256], ip_maskr[8][256]; +static unsigned long fp_maskl[8][256], fp_maskr[8][256]; +static unsigned long key_perm_maskl[8][128], key_perm_maskr[8][128]; +static unsigned long comp_maskl[8][128], comp_maskr[8][128]; +static unsigned long old_rawkey0, old_rawkey1; + +static unsigned char ascii64[] = +"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; +/* 0000000000111111111122222222223333333333444444444455555555556666 */ +/* 0123456789012345678901234567890123456789012345678901234567890123 */ + +static int ascii_to_bin(char ch) { + if(ch > 'z') + return 0; + if(ch >= 'a') + return ch - 'a' + 38; + if(ch > 'Z') + return 0; + if(ch >= 'A') + return ch - 'A' + 12; + if(ch > '9') + return 0; + if(ch >= '.') + return ch - '.'; + return 0; +} + +static void des_init() { + int i, j, b, k, inbit, obit; + unsigned long *p, *il, *ir, *fl, *fr; + + old_rawkey0 = old_rawkey1 = 0L; + saltbits = 0L; + old_salt = 0L; + bits24 = (bits28 = bits32 + 4) + 4; + + /* + * Invert the S-boxes, reordering the input bits. + */ + for(i = 0; i < 8; i++) + for(j = 0; j < 64; j++) { + b = (j & 0x20) | ((j & 1) << 4) | ((j >> 1) & 0xf); + u_sbox[i][j] = sbox[i][b]; + } + + /* + * Convert the inverted S-boxes into 4 arrays of 8 bits. + * Each will handle 12 bits of the S-box input. + */ + for(b = 0; b < 4; b++) + for(i = 0; i < 64; i++) + for(j = 0; j < 64; j++) + m_sbox[b][(i << 6) | j] = + (u_sbox[(b << 1)][i] << 4) | + u_sbox[(b << 1) + 1][j]; + + /* + * Set up the initial & final permutations into a useful form, and + * initialise the inverted key permutation. + */ + for(i = 0; i < 64; i++) { + init_perm[final_perm[i] = IP[i] - 1] = i; + inv_key_perm[i] = 255; + } + + /* + * Invert the key permutation and initialise the inverted key + * compression permutation. + */ + for(i = 0; i < 56; i++) { + u_key_perm[i] = key_perm[i] - 1; + inv_key_perm[key_perm[i] - 1] = i; + inv_comp_perm[i] = 255; + } + + /* + * Invert the key compression permutation. + */ + for(i = 0; i < 48; i++) { + inv_comp_perm[comp_perm[i] - 1] = i; + } + + /* + * Set up the OR-mask arrays for the initial and final permutations, + * and for the key initial and compression permutations. + */ + for(k = 0; k < 8; k++) { + for(i = 0; i < 256; i++) { + *(il = &ip_maskl[k][i]) = 0L; + *(ir = &ip_maskr[k][i]) = 0L; + *(fl = &fp_maskl[k][i]) = 0L; + *(fr = &fp_maskr[k][i]) = 0L; + for(j = 0; j < 8; j++) { + inbit = 8 * k + j; + if(i & bits8[j]) { + if((obit = init_perm[inbit]) < 32) + *il |= bits32[obit]; + else + *ir |= bits32[obit-32]; + if ((obit = final_perm[inbit]) < 32) + *fl |= bits32[obit]; + else + *fr |= bits32[obit - 32]; + } + } + } + for(i = 0; i < 128; i++) { + *(il = &key_perm_maskl[k][i]) = 0L; + *(ir = &key_perm_maskr[k][i]) = 0L; + for(j = 0; j < 7; j++) { + inbit = 8 * k + j; + if(i & bits8[j + 1]) { + if((obit = inv_key_perm[inbit]) == 255) + continue; + if(obit < 28) + *il |= bits28[obit]; + else + *ir |= bits28[obit - 28]; + } + } + *(il = &comp_maskl[k][i]) = 0L; + *(ir = &comp_maskr[k][i]) = 0L; + for(j = 0; j < 7; j++) { + inbit = 7 * k + j; + if(i & bits8[j + 1]) { + if((obit=inv_comp_perm[inbit]) == 255) + continue; + if(obit < 24) + *il |= bits24[obit]; + else + *ir |= bits24[obit - 24]; + } + } + } + } + + /* + * Invert the P-box permutation, and convert into OR-masks for + * handling the output of the S-box arrays setup above. + */ + for(i = 0; i < 32; i++) + un_pbox[pbox[i] - 1] = i; + + for(b = 0; b < 4; b++) + for(i = 0; i < 256; i++) { + *(p = &psbox[b][i]) = 0L; + for (j = 0; j < 8; j++) { + if (i & bits8[j]) + *p |= bits32[un_pbox[8 * b + j]]; + } + } + + des_initialised = 1; +} + +static void setup_salt(long salt) { + unsigned long obit, saltbit; + int i; + + if (salt == old_salt) + return; + old_salt = salt; + + saltbits = 0L; + saltbit = 1; + obit = 0x800000; + for (i = 0; i < 24; i++) { + if (salt & saltbit) + saltbits |= obit; + saltbit <<= 1; + obit >>= 1; + } +} + +static int des_setkey(const char *key) { + unsigned long k0, k1, rawkey0, rawkey1; + int shifts, round; + + if(!des_initialised) + des_init(); + + rawkey0 = ntohl(*(unsigned long *) key); + rawkey1 = ntohl(*(unsigned long *) (key + 4)); + + if((rawkey0 | rawkey1) + && rawkey0 == old_rawkey0 + && rawkey1 == old_rawkey1) { + /* + * Already setup for this key. + * This optimisation fails on a zero key (which is weak and + * has bad parity anyway) in order to simplify the starting + * conditions. + */ + return 0; + } + old_rawkey0 = rawkey0; + old_rawkey1 = rawkey1; + + /* + * Do key permutation and split into two 28-bit subkeys. + */ + k0 = key_perm_maskl[0][rawkey0 >> 25] + | key_perm_maskl[1][(rawkey0 >> 17) & 0x7f] + | key_perm_maskl[2][(rawkey0 >> 9) & 0x7f] + | key_perm_maskl[3][(rawkey0 >> 1) & 0x7f] + | key_perm_maskl[4][rawkey1 >> 25] + | key_perm_maskl[5][(rawkey1 >> 17) & 0x7f] + | key_perm_maskl[6][(rawkey1 >> 9) & 0x7f] + | key_perm_maskl[7][(rawkey1 >> 1) & 0x7f]; + k1 = key_perm_maskr[0][rawkey0 >> 25] + | key_perm_maskr[1][(rawkey0 >> 17) & 0x7f] + | key_perm_maskr[2][(rawkey0 >> 9) & 0x7f] + | key_perm_maskr[3][(rawkey0 >> 1) & 0x7f] + | key_perm_maskr[4][rawkey1 >> 25] + | key_perm_maskr[5][(rawkey1 >> 17) & 0x7f] + | key_perm_maskr[6][(rawkey1 >> 9) & 0x7f] + | key_perm_maskr[7][(rawkey1 >> 1) & 0x7f]; + /* + * Rotate subkeys and do compression permutation. + */ + shifts = 0; + for(round = 0; round < 16; round++) { + unsigned long t0, t1; + + shifts += key_shifts[round]; + + t0 = (k0 << shifts) | (k0 >> (28 - shifts)); + t1 = (k1 << shifts) | (k1 >> (28 - shifts)); + + de_keysl[15 - round] = + en_keysl[round] = comp_maskl[0][(t0 >> 21) & 0x7f] + | comp_maskl[1][(t0 >> 14) & 0x7f] + | comp_maskl[2][(t0 >> 7) & 0x7f] + | comp_maskl[3][t0 & 0x7f] + | comp_maskl[4][(t1 >> 21) & 0x7f] + | comp_maskl[5][(t1 >> 14) & 0x7f] + | comp_maskl[6][(t1 >> 7) & 0x7f] + | comp_maskl[7][t1 & 0x7f]; + + de_keysr[15 - round] = en_keysr[round] = + comp_maskr[0][(t0 >> 21) & 0x7f] + | comp_maskr[1][(t0 >> 14) & 0x7f] + | comp_maskr[2][(t0 >> 7) & 0x7f] + | comp_maskr[3][t0 & 0x7f] + | comp_maskr[4][(t1 >> 21) & 0x7f] + | comp_maskr[5][(t1 >> 14) & 0x7f] + | comp_maskr[6][(t1 >> 7) & 0x7f] + | comp_maskr[7][t1 & 0x7f]; + } + return 0; +} + +static int do_des(unsigned long l_in, unsigned long r_in, unsigned long *l_out, + unsigned long *r_out, int count) { + /* + * l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format. + */ + unsigned long l, r, *kl, *kr, *kl1, *kr1; + unsigned long f, r48l, r48r; + int round; + + if(count == 0) { + return 1; + } else if(count > 0) { + /* + * Encrypting + */ + kl1 = en_keysl; + kr1 = en_keysr; + } else { + /* + * Decrypting + */ + count = -count; + kl1 = de_keysl; + kr1 = de_keysr; + } + + /* + * Do initial permutation (IP). + */ + l = ip_maskl[0][l_in >> 24] + | ip_maskl[1][(l_in >> 16) & 0xff] + | ip_maskl[2][(l_in >> 8) & 0xff] + | ip_maskl[3][l_in & 0xff] + | ip_maskl[4][r_in >> 24] + | ip_maskl[5][(r_in >> 16) & 0xff] + | ip_maskl[6][(r_in >> 8) & 0xff] + | ip_maskl[7][r_in & 0xff]; + r = ip_maskr[0][l_in >> 24] + | ip_maskr[1][(l_in >> 16) & 0xff] + | ip_maskr[2][(l_in >> 8) & 0xff] + | ip_maskr[3][l_in & 0xff] + | ip_maskr[4][r_in >> 24] + | ip_maskr[5][(r_in >> 16) & 0xff] + | ip_maskr[6][(r_in >> 8) & 0xff] + | ip_maskr[7][r_in & 0xff]; + + while(count--) { + /* + * Do each round. + */ + kl = kl1; + kr = kr1; + round = 16; + while(round--) { + /* + * Expand R to 48 bits (simulate the E-box). + */ + r48l = ((r & 0x00000001) << 23) + | ((r & 0xf8000000) >> 9) + | ((r & 0x1f800000) >> 11) + | ((r & 0x01f80000) >> 13) + | ((r & 0x001f8000) >> 15); + + r48r = ((r & 0x0001f800) << 7) + | ((r & 0x00001f80) << 5) + | ((r & 0x000001f8) << 3) + | ((r & 0x0000001f) << 1) + | ((r & 0x80000000) >> 31); + /* + * Do salting for crypt() and friends, and + * XOR with the permuted key. + */ + f = (r48l ^ r48r) & saltbits; + r48l ^= f ^ *kl++; + r48r ^= f ^ *kr++; + /* + * Do sbox lookups (which shrink it back to 32 bits) + * and do the pbox permutation at the same time. + */ + f = psbox[0][m_sbox[0][r48l >> 12]] + | psbox[1][m_sbox[1][r48l & 0xfff]] + | psbox[2][m_sbox[2][r48r >> 12]] + | psbox[3][m_sbox[3][r48r & 0xfff]]; + /* + * Now that we've permuted things, complete f(). + */ + f ^= l; + l = r; + r = f; + } + r = l; + l = f; + } + /* + * Do final permutation (inverse of IP). + */ + *l_out = fp_maskl[0][l >> 24] + | fp_maskl[1][(l >> 16) & 0xff] + | fp_maskl[2][(l >> 8) & 0xff] + | fp_maskl[3][l & 0xff] + | fp_maskl[4][r >> 24] + | fp_maskl[5][(r >> 16) & 0xff] + | fp_maskl[6][(r >> 8) & 0xff] + | fp_maskl[7][r & 0xff]; + *r_out = fp_maskr[0][l >> 24] + | fp_maskr[1][(l >> 16) & 0xff] + | fp_maskr[2][(l >> 8) & 0xff] + | fp_maskr[3][l & 0xff] + | fp_maskr[4][r >> 24] + | fp_maskr[5][(r >> 16) & 0xff] + | fp_maskr[6][(r >> 8) & 0xff] + | fp_maskr[7][r & 0xff]; + return 0; +} + +char *crypt(char *key, char *setting) { + unsigned long count, salt, l, r0, r1, keybuf[2]; + unsigned char *p, *q; + static unsigned char output[21]; + + if(!des_initialised) + des_init(); + /* + * Copy the key, shifting each character up by one bit + * and padding with zeros. + */ + q = (unsigned char *)keybuf; + while(q - (unsigned char *)keybuf - 8) { + if((*q++ = *key << 1)) + key++; + } + if(des_setkey((unsigned char *)keybuf)) + return NULL; + + /* + * "old"-style: + * setting - 2 bytes of salt + * key - up to 8 characters + */ + count = 25; + + salt = (ascii_to_bin(setting[1]) << 6) + | ascii_to_bin(setting[0]); + + output[0] = setting[0]; + /* + * If the encrypted password that the salt was extracted from + * is only 1 character long, the salt will be corrupted. We + * need to ensure that the output string doesn't have an extra + * NUL in it! + */ + output[1] = setting[1] ? setting[1] : output[0]; + + p = output + 2; + + setup_salt(salt); + /* + * Do it. + */ + if(do_des(0L, 0L, &r0, &r1, count)) + return NULL; + /* + * Now encode the result... + */ + l = (r0 >> 8); + *p++ = ascii64[(l >> 18) & 0x3f]; + *p++ = ascii64[(l >> 12) & 0x3f]; + *p++ = ascii64[(l >> 6) & 0x3f]; + *p++ = ascii64[l & 0x3f]; + + l = (r0 << 16) | ((r1 >> 16) & 0xffff); + *p++ = ascii64[(l >> 18) & 0x3f]; + *p++ = ascii64[(l >> 12) & 0x3f]; + *p++ = ascii64[(l >> 6) & 0x3f]; + *p++ = ascii64[l & 0x3f]; + + l = r1 << 2; + *p++ = ascii64[(l >> 12) & 0x3f]; + *p++ = ascii64[(l >> 6) & 0x3f]; + *p++ = ascii64[l & 0x3f]; + *p = 0; + + return output; +} +#endif diff --git a/mbbsd/dice.c b/mbbsd/dice.c new file mode 100644 index 00000000..d64ce63c --- /dev/null +++ b/mbbsd/dice.c @@ -0,0 +1,447 @@ +/* $Id: dice.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "modes.h" +#include "proto.h" + +#define DICE_TXT BBSHOME "/etc/dice.txt" +#define DICE_DATA BBSHOME "/etc/dice.data" +#define DICE_WIN BBSHOME "/etc/windice.log" +#define DICE_LOST BBSHOME "/etc/lostdice.log" + +#define B_MAX 500 +#define B_MIN 10 +#define B_COMMON 1 +#define B_TIMES 5 +#define B_THIRD 3 + +extern int usernum; +static int flag[100], value[100]; + +typedef struct dicedata_t { + int mybet; + int mymoney; +} dicedata_t; + +static void set_bingo(int bet[]) { + int i, j = 0, k = 0, m = 0; + + for(i = 0; i < 3; i++) + for(j = 2; j > i; j--) + if(bet[j] < bet[j - 1]) { + m = bet[j]; + bet[j] = bet[j - 1]; + bet[j - 1]=m; + } + + for(i = 0; i < 100; i++) + flag[i] = 0; + + for(i = 0; i < 3; i++) + flag[bet[i]]++; + j = bet[0] + bet[1] + bet[2]; + + if((abs(bet[1] - bet[0]) == 1 && abs(bet[2] - bet[0]) == 2) || + (abs(bet[2] - bet[0]) == 1 && abs(bet[1] - bet[0]) == 2)) + flag[66] = B_TIMES; + + if(j < 10){ + flag[7] = B_COMMON; + for(i = 0; i < 3; i++) + if(bet[i] == 4) + flag[74] = B_TIMES; + } else if(j > 11) { + flag[8] = B_COMMON; + for(i = 0; i < 3; i++) + if(bet[i] == 3) + flag[83]=B_TIMES; + } else + flag[11] = B_THIRD; + + for(i = 0; i < 3; i++) + for(j = i; j < 3; j++) { + m = bet[i]; + k = bet[j]; + if(m != k) + flag[m * 10 + k] = B_TIMES; + } +} + +static int bingo(int mybet) { + return flag[mybet]; +} + +int IsNum(char *a, int n) { + int i; + + for(i = 0; i < n; i++) + if (a[i] > '9' || a[i] < '0' ) + return 0; + return 1; +} + +int IsSNum(char *a) { + int i; + + for(i = 0; a[i]; i++) + if(a[i] > '9' || a[i] < '0') + return 0; + return 1; +} + +static void show_data(void) { + move(0, 0); + prints("\033[31m ¢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¢{\033[m\n"); + prints("\033[45;37m¿²v¤@\033[m\033[31m ¢x \033[33m[1]©ã¤@ÂI [2]©ã¤GÂI " + "[3]©ã¤TÂI [4]©ã¥|ÂI [5]©ã¤ÂI [6]©ã¤»ÂI \033[31m ¢x\033[m\n"); + prints("\033[31m ¢x \033[33m[7]©ã¤p [8]©ã¤j " + " \033[31m ¢x\033[m\n"); + prints("\033[31m ¢x " + " ¢x\033[m\n"); + prints("\033[45;37m½ß²v¤T\033[m\033[31m ¢x \033[33m[11]©ã¤¤(Á`ÂI¼Æµ¥©ó11" + "©Î10) \033[31m ¢x\033[m\n"); + prints("\033[31m ¢x " + " ¢x\033[m\n"); + prints("\033[45;37m½ß²v¤\033[m\033[31m ¢x \033[33m[74]©ã¤p¥B¥|ÂI [83]©ã" + "¤j¥B¤TÂI [66]©ã³s¸¹ \033[31m ¢x\033[m\n"); + prints("\033[31m ¢x " + " ¢x\033[m\n"); + prints("\033[31m ¢x \033[33m[12]©ã¤@¤GÂI [13]©ã¤@¤TÂI [14]©ã¤@¥|ÂI" + " [15]©ã¤@¤ÂI [16]©ã¤@¤»ÂI\033[31m ¢x\033[m\n"); + prints("\033[31m ¢x \033[33m[23]©ã¤G¤TÂI [24]©ã¤G¥|ÂI [25]©ã¤G¤ÂI" + " [26]©ã¤G¤»ÂI [34]©ã¤T¥|ÂI\033[31m ¢x\033[m\n"); + prints("\033[31m ¢x \033[33m[35]©ã¤T¤ÂI [36]©ã¤T¤»ÂI [45]©ã¥|¤ÂI" + " [46]©ã¥|¤»ÂI [56]©ã¤¤»ÂI\033[31m ¢x\033[m\n"); + prints("\033[31m ¢|¢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¢}\033[m\n"); +} + +static void show_count(int index, int money) { + int i = 0, count = 2, j, k; + + value[index] += money; + move(14,0); + clrtoline(18); + for(i = 1, j = 13; i <= 8; i++, count += 12) { + if(i == 6) { + j = 14; + count = 2; + } + move(j,count); + prints("[%2d]:%d ", i, value[i]); + } + + count = 2; + i = 15; + for(j = 1; j <= 5; j++) + for(k = j + 1; k <= 6; k++, count += 12) { + if(j == 2 && k == 4) { + i = 16; + count = 2; + } else if(j==4 && k==5) { + i = 17; + count = 2; + } + move(i,count); + prints("[%d%d]:%d ", j, k, value[j * 10 + k]); + } + + move(18,2); + prints("[11]:%d",value[11]); + move(18,14); + prints("[66]:%d",value[66]); + move(18,26); + prints("[74]:%d",value[74]); + move(18,38); + prints("[83]:%d",value[83]); +} + +static int check_index(int index) { + int i,tp[] = {1, 2, 3, 4, 5, 6, 7, 8, 11, 12, 13, 14, 15, 16, 23, 24, 25, + 26, 34, 35, 36, 45, 46, 56, 66, 74, 83}; + if(index < 0 || index > 100) + return 0; + for(i = 0; i < 27; i++) + if(index == tp[i]) + return 1; + return 0; +} + +extern userec_t cuser; + +static int del(int total, dicedata_t *table) { + int index, money; + char data[10]; + int i; + + while(1) { + do { + move(22,0); + clrtoeol(); + getdata(21, 0, "¿é¤J°h¿ïªº¼Æ¦r(¥´qÂ÷¶}): ", data, 3, LCECHO); + if(data[0] == 'q' || data[0] == 'Q') + return 0; + } while(!IsNum(data,strlen(data))); + + index = atoi(data); + for(i = 0; i < total; i++) { + if(table[i].mybet == index){ + do { + getdata(21, 0, "¦h¤Ö¿ú: ", data, 10, LCECHO); + } while(!IsNum(data,strlen(data))); + money = atoi(data); + if(money>table[i].mymoney) { + move(22,0); + clrtoeol(); + prints("¤£°÷¦©°Õ"); + i--; + continue; + } + demoney(money); + move(19,0); + clrtoeol(); + prints("§A²{¦b¦³ %u Ptt$¼Ú", cuser.money); + table[i].mymoney -= money; + show_count(index, -money); + break; + } + } + } + return 0; +} + +static int IsLegal(char *data) { + int money = atoi(data); + if(IsNum(data,strlen(data)) && money<=B_MAX && money>=B_MIN) + return money; + return 0; +} + +static void show_output(int bet[]) { + int i, j = 10; + + move(12,0); + clrtoline(17); + /* ¼È®É°°Õ ¦]¬°¨º¦Uclrtoline©Ç©Çªº */ + for(i = 13; i <= 18; i++) { + move(i,0); + prints(" "); + } + move(12,0); + prints("\033[1;31m ¢z¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w" + "¢w¢{\033[m\n\n\n\n\n\n"); + prints("\033[1;31m ¢|¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w" + "¢w¢}\033[m"); + for(i = 0; i < 3; i++, j += 25) { + switch(bet[i]) { + case 1: + move(13, j);prints("\033[37m¢~¢w¢w¢w¢w¢¡\033[m"); + move(14, j);prints("\033[37m¢x ¢x\033[m"); + move(15, j);prints("\033[37m¢x ¡´ ¢x\033[m"); + move(16, j);prints("\033[37m¢x ¢x\033[m"); + move(17, j);prints("\033[37m¢¢¢w¢w¢w¢w¢£\033[m"); + break; + case 2: + move(13, j);prints("\033[37m¢~¢w¢w¢w¢w¢¡\033[m"); + move(14, j);prints("\033[37m¢x ¡´¢x\033[m"); + move(15, j);prints("\033[37m¢x ¢x\033[m"); + move(16, j);prints("\033[37m¢x¡´ ¢x\033[m"); + move(17, j);prints("\033[37m¢¢¢w¢w¢w¢w¢£\033[m"); + break; + case 3: + move(13, j);prints("\033[37m¢~¢w¢w¢w¢w¢¡\033[m"); + move(14, j);prints("\033[37m¢x ¡´¢x\033[m"); + move(15, j);prints("\033[37m¢x ¡´ ¢x\033[m"); + move(16, j);prints("\033[37m¢x¡´ ¢x\033[m"); + move(17, j);prints("\033[37m¢¢¢w¢w¢w¢w¢£\033[m"); + break; + case 4: + move(13, j);prints("\033[37m¢~¢w¢w¢w¢w¢¡\033[m"); + move(14, j);prints("\033[37m¢x¡´ ¡´¢x\033[m"); + move(15, j);prints("\033[37m¢x ¢x\033[m"); + move(16, j);prints("\033[37m¢x¡´ ¡´¢x\033[m"); + move(17, j);prints("\033[37m¢¢¢w¢w¢w¢w¢£\033[m"); + break; + case 5: + move(13, j);prints("\033[37m¢~¢w¢w¢w¢w¢¡\033[m"); + move(14, j);prints("\033[37m¢x¡´ ¡´¢x\033[m"); + move(15, j);prints("\033[37m¢x ¡´ ¢x\033[m"); + move(16, j);prints("\033[37m¢x¡´ ¡´¢x\033[m"); + move(17, j);prints("\033[37m¢¢¢w¢w¢w¢w¢£\033[m"); + break; + case 6: + move(13, j);prints("\033[37m¢~¢w¢w¢w¢w¢¡\033[m"); + move(14, j);prints("\033[37m¢x¡´ ¡´¢x\033[m"); + move(15, j);prints("\033[37m¢x¡´ ¡´¢x\033[m"); + move(16, j);prints("\033[37m¢x¡´ ¡´¢x\033[m"); + move(17, j);prints("\033[37m¢¢¢w¢w¢w¢w¢£\033[m"); + break; + } + } +} + +#define lockreturn0(unmode, state) if(lockutmpmode(unmode, state)) return 0 + +int dice_main(void) { + char input[10],data[256], ch; + dicedata_t table[256]; + int bet[3], index, money = 0, i, ya = 0, j, total, sig = 0; + FILE *winfp/* , *lostfp */; + + more(DICE_TXT, NA); + reload_money(); + if(cuser.money < 10){ + move(19,0); + prints("\033[1;37m¶W¹L¤Q¤¸¦A¨Óª±§a~~\033[m"); + pressanykey(); + return 0; + } + + lockreturn0(DICE, LOCK_MULTI); + winfp = fopen(DICE_WIN,"a"); + /*lostfp = fopen(DICE_LOST,"a");*/ + if(!winfp /*|| !lostfp*/) + return 0; + + do { + total = 0; i = 0; + ch = 'y'; + clear(); + show_data(); + for(j = 0; j < 3; j++) + bet[j] = rand() % 6 + 1; + + for(j = 0; j < 100; j++) + value[j] = 0; + + while(1) { + move(19,0); + prints("\033[1;32m§A²{¦b¦³\033[1;31m %u \033[1;32mPtt$¼Ú\033[m", + cuser.money); + getdata(20, 0, "\033[1;37m¼Æ¦r:¥[¿ï d:°h¿ï s:¶}©l©ÎÂ÷¶}\033[m: ", + input, 5, LCECHO); + reload_money(); + if(input[0] != 's' && input[0] != 'd' && cuser.money < 10) { + move(21, 0); + clrtoeol(); + prints("\033[1;37m¶W¹L¤Q¤¸¤~¯à½ä~\033[m"); + continue; + } + if(input[0] == 'd' || input[0] == 'D') { + del(i, table); + continue; + } + if(input[0] == 's' || input[0] == 'S') + break; + + if(!IsNum(input,strlen(input))) + continue; + + index=atoi(input); + if(check_index(index) == 0) + continue; +/*¿é¤J¿úªºloop*/ + while(1) { + if(cuser.money < 10) + break; + getdata(21, 0, "\033[1;32m½ä¦h¤Ö¿ú©O\033[1;37m(¤j©ó10 ¤p©ó500)" + "\033[m: ", input, 9, LCECHO); + if(!(money = IsLegal(input))||input[0] == '0') + continue; + reload_money(); + if(money > cuser.money) + continue; + for(j = 0, sig = 0; j < i; j++) + if(table[j].mybet == index) { + if(table[j].mymoney == B_MAX) + sig = 2; + else if(table[j].mymoney+money>B_MAX) { + sig = 1; + break; + } else { + vice(money,"»ë¤l"); + table[j].mymoney += money; + j = -1; + break; + } + } + if(sig == 2) + break; + if(sig == 1) + continue; + if(j != -1) { + bzero((char*)&table[i], sizeof(dicedata_t)); + table[i].mybet = index; + table[i++].mymoney = money; + vice(money,"»ë¤l"); + } + break; + } + reload_money(); + move(19,0); + prints("\033[1;32m§A²{¦b¦³ \033[1;31m%u\033[1;32m Ptt$¼Ú", + cuser.money); + if(sig != 2) + show_count(index, money); + } + + if(i == 0) { + fclose(winfp); + /*fclose(lostfp);*/ + unlockutmpmode(); + return 0; + } + + show_output(bet); + set_bingo(bet); + + for(j = 0; j < i; j++) { + if(table[j].mymoney <= 0) + continue; + ya = bingo(table[j].mybet); + if(ya == 0) { + /*sprintf(data, "%-15s ¿é¤F %-8d $", cuser.userid, + table[j].mymoney); + fprintf(lostfp, "%s\n", data);*/ + continue; + } + demoney(table[j].mymoney * ya + table[j].mymoney); + total += table[j].mymoney * ya; + if (table[j].mymoney * ya > 500){ /* ¶W¹L500¶ô¿ú¤~°µlog ´î¤Öio */ + sprintf(data, "%-15s ©ã%-2d¿ï¶µ%-8d¶ô¿ú ¤¤¤F%d¿ ²bÁÈ:%-8d\n", + cuser.userid,table[j].mybet, + table[j].mymoney, ya, table[j].mymoney * ya); + fputs(data,winfp); + } + ya = 0; + } + + if(total > 0) { + move(21,0); + prints("\033[1;32m§AŤF \033[1;31m%d\033[1;32m Ptt$ ò~~" + " \033[m", total); + } else { + move(21,0); + clrtoeol(); + prints("\033[1;32m¯u¥i±¤ ¤U¦¸¦A¨Ó¸I¸I¹B®ð§a\033[m"); + } + + move(19,0); + clrtoeol(); + prints("\033[1;32m§A²{¦b¦³ \033[1;31m%u\033[1;32m Ptt$¼Ú\033[m", + cuser.money); + + getdata(23, 0, "\033[1;32mÄ~Äò¾Ä°«[\033[1;37my/n\033[1;32m]\033[m: ", + input, 2, LCECHO); + } while(input[0] != 'n' && input[0] != 'N'); + fclose(winfp); + /*fclose(lostfp);*/ + unlockutmpmode(); + return 0; +} diff --git a/mbbsd/edit.c b/mbbsd/edit.c new file mode 100644 index 00000000..19f437af --- /dev/null +++ b/mbbsd/edit.c @@ -0,0 +1,2256 @@ +/* $Id: edit.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <unistd.h> +#include <time.h> +#include <sys/types.h> +#include "config.h" +#include "pttstruct.h" +#include "config.h" +#include "common.h" +#include "modes.h" +#include "perm.h" +#include "proto.h" + +#define WRAPMARGIN (511) + +typedef struct textline_t { + struct textline_t *prev; + struct textline_t *next; + int len; + char data[WRAPMARGIN + 1]; +} textline_t; + +extern int current_font_type; +extern char *str_author1; +extern char *str_author2; +extern int t_lines, t_columns; /* Screen size / width */ +extern int b_lines; /* Screen bottom line number: t_lines-1 */ +extern char quote_file[80]; +extern char quote_user[80]; +extern int curredit; +extern unsigned int currbrdattr; +extern char currboard[]; /* name of currently selected board */ +extern char *str_reply; +extern char *str_post1; +extern char *str_post2; +extern char *BBSName; +extern char fromhost[]; +extern unsigned int currstat; +extern crosspost_t postrecord; +extern userinfo_t *currutmp; +extern int KEY_ESC_arg; +extern char reset_color[]; +extern char trans_buffer[256]; + +#define KEEP_EDITING -2 +#define BACKUP_LIMIT 100 +#define SCR_WIDTH 80 + +enum { + NOBODY, MANAGER, SYSOP +}; + +static textline_t *firstline = NULL; +static textline_t *lastline = NULL; +static textline_t *currline = NULL; +static textline_t *blockline = NULL; +static textline_t *top_of_win = NULL; +static textline_t *deleted_lines = NULL; + +extern int local_article; +extern char real_name[20]; +static char line[WRAPMARGIN + 2]; +static int ifuseanony=0; +static int currpnt, currln, totaln; +static int curr_window_line; +static int redraw_everything; +static int insert_character; +static int my_ansimode; +static int raw_mode; +static int edit_margin; +static int blockln = -1; +static int blockpnt; +static int prevln = -1; +static int prevpnt; +static int line_dirty; +static int indent_mode; +static int insert_c = ' '; + +static char fp_bak[] = "bak"; + +char save_title[STRLEN]; + +/* °O¾ÐÅéºÞ²z»P½s¿è³B²z */ +static void indigestion(i) { + fprintf(stderr, "ÄY«¤º¶Ë %d\n", i); +} + +/* Thor: ansi ®y¼ÐÂà´« for color ½s¿è¼Ò¦¡ */ +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(ch)) + tmp++; + if(ch) + tmp++; + continue; + } + if(ansix <= 0) + break; + tmp++; + ansix--; + } + return tmp - data; +} + +static int n2ansi(int nx, textline_t * line) { + register int 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(ch)) + tmp++; + if(ch) + tmp++; + continue; + } + if(tmp >= nxp) + break; + tmp++; + ansix++; + } + return ansix; +} + +/* ¿Ã¹õ³B²z¡G»²§U°T®§¡BÅã¥Ü½s¿è¤º®e */ +static void edit_msg() { + static char *edit_mode[2] = {"¨ú¥N", "´¡¤J"}; + register int n = currpnt; + + if(my_ansimode) /* Thor: §@ ansi ½s¿è */ + n = n2ansi(n, currline); + n++; + move(b_lines, 0); + clrtoeol(); + prints("\033[%sm ½s¿è¤å³¹ \033[31;47m (Ctrl-Z)\033[30m»²§U»¡©ú " + "\033[31;47m(^G)\033[30m´¡¤J¹Ï¤å®w \033[31m(^X,^Q)" + "\033[30mÂ÷¶}ùø%s¢x%c%c%c%cùø %3d:%3d \033[m", + "37;44", + edit_mode[insert_character], + my_ansimode ? 'A' : 'a', indent_mode ? 'I' : 'i', + 'P' , raw_mode ? 'R' : 'r', + currln + 1, n); +} + +static textline_t *back_line(textline_t *pos, int num) { + while(num-- > 0) { + register textline_t *item; + + if(pos && (item = pos->prev)) { + pos = item; + currln--; + } + } + return pos; +} + +static textline_t *forward_line(textline_t *pos, int num) { + while(num-- > 0) { + register textline_t *item; + + if(pos && (item = pos->next)) { + pos = item; + currln++; + } + } + return pos; +} + +static int getlineno() { + int cnt = 0; + textline_t *p = currline; + + while(p && (p != top_of_win)) { + cnt++; + p = p->prev; + } + return cnt; +} + +static char *killsp(char *s) { + while(*s == ' ') + s++; + return s; +} + +static textline_t *alloc_line() { + register textline_t *p; + + if((p = (textline_t *)malloc(sizeof(textline_t)))) { + memset(p, 0, sizeof(textline_t)); + return p; + } + + indigestion(13); + abort_bbs(0); + return NULL; +} + +/* append p after line in list. keeps up with last line */ +static void append(textline_t *p, textline_t *line) { + register textline_t *n; + + if((p->next = n = line->next)) + n->prev = p; + else + lastline = p; + line->next = p; + p->prev = line; +} + +/* + delete_line deletes 'line' from the list, + and maintains the lastline, and firstline pointers. +*/ + +static void delete_line(textline_t *line) { + register textline_t *p = line->prev; + register textline_t *n = line->next; + + if(!p && !n) { + line->data[0] = line->len = 0; + return; + } + if(n) + n->prev = p; + else + lastline = p; + if(p) + p->next = n; + else + firstline = n; + strcat(line->data, "\n"); + line->prev = deleted_lines; + deleted_lines = line; + totaln--; +} + +static int ask(char *prompt) { + int ch; + + move (0, 0); + clrtoeol (); + standout (); + prints ("%s", prompt); + standend (); + ch = igetkey (); + move (0, 0); + clrtoeol (); + return (ch); +} + +static int indent_spcs() { + textline_t* p; + int spcs; + + if(!indent_mode) + return 0; + + for(p = currline; p; p = p->prev) { + for(spcs = 0; p->data[spcs] == ' '; ++spcs); + if (p->data[spcs]) + return spcs; + } + return 0; +} + +/* split 'line' right before the character pos */ +static void split(textline_t *line, int pos) { + if(pos <= line->len) { + register textline_t *p = alloc_line(); + register char *ptr; + int spcs = indent_spcs(); + + totaln++; + + p->len = line->len - pos + spcs; + line->len = pos; + + memset(p->data, ' ', spcs); + p->data[spcs] = 0; + strcat(p->data, (ptr = line->data + pos)); + ptr[0] = '\0'; + append(p, line); + if(line == currline && pos <= currpnt) { + currline = p; + if(pos == currpnt) + currpnt = spcs; + else + currpnt -= pos; + curr_window_line++; + currln++; + } + redraw_everything = YEA; + } +} + +static void insert_char(int ch) { + register textline_t *p = currline; + register int i = p->len; + register char *s; + int wordwrap = YEA; + + if(currpnt > i) { + indigestion(1); + return; + } + if(currpnt < i && !insert_character) { + p->data[currpnt++] = ch; + /* Thor: ansi ½s¿è, ¥i¥Hoverwrite, ¤£»\¨ì ansi code */ + if(my_ansimode) + currpnt = ansi2n(n2ansi(currpnt, p),p); + } else { + while(i >= currpnt) { + p->data[i + 1] = p->data[i]; + i--; + } + p->data[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); + } + 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++; + } + } +} + +static void insert_string(char *str) { + int ch; + + while((ch = *str++)) { + if(isprint2(ch) || ch == '\033') + insert_char(ch); + else if(ch == '\t') { + do { + insert_char(' '); + } while(currpnt & 0x7); + } else if(ch == '\n') + split(currline, currpnt); + } +} + +static int undelete_line() { + textline_t* p = deleted_lines; + textline_t* currline0 = currline; + textline_t* top_of_win0 = top_of_win; + int currpnt0 = currpnt; + int currln0 = currln; + int curr_window_line0 = curr_window_line; + int indent_mode0 = indent_mode; + + if(!deleted_lines) + return 0; + + indent_mode = 0; + insert_string(deleted_lines->data); + indent_mode = indent_mode0; + deleted_lines = deleted_lines->prev; + free(p); + + currline = currline0; + top_of_win = top_of_win0; + currpnt = currpnt0; + currln = currln0; + curr_window_line = curr_window_line0; + return 0; +} + +/* + 1) lines were joined and one was deleted + 2) lines could not be joined + 3) next line is empty + returns false if: + 1) Some of the joined line wrapped +*/ +static int join(textline_t *line) { + register textline_t *n; + register int ovfl; + + if(!(n = line->next)) + return YEA; + if(!*killsp(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); + return YEA; + } else { + register char *s; + + 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 + n->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++; + } + } + return NA; + } +} + +static void delete_char() { + register int len; + + if((len = currline->len)) { + register int i; + register char *s; + + if(currpnt >= len) { + indigestion(1); + return; + } + for(i = currpnt, s = currline->data + i; i != len; i++, s++) + s[0] = s[1]; + currline->len--; + } +} + +static void load_file(FILE *fp) { + int indent_mode0 = indent_mode; + + indent_mode = 0; + while(fgets(line, WRAPMARGIN + 2, fp)) + insert_string(line); + fclose(fp); + 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(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, 4, LCECHO); + if(*ans != 'n' && (fp = fopen(fp_tmpbuf, "r"))) { + prevln = currln; + prevpnt = currpnt; + load_file(fp); + while(curr_window_line >= b_lines) { + curr_window_line--; + top_of_win = top_of_win->next; + } + } +} + +static void write_tmpbuf() { + FILE *fp; + char fp_tmpbuf[80], ans[4]; + textline_t *p; + + 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, 4, LCECHO); + + if(ans[0] == 'q') + return; + } + + if((fp = fopen(fp_tmpbuf, (ans[0] == 'w' ? "w" : "a+")))) { + for(p = firstline; p; p = p->next) { + if(p->next || p->data[0]) + fprintf(fp, "%s\n", p->data); + } + fclose(fp); + } +} + +static void erase_tmpbuf() { + 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, 4, LCECHO); + if(*ans == 'y') + unlink(fp_tmpbuf); +} + +/* ½s¿è¾¹¦Û°Ê³Æ¥÷ */ +void auto_backup() { + if(currline) { + FILE *fp; + textline_t *p, *v; + char bakfile[64]; + int count = 0; + + setuserfile(bakfile, fp_bak); + if((fp = fopen(bakfile, "w"))) { + for(p = firstline; p != NULL && count < 512; p = v,count++) { + v = p->next; + fprintf(fp, "%s\n", p->data); + free(p); + } + fclose(fp); + } + currline = NULL; + } +} + +void restore_backup() { + 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(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 do_quote() { + int op; + char buf[256]; + + 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 = indent_mode; + + fgets(buf, 256, 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, ' '); + str[0] = '\0'; + } + } else + ptr = quote_user; + + indent_mode = 0; + insert_string("¡° ¤Þz¡m"); + insert_string(ptr); + insert_string("¡n¤§»Ê¨¥¡G\n"); + + if(op != 'a') /* ¥h±¼ header */ + while(fgets(buf, 256, inf) && buf[0] != '\n'); + + if(op == 'a') + while(fgets(buf, 256, inf)) { + insert_char(':'); + insert_char(' '); + insert_string(Ptt_prints(buf,STRIP_ALL)); + } + else if(op == 'r') + while(fgets(buf, 256, inf)) + insert_string(Ptt_prints(buf,NO_RELOAD)); + else { + if(curredit & EDIT_LIST) /* ¥h±¼ mail list ¤§ header */ + while (fgets(buf, 256, inf) && (!strncmp(buf, "¡° ", 3))); + while(fgets(buf, 256, inf)) { + if(!strcmp(buf, "--\n")) + break; + if(!garbage_line(buf)) { + insert_char(':'); + insert_char(' '); + insert_string(Ptt_prints(buf,STRIP_ALL)); + } + } + } + indent_mode = indent_mode0; + fclose(inf); + } + } +} + +/* ¼f¬d user ¤Þ¨¥ªº¨Ï¥Î */ +static int check_quote() { + register textline_t *p = 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" + "\033[1;33m1) ¼W¥[¤@¨Ç¤å³¹ ©Î 2) §R°£¤£¥²n¤§¤Þ¨¥\033[m"); + { + char ans[4]; + + getdata(12, 12, "(E)Ä~Äò½s¿è (W)±j¨î¼g¤J¡H[E] ", ans, 4, LCECHO); + if(ans[0] == 'w') + return 0; + } + return 1; + } + return 0; +} + +/* Àɮ׳B²z¡GŪÀÉ¡B¦sÀÉ¡B¼ÐÃD¡Bñ¦WÀÉ */ +static void read_file(char *fpath) { + FILE *fp; + + if((fp = fopen(fpath, "r")) == NULL) { + if((fp = fopen(fpath, "w+"))) { + fclose(fp); + return; + } + indigestion(4); + abort_bbs(0); + } + load_file(fp); +} + +extern userec_t cuser; + +void write_header(FILE *fp) { + time_t now = time(0); + + if(curredit & EDIT_MAIL || curredit & EDIT_LIST) { + fprintf(fp, "%s %s (%s)\n", str_author1, cuser.userid, +#if defined(REALINFO) && defined(MAIL_REALNAMES) + cuser.realname +#else + cuser.username +#endif + ); + } else { + char *ptr; + struct { + char author[IDLEN + 1]; + char board[IDLEN + 1]; + char title[66]; + time_t date; /* last post's date */ + int number; /* post number */ + } postlog; + + strcpy(postlog.author, cuser.userid); + 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, 12, DOECHO); + else + getdata(3, 0, "½Ð¿é¤J§A·Q¥ÎªºID¡A¤]¥iª½±µ«ö[Enter]¨Ï¥ÎìID¡G", + real_name, 12, DOECHO); + if(!real_name[0] && defanony) { + strcpy(real_name, "Anonymous"); + strcpy(postlog.author, real_name); + ifuseanony = 1; + } else { + if(!strcmp("r",real_name) || (!defanony && !real_name[0])) + sprintf(postlog.author,"%s",cuser.userid); + else { + sprintf(postlog.author,"%s.",real_name); + ifuseanony=1; + } + } + } +#endif + strcpy(postlog.board, currboard); + ptr = save_title; + if(!strncmp(ptr, str_reply, 4)) + ptr += 4; + strncpy(postlog.title, ptr, 65); + 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.username : + "²q²q§Ú¬O½Ö ? ^o^"), + local_article ? str_post2 : str_post1, currboard); + } else { + fprintf(fp, "%s %s (%s) %s %s\n", str_author1, cuser.userid, +#if defined(REALINFO) && defined(POSTS_REALNAMES) + cuser.realname, +#else + cuser.username, +#endif + local_article ? str_post2 : str_post1, currboard); + } +#else /* HAVE_ANONYMOUS */ + fprintf(fp, "%s %s (%s) %s %s\n", str_author1, cuser.userid, +#if defined(REALINFO) && defined(POSTS_REALNAMES) + cuser.realname, +#else + cuser.username, +#endif + local_article ? str_post2 : str_post1, currboard); +#endif /* HAVE_ANONYMOUS */ + + } + save_title[72] = '\0'; + fprintf(fp, "¼ÐÃD: %s\n®É¶¡: %s\n", save_title, ctime(&now)); +} + +void addsignature(FILE *fp, int ifuseanony) { + FILE *fs; + int i; + char buf[WRAPMARGIN + 1]; + char fpath[STRLEN]; + + static char msg[] = "½Ð¿ï¾Üñ¦WÀÉ (1-9, 0=¤£¥[)[0]: "; + char ch; + + if(!strcmp(cuser.userid,STR_GUEST)) { + fprintf(fp, "\n--\n¡° µo«H¯¸ :" BBSNAME "(" MYHOSTNAME + ") \n¡» From: %s\n", fromhost); + return; + } + if(!ifuseanony) { + i = showsignature(fpath); + msg[27] = ch = '0' | (cuser.uflag & SIG_FLAG); + getdata(0, 0, msg, buf, 4, DOECHO); + + if(ch != buf[0] && buf[0] >= '0' && buf[0] <= '9') { + ch = buf[0]; + cuser.uflag = (cuser.uflag & ~SIG_FLAG) | (ch & SIG_FLAG); + } + + if(ch != '0') { + fpath[i] = ch; + 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); + } + } + } +#ifdef HAVE_ORIGIN +#ifdef HAVE_ANONYMOUS + if(ifuseanony) + fprintf(fp, "\n--\n¡° µo«H¯¸: " BBSNAME "(" MYHOSTNAME + ") \n¡» From: %s\n", "¼Ê¦W¤Ñ¨Ïªº®a"); + else { + char temp[32]; + + strncpy(temp, fromhost, 31); + temp[32] = '\0'; + fprintf(fp, "\n--\n¡° µo«H¯¸: " BBSNAME "(" MYHOSTNAME + ") \n¡» From: %s\n", temp); + } +#else + strncpy (temp,fromhost,15); + fprintf(fp, "\n--\n¡° µo«H¯¸: " BBSNAME "(" MYHOSTNAME + ") \n¡» From: %s\n", temp); +#endif +#endif +} + +static int +write_file(char *fpath, int saveheader, int *islocal) { + time_t now; + 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"); + if(currstat == SMAIL) + msg = "[S]Àx¦s (A)©ñ±ó (T)§ï¼ÐÃD (E)Ä~Äò (R/W/D)Ū¼g§R¼È¦sÀÉ¡H"; + else if(local_article) + msg = "[L]¯¸¤º«H¥ó (S)Àx¦s (A)©ñ±ó (T)§ï¼ÐÃD (E)Ä~Äò " + "(R/W/D)Ū¼g§R¼È¦sÀÉ¡H"; + else + msg = "[S]Àx¦s (L)¯¸¤º«H¥ó (A)©ñ±ó (T)§ï¼ÐÃD (E)Ä~Äò " + "(R/W/D)Ū¼g§R¼È¦sÀÉ¡H"; + getdata(1, 0, msg, ans, 3, LCECHO); + + switch(ans[0]) { + case 'a': + outs("¤å³¹\033[1m ¨S¦³ \033[m¦s¤J"); + safe_sleep(1); + aborted = -1; + break; + case 'r': + read_tmpbuf(-1); + case 'e': + return KEEP_EDITING; + case 'w': + write_tmpbuf(); + return KEEP_EDITING; + case 'd': + erase_tmpbuf(); + return KEEP_EDITING; + case 't': + move(3, 0); + prints("¼ÐÃD¡G%s", save_title); + strcpy(ans,save_title); + if(getdata_buf(4, 0, "·s¼ÐÃD¡G", ans, TTLEN, DOECHO)) + strcpy(save_title, ans); + return KEEP_EDITING; + case 's': + if(!HAS_PERM(PERM_LOGINOK)) { + local_article = 1; + move(2, 0); + prints("±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) { + sethomepath(fpath, cuser.userid); + strcpy(fpath, tempnam(fpath, "ve_")); + } + + if((fp = fopen(fpath, "w")) == NULL) { + indigestion(5); + abort_bbs(0); + } + if(saveheader) + write_header(fp); + } + + for(p = firstline; p; p = v) { + v = p->next; + if(!aborted) { + msg = p->data; + if(v || msg[0]) { + trim(msg); + + line++; + if(currstat == POSTING && po) { + saveheader = str_checksum(msg); + if(saveheader) { + if(postrecord.checksum[po] == saveheader) { + po++; + if(po > 3) { + postrecord.times++; + po =0; + } + } else + po = 1; + if(currstat == POSTING && line >= totaln/2 && + sum < 3) { + checksum[sum++] = saveheader; + } + } + } +#ifdef SUPPORT_GB + if(current_font_type == TYPE_GB) + { + fprintf(fp, "%s\n", hc_convert_str(msg, HC_GBtoBIG, HC_DO_SINGLE)); + } + else +#endif + fprintf(fp, "%s\n", msg); + } + } + free(p); + } + currline = NULL; + + if(postrecord.times > MAX_CROSSNUM - 1) + anticrosspost(); + + if(po && sum == 3) { + memcpy(&postrecord.checksum[1], checksum, sizeof(int) * 3); + postrecord.times =0; + } + if(!aborted) { + if(islocal) + *islocal = (local_article == 1); + if(currstat == POSTING || currstat == SMAIL) + addsignature(fp,ifuseanony); + else if(currstat == REEDIT +#ifndef ALL_REEDIT_LOG + && strcmp(currboard, "SYSOP") == 0 +#endif + ) + { + time(&now); + ptime = localtime(&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); + if(local_article && (currstat == POSTING)) + return 0; + return 0; + } + return aborted; +} + + +static void display_buffer() { + register textline_t *p; + register int i; + int inblock; + char buf[WRAPMARGIN + 2]; + int min, max; + + if(currpnt > blockpnt) { + min = blockpnt; + max = currpnt; + } else { + min = currpnt; + max = blockpnt; + } + + for(p = top_of_win, i = 0; i < b_lines; i++) { + move(i, 0); + clrtoeol(); + if(blockln >= 0 && + ((blockln <= currln && blockln <= (currln - curr_window_line + i) && + (currln - curr_window_line + i) <= currln) || + (currln <= (currln - curr_window_line + i) && + (currln - curr_window_line + i) <= blockln))) { + outs("\033[7m"); + inblock = 1; + } else + inblock = 0; + if(p) { + if(my_ansimode) + if(currln == blockln && p == currline && max > min) { + outs("\033[m"); + strncpy(buf, p->data, min); + buf[min] = 0; + outs(buf); + outs("\033[7m"); + strncpy(buf, p->data + min, max - min); + buf[max - min] = 0; + outs(buf); + outs("\033[m"); + outs(p->data + max); + } else + outs(p->data); + else if(currln == blockln && p == currline && max > min) { + outs("\033[m"); + strncpy(buf, p->data, min); + buf[min] = 0; + edit_outs(buf); + outs("\033[7m"); + strncpy(buf, p->data + min, max - min); + buf[max - min] = 0; + edit_outs(buf); + outs("\033[m"); + edit_outs(p->data + max); + } else + edit_outs(&p->data[edit_margin]); + p = p->next; + if(inblock) + outs("\033[m"); + } else + outch('~'); + } + edit_msg(); +} + +static void goto_line(int lino) { + char buf[10]; + + if(lino > 0 || + (getdata(b_lines - 1, 0, "¸õ¦Ü²Ä´X¦æ:", buf, 10, DOECHO) && + sscanf(buf, "%d", &lino) && lino > 0)) { + textline_t* p; + + prevln = currln; + prevpnt = currpnt; + p = firstline; + currln = lino - 1; + + while(--lino && p->next) + p = p->next; + + if(p) + currline = p; + else { + currln = totaln; + currline = lastline; + } + currpnt = 0; + if(currln < 11) { + top_of_win = firstline; + curr_window_line = currln; + } else { + int i; + + curr_window_line = 11; + for(i = curr_window_line; i; i--) + p = p->prev; + top_of_win = p; + } + } + redraw_everything = YEA; +} + +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; +} + +/* + mode: + 0: prompt + 1: forward + -1: backward +*/ +static void search_str(int mode) { + static char str[80]; + typedef char* (*FPTR)(); + static FPTR fptr; + char ans[4] = "n"; + + if(!mode) { + if(getdata_buf(b_lines - 1, 0,"[·j´M]ÃöÁä¦r:",str, 65, DOECHO)) + if(*str) { + if(getdata(b_lines - 1, 0, "°Ï¤À¤j¤p¼g(Y/N/Q)? [N] ", + ans, 4, LCECHO) && *ans == 'y') + fptr = strstr; + else + fptr = strcasestr; + } + } + + if(*str && *ans != 'q') { + textline_t* p; + char *pos = NULL; + int lino; + + if(mode >= 0) { + for(lino = currln, p = currline; p; p = p->next, lino++) + if((pos = fptr(p->data + (lino == currln ? currpnt + 1 : 0), + str)) && (lino != currln || + pos - p->data != currpnt)) + break; + } else { + for(lino = currln, p = currline; p; p = p->prev, lino--) + if((pos = fptr(p->data, str)) && + (lino != currln || pos - p->data != currpnt)) + break; + } + if(pos) { + prevln = currln; + prevpnt = currpnt; + currline = p; + currln = lino; + currpnt = pos - p->data; + if(lino < 11) { + top_of_win = firstline; + curr_window_line = currln; + } else { + int i; + + curr_window_line = 11; + for(i = curr_window_line; i; i--) + p = p->prev; + top_of_win = p; + } + redraw_everything = YEA; + } + } + if(!mode) + redraw_everything = YEA; +} + +static void match_paren() { + static char parens[] = "()[]{}"; + int type; + int parenum = 0; + char *ptype; + textline_t* p; + int lino; + int c, i = 0; + + if(!(ptype = strchr(parens, currline->data[currpnt]))) + return; + + type = (ptype - parens) / 2; + parenum += ((ptype - parens) % 2) ? -1 : 1; + + if(parenum > 0) { + for(lino = currln, p = currline; p; p = p->next, lino++) { + lino = lino; + for(i = (lino == currln) ? currpnt + 1 : 0; + i < strlen(p->data); i++) + if(p->data[i] == '/' && p->data[++i] == '*') { + ++i; + while(1) { + while(i < strlen(p->data) - 1 && + !(p->data[i] == '*' && p->data[i + 1] == '/')) + i++; + if(i >= strlen(p->data) - 1 && p->next) { + p = p->next; + ++lino; + i = 0; + } else + break; + } + } else if((c = p->data[i]) == '\'' || c == '"') { + while(1) { + while(i < (int)(strlen(p->data) - 1)) + if(p->data[++i] == '\\' && i < strlen(p->data) - 2) + ++i; + else if(p->data[i] == c) + goto end_quote; + if(i >= strlen(p->data) - 1 && p->next) { + p = p->next; + ++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 = currln, p = currline; p; p = p->prev, lino--) + for(i = (lino == currln) ? currpnt - 1 : strlen(p->data) - 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; + --lino; + i = strlen(p->data) - 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; + --lino; + i = strlen(p->data); + } 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 = currln - curr_window_line; + int bottom = currln - curr_window_line + b_lines - 1; + + currpnt = i; + currline = p; + curr_window_line += lino - currln; + currln = lino; + + if(lino < top || lino > bottom) { + if(lino < 11) { + top_of_win = firstline; + curr_window_line = currln; + } else { + int i; + + curr_window_line = 11; + for(i = curr_window_line; i; i--) + p = p->prev; + top_of_win = p; + } + redraw_everything = YEA; + } + } +} + +static void block_del(int hide) { + if(blockln < 0) { + blockln = currln; + blockpnt = currpnt; + blockline = currline; + } else { + char fp_tmpbuf[80]; + FILE* fp; + textline_t *begin, *end, *p; + char tmpfname[10] = "buf.0"; + char ans[6] = "w+n"; + + move(b_lines - 1, 0); + clrtoeol(); + if(hide == 1) + tmpfname[4] = 'q'; + else if(!hide && !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') + tmpfname[4] = 'q'; + if('1' <= tmpfname[4] && tmpfname[4] <= '9') { + setuserfile(fp_tmpbuf, tmpfname); + if(tmpfname[4] != '5' && dashf(fp_tmpbuf)) { + more(fp_tmpbuf, NA); + getdata(b_lines - 1, 0, "¼È¦sÀɤw¦³¸ê®Æ (A)ªþ¥[ (W)Âмg " + "(Q)¨ú®ø¡H[W] ", ans, 4, LCECHO); + if(*ans == 'q') + tmpfname[4] = 'q'; + else if(*ans != 'a') + *ans = 'w'; + } + if(tmpfname[4] != '5') { + getdata(b_lines - 1, 0, "§R°£°Ï¶ô(Y/N)?[N] ", + ans + 2, 4, LCECHO); + if(ans[2] != 'y') + ans[2] = 'n'; + } + } else if(hide != 3) + ans[2] = 'y'; + + tmpfname[5] = ans[1] = ans[3] = 0; + if(tmpfname[4] != 'q') { + if(currln >= blockln) { + begin = blockline; + end = currline; + if(ans[2] == 'y' && !(begin == end && currpnt != blockpnt)) { + curr_window_line -= (currln - blockln); + if(curr_window_line < 0) { + curr_window_line = 0; + if(end->next) + (top_of_win = end->next)->prev = begin->prev; + else + top_of_win = (lastline = begin->prev); + } + currln -= (currln - blockln); + } + } else { + begin = currline; + end = blockline; + } + if(ans[2] == 'y' && !(begin == end && currpnt != blockpnt)) { + if(begin->prev) + begin->prev->next = end->next; + else if(end->next) + top_of_win = firstline = end->next; + else { + currline = top_of_win = firstline = + lastline = alloc_line(); + currln = curr_window_line = edit_margin = 0; + } + + if(end->next) + (currline = end->next)->prev = begin->prev; + else if(begin->prev) { + currline = (lastline = begin->prev); + currln--; + if(curr_window_line > 0) + curr_window_line--; + } + } + + setuserfile(fp_tmpbuf, tmpfname); + if((fp = fopen(fp_tmpbuf, ans))) { + if(begin == end && currpnt != blockpnt) { + char buf[WRAPMARGIN + 2]; + + if(currpnt > blockpnt) { + strcpy(buf, begin->data + blockpnt); + buf[currpnt - blockpnt] = 0; + } else { + strcpy(buf, begin->data + currpnt); + buf[blockpnt - currpnt] = 0; + } + fputs(buf, fp); + } else { + for(p = begin; p != end; p = p->next) + fprintf(fp, "%s\n", p->data); + fprintf(fp, "%s\n", end->data); + } + fclose(fp); + } + + if(ans[2] == 'y') { + if(begin == end && currpnt != blockpnt) { + int min, max; + + if(currpnt > blockpnt) { + min = blockpnt; + max = currpnt; + } else { + min = currpnt; + max = blockpnt; + } + strcpy(begin->data + min, begin->data + max); + begin->len -= max - min; + currpnt = min; + } else { + for(p = begin; p != end; totaln--) + free((p = p->next)->prev); + free(end); + totaln--; + currpnt = 0; + } + } + } + blockln = -1; + redraw_everything = YEA; + } +} + +static void block_shift_left() { + textline_t *begin, *end, *p; + + if(currln >= blockln) { + begin = blockline; + end = currline; + } else { + begin = currline; + end = blockline; + } + p = begin; + while(1) { + if(p->len) { + strcpy(p->data, p->data + 1); + --p->len; + } + if(p == end) + break; + else + p = p->next; + } + if(currpnt > currline->len) + currpnt = currline->len; + redraw_everything = YEA; +} + +static void block_shift_right() { + textline_t *begin, *end, *p; + + if(currln >= blockln) { + begin = blockline; + end = currline; + } else { + begin = currline; + end = blockline; + } + p = begin; + while(1) { + if(p->len < WRAPMARGIN) { + int i = p->len + 1; + + while(i--) + p->data[i + 1] = p->data[i]; + p->data[0] = insert_character ? ' ' : insert_c; + ++p->len; + } + if(p == end) + break; + else + p = p->next; + } + if(currpnt > currline->len) + currpnt = currline->len; + redraw_everything = YEA; +} + +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() { + textline_t *begin, *end, *p; + + if(currln >= blockln) { + begin = blockline; + end = currline; + } else { + begin = currline; + end = blockline; + } + p = begin; + while(1) { + transform_to_color(p->data); + if(p == end) + break; + else + p = p->next; + } + block_del(1); +} + +/* ½s¿è³B²z¡G¥Dµ{¦¡¡BÁä½L³B²z */ +int vedit(char *fpath, int saveheader, int *islocal) { + FILE *fp1; + char last = 0, buf[200]; /* the last key you press */ + int ch, foo; + int lastindent = -1; + int last_margin; + int mode0 = currutmp->mode; + int destuid0 = currutmp->destuid; + unsigned int money=0; + unsigned short int interval=0; + time_t now=0,th; + + textline_t* firstline0 = firstline; + textline_t* lastline0 = lastline; + textline_t* currline0 = currline; + textline_t* blockline0 = blockline; + textline_t* top_of_win0 = top_of_win; + int local_article0 = local_article; + int currpnt0 = currpnt; + int currln0 = currln; + int totaln0 = totaln; + int curr_window_line0 = curr_window_line; + int insert_character0 = insert_character; + int my_ansimode0 = my_ansimode; + int edit_margin0 = edit_margin; + int blockln0 = blockln, count=0, tin=0; + + currutmp->mode = EDITING; + currutmp->destuid = currstat; + insert_character = redraw_everything = 1; + prevln = blockln = -1; + + line_dirty = currpnt = totaln = my_ansimode = 0; + currline = top_of_win = firstline = lastline = alloc_line(); + + if(*fpath) + read_file(fpath); + + if(*quote_file) { + do_quote(); + *quote_file = '\0'; + if(quote_file[79] == 'L') + local_article = 1; + } + + currline = firstline; + currpnt = currln = curr_window_line = edit_margin = last_margin = 0; + + while(1) { + if(redraw_everything || blockln >= 0) { + display_buffer(); + redraw_everything = NA; + } + if(my_ansimode) + ch = n2ansi(currpnt, currline); + else + ch = currpnt - edit_margin; + move(curr_window_line, ch); + if(!line_dirty && strcmp(line, currline->data)) + strcpy(line, currline->data); + ch = igetkey(); + /* jochang debug */ + if((interval = (unsigned short int)((th = currutmp->lastact) - now))) { + now = th; + if((char)ch != last) { + money++; + last = (char)ch; + } + } + if(interval && interval == tin) + count++; + else + { + count=0; + tin = interval; + } + /* ³sÄò240Óinterval¤@¼Ë , ¤À©ú¬O¦bÀÄ°] */ + if(count >= 240) { + sprintf(buf, "\033[1;33;46m%s\033[37m¦b\033[37;45m%s" + "\033[37mªO¹HªkÁÈ¿ú , %s\033[m", cuser.userid, + currboard,ctime(&now)); + log_file ("etc/illegal_money",buf); + money = 0 ; + post_violatelaw(cuser.userid, "Ptt ¨t²Îĵ¹î", "¹HªkÁÈ¿ú", "¦©°£¤£ªk©Ò±o"); + mail_violatelaw(cuser.userid, "Ptt ¨t²Îĵ¹î", "¹HªkÁÈ¿ú", "¦©°£¤£ªk©Ò±o"); +// demoney(10000); +// abort_bbs(0); + } + + if(raw_mode) + switch (ch) { + case Ctrl('S'): + case Ctrl('Q'): + case Ctrl('T'): + continue; + break; + } + if(ch < 0x100 && isprint2(ch)) { + insert_char(ch); + lastindent = -1; + line_dirty = 1; + } else { + if(ch == Ctrl('P') || ch == KEY_UP || ch == KEY_DOWN || + ch == Ctrl('N')) { + if(lastindent == -1) + lastindent = currpnt; + } else + 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; + case '-': + ch = Ctrl('_'); + break; + case 's': + ch = Ctrl('S'); + break; + } + + switch(ch) { + case Ctrl('X'): /* Save and exit */ + foo = write_file(fpath, saveheader, islocal); + if(foo != KEEP_EDITING) { + currutmp->mode = mode0; + currutmp->destuid = destuid0; + firstline = firstline0; + lastline = lastline0; + currline = currline0; + blockline = blockline0; + top_of_win = top_of_win0; + local_article = local_article0; + currpnt = currpnt0; + currln = currln0; + totaln = totaln0; + curr_window_line = curr_window_line0; + insert_character = insert_character0; + my_ansimode = my_ansimode0; + edit_margin = edit_margin0; + blockln = blockln0; + if(!foo) + return money; + else + return foo; + } + line_dirty = 1; + redraw_everything = YEA; + break; + case Ctrl('W'): + if(blockln >= 0) + block_del(2); + line_dirty = 1; + break; + case Ctrl('Q'): /* Quit without saving */ + ch = ask("µ²§ô¦ý¤£Àx¦s (Y/N)? [N]: "); + if(ch == 'y' || ch == 'Y') { + currutmp->mode = mode0; + currutmp->destuid = destuid0; + firstline = firstline0; + lastline = lastline0; + currline = currline0; + blockline = blockline0; + top_of_win = top_of_win0; + local_article = local_article0; + currpnt = currpnt0; + currln = currln0; + totaln = totaln0; + curr_window_line = curr_window_line0; + insert_character = insert_character0; + my_ansimode = my_ansimode0; + edit_margin = edit_margin0; + blockln = blockln0; + return -1; + } + line_dirty = 1; + redraw_everything = YEA; + break; + case Ctrl('C'): + ch = insert_character; + insert_character = redraw_everything = YEA; + if(!my_ansimode) + insert_string(reset_color); + else { + char ans[4]; + move(b_lines - 2, 55); + outs("\033[1;33;40mB\033[41mR\033[42mG\033[43mY\033[44mL" + "\033[45mP\033[46mC\033[47mW\033[m"); + if(getdata(b_lines - 1, 0, + "½Ð¿é¤J «G«×/«e´º/I´º[¥¿±`¥Õ¦r¶Â©³][0wb]¡G", + ans, 4, LCECHO)) { + char t[] = "BRGYLPCW"; + char color[15]; + char *tmp, *apos = ans; + int fg, bg; + + strcpy(color, "\033["); + if(isdigit(*apos)) { + sprintf(color, "%s%c", color, *(apos++)); + if(*apos) + sprintf(color, "%s;", 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); + } + sprintf(color, "%sm", color); + insert_string(color); + } else + insert_string(reset_color); + } + insert_character = ch; + line_dirty = 1; + break; + case KEY_ESC: + line_dirty = 0; + switch(KEY_ESC_arg) { + case 'U': + t_users(); + redraw_everything = YEA; + line_dirty = 1; + break; + case 'i': + t_idle(); + redraw_everything = YEA; + line_dirty = 1; + break; + case 'n': + search_str(1); + break; + case 'p': + search_str(-1); + break; + case 'L': + case 'J': + goto_line(0); + 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'); + redraw_everything = YEA; + break; + case 'l': /* block delete */ + case ' ': + block_del(0); + line_dirty = 1; + break; + case 'u': + if(blockln >= 0) + block_del(1); + line_dirty = 1; + break; + case 'c': + if(blockln >= 0) + block_del(3); + line_dirty = 1; + break; + case 'y': + undelete_line(); + break; + case 'R': + raw_mode ^= 1; + line_dirty = 1; + break; + case 'I': + indent_mode ^= 1; + line_dirty = 1; + break; + case 'j': + if(blockln >= 0) + block_shift_left(); + else if(currline->len) { + int currpnt0 = currpnt; + currpnt = 0; + delete_char(); + currpnt = (currpnt0 <= currline->len) ? currpnt0 : + currpnt0 - 1; + if(my_ansimode) + currpnt = ansi2n(n2ansi(currpnt, currline), + currline); + } + line_dirty = 1; + break; + case 'k': + if(blockln >= 0) + block_shift_right(); + else { + int currpnt0 = currpnt; + + currpnt = 0; + insert_char(' '); + currpnt = currpnt0; + } + line_dirty = 1; + break; + case 'f': + while(currpnt < currline->len && + isalnum(currline->data[++currpnt])); + while(currpnt < currline->len && + isspace(currline->data[++currpnt])); + line_dirty = 1; + break; + case 'b': + while(currpnt && isalnum(currline->data[--currpnt])); + while(currpnt && isspace(currline->data[--currpnt])); + line_dirty = 1; + break; + case 'd': + while(currpnt < currline->len) { + delete_char(); + if(!isalnum(currline->data[currpnt])) + break; + } + while(currpnt < currline->len) { + delete_char(); + if(!isspace(currline->data[currpnt])) + break; + } + line_dirty = 1; + break; + default: + line_dirty = 1; + } + break; + case Ctrl('_'): + if(strcmp(line, currline->data)) { + char buf[WRAPMARGIN]; + + strcpy(buf, currline->data); + strcpy(currline->data, line); + strcpy(line, buf); + currline->len = strlen(currline->data); + currpnt = 0; + line_dirty = 1; + } + break; + case Ctrl('S'): + search_str(0); + break; + case Ctrl('U'): + insert_char('\033'); + line_dirty = 1; + break; + case Ctrl('V'): /* Toggle ANSI color */ + my_ansimode ^= 1; + if(my_ansimode && blockln >= 0) + block_color(); + clear(); + redraw_everything = YEA; + line_dirty = 1; + break; + case Ctrl('I'): + do { + insert_char(' '); + } while(currpnt & 0x7); + line_dirty = 1; + break; + case '\r': + case '\n': + split(currline, currpnt); + line_dirty = 0; + break; + case Ctrl('G'): + { + unsigned int currstat0 = currstat; + setutmpmode(EDITEXP); + a_menu("½s¿è»²§U¾¹", "etc/editexp", + (HAS_PERM(PERM_SYSOP) ? SYSOP : NOBODY)); + currstat = currstat0; + } + if(trans_buffer[0]) { + if((fp1 = fopen(trans_buffer, "r"))) { + int indent_mode0 = indent_mode; + + indent_mode = 0; + prevln = currln; + prevpnt = currpnt; + while(fgets(line, WRAPMARGIN + 2, fp1)) { + if(!strncmp(line,"§@ªÌ:",5) || + !strncmp(line,"¼ÐÃD:",5) || + !strncmp(line,"®É¶¡:",5)) + continue; + insert_string(line); + } + fclose(fp1); + indent_mode = indent_mode0; + while(curr_window_line >= b_lines) { + curr_window_line--; + top_of_win = top_of_win->next; + } + } + } + redraw_everything = YEA; + line_dirty = 1; + break; + case Ctrl('Z'): /* Help */ + more("etc/ve.hlp",YEA); + redraw_everything = YEA; + line_dirty = 1; + break; + case Ctrl('L'): + clear(); + redraw_everything = YEA; + line_dirty = 1; + break; + case KEY_LEFT: + if(currpnt) { + if(my_ansimode) + currpnt = n2ansi(currpnt, currline); + currpnt--; + if(my_ansimode) + currpnt = ansi2n(currpnt, currline); + line_dirty = 1; + } else if(currline->prev) { + curr_window_line--; + currln--; + currline = currline->prev; + currpnt = currline->len; + line_dirty = 0; + } + break; + case KEY_RIGHT: + if(currline->len != currpnt) { + if(my_ansimode) + currpnt = n2ansi(currpnt, currline); + currpnt++; + if(my_ansimode) + currpnt = ansi2n(currpnt, currline); + line_dirty = 1; + } else if(currline->next) { + currpnt = 0; + curr_window_line++; + currln++; + currline = currline->next; + line_dirty = 0; + } + break; + case KEY_UP: + case Ctrl('P'): + if(currline->prev) { + if(my_ansimode) + ch = n2ansi(currpnt,currline); + curr_window_line--; + currln--; + currline = currline->prev; + if(my_ansimode) + currpnt = ansi2n(ch , currline); + else + currpnt = (currline->len > lastindent) ? lastindent : + currline->len; + line_dirty = 0; + } + break; + case KEY_DOWN: + case Ctrl('N'): + if(currline->next) { + if(my_ansimode) + ch = n2ansi(currpnt,currline); + currline = currline->next; + curr_window_line++; + currln++; + if(my_ansimode) + currpnt = ansi2n(ch , currline); + else + currpnt = (currline->len > lastindent) ? lastindent : + currline->len; + line_dirty = 0; + } + break; + case Ctrl('B'): + case KEY_PGUP: + redraw_everything = currln; + top_of_win = back_line(top_of_win, 22); + currln = redraw_everything; + currline = back_line(currline, 22); + curr_window_line = getlineno(); + if(currpnt > currline->len) + currpnt = currline->len; + redraw_everything = YEA; + line_dirty = 0; + break; + case KEY_PGDN: + case Ctrl('F'): + redraw_everything = currln; + top_of_win = forward_line(top_of_win, 22); + currln = redraw_everything; + currline = forward_line(currline, 22); + curr_window_line = getlineno(); + if(currpnt > currline->len) + currpnt = currline->len; + redraw_everything = YEA; + line_dirty = 0; + break; + case KEY_END: + case Ctrl('E'): + currpnt = currline->len; + line_dirty = 1; + break; + case Ctrl(']'): /* start of file */ + prevln = currln; + prevpnt = currpnt; + currline = top_of_win = firstline; + currpnt = currln = curr_window_line = 0; + redraw_everything = YEA; + line_dirty = 0; + break; + case Ctrl('T'): /* tail of file */ + prevln = currln; + prevpnt = currpnt; + top_of_win = back_line(lastline, 23); + currline = lastline; + curr_window_line = getlineno(); + currln = totaln; + redraw_everything = YEA; + currpnt = 0; + line_dirty = 0; + break; + case KEY_HOME: + case Ctrl('A'): + currpnt = 0; + line_dirty = 1; + break; + case KEY_INS: /* Toggle insert/overwrite */ + case Ctrl('O'): + if(blockln >= 0 && insert_character) { + char ans[4]; + + getdata(b_lines - 1, 0, + "°Ï¶ô·L½Õ¥k²¾´¡¤J¦r¤¸(¹w³]¬°ªÅ¥Õ¦r¤¸)", + ans, 4, LCECHO); + insert_c = (*ans) ? *ans : ' '; + } + insert_character ^= 1; + line_dirty = 1; + break; + case Ctrl('H'): + case '\177': /* backspace */ + line_dirty = 1; + if(my_ansimode) { + my_ansimode = 0; + clear(); + redraw_everything = YEA; + } else { + if(currpnt == 0) { + textline_t *p; + + if(!currline->prev) + break; + line_dirty = 0; + curr_window_line--; + currln--; + currline = currline->prev; + currpnt = currline->len; + redraw_everything = YEA; + if(*killsp(currline->next->data) == '\0') { + delete_line(currline->next); + break; + } + p = currline; + while(!join(p)) { + p = p->next; + if(p == NULL) { + indigestion(2); + abort_bbs(0); + } + } + break; + } + currpnt--; + delete_char(); + } + break; + case Ctrl('D'): + case KEY_DEL: /* delete current character */ + line_dirty = 1; + if(currline->len == currpnt) { + textline_t *p = currline; + + while(!join(p)) { + p = p->next; + if(p == NULL) { + indigestion(2); + abort_bbs(0); + } + } + line_dirty = 0; + redraw_everything = YEA; + } else { + delete_char(); + if(my_ansimode) + currpnt = ansi2n(n2ansi(currpnt, currline), currline); + } + break; + case Ctrl('Y'): /* delete current line */ + currline->len = currpnt = 0; + case Ctrl('K'): /* delete to end of line */ + if(currline->len == 0) { + textline_t *p = currline->next; + if(!p) { + p = currline->prev; + if(!p) + break; + if(curr_window_line > 0) { + curr_window_line--; + currln--; + } + } + if(currline == top_of_win) + top_of_win = p; + delete_line(currline); + currline = p; + redraw_everything = YEA; + line_dirty = 0; + break; + } + if(currline->len == currpnt) { + textline_t *p = currline; + + while(!join(p)) { + p = p->next; + if(p == NULL) { + indigestion(2); + abort_bbs(0); + } + } + redraw_everything = YEA; + line_dirty = 0; + break; + } + currline->len = currpnt; + currline->data[currpnt] = '\0'; + line_dirty = 1; + break; + } + if(currln < 0) + currln = 0; + if(curr_window_line < 0) { + curr_window_line = 0; + if(!top_of_win->prev) + indigestion(6); + else { + top_of_win = top_of_win->prev; + rscroll(); + } + } + if(curr_window_line == b_lines) { + curr_window_line = t_lines - 2; + if(!top_of_win->next) + indigestion(7); + else { + top_of_win = top_of_win->next; + move(b_lines, 0); + clrtoeol(); + scroll(); + } + } + } + edit_margin = currpnt < SCR_WIDTH - 1 ? 0 : currpnt / 72 * 72; + + if(!redraw_everything) { + if(edit_margin != last_margin) { + last_margin = edit_margin; + redraw_everything = YEA; + } else { + move(curr_window_line, 0); + clrtoeol(); + if(my_ansimode) + outs(currline->data); + else + edit_outs(&currline->data[edit_margin]); + edit_msg(); + } + } + } +} diff --git a/mbbsd/friend.c b/mbbsd/friend.c new file mode 100644 index 00000000..3d2167ae --- /dev/null +++ b/mbbsd/friend.c @@ -0,0 +1,509 @@ +/* $Id: friend.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/file.h> +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "perm.h" +#include "proto.h" + +extern char currboard[]; /* name of currently selected board */ +extern char *fn_overrides; +extern userinfo_t *currutmp; +extern char *fn_reject; +extern int usernum; +extern char *str_space; +extern char *msg_uid; + +/* ------------------------------------- */ +/* ¯S§O¦W³æ */ +/* ------------------------------------- */ + +/* Ptt ¨ä¥L¯S§O¦W³æªºÀɦW */ +static char special_list[] = "list.0"; +static char special_des[] = "ldes.0"; + +/* ¯S§O¦W³æªº¤W */ +static unsigned int friend_max[8] = { + MAX_FRIEND, + MAX_REJECT, + MAX_LOGIN_INFO, + MAX_POST_INFO, + MAX_NAMELIST, + MAX_NAMELIST, + MAX_NAMELIST, + MAX_NAMELIST +}; +/* ÁöµM¦n¤Í¸òÃa¤H¦W³æ³£¬O * 2 ¦ý¬O¤@¦¸³Ì¦hload¨ìshm¥u¯à¦³128 */ + +/* Ptt ¦UºØ¯S§O¦W³æªºÀɦW */ +char *friend_file[8] = { + FN_OVERRIDES, + FN_REJECT, + "alohaed", + "postlist", + "", + FN_CANVOTE, + FN_WATER, + FN_VISABLE +}; + +/* Ptt ¦UºØ¯S§O¦W³æªº¸Éz */ +static char *friend_desc[8] = { + "¤Í½Ë´yz¡G", + "´c§Î´cª¬¡G", + "", + "", + "´yz¤@¤U¡G", + "§ë²¼ªÌ´yz¡G", + "´c§Î´cª¬¡G", + "¬ÝªO¦n¤Í´yz" +}; + +/* Ptt ¦UºØ¯S§O¦W³æªº¤¤¤å±Ôz */ +static char *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³æ" +}; + +static 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]); +} + +static int friend_count(char *fname) { + FILE *fp; + int count = 0; + char buf[200]; + +#if 0 + if ((fp = fopen(fname, "r"))) + while (fgets(buf, 200, fp)) + count++; +#endif + +/*rocker.011018: §Ñ°OÃöÀɤF... */ + if ((fp = fopen(fname, "r"))) + { + while (fgets(buf, 200, fp)) count++; + fclose (fp); + } + + return count; +} + +void friend_add(char *uident, int type) { + char fpath[80]; + + setfriendfile(fpath, type); + if (friend_count(fpath) > friend_max[type]) + return; + + if ((uident[0] > ' ') && !belong(fpath, uident)) + { + FILE *fp; + char buf[40] = ""; + char t_uident[IDLEN + 1]; + + /* Thor: avoid uident run away when get data */ + strcpy(t_uident, uident); + + if (type != FRIEND_ALOHA && type != FRIEND_POST) + getdata(2, 0, friend_desc[type], buf, 40, DOECHO); + + if ((fp = fopen(fpath, "a"))) + { + flock(fileno(fp), LOCK_EX); + fprintf(fp, "%-13s%s\n", t_uident, buf); + flock(fileno(fp), LOCK_UN); + fclose(fp); + } + } +} + +static void friend_special() { + char genbuf[70], i, fname[70]; + + friend_file[FRIEND_SPECIAL] = special_list; + for (i = 0; i <= 9; i++) + { + sprintf(genbuf, " (\033[36m%d\033[m) .. ", i); + special_des[5] = i + '0'; + setuserfile(fname, special_des); + if (dashf(fname)) + { + /* no NULL check?? */ + FILE *fp = fopen(fname, "r"); + + fgets(genbuf + 15, 40, fp); + genbuf[47] = 0; + } + 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; + + setfriendfile(fpath, type); + + do + { + move(2, 0); + clrtobot(); + outs("n¤Þ¤Jþ¤@Ó¦W³æ?\n"); + for (i = 0, j = 0; i <= 7; i++) + { + if (i == type) + continue; + j++; + if (i <= 4) + sprintf(buf, " (%d) %-s\n", j, friend_list[(int) i]); + else + sprintf(buf, " (%d) %s ª©ªº %s\n", j, currboard, + friend_list[(int) i]); + outs(buf); + } + outs(" (S) ¿ï¾Ü¨ä¥L¬ÝªOªº¯S§O¦W³æ"); + getdata(11, 0, "½Ð¿ï¾Ü ©Î ª½±µ[Enter] ©ñ±ó:", buf, 3, LCECHO); + if (!buf[0]) + return; + if (buf[0] == 's') + Select(); + } + while (buf[0] < '1' || buf[0] > '9'); + + j = buf[0] - '1'; + if (j >= type) + j++; + if (j == FRIEND_SPECIAL) + friend_special(); + + setfriendfile(sfile, j); + + fp = fopen(sfile, "r"); + while (fgets(buf, 80, fp) && count <= friend_max[type]) + { + char the_id[15]; + + sscanf(buf, "%s", the_id); + if (!belong(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); +} + +void friend_delete(char *uident, int type) { + FILE *fp, *nfp; + char fn[80], fnnew[80]; + char genbuf[200]; + + setfriendfile(fn, type); + + sprintf(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); + fclose(fp); + fclose(nfp); + Rename(fnnew, fn); + } +} + +static void friend_editdesc(char *uident, int type) { + FILE *fp, *nfp; + char fnnew[200], genbuf[200], fn[200]; + setfriendfile(fn, type); + sprintf(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, "קï´yz¡G", buf, 40, DOECHO); + fprintf(nfp, "%-13s%s\n", uident, buf); + } + } + fclose(fp); + fclose(nfp); + Rename(fnnew, fn); + } +} + +void friend_load() { + FILE *fp; + int myfriends[MAX_FRIEND]; + int myrejects[MAX_REJECT]; + int friendcount, rejectedcount; + char genbuf[200]; + + memset(myfriends, 0, sizeof(myfriends)); + friendcount = 0; + setuserfile(genbuf, fn_overrides); + if ((fp = fopen(genbuf, "r"))) + { + int unum; + + while (fgets(genbuf, STRLEN, fp) && friendcount < MAX_FRIEND - 1) + if (strtok(genbuf, str_space)) + if ((unum = searchuser(genbuf))) + myfriends[friendcount++] = unum; + fclose(fp); + } + memcpy(currutmp->friend, myfriends, sizeof(myfriends)); + + memset(myrejects, 0, sizeof(myrejects)); + rejectedcount = 0; + setuserfile(genbuf, fn_reject); + if ((fp = fopen(genbuf, "r"))) + { + int unum; + + while (fgets(genbuf, STRLEN, fp) && rejectedcount < MAX_REJECT - 1) + if (strtok(genbuf, str_space)) + if ((unum = searchuser(genbuf))) + myrejects[rejectedcount++] = unum; + fclose(fp); + } + memcpy(currutmp->reject, myrejects, sizeof(myrejects)); + if(currutmp->friendtotal) logout_friend_online(); + login_friend_online(); +} + +extern userec_t cuser; + +static void friend_water(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, "%s", userid); + if((tuid = searchuser(userid)) && tuid != usernum && + (uentp = (userinfo_t *) search_ulist(tuid)) && + isvisible_uid(tuid)) + my_write(uentp->pid, message, uentp->userid, 1); + } + fclose(fp); +} + +void friend_edit(int type) { + char fpath[80], line[80], uident[20]; + 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, "/bin/cp %s %s.old", fpath, fpath); + system(genbuf); + } + } + + dirty = 0; + while (1) + { + stand_title(friend_list[type]); + move(0, 40); + sprintf(line, "(¦W³æ¤W:%dÓ¤H)", friend_max[type]); + outs(line); + count = 0; + CreateNameList(); + + if ((fp = fopen(fpath, "r"))) + { + move(3, 0); + column = 0; + while (fgets(genbuf, STRLEN, fp)) + { + if (genbuf[0] <= ' ') + continue; + strtok(genbuf, str_space); + 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)µ²§ô¡H[Q]" : + "(A)¼W¥[ (P)¤Þ¤J¨ä¥L¦W³æ (Q)µ²§ô¡H[Q]"), + uident, 3, LCECHO); + if (*uident == 'a') + { + move(1, 0); + usercomplete(msg_uid, uident); + if (uident[0] && searchuser(uident) && !InNameList(uident)) + { + friend_add(uident, type); + dirty = 1; + } + } + else if (*uident == 'p') + { + friend_append(type, count); + dirty = 1; + } + else if (*uident == 'e' && count) + { + move(1, 0); + namecomplete(msg_uid, uident); + if (uident[0] && InNameList(uident)) + { + friend_editdesc(uident, type); + } + } + else if (*uident == 'd' && count) + { + move(1, 0); + namecomplete(msg_uid, uident); + if (uident[0] && InNameList(uident)) + { + friend_delete(uident, type); + dirty = 1; + } + } + else if (*uident == 'l' && count) + more(fpath, YEA); + else if (*uident == 'k' && count) + { + getdata(2, 0, "¾ã¥÷¦W³æ±N·|³Q§R°£,±z½T©w¶Ü (a/N)?", uident, 3, + LCECHO); + if (*uident == 'a') + unlink(fpath); + dirty = 1; + } + else if (*uident == 'w' && count) + { + if (!getdata(0, 0, "¸sÅé¤ô²y:", uident, 60, DOECHO)) + continue; + if (getdata(0, 0, "½T©w¥á¥X¸sÅé¤ô²y? [Y]", line, 4, LCECHO) && + *line == 'n') + continue; + friend_water(uident, type); + } + else + break; + } + if (dirty) + { + move(2, 0); + outs("§ó·s¸ê®Æ¤¤..½ÐµyÔ....."); + refresh(); + if (type == FRIEND_ALOHA || type == FRIEND_POST) + { + sprintf(genbuf, "%s.old", fpath); + if ((fp = fopen(genbuf, "r"))) + { + while (fgets(line, 80, fp)) + { + sscanf(line, "%s", uident); + sethomefile(genbuf, uident, + type == FRIEND_ALOHA ? "aloha" : "postnotify"); + del_distinct(genbuf, cuser.userid); + } + fclose(fp); + } + sprintf(genbuf, "%s", fpath); + if ((fp = fopen(genbuf, "r"))) + { + while (fgets(line, 80, fp)) + { + sscanf(line, "%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"))) + { + fprintf(fp, "%s", genbuf); + fclose(fp); + } + } + friend_load(); + } +} + +int t_override() { + friend_edit(FRIEND_OVERRIDE); + return 0; +} + +int t_reject() { + friend_edit(FRIEND_REJECT); + return 0; +} diff --git a/mbbsd/gamble.c b/mbbsd/gamble.c new file mode 100644 index 00000000..23867450 --- /dev/null +++ b/mbbsd/gamble.c @@ -0,0 +1,361 @@ +/* $Id: gamble.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <time.h> +#include <string.h> +#include <sys/types.h> +#include <stdlib.h> +#include <unistd.h> +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "modes.h" +#include "proto.h" +extern int usernum; + +#ifndef _BBS_UTIL_C_ +extern userec_t cuser; +extern int b_lines; + +#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 char betname[MAX_ITEM][MAX_ITEM_LEN]; +static int currbid; + +int post_msg(char* bname, char* title, char *msg, char* author) +{ + FILE *fp; + int bid; + fileheader_t fhdr; + time_t now = time(0); + char genbuf[256]; + + /* ¦b bname ª©µoªí·s¤å³¹ */ + sprintf(genbuf, "boards/%s", bname); + stampfile(genbuf, &fhdr); + fp = fopen(genbuf,"w"); + + if(!fp) + return -1; + + fprintf(fp, "§@ªÌ: %s ¬ÝªO: %s\n¼ÐÃD: %s \n",author,bname,title); + fprintf(fp, "®É¶¡: %s\n", ctime(&now)); + + /* ¤å³¹ªº¤º®e */ + fprintf(fp, "%s", msg); + fclose(fp); + + /* ±NÀÉ®×¥[¤J¦Cªí */ + strcpy(fhdr.title, title); + strcpy(fhdr.owner, author); + setbdir(genbuf,bname); + if(append_record(genbuf, &fhdr, sizeof(fhdr))!=-1) + if((bid = getbnum(bname)) > 0) + setbtotal(bid); + return 0; +} + +int post_file(char* bname, char* title, char *filename, 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); + fread(msg,1,size,fp); + size= post_msg(bname, title, msg, author); + fclose(fp); + free(msg); + return size; +} + + +static int load_ticket_record(char *direct, int ticket[]) +{ + char buf[256]; + int i, total=0; + FILE *fp; + sprintf(buf,"%s/"FN_TICKET_RECORD,direct); + if(!(fp=fopen(buf,"r"))) return 0; + for(i=0;i<MAX_ITEM && fscanf(fp, "%9d ",&ticket[i]); i++) + total=total+ticket[i]; + fclose(fp); + return total; +} + +static int show_ticket_data(char *direct, int *price, 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]; + + clear(); + if (bh) + { + sprintf(genbuf,"%s ½ä½L", bh->brdname); + showtitle(genbuf, BBSNAME); + } + else + showtitle("Ptt½ä½L", BBSNAME); + move(2, 0); + sprintf(genbuf, "%s/"FN_TICKET_ITEMS, direct); + if(!(fp = fopen(genbuf,"r"))) + { + prints("\n¥Ø«e¨Ã¨S¦³Á|¿ì½ä½L\n"); + sprintf(genbuf, "%s/"FN_TICKET_OUTCOME, direct); + if(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++) + strtok(betname[count],"\r\n"); + fclose(fp); + + prints("\033[32m¯¸³W:\033[m 1.¥iÁʶR¥H¤U¤£¦PÃþ«¬ªº±m²¼¡C¨C±inªá \033[32m%d\033[m ¤¸¡C\n" + " 2.%s\n" + " 3.¶}¼ú®É¥u¦³¤@ºØ±m²¼¤¤¼ú, ¦³ÁʶR¸Ó±m²¼ªÌ, «h¥i¨ÌÁʶRªº±i¼Æ§¡¤À" + "Á`½äª÷¡C\n" + " 4.¨Cµ§¼úª÷¥Ñ¨t²Î©â¨ú 5% ¤§µ|ª÷%s¡C\n\n" + "\033[32m%s:\033[m", *price, + bh?"¦¹½ä½L¥Ñª©¥Dt³dÁ|¿ì¨Ã¥B¨M©w¶}¼ú®É¶¡µ²ªG, ¯¸ªø¤£ºÞ, Ä@½äªA¿é¡C": + "¨t²Î¨C¤Ñ 2:00 11:00 16:00 21:00 ¶}¼ú¡C", + bh?", ¨ä¤¤ 2% ¤Àµ¹¶}¼úª©¥D":"", + bh?"ª©¥D¦Ûq³W«h¤Î»¡©ú":"«e´X¦¸¶}¼úµ²ªG"); + + + sprintf(genbuf, "%s/"FN_TICKET, direct); + if(!dashf(genbuf)) + { + sprintf(genbuf, "%s/"FN_TICKET_END, direct); + end=1; + } + show_file(genbuf, 8, -1, NO_RELOAD); + move(15,0); + prints("\033[1;32m¥Ø«e¤Uª`ª¬ªp:\033[m\n"); + + total=load_ticket_record(direct, ticket); + + prints("\033[33m"); + for(i = 0 ; i<count; i++) + { + prints("%d.%-8s: %-7d", i+1, betname[i], ticket[i]); + if(i==3) prints("\n"); + } + prints("\033[m\n\033[42m ¤Uª`Á`ª÷ÃB:\033[31m %d ¤¸ \033[m",total*(*price)); + if(end) + { + prints("\n½ä½L¤w¸g°±¤î¤Uª`\n"); + return -count; + } + return count; +} + +static void append_ticket_record(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]; + sprintf(genbuf, "%s/"FN_TICKET_USER, direct); + + if((fp = fopen(genbuf,"a"))) { + fprintf(fp, "%s %d %d\n", cuser.userid, ch, n); + fclose(fp); + } + load_ticket_record(direct, ticket); + ticket[ch] += n; + sprintf(genbuf, "%s/" FN_TICKET_RECORD, direct); + if((fp = fopen(genbuf,"w"))) { + for(i=0; i<count; i++) + fprintf(fp,"%d ", ticket[i]); + fclose(fp); + } +} + +#define lockreturn0(unmode, state) if(lockutmpmode(unmode, state)) return 0 +int ticket(int bid) +{ + int ch, n, price, count, end=0; + char path[128],fn_ticket[128]; + boardheader_t *bh=NULL; + + 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(path, &price, bh); + if(count<=0) + { + pressanykey(); + break; + } + move(20, 0); + reload_money(); + prints("\033[44m¿ú: %-10d \033[m\n\033[1m½Ð¿ï¾ÜnÁʶRªººØÃþ(1~%d)" + "[Q:Â÷¶}]\033[m:", cuser.money,count); + ch = igetch(); + /*-- + Tim011127 + ¬°¤F±±¨îCS°ÝÃD ¦ý¬O³oÃäÁÙ¤£¯à§¹¥þ¸Ñ¨M³o°ÝÃD, + Yuser³q¹LÀˬd¤U¥h, è¦nª©¥D¶}¼ú, ÁÙ¬O·|³y¦¨userªº³o¦¸¬ö¿ý + «Ü¦³¥i¯à¶]¨ì¤U¦¸½ä½Lªº¬ö¿ý¥h, ¤]«Ü¦³¥i¯à³Qª©¥D·s¶}½ä½L®É¬~±¼ + ¤£¹L³oÃä¦Ü¤Ö¥i¥H°µ¨ìªº¬O, ³»¦h¥u·|¦³¤@µ§¸ê®Æ¬O¿ùªº + --*/ + if(bid && !dashf(fn_ticket)) + { + move(b_lines-1,0); + prints("«z!! @£«®º...ª©¥D¤w¸g°±¤î¤Uª`¤F ¤£¯à½äÂP"); + pressanykey(); + break; + } + + if(ch=='q' || ch == 'Q') + break; + ch-='1'; + if(end || ch >= count || ch < 0) + continue; + n=0; + ch_buyitem(price, "etc/buyticket", &n); + if(n > 0) + append_ticket_record(path,ch,n,count); + } + unlockutmpmode(); + return 0; +} + +int openticket(int bid) { + char path[128],buf[256],outcome[128]; + int i, money=0, count, bet, price, total = 0, ticket[8]={0,0,0,0,0,0,0,0}; + boardheader_t *bh=getbcache(bid); + time_t now = time(NULL); + FILE *fp, *fp1; + + setbpath(path, bh->brdname); + count=-show_ticket_data(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, "\033[1m¿ï¾Ü¤¤¼úªº¸¹½X(0:¨ú®ø)\033[m:", buf, 3, LCECHO); + bet=atoi(buf); + move(0,0); + clrtoeol(); + } while(bet<0 || bet>count); + if(bet==0) + {unlockutmpmode(); return 0;} + getdata(21, 0, "\033[1m¦A¦¸½T»{¤¤¼úªº¸¹½X\033[m:", buf, 3, LCECHO); + }while(bet!=atoi(buf)); + + bet -= 1; //Âন¯x°}ªºindex + + total=load_ticket_record(path, ticket); + setbfile(buf,bh->brdname,FN_TICKET_END); + if(!(fp1 = fopen(buf,"r"))) + { + unlockutmpmode(); + return 0; + } + // ÁÙ¨S¶}§¹¼ú¤£¯à½ä³Õ ¥unmv¤@¶µ´N¦n + 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; + setbfile(outcome,bh->brdname,FN_TICKET_OUTCOME); + if((fp = fopen(outcome, "w"))) + { + fprintf(fp,"½ä½L»¡©ú\n"); + while(fgets(buf,256,fp1)) + { + buf[255]=0; + fprintf(fp,"%s",buf); + } + fprintf(fp,"¤Uª`±¡ªp\n"); + + fprintf(fp, "\033[33m"); + 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, "\033[m\n"); + + 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 ªT¢Þ¹ô \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", + Cdatelite(&now), betname[bet], total*price, money, + total? (float)ticket[bet] / total:0); + + fclose(fp); + } + fclose(fp1); + + setbfile(buf, bh->brdname, FN_TICKET_END); + unlink(buf); +/* + if(fork()) + { + more(outcome,YEA); + unlockutmpmode(); + return 0; + } +*/ + sprintf(buf, "[¤½§i] %s ½ä½L¶}¼ú", bh->brdname); + post_file(bh->brdname, buf, outcome, "[½ä¯«]"); + post_file("Record", buf+7, outcome, "[°¨¸ô±´¤l]"); + /* + ¥H¤U¬Oµ¹¿ú°Ê§@ + */ + setbfile(buf, bh->brdname, FN_TICKET_USER); + if (ticket[bet] && (fp = fopen(buf, "r"))) + { + int mybet, uid; + char userid[IDLEN]; + + while (fscanf(fp, "%s %d %d\n", userid, &mybet, &i) != EOF) + { + if (mybet == bet) + { + printf("®¥³ß %-15s¶R¤F%9d ±i %s, Àò±o %d ªT¢Þ¹ô\n" + ,userid, i, betname[mybet], money * i); + if((uid=getuser(userid))==0) continue; + deumoney(uid, money * i); + sprintf(buf, "%s ¤¤¼ú«¨! $ %d", bh->brdname, money * i); + mail_id(userid, buf, outcome, "Ptt½ä³õ"); + } + } + } + setbfile(buf, bh->brdname, FN_TICKET_RECORD); + unlink(buf); + setbfile(buf, bh->brdname, FN_TICKET_USER); + unlink(buf); + return 0; +} + +int ticket_main() { + ticket(0); + return 0; +} +#endif diff --git a/mbbsd/gomo.c b/mbbsd/gomo.c new file mode 100644 index 00000000..06062ce4 --- /dev/null +++ b/mbbsd/gomo.c @@ -0,0 +1,417 @@ +/* $Id: gomo.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <time.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <string.h> +#include "config.h" +#include "pttstruct.h" +#include "gomo.h" +#include "common.h" +#include "modes.h" +#include "proto.h" + +extern int usernum; +extern userinfo_t *currutmp; + +char ku[BRDSIZ][BRDSIZ]; +static char *chess[] = { "¡´", "¡³" }; +static int tick, lastcount, mylasttick, hislasttick; + +unsigned char *pat, *adv; + +typedef struct { + char x; + char y; +} Horder_t; + +static Horder_t *v, pool[225]; + +static void HO_init() { + memset(pool, 0, sizeof(pool)); + v = pool; + pat = pat_gomoku; + adv = adv_gomoku; + memset(ku, 0, sizeof(ku)); +} + +static void HO_add(Horder_t *mv) { + *v++ = *mv; +} + +static void HO_undo(Horder_t *mv) { + char *str = "¢z¢s¢{¢u¢q¢t¢|¢r¢}"; + int n1, n2, loc; + + *mv = *(--v); + ku[(int)mv->x][(int)mv->y] = BBLANK; + BGOTO(mv->x, mv->y); + n1 = (mv->x == 0) ? 0 : (mv->x == 14) ? 2 : 1; + n2 = (mv->y == 14)? 0 : (mv->y == 0) ? 2 : 1; + loc= 2 * ( n2 * 3 + n1); + prints("%.2s", str + loc); +} + +extern userec_t cuser; + +static void HO_log(char *user) { + int i; + FILE *log; + char buf[80]; + char buf1[80]; + char title[80]; + Horder_t *ptr = pool; + extern screenline_t *big_picture; + fileheader_t mymail; + + sprintf(buf, "home/%c/%s/F.%d", cuser.userid[0], cuser.userid, + rand() & 65535); + log = fopen(buf, "w"); + + for(i = 1; i < 17; i++) + fprintf(log, "%.*s\n", big_picture[i].len, big_picture[i].data); + + i = 0; + do { + fprintf(log, "[%2d]%s ==> %c%d%c", i + 1, chess[i % 2], + 'A' + ptr->x, ptr->y + 1, (i % 2) ? '\n' : '\t'); + i++; + } while( ++ptr < v); + fclose(log); + + sethomepath(buf1, cuser.userid); + stampfile(buf1, &mymail); + + mymail.savemode = 'H'; /* hold-mail flag */ + mymail.filemode = FILE_READ; + strcpy(mymail.owner, "[³Æ.§Ñ.¿ý]"); + sprintf(mymail.title, "\033[37;41m´ÑÃÐ\033[m %s VS %s", + cuser.userid, user); + sethomedir(title, cuser.userid); + Rename(buf, buf1); + append_record(title, &mymail, sizeof(mymail)); + + unlink(buf); +} + +static int countgomo() { + Horder_t *ptr; + int i; + + ptr = pool; + i = 0; + do { + i++; + } while(++ptr < v); + return i; +} + +static int chkmv(Horder_t *mv, int color, int limit) { + char *xtype[] = {"\033[1;31m¸õ¤T\033[m", "\033[1;31m¬¡¤T\033[m", + "\033[1;31m¦º¥|\033[m", "\033[1;31m¸õ¥|\033[m", + "\033[1;31m¬¡¥|\033[m", "\033[1;31m¥|¤T\033[m", + "\033[1;31mÂù¤T\033[m", "\033[1;31mÂù¥|\033[m", + "\033[1;31mÂù¥|\033[m", "\033[1;31m³s¤»\033[m", + "\033[1;31m³s¤\033[m"}; + int rule = getstyle(mv->x, mv->y, color, limit); + if(rule > 1 && rule < 13) { + move(15, 40); + outs(xtype[rule - 2]); + bell(); + } + return chkwin(rule, limit); +} + +static int gomo_key(int fd, int ch, Horder_t *mv) { + if( ch >= 'a' && ch <= 'o') { + char pbuf[4], vx, vy; + + *pbuf = ch; + if(fd) + add_io(0, 0); + oldgetdata(17, 0, "ª½±µ«ü©w¦ì¸m :", pbuf, 4, DOECHO); + if(fd) + add_io(fd, 0); + vx = pbuf[0] - 'a'; + vy = atoi(pbuf + 1) - 1; + if(vx >= 0 && vx < 15 && vy >= 0 && vy < 15 && + ku[(int)vx][(int)vy] == BBLANK) { + mv->x = vx; + mv->y = vy; + return 1; + } + } else { + switch(ch) { + case KEY_RIGHT: + mv->x = (mv->x == BRDSIZ - 1) ? mv->x : mv->x + 1; + break; + case KEY_LEFT: + mv->x = (mv->x == 0 ) ? 0 : mv->x - 1; + break; + case KEY_UP: + mv->y = (mv->y == BRDSIZ - 1) ? mv->y : mv->y + 1; + break; + case KEY_DOWN: + mv->y = (mv->y == 0 ) ? 0 : mv->y - 1; + break; + case ' ': + case '\r': + if(ku[(int)mv->x][(int)mv->y] == BBLANK) + return 1; + } + } + return 0; +} + +extern userec_t xuser; + +static int reload_gomo() { + passwd_query(usernum, &xuser); + cuser.five_win = xuser.five_win; + cuser.five_lose = xuser.five_lose; + cuser.five_tie = xuser.five_tie; + return 0; +} + +int gomoku(int fd) { + Horder_t mv; + int me, he, win, ch; + int hewantpass, iwantpass; + userinfo_t *my = currutmp; + + HO_init(); + me = !(my->turn) + 1; + he = my->turn + 1; + win = 1; + tick=time(0) + MAX_TIME; + lastcount = MAX_TIME; + setutmpmode(M_FIVE); + clear(); + + prints("\033[1;46m ¤¤l´Ñ¹ï¾Ô \033[45m%30s VS %-30s\033[m", + cuser.userid, my->mateid); + show_file("etc/@five", 1, -1, ONLY_COLOR); + move(11, 40); + prints("§Ú¬O %s", me == BBLACK ? "¥ý¤â ¡´, ¦³¸T¤â" : "«á¤â ¡³"); + move(16, 40); + prints("\033[1;33m%s", cuser.userid); + move(17, 40); + prints("\033[1;33m%s", my->mateid); + + reload_gomo(); + move(16, 60); + prints("\033[1;31m%d\033[37m³Ó \033[34m%d\033[37m±Ñ \033[36m%d\033[37m©M" + "\033[m", cuser.five_win, cuser.five_lose, cuser.five_tie); + + getuser(my->mateid); + move(17, 60); + prints("\033[1;31m%d\033[37m³Ó \033[34m%d\033[37m±Ñ \033[36m%d\033[37m" + "©M\033[m", xuser.five_win, xuser.five_lose, xuser.five_tie); + + cuser.five_lose++; + /* ¤@¶i¨Ó¥ý¥[¤@³õ±Ñ³õ, ŤF«á¦A¦©¦^¥h, ÁקK§Ö¿é¤F´c·NÂ_½u */ + passwd_update(usernum, &cuser); + + add_io(fd, 0); + + hewantpass = iwantpass = 0; + mv.x = mv.y = 7; + move(18, 40); + prints("%s®É¶¡ÁÙ³Ñ%d:%02d\n", my->turn ? "§Aªº" : "¹ï¤è", + MAX_TIME / 60, MAX_TIME % 60); + for(;;) { + move(13, 40); + outs(my->turn ? "½ü¨ì¦Û¤v¤U¤F!": "µ¥«Ý¹ï¤è¤U¤l.."); + if(lastcount != tick-time(0)) { + lastcount = tick-time(0); + move(18, 40); + prints("%s®É¶¡ÁÙ³Ñ%d:%02d\n", my->turn ? "§Aªº" : "¹ï¤è", + lastcount / 60, lastcount % 60); + if(lastcount <= 0 && my->turn) { + move(19, 40); + outs("®É¶¡¤w¨ì, §A¿é¤F"); + my->five_lose++; + send(fd, '\0', 1, 0); + break; + } + if(lastcount <= -5 && !my->turn) { + move(19, 40); + outs("¹ï¤â¤Ó¤[¨S¤U, §AŤF!"); + win = 1; + cuser.five_lose--; + cuser.five_win++; + my->five_win++; + passwd_update(usernum, &cuser); + mv.x = mv.y = -2; + send(fd, &mv, sizeof(Horder_t), 0); + mv = *(v - 1); + break; + } + } + move(14, 40); + if(hewantpass) { + outs("\033[1;32m©M´Ñn¨D!\033[m"); + bell(); + } else + clrtoeol(); + BGOTOCUR(mv.x, mv.y); + ch = igetkey(); + if(ch != I_OTHERDATA) + iwantpass = 0; + if(ch == 'q') { + if(countgomo() < 10) { + cuser.five_lose--; + passwd_update(usernum, &cuser); + } + send(fd, '\0', 1, 0); + break; + } else if(ch == 'u' && !my->turn && v > pool) { + mv.x = mv.y = -1; + ch = send(fd, &mv, sizeof(Horder_t), 0); + if(ch == sizeof(Horder_t)) { + HO_undo(&mv); + tick = mylasttick; + my->turn = 1; + continue; + } else + break; + } + if(ch == 'p') { + if(my->turn ) { + if(iwantpass == 0) { + iwantpass = 1; + mv.x = mv.y = -2; + send(fd, &mv, sizeof(Horder_t), 0); + mv = *(v - 1); + } + continue; + } else if(hewantpass) { + win = 0; + cuser.five_lose--; + cuser.five_tie++; + my->five_tie++; + passwd_update(usernum, &cuser); + mv.x=mv.y=-2; + send(fd, &mv, sizeof(Horder_t), 0); + mv = *(v - 1); + break; + } + } + + if(ch == I_OTHERDATA) { + ch = recv(fd, &mv, sizeof(Horder_t), 0); + if(ch != sizeof(Horder_t)) { + lastcount=tick-time(0); + if(lastcount >=0) { + win = 1; + cuser.five_lose--; + if(countgomo() >=10) { + cuser.five_win++; + my->five_win++; + } + passwd_update(usernum, &cuser); + outmsg("¹ï¤è»{¿é¤F!!"); + break; + } else { + win = 0; + outmsg("§A¶W¹L®É¶¡¥¼¤U¤l, ¿é¤F!"); + my->five_lose++; + break; + } + } else if(mv.x == -2 && mv.y == -2) { + if(iwantpass == 1) { + win = 0; + cuser.five_lose--; + cuser.five_tie++; + my->five_tie++; + passwd_update(usernum, &cuser); + break; + } else { + hewantpass = 1; + mv = *(v - 1); + continue; + } + } + if(my->turn && mv.x == -1 && mv.y == -1) { + outmsg("¹ï¤è®¬´Ñ"); + tick = hislasttick; + HO_undo(&mv); + my->turn = 0; + continue; + } + + if(!my->turn) { + win = chkmv(&mv, he, he == BBLACK); + HO_add(&mv); + hislasttick = tick; + tick = time(0) + MAX_TIME; + ku[(int)mv.x][(int)mv.y] = he; + bell(); + BGOTO(mv.x, mv.y); + outs(chess[he - 1]); + + if(win) { + outmsg(win == 1 ? "¹ï¤èŤF!" : "¹ï¤è¸T¤â"); + if(win != 1) { + cuser.five_lose--; + cuser.five_win++; + my->five_win++; + passwd_update(usernum, &cuser); + } else + my->five_lose++; + win = -win; + break; + } + my->turn = 1; + } + continue; + } + + if(my->turn) { + if(gomo_key(fd, ch, &mv)) + my->turn = 0; + else + continue; + + if(!my->turn) { + HO_add(&mv); + BGOTO(mv.x, mv.y); + outs(chess[me - 1]); + win = chkmv( &mv, me, me == BBLACK); + ku[(int)mv.x][(int)mv.y] = me; + mylasttick = tick; + tick = time(0) + MAX_TIME; /*˼Æ*/ + lastcount = MAX_TIME; + if(send(fd, &mv, sizeof(Horder_t), 0) != sizeof(Horder_t)) + break; + if(win) { + outmsg(win == 1 ? "§ÚĹÅo~~" : "¸T¤â¿é¤F" ); + if(win == 1) { + cuser.five_lose--; + cuser.five_win++; + my->five_win++; + passwd_update(usernum, &cuser); + } else + my->five_lose++; + break; + } + move(15, 40); + clrtoeol(); + } + } + } + add_io(0, 0); + close(fd); + + igetch(); + if(v > pool) { + char ans[4]; + + getdata(19 , 0, "n«O¯d¥»§½¦¨´ÑÃжÜ?(y/N)", ans, 4, LCECHO); + if(*ans == 'y') + HO_log(my->mateid); + } + return 0; +} diff --git a/mbbsd/gomo1.c b/mbbsd/gomo1.c new file mode 100644 index 00000000..953bad2d --- /dev/null +++ b/mbbsd/gomo1.c @@ -0,0 +1,136 @@ +/* $Id: gomo1.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include "config.h" +#include "pttstruct.h" +#include "proto.h" + +#define QCAST int (*)(const void *, const void *) + +#define BBLANK (0) /* ªÅ¥Õ */ +#define BBLACK (1) /* ¶Â¤l, ¥ý¤â */ +#define BWHITE (2) /* ¥Õ¤l, «á¤â */ +#ifndef BRDSIZ +#define BRDSIZ (15) /* ´Ñ½L³æÃä¤j¤p */ +#endif + +extern char ku[BRDSIZ][BRDSIZ]; + +/* pattern and advance map */ +extern unsigned char *pat, *adv; + +static int intrevcmp(const void *a, const void *b) { + return (*(int *)b - *(int *)a); +} + +/* x,y: 0..BRDSIZ-1 ; color: CBLACK,CWHITE ; dx,dy: -1,0,+1 */ +static int gomo_getindex(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 <<= 1) { + 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; +} + +int chkwin(int style, int limit) { + if(style == 0x0c) + return 1 /* style */; + else if(limit == 0) { + if(style == 0x0b) + return 1 /* style */; + return 0; + } + if((style < 0x0c) && (style > 0x07)) + return -1 /* -style */; + return 0; +} + +/* x,y: 0..BRDSIZ-1 ; color: CBLACK,CWHITE ; limit:1,0 ; dx,dy: 0,1 */ +static int dirchk(int x, int y, int color, int limit, int dx, int dy) { + int le, ri, loc, style; + + le = gomo_getindex(x, y, color, -dx, -dy); + ri = gomo_getindex(x, y, color, dx, dy); + + loc = (le > ri) ? (((le * (le + 1)) >> 1) + ri) : + (((ri * (ri + 1)) >> 1) + le); + + style = pat[loc]; + + if(limit == 0) + return (style & 0x0f); + + style >>= 4; + + if((style == 3) || (style == 2)) { + int i, n, tmp, nx, ny; + + n = adv[loc >> 1]; + + ((loc & 1) == 0) ? (n >>= 4) : (n &= 0x0f); + + 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(nx, ny, color, 0, dx, dy) == 0x06) && + (chkwin(getstyle(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 */ +int getstyle(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; + + for(i = 0; i < 4; i++) + dir[i] = dirchk(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; +} diff --git a/mbbsd/guess.c b/mbbsd/guess.c new file mode 100644 index 00000000..27a337f7 --- /dev/null +++ b/mbbsd/guess.c @@ -0,0 +1,364 @@ +/* $Id: guess.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "modes.h" +#include "proto.h" + +extern char *BBSName; +extern int usernum; +#define LOGPASS BBSHOME "/etc/winguess.log" + +static void show_table(char TABLE[], char ifcomputer) { + int i; + + move(0, 35); + prints("\033[1;44;33m ¡i ²q¼Æ¦r ¡j \033[m"); + move(8, 1); + prints("\033[1;44;36m¥Ø «e ¿ ²v\033[m\n"); + prints("\033[1;33m=================\033[m\n"); + if(ifcomputer) { + prints("Ĺ¹q¸£: 2 ¿\n"); + prints("¿é¹q¸£: 0 ¿\n"); + } else { + for(i = 1; i <= 6; i++) + prints("²Ä%d¦¸, %02d¿\n",i,TABLE[i]); + } + prints("\033[33m=================\033[m"); +} + +extern userec_t cuser; + +static unsigned long int get_money(void) { + int money, i; + char data[20]; + + move(1, 0); + prints("±z¥Ø«e¦³:%d Ptt$", cuser.money); + do { + getdata(2, 0, "n½ä¦h¤Ö(5-10©Î«öqÂ÷¶}): ", data, 9, LCECHO); + money = strlen(data); + if(data[0] == 'q' || data[0] == 'Q') { + unlockutmpmode(); + return 0; + } + for(i = 0; i < money; i++) + if(data[i]<'0' || data[i]>'9') { + money = -1; + break; + } + if(money != -1){ + money = atol(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 Ptt$", cuser.money - money); + return money; +} + +static int check_data(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(int count) { + static char data[5]; + while(1) { + getdata(6, 0, "¿é¤J¥|¦ì¼Æ¦r(¤£«½Æ): ", data, 5, LCECHO); + if(check_data(data) == 1) + break; + } + return data; +} + +static int guess_play(char *data, 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 => \033[1;32m%dA %dB\033[m", 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]; + + sprintf(n1, "%04d",correct); + sprintf(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]; + + sprintf(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 = rand() % 10000; + } while(!legal(guess)); + } else + guess = n[rand() % j]; + k = result(correct, guess); + if(k == 40) { + move(total + 8, 25); + sprintf(data, "%04d", guess); + prints("%s => ²q¤¤¤F!!", data); + return 1; + } else { + move(total + 8, 25); + sprintf(data, "%04d", guess); + prints("%s => \033[1;32m%dA %dB\033[m", 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 = rand() % 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() { + unsigned long int money; + char computerwin = 0,youwin = 0; + int count = 0,c_count = 0; + char ifcomputer; + char answer[5]; + int *n = NULL; + char yournum[5]; + char *flag = NULL; + static 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); + prints("¿ú¤£°÷°Õ ¦Ü¤Ön 5 Ptt$"); + unlockutmpmode(); + pressanykey(); + return 1; + } + if((money = get_money()) == 0) + return 1; + vice(money,"²q¼Æ¦r"); + + Diff_Random(answer); + move(2, 0); + clrtoeol(); + prints("±z¤Uª` :%d Ptt$", money); + + getdata_str(4, 0, "±zn©M¹q¸£¤ñÁɶÜ? <y/n>[y]:", &ifcomputer, 2, + LCECHO, "y"); + if(ifcomputer == 'y') { + ifcomputer = 1; + show_table(TABLE, 1); + } else { + ifcomputer = 0; + show_table(TABLE, 0); + } + if(ifcomputer) { + do { + getdata(5, 0, "½Ð¿é¤J±znÅý¹q¸£²qªº¼Æ¦r: ", yournum, 5, LCECHO); + } while(!legal(atoi(yournum))); + move(8, 25); + prints("¹q¸£²q"); + flag = malloc(sizeof(char) * 10000); + n = malloc(sizeof(int) * 1500); + initcomputer(flag); + } + move(8, 55); + prints("§A²q"); + while(((!computerwin || !youwin) && count <10 && (ifcomputer)) || + (!ifcomputer && count < 10 && !youwin)) { + if(!computerwin && ifcomputer) { + ++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(count),answer,count)) + youwin=1; + } + } + move(17, 35); + if(ifcomputer) { + free(flag); + free(n); + if(count > c_count) { + prints("§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 %ld Ptt$\n", cuser.userid, money); + fclose(file); + } + unlockutmpmode(); + pressanykey(); + return 1; + } else if(count < c_count) { + prints("¯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¸£ %ld Ptt$\n", cuser.userid, count, + c_count, money * 2); + fclose(file); + } + unlockutmpmode(); + pressanykey(); + return 1; + } 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) { + prints("¯u¼F®`, ¿ú³Q§AÁȨ«¤F"); + if((file = fopen(LOGPASS,"a"))) { + fprintf(file, "id: %s, ²Ä%d¦¸²q¤¤, ŤF %ld Ptt$\n", + cuser.userid, count, TABLE[count] * money); + fclose(file); + } + } else if(count > 5) { + prints("ü, ¤Ó¦h¦¸¤~²q¥X¨Ó¤F"); + if((file = fopen(LOGPASS,"a"))) { + fprintf(file, "id: %s, ²Ä%d¦¸¤~²q¤¤, ½ß¤F %ld Ptt$\n", + cuser.userid, count, money); + fclose(file); + } + } + else { + prints("¤¦¸²q¥X¨Ó, ÁÙ§A¥»¿ú§a"); + move(18,35); + clrtoeol(); + prints("§A®³¦^¤F%d Ptt$\n", money); + if((file = fopen(LOGPASS,"a"))) { + fprintf(file, "id: %s, ²Ä%d¦¸²q¤¤, ®³¦^¤F¥»¿ú %ld Ptt$\n", + cuser.userid, count, money); + fclose(file); + } + } + unlockutmpmode(); + pressanykey(); + return 1; + } + move(17,35); + prints("¼K¼K ¼Ð·Çµª®×¬O %s ", answer); + move(18,35); + prints("¤U¦¸¦A¨Ó§a"); + if((file = fopen(BBSHOME "/etc/loseguess.log","a"))) { + fprintf(file,"id: %s ½ä¤F %ld Ptt$\n",cuser.userid,money); + fclose(file); + } + return 1; +} diff --git a/mbbsd/indict.c b/mbbsd/indict.c new file mode 100644 index 00000000..407b5ae9 --- /dev/null +++ b/mbbsd/indict.c @@ -0,0 +1,184 @@ +/* $Id: indict.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include "config.h" +#include "pttstruct.h" +#include "perm.h" +#include "common.h" +#include "modes.h" +#include "proto.h" + +#define REFER "etc/dicts" + +extern userec_t cuser; +char dict[41],database[41]; + +static void addword(char word[]) { + char buf[150],temp[150],a[3]; + FILE *fp = fopen(database,"r+"); + + fgets(buf,130,fp); + fseek(fp,0,2); + if(HAVE_PERM(PERM_LOGINOK)) { + clear(); + move(4,0); + outs(" \033[31mĵ§i\033[m:Y»W·N¶ñ¼g°²¸ê®Æ±N\033[36m¬åid\033[m³B¥÷\n"); + sprintf(temp, "\n¿é¤J½d§Q\n:\033[33m%s\033[m", buf); + outs(temp); + outs("\n½Ð¨Ì¤W¦C½d¨Ò¿é¤J¤@¦æ¸ê®Æ(ª½±µenter©ñ±ó)\n"); + getdata(10, 0, ":", buf, 65, DOECHO); + if(buf[0]) { + getdata(13, 0, "½T©w·s¼W?(Y/n)", a, 2, LCECHO); + if(a[0] != 'n') + fprintf(fp, "%-65s[%s]\n", buf, cuser.userid); + } + } + fclose(fp); + clear(); +} + +static int choose_dict(void) { + int c; + FILE *fp; + char buf[10][21], data[10][21], cho[130]; + + move(12, 0); + clrtobot(); + outs(" " + "¡´ \033[45;33m¦r¨åò ¡º n¬dþ¤@¥»¡H\033[m ¡´"); + + if((fp = fopen(REFER, "r"))) { + for(c = 0; fscanf(fp, "%s %s", buf[c], data[c]) != EOF; c++ ) { + sprintf(cho,"\n " + "(\033[36m%d\033[m) %-20s¤j¦r¨å",c+1,buf[c]); + outs(cho); + } + + getdata(22, 14, " ¡¹ ½Ð¿ï¾Ü¡A[Enter]Â÷¶}¡G", cho, 3, LCECHO); + cho[0] -= '1'; + if(cho[1]) + cho[0] = (cho[0] + 1) * 10 + (cho[1] - '1'); + + if(cho[0] >= 0 && cho[0] < c) { + strcpy(dict, buf[(int)cho[0]]); + strcpy(database, data[(int)cho[0]]); + return 1; + } else + return 0; + } + return 0; +} + +static char *lower(char str[]) { + int c; + static char temp[200]; + + strcpy(temp,str); + for(c = 0; temp[c] !=0; c++) + if(temp[c] >= 'A' && temp[c] <= 'Z') + temp[c] += 'a' - 'A'; + return temp; +} + +int use_dict() { + FILE *fp; + char lang[150], word[80] = ""; + char j, f, buf[120], sys[] = "|\033[31me\033[m:½sÄy¦r¨å"; + int i = 0; + + setutmpmode(DICT); + if(!HAS_PERM(PERM_SYSOP)) + sys[0]=0; + + clear(); + + sprintf(buf,"\033[45m ¡´\033[1;44;33m" + " %-14s\033[3;45m ¡´ ", dict); + strcpy(&buf[100],"\033[m\n"); + for(;;) { + move(0, 0); + sprintf(lang, " ½Ð¿é¤JÃöÁä¦r¦ê(%s) ©Î«ü¥O(h,t,a)\n", dict); + outs(lang); + sprintf(lang, "[\033[32m<ÃöÁä¦r>\033[m|\033[32mh\033[m:help|\033[32m" + "t\033[m:©Ò¦³¸ê®Æ|\033[32ma\033[m:·s¼W¸ê®Æ%s]\n:", sys); + outs(lang); + getdata(2, 0, ":", word, 18, DOECHO); + outs("¸ê®Æ·j´M¤¤½ÐµyÔ...."); + strcpy(word,lower(word)); + if(word[0] == 0) + return 0; + clear(); + move(4, 0); + outs(buf); + if(strlen(word) == 1) { + if(word[0] == 'a') { + clear(); + move(4,0); + outs(buf); + addword(word); + continue; + } else if(word[0] == 't') + word[0] = 0; + else if(word[0] == 'h') { + more("etc/dict.hlp",YEA); + clear(); + continue; + } else if(word[0]=='e') { + vedit(database,NA, NULL); + clear(); + continue; + } else { + outs("¦r¦ê¤Óµu,½Ð¿é¤J¦h¤@ÂIÃöÁä¦r"); + continue; + } + } + + if((fp = fopen(database,"r"))) { + i = 0; + while(fgets(lang,150,fp) != NULL) { + if(lang[65] == '[') { + lang[65] = 0; + f = 1; + } else + f = 0; + if(strstr(lower(lang),word)) { + if(f == 1) + lang[65] = '['; + outs(lang); + i++; + if(!((i+1)%17)) { + move(23, 0); + outs("\033[45m " + "¥ô·NÁäÄ~Äò Q:Â÷¶} " + "\033[m "); + j = igetch(); + if(j == 'q') + break; + else { + clear(); + move(4,0); + outs(buf); + } + } + } + } + } + fclose(fp); + if(i == 0) { + getdata(5, 0, "¨S³oÓ¸ê®ÆC,·s¼W¶Ü?(y/N)", lang, 3, LCECHO); + if(lang[0] == 'y') { + clear(); + move(4,0); + outs(buf); + addword(word); + } + } + } +} + +int x_dict() { + if(choose_dict()) + use_dict(); + return 0; +} diff --git a/mbbsd/io.c b/mbbsd/io.c new file mode 100644 index 00000000..e3d03b9b --- /dev/null +++ b/mbbsd/io.c @@ -0,0 +1,611 @@ +/* $Id: io.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <time.h> +#include <unistd.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/time.h> +#include <sys/ioctl.h> +#include <signal.h> +#include "config.h" +#include "pttstruct.h" +#include "perm.h" +#include "modes.h" +#include "common.h" +#include "proto.h" + +#if defined(linux) +#define OBUFSIZE 2048 +#define IBUFSIZE 128 +#else +#define OBUFSIZE 4096 +#define IBUFSIZE 256 +#endif + +extern int current_font_type; +extern char *fn_proverb; +extern userinfo_t *currutmp; +extern unsigned int currstat; +extern pid_t currpid; +extern int errno; +extern screenline_t *big_picture; +extern int t_lines, t_columns; /* Screen size / width */ +extern int curr_idle_timeout; +extern water_t water[6], *swater[5], *water_which; +extern char water_usies; + +static char outbuf[OBUFSIZE], inbuf[IBUFSIZE]; +static int obufsize = 0, ibufsize = 0; +static int icurrchar = 0; + +/* ----------------------------------------------------- */ +/* ©w®ÉÅã¥Ü°ÊºA¬ÝªO */ +/* ----------------------------------------------------- */ +extern userec_t cuser; + +static void hit_alarm_clock() { + if(HAS_PERM(PERM_NOTIMEOUT) || PERM_HIDE(currutmp) || currstat == MAILALL) + return; +// if(time(0) - currutmp->lastact > IDLE_TIMEOUT - 2) { + if(time(0) - currutmp->lastact > curr_idle_timeout - 2) { + clear(); + if(currpid > 0) kill(currpid, SIGHUP); + } +// alarm(IDLE_TIMEOUT); + alarm(curr_idle_timeout); +} + +void init_alarm() { + signal(SIGALRM, (void (*)(int))hit_alarm_clock); +// alarm(IDLE_TIMEOUT); + alarm(curr_idle_timeout); +} + +/* ----------------------------------------------------- */ +/* output routines */ +/* ----------------------------------------------------- */ + +void oflush() { + if(obufsize) { + write(1, outbuf, obufsize); + obufsize = 0; + } +} + +void init_buf() +{ + + memset(inbuf,0,IBUFSIZE); +} +void output(char *s, int len) { + /* Invalid if len >= OBUFSIZE */ + + if(obufsize + len > OBUFSIZE) { + write(1, outbuf, obufsize); + obufsize = 0; + } + memcpy(outbuf + obufsize, s, len); + obufsize += len; +} + +int ochar(int c) { + if(obufsize > OBUFSIZE - 1) { + 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() { + return icurrchar - ibufsize; +} + +int watermode = -1; +/* Ptt ¤ô²y¦^ÅU¥Îªº°Ñ¼Æ */ +/* watermode = -1 ¨S¦b¦^¤ô²y + = 0 ¦b¦^¤W¤@Áû¤ô²y (Ctrl-R) + > 0 ¦b¦^«e n Áû¤ô²y (Ctrl-R Ctrl-R) */ + +/* + 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() { + int len; + + 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) */ + + 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) + return I_TIMEOUT; + + if(i_newfd && FD_ISSET(i_newfd, &readfds)) + return I_OTHERDATA; + } + + while((len = read(0, inbuf, IBUFSIZE)) <= 0) { + if(len == 0 || errno != EINTR) + abort_bbs(0); + /* raise(SIGHUP); */ + } + ibufsize = len; + icurrchar = 0; + } + + if(currutmp) + currutmp->lastact = time(0); + return inbuf[icurrchar++]; +} + +static int water_which_flag=0; +int igetch() { + register int ch; + while((ch = dogetch())) { + switch(ch) { + case Ctrl('L'): + redoscr(); + continue; + case Ctrl('U'): + if(currutmp != NULL && currutmp->mode != EDITING + && currutmp->mode != LUSERS && currutmp->mode) { + + screenline_t *screen0 = calloc(t_lines, sizeof(screenline_t)); + int y, x, my_newfd; + + getyx(&y, &x); + memcpy(screen0, big_picture, t_lines * sizeof(screenline_t)); + my_newfd = i_newfd; + i_newfd = 0; + t_users(); + i_newfd = my_newfd; + memcpy(big_picture, screen0, t_lines * sizeof(screenline_t)); + move(y, x); + free(screen0); + redoscr(); + continue; + } else + return (ch); + case KEY_TAB: + if( WATERMODE(WATER_ORIG) || WATERMODE(WATER_NEW) ) + if( currutmp != NULL && watermode > 0 ){ + watermode = (watermode + water_which->count) + % water_which->count + 1; + t_display_new(); + continue; + } + return ch; + break; + + case Ctrl('R'): + if(currutmp == NULL) + return (ch); + if( WATERMODE(WATER_ORIG) || WATERMODE(WATER_NEW) ){ + 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(currutmp->msgs[0].pid) { + /* ²Ä¤@¦¸«ö Ctrl-R (¥²¶·¥ý³Q¥á¹L¤ô²y) */ + screenline_t *screen0; + int y, x, my_newfd; + screen0 = calloc(t_lines, sizeof(screenline_t)); + getyx(&y, &x); + memcpy(screen0, big_picture, t_lines*sizeof(screenline_t)); + + /* ¦pªG¥¿¦btalkªº¸Ü¥ý¤£³B²z¹ï¤è°e¹L¨Óªº«Ê¥] (¤£¥hselect) */ + my_newfd = i_newfd; + i_newfd = 0; + show_last_call_in(0); + watermode = 0; + my_write(currutmp->msgs[0].pid, "¤ô²y¥á¹L¥h ¡G ", + currutmp->msgs[0].userid, 0); + i_newfd = my_newfd; + + /* ÁÙì¿Ã¹õ */ + memcpy(big_picture, screen0, t_lines*sizeof(screenline_t)); + move(y, x); + free(screen0); + redoscr(); + continue; + } + else + return ch; + } + + if( currutmp->msgs[0].pid && + WATERMODE(WATER_OFO) && watermode == -1 ){ + int y, x, my_newfd; + screenline_t *screen0 = calloc(t_lines, sizeof(screenline_t)); + memcpy(screen0, big_picture, t_lines * sizeof(screenline_t)); + getyx(&y, &x); + my_newfd = i_newfd; + i_newfd = 0; + my_write2(); + memcpy(big_picture, screen0, t_lines * sizeof(screenline_t)); + i_newfd = my_newfd; + move(y, x); + free(screen0); + redoscr(); + continue; + } + + return ch; + case '\n': /* Ptt§â \n®³±¼ */ + continue; + case Ctrl('T'): + if( WATERMODE(WATER_ORIG) || WATERMODE(WATER_NEW) ){ + if(watermode > 0) { + if(watermode>1) + watermode--; + else + watermode = water_which->count; + t_display_new(); + continue; + } + } + return (ch); + + case Ctrl('E'): + if( WATERMODE(WATER_ORIG) || WATERMODE(WATER_NEW) ){ + if(watermode >0){ + 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('W'): + if(watermode >0) + { + 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; + } + else return ch; + default: + return ch; + } + } + return 0; +} + +int oldgetdata(int line, int col, char *prompt, char *buf, int len, int echo) { + register int ch, i; + int clen; + int x = col, y = line; + extern unsigned char scr_cols; +#define MAXLASTCMD 12 + static char lastcmd[MAXLASTCMD][80]; + + strip_ansi(buf, buf, STRIP_ALL); + + if(prompt) { + + move(line, col); + + clrtoeol(); + + outs(prompt); + + x += strip_ansi(NULL,prompt,0); + } + + if(!echo) { + len--; + clen = 0; + while((ch = igetch()) != '\r') { + if(ch == '\177' || ch == Ctrl('H')) { + if(!clen) { + bell(); + continue; + } + clen--; + if(echo) { + ochar(Ctrl('H')); + ochar(' '); + ochar(Ctrl('H')); + } + continue; + } +// Ptt +#ifdef BIT8 + if(!isprint2(ch)) +#else + if(!isprint(ch)) +#endif + { + if(echo) + bell(); + continue; + } + + if(clen >= len) { + if(echo) + bell(); + continue; + } + buf[clen++] = ch; + if(echo) + ochar(ch); + } + buf[clen] = '\0'; + outc('\n'); + oflush(); + } else { + int cmdpos = -1; + int currchar = 0; + + standout(); + for(clen = len--; clen; clen--) + outc(' '); + standend(); + buf[len] = 0; + move(y, x); + edit_outs(buf); + clen = currchar = strlen(buf); + + while(move(y, x + currchar), (ch = igetkey()) != '\r') { + switch(ch) { + case KEY_DOWN: + case Ctrl('N'): + buf[clen] = '\0'; /* Ptt */ + strncpy(lastcmd[cmdpos], buf, 79); + cmdpos += MAXLASTCMD - 2; + case Ctrl('P'): + case KEY_UP: + if(ch == KEY_UP || ch == Ctrl('P')) { + buf[clen] = '\0'; /* Ptt */ + strncpy(lastcmd[cmdpos], buf, 79); + } + cmdpos++; + cmdpos %= MAXLASTCMD; + strncpy(buf, lastcmd[cmdpos], len); + buf[len] = 0; + + move(y, x); /* clrtoeof */ + for(i = 0; i <= clen; i++) + outc(' '); + move(y, x); + edit_outs(buf); + clen = currchar = strlen(buf); + break; + case KEY_LEFT: + if(currchar) + --currchar; + break; + case KEY_RIGHT: + if(buf[currchar]) + ++currchar; + break; + case '\177': + case Ctrl('H'): + if(currchar) { + currchar--; + clen--; + for(i = currchar; i <= clen; i++) + buf[i] = buf[i + 1]; + move(y, x + clen); + outc(' '); + move(y, x); + edit_outs(buf); + } + break; + case Ctrl('Y'): + currchar = 0; + case Ctrl('K'): + buf[currchar] = 0; + move(y, x + currchar); + for(i = currchar; i < clen; i++) + outc(' '); + clen = currchar; + break; + case Ctrl('D'): + if(buf[currchar]) { + clen--; + for(i = currchar; i <= clen; i++) + buf[i] = buf[i + 1]; + move(y, x + clen); + outc(' '); + move(y, x); + edit_outs(buf); + } + break; + case Ctrl('A'): + currchar = 0; + break; + case Ctrl('E'): + currchar = clen; + break; + default: + if(isprint2(ch) && clen < len && x + clen < scr_cols) { + for(i = clen + 1; i > currchar;i--) + buf[i] = buf[i - 1]; + buf[currchar] = ch; + move(y, x + currchar); + edit_outs(buf + currchar); + currchar++; + clen++; + } + break; + }/* end case */ + } /* end while */ + + if(clen > 1) + for(cmdpos = MAXLASTCMD - 1; cmdpos; cmdpos--) { + strcpy(lastcmd[cmdpos], lastcmd[cmdpos - 1]); + strncpy(lastcmd[0], buf, len); + } + if(echo) + outc('\n'); + refresh(); + } + if((echo == LCECHO) && ((ch = buf[0]) >= 'A') && (ch <= 'Z')) + buf[0] = ch | 32; +#ifdef SUPPORT_GB + if(echo == DOECHO && current_font_type == TYPE_GB) + { + strcpy(buf,hc_convert_str(buf, HC_GBtoBIG, HC_DO_SINGLE)); + } +#endif + return clen; +} + +/* Ptt */ +int getdata_buf(int line, int col, char *prompt, char *buf, int len, int echo) { + return oldgetdata(line, col, prompt, buf, len, echo); +} + +char +getans(char *prompt) +{ + char ans[5]; + + getdata(t_lines-1, 0, prompt, ans, 4, LCECHO); + return ans[0]; +} + +int getdata_str(int line, int col, char *prompt, char *buf, int len, int echo, char *defaultstr) { + strncpy(buf, defaultstr, len); + + buf[len] = 0; + return oldgetdata(line, col, prompt, buf, len, echo); +} + +int getdata(int line, int col, char *prompt, char *buf, int len, int echo) { + buf[0] = 0; + return oldgetdata(line, col, prompt, buf, len, echo); +} + +int +rget(int x,char *prompt) +{ + register int ch; + + move(x,0); + clrtobot(); + outs(prompt); + refresh(); + + ch = igetch(); + if( ch >= 'A' && ch <= 'Z') ch |= 32; + + return ch; +} + + +int KEY_ESC_arg; + +int igetkey() { + int mode; + int ch, last; + + mode = last = 0; + while(1) { + ch = igetch(); + if(mode == 0) { + if(ch == KEY_ESC) + mode = 1; + else + return ch; /* Normal Key */ + } else if (mode == 1) { /* Escape sequence */ + if(ch == '[' || ch == 'O') + mode = 2; + else if(ch == '1' || ch == '4') + mode = 3; + else { + KEY_ESC_arg = ch; + return KEY_ESC; + } + } else if(mode == 2) { /* Cursor key */ + if(ch >= 'A' && ch <= 'D') + return KEY_UP + (ch - 'A'); + else if(ch >= '1' && ch <= '6') + mode = 3; + else + return ch; + } else if (mode == 3) { /* Ins Del Home End PgUp PgDn */ + if(ch == '~') + return KEY_HOME + (last - '1'); + else + return ch; + } + last = ch; + } +} + diff --git a/mbbsd/kaede.c b/mbbsd/kaede.c new file mode 100644 index 00000000..c0bd5103 --- /dev/null +++ b/mbbsd/kaede.c @@ -0,0 +1,95 @@ +/* $Id: kaede.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/types.h> +#include "config.h" +#include "pttstruct.h" +#include "proto.h" + +extern struct utmpfile_t *utmpshm; +extern userec_t cuser; + +char *Ptt_prints(char *str, int mode) { + char *po , strbuf[256]; + + while((po = strstr(str, "\033*s"))) { + po[0] = 0; + sprintf(strbuf, "%s%s%s", str, cuser.userid, po + 3); + strcpy(str, strbuf); + } + while((po = strstr(str, "\033*t"))) { + time_t now = time(0); + + po[0] = 0; + sprintf(strbuf, "%s%s", str, Cdate(&now)); + str[strlen(strbuf)-1] = 0; + strcat(strbuf, po + 3); + strcpy(str, strbuf); + } + while((po = strstr(str, "\033*u"))) { + int attempts; + + attempts = utmpshm->number; + po[0] = 0; + sprintf(strbuf, "%s%d%s", str, attempts, po + 3); + strcpy(str, strbuf); + } + while((po = strstr(str, "\033*b"))) { + po[0] = 0; + sprintf(strbuf, "%s%d/%d%s", str, cuser.month, cuser.day, po + 3); + strcpy(str, strbuf); + } + while((po = strstr(str, "\033*l"))) { + po[0] = 0; + sprintf(strbuf, "%s%d%s", str, cuser.numlogins, po + 3); + strcpy(str, strbuf); + } + while((po = strstr(str, "\033*p"))) { + po[0] = 0; + sprintf(strbuf, "%s%d%s", str, cuser.numposts, po + 3); + strcpy(str, strbuf); + } + while((po = strstr(str, "\033*n"))) { + po[0] = 0; + sprintf(strbuf, "%s%s%s", str, cuser.username, po + 3); + strcpy(str, strbuf); + } + while((po = strstr(str, "\033*m"))) { + po[0] = 0; + sprintf(strbuf, "%s%d%s", str, cuser.money, po + 3); + strcpy(str, strbuf); + } + strip_ansi(str, str ,mode); + return str; +} + +int Rename(char* src, char* dst) { + if(rename(src, dst) == 0) + return 0; + return -1; +} + +int Link(char* src, char* dst) { + char cmd[200]; + + if(strcmp(src, BBSHOME "/home") == 0) + return 1; + if(link(src, dst) == 0) + return 0; + + sprintf(cmd, "/bin/cp -R %s %s", src, dst); + return system(cmd); +} + +char *my_ctime(const time_t *t) { + struct tm *tp; + static char ans[100]; + + tp = localtime(t); + sprintf(ans, "%02d/%02d/%02d %02d:%02d:%02d", (tp->tm_year % 100), + tp->tm_mon + 1,tp->tm_mday, tp->tm_hour, tp->tm_min, tp->tm_sec); + return ans; +} diff --git a/mbbsd/lovepaper.c b/mbbsd/lovepaper.c new file mode 100644 index 00000000..52e8cbd5 --- /dev/null +++ b/mbbsd/lovepaper.c @@ -0,0 +1,120 @@ +/* $Id: lovepaper.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> +#include <sys/types.h> +#include "config.h" +#include "pttstruct.h" +#include "modes.h" +#include "common.h" +#include "proto.h" + +#define DATA "etc/lovepaper.dat" + +extern userec_t cuser; + +int x_love() { + char buf1[200], save_title[TTLEN + 1]; + char receiver[61], path[STRLEN] = "home/"; + int x, y = 0, tline = 0, poem = 0; + FILE *fp, *fpo; + time_t timenow; + struct tm *gtime; + fileheader_t mhdr; + + setutmpmode(LOVE); + time(&timenow); + gtime = localtime(&timenow); + sprintf(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 ª© \n"); + outs("¦³¦óÃø¥H±Ò¾¦ªº¸Ü,¥æ¥Ñ¨t²ÎÀ°§A»¡§a.\nª¨ª¨»¡ : Àݱ¡¤£¥Çªk.\n"); + + if(!getdata(7, 0, "¦¬«H¤H¡G", receiver, 60, DOECHO)) return 0; + if(receiver[0] && !(searchuser(receiver) && + getdata(8, 0, "¥D ÃD¡G", save_title, + TTLEN, DOECHO))) { + move(10, 0); + outs("¦¬«H¤H©Î¥DÃD¤£¥¿½T, ±¡®ÑµLªk¶Ç»¼. "); + pressanykey(); + return 0; + } + + fpo = fopen(path, "w"); + 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 = (rand() % (x - 1)) * tline; + break; + default: + if(!poem) { + if(y > 0) + y = y - 1; + else { + if(tline > 0) { + fprintf(fpo, "%s", buf1); + tline--; + } + } + } else { + if(buf1[0] == '$') + y--; + else if(y == 0) + fprintf(fpo,"%s",buf1); + } + } + + } + + fclose(fp); + fclose(fpo); + if(vedit(path, YEA, NULL) == -1) { + unlink(path); + clear(); + outs("\n\n ©ñ±ó±H±¡®Ñ\n"); + pressanykey(); + return -2; + } + sethomepath(buf1, receiver); + stampfile(buf1, &mhdr); + Rename(path, buf1); + strncpy(mhdr.title, save_title, TTLEN); + strcpy(mhdr.owner, cuser.userid); + mhdr.savemode = '\0'; + sethomedir(path, receiver ); + if(append_record(path, &mhdr, sizeof(mhdr)) == -1) + return -1; + hold_mail(buf1, receiver); + return 1; + } + return 0; +} diff --git a/mbbsd/mail.c b/mbbsd/mail.c new file mode 100644 index 00000000..e480abb2 --- /dev/null +++ b/mbbsd/mail.c @@ -0,0 +1,1675 @@ +/* $Id: mail.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <string.h> +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "perm.h" +#include "modes.h" +#include "proto.h" + +extern int TagNum; +extern int b_lines; /* Screen bottom line number: t_lines-1 */ +extern char save_title[]; /* used by editor when inserting */ +extern int curredit; +extern char *err_uid; +extern char *msg_cancel; +extern char *msg_uid; +extern char *fn_overrides; +extern char quote_file[80]; +extern char quote_user[80]; +extern char *fn_notes; +extern char *msg_mailer; +extern char *msg_sure_ny; +extern char *BBSName; +extern char currtitle[44]; +extern unsigned char currfmode; /* current file mode */ +extern char *msg_del_ny; +extern char currfile[FNLEN]; +extern int currmode; +extern char currboard[]; /* name of currently selected board */ +extern char *str_space; +extern char *str_author1; +extern char *str_author2; +extern userinfo_t *currutmp; +extern unsigned int currstat; +extern pid_t currpid; +extern int usernum; +extern char *str_mail_address; +extern userec_t cuser; + +char currmaildir[32]; +static char msg_cc[] = "\033[32m[¸s²Õ¦W³æ]\033[m\n"; +static char listfile[] = "list.0"; +static int mailkeep = 0, mailsum = 0; +static int mailsumlimit = 0,mailmaxkeep = 0; + +int setforward() { + char buf[80], ip[50] = "", yn[4]; + FILE *fp; + + sethomepath(buf, cuser.userid); + strcat(buf,"/.forward"); + if((fp = fopen(buf,"r"))) { + fscanf(fp,"%s",ip); + fclose(fp); + } + getdata_buf(b_lines - 1, 0, "½Ð¿é¤J«H½c¦Û°ÊÂà±Hªºemail¦a§}:", + ip, 41, DOECHO); + if(ip[0] && ip[0] != ' ') { + getdata(b_lines, 0, "½T©w¶}±Ò¦Û°ÊÂà«H¥\\¯à?(Y/n)", yn, 3, + LCECHO); + if(yn[0] != 'n' && (fp = fopen(buf, "w"))) { + move(b_lines,0); + clrtoeol(); + fprintf(fp,"%s",ip); + fclose(fp); + outs("³]©w§¹¦¨!"); + refresh(); + return 0; + } + } + move(b_lines,0); + clrtoeol(); + outs("¨ú®ø¦Û°ÊÂà«H!"); + unlink(buf); + refresh(); + return 0; +} + +int built_mail_index() { + char genbuf[128]; + + getdata(b_lines, 0, + "««Ø«H½c?(ĵ§i:½Ð½T©w«H½c¦³°ÝÃD®É¤~¨Ï¥Î)(y/N)", genbuf, 3, + LCECHO); + if(genbuf[0] != 'y') return 0; + + sprintf(genbuf, BBSHOME "/bin/buildir " BBSHOME "/home/%c/%s", + cuser.userid[0], cuser.userid); + move(22,0); + prints("\033[1;31m¤w¸g³B²z§¹²¦!! ½Ñ¦h¤£«K ·q½Ðì½Ì~\033[m");pressanykey(); + system(genbuf); + return 0; +} + +int mailalert(char *userid) +{ + userinfo_t *uentp=NULL; + int n,tuid,i; + + if((tuid=searchuser(userid))==0) return -1; + + n=count_logins(tuid, 0); + for(i=1;i<=n;i++) + if((uentp = (userinfo_t *)search_ulistn(tuid, i))) + uentp->mailalert=1; + return 0; +} + +int mail_muser(userec_t muser, char *title, char *filename) { + return mail_id(muser.userid, title, filename, cuser.userid); +} + +/* Heat: ¥Îid¨Ó±H«H,¤º®e«hlink·Ç³Æ¦nªºÀÉ®× */ +int mail_id(char* id, char *title, char *filename, char *owner) { + fileheader_t mhdr; + char genbuf[128]; + sethomepath(genbuf, id); + if(stampfile(genbuf, &mhdr)) + return 0; + strcpy(mhdr.owner, owner); + strncpy(mhdr.title, title, TTLEN); + mhdr.savemode = 0; + mhdr.filemode = 0; + Link(filename, genbuf); + sethomedir(genbuf,id); + append_record(genbuf, &mhdr, sizeof(mhdr)); + mailalert(id); + return 0; +} + +int invalidaddr(char *addr) { + if(*addr == '\0') + return 1; /* blank */ + while(*addr) { + if(not_alnum(*addr) && !strchr("[].%!@:-_;", *addr)) + return 1; + addr++; + } + return 0; +} + +int m_internet() { + char receiver[60]; + + getdata(20, 0, "¦¬«H¤H¡G", receiver, 60, DOECHO); + if(strchr(receiver, '@') && !invalidaddr(receiver) && + getdata(21, 0, "¥D ÃD¡G", save_title, TTLEN, DOECHO)) + do_send(receiver, save_title); + else { + move(22, 0); + outs("¦¬«H¤H©Î¥DÃD¤£¥¿½T, ½Ð«·s¿ï¨ú«ü¥O"); + pressanykey(); + } + return 0; +} + +void m_init() { + sethomedir(currmaildir, cuser.userid); +} + +int chkmailbox() { + if(!HAVE_PERM(PERM_SYSOP) && !HAVE_PERM(PERM_MAILLIMIT)) { + int max_keepmail = MAX_KEEPMAIL; + if ( HAS_PERM(PERM_SYSSUBOP) || HAS_PERM(PERM_SMG) || + HAS_PERM(PERM_PRG) || HAS_PERM(PERM_ACTION) || HAS_PERM(PERM_PAINT)) + { + mailsumlimit = 700; + max_keepmail = 500; + } + else if(HAS_PERM(PERM_BM)) + { + mailsumlimit = 500; + max_keepmail = 300; + } + else if(HAS_PERM(PERM_LOGINOK)) + mailsumlimit = 200; + else + mailsumlimit = 50; + mailsumlimit += cuser.exmailbox * 10; + mailmaxkeep = max_keepmail + cuser.exmailbox; + m_init(); + if((mailkeep = get_num_records(currmaildir, sizeof(fileheader_t))) > + mailmaxkeep) { + move(b_lines, 0); + clrtoeol(); + bell(); + prints("±z«O¦s«H¥ó¼Æ¥Ø %d ¶W¥X¤W %d, ½Ð¾ã²z", + mailkeep, mailmaxkeep); + bell(); + refresh(); + igetch(); + return mailkeep; + } + if((mailsum = get_sum_records(currmaildir, sizeof(fileheader_t))) > + mailsumlimit) { + move(b_lines, 0); + clrtoeol(); + bell(); + prints("±z«O¦s«H¥ó®e¶q %d(k)¶W¥X¤W %d(k), ½Ð¾ã²z", + mailsum, mailsumlimit); + bell(); + refresh(); + igetch(); + return mailkeep; + } + } + return 0; +} + +static void do_hold_mail(char *fpath, char *receiver, char *holder) { + char buf[80], title[128]; + + fileheader_t mymail; + + sethomepath(buf, holder); + stampfile(buf, &mymail); + + mymail.savemode = 'H'; /* hold-mail flag */ + mymail.filemode = FILE_READ; + strcpy(mymail.owner, "[³Æ.§Ñ.¿ý]"); + if(receiver) { + sprintf(title, "(%s) %s", receiver, save_title); + strncpy(mymail.title, title, TTLEN); + } else + strcpy(mymail.title, save_title); + + sethomedir(title, holder); + + unlink(buf); + Link(fpath, buf); + /* Ptt: append_record->do_append */ + do_append(title, &mymail, sizeof(mymail)); +} + +extern userec_t xuser; + +void hold_mail(char *fpath, char *receiver) { + char buf[4]; + + getdata(b_lines - 1, 0, "¤w¶¶§Q±H¥X¡A¬O§_¦Û¦s©³½Z(Y/N)¡H[N] ", + buf, 4, LCECHO); + + if(buf[0] == 'y') + do_hold_mail(fpath, receiver, cuser.userid); +} + +int do_send(char *userid, char *title) { + fileheader_t mhdr; + char fpath[STRLEN]; + char receiver[IDLEN]; + char genbuf[200]; + int internet_mail, i; + + if(strchr(userid, '@')) + internet_mail = 1; + else { + internet_mail = 0; + if(!getuser(userid)) + return -1; + if(!(xuser.userlevel & PERM_READMAIL)) + return -3; + + if(!title) + getdata(2, 0, "¥DÃD¡G", save_title, TTLEN, DOECHO); + curredit |= EDIT_MAIL; + curredit &= ~EDIT_ITEM; + } + + 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©wn±H¥X¶Ü? (Y/N) [Y]", + userid, 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, title, userid); +#else + bsmtp(fpath, title, userid,0); +#endif + hold_mail(fpath, userid); + } + unlink(fpath); + return res; + } else { + strcpy(receiver, userid); + sethomepath(genbuf, userid); + stampfile(genbuf, &mhdr); + strcpy(mhdr.owner, cuser.userid); + strncpy(mhdr.title, save_title, TTLEN); + mhdr.savemode = '\0'; + if(vedit(genbuf, YEA, NULL) == -1) { + unlink(genbuf); + clear(); + return -2; + } + 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(fpath, &mhdr, sizeof(mhdr)) == -1) + return -1; + mailalert(userid); + } + hold_mail(genbuf, userid); + return 0; + } +} + +void my_send(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() { + 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 */ +extern struct word_t *toplev; + +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); + getdata(1, 0, + "(I)¤Þ¤J¦n¤Í (O)¤Þ¤J¤W½u³qª¾ (N)¤Þ¤J·s¤å³¹³qª¾ " + "(0-9)¤Þ¤J¨ä¥L¯S§O¦W³æ\n" + "(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("½Ð¿é¤Jn¼W¥[ªº¥N¸¹(¥u«ö ENTER µ²§ô·s¼W): ", uid); + if(uid[0] == '\0') + break; + + move(2, 0); + clrtoeol(); + + if(!searchuser(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("½Ð¿é¤Jn§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; + 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"); + while(fgets(genbuf, 256, fp)) { + if(strncmp(genbuf, "¡° ", 3)) { + if(listing) + break; + } else { + if(listing) { + strtok(ptr = genbuf + 3, " \n\r"); + do { + if(searchuser(ptr) && !InNameList(ptr) && + strcmp(cuser.userid, ptr)) { + AddNameList(ptr); + reciper++; + } + } while((ptr = (char *)strtok(NULL, " \n\r"))); + } else if(!strncmp(genbuf + 3, "[³q§i]", 6)) + listing = 1; + } + } + 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, 64, DOECHO); + sprintf(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; + outs(msg_cancel); + pressanykey(); + return; + } + + stand_title("±H«H¤¤..."); + refresh(); + + 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) && strcmp(STR_GUEST, p->word) ) + sethomepath(genbuf, p->word); + else + continue; + stampfile(genbuf, &mymail); + unlink(genbuf); + Link(fpath, genbuf); + + strcpy(mymail.owner, cuser.userid); + strcpy(mymail.title, save_title); + mymail.savemode = 'M'; /* multi-send flag */ + sethomedir(genbuf, p->word); + if(append_record(genbuf, &mymail, sizeof(mymail)) == -1) + outs(err_uid); + mailalert(p->word); + } + hold_mail(fpath, NULL); + unlink(fpath); + curredit = 0; + } else + outs(msg_cancel); + pressanykey(); +} + +static int multi_reply(int ent, fileheader_t *fhdr, char *direct) { + if(fhdr->savemode != 'M') + return mail_reply(ent, fhdr, direct); + + stand_title("¸s²Õ¦^«H"); + strcpy(quote_user, fhdr->owner); + setuserfile(quote_file, fhdr->filename); + multi_send(fhdr->title); + return 0; +} + +int mail_list() { + stand_title("¸s²Õ§@·~"); + multi_send(NULL); + return 0; +} + +int mail_all() { + FILE *fp; + fileheader_t mymail; + char fpath[TTLEN]; + char genbuf[200]; + extern struct uhash_t *uhash; + int i, unum; + char *userid; + + stand_title("µ¹©Ò¦³¨Ï¥ÎªÌªº¨t²Î³q§i"); + setutmpmode(SMAIL); + getdata(2, 0, "¥DÃD¡G", fpath, 64, DOECHO); + sprintf(save_title, "[¨t²Î³q§i]\033[1;32m %s\033[m", fpath); + + setuserfile(fpath, fn_notes); + + if((fp = fopen(fpath, "w"))) { + fprintf(fp, "¡° [\033[1m¨t²Î³q§i\033[m] ³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); + Link(fpath, genbuf); + unlink(fpath); + strcpy(fpath, genbuf); + + strcpy(mymail.owner, cuser.userid); /*¯¸ªø ID*/ + strcpy(mymail.title, save_title); + mymail.savemode = 0; + + sethomedir(genbuf, cuser.userid); + if(append_record(genbuf, &mymail, sizeof(mymail)) == -1) + outs(err_uid); + + for(unum = uhash->number, i = 0; i < unum; i++) { + if(bad_user_id(uhash->userid[i])) + continue; /* Ptt */ + + userid = uhash->userid[i]; + if(strcmp(userid,STR_GUEST) && strcmp(userid, "new") && + strcmp(userid, cuser.userid)) { + sethomepath(genbuf, userid); + stampfile(genbuf, &mymail); + unlink(genbuf); + Link(fpath, genbuf); + + strcpy(mymail.owner, cuser.userid); + strcpy(mymail.title, save_title); + mymail.savemode = 0; + /* mymail.filemode |= FILE_MARKED; Ptt ¤½§i§ï¦¨¤£·|mark */ + sethomedir(genbuf, userid); + if(append_record(genbuf, &mymail, sizeof(mymail)) == -1) + outs(err_uid); + sprintf(genbuf, "%*s %5d / %5d", IDLEN + 1, userid, i + 1, unum); + outmsg(genbuf); + refresh(); + } + } + return 0; +} + +int mail_mbox() { + char cmd[100]; + fileheader_t fhdr; + + sprintf(cmd, "/tmp/%s.uu", cuser.userid); + sprintf(fhdr.title, "%s ¨p¤H¸ê®Æ", cuser.userid); + doforward(cmd, &fhdr, 'Z'); + return 0; +} + +static int m_forward(int ent, fileheader_t *fhdr, char *direct) { + char uid[STRLEN]; + + stand_title("Âà¹F«H¥ó"); + usercomplete(msg_uid, uid); + if(uid[0] == '\0') + return FULLUPDATE; + + strcpy(quote_user, fhdr->owner); + setuserfile(quote_file, fhdr->filename); + sprintf(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(); + return FULLUPDATE; +} + +static int delmsgs[128]; +static int delcnt; +static int mrd; + +static int read_new_mail(fileheader_t *fptr) { + static int idc; + char done = NA, delete_it; + char fname[256]; + char genbuf[4]; + + if(fptr == NULL) { + delcnt = 0; + idc = 0; + return 0; + } + idc++; + if(fptr->filemode) + return 0; + clear(); + move(10, 0); + prints("±znŪ¨Ó¦Û[%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), idc)) + return -1; + + mrd = 1; + delete_it = NA; + while(!done) { + int more_result = more(fname, YEA); + + switch(more_result) { + case 1: + return READ_PREV; + case 2: + return RELATE_PREV; + case 3: + return READ_NEXT; + case 4: + return RELATE_NEXT; + case 5: + return RELATE_FIRST; + case 6: + return 0; + case 7: + mail_reply(idc, fptr, currmaildir); + return FULLUPDATE; + case 8: + multi_reply(idc, fptr, currmaildir); + return FULLUPDATE; + } + move(b_lines, 0); + clrtoeol(); + outs(msg_mailer); + refresh(); + + switch(egetch()) { + case 'r': + case 'R': + mail_reply(idc, fptr, currmaildir); + break; + case 'x': + m_forward(idc, fptr, currmaildir); + break; + case 'y': + multi_reply(idc, fptr, currmaildir); + break; + case 'd': + case 'D': + delete_it = YEA; + default: + done = YEA; + } + } + if(delete_it) { + clear(); + prints("§R°£«H¥ó¡m%s¡n", fptr->title); + getdata(1, 0, msg_sure_ny, genbuf, 2, LCECHO); + if(genbuf[0] == 'y') { + unlink(fname); + delmsgs[delcnt++] = idc; + } + } + clear(); + return 0; +} + +int m_new() { + clear(); + mrd = 0; + setutmpmode(RMAIL); + read_new_mail(NULL); + clear(); + curredit |= EDIT_MAIL; + curredit &= ~EDIT_ITEM; + if(apply_record(currmaildir, read_new_mail, sizeof(fileheader_t)) == -1) { + outs("¨S¦³·s«H¥ó¤F"); + pressanykey(); + return -1; + } + curredit = 0; + if(delcnt) { + while(delcnt--) + delete_record(currmaildir, sizeof(fileheader_t), delmsgs[delcnt]); + } + outs(mrd ? "«H¤w¾\\²¦" : "¨S¦³·s«H¥ó¤F"); + pressanykey(); + return -1; +} + +static void mailtitle() { + char buf[256] = ""; + + showtitle("\0¶l¥ó¿ï³æ", BBSName); + sprintf(buf,"[¡ö]Â÷¶}[¡ô¡õ]¿ï¾Ü[¡÷]¾\\Ū«H¥ó [R]¦^«H [x]Âà¹F " + "[y]¸s²Õ¦^«H [O]¯¸¥~«H:%s [h]¨D§U\n\033[7m" + "½s¸¹ ¤é ´Á §@ ªÌ «H ¥ó ¼Ð ÃD \033[32m", + HAS_PERM(PERM_NOOUTMAIL)? "\033[31mÃö\033[m":"¶}"); + outs(buf); + buf[0]=0; + if(mailsumlimit) { + sprintf(buf,"(®e¶q:%d/%dk %d/%d½g)", mailsum, mailsumlimit, + mailkeep, mailmaxkeep); + } + sprintf(buf, "%s%*s\033[m", buf, 29 - (int) strlen(buf), ""); + outs(buf); +} + +static void maildoent(int num, fileheader_t *ent) { + char *title, *mark, color, type = "+ Mm"[ent->filemode]; + + if (TagNum && !Tagger(atoi(ent->filename + 2), 0, TAG_NIN)) + type = 'D'; + + title = subject(mark = ent->title); + if(title == mark) { + color = '1'; + mark = "¡º"; + } else { + color = '3'; + mark = "R:"; + } + + if(strncmp(currtitle, title, 40)) + prints("%5d %c %-7s%-15.14s%s %.46s\n", num, type, + ent->date, ent->owner, mark, title); + else + prints("%5d %c %-7s%-15.14s\033[1;3%cm%s %.46s\033[0m\n", num, type, + ent->date, ent->owner, color, mark, title); +} + +#ifdef POSTBUG +extern int bug_possible; +#endif + + +static int m_idle(int ent, fileheader_t *fhdr, char *direct) { + t_idle(); + return FULLUPDATE; +} + +static int mail_del(int ent, fileheader_t *fhdr, char *direct) { + char genbuf[200]; + + if(fhdr->filemode & FILE_MARKED) + return DONOTHING; + + getdata(1, 0, msg_del_ny, genbuf, 3, LCECHO); + if(genbuf[0] == 'y') { + strcpy(currfile, fhdr->filename); + if(!delete_file(direct, sizeof(*fhdr), ent, cmpfilename)) { + setdirpath(genbuf, direct, fhdr->filename); + unlink(genbuf); + if((currmode & MODE_SELECT)) { + int now; + + sethomedir(genbuf, cuser.userid); + now = getindex(genbuf, fhdr->filename, sizeof(fileheader_t)); + delete_file(genbuf, sizeof(fileheader_t), now, cmpfilename); + } + return DIRCHANGED; + } + } + return FULLUPDATE; +} + +static int mail_read(int ent, fileheader_t *fhdr, char *direct) { + char buf[64]; + char done, delete_it, replied; + + clear(); + setdirpath(buf, direct, fhdr->filename); + strncpy(currtitle, subject(fhdr->title), 40); + done = delete_it = replied = NA; + while(!done) { + int more_result = more(buf, YEA); + + if(more_result != -1) { + fhdr->filemode |= FILE_READ; + if((currmode & MODE_SELECT)) { + int now; + + now = getindex(currmaildir, fhdr->filename, + sizeof(fileheader_t)); + substitute_record(currmaildir, fhdr, sizeof(*fhdr), now); + substitute_record(direct, fhdr, sizeof(*fhdr), ent); + } + else + substitute_record(currmaildir, fhdr, sizeof(*fhdr), ent); + } + switch(more_result) { + case 1: + return READ_PREV; + case 2: + return RELATE_PREV; + case 3: + return READ_NEXT; + case 4: + return RELATE_NEXT; + case 5: + return RELATE_FIRST; + case 6: + return FULLUPDATE; + case 7: + mail_reply(ent, fhdr, direct); + return FULLUPDATE; + case 8: + multi_reply(ent, fhdr, direct); + return FULLUPDATE; + } + move(b_lines, 0); + clrtoeol(); + refresh(); + outs(msg_mailer); + + switch(egetch()) { + case 'r': + case 'R': + replied = YEA; + mail_reply(ent, fhdr, direct); + break; + case 'x': + m_forward(ent, fhdr, direct); + break; + case 'y': + multi_reply(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; +#ifdef POSTBUG + if(replied) + bug_possible = YEA; +#endif + if((currmode & MODE_SELECT)) { + int now; + + now = getindex(currmaildir, fhdr->filename, sizeof(fileheader_t)); + substitute_record(currmaildir, fhdr, sizeof(*fhdr), now); + substitute_record(direct, fhdr, sizeof(*fhdr), ent); + } else + substitute_record(currmaildir, fhdr, sizeof(*fhdr), ent); +#ifdef POSTBUG + bug_possible = NA; +#endif + } + return FULLUPDATE; +} + +/* in boards/mail ¦^«Hµ¹ì§@ªÌ¡AÂà«H¯¸¥ç¥i */ +int mail_reply(int ent, fileheader_t *fhdr, char *direct) { + char uid[STRLEN]; + char *t; + FILE *fp; + char genbuf[512]; + + 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 */ + strcpy(quote_user, fhdr->owner); + if(strchr(quote_user, '.')) { + genbuf[0] = '\0'; + if((fp = fopen(quote_file, "r"))) { + fgets(genbuf, 512, fp); + fclose(fp); + } + + t = strtok(genbuf, str_space); + if(!strcmp(t, str_author1) || !strcmp(t, str_author2)) + strcpy(uid, strtok(NULL, str_space)); + else { + outs("¿ù»~: §ä¤£¨ì§@ªÌ¡C"); + pressanykey(); + return FULLUPDATE; + } + } else + strcpy(uid, quote_user); + + /* 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; + } + curredit = ent; + pressanykey(); + return FULLUPDATE; +} + +static int mail_edit(int ent, fileheader_t *fhdr, char *direct) { + char genbuf[200]; + + if(!HAS_PERM(PERM_SYSOP) && + strcmp(cuser.userid, fhdr->owner) && + strcmp("[³Æ.§Ñ.¿ý]", fhdr->owner)) + return DONOTHING; + + setdirpath(genbuf, direct, fhdr->filename); + vedit(genbuf, NA, NULL); + return FULLUPDATE; +} + +static int mail_nooutmail(int ent, fileheader_t *fhdr, char *direct) +{ + cuser.userlevel ^= PERM_NOOUTMAIL; + passwd_update(usernum, &cuser); + return FULLUPDATE; + +} + +static int mail_mark(int ent, fileheader_t *fhdr, char *direct) { + fhdr->filemode ^= FILE_MARKED; + + if((currmode & MODE_SELECT)) { + int now; + + now = getindex(currmaildir, fhdr->filename, sizeof(fileheader_t)); + substitute_record(currmaildir, fhdr, sizeof(*fhdr), now); + substitute_record(direct, fhdr, sizeof(*fhdr), ent); + } else + substitute_record(currmaildir, fhdr, sizeof(*fhdr), ent); + return PART_REDRAW; +} + +/* help for mail reading */ +static char *mail_help[] = { + "\0¹q¤l«H½c¾Þ§@»¡©ú", + "\01°ò¥»©R¥O", + "(p)(¡ô) «e¤@½g¤å³¹", + "(n)(¡õ) ¤U¤@½g¤å³¹", + "(P)(PgUp) «e¤@¶", + "(N)(PgDn) ¤U¤@¶", + "(##)(cr) ¸õ¨ì²Ä ## µ§", + "($) ¸õ¨ì³Ì«á¤@µ§", + "\01¶i¶¥©R¥O", + "(r)(¡÷)/(R)Ū«H / ¦^«H", + "(O) Ãö³¬/¶}±Ò ¯¸¥~«H¥óÂà¤J", + "(c/z) ¦¬¤J¦¹«H¥ó¶i¤J¨p¤H«H¥ó§¨/¶i¤J¨p¤H«H¥ó§¨", + "(x/X) Âà¹F«H¥ó/Âà¿ý¤å³¹¨ì¨ä¥L¬ÝªO", + "(y) ¸s²Õ¦^«H", + "(F) ±N«H¶Ç°e¦^±zªº¹q¤l«H½c (u)¤ô²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() { + show_help(mail_help); + return FULLUPDATE; +} + +static int mail_cross_post(int ent, fileheader_t *fhdr, 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]; + + make_blist(); + move(2, 0); + clrtoeol(); + move(3, 0); + clrtoeol(); + move(1, 0); + namecomplete("Âà¿ý¥»¤å³¹©ó¬ÝªO¡G", xboard); + if(*xboard == '\0' || !haspostperm(xboard)) + return FULLUPDATE; + + ent = 1; + if(HAS_PERM(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) + sprintf(xtitle, "[Âà¿ý]%.66s", fhdr->title); + else + strcpy(xtitle, fhdr->title); + + sprintf(genbuf, "±Ä¥Îì¼ÐÃD¡m%.60s¡n¶Ü?[Y] ", xtitle); + getdata(2, 0, genbuf, genbuf2, 4, LCECHO); + if(*genbuf2 == 'n') + if(getdata(2, 0, "¼ÐÃD¡G", genbuf, TTLEN, DOECHO)) + strcpy(xtitle, genbuf); + + 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) + strcpy(xfile.owner, fhdr->owner); + else + strcpy(xfile.owner, cuser.userid); + strcpy(xfile.title, xtitle); + if(genbuf[0] == 'l') { + xfile.savemode = 'L'; + xfile.filemode = FILE_LOCAL; + } else + xfile.savemode = 'S'; + + setuserfile(fname, fhdr->filename); + if(ent) { + xptr = fopen(xfpath, "w"); + + strcpy(save_title, xfile.title); + strcpy(xfpath, currboard); + strcpy(currboard, xboard); + write_header(xptr); + strcpy(currboard, xfpath); + + fprintf(xptr, "¡° [¥»¤åÂà¿ý¦Û %s «H½c]\n\n", cuser.userid); + + b_suckinfile(xptr, fname); + addsignature(xptr,0); + fclose(xptr); + } else { + unlink(xfpath); + Link(fname, xfpath); + } + + setbdir(fname, xboard); + append_record(fname, &xfile, sizeof(xfile)); + setbtotal(getbnum(xboard)); + if(!xfile.filemode) + outgo_post(&xfile, xboard); + cuser.numposts++; + passwd_update(usernum, &cuser); + outs("¤å³¹Âà¿ý§¹¦¨"); + pressanykey(); + currmode = currmode0; + } + return FULLUPDATE; +} + +int mail_man() { + char buf[64],buf1[64]; + if (HAS_PERM(PERM_MAILLIMIT)) { + int mode0 = currutmp->mode; + int stat0 = currstat; + + sethomeman(buf, cuser.userid); + sprintf(buf1, "%s ªº«H¥ó§¨", cuser.userid); + a_menu(buf1, buf, 1); + currutmp->mode = mode0; + currstat = stat0; + return FULLUPDATE; + } + return DONOTHING; +} + +static int mail_cite(int ent, fileheader_t *fhdr, char *direct) { + char fpath[256]; + char title[TTLEN + 1]; + static char xboard[20]; + char buf[20]; + boardheader_t *bp; + + setuserfile(fpath, fhdr->filename); + strcpy(title, "¡º "); + strncpy(title+3, fhdr->title, TTLEN-3); + title[TTLEN] = '\0'; + a_copyitem(fpath, title, 0, 1); + + if(cuser.userlevel >= PERM_BM) { + move(2, 0); + clrtoeol(); + move(3, 0); + clrtoeol(); + move(1, 0); + make_blist(); + namecomplete("¿é¤J¬Ýª©¦WºÙ (ª½±µEnter¶i¤J¨p¤H«H¥ó§¨)¡G", buf); + if(*buf) + strcpy(xboard, buf); + if(*xboard && (bp = getbcache(getbnum(xboard)))) { + setapath(fpath, xboard); + setutmpmode(ANNOUNCE); + a_menu(xboard, fpath, HAS_PERM(PERM_ALLBOARD) ? 2 : + is_BM(bp->BM) ? 1 : 0); + } else { + mail_man(); + } + return FULLUPDATE; + } else { + mail_man(); + return FULLUPDATE; + } +} + +static int mail_save(int ent, fileheader_t *fhdr, char *direct) { + char fpath[256]; + char title[TTLEN+1]; + + if(HAS_PERM(PERM_MAILLIMIT)) { + setuserfile(fpath, fhdr->filename); + strcpy(title, "¡º "); + strncpy(title + 3, fhdr->title, TTLEN - 3); + title[TTLEN] = '\0'; + a_copyitem(fpath, title, fhdr->owner, 1); + sethomeman(fpath, cuser.userid); + a_menu(cuser.userid, fpath, 1); + return FULLUPDATE; + } + return DONOTHING; +} + +#ifdef OUTJOBSPOOL +static int mail_waterball(int ent, fileheader_t *fhdr, char *direct) +{ + static char address[60], cmode = 1; + char fname[500], genbuf[200]; + FILE *fp; + int now; + + if(!address[0]) + strcpy(address, cuser.email); + if(address[0]) { + sprintf(genbuf, "±Hµ¹ [%s] ¶Ü(Y/N/Q)¡H[Y] ", address); + getdata(b_lines - 2, 0, genbuf, fname, 3, LCECHO); + if(fname[0] == 'q') { outmsg("¨ú®ø³B²z"); return 1; } + if(fname[0] == 'n') + address[0] = '\0'; + } + + if(!address[0]) { + getdata(b_lines - 2, 0, "½Ð¿é¤J¶l¥ó¦a§}¡G", fname, 60, DOECHO); + if(fname[0] && strchr(fname, '.')) { + strcpy(address, fname); + } else { + outmsg("¨ú®ø³B²z"); + return 1; + } + } + if(invalidaddr(address)) + return -2; + + // sprintf(fname, "%d\n", cmode); + getdata(b_lines - 1, 0, "¨Ï¥Î¼Ò¦¡(0/1)? [1]", fname, 3, LCECHO); + cmode = (fname[0] != '0' && fname[0] != '1') ? 1 : fname[0] - '0'; + + now = time(NULL); + sprintf(fname, BBSHOME "/jobspool/water.src.%s-%d", + cuser.userid, now); + sprintf(genbuf, "cp " BBSHOME "/home/%c/%s/%s %s", + cuser.userid[0], cuser.userid, fhdr->filename, fname); + system(genbuf); + /* dirty code ;x */ + sprintf(fname, BBSHOME "/jobspool/water.des.%s-%d", + cuser.userid, now); + fp = fopen(fname, "wt"); + fprintf(fp, "%s\n%s\n%d\n", cuser.userid, address, cmode); + fclose(fp); + return FULLUPDATE; +} +#endif +static struct onekey_t mail_comms[] = { + {'z', mail_man}, + {'c', mail_cite}, + {'s', mail_save}, + {'d', mail_del}, + {'D', del_range}, + {'r', mail_read}, + {'R', mail_reply}, + {'E', mail_edit}, + {'m', mail_mark}, + {'O', mail_nooutmail}, + {'T', edit_title}, + {'x', m_forward}, + {'X', mail_cross_post}, + {Ctrl('G'), built_mail_index}, /* ׫H½c */ + {'y', multi_reply}, + {Ctrl('I'), m_idle}, + {'h', m_help}, +#ifdef OUTJOBSPOOL + {'u', mail_waterball}, +#endif + {'\0', NULL} +}; + +int m_read() { + if(get_num_records(currmaildir, sizeof(fileheader_t))) { + curredit = EDIT_MAIL; + curredit &= ~EDIT_ITEM; + i_read(RMAIL, currmaildir, mailtitle, maildoent, mail_comms, -1); + curredit = 0; + currutmp->mailalert = load_mailalert(cuser.userid); + return 0; + } else { + outs("±z¨S¦³¨Ó«H"); + return XEASY; + } +} + +/* ±H¯¸¤º«H */ +static int send_inner_mail(char *fpath, char *title, char *receiver) { + char genbuf[256]; + fileheader_t mymail; + + if(!searchuser(receiver)) + return -2; + sethomepath(genbuf, receiver); + stampfile(genbuf, &mymail); + if(!strcmp(receiver, cuser.userid)) { + strcpy(mymail.owner, "[" BBSNAME "]"); + mymail.filemode = FILE_READ; + } else + strcpy(mymail.owner, cuser.userid); + strncpy(mymail.title, title, TTLEN); + unlink(genbuf); + Link(fpath, genbuf); + sethomedir(genbuf, receiver); + return do_append(genbuf, &mymail, sizeof(mymail)); +} + +#include <netdb.h> +#include <pwd.h> +#include <time.h> + +#ifndef USE_BSMTP +static int bbs_sendmail(char *fpath, char *title, char *receiver) { + static int configured = 0; + static char myhostname[STRLEN]; + static char myusername[20]; + struct hostent *hbuf; + struct passwd *pbuf; + char *ptr; + char genbuf[256]; + FILE *fin, *fout; + + /* ¤¤³~ÄdºI */ + if((ptr = strchr(receiver, ';'))) { + struct tm *ptime; + time_t now; + + *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 + strcpy(hacker,receiver); + return send_inner_mail(fpath, title, hacker); + } + + /* setup the hostname and username */ + if(!configured) { + /* get host name */ + hbuf = gethostbyname("localhost"); + if(hbuf) + strncpy(myhostname, hbuf->h_name, STRLEN); + + /* get bbs uident */ + pbuf = getpwuid(getuid()); + if(pbuf) + strncpy(myusername, pbuf->pw_name, 20); + if(hbuf && pbuf) + configured = 1; + else + return -1; + } + + /* Running the sendmail */ + if(fpath == NULL) { + sprintf(genbuf, "/usr/sbin/sendmail %s > /dev/null", receiver); + fin = fopen("etc/confirm", "r"); + } else { + sprintf(genbuf, "/usr/sbin/sendmail -f %s%s %s > /dev/null", + cuser.userid, str_mail_address, receiver); + fin = fopen(fpath, "r"); + } + fout = popen(genbuf, "w"); + if(fin == NULL || fout == NULL) + return -1; + + if(fpath) + fprintf(fout, "Reply-To: %s%s\nFrom: %s%s\n", + cuser.userid, str_mail_address, cuser.userid, + str_mail_address); + fprintf(fout, "To: %s\nSubject: %s\n", receiver, title); + fprintf(fout, "X-Disclaimer: " BBSNAME "¹ï¥»«H¤º®e®¤¤£t³d¡C\n\n"); + + while(fgets(genbuf, 255, 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(char *fpath, char *title, char *rcpt, int method) { + char buf[80], *ptr; + time_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 + strcpy(hacker, rcpt); + return send_inner_mail(fpath, title, hacker); + } + + chrono = time(NULL); + if(method != MQ_JUSTIFY) { /* »{ÃÒ«H */ + /* stamp the queue file */ + strcpy(buf, "out/"); + for(;;) { + sprintf(buf + 4,"M.%ld.A", ++chrono); + if(!dashf(buf)) { + Link(fpath, buf); + break; + } + } + + fpath = buf; + + strcpy(mqueue.filepath, fpath); + strcpy(mqueue.subject, title); + } + /* setup mail queue */ + mqueue.mailtime = chrono; + mqueue.method = method; + strcpy(mqueue.sender, cuser.userid); + strcpy(mqueue.username, cuser.username); + strcpy(mqueue.rcpt, rcpt); + if(do_append("out/.DIR", (fileheader_t *)&mqueue, sizeof(mqueue)) < 0) + return 0; + return chrono; +} +#endif /* USE_BSMTP */ + +int doforward(char *direct, fileheader_t *fh, int mode) { + static char address[60]; + char fname[500]; + int return_no; + char genbuf[200]; + + if(!address[0]) + strcpy(address, cuser.email); + + if(address[0]) { + sprintf(genbuf, "½T©wÂà±Hµ¹ [%s] ¶Ü(Y/N/Q)¡H[Y] ", address); + getdata(b_lines - 1, 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, '.')) + strcpy(address, fname); + else + sprintf(address, "%s.bbs@%s", fname, MYHOSTNAME); + } else { + outmsg("¨ú®øÂà±H"); + return 1; + } + }while(mode=='Z' && strstr(address, MYHOSTNAME)); + } + if(invalidaddr(address)) + return -2; + + sprintf(fname, "¥¿Âà±Hµ¹ %s, ½ÐµyÔ...", address); + outmsg(fname); + move(b_lines - 1, 0); + refresh(); + + /* °lÂÜ¨Ï¥ÎªÌ */ + if(HAS_PERM(PERM_LOGUSER)) { + time_t now = time(NULL); + char msg[200]; + + sprintf(msg, "%s mailforward to %s at %s", + cuser.userid, address, Cdate(&now)); + log_user(msg); + } + + if(mode == 'Z') { + sprintf(fname, TAR_PATH " cfz - home/%c/%s | " + "/usr/bin/uuencode %s.tgz > %s", + cuser.userid[0], cuser.userid, cuser.userid, direct); + system(fname); + strcpy(fname, direct); + } else if(mode == 'U') { + char tmp_buf[128]; + + sprintf(fname, "/tmp/bbs.uu%05d", currpid); + sprintf(tmp_buf, "/usr/bin/uuencode %s/%s uu.%05d > %s", + direct, fh->filename, currpid, fname); + system(tmp_buf); + } else if (mode == 'F'){ + char tmp_buf[128]; + + sprintf(fname, "/tmp/bbs.f%05d", currpid); + sprintf(tmp_buf, "cp %s/%s %s",direct,fh->filename,fname); + system(tmp_buf); + } else + return -1; + + return_no = +#ifndef USE_BSMTP + bbs_sendmail(fname, fh->title, address); +#else + bsmtp(fname, fh->title, address,mode); +#endif + unlink(fname); + return (return_no); +} + +int load_mailalert(char *userid) { + struct stat st; + char maildir[256]; + int fd; + register int numfiles; + fileheader_t my_mail; + + sethomedir(maildir, userid); + if(!HAS_PERM(PERM_BASIC)) + return 0; + if(stat(maildir, &st) < 0) + return 0; + numfiles = st.st_size / sizeof(fileheader_t); + if(numfiles <= 0) + return 0; + + /* ¬Ý¬Ý¦³¨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(numfiles--) { + read(fd, &my_mail, sizeof(fileheader_t)); + if(!(my_mail.filemode & FILE_READ)) { + close(fd); + return 1; + } + lseek(fd, -(off_t)2 * sizeof(fileheader_t), SEEK_CUR); + } + close(fd); + } + return 0; +} + +#ifdef EMAIL_JUSTIFY +static void mail_justify(userec_t muser) { + fileheader_t mhdr; + char title[128], buf1[80]; + FILE* fp; + + sethomepath(buf1, muser.userid); + stampfile(buf1, &mhdr); + unlink(buf1); + strcpy(mhdr.owner, cuser.userid); + strncpy(mhdr.title, "[¼f®Ö³q¹L]", TTLEN); + mhdr.savemode = 0; + mhdr.filemode = 0; + + if(valid_ident(muser.email) && !invalidaddr(muser.email)) { + char title[80], *ptr; + unsigned short checksum; /* 16-bit is enough */ + char ch; + + checksum = searchuser(muser.userid); + ptr = muser.email; + while((ch = *ptr++)) { + if(ch <= ' ') + break; + if(ch >= 'A' && ch <= 'Z') + ch |= 0x20; + checksum = (checksum << 1) ^ ch; + } + + sprintf(title, "[PTT BBS]To %s(%d:%d) [User Justify]", + muser.userid, getuser(muser.userid) + MAGIC_KEY, checksum); + if( +#ifndef USE_BSMTP + bbs_sendmail(NULL, title, muser.email) +#else + bsmtp(NULL, title, muser.email, MQ_JUSTIFY); +#endif + < 0) + Link("etc/bademail", buf1); + else + Link("etc/replyemail", buf1); + } else + Link("etc/bademail", buf1); + sethomedir(title, muser.userid); + append_record(title, &mhdr, sizeof(mhdr)); +} +#endif /* EMAIL_JUSTIFY */ diff --git a/mbbsd/mbbsd.c b/mbbsd/mbbsd.c new file mode 100644 index 00000000..c4849da5 --- /dev/null +++ b/mbbsd/mbbsd.c @@ -0,0 +1,1465 @@ +/* $Id: mbbsd.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <setjmp.h> +#include <signal.h> +#include <unistd.h> +#include <fcntl.h> +#include <syslog.h> +#include <errno.h> +#include <netdb.h> +#include <time.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <sys/socket.h> +#include <sys/time.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <arpa/telnet.h> +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "perm.h" +#include "modes.h" +#include "proto.h" +#ifdef FreeBSD + #include <machine/limits.h> +#else + #include <limits.h> +#endif + +#define SOCKET_QLEN 4 +#define TH_LOW 100 +#define TH_HIGH 120 + +extern int t_lines, t_columns; /* Screen size / width */ +extern int b_lines; /* Screen bottom line number: t_lines-1 */ +extern userinfo_t *currutmp; +extern int curr_idle_timeout; + +static void do_aloha (char *hello); + +static jmp_buf byebye; + +int talkrequest = NA; + +static char remoteusername[40] = "?"; + +extern struct fromcache_t *fcache; +extern struct utmpfile_t *utmpshm; +extern int fcache_semid; + +static unsigned char enter_uflag; +static int use_shell_login_mode = 0; + +char fromhost[STRLEN] = "\0"; + +static struct sockaddr_in xsin; + +/* 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 () +{ + int n; + char buf[80]; + + /* + * 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); + + strftime (buf, 80, "%d/%b/%Y:%H:%M:%S", dummy_time); + + if ((n = fork ())){ + exit (0); + } + + /* rocker.011018: it's a good idea to close all unexcept fd!! */ + n = getdtablesize (); + while (n) + close (--n); + /* 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 */ + if ((n = fork ())){ + exit (0); + } +} + +static void +reapchild (int sig) +{ + int state, pid; + + while ((pid = waitpid (-1, &state, WNOHANG | WUNTRACED)) > 0) + ; +} + +#define BANNER \ +"¡i" BBSNAME "¡j¡· ¥x¤j¬y¦æºô ¡·(" MYHOSTNAME ") ½Õ´T(" MYIP ") " +/* +#define BANNER \ +"¡i" BBSNAME "¡j¡· ¥x¤j¬y¦æºô ¡·(" MYHOSTNAME ")\r\n"\ +" ½Õ´T(" MYIP ") " +*/ +/* check load and print approriate banner string in buf */ +static int +chkload (char *buf) +{ + char cpu_load[30]; + int i; + + i = cpuload (cpu_load); + + sprintf (buf, BANNER" ¨t²Ît²ü\r\n %s %s \r\n", cpu_load, + (i > MAX_CPULOAD ? "¡A°ªt²ü¶q¡A½Ðµy«á¦A¨Ó " + "(½Ð§Q¥Îport 3000~3010³s½u)" : "")); +#ifdef INSCREEN + strcpy(buf, (i > MAX_CPULOAD ? BANNER + "°ªt²ü¶q¡A½Ðµy«á¦A¨Ó(½Ð§Q¥Îport 3000~3010³s½u)" : "")); +#else + sprintf(buf, BANNER "%s\r\n", + (i > MAX_CPULOAD ? "°ªt²ü¶q¡A½Ðµy«á¦A¨Ó(½Ð§Q¥Îport 3000~3010³s½u)":"")); +#endif + if (i > MAX_CPULOAD) + return 1; + else if (i > MAX_CPULOAD / 2) + curr_idle_timeout = 10 * 60; + else + curr_idle_timeout = 30 * 60; + + return 0; +} + +extern userec_t cuser; + +void +log_user (char *msg) +{ + char filename[200]; + + sprintf (filename, BBSHOME "/home/%c/%s/USERLOG", + cuser.userid[0], cuser.userid); + log_file (filename, msg); +} + +extern time_t login_start_time; + +void +log_usies (char *mode, char *mesg) +{ + char genbuf[200]; + time_t now = time (0); + + if (!mesg) + sprintf (genbuf, cuser.userid[0] ? "%s %s %-12s Stay:%d (%s)" : + "%s %s %s Stay:%d (%s)", + Cdate (&now), mode, cuser.userid, + (int)(now - login_start_time) / 60, cuser.username); + else + sprintf (genbuf, cuser.userid[0] ? "%s %s %-12s %s" : "%s %s %s%s", + Cdate (&now), mode, cuser.userid, mesg); + log_file (FN_USIES, genbuf); + + /* °lÂÜ¨Ï¥ÎªÌ */ + if (HAS_PERM (PERM_LOGUSER)) + log_user (genbuf); +} + +static void +setflags (int mask, int value) +{ + if (value) + cuser.uflag |= mask; + else + cuser.uflag &= ~mask; +} + +extern int usernum; +extern int currmode; + +void +u_exit (char *mode) +{ + //userec_t xuser; + int diff = (time (0) - login_start_time) / 60; + + reload_money(); + auto_backup (); + save_brdbuf(); + setflags (PAGER_FLAG, currutmp->pager != 1); + setflags (CLOAK_FLAG, currutmp->invisible); + + cuser.invisible = currutmp->invisible; + cuser.pager = currutmp->pager; + cuser.mind = currutmp->mind; + if (!(HAS_PERM (PERM_SYSOP) && HAS_PERM (PERM_DENYPOST)) && + !currutmp->invisible ) + do_aloha ("<<¤U¯¸³qª¾>> -- §Ú¨«Åo¡I"); + + purge_utmp (currutmp); + if ((cuser.uflag != enter_uflag) || (currmode & MODE_DIRTY) || diff) + { + if (!diff && cuser.numlogins) + cuser.numlogins = --cuser.numlogins; + /* Leeym ¤W¯¸°±¯d®É¶¡¨î¦¡ */ + } + passwd_update (usernum, &cuser); + log_usies (mode, NULL); +} + +static void +system_abort () +{ + if (currmode) + u_exit ("ABORT"); + + clear (); + refresh (); + fprintf (stdout, "ÁÂÁÂ¥úÁ{, °O±o±`¨Ó³á !\n"); + exit (0); +} + +void +abort_bbs (int sig) +{ + if (currmode) + u_exit ("AXXED"); + exit (0); +} + +static void +abort_bbs_debug (int sig) +{ + static int reentrant = 0; + + if (!reentrant){ + reentrant = 1; + if (currmode) + u_exit ("AXXED"); + setproctitle("debug me!(%d)",sig); + sleep(3600); /* wait 60 mins for debug */ + } + exit (0); +} + +/* µn¿ý BBS µ{¦¡ */ +static void +mysrand () +{ + srand (time (NULL) + currutmp->pid); /* ®É¶¡¸ò pid ·í rand ªº seed */ +} + +extern userec_t xuser; + +int +dosearchuser (char *userid) +{ + if ((usernum = getuser (userid))) + memcpy (&cuser, &xuser, sizeof (cuser)); + else + memset (&cuser, 0, sizeof (cuser)); + return usernum; +} + +static void +talk_request () +{ + bell (); + bell (); + if (currutmp->msgcount){ + char buf[200]; + time_t now = time (0); + + sprintf (buf, "\033[33;41m¡¹%s\033[34;47m [%s] %s \033[0m", + utmpshm->uinfo[currutmp->destuip].userid, my_ctime (&now), + (currutmp->sig == 2)? "«n®ø®§¼s¼½¡I(½ÐCtrl-U,l¬d¬Ý¼ö°T°O¿ý)" + : "©I¥s¡B©I¥s¡AÅ¥¨ì½Ð¦^µª"); + move (0, 0); + clrtoeol (); + outs (buf); + refresh (); + } + else{ + unsigned char mode0 = currutmp->mode; + char c0 = currutmp->chatid[0]; + screenline_t *screen0 = calloc (t_lines, sizeof (screenline_t)); + extern screenline_t *big_picture; + + currutmp->mode = 0; + currutmp->chatid[0] = 1; + memcpy (screen0, big_picture, t_lines * sizeof (screenline_t)); + talkreply (); + currutmp->mode = mode0; + currutmp->chatid[0] = c0; + memcpy (big_picture, screen0, t_lines * sizeof (screenline_t)); + free (screen0); + redoscr (); + } +} + +extern char *fn_writelog; +FILE *fp_writelog = NULL; + +void +show_last_call_in (int save) +{ + char buf[200]; + sprintf (buf, "\033[1;33;46m¡¹%s\033[37;45m %s \033[m", + currutmp->msgs[0].userid, currutmp->msgs[0].last_call_in); + move (b_lines, 0); + clrtoeol (); + refresh (); + outmsg (buf); + + if (save){ + char genbuf[200]; + time_t now; + if (!fp_writelog){ + sethomefile (genbuf, cuser.userid, fn_writelog); + fp_writelog = fopen (genbuf, "a"); + } + if (fp_writelog){ + time (&now); + fprintf (fp_writelog, "%s \033[0m[%s]\n", buf, Cdatelite (&now)); + } + } +} + +extern unsigned int currstat; +water_t water[6], *swater[6], *water_which=&water[0]; +char water_usies=0; +extern int watermode; +static int add_history_water(water_t *w, 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(msgque_t *msg) +{ + int i,j; + water_t *tmp; + add_history_water(&water[0], msg); + for(i = 0 ; i < 5 && swater[i] ; i++ ) + if( swater[i]->pid == msg->pid ) + break; + if( i != 5 ){ + if( !swater[i] ){ + water_usies = i + 1; + swater[i] = &water[i + 1]; + strcpy(swater[i]->userid, msg->userid); + swater[i]->pid = msg->pid; + } + tmp = swater[i]; + } + else{ + tmp = swater[4]; + memset(swater[4], 0, sizeof (water_t)); + strcpy(swater[4]->userid, msg->userid); + swater[4]->pid = msg->pid; + i = 4; + } + + 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; +} + +static void +write_request (int sig) +{ + struct tm *ptime; + time_t now; + + time (&now); + ptime = localtime (&now); + + if (currutmp->pager != 0 && + 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) + { + int i; + char c0 = currutmp->chatid[0]; + int currstat0 = currstat; + unsigned char mode0 = currutmp->mode; + + currutmp->mode = 0; + currutmp->chatid[0] = 2; + currstat = XMODE; + + do + { + bell (); + show_last_call_in (1); + igetch (); + currutmp->msgcount--; + if (currutmp->msgcount >= MAX_MSGS) + { + /* this causes chaos... jochang */ + raise (SIGFPE); + } + + add_history(&currutmp->msgs[0]); + for (i = 0; i < currutmp->msgcount; i++) + currutmp->msgs[i] = currutmp->msgs[i + 1]; + } + while (currutmp->msgcount); + currutmp->chatid[0] = c0; + currutmp->mode = mode0; + currstat = currstat0; + } + else + { + bell (); + show_last_call_in (1); + add_history(&currutmp->msgs[0]); + + refresh (); + currutmp->msgcount = 0; + } +} + +#if 0 +static void +write_request (int sig) +{ + int i, mtimemin, wu; + static char inlock = 0; + if( inlock ) /* ¦pªG¤w¸g¶i¨Ó¤F (ªí¥Ü¤WÓ¤ô²yÁÙ¨S¦³³B²z§¹, + ·sªº¤ô²y¤S¶i¨Ó) «h¤£°µ¥ô¦ó¨Æª½±µ return */ + return; + inlock = 1; + do{ + for( wu = 0 ; wu < 5 ; ++wu ) + if( water[wu].pid == currutmp->msgs[0].pid ) + break; + if( wu == 5 ){ + for( i = 0, mtimemin = INT_MAX ; i < 5 ; ++i ) + if( water[i].pid == 0 ){ + ++water_usies; + wu = i; + break; + } + else if( water[i].mtime < mtimemin ){ + mtimemin = water[i].mtime; + wu = i; + } + water[wu].pid = currutmp->msgs[0].pid; + strcpy(water[wu].userid, currutmp->msgs[0].userid); + water[wu].msgtop = 0; + for( i = 0 ; i < 5 ; ++i ) + water[wu].msg[i][0] = 0; + } + water[wu].mtime = time(NULL); + strncpy(water[wu].msg[ (int)water[wu].msgtop ], + currutmp->msgs[0].last_call_in, 64); + ++water[wu].msgtop; + water[wu].msgtop %= 5; + + bell (); + show_last_call_in (1); + refresh(); + + if( watermode == 0 ){ /* in waterball selection mode + if( wu != 0 ){ + water_scr(water_which, 0); + qsort(water, 5, sizeof(water_t), cmpwatermtime); + for( i = 0 ; i < 5 ; ++i ) + if( water[i].pid == 0 ) + break; + else + water_scr(i, 0); + water_scr(water_which = 0, 1); + refresh(); + } */ + } + --currutmp->msgcount; + for( i = 0 ; i < currutmp->msgcount - 1 ; ++i ) + currutmp->msgs[i] = currutmp->msgs[i + 1]; + } while( currutmp->msgcount > 0 ); + inlock = 0; +} +#endif + +static void +multi_user_check () +{ + register userinfo_t *ui; + register pid_t pid; + char genbuf[3]; + + if (HAS_PERM (PERM_SYSOP)) + return; /* don't check sysops */ + + if (cuser.userlevel){ + if (!(ui = (userinfo_t *) search_ulist (usernum))) + return; /* user isn't logged in */ + + pid = ui->pid; + if (!pid /*|| (kill(pid, 0) == -1) */ ) + return; /* stale entry in utmp file */ + + getdata (b_lines - 1, 0, "±z·Q§R°£¨ä¥L«½Æªº login (Y/N)¶Ü¡H[Y] ", + genbuf, 3, LCECHO); + + if (genbuf[0] != 'n'){ + if (pid > 0) + kill (pid, SIGHUP); + log_usies ("KICK ", cuser.username); + } + else{ + if (search_ulistn(usernum, 3)!=NULL) + system_abort (); /* Goodbye(); */ + } + } + else{ + /* allow multiple guest user */ + if (search_ulistn(usernum, 100)!=NULL){ + outs ("\n©êºp¡A¥Ø«e¤w¦³¤Ó¦h guest, ½Ðµy«á¦A¸Õ¡C\n"); + pressanykey (); + oflush (); + exit (1); + } + } +} + +/* bad login */ +static char str_badlogin[] = "logins.bad"; + +static void +logattempt (char *uid, char type) +{ + char fname[40]; + int fd, len; + char genbuf[200]; + + sprintf (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 == '-'){ + sprintf (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); + } + } +} + +extern char *str_new; +extern char *err_uid; + +static void +login_query () +{ + char uid[IDLEN + 1], passbuf[PASSLEN]; + int attempts; + char genbuf[200]; + extern struct utmpfile_t *utmpshm; + resolve_utmp (); + attach_uhash (); + attempts = utmpshm->number; + show_file ("etc/Welcome", 1, -1, NO_RELOAD); + output ("1", 1); + if (attempts >= MAX_ACTIVE){ + outs ("¥Ñ©ó¤H¼Æ¤Ó¦h¡A½Ð±zµy«á¦A¨Ó¡C\n"); + refresh (); + exit (1); + } + + /* hint */ + + attempts = 0; + while (1){ + if (attempts++ >= LOGINATTEMPTS){ + more ("etc/goodbye", NA); + pressanykey (); + exit (1); + } + getdata (20, 0, "½Ð¿é¤J¥N¸¹¡A©Î¥H[guest]°ÑÆ[¡A¥H[new]µù¥U¡G", + uid, IDLEN + 1, DOECHO); + if (strcasecmp (uid, str_new) == 0){ +#ifdef LOGINASNEW + new_register (); + break; +#else + outs ("¥»¨t²Î¥Ø«eµLªk¥H new µù¥U, ½Ð¥Î guest ¶i¤J\n"); + continue; +#endif + } + else if (uid[0] == '\0' || !dosearchuser (uid)){ + outs (err_uid); + } + else if (strcmp (uid, STR_GUEST)){ + getdata (21, 0, MSG_PASSWD, passbuf, PASSLEN, NOECHO); + passbuf[8] = '\0'; + + if (!checkpasswd (cuser.passwd, passbuf) + /* || (HAS_PERM(PERM_SYSOP) && !use_shell_login_mode) */ ){ + logattempt (cuser.userid, '-'); + outs (ERR_PASSWD); + } + else{ + logattempt (cuser.userid, ' '); + if (strcasecmp ("SYSOP", cuser.userid) == 0) + cuser.userlevel = PERM_BASIC | PERM_CHAT | PERM_PAGE | + PERM_POST | PERM_LOGINOK | PERM_MAILLIMIT | + PERM_CLOAK | PERM_SEECLOAK | PERM_XEMPT | + PERM_DENYPOST | PERM_BM | PERM_ACCOUNTS | + PERM_CHATROOM | PERM_BOARD | PERM_SYSOP | PERM_BBSADM; + break; + } + } + else{ /* guest */ + cuser.userlevel = 0; + cuser.uflag = COLOR_FLAG | PAGER_FLAG | BRDSORT_FLAG | MOVIE_FLAG; + break; + } + } + multi_user_check (); + sethomepath (genbuf, cuser.userid); + mkdir (genbuf, 0755); +} + +void +add_distinct (char *fname, char *line) +{ + FILE *fp; + int n = 0; + + if ((fp = fopen (fname, "a+"))){ + char buffer[80]; + char tmpname[100]; + FILE *fptmp; + + strcpy (tmpname, fname); + 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); + unlink (fname); + rename (tmpname, fname); + } +} + +void +del_distinct (char *fname, char *line) +{ + FILE *fp; + int n = 0; + + if ((fp = fopen (fname, "r"))){ + char buffer[80]; + char tmpname[100]; + FILE *fptmp; + + strcpy (tmpname, fname); + 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)) + 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); + unlink (fname); + rename (tmpname, fname); + } +} + +#ifdef WHERE +static int +where (char *from) +{ + register int i = 0, count = 0, j; + + for (j = 0; j < fcache->top; j++){ + char *token = strtok (fcache->domain[j], "&"); + + i = 0; + count = 0; + while (token){ + if (strstr (from, token)) + count++; + token = strtok (NULL, "&"); + i++; + } + if (i == count) + break; + } + if (i != count) + return 0; + return j; +} +#endif + +static void +check_BM () +{ + int i; + boardheader_t *bhdr; + extern boardheader_t *bcache; + extern int numboards; + + cuser.userlevel &= ~PERM_BM; + for (i = 0, bhdr = bcache; i < numboards && !is_BM (bhdr->BM); i++, bhdr++) + ; +} + +extern pid_t currpid; +extern crosspost_t postrecord; + +static void +setup_utmp (int mode) +{ + userinfo_t uinfo; + /* + char buf[80]; + char remotebuf[1024]; + time_t now = time(NULL); + */ + memset (&uinfo, 0, sizeof (uinfo)); + uinfo.pid = currpid = getpid (); + uinfo.uid = usernum; + uinfo.mode = currstat = mode; + uinfo.msgcount = 0; + uinfo.mailalert = load_mailalert (cuser.userid); + if (!(cuser.numlogins % 20) && cuser.userlevel & PERM_BM) + check_BM (); /* Ptt ¦Û°Ê¨ú¤UÂ÷¾ªO¥DÅv¤O */ + + uinfo.userlevel = cuser.userlevel; + uinfo.sex = cuser.sex % 8; + uinfo.lastact = time (NULL); + + postrecord.times = 0; /* pºâcrosspost¼Æ */ + + strcpy (uinfo.userid, cuser.userid); + strcpy (uinfo.realname, cuser.realname); + strcpy (uinfo.username, cuser.username); + strncpy (uinfo.from, fromhost, 23); + + uinfo.five_win = cuser.five_win; + uinfo.five_lose = cuser.five_lose; + uinfo.five_tie = cuser.five_tie; + + uinfo.invisible = cuser.invisible % 2; + uinfo.pager = cuser.pager%5; + uinfo.mind = cuser.mind; + uinfo.brc_id = 0; +#ifdef WHERE + uinfo.from_alias = where (fromhost); +#else + uinfo.from_alias = 0; +#endif +#ifndef FAST_LOGIN + setuserfile (buf, "remoteuser"); + + strcpy (remotebuf, fromhost); + strcat (remotebuf, ctime (&now)); + remotebuf[strlen (remotebuf) - 1] = 0; + add_distinct (buf, remotebuf); +#endif + if (enter_uflag & CLOAK_FLAG) + uinfo.invisible = YEA; + getnewutmpent (&uinfo); +#ifndef _BBS_UTIL_C_ + friend_load (); +#endif +} + +extern char margs[]; +extern char *str_sysop; +extern char *loginview_file[NUMVIEWFILE][2]; + +static void +user_login () +{ + char ans[4], i; + char genbuf[200]; + struct tm *ptime, *tmp; + time_t now; + int a; + /*** Heat:¼s§iµü + char *ADV[] = { + "7/17 @LIVE ¶Ã¼u, ¦óªYÁJ ªº ¤J³õ¨÷n°eµ¹ ptt ªº·R¥ÎªÌ!", + "±ýª¾¸Ô±¡½Ð¬Ý PttAct ªO!!", + }; ***/ + + log_usies ("ENTER", fromhost); + setproctitle ("%s: %s", margs, cuser.userid); + resolve_garbage (); + resolve_fcache (); + resolve_boards (); + memset( &water[0],0,sizeof(water_t) * 6); + strcpy(water[0].userid, " ¥þ³¡ "); + /* ªì©l¤Æ uinfo¡Bflag¡Bmode */ + setup_utmp (LOGIN); + mysrand (); /* ªì©l¤Æ: random number ¼W¥[user¸ò®É¶¡ªº®t²§ */ + currmode = MODE_STARTED; + enter_uflag = cuser.uflag; + + /* get local time */ + time (&now); + ptime = localtime (&now); + tmp = localtime (&cuser.lastlogin); + if ((a = utmpshm->number) > fcache->max_user){ + fcache->max_user = a; + fcache->max_time = now; + } + init_brdbuf(); + brc_initial (DEFAULT_BOARD); + set_board (); + /* µe±³B²z¶}©l */ + if (!(HAS_PERM (PERM_SYSOP) && HAS_PERM (PERM_DENYPOST)) && !currutmp->invisible ) + do_aloha ("<<¤W¯¸³qª¾>> -- §Ú¨Ó°Õ¡I"); + if (ptime->tm_mday == cuser.day && ptime->tm_mon + 1 == cuser.month){ + more ("etc/Welcome_birth", NA); + currutmp->birth = 1; + } + else{ +#ifdef MULTI_WELCOME_LOGIN + char buf[80]; + int nScreens; + for( nScreens = 0 ; nScreens < 10 ; ++nScreens ){ + sprintf(buf, "etc/Welcome_login.%d", nScreens); + if( access(buf, 0) < 0 ) + break; + } + printf("%d\n", nScreens); + if( nScreens == 0 ){ // multi screen error? + more ("etc/Welcome_login", NA); + } + else{ + sprintf(buf, "etc/Welcome_login.%d", (int)login_start_time % nScreens); + more (buf, NA); + } +#else + more ("etc/Welcome_login", NA); +#endif +// pressanykey(); +// more("etc/CSIE_Week", NA); + currutmp->birth = 0; + } + + if (cuser.userlevel){/* not guest */ + move (t_lines - 4, 0); + prints (" Åwªï±z²Ä \033[1;33m%d\033[0;37m «×«ô³X¥»¯¸¡A" + "¤W¦¸±z¬O±q \033[1;33m%s\033[0;37m ³s©¹¥»¯¸¡A\n" + " §Ú°O±o¨º¤Ñ¬O \033[1;33m%s\033[0;37m¡C\n", + ++cuser.numlogins, cuser.lasthost, Cdate (&cuser.lastlogin)); + pressanykey (); + + if (currutmp->birth && tmp->tm_mday != ptime->tm_mday){ + more ("etc/birth.post", YEA); + brc_initial ("WhoAmI"); + set_board (); + do_post (); + } + setuserfile (genbuf, str_badlogin); + if (more (genbuf, NA) != -1){ + getdata (b_lines - 1, 0, "±zn§R°£¥H¤W¿ù»~¹Á¸Õªº°O¿ý¶Ü(Y/N)?[Y]", + ans, 3, LCECHO); + if (*ans != 'n') + unlink (genbuf); + } + check_register (); + strncpy (cuser.lasthost, fromhost, 16); + cuser.lasthost[15] = '\0'; + restore_backup (); + } + else if (!strcmp (cuser.userid, STR_GUEST)){ + 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; + sprintf (cuser.username, "®üÃäº}¨Óªº%s", nick[(int) i]); + sprintf (currutmp->username, cuser.username); + sprintf (cuser.realname, name[(int) i]); + sprintf (currutmp->realname, cuser.realname); + sprintf (cuser.address, addr[(int) i]); + cuser.sex = i % 8; + currutmp->pager = 2; + pressanykey (); + } + else + pressanykey (); + + if (!PERM_HIDE (currutmp)) + cuser.lastlogin = login_start_time; + + passwd_update (usernum, &cuser); + + for (i = 0; i < NUMVIEWFILE; i++) + if ((cuser.loginview >> i) & 1) + more (loginview_file[(int) i][0], YEA); + + +} + +static void +do_aloha (char *hello) +{ + FILE *fp; + char userid[80]; + char genbuf[200]; + + setuserfile (genbuf, "aloha"); + if ((fp = fopen (genbuf, "r"))){ + sprintf (genbuf, hello); + while (fgets (userid, 80, fp)){ + userinfo_t *uentp; + int tuid; + + if ((tuid = searchuser (userid)) && tuid != usernum && + (uentp = (userinfo_t *) search_ulist (tuid)) && + isvisible(uentp, currutmp)){ + my_write (uentp->pid, genbuf, uentp->userid, 2); + } + } + fclose (fp); + } +} + +static void +do_term_init () +{ + term_init (); + initscr (); +} + +extern char *fn_register; +extern int showansi; + +static void +start_client () +{ + extern struct commands_t cmdlist[]; +#if FORCE_PROCESS_REGISTER_FORM + int nreg; +#endif + + /* 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_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 */ + user_login (); + m_init (); + +#if FORCE_PROCESS_REGISTER_FORM + if (HAS_PERM (PERM_SYSOP) && (nreg = dashs (fn_register) / 163) > 100){ + char cpu_load[30]; + if (cpuload (cpu_load) > MAX_CPULOAD * 2 / 3) + /* DickG: ®Ú¾Ú¥Ø«eªº load ¨Ó¨M©wn¼f®Öªº¼Æ¥Ø */ + scan_register_form (fn_register, 1, nreg / 20); + else + scan_register_form (fn_register, 1, nreg / 10); + } +#endif + if (HAVE_PERM (PERM_SYSOP | PERM_BM)) + b_closepolls (); + if (!(cuser.uflag & COLOR_FLAG)) + showansi = 0; +#ifdef DOTIMEOUT + /* init_alarm(); */// cause strange logout with saving post. + signal (SIGALRM, SIG_IGN); +#else + signal (SIGALRM, SIG_IGN); +#endif + if (chkmailbox ()) + m_read (); + + domenu (MMENU, "¥D¥\\¯àªí", (currutmp->mailalert ? 'M' : 'C'), cmdlist); +} + +/* FSA (finite state automata) for telnet protocol */ +static void +telnet_init () +{ + static char svr[] = { + IAC, DO, TELOPT_TTYPE, + IAC, SB, TELOPT_TTYPE, TELQUAL_SEND, IAC, SE, + IAC, WILL, TELOPT_ECHO, + IAC, WILL, TELOPT_SGA + }; + char *cmd; + int n, len, rset; + struct timeval to; + char buf[64]; + for (n = 0, cmd = svr; n < 4; n++){ + len = (n == 1 ? 6 : 3); + write (0, cmd, len); + cmd += len; + to.tv_sec = 3; + to.tv_usec = 0; + rset=1; + if (select (1, (fd_set *) & rset, NULL, NULL, &to) > 0) + recv(0, buf, sizeof (buf),0); + } +} + +/* ¨ú±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 STRN_CPY(d,s,l) { strncpy((d),(s),(l)); (d)[(l)-1] = 0; } +#define RFC931_TIMEOUT 10 +#define RFC931_PORT 113 /* Semi-well-known port */ +#define ANY_PORT 0 /* Any old port will do */ + +/* timeout - handle timeouts */ +static void +timeout (int sig) +{ + longjmp (byebye, sig); +} + +static void +getremotename (struct sockaddr_in *from, char *rhost, char *rname) +{ + + /* get remote host name */ + +#ifdef FAST_LOGIN + 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; + strcpy (rname, user); + } + } + alarm (0); + } + fclose (fp); +#endif +} + +static int +bind_port (int port) +{ + int sock, on; + + 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)); + + on = 0; + setsockopt (sock, SOL_SOCKET, SO_LINGER, (char *) &on, sizeof (on)); + + 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 void shell_login (int argc, char *argv[], char *envp[]); +static void daemon_login (int argc, char *argv[], char *envp[]); +static int check_ban_and_load (int fd); +#ifdef SUPPORT_GB +extern int current_font_type; +#endif + +int +main (int argc, char *argv[], char *envp[]) +{ + /* avoid SIGPIPE */ + signal (SIGPIPE, SIG_IGN); + + /* avoid erroneous signal from other mbbsd */ + signal (SIGUSR1, SIG_IGN); + signal (SIGUSR2, SIG_IGN); + + /* check if invoked as "bbs" */ + if (argc == 3) + shell_login (argc, argv, envp); + else + daemon_login (argc, argv, envp); + + return 0; +} + +static void +shell_login (int argc, char *argv[], char *envp[]) +{ + + /* Give up root privileges: no way back from here */ + setgid (BBSGID); + setuid (BBSUID); + chdir (BBSHOME); + + /* mmap passwd file */ + if (passwd_mmap ()) + exit (1); + + use_shell_login_mode = 1; + initsetproctitle (argc, argv, envp); + + /* copy fromindent: Standard input:1138: Error:Unexpected end of file + the original "bbs" */ + if (argc > 1){ + strcpy (fromhost, argv[1]); + if (argc > 3) + strcpy (remoteusername, argv[3]); + } + + close (2); + /* don't close fd 1, at least init_tty need it */ + + init_tty (); + if (check_ban_and_load (0)){ + exit (0); + } + start_client (); +} + +static void +daemon_login (int argc, char *argv[], char *envp[]) +{ + int msock, csock; /* socket for Master and Child */ + FILE *fp; + int listen_port = 23; + int len_of_sock_addr; + char buf[256]; + + /* setup standalone */ + + start_daemon(); + + signal_restart(SIGCHLD, reapchild); + + /* choose port */ + if(argc == 1) + listen_port = 3006; + else if(argc >= 2) + listen_port = atoi(argv[1]); + + sprintf(margs, "%s %d ", argv[0],listen_port); + + /* port binding */ + xsin.sin_family = AF_INET; + msock = bind_port(listen_port); + if(msock<0) { + syslog(LOG_INFO, "mbbsd bind_port failed.\n"); + exit(1); + } + + + initsetproctitle(argc, argv, envp); + setproctitle("%s: listening ", margs); + + /* Give up root privileges: no way back from here */ + setgid(BBSGID); + setuid(BBSUID); + chdir(BBSHOME); + + /* mmap passwd file */ + if(passwd_mmap()) + { + exit(1); + } + sprintf(buf, "run/mbbsd.%d.pid", listen_port); + if((fp = fopen(buf, "w"))) { + fprintf(fp, "%d\n", getpid()); + fclose(fp); + } + + /* main loop */ + for(;;) { + len_of_sock_addr = sizeof(xsin); + csock = accept(msock, (struct sockaddr *)&xsin, &len_of_sock_addr); + + if(csock < 0) { + if(errno!=EINTR) sleep(1); + continue; + } + + if(check_ban_and_load(csock)) + { + close(csock); + continue; + } + + if(fork()==0) + break; + else + close(csock); + + } + /* here is only child running */ + + setproctitle("%s: ...login wait... ", margs); + close(msock); + dup2(csock, 0); + close(csock); + + getremotename(&xsin, fromhost, remoteusername); + telnet_init(); + start_client(); + close(0); + close(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 char buf[256]; + static time_t chkload_time = 0; + static int overload = 0; /* overload or banned, update every 1 sec */ + static int banned = 0; + + if((time(0) - chkload_time) > 1) { + overload = chkload(buf); + banned = !access(BBSHOME "/BAN",R_OK) && + (strcmp(fromhost, "localhost") != 0); + chkload_time = time(0); + } + + write(fd, buf, strlen(buf)); + + if(banned && (fp = fopen(BBSHOME "/BAN", "r"))) { + while(fgets(buf, 256, fp)) + write(fd, buf, strlen(buf)); + fclose(fp); + } + + if(banned || overload) + return -1; + +#ifdef INSCREEN + write(fd, INSCREEN, strlen(INSCREEN)); +#endif + + return 0; +} diff --git a/mbbsd/menu.c b/mbbsd/menu.c new file mode 100644 index 00000000..d48670b3 --- /dev/null +++ b/mbbsd/menu.c @@ -0,0 +1,596 @@ +/* $Id: menu.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <sys/types.h> +#include <string.h> +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "perm.h" +#include "modes.h" +#include "proto.h" +extern int usernum; +extern int talkrequest; +extern char *fn_register; +extern char currboard[]; /* name of currently selected board */ +extern int currmode; +extern unsigned int currstat; +extern char reset_color[]; +extern userinfo_t *currutmp; +extern char *BBSName; +extern int b_lines; /* Screen bottom line number: t_lines-1 */ + +/* help & menu processring */ +static int refscreen = NA; +extern char *boardprefix; +extern struct utmpfile_t *utmpshm; + +int egetch() { + int rval; + + while(1) { + rval = igetkey(); + if(talkrequest) { + talkreply(); + refscreen = YEA; + return rval; + } + if(rval != Ctrl('L')) + return rval; + redoscr(); + } +} + +extern userec_t cuser; +extern char *fn_board; +extern char board_hidden_status; + +void showtitle(char *title, char *mid) { + char buf[40], numreg[50]; + int nreg, spc = 0, pad, bid; + boardheader_t bh; + static char lastboard[16] = {0}; + + spc = strlen(mid); + if(title[0] == 0) + title++; + else if(currutmp->mailalert) { + mid = "\033[41;5m ¶l®t¨Ó«ö¹aÅo " TITLE_COLOR; + spc = 22; + } else if(HAS_PERM(PERM_SYSOP) && (nreg = dashs(fn_register)/163) > 10) { + /* ¶W¹L¤QÓ¤H¥¼¼f®Ö */ + sprintf(numreg, "\033[41;5m ¦³%03d/%03d¥¼¼f®Ö " TITLE_COLOR, + nreg, + (int)dashs("register.new.tmp") / 163); + mid = numreg; + spc = 22; + } + spc = 66 - strlen(title) - spc - strlen(currboard); + if(spc < 0) + spc = 0; + pad = 1 - (spc & 1); + memset(buf, ' ', spc >>= 1); + buf[spc] = '\0'; + + clear(); + prints(TITLE_COLOR "¡i%s¡j%s\033[33m%s%s%s\033[3%s¡m", + title, buf, mid, buf, " " + pad, + currmode & MODE_SELECT ? "6m¨t¦C" : currmode & MODE_ETC ? "5m¨ä¥L" : + currmode & MODE_DIGEST ? "2m¤åºK" : "7m¬ÝªO"); + + if( strcmp(currboard, lastboard) ){ /* change board */ + if( currboard[0] != 0 && + (bid = getbnum(currboard)) > 0 && + (get_record(fn_board, &bh, sizeof(bh), bid) != -1) ){ + board_hidden_status = ((bh.brdattr & BRD_HIDE) && + (bh.brdattr & BRD_POSTMASK)); + strncpy(lastboard, currboard, sizeof(lastboard)); + } + } + + if( board_hidden_status ) + prints("\033[32m%s", currboard); + else + prints("%s", currboard); + prints("\033[3%dm¡n\033[0m\n", currmode & MODE_SELECT ? 6 : + currmode & MODE_ETC ? 5 : currmode & MODE_DIGEST ? 2 : 7); +} + +/* °Êµe³B²z */ +#define FILMROW 11 +static unsigned char menu_row = 12; +static unsigned char menu_column = 20; +static char mystatus[160]; + +static int u_movie() { + cuser.uflag ^= MOVIE_FLAG; + return 0; +} + +void movie(int i) { + extern struct pttcache_t *ptt; + static short history[MAX_HISTORY]; + static char myweek[] = "¤Ñ¤@¤G¤T¥|¤¤»"; + const char *msgs[] = {"Ãö³¬", "¥´¶}", "©Þ±¼", "¨¾¤ô","¦n¤Í"}; + time_t now = time(NULL); + struct tm *ptime = localtime(&now); + + if((currstat != CLASS) && (cuser.uflag & MOVIE_FLAG) && + !ptt->busystate && ptt->max_film > 0) { + if(currstat == PSALE) { + i = PSALE; + reload_money(); + } else { + do { + if(!i) + i = 1 + (int)(((float)ptt->max_film * + rand()) / (RAND_MAX + 1.0)); + + for(now = ptt->max_history; now >= 0; now--) + if(i == history[now]) { + i = 0; + break; + } + } while(i == 0); + } + + memcpy(history, &history[1], ptt->max_history * sizeof(short)); + history[ptt->max_history] = now = i; + + if(i == 999) /* Goodbye my friend */ + i = 0; + + move(1, 0); + clrtoline(1 + FILMROW); /* ²M±¼¤W¦¸ªº */ + Jaky_outs(ptt->notes[i], 11); /* ¥u¦L11¦æ´N¦n */ + outs(reset_color); + } + i = ptime->tm_wday << 1; + sprintf(mystatus, "\033[34;46m[%d/%d ¬P´Á%c%c %d:%02d]\033[1;33;45m%-14s" + "\033[30;47m ¥Ø«e§{¸Ì¦³ \033[31m%d\033[30m¤H, §Ú¬O\033[31m%-12s" + "\033[30m[¦©¾÷]\033[31m%s\033[0m", + ptime->tm_mon + 1, ptime->tm_mday, myweek[i], myweek[i + 1], + ptime->tm_hour, ptime->tm_min, currutmp->birth ? + "¥Í¤én½Ð«Èò" : ptt->today_is, + utmpshm->number, cuser.userid, msgs[currutmp->pager]); + outmsg(mystatus); + refresh(); +} + +static int show_menu(commands_t *p) { + register int n = 0; + register char *s; + const char *state[4]={"¥Î¥\\«¬", "¦w¶h«¬", "¦Û©w«¬", "SHUTUP"}; + char buf[80]; + + movie(currstat); + + move(menu_row, 0); + while((s = p[n].desc)) { + if(HAS_PERM(p[n].level)) { + sprintf(buf, s + 2, state[cuser.proverb % 4]); + prints("%*s (\033[1;36m%c\033[0m)%s\n", menu_column, "", s[1], + buf); + } + n++; + } + return n - 1; +} + +void domenu(int cmdmode, char *cmdtitle, int cmd, commands_t cmdtable[]) { + int lastcmdptr; + int n, pos, total, i; + int err; + int chkmailbox(); + static char cmd0[LOGIN]; + + if(cmd0[cmdmode]) + cmd = cmd0[cmdmode]; + + setutmpmode(cmdmode); + + showtitle(cmdtitle, BBSName); + + total = show_menu(cmdtable); + + outmsg(mystatus); + lastcmdptr = pos = 0; + + do { + i = -1; + switch(cmd) { + case Ctrl('C'): + cal(); + i = lastcmdptr; + refscreen = YEA; + break; + 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(!HAS_PERM(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(!HAS_PERM(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]; + cmd0[cmdmode] = cmdtable[lastcmdptr].desc[0]; + } + + if(cmd >= 'a' && cmd <= 'z') + cmd &= ~0x20; + while(++i <= total) + if(cmdtable[i].desc[1] == cmd) + break; + } + + if(i > total || !HAS_PERM(cmdtable[i].level)) + continue; + + if(refscreen) { + showtitle(cmdtitle, BBSName); + + show_menu(cmdtable); + + outmsg(mystatus); + refscreen = NA; + } + cursor_clear(menu_row + pos, menu_column); + n = pos = -1; + while(++n <= (lastcmdptr = i)) + if(HAS_PERM(cmdtable[n].level)) + pos++; + + cursor_show(menu_row + pos, menu_column); + } while(((cmd = egetch()) != EOF) || refscreen); + + abort_bbs(0); +} +/* INDENT OFF */ + +/* administrator's maintain menu */ +static commands_t adminlist[] = { + {m_user, PERM_ACCOUNTS, "UUser ¨Ï¥ÎªÌ¸ê®Æ"}, + {search_user_bypwd, PERM_SYSOP, "SSearch User ¯S®í·j´M¨Ï¥ÎªÌ"}, + {search_user_bybakpwd,PERM_SYSOP, "OOld User data ¬d¾\\³Æ¥÷¨Ï¥ÎªÌ¸ê®Æ"}, + {m_board, PERM_SYSOP, "BBoard ³]©w¬ÝªO"}, + {m_register, PERM_SYSOP, "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 ¬õ¥]Âû"}, +#ifdef HAVE_MAILCLEAN + {m_mclean, PERM_SYSOP, "MMail Clean ²M²z¨Ï¥ÎªÌÓ¤H«H½c"}, +#endif +#ifdef HAVE_REPORT + {m_trace, PERM_SYSOP, "TTrace ³]©w¬O§_°O¿ý°£¿ù¸ê°T"}, +#endif + {NULL, 0, NULL} +}; + +/* mail menu */ +static commands_t maillist[] = { + {m_new, PERM_READMAIL, "RNew ¾\\Ū·s¶i¶l¥ó"}, + {m_read, PERM_READMAIL, "RRead ¦h¥\\¯àŪ«H¿ï³æ"}, + {m_send, PERM_BASIC, "RSend ¯¸¤º±H«H"}, + {main_bbcall, PERM_LOGINOK, "BBBcall \033[1;31m¹q¸Ü¯µ®Ñ\033[m"}, + {x_love, PERM_LOGINOK, "PPaper \033[1;32m±¡®Ñ²£¥Í¾¹\033[m "}, + {mail_list, PERM_BASIC, "RMail List ¸s²Õ±H«H"}, + {setforward, PERM_LOGINOK,"FForward \033[32m³]©w«H½c¦Û°ÊÂà±H\033[m"}, + {m_sysop, 0, "YYes, sir! ½Ô´A¯¸ªø"}, + {m_internet, PERM_INTERNET, "RInternet ±H«H¨ì Internet"}, + {mail_mbox, PERM_INTERNET, "RZip UserHome §â©Ò¦³¨p¤H¸ê®Æ¥´¥]¦^¥h"}, + {built_mail_index, PERM_LOGINOK, "SSavemail §â«H¥ó±Ï¦^¨Ó"}, + {mail_all, PERM_SYSOP, "RAll ±H«Hµ¹©Ò¦³¨Ï¥ÎªÌ"}, + {NULL, 0, NULL} +}; + +/* Talk menu */ +static 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ª«"}, + {t_talk, PERM_PAGE, "TTalk §ä¤H²á²á"}, + {t_chat, PERM_CHAT, "CChat §ä®a¯ù§{³ð¯ù¥h"}, +#ifdef HAVE_MUD + {x_mud, 0, "VVrChat \033[1;32mµêÀÀ¹ê·~²á¤Ñ¼s³õ\033[m"}, +#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 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³æ"}, +#ifdef POSTNOTIFY + {t_post,PERM_LOGINOK, "NNewPost ·s¤å³¹³qª¾¦W³æ"}, +#endif + {t_special,PERM_LOGINOK, "SSpecial ¨ä¥L¯S§O¦W³æ"}, + {NULL, 0, NULL} +}; + +/* User menu */ +static commands_t userlist[] = { + {u_info, PERM_LOGINOK, "IInfo ³]©wÓ¤H¸ê®Æ»P±K½X"}, + {calendar, PERM_LOGINOK, "CCalendar Ó¤H¦æ¨Æ¾ä"}, + {u_editcalendar, PERM_LOGINOK, "CCalendarEdit ½s¿èÓ¤H¦æ¨Æ¾ä"}, + {u_loginview, PERM_LOGINOK, "LLogin View ¿ï¾Ü¶i¯¸µe±"}, + {u_ansi, 0, "AANSI ¤Á´« ANSI \033[36m±m\033[35m¦â\033[37m/" + "\033[30;47m¶Â\033[1;37m¥Õ\033[m¼Ò¥Ü"}, + {u_movie, 0, "MMovie ¤Á´«°Êµe¼Ò¥Ü"}, +#ifdef HAVE_SUICIDE + {u_kill, PERM_BASIC, "IKill ¦Û±þ¡I¡I"}, +#endif + {u_editplan, PERM_LOGINOK, "QQueryEdit ½s¿è¦W¤ùÀÉ"}, + {u_editsig, PERM_LOGINOK, "SSignature ½s¿èñ¦WÀÉ"}, +#if HAVE_FREECLOAK + {u_cloak, PERM_LOGINOK, "CCloak Áô¨³N"}, +#else + {u_cloak, PERM_CLOAK, "CCloak Áô¨³N"}, +#endif + {u_register, PERM_BASIC, "RRegister ¶ñ¼g¡mµù¥U¥Ó½Ð³æ¡n"}, + {u_list, PERM_SYSOP, "UUsers ¦C¥Xµù¥U¦W³æ"}, + {NULL, 0, NULL} +}; + +/* XYZ tool menu */ +static commands_t xyzlist[] = { +#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¬Ýª©ºëµØ°Ï±Æ¦æº]¡n"}, +// {x_boards,0, "HHot Boards ¡m¬Ýª©¤H®ð±Æ¦æº]¡n"}, + {x_history, 0, "HHistory ¡m§Ú̪º¦¨ªø¡n"}, + {x_note, 0, "NNote ¡m»Ä²¢W»¶¬y¨¥ª©¡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"}, + {x_birth, 0, "BBirthday ¡m¤µ¤é¹Ø¬P¤jÆ[¡n"}, + {p_sysinfo, 0, "XXload ¡m¬d¬Ý¨t²Ît²ü¡n"}, + {NULL, 0, NULL} +}; + +/* Ptt money menu */ +static 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 int p_money() { + domenu(PSALE, "¢Þtt¶q³c©±", '0', moneylist); + return 0; +}; + +static commands_t jceelist[] = { + {x_90,PERM_LOGINOK, "0090 JCEE ¡i90¾Ç¦~«×¤j¾ÇÁp©Û¬dº]¨t²Î¡j"}, + {x_89,PERM_LOGINOK, "1189 JCEE ¡i89¾Ç¦~«×¤j¾ÇÁp©Û¬dº]¨t²Î¡j"}, + {x_88,PERM_LOGINOK, "2288 JCEE ¡i88¾Ç¦~«×¤j¾ÇÁp©Û¬dº]¨t²Î¡j"}, + {x_87,PERM_LOGINOK, "3387 JCEE ¡i87¾Ç¦~«×¤j¾ÇÁp©Û¬dº]¨t²Î¡j"}, + {x_86,PERM_LOGINOK, "4486 JCEE ¡i86¾Ç¦~«×¤j¾ÇÁp©Û¬dº]¨t²Î¡j"}, + {NULL, 0, NULL} +}; + +static int m_jcee() { + domenu(JCEE, "¢Þtt¬dº]¨t²Î", '0', jceelist); + return 0; +} + +static int forsearch(); +static int playground(); + +/* Ptt Play menu */ +static commands_t playlist[] = { +#if HAVE_JCEE + {m_jcee, PERM_LOGINOK, "JJCEE ¡i ¤j¾ÇÁp¦Ò¬dº]¨t²Î ¡j"}, +#endif + {note, PERM_LOGINOK, "NNote ¡i ¨è¨è¬y¨¥ª© ¡j"}, + {x_weather,0 , "WWeather ¡i ®ð¶H¹w³ø ¡j"}, + {x_stock,0 , "SStock ¡i ªÑ¥«¦æ±¡ ¡j"}, +#ifdef HAVE_BIG2 + {x_big2, 0, "BBig2 ¡i ºô¸ô¤j¦Ñ¤G ¡j"}, +#endif +#ifdef HAVE_MJ + {x_mj, PERM_LOGINOK, "QQkmj ¡i ºô¸ô¥´³Â±N ¡j"}, +#endif +#ifdef HAVE_BRIDGE + {x_bridge, PERM_LOGINOK, "OOkBridge ¡i ¾ôµPÄv§Þ ¡j"}, +#endif +#ifdef HAVE_GOPHER + {x_gopher, PERM_LOGINOK, "GGopher ¡i ¦a¹«¸ê®Æ®w ¡j"}, +#endif +#ifdef HAVE_TIN + {x_tin, PERM_LOGINOK, "NNEWS ¡i ºô»Ú·s»D ¡j"}, +#endif +#ifdef BBSDOORS + {x_bbsnet, PERM_LOGINOK, "BBBSNet ¡i ¨ä¥L BBS¯¸ ¡j"}, +#endif +#ifdef HAVE_WWW + {x_www, PERM_LOGINOK, "WWWW Browser ¡i ¨L¨L¨L ¡j"}, +#endif + {forsearch,PERM_LOGINOK, "SSearchEngine¡i\033[1;35m ¢Þtt·j´M¾¹ \033[m¡j"}, + {topsong,PERM_LOGINOK, "TTop Songs ¡i\033[1;32m¼Ú®áÂIºq±Æ¦æº]\033[m¡j"}, + {p_money,PERM_LOGINOK, "PPay ¡i\033[1;31m ¢Þtt¶q³c©± \033[m¡j"}, + {chicken_main,PERM_LOGINOK, "CChicken " + "¡i\033[1;34m ¢Þtt¾iÂû³õ \033[m¡j"}, + {playground,PERM_LOGINOK, "AAmusement ¡i\033[1;33m ¢Þtt¹C¼Ö³õ \033[m¡j"}, + {NULL, 0, NULL} +}; + +static commands_t plist[] = { + +/* {p_ticket_main, PERM_LOGINOK,"00Pre ¡i Á`²Î¾÷ ¡j"}, + {alive, PERM_LOGINOK, "00Alive ¡i q²¼Âû ¡j"}, +*/ + {ticket_main, PERM_LOGINOK, "11Gamble ¡i ¢Þtt½ä³õ ¡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(AMUSE, "¢Þtt¹C¼Ö³õ",'1',plist); + return 0; +} + +static commands_t slist[] = { + {x_dict,0, "11Dictionary " + "¡i\033[1;33m ½ì¨ý¤j¦r¨å \033[m¡j"}, + {main_railway, PERM_LOGINOK, "33Railway " + "¡i\033[1;32m ¤õ¨®ªí¬d¸ß \033[m¡j"}, + {NULL, 0, NULL} +}; + +static int forsearch() { + domenu(SREG, "¢Þtt·j´M¾¹", '1', slist); + return 0; +} + +/* main menu */ + +static int admin() { + domenu(ADMIN, "¨t²ÎºûÅ@", 'X', adminlist); + return 0; +} + +static int Mail() { + domenu(MAIL, "¹q¤l¶l¥ó", 'R', maillist); + return 0; +} + +static int Talk() { + domenu(TMENU, "²á¤Ñ»¡¸Ü", 'U', talklist); + return 0; +} + +static int User() { + domenu(UMENU, "Ó¤H³]©w", 'A', userlist); + return 0; +} + +static int Xyz() { + domenu(XMENU, "¤u¨ãµ{¦¡", 'M', xyzlist); + return 0; +} + +static int Play_Play() { + domenu(PMENU, "ºô¸ô¹C¼Ö³õ", 'A', playlist); + return 0; +} + +static int Name_Menu() { + domenu(NMENU, "¥Õ¦â®£©Æ", 'O', namelist); + return 0; +} + +commands_t cmdlist[] = { + {admin,PERM_SYSOP|PERM_VIEWSYSOP, "00Admin ¡i ¨t²ÎºûÅ@°Ï ¡j"}, + {Announce, 0, "AAnnounce ¡i ºëµØ¤½§GÄæ ¡j"}, + {Boards, 0, "FFavorite ¡i §Ú ªº ³Ì·R ¡j"}, + {root_board, 0, "CClass ¡i ¤À²Õ°Q½×°Ï ¡j"}, + {Mail, PERM_BASIC, "MMail ¡i ¨p¤H«H¥ó°Ï ¡j"}, + {Talk, 0, "TTalk ¡i ¥ð¶¢²á¤Ñ°Ï ¡j"}, + {User, 0, "UUser ¡i Ó¤H³]©w°Ï ¡j"}, + {Xyz, 0, "XXyz ¡i ¨t²Î¤u¨ã°Ï ¡j"}, + {Play_Play,0, "PPlay ¡i ¹C¼Ö³õ/¤j¾Ç¬dº]¡j"}, + {Name_Menu,PERM_LOGINOK, "NNamelist ¡i ½s¯S§O¦W³æ ¡j"}, + {Goodbye, 0, "GGoodbye Â÷¶}¡A¦A¨£¡K¡K"}, + {NULL, 0, NULL} +}; diff --git a/mbbsd/more.c b/mbbsd/more.c new file mode 100644 index 00000000..f7755874 --- /dev/null +++ b/mbbsd/more.c @@ -0,0 +1,931 @@ +/* $Id: more.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <time.h> +#include <sys/types.h> +#include <sys/stat.h> + +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "modes.h" +#include "perm.h" +#include "proto.h" + +extern int showansi; +extern int t_lines, t_columns; /* Screen size / width */ +extern int b_lines; /* Screen bottom line number: t_lines-1 */ +extern char *str_author1; +extern char *str_author2; +extern char *str_post1; +extern char *str_post2; +extern char *msg_seperator; +extern char reset_color[]; + +#define MORE_BUFSIZE 4096 +#define MORE_WINSIZE 4096 +#define STR_ANSICODE "[0123456789;," + +static int more_base, more_size, more_head; +static unsigned char more_pool[MORE_BUFSIZE]; + + +#define MAXPATHLEN 256 +static char *more_help[] = { + "\0¾\\Ū¤å³¹¥\\¯àÁä¨Ï¥Î»¡©ú", + "\01´å¼Ð²¾°Ê¥\\¯àÁä", + "(¡ô) ¤W±²¤@¦æ", + "(¡õ)(Enter) ¤U±²¤@¦æ", + "(^B)(PgUp)(BackSpace) ¤W±²¤@¶", + "(¡÷)(PgDn)(Space) ¤U±²¤@¶", + "(0)(g)(Home) Àɮ׶}ÀY", + "($)(G) (End) ÀÉ®×µ²§À", + "\01¨ä¥L¥\\¯àÁä", + "(/) ·j´M¦r¦ê", + "(n/N) «½Æ¥¿/¤Ï¦V·j´M", + "(TAB) URL³sµ²", + "(Ctrl-T) ¦s¨ì¼È¦sÀÉ", + "(:/f/b) ¸õ¦Ü¬Y¶/¤U/¤W½g", + "(F/B) ¸õ¦Ü¦P¤@·j´M¥DÃD¤U/¤W½g", + "(a/A) ¸õ¦Ü¦P¤@§@ªÌ¤U/¤W½g", + "([/]) ¥DÃD¦¡¾\\Ū ¤W/¤U", + "(t) ¥DÃD¦¡´`§Ç¾\\Ū", + "(Ctrl-C) ¤ppºâ¾÷", + "(q)(¡ö) µ²§ô", + "(h)(H)(?) »²§U»¡©úµe±", + NULL +}; + +int beep = 0; + +static void +more_goto (int fd, off_t off) +{ + int base = more_base; + + if (off < base || off >= base + more_size) + { + more_base = base = off & (-MORE_WINSIZE); + lseek (fd, base, SEEK_SET); + more_size = read (fd, more_pool, MORE_BUFSIZE); + } + more_head = off - base; +} + +static int +more_readln (int fd, unsigned char *buf) +{ + int ch; + + unsigned char *data, *tail, *cc; + int len, bytes, in_ansi; + int size, head, ansilen; + + len = bytes = in_ansi = ansilen = 0; + tail = buf + ANSILINELEN - 1; + size = more_size; + head = more_head; + data = &more_pool[head]; + + do + { + if (head >= size) + { + more_base += size; + data = more_pool; + more_size = size = read (fd, data, MORE_BUFSIZE); + if (size == 0) + break; + head = 0; + } + + ch = *data++; + head++; + bytes++; + if (ch == '\n') + { + break; + } + if (ch == '\t') + { + do + { + *buf++ = ' '; + } + while ((++len & 7) && len < 80); + } + else if (ch == '\033') + { + if (atoi (data + 1) > 47) + { + if ((cc = strchr (data + 1, 'm')) != NULL) + { + ch = cc - data + 1; + + data += ch; + head += ch; + bytes += ch; + } + } + else + { + if (showansi) + *buf++ = ch; + in_ansi = 1; + } + } + else if (in_ansi) + { + if (showansi) + *buf++ = ch; + if (!strchr (STR_ANSICODE, ch)) + in_ansi = 0; + } + else if (isprint2 (ch)) + { + len++; + *buf++ = ch; + } + } + while (len < 80 && buf < tail); + *buf = '\0'; + more_head = head; + return bytes; +} + +/* not used +static int readln(FILE *fp, char *buf) { + register int ch, i, len, bytes, in_ansi; + + len = bytes = in_ansi = i = 0; + while(len < 80 && i < ANSILINELEN && (ch = getc(fp)) != EOF) { + bytes++; + if(ch == '\n') + break; + else if(ch == '\t') + do { + buf[i++] = ' '; + } while((++len & 7) && len < 80); + else if(ch == '\a') + beep = 1; + else if(ch == '\033') { + if(showansi) + buf[i++] = ch; + in_ansi = 1; + } else if(in_ansi) { + if(showansi) + buf[i++] = ch; + if(!strchr("[0123456789;,", ch)) + in_ansi = 0; + } else if(isprint2(ch)) { + len++; + buf[i++] = ch; + } + } + buf[i] = '\0'; + return bytes; +} +*/ + +extern userec_t cuser; + +static int more_web(char *fpath, int promptend); + +int more(char *fpath, int promptend) { + extern char* strcasestr(); + static char *head[4] = {"§@ªÌ", "¼ÐÃD", "®É¶¡" ,"Âà«H"}; + char *ptr, *word = NULL, buf[ANSILINELEN + 1], *ch1; + struct stat st; + +/* rocker */ + //FILE *fp; + int fd, fsize; + + unsigned int pagebreak[MAX_PAGES], pageno, lino = 0; + int line, ch, viewed, pos, numbytes; + int header = 0; + int local = 0; + char search_char0=0; + static char search_str[81]=""; + typedef char* (*FPTR)(); + static FPTR fptr; + int searching = 0; + int scrollup = 0; + char *printcolor[3]= {"44","33;45","0;34;46"}, color =0; + char *http[80]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; + /* Ptt */ + char pagemode = 0; + char pagecount = 0; + + memset(pagebreak, 0, sizeof(pagebreak)); + if(*search_str) + search_char0 = *search_str; + *search_str = 0; + + + fd = open (fpath, O_RDONLY, 0600); + if (fd < 0) return -1; + + if(fstat(fd, &st) || ((fsize = st.st_size) <= 0) || S_ISDIR (st.st_mode)) + { + close(fd); //Ptt + return -1; + } + pagebreak[0] = pageno = viewed = line = pos = 0; + clear(); + +/* rocker */ + + more_base = more_head = more_size = 0; + + while((numbytes = more_readln(fd, buf)) || (line == t_lines)) { + if(scrollup) { + rscroll(); + move(0, 0); + } + if(numbytes) { /* ¤@¯ë¸ê®Æ³B²z */ + if(!viewed) { /* begin of file */ + if(showansi) { /* header processing */ + if(!strncmp(buf, str_author1, LEN_AUTHOR1)) { + line = 3; + word = buf + LEN_AUTHOR1; + local = 1; + } else if(!strncmp(buf, str_author2, LEN_AUTHOR2)) { + line = 4; + word = buf + LEN_AUTHOR2; + } + + while(pos < line) { + if(!pos && ((ptr = strstr(word, str_post1)) || + (ptr = strstr(word, str_post2)))) { + ptr[-1] = '\0'; + prints("\033[47;34m %s \033[44;37m%-53.53s" + "\033[47;34m %.4s \033[44;37m%-13s\033[m\n", + head[0], word, ptr, ptr + 5); + } else if (pos < 4) + prints("\033[47;34m %s \033[44;37m%-72.72s" + "\033[m\n", head[pos], word); + + viewed += numbytes; + numbytes = more_readln(fd, buf); + + /* ²Ä¤@¦æ¤Óªø¤F */ + if(!pos && viewed > 79) { + /* ²Ä¤G¦æ¤£¬O [¼Ð....] */ + if(memcmp( buf, head[1], 2)) { + /* Ū¤U¤@¦æ¶i¨Ó³B²z */ + viewed += numbytes; + numbytes = more_readln(fd, buf); + } + } + pos++; + } + if(pos) { + header = 1; + + prints("\033[36m%s\033[m\n", msg_seperator); + line = pos = 4; + } + } + lino = pos; + word = NULL; + } + + /* ¡°³B²z¤Þ¥ÎªÌ & ¤Þ¨¥ */ + if((buf[1] == ' ') && (buf[0] == ':' || buf[0] == '>')) + word = "\033[36m"; + else if(!strncmp(buf, "¡°", 2) || !strncmp(buf, "==>", 3)) + word = "\033[32m"; + + ch1 = buf; + while(1) { + int i; + char e,*ch2; + + if((ch2 = strstr(ch1, "http://"))) + ; + else if((ch2 = strstr(ch1,"gopher://"))) + ; + else if((ch2 = strstr(ch1,"mailto:"))) + ; + else + break; + for(e = 0; ch2[(int)e] != ' ' && ch2[(int)e] != '\n' && + ch2[(int)e] != '\0' && ch2[(int)e] != '"' && + ch2[(int)e] != ';' && ch2[(int)e] != ']'; e++); + for(i = 0; http[i] && i < 80; i++) + if(!strncmp(http[i], ch2, e) && http[(int)e] == 0) + break; + if(!http[i]) { + http[i] = (char *)malloc(e + 1); + strncpy(http[i], ch2, e); + http[i][(int)e] = 0; + pagecount++; + } + ch1 = &ch2[7]; + } + if(word) + outs(word); + { + char msg[500], *pos; + + if(*search_str && (pos = fptr(buf, search_str))) { + char SearchStr[81]; + char buf1[100], *pos1; + + strncpy(SearchStr, pos, strlen(search_str)); + SearchStr[strlen(search_str)] = 0; + searching = 0; + sprintf(msg, "%.*s\033[7m%s\033[m", pos - buf, buf, + SearchStr); + while((pos = fptr(pos1 = pos + strlen(search_str), + search_str))) { + sprintf(buf1, "%.*s\033[7m%s\033[m", pos - pos1, + pos1, SearchStr); + strcat(msg, buf1); + } + strcat(msg, pos1); + outs(Ptt_prints(msg,NO_RELOAD)); + } else + outs(Ptt_prints(buf,NO_RELOAD)); + } + if(word) { + outs("\033[m"); + word = NULL; + } + outch('\n'); + + if(beep) { + bell(); + beep = 0; + } + + if(line < b_lines) /* ¤@¯ë¸ê®ÆŪ¨ú */ + line++; + + if(line == b_lines && searching == -1) { + if(pageno > 0) + more_goto(fd, viewed = pagebreak[--pageno]); + else + searching = 0; + lino = pos = line = 0; + clear(); + continue; + } + + if(scrollup) { + move(line = b_lines, 0); + clrtoeol(); + for(pos = 1; pos < b_lines; pos++) + viewed += more_readln(fd, buf); + } else if(pos == b_lines) /* ±²°Ê¿Ã¹õ */ + scroll(); + else + pos++; + + if(!scrollup && ++lino >= b_lines && pageno < MAX_PAGES - 1) { + pagebreak[++pageno] = viewed; + lino = 1; + } + + if(scrollup) { + lino = scrollup; + scrollup = 0; + } + viewed += numbytes; /* ²ÖpŪ¹L¸ê®Æ */ + } else + line = b_lines; /* end of END */ + + if(promptend && + ((!searching && line == b_lines) || viewed == fsize)) { + /* Kaede è¦n 100% ®É¤£°± */ + move(b_lines, 0); + if(viewed == fsize) { + if(searching == 1) + searching = 0; + color = 0; + } else if(pageno == 1 && lino == 1) { + if(searching == -1) + searching = 0; + color = 1; + } else + color = 2; + + prints("\033[m\033[%sm ÂsÄý P.%d(%d%%) %s %-30.30s%s", + printcolor[(int)color], + pageno, + (int)((viewed * 100) / fsize), + pagemode ? "\033[30;47m" : "\033[31;47m", + pagemode ? http[pagemode-1] : "(h)\033[30m¨D§U \033[31m¡÷¡õ[PgUp][", + pagemode ? "\033[31m[TAB]\033[30m¤Á´« \033[31m[Enter]\033[30m¿ï©w \033[31m¡ö\033[30m©ñ±ó\033[m" : "PgDn][Home][End]\033[30m´å¼Ð²¾°Ê \033[31m¡ö[q]\033[30mµ²§ô \033[m"); + + + while(line == b_lines || (line > 0 && viewed == fsize)) { + switch((ch = egetch())) { + case ':': + { + char buf[10]; + int i = 0; + + getdata(b_lines - 1, 0, "Goto Page: ", buf, 5, DOECHO); + sscanf(buf, "%d", &i); + if(0 < i && i < MAX_PAGES && (i == 1 || pagebreak[i - 1])) + pageno = i - 1; + else if(pageno) + pageno--; + lino = line = 0; + break; + } + case '/': + { + char ans[4] = "n"; + + *search_str = search_char0; + getdata_buf(b_lines - 1, 0,"[·j´M]ÃöÁä¦r:", search_str, + 40, DOECHO); + if(*search_str) { + searching = 1; + if(getdata(b_lines - 1, 0, "°Ï¤À¤j¤p¼g(Y/N/Q)? [N] ", + ans, 4, LCECHO) && *ans == 'y') + fptr = strstr; + else + fptr = strcasestr; + } + if(*ans == 'q') + searching = 0; + if(pageno) + pageno--; + lino = line = 0; + break; + } + case 'n': + if(*search_str) { + searching = 1; + if(pageno) + pageno--; + lino = line = 0; + } + break; + case 'N': + if(*search_str) { + searching = -1; + if(pageno) + pageno--; + lino = line = 0; + } + break; + case 'r': + case 'R': + case 'Y': + close(fd); + return 7; + case 'y': + close(fd); + return 8; + case 'A': + close(fd); + return 9; + case 'a': + close(fd); + return 10; + case 'F': + close(fd); + return 11; + case 'B': + close(fd); + return 12; + case KEY_LEFT: + if(pagemode) { + pagemode = 0; + *search_str = 0; + if(pageno) + pageno--; + lino = line = 0; + break; + } + close(fd); + return 6; + case 'q': + close(fd); + return 0; + case 'b': + close(fd); + return 1; + case 'f': + close(fd); + return 3; + case ']': /* Kaede ¬°¤F¥DÃD¾\Ū¤è«K */ + close(fd); + return 4; + case '[': /* Kaede ¬°¤F¥DÃD¾\Ū¤è«K */ + close(fd); + return 2; + case '=': /* Kaede ¬°¤F¥DÃD¾\Ū¤è«K */ + close(fd); + return 5; + case Ctrl('F'): + case KEY_PGDN: + line = 1; + break; + case 't': + if(viewed == fsize) { + close(fd); + return 4; + } + line = 1; + break; + case ' ': + if(viewed == fsize) { + close(fd); + return 3; + } + line = 1; + break; + case KEY_RIGHT: + if(viewed == fsize) { + close(fd); + return 0; + } + line = 1; + break; + case '\r': + case '\n': + if(pagemode) { + more_web(http[pagemode-1],YEA); + pagemode = 0; + *search_str = 0; + if(pageno) + pageno--; + lino = line = 0; + break; + } + case KEY_DOWN: + if(viewed == fsize || + (promptend == 2 && (ch == '\r' || ch == '\n'))) { + close(fd); + return 3; + } + line = t_lines - 2; + break; + case '$': + case 'G': + case KEY_END: + line = t_lines; + break; + case '0': + case 'g': + case KEY_HOME: + pageno = line = 0; + break; + case 'h': + case 'H': + case '?': + /* Kaede Buggy ... */ + show_help(more_help); + if(pageno) + pageno--; + lino = line = 0; + break; + case 'E': + if(HAS_PERM(PERM_SYSOP) && strcmp(fpath, "etc/ve.hlp")) { + close(fd); + vedit(fpath, NA, NULL); + return 0; + } + break; + case Ctrl('C'): + cal(); + if(pageno) + pageno--; + lino = line = 0; + break; + + case Ctrl('T'): + getdata(b_lines - 2, 0, "§â³o½g¤å³¹¦¬¤J¨ì¼È¦sÀÉ¡H[y/N] ", + buf, 4, LCECHO); + if(buf[0] == 'y') { + char tmpbuf[128]; + + setuserfile(tmpbuf, ask_tmpbuf(b_lines - 1)); + sprintf(buf, "cp -f %s %s", fpath, tmpbuf); + system(buf); + } + if(pageno) + pageno--; + lino = line = 0; + break; +#if 0 + case Ctrl('I'): + if(!pagecount) + break; + pagemode = (pagemode % pagecount) + 1; + strncpy(search_str,http[pagemode-1],80); + search_str[80] =0; + fptr = strstr; + if(pageno) + pageno--; + lino = line = 0; + break; +#endif + case KEY_UP: + line = -1; + break; + case Ctrl('B'): + case KEY_PGUP: + if(pageno > 1) { + if(lino < 2) + pageno -= 2; + else + pageno--; + lino = line = 0; + } else if(pageno && lino > 1) + pageno = line = 0; + break; + case Ctrl('H'): + if(pageno > 1) { + if(lino < 2) + pageno -= 2; + else + pageno--; + lino = line = 0; + } else if(pageno && lino > 1) + pageno = line = 0; + else { + close(fd); + return 1; + } + } + } + + if(line > 0) { + move(b_lines, 0); + clrtoeol(); + refresh(); + } else if(line < 0) { /* Line scroll up */ + if(pageno <= 1) { + if(lino == 1 || !pageno) { + close(fd); + return 1; + } + if(header && lino <= 5) { + more_goto(fd, viewed = pagebreak[scrollup = lino = + pageno = 0] = 0); + clear(); + } + } + if(pageno && lino > 1 + local) { + line = (lino - 2) - local; + if(pageno > 1 && viewed == fsize) + line += local; + scrollup = lino - 1; + more_goto(fd, viewed = pagebreak[pageno - 1]); + while(line--) + viewed += more_readln(fd, buf); + } else if(pageno > 1) { + scrollup = b_lines - 1; + line = (b_lines - 2) - local; + more_goto(fd, viewed = pagebreak[--pageno - 1]); + while(line--) + viewed += more_readln(fd, buf); + } + line = pos = 0; + } else { + pos = 0; + more_goto (fd, viewed = pagebreak[pageno]); + move(0,0); + clear(); + } + } + } + + close(fd); + if(promptend) { + pressanykey(); + clear(); + } else + outs(reset_color); + return 0; +} + +static int more_web(char *fpath, int promptend) { + char *ch, *ch1 = NULL; + char *hostname = fpath,userfile[MAXPATHLEN],file[MAXPATHLEN]="/"; + char genbuf[200]; + time_t dtime; +#if !defined(USE_LYNX) && defined(USE_PROXY) + int a; + FILE *fp; + struct hostent *h; + struct sockaddr_in sin; +#endif + + if((ch = strstr(fpath, "mailto:"))) { + if(!HAS_PERM(PERM_LOGINOK)) { + move(b_lines - 1,0); + outs("\033[41m ±zªºÅv¤£¨¬µLªk¨Ï¥Îinternet mail... \033[m"); + refresh(); + return 0; + } + if(!invalidaddr(&ch[7]) && + getdata(b_lines - 1, 0, "[±H«H]¥DÃD¡G", genbuf, 40, DOECHO)) + do_send(&ch[7], genbuf); + else { + move(b_lines - 1,0); + outs("\033[41m ¦¬«H¤Hemail ©Î ¼ÐÃD ¦³»~... \033[m"); + refresh(); + } + return 0; + } + if((ch = strstr(fpath, "gopher://"))) { + item_t item; + + strcpy(item.X.G.server, &ch[9]); + strcpy(item.X.G.path, "1/"); + item.X.G.port = 70; + gem(fpath , &item, 0); + return 0; + } + if((ch = strstr(fpath, "http://"))) + hostname=&ch[7]; + if((ch = strchr(hostname, '/'))) { + *ch = 0; + if(&ch1[1]) + strcat(file,&ch[1]); + } + if(file[strlen(file) - 1] == '/') + strcat(file,"index.html"); + move(b_lines-1,0); + clrtoeol(); +#ifdef USE_PROXY + sprintf(genbuf, "\033[33;44m ¥¿¦b³s©¹%s.(proxy:%s).....½ÐµyÔ....\033[m", + hostname, PROXYSERVER); +#else + sprintf(genbuf, "\033[33;44m ¥¿¦b³s©¹%s......½ÐµyÔ....\033[m", hostname); +#endif + outs(genbuf); + refresh(); + +#ifdef LOCAL_PROXY +/* ¥ý§ä local disk ªº proxy */ + time(&dtime); + sprintf(userfile,"hproxy/%s%s",hostname,file); + if(dashf(userfile) && (dtime - dasht(userfile)) < HPROXYDAY * 24 * 60 + && more(userfile,promptend)) { + return 1; + } + ch=userfile - 1; + while((ch1 = strchr(ch + 1,'/'))) { + *ch1 = 0; + if(!dashd(ch)) + mkdir(ch+1,0755); + chdir(ch+1); + *ch1 = '/'; + ch = ch1; + } + chdir(BBSHOME); +#endif + +#ifndef USE_LYNX +#ifdef USE_PROXY + if(!(h = gethostbyname(PROXYSERVER))) { + outs("\033[33;44m §ä¤£¨ì³oÓproxy server!..\033[m"); + refresh(); + return; + } + ()memset((char *)&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + + if(h == NULL) + sin.sin_addr.s_addr = inet_addr(PROXYSERVER); + else + ()memcpy(&sin.sin_addr.s_addr, h->h_addr, h->h_length); + + sin.sin_port = htons((ushort)PROXYPORT); /* HTTP port */ + a = socket(AF_INET, SOCK_STREAM, 0); + if((connect(a, (struct sockaddr *) & sin, sizeof sin)) < 0) { + outs("\033[1;44m ³s±µ¨ìproxy¨ü¨ì©Úµ´ ! \033[m"); + refresh(); + return; + } + sprintf(genbuf,"GET http://%s/%s HTTP/1.1\n",hostname,file); +#else + if(!(h = gethostbyname(hostname))) { + outs("\033[33;44m §ä¤£¨ì³oÓserver!..\033[m"); + refresh(); + return; + } + ()memset((char *) &sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + + if(h == NULL) + sin.sin_addr.s_addr = inet_addr(hostname); + else + ()memcpy(&sin.sin_addr.s_addr, h->h_addr, h->h_length); + + sin.sin_port = htons((ushort)80); + a = socket(AF_INET, SOCK_STREAM, 0); + if((connect(a, (struct sockaddr *) & sin, sizeof sin)) < 0) { + outs("\033[1;44m ³s±µ¨ü¨ì©Úµ´ ! \033[m"); + refresh(); + return; + } + sprintf(genbuf, "GET %s\n", file); +#endif + + for(i = strlen(file); file[i - 1] != '/' && i > 0 ; i--); + file[i] = 0; + + i = strlen(genbuf); + write(a, genbuf, i); + +#define BLANK 001 +#define ISPRINT 002 +#define PRE 004 +#define CENTER 010 + if((fp = fopen(userfile,"w"))) { + int flag = 2, c; + char path[MAXPATHLEN]; + unsigned char j, k; + + while((i = read(a,genbuf,200))) { + if(i < 0) + return; + genbuf[i]=0; + + for(j = 0, k = 0; genbuf[j] && j < i; j++) { + if((flag & ISPRINT) && genbuf[j] == '<') + flag |= BLANK; + else if((flag & ISPRINT) && genbuf[j] == '>') + flag &= ~BLANK; + else { + if(!(flag & BLANK)) { + if(j != k && (genbuf[j] != '\n' || flag & PRE)) + genbuf[k++] = genbuf[j]; + } else { + switch(char_lower(genbuf[j])) { + case 'a': + break; + case 'b': + if(genbuf[j + 1] == 'r' && genbuf[j + 2] == '>') + genbuf[k++] = '\n'; + break; + case 'h': + if(genbuf[j + 1] == 'r' && + (genbuf[j + 2] == '>' || + genbuf[j + 2] == 's')) { + strncpy(&genbuf[k], "\n--\n", 4); + k += 4; + } + break; + case 'l': + if(genbuf[j + 1] == 'i' && genbuf[j + 2]=='>') { + strncpy(&genbuf[k], "\n¡· ", 4); + k += 4; + } + break; + case 'p': + if(genbuf[j + 1]=='>') { + genbuf[k++] = '\n'; + genbuf[k++] = '\n'; + } else if(genbuf[j + 1] == 'r' && + genbuf[j + 2] == 'e') + flag ^= PRE; + break; + case 't': + if(genbuf[j + 1] == 'd' && genbuf[j + 2]=='>') { + strncpy(&genbuf[k], "\n-\n", 3); + k += 3; + } + break; + } + } + if((genbuf[j] & 0x80) && (flag & ISPRINT)) + flag &= ~ISPRINT; + else + flag |= ISPRINT; + } + } + genbuf[k]=0; + fputs(genbuf, fp); + } + fclose(fp); + close(a); + return more(userfile, promptend); + } + return 0; +#else /* use lynx dump */ + sprintf(genbuf, "lynx -dump http://%s%s > %s", hostname, file, userfile); + system(genbuf); + return more(userfile, promptend); +#endif +} diff --git a/mbbsd/name.c b/mbbsd/name.c new file mode 100644 index 00000000..2f84a1fe --- /dev/null +++ b/mbbsd/name.c @@ -0,0 +1,473 @@ +/* $Id: name.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <signal.h> +#include <sys/types.h> +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "proto.h" + +extern char *str_space; +extern int p_lines; /* a Page of Screen line numbers: tlines-4 */ +extern int b_lines; /* Screen bottom line number: t_lines-1 */ + +word_t *toplev = NULL; +static word_t *current = NULL; +static char *msg_more = "\033[7m-- More --\033[m"; + +typedef char (*arrptr)[]; +/* name complete for user ID */ + +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; + } + 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) + strcpy(cwbuf[num++], cwlist[n]); + } + return num; +} + +static void FreeNameList() { + word_t *p, *temp; + + for(p = toplev; p; p = temp) { + temp = p->next; + free(p->word); + free(p); + } +} + +void CreateNameList() { + if(toplev) + FreeNameList(); + toplev = current = NULL; +} + +void AddNameList(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(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; +} + +int InNameList(char *name) { + word_t *p; + + for(p = toplev; p; p = p->next) + if(!strcmp(p->word, name)) + return 1; + return 0; +} + +void ShowNameList(int row, int column, 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, char *listfile, char *msg) { + FILE *fp; + char genbuf[200]; + + if((fp = fopen(listfile, "r"))) { + while(fgets(genbuf, STRLEN, fp)) { + strtok(genbuf, str_space); + if(!InNameList(genbuf)) { + AddNameList(genbuf); + (*reciper)++; + } else { + RemoveNameList(genbuf); + (*reciper)--; + } + } + fclose(fp); + ShowNameList(3, 0, msg); + } +} + +static int NumInList(word_t *list) { + register int i; + + for(i = 0; list; i++) + list = list->next; + return i; +} + +int chkstr(char *otag, char *tag, char *name) { + char ch, *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(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; +} + +void namecomplete(char *prompt, char *data) { + char *temp; + word_t *cwlist, *morelist; + int x, y, origx, origy; + 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); + getyx(&origy, &origx); + standout(); + prints("%*s", IDLEN + 1, ""); + standend(); + move(y, x); + refresh(); + + while((ch = igetch()) != EOF) { + if(ch == '\n' || ch == '\r') { + *temp = '\0'; + outc('\n'); + if(NumInList(cwlist) == 1) + strcpy(data, cwlist->word); + ClearSubList(cwlist); + break; + } + if(ch == ' ') { + int col, len; + + if(NumInList(cwlist) == 1) { + strcpy(data, cwlist->word); + move(y, x); + outs(data + count); + count = strlen(data); + temp = data + count; + getyx(&y, &x); + continue; + } + clearbot = YEA; + col = 0; + if(!morelist) + morelist = cwlist; + len = MaxLen(morelist, p_lines); + move(2, 0); + clrtobot(); + printdash("¬ÛÃö¸ê°T¤@Äýªí"); + while(len + col < 80) { + 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) { + move(b_lines, 0); + outs(msg_more); + } + move(y, x); + continue; + } + if(ch == '\177' || ch == '\010') { + if(temp == data) + continue; + temp--; + count--; + *temp = '\0'; + ClearSubList(cwlist); + cwlist = GetSubList(data, toplev); + morelist = NULL; + x--; + move(y, x); + outc(' '); + move(y, x); + 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; + move(y, x); + outc(ch); + x++; + } + } + if(ch == EOF) + /* longjmp(byebye, -1); */ + raise(SIGHUP); /* jochang: don't know if this is necessary... */ + outc('\n'); + refresh(); + if(clearbot) { + move(2, 0); + clrtobot(); + } + if(*data) { + move(origy, origx); + outs(data); + outc('\n'); + } +} + +void usercomplete(char *prompt, char *data) { + char *temp; + char *cwbuf, *cwlist; + int cwnum, x, y, origx, origy; + int clearbot = NA, count = 0, morenum = 0; + char ch; + + cwbuf = malloc(MAX_USERS * (IDLEN + 1)); + cwlist = u_namearray((arrptr)cwbuf, &cwnum, ""); + temp = data; + + outs(prompt); + clrtoeol(); + getyx(&y, &x); + getyx(&origy, &origx); + standout(); + prints("%*s", IDLEN + 1, ""); + standend(); + move(y, x); + while((ch = igetch()) != EOF) { + if(ch == '\n' || ch == '\r') { + int i; + char *ptr; + + *temp = '\0'; + outc('\n'); + ptr = (char *)cwlist; + for(i = 0; i < cwnum; i++) { + if(strncasecmp(data, ptr, IDLEN + 1) == 0) + strcpy(data, ptr); + ptr += IDLEN + 1; + } + break; + } else if(ch == ' ') { + int col, len; + + if(cwnum == 1) { + strcpy(data, (char *)cwlist); + move(y, x); + outs(data + count); + count = strlen(data); + temp = data + count; + getyx(&y, &x); + continue; + } + clearbot = YEA; + col = 0; + len = UserMaxLen((arrptr)cwlist, cwnum, morenum, p_lines); + move(2, 0); + clrtobot(); + printdash("¨Ï¥ÎªÌ¥N¸¹¤@Äýªí"); + while(len + col < 79) { + int i; + + for(i = 0; morenum < cwnum && i < p_lines; i++) { + move(3 + i, col); + prints("%s ", 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); + outs(msg_more); + } else + morenum = 0; + move(y, x); + continue; + } else if(ch == '\177' || ch == '\010') { + if(temp == data) + continue; + temp--; + count--; + *temp = '\0'; + cwlist = u_namearray((arrptr)cwbuf, &cwnum, data); + morenum = 0; + x--; + move(y, x); + outc(' '); + move(y, x); + continue; + } else if(count < STRLEN && isprint(ch)) { + int n; + + *temp++ = ch; + *temp = '\0'; + n = UserSubArray((arrptr)cwbuf, (arrptr)cwlist, cwnum, ch, count); + if(n == 0) { + temp--; + *temp = '\0'; + continue; + } + cwlist = cwbuf; + count++; + cwnum = n; + morenum = 0; + move(y, x); + outc(ch); + x++; + } + } + free(cwbuf); + if(ch == EOF) + /* longjmp(byebye, -1); */ + raise(SIGHUP); /* jochang: don't know if this is necessary */ + outc('\n'); + refresh(); + if(clearbot) { + move(2, 0); + clrtobot(); + } + if(*data) { + move(origy, origx); + outs(data); + outc('\n'); + } +} diff --git a/mbbsd/osdep.c b/mbbsd/osdep.c new file mode 100644 index 00000000..967a4db0 --- /dev/null +++ b/mbbsd/osdep.c @@ -0,0 +1,79 @@ +/* $Id: osdep.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <unistd.h> + +#if defined(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(long *total, long *used) { + double percent = -1; + char buf[101]; + FILE *fp; + + if((fp = fopen("/proc/meminfo","r"))) { + while(fgets(buf, 100, fp) && buf[0] != 'S'); + if(sscanf(buf + 6, "%ld %ld", total, used) == 2) + if(*total != 0) + percent = (double)*used / (double)*total; + fclose(fp); + } + return percent; +} + +#elif __FreeBSD__ >=4 + +#include <kvm.h> + +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]; +} + +double swapused(long *total, long *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 diff --git a/mbbsd/othello.c b/mbbsd/othello.c new file mode 100644 index 00000000..47b8cef3 --- /dev/null +++ b/mbbsd/othello.c @@ -0,0 +1,541 @@ +/* $Id: othello.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "modes.h" +#include "proto.h" + +extern char *BBSName; + +#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) + +static char nowx = 3, nowy = 3; +static char *CHESS_TYPE[] = {NONE_CHESS, HINT_CHESS, BLACK_CHESS, WHITE_CHESS}; +static char DIRX[] = {-1,-1,-1, 0, 1, 1, 1, 0}; +static char DIRY[] = {-1, 0, 1, 1, 1, 0,-1,-1}; +static char number[2]; + +static char pass = 0; +static char if_hint = 0; +static int think, which_table; + +static char nowboard[10][10]= +{{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {-1, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, -1}, + {-1, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, -1}, + {-1, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, -1}, + {-1, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, -1}, + {-1, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, -1}, + {-1, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, -1}, + {-1, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, -1}, + {-1, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, -1}, + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}; +static 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 char table[NR_TABLE + 1][10][10]; +static void print_chess(int x, int y, char chess) { + move(STARTX - 1 + x * 2, STARTY - 2 + y * 4); + if(chess != HINT || if_hint == 1) + prints(CHESS_TYPE[(int)chess]); + else + prints(CHESS_TYPE[NONE]); + refresh(); +} + +extern userec_t cuser; + +static void printboard() { + int i; + + move(STARTX, STARTY); + prints("¢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); + prints ("¢x ¢x ¢x ¢x ¢x ¢x ¢x ¢x ¢x"); + move(STARTX + 2 + i * 2, STARTY); + prints ("¢u¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢q¢w¢t"); + } + move(STARTX + 1 + i * 2, STARTY); + prints("¢x ¢x ¢x ¢x ¢x ¢x ¢x ¢x ¢x"); + move(STARTX + 2 + i * 2, STARTY); + prints("¢|¢w¢r¢w¢r¢w¢r¢w¢r¢w¢r¢w¢r¢w¢r¢w¢}"); + print_chess(4, 4, WHITE); + print_chess(5, 5, WHITE); + print_chess(4, 5, BLACK); + print_chess(5, 4, BLACK); + move(3, 56); + prints("(¶Â)%s",cuser.userid); + move(3, 72); + prints(": 02"); + move(4, 56); + prints("(¥Õ)¹q¸£ : 02"); + move(6, 56); + prints("¡ ¥i¥H¤U¤§³B"); + move(7, 56); + prints("[q] °h¥X"); + move(8, 56); + prints("[h] ¶}±Ò/Ãö³¬ ´£¥Ü"); + move(9,56); + prints("[Enter][Space] ¤U´Ñ"); + move(10, 56); + prints("¤W:¡ô, i"); + move(11, 56); + prints("¤U:¡õ, k"); + move(12, 56); + prints("¥ª:¡ö, j"); + move(13, 56); + prints("¥k:¡÷, l"); +} + +static int get_key(char nowx, char nowy) { + int ch; + + move(STARTX - 1 + nowx * 2, STARTY - 1 + nowy * 4); + ch = igetkey(); + move(STARTX - 1 + nowx * 2, STARTY - 2 + nowy * 4); + if(nowboard[(int)nowx][(int)nowy] != HINT || if_hint==1) + outs(CHESS_TYPE[(int)nowboard[(int)nowx][(int)nowy]]); + 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(char color) { + int i, j, temp = 0; + + for(i = 1; i <= 8; i++) + for(j = 1; j <= 8; j++) { + if(nowboard[i][j] == HINT) + nowboard[i][j] = NONE; + if(if_can_put(i, j, color, nowboard)) { + nowboard[i][j] = HINT; + temp++; + } + print_chess(i, j, 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(int quit) { + FILE *fp,*fp1; + char *opponent[] = {"","CD-65","","À¦¨à","¤p«Ä","","¤j¤H","±M®a"}; + + move(STARTX - 1, 30); + prints (" "); + move(22, 35); + fp = fopen(LOGFILE, "a"); + if(!quit) { + fp1 = fopen(SECRET, "a"); + if(fp1) { + fprintf(fp1, "%d,%d,%s,%02d,%02d\n", think, which_table, + cuser.userid, number[0], number[1]); + fclose(fp1); + } + } + + if(quit) { + if(number[0] == 2 && number[1] == 2) { + if(fp) + fclose(fp); + return; + } + fprintf(fp, "¦b%s¯Å¤¤, %sÁ{°}²æ°k\n", opponent[think], cuser.userid); + if(fp) + fclose(fp); + return; + } + if(number[0] > number[1]) { + prints("§AŤF¹q¸£%02d¤l", number[0] - number[1]); + if(think == 6 && number[0] - number[1] >= 50) + demoney(200); + if(think == 7 && number[0] - number[1] >= 40) + demoney(200); + if(fp) + fprintf(fp, "¦b%s¯Å¤¤, %s¥H %02d:%02d ŤF¹q¸£%02d¤l\n", + opponent[think], cuser.userid, number[0], number[1], + number[0] - number[1]); + } else if(number[1] > number[0]) { + prints("¹q¸£Ä¹¤F§A%02d¤l", number[1] - number[0]); + if(fp) { + fprintf(fp, "¦b%s¯Å¤¤, ", opponent[think]); + if(number[1] - number[0] > 20) + fprintf(fp, "¹q¸£¥H %02d:%02d ºG¹q%s %02d¤l\n", number[1], + number[0], cuser.userid, number[1] - number[0]); + else + fprintf(fp, "¹q¸£¥H %02d:%02d ŤF%s %02d¤l\n", number[1], + number[0], cuser.userid, number[1] - number[0]); + } + } else { + prints("§A©M¹q¸£¥´¦¨¥¤â!!"); + if(fp) + fprintf(fp, "¦b%s¯Å¤¤, %s©M¹q¸£¥H %02d:%02d ¥´¦¨¤F¥¤â\n", + opponent[think], cuser.userid, number[1], number[0]); + } + if(fp) + fclose(fp); + move(1,1); + igetkey(); +} + +static void othello_redraw() { + int i, j; + + for(i = 1; i <= 8; i++) + for(j = 1; j <= 8; j++) + print_chess(i, j, nowboard[i][j]); +} + +static int player(char color) { + int ch; + + if(get_hint(color)) { + while(true) { + ch = get_key(nowx,nowy); + switch(ch) { + case 'J': + case 'j': + case KEY_LEFT: + nowy--; + break; + case 'L': + case 'l': + case KEY_RIGHT: + nowy++; + break; + case 'I': + case 'i': + case KEY_UP: + nowx--; + break; + case 'K': + case 'k': + case KEY_DOWN: + nowx++; + break; + case ' ': + case '\r': + if(nowboard[(int)nowx][(int)nowy] != HINT) + break; + pass = 0; + nowboard[(int)nowx][(int)nowy] = color; + eat(nowx, nowy, color, nowboard); + print_chess(nowx, nowy, color); + return true; + case 'q': + end_of_game(1); + return false; + case 'H': + case 'h': + if_hint = if_hint^1; + othello_redraw(); + break; + } + if(nowx == 9) + nowx=1; + if(nowx == 0) + nowx=8; + if(nowy == 9) + nowy=1; + if(nowy == 0) + nowy=8; + } + } else { + pass++; + if(pass == 1) { + move(23, 34); + prints("§A¥²»Ý©ñ±ó³o¤@¨B!!"); + igetch(); + move(28,23); + prints(" "); + } else { + end_of_game(0); + return false; + } + } + return 0; +} + +static void init() { + int i, j, i1, j1; + + nowx = 4; + nowy = 4; + number[0] = 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); + table[0][i][j] = init_table[0][i1][j1]; + table[1][i][j] = init_table[1][i1][j1]; + } + for(i = 1; i <= 8; i++) + for(j = 1; j <= 8; j++) + nowboard[i][j] = NONE; + nowboard[4][4] = nowboard[5][5] = WHITE; + nowboard[4][5] = nowboard[5][4] = BLACK; +} + +static void report() { + int i, j; + + number[0] = number[1] = 0; + for(i = 1; i <= 8; i++) + for(j = 1; j <= 8; j++) + if(nowboard[i][j] == BLACK) + number[0]++; + else if(nowboard[i][j] == WHITE) + number[1]++; + move(3, 60); + prints("%s", cuser.userid); + move(3, 72); + prints(": %02d", number[0]); + move(4, 60); + prints("¹q¸£ : %02d", number[1]); +} + +static int EVL(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 += table[table_number][a][b]; + else + points -= table[table_number][a][b]; + } + return ((color == BLACK) ? points : -points); +} + +static int alphabeta(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(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(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(chessboard, color, table); + return ((level & 1) ? alpha : beta); +} + +static int Computer(int thinkstep, int table) { + int i, j, maxi = 0, maxj = 0, level = 1; + char chessboard[10][10]; + int alpha = -10000, k; + if((number[0] + 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,nowboard)) { + memcpy(chessboard, nowboard, sizeof(char) * 100); + eat(i, j, WHITE, chessboard); + k = alphabeta(alpha, 10000, level + 1, chessboard, thinkstep, + BLACK, table); + if(k > alpha) { + alpha = k; + maxi = i; + maxj = j; + } + } + } + if(alpha != -10000) { + eat(maxi, maxj, WHITE, nowboard); + pass = 0; + nowx = maxi; + nowy = maxj; + } else { + move(23, 30); + prints("¹q¸£©ñ±ó³o¤@¨B´Ñ!!"); + pass++; + if(pass == 2) { + move(23, 24); + prints(" "); + end_of_game(0); + return false; + } + igetch(); + move(23, 24); + prints(" "); + } + return true; +} + +static int choose() { + char thinkstep[2]; + + move(2, 0); + prints("½Ð¿ï¾ÜÃø«×:"); + move(5, 0); + prints("(1) CD-65\n"); /* ·Q 1 ¨B */ + prints("(2) À¦¨à\n"); /* ·Q 3 ¨B */ + prints("(3) ¤p«Ä\n"); /* ·Q 4 ¨B */ + do { + getdata(4, 0, "½Ð¿ï¾Ü¤@Ó¹ï¶H©M±z¹ï¥´:(1~5)", thinkstep, 2, LCECHO); + } 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() { + lockreturn0(OTHELLO, LOCK_MULTI); + clear(); + init(); + think = choose(); + showtitle("¶Â¥Õ´Ñ", BBSName); + printboard(); + which_table = rand() % NR_TABLE; + while(true) { + move(STARTX - 1, 30); + prints("½ü¨ì§A¤U¤F..."); + if(!player(BLACK)) + break; + report(); + othello_redraw(); + if(number[0] + number[1] == 64) { + end_of_game(0); + break; + } + move(STARTX - 1, 30); + prints("¹q¸£«ä¦Ò¤¤..."); + refresh(); + if(!Computer(think, which_table)) + break; + report(); + othello_redraw(); + if(number[0] + number[1] == 64) { + end_of_game(0); + break; + } + } + more(LOGFILE, YEA); + unlockutmpmode(); + return 1; +} diff --git a/mbbsd/page.c b/mbbsd/page.c new file mode 100644 index 00000000..c77ef421 --- /dev/null +++ b/mbbsd/page.c @@ -0,0 +1,130 @@ +/* $Id: page.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include "config.h" +#include "pttstruct.h" +#include "modes.h" +#include "common.h" +#include "proto.h" + +#define hpressanykey(a) {move(22, 0); prints(a); pressanykey();} +static void filt_railway(char* fpath) { + char buf[256], tmppath[32]; + FILE* fp = fopen(fpath, "w"), *tp; + + sprintf(tmppath, "%s.railway", fpath); + if(!fp || !(tp = fopen(tmppath, "r"))) + return; + + while(fgets(buf, 255, tp)) { + if(strstr(buf, "INLINE")) + continue; + if(strstr(buf, "LINK")) + break; + fprintf(fp, "%s", buf); + } + fclose(fp); + fclose(tp); + unlink(tmppath); +} + +extern userec_t cuser; + +int main_railway() { + fileheader_t mhdr; + char genbuf[200]; + int from, to, time_go, time_reach; + char tt[2], type[2]; + char command[256], buf[8]; + char *addr[]= { + "°ò¶©", "¤K°ô", "¤C°ô", "¤°ô", "¦Á¤î", "«n´ä", "ªQ¤s", "¥x¥_", "¸UµØ", + "ªO¾ô", "¾ðªL", "¤s¨Î", "Åaºq", "®ç¶é", "¤ºÃc", "¤¤Ãc", "®H¤ß", "·¨±ö", + "´ò¤f", "·sÂ×", "¦Ë¥_", "·s¦Ë", "»¤s", "±T³»", "¦Ë«n", "³y¾ô", "Â×´I", + "½Í¤å", "¤j¤s", "«áÀs", "Às´ä", "¥Õ¨F¤Ù", "·s®H", "³q¾]", "b¸Ì", + "¤é«n", "¤j¥Ò", "»O¤¤´ä", "²M¤ô", "¨F³À", "Às¤«", "¤j¨{", "°l¤À", + "]®ß", "«n¶Õ", "»ÉÆr", "¤T¸q", "³Ó¿³", "®õ¦w", "¦Z¨½", "Â×ì", "¼æ¤l", + "¥x¤¤", "¯Q¤é", "¦¨¥\\", "¹ü¤Æ", "ªá¾Â", "ûªL", "¥Ã¹t", "ªÀÀY", + "¥Ð¤¤", "¤G¤ô", "ªL¤º", "¥Ûºh", "¤æ¤»", "¤æ«n", "¥ÛÀt", "¤jªL", + "¥Á¶¯", "¹Å¸q", "¤ô¤W", "«n¹t", "«á¾À", "·sÀç", "¬hÀç", "ªL»ñÀç", + "¶©¥Ð", "©ÞªL", "µ½¤Æ", "·s¥«", "¥Ã±d", "¥x«n", "«O¦w", "¤¤¬w", + "¤j´ò", "¸ô¦Ë", "©£¤s", "¾ôÀY", "·£±ê", "¥ªÀç", "°ª¶¯", "»ñ¤s", + "¤E¦±°ó", "«ÌªF", NULL, NULL + }; + + setutmpmode(RAIL_WAY); + clear(); + move(0,25); + prints("\033[1;37;45m ¤õ¨®¬d¸ß¨t²Î \033[1;44;33m§@ªÌ:Heat\033[m"); + move(1,0); + outs("\033[1;33m + 1.°ò¶© 16.¤¤Ãc 31.Às´ä 46.»ÉÆr 61.¥Ð¤¤ 76.ªL»ñÀç 91.°ª¶¯ + 2.¤K°ô 17.®H¤ß 32.¥Õ¨F¤Ù 47.¤T¸q 62.¤G¤ô 77.¶©¥Ð 92.»ñ¤s + 3.¤C°ô 18.·¨±ö 33.·s®H 48.³Ó¿³ 63.ªL¤º 78.©ÞªL 93.¤E¦±°ó + 4.¤°ô 19.´ò¤f 34.³q¾] 49.®õ¦w 64.¥Ûºh 79.µ½¤Æ 94.«ÌªF + 5.¦Á¤î 20.·sÂ× 35.b¸Ì 50.¦Z¨½ 65.¤æ¤» 80.·s¥« + 6.«n´ä 21.¦Ë¥_ 36.¤é«n 51.Â×ì 66.¤æ«n 81.¥Ã±d + 7.ªQ¤s 22.·s¦Ë 37.¤j¥Ò 52.¼æ¤l 67.¥ÛÀt 82.¥x«n + 8.¥x¥_ 23.»¤s 38.»O¤¤´ä 53.¥x¤¤ 68.¤jªL 83.«O¦w + 9.¸UµØ 24.±T³» 39.²M¤ô 54.¯Q¤é 69.¥Á¶¯ 84.¤¤¬w +10.ªO¾ô 25.¦Ë«n 40.¨F³À 55.¦¨¥\\ 70.¹Å¸q 85.¤j´ò +11.¾ðªL 26.³y¾ô 41.Às¤« 56.¹ü¤Æ 71.¤ô¤W 86.¸ô¦Ë +12.¤s¨Î 27.Â×´I 42.¤j¨{ 57.ªá¾Â 72.«n¹t 87.©£¤s +13.Åaºq 28.½Í¤å 43.°l¤À 58.ûªL 73.«á¾À 88.¾ôÀY +14.®ç¶é 29.¤j¤s 44.]®ß 59.¥Ã¹t 74.·sÀç 89.·£±ê +15.¤ºÃc 30.«áÀs 45.«n¶Õ 60.ªÀÀY 75.¬hÀç 90.¥ªÀç\033[m"); + + getdata(17, 0, "\033[1;35m§A½T©wn·j´M¶Ü?[y/n]:\033[m", buf, 2, LCECHO); + if(buf[0] != 'y' && buf[0] != 'Y') + return 0; + while(1) + if(getdata(18, 0, "\033[1;35m½Ð¿é¤J°_¯¸(1-94):\033[m", buf, 3, LCECHO) && + (from = atoi(buf)) >= 1 && from <= 94) + break; + while(1) + if(getdata(18, 40, "\033[1;35m½Ð¿é¤J¥Øªº¦a(1-94):\033[m", + buf, 3, LCECHO) && + (to = atoi(buf)) >= 1 && to <= 94) + break; + while(1) + if(getdata(19, 0, "\033[1;35m½Ð¿é¤J®É¶¡°Ï¬q(0-23) ¥Ñ:\033[m", + buf,3,LCECHO) && + (time_go = atoi(buf)) >= 0 && time_go <= 23) + break; + while(1) + if(getdata(19, 40, "\033[1;35m¨ì:\033[m", buf, 3, LCECHO) && + (time_reach=atoi(buf)) >= 0 && time_reach <= 23) + break; + while(1) + if(getdata(20, 0, "\033[1;35m·Q¬d¸ß 1:¹ï¸¹§Ö¨® 2:´¶³q¥§Ö\033[m", + type,2,LCECHO) && (type[0] == '1' || type[0] == '2')) + break; + while(1) + if(getdata(21, 0, "\033[1;35m±ý¬d¸ß 1:¥Xµo®É¶¡ 2:¨ì¹F®É¶¡\033[m", + tt, 2, LCECHO) && + (tt[0]=='1' || tt[0]=='2')) + break; + sethomepath(genbuf, cuser.userid); + stampfile(genbuf, &mhdr); + strcpy(mhdr.owner, "Ptt·j´M¾¹"); + strncpy(mhdr.title, "¤õ¨®®É¨è·j´Mµ²ªG", TTLEN); + mhdr.savemode = '\0'; + + sprintf(command,"echo \"from-station=%s&to-station=%s" + "&from-time=%02d00&to-time=%02d00&tt=%s&type=%s\" | " + "lynx -dump -post_data " + "\"http://www.railway.gov.tw/cgi-bin/timetk.cgi\" > %s.railway", + addr[from - 1], addr[to - 1], time_go, time_reach, + (tt[0] == '1') ? "start" : "arriv", + (type[0] == '1') ? "fast" : "slow", genbuf); + + system(command); + filt_railway(genbuf); + sethomedir(genbuf, cuser.userid); + if(append_record(genbuf, &mhdr, sizeof(mhdr)) == -1) + return -1; + hpressanykey("\033[1;31m§ÚÌ·|§â·j´Mµ²ªG«Ü§Ö´N±Hµ¹§Aò ^_^\033[m"); + return 0; +} diff --git a/mbbsd/passwd.c b/mbbsd/passwd.c new file mode 100644 index 00000000..28a31119 --- /dev/null +++ b/mbbsd/passwd.c @@ -0,0 +1,138 @@ +/* $Id: passwd.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/mman.h> +#include <sys/ipc.h> +#include <sys/sem.h> +#include "config.h" +#include "pttstruct.h" +#include "modes.h" +#include "proto.h" + +extern char *fn_passwd; + +static userec_t *passwd_image = NULL; +static int passwd_image_size; +static int semid = -1; + +#ifndef SEM_R +#define SEM_R 0400 +#endif + +#ifndef SEM_A +#define SEM_A 0200 +#endif + +#ifndef __FreeBSD__ +union semun { + int val; /* value for SETVAL */ + struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */ + u_short *array; /* array for GETALL & SETALL */ + struct seminfo *__buf; /* buffer for IPC_INFO */ +}; +#endif + +int passwd_mmap() { + int fd; + + fd = open(fn_passwd, O_RDWR); + if(fd > 0) + { + struct stat st; + + fstat(fd, &st); + passwd_image_size = st.st_size; + passwd_image = mmap(NULL, passwd_image_size, + PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if(passwd_image == (userec_t *)-1) { + perror("mmap"); + return -1; + } +/* rocker 011018: after success get mmap, close file descript */ + close (fd); + + semid = semget(PASSWDSEM_KEY, 1, SEM_R | SEM_A | IPC_CREAT | IPC_EXCL); + if(semid == -1) { + if(errno == EEXIST) { + semid = semget(PASSWDSEM_KEY, 1, SEM_R | SEM_A); + if(semid == -1) { + perror("semget"); + exit(1); + } + } else { + perror("semget"); + exit(1); + } + } else { + union semun s; + + s.val = 1; + if(semctl(semid, 0, SETVAL, s) == -1) { + perror("semctl"); + exit(1); + } + } + } else { + perror(fn_passwd); + return -1; + } + return 0; +} + +extern int usernum; +int passwd_update_money(int num) { + int money; + if(num < 1 || num > MAX_USERS) + return -1; + money = moneyof(num); + memcpy(&passwd_image[num - 1].money, &money, sizeof(int)); + return 0; +} + +int passwd_update(int num, userec_t *buf) { + if(num < 1 || num > MAX_USERS) + return -1; + buf->money = moneyof(num); + memcpy(&passwd_image[num - 1], buf, sizeof(userec_t)); + return 0; +} + +int passwd_query(int num, userec_t *buf) { + if(num < 1 || num > MAX_USERS) + return -1; + memcpy(buf, &passwd_image[num - 1], sizeof(userec_t)); + return 0; +} + +int passwd_apply(int (*fptr)(userec_t *)) { + int i; + + for(i = 0; i < MAX_USERS; i++) + if((*fptr)(&passwd_image[i]) == QUIT) + return QUIT; + return 0; +} + +void passwd_lock() { + struct sembuf buf = { 0, -1, SEM_UNDO }; + + if(semop(semid, &buf, 1)) { + perror("semop"); + exit(1); + } +} + +void passwd_unlock() { + struct sembuf buf = { 0, 1, SEM_UNDO }; + + if(semop(semid, &buf, 1)) { + perror("semop"); + exit(1); + } +} diff --git a/mbbsd/read.c b/mbbsd/read.c new file mode 100644 index 00000000..b92f95e7 --- /dev/null +++ b/mbbsd/read.c @@ -0,0 +1,998 @@ +/* $Id: read.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <unistd.h> +#include <stdlib.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include "config.h" +#include "pttstruct.h" +#include "modes.h" +#include "common.h" +#include "perm.h" +#include "proto.h" + +#define MAXPATHLEN 256 + +extern int p_lines; /* a Page of Screen line numbers: tlines-4 */ +extern int b_lines; /* Screen bottom line number: t_lines-1 */ +extern char currowner[IDLEN + 2]; +extern char currtitle[44]; +extern char currauthor[IDLEN + 2]; +extern char *str_reply; +extern char *msg_fwd_ok; +extern char *msg_fwd_err1; +extern char *msg_fwd_err2; +extern int currmode; +extern unsigned int currstat; +extern char currboard[]; /* name of currently selected board */ +extern int KEY_ESC_arg; +extern int curredit; +extern char *msg_mailer; +extern int currbid; +extern bcache_t *brdshm; + +char currdirect[64]; +static fileheader_t *headers = NULL; +static int last_line; +static int hit_thread; + +/* rocker.011018: add new tag */ + +extern int rget(); +extern char getans(); +extern void touchdircache(); +extern int get_fileheader_cache(); + +/* rocker.011018: ·sªºtag¤è¦¡ */ + +#define MAXTAGS 256 + +#include <sys/mman.h> + +typedef struct +{ + time_t chrono; + int recno; +} TagItem; + + +/* ----------------------------------------------------- */ +/* Tag List ¼ÐÅÒ */ +/* ----------------------------------------------------- */ + + +int TagNum; /* tag's number */ +TagItem TagList[MAXTAGS]; /* ascending list */ + +void +UnTagger (int locus) +{ + if (locus > TagNum) return; + + TagNum--; + + if (TagNum > locus) + memcpy(&TagList[locus], &TagList[locus + 1], + (TagNum - locus) * sizeof(TagItem)); +} + +int +Tagger(time_t chrono, int recno, int mode) +{ + int head, tail, posi = 0, comp; + + 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) + return NA; + + TagNum--; + memcpy(&TagList[posi], &TagList[posi + 1], + (TagNum - posi) * sizeof(TagItem)); + } + else if (TagNum < MAXTAGS) + { + TagItem *tagp, buf[MAXTAGS]; + + tail = (TagNum - head) * sizeof(TagItem); + tagp = &TagList[head]; + memcpy(buf, tagp, tail); + tagp->chrono = chrono; + tagp->recno = recno; + memcpy(++tagp, buf, tail); + TagNum++; + } + else + { + bell(); + return 0; /* full */ + } + return YEA; +} + + +void +EnumTagName( char *fname, int locus) +{ + sprintf(fname, "M.%d.A", (int) TagList[locus].chrono); +} + +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(char *msg) +{ + char buf[80]; + int num; + + num = TagNum; + sprintf(buf, "¡» %s A)¤å³¹ T)¼Ð°O Q)uit?", msg); + switch (rget(b_lines-1, buf)) + { + case 'q': + num = -1; + break; + case 'a': + num = 0; + } + return num; +} + + +#include <sys/mman.h> + +#define BATCH_SIZE 65536 + +char * +f_map (char *fpath, int *fsize) +{ + int fd, size; + struct stat st; + + 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; + } + + fpath = (char *) mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); + close(fd); + *fsize = size; + return fpath; +} + + +static int +TagThread(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) +{ + if (TagNum && ((currstat != READING) || (currmode & MODE_BOARD))) + { + if(getans("§R°£©Ò¦³¼Ð°O[N]?") != 'y') + return FULLUPDATE; + delete_range(currdirect, 0, 0); + TagNum = 0; + if(bid>0); + setbtotal(bid); + return NEWDIRECT; + } + return DONOTHING; +} + + +/* ----------------------------------------------------- */ +/* cursor & reading record position control */ +/* ----------------------------------------------------- */ +keeploc_t *getkeep(char *s, int def_topline, int def_cursline) { + static struct keeploc_t *keeplist = NULL; + struct keeploc_t *p; + void *malloc(); + + if(def_cursline >= 0) + for(p = keeplist; p; p = p->next) { + if(!strcmp(s, p->key)) { + if(p->crs_ln < 1) + p->crs_ln = 1; + return p; + } + } + else + def_cursline = -def_cursline; + p = (keeploc_t *)malloc(sizeof(keeploc_t)); + p->key = (char *)malloc(strlen(s) + 1); + strcpy(p->key, s); + p->top_ln = def_topline; + p->crs_ln = def_cursline; + p->next = keeplist; + return (keeplist = p); +} + +void fixkeep(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 top; + + if(val > last_line) { + bell(); + val = last_line; + } + if(val <= 0) { + bell(); + val = 1; + } + + top = locmem->top_ln; + if(val >= top && val < top + p_lines) { + cursor_clear(3 + locmem->crs_ln - top, 0); + locmem->crs_ln = val; + cursor_show(3 + val - top, 0); + return DONOTHING; + } + locmem->top_ln = val - from_top; + if(locmem->top_ln <= 0) + locmem->top_ln = 1; + locmem->crs_ln = val; + return PARTUPDATE; +} + +static int move_cursor_line(keeploc_t *locmem, int mode) { + int top, crs; + int reload = 0; + + top = locmem->top_ln; + crs = locmem->crs_ln; + if(mode == READ_PREV) { + if(crs <= top) { + top -= p_lines - 1; + if(top < 1) + top = 1; + reload = 1; + } + if(--crs < 1) { + crs = 1; + reload = -1; + } + } else if(mode == READ_NEXT) { + if(crs >= top + p_lines - 1) { + top += p_lines - 1; + reload = 1; + } + if(++crs > last_line) { + crs = last_line; + reload = -1; + } + } + locmem->top_ln = top; + locmem->crs_ln = crs; + return reload; +} + +static int thread(keeploc_t *locmem, int stype) { + static char a_ans[32], t_ans[32]; + char ans[32], s_pmt[64]; + register char *tag, *query = NULL; + register int now, pos, match, near = 0; + fileheader_t fh; + int circulate_flag = 1; /* circulate at end or begin */ + + match = hit_thread = 0; + now = pos = locmem->crs_ln; + if(stype == 'A') { + if(!*currowner) + return DONOTHING; + str_lower(a_ans, currowner); + query = a_ans; + circulate_flag = 0; + stype = 0; + } else if(stype == 'a') { + if(!*currowner) + return DONOTHING; + str_lower(a_ans, currowner); + query = a_ans; + circulate_flag = 0; + stype = RS_FORWARD; + } else if(stype == '/') { + if(!*t_ans) + return DONOTHING; + query = t_ans; + circulate_flag = 0; + stype = RS_TITLE | RS_FORWARD; + } else if(stype == '?') { + if(!*t_ans) + return DONOTHING; + circulate_flag = 0; + query = t_ans; + stype = RS_TITLE; + } else if(stype & RS_RELATED) { + tag = headers[pos - locmem->top_ln].title; + if(stype & RS_CURRENT) { + if(stype & RS_FIRST) { + if(!strncmp(currtitle, tag, 40)) + return DONOTHING; + near = 0; + } + query = currtitle; + } else { + query = subject(tag); + if(stype & RS_FIRST) { + if(query == tag) + return DONOTHING; + near = 0; + } + } + } else if(!(stype & RS_THREAD)) { + query = (stype & RS_TITLE) ? t_ans : a_ans; + if(!*query && query == a_ans) { + if(*currowner) + strcpy(a_ans, currowner); + else if (*currauthor) + strcpy(a_ans, currauthor); + } + sprintf(s_pmt, "%s·j´M%s [%s] ",(stype & RS_FORWARD) ? "©¹«á":"©¹«e", + (stype & RS_TITLE) ? "¼ÐÃD" : "§@ªÌ", query); + getdata(b_lines - 1, 0, s_pmt, ans, 30, DOECHO); + if(*ans) + strcpy(query, ans); + else if(*query == '\0') + return DONOTHING; + } + + tag = fh.owner; + + do { + if(!circulate_flag || stype & RS_RELATED) { + if(stype & RS_FORWARD) { + if(++now > last_line) + return DONOTHING; + } else { + if(--now <= 0) { + if((stype & RS_FIRST) && (near)) { + hit_thread = 1; + return cursor_pos(locmem, near, 10); + } + return DONOTHING; + } + } + } else { + if(stype & RS_FORWARD) { + if(++now > last_line) + now = 1; + } else if(--now <= 0) + now = last_line; + } + + get_record(currdirect, &fh, sizeof(fileheader_t), now); + + if(fh.owner[0] == '-') + continue; + + if(stype & RS_THREAD) { + if(strncasecmp(fh.title, str_reply, 3)) { + hit_thread = 1; + return cursor_pos(locmem, now, 10); + } + continue; + } + + if(stype & RS_TITLE) + tag = subject(fh.title); + + if(((stype & RS_RELATED) && !strncmp(tag, query, 40)) || + (!(stype & RS_RELATED) && ((query == currowner) ? + !strcmp(tag, query) : + strstr_lower(tag, query)))) { + if((stype & RS_FIRST) && tag != fh.title) { + near = now; + continue; + } + + hit_thread = 1; + match = cursor_pos(locmem, now, 10); + if((!(stype & RS_CURRENT)) && + (stype & RS_RELATED) && + strncmp(currtitle, query, 40)) { + strncpy(currtitle, query, 40); + match = PARTUPDATE; + } + break; + } + } while(now != pos); + + return match; +} + + +#ifdef INTERNET_EMAIL +static void mail_forward(fileheader_t *fhdr, char *direct, int mode) { + int i; + char buf[STRLEN]; + char *p; + + strncpy(buf, direct, sizeof(buf)); + if((p = strrchr(buf, '/'))) + *p = '\0'; + switch(i = doforward(buf, fhdr, mode)) { + case 0: + outmsg(msg_fwd_ok); + break; + case -1: + outmsg(msg_fwd_err1); + break; + case -2: + outmsg(msg_fwd_err2); + break; + default: + break; + } + refresh(); + sleep(1); +} +#endif + +extern userec_t cuser; + +static int select_read(keeploc_t *locmem, int sr_mode) { + register char *tag,*query,*temp; + fileheader_t fh; + char fpath[80], genbuf[MAXPATHLEN], buf3[5]; + char static t_ans[TTLEN+1]=""; + char static a_ans[IDLEN+1]=""; + int fd, fr, size = sizeof(fileheader_t); + struct stat st; +/* rocker.011018: make a reference number for process article */ + int reference = 0; + + if((currmode & MODE_SELECT)) + return -1; + if(sr_mode == RS_TITLE) + query = subject(headers[locmem->crs_ln - locmem->top_ln].title); + else if(sr_mode == RS_NEWPOST) + { + strcpy(buf3, "Re: "); + query = buf3; + } + else + { + char buff[80]; + + query = (sr_mode == RS_RELATED) ? t_ans : a_ans; + sprintf(buff, "·j´M%s [%s] ", + (sr_mode == RS_RELATED) ? "¼ÐÃD" : "§@ªÌ", query); + getdata(b_lines, 0,buff, query, 30, DOECHO); + if(!(*query)) + return DONOTHING; + } + + if((fd = open(currdirect, O_RDONLY, 0)) != -1) { + sprintf(genbuf,"SR.%s",cuser.userid); + if(currstat==RMAIL) + sethomefile(fpath,cuser.userid,genbuf); + else + setbfile(fpath,currboard,genbuf); + if(((fr = open(fpath,O_WRONLY | O_CREAT | O_TRUNC,0600)) != -1)) { + switch(sr_mode) { + case RS_TITLE: + while(read(fd,&fh,size) == size) { + ++reference; + tag = subject(fh.title); + if(!strncmp(tag, query, 40)) + { + fh.money = reference | FHR_REFERENCE; + write(fr,&fh,size); + } + } + break; + case RS_RELATED: + while(read(fd,&fh,size) == size) { + ++reference; + tag = fh.title; + if(strcasestr(tag,query)) + { + fh.money = reference | FHR_REFERENCE; + write(fr,&fh,size); + } + } + break; + case RS_NEWPOST: + while(read(fd, &fh, size) == size) { + ++reference; + tag = fh.title; + temp = strstr(tag, query); + if(temp == NULL || temp != tag) + { + write(fr, &fh, size); + fh.money = reference | FHR_REFERENCE; + } + } + case RS_AUTHOR: + while(read(fd,&fh,size) == size) { + ++reference; + tag = fh.owner; + if(strcasestr(tag,query)) + { + write(fr,&fh,size); + fh.money = reference | FHR_REFERENCE; + } + } + break; + } + fstat(fr,&st); + close(fr); + } + close(fd); + if(st.st_size) { + currmode |= MODE_SELECT; + strcpy(currdirect,fpath); + } + } + return st.st_size; +} + +extern userec_t xuser; + +static int i_read_key(onekey_t *rcmdlist, keeploc_t *locmem, int ch, int bid) { + int i, mode = DONOTHING; + + switch(ch) { + case 'q': + case 'e': + case KEY_LEFT: + return (currmode & MODE_SELECT) ? board_select() : + (currmode & MODE_ETC) ? board_etc() : + (currmode & MODE_DIGEST) ? board_digest() : DOQUIT; + case Ctrl('L'): + redoscr(); + break; +/* + case Ctrl('C'): + cal(); + return FULLUPDATE; + break; +*/ + case KEY_ESC: + if(KEY_ESC_arg == 'i') { + t_idle(); + return FULLUPDATE; + } + break; + case Ctrl('H'): + if(select_read(locmem, RS_NEWPOST)) + return NEWDIRECT; + else + return READ_REDRAW; + case 'a': + case 'A': + if(select_read(locmem,RS_AUTHOR)) + return NEWDIRECT; + else + return READ_REDRAW; + case '/': + case '?': + if(select_read(locmem,RS_RELATED)) + return NEWDIRECT; + else + return READ_REDRAW; + case 'S': + if(select_read(locmem,RS_TITLE)) + return NEWDIRECT; + else + return READ_REDRAW; + /* quick search title first */ + case '=': + return thread(locmem, RELATE_FIRST); + case '\\': + return thread(locmem, CURSOR_FIRST); + /* quick search title forword */ + case ']': + return thread(locmem, RELATE_NEXT); + case '+': + return thread(locmem, CURSOR_NEXT); + /* quick search title backword */ + case '[': + return thread(locmem, RELATE_PREV); + case '-': + return thread(locmem, CURSOR_PREV); + case '<': + case ',': + return thread(locmem, THREAD_PREV); + case '.': + case '>': + return thread(locmem, THREAD_NEXT); + case 'p': + case 'k': + case KEY_UP: + return cursor_pos(locmem, locmem->crs_ln - 1, p_lines - 2); + case 'n': + case 'j': + case KEY_DOWN: + return cursor_pos(locmem, locmem->crs_ln + 1, 1); + case ' ': + case KEY_PGDN: + case 'N': + case Ctrl('F'): + if(last_line >= locmem->top_ln + p_lines) { + if(last_line > locmem->top_ln + p_lines) + locmem->top_ln += p_lines; + else + locmem->top_ln += p_lines - 1; + locmem->crs_ln = locmem->top_ln; + return PARTUPDATE; + } + cursor_clear(3 + locmem->crs_ln - locmem->top_ln, 0); + locmem->crs_ln = last_line; + cursor_show(3 + locmem->crs_ln - locmem->top_ln, 0); + break; + case KEY_PGUP: + case Ctrl('B'): + case 'P': + if(locmem->top_ln > 1) { + locmem->top_ln -= p_lines; + if(locmem->top_ln <= 0) + locmem->top_ln = 1; + locmem->crs_ln = locmem->top_ln; + return PARTUPDATE; + } + break; + case KEY_END: + case '$': + if(last_line >= locmem->top_ln + p_lines) { + locmem->top_ln = last_line - p_lines + 1; + if(locmem->top_ln <= 0) + locmem->top_ln = 1; + locmem->crs_ln = last_line; + return PARTUPDATE; + } + cursor_clear(3 + locmem->crs_ln - locmem->top_ln, 0); + locmem->crs_ln = last_line; + cursor_show(3 + locmem->crs_ln - locmem->top_ln, 0); + break; + case 'F': + case 'U': + if(HAS_PERM(PERM_FORWARD)) { + mail_forward(&headers[locmem->crs_ln - locmem->top_ln], + currdirect, ch /*== 'U'*/); + /*by CharlieL*/ + return FULLUPDATE; + } + break; + case Ctrl('Q'): + return my_query(headers[locmem->crs_ln - locmem->top_ln].owner); + case Ctrl('S'): + if(HAS_PERM(PERM_ACCOUNTS)) { + int id; + userec_t muser; + + strcpy(currauthor, headers[locmem->crs_ln - locmem->top_ln].owner); + stand_title("¨Ï¥ÎªÌ³]©w"); + move(1, 0); + if((id = getuser(headers[locmem->crs_ln - locmem->top_ln].owner))){ + memcpy(&muser, &xuser, sizeof(muser)); + user_display(&muser, 1); + uinfo_query(&muser, 1, id); + } + return FULLUPDATE; + } + break; + +/* rocker.011018: ±Ä¥Î·sªºtag¼Ò¦¡ */ + case 't': +/* 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].money & ~FHR_REFERENCE) : + locmem->crs_ln, TAG_TOGGLE)) + return POS_NEXT; + return DONOTHING; + + case Ctrl('C'): + if (TagNum) + { + TagNum = 0; + return FULLUPDATE; + } + return DONOTHING; + + case Ctrl('T'): + return TagThread(currdirect); + case Ctrl('D'): + return TagPruner(bid); + case '\n': + case '\r': + case 'l': + case KEY_RIGHT: + ch = 'r'; + default: + for(i = 0; rcmdlist[i].fptr; i++) { + if(rcmdlist[i].key == ch) { + mode = (*(rcmdlist[i].fptr))(locmem->crs_ln, + &headers[locmem->crs_ln - + locmem->top_ln], currdirect); + break; + } + if(rcmdlist[i].key == 'h') + if(currmode & (MODE_ETC | MODE_DIGEST)) + return DONOTHING; + } + } + return mode; +} + +void i_read(int cmdmode, char *direct, void (*dotitle)(), void (*doentry)(), onekey_t *rcmdlist, int bidcache) { + keeploc_t *locmem = NULL; + int recbase = 0, mode, ch; + int num = 0, entries = 0; + int i; + int jump = 0; + char genbuf[4]; + char currdirect0[64]; + int last_line0 = last_line; + int hit_thread0 = hit_thread; + fileheader_t *headers0 = headers; + + strcpy(currdirect0 ,currdirect); +#define FHSZ sizeof(fileheader_t) +// Ptt:³oÃäheaders ¥i¥H°w¹ï¬ÝªOªº³Ì«á60½g°µcache + headers = (fileheader_t *)calloc(p_lines, FHSZ); + strcpy(currdirect, direct); + mode = NEWDIRECT; + +/* rocker.011018: ¥[¤J·sªºtag¾÷¨î */ + TagNum = 0; + + do { + /* ¨Ì¾Ú mode Åã¥Ü fileheader */ + setutmpmode(cmdmode); + switch(mode) { + case NEWDIRECT: /* ²Ä¤@¦¸¸ü¤J¦¹¥Ø¿ý */ + case DIRCHANGED: + if(bidcache>0 && !(currmode & (MODE_SELECT| MODE_DIGEST)) ) + last_line=getbtotal(currbid); + else + last_line= get_num_records(currdirect, FHSZ); + + if(mode == NEWDIRECT) { + if(last_line == 0) { + if(curredit & EDIT_ITEM) { + outs("¨S¦³ª««~"); + refresh(); + goto return_i_read; + } else if(curredit & EDIT_MAIL) { + outs("¨S¦³¨Ó«H"); + refresh(); + goto return_i_read; + } else if(currmode & MODE_ETC) { + board_etc(); /* Kaede */ + outmsg("©|¥¼¦¬¿ý¨ä¥¦¤å³¹"); + refresh(); + } else if(currmode & MODE_DIGEST) { + board_digest(); /* Kaede */ + outmsg("©|¥¼¦¬¿ý¤åºK"); + refresh(); + } else if(currmode & MODE_SELECT) { + board_select(); /* Leeym */ + outmsg("¨S¦³¦¹¨t¦Cªº¤å³¹"); + refresh(); + } else { + getdata(b_lines - 1, 0, + "¬ÝªO·s¦¨¥ß (P)µoªí¤å³¹ (Q)Â÷¶}¡H[Q] ", + genbuf, 4, LCECHO); + if(genbuf[0] == 'p') + do_post(); + goto return_i_read; + } + } + num = last_line - p_lines + 1; + locmem = getkeep(currdirect, num < 1 ? 1 : num, last_line); + } + recbase = -1; + + case FULLUPDATE: + (*dotitle)(); + + case PARTUPDATE: + if(last_line < locmem->top_ln + p_lines) { + if(bidcache>0 && !(currmode & (MODE_SELECT| MODE_DIGEST))) + num=getbtotal(currbid); + else + num = get_num_records(currdirect, FHSZ); + + if(last_line != num) { + last_line = num; + recbase = -1; + } + } + + if(last_line == 0) + goto return_i_read; + else 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(bidcache>0 && !(currmode & (MODE_SELECT| MODE_DIGEST)) + && (last_line - recbase) < DIRCACHESIZE ) + entries = get_fileheader_cache(currbid, currdirect, headers, + recbase, p_lines); + else + entries = get_records(currdirect, headers, FHSZ, recbase, + p_lines); + } + if(locmem->crs_ln > last_line) + locmem->crs_ln = last_line; + move(3, 0); + clrtobot(); + case PART_REDRAW: + move(3, 0); + for (i = 0; i < entries; i++) + (*doentry) (locmem->top_ln + i, &headers[i]); + case READ_REDRAW: + outmsg(curredit & EDIT_ITEM ? + "\033[44m ¨p¤H¦¬Âà \033[30;47m Ä~Äò? \033[m" : + curredit & EDIT_MAIL ? msg_mailer : MSG_POSTER); + break; + case READ_PREV: + case READ_NEXT: + case RELATE_PREV: + case RELATE_NEXT: + case RELATE_FIRST: + case POS_NEXT: + case 'A': + case 'a': + case '/': + case '?': + jump = 1; + break; + } + + /* Ū¨úÁä½L¡A¥[¥H³B²z¡A³]©w mode */ + if(!jump) { + cursor_show(3 + locmem->crs_ln - locmem->top_ln, 0); + ch = egetch(); + mode = DONOTHING; + } else + ch = ' '; + + if(mode == POS_NEXT) { + mode = cursor_pos(locmem, locmem->crs_ln + 1, 1); + if(mode == DONOTHING) + mode = PART_REDRAW; + jump = 0; + } else if(ch >= '0' && ch <= '9') { + if((i = search_num(ch, last_line)) != -1) + mode = cursor_pos(locmem, i + 1, 10); + } else { + if(!jump) + mode = i_read_key(rcmdlist, locmem, ch, currbid); + while(mode == READ_NEXT || mode == READ_PREV || + mode == RELATE_FIRST || mode == RELATE_NEXT || + mode == RELATE_PREV || mode == THREAD_NEXT || + mode == THREAD_PREV || mode == 'A' || mode == 'a' || + mode == '/' || mode == '?') { + int reload; + + if(mode == READ_NEXT || mode == READ_PREV) + reload = move_cursor_line(locmem, mode); + else { + reload = thread(locmem, mode); + if(!hit_thread) { + mode = FULLUPDATE; + break; + } + } + + if(reload == -1) { + mode = FULLUPDATE; + break; + } else if(reload) { + recbase = locmem->top_ln; + + if(bidcache>0 && !(currmode &(MODE_SELECT| MODE_DIGEST)) + && last_line-recbase<DIRCACHESIZE ) + entries = get_fileheader_cache(currbid, currdirect, + headers, recbase, p_lines); + else + entries = get_records(currdirect, headers, FHSZ, recbase, + p_lines); + + if(entries <= 0) { + last_line = -1; + break; + } + } + num = locmem->crs_ln - locmem->top_ln; + if(headers[num].owner[0] != '-') + mode = i_read_key(rcmdlist, locmem, ch, bidcache); + } + } + } while(mode != DOQUIT); +#undef FHSZ + + return_i_read: + free(headers); + last_line = last_line0; + hit_thread = hit_thread0; + headers = headers0; + strcpy(currdirect ,currdirect0); + return; +} diff --git a/mbbsd/record.c b/mbbsd/record.c new file mode 100644 index 00000000..59bc6a75 --- /dev/null +++ b/mbbsd/record.c @@ -0,0 +1,536 @@ +/* $Id: record.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <string.h> +#include <unistd.h> +#include <time.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/file.h> +#include "config.h" +#include "pttstruct.h" +#include "modes.h" +#include "proto.h" + +#undef HAVE_MMAP +#define BUFSIZE 512 + +extern char *str_reply; + +static void PttLock(int fd, int size, int mode) { + static struct flock lock_it; + int ret; + + lock_it.l_whence = SEEK_CUR; /* from current point */ + lock_it.l_start = 0; /* -"- */ + lock_it.l_len = size; /* length of data */ + lock_it.l_type = mode; /* set exclusive/write lock */ + lock_it.l_pid = 0; /* pid not actually interesting */ + while((ret = fcntl(fd, F_SETLKW, &lock_it)) < 0 && errno == EINTR); +} + +#define safewrite write + +int get_num_records(char *fpath, int size) { + struct stat st; + if(stat(fpath, &st) == -1) + return 0; + return st.st_size / size; +} + +int get_sum_records(char* fpath, int size) { + struct stat st; + long ans = 0; + FILE* fp; + fileheader_t fhdr; + char buf[200], *p; + + if(!(fp = fopen(fpath, "r"))) + return -1; + + strcpy(buf, fpath); + p = strrchr(buf, '/') + 1; + + while(fread(&fhdr, size, 1, fp) == 1) { + strcpy(p, fhdr.filename); + if(stat(buf, &st) == 0 && S_ISREG(st.st_mode) && st.st_nlink == 1) + ans += st.st_size; + } + fclose(fp); + return ans / 1024; +} + +int get_record(char *fpath, void *rptr, int size, int id) { + int fd = -1; + + if(id < 1 || (fd = open(fpath, O_RDONLY, 0)) != -1) { + if(lseek(fd, (off_t)(size * (id - 1)), SEEK_SET) != -1) { + if(read(fd, rptr, size) == size) { + close(fd); + return 0; + } + } + close(fd); + } + return -1; +} + +int get_records(char *fpath, void *rptr, int size, int id, int number) { + int fd; + + if(id < 1 || (fd = open(fpath, O_RDONLY, 0)) == -1) + return -1; + + if(lseek(fd, (off_t)(size * (id - 1)), SEEK_SET) == -1) { + close(fd); + return 0; + } + if((id = read(fd, rptr, size * number)) == -1) { + close(fd); + return -1; + } + close(fd); + return id / size; +} + +int substitute_record(char *fpath, void *rptr, int size, int id) { + int fd; + + if(id < 1 || (fd = open(fpath, O_WRONLY | O_CREAT, 0644)) == -1) + return -1; + + lseek(fd, (off_t) (size * (id - 1)), SEEK_SET); + PttLock(fd, size, F_WRLCK); + safewrite(fd, rptr, size); + PttLock(fd, size, F_UNLCK); + close(fd); + + return 0; +} + +/* rocker.011022: ÁקKlockÀɶ}±Ò®É¤£¥¿±`Â_½u,³y¦¨¥Ã¤[lock */ +static int +force_open (char *fname) +{ + int fd; + time_t expire; + + expire = time(NULL) - 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; +} + + +#if !defined(_BBS_UTIL_C_) +/* new/old/lock file processing */ +typedef struct nol_t { + char newfn[256]; + char oldfn[256]; + char lockfn[256]; +} nol_t; + +static void nolfilename(nol_t *n, char *fpath) { + sprintf(n->newfn, "%s.new", fpath); + sprintf(n->oldfn, "%s.old", fpath); + sprintf(n->lockfn, "%s.lock", fpath); +} + +int delete_record(char fpath[], int size, int id) { + nol_t my; + char abuf[BUFSIZE]; + int fdr, fdw, fd; + int count; + + 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) { + move(10,10); + outs("delete_record failed!!! (open)"); + pressanykey(); + 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)) { + flock(fd, LOCK_UN); + close(fd); + close(fdr); + return -1; + } + count = 1; + while(read(fdr, abuf, size) == size) { + if(id != count++ && (safewrite(fdw, abuf, size) == -1)) { + unlink(my.newfn); + close(fdr); + close(fdw); + flock(fd, LOCK_UN); + close(fd); + return -1; + } + } + 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 0; +} + +static char *title_body(char *title) { + if(!strncasecmp(title, str_reply, 3)) { + title += 3; + if(*title == ' ') + title++; + } + return title; +} + +int delete_range(char *fpath, int id1, int id2) { + fileheader_t fhdr; + nol_t my; + char fullpath[STRLEN], *t; + int fdr, fdw, fd; + int count; + extern int Tagger(); + + 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; + strcpy(fullpath, fpath); + t = strrchr(fullpath, '/') + 1; + + 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) || /* ¤åºK */ + (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); + } + ++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 0; +} + +int search_rec(char* dirname, int (*filecheck)()) { + fileheader_t fhdr; + FILE *fp; + int ans = 0; + + if(!(fp = fopen(dirname, "r"))) + return 0; + + while(fread(&fhdr, sizeof(fhdr), 1, fp)) { + ans++; + if((*filecheck) (&fhdr)) { + fclose(fp); + return ans; + } + } + fclose(fp); + return 0; +} + +int delete_files(char* dirname, int (*filecheck)(), int record) { + fileheader_t fhdr; + FILE *fp, *fptmp; + int ans = 0; + char tmpfname[128]; + char genbuf[256]; + char deleted[256]; + fileheader_t delfh; + char deletedDIR[] = "boards/deleted/.DIR"; + + strcpy(deleted, "boards/deleted"); + + if(!(fp = fopen(dirname, "r"))) + return ans; + + strcpy(tmpfname, dirname); + strcat(tmpfname, "_tmp"); + + if(!(fptmp = fopen(tmpfname, "w"))) { + fclose(fp); + return ans; + } + + while(fread(&fhdr, sizeof(fhdr), 1, fp)){ + if((*filecheck)(&fhdr)) { + ans++; + setdirpath(genbuf, dirname, fhdr.filename); + if (record){ + deleted[14] = '\0'; + stampfile(deleted, &delfh); + strcpy(delfh.owner, fhdr.owner); + strcpy(delfh.title, fhdr.title); + Link(genbuf, deleted); + append_record(deletedDIR, &delfh, sizeof(delfh)); + } + unlink(genbuf); + } else + fwrite(&fhdr, sizeof(fhdr), 1, fptmp); + } + + fclose(fp); + fclose(fptmp); + unlink(dirname); + Rename(tmpfname, dirname); + + return ans; +} + +int delete_file(char *dirname, int size, int ent, int (*filecheck)()) { + char abuf[BUFSIZE]; + int fd; + struct stat st; + long numents; + + if(ent < 1 || (fd = open(dirname, O_RDWR)) == -1) + return -1; + flock(fd, LOCK_EX); + fstat(fd, &st); + numents = ((long) st.st_size) / size; + if(((long) st.st_size) % size) + fprintf(stderr, "align err\n"); + if(lseek(fd, (off_t) size * (ent - 1), SEEK_SET) != -1) { + if(read(fd, abuf, size) == size){ + if((*filecheck) (abuf)) { + int i; + + for(i = ent; i < numents; i++) { + if(lseek(fd, (off_t)((i) * size), SEEK_SET) == -1 || + read(fd, abuf, size) != size || + lseek(fd, (off_t)(i - 1) * size, SEEK_SET) == -1) + break; + if(safewrite(fd, abuf, size) != size) + break; + } + ftruncate(fd, (off_t) size * (numents - 1)); + flock(fd, LOCK_UN); + close(fd); + return 0; + } + } + } + lseek(fd, 0, SEEK_SET); + ent = 1; + while(read(fd, abuf, size) == size) { + if((*filecheck)(abuf)) { + int i; + + for(i = ent; i < numents; i++) { + if(lseek(fd, (off_t) (i + 1) * size, SEEK_SET) == -1 || + read(fd, abuf, size) != size || + lseek(fd, (off_t) (i) * size, SEEK_SET) == -1 || + safewrite(fd, abuf, size) != size) + break; + } + ftruncate(fd, (off_t) size * (numents - 1)); + flock(fd, LOCK_UN); + close(fd); + return 0; + } + ent++; + } + flock(fd, LOCK_UN); + close(fd); + return -1; +} + +#endif /* !defined(_BBS_UTIL_C_) */ + +int apply_record(char *fpath, int (*fptr)(), int size) { + char abuf[BUFSIZE]; + FILE* fp; + + if(!(fp = fopen(fpath, "r"))) + return -1; + + while(fread(abuf, 1, size, fp) == size) + if((*fptr) (abuf) == QUIT) { + fclose(fp); + return QUIT; + } + fclose(fp); + return 0; +} + +/* mail / post ®É¡A¨Ì¾Ú®É¶¡«Ø¥ßÀɮסA¥[¤W¶lÂW */ +int stampfile(char *fpath, fileheader_t *fh) { + register char *ip = fpath; + time_t dtime; + struct tm *ptime; + int fp = 0; + + if(access(fpath, X_OK | R_OK | W_OK)) + mkdir(fpath, 0755); + + time(&dtime); + while (*(++ip)); + *ip++ = '/'; + do { + sprintf(ip, "M.%ld.A", ++dtime ); + if(fp == -1 && errno != EEXIST) + return -1; + } while((fp = open(fpath, O_CREAT | O_EXCL | O_WRONLY, 0644)) == -1); + close(fp); + memset(fh, 0, sizeof(fileheader_t)); + strcpy(fh->filename, ip); + ptime = localtime(&dtime); + sprintf(fh->date, "%2d/%02d", ptime->tm_mon + 1, ptime->tm_mday); + return 0; +} + +void stampdir(char *fpath, fileheader_t *fh) { + register char *ip = fpath; + time_t dtime; + struct tm *ptime; + + if(access(fpath, X_OK | R_OK | W_OK)) + mkdir(fpath, 0755); + + time(&dtime); + while(*(++ip)); + *ip++ = '/'; + do { + sprintf(ip, "D%lX", ++dtime & 07777); + } while(mkdir(fpath, 0755) == -1); + memset(fh, 0, sizeof(fileheader_t)); + strcpy(fh->filename, ip); + ptime = localtime(&dtime); + sprintf(fh->date, "%2d/%02d", ptime->tm_mon + 1, ptime->tm_mday); +} + +void stamplink(char *fpath, fileheader_t *fh) { + register char *ip = fpath; + time_t dtime; + struct tm *ptime; + + if(access(fpath, X_OK | R_OK | W_OK)) + mkdir(fpath, 0755); + + time(&dtime); + while(*(++ip)); + *ip++ = '/'; + do { + sprintf(ip, "S%lX", ++dtime ); + } while(symlink("temp", fpath) == -1); + memset(fh, 0, sizeof(fileheader_t)); + strcpy(fh->filename, ip); + ptime = localtime(&dtime); + sprintf(fh->date, "%2d/%02d", ptime->tm_mon + 1, ptime->tm_mday); +} + +int do_append(char *fpath, fileheader_t *record, int size) { + int fd; + + if((fd = open(fpath, O_WRONLY | O_CREAT, 0644)) == -1) { + perror("open"); + return -1; + } + flock(fd, LOCK_EX); + lseek(fd, 0, SEEK_END); + + safewrite(fd, record, size); + + flock(fd, LOCK_UN); + close(fd); + return 0; +} + +int append_record(char *fpath, fileheader_t *record, int size) { +#if !defined(_BBS_UTIL_C_) + int m,n; + if(get_num_records(fpath, sizeof(fileheader_t)) <= MAX_KEEPMAIL * 2) { + FILE *fp; + char buf[512],address[200]; + + for(n = strlen(fpath) - 1 ; fpath[n] != '/' && n > 0; n--); + strncpy(buf, fpath, n + 1); + buf[n + 1] = 0; + for(m = strlen(buf) - 2 ; buf[m] != '/' && m > 0 ; m--); + strcat(buf, ".forward"); + if((fp = fopen(buf,"r"))) { + fscanf(fp,"%s",address); + fclose(fp); + if(buf[0] != 0 && buf[0] != ' ') { + buf[n + 1] = 0; + strcat(buf, record->filename); + do_append(fpath,record,size); +#ifndef USE_BSMTP + bbs_sendmail(buf,record->title,address); +#else + bsmtp(buf, record->title, address, 0); +#endif + return 0; + } + } + } +#endif + + do_append(fpath,record,size); + + return 0; +} diff --git a/mbbsd/register.c b/mbbsd/register.c new file mode 100644 index 00000000..e9c25be5 --- /dev/null +++ b/mbbsd/register.c @@ -0,0 +1,339 @@ +/* $Id: register.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#define _XOPEN_SOURCE + +#include <stdio.h> +#include <strings.h> +#include <string.h> +#include <unistd.h> +#include <time.h> +#include <fcntl.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include "config.h" +#include "pttstruct.h" +#include "perm.h" +#include "common.h" +#include "proto.h" + +extern char *str_new; +extern char *msg_uid; +extern int t_lines, t_columns; /* Screen size / width */ +extern char *str_mail_address; + +/* password encryption */ +static char pwbuf[14]; + +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; + } + strcpy(pwbuf, pw); + return crypt(pwbuf, saltc); + } + return ""; +} + +int checkpasswd(char *passwd, char *test) { + char *pw; + + strncpy(pwbuf, test, 14); + pw = crypt(pwbuf, passwd); + return (!strncmp(pw, passwd, 14)); +} + +/* Àˬd user µù¥U±¡ªp */ +int bad_user_id(char *userid) { + int len, i; + len = strlen(userid); + + if(len < 2) + return 1; + + if (not_alpha(userid[0])) + return 1; + for (i=1; i<len; i++) //DickG:×¥¿¤F¥u¤ñ¸û userid ²Ä¤@Ó¦r¤¸ªº bug + if(not_alnum(userid[i])) + return 1; + + if(strcasecmp(userid, str_new) == 0) + return 1; + + /* while((ch = *(++userid))) + if(not_alnum(ch)) + return 1;*/ + return 0; +} + +/* -------------------------------- */ +/* New policy for allocate new user */ +/* (a) is the worst user currently */ +/* (b) is the object to be compared */ +/* -------------------------------- */ +static int compute_user_value(userec_t *urec, time_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 */ + 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,userec_t *urec) +{ + userec_t zerorec; + time_t now=time(NULL); + char genbuf[200],genbuf2[200]; + int val; + if((val = compute_user_value(urec, now)) < 0) { + sprintf(genbuf, "#%d %-12s %15.15s %d %d %d", + uid, urec->userid, ctime(&(urec->lastlogin)) + 4, + urec->numlogins, urec->numposts, val); + if(val > -1 * 60 * 24 * 365) { + memset(&zerorec, 0, sizeof(zerorec)); + log_usies("CLEAN", genbuf); + sprintf(genbuf, "home/%c/%s", urec->userid[0], + urec->userid); + sprintf(genbuf2, "tmp/%s", urec->userid); + if(dashd(genbuf) && Rename(genbuf, genbuf2)) { + sprintf(genbuf, "/bin/rm -fr home/%c/%s >/dev/null 2>&1", + urec->userid[0],urec->userid); + system(genbuf); + } + passwd_update(uid, &zerorec); + remove_from_uhash(uid - 1); + add_to_uhash(uid - 1, ""); + } + else + { + val=0; + log_usies("DATED", genbuf); + } + } + return val; +} + +extern char *fn_passwd; + +int getnewuserid() { + char genbuf[50]; + static char *fn_fresh = ".fresh"; + userec_t utmp,zerorec; + time_t clock; + struct stat st; + int fd, i; + + memset(&zerorec, 0, sizeof(zerorec)); + clock = time(NULL); + + /* Lazy method : ¥ý§ä´M¤w¸g²M°£ªº¹L´Á±b¸¹ */ + if((i = searchnewuser(0)) == 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(i = 2; i <= MAX_USERS; i++) { + passwd_query(i, &utmp); + check_and_expire_account(i,&utmp); + } + } + } + + passwd_lock(); + i = searchnewuser(1); + if((i <= 0) || (i > MAX_USERS)) { + passwd_unlock(); + if(more("etc/user_full", NA) == -1) + fprintf(stdout, "©êºp¡A¨Ï¥ÎªÌ±b¸¹¤w¸gº¡¤F¡AµLªkµù¥U·sªº±b¸¹\n\r"); + safe_sleep(2); + exit(1); + } + + sprintf(genbuf, "uid %d", i); + log_usies("APPLY", genbuf); + + strcpy(zerorec.userid, str_new); + zerorec.lastlogin = clock; + passwd_update(i, &zerorec); + setuserid(i, zerorec.userid); + passwd_unlock(); + return i; +} + +void new_register() { + extern userec_t xuser; + userec_t newuser; + char passbuf[STRLEN]; + int allocid, try, id; + + memset(&newuser, 0, sizeof(newuser)); + more("etc/register", NA); + try = 0; + while(1) { + if(++try >= 6) { + outs("\n±z¹Á¸Õ¿ù»~ªº¿é¤J¤Ó¦h¡A½Ð¤U¦¸¦A¨Ó§a\n"); + refresh(); + + pressanykey(); + oflush(); + exit(1); + } + getdata(17, 0, msg_uid, newuser.userid, IDLEN + 1, DOECHO); + + if(bad_user_id(newuser.userid)) + outs("µLªk±µ¨ü³oÓ¥N¸¹¡A½Ð¨Ï¥Î^¤å¦r¥À¡A¨Ã¥B¤£n¥]§tªÅ®æ\n"); + else if ((id=getuser(newuser.userid)) && + (id=check_and_expire_account(id,&xuser))>=0) + { + if(id==999999) + outs("¦¹¥N¸¹¤w¸g¦³¤H¨Ï¥Î ¬O¤£¦º¤§¨"); + else + { + sprintf(passbuf,"¦¹¥N¸¹¤w¸g¦³¤H¨Ï¥Î ÁÙ¦³%d¤Ñ¤~¹L´Á \n",id/(60*24)); + outs(passbuf); + } + } + else + break; + } + + try = 0; + while(1) { + if(++try >= 6) { + outs("\n±z¹Á¸Õ¿ù»~ªº¿é¤J¤Ó¦h¡A½Ð¤U¦¸¦A¨Ó§a\n"); + refresh(); + + pressanykey(); + oflush(); + exit(1); + } + if((getdata(19, 0, "½Ð³]©w±K½X¡G", passbuf, PASSLEN, NOECHO) < 3) || + !strcmp(passbuf, newuser.userid)) { + outs("±K½X¤Ó²³æ¡A©ö¾D¤J«I¡A¦Ü¤Ön 4 Ó¦r¡A½Ð«·s¿é¤J\n"); + continue; + } + strncpy(newuser.passwd, passbuf, PASSLEN); + getdata(20, 0, "½ÐÀˬd±K½X¡G", passbuf, PASSLEN, NOECHO); + if(strncmp(passbuf, newuser.passwd, PASSLEN)) { + outs("±K½X¿é¤J¿ù»~, ½Ð«·s¿é¤J±K½X.\n"); + continue; + } + passbuf[8] = '\0'; + strncpy(newuser.passwd, genpasswd(passbuf), PASSLEN); + break; + } + newuser.userlevel = PERM_DEFAULT; + newuser.uflag = COLOR_FLAG | BRDSORT_FLAG | MOVIE_FLAG; + newuser.firstlogin = newuser.lastlogin = time(NULL); + newuser.money = 0; + newuser.pager = 1; + allocid = getnewuserid(); + if(allocid > MAX_USERS || allocid <= 0) { + fprintf(stderr, "¥»¯¸¤H¤f¤w¹F¹¡©M¡I\n"); + exit(1); + } + + if(passwd_update(allocid, &newuser) == -1) { + fprintf(stderr, "«Èº¡¤F¡A¦A¨£¡I\n"); + exit(1); + } + setuserid(allocid, newuser.userid); + if(!dosearchuser(newuser.userid)) { + fprintf(stderr, "µLªk«Ø¥ß±b¸¹\n"); + exit(1); + } +} + +extern userec_t cuser; + +void check_register() { + char *ptr = NULL; + + stand_title("½Ð¸Ô²Ó¶ñ¼gÓ¤H¸ê®Æ"); + + while(strlen(cuser.username) < 2) + getdata(2, 0, "ºï¸¹¼ÊºÙ¡G", cuser.username, 24, DOECHO); + + for(ptr = cuser.username; *ptr; ptr++) { + if (*ptr == 9) /* TAB convert */ + *ptr = ' '; + } + while(strlen(cuser.realname) < 4) + getdata(4, 0, "¯u¹ê©m¦W¡G", cuser.realname, 20, DOECHO); + + while(strlen(cuser.address) < 8) + getdata(6, 0, "Ápµ¸¦a§}¡G", cuser.address, 50, DOECHO); + + + if(!strchr(cuser.email, '@')) { + bell(); + move(t_lines - 4, 0); + prints("¡° ¬°¤F±zªºÅv¯q¡A½Ð¶ñ¼g¯u¹êªº E-mail address¡A " + "¥H¸ê½T»{»Õ¤U¨¥÷¡A\n" + "®æ¦¡¬° \033[44muser@domain_name\033[0m ©Î \033[44muser" + "@\\[ip_number\\]\033[0m¡C\n\n" + "¡° ¦pªG±z¯uªº¨S¦³ E-mail¡A½Ðª½±µ«ö [return] §Y¥i¡C"); + + do { + getdata(8, 0, "¹q¤l«H½c¡G", cuser.email, 50, DOECHO); + if(!cuser.email[0]) + sprintf(cuser.email, "%s%s", cuser.userid, str_mail_address); + } while(!strchr(cuser.email, '@')); + + } + if(!HAS_PERM(PERM_SYSOP) && !HAS_PERM(PERM_LOGINOK)) { + /* ¦^ÂйL¨¥÷»{ÃÒ«H¨ç¡A©Î´¿¸g E-mail post ¹L */ + clear(); + move(9,3); + prints("½Ð¸Ô¶ñ¼g\033[32mµù¥U¥Ó½Ð³æ\033[m¡A" + "³q§i¯¸ªø¥HÀò±o¶i¶¥¨Ï¥ÎÅv¤O¡C\n\n\n\n"); + u_register(); + } + +#ifdef NEWUSER_LIMIT + if(!(cuser.userlevel & PERM_LOGINOK) && !HAS_PERM(PERM_SYSOP)) { + if(cuser.lastlogin - cuser.firstlogin < 3 * 86400) + cuser.userlevel &= ~PERM_POST; + more("etc/newuser", YEA); + } +#endif +} diff --git a/mbbsd/screen.c b/mbbsd/screen.c new file mode 100644 index 00000000..46ad5b38 --- /dev/null +++ b/mbbsd/screen.c @@ -0,0 +1,559 @@ +/* $Id: screen.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <stdarg.h> +#include <sys/types.h> +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "proto.h" + +extern int t_lines, t_columns; /* Screen size / width */ +extern int b_lines; /* Screen bottom line number: t_lines-1 */ +extern int p_lines; /* a Page of Screen line numbers: tlines-4 */ +extern int showansi; + +extern char *clearbuf; +extern char *cleolbuf; +extern char *scrollrev; +extern char *strtstandout; +extern char *endstandout; +extern int clearbuflen; +extern int cleolbuflen; +extern int scrollrevlen; +extern int strtstandoutlen; +extern int endstandoutlen; +extern int automargins; +#ifdef SUPPORT_GB +static int current_font_type=TYPE_BIG5; +static int gbinited=0; +#endif +#define SCR_WIDTH 80 +#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) + +unsigned char scr_lns, scr_cols; +static unsigned char cur_ln = 0, cur_col = 0; +static unsigned char docls, downfrom = 0; +static unsigned char standing = NA; +static char roll = 0; +static int scrollcnt, tc_col, tc_line; + +screenline_t *big_picture = NULL; + +#define MODIFIED (1) /* if line has been modifed, screen output */ +#define STANDOUT (2) /* if this line has a standout region */ + +int tputs(const char *str, int affcnt, int (*putc)(int)); + +void initscr() { + if(!big_picture) { + scr_lns = t_lines; + scr_cols = t_columns = ANSILINELEN; + /* scr_cols = MIN(t_columns, ANSILINELEN); */ + big_picture = (screenline_t *) calloc(scr_lns, sizeof(screenline_t)); + docls = YEA; + } +} + +void move(int y, int x) { + cur_col = x; + cur_ln = y; +} + +void getyx(int *y, int *x) { + *y = cur_ln; + *x = cur_col; +} + +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(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 redoscr() { + register screenline_t *bp; + register int i, j, 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); + if(bp->mode & STANDOUT) + standoutput(bp->data, 0, len, bp->sso, bp->eso); + else + output(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(); +} + +void refresh() { + register screenline_t *bp = big_picture; + register int i, j, len; + extern int automargins; + extern int scrollrevlen; + if(num_in_buf()) + return; + + if((docls) || (abs(scrollcnt) >= (scr_lns - 3))) { + redoscr(); + return; + } + + if(scrollcnt < 0) { + if(!scrollrevlen) { + redoscr(); + 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); + if(bp->emod >= len) + bp->emod = len - 1; + rel_move(tc_col, tc_line, bp->smod, i); + + if(bp->mode & STANDOUT) + standoutput(bp->data, bp->smod, bp->emod + 1, + bp->sso, bp->eso); + else + output(&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; + if(++tc_line >= t_lines) + tc_line = b_lines; + } else + tc_col = t_columns - 1; + } + } + + if(bp->oldlen > len) { + 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() { + register screenline_t *slp; + + register int i; + + docls = YEA; + cur_col = cur_ln = roll = downfrom = i = 0; + do { + slp = &big_picture[i]; + slp->mode = slp->len = slp->oldlen = 0; + } while(++i < scr_lns); +} + +void clrtoeol() { + register screenline_t *slp; + register int ln; + + standing = NA; + if((ln = cur_ln + roll) >= scr_lns) + ln -= scr_lns; + slp = &big_picture[ln]; + if(cur_col <= slp->sso) + slp->mode &= ~STANDOUT; + + 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 clrtoline(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 = 255; + } +} + +void clrtobot() { + clrtoline(scr_lns); +} + +void outch(unsigned char c) { + register screenline_t *slp; + register int i; + + if((i = cur_ln + roll) >= scr_lns) + i -= scr_lns; + slp = &big_picture[i]; + + 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 != '\033' && !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) != 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 (++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++; + } + +} + +static void parsecolor(char *buf) { + char *val; + char data[24]; + + data[0] = '\0'; + val = (char *)strtok(buf, ";"); + + while(val) { + if(atoi(val) < 30) { + if(data[0]) + strcat(data, ";"); + strcat(data, val); + } + val = (char *) strtok(NULL, ";"); + } + strcpy(buf, data); +} + +#define NORMAL (00) +#define ESCAPE (01) +#define VTKEYS (02) + +void outc(unsigned char ch) { + if(showansi) + outch(ch); + else { + static char buf[24]; + static int p = 0; + static int mode = NORMAL; + int i; + + switch(mode) { + case NORMAL: + if(ch == '\033') + mode = ESCAPE; + else + outch(ch); + return; + case ESCAPE: + if(ch == '[') + mode = VTKEYS; + else { + mode = NORMAL; + outch(''); + outch(ch); + } + return; + case VTKEYS: + if(ch == 'm') { + buf[p++] = '\0'; + parsecolor(buf); + } else if((p < 24) && (not_alpha(ch))) { + buf[p++] = ch; + return; + } + if(buf[0]) { + outch(''); + outch('['); + + for(i = 0; (p = buf[i]); i++) + outch(p); + outch(ch); + } + p = 0; + mode = NORMAL; + } + } +} + +static void do_outs(char *str) { + while(*str) + { + outc(*str++); + } +} +#ifdef SUPPORT_GB +static void gb_init() +{ + if(current_font_type == TYPE_GB) + { + hc_readtab(BBSHOME"/etc/hc.tab"); + } + gbinited = 1; +} + +static void gb_outs(char *str) +{ + do_outs(hc_convert_str(str, HC_BIGtoGB, HC_DO_SINGLE)); +} +#endif +int edit_outs(char *text) { + register int column = 0; + register char ch; +#ifdef SUPPORT_GB + if(current_font_type == TYPE_GB) + text = hc_convert_str(text, HC_BIGtoGB, HC_DO_SINGLE); +#endif + while((ch = *text++) && (++column < SCR_WIDTH)) + outch(ch == 27 ? '*' : ch); + + return 0; +} + +void outs(char *str) { +#ifdef SUPPORT_GB + if(current_font_type == TYPE_BIG5) +#endif + do_outs(str); +#ifdef SUPPORT_GB + else + { + if(!gbinited) gb_init(); + gb_outs(str); + } +#endif +} + + +/* Jaky */ +void Jaky_outs(char *str, int line) { +#ifdef SUPPORT_GB + if(current_font_type == TYPE_GB) + str = hc_convert_str(str, HC_BIGtoGB, HC_DO_SINGLE); +#endif + while(*str && line) { + outc(*str); + if(*str=='\n') + line--; + str++; + } +} + +void outmsg(char *msg) { + move(b_lines, 0); + clrtoeol(); +#ifdef SUPPORT_GB + if(current_font_type == TYPE_GB) + msg = hc_convert_str(msg, HC_BIGtoGB, HC_DO_SINGLE); +#endif + while(*msg) + outc(*msg++); +} + +void prints(char *fmt, ...) { + va_list args; + char buff[1024]; + + va_start(args, fmt); + vsprintf(buff, fmt, args); + va_end(args); + outs(buff); +} + +void mprints(int y, int x, char *str) { + move(y, x); + clrtoeol(); + prints(str); +} + +void scroll() { + scrollcnt++; + if(++roll >= scr_lns) + roll = 0; + move(b_lines, 0); + clrtoeol(); +} + +void rscroll() { + 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() { + if(!standing && strtstandoutlen) { + register screenline_t *slp; + + slp = &big_picture[((cur_ln + roll) % scr_lns)]; + standing = YEA; + slp->sso = slp->eso = cur_col; + slp->mode |= STANDOUT; + } +} + +void standend() { + if(standing && strtstandoutlen) { + register screenline_t *slp; + + slp = &big_picture[((cur_ln + roll) % scr_lns)]; + standing = NA; + slp->eso = MAX(slp->eso, cur_col); + } +} diff --git a/mbbsd/stuff.c b/mbbsd/stuff.c new file mode 100644 index 00000000..9218b7f0 --- /dev/null +++ b/mbbsd/stuff.c @@ -0,0 +1,524 @@ +/* $Id: stuff.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include <ctype.h> +#include <unistd.h> +#include <time.h> +#include <sys/types.h> +#include <sys/stat.h> +#include "config.h" +#include "pttstruct.h" +#include "modes.h" +#include "common.h" +#include "perm.h" +#include "proto.h" + +extern int currmode; +extern char *fn_mandex; +extern char *str_reply; +extern char *str_space; +extern int b_lines; /* Screen bottom line number: t_lines-1 */ +extern userec_t cuser; + +/* ----------------------------------------------------- */ +/* set file path for boards/user home */ +/* ----------------------------------------------------- */ +static char *str_home_file = "home/%c/%s/%s"; +static char *str_board_file = "boards/%s/%s"; + +#define STR_DOTDIR ".DIR" +static char *str_dotdir = STR_DOTDIR; + +void setcalfile(char *buf, char *userid) { + sprintf(buf, "home/%c/%s/calendar", userid[0], userid); +} + +void sethomepath(char *buf, char *userid) { + sprintf(buf, "home/%c/%s", userid[0], userid); +} + +void sethomedir(char *buf, char *userid) { + sprintf(buf, str_home_file, userid[0], userid, str_dotdir); +} + +void sethomeman(char *buf, char *userid) { + sprintf(buf, str_home_file, userid[0], userid, "man"); +} + +void sethomefile(char *buf, char *userid, char *fname) { + sprintf(buf, str_home_file, userid[0], userid, fname); +} + +void setuserfile(char *buf, char *fname) { + sprintf(buf, str_home_file, cuser.userid[0], cuser.userid, fname); +} + +void setapath(char *buf, char *boardname) { + sprintf(buf, "man/boards/%s", boardname); +} + +void setadir(char *buf, char *path) { + sprintf(buf, "%s/%s", path, str_dotdir); +} + +void setbpath(char *buf, char *boardname) { + sprintf(buf, "boards/%s", boardname); +} + +void setbdir(char *buf, char *boardname) { + sprintf(buf, str_board_file, boardname, + currmode & MODE_ETC ? ".ETC" : + (currmode & MODE_DIGEST ? fn_mandex : str_dotdir)); +} + +void setbfile(char *buf, char *boardname, char *fname) { + sprintf(buf, str_board_file, boardname, fname); +} + +void setdirpath(char *buf, char *direct, char *fname) { + strcpy(buf, direct); + direct = strrchr(buf, '/'); + strcpy(direct + 1, fname); +} + +char *subject(char *title) { + if(!strncasecmp(title, str_reply, 3)) { + title += 3; + if(*title == ' ') + title++; + } + return title; +} + +/* ----------------------------------------------------- */ +/* ¦r¦êÂà´«Àˬd¨ç¼Æ */ +/* ----------------------------------------------------- */ +int str_checksum(char *str) { + int n = 1; + if(strlen(str) < 6) + return 0; + while(*str) + n += *(str++) * (n); + return n; +} + +void str_lower(char *t, char *s) { + register unsigned char ch; + + do { + ch = *s++; + *t++ = char_lower(ch); + } while(ch); +} + +int strstr_lower(char *str, char *tag) { + char buf[STRLEN]; + + str_lower(buf, str); + return (int)strstr(buf, tag); +} + +void trim(char *buf) { /* remove trailing space */ + char *p = buf; + + while(*p) + p++; + while(--p >= buf) { + if(*p == ' ') + *p = '\0'; + else + break; + } +} + +/* ----------------------------------------------------- */ +/* ¦r¦êÀˬd¨ç¼Æ¡G^¤å¡B¼Æ¦r¡BÀɦW¡BE-mail address */ +/* ----------------------------------------------------- */ +int isprint2(char ch) { + return ((ch & 0x80) ? 1 : isprint(ch)); + //return 1; +} + +int not_alpha(char ch) { + return (ch < 'A' || (ch > 'Z' && ch < 'a') || ch > 'z'); +} + +int not_alnum(char ch) { + return (ch < '0' || (ch > '9' && ch < 'A') || + (ch > 'Z' && ch < 'a') || ch > 'z'); +} + +int invalid_pname(char *str) { + char *p1, *p2, *p3; + + p1 = str; + while(*p1) { + if(!(p2 = strchr(p1, '/'))) + p2 = str + strlen(str); + if(p1 + 1 > p2 || p1 + strspn(p1, ".") == p2) + return 1; + for(p3 = p1; p3 < p2; p3++) + if(not_alnum(*p3) && !strchr("@[]-._", *p3)) + return 1; + p1 = p2 + (*p2 ? 1 : 0); + } + return 0; +} + +int valid_ident(char *ident) { + static char *invalid[] = {"unknown@", "root@", "gopher@", "bbs@", + "@bbs", "guest@", "@ppp", "@slip", NULL}; + char buf[128]; + int i; + + str_lower(buf, ident); + for(i = 0; invalid[i]; i++) + if(strstr(buf, invalid[i])) + return 0; + return 1; +} + +int is_uBM(char *list, 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(char *list) { + if(is_uBM(list,cuser.userid)) { + cuser.userlevel |= PERM_BM; /* Ptt ¦Û°Ê¥[¤WBMªºÅv§Q */ + return 1; + } + return 0; +} + +int userid_is_BM(char *userid, char *list) { + register int ch, len; + + 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; +} + +/* ----------------------------------------------------- */ +/* ÀÉ®×Àˬd¨ç¼Æ¡GÀɮסB¥Ø¿ý¡BÄÝ©ó */ +/* ----------------------------------------------------- */ +off_t dashs(char *fname) { + struct stat st; + + if(!stat(fname, &st)) + return st.st_size; + else + return -1; +} + +long dasht(char *fname) { + struct stat st; + + if(!stat(fname, &st)) + return st.st_mtime; + else + return -1; +} + +int dashl(char *fname) { + struct stat st; + + return (lstat(fname, &st) == 0 && S_ISLNK(st.st_mode)); +} + +int dashf(char *fname) { + struct stat st; + + return (stat(fname, &st) == 0 && S_ISREG(st.st_mode)); +} + +int dashd(char *fname) { + struct stat st; + + return (stat(fname, &st) == 0 && S_ISDIR(st.st_mode)); +} + +int belong(char *filelist, char *key) { + FILE *fp; + int rc = 0; + + if((fp = fopen(filelist, "r"))) { + char buf[STRLEN], *ptr; + + while(fgets(buf, STRLEN, fp)) { + if((ptr = strtok(buf, str_space)) && !strcasecmp(ptr, key)) { + rc = 1; + break; + } + } + fclose(fp); + } + return rc; +} + +char *Cdate(time_t *clock) { + static char foo[32]; + struct tm *mytm = localtime(clock); + + strftime(foo, 32, "%m/%d/%Y %T %a", mytm); + return foo; +} + +char *Cdatelite(time_t *clock) { + static char foo[32]; + struct tm *mytm = localtime(clock); + + strftime(foo, 32, "%m/%d/%Y %T", mytm); + return foo; +} + +char *Cdatedate(time_t *clock){ + static char foo[32]; + struct tm *mytm = localtime(clock); + + strftime(foo, 32, "%m/%d/%Y", mytm); + return foo; +} + +static void capture_screen() { + char fname[200]; + FILE* fp; + extern screenline_t *big_picture; + extern unsigned char scr_lns; + int i; + + getdata(b_lines - 2, 0, "§â³oÓµe±¦¬¤J¨ì¼È¦sÀÉ¡H[y/N] ", + fname, 4, LCECHO); + if(fname[0] != 'y' ) return; + + setuserfile(fname, ask_tmpbuf(b_lines - 1)); + if((fp = fopen(fname, "w"))) { + for(i = 0; i < scr_lns; i++) + fprintf(fp, "%.*s\n", big_picture[i].len, big_picture[i].data); + fclose(fp); + } +} + +void pressanykey() { + int ch; + + outmsg("\033[37;45;1m " + "¡´ ½Ð«ö \033[33m(Space/Return)\033[37m Ä~Äò ¡´" + " \033[33m(^T)\033[37m ¦s¼È¦sÀÉ \033[m"); + do { + ch = igetkey(); + + if(ch == Ctrl('T')) { + capture_screen(); + break; + } + } while((ch != ' ') && (ch != KEY_LEFT) && (ch != '\r') && (ch != '\n')); + move(b_lines, 0); + clrtoeol(); + refresh(); +} + +int vmsg (const char *fmt, ...) +{ + va_list ap; + char msg[80] = {0}; + int ch; + + va_start (ap, fmt); + vsprintf (msg, fmt, ap); + va_end (ap); + + move (b_lines, 0); + clrtoeol (); + + if (*msg) + prints ("\033[1;36;44m ¡» %-55.54s \033[33;46m \033[200m\033[1431m\033[506m[½Ð«ö¥ô·NÁäÄ~Äò]\033[201m \033[m", msg); + else + outs ("\033[46;1m \033[37m" + "\033[200m\033[1431m\033[506m¡¼ ½Ð«ö \033[33m(Space/Return)\033[37m Ä~Äò ¡¼\033[201m" + " \033[m"); + + do { + ch = igetkey(); + + if(ch == Ctrl('T')) { + capture_screen(); + break; + } + } while((ch != ' ') && (ch != KEY_LEFT) && (ch != '\r') && (ch != '\n')); + + + move (b_lines, 0); + clrtoeol (); + refresh (); + return ch; +} + +void bell() { + char c; + + c = Ctrl('G'); + write(1, &c, 1); +} + +int search_num(int ch, int max) { + int clen = 1; + int x, y; + extern unsigned char scr_cols; + char genbuf[10]; + + outmsg("\033[7m ¸õ¦Ü²Ä´X¶µ¡G\033[m"); + outc(ch); + genbuf[0] = ch; + getyx(&y, &x); + x--; + while((ch = igetch()) != '\r') { + if(ch == 'q' || ch == 'e') + return -1; + if(ch == '\n') + break; + if(ch == '\177' || ch == Ctrl('H')) { + if(clen == 0) { + bell(); + continue; + } + clen--; + move(y, x + clen); + outc(' '); + move(y, x + clen); + continue; + } + if(!isdigit(ch)) { + bell(); + continue; + } + if(x + clen >= scr_cols || clen >= 6) { + bell(); + continue; + } + genbuf[clen++] = ch; + outc(ch); + } + genbuf[clen] = '\0'; + move(b_lines, 0); + clrtoeol(); + if(genbuf[0] == '\0') + return -1; + clen = atoi(genbuf); + if(clen == 0) + return 0; + if(clen > max) + return max; + return clen - 1; +} + +void stand_title(char *title) { + clear(); + prints("\033[1;37;46m¡i %s ¡j\033[m\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 = egetch(); + move(row, column); + outs(STR_UNCUR); + return ch; +} + +void printdash(char *mesg) { + int head = 0, tail; + + if(mesg) + head = (strlen(mesg) + 1) >> 1; + + tail = head; + + while(head++ < 38) + outch('-'); + + if(tail) { + outch(' '); + outs(mesg); + outch(' '); + } + + while(tail++ < 38) + outch('-'); + outch('\n'); +} + +int log_file(char *filename,char *buf) { + FILE *fp; + + if((fp = fopen(filename, "a" )) != NULL ) { + fputs( buf, fp ); + if(!strchr(buf,'\n')) + fputc('\n',fp); + fclose( fp ); + return 0; + } + else + return -1; +} + +void show_help(char *helptext[]) { + char *str; + int i; + + clear(); + for(i = 0; (str = helptext[i]); i++) { + if(*str == '\0') + prints("\033[1m¡i %s ¡j\033[0m\n", str + 1); + else if(*str == '\01') + prints("\n\033[36m¡i %s ¡j\033[m\n", str + 1); + else + prints(" %s\n", str); + } + pressanykey(); +} diff --git a/mbbsd/syspost.c b/mbbsd/syspost.c new file mode 100644 index 00000000..b7aefe10 --- /dev/null +++ b/mbbsd/syspost.c @@ -0,0 +1,102 @@ +/* $Id: syspost.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <sys/types.h> +#include "config.h" +#include "pttstruct.h" +#include "perm.h" +#include "common.h" +#include "proto.h" + +extern char *str_permid[]; +extern userec_t cuser; + +void post_change_perm(int oldperm, int newperm, char *sysopid, char *userid) { + FILE *fp; + fileheader_t fhdr; + time_t now = time(0); + char genbuf[200], reason[30]; + int i, flag=0; + + strcpy(genbuf, "boards/Security"); + stampfile(genbuf, &fhdr); + if(!(fp = fopen(genbuf,"w"))) + return; + + fprintf(fp, "§@ªÌ: [¨t²Î¦w¥þ§½] ¬ÝªO: Security\n" + "¼ÐÃD: [¤½¦w³ø§i] ¯¸ªøקïÅv³ø§i\n" + "®É¶¡: %s\n", ctime(&now)); + for(i = 5; i < NUMPERMS; i++) { + if(((oldperm >> i) & 1) != ((newperm >> i) & 1)) { + fprintf (fp, " ¯¸ªø\033[1;32m%s%s%s%s\033[mªºÅv\n", + sysopid, + (((oldperm >> i) & 1) ? "\033[1;33mÃö³¬":"\033[1;33m¶}±Ò"), + userid, str_permid[i]); + flag++; + } + } + + if(flag) { + clrtobot(); + clear(); + while(!getdata_str(5, 0, "½Ð¿é¤J²z¥Ñ¥H¥Üt³d¡G", + reason, 60, DOECHO, "¬Ýª©ª©¥D:")); + fprintf(fp, "\n \033[1;37m¯¸ªø%sקïÅv²z¥Ñ¬O¡G%s\033[m", + cuser.userid, reason); + fclose(fp); + + sprintf(fhdr.title, "[¤½¦w³ø§i] ¯¸ªø%sקï%sÅv³ø§i", + cuser.userid, userid); + strcpy(fhdr.owner, "[¨t²Î¦w¥þ§½]"); + append_record("boards/Security/.DIR", &fhdr, sizeof(fhdr)); + } +} + +void post_violatelaw(char* crime, char* police, char* reason, char* result){ + char genbuf[200]; + fileheader_t fhdr; + time_t now; + FILE *fp; + strcpy(genbuf, "boards/Security"); + stampfile(genbuf, &fhdr); + if(!(fp = fopen(genbuf,"w"))) + return; + now = time(NULL); + fprintf(fp, "§@ªÌ: [Pttªk°|] ¬ÝªO: Security\n" + "¼ÐÃD: [³ø§i] %-20s ¹Hªk§P¨M³ø§i\n" + "®É¶¡: %s\n" + "\033[1;32m%s\033[m§P¨M¡G\n \033[1;32m%s\033[m" + "¦]\033[1;35m%s\033[m¦æ¬°¡A\n¹H¤Ï¥»¯¸¯¸³W¡A³B¥H\033[1;35m%s\033[m¡A¯S¦¹¤½§i", + crime, ctime(&now), police, crime, reason, result); + fclose(fp); + sprintf(fhdr.title, "[³ø§i] %-20s ¹Hªk§P¨M³ø§i", crime); + strcpy(fhdr.owner, "[Pttªk°|]"); + append_record("boards/Security/.DIR", &fhdr, sizeof(fhdr)); + + strcpy(genbuf, "boards/ViolateLaw"); + stampfile(genbuf, &fhdr); + if(!(fp = fopen(genbuf,"w"))) + return; + now = time(NULL); + fprintf(fp, "§@ªÌ: [Pttªk°|] ¬ÝªO: ViolateLaw\n" + "¼ÐÃD: [³ø§i] %-20s ¹Hªk§P¨M³ø§i\n" + "®É¶¡: %s\n" + "\033[1;32m%s\033[m§P¨M¡G\n \033[1;32m%s\033[m" + "¦]\033[1;35m%s\033[m¦æ¬°¡A\n¹H¤Ï¥»¯¸¯¸³W¡A³B¥H\033[1;35m%s\033[m¡A¯S¦¹¤½§i", + crime, ctime(&now), police, crime, reason, result); + fclose(fp); + sprintf(fhdr.title, "[³ø§i] %-20s ¹Hªk§P¨M³ø§i", crime); + strcpy(fhdr.owner, "[Pttªk°|]"); + + append_record("boards/ViolateLaw/.DIR", &fhdr, sizeof(fhdr)); + +} + +void post_newboard(char* bgroup, char* bname, char* bms){ + char genbuf[256], title[128]; + sprintf(title, "[·sª©¦¨¥ß] %s", bname); + sprintf(genbuf, "%s ¶}¤F¤@Ó·sª© %s : %s\n\n·s¥ôª©¥D¬° %s\n\n®¥³ß*^_^*\n", + cuser.userid, bname, bgroup, bms); + post_msg("Record", title, genbuf, "[¨t²Î]"); +} diff --git a/mbbsd/talk.c b/mbbsd/talk.c new file mode 100644 index 00000000..3012b2d2 --- /dev/null +++ b/mbbsd/talk.c @@ -0,0 +1,2663 @@ +/* $Id: talk.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <syslog.h> +#include <unistd.h> +#include <stdlib.h> +#include <signal.h> +#include <netdb.h> +#include <time.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "perm.h" +#include "modes.h" +#include "proto.h" + +#define QCAST int (*)(const void *, const void *) + +extern userinfo_t *currutmp; +extern char *ModeTypeTable[MAX_MODES]; +extern char *fn_overrides; +extern int usernum; +extern char *msg_sure_ny; +extern char *msg_cancel; +extern unsigned int currstat; +extern char *fn_writelog; +extern FILE *fp_writelog; +extern pid_t currpid; +extern int b_lines; /* Screen bottom line number: t_lines-1 */ +extern int t_lines, t_columns; /* Screen size / width */ +extern char *fn_talklog; +extern char currauthor[IDLEN + 2]; +extern char *msg_usr_left; +extern char *msg_uid; +extern char *BBSName; +extern int p_lines; /* a Page of Screen line numbers: tlines-4 */ +extern char fromhost[]; +extern char *err_uid; +extern int talkrequest; +extern char *msg_shortulist; +extern char *msg_nobody; +extern boardheader_t *bcache; +extern int curr_idle_timeout; +extern userec_t cuser; +extern userec_t xuser; + + +static char *IdleTypeTable[] = { + "°¸¦bªá§b°Õ", "±¡¤H¨Ó¹q", "³V¹¤¤", "«ô¨£©P¤½", "°²¦ºª¬ºA", "§Ú¦b«ä¦Ò" +}; +static char *sig_des[] = { + "°«Âû", "²á¤Ñ", "", "¤U´Ñ", "¶H´Ñ", "·t´Ñ" +}; + +#define MAX_SHOW_MODE 3 +#define M_INT 15 /* monitor mode update interval */ +#define P_INT 20 /* interval to check for page req. in + * talk/chat */ +#define BOARDFRI 1 + +typedef struct talkwin_t { + int curcol, curln; + int sline, eline; +} talkwin_t; + +typedef struct pickup_t { + userinfo_t *ui; + time_t idle; + int friend; +} pickup_t; + +extern int bind( /* int,struct sockaddr *, int */ ); +extern char *getuserid(); +extern struct utmpfile_t *utmpshm; +extern int watermode; +extern water_t water[6], *swater[5], *water_which; +extern char *friend_file[8], water_usies; + +/* °O¿ý friend ªº user number */ +//#define PICKUP_WAYS 7 //Ãö±¼¤k¤hÀu¥ý +#define PICKUP_WAYS 6 + +static int pickup_way = 0; +static char *fcolor[11] = { + "", "\033[36m", "\033[32m", "\033[1;32m", + "\033[33m", "\033[1;33m", "\033[1;37m", "\033[1;37m", + "\033[31m", "\033[1;35m", "\033[1;36m" +}; +static char save_page_requestor[40]; +static char page_requestor[40]; +static char description[30]; +static FILE *flog; + + +char *modestring(userinfo_t * uentp, int simple) { + static char modestr[40]; + static char *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 (!(HAS_PERM(PERM_SYSOP) || HAS_PERM(PERM_SEECLOAK)) && + ( + (uentp->invisible || (fri_stat & HRM)) && + !((fri_stat & HFM) && (fri_stat & HRM)) + ) + ) + return notonline; + else if (mode == EDITING) + { + sprintf(modestr, "E:%s", + ModeTypeTable[uentp->destuid < EDITING ? uentp->destuid : + EDITING]); + word = modestr; + } + else if (!mode && *uentp->chatid == 1) + { + if (!simple) + sprintf(modestr, "¦^À³ %s", getuserid(uentp->destuid)); + else + sprintf(modestr, "¦^À³©I¥s"); + } + else if (!mode && *uentp->chatid == 2) + if (uentp->msgcount < 10) + { + char *cnum[10] = + {"", "¤@", "¨â", "¤T", "¥|", "¤", "¤»", "¤C", + "¤K", "¤E"}; + sprintf(modestr, "¤¤%sÁû¤ô²y", cnum[uentp->msgcount]); + } + else + sprintf(modestr, "¤£¦æ¤F @_@"); + else if (!mode && *uentp->chatid == 3) + sprintf(modestr, "¤ô²y·Ç³Æ¤¤"); + 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) + sprintf(modestr, "%s (%s)", word, uentp->chatid); + else if (mode == TALK) + { + if (!isvisible_uid(uentp->destuid))/* Leeym ¹ï¤è(µµ¦â)Áô§Î */ + sprintf(modestr, "%s", "¥æ½Í ªÅ®ð");/* Leeym ¤j®a¦Û¤vµo´§§a¡I */ + else + sprintf(modestr, "%s %s", word, getuserid(uentp->destuid)); + } + else if (mode == M_FIVE) + { + if (!isvisible_uid(uentp->destuid)) + sprintf(modestr, "%s", "¤¤l´Ñ ªÅ®ð"); + else + sprintf(modestr, "%s %s", word, getuserid(uentp->destuid)); + } + else if (mode == CHC) + { + if (isvisible_uid(uentp->destuid)) + sprintf(modestr, "%s", "¤U¶H´Ñ"); + else + sprintf(modestr, "¤U¶H´Ñ %s", getuserid(uentp->destuid)); + } + else if (mode != PAGE && mode != TQUERY) + return word; + else + sprintf(modestr, "%s %s", word, getuserid(uentp->destuid)); + + return (modestr); +} + +int set_friend_bit(userinfo_t * me, userinfo_t * ui) { + int unum, *myfriends, hit=0, n; + +/* §PÂ_¹ï¤è¬O§_¬°§ÚªºªB¤Í ? */ + unum = ui->uid; + myfriends = me->friend; + while ((n = *myfriends++)) + { + if (unum == n) + { + hit = IFH; + break; + } + } + +/* §PÂ_§Ú¬O§_¬°¹ï¤èªºªB¤Í ? */ + myfriends = ui->friend; + while ((unum = *myfriends++)) + { + if (unum == me->uid) + { + hit |= HFM; + break; + } + } + +/* §PÂ_¹ï¤è¬O§_¬°§Úªº¤³¤H ? */ + + unum = ui->uid; + myfriends = me->reject; + while ((n = *myfriends++)) + { + if (unum == n) + { + hit |= IRH; + break; + } + } + +/* §PÂ_§Ú¬O§_¬°¹ï¤èªº¤³¤H ? */ + myfriends = ui->reject; + while ((unum = *myfriends++)) + { + if (unum == me->uid) + { + hit |= HRM; + break; + } + } + return hit; +} +int reverse_friend_stat(int stat) +{ + int stat1=0; + if(stat & IFH) + stat1 |=HFM; + if(stat & IRH) + stat1 |=HRM; + if(stat & HFM) + stat1 |=IFH; + if(stat & HRM) + stat1 |=IRH; + if(stat & IBH) + stat1 |=IBH; + return stat1; +} + +int login_friend_online(){ + userinfo_t *uentp; + int i, stat, stat1; + int offset=(int) (currutmp - &utmpshm->uinfo[0]); + for (i=0;i<utmpshm->number && currutmp->friendtotal<MAX_FRIEND; i++) + { + uentp = (utmpshm->sorted[utmpshm->currsorted][0][i]); + if(uentp && uentp->uid && (stat=set_friend_bit(currutmp,uentp))) + { + stat1=reverse_friend_stat(stat); + stat <<= 24; + stat |= (int) (uentp - &utmpshm->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 0; +} + +int logout_friend_online(){ + int i, j, k; + int offset=(int) (currutmp - &utmpshm->uinfo[0]); + userinfo_t *ui; + while(currutmp->friendtotal) + { + i = currutmp->friendtotal-1; + j = (currutmp->friend_online[i] & 0xFFFFFF); + currutmp->friend_online[i]=0; + ui = &utmpshm->uinfo[j]; + if(ui->pid && ui!=currutmp) + { + for(k=0; k<ui->friendtotal && + (int)(ui->friend_online[k] & 0xFFFFFF) !=offset; k++); + if(k<ui->friendtotal) + { + ui->friendtotal--; + ui->friend_online[k]=ui->friend_online[ui->friendtotal]; + ui->friend_online[ui->friendtotal]=0; + } + } + currutmp->friendtotal--; + currutmp->friend_online[currutmp->friendtotal]=0; + } + return 0; +} + + +int friend_stat(userinfo_t *me, 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++) + { + j = (me->friend_online[i] & 0xFFFFFF); + if(ui == &utmpshm->uinfo[j]) + { + hit |= me->friend_online[i] >>24; + break; + } + } + if (PERM_HIDE(ui)) + return hit & ST_FRIEND; + return hit; +} + +int isvisible_stat(userinfo_t * me, userinfo_t * uentp, int fri_stat) { + if (uentp->userid[0] == 0) + 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) ? 0 : 1; +} + +int isvisible(userinfo_t * me, userinfo_t * uentp) { + return isvisible_stat(currutmp, uentp, friend_stat(me, uentp)); +} + +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') + { + sprintf(genbuf, "%s (%s)", uentp->userid, uentp->username); + 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(); +} + +static void chicken_query(char *userid) { + char buf[100]; + + if (getuser(userid)) + { + if (xuser.mychicken.name[0]) + { + time_diff(&(xuser.mychicken)); + if (!isdeadth(&(xuser.mychicken))) + { + show_chicken_data(&(xuser.mychicken), NULL); + sprintf(buf, "\n\n¥H¤W¬O %s ªºÃdª«¸ê®Æ..", userid); + outs(buf); + } + } + else + { + move(1, 0); + clrtobot(); + sprintf(buf, "\n\n%s ¨Ã¨S¦³¾iÃdª«..", userid); + outs(buf); + } + pressanykey(); + } +} + +int my_query(char *uident) { + userec_t muser; + int tuid, i, fri_stat=0; + unsigned long int j; + userinfo_t *uentp; + static const char *money[10] = + {"¶Å¥x°ª¿v", "¨ª³h", "²M´H", "´¶³q", "¤p±d", + "¤p´I", "¤¤´I", "¤j´I¯Î", "´I¥i¼Ä°ê", "¤ñº¸»\\¤Ñ"}, + *sex[8] = + {MSG_BIG_BOY, MSG_BIG_GIRL, + MSG_LITTLE_BOY, MSG_LITTLE_GIRL, + MSG_MAN, MSG_WOMAN, MSG_PLANT, MSG_MIME}; + + + if ((tuid = getuser(uident))) + { + memcpy(&muser, &xuser, sizeof(muser)); + move(1, 0); + clrtobot(); + move(1, 0); + setutmpmode(TQUERY); + currutmp->destuid = tuid; + + j = muser.money; + for (i = 0; i < 10 && j > 10; i++) + j /= 10; + prints("¡m¢×¢Ò¼ÊºÙ¡n%s(%s)%*s¡m¸gÀÙª¬ªp¡n%s\n", + muser.userid, + muser.username, + 26 - strlen(muser.userid) - strlen(muser.username), "", + money[i]); + prints("¡m¤W¯¸¦¸¼Æ¡n%d¦¸", muser.numlogins); + move(2, 40); + prints("¡m¤å³¹½g¼Æ¡n%d½g\n", muser.numposts); + + if((uentp = (userinfo_t *) search_ulist(tuid))) + fri_stat=friend_stat(currutmp, uentp); + prints("\033[1;33m¡m¥Ø«e°ÊºA¡n%-28.28s\033[m", + (uentp && isvisible_stat(currutmp, uentp, fri_stat)) ? + modestring(uentp, 0) : "¤£¦b¯¸¤W"); + + outs(((uentp && uentp->mailalert) || 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 : "(¤£¸Ô)")); + if ((uentp && fri_stat&HFM) || HAS_PERM(PERM_SYSOP)) + prints("¡m ©Ê §O ¡n%-28.28s¡m¨p¦³°]²£¡n%ld »È¨â\n", + sex[muser.sex % 8], + muser.money); + prints("¡m¤¤l´Ñ¾ÔÁZ¡n%3d ³Ó %3d ±Ñ %3d ©M " + "¡m¶H´Ñ¾ÔÁZ¡n%3d ³Ó %3d ±Ñ %3d ©M", + muser.five_win, muser.five_lose, muser.five_tie, + muser.chc_win, muser.chc_lose, muser.chc_tie); + showplans(uident); + pressanykey(); + return FULLUPDATE; + } + return DONOTHING; +} + +static char t_last_write[200] = ""; + +void water_scr(water_t **currwater, int which, char type) +{ + if( type == 1 ){ + int i; + int colors[] = {33, 37, 33, 37, 33}; + move(8 + which, 28);prints(" "); + move(8 + which, 28); + prints("\033[1;37;45m %-14s \033[0m", currwater[which]->userid); + for( i = 0 ; i < 5 ; ++i ){ + move(16 + i, 4); + prints(" "); + move(16 + i, 4); + if( currwater[which]->msg[ (currwater[which]->top-i+4) % 5 ].last_call_in[0] != 0 ) + prints("\033[0m \033[1;%d;44m¡¹%-64s\033[0m \n", + colors[i], + currwater[which]->msg[ (currwater[which]->top-i+4) % 5 ].last_call_in); + else + prints("\033[0m¡@\n"); + } + move(0, 0);prints(" "); + move(0, 0); + prints("\033[0m¤ÏÀ» %s:", currwater[which]->userid); + clrtoeol(); + move(0, strlen(currwater[which]->userid) + 6); + } + else{ + move(8 + which, 28); + prints("123456789012345678901234567890"); + // refresh(); + move(8 + which, 28); + prints("\033[1;37;44m %-13s¡@\033[0m", currwater[which]->userid); + // refresh(); + } +} + +void my_write2(void) +{ + int i, ch, currstat0, currwater_usies; + char genbuf[256], msg[80], done = 0, c0, which; + water_t *tw, *currwater[5]; + unsigned char mode0; + + watermode = 0; + currstat0 = currstat; + c0 = currutmp->chatid[0]; + mode0 = currutmp->mode; + currutmp->mode = 0; + currutmp->chatid[0] = 3; + currstat = XMODE; + + // init screen + memcpy(currwater, swater, sizeof(water_t*) * 5); + currwater_usies = water_usies; + move(7, 28); + prints("\033[1;33;46m ¡ô ¤ô²y¤ÏÀ»¹ï¶H ¡õ\033[0m"); + for( i = 0 ; i < 5 ; ++i ) + if( currwater[i] == NULL || currwater[i]->pid == 0 ) + break; + else + water_scr(currwater, i, 0); + move(15, 4); + prints("\033[0m \033[1;35m¡º\033[1;36m¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w" + "¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w\033[1;35m¡º\033[0m "); + move(22, 4); + prints(" \033[1;35m¡º\033[1;36m¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w" + "¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w\033[1;35m¡º\033[0m "); + move(21, 4);prints(" "); + move(21, 4); + prints("\033[0m \033[1;37;46m%-66s\033[0m \n", t_last_write); + water_scr(currwater, 0, 1); + refresh(); + + which = 0; + do{ + switch( (ch = igetkey()) ){ + case Ctrl('T'): + case KEY_UP: + if( currwater_usies != 1 ){ + water_scr(currwater, which, 0); + which = (which - 1 + currwater_usies) % currwater_usies; + water_scr(currwater, which, 1); + refresh(); + } + break; + + case KEY_DOWN: + case Ctrl('R'): + if( currwater_usies != 1 ){ + water_scr(currwater, which, 0); + which = (which + 1 + currwater_usies) % currwater_usies; + water_scr(currwater, which, 1); + refresh(); + } + break; + + case KEY_LEFT: + done = 1; + break; + + default: + done = 1; + watermode = 1; + tw = currwater[(int)which]; + + if( ch != '\r' && ch != '\n' ){ + msg[0] = ch, msg[1] = 0; + } + else + msg[0] = 0; + move(0, 0);prints("\033[m"); clrtoeol(); + refresh(); + sprintf(genbuf, "§ðÀ» %s:", tw->userid); + if( !oldgetdata(0, 0, genbuf, msg, + 80-strlen(tw->userid)-6, DOECHO) ) + break; + + my_write(tw->pid, msg, tw->userid, 4); + break; + } + } while( !done ); + + watermode = -1; + currstat = currstat0; + currutmp->chatid[0] = c0; + currutmp->mode = mode0; +} + +/* + ³Q©I¥sªº®É¾÷: + 1. ¥á¸s²Õ¤ô²y flag = 1 (pre-edit) + 2. ¦^¤ô²y flag = 0 + 3. ¤W¯¸aloha flag = 2 (pre-edit) + 4. ¼s¼½ flag = 3 if SYSOP, otherwise flag = 1 (pre-edit) + 5. ¥á¤ô²y flag = 0 + 6. my_write2 flag = 4 (pre-edit) but confirm +*/ +int my_write(pid_t pid, char *prompt, char *id, int flag) { + int len, currstat0 = currstat, fri_stat; + char msg[80], destid[IDLEN + 1]; + char genbuf[200], buf[200], c0 = currutmp->chatid[0]; + unsigned char mode0 = currutmp->mode; + time_t now; + struct tm *ptime; + userinfo_t *uin; + uin = (userinfo_t *)search_ulist_pid(pid); + strcpy(destid, id); + + if(!uin && !(flag == 0 && water_which->count> 0)) { + outmsg("\033[1;33;41mÁV¿|! ¹ï¤è¤w¸¨¶]¤F(¤£¦b¯¸¤W)! \033[37m~>_<~\033[m"); + clrtoeol(); + refresh(); + watermode = -1; + return 0; + } + currutmp->mode = 0; + currutmp->chatid[0] = 3; + currstat = XMODE; + + time(&now); + ptime = localtime(&now); + + if(flag == 0) { + /* ¤@¯ë¤ô²y */ + watermode = 0; + if(!(len = getdata(0, 0, prompt, msg, 56, DOECHO))) { + outmsg("\033[1;33;42mºâ¤F! ©ñ§A¤@°¨...\033[m"); + clrtoeol(); + refresh(); + 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); + strcpy(destid, water_which->msg[i].userid); + } + } else { + /* pre-edit ªº¤ô²y */ + strcpy(msg, prompt); + len = strlen(msg); + } + + watermode = -1; + strip_ansi(msg, msg, 0); + if(uin && *uin->userid && (flag == 0 || flag == 4)) { + sprintf(buf, "¥áµ¹ %s : %s [Y/n]?", uin->userid, msg); + getdata(0, 0, buf, genbuf, 3, LCECHO); + if(genbuf[0] == 'n') { + outmsg("\033[1;33;42mºâ¤F! ©ñ§A¤@°¨...\033[m"); + clrtoeol(); + refresh(); + currutmp->chatid[0] = c0; + currutmp->mode = mode0; + currstat = currstat0; + watermode = -1; + return 0; + } + } + + if(!uin || !*uin->userid || strcasecmp(destid, uin->userid)) { + outmsg("\033[1;33;41mÁV¿|! ¹ï¤è¤w¸¨¶]¤F(¤£¦b¯¸¤W)! \033[37m~>_<~\033[m"); + clrtoeol(); + refresh(); + currutmp->chatid[0] = c0; + currutmp->mode = mode0; + currstat = currstat0; + return 0; + } + + fri_stat=friend_stat(currutmp, uin); + time(&now); + if(flag != 2) { /* 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", + uin->userid, msg, Cdatelite(&now)); + snprintf(t_last_write, 66, "To %s: %s", uin->userid, msg); + } + } + + if(flag == 3 && uin->msgcount) { + /* ¤£À´ */ + uin->destuip = currutmp - &utmpshm->uinfo[0]; + uin->sig = 2; + if(uin->pid > 0) kill(uin->pid, SIGUSR1); + } else if(flag != 2 && + !HAS_PERM(PERM_SYSOP) && + (uin->pager == 3 || + uin->pager == 2 || + (uin->pager == 4 && + !(fri_stat & HFM)))) + outmsg("\033[1;33;41mÁV¿|! ¹ï¤è¨¾¤ô¤F! \033[37m~>_<~\033[m"); + else { + if(uin->msgcount < MAX_MSGS) { + unsigned char pager0 = uin->pager; + + uin->pager = 2; + uin->msgs[uin->msgcount].pid = currpid; + strcpy(uin->msgs[uin->msgcount].userid, cuser.userid); + strcpy(uin->msgs[uin->msgcount++].last_call_in, msg); + uin->pager = pager0; + } else if (flag != 2) + outmsg("\033[1;33;41mÁV¿|! ¹ï¤è¤£¦æ¤F! (¦¬¨ì¤Ó¦h¤ô²y) \033[37m@_@\033[m"); + + if(uin->msgcount == 1 && (uin->pid <= 0 || kill(uin->pid, SIGUSR2) == -1) && flag != 2) + outmsg("\033[1;33;41mÁV¿|! ¨S¥´¤¤! \033[37m~>_<~\033[m"); + else if(uin->msgcount == 1 && flag != 2) + outmsg("\033[1;33;44m¤ô²y¯{¹L¥h¤F! \033[37m*^o^*\033[m"); + else if(uin->msgcount > 1 && uin->msgcount < MAX_MSGS && flag != 2) + outmsg("\033[1;33;44m¦A¸É¤W¤@²É! \033[37m*^o^*\033[m"); + } + + clrtoeol(); + refresh(); + + currutmp->chatid[0] = c0; + currutmp->mode = mode0; + currstat = currstat0; + return 1; +} +void t_display_new() { + static int t_display_new_flag=0; + int i, off=2; + if (t_display_new_flag) + return; + else + t_display_new_flag = 1; + + 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-E Ctrl-W ]Áä¤Á´«¢w¢w¢w¢w"); + if( WATERMODE(WATER_NEW) ){ + move(2, 0); + clrtoeol(); + for (i = 0; i<6 ; i++){ + if(i>0) + prints("%s%-13.13s\033[m", + swater[i-1]==water_which?"\033[1;33;47m ": + " ", + swater[i-1] ? swater[i-1]->userid:""); + else + prints("%s ¥þ³¡ \033[m", + water_which==&water[0]?"\033[1;33;45m ": + " "); + } + } + + for (i = 0; i < water_which->count; i++){ + int a = (water_which->top - i - 1 + MAX_REVIEW) % MAX_REVIEW, + 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("\033[1;33;46m %s \033[37;45m %s \033[m%*s", + water_which->msg[a].userid, + water_which->msg[a].last_call_in, len, + ""); + else + prints("\033[1;44m>\033[1;33;47m%s " + "\033[37;45m %s \033[m%*s", + water_which->msg[a].userid, + water_which->msg[a].last_call_in, + len,""); + } + + if (t_last_write[0]){ + move(i + off, 0); + clrtoeol(); + prints(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; +} +#if 0 +void t_display_new() { + int i, which=water_which; + char buf[200]; + + if (t_display_new_flag) + return; + else + t_display_new_flag = 1; + + if (oldmsg_count && watermode > 0) + { + move(1, 0); + outs( + "¢w¢w¢w¢w¢w¢w¢w¤ô¢w²y¢w¦^¢wÅU¢w¢w¢w¢w¢w¢w¢w¢w¢w" + "¥Î[Ctrl-R Ctrl-T]Áä¤Á´«¢w¢w¢w¢w¢w"); + move(2, 0); + prints(" |"); + for (i = 0; i<5 && water[i].pid != 0; i++) + prints(" %s%13.13s \033[m|",which==i?"\033[1;33m":"", + water[i].userid); + + for( i = 0 ; i < 5 && + water[which].msg[ (water[which].msgtop-i+4) % 5 ][0] != 0; ++i ){ + move(3 + i, 0); + if (watermode - 1 != i) + sprintf(buf, "\033[1;33;46m %s \033[37;45m %s \033[m", + water[which].userid, + water[which].msg[ (water[which].msgtop-i+4) % 5 ]); + else + sprintf(buf, "\033[1;44m>\033[1;33;47m%s \033[37;45m %s \033[m", + water[which].userid, + water[which].msg[ (water[which].msgtop-i+4) % 5 ]); + } + /* + for (i = 0; i < oldmsg_count; i++) + { + int a = (water[water_which].top - i - 1 + MAX_REVIEW) % MAX_REVIEW; + + move(i + 3, 0); + clrtoeol(); + if (watermode - 1 != i) + sprintf(buf, "\033[1;33;46m %s \033[37;45m %s \033[m", + oldmsg[a].userid, oldmsg[a].last_call_in); + else + sprintf(buf, "\033[1;44m>\033[1;33;47m%s " + "\033[37;45m %s \033[m", + oldmsg[a].userid, oldmsg[a].last_call_in); + outs(buf); + } +*/ + if (t_last_write[0]) + { + move(i + 3, 0); + clrtoeol(); + outs(t_last_write); + i++; + } + move(i + 3, 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¢w"); + } + t_display_new_flag = 0; +} +#endif + +int t_display() { + char genbuf[200], ans[4]; + if(fp_writelog) + { fclose(fp_writelog); fp_writelog=NULL;} + setuserfile(genbuf, fn_writelog); + if (more(genbuf, YEA) != -1) + { + getdata(b_lines - 1, 0, "²M°£(C) ²¾¦Ü³Æ§Ñ¿ý(M) «O¯d(R) (C/M/R)?[R]", + ans, 3, LCECHO); + if (*ans == 'm') + { + fileheader_t mymail; + char title[128], buf[80]; + + sethomepath(buf, cuser.userid); + stampfile(buf, &mymail); + + mymail.savemode = 'H'; /* hold-mail flag */ + mymail.filemode = FILE_READ; + strcpy(mymail.owner, "[³Æ.§Ñ.¿ý]"); + strcpy(mymail.title, "¼ö½u\033[37;41m°O¿ý\033[m"); + 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 + region_scroll_up(twin->sline, twin->eline); + move(twin->curln, twin->curcol); +} + +static void do_talk_char(talkwin_t * twin, int ch) { + extern screenline_t *big_picture; + screenline_t *line; + int i; + char ch0, buf[81]; + + if (isprint2(ch)) + { + ch0 = big_picture[twin->curln].data[twin->curcol]; + if (big_picture[twin->curln].len < 79) + move(twin->curln, twin->curcol); + else + do_talk_nextline(twin); + outc(ch); + ++(twin->curcol); + line = big_picture + twin->curln; + if (twin->curcol < line->len) + { /* insert */ + ++(line->len); + memcpy(buf, line->data + twin->curcol, 80); + save_cursor(); + do_move(twin->curcol, twin->curln); + ochar(line->data[twin->curcol] = ch0); + for (i = twin->curcol + 1; i < line->len; i++) + ochar(line->data[i] = buf[i - twin->curcol - 1]); + restore_cursor(); + } + line->data[line->len] = 0; + return; + } + + switch (ch) + { + case Ctrl('H'): + case '\177': + if (twin->curcol == 0) + return; + line = big_picture + twin->curln; + --(twin->curcol); + if (twin->curcol < line->len) + { + --(line->len); + save_cursor(); + do_move(twin->curcol, twin->curln); + for (i = twin->curcol; i < line->len; i++) + ochar(line->data[i] = line->data[i + 1]); + line->data[i] = 0; + ochar(' '); + restore_cursor(); + } + move(twin->curln, twin->curcol); + return; + case Ctrl('D'): + line = big_picture + twin->curln; + if (twin->curcol < line->len) + { + --(line->len); + save_cursor(); + do_move(twin->curcol, twin->curln); + for (i = twin->curcol; i < line->len; i++) + ochar(line->data[i] = line->data[i + 1]); + line->data[i] = 0; + ochar(' '); + restore_cursor(); + } + return; + case Ctrl('G'): + bell(); + return; + case Ctrl('B'): + if (twin->curcol > 0) + { + --(twin->curcol); + move(twin->curln, twin->curcol); + } + return; + case Ctrl('F'): + if (twin->curcol < 79) + { + ++(twin->curcol); + move(twin->curln, twin->curcol); + } + return; + case KEY_TAB: + twin->curcol += 8; + if (twin->curcol > 80) + twin->curcol = 80; + move(twin->curln, twin->curcol); + return; + case Ctrl('A'): + twin->curcol = 0; + move(twin->curln, twin->curcol); + return; + case Ctrl('K'): + clrtoeol(); + return; + case Ctrl('Y'): + twin->curcol = 0; + move(twin->curln, twin->curcol); + clrtoeol(); + return; + case Ctrl('E'): + twin->curcol = big_picture[twin->curln].len; + move(twin->curln, twin->curcol); + return; + case Ctrl('M'): + case Ctrl('J'): + line = big_picture + twin->curln; + strncpy(buf, line->data, line->len); + buf[line->len] = 0; + do_talk_nextline(twin); + break; + case Ctrl('P'): + line = big_picture + twin->curln; + strncpy(buf, line->data, line->len); + buf[line->len] = 0; + if (twin->curln > twin->sline) + { + --(twin->curln); + move(twin->curln, twin->curcol); + } + break; + case Ctrl('N'): + line = big_picture + twin->curln; + strncpy(buf, line->data, line->len); + buf[line->len] = 0; + if (twin->curln < twin->eline) + { + ++(twin->curln); + move(twin->curln, twin->curcol); + } + break; + } + trim(buf); + if (*buf) + fprintf(flog, "%s%s: %s%s\n", + (twin->eline == b_lines - 1) ? "\033[1;35m" : "", + (twin->eline == b_lines - 1) ? + getuserid(currutmp->destuid) : cuser.userid, buf, + (ch == Ctrl('P')) ? "\033[37;45m(Up)\033[m" : "\033[m"); +} + +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; + struct tm *ptime; + time_t now; + char genbuf[200], fpath[100]; + + time(&now); + ptime = localtime(&now); + + sethomepath(fpath, cuser.userid); + strcpy(fpath, tempnam(fpath, "talk_")); + flog = fopen(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); + sprintf(genbuf, "%s¡i%s", cuser.userid, cuser.username); + i = ch - strlen(genbuf); + if (i >= 0) + i = (i >> 1) + 1; + else + { + genbuf[ch] = '\0'; + i = 1; + } + memset(data, ' ', i); + data[i] = '\0'; + + sprintf(mid_line, "\033[1;46;37m ½Í¤Ñ»¡¦a \033[45m%s%s¡j" + " »P %s%s\033[0m", 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; + + clear(); + move(i, 0); + outs(mid_line); + move(0, 0); + + add_io(fd, 0); + + while (1) + { + ch = igetkey(); + if (ch == I_OTHERDATA) + { + datac = recv(fd, data, sizeof(data), 0); + if (datac <= 0) + break; + for (i = 0; i < datac; i++) + do_talk_char(&itswin, data[i]); + } + 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) + fprintf(log, "%c", (ch == Ctrl('M')) ? '\n' : (char) *data); + do_talk_char(&mywin, *data); + } + } + if (log) + fclose(log); + + add_io(0, 0); + close(fd); + + if (flog) + { + char ans[4]; + extern screenline_t *big_picture; + extern unsigned char scr_lns; + int i; + + time(&now); + fprintf(flog, "\n\033[33;44mÂ÷§Oµe± [%s] ... \033[m\n", + Cdatelite(&now)); + for (i = 0; i < scr_lns; i++) + fprintf(flog, "%.*s\n", big_picture[i].len, big_picture[i].data); + fclose(flog); + more(fpath, NA); + getdata(b_lines - 1, 0, "²M°£(C) ²¾¦Ü³Æ§Ñ¿ý(M). (C/M)?[C]", + ans, 4, LCECHO); + if (*ans == 'm') + { + fileheader_t mymail; + char title[128]; + + sethomepath(genbuf, cuser.userid); + stampfile(genbuf, &mymail); + mymail.savemode = 'H'; /* hold-mail flag */ + mymail.filemode = FILE_READ; + strcpy(mymail.owner, "[³Æ.§Ñ.¿ý]"); + sprintf(mymail.title, "¹ï¸Ü°O¿ý \033[1;36m(%s)\033[m", + getuserid(currutmp->destuid)); + sethomedir(title, cuser.userid); + Rename(fpath, genbuf); + append_record(title, &mymail, sizeof(mymail)); + } + else + unlink(fpath); + flog = 0; + } + setutmpmode(XINFO); +} + +#define lockreturn(unmode, state) if(lockutmpmode(unmode, state)) return + +static void my_talk(userinfo_t * uin, int fri_stat) { + int sock, msgsock, length, ch, error = 0; + struct sockaddr_in server; + pid_t pid; + char c; + char genbuf[4]; + + unsigned char mode0 = currutmp->mode; + + ch = uin->mode; + strcpy(currauthor, uin->userid); + + 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)) || + uin->lockmode == M_FIVE || uin->lockmode == CHC) + { + outs("¤H®a¦b¦£°Õ"); + } + else if (!HAS_PERM(PERM_SYSOP) && + ( + ((fri_stat& HRM) && !(fri_stat& HFM)) || + ((!uin->pager) && !(fri_stat & HFM)) + ) + ) + { + outs("¹ï¤èÃö±¼©I¥s¾¹¤F"); + } + else if (!HAS_PERM(PERM_SYSOP) && + ( + ((fri_stat & HRM) && !(fri_stat& HFM)) || + uin->pager == 2 + ) + ) + { + outs("¹ï¤è©Þ±¼©I¥s¾¹¤F"); + } + else if (!HAS_PERM(PERM_SYSOP) && + !(fri_stat & HFM) && uin->pager == 4) + { + outs("¹ï¤è¥u±µ¨ü¦n¤Íªº©I¥s"); + } + else if (!(pid = uin->pid) /*|| (kill(pid, 0) == -1) */ ) + { +// resetutmpent(); + outs(msg_usr_left); + } + else + { + showplans(uin->userid); + getdata(2, 0, "n©M¥L(¦o) (T)½Í¤Ñ(F)¤U¤¤l´Ñ(P)°«Ãdª«" + "(C)¤U¶H´Ñ(D)¤U·t´Ñ(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 'p': + reload_chicken(); + getuser(uin->userid); + if (uin->lockmode == CHICKEN || currutmp->lockmode == CHICKEN) + error = 1; + if (!cuser.mychicken.name[0] || !xuser.mychicken.name[0]) + error = 2; + if (error) + { + outmsg(error == 2 ? "¨Ã«D¨â¤H³£¾iÃdª«" : + "¦³¤@¤èªºÃdª«¥¿¦b¨Ï¥Î¤¤"); + bell(); + refresh(); + sleep(1); + return; + } + uin->sig = SIG_PK; + break; + default: + return; + } + + uin->turn = 1; + currutmp->turn = 0; + strcpy(uin->mateid, currutmp->userid); + strcpy(currutmp->mateid, uin->userid); + + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock < 0) + { + perror("sock err"); + unlockutmpmode(); + return; + } + 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; + } + length = sizeof(server); + if (getsockname(sock, (struct sockaddr *) &server, &length) < 0) + { + close(sock); + perror("sock name err"); + unlockutmpmode(); + return; + } + currutmp->sockactive = YEA; + currutmp->sockaddr = server.sin_port; + currutmp->destuid = uin->uid; + setutmpmode(PAGE); + uin->destuip = currutmp - &utmpshm->uinfo[0]; + if(pid > 0) kill(pid, SIGUSR1); + clear(); + prints("¥¿©I¥s %s.....\nÁä¤J Ctrl-D ¤¤¤î....", uin->userid); + + listen(sock, 1); + add_io(sock, 5); + while (1) + { + ch = igetch(); + if (ch == I_TIMEOUT) + { + ch = uin->mode; + if (!ch && uin->chatid[0] == 1 && + uin->destuip == currutmp - &utmpshm->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; + outmsg("¤H®a¦b¦£°Õ"); + pressanykey(); + unlockutmpmode(); + return; + } + else + { +#ifdef linux + add_io(sock, 20); /* added for linux... achen */ +#endif + move(0, 0); + outs("¦A"); + bell(); + + uin->destuip = currutmp - &utmpshm->uinfo[0]; + if(pid <= 0 || kill(pid, SIGUSR1) == -1) + { +#ifdef linux + add_io(sock, 20); /* added 4 linux... achen */ +#endif + outmsg(msg_usr_left); + refresh(); + pressanykey(); + unlockutmpmode(); + return; + } + continue; + } + } + + if (ch == I_OTHERDATA) + break; + + if (ch == '\004') + { + add_io(0, 0); + close(sock); + currutmp->sockactive = currutmp->destuid = 0; + unlockutmpmode(); + return; + } + } + + msgsock = accept(sock, (struct sockaddr *) 0, (int *) 0); + if (msgsock == -1) + { + perror("accept"); + unlockutmpmode(); + return; + } + add_io(0, 0); + close(sock); + currutmp->sockactive = NA; + read(msgsock, &c, sizeof c); + + if (c == 'y') + { + sprintf(save_page_requestor, "%s (%s)", + uin->userid, uin->username); + /* gomo */ + switch (uin->sig) + { + case SIG_DARK: + main_dark(msgsock, uin); + break; + case SIG_PK: + chickenpk(msgsock); + break; + case SIG_GOMO: + gomoku(msgsock); + break; + case SIG_CHC: + chc(msgsock); + 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() { + clear(); + + outs("\033[36m¡i ¥ð¶¢²á¤Ñ¨Ï¥Î»¡©ú ¡j\033[m\n\n" + "(¡ö)(e) µ²§ôÂ÷¶} (h) ¬Ý¨Ï¥Î»¡©ú\n" + "(¡ô)/(¡õ)(n) ¤W¤U²¾°Ê (TAB) ¤Á´«±Æ§Ç¤è¦¡\n" + "(PgUp)(^B) ¤W¶¿ï³æ ( )(PgDn)(^F) ¤U¶¿ï³æ\n" + "(Hm)/($)(Ed) º/§À (S) " + "¨Ó·½/¦n¤Í´yz/¾ÔÁZ ¤Á´«\n" + "(m) ±H«H (q/c) " + "¬d¸ßºô¤Í/Ãdª«\n" + "(r) ¾\\Ū«H¥ó (l) ¬Ý¤W¦¸¼ö°T\n" + "(f) ¥þ³¡/¦n¤Í¦Cªí (¼Æ¦r) ¸õ¦Ü¸Ó¨Ï¥ÎªÌ\n" + "(p) ¤Á´«©I¥s¾¹ (g/i) µ¹¿ú/¤Á´«¤ß±¡\n" + "(a/d/o) ¦n¤Í ¼W¥[/§R°£/קï (/)(s) ºô¤ÍID/¼ÊºÙ·j´M"); + + if (HAS_PERM(PERM_PAGE)) + { + outs("\n\n\033[36m¡i ¥æ½Í±M¥ÎÁä ¡j\033[m\n\n" + "(¡÷)(t)(Enter) ¸ò¥L¡þ¦o²á¤Ñ\n" + "(w) ¼ö½u Call in\n" + "(b) ¹ï¦n¤Í¼s¼½ (¤@©wn¦b¦n¤Í¦Cªí¤¤)\n" + "(^R) §Y®É¦^À³ (¦³¤H Call in §A®É)"); + } + + if (HAS_PERM(PERM_SYSOP)) + { + outs("\n\n\033[36m¡i ¯¸ªø±M¥ÎÁä ¡j\033[m\n\n"); + if (HAS_PERM(PERM_SYSOP)) + outs("(u)/(H) ³]©w¨Ï¥ÎªÌ¸ê®Æ/¤Á´«Áô§Î¼Ò¦¡\n"); + outs("(R)/(K) ¬d¸ß¨Ï¥ÎªÌªº¯u¹ê©m¦W/§âÃa³J½ð¥X¥h\n"); + } + pressanykey(); +} + +static int listcuent(userinfo_t * uentp) { + if((!uentp->invisible || HAS_PERM(PERM_SYSOP) || HAS_PERM(PERM_SEECLOAK))) + AddNameList(uentp->userid); + return 0; +} + +static void creat_list() { + CreateNameList(); + apply_ulist(listcuent); +} + +static int search_pickup(int num, int actor, pickup_t pklist[]) { + char genbuf[IDLEN + 2]; + + move(1, 0); + creat_list(); + namecomplete(msg_uid, genbuf); + if (genbuf[0]) + { + int n = (num + 1) % actor; + while (n != num) + { + if (!strcasecmp(pklist[n].ui->userid, genbuf)) + return n; + if (++n >= actor) + n = 0; + } + } + return -1; +} + +/* Kaede show friend description */ +static char *friend_descript(char *uident) { + static char *space_buf = " "; + static char desc_buf[80]; + char fpath[80], name[IDLEN + 2], *desc, *ptr; + int len, flag; + FILE *fp; + char genbuf[200]; + + setuserfile(fpath, friend_file[0]); + + if ((fp = fopen(fpath, "r"))) + { + sprintf(name, "%s ", uident); + len = strlen(name); + desc = genbuf + 13; + + while ((flag = (int) fgets(genbuf, STRLEN, fp))) + { + if (!memcmp(genbuf, name, len)) + { + if ((ptr = strchr(desc, '\n'))) + ptr[0] = '\0'; + if (desc) + break; + } + } + fclose(fp); + if (desc && flag) + strcpy(desc_buf, desc); + else + return space_buf; + + return desc_buf; + } + else + return space_buf; +} + +static char *descript(int show_mode, userinfo_t * uentp, time_t diff, + fromcache_t * fcache) { + switch (show_mode) + { + case 1: + return friend_descript(uentp->userid); + case 0: + return (((uentp->pager != 2 && uentp->pager != 3 && diff) || + HAS_PERM(PERM_SYSOP)) ? +#ifdef WHERE + uentp->from_alias ? fcache->replace[uentp->from_alias] : + uentp->from +#else + uentp->from +#endif + : "*"); + case 2: + sprintf(description, "%3d/%3d/%3d", uentp->five_win, + uentp->five_lose, uentp->five_tie); + description[20] = 0; + return description; + default: + syslog(LOG_WARNING, "damn!!! what's wrong?? show_mode = %d", + show_mode); + return ""; + } +} + +static int pickup_user_cmp(time_t now, int sortedway, int cmp_fri, + pickup_t pklist[], int *bfriends_number, int *ifh_number, + int *hfm_number,int *irh_number, char *keyword) +{ + int i, fri_stat, is_friend, count=0, diff; + userinfo_t *uentp; + for (i=0;i<utmpshm->number;i++) + { + uentp = (utmpshm->sorted[utmpshm->currsorted][sortedway][i]); + if (!uentp || !uentp->pid) continue; + fri_stat = friend_stat(currutmp, uentp); + if(uentp->uid==currutmp->uid) + fri_stat = fri_stat|IFH|HFM; + is_friend = (fri_stat & IRH) && !(fri_stat & IFH) ? 0 : + fri_stat & ST_FRIEND; + if (!isvisible_stat(currutmp, uentp, fri_stat) || + ((cmp_fri==1 && !is_friend) || + (cmp_fri==-1 && is_friend)) || + (keyword[0] && !strcasestr(uentp->username,keyword)) + ) continue; + if (bfriends_number && fri_stat & IBH) (*bfriends_number)++; + if (ifh_number && fri_stat & IFH) (*ifh_number)++; + if (hfm_number && fri_stat & HFM) (*hfm_number)++; + if (irh_number && fri_stat & IRH) (*irh_number)++; +#ifdef SHOW_IDLE_TIME + diff = now - uentp->lastact; +#ifdef DOTIMEOUT + /* prevent fault /dev mount from kicking out users */ + if ((diff > curr_idle_timeout + 10) && + (diff < 60 * 60 * 24 * 5)) + { + if ((uentp->pid <= 0 || kill(uentp->pid, SIGHUP) == -1) && + (errno == ESRCH)) + purge_utmp(uentp); + continue; + } +#endif + pklist[count].idle = diff; +#endif + pklist[count].friend = fri_stat; + pklist[count].ui = uentp; + count++; + } + return count; +} + +static int cmputmpfriend(const void *i, const void *j) +{ + if((((pickup_t*)j)->friend&ST_FRIEND)==(((pickup_t*)i)->friend&ST_FRIEND)) + return strcasecmp( ((pickup_t*)i)->ui->userid, + ((pickup_t*)j)->ui->userid); + else + return (((pickup_t*)j)->friend&ST_FRIEND) - + (((pickup_t*)i)->friend&ST_FRIEND); +} + +static void pickup_user() { + static int real_name = 0; + static int show_mode = 0; + static int show_uid = 0; + static int show_board = 0; + static int show_pid = 0; + static int num = 0; + char genbuf[200]; + +#ifdef WHERE + extern struct fromcache_t *fcache; +#endif + + register userinfo_t *uentp; + register pid_t pid0 = 0; /* Ptt ©w¦ì */ + register int id0 = 0; /* US_PICKUP®Éªº´å¼Ð¥Î */ + register int state = US_PICKUP, ch; + register int actor = 0, head, foot; + int fri_stat, bfriends_number, ifh_number, irh_number, hfm_number; + int savemode = currstat; + int i, sortedway; /* ¥u¬Oloop¦³¥Î¨ì */ + time_t diff, freshtime; + pickup_t pklist[USHM_SIZE]; /* parameter Pttµù */ +/* num : ²{¦bªº´å¼Ð¦ì */ +/* foot: ¦¹¶ªº¸}¸} */ + char buf[20],keyword[13]=""; /* actor:¦@¦³¦h¤Öuser */ + char pagerchar[5] = "* -Wf"; + char *msg_pickup_way[PICKUP_WAYS] = + { + "¶Ù! ªB¤Í", + "ºô¤Í¥N¸¹", + "ºô¤Í°ÊºA", + "µo§b®É¶¡", + "¨Ó¦Û¦ó¤è", + "¤¤l´Ñ ", +// "¤k¤hÀu¥ý" + }; + char *MODE_STRING[MAX_SHOW_MODE] = + { + "¬G¶m", + "¦n¤Í´yz", + "¤¤l´Ñ¾ÔÁZ" + }; + char + *Mind[] = + {" ", + "^-^", "^_^", "Q_Q", "@_@", "/_\\", "=_=", "-_-", "-.-", ">_<", + "-_+", "!_!", "o_o", "z_Z", "O_O", "O.O", "$_$", "^*^", "O_<", + "³ß!", "«ã!", "«s!", "¼Ö!", ":) ", ":( ", ":~ ", ":q ", ":O ", + ":D ", ":p ", ";) ", ":> ", ";> ", ":< ", ":)~", ":D~", ">< ", + "^^;", "^^|", "ú;", NULL}; + + while (1) + { + if (utmpshm->uptime > freshtime || state == US_PICKUP || + state ==US_RESORT) + { + state = US_PICKUP; + time(&freshtime); + ifh_number=hfm_number=irh_number=bfriends_number = actor = ch = 0; + if(pickup_way==0) + sortedway=0; + else + sortedway=pickup_way-1; + + //qsort(pklist,actor,sizeof(pickup_t),cmputmpfriend); + if(pickup_way==0 || (cuser.uflag & FRIEND_FLAG)) + { + actor=pickup_user_cmp(freshtime, sortedway, 1, + pklist, &bfriends_number, &ifh_number, &hfm_number, + NULL,keyword); + if(sortedway==0) + qsort(pklist,actor,sizeof(pickup_t),cmputmpfriend); + if(!(cuser.uflag & FRIEND_FLAG)) + actor=pickup_user_cmp(freshtime, sortedway, -1, + pklist+actor, NULL, NULL, NULL, &irh_number, + keyword); + } + else + { + actor=pickup_user_cmp(freshtime, sortedway, 0, + pklist, &bfriends_number, &ifh_number, &hfm_number, + &irh_number, keyword); + } + + + if (!actor) + { + if(keyword[0]) + { + mprints(b_lines-1,0, + "·j´M¤£¨ì¥ô¦ó¤H !!"); + keyword[0]=0; + pressanykey(); + continue; + } + getdata(b_lines - 1, 0, + "§AªºªB¤ÍÁÙ¨S¤W¯¸¡An¬Ý¬Ý¤@¯ëºô¤Í¶Ü(Y/N)¡H[Y]", + genbuf, 4, LCECHO); + if (genbuf[0] != 'n') + { + cuser.uflag &= ~FRIEND_FLAG; + continue; + } + return; + } + } + if (state >= US_ACTION) + { + showtitle((cuser.uflag & FRIEND_FLAG) ? "¦n¤Í¦Cªí" : "¥ð¶¢²á¤Ñ", + BBSName); + prints(" ±Æ§Ç¡G[%s] ¤W¯¸¤H¼Æ¡G%-4d\033[1;32m§ÚªºªB¤Í¡G%-3d" + "\033[33m»P§Ú¬°¤Í¡G%-3d\033[36mªO¤Í¡G%-4d\033[31mÃa¤H¡G" + "%-2d\033[m\n" + "\033[7m %s P%c¥N¸¹ %-17s%-17s%-13s%-10s\033[m\n", + msg_pickup_way[pickup_way], actor, ifh_number, + hfm_number, bfriends_number, irh_number, + show_uid ? "UID" : "No.", + (HAS_PERM(PERM_SEECLOAK) || HAS_PERM(PERM_SYSOP)) ? 'C' : ' ', + real_name ? "©m¦W" : "¼ÊºÙ", + MODE_STRING[show_mode], + show_board ? "Board" : "°ÊºA", + show_pid ? " PID" : "³Æµù µo§b" + ); + } + else + { + move(3, 0); + clrtobot(); + } + if (pid0) + for (ch = 0; ch < actor; ch++) + { + if (pid0 == (pklist[ch].ui)->pid && + id0 == 256 * pklist[ch].ui->userid[0] + + pklist[ch].ui->userid[1]) + { + num = ch; + } + } + if (num < 0) + num = 0; + else if (num >= actor) + num = actor - 1; + head = (num / p_lines) * p_lines; + foot = head + p_lines; + if (foot > actor) + foot = actor; + for (ch = head; ch < foot; ch++) + { + uentp = pklist[ch].ui; + + if (!uentp->pid) + { + prints("%5d < Â÷¯¸¤¤..>\n",ch); + continue; + } +#ifdef SHOW_IDLE_TIME + diff = pklist[ch].idle; + if (diff > 59990) diff = 59990; /* Doma: ¥H§K¤@¤j¦êªºµo§b®É¶¡ */ + if (diff > 0) + sprintf(buf, "%3ld'%02ld", diff / 60, diff % 60); + else + buf[0] = '\0'; +#else + buf[0] = '\0'; +#endif + i = pklist[ch].friend; +#ifdef SHOWPID + if (show_pid) + sprintf(buf, "%6d", uentp->pid); +#endif + if (PERM_HIDE(uentp)) + state = 9; + else if(currutmp == uentp) + state =10; + else if(i & IRH && !(i & IFH)) + state = 8; + else + state =(i&ST_FRIEND)>>2; + diff = uentp->pager & !(i&HRM); + prints("%5d %c%c%s%-13s%-17.16s\033[m%-17.16s%-13.13s" + "\33[33m%-4.4s\33[m%s\n", +#ifdef SHOWUID + show_uid ? uentp->uid : +#endif + (ch + 1), + (i & HRM) ? 'X' : + pagerchar[uentp->pager % 5], + (uentp->invisible ? ')' : ' '), + fcolor[state], + /* %s */ + uentp->userid, + + /* %-13s ¼ÊºÙ */ +#ifdef REALINFO + real_name ? uentp->realname : +#endif + uentp->username, + /* %-17.16s ¬G¶m */ + descript(show_mode, uentp, diff, fcache), + + /* %-17.16s ¬ÝªO */ +#ifdef SHOWBOARD + show_board ? (uentp->brc_id == 0 ? "" : + bcache[uentp->brc_id - 1].brdname) : +#endif + /* %-13.13s */ + modestring(uentp, 0), + /* %4s ³Æµù */ + ((uentp->userlevel & PERM_VIOLATELAW) ? "³q½r" : + (uentp->birth ? "¹Ø¬P" : + Mind[uentp->mind])), + /* %s µo§b */ + buf); + } + if (state == US_PICKUP) + continue; + + move(b_lines, 0); + outs("\033[31;47m(TAB/f)\033[30m±Æ§Ç/¦n¤Í \033[31m(t)\033[30m²á¤Ñ " + "\033[31m(a/d/o)\033[30m¥æ¤Í \033[31m(q)\033[30m¬d¸ß " + "\033[31m(w)\033[30m¤ô²y \033[31m(m)\033[30m±H«H \033[31m(h)" + "\033[30m½u¤W»²§U \033[m"); + state = 0; + while (!state) + { + ch = cursor_key(num + 3 - head, 0); + if (ch == KEY_RIGHT || ch == '\n' || ch == '\r') + ch = 't'; + + switch (ch) + { + case KEY_LEFT: + case 'e': + case 'E': + if(!keyword[0]) return; + keyword[0]=0; + state = US_PICKUP; + break; + + case KEY_TAB: + pickup_way = (pickup_way + 1) % PICKUP_WAYS; + state = US_RESORT; + num = 0; + break; + + case KEY_DOWN: + case 'n': + case 'j': + if (++num < actor) + { + if (num >= foot) + state = US_REDRAW; + break; + } + case '0': + case KEY_HOME: + num = 0; + if (head) + state = US_REDRAW; + break; + case 'H': + if (HAS_PERM(PERM_SYSOP)) + { + currutmp->userlevel ^= PERM_DENYPOST; + state = US_REDRAW; + } + break; + case 'D': + if (HAS_PERM(PERM_SYSOP)) + { + char buf[100]; + + sprintf(buf, "¥N¸¹ [%s]¡G", currutmp->userid); + if (!getdata(1, 0, buf, currutmp->userid, IDLEN + 1, + DOECHO)) + strcpy(currutmp->userid, cuser.userid); + state = US_REDRAW; + } + break; + case 'F': + if (HAS_PERM(PERM_SYSOP)) + { + char buf[100]; + + sprintf(buf, "¬G¶m [%s]¡G", currutmp->from); + if (!getdata(1, 0, buf, currutmp->from, 17, DOECHO)) + strncpy(currutmp->from, fromhost, 23); + state = US_REDRAW; + } + break; + case 'C': +#if !HAVE_FREECLOAK + if (HAS_PERM(PERM_CLOAK)) +#endif + { + currutmp->invisible ^= 1; + state = US_REDRAW; + } + break; + case ' ': + case KEY_PGDN: + case Ctrl('F'): + if (foot < actor) + { + num += p_lines; + state = US_REDRAW; + break; + } + if (head) + num = 0; + state = US_PICKUP; + break; + case KEY_UP: + case 'k': + if (--num < head) + { + if (num < 0) + { + num = actor - 1; + if (actor == foot) + break; + } + state = US_REDRAW; + } + break; + case KEY_PGUP: + case Ctrl('B'): + case 'P': + if (head) + { + num -= p_lines; + state = US_REDRAW; + break; + } + + case KEY_END: + case '$': + num = actor - 1; + if (foot < actor) + state = US_REDRAW; + break; + + case '/': + getdata_buf(b_lines-1,0,"½Ð¿é¤J¼ÊºÙÃöÁä¦r:",keyword, 12, + DOECHO); + state = US_PICKUP; + break; + case 's': + 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, actor - 1)) >= 0) + num = tmp; + state = US_REDRAW; + } + break; +#ifdef REALINFO + case 'R': /* Åã¥Ü¯u¹ê©m¦W */ + if (HAS_PERM(PERM_SYSOP)) + real_name ^= 1; + state = US_PICKUP; + break; +#endif +#ifdef SHOWUID + case 'U': + if (HAS_PERM(PERM_SYSOP)) + show_uid ^= 1; + state = US_PICKUP; + break; +#endif +#ifdef SHOWBOARD + case 'Y': + if (HAS_PERM(PERM_SYSOP)) + show_board ^= 1; + state = US_PICKUP; + break; +#endif +#ifdef SHOWPID + case '#': + if (HAS_PERM(PERM_SYSOP)) + show_pid ^= 1; + state = US_PICKUP; + break; +#endif + + case 'b': /* broadcast */ + if (cuser.uflag & FRIEND_FLAG || HAS_PERM(PERM_SYSOP)) + { + int actor_pos = actor; + char ans[4]; + + state = US_PICKUP; + if (!getdata(0, 0, "¼s¼½°T®§:", genbuf, 60, DOECHO)) + break; + if (getdata(0, 0, "½T©w¼s¼½? [Y]", ans, 4, LCECHO) && + *ans == 'n') + break; + while (actor_pos) + { + uentp = pklist[--actor_pos].ui; + fri_stat = pklist[actor_pos].friend; + if (uentp->pid && + currpid != uentp->pid && + uentp->pid > 0 && kill(uentp->pid, 0) != -1 && + (HAS_PERM(PERM_SYSOP) || + (uentp->pager != 3 && + (uentp->pager != 4 || fri_stat & HFM)))) + my_write(uentp->pid, genbuf, uentp->userid, HAS_PERM(PERM_SYSOP) ? 3 : 1); + } + } + break; + case 'S': /* Åã¥Ü¦n¤Í´yz */ + show_mode = (++show_mode) % MAX_SHOW_MODE; + state = US_PICKUP; + break; + case 'u': /* ½u¤Wקï¸ê®Æ */ + case 'K': /* §âÃa³J½ð¥X¥h */ + if (!HAS_PERM(PERM_ACCOUNTS)) + continue; + state = US_ACTION; + break; + case 'i': + state = US_ACTION; + break; + case Ctrl('S'): + state = US_ACTION; + break; + case 't': + case 'w': + if (!(cuser.userlevel & PERM_LOGINOK)) + continue; + state = US_ACTION; + break; + case 'a': + case 'd': + case 'o': + case 'f': + case 'g': + if (!HAS_PERM(PERM_LOGINOK)) + /* µù¥U¤~¦³ Friend */ + break; + if (ch == 'f') + { + cuser.uflag ^= FRIEND_FLAG; + state = US_PICKUP; + break; + } + state = US_ACTION; + break; + case 'q': + case 'c': + case 'm': + case 'r': + case 'l': + /* guest ¥u¯à query */ + if (!cuser.userlevel && ch != 'q' && ch != 'l') + break; + case 'h': + state = US_ACTION; + break; + case 'p': + if (HAS_PERM(PERM_BASIC)) + { + t_pager(); + state = US_REDRAW; + } + break; + case 'W': + { + int tmp; + char *wm[3] = {"¤@¯ë", "¶i¶¥", "¥¼¨Ó"}; + tmp = cuser.uflag2 & WATER_MASK; + cuser.uflag2 -= tmp; + tmp = (tmp + 1) % 3; + cuser.uflag2 |= tmp; + prints("¤Á´«¨ì %s ¤ô²y¼Ò¦¡", wm[tmp]); + refresh(); + sleep(1); + state = US_REDRAW; + } + default: /* refresh screen */ + state = US_REDRAW; + } + } + + if (state != US_ACTION) + { + pid0 = 0; + continue; + } + + /* Ptt decide cur */ + uentp = pklist[num].ui; + fri_stat = friend_stat(currutmp, uentp); + pid0 = uentp->pid; + id0 = 256 * uentp->userid[0] + uentp->userid[1]; + + if (ch == 'w') + { + if ((uentp->pid != currpid) && + (HAS_PERM(PERM_SYSOP) || + (uentp->pager != 3 && + (fri_stat & HFM || uentp->pager != 4)))) + { + cursor_show(num + 3 - head, 0); + sprintf(genbuf, "Call-In %s ¡G", uentp->userid); + my_write(uentp->pid, genbuf, uentp->userid, 0); + } + } + else if (ch == 'l') + { /* Thor: ¬Ý Last call in */ + t_display(); + } + else + { + switch (ch) + { + case 'r': + m_read(); + break; + case 'g': /* give money */ + move(b_lines - 2, 0); + if (strcmp(uentp->userid, cuser.userid)) + { + sprintf(genbuf, "nµ¹ %s ¦h¤Ö¿ú©O? ", uentp->userid); + outs(genbuf); + if (getdata(b_lines - 1, 0, "[»È¦æÂà±b]:", genbuf, 7, + LCECHO)) + { + clrtoeol(); + if ((ch = atoi(genbuf)) <= 0) + break; + reload_money(); + if (ch > cuser.money) + outs("\033[41m ²{ª÷¤£¨¬~~\033[m"); + else + { + deumoney(uentp->uid, ch); + sprintf(genbuf, "\033[44m ¶â..ÁٳѤU %d ¿ú.." + "\033[m", demoney(-1*ch)); + outs(genbuf); + sprintf(genbuf, "%s\tµ¹%s\t%d\t%s", cuser.userid, + uentp->userid, ch, + ctime(&currutmp->lastact)); + log_file(FN_MONEY, genbuf); + mail_redenvelop(cuser.userid, uentp->userid, ch, 'Y'); + } + } + else + { + clrtoeol(); + outs("\033[41m ¥æ©ö¨ú®ø! \033[m"); + } + } + else + outs("\033[33m ¦Û¤vµ¹¦Û¤v? A²Â..\033[m"); + refresh(); + sleep(1); + break; +#ifdef SHOWMIND + case 'i': + move(3,0); + clrtobot(); + for (i = 1; Mind[i]!=NULL; i++) + { + move(5+(i-1)/7,((i-1)%7)*10); + prints("%2d: %s",i,Mind[i]); + } + getdata(b_lines - 1, 0, "§A²{¦bªº¤ß±¡ 0:µL q¤£ÅÜ [q]:", + genbuf, 3, LCECHO); + if (genbuf[0] && genbuf[0] != 'q') + currutmp->mind=atoi(genbuf)%i; + state = US_REDRAW; + break; +#endif + case 'a': + friend_add(uentp->userid, FRIEND_OVERRIDE); + friend_load(); + state = US_PICKUP; + break; + case 'd': + friend_delete(uentp->userid, FRIEND_OVERRIDE); + friend_load(); + state = US_PICKUP; + break; + case 'o': + t_override(); + state = US_PICKUP; + break; + case 'K': + if (uentp->pid > 0 && kill(uentp->pid, 0) != -1) + { + move(1, 0); + clrtobot(); + move(2, 0); + my_kick(uentp); + state = US_PICKUP; + } + break; + case 'm': + stand_title("±H «H"); + prints("[±H«H] ¦¬«H¤H¡G%s", uentp->userid); + my_send(uentp->userid); + break; + case 'q': + strcpy(currauthor, uentp->userid); + my_query(uentp->userid); + break; + case 'c': + chicken_query(uentp->userid); + break; + case 'u': /* Thor: ¥i½u¤W¬d¬Ý¤Îקï¨Ï¥ÎªÌ */ + { + int id; + userec_t muser; + + strcpy(currauthor, uentp->userid); + stand_title("¨Ï¥ÎªÌ³]©w"); + move(1, 0); + if ((id = getuser(uentp->userid))) + { + memcpy(&muser, &xuser, sizeof(muser)); + user_display(&muser, 1); + uinfo_query(&muser, 1, id); + } + } + break; + + case 'h': /* Thor: ¬Ý Help */ + t_showhelp(); + break; + + case 't': + if (uentp->pid != currpid && + (strcmp(uentp->userid, cuser.userid))) + { + move(1, 0); + clrtobot(); + move(3, 0); + my_talk(uentp, fri_stat); + state = US_PICKUP; + } + break; + } + } + setutmpmode(savemode); + } +} + +int t_users() { + int destuid0 = currutmp->destuid; + int mode0 = currutmp->mode; + int stat0 = currstat; + + setutmpmode(LUSERS); + pickup_user(); + currutmp->mode = mode0; + currutmp->destuid = destuid0; + currstat = stat0; + return 0; +} + +int t_pager() { + currutmp->pager = (currutmp->pager + 1) % 5; + return 0; +} + +int t_idle() { + int destuid0 = currutmp->destuid; + int mode0 = currutmp->mode; + int stat0 = currstat; + char genbuf[20]; + char buf[80], passbuf[PASSLEN]; + + 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') + currutmp->destuid = genbuf[0] - '0'; + else + currutmp->destuid = 0; + + if (currutmp->destuid == 6) + if (!cuser.userlevel || + !getdata(b_lines - 1, 0, "µo§bªº²z¥Ñ¡G", currutmp->chatid, 11, + DOECHO)) + currutmp->destuid = 0; + do + { + move(b_lines - 2, 0); + clrtoeol(); + sprintf(buf, "(Âê©w¿Ã¹õ)µo§bì¦]: %s", (currutmp->destuid != 6) ? + IdleTypeTable[currutmp->destuid] : currutmp->chatid); + outs(buf); + refresh(); + getdata(b_lines - 1, 0, MSG_PASSWD, passbuf, PASSLEN, 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() { + char uident[STRLEN]; + + stand_title("¬d¸ßÃdª«"); + usercomplete(msg_uid, uident); + if (uident[0]) + chicken_query(uident); + return 0; +} + +int t_query() { + char uident[STRLEN]; + + stand_title("¬d¸ßºô¤Í"); + usercomplete(msg_uid, uident); + if (uident[0]) + my_query(uident); + return 0; +} + +int t_talk() { + 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"); + creat_list(); + namecomplete(msg_uid, uident); + if (uident[0] == '\0') + return 0; + + move(3, 0); + if (!(tuid = searchuser(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)); + + return 0; +} + +/* ¦³¤H¨Ó¦êªù¤l¤F¡A¦^À³©I¥s¾¹ */ +static userinfo_t *uip; +void talkreply() { + struct hostent *h; + char buf[4]; + struct sockaddr_in sin; + char genbuf[200]; + int a, sig = currutmp->sig; + + talkrequest = NA; + uip = &utmpshm->uinfo[currutmp->destuip]; + sprintf(page_requestor, "%s (%s)", uip->userid, uip->username); + currutmp->destuid = uip->uid; + currstat = XMODE; /* ÁקK¥X²{°Êµe */ + + clear(); + + prints("\n\n"); + 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) \033[1;33m§Ú¦Û¤v¿é¤J²z¥Ñ¦n¤F...\033[m\n"); + prints(" (1) %s¡H¥ý®³100»È¨â¨Ó" + " (2) %s¡H¥ý®³1000»È¨â¨Ó..\n\n", sig_des[sig], sig_des[sig]); + + getuser(uip->userid); + currutmp->msgs[0].pid = uip->pid; + strcpy(currutmp->msgs[0].userid, uip->userid); + strcpy(currutmp->msgs[0].last_call_in, "©I¥s¡B©I¥s¡AÅ¥¨ì½Ð¦^µª (Ctrl-R)"); + prints("¹ï¤è¨Ó¦Û [%s]¡A¦@¤W¯¸ %d ¦¸¡A¤å³¹ %d ½g\n", + uip->from, xuser.numlogins, xuser.numposts); + showplans(uip->userid); + show_last_call_in(0); + + sprintf(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, 4, LCECHO); + + if (uip->mode != PAGE) + { + sprintf(genbuf, "%s¤w°±¤î©I¥s¡A«öEnterÄ~Äò...", page_requestor); + getdata(0, 0, genbuf, buf, 4, LCECHO); + return; + } + currutmp->msgcount = 0; + strcpy(save_page_requestor, page_requestor); + memset(page_requestor, 0, sizeof(page_requestor)); + if (!(h = gethostbyname("localhost"))) + { + perror("gethostbyname"); + return; + } + memset(&sin, 0, sizeof(sin)); + sin.sin_family = h->h_addrtype; + memcpy(&sin.sin_addr, h->h_addr, h->h_length); + sin.sin_port = uip->sockaddr; + a = socket(sin.sin_family, SOCK_STREAM, 0); + if ((connect(a, (struct sockaddr *) &sin, sizeof(sin)))) + { + perror("connect err"); + return; + } + if (!buf[0] || !strchr("yabcdef12", buf[0])) + buf[0] = 'n'; + write(a, buf, 1); + if (buf[0] == 'f' || buf[0] == 'F') + { + if (!getdata(b_lines, 0, "¤£¯àªºì¦]¡G", genbuf, 60, DOECHO)) + strcpy(genbuf, "¤£§i¶D§A«¨ !! ^o^"); + write(a, genbuf, 60); + } + uip->destuip = currutmp - &utmpshm->uinfo[0]; + if (buf[0] == 'y') + switch (sig) + { + case SIG_DARK: + main_dark(a, uip); + break; + case SIG_PK: + chickenpk(a); + break; + case SIG_GOMO: + gomoku(a); + break; + case SIG_CHC: + chc(a); + break; + case SIG_TALK: + default: + do_talk(a); + } + else + close(a); + clear(); +} + +/* ºô¤Í°ÊºA²ªí */ +/* not used +static int shortulist(userinfo_t * uentp) { + static int lineno, fullactive, linecnt; + static int moreactive, page, num; + char uentry[50]; + int state; + + if (!lineno) + { + lineno = 3; + page = moreactive ? (page + p_lines * 3) : 0; + linecnt = num = moreactive = 0; + move(1, 70); + prints("Page: %d", page / (p_lines) / 3 + 1); + move(lineno, 0); + } + + if (uentp == NULL) + { + int finaltally; + + clrtoeol(); + move(++lineno, 0); + clrtobot(); + finaltally = fullactive; + lineno = fullactive = 0; + return finaltally; + } + if ((!HAS_PERM(PERM_SYSOP) && + !HAS_PERM(PERM_SEECLOAK) && + uentp->invisible) || + ((friend_stat(currutmp, uentp) & HRM) && + !HAS_PERM(PERM_SYSOP))) + { + if (lineno >= b_lines) + return 0; + if (num++ < page) + return 0; + memset(uentry, ' ', 25); + uentry[25] = '\0'; + } + else + { + fullactive++; + if (lineno >= b_lines) + { + moreactive = 1; + return 0; + } + if (num++ < page) + return 0; + + state = (currutmp == uentp) ? 10 : + (friend_stat(currutmp,uentp)&ST_FRIEND)>>2; + + if (PERM_HIDE(uentp)) + state = 9; + + sprintf(uentry, "%s%-13s%c%-10s%s ", fcolor[state], + uentp->userid, uentp->invisible ? '#' : ' ', + modestring(uentp, 1), state ? "\033[0m" : ""); + } + if (++linecnt < 3) + { + strcat(uentry, "¢x"); + outs(uentry); + } + else + { + outs(uentry); + linecnt = 0; + clrtoeol(); + move(++lineno, 0); + } + return 0; +} +*/ diff --git a/mbbsd/term.c b/mbbsd/term.c new file mode 100644 index 00000000..61a0128d --- /dev/null +++ b/mbbsd/term.c @@ -0,0 +1,144 @@ +/* $Id: term.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <termios.h> +#include <string.h> +#include <syslog.h> +#include <signal.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "proto.h" + +int tgetent(const char *bp, char *name); +char *tgetstr(const char *id, char **area); +int tgetflag(const char *id); +int tgetnum(const char *id); +int tputs(const char *str, int affcnt, int (*putc)(int)); +char *tparm(const char *str, ...); +char *tgoto(const char *cap, int col, int row); + +static struct termios tty_state, tty_new; + +/* ----------------------------------------------------- */ +/* basic tty control */ +/* ----------------------------------------------------- */ +void init_tty() { + 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) + +char *clearbuf = "\33[H\33[J"; +int clearbuflen = 6; + +char *cleolbuf = "\33[K"; +int cleolbuflen = 3; + +char *scrollrev = "\33M"; +int scrollrevlen = 2; + +char *strtstandout = "\33[7m"; +int strtstandoutlen = 4; + +char *endstandout = "\33[m"; +int endstandoutlen = 3; + +int t_lines = 24; +int b_lines = 23; +int p_lines = 20; +int t_columns = 80; + +int automargins = 1; + +static char *outp; +static int *outlp; + + +static int outcf(int ch) { + if(*outlp < TERMCOMSIZE) { + (*outlp)++; + *outp++ = ch; + } + return 0; +} + +extern screenline_t *big_picture; + +static void term_resize(int sig) { + struct winsize newsize; + screenline_t *new_picture; + + signal(SIGWINCH, SIG_IGN); /* Don't bother me! */ + ioctl(0, TIOCGWINSZ, &newsize); + if(newsize.ws_row > t_lines) { + new_picture = (screenline_t *)calloc(newsize.ws_row, + sizeof(screenline_t)); + if(new_picture == NULL) { + syslog(LOG_ERR, "calloc(): %m"); + return; + } + free(big_picture); + big_picture = new_picture; + } + + t_lines=newsize.ws_row; + b_lines=t_lines-1; + p_lines=t_lines-4; + + signal(SIGWINCH, term_resize); +} + +int term_init() { + signal(SIGWINCH, term_resize); + return YEA; +} + +char term_buf[32]; + +void do_move(int destcol, int destline) { + char buf[16], *p; + + sprintf(buf, "\33[%d;%dH", destline + 1, destcol + 1); + for(p = buf; *p; p++) + ochar(*p); +} + +void save_cursor() { + ochar('\33'); + ochar('7'); +} + +void restore_cursor() { + ochar('\33'); + ochar('8'); +} + +void change_scroll_range(int top, int bottom) { + char buf[16], *p; + + sprintf(buf, "\33[%d;%dr", top + 1, bottom + 1); + for(p = buf; *p; p++) + ochar(*p); +} + +void scroll_forward() { + ochar('\33'); + ochar('D'); +} diff --git a/mbbsd/toolkit.c b/mbbsd/toolkit.c new file mode 100644 index 00000000..81a0d6f0 --- /dev/null +++ b/mbbsd/toolkit.c @@ -0,0 +1,14 @@ +/* $Id: toolkit.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <ctype.h> +#include <sys/types.h> +#include "config.h" +#include "pttstruct.h" + +unsigned StringHash(unsigned char *s) { + unsigned int v=0; + while(*s) { + v = (v << 8) | (v >> 24); + v ^= toupper(*s++); /* note this is case insensitive */ + } + return (v * 2654435769UL) >> (32 - HASH_BITS); +} diff --git a/mbbsd/topsong.c b/mbbsd/topsong.c new file mode 100644 index 00000000..d3a65447 --- /dev/null +++ b/mbbsd/topsong.c @@ -0,0 +1,79 @@ +/* $Id: topsong.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <sys/types.h> +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "proto.h" + +#define MAX_SONGS 300 +#define QCAST int (*)(const void *, const void *) + +typedef struct songcmp_t { + char name[100]; + char cname[100]; + long int count; +} songcmp_t; + +static long int totalcount=0; + +static int count_cmp(songcmp_t *b, songcmp_t *a) { + return (a->count - b->count); +} + +int topsong() { + more(FN_TOPSONG,YEA); + return 0; +} + +static int strip_blank(char *cbuf, char *buf) { + for(; *buf; buf++) + if(*buf != ' ') + *cbuf++ = *buf; + *cbuf = 0; + return 0; +} + +void sortsong() { + 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; + while(fgets(buf, 200, fp)) { + strtok(buf, "\n\r"); + strip_blank(cbuf, buf); + if(!cbuf[0] || !isprint2(cbuf[0])) + continue; + + for(n = 0; n < MAX_SONGS && songs[n].name[0]; n++) + if(!strcmp(songs[n].cname,cbuf)) + break; + strcpy(songs[n].name, buf); + strcpy(songs[n].cname, cbuf); + songs[n].count++; + totalcount++; + } + qsort(songs, MAX_SONGS, sizeof(songcmp_t), (QCAST)count_cmp); + fprintf(fo, + " \033[36m¢w¢w\033[37m¦W¦¸\033[36m¢w¢w¢w¢w¢w¢w\033[37mºq" + " ¦W\033[36m¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w\033[37m¦¸¼Æ\033[36m" + "¢w¢w\033[32m¦@%ld¦¸\033[36m¢w¢w\033[m\n", totalcount); + for(n = 0; n < 100 && songs[n].name[0]; n++) { + fprintf(fo, " %5d. %-38.38s %4ld \033[32m[%.2f]\033[m\n", n + 1, + songs[n].name, songs[n].count, + (float)songs[n].count/totalcount); + } + fclose(fp); + fclose(fo); +} diff --git a/mbbsd/uptime b/mbbsd/uptime new file mode 100644 index 00000000..4f8281fb --- /dev/null +++ b/mbbsd/uptime @@ -0,0 +1,23 @@ +cache.c: if(fcache->busystate) +cache.c: fcache->busystate = 1; +cache.c: bzero(fcache->domain, sizeof fcache->domain); +cache.c: fcache->top=0; +cache.c: sscanf(buf,"%s",fcache->domain[fcache->top]); +cache.c: po = buf + strlen(fcache->domain[fcache->top]); +cache.c: strncpy(fcache->replace[fcache->top],po,49); +cache.c: fcache->replace[fcache->top] +cache.c: [strlen(fcache->replace[fcache->top])-1] = 0; +cache.c: (fcache->top)++; +cache.c: if(fcache->top == MAX_FROM) +cache.c: fcache->max_user=0; +cache.c: fcache->uptime = fcache->touchtime; +cache.c: fcache->busystate = 0; +cache.c: if(fcache->touchtime == 0) +cache.c: fcache->touchtime = 1; +cache.c: while(fcache->uptime < fcache->touchtime) +mbbsd.c: for (j = 0; j < fcache->top; j++){ +mbbsd.c: char *token = strtok (fcache->domain[j], "&"); +mbbsd.c: if ((a = utmpshm->number) > fcache->max_user){ +mbbsd.c: fcache->max_user = a; +mbbsd.c: fcache->max_time = now; +talk.c: uentp->from_alias ? fcache->replace[uentp->from_alias] : diff --git a/mbbsd/user.c b/mbbsd/user.c new file mode 100644 index 00000000..41aacfa9 --- /dev/null +++ b/mbbsd/user.c @@ -0,0 +1,980 @@ +/* $Id: user.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> +#include <ctype.h> +#include <sys/types.h> +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "perm.h" +#include "modes.h" +#include "proto.h" + +extern int numboards; +extern boardheader_t *bcache; +extern char *loginview_file[NUMVIEWFILE][2]; +extern int b_lines; /* Screen bottom line number: t_lines-1 */ +extern time_t login_start_time; +extern char *msg_uid; +extern int usernum; +extern char *msg_sure_ny; +extern userinfo_t *currutmp; +extern int showansi; +extern char reset_color[]; +extern char *fn_proverb; +extern char *fn_plans; +extern char *msg_del_ok; +extern char *fn_register; +extern char *msg_nobody; +extern userec_t cuser; +extern userec_t xuser; + +static char *sex[8] = { + MSG_BIG_BOY, MSG_BIG_GIRL, MSG_LITTLE_BOY, MSG_LITTLE_GIRL, + MSG_MAN, MSG_WOMAN, MSG_PLANT, MSG_MIME +}; + +int u_loginview() { + int i; + unsigned int pbits = cuser.loginview; + char choice[5]; + + clear(); + move(4,0); + for(i = 0; i < NUMVIEWFILE ; i++) + prints(" %c. %-20s %-15s \n", 'A' + i, + loginview_file[i][1],((pbits >> i) & 1 ? "£¾" : "¢æ")); + + clrtobot(); + while(getdata(b_lines - 1, 0, "½Ð«ö [A-N] ¤Á´«³]©w¡A«ö [Return] µ²§ô¡G", + choice, 3, LCECHO)) { + i = choice[0] - 'a'; + if(i >= NUMVIEWFILE || i < 0) + bell(); + else { + pbits ^= (1 << i); + move( i + 4 , 28 ); + prints((pbits >> i) & 1 ? "£¾" : "¢æ"); + } + } + + if(pbits != cuser.loginview) { + cuser.loginview = pbits ; + passwd_update(usernum, &cuser); + } + return 0; +} + +void user_display(userec_t *u, int real) { + int diff = 0; + char genbuf[200]; + + clrtobot(); + prints( + " \033[30;41m¢r¢s¢r¢s¢r¢s\033[m \033[1;30;45m ¨Ï ¥Î ªÌ" + " ¸ê ®Æ " + " \033[m \033[30;41m¢r¢s¢r¢s¢r¢s\033[m\n"); + prints(" ¥N¸¹¼ÊºÙ: %s(%s)\n" + " ¯u¹ê©m¦W: %s\n" + " ©~¦í¦í§}: %s\n" + " ¹q¤l«H½c: %s\n" + " ©Ê §O: %s\n" + " »È¦æ±b¤á: %ld »È¨â\n", + u->userid, u->username, u->realname, 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" + " ¨¤ÀÃÒ¸¹: %s\n" + " ¤â¾÷¸¹½X: %010d\n" + " ¥Í ¤é: %02i/%02i/%02i\n" + " ¤pÂû¦W¦r: %s\n", + get_num_records(genbuf, sizeof(fileheader_t)), + u->exmailbox, u->ident, u->mobile, + u->month, u->day, u->year % 100, u->mychicken.name); + prints(" µù¥U¤é´Á: %s", ctime(&u->firstlogin)); + prints(" «e¦¸¥úÁ{: %s", ctime(&u->lastlogin)); + prints(" «e¦¸ÂIºq: %s", ctime(&u->lastsong)); + prints(" ¤W¯¸¤å³¹: %d ¦¸ / %d ½g\n", + u->numlogins, u->numposts); + + if(real) { + 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 = (time(0) - login_start_time) / 60; + prints(" °±¯d´Á¶¡: %d ¤p®É %2d ¤À\n", + diff / 60, diff % 60); + } + + /* Thor: ·Q¬Ý¬Ý³oÓ user ¬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(" \033[30;41m¢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\033[m"); + + outs((u->userlevel & PERM_LOGINOK) ? + "\n±zªºµù¥Uµ{§Ç¤w¸g§¹¦¨¡AÅwªï¥[¤J¥»¯¸" : + "\n¦pªGn´£ª@Åv¡A½Ð°Ñ¦Ò¥»¯¸¤½§GÄæ¿ì²zµù¥U"); + +#ifdef NEWUSER_LIMIT + if((u->lastlogin - u->firstlogin < 3 * 86400) && !HAS_PERM(PERM_POST)) + outs("\n·s¤â¤W¸ô¡A¤T¤Ñ«á¶}©ñÅv"); +#endif +} + +void mail_violatelaw(char* crime, char* police, char* reason, char* result){ + char genbuf[200]; + fileheader_t fhdr; + time_t now; + FILE *fp; + sprintf(genbuf, "home/%c/%s", crime[0], crime); + stampfile(genbuf, &fhdr); + if(!(fp = fopen(genbuf,"w"))) + return; + now = time(NULL); + fprintf(fp, "§@ªÌ: [Pttªk°|]\n" + "¼ÐÃD: [³ø§i] ¹Hªk§P¨M³ø§i\n" + "®É¶¡: %s\n" + "\033[1;32m%s\033[m§P¨M¡G\n \033[1;32m%s\033[m" + "¦]\033[1;35m%s\033[m¦æ¬°¡A\n¹H¤Ï¥»¯¸¯¸³W¡A³B¥H\033[1;35m%s\033[m¡A¯S¦¹³qª¾" + "\n½Ð¨ì PttLaw ¬d¸ß¬ÛÃöªk³W¸ê°T¡A¨Ã¨ì Play-Pay-ViolateLaw ú¥æ»@³æ", + ctime(&now), police, crime, reason, result); + fclose(fp); + sprintf(fhdr.title, "[³ø§i] ¹Hªk§P¨M³ø§i"); + strcpy(fhdr.owner, "[Pttªk°|]"); + sprintf(genbuf, "home/%c/%s/.DIR", crime[0], crime); + append_record(genbuf, &fhdr, sizeof(fhdr)); +} + +static void violate_law(userec_t *u, int unum){ + char ans[4], ans2[4]; + char reason[128]; + move(1,0); + clrtobot(); + move(2,0); + prints("(1)Cross-post (2)¶Ãµo¼s§i«H (3)¶Ãµo³sÂê«H\n"); + prints("(4)ÄÌÂZ¯¸¤W¨Ï¥ÎªÌ (8)¨ä¥L¥H»@³æ³B¸m¦æ¬°\n(9)¬å id ¦æ¬°\n"); + getdata(5, 0, "(0)µ²§ô", + ans, 3, DOECHO); + switch(ans[0]){ + case '1': + sprintf(reason, "%s", "Cross-post"); + break; + case '2': + sprintf(reason, "%s", "¶Ãµo¼s§i«H"); + break; + case '3': + sprintf(reason, "%s", "¶Ãµ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'){ + char src[STRLEN], dst[STRLEN]; + sprintf(src, "home/%c/%s", u->userid[0], u->userid); + sprintf(dst, "tmp/%s", u->userid); + Rename(src, dst); + log_usies("KILL", u->userid); + post_violatelaw(u->userid, cuser.userid, reason, "¬å°£ ID"); + u->userid[0] = '\0'; + setuserid(unum, u->userid); + passwd_update(unum, u); + } + else{ + u->userlevel |= PERM_VIOLATELAW; + u->vl_count ++; + passwd_update(unum, u); + post_violatelaw(u->userid, cuser.userid, reason, "»@³æ³B¥÷"); + mail_violatelaw(u->userid, cuser.userid, reason, "»@³æ³B¥÷"); + } + pressanykey(); +} + +extern char* str_permid[]; + +void uinfo_query(userec_t *u, int real, int unum) { + userec_t x; + register int i = 0, fail, mail_changed; + char ans[4], buf[STRLEN], *p; + char genbuf[200], reason[50]; + unsigned long int money = 0; + fileheader_t fhdr; + int flag = 0, temp = 0, money_change = 0; + time_t now; + + FILE *fp; + + fail = mail_changed = 0; + + memcpy(&x, u, sizeof(userec_t)); + getdata(b_lines - 1, 0, real ? + "(1)§ï¸ê®Æ(2)³]±K½X(3)³]Åv(4)¬å±b¸¹(5)§ïID" + "(6)±þ/´_¬¡Ãdª«(7)¼f§P [0]µ²§ô " : + "½Ð¿ï¾Ü (1)קï¸ê®Æ (2)³]©w±K½X ==> [0]µ²§ô ", + ans, 3, DOECHO); + + if(ans[0] > '2' && !real) + ans[0] = '0'; + + if(ans[0] == '1' || ans[0] == '3') { + clear(); + i = 2; + move(i++, 0); + outs(msg_uid); + outs(x.userid); + } + + switch(ans[0]) { + case '7': + violate_law(&x, unum); + return; + case '1': + move(0, 0); + outs("½Ð³v¶µ×§ï¡C"); + + getdata_buf(i++, 0," ¼Ê ºÙ ¡G",x.username, 24, DOECHO); + if(real) { + getdata_buf(i++, 0, "¯u¹ê©m¦W¡G", x.realname, 20, DOECHO); + getdata_buf(i++, 0, "¨¤ÀÃÒ¸¹¡G", x.ident, 11, DOECHO); + getdata_buf(i++, 0, "©~¦í¦a§}¡G", x.address, 50, DOECHO); + } + sprintf(buf, "%010d", x.mobile); + getdata_buf(i++, 0, "¤â¾÷¸¹½X¡G", buf, 11, LCECHO); + x.mobile=atoi(buf); + getdata_str(i++, 0, "¹q¤l«H½c[ÅÜ°Ên«·s»{ÃÒ]¡G", buf, 50, DOECHO, + x.email); + if(strcmp(buf,x.email) && strchr(buf, '@')) { + strcpy(x.email,buf); + mail_changed = 1 - real; + } + + sprintf(genbuf, "%i", (u->sex + 1) % 8); + getdata_str(i++, 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) { + int len; + + sprintf(genbuf, "%02i/%02i/%02i", + u->month, u->day, u->year % 100); + len = getdata_str(i, 0, "¥Í¤é ¤ë¤ë/¤é¤é/¦è¤¸¡G", buf, 9, + DOECHO,genbuf); + if(len && len != 8) + continue; + if(!len) { + x.month = u->month; + x.day = u->day; + x.year = u->year; + } else if(len == 8) { + x.month = (buf[0] - '0') * 10 + (buf[1] - '0'); + x.day = (buf[3] - '0') * 10 + (buf[4] - '0'); + x.year = (buf[6] - '0') * 10 + (buf[7] - '0'); + } else + continue; + if(!real && (x.month > 12 || x.month < 1 || x.day > 31 || + x.day < 1 || x.year > 90 || x.year < 40)) + continue; + i++; + break; + } + if(real) { + unsigned long int l; + if(HAS_PERM(PERM_BBSADM)) { + sprintf(genbuf, "%d", x.money); + if(getdata_str(i++, 0,"»È¦æ±b¤á¡G", buf, 10, DOECHO,genbuf)) + if((l = atol(buf)) >= 0) { + if(l != x.money) { + money_change = 1; + money = x.money; + x.money = l; + } + } + } + sprintf(genbuf, "%d", x.exmailbox); + if(getdata_str(i++, 0,"ÁʶR«H½c¼Æ¡G", buf, 4, DOECHO,genbuf)) + if((l = atol(buf)) >= 0) + x.exmailbox = (int)l; + + getdata_buf(i++, 0, "»{ÃÒ¸ê®Æ¡G", x.justify, 44, DOECHO); + getdata_buf(i++, 0, "³Ìªñ¥úÁ{¾÷¾¹¡G", x.lasthost, 16, DOECHO); + + sprintf(genbuf, "%d", x.numlogins); + if(getdata_str(i++, 0,"¤W½u¦¸¼Æ¡G", buf, 10, DOECHO,genbuf)) + if((fail = atoi(buf)) >= 0) + x.numlogins = fail; + + sprintf(genbuf,"%d", u->numposts); + if(getdata_str(i++, 0, "¤å³¹¼Æ¥Ø¡G", buf, 10, DOECHO,genbuf)) + if((fail = atoi(buf)) >= 0) + x.numposts = fail; + sprintf(genbuf, "%d", u->vl_count); + if (getdata_str(i++, 0, "¹Hªk°O¿ý¡G", buf, 10, DOECHO, genbuf)) + if ((fail = atoi(buf)) >= 0) + x.vl_count = fail; + + sprintf(genbuf, "%d/%d/%d", u->five_win, u->five_lose, + u->five_tie); + if(getdata_str(i++, 0, "¤¤l´Ñ¾ÔÁZ ³Ó/±Ñ/©M¡G", buf, 16, DOECHO, + genbuf)) + while(1) { + p = strtok(buf, "/\r\n"); + if(!p) break; + x.five_win = atoi(p); + p = strtok(NULL, "/\r\n"); + if(!p) break; + x.five_lose = atoi(p); + p = strtok(NULL, "/\r\n"); + if(!p) break; + x.five_tie = atoi(p); + break; + } + sprintf(genbuf, "%d/%d/%d", u->chc_win, u->chc_lose, u->chc_tie); + if(getdata_str(i++, 0, "¶H´Ñ¾ÔÁZ ³Ó/±Ñ/©M¡G", buf, 16, DOECHO, + genbuf)) + while(1) { + p = strtok(buf, "/\r\n"); + if(!p) break; + x.chc_win = atoi(p); + p = strtok(NULL, "/\r\n"); + if(!p) break; + x.chc_lose = atoi(p); + p = strtok(NULL, "/\r\n"); + if(!p) break; + x.chc_tie = atoi(p); + break; + } + fail = 0; + } + break; + + case '2': + i = 19; + if(!real) { + if(!getdata(i++, 0, "½Ð¿é¤Jì±K½X¡G", buf, PASSLEN, NOECHO) || + !checkpasswd(u->passwd, buf)) { + outs("\n\n±z¿é¤Jªº±K½X¤£¥¿½T\n"); + fail++; + break; + } + } + else{ + char witness[3][32]; + time_t now = time(NULL); + for(i=0;i<3;i++){ + if(!getdata(19+i, 0, "½Ð¿é¤J¨ó§UÃÒ©ú¤§¨Ï¥ÎªÌ¡G", witness[i], 32, DOECHO)){ + outs("\n¤£¿é¤J«hµLªk§ó§ï\n"); + fail++; + break; + } + else if (!getuser(witness[i])){ + outs("\n¬dµL¦¹¨Ï¥ÎªÌ\n"); + fail++; + break; + } + else if (now - xuser.firstlogin < 6*30*24*60*60){ + outs("\nµù¥U¥¼¶W¹L¥b¦~¡A½Ð«·s¿é¤J\n"); + i--; + } + } + if (i < 3) + break; + else + i = 20; + } + + if(!getdata(i++, 0, "½Ð³]©w·s±K½X¡G", buf, PASSLEN, NOECHO)) { + outs("\n\n±K½X³]©w¨ú®ø, Ä~Äò¨Ï¥Î±K½X\n"); + fail++; + break; + } + strncpy(genbuf, buf, PASSLEN); + + getdata(i++, 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'; + strncpy(x.passwd, genpasswd(buf), PASSLEN); + if (real) + x.userlevel &= (!PERM_LOGINOK); + break; + + case '3': + i = setperms(x.userlevel, str_permid); + if(i == x.userlevel) + fail++; + else { + flag=1; + temp=x.userlevel; + x.userlevel = i; + } + break; + + case '4': + i = QUIT; + break; + + case '5': + if (getdata_str(b_lines - 3, 0, "·sªº¨Ï¥ÎªÌ¥N¸¹¡G", genbuf, IDLEN + 1, + DOECHO,x.userid)) { + if(searchuser(genbuf)) { + outs("¿ù»~! ¤w¸g¦³¦P¼Ë ID ªº¨Ï¥ÎªÌ"); + fail++; + } else + strcpy(x.userid, genbuf); + } + break; + case '6': + if(x.mychicken.name[0]) + x.mychicken.name[0] = 0; + else + strcpy(x.mychicken.name,"[¦º]"); + break; + default: + return; + } + + if(fail) { + pressanykey(); + return; + } + + getdata(b_lines - 1, 0, msg_sure_ny, ans, 3, LCECHO); + if(*ans == 'y') { + if(flag) + post_change_perm(temp,i,cuser.userid,x.userid); + 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); + } + memcpy(u, &x, sizeof(x)); + if(mail_changed) { +#ifdef EMAIL_JUSTIFY + x.userlevel &= ~PERM_LOGINOK; + mail_justify(); +#endif + } + + if(i == QUIT) { + char src[STRLEN], dst[STRLEN]; + + sprintf(src, "home/%c/%s", x.userid[0], x.userid); + sprintf(dst, "tmp/%s", x.userid); + if(Rename(src, dst)) { + sprintf(genbuf, "/bin/rm -fr %s >/dev/null 2>&1", src); +/* do not remove + system(genbuf); +*/ + } + log_usies("KILL", x.userid); + x.userid[0] = '\0'; + setuserid(unum, x.userid); + } else + log_usies("SetUser", x.userid); + if(money_change) + setumoney(unum,x.money); + passwd_update(unum, &x); + now = time(0); + if(money_change) { + strcpy(genbuf, "boards/Security"); + stampfile(genbuf, &fhdr); + if(!(fp = fopen(genbuf,"w"))) + return; + + now = time(NULL); + fprintf(fp, "§@ªÌ: [¨t²Î¦w¥þ§½] ¬ÝªO: Security\n" + "¼ÐÃD: [¤½¦w³ø§i] ¯¸ªøקïª÷¿ú³ø§i\n" + "®É¶¡: %s\n" + " ¯¸ªø\033[1;32m%s\033[m§â\033[1;32m%s\033[m" + "ªº¿ú±q\033[1;35m%ld\033[m§ï¦¨\033[1;35m%d\033[m", + ctime(&now), cuser.userid, x.userid, money, x.money); + + clrtobot (); + clear(); + while(!getdata(5, 0, "½Ð¿é¤J²z¥Ñ¥H¥Üt³d¡G", reason, 60, DOECHO)); + + fprintf(fp, "\n \033[1;37m¯¸ªø%sקï¿ú²z¥Ñ¬O¡G%s\033[m", + cuser.userid, reason); + fclose(fp); + sprintf(fhdr.title, "[¤½¦w³ø§i] ¯¸ªø%sקï%s¿ú³ø§i", cuser.userid, + x.userid); + strcpy(fhdr.owner, "[¨t²Î¦w¥þ§½]"); + append_record("boards/Security/.DIR", &fhdr, sizeof(fhdr)); + } + } +} + +int u_info() { + move(2, 0); + user_display(&cuser, 0); + uinfo_query(&cuser, 0, usernum); + strcpy(currutmp->realname, cuser.realname); + strcpy(currutmp->username, cuser.username); + return 0; +} + +int u_ansi() { + showansi ^= 1; + cuser.uflag ^= COLOR_FLAG; + outs(reset_color); + return 0; +} + +int u_cloak() { + outs((currutmp->invisible ^= 1) ? MSG_CLOAKED : MSG_UNCLOAK); + return XEASY; +} + +int u_switchproverb() { +/* char *state[4]={"¥Î¥\\«¬","¦w¶h«¬","¦Û©w«¬","SHUTUP"}; */ + char buf[100]; + + cuser.proverb =(cuser.proverb +1) %4; + setuserfile(buf,fn_proverb); + if(cuser.proverb==2 && dashd(buf)) { + FILE *fp = fopen(buf,"a"); + + fprintf(fp,"®y¥k»Êª¬ºA¬°[¦Û©w«¬]n°O±o³]®y¥k»Êªº¤º®eò!!"); + fclose(fp); + } + passwd_update(usernum, &cuser); + return 0; +} + +int u_editproverb() { + char buf[100]; + + setutmpmode(PROVERB); + setuserfile(buf,fn_proverb); + move(1,0); + clrtobot(); + outs("\n\n ½Ð¤@¦æ¤@¦æ¨Ì§ÇÁä¤J·Q¨t²Î´£¿ô§Aªº¤º®e,\n" + " Àx¦s«á°O±o§âª¬ºA³]¬° [¦Û©w«¬] ¤~¦³§@¥Î\n" + " ®y¥k»Ê³Ì¦h100±ø"); + pressanykey(); + vedit(buf,NA, NULL); + return 0; +} + +void showplans(char *uid) { + char genbuf[200]; + + sethomefile(genbuf, uid, fn_plans); + if(!show_file(genbuf, 7, MAX_QUERYLINES, ONLY_COLOR)) + prints("¡mÓ¤H¦W¤ù¡n%s ¥Ø«e¨S¦³¦W¤ù", uid); +} + +int showsignature(char *fname) { + FILE *fp; + char buf[256]; + int i, j; + char ch; + + clear(); + move(2, 0); + setuserfile(fname, "sig.0"); + j = strlen(fname) - 1; + + for(ch = '1'; ch <= '9'; ch++) { + fname[j] = ch; + if((fp = fopen(fname, "r"))) { + prints("\033[36m¡i ñ¦WÀÉ.%c ¡j\033[m\n", ch); + for(i = 0; i++ < MAX_SIGLINES && fgets(buf, 256, fp); outs(buf)); + fclose(fp); + } + } + return j; +} + +int u_editsig() { + int aborted; + char ans[4]; + int j; + char genbuf[200]; + + j = showsignature(genbuf); + + getdata(0, 0, "ñ¦WÀÉ (E)½s¿è (D)§R°£ (Q)¨ú®ø¡H[Q] ", ans, 4, LCECHO); + + aborted = 0; + if(ans[0] == 'd') + aborted = 1; + if(ans[0] == 'e') + aborted = 2; + + if(aborted) { + if(!getdata(1, 0, "½Ð¿ï¾Üñ¦WÀÉ(1-9)¡H[1] ", ans, 4, 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() { + 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 u_editcalendar() { + char genbuf[200]; + + getdata(b_lines - 1, 0, "¦æ¨Æ¾ä (D)§R°£ (E)½s¿è [Q]¨ú®ø¡H[Q] ", + genbuf, 3, LCECHO); + + if(genbuf[0] == 'e') { + int aborted; + + setutmpmode(EDITPLAN); + setcalfile(genbuf, cuser.userid); + aborted = vedit(genbuf, NA, NULL); + if(aborted != -1) + outs("¦æ¨Æ¾ä§ó·s§¹²¦"); + pressanykey(); + return 0; + } else if(genbuf[0] == 'd') { + setcalfile(genbuf, cuser.userid); + unlink(genbuf); + outmsg("¦æ¨Æ¾ä§R°£§¹²¦"); + } + return 0; +} + +/* ¨Ï¥ÎªÌ¶ñ¼gµù¥Uªí®æ */ +static void getfield(int line, char *info, char *desc, char *buf, int len) { + char prompt[STRLEN]; + char genbuf[200]; + + sprintf(genbuf, "ì¥ý³]©w¡G%-30.30s (%s)", buf, info); + move(line, 2); + outs(genbuf); + sprintf(prompt, "%s¡G", desc); + if(getdata_str(line + 1, 2, prompt, genbuf, len, DOECHO, buf)) + strcpy(buf, genbuf); + move(line, 2); + prints("%s¡G%s", desc, buf); + clrtoeol(); +} + +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 u_register() { + char rname[20], addr[50], ident[11], mobile[20]; + char phone[20], career[40], email[50],birthday[9],sex_is[2],year,mon,day; + char ans[3], *ptr; + FILE *fn; + time_t now; + char genbuf[200]; + + if(cuser.userlevel & PERM_LOGINOK) { + outs("±zªº¨¥÷½T»{¤w¸g§¹¦¨¡A¤£»Ý¶ñ¼g¥Ó½Ðªí"); + return XEASY; + } + if((fn = fopen(fn_register, "r"))) { + while(fgets(genbuf, STRLEN, fn)) { + if((ptr = strchr(genbuf, '\n'))) + *ptr = '\0'; + if(strncmp(genbuf, "uid: ", 5) == 0 && + strcmp(genbuf + 5, cuser.userid) == 0) { + fclose(fn); + outs("±zªºµù¥U¥Ó½Ð³æ©|¦b³B²z¤¤¡A½Ð@¤ßµ¥Ô"); + return XEASY; + } + } + fclose(fn); + } + + getdata(b_lines - 1, 0, "±z½T©wn¶ñ¼gµù¥U³æ¶Ü(Y/N)¡H[N] ", ans, 3, LCECHO); + if(ans[0] != 'y') + return FULLUPDATE; + + move(2, 0); + clrtobot(); + strcpy(ident, cuser.ident); + strcpy(rname, cuser.realname); + strcpy(addr, cuser.address); + strcpy(email, cuser.email); + sprintf(mobile,"0%09d",cuser.mobile); + sprintf(birthday, "%02i/%02i/%02i", + cuser.month, cuser.day, cuser.year % 100); + sex_is[0]=(cuser.sex % 8)+'1';sex_is[1]=0; + career[0] = phone[0] = '\0'; + while(1) { + clear(); + move(1, 0); + prints("%s(%s) ±z¦n¡A½Ð¾Ú¹ê¶ñ¼g¥H¤Uªº¸ê®Æ:", + cuser.userid, cuser.username); + do{ + getfield(3, "D120908396", "¨¤ÀÃÒ¸¹", ident, 11); + }while(removespace(ident)<10 || !isalpha(ident[0])); + do{ + getfield(5, "½Ð¥Î¤¤¤å", "¯u¹ê©m¦W", rname, 20); + }while(!removespace(rname) || isalpha(rname[0])); + do{ + getfield(7, "¾Ç®Õ¨t¯Å©Î³æ¦ì¾ºÙ", "ªA°È³æ¦ì", career, 40); + }while(!removespace(career)); + do{ + getfield(9, "¥]¬A¹ì«Ç©ÎªùµP¸¹½X", "¥Ø«e¦í§}", addr, 50); + }while(!(addr[0])); + do{ + getfield(11, "¥]¬Aªø³~¼·¸¹°Ï°ì½X", "³sµ¸¹q¸Ü", phone, 20); + }while(!removespace(phone)); + getfield(13, "¥u¿é¤J¼Æ¦r ¦p:0912345678", "¤â¾÷¸¹½X", mobile, 20); + while(1) { + int len; + + getfield(15,"¤ë¤ë/¤é¤é/¦è¤¸ ¦p:09/27/76","¥Í¤é",birthday,9); + len = strlen(birthday); + if(!len) { + sprintf(birthday, "%02i/%02i/%02i", + cuser.month, cuser.day, cuser.year % 100); + mon = cuser.month; + day = cuser.day; + year = cuser.year; + } else if(len == 8) { + mon = (birthday[0] - '0') * 10 + (birthday[1] - '0'); + day = (birthday[3] - '0') * 10 + (birthday[4] - '0'); + year = (birthday[6] - '0') * 10 + (birthday[7] - '0'); + } else + continue; + if(mon > 12 || mon < 1 || day > 31 || day < 1 || year > 90 || + year < 40) + continue; + break; + } + getfield(17, "1.¸¯®æ 2.©j±µ ", "©Ê§O", sex_is, 2); + getfield(19, "¨¤À»{ÃÒ¥Î", "E-Mail Address", email, 50); + + getdata(b_lines - 1, 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; + } + strcpy(cuser.ident, ident); + strcpy(cuser.realname, rname); + strcpy(cuser.address, addr); + strcpy(cuser.email, email); + cuser.mobile = atoi(mobile); + cuser.sex= (sex_is[0] - '1') % 8; + cuser.month = mon; + cuser.day = day; + cuser.year = year; + if((fn = fopen(fn_register, "a"))) { + now = time(NULL); + trim(career); + trim(addr); + trim(phone); + fprintf(fn, "num: %d, %s", usernum, ctime(&now)); + fprintf(fn, "uid: %s\n", cuser.userid); + fprintf(fn, "ident: %s\n", ident); + 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); + } + clear(); + move(9,3); + prints("³Ì«áPost¤@½g\033[32m¦Û§Ú¤¶²Ð¤å³¹\033[mµ¹¤j®a§a¡A" + "§i¶D©Ò¦³¦Ñ°©ÀY\033[31m§Ú¨Ó°Õ^$¡C\\n\n\n\n"); + pressanykey(); + cuser.userlevel |= PERM_POST; + brc_initial("WhoAmI"); + set_board(); + do_post(); + cuser.userlevel &= ~PERM_POST; + return 0; +} + +/* ¦C¥X©Ò¦³µù¥U¨Ï¥ÎªÌ */ +extern struct uhash_t *uhash; +static int usercounter, totalusers, showrealname; +static ushort u_list_special; + +static int u_list_CB(userec_t *uentp) { + static int i; + char permstr[8], *ptr; + register int level; + + if(uentp == NULL) { + move(2, 0); + clrtoeol(); + prints("\033[7m ¨Ï¥ÎªÌ¥N¸¹ %-25s ¤W¯¸ ¤å³¹ %s " + "³Ìªñ¥úÁ{¤é´Á \033[0m\n", + showrealname ? "¯u¹ê©m¦W" : "ºï¸¹¼ÊºÙ", + HAS_PERM(PERM_SEEULEVELS) ? "µ¥¯Å" : ""); + i = 3; + return 0; + } + + if(bad_user_id(uentp->userid)) + return 0; + + if((uentp->userlevel & ~(u_list_special)) == 0) + return 0; + + if(i == b_lines) { + prints("\033[34;46m ¤wÅã¥Ü %d/%d ¤H(%d%%) \033[31;47m " + "(Space)\033[30m ¬Ý¤U¤@¶ \033[31m(Q)\033[30m Â÷¶} \033[m", + usercounter, totalusers, usercounter * 100 / totalusers); + i = igetch(); + if(i == 'q' || i == 'Q') + return QUIT; + i = 3; + } + if(i == 3) { + move(3, 0); + clrtobot(); + } + + level = uentp->userlevel; + strcpy(permstr, "----"); + if(level & PERM_SYSOP) + permstr[0] = 'S'; + else if(level & PERM_ACCOUNTS) + permstr[0] = 'A'; + else if(level & PERM_DENYPOST) + 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, + showrealname ? uentp->realname : uentp->username, + uentp->numlogins, uentp->numposts, + HAS_PERM(PERM_SEEULEVELS) ? permstr : "", ptr); + usercounter++; + i++; + return 0; +} + +int u_list() { + char genbuf[3]; + + setutmpmode(LAUSERS); + showrealname = u_list_special = usercounter = 0; + totalusers = uhash->number; + if(HAS_PERM(PERM_SEEULEVELS)) { + getdata(b_lines - 1, 0, "Æ[¬Ý [1]¯S®íµ¥¯Å (2)¥þ³¡¡H", + genbuf, 3, DOECHO); + if(genbuf[0] != '2') + u_list_special = PERM_BASIC | PERM_CHAT | PERM_PAGE | PERM_POST | PERM_LOGINOK | PERM_BM; + } + if(HAS_PERM(PERM_CHATROOM) || HAS_PERM(PERM_SYSOP)) { + getdata(b_lines - 1, 0, "Åã¥Ü [1]¯u¹ê©m¦W (2)¼ÊºÙ¡H", + genbuf, 3, DOECHO); + if(genbuf[0] != '2') + showrealname = 1; + } + u_list_CB(NULL); + if(passwd_apply(u_list_CB) == -1) { + outs(msg_nobody); + return XEASY; + } + move(b_lines, 0); + clrtoeol(); + prints("\033[34;46m ¤wÅã¥Ü %d/%d ªº¨Ï¥ÎªÌ(¨t²Î®e¶qµL¤W) " + "\033[31;47m (½Ð«ö¥ô·NÁäÄ~Äò) \033[m", usercounter, totalusers); + egetch(); + return 0; +} diff --git a/mbbsd/var.c b/mbbsd/var.c new file mode 100644 index 00000000..7b07f63b --- /dev/null +++ b/mbbsd/var.c @@ -0,0 +1,268 @@ +/* $Id: var.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <sys/types.h> +#include "config.h" +#include "pttstruct.h" +#include "common.h" + +char *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 */ + "¤£±µ¨ü¯¸¥~ªº«H", /* PERM_ */ + "¨S·Q¨ì", /* PERM_ */ + "µøı¯¸ªø", /* PERM_VIEWSYSOP */ + "Æ[¹î¨Ï¥ÎªÌ¦æÂÜ", /* PERM_LOGUSER */ + "ºëµØ°ÏÁ`¾ã²zÅv", /* PERM_Announce */ + "¤½Ãö²Õ", /* PERM_RELATION */ + "¯S°È²Õ", /* PERM_SMG */ + "µ{¦¡²Õ", /* PERM_PRG */ + "¬¡°Ê²Õ", /* PERM_ACTION */ + "¬ü¤u²Õ", /* PERM_PAINT */ + "¥ßªk²Õ", /* PERM_LAW */ + "¤p²Õªø", /* PERM_SYSSUBOP */ + "¤@¯Å¥DºÞ", /* PERM_LSYSOP */ + "¢Þ¢ü¢ü" /* PERM_PTT */ +}; + +char *str_permboard[] = { + "¤£¥i Zap", /* BRD_NOZAP */ + "¤£¦C¤J²Îp", /* BRD_NOCOUNT */ + "¤£Âà«H", /* BRD_NOTRAN */ + "¸s²Õª©", /* BRD_GROUP */ + "ÁôÂê©", /* BRD_HIDE */ + "¨î(¤£»Ý³]©w)", /* BRD_POSTMASK */ + "°Î¦Wª©", /* BRD_ANONYMOUS */ + "¹w³]°Î¦Wª©", /* BRD_DEFAULTANONYMOUS */ + "¹Hªk§ï¶i¤¤¬Ýª©", /* BRD_BAD */ + "³s¸p±M¥Î¬Ýª©", /* BRD_VOTEBOARD */ + "¨S·Q¨ì", + "¨S·Q¨ì", + "¨S·Q¨ì", + "¨S·Q¨ì", + "¨S·Q¨ì", + "¨S·Q¨ì", + "¨S·Q¨ì", + "¨S·Q¨ì", + "¨S·Q¨ì", + "¨S·Q¨ì", + "¨S·Q¨ì", + "¨S·Q¨ì", + "¨S·Q¨ì", + "¨S·Q¨ì", + "¨S·Q¨ì", + "¨S·Q¨ì", + "¨S·Q¨ì", + "¨S·Q¨ì", + "¨S·Q¨ì", + "¨S·Q¨ì", + "¨S·Q¨ì", + "¨S·Q¨ì", +}; + +int usernum; +pid_t currpid; /* current process ID */ +unsigned int currstat; +int currmode = 0; +int curredit = 0; +int showansi = 1; +int curr_idle_timeout = IDLE_TIMEOUT; +time_t login_start_time; +userec_t cuser; /* current user structure */ +userec_t xuser; /* lookup user structure */ +char quote_file[80] = "\0"; +char quote_user[80] = "\0"; +time_t paste_time; +char paste_title[STRLEN]; +char paste_path[256]; +int paste_level; +char currtitle[40] = "\0"; +char vetitle[40] = "\0"; +char currowner[IDLEN + 2] = "\0"; +char currauthor[IDLEN + 2] = "\0"; +char currfile[FNLEN]; /* current file name @ bbs.c mail.c */ +unsigned char currfmode; /* current file mode */ +char currboard[IDLEN + 2]; +int currbid; +unsigned int currbrdattr; +char currBM[IDLEN * 3 + 10]; +char reset_color[4] = "\033[m"; +char margs[64] = "\0"; /* main argv list*/ +crosspost_t postrecord; /* anti cross post */ + +/* global string variables */ +/* filename */ + +char *fn_passwd = FN_PASSWD; +char *fn_board = FN_BOARD; +char *fn_note_ans = FN_NOTE_ANS; +char *fn_register = "register.new"; +char *fn_plans = "plans"; +char *fn_writelog = "writelog"; +char *fn_talklog = "talklog"; +char *fn_overrides = FN_OVERRIDES; +char *fn_reject = FN_REJECT; +char *fn_canvote = FN_CANVOTE; +char *fn_notes = "notes"; +char *fn_water = FN_WATER; +char *fn_visable = FN_VISABLE; +char *fn_mandex = "/.Names"; +char *fn_proverb = "proverb"; + +/* are descript in userec.loginview */ + +char *loginview_file[NUMVIEWFILE][2] = { + {FN_NOTE_ANS ,"»Ä²¢W»¶¬y¨¥ªO"}, + {FN_TOPSONG ,"ÂIºq±Æ¦æº]" }, + {"etc/topusr" ,"¤Q¤j±Æ¦æº]" }, + {"etc/topusr100" ,"¦Ê¤j±Æ¦æº]" }, + {"etc/birth.today" ,"¤µ¤é¹Ø¬P" }, + {"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®ð±Æ¦æº]"} +}; + +/* message */ +char *msg_seperator = MSG_SEPERATOR; +char *msg_mailer = MSG_MAILER; +char *msg_shortulist = MSG_SHORTULIST; + +char *msg_cancel = MSG_CANCEL; +char *msg_usr_left = MSG_USR_LEFT; +char *msg_nobody = MSG_NOBODY; + +char *msg_sure_ny = MSG_SURE_NY; +char *msg_sure_yn = MSG_SURE_YN; + +char *msg_bid = MSG_BID; +char *msg_uid = MSG_UID; + +char *msg_del_ok = MSG_DEL_OK; +char *msg_del_ny = MSG_DEL_NY; + +char *msg_fwd_ok = MSG_FWD_OK; +char *msg_fwd_err1 = MSG_FWD_ERR1; +char *msg_fwd_err2 = MSG_FWD_ERR2; + +char *err_board_update = ERR_BOARD_UPDATE; +char *err_bid = ERR_BID; +char *err_uid = ERR_UID; +char *err_filename = ERR_FILENAME; + +char *str_mail_address = "." BBSUSER "@" MYHOSTNAME; +char *str_new = "new"; +char *str_reply = "Re: "; +char *str_space = " \t\n\r"; +char *str_sysop = "SYSOP"; +char *str_author1 = STR_AUTHOR1; +char *str_author2 = STR_AUTHOR2; +char *str_post1 = STR_POST1; +char *str_post2 = STR_POST2; +char *BBSName = BBSNAME; + +/* #define MAX_MODES 78 */ +/* MAX_MODES is defined in common.h */ + +char *ModeTypeTable[MAX_MODES] = { + "µo§b", /* IDLE */ + "¥D¿ï³æ", /* MMENU */ + "¨t²ÎºûÅ@", /* ADMIN */ + "¶l¥ó¿ï³æ", /* MAIL */ + "¥æ½Í¿ï³æ", /* TMENU */ + "¨Ï¥ÎªÌ¿ï³æ", /* UMENU */ + "XYZ ¿ï³æ", /* XMENU */ + "¤ÀÃþ¬ÝªO", /* CLASS */ + "Play¿ï³æ", /* PMENU */ + "½s¯S§O¦W³æ", /* NMENU */ + "¢Þtt¶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Äy»²§U¾¹", /* EDITEXP */ + "¥Ó½ÐIP¦ì§}", /* IPREG */ + "ºôºÞ¿ì¤½¤¤", /* NetAdm */ + "µêÀÀ¹ê·~§{", /* DRINK */ + "pºâ¾÷", /* CAL */ + "½sÄy®y¥k»Ê", /* PROVERB */ + "¤½§GÄæ", /* ANNOUNCE */ + "¨è¬y¨¥ª©", /* EDNOTE */ + "^º~½Ķ¾÷", /* CDICT */ + "À˵ø¦Û¤vª««~", /* LOBJ */ + "ÂIºq", /* OSONG */ + "¥¿¦bª±¤pÂû", /* CHICKEN */ + "ª±±m¨é", /* TICKET */ + "²q¼Æ¦r", /* GUESSNUM */ + "¹C¼Ö³õ", /* AMUSE */ + "¶Â¥Õ´Ñ", /* 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µX", /* DARK */ + "NBA¤j²q´ú" /* TMPJACK */ + "¢Þtt¬dº]¨t²Î", /* JCEE */ + "«½s¤å³¹" /* REEDIT */ +}; diff --git a/mbbsd/vice.c b/mbbsd/vice.c new file mode 100644 index 00000000..46f695d9 --- /dev/null +++ b/mbbsd/vice.c @@ -0,0 +1,151 @@ +/* $Id: vice.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "modes.h" +#include "proto.h" +extern int usernum; + +#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, sizeof(tbingo)); + 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], 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; +} +// Ptt: showfile ran_showfile more ¤TªÌn¾ã¦X +static int ran_showfile(int y, int x, char *filename, int maxnum) { + FILE *fs; + char buf[512]; + + bzero(buf, sizeof(char) * 512); + sprintf(buf, "%s%d", filename, rand() % 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, 511, fs)) + prints("%s", buf); + + fclose(fs); + return 1; +} + +static int ran_showmfile(char *filename, int maxnum) { + char buf[256]; + + sprintf(buf, "%s%d", filename, rand() % maxnum + 1); + return more(buf, YEA); +} + +extern userec_t cuser; + +int vice_main() { + 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(); + prints("³o¤@´Áªºµo²¼¸¹½X"); + while(fgets(serial, 15, fd)) { + if((ptr = strchr(serial,'\r'))) + *ptr = 0; + if(j == 0) + i++; + move(10 + i, 24 + j); + prints("%s", serial); + j += 9; + j %= 45; + } + getdata(8, 0, "«ö'c'¶}©l¹ï¼ú¤F(©Î¬O¥ô·NÁäÂ÷¶})): ", ch, 2, 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 new file mode 100644 index 00000000..62916c99 --- /dev/null +++ b/mbbsd/vote.c @@ -0,0 +1,1068 @@ +/* $Id: vote.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <time.h> +#include <unistd.h> +#include <ctype.h> +#include <sys/file.h> +#include <sys/types.h> +#include <sys/stat.h> +#include "config.h" +#include "pttstruct.h" +#include "modes.h" +#include "common.h" +#include "perm.h" +#include "proto.h" + +static int total; +extern int numboards; +extern boardheader_t *bcache; /* Thor: for speed up */ +extern char *err_board_update; +extern char *fn_board; +extern char *msg_seperator; +extern int t_lines, t_columns; /* Screen size / width */ +extern int b_lines; /* Screen bottom line number: t_lines-1 */ +extern int currmode; +extern int usernum; +extern char currboard[]; /* name of currently selected board */ +extern userec_t cuser; + +static char STR_bv_control[] = "control"; /* §ë²¼¤é´Á ¿ï¶µ */ +static char STR_bv_desc[] = "desc"; /* §ë²¼¥Øªº */ +static char STR_bv_ballots[] = "ballots"; +static char STR_bv_flags[] = "flags"; +static char STR_bv_comments[] = "comments"; /* §ë²¼ªÌªº«Ø·N */ +static char STR_bv_limited[] = "limited"; /* ¨p¤H§ë²¼ */ +static char STR_bv_title[] = "vtitle"; + +static char STR_bv_results[] = "results"; + +static char STR_new_control[] = "control0"; /* §ë²¼¤é´Á ¿ï¶µ */ +static char STR_new_desc[] = "desc0"; /* §ë²¼¥Øªº */ +static char STR_new_ballots[] = "ballots0"; +static char STR_new_flags[] = "flags0"; +static char STR_new_comments[] = "comments0"; /* §ë²¼ªÌªº«Ø·N */ +static char STR_new_limited[] = "limited0"; /* ¨p¤H§ë²¼ */ +static char STR_new_title[] = "vtitle0"; + +int strip_ansi(char *buf, char *str, int mode) { + register int ansi, count = 0; + + for(ansi = 0; *str /*&& *str != '\n' */; str++) { + if(*str == 27) { + if(mode) { + if(buf) + *buf++ = *str; + count++; + } + ansi = 1; + } else if(ansi && strchr("[;1234567890mfHABCDnsuJKc=n", *str)) { + if((mode == NO_RELOAD && !strchr("c=n", *str)) || + (mode == ONLY_COLOR && strchr("[;1234567890m", *str))) { + if(buf) + *buf++ = *str; + count++; + } + if(strchr("mHn ", *str)) + ansi = 0; + } else { + ansi =0; + if(buf) + *buf++ = *str; + count++; + } + } + if(buf) + *buf = '\0'; + return count; +} + +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); + } +} + +static void b_count(char *buf, int counts[]) { + char inchar; + int fd; + + memset(counts, 0, 31 * sizeof(counts[0])); + total = 0; + if((fd = open(buf, O_RDONLY)) != -1) { + flock(fd, LOCK_EX); /* Thor: ¨¾¤î¦h¤H¦P®Éºâ */ + while(read(fd, &inchar, 1) == 1) { + counts[(int)(inchar - 'A')]++; + total++; + } + flock(fd, LOCK_UN); + close(fd); + } +} + + +static int b_nonzeroNum(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(char *bname, char *fname, char *fpath) { + register char *ip; + time_t dtime; + int fd, bid; + fileheader_t header; + + ip = fpath; + while(*(++ip)); + *ip++ = '/'; + + /* get a filename by timestamp */ + + dtime = time(0); + for(;;) { + sprintf(ip, "M.%ld.A", ++dtime); + fd = open(fpath, O_CREAT | O_EXCL | O_WRONLY, 0644); + if(fd >= 0) + break; + dtime++; + } + close(fd); + + log_usies("TESTfn", fname); + log_usies("TESTfp", fpath); + + unlink(fpath); + link(fname, fpath); + + /* append record to .DIR */ + + memset(&header, 0, sizeof(fileheader_t)); + strcpy(header.owner, "[°¨¸ô±´¤l]"); + sprintf(header.title, "[%s] ¬ÝªO ¿ï±¡³ø¾É", bname); + { + register struct tm *ptime = localtime(&dtime); + + sprintf(header.date, "%2d/%02d", ptime->tm_mon + 1, ptime->tm_mday); + } + strcpy(header.filename, ip); + + strcpy(ip, ".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(boardheader_t *fh, int ind) { + FILE *cfp, *tfp, *frp, *xfp; + char *bname ; + char buf[STRLEN]; + char inbuf[80]; + int counts[31]; + int num ; + int junk; + char b_control[64]; + char b_newresults[64]; + char b_report[64]; + time_t closetime, now; + + fh->bvote--; + + if(fh->bvote==0) + fh->bvote=2; + else if(fh->bvote==2) + fh->bvote=1; + + if(ind) { + sprintf(STR_new_ballots, "%s%d", STR_bv_ballots, ind); + sprintf(STR_new_control, "%s%d", STR_bv_control, ind); + sprintf(STR_new_desc, "%s%d", STR_bv_desc, ind); + sprintf(STR_new_flags, "%s%d", STR_bv_flags, ind); + sprintf(STR_new_comments, "%s%d", STR_bv_comments, ind); + sprintf(STR_new_limited, "%s%d", STR_bv_limited, ind); + sprintf(STR_new_title, "%s%d", STR_bv_title, ind); + } else { + strcpy(STR_new_ballots, STR_bv_ballots); + strcpy(STR_new_control, STR_bv_control); + strcpy(STR_new_desc, STR_bv_desc); + strcpy(STR_new_flags, STR_bv_flags); + strcpy(STR_new_comments, STR_bv_comments); + strcpy(STR_new_limited, STR_bv_limited); + strcpy(STR_new_title, STR_bv_title); + } + + bname = fh->brdname; + + setbfile(buf, bname, STR_new_control); + cfp = fopen(buf,"r"); + fscanf(cfp, "%d\n%lu\n", &junk, &closetime); + fclose(cfp); + + setbfile(b_control, bname, "tmp"); + if(rename(buf, b_control) == -1) + return; + setbfile(buf, bname, STR_new_flags); + num = b_nonzeroNum(buf); + unlink(buf); + setbfile(buf, bname, STR_new_ballots); + b_count(buf, counts); + unlink(buf); + + setbfile(b_newresults, bname, "newresults"); + if((tfp = fopen(b_newresults, "w")) == NULL) + return; + + now = time(NULL); + setbfile(buf, bname, STR_new_title); + + if((xfp=fopen(buf,"r"))) { + fgets(inbuf, sizeof(inbuf), xfp); + fprintf(tfp, "%s\n¡» §ë²¼¦WºÙ: %s\n\n", msg_seperator, inbuf); + } + + fprintf(tfp, "%s\n¡» §ë²¼¤¤¤î©ó: %s\n\n¡» ²¼¿ïÃD¥Ø´yz:\n\n", + msg_seperator, ctime(&closetime)); + fh->vtime = now; + + setbfile(buf, bname, STR_new_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§ë %d ²¼)\n", + num, junk); + while(fgets(inbuf, sizeof(inbuf), cfp)) { + inbuf[(strlen(inbuf) - 1)] = '\0'; + num = counts[inbuf[0] - 'A']; + fprintf(tfp, " %-42s %3d ²¼ %02.2f%%\n", inbuf + 3, num, + (float)(num*100)/(float)(total)); + } + fclose(cfp); + } + unlink(b_control); + + fprintf(tfp, "%s\n¡» ¨Ï¥ÎªÌ«Øij¡G\n\n", msg_seperator); + setbfile(buf, bname, STR_new_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); + } + sprintf(inbuf, "boards/%s", bname); + vote_report(bname, b_report, inbuf); + if(!(fh->brdattr &BRD_NOCOUNT)) { + sprintf(inbuf, "boards/%s", "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(boardheader_t *fh) { + FILE *cfp; + time_t closetime, now; + int i; + char buf[STRLEN]; + char temp[STRLEN]; + + now = time(NULL); + for(i = 0; i < 9; i++) { + if(i) + sprintf(STR_new_control, "%s%d", STR_bv_control, i); + else + strcpy(STR_new_control, STR_bv_control); + + setbfile(buf, fh->brdname, STR_new_control); + cfp = fopen(buf,"r"); + if (!cfp) + continue; + fgets(temp,sizeof(temp),cfp); + fscanf(cfp, "%lu\n", &closetime); + fclose(cfp); + if(closetime < now) + b_result_one(fh,i); + } +} + +static int b_close(boardheader_t *fh) { + time_t now; + now = time(NULL); + + if(fh->bvote == 2) { + if(fh->vtime < now - 3 * 86400) { + fh->bvote = 0; + return 1; + } + else + return 0; + } + b_result(fh); + return 1; +} + +int b_closepolls() { + static char *fn_vote_polling = ".polling"; + boardheader_t *fhp; + FILE *cfp; + time_t now; + int pos, dirty; + time_t last; + char timebuf[100]; + + now = time(NULL); +/* Edited by CharlieL for can't auto poll bug */ + + if((cfp = fopen(fn_vote_polling,"r"))) { + fgets(timebuf,100*sizeof(char),cfp); + sscanf(timebuf, "%lu", &last); + fclose(cfp); + if(last + 3600 >= now) + return 0; + } + + if((cfp = fopen(fn_vote_polling, "w")) == NULL) + return 0; + fprintf(cfp, "%lu\n%s\n", now, ctime(&now)); + fclose(cfp); + + dirty = 0; + for(fhp = bcache, pos = 1; pos <= numboards; fhp++, pos++) { + if(fhp->bvote && b_close(fhp)) { + if(substitute_record(fn_board, fhp, sizeof(*fhp), pos) == -1) + outs(err_board_update); + dirty = 1; + } + } + if(dirty) /* vote flag changed */ + reset_board(pos); + + return 0; +} + +static int vote_view(char *bname, int index) { + boardheader_t *fhp; + FILE* fp; + char buf[STRLEN], genbuf[STRLEN], inbuf[STRLEN]; + struct stat stbuf; + int fd, num = 0, i, pos, counts[31]; + time_t closetime; + + if(index) { + sprintf(STR_new_ballots, "%s%d", STR_bv_ballots, index); + sprintf(STR_new_control, "%s%d", STR_bv_control, index); + sprintf(STR_new_desc, "%s%d", STR_bv_desc, index); + sprintf(STR_new_flags, "%s%d", STR_bv_flags, index); + sprintf(STR_new_comments, "%s%d", STR_bv_comments, index); + sprintf(STR_new_limited, "%s%d", STR_bv_limited, index); + sprintf(STR_new_title, "%s%d", STR_bv_title, index); + } else { + strcpy(STR_new_ballots, STR_bv_ballots); + strcpy(STR_new_control, STR_bv_control); + strcpy(STR_new_desc, STR_bv_desc); + strcpy(STR_new_flags, STR_bv_flags); + strcpy(STR_new_comments, STR_bv_comments); + strcpy(STR_new_limited, STR_bv_limited); + strcpy(STR_new_title, STR_bv_title); + } + + setbfile(buf, bname, STR_new_ballots); + if((fd = open(buf, O_RDONLY)) > 0) { + fstat(fd, &stbuf); + close(fd); + } else + stbuf.st_size = 0; + + setbfile(buf, bname, STR_new_title); + move(0, 0); + clrtobot(); + + if((fp = fopen(buf, "r"))) { + fgets(inbuf, sizeof(inbuf), fp); + prints("\n§ë²¼¦WºÙ: %s", inbuf); + } + + setbfile(buf, bname, STR_new_control); + fp = fopen(buf, "r"); + fgets(inbuf, sizeof(inbuf), fp); + fscanf(fp, "%lu\n", &closetime); + + prints("\n¡» ¹wª¾§ë²¼¬ö¨Æ: ¨C¤H³Ì¦h¥i§ë %d ²¼,¥Ø«e¦@¦³ %d ²¼,\n" + "¥»¦¸§ë²¼±Nµ²§ô©ó %s", atoi(inbuf), stbuf.st_size, + ctime(&closetime)); + + /* Thor: ¶}©ñ ²¼¼Æ ¹wª¾ */ + setbfile(buf, bname, STR_new_flags); + num = b_nonzeroNum(buf); + + setbfile(buf, bname, STR_new_ballots); + b_count(buf, counts); + + prints("¦@¦³ %d ¤H§ë²¼\n", num); + total = 0; + + while(fgets(inbuf, sizeof(inbuf), fp)) { + inbuf[(strlen(inbuf) - 1)] = '\0'; + inbuf[30] = '\0'; /* truncate */ + i = inbuf[0] - 'A'; + num = counts[i]; + move(i % 15 + 6, i / 15 * 40); + prints(" %-32s%3d ²¼", inbuf, num); + total += num; + } + fclose(fp); + pos = getbnum(bname); + 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') { + setbfile(buf, bname, STR_new_control); + unlink(buf); + setbfile(buf, bname, STR_new_flags); + unlink(buf); + setbfile(buf, bname, STR_new_ballots); + unlink(buf); + setbfile(buf, bname, STR_new_desc); + unlink(buf); + setbfile(buf, bname, STR_new_limited); + unlink(buf); + setbfile(buf,bname, STR_new_title); + unlink(buf); + + if(fhp->bvote) + fhp->bvote--; + if (fhp->bvote == 2) + fhp->bvote = 1; + + 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(fhp,index); + if(substitute_record(fn_board, fhp, sizeof(*fhp), pos) == -1) + outs(err_board_update); + + reset_board(pos); + } + return FULLUPDATE; +} + +static int vote_view_all(char *bname) { + int i; + int x = -1; + FILE *fp, *xfp; + char buf[STRLEN], genbuf[STRLEN]; + char inbuf[80]; + + strcpy(STR_new_control, STR_bv_control); + strcpy(STR_new_title, STR_bv_title); + setbfile(buf, bname, STR_new_control); + move(0, 0); + if((fp=fopen(buf,"r"))) { + prints("(0) "); + x = 0; + fclose(fp); + + setbfile(buf, bname, STR_new_title); + if((xfp=fopen(buf,"r"))) + fgets(inbuf, sizeof(inbuf), xfp); + else + strcpy(inbuf, "µL¼ÐÃD"); + prints("%s\n", inbuf); + fclose(xfp); + } + + for(i = 1; i < 9; i++) { + sprintf(STR_new_control, "%s%d", STR_bv_control, i); + sprintf(STR_new_title, "%s%d", STR_bv_title, i); + setbfile(buf, bname, STR_new_control); + if((fp=fopen(buf,"r"))) { + prints("(%d) ", i); + x = i; + fclose(fp); + + setbfile(buf, bname, STR_new_title); + if((xfp=fopen(buf,"r"))) + fgets(inbuf, sizeof(inbuf), xfp); + else + strcpy(inbuf, "µL¼ÐÃD"); + prints("%s\n", inbuf); + fclose(xfp); + } + } + + if(x < 0) + return FULLUPDATE; + sprintf(buf, "n¬Ý´X¸¹§ë²¼ [%d] ", x); + + getdata(b_lines - 1, 0, buf, genbuf, 4, LCECHO); + + if(genbuf[0] < '0' || genbuf[0] > '8') + genbuf[0] = '0'+x; + + if(genbuf[0] != '0') + sprintf(STR_new_control, "%s%c", STR_bv_control, genbuf[0]); + else + strcpy(STR_new_control, STR_bv_control); + + setbfile(buf, bname, STR_new_control); + + if((fp=fopen(buf,"r"))) { + fclose(fp); + return vote_view(bname, genbuf[0] - '0'); + } + else + return FULLUPDATE; +} + +static int vote_maintain(char *bname) { + FILE *fp = NULL; + char inbuf[STRLEN], buf[STRLEN]; + int num = 0, aborted, pos, x, i; + time_t closetime; + boardheader_t *fhp; + char genbuf[4]; + + if(!(currmode & MODE_BOARD)) + return 0; + if((pos = getbnum(bname)) <= 0) + return 0; + + stand_title("Á|¿ì§ë²¼"); + fhp = bcache + pos - 1; + +/* CharlieL */ + if(fhp->bvote != 2 && fhp->bvote !=0) { + getdata(b_lines - 1, 0, + "(V)Æ[¹î¥Ø«e§ë²¼ (M)Á|¿ì·s§ë²¼ (A)¨ú®ø©Ò¦³§ë²¼ (Q)Ä~Äò [Q]", + genbuf, 4, LCECHO); + if(genbuf[0] == 'v') + return vote_view_all(bname); + else if(genbuf[0] == 'a') { + fhp->bvote=0; + + setbfile(buf, bname, STR_bv_control); + unlink(buf); + setbfile(buf, bname, STR_bv_flags); + unlink(buf); + setbfile(buf, bname, STR_bv_ballots); + unlink(buf); + setbfile(buf, bname, STR_bv_desc); + unlink(buf); + setbfile(buf, bname, STR_bv_limited); + unlink(buf); + setbfile(buf, bname, STR_bv_title); + unlink(buf); + + for(i = 1; i < 9; i++) { + sprintf(STR_new_ballots, "%s%d", STR_bv_ballots, i); + sprintf(STR_new_control, "%s%d", STR_bv_control, i); + sprintf(STR_new_desc, "%s%d", STR_bv_desc, i); + sprintf(STR_new_flags, "%s%d", STR_bv_flags, i); + sprintf(STR_new_comments, "%s%d", STR_bv_comments, i); + sprintf(STR_new_limited, "%s%d", STR_bv_limited, i); + sprintf(STR_new_title, "%s%d", STR_bv_title, i); + + setbfile(buf, bname, STR_new_control); + unlink(buf); + setbfile(buf, bname, STR_new_flags); + unlink(buf); + setbfile(buf, bname, STR_new_ballots); + unlink(buf); + setbfile(buf, bname, STR_new_desc); + unlink(buf); + setbfile(buf, bname, STR_new_limited); + unlink(buf); + setbfile(buf, bname, STR_new_title); + unlink(buf); + } + if(substitute_record(fn_board, fhp, sizeof(*fhp), pos) == -1) + outs(err_board_update); + + return FULLUPDATE; + } else if(genbuf[0] != 'm' || fhp->bvote > 10) + return FULLUPDATE; + } + + strcpy(STR_new_control, STR_bv_control); + setbfile(buf,bname, STR_new_control); + x = 0; + while(x < 9 && (fp = fopen(buf,"r")) != NULL) { + fclose(fp); + x++; + sprintf(STR_new_control, "%s%d", STR_bv_control, x); + setbfile(buf, bname, STR_new_control); + } + if(fp) + fclose(fp); + if(x >=9) + return FULLUPDATE; + if(x) { + sprintf(STR_new_ballots, "%s%d", STR_bv_ballots,x); + sprintf(STR_new_control, "%s%d", STR_bv_control,x); + sprintf(STR_new_desc, "%s%d", STR_bv_desc,x); + sprintf(STR_new_flags, "%s%d", STR_bv_flags,x); + sprintf(STR_new_comments, "%s%d", STR_bv_comments,x); + sprintf(STR_new_limited, "%s%d", STR_bv_limited,x); + sprintf(STR_new_title, "%s%d", STR_bv_title,x); + } else { + strcpy(STR_new_ballots, STR_bv_ballots); + strcpy(STR_new_control, STR_bv_control); + strcpy(STR_new_desc, STR_bv_desc); + strcpy(STR_new_flags, STR_bv_flags); + strcpy(STR_new_comments, STR_bv_comments); + strcpy(STR_new_limited, STR_bv_limited); + strcpy(STR_new_title, STR_bv_title); + } + clear(); + move(0,0); + prints("²Ä %d ¸¹§ë²¼\n", x); + setbfile(buf, bname, STR_new_title); + getdata(4, 0, "½Ð¿é¤J§ë²¼¦WºÙ", inbuf, 30, LCECHO); + if(inbuf[0]=='\0') + strcpy(inbuf,"¤£ª¾¦Wªº"); + fp = fopen(buf, "w"); + fprintf(fp, "%s", inbuf); + fclose(fp); + + prints("«ö¥ô¦óÁä¶}©l½s¿è¦¹¦¸ [§ë²¼©v¦®]"); + pressanykey(); + setbfile(buf, bname, STR_new_desc); + aborted = vedit(buf, NA, NULL); + if(aborted== -1) { + clear(); + outs("¨ú®ø¦¹¦¸§ë²¼"); + pressanykey(); + return FULLUPDATE; + } + aborted = 0; + setbfile(buf, bname, STR_new_flags); + unlink(buf); + + getdata(4, 0, + "¬O§_©w§ë²¼ªÌ¦W³æ¡G(y)½sÄy¥i§ë²¼¤Hû¦W³æ[n]¥ô¦ó¤H¬Ò¥i§ë²¼:[N]", + inbuf, 2, LCECHO); + setbfile(buf, bname, STR_new_limited); + if(inbuf[0] == 'y') { + fp = fopen(buf, "w"); + fprintf(fp,"¦¹¦¸§ë²¼³]"); + fclose(fp); + friend_edit(FRIEND_CANVOTE); + } else { + if(dashf(buf)) + unlink(buf); + } + clear(); + getdata(0, 0, "¦¹¦¸§ë²¼¶i¦æ´X¤Ñ (¤@¨ì¤Q¤Ñ)¡H", inbuf, 4, DOECHO); + + closetime = atoi(inbuf); + if(closetime <= 0) + closetime = 1; + else if(closetime >10) + closetime = 10; + + closetime = closetime * 86400 + time(NULL); + setbfile(buf, bname, STR_new_control); + fp = fopen(buf, "w"); + fprintf(fp, "00\n%lu\n", closetime); + + outs("\n½Ð¨Ì§Ç¿é¤J¿ï¶µ, «ö ENTER §¹¦¨³]©w"); + num = 0; + while(!aborted) { + sprintf(buf, "%c) ", num + 'A'); + getdata((num % 15) + 2, (num / 15) * 40, buf, inbuf, 36, DOECHO); + if(*inbuf) { + fprintf(fp, "%1c) %s\n", (num+'A'), inbuf); + num++; + } + if((*inbuf == '\0' && num >= 1) || num == 30) + aborted = 1; + } + sprintf(buf, "½Ð°Ý¨C¤H³Ì¦h¥i§ë´X²¼¡H([1]¡ã%d): ", num); + + getdata(t_lines-3, 0, buf, inbuf, 3, DOECHO); + + if(atoi(inbuf) <= 0 || atoi(inbuf) > num) + strcpy(inbuf,"1"); + + rewind(fp); + fprintf(fp, "%2d\n", MAX(1, atoi(inbuf))); + fclose(fp); + + if(fhp->bvote == 2) + fhp->bvote = 0; + else if(fhp->bvote == 1) + fhp->bvote = 2; + else if(fhp->bvote == 2) + fhp->bvote = 1; + + 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(char *bname, int index, char val) { + char buf[256], flag; + int fd, num, size; + + if(index) + sprintf(STR_new_flags, "%s%d", STR_bv_flags, index); + else + strcpy(STR_new_flags, STR_bv_flags); + + num = usernum - 1; + setbfile(buf, bname, STR_new_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 same(char compare, char list[], int num) { + int n; + int rep = 0; + + for(n = 0; n < num; n++) { + if(compare == list[n]) + rep = 1; + if(rep == 1) + list[n] = list[n + 1]; + } + return rep; +} + +static int user_vote_one(char *bname, int ind) { + FILE* cfp,*fcm; + char buf[STRLEN]; + boardheader_t *fhp; + int pos = 0, i = 0, count = 0, tickets, fd; + char inbuf[80], choices[31], vote[4], chosen[31]; + time_t closetime; + + if(ind) { + sprintf(STR_new_ballots, "%s%d", STR_bv_ballots, ind); + sprintf(STR_new_control, "%s%d", STR_bv_control, ind); + sprintf(STR_new_desc, "%s%d", STR_bv_desc, ind); + sprintf(STR_new_flags, "%s%d", STR_bv_flags, ind); + sprintf(STR_new_comments, "%s%d", STR_bv_comments, ind); + sprintf(STR_new_limited, "%s%d", STR_bv_limited, ind); + } else { + strcpy(STR_new_ballots, STR_bv_ballots); + strcpy(STR_new_control, STR_bv_control); + strcpy(STR_new_desc, STR_bv_desc); + strcpy(STR_new_flags, STR_bv_flags); + strcpy(STR_new_comments, STR_bv_comments); + strcpy(STR_new_limited, STR_bv_limited); + } + + setbfile(buf, bname, STR_new_control); + cfp = fopen(buf,"r"); + if(!cfp) + return FULLUPDATE; + + setbfile(buf, bname, STR_new_limited); /* Ptt */ + if(dashf(buf)) { + setbfile(buf, bname, FN_CANVOTE); + if(!belong(buf, cuser.userid)) { + fclose(cfp); + outs("\n\n¹ï¤£°_! ³o¬O¨p¤H§ë²¼..§A¨Ã¨S¦³¨üÁÜò!"); + pressanykey(); + return FULLUPDATE; + } else { + outs("\n\n®¥³ß§A¨üÁܦ¹¦¸¨p¤H§ë²¼....<«ö¥ô·NÁäÀ˵ø¦¹¦¸¨üÁܦW³æ>"); + pressanykey(); + more(buf, YEA); + } + } + if(vote_flag(bname, ind, '\0')) { + outs("\n\n¦¹¦¸§ë²¼¡A§A¤w§ë¹L¤F¡I"); + pressanykey(); + return FULLUPDATE; + } + + setutmpmode(VOTING); + setbfile(buf, bname, STR_new_desc); + more(buf, YEA); + + stand_title("§ë²¼½c"); + if((pos = getbnum(bname)) <= 0) + return 0; + + fhp = bcache + pos - 1; + fgets(inbuf, sizeof(inbuf), cfp); + tickets = atoi(inbuf); + fscanf(cfp,"%lu\n", &closetime); + + prints("§ë²¼¤è¦¡¡G½T©w¦n±zªº¿ï¾Ü«á¡A¿é¤J¨ä¥N½X(A, B, C...)§Y¥i¡C\n" + "¦¹¦¸§ë²¼§A¥i¥H§ë %1d ²¼¡C" + "«ö 0 ¨ú®ø§ë²¼ , 1 §¹¦¨§ë²¼\n" + "¦¹¦¸§ë²¼±Nµ²§ô©ó¡G%s \n", + tickets, ctime(&closetime)); + move(5, 0); + memset(choices, 0, sizeof(choices)); + memset(chosen , 0, sizeof(chosen)); + + while(fgets(inbuf, sizeof(inbuf), cfp)) { + move((count % 15) + 5, (count / 15) * 40); + prints( " %s", strtok(inbuf, "\n\0")); + choices[count++] = inbuf[0]; + } + fclose(cfp); + + while(1) { + vote[0] = vote[1] = '\0'; + move(t_lines - 2, 0); + prints("§AÁÙ¥i¥H§ë %2d ²¼", tickets - i); + getdata(t_lines - 4, 0, "¿é¤J±zªº¿ï¾Ü: ", vote, 3, DOECHO); + *vote = toupper(*vote); + if(vote[0] == '0' || (!vote[0] && !i)) { + outs("°Oªº¦A¨Ó§ë³á!!"); + break; + } else if(vote[0] == '1' && i) + ; + else if(!vote[0]) + continue; + else if(index(choices, vote[0]) == NULL) /* µL®Ä */ + continue; + else if(same(vote[0], chosen, i)) { + move(((vote[0] - 'A') % 15) + 5, (((vote[0] - 'A')) / 15) * 40); + prints(" "); + i--; + continue; + } else { + if(i == tickets) + continue; + chosen[i] = vote[0]; + move(((vote[0]-'A') % 15) + 5, (((vote[0] - 'A')) / 15) * 40); + prints("*"); + i++; + continue; + } + + if(vote_flag(bname, ind, vote[0]) != 0) + prints("«ÂЧ벼! ¤£¤©p²¼¡C"); + else { + setbfile(buf, bname, STR_new_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++) + strcpy(mycomments[i], "\n"); + + flock(fd, LOCK_EX); + for(count = 0; count < 31; count++) { + if(chosen[count]) + write(fd, &chosen[count], 1); + } + 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], 74, + 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, STR_new_comments); + if(mycomments[0]) + if((fcm = fopen(b_comments, "a"))){ + fprintf(fcm, + "\033[36m¡³¨Ï¥ÎªÌ\033[1;36m %s " + "\033[;36mªº«Øij¡G\033[m\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); + prints("¤w§¹¦¨§ë²¼¡I\n"); + } + } + break; + } + pressanykey(); + return FULLUPDATE; +} + +static int user_vote(char *bname) { + int pos; + boardheader_t *fhp; + char buf[STRLEN]; + FILE* fp,*xfp; + int i, x = -1; + char genbuf[STRLEN]; + char inbuf[80]; + + if((pos = getbnum(bname)) <= 0) + return 0; + + fhp = bcache + pos - 1; + + move(0,0); + clrtobot(); + + if(fhp->bvote == 2 || fhp->bvote == 0) { + outs("\n\n¥Ø«e¨Ã¨S¦³¥ô¦ó§ë²¼Á|¦æ¡C"); + pressanykey(); + return FULLUPDATE; + } + + if(!HAS_PERM(PERM_LOGINOK)) { + outs("\n¹ï¤£°_! ±z¥¼º¡¤G¤Q·³, ÁÙ¨S¦³§ë²¼Åv³á!"); + pressanykey(); + return FULLUPDATE; + } + + strcpy(STR_new_control, STR_bv_control); + strcpy(STR_new_title, STR_bv_title); + setbfile(buf, bname, STR_new_control); + move(0, 0); + if((fp = fopen(buf, "r"))) { + prints("(0) "); + x = 0; + fclose(fp); + + setbfile(buf, bname, STR_new_title); + if((xfp = fopen(buf,"r"))) + fgets(inbuf, sizeof(inbuf), xfp); + else + strcpy(inbuf, "µL¼ÐÃD"); + prints("%s\n", inbuf); + fclose(xfp); + } + + for(i = 1; i < 9; i++) { + sprintf(STR_new_control, "%s%d", STR_bv_control, i); + sprintf(STR_new_title, "%s%d", STR_bv_title, i); + setbfile(buf, bname, STR_new_control); + if((fp = fopen(buf, "r"))) { + prints("(%d) ", i); + x = i; + fclose(fp); + + setbfile(buf, bname, STR_new_title); + if((xfp = fopen(buf, "r"))) + fgets(inbuf, sizeof(inbuf), xfp); + else + strcpy(inbuf, "µL¼ÐÃD"); + prints("%s\n", inbuf); + fclose(xfp); + } + } + + if(x < 0) + return FULLUPDATE; + + sprintf(buf, "n§ë´X¸¹§ë²¼ [%d] ", x); + + getdata(b_lines - 1, 0, buf, genbuf, 4, LCECHO); + + if(genbuf[0] < '0' || genbuf[0] > '8') + genbuf[0] = x + '0'; + + if(genbuf[0] != '0') + sprintf(STR_new_control, "%s%c", STR_bv_control, genbuf[0]); + else + strcpy(STR_new_control, STR_bv_control); + + setbfile(buf, bname, STR_new_control); + + if((fp = fopen(buf, "r"))){ + fclose(fp); + + return user_vote_one(bname, genbuf[0] - '0'); + } else + return FULLUPDATE; +} + +static int vote_results(char *bname) { + char buf[STRLEN]; + + setbfile(buf, bname, STR_bv_results); + if(more(buf, YEA) == -1) + outs("\n¥Ø«e¨S¦³¥ô¦ó§ë²¼ªºµ²ªG¡C"); + return FULLUPDATE; +} + +int b_vote_maintain() { + return vote_maintain(currboard); +} + +int b_vote() { + return user_vote(currboard); +} + +int b_results() { + return vote_results(currboard); +} diff --git a/mbbsd/voteboard.c b/mbbsd/voteboard.c new file mode 100644 index 00000000..1286d986 --- /dev/null +++ b/mbbsd/voteboard.c @@ -0,0 +1,447 @@ +/* $Id: voteboard.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/file.h> +#include "config.h" +#include "pttstruct.h" +#include "modes.h" +#include "common.h" +#include "perm.h" +#include "proto.h" + +#define VOTEBOARD "NewBoard" + +extern char currboard[]; +extern int currbid; +extern boardheader_t *bcache; +extern int currmode; +extern userec_t cuser; + +void do_voteboardreply(fileheader_t *fhdr){ + char genbuf[1024]; + char reason[60]; + char fpath[80]; + char oldfpath[80]; + char opnion[10]; + char *ptr; + FILE *fo, *fp; + fileheader_t votefile; + int len; + int i, j; + int fd; + time_t endtime, now = time(NULL); + int hastime = 0; + + + clear(); + if(!(currmode & MODE_POST)) { + move(5, 10); + outs("¹ï¤£°_¡A±z¥Ø«eµLªk¦b¦¹µoªí¤å³¹¡I"); + pressanykey(); + return; + } + + setbpath(fpath, currboard); + stampfile(fpath, &votefile); + + setbpath(oldfpath, currboard); + + strcat(oldfpath, "/"); + strcat(oldfpath, fhdr->filename); + + fp = fopen(oldfpath, "r"); + + len = strlen(cuser.userid); + + while(fgets(genbuf, 1024, fp)){ + if (!strncmp(genbuf, "³s¸pµ²§ô®É¶¡", 12)){ + hastime = 1; + ptr = strchr(genbuf, '('); + sscanf(ptr+1, "%ld", &endtime); + if (endtime < now){ + prints("³s¸p®É¶¡¤w¹L"); + pressanykey(); + fclose(fp); + return; + } + } + if (!strncmp(genbuf+4, cuser.userid, len)){ + move(5, 10); + prints("±z¤w¸g³s¸p¹L¥»½g¤F"); + opnion[0] = 'n'; + getdata(7, 0, "nקï±z¤§«eªº³s¸p¶Ü¡H(Y/N) [N]", opnion, 3, LCECHO); + if (opnion[0] != 'y'){ + fclose(fp); + return; + } + strcpy(reason, genbuf+19); + } + } + fclose(fp); + + if((fd = open(oldfpath, O_RDONLY)) == -1) + return; + flock(fd, LOCK_EX); + + fo = fopen(fpath, "w"); + + if (!fo) + return; + i = 0; + while(fo){ + j = 0; + do{ + if (read(fd, genbuf+j, 1)<=0){ + flock(fd, LOCK_UN); + close(fd); + fclose(fo); + unlink(fpath); + return; + } + j++; + }while(genbuf[j-1] !='\n'); + genbuf[j] = '\0'; + i++; + if (!strncmp("----------", genbuf, 10)) + break; + if (i > 3) + prints(genbuf); + fprintf(fo, "%s", genbuf); + } + if (!hastime){ + now += 14*24*60*60; + fprintf(fo, "³s¸pµ²§ô®É¶¡: (%ld)%s", now, ctime(&now)); + now -= 14*24*60*60; + } + + fprintf(fo, "%s", genbuf); + + do{ + if (!getdata(18, 0, "½Ð°Ý±z (Y)¤ä«ù (N)¤Ï¹ï ³oÓijÃD¡G", opnion, 3, LCECHO)){ + flock(fd, LOCK_UN); + close(fd); + fclose(fo); + unlink(fpath); + return; + } + }while(opnion[0] != 'y' && opnion[0] != 'n'); + + if (!getdata(20, 0, "½Ð°Ý±z»P³oÓijÃDªºÃö«Y©Î³s¸p²z¥Ñ¬°¦ó¡G", reason, 40, DOECHO)){ + flock(fd, LOCK_UN); + close(fd); + fclose(fo); + unlink(fpath); + return; + } + + i = 0; + + while(fo){ + i++; + j = 0; + do{ + if (read(fd, genbuf+j, 1)<=0){ + flock(fd, LOCK_UN); + close(fd); + fclose(fo); + unlink(fpath); + return; + } + j++; + }while(genbuf[j-1] !='\n'); + genbuf[j] = '\0'; + if (!strncmp("----------", genbuf, 10)) + break; + if (strncmp(genbuf+4, cuser.userid, len)) + fprintf(fo, "%3d.%s", i, genbuf+4); + else + i--; + } + if (opnion[0] == 'y') + fprintf(fo, "%3d.%-15s%-34s ¨Ó·½:%s\n", i, cuser.userid, reason,cuser.lasthost); + i = 0; + fprintf(fo, "%s", genbuf); + while(fo){ + i++; + j = 0; + do{ + if (!read(fd, genbuf+j, 1)) + break; + j++; + }while(genbuf[j-1] !='\n'); + genbuf[j] = '\0'; + if (j <= 3) + break; + if (strncmp(genbuf+4, cuser.userid, len)) + fprintf(fo, "%3d.%s", i, genbuf+4); + else + i--; + } + if (opnion[0] == 'n') + fprintf(fo, "%3d.%-15s%-34s ¨Ó·½:%s\n", i, cuser.userid, reason,cuser.lasthost); + flock(fd, LOCK_UN); + close(fd); + fclose(fo); + unlink(oldfpath); + rename(fpath, oldfpath); +} + +int do_voteboard() { + fileheader_t votefile; + char topic[100]; + char title[80]; + char genbuf[1024]; + char fpath[80]; + FILE* fp; + int temp, i; + time_t now = time(NULL); + + clear(); + if(!(currmode & MODE_POST)) { + move(5, 10); + outs("¹ï¤£°_¡A±z¥Ø«eµLªk¦b¦¹µoªí¤å³¹¡I"); + pressanykey(); + return FULLUPDATE; + } + + move(0, 0); + clrtobot(); + prints("±z¥¿¦b¨Ï¥Î PTT ªº³s¸p¨t²Î\n"); + prints("¥»³s¸p¨t²Î±N¸ß°Ý±z¤@¨Ç°ÝÃD¡A½Ð¤p¤ß¦^µª¤~¯à¶}©l³s¸p\n"); + prints("¥ô·N´£¥X³s¸p®×ªÌ¡A±N³Q¦C¤J¥»¨t²Î¤£¨üÅwªï¨Ï¥ÎªÌ³á\n"); + pressanykey(); + move(0, 0); + clrtobot(); + prints("(1)¥Ó½Ð·sª© (2)¼o°£Âª© (3)³s¸pª©¥D (4)½}§Kª©¥D\n"); + if (!strcmp(currboard, VOTEBOARD)) + prints("(5)³s¸p¤p²Õªø (6)½}§K¤p²Õªø "); + if (!strcmp(currboard, VOTEBOARD) && HAS_PERM(PERM_SYSOP)) + prints("(7)¯¸¥Á¤½§ë"); + prints("(8)¥Ó½Ð·s¸s²Õ"); + + do{ + getdata(3, 0, "½Ð¿é¤J³s¸pÃþ§O¡G", topic, 3, DOECHO); + temp = atoi(topic); + }while(temp <= 0 && temp >= 9); + + switch(temp){ + case 1: + do{ + if (!getdata(4, 0, "½Ð¿é¤J¬Ýª©^¤å¦WºÙ¡G", topic, IDLEN+1, DOECHO)) + return FULLUPDATE; + else if (invalid_brdname(topic)) + outs("¤£¬O¥¿½Tªº¬Ýª©¦WºÙ"); + else if (getbnum(topic) > 0) + outs("¥»¦WºÙ¤w¸g¦s¦b"); + else + break; + }while(temp > 0); + sprintf(title, "[¥Ó½Ð·sª©] %s", topic); + sprintf(genbuf, "%s\n\n%s%s\n%s","¥Ó½Ð·sª©", "^¤å¦WºÙ: ", topic, "¤¤¤å¦WºÙ: "); + + if (!getdata(5, 0, "½Ð¿é¤J¬Ýª©¤¤¤å¦WºÙ¡G", topic, 20, DOECHO)) + return FULLUPDATE; + strcat(genbuf, topic); + strcat(genbuf, "\n¬Ýª©Ãþ§O: "); + if (!getdata(6, 0, "½Ð¿é¤J¬Ýª©Ãþ§O¡G", topic, 20, DOECHO)) + return FULLUPDATE; + strcat(genbuf, topic); + strcat(genbuf, "\nª©¥D¦W³æ: "); + getdata(7, 0, "½Ð¿é¤Jª©¥D¦W³æ¡G", topic, IDLEN * 3 + 3, DOECHO); + strcat(genbuf, topic); + strcat(genbuf, "\n¥Ó½Ðì¦]: \n"); + outs("½Ð¿é¤J¥Ó½Ðì¦](¦Ü¦h¤¦æ)¡An²M·¡¶ñ¼g¤£µM¤£·|®Öã³á"); + for(i= 8;i<13;i++){ + if (!getdata(i, 0, "¡G", topic, 60, DOECHO)) + break; + strcat(genbuf, topic); + strcat(genbuf, "\n"); + } + if (i==8) + return FULLUPDATE; + break; + case 2: + do{ + if (!getdata(4, 0, "½Ð¿é¤J¬Ýª©^¤å¦WºÙ¡G", topic, IDLEN+1, DOECHO)) + return FULLUPDATE; + else if (getbnum(topic) <= 0) + outs("¥»¦WºÙ¨Ã¤£¦s¦b"); + else + break; + }while(temp > 0); + sprintf(title, "[¼o°£Âª©] %s", topic); + sprintf(genbuf, "%s\n\n%s%s\n","¼o°£Âª©", "^¤å¦WºÙ: ", topic); + strcat(genbuf, "\n¼o°£ì¦]: \n"); + outs("½Ð¿é¤J¼o°£ì¦](¦Ü¦h¤¦æ)¡An²M·¡¶ñ¼g¤£µM¤£·|®Öã³á"); + for(i= 8;i<13;i++){ + if (!getdata(i, 0, "¡G", topic, 60, DOECHO)) + break; + strcat(genbuf, topic); + strcat(genbuf, "\n"); + } + if (i==8) + return FULLUPDATE; + + break; + case 3: + do{ + if (!getdata(4, 0, "½Ð¿é¤J¬Ýª©^¤å¦WºÙ¡G", topic, IDLEN+1, DOECHO)) + return FULLUPDATE; + else if (getbnum(topic) <= 0) + outs("¥»¦WºÙ¨Ã¤£¦s¦b"); + else + break; + }while(temp > 0); + sprintf(title, "[³s¸pª©¥D] %s", topic); + sprintf(genbuf, "%s\n\n%s%s\n%s%s","³s¸pª©¥D", "^¤å¦WºÙ: ", topic, "¥Ó½Ð ID : ", cuser.userid); + strcat(genbuf, "\n¥Ó½Ð¬F¨£: \n"); + outs("½Ð¿é¤J¥Ó½Ð¬F¨£(¦Ü¦h¤¦æ)¡An²M·¡¶ñ¼g¤£µM¤£·|®Öã³á"); + for(i= 8;i<13;i++){ + if (!getdata(i, 0, "¡G", topic, 60, DOECHO)) + break; + strcat(genbuf, topic); + strcat(genbuf, "\n"); + } + if (i==8) + return FULLUPDATE; + break; + case 4: + do{ + if (!getdata(4, 0, "½Ð¿é¤J¬Ýª©^¤å¦WºÙ¡G", topic, IDLEN+1, DOECHO)) + return FULLUPDATE; + else if ((i = getbnum(topic)) <= 0) + outs("¥»¦WºÙ¨Ã¤£¦s¦b"); + else + break; + }while(temp > 0); + sprintf(title, "[½}§Kª©¥D] %s", topic); + sprintf(genbuf, "%s\n\n%s%s\n%s","½}§Kª©¥D", "^¤å¦WºÙ: ", topic, "ª©¥D ID : "); + do{ + if (!getdata(6, 0, "½Ð¿é¤Jª©¥DID¡G", topic, IDLEN + 1, DOECHO)) + return FULLUPDATE; + else if (!userid_is_BM(topic, bcache[i-1].BM)) + outs("¤£¬O¸Óª©ªºª©¥D"); + else + break; + }while(temp > 0); + strcat(genbuf, topic); + strcat(genbuf, "\n½}§Kì¦]: \n"); + outs("½Ð¿é¤J½}§Kì¦](¦Ü¦h¤¦æ)¡An²M·¡¶ñ¼g¤£µM¤£·|®Öã³á"); + for(i= 8;i<13;i++){ + if (!getdata(i, 0, "¡G", topic, 60, DOECHO)) + break; + strcat(genbuf, topic); + strcat(genbuf, "\n"); + } + if (i==8) + return FULLUPDATE; + break; + case 5: + if (!getdata(4, 0, "½Ð¿é¤J¤p²Õ¤¤^¤å¦WºÙ¡G", topic, 30, DOECHO)) + return FULLUPDATE; + sprintf(title, "[³s¸p¤p²Õªø] %s", topic); + sprintf(genbuf, "%s\n\n%s%s\n%s%s","³s¸p¤p²Õªø", "¤p²Õ¦WºÙ: ", topic, "¥Ó½Ð ID : ", cuser.userid); + strcat(genbuf, "\n¥Ó½Ð¬F¨£: \n"); + outs("½Ð¿é¤J¥Ó½Ð¬F¨£(¦Ü¦h¤¦æ)¡An²M·¡¶ñ¼g¤£µM¤£·|®Öã³á"); + for(i= 8;i<13;i++){ + if (!getdata(i, 0, "¡G", topic, 60, DOECHO)) + break; + strcat(genbuf, topic); + strcat(genbuf, "\n"); + } + if (i==8) + return FULLUPDATE; + break; + case 6: + + if (!getdata(4, 0, "½Ð¿é¤J¤p²Õ¤¤^¤å¦WºÙ¡G", topic, 30, DOECHO)) + return FULLUPDATE; + sprintf(title, "[½}§K¤p²Õªø] %s", topic); + sprintf(genbuf, "%s\n\n%s%s\n%s","½}§K¤p²Õªø", "¤p²Õ¦WºÙ: ", topic, "¤p²Õªø ID : "); + if (!getdata(6, 0, "½Ð¿é¤J¤p²ÕªøID¡G", topic, IDLEN + 1, DOECHO)) + return FULLUPDATE; + strcat(genbuf, topic); + strcat(genbuf, "\n½}§Kì¦]: \n"); + outs("½Ð¿é¤J½}§Kì¦](¦Ü¦h¤¦æ)¡An²M·¡¶ñ¼g¤£µM¤£·|®Öã³á"); + for(i= 8;i<13;i++){ + if (!getdata(i, 0, "¡G", topic, 60, DOECHO)) + break; + strcat(genbuf, topic); + strcat(genbuf, "\n"); + } + if (i==8) + return FULLUPDATE; + break; + case 7: + if (!HAS_PERM(PERM_SYSOP)) + return FULLUPDATE; + if (!getdata(4, 0, "½Ð¿é¤J¤½§ë¥DÃD¡G", topic, 30, DOECHO)) + return FULLUPDATE; + sprintf(title, "%s %s", "[¯¸¥Á¤½§ë]", topic); + sprintf(genbuf, "%s\n\n%s%s\n","¯¸¥Á¤½§ë", "¤½§ë¥DÃD: ", topic); + strcat(genbuf, "\n¤½§ëì¦]: \n"); + outs("½Ð¿é¤J¤½§ëì¦](¦Ü¦h¤¦æ)¡An²M·¡¶ñ¼g¤£µM¤£·|®Öã³á"); + for(i= 8;i<13;i++){ + if (!getdata(i, 0, "¡G", topic, 60, DOECHO)) + break; + strcat(genbuf, topic); + strcat(genbuf, "\n"); + } + if (i==8) + return FULLUPDATE; + break; + case 8: + if(!getdata(4, 0, "½Ð¿é¤J¸s²Õ¤¤^¤å¦WºÙ¡G", topic, 30, DOECHO)) + return FULLUPDATE; + sprintf(title, "[¥Ó½Ð·s¸s²Õ] %s", topic); + sprintf(genbuf, "%s\n\n%s%s\n%s%s","¥Ó½Ð¸s²Õ", "¸s²Õ¦WºÙ: ", topic, "¥Ó½Ð ID : ", cuser.userid); + strcat(genbuf, "\n¥Ó½Ð¬F¨£: \n"); + outs("½Ð¿é¤J¥Ó½Ð¬F¨£(¦Ü¦h¤¦æ)¡An²M·¡¶ñ¼g¤£µM¤£·|®Öã³á"); + for(i= 8;i<13;i++){ + if (!getdata(i, 0, "¡G", topic, 60, DOECHO)) + break; + strcat(genbuf, topic); + strcat(genbuf, "\n"); + } + if (i==8) + return FULLUPDATE; + break; + default: + return FULLUPDATE; + } + strcat(genbuf, "³s¸pµ²§ô®É¶¡: "); + now += 14*24*60*60; + sprintf(topic, "(%ld)", now); + strcat(genbuf, topic); + strcat(genbuf, ctime(&now)); + 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", "§@ªÌ: ", cuser.userid, + "¬ÝªO: ", currboard, + "¼ÐÃD: ", title, + "®É¶¡: ", ctime(&now)); + fprintf(fp, "%s\n", genbuf); + fclose(fp); + strcpy(votefile.owner, cuser.userid); + strcpy(votefile.title, title); + votefile.savemode = 'S'; + 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 new file mode 100644 index 00000000..786add30 --- /dev/null +++ b/mbbsd/xyz.c @@ -0,0 +1,448 @@ +/* $Id: xyz.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <unistd.h> +#include <signal.h> +#include <time.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "modes.h" +#include "proto.h" + +extern char *fn_note_ans; +extern int b_lines; /* Screen bottom line number: t_lines-1 */ +extern char *BBSName; +extern char fromhost[]; +extern userinfo_t *currutmp; +extern int curr_idle_timeout; +extern userec_t cuser; + +/* ¦UºØ²Îp¤Î¬ÛÃö¸ê°T¦Cªí */ +/* Ptt90¦~«×¤j¾ÇÁp©Û¬dº]¨t²Î */ +int x_90() { + extern char dict[21], database[41]; + strcpy(dict, "(90)ã¦ÒÃÒ¸¹/©m¦W/¾Ç®Õ/¬ì¨t/Ãþ²Õ"); + strcpy(database, "etc/90"); + use_dict(); + return 0; +} + +/* Ptt89¦~«×¤j¾ÇÁp©Û¬dº]¨t²Î */ +int x_89() { + extern char dict[21], database[41]; + strcpy(dict, "(89)ã¦ÒÃÒ¸¹/©m¦W/¾Ç®Õ/¬ì¨t/Ãþ²Õ"); + strcpy(database, "etc/89"); + use_dict(); + return 0; +} +/* Ptt88¦~«×¤j¾ÇÁp©Û¬dº]¨t²Î */ +int x_88() { + extern char dict[21], database[41]; + + strcpy(dict, "(88)ã¦ÒÃÒ¸¹/©m¦W/¾Ç®Õ/¬ì¨t/Ãþ²Õ"); + strcpy(database, "etc/88"); + use_dict(); + return 0; +} +/* Ptt87¦~«×¤j¾ÇÁp©Û¬dº]¨t²Î */ +int x_87() { + extern char dict[21], database[41]; + + strcpy(dict, "(87)ã¦ÒÃÒ¸¹/©m¦W/¾Ç®Õ/¬ì¨t"); + strcpy(database, "etc/87"); + use_dict(); + return 0; +} + +/* Ptt86¦~«×¤j¾ÇÁp©Û¬dº]¨t²Î */ +int x_86() { + extern char dict[21], database[41]; + + strcpy(dict, "(86)ã¦ÒÃÒ¸¹/©m¦W/¾Ç®Õ/¬ì¨t"); + strcpy(database, "etc/86"); + use_dict(); + return 0; +} + +int x_boardman() { + more("etc/topboardman", YEA); + return 0; +} + +int x_user100() { + more("etc/topusr100", YEA); + return 0; +} + +int x_history() { + more("etc/history", YEA); + return 0; +} + +#ifdef HAVE_X_BOARDS +static int x_boards() { + more("etc/topboard.tmp", YEA); + return 0; +} +#endif + +int x_birth() { + more("etc/birth.today", YEA); + return 0; +} + +int x_weather() { + more("etc/weather.tmp", YEA); + return 0; +} + +int x_stock() { + more("etc/stock.tmp", YEA); + return 0; +} + +int x_note() { + more(fn_note_ans, YEA); + return 0; +} + +int x_issue() { + more("etc/day", YEA); + return 0; +} + +int x_week() { + more("etc/week", YEA); + return 0; +} + +int x_today() { + more("etc/today", YEA); + return 0; +} + +int x_yesterday() { + more("etc/yesterday", YEA); + return 0; +} + +int x_login() { + more("etc/Welcome_login", YEA); + return 0; +} + +#ifdef HAVE_INFO +static int x_program() { + more("etc/version", YEA); + return 0; +} +#endif + +#ifdef HAVE_LICENSE +static int x_gpl() { + more("etc/GPL", YEA); + return 0; +} +#endif + +/* Â÷¶} BBS ¯¸ */ +int note() { + static char *fn_note_tmp = "note.tmp"; + static 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 { + time_t date; + char userid[IDLEN + 1]; + char username[19]; + char buf[3][80]; + } notedata_t; + notedata_t myitem; + + if(cuser.money < 5) { + outmsg("\033[1;41m «u§r! n§ë¤»È¤~¯à¯d¨¥...¨S¿úC..\033[m"); + clrtoeol(); + refresh(); + 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], 78, + 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); + strncpy(myitem.username, cuser.username, 18); + myitem.username[18] = '\0'; + time(&(myitem.date)); + + /* begin load file */ + if((foo = fopen(".note", "a")) == NULL) + return 0; + + if((fp = fopen(fn_note_ans, "w")) == NULL) + return 0; + + if((fx = open(fn_note_tmp, O_WRONLY | O_CREAT, 0644)) <= 0) + 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("\033[1;31;44m¡ó¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢t" + "\033[37m»Ä²¢W»¶ªO\033[31m¢u¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¡ó" + "\033[m\n", fp); + collect = 1; + + while(total) { + sprintf(buf, "\033[1;31m¢~¢t\033[32m %s \033[37m(%s)", + myitem.userid, myitem.username); + len = strlen(buf); + + for(i = len ; i < 73; i++) + strcat(buf, " "); + sprintf(buf2, " \033[1;36m%.14s\033[31m ¢u¢¡\033[m\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, "\033[1;31m¢x\033[m%-74.74s\033[1;31m¢x\033[m\n", + myitem.buf[i]); + if(collect) + fprintf(foo, "\033[1;31m¢x\033[m%-74.74s\033[1;31m¢x\033[m\n", + myitem.buf[i]); + } + fputs("\033[1;31m¢¢¢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¢£\033[m\n",fp); + + if(collect) { + fputs("\033[1;31m¢¢¢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¢£\033[m\n", foo); + fclose(foo); + collect = 0; + } + + write(fx, &myitem, sizeof(myitem)); + + if(--total) + read(fd, (char *) &myitem, sizeof(myitem)); + } + fputs("\033[1;31;44m¡ó¢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¡ó\033[m\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() { + 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); + } + } + } + } + + move(12, 0); + clrtobot(); + prints("%16s %-18sÅv³d¹º¤À\n\n", "½s¸¹", "¯¸ªø ID"); + + for(i = 0; i < j; i++) + prints("%15d. \033[1;%dm%-16s%s\033[0m\n", + i + 1, 31 + i % 7, sysoplist[i].userid, sysoplist[i].duty); + prints("%-14s0. \033[1;%dmÂ÷¶}\033[0m", "", 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) { + clear(); + do_send(sysoplist[i].userid, NULL); + } + } +} + +int m_sysop() { + setutmpmode(MSYSOP); + mail_sysop(); + return 0; +} + +int Goodbye() { + extern void movie(); + char genbuf[100]; + + getdata(b_lines - 1, 0, "±z½T©wnÂ÷¶}¡i " BBSNAME " ¡j¶Ü(Y/N)¡H[N] ", + genbuf, 3, LCECHO); + + if(*genbuf != 'y') + return 0; + + movie(999); + if(cuser.userlevel) { + getdata(b_lines - 1, 0, + "(G)ÀH·¦Ó³u (M)¦«¹Ú¯¸ªø (N)»Ä²¢W»¶¬y¨¥ª©¡H[G] ", + genbuf, 3, LCECHO); + if(genbuf[0] == 'm') + mail_sysop(); + else if(genbuf[0] == 'n') + note(); + } + + clear(); + prints("\033[1;36m¿Ë·Rªº \033[33m%s(%s)\033[36m¡A§O§Ñ¤F¦A«×¥úÁ{\033[45;33m" + " %s \033[40;36m¡I\n¥H¤U¬O±z¦b¯¸¤ºªºµù¥U¸ê®Æ:\033[0m\n", + cuser.userid, cuser.username, BBSName); + user_display(&cuser, 0); + pressanykey(); + + more("etc/Logout",NA); + pressanykey(); + u_exit("EXIT "); + return QUIT; +} + +/* ¤ä´©¥~±¾µ{¦¡ : tin¡Bgopher¡Bwww¡Bbbsnet¡Bgame¡Bcsh */ +#define LOOKFIRST (0) +#define LOOKLAST (1) +#define QUOTEMODE (2) +#define MAXCOMSZ (1024) +#define MAXARGS (40) +#define MAXENVS (20) +#define BINDIR BBSHOME"/bin/" + +#define MAXPATHLEN 256 + +#ifdef HAVE_TIN +static int x_tin() { + clear(); + return exec_cmd(NEWS, YEA, "bin/tin.sh", "TIN"); +} +#endif + +#ifdef HAVE_GOPHER +static int x_gopher() { + clear(); + return exec_cmd(GOPHER, YEA, "bin/gopher.sh", "GOPHER"); +} +#endif + +#ifdef HAVE_WWW +static int x_www() { + return exec_cmd(WWW, NA, "bin/www.sh", "WWW"); +} +#endif + +#ifdef HAVE_IRC +static int x_irc() { + return exec_cmd(XMODE, NA, "bin/irc.sh", "IRC"); +} +#endif + +#ifdef HAVE_ARCHIE +static int x_archie() { + char buf[STRLEN], ans[4]; + char genbuf1[100], genbuf2[200]; + char *s; + + setutmpmode(ARCHIE); + clear(); + outs("\nÅwªï¥úÁ{¡i\033[1;33;44m" BBSNAME "\033[m¡j¨Ï¥Î " + "\033[32mARCHIE\033[m ¥\\¯à\n"); + outs("\n¥»¥\\¯à±N¬°±z¦C¥X¦bþÓ FTP ¯¸¦s¦³±z±ý´M§äªºÀÉ®×.\n"); + outs("\n½Ð¿é¤J±ý·j´Mªº¦r¦ê, ©Îª½±µ«ö <ENTER> ¨ú®ø¡C\n"); + outs("\n coder by Harimau\n"); + outs(" modified by Leeym\n"); + getdata(13,0,"·j´M¦r¦ê¡G",buf,20,DOECHO,0); + if(buf[0]=='\0') { + prints("\n¨ú®ø·j´M.....\n"); + pressanykey(); + return; + } + + for(s = buf; *s != '\0'; s++) { + if(isspace(*s)) { + prints("\n¤@¦¸¥u¯à·j´M¤@Ó¦r¦ê°Õ, ¤£¯à¤Ó³g¤ß³á!!"); + pressanykey(); + return; + } + } + bbssetenv("ARCHIESTRING", buf); + exec_cmd(ARCHIE, YEA, "bin/archie.sh", ARCHIE); + log_usies("ARCHIE", ""); + strcpy(genbuf1, buf); + sprintf(buf, BBSHOME "/tmp/archie.%s", cuser.userid); + if(dashf(buf)) { + getdata(0, 0, "n±Nµ²ªG±H¦^«H½c¶Ü(Y/N)¡H[N]", ans, 3, DOECHO,0); + if(*ans == 'y') { + fileheader_t mhdr; + char title[128], buf1[80]; + FILE* fp; + + sethomepath(buf1, cuser.userid); + stampfile(buf1, &mhdr); + strcpy(mhdr.owner, cuser.userid); + sprintf(genbuf2, "Archie ·j´MÀÉ®×: %s µ²ªG", genbuf1); + strcpy(mhdr.title, genbuf2); + mhdr.savemode = 0; + mhdr.filemode = 0; + sethomedir(title, cuser.userid); + append_record(title, &mhdr, sizeof(mhdr)); + Link(buf, buf1); + } + more( buf, YEA); + unlink (buf); + } +} +#endif /* HAVE_ARCHIE */ |