static void purple_xfer_ask_recv(PurpleXfer *xfer) { char *buf, *size_buf; size_t size; gconstpointer thumb; gsize thumb_size; /* If we have already accepted the request, ask the destination file name directly */ if (purple_xfer_get_status(xfer) != PURPLE_XFER_STATUS_ACCEPTED) { PurpleBuddy *buddy = purple_find_buddy(xfer->account, xfer->who); if (purple_xfer_get_filename(xfer) != NULL) { size = purple_xfer_get_size(xfer); size_buf = purple_str_size_to_units(size); buf = g_strdup_printf(_("%s wants to send you %s (%s)"), buddy ? purple_buddy_get_alias(buddy) : xfer->who, purple_xfer_get_filename(xfer), size_buf); g_free(size_buf); } else { buf = g_strdup_printf(_("%s wants to send you a file"), buddy ? purple_buddy_get_alias(buddy) : xfer->who); } if (xfer->message != NULL) serv_got_im(purple_account_get_connection(xfer->account), xfer->who, xfer->message, 0, time(NULL)); if ((thumb = purple_xfer_get_thumbnail(xfer, &thumb_size))) { purple_request_accept_cancel_with_icon(xfer, NULL, buf, NULL, PURPLE_DEFAULT_ACTION_NONE, xfer->account, xfer->who, NULL, thumb, thumb_size, xfer, G_CALLBACK(purple_xfer_choose_file), G_CALLBACK(cancel_recv_cb)); } else { purple_request_accept_cancel(xfer, NULL, buf, NULL, PURPLE_DEFAULT_ACTION_NONE, xfer->account, xfer->who, NULL, xfer, G_CALLBACK(purple_xfer_choose_file), G_CALLBACK(cancel_recv_cb)); } g_free(buf); } else purple_xfer_choose_file(xfer); }
static void purple_xfer_conversation_write_internal(PurpleXfer *xfer, const char *message, gboolean is_error, gboolean print_thumbnail) { PurpleConversation *conv = NULL; PurpleMessageFlags flags = PURPLE_MESSAGE_SYSTEM; char *escaped; gconstpointer thumbnail_data; gsize size; g_return_if_fail(xfer != NULL); g_return_if_fail(message != NULL); thumbnail_data = purple_xfer_get_thumbnail(xfer, &size); conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, xfer->who, purple_xfer_get_account(xfer)); if (conv == NULL) return; escaped = g_markup_escape_text(message, -1); if (is_error) flags |= PURPLE_MESSAGE_ERROR; if (print_thumbnail && thumbnail_data) { gchar *message_with_img; gpointer data = g_memdup(thumbnail_data, size); int id = purple_imgstore_add_with_id(data, size, NULL); message_with_img = g_strdup_printf("<img id='%d'> %s", id, escaped); purple_conversation_write(conv, NULL, message_with_img, flags, time(NULL)); purple_imgstore_unref_by_id(id); g_free(message_with_img); } else { purple_conversation_write(conv, NULL, escaped, flags, time(NULL)); } g_free(escaped); }
static gchar * gen_context(PurpleXfer *xfer, const char *file_name, const char *file_path) { gsize size = 0; MsnFileContext *header; gchar *u8 = NULL; gchar *ret; gunichar2 *uni = NULL; glong currentChar = 0; glong len = 0; const char *preview; gsize preview_len; size = purple_xfer_get_size(xfer); purple_xfer_prepare_thumbnail(xfer, "png"); if (!file_name) { gchar *basename = g_path_get_basename(file_path); u8 = purple_utf8_try_convert(basename); g_free(basename); file_name = u8; } uni = g_utf8_to_utf16(file_name, -1, NULL, &len, NULL); if (u8) { g_free(u8); file_name = NULL; u8 = NULL; } preview = purple_xfer_get_thumbnail(xfer, &preview_len); header = g_malloc(sizeof(MsnFileContext) + preview_len); header->length = GUINT32_TO_LE(sizeof(MsnFileContext) - 1); header->version = GUINT32_TO_LE(2); /* V.3 contains additional unnecessary data */ header->file_size = GUINT64_TO_LE(size); if (preview) header->type = GUINT32_TO_LE(0); else header->type = GUINT32_TO_LE(1); len = MIN(len, MAX_FILE_NAME_LEN); for (currentChar = 0; currentChar < len; currentChar++) { header->file_name[currentChar] = GUINT16_TO_LE(uni[currentChar]); } memset(&header->file_name[currentChar], 0x00, (MAX_FILE_NAME_LEN - currentChar) * 2); memset(&header->unknown1, 0, sizeof(header->unknown1)); header->unknown2 = GUINT32_TO_LE(0xffffffff); if (preview) { memcpy(&header->preview, preview, preview_len); } header->preview[preview_len] = '\0'; g_free(uni); ret = purple_base64_encode((const guchar *)header, sizeof(MsnFileContext) + preview_len); g_free(header); return ret; }
static gchar * gen_context(PurpleXfer *xfer, const char *file_name, const char *file_path) { goffset size = 0; MsnFileContext context; gchar *u8 = NULL; gchar *ret; gunichar2 *uni = NULL; glong currentChar = 0; glong len = 0; const char *preview; gsize preview_len; size = purple_xfer_get_size(xfer); purple_xfer_prepare_thumbnail(xfer, "png"); if (!file_name) { gchar *basename = g_path_get_basename(file_path); u8 = purple_utf8_try_convert(basename); g_free(basename); file_name = u8; } uni = g_utf8_to_utf16(file_name, -1, NULL, &len, NULL); if (u8) { g_free(u8); file_name = NULL; u8 = NULL; } preview = purple_xfer_get_thumbnail(xfer, &preview_len); context.length = MSN_FILE_CONTEXT_SIZE_V2; context.version = 2; /* V.3 contains additional unnecessary data */ context.file_size = size; if (preview) context.type = 0; else context.type = 1; len = MIN(len, MAX_FILE_NAME_LEN); for (currentChar = 0; currentChar < len; currentChar++) { context.file_name[currentChar] = GUINT16_TO_LE(uni[currentChar]); } memset(&context.file_name[currentChar], 0x00, (MAX_FILE_NAME_LEN - currentChar) * 2); #if 0 memset(&context.unknown1, 0, sizeof(context.unknown1)); context.unknown2 = 0xffffffff; #endif /* Mind the cast, as in, don't free it after! */ context.preview = (char *)preview; context.preview_len = preview_len; u8 = msn_file_context_to_wire(&context); ret = purple_base64_encode((const guchar *)u8, MSN_FILE_CONTEXT_SIZE_V2 + preview_len); g_free(uni); g_free(u8); return ret; }