数据结构
消息索引
- msgindex:全消息箱
- msgindex2:收件箱
- 0x00-0x03 4字节
- 对于收件箱:已读消息个数
- 之后:struct msghead[]
- 对应 MsgHead
struct msghead {
int pos, len; // 消息体在msgcontent中的位置&长度
char sent; // 1: 发送的消息 0: 收到的消息
char mode; //
char id[IDLEN+2]; // 发送/接收者ID
time_t time; // 发送/接收时间
int frompid, topid; // 发送/接收者进程号
};
发送消息过程分析
int sendmsgfunc(struct user_info *uentp, const char *msgstr, int mode)
{
char uident[STRLEN];
struct user_info *uin;
struct msghead head, head2;
*msgerr = 0;
uin = uentp; // uin = 接收者userinfo
strcpy(uident, uin->userid); // uident = 接收者userid
if (!HAS_PERM(currentuser, PERM_SEECLOAK) && uin->invisible && strcmp(uin->userid, currentuser->userid) && mode != 4)
// 若接收者隐身并且我们不能看隐身,并且不是自己发给自己,则不让发
{
return -2;
}
if ((mode != 3) && (LOCKSCREEN == uin->mode)) { /* Leeward 98.02.28 */
// 对方锁屏,不让发
strcpy(msgerr, "对方已经锁定屏幕,请稍候再发或给他(她)写信...");
return -1;
}
if ((mode != 3) && (false == canIsend2(currentuser,uin->userid))) { /*Haohmaru.06.06.99.检查自己是否被ignore */
// 对方拒绝你的消息,不让发
// canIsend2()在stuff.c
// 拒绝列表在ignores文件里
strcpy(msgerr, "对方拒绝接受你的讯息...");
return -1;
}
if (mode != 3 && uin->mode != WEBEXPLORE) {
if (get_unreadcount(uident) > MAXMESSAGE) {
// 未读消息太多,不让发
strcpy(msgerr, "对方尚有一些讯息未处理,请稍候再发或给他(她)写信...");
return -1;
}
}
if (msgstr == NULL) {
// 木有消息,不让发……
// Comment: 为啥不早查……
return 0;
}
// 开工构造消息头
// 这个是存接收者那边的……
head.time = time(0); // 发送时间
head.sent = 0; // 接收方消息头
head.mode = mode; // 发送者模式
strncpy(head.id, currentuser->userid, IDLEN+2); // 发送者userid(sent=0)
head.frompid = getuinfopid(); // 发送者pid
head.topid = uin->pid; // 接收者pid
// 这个是存发送者那边的……
memcpy(&head2, &head, sizeof(struct msghead)); // 拷一份,发送者消息头
head2.sent = 1; // 我发的!
strncpy(head2.id, uident, IDLEN+2); // 接收者userid(sent=1)
// 造好了
// 再查一次用户userinfo……
// t_search()在stuff.c
uin = t_search(MsgDesUid, uentp->pid);
// 这次查败了,说明接收者跑了,可能是写消息的时候跑的
if ((uin == NULL) || (uin->active == 0) || (uin->pid == 0) || ((kill(uin->pid, 0) != 0) && (uentp->pid != 1))
|| strncasecmp(MsgDesUid,uident,STRLEN)) {
strcpy(msgerr, "对方已经离线...");
return -1;
}
// 保存消息
// 消息加到接收者收件箱
if (save_msgtext(uident, &head, msgstr) < 0)
return -2;
if (strcmp(currentuser->userid, uident)&&mode!=3) {
// 如果不是自己发给自己,那就在发送者这边也存一份……
if (save_msgtext(currentuser->userid, &head2, msgstr) < 0)
return -2;
}
if( uin->mode == WWW ){
uin->mailcheck |= CHECK_MSG;
return 1;
}
// 保存完毕
// 消息通知
// 发送SIGUSR2说明有新消息
if (uentp->pid != 1 && kill(uin->pid, SIGUSR2) == -1) {
strcpy(msgerr, "对方已经离线.....");
return -1;
}
// 完成!
return 1;
}
libmsg.c
- canmsg [(struct userec *fromuser, struct user_info *uin)]
- User.CanSendTo()
- can_override [(char *userid, char *whoasks)]
- 没人用过……
- msg_can_sendmsg [(char *userid, int utmppid)]
- 没人用过……
- save_msgtext()
- 对应 MsgBox.SaveMsgText()
- 把消息存到用户的msgindex与msgcontent文件中。如果是接收到的,也存到msgindex2中。
- load_msghead()
- 对应 MsgBox.LoadMsgHead()
- 读出某个消息头,可以指定全消息箱还是收件箱。
- get_msgcount()
- 对应 MsgBox.GetMsgCount()
- 获取消息数量。
- clear_msg()
- 对应 MsgBox.ClearMsg()
- 清除所有消息
- get_unreadcount()
- 对应 MsgBox.GetUnreadCount()
- 获取未读消息数
- get_unreadmsg()
- 对应 MsgBox.GetUnreadMsg()
- 从收件箱里获取某条消息,并且修改已读指针。
- load_msgtext()
- 对应 MsgBox.LoadMsgText()
- 读取某条消息的内容。
- sendmsgfunc()
- 发送消息。
- translate_msg()
- 将消息转换为在消息记录之类里面看见的样子
- mail_msg()
- 将所有消息放入邮件寄回信箱。
- mailbacklastmsg()
- 将未发送成功消息寄回信箱。
SMS支持
不在研究范围……
SQL相关
意义不明…… 貌似是通讯录一类的东西