# HG changeset patch # User Eric Warmenhoven # Date 975711696 0 # Node ID ed8855ae663234d315feccae8dc0c2b4ad87c545 # Parent cda9dfc65693dbbeaa948fd75085d85335e45397 [gaim-migrate @ 1194] libfaim updates. committer: Tailor Script diff -r cda9dfc65693 -r ed8855ae6632 libfaim/CHANGES --- a/libfaim/CHANGES Fri Dec 01 22:55:18 2000 +0000 +++ b/libfaim/CHANGES Fri Dec 01 23:01:36 2000 +0000 @@ -1,6 +1,17 @@ No release numbers ------------------ + - Fri Dec 1 22:25:56 UTC 2000 + - Fix numerous tiny (but sometimes catastrophic) bugs dealing + with connection death (particularly with chat connections) + - *** Any connection with a -1 fd will get returned by aim_select + immediatly now... your code probably already handles this implicitly. + + - Wed Nov 29 17:31:23 UTC 2000 + - Rewrote some of the msgcookie stuff + - Changed cachecookies to uncachecookies where it makes sense (arg!) + - Minor other stuff + - Fri Nov 10 08:24:34 UTC 2000 - Add sess->flags (replaces sess->snaclogin) - Remove odd setstatus call in chat parser diff -r cda9dfc65693 -r ed8855ae6632 libfaim/aim_chat.c --- a/libfaim/aim_chat.c Fri Dec 01 22:55:18 2000 +0000 +++ b/libfaim/aim_chat.c Fri Dec 01 23:01:36 2000 +0000 @@ -25,6 +25,10 @@ for (cur = sess->connlist; cur; cur = cur->next) { if (cur->type != AIM_CONN_TYPE_CHAT) continue; + if (!cur->priv) { + printf("faim: chat: chat connection with no name! (fd = %d)\n", cur->fd); + continue; + } if (strcmp((char *)cur->priv, name) == 0) break; } @@ -38,8 +42,10 @@ if (!conn || !roomname) return -1; - conn->priv = malloc(strlen(roomname)+1); - strcpy(conn->priv, roomname); + if (conn->priv) + free(conn->priv); + + conn->priv = strdup(roomname); return 0; } @@ -250,7 +256,7 @@ if (detaillevel != 0x02) { if (detaillevel == 0x01) - printf("faim: chat_roomupdateinfo: detail level 2 not supported\n"); + printf("faim: chat_roomupdateinfo: detail level 1 not supported\n"); else printf("faim: chat_roomupdateinfo: unknown detail level %d\n", detaillevel); return 1; @@ -422,10 +428,11 @@ struct aim_userinfo_s userinfo; rxcallback_t userfunc=NULL; int ret = 1, i = 0, z = 0; - u_char cookie[8]; + unsigned char cookie[8]; int channel; struct aim_tlvlist_t *outerlist; char *msg = NULL; + struct aim_msgcookie_t *ck; memset(&userinfo, 0x00, sizeof(struct aim_userinfo_s)); @@ -437,7 +444,11 @@ for (z=0; z<8; z++,i++) cookie[z] = command->data[i]; - aim_cachecookie(sess, aim_mkcookie(cookie, AIM_COOKIETYPE_ICBM, NULL)); + if ((ck = aim_uncachecookie(sess, cookie, AIM_COOKIETYPE_CHAT))) { + if (ck->data) + free(ck->data); + free(ck); + } /* * Channel ID @@ -547,7 +558,7 @@ struct aim_conn_t *conn; if ((conn = aim_chat_getconn(sess, name))) - aim_conn_kill(sess, &conn); + aim_conn_close(conn); if (!conn) return -1; @@ -569,7 +580,10 @@ int i,curbyte=0; if (!sess || !conn || !sn || !msg || !roomname) - return 0; + return -1; + + if (conn->type != AIM_CONN_TYPE_BOS) + return -1; if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 1152+strlen(sn)+strlen(roomname)+strlen(msg)))) return -1; @@ -583,6 +597,8 @@ */ for (i=0;i<8;i++) curbyte += aimutil_put8(newpacket->data+curbyte, (u_char)rand()); + + /* XXX this should get uncached by the unwritten 'invite accept' handler */ aim_cachecookie(sess, aim_mkcookie(newpacket->data+curbyte-8, AIM_COOKIETYPE_CHAT, NULL)); /* diff -r cda9dfc65693 -r ed8855ae6632 libfaim/aim_conn.c --- a/libfaim/aim_conn.c Fri Dec 01 22:55:18 2000 +0000 +++ b/libfaim/aim_conn.c Fri Dec 01 23:01:36 2000 +0000 @@ -39,37 +39,6 @@ } /** - * aim_conn_getnext - Gets a new connection structure. - * @sess: Session - * - * Allocate a new empty connection structure. - * - */ -faim_internal struct aim_conn_t *aim_conn_getnext(struct aim_session_t *sess) -{ - struct aim_conn_t *newconn, *cur; - - if (!(newconn = malloc(sizeof(struct aim_conn_t)))) - return NULL; - - memset(newconn, 0, sizeof(struct aim_conn_t)); - aim_conn_close(newconn); - newconn->next = NULL; - - faim_mutex_lock(&sess->connlistlock); - if (sess->connlist == NULL) - sess->connlist = newconn; - else { - for (cur = sess->connlist; cur->next; cur = cur->next) - ; - cur->next = newconn; - } - faim_mutex_unlock(&sess->connlistlock); - - return newconn; -} - -/** * aim_conn_init - Reset a connection to default values. * @deadconn: Connection to be reset * @@ -96,6 +65,37 @@ } /** + * aim_conn_getnext - Gets a new connection structure. + * @sess: Session + * + * Allocate a new empty connection structure. + * + */ +faim_internal struct aim_conn_t *aim_conn_getnext(struct aim_session_t *sess) +{ + struct aim_conn_t *newconn, *cur; + + if (!(newconn = malloc(sizeof(struct aim_conn_t)))) + return NULL; + + memset(newconn, 0, sizeof(struct aim_conn_t)); + aim_conn_init(newconn); + newconn->next = NULL; + + faim_mutex_lock(&sess->connlistlock); + if (sess->connlist == NULL) + sess->connlist = newconn; + else { + for (cur = sess->connlist; cur->next; cur = cur->next) + ; + cur->next = newconn; + } + faim_mutex_unlock(&sess->connlistlock); + + return newconn; +} + +/** * aim_conn_kill - Close and free a connection. * @sess: Session for the connection * @deadconn: Connection to be freed @@ -131,7 +131,8 @@ /* XXX: do we need this for txqueue too? */ aim_rxqueue_cleanbyconn(sess, *deadconn); - aim_conn_close(*deadconn); + if ((*deadconn)->fd != -1) + aim_conn_close(*deadconn); if ((*deadconn)->priv) free((*deadconn)->priv); free(*deadconn); @@ -146,34 +147,22 @@ * * Close (but not free) a connection. * + * This leaves everything untouched except for clearing the + * handler list and setting the fd to -1 (used to recognize + * dead connections). + * */ faim_export void aim_conn_close(struct aim_conn_t *deadconn) { - int typesav = -1, subtypesav = -1; - void *privsav = NULL; faim_mutex_destroy(&deadconn->active); faim_mutex_destroy(&deadconn->seqnum_lock); if (deadconn->fd >= 3) close(deadconn->fd); + deadconn->fd = -1; if (deadconn->handlerlist) aim_clearhandlers(deadconn); - typesav = deadconn->type; - subtypesav = deadconn->subtype; - - if (deadconn->priv && (deadconn->type != AIM_CONN_TYPE_RENDEZVOUS)) { - free(deadconn->priv); - deadconn->priv = NULL; - } - privsav = deadconn->priv; - - aim_conn_init(deadconn); - - deadconn->type = typesav; - deadconn->subtype = subtypesav; - deadconn->priv = privsav; - return; } @@ -547,7 +536,12 @@ faim_mutex_lock(&sess->connlistlock); for (cur = sess->connlist; cur; cur = cur->next) { - if (cur->status & AIM_CONN_STATUS_INPROGRESS) { + if (cur->fd == -1) { + /* don't let invalid/dead connections sit around */ + *status = 2; + faim_mutex_unlock(&sess->connlistlock); + return cur; + } else if (cur->status & AIM_CONN_STATUS_INPROGRESS) { FD_SET(cur->fd, &wfds); haveconnecting++; } diff -r cda9dfc65693 -r ed8855ae6632 libfaim/aim_msgcookie.c --- a/libfaim/aim_msgcookie.c Fri Dec 01 22:55:18 2000 +0000 +++ b/libfaim/aim_msgcookie.c Fri Dec 01 23:01:36 2000 +0000 @@ -24,13 +24,13 @@ * - newcook->addtime is updated accordingly; * - cookie->type is just passed across. * - * returns -1 on error, 0 on success. */ - + * returns -1 on error, 0 on success. + */ faim_internal int aim_cachecookie(struct aim_session_t *sess, struct aim_msgcookie_t *cookie) { - struct aim_msgcookie_t *newcook = NULL, *cur = NULL; - + struct aim_msgcookie_t *newcook; + if (!cookie) return -1; @@ -46,30 +46,18 @@ free(cookie->data); } - return(0); + + return 0; } if (!(newcook = malloc(sizeof(struct aim_msgcookie_t)))) return -1; memcpy(newcook, cookie, sizeof(struct aim_msgcookie_t)); newcook->addtime = time(NULL); - - if(newcook->next) - printf("faim: cachecookie: newcook->next isn't NULL ???\n"); + + newcook->next = sess->msgcookies; + sess->msgcookies = newcook; - newcook->next = NULL; - - cur = sess->msgcookies; - - if (cur == NULL) { - sess->msgcookies = newcook; - return 0; - } - - while (cur->next != NULL) - cur = cur->next; - cur->next = newcook; - return 0; } @@ -79,7 +67,6 @@ * it. removes struct from chain. returns the struct if found, or * NULL on not found. */ - faim_internal struct aim_msgcookie_t *aim_uncachecookie(struct aim_session_t *sess, unsigned char *cookie, int type) { struct aim_msgcookie_t *cur; @@ -87,23 +74,28 @@ if (!cookie || !sess->msgcookies) return NULL; - cur = sess->msgcookies; + if ((sess->msgcookies->type == type) && + (memcmp(sess->msgcookies->cookie, cookie, 8) == 0)) { + struct aim_msgcookie_t *tmp; - if ( (memcmp(cur->cookie, cookie, 8) == 0) && (cur->type == type) ) { - sess->msgcookies = cur->next; - return cur; + tmp = sess->msgcookies; + sess->msgcookies = sess->msgcookies->next; + + return tmp; } - while (cur->next) { - if ( (memcmp(cur->next->cookie, cookie, 8) == 0) && (cur->next->type == type) ) { + for (cur = sess->msgcookies; cur->next; cur = cur->next) { + if ((cur->next->type == type) && + (memcmp(cur->next->cookie, cookie, 8) == 0)) { struct aim_msgcookie_t *tmp; tmp = cur->next; cur->next = cur->next->next; + return tmp; } - cur = cur->next; } + return NULL; } @@ -123,15 +115,14 @@ faim_export int aim_purgecookies(struct aim_session_t *sess, int maxage) { struct aim_msgcookie_t *cur; - struct aim_msgcookie_t *remed = NULL; time_t curtime; - cur = sess->msgcookies; - - curtime = time(&curtime); - - while (cur) { - if ( (cur->addtime) > (curtime - maxage) ) { + curtime = time(NULL); + + for (cur = sess->msgcookies; cur; cur = cur->next) { + if (cur->addtime > (time(NULL) - maxage)) { + struct aim_msgcookie_t *remed = NULL; + #if DEBUG > 1 printf("aimmsgcookie: WARNING purged obsolete message cookie %x%x%x%x %x%x%x%x\n", cur->cookie[0], cur->cookie[1], cur->cookie[2], cur->cookie[3], @@ -145,9 +136,6 @@ free(remed); } } - - cur = cur->next; - } return 0; @@ -157,42 +145,34 @@ { struct aim_msgcookie_t *cookie; - if(!c) - return(NULL); + if (!c) + return NULL; - if( (cookie = calloc(1, sizeof(struct aim_msgcookie_t))) == NULL) - return(NULL); + if (!(cookie = calloc(1, sizeof(struct aim_msgcookie_t)))) + return NULL; cookie->data = data; - cookie->type = type; - memcpy(cookie->cookie, c, 8); - return(cookie); + return cookie; } faim_internal struct aim_msgcookie_t *aim_checkcookie(struct aim_session_t *sess, unsigned char *cookie, int type) { struct aim_msgcookie_t *cur; - if(!sess->msgcookies) - return NULL; - - cur = sess->msgcookies; + for (cur = sess->msgcookies; cur; cur = cur->next) { + if ((cur->type == type) && + (memcmp(cur->cookie, cookie, 8) == 0)) + return cur; + } - if( (memcmp(cur->cookie, cookie, 8) == 0) && (cur->type == type)) - return(cur); - - while( (cur = cur->next) ) - if( (memcmp(cur->cookie, cookie, 8) == 0) && (cur->type == type)) - return(cur); - - return(NULL); + return NULL; } static int aim_freecookie(struct aim_msgcookie_t *cookie) { - return(0); + return 0; } faim_internal int aim_msgcookie_gettype(int reqclass) { diff -r cda9dfc65693 -r ed8855ae6632 libfaim/aim_rxqueue.c --- a/libfaim/aim_rxqueue.c Fri Dec 01 22:55:18 2000 +0000 +++ b/libfaim/aim_rxqueue.c Fri Dec 01 23:01:36 2000 +0000 @@ -57,6 +57,9 @@ if (!sess || !conn) return 0; + if (conn->fd == -1) + return -1; /* its a aim_conn_close()'d connection */ + if (conn->fd < 3) /* can happen when people abuse the interface */ return 0; diff -r cda9dfc65693 -r ed8855ae6632 libfaim/aim_txqueue.c --- a/libfaim/aim_txqueue.c Fri Dec 01 22:55:18 2000 +0000 +++ b/libfaim/aim_txqueue.c Fri Dec 01 23:01:36 2000 +0000 @@ -306,7 +306,7 @@ if (send(cur->conn->fd, curPacket, buflen, 0) != buflen) { faim_mutex_unlock(&cur->conn->active); cur->sent = 1; - aim_conn_kill(sess, &cur->conn); + aim_conn_close(cur->conn); return 0; /* bail out */ } diff -r cda9dfc65693 -r ed8855ae6632 libfaim/faim/aim.h --- a/libfaim/faim/aim.h Fri Dec 01 22:55:18 2000 +0000 +++ b/libfaim/faim/aim.h Fri Dec 01 23:01:36 2000 +0000 @@ -1,6 +1,9 @@ /* * Main libfaim header. Must be included in client for prototypes/macros. * + * "come on, i turned a chick lesbian; i think this is the hackish equivalent" + * -- Josh Meyer + * */ #ifndef __AIM_H__