BBS的用户相关的东西。这块非常复杂,分成好几个部分。

UTMP

UTMPHEAD

struct UTMPHEAD {
    int next[USHM_SIZE];
    int hashhead[UTMP_HASHSIZE + 1];    /* use UCACHE_HASHSIZE/32 */
    int number;
    int listhead;
    int list_prev[USHM_SIZE];   /* sorted list prev ptr */
    int list_next[USHM_SIZE];   /* sorted list next ptr */
    time_t uptime;
};

static struct UTMPHEAD *utmphead;

utmphead其实指向一块shared memory,key = UTMPHEAD_SHMKEY

UTMPHEAD结构/数据由UtmpHead类处理,全都为GetXXX/SetXXX形式。

listhead, list_prev和list_next构成一个单向循环链表,listhead是表头,里面按照不分大小写的userid排列。

hashhead和next构成一个拉链式散列表,hashhead是表头,next是链上下一个。

number是登录用户数。uptime是上次刷新用户列表的时间。

UTMPFILE

  • 摘自KBS网站

utmpshm 的类型是 UTMPFILE 结构,用来存储登录的状态信息。注意 wwwguest 和这个结构完全没有关系。 这其实也是一块shared memory, key = UTMP_SHMKEY

#define USHM_SIZE       (MAXACTIVE + 10)
struct UTMPFILE {
    struct user_info uinfo[USHM_SIZE];
//        登录状态信息。每个登录都有一个登录号(utmpnum),他就是该登录在
//        uinfo 数组中的位置,注意 utmpnum 是 1-based。
};

uinfo 数组的每一个元素都可以用来存储一个登录的状态信息,其结构 user_info 定义:

struct user_info {              /* Structure used in UTMP file */
    int active;                 /* When allocated this field is true */
//        本结构当前是否代表一个登录用户。
    int uid;                    /* Used to find user name in passwd file */
//        登录用户的 uid。
    int pid;                    /* kill() to notify user of talk request */
//        telnet 登录表示其进程号。www 登录设置为 1。
    int invisible;              /* Used by cloaking function in Xyz menu */
//        是否隐身。
    int sockactive;             /* Used to coordinate talk requests */
    int sockaddr;               /* ... */
    int destuid;                /* talk uses this to identify who called */
    int mode;                   /* UL/DL, Talk Mode, Chat Mode, ... */
//        状态,应该赋值为 modes.h 里面的常数。
    int pager;                  /* pager toggle, true, or false */
/*        呼叫器状态,bitwise-OR 以下属性
            ALL_PAGER       0x1
            FRIEND_PAGER    0x2
            ALLMSG_PAGER    0x4
            FRIENDMSG_PAGER 0x8 */
    int in_chat;                /* for in_chat commands   */
    char chatid[16];            /* chat id, if in chat mode */
    char from[IPLEN + 4];       /* machine name the user called in from */
//        登录 IP。
    time_t logintime;
//        登录时间戳。
    int lastpost;
//        上次发文的时间戳。
    char unused[32];
    time_t freshtime;
//        上次活动的时间戳,用来计算发呆时间。
    int utmpkey;
//        登录 key,用于 www cookie 验证保持用户身份。
    unsigned int mailbox_prop;  /* properties of getCurrentUser()'s mailbox */
//        用户信箱选项,登录时从用户 .mailbox.prop 文件读取,参考 3.3 节
    char userid[20];
//        用户名
    char realname[20];
//        真实姓名,登录时从用户 userdata 结构读取
    char username[40];
//        用户昵称,登录时从 uidshm 共享内存去读取,修改临时昵称就是修改这个字段
    int friendsnum;
//        好友数量
    int friends_uid[MAXFRIENDS];
//        每个好友的 uid,前 friendsnum 个有效。
#ifdef FRIEND_MULTI_GROUP
    unsigned int friends_p[MAXFRIENDS];
#endif
    int currentboard;
//        当前所在版面的 bid 号
    unsigned int mailcheck;     /* if have new mail or new msg, stiger */
//        当前登录是否有新信或新消息
};

utmp.c

get_utmpshm_addr()
  • Utmp.utmpshm
longlock [(int signo)]
  • inside Utmp.Lock()
utmp_lock
  • Utmp.Lock()
utmp_unlock [(int fd)]
  • Utmp.Unlock()
utmp_setreadonly [(int readonly)]
  • UtmpHead.SetReadOnly()
detach_utmp

仅在WWW中使用。

resolve_utmp
  • Utmp.Init()
utmp_hash [(const char *userid)]
  • Utmp.Hash()
   logloop
getnewutmpent [(struct user_info *up)]
  • Utmp.GetNewUtmpEntry()
getnewutmpent2 [(struct user_info *up)]

仅在WWW中使用。

   rebuild_list [(struct user_info *up, char *arg, int p)]
   apply_ulist [(APPLY_UTMP_FUNC fptr, void *arg)]
   apply_ulist_addr [(APPLY_UTMP_FUNC fptr, void *arg)]
   apply_utmpuid [(APPLY_UTMP_FUNC fptr, int uid, void *arg)]
   apply_utmp [(APPLY_UTMP_FUNC fptr, int maxcount,const char *userid, void *arg)]
   search_ulist [(struct user_info *uentp, int (*fptr) (int, struct user_info *), int farg)]
clear_utmp2 [(int uent)]
  • Utmp.Clear2() TODO
clear_utmp [(int uent, int useridx, int pid)]
  • Utmp.Clear()
get_utmp_number
  • UtmpHead.GetNumber()
get_utmpent [(int utmpnum)]
  • UserInfo.__init__()
get_utmpent_num [(struct user_info *uent)]
  • UserInfo.GetIndex()

好友相关

BBS 好友列表

   cmpfuid [(const void*a,const void*b)]
   getfriendstr [(struct userec* user,struct user_info* puinfo)]
   myfriend [(int uid, char *fexp)]
   hisfriend [(int uid,struct user_info* him)]

ucache.c

ucache_lock
ucache_unlock [(int fd)]
   ucache_hashinit
   ucache_hash_deep [(const char *userid)]
   ucache_hash [(const char *userid)]
   fillucache [(struct userec *uentp, int *number, int *prev)]
   flush_ucache
   load_ucache
resolve_ucache
  • UCache.Init()
   detach_ucache
   getuserid [(char *userid, int uid)]
   setuserid_internal [(int num, const char *userid)]
   setuserid2 [(int num, const char *userid)]
   setuserid [(int num, const char *userid)]
   searchnewuser
searchuser [(const char *userid)]
  • UCache.SearchUser()
getuser [(const char *userid, struct userec **user)]
  • UCache.GetUser()
   getuserid2 [(int uid)]
   u_namearray [(char buf[][IDLEN + 1], int *pnum, char *tag)]
   getnewuserid3 [(char *userid)]
   getnewuserid2 [(char *userid)]
getuserbynum [(int num)]
  • UCache.GetUserByUid()
   getnewuserid [(char *userid)]
   update_user [(struct userec *user, int num, int all)]
   apply_users [(int (*fptr) (struct userec *, char *), char *arg)]
   get_giveupinfo [(char* userid,int* basicperm,int s[10][2])]
   save_giveupinfo [(struct userec* lookupuser,int lcount,int s[10][2])]
   setcachehomefile [(char* path,const char* user,int unum,char* file)]
   init_cachedata [(const char* userid,int unum)]
   flush_cachedata [(const char* userid)]
   clean_cachedata [(const char* userid,int unum)]
   do_after_login [(struct userec* user,int unum,int mode)]
   do_after_logout [(struct userec* user,struct user_info* userinfo,int unum,int mode)]

自定义User Title相关

   load_user_title
   flush_user_title
   get_user_title [(unsigned char titleidx)]
   set_user_title [(unsigned char titleidx,char* newtitle)]

WWW相关

   longlock [(int signo)]
   www_guest_lock
   www_guest_unlock [(int fd)]
   resolve_guest_table