No release numbers
------------------
+ - Wed Dec 29 09:14:45 UTC 1999
+ - Added a capability block to aim_bos_setprofile. Can now get chat invites again.
+ - Extended ICBM parser to support channel 2 messages (chat invites)
+ - A channel parameter has been prepended to the varargs -- REQUIRES CLIENT CHANGES.
+ - Extended faimtest to support chat invites.
+ - Changed faimtest to get sn/password from environment
+
- Wed Dec 29 04:17:03 UTC 1999
- Added -g to CFLAGS
- Added aim_sendconnack() to aim_login.c (needed for newer login)
- Fiddled with version information. Added aim_setversions()
- Added table of SNAC names for showing unknown snacs (jbm)
- Added a middle handler for MOTD
- - Added new authorization SNACs to faim/aim_cbtypes.h
-
+ - Added new authorization SNACs to faim/aim_cbtypes.h
+
- Sun Dec 26 22:59:10 UTC 1999
- Renamed login_phase1_struct to aim_login_struct
- Changed cookie and sn to be static arrays in aim_login_struct
int aim_parse_incoming_im_middle(struct aim_session_t *sess,
struct command_rx_struct *command)
{
- struct aim_userinfo_s userinfo;
- u_int i = 0, j = 0, y = 0, z = 0;
- char *msg = NULL;
- u_int icbmflags = 0;
+ u_int i = 0,z;
rxcallback_t userfunc = NULL;
u_char cookie[8];
int channel;
struct aim_tlvlist_t *tlvlist;
- struct aim_tlv_t *msgblocktlv, *tmptlv;
- u_char *msgblock;
+ struct aim_userinfo_s userinfo;
u_short wastebits;
- u_short flag1,flag2;
- memset(&userinfo, 0x00, sizeof(struct aim_userinfo_s));
-
i = 10; /* Skip SNAC header */
/*
* Channel 0x0001 is the message channel. There are
* other channels for things called "rendevous"
* which represent chat and some of the other new
- * features of AIM2/3/3.5. We only support
- * standard messages; those on channel 0x0001.
+ * features of AIM2/3/3.5.
+ *
+ * Channel 0x0002 is the Rendevous channel, which
+ * is where Chat Invitiations come from.
+ *
*/
channel = aimutil_get16(command->data+i);
i += 2;
- if (channel != 0x0001)
+
+ /*
+ *
+ */
+ if ((channel != 0x01) && (channel != 0x02))
{
printf("faim: icbm: ICBM received on an unsupported channel. Ignoring.\n (chan = %04x)", channel);
return 1;
memcpy(userinfo.sn, command->data+i+1, (int)command->data[i]);
userinfo.sn[(int)command->data[i]] = '\0';
i += 1 + (int)command->data[i];
-
+
/*
- * Unknown bits.
+ * Warning Level
*/
- wastebits = aimutil_get16(command->data+i);
+ userinfo.warnlevel = aimutil_get16(command->data+i); /* guess */
i += 2;
+
+ /*
+ * Number of TLVs that follow. Not needed.
+ */
wastebits = aimutil_get16(command->data+i);
i += 2;
-
+
/*
* Read block of TLVs. All further data is derived
* from what is parsed here.
tlvlist = aim_readtlvchain(command->data+i, command->commandlen-i);
/*
- * Check Autoresponse status. If it is an autoresponse,
- * it will contain a second type 0x0004 TLV, with zero length.
- */
- if (aim_gettlv(tlvlist, 0x0004, 2))
- icbmflags |= AIM_IMFLAGS_AWAY;
-
- /*
- * Check Ack Request status.
- */
- if (aim_gettlv(tlvlist, 0x0003, 2))
- icbmflags |= AIM_IMFLAGS_ACK;
-
- /*
- * Extract the various pieces of the userinfo struct.
+ * From here on, its depends on what channel we're on.
*/
- /* Class. */
- if ((tmptlv = aim_gettlv(tlvlist, 0x0001, 1)))
- userinfo.class = aimutil_get16(tmptlv->value);
- /* Member-since date. */
- if ((tmptlv = aim_gettlv(tlvlist, 0x0002, 1)))
+ if (channel == 1)
{
- /* If this is larger than 4, its probably the message block, skip */
- if (tmptlv->length <= 4)
- userinfo.membersince = aimutil_get32(tmptlv->value);
+ u_int j = 0, y = 0, z = 0;
+ char *msg = NULL;
+ u_int icbmflags = 0;
+ struct aim_tlv_t *msgblocktlv, *tmptlv;
+ u_char *msgblock;
+ u_short flag1,flag2;
+
+ memset(&userinfo, 0x00, sizeof(struct aim_userinfo_s));
+
+ /*
+ * Check Autoresponse status. If it is an autoresponse,
+ * it will contain a second type 0x0004 TLV, with zero length.
+ */
+ if (aim_gettlv(tlvlist, 0x0004, 2))
+ icbmflags |= AIM_IMFLAGS_AWAY;
+
+ /*
+ * Check Ack Request status.
+ */
+ if (aim_gettlv(tlvlist, 0x0003, 2))
+ icbmflags |= AIM_IMFLAGS_ACK;
+
+ /*
+ * Extract the various pieces of the userinfo struct.
+ */
+ /* Class. */
+ if ((tmptlv = aim_gettlv(tlvlist, 0x0001, 1)))
+ userinfo.class = aimutil_get16(tmptlv->value);
+ /* Member-since date. */
+ if ((tmptlv = aim_gettlv(tlvlist, 0x0002, 1)))
+ {
+ /* If this is larger than 4, its probably the message block, skip */
+ if (tmptlv->length <= 4)
+ userinfo.membersince = aimutil_get32(tmptlv->value);
+ }
+ /* On-since date */
+ if ((tmptlv = aim_gettlv(tlvlist, 0x0003, 1)))
+ userinfo.onlinesince = aimutil_get32(tmptlv->value);
+ /* Idle-time */
+ if ((tmptlv = aim_gettlv(tlvlist, 0x0004, 1)))
+ userinfo.idletime = aimutil_get16(tmptlv->value);
+ /* Session Length (AIM) */
+ if ((tmptlv = aim_gettlv(tlvlist, 0x000f, 1)))
+ userinfo.sessionlen = aimutil_get16(tmptlv->value);
+ /* Session Length (AOL) */
+ if ((tmptlv = aim_gettlv(tlvlist, 0x0010, 1)))
+ userinfo.sessionlen = aimutil_get16(tmptlv->value);
+
+ /*
+ * Message block.
+ *
+ * XXX: Will the msgblock always be the second 0x0002?
+ */
+ msgblocktlv = aim_gettlv(tlvlist, 0x0002, 1);
+ if (!msgblocktlv)
+ {
+ printf("faim: icbm: major error! no message block TLV found!\n");
+ aim_freetlvchain(&tlvlist);
+ }
+
+ /*
+ * Extracting the message from the unknown cruft.
+ *
+ * This is a bit messy, and I'm not really qualified,
+ * even as the author, to comment on it. At least
+ * its not as bad as a while loop shooting into infinity.
+ *
+ * "Do you believe in magic?"
+ *
+ */
+ msgblock = msgblocktlv->value;
+ j = 0;
+
+ wastebits = aimutil_get8(msgblock+j++);
+ wastebits = aimutil_get8(msgblock+j++);
+
+ y = aimutil_get16(msgblock+j);
+ j += 2;
+ for (z = 0; z < y; z++)
+ wastebits = aimutil_get8(msgblock+j++);
+ wastebits = aimutil_get8(msgblock+j++);
+ wastebits = aimutil_get8(msgblock+j++);
+
+ /*
+ * Message string length, including flag words.
+ */
+ i = aimutil_get16(msgblock+j);
+ j += 2;
+
+ /*
+ * Flag words.
+ *
+ * Its rumored that these can kick in some funky
+ * 16bit-wide char stuff that used to really kill
+ * libfaim. Hopefully the latter is no longer true.
+ *
+ * Though someone should investiagte the former.
+ *
+ */
+ flag1 = aimutil_get16(msgblock+j);
+ j += 2;
+ flag2 = aimutil_get16(msgblock+j);
+ j += 2;
+
+ if (flag1 || flag2)
+ printf("faim: icbm: **warning: encoding flags are being used! {%04x, %04x}\n", flag1, flag2);
+
+ /*
+ * Message string.
+ */
+ i -= 4;
+ msg = (char *)malloc(i+1);
+ memcpy(msg, msgblock+j, i);
+ msg[i] = '\0';
+
+ /*
+ * Call client.
+ */
+ userfunc = aim_callhandler(command->conn, 0x0004, 0x0007);
+ if (userfunc)
+ i = userfunc(sess, command, channel, &userinfo, msg, icbmflags, flag1, flag2);
+ else
+ i = 0;
+
+ free(msg);
}
- /* On-since date */
- if ((tmptlv = aim_gettlv(tlvlist, 0x0003, 1)))
- userinfo.onlinesince = aimutil_get32(tmptlv->value);
- /* Idle-time */
- if ((tmptlv = aim_gettlv(tlvlist, 0x0004, 1)))
- userinfo.idletime = aimutil_get16(tmptlv->value);
- /* Session Length (AIM) */
- if ((tmptlv = aim_gettlv(tlvlist, 0x000f, 1)))
- userinfo.sessionlen = aimutil_get16(tmptlv->value);
- /* Session Length (AOL) */
- if ((tmptlv = aim_gettlv(tlvlist, 0x0010, 1)))
- userinfo.sessionlen = aimutil_get16(tmptlv->value);
-
- /*
- * Message block.
- *
- * XXX: Will the msgblock always be the second 0x0002?
- */
- msgblocktlv = aim_gettlv(tlvlist, 0x0002, 1);
- if (!msgblocktlv)
+ else if (channel == 0x0002)
{
- printf("faim: icbm: major error! no message block TLV found!\n");
- aim_freetlvchain(&tlvlist);
- }
-
- /*
- * Extracting the message from the unknown cruft.
- *
- * This is a bit messy, and I'm not really qualified,
- * even as the author, to comment on it. At least
- * its not as bad as a while loop shooting into infinity.
- *
- * "Do you believe in magic?"
- *
- */
- msgblock = msgblocktlv->value;
- j = 0;
-
- wastebits = aimutil_get8(msgblock+j++);
- wastebits = aimutil_get8(msgblock+j++);
-
- y = aimutil_get16(msgblock+j);
- j += 2;
- for (z = 0; z < y; z++)
- wastebits = aimutil_get8(msgblock+j++);
- wastebits = aimutil_get8(msgblock+j++);
- wastebits = aimutil_get8(msgblock+j++);
+ struct aim_tlv_t *block1;
+ struct aim_tlvlist_t *list2;
+ struct aim_tlv_t *tmptlv;
+ int a;
+ u_short exchange,instance;
+ char *roomname,*msg,*encoding,*lang;
+
+ /* Class. */
+ if ((tmptlv = aim_gettlv(tlvlist, 0x0001, 1)))
+ userinfo.class = aimutil_get16(tmptlv->value);
+ /* On-since date */
+ if ((tmptlv = aim_gettlv(tlvlist, 0x0003, 1)))
+ userinfo.onlinesince = aimutil_get32(tmptlv->value);
+ /* Idle-time */
+ if ((tmptlv = aim_gettlv(tlvlist, 0x0004, 1)))
+ userinfo.idletime = aimutil_get16(tmptlv->value);
+ /* Session Length (AIM) */
+ if ((tmptlv = aim_gettlv(tlvlist, 0x000f, 1)))
+ userinfo.sessionlen = aimutil_get16(tmptlv->value);
+ /* Session Length (AOL) */
+ if ((tmptlv = aim_gettlv(tlvlist, 0x0010, 1)))
+ userinfo.sessionlen = aimutil_get16(tmptlv->value);
+
+ /*
+ * There's another block of TLVs embedded in the type 5 here.
+ */
+ block1 = aim_gettlv(tlvlist, 0x0005, 1);
+ if (!block1)
+ return 1; /* major problem */
+
+ a = 0x1a; /* skip -- not sure what this information is! */
+
+ list2 = aim_readtlvchain(block1->value+a, block1->length-a);
+ if (aim_gettlv(list2, 0x2711, 1))
+ {
+ struct aim_tlv_t *name;
+ int len;
+
+ name = aim_gettlv(list2, 0x2711, 1);
+
+ exchange = aimutil_get16(name->value+0);
+
+ len = aimutil_get16(name->value+2);
+ roomname = (char *)malloc(len+1);
+ memcpy(roomname, name->value+3, len);
+ roomname[len] = '\0';
+
+ instance = aimutil_get16(name->value+3+len);
+ }
+
+ if (aim_gettlv(list2, 0x000c, 1))
+ msg = aim_gettlv_str(list2, 0x000c, 1);
+
+ if (aim_gettlv(list2, 0x000d, 1))
+ encoding = aim_gettlv_str(list2, 0x000d, 1);
- /*
- * Message string length, including flag words.
- */
- i = aimutil_get16(msgblock+j);
- j += 2;
-
- /*
- * Flag words.
- *
- * Its rumored that these can kick in some funky
- * 16bit-wide char stuff that used to really kill
- * libfaim. Hopefully the latter is no longer true.
- *
- * Though someone should investiagte the former.
- *
- */
- flag1 = aimutil_get16(msgblock+j);
- j += 2;
- flag2 = aimutil_get16(msgblock+j);
- j += 2;
-
- if (flag1 || flag2)
- printf("faim: icbm: **warning: encoding flags are being used! {%04x, %04x}\n", flag1, flag2);
-
- /*
- * Message string.
- */
- i -= 4;
- msg = (char *)malloc(i+1);
- memcpy(msg, msgblock+j, i);
- msg[i] = '\0';
+ if (aim_gettlv(list2, 0x000e, 1))
+ lang = aim_gettlv_str(list2, 0x000e, 1);
+
+ /*
+ * Call client.
+ */
+ userfunc = aim_callhandler(command->conn, 0x0004, 0x0007);
+ if (userfunc)
+ i = userfunc(sess, command, channel, &userinfo, roomname, msg, encoding+1, lang+1, exchange, instance);
+ else
+ i = 0;
+
+ free(roomname);
+ free(msg);
+ free(encoding);
+ free(lang);
+ aim_freetlvchain(&list2);
+ }
/*
* Free up the TLV chain.
*/
aim_freetlvchain(&tlvlist);
+
- /*
- * Call client.
- */
- userfunc = aim_callhandler(command->conn, 0x0004, 0x0007);
- if (userfunc)
- i = userfunc(sess, command, &userinfo, msg, icbmflags, flag1, flag2);
- else
- i = 0;
-
- free(msg);
-
- return 1;
+ return i;
}
/*
*
* Gives BOS your profile.
*
+ *
+ * The large data chunk given here is of unknown decoding.
+ * What I do know is that each 0x20 byte repetition
+ * represents a capability. People with only the
+ * first two reptitions can support normal messaging
+ * and chat (client version 2.0 or 3.0). People with
+ * the third as well can also support voice chat (client
+ * version 3.5 or higher). IOW, if we don't send this,
+ * we won't get chat invitations (get "software doesn't
+ * support chat" error).
+ *
+ * This data is broadcast along with your oncoming
+ * buddy command to everyone who has you on their
+ * buddy list, as a type 0x0002 TLV.
+ *
*/
u_long aim_bos_setprofile(struct aim_session_t *sess,
struct aim_conn_t *conn,
char *profile)
{
- int packet_profile_len = 0;
struct command_tx_struct newpacket;
int i = 0;
-
- /* len: SNAC */
- packet_profile_len = 10;
- /* len: T+L (where t(0001)) */
- packet_profile_len += 2 + 2;
- /* len: V (where t(0001)) */
- packet_profile_len += strlen("text/x-aolrtf");
- /* len: T+L (where t(0002)) */
- packet_profile_len += 2 + 2;
- /* len: V (where t(0002)) */
- packet_profile_len += strlen(profile);
+ u_char funkydata[] = {
+ 0x09, 0x46, 0x13, 0x46, 0x4c, 0x7f, 0x11, 0xd1,
+ 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00,
+ 0x09, 0x46, 0x13, 0x41, 0x4c, 0x7f, 0x11, 0xd1,
+ 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00,
+
+ 0x09, 0x46, 0x13, 0x45, 0x4c, 0x7f, 0x11, 0xd1,
+ 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00,
+ 0x74, 0x8f, 0x24, 0x20, 0x62, 0x87, 0x11, 0xd1,
+ 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00,
+
+ 0x09, 0x46, 0x13, 0x48, 0x4c, 0x7f, 0x11, 0xd1,
+ 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00,
+ 0x09, 0x46, 0x13, 0x43, 0x4c, 0x7f, 0x11, 0xd1,
+ 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00
+ };
newpacket.type = 0x02;
if (conn)
else
newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
- newpacket.commandlen = packet_profile_len;
- newpacket.data = (char *) malloc(packet_profile_len);
-
- i = 0;
+ newpacket.commandlen = 1152+strlen(profile)+1; /*arbitrarily large */
+ newpacket.data = (char *) malloc(newpacket.commandlen);
i += aim_putsnac(newpacket.data, 0x0002, 0x004, 0x0000, sess->snac_nextid);
-
- /* TLV t(0001) */
- newpacket.data[i++] = 0x00;
- newpacket.data[i++] = 0x01;
- /* TLV l(000d) */
- newpacket.data[i++] = 0x00;
- newpacket.data[i++] = 0x0d;
- /* TLV v(text/x-aolrtf) */
- memcpy(&(newpacket.data[i]), "text/x-aolrtf", 0x000d);
- i += 0x000d;
+ i += aim_puttlv_str(newpacket.data+i, 0x0001, strlen("text/x-aolrtf; charset=\"us-ascii\""), "text/x-aolrtf; charset=\"us-ascii\"");
+ i += aim_puttlv_str(newpacket.data+i, 0x0002, strlen(profile), profile);
+ /* why do we send this twice? */
+ i += aim_puttlv_str(newpacket.data+i, 0x0003, strlen("text/x-aolrtf; charset=\"us-ascii\""), "text/x-aolrtf; charset=\"us-ascii\"");
- /* TLV t(0002) */
- newpacket.data[i++] = 0x00;
- newpacket.data[i++] = 0x02;
- /* TLV l() */
- newpacket.data[i++] = (strlen(profile) >> 8) & 0xFF;
- newpacket.data[i++] = (strlen(profile) & 0xFF);
- /* TLV v(profile) */
- memcpy(&(newpacket.data[i]), profile, strlen(profile));
+ /* a blank TLV 0x0004 --- not sure what this is either */
+ i += aimutil_put16(newpacket.data+i, 0x0004);
+ i += aimutil_put16(newpacket.data+i, 0x0000);
+ /* Capability information. */
+ i += aim_puttlv_str(newpacket.data+i, 0x0005, 0x0060, funkydata);
+
+ newpacket.commandlen = i;
aim_tx_enqueue(sess, &newpacket);
return (sess->snac_nextid++);
else
newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
newpacket.type = 0x02;
- newpacket.commandlen = 10 + (4*13);
+ newpacket.commandlen = 10 + (4*11);
newpacket.data = (char *) malloc(newpacket.commandlen);
i = aim_putsnac(newpacket.data, 0x0001, 0x0017, 0x0000, sess->snac_nextid);
i += aimutil_put16(newpacket.data+i, 0x0001);
i += aimutil_put16(newpacket.data+i, 0x0003);
+
i += aimutil_put16(newpacket.data+i, 0x0002);
i += aimutil_put16(newpacket.data+i, 0x0001);
+
i += aimutil_put16(newpacket.data+i, 0x0003);
i += aimutil_put16(newpacket.data+i, 0x0001);
+
i += aimutil_put16(newpacket.data+i, 0x0004);
i += aimutil_put16(newpacket.data+i, 0x0001);
+
i += aimutil_put16(newpacket.data+i, 0x0006);
i += aimutil_put16(newpacket.data+i, 0x0001);
+
i += aimutil_put16(newpacket.data+i, 0x0008);
i += aimutil_put16(newpacket.data+i, 0x0001);
+
i += aimutil_put16(newpacket.data+i, 0x0009);
i += aimutil_put16(newpacket.data+i, 0x0001);
+
i += aimutil_put16(newpacket.data+i, 0x000a);
i += aimutil_put16(newpacket.data+i, 0x0001);
+
i += aimutil_put16(newpacket.data+i, 0x000b);
i += aimutil_put16(newpacket.data+i, 0x0002);
+
i += aimutil_put16(newpacket.data+i, 0x000c);
i += aimutil_put16(newpacket.data+i, 0x0001);
+
i += aimutil_put16(newpacket.data+i, 0x0015);
- i += aimutil_put16(newpacket.data+i, 0x0003);
- i += aimutil_put16(newpacket.data+i, 0x000f);
- i += aimutil_put16(newpacket.data+i, 0x0001);
- i += aimutil_put16(newpacket.data+i, 0x0005);
i += aimutil_put16(newpacket.data+i, 0x0001);
#if 0
*/
-#define FAIMTEST_SCREENNAME "SCREENNAME"
-#define FAIMTEST_PASSWORD "PASSWORD"
-
#include <faim/aim.h>
int faimtest_parse_oncoming(struct aim_session_t *, struct command_rx_struct *, ...);
int faimtest_parse_motd(struct aim_session_t *, struct command_rx_struct *command, ...);
int faimtest_parse_login(struct aim_session_t *, struct command_rx_struct *command, ...);
+static char *screenname,*password;
+
int main(void)
{
struct aim_session_t aimsess;
aim_session_init(&aimsess);
+ if ( !(screenname = getenv("SCREENNAME")) ||
+ !(password = getenv("PASSWORD")))
+ {
+ printf("Must specify SCREENAME and PASSWORD in environment.\n");
+ return -1;
+ }
+
/*
* (I used a goto-based loop here because n wanted quick proof
* that reconnecting without restarting was actually possible...)
#else
aim_conn_addhandler(&aimsess, authconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_AUTHSUCCESS, faimtest_parse_authresp, 0);
aim_conn_addhandler(&aimsess, authconn, AIM_CB_FAM_GEN, AIM_CB_GEN_SERVERREADY, faimtest_authsvrready, 0);
- aim_send_login(&aimsess, authconn, FAIMTEST_SCREENNAME, FAIMTEST_PASSWORD, &info);
+ aim_send_login(&aimsess, authconn, screenname, password, &info);
#endif
}
switch (command->conn->type)
{
case AIM_CONN_TYPE_BOS:
+
aim_bos_reqrate(sess, command->conn); /* request rate info */
aim_bos_ackrateresp(sess, command->conn); /* ack rate info response -- can we say timing? */
aim_bos_setprivacyflags(sess, command->conn, 0x00000003);
*/
int faimtest_parse_incoming_im(struct aim_session_t *sess, struct command_rx_struct *command, ...)
{
- struct aim_userinfo_s *userinfo;
- char *msg = NULL;
- u_int icbmflags = 0;
+ int channel;
va_list ap;
- char *tmpstr = NULL;
- u_short flag1, flag2;
va_start(ap, command);
- userinfo = va_arg(ap, struct aim_userinfo_s *);
- msg = va_arg(ap, char *);
- icbmflags = va_arg(ap, u_int);
- flag1 = va_arg(ap, u_short);
- flag2 = va_arg(ap, u_short);
- va_end(ap);
+ channel = va_arg(ap, int);
- printf("faimtest: icbm: sn = \"%s\"\n", userinfo->sn);
- printf("faimtest: icbm: warnlevel = 0x%04x\n", userinfo->warnlevel);
- printf("faimtest: icbm: class = 0x%04x ", userinfo->class);
- if (userinfo->class & 0x0010)
- printf("(FREE)\n");
- else if (userinfo->class & 0x0001)
- printf("(TRIAL)\n");
- else if (userinfo->class & 0x0004)
- printf("(AOL)\n");
- else
- printf("(UNKNOWN)\n");
- printf("faimtest: icbm: membersince = %lu\n", userinfo->membersince);
- printf("faimtest: icbm: onlinesince = %lu\n", userinfo->onlinesince);
- printf("faimtest: icbm: idletime = 0x%04x\n", userinfo->idletime);
-
- printf("faimtest: icbm: icbmflags = ");
- if (icbmflags & AIM_IMFLAGS_AWAY)
- printf("away ");
- if (icbmflags & AIM_IMFLAGS_ACK)
- printf("ackrequest ");
- printf("\n");
-
- printf("faimtest: icbm: encoding flags = {%04x, %04x}\n", flag1, flag2);
-
- printf("faimtest: icbm: message: %s\n", msg);
-
- if (msg)
+ /*
+ * Channel 1: Standard Message
+ */
+ if (channel == 1)
{
- tmpstr = index(msg, '>');
- if (tmpstr != NULL)
- tmpstr+=1;
- else
- tmpstr = msg;
+ struct aim_userinfo_s *userinfo;
+ char *msg = NULL;
+ u_int icbmflags = 0;
+ char *tmpstr = NULL;
+ u_short flag1, flag2;
+
+ userinfo = va_arg(ap, struct aim_userinfo_s *);
+ msg = va_arg(ap, char *);
+ icbmflags = va_arg(ap, u_int);
+ flag1 = va_arg(ap, u_short);
+ flag2 = va_arg(ap, u_short);
+ va_end(ap);
- if ( (strlen(tmpstr) >= 10) &&
- (!strncmp(tmpstr, "disconnect", 10)) )
- {
- aim_send_im(sess, command->conn, "midendian", 0, "ta ta...");
- aim_logoff(sess);
- }
- else if (strstr(tmpstr, "goodday"))
+ printf("faimtest: icbm: sn = \"%s\"\n", userinfo->sn);
+ printf("faimtest: icbm: warnlevel = 0x%04x\n", userinfo->warnlevel);
+ printf("faimtest: icbm: class = 0x%04x ", userinfo->class);
+ if (userinfo->class & 0x0010)
+ printf("(FREE) ");
+ if (userinfo->class & 0x0001)
+ printf("(TRIAL) ");
+ if (userinfo->class & 0x0004)
+ printf("(AOL) ");
+ printf("\n");
+ printf("faimtest: icbm: membersince = %lu\n", userinfo->membersince);
+ printf("faimtest: icbm: onlinesince = %lu\n", userinfo->onlinesince);
+ printf("faimtest: icbm: idletime = 0x%04x\n", userinfo->idletime);
+
+ printf("faimtest: icbm: icbmflags = ");
+ if (icbmflags & AIM_IMFLAGS_AWAY)
+ printf("away ");
+ if (icbmflags & AIM_IMFLAGS_ACK)
+ printf("ackrequest ");
+ printf("\n");
+
+ printf("faimtest: icbm: encoding flags = {%04x, %04x}\n", flag1, flag2);
+
+ printf("faimtest: icbm: message: %s\n", msg);
+
+ if (msg)
{
- printf("faimtest: icbm: sending response\n");
- aim_send_im(sess, command->conn, userinfo->sn, 0, "Good day to you too.");
- }
+ tmpstr = index(msg, '>');
+ if (tmpstr != NULL)
+ tmpstr+=1;
+ else
+ tmpstr = msg;
+
+ if ( (strlen(tmpstr) >= 10) &&
+ (!strncmp(tmpstr, "disconnect", 10)) )
+ {
+ aim_send_im(sess, command->conn, "midendian", 0, "ta ta...");
+ aim_logoff(sess);
+ }
+ else if (strstr(tmpstr, "goodday"))
+ {
+ printf("faimtest: icbm: sending response\n");
+ aim_send_im(sess, command->conn, userinfo->sn, 0, "Good day to you too.");
+ }
#if 0
- else if (!strncmp(tmpstr, "joinchat", 8))
- {
- aim_chat_join(sess, command->conn, "GoodDay");
- }
+ else if (!strncmp(tmpstr, "joinchat", 8))
+ {
+ aim_chat_join(sess, command->conn, "GoodDay");
+ }
#endif
- else
- {
+ else
+ {
#if 0
- printf("faimtest: icbm: starting chat...\n");
- aim_bos_reqservice(sess, command->conn, AIM_CONN_TYPE_CHATNAV);
+ printf("faimtest: icbm: starting chat...\n");
+ aim_bos_reqservice(sess, command->conn, AIM_CONN_TYPE_CHATNAV);
#else
- aim_bos_setidle(sess, command->conn, 0x0ffffffe);
+ aim_bos_setidle(sess, command->conn, 0x0ffffffe);
#endif
+ }
+
}
-
}
-
+ /*
+ * Channel 2: Chat Invitation
+ */
+ else if (channel == 2)
+ {
+ struct aim_userinfo_s *userinfo;
+ char *roomname,*msg,*encoding,*lang;
+ u_short exchange, instance;
+
+ userinfo = va_arg(ap, struct aim_userinfo_s *);
+ roomname = va_arg(ap, char *);
+ msg = va_arg(ap, char *);
+ encoding = va_arg(ap, char *);
+ lang = va_arg(ap, char *);
+ exchange = va_arg(ap, u_short);
+ instance = va_arg(ap, u_short);
+ va_end(ap);
+
+ printf("faimtest: chat invitation: source sn = %s\n", userinfo->sn);
+ printf("faimtest: chat invitation: \twarnlevel = 0x%04x\n", userinfo->warnlevel);
+ printf("faimtest: chat invitation: \tclass = 0x%04x ", userinfo->class);
+ if (userinfo->class & 0x0010)
+ printf("(FREE) ");
+ if (userinfo->class & 0x0001)
+ printf("(TRIAL) ");
+ if (userinfo->class & 0x0004)
+ printf("(AOL) ");
+ printf("\n");
+ /* we dont get membersince on chat invites! */
+ printf("faimtest: chat invitation: \tonlinesince = %lu\n", userinfo->onlinesince);
+ printf("faimtest: chat invitation: \tidletime = 0x%04x\n", userinfo->idletime);
+
+ printf("faimtest: chat invitation: message = %s\n", msg);
+ printf("faimtest: chat invitation: room name = %s\n", roomname);
+ printf("faimtest: chat invitation: encoding = %s\n", encoding);
+ printf("faimtest: chat invitation: language = %s\n", lang);
+ printf("faimtest: chat invitation: exchange = 0x%04x\n", exchange);
+ printf("faimtest: chat invitation: instance = 0x%04x\n", instance);
+ }
+ else
+ printf("faimtest does not support channels > 2 (chan = %02x)\n", channel);
printf("faimtest: icbm: done with ICBM handling\n");
return 1;