diff options
Diffstat (limited to 'mbbsd/user.c')
-rw-r--r-- | mbbsd/user.c | 980 |
1 files changed, 980 insertions, 0 deletions
diff --git a/mbbsd/user.c b/mbbsd/user.c new file mode 100644 index 00000000..41aacfa9 --- /dev/null +++ b/mbbsd/user.c @@ -0,0 +1,980 @@ +/* $Id: user.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> +#include <ctype.h> +#include <sys/types.h> +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "perm.h" +#include "modes.h" +#include "proto.h" + +extern int numboards; +extern boardheader_t *bcache; +extern char *loginview_file[NUMVIEWFILE][2]; +extern int b_lines; /* Screen bottom line number: t_lines-1 */ +extern time_t login_start_time; +extern char *msg_uid; +extern int usernum; +extern char *msg_sure_ny; +extern userinfo_t *currutmp; +extern int showansi; +extern char reset_color[]; +extern char *fn_proverb; +extern char *fn_plans; +extern char *msg_del_ok; +extern char *fn_register; +extern char *msg_nobody; +extern userec_t cuser; +extern userec_t xuser; + +static char *sex[8] = { + MSG_BIG_BOY, MSG_BIG_GIRL, MSG_LITTLE_BOY, MSG_LITTLE_GIRL, + MSG_MAN, MSG_WOMAN, MSG_PLANT, MSG_MIME +}; + +int u_loginview() { + int i; + unsigned int pbits = cuser.loginview; + char choice[5]; + + clear(); + move(4,0); + for(i = 0; i < NUMVIEWFILE ; i++) + prints(" %c. %-20s %-15s \n", 'A' + i, + loginview_file[i][1],((pbits >> i) & 1 ? "ˇ" : "X")); + + clrtobot(); + while(getdata(b_lines - 1, 0, "請按 [A-N] 切換設定,按 [Return] 結束:", + choice, 3, LCECHO)) { + i = choice[0] - 'a'; + if(i >= NUMVIEWFILE || i < 0) + bell(); + else { + pbits ^= (1 << i); + move( i + 4 , 28 ); + prints((pbits >> i) & 1 ? "ˇ" : "X"); + } + } + + if(pbits != cuser.loginview) { + cuser.loginview = pbits ; + passwd_update(usernum, &cuser); + } + return 0; +} + +void user_display(userec_t *u, int real) { + int diff = 0; + char genbuf[200]; + + clrtobot(); + prints( + " \033[30;41m┴┬┴┬┴┬\033[m \033[1;30;45m 使 用 者" + " 資 料 " + " \033[m \033[30;41m┴┬┴┬┴┬\033[m\n"); + prints(" 代號暱稱: %s(%s)\n" + " 真實姓名: %s\n" + " 居住住址: %s\n" + " 電子信箱: %s\n" + " 性 別: %s\n" + " 銀行帳戶: %ld 銀兩\n", + u->userid, u->username, u->realname, u->address, u->email, + sex[u->sex % 8], u->money); + + sethomedir(genbuf, u->userid); + prints(" 私人信箱: %d 封 (購買信箱: %d 封)\n" + " 身分證號: %s\n" + " 手機號碼: %010d\n" + " 生 日: %02i/%02i/%02i\n" + " 小雞名字: %s\n", + get_num_records(genbuf, sizeof(fileheader_t)), + u->exmailbox, u->ident, u->mobile, + u->month, u->day, u->year % 100, u->mychicken.name); + prints(" 註冊日期: %s", ctime(&u->firstlogin)); + prints(" 前次光臨: %s", ctime(&u->lastlogin)); + prints(" 前次點歌: %s", ctime(&u->lastsong)); + prints(" 上站文章: %d 次 / %d 篇\n", + u->numlogins, u->numposts); + + if(real) { + strcpy(genbuf, "bTCPRp#@XWBA#VSM0123456789ABCDEF"); + for(diff = 0; diff < 32; diff++) + if(!(u->userlevel & (1 << diff))) + genbuf[diff] = '-'; + prints(" 認證資料: %s\n" + " user權限: %s\n", + u->justify, genbuf); + } else { + diff = (time(0) - login_start_time) / 60; + prints(" 停留期間: %d 小時 %2d 分\n", + diff / 60, diff % 60); + } + + /* Thor: 想看看這個 user 是那些版的版主 */ + if(u->userlevel >= PERM_BM) { + int i; + boardheader_t *bhdr; + + outs(" 擔任板主: "); + + for(i = 0, bhdr = bcache; i < numboards; i++, bhdr++) { + if(is_uBM(bhdr->BM,u->userid)) { + outs(bhdr->brdname); + outc(' '); + } + } + outc('\n'); + } + outs(" \033[30;41m┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴" + "┬┴┬┴┬┴┬\033[m"); + + outs((u->userlevel & PERM_LOGINOK) ? + "\n您的註冊程序已經完成,歡迎加入本站" : + "\n如果要提昇權限,請參考本站公佈欄辦理註冊"); + +#ifdef NEWUSER_LIMIT + if((u->lastlogin - u->firstlogin < 3 * 86400) && !HAS_PERM(PERM_POST)) + outs("\n新手上路,三天後開放權限"); +#endif +} + +void mail_violatelaw(char* crime, char* police, char* reason, char* result){ + char genbuf[200]; + fileheader_t fhdr; + time_t now; + FILE *fp; + sprintf(genbuf, "home/%c/%s", crime[0], crime); + stampfile(genbuf, &fhdr); + if(!(fp = fopen(genbuf,"w"))) + return; + now = time(NULL); + fprintf(fp, "作者: [Ptt法院]\n" + "標題: [報告] 違法判決報告\n" + "時間: %s\n" + "\033[1;32m%s\033[m判決:\n \033[1;32m%s\033[m" + "因\033[1;35m%s\033[m行為,\n違反本站站規,處以\033[1;35m%s\033[m,特此通知" + "\n請到 PttLaw 查詢相關法規資訊,並到 Play-Pay-ViolateLaw 繳交罰單", + ctime(&now), police, crime, reason, result); + fclose(fp); + sprintf(fhdr.title, "[報告] 違法判決報告"); + strcpy(fhdr.owner, "[Ptt法院]"); + sprintf(genbuf, "home/%c/%s/.DIR", crime[0], crime); + append_record(genbuf, &fhdr, sizeof(fhdr)); +} + +static void violate_law(userec_t *u, int unum){ + char ans[4], ans2[4]; + char reason[128]; + move(1,0); + clrtobot(); + move(2,0); + prints("(1)Cross-post (2)亂發廣告信 (3)亂發連鎖信\n"); + prints("(4)騷擾站上使用者 (8)其他以罰單處置行為\n(9)砍 id 行為\n"); + getdata(5, 0, "(0)結束", + ans, 3, DOECHO); + switch(ans[0]){ + case '1': + sprintf(reason, "%s", "Cross-post"); + break; + case '2': + sprintf(reason, "%s", "亂發廣告信"); + break; + case '3': + sprintf(reason, "%s", "亂發連鎖信"); + break; + case '4': + while(!getdata(7, 0, "請輸入被檢舉理由以示負責:", reason, 50, DOECHO)); + strcat(reason, "[騷擾站上使用者]"); + break; + case '8': + case '9': + while(!getdata(6, 0, "請輸入理由以示負責:", reason, 50, DOECHO)); + break; + default: + return; + } + getdata(7, 0, msg_sure_ny, ans2, 3, LCECHO); + if(*ans2 != 'y') + return; + if (ans[0]=='9'){ + char src[STRLEN], dst[STRLEN]; + sprintf(src, "home/%c/%s", u->userid[0], u->userid); + sprintf(dst, "tmp/%s", u->userid); + Rename(src, dst); + log_usies("KILL", u->userid); + post_violatelaw(u->userid, cuser.userid, reason, "砍除 ID"); + u->userid[0] = '\0'; + setuserid(unum, u->userid); + passwd_update(unum, u); + } + else{ + u->userlevel |= PERM_VIOLATELAW; + u->vl_count ++; + passwd_update(unum, u); + post_violatelaw(u->userid, cuser.userid, reason, "罰單處份"); + mail_violatelaw(u->userid, cuser.userid, reason, "罰單處份"); + } + pressanykey(); +} + +extern char* str_permid[]; + +void uinfo_query(userec_t *u, int real, int unum) { + userec_t x; + register int i = 0, fail, mail_changed; + char ans[4], buf[STRLEN], *p; + char genbuf[200], reason[50]; + unsigned long int money = 0; + fileheader_t fhdr; + int flag = 0, temp = 0, money_change = 0; + time_t now; + + FILE *fp; + + fail = mail_changed = 0; + + memcpy(&x, u, sizeof(userec_t)); + getdata(b_lines - 1, 0, real ? + "(1)改資料(2)設密碼(3)設權限(4)砍帳號(5)改ID" + "(6)殺/復活寵物(7)審判 [0]結束 " : + "請選擇 (1)修改資料 (2)設定密碼 ==> [0]結束 ", + ans, 3, DOECHO); + + if(ans[0] > '2' && !real) + ans[0] = '0'; + + if(ans[0] == '1' || ans[0] == '3') { + clear(); + i = 2; + move(i++, 0); + outs(msg_uid); + outs(x.userid); + } + + switch(ans[0]) { + case '7': + violate_law(&x, unum); + return; + case '1': + move(0, 0); + outs("請逐項修改。"); + + getdata_buf(i++, 0," 暱 稱 :",x.username, 24, DOECHO); + if(real) { + getdata_buf(i++, 0, "真實姓名:", x.realname, 20, DOECHO); + getdata_buf(i++, 0, "身分證號:", x.ident, 11, DOECHO); + getdata_buf(i++, 0, "居住地址:", x.address, 50, DOECHO); + } + sprintf(buf, "%010d", x.mobile); + getdata_buf(i++, 0, "手機號碼:", buf, 11, LCECHO); + x.mobile=atoi(buf); + getdata_str(i++, 0, "電子信箱[變動要重新認證]:", buf, 50, DOECHO, + x.email); + if(strcmp(buf,x.email) && strchr(buf, '@')) { + strcpy(x.email,buf); + mail_changed = 1 - real; + } + + sprintf(genbuf, "%i", (u->sex + 1) % 8); + getdata_str(i++, 0, "性別 (1)葛格 (2)姐接 (3)底迪 (4)美眉 (5)薯叔 " + "(6)阿姨 (7)植物 (8)礦物:", + buf, 3, DOECHO,genbuf); + if(buf[0] >= '1' && buf[0] <= '8') + x.sex = (buf[0] - '1') % 8; + else + x.sex = u->sex % 8; + + while(1) { + int len; + + sprintf(genbuf, "%02i/%02i/%02i", + u->month, u->day, u->year % 100); + len = getdata_str(i, 0, "生日 月月/日日/西元:", buf, 9, + DOECHO,genbuf); + if(len && len != 8) + continue; + if(!len) { + x.month = u->month; + x.day = u->day; + x.year = u->year; + } else if(len == 8) { + x.month = (buf[0] - '0') * 10 + (buf[1] - '0'); + x.day = (buf[3] - '0') * 10 + (buf[4] - '0'); + x.year = (buf[6] - '0') * 10 + (buf[7] - '0'); + } else + continue; + if(!real && (x.month > 12 || x.month < 1 || x.day > 31 || + x.day < 1 || x.year > 90 || x.year < 40)) + continue; + i++; + break; + } + if(real) { + unsigned long int l; + if(HAS_PERM(PERM_BBSADM)) { + sprintf(genbuf, "%d", x.money); + if(getdata_str(i++, 0,"銀行帳戶:", buf, 10, DOECHO,genbuf)) + if((l = atol(buf)) >= 0) { + if(l != x.money) { + money_change = 1; + money = x.money; + x.money = l; + } + } + } + sprintf(genbuf, "%d", x.exmailbox); + if(getdata_str(i++, 0,"購買信箱數:", buf, 4, DOECHO,genbuf)) + if((l = atol(buf)) >= 0) + x.exmailbox = (int)l; + + getdata_buf(i++, 0, "認證資料:", x.justify, 44, DOECHO); + getdata_buf(i++, 0, "最近光臨機器:", x.lasthost, 16, DOECHO); + + sprintf(genbuf, "%d", x.numlogins); + if(getdata_str(i++, 0,"上線次數:", buf, 10, DOECHO,genbuf)) + if((fail = atoi(buf)) >= 0) + x.numlogins = fail; + + sprintf(genbuf,"%d", u->numposts); + if(getdata_str(i++, 0, "文章數目:", buf, 10, DOECHO,genbuf)) + if((fail = atoi(buf)) >= 0) + x.numposts = fail; + sprintf(genbuf, "%d", u->vl_count); + if (getdata_str(i++, 0, "違法記錄:", buf, 10, DOECHO, genbuf)) + if ((fail = atoi(buf)) >= 0) + x.vl_count = fail; + + sprintf(genbuf, "%d/%d/%d", u->five_win, u->five_lose, + u->five_tie); + if(getdata_str(i++, 0, "五子棋戰績 勝/敗/和:", buf, 16, DOECHO, + genbuf)) + while(1) { + p = strtok(buf, "/\r\n"); + if(!p) break; + x.five_win = atoi(p); + p = strtok(NULL, "/\r\n"); + if(!p) break; + x.five_lose = atoi(p); + p = strtok(NULL, "/\r\n"); + if(!p) break; + x.five_tie = atoi(p); + break; + } + sprintf(genbuf, "%d/%d/%d", u->chc_win, u->chc_lose, u->chc_tie); + if(getdata_str(i++, 0, "象棋戰績 勝/敗/和:", buf, 16, DOECHO, + genbuf)) + while(1) { + p = strtok(buf, "/\r\n"); + if(!p) break; + x.chc_win = atoi(p); + p = strtok(NULL, "/\r\n"); + if(!p) break; + x.chc_lose = atoi(p); + p = strtok(NULL, "/\r\n"); + if(!p) break; + x.chc_tie = atoi(p); + break; + } + fail = 0; + } + break; + + case '2': + i = 19; + if(!real) { + if(!getdata(i++, 0, "請輸入原密碼:", buf, PASSLEN, NOECHO) || + !checkpasswd(u->passwd, buf)) { + outs("\n\n您輸入的密碼不正確\n"); + fail++; + break; + } + } + else{ + char witness[3][32]; + time_t now = time(NULL); + for(i=0;i<3;i++){ + if(!getdata(19+i, 0, "請輸入協助證明之使用者:", witness[i], 32, DOECHO)){ + outs("\n不輸入則無法更改\n"); + fail++; + break; + } + else if (!getuser(witness[i])){ + outs("\n查無此使用者\n"); + fail++; + break; + } + else if (now - xuser.firstlogin < 6*30*24*60*60){ + outs("\n註冊未超過半年,請重新輸入\n"); + i--; + } + } + if (i < 3) + break; + else + i = 20; + } + + if(!getdata(i++, 0, "請設定新密碼:", buf, PASSLEN, NOECHO)) { + outs("\n\n密碼設定取消, 繼續使用舊密碼\n"); + fail++; + break; + } + strncpy(genbuf, buf, PASSLEN); + + getdata(i++, 0, "請檢查新密碼:", buf, PASSLEN, NOECHO); + if(strncmp(buf, genbuf, PASSLEN)) { + outs("\n\n新密碼確認失敗, 無法設定新密碼\n"); + fail++; + break; + } + buf[8] = '\0'; + strncpy(x.passwd, genpasswd(buf), PASSLEN); + if (real) + x.userlevel &= (!PERM_LOGINOK); + break; + + case '3': + i = setperms(x.userlevel, str_permid); + if(i == x.userlevel) + fail++; + else { + flag=1; + temp=x.userlevel; + x.userlevel = i; + } + break; + + case '4': + i = QUIT; + break; + + case '5': + if (getdata_str(b_lines - 3, 0, "新的使用者代號:", genbuf, IDLEN + 1, + DOECHO,x.userid)) { + if(searchuser(genbuf)) { + outs("錯誤! 已經有同樣 ID 的使用者"); + fail++; + } else + strcpy(x.userid, genbuf); + } + break; + case '6': + if(x.mychicken.name[0]) + x.mychicken.name[0] = 0; + else + strcpy(x.mychicken.name,"[死]"); + break; + default: + return; + } + + if(fail) { + pressanykey(); + return; + } + + getdata(b_lines - 1, 0, msg_sure_ny, ans, 3, LCECHO); + if(*ans == 'y') { + if(flag) + post_change_perm(temp,i,cuser.userid,x.userid); + if(strcmp(u->userid, x.userid)) { + char src[STRLEN], dst[STRLEN]; + + sethomepath(src, u->userid); + sethomepath(dst, x.userid); + Rename(src, dst); + setuserid(unum, x.userid); + } + memcpy(u, &x, sizeof(x)); + if(mail_changed) { +#ifdef EMAIL_JUSTIFY + x.userlevel &= ~PERM_LOGINOK; + mail_justify(); +#endif + } + + if(i == QUIT) { + char src[STRLEN], dst[STRLEN]; + + sprintf(src, "home/%c/%s", x.userid[0], x.userid); + sprintf(dst, "tmp/%s", x.userid); + if(Rename(src, dst)) { + sprintf(genbuf, "/bin/rm -fr %s >/dev/null 2>&1", src); +/* do not remove + system(genbuf); +*/ + } + log_usies("KILL", x.userid); + x.userid[0] = '\0'; + setuserid(unum, x.userid); + } else + log_usies("SetUser", x.userid); + if(money_change) + setumoney(unum,x.money); + passwd_update(unum, &x); + now = time(0); + if(money_change) { + strcpy(genbuf, "boards/Security"); + stampfile(genbuf, &fhdr); + if(!(fp = fopen(genbuf,"w"))) + return; + + now = time(NULL); + fprintf(fp, "作者: [系統安全局] 看板: Security\n" + "標題: [公安報告] 站長修改金錢報告\n" + "時間: %s\n" + " 站長\033[1;32m%s\033[m把\033[1;32m%s\033[m" + "的錢從\033[1;35m%ld\033[m改成\033[1;35m%d\033[m", + ctime(&now), cuser.userid, x.userid, money, x.money); + + clrtobot (); + clear(); + while(!getdata(5, 0, "請輸入理由以示負責:", reason, 60, DOECHO)); + + fprintf(fp, "\n \033[1;37m站長%s修改錢理由是:%s\033[m", + cuser.userid, reason); + fclose(fp); + sprintf(fhdr.title, "[公安報告] 站長%s修改%s錢報告", cuser.userid, + x.userid); + strcpy(fhdr.owner, "[系統安全局]"); + append_record("boards/Security/.DIR", &fhdr, sizeof(fhdr)); + } + } +} + +int u_info() { + move(2, 0); + user_display(&cuser, 0); + uinfo_query(&cuser, 0, usernum); + strcpy(currutmp->realname, cuser.realname); + strcpy(currutmp->username, cuser.username); + return 0; +} + +int u_ansi() { + showansi ^= 1; + cuser.uflag ^= COLOR_FLAG; + outs(reset_color); + return 0; +} + +int u_cloak() { + outs((currutmp->invisible ^= 1) ? MSG_CLOAKED : MSG_UNCLOAK); + return XEASY; +} + +int u_switchproverb() { +/* char *state[4]={"用功\型","安逸型","自定型","SHUTUP"}; */ + char buf[100]; + + cuser.proverb =(cuser.proverb +1) %4; + setuserfile(buf,fn_proverb); + if(cuser.proverb==2 && dashd(buf)) { + FILE *fp = fopen(buf,"a"); + + fprintf(fp,"座右銘狀態為[自定型]要記得設座右銘的內容唷!!"); + fclose(fp); + } + passwd_update(usernum, &cuser); + return 0; +} + +int u_editproverb() { + char buf[100]; + + setutmpmode(PROVERB); + setuserfile(buf,fn_proverb); + move(1,0); + clrtobot(); + outs("\n\n 請一行一行依序鍵入想系統提醒你的內容,\n" + " 儲存後記得把狀態設為 [自定型] 才有作用\n" + " 座右銘最多100條"); + pressanykey(); + vedit(buf,NA, NULL); + return 0; +} + +void showplans(char *uid) { + char genbuf[200]; + + sethomefile(genbuf, uid, fn_plans); + if(!show_file(genbuf, 7, MAX_QUERYLINES, ONLY_COLOR)) + prints("《個人名片》%s 目前沒有名片", uid); +} + +int showsignature(char *fname) { + FILE *fp; + char buf[256]; + int i, j; + char ch; + + clear(); + move(2, 0); + setuserfile(fname, "sig.0"); + j = strlen(fname) - 1; + + for(ch = '1'; ch <= '9'; ch++) { + fname[j] = ch; + if((fp = fopen(fname, "r"))) { + prints("\033[36m【 簽名檔.%c 】\033[m\n", ch); + for(i = 0; i++ < MAX_SIGLINES && fgets(buf, 256, fp); outs(buf)); + fclose(fp); + } + } + return j; +} + +int u_editsig() { + int aborted; + char ans[4]; + int j; + char genbuf[200]; + + j = showsignature(genbuf); + + getdata(0, 0, "簽名檔 (E)編輯 (D)刪除 (Q)取消?[Q] ", ans, 4, LCECHO); + + aborted = 0; + if(ans[0] == 'd') + aborted = 1; + if(ans[0] == 'e') + aborted = 2; + + if(aborted) { + if(!getdata(1, 0, "請選擇簽名檔(1-9)?[1] ", ans, 4, DOECHO)) + ans[0] = '1'; + if(ans[0] >= '1' && ans[0] <= '9') { + genbuf[j] = ans[0]; + if(aborted == 1) { + unlink(genbuf); + outs(msg_del_ok); + } else { + setutmpmode(EDITSIG); + aborted = vedit(genbuf, NA, NULL); + if(aborted != -1) + outs("簽名檔更新完畢"); + } + } + pressanykey(); + } + return 0; +} + +int u_editplan() { + char genbuf[200]; + + getdata(b_lines - 1, 0, "名片 (D)刪除 (E)編輯 [Q]取消?[Q] ", + genbuf, 3, LCECHO); + + if(genbuf[0] == 'e') { + int aborted; + + setutmpmode(EDITPLAN); + setuserfile(genbuf, fn_plans); + aborted = vedit(genbuf, NA, NULL); + if(aborted != -1) + outs("名片更新完畢"); + pressanykey(); + return 0; + } else if(genbuf[0] == 'd') { + setuserfile(genbuf, fn_plans); + unlink(genbuf); + outmsg("名片刪除完畢"); + } + return 0; +} + +int u_editcalendar() { + char genbuf[200]; + + getdata(b_lines - 1, 0, "行事曆 (D)刪除 (E)編輯 [Q]取消?[Q] ", + genbuf, 3, LCECHO); + + if(genbuf[0] == 'e') { + int aborted; + + setutmpmode(EDITPLAN); + setcalfile(genbuf, cuser.userid); + aborted = vedit(genbuf, NA, NULL); + if(aborted != -1) + outs("行事曆更新完畢"); + pressanykey(); + return 0; + } else if(genbuf[0] == 'd') { + setcalfile(genbuf, cuser.userid); + unlink(genbuf); + outmsg("行事曆刪除完畢"); + } + return 0; +} + +/* 使用者填寫註冊表格 */ +static void getfield(int line, char *info, char *desc, char *buf, int len) { + char prompt[STRLEN]; + char genbuf[200]; + + sprintf(genbuf, "原先設定:%-30.30s (%s)", buf, info); + move(line, 2); + outs(genbuf); + sprintf(prompt, "%s:", desc); + if(getdata_str(line + 1, 2, prompt, genbuf, len, DOECHO, buf)) + strcpy(buf, genbuf); + move(line, 2); + prints("%s:%s", desc, buf); + clrtoeol(); +} + +static int removespace(char* s){ + int i, index; + + for(i=0, index=0;s[i];i++){ + if (s[i] != ' ') + s[index++] = s[i]; + } + s[index] = '\0'; + return index; +} + +int u_register() { + char rname[20], addr[50], ident[11], mobile[20]; + char phone[20], career[40], email[50],birthday[9],sex_is[2],year,mon,day; + char ans[3], *ptr; + FILE *fn; + time_t now; + char genbuf[200]; + + if(cuser.userlevel & PERM_LOGINOK) { + outs("您的身份確認已經完成,不需填寫申請表"); + return XEASY; + } + if((fn = fopen(fn_register, "r"))) { + while(fgets(genbuf, STRLEN, fn)) { + if((ptr = strchr(genbuf, '\n'))) + *ptr = '\0'; + if(strncmp(genbuf, "uid: ", 5) == 0 && + strcmp(genbuf + 5, cuser.userid) == 0) { + fclose(fn); + outs("您的註冊申請單尚在處理中,請耐心等候"); + return XEASY; + } + } + fclose(fn); + } + + getdata(b_lines - 1, 0, "您確定要填寫註冊單嗎(Y/N)?[N] ", ans, 3, LCECHO); + if(ans[0] != 'y') + return FULLUPDATE; + + move(2, 0); + clrtobot(); + strcpy(ident, cuser.ident); + strcpy(rname, cuser.realname); + strcpy(addr, cuser.address); + strcpy(email, cuser.email); + sprintf(mobile,"0%09d",cuser.mobile); + sprintf(birthday, "%02i/%02i/%02i", + cuser.month, cuser.day, cuser.year % 100); + sex_is[0]=(cuser.sex % 8)+'1';sex_is[1]=0; + career[0] = phone[0] = '\0'; + while(1) { + clear(); + move(1, 0); + prints("%s(%s) 您好,請據實填寫以下的資料:", + cuser.userid, cuser.username); + do{ + getfield(3, "D120908396", "身分證號", ident, 11); + }while(removespace(ident)<10 || !isalpha(ident[0])); + do{ + getfield(5, "請用中文", "真實姓名", rname, 20); + }while(!removespace(rname) || isalpha(rname[0])); + do{ + getfield(7, "學校系級或單位職稱", "服務單位", career, 40); + }while(!removespace(career)); + do{ + getfield(9, "包括寢室或門牌號碼", "目前住址", addr, 50); + }while(!(addr[0])); + do{ + getfield(11, "包括長途撥號區域碼", "連絡電話", phone, 20); + }while(!removespace(phone)); + getfield(13, "只輸入數字 如:0912345678", "手機號碼", mobile, 20); + while(1) { + int len; + + getfield(15,"月月/日日/西元 如:09/27/76","生日",birthday,9); + len = strlen(birthday); + if(!len) { + sprintf(birthday, "%02i/%02i/%02i", + cuser.month, cuser.day, cuser.year % 100); + mon = cuser.month; + day = cuser.day; + year = cuser.year; + } else if(len == 8) { + mon = (birthday[0] - '0') * 10 + (birthday[1] - '0'); + day = (birthday[3] - '0') * 10 + (birthday[4] - '0'); + year = (birthday[6] - '0') * 10 + (birthday[7] - '0'); + } else + continue; + if(mon > 12 || mon < 1 || day > 31 || day < 1 || year > 90 || + year < 40) + continue; + break; + } + getfield(17, "1.葛格 2.姐接 ", "性別", sex_is, 2); + getfield(19, "身分認證用", "E-Mail Address", email, 50); + + getdata(b_lines - 1, 0, "以上資料是否正確(Y/N)?(Q)取消註冊 [N] ", + ans, 3, LCECHO); + if(ans[0] == 'q') + return 0; + if(ans[0] == 'y') + break; + } + strcpy(cuser.ident, ident); + strcpy(cuser.realname, rname); + strcpy(cuser.address, addr); + strcpy(cuser.email, email); + cuser.mobile = atoi(mobile); + cuser.sex= (sex_is[0] - '1') % 8; + cuser.month = mon; + cuser.day = day; + cuser.year = year; + if((fn = fopen(fn_register, "a"))) { + now = time(NULL); + trim(career); + trim(addr); + trim(phone); + fprintf(fn, "num: %d, %s", usernum, ctime(&now)); + fprintf(fn, "uid: %s\n", cuser.userid); + fprintf(fn, "ident: %s\n", ident); + fprintf(fn, "name: %s\n", rname); + fprintf(fn, "career: %s\n", career); + fprintf(fn, "addr: %s\n", addr); + fprintf(fn, "phone: %s\n", phone); + fprintf(fn, "mobile: %s\n", mobile); + fprintf(fn, "email: %s\n", email); + fprintf(fn, "----\n"); + fclose(fn); + } + clear(); + move(9,3); + prints("最後Post一篇\033[32m自我介紹文章\033[m給大家吧," + "告訴所有老骨頭\033[31m我來啦^$。\\n\n\n\n"); + pressanykey(); + cuser.userlevel |= PERM_POST; + brc_initial("WhoAmI"); + set_board(); + do_post(); + cuser.userlevel &= ~PERM_POST; + return 0; +} + +/* 列出所有註冊使用者 */ +extern struct uhash_t *uhash; +static int usercounter, totalusers, showrealname; +static ushort u_list_special; + +static int u_list_CB(userec_t *uentp) { + static int i; + char permstr[8], *ptr; + register int level; + + if(uentp == NULL) { + move(2, 0); + clrtoeol(); + prints("\033[7m 使用者代號 %-25s 上站 文章 %s " + "最近光臨日期 \033[0m\n", + showrealname ? "真實姓名" : "綽號暱稱", + HAS_PERM(PERM_SEEULEVELS) ? "等級" : ""); + i = 3; + return 0; + } + + if(bad_user_id(uentp->userid)) + return 0; + + if((uentp->userlevel & ~(u_list_special)) == 0) + return 0; + + if(i == b_lines) { + prints("\033[34;46m 已顯示 %d/%d 人(%d%%) \033[31;47m " + "(Space)\033[30m 看下一頁 \033[31m(Q)\033[30m 離開 \033[m", + usercounter, totalusers, usercounter * 100 / totalusers); + i = igetch(); + if(i == 'q' || i == 'Q') + return QUIT; + i = 3; + } + if(i == 3) { + move(3, 0); + clrtobot(); + } + + level = uentp->userlevel; + strcpy(permstr, "----"); + if(level & PERM_SYSOP) + permstr[0] = 'S'; + else if(level & PERM_ACCOUNTS) + permstr[0] = 'A'; + else if(level & PERM_DENYPOST) + permstr[0] = 'p'; + + if(level & (PERM_BOARD)) + permstr[1] = 'B'; + else if(level & (PERM_BM)) + permstr[1] = 'b'; + + if(level & (PERM_XEMPT)) + permstr[2] = 'X'; + else if(level & (PERM_LOGINOK)) + permstr[2] = 'R'; + + if(level & (PERM_CLOAK | PERM_SEECLOAK)) + permstr[3] = 'C'; + + ptr = (char *)Cdate(&uentp->lastlogin); + ptr[18] = '\0'; + prints("%-14s %-27.27s%5d %5d %s %s\n", + uentp->userid, + showrealname ? uentp->realname : uentp->username, + uentp->numlogins, uentp->numposts, + HAS_PERM(PERM_SEEULEVELS) ? permstr : "", ptr); + usercounter++; + i++; + return 0; +} + +int u_list() { + char genbuf[3]; + + setutmpmode(LAUSERS); + showrealname = u_list_special = usercounter = 0; + totalusers = uhash->number; + if(HAS_PERM(PERM_SEEULEVELS)) { + getdata(b_lines - 1, 0, "觀看 [1]特殊等級 (2)全部?", + genbuf, 3, DOECHO); + if(genbuf[0] != '2') + u_list_special = PERM_BASIC | PERM_CHAT | PERM_PAGE | PERM_POST | PERM_LOGINOK | PERM_BM; + } + if(HAS_PERM(PERM_CHATROOM) || HAS_PERM(PERM_SYSOP)) { + getdata(b_lines - 1, 0, "顯示 [1]真實姓名 (2)暱稱?", + genbuf, 3, DOECHO); + if(genbuf[0] != '2') + showrealname = 1; + } + u_list_CB(NULL); + if(passwd_apply(u_list_CB) == -1) { + outs(msg_nobody); + return XEASY; + } + move(b_lines, 0); + clrtoeol(); + prints("\033[34;46m 已顯示 %d/%d 的使用者(系統容量無上限) " + "\033[31;47m (請按任意鍵繼續) \033[m", usercounter, totalusers); + egetch(); + return 0; +} |