static void delete_buddy_icon_settings(PurpleBlistNode *node, const char *setting_name) { purple_blist_node_remove_setting(node, setting_name); if (purple_strequal(setting_name, "buddy_icon")) { purple_blist_node_remove_setting(node, "avatar_hash"); purple_blist_node_remove_setting(node, "icon_checksum"); } }
static void buddytimezone_submitfields_cb(PurpleRequestFields * fields, PurpleBlistNode * data) { PurpleBlistNode *node; PurpleRequestField *list; /* timezone stuff */ purple_debug(PURPLE_DEBUG_INFO, PLUGIN_STATIC_NAME, "buddytimezone_submitfields_cb(%p,%p)\n", fields, data); switch (data->type) { case PURPLE_BLIST_BUDDY_NODE: node = (PurpleBlistNode *) purple_buddy_get_contact((PurpleBuddy *) data); break; case PURPLE_BLIST_CONTACT_NODE: case PURPLE_BLIST_GROUP_NODE: /* code handles either case */ node = data; break; case PURPLE_BLIST_CHAT_NODE: case PURPLE_BLIST_OTHER_NODE: default: /* Not applicable */ return; } list = purple_request_fields_get_field(fields, CONTROL_NAME); if (ui_ops != NULL && ui_ops->get_timezone_menu_selection != NULL) { const char *seldata = ui_ops->get_timezone_menu_selection(list->ui_data); if (seldata == NULL) purple_blist_node_remove_setting(node, SETTING_NAME); else purple_blist_node_set_string(node, SETTING_NAME, seldata); } else { const GList *sellist; void *seldata = NULL; sellist = purple_request_field_list_get_selected(list); if (sellist) seldata = purple_request_field_list_get_data(list, sellist->data); /* Otherwise, it's fixed value and this means deletion */ if (seldata == TIMEZONE_FLAG) purple_blist_node_set_string(node, SETTING_NAME, sellist->data); else if (seldata == DISABLED_FLAG) purple_blist_node_set_string(node, SETTING_NAME, "none"); else purple_blist_node_remove_setting(node, SETTING_NAME); } }
void purple_buddy_icons_set_for_user(PurpleAccount *account, const char *username, void *icon_data, size_t icon_len, const char *checksum) { GHashTable *icon_cache; PurpleBuddyIcon *icon = NULL; g_return_if_fail(account != NULL); g_return_if_fail(username != NULL); icon_cache = g_hash_table_lookup(account_cache, account); if (icon_cache != NULL) icon = g_hash_table_lookup(icon_cache, username); if (icon != NULL) purple_buddy_icon_set_data(icon, icon_data, icon_len, checksum); else if (icon_data && icon_len > 0) { PurpleBuddyIcon *icon = purple_buddy_icon_new(account, username, icon_data, icon_len, checksum); /* purple_buddy_icon_new() calls * purple_buddy_icon_set_data(), which calls * purple_buddy_icon_update(), which has the buddy list * and conversations take references as appropriate. * This function doesn't return icon, so we can't * leave a reference dangling. */ purple_buddy_icon_unref(icon); } else { /* If the buddy list or a conversation was holding a * reference, we'd have found the icon in the cache. * Since we know we're deleting the icon, we only * need a subset of purple_buddy_icon_update(). */ GSList *buddies = purple_find_buddies(account, username); while (buddies != NULL) { PurpleBuddy *buddy = (PurpleBuddy *)buddies->data; unref_filename(purple_blist_node_get_string((PurpleBlistNode *)buddy, "buddy_icon")); purple_blist_node_remove_setting((PurpleBlistNode *)buddy, "buddy_icon"); purple_blist_node_remove_setting((PurpleBlistNode *)buddy, "icon_checksum"); buddies = g_slist_delete_link(buddies, buddies); } } }
static void _purple_events_ui_reset_setting(PurpleBlistNode *node) { node = _purple_events_ui_get_good_node(node); if ( node == NULL ) return; purple_blist_node_remove_setting(node, "events"); }
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; }
void purple_buddy_icon_update(PurpleBuddyIcon *icon) { PurpleConversation *conv; PurpleAccount *account; const char *username; PurpleBuddyIcon *icon_to_set; GSList *buddies; g_return_if_fail(icon != NULL); account = purple_buddy_icon_get_account(icon); username = purple_buddy_icon_get_username(icon); /* If no data exists (icon->img == NULL), then call the functions below * with NULL to unset the icon. They will then unref the icon and it should * be destroyed. The only way it wouldn't be destroyed is if someone * else is holding a reference to it, in which case they can kill * the icon when they realize it has no data. */ icon_to_set = icon->img ? icon : NULL; /* Ensure that icon remains valid throughout */ purple_buddy_icon_ref(icon); buddies = purple_find_buddies(account, username); while (buddies != NULL) { PurpleBuddy *buddy = (PurpleBuddy *)buddies->data; char *old_icon; purple_buddy_set_icon(buddy, icon_to_set); old_icon = g_strdup(purple_blist_node_get_string((PurpleBlistNode *)buddy, "buddy_icon")); if (icon->img && purple_buddy_icons_is_caching()) { const char *filename = purple_imgstore_get_filename(icon->img); purple_blist_node_set_string((PurpleBlistNode *)buddy, "buddy_icon", filename); if (icon->checksum && *icon->checksum) { purple_blist_node_set_string((PurpleBlistNode *)buddy, "icon_checksum", icon->checksum); } else { purple_blist_node_remove_setting((PurpleBlistNode *)buddy, "icon_checksum"); } ref_filename(filename); } else if (!icon->img) { purple_blist_node_remove_setting((PurpleBlistNode *)buddy, "buddy_icon"); purple_blist_node_remove_setting((PurpleBlistNode *)buddy, "icon_checksum"); } unref_filename(old_icon); g_free(old_icon); buddies = g_slist_delete_link(buddies, buddies); } conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, username, account); if (conv != NULL) purple_conv_im_set_icon(PURPLE_CONV_IM(conv), icon_to_set); /* icon's refcount was incremented above */ purple_buddy_icon_unref(icon); }
void _purple_buddy_icons_blist_loaded_cb() { PurpleBlistNode *node = purple_blist_get_root(); const char *dirname = purple_buddy_icons_get_cache_dir(); /* Doing this once here saves having to check it inside a loop. */ if (old_icons_dir != NULL) { if (!g_file_test(dirname, G_FILE_TEST_IS_DIR)) { purple_debug_info("buddyicon", "Creating icon cache directory.\n"); if (g_mkdir(dirname, S_IRUSR | S_IWUSR | S_IXUSR) < 0) { purple_debug_error("buddyicon", "Unable to create directory %s: %s\n", dirname, g_strerror(errno)); } } } while (node != NULL) { if (PURPLE_BLIST_NODE_IS_BUDDY(node)) { const char *filename; filename = purple_blist_node_get_string(node, "buddy_icon"); if (filename != NULL) { if (old_icons_dir != NULL) { migrate_buddy_icon(node, "buddy_icon", dirname, filename); } else { char *path = g_build_filename(dirname, filename, NULL); if (!g_file_test(path, G_FILE_TEST_EXISTS)) { purple_blist_node_remove_setting(node, "buddy_icon"); purple_blist_node_remove_setting(node, "icon_checksum"); } else ref_filename(filename); g_free(path); } } } else if (PURPLE_BLIST_NODE_IS_CONTACT(node) || PURPLE_BLIST_NODE_IS_CHAT(node) || PURPLE_BLIST_NODE_IS_GROUP(node)) { const char *filename; filename = purple_blist_node_get_string(node, "custom_buddy_icon"); if (filename != NULL) { if (old_icons_dir != NULL) { migrate_buddy_icon(node, "custom_buddy_icon", dirname, filename); } else { char *path = g_build_filename(dirname, filename, NULL); if (!g_file_test(path, G_FILE_TEST_EXISTS)) { purple_blist_node_remove_setting(node, "custom_buddy_icon"); } else ref_filename(filename); g_free(path); } } } node = purple_blist_node_next(node, TRUE); } }
static void migrate_buddy_icon(PurpleBlistNode *node, const char *setting_name, const char *dirname, const char *filename) { char *path; if (filename[0] != '/') { path = g_build_filename(dirname, filename, NULL); if (g_file_test(path, G_FILE_TEST_EXISTS)) { g_free(path); return; } g_free(path); path = g_build_filename(old_icons_dir, filename, NULL); } else path = g_strdup(filename); if (g_file_test(path, G_FILE_TEST_EXISTS)) { guchar *icon_data; size_t icon_len; FILE *file; char *new_filename; if (!read_icon_file(path, &icon_data, &icon_len)) { g_free(path); delete_buddy_icon_settings(node, setting_name); return; } if (icon_data == NULL || icon_len <= 0) { /* This really applies to the icon_len check. * icon_data should never be NULL if * read_icon_file() returns TRUE. */ purple_debug_error("buddyicon", "Empty buddy icon file: %s\n", path); delete_buddy_icon_settings(node, setting_name); g_free(path); return; } g_free(path); new_filename = purple_util_get_image_filename(icon_data, icon_len); if (new_filename == NULL) { purple_debug_error("buddyicon", "New icon filename is NULL. This should never happen! " "The old filename was: %s\n", path); delete_buddy_icon_settings(node, setting_name); g_return_if_reached(); } path = g_build_filename(dirname, new_filename, NULL); if ((file = g_fopen(path, "wb")) != NULL) { if (!fwrite(icon_data, icon_len, 1, file)) { purple_debug_error("buddyicon", "Error writing %s: %s\n", path, g_strerror(errno)); } else purple_debug_info("buddyicon", "Wrote migrated cache file: %s\n", path); fclose(file); } else { purple_debug_error("buddyicon", "Unable to create file %s: %s\n", path, g_strerror(errno)); g_free(new_filename); g_free(path); delete_buddy_icon_settings(node, setting_name); return; } g_free(path); purple_blist_node_set_string(node, setting_name, new_filename); ref_filename(new_filename); g_free(new_filename); if (purple_strequal(setting_name, "buddy_icon")) { const char *hash; hash = purple_blist_node_get_string(node, "avatar_hash"); if (hash != NULL) { purple_blist_node_set_string(node, "icon_checksum", hash); purple_blist_node_remove_setting(node, "avatar_hash"); } } } else { purple_debug_error("buddyicon", "Old icon file doesn't exist: %s\n", path); delete_buddy_icon_settings(node, setting_name); g_free(path); } }