From 3b101546ec5eb89988837c6134b01281dd0cfe0d Mon Sep 17 00:00:00 2001 From: jbm Date: Sat, 14 Oct 2000 06:50:36 +0000 Subject: [PATCH] (guest commit by jbm) - Mon Oct 9 04:24:56 CDT 2000 (jbm) - took care of the XXXs in aim_putuserinfo() - now use dynamic TLV count to send ("look ma, no magic!") - now send cap blocks - now send icq info if a numeric SN - Wed Oct 4 21:29:47 CDT 2000 (jbm) - Fix borked disconnect callbacks - Add aim_conn_in_sess() - A little housekeeping in faimtest ("fixing" order of printf, remove a comment) - Mon Sep 25 00:21:31 CDT 2000 (jbm) - Add a couple of ICQ userinfo parses --- CHANGES | 15 +++++++++++++ aim_conn.c | 14 ++++++++++++ aim_ft.c | 47 +++++++++++++++++++++++---------------- aim_info.c | 46 ++++++++++++++++++++++++++++++++------ aim_tlv.c | 45 +++++++++++++++++++++++++++++++++++++ faim/aim.h | 3 +++ utils/faimtest/faimtest.c | 16 ++++++++----- 7 files changed, 154 insertions(+), 32 deletions(-) diff --git a/CHANGES b/CHANGES index bd80336..846f35d 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,21 @@ No release numbers ------------------ + - Mon Oct 9 04:24:56 CDT 2000 (jbm) + - took care of the XXXs in aim_putuserinfo() + - now use dynamic TLV count to send ("look ma, no magic!") + - now send cap blocks + - now send icq info if a numeric SN + + - Wed Oct 4 21:29:47 CDT 2000 (jbm) + - Fix borked disconnect callbacks + - Add aim_conn_in_sess() + - A little housekeeping in faimtest ("fixing" order of printf, + remove a comment) + + - Mon Sep 25 00:21:31 CDT 2000 (jbm) + - Add a couple of ICQ userinfo parses + - Fri Sep 22 22:47:49 UTC 2000 - Add aim_icq_setstatus() (jbm) diff --git a/aim_conn.c b/aim_conn.c index f35b7f9..61c24f4 100644 --- a/aim_conn.c +++ b/aim_conn.c @@ -406,6 +406,20 @@ static int aim_countconn(struct aim_session_t *sess) return cnt; } +faim_export int aim_conn_in_sess(struct aim_session_t *sess, struct aim_conn_t *conn) +{ + struct aim_conn_t *cur; + + faim_mutex_lock(&sess->connlistlock); + for(cur = sess->connlist; cur; cur = cur->next) + if(cur == conn) { + faim_mutex_unlock(&sess->connlistlock); + return 1; + } + faim_mutex_unlock(&sess->connlistlock); + return 0; +} + /* * aim_select(timeout) * diff --git a/aim_ft.c b/aim_ft.c index c78862f..f7ccec8 100644 --- a/aim_ft.c +++ b/aim_ft.c @@ -847,7 +847,6 @@ faim_internal int aim_get_command_rendezvous(struct aim_session_t *sess, struct faimdprintf(2, "faim: rend: read error (fd: %i) %02x%02x%02x%02x%02x%02x (%i)\n", conn->fd, hdrbuf1[0],hdrbuf1[1],hdrbuf1[0],hdrbuf1[0],hdrbuf1[0],hdrbuf1[0],hdrlen); faim_mutex_unlock(&conn->active); - aim_conn_close(conn); if(hdrlen < 0) perror("read"); @@ -855,45 +854,55 @@ faim_internal int aim_get_command_rendezvous(struct aim_session_t *sess, struct int i = -1; switch(conn->subtype) { case AIM_CONN_SUBTYPE_OFT_DIRECTIM: { /* XXX: clean up cookies here ? */ - struct aim_directim_priv *priv; - if(!(priv = (struct aim_directim_priv *)conn->priv) ) + struct aim_directim_priv *priv = NULL; + if(!(priv = (struct aim_directim_priv *)conn->priv) ) return -1; /* not much we can do */ + aim_uncachecookie(sess, priv->cookie, AIM_COOKIETYPE_OFTIM); - if ( (userfunc = aim_callhandler(conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMDISCONNECT)) ) - i = userfunc(sess, NULL, conn, priv->sn); - else - aim_conn_kill(sess, &conn); + + if ( (userfunc = aim_callhandler(conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMDISCONNECT)) ) { + aim_conn_close(conn); + return userfunc(sess, NULL, conn, priv->sn); + } - aim_uncachecookie(sess, priv->cookie, AIM_COOKIETYPE_OFTIM); + break; } + case AIM_CONN_SUBTYPE_OFT_GETFILE: { struct aim_filetransfer_priv *priv; if(!(priv = (struct aim_filetransfer_priv *)conn->priv)) return -1; - if ( (userfunc = aim_callhandler(conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEDISCONNECT)) ) - i = userfunc(sess, NULL, conn, priv->sn); - else - aim_conn_kill(sess, &conn); - aim_uncachecookie(sess, priv->cookie, AIM_COOKIETYPE_OFTGET); + + if ( (userfunc = aim_callhandler(conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEDISCONNECT)) ) { + aim_conn_close(conn); + return userfunc(sess, NULL, conn, priv->sn); + } + + break; } + case AIM_CONN_SUBTYPE_OFT_SENDFILE: { struct aim_filetransfer_priv *priv; if(!(priv = (struct aim_filetransfer_priv *)conn->priv)) return -1; - if ( (userfunc = aim_callhandler(conn, AIM_CB_FAM_OFT, AIM_CB_OFT_SENDFILEDISCONNECT)) ) - i = userfunc(sess, NULL, conn, priv->sn); - else - aim_conn_kill(sess, &conn); + aim_uncachecookie(sess, priv->cookie, AIM_COOKIETYPE_OFTSEND); + if ( (userfunc = aim_callhandler(conn, AIM_CB_FAM_OFT, AIM_CB_OFT_SENDFILEDISCONNECT)) ) { + aim_conn_close(conn); + return userfunc(sess, NULL, conn, priv->sn); + } - aim_uncachecookie(sess, priv->cookie, AIM_COOKIETYPE_OFTSEND); + break; } } - return i; + aim_conn_close(conn); + aim_conn_kill(sess, &conn); + + return -1; } } diff --git a/aim_info.c b/aim_info.c index 34d2768..0e6ada2 100644 --- a/aim_info.c +++ b/aim_info.c @@ -320,11 +320,30 @@ faim_internal int aim_extractuserinfo(u_char *buf, struct aim_userinfo_s *outinf * Some decoding of values done by Scott */ case 0x0006: - if (aimutil_get16(buf+i+2) != 0x04) - break; outinfo->icqinfo.status = aimutil_get16(buf+i+2+2+2); break; + + /* + * Type = 0x000a + * + * ICQ User IP Address. + * Ahh, the joy of ICQ security. + */ + case 0x000a: + outinfo->icqinfo.ipaddr = aimutil_get32(&buf[i+4]); + break; + + /* Type = 0x000c + * + * random crap containing the IP address, + * apparently a port number, and some Other Stuff. + * + */ + case 0x000c: + memcpy(outinfo->icqinfo.crap, &buf[i+4], 0x25); + break; + /* * Type = 0x000d * @@ -562,7 +581,7 @@ faim_internal int aim_parse_userinfo_middle(struct aim_session_t *sess, */ faim_internal int aim_putuserinfo(u_char *buf, int buflen, struct aim_userinfo_s *info) { - int i = 0; + int i = 0, numberpos; struct aim_tlvlist_t *tlvlist = NULL; if (!buf || !info) @@ -573,17 +592,30 @@ faim_internal int aim_putuserinfo(u_char *buf, int buflen, struct aim_userinfo_s i += aimutil_put16(buf+i, info->warnlevel); - /* XXX: we only put down five */ - i += aimutil_put16(buf+i, 5); + numberpos = i; + i += aimutil_put16(buf+i, 0); /* fill in for real later */ aim_addtlvtochain16(&tlvlist, 0x0001, info->flags); aim_addtlvtochain32(&tlvlist, 0x0002, info->membersince); aim_addtlvtochain32(&tlvlist, 0x0003, info->onlinesince); aim_addtlvtochain16(&tlvlist, 0x0004, info->idletime); - /* XXX: should put caps here */ + +#if ICQ_OSCAR_SUPPORT + if(atoi(info->sn) != 0) { + aim_addtlvtochain16(&tlvlist, 0x0006, info->icqinfo.status); + aim_addtlvtochain32(&tlvlist, 0x000a, info->icqinfo.ipaddr); + } +#endif + + aim_addtlvtochain_caps(&tlvlist, 0x000d, info->capabilities); + + aim_addtlvtochain32(&tlvlist, 0x000f, info->sessionlen); + aim_addtlvtochain32(&tlvlist, (unsigned short)((info->flags)&AIM_FLAG_AOL?0x0010:0x000f), info->sessionlen); - + i += aim_writetlvchain(buf+i, buflen-i, &tlvlist); aim_freetlvchain(&tlvlist); + + aimutil_put16(buf+numberpos, aim_counttlvchain(&tlvlist)); return i; } diff --git a/aim_tlv.c b/aim_tlv.c index ba5b1cb..3557d5a 100644 --- a/aim_tlv.c +++ b/aim_tlv.c @@ -95,6 +95,21 @@ faim_internal int aim_counttlvchain(struct aim_tlvlist_t **list) return count; } +faim_export int aim_sizetlvchain(struct aim_tlvlist_t **list) +{ + struct aim_tlvlist_t *cur; + int size = 0; + + if (!list || !(*list)) + return 0; + + for (cur = *list; cur; cur = cur->next) + size += (4 + cur->tlv->length); + + return size; +} + + faim_internal int aim_addtlvtochain_str(struct aim_tlvlist_t **list, unsigned short type, char *str, int len) { struct aim_tlvlist_t *newtlv; @@ -188,6 +203,36 @@ faim_internal int aim_addtlvtochain32(struct aim_tlvlist_t **list, unsigned shor return 4; } +faim_internal int aim_addtlvtochain_caps(struct aim_tlvlist_t **list, unsigned short type, unsigned short caps) +{ + unsigned char buf[128]; /* icky fixed length buffer */ + struct aim_tlvlist_t *newtl; + struct aim_tlvlist_t *cur; + + if(!list) + return 0; + + newtl->tlv = aim_createtlv(); + newtl->tlv->type = type; + + newtl->tlv->length = aim_putcap(buf, 128, caps); + newtl->tlv->value = (unsigned char *)calloc(1, newtl->tlv->length); + memcpy(newtl->tlv->value, &buf, newtl->tlv->length); + + newtl->next = NULL; + + if (*list == NULL) { + *list = newtl; + } else if ((*list)->next == NULL) { + (*list)->next = newtl; + } else { + for(cur = *list; cur->next; cur = cur->next) + ; + cur->next = newtl; + } + return newtl->tlv->length; +} + faim_internal int aim_writetlvchain(u_char *buf, int buflen, struct aim_tlvlist_t **list) { int goodbuflen = 0; diff --git a/faim/aim.h b/faim/aim.h index 5f89fe1..4f44b02 100644 --- a/faim/aim.h +++ b/faim/aim.h @@ -368,6 +368,8 @@ struct aim_userinfo_s { u_short capabilities; struct { unsigned short status; + unsigned int ipaddr; + char crap[0x25]; /* until we figure it out... */ } icqinfo; }; @@ -416,6 +418,7 @@ faim_internal int aim_writetlvchain(u_char *buf, int buflen, struct aim_tlvlist_ faim_internal int aim_addtlvtochain16(struct aim_tlvlist_t **list, unsigned short type, unsigned short val); faim_internal int aim_addtlvtochain32(struct aim_tlvlist_t **list, unsigned short type, unsigned long val); faim_internal int aim_addtlvtochain_str(struct aim_tlvlist_t **list, unsigned short type, char *str, int len); +faim_internal int aim_addtlvtochain_caps(struct aim_tlvlist_t **list, unsigned short type, unsigned short caps); faim_internal int aim_counttlvchain(struct aim_tlvlist_t **list); /* diff --git a/utils/faimtest/faimtest.c b/utils/faimtest/faimtest.c index 12ca994..c1013f4 100644 --- a/utils/faimtest/faimtest.c +++ b/utils/faimtest/faimtest.c @@ -256,7 +256,12 @@ int main(void) aim_rxdispatch(&aimsess); } else { printf("connection error (type 0x%04x:0x%04x)\n", waitingconn->type, waitingconn->subtype); - aim_conn_kill(&aimsess, &waitingconn); + if(waitingconn->type == AIM_CONN_TYPE_RENDEZVOUS) { + /* we should have callbacks for all these, else the library will do the conn_kill for us. */ + printf("connection error: rendezvous connection. you forgot register a disconnect callback, right?\n"); + } + else + aim_conn_kill(&aimsess, &waitingconn); if (!aim_getconn_type(&aimsess, AIM_CONN_TYPE_BOS)) { printf("major connection error\n"); keepgoing = 0; @@ -721,7 +726,6 @@ int faimtest_parse_incoming_im(struct aim_session_t *sess, struct command_rx_str } else if (!strncmp(tmpstr, "open directim", 13)) { struct aim_conn_t *newconn; newconn = aim_directim_initiate(sess, command->conn, NULL, userinfo->sn); - //aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINITIATE, faimtest_directim_initiate, 0); } else if (!strncmp(tmpstr, "reqsendmsg", 10)) { aim_send_im(sess, command->conn, "vaxherder", 0, "sendmsg 7900"); } else if (!strncmp(tmpstr, "sendmsg", 7)) { @@ -858,10 +862,10 @@ int faimtest_parse_incoming_im(struct aim_session_t *sess, struct command_rx_str aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMDISCONNECT, faimtest_directim_disconnect, 0); aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING, faimtest_directim_typing, 0); - aim_send_im_direct(sess, newconn, "goodday"); - printf("faimtest: OFT: DirectIM: connected to %s\n", userinfo->sn); + aim_send_im_direct(sess, newconn, "goodday"); + break; } default: @@ -963,9 +967,9 @@ int faimtest_directim_disconnect(struct aim_session_t *sess, struct command_rx_s sn = va_arg(ap, char *); va_end(ap); - aim_conn_kill(sess, &conn); - printf("faimtest: directim: disconnected from %s\n", sn); + + aim_conn_kill(sess, &conn); return 1; } -- 2.45.2