# HG changeset patch # User Mark Doliner # Date 1104101572 0 # Node ID 9903182f2aac7c005317fd71ceed2bc4ee953c61 # Parent 108151be77a3a3e15b6a830bdc550498b0832ac5 [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 diff -r 108151be77a3 -r 9903182f2aac src/account.c --- 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, diff -r 108151be77a3 -r 9903182f2aac src/gtkmain.c --- a/src/gtkmain.c Sun Dec 26 18:58:36 2004 +0000 +++ b/src/gtkmain.c Sun Dec 26 22:52:52 2004 +0000 @@ -627,8 +627,6 @@ g_free(gaimrc); g_free(accountsxml); - gaim_accounts_load(); - gaim_set_blist(gaim_blist_new()); gaim_blist_load(); diff -r 108151be77a3 -r 9903182f2aac src/gtkprivacy.c --- a/src/gtkprivacy.c Sun Dec 26 18:58:36 2004 +0000 +++ b/src/gtkprivacy.c Sun Dec 26 22:52:52 2004 +0000 @@ -123,6 +123,7 @@ for (l = list; l != NULL; l = l->next) { temp_name = (const char *)l->data; + /* Should this use gaim_normalize()? */ if (!gaim_utf8_strcasecmp(name, temp_name)) return temp_name; } diff -r 108151be77a3 -r 9903182f2aac src/savedstatuses.c --- a/src/savedstatuses.c Sun Dec 26 18:58:36 2004 +0000 +++ b/src/savedstatuses.c Sun Dec 26 22:52:52 2004 +0000 @@ -101,7 +101,7 @@ /************************************************************************** -* Saved status writting to disk +* Writting to disk **************************************************************************/ static xmlnode * @@ -206,14 +206,14 @@ /************************************************************************** -* Saved status reading from disk +* Reading from disk **************************************************************************/ static GaimSavedStatusSub * parse_substatus(xmlnode *substatus) { GaimSavedStatusSub *ret; xmlnode *node; - char *data = NULL; + char *data; ret = g_new0(GaimSavedStatusSub, 1); @@ -238,21 +238,19 @@ /* Read the state */ node = xmlnode_get_child(substatus, "state"); - if (node != NULL) - data = xmlnode_get_data(node); - if (data != NULL) { + if ((node != NULL) && ((data = xmlnode_get_data(node)) == NULL)) + { ret->type = gaim_status_type_find_with_id( - ret->account->status_types, data); + ret->account->status_types, data); g_free(data); - data = NULL; } /* Read the message */ node = xmlnode_get_child(substatus, "message"); - if (node != NULL) - data = xmlnode_get_data(node); - if (data != NULL) + if ((node != NULL) && ((data = xmlnode_get_data(node)) == NULL)) + { ret->message = data; + } return ret; } @@ -287,7 +285,7 @@ GaimSavedStatus *ret; xmlnode *node; const char *attrib; - char *data = NULL; + char *data; int i; ret = g_new0(GaimSavedStatus, 1); @@ -308,20 +306,18 @@ /* Read the primitive status type */ node = xmlnode_get_child(status, "state"); - if (node != NULL) - data = xmlnode_get_data(node); - if (data != NULL) { + if ((node != NULL) && ((data = xmlnode_get_data(node)) == NULL)) + { ret->type = gaim_primitive_get_type_from_id(data); g_free(data); - data = NULL; } /* Read the message */ node = xmlnode_get_child(status, "message"); - if (node != NULL) - data = xmlnode_get_data(node); - if (data != NULL) + if ((node != NULL) && ((data = xmlnode_get_data(node)) == NULL)) + { ret->message = data; + } /* Read substatuses */ for (node = xmlnode_get_child(status, "status"); node != NULL; @@ -342,48 +338,15 @@ * @return TRUE on success, FALSE on failure (if the file can not * be opened, or if it contains invalid XML). */ -static gboolean -read_statuses(const char *filename) +static void +load_statuses(void) { - GError *error; - gchar *contents = NULL; - gsize length; xmlnode *statuses, *status; - gaim_debug_info("status", "Reading %s\n", filename); - - if (!g_file_get_contents(filename, &contents, &length, &error)) - { - gaim_debug_error("status", "Error reading statuses: %s\n", - error->message); - g_error_free(error); - return FALSE; - } - - statuses = xmlnode_from_str(contents, length); + statuses = gaim_util_read_xml_from_file("status.xml", _("saved statuses")); if (statuses == NULL) - { - FILE *backup; - gchar *name; - gaim_debug_error("status", "Error parsing statuses\n"); - name = g_strdup_printf("%s~", filename); - if ((backup = fopen(name, "w"))) - { - fwrite(contents, length, 1, backup); - fclose(backup); - chmod(name, S_IRUSR | S_IWUSR); - } - else - { - gaim_debug_error("status", "Unable to write backup %s\n", name); - } - g_free(name); - g_free(contents); - return FALSE; - } - - g_free(contents); + return; for (status = xmlnode_get_child(statuses, "status"); status != NULL; status = xmlnode_get_next_twin(status)) @@ -393,40 +356,7 @@ saved_statuses = g_list_append(saved_statuses, new); } - gaim_debug_info("status", "Finished reading statuses\n"); - xmlnode_free(statuses); - - return TRUE; -} - -static void -load_statuses(void) -{ - const char *user_dir = gaim_user_dir(); - gchar *filename; - gchar *msg; - - g_return_if_fail(user_dir != NULL); - - statuses_loaded = TRUE; - - filename = g_build_filename(user_dir, "status.xml", NULL); - - if (g_file_test(filename, G_FILE_TEST_EXISTS)) - { - if (!read_statuses(filename)) - { - msg = g_strdup_printf(_("An error was encountered parsing the " - "file containing your saved statuses (%s). They " - "have not been loaded, and the old file has been " - "renamed to status.xml~."), filename); - gaim_notify_error(NULL, NULL, _("Saved Statuses Error"), msg); - g_free(msg); - } - } - - g_free(filename); } diff -r 108151be77a3 -r 9903182f2aac src/util.c --- a/src/util.c Sun Dec 26 18:58:36 2004 +0000 +++ b/src/util.c Sun Dec 26 22:52:52 2004 +0000 @@ -24,6 +24,7 @@ #include "conversation.h" #include "debug.h" +#include "notify.h" #include "prpl.h" #include "prefs.h" #include "util.h" @@ -2048,6 +2049,75 @@ return TRUE; } +xmlnode * +gaim_util_read_xml_from_file(const char *filename, const char *description) +{ + const char *user_dir = gaim_user_dir(); + gchar *filename_full; + GError *error; + gchar *contents = NULL; + gsize length; + xmlnode *node = NULL; + + g_return_val_if_fail(user_dir != NULL, NULL); + + gaim_debug_info("util", "Reading file %s from directory %s\n", + filename, user_dir); + + filename_full = g_build_filename(user_dir, filename, NULL); + + if (!g_file_test(filename_full, G_FILE_TEST_EXISTS)) + { + gaim_debug_info("util", "File %s does not exist (this is not " + "necessarily an error)\n", filename_full); + g_free(filename_full); + return NULL; + } + + if (!g_file_get_contents(filename_full, &contents, &length, &error)) + { + gaim_debug_error("util", "Error reading file %s: %s\n", + filename_full, error->message); + g_error_free(error); + } + + if ((contents != NULL) && (length > 0)) + { + node = xmlnode_from_str(contents, length); + + /* If we were unable to parse the file then save its contents to a backup file */ + if (node == NULL) + { + gchar *filename_temp; + + filename_temp = g_strdup_printf("%s~", filename); + gaim_debug_error("util", "Error parsing file %s. Rrenaming old " + "file to %s\n", filename_full, filename_temp); + gaim_util_write_data_to_file(filename_temp, contents, length); + g_free(filename_temp); + } + + g_free(contents); + } + + /* If we could not parse the file then show the user an error message */ + if (node == NULL) + { + gchar *title, *msg; + title = g_strdup_printf(_("Error Reading %s"), filename); + msg = g_strdup_printf(_("An error was encountered reading your " + "%s. They have not been loaded, and the old file " + "been renamed to %s~."), description, filename_full); + gaim_notify_error(NULL, NULL, title, msg); + g_free(title); + g_free(msg); + } + + g_free(filename_full); + + return node; +} + /* * Like mkstemp() but returns a file pointer, uses a pre-set template, * uses the semantics of tempnam() for the directory to use and allocates diff -r 108151be77a3 -r 9903182f2aac src/util.h --- a/src/util.h Sun Dec 26 18:58:36 2004 +0000 +++ b/src/util.h Sun Dec 26 22:52:52 2004 +0000 @@ -31,6 +31,7 @@ #include #include "account.h" +#include "xmlnode.h" #ifdef __cplusplus extern "C" { @@ -395,6 +396,23 @@ size_t size); /** + * Read the contents of a given file and parse the results into an + * xmlnode tree structure. This is intended to be used to read + * Gaim's configuration xml files (prefs.xml, pounces.xml, etc.) + * + * @param filename The basename of the file to open in the gaim_user_dir. + * @param description A very short description of the contents of this + * file. This is used in error messages shown to the + * user when the file can not be opened. For example, + * "preferences," or "buddy pounces." + * + * @return An xmlnode tree of the contents of the given file. Or NULL, if + * the file does not exist or there was an error reading the file. + */ +xmlnode *gaim_util_read_xml_from_file(const char *filename, + const char *description); + +/** * Creates a temporary file and returns a file pointer to it. * * This is like mkstemp(), but returns a file pointer and uses a diff -r 108151be77a3 -r 9903182f2aac src/xmlnode.c --- a/src/xmlnode.c Sun Dec 26 18:58:36 2004 +0000 +++ b/src/xmlnode.c Sun Dec 26 22:52:52 2004 +0000 @@ -148,7 +148,7 @@ xmlnode_insert_child(node, attrib_node); } -const char* +const char * xmlnode_get_attrib(xmlnode *node, const char *attr) { xmlnode *x; @@ -231,7 +231,6 @@ g_return_val_if_fail(node != NULL, NULL); - for(c = node->child; c; c = c->next) { if(c->type == XMLNODE_TYPE_DATA) { if(!str) @@ -246,7 +245,7 @@ return g_string_free(str, FALSE); } -static gchar * +static char * xmlnode_to_str_helper(xmlnode *node, int *len, gboolean formatting, int depth) { GString *text = g_string_new(""); @@ -317,16 +316,16 @@ return g_string_free(text, FALSE); } -gchar * +char * xmlnode_to_str(xmlnode *node, int *len) { return xmlnode_to_str_helper(node, len, FALSE, 0); } -gchar * +char * xmlnode_to_formatted_str(xmlnode *node, int *len) { - gchar *xml, *xml_with_declaration; + char *xml, *xml_with_declaration; xml = xmlnode_to_str_helper(node, len, TRUE, 0); xml_with_declaration = diff -r 108151be77a3 -r 9903182f2aac src/xmlnode.h --- a/src/xmlnode.h Sun Dec 26 18:58:36 2004 +0000 +++ b/src/xmlnode.h Sun Dec 26 22:52:52 2004 +0000 @@ -161,7 +161,7 @@ * @return The node repersented as a string. You must * g_free this string when finished using it. */ -gchar *xmlnode_to_str(xmlnode *node, int *len); +char *xmlnode_to_str(xmlnode *node, int *len); /** * Returns the node in a string of human readable xml. @@ -173,7 +173,7 @@ * tab and new line characters. You must * g_free this string when finished using it. */ -gchar *xmlnode_to_formatted_str(xmlnode *node, int *len); +char *xmlnode_to_formatted_str(xmlnode *node, int *len); /** * Creates a node from a string of XML. Calling this on the