summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/proto.h9
-rw-r--r--mbbsd/admin.c7
-rw-r--r--mbbsd/mbbsd.c2
-rw-r--r--mbbsd/passwd.c68
-rw-r--r--mbbsd/read.c2
-rw-r--r--mbbsd/talk.c2
-rw-r--r--mbbsd/user.c168
7 files changed, 172 insertions, 86 deletions
diff --git a/include/proto.h b/include/proto.h
index 1276c1f1..b01e8712 100644
--- a/include/proto.h
+++ b/include/proto.h
@@ -612,7 +612,7 @@ int kill_user(int num, const char *userid);
int u_editcalendar(void);
void user_display(const userec_t *u, int real);
int isvalidemail(char *email);
-void uinfo_query(userec_t *u, int real, int unum);
+void uinfo_query(const char *uid, int real, int unum);
int showsignature(char *fname, int *j, SigInfo *psi);
int u_cancelbadpost();
void kick_all(const char *user);
@@ -700,6 +700,7 @@ int pwcuDecNumPost ();
int pwcuSetGoodPost (unsigned int newgp);
int pwcuViolateLaw ();
int pwcuSaveViolateLaw ();
+int pwcuCancelBadpost ();
int pwcuAddExMailBox (int m);
int pwcuToggleOutMail ();
int pwcuSetLoginView (unsigned int bits);
@@ -708,16 +709,20 @@ int pwcuSetMyAngel (const char *angel_uid);
int pwcuSetNickname (const char *nickname);
int pwcuChessResult (int sigType, ChessGameResult);
int pwcuSetChessEloRating(uint16_t elo_rating);
+int pwcuSaveUserFlags ();
// non-important based variables (only save on exit)
int pwcuSetSignature (unsigned char newsig);
int pwcuSetWaterballMode(unsigned int bm);
int pwcuToggleSortBoard ();
int pwcuToggleFriendList();
+int pwcuToggleUserFlag (unsigned int mask); // not saved until pwcuSaveUserFlags
+int pwcuToggleUserFlag2 (unsigned int mask); // not saved until pwcuSaveUserFlags
-// session save
+// session management
int pwcuLoginSave ();
int pwcuExitSave ();
+int pwcuReload ();
// initialization
void pwcuInitZero ();
diff --git a/mbbsd/admin.c b/mbbsd/admin.c
index 48ebba94..0ed06412 100644
--- a/mbbsd/admin.c
+++ b/mbbsd/admin.c
@@ -43,7 +43,7 @@ m_user(void)
if ((id = getuser(genbuf, &xuser))) {
user_display(&xuser, 1);
if( HasUserPerm(PERM_ACCOUNTS) )
- uinfo_query(&xuser, 1, id);
+ uinfo_query(xuser.userid, 1, id);
else
pressanykey();
} else {
@@ -217,10 +217,13 @@ search_key_user(const char *passwdfile, int mode)
// user_display does not have linefeed in tail.
if (isCurrentPwd && HasUserPerm(PERM_ACCOUNTS))
- uinfo_query(&user, 1, unum);
+ uinfo_query(user.userid, 1, unum);
else
outs("\n");
+ // XXX don't trust 'user' variable after here
+ // because uinfo_query may have changed it.
+
outs(ANSI_COLOR(44) " 空白鍵" \
ANSI_COLOR(37) ":搜尋下一個 " \
ANSI_COLOR(33)" Q" ANSI_COLOR(37)": 離開");
diff --git a/mbbsd/mbbsd.c b/mbbsd/mbbsd.c
index e193bf12..c77b508e 100644
--- a/mbbsd/mbbsd.c
+++ b/mbbsd/mbbsd.c
@@ -342,7 +342,7 @@ signal_xcpu_handler(int sig)
last_time_exceeded = login_start_time;
assert(last_time_exceeded);
// 不用 (time(0) - login_start_time) 來平均, 避免用好幾天之後突然狂吃 cpu 的狀況.
- if (time(0) - last_time_exceeded < 86400)
+ if (time(0) - last_time_exceeded < DAY_SECONDS)
give_more_time = false;
last_time_exceeded = time(0);
diff --git a/mbbsd/passwd.c b/mbbsd/passwd.c
index 61e472a8..e8ed21e2 100644
--- a/mbbsd/passwd.c
+++ b/mbbsd/passwd.c
@@ -170,6 +170,25 @@ pwcuSaveViolateLaw()
PWCU_END();
}
+int
+pwcuCancelBadpost()
+{
+ int day;
+ PWCU_START();
+
+ // check timebomb again
+ day = (now - u.timeremovebadpost ) / DAY_SECONDS;
+ if (day <= 180)
+ return -1;
+ if (u.badpost < 1)
+ return -1;
+
+ cuser.badpost = --u.badpost;
+ cuser.timeremovebadpost = u.timeremovebadpost = now;
+
+ PWCU_END();
+}
+
int
pwcuAddExMailBox(int m)
{
@@ -323,6 +342,15 @@ pwcuSetChessEloRating(uint16_t elo_rating)
PWCU_END();
}
+int
+pwcuSaveUserFlags()
+{
+ PWCU_START();
+ u.uflag = cuser.uflag;
+ u.uflag2 = cuser.uflag2;
+ PWCU_END();
+}
+
// non-important variables (only save on exit)
int
@@ -341,18 +369,34 @@ pwcuSetWaterballMode(unsigned int bm)
return 0;
}
-int pwcuToggleSortBoard ()
+int
+pwcuToggleSortBoard ()
{
cuser.uflag ^= BRDSORT_FLAG;
return 0;
}
-int pwcuToggleFriendList()
+int
+pwcuToggleFriendList()
{
cuser.uflag ^= FRIEND_FLAG;
return 0;
}
+int
+pwcuToggleUserFlag (unsigned int mask)
+{
+ cuser.uflag ^= mask;
+ return 0;
+}
+
+int
+pwcuToggleUserFlag2 (unsigned int mask)
+{
+ cuser.uflag2 ^= mask;
+ return 0;
+}
+
// session save
// XXX this is a little different - only invoked at login,
@@ -365,8 +409,8 @@ int pwcuLoginSave ()
strlcpy(cuser.lasthost, fromhost, sizeof(cuser.lasthost));
// calculate numlogins (only increase one per each key)
- if (((login_start_time - cuser.firstlogin) % 86400) !=
- ((cuser.lastlogin - cuser.firstlogin) % 86400) )
+ if (((login_start_time - cuser.firstlogin) % DAY_SECONDS) !=
+ ((cuser.lastlogin - cuser.firstlogin) % DAY_SECONDS) )
cuser.numlogins++;
// update last login time
@@ -380,10 +424,16 @@ int pwcuLoginSave ()
// XXX this is a little different - only invoked at exist,
// so no need to sync back to cuser.
-int pwcuExitSave ()
+int
+pwcuExitSave ()
{
PWCU_START();
+ // uflag and uflag2: always trust cuser except REJ_OUTTAMAIL
+ _SETBY_BIT(cuser.uflag2, REJ_OUTTAMAIL, (u.uflag2 & REJ_OUTTAMAIL));
+ u.uflag = cuser.uflag;
+ u.uflag2= cuser.uflag2;
+
_DISABLE_BIT(u.uflag, (PAGER_FLAG | CLOAK_FLAG));
if (currutmp->pager != PAGER_ON)
_ENABLE_BIT(u.uflag, PAGER_FLAG);
@@ -403,6 +453,14 @@ int pwcuExitSave ()
PWCU_END();
}
+int
+pwcuReload ()
+{
+ int r = passwd_sync_query(usernum, &cuser);
+ // XXX TODO verify cuser structure?
+ return r;
+}
+
// Initialization
void pwcuInitZero ()
diff --git a/mbbsd/read.c b/mbbsd/read.c
index 4dca75c4..6071ac39 100644
--- a/mbbsd/read.c
+++ b/mbbsd/read.c
@@ -985,7 +985,7 @@ i_read_key(const onekey_t * rcmdlist, keeploc_t * locmem,
if ((id = getuser(headers[locmem->crs_ln - locmem->top_ln].owner, &muser))) {
user_display(&muser, 1);
if( HasUserPerm(PERM_ACCOUNTS) )
- uinfo_query(&muser, 1, id);
+ uinfo_query(muser.userid, 1, id);
else
pressanykey();
}
diff --git a/mbbsd/talk.c b/mbbsd/talk.c
index 14f55478..bc728b8d 100644
--- a/mbbsd/talk.c
+++ b/mbbsd/talk.c
@@ -2835,7 +2835,7 @@ userlist(void)
if ((id = getuser(uentp->userid, &muser)) > 0) {
user_display(&muser, 1);
if( HasUserPerm(PERM_ACCOUNTS) )
- uinfo_query(&muser, 1, id);
+ uinfo_query(muser.userid, 1, id);
else
pressanykey();
}
diff --git a/mbbsd/user.c b/mbbsd/user.c
index 84a2d83e..0b356eab 100644
--- a/mbbsd/user.c
+++ b/mbbsd/user.c
@@ -73,43 +73,51 @@ u_loginview(void)
int u_cancelbadpost(void)
{
- int day;
- if(cuser.badpost==0)
- {vmsg("你並沒有劣文."); return 0;}
-
- if(search_ulistn(usernum,2))
- {vmsg("請登出其他視窗, 否則不受理."); return 0;}
+ int day, prev = cuser.badpost;
- passwd_sync_query(usernum, cuser_ref);
- if (currutmp && (currutmp->alerts & ALERT_PWD))
- currutmp->alerts &= ~ALERT_PWD;
+ // early check.
+ if(cuser.badpost==0) {
+ vmsg("你並沒有劣文.");
+ return 0;
+ }
+
+ // early check for race condition
+ if(search_ulistn(usernum,2)) {
+ vmsg("請登出其他視窗, 否則不受理.");
+ return 0;
+ }
+ // early check for time (must do again later)
day = 180 - (now - cuser.timeremovebadpost ) / DAY_SECONDS;
- if(day>0 && day<=180)
- {
- vmsgf("每 180 天才能申請一次, 還剩 %d 天.", day);
- vmsg("您也可以注意站方是否有勞動服務方式刪除劣文.");
- return 0;
- }
-
- if(
- vmsg("我願意尊守站方規定,組規,以及板規[y/N]?")!='y' ||
- vmsg("我願意尊重不歧視族群,不鬧板,尊重各板主權力[y/N]?")!='y' ||
- vmsg("我願意謹慎發表有意義言論,不謾罵攻擊,不跨板廣告[y/N]?")!='y' )
-
- {vmsg("請您思考清楚後再來申請刪除."); return 0;}
-
- if(search_ulistn(usernum,2))
- {vmsg("請登出其他視窗, 否則不受理."); return 0;}
- if(cuser.badpost)
+ if(day>0 && day<=180) {
+ vmsgf("每 180 天才能申請一次, 還剩 %d 天.", day);
+ return 0;
+ }
+
+ // 無聊的 disclaimer...
+ if( vmsg("我願意尊守站方規定,組規,以及板規[y/N]?")!='y' ||
+ vmsg("我願意尊重不歧視族群,不鬧板,尊重各板主權力[y/N]?")!='y' ||
+ vmsg("我願意謹慎發表有意義言論,不謾罵攻擊,不跨板廣告[y/N]?")!='y' )
{
- int prev = cuser.badpost--;
- cuser.timeremovebadpost = now;
- passwd_sync_update(usernum, cuser_ref);
- log_filef("log/cancelbadpost.log", LOG_CREAT,
- "%s %s 刪除一篇劣文 (%d -> %d 篇)\n",
- Cdate(&now), cuser.userid, prev, cuser.badpost);
+ vmsg("請您思考清楚後再來申請刪除.");
+ return 0;
+ }
+
+ // check again for race condition
+ if(search_ulistn(usernum,2)) {
+ vmsg("請登出其他視窗, 否則不受理.");
+ return 0;
+ }
+
+ if (pwcuCancelBadpost() != 0) {
+ vmsg("刪除失敗,請洽站務人員。");
+ return 0;
}
+
+ log_filef("log/cancelbadpost.log", LOG_CREAT,
+ "%s %s 刪除一篇劣文 (%d -> %d 篇)\n",
+ Cdate(&now), cuser.userid, prev, cuser.badpost);
+
vmsg("恭喜您已經成功\刪除一篇劣文.");
return 0;
}
@@ -466,12 +474,12 @@ void Customize(void)
key -= 'a';
dirty = 1;
+
if(key < ic)
{
- cuser.uflag ^= masks1[key];
+ pwcuToggleUserFlag(masks1[key]);
} else {
- key -= ic;
- cuser.uflag2 ^= masks2[key];
+ pwcuToggleUserFlag2(masks2[key]);
}
continue;
}
@@ -526,7 +534,7 @@ void Customize(void)
if(dirty)
{
- passwd_sync_update(usernum, cuser_ref);
+ pwcuSaveUserFlags();
outs("設定已儲存。\n");
} else {
outs("結束設定。\n");
@@ -538,7 +546,7 @@ void Customize(void)
void
-uinfo_query(userec_t *u, int adminmode, int unum)
+uinfo_query(const char *orig_uid, int adminmode, int unum)
{
userec_t x;
int i = 0, fail;
@@ -552,24 +560,35 @@ uinfo_query(userec_t *u, int adminmode, int unum)
int money_changed;
int tokill = 0;
int changefrom = 0;
+ int xuid;
fail = 0;
mail_changed = money_changed = perm_changed = 0;
+ // verify unum
+ xuid = getuser(orig_uid, &x);
+ if (xuid == 0)
{
- // verify unum
- int xuid = getuser(u->userid, &x);
- if (xuid != unum)
- {
- move(b_lines-1, 0); clrtobot();
- prints(ANSI_COLOR(1;31) "錯誤資訊: unum=%d (lookup xuid=%d)"
- ANSI_RESET "\n", unum, xuid);
- vmsg("系統錯誤: 使用者資料號碼 (unum) 不合。請至 " BN_BUGREPORT "報告。");
- return;
- }
+ vmsgf("找不到使用者 %s。", orig_uid);
+ return;
+ }
+ if (xuid != unum)
+ {
+ move(b_lines-1, 0); clrtobot();
+ prints(ANSI_COLOR(1;31) "錯誤資訊: unum=%d (lookup xuid=%d)"
+ ANSI_RESET "\n", unum, xuid);
+ vmsg("系統錯誤: 使用者資料號碼 (unum) 不合。請至 " BN_BUGREPORT "報告。");
+ return;
+ }
+ if (strcmp(orig_uid, x.userid) != 0)
+ {
+ move(b_lines-1, 0); clrtobot();
+ prints(ANSI_COLOR(1;31) "錯誤資訊: userid=%s (lookup userid=%s)"
+ ANSI_RESET "\n", orig_uid, x.userid);
+ vmsg("系統錯誤: 使用者 ID 記錄不不合。請至 " BN_BUGREPORT "報告。");
+ return;
}
- memcpy(&x, u, sizeof(userec_t));
ans = vans(adminmode ?
"(1)改資料(2)密碼(3)權限(4)砍帳號(5)改ID(6)寵物(7)審判(M)信箱 [0]結束 " :
"請選擇 (1)修改資料 (2)設定密碼 (M)修改信箱 (C) 個人化設定 ==> [0]結束 ");
@@ -680,23 +699,19 @@ uinfo_query(userec_t *u, int adminmode, int unum)
snprintf(buf, sizeof(buf), "%010d", x.mobile);
getdata_buf(y++, 0, "手機號碼:", buf, 11, NUMECHO);
x.mobile = atoi(buf);
- snprintf(genbuf, sizeof(genbuf), "%d", (u->sex + 1) % 8);
+ snprintf(genbuf, sizeof(genbuf), "%d", (x.sex + 1) % 8);
getdata_str(y++, 0, "性別 (1)葛格 (2)姐接 (3)底迪 (4)美眉 (5)薯叔 "
"(6)阿姨 (7)植物 (8)礦物:",
buf, 3, NUMECHO, genbuf);
if (buf[0] >= '1' && buf[0] <= '8')
x.sex = (buf[0] - '1') % 8;
else
- x.sex = u->sex % 8;
+ x.sex = x.sex % 8;
while (1) {
snprintf(genbuf, sizeof(genbuf), "%04i/%02i/%02i",
- u->year + 1900, u->month, u->day);
- if (getdata_str(y, 0, "生日 西元/月月/日日:", buf, 11, DOECHO, genbuf) == 0) {
- x.month = u->month;
- x.day = u->day;
- x.year = u->year;
- } else {
+ x.year + 1900, x.month, x.day);
+ if (getdata_str(y, 0, "生日 西元/月月/日日:", buf, 11, DOECHO, genbuf) != 0) {
int y, m, d;
if (ParseDate(buf, &y, &m, &d))
continue;
@@ -743,7 +758,7 @@ uinfo_query(userec_t *u, int adminmode, int unum)
int j, k;
FILE* fp;
for(j = 0; j < 2; ++j){
- sethomefile(genbuf, u->userid, chess_photo_name[j]);
+ sethomefile(genbuf, x.userid, chess_photo_name[j]);
fp = fopen(genbuf, "r");
if(fp != NULL){
FILE* newfp;
@@ -757,7 +772,7 @@ uinfo_query(userec_t *u, int adminmode, int unum)
getdata_buf(y, 0, mybuf, genbuf + 11, 80 - 11, DOECHO);
++y;
- sethomefile(mybuf, u->userid, chess_photo_name[j]);
+ sethomefile(mybuf, x.userid, chess_photo_name[j]);
strcat(mybuf, ".new");
if((newfp = fopen(mybuf, "w")) != NULL){
rewind(fp);
@@ -770,8 +785,8 @@ uinfo_query(userec_t *u, int adminmode, int unum)
fclose(newfp);
- sethomefile(genbuf, u->userid, chess_photo_name[j]);
- sethomefile(mybuf, u->userid, chess_photo_name[j]);
+ sethomefile(genbuf, x.userid, chess_photo_name[j]);
+ sethomefile(mybuf, x.userid, chess_photo_name[j]);
strcat(mybuf, ".new");
Rename(mybuf, genbuf);
@@ -810,24 +825,24 @@ uinfo_query(userec_t *u, int adminmode, int unum)
if (getdata_str(y++, 0, "上線次數:", buf, 10, DOECHO, genbuf))
if ((tmp = atoi(buf)) >= 0)
x.numlogins = tmp;
- snprintf(genbuf, sizeof(genbuf), "%d", u->numposts);
+ snprintf(genbuf, sizeof(genbuf), "%d", x.numposts);
if (getdata_str(y++, 0, "文章數目:", buf, 10, DOECHO, genbuf))
if ((tmp = atoi(buf)) >= 0)
x.numposts = tmp;
#ifdef ASSESS
- snprintf(genbuf, sizeof(genbuf), "%d", u->badpost);
+ snprintf(genbuf, sizeof(genbuf), "%d", x.badpost);
if (getdata_str(y++, 0, "惡劣文章數:", buf, 10, DOECHO, genbuf))
if ((tmp = atoi(buf)) >= 0)
x.badpost = tmp;
#endif // ASSESS
- snprintf(genbuf, sizeof(genbuf), "%d", u->vl_count);
+ snprintf(genbuf, sizeof(genbuf), "%d", x.vl_count);
if (getdata_str(y++, 0, "違法記錄:", buf, 10, DOECHO, genbuf))
if ((tmp = atoi(buf)) >= 0)
x.vl_count = tmp;
snprintf(genbuf, sizeof(genbuf),
- "%d/%d/%d", u->five_win, u->five_lose, u->five_tie);
+ "%d/%d/%d", x.five_win, x.five_lose, x.five_tie);
if (getdata_str(y++, 0, "五子棋戰績 勝/敗/和:", buf, 16, DOECHO,
genbuf))
while (1) {
@@ -848,7 +863,7 @@ uinfo_query(userec_t *u, int adminmode, int unum)
break;
}
snprintf(genbuf, sizeof(genbuf),
- "%d/%d/%d", u->chc_win, u->chc_lose, u->chc_tie);
+ "%d/%d/%d", x.chc_win, x.chc_lose, x.chc_tie);
if (getdata_str(y++, 0, "象棋戰績 勝/敗/和:", buf, 16, DOECHO,
genbuf))
while (1) {
@@ -898,7 +913,7 @@ uinfo_query(userec_t *u, int adminmode, int unum)
y = 19;
if (!adminmode) {
if (!getdata(y++, 0, "請輸入原密碼:", buf, PASSLEN, NOECHO) ||
- !checkpasswd(u->passwd, buf)) {
+ !checkpasswd(x.passwd, buf)) {
outs("\n\n您輸入的密碼不正確\n");
fail++;
break;
@@ -959,7 +974,7 @@ uinfo_query(userec_t *u, int adminmode, int unum)
}
pre_confirmed = 1;
- sprintf(title, "%s 的密碼重設通知 (by %s)",u->userid, cuser.userid);
+ sprintf(title, "%s 的密碼重設通知 (by %s)",x.userid, cuser.userid);
unlink("etc/updatepwd.log");
if(! (fp = fopen("etc/updatepwd.log", "w")))
{
@@ -971,11 +986,11 @@ uinfo_query(userec_t *u, int adminmode, int unum)
fprintf(fp, "%s 要求密碼重設:\n"
"見證人為 %s, %s, %s",
- u->userid, witness[0], witness[1], witness[2] );
+ x.userid, witness[0], witness[1], witness[2] );
fclose(fp);
post_file(BN_SECURITY, title, "etc/updatepwd.log", "[系統安全局]");
- mail_id(u->userid, title, "etc/updatepwd.log", cuser.userid);
+ mail_id(x.userid, title, "etc/updatepwd.log", cuser.userid);
for(i=0; i<3; i++)
{
mail_id(witness[i], title, "etc/updatepwd.log", cuser.userid);
@@ -1029,9 +1044,11 @@ uinfo_query(userec_t *u, int adminmode, int unum)
strlcpy(x.userid, genbuf, sizeof(x.userid));
}
break;
+
case '6':
chicken_toggle_death(x.userid);
break;
+
default:
return;
}
@@ -1058,10 +1075,11 @@ uinfo_query(userec_t *u, int adminmode, int unum)
mail_id(x.userid, "翅膀長出來了!", "etc/angel_notify", "[上帝]");
#endif
}
- if (strcmp(u->userid, x.userid)) {
+
+ if (strcmp(orig_uid, x.userid)) {
char src[STRLEN], dst[STRLEN];
- kick_all(u->userid);
- sethomepath(src, u->userid);
+ kick_all(orig_uid);
+ sethomepath(src, orig_uid);
sethomepath(dst, x.userid);
Rename(src, dst);
setuserid(unum, x.userid);
@@ -1070,7 +1088,7 @@ uinfo_query(userec_t *u, int adminmode, int unum)
// wait registration.
x.userlevel &= ~(PERM_LOGINOK | PERM_POST);
}
- memcpy(u, &x, sizeof(x));
+
if (tokill) {
kick_all(x.userid);
delete_allpost(x.userid);
@@ -1120,7 +1138,9 @@ u_info(void)
move(2, 0);
reload_money();
user_display(cuser_ref, 0);
- uinfo_query (cuser_ref, 0, usernum);
+ uinfo_query (cuser.userid, 0, usernum);
+ // XXX TODO update from u to cuser
+ pwcuReload();
strlcpy(currutmp->nickname, cuser.nickname, sizeof(currutmp->nickname));
return 0;
}