Mercurial > pidgin
changeset 31372:17a4b32f4d46
propagate from branch 'im.pidgin.pidgin' (head 8480ab9498b0e22b164f3a40c100f59e2d6dd916)
to branch 'im.pidgin.pidgin.next.minor' (head 490036a7b4ce807cb851ded91af7d959fe1c029e)
author | Paul Aurich <paul@darkrain42.org> |
---|---|
date | Sun, 30 Jan 2011 17:52:06 +0000 |
parents | 28e27a37e4b4 (current diff) 24d62d6f72cc (diff) |
children | 6c660dc7cb6a |
files | ChangeLog configure.ac libpurple/mediamanager.c pidgin/gtkstatusbox.c pidgin/gtkutils.c |
diffstat | 54 files changed, 1278 insertions(+), 744 deletions(-) [+] |
line wrap: on
line diff
--- a/COPYRIGHT Sun Jan 09 04:40:07 2011 +0000 +++ b/COPYRIGHT Sun Jan 30 17:52:06 2011 +0000 @@ -81,6 +81,7 @@ Norbert Buchmuller Johannes Buchner Sean Burke +Gabriel Burt Thomas Butter Trevor Caira Andrea Canciani @@ -94,6 +95,7 @@ Matěj Cepl Cerulean Studios, LLC Jonathan Champ +Markos Chandras Matthew Chapman Christophe Chapuis Patrick Cheung @@ -130,6 +132,7 @@ Florian Delizy Jiri Denemark Vinicius Depizzol +Marc Dequènes Philip Derrin Taso N. Devetzis Balwinder Singh Dheeman @@ -579,6 +582,7 @@ Timmy Yee Li Yuan Yuriy Yevgrafov +Jan Zachorowski Nickolai Zeldovich Tom Zickel Marco Ziech
--- a/ChangeLog Sun Jan 09 04:40:07 2011 +0000 +++ b/ChangeLog Sun Jan 30 17:52:06 2011 +0000 @@ -15,8 +15,20 @@ number of times video must be scaled down, saving CPU time. (Jakub Adam) (half of #13095) * Starting multiple video calls and ending one no longer causes the other - calls to stop sending audio and video. (Jakub Adam) (#12758) - * Perl bindings now respect LDFLAGS. (Peter Volkov) (#12638) + calls to stop sending audio and video. (Jakub Adam) (#12758, #13237) + * Perl bindings now respect LDFLAGS. (Peter Volkov, Markos Chandras) + (#12638) + * Added AddTrust External Root CA. (#11554) + * Resolve some issues validating X.509 certificates signed off the CAcert + Class 3 intermediate cert when using the GnuTLS SSL/TLS plugin. + + Gadu-Gadu: + * Don't drop whole messages when text is colored. (Jan Zachorowski) + (#13259) + + Groupwise: + * Don't show two windows when using "Get Info" on a buddy. (Gabriel Burt; + Novell, Inc.) (#13108) IRC: * Don't send ISON messages longer than 512 bytes. (Jeffrey Honig) (#9692) @@ -25,6 +37,10 @@ * Stop sending audio when placing a call on hold. (Jakub Adam) (#13032) * Stop translating gpointers to ints in the dbus API. This removes functions from the dbus API. (The openSUSE Project) (#12507) + * Fix D-Bus introspection calls that omit the interface parameter. (Tom + Samstag) (#13073) + * Fixed bugs in purple_str_to_time() that caused the most recent 'make + check' failures. (Nader Morshed) (#13131) Pidgin: * Support using the Page Up and Page Down keys on the numeric keypad in @@ -35,6 +51,9 @@ Plugins: * The Voice/Video Settings plugin no longer resets selected devices to defaults. (Jakub Adam) (#13044) + * The Voice/Video Settings plugin no longer crashes when a stored device + name is not found in the list of available devices. (Jakub Adam) + (#13238) * The Autoaccept plugin now allows disabling filename escaping. (Rok Mandeljc) (half of #11459) * The Autoaccept plugin now allows choosing Reject/Ask/Accept for @@ -46,6 +65,8 @@ XMPP: * Don't crash when receiving an unexpected/invalid jingle transport type. (Nikita Kozlov) (#13136) + * Handle Connection: Close headers for BOSH, when the server does not + terminate the connection itself. (#13008) Yahoo!/Yahoo! JAPAN: * Fix a crash when an account disconnects before a p2p session is @@ -931,7 +952,7 @@ from you on MSN. * Support sending an invite message to buddies when requesting authorization from them on MSN. - * Timeout switchboard connections aggressively (60 seconds). + * Timeout switchboard connections after 60 seconds (msn-pecan devs). XMPP: * Voice & Video support with Jingle (XEP-0166, 0167, 0176, & 0177),
--- a/configure.ac Sun Jan 09 04:40:07 2011 +0000 +++ b/configure.ac Sun Jan 30 17:52:06 2011 +0000 @@ -2406,7 +2406,7 @@ AC_MSG_CHECKING(for me pot o' gold) AC_MSG_RESULT(no) -AC_CHECK_FUNCS(gethostid lrand48) +AC_CHECK_FUNCS(gethostid lrand48 timegm) AC_CHECK_FUNCS(memcpy memmove random strchr strerror vprintf) AC_CHECK_HEADERS(malloc.h paths.h sgtty.h stdarg.h sys/cdefs.h) AC_CHECK_HEADERS(sys/file.h sys/filio.h sys/ioctl.h sys/msgbuf.h)
--- a/libpurple/certificate.c Sun Jan 09 04:40:07 2011 +0000 +++ b/libpurple/certificate.c Sun Jan 30 17:52:06 2011 +0000 @@ -1602,7 +1602,7 @@ GSList *ca_crts, *cur; GByteArray *last_fpr, *ca_fpr; gboolean valid = FALSE; - gchar *ca_id; + gchar *ca_id, *ca2_id; peer_crt = (PurpleCertificate *) chain->data; @@ -1619,7 +1619,6 @@ return; } /* if (self signed) */ - /* Next, attempt to verify the last certificate against a CA */ ca = purple_certificate_find_pool(x509_tls_cached.scheme_name, "ca"); /* Next, check that the certificate chain is valid */ @@ -1669,6 +1668,9 @@ return; } /* if (signature chain not good) */ + /* Next, attempt to verify the last certificate is signed by a trusted + * CA, or is a trusted CA (based on fingerprint). + */ /* If, for whatever reason, there is no Certificate Authority pool loaded, we'll verify the subject name and then warn about thsi. */ if ( !ca ) { @@ -1684,27 +1686,31 @@ end_crt = g_list_last(chain)->data; - /* Attempt to look up the last certificate's issuer */ - ca_id = purple_certificate_get_issuer_unique_id(end_crt); + /* Attempt to look up the last certificate, and the last certificate's + * issuer. + */ + ca_id = purple_certificate_get_issuer_unique_id(end_crt); + ca2_id = purple_certificate_get_unique_id(end_crt); purple_debug_info("certificate/x509/tls_cached", "Checking for a CA with DN=%s\n", ca_id); - ca_crts = x509_ca_get_certs(ca_id); + purple_debug_info("certificate/x509/tls_cached", + "Also checking for a CA with DN=%s\n", + ca2_id); + ca_crts = g_slist_concat(x509_ca_get_certs(ca_id), x509_ca_get_certs(ca2_id)); + g_free(ca_id); + g_free(ca2_id); if ( NULL == ca_crts ) { flags |= PURPLE_CERTIFICATE_CA_UNKNOWN; purple_debug_warning("certificate/x509/tls_cached", - "Certificate Authority with DN='%s' not " - "found. I'll prompt the user, I guess.\n", - ca_id); - g_free(ca_id); + "No Certificate Authorities with either DN found " + "found. I'll prompt the user, I guess.\n"); x509_tls_cached_check_subject_name(vrq, flags); return; } - g_free(ca_id); - /* * Check the fingerprints; if they match, then this certificate *is* one * of the designated "trusted roots", and we don't need to verify the @@ -1714,10 +1720,6 @@ * * If the fingerprints don't match, we'll fall back to checking the * signature. - * - * GnuTLS doesn't seem to include the final root in the verification - * list, so this check will never succeed. NSS *does* include it in - * the list, so here we are. */ last_fpr = purple_certificate_get_fingerprint_sha1(end_crt); for (cur = ca_crts; cur; cur = cur->next) {
--- a/libpurple/dbus-analyze-signals.py Sun Jan 09 04:40:07 2011 +0000 +++ b/libpurple/dbus-analyze-signals.py Sun Jan 30 17:52:06 2011 +0000 @@ -32,7 +32,7 @@ continue signal = nameregex.sub(lambda x:x.group()[1].upper(), '-'+signal) - print "\"<signal name='%s'>\\n\""%signal + print "\" <signal name='%s'>\\n\""%signal args = marshal.split('_') # ['purple', 'marshal', <return type>, '', args...] @@ -52,9 +52,9 @@ type = 't' elif arg == "BOOLEAN": type = 'b' - print "\"<arg type='%s'/>\\n\""%type + print "\" <arg type='%s'/>\\n\""%type - print "\"</signal>\\n\"" + print "\" </signal>\\n\"" print ";"
--- a/libpurple/dbus-server.c Sun Jan 09 04:40:07 2011 +0000 +++ b/libpurple/dbus-server.c Sun Jan 30 17:52:06 2011 +0000 @@ -501,7 +501,9 @@ g_string_append(str, "<!DOCTYPE node PUBLIC '-//freedesktop//DTD D-BUS Object Introspection 1.0//EN' 'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>\n"); g_string_append_printf(str, "<node name='%s'>\n", DBUS_PATH_PURPLE); - g_string_append_printf(str, "<interface name='%s'>\n", DBUS_INTERFACE_PURPLE); + g_string_append(str, " <interface name='org.freedesktop.DBus.Introspectable'>\n <method name='Introspect'>\n <arg name='data' direction='out' type='s'/>\n </method>\n </interface>\n\n"); + + g_string_append_printf(str, " <interface name='%s'>\n", DBUS_INTERFACE_PURPLE); bindings_list = NULL; purple_signal_emit(purple_dbus_get_handle(), "dbus-introspect", &bindings_list); @@ -517,7 +519,7 @@ { const char *text; - g_string_append_printf(str, "<method name='%s'>\n", bindings[i].name); + g_string_append_printf(str, " <method name='%s'>\n", bindings[i].name); text = bindings[i].parameters; while (*text) @@ -529,10 +531,10 @@ name = dbus_gettext(&text); g_string_append_printf(str, - "<arg name='%s' type='%s' direction='%s'/>\n", + " <arg name='%s' type='%s' direction='%s'/>\n", name, type, direction); } - g_string_append(str, "</method>\n"); + g_string_append(str, " </method>\n"); } } @@ -549,7 +551,7 @@ } g_string_append(str, signals); - g_string_append(str, "</interface>\n</node>\n"); + g_string_append(str, " </interface>\n</node>\n"); reply = dbus_message_new_method_return(message); dbus_message_append_args(reply, DBUS_TYPE_STRING, &(str->str), @@ -568,10 +570,8 @@ "dbus-method-called", connection, message)) return DBUS_HANDLER_RESULT_HANDLED; - if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_CALL && - dbus_message_has_path(message, DBUS_PATH_PURPLE) && - dbus_message_has_interface(message, DBUS_INTERFACE_INTROSPECTABLE) && - dbus_message_has_member(message, "Introspect")) + if (dbus_message_is_method_call(message, DBUS_INTERFACE_INTROSPECTABLE, "Introspect") && + dbus_message_has_path(message, DBUS_PATH_PURPLE)) { DBusMessage *reply; reply = purple_dbus_introspect(message);
--- a/libpurple/media/backend-fs2.c Sun Jan 09 04:40:07 2011 +0000 +++ b/libpurple/media/backend-fs2.c Sun Jan 30 17:52:06 2011 +0000 @@ -155,6 +155,44 @@ { } +static gboolean +event_probe_cb(GstPad *srcpad, GstEvent *event, gboolean release_pad) +{ + if (GST_EVENT_TYPE(event) == GST_EVENT_CUSTOM_DOWNSTREAM + && gst_event_has_name(event, "purple-unlink-tee")) { + + const GstStructure *s = gst_event_get_structure(event); + + gst_pad_unlink(srcpad, gst_pad_get_peer(srcpad)); + + gst_pad_remove_event_probe(srcpad, + g_value_get_uint(gst_structure_get_value(s, "handler-id"))); + + if (g_value_get_boolean(gst_structure_get_value(s, "release-pad"))) + gst_element_release_request_pad(GST_ELEMENT_PARENT(srcpad), srcpad); + + return FALSE; + } + + return TRUE; +} + +static void +unlink_teepad_dynamic(GstPad *srcpad, gboolean release_pad) +{ + guint id = gst_pad_add_event_probe(srcpad, G_CALLBACK(event_probe_cb), NULL); + + if (GST_IS_GHOST_PAD(srcpad)) + srcpad = gst_ghost_pad_get_target(GST_GHOST_PAD(srcpad)); + + gst_element_send_event(gst_pad_get_parent_element(srcpad), + gst_event_new_custom(GST_EVENT_CUSTOM_DOWNSTREAM, + gst_structure_new("purple-unlink-tee", + "release-pad", G_TYPE_BOOLEAN, release_pad, + "handler-id", G_TYPE_UINT, id, + NULL))); +} + static void purple_media_backend_fs2_dispose(GObject *obj) { @@ -179,7 +217,7 @@ g_list_delete_link(sessions, sessions)) { PurpleMediaBackendFs2Session *session = sessions->data; if (session->srcpad) { - gst_pad_set_blocked(session->srcpad, TRUE); + unlink_teepad_dynamic(session->srcpad, FALSE); gst_object_unref(session->srcpad); session->srcpad = NULL; }
--- a/libpurple/mediamanager.c Sun Jan 09 04:40:07 2011 +0000 +++ b/libpurple/mediamanager.c Sun Jan 30 17:52:06 2011 +0000 @@ -400,7 +400,6 @@ GstIteratorResult result; gst_element_release_request_pad(GST_ELEMENT_PARENT(pad), pad); - gst_pad_set_blocked(pad, FALSE); iter = gst_element_iterate_src_pads(parent);
--- a/libpurple/protocols/gg/gg.c Sun Jan 09 04:40:07 2011 +0000 +++ b/libpurple/protocols/gg/gg.c Sun Jan 30 17:52:06 2011 +0000 @@ -1464,6 +1464,10 @@ increased_len += 4; under = FALSE; } + + if (actformat->font & GG_FONT_COLOR) { + cformats += sizeof(struct gg_msg_richtext_color); + } } msg = message->str;
--- a/libpurple/protocols/jabber/auth_cyrus.c Sun Jan 09 04:40:07 2011 +0000 +++ b/libpurple/protocols/jabber/auth_cyrus.c Sun Jan 30 17:52:06 2011 +0000 @@ -520,9 +520,12 @@ g_free(dec_in); if (js->sasl_state != SASL_OK) { - /* This should never happen! */ + /* This happens when the server sends back jibberish + * in the "additional data with success" case. + * Seen with Wildfire 3.0.1. + */ *error = g_strdup(_("Invalid response from server")); - g_return_val_if_reached(JABBER_SASL_STATE_FAIL); + return JABBER_SASL_STATE_FAIL; } }
--- a/libpurple/protocols/jabber/bosh.c Sun Jan 09 04:40:07 2011 +0000 +++ b/libpurple/protocols/jabber/bosh.c Sun Jan 30 17:52:06 2011 +0000 @@ -108,8 +108,27 @@ int requests; /* number of outstanding HTTP requests */ gboolean headers_done; + gboolean close; +}; -}; +static void +debug_dump_http_connections(PurpleBOSHConnection *conn) +{ + int i; + + g_return_if_fail(conn != NULL); + + for (i = 0; i < NUM_HTTP_CONNECTIONS; ++i) { + PurpleHTTPConnection *httpconn = conn->connections[i]; + if (httpconn == NULL) + purple_debug_misc("jabber", "BOSH %p->connections[%d] = (nil)\n", + conn, i); + else + purple_debug_misc("jabber", "BOSH %p->connections[%d] = %p, state = %d" + ", requests = %d\n", conn, i, httpconn, + httpconn->state, httpconn->requests); + } +} static void http_connection_connect(PurpleHTTPConnection *conn); static void http_connection_send_request(PurpleHTTPConnection *conn, @@ -263,18 +282,8 @@ { int i; - if (purple_debug_is_verbose()) { - for (i = 0; i < NUM_HTTP_CONNECTIONS; ++i) { - PurpleHTTPConnection *httpconn = conn->connections[i]; - if (httpconn == NULL) - purple_debug_misc("jabber", "BOSH %p->connections[%d] = (nil)\n", - conn, i); - else - purple_debug_misc("jabber", "BOSH %p->connections[%d] = %p, state = %d" - ", requests = %d\n", conn, i, httpconn, - httpconn->state, httpconn->requests); - } - } + if (purple_debug_is_verbose()) + debug_dump_http_connections(conn); /* Easy solution: Does everyone involved support pipelining? Hooray! Just use * one TCP connection! */ @@ -297,11 +306,23 @@ return NULL; } - /* Third loop, look for one that's NULL and create a new connection */ + /* Third loop, is something offline that we can connect? */ + for (i = 0; i < NUM_HTTP_CONNECTIONS; ++i) { + if (conn->connections[i] && + conn->connections[i]->state == HTTP_CONN_OFFLINE) { + purple_debug_info("jabber", "bosh: Reconnecting httpconn " + "(%i, %p)\n", i, conn->connections[i]); + http_connection_connect(conn->connections[i]); + return NULL; + } + } + + /* Fourth loop, look for one that's NULL and create a new connection */ for (i = 0; i < NUM_HTTP_CONNECTIONS; ++i) { if (!conn->connections[i]) { - purple_debug_info("jabber", "bosh: Creating and connecting new httpconn\n"); conn->connections[i] = jabber_bosh_http_connection_init(conn); + purple_debug_info("jabber", "bosh: Creating and connecting new httpconn " + "(%i, %p)\n", i, conn->connections[i]); http_connection_connect(conn->connections[i]); return NULL; @@ -444,6 +465,25 @@ send_timer_cb(bosh); } +static void +jabber_bosh_disable_pipelining(PurpleBOSHConnection *bosh) +{ + /* Do nothing if it's already disabled */ + if (!bosh->pipelining) + return; + + bosh->pipelining = FALSE; + if (bosh->connections[1] == NULL) { + bosh->connections[1] = jabber_bosh_http_connection_init(bosh); + http_connection_connect(bosh->connections[1]); + } else { + /* Shouldn't happen; this should be the only place pipelining + * is turned off. + */ + g_warn_if_reached(); + } +} + static void jabber_bosh_connection_received(PurpleBOSHConnection *conn, xmlnode *node) { xmlnode *child; JabberStream *js = conn->js; @@ -611,6 +651,8 @@ static void connection_common_established_cb(PurpleHTTPConnection *conn) { + purple_debug_misc("jabber", "bosh: httpconn %p re-connected\n", conn); + /* Indicate we're ready and reset some variables */ conn->state = HTTP_CONN_CONNECTED; if (conn->requests != 0) @@ -622,9 +664,13 @@ g_string_free(conn->read_buf, TRUE); conn->read_buf = NULL; } + conn->close = FALSE; conn->headers_done = FALSE; conn->handled_len = conn->body_len = 0; + if (purple_debug_is_verbose()) + debug_dump_http_connections(conn->bosh); + if (conn->bosh->js->reinit) jabber_bosh_connection_send(conn->bosh, PACKET_NORMAL, NULL); else if (conn->bosh->state == BOSH_CONN_ONLINE) { @@ -639,6 +685,7 @@ static void http_connection_disconnected(PurpleHTTPConnection *conn) { + gboolean had_requests = FALSE; /* * Well, then. Fine! I never liked you anyway, server! I was cheating on you * with AIM! @@ -662,7 +709,8 @@ conn->writeh = 0; } - if (conn->requests > 0 && conn->read_buf->len == 0) { + had_requests = (conn->requests > 0); + if (had_requests && conn->read_buf->len == 0) { purple_debug_error("jabber", "bosh: Adjusting BOSHconn requests (%d) to %d\n", conn->bosh->requests, conn->bosh->requests - conn->requests); conn->bosh->requests -= conn->requests; @@ -671,13 +719,15 @@ if (conn->bosh->pipelining) { /* Hmmmm, fall back to multiple connections */ - conn->bosh->pipelining = FALSE; - if (conn->bosh->connections[1] == NULL) { - conn->bosh->connections[1] = jabber_bosh_http_connection_init(conn->bosh); - http_connection_connect(conn->bosh->connections[1]); - } + jabber_bosh_disable_pipelining(conn->bosh); } + if (!had_requests) + /* If the server disconnected us without any requests, let's + * just wait until we have something to send before we reconnect + */ + return; + if (++conn->bosh->failed_connections == MAX_FAILED_CONNECTIONS) { purple_connection_error_reason(conn->bosh->js->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, @@ -704,30 +754,49 @@ cursor = conn->read_buf->str + conn->handled_len; + if (purple_debug_is_verbose()) + purple_debug_misc("jabber", "BOSH server sent: %s\n", cursor); + + /* TODO: Chunked encoding and check response version :/ */ if (!conn->headers_done) { - const char *content_length = purple_strcasestr(cursor, "\r\nContent-Length"); + const char *content_length = purple_strcasestr(cursor, "\r\nContent-Length:"); + const char *connection = purple_strcasestr(cursor, "\r\nConnection:"); const char *end_of_headers = strstr(cursor, "\r\n\r\n"); /* Make sure Content-Length is in headers, not body */ if (content_length && (!end_of_headers || content_length < end_of_headers)) { - const char *sep; int len; - if ((sep = strstr(content_length, ": ")) == NULL || - strstr(sep, "\r\n") == NULL) + if (strstr(content_length, "\r\n") == NULL) /* * The packet ends in the middle of the Content-Length line. * We'll try again later when we have more. */ return; - len = atoi(sep + 2); + len = atoi(content_length + strlen("\r\nContent-Length:")); if (len == 0) - purple_debug_warning("jabber", "Found mangled Content-Length header.\n"); + purple_debug_warning("jabber", "Found mangled Content-Length header, or server returned 0-length response.\n"); conn->body_len = len; } + if (connection && (!end_of_headers || content_length < end_of_headers)) { + const char *tmp; + if (strstr(connection, "\r\n") == NULL) + return; + + + tmp = connection + strlen("\r\nConnection:"); + while (*tmp && (*tmp == ' ' || *tmp == '\t')) + ++tmp; + + if (!g_ascii_strncasecmp(tmp, "close", strlen("close"))) { + conn->close = TRUE; + jabber_bosh_disable_pipelining(conn->bosh); + } + } + if (end_of_headers) { conn->headers_done = TRUE; conn->handled_len = end_of_headers - conn->read_buf->str + 4; @@ -752,6 +821,14 @@ http_received_cb(conn->read_buf->str + conn->handled_len, conn->body_len, conn->bosh); + /* Connection: Close? */ + if (conn->close && conn->state == HTTP_CONN_CONNECTED) { + if (purple_debug_is_verbose()) + purple_debug_misc("jabber", "bosh (%p), server sent Connection: " + "close\n", conn); + http_connection_disconnected(conn); + } + if (conn->bosh->state == BOSH_CONN_ONLINE && (conn->bosh->requests == 0 || conn->bosh->pending->bufused > 0)) { purple_debug_misc("jabber", "BOSH: Sending an empty request\n"); @@ -791,10 +868,11 @@ if (cnt == 0 || (cnt < 0 && errno != EAGAIN)) { if (cnt < 0) - purple_debug_info("jabber", "bosh read=%d, errno=%d, error=%s\n", - cnt, errno, g_strerror(errno)); + purple_debug_info("jabber", "BOSH (%p) read=%d, errno=%d, error=%s\n", + conn, cnt, errno, g_strerror(errno)); else - purple_debug_info("jabber", "bosh server closed the connection\n"); + purple_debug_info("jabber", "BOSH server closed the connection (%p)\n", + conn); /* * If the socket is closed, the processing really needs to know about @@ -911,6 +989,9 @@ else ret = write(conn->fd, data, len); + if (purple_debug_is_verbose()) + purple_debug_misc("jabber", "BOSH (%p): wrote %d bytes\n", conn, ret); + return ret; } @@ -975,7 +1056,10 @@ if (purple_debug_is_unsafe() && purple_debug_is_verbose()) /* Will contain passwords for SASL PLAIN and is verbose */ - purple_debug_misc("jabber", "BOSH: Sending %s\n", data); + purple_debug_misc("jabber", "BOSH (%p): Sending %s\n", conn, data); + else if (purple_debug_is_verbose()) + purple_debug_misc("jabber", "BOSH (%p): Sending request of " + "%" G_GSIZE_FORMAT " bytes.\n", conn, len); if (conn->writeh == 0) ret = http_connection_do_send(conn, data, len);
--- a/libpurple/protocols/msn/directconn.c Sun Jan 09 04:40:07 2011 +0000 +++ b/libpurple/protocols/msn/directconn.c Sun Jan 30 17:52:06 2011 +0000 @@ -539,13 +539,11 @@ msn_dc_enqueue_part(MsnDirectConn *dc, MsnSlpMessagePart *part) { MsnDirectConnPacket *p; - guint32 length; + size_t length; - length = part->size + P2P_PACKET_HEADER_SIZE; - p = msn_dc_new_packet(length); - - memcpy(p->data, part->header, P2P_PACKET_HEADER_SIZE); - memcpy(p->data + P2P_PACKET_HEADER_SIZE, part->buffer, part->size); + p = msn_dc_new_packet(0); + p->data = (guchar *)msn_slpmsgpart_serialize(part, &length); + p->length = length - P2P_PACKET_FOOTER_SIZE; /* DC doesn't need footer? */ p->sent_cb = msn_dc_send_packet_cb; p->part = msn_slpmsgpart_ref(part);
--- a/libpurple/protocols/msn/error.c Sun Jan 09 04:40:07 2011 +0000 +++ b/libpurple/protocols/msn/error.c Sun Jan 30 17:52:06 2011 +0000 @@ -31,7 +31,7 @@ typedef struct { - PurpleConnection *gc; + MsnSession *session; char *who; char *group; gboolean add; @@ -293,9 +293,9 @@ group = purple_find_group(data->group); if (group != NULL) - buddy = purple_find_buddy_in_group(purple_connection_get_account(data->gc), data->who, group); + buddy = purple_find_buddy_in_group(data->session->account, data->who, group); else - buddy = purple_find_buddy(purple_connection_get_account(data->gc), data->who); + buddy = purple_find_buddy(data->session->account, data->who); if (buddy != NULL) purple_blist_remove_buddy(buddy); @@ -309,14 +309,9 @@ /* this *should* be necessary !! */ msn_complete_sync_issue(data); #endif + MsnUserList *userlist = data->session->userlist; - if (g_list_find(purple_connections_get_all(), data->gc) != NULL) - { - MsnSession *session = data->gc->proto_data; - MsnUserList *userlist = session->userlist; - - msn_userlist_add_buddy(userlist, data->who, data->group); - } + msn_userlist_add_buddy(userlist, data->who, data->group); g_free(data->group); g_free(data->who); @@ -326,18 +321,14 @@ static void msn_rem_cb(MsnAddRemData *data) { + MsnUserList *userlist = data->session->userlist; msn_complete_sync_issue(data); - if (g_list_find(purple_connections_get_all(), data->gc) != NULL) - { - MsnSession *session = data->gc->proto_data; - MsnUserList *userlist = session->userlist; - if (data->group == NULL) { - msn_userlist_rem_buddy_from_list(userlist, data->who, MSN_LIST_FL); - } else { - g_free(data->group); - } + if (data->group == NULL) { + msn_userlist_rem_buddy_from_list(userlist, data->who, MSN_LIST_FL); + } else { + g_free(data->group); } g_free(data->who); @@ -356,10 +347,10 @@ account = session->account; gc = purple_account_get_connection(account); - data = g_new0(MsnAddRemData, 1); - data->who = g_strdup(passport); - data->group = g_strdup(group_name); - data->gc = gc; + data = g_new0(MsnAddRemData, 1); + data->who = g_strdup(passport); + data->group = g_strdup(group_name); + data->session = session; msg = g_strdup_printf(_("Buddy list synchronization issue in %s (%s)"), purple_account_get_username(account), @@ -382,7 +373,7 @@ } purple_request_action(gc, NULL, msg, reason, PURPLE_DEFAULT_ACTION_NONE, - purple_connection_get_account(gc), data->who, NULL, + account, data->who, NULL, data, 2, _("Yes"), G_CALLBACK(msn_add_cb), _("No"), G_CALLBACK(msn_rem_cb)); @@ -390,3 +381,4 @@ g_free(reason); g_free(msg); } +
--- a/libpurple/protocols/msn/msg.c Sun Jan 09 04:40:07 2011 +0000 +++ b/libpurple/protocols/msn/msg.c Sun Jan 30 17:52:06 2011 +0000 @@ -613,15 +613,7 @@ if (msg->msnslp_message) { - g_string_append_printf(str, "Session ID: %u\r\n", msg->part->header->session_id); - g_string_append_printf(str, "ID: %u\r\n", msg->part->header->id); - g_string_append_printf(str, "Offset: %" G_GUINT64_FORMAT "\r\n", msg->part->header->offset); - g_string_append_printf(str, "Total size: %" G_GUINT64_FORMAT "\r\n", msg->part->header->total_size); - g_string_append_printf(str, "Length: %u\r\n", msg->part->header->length); - g_string_append_printf(str, "Flags: 0x%x\r\n", msg->part->header->flags); - g_string_append_printf(str, "ACK ID: %u\r\n", msg->part->header->ack_id); - g_string_append_printf(str, "SUB ID: %u\r\n", msg->part->header->ack_sub_id); - g_string_append_printf(str, "ACK Size: %" G_GUINT64_FORMAT "\r\n", msg->part->header->ack_size); + msn_slpmsgpart_to_string(msg->part, str); if (purple_debug_is_verbose() && body != NULL) { @@ -638,27 +630,17 @@ else { int i; - int bin_len; - if (msg->part->footer->value == P2P_APPID_SESSION) - bin_len = P2P_PACKET_HEADER_SIZE; - else - bin_len = body_len; - - for (i = 0; i < bin_len; i++) + for (i = 0; i < body_len; i++) { g_string_append_printf(str, "%.2hhX ", body[i]); if ((i % 16) == 15) g_string_append(str, "\r\n"); } - if (bin_len == P2P_PACKET_HEADER_SIZE) - g_string_append_printf(str, "%s ", body + P2P_PACKET_HEADER_SIZE); g_string_append(str, "\r\n"); } } - - g_string_append_printf(str, "Footer: 0x%08X\r\n", msg->part->footer->value); } else {
--- a/libpurple/protocols/msn/msg.h Sun Jan 09 04:40:07 2011 +0000 +++ b/libpurple/protocols/msn/msg.h Sun Jan 30 17:52:06 2011 +0000 @@ -79,7 +79,6 @@ MsnMsgType type; gboolean msnslp_message; - MsnSlpMessage *slpmsg; MsnSlpMessagePart *part; char *remote_user; @@ -99,7 +98,6 @@ been ref'ed for using it in a callback. */ MsnCommand *cmd; - MsnTransaction *trans; MsnMsgCb ack_cb; /**< The callback to call when we receive an ACK of this message. */ @@ -107,8 +105,6 @@ message. */ void *ack_data; /**< The data used by callbacks. */ - MsnMsgErrorType error; /**< The error of the message. */ - guint32 retries; };
--- a/libpurple/protocols/msn/p2p.c Sun Jan 09 04:40:07 2011 +0000 +++ b/libpurple/protocols/msn/p2p.c Sun Jan 30 17:52:06 2011 +0000 @@ -27,12 +27,32 @@ #include "p2p.h" #include "msnutils.h" -MsnP2PHeader * -msn_p2p_header_from_wire(const char *wire) +MsnP2PInfo * +msn_p2p_info_new(void) +{ + return g_new0(MsnP2PInfo, 1); +} + +MsnP2PInfo * +msn_p2p_info_dup(MsnP2PInfo *info) +{ + MsnP2PInfo *new_info = g_new0(MsnP2PInfo, 1); + *new_info = *info; + return new_info; +} + +void +msn_p2p_info_free(MsnP2PInfo *info) +{ + g_free(info); +} + +size_t +msn_p2p_header_from_wire(MsnP2PInfo *info, const char *wire) { MsnP2PHeader *header; - header = g_new(MsnP2PHeader, 1); + header = &info->header; header->session_id = msn_pop32le(wire); header->id = msn_pop32le(wire); @@ -44,15 +64,17 @@ header->ack_sub_id = msn_pop32le(wire); header->ack_size = msn_pop64le(wire); - return header; + return P2P_PACKET_HEADER_SIZE; } char * -msn_p2p_header_to_wire(MsnP2PHeader *header) +msn_p2p_header_to_wire(MsnP2PInfo *info, size_t *len) { + MsnP2PHeader *header; char *wire; char *tmp; + header = &info->header; tmp = wire = g_new(char, P2P_PACKET_HEADER_SIZE); msn_push32le(tmp, header->session_id); @@ -65,35 +87,58 @@ msn_push32le(tmp, header->ack_sub_id); msn_push64le(tmp, header->ack_size); + if (len) + *len = P2P_PACKET_HEADER_SIZE; + return wire; } -MsnP2PFooter * -msn_p2p_footer_from_wire(const char *wire) +size_t +msn_p2p_footer_from_wire(MsnP2PInfo *info, const char *wire) { MsnP2PFooter *footer; - footer = g_new(MsnP2PFooter, 1); + footer = &info->footer; footer->value = msn_pop32be(wire); - return footer; + return P2P_PACKET_FOOTER_SIZE; } char * -msn_p2p_footer_to_wire(MsnP2PFooter *footer) +msn_p2p_footer_to_wire(MsnP2PInfo *info, size_t *len) { + MsnP2PFooter *footer; char *wire; char *tmp; + footer = &info->footer; tmp = wire = g_new(char, P2P_PACKET_FOOTER_SIZE); msn_push32be(tmp, footer->value); + if (len) + *len = P2P_PACKET_FOOTER_SIZE; + return wire; } +void +msn_p2p_info_to_string(MsnP2PInfo *info, GString *str) +{ + g_string_append_printf(str, "Session ID: %u\r\n", info->header.session_id); + g_string_append_printf(str, "ID: %u\r\n", info->header.id); + g_string_append_printf(str, "Offset: %" G_GUINT64_FORMAT "\r\n", info->header.offset); + g_string_append_printf(str, "Total size: %" G_GUINT64_FORMAT "\r\n", info->header.total_size); + g_string_append_printf(str, "Length: %u\r\n", info->header.length); + g_string_append_printf(str, "Flags: 0x%x\r\n", info->header.flags); + g_string_append_printf(str, "ACK ID: %u\r\n", info->header.ack_id); + g_string_append_printf(str, "SUB ID: %u\r\n", info->header.ack_sub_id); + g_string_append_printf(str, "ACK Size: %" G_GUINT64_FORMAT "\r\n", info->header.ack_size); + g_string_append_printf(str, "Footer: 0x%08X\r\n", info->footer.value); +} + gboolean msn_p2p_msg_is_data(const MsnP2PHeaderFlag flags) { @@ -102,3 +147,135 @@ flags == P2P_FILE_DATA); } +gboolean +msn_p2p_info_is_valid(MsnP2PInfo *info) +{ + return info->header.total_size >= info->header.length; +} + +gboolean +msn_p2p_info_is_final(MsnP2PInfo *info) +{ + return info->header.offset + info->header.length >= info->header.total_size; +} + +guint32 +msn_p2p_info_get_session_id(MsnP2PInfo *info) +{ + return info->header.session_id; +} + +guint32 +msn_p2p_info_get_id(MsnP2PInfo *info) +{ + return info->header.id; +} + +guint64 +msn_p2p_info_get_offset(MsnP2PInfo *info) +{ + return info->header.offset; +} + +guint64 +msn_p2p_info_get_total_size(MsnP2PInfo *info) +{ + return info->header.total_size; +} + +guint32 +msn_p2p_info_get_length(MsnP2PInfo *info) +{ + return info->header.length; +} + +guint32 +msn_p2p_info_get_flags(MsnP2PInfo *info) +{ + return info->header.flags; +} + +guint32 +msn_p2p_info_get_ack_id(MsnP2PInfo *info) +{ + return info->header.ack_id; +} + +guint32 +msn_p2p_info_get_ack_sub_id(MsnP2PInfo *info) +{ + return info->header.ack_sub_id; +} + +guint64 +msn_p2p_info_get_ack_size(MsnP2PInfo *info) +{ + return info->header.ack_size; +} + +guint32 +msn_p2p_info_get_app_id(MsnP2PInfo *info) +{ + return info->footer.value; +} + +void +msn_p2p_info_set_session_id(MsnP2PInfo *info, guint32 session_id) +{ + info->header.session_id = session_id; +} + +void +msn_p2p_info_set_id(MsnP2PInfo *info, guint32 id) +{ + info->header.id = id; +} + +void +msn_p2p_info_set_offset(MsnP2PInfo *info, guint64 offset) +{ + info->header.offset = offset; +} + +void +msn_p2p_info_set_total_size(MsnP2PInfo *info, guint64 total_size) +{ + info->header.total_size = total_size; +} + +void +msn_p2p_info_set_length(MsnP2PInfo *info, guint32 length) +{ + info->header.length = length; +} + +void +msn_p2p_info_set_flags(MsnP2PInfo *info, guint32 flags) +{ + info->header.flags = flags; +} + +void +msn_p2p_info_set_ack_id(MsnP2PInfo *info, guint32 ack_id) +{ + info->header.ack_id = ack_id; +} + +void +msn_p2p_info_set_ack_sub_id(MsnP2PInfo *info, guint32 ack_sub_id) +{ + info->header.ack_sub_id = ack_sub_id; +} + +void +msn_p2p_info_set_ack_size(MsnP2PInfo *info, guint64 ack_size) +{ + info->header.ack_size = ack_size; +} + +void +msn_p2p_info_set_app_id(MsnP2PInfo *info, guint32 app_id) +{ + info->footer.value = app_id; +} +
--- a/libpurple/protocols/msn/p2p.h Sun Jan 09 04:40:07 2011 +0000 +++ b/libpurple/protocols/msn/p2p.h Sun Jan 30 17:52:06 2011 +0000 @@ -58,6 +58,11 @@ } MsnP2PFooter; #define P2P_PACKET_FOOTER_SIZE (1 * 4) +typedef struct { + MsnP2PHeader header; + MsnP2PFooter footer; +} MsnP2PInfo; + typedef enum { P2P_NO_FLAG = 0x0, /**< No flags specified */ @@ -88,19 +93,98 @@ P2P_APPID_DISPLAY = 0xC /**< Display Image */ } MsnP2PAppId; -MsnP2PHeader * -msn_p2p_header_from_wire(const char *wire); +MsnP2PInfo * +msn_p2p_info_new(void); + +MsnP2PInfo * +msn_p2p_info_dup(MsnP2PInfo *info); + +void +msn_p2p_info_free(MsnP2PInfo *info); + +size_t +msn_p2p_header_from_wire(MsnP2PInfo *info, const char *wire); char * -msn_p2p_header_to_wire(MsnP2PHeader *header); +msn_p2p_header_to_wire(MsnP2PInfo *info, size_t *len); -MsnP2PFooter * -msn_p2p_footer_from_wire(const char *wire); +size_t +msn_p2p_footer_from_wire(MsnP2PInfo *info, const char *wire); char * -msn_p2p_footer_to_wire(MsnP2PFooter *footer); +msn_p2p_footer_to_wire(MsnP2PInfo *info, size_t *len); + +void +msn_p2p_info_to_string(MsnP2PInfo *info, GString *str); gboolean msn_p2p_msg_is_data(const MsnP2PHeaderFlag flags); +gboolean +msn_p2p_info_is_valid(MsnP2PInfo *info); + +gboolean +msn_p2p_info_is_final(MsnP2PInfo *info); + +guint32 +msn_p2p_info_get_session_id(MsnP2PInfo *info); + +guint32 +msn_p2p_info_get_id(MsnP2PInfo *info); + +guint64 +msn_p2p_info_get_offset(MsnP2PInfo *info); + +guint64 +msn_p2p_info_get_total_size(MsnP2PInfo *info); + +guint32 +msn_p2p_info_get_length(MsnP2PInfo *info); + +guint32 +msn_p2p_info_get_flags(MsnP2PInfo *info); + +guint32 +msn_p2p_info_get_ack_id(MsnP2PInfo *info); + +guint32 +msn_p2p_info_get_ack_sub_id(MsnP2PInfo *info); + +guint64 +msn_p2p_info_get_ack_size(MsnP2PInfo *info); + +guint32 +msn_p2p_info_get_app_id(MsnP2PInfo *info); + +void +msn_p2p_info_set_session_id(MsnP2PInfo *info, guint32 session_id); + +void +msn_p2p_info_set_id(MsnP2PInfo *info, guint32 id); + +void +msn_p2p_info_set_offset(MsnP2PInfo *info, guint64 offset); + +void +msn_p2p_info_set_total_size(MsnP2PInfo *info, guint64 total_size); + +void +msn_p2p_info_set_length(MsnP2PInfo *info, guint32 length); + +void +msn_p2p_info_set_flags(MsnP2PInfo *info, guint32 flags); + +void +msn_p2p_info_set_ack_id(MsnP2PInfo *info, guint32 ack_id); + +void +msn_p2p_info_set_ack_sub_id(MsnP2PInfo *info, guint32 ack_sub_id); + +void +msn_p2p_info_set_ack_size(MsnP2PInfo *info, guint64 ack_size); + +void +msn_p2p_info_set_app_id(MsnP2PInfo *info, guint32 app_id); + #endif /* MSN_P2P_H */ +
--- a/libpurple/protocols/msn/sbconn.c Sun Jan 09 04:40:07 2011 +0000 +++ b/libpurple/protocols/msn/sbconn.c Sun Jan 30 17:52:06 2011 +0000 @@ -126,8 +126,6 @@ trans->payload = payload; trans->payload_len = payload_len; - msg->trans = trans; - msn_cmdproc_send_trans(cmdproc, trans); }
--- a/libpurple/protocols/msn/slp.c Sun Jan 09 04:40:07 2011 +0000 +++ b/libpurple/protocols/msn/slp.c Sun Jan 30 17:52:06 2011 +0000 @@ -293,7 +293,7 @@ gen_context(PurpleXfer *xfer, const char *file_name, const char *file_path) { gsize size = 0; - MsnFileContext header; + MsnFileContext context; gchar *u8 = NULL; gchar *ret; gunichar2 *uni = NULL; @@ -323,28 +323,28 @@ preview = purple_xfer_get_thumbnail(xfer, &preview_len); - header.length = MSN_FILE_CONTEXT_SIZE; - header.version = 2; /* V.3 contains additional unnecessary data */ - header.file_size = size; + context.length = MSN_FILE_CONTEXT_SIZE; + context.version = 2; /* V.3 contains additional unnecessary data */ + context.file_size = size; if (preview) - header.type = 0; + context.type = 0; else - header.type = 1; + context.type = 1; len = MIN(len, MAX_FILE_NAME_LEN); for (currentChar = 0; currentChar < len; currentChar++) { - header.file_name[currentChar] = GUINT16_TO_LE(uni[currentChar]); + context.file_name[currentChar] = GUINT16_TO_LE(uni[currentChar]); } - memset(&header.file_name[currentChar], 0x00, (MAX_FILE_NAME_LEN - currentChar) * 2); + memset(&context.file_name[currentChar], 0x00, (MAX_FILE_NAME_LEN - currentChar) * 2); - memset(&header.unknown1, 0, sizeof(header.unknown1)); - header.unknown2 = 0xffffffff; + memset(&context.unknown1, 0, sizeof(context.unknown1)); + context.unknown2 = 0xffffffff; /* Mind the cast, as in, don't free it after! */ - header.preview = (char *)preview; - header.preview_len = preview_len; + context.preview = (char *)preview; + context.preview_len = preview_len; - u8 = msn_file_context_to_wire(&header); + u8 = msn_file_context_to_wire(&context); ret = purple_base64_encode((const guchar *)u8, MSN_FILE_CONTEXT_SIZE + preview_len); g_free(uni);
--- a/libpurple/protocols/msn/slpcall.c Sun Jan 09 04:40:07 2011 +0000 +++ b/libpurple/protocols/msn/slpcall.c Sun Jan 30 17:52:06 2011 +0000 @@ -511,7 +511,7 @@ /* File Transfer */ PurpleAccount *account; PurpleXfer *xfer; - MsnFileContext *header; + MsnFileContext *file_context; char *buf; gsize bin_len; guint32 file_size; @@ -528,12 +528,12 @@ slpcall->slplink->remote_user); buf = (char *)purple_base64_decode(context, &bin_len); - header = msn_file_context_from_wire(buf, bin_len); + file_context = msn_file_context_from_wire(buf, bin_len); - if (header != NULL) { - file_size = header->file_size; + if (file_context != NULL) { + file_size = file_context->file_size; - file_name = g_convert((const gchar *)&header->file_name, + file_name = g_convert((const gchar *)&file_context->file_name, MAX_FILE_NAME_LEN * 2, "UTF-8", "UTF-16LE", NULL, NULL, NULL); @@ -554,16 +554,16 @@ xfer->data = slpcall; - if (header->preview) { - purple_xfer_set_thumbnail(xfer, header->preview, - header->preview_len, + if (file_context->preview) { + purple_xfer_set_thumbnail(xfer, file_context->preview, + file_context->preview_len, "image/png"); - g_free(header->preview); + g_free(file_context->preview); } purple_xfer_request(xfer); } - g_free(header); + g_free(file_context); g_free(buf); accepted = TRUE; @@ -1059,16 +1059,21 @@ MsnSlpCall *slpcall; const guchar *body; gsize body_len; + guint32 session_id; + guint32 flags; slpcall = NULL; body = slpmsg->buffer; - body_len = slpmsg->header->offset; + body_len = msn_p2p_info_get_offset(slpmsg->p2p_info); - if (slpmsg->header->flags == P2P_NO_FLAG || slpmsg->header->flags == P2P_WLM2009_COMP) + session_id = msn_p2p_info_get_session_id(slpmsg->p2p_info); + flags = msn_p2p_info_get_flags(slpmsg->p2p_info); + + if (flags == P2P_NO_FLAG || flags == P2P_WLM2009_COMP) { char *body_str; - if (slpmsg->header->session_id == 64) + if (session_id == 64) { /* This is for handwritten messages (Ink) */ GError *error = NULL; @@ -1125,9 +1130,9 @@ } g_free(body_str); } - else if (msn_p2p_msg_is_data(slpmsg->header->flags)) + else if (msn_p2p_msg_is_data(flags)) { - slpcall = msn_slplink_find_slp_call_with_session_id(slplink, slpmsg->header->session_id); + slpcall = msn_slplink_find_slp_call_with_session_id(slplink, session_id); if (slpcall != NULL) { @@ -1142,22 +1147,13 @@ slpcall->wasted = TRUE; } } -#if 0 - else if (slpmsg->header->flags == 0x100) - { - slpcall = slplink->directconn->initial_call; - - if (slpcall != NULL) - msn_slpcall_session_init(slpcall); - } -#endif - else if (slpmsg->header->flags == P2P_ACK) + else if (flags == P2P_ACK) { /* Acknowledgement of previous message. Don't do anything currently. */ } else purple_debug_warning("msn", "Unprocessed SLP message with flags 0x%04x\n", - slpmsg->header->flags); + flags); return slpcall; }
--- a/libpurple/protocols/msn/slplink.c Sun Jan 09 04:40:07 2011 +0000 +++ b/libpurple/protocols/msn/slplink.c Sun Jan 30 17:52:06 2011 +0000 @@ -281,17 +281,21 @@ msn_slplink_send_msgpart(MsnSlpLink *slplink, MsnSlpMessage *slpmsg) { MsnSlpMessagePart *part; + MsnP2PInfo *info; long long real_size; size_t len = 0; + guint64 offset; /* Maybe we will want to create a new msg for this slpmsg instead of * reusing the same one all the time. */ - part = msn_slpmsgpart_new(slpmsg->header, slpmsg->footer); + info = slpmsg->p2p_info; + part = msn_slpmsgpart_new(info); part->ack_data = slpmsg; - real_size = (slpmsg->header->flags == P2P_ACK) ? 0 : slpmsg->size; + real_size = (msn_p2p_info_get_flags(info) == P2P_ACK) ? 0 : slpmsg->size; - if (slpmsg->header->offset < real_size) + offset = msn_p2p_info_get_offset(info); + if (offset < real_size) { if (slpmsg->slpcall && slpmsg->slpcall->xfer && purple_xfer_get_type(slpmsg->slpcall->xfer) == PURPLE_XFER_SEND && purple_xfer_get_status(slpmsg->slpcall->xfer) == PURPLE_XFER_STATUS_STARTED) @@ -301,15 +305,15 @@ } else { - len = slpmsg->size - slpmsg->header->offset; + len = slpmsg->size - offset; if (len > MSN_SBCONN_MAX_SIZE) len = MSN_SBCONN_MAX_SIZE; - msn_slpmsgpart_set_bin_data(part, slpmsg->buffer + slpmsg->header->offset, len); + msn_slpmsgpart_set_bin_data(part, slpmsg->buffer + offset, len); } - slpmsg->header->length = len; + msn_p2p_info_set_length(slpmsg->p2p_info, len); } #if 0 @@ -326,7 +330,7 @@ msn_slplink_send_part(slplink, part); - if (msn_p2p_msg_is_data(slpmsg->header->flags) && + if (msn_p2p_msg_is_data(msn_p2p_info_get_flags(info)) && (slpmsg->slpcall != NULL)) { slpmsg->slpcall->progress = TRUE; @@ -334,7 +338,7 @@ if (slpmsg->slpcall->progress_cb != NULL) { slpmsg->slpcall->progress_cb(slpmsg->slpcall, slpmsg->size, - len, slpmsg->header->offset); + len, offset); } } @@ -344,27 +348,30 @@ static void msn_slplink_release_slpmsg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg) { - slpmsg = slpmsg; - slpmsg->footer = g_new0(MsnP2PFooter, 1); + MsnP2PInfo *info; + guint32 flags; + + info = slpmsg->p2p_info; - if (slpmsg->header->flags == P2P_NO_FLAG) + flags = msn_p2p_info_get_flags(info); + if (flags == P2P_NO_FLAG) { - slpmsg->header->ack_id = rand() % 0xFFFFFF00; + msn_p2p_info_set_ack_id(info, rand() % 0xFFFFFF00); } - else if (msn_p2p_msg_is_data(slpmsg->header->flags)) + else if (msn_p2p_msg_is_data(flags)) { MsnSlpCall *slpcall; slpcall = slpmsg->slpcall; g_return_if_fail(slpcall != NULL); - slpmsg->header->session_id = slpcall->session_id; - slpmsg->footer->value = slpcall->app_id; - slpmsg->header->ack_id = rand() % 0xFFFFFF00; + msn_p2p_info_set_session_id(info, slpcall->session_id); + msn_p2p_info_set_app_id(info, slpcall->app_id); + msn_p2p_info_set_ack_id(info, rand() % 0xFFFFFF00); } - slpmsg->header->id = slpmsg->id; + msn_p2p_info_set_id(info, slpmsg->id); - slpmsg->header->total_size = slpmsg->size; + msn_p2p_info_set_total_size(info, slpmsg->size); msn_slplink_send_msgpart(slplink, slpmsg); } @@ -400,20 +407,20 @@ } static MsnSlpMessage * -msn_slplink_create_ack(MsnSlpLink *slplink, MsnP2PHeader *header) +msn_slplink_create_ack(MsnSlpLink *slplink, MsnP2PInfo *info) { MsnSlpMessage *slpmsg; - slpmsg = msn_slpmsg_ack_new(header); + slpmsg = msn_slpmsg_ack_new(info); msn_slpmsg_set_slplink(slpmsg, slplink); return slpmsg; } static void -msn_slplink_send_ack(MsnSlpLink *slplink, MsnP2PHeader *header) +msn_slplink_send_ack(MsnSlpLink *slplink, MsnP2PInfo *info) { - MsnSlpMessage *slpmsg = msn_slplink_create_ack(slplink, header); + MsnSlpMessage *slpmsg = msn_slplink_create_ack(slplink, info); msn_slplink_send_slpmsg(slplink, slpmsg); msn_slpmsg_destroy(slpmsg); @@ -428,7 +435,7 @@ { MsnSlpMessage *slpmsg = e->data; - if ((slpmsg->header->session_id == session_id) && (slpmsg->id == id)) + if ((msn_p2p_info_get_session_id(slpmsg->p2p_info) == session_id) && (slpmsg->id == id)) return slpmsg; } @@ -436,22 +443,26 @@ } static MsnSlpMessage * -init_first_msg(MsnSlpLink *slplink, MsnP2PHeader *header) +init_first_msg(MsnSlpLink *slplink, MsnP2PInfo *info) { MsnSlpMessage *slpmsg; + guint32 session_id; + guint32 flags; slpmsg = msn_slpmsg_new(slplink); - slpmsg->id = header->id; - slpmsg->header->session_id = header->session_id; - slpmsg->size = header->total_size; - slpmsg->header->flags = header->flags; + slpmsg->id = msn_p2p_info_get_id(info); + session_id = msn_p2p_info_get_session_id(info); + msn_p2p_info_set_session_id(slpmsg->p2p_info, session_id); + slpmsg->size = msn_p2p_info_get_total_size(info); + flags = msn_p2p_info_get_flags(info); + msn_p2p_info_set_flags(slpmsg->p2p_info, flags); - if (slpmsg->header->session_id) + if (session_id) { - slpmsg->slpcall = msn_slplink_find_slp_call_with_session_id(slplink, slpmsg->header->session_id); + slpmsg->slpcall = msn_slplink_find_slp_call_with_session_id(slplink, session_id); if (slpmsg->slpcall != NULL) { - if (msn_p2p_msg_is_data(header->flags)) + if (msn_p2p_msg_is_data(flags)) { PurpleXfer *xfer = slpmsg->slpcall->xfer; if (xfer != NULL) @@ -488,9 +499,10 @@ } static void -process_complete_msg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg, MsnP2PHeader *header) +process_complete_msg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg, MsnP2PInfo *info) { MsnSlpCall *slpcall; + guint32 flags; slpcall = msn_slp_process_msg(slplink, slpmsg); @@ -501,8 +513,10 @@ purple_debug_info("msn", "msn_slplink_process_msg: slpmsg complete\n"); - if (slpmsg->header->flags == P2P_NO_FLAG || slpmsg->header->flags == P2P_WLM2009_COMP || - msn_p2p_msg_is_data(slpmsg->header->flags)) + flags = msn_p2p_info_get_flags(slpmsg->p2p_info); + + if (flags == P2P_NO_FLAG || flags == P2P_WLM2009_COMP || + msn_p2p_msg_is_data(flags)) { /* Release all the messages and send the ACK */ @@ -515,11 +529,11 @@ */ purple_debug_info("msn", "msn_slplink_process_msg: save ACK\n"); - slpcall->slplink->dc->prev_ack = msn_slplink_create_ack(slplink, header); + slpcall->slplink->dc->prev_ack = msn_slplink_create_ack(slplink, info); } else if (!slpcall->wasted) { purple_debug_info("msn", "msn_slplink_process_msg: send ACK\n"); - msn_slplink_send_ack(slplink, header); + msn_slplink_send_ack(slplink, info); msn_slplink_send_queued_slpmsgs(slplink); } } @@ -539,16 +553,17 @@ purple_xfer_prpl_ready(slpmsg->slpcall->xfer); } else if (slpmsg->size && slpmsg->buffer) { - if (G_MAXSIZE - part->size < part->header->offset - || (part->header->offset + part->size) > slpmsg->size - || slpmsg->header->offset != part->header->offset) { + guint64 offset = msn_p2p_info_get_offset(part->info); + if (G_MAXSIZE - part->size < offset + || (offset + part->size) > slpmsg->size + || msn_p2p_info_get_offset(slpmsg->p2p_info) != offset) { purple_debug_error("msn", "Oversized slpmsg - msgsize=%lld offset=%" G_GUINT64_FORMAT " len=%" G_GSIZE_FORMAT "\n", - slpmsg->size, part->header->offset, part->size); + slpmsg->size, offset, part->size); g_return_if_reached(); } else { - memcpy(slpmsg->buffer + part->header->offset, part->buffer, part->size); - slpmsg->header->offset += part->size; + memcpy(slpmsg->buffer + offset, part->buffer, part->size); + msn_p2p_info_set_offset(slpmsg->p2p_info, offset + part->size); } } } @@ -557,12 +572,12 @@ msn_slplink_process_msg(MsnSlpLink *slplink, MsnSlpMessagePart *part) { MsnSlpMessage *slpmsg; - MsnP2PHeader *header; + MsnP2PInfo *info; guint64 offset; - header = part->header; + info = part->info; - if (header->total_size < header->length) + if (!msn_p2p_info_is_valid(info)) { /* We seem to have received a bad header */ purple_debug_warning("msn", "Total size listed in SLP binary header " @@ -571,12 +586,15 @@ return; } - offset = header->offset; + offset = msn_p2p_info_get_offset(info); if (offset == 0) - slpmsg = init_first_msg(slplink, header); + slpmsg = init_first_msg(slplink, info); else { - slpmsg = msn_slplink_message_find(slplink, header->session_id, header->id); + guint32 session_id, id; + session_id = msn_p2p_info_get_session_id(info); + id = msn_p2p_info_get_id(info); + slpmsg = msn_slplink_message_find(slplink, session_id, id); if (slpmsg == NULL) { /* Probably the transfer was cancelled */ @@ -587,8 +605,7 @@ slpmsg_add_part(slpmsg, part); - - if (msn_p2p_msg_is_data(slpmsg->header->flags) && + if (msn_p2p_msg_is_data(msn_p2p_info_get_flags(slpmsg->p2p_info)) && (slpmsg->slpcall != NULL)) { slpmsg->slpcall->progress = TRUE; @@ -606,8 +623,8 @@ #endif /* All the pieces of the slpmsg have been received */ - if (header->offset + header->length >= header->total_size) - process_complete_msg(slplink, slpmsg, header); + if (msn_p2p_info_is_final(info)) + process_complete_msg(slplink, slpmsg, info); /* NOTE: The slpmsg will be destroyed in process_complete_msg or left in the slplink until fully received. Don't free it here!
--- a/libpurple/protocols/msn/slpmsg.c Sun Jan 09 04:40:07 2011 +0000 +++ b/libpurple/protocols/msn/slpmsg.c Sun Jan 30 17:52:06 2011 +0000 @@ -48,8 +48,7 @@ else slpmsg->slplink = NULL; - slpmsg->header = g_new0(MsnP2PHeader, 1); - slpmsg->footer = NULL; + slpmsg->p2p_info = msn_p2p_info_new(); return slpmsg; } @@ -90,8 +89,7 @@ slplink->slp_msgs = g_list_remove(slplink->slp_msgs, slpmsg); - g_free(slpmsg->header); - g_free(slpmsg->footer); + msn_p2p_info_free(slpmsg->p2p_info); g_free(slpmsg); } @@ -193,7 +191,6 @@ slpmsg = msn_slpmsg_new(slplink); msn_slpmsg_set_body(slpmsg, body, body_len); - slpmsg->sip = TRUE; slpmsg->slpcall = slpcall; g_free(body); @@ -201,18 +198,20 @@ return slpmsg; } -MsnSlpMessage *msn_slpmsg_ack_new(MsnP2PHeader *header) +MsnSlpMessage *msn_slpmsg_ack_new(MsnP2PInfo *ack_info) { MsnSlpMessage *slpmsg; + MsnP2PInfo *new_info; slpmsg = msn_slpmsg_new(NULL); - slpmsg->header->session_id = header->session_id; - slpmsg->size = header->total_size; - slpmsg->header->flags = P2P_ACK; - slpmsg->header->ack_id = header->id; - slpmsg->header->ack_sub_id = header->ack_id; - slpmsg->header->ack_size = header->total_size; + new_info = slpmsg->p2p_info; + msn_p2p_info_set_session_id(new_info, msn_p2p_info_get_session_id(ack_info)); + slpmsg->size = msn_p2p_info_get_total_size(ack_info); + msn_p2p_info_set_flags(new_info, P2P_ACK); + msn_p2p_info_set_ack_id(new_info, msn_p2p_info_get_id(ack_info)); + msn_p2p_info_set_ack_sub_id(new_info, msn_p2p_info_get_ack_id(ack_info)); + msn_p2p_info_set_ack_size(new_info, msn_p2p_info_get_total_size(ack_info)); slpmsg->info = "SLP ACK"; return slpmsg; @@ -224,7 +223,7 @@ slpmsg = msn_slpmsg_new(NULL); slpmsg->slpcall = slpcall; - slpmsg->header->flags = P2P_MSN_OBJ_DATA; + msn_p2p_info_set_flags(slpmsg->p2p_info, P2P_MSN_OBJ_DATA); slpmsg->info = "SLP DATA"; msn_slpmsg_set_image(slpmsg, img); @@ -239,7 +238,7 @@ slpmsg = msn_slpmsg_new(NULL); slpmsg->slpcall = slpcall; - slpmsg->header->session_id = slpcall->session_id; + msn_p2p_info_set_session_id(slpmsg->p2p_info, slpcall->session_id); msn_slpmsg_set_body(slpmsg, NULL, 4); slpmsg->info = "SLP DATA PREP"; @@ -254,7 +253,7 @@ slpmsg = msn_slpmsg_new(NULL); slpmsg->slpcall = slpcall; - slpmsg->header->flags = P2P_FILE_DATA; + msn_p2p_info_set_flags(slpmsg->p2p_info, P2P_FILE_DATA); slpmsg->info = "SLP FILE"; slpmsg->size = size; @@ -267,27 +266,25 @@ char *footer; char *base; char *tmp; - size_t siz; + size_t header_size, footer_size; - base = g_malloc(P2P_PACKET_HEADER_SIZE + slpmsg->size + P2P_PACKET_FOOTER_SIZE); + header = msn_p2p_header_to_wire(slpmsg->p2p_info, &header_size); + footer = msn_p2p_footer_to_wire(slpmsg->p2p_info, &footer_size); + + base = g_malloc(header_size + slpmsg->size + footer_size); tmp = base; - header = msn_p2p_header_to_wire(slpmsg->header); - footer = msn_p2p_footer_to_wire(slpmsg->footer); - - siz = P2P_PACKET_HEADER_SIZE; /* Copy header */ - memcpy(tmp, header, siz); - tmp += siz; + memcpy(tmp, header, header_size); + tmp += header_size; /* Copy body */ memcpy(tmp, slpmsg->buffer, slpmsg->size); tmp += slpmsg->size; /* Copy footer */ - siz = P2P_PACKET_FOOTER_SIZE; - memcpy(tmp, footer, siz); - tmp += siz; + memcpy(tmp, footer, footer_size); + tmp += footer_size; *ret_size = tmp - base; @@ -303,15 +300,7 @@ str = g_string_new(NULL); - g_string_append_printf(str, "Session ID: %u\r\n", slpmsg->header->session_id); - g_string_append_printf(str, "ID: %u\r\n", slpmsg->header->id); - g_string_append_printf(str, "Offset: %" G_GUINT64_FORMAT "\r\n", slpmsg->header->offset); - g_string_append_printf(str, "Total size: %" G_GUINT64_FORMAT "\r\n", slpmsg->header->total_size); - g_string_append_printf(str, "Length: %u\r\n", slpmsg->header->length); - g_string_append_printf(str, "Flags: 0x%x\r\n", slpmsg->header->flags); - g_string_append_printf(str, "ACK ID: %u\r\n", slpmsg->header->ack_id); - g_string_append_printf(str, "SUB ID: %u\r\n", slpmsg->header->ack_sub_id); - g_string_append_printf(str, "ACK Size: %" G_GUINT64_FORMAT "\r\n", slpmsg->header->ack_size); + msn_p2p_info_to_string(slpmsg->p2p_info, str); if (purple_debug_is_verbose() && slpmsg->buffer != NULL) { g_string_append_len(str, (gchar*)slpmsg->buffer, slpmsg->size); @@ -324,7 +313,5 @@ } - g_string_append_printf(str, "Footer: %u\r\n", slpmsg->footer->value); - purple_debug_info("msn", "SlpMessage %s:\n{%s}\n", slpmsg->info, str->str); }
--- a/libpurple/protocols/msn/slpmsg.h Sun Jan 09 04:40:07 2011 +0000 +++ b/libpurple/protocols/msn/slpmsg.h Sun Jan 30 17:52:06 2011 +0000 @@ -45,13 +45,10 @@ MsnSlpLink *slplink; /**< The slplink through which this slp message is being sent. */ MsnSession *session; - MsnP2PHeader *header; - MsnP2PFooter *footer; + MsnP2PInfo *p2p_info; long id; - gboolean sip; /**< A flag that states if this is a SIP slp message. */ - gboolean ft; PurpleStoredImage *img; guchar *buffer; @@ -94,8 +91,6 @@ void msn_slpmsg_set_body(MsnSlpMessage *slpmsg, const char *body, long long size); void msn_slpmsg_set_image(MsnSlpMessage *slpmsg, PurpleStoredImage *img); -void msn_slpmsg_open_file(MsnSlpMessage *slpmsg, - const char *file_name); MsnSlpMessage * msn_slpmsg_sip_new(MsnSlpCall *slpcall, int cseq, const char *header, const char *branch, @@ -109,7 +104,7 @@ * * @return A new SlpMessage with ACK headers */ -MsnSlpMessage *msn_slpmsg_ack_new(MsnP2PHeader *header); +MsnSlpMessage *msn_slpmsg_ack_new(MsnP2PInfo *info); /** * Create a new SLP message for MsnObject data.
--- a/libpurple/protocols/msn/slpmsg_part.c Sun Jan 09 04:40:07 2011 +0000 +++ b/libpurple/protocols/msn/slpmsg_part.c Sun Jan 30 17:52:06 2011 +0000 @@ -28,16 +28,14 @@ #include "slpmsg.h" #include "slpmsg_part.h" -MsnSlpMessagePart *msn_slpmsgpart_new(MsnP2PHeader *header, MsnP2PFooter *footer) +MsnSlpMessagePart *msn_slpmsgpart_new(MsnP2PInfo *info) { MsnSlpMessagePart *part; part = g_new0(MsnSlpMessagePart, 1); - if (header) - part->header = g_memdup(header, P2P_PACKET_HEADER_SIZE); - if (footer) - part->footer = g_memdup(footer, P2P_PACKET_FOOTER_SIZE); + if (info) + part->info = msn_p2p_info_dup(info); part->ack_cb = msn_slpmsgpart_ack; part->nak_cb = msn_slpmsgpart_nak; @@ -48,20 +46,22 @@ MsnSlpMessagePart *msn_slpmsgpart_new_from_data(const char *data, size_t data_len) { MsnSlpMessagePart *part; + size_t len; int body_len; if (data_len < P2P_PACKET_HEADER_SIZE) { return NULL; } - part = msn_slpmsgpart_new(NULL, NULL); + part = msn_slpmsgpart_new(NULL); + part->info = msn_p2p_info_new(); /* Extract the binary SLP header */ - part->header = msn_p2p_header_from_wire(data); - data += P2P_PACKET_HEADER_SIZE; + len = msn_p2p_header_from_wire(part->info, data); + data += len; /* Extract the body */ - body_len = data_len - P2P_PACKET_HEADER_SIZE - P2P_PACKET_FOOTER_SIZE; + body_len = data_len - len - P2P_PACKET_FOOTER_SIZE; /* msg->body_len = msg->msnslp_header.length; */ if (body_len > 0) { @@ -73,15 +73,14 @@ /* Extract the footer */ if (body_len >= 0) - part->footer = msn_p2p_footer_from_wire(data); + msn_p2p_footer_from_wire(part->info, data); return part; } static void msn_slpmsgpart_destroy(MsnSlpMessagePart *part) { - g_free(part->header); - g_free(part->footer); + g_free(part->info); g_free(part->buffer); g_free(part); @@ -138,27 +137,25 @@ char *footer; char *base; char *tmp; - size_t siz; + size_t header_size, footer_size; - base = g_malloc(P2P_PACKET_HEADER_SIZE + part->size + P2P_PACKET_FOOTER_SIZE); + header = msn_p2p_header_to_wire(part->info, &header_size); + footer = msn_p2p_footer_to_wire(part->info, &footer_size); + + base = g_malloc(header_size + part->size + footer_size); tmp = base; - header = msn_p2p_header_to_wire(part->header); - footer = msn_p2p_footer_to_wire(part->footer); - - siz = P2P_PACKET_HEADER_SIZE; /* Copy header */ - memcpy(tmp, header, siz); - tmp += siz; + memcpy(tmp, header, header_size); + tmp += header_size; /* Copy body */ memcpy(tmp, part->buffer, part->size); tmp += part->size; /* Copy footer */ - siz = P2P_PACKET_FOOTER_SIZE; - memcpy(tmp, footer, siz); - tmp += siz; + memcpy(tmp, footer, footer_size); + tmp += footer_size; *ret_size = tmp - base; @@ -167,23 +164,27 @@ return base; } + /* We have received the message ack */ void msn_slpmsgpart_ack(MsnSlpMessagePart *part, void *data) { MsnSlpMessage *slpmsg; + guint64 offset; long long real_size; slpmsg = data; - real_size = (slpmsg->header->flags == P2P_ACK) ? 0 : slpmsg->size; + real_size = (msn_p2p_info_get_flags(slpmsg->p2p_info) == P2P_ACK) ? 0 : slpmsg->size; - slpmsg->header->offset += part->header->length; + offset = msn_p2p_info_get_offset(slpmsg->p2p_info); + offset += msn_p2p_info_get_length(part->info); + msn_p2p_info_set_offset(slpmsg->p2p_info, offset); slpmsg->parts = g_list_remove(slpmsg->parts, part); msn_slpmsgpart_unref(part); - if (slpmsg->header->offset < real_size) + if (offset < real_size) { if (slpmsg->slpcall->xfer && purple_xfer_get_status(slpmsg->slpcall->xfer) == PURPLE_XFER_STATUS_STARTED) { @@ -196,7 +197,7 @@ else { /* The whole message has been sent */ - if (msn_p2p_msg_is_data(slpmsg->header->flags)) + if (msn_p2p_msg_is_data(msn_p2p_info_get_flags(slpmsg->p2p_info))) { if (slpmsg->slpcall != NULL) { @@ -222,3 +223,9 @@ msn_slpmsgpart_unref(part); } +void +msn_slpmsgpart_to_string(MsnSlpMessagePart *part, GString *str) +{ + msn_p2p_info_to_string(part->info, str); +} +
--- a/libpurple/protocols/msn/slpmsg_part.h Sun Jan 09 04:40:07 2011 +0000 +++ b/libpurple/protocols/msn/slpmsg_part.h Sun Jan 30 17:52:06 2011 +0000 @@ -34,8 +34,7 @@ { guint ref_count; - MsnP2PHeader *header; - MsnP2PFooter *footer; + MsnP2PInfo *info; MsnSlpPartCb ack_cb; MsnSlpPartCb nak_cb; @@ -45,7 +44,7 @@ size_t size; }; -MsnSlpMessagePart *msn_slpmsgpart_new(MsnP2PHeader *header, MsnP2PFooter *footer); +MsnSlpMessagePart *msn_slpmsgpart_new(MsnP2PInfo *info); MsnSlpMessagePart *msn_slpmsgpart_new_from_data(const char *data, size_t data_len); @@ -60,4 +59,8 @@ void msn_slpmsgpart_ack(MsnSlpMessagePart *part, void *data); void msn_slpmsgpart_nak(MsnSlpMessagePart *part, void *data); + +void msn_slpmsgpart_to_string(MsnSlpMessagePart *part, GString *str); + #endif /* MSN_SLPMSG_PART_H */ +
--- a/libpurple/protocols/msn/xfer.c Sun Jan 09 04:40:07 2011 +0000 +++ b/libpurple/protocols/msn/xfer.c Sun Jan 30 17:52:06 2011 +0000 @@ -162,25 +162,25 @@ } gchar * -msn_file_context_to_wire(MsnFileContext *header) +msn_file_context_to_wire(MsnFileContext *context) { gchar *ret, *tmp; - tmp = ret = g_new(gchar, MSN_FILE_CONTEXT_SIZE + header->preview_len + 1); + tmp = ret = g_new(gchar, MSN_FILE_CONTEXT_SIZE + context->preview_len + 1); - msn_push32le(tmp, header->length); - msn_push32le(tmp, header->version); - msn_push64le(tmp, header->file_size); - msn_push32le(tmp, header->type); - memcpy(tmp, header->file_name, MAX_FILE_NAME_LEN * 2); + msn_push32le(tmp, context->length); + msn_push32le(tmp, context->version); + msn_push64le(tmp, context->file_size); + msn_push32le(tmp, context->type); + memcpy(tmp, context->file_name, MAX_FILE_NAME_LEN * 2); tmp += MAX_FILE_NAME_LEN * 2; - memcpy(tmp, header->unknown1, sizeof(header->unknown1)); - tmp += sizeof(header->unknown1); - msn_push32le(tmp, header->unknown2); - if (header->preview) { - memcpy(tmp, header->preview, header->preview_len); + memcpy(tmp, context->unknown1, sizeof(context->unknown1)); + tmp += sizeof(context->unknown1); + msn_push32le(tmp, context->unknown2); + if (context->preview) { + memcpy(tmp, context->preview, context->preview_len); } - tmp[header->preview_len] = '\0'; + tmp[context->preview_len] = '\0'; return ret; } @@ -188,48 +188,48 @@ MsnFileContext * msn_file_context_from_wire(const char *buf, gsize len) { - MsnFileContext *header; + MsnFileContext *context; if (!buf || len < MSN_FILE_CONTEXT_SIZE) return NULL; - header = g_new(MsnFileContext, 1); + context = g_new(MsnFileContext, 1); - header->length = msn_pop32le(buf); - header->version = msn_pop32le(buf); - if (header->version == 2) { + context->length = msn_pop32le(buf); + context->version = msn_pop32le(buf); + if (context->version == 2) { /* The length field is broken for this version. No check. */ - header->length = MSN_FILE_CONTEXT_SIZE; - } else if (header->version == 3) { - if (header->length != MSN_FILE_CONTEXT_SIZE + 63) { - g_free(header); + context->length = MSN_FILE_CONTEXT_SIZE; + } else if (context->version == 3) { + if (context->length != MSN_FILE_CONTEXT_SIZE + 63) { + g_free(context); return NULL; } else if (len < MSN_FILE_CONTEXT_SIZE + 63) { - g_free(header); + g_free(context); return NULL; } } else { - purple_debug_warning("msn", "Received MsnFileContext with unknown version: %d\n", header->version); - g_free(header); + purple_debug_warning("msn", "Received MsnFileContext with unknown version: %d\n", context->version); + g_free(context); return NULL; } - header->file_size = msn_pop64le(buf); - header->type = msn_pop32le(buf); - memcpy(header->file_name, buf, MAX_FILE_NAME_LEN * 2); + context->file_size = msn_pop64le(buf); + context->type = msn_pop32le(buf); + memcpy(context->file_name, buf, MAX_FILE_NAME_LEN * 2); buf += MAX_FILE_NAME_LEN * 2; - memcpy(header->unknown1, buf, sizeof(header->unknown1)); - buf += sizeof(header->unknown1); - header->unknown2 = msn_pop32le(buf); + memcpy(context->unknown1, buf, sizeof(context->unknown1)); + buf += sizeof(context->unknown1); + context->unknown2 = msn_pop32le(buf); - if (header->type == 0 && len > header->length) { - header->preview_len = len - header->length; - header->preview = g_memdup(buf, header->preview_len); + if (context->type == 0 && len > context->length) { + context->preview_len = len - context->length; + context->preview = g_memdup(buf, context->preview_len); } else { - header->preview_len = 0; - header->preview = NULL; + context->preview_len = 0; + context->preview = NULL; } - return header; + return context; }
--- a/libpurple/protocols/msn/xfer.h Sun Jan 09 04:40:07 2011 +0000 +++ b/libpurple/protocols/msn/xfer.h Sun Jan 30 17:52:06 2011 +0000 @@ -22,6 +22,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ +#ifndef MSN_XFER_H +#define MSN_XFER_H #include "slpcall.h" @@ -56,8 +58,10 @@ void msn_xfer_end_cb(MsnSlpCall *slpcall, MsnSession *session); gchar * -msn_file_context_to_wire(MsnFileContext *header); +msn_file_context_to_wire(MsnFileContext *context); MsnFileContext * msn_file_context_from_wire(const char *buf, gsize len); +#endif /* MSN_XFER_H */ +
--- a/libpurple/protocols/novell/novell.c Sun Jan 09 04:40:07 2011 +0000 +++ b/libpurple/protocols/novell/novell.c Sun Jan 30 17:52:06 2011 +0000 @@ -74,7 +74,7 @@ _sync_privacy_lists(NMUser *user); static void -_show_info(PurpleConnection * gc, NMUserRecord * user_record); +_show_info(PurpleConnection * gc, NMUserRecord * user_record, char * name); const char * _get_conference_name(int id); @@ -705,7 +705,7 @@ user_record = (NMUserRecord *) resp_data; if (user_record) { _show_info(purple_account_get_connection(user->client_data), - user_record); + user_record, g_strdup(name)); } } else { gc = purple_account_get_connection(user->client_data); @@ -1505,7 +1505,7 @@ /* Display a dialog box showing the properties for the given user record */ static void -_show_info(PurpleConnection * gc, NMUserRecord * user_record) +_show_info(PurpleConnection * gc, NMUserRecord * user_record, char * name) { PurpleNotifyUserInfo *user_info = purple_notify_user_info_new(); int count, i; @@ -1544,9 +1544,10 @@ } } - purple_notify_userinfo(gc, nm_user_record_get_userid(user_record), - user_info, NULL, NULL); + purple_notify_userinfo(gc, name, user_info, NULL, NULL); purple_notify_user_info_destroy(user_info); + + g_free(name); } /* Send a join conference, the first item in the parms list is the @@ -2912,11 +2913,9 @@ user_record = nm_find_user_record(user, name); if (user_record) { - - _show_info(gc, user_record); + _show_info(gc, user_record, g_strdup(name)); } else { - rc = nm_send_get_details(user, name, _get_details_resp_show_info, g_strdup(name));
--- a/libpurple/protocols/oscar/family_feedbag.c Sun Jan 09 04:40:07 2011 +0000 +++ b/libpurple/protocols/oscar/family_feedbag.c Sun Jan 30 17:52:06 2011 +0000 @@ -44,10 +44,66 @@ */ #include "oscar.h" +#include "debug.h" static int aim_ssi_addmoddel(OscarData *od); /** + * List types based on http://dev.aol.com/aim/oscar/#FEEDBAG (archive.org) + * and http://iserverd.khstu.ru/oscar/ssi_item.html + * + * @param type The type of a list item as integer number, as provided by an aim_ssi_item struct. + * @return Returns the name of the item type as a character string. + */ +static const gchar* +aim_ssi_type_to_string(guint16 type) +{ + struct TypeStringPair + { + guint16 type; + const gchar *string; + }; + static const struct TypeStringPair type_strings[] = { + { 0x0000, "Buddy" }, + { 0x0001, "Group" }, + { 0x0002, "Permit/Visible" }, + { 0x0003, "Deny/Invisible" }, + { 0x0004, "PDInfo" }, + { 0x0005, "PresencePrefs" }, + { 0x0006, "Non-Buddy Info" }, + { 0x0009, "ClientPrefs" }, + { 0x000e, "ICQDeny/Ignore" }, + { 0x0014, "Buddy Icon" }, + { 0x0015, "Recent Buddies" }, + { 0x0019, "Non-Buddy" }, + { 0x001d, "Vanity Info" }, + { 0x0020, "ICQ-MDir" }, + { 0x0029, "Facebook" }, + }; + int i; + for (i = 0; i < G_N_ELEMENTS(type_strings); i++) { + if (type_strings[i].type == type) { + return type_strings[i].string; + } + } + return "unknown"; +} + +/** For debug log output: Appends a line containing information about a given list item to a string. + * + * @param str String to which the line will be appended. + * @param prefix A string which will be prepended to the line. + * @param item List item from which information is extracted. + */ +static void +aim_ssi_item_debug_append(GString *str, char *prefix, struct aim_ssi_item *item) +{ + g_string_append_printf(str, + "%s gid=0x%04hx, bid=0x%04hx, list_type=0x%04hx [%s], name=%s.\n", + prefix, item->gid, item->bid, item->type, aim_ssi_type_to_string(item->type), item->name); +} + +/** * Locally rebuild the 0x00c8 TLV in the additional data of the given group. * * @param list A pointer to a pointer to the current list of items. @@ -478,6 +534,7 @@ struct aim_ssi_item *cur1, *cur2; struct aim_ssi_tmp *cur, *new; int n = 0; + GString *debugstr = g_string_new(""); /* * The variable "n" is used to limit the number of addmoddel's that @@ -517,6 +574,7 @@ cur->next = new; } else od->ssi.pending = new; + aim_ssi_item_debug_append(debugstr, "Deleting item ", cur1); } } } @@ -537,6 +595,7 @@ cur->next = new; } else od->ssi.pending = new; + aim_ssi_item_debug_append(debugstr, "Adding item ", cur1); } } } @@ -558,9 +617,21 @@ cur->next = new; } else od->ssi.pending = new; + aim_ssi_item_debug_append(debugstr, "Modifying item ", cur1); } } } + if (debugstr->len > 0) { + purple_debug_info("oscar", "%s", debugstr->str); + if (purple_debug_is_verbose()) { + g_string_truncate(debugstr, 0); + for (cur1 = od->ssi.local; cur1; cur1 = cur1->next) + aim_ssi_item_debug_append(debugstr, "\t", cur1); + purple_debug_misc("oscar", "Dumping item list of account %s:\n%s", + purple_connection_get_account(od->gc)->username, debugstr->str); + } + } + g_string_free(debugstr, TRUE); /* We're out of stuff to do, so tell the AIM servers we're done and exit */ if (!od->ssi.pending) { @@ -1165,6 +1236,7 @@ guint16 namelen, gid, bid, type; char *name; GSList *data; + GString *debugstr = g_string_new(""); fmtver = byte_stream_get8(bs); /* Version of ssi data. Should be 0x00 */ od->ssi.numitems += byte_stream_get16(bs); /* # of items in this SSI SNAC */ @@ -1179,10 +1251,13 @@ bid = byte_stream_get16(bs); type = byte_stream_get16(bs); data = aim_tlvlist_readlen(bs, byte_stream_get16(bs)); - aim_ssi_itemlist_add(&od->ssi.official, name, gid, bid, type, data); + aim_ssi_item_debug_append(debugstr, "\t", aim_ssi_itemlist_add(&od->ssi.official, name, gid, bid, type, data)); g_free(name); aim_tlvlist_free(data); } + purple_debug_misc("oscar", "Reading items from tlvlist for account %s:\n%s", + purple_connection_get_account(od->gc)->username, debugstr->str); + g_string_free(debugstr, TRUE); /* Read in the timestamp */ od->ssi.timestamp = byte_stream_get32(bs);
--- a/libpurple/protocols/zephyr/Zinternal.c Sun Jan 09 04:40:07 2011 +0000 +++ b/libpurple/protocols/zephyr/Zinternal.c Sun Jan 30 17:52:06 2011 +0000 @@ -30,7 +30,6 @@ #else #include <arpa/inet.h> #include <sys/socket.h> -#include <utmp.h> #endif int __Zephyr_fd = -1;
--- a/libpurple/protocols/zephyr/zephyr.c Sun Jan 09 04:40:07 2011 +0000 +++ b/libpurple/protocols/zephyr/zephyr.c Sun Jan 30 17:52:06 2011 +0000 @@ -870,12 +870,12 @@ zephyr_triple *zt1, *zt2; gchar *send_inst_utf8; zephyr_account *zephyr = gc->proto_data; - zt1 = new_triple(gc->proto_data,notice.z_class, notice.z_class_inst, notice.z_recipient); - zt2 = find_sub_by_triple(gc->proto_data,zt1); + zt1 = new_triple(zephyr,notice.z_class, notice.z_class_inst, notice.z_recipient); + zt2 = find_sub_by_triple(zephyr,zt1); if (!zt2) { /* This is a server supplied subscription */ zephyr->subscrips = g_slist_append(zephyr->subscrips, new_triple(zephyr,zt1->class,zt1->instance,zt1->recipient)); - zt2 = find_sub_by_triple(gc->proto_data,zt1); + zt2 = find_sub_by_triple(zephyr,zt1); } if (!zt2->open) { @@ -1499,6 +1499,7 @@ static void process_anyone(PurpleConnection *gc) { + zephyr_account *zephyr = purple_connection_get_protocol_data(gc); FILE *fd; gchar buff[BUFSIZ], *filename; PurpleGroup *g; @@ -1515,7 +1516,7 @@ strip_comments(buff); if (buff[0]) { if (!(b = purple_find_buddy(gc->account, buff))) { - char *stripped_user = zephyr_strip_local_realm(gc->proto_data,buff); + char *stripped_user = zephyr_strip_local_realm(zephyr,buff); purple_debug_info("zephyr","stripped_user %s\n",stripped_user); if (!(b = purple_find_buddy(gc->account,stripped_user))){ b = purple_buddy_new(gc->account, stripped_user, NULL); @@ -1924,13 +1925,12 @@ fclose(fd); } -static void write_anyone(PurpleConnection *gc) +static void write_anyone(zephyr_account *zephyr) { GSList *buddies; char *fname; FILE *fd; PurpleAccount *account; - zephyr_account* zephyr = gc->proto_data; fname = g_strdup_printf("%s/.anyone", purple_home_dir()); fd = g_fopen(fname, "w"); if (!fd) { @@ -1938,7 +1938,7 @@ return; } - account = purple_connection_get_account(gc); + account = zephyr->account; for (buddies = purple_find_buddies(account, NULL); buddies; buddies = g_slist_delete_link(buddies, buddies)) { PurpleBuddy *b = buddies->data; @@ -1966,10 +1966,10 @@ g_list_free(zephyr->pending_zloc_names); if (purple_account_get_bool(gc->account, "write_anyone", FALSE)) - write_anyone(gc); + write_anyone(zephyr); if (purple_account_get_bool(gc->account, "write_zsubs", FALSE)) - write_zsubs(gc->proto_data); + write_zsubs(zephyr); s = zephyr->subscrips; while (s) { @@ -2032,7 +2032,7 @@ char *recipient; zephyr_account *zephyr = gc->proto_data; - zt = find_sub_by_id(gc->proto_data,id); + zt = find_sub_by_id(zephyr,id); if (!zt) /* this should never happen. */ return -EINVAL; @@ -2432,8 +2432,8 @@ if (!g_ascii_strcasecmp(recip, "%me%")) recip = zephyr->username; - zt1 = new_triple(gc->proto_data,classname, instname, recip); - zt2 = find_sub_by_triple(gc->proto_data,zt1); + zt1 = new_triple(zephyr,classname, instname, recip); + zt2 = find_sub_by_triple(zephyr,zt1); if (zt2) { free_triple(zt1); if (!zt2->open) { @@ -2563,7 +2563,7 @@ zephyr_account* zephyr = gc->proto_data; char *sender = (char *)zephyr->username; - zt = find_sub_by_id(gc->proto_data,id); + zt = find_sub_by_id(zephyr,id); /* find_sub_by_id can return NULL */ if (!zt) return;
--- a/libpurple/util.c Sun Jan 09 04:40:07 2011 +0000 +++ b/libpurple/util.c Sun Jan 30 17:52:06 2011 +0000 @@ -664,159 +664,192 @@ return mktime(&tm); } +/* originally taken from GLib trunk 1-6-11 */ +/* originally licensed as LGPL 2+ */ +static time_t +mktime_utc(struct tm *tm) +{ + time_t retval; + +#ifndef HAVE_TIMEGM + static const gint days_before[] = + { + 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 + }; +#endif + +#ifndef HAVE_TIMEGM + if (tm->tm_mon < 0 || tm->tm_mon > 11) + return (time_t) -1; + + retval = (tm->tm_year - 70) * 365; + retval += (tm->tm_year - 68) / 4; + retval += days_before[tm->tm_mon] + tm->tm_mday - 1; + + if (tm->tm_year % 4 == 0 && tm->tm_mon < 2) + retval -= 1; + + retval = ((((retval * 24) + tm->tm_hour) * 60) + tm->tm_min) * 60 + tm->tm_sec; +#else + retval = timegm (tm); +#endif /* !HAVE_TIMEGM */ + + return retval; +} + time_t purple_str_to_time(const char *timestamp, gboolean utc, - struct tm *tm, long *tz_off, const char **rest) + struct tm *tm, long *tz_off, const char **rest) { - time_t retval = 0; - static struct tm t; - const char *c = timestamp; - int year = 0; + struct tm t; + const gchar *str; + gint year = 0; long tzoff = PURPLE_NO_TZ_OFF; - - time(&retval); - localtime_r(&retval, &t); + time_t retval; + gboolean mktime_with_utc = TRUE; if (rest != NULL) *rest = NULL; + g_return_val_if_fail(timestamp != NULL, 0); + + str = timestamp; + + /* Strip leading whitespace */ + while (g_ascii_isspace(*str)) + str++; + + if (*str == '\0') { + if (rest != NULL && *str != '\0') + *rest = str; + + return 0; + } + + if (!g_ascii_isdigit(*str) && *str != '-' && *str != '+') { + if (rest != NULL && *str != '\0') + *rest = str; + + return 0; + } + /* 4 digit year */ - if (sscanf(c, "%04d", &year) && year > 1900) - { - c += 4; - if (*c == '-') - c++; + if (sscanf(str, "%04d", &year) && year >= 1900) { + str += 4; + + if (*str == '-' || *str == '/') + str++; + t.tm_year = year - 1900; } /* 2 digit month */ - if (!sscanf(c, "%02d", &t.tm_mon)) - { - if (rest != NULL && *c != '\0') - *rest = c; + if (!sscanf(str, "%02d", &t.tm_mon)) { + if (rest != NULL && *str != '\0') + *rest = str; + return 0; } - c += 2; - if (*c == '-' || *c == '/') - c++; + + str += 2; t.tm_mon -= 1; + if (*str == '-' || *str == '/') + str++; + /* 2 digit day */ - if (!sscanf(c, "%02d", &t.tm_mday)) - { - if (rest != NULL && *c != '\0') - *rest = c; + if (!sscanf(str, "%02d", &t.tm_mday)) { + if (rest != NULL && *str != '\0') + *rest = str; + return 0; } - c += 2; - if (*c == '/') - { - c++; - - if (!sscanf(c, "%04d", &t.tm_year)) - { - if (rest != NULL && *c != '\0') - *rest = c; + + str += 2; + + /* Grab the year off the end if there's still stuff */ + if (*str == '/' || *str == '-') { + /* But make sure we don't read the year twice */ + if (year >= 1900) { + if (rest != NULL && *str != '\0') + *rest = str; + + return 0; + } + + str++; + + if (!sscanf(str, "%04d", &t.tm_year)) { + if (rest != NULL && *str != '\0') + *rest = str; + return 0; } + t.tm_year -= 1900; - } - else if (*c == 'T' || *c == '.') - { - c++; - /* we have more than a date, keep going */ - - /* 2 digit hour */ - if ((sscanf(c, "%02d:%02d:%02d", &t.tm_hour, &t.tm_min, &t.tm_sec) == 3 && (c = c + 8)) || - (sscanf(c, "%02d%02d%02d", &t.tm_hour, &t.tm_min, &t.tm_sec) == 3 && (c = c + 6))) + } else if (*str == 'T' || *str == '.') { + str++; + + /* Continue grabbing the hours/minutes/seconds */ + if ((sscanf(str, "%02d:%02d:%02d", &t.tm_hour, &t.tm_min, &t.tm_sec) == 3 && + (str += 8)) || + (sscanf(str, "%02d%02d%02d", &t.tm_hour, &t.tm_min, &t.tm_sec) == 3 && + (str += 6))) { - gboolean offset_positive = FALSE; - int tzhrs; - int tzmins; - - t.tm_isdst = -1; - - if (*c == '.') { + gint sign, tzhrs, tzmins; + + if (*str == '.') { + /* Cut off those pesky micro-seconds */ do { - c++; - } while (*c >= '0' && *c <= '9'); /* dealing with precision we don't care about */ - } - if (*c == '+') - offset_positive = TRUE; - if (((*c == '+' || *c == '-') && (c = c + 1)) && - ((sscanf(c, "%02d:%02d", &tzhrs, &tzmins) == 2 && (c = c + 5)) || - (sscanf(c, "%02d%02d", &tzhrs, &tzmins) == 2 && (c = c + 4)))) - { - tzoff = tzhrs*60*60 + tzmins*60; - if (offset_positive) - tzoff *= -1; - } - else if ((*c == 'Z') && (c = c + 1)) - { - /* 'Z' = Zulu = UTC */ - tzoff = 0; + str++; + } while (*str >= '0' && *str <= '9'); } - else if (utc) - { - static struct tm tmptm; - time_t tmp; - tmp = mktime(&t); - /* we care about whether it *was* dst, and the offset, here on this - * date, not whether we are currently observing dst locally *now*. - * This isn't perfect, because we would need to know in advance the - * offset we are trying to work out in advance to be sure this - * works for times around dst transitions but it'll have to do. */ - localtime_r(&tmp, &tmptm); - t.tm_isdst = tmptm.tm_isdst; -#ifdef HAVE_TM_GMTOFF - t.tm_gmtoff = tmptm.tm_gmtoff; -#endif - } - - if (rest != NULL && *c != '\0') - { - if (*c == ' ') - c++; - if (*c != '\0') - *rest = c; + + sign = (*str == '+') ? -1 : 1; + + /* Process the timezone */ + if (*str == '+' || *str == '-') { + str++; + + if (((sscanf(str, "%02d:%02d", &tzhrs, &tzmins) == 2 && (str += 5)) || + (sscanf(str, "%02d%02d", &tzhrs, &tzmins) == 2 && (str += 4)))) + { + tzoff = tzhrs * 60 * 60 + tzmins * 60; + tzoff *= sign; + } else { + if (rest != NULL && *str != '\0') + *rest = str; + + return 0; + } + } else if (*str == 'Z') { + /* 'Z' = Zulu = UTC */ + str++; + utc = TRUE; + } else if (!utc) { + /* Local Time */ + t.tm_isdst = -1; + mktime_with_utc = FALSE; } - if (tzoff != PURPLE_NO_TZ_OFF || utc) - { -#if defined(_WIN32) - long sys_tzoff; -#endif - -#if defined(_WIN32) || defined(HAVE_TM_GMTOFF) || defined (HAVE_TIMEZONE) - if (tzoff == PURPLE_NO_TZ_OFF) - tzoff = 0; -#endif - -#ifdef _WIN32 - if ((sys_tzoff = wpurple_get_tz_offset()) == -1) - tzoff = PURPLE_NO_TZ_OFF; - else - tzoff += sys_tzoff; -#else -#ifdef HAVE_TM_GMTOFF - tzoff += t.tm_gmtoff; -#else -# ifdef HAVE_TIMEZONE - tzset(); /* making sure */ - tzoff -= timezone; -# endif -#endif -#endif /* _WIN32 */ - } - } - else - { - if (rest != NULL && *c != '\0') - *rest = c; + if (utc) + tzoff = 0; } } - retval = mktime(&t); + if (rest != NULL && *str != '\0') { + /* Strip trailing whitespace */ + while (g_ascii_isspace(*str)) + str++; + + if (*str != '\0') + *rest = str; + } + + if (mktime_with_utc) + retval = mktime_utc(&t); + else + retval = mktime(&t); if (tm != NULL) *tm = t;
--- a/pidgin/gtkdialogs.c Sun Jan 09 04:40:07 2011 +0000 +++ b/pidgin/gtkdialogs.c Sun Jan 30 17:52:06 2011 +0000 @@ -73,7 +73,7 @@ static const struct developer developers[] = { {"Daniel 'datallah' Atallah", NULL, NULL}, {"Paul 'darkrain42' Aurich", NULL, NULL}, - {"John 'rekkanoryo' Bailey", N_("bug master"), NULL}, + {"John 'rekkanoryo' Bailey", NULL, NULL}, {"Ethan 'Paco-Paco' Blanton", NULL, NULL}, {"Hylke Bons", N_("artist"), "hylkebons@gmail.com"}, /* feel free to not translate this */ @@ -199,7 +199,7 @@ {N_("Kurdish"), "ku", "Rizoyê Xerzî", "rizoxerzi@hotmail.com"}, {N_("Lao"), "lo", "Anousak Souphavah", "anousak@gmail.com"}, {N_("Maithili"), "mai", "Sangeeta Kumari", "sangeeta_0975@yahoo.com"}, - {"Meadow Mari", "mhr", "David Preece", "davidpreece1@gmail.com"}, + {N_("Meadow Mari"), "mhr", "David Preece", "davidpreece1@gmail.com"}, {N_("Macedonian"), "mk", "Arangel Angov ", "arangel@linux.net.mk"}, {N_("Macedonian"), "mk", "Ivana Kirkovska", "ivana.kirkovska@gmail.com"}, {N_("Macedonian"), "mk", "Jovan Naumovski", "jovan@lugola.net"},
--- a/pidgin/gtkutils.c Sun Jan 09 04:40:07 2011 +0000 +++ b/pidgin/gtkutils.c Sun Jan 30 17:52:06 2011 +0000 @@ -1458,6 +1458,7 @@ static void dnd_image_ok_callback(_DndData *data, int choice) { + const gchar *shortname; gchar *filedata; size_t size; struct stat st; @@ -1512,7 +1513,9 @@ break; } - id = purple_imgstore_add_with_id(filedata, size, data->filename); + shortname = strrchr(data->filename, G_DIR_SEPARATOR); + shortname = shortname ? shortname + 1 : data->filename; + id = purple_imgstore_add_with_id(filedata, size, shortname); gtk_text_buffer_get_iter_at_mark(GTK_IMHTML(gtkconv->entry)->text_buffer, &iter, gtk_text_buffer_get_insert(GTK_IMHTML(gtkconv->entry)->text_buffer));
--- a/pidgin/plugins/vvconfig.c Sun Jan 09 04:40:07 2011 +0000 +++ b/pidgin/plugins/vvconfig.c Sun Jan 30 17:52:06 2011 +0000 @@ -82,20 +82,11 @@ GstPropertyProbe *probe; const GParamSpec *pspec; - if (!strcmp(element_name, "<custom>")) { - ret = g_list_prepend(ret, NULL); - ret = g_list_prepend(ret, (gpointer)_("Default")); - ret = g_list_prepend(ret, ""); - return ret; - } - ret = g_list_prepend(ret, (gpointer)_("Default")); ret = g_list_prepend(ret, ""); - if (*element_name == '\0') { - ret = g_list_prepend(ret, NULL); - ret = g_list_reverse(ret); - return ret; + if (!strcmp(element_name, "<custom>") || (*element_name == '\0')) { + return g_list_reverse(ret); } element = gst_element_factory_make(element_name, "test"); @@ -120,9 +111,7 @@ array = gst_property_probe_probe_and_get_values (probe, pspec); if (array == NULL) { purple_debug_info("vvconfig", "'%s' has no devices\n", element_name); - ret = g_list_prepend(ret, NULL); - ret = g_list_reverse(ret); - return ret; + return g_list_reverse(ret); } for (n=0; n < array->n_values; ++n) { @@ -153,10 +142,7 @@ } gst_object_unref(element); - ret = g_list_prepend(ret, NULL); - ret = g_list_reverse(ret); - - return ret; + return g_list_reverse(ret); } static GList * @@ -173,7 +159,6 @@ ret = g_list_prepend(ret, (gpointer)plugins[0]); } } - ret = g_list_prepend(ret, NULL); ret = g_list_reverse(ret); return ret; } @@ -236,7 +221,8 @@ pref = g_strdup(name); strcpy(pref + strlen(pref) - strlen("plugin"), "device"); devices = get_element_devices(value); - if (g_list_find(devices, purple_prefs_get_string(pref)) == NULL) + if (g_list_find_custom(devices, purple_prefs_get_string(pref), + (GCompareFunc)strcmp) == NULL) purple_prefs_set_string(pref, g_list_next(devices)->data); widget = pidgin_prefs_dropdown_from_list(parent, label, PURPLE_PREF_STRING,
--- a/pidgin/win32/nsis/pidgin-installer.nsi Sun Jan 09 04:40:07 2011 +0000 +++ b/pidgin/win32/nsis/pidgin-installer.nsi Sun Jan 30 17:52:06 2011 +0000 @@ -530,6 +530,7 @@ Push "xmpp" Call un.UnregisterURIHandler + Delete "$INSTDIR\ca-certs\AddTrust_External_Root.pem" Delete "$INSTDIR\ca-certs\America_Online_Root_Certification_Authority_1.pem" Delete "$INSTDIR\ca-certs\AOL_Member_CA.pem" Delete "$INSTDIR\ca-certs\CAcert_Class3.pem"
--- a/pidgin/win32/winpidgin.c Sun Jan 09 04:40:07 2011 +0000 +++ b/pidgin/win32/winpidgin.c Sun Jan 30 17:52:06 2011 +0000 @@ -632,11 +632,11 @@ } else { if (strchr(__argv[i], 'd')) debug = TRUE; - else if (strchr(__argv[i], 'h')) + if (strchr(__argv[i], 'h')) help = TRUE; - else if (strchr(__argv[i], 'v')) + if (strchr(__argv[i], 'v')) version = TRUE; - else if (strchr(__argv[i], 'm')) + if (strchr(__argv[i], 'm')) multiple = TRUE; } }
--- a/po/POTFILES.in Sun Jan 09 04:40:07 2011 +0000 +++ b/po/POTFILES.in Sun Jan 30 17:52:06 2011 +0000 @@ -124,8 +124,8 @@ libpurple/protocols/mxit/filexfer.c libpurple/protocols/mxit/http.c libpurple/protocols/mxit/login.c +libpurple/protocols/mxit/multimx.c libpurple/protocols/mxit/mxit.c -libpurple/protocols/mxit/multimx.c libpurple/protocols/mxit/profile.c libpurple/protocols/mxit/protocol.c libpurple/protocols/mxit/roster.c @@ -148,8 +148,8 @@ libpurple/protocols/oscar/oft.c libpurple/protocols/oscar/oscar.c libpurple/protocols/oscar/peer.c +libpurple/protocols/oscar/userinfo.c libpurple/protocols/oscar/util.c -libpurple/protocols/oscar/userinfo.c libpurple/protocols/oscar/visibility.c libpurple/protocols/qq/buddy_info.c libpurple/protocols/qq/buddy_list.c
--- a/po/ar.po Sun Jan 09 04:40:07 2011 +0000 +++ b/po/ar.po Sun Jan 30 17:52:06 2011 +0000 @@ -747,9 +747,9 @@ #, c-format msgid "File Transfers - %d%% of %d file" msgid_plural "File Transfers - %d%% of %d files" -msgstr[0] "نقل الملفات - %d%% من %0.sصفر ملفات" -msgstr[1] "نقل الملفات - %d%% من %0.sملف واحد" -msgstr[2] "نقل الملفات - %d%% من %0.sملفين" +msgstr[0] "نقل الملفات - %d%% من صفر ملفات" +msgstr[1] "نقل الملفات - %d%% من ملف واحد" +msgstr[2] "نقل الملفات - %d%% من ملفين" msgstr[3] "نقل الملفات - %d%% من %d ملفات" msgstr[4] "نقل الملفات - %d%% من %d ملفا" msgstr[5] "نقل الملفات - %d%% من %d ملف" @@ -921,9 +921,9 @@ #, c-format msgid "%s (%s) has %d new message." msgid_plural "%s (%s) has %d new messages." -msgstr[0] "لا رسائل%0.s جديدة لـ %s (%s)." -msgstr[1] "%s (%s) لديه %0.sرسالة واحدة جديدة" -msgstr[2] "%s (%s) لديه %0.sرسالتان جديدتان." +msgstr[0] "لا رسائل جديدة لـ %s (%s)." +msgstr[1] "%s (%s) لديه رسالة واحدة جديدة" +msgstr[2] "%s (%s) لديه رسالتان جديدتان." msgstr[3] "%s (%s) لديه %d رسائل جديدة." msgstr[4] "%s (%s) لديه %d رسالة جديدة." msgstr[5] "%s (%s) لديه %d رسالة جديدة." @@ -11231,9 +11231,9 @@ #, c-format msgid "%s, %d hour" msgid_plural "%s, %d hours" -msgstr[0] "%s، %0.sلا ساعات" -msgstr[1] "%s، %0.sساعة واحدة" -msgstr[2] "%s، %0.sساعتين" +msgstr[0] "%s، لا ساعات" +msgstr[1] "%s، ساعة واحدة" +msgstr[2] "%s، ساعتين" msgstr[3] "%s، %d ساعات" msgstr[4] "%s، %d ساعة" msgstr[5] "%s، %d ساعة" @@ -11251,9 +11251,9 @@ #, c-format msgid "%s, %d minute" msgid_plural "%s, %d minutes" -msgstr[0] "%s، %0.sلا دقائق" -msgstr[1] "%s، %0.sدقيقة واحدة" -msgstr[2] "%s، %0.sدقيقتين" +msgstr[0] "%s، لا دقائق" +msgstr[1] "%s، دقيقة واحدة" +msgstr[2] "%s، دقيقتين" msgstr[3] "%s، %d دقائق" msgstr[4] "%s، %d دقيقة" msgstr[5] "%s، %d دقيقة" @@ -11604,13 +11604,12 @@ msgid "The text information for a buddy's status" msgstr "غيّر معلومات المستخدم لأجل %s" -#, c-format msgid "You have %d contact named %s. Would you like to merge them?" msgid_plural "" "You currently have %d contacts named %s. Would you like to merge them?" -msgstr[0] "لا مراسلين%0.s لديك باسم %s. أتريد دمجهم؟" -msgstr[1] "لديك مراسل واحد%0.s باسم %s. أتريد دمجه؟" -msgstr[2] "لديك مراسليْن%0.s باسم %s. أتريد دمجهما؟" +msgstr[0] "%0.sلا مراسلين لديك باسم %s. أتريد دمجهم؟" +msgstr[1] "%0.sلديك مراسل واحد باسم %s. أتريد دمجه؟" +msgstr[2] "%0.sلديك مراسليْن باسم %s. أتريد دمجهما؟" msgstr[3] "لديك %d مراسلين باسم %s. أتريد دمجهم؟" msgstr[4] "لديك %d مراسلا باسم %s. أتريد دمجهم؟" msgstr[5] "لديك %d مراسل باسم %s. أتريد دمجهم؟" @@ -11948,12 +11947,11 @@ msgid "/Tools/Room List" msgstr "/الأدوات/قائمة الغرف" -#, c-format msgid "%d unread message from %s\n" msgid_plural "%d unread messages from %s\n" -msgstr[0] "لا رسائل%0.s غير مقروءة من %s\n" -msgstr[1] "رسالة واحدة%0.s غير مقروءة من %s\n" -msgstr[2] "رسالتان%0.s غير مقروءتان من %s\n" +msgstr[0] "%0.sلا رسائل غير مقروءة من %s\n" +msgstr[1] "%0.sرسالة واحدة غير مقروءة من %s\n" +msgstr[2] "%0.sرسالتان غير مقروءتان من %s\n" msgstr[3] "%d رسائل غير مقروءة من %s\n" msgstr[4] "%d رسالة غير مقروءة من %s\n" msgstr[5] "%d رسالة غير مقروءة من %s\n" @@ -12932,13 +12930,13 @@ "You are about to remove the contact containing %s and %d other buddies from " "your buddy list. Do you want to continue?" msgstr[0] "" -"أنت بصدد إزالة مراسل يحتوي %s و %0.sلا أصدقاء من قائمة أصدقائك. هل تريد " +"أنت بصدد إزالة مراسل يحتوي %s ولا أصدقاء من قائمة أصدقائك. هل تريد " "الاستمرار؟" msgstr[1] "" -"أنت بصدد إزالة مراسل يحتوي %s و %0.sصديق آخر من قائمة أصدقائك. هل تريد " +"أنت بصدد إزالة مراسل يحتوي %s وصديق آخر من قائمة أصدقائك. هل تريد " "الاستمرار؟" msgstr[2] "" -"أنت بصدد إزالة مراسل يحتوي %s و %0.sصديقين آخرين من قائمة أصدقائك. هل تريد " +"أنت بصدد إزالة مراسل يحتوي %s وصديقين آخرين من قائمة أصدقائك. هل تريد " "الاستمرار؟" msgstr[3] "" "أنت بصدد إزالة مراسل يحتوي %s و %d أصدقاء آخرين من قائمة أصدقائك. هل تريد " @@ -13504,12 +13502,12 @@ #, c-format msgid "%s has %d new message." msgid_plural "%s has %d new messages." -msgstr[0] "لا رسائل%0.s جديدة ل %s." -msgstr[1] "رسالة%0.s جديدة ل %s." -msgstr[2] "رسالتان%0.s جديدتان ل %s." -msgstr[3] "%Id رسائل جديدة ل %s." -msgstr[4] "%Id رسالة جديدة ل %s." -msgstr[5] "%Id رسالة جديدة ل %s." +msgstr[0] "لا رسائل جديدة ل %s." +msgstr[1] "رسالة جديدة ل %s." +msgstr[2] "رسالتان جديدتان ل %s." +msgstr[3] "%2$d رسائل جديدة ل %1$s." +msgstr[4] "%2$d رسالة جديدة ل %1$s." +msgstr[5] "%2$d رسالة جديدة ل %1$s." #, c-format msgid "<b>%d new email.</b>"
--- a/po/az.po Sun Jan 09 04:40:07 2011 +0000 +++ b/po/az.po Sun Jan 30 17:52:06 2011 +0000 @@ -15,7 +15,7 @@ "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: Plural-Forms: nplurals=2; plural=(n != 1);\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: KBabel 1.3\n" #. Translators may want to transliterate the name.
--- a/po/ca.po Sun Jan 09 04:40:07 2011 +0000 +++ b/po/ca.po Sun Jan 30 17:52:06 2011 +0000 @@ -3,7 +3,7 @@ # Copyright (C) unknown, Robert Millan <zeratul2@wanadoo.es> # Copyright (C) December 2003 (from 2003-12-12 until 2003-12-18), # January (2004-01-07,12), Xan <dxpublica@telefonica.net> -# Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010 +# Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 # Josep Puigdemont i Casamajó <josep.puigdemont@gmail.com> # # This file is distributed under the same license as the Pidgin package. @@ -33,8 +33,8 @@ msgstr "" "Project-Id-Version: Pidgin\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2010-12-23 07:57+0100\n" -"PO-Revision-Date: 2010-12-23 08:04+0100\n" +"POT-Creation-Date: 2011-01-30 11:04+0100\n" +"PO-Revision-Date: 2011-01-30 11:11+0100\n" "Last-Translator: Josep Puigdemont i Casamajó <josep.puigdemont@gmail.com>\n" "Language-Team: Catalan <tradgnome@softcatala.net>\n" "Language: ca\n" @@ -2387,9 +2387,12 @@ "Camí on desar els fitxers\n" "(introduïu tot el camí)" -msgid "Automatically reject from users not in buddy list" -msgstr "" -"Rebutja automàticament dels usuaris que no estiguin a la llista d'amics" +msgid "" +"When a file-transfer request arrives from a user who is\n" +"*not* on your buddy list:" +msgstr "" +"Quan arribi una sol·licitud de transferència d'un fitxer d'un\n" +"usuari que *no* és a la vostra llista d'amics:" msgid "" "Notify with a popup when an autoaccepted file transfer is complete\n" @@ -2402,6 +2405,10 @@ msgid "Create a new directory for each user" msgstr "Crea un directori nou per a cada usuari" +#, fuzzy +msgid "Escape the filenames" +msgstr "%s ha cancel·lat la transferència del fitxer" + msgid "Notes" msgstr "Notes" @@ -3859,7 +3866,10 @@ msgid "Server requires plaintext authentication over an unencrypted stream" msgstr "El servidor requereix autenticació de text sobre un flux no xifrat" -#. This should never happen! +#. This happens when the server sends back jibberish +#. * in the "additional data with success" case. +#. * Seen with Wildfire 3.0.1. +#. msgid "Invalid response from server" msgstr "La resposta del servidor no és vàlida" @@ -6201,6 +6211,20 @@ msgid "Retrieving User Information..." msgstr "S'està obtenint informació de l'usuari..." +#. you were kicked +msgid "You have been kicked from this MultiMX." +msgstr "Us han fet fora d'aquest MultiMX." + +msgid "was kicked" +msgstr "ha estat fet fora" + +msgid "_Room Name:" +msgstr "Nom de la _Sala:" + +#. Display system message in chat window +msgid "You have invited" +msgstr "Heu convidat" + msgid "Loading menu..." msgstr "S'està carregant el menú..." @@ -6229,20 +6253,6 @@ msgid "Enable splash-screen popup" msgstr "Habilita la pantalla de presentació emergent" -#. you were kicked -msgid "You have been kicked from this MultiMX." -msgstr "Us han fet fora d'aquest MultiMX." - -msgid "was kicked" -msgstr "ha estat fet fora" - -msgid "_Room Name:" -msgstr "Nom de la _Sala:" - -#. Display system message in chat window -msgid "You have invited" -msgstr "Heu convidat" - msgid "Last Online" msgstr "Darrer cop en línia" @@ -7917,75 +7927,6 @@ "necessari per poder enviar imatges instantànies. Atès que es revelarà la " "vostra adreça IP, això es pot considerar un risc de privadesa." -msgid "Invalid SNAC" -msgstr "SNAC invàlid" - -msgid "Server rate limit exceeded" -msgstr "S'ha excedit el límit de velocitat del servidor" - -msgid "Client rate limit exceeded" -msgstr "S'ha excedit el límit de velocitat del client" - -msgid "Service unavailable" -msgstr "Servei no disponible" - -msgid "Service not defined" -msgstr "Servei no definit" - -msgid "Obsolete SNAC" -msgstr "SNAC obsolet" - -msgid "Not supported by host" -msgstr "El servidor no ho permet" - -msgid "Not supported by client" -msgstr "El client no ho permet" - -msgid "Refused by client" -msgstr "Rebutjat pel client" - -msgid "Reply too big" -msgstr "Resposta massa gran" - -msgid "Responses lost" -msgstr "S'han perdut respostes" - -msgid "Request denied" -msgstr "Petició denegada" - -msgid "Busted SNAC payload" -msgstr "Càrrega SNAC malmesa" - -msgid "Insufficient rights" -msgstr "Drets insuficients" - -msgid "In local permit/deny" -msgstr "En la llista de permès/denegat local" - -msgid "Warning level too high (sender)" -msgstr "Nivell d'avís massa alt (remitent)" - -msgid "Warning level too high (receiver)" -msgstr "Nivell d'avís massa alt (receptor)" - -msgid "User temporarily unavailable" -msgstr "Usuari no disponible temporalment" - -msgid "No match" -msgstr "Cap coincidència" - -msgid "List overflow" -msgstr "Sobreeiximent de la llista" - -msgid "Request ambiguous" -msgstr "Petició ambigua" - -msgid "Queue full" -msgstr "Cua plena" - -msgid "Not while on AOL" -msgstr "No es pot fer mentre estigui a AOL" - #. Label msgid "Buddy Icon" msgstr "Icona de l'amic" @@ -8104,6 +8045,75 @@ msgid "Capabilities" msgstr "Capacitats" +msgid "Invalid SNAC" +msgstr "SNAC invàlid" + +msgid "Server rate limit exceeded" +msgstr "S'ha excedit el límit de velocitat del servidor" + +msgid "Client rate limit exceeded" +msgstr "S'ha excedit el límit de velocitat del client" + +msgid "Service unavailable" +msgstr "Servei no disponible" + +msgid "Service not defined" +msgstr "Servei no definit" + +msgid "Obsolete SNAC" +msgstr "SNAC obsolet" + +msgid "Not supported by host" +msgstr "El servidor no ho permet" + +msgid "Not supported by client" +msgstr "El client no ho permet" + +msgid "Refused by client" +msgstr "Rebutjat pel client" + +msgid "Reply too big" +msgstr "Resposta massa gran" + +msgid "Responses lost" +msgstr "S'han perdut respostes" + +msgid "Request denied" +msgstr "Petició denegada" + +msgid "Busted SNAC payload" +msgstr "Càrrega SNAC malmesa" + +msgid "Insufficient rights" +msgstr "Drets insuficients" + +msgid "In local permit/deny" +msgstr "En la llista de permès/denegat local" + +msgid "Warning level too high (sender)" +msgstr "Nivell d'avís massa alt (remitent)" + +msgid "Warning level too high (receiver)" +msgstr "Nivell d'avís massa alt (receptor)" + +msgid "User temporarily unavailable" +msgstr "Usuari no disponible temporalment" + +msgid "No match" +msgstr "Cap coincidència" + +msgid "List overflow" +msgstr "Sobreeiximent de la llista" + +msgid "Request ambiguous" +msgstr "Petició ambigua" + +msgid "Queue full" +msgstr "Cua plena" + +msgid "Not while on AOL" +msgstr "No es pot fer mentre estigui a AOL" + #. Translators: This string is a menu option that, if selected, will cause #. you to appear online to the chosen user even when your status is set to #. Invisible. @@ -8703,14 +8713,14 @@ msgid "Select Server" msgstr "Seleccioneu un servidor" -msgid "QQ2005" -msgstr "QQ2005" +msgid "QQ2008" +msgstr "QQ2008" msgid "QQ2007" msgstr "QQ2007" -msgid "QQ2008" -msgstr "QQ2008" +msgid "QQ2005" +msgstr "QQ2005" msgid "Connect by TCP" msgstr "Connecta amb TCP" @@ -12284,10 +12294,6 @@ msgid "Fatal Error" msgstr "Error fatal" -# Fixme -msgid "bug master" -msgstr "bug master" - msgid "artist" msgstr "artista" @@ -12469,6 +12475,9 @@ msgid "Maithili" msgstr "Maithili" +msgid "Meadow Mari" +msgstr "Txeremís oriental" + msgid "Macedonian" msgstr "Macedoni" @@ -15626,6 +15635,14 @@ msgid "You do not have permission to uninstall this application." msgstr "No tens permís per desinstal.lar aquesta aplicació." +#~ msgid "Automatically reject from users not in buddy list" +#~ msgstr "" +#~ "Rebutja automàticament dels usuaris que no estiguin a la llista d'amics" + +# Fixme +#~ msgid "bug master" +#~ msgstr "bug master" + #~ msgid "Error requesting %s" #~ msgstr "S'ha produït un error en sol·licitar %s"
--- a/po/de.po Sun Jan 09 04:40:07 2011 +0000 +++ b/po/de.po Sun Jan 30 17:52:06 2011 +0000 @@ -2,7 +2,7 @@ # Pidgin German translation # Copyright (C) 2001, Daniel Seifert <Pidgin-translation@dseifert.de> # Copyright (C) 2002, Karsten Weiss <knweiss@gmx.de> -# Copyright (C) 2002-2010, Björn Voigt <bjoern@cs.tu-berlin.de>, +# Copyright (C) 2002-2011, Björn Voigt <bjoern@cs.tu-berlin.de>, # Jochen Kemnade <jochenkemnade@web.de> # # This file is distributed under the same license as the Pidgin package. @@ -11,9 +11,9 @@ msgstr "" "Project-Id-Version: de\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2010-12-22 10:12+0100\n" -"PO-Revision-Date: 2010-12-22 10:21+0100\n" -"Last-Translator: Björn Voigt <bjoern@cs.tu-berlin.de>\n" +"POT-Creation-Date: 2011-01-25 20:46+0100\n" +"PO-Revision-Date: 2011-01-25 20:46+0100\n" +"Last-Translator: Jochen Kemnade <jochenkemnade@web.de>\n" "Language-Team: German <de@li.org>\n" "Language: de\n" "MIME-Version: 1.0\n" @@ -401,7 +401,7 @@ msgstr "Chat betreten" msgid "Please enter the name of the chat you want to join." -msgstr "Bitte geben Sie die den Namen des Chats an, den Sie betreten möchten." +msgstr "Bitte geben Sie den Namen des Chats an, den Sie betreten möchten." msgid "Join" msgstr "Betreten" @@ -568,7 +568,7 @@ msgstr "Konten reaktivieren" msgid "No such command." -msgstr "Es gibt kein solches Kommando." +msgstr "Unbekanntes Kommando." msgid "Syntax Error: You typed the wrong number of arguments to that command." msgstr "" @@ -581,7 +581,8 @@ msgstr "Dieses Kommando funktioniert nur in Chats, nicht bei IMs." msgid "That command only works in IMs, not chats." -msgstr "Dieses Kommando funktioniert nur bei IMs, nicht bei Chats." +msgstr "" +"Dieses Kommando funktioniert nur bei Sofortnachrichten, nicht bei Chats." msgid "That command doesn't work on this protocol." msgstr "Dieses Kommando funktioniert nicht in diesem Protokoll." @@ -646,7 +647,7 @@ msgstr "Einladen..." msgid "Enable Logging" -msgstr "Mitschnitt einschalten" +msgstr "Mitschnitt aktivieren" msgid "Enable Sounds" msgstr "Klänge aktivieren" @@ -801,7 +802,7 @@ msgstr "Status" msgid "Close this window when all transfers finish" -msgstr "Schließe dieses Fenster, wenn alle Übertragungen abgeschlossen sind" +msgstr "Fenster schließen, wenn alle Übertragungen abgeschlossen sind" msgid "Clear finished transfers" msgstr "Entferne komplette Übertragungen" @@ -816,7 +817,7 @@ msgstr "Abgebrochen" msgid "Failed" -msgstr "Gescheitert" +msgstr "Fehlgeschlagen" #, c-format msgid "%.2f KiB/s" @@ -884,11 +885,11 @@ #, c-format msgid "Conversations in %s" -msgstr "Unterhaltung in %s" +msgstr "Unterhaltungen in %s" #, c-format msgid "Conversations with %s" -msgstr "Unterhaltung mit %s" +msgstr "Unterhaltungen mit %s" msgid "All Conversations" msgstr "Alle Unterhaltungen" @@ -910,7 +911,7 @@ msgstr "Ablehnen" msgid "Call in progress." -msgstr "Anruf läuft." +msgstr "Verbindungsaufbau." msgid "The call has been terminated." msgstr "Der Anruf wurde beendet." @@ -926,7 +927,7 @@ "starten." msgid "You have rejected the call." -msgstr "Sie haben den Anruf abgelehnt." +msgstr "Sie haben den Anruf abgewiesen." msgid "call: Make an audio call." msgstr "call: Einen Audio-Anruf tätigen." @@ -1009,7 +1010,7 @@ msgstr "Keine Einstellungsoptionen für dieses Plugin." msgid "Error loading plugin" -msgstr "Beim Laden des Plugins traten Fehler auf" +msgstr "Beim Laden des Plugins ist ein Fehler aufgetreten" msgid "The selected file is not a valid plugin." msgstr "Die gewählte Datei ist kein gültiges Plugin." @@ -1021,7 +1022,7 @@ "genaue Fehlermeldung zu sehen." msgid "Select plugin to install" -msgstr "Wählen Sie ein Plugin zum Installieren" +msgstr "Zu installierendes Plugin auswählen" msgid "You can (un)load plugins from the following list." msgstr "Die können Plugins von der folgenden Liste laden bzw. entladen." @@ -1064,10 +1065,10 @@ msgstr "Alarm, wenn Buddy..." msgid "Signs on" -msgstr "sich angemeldet" +msgstr "sich anmeldet" msgid "Signs off" -msgstr "sich abgemeldet" +msgstr "sich abmeldet" msgid "Goes away" msgstr "hinausgeht" @@ -1085,7 +1086,7 @@ msgstr "zu tippen beginnt" msgid "Pauses while typing" -msgstr "beim Tippen anhält" +msgstr "das Tippen unterbricht" msgid "Stops typing" msgstr "aufhört zu tippen" @@ -1119,13 +1120,13 @@ msgstr "Wiederkehrend" msgid "Cannot create pounce" -msgstr "Kann Alarm nicht erzeugen" +msgstr "Alarm konnte nicht erstellt werden" msgid "You do not have any accounts." msgstr "Sie haben keine Kontos." msgid "You must create an account first before you can create a pounce." -msgstr "Sie müssen ein Konto anlegen, bevor Sie einen Alarm erzeugen können." +msgstr "Sie müssen ein Konto anlegen, bevor Sie einen Alarm einrichten können." #, c-format msgid "Are you sure you want to delete the pounce on %s for %s?" @@ -1164,7 +1165,7 @@ #, c-format msgid "%s has become idle (%s)" -msgstr "%s wurde untätig (%s)" +msgstr "%s ist nun untätig (%s)" #, c-format msgid "%s has gone away. (%s)" @@ -1178,7 +1179,7 @@ msgstr "Unbekanntes Alarm-Ereignis. Bitte berichten Sie dieses Problem!" msgid "Based on keyboard use" -msgstr "Abhängig von Tastaturbenutzung" +msgstr "Abhängig von der Tastaturbenutzung" msgid "From last sent message" msgstr "Von letzter gesendeter Nachricht" @@ -1199,7 +1200,7 @@ msgstr "Mitschnitt-Format" msgid "Log IMs" -msgstr "IMs mitschneiden" +msgstr "Sofortnachrichten mitschneiden" msgid "Log chats" msgstr "Chats mitschneiden" @@ -1247,7 +1248,7 @@ msgstr "Drücken Sie 'Enter', um mehr Räume dieser Kategorie zu finden." msgid "Get" -msgstr "Holen" +msgstr "Abrufen" #. Create the window. msgid "Room List" @@ -1441,7 +1442,7 @@ msgstr "Statusmeldungen" msgid "Error loading the plugin." -msgstr "Beim Laden des Plugins traten Fehler auf." +msgstr "Beim Laden des Plugins ist ein Fehler aufgetreten." msgid "Couldn't find X display" msgstr "Konnte X-Display nicht finden" @@ -1519,7 +1520,7 @@ msgstr "<b>Unterhaltung mit %s am %s:</b><br>" msgid "History Plugin Requires Logging" -msgstr "Das Verlaufs-Plugin erfordert das Mitschneiden" +msgstr "Für das Verlaufs-Plugin muss das Mitschneiden aktiviert sein" msgid "" "Logging can be enabled from Tools -> Preferences -> Logging.\n" @@ -1543,7 +1544,7 @@ "When a new conversation is opened this plugin will insert the last " "conversation into the current conversation." msgstr "" -"Wenn eine neue Unterhaltung eröffnet wird, fügt dieses Plugin die letzte " +"Wenn eine neue Unterhaltung begonnen wird, fügt dieses Plugin die letzte " "Unterhaltung in die aktuelle Unterhaltung ein." #, c-format @@ -1607,7 +1608,7 @@ msgstr "Verschachtelte Gruppen (experimentell)" msgid "Provides alternate buddylist grouping options." -msgstr "Bietet alternative Einstellungen für die Kontaktlisten-Gruppierung." +msgstr "Bietet alternative Einstellungen für die Gruppierung der Kontaktliste." msgid "Lastlog" msgstr "Verlauf" @@ -1900,11 +1901,11 @@ #, c-format msgid "Failed to get name: %s" -msgstr "Kann den Namen nicht bekommen: %s" +msgstr "Name konnte nicht abgerufen werden: %s" #, c-format msgid "Failed to get serv name: %s" -msgstr "Kann den Serv-Namen nicht bekommen: %s" +msgstr "Serv-Name konnte nicht abgerufen werden: %s" msgid "Purple's D-BUS server is not running for the reason listed below" msgstr "Purple's D-Bus-Server läuft aus dem folgenden Grund nicht" @@ -2041,7 +2042,7 @@ msgstr "Übertragung der Datei %s ist komplett" msgid "File transfer complete" -msgstr "Dateiübertragung ist komplett" +msgstr "Dateiübertragung abgeschlossen" #, c-format msgid "You cancelled the transfer of %s" @@ -2368,8 +2369,12 @@ "Pfad in denen die Dateien gespeichert werden sollen\n" "(Bitte geben Sie den vollständigen Pfad an)" -msgid "Automatically reject from users not in buddy list" -msgstr "Automatisch von Benutzern ablehnen, die nicht in der Buddy-Liste sind" +msgid "" +"When a file-transfer request arrives from a user who is\n" +"*not* on your buddy list:" +msgstr "" +"Wenn eine Dateitransferanfrage von einem Benutzer ankommt, \n" +"der *nicht* in Ihrer Buddy-Liste ist:" msgid "" "Notify with a popup when an autoaccepted file transfer is complete\n" @@ -2382,6 +2387,9 @@ msgid "Create a new directory for each user" msgstr "Für jeden Benutzer ein neues Verzeichnis anlegen" +msgid "Escape the filenames" +msgstr "Sonderzeichen in Dateinamen ersetzen" + msgid "Notes" msgstr "Notizen" @@ -3850,7 +3858,10 @@ "Der Server erfordert eine Klartext-Authentifizierung über einen " "unverschlüsselten Kanal" -#. This should never happen! +#. This happens when the server sends back jibberish +#. * in the "additional data with success" case. +#. * Seen with Wildfire 3.0.1. +#. msgid "Invalid response from server" msgstr "Ungültige Serverantwort" @@ -8730,14 +8741,14 @@ msgid "Select Server" msgstr "Server wählen" -msgid "QQ2005" -msgstr "QQ2005" +msgid "QQ2008" +msgstr "QQ2008" msgid "QQ2007" msgstr "QQ2007" -msgid "QQ2008" -msgstr "QQ2008" +msgid "QQ2005" +msgstr "QQ2005" msgid "Connect by TCP" msgstr "Über TCP verbinden" @@ -12328,9 +12339,6 @@ msgid "Fatal Error" msgstr "Schwerer Fehler" -msgid "bug master" -msgstr "Bug-Master" - msgid "artist" msgstr "Künstler" @@ -12510,6 +12518,9 @@ msgid "Maithili" msgstr "Maithili" +msgid "Meadow Mari" +msgstr "Wiesen-Mari" + msgid "Macedonian" msgstr "Makedonisch" @@ -13448,10 +13459,10 @@ msgstr "Budd_y-Name:" msgid "Si_gns on" -msgstr "si_ch angemeldet" +msgstr "si_ch anmeldet" msgid "Signs o_ff" -msgstr "sich abgemel_det" +msgstr "sich abmel_det" msgid "Goes a_way" msgstr "hinausgeh_t" @@ -15662,15 +15673,3 @@ msgid "You do not have permission to uninstall this application." msgstr "Sie haben keine Berechtigung, diese Anwendung zu deinstallieren." - -#~ msgid "Error requesting %s" -#~ msgstr "Fehler beim Anfordern von %s" - -#~ msgid "An error occurred on the in-band bytestream transfer\n" -#~ msgstr "Bei der In-Band-Bytestrom-Übertragung trat ein Fehler auf\n" - -#~ msgid "Transfer was closed." -#~ msgstr "Übertragung wurde geschlossen." - -#~ msgid "Failed to open in-band bytestream" -#~ msgstr "Öffnen des In-Band-Bytestroms fehlgeschlagen"
--- a/po/el.po Sun Jan 09 04:40:07 2011 +0000 +++ b/po/el.po Sun Jan 30 17:52:06 2011 +0000 @@ -18,7 +18,7 @@ "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: Plural-Forms: nplurals=2; plural=(n != 1)\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" "X-Generator: Lokalize 0.3\n" #. Translators may want to transliterate the name.
--- a/po/en_AU.po Sun Jan 09 04:40:07 2011 +0000 +++ b/po/en_AU.po Sun Jan 30 17:52:06 2011 +0000 @@ -16,7 +16,7 @@ "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=n>1;\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" #. Translators may want to transliterate the name. #. It is not to be translated.
--- a/po/en_GB.po Sun Jan 09 04:40:07 2011 +0000 +++ b/po/en_GB.po Sun Jan 30 17:52:06 2011 +0000 @@ -15,7 +15,7 @@ "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=n>1;\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" #. Translators may want to transliterate the name. #. It is not to be translated.
--- a/po/eu.po Sun Jan 09 04:40:07 2011 +0000 +++ b/po/eu.po Sun Jan 30 17:52:06 2011 +0000 @@ -16,7 +16,7 @@ "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: KBabel 1.9.1\n" -"Plural-Forms: Plural-Forms: Plural-Forms: nplurals=2; plural=(n != 1);\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" #. Translators may want to transliterate the name. #. It is not to be translated.
--- a/po/gl.po Sun Jan 09 04:40:07 2011 +0000 +++ b/po/gl.po Sun Jan 30 17:52:06 2011 +0000 @@ -18,7 +18,7 @@ "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: Plural-Forms: nplurals=2; plural=(n != 1);\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: KBabel 1.11.4\n" #. Translators may want to transliterate the name.
--- a/po/hu.po Sun Jan 09 04:40:07 2011 +0000 +++ b/po/hu.po Sun Jan 30 17:52:06 2011 +0000 @@ -1,22 +1,22 @@ # Hungarian translation of pidgin. -# Copyright (C) 2003, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +# Copyright (C) 2003, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. # This file is distributed under the same license as the Pidgin package. # The Hungarian translation of Pidgin was sponsored by Novell Hungary, many thanks for it! # # Zoltan Sutto <suttozoltan@chello.hu>, 2003. -# Gabor Kelemen <kelemeng at gnome dot hu>, 2005, 2006, 2007, 2008, 2009, 2010. -msgid "" -msgstr "" -"Project-Id-Version: pidgin 2.7\n" +# Gabor Kelemen <kelemeng at gnome dot hu>, 2005, 2006, 2007, 2008, 2009, 2010, 2011. +msgid "" +msgstr "" +"Project-Id-Version: pidgin 2.7.10\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2010-12-21 15:20+0100\n" -"PO-Revision-Date: 2010-12-21 15:19+0100\n" +"POT-Creation-Date: 2011-01-25 15:12+0100\n" +"PO-Revision-Date: 2011-01-25 15:12+0100\n" "Last-Translator: Gabor Kelemen <kelemeng at gnome dot hu>\n" "Language-Team: Hungarian <gnome at fsf dot hu>\n" -"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Language: \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: KBabel 1.11.4\n" @@ -2350,9 +2350,12 @@ "A fájlok mentési útvonala\n" "(Teljes elérési utat adjon meg)" -msgid "Automatically reject from users not in buddy list" -msgstr "" -"Automatikus visszautasítás a partnerlistán nem szereplő felhasználóktól" +msgid "" +"When a file-transfer request arrives from a user who is\n" +"*not* on your buddy list:" +msgstr "" +"Ha fájlküldési kérés érkezik egy a partnerlistán NEM szereplő\n" +"felhasználótól:" msgid "" "Notify with a popup when an autoaccepted file transfer is complete\n" @@ -2365,6 +2368,9 @@ msgid "Create a new directory for each user" msgstr "Új könyvtár létrehozása minden felhasználóhoz" +msgid "Escape the filenames" +msgstr "Fájlnevek escape-elése." + msgid "Notes" msgstr "Megjegyzések" @@ -3828,7 +3834,10 @@ msgstr "" "A kiszolgáló szöveges hitelesítést követel meg egy nem titkosított csatornán" -#. This should never happen! +#. This happens when the server sends back jibberish +#. * in the "additional data with success" case. +#. * Seen with Wildfire 3.0.1. +#. msgid "Invalid response from server" msgstr "Érvénytelen válasz a kiszolgálótól" @@ -6757,8 +6766,8 @@ #, c-format msgid "Unable to send message. Could not get details for user (%s)." msgstr "" -"Az üzenetet nem lehet elküldeni. A felhasználó részletei nem kérhetőek le " -"(%s)." +"Az üzenetet nem lehet elküldeni. A felhasználó részletei nem kérhetőek le (%" +"s)." #, c-format msgid "Unable to add %s to your buddy list (%s)." @@ -7191,8 +7200,8 @@ "%s tried to send you a %s file, but we only allow files up to %s over Direct " "IM. Try using file transfer instead.\n" msgstr "" -"%s egy %s fájlt próbált küldeni, de közvetlen kapcsolatban legfeljebb csak " -"%s méretű fájl küldhető. Próbálkozzon inkább a fájlátvitellel.\n" +"%s egy %s fájlt próbált küldeni, de közvetlen kapcsolatban legfeljebb csak %" +"s méretű fájl küldhető. Próbálkozzon inkább a fájlátvitellel.\n" #, c-format msgid "File %s is %s, which is larger than the maximum size of %s." @@ -8628,14 +8637,14 @@ msgid "Select Server" msgstr "Válassza ki a kiszolgálót" -msgid "QQ2005" -msgstr "QQ2005" +msgid "QQ2008" +msgstr "QQ2008" msgid "QQ2007" msgstr "QQ2007" -msgid "QQ2008" -msgstr "QQ2008" +msgid "QQ2005" +msgstr "QQ2005" msgid "Connect by TCP" msgstr "Kapcsolódás TCP segítségével" @@ -10831,8 +10840,8 @@ #, c-format msgid "Access denied: HTTP proxy server forbids port %d tunneling" msgstr "" -"Hozzáférés megtagadva: a HTTP proxy kiszolgáló tiltja az alagutazást a(z) " -"%d. porton" +"Hozzáférés megtagadva: a HTTP proxy kiszolgáló tiltja az alagutazást a(z) %" +"d. porton" #, c-format msgid "Error resolving %s" @@ -11080,8 +11089,8 @@ "An error was encountered reading your %s. The file has not been loaded, and " "the old file has been renamed to %s~." msgstr "" -"Hiba történt a(z) %s olvasásakor. Ez a fájl nem lett betöltve, a régi fájl " -"%s~ néven lett elmentve." +"Hiba történt a(z) %s olvasásakor. Ez a fájl nem lett betöltve, a régi fájl %" +"s~ néven lett elmentve." msgid "" "Chat over IM. Supports AIM, Google Talk, Jabber/XMPP, MSN, Yahoo and more" @@ -12207,10 +12216,6 @@ msgid "Fatal Error" msgstr "Végzetes hiba" -# fixme: jobb ötlet? -msgid "bug master" -msgstr "hibaritkító" - msgid "artist" msgstr "grafikus" @@ -12390,6 +12395,9 @@ msgid "Maithili" msgstr "Maithili" +msgid "Meadow Mari" +msgstr "Mari" + msgid "Macedonian" msgstr "macedón" @@ -12510,8 +12518,8 @@ "to multiple messaging services at once. %s is written in C using GTK+. %s " "is released, and may be modified and redistributed, under the terms of the " "GPL version 2 (or later). A copy of the GPL is distributed with %s. %s is " -"copyrighted by its contributors, a list of whom is also distributed with " -"%s. There is no warranty for %s.<BR><BR>" +"copyrighted by its contributors, a list of whom is also distributed with %" +"s. There is no warranty for %s.<BR><BR>" msgstr "" "A %s egy libpurple alapú moduláris üzenetküldő kliens, amely egyszerre több " "üzenetküldő szolgáltatáshoz is képes csatlakozni. A %s GTK+ használatával, C " @@ -13061,16 +13069,16 @@ #, c-format msgid "" -"Are you sure you want to permanently delete the log of the conversation in " -"%s which started at %s?" +"Are you sure you want to permanently delete the log of the conversation in %" +"s which started at %s?" msgstr "" "Biztos, hogy törölni akarja a(z) %s csatornán folytatott, %s időpontban " "kezdődött beszélgetés naplóját?" #, c-format msgid "" -"Are you sure you want to permanently delete the system log which started at " -"%s?" +"Are you sure you want to permanently delete the system log which started at %" +"s?" msgstr "" "Biztos, hogy törölni akarja a(z) %s időpontban kezdődött rendszernaplót?" @@ -15421,8 +15429,8 @@ #, no-c-format msgid "" "Error Installing Spellchecking ($R3).$\\rIf retrying fails, manual " -"installation instructions are at: http://developer.pidgin.im/wiki/Installing" -"%20Pidgin#manual_win32_spellcheck_installation" +"installation instructions are at: http://developer.pidgin.im/wiki/Installing%" +"20Pidgin#manual_win32_spellcheck_installation" msgstr "" "Hiba a helyesírás-ellenőrző telepítésekor. ($R3).$\\rHa az újrapróbálkozás " "meghiúsul, akkor saját kezűleg is telepítheti a http://developer.pidgin.im/"
--- a/po/hy.po Sun Jan 09 04:40:07 2011 +0000 +++ b/po/hy.po Sun Jan 30 17:52:06 2011 +0000 @@ -3,7 +3,6 @@ # This file is distributed under the same license as the PACKAGE package. # David Avsharyan <avsharyan@gmail.com>, 2009. # -#, fuzzy msgid "" msgstr "" "Project-Id-Version: am\n" @@ -16,7 +15,7 @@ "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" +"Plural-Forms: nplurals=1; plural=0;\n" #. Translators may want to transliterate the name. #. It is not to be translated.
--- a/po/mn.po Sun Jan 09 04:40:07 2011 +0000 +++ b/po/mn.po Sun Jan 30 17:52:06 2011 +0000 @@ -15,7 +15,7 @@ "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" +"Plural-Forms: nplurals=1; plural=0;\n" #. Translators may want to transliterate the name. #. It is not to be translated.
--- a/po/ms_MY.po Sun Jan 09 04:40:07 2011 +0000 +++ b/po/ms_MY.po Sun Jan 30 17:52:06 2011 +0000 @@ -15,7 +15,7 @@ "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: KBabel 1.11.4\n" #. Translators may want to transliterate the name.
--- a/po/ta.po Sun Jan 09 04:40:07 2011 +0000 +++ b/po/ta.po Sun Jan 30 17:52:06 2011 +0000 @@ -19,7 +19,7 @@ "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: Plural-Forms: nplurals=2; plural=(n != 1);\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Poedit-Country: INDIA\n" "X-Generator: Lokalize 1.0\n" "X-Poedit-Bookmarks: -1,470,-1,-1,-1,-1,-1,-1,-1,1715\n"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/ca-certs/AddTrust_External_Root.pem Sun Jan 30 17:52:06 2011 +0000 @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU +MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs +IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290 +MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux +FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h +bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v +dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt +H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9 +uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX +mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX +a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN +E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0 +WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD +VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0 +Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU +cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx +IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN +AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH +YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 +6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC +Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX +c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a +mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= +-----END CERTIFICATE-----