diff options
Diffstat (limited to 'mbbsd/admin.c')
-rw-r--r-- | mbbsd/admin.c | 1087 |
1 files changed, 0 insertions, 1087 deletions
diff --git a/mbbsd/admin.c b/mbbsd/admin.c index 0bb424db..d0efa3e1 100644 --- a/mbbsd/admin.c +++ b/mbbsd/admin.c @@ -164,9 +164,6 @@ search_key_user(const char *passwdfile, int mode) else if ((!keytype || keytype == 7) && strcasestr(user.justify, key)) keymatch = user.justify; - else if ((!keytype) && - strcasestr(user.mychicken.name, key)) - keymatch = user.mychicken.name; } if(keymatch) { @@ -1061,1090 +1058,6 @@ int make_symbolic_link_interactively(int gid) return 0; } -/* FIXME 真是一團垃圾 - * - * fdata 用了太多 magic number - * return value 應該是指 reason (return index + 1) - * ans[0] 指的是帳管選擇的「錯誤的欄位」 (Register 選單裡看到的那些) - */ -static int -auto_scan(char fdata[][STRLEN], char ans[]) -{ - int good = 0; - int count = 0; - int i; - char temp[10]; - - if (!strncmp(fdata[1], "小", 2) || strstr(fdata[1], "丫") - || strstr(fdata[1], "誰") || strstr(fdata[1], "不")) { - ans[0] = '0'; - return 1; - } - strlcpy(temp, fdata[1], 3); - - /* 疊字 */ - if (!strncmp(temp, &(fdata[1][2]), 2)) { - ans[0] = '0'; - return 1; - } - if (strlen(fdata[1]) >= 6) { - if (strstr(fdata[1], "陳水扁")) { - ans[0] = '0'; - return 1; - } - if (strstr("趙錢孫李周吳鄭王", temp)) - good++; - else if (strstr("杜顏黃林陳官余辛劉", temp)) - good++; - else if (strstr("蘇方吳呂李邵張廖應蘇", temp)) - good++; - else if (strstr("徐謝石盧施戴翁唐", temp)) - good++; - } - if (!good) - return 0; - - if (!strcmp(fdata[2], fdata[3]) || - !strcmp(fdata[2], fdata[4]) || - !strcmp(fdata[3], fdata[4])) { - ans[0] = '4'; - return 5; - } - if (strstr(fdata[2], "大")) { - if (strstr(fdata[2], "台") || strstr(fdata[2], "淡") || - strstr(fdata[2], "交") || strstr(fdata[2], "政") || - strstr(fdata[2], "清") || strstr(fdata[2], "警") || - strstr(fdata[2], "師") || strstr(fdata[2], "銘傳") || - strstr(fdata[2], "中央") || strstr(fdata[2], "成") || - strstr(fdata[2], "輔") || strstr(fdata[2], "東吳")) - good++; - } else if (strstr(fdata[2], "女中")) - good++; - - if (strstr(fdata[3], "地球") || strstr(fdata[3], "宇宙") || - strstr(fdata[3], "信箱")) { - ans[0] = '2'; - return 3; - } - if (strstr(fdata[3], "市") || strstr(fdata[3], "縣")) { - if (strstr(fdata[3], "路") || strstr(fdata[3], "街")) { - if (strstr(fdata[3], "號")) - good++; - } - } - for (i = 0; fdata[4][i]; i++) { - if (isdigit((int)fdata[4][i])) - count++; - } - - if (count <= 4) { - ans[0] = '3'; - return 4; - } else if (count >= 7) - good++; - - if (good >= 3) { - ans[0] = 'y'; - return -1; - } else - return 0; -} - -#define REJECT_REASONS (6) -#define FN_REGISTER_LOG "register.log" - -// read count entries from regsrc to a temp buffer -FILE * -pull_regform(const char *regfile, char *workfn, int count) -{ - FILE *fp = NULL; - - snprintf(workfn, PATHLEN, "%s.tmp", regfile); - if (dashf(workfn)) { - vmsg("其他 SYSOP 也在審核註冊申請單"); - return NULL; - } - - // count < 0 means unlimited pulling - Rename(regfile, workfn); - if ((fp = fopen(workfn, "r")) == NULL) { - vmsgf("系統錯誤,無法讀取註冊資料檔: %s", workfn); - return NULL; - } - return fp; -} - -// write all left in "remains" to regfn. -void -pump_regform(const char *regfn, FILE *remains) -{ - // restore trailing tickets - char buf[PATHLEN]; - FILE *fout = fopen(regfn, "at"); - if (!fout) - return; - - while (fgets(buf, sizeof(buf), remains)) - fputs(buf, fout); - fclose(fout); -} - -/* 處理 Register Form */ -// TODO XXX process someone directly, according to target_uid. -int -scan_register_form(const char *regfile, int automode, const char *target_uid) -{ - char genbuf[200]; - char *logfile = FN_REGISTER_LOG; - char *field[] = { - "uid", "name", "career", "addr", "phone", "email", NULL - }; - char *finfo[] = { - "帳號", "真實姓名", "服務單位", "目前住址", - "連絡電話", "電子郵件信箱", NULL - }; - char *reason[REJECT_REASONS+1] = { - "輸入真實姓名", - "詳填「(畢業)學校及『系』『級』」或「服務單位(含所屬縣市及職稱)」", - "填寫完整的住址資料 (含縣市名稱, 台北市請含行政區域)", - "詳填連絡電話 (含區域碼, 中間不用加 '-', '(', ')'等符號", - "精確並完整填寫註冊申請表", - "用中文填寫申請單", - NULL - }; - char *autoid = "AutoScan"; - userec_t muser; - FILE *fn, *fout, *freg; - char fdata[6][STRLEN]; - char fname[STRLEN] = "", buf[STRLEN]; - char ans[4], *ptr, *uid; - int n = 0, unum = 0, tid = 0; - int nSelf = 0, nAuto = 0; - - uid = cuser.userid; - move(2, 0); - - fn = pull_regform(regfile, fname, -1); - if (!fn) - return -1; - - while( fgets(genbuf, STRLEN, fn) ){ - memset(fdata, 0, sizeof(fdata)); - do { - if( genbuf[0] == '-' ) - break; - if ((ptr = (char *)strstr(genbuf, ": "))) { - *ptr = '\0'; - for (n = 0; field[n]; n++) { - if (strcmp(genbuf, field[n]) == 0) { - strlcpy(fdata[n], ptr + 2, sizeof(fdata[n])); - if ((ptr = (char *)strchr(fdata[n], '\n'))) - *ptr = '\0'; - } - } - } - } while( fgets(genbuf, STRLEN, fn) ); - tid ++; - - if ((unum = getuser(fdata[0], &muser)) == 0) { - move(2, 0); - clrtobot(); - outs("系統錯誤,查無此人\n\n"); - for (n = 0; field[n]; n++) - prints("%s : %s\n", finfo[n], fdata[n]); - pressanykey(); - } else { - if (automode) - uid = autoid; - - if ((!automode || !auto_scan(fdata, ans))) { - uid = cuser.userid; - - move(1, 0); - clrtobot(); - prints("帳號位置 : %d\n", unum); - user_display(&muser, 1); - move(14, 0); - prints(ANSI_COLOR(1;32) "------------- " - "請站長嚴格審核使用者資料,這是第 %d 份" - "------------" ANSI_RESET "\n", tid); - prints(" %-12s: %s\n", finfo[0], fdata[0]); -#ifdef FOREIGN_REG - prints("0.%-12s: %s%s\n", finfo[1], fdata[1], - muser.uflag2 & FOREIGN ? " (外籍)" : ""); -#else - prints("0.%-12s: %s\n", finfo[1], fdata[1]); -#endif - for (n = 2; field[n]; n++) { - prints("%d.%-12s: %s\n", n - 1, finfo[n], fdata[n]); - } - if (muser.userlevel & PERM_LOGINOK) { - ans[0] = getkey("此帳號已經完成註冊, " - "更新(Y/N/Skip)?[N] "); - if (ans[0] != 'y' && ans[0] != 's') - ans[0] = 'd'; - } else { - if (search_ulist(unum) == NULL) - { - move(b_lines, 0); clrtoeol(); - outs("是否接受此資料(Y/N/Q/Del/Skip)?[S] "); - // FIXME if the user got online here - ans[0] = igetch(); - } - else - ans[0] = 's'; - ans[0] = tolower(ans[0]); - if (ans[0] != 'y' && ans[0] != 'n' && - ans[0] != 'q' && ans[0] != 'd' && - !('0' <= ans[0] && ans[0] < ('0' + REJECT_REASONS))) - ans[0] = 's'; - ans[1] = 0; - } - nSelf++; - } else - nAuto++; - - switch (ans[0]) { - case 'q': - if ((freg = fopen(regfile, "a"))) { - for (n = 0; field[n]; n++) - fprintf(freg, "%s: %s\n", field[n], fdata[n]); - fprintf(freg, "----\n"); - while (fgets(genbuf, STRLEN, fn)) - fputs(genbuf, freg); - fclose(freg); - } - case 'd': - break; - - case '0': case '1': case '2': - case '3': case '4': case '5': - /* please confirm match REJECT_REASONS here */ - case 'n': - if (ans[0] == 'n') { - int nf = 0; - move(8, 0); - clrtobot(); - outs("請提出退回申請表原因,按 <enter> 取消\n"); - for (n = 0; n < REJECT_REASONS; n++) - prints("%d) 請%s\n", n, reason[n]); - outs("\n"); // preserved for prompt - for (nf = 0; field[nf]; nf++) - prints("%s: %s\n", finfo[nf], fdata[nf]); - } else - buf[0] = ans[0]; - - if (ans[0] != 'n' || - getdata(9 + n, 0, "退回原因: ", buf, 60, DOECHO)) - if ((buf[0] - '0') >= 0 && (buf[0] - '0') < n) { - int i; - fileheader_t mhdr; - char title[128], buf1[80]; - FILE *fp; - - sethomepath(buf1, muser.userid); - stampfile(buf1, &mhdr); - strlcpy(mhdr.owner, cuser.userid, sizeof(mhdr.owner)); - strlcpy(mhdr.title, "[註冊失敗]", TTLEN); - mhdr.filemode = 0; - sethomedir(title, muser.userid); - if (append_record(title, &mhdr, sizeof(mhdr)) != -1) { - char rejfn[PATHLEN]; - fp = fopen(buf1, "w"); - - for(i = 0; buf[i] && i < sizeof(buf); i++){ - if (buf[i] >= '0' && buf[i] < '0'+n) - { - fprintf(fp, "[退回原因] 請%s\n", - reason[buf[i] - '0']); - } - } - - fclose(fp); - - // build reject file - setuserfile(rejfn, "justify.reject"); - Copy(buf1, rejfn); - } - if ((fout = fopen(logfile, "a"))) { - for (n = 0; field[n]; n++) - fprintf(fout, "%s: %s\n", field[n], fdata[n]); - fprintf(fout, "Date: %s\n", Cdate(&now)); - fprintf(fout, "Rejected: %s [%s]\n----\n", - uid, buf); - fclose(fout); - } - break; - } - move(10, 0); - clrtobot(); - outs("取消退回此註冊申請表"); - /* no break? */ - - case 's': - if ((freg = fopen(regfile, "a"))) { - for (n = 0; field[n]; n++) - fprintf(freg, "%s: %s\n", field[n], fdata[n]); - fprintf(freg, "----\n"); - fclose(freg); - } - break; - - default: - outs("以下使用者資料已經更新:\n"); - mail_muser(muser, "[註冊成功\囉]", "etc/registered"); - -#if FOREIGN_REG_DAY > 0 - if(muser.uflag2 & FOREIGN) - mail_muser(muser, "[出入境管理局]", "etc/foreign_welcome"); -#endif - - muser.userlevel |= (PERM_LOGINOK | PERM_POST); - strlcpy(muser.realname, fdata[1], sizeof(muser.realname)); - strlcpy(muser.address, fdata[3], sizeof(muser.address)); - strlcpy(muser.email, fdata[5], sizeof(muser.email)); - snprintf(genbuf, sizeof(genbuf), "%s:%s:%s", - fdata[4], fdata[2], uid); - strlcpy(muser.justify, genbuf, sizeof(muser.justify)); - - passwd_update(unum, &muser); - // XXX TODO notify users? - sendalert(muser.userid, ALERT_PWD_PERM); // force to reload perm - - sethomefile(buf, muser.userid, "justify"); - log_file(buf, LOG_CREAT, genbuf); - - if ((fout = fopen(logfile, "a"))) { - for (n = 0; field[n]; n++) - fprintf(fout, "%s: %s\n", field[n], fdata[n]); - fprintf(fout, "Date: %s\n", Cdate(&now)); - fprintf(fout, "Approved: %s\n", uid); - fprintf(fout, "----\n"); - fclose(fout); - } - sethomefile(genbuf, muser.userid, "justify.wait"); - unlink(genbuf); - break; - } - } - } - - fclose(fn); - unlink(fname); - - move(0, 0); - clrtobot(); - - move(5, 0); - prints("您審了 %d 份註冊單,AutoScan 審了 %d 份", nSelf, nAuto); - - pressanykey(); - return (0); -} - -#ifdef EXP_ADMIN_REGFORM - -#define FORMS_IN_PAGE (10) -#define REASON_LEN (60) -static const char *reasonstr[REJECT_REASONS] = { - "輸入真實姓名", - "詳填(畢業)學校『系』『級』或服務單位(含所屬縣市及職稱)", - "填寫完整的住址資料 (含縣市名稱, 台北市請含行政區域)", - "詳填連絡電話 (含區碼, 中間不加 '-', '(', ')' 等符號)", - "精確並完整填寫註冊申請表", - "用中文填寫申請單", -}; - -#define REASON_FIRSTABBREV '0' -#define REASON_IN_ABBREV(x) \ - ((x) >= REASON_FIRSTABBREV && (x) - REASON_FIRSTABBREV < REJECT_REASONS) -#define REASON_EXPANDABBREV(x) reasonstr[(x) - REASON_FIRSTABBREV] - -static void -prompt_regform_ui() -{ - move(b_lines, 0); - outs(ANSI_COLOR(30;47) " " - ANSI_COLOR(31) "y" ANSI_COLOR(30) "接受 " - ANSI_COLOR(31) "n" ANSI_COLOR(30) "拒絕 " - ANSI_COLOR(31) "d" ANSI_COLOR(30) "刪除 " - ANSI_COLOR(31) "s" ANSI_COLOR(30) "跳過 " - ANSI_COLOR(31) "u" ANSI_COLOR(30) "復原 " - " " - ANSI_COLOR(31) "0-9jk↑↓" ANSI_COLOR(30) "移動 " - ANSI_COLOR(31) "空白/PgDn" ANSI_COLOR(30) "儲存+下頁 " - " " - ANSI_COLOR(31) "q/END" ANSI_COLOR(30) "結束 " - ANSI_RESET); -} - -void -resolve_reason(char *s, int y) -{ - // should start with REASON_FIRSTABBREV - const char *reason_prompt = - " (0)真實姓名 (1)詳填系級 (2)完整住址" - " (3)詳填電話 (4)確實填寫 (5)中文填寫"; - - s[0] = 0; - move(y, 0); - outs(reason_prompt); outs("\n"); - - do { - getdata(y+1, 0, - "退回原因: ", s, REASON_LEN, DOECHO); - - // convert abbrev reasons (format: single digit, or multiple digites) - if (REASON_IN_ABBREV(s[0])) - { - if (s[1] == 0) // simple replace ment - { - strlcpy(s+2, REASON_EXPANDABBREV(s[0]), - REASON_LEN-2); - s[0] = 0xbd; // '請'[0]; - s[1] = 0xd0; // '請'[1]; - } else { - // strip until all digites - char *p = s; - while (*p) - { - if (!REASON_IN_ABBREV(*p)) - *p = ' '; - p++; - } - strip_blank(s, s); - strlcat(s, " [多重原因]", REASON_LEN); - } - } - - if (strlen(s) < 4) - { - if (vmsg("原因太短。 要取消退回嗎? (y/N): ") == 'y') - { - *s = 0; - return; - } - } - } while (strlen(s) < 4); -} - -void -regform_accept(const char *userid, const char *justify) -{ - char buf[PATHLEN]; - int unum = 0; - userec_t muser; - - unum = getuser(userid, &muser); - if (unum == 0) - return; // invalid user - - muser.userlevel |= (PERM_LOGINOK | PERM_POST); - strlcpy(muser.justify, justify, sizeof(muser.justify)); - // manual accept sets email to 'x' - strlcpy(muser.email, "x", sizeof(muser.email)); - - // handle files - sethomefile(buf, muser.userid, "justify.wait"); - unlink(buf); - sethomefile(buf, muser.userid, "justify.reject"); - unlink(buf); - sethomefile(buf, muser.userid, "justify"); - log_filef(buf, LOG_CREAT, "%s\n", muser.justify); - - // update password file - passwd_update(unum, &muser); - - // alert online users? - sendalert(muser.userid, ALERT_PWD_PERM|ALERT_PWD_JUSTIFY); // force to reload perm - -#if FOREIGN_REG_DAY > 0 - if(muser.uflag2 & FOREIGN) - mail_muser(muser, "[出入境管理局]", "etc/foreign_welcome"); - else -#endif - // last: send notification mail - mail_muser(muser, "[註冊成功\囉]", "etc/registered"); -} - -void -regform_reject(const char *userid, char *reason) -{ - char buf[PATHLEN]; - FILE *fp = NULL; - int unum = 0; - userec_t muser; - - unum = getuser(userid, &muser); - if (unum == 0) - return; // invalid user - - muser.userlevel &= ~(PERM_LOGINOK | PERM_POST); - - // handle files - sethomefile(buf, muser.userid, "justify.wait"); - unlink(buf); - - // update password file - passwd_update(unum, &muser); - - // alert notify users? - sendalert(muser.userid, ALERT_PWD_PERM); // force to reload perm - - // last: send notification - mkuserdir(muser.userid); - sethomefile(buf, muser.userid, "justify.reject"); - fp = fopen(buf, "wt"); - assert(fp); - syncnow(); - fprintf(fp, "%s 註冊失敗。\n", Cdate(&now)); - - // multiple abbrev loop - if (REASON_IN_ABBREV(reason[0])) - { - int i = 0; - for (i = 0; i < REASON_LEN && REASON_IN_ABBREV(reason[i]); i++) - fprintf(fp, "[退回原因] 請%s\n", REASON_EXPANDABBREV(reason[i])); - } else { - fprintf(fp, "[退回原因] %s\n", reason); - } - fclose(fp); - mail_muser(muser, "[註冊失敗]", buf); -} - -// TODO define and use structure instead, even in reg request file. -// -typedef struct { - // current format: - // (optional) num: unum, date - // [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] mobile: (deprecated) - // [7] ---- - // lasthost: 16 - char userid[IDLEN+1]; - - char exist; - char online; - char pad [ 5]; // IDLEN(12)+1+1+1+5=20 - - char name [20]; - char career[40]; - char addr [50]; - char phone [20]; -} RegformEntry; - -int -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) -{ - FILE *fout = fopen(logfn, "at"); - if (!fout) - return 0; - - print_regform_entry(pre, fout, 0); - if (varname && *varname) - { - 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; -} - -// #define REGFORM_DISABLE_ONLINE_USER - -int -handle_register_form(const char *regfile, int dryrun) -{ - int unum = 0; - int yMsg = FORMS_IN_PAGE*2+1; - FILE *fp = NULL; - userec_t muser; - RegformEntry forms [FORMS_IN_PAGE]; - char ans [FORMS_IN_PAGE]; - char rejects[FORMS_IN_PAGE][REASON_LEN]; // reject reason length - char fname [PATHLEN] = ""; - char justify[REGLEN+1]; - char rsn [REASON_LEN]; - int cforms = 0, // current loaded forms - parsed = 0, // total parsed forms - ci = 0, // cursor index - ch = 0, // input key - i, blanks; - long fsz = 0, fpos = 0; - - // prepare reg tickets - if (dryrun) - { - // directly open regfile to try - fp = fopen(regfile, "rt"); - } else { - fp = pull_regform(regfile, fname, -1); - } - - if (!fp) - return 0; - - // retreieve file info - fpos = ftell(fp); - fseek(fp, 0, SEEK_END); - fsz = ftell(fp); - fseek(fp, fpos, SEEK_SET); - if (!fsz) fsz = 1; - - while (ch != 'q') - { - // initialize and prepare - memset(ans, 0, sizeof(ans)); - memset(rejects, 0, sizeof(rejects)); - memset(forms, 0, sizeof(forms)); - cforms = 0; - - // load forms - while (cforms < FORMS_IN_PAGE && load_regform_entry(&forms[cforms], fp)) - cforms++, parsed ++; - - // if no more forms then leave. - // TODO what if regform error? - if (cforms < 1) - break; - - // adjust cursor if required - if (ci >= cforms) - ci = cforms-1; - - // display them all. - clear(); - for (i = 0; i < cforms; i++) - { - // fetch user information - memset(&muser, 0, sizeof(muser)); - unum = getuser(forms[i].userid, &muser); - forms[i].exist = unum ? 1 : 0; - if (unum) forms[i].online = search_ulist(unum) ? 1 : 0; - - // if already got login level, delete by default. - if (!unum) - ans[i] = 'd'; - else { - if (muser.userlevel & PERM_LOGINOK) - ans[i] = 'd'; -#ifdef REGFORM_DISABLE_ONLINE_USER - else if (forms[i].online) - ans[i] = 's'; -#endif // REGFORM_DISABLE_ONLINE_USER - } - - // print - move(i*2, 0); - prints(" %2d%s %s%-12s " ANSI_RESET, - i+1, - (unum == 0) ? ANSI_COLOR(1;31) "D" : - ( (muser.userlevel & PERM_LOGINOK) ? - ANSI_COLOR(1;33) "Y" : -#ifdef REGFORM_DISABLE_ONLINE_USER - forms[i].online ? "s" : -#endif - "."), - forms[i].online ? ANSI_COLOR(1;35) : ANSI_COLOR(1), - 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(" %s %-50s%20s\n", - (muser.userlevel & PERM_NOREGCODE) ? - ANSI_COLOR(1;31) "T" ANSI_RESET : " ", - forms[i].addr, forms[i].phone); - } - - // display page info - { - char msg[STRLEN]; - fpos = ftell(fp); - if (fpos > fsz) fsz = fpos*10; - snprintf(msg, sizeof(msg), - " 已顯示 %d 份註冊單 (%2d%%) ", - parsed, (int)(fpos*100/fsz)); - prints(ANSI_COLOR(7) "\n%78s" ANSI_RESET "\n", msg); - } - - // 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; - - 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'; - if (ci >= cforms) ci = cforms-1; - break; - case '0': - ci = 10-1; - if (ci >= cforms) ci = cforms-1; - break; - - /* - case KEY_HOME: ci = 0; break; - case KEY_END: ci = cforms-1; break; - */ - - // abort - case KEY_END: - case 'q': - ch = 'q'; - if (getans("確定要離開了嗎? (本頁變更將不會儲存) [y/N]: ") != 'y') - { - prompt_regform_ui(); - ch = 0; - continue; - } - break; - - // prepare to go next page - case KEY_PGDN: - case ' ': - ch = ' '; - - // solving blank (undecided entries) - for (i = 0, blanks = 0; i < cforms; i++) - if (ans[i] == 0) blanks ++; - - if (!blanks) - break; - - // have more blanks - ch = getans("尚未指定的 %d 個項目要: (S跳過/y通過/n拒絕/e繼續編輯): ", - blanks); - - if (ch == 'e') - { - prompt_regform_ui(); - ch = 0; - continue; - } - if (ch == 'y') { - // do nothing. - } else if (ch == 'n') { - // query reject reason - resolve_reason(rsn, yMsg); - if (*rsn == 0) - ch = 's'; - } else ch = 's'; - - // filling answers - for (i = 0; i < cforms; i++) - { - if (ans[i] != 0) - continue; - ans[i] = ch; - if (ch != 'n') - continue; - strlcpy(rejects[i], rsn, REASON_LEN); - } - - ch = ' '; // go to page mode! - break; - - // function keys - case 'y': // accept -#ifdef REGFORM_DISABLE_ONLINE_USER - if (forms[ci].online) - { - vmsg("暫不開放審核在線上使用者。"); - break; - } -#endif - case 's': // skip - 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; - - case 'u': // undo -#ifdef REGFORM_DISABLE_ONLINE_USER - if (forms[ci].online) - { - vmsg("暫不開放審核在線上使用者。"); - break; - } -#endif - grayout(ci*2, ci*2+1, GRAYOUT_NORM); - move_ansi(ci*2, 4); outc('.'); - ans[ci] = 0; - ch = 'j'; // go next - break; - - case 'n': // reject -#ifdef REGFORM_DISABLE_ONLINE_USER - if (forms[ci].online) - { - vmsg("暫不開放審核在線上使用者。"); - break; - } -#endif - // query for reason - resolve_reason(rejects[ci], yMsg); - prompt_regform_ui(); - - if (!rejects[ci][0]) - break; - - move(yMsg, 0); - prints("退回 %s 註冊單原因:\n %s\n", forms[ci].userid, rejects[ci]); - - // do reject - grayout(ci*2, ci*2+1, GRAYOUT_DARK); - move_ansi(ci*2, 4); outc(ch); - ans[ci] = ch; - ch = 'j'; // go next - - break; - } // switch(ch) - - // change cursor - if (ch == 'j' && ++ci >= cforms) - ci = cforms -1; - } // while(ch != QUIT/SAVE) - - // if exit, we still need to skip all read forms - if (ch == 'q') - { - for (i = 0; i < cforms; i++) - ans[i] = 's'; - } - - // page complete (save). - assert(ch == ' ' || ch == 'q'); - - // save/commit if required. - if (dryrun) - { - // prmopt for debug - clear(); - stand_title("測試模式"); - outs("您正在執行測試模式,所以剛審的註冊單並不會生效。\n" - "下面列出的是剛才您審完的結果:\n\n"); - - 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); - - prints("%2d. %-12s - %c %s\n", i+1, forms[i].userid, ans[i], - ans[i] == 'n' ? rejects[i] : - ans[i] == 'y' ? justify : ""); - } - if (ch != 'q') - pressanykey(); - } - else - { - // real functionality - for (i = 0; i < cforms; i++) - { - if (ans[i] == 'y') - { - // build justify string - 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 - - } // while (ch != 'q') - - // cleaning left regforms - if (!dryrun) - { - pump_regform(regfile, fp); - fclose(fp); - unlink(fname); - } else { - // directly close file should be OK. - fclose(fp); - } - - return 0; -} - -#endif // EXP_ADMIN_REGFORM - -int -m_register(void) -{ - FILE *fn; - int x, y, wid, len; - char ans[4]; - char genbuf[200]; - - if ((fn = fopen(fn_register, "r")) == NULL) { - outs("目前並無新註冊資料"); - return XEASY; - } - stand_title("審核使用者註冊資料"); - y = 2; - x = wid = 0; - - while (fgets(genbuf, STRLEN, fn) && x < 65) { - if (strncmp(genbuf, "uid: ", 5) == 0) { - move(y++, x); - outs(genbuf + 5); - len = strlen(genbuf + 5); - if (len > wid) - wid = len; - if (y >= t_lines - 3) { - y = 2; - x += wid + 2; - } - } - } - fclose(fn); - getdata(b_lines - 1, 0, -#ifdef EXP_ADMIN_REGFORM - "開始審核嗎(Auto自動/Yes手動/No不審/Exp新界面)?[N] ", -#else - "開始審核嗎(Auto自動/Yes手動/No不審)?[N] ", -#endif - ans, sizeof(ans), LCECHO); - if (ans[0] == 'a') - scan_register_form(fn_register, 1, NULL); - else if (ans[0] == 'y') - scan_register_form(fn_register, 0, NULL); - -#ifdef EXP_ADMIN_REGFORM - else if (ans[0] == 'e') - { -#ifdef EXP_ADMIN_REGFORM_DRYRUN - int dryrun = 0; - if (getans("你要進行純測試(T)還是真的執行審核(y)?") == 'y') - { - vmsg("進入實際執行模式,所有審核動作都是真的。"); - dryrun = 0; - } else { - vmsg("測試模式。"); - dryrun = 1; - } - handle_register_form(fn_register, dryrun); -#else - // run directly. - handle_register_form(fn_register, 0); -#endif - } -#endif - - return 0; -} - -int -cat_register(void) -{ - if (system("cat register.new.tmp >> register.new") == 0 && - unlink("register.new.tmp") == 0) - vmsg("OK 嚕~~ 繼續去奮鬥吧!!"); - else - vmsg("沒辦法CAT過去呢 去檢查一下系統吧!!"); - return 0; -} - static void give_id_money(const char *user_id, int money, const char *mail_title) { |