changeset 10414:26eac2362c32

[gaim-migrate @ 11664] I'm starting to feel better. Little change here, little change there. Mostly I added a function gaim_util_write_xml_file to be used to write our config files. committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Sat, 25 Dec 2004 18:33:27 +0000
parents 960b6a41d02f
children 5b7a74d397cc
files src/blist.c src/gtkpluginpref.c src/pluginpref.c src/pluginpref.h src/status.c src/util.c src/util.h
diffstat 7 files changed, 146 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/src/blist.c	Fri Dec 24 16:45:33 2004 +0000
+++ b/src/blist.c	Sat Dec 25 18:33:27 2004 +0000
@@ -2389,20 +2389,16 @@
 	char *filename;
 	char *filename_real;
 
-	if (!user_dir)
-		return;
+	g_return_if_fail(user_dir != NULL);
 
 	if (!blist_safe_to_write) {
-		gaim_debug(GAIM_DEBUG_WARNING, "blist save",
+		gaim_debug_warning("blist save",
 				   "AHH!! Tried to write the blist before we read it!\n");
 		return;
 	}
 
-	file = fopen(user_dir, "r");
-	if (!file)
+	if (!g_file_test(user_dir, G_FILE_TEST_IS_DIR))
 		mkdir(user_dir, S_IRUSR | S_IWUSR | S_IXUSR);
-	else
-		fclose(file);
 
 	filename = g_build_filename(user_dir, "blist.xml.save", NULL);
 
@@ -2411,8 +2407,7 @@
 		fclose(file);
 		chmod(filename, S_IRUSR | S_IWUSR);
 	} else {
-		gaim_debug(GAIM_DEBUG_ERROR, "blist save", "Unable to write %s\n",
-				   filename);
+		gaim_debug_error("blist", "Unable to write %s\n", filename);
 		g_free(filename);
 		return;
 	}
@@ -2427,7 +2422,7 @@
 	filename_real = g_build_filename(user_dir, "blist.xml", NULL);
 
 	if (rename(filename, filename_real) < 0)
-		gaim_debug(GAIM_DEBUG_ERROR, "blist save",
+		gaim_debug_error("blist",
 				   "Error renaming %s to %s\n", filename, filename_real);
 
 	g_free(filename);
--- a/src/gtkpluginpref.c	Fri Dec 24 16:45:33 2004 +0000
+++ b/src/gtkpluginpref.c	Sat Dec 25 18:33:27 2004 +0000
@@ -56,7 +56,7 @@
 		case GAIM_PLUGIN_PREF_CHOICE:
 			gtk_label = gaim_gtk_prefs_dropdown_from_list(parent, pref_label,
 											  GAIM_PREF_STRING, pref_name,
-											  gaim_plugin_pref_get_choices(pref));						
+											  gaim_plugin_pref_get_choices(pref));
 			gtk_misc_set_alignment(GTK_MISC(gtk_label), 0, 0.5);
 
 			if(sg)
@@ -116,7 +116,7 @@
 		case GAIM_PLUGIN_PREF_NONE:
 		default:
 			gaim_plugin_pref_get_bounds(pref, &min, &max);
-			gaim_gtk_prefs_labeled_spin_button(parent, pref_label, 
+			gaim_gtk_prefs_labeled_spin_button(parent, pref_label,
 					pref_name, min, max, sg);
 			break;
 	}
--- a/src/pluginpref.c	Fri Dec 24 16:45:33 2004 +0000
+++ b/src/pluginpref.c	Sat Dec 25 18:33:27 2004 +0000
@@ -209,7 +209,7 @@
 				pref->name);
 		return;
 	}
-		
+
 	if(min > max) {
 		tmp = min;
 		min = max;
--- a/src/pluginpref.h	Fri Dec 24 16:45:33 2004 +0000
+++ b/src/pluginpref.h	Sat Dec 25 18:33:27 2004 +0000
@@ -76,7 +76,7 @@
  * @return a GList of plugin preferences
  */
 GList *gaim_plugin_pref_frame_get_prefs(GaimPluginPrefFrame *frame);
- 
+
 /**
  * Create a new plugin preference
  *
--- a/src/status.c	Fri Dec 24 16:45:33 2004 +0000
+++ b/src/status.c	Sat Dec 25 18:33:27 2004 +0000
@@ -1998,8 +1998,7 @@
 	gchar *filename;
 	gchar *msg;
 
-	if (user_dir == NULL)
-		return;
+	g_return_if_fail(user_dir != NULL);
 
 	filename = g_build_filename(user_dir, "status.xml", NULL);
 
@@ -2022,5 +2021,7 @@
 void
 gaim_statuses_sync(void)
 {
-	/* TODO: Write me, baby. */
+	/* TODO: Only attempt to write if we've already read the file. */
+
+	//gaim_util_write_xml_file("status.xml", data);
 }
--- a/src/util.c	Fri Dec 24 16:45:33 2004 +0000
+++ b/src/util.c	Sat Dec 25 18:33:27 2004 +0000
@@ -1930,6 +1930,125 @@
 }
 
 /*
+ * This function is long and beautiful, like my--um, yeah.  Anyway,
+ * it includes lots of error checking so as we don't overwrite
+ * people's settings if there is a problem writing the new values.
+ */
+gboolean
+gaim_util_write_xml_file(const char *filename, const char *data)
+{
+	const char *user_dir = gaim_user_dir();
+	gchar *filename_temp, *filename_full;
+	FILE *file;
+	size_t datalen, byteswritten;
+	struct stat st;
+
+	g_return_val_if_fail(user_dir != NULL, FALSE);
+
+	gaim_debug_info("util", "Writing file %s to directory %s\n",
+					filename, user_dir);
+
+	/* Ensure the user directory exists */
+	if (!g_file_test(user_dir, G_FILE_TEST_IS_DIR))
+	{
+		if (mkdir(user_dir, S_IRUSR | S_IWUSR | S_IXUSR) == -1)
+		{
+			gaim_debug_error("util", "Error creating directory %s: %s\n",
+							 user_dir, strerror(errno));
+			return FALSE;
+		}
+	}
+
+	filename_full = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s.xml", user_dir, filename);
+	filename_temp = g_strdup_printf("%s.save", filename_full);
+
+	/* Remove an old temporary file, if one exists */
+	if (g_file_test(filename_temp, G_FILE_TEST_EXISTS))
+	{
+		if (unlink(filename_temp) == -1)
+		{
+			gaim_debug_error("util", "Error removing old file %s: %s\n",
+							 filename_temp, strerror(errno));
+		}
+	}
+
+	/* Open file */
+	file = fopen(filename_temp, "w");
+	if (file == NULL)
+	{
+		gaim_debug_error("util", "Error opening file %s for writing: %s\n",
+						 filename_temp, strerror(errno));
+		g_free(filename_full);
+		g_free(filename_temp);
+		return FALSE;
+	}
+
+	/* Write to file */
+	datalen = strlen(data);
+	byteswritten = fwrite(data, 1, datalen, file);
+
+	/* Close file */
+	if (fclose(file) != 0)
+	{
+		gaim_debug_error("util", "Error closing file %s: %s\n",
+						 filename_temp, strerror(errno));
+		g_free(filename_full);
+		g_free(filename_temp);
+		return FALSE;
+	}
+
+	/* Ensure the file is the correct size */
+	if (byteswritten != datalen)
+	{
+		gaim_debug_error("util", "Error writing to file %s: Wrote %z bytes "
+						 "but should have written %z; is your disk full?\n",
+						 filename_temp, byteswritten, datalen);
+		g_free(filename_full);
+		g_free(filename_temp);
+		return FALSE;
+	}
+	/* Use stat to be absolutely sure. */
+	if ((stat(filename_temp, &st) == -1) || (st.st_size != datalen))
+	{
+		gaim_debug_error("util", "Error writing data to file %s: "
+						 "Incomplete file written; is your disk full?\n",
+						 filename_temp);
+		g_free(filename_full);
+		g_free(filename_temp);
+		return FALSE;
+	}
+
+	/* Set file permissions */
+	if (chmod(filename_temp, S_IRUSR | S_IWUSR) == -1)
+	{
+		gaim_debug_error("util", "Error setting permissions of file %s: %s\n",
+						 filename_temp, strerror(errno));
+	}
+
+	/* Remove the old file, if it exists */
+	if (g_file_test(filename_full, G_FILE_TEST_EXISTS))
+	{
+		if (unlink(filename_full) == -1)
+		{
+			gaim_debug_error("util", "Error removing old file %s: %s\n",
+							 filename_full, strerror(errno));
+		}
+	}
+
+	/* Rename to the REAL name */
+	if (rename(filename_temp, filename_full) == -1)
+	{
+		gaim_debug_error("util", "Error renaming %s to %s: %s\n",
+						 filename_temp, filename_full, strerror(errno));
+	}
+
+	g_free(filename_full);
+	g_free(filename_temp);
+
+	return TRUE;
+}
+
+/*
  * Like mkstemp() but returns a file pointer, uses a pre-set template,
  * uses the semantics of tempnam() for the directory to use and allocates
  * the space for the filepath.
--- a/src/util.h	Fri Dec 24 16:45:33 2004 +0000
+++ b/src/util.h	Sat Dec 25 18:33:27 2004 +0000
@@ -377,6 +377,20 @@
 int gaim_build_dir(const char *path, int mode);
 
 /**
+ * Write a null-terminated string of data to a file of the given name
+ * in the Gaim user directory ($HOME/.gaim by default).  The data is
+ * typically a serialized version of one of Gaim's config files, such
+ * as prefs.xml, accounts.xml, etc.  And the string is typically
+ * obtained using xmlnode_to_formatted_str.
+ *
+ * @param filename The basename of the file to write in the gaim_user_dir.
+ * @param data     A null-terminated string of data to write.
+ *
+ * @return TRUE if the file was written successfully.  FALSE otherwise.
+ */
+gboolean gaim_util_write_xml_file(const char *filename, const char *data);
+
+/**
  * Creates a temporary file and returns a file pointer to it.
  *
  * This is like mkstemp(), but returns a file pointer and uses a