/* $Id$ */ #define PWCU_IMPL #include "bbs.h" #ifdef _BBS_UTIL_C_ #error sorry, mbbsd/passwd.c does not support utility mode anymore. please use libcmbbs instead. #endif #ifdef CONST_CUSER #undef cuser #define cuser pwcuser #endif void passwd_force_update(int flag) { if(!currutmp || (currutmp->alerts & ALERT_PWD) == 0) return; currutmp->alerts &= ~flag; } int initcuser(const char *userid) { usernum = passwd_load_user(userid, &cuser); return usernum; } // XXX I don't like the stupid synchronization here, // but simply following previous work here... int passwd_sync_update(int num, userec_t * buf) { int alerts; if (num < 1 || num > MAX_USERS) return -1; // money update should be done before everything. buf->money = moneyof(num); if(usernum == num && currutmp && ((alerts = currutmp->alerts) & ALERT_PWD)) { userec_t u; if (passwd_sync_query(num, &u) != 0) return -1; if(alerts & ALERT_PWD_BADPOST) cuser.badpost = buf->badpost = u.badpost; if(alerts & ALERT_PWD_PERM) cuser.userlevel = buf->userlevel = u.userlevel; if(alerts & ALERT_PWD_JUSTIFY) { memcpy(buf->justify, u.justify, sizeof(u.justify)); memcpy(cuser.justify, u.justify, sizeof(u.justify)); memcpy(buf->email, u.email, sizeof(u.email)); memcpy(cuser.email, u.email, sizeof(u.email)); } currutmp->alerts &= ~ALERT_PWD; // ALERT_PWD_RELOAD: reload all! No need to write. if (alerts & ALERT_PWD_RELOAD) { memcpy(&cuser, &u, sizeof(u)); return 0; } } if (passwd_update(num, buf) != 0) return -1; return 0; } // XXX I don't like the stupid synchronization here, // but simply following previous work here... int passwd_sync_query(int num, userec_t * buf) { if (passwd_query(num, buf) < 0) return -1; return 0; } // pwcu*: current user password helpers static int pwcuInitCUser(userec_t *u) { assert(usernum > 0 && usernum <= MAX_USERS); if (passwd_query(usernum, u) != 0) return -1; assert(strncmp(u->userid, cuser.userid, IDLEN) == 0); if (strncmp(u->userid, cuser.userid, IDLEN) != 0) return -1; return 0; } static int pwcuFinalCUser(userec_t *u) { assert(usernum > 0 && usernum <= MAX_USERS); assert(strcmp(u->userid, cuser.userid) == 0); if (passwd_update(usernum, u) != 0) return -1; return 0; } #define PWCU_START() userec_t u; if(pwcuInitCUser (&u) != 0) return -1 #define PWCU_END() if (pwcuFinalCUser(&u) != 0) return -1; return 0 #define _ENABLE_BIT( var,mask) var |= (mask) #define _DISABLE_BIT(var,mask) var &= ~(mask) #define _SETBY_BIT(var,mask,val) if (val) { _ENABLE_BIT(var, (mask)); } else { _DISABLE_BIT(var, (mask)); } int pwcuBitEnableLevel (unsigned int mask) { PWCU_START(); _ENABLE_BIT( u.userlevel, mask); _ENABLE_BIT(cuser.userlevel, mask); PWCU_END(); } int pwcuBitDisableLevel (unsigned int mask) { PWCU_START(); _DISABLE_BIT( u.userlevel, mask); _DISABLE_BIT(cuser.userlevel, mask); PWCU_END(); } int pwcuIncNumPost() { PWCU_START(); cuser.numposts = ++u.numposts; PWCU_END(); } int pwcuDecNumPost() { PWCU_START(); if (u.numposts > 0) u.numposts--; cuser.numposts = u.numposts; PWCU_END(); } int pwcuViolateLaw () { PWCU_START(); _ENABLE_BIT( u.userlevel, PERM_VIOLATELAW); _ENABLE_BIT(cuser.userlevel, PERM_VIOLATELAW); u.timeviolatelaw = now; cuser.timeviolatelaw = u.timeviolatelaw; u.vl_count++; cuser.vl_count = u.vl_count; PWCU_END(); } int pwcuSaveViolateLaw() { PWCU_START(); _DISABLE_BIT( u.userlevel, PERM_VIOLATELAW); _DISABLE_BIT(cuser.userlevel, PERM_VIOLATELAW); PWCU_END(); } int pwcuAddExMailBox(int m) { PWCU_START(); u.exmailbox += m; cuser.exmailbox = u.exmailbox; PWCU_END(); } int pwcuSetLastSongTime (time4_t clk) { PWCU_START(); u.lastsong = clk; cuser.lastsong = clk; PWCU_END(); } int pwcuSetMyAngel (const char *angel_uid) { PWCU_START(); strlcpy( u.myangel, angel_uid, sizeof( u.myangel)); strlcpy(cuser.myangel, angel_uid, sizeof(cuser.myangel)); PWCU_END(); } int pwcuSetNickname (const char *nickname) { PWCU_START(); strlcpy( u.nickname, nickname, sizeof( u.nickname)); strlcpy(cuser.nickname, nickname, sizeof(cuser.nickname)); PWCU_END(); } int pwcuToggleOutMail() { PWCU_START(); u.uflag2 ^= REJ_OUTTAMAIL; _SETBY_BIT(cuser.uflag2, REJ_OUTTAMAIL, u.uflag2 & REJ_OUTTAMAIL); PWCU_END(); } int pwcuSetLoginView(unsigned int bits) { PWCU_START(); u.loginview = bits; cuser.loginview = u.loginview; PWCU_END(); } #include "chess.h" int pwcuChessResult(int sigType, ChessGameResult r) { uint16_t *utmp_win = NULL, *cuser_win = NULL, *u_win = NULL, *utmp_lose= NULL, *cuser_lose= NULL, *u_lose= NULL, *utmp_tie = NULL, *cuser_tie = NULL, *u_tie = NULL; PWCU_START(); // verify variable size assert(sizeof(* utmp_win) == sizeof(currutmp->chc_win)); assert(sizeof(*cuser_lose)== sizeof( cuser.five_lose)); assert(sizeof(* u_tie) == sizeof( u.go_tie)); // determine variables switch(sigType) { case SIG_CHC: utmp_win = &(currutmp->chc_win); utmp_lose = &(currutmp->chc_lose); utmp_tie = &(currutmp->chc_tie); cuser_win = &( cuser.chc_win); cuser_lose= &( cuser.chc_lose); cuser_tie = &( cuser.chc_tie); u_win = &( u.chc_win); u_lose = &( u.chc_lose); u_tie = &( u.chc_tie); break; case SIG_GO: utmp_win = &(currutmp->go_win); utmp_lose = &(currutmp->go_lose); utmp_tie = &(currutmp->go_tie); cuser_win = &( cuser.go_win); cuser_lose= &( cuser.go_lose); cuser_tie = &( cuser.go_tie); u_win = &( u.go_win); u_lose = &( u.go_lose); u_tie = &( u.go_tie); break; case SIG_GOMO: utmp_win = &(currutmp->five_win); utmp_lose = &(currutmp->five_lose); utmp_tie = &(currutmp->five_tie); cuser_win = &( cuser.five_win); cuser_lose= &( cuser.five_lose); cuser_tie = &( cuser.five_tie); u_win = &( u.five_win); u_lose = &( u.five_lose); u_tie = &( u.five_tie); break; default: assert(!"unknown sigtype"); break; } // perform action switch(r) { case CHESS_RESULT_WIN: *utmp_win = *cuser_win = ++(*u_win); // recover init lose if (*u_lose > 0) *utmp_lose = *cuser_lose = --(*u_lose); break; case CHESS_RESULT_TIE: *utmp_tie = *cuser_tie = ++*u_tie; // recover init lose if (*u_lose > 0) *utmp_lose = *cuser_lose = --(*u_lose); break; case CHESS_RESULT_LOST: *utmp_lose = *cuser_lose = ++(*u_lose); break; default: assert(!"unknown result"); return -1; } PWCU_END(); } int pwcuSetChessEloRating(uint16_t elo_rating) { PWCU_START(); cuser.chess_elo_rating = u.chess_elo_rating = elo_rating; PWCU_END(); } // non-important variables (only save on exit) int pwcuSetSignature(unsigned char newsig) { cuser.signature = newsig; return 0; } int pwcuSetWaterballMode(unsigned int bm) { bm &= WATER_MASK; cuser.uflag2 &= ~WATER_MASK; cuser.uflag2 |= bm; return 0; } int pwcuToggleSortBoard () { cuser.uflag ^= BRDSORT_FLAG; return 0; } int pwcuToggleFriendList() { cuser.uflag ^= FRIEND_FLAG; return 0; } // session save // XXX this is a little different - only invoked at login, // which we should update/calculate every variables to log. int pwcuLoginSave () { PWCU_START(); // XXX no need to reload for speed up? // new host from 'fromhost' 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) ) cuser.numlogins++; // update last login time cuser.lastlogin = login_start_time; if (!PERM_HIDE(currutmp)) cuser.lastseen = login_start_time; PWCU_END(); } // XXX this is a little different - only invoked at exist, // so no need to sync back to cuser. int pwcuExitSave () { PWCU_START(); _DISABLE_BIT(u.uflag, (PAGER_FLAG | CLOAK_FLAG)); if (currutmp->pager != PAGER_ON) _ENABLE_BIT(u.uflag, PAGER_FLAG); if (currutmp->invisible) _ENABLE_BIT(u.uflag, CLOAK_FLAG); u.invisible = currutmp->invisible; u.withme = currutmp->withme; u.pager = currutmp->pager; // XXX 當初設計的人把 mind 設計成非 NULL terminated 的... // assert(sizeof(u.mind) == sizeof(currutmp->mind)); memcpy(u.mind,currutmp->mind, sizeof(u.mind)); reload_money(); PWCU_END(); } // Initialization void pwcuInitZero () { bzero(&cuser, sizeof(cuser)); } int pwcuInitAdminPerm () { PWCU_START(); cuser.userlevel = PERM_BASIC | PERM_CHAT | PERM_PAGE | PERM_POST | PERM_LOGINOK | PERM_MAILLIMIT | PERM_CLOAK | PERM_SEECLOAK | PERM_XEMPT | PERM_SYSOPHIDE | PERM_BM | PERM_ACCOUNTS | PERM_CHATROOM | PERM_BOARD | PERM_SYSOP | PERM_BBSADM; PWCU_END(); } void pwcuInitGuestPerm () { cuser.userlevel = 0; cuser.uflag = PAGER_FLAG | BRDSORT_FLAG | MOVIE_FLAG; cuser.uflag2= 0; // we don't need FAVNEW_FLAG or anything else. # ifdef GUEST_DEFAULT_DBCS_NOINTRESC _ENABLE_BIT(cuser.uflag, DBCS_NOINTRESC); # endif } #undef DIM #define DIM(x) (sizeof(x)/sizeof(x[0])) void pwcuInitGuestInfo () { int i; char *nick[] = { "椰子", "貝殼", "內衣", "寶特瓶", "翻車魚", "樹葉", "浮萍", "鞋子", "潛水艇", "魔王", "鐵罐", "考卷", "大美女" }; i = random() % DIM(nick); snprintf(cuser.nickname, sizeof(cuser.nickname), "海邊漂來的%s", nick[i]); strlcpy(currutmp->nickname, cuser.nickname, sizeof(currutmp->nickname)); strlcpy(cuser.realname, "guest", sizeof(cuser.realname)); memset (cuser.mind, 0, sizeof(cuser.mind)); cuser.sex = i % 8; }