PurpleBuddyIcon * purple_buddy_icon_unref(PurpleBuddyIcon *icon) { if (icon == NULL) return NULL; g_return_val_if_fail(icon->ref_count > 0, NULL); icon->ref_count--; if (icon->ref_count == 0) { GHashTable *icon_cache = g_hash_table_lookup(account_cache, purple_buddy_icon_get_account(icon)); if (icon_cache != NULL) g_hash_table_remove(icon_cache, purple_buddy_icon_get_username(icon)); g_free(icon->username); g_free(icon->checksum); purple_imgstore_unref(icon->img); PURPLE_DBUS_UNREGISTER_POINTER(icon); g_slice_free(PurpleBuddyIcon, icon); return NULL; } return icon; }
PurpleStoredImage * purple_buddy_icons_set_account_icon(PurpleAccount *account, guchar *icon_data, size_t icon_len) { PurpleStoredImage *old_img; PurpleStoredImage *img = NULL; char *old_icon; if (icon_data != NULL && icon_len > 0) { img = purple_buddy_icon_data_new(icon_data, icon_len, NULL); } old_icon = g_strdup(purple_account_get_string(account, "buddy_icon", NULL)); if (img && purple_buddy_icons_is_caching()) { const char *filename = purple_imgstore_get_filename(img); purple_account_set_string(account, "buddy_icon", filename); purple_account_set_int(account, "buddy_icon_timestamp", time(NULL)); ref_filename(filename); } else { purple_account_set_string(account, "buddy_icon", NULL); purple_account_set_int(account, "buddy_icon_timestamp", 0); } unref_filename(old_icon); old_img = g_hash_table_lookup(pointer_icon_cache, account); if (img) g_hash_table_insert(pointer_icon_cache, account, img); else g_hash_table_remove(pointer_icon_cache, account); if (purple_account_is_connected(account)) { PurpleConnection *gc; PurplePluginProtocolInfo *prpl_info; gc = purple_account_get_connection(account); prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); if (prpl_info && prpl_info->set_buddy_icon) prpl_info->set_buddy_icon(gc, img); } if (old_img) purple_imgstore_unref(old_img); else if (old_icon) { /* The old icon may not have been loaded into memory. In that * case, we'll need to uncache the filename. The filenames * are ref-counted, so this is safe. */ purple_buddy_icon_data_uncache_file(old_icon); } g_free(old_icon); return img; }
void purple_buddy_icon_set_data(PurpleBuddyIcon *icon, guchar *data, size_t len, const char *checksum) { PurpleStoredImage *old_img; g_return_if_fail(icon != NULL); old_img = icon->img; icon->img = NULL; if (data != NULL) { if (len > 0) icon->img = purple_buddy_icon_data_new(data, len, NULL); else g_free(data); } g_free(icon->checksum); icon->checksum = g_strdup(checksum); purple_buddy_icon_update(icon); purple_imgstore_unref(old_img); }
void msn_session_finish_login(MsnSession *session) { PurpleAccount *account; PurpleConnection *gc; PurpleStoredImage *img; if (!session->logged_in) { account = session->account; gc = purple_account_get_connection(account); img = purple_buddy_icons_find_account_icon(session->account); /* TODO: Do we really want to call this if img is NULL? */ msn_user_set_buddy_icon(session->user, img); if (img != NULL) purple_imgstore_unref(img); session->logged_in = TRUE; purple_connection_set_state(gc, PURPLE_CONNECTED); /* Sync users */ msn_session_sync_users(session); } /* TODO: Send this when updating status instead? */ msn_notification_send_uux_endpointdata(session); msn_notification_send_uux_private_endpointdata(session); msn_change_status(session); }
static void purple_smiley_set_data_impl(PurpleSmiley *smiley, guchar *smiley_data, size_t smiley_data_len) { PurpleStoredImage *old_img, *new_img; const char *old_filename = NULL; const char *new_filename = NULL; g_return_if_fail(smiley != NULL); g_return_if_fail(smiley_data != NULL); g_return_if_fail(smiley_data_len > 0); old_img = smiley->img; new_img = purple_smiley_data_new(smiley_data, smiley_data_len); g_object_set(G_OBJECT(smiley), PROP_IMGSTORE_S, new_img, NULL); /* If the old and new image files have different names we need * to unstore old image file. */ if (!old_img) return; old_filename = purple_imgstore_get_filename(old_img); new_filename = purple_imgstore_get_filename(smiley->img); if (g_ascii_strcasecmp(old_filename, new_filename)) purple_smiley_data_unstore(old_filename); purple_imgstore_unref(old_img); }
void purple_imgstore_unref_by_id(int id) { PurpleStoredImage *img = purple_imgstore_find_by_id(id); g_return_if_fail(img != NULL); purple_imgstore_unref(img); }
void msn_object_set_image(MsnObject *obj, PurpleStoredImage *img) { g_return_if_fail(obj != NULL); g_return_if_fail(img != NULL); /* obj->local = TRUE; */ purple_imgstore_unref(obj->img); obj->img = purple_imgstore_ref(img); }
void msn_slpmsg_destroy(MsnSlpMessage *slpmsg) { MsnSlpLink *slplink; GList *cur; g_return_if_fail(slpmsg != NULL); #ifdef MSN_DEBUG_SLPMSG purple_debug_info("msn", "slpmsg destroy (%p)\n", slpmsg); #endif 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, * but to avoid code duplication, it's sharing buffer. */ if (slpmsg->img == NULL) g_free(slpmsg->buffer); #ifdef MSN_DEBUG_SLP /* if (slpmsg->info != NULL) g_free(slpmsg->info); */ #endif for (cur = slpmsg->msgs; cur != NULL; cur = cur->next) { /* Something is pointing to this slpmsg, so we should remove that * pointer to prevent a crash. */ /* Ex: a user goes offline and after that we receive an ACK */ MsnMessage *msg = cur->data; #ifdef MSN_DEBUG_SLPMSG purple_debug_info("msn", "Unlink slpmsg callbacks.\n"); #endif msg->ack_cb = NULL; msg->nak_cb = NULL; msg->ack_data = NULL; } g_list_free(slpmsg->msgs); slplink->slp_msgs = g_list_remove(slplink->slp_msgs, slpmsg); g_free(slpmsg); }
void msn_object_destroy(MsnObject *obj) { g_return_if_fail(obj != NULL); g_free(obj->creator); g_free(obj->location); g_free(obj->friendly); g_free(obj->sha1d); g_free(obj->sha1c); purple_imgstore_unref(obj->img); if (obj->local) local_objs = g_list_remove(local_objs, obj); g_free(obj); }
void msn_session_finish_login (MsnSession *session) { PurpleAccount *account; PurpleStoredImage *img; if (session->logged_in) return; account = msn_session_get_user_data (session); #ifdef HAVE_LIBPURPLE sync_users (session); #endif img = purple_buddy_icons_find_account_icon (account); { struct pn_buffer *image; if (img) image = pn_buffer_new_memdup ((const gpointer) purple_imgstore_get_data (img), purple_imgstore_get_size (img)); else image = NULL; pn_contact_set_buddy_icon (session->user, image); } purple_imgstore_unref (img); session->logged_in = TRUE; /** @todo move this to msn.c */ pn_update_status (session); pn_update_personal_message (session); pn_timeout_tune_status (session); { PurpleConnection *connection; connection = purple_account_get_connection (account); purple_connection_set_state (connection, PURPLE_CONNECTED); } pn_contactlist_check_pending (session->contactlist); }
void msn_session_finish_login(MsnSession *session) { PurpleAccount *account; PurpleConnection *gc; PurpleStoredImage *img; const char *passport; if (session->logged_in) { /* We are probably here because of a mid-session notification server XFR * We must send a CHG now, otherwise the servers default to invisible, * and prevent things happening, like sending IMs */ msn_change_status(session); return; } account = session->account; gc = purple_account_get_connection(account); img = purple_buddy_icons_find_account_icon(session->account); msn_user_set_buddy_icon(session->user, img); purple_imgstore_unref(img); session->logged_in = TRUE; msn_change_status(session); purple_connection_set_state(gc, PURPLE_CONNECTED); /* Sync users */ msn_session_sync_users(session); /* It seems that some accounts that haven't accessed hotmail for a while * and @msn.com accounts don't automatically get the initial email * notification so we always request it on login */ passport = purple_normalize(account, purple_account_get_username(account)); if ((strstr(passport, "@hotmail.") != NULL) || (strstr(passport, "@msn.com") != NULL)) { msn_cmdproc_send(session->notification->cmdproc, "URL", "%s", "INBOX"); } }
void UploadPortrait(gpointer data, gint source, const gchar * error_message) { struct fetion_account_data *sip = data; PurpleStoredImage *img = sip->icon; gchar *head; gchar *buf; gint head_len; gint ret, lenth, writed; gconstpointer img_data = purple_imgstore_get_data(img); size_t size = purple_imgstore_get_size(img); head = g_strdup_printf("POST /%s/setportrait.aspx HTTP/1.1\r\n" "User-Agent: IIC2.0/PC 3.3.0370\r\n" "Content-Type: image/jpeg\r\n" "Host: %s\r\n" "Cookie: ssic=%s\r\n" "Content-Length: %d\r\n\r\n", sip->UploadPrefix, sip->UploadServer, sip->ssic, size); purple_debug_info("fetion:", "UploadPortrait:head[%s][%d]\n", head, size); head_len = strlen(head); buf = g_malloc(head_len + size); memcpy(buf, head, head_len); memcpy(buf + head_len, img_data, size); lenth = size + strlen(head); writed = 0; ret = write(source, buf, lenth); if (ret < 0 && errno == EAGAIN) ret = 0; g_return_if_fail(ret >= 0); if (ret < lenth) { purple_circ_buffer_append(sip->icon_buf, buf + ret, lenth - ret); sip->icon_handler = purple_input_add(source, PURPLE_INPUT_WRITE, (PurpleInputFunction) UploadPortrait_cb, sip); } g_free(head); sip->icon = NULL; purple_imgstore_unref(img); }
void bonjour_dns_sd_update_buddy_icon(BonjourDnsSd *data) { PurpleStoredImage *img; if ((img = purple_buddy_icons_find_account_icon(data->account))) { gconstpointer avatar_data; gsize avatar_len; avatar_data = purple_imgstore_get_data(img); avatar_len = purple_imgstore_get_size(img); if (_mdns_set_buddy_icon_data(data, avatar_data, avatar_len)) { /* The filename is a SHA-1 hash of the data (conveniently what we need) */ const char *p, *filename = purple_imgstore_get_filename(img); g_free(data->phsh); data->phsh = NULL; /* Get rid of the extension */ p = strchr(filename, '.'); if (p) data->phsh = g_strndup(filename, p - filename); else purple_debug_error("bonjour", "account buddy icon returned unexpected filename (%s)" "; unable to extract hash. Clearing buddy icon\n", filename); /* Update our TXT record */ publish_presence(data, PUBLISH_UPDATE); } purple_imgstore_unref(img); } else { /* We need to do this regardless of whether data->phsh is set so that we * cancel any icons that are currently in the process of being set */ _mdns_set_buddy_icon_data(data, NULL, 0); if (data->phsh != NULL) { /* Clear the buddy icon */ g_free(data->phsh); data->phsh = NULL; /* Update our TXT record */ publish_presence(data, PUBLISH_UPDATE); } } }
static void purple_smiley_finalize(GObject *obj) { PurpleSmiley *smiley = PURPLE_SMILEY(obj); if (g_hash_table_lookup(smiley_shortcut_index, smiley->shortcut)) { g_hash_table_remove(smiley_shortcut_index, smiley->shortcut); g_hash_table_remove(smiley_checksum_index, smiley->checksum); } g_free(smiley->shortcut); g_free(smiley->checksum); if (smiley->img) purple_smiley_data_unstore(purple_imgstore_get_filename(smiley->img)); purple_imgstore_unref(smiley->img); PURPLE_DBUS_UNREGISTER_POINTER(smiley); purple_smileys_save(); }
void msn_slpmsg_destroy(MsnSlpMessage *slpmsg) { MsnSlpLink *slplink; GList *cur; g_return_if_fail(slpmsg != NULL); if (purple_debug_is_verbose()) purple_debug_info("msn", "slpmsg destroy (%p)\n", slpmsg); slplink = slpmsg->slplink; purple_imgstore_unref(slpmsg->img); /* We don't want to free the data of the PurpleStoredImage, * but to avoid code duplication, it's sharing buffer. */ if (slpmsg->img == NULL) g_free(slpmsg->buffer); for (cur = slpmsg->parts; cur != NULL; cur = g_list_delete_link(cur, cur)) { /* Something is pointing to this slpmsg, so we should remove that * pointer to prevent a crash. */ /* Ex: a user goes offline and after that we receive an ACK */ MsnSlpMessagePart *part = cur->data; part->ack_cb = NULL; part->nak_cb = NULL; part->ack_data = NULL; msn_slpmsgpart_unref(part); } slplink->slp_msgs = g_list_remove(slplink->slp_msgs, slpmsg); msn_p2p_info_free(slpmsg->p2p_info); g_free(slpmsg); }
void msn_session_finish_login(MsnSession *session) { PurpleAccount *account; PurpleConnection *gc; PurpleStoredImage *img; const char *passport; if (session->logged_in) return; account = session->account; gc = purple_account_get_connection(account); img = purple_buddy_icons_find_account_icon(session->account); msn_user_set_buddy_icon(session->user, img); purple_imgstore_unref(img); session->logged_in = TRUE; msn_change_status(session); purple_connection_set_state(gc, PURPLE_CONNECTED); /* Sync users */ msn_session_sync_users(session); /* It seems that some accounts that haven't accessed hotmail for a while * and @msn.com accounts don't automatically get the initial email * notification so we always request it on login */ passport = purple_normalize(account, purple_account_get_username(account)); if ((strstr(passport, "@hotmail.") != NULL) || (strstr(passport, "@msn.com") != NULL)) { msn_cmdproc_send(session->notification->cmdproc, "URL", "%s", "INBOX"); } }
static void purple_smiley_set_property(GObject *object, guint param_id, const GValue *value, GParamSpec *spec) { PurpleSmiley *smiley = PURPLE_SMILEY(object); PurpleSmileyPrivate *priv = PURPLE_SMILEY_GET_PRIVATE(smiley); switch (param_id) { case PROP_SHORTCUT: { const char *shortcut = g_value_get_string(value); purple_smiley_set_shortcut(smiley, shortcut); } break; case PROP_IMGSTORE: { PurpleStoredImage *img = g_value_get_pointer(value); purple_imgstore_unref(priv->img); g_free(priv->checksum); priv->img = img; if (img) { priv->checksum = g_compute_checksum_for_data( G_CHECKSUM_SHA1, purple_imgstore_get_data(img), purple_imgstore_get_size(img)); purple_smiley_data_store(img); } else { priv->checksum = NULL; } } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, spec); break; } }
static void purple_smiley_set_property(GObject *object, guint param_id, const GValue *value, GParamSpec *spec) { PurpleSmiley *smiley = PURPLE_SMILEY(object); switch (param_id) { case PROP_SHORTCUT: { const char *shortcut = g_value_get_string(value); purple_smiley_set_shortcut(smiley, shortcut); } break; case PROP_IMGSTORE: { PurpleStoredImage *img = g_value_get_pointer(value); purple_imgstore_unref(smiley->img); g_free(smiley->checksum); smiley->img = img; if (img) { smiley->checksum = purple_util_get_image_checksum( purple_imgstore_get_data(img), purple_imgstore_get_size(img)); purple_smiley_data_store(img); } else { smiley->checksum = NULL; } g_object_notify(object, PROP_IMGSTORE_S); } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, spec); break; } }
PurpleStoredImage * purple_buddy_icons_node_set_custom_icon(PurpleBlistNode *node, guchar *icon_data, size_t icon_len) { char *old_icon; PurpleStoredImage *old_img; PurpleStoredImage *img = NULL; g_return_val_if_fail(node != NULL, NULL); if (!PURPLE_BLIST_NODE_IS_CONTACT(node) && !PURPLE_BLIST_NODE_IS_CHAT(node) && !PURPLE_BLIST_NODE_IS_GROUP(node)) { return NULL; } old_img = g_hash_table_lookup(pointer_icon_cache, node); if (icon_data != NULL && icon_len > 0) { img = purple_buddy_icon_data_new(icon_data, icon_len, NULL); } old_icon = g_strdup(purple_blist_node_get_string(node, "custom_buddy_icon")); if (img && purple_buddy_icons_is_caching()) { const char *filename = purple_imgstore_get_filename(img); purple_blist_node_set_string(node, "custom_buddy_icon", filename); ref_filename(filename); } else { purple_blist_node_remove_setting(node, "custom_buddy_icon"); } unref_filename(old_icon); if (img) g_hash_table_insert(pointer_icon_cache, node, img); else g_hash_table_remove(pointer_icon_cache, node); if (PURPLE_BLIST_NODE_IS_CONTACT(node)) { PurpleBlistNode *child; for (child = purple_blist_node_get_first_child(node); child; child = purple_blist_node_get_sibling_next(child)) { PurpleBuddy *buddy; PurpleConversation *conv; if (!PURPLE_BLIST_NODE_IS_BUDDY(child)) continue; buddy = (PurpleBuddy *)child; conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, purple_buddy_get_name(buddy), purple_buddy_get_account(buddy)); if (conv) purple_conversation_update(conv, PURPLE_CONV_UPDATE_ICON); /* Is this call necessary anymore? Can the buddies * themselves need updating when the custom buddy * icon changes? */ purple_blist_update_node_icon((PurpleBlistNode*)buddy); } } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) { PurpleConversation *conv = NULL; conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, purple_chat_get_name((PurpleChat*)node), purple_chat_get_account((PurpleChat*)node)); if (conv) { purple_conversation_update(conv, PURPLE_CONV_UPDATE_ICON); } } purple_blist_update_node_icon(node); if (old_img) { purple_imgstore_unref(old_img); } else if (old_icon) { /* The old icon may not have been loaded into memory. In that * case, we'll need to uncache the filename. The filenames * are ref-counted, so this is safe. */ purple_buddy_icon_data_uncache_file(old_icon); } g_free(old_icon); return img; }
static void got_sessionreq(MsnSlpCall *slpcall, const char *branch, const char *euf_guid, const char *context) { pecan_debug ("euf_guid=[%s]", euf_guid); if (!strcmp(euf_guid, "A4268EEC-FEC5-49E5-95C3-F126696BDBF6")) { /* Emoticon or UserDisplay */ char *content; gsize len; MsnSlpSession *slpsession; MsnSlpLink *slplink; MsnSlpMessage *slpmsg; MsnObject *obj; char *msnobj_data; PecanBuffer *image; int type; /* Send Ok */ content = pecan_strdup_printf("SessionID: %lu\r\n\r\n", slpcall->session_id); send_ok(slpcall, branch, "application/x-msnmsgr-sessionreqbody", content); g_free(content); slplink = slpcall->slplink; msnobj_data = (char *)purple_base64_decode(context, &len); obj = msn_object_new_from_string(msnobj_data); type = msn_object_get_type(obj); g_free(msnobj_data); if (type == MSN_OBJECT_USERTILE) { /* image is owned by a local object, not obj */ image = msn_object_get_image(obj); } #if PURPLE_VERSION_CHECK(2,5,0) else if (type == MSN_OBJECT_EMOTICON) { PurpleStoredImage *img; char *path; path = g_build_filename(purple_smileys_get_storing_dir(), msn_object_get_location(obj), NULL); img = purple_imgstore_new_from_file(path); image = pecan_buffer_new_memdup ((const gpointer) purple_imgstore_get_data (img), purple_imgstore_get_size (img)); purple_imgstore_unref(img); g_free(path); } #endif /* PURPLE_VERSION_CHECK(2,5,0) */ else { pecan_error ("Wrong object?"); msn_object_destroy(obj); g_return_if_reached(); } if (!image) { pecan_error ("Wrong object"); msn_object_destroy (obj); g_return_if_reached (); } msn_object_destroy(obj); { gchar *tmp; tmp = msn_object_to_string (obj); pecan_info ("object requested: %s", tmp); g_free (tmp); } slpsession = msn_slplink_find_slp_session(slplink, slpcall->session_id); /* DATA PREP */ slpmsg = msn_slpmsg_new(slplink); slpmsg->slpcall = slpcall; slpmsg->slpsession = slpsession; slpmsg->session_id = slpsession->id; msn_slpmsg_set_body(slpmsg, NULL, 4); #ifdef PECAN_DEBUG_SLP slpmsg->info = "SLP DATA PREP"; #endif msn_slplink_queue_slpmsg(slplink, slpmsg); /* DATA */ slpmsg = msn_slpmsg_new(slplink); slpmsg->slpcall = slpcall; slpmsg->slpsession = slpsession; slpmsg->flags = 0x20; #ifdef PECAN_DEBUG_SLP slpmsg->info = "SLP DATA"; #endif msn_slpmsg_set_image (slpmsg, image); msn_slplink_queue_slpmsg(slplink, slpmsg); } else if (!strcmp(euf_guid, "5D3E02AB-6190-11D3-BBBB-00C04F795683")) { /* File Transfer */ PurpleAccount *account; PurpleXfer *xfer; char *bin; gsize bin_len; guint32 file_size; char *file_name; gunichar2 *uni_name; 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; xfer = purple_xfer_new(account, PURPLE_XFER_RECEIVE, slpcall->slplink->remote_user); if (xfer) { bin = (char *)purple_base64_decode(context, &bin_len); file_size = GUINT32_FROM_LE(*(gsize *)(bin + 8)); uni_name = (gunichar2 *)(bin + 20); while(*uni_name != 0 && ((char *)uni_name - (bin + 20)) < MAX_FILE_NAME_LEN) { *uni_name = GUINT16_FROM_LE(*uni_name); uni_name++; } file_name = g_utf16_to_utf8((const gunichar2 *)(bin + 20), -1, NULL, NULL, NULL); g_free(bin); purple_xfer_set_filename(xfer, file_name); purple_xfer_set_size(xfer, file_size); 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); slpcall->xfer = xfer; purple_xfer_ref(slpcall->xfer); xfer->data = slpcall; purple_xfer_request(xfer); } } }