summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2007-12-29 11:33:14 +0800
committerpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2007-12-29 11:33:14 +0800
commit355996889f971d3431cba4cd206c49937854a7a9 (patch)
treecd8ef0a52420f4ed9513fb6ad9f0ed3c3157f9ea
parent49a3549d92809881652ad6ec6adad666084d7d3a (diff)
downloadpttbbs-355996889f971d3431cba4cd206c49937854a7a9.tar
pttbbs-355996889f971d3431cba4cd206c49937854a7a9.tar.gz
pttbbs-355996889f971d3431cba4cd206c49937854a7a9.tar.bz2
pttbbs-355996889f971d3431cba4cd206c49937854a7a9.tar.lz
pttbbs-355996889f971d3431cba4cd206c49937854a7a9.tar.xz
pttbbs-355996889f971d3431cba4cd206c49937854a7a9.tar.zst
pttbbs-355996889f971d3431cba4cd206c49937854a7a9.zip
- fix announce crash bugs (reason: entering a_menu may have different board
than currbid/currboard.) git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@3754 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
-rw-r--r--include/proto.h2
-rw-r--r--include/pttstruct.h10
-rw-r--r--mbbsd/announce.c121
-rw-r--r--mbbsd/bbs.c3
-rw-r--r--mbbsd/cal.c4
-rw-r--r--mbbsd/edit.c1
-rw-r--r--mbbsd/mail.c7
7 files changed, 96 insertions, 52 deletions
diff --git a/include/proto.h b/include/proto.h
index f7a4467d..d7d353db 100644
--- a/include/proto.h
+++ b/include/proto.h
@@ -40,7 +40,7 @@ int make_symbolic_link_interactively(int gid);
void merge_dir(const char *dir1, const char *dir2, int isoutter);
/* announce */
-int a_menu(const char *maintitle, const char *path, int lastlevel, char *trans_buffer);
+int a_menu(const char *maintitle, const char *path, int lastlevel, int lastbid, char *trans_buffer);
void a_copyitem(const char* fpath, const char* title, const char* owner, int mode);
int Announce(void);
void gem(char* maintitle, item_t* path, int update);
diff --git a/include/pttstruct.h b/include/pttstruct.h
index d7cb7500..eb2edb5c 100644
--- a/include/pttstruct.h
+++ b/include/pttstruct.h
@@ -282,13 +282,6 @@ typedef struct {
union xitem_t X;
} item_t;
-typedef struct {
- item_t *item[MAX_ITEMS];
- char mtitle[STRLEN];
- char *path;
- int num, page, now, level;
-} gmenu_t;
-
#define FAVMAX 1024 /* Max boards of Myfavorite */
#define FAVGMAX 32 /* Max groups of Myfavorite */
#define FAVGSLEN 8 /* Max Length of Description String */
@@ -416,12 +409,13 @@ typedef struct {
void *raw_memory;
} screen_backup_t;
+// menu_t 其實是 gmenu_t (deprecated), 精華區專用 menu
typedef struct {
int header_size;
fileheader_t *header;
char mtitle[STRLEN];
const char *path;
- int num, page, now, level;
+ int num, page, now, level, bid;
} menu_t;
/* Used to pass commands to the readmenu.
diff --git a/mbbsd/announce.c b/mbbsd/announce.c
index 28ea9784..dd7acd3f 100644
--- a/mbbsd/announce.c
+++ b/mbbsd/announce.c
@@ -1,6 +1,16 @@
/* $Id$ */
#include "bbs.h"
+// XXX piaip 2007/12/29
+// 最近發現很多 code 都死在 announce
+// 因為進來要看 lastlevel 而非 currbid
+// user 可能一進 BBS 直殺郵件->mail_cite->進精華區
+// 於是就爆炸
+// 同理 currboard 也不該用
+// 請改用 me.bid (注意 me.bid 可能為 0, 表示進來的非看板。)
+//
+// XXX 9999 麻煩想個方式改掉
+
/* copy temp queue operation -------------------------------------- */
/* TODO
@@ -373,7 +383,7 @@ a_additem(menu_t * pm, const fileheader_t * myheader)
#define ADDITEM 0
#define ADDGROUP 1
-#define ADDLINK 2
+// #define ADDLINK 2 [deprecated]
static void
a_newitem(menu_t * pm, int mode)
@@ -400,6 +410,7 @@ a_newitem(menu_t * pm, int mode)
stampdir(fpath, &item);
strlcpy(item.title, "◆ ", sizeof(item.title)); /* A1BB */
break;
+#if 0 // 有安全考量,最好停用。
case ADDLINK:
stamplink(fpath, &item);
if (!getdata(b_lines - 2, 1, "新增連線:", buf, 61, DOECHO))
@@ -437,6 +448,7 @@ a_newitem(menu_t * pm, int mode)
igetch();
return;
}
+#endif // ADDLINK
}
if (!getdata(b_lines - 1, 1, mesg[mode], &item.title[3], 55, DOECHO)) {
@@ -454,6 +466,7 @@ a_newitem(menu_t * pm, int mode)
return;
}
break;
+#if 0 // deprecated due to security reason
case ADDLINK:
unlink(fpath);
if (symlink(lpath, fpath) == -1) {
@@ -462,6 +475,7 @@ a_newitem(menu_t * pm, int mode)
return;
}
break;
+#endif
}
strlcpy(item.owner, cuser.userid, sizeof(item.owner));
@@ -655,7 +669,24 @@ a_pastetagpost(menu_t * pm, int mode)
copyqueue_reset();
while (tagnum--) {
+ memset(&fhdr, 0, sizeof(fhdr));
EnumTagFhdr(&fhdr, dirname, ent++);
+
+ // XXX many process crashed here as fhdr.filename[0] == 0
+ // let's workaround it? or trace?
+ // if (!fhdr->filename[0])
+ // continue;
+
+ if (!fhdr.filename[0])
+ {
+ grayout(0, b_lines-2, GRAYOUT_DARK);
+ move(b_lines-1, 0); clrtobot();
+ prints("第 %d 項處理發生錯誤。 請把你剛剛進行的完整步驟貼到 "
+ GLOBAL_BUGREPORT " 板。\n", ent);
+ vmsg("忽略錯誤並繼續進行。");
+ continue;
+ }
+
if (TagBoard == 0)
sethomefile(buf, cuser.userid, fhdr.filename);
else
@@ -724,7 +755,7 @@ a_delrange(menu_t * pm)
{
char fname[PATHLEN];
- snprintf(fname, sizeof(fname), "%s/.DIR", pm->path);
+ snprintf(fname, sizeof(fname), "%s/" FN_DIR, pm->path);
del_range(0, NULL, fname);
pm->num = get_num_records(fname, FHSZ);
}
@@ -798,7 +829,7 @@ a_delete(menu_t * pm)
sizeof(backup.title) - 3);
/* merge setapath(buf, "deleted"); setadir(buf, buf); */
- snprintf(buf, sizeof(buf), "man/boards/%c/%s/.DIR",
+ snprintf(buf, sizeof(buf), "man/boards/%c/%s/" FN_DIR,
'd', "deleted");
append_record(buf, &backup, sizeof(backup));
} else { /* Ptt 損毀的項目 */
@@ -972,18 +1003,23 @@ static int
isvisible_man(const menu_t * me)
{
fileheader_t *fhdr = &me->header[me->now - me->page];
- if (me->level < MANAGER && ((fhdr->filemode & FILE_BM) ||
- ((fhdr->filemode & FILE_HIDE) &&
- /* board friend only effact when
- * in board reading mode */
- (currstat == ANNOUNCE ||
- !is_hidden_board_friend(currbid, currutmp->uid))
- )))
+ /* board friend only effact when in board reading mode */
+ if (me->level >= MANAGER)
+ return 1;
+ if (fhdr->filemode & FILE_BM)
return 0;
+ if (fhdr->filemode & FILE_HIDE)
+ {
+ if (currstat == ANNOUNCE ||
+ !is_hidden_board_friend(me->bid, currutmp->uid))
+ return 0;
+ }
return 1;
}
int
-a_menu(const char *maintitle, const char *path, int lastlevel, char *trans_buffer)
+a_menu(const char *maintitle, const char *path,
+ int lastlevel, int lastbid,
+ char *trans_buffer)
{
static char Fexit; // 用來跳出 recursion
menu_t me;
@@ -993,6 +1029,7 @@ a_menu(const char *maintitle, const char *path, int lastlevel, char *trans_buffe
if(trans_buffer)
trans_buffer[0] = '\0';
+ memset(&me, 0, sizeof(me));
Fexit = 0;
me.header_size = p_lines;
me.header = (fileheader_t *) calloc(me.header_size, FHSZ);
@@ -1000,6 +1037,7 @@ a_menu(const char *maintitle, const char *path, int lastlevel, char *trans_buffe
strlcpy(me.mtitle, maintitle, sizeof(me.mtitle));
setadir(fname, me.path);
me.num = get_num_records(fname, FHSZ);
+ me.bid = lastbid;
/* 精華區-tree 中部份結構屬於 cuser ==> BM */
@@ -1134,7 +1172,7 @@ a_menu(const char *maintitle, const char *path, int lastlevel, char *trans_buffe
須等該資料寫入 .DIR 內再 implement才有效率.
*/
if( !lastlevel && !HasUserPerm(PERM_SYSOP) &&
- (currbid==0 || !is_BM_cache(currbid)) && dashd(fname) )
+ (me.bid==0 || !is_BM_cache(me.bid)) && dashd(fname) )
vmsg("只有板主才可以拷貝目錄唷!");
else
a_copyitem(fname, me.header[me.now - me.page].title, 0, 1);
@@ -1208,7 +1246,8 @@ a_menu(const char *maintitle, const char *path, int lastlevel, char *trans_buffe
break;
}
} else if (dashd(fname)) {
- a_menu(me.header[me.now - me.page].title, fname, me.level, trans_buffer);
+ a_menu(me.header[me.now - me.page].title, fname,
+ me.level, me.bid, trans_buffer);
/* Ptt 強力跳出recursive */
if (Fexit) {
free(me.header);
@@ -1237,29 +1276,6 @@ a_menu(const char *maintitle, const char *path, int lastlevel, char *trans_buffe
break;
-#ifdef BLOG
- case 'b':
- if( !HasUserPerm(PERM_SYSOP) && !is_BM_cache(currbid) )
- vmsg("只有板主才可以用唷!");
- else{
- char genbuf[128];
- snprintf(genbuf, sizeof(genbuf),
- "bin/builddb.pl -f -n %d %s", me.now, currboard);
- system(genbuf);
- vmsg("資料更新完成");
- }
- me.page = 9999;
- break;
-
- case 'B':
- if( !HasUserPerm(SYSOP) && !is_BM_cache(currbid) )
- vmsg("只有板主才可以用唷!");
- else
- BlogMain(me.now);
- me.page = 9999;
-
- break;
-#endif
}
if (me.level >= MANAGER) {
@@ -1299,6 +1315,28 @@ a_menu(const char *maintitle, const char *path, int lastlevel, char *trans_buffe
default:
me.page = page0;
break;
+#ifdef BLOG
+ case 'b':
+ if (me.bid)
+ {
+ char genbuf[128];
+ char *bname = getbcache(me.bid)->brdname;
+ snprintf(genbuf, sizeof(genbuf),
+ "bin/builddb.pl -f -n %d %s", me.now, bname);
+ system(genbuf);
+ vmsg("資料更新完成");
+ }
+ me.page = 9999;
+ break;
+
+ case 'B':
+ if (me.bid && me.bid == currbid)
+ {
+ BlogMain(me.now);
+ };
+ me.page = 9999;
+ break;
+#endif
}
if (me.num)
@@ -1334,10 +1372,14 @@ a_menu(const char *maintitle, const char *path, int lastlevel, char *trans_buffe
}
if (me.level == SYSOP) {
switch (ch) {
+#if 0
+ /* who and why relly need this? */
+ // deprecated due to security reason
case 'l':
a_newitem(&me, ADDLINK);
me.page = 9999;
break;
+#endif
case 'N':
a_showname(&me);
me.page = 9999;
@@ -1355,6 +1397,7 @@ Announce(void)
setutmpmode(ANNOUNCE);
a_menu(BBSNAME "佈告欄", "man",
((HasUserPerm(PERM_SYSOP) ) ? SYSOP : NOBODY),
+ 0,
NULL);
return 0;
}
@@ -1366,6 +1409,8 @@ void BlogMain(int num)
int oldmode = currutmp->mode;
char genbuf[128], exit = 0;
+ // WARNING: 要確認 currboard/currbid 已正確設定才能用此API。
+
//setutmpmode(BLOGGING); /* will crash someone using old program */
sprintf(genbuf, "%s的部落格", currboard);
showtitle("部落格", genbuf);
@@ -1473,11 +1518,11 @@ void BlogMain(int num)
strlcpy(item.owner, cuser.userid, sizeof(item.owner));
setapath(adir, currboard);
- strcat(adir, "/.DIR");
+ strcat(adir, "/" FN_DIR);
append_record(adir, &item, FHSZ);
snprintf(buf, sizeof(buf),
- "cp -R etc/Blog.Default/.DIR etc/Blog.Default/* %s/",
+ "cp -R etc/Blog.Default/" FN_DIR " etc/Blog.Default/* %s/",
fpath);
system(buf);
diff --git a/mbbsd/bbs.c b/mbbsd/bbs.c
index b1aaa641..6702c021 100644
--- a/mbbsd/bbs.c
+++ b/mbbsd/bbs.c
@@ -2028,7 +2028,8 @@ b_man(void)
close(fd);
}
return a_menu(currboard, buf, HasUserPerm(PERM_ALLBOARD) ? 2 :
- (currmode & MODE_BOARD ? 1 : 0),
+ (currmode & MODE_BOARD ? 1 : 0),
+ currbid, // getbnum(currboard)?
NULL);
}
diff --git a/mbbsd/cal.c b/mbbsd/cal.c
index 0ed5f2b6..6b881795 100644
--- a/mbbsd/cal.c
+++ b/mbbsd/cal.c
@@ -122,7 +122,7 @@ osong(void)
if (ans[0] == '1')
break;
else if (ans[0] == '2') {
- a_menu("點歌歌本", SONGBOOK, 0, NULL);
+ a_menu("點歌歌本", SONGBOOK, 0, 0, NULL);
clear();
}
else if (ans[0] == '3') {
@@ -150,7 +150,7 @@ osong(void)
address, sizeof(address), LCECHO, receiver);
outs("\n接著要選歌囉..進入歌本好好的選一首歌吧..^o^");
pressanykey();
- a_menu("點歌歌本", SONGBOOK, 0, trans_buffer);
+ a_menu("點歌歌本", SONGBOOK, 0, 0, trans_buffer);
if (!trans_buffer[0] || strstr(trans_buffer, "home") ||
strstr(trans_buffer, "boards") || !(fp = fopen(trans_buffer, "r"))) {
unlockutmpmode();
diff --git a/mbbsd/edit.c b/mbbsd/edit.c
index dded10a9..35fc28da 100644
--- a/mbbsd/edit.c
+++ b/mbbsd/edit.c
@@ -3181,6 +3181,7 @@ vedit2(char *fpath, int saveheader, int *islocal, int flags)
setutmpmode(EDITEXP);
a_menu("編輯輔助器", "etc/editexp",
(HasUserPerm(PERM_SYSOP) ? SYSOP : NOBODY),
+ 0,
trans_buffer);
currstat = currstat0;
}
diff --git a/mbbsd/mail.c b/mbbsd/mail.c
index a3f00b99..ac4be139 100644
--- a/mbbsd/mail.c
+++ b/mbbsd/mail.c
@@ -1426,12 +1426,14 @@ mail_man(void)
sethomeman(buf, cuser.userid);
snprintf(buf1, sizeof(buf1), "%s 的信件夾", cuser.userid);
- a_menu(buf1, buf, HasUserPerm(PERM_MAILLIMIT), NULL);
+ a_menu(buf1, buf, HasUserPerm(PERM_MAILLIMIT) ? 1 : 0, 0, NULL);
currutmp->mode = mode0;
currstat = stat0;
return FULLUPDATE;
}
+// XXX BUG mail_cite 有可能會跳進 a_menu, 而 a_menu 會 check
+// currbid。 一整個糟糕的邏輯錯誤...
static int
mail_cite(int ent, fileheader_t * fhdr, const char *direct)
{
@@ -1461,6 +1463,7 @@ mail_cite(int ent, fileheader_t * fhdr, const char *direct)
setutmpmode(ANNOUNCE);
a_menu(xboard, fpath,
HasUserPerm(PERM_ALLBOARD) ? 2 : is_BM_cache(bid) ? 1 : 0,
+ bid,
NULL);
} else {
mail_man();
@@ -1484,7 +1487,7 @@ mail_save(int ent, fileheader_t * fhdr, const char *direct)
strlcpy(title + 3, fhdr->title, sizeof(title) - 3);
a_copyitem(fpath, title, fhdr->owner, 1);
sethomeman(fpath, cuser.userid);
- a_menu(cuser.userid, fpath, 1, NULL);
+ a_menu(cuser.userid, fpath, 1, 0, NULL);
return FULLUPDATE;
}
return DONOTHING;