summaryrefslogtreecommitdiffstats
path: root/mbbsd
diff options
context:
space:
mode:
authorpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2008-02-21 20:17:13 +0800
committerpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2008-02-21 20:17:13 +0800
commit4f221c083ad2f233ecfc13a8a970a598c62a2671 (patch)
tree6271b6521999bd8e97cf7a412b1345da5efa644e /mbbsd
parent95262b83a086058fc778fff20ac9c7ee76575494 (diff)
downloadpttbbs-4f221c083ad2f233ecfc13a8a970a598c62a2671.tar
pttbbs-4f221c083ad2f233ecfc13a8a970a598c62a2671.tar.gz
pttbbs-4f221c083ad2f233ecfc13a8a970a598c62a2671.tar.bz2
pttbbs-4f221c083ad2f233ecfc13a8a970a598c62a2671.tar.lz
pttbbs-4f221c083ad2f233ecfc13a8a970a598c62a2671.tar.xz
pttbbs-4f221c083ad2f233ecfc13a8a970a598c62a2671.tar.zst
pttbbs-4f221c083ad2f233ecfc13a8a970a598c62a2671.zip
- board: comment on symlink
- admin: code-refine for new admin regform validation. git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@3934 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
Diffstat (limited to 'mbbsd')
-rw-r--r--mbbsd/admin.c589
-rw-r--r--mbbsd/board.c1
2 files changed, 290 insertions, 300 deletions
diff --git a/mbbsd/admin.c b/mbbsd/admin.c
index 2c9c6475..8642f3e6 100644
--- a/mbbsd/admin.c
+++ b/mbbsd/admin.c
@@ -1145,12 +1145,15 @@ auto_scan(char fdata[][STRLEN], char ans[])
}
#define REJECT_REASONS (6)
+#define FN_REGISTER_LOG "register.log"
+
/* 處理 Register Form */
+// TODO XXX process someone directly, according to target_uid.
int
-scan_register_form(const char *regfile, int automode)
+scan_register_form(const char *regfile, int automode, const char *target_uid)
{
char genbuf[200];
- char *logfile = "register.log";
+ char *logfile = FN_REGISTER_LOG;
char *field[] = {
"uid", "name", "career", "addr", "phone", "email", NULL
};
@@ -1559,351 +1562,337 @@ regform_reject(const char *userid, char *reason)
mail_muser(muser, "[註冊失敗]", buf);
}
+// TODO define and use structure instead, even in reg request file.
+//
+typedef struct {
+ // current format:
+ // [0] uid: xxxxx (IDLEN=12)
+ // [1] name: RRRRRR (20)
+ // [2] career: YYYYYYYYYYYYYYYYYYYYYYYYYY (40)
+ // [3] addr: TTTTTTTTT (50)
+ // [4] phone: 02DDDDDDDD (20)
+ // [5] email: x (50) (deprecated)
+ // [6] ----
+ char userid[IDLEN+1];
+ char pad [ 7]; // IDLEN(12)+1+7=20
+ char name [20];
+ char career[40];
+ char addr [50];
+ char phone [20];
+} RegformEntry;
+
int
-reglog_append(FILE *fp, const char *logfn, const char *uid, const char *varname,
- const char *varval1, const char *varval2)
+load_regform_entry(RegformEntry *pre, FILE *fp)
+{
+ char buf[STRLEN];
+ char *v;
+
+ memset(pre, 0, sizeof(RegformEntry));
+ while (fgets(buf, sizeof(buf), fp))
+ {
+ if (buf[0] == '-')
+ break;
+ buf[sizeof(buf)-1] = 0;
+ v = strchr(buf, ':');
+ if (v == NULL)
+ continue;
+ *v++ = 0;
+ if (*v == ' ') v++;
+ chomp(v);
+
+ if (strcmp(buf, "uid") == 0)
+ strlcpy(pre->userid, v, sizeof(pre->userid));
+ else if (strcmp(buf, "name") == 0)
+ strlcpy(pre->name, v, sizeof(pre->name));
+ else if (strcmp(buf, "career") == 0)
+ strlcpy(pre->career, v, sizeof(pre->career));
+ else if (strcmp(buf, "addr") == 0)
+ strlcpy(pre->addr, v, sizeof(pre->addr));
+ else if (strcmp(buf, "phone") == 0)
+ strlcpy(pre->phone, v, sizeof(pre->phone));
+ }
+ return pre->userid[0] ? 1 : 0;
+}
+
+int
+print_regform_entry(const RegformEntry *pre, FILE *fp, int close)
+{
+ fprintf(fp, "uid: %s\n", pre->userid);
+ fprintf(fp, "name: %s\n", pre->name);
+ fprintf(fp, "career: %s\n", pre->career);
+ fprintf(fp, "addr: %s\n", pre->addr);
+ fprintf(fp, "phone: %s\n", pre->phone);
+ fprintf(fp, "email: %s\n", "x");
+ if (close)
+ fprintf(fp, "----\n");
+ return 1;
+}
+
+int
+append_regform(const RegformEntry *pre, const char *logfn,
+ const char *varname, const char *varval1, const char *varval2)
{
- char buf[STRLEN] = "";
FILE *fout = fopen(logfn, "at");
if (!fout)
return 0;
- while (buf[0] != '-' && fgets(buf, sizeof(buf), fp))
+ print_regform_entry(pre, fout, 0);
+ if (varname && *varname)
{
- if (buf[0] == '-' && varname && *varname)
- {
- syncnow();
- fprintf(fout, "Date: %s\n", Cdate(&now));
- fprintf(fout, "%s: ", varname);
- if (varval1) fprintf(fout, varval1);
- if (varval2) fprintf(fout, " %s", varval2);
- fprintf(fout, "\n");
- }
- fputs(buf, fout);
+ syncnow();
+ fprintf(fout, "Date: %s\n", Cdate(&now));
+ if (!varval1) varval1 = "";
+ fprintf(fout, "%s: %s", varname, varval1);
+ if (varval2) fprintf(fout, " %s", varval2);
+ fprintf(fout, "\n");
}
-
+ // close it
+ fprintf(fout, "----\n");
fclose(fout);
return 1;
}
int
-review_register_form(const char *regfile, int dryrun)
+handle_register_form(const char *regfile, int dryrun)
{
- // current format:
- // [0] uid: xxxxx (IDLEN=12)
- // [1] name: RRRRRR (20)
- // [2] career: YYYYYYYYYYYYYYYYYYYYYYYYYY (40)
- // [3] addr: TTTTTTTTT (50)
- // [4] phone: 02DDDDDDDD (20)
- // [5] email: x (50)
- // [6] ----
- int fpos = 0;
- char fname[PATHLEN] = "";
- char buf[STRLEN], *v = NULL;
- char forms[FORMS_IN_PAGE][IDLEN+1];
- char ans[FORMS_IN_PAGE];
- char justify[FORMS_IN_PAGE][REGLEN+1];
- char tmpcareer[40];
- char rejects[FORMS_IN_PAGE][REASON_LEN]; // reject reason length
- int yMsg = FORMS_IN_PAGE*2+1;
- int fi = 0, // field index
- ri = 0, // screen row index
- ci = 0, // cursor index
- ti = 0, // total form index
- ch = 0; // input key
FILE *fp = NULL;
userec_t muser;
int unum = 0;
+ RegformEntry forms [FORMS_IN_PAGE];
+ char ans [FORMS_IN_PAGE];
+ char rejects[FORMS_IN_PAGE][REASON_LEN]; // reject reason length
+ char justify[REGLEN+1];
+ int yMsg = FORMS_IN_PAGE*2+1;
+ int cforms = 0, // current loaded forms
+ parsed = 0, // total parsed forms
+ ci = 0, // cursor index
+ ch = 0, // input key
+ i, blanks;
- // prepare reg tickets
- if (dryrun)
- {
- // directly open regfile to try
- fp = fopen(regfile, "rt");
- } else {
- snprintf(fname, sizeof(fname), "%s.tmp", regfile);
- move(2, 0);
- if (dashf(fname)) {
- vmsg("其他 SYSOP 也在審核註冊申請單");
- return -1;
- }
- Rename(regfile, fname);
-
- if ((fp = fopen(fname, "r")) == NULL) {
- vmsgf("系統錯誤,無法讀取註冊資料檔: %s", fname);
- return -1;
- }
- }
+ fp = fopen(regfile, "rt");
if (!fp)
return 0;
- clear();
- fpos = ftell(fp);
- memset(ans, 0, sizeof(ans));
-
- while (fgets(buf, sizeof(buf), fp))
+ while (ch != 'q')
{
- if (buf[0] == '-')
- {
- // next user!
- // assert(fi >= 4);
- fi = 0; ti++;
- ri++; ri %= FORMS_IN_PAGE;
-
- if (ri != 0)
- continue;
-
- // ri == 0, let's navigate through this page.
- move(FORMS_IN_PAGE*2, 0); clrtobot();
- prompt_regform_ui();
-
- do {
- ch = cursor_key(ci*2, 0);
- switch (ch)
- {
- // nav keys
- case KEY_UP:
- case 'k':
- if (ci > 0) ci--;
- break;
-
- case KEY_DOWN:
- case 'j':
- ch = 'j'; // go next
- break;
-
- // quick nav (assuming to FORMS_IN_PAGE=10)
- case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
- ci = ch - '1';
- break;
- case '0':
- ci = 10-1;
- break;
-
- // go next page
- case KEY_PGDN:
- case ' ':
- ch = ' ';
- break;
-
- // abort
- case KEY_END:
- case 'q':
- ch = 'q';
- if (getans("確定要離開了嗎? (本頁變更將不會儲存) [y/N]: ") != 'y')
- {
- prompt_regform_ui();
- ch = 0;
- continue;
- }
- break;
+ // initialize and prepare
+ memset(ans, 0, sizeof(ans));
+ memset(rejects, 0, sizeof(rejects));
+ cforms = 0;
- // function keys
- case 's': // skip
- case 'y': // accept
- case 'd': // delete
- case KEY_DEL: //delete
- if (ch == KEY_DEL) ch = 'd';
-
- grayout(ci*2, ci*2+1, GRAYOUT_DARK);
- move_ansi(ci*2, 4); outc(ch);
- ans[ci] = ch;
- ch = 'j'; // go next
- break;
+ // load forms
+ while (cforms < FORMS_IN_PAGE && load_regform_entry(&forms[cforms], fp))
+ cforms++, parsed ++;
- case 'u': // undo
- grayout(ci*2, ci*2+1, GRAYOUT_NORM);
- move_ansi(ci*2, 4); outc('.');
- ans[ci] = 0;
- ch = 'j'; // go next
- break;
+ // if no more forms then leave.
+ if (cforms < 1)
+ break;
- case 'n': // reject
- // query for reason
- resolve_reason(rejects[ci], yMsg);
- move(yMsg, 0);
- prints(" %s 退回原因:\n %s\n", forms[ci], rejects[ci]);
+ // display them all.
+ clear();
+ for (i = 0; i < cforms; i++)
+ {
+ // fetch user information
+ memset(&muser, 0, sizeof(muser));
+ unum = getuser(forms[i].userid, &muser);
+
+ // if already got login level, delete by default.
+ if (unum && (muser.userlevel & PERM_LOGINOK))
+ ans[i] = 'd';
+
+ // print
+ move(i*2, 0);
+ prints(" %2d.%s%s%-12s " ANSI_RESET,
+ i+1,
+ (unum && search_ulist(unum)) ?
+ ANSI_COLOR(1;35) : "" ANSI_COLOR(1),
+ (unum == 0) ? ANSI_COLOR(1;31) "D" ANSI_RESET :
+ ( (muser.userlevel & PERM_LOGINOK) ?
+ ANSI_COLOR(1;33) "Y" ANSI_RESET : " "),
+ forms[i].userid);
+
+ prints( ANSI_COLOR(1;31) "%19s "
+ ANSI_COLOR(1;32) "%-40s" ANSI_RESET"\n",
+ forms[i].name, forms[i].career);
+
+ move(i*2+1, 0);
+ prints(" %-50s%20s\n", forms[i].addr, forms[i].phone);
+ }
- // do reject
- grayout(ci*2, ci*2+1, GRAYOUT_DARK);
- move_ansi(ci*2, 4); outc(ch);
- ans[ci] = ch;
- ch = 'j'; // go next
+ // handle user input
+ prompt_regform_ui();
+ ch = 0;
+ while (ch != 'q' && ch != ' ') {
+ ch = cursor_key(ci*2, 0);
+ switch (ch)
+ {
+ // nav keys
+ case KEY_UP:
+ case 'k':
+ if (ci > 0) ci--;
+ break;
- prompt_regform_ui();
- break;
- }
- if (ch == 'j' && ++ci >= FORMS_IN_PAGE)
- ci = FORMS_IN_PAGE -1;
- } while (ch != 'q' && ch != ' ');
+ case KEY_DOWN:
+ case 'j':
+ ch = 'j'; // go next
+ break;
- if (ch == 'q')
- break;
+ // quick nav (assuming to FORMS_IN_PAGE=10)
+ case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9':
+ ci = ch - '1';
+ break;
+ case '0':
+ ci = 10-1;
+ break;
- if (ch == ' ')
- {
- // save and go next page.
- int i, blanks = 0, nowpos = ftell(fp);
- // solving blank (undecided entries)
- for (i = 0; i < FORMS_IN_PAGE; i++)
- if (ans[i] == 0) blanks ++;
- if (blanks) {
- char rsn[REASON_LEN];
- ch = getans("尚未指定的 %d 個項目要: (S跳過/y通過/n拒絕): ", blanks);
- if (ch == 'y') {
- // do nothing.
- } else if (ch == 'n') {
- // query reject reason
- resolve_reason(rsn, yMsg);
- } else ch = 's';
-
- for (i = 0; i < FORMS_IN_PAGE; i++)
- {
- if (ans[i] != 0)
- continue;
- ans[i] = ch;
- if (ch != 'n')
- continue;
- strlcpy(rejects[i], rsn, REASON_LEN);
- }
- }
+ // go next page
+ case KEY_PGDN:
+ case ' ':
+ ch = ' ';
+ break;
- if (dryrun)
- {
- // prmopt for debug
- clear();
- stand_title("測試模式");
- outs("您正在執行測試模式,所以剛審的註冊單並不會生效。\n"
- "下面列出的是剛才您審完的結果:\n\n");
- for (i = 0; i < FORMS_IN_PAGE; i++)
+ // abort
+ case KEY_END:
+ case 'q':
+ ch = 'q';
+ if (getans("確定要離開了嗎? (本頁變更將不會儲存) [y/N]: ") != 'y')
{
- prints("%2d. %-12s - %c %s\n", i+1, forms[i], ans[i],
- ans[i] == 'n' ? rejects[i] :
- ans[i] == 'y' ? justify[i] : "");
+ prompt_regform_ui();
+ ch = 0;
+ continue;
}
- pressanykey();
-
- } else {
+ break;
- // real functionality
-
- fseek(fp, fpos, SEEK_SET); // handle entries
+ // function keys
+ case 's': // skip
+ case 'y': // accept
+ case 'd': // delete
+ case KEY_DEL: //delete
+ if (ch == KEY_DEL) ch = 'd';
+
+ grayout(ci*2, ci*2+1, GRAYOUT_DARK);
+ move_ansi(ci*2, 4); outc(ch);
+ ans[ci] = ch;
+ ch = 'j'; // go next
+ break;
- for (i = 0; i < FORMS_IN_PAGE; i++)
- {
- if (ans[i] == 'y')
- {
- regform_accept(forms[i], justify[i]);
- // log form to "register.log"
- reglog_append(fp, "register.log",
- forms[i], "Approved",
- cuser.userid, NULL);
- }
- else if (ans[i] == 'n')
- {
- regform_reject(forms[i], rejects[i]);
- // log form to "register.log"
- reglog_append(fp, "register.log",
- forms[i], "Rejected",
- cuser.userid, rejects[i]);
- }
- else if (ans[i] == 's')
- {
- // append form back to fn_register
- reglog_append(fp, fn_register,
- forms[i], NULL, NULL, NULL);
- }
- }
+ case 'u': // undo
+ grayout(ci*2, ci*2+1, GRAYOUT_NORM);
+ move_ansi(ci*2, 4); outc('.');
+ ans[ci] = 0;
+ ch = 'j'; // go next
+ break;
- fseek(fp, nowpos, SEEK_SET);
- fpos = ftell(fp);
- }
+ case 'n': // reject
+ // query for reason
+ resolve_reason(rejects[ci], yMsg);
+ move(yMsg, 0);
+ prints(" %s 退回原因:\n %s\n", forms[ci].userid, rejects[ci]);
- // reset ans for next run
- memset(ans, 0, sizeof(ans));
- }
- continue;
+ // do reject
+ grayout(ci*2, ci*2+1, GRAYOUT_DARK);
+ move_ansi(ci*2, 4); outc(ch);
+ ans[ci] = ch;
+ ch = 'j'; // go next
- } else { // normal fields, try to display it.
+ prompt_regform_ui();
+ break;
+ } // switch(ch)
- v = strchr(buf, ':');
- assert(v != NULL);
- // strip and alter value pointer
- *v = 0;
+ // change cursor
+ if (ch == 'j' && ++ci >= cforms)
+ ci = cforms -1;
+ } // while(ch != QUIT/SAVE)
- if (fi == 0 && strcmp(buf, "uid") != 0)
- continue;
+ // quick exit
+ if (ch == 'q')
+ break;
- v += 2; // ': '
- chomp(v);
+ // page complete (save).
+ assert(ch == ' ');
+
+ // solving blank (undecided entries)
+ for (i = 0, blanks = 0; i < FORMS_IN_PAGE; i++)
+ if (ans[i] == 0) blanks ++;
+ if (blanks) {
+ char rsn[REASON_LEN];
+ ch = getans("尚未指定的 %d 個項目要: (S跳過/y通過/n拒絕): ", blanks);
+ if (ch == 'y') {
+ // do nothing.
+ } else if (ch == 'n') {
+ // query reject reason
+ resolve_reason(rsn, yMsg);
+ } else ch = 's';
+
+ for (i = 0; i < cforms; i++)
+ {
+ if (ans[i] != 0)
+ continue;
+ ans[i] = ch;
+ if (ch != 'n')
+ continue;
+ strlcpy(rejects[i], rsn, REASON_LEN);
+ }
}
- switch(fi++)
+ // save/commit if required.
+ if (dryrun)
{
- case 0: move(ri*2, 0);
- memset(&muser, 0, sizeof(muser));
- memset(justify[ri], 0, sizeof(justify[ri]));
- memset(tmpcareer, 0, sizeof(tmpcareer));
- unum = getuser(v, &muser);
- if (unum == 0) muser.userid[0] = 0;
- prints(" %2d.%s%s%-12s "ANSI_RESET,
- ri+1,
- (unum && search_ulist(unum)) ?
- ANSI_COLOR(1;35) : "" ANSI_COLOR(1),
- (unum == 0) ? ANSI_COLOR(1;31) "D" ANSI_RESET :
- ( (muser.userlevel & PERM_LOGINOK) ?
- ANSI_COLOR(1;33) "Y" ANSI_RESET : " "),
- v);
- strlcpy(forms[ri], v, sizeof(forms[ri]));
-
- // if already got login level, delete by default.
- if (unum && (muser.userlevel & PERM_LOGINOK))
- ans[ri] = 'd';
+ // prmopt for debug
+ clear();
+ stand_title("測試模式");
+ outs("您正在執行測試模式,所以剛審的註冊單並不會生效。\n"
+ "下面列出的是剛才您審完的結果:\n\n");
- break;
+ for (i = 0; i < cforms; i++)
+ {
+ if (ans[i] == 'y')
+ snprintf(justify, sizeof(justify), // build justify string
+ "%s:%s:%s", forms[i].phone, forms[i].career, cuser.userid);
- case 1: prints(ANSI_COLOR(1;31)"%19s "ANSI_RESET, v);
- break;
- case 2: prints(ANSI_COLOR(1;32)"%-40s"ANSI_RESET"\n", v);
- // career
- strlcpy(tmpcareer, v, sizeof(tmpcareer));
- break;
- case 3: move(ri*2+1, 0);
- prints(" %-50s", v);
- break;
- case 4: prints("%20s\n", v);
+ prints("%2d. %-12s - %c %s\n", i+1, forms[i].userid, ans[i],
+ ans[i] == 'n' ? rejects[i] :
+ ans[i] == 'y' ? justify : "");
+ }
+ pressanykey();
+ }
+ else
+ {
+ // real functionality
+ for (i = 0; i < cforms; i++)
+ {
+ if (ans[i] == 'y')
+ {
// build justify string
- snprintf(justify[ri], sizeof(justify[ri]),
- "%s:%s:%s", v, tmpcareer, cuser.userid);
- break;
- case 5: // no need to print
- case 6:
- default:
- break;
- }
- }
+ snprintf(justify, sizeof(justify),
+ "%s:%s:%s", forms[i].phone, forms[i].career, cuser.userid);
+ regform_accept(forms[i].userid, justify);
+ // log form to FN_REGISTER_LOG
+ append_regform(&forms[i], FN_REGISTER_LOG,
+ "Approved", cuser.userid, NULL);
+ }
+ else if (ans[i] == 'n')
+ {
+ regform_reject(forms[i].userid, rejects[i]);
+ // log form to FN_REGISTER_LOG
+ append_regform(&forms[i], FN_REGISTER_LOG,
+ "Rejected", cuser.userid, rejects[i]);
+ }
+ else if (ans[i] == 's')
+ {
+ // append form back to fn_register
+ append_regform(&forms[i], fn_register,
+ NULL, NULL, NULL);
+ }
+ }
+ } // !dryrun
- if (!dryrun)
- {
- // restore trailing tickets
- FILE *fout = fopen(regfile, "at");
- if (fout)
- {
- fseek(fp, fpos, SEEK_SET);
- while (fgets(buf, sizeof(buf), fp))
- fputs(buf, fout);
- fclose(fout);
- }
- }
+ } // while (ch != 'q')
fclose(fp);
-
- if (!dryrun)
- unlink(fname);
-
return 0;
}
@@ -1943,13 +1932,13 @@ m_register(void)
#ifdef EXP_ADMIN_REGFORM
"開始審核嗎(Auto自動/Yes手動/No不審/Exp新界面)?[N] ",
#else
- "開始審核嗎(Auto/Yes/No)?[N] ",
+ "開始審核嗎(Auto自動/Yes手動/No不審)?[N] ",
#endif
ans, sizeof(ans), LCECHO);
if (ans[0] == 'a')
- scan_register_form(fn_register, 1);
+ scan_register_form(fn_register, 1, NULL);
else if (ans[0] == 'y')
- scan_register_form(fn_register, 0);
+ scan_register_form(fn_register, 0, NULL);
#ifdef EXP_ADMIN_REGFORM
else if (ans[0] == 'e')
@@ -1959,7 +1948,7 @@ m_register(void)
"請注意: 等下一切審核、刪除、等等動作都是假的,不會真的寫入系統。");
pressanykey();
- review_register_form(fn_register, 1);
+ handle_register_form(fn_register, 1);
}
#endif
diff --git a/mbbsd/board.c b/mbbsd/board.c
index 7fa74f5c..18ae88e7 100644
--- a/mbbsd/board.c
+++ b/mbbsd/board.c
@@ -1654,6 +1654,7 @@ choose_board(int newflag)
case 'L':
if ((HasUserPerm(PERM_SYSOP) ||
(HasUserPerm(PERM_SYSSUPERSUBOP) && GROUPOP())) && IN_CLASS()) {
+ // TODO XXX why need symlink here? Can we remove it?
if (make_symbolic_link_interactively(class_bid) < 0)
break;
brdnum = -1;