# HG changeset patch # User Mark Doliner # Date 1260931400 0 # Node ID fc30836fb714c55f60eb0befb8cc2c49428ddac3 # Parent 57ee55097ec8f4f2fe7cda98477d9bdf300d8288# Parent 57612c4d495b9f3b51ae8fe95d8ab0fdb5e41c7c merge of '8549b9a30115559965e9bf93bb15a45b04c1d149' and 'd1026e37e4b82add833d2a302a41c8f84e4e2bbb' diff -r 57612c4d495b -r fc30836fb714 ChangeLog --- a/ChangeLog Sat Dec 12 01:17:57 2009 +0000 +++ b/ChangeLog Wed Dec 16 02:43:20 2009 +0000 @@ -1,6 +1,10 @@ Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul version 2.6.5 (??/??/20??): + libpurple: + * TLS certificates are actually stored to the local cache once again + (accepting a name mismatch on a certificate should now be remembered) + General: * Build-time fixes for Solaris. (Paul Townsend) @@ -8,6 +12,14 @@ * Messages from some mobile clients are no longer displayed as Chinese characters (broken in 2.6.4) + MSN: + * File transfer requests will no longer cause a crash if you delete the + file before the other side accepts. + * Recieved files will no longer hold an extra lock after completion, + meaning they can be moved or deleted without complaints from your OS. + * Buddies who sign in from a second location will no longer cause an + unnecessary chat window to open. + XMPP: * Added support for the SCRAM-SHA-1 SASL mechanism. This is only available when built without Cyrus SASL support. diff -r 57612c4d495b -r fc30836fb714 libpurple/certificate.c --- a/libpurple/certificate.c Sat Dec 12 01:17:57 2009 +0000 +++ b/libpurple/certificate.c Wed Dec 16 02:43:20 2009 +0000 @@ -1431,9 +1431,8 @@ tls_peers = purple_certificate_find_pool(x509_tls_cached.scheme_name, "tls_peers"); if (tls_peers) { - if (!purple_certificate_pool_contains(tls_peers, vrq->subject_name) && - !purple_certificate_pool_store(tls_peers,vrq->subject_name, - peer_crt)) { + if (!purple_certificate_pool_store(tls_peers,vrq->subject_name, + peer_crt)) { purple_debug_error("certificate/x509/tls_cached", "FAILED to cache peer certificate\n"); } diff -r 57612c4d495b -r fc30836fb714 libpurple/conversation.h --- a/libpurple/conversation.h Sat Dec 12 01:17:57 2009 +0000 +++ b/libpurple/conversation.h Wed Dec 16 02:43:20 2009 +0000 @@ -1025,7 +1025,8 @@ GList *purple_conv_chat_set_users(PurpleConvChat *chat, GList *users); /** - * Returns a list of users in the chat room. + * Returns a list of users in the chat room. The members of the list + * are PurpleConvChatBuddy objects. * * @param chat The chat. * diff -r 57612c4d495b -r fc30836fb714 libpurple/protocols/jabber/jabber.c --- a/libpurple/protocols/jabber/jabber.c Sat Dec 12 01:17:57 2009 +0000 +++ b/libpurple/protocols/jabber/jabber.c Wed Dec 16 02:43:20 2009 +0000 @@ -639,10 +639,11 @@ js->srv_query_data = NULL; if (responses == NULL) { + purple_debug_warning("jabber", "Unable to find alternative XMPP connection " + "methods after failing to connect directly."); purple_connection_error_reason(js->gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, - _("Unable to find alternative XMPP connection " - "methods after failing to connect directly.")); + _("Unable to connect")); return; } diff -r 57612c4d495b -r fc30836fb714 libpurple/protocols/msn/slp.c --- a/libpurple/protocols/msn/slp.c Sat Dec 12 01:17:57 2009 +0000 +++ b/libpurple/protocols/msn/slp.c Wed Dec 16 02:43:20 2009 +0000 @@ -126,22 +126,60 @@ g_free(content); msn_slplink_send_queued_slpmsgs(slpcall->slplink); - msn_slpcall_destroy(slpcall); + if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) + slpcall->wasted = TRUE; + else + msn_slpcall_destroy(slpcall); } } } -void -msn_xfer_progress_cb(MsnSlpCall *slpcall, gsize total_length, gsize len, gsize offset) +gssize +msn_xfer_write(const guchar *data, gsize len, PurpleXfer *xfer) { - PurpleXfer *xfer; + MsnSlpCall *slpcall; + + g_return_val_if_fail(xfer != NULL, -1); + g_return_val_if_fail(data != NULL, -1); + g_return_val_if_fail(len > 0, -1); + + g_return_val_if_fail(purple_xfer_get_type(xfer) == PURPLE_XFER_SEND, -1); + + slpcall = xfer->data; + /* Not sure I trust it'll be there */ + g_return_val_if_fail(slpcall != NULL, -1); + + g_return_val_if_fail(slpcall->xfer_msg != NULL, -1); + + slpcall->u.outgoing.len = len; + slpcall->u.outgoing.data = data; + msn_slplink_send_msgpart(slpcall->slplink, slpcall->xfer_msg); + return MIN(1202, len); +} - xfer = slpcall->xfer; +gssize +msn_xfer_read(guchar **data, PurpleXfer *xfer) +{ + MsnSlpCall *slpcall; + gsize len; + + g_return_val_if_fail(xfer != NULL, -1); + g_return_val_if_fail(data != NULL, -1); + + g_return_val_if_fail(purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE, -1); - xfer->bytes_sent = (offset + len); - xfer->bytes_remaining = total_length - (offset + len); + slpcall = xfer->data; + /* Not sure I trust it'll be there */ + g_return_val_if_fail(slpcall != NULL, -1); - purple_xfer_update_progress(xfer); + /* Just pass up the whole GByteArray. We'll make another. */ + *data = slpcall->u.incoming_data->data; + len = slpcall->u.incoming_data->len; + + g_byte_array_free(slpcall->u.incoming_data, FALSE); + slpcall->u.incoming_data = g_byte_array_new(); + + return len; } void @@ -332,9 +370,7 @@ account = slpcall->slplink->session->account; - slpcall->cb = msn_xfer_completed_cb; slpcall->end_cb = msn_xfer_end_cb; - slpcall->progress_cb = msn_xfer_progress_cb; slpcall->branch = g_strdup(branch); slpcall->pending = TRUE; @@ -357,6 +393,10 @@ purple_xfer_set_init_fnc(xfer, msn_xfer_init); purple_xfer_set_request_denied_fnc(xfer, msn_xfer_cancel); purple_xfer_set_cancel_recv_fnc(xfer, msn_xfer_cancel); + purple_xfer_set_read_fnc(xfer, msn_xfer_read); + purple_xfer_set_write_fnc(xfer, msn_xfer_write); + + slpcall->u.incoming_data = g_byte_array_new(); slpcall->xfer = xfer; purple_xfer_ref(slpcall->xfer); diff -r 57612c4d495b -r fc30836fb714 libpurple/protocols/msn/slp.h --- a/libpurple/protocols/msn/slp.h Sat Dec 12 01:17:57 2009 +0000 +++ b/libpurple/protocols/msn/slp.h Wed Dec 16 02:43:20 2009 +0000 @@ -29,9 +29,6 @@ #include "internal.h" #include "ft.h" -void msn_xfer_progress_cb(MsnSlpCall *slpcall, gsize total_length, gsize - len, gsize offset); - MsnSlpCall * msn_slp_sip_recv(MsnSlpLink *slplink, const char *body); @@ -41,6 +38,9 @@ const guchar *body, gsize size); void msn_xfer_cancel(PurpleXfer *xfer); +gssize msn_xfer_write(const guchar *data, gsize len, PurpleXfer *xfer); +gssize msn_xfer_read(guchar **data, PurpleXfer *xfer); + void msn_xfer_end_cb(MsnSlpCall *slpcall, MsnSession *session); void msn_queue_buddy_icon_request(MsnUser *user); diff -r 57612c4d495b -r fc30836fb714 libpurple/protocols/msn/slpcall.c --- a/libpurple/protocols/msn/slpcall.c Sat Dec 12 01:17:57 2009 +0000 +++ b/libpurple/protocols/msn/slpcall.c Wed Dec 16 02:43:20 2009 +0000 @@ -105,10 +105,13 @@ slpcall->end_cb(slpcall, slpcall->slplink->session); if (slpcall->xfer != NULL) { + if (purple_xfer_get_type(slpcall->xfer) == PURPLE_XFER_RECEIVE) + g_byte_array_free(slpcall->u.incoming_data, TRUE); slpcall->xfer->data = NULL; purple_xfer_unref(slpcall->xfer); } + msn_slplink_remove_slpcall(slpcall->slplink, slpcall); g_free(slpcall->id); @@ -272,7 +275,8 @@ slpcall->timer = 0; } - slpcall->cb(slpcall, body, body_len); + if (slpcall->cb) + slpcall->cb(slpcall, body, body_len); slpcall->wasted = TRUE; } diff -r 57612c4d495b -r fc30836fb714 libpurple/protocols/msn/slpcall.h --- a/libpurple/protocols/msn/slpcall.h Sat Dec 12 01:17:57 2009 +0000 +++ b/libpurple/protocols/msn/slpcall.h Wed Dec 16 02:43:20 2009 +0000 @@ -72,6 +72,14 @@ char *data_info; PurpleXfer *xfer; + union { + GByteArray *incoming_data; + struct { + gsize len; + const guchar *data; + } outgoing; + } u; + MsnSlpMessage *xfer_msg; /* A dirty hack */ MsnSlpCb cb; void (*end_cb)(MsnSlpCall *slpcall, MsnSession *session); diff -r 57612c4d495b -r fc30836fb714 libpurple/protocols/msn/slplink.c --- a/libpurple/protocols/msn/slplink.c Sat Dec 12 01:17:57 2009 +0000 +++ b/libpurple/protocols/msn/slplink.c Wed Dec 16 02:43:20 2009 +0000 @@ -232,7 +232,7 @@ } } -static void +void msn_slplink_send_msgpart(MsnSlpLink *slplink, MsnSlpMessage *slpmsg) { MsnMessage *msg; @@ -247,11 +247,11 @@ if (slpmsg->offset < real_size) { - if (slpmsg->fp) + 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) { - char data[1202]; - len = fread(data, 1, sizeof(data), slpmsg->fp); - msn_message_set_bin_data(msg, data, len); + len = MIN(1202, slpmsg->slpcall->u.outgoing.len); + msn_message_set_bin_data(msg, slpmsg->slpcall->u.outgoing.data, len); } else { @@ -309,7 +309,13 @@ if (slpmsg->offset < real_size) { - msn_slplink_send_msgpart(slpmsg->slplink, slpmsg); + if (slpmsg->slpcall->xfer && purple_xfer_get_status(slpmsg->slpcall->xfer) == PURPLE_XFER_STATUS_STARTED) + { + slpmsg->slpcall->xfer_msg = slpmsg; + purple_xfer_prpl_ready(slpmsg->slpcall->xfer); + } + else + msn_slplink_send_msgpart(slpmsg->slplink, slpmsg); } else { @@ -448,20 +454,22 @@ send_file_cb(MsnSlpCall *slpcall) { MsnSlpMessage *slpmsg; - struct stat st; PurpleXfer *xfer; + xfer = (PurpleXfer *)slpcall->xfer; + purple_xfer_ref(xfer); + purple_xfer_start(xfer, -1, NULL, 0); + if (purple_xfer_get_status(xfer) != PURPLE_XFER_STATUS_STARTED) { + purple_xfer_unref(xfer); + return; + } + purple_xfer_unref(xfer); + slpmsg = msn_slpmsg_new(slpcall->slplink); slpmsg->slpcall = slpcall; slpmsg->flags = 0x1000030; slpmsg->info = "SLP FILE"; - - xfer = (PurpleXfer *)slpcall->xfer; - purple_xfer_start(slpcall->xfer, -1, NULL, 0); - slpmsg->fp = xfer->dest_fp; - if (g_stat(purple_xfer_get_local_filename(xfer), &st) == 0) - slpmsg->size = st.st_size; - xfer->dest_fp = NULL; /* Disable double fclose() */ + slpmsg->size = purple_xfer_get_size(xfer); msn_slplink_send_slpmsg(slpcall->slplink, slpmsg); } @@ -489,6 +497,7 @@ const char *data; guint64 offset; gsize len; + PurpleXfer *xfer = NULL; if (purple_debug_is_verbose()) msn_slpmsg_show(msg); @@ -525,12 +534,12 @@ if (slpmsg->flags == 0x20 || slpmsg->flags == 0x1000020 || slpmsg->flags == 0x1000030) { - PurpleXfer *xfer; - xfer = slpmsg->slpcall->xfer; - if (xfer != NULL) { + slpmsg->ft = TRUE; + slpmsg->slpcall->xfer_msg = slpmsg; + purple_xfer_ref(xfer); purple_xfer_start(xfer, -1, NULL, 0); @@ -540,14 +549,12 @@ g_return_if_reached(); } else { purple_xfer_unref(xfer); - slpmsg->fp = xfer->dest_fp; - xfer->dest_fp = NULL; /* Disable double fclose() */ } } } } } - if (!slpmsg->fp && slpmsg->size) + if (!slpmsg->ft && slpmsg->size) { slpmsg->buffer = g_try_malloc(slpmsg->size); if (slpmsg->buffer == NULL) @@ -569,10 +576,12 @@ } } - if (slpmsg->fp) + if (slpmsg->ft) { - /* fseek(slpmsg->fp, offset, SEEK_SET); */ - len = fwrite(data, 1, len, slpmsg->fp); + xfer = slpmsg->slpcall->xfer; + slpmsg->slpcall->u.incoming_data = + g_byte_array_append(slpmsg->slpcall->u.incoming_data, (const guchar *)data, len); + purple_xfer_prpl_ready(xfer); } else if (slpmsg->size && slpmsg->buffer) { @@ -613,29 +622,37 @@ slpcall = msn_slp_process_msg(slplink, slpmsg); - if (slpmsg->flags == 0x100) - { - MsnDirectConn *directconn; + if (slpcall == NULL) { + msn_slpmsg_destroy(slpmsg); + return; + } - directconn = slplink->directconn; + if (!slpcall->wasted) { + if (slpmsg->flags == 0x100) + { + MsnDirectConn *directconn; + + directconn = slplink->directconn; #if 0 - if (!directconn->acked) - msn_directconn_send_handshake(directconn); + if (!directconn->acked) + msn_directconn_send_handshake(directconn); #endif - } - else if (slpmsg->flags == 0x00 || slpmsg->flags == 0x1000000 || - slpmsg->flags == 0x20 || slpmsg->flags == 0x1000020 || - slpmsg->flags == 0x1000030) - { - /* Release all the messages and send the ACK */ + } + else if (slpmsg->flags == 0x00 || slpmsg->flags == 0x1000000 || + slpmsg->flags == 0x20 || slpmsg->flags == 0x1000020 || + slpmsg->flags == 0x1000030) + { + /* Release all the messages and send the ACK */ - msn_slplink_send_ack(slplink, msg); - msn_slplink_send_queued_slpmsgs(slplink); + msn_slplink_send_ack(slplink, msg); + msn_slplink_send_queued_slpmsgs(slplink); + } + } msn_slpmsg_destroy(slpmsg); - if (slpcall != NULL && slpcall->wasted) + if (slpcall->wasted) msn_slpcall_destroy(slpcall); } } @@ -732,7 +749,6 @@ slpcall->session_init_cb = send_file_cb; slpcall->end_cb = msn_xfer_end_cb; - slpcall->progress_cb = msn_xfer_progress_cb; slpcall->cb = msn_xfer_completed_cb; slpcall->xfer = xfer; purple_xfer_ref(slpcall->xfer); @@ -740,6 +756,8 @@ slpcall->pending = TRUE; purple_xfer_set_cancel_send_fnc(xfer, msn_xfer_cancel); + purple_xfer_set_read_fnc(xfer, msn_xfer_read); + purple_xfer_set_write_fnc(xfer, msn_xfer_write); xfer->data = slpcall; diff -r 57612c4d495b -r fc30836fb714 libpurple/protocols/msn/slplink.h --- a/libpurple/protocols/msn/slplink.h Sat Dec 12 01:17:57 2009 +0000 +++ b/libpurple/protocols/msn/slplink.h Wed Dec 16 02:43:20 2009 +0000 @@ -84,6 +84,9 @@ void msn_slplink_process_msg(MsnSlpLink *slplink, MsnMessage *msg); void msn_slplink_request_ft(MsnSlpLink *slplink, PurpleXfer *xfer); +/* Only exported for msn_xfer_write */ +void msn_slplink_send_msgpart(MsnSlpLink *slplink, MsnSlpMessage *slpmsg); + void msn_slplink_request_object(MsnSlpLink *slplink, const char *info, MsnSlpCb cb, diff -r 57612c4d495b -r fc30836fb714 libpurple/protocols/msn/slpmsg.c --- a/libpurple/protocols/msn/slpmsg.c Sat Dec 12 01:17:57 2009 +0000 +++ b/libpurple/protocols/msn/slpmsg.c Wed Dec 16 02:43:20 2009 +0000 @@ -60,9 +60,6 @@ slplink = slpmsg->slplink; - if (slpmsg->fp != NULL) - fclose(slpmsg->fp); - purple_imgstore_unref(slpmsg->img); /* We don't want to free the data of the PurpleStoredImage, @@ -96,7 +93,7 @@ /* We can only have one data source at a time. */ g_return_if_fail(slpmsg->buffer == NULL); g_return_if_fail(slpmsg->img == NULL); - g_return_if_fail(slpmsg->fp == NULL); + g_return_if_fail(slpmsg->ft == FALSE); if (body != NULL) slpmsg->buffer = g_memdup(body, size); @@ -112,7 +109,7 @@ /* We can only have one data source at a time. */ g_return_if_fail(slpmsg->buffer == NULL); g_return_if_fail(slpmsg->img == NULL); - g_return_if_fail(slpmsg->fp == NULL); + g_return_if_fail(slpmsg->ft == FALSE); slpmsg->img = purple_imgstore_ref(img); slpmsg->buffer = (guchar *)purple_imgstore_get_data(img); diff -r 57612c4d495b -r fc30836fb714 libpurple/protocols/msn/slpmsg.h --- a/libpurple/protocols/msn/slpmsg.h Sat Dec 12 01:17:57 2009 +0000 +++ b/libpurple/protocols/msn/slpmsg.h Wed Dec 16 02:43:20 2009 +0000 @@ -54,7 +54,7 @@ gboolean sip; /**< A flag that states if this is a SIP slp message. */ long flags; - FILE *fp; + gboolean ft; PurpleStoredImage *img; guchar *buffer; long long offset; diff -r 57612c4d495b -r fc30836fb714 libpurple/protocols/msn/switchboard.c --- a/libpurple/protocols/msn/switchboard.c Sat Dec 12 01:17:57 2009 +0000 +++ b/libpurple/protocols/msn/switchboard.c Wed Dec 16 02:43:20 2009 +0000 @@ -222,13 +222,28 @@ { MsnCmdProc *cmdproc; PurpleAccount *account; + char *semicolon; + char *passport; g_return_if_fail(swboard != NULL); cmdproc = swboard->cmdproc; account = cmdproc->session->account; - swboard->users = g_list_prepend(swboard->users, g_strdup(user)); + semicolon = strchr(user, ';'); + /* We don't really care about the machine ID. */ + if (semicolon) + passport = g_strndup(user, semicolon - user); + else + passport = g_strdup(user); + + /* Don't add multiple endpoints to the conversation. */ + if (g_list_find_custom(swboard->users, passport, (GCompareFunc)strcmp)) { + g_free(passport); + return; + } + + swboard->users = g_list_prepend(swboard->users, passport); swboard->current_users++; swboard->empty = FALSE; diff -r 57612c4d495b -r fc30836fb714 libpurple/tests/Makefile.am --- a/libpurple/tests/Makefile.am Sat Dec 12 01:17:57 2009 +0000 +++ b/libpurple/tests/Makefile.am Wed Dec 16 02:43:20 2009 +0000 @@ -27,11 +27,11 @@ -DBUILDDIR=\"$(top_builddir)\" check_libpurple_LDADD=\ - @CHECK_LIBS@ \ - $(GLIB_LIBS) \ $(top_builddir)/libpurple/protocols/jabber/libjabber.la \ $(top_builddir)/libpurple/protocols/qq/libqq.la \ $(top_builddir)/libpurple/protocols/yahoo/libymsg.la \ - $(top_builddir)/libpurple/libpurple.la + $(top_builddir)/libpurple/libpurple.la \ + @CHECK_LIBS@ \ + $(GLIB_LIBS) endif diff -r 57612c4d495b -r fc30836fb714 libpurple/tests/check_libpurple.c --- a/libpurple/tests/check_libpurple.c Sat Dec 12 01:17:57 2009 +0000 +++ b/libpurple/tests/check_libpurple.c Wed Dec 16 02:43:20 2009 +0000 @@ -44,7 +44,7 @@ purple_eventloop_set_ui_ops(&eventloop_ui_ops); /* build our fake home directory */ - home_dir = g_build_path(BUILDDIR, "libpurple", "tests", "home", NULL); + home_dir = g_build_path(G_DIR_SEPARATOR_S, BUILDDIR, "libpurple", "tests", "home", NULL); purple_util_set_user_dir(home_dir); g_free(home_dir); @@ -67,6 +67,9 @@ int number_failed; SRunner *sr; + if (g_getenv("PURPLE_CHECK_DEBUG")) + purple_debug_set_enabled(TRUE); + /* Make g_return_... functions fatal, ALWAYS. * As this is the test code, this is NOT controlled * by PURPLE_FATAL_ASSERTS. */ diff -r 57612c4d495b -r fc30836fb714 libpurple/tests/test_cipher.c --- a/libpurple/tests/test_cipher.c Sat Dec 12 01:17:57 2009 +0000 +++ b/libpurple/tests/test_cipher.c Wed Dec 16 02:43:20 2009 +0000 @@ -142,12 +142,13 @@ PurpleCipherContext *context = NULL; \ gchar cdigest[41]; \ gboolean ret = FALSE; \ + gchar *input = data; \ \ cipher = purple_ciphers_find_cipher("sha1"); \ context = purple_cipher_context_new(cipher, NULL); \ \ - if((data)) { \ - purple_cipher_context_append(context, (guchar *)(data), strlen((data))); \ + if (input) { \ + purple_cipher_context_append(context, (guchar *)input, strlen(input)); \ } else { \ gint j; \ guchar buff[1000]; \ @@ -202,12 +203,13 @@ PurpleCipherContext *context = NULL; \ gchar cdigest[65]; \ gboolean ret = FALSE; \ + gchar *input = data; \ \ cipher = purple_ciphers_find_cipher("sha256"); \ context = purple_cipher_context_new(cipher, NULL); \ \ - if((data)) { \ - purple_cipher_context_append(context, (guchar *)(data), strlen((data))); \ + if (input) { \ + purple_cipher_context_append(context, (guchar *)input, strlen(input)); \ } else { \ gint j; \ guchar buff[1000]; \