Exemple #1
0
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);
	}
}
Exemple #3
0
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);
		}
	}
}
Exemple #4
0
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");
}
Exemple #5
0
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;
}
Exemple #6
0
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);
}
Exemple #7
0
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);
	}
}
Exemple #8
0
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);
	}
}