changeset 11303:10066662176a

[gaim-migrate @ 13503] For accounts, store only the basename of a buddy icon cache file. Everyone please make sure buddy icons still work for you. committer: Tailor Script <tailor@pidgin.im>
author Richard Laager <rlaager@wiktel.com>
date Thu, 18 Aug 2005 20:49:58 +0000
parents fc17554c32c5
children 74e30ef571ce
files plugins/ChangeLog.API src/account.c src/buddyicon.c src/buddyicon.h src/gtkaccount.c src/protocols/jabber/buddy.c src/protocols/msn/session.c src/protocols/oscar/oscar.c src/protocols/yahoo/yahoo.c
diffstat 9 files changed, 108 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/plugins/ChangeLog.API	Thu Aug 18 20:05:20 2005 +0000
+++ b/plugins/ChangeLog.API	Thu Aug 18 20:49:58 2005 +0000
@@ -76,6 +76,8 @@
 	           gaim_gtkconv_get_tab_at_xy()
 	* Added:   gtk_imhtml_delete to clear out part of a imhtml buffer
 	* Changed: gaim_log_new(), added conv parameter
+	* Added:   gaim_buddy_icons_get_full_path(), to get the full path
+	           of a buddy icon setting
 
 	Signals:
 	* Changed: "received-im-msg" and "received-chat-msg" to match, both
--- a/src/account.c	Thu Aug 18 20:05:20 2005 +0000
+++ b/src/account.c	Thu Aug 18 20:49:58 2005 +0000
@@ -1210,6 +1210,31 @@
 {
 	g_return_if_fail(account != NULL);
 
+	/* Delete an existing icon from the cache. */
+	if (account->buddy_icon != NULL && (icon == NULL || strcmp(account->buddy_icon, icon)))
+	{
+		const char *dirname = gaim_buddy_icons_get_cache_dir();
+		struct stat st;
+
+		if (g_stat(account->buddy_icon, &st) == 0)
+		{
+			/* The file exists. This is a full path. */
+
+			/* XXX: This is a hack so we only delete the file if it's
+			 * in the cache dir. Otherwise, people who upgrade (who
+			 * may have buddy icon filenames set outside of the cache
+			 * dir) could lose files. */
+			if (!strncmp(dirname, account->buddy_icon, strlen(dirname)))
+				g_unlink(account->buddy_icon);
+		}
+		else
+		{
+			char *filename = g_build_filename(dirname, account->buddy_icon, NULL);
+			g_unlink(filename);
+			g_free(filename);
+		}
+	}
+
 	g_free(account->buddy_icon);
 	account->buddy_icon = (icon == NULL ? NULL : g_strdup(icon));
 	if (gaim_account_is_connected(account))
@@ -1940,6 +1965,9 @@
 	/* Remove this account's pounces */
 	gaim_pounce_destroy_all_by_account(account);
 
+	/* This will cause the deletion of an old buddy icon. */
+	gaim_account_set_buddy_icon(account, NULL);
+
 	gaim_account_destroy(account);
 }
 
--- a/src/buddyicon.c	Thu Aug 18 20:05:20 2005 +0000
+++ b/src/buddyicon.c	Thu Aug 18 20:49:58 2005 +0000
@@ -494,6 +494,18 @@
 	return cache_dir;
 }
 
+char *gaim_buddy_icons_get_full_path(const char *icon) {
+	struct stat st;
+
+	if (icon == NULL)
+		return NULL;
+
+	if (g_stat(icon, &st) == 0)
+		return g_strdup(icon);
+	else
+		return g_build_filename(gaim_buddy_icons_get_cache_dir(), icon, NULL);
+}
+
 void *
 gaim_buddy_icons_get_handle()
 {
--- a/src/buddyicon.h	Thu Aug 18 20:05:20 2005 +0000
+++ b/src/buddyicon.h	Thu Aug 18 20:49:58 2005 +0000
@@ -239,6 +239,18 @@
 const char *gaim_buddy_icons_get_cache_dir(void);
 
 /**
+ * Takes a buddy icon and returns a full path.
+ *
+ * If @a icon is a full path to an existing file, a copy of
+ * @a icon is returned. Otherwise, a newly allocated string
+ * consiting of gaim_buddy_icons_get_cache_dir() + @a icon is
+ * returned.
+ *
+ * @return The full path for an icon.
+ */
+char *gaim_buddy_icons_get_full_path(const char *icon);
+
+/**
  * Returns the buddy icon subsystem handle.
  *
  * @return The subsystem handle.
--- a/src/gtkaccount.c	Thu Aug 18 20:05:20 2005 +0000
+++ b/src/gtkaccount.c	Thu Aug 18 20:49:58 2005 +0000
@@ -196,20 +196,11 @@
 }
 
 static void
-delete_buddy_icon(const char *filename)
+set_dialog_icon(AccountPrefsDialog *dialog)
 {
-	const char *dirname;
-
-	if (filename == NULL)
-		return;
-
-	/* XXX: This is a hack so we only delete the file if it's
-	 * in the cache dir. Otherwise, people who upgrade (who
-	 * may have buddy icon filenames set outside of the cache
-	 * dir) could lose files. */
-	dirname = gaim_buddy_icons_get_cache_dir();
-	if (!strncmp(dirname, filename, strlen(dirname)))
-		g_unlink(filename);
+	char *filename = gaim_buddy_icons_get_full_path(dialog>icon_path);
+	gtk_image_set_from_file(GTK_IMAGE(dialog->icon_entry), filename);
+	g_free(filename);
 }
 
 static void
@@ -308,7 +299,7 @@
 	if (dialog->icon_path)
 		g_free(dialog->icon_path);
 	dialog->icon_path = convert_buddy_icon(dialog->plugin, filename);
-	gtk_image_set_from_file(GTK_IMAGE(dialog->icon_entry), dialog->icon_path);
+	set_dialog_icon(dialog);
 	gtk_widget_show(dialog->icon_entry);
 
 	gtk_widget_destroy(dialog->icon_filesel);
@@ -503,7 +494,7 @@
 			if (dialog->icon_path)
 				g_free(dialog->icon_path);
 			dialog->icon_path = convert_buddy_icon(dialog->plugin, tmp);
-			gtk_image_set_from_file(GTK_IMAGE(dialog->icon_entry), dialog->icon_path);
+			set_dialog_icon(dialog);
 			gtk_widget_show(dialog->icon_entry);
 			g_free(tmp);
 		}
@@ -549,7 +540,6 @@
 	const char *dirname = gaim_buddy_icons_get_cache_dir();
 	char *random   = g_strdup_printf("%x", g_random_int());
 	char *filename = g_build_filename(dirname, random, NULL);
-	g_free(random);
 
 	if (!g_file_test(dirname, G_FILE_TEST_IS_DIR)) {
 		gaim_debug_info("buddyicon", "Creating icon cache directory.\n");
@@ -561,6 +551,7 @@
 #if GTK_CHECK_VERSION(2,2,0)
 			g_strfreev(prpl_formats);
 #endif
+			g_free(random);
 			g_free(filename);
 			return NULL;
 		}
@@ -609,6 +600,7 @@
 		if (!g_file_get_contents(path, &contents, &length, NULL) ||
 		    (image = g_fopen(filename, "wb")) == NULL)
 		{
+			g_free(random);
 			g_free(filename);
 #if GTK_CHECK_VERSION(2,2,0) && !GTK_CHECK_VERSION(2,4,0)
 			g_object_unref(G_OBJECT(pixbuf));
@@ -621,6 +613,7 @@
 			fclose(image);
 			g_unlink(filename);
 
+			g_free(random);
 			g_free(filename);
 #if GTK_CHECK_VERSION(2,2,0) && !GTK_CHECK_VERSION(2,4,0)
 			g_object_unref(G_OBJECT(pixbuf));
@@ -633,7 +626,8 @@
 			g_object_unref(G_OBJECT(pixbuf));
 #endif
 
-		return filename;
+		g_free(filename);
+		return random;
 	}
 #if GTK_CHECK_VERSION(2,2,0)
 	else
@@ -675,6 +669,7 @@
 			pixbuf = scale;
 		}
 		if (error) {
+			g_free(random);
 			g_free(filename);
 			gaim_debug_error("buddyicon", "Could not open icon for conversion: %s\n", error->message);
 			g_error_free(error);
@@ -695,11 +690,13 @@
 		g_strfreev(prpl_formats);
 		if (!error) {
 			g_object_unref(G_OBJECT(pixbuf));
-			return filename;
+			g_free(filename);
+			return random;
 		} else {
 			gaim_debug_error("buddyicon", "Could not convert icon to usable format: %s\n", error->message);
 			g_error_free(error);
 		}
+		g_free(random);
 		g_free(filename);
 		g_object_unref(G_OBJECT(pixbuf));
 	}
@@ -938,7 +935,7 @@
 
 		if (gaim_account_get_buddy_icon(dialog->account) != NULL) {
 			dialog->icon_path = g_strdup(gaim_account_get_buddy_icon(dialog->account));
-			gtk_image_set_from_file(GTK_IMAGE(dialog->icon_entry),dialog->icon_path);
+			set_dialog_icon(dialog);
 		}
 	}
 
@@ -1384,7 +1381,19 @@
 		g_free(dialog->protocol_id);
 
 	if (dialog->icon_path != NULL)
+	{
+		const char *icon = gaim_account_get_buddy_icon(dialog->account);
+		if (dialog->icon_path != NULL && (icon == NULL || strcmp(dialog->icon_path, icon)))
+		{
+			/* The user set an icon, which would've been cached by convert_buddy_icon,
+			 * but didn't save the changes. Delete the cache file. */
+			char *filename = g_build_filename(gaim_buddy_icons_get_cache_dir(), dialog->icon_path, NULL);
+			g_unlink(filename);
+			g_free(filename);
+		}
+
 		g_free(dialog->icon_path);
+	}
 
 	if (dialog->icon_filesel)
 		gtk_widget_destroy(dialog->icon_filesel);
@@ -1436,11 +1445,7 @@
 		gaim_account_set_alias(dialog->account, NULL);
 
 	/* Buddy Icon */
-	value = gaim_account_get_buddy_icon(dialog->account);
-	if (value == NULL || dialog->icon_path == NULL || strcmp(value, dialog->icon_path)) {
-		delete_buddy_icon(value);
-		gaim_account_set_buddy_icon(dialog->account, dialog->icon_path);
-	}
+	gaim_account_set_buddy_icon(dialog->account, dialog->icon_path);
 
 	/* Remember Password */
 	gaim_account_set_remember_password(dialog->account,
--- a/src/protocols/jabber/buddy.c	Thu Aug 18 20:05:20 2005 +0000
+++ b/src/protocols/jabber/buddy.c	Thu Aug 18 20:49:58 2005 +0000
@@ -360,7 +360,7 @@
 	JabberIq *iq;
 	JabberStream *js = gc->proto_data;
 	xmlnode *vc_node;
-	const char *avatar_file = NULL;
+	char *avatar_file = NULL;
 
 	if(js->avatar_hash)
 		g_free(js->avatar_hash);
@@ -370,7 +370,7 @@
 	 * Send only if there's actually any *information* to send
 	 */
 	vc_node = xmlnode_from_str(info, -1);
-	avatar_file = gaim_account_get_buddy_icon(gc->account);
+	avatar_file == gaim_buddy_icons_get_full_path(gaim_account_get_buddy_icon(gc->account));
 
 	if(!vc_node && avatar_file) {
 		vc_node = xmlnode_new("vCard");
@@ -409,6 +409,7 @@
 			} else if (error != NULL) {
 				g_error_free(error);
 			}
+			g_free(avatar_file);
 
 			iq = jabber_iq_new(js, JABBER_IQ_SET);
 			xmlnode_insert_child(iq->node, vc_node);
--- a/src/protocols/msn/session.c	Thu Aug 18 20:05:20 2005 +0000
+++ b/src/protocols/msn/session.c	Thu Aug 18 20:49:58 2005 +0000
@@ -402,6 +402,7 @@
 {
 	GaimAccount *account;
 	GaimConnection *gc;
+	char *icon;
 
 	if (session->logged_in)
 		return;
@@ -409,8 +410,9 @@
 	account = session->account;
 	gc = gaim_account_get_connection(account);
 
-	msn_user_set_buddy_icon(session->user,
-							gaim_account_get_buddy_icon(session->account));
+	icon = gaim_buddy_icons_get_full_path(gaim_account_get_buddy_icon(session->account));
+	msn_user_set_buddy_icon(session->user, icon);
+	g_free(icon);
 
 	session->logged_in = TRUE;
 
--- a/src/protocols/oscar/oscar.c	Thu Aug 18 20:05:20 2005 +0000
+++ b/src/protocols/oscar/oscar.c	Thu Aug 18 20:49:58 2005 +0000
@@ -3413,7 +3413,7 @@
 	GaimAccount *account = gaim_connection_get_account(gc);
 	GaimConvImFlags flags = 0;
 	struct buddyinfo *bi;
-	const char *iconfile;
+	char *iconfile;
 	GString *message;
 	gchar *tmp;
 	aim_mpmsg_section_t *curpart;
@@ -3449,7 +3449,8 @@
 		}
 	}
 
-	if ((iconfile = gaim_account_get_buddy_icon(account)) &&
+	iconfile = gaim_buddy_icons_get_full_path(gaim_account_get_buddy_icon(account));
+	if ((iconfile != NULL) &&
 	    (args->icbmflags & AIM_IMFLAGS_BUDDYREQ) && !bi->ico_sent && bi->ico_informed) {
 		FILE *file;
 		struct stat st;
@@ -3475,6 +3476,7 @@
 			gaim_debug_error("oscar",
 					   "Can't stat buddy icon file!\n");
 	}
+	g_free(iconfile);
 
 	message = g_string_new("");
 	curpart = args->mpmsg.parts;
@@ -4820,7 +4822,7 @@
 
 	if (od->set_icon) {
 		struct stat st;
-		const char *iconfile = gaim_account_get_buddy_icon(gaim_connection_get_account(gc));
+		char *iconfile = gaim_buddy_icons_get_full_path(gaim_account_get_buddy_icon(gaim_connection_get_account(gc)));
 		if (iconfile == NULL) {
 			aim_ssi_delicon(od->sess);
 		} else if (!g_stat(iconfile, &st)) {
@@ -4841,6 +4843,7 @@
 			gaim_debug_error("oscar",
 				   "Can't stat buddy icon file!\n");
 		}
+		g_free(iconfile);
 		od->set_icon = FALSE;
 	}
 
@@ -5625,7 +5628,7 @@
 	GaimAccount *account = gaim_connection_get_account(gc);
 	struct oscar_direct_im *dim = oscar_direct_im_find(od, name);
 	int ret = 0;
-	const char *iconfile = gaim_account_get_buddy_icon(account);
+	char *iconfile = gaim_buddy_icons_get_full_path(gaim_account_get_buddy_icon(account));
 	char *tmpmsg = NULL;
 
 	if (dim && dim->connected) {
@@ -5715,6 +5718,7 @@
 				g_free(buf);
 			}
 		}
+		g_free(iconfile);
 
 		args.destsn = name;
 
@@ -6943,7 +6947,7 @@
 					aim_reqservice(od->sess, od->conn, AIM_CONN_TYPE_ICON);
 				} else {
 					struct stat st;
-					const char *iconfile = gaim_account_get_buddy_icon(gaim_connection_get_account(gc));
+					char *iconfile = gaim_buddy_icons_get_full_path(gaim_account_get_buddy_icon(gaim_connection_get_account(gc)));
 					if (iconfile == NULL) {
 						aim_ssi_delicon(od->sess);
 					} else if (!g_stat(iconfile, &st)) {
@@ -6964,13 +6968,16 @@
 						gaim_debug_error("oscar",
 										 "Can't stat buddy icon file!\n");
 					}
+					g_free(iconfile);
 				}
 			} else if (flags == 0x81) {
-				const char *iconfile = gaim_account_get_buddy_icon(gaim_connection_get_account(gc));
+				char *iconfile = gaim_buddy_icons_get_full_path(gaim_account_get_buddy_icon(gaim_connection_get_account(gc)));
 				if (iconfile == NULL)
 					aim_ssi_delicon(od->sess);
-				else
+				else {
 					aim_ssi_seticon(od->sess, md5, length);
+					g_free(iconfile);
+				}
 			}
 		} break;
 
--- a/src/protocols/yahoo/yahoo.c	Thu Aug 18 20:05:20 2005 +0000
+++ b/src/protocols/yahoo/yahoo.c	Thu Aug 18 20:49:58 2005 +0000
@@ -2410,10 +2410,11 @@
 static void yahoo_picture_check(GaimAccount *account)
 {
 	GaimConnection *gc = gaim_account_get_connection(account);
-	const char *buddyicon;
-
-	buddyicon = gaim_account_get_buddy_icon(account);
+	char *buddyicon;
+
+	buddyicon = gaim_buddy_icons_get_full_path(gaim_account_get_buddy_icon(account));
 	yahoo_set_buddy_icon(gc, buddyicon);
+	g_free(buddyicon);
 }