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)
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)
*
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");
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;
}
}
* Some decoding of values done by Scott <darkagl@pcnet.com>
*/
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
*
*/
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)
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;
}
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;
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;
u_short capabilities;
struct {
unsigned short status;
+ unsigned int ipaddr;
+ char crap[0x25]; /* until we figure it out... */
} icqinfo;
};
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);
/*
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;
} 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)) {
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:
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;
}