diff options
-rw-r--r-- | archiver/ChangeLog | 59 | ||||
-rw-r--r-- | archiver/Makefile.am | 1 | ||||
-rw-r--r-- | archiver/archive.c | 20 | ||||
-rw-r--r-- | archiver/config-log.c | 49 | ||||
-rw-r--r-- | archiver/default-user.xml | 7 | ||||
-rw-r--r-- | archiver/location.c | 101 | ||||
-rw-r--r-- | archiver/location.h | 2 | ||||
-rw-r--r-- | archiver/util.h | 8 |
8 files changed, 190 insertions, 57 deletions
diff --git a/archiver/ChangeLog b/archiver/ChangeLog index 9ff6b22fa..863ecedfa 100644 --- a/archiver/ChangeLog +++ b/archiver/ChangeLog @@ -1,3 +1,62 @@ +2001-04-24 Bradford Hovinen <hovinen@ximian.com> + + * location.c (location_store): Use read rather than fread + +2001-04-23 Bradford Hovinen <hovinen@ximian.com> + + * location.c (location_store): Block SIGPIPE + (location_store): Fix off-by-one bug + + * archive.c (archive_get_current_location_id): Store a full + snapshot of the system after the default location is created + + * location.c (run_backend_proc): Added parameter do_get to allow + control of whether pipe is opened to read or write + (store_snapshot_cb): Implement. Invokes the given backend with + --get and stores the XML data + (location_store_full_snapshot): Implement. Stores a complete + snapshot with all backend data + (subtract_xml_node): Assume all nodes are the same + (location_store): Add string termination character + (location_store): Only store data if any data were actually read + +2001-04-22 Bradford Hovinen <hovinen@ximian.com> + + * config-log.c (config_log_iterate): Use the correct data pointer + to pass to the callback + + * location.c (location_new): Save the metadata for the newly + created location right away + + * util.h: Defined DEBUG_MSG macro for debugging messages + + * archive.c (archive_unregister_location): Don't remove the + location from the tree if the object is marked destroyed + +2001-04-21 Bradford Hovinen <hovinen@ximian.com> + + * archive.c (archive_destroy): Return if the archive was already + destroyed + + * location.c (location_delete): Unregister the location before + destroying it + + * config-log.c (config_log_delete): Set deleted flag + (config_log_destroy): Only dump the log if the log is not marked + deleted + + * location.c (location_delete): Check return value of rmdir + + * config-log.c (io_buffer_destroy): Call g_io_channel_close to + close the GIOChannel + (disconnect_socket): Force the removal of the source id from the + main loop + (config_log_destroy): Disconnect the socket after unloading, not + before + + * location.c (location_delete): Remember to have a NULL at the end + of arguments to g_strconcat () + 2001-04-20 Bradford Hovinen <hovinen@ximian.com> * config-log.c: Added InputBuffer, removed get_line diff --git a/archiver/Makefile.am b/archiver/Makefile.am index 160fb7517..8ebc620e0 100644 --- a/archiver/Makefile.am +++ b/archiver/Makefile.am @@ -13,6 +13,7 @@ INCLUDES = \ -DGNOMELOCALEDIR=\""$(datadir)/locale"\" \ -I$(includedir) $(GNOME_INCLUDEDIR) \ -DVERSION=\""$(VERSION)"\" \ + -DG_LOG_DOMAIN=\"libximian-archiver\" \ -DCONFIGDIR=\""/etc"\" \ -DLOCATION_DIR=\""$(datadir)/ximian-config/default"\" \ -DGLADE_DIR=\""$(datadir)/ximian-config/glade"\" \ diff --git a/archiver/archive.c b/archiver/archive.c index 913fea971..461dc0cda 100644 --- a/archiver/archive.c +++ b/archiver/archive.c @@ -33,6 +33,7 @@ #include <errno.h> #include "archive.h" +#include "util.h" typedef struct _GRealTree GRealTree; typedef struct _GTreeNode GTreeNode; @@ -233,6 +234,8 @@ archive_destroy (GtkObject *object) g_return_if_fail (object != NULL); g_return_if_fail (IS_ARCHIVE (object)); + DEBUG_MSG ("Enter"); + archive = ARCHIVE (object); g_tree_traverse (archive->locations, @@ -246,6 +249,8 @@ archive_destroy (GtkObject *object) g_free (archive->current_location_id); GTK_OBJECT_CLASS (parent_class)->destroy (GTK_OBJECT (archive)); + + DEBUG_MSG ("Exit"); } /** @@ -341,8 +346,9 @@ archive_unregister_location (Archive *archive, Location *location) g_return_if_fail (location != NULL); g_return_if_fail (IS_LOCATION (location)); - /* FIXME: We might be screwing things up here if we're traversing... */ - g_tree_remove (archive->locations, location); + if (GTK_OBJECT_DESTROYED (archive)) return; + + g_tree_remove (archive->locations, location_get_id (location)); } /** @@ -460,6 +466,7 @@ const gchar * archive_get_current_location_id (Archive *archive) { gboolean def; + Location *loc; g_return_val_if_fail (archive != NULL, NULL); g_return_val_if_fail (IS_ARCHIVE (archive), NULL); @@ -477,8 +484,13 @@ archive_get_current_location_id (Archive *archive) /* Create default location if it does not exist */ if (def && archive_get_location (archive, archive->current_location_id) == NULL) - location_new (archive, archive->current_location_id, - NULL); + { + loc = LOCATION + (location_new (archive, + archive->current_location_id, + NULL)); + location_store_full_snapshot (loc); + } } return archive->current_location_id; diff --git a/archiver/config-log.c b/archiver/config-log.c index 70aa08d0a..e7c0b30e7 100644 --- a/archiver/config-log.c +++ b/archiver/config-log.c @@ -83,6 +83,7 @@ struct _ConfigLogPrivate IOBuffer *file_buffer; char *filename; + gboolean deleted; GList *log_data; GList *first_old; @@ -287,8 +288,8 @@ config_log_destroy (GtkObject *object) config_log = CONFIG_LOG (object); + do_unload (config_log, !config_log->p->deleted); disconnect_socket (config_log); - do_unload (config_log, TRUE); GTK_OBJECT_CLASS (parent_class)->destroy (GTK_OBJECT (config_log)); } @@ -351,6 +352,7 @@ config_log_delete (ConfigLog *config_log) if (config_log->p->filename != NULL) unlink (config_log->p->filename); + config_log->p->deleted = TRUE; gtk_object_destroy (GTK_OBJECT (config_log)); } @@ -530,7 +532,7 @@ config_log_iterate (ConfigLog *config_log, ConfigLogIteratorCB callback, while (node != NULL) { entry = (ConfigLogEntry *) node->data; if (callback (config_log, entry->id, entry->backend_id, - entry->date, node->data)) break; + entry->date, data)) break; if (node->next == NULL) node = load_log_entry (config_log, FALSE, @@ -957,8 +959,7 @@ write_log (IOBuffer *output, ConfigLogEntry *entry) entry->date->tm_mon + 1, entry->date->tm_mday, entry->date->tm_hour, entry->date->tm_min, entry->date->tm_sec, entry->backend_id); - g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, - "%s (pid %d): Writing %s", __FUNCTION__, getpid (), str); + DEBUG_MSG ("Writing %s", str); io_buffer_write (output, str); g_free (str); } @@ -971,6 +972,8 @@ dump_log (ConfigLog *config_log) int out_fd; IOBuffer *output; + DEBUG_MSG ("Enter"); + g_return_if_fail (config_log != NULL); g_return_if_fail (IS_CONFIG_LOG (config_log)); g_return_if_fail (config_log->p->location != NULL); @@ -1005,6 +1008,8 @@ dump_log (ConfigLog *config_log) if (config_log->p->filename) rename (filename_out, config_log->p->filename); + + DEBUG_MSG ("Exit"); } static gboolean @@ -1037,9 +1042,7 @@ connect_socket (ConfigLog *config_log) (GIOFunc) socket_connect_cb, config_log); } else { - g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, - "%s (pid %d): Adding watch to listen for data\n", - __FUNCTION__, getpid ()); + DEBUG_MSG ("Adding watch to listen for data"); config_log->p->input_id = g_io_add_watch (config_log->p->socket_buffer->channel, @@ -1116,8 +1119,7 @@ bind_socket (ConfigLog *config_log, int fd, gboolean do_connect) } if (do_connect && !config_log->p->socket_owner) { - g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, - "Trying to connect to socket (pid %d)", getpid ()); + DEBUG_MSG ("Trying to connect to socket"); if (!connect (fd, (struct sockaddr *) &name, SUN_LEN (&name))) return TRUE; @@ -1154,6 +1156,8 @@ disconnect_socket (ConfigLog *config_log) g_list_foreach (config_log->p->slaves, (GFunc) slave_destroy, NULL); + g_source_remove (config_log->p->input_id); + if (config_log->p->socket_buffer != NULL) io_buffer_destroy (config_log->p->socket_buffer); } @@ -1166,8 +1170,7 @@ socket_connect_cb (GIOChannel *channel, GIOCondition condition, struct sockaddr_un addr; socklen_t len; - g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Enter %s (pid %d)", - __FUNCTION__, getpid ()); + DEBUG_MSG ("Enter"); g_return_val_if_fail (config_log != NULL, FALSE); g_return_val_if_fail (IS_CONFIG_LOG (config_log), FALSE); @@ -1188,8 +1191,7 @@ socket_connect_cb (GIOChannel *channel, GIOCondition condition, slave_new (config_log, fd)); } - g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Exit %s (pid %d)", - __FUNCTION__, getpid ()); + DEBUG_MSG ("Exit"); return TRUE; } @@ -1204,8 +1206,7 @@ socket_data_cb (GIOChannel *channel, GIOCondition condition, g_return_val_if_fail (config_log != NULL, FALSE); g_return_val_if_fail (IS_CONFIG_LOG (config_log), FALSE); - g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Enter %s (pid %d)", - __FUNCTION__, getpid ()); + DEBUG_MSG ("Enter"); if (condition == G_IO_IN) { load_log_entry (config_log, TRUE, @@ -1217,8 +1218,7 @@ socket_data_cb (GIOChannel *channel, GIOCondition condition, return FALSE; } - g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Exit %s (pid %d)", - __FUNCTION__, getpid ()); + DEBUG_MSG ("Exit"); return TRUE; } @@ -1270,8 +1270,7 @@ static gboolean slave_data_cb (GIOChannel *channel, GIOCondition condition, Slave *slave) { - g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Enter %s (pid %d)", - __FUNCTION__, getpid ()); + DEBUG_MSG ("Enter"); g_return_val_if_fail (slave != NULL, FALSE); g_return_val_if_fail (slave->config_log != NULL, FALSE); @@ -1287,7 +1286,7 @@ slave_data_cb (GIOChannel *channel, GIOCondition condition, slave_broadcast_data (slave, slave->config_log); } - g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Exit %s", __FUNCTION__); + DEBUG_MSG ("Exit"); return TRUE; } @@ -1348,11 +1347,8 @@ io_buffer_new (GIOChannel *channel, gboolean from_socket) static void io_buffer_destroy (IOBuffer *buffer) { - int fd; - - fd = g_io_channel_unix_get_fd (buffer->channel); + g_io_channel_close (buffer->channel); g_io_channel_unref (buffer->channel); - close (fd); g_free (buffer); } @@ -1426,9 +1422,8 @@ io_buffer_read_line (IOBuffer *buffer) { start_ptr = buffer->read_ptr; buffer->read_ptr = end_ptr + 1; - g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, - "%s (pid %d): Line read was %s; from_socket = %d", - __FUNCTION__, getpid (), start_ptr, buffer->from_socket); + DEBUG_MSG ("Line read was %s; from_socket = %d", + start_ptr, buffer->from_socket); return start_ptr; } diff --git a/archiver/default-user.xml b/archiver/default-user.xml index d7c887869..7868ff38d 100644 --- a/archiver/default-user.xml +++ b/archiver/default-user.xml @@ -2,11 +2,8 @@ <location> <contains backend="background-properties-capplet"/> - <contains backend="bell-properties"/> - <contains backend="gnome-edit-properties-capplet"/> + <contains backend="bell-properties-capplet"/> <contains backend="keyboard-properties"/> - <contains backend="mouse-properties"/> + <contains backend="mouse-properties-capplet"/> <contains backend="screensaver-properties-capplet"/> - <contains backend="session-properties-capplet"/> - <contains backend="wm-properties"/> </location> diff --git a/archiver/location.c b/archiver/location.c index aa22cb0ca..726cfaa2d 100644 --- a/archiver/location.c +++ b/archiver/location.c @@ -33,9 +33,11 @@ #include <tree.h> #include <parser.h> #include <errno.h> +#include <signal.h> #include "location.h" #include "archive.h" +#include "util.h" static GtkObjectClass *parent_class; @@ -85,6 +87,9 @@ static void location_get_arg (GtkObject *object, static void location_destroy (GtkObject *object); static void location_finalize (GtkObject *object); +static gint store_snapshot_cb (Location *location, + gchar *backend_id); + static gint get_backends_cb (BackendList *backend_list, gchar *backend_id, Location *location); @@ -101,7 +106,8 @@ static void write_metadata_file (Location *location, static gboolean do_rollback (gchar *backend_id, xmlDocPtr xml_doc); static xmlDocPtr load_xml_data (gchar *fullpath, gint id); -static gint run_backend_proc (gchar *backend_id); +static gint run_backend_proc (gchar *backend_id, + gboolean do_get); static BackendNote *backend_note_new (gchar *backend_id, ContainmentType type); @@ -290,6 +296,7 @@ location_new (Archive *archive, const gchar *locid, Location *inherits) LOCATION (object)->p->is_new = TRUE; archive_register_location (archive, LOCATION (object)); + save_metadata (LOCATION (object)); return object; } @@ -412,7 +419,7 @@ location_delete (Location *location) g_return_if_fail (IS_LOCATION (location)); metadata_filename = g_strconcat (location->p->fullpath, - "/location.xml"); + "/location.xml", NULL); unlink (metadata_filename); g_free (metadata_filename); @@ -420,7 +427,10 @@ location_delete (Location *location) (ConfigLogIteratorCB) data_delete_cb, location); config_log_delete (location->p->config_log); - rmdir (location->p->fullpath); + if (rmdir (location->p->fullpath) == -1) + g_warning ("%s: Could not remove directory: %s\n", + __FUNCTION__, g_strerror (errno)); + gtk_object_destroy (GTK_OBJECT (location)); } @@ -445,24 +455,33 @@ location_store (Location *location, gchar *backend_id, FILE *input, { xmlDocPtr doc; char *buffer = NULL; - int len = 0; + int len = 0, bytes_read = 0; g_return_if_fail (location != NULL); g_return_if_fail (IS_LOCATION (location)); - while (!feof (input)) { - if (!len) buffer = g_new (char, 16384); - else buffer = g_renew (char, buffer, len + 16384); - fread (buffer + len, 1, 16384, input); - len += 16384; - } + fflush (input); - doc = xmlParseMemory (buffer, strlen (buffer)); - g_free (buffer); + do { + DEBUG_MSG ("Iteration"); + if (!len) buffer = g_new (char, 4097); + else buffer = g_renew (char, buffer, len + 4097); + bytes_read = read (fileno (input), buffer + len, 4096); + buffer[len + bytes_read] = '\0'; + len += 4096; + } while (bytes_read == 4096); - location_store_xml (location, backend_id, doc, store_type); + if (len >= 4096 && len > 0) { + DEBUG_MSG ("Data found; parsing"); + doc = xmlParseMemory (buffer, len - 4096 + bytes_read); + g_free (buffer); - xmlFreeDoc (doc); + location_store_xml (location, backend_id, doc, store_type); + + xmlFreeDoc (doc); + } else { + g_critical ("No data to store"); + } } /** @@ -1077,6 +1096,41 @@ location_set_id (Location *location, const gchar *locid) config_log_reset_filenames (location->p->config_log); } +/** + * location_store_full_snapshot: + * @location: + * + * Gets XML snapshot data from all the backends contained in this location and + * archives those data + */ + +void +location_store_full_snapshot (Location *location) +{ + g_return_if_fail (location != NULL); + g_return_if_fail (IS_LOCATION (location)); + + location_foreach_backend (location, + (LocationBackendCB) store_snapshot_cb, + NULL); +} + +static gint +store_snapshot_cb (Location *location, gchar *backend_id) +{ + int fd; + FILE *pipe; + + DEBUG_MSG ("Storing %s", backend_id); + + fd = run_backend_proc (backend_id, TRUE); + pipe = fdopen (fd, "r"); + location_store (location, backend_id, pipe, STORE_MASK_PREVIOUS); + fclose (pipe); + + return FALSE; +} + static gint get_backends_cb (BackendList *backend_list, gchar *backend_id, Location *location) @@ -1349,7 +1403,7 @@ do_rollback (gchar *backend_id, xmlDocPtr doc) */ if (doc == NULL) return FALSE; - fd = run_backend_proc (backend_id); + fd = run_backend_proc (backend_id, FALSE); if (fd == -1) return FALSE; output = fdopen (fd, "w"); @@ -1372,22 +1426,26 @@ load_xml_data (gchar *fullpath, gint id) return xml_doc; } -/* Run the given backend and return the file descriptor used to write +/* Run the given backend and return the file descriptor used to read or write * XML to it */ static gint -run_backend_proc (gchar *backend_id) +run_backend_proc (gchar *backend_id, gboolean do_get) { char *args[3]; int fd[2]; pid_t pid; + int p_fd, c_fd; if (pipe (fd) == -1) return -1; pid = fork (); + p_fd = do_get ? 0 : 1; + c_fd = do_get ? 1 : 0; + if (pid == (pid_t) -1) { return -1; } @@ -1395,7 +1453,7 @@ run_backend_proc (gchar *backend_id) int i; gchar *path, *path1; - dup2 (fd[0], 0); + dup2 (fd[c_fd], c_fd); for (i = 3; i < FOPEN_MAX; i++) close (i); path = g_getenv ("PATH"); @@ -1408,11 +1466,12 @@ run_backend_proc (gchar *backend_id) } args[0] = gnome_is_program_in_path (backend_id); - args[1] = "--set"; + args[1] = do_get ? "--get" : "--set"; args[2] = NULL; if (!args[0]) { g_warning ("Backend not in path: %s", backend_id); + close (c_fd); exit (-1); } @@ -1421,7 +1480,7 @@ run_backend_proc (gchar *backend_id) return 0; } else { - return fd[1]; + return fd[p_fd]; } } @@ -1573,7 +1632,7 @@ subtract_xml_node (xmlNodePtr node1, xmlNodePtr node2, gboolean strict) { xmlNodePtr child, tmp, iref; GList *node2_children = NULL, *i; - gboolean found, same, all_same; + gboolean found, same, all_same = TRUE; if (node1->type == XML_TEXT_NODE) { if (node2->type == XML_TEXT_NODE && diff --git a/archiver/location.h b/archiver/location.h index 97141fd5a..674c3bd84 100644 --- a/archiver/location.h +++ b/archiver/location.h @@ -135,4 +135,6 @@ const gchar *location_get_id (Location *location); void location_set_id (Location *location, const gchar *locid); +void location_store_full_snapshot (Location *location); + #endif /* __LOCATION */ diff --git a/archiver/util.h b/archiver/util.h index e3f61d937..444feaa0b 100644 --- a/archiver/util.h +++ b/archiver/util.h @@ -27,6 +27,14 @@ #include <time.h> #include <glib.h> +#ifdef __GNUC__ +# define DEBUG_MSG(str, args...) \ + g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "(%d:%s) " str, \ + getpid (), __FUNCTION__ , ## args) +#else +# define DEBUG_MSG(str, args...) +#endif + gboolean extract_number (char **str, int *number, int digits); struct tm *parse_date (char *str); |