# HG changeset patch # User Eric Warmenhoven # Date 959632248 0 # Node ID 501e09c51cbc8337572e4bfbec32f4a50e8c8209 # Parent 29e1669b006b99c8aaeba7202a6c06e0902435fa [gaim-migrate @ 289] Updates to libfaim -> updates to gaim. committer: Tailor Script diff -r 29e1669b006b -r 501e09c51cbc libfaim/CHANGES --- a/libfaim/CHANGES Mon May 29 00:56:37 2000 +0000 +++ b/libfaim/CHANGES Mon May 29 20:30:48 2000 +0000 @@ -1,6 +1,24 @@ No release numbers ------------------ + - Mon May 29 12:08:28 GMT 2000 + - Rearranged aim_tx_flushqueue(); moved write operation + to aim_tx_sendframe() + - Turned aim_tx_enqueue() into a macro that calls sess->tx_enqueue, + a function pointer to whatever you want to use to enqueue + things for transmition (or not) + - Old aim_tx_enqueue becomes aim_tx_enqueue__queuebased. Added + aim_tx_enqueue__immediate for doing immediate writes. Default + is to use queue-based procedure. + - Cleaned up parts of aim_conn.c + - Added locking around the sockets themselves. Should allow + for full cross-thread usage. + - Unfortunatly, only pthreads are supported at this time. + If you don't have pthreads on your arch, implement the + macros your arch needs and send me a patch. (A SysV + semaphore implementation would be trivial, as would a + simple integer-based lock.) + - Sun May 21 14:59:20 GMT 2000 - Added infotype parameter to aim_getinfo() for requesting different types of messages. AIM_GETINFO_GENERALINFO diff -r 29e1669b006b -r 501e09c51cbc libfaim/CHANGES.gaim --- a/libfaim/CHANGES.gaim Mon May 29 00:56:37 2000 +0000 +++ b/libfaim/CHANGES.gaim Mon May 29 20:30:48 2000 +0000 @@ -1,3 +1,17 @@ + +Mon May 29 20:24:24 UTC 2000 EWarmenhoven + - Updated the libfaim code to the latest that's in libfaim's CVS. The + new code has one nice feature and one feature that may or may not + cause problems. The nice feature is aim_tx_enqueue__immediate, which + means that the change to aim_txenqueue I made no longer applies, I + just have to set gaim_sess->tx_enqueue to the __immediate function. + The one that may cause problems is libfaim has the beginnings of + threads. The way the code worked in libfaim was if you were using + linux, FAIM_USEPTHREADS was defined, otherwise, you couldn't use + libfaim. Since gaim requires pthreads at ./configure-time, we can + let anyone use it. So I changed that in faimconfig.h. + - The changes clued me in to a few bugs in oscar.c that were causing + signon problems. Those should be fixed now. Sun May 28 21:33:43 UTC 2000 EWarmenhoven - Figured out how aim_set_latency works, and why I thought it wasn't diff -r 29e1669b006b -r 501e09c51cbc libfaim/aim.h --- a/libfaim/aim.h Mon May 29 00:56:37 2000 +0000 +++ b/libfaim/aim.h Mon May 29 20:30:48 2000 +0000 @@ -9,6 +9,10 @@ #include #include +#ifndef FAIM_USEPTHREADS +#error pthreads are currently required. +#endif + #include #include #include @@ -17,6 +21,14 @@ #include #include +#ifdef FAIM_USEPTHREADS +#include +#define faim_mutex_t pthread_mutex_t +#define faim_mutex_init pthread_mutex_init +#define faim_mutex_lock pthread_mutex_lock +#define faim_mutex_unlock pthread_mutex_unlock +#endif + #ifdef _WIN32 #include #include @@ -121,6 +133,9 @@ time_t lastactivity; /* time of last transmit */ int forcedlatency; struct aim_rxcblist_t *handlerlist; +#ifdef FAIM_USEPTHREADS + faim_mutex_t active; +#endif }; /* struct for incoming commands */ @@ -180,10 +195,15 @@ /* * TX/RX queues */ - struct command_tx_struct *queue_outgoing; + struct command_tx_struct *queue_outgoing; struct command_rx_struct *queue_incoming; /* + * Tx Enqueuing function + */ + int (*tx_enqueue)(struct aim_session_t *, struct command_tx_struct *); + + /* * This is a dreadful solution to the what-room-are-we-joining * problem. (There's no connection between the service * request and the resulting redirect.) @@ -301,7 +321,10 @@ int aim_parse_last_bad(struct aim_session_t *, struct command_rx_struct *, ...); struct command_tx_struct *aim_tx_new(int, struct aim_conn_t *, int); -int aim_tx_enqueue(struct aim_session_t *, struct command_tx_struct *); +int aim_tx_enqueue__queuebased(struct aim_session_t *, struct command_tx_struct *); +int aim_tx_enqueue__immediate(struct aim_session_t *, struct command_tx_struct *); +#define aim_tx_enqueue(x, y) ((*(x->tx_enqueue))(x, y)) +int aim_tx_sendframe(struct command_tx_struct *cur); u_int aim_get_next_txseqnum(struct aim_conn_t *); int aim_tx_flushqueue(struct aim_session_t *); int aim_tx_printqueue(struct aim_session_t *); diff -r 29e1669b006b -r 501e09c51cbc libfaim/aim_conn.c --- a/libfaim/aim_conn.c Mon May 29 00:56:37 2000 +0000 +++ b/libfaim/aim_conn.c Mon May 29 20:30:48 2000 +0000 @@ -11,18 +11,9 @@ void aim_connrst(struct aim_session_t *sess) { int i; - for (i = 0; i < AIM_CONN_MAX; i++) - { - sess->conns[i].fd = -1; - sess->conns[i].type = -1; - sess->conns[i].status = 0; - sess->conns[i].seqnum = 0; - sess->conns[i].lastactivity = 0; - sess->conns[i].forcedlatency = 0; - aim_clearhandlers(&(sess->conns[i])); - sess->conns[i].handlerlist = NULL; - } - + for (i = 0; i < AIM_CONN_MAX; i++) { + aim_conn_close(&sess->conns[i]); + } } struct aim_conn_t *aim_conn_getnext(struct aim_session_t *sess) @@ -48,6 +39,7 @@ if (deadconn->priv) free(deadconn->priv); deadconn->priv = NULL; + faim_mutex_init(&deadconn->active, NULL); } struct aim_conn_t *aim_getconn_type(struct aim_session_t *sess, @@ -100,13 +92,12 @@ * */ - for(i=0;istatus = (h_errno | AIM_CONN_STATUS_RESOLVERR); - return connstruct; - } + if (hp == NULL) { + connstruct->status = (h_errno | AIM_CONN_STATUS_RESOLVERR); + return connstruct; + } memset(&sa.sin_zero, 0, 8); sa.sin_port = htons(port); @@ -127,12 +117,11 @@ connstruct->fd = socket(hp->h_addrtype, SOCK_STREAM, 0); ret = connect(connstruct->fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)); - if( ret < 0) - { - connstruct->fd = -1; - connstruct->status = (errno | AIM_CONN_STATUS_CONNERR); - return connstruct; - } + if(ret < 0) { + connstruct->fd = -1; + connstruct->status = (errno | AIM_CONN_STATUS_CONNERR); + return connstruct; + } return connstruct; } @@ -140,8 +129,8 @@ int aim_conngetmaxfd(struct aim_session_t *sess) { int i,j; - j=0; - for (i=0;iconns[i].fd > j) j = sess->conns[i].fd; return j; @@ -150,8 +139,8 @@ int aim_countconn(struct aim_session_t *sess) { int i,cnt; - cnt = 0; - for (i=0;iconns[i].fd > -1) cnt++; return cnt; @@ -239,8 +228,6 @@ void aim_session_init(struct aim_session_t *sess) { - int i; - if (!sess) return; @@ -250,23 +237,19 @@ sess->logininfo.email = NULL; sess->logininfo.regstatus = 0x00; - for (i = 0; i < AIM_CONN_MAX; i++) - { - sess->conns[i].fd = -1; - sess->conns[i].type = -1; - sess->conns[i].status = 0; - sess->conns[i].seqnum = 0; - sess->conns[i].lastactivity = 0; - sess->conns[i].forcedlatency = 0; - sess->conns[i].handlerlist = NULL; - sess->conns[i].priv = NULL; - } - + aim_connrst(sess); + sess->queue_outgoing = NULL; sess->queue_incoming = NULL; sess->pendingjoin = NULL; sess->outstanding_snacs = NULL; sess->snac_nextid = 0x00000001; + /* + * This must always be set. Default to the queue-based + * version for back-compatibility. + */ + sess->tx_enqueue = &aim_tx_enqueue__queuebased; + return; } diff -r 29e1669b006b -r 501e09c51cbc libfaim/aim_misc.c --- a/libfaim/aim_misc.c Mon May 29 00:56:37 2000 +0000 +++ b/libfaim/aim_misc.c Mon May 29 20:30:48 2000 +0000 @@ -648,7 +648,7 @@ } /* - * aim_bos_reqicbmparaminfo() +* aim_bos_reqicbmparaminfo() * * Request ICBM parameter information. * @@ -658,3 +658,4 @@ { return aim_genericreq_n(sess, conn, 0x0004, 0x0004); } + diff -r 29e1669b006b -r 501e09c51cbc libfaim/aim_rxhandlers.c --- a/libfaim/aim_rxhandlers.c Mon May 29 00:56:37 2000 +0000 +++ b/libfaim/aim_rxhandlers.c Mon May 29 20:30:48 2000 +0000 @@ -5,7 +5,7 @@ * with aim_rxdispatch(), the Rx dispatcher. Queue/list management is * actually done in aim_rxqueue.c. * - * Changes by Eric Warmenhoven, Wed May 24 09:33:38 UTC 2000: + * Changes by EWarmenhoven, Wed May 24 09:33:38 UTC 2000: * - there were some "bleck" printf's i changed to faimdprintf's. * */ diff -r 29e1669b006b -r 501e09c51cbc libfaim/aim_rxqueue.c --- a/libfaim/aim_rxqueue.c Mon May 29 00:56:37 2000 +0000 +++ b/libfaim/aim_rxqueue.c Mon May 29 20:30:48 2000 +0000 @@ -31,10 +31,13 @@ * 2 short -- Sequence number * 4 short -- Number of data bytes that follow. */ + faim_mutex_lock(&conn->active); if (read(conn->fd, generic, 6) < 6){ aim_conn_close(conn); + faim_mutex_unlock(&conn->active); return -1; } + faim_mutex_unlock(&conn->active); /* * This shouldn't happen unless the socket breaks, the server breaks, @@ -72,12 +75,15 @@ } /* read the data portion of the packet */ + faim_mutex_lock(&conn->active); if (read(conn->fd, newrx->data, newrx->commandlen) < newrx->commandlen){ free(newrx->data); free(newrx); aim_conn_close(conn); + faim_mutex_unlock(&conn->active); return -1; } + faim_mutex_unlock(&conn->active); newrx->conn = conn; diff -r 29e1669b006b -r 501e09c51cbc libfaim/aim_txqueue.c --- a/libfaim/aim_txqueue.c Mon May 29 00:56:37 2000 +0000 +++ b/libfaim/aim_txqueue.c Mon May 29 20:30:48 2000 +0000 @@ -3,11 +3,6 @@ * * Herein lies all the mangement routines for the transmit (Tx) queue. * - * Changes by EWarmenhoven Fri May 26 22:52:46 UTC 2000: - * - added aim_tx_flushqueue() to the end of aim_tx_enqueue() so that I don't - * have to worry about it any more. mid tells me that doing so will solve the - * 100% bug. Thanks mid! - * */ #include @@ -24,8 +19,10 @@ { struct command_tx_struct *new; - if (!conn) + if (!conn) { + printf("aim_tx_new: ERROR: no connection specified\n"); return NULL; + } new = (struct command_tx_struct *)malloc(sizeof(struct command_tx_struct)); if (!new) @@ -44,7 +41,7 @@ } /* - * aim_tx_enqeue() + * aim_tx_enqeue__queuebased() * * The overall purpose here is to enqueue the passed in command struct * into the outgoing (tx) queue. Basically... @@ -55,9 +52,12 @@ * 5) Unlock the struct once it's linked in * 6) Return * + * Note that this is only used when doing queue-based transmitting; + * that is, when sess->tx_enqueue is set to &aim_tx_enqueue__queuebased. + * */ -int aim_tx_enqueue(struct aim_session_t *sess, - struct command_tx_struct *newpacket) +int aim_tx_enqueue__queuebased(struct aim_session_t *sess, + struct command_tx_struct *newpacket) { struct command_tx_struct *cur; @@ -92,8 +92,40 @@ faimdprintf(2, "back from aim_tx_printqueue()\n"); #endif - /* mid tells me this should solve a lot of my problems */ - aim_tx_flushqueue(sess); + return 0; +} + +/* + * aim_tx_enqueue__immediate() + * + * Parallel to aim_tx_enqueue__queuebased, however, this bypasses + * the whole queue mess when you want immediate writes to happen. + * + * Basically the same as its __queuebased couterpart, however + * instead of doing a list append, it just calls aim_tx_sendframe() + * right here. + * + */ +int aim_tx_enqueue__immediate(struct aim_session_t *sess, struct command_tx_struct *newpacket) +{ + if (newpacket->conn == NULL) { + faimdprintf(1, "aim_tx_enqueue: ERROR: packet has no connection\n"); + if (newpacket->data) + free(newpacket->data); + free(newpacket); + return -1; + } + + newpacket->seqnum = aim_get_next_txseqnum(newpacket->conn); + + newpacket->lock = 1; /* lock */ + newpacket->sent = 0; /* not sent yet */ + + aim_tx_sendframe(newpacket); + + if (newpacket->data) + free(newpacket->data); + free(newpacket); return 0; } @@ -169,10 +201,72 @@ * 9) Step to next struct in list and go back to 1. * */ +int aim_tx_sendframe(struct command_tx_struct *cur) +{ + u_char *curPacket; + + if (!cur) + return -1; /* fatal */ + + cur->lock = 1; /* lock the struct */ + + /* allocate full-packet buffer */ + curPacket = (char *) malloc(cur->commandlen + 6); + + /* command byte */ + curPacket[0] = 0x2a; + + /* type/family byte */ + curPacket[1] = cur->type; + + /* bytes 3+4: word: FLAP sequence number */ + aimutil_put16(curPacket+2, cur->seqnum); + + /* bytes 5+6: word: SNAC len */ + aimutil_put16(curPacket+4, cur->commandlen); + + /* bytes 7 and on: raw: SNAC data */ /* XXX: ye gods! get rid of this! */ + memcpy(&(curPacket[6]), cur->data, cur->commandlen); + + /* full image of raw packet data now in curPacket */ + faim_mutex_lock(&cur->conn->active); + if ( (u_int)write(cur->conn->fd, curPacket, (cur->commandlen + 6)) != (cur->commandlen + 6)) { + faim_mutex_unlock(&cur->conn->active); + printf("\nWARNING: Error in sending packet 0x%4x -- will try again next time\n\n", cur->seqnum); + cur->sent = 0; /* mark it unsent */ + return 0; /* bail out -- continuable error */ + } else { + faimdprintf(2, "\nSENT 0x%4x\n\n", cur->seqnum); + + cur->sent = 1; /* mark the struct as sent */ + cur->conn->lastactivity = time(NULL); + } + faim_mutex_unlock(&cur->conn->active); + +#if debug > 2 + faimdprintf(2, "\nPacket:"); + for (i = 0; i < (cur->commandlen + 6); i++) { + if ((i % 8) == 0) { + faimdprintf(2, "\n\t"); + } + if (curPacket[i] >= ' ' && curPacket[i]<127) { + faimdprintf(2, "%c=%02x ", curPacket[i], curPacket[i]); + } else { + faimdprintf(2, "0x%2x ", curPacket[i]); + } + } + faimdprintf(2, "\n"); +#endif + cur->lock = 0; /* unlock the struct */ + free(curPacket); /* free up full-packet buffer */ + + return 1; /* success */ +} + int aim_tx_flushqueue(struct aim_session_t *sess) { struct command_tx_struct *cur; - u_char *curPacket = NULL; + #if debug > 1 int i = 0; #endif @@ -193,54 +287,9 @@ /* FIXME FIXME -- should be a break! we dont want to block the upper layers */ sleep((cur->conn->lastactivity + cur->conn->forcedlatency) - time(NULL)); } - - cur->lock = 1; /* lock the struct */ - - /* allocate full-packet buffer */ - curPacket = (char *) malloc(cur->commandlen + 6); - - /* command byte */ - curPacket[0] = 0x2a; - - /* type/family byte */ - curPacket[1] = cur->type; - - /* bytes 3+4: word: FLAP sequence number */ - aimutil_put16(curPacket+2, cur->seqnum); - /* bytes 5+6: word: SNAC len */ - aimutil_put16(curPacket+4, cur->commandlen); - - /* bytes 7 and on: raw: SNAC data */ - memcpy(&(curPacket[6]), cur->data, cur->commandlen); - - /* full image of raw packet data now in curPacket */ - if ( (u_int)write(cur->conn->fd, curPacket, (cur->commandlen + 6)) != (cur->commandlen + 6)) { - printf("\nWARNING: Error in sending packet 0x%4x -- will try again next time\n\n", cur->seqnum); - cur->sent = 0; /* mark it unsent */ - continue; /* bail out */ - } else { - faimdprintf(2, "\nSENT 0x%4x\n\n", cur->seqnum); - - cur->sent = 1; /* mark the struct as sent */ - cur->conn->lastactivity = time(NULL); - } -#if debug > 2 - faimdprintf(2, "\nPacket:"); - for (i = 0; i < (cur->commandlen + 6); i++) { - if ((i % 8) == 0) { - faimdprintf(2, "\n\t"); - } - if (curPacket[i] >= ' ' && curPacket[i]<127) { - faimdprintf(2, "%c=%02x ", curPacket[i], curPacket[i]); - } else { - faimdprintf(2, "0x%2x ", curPacket[i]); - } - } - faimdprintf(2, "\n"); -#endif - cur->lock = 0; /* unlock the struct */ - free(curPacket); /* free up full-packet buffer */ + if (aim_tx_sendframe(cur) == -1) + break; } } diff -r 29e1669b006b -r 501e09c51cbc libfaim/faimconfig.h --- a/libfaim/faimconfig.h Mon May 29 00:56:37 2000 +0000 +++ b/libfaim/faimconfig.h Mon May 29 20:30:48 2000 +0000 @@ -6,6 +6,13 @@ * that they'll get set here. Notably, the 'debug' of this file is _not_ * the same as the frontend 'debug'. They can be different values. * + * Changes by EWarmenhoven Mon May 29 20:08:17 UTC 2000: + * - since gaim requires pthreads to be present at ./configure-time, all + * systems gaim runs on theoretically have pthreads (this may not be true + * since gaim does not use pthreads itself, hence there are ways around it). + * Therefore, #define FAIM_USEPTHREADS should not be surrounded by + * #ifdef __linux__/#endif. + * */ #ifndef __FAIMCONFIG_H__ @@ -103,4 +110,19 @@ */ #define AIMUTIL_USEMACROS +/* + * Select whether or not to use POSIX thread functionality. + * + * Default: defined on Linux, otherwise undefined + */ +/* gaim requires pthreads (though only at configure time), so this applies to + * more than just linux +#ifdef __linux__ +#define FAIM_USEPTHREADS +#endif +*/ +#define FAIM_USEPTHREADS + #endif /* __FAIMCONFIG_H__ */ + + diff -r 29e1669b006b -r 501e09c51cbc src/oscar.c --- a/src/oscar.c Mon May 29 00:56:37 2000 +0000 +++ b/src/oscar.c Mon May 29 20:30:48 2000 +0000 @@ -92,6 +92,10 @@ sess = g_new0(struct aim_session_t, 1); aim_session_init(sess); + /* we need an immediate queue because we don't use a while-loop to + * see if things need to be sent. */ + sess->tx_enqueue = &aim_tx_enqueue__immediate; + gaim_sess = sess; sprintf(buf, "Looking up %s", FAIM_LOGIN_SERVER); set_login_progress(1, buf); @@ -222,6 +226,7 @@ hide_login_progress("Could Not Connect"); return -1; } + gaim_conn = bosconn; aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ACK, AIM_CB_ACK_ACK, NULL, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_SERVERREADY, gaim_server_ready, 0); @@ -320,9 +325,6 @@ aim_bos_reqservice(sess, command->conn, AIM_CONN_TYPE_CHATNAV); - gaim_sess = sess; - gaim_conn = command->conn; - debug_print("Roger that, all systems go\n"); #ifdef USE_APPLET make_buddy();