# HG changeset patch # User Sean Egan # Date 1200602688 0 # Node ID 3c814c64a507d9cbecd064b112cec6ade15ca564 # Parent 2fb026d3f42b44f9073df8c31e2d73da05dc875d# Parent 6edcab92fb1dfd7fcd41802262d5e3456aefaa51 merge of '4b5e932e01a84088124dee9791809545cdc9240b' and 'e4081b0fea9b2e91db9a532aa729cfc1c078f287' diff -r 2fb026d3f42b -r 3c814c64a507 COPYRIGHT --- a/COPYRIGHT Thu Jan 17 20:37:22 2008 +0000 +++ b/COPYRIGHT Thu Jan 17 20:44:48 2008 +0000 @@ -270,6 +270,7 @@ Padraig O'Briain Christopher O'Brien (siege) Jon Oberheide +Yusuke Odate Ruediger Oertel Gudmundur Bjarni Olafsson Bartosz Oler @@ -371,6 +372,7 @@ Richard Stellingwerff Charlie Stockman David Stoddard +Andreas Stührk Oleg Sukhodolsky Sun Microsystems Mårten Svantesson (fursten) @@ -426,6 +428,7 @@ Andrew Whewell Simon Wilkinson Dan Willemsen +Justin Williams (Jaywalker) Jason Willis Matt Wilson Dan Winship diff -r 2fb026d3f42b -r 3c814c64a507 ChangeLog --- a/ChangeLog Thu Jan 17 20:37:22 2008 +0000 +++ b/ChangeLog Thu Jan 17 20:44:48 2008 +0000 @@ -9,7 +9,10 @@ now required to use Bonjour. * Partial support for viewing ICQ status notes (Collin from ComBOTS GmbH). + * Support for /notice on IRC. * Support for Yahoo Messenger 7.0+ file transfer method (Thanumalayan S.) + * Support for retrieving full names and addresses from the address book + on Yahoo! Japan (Yusuke Odate) Pidgin: * Added the ability to theme conversation name colors (red and blue) @@ -23,14 +26,14 @@ Finch: * 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. + 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. * New bindings alt+tab and alt+shift+tab to help navigating between the - higlighted windows (details on the man-page). + higlighted windows (details on the man page). * Recently signed on (or off) buddies blink in the buddy list. - * New action 'Room List' in the action-list can be used to get the list of + * New action 'Room List' in the action list can be used to get the list of available chat rooms for an online account. version 2.3.1 (12/7/2007): diff -r 2fb026d3f42b -r 3c814c64a507 ChangeLog.API --- a/ChangeLog.API Thu Jan 17 20:37:22 2008 +0000 +++ b/ChangeLog.API Thu Jan 17 20:44:48 2008 +0000 @@ -18,6 +18,18 @@ * purple_roomlist_field_get_type * purple_roomlist_field_get_label * purple_roomlist_field_get_hidden + * unlocalized_name field in PurpleAttentionType for UIs that need it. + * Some accessor and mutator functions for PurpleAttentionType: + * purple_attention_type_set_name + * purple_attention_type_set_incoming_desc + * purple_attention_type_set_outgoing_desc + * purple_attention_type_set_icon_name + * purple_attention_type_set_unlocalized_name + * purple_attention_type_get_name + * purple_attention_type_get_incoming_desc + * purple_attention_type_get_outgoing_desc + * purple_attention_type_get_icon_name + * purple_attention_type_get_unlocalized_name Pidgin: Added: diff -r 2fb026d3f42b -r 3c814c64a507 finch/gntcertmgr.c --- a/finch/gntcertmgr.c Thu Jan 17 20:37:22 2008 +0000 +++ b/finch/gntcertmgr.c Thu Jan 17 20:44:48 2008 +0000 @@ -235,7 +235,7 @@ purple_request_close_with_handle((void *)key); purple_request_yes_no((void *)key, _("Confirm certificate delete"), primary, NULL, - 2, + 1, NULL, NULL, NULL, g_strdup(key), tls_peers_mgmt_delete_confirm_cb, diff -r 2fb026d3f42b -r 3c814c64a507 finch/gntrequest.c --- a/finch/gntrequest.c Thu Jan 17 20:37:22 2008 +0000 +++ b/finch/gntrequest.c Thu Jan 17 20:44:48 2008 +0000 @@ -253,7 +253,7 @@ void *user_data, size_t actioncount, va_list actions) { - GntWidget *window, *box, *button; + GntWidget *window, *box, *button, *focus = NULL; int i; window = setup_request_window(title, primary, secondary, PURPLE_REQUEST_ACTION); @@ -272,9 +272,14 @@ g_object_set_data(G_OBJECT(button), "activate-userdata", user_data); g_object_set_data(G_OBJECT(button), "activate-id", GINT_TO_POINTER(i)); g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(request_action_cb), window); + + if (i == default_value) + focus = button; } gnt_widget_show(window); + if (focus) + gnt_box_give_focus_to_child(GNT_BOX(window), focus); return window; } diff -r 2fb026d3f42b -r 3c814c64a507 finch/gntroomlist.c --- a/finch/gntroomlist.c Thu Jan 17 20:37:22 2008 +0000 +++ b/finch/gntroomlist.c Thu Jan 17 20:44:48 2008 +0000 @@ -287,10 +287,10 @@ froomlist.accounts = accounts = gnt_combo_box_new(); reset_account_list(account); - gnt_box_add_widget(GNT_BOX(window), froomlist.accounts); - g_signal_connect(G_OBJECT(froomlist.accounts), "selection-changed", + gnt_box_add_widget(GNT_BOX(window), accounts); + g_signal_connect(G_OBJECT(accounts), "selection-changed", G_CALLBACK(roomlist_account_changed), NULL); - froomlist.account = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(froomlist.accounts)); + froomlist.account = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(accounts)); froomlist.tree = tree = gnt_tree_new_with_columns(2); gnt_tree_set_show_title(GNT_TREE(tree), TRUE); diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/account.c --- a/libpurple/account.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/account.c Thu Jan 17 20:44:48 2008 +0000 @@ -752,7 +752,7 @@ current_error = g_new0(PurpleConnectionErrorInfo, 1); current_error->type = type; - current_error->description = g_strdup(description); + current_error->description = description; set_current_error(account, current_error); } diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/account.h --- a/libpurple/account.h Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/account.h Thu Jan 17 20:44:48 2008 +0000 @@ -410,37 +410,34 @@ void purple_account_set_status_types(PurpleAccount *account, GList *status_types); /** - * Activates or deactivates a status. All changes to the statuses of - * an account go through this function or purple_account_set_status_list. - * - * Only independent statuses can be deactivated with this. To deactivate - * an exclusive status, activate a different (and exclusive?) status. + * Variadic version of purple_account_set_status_list(); the variadic list + * replaces @a attrs, and should be NULL-terminated. * - * @param account The account. - * @param status_id The ID of the status. - * @param active The active state. - * @param ... Pairs of attributes for the new status passed in - * as a NULL-terminated list of id/value pairs. + * @copydoc purple_account_set_status_list() */ void purple_account_set_status(PurpleAccount *account, const char *status_id, - gboolean active, ...) G_GNUC_NULL_TERMINATED; + gboolean active, ...) G_GNUC_NULL_TERMINATED; /** * Activates or deactivates a status. All changes to the statuses of - * an account go through this function or purple_account_set_status. + * an account go through this function or purple_account_set_status(). * - * Only independent statuses can be deactivated with this. To deactivate - * an exclusive status, activate a different (and exclusive?) status. + * You can only deactivate an exclusive status by activating another exclusive + * status. So, if @a status_id is an exclusive status and @a active is @c + * FALSE, this function does nothing. * * @param account The account. * @param status_id The ID of the status. - * @param active The active state. - * @param attrs A list of attributes in key/value pairs + * @param active Whether @a status_id is to be activated (TRUE) or + * deactivated (FALSE). + * @param attrs A list of const char * attribute names followed by + * const char * attribute values for the status. + * (For example, one pair might be "message" followed + * by "hello, talk to me!".) */ void purple_account_set_status_list(PurpleAccount *account, - const char *status_id, - gboolean active, GList *attrs); + const char *status_id, gboolean active, GList *attrs); /** * Clears all protocol-specific settings on an account. diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/certificate.c --- a/libpurple/certificate.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/certificate.c Thu Jan 17 20:44:48 2008 +0000 @@ -568,7 +568,7 @@ _("Single-use Certificate Verification"), primary, secondary, - 1, /* Accept by default */ + 0, /* Accept by default */ NULL, /* No account */ NULL, /* No other user */ NULL, /* No associated conversation */ @@ -1199,7 +1199,7 @@ _("SSL Certificate Verification"), primary, reason, - 2, /* Accept by default */ + 0, /* Accept by default */ NULL, /* No account */ NULL, /* No other user */ NULL, /* No associated conversation */ diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/dbus-analyze-functions.py --- a/libpurple/dbus-analyze-functions.py Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/dbus-analyze-functions.py Thu Jan 17 20:44:48 2008 +0000 @@ -525,9 +525,10 @@ try: self.processfunction(functiontext, paramtexts) except MyException: - sys.stderr.write(myline + "\n") +# sys.stderr.write(myline + "\n") + pass except: - sys.stderr.write(myline + "\n") +# sys.stderr.write(myline + "\n") raise self.flush() @@ -586,7 +587,7 @@ else: fprefix = "" -sys.stderr.write("%s: Functions not exported:\n" % sys.argv[0]) +#sys.stderr.write("%s: Functions not exported:\n" % sys.argv[0]) if "client" in options: bindings = ClientBindingSet(sys.stdin, fprefix, diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/dbus-server.c --- a/libpurple/dbus-server.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/dbus-server.c Thu Jan 17 20:44:48 2008 +0000 @@ -689,6 +689,7 @@ switch (purple_values[i]->type) { case PURPLE_TYPE_INT: + case PURPLE_TYPE_ENUM: xint = my_arg(gint); dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &xint); break; @@ -729,7 +730,7 @@ if (id == 0 && val != NULL) error = TRUE; /* Some error happened. */ dbus_message_iter_append_basic(iter, - (sizeof(void *) == 4) ? DBUS_TYPE_UINT32 : DBUS_TYPE_UINT64, &id); + (sizeof(id) == sizeof(dbus_int32_t)) ? DBUS_TYPE_INT32 : DBUS_TYPE_INT64, &id); break; default: /* no conversion implemented */ g_return_val_if_reached(TRUE); diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/dnsquery.c --- a/libpurple/dnsquery.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/dnsquery.c Thu Jan 17 20:44:48 2008 +0000 @@ -159,6 +159,24 @@ } #endif +static void +write_to_parent(int fd, const void *buf, size_t count) +{ + ssize_t written; + + written = write(fd, buf, count); + if (written != count) { + if (written < 0) + fprintf(stderr, "dns[%d]: Error writing data to " + "parent: %s\n", getpid(), strerror(errno)); + else + fprintf(stderr, "dns[%d]: Error: Tried to write %" + G_GSIZE_FORMAT " bytes to parent but instead " + "wrote %" G_GSIZE_FORMAT " bytes\n", + getpid(), count, written); + } +} + G_GNUC_NORETURN static void purple_dnsquery_resolver_run(int child_out, int child_in, gboolean show_debug) { @@ -201,7 +219,8 @@ } rc = read(child_in, &dns_params, sizeof(dns_params_t)); if (rc < 0) { - perror("read()"); + fprintf(stderr, "dns[%d]: Error: Could not read dns_params: " + "%s\n", getpid(), strerror(errno)); break; } if (rc == 0) { @@ -210,11 +229,13 @@ _exit(0); } if (dns_params.hostname[0] == '\0') { - printf("dns[%d]: hostname = \"\" (port = %d)!!!\n", getpid(), dns_params.port); + fprintf(stderr, "dns[%d]: Error: Parent requested resolution " + "of an empty hostname (port = %d)!!!\n", getpid(), + dns_params.port); _exit(1); } /* Tell our parent that we read the data successfully */ - write(child_out, &ch, sizeof(ch)); + write_to_parent(child_out, &ch, sizeof(ch)); /* We have the hostname and port, now resolve the IP */ @@ -230,7 +251,7 @@ */ hints.ai_socktype = SOCK_STREAM; rc = getaddrinfo(dns_params.hostname, servname, &hints, &res); - write(child_out, &rc, sizeof(rc)); + write_to_parent(child_out, &rc, sizeof(rc)); if (rc != 0) { close(child_out); if (show_debug) @@ -242,17 +263,17 @@ tmp = res; while (res) { size_t ai_addrlen = res->ai_addrlen; - write(child_out, &ai_addrlen, sizeof(ai_addrlen)); - write(child_out, res->ai_addr, res->ai_addrlen); + write_to_parent(child_out, &ai_addrlen, sizeof(ai_addrlen)); + write_to_parent(child_out, res->ai_addr, res->ai_addrlen); res = res->ai_next; } freeaddrinfo(tmp); - write(child_out, &zero, sizeof(zero)); + write_to_parent(child_out, &zero, sizeof(zero)); #else if (!inet_aton(dns_params.hostname, &sin.sin_addr)) { struct hostent *hp; if (!(hp = gethostbyname(dns_params.hostname))) { - write(child_out, &h_errno, sizeof(int)); + write_to_parent(child_out, &h_errno, sizeof(int)); close(child_out); if (show_debug) printf("DNS Error: %d\n", h_errno); @@ -265,10 +286,10 @@ sin.sin_family = AF_INET; sin.sin_port = htons(dns_params.port); - write(child_out, &zero, sizeof(zero)); - write(child_out, &addrlen, sizeof(addrlen)); - write(child_out, &sin, addrlen); - write(child_out, &zero, sizeof(zero)); + write_to_parent(child_out, &zero, sizeof(zero)); + write_to_parent(child_out, &addrlen, sizeof(addrlen)); + write_to_parent(child_out, &sin, addrlen); + write_to_parent(child_out, &zero, sizeof(zero)); #endif dns_params.hostname[0] = '\0'; } diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/dnssrv.c --- a/libpurple/dnssrv.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/dnssrv.c Thu Jan 17 20:44:48 2008 +0000 @@ -200,12 +200,20 @@ PurpleSrvCallback cb = query_data->cb; int status; - if (read(source, &size, sizeof(int)) > 0) + if (read(source, &size, sizeof(int)) == sizeof(int)) { + ssize_t red; purple_debug_info("dnssrv","found %d SRV entries\n", size); tmp = res = g_new0(PurpleSrvResponse, size); for (i = 0; i < size; i++) { - read(source, tmp++, sizeof(PurpleSrvResponse)); + red = read(source, tmp++, sizeof(PurpleSrvResponse)); + if (red != sizeof(PurpleSrvResponse)) { + purple_debug_error("dnssrv","unable to read srv " + "response: %s\n", g_strerror(errno)); + size = 0; + g_free(res); + res = NULL; + } } } else @@ -350,9 +358,12 @@ /* Child */ if (pid == 0) { + g_free(query); + close(out[0]); close(in[1]); resolve(in[0], out[1]); + /* resolve() does not return */ } close(out[1]); diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/example/nullclient.c --- a/libpurple/example/nullclient.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/example/nullclient.c Thu Jan 17 20:44:48 2008 +0000 @@ -268,6 +268,7 @@ GMainLoop *loop = g_main_loop_new(NULL, FALSE); PurpleAccount *account; PurpleSavedStatus *status; + char *res; /* libpurple's built-in DNS resolution forks processes to perform * blocking lookups without blocking the main process. It does not @@ -290,12 +291,20 @@ } } printf("Select the protocol [0-%d]: ", i-1); - fgets(name, sizeof(name), stdin); + res = fgets(name, sizeof(name), stdin); + if (!res) { + fprintf(stderr, "Failed to gets protocol selection."); + abort(); + } sscanf(name, "%d", &num); prpl = g_list_nth_data(names, num); printf("Username: "); - fgets(name, sizeof(name), stdin); + res = fgets(name, sizeof(name), stdin); + if (!res) { + fprintf(stderr, "Failed to read user name."); + abort(); + } name[strlen(name) - 1] = 0; /* strip the \n at the end */ /* Create the account */ diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/ft.c --- a/libpurple/ft.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/ft.c Thu Jan 17 20:44:48 2008 +0000 @@ -32,6 +32,7 @@ #include "proxy.h" #include "request.h" #include "util.h" +#include "debug.h" #define FT_INITIAL_BUFFER_SIZE 4096 #define FT_MAX_BUFFER_SIZE 65535 @@ -903,7 +904,12 @@ if (condition & PURPLE_INPUT_READ) { r = purple_xfer_read(xfer, &buffer); if (r > 0) { - fwrite(buffer, 1, r, xfer->dest_fp); + const size_t wc = fwrite(buffer, 1, r, xfer->dest_fp); + if (wc != r) { + purple_debug_error("filetransfer", "Unable to write whole buffer.\n"); + purple_xfer_cancel_remote(xfer); + return; + } } else if(r < 0) { purple_xfer_cancel_remote(xfer); return; @@ -911,6 +917,7 @@ } if (condition & PURPLE_INPUT_WRITE) { + size_t result; size_t s = MIN(purple_xfer_get_bytes_remaining(xfer), xfer->current_buffer_size); /* this is so the prpl can keep the connection open @@ -925,7 +932,13 @@ buffer = g_malloc0(s); - fread(buffer, 1, s, xfer->dest_fp); + result = fread(buffer, 1, s, xfer->dest_fp); + if (result != s) { + purple_debug_error("filetransfer", "Unable to read whole buffer.\n"); + purple_xfer_cancel_remote(xfer); + g_free(buffer); + return; + } /* Write as much as we're allowed to. */ r = purple_xfer_write(xfer, buffer, s); diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/log.c --- a/libpurple/log.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/log.c Thu Jan 17 20:44:48 2008 +0000 @@ -1859,11 +1859,15 @@ static char * old_logger_read (PurpleLog *log, PurpleLogReadFlags *flags) { + size_t result; struct old_logger_data *data = log->logger_data; - FILE *file = g_fopen(purple_stringref_value(data->pathref), "rb"); + const char *path = purple_stringref_value(data->pathref); + FILE *file = g_fopen(path, "rb"); char *read = g_malloc(data->length + 1); fseek(file, data->offset, SEEK_SET); - fread(read, data->length, 1, file); + result = fread(read, data->length, 1, file); + if (result != 1) + purple_debug_error("log", "Unable to read from log file: %s\n", path); fclose(file); read[data->length] = '\0'; *flags = 0; diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/plugins/offlinemsg.c --- a/libpurple/plugins/offlinemsg.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/plugins/offlinemsg.c Thu Jan 17 20:44:48 2008 +0000 @@ -159,7 +159,7 @@ purple_request_action(handle, _("Offline Message"), ask, _("You can edit/delete the pounce from the `Buddy Pounces' dialog"), - 1, + 0, offline->account, offline->who, offline->conv, offline, 2, _("Yes"), record_pounce, diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/bonjour/jabber.c --- a/libpurple/protocols/bonjour/jabber.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/bonjour/jabber.c Thu Jan 17 20:44:48 2008 +0000 @@ -995,7 +995,7 @@ bb->conversation = NULL; } - purple_timeout_add(0, _async_bonjour_jabber_close_conversation_cb, bconv); + bconv->close_timeout = purple_timeout_add(0, _async_bonjour_jabber_close_conversation_cb, bconv); } void @@ -1054,6 +1054,9 @@ if (bconv->context != NULL) bonjour_parser_setup(bconv); + if (bconv->close_timeout != 0) + purple_timeout_remove(bconv->close_timeout); + g_free(bconv->buddy_name); g_free(bconv->ip); g_free(bconv); diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/bonjour/jabber.h --- a/libpurple/protocols/bonjour/jabber.h Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/bonjour/jabber.h Thu Jan 17 20:44:48 2008 +0000 @@ -47,6 +47,7 @@ gint socket; guint rx_handler; guint tx_handler; + guint close_timeout; PurpleCircBuffer *tx_buf; int sent_stream_start; /* 0 = Unsent, 1 = Partial, 2 = Complete */ gboolean recv_stream_start; diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/irc/dcc_send.c --- a/libpurple/protocols/irc/dcc_send.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/irc/dcc_send.c Thu Jan 17 20:44:48 2008 +0000 @@ -51,9 +51,14 @@ */ static void irc_dccsend_recv_ack(PurpleXfer *xfer, const guchar *data, size_t size) { unsigned long l; + size_t result; l = htonl(xfer->bytes_sent); - write(xfer->fd, &l, sizeof(l)); + result = write(xfer->fd, &l, sizeof(l)); + if (result != sizeof(l)) { + purple_debug_error("irc", "unable to send acknowledgement: %s\n", g_strerror(errno)); + /* TODO: We should probably close the connection here or something. */ + } } static void irc_dccsend_recv_init(PurpleXfer *xfer) { diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/jabber/auth.c --- a/libpurple/protocols/jabber/auth.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/jabber/auth.c Thu Jan 17 20:44:48 2008 +0000 @@ -325,7 +325,7 @@ purple_request_yes_no(js->gc, _("Plaintext Authentication"), _("Plaintext Authentication"), msg, - 2, js->gc->account, NULL, NULL, js->gc->account, + 1, js->gc->account, NULL, NULL, js->gc->account, allow_cyrus_plaintext_auth, disallow_plaintext_auth); g_free(msg); @@ -527,7 +527,7 @@ purple_request_yes_no(js->gc, _("Plaintext Authentication"), _("Plaintext Authentication"), msg, - 2, + 1, purple_connection_get_account(js->gc), NULL, NULL, purple_connection_get_account(js->gc), allow_plaintext_auth, disallow_plaintext_auth); @@ -719,7 +719,7 @@ purple_request_yes_no(js->gc, _("Plaintext Authentication"), _("Plaintext Authentication"), _("This server requires plaintext authentication over an unencrypted connection. Allow this and continue authentication?"), - 2, + 1, purple_connection_get_account(js->gc), NULL, NULL, purple_connection_get_account(js->gc), allow_plaintext_auth, disallow_plaintext_auth); diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/jabber/jabber.c --- a/libpurple/protocols/jabber/jabber.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/jabber/jabber.c Thu Jan 17 20:44:48 2008 +0000 @@ -2301,14 +2301,10 @@ GList *jabber_attention_types(PurpleAccount *account) { static GList *types = NULL; - PurpleAttentionType *attn; if (!types) { - attn = g_new0(PurpleAttentionType, 1); - attn->name = _("Buzz"); - attn->incoming_description = _("%s has buzzed you!"); - attn->outgoing_description = _("Buzzing %s..."); - types = g_list_append(types, attn); + types = g_list_append(types, purple_attention_type_new("Buzz", _("Buzz"), + _("%s has buzzed you!"), _("Buzzing %s..."))); } return types; diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/msn/msn.c --- a/libpurple/protocols/msn/msn.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/msn/msn.c Thu Jan 17 20:44:48 2008 +0000 @@ -122,15 +122,11 @@ static GList * msn_attention_types(PurpleAccount *account) { - PurpleAttentionType *attn; static GList *list = NULL; if (!list) { - attn = g_new0(PurpleAttentionType, 1); - attn->name = _("Nudge"); - attn->incoming_description = _("%s has nudged you!"); - attn->outgoing_description = _("Nudging %s..."); - list = g_list_append(list, attn); + list = g_list_append(list, purple_attention_type_new("Nudge", _("Nudge"), + _("%s has nudged you!"), _("Nudging %s..."))); } return list; @@ -355,7 +351,7 @@ _("Do you want to allow or disallow people on " "your buddy list to send you MSN Mobile pages " "to your cell phone or other mobile device?"), - -1, + PURPLE_DEFAULT_ACTION_NONE, purple_connection_get_account(gc), NULL, NULL, gc, 3, _("Allow"), G_CALLBACK(enable_msn_pages_cb), diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/msnp9/msn.c --- a/libpurple/protocols/msnp9/msn.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/msnp9/msn.c Thu Jan 17 20:44:48 2008 +0000 @@ -122,15 +122,11 @@ static GList * msn_attention_types(PurpleAccount *account) { - PurpleAttentionType *attn; static GList *list = NULL; if (!list) { - attn = g_new0(PurpleAttentionType, 1); - attn->name = _("Nudge"); - attn->incoming_description = _("%s has nudged you!"); - attn->outgoing_description = _("Nudging %s..."); - list = g_list_append(list, attn); + list = g_list_append(list, purple_attention_type_new("Nudge", _("Nudge"), + _("%s has nudged you!"), _("Nudging %s..."))); } return list; @@ -351,7 +347,7 @@ _("Do you want to allow or disallow people on " "your buddy list to send you MSN Mobile pages " "to your cell phone or other mobile device?"), - -1, + PURPLE_DEFAULT_ACTION_NONE, purple_connection_get_account(gc), NULL, NULL, gc, 3, _("Allow"), G_CALLBACK(enable_msn_pages_cb), diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/msnp9/notification.c --- a/libpurple/protocols/msnp9/notification.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/msnp9/notification.c Thu Jan 17 20:44:48 2008 +0000 @@ -1012,7 +1012,7 @@ { purple_debug_error("msn", "Error opening temp passport file: %s\n", - strerror(errno)); + g_strerror(errno)); } else { @@ -1061,7 +1061,7 @@ { purple_debug_error("msn", "Error closing temp passport file: %s\n", - strerror(errno)); + g_strerror(errno)); g_unlink(session->passport_info.file); g_free(session->passport_info.file); diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/msnp9/servconn.c --- a/libpurple/protocols/msnp9/servconn.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/msnp9/servconn.c Thu Jan 17 20:44:48 2008 +0000 @@ -392,7 +392,7 @@ return; else if (len <= 0) { - purple_debug_error("msn", "servconn read error, len: %d error: %s\n", len, strerror(errno)); + purple_debug_error("msn", "servconn read error, len: %d error: %s\n", len, g_strerror(errno)); msn_servconn_got_error(servconn, MSN_SERVCONN_ERROR_READ); return; diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/myspace/myspace.c --- a/libpurple/protocols/myspace/myspace.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/myspace/myspace.c Thu Jan 17 20:44:48 2008 +0000 @@ -2316,6 +2316,69 @@ msim_msg_free(blocklist_msg); } +/** + * Borrowed this code from oscar_normalize. Added checking for "if userid, get name before normalizing" + * + * Basically... Returns a string that has been formated with all the spaces and caps removed. + */ +const char *msim_normalize(const PurpleAccount *account, const char *str) { + static char normalized[BUF_LEN]; + MsimSession *session; + char *tmp1, *tmp2; + int i, j; + guint id; + + g_return_val_if_fail(str != NULL, NULL); + + if (msim_is_userid(str)) { + /* Have user ID, we need to get their username first :) */ + const char *username; + + /* If the account does not exist, we can't look up the user. */ + g_return_val_if_fail(account != NULL, str); + g_return_val_if_fail(account->gc != NULL, str); + g_return_val_if_fail(account->gc->state == PURPLE_CONNECTED, str); + + purple_debug_info("msim_normalize", "%s is a userid\n",str); + + session = (MsimSession *)account->gc->proto_data; + id = atol(str); + username = msim_uid2username_from_blist(session, id); + if (!username) { + /* Not in buddy list... scheisse... TODO: Manual Lookup! */ + /* Note: manual lookup using msim_lookup_user() is a problem inside + * msim_normalize(), because msim_lookup_user() calls a callback function + * when the user information has been looked up, but msim_normalize() expects + * the result immediately. */ + purple_debug_info("msim_normalize", "Failure! %s is not in my list\n", str); + strncpy(normalized, str, BUF_LEN); + } else { + purple_debug_info("msim_normalize","%d is %s\n", id, username); + strncpy(normalized, username, BUF_LEN); + } + } else { + /* Have username. */ + strncpy(normalized, str, BUF_LEN); + } + + /* Strip spaces. */ + for (i=0, j=0; normalized[j]; i++, j++) { + while (normalized[j] == ' ') + j++; + normalized[i] = normalized[j]; + } + normalized[i] = '\0'; + + /* Lowercase and perform UTF-8 normalization. */ + tmp1 = g_utf8_strdown(normalized, -1); + tmp2 = g_utf8_normalize(tmp1, -1, G_NORMALIZE_DEFAULT); + g_snprintf(normalized, sizeof(normalized), "%s", tmp2); + g_free(tmp2); + g_free(tmp1); + + return normalized; +} + /** Return whether the buddy can be messaged while offline. * * The protocol supports offline messages in just the same way as online @@ -2970,7 +3033,7 @@ NULL, /* rename_group */ NULL, /* buddy_free */ NULL, /* convo_closed */ - NULL, /* normalize */ + msim_normalize, /* normalize */ NULL, /* set_buddy_icon */ NULL, /* remove_group */ NULL, /* get_cb_real_name */ diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/myspace/myspace.h --- a/libpurple/protocols/myspace/myspace.h Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/myspace/myspace.h Thu Jan 17 20:44:48 2008 +0000 @@ -180,8 +180,6 @@ #define MSIM_CONTACT_LIST_IMPORT_ALL_FRIENDS 1 #define MSIM_CONTACT_LIST_IMPORT_TOP_FRIENDS 2 -#define MsimAttentionType PurpleAttentionType - /* Functions */ gboolean msim_load(PurplePlugin *plugin); GList *msim_status_types(PurpleAccount *acct); @@ -201,6 +199,8 @@ void msim_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group); void msim_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group); +const char *msim_normalize(const PurpleAccount *account, const char *str); + gboolean msim_offline_message(const PurpleBuddy *buddy); void msim_close(PurpleConnection *gc); diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/myspace/zap.c --- a/libpurple/protocols/myspace/zap.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/myspace/zap.c Thu Jan 17 20:44:48 2008 +0000 @@ -29,15 +29,12 @@ msim_attention_types(PurpleAccount *acct) { static GList *types = NULL; - MsimAttentionType* attn; + PurpleAttentionType* attn; if (!types) { -#define _MSIM_ADD_NEW_ATTENTION(icn, nme, incoming, outgoing) \ - attn = g_new0(MsimAttentionType, 1); \ - attn->icon_name = icn; \ - attn->name = nme; \ - attn->incoming_description = incoming; \ - attn->outgoing_description = outgoing; \ +#define _MSIM_ADD_NEW_ATTENTION(icn, ulname, nme, incoming, outgoing) \ + attn = purple_attention_type_new(ulname, nme, incoming, outgoing); \ + purple_attention_type_set_icon_name(attn, icn); \ types = g_list_append(types, attn); /* TODO: icons for each zap */ @@ -48,37 +45,46 @@ * projectile or weapon." This term often has an electrical * connotation, for example, "he was zapped by electricity when * he put a fork in the toaster." */ - _MSIM_ADD_NEW_ATTENTION(NULL, _("Zap"), _("%s has zapped you!"), _("Zapping %s...")); + _MSIM_ADD_NEW_ATTENTION(NULL, "Zap", _("Zap"), _("%s has zapped you!"), + _("Zapping %s...")); /* Whack means "to hit or strike someone with a sharp blow" */ - _MSIM_ADD_NEW_ATTENTION(NULL, _("Whack"), _("%s has whacked you!"), _("Whacking %s...")); + _MSIM_ADD_NEW_ATTENTION(NULL, "Whack", _("Whack"), + _("%s has whacked you!"), _("Whacking %s...")); /* Torch means "to set on fire." Don't worry, this doesn't * make a whole lot of sense in English, either. Feel free * to translate it literally. */ - _MSIM_ADD_NEW_ATTENTION(NULL, _("Torch"), _("%s has torched you!"), _("Torching %s...")); + _MSIM_ADD_NEW_ATTENTION(NULL, "Torch", _("Torch"), + _("%s has torched you!"), _("Torching %s...")); /* Smooch means "to kiss someone, often enthusiastically" */ - _MSIM_ADD_NEW_ATTENTION(NULL, _("Smooch"), _("%s has smooched you!"), _("Smooching %s...")); + _MSIM_ADD_NEW_ATTENTION(NULL, "Smooch", _("Smooch"), + _("%s has smooched you!"), _("Smooching %s...")); /* A hug is a display of affection; wrapping your arms around someone */ - _MSIM_ADD_NEW_ATTENTION(NULL, _("Hug"), _("%s has hugged you!"), _("Hugging %s...")); + _MSIM_ADD_NEW_ATTENTION(NULL, "Hug", _("Hug"), _("%s has hugged you!"), + _("Hugging %s...")); /* Slap means "to hit someone with an open/flat hand" */ - _MSIM_ADD_NEW_ATTENTION(NULL, _("Slap"), _("%s has slapped you!"), _("Slapping %s...")); + _MSIM_ADD_NEW_ATTENTION(NULL, "Slap", _("Slap"), + _("%s has slapped you!"), _("Slapping %s...")); /* Goose means "to pinch someone on their butt" */ - _MSIM_ADD_NEW_ATTENTION(NULL, _("Goose"), _("%s has goosed you!"), _("Goosing %s...")); + _MSIM_ADD_NEW_ATTENTION(NULL, "Goose", _("Goose"), + _("%s has goosed you!"), _("Goosing %s...")); /* A high-five is when two people's hands slap each other * in the air above their heads. It is done to celebrate * something, often a victory, or to congratulate someone. */ - _MSIM_ADD_NEW_ATTENTION(NULL, _("High-five"), _("%s has high-fived you!"), _("High-fiving %s...")); + _MSIM_ADD_NEW_ATTENTION(NULL, "High-five", _("High-five"), + _("%s has high-fived you!"), _("High-fiving %s...")); /* We're not entirely sure what the MySpace people mean by * this... but we think it's the equivalent of "prank." Or, for * someone to perform a mischievous trick or practical joke. */ - _MSIM_ADD_NEW_ATTENTION(NULL, _("Punk"), _("%s has punk'd you!"), _("Punking %s...")); + _MSIM_ADD_NEW_ATTENTION(NULL, "Punk", _("Punk"), + _("%s has punk'd you!"), _("Punking %s...")); /* Raspberry is a slang term for the vibrating sound made * when you stick your tongue out of your mouth with your @@ -87,7 +93,8 @@ * gesture, so it does not carry a harsh negative * connotation. It is generally used in a playful tone * with friends. */ - _MSIM_ADD_NEW_ATTENTION(NULL, _("Raspberry"), _("%s has raspberried you!"), _("Raspberrying %s...")); + _MSIM_ADD_NEW_ATTENTION(NULL, "Raspberry", _("Raspberry"), + _("%s has raspberried you!"), _("Raspberrying %s...")); } return types; @@ -99,14 +106,14 @@ { GList *types; MsimSession *session; - MsimAttentionType *attn; + PurpleAttentionType *attn; PurpleBuddy *buddy; session = (MsimSession *)gc->proto_data; /* Look for this attention type, by the code index given. */ types = msim_attention_types(gc->account); - attn = (MsimAttentionType *)g_list_nth_data(types, code); + attn = (PurpleAttentionType *)g_list_nth_data(types, code); if (!attn) { purple_debug_info("msim_send_attention", "got invalid zap code %d\n", code); @@ -200,12 +207,12 @@ i = 0; do { - MsimAttentionType *attn; + PurpleAttentionType *attn; - attn = (MsimAttentionType *)types->data; + attn = (PurpleAttentionType *)types->data; - act = purple_menu_action_new(attn->name, PURPLE_CALLBACK(msim_send_zap_from_menu), - GUINT_TO_POINTER(i), NULL); + act = purple_menu_action_new(purple_attention_type_get_name(attn), + PURPLE_CALLBACK(msim_send_zap_from_menu), GUINT_TO_POINTER(i), NULL); zap_menu = g_list_append(zap_menu, act); ++i; diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/novell/nmfield.c --- a/libpurple/protocols/novell/nmfield.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/novell/nmfield.c Thu Jan 17 20:44:48 2008 +0000 @@ -164,9 +164,7 @@ case NMFIELD_TYPE_BINARY: case NMFIELD_TYPE_UTF8: case NMFIELD_TYPE_DN: - if (field->ptr_value != NULL) { - g_free(field->ptr_value); - } + g_free(field->ptr_value); break; case NMFIELD_TYPE_ARRAY: diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/novell/novell.c --- a/libpurple/protocols/novell/novell.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/novell/novell.c Thu Jan 17 20:44:48 2008 +0000 @@ -1920,6 +1920,7 @@ parms = g_slist_append(parms, nm_event_get_conference(event)); /* Prompt the user */ + /* TODO: Would it be better to use serv_got_chat_invite() here? */ gc = purple_account_get_connection(user->client_data); purple_request_action(gc, title, primary, secondary, PURPLE_DEFAULT_ACTION_NONE, diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/oscar/family_buddy.c --- a/libpurple/protocols/oscar/family_buddy.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/oscar/family_buddy.c Thu Jan 17 20:44:48 2008 +0000 @@ -219,8 +219,9 @@ if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) ret = userfunc(od, conn, frame, &userinfo); - if (snac->subtype == SNAC_SUBTYPE_BUDDY_ONCOMING) - aim_locate_requestuserinfo(od, userinfo.sn); + if (snac->subtype == SNAC_SUBTYPE_BUDDY_ONCOMING && userinfo.flags & AIM_FLAG_AWAY) + aim_locate_autofetch_away_message(od, userinfo.sn); + aim_info_free(&userinfo); return ret; diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/oscar/family_locate.c --- a/libpurple/protocols/oscar/family_locate.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/oscar/family_locate.c Thu Jan 17 20:44:48 2008 +0000 @@ -386,11 +386,11 @@ } void -aim_locate_requestuserinfo(OscarData *od, const char *sn) +aim_locate_autofetch_away_message(OscarData *od, const char *sn) { struct userinfo_node *cur; - /* Make sure we haven't already requested info for this buddy */ + /* Make sure we haven't already made an info request for this buddy */ for (cur = od->locate.requested; cur != NULL; cur = cur->next) if (aim_sncmp(sn, cur->sn) == 0) return; @@ -401,7 +401,7 @@ cur->next = od->locate.requested; od->locate.requested = cur; - aim_locate_getinfoshort(od, cur->sn, 0x00000003); + aim_locate_getinfoshort(od, cur->sn, 0x00000002); } aim_userinfo_t *aim_locate_finduserinfo(OscarData *od, const char *sn) { diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/oscar/libaim.c --- a/libpurple/protocols/oscar/libaim.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/oscar/libaim.c Thu Jan 17 20:44:48 2008 +0000 @@ -92,11 +92,11 @@ NULL, /* whiteboard_prpl_ops */ NULL, /* send_raw */ NULL, /* roomlist_room_serialize */ + NULL, /* unregister_user */ + NULL, /* send_attention */ + NULL, /* get_attention_types */ /* padding */ - NULL, - NULL, - NULL, NULL }; diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/oscar/libicq.c --- a/libpurple/protocols/oscar/libicq.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/oscar/libicq.c Thu Jan 17 20:44:48 2008 +0000 @@ -92,11 +92,11 @@ NULL, /* whiteboard_prpl_ops */ NULL, /* send_raw */ NULL, /* roomlist_room_serialize */ + NULL, /* unregister_user */ + NULL, /* send_attention */ + NULL, /* get_attention_types */ /* padding */ - NULL, - NULL, - NULL, NULL }; diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/oscar/oscar.c --- a/libpurple/protocols/oscar/oscar.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/oscar/oscar.c Thu Jan 17 20:44:48 2008 +0000 @@ -1517,6 +1517,7 @@ { struct pieceofcrap *pos = data; gchar *buf; + ssize_t result; if (!PURPLE_CONNECTION_IS_VALID(pos->gc)) { @@ -1528,8 +1529,8 @@ pos->fd = source; if (source < 0) { - buf = g_strdup_printf(_("You may be disconnected shortly. You may want to use TOC until " - "this is fixed. Check %s for updates."), PURPLE_WEBSITE); + buf = g_strdup_printf(_("You may be disconnected shortly. " + "Check %s for updates."), PURPLE_WEBSITE); purple_notify_warning(pos->gc, NULL, _("Unable to get a valid AIM login hash."), buf); @@ -1541,7 +1542,18 @@ buf = g_strdup_printf("GET " AIMHASHDATA "?offset=%ld&len=%ld&modname=%s HTTP/1.0\n\n", pos->offset, pos->len, pos->modname ? pos->modname : ""); - write(pos->fd, buf, strlen(buf)); + result = send(pos->fd, buf, strlen(buf), 0); + if (result != strlen(buf)) { + if (result < 0) + purple_debug_error("oscar", "Error writing %" G_GSIZE_FORMAT + " bytes to fetch AIM hash data: %s\n", + strlen(buf), g_strerror(errno)); + else + purple_debug_error("oscar", "Tried to write %" + G_GSIZE_FORMAT " bytes to fetch AIM hash data but " + "instead wrote %" G_GSIZE_FORMAT " bytes\n", + strlen(buf), result); + } g_free(buf); g_free(pos->modname); pos->inpa = purple_input_add(pos->fd, PURPLE_INPUT_READ, damn_you, pos); @@ -1723,7 +1735,6 @@ int type = 0; gboolean buddy_is_away = FALSE; const char *status_id; - char *itmsurl = NULL; va_list ap; aim_userinfo_t *info; @@ -1771,11 +1782,6 @@ status_id = OSCAR_STATUS_ID_AVAILABLE; } - if (info->itmsurl_encoding && info->itmsurl && info->itmsurl_len) - /* Grab the iTunes Music Store URL */ - itmsurl = oscar_encoding_to_utf8(account, info->itmsurl_encoding, - info->itmsurl, info->itmsurl_len); - if (info->flags & AIM_FLAG_WIRELESS) { purple_prpl_got_user_status(account, info->sn, OSCAR_STATUS_ID_MOBILE, NULL); @@ -1783,27 +1789,31 @@ purple_prpl_got_user_status_deactive(account, info->sn, OSCAR_STATUS_ID_MOBILE); } - if (status_id == OSCAR_STATUS_ID_AVAILABLE) + if (strcmp(status_id, OSCAR_STATUS_ID_AVAILABLE) == 0) { char *message = NULL; + char *itmsurl = NULL; if (info->status != NULL && info->status[0] != '\0') /* Grab the available message */ message = oscar_encoding_to_utf8(account, info->status_encoding, info->status, info->status_len); + if (info->itmsurl_encoding && info->itmsurl && info->itmsurl_len) + /* Grab the iTunes Music Store URL */ + itmsurl = oscar_encoding_to_utf8(account, info->itmsurl_encoding, + info->itmsurl, info->itmsurl_len); + purple_prpl_got_user_status(account, info->sn, status_id, "message", message, "itmsurl", itmsurl, NULL); g_free(message); + g_free(itmsurl); } else { - purple_prpl_got_user_status(account, info->sn, status_id, - "itmsurl", itmsurl, NULL); - } - - g_free(itmsurl); + purple_prpl_got_user_status(account, info->sn, status_id, NULL); + } /* Login time stuff */ if (info->present & AIM_USERINFO_PRESENT_ONLINESINCE) @@ -4444,7 +4454,6 @@ PurplePresence *presence; PurpleStatusType *status_type; PurpleStatusPrimitive primitive; - gboolean invisible; char *htmlinfo; char *info_encoding = NULL; @@ -4459,7 +4468,6 @@ status_type = purple_status_get_type(status); primitive = purple_status_type_get_primitive(status_type); presence = purple_account_get_presence(account); - invisible = purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_INVISIBLE); if (!setinfo) { @@ -5219,7 +5227,7 @@ data->nick = (buddy ? g_strdup(purple_buddy_get_alias_only(buddy)) : NULL); purple_request_yes_no(gc, NULL, _("Authorization Given"), dialog_msg, - 1, /* Default action is "no" */ + PURPLE_DEFAULT_ACTION_NONE, purple_connection_get_account(gc), sn, NULL, data, G_CALLBACK(purple_icq_buddyadd), @@ -5975,7 +5983,7 @@ _("Because this reveals your IP address, it " "may be considered a security risk. Do you " "wish to continue?"), - 0, + 0, /* Default action is "connect" */ purple_connection_get_account(gc), data->who, NULL, data, 2, _("C_onnect"), G_CALLBACK(oscar_ask_directim_yes_cb), diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/oscar/oscar.h --- a/libpurple/protocols/oscar/oscar.h Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/oscar/oscar.h Thu Jan 17 20:44:48 2008 +0000 @@ -1074,7 +1074,7 @@ /* 0x000f */ int aim_locate_setinterests(OscarData *od, const char *interest1, const char *interest2, const char *interest3, const char *interest4, const char *interest5, guint16 privacy); /* 0x0015 */ int aim_locate_getinfoshort(OscarData *od, const char *sn, guint32 flags); -void aim_locate_requestuserinfo(OscarData *od, const char *sn); +void aim_locate_autofetch_away_message(OscarData *od, const char *sn); guint32 aim_locate_getcaps(OscarData *od, ByteStream *bs, int len); guint32 aim_locate_getcaps_short(OscarData *od, ByteStream *bs, int len); void aim_info_free(aim_userinfo_t *); diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/oscar/peer.c --- a/libpurple/protocols/oscar/peer.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/oscar/peer.c Thu Jan 17 20:44:48 2008 +0000 @@ -1041,7 +1041,7 @@ "Images. Because your IP address will be " "revealed, this may be considered a privacy " "risk."), - PURPLE_DEFAULT_ACTION_NONE, + 0, /* Default action is "connect" */ account, sn, NULL, conn, 2, _("C_onnect"), G_CALLBACK(peer_connection_got_proposition_yes_cb), diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/qq/file_trans.c --- a/libpurple/protocols/qq/file_trans.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/qq/file_trans.c Thu Jan 17 20:44:48 2008 +0000 @@ -97,6 +97,7 @@ guint8 *buffer; PurpleCipher *cipher; PurpleCipherContext *context; + size_t wc; const gint QQ_MAX_FILE_MD5_LENGTH = 10002432; @@ -109,15 +110,20 @@ buffer = g_newa(guint8, filelen); g_return_if_fail(buffer != NULL); - fread(buffer, filelen, 1, fp); + wc = fread(buffer, filelen, 1, fp); + fclose(fp); + if (wc != 1) { + purple_debug_error("qq", "Unable to read file: %s\n", filename); + + /* TODO: XXX: Really, the caller should be modified to deal with this properly. */ + return; + } cipher = purple_ciphers_find_cipher("md5"); context = purple_cipher_context_new(cipher, NULL); purple_cipher_context_append(context, buffer, filelen); purple_cipher_context_digest(context, 16, md5, NULL); purple_cipher_context_destroy(context); - - fclose(fp); } static void _qq_get_file_header(guint8 *buf, guint8 **cursor, gint buflen, qq_file_header *fh) diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/qq/group_im.c --- a/libpurple/protocols/qq/group_im.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/qq/group_im.c Thu Jan 17 20:44:48 2008 +0000 @@ -135,7 +135,7 @@ purple_request_action(gc, _("QQ Qun Operation"), msg, reason, - 2, + PURPLE_DEFAULT_ACTION_NONE, purple_connection_get_account(gc), nombre, NULL, g, 3, _("Approve"), diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/qq/group_opt.c --- a/libpurple/protocols/qq/group_opt.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/qq/group_opt.c Thu Jan 17 20:44:48 2008 +0000 @@ -96,7 +96,8 @@ g_return_if_fail(g != NULL && g->gc != NULL && g->member > 0); qq_send_packet_get_info(g->gc, g->member, TRUE); /* we want to see window */ - purple_request_action(g->gc, NULL, _("Do you want to approve the request?"), "", 2, + purple_request_action(g->gc, NULL, _("Do you want to approve the request?"), "", + PURPLE_DEFAULT_ACTION_NONE, purple_connection_get_account(g->gc), NULL, NULL, g, 2, _("Reject"), G_CALLBACK(qq_group_reject_application_with_struct), diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/qq/sys_msg.c --- a/libpurple/protocols/qq/sys_msg.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/qq/sys_msg.c Thu Jan 17 20:44:48 2008 +0000 @@ -84,7 +84,8 @@ nombre = uid_to_purple_name(uid); purple_request_action - (gc, NULL, _("Do you want to approve the request?"), "", 2, + (gc, NULL, _("Do you want to approve the request?"), "", + PURPLE_DEFAULT_ACTION_NONE, purple_connection_get_account(gc), nombre, NULL, g, 2, _("Reject"), G_CALLBACK(qq_reject_add_request_with_gc_and_uid), @@ -107,7 +108,8 @@ qq_send_packet_get_info(gc, uid, TRUE); /* we want to see window */ nombre = uid_to_purple_name(uid); purple_request_action - (gc, NULL, _("Do you want to add this buddy?"), "", 2, + (gc, NULL, _("Do you want to add this buddy?"), "", + PURPLE_DEFAULT_ACTION_NONE, purple_connection_get_account(gc), nombre, NULL, g, 2, _("Cancel"), NULL, @@ -166,7 +168,8 @@ message = g_strdup_printf(_("You have been added by %s"), from); _qq_sys_msg_log_write(gc, message, from); purple_request_action(gc, NULL, message, - _("Would you like to add him?"), 2, + _("Would you like to add him?"), + PURPLE_DEFAULT_ACTION_NONE, purple_connection_get_account(gc), name, NULL, g, 3, _("Cancel"), NULL, @@ -240,7 +243,7 @@ _qq_sys_msg_log_write(gc, message, from); purple_request_action - (gc, NULL, message, reason, 2, + (gc, NULL, message, reason, PURPLE_DEFAULT_ACTION_NONE, purple_connection_get_account(gc), name, NULL, g, 3, _("Reject"), @@ -260,7 +263,7 @@ g2->uid = strtol(from, NULL, 10); message = g_strdup_printf(_("%s is not in your buddy list"), from); purple_request_action(gc, NULL, message, - _("Would you like to add him?"), 2, + _("Would you like to add him?"), PURPLE_DEFAULT_ACTION_NONE, purple_connection_get_account(gc), name, NULL, g2, 3, _("Cancel"), NULL, diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/sametime/sametime.c --- a/libpurple/protocols/sametime/sametime.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/sametime/sametime.c Thu Jan 17 20:44:48 2008 +0000 @@ -2286,6 +2286,7 @@ PurpleXfer *xfer; FILE *fp; + size_t wc; xfer = mwFileTransfer_getClientData(ft); g_return_if_fail(xfer != NULL); @@ -2294,7 +2295,12 @@ g_return_if_fail(fp != NULL); /* we must collect and save our precious data */ - fwrite(data->data, 1, data->len, fp); + wc = fwrite(data->data, 1, data->len, fp); + if (wc != data->len) { + DEBUG_ERROR("failed to write data\n"); + purple_xfer_cancel_local(xfer); + return; + } /* update the progress */ xfer->bytes_sent += data->len; diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/yahoo/util.c --- a/libpurple/protocols/yahoo/util.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/yahoo/util.c Thu Jan 17 20:44:48 2008 +0000 @@ -164,6 +164,25 @@ return g_strdup(""); } +char *yahoo_convert_to_numeric(const char *str) +{ + GString *gstr = NULL; + char *retstr; + const char *p; + + gstr = g_string_sized_new(strlen(str) * 6 + 1); + + for (p = str; *p; p++) { + g_string_append_printf(gstr, "&#%u;", *p); + } + + retstr = gstr->str; + + g_string_free(gstr, FALSE); + + return retstr; +} + /* * I found these on some website but i don't know that they actually * work (or are supposed to work). I didn't implement them yet. diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/yahoo/yahoo.c --- a/libpurple/protocols/yahoo/yahoo.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/yahoo/yahoo.c Thu Jan 17 20:44:48 2008 +0000 @@ -4165,17 +4165,13 @@ GList *yahoo_attention_types(PurpleAccount *account) { - PurpleAttentionType *attn; static GList *list = NULL; if (!list) { /* Yahoo only supports one attention command: the 'buzz'. */ /* This is index number YAHOO_BUZZ. */ - attn = g_new0(PurpleAttentionType, 1); - attn->name = _("Buzz"); - attn->incoming_description = _("%s has buzzed you!"); - attn->outgoing_description = _("Buzzing %s..."); - list = g_list_append(list, attn); + list = g_list_append(list, purple_attention_type_new("Buzz", _("Buzz"), + _("%s has buzzed you!"), _("Buzzing %s..."))); } return list; diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/yahoo/yahoo.h --- a/libpurple/protocols/yahoo/yahoo.h Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/yahoo/yahoo.h Thu Jan 17 20:44:48 2008 +0000 @@ -48,6 +48,8 @@ /*not sure, must test:*/ #define YAHOOJP_XFER_RELAY_HOST "relay.msg.yahoo.com" #define YAHOOJP_XFER_RELAY_PORT 80 +#define YAHOOJP_ROOMLIST_URL "http://insider.msg.yahoo.co.jp/ycontent/" +#define YAHOOJP_ROOMLIST_LOCALE "ja" #define YAHOO_AUDIBLE_URL "http://us.dl1.yimg.com/download.yahoo.com/dl/aud" @@ -216,6 +218,8 @@ */ char *yahoo_string_decode(PurpleConnection *gc, const char *str, gboolean utf8); +char *yahoo_convert_to_numeric(const char *str); + /* previously-static functions, now needed for yahoo_profile.c */ void yahoo_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gboolean full); diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/yahoo/yahoo_aliases.c --- a/libpurple/protocols/yahoo/yahoo_aliases.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/yahoo/yahoo_aliases.c Thu Jan 17 20:44:48 2008 +0000 @@ -37,6 +37,8 @@ /* I hate hardcoding this stuff, but Yahoo never sends us anything to use. Someone in the know may be able to tweak this URL */ #define YAHOO_ALIAS_FETCH_URL "http://address.yahoo.com/yab/us?v=XM&prog=ymsgr&.intl=us&diffs=1&t=0&tags=short&rt=0&prog-ver=8.1.0.249&useutf8=1&legenc=codepage-1252" #define YAHOO_ALIAS_UPDATE_URL "http://address.yahoo.com/yab/us?v=XM&prog=ymsgr&.intl=us&sync=1&tags=short&noclear=1&useutf8=1&legenc=codepage-1252" +#define YAHOOJP_ALIAS_FETCH_URL "http://address.yahoo.co.jp/yab/jp?v=XM&prog=ymsgr&.intl=jp&diffs=1&t=0&tags=short&rt=0&prog-ver=7.0.0.7" +#define YAHOOJP_ALIAS_UPDATE_URL "http://address.yahoo.co.jp/yab/jp?v=XM&prog=ymsgr&.intl=jp&sync=1&tags=short&noclear=1" void yahoo_update_alias(PurpleConnection *gc, const char *who, const char *alias); @@ -90,7 +92,10 @@ id = xmlnode_get_attrib(item,"id"); /* Yahoo stores first and last names separately, lets put them together into a full name */ - full_name = g_strstrip(g_strdup_printf("%s %s", (fn != NULL ? fn : "") , (ln != NULL ? ln : ""))); + if (yd->jp) + full_name = g_strstrip(g_strdup_printf("%s %s", (ln != NULL ? ln : "") , (fn != NULL ? fn : ""))); + else + full_name = g_strstrip(g_strdup_printf("%s %s", (fn != NULL ? fn : "") , (ln != NULL ? ln : ""))); nick_name = (nn != NULL ? g_strstrip(g_strdup_printf("%s", nn)) : NULL); if (nick_name != NULL) @@ -139,7 +144,7 @@ { struct yahoo_data *yd = gc->proto_data; struct callback_data *cb; - const char *url = YAHOO_ALIAS_FETCH_URL; + const char *url; char *request, *webpage, *webaddress; PurpleUtilFetchUrlData *url_data; @@ -148,6 +153,7 @@ cb->gc = gc; /* Build all the info to make the web request */ + url = yd->jp ? YAHOOJP_ALIAS_FETCH_URL : YAHOO_ALIAS_FETCH_URL; purple_url_parse(url, &webaddress, NULL, &webpage, NULL, NULL); request = g_strdup_printf("GET /%s HTTP/1.1\r\n" "User-Agent: Mozilla/4.0 (compatible; MSIE 5.5)\r\n" @@ -221,14 +227,15 @@ struct yahoo_data *yd; struct YahooUser *yu; char *content, *url, *request, *webpage, *webaddress, *strtmp; + char *escaped_alias, *alias_jp, *converted_alias_jp; int inttmp; struct callback_data *cb; PurpleBuddy *buddy; PurpleUtilFetchUrlData *url_data; - g_return_if_fail(alias!= NULL); - g_return_if_fail(who!=NULL); - g_return_if_fail(gc!=NULL); + g_return_if_fail(alias != NULL); + g_return_if_fail(who != NULL); + g_return_if_fail(gc != NULL); purple_debug_info("yahoo", "Sending '%s' as new alias for user '%s'.\n",alias, who); @@ -247,12 +254,25 @@ cb->gc = gc; /* Build all the info to make the web request */ - url = g_strdup(YAHOO_ALIAS_UPDATE_URL); + url = yd->jp? YAHOOJP_ALIAS_UPDATE_URL: YAHOO_ALIAS_UPDATE_URL; purple_url_parse(url, &webaddress, &inttmp, &webpage, &strtmp, &strtmp); - content = g_strdup_printf("\n" - "\n\r\n", - gc->account->username, who, yu->id, g_markup_escape_text(alias, strlen(alias))); + if (yd->jp) { + alias_jp = g_convert(alias, strlen(alias), "EUC-JP", "UTF-8", NULL, NULL, NULL); + converted_alias_jp = yahoo_convert_to_numeric(alias_jp); + content = g_strdup_printf("\n" + "\n\r\n", + gc->account->username, who, yu->id, converted_alias_jp); + free(converted_alias_jp); + g_free(alias_jp); + } + else { + escaped_alias = g_markup_escape_text(alias, strlen(alias)); + content = g_strdup_printf("\n" + "\n\r\n", + gc->account->username, who, yu->id, escaped_alias); + g_free(escaped_alias); + } request = g_strdup_printf("POST /%s HTTP/1.1\r\n" "User-Agent: Mozilla/4.0 (compatible; MSIE 5.5)\r\n" @@ -271,7 +291,6 @@ } g_free(content); - g_free(url); g_free(request); } diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/yahoo/yahoo_packet.h --- a/libpurple/protocols/yahoo/yahoo_packet.h Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/yahoo/yahoo_packet.h Thu Jan 17 20:44:48 2008 +0000 @@ -101,7 +101,7 @@ YAHOO_SERVICE_AUTH_REQ_15 = 0xd6, YAHOO_SERVICE_CHGRP_15 = 0xe7, YAHOO_SERVICE_STATUS_15 = 0xf0, - YAHOO_SERVICE_LIST_15 = 0Xf1, + YAHOO_SERVICE_LIST_15 = 0xf1, YAHOO_SERVICE_FILETRANS_15 = 0xdc, YAHOO_SERVICE_FILETRANS_INFO_15 = 0xdd, YAHOO_SERVICE_FILETRANS_ACC_15 = 0xde, diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/yahoo/yahoochat.c --- a/libpurple/protocols/yahoo/yahoochat.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/yahoo/yahoochat.c Thu Jan 17 20:44:48 2008 +0000 @@ -1461,28 +1461,30 @@ PurpleRoomlist *yahoo_roomlist_get_list(PurpleConnection *gc) { - struct yahoo_roomlist *yrl; + PurpleAccount *account; PurpleRoomlist *rl; - const char *rll; + PurpleRoomlistField *f; + GList *fields = NULL; + struct yahoo_roomlist *yrl; + const char *rll, *rlurl; char *url; - GList *fields = NULL; - PurpleRoomlistField *f; - rll = purple_account_get_string(purple_connection_get_account(gc), - "room_list_locale", YAHOO_ROOMLIST_LOCALE); + account = purple_connection_get_account(gc); - if (rll != NULL && *rll != '\0') { - url = g_strdup_printf("%s?chatcat=0&intl=%s", - purple_account_get_string(purple_connection_get_account(gc), - "room_list", YAHOO_ROOMLIST_URL), rll); - } else { - url = g_strdup_printf("%s?chatcat=0", - purple_account_get_string(purple_connection_get_account(gc), - "room_list", YAHOO_ROOMLIST_URL)); + /* for Yahoo Japan, it appears there is only one valid URL and locale */ + if(purple_account_get_bool(account, "yahoojp", FALSE)) { + rll = YAHOOJP_ROOMLIST_LOCALE; + rlurl = YAHOOJP_ROOMLIST_URL; + } + else { /* but for the rest of the world that isn't the case */ + rll = purple_account_get_string(account, "room_list_locale", YAHOO_ROOMLIST_LOCALE); + rlurl = purple_account_get_string(account, "room_list", YAHOO_ROOMLIST_URL); } + url = g_strdup_printf("%s?chatcat=0&intl=%s", rlurl, rll); + yrl = g_new0(struct yahoo_roomlist, 1); - rl = purple_roomlist_new(purple_connection_get_account(gc)); + rl = purple_roomlist_new(account); yrl->list = rl; purple_url_parse(url, &(yrl->host), NULL, &(yrl->path), NULL, NULL); @@ -1508,7 +1510,7 @@ purple_roomlist_set_fields(rl, fields); - if (purple_proxy_connect(NULL, purple_connection_get_account(gc), yrl->host, 80, + if (purple_proxy_connect(NULL, account, yrl->host, 80, yahoo_roomlist_got_connected, yrl) == NULL) { purple_notify_error(gc, NULL, _("Connection problem"), _("Unable to fetch room list.")); diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/zephyr/ZSendList.c --- a/libpurple/protocols/zephyr/ZSendList.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/zephyr/ZSendList.c Thu Jan 17 20:44:48 2008 +0000 @@ -24,7 +24,7 @@ char *list[]; int nitems; Z_AuthProc cert_routine; - Code_t (*send_routine)(void); + Code_t (*send_routine)(); { Code_t retval; ZNotice_t newnotice; diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/zephyr/ZSendNot.c --- a/libpurple/protocols/zephyr/ZSendNot.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/zephyr/ZSendNot.c Thu Jan 17 20:44:48 2008 +0000 @@ -20,7 +20,7 @@ Code_t ZSrvSendNotice(notice, cert_routine, send_routine) ZNotice_t *notice; Z_AuthProc cert_routine; - Code_t (*send_routine)(void); + Code_t (*send_routine)(); { Code_t retval; ZNotice_t newnotice; diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/zephyr/zephyr.c --- a/libpurple/protocols/zephyr/zephyr.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/zephyr/zephyr.c Thu Jan 17 20:44:48 2008 +0000 @@ -156,13 +156,20 @@ #endif static Code_t zephyr_subscribe_to(zephyr_account* zephyr, char* class, char *instance, char *recipient, char* galaxy) { + size_t result; + Code_t ret_val = -1; if (use_tzc(zephyr)) { /* ((tzcfodder . subscribe) ("class" "instance" "recipient")) */ gchar *zsubstr = g_strdup_printf("((tzcfodder . subscribe) (\"%s\" \"%s\" \"%s\"))\n",class,instance,recipient); - write(zephyr->totzc[ZEPHYR_FD_WRITE],zsubstr,strlen(zsubstr)); + size_t len = strlen(zsubstr); + result = write(zephyr->totzc[ZEPHYR_FD_WRITE],zsubstr,len); + if (result != len) { + purple_debug_error("zephyr", "Unable to write a message: %s\n", g_strerror(errno)); + } else { + ret_val = ZERR_NONE; + } g_free(zsubstr); - return ZERR_NONE; } else { if (use_zeph02(zephyr)) { @@ -170,13 +177,10 @@ sub.zsub_class = class; sub.zsub_classinst = instance; sub.zsub_recipient = recipient; - return ZSubscribeTo(&sub,1,0); - } else { - /* This should not happen */ - return -1; + ret_val = ZSubscribeTo(&sub,1,0); } } - return -1; + return ret_val; } char *local_zephyr_normalize(zephyr_account* zephyr,const char *); @@ -1373,7 +1377,11 @@ } else if (use_tzc(zephyr)) { gchar *zlocstr = g_strdup_printf("((tzcfodder . zlocate) \"%s\")\n",chk); - write(zephyr->totzc[ZEPHYR_FD_WRITE],zlocstr,strlen(zlocstr)); + size_t len = strlen(zlocstr); + size_t result = write(zephyr->totzc[ZEPHYR_FD_WRITE],zlocstr,len); + if (result != len) { + purple_debug_error("zephyr", "Unable to write a message: %s\n", g_strerror(errno)); + } g_free(zlocstr); } } @@ -2193,6 +2201,8 @@ html_buf2 = purple_unescape_html(html_buf); if(use_tzc(zephyr)) { + size_t len; + size_t result; char* zsendstr; /* CMU cclub tzc doesn't grok opcodes for now */ char* tzc_sig = zephyr_tzc_escape_msg(sig); @@ -2200,7 +2210,14 @@ zsendstr = g_strdup_printf("((tzcfodder . send) (class . \"%s\") (auth . t) (recipients (\"%s\" . \"%s\")) (message . (\"%s\" \"%s\")) ) \n", zclass, instance, recipient, tzc_sig, tzc_body); /* fprintf(stderr,"zsendstr = %s\n",zsendstr); */ - write(zephyr->totzc[ZEPHYR_FD_WRITE],zsendstr,strlen(zsendstr)); + len = strlen(zsendstr); + result = write(zephyr->totzc[ZEPHYR_FD_WRITE], zsendstr, len); + if (result != len) { + g_free(zsendstr); + g_free(html_buf2); + g_free(html_buf); + return errno; + } g_free(zsendstr); } else if (use_zeph02(zephyr)) { ZNotice_t notice; @@ -2221,6 +2238,9 @@ purple_debug_info("zephyr","About to send notice\n"); if (! ZSendNotice(¬ice, ZAUTH) == ZERR_NONE) { /* XXX handle errors here */ + g_free(buf); + g_free(html_buf2); + g_free(html_buf); return 0; } purple_debug_info("zephyr","notice sent\n"); @@ -2257,7 +2277,7 @@ ZAsyncLocateData_t ald; zephyr_account *zephyr = gc->proto_data; gchar* normalized_who = local_zephyr_normalize(zephyr,who); - + if (use_zeph02(zephyr)) { if (ZRequestLocations(normalized_who, &ald, UNACKED, ZAUTH) == ZERR_NONE) { zephyr->pending_zloc_names = g_list_append(zephyr->pending_zloc_names, @@ -2266,14 +2286,22 @@ /* XXX deal with errors somehow */ } } else if (use_tzc(zephyr)) { + size_t len; + size_t result; char* zlocstr = g_strdup_printf("((tzcfodder . zlocate) \"%s\")\n",normalized_who); zephyr->pending_zloc_names = g_list_append(zephyr->pending_zloc_names, g_strdup(normalized_who)); - write(zephyr->totzc[ZEPHYR_FD_WRITE],zlocstr,strlen(zlocstr)); + len = strlen(zlocstr); + result = write(zephyr->totzc[ZEPHYR_FD_WRITE],zlocstr,len); + if (result != len) { + purple_debug_error("zephyr", "Unable to write a message: %s\n", g_strerror(errno)); + } g_free(zlocstr); } } static void zephyr_set_status(PurpleAccount *account, PurpleStatus *status) { + size_t len; + size_t result; zephyr_account *zephyr = purple_account_get_connection(account)->proto_data; PurpleStatusPrimitive primitive = purple_status_type_get_primitive(purple_status_get_type(status)); @@ -2291,7 +2319,11 @@ } else { char *zexpstr = g_strdup_printf("((tzcfodder . set-location) (hostname . \"%s\") (exposure . \"%s\"))\n",zephyr->ourhost,zephyr->exposure); - write(zephyr->totzc[ZEPHYR_FD_WRITE],zexpstr,strlen(zexpstr)); + len = strlen(zexpstr); + result = write(zephyr->totzc[ZEPHYR_FD_WRITE],zexpstr,len); + if (result != len) { + purple_debug_error("zephyr", "Unable to write message: %s\n", g_strerror(errno)); + } g_free(zexpstr); } } @@ -2301,7 +2333,11 @@ ZSetLocation(EXPOSE_OPSTAFF); } else { char *zexpstr = g_strdup_printf("((tzcfodder . set-location) (hostname . \"%s\") (exposure . \"%s\"))\n",zephyr->ourhost,EXPOSE_OPSTAFF); - write(zephyr->totzc[ZEPHYR_FD_WRITE],zexpstr,strlen(zexpstr)); + len = strlen(zexpstr); + result = write(zephyr->totzc[ZEPHYR_FD_WRITE],zexpstr,len); + if (result != len) { + purple_debug_error("zephyr", "Unable to write message: %s\n", g_strerror(errno)); + } g_free(zexpstr); } } diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/protocols/zephyr/zephyr.h --- a/libpurple/protocols/zephyr/zephyr.h Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/protocols/zephyr/zephyr.h Thu Jan 17 20:44:48 2008 +0000 @@ -163,9 +163,9 @@ Code_t ZReadAscii16 ZP((char *, int, unsigned short *)); Code_t ZSendPacket ZP((char*, int, int)); Code_t ZSendList ZP((ZNotice_t*, char *[], int, Z_AuthProc)); -Code_t ZSrvSendList ZP((ZNotice_t*, char*[], int, Z_AuthProc, Code_t (*)(void))); +Code_t ZSrvSendList ZP((ZNotice_t*, char*[], int, Z_AuthProc, Code_t (*)())); Code_t ZSendNotice ZP((ZNotice_t *, Z_AuthProc)); -Code_t ZSrvSendNotice ZP((ZNotice_t*, Z_AuthProc, Code_t (*)(void))); +Code_t ZSrvSendNotice ZP((ZNotice_t*, Z_AuthProc, Code_t (*)())); Code_t ZFormatNotice ZP((ZNotice_t*, char**, int*, Z_AuthProc)); Code_t ZFormatSmallNotice ZP((ZNotice_t*, ZPacket_t, int*, Z_AuthProc)); Code_t ZFormatRawNoticeList ZP((ZNotice_t *notice, char *list[], int nitems, diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/prpl.c --- a/libpurple/prpl.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/prpl.c Thu Jan 17 20:44:48 2008 +0000 @@ -29,6 +29,107 @@ #include "util.h" /**************************************************************************/ +/** @name Attention Type API */ +/**************************************************************************/ +PurpleAttentionType * +purple_attention_type_new(const char *ulname, const char *name, + const char *inc_desc, const char *out_desc) +{ + PurpleAttentionType *attn = g_new0(PurpleAttentionType, 1); + + purple_attention_type_set_name(attn, name); + purple_attention_type_set_incoming_desc(attn, inc_desc); + purple_attention_type_set_outgoing_desc(attn, out_desc); + purple_attention_type_set_unlocalized_name(attn, ulname); + + return attn; +} + + +void +purple_attention_type_set_name(PurpleAttentionType *type, const char *name) +{ + g_return_if_fail(type != NULL); + + type->name = name; +} + +void +purple_attention_type_set_incoming_desc(PurpleAttentionType *type, const char *desc) +{ + g_return_if_fail(type != NULL); + + type->incoming_description = desc; +} + +void +purple_attention_type_set_outgoing_desc(PurpleAttentionType *type, const char *desc) +{ + g_return_if_fail(type != NULL); + + type->outgoing_description = desc; +} + +void +purple_attention_type_set_icon_name(PurpleAttentionType *type, const char *name) +{ + g_return_if_fail(type != NULL); + + type->icon_name = name; +} + +void +purple_attention_type_set_unlocalized_name(PurpleAttentionType *type, const char *ulname) +{ + g_return_if_fail(type != NULL); + + type->unlocalized_name = ulname; +} + +const char * +purple_attention_type_get_name(const PurpleAttentionType *type) +{ + g_return_val_if_fail(type != NULL, NULL); + + return type->name; +} + +const char * +purple_attention_type_get_incoming_desc(const PurpleAttentionType *type) +{ + g_return_val_if_fail(type != NULL, NULL); + + return type->incoming_description; +} + +const char * +purple_attention_type_get_outgoing_desc(const PurpleAttentionType *type) +{ + g_return_val_if_fail(type != NULL, NULL); + + return type->outgoing_description; +} + +const char * +purple_attention_type_get_icon_name(const PurpleAttentionType *type) +{ + g_return_val_if_fail(type != NULL, NULL); + + if(type->icon_name == NULL || *(type->icon_name) == '\0') + return NULL; + + return type->icon_name; +} + +const char * +purple_attention_type_get_unlocalized_name(const PurpleAttentionType *type) +{ + g_return_val_if_fail(type != NULL, NULL); + + return type->unlocalized_name; +} + +/**************************************************************************/ /** @name Protocol Plugin API */ /**************************************************************************/ void diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/prpl.h --- a/libpurple/prpl.h Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/prpl.h Thu Jan 17 20:44:48 2008 +0000 @@ -99,9 +99,9 @@ const char *incoming_description; /**< Shown when sent */ const char *outgoing_description; /**< Shown when receied */ const char *icon_name; /**< Icon to display (optional) */ + const char *unlocalized_name; /**< Unlocalized name for UIs needing it */ /* Reserved fields for future purposes */ - gpointer _reserved1; gpointer _reserved2; gpointer _reserved3; gpointer _reserved4; @@ -412,6 +412,127 @@ #endif /**************************************************************************/ +/** @name Attention Type API */ +/**************************************************************************/ +/*@{*/ + +/** + * Creates a new #PurpleAttentionType object and sets its mandatory parameters. + * + * @param ulname A non-localized string that can be used by UIs in need of such + * non-localized strings. This should be the same as @a name, + * without localization. + * @param name A localized string that the UI may display for the event. This + * should be the same string as @a ulname, with localization. + * @param inc_desc A localized description shown when the event is received. + * @param out_desc A localized description shown when the event is sent. + * @return A pointer to the new object. + * @since 2.4.0 + */ +PurpleAttentionType *purple_attention_type_new(const char *ulname, const char *name, + const char *inc_desc, const char *out_desc); + +/** + * Sets the displayed name of the attention-demanding event. + * + * @param type The attention type. + * @param name The localized name that will be displayed by UIs. This should be + * the same string given as the unlocalized name, but with + * localization. + * @since 2.4.0 + */ +void purple_attention_type_set_name(PurpleAttentionType *type, const char *name); + +/** + * Sets the description of the attention-demanding event shown in conversations + * when the event is received. + * + * @param type The attention type. + * @param desc The localized description for incoming events. + * @since 2.4.0 + */ +void purple_attention_type_set_incoming_desc(PurpleAttentionType *type, const char *desc); + +/** + * Sets the description of the attention-demanding event shown in conversations + * when the event is sent. + * + * @param type The attention type. + * @param desc The localized description for outgoing events. + * @since 2.4.0 + */ +void purple_attention_type_set_outgoing_desc(PurpleAttentionType *type, const char *desc); + +/** + * Sets the name of the icon to display for the attention event; this is optional. + * + * @param type The attention type. + * @param name The icon's name. + * @note Icons are optional for attention events. + * @since 2.4.0 + */ +void purple_attention_type_set_icon_name(PurpleAttentionType *type, const char *name); + +/** + * Sets the unlocalized name of the attention event; some UIs may need this, + * thus it is required. + * + * @param type The attention type. + * @param ulname The unlocalized name. This should be the same string given as + * the localized name, but without localization. + * @since 2.4.0 + */ +void purple_attention_type_set_unlocalized_name(PurpleAttentionType *type, const char *ulname); + +/** + * Get the attention type's name as displayed by the UI. + * + * @param type The attention type. + * @return The name. + * @since 2.4.0 + */ +const char *purple_attention_type_get_name(const PurpleAttentionType *type); + +/** + * Get the attention type's description shown when the event is received. + * + * @param type The attention type. + * @return The description. + * @since 2.4.0 + */ +const char *purple_attention_type_get_incoming_desc(const PurpleAttentionType *type); + +/** + * Get the attention type's description shown when the event is sent. + * + * @param type The attention type. + * @return The description. + * @since 2.4.0 + */ +const char *purple_attention_type_get_outgoing_desc(const PurpleAttentionType *type); + +/** + * Get the attention type's icon name. + * + * @param type The attention type. + * @return The icon name or @c NULL if unset/empty. + * @note Icons are optional for attention events. + * @since 2.4.0 + */ +const char *purple_attention_type_get_icon_name(const PurpleAttentionType *type); + +/** + * Get the attention type's unlocalized name; this is useful for some UIs. + * + * @param type The attention type + * @return The unlocalized name. + * @since 2.4.0 + */ +const char *purple_attention_type_get_unlocalized_name(const PurpleAttentionType *type); + +/*@}*/ + +/**************************************************************************/ /** @name Protocol Plugin API */ /**************************************************************************/ /*@{*/ diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/request.h --- a/libpurple/request.h Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/request.h Thu Jan 17 20:44:48 2008 +0000 @@ -1318,6 +1318,8 @@ * @param secondary Secondary information, or @c NULL if there is none. * @param default_action The default action, zero-indexed; if the third action * supplied should be the default, supply 2. + * The should be the action that users are most likely + * to select. * @param account The #PurpleAccount associated with this request, or @c * NULL if none is. * @param who The username of the buddy associated with this request, @@ -1356,6 +1358,8 @@ * @param secondary Secondary information, or @c NULL if there is none. * @param default_action The default action, zero-indexed; if the third action * supplied should be the default, supply 2. + * The should be the action that users are most likely + * to select. * @param account The #PurpleAccount associated with this request, or @c * NULL if none is. * @param who The username of the buddy associated with this request, diff -r 2fb026d3f42b -r 3c814c64a507 libpurple/util.c --- a/libpurple/util.c Thu Jan 17 20:37:22 2008 +0000 +++ b/libpurple/util.c Thu Jan 17 20:44:48 2008 +0000 @@ -4629,6 +4629,15 @@ #endif /* !_WIN32 */ } +static void +set_status_with_attrs(PurpleStatus *status, ...) +{ + va_list args; + va_start(args, status); + purple_status_set_active_with_attrs(status, TRUE, args); + va_end(args); +} + void purple_util_set_current_song(const char *title, const char *artist, const char *album) { GList *list = purple_accounts_get_all(); @@ -4644,10 +4653,11 @@ if (!tune) continue; if (title) { - purple_status_set_active(tune, TRUE); - purple_status_set_attr_string(tune, PURPLE_TUNE_TITLE, title); - purple_status_set_attr_string(tune, PURPLE_TUNE_ARTIST, artist); - purple_status_set_attr_string(tune, PURPLE_TUNE_ALBUM, album); + set_status_with_attrs(tune, + PURPLE_TUNE_TITLE, title, + PURPLE_TUNE_ARTIST, artist, + PURPLE_TUNE_ALBUM, album, + NULL); } else { purple_status_set_active(tune, FALSE); } diff -r 2fb026d3f42b -r 3c814c64a507 pidgin/gtkaccount.c --- a/pidgin/gtkaccount.c Thu Jan 17 20:37:22 2008 +0000 +++ b/pidgin/gtkaccount.c Thu Jan 17 20:44:48 2008 +0000 @@ -2177,6 +2177,7 @@ treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(dialog->model)); dialog->treeview = treeview; gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE); + g_object_unref(G_OBJECT(dialog->model)); sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); gtk_tree_selection_set_mode(sel, GTK_SELECTION_MULTIPLE); diff -r 2fb026d3f42b -r 3c814c64a507 pidgin/gtkblist.c --- a/pidgin/gtkblist.c Thu Jan 17 20:37:22 2008 +0000 +++ b/pidgin/gtkblist.c Thu Jan 17 20:44:48 2008 +0000 @@ -937,7 +937,6 @@ pidgin_blist_joinchat_show(void) { GtkWidget *hbox, *vbox; - GtkWidget *rowbox; GtkWidget *label; PidginBuddyList *gtkblist; GtkWidget *img = NULL; @@ -981,7 +980,6 @@ data->account_menu = pidgin_account_option_menu_new(NULL, FALSE, G_CALLBACK(joinchat_select_account_cb), chat_account_filter_func, data); - gtk_box_pack_start(GTK_BOX(rowbox), data->account_menu, TRUE, TRUE, 0); pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("_Account:"), data->sg, data->account_menu, TRUE, NULL); @@ -4145,12 +4143,11 @@ static void pidgin_blist_new_list(PurpleBuddyList *blist) { PidginBuddyList *gtkblist; - PidginBuddyListPrivate *priv; gtkblist = g_new0(PidginBuddyList, 1); gtkblist->connection_errors = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free); - gtkblist->priv = priv = g_new0(PidginBuddyListPrivate, 1); + gtkblist->priv = g_new0(PidginBuddyListPrivate, 1); blist->ui_data = gtkblist; } @@ -6071,6 +6068,7 @@ gtkblist->timeout = 0; gtkblist->drag_timeout = 0; gtkblist->window = gtkblist->vbox = gtkblist->treeview = NULL; + g_object_unref(G_OBJECT(gtkblist->treemodel)); gtkblist->treemodel = NULL; g_object_unref(G_OBJECT(gtkblist->ift)); g_object_unref(G_OBJECT(gtkblist->empty_avatar)); diff -r 2fb026d3f42b -r 3c814c64a507 pidgin/gtkcertmgr.c --- a/pidgin/gtkcertmgr.c Thu Jan 17 20:37:22 2008 +0000 +++ b/pidgin/gtkcertmgr.c Thu Jan 17 20:44:48 2008 +0000 @@ -373,7 +373,7 @@ purple_request_yes_no(tpm_dat, _("Confirm certificate delete"), primary, NULL, /* Can this be NULL? */ - 2, /* NO is default action */ + 1, /* NO is default action */ NULL, NULL, NULL, id, /* id ownership passed to callback */ tls_peers_mgmt_delete_confirm_cb, @@ -422,6 +422,7 @@ tpm_dat->listview = listview = GTK_TREE_VIEW(gtk_tree_view_new_with_model(GTK_TREE_MODEL(store))); + g_object_unref(G_OBJECT(store)); { GtkCellRenderer *renderer; diff -r 2fb026d3f42b -r 3c814c64a507 pidgin/gtkconv.c --- a/pidgin/gtkconv.c Thu Jan 17 20:37:22 2008 +0000 +++ b/pidgin/gtkconv.c Thu Jan 17 20:44:48 2008 +0000 @@ -441,6 +441,13 @@ cmdline = cmd + strlen(prefix); + if (strcmp(cmdline, "xyzzy") == 0) { + purple_conversation_write(conv, "", "Nothing happens", + PURPLE_MESSAGE_NO_LOG, time(NULL)); + g_free(cmd); + return TRUE; + } + gtk_text_iter_forward_chars(&start, g_utf8_strlen(prefix, -1)); gtk_text_buffer_get_end_iter(GTK_IMHTML(gtkconv->entry)->text_buffer, &end); markup = gtk_imhtml_get_markup_range(GTK_IMHTML(gtkconv->entry), &start, &end); diff -r 2fb026d3f42b -r 3c814c64a507 pidgin/gtkimhtmltoolbar.c --- a/pidgin/gtkimhtmltoolbar.c Thu Jan 17 20:37:22 2008 +0000 +++ b/pidgin/gtkimhtmltoolbar.c Thu Jan 17 20:44:48 2008 +0000 @@ -1312,6 +1312,7 @@ gtk_box_pack_start(GTK_BOX(hbox), box, FALSE, FALSE, 0); g_object_set_data(G_OBJECT(hbox), "lean-view", box); + gtk_widget_show(box); purple_prefs_connect_callback(toolbar, PIDGIN_PREFS_ROOT "/conversations/toolbar/wide", imhtmltoolbar_view_pref_changed, toolbar); diff -r 2fb026d3f42b -r 3c814c64a507 pidgin/gtklog.c --- a/pidgin/gtklog.c Thu Jan 17 20:37:22 2008 +0000 +++ b/pidgin/gtklog.c Thu Jan 17 20:44:48 2008 +0000 @@ -139,7 +139,7 @@ { /* Searching for the same term acts as "Find Next" */ gtk_imhtml_search_find(GTK_IMHTML(lv->imhtml), lv->search); - return; + return; } pidgin_set_cursor(lv->window, GDK_WATCH); @@ -321,7 +321,7 @@ data2[0] = lv->treestore; data2[1] = data[3]; /* iter */ data2[2] = log; - purple_request_action(lv, NULL, "Delete Log?", tmp, 0, + purple_request_action(lv, NULL, "Delete Log?", tmp, 0, NULL, NULL, NULL, data2, 2, _("Delete"), delete_log_cb, @@ -556,8 +556,13 @@ if (!purple_prefs_get_bool("/purple/logging/log_chats")) log_preferences = _("Chats will only be logged if the \"Log all chats\" preference is enabled."); } + g_free(ht->screenname); + g_free(ht); } + if(icon != NULL) + gtk_widget_destroy(icon); + purple_notify_info(NULL, title, _("No logs were found"), log_preferences); return NULL; } @@ -614,6 +619,7 @@ gtk_paned_add1(GTK_PANED(pane), sw); lv->treestore = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_POINTER); lv->treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (lv->treestore)); + g_object_unref(G_OBJECT(lv->treestore)); rend = gtk_cell_renderer_text_new(); col = gtk_tree_view_column_new_with_attributes ("time", rend, "markup", 0, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW(lv->treeview), col); @@ -730,18 +736,19 @@ } void pidgin_log_show_contact(PurpleContact *contact) { - struct log_viewer_hash_t *ht = g_new0(struct log_viewer_hash_t, 1); + struct log_viewer_hash_t *ht; PurpleBlistNode *child; PidginLogViewer *lv = NULL; GList *logs = NULL; GdkPixbuf *pixbuf; - GtkWidget *image = gtk_image_new(); + GtkWidget *image; const char *name = NULL; char *title; int total_log_size = 0; g_return_if_fail(contact != NULL); + ht = g_new0(struct log_viewer_hash_t, 1); ht->type = PURPLE_LOG_IM; ht->contact = contact; @@ -763,9 +770,16 @@ } logs = g_list_sort(logs, purple_log_compare); + image = gtk_image_new(); pixbuf = gtk_widget_render_icon(image, PIDGIN_STOCK_STATUS_PERSON, gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_SMALL), "GtkWindow"); - gtk_image_set_from_pixbuf(GTK_IMAGE(image), pixbuf); + if (pixbuf) { + gtk_image_set_from_pixbuf(GTK_IMAGE(image), pixbuf); + g_object_unref(pixbuf); + } else { + gtk_widget_destroy(image); + image = NULL; + } if (contact->alias != NULL) name = contact->alias; diff -r 2fb026d3f42b -r 3c814c64a507 pidgin/gtkmain.c --- a/pidgin/gtkmain.c Thu Jan 17 20:37:22 2008 +0000 +++ b/pidgin/gtkmain.c Thu Jan 17 20:44:48 2008 +0000 @@ -508,6 +508,7 @@ {"session", required_argument, NULL, 's'}, {"version", no_argument, NULL, 'v'}, {"display", required_argument, NULL, 'D'}, + {"sync", no_argument, NULL, 'S'}, {0, 0, 0, 0} }; @@ -517,7 +518,7 @@ debug_enabled = FALSE; #endif - /* This is the first Glib function call. Make sure to initialize GThread bfeore then */ + /* Initialize GThread before calling any Glib or GTK+ functions. */ g_thread_init(NULL); #ifdef ENABLE_NLS @@ -654,6 +655,7 @@ opt_si = FALSE; break; case 'D': /* --display */ + case 'S': /* --sync */ /* handled by gtk_init_check below */ break; case '?': /* show terse help */ diff -r 2fb026d3f42b -r 3c814c64a507 pidgin/gtknotify.c --- a/pidgin/gtknotify.c Thu Jan 17 20:37:22 2008 +0000 +++ b/pidgin/gtknotify.c Thu Jan 17 20:44:48 2008 +0000 @@ -379,6 +379,7 @@ mail_dialog->treemodel = gtk_tree_store_new(COLUMNS_PIDGIN_MAIL, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_POINTER); mail_dialog->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(mail_dialog->treemodel)); + g_object_unref(G_OBJECT(mail_dialog->treemodel)); gtk_tree_view_set_search_column(GTK_TREE_VIEW(mail_dialog->treeview), PIDGIN_MAIL_TEXT); gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(mail_dialog->treeview), pidgin_tree_view_search_equal_func, NULL, NULL); @@ -818,6 +819,7 @@ /* Setup the treeview */ treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model)); + g_object_unref(G_OBJECT(model)); gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE); gtk_widget_set_size_request(treeview, 500, 400); gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)), diff -r 2fb026d3f42b -r 3c814c64a507 pidgin/gtkpounce.c --- a/pidgin/gtkpounce.c Thu Jan 17 20:37:22 2008 +0000 +++ b/pidgin/gtkpounce.c Thu Jan 17 20:44:48 2008 +0000 @@ -1237,6 +1237,7 @@ /* Create the treeview */ treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(dialog->model)); + g_object_unref(G_OBJECT(dialog->model)); dialog->treeview = treeview; gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE); diff -r 2fb026d3f42b -r 3c814c64a507 pidgin/gtkprefs.c --- a/pidgin/gtkprefs.c Thu Jan 17 20:37:22 2008 +0000 +++ b/pidgin/gtkprefs.c Thu Jan 17 20:44:48 2008 +0000 @@ -478,12 +478,20 @@ { FILE *f; gchar *path; + size_t wc; if ((error_message != NULL) || (len == 0)) return; f = purple_mkstemp(&path, TRUE); - fwrite(themedata, len, 1, f); + wc = fwrite(themedata, len, 1, f); + if (wc != 1) { + purple_debug_warning("theme_got_url", "Unable to write theme data.\n"); + fclose(f); + g_unlink(path); + g_free(path); + return; + } fclose(f); theme_install_theme(path, user_data); @@ -1457,15 +1465,15 @@ } entry = gtk_entry_new(); - if (strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/browsers/browser"), "custom")) - gtk_widget_set_sensitive(hbox, FALSE); - purple_prefs_connect_callback(prefs, PIDGIN_PREFS_ROOT "/browsers/browser", - browser_changed2_cb, hbox); gtk_entry_set_text(GTK_ENTRY(entry), purple_prefs_get_path(PIDGIN_PREFS_ROOT "/browsers/command")); g_signal_connect(G_OBJECT(entry), "focus-out-event", G_CALLBACK(manual_browser_set), NULL); - pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("_Manual:\n(%s for URL)"), sg, entry, TRUE, NULL); + hbox = pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("_Manual:\n(%s for URL)"), sg, entry, TRUE, NULL); + if (strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/browsers/browser"), "custom")) + gtk_widget_set_sensitive(hbox, FALSE); + purple_prefs_connect_callback(prefs, PIDGIN_PREFS_ROOT "/browsers/browser", + browser_changed2_cb, hbox); gtk_widget_show_all(ret); g_object_unref(sg); @@ -1718,9 +1726,6 @@ int j; const char *file; char *pref; -#if !defined _WIN32 || defined USE_GSTREAMER - GtkWidget *label; -#endif #ifndef _WIN32 GtkWidget *dd; GtkWidget *entry; diff -r 2fb026d3f42b -r 3c814c64a507 pidgin/gtkprivacy.c --- a/pidgin/gtkprivacy.c Thu Jan 17 20:37:22 2008 +0000 +++ b/pidgin/gtkprivacy.c Thu Jan 17 20:44:48 2008 +0000 @@ -474,6 +474,8 @@ if (privacy_dialog == NULL) return; + g_object_unref(G_OBJECT(privacy_dialog->allow_store)); + g_object_unref(G_OBJECT(privacy_dialog->block_store)); g_free(privacy_dialog); privacy_dialog = NULL; } diff -r 2fb026d3f42b -r 3c814c64a507 pidgin/gtkrequest.c --- a/pidgin/gtkrequest.c Thu Jan 17 20:37:22 2008 +0000 +++ b/pidgin/gtkrequest.c Thu Jan 17 20:44:48 2008 +0000 @@ -663,7 +663,11 @@ gtk_widget_grab_focus(img); gtk_widget_grab_default(img); } else - gtk_dialog_set_default_response(GTK_DIALOG(dialog), default_action); + /* + * Need to invert the default_action number because the + * buttons are added to the dialog in reverse order. + */ + gtk_dialog_set_default_response(GTK_DIALOG(dialog), action_count - 1 - default_action); /* Show everything. */ pidgin_auto_parent_window(dialog); @@ -1007,6 +1011,7 @@ /* Create the tree view */ treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); + g_object_unref(G_OBJECT(store)); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE); sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); diff -r 2fb026d3f42b -r 3c814c64a507 pidgin/gtksavedstatuses.c --- a/pidgin/gtksavedstatuses.c Thu Jan 17 20:37:22 2008 +0000 +++ b/pidgin/gtksavedstatuses.c Thu Jan 17 20:44:48 2008 +0000 @@ -669,6 +669,7 @@ purple_request_close_with_handle(status_window); purple_notify_close_with_handle(status_window); purple_signals_disconnect_by_handle(status_window); + g_object_unref(G_OBJECT(status_window->model)); g_free(status_window); status_window = NULL; } @@ -723,6 +724,7 @@ status_editor_remove_dialog(dialog); g_free(dialog->original_title); + g_object_unref(G_OBJECT(dialog->model)); g_free(dialog); return FALSE; diff -r 2fb026d3f42b -r 3c814c64a507 pidgin/gtkstatusbox.c --- a/pidgin/gtkstatusbox.c Thu Jan 17 20:37:22 2008 +0000 +++ b/pidgin/gtkstatusbox.c Thu Jan 17 20:44:48 2008 +0000 @@ -320,12 +320,20 @@ { FILE *f; gchar *path; + size_t wc; if ((error_message != NULL) || (len == 0)) return; f = purple_mkstemp(&path, TRUE); - fwrite(themedata, len, 1, f); + wc = fwrite(themedata, len, 1, f); + if (wc != 1) { + purple_debug_warning("theme_got_url", "Unable to write theme data.\n"); + fclose(f); + g_unlink(path); + g_free(path); + return; + } fclose(f); icon_choose_cb(path, user_data); @@ -507,16 +515,10 @@ purple_signals_disconnect_by_handle(statusbox); purple_prefs_disconnect_by_handle(statusbox); - gdk_cursor_unref(statusbox->hand_cursor); - gdk_cursor_unref(statusbox->arrow_cursor); + destroy_icon_box(statusbox); - purple_imgstore_unref(statusbox->buddy_icon_img); - g_object_unref(G_OBJECT(statusbox->buddy_icon)); - g_object_unref(G_OBJECT(statusbox->buddy_icon_hover)); - - if (statusbox->buddy_icon_sel) - gtk_widget_destroy(statusbox->buddy_icon_sel); - + g_object_unref(G_OBJECT(statusbox->store)); + g_object_unref(G_OBJECT(statusbox->dropdown_store)); G_OBJECT_CLASS(parent_class)->finalize(obj); } diff -r 2fb026d3f42b -r 3c814c64a507 pidgin/gtkutils.c --- a/pidgin/gtkutils.c Thu Jan 17 20:37:22 2008 +0000 +++ b/pidgin/gtkutils.c Thu Jan 17 20:44:48 2008 +0000 @@ -1595,7 +1595,7 @@ else if (!(im || ft)) purple_request_yes_no(NULL, NULL, _("You have dragged an image"), _("Would you like to set it as the buddy icon for this user?"), - 0, + PURPLE_DEFAULT_ACTION_NONE, account, who, NULL, data, (GCallback)dnd_set_icon_ok_cb, (GCallback)dnd_set_icon_cancel_cb); else diff -r 2fb026d3f42b -r 3c814c64a507 pidgin/win32/nsis/pidgin-installer.nsi --- a/pidgin/win32/nsis/pidgin-installer.nsi Thu Jan 17 20:37:22 2008 +0000 +++ b/pidgin/win32/nsis/pidgin-installer.nsi Thu Jan 17 20:44:48 2008 +0000 @@ -1167,6 +1167,10 @@ MessageBox MB_RETRYCANCEL|MB_ICONEXCLAMATION $(PIDGIN_IS_RUNNING) /SD IDCANCEL IDRETRY retry_runcheck Abort + ; Close the Handle (If we don't do this, the uninstaller called from within will fail) + ; This is not optimal because there is a (small) window of time when a new process could start + System::Call 'kernel32::CloseHandle(i $R1) i .R1' + Pop $R1 Pop $R0 FunctionEnd diff -r 2fb026d3f42b -r 3c814c64a507 po/POTFILES.in --- a/po/POTFILES.in Thu Jan 17 20:37:22 2008 +0000 +++ b/po/POTFILES.in Thu Jan 17 20:44:48 2008 +0000 @@ -72,6 +72,7 @@ libpurple/protocols/bonjour/bonjour.c libpurple/protocols/bonjour/bonjour.h libpurple/protocols/bonjour/jabber.c +libpurple/protocols/bonjour/mdns_win32.c libpurple/protocols/gg/gg.c libpurple/protocols/irc/cmds.c libpurple/protocols/irc/dcc_send.c @@ -213,6 +214,7 @@ pidgin/pidgin.h pidgin/pidgincombobox.c pidgin/pidginstock.c +pidgin/pidgintooltip.c pidgin/pixmaps/emotes/default/24/default.theme.in pidgin/pixmaps/emotes/none/none.theme.in pidgin/plugins/cap/cap.c