# HG changeset patch # User Mark Doliner # Date 1103999607 0 # Node ID 26eac2362c32107b5a47745620af10bbbb0ffb69 # Parent 960b6a41d02f4e51576afb46bbd25aa2f2bfc535 [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 diff -r 960b6a41d02f -r 26eac2362c32 src/blist.c --- 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); diff -r 960b6a41d02f -r 26eac2362c32 src/gtkpluginpref.c --- 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; } diff -r 960b6a41d02f -r 26eac2362c32 src/pluginpref.c --- 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; diff -r 960b6a41d02f -r 26eac2362c32 src/pluginpref.h --- 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 * diff -r 960b6a41d02f -r 26eac2362c32 src/status.c --- 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); } diff -r 960b6a41d02f -r 26eac2362c32 src/util.c --- 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. diff -r 960b6a41d02f -r 26eac2362c32 src/util.h --- 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