changeset 10423:3232e1a33899

[gaim-migrate @ 11675] Set version numbers for all our xml files Use xmlnode for writing accounts.xml Add 2 conveniencey helper functions to xmlnode committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Sun, 26 Dec 2004 18:38:22 +0000
parents e0cf2f3f9929
children 108151be77a3
files src/account.c src/blist.c src/idle.c src/pounce.c src/prefs.c src/savedstatuses.c src/xmlnode.c src/xmlnode.h
diffstat 8 files changed, 245 insertions(+), 174 deletions(-) [+]
line wrap: on
line diff
--- a/src/account.c	Sun Dec 26 05:56:18 2004 +0000
+++ b/src/account.c	Sun Dec 26 18:38:22 2004 +0000
@@ -34,6 +34,7 @@
 #include "signals.h"
 #include "status.h"
 #include "util.h"
+#include "xmlnode.h"
 
 typedef enum
 {
@@ -1353,197 +1354,196 @@
 }
 
 static void
-write_setting(gpointer key, gpointer value, gpointer user_data)
+setting_to_xmlnode(gpointer key, gpointer value, gpointer user_data)
 {
-	GaimAccountSetting *setting;
 	const char *name;
-	FILE *fp;
+	GaimAccountSetting *setting;
+	xmlnode *node, *child;
+	char buf[20];
 
+	name    = (const char *)key;
 	setting = (GaimAccountSetting *)value;
-	name    = (const char *)key;
-	fp      = (FILE *)user_data;
+	node    = (xmlnode *)user_data;
+
+	child = xmlnode_new("setting");
+	xmlnode_set_attrib(child, "name", name);
 
 	if (setting->type == GAIM_PREF_INT) {
-		fprintf(fp, "   <setting name='%s' type='int'>%d</setting>\n",
-				name, setting->value.integer);
+		xmlnode_set_attrib(child, "type", "int");
+		snprintf(buf, sizeof(buf), "%d", setting->value.integer);
+		xmlnode_insert_data(child, buf, -1);
 	}
 	else if (setting->type == GAIM_PREF_STRING && setting->value.string != NULL) {
-		fprintf(fp, "   <setting name='%s' type='string'>%s</setting>\n",
-				name, setting->value.string);
+		xmlnode_set_attrib(child, "type", "string");
+		xmlnode_insert_data(child, setting->value.string, -1);
 	}
 	else if (setting->type == GAIM_PREF_BOOLEAN) {
-		fprintf(fp, "   <setting name='%s' type='bool'>%d</setting>\n",
-				name, setting->value.bool);
+		xmlnode_set_attrib(child, "type", "bool");
+		snprintf(buf, sizeof(buf), "%d", setting->value.bool);
+		xmlnode_insert_data(child, buf, -1);
 	}
-}
 
-static void
-write_ui_setting_list(gpointer key, gpointer value, gpointer user_data)
-{
-	GHashTable *table;
-	const char *ui;
-	FILE *fp;
-
-	table = (GHashTable *)value;
-	ui    = (const char *)key;
-	fp    = (FILE *)user_data;
-
-	fprintf(fp, "  <settings ui='%s'>\n", ui);
-	g_hash_table_foreach(table, write_setting, fp);
-	fprintf(fp, "  </settings>\n");
+	xmlnode_insert_child(node, child);
 }
 
 static void
-gaim_accounts_write(FILE *fp, GaimAccount *account)
+ui_setting_to_xmlnode(gpointer key, gpointer value, gpointer user_data)
 {
-	GaimProxyInfo *proxy_info;
+	const char *ui;
+	GHashTable *table;
+	xmlnode *node, *child;
+
+	ui    = (const char *)key;
+	table = (GHashTable *)value;
+	node  = (xmlnode *)user_data;
+
+	child = xmlnode_new("settings");
+	xmlnode_set_attrib(child, "ui", ui);
+	g_hash_table_foreach(table, setting_to_xmlnode, child);
+
+	xmlnode_insert_child(node, child);
+}
+
+static xmlnode *
+proxy_settings_to_xmlnode(GaimProxyInfo *proxy_info)
+{
+	xmlnode *node, *child;
 	GaimProxyType proxy_type;
-	const char *password, *alias, *user_info, *buddy_icon;
-	char *esc;
+	const char *value;
+	int int_value;
+	char buf[20];
+
+	proxy_type = gaim_proxy_info_get_type(proxy_info);
 
-	fprintf(fp, " <account>\n");
-	fprintf(fp, "  <protocol>%s</protocol>\n", account->protocol_id);
-	esc = g_markup_escape_text(gaim_account_get_username(account), -1);
-	fprintf(fp, "  <name>%s</name>\n", esc);
-	g_free(esc);
+	node = xmlnode_new("proxy");
+
+	child = xmlnode_new_child_with_data(node, "type",
+			(proxy_type == GAIM_PROXY_USE_GLOBAL ? "global" :
+			 proxy_type == GAIM_PROXY_NONE       ? "none"   :
+			 proxy_type == GAIM_PROXY_HTTP       ? "http"   :
+			 proxy_type == GAIM_PROXY_SOCKS4     ? "socks4" :
+			 proxy_type == GAIM_PROXY_SOCKS5     ? "socks5" :
+			 proxy_type == GAIM_PROXY_USE_ENVVAR ? "envvar" : "unknown"), -1);
 
-	if (gaim_account_get_remember_password(account) &&
-		(password = gaim_account_get_password(account)) != NULL) {
-		esc = g_markup_escape_text(password, -1);
-		fprintf(fp, "  <password>%s</password>\n", esc);
-		g_free(esc);
+	if (proxy_type != GAIM_PROXY_USE_GLOBAL &&
+		proxy_type != GAIM_PROXY_NONE &&
+		proxy_type != GAIM_PROXY_USE_ENVVAR)
+	{
+		if ((value = gaim_proxy_info_get_host(proxy_info)) != NULL)
+			child = xmlnode_new_child_with_data(node, "host", value, -1);
+
+		if ((int_value = gaim_proxy_info_get_port(proxy_info)) != 0)
+		{
+			snprintf(buf, sizeof(buf), "%d", int_value);
+			child = xmlnode_new_child_with_data(node, "port", buf, -1);
+		}
+
+		if ((value = gaim_proxy_info_get_username(proxy_info)) != NULL)
+			child = xmlnode_new_child_with_data(node, "username", value, -1);
+
+		if ((value = gaim_proxy_info_get_password(proxy_info)) != NULL)
+			child = xmlnode_new_child_with_data(node, "password", value, -1);
 	}
 
-	if ((alias = gaim_account_get_alias(account)) != NULL) {
-		esc = g_markup_escape_text(alias, -1);
-		fprintf(fp, "  <alias>%s</alias>\n", esc);
-		g_free(esc);
+	return node;
+}
+
+static xmlnode *
+account_to_xmlnode(GaimAccount *account)
+{
+	xmlnode *node, *child;
+	const char *tmp;
+	GaimProxyInfo *proxy_info;
+
+	node = xmlnode_new("account");
+
+	child = xmlnode_new("protocol");
+	xmlnode_insert_data(child, gaim_account_get_protocol_id(account), -1);
+	xmlnode_insert_child(node, child);
+
+	child = xmlnode_new("name");
+	xmlnode_insert_data(child, gaim_account_get_username(account), -1);
+	xmlnode_insert_child(node, child);
+
+	if (gaim_account_get_remember_password(account) &&
+		((tmp = gaim_account_get_password(account)) != NULL))
+	{
+		child = xmlnode_new("password");
+		xmlnode_insert_data(child, tmp, -1);
+		xmlnode_insert_child(node, child);
 	}
 
-	if ((user_info = gaim_account_get_user_info(account)) != NULL) {
-		esc = g_markup_escape_text(user_info, -1);
-                gaim_str_strip_cr(esc);
-		fprintf(fp, "  <userinfo>%s</userinfo>\n", esc);
-		g_free(esc);
+	if ((tmp = gaim_account_get_alias(account)) != NULL)
+	{
+		child = xmlnode_new("alias");
+		xmlnode_insert_data(child, tmp, -1);
+		xmlnode_insert_child(node, child);
 	}
 
-	if ((buddy_icon = gaim_account_get_buddy_icon(account)) != NULL) {
-		esc = g_markup_escape_text(buddy_icon, -1);
-		fprintf(fp, "  <buddyicon>%s</buddyicon>\n", esc);
-		g_free(esc);
+	if ((tmp = gaim_account_get_user_info(account)) != NULL)
+	{
+		/* TODO: Do we need to call gaim_str_strip_cr(tmp) here? */
+		child = xmlnode_new("userinfo");
+		xmlnode_insert_data(child, tmp, -1);
+		xmlnode_insert_child(node, child);
 	}
 
-	fprintf(fp, "  <settings>\n");
-	g_hash_table_foreach(account->settings, write_setting, fp);
-	fprintf(fp, "  </settings>\n");
+	if ((tmp = gaim_account_get_buddy_icon(account)) != NULL)
+	{
+		child = xmlnode_new("buddyicon");
+		xmlnode_insert_data(child, tmp, -1);
+		xmlnode_insert_child(node, child);
+	}
 
-	g_hash_table_foreach(account->ui_settings, write_ui_setting_list, fp);
+	child = xmlnode_new("settings");
+	g_hash_table_foreach(account->settings, setting_to_xmlnode, child);
+	xmlnode_insert_child(node, child);
+
+	g_hash_table_foreach(account->ui_settings, ui_setting_to_xmlnode, node);
 
 	if ((proxy_info = gaim_account_get_proxy_info(account)) != NULL)
 	{
-		const char *value;
-		int int_value;
-
-		proxy_type = gaim_proxy_info_get_type(proxy_info);
-
-		fprintf(fp, "  <proxy>\n");
-		fprintf(fp, "   <type>%s</type>\n",
-				(proxy_type == GAIM_PROXY_USE_GLOBAL ? "global" :
-				 proxy_type == GAIM_PROXY_NONE       ? "none"   :
-				 proxy_type == GAIM_PROXY_HTTP       ? "http"   :
-				 proxy_type == GAIM_PROXY_SOCKS4     ? "socks4" :
-				 proxy_type == GAIM_PROXY_SOCKS5     ? "socks5" :
-				 proxy_type == GAIM_PROXY_USE_ENVVAR ? "envvar" : "unknown"));
-
-		if (proxy_type != GAIM_PROXY_USE_GLOBAL &&
-			proxy_type != GAIM_PROXY_NONE &&
-			proxy_type != GAIM_PROXY_USE_ENVVAR) {
-			if ((value = gaim_proxy_info_get_host(proxy_info)) != NULL)
-				fprintf(fp, "   <host>%s</host>\n", value);
-
-			if ((int_value = gaim_proxy_info_get_port(proxy_info)) != 0)
-				fprintf(fp, "   <port>%d</port>\n", int_value);
-
-			if ((value = gaim_proxy_info_get_username(proxy_info)) != NULL)
-				fprintf(fp, "   <username>%s</username>\n", value);
-
-			if ((value = gaim_proxy_info_get_password(proxy_info)) != NULL)
-				fprintf(fp, "   <password>%s</password>\n", value);
-		}
-
-		fprintf(fp, "  </proxy>\n");
+		child = proxy_settings_to_xmlnode(proxy_info);
+		xmlnode_insert_child(node, child);
 	}
 
-	fprintf(fp, " </account>\n");
+	return node;
+}
+
+static xmlnode *
+accounts_to_xmlnode(void)
+{
+	xmlnode *node, *child;
+	GList *cur;
+
+	node = xmlnode_new("accounts");
+	xmlnode_set_attrib(node, "version", "1.0");
+
+	for (cur = gaim_accounts_get_all(); cur != NULL; cur = cur->next)
+	{
+		child = account_to_xmlnode(cur->data);
+		xmlnode_insert_child(node, child);
+	}
+
+	return node;
 }
 
 void
 gaim_accounts_sync(void)
 {
-	FILE *fp;
-	struct stat st;
-	const char *user_dir = gaim_user_dir();
-	char *filename;
-	char *filename_real;
+	xmlnode *node;
+	char *data;
 
 	if (!accounts_loaded) {
-		gaim_debug_error("accounts",
-				   "Writing accounts to disk.\n");
-		schedule_accounts_save();
-		return;
+		gaim_debug_error("accounts", "Attempted to save accounts before they "
+						 "were read!\n");
 	}
 
-	if (user_dir == NULL)
-		return;
-
-	gaim_debug_info("accounts", "Writing accounts to disk.\n");
-
-	fp = fopen(user_dir, "r");
-
-	if (fp == NULL)
-		mkdir(user_dir, S_IRUSR | S_IWUSR | S_IXUSR);
-	else
-		fclose(fp);
-
-	filename = g_build_filename(user_dir, "accounts.xml.save", NULL);
-
-	if ((fp = fopen(filename, "w")) != NULL) {
-		GList *l;
-
-		fprintf(fp, "<?xml version='1.0' encoding='UTF-8' ?>\n\n");
-		fprintf(fp, "<accounts>\n");
-
-		for (l = gaim_accounts_get_all(); l != NULL; l = l->next)
-			gaim_accounts_write(fp, l->data);
-
-		fprintf(fp, "</accounts>\n");
-
-		fclose(fp);
-		chmod(filename, S_IRUSR | S_IWUSR);
-	}
-	else {
-		gaim_debug_error("accounts", "Unable to write %s\n",
-				   filename);
-		g_free(filename);
-		return;
-	}
-
-	if (stat(filename, &st) || (st.st_size == 0)) {
-		gaim_debug_error("accounts", "Failed to save accounts\n");
-		unlink(filename);
-		g_free(filename);
-		return;
-	}
-
-	filename_real = g_build_filename(user_dir, "accounts.xml", NULL);
-
-	if (rename(filename, filename_real) < 0) {
-		gaim_debug_error("accounts", "Error renaming %s to %s\n",
-				   filename, filename_real);
-	}
-
-	g_free(filename);
-	g_free(filename_real);
+	node = accounts_to_xmlnode();
+	data = xmlnode_to_formatted_str(node, NULL);
+	gaim_util_write_data_to_file("accounts.xml", data, -1);
+	g_free(data);
+	xmlnode_free(node);
 }
 
 void
--- a/src/blist.c	Sun Dec 26 05:56:18 2004 +0000
+++ b/src/blist.c	Sun Dec 26 18:38:22 2004 +0000
@@ -2360,8 +2360,8 @@
 	GList *accounts;
 	GaimBlistNode *gnode;
 
-	fprintf(file, "<?xml version='1.0' encoding='UTF-8' ?>\n");
-	fprintf(file, "<gaim version=\"1\">\n");
+	fprintf(file, "<?xml version='1.0' encoding='UTF-8' ?>\n\n");
+	fprintf(file, "<gaim version='1.0'>\n");
 	fprintf(file, "\t<blist>\n");
 
 	for (gnode = gaimbuddylist->root; gnode; gnode = gnode->next) {
--- a/src/idle.c	Sun Dec 26 05:56:18 2004 +0000
+++ b/src/idle.c	Sun Dec 26 18:38:22 2004 +0000
@@ -198,5 +198,4 @@
 	}
 
 	return TRUE;
-
 }
--- a/src/pounce.c	Sun Dec 26 05:56:18 2004 +0000
+++ b/src/pounce.c	Sun Dec 26 18:38:22 2004 +0000
@@ -875,7 +875,7 @@
 		GList *l;
 
 		fprintf(fp, "<?xml version='1.0' encoding='UTF-8' ?>\n\n");
-		fprintf(fp, "<pounces>\n");
+		fprintf(fp, "<pounces version='1.0'>\n");
 
 		for (l = gaim_pounces_get_all(); l != NULL; l = l->next)
 			gaim_pounces_write(fp, l->data);
--- a/src/prefs.c	Sun Dec 26 05:56:18 2004 +0000
+++ b/src/prefs.c	Sun Dec 26 18:38:22 2004 +0000
@@ -740,8 +740,8 @@
 	if(!pref) {
 		pref = &prefs;
 
-		fprintf(f, "<?xml version='1.0' encoding='UTF-8' ?>\n");
-		fprintf(f, "<pref name='/'");
+		fprintf(f, "<?xml version='1.0' encoding='UTF-8' ?>\n\n");
+		fprintf(f, "<pref version='1.0' name='/'");
 	} else {
 		for(i=0; i<depth; i++)
 			fprintf(f, "\t");
--- a/src/savedstatuses.c	Sun Dec 26 05:56:18 2004 +0000
+++ b/src/savedstatuses.c	Sun Dec 26 18:38:22 2004 +0000
@@ -64,9 +64,9 @@
 	char *message;
 };
 
-static GList *saved_statuses = NULL;
-gboolean have_read_saved_statuses = FALSE;
-static guint statuses_save_timer = 0;
+static GList   *saved_statuses = NULL;
+static guint    statuses_save_timer = 0;
+static gboolean statuses_loaded = FALSE;
 
 /**************************************************************************
 * Helper functions
@@ -165,7 +165,7 @@
 	GList *cur;
 
 	node = xmlnode_new("statuses");
-	xmlnode_set_attrib(node, "version", "1");
+	xmlnode_set_attrib(node, "version", "1.0");
 
 	for (cur = saved_statuses; cur != NULL; cur = cur->next)
 	{
@@ -179,20 +179,20 @@
 static void
 sync_statuses(void)
 {
-	xmlnode *statuses;
+	xmlnode *node;
 	char *data;
 
-	if (!have_read_saved_statuses) {
+	if (!statuses_loaded) {
 		gaim_debug_error("status", "Attempted to save statuses before they "
 						 "were read!\n");
 		return;
 	}
 
-	statuses = statuses_to_xmlnode();
-	data = xmlnode_to_formatted_str(statuses, NULL);
+	node = statuses_to_xmlnode();
+	data = xmlnode_to_formatted_str(node, NULL);
 	gaim_util_write_data_to_file("status.xml", data, -1);
 	g_free(data);
-	xmlnode_free(statuses);
+	xmlnode_free(node);
 }
 
 static gboolean
@@ -416,7 +416,7 @@
 
 	g_return_if_fail(user_dir != NULL);
 
-	have_read_saved_statuses = TRUE;
+	statuses_loaded = TRUE;
 
 	filename = g_build_filename(user_dir, "status.xml", NULL);
 
--- a/src/xmlnode.c	Sun Dec 26 05:56:18 2004 +0000
+++ b/src/xmlnode.c	Sun Dec 26 18:38:22 2004 +0000
@@ -38,6 +38,7 @@
 new_node(const char *name, XMLNodeType type)
 {
 	xmlnode *node = g_new0(xmlnode, 1);
+
 	if(name)
 		node->name = g_strdup(name);
 	node->type = type;
@@ -53,7 +54,23 @@
 	return new_node(name, XMLNODE_TYPE_TAG);
 }
 
-xmlnode *xmlnode_new_child(xmlnode *parent, const char *name)
+xmlnode*
+xmlnode_new_with_data(const char *name, const char *data, size_t size)
+{
+	xmlnode *node;
+
+	g_return_val_if_fail(name != NULL, NULL);
+	g_return_val_if_fail(data != NULL, NULL);
+	g_return_val_if_fail(size != 0, NULL);
+
+	node = new_node(name, XMLNODE_TYPE_TAG);
+	xmlnode_insert_data(node, data, size);
+
+	return node;
+}
+
+xmlnode *
+xmlnode_new_child(xmlnode *parent, const char *name)
 {
 	xmlnode *node;
 
@@ -67,6 +84,25 @@
 	return node;
 }
 
+xmlnode *
+xmlnode_new_child_with_data(xmlnode *parent, const char *name,
+							const char *data, size_t size)
+{
+	xmlnode *node;
+
+	g_return_val_if_fail(parent != NULL, NULL);
+	g_return_val_if_fail(name != NULL, NULL);
+	g_return_val_if_fail(data != NULL, NULL);
+	g_return_val_if_fail(size != 0, NULL);
+
+	node = new_node(name, XMLNODE_TYPE_TAG);
+	xmlnode_insert_data(node, data, size);
+
+	xmlnode_insert_child(parent, node);
+
+	return node;
+}
+
 void
 xmlnode_insert_child(xmlnode *parent, xmlnode *child)
 {
@@ -162,7 +198,8 @@
 	return NULL;
 }
 
-void xmlnode_free(xmlnode *node)
+void
+xmlnode_free(xmlnode *node)
 {
 	xmlnode *x, *y;
 
@@ -243,7 +280,8 @@
 	return g_string_free(str, FALSE);
 }
 
-static gchar *xmlnode_to_str_helper(xmlnode *node, int *len, gboolean formatting, int depth)
+static gchar *
+xmlnode_to_str_helper(xmlnode *node, int *len, gboolean formatting, int depth)
 {
 	GString *text = g_string_new("");
 	xmlnode *c;
@@ -313,11 +351,15 @@
 	return g_string_free(text, FALSE);
 }
 
-gchar *xmlnode_to_str(xmlnode *node, int *len) {
+gchar *
+xmlnode_to_str(xmlnode *node, int *len)
+{
 	return xmlnode_to_str_helper(node, len, FALSE, 0);
 }
 
-gchar *xmlnode_to_formatted_str(xmlnode *node, int *len) {
+gchar *
+xmlnode_to_formatted_str(xmlnode *node, int *len)
+{
 	gchar *xml, *xml_with_declaration;
 
 	xml = xmlnode_to_str_helper(node, len, TRUE, 0);
@@ -395,7 +437,8 @@
 };
 
 
-xmlnode *xmlnode_from_str(const char *str, size_t size)
+xmlnode *
+xmlnode_from_str(const char *str, size_t size)
 {
 	struct _xmlnode_parser_data *xpd = g_new0(struct _xmlnode_parser_data, 1);
 	xmlnode *ret;
@@ -418,7 +461,8 @@
 	return ret;
 }
 
-xmlnode *xmlnode_copy(xmlnode *src)
+xmlnode *
+xmlnode_copy(xmlnode *src)
 {
 	xmlnode *ret;
 	xmlnode *child;
@@ -451,7 +495,9 @@
 	return ret;
 }
 
-xmlnode *xmlnode_get_next_twin(xmlnode *node) {
+xmlnode *
+xmlnode_get_next_twin(xmlnode *node)
+{
 	xmlnode *sibling;
 	const char *ns = xmlnode_get_attrib(node, "xmlns");
 
@@ -470,4 +516,3 @@
 
 	return NULL;
 }
-
--- a/src/xmlnode.h	Sun Dec 26 05:56:18 2004 +0000
+++ b/src/xmlnode.h	Sun Dec 26 18:38:22 2004 +0000
@@ -59,6 +59,19 @@
 xmlnode *xmlnode_new(const char *name);
 
 /**
+ * Creates a new xmlnode and inserts data into it.
+ *
+ * @param name The name of the node.
+ * @param data The data to insert.
+ * @param size The size of the data to insert.  If data is
+ *             null-terminated you can pass in -1.
+ *
+ * @return The new node.
+ */
+xmlnode *xmlnode_new_with_data(const char *name,
+							   const char *data, size_t size);
+
+/**
  * Creates a new xmlnode child.
  *
  * @param parent The parent node.
@@ -69,6 +82,20 @@
 xmlnode *xmlnode_new_child(xmlnode *parent, const char *name);
 
 /**
+ * Creates a new xmlnode child and inserts data into it.
+ *
+ * @param parent The parent node.
+ * @param name   The name of the child node.
+ * @param data   The data to insert.
+ * @param size   The size of the data to insert.  If data is
+ *               null-terminated you can pass in -1.
+ *
+ * @return The new child node.
+ */
+xmlnode *xmlnode_new_child_with_data(xmlnode *parent, const char *name,
+									 const char *data, size_t size);
+
+/**
  * Inserts a node into a node as a child.
  *
  * @param parent The parent node to insert child into.