作者itoc, 信區: itoc
標題[修正] newbrd.c 免連署的看板申請
時間04/04/05
作者: itoc (League) 看板: plan
標題: [修正] 免連署的看板申請
時間: 2004/03/16 Tue 23:56:53 Updated: 2005/05/19
※ 引述《yenning.bbs@bbs.seehere.org (yenning)》之銘言:
> 是不是能用成像itoc.twbbs.org的看板連署一樣?
1. 拔掉 newbrd.c 的所有連署功能,^P 只剩下申請看板
2. 免連署的看板申請
3. 尚未開板的顯示 '+',已開板完畢顯示 ' '
若是 VIP 的申請,在尚未開板前會顯示 '*'
4. 申請看板時即填入所有資訊,站長按 o 就直接開板完成
5. 如果做了精華區的 patch,那麼還直接加入 Class
6. help 沒有改,想寫的人再自己寫 :p
: theme.h
NECKER_COSIGN、FOOTER_COSIGN、FEETER_COSIGN
這三個自己改一下,不改也沒差
指令就只剩下 (r)讀取 (^P)申請 (d)刪除 (o)開板 (E)編輯 (^Q/^O)查詢
: struct.h HAVE_COSIGN 這一段改成這樣
#ifdef HAVE_COSIGN
/* ----------------------------------------------------- */
/* newbrd.c 中運用的資料結構 */
/* ----------------------------------------------------- */
typedef struct NewBoardHeader
{
char brdname[BNLEN + 1];
char class[BCLEN + 1];
char title[BTLEN + 1];
time_t btime;
time_t etime;
char xname[32];
char owner[IDLEN + 1];
char date[9];
usint mode;
int readlevel;
} NBRD;
#define NBRD_FINISH 0x01 /* 已結案 */
#define NBRD_VIPAPPLY 0x02 /* VIP 的申請 */
#endif /* HAVE_COSIGN */
: newbrd.c 換成以下
: ----------------------------------------------------
注意 is_vip_apply() 的部分要自己改寫,當然你也可以直接 return 0,就沒有 VIP
nbrd_add() 裡面的分類依各站自定
----------------------------------------------------
如果還希望自動加入 Class 分類,那麼參考精華區這篇
[功能] newbrd.c 連署開板後自動加入 Class
: ----------------------------------------------------
/*-------------------------------------------------------*/
/* newbrd.c ( YZU_CSE WindTop BBS ) */
/*-------------------------------------------------------*/
/* target : 連署功能 */
/* create : 00/01/02 */
/* update : 02/04/29 */
/*-------------------------------------------------------*/
/* run/newbrd/_/.DIR - newbrd control header */
/* run/newbrd/_/@/@_ - newbrd description file */
/*-------------------------------------------------------*/
#include "bbs.h"
#ifdef HAVE_COSIGN
extern XZ xz[];
extern char xo_pool[];
extern BCACHE *bshm; /* itoc.010805: 開新板用 */
static int nbrd_add();
static int nbrd_body();
static int nbrd_head();
static int
cmpbtime(nbrd)
NBRD *nbrd;
{
return nbrd->btime == currchrono;
}
static int
nbrd_stamp(folder, nbrd, fpath)
char *folder;
NBRD *nbrd;
char *fpath;
{
char *fname;
char *family = NULL;
int rc;
int token;
fname = fpath;
while (rc = *folder++)
{
*fname++ = rc;
if (rc == '/')
family = fname;
}
fname = family;
*family++ = '@';
token = time(0);
archiv32(token, family);
rc = open(fpath, O_WRONLY | O_CREAT | O_EXCL, 0600);
nbrd->btime = token;
str_stamp(nbrd->date, &nbrd->btime);
strcpy(nbrd->xname, fname);
return rc;
}
static void
nbrd_fpath(fpath, folder, nbrd)
char *fpath;
char *folder;
NBRD *nbrd;
{
char *str = NULL;
int cc;
while (cc = *folder++)
{
*fpath++ = cc;
if (cc == '/')
str = fpath;
}
strcpy(str, nbrd->xname);
}
static int
nbrd_init(xo)
XO *xo;
{
xo_load(xo, sizeof(NBRD));
return nbrd_head(xo);
}
static int
nbrd_load(xo)
XO *xo;
{
xo_load(xo, sizeof(NBRD));
return nbrd_body(xo);
}
static char
nbrd_attr(nbrd)
NBRD *nbrd;
{
/* 已開板完成用 ' '
未開板的一般人申請用 '+'
未開板的VIP申請用 '+' (一般使用者看到)
未開板的VIP申請用 '*' (只有站長可見)
*/
usint mode;
mode = nbrd->mode;
return mode & NBRD_FINISH ? ' ' :
(HAS_PERM(PERM_ALLBOARD) && (mode & NBRD_VIPAPPLY) ? '*' : '+');
}
static void
nbrd_item(num, nbrd)
int num;
NBRD *nbrd;
{
prints("%6d %c %-5s %-13s %-13s[%s] %.*s\n",
num, nbrd_attr(nbrd), nbrd->date + 3, nbrd->owner,
nbrd->brdname, nbrd->class, d_cols + 29, nbrd->title);
}
static int
nbrd_body(xo)
XO *xo;
{
NBRD *nbrd;
int num, max, tail;
max = xo->max;
if (max <= 0)
{
if (vans("要新增連署項目嗎(Y/N)?[N] ") == 'y')
return nbrd_add(xo);
return XO_QUIT;
}
nbrd = (NBRD *) xo_pool;
num = xo->top;
tail = num + XO_TALL;
if (max > tail)
max = tail;
move(3, 0);
do
{
nbrd_item(++num, nbrd++);
} while (num < max);
clrtobot();
/* return XO_NONE; */
return XO_FOOT; /* itoc.010403: 把 b_lines 填上 feeter */
}
static int
nbrd_head(xo)
XO *xo;
{
vs_head("申請看板", str_site);
outs(NECKER_COSIGN);
return nbrd_body(xo);
}
static int
is_vip_apply() /* 是不是 VIP 的申請 */
{
char *str, email[80];
// 以下這一段要由各站自定
if (HAS_PERM(PERM_VALID))
{
str_lower(email, cuser.email);
/* 檢查 .ee##(g)@nctu.edu.tw */
if (str = (char *) strchr(email, '.'))
{
if (*(str + 1) == 'e' && *(str + 2) == 'e' &&
(!strcmp(str + 5, "@nctu.edu.tw") || !strcmp(str + 5, "g@nctu.edu.tw")))
{
return 1;
}
}
/* 檢查 u##11###@cc.nctu.edu.tw */
if (strlen(email) == 23)
{
if (email[0] == 'u' && email[3] == '1' && email[4] == '1' &&
!strcmp(email + 8, "@cc.nctu.edu.tw"))
{
return 1;
}
}
}
// 以上這一段要由各站自定
return 0;
}
static int
nbrd_add(xo)
XO *xo;
{
int fd, readlevel;
char *dir, fpath[80], path[80], *plevel;
char *brdname, *title;
FILE *fp;
NBRD nbrd;
if (!cuser.userlevel)
return XO_NONE;
memset(&nbrd, 0, sizeof(NBRD));
brdname = nbrd.brdname;
title = nbrd.title;
if (!vget(b_lines, 0, "英文板名:", brdname, BNLEN + 1, DOECHO))
return XO_FOOT;
if (brd_bno(brdname) >= 0)
{
vmsg("已有此板");
return XO_FOOT;
}
if (!valid_brdname(brdname)) /* itoc.020726: 檢查板名是否合法 */
{
vmsg("板名不合法");
return XO_FOOT;
}
// 以下這一段要由各站自定
switch (vans("看板分類:1)個人 2)寢板 3)班板 4)黨羽 5)營隊 6)其他 [Q] "))
{
case '1':
plevel = "個人";
break;
case '2':
plevel = "寢板";
break;
case '3':
plevel = "班板";
break;
case '4':
plevel = "黨羽";
break;
case '5':
plevel = "營隊";
break;
case '6':
plevel = "??"; /* 讓站長自己手動改 */
vmsg("請於補充事項中註明您要的看板分類");
break;
default:
return XO_FOOT;
}
// 以上這一段要由各站自定
strcpy(nbrd.class, plevel);
readlevel = vans("看板屬性:1)公開 2)秘密 3)好友 [Q] ") - '0';
switch (readlevel)
{
case 1:
plevel = "公開";
break;
case 2:
plevel = "秘密";
break;
case 3:
plevel = "好友";
break;
default:
return XO_FOOT;
}
if (!vget(b_lines, 0, "看板主題:", title, BTLEN + 1, DOECHO))
return XO_FOOT;
dir = xo->dir;
if ((fd = nbrd_stamp(dir, &nbrd, fpath)) < 0)
return nbrd_head(xo);
close(fd);
vmsg("還有要補充什麼嗎?[例如轉信、諂媚站長的話...:p]");
sprintf(path, "tmp/%s.nbrd", cuser.userid); /* 連署原因的暫存檔案 */
fd = vedit(path, 0);
if (fd)
{
unlink(fpath);
vmsg(msg_cancel);
return nbrd_head(xo);
}
strcpy(nbrd.owner, cuser.userid);
nbrd.readlevel = readlevel;
nbrd.mode = is_vip_apply() ? NBRD_VIPAPPLY : 0;
rec_add(dir, &nbrd, sizeof(NBRD));
fp = fopen(fpath, "a+");
fprintf(fp, "作者: %s (%s) 站內: 看板申請\n", cuser.userid, cuser.username);
fprintf(fp, "標題: [看板申請] %s\n", brdname);
fprintf(fp, "時間: %s\n\n", Now());
fprintf(fp, "英文板名:%s\n", brdname);
fprintf(fp, "看板分類:%s\n", nbrd.class);
fprintf(fp, "看板主題:%s\n", title);
fprintf(fp, "板主名稱:%s\n", nbrd.owner);
fprintf(fp, "看板屬性:%s\n\n\n", plevel);
f_suck(fp, path);
unlink(path);
fprintf(fp, "\n--\n□ 本文章由 %s 從 %s 申請\n", cuser.userid, fromhost);
fclose(fp);
vmsg("請等待站長開板");
return nbrd_init(xo);
}
static int /* 1:開板成功 */
nbrd_newbrd(nbrd) /* 開新版 */
NBRD *nbrd;
{
BRD newboard;
ACCT acct;
memset(&newboard, 0, sizeof(BRD));
/* itoc.010805: 新看板預設 battr = 不轉信; 看板板主為提起連署者 */
switch (nbrd->readlevel)
{
case 2: /* 秘密 */
newboard.readlevel = PERM_SYSOP;
newboard.battr = BRD_NOTRAN | BRD_NOSTAT | BRD_NOVOTE;
break;
case 3: /* 好友 */
newboard.readlevel = PERM_BOARD;
newboard.battr = BRD_NOTRAN | BRD_NOSTAT | BRD_NOVOTE;
break;
default: /* 公開 */
newboard.postlevel = PERM_POST;
newboard.battr = BRD_NOTRAN;
break;
}
strcpy(newboard.brdname, nbrd->brdname);
strcpy(newboard.class, nbrd->class);
strcpy(newboard.title, nbrd->title);
strcpy(newboard.BM, nbrd->owner);
if (acct_load(&acct, nbrd->owner) >= 0)
acct_setperm(&acct, PERM_BM, 0);
if (brd_new(&newboard) < 0)
return 0;
vmsg("新板成立,記著加入分類群組");
return 1;
}
static int
nbrd_open(xo)
XO *xo;
{
NBRD *nbrd;
if (!HAS_PERM(PERM_ALLBOARD))
return XO_NONE;
nbrd = (NBRD *) xo_pool + (xo->pos - xo->top);
/* itoc.030519: 避免重覆開板 */
if (brd_bno(nbrd->brdname) >= 0)
{
nbrd->mode = NBRD_FINISH;
currchrono = nbrd->btime;
rec_put(xo->dir, nbrd, sizeof(NBRD), xo->pos, cmpbtime);
vmsg("已有此板");
return nbrd_init(xo);
}
if (nbrd->mode & NBRD_FINISH)
{
vmsg("已完成開板");
}
else
{
if (vans("請確定開啟看板(Y/N)?[N] ") == 'y')
{
if (nbrd_newbrd(nbrd))
{
nbrd->mode = NBRD_FINISH;
currchrono = nbrd->btime;
rec_put(xo->dir, nbrd, sizeof(NBRD), xo->pos, cmpbtime);
}
return nbrd_init(xo);
}
}
return XO_FOOT;
}
static int
nbrd_browse(xo)
XO *xo;
{
int key;
NBRD *nbrd;
char fpath[80];
/* itoc.010304: 為了讓閱讀到一半也可以加入連署,考慮 more 傳回值 */
for (;;)
{
nbrd = (NBRD *) xo_pool + (xo->pos - xo->top);
nbrd_fpath(fpath, xo->dir, nbrd);
if ((key = more(fpath, FOOTER_COSIGN)) < 0)
break;
if (!key)
key = vkey();
switch (key)
{
case KEY_UP:
case KEY_PGUP:
case '[':
case 'k':
key = xo->pos - 1;
if (key < 0)
break;
xo->pos = key;
if (key <= xo->top)
{
xo->top = (key / XO_TALL) * XO_TALL;
nbrd_load(xo);
}
continue;
case KEY_DOWN:
case KEY_PGDN:
case ']':
case 'j':
case ' ':
key = xo->pos + 1;
if (key >= xo->max)
break;
xo->pos = key;
if (key >= xo->top + XO_TALL)
{
xo->top = (key / XO_TALL) * XO_TALL;
nbrd_load(xo);
}
continue;
case 'h':
xo_help("cosign");
break;
}
break;
}
return nbrd_head(xo);
}
static int
nbrd_delete(xo)
XO *xo;
{
NBRD *nbrd;
char fpath[80];
nbrd = (NBRD *) xo_pool + (xo->pos - xo->top);
if (strcmp(cuser.userid, nbrd->owner) && !HAS_PERM(PERM_ALLBOARD))
return XO_NONE;
if (vans(MSG_DEL_NY) != 'y')
return nbrd_head(xo);
nbrd_fpath(fpath, xo->dir, nbrd);
unlink(fpath);
rec_del(xo->dir, sizeof(NBRD), xo->pos, NULL);
return nbrd_init(xo);
}
static int
nbrd_edit(xo)
XO *xo;
{
if (HAS_PERM(PERM_ALLBOARD))
{
char fpath[64];
NBRD *nbrd;
nbrd = (NBRD *) xo_pool + (xo->pos - xo->top);
nbrd_fpath(fpath, xo->dir, nbrd);
vedit(fpath, 0);
return nbrd_head(xo);
}
return XO_NONE;
}
static int
nbrd_uquery(xo)
XO *xo;
{
NBRD *nbrd;
nbrd = (NBRD *) xo_pool + (xo->pos - xo->top);
move(1, 0);
clrtobot();
my_query(nbrd->owner);
return nbrd_head(xo);
}
static int
nbrd_usetup(xo)
XO *xo;
{
NBRD *nbrd;
ACCT acct;
if (!HAS_PERM(PERM_ALLACCT))
return XO_NONE;
nbrd = (NBRD *) xo_pool + (xo->pos - xo->top);
if (acct_load(&acct, nbrd->owner) < 0)
return XO_NONE;
move(3, 0);
acct_setup(&acct, 1);
return nbrd_head(xo);
}
static int
nbrd_help(xo)
XO *xo;
{
xo_help("cosign");
return nbrd_head(xo);
}
static KeyFunc nbrd_cb[] =
{
XO_INIT, nbrd_init,
XO_LOAD, nbrd_load,
XO_HEAD, nbrd_head,
XO_BODY, nbrd_body,
'r', nbrd_browse,
'd', nbrd_delete,
'E', nbrd_edit,
'o', nbrd_open,
Ctrl('P'), nbrd_add,
Ctrl('Q'), nbrd_uquery,
Ctrl('O'), nbrd_usetup,
'h', nbrd_help
};
int
XoNewBoard()
{
XO *xo;
char fpath[64];
sprintf(fpath, "run/newbrd/%s", fn_dir);
xz[XZ_COSIGN - XO_ZONE].xo = xo = xo_new(fpath);
xz[XZ_COSIGN - XO_ZONE].cb = nbrd_cb;
xo->key = XZ_COSIGN;
xover(XZ_COSIGN);
free(xo);
return 0;
}
#endif /* HAVE_COSIGN */
--
□ 本文章由 itoc 從 itoc.Dorm11.NCTU.edu.tw 發表