(未显示同一用户的7个中间版本)
第1行: 第1行:
BBS的用户相关的东西。这块非常复杂,分成好几个部分。
+
[[Category:BBS 代码分析]]
 +
 
 +
对应于单个会话,也就是好友列表上一项的内容。一个用户可以有多个会话。
  
 
== UTMP ==
 
== UTMP ==
 +
 +
索引:'''loginid''',有时候也称为utmpent, uent等,就是在UTMPFILE.uinfo里的索引,不过是1为基础的。
  
 
=== UTMPHEAD ===
 
=== UTMPHEAD ===
第17行: 第21行:
 
static struct UTMPHEAD *utmphead;
 
static struct UTMPHEAD *utmphead;
 
</source>
 
</source>
utmphead其实指向一块shared memory,key = UTMP_SHMKEY
+
utmphead其实指向一块shared memory,key = UTMPHEAD_SHMKEY
  
 
UTMPHEAD结构/数据由UtmpHead类处理,全都为GetXXX/SetXXX形式。
 
UTMPHEAD结构/数据由UtmpHead类处理,全都为GetXXX/SetXXX形式。
 +
 +
listhead, list_prev和list_next构成一个单向循环链表,listhead是表头,里面按照不分大小写的userid排列。里面都是loginid,list_prev和list_next以loginid-1作为索引。
 +
 +
hashhead和next构成一个拉链式散列表,hashhead是表头,next是链上下一个。里面也都是loginid,hashead以哈希值作为索引,next以loginid-1作为索引。
 +
 +
其中,hashhead[0]为特殊链表,包含所有空闲的loginid。
 +
 +
number是登录用户数。uptime是上次刷新用户列表的时间,到时间就会扫一遍,剔除异常项。
 +
 +
=== UTMPFILE ===
 +
* 摘自KBS网站
 +
 +
utmpshm 的类型是 UTMPFILE 结构,用来存储登录的状态信息。注意 wwwguest 和这个结构完全没有关系。
 +
这其实也是一块shared memory, key = UTMP_SHMKEY
 +
 +
<source lang="C">
 +
#define USHM_SIZE      (MAXACTIVE + 10)
 +
struct UTMPFILE {
 +
    struct user_info uinfo[USHM_SIZE];
 +
//        登录状态信息。每个登录都有一个登录号(utmpnum),他就是该登录在
 +
//        uinfo 数组中的位置,注意 utmpnum 是 1-based。
 +
};
 +
</source>
 +
 +
uinfo 数组的每一个元素都可以用来存储一个登录的状态信息,其结构 user_info 定义:
 +
 +
<source lang="C">
 +
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 */
 +
//        当前登录是否有新信或新消息
 +
};
 +
</source>
  
 
== utmp.c ==
 
== utmp.c ==
第39行: 第124行:
  
 
; detach_utmp
 
; detach_utmp
仅在WWW中使用。
+
: 仅在WWW中使用。
  
 
; resolve_utmp
 
; resolve_utmp
第47行: 第132行:
 
* Utmp.Hash()
 
* Utmp.Hash()
  
    logloop
+
; logloop
 +
* verify.verifyUtmpHead()
 +
: 检测列表是否循环。
  
 
; getnewutmpent [(struct user_info *up)]
 
; getnewutmpent [(struct user_info *up)]
 
* Utmp.GetNewUtmpEntry()
 
* Utmp.GetNewUtmpEntry()
 +
: 将新建的UserInfo填入空闲的UserInfo中,插入列表和哈希表,增加用户技术等。登录的一部分。
  
 
; getnewutmpent2 [(struct user_info *up)]
 
; getnewutmpent2 [(struct user_info *up)]
仅在WWW中使用。
+
: 仅在WWW中使用。
 +
 
 +
; rebuild_list [(struct user_info *up, char *arg, int p)]
 +
* Utmp.RebuildList() '''TODO'''
 +
: 重建UtmpHead里的列表。方法是从空的开始一个一个插。
  
    rebuild_list [(struct user_info *up, char *arg, int p)]
 
 
     apply_ulist [(APPLY_UTMP_FUNC fptr, void *arg)]
 
     apply_ulist [(APPLY_UTMP_FUNC fptr, void *arg)]
 
     apply_ulist_addr [(APPLY_UTMP_FUNC fptr, void *arg)]
 
     apply_ulist_addr [(APPLY_UTMP_FUNC fptr, void *arg)]
第63行: 第154行:
  
 
; clear_utmp2 [(int uent)]
 
; clear_utmp2 [(int uent)]
 +
* Utmp.Clear2()
 +
: 清理会话,包括从列表和哈希表删掉,减上站数,清空记录,以及调DoAfterLogout()做收尾工作。
 +
 +
; clear_utmp [(int uent, int useridx, int pid)]
 
* Utmp.Clear()
 
* Utmp.Clear()
 
+
: 稍作检查,将SHM弄成可写,拿锁,随后调Clear2(),之后防锁,恢复只读。
    clear_utmp [(int uent, int useridx, int pid)]
 
  
 
; get_utmp_number
 
; get_utmp_number
 
* UtmpHead.GetNumber()
 
* UtmpHead.GetNumber()
 +
: 拿上站人数
 +
 +
; get_utmpent [(int utmpnum)]
 +
* UserInfo.__init__()
 +
 +
; get_utmpent_num [(struct user_info *uent)]
 +
* UserInfo.GetIndex()
  
    get_utmpent [(int utmpnum)]
+
=== 好友相关 ===
    get_utmpent_num [(struct user_info *uent)]
+
见[[BBS 好友列表]]
 
     cmpfuid [(const void*a,const void*b)]
 
     cmpfuid [(const void*a,const void*b)]
 
     getfriendstr [(struct userec* user,struct user_info* puinfo)]
 
     getfriendstr [(struct userec* user,struct user_info* puinfo)]
 
     myfriend [(int uid, char *fexp)]
 
     myfriend [(int uid, char *fexp)]
 
     hisfriend [(int uid,struct user_info* him)]
 
     hisfriend [(int uid,struct user_info* him)]

2012年2月5日 (日) 04:18的最新版本


对应于单个会话,也就是好友列表上一项的内容。一个用户可以有多个会话。

UTMP

索引:loginid,有时候也称为utmpent, uent等,就是在UTMPFILE.uinfo里的索引,不过是1为基础的。

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排列。里面都是loginid,list_prev和list_next以loginid-1作为索引。

hashhead和next构成一个拉链式散列表,hashhead是表头,next是链上下一个。里面也都是loginid,hashead以哈希值作为索引,next以loginid-1作为索引。

其中,hashhead[0]为特殊链表,包含所有空闲的loginid。

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
  • verify.verifyUtmpHead()
检测列表是否循环。
getnewutmpent [(struct user_info *up)]
  • Utmp.GetNewUtmpEntry()
将新建的UserInfo填入空闲的UserInfo中,插入列表和哈希表,增加用户技术等。登录的一部分。
getnewutmpent2 [(struct user_info *up)]
仅在WWW中使用。
rebuild_list [(struct user_info *up, char *arg, int p)]
  • Utmp.RebuildList() TODO
重建UtmpHead里的列表。方法是从空的开始一个一个插。
   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()
清理会话,包括从列表和哈希表删掉,减上站数,清空记录,以及调DoAfterLogout()做收尾工作。
clear_utmp [(int uent, int useridx, int pid)]
  • Utmp.Clear()
稍作检查,将SHM弄成可写,拿锁,随后调Clear2(),之后防锁,恢复只读。
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)]