精華區beta SetupBBS 關於我們 聯絡資訊
/*-------------------------------------------------------*/ /* xyz.c ( NTHU CS MapleBBS Ver 2.36 ) */ /*-------------------------------------------------------*/ /* target : system toolbox routines */ /* create : 95/03/29 */ /* update : 95/12/15 */ /*-------------------------------------------------------*/ #include "bbs.h" /* ----------------------------------------------------- */ /* 各種統計及相關資訊列表 */ /* ----------------------------------------------------- */ int /* Ptt86年度大學聯招查榜系統 */ x_86() { extern char dict[21],database[41]; strcpy(dict,"准考證號/姓名/學校/科系"); strcpy(database,"etc/86"); use_dict(); } int x_user() { more("etc/topusr", YEA); return 0; } int x_user100() { more("etc/topusr100", YEA); return 0; } int x_history() { more("etc/history", YEA); return 0; } x_boards() { more("etc/topboard.tmp", YEA); return 0; } 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 x_program() { more("etc/version", YEA); return 0; } #endif #ifdef HAVE_License x_gpl() { more("etc/GPL", YEA); return 0; } #endif int Welcome() { more("etc/Welcome", YEA); return 0; } int show_hint_message() { struct timeval timep; struct timezone timezp; int i, j, msgNum; FILE *hintp; char msg[136]; if (!(hintp = fopen("etc/hint", "r"))) return 0; fgets(msg, 135, hintp); msgNum = atoi(msg); gettimeofday(&timep, &timezp); i = (int) timep.tv_sec%(msgNum + 1); /* 最新的一篇機會加倍 */ if (i == msgNum) i--; j = 0; while (j < i) { fgets(msg, 135, hintp); msg[1] = '\0'; if (!strcmp(msg,"#")) j++; } move(12, 0); clrtobot(); fgets(msg, 135, hintp); prints("系統功\能精靈: 您可曾知道?\n"); prints(" %s", msg); fgets(msg, 135, hintp); prints(" %s", msg); pressanykey(); fclose(hintp); } /* ----------------------------------------------------- */ /* 離開 BBS 站 */ /* ----------------------------------------------------- */ void note() { static char *fn_note_tmp = "note.tmp"; static char *fn_note_dat = "note.dat"; int total, i, collect, len; struct stat st; char buf[256], buf2[80], *p; int fd, fx; FILE *fp, *foo; struct notedata { time_t date; char userid[IDLEN + 1]; char username[19]; char buf[3][80]; }; struct notedata myitem; setutmpmode(EDNOTE); do { myitem.buf[0][0] = myitem.buf[1][0] = myitem.buf[2][0] = '\0'; move(12, 0); clrtobot(); outs("\n請留言 (至多三行),按[Enter]結束"); for (i = 0; (i < 3) && getdata(16 + i, 0, ":", myitem.buf[i], 78, DOECHO); i++); getdata(b_lines - 1, 0, "(S)儲存 (E)重新來過 (Q)取消?[S] ", buf, 3, LCECHO); /* woju */ if (buf[0] == 'q' || i == 0 && *buf != 'e') return; } while (buf[0] == 'e'); 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; if ((fp = fopen(fn_note_ans, "w")) == NULL) return; if ((fx = open(fn_note_tmp, O_WRONLY | O_CREAT, 0644)) <= 0) return; if ((fd = open(fn_note_dat, O_RDONLY)) == -1) { total = 1; } else if (fstat(fd, &st) != -1) { total = st.st_size / sizeof(struct notedata) + 1; if (total > MAX_NOTE) total = MAX_NOTE; } fputs(" ● 酸 甜 苦 辣 流 言 版 ● \n\n",fp); collect = 1; while (total) { sprintf(buf, "Υ %s (%s)", myitem.userid, myitem.username); len = strlen(buf); strcat(buf, " " + (len & 1)); for (i = len >> 1; i < 41; i++) strcat(buf, "▄"); sprintf(buf2, " %.14s Υ\n", Cdate(&(myitem.date))); strcat(buf, buf2); fputs(buf, fp); if (collect) fputs(buf, foo); sprintf(buf, "%s\n%s\n%s\n", myitem.buf[0], myitem.buf[1], myitem.buf[2]); fputs(buf, fp); if (collect) { fputs(buf, foo); fclose(foo); collect = 0; } write(fx, &myitem, sizeof(myitem)); if (--total) read(fd, (char *) &myitem, sizeof(myitem)); } fclose(fp); close(fd); close(fx); Rename(fn_note_tmp, fn_note_dat); more(fn_note_ans, YEA); } static void mail_sysop() { FILE *fp; char genbuf[200]; if (fp = fopen("etc/sysop", "r")) { int i, j; char *ptr; struct SYSOPLIST { char userid[IDLEN + 1]; char duty[40]; } 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權責劃分\n\n", "編號", "站長 ID"/*, msg_seperator*/); for (i = 0; i < j; i++) { prints("%15d. m%-16s%s\n", i + 1, 31 + i % 7, sysoplist[i].userid, sysoplist[i].duty); } prints("%-14s0. m離開", "", 31 + j % 7); getdata(b_lines - 1, 0, " 請輸入代碼[0]:", 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, "您確定要離開【 " BOARDNAME " 】嗎(Y/N)?[N] ", genbuf, 3, LCECHO); if (*genbuf != 'y') return 0; movie(999); if (cuser.userlevel) { getdata(b_lines - 1, 0, "(G)隨風而逝 (M)托夢站長 (N)酸甜苦辣流言版?[G] ", genbuf, 3, LCECHO); if (genbuf[0] == 'm') mail_sysop(); else if (genbuf[0] == 'n') note(); } clear(); prints("親愛的 %s(%s),別忘了再度光臨" " %s !\n以下是您在站內的註冊資料:\n", cuser.userid, cuser.username, BoardName); user_display(&cuser, 0); pressanykey(); more("etc/Logout",NA); pressanykey(); if (currmode) u_exit("EXIT "); sleep(1); reset_tty(); exit(0); } /* ----------------------------------------------------- */ /* 支援外掛程式 : tin、gopher、www、bbsnet、game、csh */ /* ----------------------------------------------------- */ #ifdef HAVE_EXTERNAL #define LOOKFIRST (0) #define LOOKLAST (1) #define QUOTEMODE (2) #define MAXCOMSZ (1024) #define MAXARGS (40) #define MAXENVS (20) #define BINDIR BBSHOME"/bin/" char *bbsenv[MAXENVS]; int numbbsenvs = 0; int bbssetenv(env, val) char *env, *val; { register int i, len; extern char *malloc(); if (numbbsenvs == 0) bbsenv[0] = NULL; len = strlen(env); for (i = 0; bbsenv[i]; i++) if (!ci_strncmp(env, bbsenv[i], len)) break; if (i >= MAXENVS) return -1; if (bbsenv[i]) free(bbsenv[i]); else bbsenv[++numbbsenvs] = NULL; bbsenv[i] = malloc(strlen(env) + strlen(val) + 2); strcpy(bbsenv[i], env); strcat(bbsenv[i], "="); strcat(bbsenv[i], val); } #define MAXPATHLEN 256 int do_exec(com, wd) char *com, *wd; { char genbuf[200]; char path[MAXPATHLEN]; char pcom[MAXCOMSZ]; char *arglist[MAXARGS]; char *tz; register int i, len; register int argptr; register char *lparse; int status, w; pid_t pid; int pmode; void (*isig) (), (*qsig) (); strncpy(path, BINDIR, MAXPATHLEN); strncpy(pcom, com, MAXCOMSZ); len = MIN(strlen(com) + 1, MAXCOMSZ); pmode = LOOKFIRST; for (i = 0, argptr = 0; i < len; i++) { if (pcom[i] == '\0') break; if (pmode == QUOTEMODE) { if (pcom[i] == '\001') { pmode = LOOKFIRST; pcom[i] = '\0'; continue; } continue; } if (pcom[i] == '\001') { pmode = QUOTEMODE; arglist[argptr++] = &pcom[i + 1]; if (argptr + 1 == MAXARGS) break; continue; } if (pmode == LOOKFIRST) if (pcom[i] != ' ') { arglist[argptr++] = &pcom[i]; if (argptr + 1 == MAXARGS) break; pmode = LOOKLAST; } else continue; if (pcom[i] == ' ') { pmode = LOOKFIRST; pcom[i] = '\0'; } } arglist[argptr] = NULL; if (argptr == 0) return -1; if (*arglist[0] == '/') strncpy(path, arglist[0], MAXPATHLEN); else strncat(path, arglist[0], MAXPATHLEN); reset_tty(); alarm(0); if ((pid = vfork()) == 0) { if (wd) if (chdir(wd)) { fprintf(stderr, "Unable to chdir to '%s'\n", wd); exit(-1); } bbssetenv("PATH", "/bin:."); bbssetenv("TERM", "vt100"/* cuser.termtype */); bbssetenv("USER", cuser.userid); bbssetenv("USERNAME", cuser.username); /* added for tin's HOME and EDITOR */ /* woju */ sprintf(genbuf, "/home/bbs/home/%s", cuser.userid); bbssetenv("HOME", genbuf); bbssetenv("EDITOR", "/bin/ve"); /* end */ /* added for tin's reply to */ bbssetenv("REPLYTO", cuser.email); bbssetenv("FROMHOST", fromhost); /* end of insertion */ if ((tz = getenv("TZ")) != NULL) bbssetenv("TZ", tz); if (numbbsenvs == 0) bbsenv[0] = NULL; execve(path, arglist, bbsenv); fprintf(stderr, "EXECV FAILED... path = '%s'\n", path); exit(-1); } isig = signal(SIGINT, SIG_IGN); qsig = signal(SIGQUIT, SIG_IGN); while ((w = wait(&status)) != pid && w != 1) /* NULL STATEMENT */ ; signal(SIGINT, isig); signal(SIGQUIT, qsig); restore_tty(); #ifdef DOTIMEOUT alarm(IDLE_TIMEOUT); #endif return ((w == -1) ? w : status); } int exec_cmd(umode, pager, cmdfile, mesg) char *cmdfile, *mesg; { char buf[64]; int save_pager; if (!dashf(cmdfile)) { move(2, 0); prints("很抱歉, 本站不提供 %s (%s) 功\能.", mesg, cmdfile); return 0; } save_pager = currutmp->pager; if (pager == NA) { currutmp->pager = pager; } setutmpmode(umode); sprintf(buf, "/bin/sh %s", cmdfile); reset_tty(); do_exec(buf, NULL); restore_tty(); currutmp->pager = save_pager; clear(); return 0; } /* #ifdef HAVE_CAL x_cal() { char k; int save_pager; save_pager = currutmp->pager; currutmp->pager = 2; setutmpmode(CAL); reset_tty(); clear(); outs("小計算機 <請按任意鍵啟動> "); k=igetch(); do_exec("/home/bbs/bin/calc", NULL); restore_tty(); currutmp->pager = save_pager; } #endif */ int x_cdict() { char k; int save_pager; save_pager = currutmp->pager; currutmp->pager = 2; setutmpmode(CDICT); reset_tty(); clear(); outs("英漢翻譯機 <請按任意鍵啟動> "); k=igetch(); do_exec("/usr/bin/cdict", NULL); restore_tty(); currutmp->pager = save_pager; } #ifdef HAVE_TIN x_tin() { clear(); return exec_cmd(NEWS, YEA, "bin/tin.sh", "TIN"); } #endif #ifdef HAVE_GOPHER x_gopher() { clear(); return exec_cmd(GOPHER, YEA, "bin/gopher.sh", "GOPHER"); } #endif #ifdef HAVE_MJ x_mj() { char buf[64]; int save_pager; clear(); save_pager = currutmp->pager; currutmp->pager = 2; setutmpmode(MJ); reset_tty(); sprintf(buf, "/home/bbs/bin/qkmj95p4-linux 140.112.28.167 7001"); do_exec(buf, NULL); restore_tty(); currutmp->pager = save_pager; clear(); prints(" 謝謝 %s 的光臨!!\n", cuser.userid); outs(" 歡迎下次再來摸兩圈啊!! ^o^\n"); pressanykey(); clear(); return 0; } #endif #ifdef HAVE_BIG2 x_big2() { char buf[64]; int save_pager; clear(); save_pager = currutmp->pager; currutmp->pager = 2; setutmpmode(BIG2); reset_tty(); sprintf(buf, "/home/bbs/bin/big2"); do_exec(buf, NULL); restore_tty(); currutmp->pager = save_pager; clear(); prints(" 謝謝 %s 的光臨!!\n", cuser.userid); outs(" 歡迎下次再來湊四腳啊!! ^o^\n"); pressanykey(); clear(); return 0; } #endif #ifdef HAVE_WWW x_www() { return exec_cmd(WWW, NA, "bin/www.sh", "WWW"); } #endif /* HAVE_WWW */ #ifdef HAVE_IRC x_irc() { return exec_cmd(XMODE, NA, "bin/irc.sh", "IRC"); } #endif /* HAVE_IRC */ #ifdef HAVE_ADM_SHELL x_csh() { int save_pager; clear(); refresh(); reset_tty(); save_pager = currutmp->pager; currutmp->pager = 2; #ifdef HAVE_REPORT report("shell out"); #endif #ifdef SYSV do_exec("sh", NULL); #else do_exec("tcsh", NULL); #endif restore_tty(); currutmp->pager = save_pager; clear(); return 0; } #endif /* NO_ADM_SHELL */ #ifdef BBSDOORS x_bbsnet() /* Bill Schwartz */ { int save_pager = currutmp->pager; currutmp->pager = 2; setutmpmode(BBSNET); /* bbsnet.sh is a shell script that can be customized without */ /* having to recompile anything. If you edit it while someone */ /* is in bbsnet they will be sent back to the xyz menu when they */ /* leave the system they are currently in. */ clear(); reset_tty(); do_exec("bbsnet.sh", NULL); restore_tty(); currutmp->pager = save_pager; clear(); return 0; } #endif #ifdef HAVE_MUD x_mud() { char buf[64]; int save_pager; clear(); outs("歡迎進入 【批踢踢實業坊】 來玩虛擬聊天場\n"); outs("Ptt: 嘿嘿...經驗值是從bbs上表現算的唷\n"); outs(" 版主加七級,站長一律65級.\n"); outs(" 請用自己在bbs上的ID與passwd進入\n\n"); pressanykey(); save_pager = currutmp->pager; currutmp->pager = 2; setutmpmode(DRINK); reset_tty(); system("stty pass8"); system("telnet 140.112.171.204 4000 "); restore_tty(); currutmp->pager = save_pager; clear(); prints("謝謝 %s 的光臨!!\n", cuser.userid); outs("歡迎下次再來啊!! ^o^\n"); pressanykey(); clear(); return 0; } #endif #ifdef HAVE_BRIDGE x_bridge() { char buf[64]; int save_pager; clear(); outs("歡迎進入 【批踢踢實業坊】 來玩網路橋牌\n"); outs("Ptt: 玩橋牌不用賭錢,\n"); outs(" 還可以和大家連誼,多玩有益健康喔!! *^_^*\n\n"); outs("SYSOP: 嗯嗯..還可以預防老人癡呆症!!\n"); outs(" (別不相信,這有根據的!!)\n\n"); pressanykey(); save_pager = currutmp->pager; currutmp->pager = 2; setutmpmode(BRIDGE); reset_tty(); sprintf(buf, "/home/bbs/bin/okbridge -n %s -s 140.112.171.204", cuser.userid); do_exec(buf, NULL); restore_tty(); currutmp->pager = save_pager; clear(); prints("謝謝 %s 的光臨!!\n", cuser.userid); outs("歡迎下次再來橋一下啊!! ^o^\n"); pressanykey(); clear(); return 0; } #endif #ifdef HAVE_GAME x_game() { int save_pager = currutmp->pager; currutmp->pager = 2; setutmpmode(BBSNET); /* bbsnet.sh is a shell script that can be customized without */ /* having to recompile anything. If you edit it while someone */ /* is in bbsnet they will be sent back to the xyz menu when they */ /* leave the system they are currently in. */ reset_tty(); do_exec("game.sh", NULL); restore_tty(); currutmp->pager = save_pager; clear(); return 0; } #endif /* HAVE_GAME */ #ifdef HAVE_ARCHIE x_archie() { char buf[STRLEN], ans[4]; char genbuf1[100], genbuf2[200]; char *s; setutmpmode(ARCHIE); clear(); outs("\n歡迎光臨【批踢踢實業坊】使用 ARCHIE 功\能\n"); outs("\n本功\能將為您列出在哪個 FTP 站存有您欲尋找的檔案.\n"); outs("\n請輸入欲搜尋的字串, 或直接按 <ENTER> 取消。\n"); outs("\n coder by Harimau\n"); outs(" modified by Leeym\n"); getdata(13,0,"搜尋字串:",buf,20,DOECHO,0); if (buf[0]=='\0') { prints("\n取消搜尋.....\n"); pressanykey(); return; } for(s=buf;*s != '\0';s++) { if(isspace(*s)) { prints("\n一次只能搜尋一個字串啦, 不能太貪心喔!!"); pressanykey(); return; } } bbssetenv("ARCHIESTRING",buf); exec_cmd( ARCHIE, YEA, "bin/archie.sh",ARCHIE); log_usies("ARCHIE",""); strcpy(genbuf1, buf); sprintf(buf,"/home/bbs/tmp/archie.%s",cuser.userid); if (dashf(buf)) { getdata(0, 0, "要將結果寄回信箱嗎(Y/N)?[N]", ans, 3, DOECHO,0); if (*ans == 'y') { fileheader mhdr; char title[128], buf1[80]; FILE* fp; sethomepath(buf1, cuser.userid); stampfile(buf1, &mhdr); strcpy(mhdr.owner, cuser.userid); sprintf(genbuf2, "Archie 搜尋檔案: %s 結果", 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 */ #endif /* HAVE_EXTERNAL */