# HG changeset patch # User Eric Warmenhoven # Date 976665538 0 # Node ID 2ac6ccb94229ef9b9b7b99d0be18420a919d37c1 # Parent eaa0e2f5ace4a6c7eb5d0fe89f99c1eaebf6f911 [gaim-migrate @ 1255] libfaim stuff committer: Tailor Script diff -r eaa0e2f5ace4 -r 2ac6ccb94229 libfaim/CHANGES --- a/libfaim/CHANGES Tue Dec 12 23:09:07 2000 +0000 +++ b/libfaim/CHANGES Tue Dec 12 23:58:58 2000 +0000 @@ -1,6 +1,17 @@ No release numbers ------------------ + - Tue Dec 12 23:02:41 UTC 2000 + - Got pissed off at sess->logininfo. Got rid of it. + - Now pass all that stuff in as varargs, like it should be. + - *** Look at the changes to faimtest. You'll also need to + change anything in your code that references sess->logininfo + to reference sess->sn instead. The rest of the other info + is now unavailable (it was before, too, it just didnt look like it). + - A few other minor cleanups. + - Added aim_gettlv8/16/32, aim_puttlv_8, and aim_addtlvtochain_noval. + - Added that short 0x004a TLV to the auth request, like WinAIM 4.3. + - Mon Dec 4 23:46:35 UTC 2000 - Add exchange to the create response callback (doh!) diff -r eaa0e2f5ace4 -r 2ac6ccb94229 libfaim/aim_ft.c --- a/libfaim/aim_ft.c Tue Dec 12 23:09:07 2000 +0000 +++ b/libfaim/aim_ft.c Tue Dec 12 23:58:58 2000 +0000 @@ -26,7 +26,7 @@ int acceptfd = 0; rxcallback_t userfunc; struct sockaddr cliaddr; - unsigned int clilen = sizeof(cliaddr); + socklen_t clilen = sizeof(cliaddr); int ret = 0; /* @@ -151,7 +151,7 @@ i += aimutil_put16(newpacket2->hdr.oft.hdr2+i, 0x0000); i += aimutil_put16(newpacket2->hdr.oft.hdr2+i, 0x0000); - i += aimutil_putstr(newpacket2->hdr.oft.hdr2+i, sess->logininfo.screen_name, strlen(sess->logininfo.screen_name)); + i += aimutil_putstr(newpacket2->hdr.oft.hdr2+i, sess->sn, strlen(sess->sn)); i = 52; /* 0x34 */ i += aimutil_put8(newpacket2->hdr.oft.hdr2+i, 0x00); /* 53 */ @@ -205,7 +205,7 @@ i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000); i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000); - i += aimutil_putstr(newpacket->hdr.oft.hdr2+i, sess->logininfo.screen_name, strlen(sess->logininfo.screen_name)); + i += aimutil_putstr(newpacket->hdr.oft.hdr2+i, sess->sn, strlen(sess->sn)); i = 52; /* 0x34 */ i += aimutil_put8(newpacket->hdr.oft.hdr2+i, 0x00); /* 53 */ @@ -1572,6 +1572,86 @@ } /* + * int aim_getfile_send_chunk(struct aim_conn_t *conn, FILE *tosend, struct aim_fileheader_t *fh, int pos, int bufsize) + * conn is the OFT connection to shove the data down, + * tosend is the FILE * for the file to send + * fh is the filled-in fh value + * pos is the position to start at (at beginning should be 0, after 5 + * bytes are sent should be 5); -1 for "don't seek" + * bufsize is the size of the chunk to send + * + * returns -1 on error, new pos on success. + * + * + * Notes on usage: + * You don't really have to keep track of pos if you don't want + * to. just always call with -1 for pos, and it'll use the one + * contained within the FILE *. + * + * if (pos + chunksize > fh->size), we only send as much data as we + * can get (ie: up to fh->size. + */ + +faim_export int aim_getfile_send_chunk(struct aim_conn_t *conn, FILE *tosend, struct aim_fileheader_t *fh, int pos, int bufsize) +{ + int bufpos; + char *buf; + + /* sanity checks */ + if(conn->type != AIM_CONN_TYPE_RENDEZVOUS || conn->type != AIM_CONN_SUBTYPE_OFT_GETFILE) { + faimdprintf(1, "faim: getfile_send_chunk: conn->type(0x%04x) != RENDEZVOUS or conn->subtype(0x%04x) != GETFILE\n", conn->type, conn->subtype); + return -1; + } + + if(!tosend) { + faimdprintf(1, "faim: getfile_send_chunk: file pointer isn't valid\n"); + return -1; + } + + if(!fh) { + faimdprintf(1, "faim: getfile_send_chunk: fh isn't valid\n"); + return -1; + } + + /* real code */ + + if(!(buf = (char *)calloc(1, bufsize))) { + perror("faim: getfile_send_chunk: calloc:"); + faimdprintf(2, "faim: getfile_send_chunk calloc error\n"); + return -1; + } + + if(pos != -1) { + if( fseek(tosend, pos, SEEK_SET) == -1) { + perror("faim: getfile_send_chunk: fseek:"); + faimdprintf(2, "faim: getfile_send_chunk fseek error\n"); + } + } + + faimdprintf(2, "faim: getfile_send_chunk: using %i byte blocks\n", bufsize); + + for(bufpos = 0; pos < fh->size; bufpos++, pos++) { + if( (buf[bufpos] = fgetc(tosend)) == EOF) { + if(pos != fh->size) { + faimdprintf(1, "faim: getfile_send_chunk: hrm... apparent early EOF at pos 0x%x of 0x%x\n", pos, fh->size); + free(buf); + return -1; + } + } + } + + if( write(conn->fd, buf, bufpos+1) != (bufpos+1)) { + faimdprintf(1, "faim: getfile_send_chunk cleanup: whoopsy, didn't write it all...\n"); + free(buf); + return -1; + } + + free(buf); + + return (pos + bufpos); +} + +/* * aim_tx_destroy: * free's tx_command_t's. if command is locked, doesn't free. * returns -1 on error (locked struct); 0 on success. @@ -1802,92 +1882,3 @@ } #endif - -/* - * int aim_getfile_send_chunk(struct aim_conn_t *conn, FILE *tosend, struct aim_fileheader_t *fh, int pos, int bufsize) - * conn is the OFT connection to shove the data down, - * tosend is the FILE * for the file to send - * fh is the filled-in fh value - * pos is the position to start at (at beginning should be 0, after 5 - * bytes are sent should be 5); -1 for "don't seek" - * bufsize is the size of the chunk to send - * - * returns -1 on error, new pos on success. 0 on EOF - * - * - * Notes on usage: - * You don't really have to keep track of pos if you don't want - * to. just always call with -1 for pos, and it'll use the one - * contained within the FILE *. - * - * if (pos + chunksize > fh->size), we only send as much data as we - * can get (ie: up to fh->size. - */ - -faim_export int aim_getfile_send_chunk(struct aim_conn_t *conn, FILE *tosend, struct aim_fileheader_t *fh, int pos, int bufsize) -{ - int bufpos; - int curpos; - char *buf; - - /* sanity checks */ - if(conn->type != AIM_CONN_TYPE_RENDEZVOUS || conn->subtype != AIM_CONN_SUBTYPE_OFT_GETFILE) { - faimdprintf(1, "faim: getfile_send_chunk: conn->type(0x%04x) != RENDEZVOUS or conn->subtype(0x%04x) != GETFILE\n", conn->type, conn->subtype); - return -1; - } - - if(!tosend) { - faimdprintf(1, "faim: getfile_send_chunk: file pointer isn't valid\n"); - return -1; - } - - if(!fh) { - faimdprintf(1, "faim: getfile_send_chunk: fh isn't valid\n"); - return -1; - } - - /* real code */ - - if(!(buf = (char *)calloc(1, bufsize))) { - perror("faim: getfile_send_chunk: calloc:"); - faimdprintf(2, "faim: getfile_send_chunk calloc error\n"); - return -1; - } - - if(pos != -1) { - if( fseek(tosend, pos, SEEK_SET) == -1) { - perror("faim: getfile_send_chunk: fseek:"); - faimdprintf(2, "faim: getfile_send_chunk fseek error\n"); - } - curpos = pos; - } else - pos = ftell(tosend); - - - faimdprintf(2, "faim: getfile_send_chunk: using %i byte blocks\n", bufsize); - - for(bufpos = 0; (bufpos < bufsize) && (pos < fh->size); bufpos++, pos++) { - if( (buf[bufpos] = fgetc(tosend)) == EOF) { -#if 0 /* fuck checking */ - if(pos != fh->size) { - fprintf(stderr, "faim: getfile_send_chunk: hrm... apparent early EOF at pos 0x%x of 0x%x\n", pos, fh->size); - perror("getfile_send_chunk: fgetc: "); - free(buf); - return -1; - } -#endif - return 0; - } - } - - if( write(conn->fd, buf, bufpos+1) != (bufpos+1)) { - faimdprintf(1, "faim: getfile_send_chunk cleanup: whoopsy, didn't write it all...\n"); - perror("getfile_send_chunk: write: "); - free(buf); - return -1; - } - - free(buf); - - return (pos+1); -} diff -r eaa0e2f5ace4 -r 2ac6ccb94229 libfaim/aim_login.c --- a/libfaim/aim_login.c Tue Dec 12 23:09:07 2000 +0000 +++ b/libfaim/aim_login.c Tue Dec 12 23:58:58 2000 +0000 @@ -132,6 +132,17 @@ * encode_password(). See that function for their * stupid method of doing it. * + * Latest WinAIM: + * clientstring = "AOL Instant Messenger (SM), version 4.3.2188/WIN32" + * major2 = 0x0109 + * major = 0x0400 + * minor = 0x0003 + * minor2 = 0x0000 + * build = 0x088c + * unknown = 0x00000086 + * lang = "en" + * country = "us" + * unknown4a = 0x01 */ faim_export int aim_send_login (struct aim_session_t *sess, struct aim_conn_t *conn, @@ -188,7 +199,9 @@ curbyte += aim_puttlv_32(newpacket->data+curbyte, 0x0014, clientinfo->unknown); curbyte += aim_puttlv_16(newpacket->data+curbyte, 0x0009, 0x0015); + curbyte += aim_puttlv_8(newpacket->data+curbyte, 0x004a, 0x01); } else { + /* Use very specific version numbers, to further indicate the hack. */ curbyte += aim_puttlv_16(newpacket->data+curbyte, 0x0016, 0x010a); curbyte += aim_puttlv_16(newpacket->data+curbyte, 0x0017, 0x0004); curbyte += aim_puttlv_16(newpacket->data+curbyte, 0x0018, 0x003c); @@ -272,7 +285,7 @@ * It can be either an error or a success, depending on the * precense of certain TLVs. * - * The client should check the value of logininfo->errorcode. If + * The client should check the value passed as errorcode. If * its nonzero, there was an error. * */ @@ -281,10 +294,10 @@ { struct aim_tlvlist_t *tlvlist; int ret = 1; - char *sn; rxcallback_t userfunc = NULL; - - memset(&sess->logininfo, 0x00, sizeof(sess->logininfo)); + char *sn = NULL, *bosip = NULL, *errurl = NULL, *email = NULL; + unsigned char *cookie = NULL; + int errorcode = 0, regstatus = 0; /* * Read block of TLVs. All further data is derived @@ -301,74 +314,69 @@ /* * No matter what, we should have a screen name. */ - sn = aim_gettlv_str(tlvlist, 0x0001, 1); - strncpy(sess->logininfo.screen_name, sn, strlen(sn)); - free(sn); + memset(sess->sn, 0, sizeof(sess->sn)); + if (aim_gettlv(tlvlist, 0x0001, 1)) { + sn = aim_gettlv_str(tlvlist, 0x0001, 1); + strncpy(sess->sn, sn, sizeof(sess->sn)); + } /* * Check for an error code. If so, we should also * have an error url. */ - if (aim_gettlv(tlvlist, 0x0008, 1)) { - struct aim_tlv_t *errtlv; - errtlv = aim_gettlv(tlvlist, 0x0008, 1); - sess->logininfo.errorcode = aimutil_get16(errtlv->value); - sess->logininfo.errorurl = aim_gettlv_str(tlvlist, 0x0004, 1); - } - /* - * If we have both an IP number (0x0005) and a cookie (0x0006), - * then the login was successful. + if (aim_gettlv(tlvlist, 0x0008, 1)) + errorcode = aim_gettlv16(tlvlist, 0x0008, 1); + if (aim_gettlv(tlvlist, 0x0004, 1)) + errurl = aim_gettlv_str(tlvlist, 0x0004, 1); + + /* + * BOS server address. */ - else if (aim_gettlv(tlvlist, 0x0005, 1) && aim_gettlv(tlvlist, 0x0006, 1) - /*aim_gettlv(tlvlist, 0x0006, 1)->length*/) { + if (aim_gettlv(tlvlist, 0x0005, 1)) + bosip = aim_gettlv_str(tlvlist, 0x0005, 1); + + /* + * Authorization cookie. + */ + if (aim_gettlv(tlvlist, 0x0006, 1)) { struct aim_tlv_t *tmptlv; - /* - * IP address of BOS server. - */ - sess->logininfo.BOSIP = aim_gettlv_str(tlvlist, 0x0005, 1); - - /* - * Authorization Cookie - */ tmptlv = aim_gettlv(tlvlist, 0x0006, 1); - memcpy(sess->logininfo.cookie, tmptlv->value, AIM_COOKIELEN); - - /* - * The email address attached to this account - * Not available for ICQ logins. - */ - if (aim_gettlv(tlvlist, 0x0011, 1)) - sess->logininfo.email = aim_gettlv_str(tlvlist, 0x0011, 1); - - /* - * The registration status. (Not real sure what it means.) - * Not available for ICQ logins. - */ - if ((tmptlv = aim_gettlv(tlvlist, 0x0013, 1))) - sess->logininfo.regstatus = aimutil_get16(tmptlv->value); - + + if ((cookie = malloc(tmptlv->length))) + memcpy(cookie, tmptlv->value, tmptlv->length); } - userfunc = aim_callhandler(command->conn, 0x0017, 0x0003); + /* + * The email address attached to this account + * Not available for ICQ logins. + */ + if (aim_gettlv(tlvlist, 0x0011, 1)) + email = aim_gettlv_str(tlvlist, 0x0011, 1); - if (userfunc) - ret = userfunc(sess, command); + /* + * The registration status. (Not real sure what it means.) + * Not available for ICQ logins. + */ + if (aim_gettlv(tlvlist, 0x0013, 1)) + regstatus = aim_gettlv16(tlvlist, 0x0013, 1); - aim_freetlvchain(&tlvlist); - if (sess->logininfo.BOSIP) { - free(sess->logininfo.BOSIP); - sess->logininfo.BOSIP = NULL; - } - if (sess->logininfo.email) { - free(sess->logininfo.email); - sess->logininfo.email = NULL; - } - if (sess->logininfo.errorurl) { - free(sess->logininfo.errorurl); - sess->logininfo.errorurl = NULL; - } + if ((userfunc = aim_callhandler(command->conn, 0x0017, 0x0003))) + ret = userfunc(sess, command, sn, errorcode, errurl, regstatus, email, bosip, cookie); + + + if (sn) + free(sn); + if (bosip) + free(bosip); + if (errurl) + free(errurl); + if (email) + free(email); + if (cookie) + free(cookie); + aim_freetlvchain(&tlvlist); return ret; } @@ -409,7 +417,8 @@ */ faim_export unsigned long aim_sendauthresp(struct aim_session_t *sess, struct aim_conn_t *conn, - char *sn, char *bosip, + char *sn, int errorcode, + char *errorurl, char *bosip, char *cookie, char *email, int regstatus) { @@ -424,11 +433,11 @@ if (sn) aim_addtlvtochain_str(&tlvlist, 0x0001, sn, strlen(sn)); else - aim_addtlvtochain_str(&tlvlist, 0x0001, sess->logininfo.screen_name, strlen(sess->logininfo.screen_name)); + aim_addtlvtochain_str(&tlvlist, 0x0001, sess->sn, strlen(sess->sn)); - if (sess->logininfo.errorcode) { - aim_addtlvtochain16(&tlvlist, 0x0008, sess->logininfo.errorcode); - aim_addtlvtochain_str(&tlvlist, 0x0004, sess->logininfo.errorurl, strlen(sess->logininfo.errorurl)); + if (errorcode) { + aim_addtlvtochain16(&tlvlist, 0x0008, errorcode); + aim_addtlvtochain_str(&tlvlist, 0x0004, errorurl, strlen(errorurl)); } else { aim_addtlvtochain_str(&tlvlist, 0x0005, bosip, strlen(bosip)); aim_addtlvtochain_str(&tlvlist, 0x0006, cookie, AIM_COOKIELEN); @@ -438,6 +447,7 @@ tx->commandlen = aim_writetlvchain(tx->data, tx->commandlen, &tlvlist); tx->lock = 0; + return aim_tx_enqueue(sess, tx); } diff -r eaa0e2f5ace4 -r 2ac6ccb94229 libfaim/aim_tlv.c --- a/libfaim/aim_tlv.c Tue Dec 12 23:09:07 2000 +0000 +++ b/libfaim/aim_tlv.c Tue Dec 12 23:58:58 2000 +0000 @@ -322,6 +322,41 @@ } /** + * aim_addtlvtochain_noval - Add a blank TLV to a TLV chain + * @list: Destination chain + * @type: TLV type to add + * + * Adds a TLV with a zero length to a TLV chain. + * + */ +faim_internal int aim_addtlvtochain_noval(struct aim_tlvlist_t **list, unsigned short type) +{ + struct aim_tlvlist_t *newtlv; + struct aim_tlvlist_t *cur; + + newtlv = (struct aim_tlvlist_t *)malloc(sizeof(struct aim_tlvlist_t)); + memset(newtlv, 0x00, sizeof(struct aim_tlvlist_t)); + + newtlv->tlv = aim_createtlv(); + newtlv->tlv->type = type; + newtlv->tlv->length = 0; + newtlv->tlv->value = NULL; + + newtlv->next = NULL; + + if (*list == NULL) { + *list = newtlv; + } else if ((*list)->next == NULL) { + (*list)->next = newtlv; + } else { + for(cur = *list; cur->next; cur = cur->next) + ; + cur->next = newtlv; + } + return newtlv->tlv->length; +} + +/** * aim_writetlvchain - Write a TLV chain into a data buffer. * @buf: Destination buffer * @buflen: Maximum number of bytes that will be written to buffer @@ -421,6 +456,63 @@ } /** + * aim_gettlv8 - Retrieve the Nth TLV in chain as a 8bit integer. + * @list: Source TLV chain + * @type: TLV type to search for + * @nth: Index of TLV to return + * + * Same as aim_gettlv(), except that the return value is a + * 8bit integer instead of an aim_tlv_t. + * + */ +faim_internal unsigned char aim_gettlv8(struct aim_tlvlist_t *list, unsigned short type, int num) +{ + struct aim_tlv_t *tlv; + + if (!(tlv = aim_gettlv(list, type, num)) || !tlv->value) + return 0; /* erm */ + return aimutil_get8(tlv->value); +} + +/** + * aim_gettlv16 - Retrieve the Nth TLV in chain as a 16bit integer. + * @list: Source TLV chain + * @type: TLV type to search for + * @nth: Index of TLV to return + * + * Same as aim_gettlv(), except that the return value is a + * 16bit integer instead of an aim_tlv_t. + * + */ +faim_internal unsigned short aim_gettlv16(struct aim_tlvlist_t *list, unsigned short type, int num) +{ + struct aim_tlv_t *tlv; + + if (!(tlv = aim_gettlv(list, type, num)) || !tlv->value) + return 0; /* erm */ + return aimutil_get16(tlv->value); +} + +/** + * aim_gettlv32 - Retrieve the Nth TLV in chain as a 32bit integer. + * @list: Source TLV chain + * @type: TLV type to search for + * @nth: Index of TLV to return + * + * Same as aim_gettlv(), except that the return value is a + * 32bit integer instead of an aim_tlv_t. + * + */ +faim_internal unsigned long aim_gettlv32(struct aim_tlvlist_t *list, unsigned short type, int num) +{ + struct aim_tlv_t *tlv; + + if (!(tlv = aim_gettlv(list, type, num)) || !tlv->value) + return 0; /* erm */ + return aimutil_get32(tlv->value); +} + +/** * aim_grabtlv - Grab a single TLV from a data buffer * @src: Source data buffer (must be at least 4 bytes long) * @@ -550,6 +642,26 @@ } /** + * aim_puttlv_8 - Write a one-byte TLV. + * @buf: Destination buffer + * @t: TLV type + * @v: Value + * + * Writes a TLV with a one-byte integer value portion. + * + */ +faim_export int aim_puttlv_8(unsigned char *buf, unsigned short t, unsigned char v) +{ + int curbyte=0; + + curbyte += aimutil_put16(buf+curbyte, (unsigned short)(t&0xffff)); + curbyte += aimutil_put16(buf+curbyte, (unsigned short)0x0001); + curbyte += aimutil_put8(buf+curbyte, (unsigned char)(v&0xff)); + + return curbyte; +} + +/** * aim_puttlv_16 - Write a two-byte TLV. * @buf: Destination buffer * @t: TLV type diff -r eaa0e2f5ace4 -r 2ac6ccb94229 libfaim/faim/aim.h --- a/libfaim/faim/aim.h Tue Dec 12 23:09:07 2000 +0000 +++ b/libfaim/faim/aim.h Tue Dec 12 23:58:58 2000 +0000 @@ -143,22 +143,6 @@ #define AIM_MD5_STRING "AOL Instant Messenger (SM)" /* - * Login info. Passes information from the Authorization - * stage of login to the service (BOS, etc) connection - * phase. - * - */ -struct aim_login_struct { - char screen_name[MAXSNLEN+1]; - char *BOSIP; - unsigned char cookie[AIM_COOKIELEN]; - char *email; - u_short regstatus; - char *errorurl; - u_short errorcode; -}; - -/* * Client info. Filled in by the client and passed * in to aim_login(). The information ends up * getting passed to OSCAR through the initial @@ -297,21 +281,24 @@ /* ---- Client Accessible ------------------------ */ /* - * Login information. See definition above. + * Our screen name. * */ - struct aim_login_struct logininfo; + char sn[MAXSNLEN+1]; /* * Pointer to anything the client wants to * explicitly associate with this session. + * + * This is for use in the callbacks mainly. In any + * callback, you can access this with sess->aux_data. + * */ void *aux_data; /* * OFT Data */ - struct aim_oft_session_t oft; /* ---- Internal Use Only ------------------------ */ @@ -419,9 +406,13 @@ faim_internal struct aim_tlv_t *aim_grabtlvstr(u_char *src); faim_internal struct aim_tlv_t *aim_gettlv(struct aim_tlvlist_t *, u_short, int); faim_internal char *aim_gettlv_str(struct aim_tlvlist_t *, u_short, int); +faim_internal unsigned char aim_gettlv8(struct aim_tlvlist_t *list, unsigned short type, int num); +faim_internal unsigned short aim_gettlv16(struct aim_tlvlist_t *list, unsigned short type, int num); +faim_internal unsigned long aim_gettlv32(struct aim_tlvlist_t *list, unsigned short type, int num); faim_internal int aim_puttlv (u_char *dest, struct aim_tlv_t *newtlv); faim_internal struct aim_tlv_t *aim_createtlv(void); faim_internal int aim_freetlv(struct aim_tlv_t **oldtlv); +faim_export int aim_puttlv_8(unsigned char *buf, unsigned short t, unsigned char v); faim_internal int aim_puttlv_16(u_char *, u_short, u_short); faim_internal int aim_puttlv_32(u_char *, u_short, u_long); faim_internal int aim_puttlv_str(u_char *buf, u_short t, int l, char *v); @@ -430,6 +421,7 @@ 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_addtlvtochain_noval(struct aim_tlvlist_t **list, unsigned short type); faim_internal int aim_counttlvchain(struct aim_tlvlist_t **list); /* @@ -460,7 +452,7 @@ faim_export int aim_sendconnack(struct aim_session_t *sess, struct aim_conn_t *conn); faim_export int aim_request_login (struct aim_session_t *sess, struct aim_conn_t *conn, char *sn); faim_export int aim_send_login (struct aim_session_t *, struct aim_conn_t *, char *, char *, struct client_info_s *, char *key); -faim_export unsigned long aim_sendauthresp(struct aim_session_t *sess, struct aim_conn_t *conn, char *sn, char *bosip, char *cookie, char *email, int regstatus); +faim_export unsigned long aim_sendauthresp(struct aim_session_t *sess, struct aim_conn_t *conn, char *sn, int errorcode, char *errorurl, char *bosip, char *cookie, char *email, int regstatus); faim_export int aim_gencookie(unsigned char *buf); faim_export int aim_sendserverready(struct aim_session_t *sess, struct aim_conn_t *conn); faim_internal int aim_authkeyparse(struct aim_session_t *sess, struct command_rx_struct *command); diff -r eaa0e2f5ace4 -r 2ac6ccb94229 src/oscar.c --- a/src/oscar.c Tue Dec 12 23:09:07 2000 +0000 +++ b/src/oscar.c Tue Dec 12 23:58:58 2000 +0000 @@ -453,14 +453,29 @@ int gaim_parse_auth_resp(struct aim_session_t *sess, struct command_rx_struct *command, ...) { + va_list ap; struct aim_conn_t *bosconn = NULL; + char *sn = NULL, *bosip = NULL, *errurl = NULL, *email = NULL; + unsigned char *cookie = NULL; + int errorcode = 0, regstatus = 0; + struct gaim_connection *gc = find_gaim_conn_by_aim_sess(sess); - sprintf(debug_buff, "inside auth_resp (Screen name: %s)\n", - sess->logininfo.screen_name); + + va_start(ap, command); + sn = va_arg(ap, char *); + errorcode = va_arg(ap, int); + errurl = va_arg(ap, char *); + regstatus = va_arg(ap, int); + email = va_arg(ap, char *); + bosip = va_arg(ap, char *); + cookie = va_arg(ap, unsigned char *); + va_end(ap); + + sprintf(debug_buff, "inside auth_resp (Screen name: %s)\n", sn); debug_print(debug_buff); - if (sess->logininfo.errorcode) { - switch (sess->logininfo.errorcode) { + if (errorcode || !bosip || !cookie) { + switch (errorcode) { case 0x18: /* connecting too frequently */ hide_login_progress(gc, _("You have been connecting and disconnecting too frequently. Wait ten minutes and try again. If you continue to try, you will need to wait even longer.")); @@ -480,12 +495,8 @@ hide_login_progress(gc, _("Authentication Failed")); break; } - sprintf(debug_buff, "Login Error Code 0x%04x\n", - sess->logininfo.errorcode); - debug_print(debug_buff); - sprintf(debug_buff, "Error URL: %s\n", - sess->logininfo.errorurl); - debug_print(debug_buff); + debug_printf("Login Error Code 0x%04x\n", errorcode); + debug_printf("Error URL: %s\n", errurl); #ifdef USE_APPLET set_user_state(offline); #endif @@ -494,18 +505,17 @@ } - if (sess->logininfo.email) { - sprintf(debug_buff, "Email: %s\n", sess->logininfo.email); - debug_print(debug_buff); + if (email) { + debug_printf("Email: %s\n", email); } else { - debug_print("Email is NULL\n"); + debug_printf("Email is NULL\n"); } sprintf(debug_buff, "Closing auth connection...\n"); debug_print(debug_buff); gdk_input_remove(gc->inpa); aim_conn_kill(sess, &command->conn); - bosconn = aim_newconn(sess, AIM_CONN_TYPE_BOS, sess->logininfo.BOSIP); + bosconn = aim_newconn(sess, AIM_CONN_TYPE_BOS, bosip); if (bosconn == NULL) { #ifdef USE_APPLET set_user_state(offline); @@ -544,7 +554,7 @@ aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_DEFAULT, aim_parse_unknown, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_MOTD, gaim_parse_motd, 0); - aim_auth_sendcookie(sess, bosconn, sess->logininfo.cookie); + aim_auth_sendcookie(sess, bosconn, cookie); ((struct oscar_data *)gc->proto_data)->conn = bosconn; gc->inpa = gdk_input_add(bosconn->fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION, oscar_callback, bosconn);