# HG changeset patch # User Sadrul Habib Chowdhury # Date 1191978376 0 # Node ID 2a6ef74f5a4e7cb97477a3606bed49fd97bdac12 # Parent e0ce7124d2d48e348494e82c681749e742051ffb# Parent 817425918f92493614e348627bdd15bd396c9024 merge of '3efb5d625e5a73423be8be77a6baeed0b65f7e55' and 'c848ad4c20988b5dac9ac164455d3ba2d7307230' diff -r e0ce7124d2d4 -r 2a6ef74f5a4e .mtn-ignore --- a/.mtn-ignore Wed Oct 10 01:01:21 2007 +0000 +++ b/.mtn-ignore Wed Oct 10 01:06:16 2007 +0000 @@ -21,7 +21,7 @@ config.status config.sub configure$ -finch/finch +finch/finch$ finch/libgnt/gntmarshal.c finch/libgnt/gntmarshal.h depcomp diff -r e0ce7124d2d4 -r 2a6ef74f5a4e doc/C-HOWTO.dox --- a/doc/C-HOWTO.dox Wed Oct 10 01:01:21 2007 +0000 +++ b/doc/C-HOWTO.dox Wed Oct 10 01:06:16 2007 +0000 @@ -269,3 +269,4 @@ you may have guessed, this also gets read when libpurple is probing your plugin. If this is missing, the plugin will not load. */ +// vim: syntax=c.doxygen diff -r e0ce7124d2d4 -r 2a6ef74f5a4e doc/account-signals.dox --- a/doc/account-signals.dox Wed Oct 10 01:01:21 2007 +0000 +++ b/doc/account-signals.dox Wed Oct 10 01:06:16 2007 +0000 @@ -11,6 +11,8 @@ @signal account-status-changed @endsignals + @see account.h +
@signaldef account-added @@ -101,4 +103,4 @@ @endsignaldef */ -// vim: syntax=c tw=75 et +// vim: syntax=c.doxygen tw=75 et diff -r e0ce7124d2d4 -r 2a6ef74f5a4e doc/blist-signals.dox --- a/doc/blist-signals.dox Wed Oct 10 01:01:21 2007 +0000 +++ b/doc/blist-signals.dox Wed Oct 10 01:06:16 2007 +0000 @@ -13,6 +13,8 @@ @signal blist-node-aliased @endsignals + @see blist.h +
@signaldef buddy-status-changed @@ -105,4 +107,4 @@ @endsignaldef */ -// vim: syntax=c tw=75 et +// vim: syntax=c.doxygen tw=75 et diff -r e0ce7124d2d4 -r 2a6ef74f5a4e doc/certificate-signals.dox --- a/doc/certificate-signals.dox Wed Oct 10 01:01:21 2007 +0000 +++ b/doc/certificate-signals.dox Wed Oct 10 01:06:16 2007 +0000 @@ -5,6 +5,8 @@ @signal certificate-deleted @endsignals + @see certificate.h +
@signaldef certificate-stored @@ -28,4 +30,4 @@ @endsignaldef */ -// vim: syntax=c tw=75 et +// vim: syntax=c.doxygen tw=75 et diff -r e0ce7124d2d4 -r 2a6ef74f5a4e doc/cipher-signals.dox --- a/doc/cipher-signals.dox Wed Oct 10 01:01:21 2007 +0000 +++ b/doc/cipher-signals.dox Wed Oct 10 01:06:16 2007 +0000 @@ -5,6 +5,8 @@ @signal cipher-removed @endsignals + @see cipher.h +
@signaldef cipher-added @@ -26,4 +28,4 @@ @endsignaldef */ -// vim: syntax=c tw=75 et +// vim: syntax=c.doxygen tw=75 et diff -r e0ce7124d2d4 -r 2a6ef74f5a4e doc/connection-signals.dox --- a/doc/connection-signals.dox Wed Oct 10 01:01:21 2007 +0000 +++ b/doc/connection-signals.dox Wed Oct 10 01:06:16 2007 +0000 @@ -7,6 +7,8 @@ @signal signed-off @endsignals + @see connection.h +
@signaldef signing-on @@ -46,4 +48,4 @@ @endsignaldef */ -// vim: syntax=c tw=75 et +// vim: syntax=c.doxygen tw=75 et diff -r e0ce7124d2d4 -r 2a6ef74f5a4e doc/conversation-signals.dox --- a/doc/conversation-signals.dox Wed Oct 10 01:01:21 2007 +0000 +++ b/doc/conversation-signals.dox Wed Oct 10 01:06:16 2007 +0000 @@ -32,6 +32,8 @@ @signal conversation-extended-menu @endsignals + @see conversation.h + @signaldef writing-im-msg @signalproto gboolean (*writing_im_msg)(PurpleAccount *account, const char *who, @@ -429,4 +431,4 @@ @param list A pointer to the list of actions. @endsignaldef */ -// vim: syntax=c tw=75 et +// vim: syntax=c.doxygen tw=75 et diff -r e0ce7124d2d4 -r 2a6ef74f5a4e doc/core-signals.dox --- a/doc/core-signals.dox Wed Oct 10 01:01:21 2007 +0000 +++ b/doc/core-signals.dox Wed Oct 10 01:06:16 2007 +0000 @@ -4,6 +4,8 @@ @signal quitting @endsignals + @see core.h +
@signaldef quitting @@ -15,4 +17,4 @@ @endsignaldef */ -// vim: syntax=c tw=75 et +// vim: syntax=c.doxygen tw=75 et diff -r e0ce7124d2d4 -r 2a6ef74f5a4e doc/dbus-server-signals.dox --- a/doc/dbus-server-signals.dox Wed Oct 10 01:01:21 2007 +0000 +++ b/doc/dbus-server-signals.dox Wed Oct 10 01:06:16 2007 +0000 @@ -5,6 +5,8 @@ @signal dbus-introspect @endsignals + @see dbus-server.h +
@signaldef dbus-method-called @@ -29,4 +31,4 @@ @endsignaldef */ -// vim: syntax=c tw=75 et +// vim: syntax=c.doxygen tw=75 et diff -r e0ce7124d2d4 -r 2a6ef74f5a4e doc/gtkaccount-signals.dox --- a/doc/gtkaccount-signals.dox Wed Oct 10 01:01:21 2007 +0000 +++ b/doc/gtkaccount-signals.dox Wed Oct 10 01:06:16 2007 +0000 @@ -4,6 +4,8 @@ @signal account-modified @endsignals + @see gtkaccount.h +
@signaldef account-modified @@ -15,4 +17,4 @@ @param account The account that has been modified. @endsignaldef */ -// vim: syntax=c tw=75 et +// vim: syntax=c.doxygen tw=75 et diff -r e0ce7124d2d4 -r 2a6ef74f5a4e doc/gtkblist-signals.dox --- a/doc/gtkblist-signals.dox Wed Oct 10 01:01:21 2007 +0000 +++ b/doc/gtkblist-signals.dox Wed Oct 10 01:06:16 2007 +0000 @@ -7,6 +7,8 @@ @signal drawing-tooltip @endsignals + @see gtkblist.h +
@signaldef gtkblist-hiding @@ -52,4 +54,4 @@ a compact tooltip for a non-priority buddy. @endsignaldef */ -// vim: syntax=c tw=75 et +// vim: syntax=c.doxygen tw=75 et diff -r e0ce7124d2d4 -r 2a6ef74f5a4e doc/gtkconv-signals.dox --- a/doc/gtkconv-signals.dox Wed Oct 10 01:01:21 2007 +0000 +++ b/doc/gtkconv-signals.dox Wed Oct 10 01:06:16 2007 +0000 @@ -139,4 +139,4 @@ @endsignaldef */ -// vim: syntax=c tw=75 et +// vim: syntax=c.doxygen tw=75 et diff -r e0ce7124d2d4 -r 2a6ef74f5a4e doc/gtkimhtml-signals.dox --- a/doc/gtkimhtml-signals.dox Wed Oct 10 01:01:21 2007 +0000 +++ b/doc/gtkimhtml-signals.dox Wed Oct 10 01:06:16 2007 +0000 @@ -8,6 +8,8 @@ @signal format_function_update @endsignals + @see gtkimhtml.h +
@signaldef url_clicked @@ -57,4 +59,4 @@ @param data User defined data. @endsignaldef */ -// vim: syntax=c tw=75 et +// vim: syntax=c.doxygen tw=75 et diff -r e0ce7124d2d4 -r 2a6ef74f5a4e doc/gtklog-signals.dox --- a/doc/gtklog-signals.dox Wed Oct 10 01:01:21 2007 +0000 +++ b/doc/gtklog-signals.dox Wed Oct 10 01:06:16 2007 +0000 @@ -4,6 +4,8 @@ @signal log-displaying @endsignals + @see gtklog.h +
@signaldef log-displaying @@ -17,4 +19,4 @@ @endsignaldef */ -// vim: syntax=c tw=75 et +// vim: syntax=c.doxygen tw=75 et diff -r e0ce7124d2d4 -r 2a6ef74f5a4e doc/imgstore-signals.dox --- a/doc/imgstore-signals.dox Wed Oct 10 01:01:21 2007 +0000 +++ b/doc/imgstore-signals.dox Wed Oct 10 01:06:16 2007 +0000 @@ -4,6 +4,8 @@ @signal image-deleting @endsignals + @see imgstore.h +
@signaldef image-deleting @@ -11,7 +13,7 @@ char *(*image_deleting)(const PurpleStoredImage *img); @endsignalproto @signaldesc - Emitted when a PurpleStoredImage is about to be destroyed. This allows + Emitted when a #PurpleStoredImage is about to be destroyed. This allows for what amounts to weak references. Code can hold onto a pointer to the PurpleStoredImage without actually "holding" a reference. They can then use a signal handler to let them know when their img is about to @@ -21,4 +23,4 @@ @endsignaldef */ -// vim: syntax=c tw=75 et +// vim: syntax=c.doxygen tw=75 et diff -r e0ce7124d2d4 -r 2a6ef74f5a4e doc/log-signals.dox --- a/doc/log-signals.dox Wed Oct 10 01:01:21 2007 +0000 +++ b/doc/log-signals.dox Wed Oct 10 01:06:16 2007 +0000 @@ -4,6 +4,8 @@ @signal log-timestamp @endsignals + @see log.h +
@signaldef log-timestamp @@ -21,4 +23,4 @@ @endsignaldef */ -// vim: syntax=c tw=75 et +// vim: syntax=c.doxygen tw=75 et diff -r e0ce7124d2d4 -r 2a6ef74f5a4e doc/notify-signals.dox --- a/doc/notify-signals.dox Wed Oct 10 01:01:21 2007 +0000 +++ b/doc/notify-signals.dox Wed Oct 10 01:06:16 2007 +0000 @@ -6,6 +6,8 @@ @signal displaying-emails-notification @endsignals + @see notify.h + @signaldef displaying-userinfo @signalproto void (*displaying_userinfo)(PurpleAccount *account, const char *who, PurpleNotifyUserInfo *user_info); @@ -53,4 +55,4 @@ @endsignaldef */ -// vim: syntax=c tw=75 et +// vim: syntax=c.doxygen tw=75 et diff -r e0ce7124d2d4 -r 2a6ef74f5a4e doc/plugin-ids.dox --- a/doc/plugin-ids.dox Wed Oct 10 01:01:21 2007 +0000 +++ b/doc/plugin-ids.dox Wed Oct 10 01:06:16 2007 +0000 @@ -2,10 +2,10 @@ @section Introduction Every plugin contains a unique identifier to prevent duplicate plugin - loading and conflicts. This, which will be called a plugin ID from here - on, must follow a specific format. This format categorizes a plugin and - makes duplicate IDs unlikely. - + loading and conflicts. Third-party plugins (that is, plugins written by + anyone who is not a libpurple, Pidgin, or Finch developer) are expected + to use a plugin ID that follows a specific format. This format + categorizes plugins and makes duplicate IDs highly unlikely. @section Format The basic format of a plugin ID is as follows: @@ -15,27 +15,79 @@ The @em type indicator specifies the type of plugin. This must be one of the following: - - core - Core plugin, capable of being loaded in any program using - libpurple. It must not use any UI-specific code. - - prpl - Protocol plugin, providing additional protocols to - connect to. - - lopl - Loader plugin, which loads scripts as plugins (like Perl - or TCL). - - gtk - GTK+ 2.x plugin. It may use GTK+ code, but cannot use any - window toolkit code (such as X11 or Win32). - - gtk-x11 - GTK+ 2.x plugin using X11 code. - - gtk-win32 - GTK+ 2.x plugin using Win32 code. - - qpe - Gaim for Qtopia plugin. + - core - A core libpurple plugin, capable of being loaded in any + program using libpurple. Core plugins may not contain any + UI-specific code. + - prpl - A protocol plugin. This is a special type of core plugin, + which provides libpurple the ability to connect to + another IM or chat network. + - lopl - A loader plugin, which loads scripts as plugins. Perl and + Tcl plugins are made possible by loader plugins. + - gtk - A GTK+ 2.x (a.k.a. Pidgin) plugin. These plugins may use + GTK+ code, but may not use window toolkit code, such as + X11, Win32, Cocoa, or Carbon. + - gtk-x11 - A GTK+ 2.x plugin that uses X11 code. These plugins may + use both GTK+ code and X11 code, allowing to hook into + features specific to X11. + - gtk-win32 - A GTK+ plugin that uses Win32 code. These plugins may use + both GTK+ code and Win32 code, allowing to hook into + features available on Windows. + - gnt - A GNT (a.k.a. Finch) plugin. These plugins may use GNT code. + - qpe - A plugin for the (now-abandoned) Qutopia user interface. + + The @em username must be a unique identifier for you. It + @em should be your http://developer.pidgin.im Trac user ID. Failing that, you + could use your SourceForge user ID or your Freenode IRC nickname, if you + have either. The http://developer.pidgin.im Trac user ID is preferred. + Do @em not leave this field blank! + + The @em pluginname is the name of your plugin. It is usually all + lowercase letters and matches the static plugin ID (the first argument to + the PURPLE_INIT_PLUGIN() macro call), although it can be anything you + like. Do @em not include version information in the plugin ID--the + #PurplePluginInfo structure already has a field for this. + + @section nospaces One Last Rule for Plugin IDs + + The last rule of plugin IDs is the most important of all. Plugin IDs may + @em NOT contain spaces. If you need a space, use another hyphen (-). - The @em username must be a unique identifier for that person. It - @em should be your SourceForge ID. Do @em not leave this field - blank. + @section exceptions Exceptions to the Rule + + As with any rule there are exceptions. If you browse through the source + tree you will see that the plugins we distribute with the Pidgin source + do not contain a username field. This is because while one developer may + have written each specific plugin, the plugins are maintained + collectively by the entire development team. This lack of a username + field is also an indicator that the plugin is one of our plugins and not + a third-party plugin. + + Another exception to the rule is the Purple Plugin + Pack. All plugins whose lives started in the Purple Plugin Pack use + "plugin_pack" for the username field to indicate origination in + the Purple Plugin Pack. - The @em pluginname is the name of your plugin. It can be whatever you like, - though it's common to keep it all lowercase. Do not use spaces! If you - want a space, use a '-'. Please do not put a version indicator in the ID. - The PurplePlugin structure already has a field for this. + These two exceptions are mentioned here for completeness. We don't + encourage breaking the conventions set forth by the rules outlined above. + + @section examples Examples of Well-Chosen Plugin IDs + + The following is a list of well-chosen Plugin IDs listing a few good examples. + - "gtk-amc_grim-guifications" - This is the plugin ID for the + Guifications 2.x plugin. + - "gtk-rlaager-album" - This is the plugin ID for the Album + plugin, which is now part of the + Purple Plugin Pack. Its ID follows the + rules because its life started prior + to its inclusion in the Plugin Pack. + - "core-rlaager-irchelper" - This is the plugin ID for the IRC + Helper plugin, which is now part + of the Purple Plugin Pack. Its ID + follows the rules because its + life started prior to its + inclusion in the Plugin Pack. @section plugin-db Plugin Database Although it doesn't exist yet, in time there will be a plugin database @@ -45,4 +97,4 @@ */ -// vim: syntax=c tw=75 et +// vim: syntax=c.doxygen tw=75 et diff -r e0ce7124d2d4 -r 2a6ef74f5a4e doc/plugin-signals.dox --- a/doc/plugin-signals.dox Wed Oct 10 01:01:21 2007 +0000 +++ b/doc/plugin-signals.dox Wed Oct 10 01:06:16 2007 +0000 @@ -5,6 +5,8 @@ @signal plugin-unload @endsignals + @see plugin.h +
@signaldef plugin-load @@ -26,4 +28,4 @@ @endsignaldef */ -// vim: syntax=c tw=75 et +// vim: syntax=c.doxygen tw=75 et diff -r e0ce7124d2d4 -r 2a6ef74f5a4e doc/savedstatus-signals.dox --- a/doc/savedstatus-signals.dox Wed Oct 10 01:01:21 2007 +0000 +++ b/doc/savedstatus-signals.dox Wed Oct 10 01:06:16 2007 +0000 @@ -4,6 +4,8 @@ @signal savedstatus-changed @endsignals + @see savedstatus.h +
@signaldef savedstatus-changed @@ -15,4 +17,4 @@ @endsignaldef */ -// vim: syntax=c tw=75 et +// vim: syntax=c.doxygen tw=75 et diff -r e0ce7124d2d4 -r 2a6ef74f5a4e doc/sound-signals.dox --- a/doc/sound-signals.dox Wed Oct 10 01:01:21 2007 +0000 +++ b/doc/sound-signals.dox Wed Oct 10 01:06:16 2007 +0000 @@ -4,6 +4,8 @@ @signal playing-sound-event @endsignals + @see sound.h +
@signaldef playing-sound-event @@ -18,4 +20,4 @@ @endsignaldef */ -// vim: syntax=c tw=75 et +// vim: syntax=c.doxygen tw=75 et diff -r e0ce7124d2d4 -r 2a6ef74f5a4e doc/xfer-signals.dox --- a/doc/xfer-signals.dox Wed Oct 10 01:01:21 2007 +0000 +++ b/doc/xfer-signals.dox Wed Oct 10 01:06:16 2007 +0000 @@ -12,6 +12,8 @@ @signal file-send-complete @endsignals + @see ft.h +
@signaldef file-recv-accept @@ -109,4 +111,4 @@ @endsignaldef */ -// vim: syntax=c tw=75 et +// vim: syntax=c.doxygen tw=75 et diff -r e0ce7124d2d4 -r 2a6ef74f5a4e libpurple/plugins/log_reader.c --- a/libpurple/plugins/log_reader.c Wed Oct 10 01:01:21 2007 +0000 +++ b/libpurple/plugins/log_reader.c Wed Oct 10 01:06:16 2007 +0000 @@ -232,7 +232,6 @@ struct adium_logger_data *data; GError *error = NULL; gchar *read = NULL; - gsize length; /* XXX: TODO: We probably want to set PURPLE_LOG_READ_NO_NEWLINE * XXX: TODO: for HTML logs. */ @@ -246,8 +245,9 @@ g_return_val_if_fail(data->path != NULL, g_strdup("")); purple_debug_info("Adium log read", "Reading %s\n", data->path); - if (!g_file_get_contents(data->path, &read, &length, &error)) { - purple_debug_error("Adium log read", "Error reading log\n"); + if (!g_file_get_contents(data->path, &read, NULL, &error)) { + purple_debug_error("Adium log read", "Error reading log: %s\n", + (error && error->message) ? error->message : "Unknown error"); if (error) g_error_free(error); return g_strdup(""); @@ -1808,8 +1808,10 @@ error = NULL; if (!g_file_get_contents(path, &contents, NULL, &error)) { purple_debug_error("QIP logger", - "Couldn't read file %s: %s \n", path, error->message); - g_error_free(error); + "Couldn't read file %s: %s \n", path, + (error && error->message) ? error->message : "Unknown error"); + if (error) + g_error_free(error); g_free(path); return list; } @@ -1937,13 +1939,11 @@ g_return_val_if_fail(data->path != NULL, g_strdup("")); g_return_val_if_fail(data->length > 0, g_strdup("")); - error = NULL; - - contents = g_malloc(data->length + 2); - file = g_fopen(data->path, "rb"); g_return_val_if_fail(file != NULL, g_strdup("")); - + + contents = g_malloc(data->length + 2); + fseek(file, data->offset, SEEK_SET); fread(contents, data->length, 1, file); fclose(file); @@ -1955,8 +1955,10 @@ error = NULL; if (!(utf8_string = g_convert(contents, -1, "UTF-8", "Cp1251", NULL, NULL, &error))) { purple_debug_error("QIP logger", - "Couldn't convert file %s to UTF-8: %s\n", data->path, error->message); - g_error_free(error); + "Couldn't convert file %s to UTF-8: %s\n", data->path, + (error && error->message) ? error->message : "Unknown error"); + if (error) + g_error_free(error); g_free(contents); return g_strdup(""); } @@ -2022,7 +2024,7 @@ g_string_append(formatted, " "); if (is_in_message) { - if (buddy_name != NULL && buddy->alias) { + if (buddy_name != NULL && buddy != NULL && buddy->alias) { g_string_append_printf(formatted, "" "%s: ", buddy->alias); @@ -2052,7 +2054,9 @@ g_string_append(formatted, line); g_string_append(formatted, "
"); } - line = ++c; + + if (c) + line = ++c; } } g_free(contents); @@ -2151,18 +2155,18 @@ /* Calculate default Messenger Plus! log directory. */ #ifdef _WIN32 + path = NULL; folder = wpurple_get_special_folder(CSIDL_PERSONAL); if (folder) { path = g_build_filename(folder, "My Chat Logs", NULL); g_free(folder); - } else - path = g_strdup(""); + } #else path = g_build_filename(PURPLE_LOG_READER_WINDOWS_MOUNT_POINT, "Documents and Settings", g_get_user_name(), "My Documents", "My Chat Logs", NULL); #endif - purple_prefs_add_string("/plugins/core/log_reader/messenger_plus/log_directory", path); + purple_prefs_add_string("/plugins/core/log_reader/messenger_plus/log_directory", path ? path : ""); g_free(path); @@ -2171,18 +2175,18 @@ /* Calculate default MSN message history directory. */ #ifdef _WIN32 + path = NULL; folder = wpurple_get_special_folder(CSIDL_PERSONAL); if (folder) { path = g_build_filename(folder, "My Received Files", NULL); g_free(folder); - } else - path = g_strdup(""); + } #else path = g_build_filename(PURPLE_LOG_READER_WINDOWS_MOUNT_POINT, "Documents and Settings", g_get_user_name(), "My Documents", "My Received Files", NULL); #endif - purple_prefs_add_string("/plugins/core/log_reader/msn/log_directory", path); + purple_prefs_add_string("/plugins/core/log_reader/msn/log_directory", path ? path : ""); g_free(path); @@ -2261,22 +2265,22 @@ g_key_file_free(key_file); } #else /* !GLIB_CHECK_VERSION(2,6,0) */ - gsize length; gchar *contents = NULL; purple_debug_info("Trillian talk.ini read", - "Reading %s\n", path); - if (!g_file_get_contents(path, &contents, &length, &error)) { + "Reading %s\n", path); + if (!g_file_get_contents(path, &contents, NULL, &error)) { purple_debug_error("Trillian talk.ini read", - "Error reading talk.ini\n"); + "Error reading talk.ini: %s\n", + (error && error->message) ? error->message : "Unknown error"); if (error) g_error_free(error); - g_free(path); } else { - char *line = contents; - while (*contents) { - if (*contents == '\n') { - *contents = '\0'; + char *cursor, *line; + line = cursor = contents; + while (*cursor) { + if (*cursor == '\n') { + *cursor = '\0'; /* XXX: This assumes the first Directory key is under [Logging]. */ if (purple_str_has_prefix(line, "Directory=")) { @@ -2288,25 +2292,29 @@ found = TRUE; } - contents++; - line = contents; + cursor++; + line = cursor; } else - contents++; + cursor++; } - g_free(path); g_free(contents); } + g_free(path); #endif /* !GTK_CHECK_VERSION(2,6,0) */ } /* path */ if (!found) { + path = NULL; folder = wpurple_get_special_folder(CSIDL_PROGRAM_FILES); if (folder) { path = g_build_filename(folder, "Trillian", "users", "default", "logs", NULL); g_free(folder); - } else - path = g_strdup(""); + } + + purple_prefs_add_string( + "/plugins/core/log_reader/trillian/log_directory", path ? path : ""); + g_free(path); } #else /* !defined(_WIN32) */ /* TODO: At some point, this could attempt to parse talk.ini @@ -2317,28 +2325,27 @@ path = g_build_filename(PURPLE_LOG_READER_WINDOWS_MOUNT_POINT, "Program Files", "Trillian", "users", "default", "logs", NULL); + purple_prefs_add_string( + "/plugins/core/log_reader/trillian/log_directory", path); + g_free(path); #endif - /*XXX: Why do we even bother allocating it ? */ - g_free(path); - - /* Add QIP log directory preference. */ purple_prefs_add_none("/plugins/core/log_reader/qip"); /* Calculate default QIP log directory. */ #ifdef _WIN32 + path = NULL; folder = wpurple_get_special_folder(CSIDL_PROGRAM_FILES); if (folder) { path = g_build_filename(folder, "QIP", "Users", NULL); g_free(folder); - } else - path = g_strdup(""); + } #else path = g_build_filename(PURPLE_LOG_READER_WINDOWS_MOUNT_POINT, "Program Files", "QIP", "Users", NULL); #endif - purple_prefs_add_string("/plugins/core/log_reader/qip/log_directory", path); + purple_prefs_add_string("/plugins/core/log_reader/qip/log_directory", path ? path : ""); g_free(path); } diff -r e0ce7124d2d4 -r 2a6ef74f5a4e libpurple/plugins/ssl/ssl-gnutls.c --- a/libpurple/plugins/ssl/ssl-gnutls.c Wed Oct 10 01:01:21 2007 +0000 +++ b/libpurple/plugins/ssl/ssl-gnutls.c Wed Oct 10 01:06:16 2007 +0000 @@ -884,7 +884,7 @@ gnutls_x509_crt crt_dat; /* GnuTLS time functions return this on error */ const time_t errval = (time_t) (-1); - + gboolean success = TRUE; g_return_val_if_fail(crt, FALSE); g_return_val_if_fail(crt->scheme == &x509_gnutls, FALSE); @@ -893,16 +893,16 @@ if (activation) { *activation = gnutls_x509_crt_get_activation_time(crt_dat); + if (*activation == errval) + success = FALSE; } if (expiration) { *expiration = gnutls_x509_crt_get_expiration_time(crt_dat); + if (*expiration == errval) + success = FALSE; } - if (*activation == errval || *expiration == errval) { - return FALSE; - } - - return TRUE; + return success; } /* X.509 certificate operations provided by this plugin */ diff -r e0ce7124d2d4 -r 2a6ef74f5a4e libpurple/plugins/ssl/ssl-nss.c --- a/libpurple/plugins/ssl/ssl-nss.c Wed Oct 10 01:01:21 2007 +0000 +++ b/libpurple/plugins/ssl/ssl-nss.c Wed Oct 10 01:06:16 2007 +0000 @@ -386,6 +386,7 @@ static GList * ssl_nss_peer_certs(PurpleSslConnection *gsc) { +#if 0 PurpleSslNssData *nss_data = PURPLE_SSL_NSS_DATA(gsc); CERTCertificate *cert; /* @@ -397,6 +398,10 @@ /* TODO: this is a blind guess */ cert = SSL_PeerCertificate(nss_data->fd); + if (cert) + CERT_DestroyCertificate(cert); +#endif + return NULL; @@ -430,11 +435,12 @@ filename); /* Load the raw data up */ - g_return_val_if_fail( - g_file_get_contents(filename, - &rawcert, &len, - NULL ), - NULL); + if (!g_file_get_contents(filename, + &rawcert, &len, + NULL)) { + purple_debug_error("nss/x509", "Unable to read certificate file.\n"); + return NULL; + } /* Decode the certificate */ crt_dat = CERT_DecodeCertFromPackage(rawcert, len); diff -r e0ce7124d2d4 -r 2a6ef74f5a4e libpurple/protocols/bonjour/bonjour.c --- a/libpurple/protocols/bonjour/bonjour.c Wed Oct 10 01:01:21 2007 +0000 +++ b/libpurple/protocols/bonjour/bonjour.c Wed Oct 10 01:06:16 2007 +0000 @@ -188,6 +188,8 @@ if (bonjour_group != NULL) purple_blist_remove_group(bonjour_group); + g_free(bd); + connection->proto_data = NULL; } static const char * @@ -581,7 +583,7 @@ fullname = g_utf16_to_utf8(username, -1, NULL, NULL, NULL); } - g_idle_add(_set_default_name_cb, fullname); + purple_timeout_add(0, _set_default_name_cb, fullname); return NULL; } diff -r e0ce7124d2d4 -r 2a6ef74f5a4e libpurple/protocols/bonjour/parser.c --- a/libpurple/protocols/bonjour/parser.c Wed Oct 10 01:01:21 2007 +0000 +++ b/libpurple/protocols/bonjour/parser.c Wed Oct 10 01:06:16 2007 +0000 @@ -64,7 +64,7 @@ char *attrib_ns = NULL; if (attributes[i+2]) { - attrib_ns = g_strdup((char*)attributes[i+2]);; + attrib_ns = g_strdup((char*)attributes[i+2]); } memcpy(attrib, attributes[i+3], attrib_len); @@ -101,7 +101,7 @@ if(!xmlStrcmp(element_name, (xmlChar*) "stream")) { /* Asynchronously close the conversation to prevent bonjour_parser_setup() * being called from within this context */ - g_idle_add(_async_bonjour_jabber_stream_ended_cb, pb); + purple_timeout_add(0, _async_bonjour_jabber_stream_ended_cb, pb); } return; } diff -r e0ce7124d2d4 -r 2a6ef74f5a4e libpurple/protocols/irc/irc.h --- a/libpurple/protocols/irc/irc.h Wed Oct 10 01:01:21 2007 +0000 +++ b/libpurple/protocols/irc/irc.h Wed Oct 10 01:06:16 2007 +0000 @@ -99,6 +99,8 @@ int irc_send(struct irc_conn *irc, const char *buf); gboolean irc_blist_timeout(struct irc_conn *irc); +char *irc_escape_privmsg(const char *text, gssize length); + char *irc_mirc2html(const char *string); char *irc_mirc2txt(const char *string); diff -r e0ce7124d2d4 -r 2a6ef74f5a4e libpurple/protocols/irc/msgs.c --- a/libpurple/protocols/irc/msgs.c Wed Oct 10 01:01:21 2007 +0000 +++ b/libpurple/protocols/irc/msgs.c Wed Oct 10 01:06:16 2007 +0000 @@ -1066,7 +1066,7 @@ return; } - msg = g_markup_escape_text(tmp, -1); + msg = irc_escape_privmsg(tmp, -1); g_free(tmp); tmp = irc_mirc2html(msg); diff -r e0ce7124d2d4 -r 2a6ef74f5a4e libpurple/protocols/irc/parse.c --- a/libpurple/protocols/irc/parse.c Wed Oct 10 01:01:21 2007 +0000 +++ b/libpurple/protocols/irc/parse.c Wed Oct 10 01:06:16 2007 +0000 @@ -281,6 +281,61 @@ return purple_utf8_salvage(string); } +/* This function is shamelessly stolen from glib--it is an old version of the + * private function append_escaped_text, used by g_markup_escape_text, whose + * behavior changed in glib 2.12. */ +static void irc_append_escaped_text(GString *str, const char *text, gssize length) +{ + const char *p = text; + const char *end = text + length; + const char *next = NULL; + + while(p != end) { + next = g_utf8_next_char(p); + + switch(*p) { + case '&': + g_string_append(str, "&"); + break; + case '<': + g_string_append(str, "<"); + break; + case '>': + g_string_append(str, ">"); + break; + case '\'': + g_string_append(str, "'"); + break; + case '"': + g_string_append(str, """); + break; + default: + g_string_append_len(str, p, next - p); + break; + } + + p = next; + } +} + +/* This function is shamelessly stolen from glib--it is an old version of the + * function g_markup_escape_text, whose behavior changed in glib 2.12. */ +char *irc_escape_privmsg(const char *text, gssize length) +{ + GString *str; + + g_return_val_if_fail(text != NULL, NULL); + + if(length < 0) + length = strlen(text); + + str = g_string_sized_new(length); + + irc_append_escaped_text(str, text, length); + + return g_string_free(str, FALSE); +} + /* XXX tag closings are not necessarily correctly nested here! If we * get a ^O or reach the end of the string and there are open * tags, they are closed in a fixed order ... this means, for diff -r e0ce7124d2d4 -r 2a6ef74f5a4e libpurple/protocols/jabber/chat.c --- a/libpurple/protocols/jabber/chat.c Wed Oct 10 01:01:21 2007 +0000 +++ b/libpurple/protocols/jabber/chat.c Wed Oct 10 01:06:16 2007 +0000 @@ -964,7 +964,7 @@ static void jabber_chat_disco_traffic_cb(JabberStream *js, xmlnode *packet, gpointer data) { JabberChat *chat; - xmlnode *query; + /*xmlnode *query;*/ int id = GPOINTER_TO_INT(data); if(!(chat = jabber_chat_find_by_id(js, id))) @@ -974,6 +974,8 @@ * support this request */ chat->xhtml = TRUE; + /* disabling this until more MUC servers support + * announcing this if(xmlnode_get_child(packet, "error")) { return; } @@ -981,8 +983,6 @@ if(!(query = xmlnode_get_child(packet, "query"))) return; - /* disabling this until more MUC servers support - * announcing this chat->xhtml = FALSE; for(x = xmlnode_get_child(query, "feature"); x; x = xmlnode_get_next_twin(x)) { diff -r e0ce7124d2d4 -r 2a6ef74f5a4e libpurple/protocols/jabber/google.c --- a/libpurple/protocols/jabber/google.c Wed Oct 10 01:01:21 2007 +0000 +++ b/libpurple/protocols/jabber/google.c Wed Oct 10 01:06:16 2007 +0000 @@ -110,7 +110,7 @@ tos[i] = (to_name != NULL ? to_name : ""); froms[i] = (from != NULL ? from : ""); subjects[i] = (subject != NULL ? subject : g_strdup("")); - urls[i] = (url != NULL ? url : ""); + urls[i] = url; tid = xmlnode_get_attrib(message, "tid"); if (tid && diff -r e0ce7124d2d4 -r 2a6ef74f5a4e libpurple/protocols/jabber/iq.c --- a/libpurple/protocols/jabber/iq.c Wed Oct 10 01:01:21 2007 +0000 +++ b/libpurple/protocols/jabber/iq.c Wed Oct 10 01:06:16 2007 +0000 @@ -248,7 +248,6 @@ JabberIq *iq; const char *type, *from, *id; xmlnode *query; - char *os = NULL; type = xmlnode_get_attrib(packet, "type"); @@ -256,6 +255,7 @@ GHashTable *ui_info; const char *ui_name = NULL, *ui_version = NULL; #if 0 + char *os = NULL; if(!purple_prefs_get_bool("/plugins/prpl/jabber/hide_os")) { struct utsname osinfo; @@ -290,10 +290,12 @@ xmlnode_insert_data(xmlnode_new_child(query, "version"), VERSION, -1); } +#if 0 if(os) { xmlnode_insert_data(xmlnode_new_child(query, "os"), os, -1); g_free(os); } +#endif jabber_iq_send(iq); } diff -r e0ce7124d2d4 -r 2a6ef74f5a4e libpurple/protocols/jabber/jabber.c --- a/libpurple/protocols/jabber/jabber.c Wed Oct 10 01:01:21 2007 +0000 +++ b/libpurple/protocols/jabber/jabber.c Wed Oct 10 01:06:16 2007 +0000 @@ -1914,7 +1914,7 @@ text = _("Authentication Failure"); } } else if(!strcmp(packet->name, "stream:error") || - (!strcmp(packet->name, "error") && + (!strcmp(packet->name, "error") && xmlns && !strcmp(xmlns, "http://etherx.jabber.org/streams"))) { if(xmlnode_get_child(packet, "bad-format")) { text = _("Bad Format"); @@ -2189,55 +2189,67 @@ return PURPLE_CMD_RET_OK; } +static gboolean _jabber_send_buzz(JabberStream *js, const char *username, char **error) { + + JabberBuddy *jb; + JabberBuddyResource *jbr; + GList *iter; + + if(!username) + return FALSE; + + jb = jabber_buddy_find(js, username, FALSE); + if(!jb) { + *error = g_strdup_printf(_("Unable to buzz, because there is nothing known about user %s."), username); + return FALSE; + } + + jbr = jabber_buddy_find_resource(jb, NULL); + if(!jbr) { + *error = g_strdup_printf(_("Unable to buzz, because user %s might be offline."), username); + return FALSE; + } + + if(!jbr->caps) { + *error = g_strdup_printf(_("Unable to buzz, because there is nothing known about user %s."), username); + return FALSE; + } + + for(iter = jbr->caps->features; iter; iter = g_list_next(iter)) { + if(!strcmp(iter->data, "http://www.xmpp.org/extensions/xep-0224.html#ns")) { + xmlnode *buzz, *msg = xmlnode_new("message"); + gchar *to; + + to = g_strdup_printf("%s/%s", username, jbr->name); + xmlnode_set_attrib(msg, "to", to); + g_free(to); + + /* avoid offline storage */ + xmlnode_set_attrib(msg, "type", "headline"); + + buzz = xmlnode_new_child(msg, "attention"); + xmlnode_set_namespace(buzz, "http://www.xmpp.org/extensions/xep-0224.html#ns"); + + jabber_send(js, msg); + xmlnode_free(msg); + + return TRUE; + } + } + + *error = g_strdup_printf(_("Unable to buzz, because the user %s does not support it."), username); + return FALSE; +} + static PurpleCmdRet jabber_cmd_buzz(PurpleConversation *conv, const char *cmd, char **args, char **error, void *data) { JabberStream *js = conv->account->gc->proto_data; - xmlnode *msg, *buzz; - JabberBuddy *jb; - JabberBuddyResource *jbr; - char *to; - GList *iter; if(!args || !args[0]) return PURPLE_CMD_RET_FAILED; - - jb = jabber_buddy_find(js, args[0], FALSE); - if(!jb) { - *error = g_strdup_printf(_("Unable to buzz, because there is nothing known about user %s."), args[0]); - return PURPLE_CMD_RET_FAILED; - } - - jbr = jabber_buddy_find_resource(jb, NULL); - if(!jbr) { - *error = g_strdup_printf(_("Unable to buzz, because user %s might be offline."), args[0]); - return PURPLE_CMD_RET_FAILED; - } - if(!jbr->caps) { - *error = g_strdup_printf(_("Unable to buzz, because there is nothing known about user %s."), args[0]); - return PURPLE_CMD_RET_FAILED; - } - for(iter = jbr->caps->features; iter; iter = g_list_next(iter)) { - if(!strcmp(iter->data, "http://www.xmpp.org/extensions/xep-0224.html#ns")) { - msg = xmlnode_new("message"); - to = g_strdup_printf("%s/%s", args[0], jbr->name); - xmlnode_set_attrib(msg,"to",to); - g_free(to); - - /* avoid offline storage */ - xmlnode_set_attrib(msg,"type","headline"); - - buzz = xmlnode_new_child(msg,"attention"); - xmlnode_set_namespace(buzz,"http://www.xmpp.org/extensions/xep-0224.html#ns"); - - jabber_send(js,msg); - xmlnode_free(msg); - - return PURPLE_CMD_RET_OK; - } - } - *error = g_strdup_printf(_("Unable to buzz, because the user %s does not support it."), args[0]); - return PURPLE_CMD_RET_FAILED; + + return _jabber_send_buzz(js, args[0], error) ? PURPLE_CMD_RET_OK : PURPLE_CMD_RET_FAILED; } GList *jabber_attention_types(PurpleAccount *account) @@ -2258,23 +2270,16 @@ gboolean jabber_send_attention(PurpleConnection *gc, const char *username, guint code) { - PurpleConversation *conv; - char *error; - char *args[1]; - PurpleCmdRet ret; - - conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, username, gc->account); - - args[0] = (char *)username; + JabberStream *js = gc->proto_data; + gchar *error = NULL; - ret = jabber_cmd_buzz(conv, "buzz", args, &error, NULL); - - if (ret == PURPLE_CMD_RET_FAILED) { + if (!_jabber_send_buzz(js, username, &error)) { purple_debug_error("jabber", "jabber_send_attention: jabber_cmd_buzz failed with error: %s\n", error ? error : "(NULL)"); + g_free(error); return FALSE; - } else { - return TRUE; } + + return TRUE; } diff -r e0ce7124d2d4 -r 2a6ef74f5a4e libpurple/protocols/jabber/parser.c --- a/libpurple/protocols/jabber/parser.c Wed Oct 10 01:01:21 2007 +0000 +++ b/libpurple/protocols/jabber/parser.c Wed Oct 10 01:06:16 2007 +0000 @@ -80,7 +80,7 @@ char *attrib_ns = NULL; if (attributes[i+2]) { - attrib_ns = g_strdup((char*)attributes[i+2]);; + attrib_ns = g_strdup((char*)attributes[i+2]); } memcpy(attrib, attributes[i+3], attrib_len); diff -r e0ce7124d2d4 -r 2a6ef74f5a4e libpurple/protocols/jabber/roster.c --- a/libpurple/protocols/jabber/roster.c Wed Oct 10 01:01:21 2007 +0000 +++ b/libpurple/protocols/jabber/roster.c Wed Oct 10 01:06:16 2007 +0000 @@ -67,8 +67,10 @@ if(!groups) { if(!buddies) g2 = g_slist_append(g2, g_strdup(_("Buddies"))); - else + else { + g_slist_free(buddies); return; + } } my_bare_jid = g_strdup_printf("%s@%s", js->user->node, js->user->domain); @@ -229,6 +231,11 @@ remove_purple_buddies(js, jid); } else { GSList *groups = NULL; + + if (js->server_caps & JABBER_CAP_GOOGLE_ROSTER) + if (!jabber_google_roster_incoming(js, item)) + continue; + for(group = xmlnode_get_child(item, "group"); group; group = xmlnode_get_next_twin(group)) { char *group_name; @@ -237,10 +244,9 @@ if (g_slist_find_custom(groups, group_name, (GCompareFunc)purple_utf8_strcasecmp) == NULL) groups = g_slist_append(groups, group_name); + else + g_free(group_name); } - if (js->server_caps & JABBER_CAP_GOOGLE_ROSTER) - if (!jabber_google_roster_incoming(js, item)) - continue; add_purple_buddies_to_groups(js, jid, name, groups); } } @@ -263,6 +269,9 @@ JabberIq *iq; xmlnode *query, *item, *group; + if(!(b = purple_find_buddy(js->gc->account, name))) + return; + if(grps) { groups = grps; } else { @@ -277,9 +286,6 @@ } } - if(!(b = purple_find_buddy(js->gc->account, name))) - return; - iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:roster"); query = xmlnode_get_child(iq->node, "query"); @@ -397,12 +403,12 @@ void jabber_roster_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) { GSList *buddies = purple_find_buddies(gc->account, buddy->name); - GSList *groups = NULL; buddies = g_slist_remove(buddies, buddy); if(buddies != NULL) { PurpleBuddy *tmpbuddy; PurpleGroup *tmpgroup; + GSList *groups = NULL; while(buddies) { tmpbuddy = buddies->data; @@ -412,6 +418,7 @@ } jabber_roster_update(gc->proto_data, buddy->name, groups); + g_slist_free(groups); } else { JabberIq *iq = jabber_iq_new_query(gc->proto_data, JABBER_IQ_SET, "jabber:iq:roster"); @@ -423,9 +430,4 @@ jabber_iq_send(iq); } - - if(buddies) - g_slist_free(buddies); - if(groups) - g_slist_free(groups); } diff -r e0ce7124d2d4 -r 2a6ef74f5a4e libpurple/protocols/jabber/usermood.c --- a/libpurple/protocols/jabber/usermood.c Wed Oct 10 01:01:21 2007 +0000 +++ b/libpurple/protocols/jabber/usermood.c Wed Oct 10 01:06:16 2007 +0000 @@ -26,6 +26,7 @@ #include #include "internal.h" #include "request.h" +#include "debug.h" static const char *moodstrings[] = { "afraid", @@ -145,9 +146,26 @@ } static void do_mood_set_from_fields(PurpleConnection *gc, PurpleRequestFields *fields) { - JabberStream *js = gc->proto_data; - - jabber_mood_set(js, moodstrings[purple_request_fields_get_choice(fields, "mood")], purple_request_fields_get_string(fields, "text")); + JabberStream *js; + int max_mood_idx; + int selected_mood = purple_request_fields_get_choice(fields, "mood"); + + if (!PURPLE_CONNECTION_IS_VALID(gc)) { + purple_debug_error("jabber", "Unable to set mood; account offline.\n"); + return; + } + + js = gc->proto_data; + + /* This is ugly, but protects us from unexpected values. */ + for (max_mood_idx = 0; moodstrings[max_mood_idx]; max_mood_idx++); + + if (selected_mood < 0 || selected_mood >= max_mood_idx) { + purple_debug_error("jabber", "Invalid mood index (%d) selected.\n", selected_mood); + return; + } + + jabber_mood_set(js, moodstrings[selected_mood], purple_request_fields_get_string(fields, "text")); } static void do_mood_set_mood(PurplePluginAction *action) { diff -r e0ce7124d2d4 -r 2a6ef74f5a4e libpurple/protocols/msn/contact.c --- a/libpurple/protocols/msn/contact.c Wed Oct 10 01:01:21 2007 +0000 +++ b/libpurple/protocols/msn/contact.c Wed Oct 10 01:06:16 2007 +0000 @@ -1177,7 +1177,7 @@ purple_debug_warning("MSN CL", "Unable to retrieve user %s from the userlist!\n", passport); } - if (user->uid != NULL) { + if (user != NULL && user->uid != NULL) { contact_xml = g_strdup_printf(MSN_CONTACT_ID_XML, user->uid); } else { contact_xml = g_strdup_printf(MSN_CONTACT_XML, passport); diff -r e0ce7124d2d4 -r 2a6ef74f5a4e libpurple/protocols/msn/msn.c --- a/libpurple/protocols/msn/msn.c Wed Oct 10 01:01:21 2007 +0000 +++ b/libpurple/protocols/msn/msn.c Wed Oct 10 01:06:16 2007 +0000 @@ -943,7 +943,7 @@ imdata->msg = body_str; imdata->flags = flags; imdata->when = time(NULL); - g_idle_add(msn_send_me_im, imdata); + purple_timeout_add(0, msn_send_me_im, imdata); } msn_message_destroy(msg); @@ -1103,7 +1103,7 @@ userlist = session->userlist; who = msn_normalize(gc->account, buddy->name); - purple_debug_info("MSN","Add user:%s to group:%s\n", who, group->name); + purple_debug_info("MSN","Add user:%s to group:%s\n", who, (group && group->name) ? group->name : "(null)"); if (!session->logged_in) { #if 0 diff -r e0ce7124d2d4 -r 2a6ef74f5a4e libpurple/protocols/msn/notification.c --- a/libpurple/protocols/msn/notification.c Wed Oct 10 01:01:21 2007 +0000 +++ b/libpurple/protocols/msn/notification.c Wed Oct 10 01:06:16 2007 +0000 @@ -230,11 +230,9 @@ { MsnSession *session; PurpleAccount *account; - PurpleConnection *gc; session = cmdproc->session; account = session->account; - gc = purple_account_get_connection(account); if (!g_ascii_strcasecmp(cmd->params[1], "OK")) { @@ -450,7 +448,7 @@ const char *passport; const char *content_type; - purple_debug_info("MSNP14","Process UBM payload:%s\n",payload); + purple_debug_info("MSNP14","Process UBM payload:%.*s\n", len, payload); msg = msn_message_new_from_cmd(cmdproc->session, cmd); msn_message_parse_payload(msg, payload, len,MSG_LINE_DEM,MSG_BODY_DEM); @@ -533,7 +531,7 @@ }else{ g_return_if_fail(cmd->payload_cb != NULL); - purple_debug_info("MSNP14","UBM payload:{%s}\n",cmd->payload); + purple_debug_info("MSNP14","UBM payload:{%.*s}\n", cmd->payload_len, cmd->payload); ubm_cmd_post(cmdproc, cmd, cmd->payload, cmd->payload_len); } } @@ -1616,7 +1614,6 @@ { MsnSession *session; PurpleAccount *account; - PurpleConnection *gc; MsnUser *user; const char *passport; char *psm_str, *currentmedia_str, *str; @@ -1626,7 +1623,6 @@ session = cmdproc->session; account = session->account; - gc = purple_account_get_connection(account); passport = cmd->params[0]; user = msn_userlist_find_user(session->userlist, passport); diff -r e0ce7124d2d4 -r 2a6ef74f5a4e libpurple/protocols/msn/oim.c --- a/libpurple/protocols/msn/oim.c Wed Oct 10 01:01:21 2007 +0000 +++ b/libpurple/protocols/msn/oim.c Wed Oct 10 01:06:16 2007 +0000 @@ -608,8 +608,9 @@ purple_debug_info("MSN OIM:OIM", "%s", xmlmsg); node = xmlnode_from_str(xmlmsg, strlen(xmlmsg)); - if (strcmp(node->name, "MD") != 0) { - xmlnode_free(node); + if (!node || !node->name || strcmp(node->name, "MD") != 0) { + if (node) + xmlnode_free(node); return; } diff -r e0ce7124d2d4 -r 2a6ef74f5a4e libpurple/protocols/msn/soap.c --- a/libpurple/protocols/msn/soap.c Wed Oct 10 01:01:21 2007 +0000 +++ b/libpurple/protocols/msn/soap.c Wed Oct 10 01:06:16 2007 +0000 @@ -131,6 +131,7 @@ MsnSoapSslErrorCbFunction error_cb) { purple_debug_misc("MSN SOAP","Initializing SOAP connection\n"); + g_free(soapconn->login_host); soapconn->login_host = g_strdup(host); soapconn->ssl_conn = ssl; soapconn->connect_cb = connect_cb; @@ -204,11 +205,9 @@ void msn_soap_destroy(MsnSoapConn *soapconn) { - if(soapconn->login_host) - g_free(soapconn->login_host); + g_free(soapconn->login_host); - if(soapconn->login_path) - g_free(soapconn->login_path); + g_free(soapconn->login_path); /*remove the write handler*/ if (soapconn->output_handler > 0){ diff -r e0ce7124d2d4 -r 2a6ef74f5a4e libpurple/protocols/msn/userlist.c --- a/libpurple/protocols/msn/userlist.c Wed Oct 10 01:01:21 2007 +0000 +++ b/libpurple/protocols/msn/userlist.c Wed Oct 10 01:06:16 2007 +0000 @@ -227,11 +227,8 @@ } else if (list_id == MSN_LIST_RL) { - PurpleConnection *gc; PurpleConversation *convo; - gc = purple_account_get_connection(account); - purple_debug_info("msn", "%s has added you to his or her buddy list.\n", passport); diff -r e0ce7124d2d4 -r 2a6ef74f5a4e libpurple/protocols/oscar/oscar.c --- a/libpurple/protocols/oscar/oscar.c Wed Oct 10 01:01:21 2007 +0000 +++ b/libpurple/protocols/oscar/oscar.c Wed Oct 10 01:06:16 2007 +0000 @@ -1721,7 +1721,6 @@ { PurpleConnection *gc; PurpleAccount *account; - PurplePresence *presence; struct buddyinfo *bi; time_t time_idle = 0, signon = 0; int type = 0; @@ -1734,7 +1733,6 @@ gc = od->gc; account = purple_connection_get_account(gc); - presence = purple_account_get_presence(account); va_start(ap, fr); info = va_arg(ap, aim_userinfo_t *); diff -r e0ce7124d2d4 -r 2a6ef74f5a4e libpurple/tests/test_cipher.c --- a/libpurple/tests/test_cipher.c Wed Oct 10 01:01:21 2007 +0000 +++ b/libpurple/tests/test_cipher.c Wed Oct 10 01:06:16 2007 +0000 @@ -8,7 +8,6 @@ #include "tests.h" #include "../cipher.h" -#include "../signal.h" /****************************************************************************** * MD4 Tests diff -r e0ce7124d2d4 -r 2a6ef74f5a4e libpurple/util.c --- a/libpurple/util.c Wed Oct 10 01:01:21 2007 +0000 +++ b/libpurple/util.c Wed Oct 10 01:06:16 2007 +0000 @@ -2548,15 +2548,14 @@ filename_full = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", user_dir, filename); - ret = purple_util_write_data_to_file_absolute(filename_full, - data,size); + ret = purple_util_write_data_to_file_absolute(filename_full, data, size); g_free(filename_full); return ret; } gboolean -purple_util_write_data_to_file_absolute(const char *filename_full, const char *data, size_t size) +purple_util_write_data_to_file_absolute(const char *filename_full, const char *data, gssize size) { gchar *filename_temp; FILE *file; diff -r e0ce7124d2d4 -r 2a6ef74f5a4e libpurple/util.h --- a/libpurple/util.h Wed Oct 10 01:01:21 2007 +0000 +++ b/libpurple/util.h Wed Oct 10 01:06:16 2007 +0000 @@ -607,7 +607,7 @@ * */ gboolean -purple_util_write_data_to_file_absolute(const char *filename_full, const char *data, size_t size); +purple_util_write_data_to_file_absolute(const char *filename_full, const char *data, gssize size); /** * Read the contents of a given file and parse the results into an diff -r e0ce7124d2d4 -r 2a6ef74f5a4e libpurple/xmlnode.c --- a/libpurple/xmlnode.c Wed Oct 10 01:01:21 2007 +0000 +++ b/libpurple/xmlnode.c Wed Oct 10 01:06:16 2007 +0000 @@ -146,6 +146,19 @@ } } +/* Compare two nullable xmlns strings. + * They are considered equal if they're both NULL or the strings are equal + */ +static gboolean _xmlnode_compare_xmlns(const char *xmlns1, const char *xmlns2) { + gboolean equal = FALSE; + + if (xmlns1 == NULL && xmlns2 == NULL) + equal = TRUE; + else if (xmlns1 != NULL && xmlns2 != NULL && !strcmp(xmlns1, xmlns2)) + equal = TRUE; + + return equal; +} void xmlnode_remove_attrib_with_namespace(xmlnode *node, const char *attr, const char *xmlns) @@ -159,7 +172,7 @@ { if(attr_node->type == XMLNODE_TYPE_ATTRIB && !strcmp(attr_node->name, attr) && - !strcmp(attr_node->xmlns, xmlns)) + _xmlnode_compare_xmlns(xmlns, attr_node->xmlns)) { if(node->child == attr_node) { node->child = attr_node->next; @@ -238,7 +251,8 @@ for(x = node->child; x; x = x->next) { if(x->type == XMLNODE_TYPE_ATTRIB && - !strcmp(attr, x->name) && !strcmp(x->xmlns, xmlns)) { + !strcmp(attr, x->name) && + _xmlnode_compare_xmlns(xmlns, x->xmlns)) { return x->data; } } @@ -326,6 +340,7 @@ child_name = names[1]; for(x = parent->child; x; x = x->next) { + /* XXX: Is it correct to ignore the namespace for the match if none was specified? */ const char *xmlns = NULL; if(ns) xmlns = xmlnode_get_namespace(x); @@ -673,6 +688,7 @@ g_return_val_if_fail(node->type == XMLNODE_TYPE_TAG, NULL); for(sibling = node->next; sibling; sibling = sibling->next) { + /* XXX: Is it correct to ignore the namespace for the match if none was specified? */ const char *xmlns = NULL; if(ns) xmlns = xmlnode_get_namespace(sibling); diff -r e0ce7124d2d4 -r 2a6ef74f5a4e pidgin/gtkblist.c --- a/pidgin/gtkblist.c Wed Oct 10 01:01:21 2007 +0000 +++ b/pidgin/gtkblist.c Wed Oct 10 01:06:16 2007 +0000 @@ -4347,7 +4347,6 @@ gpointer user_data) { PurpleAccount *account; - PurpleStatusType *status_type; gchar *escaped, *text; GtkWidget *button, *label, *image, *hbox; GdkPixbuf *pixbuf; @@ -4362,8 +4361,8 @@ hbox = gtk_hbox_new(FALSE, 6); /* Create the icon */ - if ((status_type = purple_account_get_status_type_with_primitive(account, - PURPLE_STATUS_OFFLINE))) { + if (purple_account_get_status_type_with_primitive(account, + PURPLE_STATUS_OFFLINE) != NULL) { pixbuf = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL); if (pixbuf != NULL) { image = gtk_image_new_from_pixbuf(pixbuf); @@ -5367,7 +5366,7 @@ BUDDY_ICON_COLUMN, avatar, BUDDY_ICON_VISIBLE_COLUMN, biglist, EMBLEM_COLUMN, emblem, - EMBLEM_VISIBLE_COLUMN, emblem, + EMBLEM_VISIBLE_COLUMN, (emblem != NULL), PROTOCOL_ICON_COLUMN, pidgin_create_prpl_icon(buddy->account, PIDGIN_PRPL_ICON_SMALL), PROTOCOL_ICON_VISIBLE_COLUMN, purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons"), BGCOLOR_COLUMN, NULL, @@ -5378,6 +5377,8 @@ g_free(mark); g_free(idle); + if(emblem) + g_object_unref(emblem); if(status) g_object_unref(status); if(avatar) @@ -5549,6 +5550,8 @@ -1); g_free(mark); + if(emblem) + g_object_unref(emblem); if(status) g_object_unref(status); if(avatar) diff -r e0ce7124d2d4 -r 2a6ef74f5a4e pidgin/gtkconv.c --- a/pidgin/gtkconv.c Wed Oct 10 01:01:21 2007 +0000 +++ b/pidgin/gtkconv.c Wed Oct 10 01:06:16 2007 +0000 @@ -2498,11 +2498,16 @@ gtk_list_store_set(GTK_LIST_STORE(gtkconv->infopane_model), &(gtkconv->infopane_iter), CONV_EMBLEM_COLUMN, emblem, -1); + if (emblem) + g_object_unref(emblem); if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons")) { + emblem = pidgin_create_prpl_icon(gtkconv->active_conv->account, PIDGIN_PRPL_ICON_SMALL); gtk_list_store_set(GTK_LIST_STORE(gtkconv->infopane_model), &(gtkconv->infopane_iter), - CONV_PROTOCOL_ICON_COLUMN, pidgin_create_prpl_icon(gtkconv->active_conv->account, PIDGIN_PRPL_ICON_SMALL), -1); + CONV_PROTOCOL_ICON_COLUMN, emblem, -1); + if (emblem) + g_object_unref(emblem); } /* XXX seanegan Why do I have to do this? */ @@ -4358,45 +4363,54 @@ gtk_menu_shell_insert(GTK_MENU_SHELL(menu), menuitem, 1); } - static void resize_imhtml_cb(PidginConversation *gtkconv) { GtkTextBuffer *buffer; GtkTextIter iter; - int wrapped_lines; - int lines; - GdkRectangle oneline; + int wrapped_lines; + int lines; + GdkRectangle oneline; GtkRequisition sr; - int height; - int pad_top, pad_inside, pad_bottom; + int height, diff; + int pad_top, pad_inside, pad_bottom; buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->entry)); - wrapped_lines = 1; - gtk_text_buffer_get_start_iter(buffer, &iter); - gtk_text_view_get_iter_location(GTK_TEXT_VIEW(gtkconv->entry), &iter, &oneline); - while (gtk_text_view_forward_display_line(GTK_TEXT_VIEW(gtkconv->entry), &iter)) - wrapped_lines++; - - lines = gtk_text_buffer_get_line_count(buffer); - - /* Show a maximum of 4 lines */ - lines = MIN(lines, 4); - wrapped_lines = MIN(wrapped_lines, 4); - - pad_top = gtk_text_view_get_pixels_above_lines(GTK_TEXT_VIEW(gtkconv->entry)); - pad_bottom = gtk_text_view_get_pixels_below_lines(GTK_TEXT_VIEW(gtkconv->entry)); - pad_inside = gtk_text_view_get_pixels_inside_wrap(GTK_TEXT_VIEW(gtkconv->entry)); - - height = (oneline.height + pad_top + pad_bottom) * lines; - height += (oneline.height + pad_inside) * (wrapped_lines - lines); + wrapped_lines = 1; + gtk_text_buffer_get_start_iter(buffer, &iter); + gtk_text_view_get_iter_location(GTK_TEXT_VIEW(gtkconv->entry), &iter, &oneline); + while (gtk_text_view_forward_display_line(GTK_TEXT_VIEW(gtkconv->entry), &iter)) + wrapped_lines++; + + lines = gtk_text_buffer_get_line_count(buffer); + + /* Show a maximum of 4 lines */ + lines = MIN(lines, 4); + wrapped_lines = MIN(wrapped_lines, 4); + + pad_top = gtk_text_view_get_pixels_above_lines(GTK_TEXT_VIEW(gtkconv->entry)); + pad_bottom = gtk_text_view_get_pixels_below_lines(GTK_TEXT_VIEW(gtkconv->entry)); + pad_inside = gtk_text_view_get_pixels_inside_wrap(GTK_TEXT_VIEW(gtkconv->entry)); + + height = (oneline.height + pad_top + pad_bottom) * lines; + height += (oneline.height + pad_inside) * (wrapped_lines - lines); gtkconv->auto_resize = TRUE; - g_idle_add(reset_auto_resize_cb, gtkconv); - gtk_widget_size_request(gtkconv->lower_hbox, &sr); - if (sr.height < height + PIDGIN_HIG_BOX_SPACE) { + g_idle_add(reset_auto_resize_cb, gtkconv); + + diff = height - gtkconv->entry->allocation.height; + + if (diff > 0) { + gtk_widget_size_request(gtkconv->lower_hbox, &sr); gtkconv->entry_growing = TRUE; - gtk_widget_set_size_request(gtkconv->lower_hbox, -1, height + PIDGIN_HIG_BOX_SPACE); + + /* uncomment this to auto resize even after the user manually + resizes + gtk_paned_set_position(GTK_PANED(gtkconv->lower_hbox->parent->parent), + -1); + */ + gtk_widget_set_size_request(gtkconv->lower_hbox, -1, + diff + gtkconv->lower_hbox->allocation.height); } } @@ -4728,7 +4742,6 @@ g_object_set(rend, "ellipsize", PANGO_ELLIPSIZE_END, NULL); #endif - rend = gtk_cell_renderer_pixbuf_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(gtkconv->infopane), rend, FALSE); gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(gtkconv->infopane), rend, "pixbuf", CONV_PROTOCOL_ICON_COLUMN, NULL); diff -r e0ce7124d2d4 -r 2a6ef74f5a4e pidgin/win32/winpidgin.c --- a/pidgin/win32/winpidgin.c Wed Oct 10 01:01:21 2007 +0000 +++ b/pidgin/win32/winpidgin.c Wed Oct 10 01:06:16 2007 +0000 @@ -545,7 +545,7 @@ if (strstr(lpszCmdLine, "-d") || strstr(lpszCmdLine, "-h") || strstr(lpszCmdLine, "-v")) { /* If stdout hasn't been redirected to a file, alloc a console * (_istty() doesn't work for stuff using the GUI subsystem) */ - if (_fileno(stdout) == -1) { + if (_fileno(stdout) == -1 || _fileno(stdout) == -2) { LPFNATTACHCONSOLE MyAttachConsole = NULL; if ((hmod = GetModuleHandle("kernel32.dll"))) { MyAttachConsole =