- 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.
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.
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);
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
#include <netinet/in.h>
#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
while (cur) {
tmp = cur->next;
aim_conn_close(cur);
- free(cur);
+ connkill_real(sess, &cur);
cur = tmp;
}
}
*/
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;
}
*/
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;
}
*
* 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)
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;
}
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
*
#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;
}
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;
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);
#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;
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;
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");
} 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);