From: mid Date: Thu, 16 Aug 2001 13:28:01 +0000 (+0000) Subject: - Thu Aug 16 06:17:57 PDT 2001 X-Git-Tag: rel_0_99_2~27 X-Git-Url: http://andersk.mit.edu/gitweb/libfaim.git/commitdiff_plain/1dcd23dd5076d2a9d2e9d23f9ac025173f5aa346 - Thu Aug 16 06:17:57 PDT 2001 - Reformat a bit of im.c and aim.h - Rearrange encoding/subencoding checks in IM parsing --- diff --git a/CHANGES b/CHANGES index 2931c90..c8ded87 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,10 @@ No release numbers ------------------ + - Thu Aug 16 06:17:57 PDT 2001 + - Reformat a bit of im.c and aim.h + - Rearrange encoding/subencoding checks in IM parsing + - Fri Aug 3 14:19:37 EDT 2001 - Naje aun_sebd_un retyrn sabe vakyes diff --git a/include/aim.h b/include/aim.h index d850c1f..bb3b8d6 100644 --- a/include/aim.h +++ b/include/aim.h @@ -636,17 +636,17 @@ struct aim_fileheader_t { }; struct aim_filetransfer_priv { - char sn[MAXSNLEN]; - char cookie[8]; - char ip[30]; - int state; - struct aim_fileheader_t fh; + char sn[MAXSNLEN]; + char cookie[8]; + char ip[30]; + int state; + struct aim_fileheader_t fh; }; struct aim_chat_roominfo { - u_short exchange; - char *name; - u_short instance; + unsigned short exchange; + char *name; + unsigned short instance; }; #define AIM_IMFLAGS_AWAY 0x01 /* mark as an autoreply */ @@ -655,53 +655,56 @@ struct aim_chat_roominfo { #define AIM_IMFLAGS_ISO_8859_1 0x08 #define AIM_IMFLAGS_BUDDYREQ 0x10 /* buddy icon requested */ #define AIM_IMFLAGS_HASICON 0x20 /* already has icon (timestamp included) */ +#define AIM_IMFLAGS_SUBENC_MACINTOSH 0x40 /* damn that Steve Jobs! */ struct aim_sendimext_args { - const char *destsn; - unsigned short flags; - const char *msg; - int msglen; - int iconlen; - time_t iconstamp; - unsigned short iconsum; + const char *destsn; + unsigned short flags; + const char *msg; + int msglen; + int iconlen; + time_t iconstamp; + unsigned short iconsum; }; struct aim_incomingim_ch1_args { - char *msg; - int msglen; - unsigned long icbmflags; - unsigned short flag1; - unsigned short flag2; - int finlen; - unsigned char fingerprint[10]; - time_t iconstamp; + char *msg; + int msglen; + unsigned long icbmflags; + unsigned short flag1; + unsigned short flag2; + int finlen; + unsigned char fingerprint[10]; + time_t iconstamp; + int extdatalen; + unsigned char *extdata; }; struct aim_incomingim_ch2_args { - unsigned short reqclass; - unsigned short status; - union { - struct { - unsigned int length; - time_t timestamp; - unsigned char *icon; - } icon; - struct { - } voice; - struct aim_directim_priv *directim; - struct { - char *msg; - char *encoding; - char *lang; - struct aim_chat_roominfo roominfo; - } chat; - struct { - char *ip; - unsigned char *cookie; - } getfile; - struct { - } sendfile; - } info; + unsigned short reqclass; + unsigned short status; + union { + struct { + unsigned int length; + time_t timestamp; + unsigned char *icon; + } icon; + struct { + } voice; + struct aim_directim_priv *directim; + struct { + char *msg; + char *encoding; + char *lang; + struct aim_chat_roominfo roominfo; + } chat; + struct { + char *ip; + unsigned char *cookie; + } getfile; + struct { + } sendfile; + } info; }; faim_export int aim_send_im_ext(struct aim_session_t *sess, struct aim_conn_t *conn, struct aim_sendimext_args *args); diff --git a/src/im.c b/src/im.c index d78ddd8..7500d35 100644 --- a/src/im.c +++ b/src/im.c @@ -433,122 +433,144 @@ static int outgoingim(struct aim_session_t *sess, aim_module_t *mod, struct comm static int incomingim_ch1(struct aim_session_t *sess, aim_module_t *mod, struct command_rx_struct *rx, aim_modsnac_t *snac, unsigned short channel, struct aim_userinfo_s *userinfo, unsigned char *data, int datalen, unsigned char *cookie) { - unsigned short type, length; - aim_rxcallback_t userfunc; - int i, ret = 0; - struct aim_incomingim_ch1_args args; - - memset(&args, 0, sizeof(args)); - - /* - * This used to be done using tlvchains. For performance reasons, - * I've changed it to process the TLVs in-place. This avoids lots - * of per-IM memory allocations. - */ - for (i = 0; i < datalen; ) { - - type = aimutil_get16(data+i); - i += 2; - - length = aimutil_get16(data+i); - i += 2; - - if (type == 0x0002) { /* Message Block */ - unsigned short wastebits; - unsigned char *msgblock; - int j = 0, y = 0, z = 0; - - msgblock = data+i; - - /* - * 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?" - * - */ - - 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++); - - args.finlen = j; - if (args.finlen > sizeof(args.fingerprint)) - args.finlen = sizeof(args.fingerprint); - memcpy(args.fingerprint, msgblock, args.finlen); - - /* Message string length, including flag words. */ - args.msglen = aimutil_get16(msgblock+j); - j += 2; - - /* Flag words. */ - args.flag1 = aimutil_get16(msgblock+j); - if (args.flag1 == 0x0002) - args.icbmflags |= AIM_IMFLAGS_UNICODE; - else if (args.flag1 == 0x0003) - args.icbmflags |= AIM_IMFLAGS_ISO_8859_1; - j += 2; - - args.flag2 = aimutil_get16(msgblock+j); - j += 2; - - if ((args.flag1 && (args.flag1 != 0x0002) && (args.flag1 != 0x0003)) || args.flag2) - faimdprintf(sess, 0, "icbm: **warning: encoding flags are being used! {%04x, %04x}\n", args.flag1, args.flag2); - - /* Message string. */ - args.msglen -= 4; - if (args.icbmflags & AIM_IMFLAGS_UNICODE) { - args.msg = malloc(args.msglen+2); - memcpy(args.msg, msgblock+j, args.msglen); - args.msg[args.msglen] = '\0'; /* wide NULL */ - args.msg[args.msglen+1] = '\0'; - } else { - args.msg = malloc(args.msglen+1); - memcpy(args.msg, msgblock+j, args.msglen); - args.msg[args.msglen] = '\0'; - } + unsigned short type, length; + aim_rxcallback_t userfunc; + int i, ret = 0; + struct aim_incomingim_ch1_args args; - } else if (type == 0x0003) { /* Server Ack Requested */ + memset(&args, 0, sizeof(args)); - args.icbmflags |= AIM_IMFLAGS_ACK; - - } else if (type == 0x0004) { /* Message is Auto Response */ - - args.icbmflags |= AIM_IMFLAGS_AWAY; - - } else if ((type == 0x0008) && - (length == 0x000c)) { /* I-HAVE-A-REALLY-PURTY-ICON Flag */ - - args.iconstamp = aimutil_get32(data+i+8); - args.icbmflags |= AIM_IMFLAGS_HASICON; - - } else if (type == 0x0009) { - - args.icbmflags |= AIM_IMFLAGS_BUDDYREQ; - - } else { - fprintf(stderr, "incomingim_ch1: unknown TLV 0x%04x (len %d)\n", type, length); - } - - i += length; - } + /* + * This used to be done using tlvchains. For performance reasons, + * I've changed it to process the TLVs in-place. This avoids lots + * of per-IM memory allocations. + */ + for (i = 0; i < datalen; ) { + + type = aimutil_get16(data+i); + i += 2; + + length = aimutil_get16(data+i); + i += 2; + + if (type == 0x0002) { /* Message Block */ + unsigned short wastebits; + unsigned char *msgblock; + int j = 0, y = 0, z = 0; + + msgblock = data+i; + + /* + * 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?" + * + */ + + 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++); + + args.finlen = j; + if (args.finlen > sizeof(args.fingerprint)) + args.finlen = sizeof(args.fingerprint); + memcpy(args.fingerprint, msgblock, args.finlen); + + /* Message string length, including flag words. */ + args.msglen = aimutil_get16(msgblock+j); + j += 2; + + /* Flag words. */ + args.flag1 = aimutil_get16(msgblock+j); + if (args.flag1 == 0x0000) + ; /* ASCII */ + else if (args.flag1 == 0x0002) + args.icbmflags |= AIM_IMFLAGS_UNICODE; + else if (args.flag1 == 0x0003) + args.icbmflags |= AIM_IMFLAGS_ISO_8859_1; + else if (args.flag1 == 0xffff) + ; /* no encoding (yeep!) */ + j += 2; + + args.flag2 = aimutil_get16(msgblock+j); + if (args.flag2 == 0x0000) + ; /* standard subencoding? */ + else if (args.flag2 == 0x000b) + args.icbmflags |= AIM_IMFLAGS_SUBENC_MACINTOSH; + else if (args.flag2 == 0xffff) + ; /* no subencoding */ + j += 2; + + if ( ((args.flag1 != 0x0000) && + (args.flag1 != 0x0002) && + (args.flag1 != 0x0003) && + (args.flag1 != 0xffff)) || + ((args.flag2 != 0x0000) && + (args.flag2 != 0x000b) && + (args.flag2 != 0xffff))) { + faimdprintf(sess, 0, "icbm: **warning: encoding flags are being used! {%04x, %04x}\n", args.flag1, args.flag2); + } + + /* Message string. */ + args.msglen -= 4; + if (args.icbmflags & AIM_IMFLAGS_UNICODE) { + args.msg = malloc(args.msglen+2); + memcpy(args.msg, msgblock+j, args.msglen); + args.msg[args.msglen] = '\0'; /* wide NULL */ + args.msg[args.msglen+1] = '\0'; + } else { + args.msg = malloc(args.msglen+1); + memcpy(args.msg, msgblock+j, args.msglen); + args.msg[args.msglen] = '\0'; + } + + } else if (type == 0x0003) { /* Server Ack Requested */ + + args.icbmflags |= AIM_IMFLAGS_ACK; + + } else if (type == 0x0004) { /* Message is Auto Response */ + + args.icbmflags |= AIM_IMFLAGS_AWAY; + + } else if ((type == 0x0008) && (length == 0x000c)) { /* I-HAVE-A-REALLY-PURTY-ICON Flag */ + + args.iconstamp = aimutil_get32(data+i+8); + args.icbmflags |= AIM_IMFLAGS_HASICON; + + } else if (type == 0x0009) { + + args.icbmflags |= AIM_IMFLAGS_BUDDYREQ; + + } else if (type == 0x0017) { + + args.extdatalen = length; + args.extdata = data+i; + + } else { + fprintf(stderr, "incomingim_ch1: unknown TLV 0x%04x (len %d)\n", type, length); + } + + i += length; + } - if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) - ret = userfunc(sess, rx, channel, userinfo, &args); + if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) + ret = userfunc(sess, rx, channel, userinfo, &args); - free(args.msg); + free(args.msg); - return ret; + return ret; } static int incomingim_ch2(struct aim_session_t *sess, aim_module_t *mod, struct command_rx_struct *rx, aim_modsnac_t *snac, unsigned short channel, struct aim_userinfo_s *userinfo, struct aim_tlvlist_t *tlvlist, unsigned char *cookie)