summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--archiver/ChangeLog59
-rw-r--r--archiver/Makefile.am1
-rw-r--r--archiver/archive.c20
-rw-r--r--archiver/config-log.c49
-rw-r--r--archiver/default-user.xml7
-rw-r--r--archiver/location.c101
-rw-r--r--archiver/location.h2
-rw-r--r--archiver/util.h8
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);