diff src/account.c @ 10425:9903182f2aac

[gaim-migrate @ 11677] Added a util function to read an xml file and parse it into an xmlnode tree Changed accounts.xml reading to use xmlnode's committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Sun, 26 Dec 2004 22:52:52 +0000
parents 108151be77a3
children 30d9ec7d001b
line wrap: on
line diff
--- a/src/account.c	Sun Dec 26 18:58:36 2004 +0000
+++ b/src/account.c	Sun Dec 26 22:52:52 2004 +0000
@@ -36,22 +36,6 @@
 #include "util.h"
 #include "xmlnode.h"
 
-typedef enum
-{
-	TAG_NONE = 0,
-	TAG_PROTOCOL,
-	TAG_NAME,
-	TAG_PASSWORD,
-	TAG_ALIAS,
-	TAG_USERINFO,
-	TAG_BUDDYICON,
-	TAG_SETTING,
-	TAG_TYPE,
-	TAG_HOST,
-	TAG_PORT
-
-} AccountParserTag;
-
 typedef struct
 {
 	GaimPrefType type;
@@ -68,24 +52,6 @@
 
 } GaimAccountSetting;
 
-typedef struct
-{
-	AccountParserTag tag;
-
-	GaimAccount *account;
-	GaimProxyInfo *proxy_info;
-	char *protocol_id;
-
-	GString *buffer;
-
-	GaimPrefType setting_type;
-	char *setting_ui;
-	char *setting_name;
-
-	gboolean in_proxy;
-
-} AccountParserData;
-
 
 static GaimAccountUiOps *account_ui_ops = NULL;
 
@@ -1052,305 +1018,252 @@
 	}
 }
 
-/* XML Stuff */
 static void
-free_parser_data(gpointer user_data)
+parse_settings(xmlnode *node, GaimAccount *account)
 {
-	AccountParserData *data = user_data;
+	const char *ui;
+	xmlnode *child;
 
-	if (data->buffer != NULL)
-		g_string_free(data->buffer, TRUE);
-
-	if (data->setting_name != NULL)
-		g_free(data->setting_name);
-
-	g_free(data);
-}
+	/* Get the UI string, if these are UI settings */
+	ui = xmlnode_get_attrib(node, "ui");
 
-static void
-start_element_handler(GMarkupParseContext *context,
-					  const gchar *element_name,
-					  const gchar **attribute_names,
-					  const gchar **attribute_values,
-					  gpointer user_data, GError **error)
-{
-	const char *value;
-	AccountParserData *data = user_data;
-	GHashTable *atts;
-	int i;
+	/* Read settings, one by one */
+	for (child = xmlnode_get_child(node, "setting"); child != NULL;
+			child = xmlnode_get_next_twin(child))
+	{
+		const char *name, *str_type;
+		GaimPrefType type;
+		char *data;
 
-	atts = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
-
-	for (i = 0; attribute_names[i] != NULL; i++) {
-		g_hash_table_insert(atts, g_strdup(attribute_names[i]),
-							g_strdup(attribute_values[i]));
-	}
-
-	if (data->buffer != NULL) {
-		g_string_free(data->buffer, TRUE);
-		data->buffer = NULL;
-	}
+		name = xmlnode_get_attrib(child, "name");
+		if (name == NULL)
+			/* Ignore this setting */
+			continue;
 
-	if (!strcmp(element_name, "protocol"))
-		data->tag = TAG_PROTOCOL;
-	else if (!strcmp(element_name, "name") || !strcmp(element_name, "username"))
-		data->tag = TAG_NAME;
-	else if (!strcmp(element_name, "password"))
-		data->tag = TAG_PASSWORD;
-	else if (!strcmp(element_name, "alias"))
-		data->tag = TAG_ALIAS;
-	else if (!strcmp(element_name, "userinfo"))
-		data->tag = TAG_USERINFO;
-	else if (!strcmp(element_name, "buddyicon"))
-		data->tag = TAG_BUDDYICON;
-	else if (!strcmp(element_name, "proxy")) {
-		data->in_proxy = TRUE;
+		str_type = xmlnode_get_attrib(child, "type");
+		if (!strcmp(str_type, "string"))
+			type = GAIM_PREF_STRING;
+		else if (!strcmp(str_type, "int"))
+			type = GAIM_PREF_INT;
+		else if (!strcmp(str_type, "bool"))
+			type = GAIM_PREF_BOOLEAN;
+		else
+			/* Ignore this setting */
+			continue;
+
+		data = xmlnode_get_data(child);
+		if (data == NULL)
+			/* Ignore this setting */
+			continue;
 
-		data->proxy_info = gaim_proxy_info_new();
+		if (ui == NULL)
+		{
+			if (type == GAIM_PREF_STRING)
+				gaim_account_set_string(account, name, data);
+			else if (type == GAIM_PREF_INT)
+				gaim_account_set_int(account, name, atoi(data));
+			else if (type == GAIM_PREF_BOOLEAN)
+				gaim_account_set_bool(account, name,
+									  (*data == '0' ? FALSE : TRUE));
+		} else {
+			if (type == GAIM_PREF_STRING)
+				gaim_account_set_ui_string(account, ui, name, data);
+			else if (type == GAIM_PREF_INT)
+				gaim_account_set_ui_int(account, ui, name, atoi(data));
+			else if (type == GAIM_PREF_BOOLEAN)
+				gaim_account_set_ui_bool(account, ui, name,
+										 (*data == '0' ? FALSE : TRUE));
+		}
+
+		g_free(data);
 	}
-	else if (!strcmp(element_name, "type"))
-		data->tag = TAG_TYPE;
-	else if (!strcmp(element_name, "host"))
-		data->tag = TAG_HOST;
-	else if (!strcmp(element_name, "port"))
-		data->tag = TAG_PORT;
-	else if (!strcmp(element_name, "settings")) {
-		if ((value = g_hash_table_lookup(atts, "ui")) != NULL) {
-			data->setting_ui = g_strdup(value);
-		}
-	}
-	else if (!strcmp(element_name, "setting")) {
-		data->tag = TAG_SETTING;
-
-		if ((value = g_hash_table_lookup(atts, "name")) != NULL)
-			data->setting_name = g_strdup(value);
-
-		if ((value = g_hash_table_lookup(atts, "type")) != NULL) {
-			if (!strcmp(value, "string"))
-				data->setting_type = GAIM_PREF_STRING;
-			else if (!strcmp(value, "int"))
-				data->setting_type = GAIM_PREF_INT;
-			else if (!strcmp(value, "bool"))
-				data->setting_type = GAIM_PREF_BOOLEAN;
-		}
-	}
-
-	g_hash_table_destroy(atts);
 }
 
 static void
-end_element_handler(GMarkupParseContext *context, const gchar *element_name,
-					gpointer user_data,  GError **error)
+parse_proxy_info(xmlnode *node, GaimAccount *account)
 {
-	AccountParserData *data = user_data;
-	gchar *buffer;
-
-	if (data->buffer == NULL)
-		return;
-
-	buffer = g_string_free(data->buffer, FALSE);
-	data->buffer = NULL;
+	GaimProxyInfo *proxy_info;
+	xmlnode *child;
+	char *data;
 
-	if (data->tag == TAG_PROTOCOL) {
-		data->protocol_id = g_strdup(buffer);
-	}
-	else if (data->tag == TAG_NAME) {
-		if (data->in_proxy) {
-			gaim_proxy_info_set_username(data->proxy_info, buffer);
-		}
-		else {
-			data->account = gaim_account_new(buffer, data->protocol_id);
+	proxy_info = gaim_proxy_info_new();
 
-			gaim_accounts_add(data->account);
-
-			g_free(data->protocol_id);
+	/* Use the global proxy settings, by default */
+	gaim_proxy_info_set_type(proxy_info, GAIM_PROXY_USE_GLOBAL);
 
-			data->protocol_id = NULL;
-		}
-	}
-	else if (data->tag == TAG_PASSWORD) {
-		if (*buffer != '\0') {
-			if (data->in_proxy) {
-				gaim_proxy_info_set_password(data->proxy_info, buffer);
-			}
-			else {
-				gaim_account_set_password(data->account, buffer);
-				gaim_account_set_remember_password(data->account, TRUE);
-			}
+	/* Read proxy type */
+	child = xmlnode_get_child(node, "type");
+	if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
+	{
+		if (!strcmp(data, "global"))
+			gaim_proxy_info_set_type(proxy_info, GAIM_PROXY_USE_GLOBAL);
+		else if (!strcmp(data, "none"))
+			gaim_proxy_info_set_type(proxy_info, GAIM_PROXY_NONE);
+		else if (!strcmp(data, "http"))
+			gaim_proxy_info_set_type(proxy_info, GAIM_PROXY_HTTP);
+		else if (!strcmp(data, "socks4"))
+			gaim_proxy_info_set_type(proxy_info, GAIM_PROXY_SOCKS4);
+		else if (!strcmp(data, "socks5"))
+			gaim_proxy_info_set_type(proxy_info, GAIM_PROXY_SOCKS5);
+		else if (!strcmp(data, "envvar"))
+			gaim_proxy_info_set_type(proxy_info, GAIM_PROXY_USE_ENVVAR);
+		else
+		{
+			gaim_debug_error("account", "Invalid proxy type found when "
+							 "loading account information for %s\n",
+							 gaim_account_get_username(account));
 		}
-	}
-	else if (data->tag == TAG_ALIAS) {
-		if (*buffer != '\0')
-			gaim_account_set_alias(data->account, buffer);
-	}
-	else if (data->tag == TAG_USERINFO) {
-		if (*buffer != '\0')
-			gaim_account_set_user_info(data->account, buffer);
-	}
-	else if (data->tag == TAG_BUDDYICON) {
-		if (*buffer != '\0')
-			gaim_account_set_buddy_icon(data->account, buffer);
+		g_free(data);
 	}
-	else if (data->tag == TAG_TYPE) {
-		if (data->in_proxy) {
-			if (!strcmp(buffer, "global"))
-				gaim_proxy_info_set_type(data->proxy_info,
-										 GAIM_PROXY_USE_GLOBAL);
-			else if (!strcmp(buffer, "none"))
-				gaim_proxy_info_set_type(data->proxy_info, GAIM_PROXY_NONE);
-			else if (!strcmp(buffer, "http"))
-				gaim_proxy_info_set_type(data->proxy_info, GAIM_PROXY_HTTP);
-			else if (!strcmp(buffer, "socks4"))
-				gaim_proxy_info_set_type(data->proxy_info, GAIM_PROXY_SOCKS4);
-			else if (!strcmp(buffer, "socks5"))
-				gaim_proxy_info_set_type(data->proxy_info, GAIM_PROXY_SOCKS5);
-			else if (!strcmp(buffer, "envvar"))
-				gaim_proxy_info_set_type(data->proxy_info, GAIM_PROXY_USE_ENVVAR);
-			else
-				gaim_debug_error("account",
-						   "Invalid proxy type found when loading account "
-						   "information for %s\n",
-						   gaim_account_get_username(data->account));
-		}
+
+	/* Read proxy host */
+	child = xmlnode_get_child(node, "host");
+	if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
+	{
+		gaim_proxy_info_set_host(proxy_info, data);
+		g_free(data);
 	}
-	else if (data->tag == TAG_HOST) {
-		if (data->in_proxy && *buffer != '\0')
-			gaim_proxy_info_set_host(data->proxy_info, buffer);
-	}
-	else if (data->tag == TAG_PORT) {
-		if (data->in_proxy && *buffer != '\0')
-			gaim_proxy_info_set_port(data->proxy_info, atoi(buffer));
+
+	/* Read proxy port */
+	child = xmlnode_get_child(node, "port");
+	if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
+	{
+		gaim_proxy_info_set_port(proxy_info, atoi(data));
+		g_free(data);
 	}
-	else if (data->tag == TAG_SETTING) {
-		if (*buffer != '\0') {
-			if (data->setting_ui != NULL) {
-				if (data->setting_type == GAIM_PREF_STRING)
-					gaim_account_set_ui_string(data->account, data->setting_ui,
-											   data->setting_name, buffer);
-				else if (data->setting_type == GAIM_PREF_INT)
-					gaim_account_set_ui_int(data->account, data->setting_ui,
-											data->setting_name, atoi(buffer));
-				else if (data->setting_type == GAIM_PREF_BOOLEAN)
-					gaim_account_set_ui_bool(data->account, data->setting_ui,
-											 data->setting_name,
-											 (*buffer == '0' ? FALSE : TRUE));
-			}
-			else {
-				if (data->setting_type == GAIM_PREF_STRING)
-					gaim_account_set_string(data->account, data->setting_name,
-											buffer);
-				else if (data->setting_type == GAIM_PREF_INT)
-					gaim_account_set_int(data->account, data->setting_name,
-										 atoi(buffer));
-				else if (data->setting_type == GAIM_PREF_BOOLEAN)
-					gaim_account_set_bool(data->account, data->setting_name,
-										  (*buffer == '0' ? FALSE : TRUE));
-			}
-		}
+
+	/* Read proxy username */
+	child = xmlnode_get_child(node, "username");
+	if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
+	{
+		gaim_proxy_info_set_username(proxy_info, data);
+		g_free(data);
+	}
 
-		g_free(data->setting_name);
-		data->setting_name = NULL;
+	/* Read proxy password */
+	child = xmlnode_get_child(node, "password");
+	if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
+	{
+		gaim_proxy_info_set_password(proxy_info, data);
+		g_free(data);
 	}
-	else if (!strcmp(element_name, "proxy")) {
-		data->in_proxy = FALSE;
 
-		if (gaim_proxy_info_get_type(data->proxy_info) == GAIM_PROXY_USE_GLOBAL) {
-			gaim_proxy_info_destroy(data->proxy_info);
-			data->proxy_info = NULL;
-		}
-		else if (*buffer != '\0') {
-			gaim_account_set_proxy_info(data->account, data->proxy_info);
-		}
-	}
-	else if (!strcmp(element_name, "settings")) {
-		if (data->setting_ui != NULL) {
-			g_free(data->setting_ui);
-			data->setting_ui = NULL;
-		}
+	/* If there are no values set then proxy_infourn NULL */
+	if ((gaim_proxy_info_get_type(proxy_info) == GAIM_PROXY_USE_GLOBAL) &&
+		(gaim_proxy_info_get_host(proxy_info) == NULL) &&
+		(gaim_proxy_info_get_port(proxy_info) == 0) &&
+		(gaim_proxy_info_get_username(proxy_info) == NULL) &&
+		(gaim_proxy_info_get_password(proxy_info) == NULL))
+	{
+		gaim_proxy_info_destroy(proxy_info);
+		return;
 	}
 
-	data->tag = TAG_NONE;
+	gaim_account_set_proxy_info(account, proxy_info);
+}
+
+static GaimAccount *
+parse_account(xmlnode *node)
+{
+	GaimAccount *ret;
+	xmlnode *child;
+	char *protocol_id = NULL;
+	char *name = NULL;
+	char *data;
+
+	child = xmlnode_get_child(node, "protocol");
+	if (child != NULL)
+		protocol_id = xmlnode_get_data(child);
+
+	child = xmlnode_get_child(node, "name");
+	if (child != NULL)
+		name = xmlnode_get_data(child);
+	if (name == NULL)
+	{
+		/* Do we really need to do this? */
+		child = xmlnode_get_child(node, "username");
+		if (child != NULL)
+			name = xmlnode_get_data(child);
+	}
+
+	if ((protocol_id == NULL) || (name == NULL))
+	{
+		free(protocol_id);
+		free(name);
+		return NULL;
+	}
+
+	ret = gaim_account_new(name, protocol_id);
+	free(name);
+	free(protocol_id);
 
-	g_free(buffer);
+	/* Read the password */
+	child = xmlnode_get_child(node, "password");
+	if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
+	{
+		gaim_account_set_password(ret, data);
+		gaim_account_set_remember_password(ret, TRUE);
+		g_free(data);
+	}
+
+	/* Read the alias */
+	child = xmlnode_get_child(node, "alias");
+	if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
+	{
+		gaim_account_set_alias(ret, data);
+		g_free(data);
+	}
+
+	/* Read the userinfo */
+	child = xmlnode_get_child(node, "userinfo");
+	if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
+	{
+		gaim_account_set_user_info(ret, data);
+		g_free(data);
+	}
+
+	/* Read the buddyicon */
+	child = xmlnode_get_child(node, "buddyicon");
+	if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
+	{
+		gaim_account_set_buddy_icon(ret, data);
+		g_free(data);
+	}
+
+	/* Read settings (both core and UI) */
+	for (child = xmlnode_get_child(node, "settings"); child != NULL;
+			child = xmlnode_get_next_twin(child))
+	{
+		parse_settings(child, ret);
+	}
+
+	/* Read proxy */
+	child = xmlnode_get_child(node, "proxy");
+	if (child != NULL)
+	{
+		parse_proxy_info(child, ret);
+	}
+
+	return ret;
 }
 
 static void
-text_handler(GMarkupParseContext *context, const gchar *text,
-			 gsize text_len, gpointer user_data, GError **error)
-{
-	AccountParserData *data = user_data;
-
-	if (data->buffer == NULL)
-		data->buffer = g_string_new_len(text, text_len);
-	else
-		g_string_append_len(data->buffer, text, text_len);
-}
-
-static GMarkupParser accounts_parser =
+load_accounts(void)
 {
-	start_element_handler,
-	end_element_handler,
-	text_handler,
-	NULL,
-	NULL
-};
+	xmlnode *node, *child;
 
-gboolean
-gaim_accounts_load()
-{
-	gchar *filename = g_build_filename(gaim_user_dir(), "accounts.xml", NULL);
-	gchar *contents = NULL;
-	gsize length;
-	GMarkupParseContext *context;
-	GError *error = NULL;
-	AccountParserData *parser_data;
-
-	if (filename == NULL) {
-		accounts_loaded = TRUE;
-		return FALSE;
-	}
+	node = gaim_util_read_xml_from_file("accounts.xml", _("accounts"));
 
-	if (!g_file_get_contents(filename, &contents, &length, &error)) {
-		gaim_debug_error("accounts",
-				   "Error reading accounts: %s\n", error->message);
-		g_error_free(error);
-		g_free(filename);
-		accounts_loaded = TRUE;
-
-		return FALSE;
-	}
-
-	parser_data = g_new0(AccountParserData, 1);
-
-	context = g_markup_parse_context_new(&accounts_parser, 0,
-										 parser_data, free_parser_data);
-
-	if (!g_markup_parse_context_parse(context, contents, length, NULL)) {
-		g_markup_parse_context_free(context);
-		g_free(contents);
-		g_free(filename);
-		accounts_loaded = TRUE;
+	if (node == NULL)
+		return;
 
-		return TRUE;
+	for (child = xmlnode_get_child(node, "account"); child != NULL;
+			child = xmlnode_get_next_twin(child))
+	{
+		GaimAccount *new;
+		new = parse_account(child);
+		gaim_accounts_add(new);
 	}
-
-	if (!g_markup_parse_context_end_parse(context, NULL)) {
-		gaim_debug_error("accounts", "Error parsing %s\n",
-				   filename);
-		g_markup_parse_context_free(context);
-		g_free(contents);
-		g_free(filename);
-		accounts_loaded = TRUE;
-
-		return TRUE;
-	}
-
-	g_markup_parse_context_free(context);
-	g_free(contents);
-	g_free(filename);
-	accounts_loaded = TRUE;
-
-	return TRUE;
 }
 
 static void
@@ -1395,9 +1308,12 @@
 	table = (GHashTable *)value;
 	node  = (xmlnode *)user_data;
 
-	child = xmlnode_new_child(node, "settings");
-	xmlnode_set_attrib(child, "ui", ui);
-	g_hash_table_foreach(table, setting_to_xmlnode, child);
+	if (g_hash_table_size(table) > 0)
+	{
+		child = xmlnode_new_child(node, "settings");
+		xmlnode_set_attrib(child, "ui", ui);
+		g_hash_table_foreach(table, setting_to_xmlnode, child);
+	}
 }
 
 static xmlnode *
@@ -1496,10 +1412,16 @@
 		xmlnode_insert_data(child, tmp, -1);
 	}
 
-	child = xmlnode_new_child(node, "settings");
-	g_hash_table_foreach(account->settings, setting_to_xmlnode, child);
+	if (g_hash_table_size(account->settings) > 0)
+	{
+		child = xmlnode_new_child(node, "settings");
+		g_hash_table_foreach(account->settings, setting_to_xmlnode, child);
+	}
 
-	g_hash_table_foreach(account->ui_settings, ui_setting_to_xmlnode, node);
+	if (g_hash_table_size(account->ui_settings) > 0)
+	{
+		g_hash_table_foreach(account->ui_settings, ui_setting_to_xmlnode, node);
+	}
 
 	if ((proxy_info = gaim_account_get_proxy_info(account)) != NULL)
 	{
@@ -1728,6 +1650,8 @@
 {
 	void *handle = gaim_accounts_get_handle();
 
+	load_accounts();
+
 	gaim_signal_register(handle, "account-connecting",
 						 gaim_marshal_VOID__POINTER, NULL, 1,
 						 gaim_value_new(GAIM_TYPE_SUBTYPE,