pidgin/ljfisher-ssl-client-auth

propagate from branch 'im.pidgin.pidgin' (head a727618dfaa697c504839afb78b7ecb859eb2d27)
to branch 'im.pidgin.pidgin.mxit' (head d0676f987e39c0467d8bef1b829860612872fad5)
  • +35 -2
    ChangeLog
  • +9 -0
    ChangeLog.API
  • +3 -3
    configure.ac
  • +21 -1
    libpurple/dnsquery.c
  • +121 -60
    libpurple/dnssrv.c
  • +4 -0
    libpurple/dnssrv.h
  • +1 -1
    libpurple/log.c
  • +6 -6
    libpurple/plugins/filectl.c
  • +26 -22
    libpurple/plugins/log_reader.c
  • +4 -2
    libpurple/plugins/tcl/tcl_ref.c
  • +3 -2
    libpurple/plugins/tcl/tcl_signals.c
  • +6 -0
    libpurple/prefs.c
  • +7 -1
    libpurple/protocols/gg/gg.c
  • +1 -2
    libpurple/protocols/gg/lib/libgadu.c
  • +3 -1
    libpurple/protocols/irc/irc.c
  • +1 -0
    libpurple/protocols/irc/parse.c
  • +5 -5
    libpurple/protocols/jabber/jabber.c
  • +12 -12
    libpurple/protocols/jabber/win32/posix.uname.c
  • +16 -13
    libpurple/protocols/msn/contact.c
  • +2 -2
    libpurple/protocols/msn/msn.c
  • +3 -0
    libpurple/protocols/msn/notification.c
  • +2 -0
    libpurple/protocols/msn/session.c
  • +0 -1
    libpurple/protocols/msn/slp.c
  • +0 -2
    libpurple/protocols/msn/slpcall.c
  • +2 -2
    libpurple/protocols/mxit/cipher.c
  • +9 -2
    libpurple/protocols/oscar/oscar.c
  • +5 -0
    libpurple/protocols/sametime/sametime.c
  • +2 -0
    libpurple/protocols/simple/simple.c
  • +1 -1
    libpurple/protocols/yahoo/libymsg.h
  • +1 -1
    libpurple/protocols/yahoo/yahoo_filexfer.c
  • +17 -11
    libpurple/protocols/zephyr/ZAsyncLocate.c
  • +2 -2
    libpurple/protocols/zephyr/ZInit.c
  • +13 -8
    libpurple/protocols/zephyr/ZRetSubs.c
  • +3 -3
    libpurple/protocols/zephyr/Zinternal.c
  • +1 -1
    libpurple/protocols/zephyr/zephyr.c
  • +2 -2
    libpurple/proxy.c
  • +1 -1
    libpurple/stun.c
  • +3 -5
    libpurple/upnp.c
  • +2 -2
    libpurple/win32/libc_interface.c
  • +1 -0
    pidgin/gtkblist.c
  • +47 -0
    pidgin/gtkdialogs.c
  • +1 -0
    pidgin/gtkdialogs.h
  • +8 -0
    pidgin/gtkmedia.c
  • +54 -31
    po/ca.po
  • +22 -6
    po/de.po
  • --- a/ChangeLog Sat Jul 09 20:10:36 2011 +0000
    +++ b/ChangeLog Fri Aug 12 21:41:34 2011 +0000
    @@ -1,19 +1,52 @@
    Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul
    -version 2.9.1 (MM/DD/YYYY):
    +version 2.10.0 (MM/DD/YYYY):
    Pidgin:
    * Make the max size of incoming smileys a pref instead of hardcoding it.
    - (Quentin Brandon)(#5231)
    + (Quentin Brandon) (#5231)
    + * Added a plugin information dialog to show information for plugins
    + that aren't otherwise visible in the plugins dialog.
    + * Fix building with GTK+ earlier than 2.14.0 (GTK+ 2.10 is still the
    + minimum supported) (#14261)
    +
    + libpurple:
    + * Fix a potential crash in the Log Reader plugin when reading QIP logs.
    + * Fix a large number of strcpy() and strcat() invocations to use
    + strlcpy() and strlcat(), etc., forestalling an entire class of
    + string buffer overrun bugs.
    + (The Electronic Frontier Foundation, Dan Auerbach, Chris Palmer,
    + Jacob Appelbaum)
    + * Change some filename manipulations in filectl.c to use MAXPATHLEN
    + instead of arbitrary length constants. (The Electronic Frontier
    + Foundation, Dan Auerbach, Chris Palmer, Jacob Appelbaum)
    Gadu-Gadu:
    * Fixed searching for buddies in public directory. (Tomasz Wasilczyk)
    (#5242)
    * Better status message handling. (Tomasz Wasilczyk) (#14314)
    * Merged two buddy blocking methods. (Tomasz Wasilczyk) (#5303)
    + * Fix building of the bundled libgadu library with older versions
    + of GnuTLS. (patch plucked from upstream) (#14365)
    +
    + ICQ:
    + * Fix crash selecting Tools->Set Mood when you're online with an
    + ICQ account that is configured as an AIM account. (#14437)
    +
    + IRC:
    + * Fix the handling of formatting following mIRC ^O (#14436)
    +
    + MSN:
    + * Fix seemingly random crashing. (#14307)
    XMPP:
    * Do not generate malformed XML ("</>") when setting an empty mood.
    (#14342)
    + * Fix the /join <room> behavior. (Broken when adding support for
    + <room>@<server>) (#14205)
    +
    + Yahoo!/Yahoo! JAPAN:
    + * Fix coming out of idle while in an unavailable state
    + * Fix logging into Yahoo! JAPAN. (#14259)
    version 2.9.0 (06/23/2011):
    Pidgin:
    --- a/ChangeLog.API Sat Jul 09 20:10:36 2011 +0000
    +++ b/ChangeLog.API Fri Aug 12 21:41:34 2011 +0000
    @@ -1,5 +1,14 @@
    Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul
    +version 2.10.0:
    + libpurple:
    + Added:
    + * purple_srv_txt_query_destroy (accidentally left out of 2.8.0)
    +
    + Pidgin:
    + Added:
    + * pidgin_dialogs_plugins_info (should not be used by anything but Pidgin)
    +
    version 2.9.0:
    libpurple:
    Added:
    --- a/configure.ac Sat Jul 09 20:10:36 2011 +0000
    +++ b/configure.ac Fri Aug 12 21:41:34 2011 +0000
    @@ -43,10 +43,10 @@
    #
    # Make sure to update finch/libgnt/configure.ac with libgnt version changes.
    #
    -m4_define([purple_lt_current], [9])
    +m4_define([purple_lt_current], [10])
    m4_define([purple_major_version], [2])
    -m4_define([purple_minor_version], [9])
    -m4_define([purple_micro_version], [1])
    +m4_define([purple_minor_version], [10])
    +m4_define([purple_micro_version], [0])
    m4_define([purple_version_suffix], [devel])
    m4_define([purple_version],
    [purple_major_version.purple_minor_version.purple_micro_version])
    --- a/libpurple/dnsquery.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/dnsquery.c Fri Aug 12 21:41:34 2011 +0000
    @@ -154,8 +154,27 @@
    static gboolean
    resolve_ip(PurpleDnsQueryData *query_data)
    {
    +#if defined(HAVE_GETADDRINFO) && defined(AI_NUMERICHOST)
    + struct addrinfo hints, *res;
    + char servname[20];
    +
    + g_snprintf(servname, sizeof(servname), "%d", query_data->port);
    + memset(&hints, 0, sizeof(hints));
    + hints.ai_family = AF_UNSPEC;
    + hints.ai_flags |= AI_NUMERICHOST;
    +
    + if (0 == getaddrinfo(query_data->hostname, servname, &hints, &res))
    + {
    + GSList *hosts = NULL;
    + hosts = g_slist_append(hosts, GINT_TO_POINTER(res->ai_addrlen));
    + hosts = g_slist_append(hosts, g_memdup(res->ai_addr, res->ai_addrlen));
    + purple_dnsquery_resolved(query_data, hosts);
    +
    + freeaddrinfo(res);
    + return TRUE;
    + }
    +#else /* defined(HAVE_GETADDRINFO) && defined(AI_NUMERICHOST) */
    struct sockaddr_in sin;
    - /* TODO: Use inet_pton for IPv6 support */
    if (inet_aton(query_data->hostname, &sin.sin_addr))
    {
    /*
    @@ -171,6 +190,7 @@
    return TRUE;
    }
    +#endif
    return FALSE;
    }
    --- a/libpurple/dnssrv.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/dnssrv.c Fri Aug 12 21:41:34 2011 +0000
    @@ -250,6 +250,52 @@
    return list;
    }
    +static PurpleSrvTxtQueryData *
    +query_data_new(int type, gchar *query, gpointer extradata)
    +{
    + PurpleSrvTxtQueryData *query_data = g_new0(PurpleSrvTxtQueryData, 1);
    + query_data->type = type;
    + query_data->extradata = extradata;
    + query_data->query = query;
    +#ifndef _WIN32
    + query_data->fd_in = -1;
    + query_data->fd_out = -1;
    +#endif
    + return query_data;
    +}
    +
    +void
    +purple_srv_txt_query_destroy(PurpleSrvTxtQueryData *query_data)
    +{
    + PurpleSrvTxtQueryUiOps *ops = purple_srv_txt_query_get_ui_ops();
    +
    + if (ops && ops->destroy)
    + ops->destroy(query_data);
    +
    + if (query_data->handle > 0)
    + purple_input_remove(query_data->handle);
    +#ifdef _WIN32
    + if (query_data->resolver != NULL)
    + {
    + /*
    + * It's not really possible to kill a thread. So instead we
    + * just set the callback to NULL and let the DNS lookup
    + * finish.
    + */
    + query_data->cb.srv = NULL;
    + return;
    + }
    + g_free(query_data->error_message);
    +#else
    + if (query_data->fd_out != -1)
    + close(query_data->fd_out);
    + if (query_data->fd_in != -1)
    + close(query_data->fd_in);
    +#endif
    + g_free(query_data->query);
    + g_free(query_data);
    +}
    +
    #ifdef USE_IDN
    static gboolean
    dns_str_is_ascii(const char *name)
    @@ -382,7 +428,11 @@
    cp += size;
    srvres = g_new0(PurpleSrvResponse, 1);
    - strcpy(srvres->hostname, name);
    + if (strlen(name) > sizeof(srvres->hostname) - 1) {
    + purple_debug_error("dnssrv", "hostname is longer than available buffer ('%s', %zd bytes)!",
    + name, strlen(name));
    + }
    + g_strlcpy(srvres->hostname, name, sizeof(srvres->hostname));
    srvres->pref = pref;
    srvres->port = port;
    srvres->weight = weight;
    @@ -523,7 +573,7 @@
    }
    waitpid(query_data->pid, &status, 0);
    - purple_srv_cancel(query_data);
    + purple_srv_txt_query_destroy(query_data);
    }
    #else /* _WIN32 */
    @@ -583,7 +633,7 @@
    query_data->resolver = NULL;
    query_data->handle = 0;
    - purple_srv_cancel(query_data);
    + purple_srv_txt_query_destroy(query_data);
    return FALSE;
    }
    @@ -730,13 +780,10 @@
    purple_debug_info("dnssrv","querying SRV record for %s: %s\n", domain,
    query);
    g_free(hostname);
    -
    - query_data = g_new0(PurpleSrvTxtQueryData, 1);
    - query_data->type = PurpleDnsTypeSrv;
    +
    + query_data = query_data_new(PurpleDnsTypeSrv, query, extradata);
    query_data->cb.srv = cb;
    - query_data->extradata = extradata;
    - query_data->query = query;
    -
    +
    if (purple_srv_txt_query_ui_resolve(query_data))
    {
    return query_data;
    @@ -746,6 +793,7 @@
    if(pipe(in) || pipe(out)) {
    purple_debug_error("dnssrv", "Could not create pipe\n");
    g_free(query);
    + g_free(query_data);
    cb(NULL, 0, extradata);
    return NULL;
    }
    @@ -753,8 +801,9 @@
    pid = fork();
    if (pid == -1) {
    purple_debug_error("dnssrv", "Could not create process!\n");
    + g_free(query);
    + g_free(query_data);
    cb(NULL, 0, extradata);
    - g_free(query);
    return NULL;
    }
    @@ -762,6 +811,7 @@
    if (pid == 0)
    {
    g_free(query);
    + g_free(query_data);
    close(out[0]);
    close(in[1]);
    @@ -784,8 +834,6 @@
    query_data->fd_in = in[1];
    query_data->handle = purple_input_add(out[0], PURPLE_INPUT_READ, resolved, query_data);
    - g_free(query);
    -
    return query_data;
    #else
    if (!initialized) {
    @@ -862,13 +910,10 @@
    purple_debug_info("dnssrv","querying TXT record for %s: %s\n", domain,
    query);
    g_free(hostname);
    -
    - query_data = g_new0(PurpleSrvTxtQueryData, 1);
    - query_data->type = PurpleDnsTypeTxt;
    +
    + query_data = query_data_new(PurpleDnsTypeTxt, query, extradata);
    query_data->cb.txt = cb;
    - query_data->extradata = extradata;
    - query_data->query = query;
    -
    +
    if (purple_srv_txt_query_ui_resolve(query_data)) {
    /* query intentionally not freed
    */
    @@ -879,6 +924,7 @@
    if(pipe(in) || pipe(out)) {
    purple_debug_error("dnssrv", "Could not create pipe\n");
    g_free(query);
    + g_free(query_data);
    cb(NULL, extradata);
    return NULL;
    }
    @@ -886,8 +932,9 @@
    pid = fork();
    if (pid == -1) {
    purple_debug_error("dnssrv", "Could not create process!\n");
    + g_free(query);
    + g_free(query_data);
    cb(NULL, extradata);
    - g_free(query);
    return NULL;
    }
    @@ -895,6 +942,7 @@
    if (pid == 0)
    {
    g_free(query);
    + g_free(query_data);
    close(out[0]);
    close(in[1]);
    @@ -911,14 +959,12 @@
    if (write(in[1], &internal_query, sizeof(internal_query)) < 0)
    purple_debug_error("dnssrv", "Could not write to TXT resolver\n");
    -
    +
    query_data->pid = pid;
    query_data->fd_out = out[0];
    query_data->fd_in = in[1];
    query_data->handle = purple_input_add(out[0], PURPLE_INPUT_READ, resolved, query_data);
    - g_free(query);
    -
    return query_data;
    #else
    if (!initialized) {
    @@ -949,39 +995,15 @@
    }
    void
    -purple_srv_cancel(PurpleSrvTxtQueryData *query_data)
    +purple_txt_cancel(PurpleSrvTxtQueryData *query_data)
    {
    - PurpleSrvTxtQueryUiOps *ops = purple_srv_txt_query_get_ui_ops();
    -
    - if (ops && ops->destroy)
    - ops->destroy(query_data);
    -
    - if (query_data->handle > 0)
    - purple_input_remove(query_data->handle);
    -#ifdef _WIN32
    - if (query_data->resolver != NULL)
    - {
    - /*
    - * It's not really possible to kill a thread. So instead we
    - * just set the callback to NULL and let the DNS lookup
    - * finish.
    - */
    - query_data->cb.srv = NULL;
    - return;
    - }
    - g_free(query_data->query);
    - g_free(query_data->error_message);
    -#else
    - close(query_data->fd_out);
    - close(query_data->fd_in);
    -#endif
    - g_free(query_data);
    + purple_srv_txt_query_destroy(query_data);
    }
    void
    -purple_txt_cancel(PurpleSrvTxtQueryData *query_data)
    +purple_srv_cancel(PurpleSrvTxtQueryData *query_data)
    {
    - purple_srv_cancel(query_data);
    + purple_srv_txt_query_destroy(query_data);
    }
    const gchar *
    @@ -1006,12 +1028,41 @@
    static void
    purple_srv_query_resolved(PurpleSrvTxtQueryData *query_data, GList *records)
    {
    + GList *l;
    + PurpleSrvResponse *records_array;
    + int i = 0, length;
    +
    g_return_if_fail(records != NULL);
    -
    - purple_debug_info("dnssrv", "SRV records resolved for %s, count: %d\n", query_data->query, g_list_length(records));
    -
    - if (query_data->cb.srv != NULL)
    - query_data->cb.srv(purple_srv_sort(records)->data, g_list_length(records), query_data->extradata);
    +
    + if (query_data->cb.srv == NULL) {
    + purple_srv_txt_query_destroy(query_data);
    +
    + while (records) {
    + g_free(records->data);
    + records = g_list_delete_link(records, records);
    + }
    + return;
    + }
    +
    + records = purple_srv_sort(records);
    + length = g_list_length(records);
    +
    + purple_debug_info("dnssrv", "SRV records resolved for %s, count: %d\n",
    + query_data->query, length);
    +
    + records_array = g_new(PurpleSrvResponse, length);
    + for (l = records; l; l = l->next, i++) {
    + records_array[i] = *(PurpleSrvResponse *)l->data;
    + }
    +
    + query_data->cb.srv(records_array, length, query_data->extradata);
    +
    + purple_srv_txt_query_destroy(query_data);
    +
    + while (records) {
    + g_free(records->data);
    + records = g_list_delete_link(records, records);
    + }
    }
    /*
    @@ -1024,19 +1075,29 @@
    purple_debug_info("dnssrv", "TXT entries resolved for %s, count: %d\n", query_data->query, g_list_length(entries));
    + /* the callback should g_free the entries.
    + */
    if (query_data->cb.txt != NULL)
    query_data->cb.txt(entries, query_data->extradata);
    + else {
    + while (entries) {
    + g_free(entries->data);
    + entries = g_list_delete_link(entries, entries);
    + }
    + }
    +
    + purple_srv_txt_query_destroy(query_data);
    }
    static void
    purple_srv_query_failed(PurpleSrvTxtQueryData *query_data, const gchar *error_message)
    {
    purple_debug_error("dnssrv", "%s\n", error_message);
    -
    +
    if (query_data->cb.srv != NULL)
    query_data->cb.srv(NULL, 0, query_data->extradata);
    -
    - purple_srv_cancel(query_data);
    +
    + purple_srv_txt_query_destroy(query_data);
    }
    static gboolean
    @@ -1069,7 +1130,7 @@
    purple_srv_txt_query_get_query(PurpleSrvTxtQueryData *query_data)
    {
    g_return_val_if_fail(query_data != NULL, NULL);
    -
    +
    return query_data->query;
    }
    @@ -1078,6 +1139,6 @@
    purple_srv_txt_query_get_type(PurpleSrvTxtQueryData *query_data)
    {
    g_return_val_if_fail(query_data != NULL, 0);
    -
    +
    return query_data->type;
    }
    --- a/libpurple/dnssrv.h Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/dnssrv.h Fri Aug 12 21:41:34 2011 +0000
    @@ -133,6 +133,8 @@
    * Cancel an SRV or DNS query.
    *
    * @param query_data The request to cancel.
    + *
    + * @deprecated Use purple_srv_txt_query_destroy instead
    */
    void purple_srv_cancel(PurpleSrvTxtQueryData *query_data);
    @@ -170,6 +172,8 @@
    *
    * @param query_data The request to cancel.
    * @since 2.6.0
    + *
    + * @deprecated Use purple_srv_txt_query_destroy instead
    */
    void purple_txt_cancel(PurpleSrvTxtQueryData *query_data);
    --- a/libpurple/log.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/log.c Fri Aug 12 21:41:34 2011 +0000
    @@ -1838,7 +1838,7 @@
    g_snprintf(convostart, length, "%s", temp);
    memset(&tm, 0, sizeof(tm));
    - sscanf(convostart, "%*s %s %d %d:%d:%d %d",
    + sscanf(convostart, "%*s %3s %d %d:%d:%d %d",
    month, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &tm.tm_year);
    /* Ugly hack, in case current locale is not English */
    if (purple_strequal(month, "Jan")) {
    --- a/libpurple/plugins/filectl.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/plugins/filectl.c Fri Aug 12 21:41:34 2011 +0000
    @@ -40,12 +40,12 @@
    run_commands()
    {
    struct stat finfo;
    - char filename[256];
    + char filename[MAXPATHLEN];
    char buffer[1024];
    char *command, *arg1, *arg2;
    FILE *file;
    - sprintf(filename, "%s" G_DIR_SEPARATOR_S "control", purple_user_dir());
    + snprintf(filename, MAXPATHLEN, "%s" G_DIR_SEPARATOR_S "control", purple_user_dir());
    file = g_fopen(filename, "r+");
    while (fgets(buffer, sizeof(buffer), file)) {
    @@ -144,9 +144,9 @@
    {
    /* most of this was taken from Bash v2.04 by the FSF */
    struct stat finfo;
    - char filename[256];
    + char filename[MAXPATHLEN];
    - sprintf(filename, "%s" G_DIR_SEPARATOR_S "control", purple_user_dir());
    + snprintf(filename, MAXPATHLEN, "%s" G_DIR_SEPARATOR_S "control", purple_user_dir());
    if ((g_stat(filename, &finfo) == 0) && (finfo.st_size > 0))
    run_commands();
    @@ -160,9 +160,9 @@
    {
    /* most of this was taken from Bash v2.04 by the FSF */
    struct stat finfo;
    - char filename[256];
    + char filename[MAXPATHLEN];
    - sprintf(filename, "%s" G_DIR_SEPARATOR_S "control", purple_user_dir());
    + snprintf(filename, MAXPATHLEN, "%s" G_DIR_SEPARATOR_S "control", purple_user_dir());
    if ((g_stat(filename, &finfo) == 0) && (finfo.st_size > 0))
    {
    --- a/libpurple/plugins/log_reader.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/plugins/log_reader.c Fri Aug 12 21:41:34 2011 +0000
    @@ -1454,11 +1454,15 @@
    const char *footer = NULL;
    GString *temp = NULL;
    - if ((c = strstr(c, "\n")))
    - {
    - *c = '\0';
    - c++;
    - }
    + /* There's always a trailing '\n' at the end of the file (see above), so
    + * just quit out if we don't find another, because we're at the end.
    + */
    + c = strchr(c, '\n');
    + if (!c)
    + break;
    +
    + *c = '\0';
    + c++;
    /* Convert links.
    *
    @@ -1482,14 +1486,14 @@
    char *end_paren;
    char *space;
    - if (!(end_paren = strstr(link, ")")))
    + if (!(end_paren = strchr(link, ')')))
    {
    /* Something is not as we expect. Bail out. */
    break;
    }
    if (!temp)
    - temp = g_string_sized_new(c ? (c - 1 - line) : strlen(line));
    + temp = g_string_sized_new(strlen(line));
    g_string_append_len(temp, line, (tmp - line));
    @@ -1504,7 +1508,7 @@
    /* The \r is a bit of a hack to keep there from being a \r in
    * the link text, which may not matter. */
    - if ((space = strstr(end_paren, " ")) || (space = strstr(end_paren, "\r")))
    + if ((space = strchr(end_paren, ' ')) || (space = strchr(end_paren, '\r')))
    {
    g_string_append_len(temp, end_paren + 1, space - end_paren - 1);
    @@ -1539,7 +1543,7 @@
    if (*line == '[') {
    const char *timestamp;
    - if ((timestamp = strstr(line, "]"))) {
    + if ((timestamp = strchr(line, ']'))) {
    line++;
    /* TODO: Parse the timestamp and convert it to Purple's format. */
    g_string_append(formatted, "<font size=\"2\">(");
    @@ -1658,7 +1662,7 @@
    }
    }
    } else {
    - const char *line2 = strstr(line, ":");
    + const char *line2 = strchr(line, ':');
    if (line2) {
    const char *acct_name;
    line2++;
    @@ -1819,7 +1823,7 @@
    gboolean add_new_log = FALSE;
    - if (*c) {
    + if (c && *c) {
    if (purple_str_has_prefix(c, QIP_LOG_IN_MESSAGE) ||
    purple_str_has_prefix(c, QIP_LOG_OUT_MESSAGE)) {
    @@ -1828,11 +1832,11 @@
    new_line = c;
    /* find EOL */
    - c = strstr(c, "\n");
    + c = strchr(c, '\n');
    c++;
    /* Find the last '(' character. */
    - if ((tmp = strstr(c, "\n")) != NULL) {
    + if ((tmp = strchr(c, '\n')) != NULL) {
    while (*tmp && *tmp != '(') --tmp;
    c = tmp;
    } else {
    @@ -1902,10 +1906,10 @@
    start_log = new_line;
    }
    - if (*c) {
    + if (c && *c) {
    /* find EOF */
    - c = strstr(c, "\n");
    - c++;
    + if ((c = strchr(c, '\n')))
    + c++;
    }
    }
    @@ -1983,13 +1987,13 @@
    is_in_message = purple_str_has_prefix(line, QIP_LOG_IN_MESSAGE_ESC);
    /* find EOL */
    - c = strstr(c, "\n");
    + c = strchr(c, '\n');
    /* XXX: Do we need buddy_name when we have buddy->alias? */
    buddy_name = ++c;
    /* Find the last '(' character. */
    - if ((tmp = strstr(c, "\n")) != NULL) {
    + if ((tmp = strchr(c, '\n')) != NULL) {
    while (*tmp && *tmp != '(') --tmp;
    c = tmp;
    } else {
    @@ -2042,12 +2046,12 @@
    }
    /* find EOF */
    - c = strstr(c, "\n");
    + c = strchr(c, '\n');
    line = ++c;
    }
    }
    } else {
    - if ((c = strstr(c, "\n")))
    + if ((c = strchr(c, '\n')))
    *c = '\0';
    if (line[0] != '\n' && line[0] != '\r') {
    @@ -2186,7 +2190,7 @@
    " length = (%d)\n",
    sn, data->path, data->offset, data->length);
    }
    - c = strstr(c, "\n");
    + c = strchr(c, '\n');
    c++;
    }
    @@ -2342,7 +2346,7 @@
    char *end;
    char *old_tag;
    char *tag;
    - end = strstr(start, "\n");
    + end = strchr(start, '\n');
    if (!end)
    break;
    *end = '\0';
    --- a/libpurple/plugins/tcl/tcl_ref.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/plugins/tcl/tcl_ref.c Fri Aug 12 21:41:34 2011 +0000
    @@ -92,6 +92,7 @@
    static void purple_tcl_ref_update(Tcl_Obj *obj)
    {
    + size_t len;
    /* This is ugly on memory, but we pretty much have to either
    * do this or guesstimate lengths or introduce a varargs
    * function in here ... ugh. */
    @@ -100,8 +101,9 @@
    OBJ_REF_VALUE(obj));
    obj->length = strlen(bytes);
    - obj->bytes = ckalloc(obj->length + 1);
    - strcpy(obj->bytes, bytes);
    + len = obj->length + 1;
    + obj->bytes = ckalloc(len);
    + g_strlcpy(obj->bytes, bytes, len);
    g_free(bytes);
    }
    --- a/libpurple/plugins/tcl/tcl_signals.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/plugins/tcl/tcl_signals.c Fri Aug 12 21:41:34 2011 +0000
    @@ -259,8 +259,9 @@
    vals[i] = ckalloc(1);
    *(char *)vals[i] = '\0';
    } else {
    - vals[i] = ckalloc(strlen(*strs[i]) + 1);
    - strcpy(vals[i], *strs[i]);
    + size_t len = strlen(*strs[i]) + 1;
    + vals[i] = ckalloc(len);
    + g_strlcpy(vals[i], *strs[i], len);
    }
    Tcl_LinkVar(handler->interp, name->str,
    (char *)&vals[i], TCL_LINK_STRING);
    --- a/libpurple/prefs.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/prefs.c Fri Aug 12 21:41:34 2011 +0000
    @@ -277,6 +277,12 @@
    }
    }
    + if ((pref_type == PURPLE_PREF_BOOLEAN || pref_type == PURPLE_PREF_INT) &&
    + pref_value == NULL) {
    + /* Missing a value attribute */
    + return;
    + }
    +
    if(purple_strequal(element_name, "item")) {
    struct purple_pref *pref;
    --- a/libpurple/protocols/gg/gg.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/protocols/gg/gg.c Fri Aug 12 21:41:34 2011 +0000
    @@ -918,6 +918,9 @@
    PurpleBuddy *buddy;
    gpointer buddy_icon_data;
    + purple_debug_info("gg", "gg_fetch_avatar_cb: got avatar image for %s\n",
    + d->uin);
    +
    /* FIXME: This shouldn't be necessary */
    if (!PURPLE_CONNECTION_IS_VALID(d->gc)) {
    g_free(d->uin);
    @@ -936,7 +939,8 @@
    purple_buddy_icons_set_for_user(account, purple_buddy_get_name(buddy),
    buddy_icon_data, len, d->avatar_url);
    - purple_debug_info("gg", "UIN: %s should have avatar now\n", d->uin);
    + purple_debug_info("gg", "gg_fetch_avatar_cb: UIN %s should have avatar "
    + "now\n", d->uin);
    out:
    g_free(d->uin);
    @@ -1018,6 +1022,8 @@
    data->uin = g_strdup(uin);
    data->avatar_url = g_strdup(bigavatar);
    + purple_debug_info("gg", "gg_get_avatar_url_cb: "
    + "requesting avatar for %s\n", uin);
    url_data = purple_util_fetch_url_request_len_with_account(account,
    bigavatar, TRUE, "Mozilla/4.0 (compatible; MSIE 5.0)",
    FALSE, NULL, FALSE, -1, gg_fetch_avatar_cb, data);
    --- a/libpurple/protocols/gg/lib/libgadu.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/protocols/gg/lib/libgadu.c Fri Aug 12 21:41:34 2011 +0000
    @@ -893,8 +893,7 @@
    gnutls_global_init();
    gnutls_certificate_allocate_credentials(&tmp->xcred);
    gnutls_init(&tmp->session, GNUTLS_CLIENT);
    - gnutls_priority_set_direct(tmp->session, "NORMAL:-VERS-TLS", NULL);
    -// gnutls_priority_set_direct(tmp->session, "NONE:+VERS-SSL3.0:+AES-128-CBC:+RSA:+SHA1:+COMP-NULL", NULL);
    + gnutls_set_default_priority(tmp->session);
    gnutls_credentials_set(tmp->session, GNUTLS_CRD_CERTIFICATE, tmp->xcred);
    #elif defined(GG_CONFIG_HAVE_OPENSSL)
    char buf[1024];
    --- a/libpurple/protocols/irc/irc.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/protocols/irc/irc.c Fri Aug 12 21:41:34 2011 +0000
    @@ -251,7 +251,9 @@
    static void irc_who_channel(PurpleConversation *conv, struct irc_conn *irc)
    {
    - if (purple_conversation_get_account(conv) == irc->account && purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
    + if (purple_conversation_get_account(conv) == irc->account
    + && purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT
    + && !purple_conv_chat_has_left(PURPLE_CONV_CHAT(conv))) {
    char *buf = irc_format(irc, "vc", "WHO", purple_conversation_get_name(conv));
    purple_debug(PURPLE_DEBUG_INFO, "irc",
    --- a/libpurple/protocols/irc/parse.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/protocols/irc/parse.c Fri Aug 12 21:41:34 2011 +0000
    @@ -459,6 +459,7 @@
    decoded = g_string_append(decoded, "</U>");
    if (font)
    decoded = g_string_append(decoded, "</FONT>");
    + bold = italic = underline = font = FALSE;
    break;
    default:
    purple_debug(PURPLE_DEBUG_ERROR, "irc", "Unexpected mIRC formatting character %d\n", *cur);
    --- a/libpurple/protocols/jabber/jabber.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/protocols/jabber/jabber.c Fri Aug 12 21:41:34 2011 +0000
    @@ -199,7 +199,7 @@
    hostname, so maybe we want to detect that and use it
    instead
    */
    - strcpy(hostname, "localhost");
    + g_strlcpy(hostname, "localhost", sizeof(hostname));
    }
    hostname[sizeof(hostname) - 1] = '\0';
    @@ -3009,7 +3009,7 @@
    {
    JabberChat *chat = jabber_chat_find_by_conv(conv);
    GHashTable *components;
    - JabberID *jid;
    + JabberID *jid = NULL;
    const char *room = NULL, *server = NULL, *handle = NULL;
    if (!chat || !args || !args[0])
    @@ -3017,7 +3017,8 @@
    components = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
    - jid = jabber_id_new(args[0]);
    + if (strchr(args[0], '@'))
    + jid = jabber_id_new(args[0]);
    if (jid) {
    room = jid->node;
    server = jid->domain;
    @@ -3673,8 +3674,7 @@
    PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY |
    PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-jabber",
    jabber_cmd_chat_join,
    - _("join: &lt;room&gt; [password]: Join a chat on this server."),
    - /* _("join: &lt;room[@server]&gt; [password]: Join a chat."), */
    + _("join: &lt;room[@server]&gt; [password]: Join a chat."),
    NULL);
    commands = g_slist_prepend(commands, GUINT_TO_POINTER(id));
    --- a/libpurple/protocols/jabber/win32/posix.uname.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/protocols/jabber/win32/posix.uname.c Fri Aug 12 21:41:34 2011 +0000
    @@ -54,32 +54,32 @@
    GetVersionEx ( &OS_version );
    GetSystemInfo ( &System_Info );
    - strcpy( uts->sysname, "WIN32_" );
    + g_strlcpy( uts->sysname, "WIN32_" , sizeof(uts->sysname));
    switch( OS_version.dwPlatformId )
    {
    case VER_PLATFORM_WIN32_NT:
    - strcat( uts->sysname, "WinNT" );
    + g_strlcat( uts->sysname, "WinNT", sizeof(uts->sysname) );
    MingwOS = WinNT;
    break;
    case VER_PLATFORM_WIN32_WINDOWS:
    switch ( OS_version.dwMinorVersion )
    {
    case 0:
    - strcat( uts->sysname, "Win95" );
    + g_strlcat( uts->sysname, "Win95", sizeof(uts->sysname) );
    MingwOS = Win95;
    break;
    case 10:
    - strcat( uts->sysname, "Win98" );
    + g_strlcat( uts->sysname, "Win98", sizeof(uts->sysname) );
    MingwOS = Win98;
    break;
    default:
    - strcat( uts->sysname, "Win??" );
    + g_strlcat( uts->sysname, "Win??", sizeof(uts->sysname) );
    MingwOS = unknown;
    break;
    }
    break;
    default:
    - strcat( uts->sysname, "Win??" );
    + g_strlcat( uts->sysname, "Win??", sizeof(uts->sysname) );
    MingwOS = unknown;
    break;
    }
    @@ -92,13 +92,13 @@
    switch( System_Info.wProcessorArchitecture )
    {
    case PROCESSOR_ARCHITECTURE_PPC:
    - strcpy( uts->machine, "ppc" );
    + g_strlcpy( uts->machine, "ppc" , sizeof( uts->machine ) );
    break;
    case PROCESSOR_ARCHITECTURE_ALPHA:
    - strcpy( uts->machine, "alpha" );
    + g_strlcpy( uts->machine, "alpha" , sizeof( uts->machine ) );
    break;
    case PROCESSOR_ARCHITECTURE_MIPS:
    - strcpy( uts->machine, "mips" );
    + g_strlcpy( uts->machine, "mips" , sizeof( uts->machine ) );
    break;
    case PROCESSOR_ARCHITECTURE_INTEL:
    /* dwProcessorType is only valid in Win95 and Win98
    @@ -115,7 +115,7 @@
    sprintf( uts->machine, "i%ld", System_Info.dwProcessorType );
    break;
    default:
    - strcpy( uts->machine, "i386" );
    + g_strlcpy( uts->machine, "i386" , sizeof( uts->machine ) );
    break;
    }
    break;
    @@ -123,12 +123,12 @@
    sprintf( uts->machine, "i%d86", System_Info.wProcessorLevel );
    break;
    default:
    - strcpy( uts->machine, "unknown" );
    + g_strlcpy( uts->machine, "unknown" , sizeof( uts->machine ) );
    break;
    }
    break;
    default:
    - strcpy( uts->machine, "unknown" );
    + g_strlcpy( uts->machine, "unknown" , sizeof( uts->machine ) );
    break;
    }
    --- a/libpurple/protocols/msn/contact.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/protocols/msn/contact.c Fri Aug 12 21:41:34 2011 +0000
    @@ -474,7 +474,7 @@
    }
    /*parse contact list*/
    -static void
    +static gboolean
    msn_parse_contact_list(MsnSession *session, xmlnode *node)
    {
    xmlnode *fault, *faultnode;
    @@ -499,13 +499,14 @@
    if (g_str_equal(errorcode, "ABDoesNotExist")) {
    msn_create_address_book(session);
    g_free(errorcode);
    - return;
    + return FALSE;
    }
    g_free(errorcode);
    }
    msn_get_contact_list(session, MSN_PS_INITIAL, NULL);
    + return FALSE;
    } else {
    xmlnode *service;
    @@ -514,6 +515,7 @@
    service; service = xmlnode_get_next_twin(service)) {
    msn_parse_each_service(session, service);
    }
    + return TRUE;
    }
    }
    @@ -534,23 +536,24 @@
    purple_debug_misc("msn", "Got the contact list!\n");
    - msn_parse_contact_list(session, resp->xml);
    + if (msn_parse_contact_list(session, resp->xml)) {
    #ifdef MSN_PARTIAL_LISTS
    - abLastChange = purple_account_get_string(session->account,
    - "ablastChange", NULL);
    - dynamicItemLastChange = purple_account_get_string(session->account,
    - "DynamicItemLastChanged", NULL);
    + abLastChange = purple_account_get_string(session->account,
    + "ablastChange", NULL);
    + dynamicItemLastChange = purple_account_get_string(session->account,
    + "DynamicItemLastChanged", NULL);
    #endif
    - if (state->partner_scenario == MSN_PS_INITIAL) {
    + if (state->partner_scenario == MSN_PS_INITIAL) {
    #ifdef MSN_PARTIAL_LISTS
    - /* XXX: this should be enabled when we can correctly do partial
    - syncs with the server. Currently we need to retrieve the whole
    - list to detect sync issues */
    - msn_get_address_book(session, MSN_PS_INITIAL, abLastChange, dynamicItemLastChange);
    + /* XXX: this should be enabled when we can correctly do partial
    + syncs with the server. Currently we need to retrieve the whole
    + list to detect sync issues */
    + msn_get_address_book(session, MSN_PS_INITIAL, abLastChange, dynamicItemLastChange);
    #else
    - msn_get_address_book(session, MSN_PS_INITIAL, NULL, NULL);
    + msn_get_address_book(session, MSN_PS_INITIAL, NULL, NULL);
    #endif
    + }
    }
    }
    }
    --- a/libpurple/protocols/msn/msn.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/protocols/msn/msn.c Fri Aug 12 21:41:34 2011 +0000
    @@ -265,9 +265,9 @@
    }
    if (real_alias[0] == '\0')
    - strcpy(real_alias, purple_account_get_username(account));
    + g_strlcpy(real_alias, purple_account_get_username(account), sizeof(real_alias));
    } else
    - strcpy(real_alias, purple_account_get_username(account));
    + g_strlcpy(real_alias, purple_account_get_username(account), sizeof(real_alias));
    closure = g_new0(struct public_alias_closure, 1);
    closure->account = account;
    --- a/libpurple/protocols/msn/notification.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/protocols/msn/notification.c Fri Aug 12 21:41:34 2011 +0000
    @@ -198,6 +198,9 @@
    {
    /* RPS authentication */
    + if (session->nexus)
    + msn_nexus_destroy(session->nexus);
    +
    session->nexus = msn_nexus_new(session);
    session->nexus->policy = g_strdup(cmd->params[3]);
    --- a/libpurple/protocols/msn/session.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/protocols/msn/session.c Fri Aug 12 21:41:34 2011 +0000
    @@ -288,6 +288,8 @@
    msn_session_activate_login_timeout(MsnSession *session)
    {
    if (!session->logged_in && session->connected) {
    + if (session->login_timeout)
    + purple_timeout_remove(session->login_timeout);
    session->login_timeout =
    purple_timeout_add_seconds(MSN_LOGIN_FQY_TIMEOUT,
    msn_login_timeout_cb, session);
    --- a/libpurple/protocols/msn/slp.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/protocols/msn/slp.c Fri Aug 12 21:41:34 2011 +0000
    @@ -284,7 +284,6 @@
    purple_xfer_unref(xfer);
    slpmsg = msn_slpmsg_file_new(slpcall, purple_xfer_get_size(xfer));
    - msn_slpmsg_set_slplink(slpmsg, slpcall->slplink);
    msn_slplink_send_slpmsg(slpcall->slplink, slpmsg);
    }
    --- a/libpurple/protocols/msn/slpcall.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/protocols/msn/slpcall.c Fri Aug 12 21:41:34 2011 +0000
    @@ -490,12 +490,10 @@
    if (img != NULL) {
    /* DATA PREP */
    slpmsg = msn_slpmsg_dataprep_new(slpcall);
    - msn_slpmsg_set_slplink(slpmsg, slplink);
    msn_slplink_queue_slpmsg(slplink, slpmsg);
    /* DATA */
    slpmsg = msn_slpmsg_obj_new(slpcall, img);
    - msn_slpmsg_set_slplink(slpmsg, slplink);
    msn_slplink_queue_slpmsg(slplink, slpmsg);
    purple_imgstore_unref(img);
    --- a/libpurple/protocols/mxit/cipher.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/protocols/mxit/cipher.c Fri Aug 12 21:41:34 2011 +0000
    @@ -85,12 +85,12 @@
    pass[sizeof( pass ) - 1] = '\0';
    /* build the custom AES encryption key */
    - strcpy( key, INITIAL_KEY );
    + g_strlcpy( key, INITIAL_KEY, sizeof( key ) );
    memcpy( key, session->clientkey, strlen( session->clientkey ) );
    ExpandKey( (unsigned char*) key, (unsigned char*) exkey );
    /* build the custom data to be encrypted */
    - strcpy( pass, SECRET_HEADER );
    + g_strlcpy( pass, SECRET_HEADER, sizeof( pass ) );
    strcat( pass, session->acc->password );
    /* pad the secret data */
    --- a/libpurple/protocols/oscar/oscar.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/protocols/oscar/oscar.c Fri Aug 12 21:41:34 2011 +0000
    @@ -743,11 +743,15 @@
    gc->flags |= PURPLE_CONNECTION_HTML;
    if (oscar_util_valid_name_icq((purple_account_get_username(account)))) {
    od->icq = TRUE;
    - gc->flags |= PURPLE_CONNECTION_SUPPORT_MOODS;
    } else {
    gc->flags |= PURPLE_CONNECTION_AUTO_RESP;
    }
    + /* Set this flag based on the protocol_id rather than the username,
    + because that is what's tied to the get_moods prpl callback. */
    + if (g_str_equal(purple_account_get_protocol_id(account), "prpl-icq"))
    + gc->flags |= PURPLE_CONNECTION_SUPPORT_MOODS;
    +
    od->default_port = purple_account_get_int(account, "port", OSCAR_DEFAULT_LOGIN_PORT);
    encryption_type = purple_account_get_string(account, "encryption", OSCAR_DEFAULT_ENCRYPTION);
    @@ -5647,7 +5651,10 @@
    tmp1 = g_utf8_strdown(buf, -1);
    tmp2 = g_utf8_normalize(tmp1, -1, G_NORMALIZE_DEFAULT);
    - strcpy(buf, tmp2);
    + if (strlen(tmp2) > sizeof(buf) - 1) {
    + purple_debug_error("oscar", "normalized string exceeds buffer length!\n");
    + }
    + g_strlcpy(buf, tmp2, sizeof(buf));
    g_free(tmp2);
    g_free(tmp1);
    --- a/libpurple/protocols/sametime/sametime.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/protocols/sametime/sametime.c Fri Aug 12 21:41:34 2011 +0000
    @@ -922,6 +922,11 @@
    alias = mwSametimeGroup_getAlias(stgroup);
    type = mwSametimeGroup_getType(stgroup);
    + if (!name) {
    + DEBUG_WARN("Can't ensure a null group\n");
    + return NULL;
    + }
    +
    DEBUG_INFO("attempting to ensure group %s, called %s\n",
    NSTR(name), NSTR(alias));
    --- a/libpurple/protocols/simple/simple.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/protocols/simple/simple.c Fri Aug 12 21:41:34 2011 +0000
    @@ -1932,6 +1932,8 @@
    gc->proto_data = sip = g_new0(struct simple_account_data, 1);
    sip->gc = gc;
    + sip->fd = -1;
    + sip->listenfd = -1;
    sip->account = account;
    sip->registerexpire = 900;
    sip->udp = purple_account_get_bool(account, "udp", FALSE);
    --- a/libpurple/protocols/yahoo/libymsg.h Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/protocols/yahoo/libymsg.h Fri Aug 12 21:41:34 2011 +0000
    @@ -48,7 +48,7 @@
    #define YAHOO_ROOMLIST_LOCALE "us"
    /* Yahoo! JAPAN stuff */
    -#define YAHOOJP_PAGER_HOST_REQ_URL "http://cs1.msg.vip.ogk.yahoo.co.jp/capacity"
    +#define YAHOOJP_PAGER_HOST_REQ_URL "http://cs1.yahoo.co.jp/capacity"
    #define YAHOOJP_TOKEN_URL "https://login.yahoo.co.jp/config/pwtoken_get?src=ymsgr&ts=&login=%s&passwd=%s&chal=%s"
    #define YAHOOJP_LOGIN_URL "https://login.yahoo.co.jp/config/pwtoken_login?src=ymsgr&ts=&token=%s"
    #define YAHOOJP_PROFILE_URL "http://profiles.yahoo.co.jp/"
    --- a/libpurple/protocols/yahoo/yahoo_filexfer.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/protocols/yahoo/yahoo_filexfer.c Fri Aug 12 21:41:34 2011 +0000
    @@ -1428,7 +1428,7 @@
    unix_time = time(NULL);
    time_str = ctime(&unix_time);
    - strcpy(time_str + strlen(time_str) - 1, "\0");
    + time_str[strlen(time_str) - 1] = '\0';
    if (xd->txbuflen == 0) {
    xd->txbuf = g_strdup_printf("HTTP/1.0 200 OK\r\n"
    --- a/libpurple/protocols/zephyr/ZAsyncLocate.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/protocols/zephyr/ZAsyncLocate.c Fri Aug 12 21:41:34 2011 +0000
    @@ -18,6 +18,7 @@
    {
    int retval;
    ZNotice_t notice;
    + size_t userlen, versionlen;
    if (ZGetFD() < 0)
    if ((retval = ZOpenPort((unsigned short *)0)) != ZERR_NONE)
    @@ -37,16 +38,18 @@
    if ((retval = ZSendNotice(&notice, auth)) != ZERR_NONE)
    return(retval);
    - if ((zald->user = (char *) malloc(strlen(user)+1)) == NULL) {
    + userlen = strlen(user) + 1;
    + versionlen = strlen(notice.z_version) + 1;
    + if ((zald->user = (char *) malloc(userlen)) == NULL) {
    return(ENOMEM);
    }
    - if ((zald->version = (char *) malloc(strlen(notice.z_version)+1)) == NULL) {
    + if ((zald->version = (char *) malloc(versionlen)) == NULL) {
    free(zald->user);
    return(ENOMEM);
    }
    zald->uid = notice.z_multiuid;
    - strcpy(zald->user,user);
    - strcpy(zald->version,notice.z_version);
    + g_strlcpy(zald->user,user,userlen);
    + g_strlcpy(zald->version,notice.z_version,versionlen);
    return(ZERR_NONE);
    }
    @@ -109,35 +112,38 @@
    __locate_list[i].host = (char *) malloc(len);
    if (!__locate_list[i].host)
    return (ENOMEM);
    - (void) strcpy(__locate_list[i].host, ptr);
    + g_strlcpy(__locate_list[i].host, ptr,len);
    ptr += len;
    len = strlen (ptr) + 1;
    __locate_list[i].time = (char *) malloc(len);
    if (!__locate_list[i].time)
    return (ENOMEM);
    - (void) strcpy(__locate_list[i].time, ptr);
    + g_strlcpy(__locate_list[i].time, ptr,len);
    ptr += len;
    len = strlen (ptr) + 1;
    __locate_list[i].tty = (char *) malloc(len);
    if (!__locate_list[i].tty)
    return (ENOMEM);
    - (void) strcpy(__locate_list[i].tty, ptr);
    + g_strlcpy(__locate_list[i].tty, ptr,len);
    ptr += len;
    }
    __locate_next = 0;
    *nlocs = __locate_num;
    if (user) {
    + size_t len;
    if (zald) {
    - if ((*user = (char *) malloc(strlen(zald->user)+1)) == NULL)
    + len = strlen(zald->user) + 1;
    + if ((*user = (char *) malloc(len)) == NULL)
    return(ENOMEM);
    - strcpy(*user,zald->user);
    + g_strlcpy(*user,zald->user,len);
    } else {
    - if ((*user = (char *) malloc(strlen(notice->z_class_inst)+1)) == NULL)
    + len = strlen(notice->z_class_inst) + 1;
    + if ((*user = (char *) malloc(len)) == NULL)
    return(ENOMEM);
    - strcpy(*user,notice->z_class_inst);
    + g_strlcpy(*user,notice->z_class_inst,len);
    }
    }
    return (ZERR_NONE);
    --- a/libpurple/protocols/zephyr/ZInit.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/protocols/zephyr/ZInit.c Fri Aug 12 21:41:34 2011 +0000
    @@ -101,14 +101,14 @@
    #ifdef ZEPHYR_USES_KERBEROS
    if (krealm) {
    - strcpy(__Zephyr_realm, krealm);
    + g_strlcpy(__Zephyr_realm, krealm, REALM_SZ);
    } else if ((krb_get_tf_fullname(TKT_FILE, d1, d2, __Zephyr_realm)
    != KSUCCESS) &&
    ((krbval = krb_get_lrealm(__Zephyr_realm, 1)) != KSUCCESS)) {
    return (krbval);
    }
    #else
    - strcpy(__Zephyr_realm, "local-realm");
    + g_strlcpy(__Zephyr_realm, "local-realm", 12);
    #endif
    __My_addr.s_addr = INADDR_NONE;
    --- a/libpurple/protocols/zephyr/ZRetSubs.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/protocols/zephyr/ZRetSubs.c Fri Aug 12 21:41:34 2011 +0000
    @@ -141,32 +141,37 @@
    }
    for (ptr=retnotice.z_message,i = 0; i< __subscriptions_num; i++) {
    + size_t len;
    +
    + len = strlen(ptr) + 1;
    __subscriptions_list[i].zsub_class = (char *)
    - malloc((unsigned)strlen(ptr)+1);
    + malloc(len);
    if (!__subscriptions_list[i].zsub_class) {
    ZFreeNotice(&retnotice);
    return (ENOMEM);
    }
    - (void) strcpy(__subscriptions_list[i].zsub_class,ptr);
    - ptr += strlen(ptr)+1;
    + g_strlcpy(__subscriptions_list[i].zsub_class,ptr,len);
    + ptr += len;
    + len = strlen(ptr) + 1;
    __subscriptions_list[i].zsub_classinst = (char *)
    - malloc((unsigned)strlen(ptr)+1);
    + malloc(len);
    if (!__subscriptions_list[i].zsub_classinst) {
    ZFreeNotice(&retnotice);
    return (ENOMEM);
    }
    - (void) strcpy(__subscriptions_list[i].zsub_classinst,ptr);
    - ptr += strlen(ptr)+1;
    + g_strlcpy(__subscriptions_list[i].zsub_classinst,ptr,len);
    + ptr += len;
    ptr2 = ptr;
    if (!*ptr2)
    ptr2 = "*";
    + len = strlen(ptr2) + 1;
    __subscriptions_list[i].zsub_recipient = (char *)
    - malloc((unsigned)strlen(ptr2)+1);
    + malloc(len);
    if (!__subscriptions_list[i].zsub_recipient) {
    ZFreeNotice(&retnotice);
    return (ENOMEM);
    }
    - (void) strcpy(__subscriptions_list[i].zsub_recipient,ptr2);
    + g_strlcpy(__subscriptions_list[i].zsub_recipient,ptr2,len);
    ptr += strlen(ptr)+1;
    }
    ZFreeNotice(&retnotice);
    --- a/libpurple/protocols/zephyr/Zinternal.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/protocols/zephyr/Zinternal.c Fri Aug 12 21:41:34 2011 +0000
    @@ -677,7 +677,7 @@
    if (buffer_len < strlen(notice->z_version)+1)
    return (ZERR_HEADERLEN);
    - (void) strcpy(ptr, notice->z_version);
    + g_strlcpy(ptr, notice->z_version, buffer_len);
    ptr += strlen(ptr)+1;
    if (ZMakeAscii32(ptr, end-ptr, Z_NUMFIELDS + notice->z_num_other_fields)
    @@ -767,9 +767,9 @@
    if (*ptr+len > end)
    return 1;
    if (field)
    - (void) strcpy(*ptr, field);
    + g_strlcpy(*ptr, field, len);
    else
    - **ptr = '\0';
    + **ptr = '\0';
    *ptr += len;
    return 0;
    --- a/libpurple/protocols/zephyr/zephyr.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/protocols/zephyr/zephyr.c Fri Aug 12 21:41:34 2011 +0000
    @@ -2235,7 +2235,7 @@
    return NULL;
    }
    - strcpy(buf, tmp);
    + g_strlcpy(buf, tmp, sizeof(buf));
    g_free(tmp);
    return buf;
    --- a/libpurple/proxy.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/proxy.c Fri Aug 12 21:41:34 2011 +0000
    @@ -981,7 +981,7 @@
    hostname[sizeof(hostname) - 1] = '\0';
    if (ret < 0 || hostname[0] == '\0') {
    purple_debug_warning("proxy", "gethostname() failed -- is your hostname set?");
    - strcpy(hostname, "localhost");
    + g_strlcpy(hostname, "localhost", sizeof(hostname));
    }
    if (domain != NULL)
    @@ -1115,7 +1115,7 @@
    hostname[sizeof(hostname) - 1] = '\0';
    if (ret < 0 || hostname[0] == '\0') {
    purple_debug_warning("proxy", "gethostname() failed -- is your hostname set?");
    - strcpy(hostname, "localhost");
    + g_strlcpy(hostname, "localhost", sizeof(hostname));
    }
    t1 = g_strdup_printf("%s:%s",
    --- a/libpurple/stun.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/stun.c Fri Aug 12 21:41:34 2011 +0000
    @@ -226,7 +226,7 @@
    memcpy(&in.s_addr, tmp + 4, 4);
    ip = inet_ntoa(in);
    if(ip)
    - strcpy(nattype.publicip, ip);
    + g_strlcpy(nattype.publicip, ip, sizeof(nattype.publicip));
    }
    tmp += ntohs(attrib->len);
    --- a/libpurple/upnp.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/upnp.c Fri Aug 12 21:41:34 2011 +0000
    @@ -535,7 +535,7 @@
    dd->retry_count++;
    purple_upnp_discover_send_broadcast(dd);
    } else {
    - if (dd->fd)
    + if (dd->fd != -1)
    close(dd->fd);
    control_info.status = PURPLE_UPNP_STATUS_UNABLE_TO_DISCOVER;
    @@ -662,7 +662,7 @@
    }
    /* Set up the sockets */
    - sock = socket(AF_INET, SOCK_DGRAM, 0);
    + dd->fd = sock = socket(AF_INET, SOCK_DGRAM, 0);
    if(sock == -1) {
    purple_debug_error("upnp",
    "purple_upnp_discover(): Failed In sock creation\n");
    @@ -672,8 +672,6 @@
    return;
    }
    - dd->fd = sock;
    -
    /* TODO: Non-blocking! */
    if((hp = gethostbyname(HTTPMU_HOST_ADDRESS)) == NULL) {
    purple_debug_error("upnp",
    @@ -820,7 +818,7 @@
    static void
    looked_up_internal_ip_cb(gpointer data, gint source, const gchar *error_message)
    {
    - if (source) {
    + if (source != -1) {
    strncpy(control_info.internalip,
    purple_network_get_local_system_ip(source),
    sizeof(control_info.internalip));
    --- a/libpurple/win32/libc_interface.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/libpurple/win32/libc_interface.c Fri Aug 12 21:41:34 2011 +0000
    @@ -982,7 +982,7 @@
    if (strcmp(tzname, zonename) == 0)
    {
    /* Matched zone */
    - strcpy(localtzname, keyname);
    + g_strlcpy(localtzname, keyname, sizeof(localtzname));
    RegCloseKey(key);
    break;
    }
    @@ -997,7 +997,7 @@
    if (strcmp(tzname, zonename) == 0)
    {
    /* Matched DST zone */
    - strcpy(localtzname, keyname);
    + g_strlcpy(localtzname, keyname, sizeof(localtzname));
    RegCloseKey(key);
    break;
    }
    --- a/pidgin/gtkblist.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/pidgin/gtkblist.c Fri Aug 12 21:41:34 2011 +0000
    @@ -3647,6 +3647,7 @@
    { N_("/Help/_Build Information"), NULL, pidgin_dialogs_buildinfo, 0, "<Item>", NULL },
    { N_("/Help/_Debug Window"), NULL, toggle_debug, 0, "<Item>", NULL },
    { N_("/Help/De_veloper Information"), NULL, pidgin_dialogs_developers, 0, "<Item>", NULL },
    + { N_("/Help/_Plugin Information"), NULL, pidgin_dialogs_plugins_info, 0, "<Item>", NULL },
    { N_("/Help/_Translator Information"), NULL, pidgin_dialogs_translators, 0, "<Item>", NULL },
    { "/Help/sep2", NULL, NULL, 0, "<Separator>", NULL },
    { N_("/Help/_About"), NULL, pidgin_dialogs_about, 4, "<StockItem>", GTK_STOCK_ABOUT },
    --- a/pidgin/gtkdialogs.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/pidgin/gtkdialogs.c Fri Aug 12 21:41:34 2011 +0000
    @@ -31,6 +31,7 @@
    #include "debug.h"
    #include "notify.h"
    +#include "plugin.h"
    #include "prpl.h"
    #include "request.h"
    #include "util.h"
    @@ -787,6 +788,52 @@
    g_free(tmp);
    }
    +void pidgin_dialogs_plugins_info(void)
    +{
    + GString *str;
    + GList *l = NULL;
    + PurplePlugin *plugin = NULL;
    + char *title = g_strdup_printf(_("%s Plugin Information"), PIDGIN_NAME);
    + char *pname = NULL, *pauthor = NULL;
    + const char *pver, *pwebsite, *pid;
    + gboolean ploaded, punloadable;
    + static GtkWidget *plugins_info = NULL;
    +
    + str = g_string_sized_new(4096);
    +
    + g_string_append_printf(str, "<FONT SIZE=\"4\">%s</FONT><BR/>",
    + _("Plugin Information"));
    +
    + for(l = purple_plugins_get_all(); l; l = l->next) {
    + plugin = (PurplePlugin *)l->data;
    +
    + pname = g_markup_escape_text(purple_plugin_get_name(plugin), -1);
    + pauthor = g_markup_escape_text(purple_plugin_get_author(plugin), -1);
    + pver = purple_plugin_get_version(plugin);
    + pwebsite = purple_plugin_get_homepage(plugin);
    + pid = purple_plugin_get_id(plugin);
    + punloadable = purple_plugin_is_unloadable(plugin);
    + ploaded = purple_plugin_is_loaded(plugin);
    +
    + g_string_append_printf(str,
    + "<FONT SIZE=\"3\"><B>%s</B></FONT><BR/><FONT SIZE=\"2\">"
    + "\t<B>Author:</B> %s<BR/>\t<B>Version:</B> %s<BR/>"
    + "\t<B>Website:</B> %s<BR/>\t<B>ID String:</B> %s<BR/>"
    + "\t<B>Loadable:</B> %s<BR/>\t<B>Loaded:</B> %s<BR/>"
    + "<BR/></FONT>", pname, pauthor ? pauthor : "(null)",
    + pver, pwebsite, pid,
    + punloadable ? "<FONT COLOR=\"#FF0000\"><B>No</B></FONT>" : "Yes",
    + ploaded ? "Yes" : "No");
    + }
    +
    + plugins_info = pidgin_build_help_dialog(title, "plugins_info", str);
    + g_signal_connect(G_OBJECT(plugins_info), "destroy",
    + G_CALLBACK(gtk_widget_destroyed), &plugins_info);
    + g_free(title);
    + g_free(pname);
    + g_free(pauthor);
    +}
    +
    static void
    pidgin_dialogs_im_cb(gpointer data, PurpleRequestFields *fields)
    {
    --- a/pidgin/gtkdialogs.h Sat Jul 09 20:10:36 2011 +0000
    +++ b/pidgin/gtkdialogs.h Fri Aug 12 21:41:34 2011 +0000
    @@ -36,6 +36,7 @@
    void pidgin_dialogs_buildinfo(void);
    void pidgin_dialogs_developers(void);
    void pidgin_dialogs_translators(void);
    +void pidgin_dialogs_plugins_info(void);
    void pidgin_dialogs_im(void);
    void pidgin_dialogs_im_with_user(PurpleAccount *, const char *);
    void pidgin_dialogs_info(void);
    --- a/pidgin/gtkmedia.c Sat Jul 09 20:10:36 2011 +0000
    +++ b/pidgin/gtkmedia.c Fri Aug 12 21:41:34 2011 +0000
    @@ -538,12 +538,20 @@
    GdkWindow *window = NULL;
    if (data->participant == NULL)
    +#if GTK_CHECK_VERSION(2, 14, 0)
    window = gtk_widget_get_window(priv->local_video);
    +#else
    + window = (priv->local_video)->window;
    +#endif
    else {
    GtkWidget *widget = pidgin_media_get_widget(data->gtkmedia,
    data->session_id, data->participant);
    if (widget)
    +#if GTK_CHECK_VERSION(2, 14, 0)
    window = gtk_widget_get_window(widget);
    +#else
    + window = widget->window;
    +#endif
    }
    if (window) {
    --- a/po/ca.po Sat Jul 09 20:10:36 2011 +0000
    +++ b/po/ca.po Fri Aug 12 21:41:34 2011 +0000
    @@ -9,32 +9,30 @@
    # This file is distributed under the same license as the Pidgin package.
    #
    # There were translation notes here by Xan, (look in older CVS revisions),
    -# those notes have been replaced by the guidelines of Softcatalà:
    -# http://www.softcatala.org/projectes/eines/guiaestil/guiaestil.htm
    -# And the translation of related terms is here:
    -# http://www.softcatala.org/projectes/eines/recull/recull.htm
    -# We also use the officialy accepted neologisms from Termcat:
    -# http://www.termcat.net/cercaterm/
    +# those notes have been replaced by the guidelines [1] and the list of
    +# computer related terms [2] of Softcatalà. We also use the officialy
    +# accepted neologisms from Termcat [3].
    #
    # En Xan havia escrit uns apunts quant a la traducció (mireu versions antigues
    -# al CVS), els apunts s'han substituït per la guia d'estil de Softcatalà:
    -# http://www.softcatala.org/projectes/eines/guiaestil/guiaestil.htm
    -# També es fa servir el recull de termes de softcatalà per a la terminologia:
    -# http://www.softcatala.org/projectes/eines/recull/recull.htm
    -# així com les resolucions del Termcat quant als neologismes (que tenen
    -# preferència en cas de contradicció amb el recull de Softcatalà):
    -# http://www.termcat.net/cercaterm/
    +# al CVS), els apunts s'han substituït per la guia d'estil [1] i el recull de
    +# termes [2] de Softcatalà, així com les resolucions del Termcat [3] quant als
    +# neologismes (que tenen preferència en cas de contradicció amb el recull de
    +# Softcatalà).
    #
    # NOTE: adjectives in catalan go [almost] always to the end, for instance:
    # NOTA: els adjectius en català acostumen a anar al final, per exemple:
    # "New file" --> "Fitxer nou"
    #
    +# [1] http://www.softcatala.org/wiki/Guia_d'estil/Guia_2010
    +# [2] http://www.softcatala.org/recull.html
    +# [3] http://www.termcat.net/cercaterm/
    +#
    msgid ""
    msgstr ""
    "Project-Id-Version: Pidgin\n"
    "Report-Msgid-Bugs-To: \n"
    -"POT-Creation-Date: 2011-05-07 10:31+0200\n"
    -"PO-Revision-Date: 2011-05-07 10:48+0200\n"
    +"POT-Creation-Date: 2011-08-11 20:14+0200\n"
    +"PO-Revision-Date: 2011-08-11 20:26+0200\n"
    "Last-Translator: Josep Puigdemont i Casamajó <josep.puigdemont@gmail.com>\n"
    "Language-Team: Catalan <tradgnome@softcatala.net>\n"
    "Language: ca\n"
    @@ -1707,6 +1705,7 @@
    msgid "Unknown"
    msgstr "Desconegut"
    +#. Changing this string? Look in add_purple_buddy_to_groups
    msgid "Buddies"
    msgstr "Amics"
    @@ -4778,8 +4777,8 @@
    msgid "invite &lt;user&gt; [message]: Invite a user to the room."
    msgstr "invite &lt;usuari&gt; [sala]: convida un usuari a la sala."
    -msgid "join: &lt;room&gt; [password]: Join a chat on this server."
    -msgstr "join: &lt;sala&gt; [contrasenya]: entra en un xat d'aquest servidor."
    +msgid "join: &lt;room[@server]&gt; [password]: Join a chat."
    +msgstr "join: &lt;sala[@servidor]&gt; [contrasenya]: entra en un xat."
    msgid "kick &lt;user&gt; [reason]: Kick a user from the room."
    msgstr "kick &lt;usuari&gt; [motiu]: fa fora de la sala un usuari."
    @@ -6344,12 +6343,16 @@
    msgstr "On visc"
    #, c-format
    -msgid "You have %i suggested friends."
    -msgstr "Teniu %i suggeriments d'amics."
    -
    -#, c-format
    -msgid "We found %i contacts that match your search."
    -msgstr "Hem trobat %i contactes que coincideixen amb la cerca."
    +msgid "You have %i suggested friend."
    +msgid_plural "You have %i suggested friends."
    +msgstr[0] "Se us ha suggerit %i amic."
    +msgstr[1] "Se us han suggerit %i amics."
    +
    +#, c-format
    +msgid "We found %i contact that matches your search."
    +msgid_plural "We found %i contacts that match your search."
    +msgstr[0] "S'ha trobat %i contacte que coincideix amb la cerca."
    +msgstr[1] "S'han trobat %i contactes que coincideixen amb la cerca."
    #. we must have lost the connection, so terminate it so that we can reconnect
    msgid "We have lost the connection to MXit. Please reconnect."
    @@ -11076,6 +11079,9 @@
    msgid "/Help/De_veloper Information"
    msgstr "/Ajuda/Informació sobre els d_esenvolupadors"
    +msgid "/Help/_Plugin Information"
    +msgstr "/Ajuda/Informació sobre els _controladors"
    +
    msgid "/Help/_Translator Information"
    msgstr "/Ajuda/Informació sobre els _traductors"
    @@ -11367,7 +11373,7 @@
    msgstr "Aconsegueix el missatge d'absència"
    msgid "Last Said"
    -msgstr "El darrer que es digué"
    +msgstr "El darrer que digué"
    msgid "Unable to save icon file to disk."
    msgstr "No s'ha pogut desar el fitxer de la icona al disc."
    @@ -11702,10 +11708,6 @@
    msgid "artist"
    msgstr "artista"
    -#. feel free to not translate this
    -msgid "Ka-Hing Cheung"
    -msgstr "Ka-Hing Cheung"
    -
    msgid "voice and video"
    msgstr "veu i vídeo"
    @@ -11718,6 +11720,10 @@
    msgid "win32 port"
    msgstr "adaptació a win32"
    +#. feel free to not translate this
    +msgid "Ka-Hing Cheung"
    +msgstr "Ka-Hing Cheung"
    +
    msgid "maintainer"
    msgstr "mantenidor"
    @@ -11838,6 +11844,9 @@
    msgid "Hindi"
    msgstr "Hindi"
    +msgid "Croatian"
    +msgstr "Croat"
    +
    msgid "Hungarian"
    msgstr "Hongarès"
    @@ -12085,6 +12094,13 @@
    msgid "%s Translator Information"
    msgstr "Informació sobre els traductors del %s"
    +#, c-format
    +msgid "%s Plugin Information"
    +msgstr "Informació sobre el connector %s"
    +
    +msgid "Plugin Information"
    +msgstr "Informació sobre el connector"
    +
    msgid "_Name"
    msgstr "_Nom"
    @@ -13062,6 +13078,13 @@
    msgid "F_lash window when IMs are received"
    msgstr "_Fes que la finestra faci un flaix quan hi arribin missatges"
    +msgid "Resize incoming custom smileys"
    +msgstr "Redimensiona les emoticones personalitzades rebudes"
    +
    +# He hagut de ser una mica flexible per mantenir-ho "curt"
    +msgid "Maximum size:"
    +msgstr "Mida màxima:"
    +
    msgid "Minimum input area height in lines:"
    msgstr "Alçada mínima en línies de l'àrea d'entrada:"
    @@ -13132,6 +13155,9 @@
    msgid "_UDP Port:"
    msgstr "Port _UDP:"
    +msgid "T_CP Port:"
    +msgstr "Port _TCP:"
    +
    msgid "Use_rname:"
    msgstr "Nom d'_usuari:"
    @@ -15514,9 +15540,6 @@
    #~ msgid "<b>IP</b>: %s<br>\n"
    #~ msgstr "<b>IP</b>: %s<br>\n"
    -#~ msgid "Login Information"
    -#~ msgstr "Informació de la connexió"
    -
    #~ msgid "<p><b>Original Author</b>:<br>\n"
    #~ msgstr "<p><b>Autor original</b>:<br>\n"
    --- a/po/de.po Sat Jul 09 20:10:36 2011 +0000
    +++ b/po/de.po Fri Aug 12 21:41:34 2011 +0000
    @@ -11,8 +11,8 @@
    msgstr ""
    "Project-Id-Version: de\n"
    "Report-Msgid-Bugs-To: \n"
    -"POT-Creation-Date: 2011-06-21 09:12+0200\n"
    -"PO-Revision-Date: 2011-06-21 09:11+0200\n"
    +"POT-Creation-Date: 2011-08-11 10:27+0200\n"
    +"PO-Revision-Date: 2011-08-11 10:12+0200\n"
    "Last-Translator: Björn Voigt <bjoern@cs.tu-berlin.de>\n"
    "Language-Team: German <de@li.org>\n"
    "Language: de\n"
    @@ -1959,7 +1959,7 @@
    msgstr "Unbekannter Grund"
    msgid "Aborting DNS lookup in Tor Proxy mode."
    -msgstr "DNS-Anfrage im Tor-Proxy-Modus abgebrochen"
    +msgstr "DNS-Anfrage im Tor-Proxy-Modus abgebrochen."
    #, c-format
    msgid ""
    @@ -4778,8 +4778,8 @@
    msgstr ""
    "invite &lt;Benutzer&gt; [Nachricht]: Lade einen Benutzer in den Raum ein."
    -msgid "join: &lt;room&gt; [password]: Join a chat on this server."
    -msgstr "join: &lt;Raum&gt; [Passwort]: Betrete einen Chat auf diesem Server."
    +msgid "join: &lt;room[@server]&gt; [password]: Join a chat."
    +msgstr "join: &lt;Raum[@Server]&gt; [Passwort]: Betrete einen Chat."
    msgid "kick &lt;user&gt; [reason]: Kick a user from the room."
    msgstr "kick &lt;Benutzer&gt; [Grund]: Kickt einen Benutzer aus dem Raum."
    @@ -11134,6 +11134,9 @@
    msgid "/Help/De_veloper Information"
    msgstr "/Hilfe/_Entwickler-Informationen"
    +msgid "/Help/_Plugin Information"
    +msgstr "/Hilfe/_Plugin-Informationen"
    +
    msgid "/Help/_Translator Information"
    msgstr "/Hilfe/Über_setzer-Informationen"
    @@ -12149,6 +12152,13 @@
    msgid "%s Translator Information"
    msgstr "%s-Übersetzer-Informationen"
    +#, c-format
    +msgid "%s Plugin Information"
    +msgstr "%s Plugin-Informationen"
    +
    +msgid "Plugin Information"
    +msgstr "Plugin-Informationen"
    +
    msgid "_Name"
    msgstr "_Name"
    @@ -12750,7 +12760,7 @@
    #, c-format
    msgid "Exiting because another libpurple client is already running.\n"
    -msgstr "Wird geschlossen, da bereits ein anderer libpurple-Client läuft\n"
    +msgstr "Wird geschlossen, da bereits ein anderer libpurple-Client läuft.\n"
    msgid "_Media"
    msgstr "_Medien"
    @@ -13116,6 +13126,12 @@
    msgid "F_lash window when IMs are received"
    msgstr "Fenster b_linkt, wenn IM-Nachrichten empfangen werden"
    +msgid "Resize incoming custom smileys"
    +msgstr "Erhaltene benutzerdefinierte Smileys skalieren"
    +
    +msgid "Maximum size:"
    +msgstr "Maximale Größe:"
    +
    msgid "Minimum input area height in lines:"
    msgstr "Minimale Höhe des Eingabefeldes in Zeilen:"