Mercurial > pidgin
changeset 21746:82016f2ea290
merge of '36ed28f7212302e500d79866f33eacde299878b2'
and 'ef615b4ae18609e0cbe2783aafc7a5114db4a06f'
author | Luke Schierer <lschiere@pidgin.im> |
---|---|
date | Mon, 03 Dec 2007 16:20:59 +0000 |
parents | ea18c129edfb (current diff) 2c0ae5e29376 (diff) |
children | d376b1e191b5 |
files | |
diffstat | 23 files changed, 301 insertions(+), 178 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Mon Dec 03 14:46:54 2007 +0000 +++ b/ChangeLog Mon Dec 03 16:20:59 2007 +0000 @@ -1,13 +1,17 @@ Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul -version 2.3.1 (??/??/????): +version 2.3.2 (??/??/????): libpurple: * Fixed various problems with loss of status messages when going or returning from idle on MySpaceIM. Finch: - * Color is used in the buddylist to indicate status. Look at the sample - gntrc file in the man-page for details. + * Color is used in the buddylist to indicate status, and the conversation + window to indicate various message attributes. Look at the sample gntrc + file in the man-page for details. + * The default keybinding for dump-screen is now M-D and uses a file + request dialog. M-d will properly delete-forward-word, and M-f has been + fixed to imitate readline's behavior. version 2.3.0 (11/24/2007): http://developer.pidgin.im/query?status=closed&milestone=2.3.0
--- a/ChangeLog.API Mon Dec 03 14:46:54 2007 +0000 +++ b/ChangeLog.API Mon Dec 03 16:20:59 2007 +0000 @@ -1,6 +1,6 @@ Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul -version 2.3.1 (??/??/????): +version 2.3.2 (??/??/????): Finch: libgnt: * Added gnt_tree_set_row_color to set the color for a row in a tree. @@ -8,6 +8,8 @@ * Added gnt_color_add_pair to define a new color. * Added gnt_colors_get_color to get an ncurses color value from a string. + * Added gnt_style_get_color to get a color pair from an entry in + ~/.gntrc version 2.3.0 (11/24/2007): libpurple:
--- a/doc/finch.1.in Mon Dec 03 14:46:54 2007 +0000 +++ b/doc/finch.1.in Mon Dec 03 16:20:59 2007 +0000 @@ -145,8 +145,19 @@ .br color-offline = red; black .br +color-message-sent = cyan; default +.br +color-message-received = red; default +.br +color-message-highlight = black; green +.br +color-message-action = yellow; default +.br +color-timestamp = blue; default +.br #See below for details on color .br + [general] .br shadow = 0
--- a/finch/gntblist.c Mon Dec 03 14:46:54 2007 +0000 +++ b/finch/gntblist.c Mon Dec 03 16:20:59 2007 +0000 @@ -1768,37 +1768,18 @@ draw_tooltip(ggblist); } -static int -get_color(char *key) -{ -#if GLIB_CHECK_VERSION(2,6,0) - int fg = 0, bg = 0; - gsize n; - char **vals; - vals = gnt_style_get_string_list(NULL, key, &n); - if (vals && n == 2) { - fg = gnt_colors_get_color(vals[0]); - bg = gnt_colors_get_color(vals[1]); - return gnt_color_add_pair(fg, bg); - } - return 0; -#else - return 0; -#endif -} - void finch_blist_init() { - color_available = get_color("color-available"); + color_available = gnt_style_get_color(NULL, "color-available"); if (!color_available) color_available = gnt_color_add_pair(COLOR_GREEN, -1); - color_away = get_color("color-away"); + color_away = gnt_style_get_color(NULL, "color-away"); if (!color_away) color_away = gnt_color_add_pair(COLOR_BLUE, -1); - color_idle = get_color("color-idle"); + color_idle = gnt_style_get_color(NULL, "color-idle"); if (!color_idle) color_idle = gnt_color_add_pair(COLOR_CYAN, -1); - color_offline = get_color("color-offline"); + color_offline = gnt_style_get_color(NULL, "color-offline"); if (!color_offline) color_offline = gnt_color_add_pair(COLOR_RED, -1);
--- a/finch/gntconv.c Mon Dec 03 14:46:54 2007 +0000 +++ b/finch/gntconv.c Mon Dec 03 16:20:59 2007 +0000 @@ -49,6 +49,7 @@ #include "gntmenu.h" #include "gntmenuitem.h" #include "gntmenuitemcheck.h" +#include "gntstyle.h" #include "gnttextview.h" #include "gnttree.h" #include "gntutils.h" @@ -64,6 +65,12 @@ const char *message, PurpleMessageFlags flags, time_t mtime); static void generate_send_to_menu(FinchConv *ggc); +static int color_message_receive; +static int color_message_send; +static int color_message_highlight; +static int color_message_action; +static int color_timestamp; + static PurpleBlistNode * get_conversation_blist_node(PurpleConversation *conv) { @@ -753,7 +760,9 @@ /* Unnecessary to print the timestamp for delayed message */ if (purple_prefs_get_bool("/finch/conversations/timestamps")) gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(ggconv->tv), - purple_utf8_strftime("(%H:%M:%S) ", localtime(&mtime)), GNT_TEXT_FLAG_DIM); + purple_utf8_strftime("(%H:%M:%S)", localtime(&mtime)), gnt_color_pair(color_timestamp)); + + gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(ggconv->tv), " ", GNT_TEXT_FLAG_NORMAL); if (flags & PURPLE_MESSAGE_AUTO_RESP) gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(ggconv->tv), @@ -764,22 +773,31 @@ { char * name = NULL; - if (purple_message_meify((char*)message, -1)) - name = g_strdup_printf("*** %s ", who); - else - name = g_strdup_printf("%s: ", who); - - gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(ggconv->tv), - name, GNT_TEXT_FLAG_BOLD); + if (purple_message_meify((char*)message, -1)) { + name = g_strdup_printf("*** %s", who); + gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(ggconv->tv), + name, gnt_color_pair(color_message_action)); + } else { + name = g_strdup_printf("%s", who); + if (flags & PURPLE_MESSAGE_SEND) + gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(ggconv->tv), + name, gnt_color_pair(color_message_send)); + else + if (flags & PURPLE_MESSAGE_NICK) { + gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(ggconv->tv), + name, gnt_color_pair(color_message_highlight)); + } else { + gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(ggconv->tv), + name, gnt_color_pair(color_message_receive)); + } + } + gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(ggconv->tv), ": ", GNT_TEXT_FLAG_NORMAL); g_free(name); - } - else + } else fl = GNT_TEXT_FLAG_DIM; if (flags & PURPLE_MESSAGE_ERROR) fl |= GNT_TEXT_FLAG_BOLD; - if (flags & PURPLE_MESSAGE_NICK) - fl |= GNT_TEXT_FLAG_UNDERLINE; /* XXX: Remove this workaround when textview can parse messages. */ newline = purple_strdup_withhtml(message); @@ -1126,6 +1144,21 @@ void finch_conversation_init() { + color_message_send = gnt_style_get_color(NULL, "color-message-sent"); + if (!color_message_send) + color_message_send = gnt_color_add_pair(COLOR_CYAN, -1); + color_message_receive = gnt_style_get_color(NULL, "color-message-received"); + if (!color_message_receive) + color_message_receive = gnt_color_add_pair(COLOR_RED, -1); + color_message_highlight = gnt_style_get_color(NULL, "color-message-highlight"); + if (!color_message_highlight) + color_message_highlight = gnt_color_add_pair(COLOR_GREEN, -1); + color_timestamp = gnt_style_get_color(NULL, "color-timestamp"); + if (!color_timestamp) + color_timestamp = gnt_color_add_pair(COLOR_BLUE, -1); + color_message_action = gnt_style_get_color(NULL, "color-message-action"); + if (!color_message_action) + color_message_action = gnt_color_add_pair(COLOR_YELLOW, -1); purple_prefs_add_none(PREF_ROOT); purple_prefs_add_none(PREF_ROOT "/size"); purple_prefs_add_int(PREF_ROOT "/size/width", 70);
--- a/finch/libgnt/gntmain.c Mon Dec 03 14:46:54 2007 +0000 +++ b/finch/libgnt/gntmain.c Mon Dec 03 16:20:59 2007 +0000 @@ -679,8 +679,9 @@ g_free(cp); clean_pid(); wm->mode = GNT_KP_MODE_NORMAL; - clear(); + endwin(); setup_io(); + refresh(); refresh_screen(); } #endif
--- a/finch/libgnt/gntstyle.c Mon Dec 03 14:46:54 2007 +0000 +++ b/finch/libgnt/gntstyle.c Mon Dec 03 16:20:59 2007 +0000 @@ -59,6 +59,25 @@ #endif } +int +gnt_style_get_color(char *group, char *key) +{ +#if GLIB_CHECK_VERSION(2,6,0) + int fg = 0, bg = 0; + gsize n; + char **vals; + vals = gnt_style_get_string_list(group, key, &n); + if (vals && n == 2) { + fg = gnt_colors_get_color(vals[0]); + bg = gnt_colors_get_color(vals[1]); + return gnt_color_add_pair(fg, bg); + } + return 0; +#else + return 0; +#endif +} + char **gnt_style_get_string_list(const char *group, const char *key, gsize *length) { #if GLIB_CHECK_VERSION(2,6,0)
--- a/finch/libgnt/gntstyle.h Mon Dec 03 14:46:54 2007 +0000 +++ b/finch/libgnt/gntstyle.h Mon Dec 03 16:20:59 2007 +0000 @@ -74,11 +74,24 @@ * * @return NULL terminated string array. The array should be freed with g_strfreev(). * - * @since 2.3.1 (gnt), 2.3.1 (pidgin) + * @since 2.3.2 */ char **gnt_style_get_string_list(const char *group, const char *key, gsize *length); /** + * Get the value of a color pair in ~/.gntrc. + * + * @param group The name of the group in the keyfile. If @c NULL, the prgname + * will be used first, if available. Otherwise, "general" will be used. + * @param key The key + * + * @return The value of the color as an int, or 0 on error. + * + * @since 2.3.2 + */ +int gnt_style_get_color(char *group, char *key); + +/** * Parse a boolean preference. For example, if 'value' is "false" (ignoring case) * or "0", the return value will be @c FALSE, otherwise @c TRUE. *
--- a/finch/libgnt/gntwm.c Mon Dec 03 14:46:54 2007 +0000 +++ b/finch/libgnt/gntwm.c Mon Dec 03 16:20:59 2007 +0000 @@ -692,6 +692,7 @@ {'\0', NULL} }; + gnt_widget_destroy(GNT_WIDGET(fs)); if ((file = g_fopen(path, "w+")) == NULL) { return; @@ -803,7 +804,6 @@ } fprintf(file, "</pre>\n</body>"); fclose(file); - gnt_widget_destroy(GNT_WIDGET(fs)); } static void @@ -817,6 +817,11 @@ { GntWidget *window = gnt_file_sel_new(); GntFileSel *sel = GNT_FILE_SEL(window); + + g_object_set(G_OBJECT(window), "vertical", TRUE, NULL); + gnt_box_add_widget(GNT_BOX(window), gnt_label_new("Please enter the filename to save the screenshot.")); + gnt_box_set_title(GNT_BOX(window), "Save Screenshot..."); + gnt_file_sel_set_suggested_filename(sel, "dump.html"); g_signal_connect(G_OBJECT(sel), "file_selected", G_CALLBACK(dump_file_save), NULL); g_signal_connect(G_OBJECT(sel->cancel), "activate", G_CALLBACK(dump_file_cancel), sel);
--- a/finch/libgnt/test/tv.c Mon Dec 03 14:46:54 2007 +0000 +++ b/finch/libgnt/test/tv.c Mon Dec 03 16:20:59 2007 +0000 @@ -112,8 +112,8 @@ gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(view), "plugins: ", GNT_TEXT_FLAG_BOLD); gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(view), "this is the 2nd line\n", GNT_TEXT_FLAG_NORMAL); - gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(view), "plugins: ", GNT_TEXT_FLAG_BOLD); - gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(view), "this is the 3rd line\n", GNT_TEXT_FLAG_NORMAL); + gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(view), "plugins: ", GNT_TEXT_FLAG_BOLD | gnt_color_pair(GNT_COLOR_HIGHLIGHT)); + gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(view), "this is the 3rd line\n", GNT_TEXT_FLAG_NORMAL | gnt_color_pair(GNT_COLOR_HIGHLIGHT)); gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(view), "plugins: ", GNT_TEXT_FLAG_BOLD); gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(view), "this is the 4th line\n", GNT_TEXT_FLAG_NORMAL);
--- a/libpurple/protocols/bonjour/jabber.c Mon Dec 03 14:46:54 2007 +0000 +++ b/libpurple/protocols/bonjour/jabber.c Mon Dec 03 16:20:59 2007 +0000 @@ -62,6 +62,12 @@ #define DOCTYPE "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" \ "<stream:stream xmlns=\"jabber:client\" xmlns:stream=\"http://etherx.jabber.org/streams\" from=\"%s\" to=\"%s\">" +enum sent_stream_start_types { + NOT_SENT = 0, + PARTIALLY_SENT = 1, + FULLY_SENT = 2 +}; + static void xep_iq_parse(xmlnode *packet, PurpleConnection *connection, PurpleBuddy *pb); @@ -100,6 +106,8 @@ bconv->rx_handler = 0; bconv->pb = pb; + bonjour_parser_setup(bconv); + return bconv; } @@ -289,7 +297,7 @@ /* If we're not ready to actually send, append it to the buffer */ if (bconv->tx_handler != 0 || bconv->connect_data != NULL - || !bconv->sent_stream_start + || bconv->sent_stream_start != FULLY_SENT || !bconv->recv_stream_start || purple_circ_buffer_get_max_read(bconv->tx_buf) > 0) { ret = -1; @@ -319,6 +327,7 @@ } if (ret < len) { + /* Don't interfere with the stream starting */ if (bconv->tx_handler == 0) bconv->tx_handler = purple_input_add(bconv->socket, PURPLE_INPUT_WRITE, _send_data_write_cb, pb); @@ -409,20 +418,6 @@ } } -void bonjour_jabber_stream_started(PurpleBuddy *pb) { - BonjourBuddy *bb = pb->proto_data; - BonjourJabberConversation *bconv = bb->conversation; - - /* If the stream has been completely started, we can start doing stuff */ - if (bconv->sent_stream_start && bconv->recv_stream_start && purple_circ_buffer_get_max_read(bconv->tx_buf) > 0) { - /* Watch for when we can write the buffered messages */ - bconv->tx_handler = purple_input_add(bconv->socket, PURPLE_INPUT_WRITE, - _send_data_write_cb, pb); - /* We can probably write the data right now. */ - _send_data_write_cb(pb, bconv->socket, PURPLE_INPUT_WRITE); - } - -} struct _stream_start_data { char *msg; @@ -478,14 +473,13 @@ /* Stream started; process the send buffer if there is one */ purple_input_remove(bconv->tx_handler); - bconv->tx_handler= 0; - bconv->sent_stream_start = TRUE; + bconv->tx_handler = 0; + bconv->sent_stream_start = FULLY_SENT; bonjour_jabber_stream_started(pb); - } -static gboolean bonjour_jabber_stream_init(PurpleBuddy *pb, int client_socket) +static gboolean bonjour_jabber_send_stream_init(PurpleBuddy *pb, int client_socket) { int ret, len; char *stream_start; @@ -495,6 +489,8 @@ purple_buddy_get_name(pb)); len = strlen(stream_start); + bb->conversation->sent_stream_start = PARTIALLY_SENT; + /* Start the stream */ ret = send(client_socket, stream_start, len, 0); @@ -521,18 +517,55 @@ bb->conversation->tx_handler = purple_input_add(client_socket, PURPLE_INPUT_WRITE, _start_stream, pb); } else - bb->conversation->sent_stream_start = TRUE; + bb->conversation->sent_stream_start = FULLY_SENT; g_free(stream_start); - /* setup the parser fresh for each stream */ - bonjour_parser_setup(bb->conversation); + return TRUE; +} + +static gboolean +_async_bonjour_jabber_close_conversation(gpointer data) { + BonjourJabberConversation *bconv = data; + bonjour_jabber_close_conversation(bconv); + return FALSE; +} + +void bonjour_jabber_stream_started(PurpleBuddy *pb) { + BonjourBuddy *bb = pb->proto_data; + BonjourJabberConversation *bconv = bb->conversation; + + if (bconv->sent_stream_start == NOT_SENT && !bonjour_jabber_send_stream_init(pb, bconv->socket)) { + const char *err = g_strerror(errno); + PurpleConversation *conv; + + purple_debug_error("bonjour", "Error starting stream with buddy %s at %s:%d error: %s\n", + purple_buddy_get_name(pb), bb->ip ? bb->ip : "(null)", bb->port_p2pj, err ? err : "(null)"); - bb->conversation->socket = client_socket; - bb->conversation->rx_handler = purple_input_add(client_socket, - PURPLE_INPUT_READ, _client_socket_handler, pb); + conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, bb->name, pb->account); + if (conv != NULL) + purple_conversation_write(conv, NULL, + _("Unable to send the message, the conversation couldn't be started."), + PURPLE_MESSAGE_SYSTEM, time(NULL)); - return TRUE; + close(bconv->socket); + /* This must be asynchronous because it destroys the parser and we + * may be in the middle of parsing. + */ + purple_timeout_add(0, _async_bonjour_jabber_close_conversation, bb->conversation); + bb->conversation = NULL; + return; + } + + /* If the stream has been completely started, we can start doing stuff */ + if (bconv->sent_stream_start == FULLY_SENT && bconv->recv_stream_start && purple_circ_buffer_get_max_read(bconv->tx_buf) > 0) { + /* Watch for when we can write the buffered messages */ + bconv->tx_handler = purple_input_add(bconv->socket, PURPLE_INPUT_WRITE, + _send_data_write_cb, pb); + /* We can probably write the data right now. */ + _send_data_write_cb(pb, bconv->socket, PURPLE_INPUT_WRITE); + } + } static void @@ -576,14 +609,15 @@ bb = pb->proto_data; /* Check if the conversation has been previously started */ + /* This really shouldn't ever happen unless something weird is going on */ if (bb->conversation == NULL) { bb->conversation = bonjour_jabber_conv_new(pb); - if (!bonjour_jabber_stream_init(pb, client_socket)) { - close(client_socket); - return; - } + /* We wait for the stream start before doing anything else */ + bb->conversation->socket = client_socket; + bb->conversation->rx_handler = purple_input_add(client_socket, + PURPLE_INPUT_READ, _client_socket_handler, pb); } else { purple_debug_warning("bonjour", "Ignoring incoming connection because an existing connection exists.\n"); @@ -696,7 +730,7 @@ return; } - if (!bonjour_jabber_stream_init(pb, source)) { + if (!bonjour_jabber_send_stream_init(pb, source)) { const char *err = g_strerror(errno); PurpleConversation *conv; @@ -714,6 +748,11 @@ bb->conversation = NULL; return; } + + /* Start listening for the stream acknowledgement */ + bb->conversation->socket = source; + bb->conversation->rx_handler = purple_input_add(source, + PURPLE_INPUT_READ, _client_socket_handler, pb); } static PurpleBuddy * @@ -843,7 +882,7 @@ /* Close the socket and remove the watcher */ if (bconv->socket >= 0) { /* Send the end of the stream to the other end of the conversation */ - if (bconv->sent_stream_start) + if (bconv->sent_stream_start == FULLY_SENT) send(bconv->socket, STREAM_END, strlen(STREAM_END), 0); /* TODO: We're really supposed to wait for "</stream:stream>" before closing the socket */ close(bconv->socket);
--- a/libpurple/protocols/bonjour/jabber.h Mon Dec 03 14:46:54 2007 +0000 +++ b/libpurple/protocols/bonjour/jabber.h Mon Dec 03 16:20:59 2007 +0000 @@ -47,7 +47,7 @@ guint rx_handler; guint tx_handler; PurpleCircBuffer *tx_buf; - gboolean sent_stream_start; + int sent_stream_start; /* 0 = Unsent, 1 = Partial, 2 = Complete */ gboolean recv_stream_start; PurpleProxyConnectData *connect_data; gpointer stream_data;
--- a/libpurple/protocols/msnp9/directconn.c Mon Dec 03 14:46:54 2007 +0000 +++ b/libpurple/protocols/msnp9/directconn.c Mon Dec 03 16:20:59 2007 +0000 @@ -81,6 +81,7 @@ create_listener(int port) { int fd; + int flags; const int on = 1; #if 0 @@ -156,7 +157,8 @@ return -1; } - fcntl(fd, F_SETFL, O_NONBLOCK); + flags = fcntl(fd, F_GETFL); + fcntl(fd, F_SETFL, flags | O_NONBLOCK); return fd; } @@ -353,7 +355,7 @@ } static void -connect_cb(gpointer data, gint source, const gchar *error_message) +connect_cb(gpointer data, gint source, PurpleInputCondition cond) { MsnDirectConn* directconn; int fd; @@ -405,6 +407,15 @@ } } +static void +directconn_connect_cb(gpointer data, gint source, const gchar *error_message) +{ + if (error_message) + purple_debug_error("msn", "Error making direct connection: %s\n", error_message); + + connect_cb(data, source, PURPLE_INPUT_READ); +} + gboolean msn_directconn_connect(MsnDirectConn *directconn, const char *host, int port) { @@ -424,14 +435,9 @@ #endif directconn->connect_data = purple_proxy_connect(NULL, session->account, - host, port, connect_cb, directconn); + host, port, directconn_connect_cb, directconn); - if (directconn->connect_data != NULL) - { - return TRUE; - } - else - return FALSE; + return (directconn->connect_data != NULL); } #if 0
--- a/libpurple/protocols/msnp9/servconn.c Mon Dec 03 14:46:54 2007 +0000 +++ b/libpurple/protocols/msnp9/servconn.c Mon Dec 03 16:20:59 2007 +0000 @@ -468,6 +468,7 @@ create_listener(int port) { int fd; + int flags; const int on = 1; #if 0 @@ -543,7 +544,8 @@ return -1; } - fcntl(fd, F_SETFL, O_NONBLOCK); + flags = fcntl(fd, F_GETFL); + fcntl(fd, F_SETFL, flags | O_NONBLOCK); return fd; }
--- a/libpurple/protocols/oscar/family_chatnav.c Mon Dec 03 14:46:54 2007 +0000 +++ b/libpurple/protocols/oscar/family_chatnav.c Mon Dec 03 16:20:59 2007 +0000 @@ -29,6 +29,49 @@ #include "oscar.h" +static int +error(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs) +{ + int ret = 0; + aim_snac_t *snac2; + guint16 error, chatnav_error; + GSList *tlvlist; + + if (!(snac2 = aim_remsnac(od, snac->id))) { + purple_debug_warning("oscar", "chatnav error: received response to unknown request (%08lx)\n", snac->id); + return 0; + } + + if (snac2->family != 0x000d) { + purple_debug_warning("oscar", "chatnav error: received response that maps to corrupt request (fam=%04x)\n", snac2->family); + return 0; + } + + /* + * We now know what the original SNAC subtype was. + */ + if (snac2->type == 0x0008) /* create room */ + { + error = byte_stream_get16(bs); + tlvlist = aim_tlvlist_read(bs); + chatnav_error = aim_tlv_get16(tlvlist, 0x0008, 1); + + purple_debug_warning("oscar", + "Could not join room, error=0x%04hx, chatnav_error=0x%04hx\n", + error, chatnav_error); + purple_notify_error(od->gc, NULL, _("Could not join chat room"), + chatnav_error == 0x0033 ? _("Invalid chat room name") : _("Unknown error")); + + ret = 1; + } + + if (snac2) + g_free(snac2->data); + g_free(snac2); + + return ret; +} + /* * Subtype 0x0002 * @@ -451,7 +494,9 @@ static int snachandler(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs) { - if (snac->subtype == 0x0009) + if (snac->subtype == 0x0001) + return error(od, conn, mod, frame, snac, bs); + else if (snac->subtype == 0x0009) return parseinfo(od, conn, mod, frame, snac, bs); return 0;
--- a/libpurple/protocols/oscar/family_feedbag.c Mon Dec 03 14:46:54 2007 +0000 +++ b/libpurple/protocols/oscar/family_feedbag.c Mon Dec 03 16:20:59 2007 +0000 @@ -115,14 +115,10 @@ gboolean exists; struct aim_ssi_item *cur, *new; - new = (struct aim_ssi_item *)g_malloc(sizeof(struct aim_ssi_item)); + new = g_new(struct aim_ssi_item, 1); /* Set the name */ - if (name) { - new->name = (char *)g_malloc((strlen(name)+1)*sizeof(char)); - strcpy(new->name, name); - } else - new->name = NULL; + new->name = g_strdup(name); /* Set the group ID# and buddy ID# */ new->gid = gid; @@ -510,7 +506,7 @@ for (cur1=od->ssi.official; cur1 && (n < 15); cur1=cur1->next) { if (!aim_ssi_itemlist_find(od->ssi.local, cur1->gid, cur1->bid)) { n++; - new = (struct aim_ssi_tmp *)g_malloc(sizeof(struct aim_ssi_tmp)); + new = g_new(struct aim_ssi_tmp, 1); new->action = SNAC_SUBTYPE_FEEDBAG_DEL; new->ack = 0xffff; new->name = NULL; @@ -530,7 +526,7 @@ for (cur1=od->ssi.local; cur1 && (n < 15); cur1=cur1->next) { if (!aim_ssi_itemlist_find(od->ssi.official, cur1->gid, cur1->bid)) { n++; - new = (struct aim_ssi_tmp *)g_malloc(sizeof(struct aim_ssi_tmp)); + new = g_new(struct aim_ssi_tmp, 1); new->action = SNAC_SUBTYPE_FEEDBAG_ADD; new->ack = 0xffff; new->name = NULL; @@ -551,7 +547,7 @@ cur2 = aim_ssi_itemlist_find(od->ssi.official, cur1->gid, cur1->bid); if (cur2 && (aim_ssi_itemlist_cmp(cur1, cur2))) { n++; - new = (struct aim_ssi_tmp *)g_malloc(sizeof(struct aim_ssi_tmp)); + new = g_new(struct aim_ssi_tmp, 1); new->action = SNAC_SUBTYPE_FEEDBAG_MOD; new->ack = 0xffff; new->name = NULL; @@ -1028,8 +1024,7 @@ return -EINVAL; g_free(group->name); - group->name = (char *)g_malloc((strlen(newgn)+1)*sizeof(char)); - strcpy(group->name, newgn); + group->name = g_strdup(newgn); /* Sync our local list with the server list */ return aim_ssi_sync(od); @@ -1461,11 +1456,7 @@ if ((item = aim_ssi_itemlist_find(od->ssi.local, gid, bid))) { item->type = type; g_free(item->name); - if (name) { - item->name = (char *)g_malloc((strlen(name)+1)*sizeof(char)); - strcpy(item->name, name); - } else - item->name = NULL; + item->name = g_strdup(name); aim_tlvlist_free(item->data); item->data = aim_tlvlist_copy(data); } @@ -1473,11 +1464,7 @@ if ((item = aim_ssi_itemlist_find(od->ssi.official, gid, bid))) { item->type = type; g_free(item->name); - if (name) { - item->name = (char *)g_malloc((strlen(name)+1)*sizeof(char)); - strcpy(item->name, name); - } else - item->name = NULL; + item->name = g_strdup(name); aim_tlvlist_free(item->data); item->data = aim_tlvlist_copy(data); } @@ -1555,10 +1542,7 @@ /* Remove the item from the local list */ /* Make sure cur->item is still valid memory */ if (aim_ssi_itemlist_valid(od->ssi.local, cur->item)) { - if (cur->item->name) { - cur->name = (char *)g_malloc((strlen(cur->item->name)+1)*sizeof(char)); - strcpy(cur->name, cur->item->name); - } + cur->name = g_strdup(cur->item->name); aim_ssi_itemlist_del(&od->ssi.local, cur->item); } cur->item = NULL; @@ -1569,11 +1553,7 @@ struct aim_ssi_item *cur1; if ((cur1 = aim_ssi_itemlist_find(od->ssi.official, cur->item->gid, cur->item->bid))) { g_free(cur->item->name); - if (cur1->name) { - cur->item->name = (char *)g_malloc((strlen(cur1->name)+1)*sizeof(char)); - strcpy(cur->item->name, cur1->name); - } else - cur->item->name = NULL; + cur->item->name = g_strdup(cur1->name); aim_tlvlist_free(cur->item->data); cur->item->data = aim_tlvlist_copy(cur1->data); } @@ -1603,11 +1583,7 @@ struct aim_ssi_item *cur1; if ((cur1 = aim_ssi_itemlist_find(od->ssi.official, cur->item->gid, cur->item->bid))) { g_free(cur1->name); - if (cur->item->name) { - cur1->name = (char *)g_malloc((strlen(cur->item->name)+1)*sizeof(char)); - strcpy(cur1->name, cur->item->name); - } else - cur1->name = NULL; + cur1->name = g_strdup(cur->item->name); aim_tlvlist_free(cur1->data); cur1->data = aim_tlvlist_copy(cur->item->data); }
--- a/libpurple/protocols/oscar/family_icbm.c Mon Dec 03 14:46:54 2007 +0000 +++ b/libpurple/protocols/oscar/family_icbm.c Mon Dec 03 16:20:59 2007 +0000 @@ -209,7 +209,6 @@ */ static int aim_im_paraminfo(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs) { - aim_rxcallback_t userfunc; struct aim_icbmparameters params; params.maxchan = byte_stream_get16(bs); @@ -219,8 +218,11 @@ params.maxrecverwarn = byte_stream_get16(bs); params.minmsginterval = byte_stream_get32(bs); - if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) - return userfunc(od, conn, frame, ¶ms); + params.flags = 0x0000000b; + params.maxmsglen = 8000; + params.minmsginterval = 0; + + aim_im_setparams(od, ¶ms); return 0; } @@ -288,7 +290,7 @@ if (!args->msg || (args->msglen <= 0)) return -EINVAL; - if (args->msglen >= MAXMSGLEN) + if (args->msglen > MAXMSGLEN) return -E2BIG; }
--- a/libpurple/protocols/oscar/oscar.c Mon Dec 03 14:46:54 2007 +0000 +++ b/libpurple/protocols/oscar/oscar.c Mon Dec 03 16:20:59 2007 +0000 @@ -176,7 +176,6 @@ static int purple_parse_locaterights(OscarData *, FlapConnection *, FlapFrame *, ...); static int purple_parse_buddyrights(OscarData *, FlapConnection *, FlapFrame *, ...); static int purple_parse_locerr (OscarData *, FlapConnection *, FlapFrame *, ...); -static int purple_icbm_param_info (OscarData *, FlapConnection *, FlapFrame *, ...); static int purple_parse_genericerr (OscarData *, FlapConnection *, FlapFrame *, ...); static int purple_memrequest (OscarData *, FlapConnection *, FlapFrame *, ...); static int purple_selfinfo (OscarData *, FlapConnection *, FlapFrame *, ...); @@ -1228,7 +1227,6 @@ oscar_data_addhandler(od, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_RECVAUTHREQ, purple_ssi_authrequest, 0); oscar_data_addhandler(od, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_RECVAUTHREP, purple_ssi_authreply, 0); oscar_data_addhandler(od, SNAC_FAMILY_FEEDBAG, SNAC_SUBTYPE_FEEDBAG_ADDED, purple_ssi_gotadded, 0); - oscar_data_addhandler(od, SNAC_FAMILY_ICBM, 0x0005, purple_icbm_param_info, 0); oscar_data_addhandler(od, SNAC_FAMILY_ICBM, SNAC_SUBTYPE_ICBM_INCOMING, purple_parse_incoming_im, 0); oscar_data_addhandler(od, SNAC_FAMILY_ICBM, SNAC_SUBTYPE_ICBM_MISSEDCALL, purple_parse_misses, 0); oscar_data_addhandler(od, SNAC_FAMILY_ICBM, SNAC_SUBTYPE_ICBM_CLIENTAUTORESP, purple_parse_clientauto, 0); @@ -1833,9 +1831,6 @@ signon = info->onlinesince; else if (info->present & AIM_USERINFO_PRESENT_SESSIONLEN) signon = time(NULL) - info->sessionlen; - if (!aim_sncmp(purple_account_get_username(account), info->sn)) { - purple_connection_set_display_name(gc, info->sn); - } purple_prpl_got_user_login_time(account, info->sn, signon); /* Idle time stuff */ @@ -3437,6 +3432,8 @@ info = va_arg(ap, aim_userinfo_t *); va_end(ap); + purple_connection_set_display_name(od->gc, info->sn); + /* * What's with the + 0.5? * The 0.5 is basically poor-man's rounding. Normally @@ -3498,32 +3495,6 @@ return 1; } -static int purple_icbm_param_info(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) { - struct aim_icbmparameters *params; - va_list ap; - - va_start(ap, fr); - params = va_arg(ap, struct aim_icbmparameters *); - va_end(ap); - - /* XXX - evidently this crashes on solaris. i have no clue why - purple_debug_misc("oscar", "ICBM Parameters: maxchannel = %hu, default flags = 0x%08lx, max msg len = %hu, " - "max sender evil = %f, max receiver evil = %f, min msg interval = %u\n", - params->maxchan, params->flags, params->maxmsglen, - ((float)params->maxsenderwarn)/10.0, ((float)params->maxrecverwarn)/10.0, - params->minmsginterval); - */ - - /* Maybe senderwarn and recverwarn should be user preferences... */ - params->flags = 0x0000000b; - params->maxmsglen = 8000; - params->minmsginterval = 0; - - aim_im_setparams(od, params); - - return 1; -} - static int purple_parse_locaterights(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) { PurpleConnection *gc = od->gc; @@ -5364,6 +5335,7 @@ if (chat_name != NULL) g_hash_table_insert(defaults, "room", g_strdup(chat_name)); + g_hash_table_insert(defaults, "exchange", g_strdup("4")); return defaults; } @@ -5380,26 +5352,29 @@ OscarData *od = (OscarData *)gc->proto_data; FlapConnection *conn; char *name, *exchange; + int exchange_int; name = g_hash_table_lookup(data, "room"); exchange = g_hash_table_lookup(data, "exchange"); - if ((name == NULL) || (*name == '\0')) { - purple_notify_error(gc, NULL, _("Invalid chat name specified."), NULL); - return; - } + g_return_if_fail(name != NULL && *name != '\0'); + g_return_if_fail(exchange != NULL); + + errno = 0; + exchange_int = strtol(exchange, NULL, 10); + g_return_if_fail(errno == 0); purple_debug_info("oscar", "Attempting to join chat room %s.\n", name); if ((conn = flap_connection_getbytype(od, SNAC_FAMILY_CHATNAV))) { purple_debug_info("oscar", "chatnav exists, creating room\n"); - aim_chatnav_createroom(od, conn, name, atoi(exchange)); + aim_chatnav_createroom(od, conn, name, exchange_int); } else { /* this gets tricky */ struct create_room *cr = g_new0(struct create_room, 1); purple_debug_info("oscar", "chatnav does not exist, opening chatnav\n"); - cr->exchange = atoi(exchange); + cr->exchange = exchange_int; cr->name = g_strdup(name); od->create_rooms = g_slist_prepend(od->create_rooms, cr); aim_srv_requestnew(od, SNAC_FAMILY_CHATNAV); @@ -6725,7 +6700,7 @@ prpl_info->protocol_options = g_list_append(prpl_info->protocol_options, option); option = purple_account_option_bool_new( - _("Always use ICQ proxy server for file transfers\n(slower, but does not reveal your IP address)"), "always_use_rv_proxy", + _("Always use AIM/ICQ proxy server for\nfile transfers and direct IM (slower,\nbut does not reveal your IP address)"), "always_use_rv_proxy", OSCAR_DEFAULT_ALWAYS_USE_RV_PROXY); prpl_info->protocol_options = g_list_append(prpl_info->protocol_options, option);
--- a/libpurple/protocols/oscar/oscar.h Mon Dec 03 14:46:54 2007 +0000 +++ b/libpurple/protocols/oscar/oscar.h Mon Dec 03 16:20:59 2007 +0000 @@ -94,11 +94,8 @@ * for WinAIM clients (up through the latest (4.0.1957)) to * send any more than 1kb. Amaze all your windows friends * with utterly oversized instant messages! - * - * TODO: the real limit is the total SNAC size at 8192. Fix this. - * */ -#define MAXMSGLEN 7987 +#define MAXMSGLEN 2544 /* * Maximum size of a Buddy Icon.
--- a/libpurple/protocols/qq/header_info.h Mon Dec 03 14:46:54 2007 +0000 +++ b/libpurple/protocols/qq/header_info.h Mon Dec 03 16:20:59 2007 +0000 @@ -33,7 +33,7 @@ #define QQ_PACKET_TAG 0x02 /* all QQ text packets starts with it */ #define QQ_PACKET_TAIL 0x03 /* all QQ text packets end with it */ -#define QQ_CLIENT 0x0E1B +#define QQ_CLIENT 0x0d55 /* list of known QQ commands */ enum {
--- a/pidgin/gtkconv.c Mon Dec 03 14:46:54 2007 +0000 +++ b/pidgin/gtkconv.c Mon Dec 03 16:20:59 2007 +0000 @@ -6476,7 +6476,7 @@ markup = title; } } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { - const char *topic = gtk_entry_get_text(GTK_ENTRY(gtkconv->u.chat->topic_text)); + const char *topic = gtkconv->u.chat->topic_text ? gtk_entry_get_text(GTK_ENTRY(gtkconv->u.chat->topic_text)) : NULL; char *esc = NULL; #if GTK_CHECK_VERSION(2,6,0) esc = topic ? g_markup_escape_text(topic, -1) : NULL; @@ -8674,7 +8674,7 @@ gtk_entry_get_text(entry)); } serv_alias_buddy(buddy); - } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { + } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { gtk_entry_set_text(GTK_ENTRY(gtkconv->u.chat->topic_text), gtk_entry_get_text(entry)); topic_callback(NULL, gtkconv); } @@ -8685,7 +8685,7 @@ infopane_entry_activate(PidginConversation *gtkconv) { GtkWidget *entry = NULL; - PurpleConversation *conv = gtkconv->active_conv; + PurpleConversation *conv = gtkconv->active_conv; const char *text = NULL; if (!GTK_WIDGET_VISIBLE(gtkconv->tab_label)) { @@ -8701,9 +8701,21 @@ if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { PurpleBuddy *buddy = purple_find_buddy(gtkconv->active_conv->account, gtkconv->active_conv->name); if (!buddy) + /* This buddy isn't in your buddy list, so we can't alias him */ return FALSE; + text = purple_buddy_get_contact_alias(buddy); } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { + PurpleConnection *gc; + PurplePluginProtocolInfo *prpl_info = NULL; + + gc = purple_conversation_get_gc(conv); + if (gc != NULL) + prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); + if (prpl_info && prpl_info->set_chat_topic == NULL) + /* This protocol doesn't support setting the chat room topic */ + return FALSE; + text = purple_conv_chat_get_topic(PURPLE_CONV_CHAT(conv)); } @@ -8722,10 +8734,9 @@ g_signal_connect(G_OBJECT(entry), "activate", G_CALLBACK(alias_cb), gtkconv); g_signal_connect(G_OBJECT(entry), "focus-out-event", G_CALLBACK(alias_focus_cb), gtkconv); g_signal_connect(G_OBJECT(entry), "key-press-event", G_CALLBACK(alias_key_press_cb), gtkconv); - - - - gtk_entry_set_text(GTK_ENTRY(entry), text); + + if (text != NULL) + gtk_entry_set_text(GTK_ENTRY(entry), text); gtk_widget_show(entry); gtk_widget_hide(gtkconv->infopane); gtk_widget_grab_focus(entry);
--- a/pidgin/gtkmain.c Mon Dec 03 14:46:54 2007 +0000 +++ b/pidgin/gtkmain.c Mon Dec 03 16:20:59 2007 +0000 @@ -609,7 +609,7 @@ #ifndef _WIN32 "c:dhmnl::s:v", #else - "c:dhnl::v", + "c:dhmnl::v", #endif long_options, NULL)) != -1) { switch (opt) {
--- a/po/POTFILES.in Mon Dec 03 14:46:54 2007 +0000 +++ b/po/POTFILES.in Mon Dec 03 16:20:59 2007 +0000 @@ -118,6 +118,7 @@ libpurple/protocols/myspace/zap.c libpurple/protocols/novell/nmuser.c libpurple/protocols/novell/novell.c +libpurple/protocols/oscar/family_chatnav.c libpurple/protocols/oscar/flap_connection.c libpurple/protocols/oscar/libaim.c libpurple/protocols/oscar/libicq.c