# HG changeset patch # User Eric Warmenhoven # Date 992669288 0 # Node ID 6bdf9954097cab2556fc8e553f7626415a71c76b # Parent 705783e5ab8ce238ec3bd78eb7b1743a516580c5 [gaim-migrate @ 2044] oscar is much less segfaulty. and more reliable. yes. committer: Tailor Script diff -r 705783e5ab8c -r 6bdf9954097c libfaim/CHANGES --- a/libfaim/CHANGES Sat Jun 16 03:18:00 2001 +0000 +++ b/libfaim/CHANGES Sat Jun 16 05:28:08 2001 +0000 @@ -1,6 +1,13 @@ No release numbers ------------------ + - Fri Jun 15 17:51:27 EDT 2001 + - Make faimtest compile on RH7.1 (new gcc). + - Add aim_conn_getsess() + - Add aim_getconn_type_all() and aim_getconn_fd(). + - Make aim_connrst() and aim_conn_getnext() static to conn.c. + - Why does arcanejill think she is in EDT? Oh well. + - Thu Jun 14 17:37:47 PDT 2001 - Rearrange aim_setprofile(). It will now let you _not_ send a profile, if you really want to (pass NULL). Note that this is quite different diff -r 705783e5ab8c -r 6bdf9954097c libfaim/aim.h --- a/libfaim/aim.h Sat Jun 16 03:18:00 2001 +0000 +++ b/libfaim/aim.h Sat Jun 16 05:28:08 2001 +0000 @@ -260,6 +260,7 @@ struct aim_rxcblist_t *handlerlist; faim_mutex_t active; /* lock around read/writes */ faim_mutex_t seqnum_lock; /* lock around ->seqnum changes */ + void *sessv; struct aim_conn_t *next; }; @@ -514,6 +515,7 @@ faim_export int aim_conn_addhandler(struct aim_session_t *, struct aim_conn_t *conn, u_short family, u_short type, aim_rxcallback_t newhandler, u_short flags); faim_export int aim_clearhandlers(struct aim_conn_t *conn); +faim_export struct aim_session_t *aim_conn_getsess(struct aim_conn_t *conn); faim_export void aim_conn_close(struct aim_conn_t *deadconn); faim_export struct aim_conn_t *aim_newconn(struct aim_session_t *, int type, char *dest); faim_export int aim_conngetmaxfd(struct aim_session_t *); @@ -529,6 +531,8 @@ faim_export void aim_session_kill(struct aim_session_t *); faim_export void aim_setupproxy(struct aim_session_t *sess, char *server, char *username, char *password); faim_export struct aim_conn_t *aim_getconn_type(struct aim_session_t *, int type); +faim_export struct aim_conn_t *aim_getconn_type_all(struct aim_session_t *, int type); +faim_export struct aim_conn_t *aim_getconn_fd(struct aim_session_t *, int fd); /* aim_misc.c */ diff -r 705783e5ab8c -r 6bdf9954097c libfaim/aim_internal.h --- a/libfaim/aim_internal.h Sat Jun 16 03:18:00 2001 +0000 +++ b/libfaim/aim_internal.h Sat Jun 16 05:28:08 2001 +0000 @@ -83,8 +83,6 @@ faim_internal int aim_cleansnacs(struct aim_session_t *, int maxage); faim_internal int aim_putsnac(u_char *, int, int, int, u_long); -faim_internal void aim_connrst(struct aim_session_t *); -faim_internal struct aim_conn_t *aim_conn_getnext(struct aim_session_t *); faim_internal struct aim_conn_t *aim_cloneconn(struct aim_session_t *sess, struct aim_conn_t *src); faim_internal int aim_oft_buildheader(unsigned char *,struct aim_fileheader_t *); diff -r 705783e5ab8c -r 6bdf9954097c libfaim/conn.c --- a/libfaim/conn.c Sat Jun 16 03:18:00 2001 +0000 +++ b/libfaim/conn.c Sat Jun 16 05:28:08 2001 +0000 @@ -22,7 +22,7 @@ * Clears out the connection list and kills any connections left. * */ -faim_internal void aim_connrst(struct aim_session_t *sess) +static void aim_connrst(struct aim_session_t *sess) { faim_mutex_init(&sess->connlistlock); if (sess->connlist) { @@ -72,7 +72,7 @@ * Allocate a new empty connection structure. * */ -faim_internal struct aim_conn_t *aim_conn_getnext(struct aim_session_t *sess) +static struct aim_conn_t *aim_conn_getnext(struct aim_session_t *sess) { struct aim_conn_t *newconn, *cur; @@ -191,6 +191,38 @@ break; } faim_mutex_unlock(&sess->connlistlock); + + return cur; +} + +faim_export struct aim_conn_t *aim_getconn_type_all(struct aim_session_t *sess, + int type) +{ + struct aim_conn_t *cur; + + faim_mutex_lock(&sess->connlistlock); + for (cur = sess->connlist; cur; cur = cur->next) { + if (cur->type == type) + break; + } + faim_mutex_unlock(&sess->connlistlock); + + return cur; +} + +/* If you pass -1 for the fd, you'll get what you ask for. Gibberish. */ +faim_export struct aim_conn_t *aim_getconn_fd(struct aim_session_t *sess, + int fd) +{ + struct aim_conn_t *cur; + + faim_mutex_lock(&sess->connlistlock); + for (cur = sess->connlist; cur; cur = cur->next) { + if (cur->fd == fd) + break; + } + faim_mutex_unlock(&sess->connlistlock); + return cur; } @@ -393,6 +425,7 @@ conn->priv = src->priv; conn->lastactivity = src->lastactivity; conn->forcedlatency = src->forcedlatency; + conn->sessv = src->sessv; /* clone handler list */ for (cur = src->handlerlist; cur; cur = cur->next) { @@ -432,7 +465,8 @@ return NULL; faim_mutex_lock(&connstruct->active); - + + connstruct->sessv = (void *)sess; connstruct->type = type; if (!dest) { /* just allocate a struct */ @@ -899,6 +933,15 @@ return 0; } +faim_export struct aim_session_t *aim_conn_getsess(struct aim_conn_t *conn) +{ + + if (!conn) + return NULL; + + return (struct aim_session_t *)conn->sessv; +} + /* * aim_logoff() * diff -r 705783e5ab8c -r 6bdf9954097c src/oscar.c --- a/src/oscar.c Sat Jun 16 03:18:00 2001 +0000 +++ b/src/oscar.c Sat Jun 16 05:28:08 2001 +0000 @@ -103,7 +103,6 @@ int id; struct gaim_connection *gc; /* i hate this. */ struct conversation *cnv; /* bah. */ - gpointer priv; /* don't ask. */ }; struct direct_im { @@ -160,18 +159,6 @@ }; #endif -static gpointer memdup(gconstpointer mem, guint size) -{ - gpointer new_mem; - - if (mem) { - new_mem = malloc(size); - memcpy(new_mem, mem, size); - return new_mem; - } else - return NULL; -} - static struct direct_im *find_direct_im(struct oscar_data *od, char *who) { GSList *d = od->direct_ims; char *n = g_strdup(normalize(who)); @@ -263,31 +250,6 @@ return c; } -static struct gaim_connection *find_gaim_conn_by_oscar_conn(struct aim_conn_t *conn) { - GSList *g = connections; - struct gaim_connection *c = NULL; - struct aim_conn_t *s; - while (g) { - c = (struct gaim_connection *)g->data; - if (c->protocol != PROTO_OSCAR) { - c = NULL; - g = g->next; - continue; - } - s = ((struct oscar_data *)c->proto_data)->sess->connlist; - while (s) { - if (conn == s) - break; - s = s->next; - } - if (s) break; - g = g->next; - c = NULL; - } - - return c; -} - static int gaim_parse_auth_resp (struct aim_session_t *, struct command_rx_struct *, ...); static int gaim_parse_login (struct aim_session_t *, struct command_rx_struct *, ...); static int gaim_server_ready (struct aim_session_t *, struct command_rx_struct *, ...); @@ -356,13 +318,14 @@ static void oscar_callback(gpointer data, gint source, GdkInputCondition condition) { struct aim_conn_t *conn = (struct aim_conn_t *)data; - struct gaim_connection *gc = find_gaim_conn_by_oscar_conn(conn); + struct aim_session_t *sess = aim_conn_getsess(conn); + struct gaim_connection *gc = sess ? sess->aux_data : NULL; struct oscar_data *odata; if (!gc) { - /* gc is null. we return, else we seg SIGSEG on next line. */ - debug_printf("oscar callback for closed connection (1).\n"); - return; + /* gc is null. we return, else we seg SIGSEG on next line. */ + debug_printf("oscar callback for closed connection (1).\n"); + return; } odata = (struct oscar_data *)gc->proto_data; @@ -468,7 +431,7 @@ odata = gc->proto_data; sess = odata->sess; - conn = aim_getconn_type(sess, AIM_CONN_TYPE_AUTH); + conn = aim_getconn_type_all(sess, AIM_CONN_TYPE_AUTH); if (source < 0) { hide_login_progress(gc, _("Couldn't connect to host")); @@ -476,14 +439,9 @@ return; } - if (conn->fd != source) - conn->fd = source; - - aim_request_login(sess, conn, gc->username); - + aim_conn_completeconnect(sess, conn); gc->inpa = gdk_input_add(conn->fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION, oscar_callback, conn); - debug_printf(_("Password sent, waiting for response\n")); } @@ -522,16 +480,18 @@ aim_conn_addhandler(sess, conn, 0x0017, 0x0007, gaim_parse_login, 0); aim_conn_addhandler(sess, conn, 0x0017, 0x0003, gaim_parse_auth_resp, 0); + conn->status |= AIM_CONN_STATUS_INPROGRESS; conn->fd = proxy_connect(user->proto_opt[USEROPT_AUTH][0] ? user->proto_opt[USEROPT_AUTH] : FAIM_LOGIN_SERVER, user->proto_opt[USEROPT_AUTHPORT][0] ? atoi(user->proto_opt[USEROPT_AUTHPORT]) : FAIM_LOGIN_PORT, oscar_login_connect, gc); - if (!user->gc || (conn->fd < 0)) { + if (conn->fd < 0) { hide_login_progress(gc, _("Couldn't connect to host")); signoff(gc); return; } + aim_request_login(sess, conn, gc->username); } static void oscar_close(struct gaim_connection *gc) { @@ -599,23 +559,15 @@ odata = gc->proto_data; sess = odata->sess; - bosconn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS); + bosconn = odata->conn; if (source < 0) { - if (bosconn->priv) - g_free(bosconn->priv); - bosconn->priv = NULL; hide_login_progress(gc, _("Could Not Connect")); signoff(gc); return; } - if (bosconn->fd != source) - bosconn->fd = source; - - aim_auth_sendcookie(sess, bosconn, bosconn->priv); - free(bosconn->priv); - bosconn->priv = NULL; + aim_conn_completeconnect(sess, bosconn); gc->inpa = gdk_input_add(bosconn->fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION, oscar_callback, bosconn); set_login_progress(gc, 4, _("Connection established, cookie sent")); @@ -750,17 +702,15 @@ } } host = g_strndup(bosip, i); - bosconn->priv = memdup(cookie, AIM_COOKIELEN); + bosconn->status |= AIM_CONN_STATUS_INPROGRESS; bosconn->fd = proxy_connect(host, port, oscar_bos_connect, gc); g_free(host); - if (!user->gc || (bosconn->fd < 0)) { - if (bosconn->priv) - g_free(bosconn->priv); - bosconn->priv = NULL; + if (bosconn->fd < 0) { hide_login_progress(gc, _("Could Not Connect")); signoff(gc); return -1; } + aim_auth_sendcookie(sess, bosconn, cookie); return 1; } @@ -824,9 +774,6 @@ return; } - if (pos->fd != source) - pos->fd = source; - g_snprintf(buf, sizeof(buf), "GET " AIMHASHDATA "?offset=%ld&len=%ld&modname=%s HTTP/1.0\n\n", pos->offset, pos->len, pos->modname ? pos->modname : ""); @@ -1016,23 +963,15 @@ odata = gc->proto_data; sess = odata->sess; - tstconn = aim_getconn_type(sess, AIM_CONN_TYPE_CHATNAV); + tstconn = aim_getconn_type_all(sess, AIM_CONN_TYPE_CHATNAV); if (source < 0) { - if (tstconn->priv) - g_free(tstconn->priv); - tstconn->priv = NULL; aim_conn_kill(sess, &tstconn); debug_printf("unable to connect to chatnav server\n"); return; } - if (tstconn->fd != source) - tstconn->fd = source; - - aim_auth_sendcookie(sess, tstconn, tstconn->priv); - free(tstconn->priv); - tstconn->priv = NULL; + aim_conn_completeconnect(sess, tstconn); odata->cnpa = gdk_input_add(tstconn->fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION, oscar_callback, tstconn); debug_printf("chatnav: connected\n"); @@ -1052,23 +991,15 @@ odata = gc->proto_data; sess = odata->sess; - tstconn = aim_getconn_type(sess, AIM_CONN_TYPE_AUTH); + tstconn = aim_getconn_type_all(sess, AIM_CONN_TYPE_AUTH); if (source < 0) { - if (tstconn->priv) - g_free(tstconn->priv); - tstconn->priv = NULL; aim_conn_kill(sess, &tstconn); debug_printf("unable to connect to authorizer\n"); return; } - if (tstconn->fd != source) - tstconn->fd = source; - - aim_auth_sendcookie(sess, tstconn, tstconn->priv); - free(tstconn->priv); - tstconn->priv = NULL; + aim_conn_completeconnect(sess, tstconn); odata->paspa = gdk_input_add(tstconn->fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION, oscar_callback, tstconn); debug_printf("chatnav: connected\n"); @@ -1084,7 +1015,6 @@ if (!g_slist_find(connections, gc)) { close(source); - g_free(ccon->priv); g_free(ccon->show); g_free(ccon->name); g_free(ccon); @@ -1097,25 +1027,20 @@ if (source < 0) { aim_conn_kill(sess, &tstconn); - g_free(ccon->priv); g_free(ccon->show); g_free(ccon->name); g_free(ccon); return; } - if (ccon->fd != source) - ccon->fd = tstconn->fd = source; - + aim_conn_completeconnect(sess, ccon->conn); ccon->inpa = gdk_input_add(tstconn->fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION, oscar_callback, tstconn); odata->oscar_chats = g_slist_append(odata->oscar_chats, ccon); aim_chat_attachname(tstconn, ccon->name); - aim_auth_sendcookie(sess, tstconn, ccon->priv); - g_free(ccon->priv); - ccon->priv = NULL; } + int gaim_handle_redirect(struct aim_session_t *sess, struct command_rx_struct *command, ...) { va_list ap; @@ -1128,7 +1053,6 @@ int i; char *host; int port; - int fd; port = user->proto_opt[USEROPT_AUTHPORT][0] ? atoi(user->proto_opt[USEROPT_AUTHPORT]) : FAIM_LOGIN_PORT, @@ -1161,18 +1085,15 @@ aim_conn_addhandler(sess, tstconn, 0x0007, 0x0005, gaim_info_change, 0); aim_conn_addhandler(sess, tstconn, 0x0007, 0x0007, gaim_account_confirm, 0); - tstconn->priv = memdup(cookie, AIM_COOKIELEN); - fd = proxy_connect(host, port, oscar_auth_connect, gc); - if (fd < 0) { - if (tstconn->priv) - g_free(tstconn->priv); - tstconn->priv = NULL; + tstconn->status |= AIM_CONN_STATUS_INPROGRESS; + tstconn->fd = proxy_connect(host, port, oscar_auth_connect, gc); + if (tstconn->fd < 0) { aim_conn_kill(sess, &tstconn); debug_printf("unable to reconnect with authorizer\n"); g_free(host); return 1; } - tstconn->fd = fd; + aim_auth_sendcookie(sess, tstconn, cookie); break; case 0xd: /* ChatNav */ tstconn = aim_newconn(sess, AIM_CONN_TYPE_CHATNAV, NULL); @@ -1183,18 +1104,15 @@ } aim_conn_addhandler(sess, tstconn, 0x0001, 0x0003, gaim_server_ready, 0); - tstconn->priv = memdup(cookie, AIM_COOKIELEN); - fd = proxy_connect(host, port, oscar_chatnav_connect, gc); - if (fd < 0) { - if (tstconn->priv) - g_free(tstconn->priv); - tstconn->priv = NULL; + tstconn->status |= AIM_CONN_STATUS_INPROGRESS; + tstconn->fd = proxy_connect(host, port, oscar_chatnav_connect, gc); + if (tstconn->fd < 0) { aim_conn_kill(sess, &tstconn); debug_printf("unable to connect to chatnav server\n"); g_free(host); return 1; } - tstconn->fd = fd; + aim_auth_sendcookie(sess, tstconn, cookie); break; case 0xe: /* Chat */ { @@ -1217,19 +1135,18 @@ ccon->exchange = exchange; ccon->show = extract_name(roomname); - ccon->priv = memdup(cookie, AIM_COOKIELEN); - fd = proxy_connect(host, port, oscar_chat_connect, ccon); - if (fd < 0) { + ccon->conn->status |= AIM_CONN_STATUS_INPROGRESS; + ccon->conn->fd = proxy_connect(host, port, oscar_chat_connect, ccon); + if (ccon->conn->fd < 0) { aim_conn_kill(sess, &tstconn); debug_printf("unable to connect to chat server\n"); g_free(host); - g_free(ccon->priv); g_free(ccon->show); g_free(ccon->name); g_free(ccon); return 1; } - ccon->fd = tstconn->fd = fd; + aim_auth_sendcookie(sess, tstconn, cookie); debug_printf("Connected to chat room %s exchange %d\n", roomname, exchange); } break; @@ -1316,19 +1233,23 @@ struct oscar_data *od = gc->proto_data; char buf[256]; - if (source < 0) { - od->direct_ims = g_slist_remove(od->direct_ims, dim); + if (!g_slist_find(connections, gc)) { g_free(dim); return; } - if (dim->conn->fd != source) - dim->conn->fd = source; - + if (source < 0) { + g_free(dim); + return; + } + + aim_conn_completeconnect(od->sess, dim->conn); if (!(dim->cnv = find_conversation(dim->name))) dim->cnv = new_conversation(dim->name); g_snprintf(buf, sizeof buf, _("Direct IM with %s established"), dim->name); write_to_conv(dim->cnv, buf, WFLAG_SYSTEM, NULL, time((time_t)NULL)); + od->direct_ims = g_slist_append(od->direct_ims, dim); + gtk_signal_connect(GTK_OBJECT(dim->cnv->window), "destroy", GTK_SIGNAL_FUNC(delete_direct_im), dim); @@ -1375,6 +1296,7 @@ } } host = g_strndup(d->priv->ip, i); + dim->conn->status |= AIM_CONN_STATUS_INPROGRESS; dim->conn->fd = proxy_connect(host, port, oscar_directim_callback, dim); g_free(host); if (dim->conn->fd < 0) { @@ -1384,8 +1306,6 @@ return TRUE; } - od->direct_ims = g_slist_append(od->direct_ims, dim); - cancel_direct_im(w, d); return TRUE;