# HG changeset patch # User Mark Doliner # Date 1185092307 0 # Node ID a244c34ce59ce7d2d8f69ea65ae3441daa74e08a # Parent ac9f19a3105170d0e46940fee6b62ec21c2b0ae8 Call the AIM_CB_SPECIAL_CONNERR callback from flap_connection_destroy_cb() rather than parse_flap_ch4(). This ensures that the AIM_CB_SPECIAL_CONNERR callback function gets called even if AOL ends our FLAP connection without sending the customary channel 4 FLAP. Apparently you're not allowed to be in chat rooms from two locations. So when you sign on from a second location AOL severs the chat connections from your first location. It does this by sending a TCP RST rather than the expected channel 4 FLAP. This lead to a crash if you were in a chat room, then signed on from a second location. Fixes #1937. diff -r ac9f19a31051 -r a244c34ce59c libpurple/protocols/oscar/flap_connection.c --- a/libpurple/protocols/oscar/flap_connection.c Sun Jul 22 07:09:33 2007 +0000 +++ b/libpurple/protocols/oscar/flap_connection.c Sun Jul 22 08:18:27 2007 +0000 @@ -356,16 +356,21 @@ FlapConnection *conn; OscarData *od; PurpleAccount *account; + aim_rxcallback_t userfunc; conn = data; od = conn->od; account = (PURPLE_CONNECTION_IS_VALID(od->gc) ? purple_connection_get_account(od->gc) : NULL); purple_debug_info("oscar", "Destroying oscar connection of " - "type 0x%04hx\n", conn->type); + "type 0x%04hx. Disconnect reason is %d\n", + conn->type, conn->disconnect_reason); od->oscar_connections = g_slist_remove(od->oscar_connections, conn); + if ((userfunc = aim_callhandler(od, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR))) + userfunc(od, conn, NULL, conn->disconnect_code, conn->error_message); + /* * TODO: If we don't have a SNAC_FAMILY_LOCATE connection then * we should try to request one instead of disconnecting. @@ -695,8 +700,6 @@ { GSList *tlvlist; char *msg = NULL; - guint16 code = 0; - aim_rxcallback_t userfunc; if (byte_stream_empty(&frame->data) == 0) { /* XXX should do something with this */ @@ -713,13 +716,17 @@ tlvlist = aim_tlvlist_read(&frame->data); if (aim_tlv_gettlv(tlvlist, 0x0009, 1)) - code = aim_tlv_get16(tlvlist, 0x0009, 1); + conn->disconnect_code = aim_tlv_get16(tlvlist, 0x0009, 1); if (aim_tlv_gettlv(tlvlist, 0x000b, 1)) msg = aim_tlv_getstr(tlvlist, 0x000b, 1); - if ((userfunc = aim_callhandler(od, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR))) - userfunc(od, conn, frame, code, msg); + /* + * The server ended this FLAP connnection, so let's be nice and + * close the physical TCP connection + */ + flap_connection_schedule_destroy(conn, + OSCAR_DISCONNECT_REMOTE_CLOSED, msg); aim_tlvlist_free(tlvlist); diff -r ac9f19a31051 -r a244c34ce59c libpurple/protocols/oscar/oscar.c --- a/libpurple/protocols/oscar/oscar.c Sun Jul 22 07:09:33 2007 +0000 +++ b/libpurple/protocols/oscar/oscar.c Sun Jul 22 08:18:27 2007 +0000 @@ -3472,7 +3472,6 @@ purple_debug_info("oscar", "Disconnected. Code is 0x%04x and msg is %s\n", code, (msg != NULL ? msg : "")); - g_return_val_if_fail(fr != NULL, 1); g_return_val_if_fail(conn != NULL, 1); if (conn->type == SNAC_FAMILY_LOCATE) { diff -r ac9f19a31051 -r a244c34ce59c libpurple/protocols/oscar/oscar.h --- a/libpurple/protocols/oscar/oscar.h Sun Jul 22 07:09:33 2007 +0000 +++ b/libpurple/protocols/oscar/oscar.h Sun Jul 22 08:18:27 2007 +0000 @@ -378,6 +378,7 @@ guint destroy_timeout; OscarDisconnectReason disconnect_reason; gchar *error_message; + guint16 disconnect_code; /* A few variables that are only used when connecting */ PurpleProxyConnectData *connect_data;