*/
-#include "aim.h" /* for most everything */
+#include <faim/aim.h>
-u_long aim_getinfo(struct aim_conn_t *conn, const char *sn)
+u_long aim_getinfo(struct aim_session_t *sess,
+ struct aim_conn_t *conn,
+ const char *sn)
{
struct command_tx_struct newpacket;
+ int i = 0;
+
+ if (!sess || !conn || !sn)
+ return 0;
if (conn)
newpacket.conn = conn;
else
- newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS);
+ newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
newpacket.lock = 1;
newpacket.type = 0x0002;
newpacket.commandlen = 12 + 1 + strlen(sn);
newpacket.data = (char *) malloc(newpacket.commandlen);
- aim_putsnac(newpacket.data, 0x0002, 0x0005, 0x0000, aim_snac_nextid);
+ i = aim_putsnac(newpacket.data, 0x0002, 0x0005, 0x0000, sess->snac_nextid);
- aimutil_put16(newpacket.data+10, 0x0001);
- aimutil_put8(newpacket.data+12, strlen(sn));
- aimutil_putstr(newpacket.data+13, sn, strlen(sn));
+ i += aimutil_put16(newpacket.data+i, 0x0001);
+ i += aimutil_put8(newpacket.data+i, strlen(sn));
+ i += aimutil_putstr(newpacket.data+i, sn, strlen(sn));
- aim_tx_enqueue(&newpacket);
+ newpacket.lock = 0;
+ aim_tx_enqueue(sess, &newpacket);
{
struct aim_snac_t snac;
- snac.id = aim_snac_nextid;
+ snac.id = sess->snac_nextid;
snac.family = 0x0002;
snac.type = 0x0005;
snac.flags = 0x0000;
snac.data = malloc(strlen(sn)+1);
- memcpy(snac.data, sn, strlen(sn)+1);
+ strcpy(snac.data, sn);
- aim_newsnac(&snac);
+ aim_newsnac(sess, &snac);
}
- return (aim_snac_nextid++);
+ return (sess->snac_nextid++);
}
/*
* 0x0004 AOL Main Service user
* 0x0008 Unknown bit 4
* 0x0010 Free (AIM) user
+ * 0x0020 Away
*
* In some odd cases, we can end up with more
* than one of these. We only want the first,
case 0x0004:
outinfo->idletime = aimutil_get16(&buf[i+4]);
break;
+
+ /*
+ * Type = 0x000d
+ *
+ * Capability information. Not real sure of
+ * actual decoding. See comment on aim_bos_setprofile()
+ * in aim_misc.c about the capability block, its the same.
+ *
+ * Ignore.
+ *
+ */
+ case 0x000d:
+ break;
+
+ /*
+ * Type = 0x000e
+ *
+ * Unknown. Always of zero length, and always only
+ * on AOL users.
+ *
+ * Ignore.
+ *
+ */
+ case 0x000e:
+ break;
/*
* Type = 0x000f: Session Length. (AIM)
* through aim_extractuserinfo() however.
*
*/
-int aim_parse_oncoming_middle(struct command_rx_struct *command)
+int aim_parse_oncoming_middle(struct aim_session_t *sess,
+ struct command_rx_struct *command)
{
struct aim_userinfo_s userinfo;
u_int i = 0;
userfunc = aim_callhandler(command->conn, AIM_CB_FAM_BUD, AIM_CB_BUD_ONCOMING);
if (userfunc)
- i = userfunc(command, &userinfo);
+ i = userfunc(sess, command, &userinfo);
return 1;
}
+/*
+ * Offgoing Buddy notifications contain no useful
+ * information other than the name it applies to.
+ *
+ */
+int aim_parse_offgoing_middle(struct aim_session_t *sess,
+ struct command_rx_struct *command)
+{
+ char sn[MAXSNLEN+1];
+ u_int i = 0;
+ rxcallback_t userfunc=NULL;
+
+ /* Protect against future SN length extensions */
+ strncpy(sn, command->data+11, (((int)(command->data+10))<=MAXSNLEN)?(int)command->data+10:MAXSNLEN);
+
+ userfunc = aim_callhandler(command->conn, AIM_CB_FAM_BUD, AIM_CB_BUD_OFFGOING);
+ if (userfunc)
+ i = userfunc(sess, command, sn);
+
+ return 1;
+}
/*
* This parses the user info stuff out all nice and pretty then calls
* the higher-level callback (in the user app).
*
*/
-int aim_parse_userinfo_middle(struct command_rx_struct *command)
+int aim_parse_userinfo_middle(struct aim_session_t *sess,
+ struct command_rx_struct *command)
{
struct aim_userinfo_s userinfo;
char *prof_encoding = NULL;
char *prof = NULL;
u_int i = 0;
rxcallback_t userfunc=NULL;
+ struct aim_tlvlist_t *tlvlist;
{
u_long snacid = 0x000000000;
struct aim_snac_t *snac = NULL;
snacid = aimutil_get32(&command->data[6]);
- snac = aim_remsnac(snacid);
-
- free(snac->data);
- free(snac);
+ snac = aim_remsnac(sess, snacid);
+
+ if (snac)
+ {
+ if (snac->data)
+ free(snac->data);
+ else
+ printf("faim: parse_userinfo_middle: warning: no ->data in cached SNAC\n");
+ free(snac);
+ }
+ else
+ printf("faim: parseuserinfo_middle: warning: no SNAC cached with for this response (%08lx)\n", snacid);
}
i = 10;
- i += aim_extractuserinfo(command->data+i, &userinfo);
-
- if (i < command->commandlen)
- {
- if (aimutil_get16(&command->data[i]) == 0x0001)
- {
- int len = 0;
-
- len = aimutil_get16(&command->data[i+2]);
-
- prof_encoding = (char *) malloc(len+1);
- memcpy(prof_encoding, &(command->data[i+4]), len);
- prof_encoding[len] = '\0';
-
- i += (2+2+len);
- }
- else
- {
- printf("faim: userinfo: **warning: unexpected TLV after TLVblock t(%02x%02x) l(%02x%02x)\n", command->data[i], command->data[i+1], command->data[i+2], command->data[i+3]);
- i += 2 + 2 + command->data[i+3];
- }
- }
- if (i < command->commandlen)
- {
- if (aimutil_get16(&command->data[i]) == 0x0002)
- {
- int len = 0;
- len = aimutil_get16(&command->data[i+2]);
-
- prof = (char *) malloc(len+1);
- memcpy(prof, &(command->data[i+4]), len);
- prof[len] = '\0';
- }
- else
- printf("faim:userinfo: **warning: profile not found, but still have data\n");
- }
+ /*
+ * extractuserinfo will give us the basic metaTLV information
+ */
+ i += aim_extractuserinfo(command->data+i, &userinfo);
+
+ /*
+ * However, in this command, there's usually more TLVs following...
+ */
+ tlvlist = aim_readtlvchain(command->data+i, command->commandlen-i);
+ prof_encoding = aim_gettlv_str(tlvlist, 0x0001, 1);
+ prof = aim_gettlv_str(tlvlist, 0x0002, 1);
userfunc = aim_callhandler(command->conn, AIM_CB_FAM_LOC, AIM_CB_LOC_USERINFO);
if (userfunc)
{
- i = userfunc(command,
+ i = userfunc(sess,
+ command,
&userinfo,
prof_encoding,
prof);
}
-
+
free(prof_encoding);
free(prof);
+ aim_freetlvchain(&tlvlist);
return 1;
}