From a25832e66b80e7159f37795cff5593b748ac5f59 Mon Sep 17 00:00:00 2001 From: mid Date: Tue, 28 Dec 1999 00:51:17 +0000 Subject: [PATCH] Integrated session changes needed for Jabber transport. Lots of changes. --- BUGS | 4 + CHANGES | 17 ++ Makefile | 8 +- aim.h | 328 ------------------------ aim_auth.c | 49 ++-- aim_buddylist.c | 34 +-- aim_cbtypes.h | 177 ------------- aim_chat.c | 19 +- aim_chatnav.c | 2 +- aim_conn.c | 125 ++++++--- aim_im.c | 85 ++++-- aim_info.c | 54 +++- aim_login.c | 14 +- aim_logoff.c | 10 +- aim_misc.c | 161 +++++++----- aim_rxhandlers.c | 232 +++++++++-------- aim_rxqueue.c | 49 ++-- aim_search.c | 18 +- aim_snac.c | 101 ++++---- aim_tlv.c | 2 +- aim_txqueue.c | 130 +++++----- aim_util.c | 2 +- aim_global.c => deprecated/aim_global.c | 2 +- faimconfig.h | 81 ------ 24 files changed, 660 insertions(+), 1044 deletions(-) delete mode 100644 aim.h delete mode 100644 aim_cbtypes.h rename aim_global.c => deprecated/aim_global.c (96%) delete mode 100644 faimconfig.h diff --git a/BUGS b/BUGS index 81daa41..57bcfbe 100644 --- a/BUGS +++ b/BUGS @@ -31,3 +31,7 @@ aim_snac.c aim_tlv.c --------- - Newer TLV bulk-read routines most likely have leakage somewhere. + +aim_rxhandlers.c +---------------- + - Need a better solution than sleep() diff --git a/CHANGES b/CHANGES index d1a0d7a..5f1f7b0 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,23 @@ No release numbers ------------------ + - Sun Dec 26 22:59:10 UTC 1999 + - Renamed login_phase1_struct to aim_login_struct + - Changed cookie and sn to be static arrays in aim_login_struct + - Integrated the Jabber-faim changes. (temas) [BIG CLIENT CHANGES] + - Added aim_session_t, removed all global variables + - Changed all functions to accept a session pointer + - Removed aim_global.c + - Updated faimtest to use an aim_session_t. + - Removed all cases where logininfo was passed as vararg to client + - Fixed small bug in aim_newconn's 'fixing' of host:port addresses + - Added an install rule to the makefile (installs headers+so only!) + - Enabled USE_SNAC_FOR_IMS by default, assuming it got fixed + by n's new aim_snac.c from ages ago + - Implemented a middle handler for 0004/0001 message errors, added + snacid lookup to get illfated destination SN and pass to client + - Implemented a short middle handler for offgoing buddy. + - Fri Dec 24 21:30:06 UTC 1999 - Added an error-counting Read() that has been sitting in my inbox - Cleaned up header files, created aim_cbtypes.h. diff --git a/Makefile b/Makefile index 7fb63d9..e2be321 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,6 @@ LIBFAIM_OBJECTS = \ aim_login.o \ aim_logoff.o \ aim_misc.o \ - aim_global.o \ aim_buddylist.o \ aim_search.o \ aim_snac.o \ @@ -37,6 +36,11 @@ allutils: libfaim cd utils; \ make +install: libfaim + cp -r faim /usr/include + cp libfaim.so /usr/lib/$(SOFILENAME) + /sbin/ldconfig + cleanutils: @echo "LIBFAIM_INC = $$PWD" > utils/Makefile.dynamicrules; \ echo "LIBFAIM_LIB = $$PWD" >> utils/Makefile.dynamicrules; \ @@ -44,4 +48,4 @@ cleanutils: make clean clean: cleanutils - rm -f $(LIBFAIM_OBJECTS) $(SONAME) libfaim.a + rm -f $(LIBFAIM_OBJECTS) $(SONAME) libfaim.a *~ core diff --git a/aim.h b/aim.h deleted file mode 100644 index 52dbbc3..0000000 --- a/aim.h +++ /dev/null @@ -1,328 +0,0 @@ -/* - * Main libfaim header. Must be included in client for prototypes/macros. - * - */ - -#ifndef __AIM_H__ -#define __AIM_H__ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#ifdef _WIN32 -#include -#include -#include -#else -#include -#include -#include -#include -#include -#endif - -/* Portability stuff (DMP) */ - -#ifdef _WIN32 -#define sleep Sleep -#define strlen(x) (int)strlen(x) /* win32 has a unsigned size_t */ -#endif - -#if defined(_WIN32) || (defined(mach) && defined(__APPLE__)) -#define gethostbyname2(x,y) gethostbyname(x) /* revert to IPv4 */ -#endif - -/* - * Login Error codes - */ -#define AIM_CONNECT_ERROR -0x1 -#define AIM_SIGNON_TOO_SOON -0x4 -#define AIM_SERVICE_FULL -0x6f - -/* - * Current Maximum Length for Screen Names (not including NULL) - */ -#define MAXSNLEN 16 - -struct login_phase1_struct { - char *screen_name; - char *BOSIP; - char *cookie; - char *email; - u_short regstatus; -}; - -extern struct login_phase1_struct aim_logininfo; - -struct client_info_s { - char clientstring[100]; /* arbitrary number */ - int major; - int minor; - int build; - char country[3]; - char lang[3]; -}; - -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 -#endif - -/* - * These could be arbitrary, but its easier to use the actual AIM values - */ -#define AIM_CONN_TYPE_AUTH 0x0007 -#define AIM_CONN_TYPE_ADS 0x0005 -#define AIM_CONN_TYPE_BOS 2 -#define AIM_CONN_TYPE_CHAT 0x000e -#define AIM_CONN_TYPE_CHATNAV 0x000d - -#define AIM_CONN_STATUS_READY 0x0001 -#define AIM_CONN_STATUS_INTERNALERR 0x0002 -#define AIM_CONN_STATUS_RESOLVERR 0x80 -#define AIM_CONN_STATUS_CONNERR 0x40 - -struct aim_conn_t { - int fd; - int type; - int seqnum; - int status; - void *priv; /* misc data the client may want to store */ - time_t lastactivity; /* time of last transmit */ - int forcedlatency; - struct aim_rxcblist_t *handlerlist; -}; -struct aim_conn_t aim_conns[AIM_CONN_MAX]; - - -/* struct for incoming commands */ -struct command_rx_struct { - /* byte 1 assumed to always be 0x2a */ - char type; /* type code (byte 2) */ - u_int seqnum; /* sequence number (bytes 3 and 4) */ - u_int commandlen; /* total packet len - 6 (bytes 5 and 6) */ - u_char *data; /* packet data (from 7 byte on) */ - u_int lock; /* 0 = open, !0 = locked */ - u_int handled; /* 0 = new, !0 = been handled */ - struct aim_conn_t *conn; /* the connection it came in on... */ - struct command_rx_struct *next; /* ptr to next struct in list */ -}; - -/* struct for outgoing commands */ -struct command_tx_struct { - /* byte 1 assumed to be 0x2a */ - char type; /* type/family code */ - u_int seqnum; /* seqnum dynamically assigned on tx */ - u_int commandlen; /* SNAC length */ - u_char *data; /* packet data */ - u_int lock; /* 0 = open, !0 = locked */ - u_int sent; /* 0 = pending, !0 = has been sent */ - struct aim_conn_t *conn; - struct command_tx_struct *next; /* ptr to next struct in list */ -}; - -/* - * AIM User Info, Standard Form. - */ -struct aim_userinfo_s { - char sn[MAXSNLEN+1]; - u_short warnlevel; - u_short idletime; - u_short class; - u_long membersince; - u_long onlinesince; - u_long sessionlen; -}; - -/* - * TLV handling - */ - -/* Generic TLV structure. */ -struct aim_tlv_t { - u_short type; - u_short length; - u_char *value; -}; - -/* List of above. */ -struct aim_tlvlist_t { - struct aim_tlv_t *tlv; - struct aim_tlvlist_t *next; -}; - -/* TLV-handling functions */ -struct aim_tlvlist_t *aim_readtlvchain(u_char *buf, int maxlen); -void aim_freetlvchain(struct aim_tlvlist_t **list); -struct aim_tlv_t *aim_grabtlv(u_char *src); -struct aim_tlv_t *aim_grabtlvstr(u_char *src); -struct aim_tlv_t *aim_gettlv(struct aim_tlvlist_t *, u_short, int); -char *aim_gettlv_str(struct aim_tlvlist_t *, u_short, int); -int aim_puttlv (u_char *dest, struct aim_tlv_t *newtlv); -struct aim_tlv_t *aim_createtlv(void); -int aim_freetlv(struct aim_tlv_t **oldtlv); -int aim_puttlv_16(u_char *, u_short, u_short); - - -int aim_get_command(void); -int aim_rxdispatch(void); -int aim_logoff(void); - -typedef int (*rxcallback_t)(struct command_rx_struct *, ...); -int aim_register_callbacks(rxcallback_t *); - -u_long aim_genericreq_n(struct aim_conn_t *conn, u_short family, u_short subtype); -u_long aim_genericreq_l(struct aim_conn_t *conn, u_short family, u_short subtype, u_long *); -u_long aim_genericreq_s(struct aim_conn_t *conn, u_short family, u_short subtype, u_short *); - -/* aim_login.c */ -int aim_send_login (struct aim_conn_t *, char *, char *, struct client_info_s *); -int aim_encode_password(const char *, char *); - - -struct command_rx_struct *aim_purge_rxqueue(struct command_rx_struct *queue); - - -int aim_parse_unknown(struct command_rx_struct *command, ...); -int aim_parse_missed_im(struct command_rx_struct *, ...); -int aim_parse_last_bad(struct command_rx_struct *, ...); - -int aim_tx_enqueue(struct command_tx_struct *); -u_int aim_get_next_txseqnum(struct aim_conn_t *); -int aim_tx_flushqueue(void); -int aim_tx_printqueue(void); -int aim_tx_purgequeue(void); - -/* queue (linked list) pointers */ -extern struct command_tx_struct *aim_queue_outgoing; /* incoming commands */ -extern struct command_rx_struct *aim_queue_incoming; /* outgoing commands */ - -/* The default callback handler array */ -extern rxcallback_t aim_callbacks[]; - -struct aim_rxcblist_t { - u_short family; - u_short type; - rxcallback_t handler; - u_short flags; - struct aim_rxcblist_t *next; -}; - -int aim_conn_setlatency(struct aim_conn_t *conn, int newval); - -int aim_conn_addhandler(struct aim_conn_t *conn, u_short family, u_short type, rxcallback_t newhandler, u_short flags); -rxcallback_t aim_callhandler(struct aim_conn_t *conn, u_short family, u_short type); -int aim_clearhandlers(struct aim_conn_t *conn); - -extern struct aim_snac_t *aim_outstanding_snacs; -extern u_long aim_snac_nextid; - -/* - * Generic SNAC structure. Rarely if ever used. - */ -struct aim_snac_t { - u_long id; - u_short family; - u_short type; - u_short flags; - void *data; - time_t issuetime; - struct aim_snac_t *next; -}; -u_long aim_newsnac(struct aim_snac_t *newsnac); -struct aim_snac_t *aim_remsnac(u_long id); -int aim_cleansnacs(int maxage); -int aim_putsnac(u_char *, int, int, int, u_long); - - -void aim_connrst(void); -struct aim_conn_t *aim_conn_getnext(void); -void aim_conn_close(struct aim_conn_t *deadconn); -struct aim_conn_t *aim_getconn_type(int type); -struct aim_conn_t *aim_newconn(int type, char *dest); -int aim_conngetmaxfd(void); -struct aim_conn_t *aim_select(struct timeval *); -int aim_conn_isready(struct aim_conn_t *); -int aim_conn_setstatus(struct aim_conn_t *, int); - -/* aim_misc.c */ - -#define AIM_VISIBILITYCHANGE_PERMITADD 0x05 -#define AIM_VISIBILITYCHANGE_PERMITREMOVE 0x06 -#define AIM_VISIBILITYCHANGE_DENYADD 0x07 -#define AIM_VISIBILITYCHANGE_DENYREMOVE 0x08 - -u_long aim_bos_setidle(struct aim_conn_t *, u_long); -u_long aim_bos_changevisibility(struct aim_conn_t *, int, char *); -u_long aim_bos_setbuddylist(struct aim_conn_t *, char *); -u_long aim_bos_setprofile(struct aim_conn_t *, char *); -u_long aim_bos_setgroupperm(struct aim_conn_t *, u_long); -u_long aim_bos_clientready(struct aim_conn_t *); -u_long aim_bos_reqrate(struct aim_conn_t *); -u_long aim_bos_ackrateresp(struct aim_conn_t *); -u_long aim_bos_setprivacyflags(struct aim_conn_t *, u_long); -u_long aim_bos_reqpersonalinfo(struct aim_conn_t *); -u_long aim_bos_reqservice(struct aim_conn_t *, u_short); -u_long aim_bos_reqrights(struct aim_conn_t *); -u_long aim_bos_reqbuddyrights(struct aim_conn_t *); -u_long aim_bos_reqlocaterights(struct aim_conn_t *); -u_long aim_bos_reqicbmparaminfo(struct aim_conn_t *); - -/* aim_rxhandlers.c */ -int aim_register_callbacks(rxcallback_t *); -int aim_rxdispatch(void); -int aim_authparse(struct command_rx_struct *); -int aim_handleredirect_middle(struct command_rx_struct *, ...); -int aim_parse_unknown(struct command_rx_struct *, ...); -int aim_parse_missed_im(struct command_rx_struct *, ...); -int aim_parse_last_bad(struct command_rx_struct *, ...); -int aim_parse_generalerrs(struct command_rx_struct *command, ...); - -/* aim_im.c */ -#define AIM_IMFLAGS_AWAY 0x01 /* mark as an autoreply */ -#define AIM_IMFLAGS_ACK 0x02 /* request a receipt notice */ -u_long aim_send_im(struct aim_conn_t *, char *, u_int, char *); -int aim_parse_incoming_im_middle(struct command_rx_struct *); -u_long aim_seticbmparam(struct aim_conn_t *conn); - -/* aim_info.c */ -u_long aim_getinfo(struct aim_conn_t *, const char *); -int aim_extractuserinfo(u_char *, struct aim_userinfo_s *); -int aim_parse_userinfo_middle(struct command_rx_struct *); -int aim_parse_oncoming_middle(struct command_rx_struct *); - -/* aim_auth.c */ -int aim_auth_sendcookie(struct aim_conn_t *, char *); -u_long aim_auth_clientready(struct aim_conn_t *); -u_long aim_auth_changepasswd(struct aim_conn_t *, char *, char *); - -/* aim_buddylist.c */ -u_long aim_add_buddy(struct aim_conn_t *, char *); -u_long aim_remove_buddy(struct aim_conn_t *, char *); - -/* aim_search.c */ -u_long aim_usersearch_address(struct aim_conn_t *, char *); -/* u_long aim_usersearch_name(struct aim_conn_t *, char *); */ - -/* aim_util.c */ -int aimutil_put8(u_char *, u_char); -u_char aimutil_get8(u_char *buf); -int aimutil_put16(u_char *, u_short); -u_short aimutil_get16(u_char *); -int aimutil_put32(u_char *, u_long); -u_long aimutil_get32(u_char *); -int aimutil_putstr(u_char *, const u_char *, int); -int aimutil_tokslen(char *toSearch, int index, char dl); -int aimutil_itemcnt(char *toSearch, char dl); -char *aimutil_itemidx(char *toSearch, int index, char dl); - -#endif /* __AIM_H__ */ - diff --git a/aim_auth.c b/aim_auth.c index bdb279a..eb98ac9 100644 --- a/aim_auth.c +++ b/aim_auth.c @@ -5,10 +5,12 @@ */ -#include "aim.h" +#include /* this just pushes the passed cookie onto the passed connection -- NO SNAC! */ -int aim_auth_sendcookie(struct aim_conn_t *conn, char *chipsahoy) +int aim_auth_sendcookie(struct aim_session_t *sess, + struct aim_conn_t *conn, + u_char *chipsahoy) { struct command_tx_struct newpacket; int curbyte=0; @@ -16,27 +18,28 @@ int aim_auth_sendcookie(struct aim_conn_t *conn, char *chipsahoy) newpacket.lock = 1; if (conn==NULL) - newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_AUTH); + newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_AUTH); else newpacket.conn = conn; newpacket.type = 0x0001; /* channel 1 (no SNACs, you know) */ - newpacket.commandlen = 4 + 2 + 2 + 0x100; + newpacket.commandlen = 4 + 2 + 2 + AIM_COOKIELEN; newpacket.data = (char *) calloc(1, newpacket.commandlen); curbyte += aimutil_put16(newpacket.data+curbyte, 0x0000); curbyte += aimutil_put16(newpacket.data+curbyte, 0x0001); curbyte += aimutil_put16(newpacket.data+curbyte, 0x0006); - curbyte += aimutil_put16(newpacket.data+curbyte, 0x0100); - memcpy(&(newpacket.data[curbyte]), chipsahoy, 0x100); + curbyte += aimutil_put16(newpacket.data+curbyte, AIM_COOKIELEN); + memcpy(&(newpacket.data[curbyte]), chipsahoy, AIM_COOKIELEN); - aim_tx_enqueue(&newpacket); + aim_tx_enqueue(sess, &newpacket); return 0; } -u_long aim_auth_clientready(struct aim_conn_t *conn) +u_long aim_auth_clientready(struct aim_session_t *sess, + struct aim_conn_t *conn) { struct command_tx_struct newpacket; int curbyte = 0; @@ -44,16 +47,16 @@ u_long aim_auth_clientready(struct aim_conn_t *conn) newpacket.lock = 1; if (conn==NULL) - newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_AUTH); + newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_AUTH); else newpacket.conn = conn; newpacket.type = 0x0002; newpacket.commandlen = 26; - newpacket.data = (char *) malloc(newpacket.commandlen); + newpacket.data = (u_char *) malloc(newpacket.commandlen); - curbyte += aim_putsnac(newpacket.data+curbyte, 0x0001, 0x0002, 0x0000, aim_snac_nextid); + curbyte += aim_putsnac(newpacket.data+curbyte, 0x0001, 0x0002, 0x0000, sess->snac_nextid); curbyte += aimutil_put16(newpacket.data+curbyte, 0x0001); curbyte += aimutil_put16(newpacket.data+curbyte, 0x0002); curbyte += aimutil_put16(newpacket.data+curbyte, 0x0001); @@ -63,25 +66,27 @@ u_long aim_auth_clientready(struct aim_conn_t *conn) curbyte += aimutil_put16(newpacket.data+curbyte, 0x0001); curbyte += aimutil_put16(newpacket.data+curbyte, 0x0001); - aim_tx_enqueue(&newpacket); + aim_tx_enqueue(sess, &newpacket); { struct aim_snac_t snac; - snac.id = aim_snac_nextid; + snac.id = sess->snac_nextid; snac.family = 0x0001; snac.type = 0x0004; snac.flags = 0x0000; snac.data = NULL; - aim_newsnac(&snac); + aim_newsnac(sess, &snac); } - return (aim_snac_nextid++); + return (sess->snac_nextid++); } -u_long aim_auth_changepasswd(struct aim_conn_t *conn, char *new, char *current) +u_long aim_auth_changepasswd(struct aim_session_t *sess, + struct aim_conn_t *conn, + char *new, char *current) { struct command_tx_struct newpacket; int i; @@ -89,7 +94,7 @@ u_long aim_auth_changepasswd(struct aim_conn_t *conn, char *new, char *current) newpacket.lock = 1; if (conn==NULL) - newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_AUTH); + newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_AUTH); else newpacket.conn = conn; @@ -98,7 +103,7 @@ u_long aim_auth_changepasswd(struct aim_conn_t *conn, char *new, char *current) newpacket.commandlen = 10 + 4 + strlen(current) + 4 + strlen(new); newpacket.data = (char *) malloc(newpacket.commandlen); - aim_putsnac(newpacket.data, 0x0007, 0x0004, 0x0000, aim_snac_nextid); + aim_putsnac(newpacket.data, 0x0007, 0x0004, 0x0000, sess->snac_nextid); /* current password TLV t(0002) */ i = 10; @@ -117,20 +122,20 @@ u_long aim_auth_changepasswd(struct aim_conn_t *conn, char *new, char *current) memcpy(&(newpacket.data[i]), new, strlen(new)); i+=strlen(new); - aim_tx_enqueue(&newpacket); + aim_tx_enqueue(sess, &newpacket); { struct aim_snac_t snac; - snac.id = aim_snac_nextid; + snac.id = sess->snac_nextid; snac.family = 0x0001; snac.type = 0x0004; snac.flags = 0x0000; snac.data = NULL; - aim_newsnac(&snac); + aim_newsnac(sess, &snac); } - return (aim_snac_nextid++); + return (sess->snac_nextid++); } diff --git a/aim_buddylist.c b/aim_buddylist.c index b9ac86a..5fdd646 100644 --- a/aim_buddylist.c +++ b/aim_buddylist.c @@ -1,5 +1,5 @@ -#include +#include /* * aim_add_buddy() @@ -7,7 +7,9 @@ * Adds a single buddy to your buddy list after login. * */ -u_long aim_add_buddy(struct aim_conn_t *conn, char *sn ) +u_long aim_add_buddy(struct aim_session_t *sess, + struct aim_conn_t *conn, + char *sn ) { struct command_tx_struct newpacket; @@ -17,26 +19,26 @@ u_long aim_add_buddy(struct aim_conn_t *conn, char *sn ) if (conn) newpacket.conn = conn; else - newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS); + newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); newpacket.lock = 1; newpacket.type = 0x0002; newpacket.commandlen = 11 + strlen( sn ); newpacket.data = (char *)malloc( newpacket.commandlen ); - aim_putsnac(newpacket.data, 0x0003, 0x0004, 0x0000, aim_snac_nextid); + aim_putsnac(newpacket.data, 0x0003, 0x0004, 0x0000, sess->snac_nextid); /* length of screenname */ newpacket.data[10] = strlen( sn ); memcpy( &(newpacket.data[11]), sn, strlen( sn ) ); - aim_tx_enqueue( &newpacket ); + aim_tx_enqueue(sess, &newpacket ); { struct aim_snac_t snac; - snac.id = aim_snac_nextid; + snac.id = sess->snac_nextid; snac.family = 0x0003; snac.type = 0x0004; snac.flags = 0x0000; @@ -44,13 +46,15 @@ u_long aim_add_buddy(struct aim_conn_t *conn, char *sn ) snac.data = malloc( strlen( sn ) + 1 ); memcpy( snac.data, sn, strlen( sn ) + 1 ); - aim_newsnac( &snac ); + aim_newsnac(sess, &snac); } - return( aim_snac_nextid++ ); + return( sess->snac_nextid++ ); } -u_long aim_remove_buddy(struct aim_conn_t *conn, char *sn ) +u_long aim_remove_buddy(struct aim_session_t *sess, + struct aim_conn_t *conn, + char *sn ) { struct command_tx_struct newpacket; @@ -60,26 +64,26 @@ u_long aim_remove_buddy(struct aim_conn_t *conn, char *sn ) if (conn) newpacket.conn = conn; else - newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS); + newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); newpacket.lock = 1; newpacket.type = 0x0002; newpacket.commandlen = 11 + strlen(sn); newpacket.data = (char *)malloc( newpacket.commandlen ); - aim_putsnac(newpacket.data, 0x0003, 0x0005, 0x0000, aim_snac_nextid); + aim_putsnac(newpacket.data, 0x0003, 0x0005, 0x0000, sess->snac_nextid); /* length of screenname */ newpacket.data[10] = strlen( sn ); memcpy( &(newpacket.data[11]), sn, strlen( sn ) ); - aim_tx_enqueue( &newpacket ); + aim_tx_enqueue(sess, &newpacket ); { struct aim_snac_t snac; - snac.id = aim_snac_nextid; + snac.id = sess->snac_nextid; snac.family = 0x0003; snac.type = 0x0005; snac.flags = 0x0000; @@ -87,9 +91,9 @@ u_long aim_remove_buddy(struct aim_conn_t *conn, char *sn ) snac.data = malloc( strlen( sn ) + 1 ); memcpy( snac.data, sn, strlen( sn ) + 1 ); - aim_newsnac( &snac ); + aim_newsnac(sess, &snac ); } - return( aim_snac_nextid++ ); + return( sess->snac_nextid++ ); } diff --git a/aim_cbtypes.h b/aim_cbtypes.h deleted file mode 100644 index c900083..0000000 --- a/aim_cbtypes.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - * AIM Callback Types - * - */ -#ifndef __AIM_CBTYPES_H__ -#define __AIM_CBTYPES_H__ - -/* - * SNAC Families. - */ -#define AIM_CB_FAM_ACK 0x0000 -#define AIM_CB_FAM_GEN 0x0001 -#define AIM_CB_FAM_LOC 0x0002 -#define AIM_CB_FAM_BUD 0x0003 -#define AIM_CB_FAM_MSG 0x0004 -#define AIM_CB_FAM_ADS 0x0005 -#define AIM_CB_FAM_INV 0x0006 -#define AIM_CB_FAM_ADM 0x0007 -#define AIM_CB_FAM_POP 0x0008 -#define AIM_CB_FAM_BOS 0x0009 -#define AIM_CB_FAM_LOK 0x000a -#define AIM_CB_FAM_STS 0x000b -#define AIM_CB_FAM_TRN 0x000c -#define AIM_CB_FAM_CTN 0x000d /* ChatNav */ -#define AIM_CB_FAM_CHT 0x000e /* Chat */ -#define AIM_CB_FAM_SPECIAL 0xffff /* Internal libfaim use */ - -/* - * SNAC Family: Ack. - * - * Not really a family, but treating it as one really - * helps it fit into the libfaim callback structure better. - * - */ -#define AIM_CB_ACK_ACK 0x0001 - -/* - * SNAC Family: General. - */ -#define AIM_CB_GEN_ERROR 0x0001 -#define AIM_CB_GEN_CLIENTREADY 0x0002 -#define AIM_CB_GEN_SERVERREADY 0x0003 -#define AIM_CB_GEN_SERVICEREQ 0x0004 -#define AIM_CB_GEN_REDIRECT 0x0005 -#define AIM_CB_GEN_RATEINFOREQ 0x0006 -#define AIM_CB_GEN_RATEINFO 0x0007 -#define AIM_CB_GEN_RATEINFOACK 0x0008 -#define AIM_CB_GEN_RATECHANGE 0x000a -#define AIM_CB_GEN_SERVERPAUSE 0x000b -#define AIM_CB_GEN_SERVERRESUME 0x000d -#define AIM_CB_GEN_REQSELFINFO 0x000e -#define AIM_CB_GEN_SELFINFO 0x000f -#define AIM_CB_GEN_EVIL 0x0010 -#define AIM_CB_GEN_SETIDLE 0x0011 -#define AIM_CB_GEN_MIGRATIONREQ 0x0012 -#define AIM_CB_GEN_MOTD 0x0013 -#define AIM_CB_GEN_SETPRIVFLAGS 0x0014 -#define AIM_CB_GEN_WELLKNOWNURL 0x0015 -#define AIM_CB_GEN_NOP 0x0016 -#define AIM_CB_GEN_DEFAULT 0xffff - -/* - * SNAC Family: Location Services. - */ -#define AIM_CB_LOC_ERROR 0x0001 -#define AIM_CB_LOC_REQRIGHTS 0x0002 -#define AIM_CB_LOC_RIGHTSINFO 0x0003 -#define AIM_CB_LOC_SETUSERINFO 0x0004 -#define AIM_CB_LOC_REQUSERINFO 0x0005 -#define AIM_CB_LOC_USERINFO 0x0006 -#define AIM_CB_LOC_WATCHERSUBREQ 0x0007 -#define AIM_CB_LOC_WATCHERNOT 0x0008 -#define AIM_CB_LOC_DEFAULT 0xffff - -/* - * SNAC Family: Buddy List Management Services. - */ -#define AIM_CB_BUD_ERROR 0x0001 -#define AIM_CB_BUD_REQRIGHTS 0x0002 -#define AIM_CB_BUD_RIGHTSINFO 0x0003 -#define AIM_CB_BUD_ADDBUDDY 0x0004 -#define AIM_CB_BUD_REMBUDDY 0x0005 -#define AIM_CB_BUD_REJECT 0x000a -#define AIM_CB_BUD_ONCOMING 0x000b -#define AIM_CB_BUD_OFFGOING 0x000c -#define AIM_CB_BUD_DEFAULT 0xffff - -/* - * SNAC Family: Messeging Services. - */ -#define AIM_CB_MSG_ERROR 0x0001 -#define AIM_CB_MSG_PARAMINFO 0x0005 -#define AIM_CB_MSG_INCOMING 0x0007 -#define AIM_CB_MSG_EVIL 0x0009 -#define AIM_CB_MSG_MISSEDCALL 0x000a -#define AIM_CB_MSG_CLIENTERROR 0x000b -#define AIM_CB_MSG_ACK 0x000c -#define AIM_CB_MSG_DEFAULT 0xffff - -/* - * SNAC Family: Advertisement Services - */ -#define AIM_CB_ADS_ERROR 0x0001 -#define AIM_CB_ADS_DEFAULT 0xffff - -/* - * SNAC Family: Invitation Services. - */ -#define AIM_CB_INV_ERROR 0x0001 -#define AIM_CB_INV_DEFAULT 0xffff - -/* - * SNAC Family: Administrative Services. - */ -#define AIM_CB_ADM_ERROR 0x0001 -#define AIM_CB_ADM_INFOCHANGE_REPLY 0x0005 -#define AIM_CB_ADM_DEFAULT 0xffff - -/* - * SNAC Family: Popup Messages - */ -#define AIM_CB_POP_ERROR 0x0001 -#define AIM_CB_POP_DEFAULT 0xffff - -/* - * SNAC Family: Misc BOS Services. - */ -#define AIM_CB_BOS_ERROR 0x0001 -#define AIM_CB_BOS_DEFAULT 0xffff - -/* - * SNAC Family: User Lookup Services - */ -#define AIM_CB_LOK_ERROR 0x0001 -#define AIM_CB_LOK_DEFAULT 0xffff - -/* - * SNAC Family: User Status Services - */ -#define AIM_CB_STS_ERROR 0x0001 -#define AIM_CB_STS_SETREPORTINTERVAL 0x0002 -#define AIM_CB_STS_REPORTACK 0x0004 -#define AIM_CB_STS_DEFAULT 0xffff - -/* - * SNAC Family: Translation Services - */ -#define AIM_CB_TRN_ERROR 0x0001 -#define AIM_CB_TRN_DEFAULT 0xffff - -/* - * SNAC Family: Chat Navigation Services - */ -#define AIM_CB_CTN_ERROR 0x0001 -#define AIM_CB_CTN_DEFAULT 0xffff - -/* - * SNAC Family: Chat Services - */ -#define AIM_CB_CHT_ERROR 0x0001 -#define AIM_CB_CHT_DEFAULT 0xffff - -/* - * SNAC Family: Internal Messages - * - * This isn't truely a SNAC family either, but using - * these, we can integrated non-SNAC services into - * the SNAC-centered libfaim callback structure. - * - */ -#define AIM_CB_SPECIAL_AUTHSUCCESS 0x0001 -#define AIM_CB_SPECIAL_AUTHOTHER 0x0002 -#define AIM_CB_SPECIAL_UNKNOWN 0xffff -#define AIM_CB_SPECIAL_DEFAULT AIM_CB_SPECIAL_UNKNOWN - - -#endif/*__AIM_CBTYPES_H__ */ diff --git a/aim_chat.c b/aim_chat.c index 1923dc7..a7af344 100644 --- a/aim_chat.c +++ b/aim_chat.c @@ -5,13 +5,15 @@ * */ -#include "aim.h" +#include /* * FIXME: Doesn't work. * */ -u_long aim_chat_join(struct aim_conn_t *conn, const char *roomname) +u_long aim_chat_join(struct aim_session_t *sess, + struct aim_conn_t *conn, + const char *roomname) { struct command_tx_struct newpacket; @@ -19,14 +21,15 @@ u_long aim_chat_join(struct aim_conn_t *conn, const char *roomname) if (conn) newpacket.conn = conn; else - newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS); + newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); + newpacket.type = 0x0002; newpacket.commandlen = 12+7+strlen(roomname)+6; newpacket.data = (char *) malloc(newpacket.commandlen); memset(newpacket.data, 0x00, newpacket.commandlen); - aim_putsnac(newpacket.data, 0x0001, 0x0004, 0x0000, aim_snac_nextid); + aim_putsnac(newpacket.data, 0x0001, 0x0004, 0x0000, sess->snac_nextid); newpacket.data[10] = 0x00; newpacket.data[11] = 0x0e; @@ -47,12 +50,12 @@ u_long aim_chat_join(struct aim_conn_t *conn, const char *roomname) printf("\n\n\n"); } - aim_tx_enqueue(&newpacket); + aim_tx_enqueue(sess, &newpacket); { struct aim_snac_t snac; - snac.id = aim_snac_nextid; + snac.id = sess->snac_nextid; snac.family = 0x0001; snac.type = 0x0004; snac.flags = 0x0000; @@ -60,8 +63,8 @@ u_long aim_chat_join(struct aim_conn_t *conn, const char *roomname) snac.data = malloc(strlen(roomname)); memcpy(snac.data, roomname, strlen(roomname)); - aim_newsnac(&snac); + aim_newsnac(sess, &snac); } - return (aim_snac_nextid++); + return (sess->snac_nextid++); } diff --git a/aim_chatnav.c b/aim_chatnav.c index 8bdc233..be99cfd 100644 --- a/aim_chatnav.c +++ b/aim_chatnav.c @@ -5,5 +5,5 @@ * */ -#include "aim.h" +#include diff --git a/aim_conn.c b/aim_conn.c index 322effd..69f06c9 100644 --- a/aim_conn.c +++ b/aim_conn.c @@ -6,31 +6,31 @@ * */ -#include "aim.h" +#include -void aim_connrst(void) +void aim_connrst(struct aim_session_t *sess) { int i; for (i = 0; i < AIM_CONN_MAX; i++) { - aim_conns[i].fd = -1; - aim_conns[i].type = -1; - aim_conns[i].status = 0; - aim_conns[i].seqnum = 0; - aim_conns[i].lastactivity = 0; - aim_conns[i].forcedlatency = 0; - aim_clearhandlers(&aim_conns[i]); - aim_conns[i].handlerlist = NULL; + 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; } } -struct aim_conn_t *aim_conn_getnext(void) +struct aim_conn_t *aim_conn_getnext(struct aim_session_t *sess) { int i; for (i=0;iconns[i].fd == -1) + return &(sess->conns[i]); return NULL; } @@ -47,12 +47,13 @@ void aim_conn_close(struct aim_conn_t *deadconn) deadconn->handlerlist = NULL; } -struct aim_conn_t *aim_getconn_type(int type) +struct aim_conn_t *aim_getconn_type(struct aim_session_t *sess, + int type) { int i; for (i=0; iconns[i].type == type) + return &(sess->conns[i]); return NULL; } @@ -65,16 +66,18 @@ struct aim_conn_t *aim_getconn_type(int type) * FIXME: Return errors in a more sane way. * */ -struct aim_conn_t *aim_newconn(int type, char *dest) +struct aim_conn_t *aim_newconn(struct aim_session_t *sess, + int type, char *dest) { struct aim_conn_t *connstruct; int ret; struct sockaddr_in sa; struct hostent *hp; u_short port = FAIM_LOGIN_PORT; + char *host = NULL; int i=0; - if (!dest || ((connstruct=aim_conn_getnext())==NULL)) + if (!dest || ((connstruct=aim_conn_getnext(sess))==NULL)) return NULL; connstruct->type = type; @@ -88,14 +91,19 @@ struct aim_conn_t *aim_newconn(int type, char *dest) * */ - for(i=0;(istatus = (h_errno | AIM_CONN_STATUS_RESOLVERR); @@ -115,26 +123,26 @@ struct aim_conn_t *aim_newconn(int type, char *dest) connstruct->status = (errno | AIM_CONN_STATUS_CONNERR); return connstruct; } - + return connstruct; } -int aim_conngetmaxfd(void) +int aim_conngetmaxfd(struct aim_session_t *sess) { int i,j; j=0; for (i=0;i j) - j = aim_conns[i].fd; + if(sess->conns[i].fd > j) + j = sess->conns[i].fd; return j; } -int aim_countconn(void) +int aim_countconn(struct aim_session_t *sess) { int i,cnt; cnt = 0; for (i=0;i -1) + if (sess->conns[i].fd > -1) cnt++; return cnt; } @@ -146,47 +154,48 @@ int aim_countconn(void) * See select(2). * */ -struct aim_conn_t *aim_select(struct timeval *timeout) +struct aim_conn_t *aim_select(struct aim_session_t *sess, + struct timeval *timeout) { fd_set fds; fd_set errfds; int i; - if (aim_countconn() <= 0) + if (aim_countconn(sess) <= 0) return 0; /* * If we have data waiting to be sent, return immediatly */ - if (aim_queue_outgoing) + if (sess->queue_outgoing) return (struct aim_conn_t *)1; FD_ZERO(&fds); FD_ZERO(&errfds); for(i=0;i-1) + if (sess->conns[i].fd>-1) { - FD_SET(aim_conns[i].fd, &fds); - FD_SET(aim_conns[i].fd, &errfds); + FD_SET(sess->conns[i].fd, &fds); + FD_SET(sess->conns[i].fd, &errfds); } - i = select(aim_conngetmaxfd()+1, &fds, NULL, &errfds, timeout); + i = select(aim_conngetmaxfd(sess)+1, &fds, NULL, &errfds, timeout); if (i>=1) { int j; for (j=0;j -1) + if (sess->conns[j].fd > -1) { - if ((FD_ISSET(aim_conns[j].fd, &errfds))) + if ((FD_ISSET(sess->conns[j].fd, &errfds))) { /* got an exception; close whats left of it up */ - aim_conn_close(&(aim_conns[j])); + aim_conn_close(&(sess->conns[j])); return (struct aim_conn_t *)-1; } - else if ((FD_ISSET(aim_conns[j].fd, &fds))) - return &(aim_conns[j]); /* return the first waiting struct */ + else if ((FD_ISSET(sess->conns[j].fd, &fds))) + return &(sess->conns[j]); /* return the first waiting struct */ } } /* should never get here */ @@ -222,3 +231,35 @@ int aim_conn_setlatency(struct aim_conn_t *conn, int newval) return 0; } + +void aim_session_init(struct aim_session_t *sess) +{ + int i; + + if (!sess) + return; + + sess->logininfo.screen_name[0] = '\0'; + sess->logininfo.BOSIP = NULL; + sess->logininfo.cookie[0] = '\0'; + 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->queue_outgoing = NULL; + sess->queue_incoming = NULL; + sess->outstanding_snacs = NULL; + sess->snac_nextid = 0x00000001; + + return; +} diff --git a/aim_im.c b/aim_im.c index f98528d..2d038b4 100644 --- a/aim_im.c +++ b/aim_im.c @@ -5,7 +5,7 @@ * */ -#include +#include /* * Send an ICBM (instant message). @@ -17,7 +17,9 @@ * when the message is received (of type 0x0004/0x000c) * */ -u_long aim_send_im(struct aim_conn_t *conn, char *destsn, u_int flags, char *msg) +u_long aim_send_im(struct aim_session_t *sess, + struct aim_conn_t *conn, + char *destsn, u_int flags, char *msg) { int curbyte,i; @@ -28,7 +30,7 @@ u_long aim_send_im(struct aim_conn_t *conn, char *destsn, u_int flags, char *msg if (conn) newpacket.conn = conn; else - newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS); + newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); /* * Its simplest to set this arbitrarily large and waste @@ -36,14 +38,20 @@ u_long aim_send_im(struct aim_conn_t *conn, char *destsn, u_int flags, char *msg */ newpacket.commandlen = 1152; - newpacket.data = (char *) calloc(1, newpacket.commandlen); + newpacket.data = (u_char *) calloc(1, newpacket.commandlen); curbyte = 0; curbyte += aim_putsnac(newpacket.data+curbyte, - 0x0004, 0x0006, 0x0000, aim_snac_nextid); + 0x0004, 0x0006, 0x0000, sess->snac_nextid); /* * Generate a random message cookie + * + * We could cache these like we do SNAC IDs. (In fact, it + * might be a good idea.) In the message error functions, + * the 8byte message cookie is returned as well as the + * SNAC ID. + * */ for (i=0;i<8;i++) curbyte += aimutil_put8(newpacket.data+curbyte, (u_char) random()); @@ -109,13 +117,13 @@ u_long aim_send_im(struct aim_conn_t *conn, char *destsn, u_int flags, char *msg newpacket.commandlen = curbyte; - aim_tx_enqueue(&newpacket); + aim_tx_enqueue(sess, &newpacket); #ifdef USE_SNAC_FOR_IMS { struct aim_snac_t snac; - snac.id = aim_snac_nextid; + snac.id = sess->snac_nextid; snac.family = 0x0004; snac.type = 0x0006; snac.flags = 0x0000; @@ -123,13 +131,13 @@ u_long aim_send_im(struct aim_conn_t *conn, char *destsn, u_int flags, char *msg snac.data = malloc(strlen(destsn)+1); memcpy(snac.data, destsn, strlen(destsn)+1); - aim_newsnac(&snac); + aim_newsnac(sess, &snac); } - aim_cleansnacs(60); /* clean out all SNACs over 60sec old */ + aim_cleansnacs(sess, 60); /* clean out all SNACs over 60sec old */ #endif - return (aim_snac_nextid++); + return (sess->snac_nextid++); } /* @@ -147,7 +155,8 @@ u_long aim_send_im(struct aim_conn_t *conn, char *destsn, u_int flags, char *msg * room we're invited to, but obviously can't attend... * */ -int aim_parse_incoming_im_middle(struct command_rx_struct *command) +int aim_parse_incoming_im_middle(struct aim_session_t *sess, + struct command_rx_struct *command) { struct aim_userinfo_s userinfo; u_int i = 0, j = 0, y = 0, z = 0; @@ -326,7 +335,7 @@ int aim_parse_incoming_im_middle(struct command_rx_struct *command) */ userfunc = aim_callhandler(command->conn, 0x0004, 0x0007); if (userfunc) - i = userfunc(command, &userinfo, msg, icbmflags, flag1, flag2); + i = userfunc(sess, command, &userinfo, msg, icbmflags, flag1, flag2); else i = 0; @@ -342,7 +351,8 @@ int aim_parse_incoming_im_middle(struct command_rx_struct *command) * idea. * */ -u_long aim_seticbmparam(struct aim_conn_t *conn) +u_long aim_seticbmparam(struct aim_session_t *sess, + struct aim_conn_t *conn) { struct command_tx_struct newpacket; int curbyte; @@ -351,13 +361,13 @@ u_long aim_seticbmparam(struct aim_conn_t *conn) if (conn) newpacket.conn = conn; else - newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS); + newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); newpacket.type = 0x02; newpacket.commandlen = 10 + 16; newpacket.data = (u_char *) malloc (newpacket.commandlen); - curbyte = aim_putsnac(newpacket.data, 0x0004, 0x0002, 0x0000, aim_snac_nextid); + curbyte = aim_putsnac(newpacket.data, 0x0004, 0x0002, 0x0000, sess->snac_nextid); curbyte += aimutil_put16(newpacket.data+curbyte, 0x0000); curbyte += aimutil_put32(newpacket.data+curbyte, 0x00000003); curbyte += aimutil_put8(newpacket.data+curbyte, 0x1f); @@ -369,7 +379,48 @@ u_long aim_seticbmparam(struct aim_conn_t *conn) curbyte += aimutil_put16(newpacket.data+curbyte, 0x0000); curbyte += aimutil_put16(newpacket.data+curbyte, 0x0000); - aim_tx_enqueue(&newpacket); + aim_tx_enqueue(sess, &newpacket); + + return (sess->snac_nextid++); +} + +int aim_parse_msgerror_middle(struct aim_session_t *sess, + struct command_rx_struct *command) +{ + u_long snacid = 0x000000000; + struct aim_snac_t *snac = NULL; + int ret = 0; + rxcallback_t userfunc = NULL; + + /* + * Get SNAC from packet and look it up + * the list of unrepliedto/outstanding + * SNACs. + * + * After its looked up, the SN that the + * message should've gone to will be + * in the ->data element of the snac struct. + * + */ + snacid = aimutil_get32(command->data+6); + snac = aim_remsnac(sess, snacid); + + if (!snac) + { + printf("faim: msgerr: got an ICBM-failed error on an unknown SNAC ID! (%08lx)\n", snacid); + } + + /* + * Call client. + */ + userfunc = aim_callhandler(command->conn, 0x0004, 0x0001); + if (userfunc) + ret = userfunc(sess, command, (snac)?snac->data:"(UNKNOWN)"); + else + ret = 0; + + free(snac->data); + free(snac); - return (aim_snac_nextid++); + return ret; } diff --git a/aim_info.c b/aim_info.c index 9d085a6..1b824ad 100644 --- a/aim_info.c +++ b/aim_info.c @@ -7,16 +7,18 @@ */ -#include "aim.h" /* for most everything */ +#include -u_long aim_getinfo(struct aim_conn_t *conn, const char *sn) +u_long aim_getinfo(struct aim_session_t *sess, + struct aim_conn_t *conn, + const char *sn) { struct command_tx_struct newpacket; if (conn) newpacket.conn = conn; else - newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS); + newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); newpacket.lock = 1; newpacket.type = 0x0002; @@ -24,18 +26,18 @@ u_long aim_getinfo(struct aim_conn_t *conn, const char *sn) newpacket.commandlen = 12 + 1 + strlen(sn); newpacket.data = (char *) malloc(newpacket.commandlen); - aim_putsnac(newpacket.data, 0x0002, 0x0005, 0x0000, aim_snac_nextid); + aim_putsnac(newpacket.data, 0x0002, 0x0005, 0x0000, sess->snac_nextid); aimutil_put16(newpacket.data+10, 0x0001); aimutil_put8(newpacket.data+12, strlen(sn)); aimutil_putstr(newpacket.data+13, sn, strlen(sn)); - aim_tx_enqueue(&newpacket); + aim_tx_enqueue(sess, &newpacket); { struct aim_snac_t snac; - snac.id = aim_snac_nextid; + snac.id = sess->snac_nextid; snac.family = 0x0002; snac.type = 0x0005; snac.flags = 0x0000; @@ -43,10 +45,10 @@ u_long aim_getinfo(struct aim_conn_t *conn, const char *sn) snac.data = malloc(strlen(sn)+1); memcpy(snac.data, sn, strlen(sn)+1); - aim_newsnac(&snac); + aim_newsnac(sess, &snac); } - return (aim_snac_nextid++); + return (sess->snac_nextid++); } /* @@ -227,7 +229,8 @@ int aim_extractuserinfo(u_char *buf, struct aim_userinfo_s *outinfo) * through aim_extractuserinfo() however. * */ -int aim_parse_oncoming_middle(struct command_rx_struct *command) +int aim_parse_oncoming_middle(struct aim_session_t *sess, + struct command_rx_struct *command) { struct aim_userinfo_s userinfo; u_int i = 0; @@ -238,18 +241,40 @@ int aim_parse_oncoming_middle(struct command_rx_struct *command) userfunc = aim_callhandler(command->conn, AIM_CB_FAM_BUD, AIM_CB_BUD_ONCOMING); if (userfunc) - i = userfunc(command, &userinfo); + i = userfunc(sess, command, &userinfo); return 1; } +/* + * Offgoing Buddy notifications contain no useful + * information other than the name it applies to. + * + */ +int aim_parse_offgoing_middle(struct aim_session_t *sess, + struct command_rx_struct *command) +{ + char sn[MAXSNLEN+1]; + u_int i = 0; + rxcallback_t userfunc=NULL; + + /* Protect against future SN length extensions */ + strncpy(sn, command->data+11, (strlen(sn)<=MAXSNLEN)?strlen(sn):MAXSNLEN); + + userfunc = aim_callhandler(command->conn, AIM_CB_FAM_BUD, AIM_CB_BUD_OFFGOING); + if (userfunc) + i = userfunc(sess, command, sn); + + return 1; +} /* * This parses the user info stuff out all nice and pretty then calls * the higher-level callback (in the user app). * */ -int aim_parse_userinfo_middle(struct command_rx_struct *command) +int aim_parse_userinfo_middle(struct aim_session_t *sess, + struct command_rx_struct *command) { struct aim_userinfo_s userinfo; char *prof_encoding = NULL; @@ -262,7 +287,7 @@ int aim_parse_userinfo_middle(struct command_rx_struct *command) struct aim_snac_t *snac = NULL; snacid = aimutil_get32(&command->data[6]); - snac = aim_remsnac(snacid); + snac = aim_remsnac(sess, snacid); free(snac->data); free(snac); @@ -288,7 +313,7 @@ int aim_parse_userinfo_middle(struct command_rx_struct *command) } else { - printf("faim: userinfo: **warning: unexpected TLV after TLVblock t(%02x%02x) l(%02x%02x)\n", command->data[i], command->data[i+1], command->data[i+2], command->data[i+3]); + printf("faim: userinfo: **warning: unexpected TLV after TLVblock t(%04x) l(%04x)\n", aimutil_get16(command->data+i), aimutil_get16(command->data+i+2)); i += 2 + 2 + command->data[i+3]; } } @@ -311,7 +336,8 @@ int aim_parse_userinfo_middle(struct command_rx_struct *command) userfunc = aim_callhandler(command->conn, AIM_CB_FAM_LOC, AIM_CB_LOC_USERINFO); if (userfunc) { - i = userfunc(command, + i = userfunc(sess, + command, &userinfo, prof_encoding, prof); diff --git a/aim_login.c b/aim_login.c index ba05e20..c7af989 100644 --- a/aim_login.c +++ b/aim_login.c @@ -5,7 +5,7 @@ * */ -#include +#include /* @@ -25,9 +25,11 @@ * stupid method of doing it. * */ -int aim_send_login (struct aim_conn_t *conn, char *sn, char *password, struct client_info_s *clientinfo) +int aim_send_login (struct aim_session_t *sess, + struct aim_conn_t *conn, + char *sn, char *password, struct client_info_s *clientinfo) { - char *password_encoded = NULL; /* to store encoded password */ + u_char *password_encoded = NULL; /* to store encoded password */ int curbyte=0; struct command_tx_struct newpacket; @@ -35,7 +37,7 @@ int aim_send_login (struct aim_conn_t *conn, char *sn, char *password, struct cl if (conn) newpacket.conn = conn; else - newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_AUTH); + newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_AUTH); newpacket.commandlen = 4 + 4+strlen(sn) + 4+strlen(password) + 6; @@ -98,7 +100,7 @@ int aim_send_login (struct aim_conn_t *conn, char *sn, char *password, struct cl curbyte += aim_puttlv_16(newpacket.data+curbyte, 0x0009, 0x0015); newpacket.lock = 0; - aim_tx_enqueue(&newpacket); + aim_tx_enqueue(sess, &newpacket); return 0; } @@ -119,7 +121,7 @@ int aim_send_login (struct aim_conn_t *conn, char *sn, char *password, struct cl * hope it doesn't change over time! * */ -int aim_encode_password(const char *password, char *encoded) +int aim_encode_password(const char *password, u_char *encoded) { u_char encoding_table[] = { 0xf3, 0xb3, 0x6c, 0x99, diff --git a/aim_logoff.c b/aim_logoff.c index ebea9dc..b16eef1 100644 --- a/aim_logoff.c +++ b/aim_logoff.c @@ -4,7 +4,7 @@ * */ -#include "aim.h" +#include /* * aim_logoff() @@ -12,16 +12,16 @@ * Closes -ALL- open connections. * */ -int aim_logoff(void) +int aim_logoff(struct aim_session_t *sess) { int i = AIM_CONN_MAX-1; while (i > -1) { - if (aim_conns[i].fd>-1) - aim_conn_close(&(aim_conns[i])); + if (sess->conns[i].fd>-1) + aim_conn_close(&(sess->conns[i])); i--; } - aim_connrst(); /* in case we want to connect again */ + aim_connrst(sess); /* in case we want to connect again */ return 0; diff --git a/aim_misc.c b/aim_misc.c index 12f5c29..f53d5b6 100644 --- a/aim_misc.c +++ b/aim_misc.c @@ -11,7 +11,7 @@ * */ -#include "aim.h" +#include /* * aim_bos_setidle() @@ -21,9 +21,11 @@ * time. * */ -u_long aim_bos_setidle(struct aim_conn_t *conn, u_long idletime) +u_long aim_bos_setidle(struct aim_session_t *sess, + struct aim_conn_t *conn, + u_long idletime) { - return aim_genericreq_l(conn, 0x0001, 0x0011, &idletime); + return aim_genericreq_l(sess, conn, 0x0001, 0x0011, &idletime); } @@ -55,7 +57,9 @@ u_long aim_bos_setidle(struct aim_conn_t *conn, u_long idletime) * * */ -u_long aim_bos_changevisibility(struct aim_conn_t *conn, int changetype, char *denylist) +u_long aim_bos_changevisibility(struct aim_session_t *sess, + struct aim_conn_t *conn, + int changetype, char *denylist) { struct command_tx_struct newpacket; u_short subtype; @@ -73,7 +77,7 @@ u_long aim_bos_changevisibility(struct aim_conn_t *conn, int changetype, char *d if (conn) newpacket.conn = conn; else - newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS); + newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); newpacket.type = 0x02; @@ -116,9 +120,9 @@ u_long aim_bos_changevisibility(struct aim_conn_t *conn, int changetype, char *d newpacket.lock = 0; - aim_tx_enqueue(&newpacket); + aim_tx_enqueue(sess, &newpacket); - return (aim_snac_nextid); /* dont increment */ + return (sess->snac_nextid); /* dont increment */ } @@ -134,7 +138,9 @@ u_long aim_bos_changevisibility(struct aim_conn_t *conn, int changetype, char *d * TODO: Clean this up. * */ -u_long aim_bos_setbuddylist(struct aim_conn_t *conn, char *buddy_list) +u_long aim_bos_setbuddylist(struct aim_session_t *sess, + struct aim_conn_t *conn, + char *buddy_list) { int i, j; @@ -181,13 +187,13 @@ u_long aim_bos_setbuddylist(struct aim_conn_t *conn, char *buddy_list) if (conn) newpacket.conn = conn; else - newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS); + newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); newpacket.commandlen = packet_login_phase3c_hi_b_len - 6; newpacket.lock = 1; newpacket.data = (char *) malloc(newpacket.commandlen); - aim_putsnac(newpacket.data, 0x0003, 0x0004, 0x0000, aim_snac_nextid); + aim_putsnac(newpacket.data, 0x0003, 0x0004, 0x0000, sess->snac_nextid); j = 10; /* the next byte */ @@ -207,9 +213,9 @@ u_long aim_bos_setbuddylist(struct aim_conn_t *conn, char *buddy_list) newpacket.lock = 0; - aim_tx_enqueue(&newpacket); + aim_tx_enqueue(sess, &newpacket); - return (aim_snac_nextid++); + return (sess->snac_nextid++); } /* @@ -218,7 +224,9 @@ u_long aim_bos_setbuddylist(struct aim_conn_t *conn, char *buddy_list) * Gives BOS your profile. * */ -u_long aim_bos_setprofile(struct aim_conn_t *conn, char *profile) +u_long aim_bos_setprofile(struct aim_session_t *sess, + struct aim_conn_t *conn, + char *profile) { int packet_profile_len = 0; struct command_tx_struct newpacket; @@ -239,13 +247,14 @@ u_long aim_bos_setprofile(struct aim_conn_t *conn, char *profile) if (conn) newpacket.conn = conn; else - newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS); + newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); + newpacket.commandlen = packet_profile_len; newpacket.data = (char *) malloc(packet_profile_len); i = 0; - i += aim_putsnac(newpacket.data, 0x0002, 0x004, 0x0000, aim_snac_nextid); + i += aim_putsnac(newpacket.data, 0x0002, 0x004, 0x0000, sess->snac_nextid); /* TLV t(0001) */ newpacket.data[i++] = 0x00; @@ -266,9 +275,9 @@ u_long aim_bos_setprofile(struct aim_conn_t *conn, char *profile) /* TLV v(profile) */ memcpy(&(newpacket.data[i]), profile, strlen(profile)); - aim_tx_enqueue(&newpacket); + aim_tx_enqueue(sess, &newpacket); - return (aim_snac_nextid++); + return (sess->snac_nextid++); } /* @@ -277,9 +286,11 @@ u_long aim_bos_setprofile(struct aim_conn_t *conn, char *profile) * Set group permisson mask. Normally 0x1f. * */ -u_long aim_bos_setgroupperm(struct aim_conn_t *conn, u_long mask) +u_long aim_bos_setgroupperm(struct aim_session_t *sess, + struct aim_conn_t *conn, + u_long mask) { - return aim_genericreq_l(conn, 0x0009, 0x0004, &mask); + return aim_genericreq_l(sess, conn, 0x0009, 0x0004, &mask); } /* @@ -290,7 +301,8 @@ u_long aim_bos_setgroupperm(struct aim_conn_t *conn, u_long mask) * TODO: Dynamisize. * */ -u_long aim_bos_clientready(struct aim_conn_t *conn) +u_long aim_bos_clientready(struct aim_session_t *sess, + struct aim_conn_t *conn) { u_char command_2[] = { /* placeholders for dynamic data */ @@ -315,18 +327,18 @@ u_long aim_bos_clientready(struct aim_conn_t *conn) if (conn) newpacket.conn = conn; else - newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS); + newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); newpacket.type = 0x02; newpacket.commandlen = command_2_len; newpacket.data = (char *) malloc (newpacket.commandlen); memcpy(newpacket.data, command_2, newpacket.commandlen); /* This write over the dynamic parts of the byte block */ - aim_putsnac(newpacket.data, 0x0001, 0x0002, 0x0000, aim_snac_nextid); + aim_putsnac(newpacket.data, 0x0001, 0x0002, 0x0000, sess->snac_nextid); - aim_tx_enqueue(&newpacket); + aim_tx_enqueue(sess, &newpacket); - return (aim_snac_nextid++); + return (sess->snac_nextid++); } /* @@ -337,9 +349,10 @@ u_long aim_bos_clientready(struct aim_conn_t *conn) * TODO: Move to aim_conn. * TODO: Move to SNAC interface. */ -u_long aim_bos_reqrate(struct aim_conn_t *conn) +u_long aim_bos_reqrate(struct aim_session_t *sess, + struct aim_conn_t *conn) { - return aim_genericreq_n(conn, 0x0001, 0x0006); + return aim_genericreq_n(sess, conn, 0x0001, 0x0006); } /* @@ -348,7 +361,8 @@ u_long aim_bos_reqrate(struct aim_conn_t *conn) * Rate Information Response Acknowledge. * */ -u_long aim_bos_ackrateresp(struct aim_conn_t *conn) +u_long aim_bos_ackrateresp(struct aim_session_t *sess, + struct aim_conn_t *conn) { struct command_tx_struct newpacket; @@ -356,12 +370,12 @@ u_long aim_bos_ackrateresp(struct aim_conn_t *conn) if (conn) newpacket.conn = conn; else - newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS); + newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); newpacket.type = 0x02; newpacket.commandlen = 18; newpacket.data = (char *) malloc(newpacket.commandlen); - aim_putsnac(newpacket.data, 0x0001, 0x0008, 0x0000, aim_snac_nextid); + aim_putsnac(newpacket.data, 0x0001, 0x0008, 0x0000, sess->snac_nextid); newpacket.data[10] = 0x00; newpacket.data[11] = 0x01; @@ -372,9 +386,9 @@ u_long aim_bos_ackrateresp(struct aim_conn_t *conn) newpacket.data[16] = 0x00; newpacket.data[17] = 0x04; - aim_tx_enqueue(&newpacket); + aim_tx_enqueue(sess, &newpacket); - return (aim_snac_nextid++); + return (sess->snac_nextid++); } /* @@ -386,9 +400,11 @@ u_long aim_bos_ackrateresp(struct aim_conn_t *conn) * * */ -u_long aim_bos_setprivacyflags(struct aim_conn_t *conn, u_long flags) +u_long aim_bos_setprivacyflags(struct aim_session_t *sess, + struct aim_conn_t *conn, + u_long flags) { - return aim_genericreq_l(conn, 0x0001, 0x0014, &flags); + return aim_genericreq_l(sess, conn, 0x0001, 0x0014, &flags); } /* @@ -398,7 +414,8 @@ u_long aim_bos_setprivacyflags(struct aim_conn_t *conn, u_long flags) * because aparently it uses SNAC flags. * */ -u_long aim_bos_reqpersonalinfo(struct aim_conn_t *conn) +u_long aim_bos_reqpersonalinfo(struct aim_session_t *sess, + struct aim_conn_t *conn) { struct command_tx_struct newpacket; @@ -406,19 +423,19 @@ u_long aim_bos_reqpersonalinfo(struct aim_conn_t *conn) if (conn) newpacket.conn = conn; else - newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS); + newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); newpacket.type = 0x02; newpacket.commandlen = 12; newpacket.data = (char *) malloc(newpacket.commandlen); - aim_putsnac(newpacket.data, 0x000a, 0x0001, 0x000e /* huh? */, aim_snac_nextid); + aim_putsnac(newpacket.data, 0x000a, 0x0001, 0x000e /* huh? */, sess->snac_nextid); newpacket.data[10] = 0x0d; newpacket.data[11] = 0xda; - aim_tx_enqueue(&newpacket); + aim_tx_enqueue(sess, &newpacket); - return (aim_snac_nextid++); + return (sess->snac_nextid++); } /* @@ -427,9 +444,11 @@ u_long aim_bos_reqpersonalinfo(struct aim_conn_t *conn) * Service request. * */ -u_long aim_bos_reqservice(struct aim_conn_t *conn, u_short serviceid) +u_long aim_bos_reqservice(struct aim_session_t *sess, + struct aim_conn_t *conn, + u_short serviceid) { - return aim_genericreq_s(conn, 0x0001, 0x0004, &serviceid); + return aim_genericreq_s(sess, conn, 0x0001, 0x0004, &serviceid); } /* @@ -438,9 +457,10 @@ u_long aim_bos_reqservice(struct aim_conn_t *conn, u_short serviceid) * Request BOS rights. * */ -u_long aim_bos_reqrights(struct aim_conn_t *conn) +u_long aim_bos_reqrights(struct aim_session_t *sess, + struct aim_conn_t *conn) { - return aim_genericreq_n(conn, 0x0009, 0x0002); + return aim_genericreq_n(sess, conn, 0x0009, 0x0002); } /* @@ -449,9 +469,10 @@ u_long aim_bos_reqrights(struct aim_conn_t *conn) * Request Buddy List rights. * */ -u_long aim_bos_reqbuddyrights(struct aim_conn_t *conn) +u_long aim_bos_reqbuddyrights(struct aim_session_t *sess, + struct aim_conn_t *conn) { - return aim_genericreq_n(conn, 0x0003, 0x0002); + return aim_genericreq_n(sess, conn, 0x0003, 0x0002); } /* @@ -466,7 +487,9 @@ u_long aim_bos_reqbuddyrights(struct aim_conn_t *conn) * back to the single. I don't see any advantage to doing it either way. * */ -u_long aim_genericreq_n(struct aim_conn_t *conn, u_short family, u_short subtype) +u_long aim_genericreq_n(struct aim_session_t *sess, + struct aim_conn_t *conn, + u_short family, u_short subtype) { struct command_tx_struct newpacket; @@ -475,7 +498,7 @@ u_long aim_genericreq_n(struct aim_conn_t *conn, u_short family, u_short subtype if (conn) newpacket.conn = conn; else - newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS); + newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); newpacket.type = 0x02; newpacket.commandlen = 10; @@ -483,31 +506,34 @@ u_long aim_genericreq_n(struct aim_conn_t *conn, u_short family, u_short subtype newpacket.data = (char *) malloc(newpacket.commandlen); memset(newpacket.data, 0x00, newpacket.commandlen); - aim_putsnac(newpacket.data, family, subtype, 0x0000, aim_snac_nextid); + aim_putsnac(newpacket.data, family, subtype, 0x0000, sess->snac_nextid); - aim_tx_enqueue(&newpacket); - return (aim_snac_nextid++); + aim_tx_enqueue(sess, &newpacket); + return (sess->snac_nextid++); } /* * * */ -u_long aim_genericreq_l(struct aim_conn_t *conn, u_short family, u_short subtype, u_long *longdata) +u_long aim_genericreq_l(struct aim_session_t *sess, + struct aim_conn_t *conn, + u_short family, u_short subtype, u_long *longdata) { struct command_tx_struct newpacket; u_long newlong; /* If we don't have data, there's no reason to use this function */ if (!longdata) - return aim_genericreq_n(conn, family, subtype); + return aim_genericreq_n(sess, conn, family, subtype); newpacket.lock = 1; if (conn) newpacket.conn = conn; else - newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS); + newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); + newpacket.type = 0x02; newpacket.commandlen = 10+sizeof(u_long); @@ -515,31 +541,34 @@ u_long aim_genericreq_l(struct aim_conn_t *conn, u_short family, u_short subtype newpacket.data = (char *) malloc(newpacket.commandlen); memset(newpacket.data, 0x00, newpacket.commandlen); - aim_putsnac(newpacket.data, family, subtype, 0x0000, aim_snac_nextid); + aim_putsnac(newpacket.data, family, subtype, 0x0000, sess->snac_nextid); /* copy in data */ newlong = htonl(*longdata); memcpy(&(newpacket.data[10]), &newlong, sizeof(u_long)); - aim_tx_enqueue(&newpacket); - return (aim_snac_nextid++); + aim_tx_enqueue(sess, &newpacket); + return (sess->snac_nextid++); } -u_long aim_genericreq_s(struct aim_conn_t *conn, u_short family, u_short subtype, u_short *shortdata) +u_long aim_genericreq_s(struct aim_session_t *sess, + struct aim_conn_t *conn, + u_short family, u_short subtype, u_short *shortdata) { struct command_tx_struct newpacket; u_short newshort; /* If we don't have data, there's no reason to use this function */ if (!shortdata) - return aim_genericreq_n(conn, family, subtype); + return aim_genericreq_n(sess, conn, family, subtype); newpacket.lock = 1; if (conn) newpacket.conn = conn; else - newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS); + newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); + newpacket.type = 0x02; newpacket.commandlen = 10+sizeof(u_short); @@ -547,14 +576,14 @@ u_long aim_genericreq_s(struct aim_conn_t *conn, u_short family, u_short subtype newpacket.data = (char *) malloc(newpacket.commandlen); memset(newpacket.data, 0x00, newpacket.commandlen); - aim_putsnac(newpacket.data, family, subtype, 0x0000, aim_snac_nextid); + aim_putsnac(newpacket.data, family, subtype, 0x0000, sess->snac_nextid); /* copy in data */ newshort = htons(*shortdata); memcpy(&(newpacket.data[10]), &newshort, sizeof(u_short)); - aim_tx_enqueue(&newpacket); - return (aim_snac_nextid++); + aim_tx_enqueue(sess, &newpacket); + return (sess->snac_nextid++); } /* @@ -563,9 +592,10 @@ u_long aim_genericreq_s(struct aim_conn_t *conn, u_short family, u_short subtype * Request Location services rights. * */ -u_long aim_bos_reqlocaterights(struct aim_conn_t *conn) +u_long aim_bos_reqlocaterights(struct aim_session_t *sess, + struct aim_conn_t *conn) { - return aim_genericreq_n(conn, 0x0002, 0x0002); + return aim_genericreq_n(sess, conn, 0x0002, 0x0002); } /* @@ -574,7 +604,8 @@ u_long aim_bos_reqlocaterights(struct aim_conn_t *conn) * Request ICBM parameter information. * */ -u_long aim_bos_reqicbmparaminfo(struct aim_conn_t *conn) +u_long aim_bos_reqicbmparaminfo(struct aim_session_t *sess, + struct aim_conn_t *conn) { - return aim_genericreq_n(conn, 0x0004, 0x0004); + return aim_genericreq_n(sess, conn, 0x0004, 0x0004); } diff --git a/aim_rxhandlers.c b/aim_rxhandlers.c index 4ae0175..d6bdc98 100644 --- a/aim_rxhandlers.c +++ b/aim_rxhandlers.c @@ -7,13 +7,13 @@ * */ -#include +#include /* * Bleck functions get called when there's no non-bleck functions * around to cleanup the mess... */ -int bleck(struct command_rx_struct *workingPtr, ...) +int bleck(struct aim_session_t *sess,struct command_rx_struct *workingPtr, ...) { u_short family; u_short subtype; @@ -23,7 +23,8 @@ int bleck(struct command_rx_struct *workingPtr, ...) return 1; } -int aim_conn_addhandler(struct aim_conn_t *conn, +int aim_conn_addhandler(struct aim_session_t *sess, + struct aim_conn_t *conn, u_short family, u_short type, rxcallback_t newhandler, @@ -103,7 +104,8 @@ rxcallback_t aim_callhandler(struct aim_conn_t *conn, return aim_callhandler(conn, family, 0xffff); } -int aim_callhandler_noparam(struct aim_conn_t *conn, +int aim_callhandler_noparam(struct aim_session_t *sess, + struct aim_conn_t *conn, u_short family, u_short type, struct command_rx_struct *ptr) @@ -111,7 +113,7 @@ int aim_callhandler_noparam(struct aim_conn_t *conn, rxcallback_t userfunc = NULL; userfunc = aim_callhandler(conn, family, type); if (userfunc) - return userfunc(ptr); + return userfunc(sess, ptr); return 0; } @@ -138,165 +140,169 @@ int aim_callhandler_noparam(struct aim_conn_t *conn, TODO: Allow for NULL handlers. */ -int aim_rxdispatch(void) +int aim_rxdispatch(struct aim_session_t *sess) { int i = 0; struct command_rx_struct *workingPtr = NULL; - if (aim_queue_incoming == NULL) + if (sess->queue_incoming == NULL) /* this shouldn't really happen, unless the main loop's select is broke */ printf("parse_generic: incoming packet queue empty.\n"); else { - workingPtr = aim_queue_incoming; + workingPtr = sess->queue_incoming; for (i = 0; workingPtr != NULL; i++) { switch(workingPtr->conn->type) { case AIM_CONN_TYPE_AUTH: - if ( (workingPtr->data[0] == 0x00) && - (workingPtr->data[1] == 0x00) && - (workingPtr->data[2] == 0x00) && - (workingPtr->data[3] == 0x01) ) - { + { + u_long head; + + head = aimutil_get32(workingPtr->data); + if (head == 0x00000001) + { #if debug > 0 - printf("got connection ack on auth line\n"); + printf("got connection ack on auth line\n"); #endif - workingPtr->handled = 1; - } - else - { - /* any user callbacks will be called from here */ - workingPtr->handled = aim_authparse(workingPtr); - } + workingPtr->handled = 1; + } + else + { + /* any user callbacks will be called from here */ + workingPtr->handled = aim_authparse(sess, workingPtr); + } + } break; case AIM_CONN_TYPE_BOS: { u_short family; u_short subtype; - family = (workingPtr->data[0] << 8) + workingPtr->data[1]; - subtype = (workingPtr->data[2] << 8) + workingPtr->data[3]; + + family = aimutil_get16(workingPtr->data); + subtype = aimutil_get16(workingPtr->data+2); + switch (family) { case 0x0000: /* not really a family, but it works */ if (subtype == 0x0001) - workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x0000, 0x0001, workingPtr); + workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0000, 0x0001, workingPtr); else - workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_UNKNOWN, workingPtr); + workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_UNKNOWN, workingPtr); break; case 0x0001: /* Family: General */ switch (subtype) { case 0x0001: - workingPtr->handled = aim_parse_generalerrs(workingPtr); + workingPtr->handled = aim_parse_generalerrs(sess, workingPtr); break; case 0x0003: - workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x0001, 0x0003, workingPtr); + workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x0003, workingPtr); break; case 0x0005: - workingPtr->handled = aim_handleredirect_middle(workingPtr); + workingPtr->handled = aim_handleredirect_middle(sess, workingPtr); break; case 0x0007: - workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x0001, 0x0007, workingPtr); + workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x0007, workingPtr); break; case 0x000a: - workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x0001, 0x000a, workingPtr); + workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x000a, workingPtr); break; case 0x000f: - workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x0001, 0x000f, workingPtr); + workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x000f, workingPtr); break; case 0x0013: - workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x0001, 0x0013, workingPtr); + workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0001, 0x0013, workingPtr); break; default: - workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, AIM_CB_FAM_GEN, AIM_CB_GEN_DEFAULT, workingPtr); + workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_GEN, AIM_CB_GEN_DEFAULT, workingPtr); } break; case 0x0002: /* Family: Location */ switch (subtype) { case 0x0001: - workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x0002, 0x0001, workingPtr); + workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0002, 0x0001, workingPtr); break; case 0x0003: - workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x0002, 0x0003, workingPtr); + workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0002, 0x0003, workingPtr); break; case 0x0006: - workingPtr->handled = aim_parse_userinfo_middle(workingPtr); + workingPtr->handled = aim_parse_userinfo_middle(sess, workingPtr); break; default: - workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, AIM_CB_FAM_LOC, AIM_CB_LOC_DEFAULT, workingPtr); + workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_LOC, AIM_CB_LOC_DEFAULT, workingPtr); } break; case 0x0003: /* Family: Buddy List */ switch (subtype) { case 0x0001: - workingPtr->handled = aim_parse_generalerrs(workingPtr); + workingPtr->handled = aim_parse_generalerrs(sess, workingPtr); break; case 0x0003: - workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x0003, 0x0003, workingPtr); + workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0003, 0x0003, workingPtr); break; case 0x000b: /* oncoming buddy */ - workingPtr->handled = aim_parse_oncoming_middle(workingPtr); + workingPtr->handled = aim_parse_oncoming_middle(sess, workingPtr); break; case 0x000c: /* offgoing buddy */ - workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x0003, 0x000c, workingPtr); + workingPtr->handled = aim_parse_offgoing_middle(sess, workingPtr); break; default: - workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, AIM_CB_FAM_BUD, AIM_CB_BUD_DEFAULT, workingPtr); + workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_BUD, AIM_CB_BUD_DEFAULT, workingPtr); } break; case 0x0004: /* Family: Messeging */ switch (subtype) { case 0x0001: - workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x0004, 0x0001, workingPtr); + workingPtr->handled = aim_parse_msgerror_middle(sess, workingPtr); break; case 0x0005: - workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x0004, 0x0005, workingPtr); + workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0004, 0x0005, workingPtr); break; case 0x0007: - workingPtr->handled = aim_parse_incoming_im_middle(workingPtr); + workingPtr->handled = aim_parse_incoming_im_middle(sess, workingPtr); break; case 0x000a: - workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x0004, 0x000a, workingPtr); + workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0004, 0x000a, workingPtr); break; default: - workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, AIM_CB_FAM_MSG, AIM_CB_MSG_DEFAULT, workingPtr); + workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_MSG, AIM_CB_MSG_DEFAULT, workingPtr); } break; case 0x0009: if (subtype == 0x0001) - workingPtr->handled = aim_parse_generalerrs(workingPtr); + workingPtr->handled = aim_parse_generalerrs(sess, workingPtr); else if (subtype == 0x0003) - workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x0009, 0x0003, workingPtr); + workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x0009, 0x0003, workingPtr); else - workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, AIM_CB_FAM_BOS, AIM_CB_BOS_DEFAULT, workingPtr); + workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_BOS, AIM_CB_BOS_DEFAULT, workingPtr); break; case 0x000a: /* Family: User lookup */ switch (subtype) { case 0x0001: - workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x000a, 0x0001, workingPtr); + workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x000a, 0x0001, workingPtr); break; case 0x0003: - workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x000a, 0x0003, workingPtr); + workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x000a, 0x0003, workingPtr); break; default: - workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, AIM_CB_FAM_LOK, AIM_CB_LOK_DEFAULT, workingPtr); + workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_LOK, AIM_CB_LOK_DEFAULT, workingPtr); } break; case 0x000b: if (subtype == 0x0001) - workingPtr->handled = aim_parse_generalerrs(workingPtr); + workingPtr->handled = aim_parse_generalerrs(sess, workingPtr); else if (subtype == 0x0002) - workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, 0x000b, 0x0002, workingPtr); + workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, 0x000b, 0x0002, workingPtr); else - workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, AIM_CB_FAM_STS, AIM_CB_STS_DEFAULT, workingPtr); + workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_STS, AIM_CB_STS_DEFAULT, workingPtr); break; default: - workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_UNKNOWN, workingPtr); + workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_UNKNOWN, workingPtr); break; } } @@ -305,45 +311,45 @@ int aim_rxdispatch(void) { u_short family; u_short subtype; - family = (workingPtr->data[0] << 8) + workingPtr->data[1]; - subtype = (workingPtr->data[2] << 8) + workingPtr->data[3]; - if ( (workingPtr->data[0] == 0x00) && - (workingPtr->data[1] == 0x02) && - (workingPtr->data[2] == 0x00) && - (workingPtr->data[3] == 0x06) ) + family = aimutil_get16(workingPtr->data); + subtype= aimutil_get16(workingPtr->data+2); + + if ((family == 0x0002) && (subtype == 0x0006)) { workingPtr->handled = 1; aim_conn_setstatus(workingPtr->conn, AIM_CONN_STATUS_READY); } else { - workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, family, subtype, workingPtr); + workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, family, subtype, workingPtr); } } break; case AIM_CONN_TYPE_CHAT: printf("\nAHH! Dont know what to do with CHAT stuff yet!\n"); - workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_DEFAULT, workingPtr); + workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_DEFAULT, workingPtr); break; default: printf("\nAHHHHH! UNKNOWN CONNECTION TYPE! (0x%02x)\n\n", workingPtr->conn->type); - workingPtr->handled = aim_callhandler_noparam(workingPtr->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_UNKNOWN, workingPtr); + workingPtr->handled = aim_callhandler_noparam(sess, workingPtr->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_UNKNOWN, workingPtr); break; } - /* move to next command */ + /* move to next command */ workingPtr = workingPtr->next; } } - aim_queue_incoming = aim_purge_rxqueue(aim_queue_incoming); + sess->queue_incoming = aim_purge_rxqueue(sess->queue_incoming); return 0; } /* * TODO: check and cure memory leakage in this function. + * TODO: update to use new tlvlist routines */ -int aim_authparse(struct command_rx_struct *command) +int aim_authparse(struct aim_session_t *sess, + struct command_rx_struct *command) { rxcallback_t userfunc = NULL; int iserror = 0; @@ -351,19 +357,19 @@ int aim_authparse(struct command_rx_struct *command) char *errorurl = NULL; short errorcode = 0x00; u_int z = 0; + u_short family,subtype; - if ( (command->data[0] == 0x00) && - (command->data[1] == 0x01) && - (command->data[2] == 0x00) && - (command->data[3] == 0x03) ) + family = aimutil_get16(command->data); + subtype= aimutil_get16(command->data+2); + + if ( (family == 0x0001) && + (subtype== 0x0003) ) { /* "server ready" -- can be ignored */ userfunc = aim_callhandler(command->conn, AIM_CB_FAM_GEN, AIM_CB_GEN_SERVERREADY); } - else if ( (command->data[0] == 0x00) && - (command->data[1] == 0x07) && - (command->data[2] == 0x00) && - (command->data[3] == 0x05) ) + else if ( (family == 0x0007) && + (subtype== 0x0005) ) { /* "information change reply" */ userfunc = aim_callhandler(command->conn, AIM_CB_FAM_ADM, AIM_CB_ADM_INFOCHANGE_REPLY); @@ -375,27 +381,18 @@ int aim_authparse(struct command_rx_struct *command) /* * Free up the loginstruct first. */ - if (aim_logininfo.screen_name) - { - free(aim_logininfo.screen_name); - aim_logininfo.screen_name = NULL; - } - if (aim_logininfo.BOSIP) + sess->logininfo.screen_name[0] = '\0'; + if (sess->logininfo.BOSIP) { - free(aim_logininfo.BOSIP); - aim_logininfo.BOSIP = NULL; + free(sess->logininfo.BOSIP); + sess->logininfo.BOSIP = NULL; } - if (aim_logininfo.cookie) + if (sess->logininfo.email) { - free(aim_logininfo.cookie); - aim_logininfo.cookie = NULL; + free(sess->logininfo.email); + sess->logininfo.email = NULL; } - if (aim_logininfo.email) - { - free(aim_logininfo.email); - aim_logininfo.email = NULL; - } - aim_logininfo.regstatus = 0; + sess->logininfo.regstatus = 0; /* all this block does is figure out if it's an error or a success, nothing more */ @@ -405,7 +402,14 @@ int aim_authparse(struct command_rx_struct *command) switch(tlv->type) { case 0x0001: /* screen name */ - aim_logininfo.screen_name = tlv->value; + if (tlv->length >= MAXSNLEN) + { + /* SN too large... truncate */ + printf("faim: login: screen name from OSCAR too long! (%d)\n", tlv->length); + strncpy(sess->logininfo.screen_name, tlv->value, MAXSNLEN); + } + else + strncpy(sess->logininfo.screen_name, tlv->value, tlv->length); z += 2 + 2 + tlv->length; free(tlv); tlv = NULL; @@ -417,25 +421,25 @@ int aim_authparse(struct command_rx_struct *command) tlv = NULL; break; case 0x0005: /* BOS IP */ - aim_logininfo.BOSIP = tlv->value; + sess->logininfo.BOSIP = tlv->value; z += 2 + 2 + tlv->length; free(tlv); tlv = NULL; break; case 0x0006: /* auth cookie */ - aim_logininfo.cookie = tlv->value; + memcpy(sess->logininfo.cookie, tlv->value, AIM_COOKIELEN); z += 2 + 2 + tlv->length; free(tlv); tlv=NULL; break; case 0x0011: /* email addy */ - aim_logininfo.email = tlv->value; + sess->logininfo.email = tlv->value; z += 2 + 2 + tlv->length; free(tlv); tlv = NULL; break; case 0x0013: /* registration status */ - aim_logininfo.regstatus = *(tlv->value); + sess->logininfo.regstatus = *(tlv->value); z += 2 + 2 + tlv->length; aim_freetlv(&tlv); break; @@ -457,15 +461,15 @@ int aim_authparse(struct command_rx_struct *command) { userfunc = aim_callhandler(command->conn, AIM_CB_FAM_GEN, AIM_CB_GEN_ERROR); if (userfunc) - return userfunc(command, &aim_logininfo, errorurl, errorcode); + return userfunc(sess, command, errorurl, errorcode); return 0; } - else if (aim_logininfo.screen_name && - aim_logininfo.cookie && aim_logininfo.BOSIP) + else if (sess->logininfo.screen_name[0] && + sess->logininfo.cookie[0] && sess->logininfo.BOSIP) { userfunc = aim_callhandler(command->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_AUTHSUCCESS); if (userfunc) - return userfunc(command, &aim_logininfo); + return userfunc(sess, command); return 0; } else @@ -473,7 +477,7 @@ int aim_authparse(struct command_rx_struct *command) } if (userfunc) - return userfunc(command); + return userfunc(sess, command); printf("handler not available!\n"); return 0; } @@ -481,7 +485,8 @@ int aim_authparse(struct command_rx_struct *command) /* * TODO: check for and cure any memory leaks here. */ -int aim_handleredirect_middle(struct command_rx_struct *command, ...) +int aim_handleredirect_middle(struct aim_session_t *sess, + struct command_rx_struct *command, ...) { struct aim_tlv_t *tlv = NULL; u_int z = 10; @@ -499,7 +504,7 @@ int aim_handleredirect_middle(struct command_rx_struct *command, ...) aim_freetlv(&tlv); /* regrab as an int */ tlv = aim_grabtlv(&(command->data[z])); - serviceid = (tlv->value[0] << 8) + tlv->value[1]; /* hehe */ + serviceid = aimutil_get16(tlv->value); z += 2 + 2 + tlv->length; aim_freetlv(&tlv); break; @@ -523,11 +528,12 @@ int aim_handleredirect_middle(struct command_rx_struct *command, ...) } userfunc = aim_callhandler(command->conn, 0x0001, 0x0005); if (userfunc) - return userfunc(command, serviceid, ip, cookie); + return userfunc(sess, command, serviceid, ip, cookie); return 0; } -int aim_parse_unknown(struct command_rx_struct *command, ...) +int aim_parse_unknown(struct aim_session_t *sess, + struct command_rx_struct *command, ...) { u_int i = 0; @@ -553,18 +559,20 @@ int aim_parse_unknown(struct command_rx_struct *command, ...) * Middle handler for 0x0001 snac of each family. * */ -int aim_parse_generalerrs(struct command_rx_struct *command, ...) +int aim_parse_generalerrs(struct aim_session_t *sess, + struct command_rx_struct *command, ...) { u_short family; u_short subtype; - family = (command->data[0] << 8) + command->data[1]; - subtype = (command->data[2] << 8) + command->data[3]; + + family = aimutil_get16(command->data+0); + subtype= aimutil_get16(command->data+2); switch(family) { default: /* Unknown family */ - return aim_callhandler_noparam(command->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_UNKNOWN, command); + return aim_callhandler_noparam(sess, command->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_UNKNOWN, command); } return 1; diff --git a/aim_rxqueue.c b/aim_rxqueue.c index f33c458..73fd5a3 100644 --- a/aim_rxqueue.c +++ b/aim_rxqueue.c @@ -7,7 +7,7 @@ */ -#include "aim.h" +#include /* * This is a modified read() to make SURE we get the number @@ -47,18 +47,11 @@ int Read(int fd, u_char *buf, int len) return i; } -/* - struct command_struct * - get_generic( - struct connection_info struct *, - struct command_struct * - ) - - Grab as many command sequences as we can off the socket, and enqueue - each command in the incoming event queue in a seperate struct. - -*/ -int aim_get_command(void) +/* + * Grab as many command sequences as we can off the socket, and enqueue + * each command in the incoming event queue in a seperate struct. + */ +int aim_get_command(struct aim_session_t *sess) { int i, readgood, j, isav, err; int s; @@ -76,7 +69,7 @@ int aim_get_command(void) /* dont wait at all (ie, never call this unless something is there) */ tv.tv_sec = 0; tv.tv_usec = 0; - conn = aim_select(&tv); + conn = aim_select(sess, &tv); if (conn==NULL) return 0; /* nothing waiting */ @@ -154,19 +147,17 @@ int aim_get_command(void) workingStruct = (struct command_rx_struct *) malloc(sizeof(struct command_rx_struct)); workingStruct->lock = 1; /* lock the struct */ - /* store type -- byte 2 */ + /* store channel -- byte 2 */ workingStruct->type = (char) generic[1]; /* store seqnum -- bytes 3 and 4 */ - workingStruct->seqnum = ( (( (u_int) generic[2]) & 0xFF) << 8); - workingStruct->seqnum += ( (u_int) generic[3]) & 0xFF; + workingStruct->seqnum = aimutil_get16(generic+2); /* store commandlen -- bytes 5 and 6 */ - workingStruct->commandlen = ( (( (u_int) generic[4]) & 0xFF ) << 8); - workingStruct->commandlen += ( (u_int) generic[5]) & 0xFF; + workingStruct->commandlen = aimutil_get16(generic+4); /* malloc for data portion */ - workingStruct->data = (char *) malloc(workingStruct->commandlen); + workingStruct->data = (u_char *) malloc(workingStruct->commandlen); /* read the data portion of the packet */ i = Read(s, workingStruct->data, workingStruct->commandlen); @@ -186,13 +177,13 @@ int aim_get_command(void) workingStruct->lock = 0; /* unlock */ /* enqueue this packet */ - if (aim_queue_incoming == NULL) + if (sess->queue_incoming == NULL) { - aim_queue_incoming = workingStruct; + sess->queue_incoming = workingStruct; } else { - workingPtr = aim_queue_incoming; + workingPtr = sess->queue_incoming; while (workingPtr->next != NULL) workingPtr = workingPtr->next; workingPtr->next = workingStruct; @@ -205,12 +196,12 @@ int aim_get_command(void) } /* - purge_rxqueue() - - This is just what it sounds. It purges the receive (rx) queue of - all handled commands. This is normally called from inside - aim_rxdispatch() after it's processed all the commands in the queue. - + * purge_rxqueue() + * + * This is just what it sounds. It purges the receive (rx) queue of + * all handled commands. This is normally called from inside + * aim_rxdispatch() after it's processed all the commands in the queue. + * */ struct command_rx_struct *aim_purge_rxqueue(struct command_rx_struct *queue) { diff --git a/aim_search.c b/aim_search.c index 62e9016..78aef0f 100644 --- a/aim_search.c +++ b/aim_search.c @@ -6,9 +6,11 @@ * */ -#include +#include -u_long aim_usersearch_address(struct aim_conn_t *conn, char *address) +u_long aim_usersearch_address(struct aim_session_t *sess, + struct aim_conn_t *conn, + char *address) { struct command_tx_struct newpacket; @@ -20,23 +22,23 @@ u_long aim_usersearch_address(struct aim_conn_t *conn, char *address) if (conn) newpacket.conn = conn; else - newpacket.conn = aim_getconn_type(AIM_CONN_TYPE_BOS); + newpacket.conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); newpacket.type = 0x0002; newpacket.commandlen = 10 + strlen(address); newpacket.data = (char *) malloc(newpacket.commandlen); - aim_putsnac(newpacket.data, 0x000a, 0x0002, 0x0000, aim_snac_nextid); + aim_putsnac(newpacket.data, 0x000a, 0x0002, 0x0000, sess->snac_nextid); memcpy(&(newpacket.data[10]), address, strlen(address)); - aim_tx_enqueue(&newpacket); + aim_tx_enqueue(sess, &newpacket); { struct aim_snac_t snac; - snac.id = aim_snac_nextid; + snac.id = sess->snac_nextid; snac.family = 0x000a; snac.type = 0x0002; snac.flags = 0x0000; @@ -44,9 +46,9 @@ u_long aim_usersearch_address(struct aim_conn_t *conn, char *address) snac.data = malloc(strlen(address)+1); memcpy(snac.data, address, strlen(address)+1); - aim_newsnac(&snac); + aim_newsnac(sess, &snac); } - return (aim_snac_nextid++); + return (sess->snac_nextid++); } diff --git a/aim_snac.c b/aim_snac.c index f2701ec..1d2c4fb 100644 --- a/aim_snac.c +++ b/aim_snac.c @@ -12,52 +12,60 @@ * */ -#include -#include +#include -struct aim_snac_t *aim_outstanding_snacs = NULL; -u_long aim_snac_nextid = 0x00000001; - -u_long aim_newsnac(struct aim_snac_t *newsnac) { - struct aim_snac_t *snac = NULL, *cur = aim_outstanding_snacs; +u_long aim_newsnac(struct aim_session_t *sess, + struct aim_snac_t *newsnac) +{ + struct aim_snac_t *snac = NULL, *cur = NULL; - assert(newsnac != NULL); - snac = calloc(1, sizeof(struct aim_snac_t)); - assert(snac != NULL); - memcpy(snac, newsnac, sizeof(struct aim_snac_t)); - snac->issuetime = time(&snac->issuetime); - snac->next = NULL; + if (!newsnac) + return 0; - if (cur == NULL) { - aim_outstanding_snacs = snac; - return(snac->id); - } - while (cur->next != NULL) - cur = cur->next; - cur->next = snac; - return(snac->id); -} + cur = sess->outstanding_snacs; -struct aim_snac_t *aim_remsnac(u_long id) { - struct aim_snac_t *cur = aim_outstanding_snacs; + snac = calloc(1, sizeof(struct aim_snac_t)); + if (!snac) + return 0; + memcpy(snac, newsnac, sizeof(struct aim_snac_t)); + snac->issuetime = time(&snac->issuetime); + snac->next = NULL; + + if (cur == NULL) { + sess->outstanding_snacs = snac; + return(snac->id); + } + while (cur->next != NULL) + cur = cur->next; + cur->next = snac; + return(snac->id); +} - if (cur == NULL) - return(NULL); - if (cur->id == id) { - aim_outstanding_snacs = cur->next; - return(cur); - } - while (cur->next != NULL) { - if (cur->next->id == id) { - struct aim_snac_t *tmp = NULL; +struct aim_snac_t *aim_remsnac(struct aim_session_t *sess, + u_long id) +{ + struct aim_snac_t *cur; + + if (cur == NULL) + return(NULL); - tmp = cur->next; - cur->next = cur->next->next; - return(tmp); - } - cur = cur->next; - } - return(NULL); + cur = sess->outstanding_snacs; + + if (cur->id == id) { + sess->outstanding_snacs = cur->next; + return(cur); + } + while (cur->next != NULL) { + if (cur->next->id == id) { + struct aim_snac_t *tmp = NULL; + + tmp = cur->next; + cur->next = cur->next->next; + return(tmp); + } + cur = cur->next; + } + return(NULL); } /* @@ -68,14 +76,17 @@ struct aim_snac_t *aim_remsnac(u_long id) { * why its called _max_age). * */ -int aim_cleansnacs(int maxage) +int aim_cleansnacs(struct aim_session_t *sess, + int maxage) { - struct aim_snac_t *cur = aim_outstanding_snacs; + struct aim_snac_t *cur; struct aim_snac_t *remed = NULL; time_t curtime; + + cur = sess->outstanding_snacs; curtime = time(&curtime); - + while (cur) { if ( (cur) && (((cur->issuetime) + maxage) < curtime)) @@ -83,7 +94,7 @@ int aim_cleansnacs(int maxage) #if DEBUG > 1 printf("aimsnac: WARNING purged obsolete snac %ul\n", cur->id); #endif - remed = aim_remsnac(cur->id); + remed = aim_remsnac(sess, cur->id); if (remed) { if (remed->data) @@ -93,7 +104,7 @@ int aim_cleansnacs(int maxage) } cur = cur->next; } - + return 0; } diff --git a/aim_tlv.c b/aim_tlv.c index a8cf05b..53dc55d 100644 --- a/aim_tlv.c +++ b/aim_tlv.c @@ -1,4 +1,4 @@ -#include +#include struct aim_tlvlist_t *aim_readtlvchain(u_char *buf, int maxlen) { diff --git a/aim_txqueue.c b/aim_txqueue.c index c6f507b..50bf425 100644 --- a/aim_txqueue.c +++ b/aim_txqueue.c @@ -5,7 +5,7 @@ * */ -#include +#include /* * aim_tx_enqeue() @@ -21,7 +21,8 @@ * */ -int aim_tx_enqueue(struct command_tx_struct *newpacket) +int aim_tx_enqueue(struct aim_session_t *sess, + struct command_tx_struct *newpacket) { struct command_tx_struct *workingPtr = NULL; struct command_tx_struct *newpacket_copy = NULL; @@ -29,7 +30,7 @@ int aim_tx_enqueue(struct command_tx_struct *newpacket) if (newpacket->conn == NULL) { printf("aim_tx_enqueue: WARNING: enqueueing packet with no connecetion, defaulting to BOS\n"); - newpacket->conn = aim_getconn_type(AIM_CONN_TYPE_BOS); + newpacket->conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); } newpacket_copy = (struct command_tx_struct *) malloc (sizeof(struct command_tx_struct)); @@ -42,13 +43,13 @@ int aim_tx_enqueue(struct command_tx_struct *newpacket) newpacket_copy->sent = 0; /* not sent yet */ newpacket_copy->next = NULL; /* always last */ - if (aim_queue_outgoing == NULL) + if (sess->queue_outgoing == NULL) { - aim_queue_outgoing = newpacket_copy; + sess->queue_outgoing = newpacket_copy; } else { - workingPtr = aim_queue_outgoing; + workingPtr = sess->queue_outgoing; while (workingPtr->next != NULL) workingPtr = workingPtr->next; workingPtr->next = newpacket_copy; @@ -66,7 +67,7 @@ int aim_tx_enqueue(struct command_tx_struct *newpacket) #if debug > 1 printf("calling aim_tx_flushqueue()\n"); #endif - aim_tx_flushqueue(); + aim_tx_flushqueue(sess); #if debug > 1 printf("back from aim_tx_flushqueue()\n"); #endif @@ -75,13 +76,13 @@ int aim_tx_enqueue(struct command_tx_struct *newpacket) } /* - aim_get_next_txseqnum() - - This increments the tx command count, and returns the seqnum - that should be stamped on the next FLAP packet sent. This is - normally called during the final step of packet preparation - before enqueuement (in aim_tx_enqueue()). - + * aim_get_next_txseqnum() + * + * This increments the tx command count, and returns the seqnum + * that should be stamped on the next FLAP packet sent. This is + * normally called during the final step of packet preparation + * before enqueuement (in aim_tx_enqueue()). + * */ u_int aim_get_next_txseqnum(struct aim_conn_t *conn) { @@ -89,19 +90,19 @@ u_int aim_get_next_txseqnum(struct aim_conn_t *conn) } /* - aim_tx_printqueue() - - This is basically for debuging purposes only. It dumps all the - records in the tx queue and their current status. Very helpful - if the queue isn't working quite right. - + * aim_tx_printqueue() + * + * This is basically for debuging purposes only. It dumps all the + * records in the tx queue and their current status. Very helpful + * if the queue isn't working quite right. + * */ #if debug > 2 int aim_tx_printqueue(void) { struct command_tx_struct *workingPtr = NULL; - workingPtr = aim_queue_outgoing; + workingPtr = sess->queue_outgoing; #if debug > 2 printf("\ncurrent aim_queue_outgoing...\n"); printf("\ttype seqnum len lock sent\n"); @@ -125,30 +126,30 @@ int aim_tx_printqueue(void) #endif /* - aim_tx_flushqueue() - - This the function is responsable for putting the queued commands - onto the wire. This function is critical to the operation of - the queue and therefore is the most prone to brokenness. It - seems to be working quite well at this point. - - Procedure: - 1) Traverse the list, only operate on commands that are unlocked - and haven't been sent yet. - 2) Lock the struct - 3) Allocate a temporary buffer to store the finished, fully - processed packet in. - 4) Build the packet from the command_tx_struct data. - 5) Write the packet to the socket. - 6) If success, mark the packet sent, if fail report failure, do NOT - mark the packet sent (so it will not get purged and therefore - be attempted again on next call). - 7) Unlock the struct. - 8) Free the temp buffer - 9) Step to next struct in list and go back to 1. - + * aim_tx_flushqueue() + * + * This the function is responsable for putting the queued commands + * onto the wire. This function is critical to the operation of + * the queue and therefore is the most prone to brokenness. It + * seems to be working quite well at this point. + * + * Procedure: + * 1) Traverse the list, only operate on commands that are unlocked + * and haven't been sent yet. + * 2) Lock the struct + * 3) Allocate a temporary buffer to store the finished, fully + * processed packet in. + * 4) Build the packet from the command_tx_struct data. + * 5) Write the packet to the socket. + * 6) If success, mark the packet sent, if fail report failure, do NOT + * mark the packet sent (so it will not get purged and therefore + * be attempted again on next call). + * 7) Unlock the struct. + * 8) Free the temp buffer + * 9) Step to next struct in list and go back to 1. + * */ -int aim_tx_flushqueue(void) +int aim_tx_flushqueue(struct aim_session_t *sess) { struct command_tx_struct *workingPtr = NULL; u_char *curPacket = NULL; @@ -156,7 +157,7 @@ int aim_tx_flushqueue(void) int i = 0; #endif - workingPtr = aim_queue_outgoing; + workingPtr = sess->queue_outgoing; #if debug > 1 printf("beginning txflush...\n"); #endif @@ -185,19 +186,20 @@ int aim_tx_flushqueue(void) /* command byte */ curPacket[0] = 0x2a; + /* type/family byte */ curPacket[1] = workingPtr->type; + /* bytes 3+4: word: FLAP sequence number */ - curPacket[2] = (char) ( (workingPtr->seqnum) >> 8); - curPacket[3] = (char) ( (workingPtr->seqnum) & 0xFF); + aimutil_put16(curPacket+2, workingPtr->seqnum); + /* bytes 5+6: word: SNAC len */ - curPacket[4] = (char) ( (workingPtr->commandlen) >> 8); - curPacket[5] = (char) ( (workingPtr->commandlen) & 0xFF); + aimutil_put16(curPacket+4, workingPtr->commandlen); + /* bytes 7 and on: raw: SNAC data */ memcpy(&(curPacket[6]), workingPtr->data, workingPtr->commandlen); /* full image of raw packet data now in curPacket */ - if ( (u_int)write(workingPtr->conn->fd, curPacket, (workingPtr->commandlen + 6)) != (workingPtr->commandlen + 6)) { printf("\nWARNING: Error in sending packet 0x%4x -- will try again next time\n\n", workingPtr->seqnum); @@ -236,7 +238,7 @@ int aim_tx_flushqueue(void) #if debug > 1 printf("calling aim_tx_purgequeue()\n"); #endif - aim_tx_purgequeue(); + aim_tx_purgequeue(sess); #if debug > 1 printf("back from aim_tx_purgequeu() [you must be a lucky one]\n"); #endif @@ -245,14 +247,14 @@ int aim_tx_flushqueue(void) } /* - aim_tx_purgequeue() - - This is responsable for removing sent commands from the transmit - queue. This is not a required operation, but it of course helps - reduce memory footprint at run time! - + * aim_tx_purgequeue() + * + * This is responsable for removing sent commands from the transmit + * queue. This is not a required operation, but it of course helps + * reduce memory footprint at run time! + * */ -int aim_tx_purgequeue(void) +int aim_tx_purgequeue(struct aim_session_t *sess) { struct command_tx_struct *workingPtr = NULL; struct command_tx_struct *workingPtr2 = NULL; @@ -260,7 +262,7 @@ int aim_tx_purgequeue(void) printf("purgequeue(): starting purge\n"); #endif /* Empty queue: nothing to do */ - if (aim_queue_outgoing == NULL) + if (sess->queue_outgoing == NULL) { #if debug > 1 printf("purgequeue(): purge done (len=0)\n"); @@ -268,20 +270,20 @@ int aim_tx_purgequeue(void) return 0; } /* One Node queue: free node and return */ - else if (aim_queue_outgoing->next == NULL) + else if (sess->queue_outgoing->next == NULL) { #if debug > 1 printf("purgequeue(): entered case len=1\n"); #endif /* only free if sent AND unlocked -- dont assume sent structs are done */ - if ( (aim_queue_outgoing->lock == 0) && - (aim_queue_outgoing->sent == 1) ) + if ( (sess->queue_outgoing->lock == 0) && + (sess->queue_outgoing->sent == 1) ) { #if debug > 1 printf("purgequeue(): purging seqnum 0x%04x\n", aim_queue_outgoing->seqnum); #endif - workingPtr2 = aim_queue_outgoing; - aim_queue_outgoing = NULL; + workingPtr2 = sess->queue_outgoing; + sess->queue_outgoing = NULL; free(workingPtr2->data); free(workingPtr2); } diff --git a/aim_util.c b/aim_util.c index d901a0e..f7cb012 100644 --- a/aim_util.c +++ b/aim_util.c @@ -4,7 +4,7 @@ * */ -#include "aim.h" +#include int aimutil_put8(u_char *buf, u_char data) { diff --git a/aim_global.c b/deprecated/aim_global.c similarity index 96% rename from aim_global.c rename to deprecated/aim_global.c index caac61f..c9350af 100644 --- a/aim_global.c +++ b/deprecated/aim_global.c @@ -6,7 +6,7 @@ */ -#include "aim.h" +#include /* the dreaded global variables... */ diff --git a/faimconfig.h b/faimconfig.h deleted file mode 100644 index f61bc4a..0000000 --- a/faimconfig.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * faimconfig.h - * - * Contains various compile-time options that apply _only to libfaim. - * Note that setting any of these options in a frontend header does not imply - * 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. - * - */ - -#ifndef __FAIMCONFIG_H__ -#define __FAIMCONFIG_H__ - -/* - * set debug to be > 0 if you want debugging information spewing - * on the attached tty. set to 0 for daily use. this value - * is _not_ inherited by the frontend, only this backend. - * - * Default: 0 -*/ -#define debug 0 - -/* - * Maximum number of connections the library can simultaneously - * handle. Five is fairly arbitrary. Only one client that I - * know of uses more than one concurrently anyway (which means - * its only lightly tested too). - * - * Default: 5 - * - */ -#define AIM_CONN_MAX 5 - -/* - * define TIS_TELNET_PROXY if you have a TIS firewall (Gauntlet) and - * you want to use FAIM through the firewall - * - * XXX: The TIS firewall code hasn't existed, let alone worked, - * in many, many months. I'd be happy to take fixes. - * - * Default: undefined - */ -#undef TIS_TELNET_PROXY "proxy.mydomain.com" - -/* - * USE_SNAC_FOR_IMS is an old feature that allowed better - * tracking of error messages by caching SNAC IDs of outgoing - * ICBMs and comparing them to incoming errors. However, - * its a helluvalot of overhead for something that should - * rarely happen. - * - * Default: undefined. Hasn't been tested in quite a long - * time. Most likely doesn't even compile. - * - */ -#undef USE_SNAC_FOR_IMS - -/* - * Default Authorizer server name and TCP port for the OSCAR farm. - * - * You shouldn't need to change this unless you're writing - * your own server. - * - * Note that only one server is needed to start the whole - * AIM process. The later server addresses come from - * the authorizer service. - * - */ -#define FAIM_LOGIN_SERVER "login.oscar.aol.com" -#define FAIM_LOGIN_PORT 5190 - -/* - * MAX_READ_ERROR can be decreased if you find dead connections - * lingering around, and not getting detected, for too long. - * - * Default: 100 - * - */ -#define MAX_READ_ERROR 100 - -#endif /* __FAIMCONFIG_H__ */ -- 2.45.2