From 59e1da90e82d438e82d37d16abb6af12c759d4ef Mon Sep 17 00:00:00 2001 From: mid Date: Sun, 9 Sep 2001 00:21:29 +0000 Subject: [PATCH] - Sat Sep 8 17:07:09 PDT 2001 - Fix directim so you can do it more than once without crashing. - This removes the connect/disconnect callbacks. They were pointless, as you can get the same information at a better spot by looking for when aim_getcommand returns -1, just like is done for FLAP connections. - (This was causing aim_conn_kill to be called twice for the same connect, once in the client callback, and once more when aim_getcommand returned the -1). - Add aim_conn_(close|kill)_rend(). This is for destroying the cookie and the internal data sections in one spot. - Fix a bug in aim_connrst (and hence aim_logout()) that caused intdata/priv to not be freed in those cases. Evil. --- CHANGES | 13 ++++++ include/aim_internal.h | 10 ++--- src/conn.c | 87 +++++++++++++++++++++------------------ src/ft.c | 86 ++++++++++++++++++++++++++------------ utils/faimtest/faimtest.c | 2 + utils/faimtest/ft.c | 34 --------------- 6 files changed, 125 insertions(+), 107 deletions(-) diff --git a/CHANGES b/CHANGES index 5728a35..495037b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,19 @@ No release numbers ------------------ + - Sat Sep 8 17:07:09 PDT 2001 + - Fix directim so you can do it more than once without crashing. + - This removes the connect/disconnect callbacks. They were pointless, as + you can get the same information at a better spot by looking for when + aim_getcommand returns -1, just like is done for FLAP connections. + - (This was causing aim_conn_kill to be called twice for the same connect, + once in the client callback, and once more when aim_getcommand returned + the -1). + - Add aim_conn_(close|kill)_rend(). This is for destroying the cookie and + the internal data sections in one spot. + - Fix a bug in aim_connrst (and hence aim_logout()) that caused intdata/priv + to not be freed in those cases. Evil. + - Sat Sep 8 07:32:27 PDT 2001 - Clean up ft.c slightly. Direct IM now works. In both directions. - This could still use a lot more help. It should use bstreams more. diff --git a/include/aim_internal.h b/include/aim_internal.h index e4ac437..635a47d 100644 --- a/include/aim_internal.h +++ b/include/aim_internal.h @@ -127,12 +127,6 @@ struct aim_tool_version { fu16_t toolversion; }; -struct aim_directim_intdata { - fu8_t cookie[8]; - char sn[MAXSNLEN+1]; - char ip[22]; -}; - faim_internal fu16_t aim_getcap(aim_session_t *sess, aim_bstream_t *bs, int len); faim_internal int aim_putcap(aim_bstream_t *bs, fu16_t caps); @@ -151,6 +145,10 @@ faim_internal int aim_chat_readroominfo(aim_bstream_t *bs, struct aim_chat_roomi faim_internal void faimdprintf(aim_session_t *sess, int dlevel, const char *format, ...); +faim_internal void aim_conn_close_rend(aim_session_t *sess, aim_conn_t *conn); +faim_internal void aim_conn_kill_rend(aim_session_t *sess, aim_conn_t *conn); + + #ifndef FAIM_INTERNAL_INSANE #define printf() printf called inside libfaim #define sprintf() unbounded sprintf used inside libfaim diff --git a/src/conn.c b/src/conn.c index cd0ef36..e489b1c 100644 --- a/src/conn.c +++ b/src/conn.c @@ -15,6 +15,35 @@ #include #endif +static void connkill_real(aim_session_t *sess, aim_conn_t **deadconn) +{ + + aim_rxqueue_cleanbyconn(sess, *deadconn); + aim_tx_cleanqueue(sess, *deadconn); + + if ((*deadconn)->fd != -1) + aim_conn_close(*deadconn); + + /* + * XXX ->priv should never be touched by the library. I know + * it used to be, but I'm getting rid of all that. Use + * ->internal instead. + */ + if ((*deadconn)->priv) + free((*deadconn)->priv); + + /* + * This will free ->internal if it necessary... + */ + if ((*deadconn)->type == AIM_CONN_TYPE_RENDEZVOUS) + aim_conn_kill_rend(sess, *deadconn); + + free(*deadconn); + deadconn = NULL; + + return; +} + /** * aim_connrst - Clears out connection list, killing remaining connections. * @sess: Session to be cleared @@ -33,7 +62,7 @@ static void aim_connrst(aim_session_t *sess) while (cur) { tmp = cur->next; aim_conn_close(cur); - free(cur); + connkill_real(sess, &cur); cur = tmp; } } @@ -79,24 +108,16 @@ static void aim_conn_init(aim_conn_t *deadconn) */ static aim_conn_t *aim_conn_getnext(aim_session_t *sess) { - aim_conn_t *newconn, *cur; + aim_conn_t *newconn; if (!(newconn = malloc(sizeof(aim_conn_t)))) return NULL; memset(newconn, 0, sizeof(aim_conn_t)); aim_conn_init(newconn); - newconn->next = NULL; - faim_mutex_lock(&sess->connlistlock); - if (!sess->connlist) - sess->connlist = newconn; - else { - for (cur = sess->connlist; cur->next; cur = cur->next) - ; - cur->next = newconn; - } - faim_mutex_unlock(&sess->connlistlock); + newconn->next = sess->connlist; + sess->connlist = newconn; return newconn; } @@ -112,42 +133,23 @@ static aim_conn_t *aim_conn_getnext(aim_session_t *sess) */ faim_export void aim_conn_kill(aim_session_t *sess, aim_conn_t **deadconn) { - aim_conn_t *cur; + aim_conn_t *cur, **prev; if (!deadconn || !*deadconn) return; - aim_tx_cleanqueue(sess, *deadconn); - - faim_mutex_lock(&sess->connlistlock); - if (sess->connlist == NULL) - ; - else if (sess->connlist->next == NULL) { - if (sess->connlist == *deadconn) - sess->connlist = NULL; - } else { - cur = sess->connlist; - while (cur->next) { - if (cur->next == *deadconn) { - cur->next = cur->next->next; - break; - } - cur = cur->next; + for (prev = &sess->connlist; (cur = *prev); ) { + if (cur == *deadconn) { + *prev = cur->next; + break; } + prev = &cur->next; } - faim_mutex_unlock(&sess->connlistlock); - /* XXX: do we need this for txqueue too? */ - aim_rxqueue_cleanbyconn(sess, *deadconn); + if (!cur) + return; /* oops */ - if ((*deadconn)->fd != -1) - aim_conn_close(*deadconn); - if ((*deadconn)->priv) - free((*deadconn)->priv); - if ((*deadconn)->internal) - free((*deadconn)->internal); - free(*deadconn); - deadconn = NULL; + connkill_real(sess, &cur); return; } @@ -160,7 +162,7 @@ faim_export void aim_conn_kill(aim_session_t *sess, aim_conn_t **deadconn) * * This leaves everything untouched except for clearing the * handler list and setting the fd to -1 (used to recognize - * dead connections). + * dead connections). It will also remove cookies if necessary. * */ faim_export void aim_conn_close(aim_conn_t *deadconn) @@ -173,6 +175,9 @@ faim_export void aim_conn_close(aim_conn_t *deadconn) deadconn->fd = -1; if (deadconn->handlerlist) aim_clearhandlers(deadconn); + if (deadconn->type == AIM_CONN_TYPE_RENDEZVOUS) + aim_conn_close_rend((aim_session_t *)deadconn->sessv, deadconn); + return; } diff --git a/src/ft.c b/src/ft.c index 0ab1140..c7068ae 100644 --- a/src/ft.c +++ b/src/ft.c @@ -21,11 +21,17 @@ o look for memory leaks.. there's going to be shitloads, i'm sure. */ +struct aim_directim_intdata { + fu8_t cookie[8]; + char sn[MAXSNLEN+1]; + char ip[22]; +}; + static int listenestablish(fu16_t portnum); static struct aim_fileheader_t *aim_oft_getfh(unsigned char *hdr); /** - * aim_handlerendconnect - call this to accept OFT connections and set up the requisite structures + * aim_handlerendconnect - call this to accept OFT connections and set up the required structures * @sess: the session * @cur: the conn the incoming connection is on * @@ -916,56 +922,91 @@ static int getcommand_getfile(aim_session_t *sess, aim_conn_t *conn) #endif } -static void disconnected_sendfile(aim_session_t *sess, aim_conn_t *conn) +static void connclose_sendfile(aim_session_t *sess, aim_conn_t *conn) { - aim_frame_t fr; - aim_rxcallback_t userfunc; aim_msgcookie_t *cook; struct aim_filetransfer_priv *priv = (struct aim_filetransfer_priv *)conn->priv; cook = aim_uncachecookie(sess, priv->cookie, AIM_COOKIETYPE_OFTSEND); aim_cookie_free(sess, cook); - fr.conn = conn; + return; +} - if ( (userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_SENDFILEDISCONNECT)) ) - userfunc(sess, &fr, priv->sn); +static void connkill_sendfile(aim_session_t *sess, aim_conn_t *conn) +{ + + free(conn->internal); return; } -static void disconnected_getfile(aim_session_t *sess, aim_conn_t *conn) +static void connclose_getfile(aim_session_t *sess, aim_conn_t *conn) { - aim_frame_t fr; - aim_rxcallback_t userfunc; aim_msgcookie_t *cook; struct aim_filetransfer_priv *priv = (struct aim_filetransfer_priv *)conn->priv; cook = aim_uncachecookie(sess, priv->cookie, AIM_COOKIETYPE_OFTGET); aim_cookie_free(sess, cook); - fr.conn = conn; + return; +} - if ( (userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEDISCONNECT)) ) - userfunc(sess, &fr, priv->sn); +static void connkill_getfile(aim_session_t *sess, aim_conn_t *conn) +{ + + free(conn->internal); return; } -static void disconnected_directim(aim_session_t *sess, aim_conn_t *conn) +static void connclose_directim(aim_session_t *sess, aim_conn_t *conn) { - aim_frame_t fr; struct aim_directim_intdata *intdata = (struct aim_directim_intdata *)conn->internal; - aim_rxcallback_t userfunc; aim_msgcookie_t *cook; cook = aim_uncachecookie(sess, intdata->cookie, AIM_COOKIETYPE_OFTIM); aim_cookie_free(sess, cook); - fr.conn = conn; + return; +} + +static void connkill_directim(aim_session_t *sess, aim_conn_t *conn) +{ + + free(conn->internal); + + return; +} + +faim_internal void aim_conn_close_rend(aim_session_t *sess, aim_conn_t *conn) +{ - if ( (userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMDISCONNECT)) ) - userfunc(sess, &fr, intdata->sn); + if (conn->type != AIM_CONN_TYPE_RENDEZVOUS) + return; + + if (conn->subtype == AIM_CONN_SUBTYPE_OFT_SENDFILE) + connclose_sendfile(sess, conn); + else if (conn->subtype == AIM_CONN_SUBTYPE_OFT_GETFILE) + connclose_getfile(sess, conn); + else if (conn->subtype == AIM_CONN_SUBTYPE_OFT_DIRECTIM) + connclose_directim(sess, conn); + + return; +} + +faim_internal void aim_conn_kill_rend(aim_session_t *sess, aim_conn_t *conn) +{ + + if (conn->type != AIM_CONN_TYPE_RENDEZVOUS) + return; + + if (conn->subtype == AIM_CONN_SUBTYPE_OFT_SENDFILE) + connkill_sendfile(sess, conn); + else if (conn->subtype == AIM_CONN_SUBTYPE_OFT_GETFILE) + connkill_getfile(sess, conn); + else if (conn->subtype == AIM_CONN_SUBTYPE_OFT_DIRECTIM) + connkill_directim(sess, conn); return; } @@ -1335,13 +1376,6 @@ faim_internal int aim_get_command_rendezvous(aim_session_t *sess, aim_conn_t *co faimdprintf(sess, 2, "faim: rend: read error (fd: %i)\n", conn->fd); - if (conn->subtype == AIM_CONN_SUBTYPE_OFT_DIRECTIM) - disconnected_directim(sess, conn); - else if (conn->subtype == AIM_CONN_SUBTYPE_OFT_GETFILE) - disconnected_getfile(sess, conn); - else if (conn->subtype == AIM_CONN_SUBTYPE_OFT_SENDFILE) - disconnected_sendfile(sess, conn); - aim_conn_close(conn); return -1; diff --git a/utils/faimtest/faimtest.c b/utils/faimtest/faimtest.c index d49d8b4..d333fcc 100644 --- a/utils/faimtest/faimtest.c +++ b/utils/faimtest/faimtest.c @@ -317,6 +317,8 @@ int main(int argc, char **argv) dvprintf("connection error (type 0x%04x:0x%04x)\n", waitingconn->type, waitingconn->subtype); /* we should have callbacks for all these, else the library will do the conn_kill for us. */ if (waitingconn->type == AIM_CONN_TYPE_RENDEZVOUS) { + if (waitingconn->subtype == AIM_CONN_SUBTYPE_OFT_DIRECTIM) + dvprintf("disconnected from %s\n", aim_directim_getsn(waitingconn)); aim_conn_kill(&aimsess, &waitingconn); } else aim_conn_kill(&aimsess, &waitingconn); diff --git a/utils/faimtest/ft.c b/utils/faimtest/ft.c index 0ced87f..17f010a 100644 --- a/utils/faimtest/ft.c +++ b/utils/faimtest/ft.c @@ -1,22 +1,6 @@ #include "faimtest.h" -static int directim_connect(aim_session_t *sess, aim_frame_t *fr, ...) -{ -#if 0 - va_list ap; - struct aim_directim_priv *priv; - - va_start(ap, fr); - priv = va_arg(ap, struct aim_directim_priv *); - - va_end(ap); -#endif - dprintf("faimtest: directim_connect\n"); - - return 1; -} - static int directim_incoming(aim_session_t *sess, aim_frame_t *fr, ...) { va_list ap; @@ -59,22 +43,6 @@ static int directim_incoming(aim_session_t *sess, aim_frame_t *fr, ...) return 1; } -static int directim_disconnect(aim_session_t *sess, aim_frame_t *fr, ...) -{ - va_list ap; - char *sn; - - va_start(ap, fr); - sn = va_arg(ap, char *); - va_end(ap); - - dvprintf("faimtest: directim: disconnected from %s\n", sn); - - aim_conn_kill(sess, &fr->conn); - - return 1; -} - static int directim_typing(aim_session_t *sess, aim_frame_t *fr, ...) { va_list ap; @@ -103,7 +71,6 @@ static int faimtest_directim_initiate(aim_session_t *sess, aim_frame_t *fr, ...) aim_conn_kill(sess, &listenerconn); aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING, directim_incoming, 0); - aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMDISCONNECT, directim_disconnect, 0); aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING, directim_typing, 0); aim_send_im_direct(sess, newconn, "goodday"); @@ -499,7 +466,6 @@ void directim_requested(aim_session_t *sess, aim_conn_t *conn, struct aim_userin } else { aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING, directim_incoming, 0); - aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMDISCONNECT, directim_disconnect, 0); aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING, directim_typing, 0); dvprintf("faimtest: OFT: DirectIM: connected to %s\n", userinfo->sn); -- 2.45.2