# HG changeset patch # User Mark Doliner # Date 1104471746 0 # Node ID ad92587161444b8ec2e111695943c5fb82f9c1f7 # Parent 0c020a10d5da8c53b6042262e1a00efccb7fbdb1 [gaim-migrate @ 11727] This should fix sf bug #1093455 Basically it's possible for people to kick you from an AIM chat room, and I don't think there's anything we can do about this. When this happens you can't rejoin, and I don't think there's anything we can do about that, either. But now, at least oscar will tell the core you're no longer in the chat room when you've been kicked. i.e. it changes the chat title from "My Lame Chat" to "(My Lame Chat)" committer: Tailor Script diff -r 0c020a10d5da -r ad9258716144 src/protocols/oscar/oscar.c --- a/src/protocols/oscar/oscar.c Thu Dec 30 19:50:49 2004 +0000 +++ b/src/protocols/oscar/oscar.c Fri Dec 31 05:42:26 2004 +0000 @@ -131,7 +131,6 @@ char *show; /* AOL did something funny to us */ fu16_t exchange; fu16_t instance; - int fd; /* this is redundant since we have the conn below */ aim_conn_t *conn; int inpa; int id; @@ -802,51 +801,73 @@ return tmp; } -static struct chat_connection *find_oscar_chat(GaimConnection *gc, int id) { - GSList *g = ((OscarData *)gc->proto_data)->oscar_chats; - struct chat_connection *c = NULL; - - while (g) { - c = (struct chat_connection *)g->data; - if (c->id == id) - break; - g = g->next; - c = NULL; - } - - return c; -} - -static struct chat_connection *find_oscar_chat_by_conn(GaimConnection *gc, - aim_conn_t *conn) { - GSList *g = ((OscarData *)gc->proto_data)->oscar_chats; - struct chat_connection *c = NULL; - - while (g) { - c = (struct chat_connection *)g->data; - if (c->conn == conn) - break; - g = g->next; - c = NULL; - } - - return c; -} - -static struct chat_connection *find_oscar_chat_by_conv(GaimConnection *gc, - GaimConversation *conv) { - GSList *g = ((OscarData *)gc->proto_data)->oscar_chats; - struct chat_connection *c = NULL; - - while (g) { - c = (struct chat_connection *)g->data; - if (c->conv == conv) - break; - g = g->next; - c = NULL; - } - - return c; +static struct chat_connection * +find_oscar_chat(GaimConnection *gc, int id) +{ + OscarData *od = (OscarData *)gc->proto_data; + GSList *cur; + struct chat_connection *cc; + + for (cur = od->oscar_chats; cur != NULL; cur = cur->next) + { + cc = (struct chat_connection *)cur->data; + if (cc->id == id) + return cc; + } + + return NULL; +} + +static struct chat_connection * +find_oscar_chat_by_conn(GaimConnection *gc, aim_conn_t *conn) +{ + OscarData *od = (OscarData *)gc->proto_data; + GSList *cur; + struct chat_connection *cc; + + for (cur = od->oscar_chats; cur != NULL; cur = cur->next) + { + cc = (struct chat_connection *)cur->data; + if (cc->conn == conn) + return cc; + } + + return NULL; +} + +static struct chat_connection * +find_oscar_chat_by_conv(GaimConnection *gc, GaimConversation *conv) +{ + OscarData *od = (OscarData *)gc->proto_data; + GSList *cur; + struct chat_connection *cc; + + for (cur = od->oscar_chats; cur != NULL; cur = cur->next) + { + cc = (struct chat_connection *)cur->data; + if (cc->conv == conv) + return cc; + } + + return NULL; +} + +static void +oscar_chat_kill(GaimConnection *gc, struct chat_connection *cc) +{ + OscarData *od = (OscarData *)gc->proto_data; + + /* Notify the conversation window that we've left the chat */ + serv_got_chat_left(gc, gaim_conv_chat_get_id(GAIM_CONV_CHAT(cc->conv))); + + /* Destroy the chat_connection */ + od->oscar_chats = g_slist_remove(od->oscar_chats, cc); + if (cc->inpa > 0) + gaim_input_remove(cc->inpa); + aim_conn_kill(od->sess, &cc->conn); + g_free(cc->name); + g_free(cc->show); + g_free(cc); } /***************************************************************************** @@ -1555,7 +1576,7 @@ "oscar callback for closed connection (1).\n"); return; } - + od = (OscarData *)gc->proto_data; if (!g_list_find(gaim_connections_get_all(), gc)) { @@ -1592,23 +1613,23 @@ "invalid data was received on the oscar TCP stream\n"); gaim_connection_error(gc, _("Disconnected.")); } else if (conn->type == AIM_CONN_TYPE_CHAT) { - struct chat_connection *c = find_oscar_chat_by_conn(gc, conn); - GaimConversation *conv = gaim_find_chat(gc, c->id); + struct chat_connection *cc = find_oscar_chat_by_conn(gc, conn); + GaimConversation *conv = gaim_find_chat(gc, cc->id); char *buf; - gaim_debug_info("oscar", - "disconnected from chat room %s\n", c->name); - c->conn = NULL; - if (c->inpa > 0) - gaim_input_remove(c->inpa); - c->inpa = 0; - c->fd = -1; - aim_conn_kill(od->sess, &conn); - buf = g_strdup_printf(_("You have been disconnected from chat room %s."), c->name); - if (conv) + + gaim_debug_info("oscar", "Lost connection " + "to chat room %s\n", cc->name); + + buf = g_strdup_printf(_("You have lost your connection " + "to chat room %s."), cc->name); + if (conv != NULL) gaim_conversation_write(conv, NULL, buf, GAIM_MESSAGE_ERROR, time(NULL)); else gaim_notify_error(gc, NULL, buf, NULL); g_free(buf); + + oscar_chat_kill(gc, cc); + } else if (conn->type == AIM_CONN_TYPE_CHATNAV) { if (od->cnpa > 0) gaim_input_remove(od->cnpa); @@ -2808,7 +2829,6 @@ ccon = g_new0(struct chat_connection, 1); ccon->conn = tstconn; ccon->gc = gc; - ccon->fd = -1; ccon->name = g_strdup(redir->chat.room); ccon->exchange = redir->chat.exchange; ccon->instance = redir->chat.instance; @@ -3262,7 +3282,7 @@ } } - if ((iconfile = gaim_account_get_buddy_icon(account)) && + if ((iconfile = gaim_account_get_buddy_icon(account)) && (args->icbmflags & AIM_IMFLAGS_BUDDYREQ) && !bi->ico_sent && bi->ico_informed) { FILE *file; struct stat st; @@ -4759,11 +4779,13 @@ msg = va_arg(ap, char *); va_end(ap); - gaim_debug_info("oscar", - "Disconnected. Code is 0x%04x and msg is %s\n", code, - (msg != NULL ? msg : "")); - - if ((fr) && (fr->conn) && (fr->conn->type == AIM_CONN_TYPE_BOS)) { + gaim_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(fr->conn != NULL, 1); + + if (fr->conn->type == AIM_CONN_TYPE_BOS) { if (code == 0x0001) { gc->wants_to_die = TRUE; gaim_connection_error(gc, _("You have been disconnected because you have signed on with this screen name at another location.")); @@ -4771,6 +4793,22 @@ gaim_connection_error(gc, _("You have been signed off for an unknown reason.")); } od->killme = TRUE; + } else if (fr->conn->type == AIM_CONN_TYPE_CHAT) { + struct chat_connection *cc; + GaimConversation *conv; + + cc = find_oscar_chat_by_conn(gc, fr->conn); + conv = gaim_find_chat(gc, cc->id); + + if (conv != NULL) + { + gchar *buf; + buf = g_strdup_printf(_("You have been disconnected from chat " + "room %s."), cc->name); + gaim_conversation_write(conv, NULL, buf, GAIM_MESSAGE_ERROR, time(NULL)); + g_free(buf); + } + oscar_chat_kill(gc, cc); } return 1; @@ -6484,42 +6522,20 @@ ccon->exchange, ccon->name, 0x0); } -static void oscar_chat_leave(GaimConnection *gc, int id) { - OscarData *od = gc ? (OscarData *)gc->proto_data : NULL; - GSList *bcs = gc->buddy_chats; - GaimConversation *b = NULL; - struct chat_connection *c = NULL; - int count = 0; - - while (bcs) { - count++; - b = (GaimConversation *)bcs->data; - if (id == gaim_conv_chat_get_id(GAIM_CONV_CHAT(b))) - break; - bcs = bcs->next; - b = NULL; - } - - if (!b) - return; - - gaim_debug_info("oscar", - "Attempting to leave room %s (currently in %d rooms)\n", b->name, count); - - c = find_oscar_chat(gc, gaim_conv_chat_get_id(GAIM_CONV_CHAT(b))); - if (c != NULL) { - if (od) - od->oscar_chats = g_slist_remove(od->oscar_chats, c); - if (c->inpa > 0) - gaim_input_remove(c->inpa); - if (gc && od->sess) - aim_conn_kill(od->sess, &c->conn); - g_free(c->name); - g_free(c->show); - g_free(c); - } - /* we do this because with Oscar it doesn't tell us we left */ - serv_got_chat_left(gc, gaim_conv_chat_get_id(GAIM_CONV_CHAT(b))); +static void +oscar_chat_leave(GaimConnection *gc, int id) +{ + GaimConversation *conv; + struct chat_connection *cc; + + conv = gaim_find_chat(gc, id); + + g_return_if_fail(conv != NULL); + + gaim_debug_info("oscar", "Leaving chat room %s\n", conv->name); + + cc = find_oscar_chat(gc, gaim_conv_chat_get_id(GAIM_CONV_CHAT(conv))); + oscar_chat_kill(gc, cc); } static int oscar_send_chat(GaimConnection *gc, int id, const char *message) { diff -r 0c020a10d5da -r ad9258716144 src/protocols/oscar/rxhandlers.c --- a/src/protocols/oscar/rxhandlers.c Thu Dec 30 19:50:49 2004 +0000 +++ b/src/protocols/oscar/rxhandlers.c Fri Dec 31 05:42:26 2004 +0000 @@ -192,7 +192,7 @@ if (aim_tlv_gettlv(tlvlist, 0x000b, 1)) msg = aim_tlv_getstr(tlvlist, 0x000b, 1); - if ((userfunc = aim_callhandler(sess, fr->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR))) + if ((userfunc = aim_callhandler(sess, fr->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR))) ret = userfunc(sess, fr, code, msg); aim_tlvlist_free(&tlvlist);