summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkcwu <kcwu@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2003-06-28 16:54:02 +0800
committerkcwu <kcwu@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2003-06-28 16:54:02 +0800
commit78192b342f0e13ded69d081292fef532e5fca76f (patch)
tree7de61a5b887c3bb7355e9bd549d5f491806c48ea
parentbe6bc296022a84e06c7396e112725fdeeeb4bf7d (diff)
downloadpttbbs-78192b342f0e13ded69d081292fef532e5fca76f.tar
pttbbs-78192b342f0e13ded69d081292fef532e5fca76f.tar.gz
pttbbs-78192b342f0e13ded69d081292fef532e5fca76f.tar.bz2
pttbbs-78192b342f0e13ded69d081292fef532e5fca76f.tar.lz
pttbbs-78192b342f0e13ded69d081292fef532e5fca76f.tar.xz
pttbbs-78192b342f0e13ded69d081292fef532e5fca76f.tar.zst
pttbbs-78192b342f0e13ded69d081292fef532e5fca76f.zip
remove gopher mode support, there is security hole
git-svn-id: http://opensvn.csie.org/pttbbs/pttbbs/trunk/pttbbs@987 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
-rw-r--r--mbbsd/announce.c604
1 files changed, 8 insertions, 596 deletions
diff --git a/mbbsd/announce.c b/mbbsd/announce.c
index 3b101816..02ea115d 100644
--- a/mbbsd/announce.c
+++ b/mbbsd/announce.c
@@ -1,344 +1,8 @@
-/* $Id: announce.c,v 1.27 2003/06/21 17:10:31 victor Exp $ */
+/* $Id: announce.c,v 1.28 2003/06/28 08:54:02 kcwu Exp $ */
#include "bbs.h"
-static void
-g_showmenu(gmenu_t * pm)
-{
- char *mytype = "編 選 絲路之旅";
- char *title, ch;
- int n, max;
- item_t *item;
-
- showtitle("精華文章", pm->mtitle);
- prints(" \033[1;36m編號 標 題%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 《精華區》尚在吸取天地間的日精月華 :)");
-
- move(b_lines, 1);
- outs(pm->level ?
- "\033[34;46m 【板 主】 \033[31;47m (h)\033[30m說明 "
- "\033[31m(q/←)\033[30m離開 \033[31m(n)\033[30m新增文章 "
- "\033[31m(g)\033[30m新增目錄 \033[31m(e)\033[30m編輯檔案 \033[m" :
- "\033[34;46m 【功\能鍵】 \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;
-}
-
-static FILE *
-my_open(char *path)
-{
- FILE *ans = 0;
- char buf[80];
- struct stat st;
-
- 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/"
-
-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 資料連線中 ... ");
- 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)) {
- fprintf(fo, "作者: %s (連線精華區)\n標題: %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, "[搜尋]關鍵字:", search_str, sizeof(search_str), DOECHO))
- if (!*search_str)
- return pm->now;
-
- str_lower(search_str, search_str);
-
- rev = rev ? -1 : 1;
- pos = pm->now;
- do {
- pos += rev;
- if (pos == pm->num)
- pos = 0;
- else if (pos < 0)
- pos = pm->num - 1;
- if (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【 " BBSNAME "連線精華區使用說明 】\033[m\n\n"
- "[←][q] 離開到上一層目錄\n"
- "[↑][k] 上一個選項\n"
- "[↓][j] 下一個選項\n"
- "[→][r][enter] 進入目錄/讀取文章\n"
- "[b][PgUp] 上頁選單\n"
- "[^F][PgDn][Spc] 下頁選單\n"
- "[##] 移到該選項\n"
- "[^S] 將文章存到信箱\n"
- "[R] 更新資料\n"
- "[N] 查詢檔名\n"
- "[c][C][^C] 拷貝文章/並跳至上次貼文章的地方/"
- "直接貼到上次貼的地方\n");
- pressanykey();
-}
-
#define PATHLEN 256
-static char paste_fname[200];
-
-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];
@@ -490,229 +154,6 @@ a_showhelp(int level)
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);
- generalnamecomplete("選擇精華區看板:", buf, sizeof(buf),
- SHM->Bnumber,
- completeboard_compar,
- completeboard_permission,
- completeboard_getname);
- if (*buf)
- strlcpy(xboard, buf, sizeof(xboard));
- 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;
-}
-
-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 中部份結構屬於 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;
-
- strlcpy(newpath, paste_path, sizeof(newpath));
- if (mode == (char)0xbc) {
- stampfile(newpath, &item);
- unlink(newpath);
- Link(fname, newpath);
- } else
- stampdir(newpath, &item);
- strlcpy(item.owner, cuser.userid, sizeof(item.owner));
- snprintf(item.title, sizeof(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);
- strlcpy(vetitle, title, sizeof(vetitle));
- 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);
- strlcpy(vetitle, title, sizeof(vetitle));
- }
- } else if (mode == (char)0xbd) {
- gem(title, node, update);
- }
- me.page = 9999;
- }
- break;
- }
- }
- for (ch = 0; ch < me.num; ch++)
- free(me.item[ch]);
-}
-
static void
a_forward(char *path, fileheader_t * pitem, int mode)
{
@@ -755,16 +196,14 @@ a_additem(menu_t * pm, fileheader_t * myheader)
#define ADDITEM 0
#define ADDGROUP 1
-#define ADDGOPHER 2
-#define ADDLINK 3
+#define ADDLINK 2
static void
a_newitem(menu_t * pm, int mode)
{
- char *mesg[4] = {
+ char *mesg[3] = {
"[新增文章] 請輸入標題:", /* ADDITEM */
"[新增目錄] 請輸入標題:", /* ADDGROUP */
- "[新增連線] 請輸入標題:", /* ADDGOPHER */
"請輸入標題:" /* ADDLINK */
};
@@ -784,13 +223,6 @@ a_newitem(menu_t * pm, int mode)
stampdir(fpath, &item);
strlcpy(item.title, "◆ ", sizeof(item.title)); /* A1BB */
break;
- case ADDGOPHER:
- bzero(&item, sizeof(item));
- strlcpy(item.title, "☉ ", sizeof(item.title)); /* A1BB */
- if (!getdata(b_lines - 2, 1, "輸入URL位址:",
- item.filename + 2, 61, DOECHO))
- return;
- break;
case ADDLINK:
stamplink(fpath, &item);
if (!getdata(b_lines - 2, 1, "新增連線:", buf, 61, DOECHO))
@@ -802,6 +234,8 @@ a_newitem(menu_t * pm, int mode)
return;
}
item.title[0] = 0;
+ // XXX Is it alright?
+ // ex: path= "PASSWD"
for (d = 0; d <= 3; d++) {
switch (d) {
case 0:
@@ -843,7 +277,7 @@ a_newitem(menu_t * pm, int mode)
if (!getdata(b_lines - 1, 1, mesg[mode], &item.title[3], 55, DOECHO)) {
if (mode == ADDGROUP)
rmdir(fpath);
- else if (mode != ADDGOPHER)
+ else
unlink(fpath);
return;
}
@@ -863,10 +297,6 @@ a_newitem(menu_t * pm, int mode)
return;
}
break;
- case ADDGOPHER:
- strlcpy(item.date, "70", sizeof(item.date));
- strncpy(item.filename, "H.", 2);
- break;
}
strlcpy(item.owner, cuser.userid, sizeof(item.owner));
@@ -1286,7 +716,7 @@ isvisible_man(menu_t * me)
int
a_menu(char *maintitle, char *path, int lastlevel)
{
- static char Fexit;
+ static char Fexit; // 用來跳出 recursion
menu_t me;
char fname[PATHLEN];
int ch, returnvalue = FULLUPDATE;
@@ -1391,15 +821,6 @@ a_menu(char *maintitle, char *path, int lastlevel)
me.page = 9999;
break;
- case 's':
- /* XXX: security problem
- 透過這個方式跳的時候不會 update currboard ,
- 可能會導致像是 check BM 的時候不正確
- AnnounceSelect();
- me.page = 9999;
- */
- break;
-
case 'e':
case 'E':
snprintf(fname, sizeof(fname),
@@ -1463,12 +884,7 @@ a_menu(char *maintitle, char *path, int lastlevel)
#endif
snprintf(fname, sizeof(fname), "%s/%s", path, fhdr->filename);
if (*fhdr->filename == 'H' && fhdr->filename[1] == '.') {
- item_t item;
- strlcpy(item.X.G.server, fhdr->filename + 2,
- sizeof(item.X.G.server));
- strlcpy(item.X.G.path, "1/", sizeof(item.X.G.path));
- item.X.G.port = 70;
- gem(fhdr->title, &item, (ch == 'R') ? 1 : 0);
+ vmsg("不再支援 gopher mode, 請使用瀏覽器瀏覽 gopher://%s/1/",fhdr->filename);
} else if (dashf(fname)) {
int more_result;
@@ -1579,10 +995,6 @@ a_menu(char *maintitle, char *path, int lastlevel)
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;