/*-------------------------------------------------------*/
/* 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 */