diff options
-rw-r--r-- | include/proto.h | 5 | ||||
-rw-r--r-- | include/pttstruct.h | 3 | ||||
-rw-r--r-- | mbbsd/admin.c | 92 | ||||
-rw-r--r-- | mbbsd/bbs.c | 6 | ||||
-rw-r--r-- | mbbsd/board.c | 87 | ||||
-rw-r--r-- | mbbsd/cache.c | 4 | ||||
-rw-r--r-- | mbbsd/fav.c | 2 | ||||
-rw-r--r-- | mbbsd/name.c | 2 |
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)); } |