summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/proto.h5
-rw-r--r--include/pttstruct.h3
-rw-r--r--mbbsd/admin.c92
-rw-r--r--mbbsd/bbs.c6
-rw-r--r--mbbsd/board.c87
-rw-r--r--mbbsd/cache.c4
-rw-r--r--mbbsd/fav.c2
-rw-r--r--mbbsd/name.c2
8 files changed, 133 insertions, 68 deletions
diff --git a/include/proto.h b/include/proto.h
index 93c4a92f..74de00da 100644
--- a/include/proto.h
+++ b/include/proto.h
@@ -20,7 +20,8 @@ int m_register();
int cat_register();
unsigned int setperms(unsigned int pbits, char *pstring[]);
void setup_man(boardheader_t * board);
-int make_symbolic_link(int gid, int bid);
+int make_symbolic_link(char *bname, int gid);
+int make_symbolic_link_interactively(int gid);
/* announce */
int a_menu(char *maintitle, char *path, int lastlevel);
@@ -75,7 +76,7 @@ int brc_unread(const char *fname, int bnum, const int *blist);
int brc_initial(const char *boardname);
void brc_update();
void brc_finalize();
-int Ben_Perm(boardheader_t *bptr);
+int HasPerm(boardheader_t *bptr);
int New();
int Boards();
int root_board();
diff --git a/include/pttstruct.h b/include/pttstruct.h
index eef261ff..0e4b4bf2 100644
--- a/include/pttstruct.h
+++ b/include/pttstruct.h
@@ -164,6 +164,9 @@ typedef struct boardheader_t {
#define BRD_BMCOUNT 000040000 /* 板主設定列入記錄 */
#define BRD_SYMBOLIC 000100000 /* symbolic link to board */
+#define BRD_LINK_TARGET(x) ((x)->postexpire)
+
+
#define TTLEN 64 /* Length of title */
#define FNLEN 33 /* Length of filename */
diff --git a/mbbsd/admin.c b/mbbsd/admin.c
index 38032f5f..a61073c5 100644
--- a/mbbsd/admin.c
+++ b/mbbsd/admin.c
@@ -310,6 +310,12 @@ m_mod_board(char *bname)
getdata_str(9, 0, msg_sure_ny, genbuf, 3, LCECHO, "N");
if (genbuf[0] != 'y' || !bname[0])
outs(MSG_DEL_CANCEL);
+ else if (bh.brdattr & BRD_SYMBOLIC) {
+ memset(&bh, 0, sizeof(bh));
+ substitute_record(fn_board, &bh, sizeof(bh), bid);
+ reset_board(bid);
+ log_usies("DelLink", bh.brdname);
+ }
else {
strlcpy(bname, bh.brdname, sizeof(bh.brdname));
snprintf(genbuf, sizeof(genbuf),
@@ -564,12 +570,25 @@ x_file()
return FULLUPDATE;
}
+static int add_board_record(boardheader_t *board)
+{
+ int bid;
+ if ((bid = getbnum("")) > 0) {
+ substitute_record(fn_board, board, sizeof(boardheader_t), bid);
+ reset_board(bid);
+ } else if (append_record(fn_board, (fileheader_t *)board, sizeof(boardheader_t)) == -1) {
+ return -1;
+ } else {
+ addbrd_touchcache();
+ }
+ return 0;
+}
+
int
m_newbrd(int recover)
{
boardheader_t newboard;
char ans[4];
- int bid;
char genbuf[200];
stand_title("建立新板");
@@ -594,8 +613,7 @@ m_newbrd(int recover)
break;
} while (1);
- if (strlen(genbuf) >= 4)
- strncpy(newboard.title, genbuf, 4);
+ strncpy(newboard.title, genbuf, 4);
newboard.title[4] = ' ';
@@ -654,16 +672,9 @@ m_newbrd(int recover)
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();
- }
+
+ add_board_record(&newboard);
+ pressanykey();
setup_man(&newboard);
outs("\n新板成立");
@@ -673,26 +684,59 @@ m_newbrd(int recover)
return 0;
}
-int make_symbolic_link(int gid, int bid)
+int make_symbolic_link(char *bname, int gid)
{
boardheader_t newboard;
-
- stand_title("建立看板連結");
+ int bid;
+
+ bid = getbnum(bname);
memset(&newboard, 0, sizeof(newboard));
- strlcpy(newboard.brdname, "1SYMLINK", sizeof(newboard.brdname));
+ /*
+ * known issue:
+ * These two stuff will be used for sorting. But duplicated brdnames
+ * may cause wrong binary-search result. So I replace the last
+ * letters of brdname to '~'(ascii code 126) in order to correct the
+ * resuilt, thought I think it's a dirty solution.
+ *
+ * Duplicate entry with same brdname may cause wrong result, if
+ * searching by key brdname. But people don't need to know a board
+ * is symbolic, so just let SYSOP know it. You may want to read
+ * board.c:load_boards().
+ */
+
+ strlcpy(newboard.brdname, bname, sizeof(newboard.brdname));
+ newboard.brdname[strlen(bname) - 1] = '~';
+ strlcpy(newboard.title, bcache[bid - 1].title, sizeof(newboard.title));
+ strcpy(newboard.title + 5, "@看板連結");
+
newboard.gid = gid;
- newboard.nuser = bid;
+ BRD_LINK_TARGET(&newboard) = bid;
newboard.brdattr = BRD_NOTRAN | BRD_SYMBOLIC;
- 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) {
+
+ if (add_board_record(&newboard) < 0)
+ return -1;
+ return bid;
+}
+
+int make_symbolic_link_interactively(int gid)
+{
+ char buf[32];
+
+ generalnamecomplete(msg_bid, buf, sizeof(buf), SHM->Bnumber,
+ completeboard_compar,
+ completeboard_permission,
+ completeboard_getname);
+ if (!buf[0])
+ return -1;
+
+ stand_title("建立看板連結");
+
+ if (make_symbolic_link(buf, gid) < 0) {
vmsg("看板連結建立失敗");
return -1;
- } else {
- addbrd_touchcache();
}
+ log_usies("NewSymbolic", buf);
return 0;
}
diff --git a/mbbsd/bbs.c b/mbbsd/bbs.c
index 44003d91..5f4016bd 100644
--- a/mbbsd/bbs.c
+++ b/mbbsd/bbs.c
@@ -113,7 +113,7 @@ set_board()
boardheader_t *bp;
bp = getbcache(currbid);
- if( !Ben_Perm(bp) ){
+ if( !HasPerm(bp) ){
vmsg("access control violation, exit");
u_exit("access control violation!");
exit(-1);
@@ -123,7 +123,7 @@ set_board()
strcpy(currBM, "徵求中");
else
snprintf(currBM, sizeof(currBM), "板主:%s", bp->BM);
- currmode = (currmode & (MODE_DIRTY | MODE_MENU)) | MODE_STARTED;
+ currmode = (currmode & (MODE_DIRTY | MODE_GROUPOP)) | MODE_STARTED;
if (HAS_PERM(PERM_ALLBOARD) || is_BM_cache(currbid))
currmode = currmode | MODE_BOARD | MODE_POST;
@@ -308,7 +308,7 @@ do_select(int ent, fileheader_t * fhdr, char *direct)
if (bname[0] == '\0' || !(i = getbnum(bname)))
return FULLUPDATE;
bh = getbcache(i);
- if (!Ben_Perm(bh))
+ if (!HasPerm(bh))
return FULLUPDATE;
strlcpy(bname, bh->brdname, sizeof(bname));
currbid = i;
diff --git a/mbbsd/board.c b/mbbsd/board.c
index dff99939..e9a7f265 100644
--- a/mbbsd/board.c
+++ b/mbbsd/board.c
@@ -272,7 +272,6 @@ brc_unread(const char *fname, int bnum, const int *blist)
#define NBRD_UNREAD 32
#define NBRD_SYMBOLIC 64
-#define BRD_LINK_TARGET(x) ((x)->nuser)
#define TITLE_MATCH(bptr, key) ((key)[0] && !strcasestr((bptr)->title, (key)))
#define GROUPOP() (currmode & MODE_GROUPOP)
@@ -612,9 +611,13 @@ load_boards(char *key)
!((state = HasPerm(bptr)) || GROUPOP()) ||
(bptr->brdattr & (BRD_GROUPBOARD | BRD_SYMBOLIC)) ||
TITLE_MATCH(bptr, key) ||
- // XXX:
- // class_bid == -1 should be remove
- // if symbolic link work fine
+ /* Should "class_bid == -1" be removed if symbolic
+ * link work fine?
+ * Consideration:
+ * Symbolic link cause too much IO because
+ * add/remove link will be change .BRD, but
+ * scanning the whole boards take much CPU.
+ */
(class_bid == -1 && bptr->nuser < 5))
continue;
addnewbrdstat(n, state);
@@ -638,10 +641,14 @@ load_boards(char *key)
state = HasPerm(bptr);
if ( !(state || GROUPOP()) || TITLE_MATCH(bptr, key) )
continue;
+
if (bptr->brdattr & BRD_SYMBOLIC) {
- n = BRD_LINK_TARGET(bptr);
- bptr = &bcache[n];
- state |= NBRD_SYMBOLIC;
+
+ /* Only SYSOP knows a board is symbolic */
+ if (HAS_PERM(PERM_SYSOP))
+ state |= NBRD_SYMBOLIC;
+ else
+ n = BRD_LINK_TARGET(bptr) - 1;
}
addnewbrdstat(n, state);
}
@@ -919,6 +926,11 @@ set_menu_BM(char *BM)
}
}
+static void replace_link_by_target(boardstat_t *board)
+{
+ board->bid = BRD_LINK_TARGET(&bcache[board->bid - 1]);
+ board->myattr &= ~NBRD_SYMBOLIC;
+}
static void
choose_board(int newflag)
@@ -1114,7 +1126,7 @@ choose_board(int newflag)
break;
case 'y':
if (get_current_fav() != NULL || yank_flag != 0)
- yank_flag = (yank_flag + 1) % 2;
+ yank_flag = (yank_flag + 1) % 2;
brdnum = -1;
break;
case Ctrl('D'):
@@ -1152,14 +1164,8 @@ choose_board(int newflag)
break;
case 'L':
if (HAS_PERM(PERM_SYSOP) && class_bid > 0) {
- tmp = generalnamecomplete("請輸入看板英文名稱:",
- buf, sizeof(buf),
- SHM->Bnumber,
- completeboard_compar,
- completeboard_permission,
- completeboard_getname);
- if (tmp >= 0)
- make_symbolic_link(class_bid, tmp);
+ if (make_symbolic_link_interactively(class_bid) < 0)
+ break;
brdnum = -1;
head = 9999;
}
@@ -1175,6 +1181,12 @@ choose_board(int newflag)
head = 9999;
}
break;
+ case 'l':
+ if (HAS_PERM(PERM_SYSOP) && (nbrd[num].myattr & NBRD_SYMBOLIC)) {
+ replace_link_by_target(&nbrd[num]);
+ head = 9999;
+ }
+ break;
case 'm':
if (HAS_PERM(PERM_BASIC)) {
ptr = &nbrd[num];
@@ -1322,7 +1334,7 @@ choose_board(int newflag)
num = tmp;
break;
case 'E':
- if (HAS_PERM(PERM_SYSOP) || GROUP_OP()) {
+ if (HAS_PERM(PERM_SYSOP) || GROUPOP()) {
ptr = &nbrd[num];
move(1, 1);
clrtobot();
@@ -1331,20 +1343,20 @@ choose_board(int newflag)
}
break;
case 'R':
- if (HAS_PERM(PERM_SYSOP) || GROUP_OP()) {
+ if (HAS_PERM(PERM_SYSOP) || GROUPOP()) {
m_newbrd(1);
brdnum = -1;
}
break;
case 'B':
- if (HAS_PERM(PERM_SYSOP) || GROUP_OP()) {
+ if (HAS_PERM(PERM_SYSOP) || GROUPOP()) {
m_newbrd(0);
brdnum = -1;
}
break;
case 'W':
if (class_bid > 0 &&
- (HAS_PERM(PERM_SYSOP) || GROUP_OP())) {
+ (HAS_PERM(PERM_SYSOP) || GROUPOP())) {
setbpath(buf, bcache[class_bid - 1].brdname);
mkdir(buf, 0755); /* Ptt:開群組目錄 */
b_note_edit_bname(class_bid);
@@ -1364,20 +1376,25 @@ choose_board(int newflag)
case 'r':
{
ptr = &nbrd[num];
- if (yank_flag == 0 && get_fav_type(&nbrd[0]) == 0)
- break;
- else if (ptr->myattr & NBRD_LINE)
- break;
- else if (ptr->myattr & NBRD_FOLDER){
- int t = num;
- num = 0;
- fav_folder_in(ptr->bid);
- choose_board(0);
- fav_folder_out();
- num = t;
- brdnum = -1;
- head = 9999;
- break;
+ if (yank_flag == 0) {
+ if (get_fav_type(&nbrd[0]) == 0)
+ break;
+ else if (ptr->myattr & NBRD_LINE)
+ break;
+ else if (ptr->myattr & NBRD_FOLDER){
+ int t = num;
+ num = 0;
+ fav_folder_in(ptr->bid);
+ choose_board(0);
+ fav_folder_out();
+ num = t;
+ brdnum = -1;
+ head = 9999;
+ break;
+ }
+ }
+ else if (ptr->myattr & NBRD_SYMBOLIC) {
+ replace_link_by_target(ptr);
}
if (!(B_BH(ptr)->brdattr & BRD_GROUPBOARD)) { /* 非sub class */
@@ -1407,7 +1424,7 @@ choose_board(int newflag)
else
class_bid = -1; /* 熱門群組用 */
- if (!GROUP_OP()) /* 如果還沒有小組長權限 */
+ if (!GROUPOP()) /* 如果還沒有小組長權限 */
set_menu_BM(B_BH(ptr)->BM);
if (now < B_BH(ptr)->bupdate) {
diff --git a/mbbsd/cache.c b/mbbsd/cache.c
index cacdb1d7..ff409191 100644
--- a/mbbsd/cache.c
+++ b/mbbsd/cache.c
@@ -667,7 +667,7 @@ reset_board(int bid) /* XXXbid: from 1 */
}
}
-#ifndef _BBS_UTIL_C_ /* because of Ben_Perm() in board.c */
+#ifndef _BBS_UTIL_C_ /* because of HasPerm() in board.c */
int
apply_boards(int (*func) (boardheader_t *))
{
@@ -675,7 +675,7 @@ apply_boards(int (*func) (boardheader_t *))
register boardheader_t *bhdr;
for (i = 0, bhdr = bcache; i < numboards; i++, bhdr++) {
- if (!(bhdr->brdattr & BRD_GROUPBOARD) && Ben_Perm(bhdr) &&
+ if (!(bhdr->brdattr & BRD_GROUPBOARD) && HasPerm(bhdr) &&
(*func) (bhdr) == QUIT)
return QUIT;
}
diff --git a/mbbsd/fav.c b/mbbsd/fav.c
index 26c2f02d..59579f60 100644
--- a/mbbsd/fav.c
+++ b/mbbsd/fav.c
@@ -239,7 +239,7 @@ static void rebuild_fav(fav_t *fp, int clean_invisible)
bp = &bcache[cast_board(ft)->bid - 1];
if (!bp->brdname[0])
continue;
- if ( clean_invisible && !Ben_Perm(bp))
+ if ( clean_invisible && !HasPerm(bp))
continue;
break;
case FAVT_LINE:
diff --git a/mbbsd/name.c b/mbbsd/name.c
index cfeceb3c..5c2db2fc 100644
--- a/mbbsd/name.c
+++ b/mbbsd/name.c
@@ -674,7 +674,7 @@ completeboard_compar(int where, char *str, int len)
int
completeboard_permission(int where)
{
- return (((currmode & MODE_GROUPOP) || Ben_Perm(SHM->bsorted[0][where])) &&
+ return (((currmode & MODE_GROUPOP) || HasPerm(SHM->bsorted[0][where])) &&
!(SHM->bsorted[0][where]->brdattr & BRD_GROUPBOARD));
}