X-Git-Url: http://andersk.mit.edu/gitweb/libfaim.git/blobdiff_plain/5b79dc938f4e84b913b53d35aa229e54f041252d..313a06b7b4be217e90a17413862dc04552f693c3:/aim_chat.c diff --git a/aim_chat.c b/aim_chat.c index 03650ac..b1f260a 100644 --- a/aim_chat.c +++ b/aim_chat.c @@ -1,13 +1,13 @@ /* * aim_chat.c * - * Routines for the Chat service. Nothing works (yet). + * Routines for the Chat service. * */ #include -char *aim_chat_getname(struct aim_conn_t *conn) +faim_export char *aim_chat_getname(struct aim_conn_t *conn) { if (!conn) return NULL; @@ -17,25 +17,23 @@ char *aim_chat_getname(struct aim_conn_t *conn) return (char *)conn->priv; /* yuck ! */ } -struct aim_conn_t *aim_chat_getconn(struct aim_session_t *sess, char *name) +faim_export struct aim_conn_t *aim_chat_getconn(struct aim_session_t *sess, char *name) { - int i; + struct aim_conn_t *cur; + + faim_mutex_lock(&sess->connlistlock); + for (cur = sess->connlist; cur; cur = cur->next) { + if (cur->type != AIM_CONN_TYPE_CHAT) + continue; + if (strcmp((char *)cur->priv, name) == 0) + break; + } + faim_mutex_unlock(&sess->connlistlock); - for (i=0;iconns[i].type == AIM_CONN_TYPE_CHAT) - { - if (sess->conns[i].priv) - if (!strcmp((char *)sess->conns[i].priv, name)) - { - return &sess->conns[i]; - } - } - } - return NULL; + return cur; } -int aim_chat_attachname(struct aim_conn_t *conn, char *roomname) +faim_export int aim_chat_attachname(struct aim_conn_t *conn, char *roomname) { if (!conn || !roomname) return -1; @@ -46,9 +44,9 @@ int aim_chat_attachname(struct aim_conn_t *conn, char *roomname) return 0; } -u_long aim_chat_send_im(struct aim_session_t *sess, - struct aim_conn_t *conn, - char *msg) +faim_export unsigned long aim_chat_send_im(struct aim_session_t *sess, + struct aim_conn_t *conn, + char *msg) { int curbyte,i; @@ -57,7 +55,7 @@ u_long aim_chat_send_im(struct aim_session_t *sess, if (!sess || !conn || !msg) return 0; - if (!(newpacket = aim_tx_new(0x0002, conn, 1152))) + if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 1152))) return -1; newpacket->lock = 1; /* lock struct */ @@ -70,7 +68,9 @@ u_long aim_chat_send_im(struct aim_session_t *sess, * Generate a random message cookie */ for (i=0;i<8;i++) - curbyte += aimutil_put8(newpacket->data+curbyte, (u_char) random()); + curbyte += aimutil_put8(newpacket->data+curbyte, (u_char) rand()); + + aim_cachecookie(sess, aim_mkcookie(newpacket->data+curbyte-8, AIM_COOKIETYPE_CHAT, NULL)); /* * metaTLV start. -- i assume this is a metaTLV. it could be the @@ -121,10 +121,10 @@ u_long aim_chat_send_im(struct aim_session_t *sess, * and room name. * */ -u_long aim_chat_join(struct aim_session_t *sess, - struct aim_conn_t *conn, - u_short exchange, - const char *roomname) +faim_export unsigned long aim_chat_join(struct aim_session_t *sess, + struct aim_conn_t *conn, + u_short exchange, + const char *roomname) { struct command_tx_struct *newpacket; int i; @@ -132,7 +132,7 @@ u_long aim_chat_join(struct aim_session_t *sess, if (!sess || !conn || !roomname) return 0; - if (!(newpacket = aim_tx_new(0x0002, conn, 10+9+strlen(roomname)+2))) + if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 10+9+strlen(roomname)+2))) return -1; newpacket->lock = 1; @@ -188,7 +188,7 @@ u_long aim_chat_join(struct aim_session_t *sess, return (sess->snac_nextid++); } -int aim_chat_readroominfo(u_char *buf, struct aim_chat_roominfo *outinfo) +faim_internal int aim_chat_readroominfo(u_char *buf, struct aim_chat_roominfo *outinfo) { int namelen = 0; int i = 0; @@ -211,7 +211,7 @@ int aim_chat_readroominfo(u_char *buf, struct aim_chat_roominfo *outinfo) i += 2; return i; -}; +} /* @@ -221,9 +221,10 @@ int aim_chat_readroominfo(u_char *buf, struct aim_chat_roominfo *outinfo) * them to any of the 'Unknown's: * - Language (English) * + * SNAC 000e/0002 */ -int aim_chat_parse_infoupdate(struct aim_session_t *sess, - struct command_rx_struct *command) +faim_internal int aim_chat_parse_infoupdate(struct aim_session_t *sess, + struct command_rx_struct *command) { struct aim_userinfo_s *userinfo = NULL; rxcallback_t userfunc=NULL; @@ -235,12 +236,25 @@ int aim_chat_parse_infoupdate(struct aim_session_t *sess, u_short tlvcount = 0; struct aim_tlvlist_t *tlvlist; char *roomdesc = NULL; + struct aim_tlv_t *tmptlv; + unsigned short unknown_c9 = 0; + unsigned long creationtime = 0; + unsigned short maxmsglen = 0; + unsigned short unknown_d2 = 0, unknown_d5 = 0; i = 10; i += aim_chat_readroominfo(command->data+i, &roominfo); detaillevel = aimutil_get8(command->data+i); i++; + + if (detaillevel != 0x02) { + if (detaillevel == 0x01) + printf("faim: chat_roomupdateinfo: detail level 1 not supported\n"); + else + printf("faim: chat_roomupdateinfo: unknown detail level %d\n", detaillevel); + return 1; + } tlvcount = aimutil_get16(command->data+i); i += 2; @@ -259,55 +273,53 @@ int aim_chat_parse_infoupdate(struct aim_session_t *sess, /* * Type 0x006f: Number of occupants. */ - if (aim_gettlv(tlvlist, 0x006f, 1)) - { - struct aim_tlv_t *tmptlv; - tmptlv = aim_gettlv(tlvlist, 0x006f, 1); - - usercount = aimutil_get16(tmptlv->value); - } + if (aim_gettlv(tlvlist, 0x006f, 1)) { + struct aim_tlv_t *tmptlv; + tmptlv = aim_gettlv(tlvlist, 0x006f, 1); + + usercount = aimutil_get16(tmptlv->value); + } /* * Type 0x0073: Occupant list. */ - if (aim_gettlv(tlvlist, 0x0073, 1)) - { - int curoccupant = 0; - struct aim_tlv_t *tmptlv; - - tmptlv = aim_gettlv(tlvlist, 0x0073, 1); - - /* Allocate enough userinfo structs for all occupants */ - userinfo = calloc(usercount, sizeof(struct aim_userinfo_s)); + if (aim_gettlv(tlvlist, 0x0073, 1)) { + int curoccupant = 0; + struct aim_tlv_t *tmptlv; + + tmptlv = aim_gettlv(tlvlist, 0x0073, 1); - i = 0; - while (curoccupant < usercount) - i += aim_extractuserinfo(tmptlv->value+i, &userinfo[curoccupant++]); - } + /* Allocate enough userinfo structs for all occupants */ + userinfo = calloc(usercount, sizeof(struct aim_userinfo_s)); + + i = 0; + while (curoccupant < usercount) + i += aim_extractuserinfo(tmptlv->value+i, &userinfo[curoccupant++]); + } /* - * Type 0x00c9: Unknown. + * Type 0x00c9: Unknown. (2 bytes) */ - if (aim_gettlv(tlvlist, 0x00c9, 1)) - ; + if ((tmptlv = aim_gettlv(tlvlist, 0x00c9, 1))) + unknown_c9 = aimutil_get16(tmptlv->value); /* - * Type 0x00ca: Creation date + * Type 0x00ca: Creation time (4 bytes) */ - if (aim_gettlv(tlvlist, 0x00ca, 1)) - ; + if ((tmptlv = aim_gettlv(tlvlist, 0x00ca, 1))) + creationtime = aimutil_get32(tmptlv->value); /* * Type 0x00d1: Maximum Message Length */ - if (aim_gettlv(tlvlist, 0x00d1, 1)) - ; + if ((tmptlv = aim_gettlv(tlvlist, 0x00d1, 1))) + maxmsglen = aimutil_get16(tmptlv->value); /* - * Type 0x00d2: Unknown. + * Type 0x00d2: Unknown. (2 bytes) */ - if (aim_gettlv(tlvlist, 0x00d2, 1)) - ; + if ((tmptlv = aim_gettlv(tlvlist, 0x00d2, 1))) + unknown_d2 = aimutil_get16(tmptlv->value);; /* * Type 0x00d3: Room Description @@ -316,23 +328,27 @@ int aim_chat_parse_infoupdate(struct aim_session_t *sess, roomdesc = aim_gettlv_str(tlvlist, 0x00d3, 1); /* - * Type 0x00d5: Unknown. + * Type 0x00d5: Unknown. (1 byte) */ - if (aim_gettlv(tlvlist, 0x00d5, 1)) - ; + if ((tmptlv = aim_gettlv(tlvlist, 0x00d5, 1))) + unknown_d5 = aimutil_get8(tmptlv->value);; userfunc = aim_callhandler(command->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_ROOMINFOUPDATE); - if (userfunc) - { - ret = userfunc(sess, - command, - &roominfo, - roomname, - usercount, - userinfo, - roomdesc); - } + if (userfunc) { + ret = userfunc(sess, + command, + &roominfo, + roomname, + usercount, + userinfo, + roomdesc, + unknown_c9, + creationtime, + maxmsglen, + unknown_d2, + unknown_d5); + } free(roominfo.name); free(userinfo); free(roomname); @@ -342,57 +358,53 @@ int aim_chat_parse_infoupdate(struct aim_session_t *sess, return ret; } -int aim_chat_parse_joined(struct aim_session_t *sess, - struct command_rx_struct *command) +faim_internal int aim_chat_parse_joined(struct aim_session_t *sess, + struct command_rx_struct *command) { struct aim_userinfo_s *userinfo = NULL; rxcallback_t userfunc=NULL; int i = 10, curcount = 0, ret = 1; - while (i < command->commandlen) - { - curcount++; - userinfo = realloc(userinfo, curcount * sizeof(struct aim_userinfo_s)); - i += aim_extractuserinfo(command->data+i, &userinfo[curcount-1]); - } + while (i < command->commandlen) { + curcount++; + userinfo = realloc(userinfo, curcount * sizeof(struct aim_userinfo_s)); + i += aim_extractuserinfo(command->data+i, &userinfo[curcount-1]); + } userfunc = aim_callhandler(command->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_USERJOIN); - if (userfunc) - { - ret = userfunc(sess, - command, - curcount, - userinfo); - } + if (userfunc) { + ret = userfunc(sess, + command, + curcount, + userinfo); + } free(userinfo); return ret; } -int aim_chat_parse_leave(struct aim_session_t *sess, - struct command_rx_struct *command) +faim_internal int aim_chat_parse_leave(struct aim_session_t *sess, + struct command_rx_struct *command) { struct aim_userinfo_s *userinfo = NULL; rxcallback_t userfunc=NULL; int i = 10, curcount = 0, ret = 1; - while (i < command->commandlen) - { - curcount++; - userinfo = realloc(userinfo, curcount * sizeof(struct aim_userinfo_s)); - i += aim_extractuserinfo(command->data+i, &userinfo[curcount-1]); - } + while (i < command->commandlen) { + curcount++; + userinfo = realloc(userinfo, curcount * sizeof(struct aim_userinfo_s)); + i += aim_extractuserinfo(command->data+i, &userinfo[curcount-1]); + } userfunc = aim_callhandler(command->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_USERLEAVE); - if (userfunc) - { - ret = userfunc(sess, - command, - curcount, - userinfo); - } + if (userfunc) { + ret = userfunc(sess, + command, + curcount, + userinfo); + } free(userinfo); @@ -404,8 +416,8 @@ int aim_chat_parse_leave(struct aim_session_t *sess, * code as channel 0x0003, however, since only the start * would be the same, we might as well do it here. */ -int aim_chat_parse_incoming(struct aim_session_t *sess, - struct command_rx_struct *command) +faim_internal int aim_chat_parse_incoming(struct aim_session_t *sess, + struct command_rx_struct *command) { struct aim_userinfo_s userinfo; rxcallback_t userfunc=NULL; @@ -420,11 +432,13 @@ int aim_chat_parse_incoming(struct aim_session_t *sess, i = 10; /* skip snac */ /* - * ICBM Cookie. Ignore it. + * ICBM Cookie. Cache it. */ for (z=0; z<8; z++,i++) cookie[z] = command->data[i]; + aim_cachecookie(sess, aim_mkcookie(cookie, AIM_COOKIETYPE_ICBM, NULL)); + /* * Channel ID * @@ -437,11 +451,10 @@ int aim_chat_parse_incoming(struct aim_session_t *sess, channel = aimutil_get16(command->data+i); i += 2; - if (channel != 0x0003) - { - printf("faim: chat_incoming: unknown channel! (0x%04x)\n", channel); - return 1; - } + if (channel != 0x0003) { + printf("faim: chat_incoming: unknown channel! (0x%04x)\n", channel); + return 1; + } /* * Start parsing TLVs right away. @@ -451,13 +464,12 @@ int aim_chat_parse_incoming(struct aim_session_t *sess, /* * Type 0x0003: Source User Information */ - if (aim_gettlv(outerlist, 0x0003, 1)) - { - struct aim_tlv_t *userinfotlv; - - userinfotlv = aim_gettlv(outerlist, 0x0003, 1); - aim_extractuserinfo(userinfotlv->value, &userinfo); - } + if (aim_gettlv(outerlist, 0x0003, 1)) { + struct aim_tlv_t *userinfotlv; + + userinfotlv = aim_gettlv(outerlist, 0x0003, 1); + aim_extractuserinfo(userinfotlv->value, &userinfo); + } /* * Type 0x0001: Unknown. @@ -499,13 +511,13 @@ int aim_chat_parse_incoming(struct aim_session_t *sess, return ret; } -u_long aim_chat_clientready(struct aim_session_t *sess, - struct aim_conn_t *conn) +faim_export unsigned long aim_chat_clientready(struct aim_session_t *sess, + struct aim_conn_t *conn) { struct command_tx_struct *newpacket; int i; - if (!(newpacket = aim_tx_new(0x0002, conn, 0x20))) + if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 0x20))) return -1; newpacket->lock = 1; @@ -530,35 +542,28 @@ u_long aim_chat_clientready(struct aim_session_t *sess, return (sess->snac_nextid++); } -int aim_chat_leaveroom(struct aim_session_t *sess, char *name) +faim_export int aim_chat_leaveroom(struct aim_session_t *sess, char *name) { - int i; + struct aim_conn_t *conn; - for (i=0;iconns[i].type == AIM_CONN_TYPE_CHAT) - { - if (sess->conns[i].priv) - if (!strcmp((char *)sess->conns[i].priv, name)) - { - aim_conn_close(&sess->conns[i]); - return 0; - } - } - } - return -1; + if ((conn = aim_chat_getconn(sess, name))) + aim_conn_kill(sess, &conn); + + if (!conn) + return -1; + return 0; } /* * conn must be a BOS connection! */ -u_long aim_chat_invite(struct aim_session_t *sess, - struct aim_conn_t *conn, - char *sn, - char *msg, - u_short exchange, - char *roomname, - u_short instance) +faim_export unsigned long aim_chat_invite(struct aim_session_t *sess, + struct aim_conn_t *conn, + char *sn, + char *msg, + u_short exchange, + char *roomname, + u_short instance) { struct command_tx_struct *newpacket; int i,curbyte=0; @@ -566,7 +571,7 @@ u_long aim_chat_invite(struct aim_session_t *sess, if (!sess || !conn || !sn || !msg || !roomname) return 0; - if (!(newpacket = aim_tx_new(0x0002, conn, 1152+strlen(sn)+strlen(roomname)+strlen(msg)))) + if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 1152+strlen(sn)+strlen(roomname)+strlen(msg)))) return -1; newpacket->lock = 1; @@ -578,6 +583,7 @@ u_long aim_chat_invite(struct aim_session_t *sess, */ for (i=0;i<8;i++) curbyte += aimutil_put8(newpacket->data+curbyte, (u_char)rand()); + aim_cachecookie(sess, aim_mkcookie(newpacket->data+curbyte-8, AIM_COOKIETYPE_CHAT, NULL)); /* * Channel (2)