(未显示同一用户的7个中间版本) | |||
第1行: | 第1行: | ||
− | + | [[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 = | + | 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 | |
+ | * 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里的列表。方法是从空的开始一个一个插。 | ||
− | |||
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(),之后防锁,恢复只读。 | |
− | |||
; 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() | ||
− | + | === 好友相关 === | |
− | + | 见[[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()
好友相关
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)]