summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2014-02-07 20:00:47 +0800
committerpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2014-02-07 20:00:47 +0800
commitf874b2044deadbbcb9906c0e1d25c4b236482066 (patch)
treea1bcc648b22e6f5f76013dfec3d18ecf764c126a
parent82fa294edb5e060b5300daef5eba030c5f2c862f (diff)
downloadpttbbs-f874b2044deadbbcb9906c0e1d25c4b236482066.tar
pttbbs-f874b2044deadbbcb9906c0e1d25c4b236482066.tar.gz
pttbbs-f874b2044deadbbcb9906c0e1d25c4b236482066.tar.bz2
pttbbs-f874b2044deadbbcb9906c0e1d25c4b236482066.tar.lz
pttbbs-f874b2044deadbbcb9906c0e1d25c4b236482066.tar.xz
pttbbs-f874b2044deadbbcb9906c0e1d25c4b236482066.tar.zst
pttbbs-f874b2044deadbbcb9906c0e1d25c4b236482066.zip
Allow BM deleting illegal contents.
Since this may be sensitive, we need sysop/groupop to explicitly set it. git-svn-id: http://opensvn.csie.org/pttbbs/trunk@5915 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
-rw-r--r--pttbbs/include/pttstruct.h3
-rw-r--r--pttbbs/mbbsd/bbs.c175
-rw-r--r--pttbbs/mbbsd/board.c20
-rw-r--r--pttbbs/mbbsd/var.c6
4 files changed, 185 insertions, 19 deletions
diff --git a/pttbbs/include/pttstruct.h b/pttbbs/include/pttstruct.h
index c05dee69..cb253237 100644
--- a/pttbbs/include/pttstruct.h
+++ b/pttbbs/include/pttstruct.h
@@ -198,7 +198,7 @@ typedef struct boardheader_t { /* 256 bytes */
} PACKSTRUCT boardheader_t;
// TODO BRD 快爆了,怎麼辦? 準備從 pad3 偷一個來當 attr2 吧...
-// #define BRD_NOZAP 0x00000001 /* (沒用到) 不可zap */
+// #define BRD_NOZAP 0x00000001 /* 不可 ZAP */
#define BRD_NOCOUNT 0x00000002 /* 不列入統計 */
#define BRD_NOTRAN 0x00000004 /* 不轉信 */
#define BRD_GROUPBOARD 0x00000008 /* 群組板 */
@@ -226,6 +226,7 @@ typedef struct boardheader_t { /* 256 bytes */
#define BRD_NOREPLY 0x02000000 /* 不可回文 */
#define BRD_ALIGNEDCMT 0x04000000 /* 對齊式的推文 */
#define BRD_NOSELFDELPOST 0x08000000 /* 不可自刪 */
+#define BRD_BM_MASK_CONTENT 0x10000000 /* 允許板主刪除特定文字 */
#define BRD_LINK_TARGET(x) ((x)->postexpire)
#define GROUPOP() (currmode & MODE_GROUPOP)
diff --git a/pttbbs/mbbsd/bbs.c b/pttbbs/mbbsd/bbs.c
index f5aeb609..670cbb9e 100644
--- a/pttbbs/mbbsd/bbs.c
+++ b/pttbbs/mbbsd/bbs.c
@@ -2657,14 +2657,14 @@ edit_title(int ent, fileheader_t * fhdr, const char *direct)
static int
solve_post(int ent, fileheader_t * fhdr, const char *direct)
{
- if ((currmode & MODE_BOARD)) {
- fhdr->filemode ^= FILE_SOLVED;
- // TODO fix race condition here.
- substitute_ref_record(direct, fhdr, ent);
- check_locked(fhdr);
- return PART_REDRAW;
- }
- return DONOTHING;
+ if (!(currmode & MODE_BOARD))
+ return DONOTHING;
+
+ fhdr->filemode ^= FILE_SOLVED;
+ // TODO fix race condition here.
+ substitute_ref_record(direct, fhdr, ent);
+ check_locked(fhdr);
+ return PART_REDRAW;
}
@@ -4119,14 +4119,16 @@ board_digest(void)
static int
-push_bottom(int ent, fileheader_t *old_fhdr, const char *direct)
+pin_post(int ent, fileheader_t *old_fhdr, const char *direct)
{
int num;
fileheader_t fhdr;
char buf[PATHLEN];
+
if ((currmode & MODE_DIGEST) || !(currmode & MODE_BOARD)
|| old_fhdr->filename[0]=='L')
return DONOTHING;
+
setbottomtotal(currbid); // <- Ptt : will be remove when stable
num = getbottomtotal(currbid);
if (!(old_fhdr->filemode & FILE_BOTTOM))
@@ -4349,15 +4351,162 @@ change_cooldown(void)
#endif
static int
+mask_post_content(int ent, fileheader_t * fhdr, const char *direct) {
+#ifndef USE_TIME_CAPSULE
+ vmsg("此功\能未開啟,請洽站長。");
+ return FULLUPDATE;
+#else
+ char pattern[STRLEN];
+ char reason[DISP_TTLEN];
+ char buf[ANSILINELEN];
+ char fpath[PATHLEN], revpath[PATHLEN];
+ char ans[3];
+ FILE *fp, *fpw;
+ int i, rev, found = 0;
+ boardheader_t *bp;
+
+ if (currstat == RMAIL)
+ return DONOTHING;
+
+ bp = getbcache(currbid);
+ assert(bp);
+
+ if (!(bp->brdattr & BRD_BM_MASK_CONTENT)) {
+ vmsg("要開啟此項功\能請洽群組長。");
+ return FULLUPDATE;
+ }
+
+ vs_hdr2(" 刪除特定文字 ", fhdr->title);
+ if (!getdata(1, 0, "刪除原因: ", reason, sizeof(reason), DOECHO))
+ return FULLUPDATE;
+ mvouts(3, 0, "請輸入要刪除的文字 (出現時會整行被[違規內容]取代, 最少兩個字元)\n");
+ if (!getdata(2, 0, "刪除文字: ", pattern, TTLEN, DOECHO) || strlen(pattern) < 2)
+ return FULLUPDATE;
+
+ // try to render and build.
+ setdirpath(fpath, direct, fhdr->filename);
+ fp = fopen(fpath, "rt");
+ if (!fp) {
+ vmsg("文章已被刪除或鎖定。");
+ return FULLUPDATE;
+ }
+ mvouts(3, 0, ANSI_COLOR(1;31) "將刪除下列文字:" ANSI_RESET "\n");
+ i = 4;
+ while (fgets(buf, sizeof(buf), fp)) {
+ if (strstr(buf, pattern)) {
+ found++;
+ mvouts(i, 0, ANSI_RESET);
+ outs(buf);
+ outs(ANSI_RESET);
+ if (++i >= b_lines) {
+ if (tolower(vmsg("按 q 放棄,或是任意鍵繼續: ")) == 'q') {
+ found = 0;
+ break;
+ }
+ i = 4;
+ move(i, 0);
+ clrtobot();
+ }
+ }
+ }
+ fclose(fp);
+
+ if (!found) {
+ vmsg("未修改檔案。");
+ return FULLUPDATE;
+ }
+
+ /* XXX race condition here... */
+ getdata(b_lines, 0, "確定要刪除這些內容嗎? [y/N]: ", ans, sizeof(ans), LCECHO);
+ if (*ans != 'y') {
+ vmsg("未修改檔案。");
+ return FULLUPDATE;
+ }
+
+ rev = timecapsule_add_revision(fpath);
+ if (!timecapsule_get_by_revision(fpath, rev, revpath, sizeof(revpath))) {
+ vmsg("系統錯誤,無法修改。");
+ return FULLUPDATE;
+ }
+ // Enforce building a new file.
+ unlink(fpath);
+
+ fp = fopen(revpath, "rt");
+ fpw = fopen(fpath, "wt");
+ while (fgets(buf, sizeof(buf), fp)) {
+ if (strstr(buf, pattern)) {
+ fputs("※ [部份違規文字已刪除]\n", fpw);
+ continue;
+ }
+ fputs(buf, fpw);
+ }
+ fclose(fp);
+ fclose(fpw);
+ log_filef(fpath, LOG_CREAT, "※%s 於 %s 刪除部份違規文字,原因: \n", cuser.userid,
+ Cdatelite(&now), reason);
+ log_filef(revpath, LOG_CREAT,
+ "※%s 於 %s 刪除部份違規文字,原因: %s\n"
+ "※違規文字樣式: %s\n",
+ cuser.userid, Cdatelite(&now), reason, pattern);
+
+ // 理論上要改 fhdr->modified, 不過在目前一團亂的同步機制下,多作多錯。
+ vmsg("違規文字已刪除。");
+ return FULLUPDATE;
+#endif
+}
+
+static int
b_moved_to_config()
{
- if ((currmode & MODE_BOARD) || HasUserPerm(PERM_SYSOP)) {
+ if (currmode & MODE_BOARD) {
vmsg("這個功\能已移入看板設定 (i) 去了!");
return FULLUPDATE;
}
return DONOTHING;
}
+static int
+moved_to_ctrl_e()
+{
+ if (currmode & MODE_BOARD) {
+ vmsg("這個功\能已移入文章管理 (Ctrl-E) 去了!");
+ return FULLUPDATE;
+ }
+ return DONOTHING;
+}
+
+static int
+manage_post(int ent, fileheader_t * fhdr, const char *direct) {
+ int ans;
+ const char *prompt = "[Y]推數歸零 [E]解除鎖定 [M]刪除特定文字:";
+
+ if (!(currmode & MODE_BOARD)) {
+ if (HasUserPerm(PERM_POLICE))
+ return lock_post(ent, fhdr, direct);
+ else
+ return DONOTHING;
+ }
+
+ ans = vmsg(prompt);
+ if (!isascii(ans))
+ return FULLUPDATE;
+
+ switch(tolower(ans)) {
+ case 'y':
+ recommend_cancel(ent, fhdr, direct);
+ break;
+
+ case 'e':
+ lock_post(ent, fhdr, direct);
+ break;
+
+ case 'm':
+ mask_post_content(ent, fhdr, direct);
+ break;
+ }
+ return FULLUPDATE;
+}
+
/* ----------------------------------------------------- */
/* 看板功能表 */
/* ----------------------------------------------------- */
@@ -4367,7 +4516,7 @@ const onekey_t read_comms[] = {
{ 0, NULL }, // Ctrl('B')
{ 0, NULL }, // Ctrl('C')
{ 0, NULL }, // Ctrl('D')
- { 1, lock_post }, // Ctrl('E')
+ { 1, manage_post }, // Ctrl('E')
{ 0, NULL }, // Ctrl('F')
#ifdef NO_GAMBLE
{ 0, NULL }, // Ctrl('G')
@@ -4430,10 +4579,10 @@ const onekey_t read_comms[] = {
{ 0, b_vote }, // 'V'
{ 0, b_notes_edit }, // 'W'
{ 1, recommend }, // 'X'
- { 1, recommend_cancel }, // 'Y'
+ { 0, moved_to_ctrl_e }, // 'Y'
{ 0, NULL }, // 'Z' 90
{ 0, NULL }, { 0, NULL }, { 0, NULL }, { 0, NULL },
- { 1, push_bottom }, // '_' 95
+ { 1, pin_post }, // '_' 95
{ 0, NULL },
{ 0, NULL }, // 'a' 97
{ 0, b_notes }, // 'b'
diff --git a/pttbbs/mbbsd/board.c b/pttbbs/mbbsd/board.c
index b155f084..27258ad9 100644
--- a/pttbbs/mbbsd/board.c
+++ b/pttbbs/mbbsd/board.c
@@ -325,7 +325,7 @@ b_config(void)
cachePostRes = CheckPostRestriction(currbid);
char canpost = (cachePostPerm && cachePostRes);
-#define LNBOARDINFO (19)
+#define LNBOARDINFO (20)
#define LNPOSTRES (12)
#define COLPOSTRES (48)
@@ -340,7 +340,7 @@ b_config(void)
grayout(0, ytitle-2, GRAYOUT_DARK);
// available hotkeys yet:
- // a b d j k p q z
+ // a b d j p q z
// 2 3 4 5 6 7 9
// better not: l 0
@@ -395,6 +395,13 @@ b_config(void)
ANSI_COLOR(1)"不開放" : "開放"
);
+ prints( " " ANSI_COLOR(1;36) "k" ANSI_RESET
+ " - 板主 %s" ANSI_RESET
+ " 刪除違規文字\n",
+ (bp->brdattr & BRD_BM_MASK_CONTENT) ?
+ ANSI_COLOR(1)"可" : "不可"
+ );
+
prints( " " ANSI_COLOR(1;36) "r" ANSI_RESET
" - %s " ANSI_RESET "推薦文章\n",
(bp->brdattr & BRD_NORECOMMEND) ?
@@ -793,6 +800,15 @@ b_config(void)
touched = 1;
break;
+ case 'k':
+ if (!(HasUserPerm(PERM_SYSOP) || (HasUserPerm(PERM_SYSSUPERSUBOP) && GROUPOP()) ) ) {
+ vmsg("此項設定需要群組長或站長權限");
+ break;
+ }
+ bp->brdattr ^= BRD_BM_MASK_CONTENT;
+ touched = 1;
+ break;
+
case 'd':
#ifndef ALLOW_BM_SET_NOSELFDELPOST
if (!(HasUserPerm(PERM_SYSOP) || (HasUserPerm(PERM_SYSSUPERSUBOP) && GROUPOP()) ) ) {
diff --git a/pttbbs/mbbsd/var.c b/pttbbs/mbbsd/var.c
index 4f3ddfda..424d9c3d 100644
--- a/pttbbs/mbbsd/var.c
+++ b/pttbbs/mbbsd/var.c
@@ -77,7 +77,7 @@ const char * const str_roleid[] = {
};
const char * const str_permboard[] = {
- "不可 Zap", /* BRD_NOZAP */
+ "(無作用)", /* deprecated: BRD_NOZAP */
"不列入統計", /* BRD_NOCOUNT */
"不轉信", /* BRD_NOTRAN */
"群組板", /* BRD_GROUPBOARD */
@@ -111,8 +111,8 @@ const char * const str_permboard[] = {
"推文記錄 IP", /* BRD_IPLOGRECMD */
"十八禁", /* BRD_OVER18 */
"對齊式推文", /* BRD_ALIGNEDCMT */
- "沒想到",
- "沒想到",
+ "不可自刪", /* BRD_NOSELFDELPOST */
+ "板主可刪特定文字", /* BRD_BM_MASK_CONTENT */
"沒想到",
"沒想到",
"沒想到",