diff options
Diffstat (limited to 'archiver')
39 files changed, 0 insertions, 10544 deletions
diff --git a/archiver/.cvsignore b/archiver/.cvsignore deleted file mode 100644 index 92ae86e11..000000000 --- a/archiver/.cvsignore +++ /dev/null @@ -1,18 +0,0 @@ -.deps -.libs -*.lo -*.la -Makefile -ximia-archiver -Makefile.in -ximian-config-manager -ximian_archiverConf.sh -ximian-archiver -bonobo-moniker-archiver -config-archiver -config_archiverConf.sh -Bonobo_Moniker_archiver.oaf -ConfigArchiver.h -ConfigArchiver-stubs.c -ConfigArchiver-skels.c -ConfigArchiver-common.c diff --git a/archiver/Bonobo_Moniker_archiver.oaf.in b/archiver/Bonobo_Moniker_archiver.oaf.in deleted file mode 100644 index 825ebcc99..000000000 --- a/archiver/Bonobo_Moniker_archiver.oaf.in +++ /dev/null @@ -1,35 +0,0 @@ -<oaf_info> - -<oaf_server iid="OAFIID:Bonobo_Moniker_archiver_Factory" type="exe" location="bonobo-moniker-archiver"> - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/GenericFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="name" type="string" value="XML Database Moniker factory"/> -</oaf_server> - -<oaf_server iid="OAFIID:Bonobo_Moniker_archiverdb" type="factory" - location="OAFIID:Bonobo_Moniker_archiver_Factory"> - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:Bonobo/Moniker:1.0"/> - <item value="IDL:Bonobo/Unknown:1.0"/> - </oaf_attribute> - <oaf_attribute name="name" type="string" value="XML Database Moniker with archiver interface"/> - <oaf_attribute name="bonobo:moniker" type="stringv"> - <item value="archiverdb:"/> - </oaf_attribute> -</oaf_server> - -<oaf_server iid="OAFIID:Bonobo_Moniker_archive" type="factory" - location="OAFIID:Bonobo_Moniker_archiver_Factory"> - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:Bonobo/Moniker:1.0"/> - <item value="IDL:Bonobo/Unknown:1.0"/> - </oaf_attribute> - <oaf_attribute name="name" type="string" value="XML archiver interface"/> - <oaf_attribute name="bonobo:moniker" type="stringv"> - <item value="archive:"/> - </oaf_attribute> -</oaf_server> - -</oaf_info> diff --git a/archiver/ChangeLog b/archiver/ChangeLog deleted file mode 100644 index 5f450d040..000000000 --- a/archiver/ChangeLog +++ /dev/null @@ -1,1084 +0,0 @@ -2004-10-14 Jody Goldberg <jody@gnome.org> - - * Release 2.8.1 - -2004-04-15 Jody Goldberg <jody@gnome.org> - - * Release 2.6.1 - -2004-04-01 Jody Goldberg <jody@gnome.org> - - * Release 2.6.0.3 - -2004-03-30 Jody Goldberg <jody@gnome.org> - - * Release 2.6.0.1 - -2004-03-23 Jody Goldberg <jody@gnome.org> - - * Release 2.6.0 - -2004-03-11 Jody Goldberg <jody@gnome.org> - - * Release 2.5.4 - -2004-02-13 Jody Goldberg <jody@gnome.org> - - * Release 2.5.3 - -2004-01-14 Jody Goldberg <jody@gnome.org> - - * Release 2.5.2 - -2003-12-30 Jody Goldberg <jody@gnome.org> - - * Release 2.5.1.1 - -2003-12-30 Jody Goldberg <jody@gnome.org> - - * Release 2.5.1 - -2003-10-28 Jody Goldberg <jody@gnome.org> - - * Release 2.5.0 - -2003-07-07 Jody Goldberg <jody@gnome.org> - - * Release 2.3.4 - -2003-06-24 Jody Goldberg <jody@gnome.org> - - * Release 2.3.3 - -2003-05-07 Jody Goldberg <jody@gnome.org> - - * Release 2.3.1 - -Tue Feb 4 17:09:18 2003 Jonathan Blandford <jrb@redhat.com> - - * Release 2.2.0.1 - -Tue Jan 21 01:15:14 2003 Jonathan Blandford <jrb@gnome.org> - - * Release 2.2.0 - -Thu Jan 16 02:41:09 2003 Jonathan Blandford <jrb@gnome.org> - - * Release 2.1.7 - -2003-01-10 Jody Goldberg <jody@gnome.org> - - * Release 2.1.6 - -2002-12-18 Jody Goldberg <jody@gnome.org> - - * Release 2.1.5 - -2002-11-23 Jody Goldberg <jody@gnome.org> - - * Release 2.1.3 - -2002-11-02 Jody Goldberg <jody@gnome.org> - - * Release 2.1.2 - -2002-10-21 Jody Goldberg <jody@gnome.org> - - * Release 2.1.1 - -2002-10-01 Jody Goldberg <jody@gnome.org> - - * Release 2.1.0.1 - -2002-08-21 Jody Goldberg <jody@gnome.org> - - * Release 2.1.0 - -2002-06-17 Jody Goldberg <jody@gnome.org> - - * Release 2.0.0 - -2002-02-27 Kjartan Maraas <kmaraas@gnome.org> - - * config-archiver.c: s/PACKAGE/GETTEXT_PACKAGE/g - * config-manager.c: Same here. - -2001-10-18 Bradford Hovinen <hovinen@ximian.com> - - * bonobo-config-archiver.c (get_listener_oafiid): Update listener name - -2001-10-13 Bradford Hovinen <hovinen@ximian.com> - - * bonobo-config-archiver.c (real_sync): Try to resolve a listener - to make sure that something is listening when we issue the sync - event (disabled for now) - (get_listener_oafiid): Implement (disabled for now) - -2001-10-05 Shaun Merrigan <shaun.merrigan@sun.com> - - * archiver-client.c (location_client_load_rollback_data): - Only use tm_gmtoffm if __USE_BSD is defined. - -2001-09-28 Bradford Hovinen <hovinen@ximian.com> - - * config-log.c (parse_line): Only set tm_gmtoff and tm_zone fields - if __USE_BSD is defined - - * util.c (parse_date): Ditto - - * bonobo-config-archiver.c (bonobo_config_archiver_new): Store the - listener id in the archiver_db structure - (bonobo_config_archiver_destroy): Remove the event source - listener; destroy the XML cache - (new_rollback_cb): Don't reload everything if we initiated the - sync ourselves - (real_sync): Mark that we are currently up to date - -2001-09-22 Bradford Hovinen <hovinen@ximian.com> - - * bonobo-config-archiver.c (notify_listeners): Abort if the object - is already destroyed - -2001-09-07 Bradford Hovinen <hovinen@ximian.com> - - * archiver-client.c (location_client_store_xml): Make backend_id - const - - * util.c (parse_date): Set the time zone - (parse_date): Initialize tm_isdst - - * archiver-client.c (location_client_store_xml): Call - ConfigArchiver_Location_storageComplete when done - (location_client_store_xml): Don't try to save the XML file if - there was an error getting the storage filename - - * location.c (location_storage_complete): Implement - (impl_ConfigArchiver_Location_storageComplete): Implement - - * config-log.c (config_log_get_backend_id_for_id): Make return - value const - -2001-09-04 Bradford Hovinen <hovinen@ximian.com> - - * location.c (location_get_storage_filename): Notify listeners - that new rollback data is available - - * bonobo-config-archiver.c (new_rollback_cb): Implement - (bonobo_config_archiver_new): Connect above to event source - - * location.c (location_store): - (location_init): Construct an event source and add its interface - - * Makefile.am (INCLUDES): Remove -DDEFAULTS_DIR - -2001-09-03 Bradford Hovinen <hovinen@ximian.com> - - * bonobo-config-archiver.c (bonobo_config_archiver_new): Accept - complete moniker as an argument; do the parsing here - - * archiver-client.c (location_client_load_rollback_data): Adjust - time from mktime according to time zone information - - * bonobo-moniker-archiver.c (is_leap_year): - (mod_date_by_str): Implement - (parse_name): Use correct math for computing offsets - - * bonobo-config-archiver.c (bonobo_config_archiver_new): Don't - print an error message if the parent moniker is bad - (bonobo_config_archiver_new): Remove debugging messages - - * archiver-client.c (location_client_load_rollback_data): Make - date and backend_id const - - * bonobo-moniker-archiver.c (archiverdb_resolve): Determine date - from moniker and pass to bonobo_config_archiver_new - - * bonobo-config-archiver.c (bonobo_config_archiver_new): Accept - date structure as argument - -2001-08-29 Bradford Hovinen <hovinen@ximian.com> - - * archive.c (foreach_build_list_cb): Don't unref the location if - it is deleted - (load_all_locations): Check if the location is marked deleted and - throw it away if so - - * location.c (location_new): Don't unref parent location - -2001-08-28 Bradford Hovinen <hovinen@ximian.com> - - * archive.c (foreach_build_list_cb): Unref the location given if - we are not going to use it - -2001-08-27 Bradford Hovinen <hovinen@ximian.com> - - * archive.c (foreach_build_list_cb): Don't add the location to the - list if it is marked deleted - (impl_ConfigArchiver_Archive_createLocation): Do - CORBA_Object_duplicate rather than bonobo_object_dup_ref - - * location.c (location_is_deleted): Implement - -2001-08-23 Bradford Hovinen <hovinen@ximian.com> - - * config-log.c (do_unload): Make sure we don't try to do this if - we are marked deleted - (config_log_delete): Call do_unload to eliminate memory leaks - - * location.c (location_delete): Set the deleted flag - - * config-log.c (dump_log): Don't try to dump the log if we are - deleted - - * location.c (save_metadata): Don't try to save metadata if we are - deleted - -2001-08-22 Hans Petter Jansson <hpj@ximian.com> - - * archiver-client.h: Fixed include path, libxml -> gnome-xml. It's - consistent with the includes in archiver-client.c, and it stops - the build breaking here. - -2001-08-21 Bradford Hovinen <hovinen@ximian.com> - - * archive.c (archive_get_current_location_id): Use - archive_create_location rather than location_new - (archive_get_current_location_id): Unref the location once we have - created it - - * archiver-client.c (location_client_load_rollback_data): Don't - try to parse the XML file if there was an exception - - * bonobo-config-archiver.c (bonobo_config_archiver_new): Make sure - to release_unref location and archive if aborting - (bonobo_config_archiver_new): Reinitialize exception structure - after we have succeeded - - * location.c (location_get_rollback_filename): Recurse on parent - location if parent_chain is set to TRUE - - * archive.c (impl_ConfigArchiver_Archive_getLocation): Set the - LocationNotFound exception if the location returned was NULL - - * location.c (impl_ConfigArchiver_Location_getRollbackFilename): Don't try - - * archive.c (impl_ConfigArchiver_Archive_getLocation): Don't try - to CORBA_Object_duplicate the result if it is NULL - (archive_get_location): Don't try to cast the result of - location_open before we know whether it is non-NULL - (impl_ConfigArchiver_Archive_createLocation): Call - bonobo_object_from_servant on parent_ref->servant - - * location.c (location_destroy): Remove debugging message; make - remaining debugging message more enlightening - - * archive.c (archive_get_child_locations): Rename from - archive_foreach_child_location; rewrite to return a GList of child - locations - (impl_ConfigArchiver_Archive_getChildLocations): Use - archive_get_child_locations - (archive_destroy): Remove debugging message - - * bonobo-moniker-archiver.c (archive_resolve): Remove debugging - messages - - * archive.c (archive_get_location): Remove debugging messages - - * config-log.c (dump_log): Remove debugging messages - - * archive.c (archive_foreach_child_location): Build a list first - and then traverse it to avoid screwing up the tree traversal - -2001-08-20 Richard Hestilow <hestilow@ximian.com> - - * Makefile.am: Add dependency on CORBA_SOURCE to archiver-client.c. - (clean-local): Add CORBA_SOURCE to files to be removed. - -2001-08-17 Bradford Hovinen <hovinen@ximian.com> - - * all: Added CORBA interface for the archiver - * config-archiver.c: Ported to new CORBA interface - -2001-08-20 Bradford Hovinen <hovinen@ximian.com> - - * location.c (load_metadata_file): Support placing the location's - label in the metadata file - -2001-08-03 Bradford Hovinen <hovinen@ximian.com> - - * config-log.c (load_log_entry): Return NULL if fgets returns NULL - (dump_log): If both first_old and log_data are NULL, go ahead and - dump the file, since nothing has been loaded yet - (config_log_garbage_collect): Don't bother dumping the log file or - reloading - (load_log_entry): Return NULL if file_stream is NULL - -2001-08-02 Bradford Hovinen <hovinen@ximian.com> - - * config-log.c (config_log_garbage_collect): Implement - (dump_log): Don't dump the old file if first_old is NULL - - * main.c (main): Support --garbage_collect - - * location.c (location_garbage_collect): - (garbage_collect_cb): Implement - -2001-07-31 Bradford Hovinen <hovinen@ximian.com> - - * config-log.c: Remove socket-based synchronization system - entirely. Switch to using standard FILE streams for interfacing - with the configuration log - - * archive.c (archive_get_current_location_id): Re-enable caching - mechanism - - * bonobo-config-archiver.c (pb_get_fn): Use - location_get_config_log rather than config_log_open; don't destroy - the log - (bonobo_config_archiver_new): Eliminate unref mechanism; it is not - needed - -2001-07-30 Bradford Hovinen <hovinen@ximian.com> - - * archive.c (archive_set_current_location_id): Use - capplet-archive/config/current/location for current location to - avoid conflicting with control-center - (archive_get_current_location_id): Always retrieve the location id - from gnome_config - - * config-log.c (socket_data_cb): Close the socket if we couldn't - load the log entry - (config_log_destroy): - (config_log_open): Disable socket sync system - (config_log_write_entry): Make sure to write log when socket_owner - not set - - * location.c (location_get_config_log): Implement - -2001-07-27 Bradford Hovinen <hovinen@ximian.com> - - * bonobo-config-archiver.c (bonobo_config_archiver_destroy): Don't - unref the event source or the property bag - - * RELEASE : 1.5.2 - -2001-07-24 Richard Hestilow <hestilow@ximian.com> - - * bonobo-config-archiver.c (pb_set_fn): Do sanity checking on - the rollback ID we get. - -2001-07-24 Richard Hestilow <hestilow@ximian.com> - - * config-log.c (parse_line): Ok, bad fix. Move that to the archiver. - - * bonobo-config-archiver.c (pb_set_fn): Moved here. - (bonobo_config_archiver_new): Don't aggregate against an EventSource, - since the PropertyBag already has one and everything will get confused. - Just use the one the bag has. - (bonobo_config_archiver_destroy): Don't unref the event source, we - don't own it any more. - -2001-07-24 Richard Hestilow <hestilow@ximian.com> - - * config-log.c (parse_line): Fix date parsing to work with DST. - - * bonobo-config-archiver.[ch]: Export a PropertyBag interface that - has the last_modified date as a read-only property. - -2001-07-24 Bradford Hovinen <hovinen@ximian.com> - - * bonobo-config-archiver.c (real_sync): Notify listeners with a sync event - (real_sync): Use correct pointer type when passing to notify_listeners - -2001-07-20 Chema Celorio <chema@celorio.com> - - * RELEASE : 1.5.0 - -2001-07-17 Bradford Hovinen <hovinen@ximian.com> - - * bonobo-config-archiver.c (bonobo_config_archiver_new): Add - mechanism for quitting once the moniker is no longer in use - (bonobo_config_archiver_new): Make archive a static variable - (bonobo_config_archiver_new): Explicitly destroy archive when - program quits - (timeout_cb): Remove - - * config-log.c (slave_apprise_data): Remove - - * archive.c (archive_unregister_location): - (archive_get_location): strdup the string to remove compiler warnings - - * location.c (location_store): Use return value - (location_store_full_snapshot): Use return value - -2001-07-12 Bradford Hovinen <hovinen@ximian.com> - - * archive.c (archive_destroy): Clear appropriate global archive pointer - (archive_get_current_location_id): Logic fix. - -2001-07-12 Chema Celorio <chema@celorio.com> - - * Makefile.am (INCLUDES): update to the new location for the xst backends - -2001-07-12 Bradford Hovinen <hovinen@ximian.com> - - * archive.c (archive_get_current_location_id): Only try to store a - full snapshot if we are in a global archive - - * bonobo-config-archiver.c (bonobo_config_archiver_new): Store - real_name in archiver_db - (bonobo_config_archiver_destroy): Use archiver_db->real_name with - bonobo_url_register - -2001-07-10 Bradford Hovinen <hovinen@ximian.com> - - * default-user.xml: Add sound-properties - - * bonobo-moniker-archiver.c (archiver_resolve): Don't accept - PropertyBag interface - -2001-07-09 Bradford Hovinen <hovinen@ximian.com> - - * bonobo-config-archiver.c (bonobo_config_archiver_new): Use - bonobo_object_unref rather than gtk_object_destroy - - * bonobo-moniker-archiver.c (archiver_resolve): Allow PropertyBag - interface as well - (parse_name): Set *location to NULL when there is no location - - * archive.c (archive_load): Use .gnome/capplet-archive rather than - .gnome/control-center - (archive_set_current_location): Removed unused variables - - * bonobo-config-archiver.c (bonobo_config_archiver_new): Try to - load the defaults file if no rollback data can be found - -2001-07-05 Bradford Hovinen <hovinen@ximian.com> - - * bonobo-config-archiver.[ch]: Use bonobo-conf rather than - bonobo-config for include path - - * bonobo-moniker-archiver.c (archiver_resolve): Update call to - Bonobo_ConfigDatabase_addDatabase - - * bonobo-config-archiver.h: Fix include directories - - * Makefile.am (INCLUDES): Update to use pkg-config standards; add - BONOBO_CFLAGS - Include configuration moniker-related material - (SUBDIRS): Remove - (bin_PROGRAMS): Added ximian-archiver - -2001-07-02 Tambet Ingo <tambet@ximian.com> - - * default-global.xml: Added display-conf backend. - -2001-06-22 Bradford Hovinen <hovinen@ximian.com> - - * archive.c (archive_get_current_location): Return NULL if the - location id is NULL - (archive_get_current_location_id): Return NULL if storing the - snapshot results in an error - - * location.c (location_store): Add return values for error - conditions; remove g_warning's and g_critical's - (location_store_full_snapshot): Folded in store_snapshot_cb; don't - call location_foreach_backend - (location_store_full_snapshot): Return error condition; 0 on - success, -1 if any backend failed - -2001-06-21 Bradford Hovinen <hovinen@ximian.com> - - * location.c (location_do_rollback): Wait for child process to - terminate - (run_backend_proc): Take an extra argument -- where to store the - PID of the child process - - * archive.c (archive_set_current_location): Use - location_get_changed_backends - - * location.c (location_get_changed_backends): - (location_does_backend_change): Implement - (create_backends_list): - (merge_backend_lists): Moved from archive.c - - * config-log.c (dump_log): Don't call close on fd - (dump_log): Use g_critical on error conditions rather than g_warning - -2001-06-20 Bradford Hovinen <hovinen@ximian.com> - - * config-log.c (slave_data_cb): Dump the log after loading it from - the slave - (dump_log): Set first_old to the beginning of the list after the dump - (do_load): Don't call do_unload - (socket_data_cb): Check for hang up first - (do_load): Don't call reset_filenames - (slave_data_cb): - (config_log_write_entry): Call io_buffer_destroy - - * archive.c, Makefile.am: Replace all instances of ximian-config - with ximian-setup-tools - - * config-log.c (slave_new): Don't apprise slave of new data - (config_log_write_entry): Dump log after every write - -2001-06-19 Bradford Hovinen <hovinen@ximian.com> - - * archive.c (archive_set_current_location): Free the location path - as we walk down it. - (create_backends_list): Implement - (merge_backend_lists): Implement - (archive_set_current_location): Call above functions - (create_backends_list): Get rid of dummy first element - (archive_set_current_location): Don't use backends->next when - calling rollback_backends_to - - * location.c (run_backend_proc): Remember to close the writing end - (location_store): Change g_error to g_critical - (run_backend_proc): Don't getenv PATH - (run_backend_proc): Make sure to close other end of pipe in child - process - -2001-06-18 Bradford Hovinen <hovinen@ximian.com> - - * location.c (location_store): Use GString API - - * config-log.c (slave_data_cb): Don't use == to test IO conditions - -2001-06-01 Bradford Hovinen <hovinen@ximian.com> - - * location.c (run_backend_proc): Don't free path string after - setting the path - -2001-05-26 Chema Celorio <chema@celorio.com> - - * Makefile.am (ximian_archiverConf.sh): create x_aConf.sh from - the XIMIAN_ARCHIVER_FOO_CONF varialbes - -2001-05-24 Arturo Espinosa Aldama <arturo@ximian.com> - - * 0.5 RELEASE - -2001-05-24 Chema Celorio <chema@celorio.com> - - * Makefile.am (libximian_archiver_la_SOURCES): add config- - manger-dialog so that distcheck would pass - (SUBDIRS): add the . dir because the capplet depends on - the archiver and we need to build the archiver first - (libximian_archiver_la_SOURCES): add location-list & - create-location-dialog - (ximian_archiverConf.sh): change to XIMIAN_ARVHIER_FOO - -2001-05-24 Bradford Hovinen <hovinen@ximian.com> - - * Makefile.am (SUBDIRS): Added location-manager-capplet - -2001-05-22 JP Rosevear <jpr@ximian.com> - - * config-log.c (bind_socket): use AF_UNIX for the family - - * location.c (run_backend_proc): use putenv() rather than setenv() - for solaris - - * config-log.c: define the SUN_LEN macro for those systems not - having it - (connect_socket): use the more portable domain type, PF_LOCAL - seems to map to PF_UNIX on linux anyhow - -2001-05-12 Chema Celorio <chema@celorio.com> - - * location.c (location_store_xml): add a carriage return after the - warning message - -2001-05-09 Arturo Espinosa Aldama <arturo@ximian.com> - - * 0.4 RELEASE - -2001-05-05 Bradford Hovinen <hovinen@ximian.com> - - * Makefile.am (ximian_archiverConf.sh): Add sed expression to - replace @VERSION@ - -2001-05-04 Bradford Hovinen <hovinen@ximian.com> - - * cluster-location.c (cluster_location_do_rollback): Implement - - * location.c (location_do_rollback): Rename from do_rollback; make - into virtual method - (location_rollback_backend_to): - (location_rollback_backend_by): - (location_rollback_id): Update to call virtual method - - * Makefile.am (libximian_archiver_la_SOURCES): - (include_HEADERS): Add cluster.[ch], cluster-location.[ch] - -2001-05-03 Bradford Hovinen <hovinen@ximian.com> - - * cluster.[ch]: New class - - * cluster.c (cluster_new): - (cluster_load): Implement - - * archive.c (archive_set_arg): Add argument ARG_IS_GLOBAL - (archive_class_init): Make ARG_PREFIX construct-only - (archive_construct): Implement - (do_load): Remove - (archive_load): Use archive_construct; pass is_global as an - argument to the object constructor - - * location.c (location_store_xml): Support STORE_DEFAULT - (store_snapshot_cb): Use STORE_DEFAULT rather than STORE_MASK_PREVIOUS - - * location.h (_StoreType): Add STORE_DEFAULT - - * config-log.c (config_log_get_rollback_id_by_steps): Return the - current id if the node represents default data - - * main.c (do_add_location): Cast correctly, fixing compiler - warning - - * config-log.c (config_log_write_entry): Add parameter - is_default_data; call get_beginning_of_time rather than - get_current_date iff is_default_data is TRUE - (get_beginning_of_time): Implement - (has_nondefaults): Implement. Return TRUE iff the config log - contains regular (non-default) entries - -2001-04-26 Arturo Espinosa <arturo@ximian.com> - - * location.c: changed g_critical to g_error. If a newer - version of glib is to be required, change configure.in then. - * util.h: Set a flag to disable the DEBUG_MSG macro, which - messes with the frontend<->backend talking. - -2001-04-24 Bradford Hovinen <hovinen@ximian.com> - - * location.c (location_store): Use read rather than fread - (location_add_backend): - (location_remove_backend): Save metadata immediately - -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 - (struct _Slave): - (struct _ConfigLogPrivate ): Replaced GIOChannel * and FILE * with - InputBuffer *'s - (input_buffer_new): Implement. Constructs a new input buffer - (input_buffer_destroy): Implement. Destroys an input buffer and - closes the file descriptor - (input_buffer_cycle): Implement (borrowed from GDict). Reads - additional data from the input file - (input_buffer_read_line): Implement (borrowed from GDict). Reads a - line from the input file and returns a pointer to it - (input_buffer_write): Implement. Write the indicated string out to - the channel - -2001-04-15 Bradford Hovinen <hovinen@ximian.com> - - * config-log.c (config_log_set_arg): Create semaphore for - auto-reloading - (do_load): Removed locking code - (load_log_entry): Support prepending log entries to the beginning - of the log; free entry->date if parsing was unsuccessful - (config_log_reset_filenames): Unlink socket filename if not owner - (config_log_reset_filenames): Rebind socket when filename is reset - (connect_socket): Implement. Creates or connects to the socket - associated with the config log - (check_socket_filename): Implement. Checks to see if the filename - associated with the socket is in use. - (bind_socket): Implement. Binds the socket to the filename. - (socket_connect_cb): Implement. Callback issued when a master gets - a new connection. - (socket_data_cb): Implement. Callback issued when a slave gets - data from the master. - (slave_new): Implement. Creates a new slave structure - (slave_destroy): Implement. Destroys a slave structure - (slave_data_cb): Implement. Callback issued when data comes in - from a slave - (slave_broadcast_data): Implement. Broadcast the first log entry - to all the slaves except the given one - (disconnect_socket): Implement. Disconnects the socket - (config_log_open): Call connect_socket - (do_unload): Don't dump the log unless currently the socket owner - (config_log_write_entry): Broadcast data to slaves or write data - to socket, depending on whether currently the socket owner - -2001-04-14 Bradford Hovinen <hovinen@ximian.com> - - * config-log.c (do_unload): Add a parameter write_log to tell - whether to write out the log when unloading - (config_log_finalize): Implement - - * config-log.[ch]: Put all data fields in ConfigLogPrivate - structure - -2001-04-11 Bradford Hovinen <hovinen@ximian.com> - - * location.c (run_backend_proc): Make sure to search location of - XST backends - - * Makefile.am (INCLUDES): Added XST_BACKEND_LOCATION - - * archive.c (archive_set_current_location_id): Don't use different - prefixes for per-user and global locations; we are assuming here - that the only person using this globally will be root anyway - (archive_get_current_location_id): Ditto - - * Makefile.am (INCLUDES): Replace obsolete hcm directory names - with ximian-config - -2001-02-20 Bradford Hovinen <hovinen@ximian.com> - - * location.c (compare_xml_nodes): Use attr->val rather than - attr->node - -2001-02-19 Bradford Hovinen <hovinen@ximian.com> - - * location.c (location_foreach_backend): Update to use BackendNote - (do_rollback): Don't do rollback if the doc is NULL - (location_store_xml): Return if this location does not contain the - backend specified - (location_store_xml): Use fprintf rather than g_warning - (subtract_xml_node): - (merge_xml_nodes): Update child node while iterating - - * config-log.c (config_log_get_rollback_ids_for_date): Remove - - * location.c (location_set_arg): ref inherited object - - * main.c (main): Don't check if the location is default; don't - create default location if non-existant - (main): Signal error if the user is adding a location and did not - specify a name - (main): Use fprintf to signal the error that a location could not - be opened - (main): Signal error and exit when archive cannot be opened, - rather than using g_error - (do_add_location): Check for NULL location_id - (do_add_location): Create default location if it does not exist - and it is specified as the parent - - * archive.c (archive_get_current_location_id): Create the default - location if it does not exist - - * backend-list.c (backend_list_contains): Use strcmp and iterate - through the list - - * location.c (location_contains): Read whether the backend is in - the master list if this location is toplevel - -2001-02-18 Bradford Hovinen <hovinen@ximian.com> - - * main.c (do_add_backend): Support ContainmentType specification - (do_store): Support StoreType specification - (struct store_options): Add set of options to support - compare_parent, mask_previous, options - (struct add_remove_backend_options): Add option for partial - containment when adding backend - - * location.c (subtract_xml_node): - (merge_xml_nodes): - (compare_xml_nodes): - (merge_xml_docs): - (subtract_xml_doc): Implement. XML node compare/merging operations - (location_store): Rewrite to call location_store_xml - (location_store_xml): Include support for diffing with - configuration data from parent config - (location_dump_rollback_data): Rewrite to use - location_load_rollback_data - (dump_xml_data): Remove - (do_rollback): Rewrite to use xmlDocDump; pass xmlDocPtr rather - than id number - (location_rollback_id): Add node merging support - (location_rollback_backend_by): - (location_rollback_backend_to): Rewrite to use - location_load_rollback_data - (location_rollback_backends_to): Rewrite to iterate through - backend list and call location_rollback_backend_to for each - element - (location_rollback_all_to): Ditto - -2001-02-14 Bradford Hovinen <hovinen@ximian.com> - - * location.h (_ContainmentType): Introduce. Specifies the type of - containment (full, partial, none), of a backend in a location - - * location.c: Added struct BackendNote; have backend list include - type of containment as well as backend id - (location_contains): Use find_note - (find_note): Implement. Finds a note for the given backend id in - the backend list - (backend_note_new): - (backend_note_destroy): Implement. Convenience functions for - creating and destroying backend notes - (load_metadata_file): - (write_metadata_file): Read/write type of backend containment - (full or partial) - (location_add_backend): Pass parameter telling whether containment - is partial - -2001-01-25 Bradford Hovinen <hovinen@ximian.com> - - * config-log.c (get_current_date): Use local time rather than - Greenwich Mean Time - - * location.c (location_store_xml): Implement; copy from - location_store - (location_store): Free filename after use - - * archive.c (archive_load): Free prefix only if not global - - * location.c (location_rollback_all_to): Increment array - - * util.c (parse_date): Normalize values - -2001-01-24 Bradford Hovinen <hovinen@ximian.com> - - * config-log.c (do_load): Disabled locking for now - - * archiver-spec: Added fine-grained location management description - -2001-01-15 Bradford Hovinen <hovinen@ximian.com> - - * Makefile.am: Added rule for ximian_archiverConf.sh; add - installation target for Conf.sh - -2001-01-13 Bradford Hovinen <hovinen@ximian.com> - - * Makefile.am: Replaced occurrences of helix with ximian - Removed references to ximian_config_manager - -2000-12-22 Bradford Hovinen <hovinen@helixcode.com> - - * archive.c (foreach_cb): - (archive_foreach_child_location): Use auxillary structure to pass - data to traversal callback - (archive_get_location): - (archive_register_location): strdup() location ids - (free_location_cb): free() key - -2000-12-20 Bradford Hovinen <hovinen@helixcode.com> - - * location.c (location_get_parent): Implement - - * archive.c (load_all_locations): Implement - (foreach_cb): - (archive_foreach_child_location): Implement - -2000-12-19 Bradford Hovinen <hovinen@helixcode.com> - - * Makefile.am (bin_PROGRAMS): Changed name of archiver to - helix-archiver - (lib_LIBRARIES): Added libhelix_archiver.a - (helix_archiver_SOURCES): Moved archiver core to - libhelix_archiver_a_SOURCES - (helix_archiver_LDADD): Added libhelix_archiver.a - (INCLUDES): Changed XML_CFLAGS to GNOME_XML_CFLAGS - (include_HEADERS): Create and include headers for - libhelix_archiver.a - (includedir): Set includedire to include/helix-archiver - -2000-12-18 Bradford Hovinen <hovinen@helixcode.com> - - * main.c (do_rollback): Support rolling back by steps - - * location.c (location_rollback_backend_by): Implement - (location_dump_rollback_data): Support passing steps as well as - date - - * config-log.c (config_log_get_rollback_id_by_steps): Implement - - * location.c (write_metadata_file): Don't support writing out the - master list any more - (save_metadata): Ditto - (load_metadata_file): Get backends list from BackendList object - (rather than finding it out oneself) if location is toplevel - (do_create): Ditto - (get_backends_cb): Implement - (location_add_backend): Add return values for error conditions - -2000-10-15 Bradford Hovinen <hovinen@helixcode.com> - - * location.c (location_rollback_backends_to): Free id_array when done - - * config-log.c (config_log_reset_filenames): Implement - - * archive.c (archive_set_current_location_id): Move gnome_config_ - code from set_current_location - - * location.c (location_set_id): Implement - - * main.c (do_rename_location): Implement - - * archive.c (free_location_cb): Don't free locid - (archive_get_location): - (archive_register_location): Don't strdup the location id - (archive_set_current_location_id): Implement - - * main.c: Add options for renaming locations and specifying that - backends should be added to or removed from the master list - - * location.c (run_backend_proc): Close all descriptors other than - 0, 1, 2 - (location_set_id): Implement - (location_set_arg): Free previous locid if exists - - * archive.c (add_location_cb): Implement - (archive_set_current_location): Add location change algorithm - - * location.c (location_find_path_from_common_parent): Implement - (location_foreach_backend): Implement - - * archive.c (archive_set_current_location): Set - archive->current_location_id - - * main.c (do_add_location): Check parent_str for NULL before - loading location - (do_change_location): Implement - (main): Support changing location - - * archive.c (archive_register_location): Implement - - * location.c (do_create): - (do_load): Use archive_get_prefix - (do_create): Load global location metadata if this location does - not inherit from anything - (location_get_id): Implement - - * archive.c (archive_get_prefix): Implement - - * location.c (location_get_path): Implement - (load_metadata_file): Use archive_is_global - (location_set_arg): Set label when setting locid - - * location.[ch]: Make all data members private - - * main.c (main): Get current location name properly, create - location iff location id is "default"; bail out with error otherwise - (do_remove_location): - (do_add_location): Implement - - * config-log.c: Include ctype.h to fix implicit declarations - - * location.c (location_rollback_backends_to): Property initialize i - (location_contains): Fix precondition checks - (do_create): Remove unused variables - - * archive.c (archive_get_location): Make a copy of locid before - working with it - (do_load): Fix precondition checks - - * location.c (location_open): - (location_new): Make locid const - - * archive.c (archive_get_location): Make locid const - - * location.c (data_delete_cb): - (location_delete): Implement - - * config-log.c (config_log_iterate): Implement - (config_log_destroy): Make private, pass GtkObject - (config_log_delete): Implement - -2000-10-14 Bradford Hovinen <hovinen@helixcode.com> - - * location.c (location_close): Add precondition checks - - * archive.c (archive_destroy): Make private; pass GtkObject - - * location.c (location_add_backend): - (location_remove_backend): Add precondition checks - (location_destroy): Make private - (location_destroy): Pass GtkObject pointer rather than Location - pointer; this cleans up assignment in _class_init - - * archive.c (archive_get_current_location_id): Implement - (archive_get_current_location): Implement - -2000-09-03 Bradford Hovinen <hovinen@helixcode.com> - - * location.c (location_new): Set is_new - (save_metadata): Don't write file unless necessary - (save_metadata): - (write_metadata_file): Split out file writing into - write_metadata_file; write default data file as necessary - (location_add_backend): - (location_remove_backend): Implement - - * main.c: Add command line arguments for adding/removing locations - and backends; move backend id argument into global options - - * location.c (do_load): - (load_metadata_file): Split out file parsing logic into - load_metadata_file; call load_metadata_file on default file to get - contains list if current location doesn't inherit anything - (load_metadata_file): g_strdup backend string - (load_metadata_file): Warn if top-level location has contains clauses - (location_store): Check if the location contains the given backend - and try the location it inherits if it doesn't - - * archive.c (archive_load): Set is_global in archive object - - * Makefile.am (Locationmeta{dir|_DATA}): Added commands to install - data files - (INCLUDES): Added define for LOCATION_DIR - -2000-09-03 Bradford Hovinen <hovinen@helixcode.com> - - * location.c (save_metadata): Write attributes when saving - diff --git a/archiver/Makefile.am b/archiver/Makefile.am deleted file mode 100644 index bf35ee478..000000000 --- a/archiver/Makefile.am +++ /dev/null @@ -1,99 +0,0 @@ -confexecdir = $(libdir) -confexec_DATA = config_archiverConf.sh - -Locationmetadir = $(datadir)/control-center/archiver -Locationmeta_DATA = default-user.xml default-global.xml - -includedir = $(prefix)/include/config-archiver - -INCLUDES = \ - -DGNOMELOCALEDIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \ - -I$(includedir) \ - $(GNOME_INCLUDEDIR) \ - -DVERSION=\""$(VERSION)"\" \ - -DG_LOG_DOMAIN=\"libconfig-archiver\" \ - -DCONFIGDIR=\""/etc"\" \ - -DLOCATION_DIR=\""$(datadir)/control-center/archiver"\" \ - -DGLADE_DIR=\""$(INTERFACES_DIR)"\" \ - -DXST_BACKEND_LOCATION=\""$(datadir)/setup-tool-backends/scripts"\" \ - @ARCHIVER_CFLAGS@ \ - @MONIKER_CFLAGS@ - -CORBA_SOURCE = \ - ConfigArchiver.h \ - ConfigArchiver-common.c \ - ConfigArchiver-stubs.c \ - ConfigArchiver-skels.c - -idl_flags = `gnome-config --cflags idl` - -$(CORBA_SOURCE): $(top_srcdir)/idl/ConfigArchiver.idl - orbit-idl $(top_srcdir)/idl/ConfigArchiver.idl -I$(top_srcdir)/idl $(idl_flags) - -bin_PROGRAMS = bonobo-moniker-archiver config-archiver - -lib_LTLIBRARIES = libconfig_archiver.la - -libconfig_archiver_la_SOURCES = \ - util.c util.h \ - archiver-client.c \ - $(CORBA_SOURCE) - -libconfig_archiver_la_LIBADD = \ - @GNOME_XML_LIBS@ - -archiver-client.c: $(CORBA_SOURCE) - -include_HEADERS = \ - ConfigArchiver.h \ - archiver-client.h - -config_archiver_SOURCES = \ - config-archiver.c - -config_archiver_LDADD = \ - @ARCHIVER_LIBS@ \ - libconfig_archiver.la - -# -# Create the config_archiverConf.sh file from the sh.in file -# -config_archiverConf.sh: config_archiverConf.sh.in Makefile - sed -e 's?\@VERSION\@?$(VERSION)?' \ - -e 's?\@CONFIG_ARCHIVER_LIBDIR\@?$(CONFIG_ARCHIVER_LIBDIR)?g' \ - -e 's?\@CONFIG_ARCHIVER_LIBS\@?$(CONFIG_ARCHIVER_LIBS)?g' \ - -e 's?\@CONFIG_ARCHIVER_INCLUDEDIR\@?$(CONFIG_ARCHIVER_INCLUDEDIR)?g' \ - < $(srcdir)/config_archiverConf.sh.in > config_archiverConf.tmp \ - && mv config_archiverConf.tmp config_archiverConf.sh - -OAF_FILES = \ - Bonobo_Moniker_archiver.oaf - -oafdir = $(datadir)/oaf -oaf_DATA = $(OAF_FILES) - -monikerdir = $(libdir)/bonobo/monikers - -Bonobo_Moniker_archiver.oaf : $(srcdir)/Bonobo_Moniker_archiver.oaf.in $(top_builddir)/config.status - sed -e "s|\@MONIKER_LIBDIR\@|$(monikerdir)|" \ - $(srcdir)/Bonobo_Moniker_archiver.oaf.in > Bonobo_Moniker_archiver.oaf - -clean-local: - -rm -f $(OAF_FILES) $(CORBA_SOURCE) - -bonobo_moniker_archiver_SOURCES = \ - bonobo-config-archiver.c bonobo-config-archiver.h \ - archive.c archive.h \ - location.c location.h \ - config-log.c config-log.h \ - backend-list.c backend-list.h \ - cluster.c cluster.h \ - cluster-location.c cluster-location.h \ - bonobo-moniker-archiver.c - -bonobo_moniker_archiver_LDADD = @MONIKER_LIBS@ libconfig_archiver.la - -EXTRA_DIST = \ - $(Locationmeta_DATA) \ - config_archiverConf.sh.in \ - Bonobo_Moniker_archiver.oaf.in diff --git a/archiver/README b/archiver/README deleted file mode 100644 index 6c3e08d8a..000000000 --- a/archiver/README +++ /dev/null @@ -1,2 +0,0 @@ -This module is no longer built as a part of control-center. - diff --git a/archiver/TODO b/archiver/TODO deleted file mode 100644 index 628df031b..000000000 --- a/archiver/TODO +++ /dev/null @@ -1,40 +0,0 @@ - * Add per-user master list - * Archiving changes in location metadata - * Fix race in lock handling and add timeout support (look in gnome-mime) - * Support multiple backends from CLI - * Add translateable backend description support - * Some way to store the rollback time for each backend, for GUI purposes - * Have defaults stored somewhere, to be restored when the user goes - back before the first configuration edit - -Long-term - * Add clustering support: - - Add Cluster class inheriting Archive class and overriding path - semantics - - Change location rollback functionality to send data through to - clients if the archive is a cluster - * Allow backend specs to identify an order in which they should be applied - - Specify this in the master list; have each location look up that - information before invoking multiple backends - -Questions - -Done - * Global list of configs for a given archive - * Location should store backend data in the location where it is valid - * Add support for dumping XML to stdout rather than running the backend - * Fix bug where EOF not sent through pipe - * Changing the name of a location - * Adding per-user/global backends - - Don't try to write out contains list on toplevel locations - - Give error if the user tries to add a backend to a toplevel location - * Consistency check on adding and removing backends - - Make sure the backend is included in the global metadata list before - adding - - When removing global and per-user backends, mark the backend - "invalid" and exclude from location_foreach_backend, - location_rollback_all_to, and location_contains. - * Refactor master list into an attribute of Archive - * Roll back x number of steps rather than by date - * Try to factor out populate_locations_list to be common between the - different dialogs diff --git a/archiver/archive.c b/archiver/archive.c deleted file mode 100644 index 6b01e3d65..000000000 --- a/archiver/archive.c +++ /dev/null @@ -1,781 +0,0 @@ -/* -*- mode: c; style: linux -*- */ - -/* archive.c - * Copyright (C) 2000-2001 Ximian, Inc. - * - * Written by Bradford Hovinen (hovinen@ximian.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <sys/stat.h> -#include <sys/types.h> -#include <fcntl.h> -#include <unistd.h> -#include <dirent.h> -#include <errno.h> - -#include "archive.h" -#include "util.h" - -static GtkObjectClass *parent_class; - -enum { - ARG_0, - ARG_PREFIX, - ARG_IS_GLOBAL -}; - -#define ARCHIVE_FROM_SERVANT(servant) (ARCHIVE (bonobo_object_from_servant (servant))) - -static void archive_init (Archive *archive); -static void archive_class_init (ArchiveClass *klass); - -static void archive_destroy (GtkObject *object); - -static void archive_set_arg (GtkObject *object, - GtkArg *arg, - guint arg_id); - -static void archive_get_arg (GtkObject *object, - GtkArg *arg, - guint arg_id); - -static void load_all_locations (Archive *archive); - -/* CORBA interface methods */ - -static ConfigArchiver_Location -impl_ConfigArchiver_Archive_getLocation (PortableServer_Servant servant, - const CORBA_char *locid, - CORBA_Environment *ev) -{ - Location *loc; - - loc = archive_get_location (ARCHIVE_FROM_SERVANT (servant), locid); - - if (loc == NULL) { - bonobo_exception_set (ev, ex_ConfigArchiver_Archive_LocationNotFound); - return CORBA_OBJECT_NIL; - } else { - return CORBA_Object_duplicate (BONOBO_OBJREF (loc), ev); - } -} - -static ConfigArchiver_Location -impl_ConfigArchiver_Archive_createLocation (PortableServer_Servant servant, - const CORBA_char *locid, - const CORBA_char *label, - const ConfigArchiver_Location parent_ref, - CORBA_Environment *ev) -{ - Location *loc; - - loc = archive_create_location (ARCHIVE_FROM_SERVANT (servant), locid, label, - LOCATION (bonobo_object_from_servant (parent_ref->servant))); - - return CORBA_Object_duplicate (BONOBO_OBJREF (loc), ev); -} - -static ConfigArchiver_LocationSeq * -impl_ConfigArchiver_Archive_getChildLocations (PortableServer_Servant servant, - ConfigArchiver_Location location_ref, - CORBA_Environment *ev) -{ - ConfigArchiver_LocationSeq *ret; - Archive *archive; - Location *location; - GList *locs, *tmp; - guint i = 0; - - archive = ARCHIVE_FROM_SERVANT (servant); - - if (location_ref == CORBA_OBJECT_NIL) - location = NULL; - else - location = LOCATION (bonobo_object_from_servant (location_ref->servant)); - - locs = archive_get_child_locations (archive, location); - - ret = ConfigArchiver_LocationSeq__alloc (); - ret->_length = g_list_length (locs); - ret->_buffer = CORBA_sequence_ConfigArchiver_Location_allocbuf (ret->_length); - - for (tmp = locs; tmp != NULL; tmp = tmp->next) - ret->_buffer[i++] = CORBA_Object_duplicate (BONOBO_OBJREF (tmp->data), ev); - - g_list_free (locs); - return ret; -} - -static CORBA_char * -impl_ConfigArchiver_Archive__get_prefix (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - return CORBA_string_dup (ARCHIVE_FROM_SERVANT (servant)->prefix); -} - -static CORBA_boolean -impl_ConfigArchiver_Archive__get_isGlobal (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - return ARCHIVE_FROM_SERVANT (servant)->is_global; -} - -static ConfigArchiver_BackendList -impl_ConfigArchiver_Archive__get_backendList (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - return bonobo_object_dup_ref (BONOBO_OBJREF (ARCHIVE_FROM_SERVANT (servant)->backend_list), ev); -} - -static ConfigArchiver_Location -impl_ConfigArchiver_Archive__get_currentLocation (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - return CORBA_Object_duplicate (BONOBO_OBJREF (archive_get_current_location (ARCHIVE_FROM_SERVANT (servant))), ev); -} - -static void -impl_ConfigArchiver_Archive__set_currentLocation (PortableServer_Servant servant, - ConfigArchiver_Location location_ref, - CORBA_Environment *ev) -{ - Archive *archive = ARCHIVE_FROM_SERVANT (servant); - Location *location; - - location = LOCATION (bonobo_object_from_servant (location_ref->servant)); - - if (location == NULL) - bonobo_exception_set (ev, ex_ConfigArchiver_Archive_LocationNotFound); - else - archive_set_current_location (archive, location); -} - -static void -impl_ConfigArchiver_Archive__set_currentLocationId (PortableServer_Servant servant, - const CORBA_char *locid, - CORBA_Environment *ev) -{ - archive_set_current_location_id (ARCHIVE_FROM_SERVANT (servant), locid); -} - -CORBA_char * -impl_ConfigArchiver_Archive__get_currentLocationId (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - return CORBA_string_dup (archive_get_current_location_id (ARCHIVE_FROM_SERVANT (servant))); -} - -BONOBO_X_TYPE_FUNC_FULL (Archive, ConfigArchiver_Archive, BONOBO_X_OBJECT_TYPE, archive); - -static void -archive_init (Archive *archive) -{ - archive->prefix = NULL; - archive->locations = g_tree_new ((GCompareFunc) strcmp); - archive->current_location_id = NULL; -} - -static void -archive_class_init (ArchiveClass *klass) -{ - GtkObjectClass *object_class; - - object_class = GTK_OBJECT_CLASS (klass); - - object_class->destroy = archive_destroy; - object_class->set_arg = archive_set_arg; - object_class->get_arg = archive_get_arg; - - gtk_object_add_arg_type ("Archive::prefix", - GTK_TYPE_POINTER, - GTK_ARG_READWRITE | GTK_ARG_CONSTRUCT_ONLY, - ARG_PREFIX); - gtk_object_add_arg_type ("Archive::is-global", - GTK_TYPE_INT, - GTK_ARG_READWRITE | GTK_ARG_CONSTRUCT_ONLY, - ARG_IS_GLOBAL); - - klass->epv.getLocation = impl_ConfigArchiver_Archive_getLocation; - klass->epv.createLocation = impl_ConfigArchiver_Archive_createLocation; - klass->epv.getChildLocations = impl_ConfigArchiver_Archive_getChildLocations; - - klass->epv._get_prefix = impl_ConfigArchiver_Archive__get_prefix; - klass->epv._get_isGlobal = impl_ConfigArchiver_Archive__get_isGlobal; - klass->epv._get_backendList = impl_ConfigArchiver_Archive__get_backendList; - klass->epv._get_currentLocation = impl_ConfigArchiver_Archive__get_currentLocation; - klass->epv._get_currentLocationId = impl_ConfigArchiver_Archive__get_currentLocationId; - - klass->epv._set_currentLocation = impl_ConfigArchiver_Archive__set_currentLocation; - klass->epv._set_currentLocationId = impl_ConfigArchiver_Archive__set_currentLocationId; - - parent_class = gtk_type_class (BONOBO_X_OBJECT_TYPE); -} - -static void -archive_set_arg (GtkObject *object, GtkArg *arg, guint arg_id) -{ - Archive *archive; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_ARCHIVE (object)); - g_return_if_fail (arg != NULL); - - archive = ARCHIVE (object); - - switch (arg_id) { - case ARG_PREFIX: - if (GTK_VALUE_POINTER (*arg) != NULL) - archive->prefix = g_strdup (GTK_VALUE_POINTER (*arg)); - break; - - case ARG_IS_GLOBAL: - archive->is_global = GTK_VALUE_INT (*arg); - archive->backend_list = - BACKEND_LIST (backend_list_new (archive->is_global)); - break; - - default: - break; - } -} - -static void -archive_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) -{ - Archive *archive; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_ARCHIVE (object)); - g_return_if_fail (arg != NULL); - - archive = ARCHIVE (object); - - switch (arg_id) { - case ARG_PREFIX: - GTK_VALUE_POINTER (*arg) = archive->prefix; - break; - - case ARG_IS_GLOBAL: - GTK_VALUE_INT (*arg) = archive->is_global; - break; - - default: - arg->type = GTK_TYPE_INVALID; - break; - } -} - -/** - * archive_construct: - * @archive: - * @is_new: TRUE iff this is a new archive - * - * Load the archive information from disk - * - * Returns: TRUE on success and FALSE on failure - */ - -gboolean -archive_construct (Archive *archive, gboolean is_new) -{ - gint ret = 0; - - g_return_val_if_fail (archive != NULL, FALSE); - g_return_val_if_fail (IS_ARCHIVE (archive), FALSE); - g_return_val_if_fail (archive->prefix != NULL, FALSE); - - if (is_new) { - if (g_file_exists (archive->prefix)) - return FALSE; - - ret = mkdir (archive->prefix, S_IREAD | S_IWRITE | S_IEXEC); - if (ret == -1) return FALSE; - } else { - if (!g_file_test (archive->prefix, G_FILE_TEST_ISDIR)) - return FALSE; - } - - return TRUE; -} - -/** - * archive_load: - * @is_global: TRUE iff we should load the global archive - * - * Load either the global or per-user configuration archive - * - * Return value: Reference to archive - **/ - -BonoboObject * -archive_load (gboolean is_global) -{ - BonoboObject *object; - gchar *prefix; - - if (is_global) - prefix = "/var/ximian-setup-tools"; - else - prefix = g_concat_dir_and_file (g_get_home_dir (), - ".gnome/capplet-archive"); - - object = BONOBO_OBJECT (gtk_object_new (archive_get_type (), - "prefix", prefix, - "is-global", is_global, - NULL)); - - if (!is_global) - g_free (prefix); - - if (archive_construct (ARCHIVE (object), FALSE) == FALSE && - archive_construct (ARCHIVE (object), TRUE) == FALSE) - { - bonobo_object_unref (object); - return NULL; - } - - return object; -} - -static gint -free_location_cb (gchar *locid, BonoboObject *location) -{ - bonobo_object_unref (location); - g_free (locid); - - return FALSE; -} - -static void -archive_destroy (GtkObject *object) -{ - Archive *archive; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_ARCHIVE (object)); - - DEBUG_MSG ("Enter"); - - archive = ARCHIVE (object); - - g_tree_traverse (archive->locations, - (GTraverseFunc) free_location_cb, - G_IN_ORDER, - NULL); - - g_tree_destroy (archive->locations); - - if (archive->current_location_id != NULL) - g_free (archive->current_location_id); - - if (archive->backend_list != NULL) - bonobo_object_unref (BONOBO_OBJECT (archive->backend_list)); - - GTK_OBJECT_CLASS (parent_class)->destroy (GTK_OBJECT (archive)); -} - -/** - * archive_get_location: - * @locid: - * - * Get a reference to the location with the given name. - * - * Return value: Reference to location, NULL if no such location exists - **/ - -Location * -archive_get_location (Archive *archive, - const gchar *locid) -{ - BonoboObject *loc_obj; - gchar *tmp; - - g_return_val_if_fail (archive != NULL, NULL); - g_return_val_if_fail (IS_ARCHIVE (archive), NULL); - g_return_val_if_fail (locid != NULL, NULL); - - /* Stupid borken glib... */ - tmp = g_strdup (locid); - loc_obj = g_tree_lookup (archive->locations, tmp); - g_free (tmp); - - if (loc_obj == NULL) { - loc_obj = location_open (archive, locid); - - if (loc_obj == NULL) - return NULL; - else - g_tree_insert (archive->locations, - g_strdup (locid), loc_obj); - } else { - bonobo_object_ref (loc_obj); - } - - return LOCATION (loc_obj); -} - -/** - * archive_create_location: - * @archive: - * @location: - * - * Creates a new location - */ - -Location * -archive_create_location (Archive *archive, - const gchar *locid, - const gchar *label, - Location *parent) -{ - Location *location; - - g_return_val_if_fail (archive != NULL, NULL); - g_return_val_if_fail (IS_ARCHIVE (archive), NULL); - g_return_val_if_fail (locid != NULL, NULL); - g_return_val_if_fail (label != NULL, NULL); - g_return_val_if_fail (parent == NULL || IS_LOCATION (parent), NULL); - - location = LOCATION (location_new (archive, locid, label, parent)); - - if (location == NULL) - return NULL; - - g_tree_insert (archive->locations, g_strdup (locid), location); - return location; -} - -/** - * archive_unregister_location: - * @archive: - * @location: - * - * Unregisters a location from the archive - **/ - -void -archive_unregister_location (Archive *archive, Location *location) -{ - gchar *tmp; - - g_return_if_fail (archive != NULL); - g_return_if_fail (IS_ARCHIVE (archive)); - g_return_if_fail (location != NULL); - g_return_if_fail (IS_LOCATION (location)); - - if (GTK_OBJECT_DESTROYED (archive)) return; - - tmp = g_strdup (location_get_id (location)); - g_tree_remove (archive->locations, tmp); - g_free (tmp); -} - -/** - * archive_get_current_location: - * - * Convenience function to get a pointer to the current location - * - * Return value: Pointer to current location, or NULL if the current location - * does not exist and a default location could not be created - **/ - -Location * -archive_get_current_location (Archive *archive) -{ - const gchar *locid; - - g_return_val_if_fail (archive != NULL, NULL); - g_return_val_if_fail (IS_ARCHIVE (archive), NULL); - - locid = archive_get_current_location_id (archive); - - if (locid == NULL) - return NULL; - else - return archive_get_location (archive, locid); -} - -/** - * archive_set_current_location: - * @location: Location to which to set archive - * - * Set the current location in an archive to the location given; apply - * configuration for the new location to all backends necessary - **/ - -void -archive_set_current_location (Archive *archive, - Location *location) -{ - Location *old_location; - GList *backends; - - g_return_if_fail (archive != NULL); - g_return_if_fail (IS_ARCHIVE (archive)); - g_return_if_fail (location != NULL); - g_return_if_fail (IS_LOCATION (location)); - - old_location = archive_get_current_location (archive); - - archive_set_current_location_id (archive, location_get_id (location)); - - backends = location_get_changed_backends (location, old_location); - location_rollback_backends_to (location, NULL, 0, backends, TRUE); -} - -/** - * archive_set_current_location_id: - * @name: - * - * Sets the current location's name, but does not invoke any rollback - **/ - -void -archive_set_current_location_id (Archive *archive, - const gchar *locid) -{ - g_return_if_fail (archive != NULL); - g_return_if_fail (IS_ARCHIVE (archive)); - g_return_if_fail (locid != NULL); - - if (archive->current_location_id != NULL) - g_free (archive->current_location_id); - - archive->current_location_id = g_strdup (locid); - - if (archive->is_global) - gnome_config_set_string - ("/ximian-setup-tools/config/current/global-location", - archive->current_location_id); - else - gnome_config_set_string - ("/capplet-archive/config/current/location", - archive->current_location_id); - - gnome_config_sync (); -} - -/** - * archive_get_current_location_id: - * - * Get the name of the current location - * - * Return value: String containing current location, should not be freed, or - * NULL if no current location exists and the default location could not be - * created - **/ - -const gchar * -archive_get_current_location_id (Archive *archive) -{ - gboolean def; - Location *loc; - Location *current_location; - - g_return_val_if_fail (archive != NULL, NULL); - g_return_val_if_fail (IS_ARCHIVE (archive), NULL); - - if (archive->current_location_id == NULL) { - if (archive->is_global) - archive->current_location_id = - gnome_config_get_string_with_default - ("/ximian-setup-tools/config/current/global-location=default", &def); - else - archive->current_location_id = - gnome_config_get_string_with_default - ("/capplet-archive/config/current/location=default", &def); - - /* Create default location if it does not exist */ - if (def) { - current_location = - archive_get_location (archive, archive->current_location_id); - - if (current_location == NULL) { - loc = archive_create_location (archive, archive->current_location_id, - _("Default location"), NULL); - if (archive->is_global && - location_store_full_snapshot (loc) < 0) - { - location_delete (loc); - return NULL; - } - - bonobo_object_unref (BONOBO_OBJECT (loc)); - } else { - bonobo_object_unref (BONOBO_OBJECT (current_location)); - } - } - } - - return archive->current_location_id; -} - -/** - * archive_get_prefix: - * @archive: - * - * Get the prefix for locations in this archive - * - * Return value: String containing prefix; should not be freed - **/ - -const gchar * -archive_get_prefix (Archive *archive) -{ - g_return_val_if_fail (archive != NULL, FALSE); - g_return_val_if_fail (IS_ARCHIVE (archive), FALSE); - - return archive->prefix; -} - -/** - * archive_is_global: - * @archive: - * - * Tell whether the archive is global or per-user - * - * Return value: TRUE if global, FALSE if per-user - **/ - -gboolean -archive_is_global (Archive *archive) -{ - g_return_val_if_fail (archive != NULL, FALSE); - g_return_val_if_fail (IS_ARCHIVE (archive), FALSE); - - return archive->is_global; -} - -/** - * archive_get_backend_list: - * @archive: - * - * Get the master backend list for this archive - * - * Return value: Reference to the master backend list - **/ - -BackendList * -archive_get_backend_list (Archive *archive) -{ - g_return_val_if_fail (archive != NULL, FALSE); - g_return_val_if_fail (IS_ARCHIVE (archive), FALSE); - - return archive->backend_list; -} - -/** - * archive_foreach_child_location: - * @archive: - * @callback: Callback to invoke - * @parent: Iterate through the children of this location; iterate through - * toplevel locations if this is NULL - * @data: Arbitrary data to pass to the callback - * - * Invoke the given callback for each location that inherits the given - * location, or for each toplevel location if the parent given is - * NULL. Terminate the iteration if any child returns a nonzero value - **/ - -static gint -foreach_build_list_cb (gchar *key, Location *value, GList **node) -{ - if (!location_is_deleted (value)) - *node = g_list_prepend (*node, value); - - return 0; -} - -GList * -archive_get_child_locations (Archive *archive, - Location *parent) -{ - GList *list = NULL, *node, *tmp; - Location *loc; - - g_return_val_if_fail (archive != NULL, NULL); - g_return_val_if_fail (IS_ARCHIVE (archive), NULL); - - load_all_locations (archive); - - g_tree_traverse (archive->locations, - (GTraverseFunc) foreach_build_list_cb, - G_IN_ORDER, - &list); - - node = list; - - while (node != NULL) { - loc = node->data; - tmp = node->next; - - if (location_get_parent (loc) != parent) { - list = g_list_remove_link (list, node); - g_list_free_1 (node); - bonobo_object_unref (BONOBO_OBJECT (loc)); - } - - node = tmp; - } - - return list; -} - -/* Load and register all the locations for this archive */ - -static void -load_all_locations (Archive *archive) -{ - DIR *archive_dir; - struct dirent entry, *entryp; - gchar *filename; - Location *location; - - archive_dir = opendir (archive->prefix); - - if (archive_dir == NULL) { - g_warning ("load_all_locations: %s", g_strerror (errno)); - return; - } - - while (1) { - if (readdir_r (archive_dir, &entry, &entryp)) { - g_warning ("load_all_locations: %s", - g_strerror (errno)); - break; - } - - if (entryp == NULL) break; - - if (strcmp (entry.d_name, ".") && - strcmp (entry.d_name, "..")) - { - filename = g_concat_dir_and_file (archive->prefix, - entry.d_name); - if (g_file_test (filename, G_FILE_TEST_ISDIR)) { - location = archive_get_location (archive, entry.d_name); - if (location_is_deleted (location)) - bonobo_object_unref (BONOBO_OBJECT (location)); - } - } - } -} diff --git a/archiver/archive.h b/archiver/archive.h deleted file mode 100644 index c446285a8..000000000 --- a/archiver/archive.h +++ /dev/null @@ -1,94 +0,0 @@ -/* -*- mode: c; style: linux -*- */ - -/* archive.h - * Copyright (C) 2000-2001 Ximian, Inc. - * - * Written by Bradford Hovinen (hovinen@ximian.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#ifndef __ARCHIVE_H -#define __ARCHIVE_H - -#include <gnome.h> - -#include "ConfigArchiver.h" - -#include "location.h" -#include "backend-list.h" - -#define ARCHIVE(obj) GTK_CHECK_CAST (obj, archive_get_type (), Archive) -#define ARCHIVE_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, archive_get_type (), ArchiveClass) -#define IS_ARCHIVE(obj) GTK_CHECK_TYPE (obj, archive_get_type ()) - -typedef struct _ArchiveClass ArchiveClass; - -struct _Archive -{ - BonoboXObject object; - - gchar *prefix; - GTree *locations; - gboolean is_global; - - gchar *current_location_id; - - BackendList *backend_list; -}; - -struct _ArchiveClass -{ - BonoboXObjectClass parent; - - POA_ConfigArchiver_Archive__epv epv; -}; - -GType archive_get_type (void); - -gboolean archive_construct (Archive *archive, - gboolean is_new); - -BonoboObject *archive_load (gboolean is_global); - -void archive_close (Archive *archive); - -Location *archive_get_location (Archive *archive, - const gchar *locid); -Location *archive_create_location (Archive *archive, - const gchar *locid, - const gchar *label, - Location *parent); -void archive_unregister_location (Archive *archive, - Location *location); - -Location *archive_get_current_location (Archive *archive); -void archive_set_current_location (Archive *archive, - Location *location); - -const gchar *archive_get_current_location_id (Archive *archive); -void archive_set_current_location_id (Archive *archive, - const gchar *locid); - -const gchar *archive_get_prefix (Archive *archive); -gboolean archive_is_global (Archive *archive); - -BackendList *archive_get_backend_list (Archive *archive); - -GList *archive_get_child_locations (Archive *archive, - Location *parent); - -#endif /* __ARCHIVE */ diff --git a/archiver/archiver-client.c b/archiver/archiver-client.c deleted file mode 100644 index 9a0c8d32d..000000000 --- a/archiver/archiver-client.c +++ /dev/null @@ -1,442 +0,0 @@ -/* -*- mode: c; style: linux -*- */ - -/* archiver-client.c - * Copyright (C) 2000-2001 Ximian, Inc. - * - * Written by Bradford Hovinen (hovinen@ximian.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <libbonobo.h> -#include <gnome-xml/parser.h> - -#include "archiver-client.h" -#include "util.h" - -static void merge_xml_docs (xmlDocPtr child_doc, - xmlDocPtr parent_doc); -static void subtract_xml_doc (xmlDocPtr child_doc, - xmlDocPtr parent_doc, - gboolean strict); -static void merge_xml_nodes (xmlNodePtr node1, - xmlNodePtr node2); -static xmlNodePtr subtract_xml_node (xmlNodePtr node1, - xmlNodePtr node2, - gboolean strict); -static gboolean compare_xml_nodes (xmlNodePtr node1, xmlNodePtr node2); - -/** - * location_client_load_rollback_data - * @location: - * @date: - * @steps: - * @backend_id: - * @parent_chain: - * - * Loads the XML data for rolling back as specified and returns the document - * object - **/ - -xmlDocPtr -location_client_load_rollback_data (ConfigArchiver_Location location, - const struct tm *date, - guint steps, - const gchar *backend_id, - gboolean parent_chain, - CORBA_Environment *opt_ev) -{ - gchar *filename; - struct tm *date_c; - time_t time_g; - - xmlDocPtr doc = NULL; - xmlDocPtr parent_doc = NULL; - ConfigArchiver_ContainmentType type = ConfigArchiver_CONTAIN_FULL; - ConfigArchiver_Location parent = CORBA_OBJECT_NIL; - - CORBA_Environment my_ev; - - g_return_val_if_fail (location != CORBA_OBJECT_NIL, NULL); - - if (opt_ev == NULL) { - opt_ev = &my_ev; - CORBA_exception_init (opt_ev); - } - - if (date != NULL) { - date_c = dup_date (date); - time_g = mktime (date_c); -#ifdef __USE_BSD - time_g += date_c->tm_gmtoff; -#endif /* __USE_BSD */ - if (date_c->tm_isdst) time_g -= 3600; - g_free (date_c); - } else { - time_g = 0; - } - - filename = ConfigArchiver_Location_getRollbackFilename - (location, time_g, steps, backend_id, parent_chain, opt_ev); - - if (!BONOBO_EX (opt_ev) && filename != NULL) - DEBUG_MSG ("Loading rollback data: %s", filename); - - if (!BONOBO_EX (opt_ev) && filename != NULL) - doc = xmlParseFile (filename); - else if (parent_chain) - type = ConfigArchiver_Location_contains (location, backend_id, opt_ev); - - if (type == ConfigArchiver_CONTAIN_PARTIAL) - parent = ConfigArchiver_Location__get_parent (location, opt_ev); - - if (parent != CORBA_OBJECT_NIL) { - parent_doc = location_client_load_rollback_data - (parent, date, steps, backend_id, TRUE, opt_ev); - bonobo_object_release_unref (parent, NULL); - } - - if (doc != NULL && parent_doc != NULL) - merge_xml_docs (doc, parent_doc); - else if (parent_doc != NULL) - doc = parent_doc; - - if (opt_ev == &my_ev) - CORBA_exception_free (opt_ev); - - return doc; -} - -/** - * location_client_store_xml: - * @location: - * @backend_id: - * @input: - * @store_type: STORE_FULL means blindly store the data, without - * modification. STORE_COMPARE_PARENT means subtract the settings the parent - * has that are different and store the result. STORE_MASK_PREVIOUS means - * store only those settings that are reflected in the previous logged data; - * if there do not exist such data, act as in STORE_COMPARE_PARENT - * @opt_ev: - * - * Store configuration data from the given XML document object in the location - * under the given backend id - **/ - -void -location_client_store_xml (ConfigArchiver_Location location, - const gchar *backend_id, - xmlDocPtr xml_doc, - ConfigArchiver_StoreType store_type, - CORBA_Environment *opt_ev) -{ - xmlDocPtr parent_doc; - xmlDocPtr prev_doc = NULL; - char *filename; - ConfigArchiver_ContainmentType contain_type; - ConfigArchiver_Location parent; - CORBA_Environment my_ev; - - g_return_if_fail (location != CORBA_OBJECT_NIL); - g_return_if_fail (xml_doc != NULL); - - if (opt_ev == NULL) { - opt_ev = &my_ev; - CORBA_exception_init (opt_ev); - } - - contain_type = ConfigArchiver_Location_contains (location, backend_id, opt_ev); - parent = ConfigArchiver_Location__get_parent (location, opt_ev); - - if (contain_type == ConfigArchiver_CONTAIN_NONE) { - if (parent == CORBA_OBJECT_NIL) { - fprintf (stderr, "Could not find a location in the " \ - "tree ancestry that stores this " \ - "backend: %s.\n", backend_id); - } else { - location_client_store_xml (parent, backend_id, xml_doc, store_type, opt_ev); - bonobo_object_release_unref (parent, NULL); - } - - if (opt_ev == &my_ev) - CORBA_exception_free (opt_ev); - - return; - } - - if (contain_type == ConfigArchiver_CONTAIN_PARTIAL && store_type != ConfigArchiver_STORE_FULL && parent != CORBA_OBJECT_NIL) { - g_assert (store_type == ConfigArchiver_STORE_MASK_PREVIOUS || - store_type == ConfigArchiver_STORE_COMPARE_PARENT); - - parent_doc = location_client_load_rollback_data - (parent, NULL, 0, backend_id, TRUE, opt_ev); - - if (store_type == ConfigArchiver_STORE_MASK_PREVIOUS) - prev_doc = location_client_load_rollback_data (location, NULL, 0, backend_id, FALSE, opt_ev); - - if (store_type == ConfigArchiver_STORE_COMPARE_PARENT) { - subtract_xml_doc (xml_doc, parent_doc, FALSE); - } else { - subtract_xml_doc (parent_doc, prev_doc, FALSE); - subtract_xml_doc (xml_doc, parent_doc, TRUE); - } - - xmlFreeDoc (parent_doc); - - if (prev_doc != NULL) - xmlFreeDoc (prev_doc); - } - - if (parent != CORBA_OBJECT_NIL) - bonobo_object_release_unref (parent, NULL); - - filename = ConfigArchiver_Location_getStorageFilename - (location, backend_id, store_type == ConfigArchiver_STORE_DEFAULT, opt_ev); - - if (!BONOBO_EX (opt_ev) && filename != NULL) { - xmlSaveFile (filename, xml_doc); - ConfigArchiver_Location_storageComplete (location, filename, opt_ev); - CORBA_free (filename); - } - - if (opt_ev == &my_ev) - CORBA_exception_free (opt_ev); -} - -static void -merge_xml_docs (xmlDocPtr child_doc, xmlDocPtr parent_doc) -{ - merge_xml_nodes (xmlDocGetRootElement (child_doc), - xmlDocGetRootElement (parent_doc)); -} - -static void -subtract_xml_doc (xmlDocPtr child_doc, xmlDocPtr parent_doc, gboolean strict) -{ - subtract_xml_node (xmlDocGetRootElement (child_doc), - xmlDocGetRootElement (parent_doc), strict); -} - -/* Merge contents of node1 and node2, where node1 overrides node2 as - * appropriate - * - * Notes: Two XML nodes are considered to be "the same" iff their names and - * all names and values of their attributes are the same. If that is not the - * case, they are considered "different" and will both be present in the - * merged node. If nodes are "the same", then this algorithm is called - * recursively. If nodes are CDATA, then node1 overrides node2 and the - * resulting node is just node1. The node merging is order-independent; child - * node from one tree are compared with all child nodes of the other tree - * regardless of the order they appear in. Hence one may have documents with - * different node orderings and the algorithm should still run correctly. It - * will not, however, run correctly in cases when the agent using this - * facility depends on the nodes being in a particular order. - * - * This XML node merging/comparison facility requires that the following - * standard be set for DTDs: - * - * Attributes' sole purpose is to identify a node. For example, a network - * configuration DTD might have an element like <interface name="eth0"> with a - * bunch of child nodes to configure that interface. The attribute "name" does - * not specify the configuration for the interface. It differentiates the node - * from the configuration for, say, interface eth1. Conversely, a node must be - * completely identified by its attributes. One cannot include identification - * information in the node's children, since otherwise the merging and - * subtraction algorithms will not know what to look for. - * - * As a corollary to the above, all configuration information must ultimately - * be in text nodes. For example, a text string might be stored as - * <configuration-item>my-value</configuration-item> but never as - * <configuration-item value="my-value"/>. As an example, if the latter is - * used, a child location might override a parent's setting for - * configuration-item. This algorithm will interpret those as different nodes - * and include them both in the merged result, since it will not have any way - * of knowing that they are really the same node with different - * configuration. - */ - -static void -merge_xml_nodes (xmlNodePtr node1, xmlNodePtr node2) -{ - xmlNodePtr child, tmp, iref; - GList *node1_children = NULL, *i; - gboolean found; - - if (node1->type == XML_TEXT_NODE) - return; - - for (child = node1->childs; child != NULL; child = child->next) - node1_children = g_list_prepend (node1_children, child); - - node1_children = g_list_reverse (node1_children); - - child = node2->childs; - - while (child != NULL) { - tmp = child->next; - - i = node1_children; found = FALSE; - - while (i != NULL) { - iref = (xmlNodePtr) i->data; - - if (compare_xml_nodes (iref, child)) { - merge_xml_nodes (iref, child); - if (i == node1_children) - node1_children = node1_children->next; - g_list_remove_link (node1_children, i); - g_list_free_1 (i); - found = TRUE; - break; - } else { - i = i->next; - } - } - - if (found == FALSE) { - xmlUnlinkNode (child); - xmlAddChild (node1, child); - } - - child = tmp; - } - - g_list_free (node1_children); -} - -/* Modifies node1 so that it only contains the parts different from node2; - * returns the modified node or NULL if the node should be destroyed - * - * strict determines whether the settings themselves are compared; it should - * be set to FALSE when the trees are being compared for the purpose of - * seeing what settings should be included in a tree and TRUE when one wants - * to restrict the settings included in a tree to those that have already been - * specified - */ - -static xmlNodePtr -subtract_xml_node (xmlNodePtr node1, xmlNodePtr node2, gboolean strict) -{ - xmlNodePtr child, tmp, iref; - GList *node2_children = NULL, *i; - gboolean found, same, all_same = TRUE; - - if (node1->type == XML_TEXT_NODE) { - if (node2->type == XML_TEXT_NODE && - (strict || !strcmp (xmlNodeGetContent (node1), - xmlNodeGetContent (node2)))) - return NULL; - else - return node1; - } - - if (node1->childs == NULL && node2->childs == NULL) - return NULL; - - for (child = node2->childs; child != NULL; child = child->next) - node2_children = g_list_prepend (node2_children, child); - - node2_children = g_list_reverse (node2_children); - - child = node1->childs; - - while (child != NULL) { - tmp = child->next; - i = node2_children; found = FALSE; all_same = TRUE; - - while (i != NULL) { - iref = (xmlNodePtr) i->data; - - if (compare_xml_nodes (child, iref)) { - same = (subtract_xml_node - (child, iref, strict) == NULL); - all_same = all_same && same; - - if (same) { - xmlUnlinkNode (child); - xmlFreeNode (child); - } - - if (i == node2_children) - node2_children = node2_children->next; - g_list_remove_link (node2_children, i); - g_list_free_1 (i); - found = TRUE; - break; - } else { - i = i->next; - } - } - - if (!found) - all_same = FALSE; - - child = tmp; - } - - g_list_free (node2_children); - - if (all_same) - return NULL; - else - return node1; -} - -/* Return TRUE iff node1 and node2 are "the same" in the sense defined above */ - -static gboolean -compare_xml_nodes (xmlNodePtr node1, xmlNodePtr node2) -{ - xmlAttrPtr attr; - gint count = 0; - - if (strcmp (node1->name, node2->name)) - return FALSE; - - /* FIXME: This is worst case O(n^2), which can add up. Could we - * optimize for the case where people have attributes in the same - * order, or does not not matter? It probably does not matter, though, - * since people don't generally have more than one or two attributes - * in a tag anyway. - */ - - for (attr = node1->properties; attr != NULL; attr = attr->next) { - g_assert (xmlNodeIsText (attr->val)); - - if (strcmp (xmlNodeGetContent (attr->val), - xmlGetProp (node2, attr->name))) - return FALSE; - - count++; - } - - /* FIXME: Is checking if the two nodes have the same number of - * attributes the correct policy here? Should we instead merge the - * attribute(s) that node1 is missing? - */ - - for (attr = node2->properties; attr != NULL; attr = attr->next) - count--; - - if (count == 0) - return TRUE; - else - return FALSE; -} diff --git a/archiver/archiver-client.h b/archiver/archiver-client.h deleted file mode 100644 index 96dd287a0..000000000 --- a/archiver/archiver-client.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -*- mode: c; style: linux -*- */ - -/* archiver-client.h - * Copyright (C) 2001 Ximian, Inc. - * - * Written by Bradford Hovinen (hovinen@ximian.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#ifndef __ARCHIVER_CLIENT_H -#define __ARCHIVER_CLIENT_H - -#include <gnome.h> -#include <gnome-xml/tree.h> -#include <time.h> - -#include "ConfigArchiver.h" - -xmlDocPtr location_client_load_rollback_data (ConfigArchiver_Location location, - const struct tm *date, - guint steps, - const gchar *backend_id, - gboolean parent_chain, - CORBA_Environment *opt_ev); - -void location_client_store_xml (ConfigArchiver_Location location, - const gchar *backend_id, - xmlDocPtr xml_doc, - ConfigArchiver_StoreType store_type, - CORBA_Environment *opt_ev); - -#endif /* __ARCHIVER_CLIENT_H */ diff --git a/archiver/archiver-spec b/archiver/archiver-spec deleted file mode 100644 index 3c5f5f0c4..000000000 --- a/archiver/archiver-spec +++ /dev/null @@ -1,122 +0,0 @@ -Rollback archiving internals -Copyright (C) 2001 Ximian Code, Inc. -Written by Bradford Hovinen <hovinen@ximian.com> - -1. Directory format - -Diagram: - - + toplevel - |-+ Location 1 - | |- <id>.xml - | | . - | | . - | | . - | |- metadata.log: - | | [<id> <date> <time> <backend> ] ^ - | | [ . ] | Time - | | [ . ] | - | | [ . ] | - | \- metadata.xml: - | [... ] - | [<inherits>location</inherits> ] - | [<contains backend-id="backend" type="full|partial"/> ] - | [... ] - |-+ Location 2 - | ... - -There is one toplevel directory for each archive. This directory -contains one or more location directories. Each location directory -must contain two files: an XML file describing the location and a log -of changes made in that location. Each change corresponds to an XML -file containing a snapshot of the configuration as modified. There is -one XML file per backend. Each change has an id number that is -incremented atomicall by the archiving script when it stores -configuration changes. The id number, as well as the date and time of -storage, form a filename that uniquely identifies each configuration -change. The archiving script must also store in the log file a line -with the id number, date and time of storage, and backend used -whenever it stores XML data. New entries are stored at the head of the -file, so that during rollback, the file may be foreward scanned to -find the appropriate identifier for the configuration file. The -per-location XML configuration file contains information on what the -location's parent is and what configurations that location defines. - -For now, the backend shall be referred to by its executable name. When -the backends gain CORBA interfaces, I suggest that the OAF id be used -instead. This reduces the problem of setting a backend's configuration -to a simple object activation and method invocation. The OAF id may -also be used to resolve the backend's human-readable name. - -2. Meta-configuration details - -In order that this system be complete, there must be a way to -ascertain the current location and to roll back changes in location. I -propose that there be a special archive in the configuration hierarchy -that contains location history in the same format as other -locations. The archiver can then be a single script that accepts -command-line arguments describing the request action: `archive this -data', `roll back this backend's configuration', and `switch to this -location'. It then handles all the details of interfacing with the -archive and applying the changes in the correct order. Conceptually, -the archiver becomes a backend in and of itself, where the frontend is -located in the GUI of HCM. It would therefore be adviseable to use the -same standards for the archiver as for other backends and hence make -it a CORBA service, where the tool-specific interface is as described -above. - -3. Fine-grained location management - -A slight modification of the basic location management system allows -individual settings to be covered by a location as well as entire -backends. The contains tag in a location's metadata file contains the -attribute type, which may either by "full" or "partial". In the former -case, rollback proceeds as described above. If it is the latter, the -archiver, upon rolling back or setting configuration for the relevant -backend in that location, first retrieves the required configuration -from both the location and its parent using the same algorithm. It -then uses an XML merging algorithm to combine the two XML files into -one, allowing the child location's data to override its parent's -data. This can be accomplished using the same technique as Bonobo uses -to allow components to override toolbars and menus in the container. - -When a child location partially defines the data for a particular -backend, it must store only those configuration settings that the user -explicitly changed when updating that backend's configuration under -that location. If the frontend simply dumped its entire XML snapshot -to the log, all of the configuration settings would be reflected in -that snapshot, and under the method indicated above, partial -containment would be equivalent to full containment. Therefore, when a -frontend stores its configuration under partial containment, the -archiver must run a node-for-node comparison between the XML data of -the parent location (retrieved using the method indicated above) and -that of the child location. Only those nodes that are different are -actually stored in the configuration log. - -When comparing XML nodes, there must be a way to identify distinct -nodes for comparison. For example, in a network configuration backend, -there might be one node for each interface. If, under the parent -location, the nodes are ordered with interface "eth0" before interface -"eth1", while under the child location, they are in reverse order, but -the configuration is otherwise identical, it is not the intention of -the user that child location should override any configuration data of -the parent location. Therefore, the best method for comparing XML data -is to compare each child of a given node in one source to all the -children of the relevant node in the other source. If any child in the -other source matches, then the XML node is a duplicate and may be -thrown out. If there is another node such that the name and attributes -are the same, but the children are different, then the algorithm -should be invoked recursively to determine the differences among the -children. If there is no such node, then the node should be included. - -4. Future directions - -The metafile log structure may run into scalability problems for -installations have have been in place for a long time. An alternative -structure that uses binary indexing might be in order. A command line -utility (with GUI interface) could be written to recover the file in -the case of corruption; such a utility could simply introspect each of -the XML files in a directory. Provided that each XML file contains -enough information to create a file entry, which is trivial, recovery -is assured. - diff --git a/archiver/backend-list.c b/archiver/backend-list.c deleted file mode 100644 index 37c9c6eee..000000000 --- a/archiver/backend-list.c +++ /dev/null @@ -1,363 +0,0 @@ -/* -*- mode: c; style: linux -*- */ - -/* backend-list.c - * Copyright (C) 2000-2001 Ximian, Inc. - * - * Written by Bradford Hovinen <hovinen@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include <parser.h> -#include <tree.h> - -#include "backend-list.h" - -enum { - ARG_0, - ARG_IS_GLOBAL -}; - -struct _BackendListPrivate -{ - gboolean is_global; - gchar *filename; - GList *backend_ids; -}; - -#define BACKEND_LIST_FROM_SERVANT(servant) (BACKEND_LIST (bonobo_object_from_servant (servant))) - -static BonoboXObjectClass *parent_class; - -static void backend_list_init (BackendList *backend_list); -static void backend_list_class_init (BackendListClass *class); - -static void backend_list_set_arg (GtkObject *object, - GtkArg *arg, - guint arg_id); -static void backend_list_get_arg (GtkObject *object, - GtkArg *arg, - guint arg_id); - -static void backend_list_finalize (GtkObject *object); - -static void do_load (BackendList *backend_list); -static void do_save (BackendList *backend_list); - -/* CORBA interface methods */ - -static CORBA_boolean -impl_ConfigArchiver_BackendList_contains (PortableServer_Servant servant, - const CORBA_char *backend_id, - CORBA_Environment *ev) -{ - return backend_list_contains (BACKEND_LIST_FROM_SERVANT (servant), backend_id); -} - -static void -impl_ConfigArchiver_BackendList_add (PortableServer_Servant servant, - const CORBA_char *backend_id, - CORBA_Environment *ev) -{ - backend_list_add (BACKEND_LIST_FROM_SERVANT (servant), backend_id); -} - -static void -impl_ConfigArchiver_BackendList_remove (PortableServer_Servant servant, - const CORBA_char *backend_id, - CORBA_Environment *ev) -{ - backend_list_remove (BACKEND_LIST_FROM_SERVANT (servant), backend_id); -} - -static void -impl_ConfigArchiver_BackendList_save (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - backend_list_save (BACKEND_LIST_FROM_SERVANT (servant)); -} - -static ConfigArchiver_StringSeq * -impl_ConfigArchiver_BackendList__get_backends (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - ConfigArchiver_StringSeq *seq; - BackendList *backend_list = BACKEND_LIST_FROM_SERVANT (servant); - guint i = 0; - GList *node; - - g_return_val_if_fail (backend_list != NULL, NULL); - g_return_val_if_fail (IS_BACKEND_LIST (backend_list), NULL); - - seq = ConfigArchiver_StringSeq__alloc (); - seq->_length = g_list_length (backend_list->p->backend_ids); - seq->_buffer = CORBA_sequence_CORBA_string_allocbuf (seq->_length); - CORBA_sequence_set_release (seq, TRUE); - - for (node = backend_list->p->backend_ids; node != NULL; node = node->next) - seq->_buffer[i++] = CORBA_string_dup (node->data); - - return seq; -} - -BONOBO_X_TYPE_FUNC_FULL (BackendList, ConfigArchiver_BackendList, BONOBO_X_OBJECT_TYPE, backend_list); - -static void -backend_list_init (BackendList *backend_list) -{ - backend_list->p = g_new0 (BackendListPrivate, 1); -} - -static void -backend_list_class_init (BackendListClass *class) -{ - GtkObjectClass *object_class; - - gtk_object_add_arg_type ("BackendList::is-global", - GTK_TYPE_INT, - GTK_ARG_CONSTRUCT_ONLY | GTK_ARG_READWRITE, - ARG_IS_GLOBAL); - - object_class = GTK_OBJECT_CLASS (class); - object_class->finalize = backend_list_finalize; - object_class->set_arg = backend_list_set_arg; - object_class->get_arg = backend_list_get_arg; - - class->epv.contains = impl_ConfigArchiver_BackendList_contains; - class->epv.add = impl_ConfigArchiver_BackendList_add; - class->epv.remove = impl_ConfigArchiver_BackendList_remove; - class->epv.save = impl_ConfigArchiver_BackendList_save; - - class->epv._get_backends = impl_ConfigArchiver_BackendList__get_backends; - - parent_class = BONOBO_X_OBJECT_CLASS - (gtk_type_class (BONOBO_X_OBJECT_TYPE)); -} - -static void -backend_list_set_arg (GtkObject *object, GtkArg *arg, guint arg_id) -{ - BackendList *backend_list; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_BACKEND_LIST (object)); - - backend_list = BACKEND_LIST (object); - - switch (arg_id) { - case ARG_IS_GLOBAL: - backend_list->p->is_global = GTK_VALUE_INT (*arg); - - backend_list->p->filename = backend_list->p->is_global ? - LOCATION_DIR "/default-global.xml" : - LOCATION_DIR "/default-user.xml"; - do_load (backend_list); - - break; - - default: - g_warning ("Bad argument set"); - break; - } -} - -static void -backend_list_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) -{ - BackendList *backend_list; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_BACKEND_LIST (object)); - - backend_list = BACKEND_LIST (object); - - switch (arg_id) { - case ARG_IS_GLOBAL: - GTK_VALUE_INT (*arg) = backend_list->p->is_global; - break; - - default: - g_warning ("Bad argument get"); - break; - } -} - -static void -backend_list_finalize (GtkObject *object) -{ - BackendList *backend_list; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_BACKEND_LIST (object)); - - backend_list = BACKEND_LIST (object); - - g_list_foreach (backend_list->p->backend_ids, (GFunc) g_free, NULL); - g_list_free (backend_list->p->backend_ids); - g_free (backend_list->p); - - GTK_OBJECT_CLASS (parent_class)->finalize (object); -} - -BonoboObject * -backend_list_new (gboolean is_global) -{ - return BONOBO_OBJECT - (gtk_object_new (backend_list_get_type (), - "is-global", is_global, - NULL)); -} - -gboolean -backend_list_contains (BackendList *backend_list, const gchar *backend_id) -{ - GList *node; - - g_return_val_if_fail (backend_list != NULL, FALSE); - g_return_val_if_fail (IS_BACKEND_LIST (backend_list), FALSE); - - for (node = backend_list->p->backend_ids; node != NULL; - node = node->next) - if (!strcmp (node->data, backend_id)) - return TRUE; - - return FALSE; -} - -/** - * backend_list_foreach: - * @backend_list: - * @callback: - * @data: - * - * Iterates through all the backends, invoking the callback given and aborting - * if any callback returns a nonzero value - * - * Return value: TRUE iff no callback issued a nonzero value, FALSE otherwise - **/ - -gboolean -backend_list_foreach (BackendList *backend_list, BackendCB callback, - gpointer data) -{ - GList *node; - - g_return_val_if_fail (backend_list != NULL, FALSE); - g_return_val_if_fail (IS_BACKEND_LIST (backend_list), FALSE); - g_return_val_if_fail (callback != NULL, FALSE); - - for (node = backend_list->p->backend_ids; node; node = node->next) - if (callback (backend_list, node->data, data)) return FALSE; - - return TRUE; -} - -void -backend_list_add (BackendList *backend_list, const gchar *backend_id) -{ - g_return_if_fail (backend_list != NULL); - g_return_if_fail (IS_BACKEND_LIST (backend_list)); - g_return_if_fail (backend_id != NULL); - - backend_list->p->backend_ids = - g_list_prepend (backend_list->p->backend_ids, g_strdup (backend_id)); -} - -void -backend_list_remove (BackendList *backend_list, const gchar *backend_id) -{ - gchar *tmp; - GList *node; - - g_return_if_fail (backend_list != NULL); - g_return_if_fail (IS_BACKEND_LIST (backend_list)); - g_return_if_fail (backend_id != NULL); - - tmp = g_strdup (backend_id); - node = g_list_find (backend_list->p->backend_ids, tmp); - backend_list->p->backend_ids = - g_list_remove_link (backend_list->p->backend_ids, node); - g_free (node->data); - g_free (tmp); - g_list_free_1 (node); -} - -void -backend_list_save (BackendList *backend_list) -{ - g_return_if_fail (backend_list != NULL); - g_return_if_fail (IS_BACKEND_LIST (backend_list)); - - do_save (backend_list); -} - -static void -do_load (BackendList *backend_list) -{ - xmlNodePtr root_node, node; - xmlDocPtr doc; - GList *list_tail = NULL; - gchar *contains_str; - - doc = xmlParseFile (backend_list->p->filename); - if (doc == NULL) return; - root_node = xmlDocGetRootElement (doc); - - for (node = root_node->childs; node; node = node->next) { - if (!strcmp (node->name, "contains")) { - contains_str = xmlGetProp (node, "backend"); - - if (contains_str != NULL) { - contains_str = g_strdup (contains_str); - list_tail = g_list_append (list_tail, - contains_str); - if (backend_list->p->backend_ids == NULL) - backend_list->p->backend_ids = - list_tail; - else - list_tail = list_tail->next; - } else { - g_warning ("Bad backends list: " \ - "contains element with no " \ - "backend attribute"); - } - } - } -} - -static void -do_save (BackendList *backend_list) -{ - xmlNodePtr root_node, child_node; - xmlDocPtr doc; - GList *node; - - doc = xmlNewDoc ("1.0"); - root_node = xmlNewDocNode (doc, NULL, "location", NULL); - - for (node = backend_list->p->backend_ids; node; node = node->next) { - child_node = xmlNewChild (root_node, NULL, "contains", NULL); - xmlNewProp (child_node, "backend", node->data); - } - - xmlDocSetRootElement (doc, root_node); - xmlSaveFile (backend_list->p->filename, doc); - xmlFreeDoc (doc); -} diff --git a/archiver/backend-list.h b/archiver/backend-list.h deleted file mode 100644 index 20aae22f3..000000000 --- a/archiver/backend-list.h +++ /dev/null @@ -1,78 +0,0 @@ -/* -*- mode: c; style: linux -*- */ - -/* backend-list.h - * Copyright (C) 2000-2001 Ximian, Inc. - * - * Written by Bradford Hovinen <hovinen@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#ifndef __BACKEND_LIST_H -#define __BACKEND_LIST_H - -#include <gnome.h> -#include <bonobo.h> - -#include "ConfigArchiver.h" - -BEGIN_GNOME_DECLS - -#define BACKEND_LIST(obj) GTK_CHECK_CAST (obj, backend_list_get_type (), BackendList) -#define BACKEND_LIST_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, backend_list_get_type (), BackendListClass) -#define IS_BACKEND_LIST(obj) GTK_CHECK_TYPE (obj, backend_list_get_type ()) - -typedef struct _BackendList BackendList; -typedef struct _BackendListClass BackendListClass; -typedef struct _BackendListPrivate BackendListPrivate; - -typedef gint (*BackendCB) (BackendList *, gchar *, gpointer); - -struct _BackendList -{ - BonoboXObject parent; - - BackendListPrivate *p; -}; - -struct _BackendListClass -{ - BonoboXObjectClass parent_class; - - POA_ConfigArchiver_BackendList__epv epv; -}; - -GType backend_list_get_type (void); - -BonoboObject *backend_list_new (gboolean is_global); - -gboolean backend_list_contains (BackendList *backend_list, - const gchar *backend_id); - -gboolean backend_list_foreach (BackendList *backend_list, - BackendCB callback, - gpointer data); - -void backend_list_add (BackendList *backend_list, - const gchar *backend_id); -void backend_list_remove (BackendList *backend_list, - const gchar *backend_id); - -void backend_list_save (BackendList *backend_list); - -END_GNOME_DECLS - -#endif /* __BACKEND_LIST_H */ diff --git a/archiver/bonobo-config-archiver.c b/archiver/bonobo-config-archiver.c deleted file mode 100644 index f8675b54a..000000000 --- a/archiver/bonobo-config-archiver.c +++ /dev/null @@ -1,942 +0,0 @@ -/** - * bonobo-config-archiver.c: XML configuration database with an interface to - * the XML archiver - * - * Author: - * Dietmar Maurer (dietmar@ximian.com) - * Bradford Hovinen <hovinen@ximian.com> - * - * Copyright 2000, 2001 Ximian, Inc. - */ - -#include <config.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <ctype.h> -#include <bonobo.h> -#include <bonobo-conf/bonobo-config-utils.h> -#include <gnome-xml/xmlmemory.h> -#include <gtk/gtkmain.h> - -#include "util.h" -#include "bonobo-config-archiver.h" - -static GtkObjectClass *parent_class = NULL; - -#define CLASS(o) BONOBO_CONFIG_ARCHIVER_CLASS (GTK_OBJECT(o)->klass) - -#define PARENT_TYPE BONOBO_CONFIG_DATABASE_TYPE -#define FLUSH_INTERVAL 30 /* 30 seconds */ - -/* Small Bonobo bug here... */ - -#undef BONOBO_RET_EX -#define BONOBO_RET_EX(ev) \ - G_STMT_START{ \ - if (BONOBO_EX (ev)) \ - return; \ - }G_STMT_END - -extern int daytime; - -static DirEntry * -dir_lookup_entry (DirData *dir, - char *name, - gboolean create) -{ - GSList *l; - DirEntry *de; - - l = dir->entries; - - while (l) { - de = (DirEntry *)l->data; - - if (!strcmp (de->name, name)) - return de; - - l = l->next; - } - - if (create) { - - de = g_new0 (DirEntry, 1); - - de->dir = dir; - - de->name = g_strdup (name); - - dir->entries = g_slist_prepend (dir->entries, de); - - return de; - } - - return NULL; -} - -static DirData * -dir_lookup_subdir (DirData *dir, - char *name, - gboolean create) -{ - GSList *l; - DirData *dd; - - l = dir->subdirs; - - while (l) { - dd = (DirData *)l->data; - - if (!strcmp (dd->name, name)) - return dd; - - l = l->next; - } - - if (create) { - - dd = g_new0 (DirData, 1); - - dd->dir = dir; - - dd->name = g_strdup (name); - - dir->subdirs = g_slist_prepend (dir->subdirs, dd); - - return dd; - } - - return NULL; -} - -static DirData * -lookup_dir (DirData *dir, - const char *path, - gboolean create) -{ - const char *s, *e; - char *name; - DirData *dd = dir; - - s = path; - while (*s == '/') s++; - - if (*s == '\0') - return dir; - - if ((e = strchr (s, '/'))) - name = g_strndup (s, e - s); - else - name = g_strdup (s); - - if ((dd = dir_lookup_subdir (dd, name, create))) { - if (e) - dd = lookup_dir (dd, e, create); - - g_free (name); - return dd; - - } else { - g_free (name); - } - - return NULL; - -} - -static DirEntry * -lookup_dir_entry (BonoboConfigArchiver *archiver_db, - const char *key, - gboolean create) -{ - char *dir_name; - char *leaf_name; - DirEntry *de; - DirData *dd; - - if ((dir_name = bonobo_config_dir_name (key))) { - dd = lookup_dir (archiver_db->dir, dir_name, create); - - if (dd && !dd->node) { - dd->node = xmlNewChild (archiver_db->doc->root, NULL, - "section", NULL); - - xmlSetProp (dd->node, "path", dir_name); - } - - g_free (dir_name); - - } else { - dd = archiver_db->dir; - - if (!dd->node) - dd->node = xmlNewChild (archiver_db->doc->root, NULL, - "section", NULL); - } - - if (!dd) - return NULL; - - if (!(leaf_name = bonobo_config_leaf_name (key))) - return NULL; - - de = dir_lookup_entry (dd, leaf_name, create); - - g_free (leaf_name); - - return de; -} - -static CORBA_any * -real_get_value (BonoboConfigDatabase *db, - const CORBA_char *key, - const CORBA_char *locale, - CORBA_Environment *ev) -{ - BonoboConfigArchiver *archiver_db = BONOBO_CONFIG_ARCHIVER (db); - DirEntry *de; - CORBA_any *value = NULL; - - de = lookup_dir_entry (archiver_db, key, FALSE); - if (!de) { - bonobo_exception_set (ev, ex_Bonobo_ConfigDatabase_NotFound); - return NULL; - } - - if (de->value) - return bonobo_arg_copy (de->value); - - /* localized value */ - if (de->node && de->node->childs && de->node->childs->next) - value = bonobo_config_xml_decode_any ((BonoboUINode *)de->node, - locale, ev); - - if (!value) - bonobo_exception_set (ev, ex_Bonobo_ConfigDatabase_NotFound); - - return value; -} - -/* Produce a new, dynamically allocated string with the OAF IID of the listener - * associated with the given backend id - */ - -static gchar * -get_listener_oafiid (const gchar *backend_id) -{ - gchar *oafiid, *tmp, *tmp1; - - tmp = g_strdup (backend_id); - if ((tmp1 = strstr (tmp, "-properties")) != NULL) *tmp1 = '\0'; - oafiid = g_strconcat ("OAFIID:Bonobo_Listener_Config_", tmp, NULL); - g_free (tmp); - - return oafiid; -} - -static void -real_sync (BonoboConfigDatabase *db, - CORBA_Environment *ev) -{ - BonoboConfigArchiver *archiver_db = BONOBO_CONFIG_ARCHIVER (db); - BonoboArg *arg; - - gchar *listener_oafiid; - Bonobo_Listener listener; - - if (!db->writeable) - return; - - /* FIXME: This will not work correctly in the pathlogical case that two - * ConfigArchiver objects sync at almost exactly the same time. - */ - - archiver_db->is_up_to_date = TRUE; - location_client_store_xml (archiver_db->location, archiver_db->backend_id, - archiver_db->doc, ConfigArchiver_STORE_MASK_PREVIOUS, ev); - - BONOBO_RET_EX (ev); - - /* Try to find a listener to apply the settings. If we can't, don't - * worry about it - */ - - listener_oafiid = get_listener_oafiid (archiver_db->backend_id); - listener = bonobo_get_object (listener_oafiid, "IDL:Bonobo/Listener:1.0", ev); - g_free (listener_oafiid); - - if (BONOBO_EX (ev)) { - listener = CORBA_OBJECT_NIL; - CORBA_exception_init (ev); - } - - arg = bonobo_arg_new (BONOBO_ARG_NULL); - bonobo_event_source_notify_listeners (archiver_db->es, "Bonobo/ConfigDatabase:sync", arg, ev); - bonobo_arg_release (arg); - - if (listener != CORBA_OBJECT_NIL) - bonobo_object_release_unref (listener, NULL); -} - -static void -notify_listeners (BonoboConfigArchiver *archiver_db, - const char *key, - const CORBA_any *value) -{ - CORBA_Environment ev; - char *dir_name; - char *leaf_name; - char *ename; - - if (GTK_OBJECT_DESTROYED (archiver_db)) - return; - - if (!key) - return; - - CORBA_exception_init (&ev); - - ename = g_strconcat ("Bonobo/Property:change:", key, NULL); - - bonobo_event_source_notify_listeners (archiver_db->es, ename, value, &ev); - - g_free (ename); - - if (!(dir_name = bonobo_config_dir_name (key))) - dir_name = g_strdup (""); - - if (!(leaf_name = bonobo_config_leaf_name (key))) - leaf_name = g_strdup (""); - - ename = g_strconcat ("Bonobo/ConfigDatabase:change", dir_name, ":", - leaf_name, NULL); - - bonobo_event_source_notify_listeners (archiver_db->es, ename, value, &ev); - - CORBA_exception_free (&ev); - - g_free (ename); - g_free (dir_name); - g_free (leaf_name); -} - -static void -real_set_value (BonoboConfigDatabase *db, - const CORBA_char *key, - const CORBA_any *value, - CORBA_Environment *ev) -{ - BonoboConfigArchiver *archiver_db = BONOBO_CONFIG_ARCHIVER (db); - DirEntry *de; - char *name; - - de = lookup_dir_entry (archiver_db, key, TRUE); - - if (de->value) - CORBA_free (de->value); - - de->value = bonobo_arg_copy (value); - - if (de->node) { - xmlUnlinkNode (de->node); - xmlFreeNode (de->node); - } - - name = bonobo_config_leaf_name (key); - - de->node = (xmlNodePtr) bonobo_config_xml_encode_any (value, name, ev); - - g_free (name); - - bonobo_ui_node_add_child ((BonoboUINode *)de->dir->node, - (BonoboUINode *)de->node); - - notify_listeners (archiver_db, key, value); -} - -static Bonobo_KeyList * -real_list_dirs (BonoboConfigDatabase *db, - const CORBA_char *dir, - CORBA_Environment *ev) -{ - BonoboConfigArchiver *archiver_db = BONOBO_CONFIG_ARCHIVER (db); - Bonobo_KeyList *key_list; - DirData *dd, *sub; - GSList *l; - int len; - - key_list = Bonobo_KeyList__alloc (); - key_list->_length = 0; - - if (!(dd = lookup_dir (archiver_db->dir, dir, FALSE))) - return key_list; - - if (!(len = g_slist_length (dd->subdirs))) - return key_list; - - key_list->_buffer = CORBA_sequence_CORBA_string_allocbuf (len); - CORBA_sequence_set_release (key_list, TRUE); - - for (l = dd->subdirs; l != NULL; l = l->next) { - sub = (DirData *)l->data; - - key_list->_buffer [key_list->_length] = - CORBA_string_dup (sub->name); - key_list->_length++; - } - - return key_list; -} - -static Bonobo_KeyList * -real_list_keys (BonoboConfigDatabase *db, - const CORBA_char *dir, - CORBA_Environment *ev) -{ - BonoboConfigArchiver *archiver_db = BONOBO_CONFIG_ARCHIVER (db); - Bonobo_KeyList *key_list; - DirData *dd; - DirEntry *de; - GSList *l; - int len; - - key_list = Bonobo_KeyList__alloc (); - key_list->_length = 0; - - if (!(dd = lookup_dir (archiver_db->dir, dir, FALSE))) - return key_list; - - if (!(len = g_slist_length (dd->entries))) - return key_list; - - key_list->_buffer = CORBA_sequence_CORBA_string_allocbuf (len); - CORBA_sequence_set_release (key_list, TRUE); - - for (l = dd->entries; l != NULL; l = l->next) { - de = (DirEntry *)l->data; - - key_list->_buffer [key_list->_length] = - CORBA_string_dup (de->name); - key_list->_length++; - } - - return key_list; -} - -static CORBA_boolean -real_dir_exists (BonoboConfigDatabase *db, - const CORBA_char *dir, - CORBA_Environment *ev) -{ - BonoboConfigArchiver *archiver_db = BONOBO_CONFIG_ARCHIVER (db); - - if (lookup_dir (archiver_db->dir, dir, FALSE)) - return TRUE; - - return FALSE; -} - -static void -delete_dir_entry (DirEntry *de) -{ - CORBA_free (de->value); - - if (de->node) { - xmlUnlinkNode (de->node); - xmlFreeNode (de->node); - } - - g_free (de->name); - g_free (de); -} - -static void -real_remove_value (BonoboConfigDatabase *db, - const CORBA_char *key, - CORBA_Environment *ev) -{ - BonoboConfigArchiver *archiver_db = BONOBO_CONFIG_ARCHIVER (db); - DirEntry *de; - - if (!(de = lookup_dir_entry (archiver_db, key, FALSE))) - return; - - de->dir->entries = g_slist_remove (de->dir->entries, de); - - delete_dir_entry (de); -} - -static void -delete_dir_data (DirData *dd, gboolean is_root) -{ - GSList *l; - - for (l = dd->subdirs; l; l = l->next) - delete_dir_data ((DirData *)l->data, FALSE); - - g_slist_free (dd->subdirs); - - dd->subdirs = NULL; - - for (l = dd->entries; l; l = l->next) - delete_dir_entry ((DirEntry *)l->data); - - g_slist_free (dd->entries); - - dd->entries = NULL; - - if (!is_root) { - g_free (dd->name); - - if (dd->node) { - xmlUnlinkNode (dd->node); - xmlFreeNode (dd->node); - } - - g_free (dd); - } -} - -static void -real_remove_dir (BonoboConfigDatabase *db, - const CORBA_char *dir, - CORBA_Environment *ev) -{ - BonoboConfigArchiver *archiver_db = BONOBO_CONFIG_ARCHIVER (db); - DirData *dd; - - if (!(dd = lookup_dir (archiver_db->dir, dir, FALSE))) - return; - - if (dd != archiver_db->dir && dd->dir) - dd->dir->subdirs = g_slist_remove (dd->dir->subdirs, dd); - - delete_dir_data (dd, dd == archiver_db->dir); -} - -static void -pb_get_fn (BonoboPropertyBag *bag, BonoboArg *arg, - guint arg_id, CORBA_Environment *ev, - gpointer user_data) -{ - BonoboConfigArchiver *archiver_db = BONOBO_CONFIG_ARCHIVER (user_data); - time_t val; - - val = ConfigArchiver_Location_getModificationTime - (archiver_db->location, archiver_db->backend_id, ev); - - BONOBO_ARG_SET_GENERAL (arg, val, TC_ulonglong, CORBA_unsigned_long_long, NULL); -} - -static void -pb_set_fn (BonoboPropertyBag *bag, const BonoboArg *arg, - guint arg_id, CORBA_Environment *ev, - gpointer user_data) -{ - g_assert_not_reached (); -} - -static void -bonobo_config_archiver_destroy (GtkObject *object) -{ - BonoboConfigArchiver *archiver_db = BONOBO_CONFIG_ARCHIVER (object); - CORBA_Environment ev; - - DEBUG_MSG ("Enter"); - - CORBA_exception_init (&ev); - - if (archiver_db->moniker != NULL) { - bonobo_url_unregister ("BONOBO_CONF:ARCHIVER", archiver_db->moniker, &ev); - g_free (archiver_db->moniker); - - if (BONOBO_EX (&ev)) { - g_critical ("Could not unregister the archiver URL"); - CORBA_exception_init (&ev); - } - } - - if (archiver_db->listener_id != 0) { - bonobo_event_source_client_remove_listener - (archiver_db->location, archiver_db->listener_id, &ev); - - if (BONOBO_EX (&ev)) - g_critical ("Could not remove the rollback data listener"); - } - - CORBA_exception_free (&ev); - - if (archiver_db->doc != NULL) { - delete_dir_data (archiver_db->dir, TRUE); - archiver_db->dir = NULL; - xmlFreeDoc (archiver_db->doc); - } - - if (archiver_db->filename != NULL) - g_free (archiver_db->filename); - - if (archiver_db->fp != NULL) - fclose (archiver_db->fp); - - if (archiver_db->location != CORBA_OBJECT_NIL) - bonobo_object_release_unref (archiver_db->location, NULL); - - if (archiver_db->archive != CORBA_OBJECT_NIL) - bonobo_object_release_unref (archiver_db->archive, NULL); - - parent_class->destroy (object); - - DEBUG_MSG ("Exit"); -} - - -static void -bonobo_config_archiver_class_init (BonoboConfigDatabaseClass *class) -{ - GtkObjectClass *object_class = (GtkObjectClass *) class; - BonoboConfigDatabaseClass *cd_class; - - parent_class = gtk_type_class (PARENT_TYPE); - - object_class->destroy = bonobo_config_archiver_destroy; - - cd_class = BONOBO_CONFIG_DATABASE_CLASS (class); - - cd_class->get_value = real_get_value; - cd_class->set_value = real_set_value; - cd_class->list_dirs = real_list_dirs; - cd_class->list_keys = real_list_keys; - cd_class->dir_exists = real_dir_exists; - cd_class->remove_value = real_remove_value; - cd_class->remove_dir = real_remove_dir; - cd_class->sync = real_sync; -} - -static void -bonobo_config_archiver_init (BonoboConfigArchiver *archiver_db) -{ - archiver_db->dir = g_new0 (DirData, 1); - - /* This will always be writeable */ - BONOBO_CONFIG_DATABASE (archiver_db)->writeable = TRUE; -} - -BONOBO_X_TYPE_FUNC (BonoboConfigArchiver, PARENT_TYPE, bonobo_config_archiver); - -static void -read_section (DirData *dd) -{ - CORBA_Environment ev; - DirEntry *de; - xmlNodePtr s; - gchar *name; - - CORBA_exception_init (&ev); - - s = dd->node->childs; - - while (s) { - if (s->type == XML_ELEMENT_NODE && - !strcmp (s->name, "entry") && - (name = xmlGetProp(s, "name"))) { - - de = dir_lookup_entry (dd, name, TRUE); - - de->node = s; - - /* we only decode it if it is a single value, - * multiple (localized) values are decoded in the - * get_value function */ - if (!(s->childs && s->childs->next)) - de->value = bonobo_config_xml_decode_any - ((BonoboUINode *)s, NULL, &ev); - - xmlFree (name); - } - s = s->next; - } - - CORBA_exception_free (&ev); -} - -static void -fill_cache (BonoboConfigArchiver *archiver_db) -{ - xmlNodePtr n; - gchar *path; - DirData *dd; - - n = archiver_db->doc->root->childs; - - while (n) { - if (n->type == XML_ELEMENT_NODE && - !strcmp (n->name, "section")) { - - path = xmlGetProp(n, "path"); - - if (!path || !strcmp (path, "")) { - dd = archiver_db->dir; - } else - dd = lookup_dir (archiver_db->dir, path, TRUE); - - if (!dd->node) - dd->node = n; - - read_section (dd); - - xmlFree (path); - } - n = n->next; - } -} - -/* parse_name - * - * Given a moniker with a backend id and (possibly) a location id encoded - * therein, parse out the backend id and the location id and set the pointers - * given to them. - * - * FIXME: Is this encoding really the way we want to do this? Ask Dietmar and - * Michael. - */ - -static gboolean -parse_name (const gchar *name, gchar **backend_id, gchar **location, struct tm **date) -{ - gchar *e, *e1, *time_str = NULL; - - *date = NULL; - - if (name[0] == '[') { - e = strchr (name + 1, '|'); - - if (e != NULL) { - *location = g_strndup (name + 1, e - (name + 1)); - e1 = strchr (e + 1, ']'); - - if (e1 != NULL) { - time_str = g_strndup (e + 1, e1 - (e + 1)); - *date = parse_date (time_str); - g_free (time_str); - } - - *backend_id = g_strdup (e1 + 1); - } else { - e = strchr (name + 1, ']'); - - if (e != NULL) - *location = g_strndup (name + 1, e - (name + 1)); - else - return FALSE; - - *backend_id = g_strdup (e + 1); - } - } else { - *backend_id = g_strdup (name); - *location = NULL; - } - - if (*location != NULL && **location == '\0') { - g_free (*location); - *location = NULL; - } - - return TRUE; -} - -static void -new_rollback_cb (BonoboListener *listener, - gchar *event_name, - CORBA_any *any, - CORBA_Environment *ev, - BonoboConfigArchiver *archiver_db) -{ - BonoboArg *arg; - - if (archiver_db->is_up_to_date) { - archiver_db->is_up_to_date = FALSE; - return; - } - - if (archiver_db->dir != NULL) { - delete_dir_data (archiver_db->dir, TRUE); - g_free (archiver_db->dir->name); - g_free (archiver_db->dir); - archiver_db->dir = g_new0 (DirData, 1); - } - - if (archiver_db->doc != NULL) - xmlFreeDoc (archiver_db->doc); - - archiver_db->doc = location_client_load_rollback_data - (archiver_db->location, NULL, 0, archiver_db->backend_id, TRUE, ev); - - if (archiver_db->doc == NULL) - g_critical ("Could not load new rollback data"); - else - fill_cache (archiver_db); - - arg = bonobo_arg_new (BONOBO_ARG_NULL); - bonobo_event_source_notify_listeners (archiver_db->es, "Bonobo/ConfigDatabase:sync", arg, ev); - bonobo_arg_release (arg); -} - -Bonobo_ConfigDatabase -bonobo_config_archiver_new (Bonobo_Moniker parent, - const Bonobo_ResolveOptions *options, - const char *moniker, - CORBA_Environment *ev) -{ - BonoboConfigArchiver *archiver_db; - Bonobo_ConfigDatabase db; - ConfigArchiver_Archive archive; - ConfigArchiver_Location location; - gchar *moniker_tmp; - gchar *backend_id; - gchar *location_id; - struct tm *date; - - g_return_val_if_fail (backend_id != NULL, NULL); - - /* Check the Bonobo URL database to see if this archiver database has - * already been created, and return it if it has */ - - moniker_tmp = g_strdup (moniker); - db = bonobo_url_lookup ("BONOBO_CONF:ARCHIVER", moniker_tmp, ev); - g_free (moniker_tmp); - - if (BONOBO_EX (ev)) { - db = CORBA_OBJECT_NIL; - CORBA_exception_init (ev); - } - - if (db != CORBA_OBJECT_NIL) - return bonobo_object_dup_ref (db, NULL); - - /* Parse out the backend id, location id, and rollback date from the - * moniker given */ - - if (parse_name (moniker, &backend_id, &location_id, &date) < 0) { - EX_SET_NOT_FOUND (ev); - return CORBA_OBJECT_NIL; - } - - /* Resolve the parent archive and the location */ - - archive = Bonobo_Moniker_resolve (parent, options, "IDL:ConfigArchiver/Archive:1.0", ev); - - if (BONOBO_EX (ev) || archive == CORBA_OBJECT_NIL) { - g_free (location_id); - g_free (date); - return CORBA_OBJECT_NIL; - } - - if (location_id == NULL || *location_id == '\0') - location = ConfigArchiver_Archive__get_currentLocation (archive, ev); - else - location = ConfigArchiver_Archive_getLocation (archive, location_id, ev); - - g_free (location_id); - - if (location == CORBA_OBJECT_NIL) { - g_free (date); - bonobo_object_release_unref (archive, NULL); - return CORBA_OBJECT_NIL; - } - - /* Construct the database object proper and fill in its values */ - - if ((archiver_db = gtk_type_new (BONOBO_CONFIG_ARCHIVER_TYPE)) == NULL) { - g_free (date); - return CORBA_OBJECT_NIL; - } - - archiver_db->backend_id = backend_id; - archiver_db->moniker = g_strdup (moniker); - archiver_db->archive = archive; - archiver_db->location = location; - - /* Load the XML data, or use the defaults file if none are present */ - - archiver_db->doc = location_client_load_rollback_data - (archiver_db->location, date, 0, archiver_db->backend_id, TRUE, ev); - g_free (date); - - if (BONOBO_EX (ev) || archiver_db->doc == NULL) { - gchar *filename; - - filename = g_strconcat (GNOMECC_DEFAULTS_DIR "/", archiver_db->backend_id, ".xml", NULL); - archiver_db->doc = xmlParseFile (filename); - g_free (filename); - - if (archiver_db->doc == NULL) { - bonobo_object_release_unref (archiver_db->location, NULL); - bonobo_object_release_unref (archiver_db->archive, NULL); - bonobo_object_unref (BONOBO_OBJECT (archiver_db)); - return CORBA_OBJECT_NIL; - } - - CORBA_exception_init (ev); - } - - /* Load data from the XML file */ - - if (archiver_db->doc->root == NULL) - archiver_db->doc->root = - xmlNewDocNode (archiver_db->doc, NULL, "bonobo-config", NULL); - - if (strcmp (archiver_db->doc->root->name, "bonobo-config")) { - xmlFreeDoc (archiver_db->doc); - archiver_db->doc = xmlNewDoc("1.0"); - archiver_db->doc->root = - xmlNewDocNode (archiver_db->doc, NULL, "bonobo-config", NULL); - } - - fill_cache (archiver_db); - - /* Construct the associated property bag and event source */ - -#if 0 - archiver_db->es = bonobo_event_source_new (); - - bonobo_object_add_interface (BONOBO_OBJECT (archiver_db), - BONOBO_OBJECT (archiver_db->es)); -#endif - - archiver_db->pb = bonobo_property_bag_new (pb_get_fn, - pb_set_fn, - archiver_db); - - bonobo_object_add_interface (BONOBO_OBJECT (archiver_db), - BONOBO_OBJECT (archiver_db->pb)); - - archiver_db->es = archiver_db->pb->es; - - bonobo_property_bag_add (archiver_db->pb, - "last_modified", 1, TC_ulonglong, NULL, - "Date (time_t) of modification", - BONOBO_PROPERTY_READABLE); - - /* Listen for events pertaining to new rollback data */ - - if (date == NULL && location_id == NULL) - archiver_db->listener_id = - bonobo_event_source_client_add_listener - (location, (BonoboListenerCallbackFn) new_rollback_cb, - "ConfigArchiver/Location:newRollbackData", ev, archiver_db); - else - archiver_db->listener_id = 0; - - /* Prepare to return the database object */ - - db = CORBA_Object_duplicate (BONOBO_OBJREF (archiver_db), NULL); - - moniker_tmp = g_strdup (moniker); - bonobo_url_register ("BONOBO_CONF:ARCHIVER", moniker_tmp, NULL, db, ev); - g_free (moniker_tmp); - - return db; -} diff --git a/archiver/bonobo-config-archiver.h b/archiver/bonobo-config-archiver.h deleted file mode 100644 index 634153b72..000000000 --- a/archiver/bonobo-config-archiver.h +++ /dev/null @@ -1,89 +0,0 @@ -/** - * bonobo-config-archiver.h: xml configuration database implementation, with - * interface to the archiver - * - * Author: - * Dietmar Maurer (dietmar@ximian.com) - * Bradford Hovinen <hovinen@ximian.com> - * - * Copyright 2000 Ximian, Inc. - */ -#ifndef __BONOBO_CONFIG_ARCHIVER_H__ -#define __BONOBO_CONFIG_ARCHIVER_H__ - -#include <stdio.h> -#include <bonobo-conf/bonobo-config-database.h> -#include <gnome-xml/tree.h> -#include <gnome-xml/parser.h> -#include <bonobo/bonobo-event-source.h> -#include <bonobo/bonobo-property-bag.h> - -#include "archiver-client.h" - -BEGIN_GNOME_DECLS - -#define EX_SET_NOT_FOUND(ev) bonobo_exception_set (ev, ex_Bonobo_Moniker_InterfaceNotFound) - -#define BONOBO_CONFIG_ARCHIVER_TYPE (bonobo_config_archiver_get_type ()) -#define BONOBO_CONFIG_ARCHIVER(o) (GTK_CHECK_CAST ((o), BONOBO_CONFIG_ARCHIVER_TYPE, BonoboConfigArchiver)) -#define BONOBO_CONFIG_ARCHIVER_CLASS(k) (GTK_CHECK_CLASS_CAST((k), BONOBO_CONFIG_ARCHIVER_TYPE, BonoboConfigArchiverClass)) -#define BONOBO_IS_CONFIG_ARCHIVER(o) (GTK_CHECK_TYPE ((o), BONOBO_CONFIG_ARCHIVER_TYPE)) -#define BONOBO_IS_CONFIG_ARCHIVER_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), BONOBO_CONFIG_ARCHIVER_TYPE)) - -typedef struct _DirData DirData; - -struct _DirData { - char *name; - GSList *entries; - GSList *subdirs; - xmlNodePtr node; - DirData *dir; -}; - -typedef struct { - char *name; - CORBA_any *value; - xmlNodePtr node; - DirData *dir; -} DirEntry; - -typedef struct _BonoboConfigArchiver BonoboConfigArchiver; - -struct _BonoboConfigArchiver { - BonoboConfigDatabase base; - - char *filename; - FILE *fp; - xmlDocPtr doc; - DirData *dir; - guint time_id; - - ConfigArchiver_Archive archive; - ConfigArchiver_Location location; - gchar *backend_id; - gchar *moniker; - - BonoboEventSource *es; - BonoboPropertyBag *pb; - - Bonobo_EventSource_ListenerId listener_id; - gboolean is_up_to_date; -}; - -typedef struct { - BonoboConfigDatabaseClass parent_class; -} BonoboConfigArchiverClass; - - -GtkType -bonobo_config_archiver_get_type (void); - -Bonobo_ConfigDatabase -bonobo_config_archiver_new (Bonobo_Moniker parent, - const Bonobo_ResolveOptions *options, - const char *moniker, - CORBA_Environment *ev); - -END_GNOME_DECLS - -#endif /* ! __BONOBO_CONFIG_ARCHIVER_H__ */ diff --git a/archiver/bonobo-moniker-archiver.c b/archiver/bonobo-moniker-archiver.c deleted file mode 100644 index 19c4efde5..000000000 --- a/archiver/bonobo-moniker-archiver.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * bonobo-moniker-archiver.c: archiver xml database moniker implementation - * - * Author: - * Dietmar Maurer (dietmar@ximian.com) - * Bradford Hovinen <hovinen@ximian.com> - * - * Copyright 2001 Ximian, Inc. - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <bonobo.h> - -#include "bonobo-config-archiver.h" -#include "archive.h" -#include "util.h" - -static Archive *user_archive = NULL; -static Archive *global_archive = NULL; - -static void -archive_destroy_cb (Archive *archive) -{ - if (archive == global_archive) - global_archive = NULL; - else if (archive == user_archive) - user_archive = NULL; -} - -static Bonobo_Unknown -archive_resolve (BonoboMoniker *moniker, - const Bonobo_ResolveOptions *options, - const CORBA_char *requested_interface, - CORBA_Environment *ev) -{ - const gchar *name; - - Bonobo_Unknown ret; - - if (strcmp (requested_interface, "IDL:ConfigArchiver/Archive:1.0")) { - EX_SET_NOT_FOUND (ev); - return CORBA_OBJECT_NIL; - } - - name = bonobo_moniker_get_name (moniker); - - if (!strcmp (name, "global-archive")) { - if (global_archive == NULL) { - global_archive = ARCHIVE (archive_load (TRUE)); - gtk_signal_connect (GTK_OBJECT (global_archive), "destroy", GTK_SIGNAL_FUNC (archive_destroy_cb), NULL); - ret = CORBA_Object_duplicate (BONOBO_OBJREF (global_archive), ev); - } else { - ret = bonobo_object_dup_ref (BONOBO_OBJREF (global_archive), ev); - } - - if (BONOBO_EX (ev)) { - g_critical ("Cannot duplicate object"); - bonobo_object_release_unref (ret, NULL); - ret = CORBA_OBJECT_NIL; - } - } - else if (!strcmp (name, "user-archive")) { - if (user_archive == NULL) { - user_archive = ARCHIVE (archive_load (FALSE)); - gtk_signal_connect (GTK_OBJECT (user_archive), "destroy", GTK_SIGNAL_FUNC (archive_destroy_cb), NULL); - ret = CORBA_Object_duplicate (BONOBO_OBJREF (user_archive), ev); - } else { - ret = bonobo_object_dup_ref (BONOBO_OBJREF (user_archive), ev); - } - - if (BONOBO_EX (ev)) { - g_critical ("Cannot duplicate object"); - bonobo_object_release_unref (ret, NULL); - ret = CORBA_OBJECT_NIL; - } - } else { - EX_SET_NOT_FOUND (ev); - ret = CORBA_OBJECT_NIL; - } - - return ret; -} - -static Bonobo_Unknown -archiverdb_resolve (BonoboMoniker *moniker, - const Bonobo_ResolveOptions *options, - const CORBA_char *requested_interface, - CORBA_Environment *ev) -{ - Bonobo_Moniker parent; - Bonobo_ConfigDatabase db; - const gchar *name; - - if (strcmp (requested_interface, "IDL:Bonobo/ConfigDatabase:1.0")) { - EX_SET_NOT_FOUND (ev); - return CORBA_OBJECT_NIL; - } - - parent = bonobo_moniker_get_parent (moniker, ev); - if (BONOBO_EX (ev)) - return CORBA_OBJECT_NIL; - - if (parent == CORBA_OBJECT_NIL) { - EX_SET_NOT_FOUND (ev); - return CORBA_OBJECT_NIL; - } - - name = bonobo_moniker_get_name (moniker); - - db = bonobo_config_archiver_new (parent, options, name, ev); - - if (db == CORBA_OBJECT_NIL || BONOBO_EX (ev)) - EX_SET_NOT_FOUND (ev); - - bonobo_object_release_unref (parent, NULL); - - return db; -} - - -static BonoboObject * -bonobo_moniker_archiver_factory (BonoboGenericFactory *this, - const char *object_id, - void *closure) -{ - if (!strcmp (object_id, "OAFIID:Bonobo_Moniker_archiverdb")) { - return BONOBO_OBJECT (bonobo_moniker_simple_new - ("archiverdb:", archiverdb_resolve)); - } - else if (!strcmp (object_id, "OAFIID:Bonobo_Moniker_archive")) { - return BONOBO_OBJECT (bonobo_moniker_simple_new - ("archive:", archive_resolve)); - } else { - g_warning ("Failing to manufacture a '%s'", object_id); - } - - return NULL; -} - -BONOBO_OAF_FACTORY_MULTI ("OAFIID:Bonobo_Moniker_archiver_Factory", - "bonobo xml archiver database moniker", "1.0", - bonobo_moniker_archiver_factory, - NULL); diff --git a/archiver/cluster-location.c b/archiver/cluster-location.c deleted file mode 100644 index 2fe987c3c..000000000 --- a/archiver/cluster-location.c +++ /dev/null @@ -1,222 +0,0 @@ -/* -*- mode: c; style: linux -*- */ - -/* cluster-location.c - * Copyright (C) 2000 Ximian, Inc. - * - * Written by Bradford Hovinen <hovinen@helixcode.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "cluster.h" -#include "cluster-location.h" - -typedef struct _pair_t pair_t; - -enum { - ARG_0, - ARG_SAMPLE -}; - -struct _ClusterLocationPrivate -{ - /* Private data members */ -}; - -struct _pair_t -{ - gpointer a, b; -}; - -static LocationClass *parent_class; - -static void cluster_location_init (ClusterLocation *cluster_location); -static void cluster_location_class_init (ClusterLocationClass *class); - -static void cluster_location_set_arg (GtkObject *object, - GtkArg *arg, - guint arg_id); -static void cluster_location_get_arg (GtkObject *object, - GtkArg *arg, - guint arg_id); - -static void cluster_location_finalize (GtkObject *object); - -static gboolean cluster_location_do_rollback (Location *location, - gchar *backend_id, - xmlDocPtr doc); - -static gboolean host_cb (Cluster *cluster, - gchar *hostname, - pair_t *pair); - -GType -cluster_location_get_type (void) -{ - static GType cluster_location_type = 0; - - if (!cluster_location_type) { - GtkTypeInfo cluster_location_info = { - "ClusterLocation", - sizeof (ClusterLocation), - sizeof (ClusterLocationClass), - (GtkClassInitFunc) cluster_location_class_init, - (GtkObjectInitFunc) cluster_location_init, - (GtkArgSetFunc) NULL, - (GtkArgGetFunc) NULL - }; - - cluster_location_type = - gtk_type_unique (location_get_type (), - &cluster_location_info); - } - - return cluster_location_type; -} - -static void -cluster_location_init (ClusterLocation *cluster_location) -{ - cluster_location->p = g_new0 (ClusterLocationPrivate, 1); -} - -static void -cluster_location_class_init (ClusterLocationClass *class) -{ - GtkObjectClass *object_class; - LocationClass *location_class; - - gtk_object_add_arg_type ("ClusterLocation::sample", - GTK_TYPE_POINTER, - GTK_ARG_READWRITE, - ARG_SAMPLE); - - object_class = GTK_OBJECT_CLASS (class); - object_class->finalize = cluster_location_finalize; - object_class->set_arg = cluster_location_set_arg; - object_class->get_arg = cluster_location_get_arg; - - location_class = LOCATION_CLASS (class); - location_class->do_rollback = cluster_location_do_rollback; - - parent_class = LOCATION_CLASS - (gtk_type_class (location_get_type ())); -} - -static void -cluster_location_set_arg (GtkObject *object, GtkArg *arg, guint arg_id) -{ - ClusterLocation *cluster_location; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_CLUSTER_LOCATION (object)); - - cluster_location = CLUSTER_LOCATION (object); - - switch (arg_id) { - case ARG_SAMPLE: - break; - - default: - g_warning ("Bad argument set"); - break; - } -} - -static void -cluster_location_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) -{ - ClusterLocation *cluster_location; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_CLUSTER_LOCATION (object)); - - cluster_location = CLUSTER_LOCATION (object); - - switch (arg_id) { - case ARG_SAMPLE: - break; - - default: - g_warning ("Bad argument get"); - break; - } -} - -static void -cluster_location_finalize (GtkObject *object) -{ - ClusterLocation *cluster_location; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_CLUSTER_LOCATION (object)); - - cluster_location = CLUSTER_LOCATION (object); - - g_free (cluster_location->p); - - GTK_OBJECT_CLASS (parent_class)->finalize (object); -} - -GtkObject * -cluster_location_new (void) -{ - return gtk_object_new (cluster_location_get_type (), - NULL); -} - -static gboolean -cluster_location_do_rollback (Location *location, gchar *backend_id, - xmlDocPtr doc) -{ - Cluster *cluster; - pair_t pair; - - g_return_val_if_fail (location != NULL, FALSE); - g_return_val_if_fail (IS_CLUSTER_LOCATION (location), FALSE); - g_return_val_if_fail (backend_id != NULL, FALSE); - g_return_val_if_fail (doc != NULL, FALSE); - - gtk_object_get (GTK_OBJECT (location), "archive", &cluster, NULL); - pair.a = doc; - pair.b = backend_id; - cluster_foreach_host (cluster, (ClusterHostCB) host_cb, &pair); - - return TRUE; -} - -static gboolean -host_cb (Cluster *cluster, gchar *hostname, pair_t *pair) -{ - xmlDocPtr doc; - gchar *backend_id, *command; - FILE *output; - - doc = pair->a; - backend_id = pair->b; - command = g_strconcat ("ssh ", hostname, " ", backend_id, " --set", - NULL); - output = popen (command, "w"); - xmlDocDump (output, doc); - pclose (output); - g_free (command); - - return FALSE; -} diff --git a/archiver/cluster-location.h b/archiver/cluster-location.h deleted file mode 100644 index 2aa54a532..000000000 --- a/archiver/cluster-location.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- mode: c; style: linux -*- */ - -/* cluster-location.h - * Copyright (C) 2000 Ximian, Inc. - * - * Written by Bradford Hovinen <hovinen@helixcode.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#ifndef __CLUSTER_LOCATION_H -#define __CLUSTER_LOCATION_H - -#include <gnome.h> - -#include "location.h" - -BEGIN_GNOME_DECLS - -#define CLUSTER_LOCATION(obj) GTK_CHECK_CAST (obj, cluster_location_get_type (), ClusterLocation) -#define CLUSTER_LOCATION_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, cluster_location_get_type (), ClusterLocationClass) -#define IS_CLUSTER_LOCATION(obj) GTK_CHECK_TYPE (obj, cluster_location_get_type ()) - -typedef struct _ClusterLocation ClusterLocation; -typedef struct _ClusterLocationClass ClusterLocationClass; -typedef struct _ClusterLocationPrivate ClusterLocationPrivate; - -struct _ClusterLocation -{ - Location parent; - - ClusterLocationPrivate *p; -}; - -struct _ClusterLocationClass -{ - LocationClass location_class; -}; - -GType cluster_location_get_type (void); - -GtkObject *cluster_location_new (void); - -END_GNOME_DECLS - -#endif /* __CLUSTER_LOCATION_H */ diff --git a/archiver/cluster.c b/archiver/cluster.c deleted file mode 100644 index f3a3c08f5..000000000 --- a/archiver/cluster.c +++ /dev/null @@ -1,437 +0,0 @@ -/* -*- mode: c; style: linux -*- */ - -/* cluster.c - * Copyright (C) 2000 Ximian, Inc. - * - * Written by Bradford Hovinen <hovinen@helixcode.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include <parser.h> - -#include "cluster.h" - -enum { - ARG_0, - ARG_SAMPLE -}; - -typedef struct _SlaveHost SlaveHost; - -struct _SlaveHost -{ - gchar *hostname; -}; - -struct _ClusterPrivate -{ - GList *slave_hosts; -}; - -static ArchiveClass *parent_class; - -static void cluster_init (Cluster *cluster); -static void cluster_class_init (ClusterClass *class); - -static void cluster_set_arg (GtkObject *object, - GtkArg *arg, - guint arg_id); -static void cluster_get_arg (GtkObject *object, - GtkArg *arg, - guint arg_id); - -static void cluster_destroy (GtkObject *object); -static void cluster_finalize (GtkObject *object); - -static gboolean cluster_construct (Cluster *cluster, - gboolean is_new); - -static gboolean load_metadata (Cluster *cluster); -static void save_metadata (Cluster *cluster); - -static void cluster_add_slave_host (Cluster *cluster, - SlaveHost *slave_host); -static void cluster_remove_slave_host (Cluster *cluster, - SlaveHost *slave_host); - -static SlaveHost *find_slave_host (Cluster *cluster, - gchar *hostname); -static gchar *get_metadata_filename (Cluster *cluster); - -static SlaveHost *slave_host_new (gchar *hostname); -static SlaveHost *slave_host_read_xml (xmlNodePtr node); -static xmlNodePtr slave_host_write_xml (SlaveHost *host); - -GType -cluster_get_type (void) -{ - static GType cluster_type = 0; - - if (!cluster_type) { - GtkTypeInfo cluster_info = { - "Cluster", - sizeof (Cluster), - sizeof (ClusterClass), - (GtkClassInitFunc) cluster_class_init, - (GtkObjectInitFunc) cluster_init, - (GtkArgSetFunc) NULL, - (GtkArgGetFunc) NULL - }; - - cluster_type = - gtk_type_unique (archive_get_type (), - &cluster_info); - } - - return cluster_type; -} - -static void -cluster_init (Cluster *cluster) -{ - cluster->p = g_new0 (ClusterPrivate, 1); -} - -static void -cluster_class_init (ClusterClass *class) -{ - GtkObjectClass *object_class; - - gtk_object_add_arg_type ("Cluster::sample", - GTK_TYPE_POINTER, - GTK_ARG_READWRITE, - ARG_SAMPLE); - - object_class = GTK_OBJECT_CLASS (class); - object_class->destroy = cluster_destroy; - object_class->finalize = cluster_finalize; - object_class->set_arg = cluster_set_arg; - object_class->get_arg = cluster_get_arg; - - parent_class = ARCHIVE_CLASS - (gtk_type_class (archive_get_type ())); -} - -static void -cluster_set_arg (GtkObject *object, GtkArg *arg, guint arg_id) -{ - Cluster *cluster; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_CLUSTER (object)); - - cluster = CLUSTER (object); - - switch (arg_id) { - case ARG_SAMPLE: - break; - - default: - g_warning ("Bad argument set"); - break; - } -} - -static void -cluster_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) -{ - Cluster *cluster; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_CLUSTER (object)); - - cluster = CLUSTER (object); - - switch (arg_id) { - case ARG_SAMPLE: - break; - - default: - g_warning ("Bad argument get"); - break; - } -} - -static void -cluster_destroy (GtkObject *object) -{ - Cluster *cluster; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_CLUSTER (object)); - - cluster = CLUSTER (object); - - save_metadata (cluster); - - GTK_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -cluster_finalize (GtkObject *object) -{ - Cluster *cluster; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_CLUSTER (object)); - - cluster = CLUSTER (object); - - g_free (cluster->p); - - GTK_OBJECT_CLASS (parent_class)->finalize (object); -} - -GtkObject * -cluster_new (gchar *prefix) -{ - GtkObject *object; - - object = gtk_object_new (cluster_get_type (), - "prefix", prefix, - "is-global", TRUE, - NULL); - - if (cluster_construct (CLUSTER (object), TRUE) == FALSE) { - gtk_object_destroy (object); - return NULL; - } - - return object; -} - -GtkObject * -cluster_load (gchar *prefix) -{ - GtkObject *object; - - object = gtk_object_new (cluster_get_type (), - "prefix", prefix, - "is-global", TRUE, - NULL); - - if (cluster_construct (CLUSTER (object), FALSE) == FALSE) { - gtk_object_destroy (object); - return NULL; - } - - return object; -} - -void -cluster_foreach_host (Cluster *cluster, ClusterHostCB callback, gpointer data) -{ - GList *node; - SlaveHost *host; - - g_return_if_fail (cluster != NULL); - g_return_if_fail (IS_CLUSTER (cluster)); - g_return_if_fail (callback != NULL); - - for (node = cluster->p->slave_hosts; node; node = node->next) { - host = node->data; - if (callback (cluster, host->hostname, data)) break; - } -} - -void -cluster_add_host (Cluster *cluster, gchar *hostname) -{ - g_return_if_fail (cluster != NULL); - g_return_if_fail (IS_CLUSTER (cluster)); - g_return_if_fail (hostname != NULL); - - cluster_add_slave_host (cluster, slave_host_new (hostname)); -} - -void -cluster_remove_host (Cluster *cluster, gchar *hostname) -{ - g_return_if_fail (cluster != NULL); - g_return_if_fail (IS_CLUSTER (cluster)); - g_return_if_fail (hostname != NULL); - - cluster_remove_slave_host (cluster, - find_slave_host (cluster, hostname)); -} - -static gboolean -cluster_construct (Cluster *cluster, gboolean is_new) -{ - if (archive_construct (ARCHIVE (cluster), is_new) == FALSE) - return FALSE; - - if (!is_new) { - if (load_metadata (cluster) == FALSE) - return FALSE; - } - - return TRUE; -} - -/* Loads the metadata associated with the cluster; returns TRUE on success and - * FALSE on failure - */ - -static gboolean -load_metadata (Cluster *cluster) -{ - xmlDocPtr doc; - xmlNodePtr root_node, node; - gchar *filename; - SlaveHost *new_host; - - filename = get_metadata_filename (cluster); - doc = xmlParseFile (filename); - g_free (filename); - - if (doc == NULL) return FALSE; - - root_node = xmlDocGetRootElement (doc); - if (strcmp (root_node->name, "cluster")) { - xmlFreeDoc (doc); - return FALSE; - } - - for (node = root_node->childs; node != NULL; node = node->next) { - if (!strcmp (node->name, "host")) { - new_host = slave_host_read_xml (node); - if (new_host != NULL) - cluster_add_slave_host (cluster, new_host); - } - } - - xmlFreeDoc (doc); - - return TRUE; -} - -static void -save_metadata (Cluster *cluster) -{ - xmlDocPtr doc; - xmlNodePtr root_node; - GList *list_node; - gchar *filename; - - doc = xmlNewDoc ("1.0"); - root_node = xmlNewDocNode (doc, NULL, "cluster", NULL); - - for (list_node = cluster->p->slave_hosts; list_node != NULL; - list_node = list_node->next) - { - xmlAddChild (root_node, - slave_host_write_xml (list_node->data)); - } - - xmlDocSetRootElement (doc, root_node); - - filename = get_metadata_filename (cluster); - xmlSaveFile (filename, doc); - g_free (filename); -} - -/* Adds a slave host to the list of slave hosts for this cluster */ - -static void -cluster_add_slave_host (Cluster *cluster, SlaveHost *slave_host) -{ - if (slave_host == NULL) return; - - cluster->p->slave_hosts = - g_list_append (cluster->p->slave_hosts, slave_host); -} - -static void -cluster_remove_slave_host (Cluster *cluster, SlaveHost *slave_host) -{ - if (slave_host == NULL) return; - - cluster->p->slave_hosts = - g_list_remove (cluster->p->slave_hosts, slave_host); -} - -static SlaveHost * -find_slave_host (Cluster *cluster, gchar *hostname) -{ - SlaveHost *host; - GList *node; - - g_return_val_if_fail (hostname != NULL, NULL); - - for (node = cluster->p->slave_hosts; node != NULL; node = node->next) { - host = node->data; - - if (!strcmp (host->hostname, hostname)) - return host; - } - - return NULL; -} - -/* Returns the filename of the metadata file (should be freed after use) */ - -static gchar * -get_metadata_filename (Cluster *cluster) -{ - return g_concat_dir_and_file - (archive_get_prefix (ARCHIVE (cluster)), "cluster.xml"); -} - -/* Constructs a new slave host structure */ - -static SlaveHost * -slave_host_new (gchar *hostname) -{ - SlaveHost *new_host; - - new_host = g_new0 (SlaveHost, 1); - new_host->hostname = g_strdup (hostname); - - return new_host; -} - -/* Constructs a new slave host structure from an XML node */ - -static SlaveHost * -slave_host_read_xml (xmlNodePtr node) -{ - gchar *hostname; - - hostname = xmlGetProp (node, "name"); - - if (hostname != NULL) - return slave_host_new (hostname); - else - return NULL; -} - -/* Constructs an XML node for the slave host */ - -static xmlNodePtr -slave_host_write_xml (SlaveHost *host) -{ - xmlNodePtr node; - - node = xmlNewNode (NULL, "host"); - xmlNewProp (node, "name", host->hostname); - return node; -} diff --git a/archiver/cluster.h b/archiver/cluster.h deleted file mode 100644 index 85dc503bb..000000000 --- a/archiver/cluster.h +++ /dev/null @@ -1,71 +0,0 @@ -/* -*- mode: c; style: linux -*- */ - -/* cluster.h - * Copyright (C) 2000 Ximian, Inc. - * - * Written by Bradford Hovinen <hovinen@helixcode.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#ifndef __CLUSTER_H -#define __CLUSTER_H - -#include <gnome.h> - -#include "archive.h" - -BEGIN_GNOME_DECLS - -#define CLUSTER(obj) GTK_CHECK_CAST (obj, cluster_get_type (), Cluster) -#define CLUSTER_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, cluster_get_type (), ClusterClass) -#define IS_CLUSTER(obj) GTK_CHECK_TYPE (obj, cluster_get_type ()) - -typedef struct _Cluster Cluster; -typedef struct _ClusterClass ClusterClass; -typedef struct _ClusterPrivate ClusterPrivate; - -typedef gboolean (*ClusterHostCB) (Cluster *, gchar *, gpointer); - -struct _Cluster -{ - Archive parent; - - ClusterPrivate *p; -}; - -struct _ClusterClass -{ - ArchiveClass archive_class; -}; - -GType cluster_get_type (void); - -GtkObject *cluster_new (gchar *prefix); -GtkObject *cluster_load (gchar *prefix); - -void cluster_foreach_host (Cluster *cluster, - ClusterHostCB callback, - gpointer data); - -void cluster_add_host (Cluster *cluster, - gchar *hostname); -void cluster_remove_host (Cluster *cluster, - gchar *hostname); - -END_GNOME_DECLS - -#endif /* __CLUSTER_H */ diff --git a/archiver/config-archiver.c b/archiver/config-archiver.c deleted file mode 100644 index 56679a84c..000000000 --- a/archiver/config-archiver.c +++ /dev/null @@ -1,439 +0,0 @@ -/* -*- mode: c; style: linux -*- */ - -/* main.c - * Copyright (C) 2000-2001 Ximian, Inc. - * - * Written by Bradford Hovinen (hovinen@ximian.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <stdio.h> -#include <time.h> -#include <sys/time.h> -#include <sys/file.h> -#include <unistd.h> -#include <errno.h> - -#include <gnome.h> -#include <bonobo.h> - -#include <gnome-xml/parser.h> - -#include "archiver-client.h" -#include "util.h" - -/* Variables resulting from command line parsing */ - -static gboolean store; -static gboolean rollback; -static gboolean change_location; -static gboolean rename_location; -static gboolean push_config; -static gboolean garbage_collect; - -static gboolean add_location; -static gboolean remove_location; -static gboolean add_backend; -static gboolean remove_backend; - -static gboolean global; -static const gchar *location_id; - -static gchar *backend_id; - -static gboolean compare_parent; -static gboolean mask_previous; - -static gchar *date_str; -static gboolean all; -static gchar *revision_id; -static gboolean last; -static guint steps; -static gboolean show; - -static gchar *parent_str; -static gchar *new_name; - -static gboolean contain_full; -static gboolean contain_partial; -static gboolean master; - -static struct poptOption archiver_operations[] = { - {"store", 's', POPT_ARG_NONE, &store, 0, - N_("Store XML data in the archive")}, - {"rollback", 'r', POPT_ARG_NONE, &rollback, 0, - N_("Roll back the configuration to a given point")}, - {"change-location", 'c', POPT_ARG_NONE, &change_location, 0, - N_("Change the location profile to the given one")}, - {"push-config", 'p', POPT_ARG_NONE, &push_config, 0, - N_("Push configuration data out to client machines (UNIMPLEMENTED)")}, - {"rename-location", '\0', POPT_ARG_NONE, &rename_location, 0, - N_("Rename a location to a new name")}, - {"add-location", '\0', POPT_ARG_NONE, &add_location, 0, - N_("Add a new location to the archive")}, - {"remove-location", '\0', POPT_ARG_NONE, &remove_location, 0, - N_("Remove a location from the archive")}, - {"add-backend", '\0', POPT_ARG_NONE, &add_backend, 0, - N_("Add a given backend to the given location")}, - {"remove-backend", '\0', POPT_ARG_NONE, &remove_backend, 0, - N_("Remove the given backend from the given location")}, - {"garbage-collect", '\0', POPT_ARG_NONE, &garbage_collect, 0, - N_("Perform garbage collection on the given location")}, - {NULL, '\0', 0, NULL, 0} -}; - -static struct poptOption global_options[] = { - {"global", 'g', POPT_ARG_NONE, &global, 0, - N_("Use the global repository")}, - {"location", 'l', POPT_ARG_STRING, &location_id, 0, - N_("Identifier of location profile on which to operate"), - N_("LOCATION")}, - {"backend", 'b', POPT_ARG_STRING, &backend_id, 0, - N_("Backend being used for this operation"), N_("BACKEND_ID")}, - {NULL, '\0', 0, NULL, 0} -}; - -static struct poptOption store_options[] = { - {"compare-parent", '\0', POPT_ARG_NONE, &compare_parent, 0, - N_("Store only the differences with the parent location's config")}, - {"mask-previous", '\0', POPT_ARG_NONE, &mask_previous, 0, - N_("Store only those settings set in the previous config")}, - {NULL, '\0', 0, NULL, 0} -}; - -static struct poptOption rollback_options[] = { - {"date", 'd', POPT_ARG_STRING, &date_str, 0, - N_("Date to which to roll back"), N_("DATE")}, - {"all", 'a', POPT_ARG_NONE, &all, 0, - N_("Roll back all configuration items")}, - {"revision-id", 'i', POPT_ARG_INT, &revision_id, 0, - N_("Roll back to the revision REVISION_ID"), N_("REVISION_ID")}, - {"last", 't', POPT_ARG_NONE, &last, 0, - N_("Roll back to the last known revision")}, - {"steps", '\0', POPT_ARG_INT, &steps, 0, - N_("Roll back by STEPS revisions"), N_("STEPS")}, - {"show", 'h', POPT_ARG_NONE, &show, 0, - N_("Don't run the backend, just dump the output")}, - {NULL, '\0', 0, NULL, 0} -}; - -static struct poptOption add_rename_location_options[] = { - {"parent", '\0', POPT_ARG_STRING, &parent_str, 0, - N_("Parent location for the new location"), N_("PARENT")}, - {"new-name", '\0', POPT_ARG_STRING, &new_name, 0, - N_("New name to assign to the location"), N_("NEW_NAME")}, - {NULL, '\0', 0, NULL, 0} -}; - -static struct poptOption add_remove_backend_options[] = { - {"master", '\0', POPT_ARG_NONE, &master, 0, - N_("Add/remove this backend to/from the master backend list")}, - {"full", '\0', POPT_ARG_NONE, &contain_full, 0, - N_("Full containment")}, - {"partial", '\0', POPT_ARG_NONE, &contain_partial, 0, - N_("Partial containment")}, - {NULL, '\0', 0, NULL, 0} -}; - -static xmlDocPtr -xml_load_from_stream (FILE *stream) -{ - GString *str; - gchar buffer[4097]; - xmlDocPtr doc; - size_t t; - - str = g_string_new (""); - - while (!feof (stream)) { - t = fread (buffer, sizeof (char), 4096, stream); - buffer[t] = '\0'; - g_string_append (str, buffer); - } - - doc = xmlParseDoc (str->str); - g_string_free (str, TRUE); - return doc; -} - -static ConfigArchiver_StringSeq * -make_backend_id_seq (gchar *backend_id, ...) -{ - ConfigArchiver_StringSeq *seq; - - seq = ConfigArchiver_StringSeq__alloc (); - seq->_length = 1; - seq->_buffer = CORBA_sequence_CORBA_string_allocbuf (1); - seq->_buffer[0] = CORBA_string_dup (backend_id); - - return seq; -} - -static void -do_store (ConfigArchiver_Location location, CORBA_Environment *ev) -{ - ConfigArchiver_StoreType type; - xmlDocPtr doc; - - if (!backend_id) { - fprintf (stderr, "No backend specified\n"); - return; - } - - if (mask_previous) - type = ConfigArchiver_STORE_MASK_PREVIOUS; - else if (compare_parent) - type = ConfigArchiver_STORE_COMPARE_PARENT; - else - type = ConfigArchiver_STORE_FULL; - - doc = xml_load_from_stream (stdin); - - location_client_store_xml (location, backend_id, doc, type, ev); -} - -static void -do_rollback (ConfigArchiver_Location location, CORBA_Environment *ev) -{ - struct tm *date = NULL; - ConfigArchiver_StringSeq *seq; - ConfigArchiver_Time tm; - xmlDocPtr doc; - - if (date_str) - date = parse_date (date_str); - else if (last || steps > 0) - date = NULL; - else if (!revision_id) { - fprintf (stderr, "No date specified\n"); - return; - } - - if (backend_id != NULL && (date != NULL || last)) { - /* FIXME: Need to support specifying multiple backends */ - if (show) { - doc = location_client_load_rollback_data (location, date, 0, backend_id, TRUE, ev); - xmlDocDump (stdout, doc); - xmlFreeDoc (doc); - } else { - tm = mktime (date); - seq = make_backend_id_seq (backend_id, NULL); - ConfigArchiver_Location_rollbackBackends (location, tm, 0, seq, TRUE, ev); - CORBA_free (seq); - } - } - else if (backend_id != NULL && steps != 0) { - if (show) { - doc = location_client_load_rollback_data (location, date, steps, backend_id, TRUE, ev); - xmlDocDump (stdout, doc); - xmlFreeDoc (doc); - } else { - seq = make_backend_id_seq (backend_id, NULL); - ConfigArchiver_Location_rollbackBackends (location, 0, steps, seq, TRUE, ev); - CORBA_free (seq); - } - } else { - g_message ("No backend specified\n"); - return; - } -} - -static void -do_change_location (ConfigArchiver_Archive archive, ConfigArchiver_Location location, CORBA_Environment *ev) -{ - ConfigArchiver_Archive__set_currentLocation (archive, location, ev); -} - -static void -do_rename_location (ConfigArchiver_Archive archive, ConfigArchiver_Location location, CORBA_Environment *ev) -{ - gboolean is_current; - CORBA_char *locid, *cid; - - if (new_name == NULL) { - fprintf (stderr, "You did not specify a new name. Try --help\n"); - } else { - locid = ConfigArchiver_Location__get_id (location, ev); - cid = ConfigArchiver_Archive__get_currentLocationId (archive, ev); - - if (!strcmp (locid, cid)) - is_current = TRUE; - else - is_current = FALSE; - - CORBA_free (locid); - CORBA_free (cid); - - ConfigArchiver_Location__set_id (location, new_name, ev); - - if (is_current) - ConfigArchiver_Archive__set_currentLocationId (archive, new_name, ev); - } -} - -static void -do_add_location (ConfigArchiver_Archive archive, CORBA_Environment *ev) -{ - ConfigArchiver_Location parent_location = CORBA_OBJECT_NIL; - - if (location_id == NULL) { - fprintf (stderr, "Error: You did not specify a location name\n"); - return; - } - - if (parent_str != NULL) { - parent_location = ConfigArchiver_Archive_getLocation (archive, parent_str, ev); - - if (parent_location == NULL && !strcmp (parent_str, "default")) - parent_location = - ConfigArchiver_Archive_createLocation (archive, "default", _("Default Location"), - CORBA_OBJECT_NIL, ev); - } - - ConfigArchiver_Archive_createLocation (archive, location_id, location_id, parent_location, ev); -} - -static void -do_remove_location (ConfigArchiver_Location location, CORBA_Environment *ev) -{ - ConfigArchiver_Location_delete (location, ev); -} - -static void -do_add_backend (ConfigArchiver_Location location, CORBA_Environment *ev) -{ - ConfigArchiver_ContainmentType type; - - if (contain_full && contain_partial) { - fprintf (stderr, "Error: Cannot have both full and partial " - "containment\n"); - return; - } - else if (contain_partial) { - type = ConfigArchiver_CONTAIN_PARTIAL; - } else { - type = ConfigArchiver_CONTAIN_FULL; - } - - ConfigArchiver_Location_addBackend (location, backend_id, type, ev); -} - -static void -do_remove_backend (ConfigArchiver_Location location, CORBA_Environment *ev) -{ - ConfigArchiver_Location_removeBackend (location, backend_id, ev); -} - -static void -do_garbage_collect (ConfigArchiver_Location location, CORBA_Environment *ev) -{ - ConfigArchiver_Location_garbageCollect (location, ev); -} - -int -main (int argc, char **argv) -{ - CORBA_ORB orb; - ConfigArchiver_Archive archive; - ConfigArchiver_Location location = CORBA_OBJECT_NIL; - CORBA_Environment ev; - - /* For Electric Fence */ - free (malloc (1)); - - bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); - bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); - textdomain (GETTEXT_PACKAGE); - - CORBA_exception_init (&ev); - - gnomelib_register_popt_table (global_options, - _("Global archiver options")); - gnomelib_register_popt_table (archiver_operations, - _("Archiver commands")); - gnomelib_register_popt_table (store_options, - _("Options for storing data")); - gnomelib_register_popt_table (rollback_options, - _("Options for rolling back")); - gnomelib_register_popt_table (add_rename_location_options, - _("Options for adding or renaming " \ - "locations")); - gnomelib_register_popt_table (add_remove_backend_options, - _("Options for adding and removing " \ - "backends")); - - gtk_type_init (); - gnomelib_init ("archiver", VERSION); - gnomelib_parse_args (argc, argv, 0); - - orb = oaf_init (argc, argv); - - if (bonobo_init (orb, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL) == FALSE) - g_error ("Cannot initialize Bonobo"); - - if (global) - archive = bonobo_get_object ("archive:global-archive", "IDL:ConfigArchiver/Archive:1.0", &ev); - else - archive = bonobo_get_object ("archive:user-archive", "IDL:ConfigArchiver/Archive:1.0", &ev); - - if (archive == CORBA_OBJECT_NIL) { - g_critical ("Could not open archive\n"); - return -1; - } - - if (!add_location) { - if (location_id == NULL) - location_id = ConfigArchiver_Archive__get_currentLocationId (archive, &ev); - - location = ConfigArchiver_Archive_getLocation (archive, location_id, &ev); - - if (location == CORBA_OBJECT_NIL) { - g_critical ("Error: Could not open location %s\n", location_id); - return -1; - } - } - - if (store) - do_store (location, &ev); - else if (rollback) - do_rollback (location, &ev); - else if (change_location) - do_change_location (archive, location, &ev); - else if (rename_location) - do_rename_location (archive, location, &ev); - else if (add_location) - do_add_location (archive, &ev); - else if (remove_location) - do_remove_location (location, &ev); - else if (add_backend) - do_add_backend (location, &ev); - else if (remove_backend) - do_remove_backend (location, &ev); - else if (garbage_collect) - do_garbage_collect (location, &ev); - - bonobo_object_release_unref (archive, NULL); - - if (location != CORBA_OBJECT_NIL) - bonobo_object_release_unref (location, NULL); - - return 0; -} diff --git a/archiver/config-log.c b/archiver/config-log.c deleted file mode 100644 index 2b08c0b61..000000000 --- a/archiver/config-log.c +++ /dev/null @@ -1,1071 +0,0 @@ -/* -*- mode: c; style: linux -*- */ - -/* config-log.c - * Copyright (C) 2000-2001 Ximian, Inc. - * - * Written by Bradford Hovinen (hovinen@ximian.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <unistd.h> -#include <fcntl.h> -#include <errno.h> -#include <ctype.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <sys/un.h> - -#include "config-log.h" -#include "location.h" -#include "util.h" - -static GtkObjectClass *parent_class; - -enum { - ARG_0, - ARG_LOCATION -}; - -typedef struct _ConfigLogEntry ConfigLogEntry; -typedef struct _Slave Slave; -typedef struct _IOBuffer IOBuffer; - -struct _ConfigLogEntry -{ - gint id; - struct tm *date; - gchar *backend_id; -}; - -struct _ConfigLogPrivate -{ - Location *location; - - FILE *file_stream; - char *filename; - gboolean deleted; - - GList *log_data; - GList *first_old; -}; - -static void config_log_init (ConfigLog *config_log); -static void config_log_class_init (ConfigLogClass *klass); - -static void config_log_set_arg (GtkObject *object, - GtkArg *arg, - guint arg_id); - -static void config_log_get_arg (GtkObject *object, - GtkArg *arg, - guint arg_id); - -static void config_log_destroy (GtkObject *object); -static void config_log_finalize (GtkObject *object); - -static GList *find_config_log_entry_id (ConfigLog *config_log, - GList *start, - gint id); -static GList *find_config_log_entry_date (ConfigLog *config_log, - GList *start, - struct tm *date); -static GList *find_config_log_entry_backend (ConfigLog *config_log, - GList *start, - const gchar *backend_id); - -static GList *load_log_entry (ConfigLog *config_log, - GList *last); - -static gboolean parse_line (char *buffer, - int *id, - struct tm *time, - char **backend_id); -static gboolean time_geq (struct tm *time1, - struct tm *time2); - -static gboolean do_load (ConfigLog *config_log); -static void do_unload (ConfigLog *config_log, - gboolean write_log); - -static gint get_next_id (ConfigLog *config_log); -static struct tm *get_beginning_of_time (void); -static struct tm *get_current_date (void); -static void write_log (FILE *output, - ConfigLogEntry *entry); -static void dump_log (ConfigLog *config_log); -static gboolean has_nondefaults (ConfigLog *config_log); - -static void config_log_entry_destroy (ConfigLogEntry *entry); - -static void dump_file (FILE *input, - FILE *output); - -GType -config_log_get_type (void) -{ - static GType config_log_type; - - if (!config_log_type) { - GtkTypeInfo config_log_info = { - "ConfigLog", - sizeof (ConfigLog), - sizeof (ConfigLogClass), - (GtkClassInitFunc) config_log_class_init, - (GtkObjectInitFunc) config_log_init, - (GtkArgSetFunc) NULL, - (GtkArgGetFunc) NULL - }; - - config_log_type = - gtk_type_unique (gtk_object_get_type (), - &config_log_info); - } - - return config_log_type; -} - -static void -config_log_init (ConfigLog *config_log) -{ - config_log->p = g_new0 (ConfigLogPrivate, 1); -} - -static void -config_log_class_init (ConfigLogClass *klass) -{ - GtkObjectClass *object_class; - - object_class = GTK_OBJECT_CLASS (klass); - - object_class->destroy = config_log_destroy; - object_class->finalize = config_log_finalize; - object_class->set_arg = config_log_set_arg; - object_class->get_arg = config_log_get_arg; - - gtk_object_add_arg_type ("ConfigLog::location", - GTK_TYPE_POINTER, - GTK_ARG_READWRITE, - ARG_LOCATION); - - parent_class = gtk_type_class (gtk_object_get_type ()); -} - -static void -config_log_set_arg (GtkObject *object, GtkArg *arg, guint arg_id) -{ - ConfigLog *config_log; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_CONFIG_LOG (object)); - g_return_if_fail (arg != NULL); - - config_log = CONFIG_LOG (object); - - switch (arg_id) { - case ARG_LOCATION: - g_return_if_fail (GTK_VALUE_POINTER (*arg) != NULL); - g_return_if_fail (IS_LOCATION (GTK_VALUE_POINTER (*arg))); - - config_log->p->location = GTK_VALUE_POINTER (*arg); - break; - - default: - break; - } -} - -static void -config_log_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) -{ - ConfigLog *config_log; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_CONFIG_LOG (object)); - g_return_if_fail (arg != NULL); - - config_log = CONFIG_LOG (object); - - switch (arg_id) { - case ARG_LOCATION: - GTK_VALUE_POINTER (*arg) = config_log->p->location; - break; - default: - arg->type = GTK_TYPE_INVALID; - break; - } -} - -/* Destroys a configuration log data structure and frees all memory - * associated with it, dumping the existing log out to disk - */ - -static void -config_log_destroy (GtkObject *object) -{ - ConfigLog *config_log; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_CONFIG_LOG (object)); - - config_log = CONFIG_LOG (object); - - do_unload (config_log, !config_log->p->deleted); - - GTK_OBJECT_CLASS (parent_class)->destroy (GTK_OBJECT (config_log)); -} - -/* Deallocates memory associated with a config log structure */ - -static void -config_log_finalize (GtkObject *object) -{ - ConfigLog *config_log; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_CONFIG_LOG (object)); - - config_log = CONFIG_LOG (object); - - g_free (config_log->p); - - GTK_OBJECT_CLASS (parent_class)->finalize (GTK_OBJECT (config_log)); -} - -/* Loads a configuration log. Creates it if it has not been created - * already - */ - -GtkObject * -config_log_open (Location *location) -{ - GtkObject *object; - - object = gtk_object_new (config_log_get_type (), - "location", location, - NULL); - - config_log_reset_filenames (CONFIG_LOG (object)); - do_load (CONFIG_LOG (object)); - - return object; -} - -/** - * config_log_delete: - * @config_log: - * - * Permanently destroy a config log, including its log file. Also destory the - * object - **/ - -void -config_log_delete (ConfigLog *config_log) -{ - g_return_if_fail (config_log != NULL); - g_return_if_fail (IS_CONFIG_LOG (config_log)); - - if (config_log->p->filename != NULL) - unlink (config_log->p->filename); - - do_unload (config_log, FALSE); - - config_log->p->deleted = TRUE; - gtk_object_destroy (GTK_OBJECT (config_log)); -} - -/* Return the id number of the most recent data written by the given - * backend prior to the given date. If date is NULL, it is assumed to - * be today. - */ - -gint -config_log_get_rollback_id_for_date (ConfigLog *config_log, - struct tm *date, - const gchar *backend_id) -{ - GList *node; - - g_return_val_if_fail (config_log != NULL, -1); - g_return_val_if_fail (IS_CONFIG_LOG (config_log), -1); - g_return_val_if_fail (backend_id != NULL, -1); - - if (config_log->p->log_data == NULL) - config_log->p->log_data = - load_log_entry (config_log, NULL); - - if (date == NULL) - node = config_log->p->log_data; - else - node = find_config_log_entry_date (config_log, - config_log->p->log_data, - date); - - node = find_config_log_entry_backend (config_log, node, backend_id); - - if (!node) - return -1; - else - return ((ConfigLogEntry *) node->data)->id; -} - -/* Return the rollback id that is the given number of steps back from the - * current revision, or -1 if there is no such id - */ - -gint -config_log_get_rollback_id_by_steps (ConfigLog *config_log, - guint steps, - const gchar *backend_id) -{ - GList *node; - - g_return_val_if_fail (config_log != NULL, -1); - g_return_val_if_fail (IS_CONFIG_LOG (config_log), -1); - g_return_val_if_fail (backend_id != NULL, -1); - - node = config_log->p->log_data; - - if (node == NULL) - node = load_log_entry (config_log, node); - - while (node != NULL && steps-- > 0) { - node = find_config_log_entry_backend - (config_log, node, backend_id); - - if (((ConfigLogEntry *) node->data)->date->tm_year == 0) - return ((ConfigLogEntry *) node->data)->id; - - if (steps > 0) { - if (node->next == NULL) - node = load_log_entry - (config_log, node); - else - node = node->next; - } - } - - if (node != NULL) - return ((ConfigLogEntry *) node->data)->id; - else - return -1; -} - -/* Return the backend that generated the data with the given id */ - -const gchar * -config_log_get_backend_id_for_id (ConfigLog *config_log, gint id) -{ - GList *node; - - g_return_val_if_fail (config_log != NULL, NULL); - g_return_val_if_fail (IS_CONFIG_LOG (config_log), NULL); - g_return_val_if_fail (id >= 0, NULL); - - if (config_log->p->log_data == NULL) - config_log->p->log_data = - load_log_entry (config_log, NULL); - - node = find_config_log_entry_id (config_log, - config_log->p->log_data, id); - - if (!node) - return NULL; - else - return ((ConfigLogEntry *) node->data)->backend_id; -} - -/* Return the date the data with the given id was written */ - -const struct tm * -config_log_get_date_for_id (ConfigLog *config_log, gint id) -{ - GList *node; - - g_return_val_if_fail (config_log != NULL, NULL); - g_return_val_if_fail (IS_CONFIG_LOG (config_log), NULL); - g_return_val_if_fail (id >= 0, NULL); - - if (config_log->p->log_data == NULL) - config_log->p->log_data = - load_log_entry (config_log, NULL); - - node = find_config_log_entry_id (config_log, - config_log->p->log_data, id); - - if (!node) - return NULL; - else - return ((ConfigLogEntry *) node->data)->date; -} - -/** - * config_log_write_entry: - * @config_log: - * @backend_id: Backend id for the log entry to write - * @is_default_data: TRUE iff the corresponding data are to be considered - * "factory defaults" for the purpose of rollback - * - * Writes a new log entry to the config log - * - * Returns the id number of the entry on success or -1 on failure - **/ - -gint -config_log_write_entry (ConfigLog *config_log, - const gchar *backend_id, - gboolean is_default_data) -{ - ConfigLogEntry *entry; - - g_return_val_if_fail (config_log != NULL, -1); - g_return_val_if_fail (IS_CONFIG_LOG (config_log), -1); - g_return_val_if_fail (backend_id != NULL, -1); - - if (is_default_data && has_nondefaults (config_log)) - return -1; - - entry = g_new0 (ConfigLogEntry, 1); - entry->id = get_next_id (config_log); - entry->backend_id = g_strdup (backend_id); - - if (is_default_data) - entry->date = get_beginning_of_time (); - else - entry->date = get_current_date (); - - config_log->p->log_data = - g_list_prepend (config_log->p->log_data, entry); - - dump_log (config_log); - - return entry->id; -} - -/** - * config_log_iterate: - * @config_log: - * @callback: - * @data: - * - * Iterate through all log entries an invoke the given callback on each one, - * passing the id, date created, and backend id to it - **/ - -void -config_log_iterate (ConfigLog *config_log, ConfigLogIteratorCB callback, - gpointer data) -{ - GList *node; - ConfigLogEntry *entry; - - g_return_if_fail (config_log != NULL); - g_return_if_fail (IS_CONFIG_LOG (config_log)); - g_return_if_fail (callback != NULL); - - node = config_log->p->log_data; - while (node != NULL) { - entry = (ConfigLogEntry *) node->data; - if (callback (config_log, entry->id, entry->backend_id, - entry->date, data)) break; - - if (node->next == NULL) - node = load_log_entry (config_log, node); - else - node = node->next; - } -} - -/** - * config_log_reset_filenames: - * @config_log: - * - * Rereads the log's location data to determine filenames - **/ - -void -config_log_reset_filenames (ConfigLog *config_log) -{ - g_return_if_fail (config_log != NULL); - g_return_if_fail (IS_CONFIG_LOG (config_log)); - - if (config_log->p->filename != NULL) - g_free (config_log->p->filename); - - config_log->p->filename = - g_concat_dir_and_file (location_get_path - (config_log->p->location), - "config.log"); -} - -/** - * config_log_reload: - * @config_log: - * - * Reloads the entire config log, throwing out any newly created entries - **/ - -void -config_log_reload (ConfigLog *config_log) -{ - g_return_if_fail (config_log != NULL); - g_return_if_fail (IS_CONFIG_LOG (config_log)); - - do_unload (config_log, FALSE); - config_log_reset_filenames (config_log); - do_load (config_log); -} - -/** - * config_log_garbage_collect: - * @config_log: - * @backend_id: Backend on which to iterate - * @callback: Callback to issue on any log entry to be culled - * @data: Arbitrary data to pass to callback - * - * Iterates through the configuration log and culls excess entries for the given - * backend. - * - * The algorithm we use is the following: We scan entries in temporal order. For - * each consecutive pair of entries, let t1 be the time at which the former was - * made and t2 be the time of the latter. If K_CONST * (t2 - t1) < t2, then we - * delete the former entry and issue the callback. We select K_CONST - * appropriately, i.e. a user will likely not want to keep entries separated by - * under five minutes for very long, while she may want to keep entries - * separated by two weeks for much longer. - */ - -#define K_CONST 15 - -void -config_log_garbage_collect (ConfigLog *config_log, - gchar *backend_id, - GarbageCollectCB callback, - gpointer data) -{ - GList *node, *list = NULL; - ConfigLogEntry *e1, *e2; - time_t t1, t2, now; - struct tm now_b, *tmp_date; - - g_return_if_fail (config_log != NULL); - g_return_if_fail (IS_CONFIG_LOG (config_log)); - - if (config_log->p->log_data == NULL) - config_log->p->log_data = - load_log_entry (config_log, NULL); - - node = config_log->p->log_data; - - /* We build a list of config log nodes to facilitate removing the nodes - * from the main cache at a later point - */ - - while (1) { - node = find_config_log_entry_backend - (config_log, node, backend_id); - - if (node == NULL) - break; - - list = g_list_prepend (list, node); - node = node->next; - } - - if (list == NULL) return; - - now = time (NULL); - gmtime_r (&now, &now_b); - now = mktime (&now_b); - - for (node = list; node->next != NULL; node = node->next) { - e1 = ((GList *) node->data)->data; - e2 = ((GList *) node->next->data)->data; - - tmp_date = dup_date (e1->date); - t1 = mktime (tmp_date); - g_free (tmp_date); - - tmp_date = dup_date (e2->date); - t2 = mktime (tmp_date); - g_free (tmp_date); - - if (now < t2 || now < t1) - g_warning ("Log entry is in the future!"); - if (t1 > t2) - g_warning ("Log entries are out of order!"); - - if (K_CONST * difftime (t2, t1) < difftime (now, t2)) { - config_log->p->log_data = - g_list_remove_link (config_log->p->log_data, node->data); - callback (config_log, backend_id, e1->id, data); - } - } - - g_list_free (list); - - config_log->p->first_old = NULL; -} - -/* Find the config log entry with the id given, starting at the given - * node. Return a pointer to the node. - */ - -static GList * -find_config_log_entry_id (ConfigLog *config_log, GList *start, gint id) -{ - GList *last; - ConfigLogEntry *entry; - - g_return_val_if_fail (config_log != NULL, NULL); - g_return_val_if_fail (IS_CONFIG_LOG (config_log), NULL); - g_return_val_if_fail (id >= 0, NULL); - - if (!start) return NULL; - - while (start != NULL) { - last = start; - entry = (ConfigLogEntry *) start->data; - if (entry->id == id) - return start; - else if (entry->id < id) - return NULL; - start = start->next; - } - - while (1) { - start = load_log_entry (config_log, last); - if (start == NULL) return NULL; - entry = (ConfigLogEntry *) start->data; - if (entry->id == id) - return start; - else if (entry->id < id) - return NULL; - } - - return NULL; -} - -/* Find the first config log entry made prior to the given date, - * starting at the given node. Return a pointer to the node. - */ - -static GList * -find_config_log_entry_date (ConfigLog *config_log, GList *start, - struct tm *date) -{ - GList *last; - ConfigLogEntry *entry; - - g_return_val_if_fail (config_log != NULL, NULL); - g_return_val_if_fail (IS_CONFIG_LOG (config_log), NULL); - g_return_val_if_fail (date != NULL, NULL); - - if (!start) return NULL; - - while (start != NULL) { - last = start; - entry = (ConfigLogEntry *) start->data; - if (time_geq (date, entry->date)) - return start; - start = start->next; - } - - while (1) { - start = load_log_entry (config_log, last); - if (start == NULL) return NULL; - entry = (ConfigLogEntry *) start->data; - if (time_geq (date, entry->date)) - return start; - } - - return NULL; -} - -/* Find the first config log entry made by the given backend, - * starting at the given node. Return a pointer to the node. - */ - -static GList * -find_config_log_entry_backend (ConfigLog *config_log, - GList *start, - const gchar *backend_id) -{ - GList *last; - ConfigLogEntry *entry; - - g_return_val_if_fail (config_log != NULL, NULL); - g_return_val_if_fail (IS_CONFIG_LOG (config_log), NULL); - g_return_val_if_fail (backend_id != NULL, NULL); - - if (!start) return NULL; - - while (start != NULL) { - last = start; - entry = (ConfigLogEntry *) start->data; - if (!strcmp (entry->backend_id, backend_id)) - return start; - start = start->next; - } - - while (1) { - start = load_log_entry (config_log, last); - if (start == NULL) return NULL; - entry = (ConfigLogEntry *) start->data; - if (!strcmp (entry->backend_id, backend_id)) - return start; - } - - return NULL; -} - -/* Loads a log entry from the given file and attaches it to the end of the config log */ - -static GList * -load_log_entry (ConfigLog *config_log, - GList *last) -{ - gchar *backend_id; - gchar buffer[1024]; - ConfigLogEntry *entry; - gboolean success; - - g_return_val_if_fail (config_log != NULL, NULL); - g_return_val_if_fail (IS_CONFIG_LOG (config_log), NULL); - - if (config_log->p->file_stream == NULL || feof (config_log->p->file_stream)) - return NULL; - - if (fgets (buffer, 1024, config_log->p->file_stream) == NULL) - return NULL; - - entry = g_new0 (ConfigLogEntry, 1); - entry->date = g_new0 (struct tm, 1); - success = parse_line (buffer, &entry->id, - entry->date, &backend_id); - - if (success) { - entry->backend_id = g_strdup (backend_id); - - last = g_list_append (last, entry); - - if (config_log->p->log_data == NULL) - config_log->p->log_data = last; - - if (config_log->p->first_old == NULL) - config_log->p->first_old = last; - - return g_list_find (last, entry); - } else { - g_free (entry->date); - g_free (entry); - return NULL; - } -} - -/* Parse a line from the log file. All pointers must be valid. - * - * Note: backend just points to somewhere in buffer, so it becomes - * invalid the next time the buffer is overwritten. If there's a - * trailing newline, it is not chopped off. - * - * Returns TRUE on success and FALSE on parse error; if FALSE is - * returned, the values placed in the variables given are undefined. - */ - -static gboolean -parse_line (char *buffer, int *id, struct tm *date, char **backend_id) -{ - unsigned int len; - - sscanf (buffer, "%x", id); - - while (isxdigit (*buffer)) buffer++; - - if (!isspace (*buffer) || !isdigit (*(buffer + 1))) return FALSE; - buffer++; - - if (extract_number (&buffer, &date->tm_year, 4) == FALSE) - return FALSE; - if (extract_number (&buffer, &date->tm_mon, 2) == FALSE) - return FALSE; - if (extract_number (&buffer, &date->tm_mday, 2) == FALSE) - return FALSE; - - date->tm_year -= 1900; - date->tm_mon--; - - if (!isspace (*buffer) || !isdigit (*(buffer + 1))) return FALSE; - buffer++; - - if (extract_number (&buffer, &date->tm_hour, 2) == FALSE) - return FALSE; - if (*buffer != ':') return FALSE; buffer++; - if (extract_number (&buffer, &date->tm_min, 2) == FALSE) - return FALSE; - if (*buffer != ':') return FALSE; buffer++; - if (extract_number (&buffer, &date->tm_sec, 2) == FALSE) - return FALSE; - -#ifdef __USE_BSD - date->tm_gmtoff = 0; - date->tm_zone = "GMT"; -#endif - - if (!isspace (*buffer) || *(buffer + 1) == '\0') return FALSE; - buffer++; - - len = strlen (buffer); - if (buffer[len - 1] == '\n') - buffer[len - 1] = '\0'; - - *backend_id = buffer; - - return TRUE; -} - -/* Return TRUE if the first given struct tm is greater than or equal - * to the second given struct tm; FALSE otherwise - */ - -static gboolean -time_geq (struct tm *time1, struct tm *time2) -{ - if (time1->tm_year > time2->tm_year) return TRUE; - if (time1->tm_year < time2->tm_year) return FALSE; - if (time1->tm_mon > time2->tm_mon) return TRUE; - if (time1->tm_mon < time2->tm_mon) return FALSE; - if (time1->tm_mday > time2->tm_mday) return TRUE; - if (time1->tm_mday < time2->tm_mday) return FALSE; - if (time1->tm_hour > time2->tm_hour) return TRUE; - if (time1->tm_hour < time2->tm_hour) return FALSE; - if (time1->tm_min > time2->tm_min) return TRUE; - if (time1->tm_min < time2->tm_min) return FALSE; - if (time1->tm_sec >= time2->tm_sec) return TRUE; - return FALSE; -} - -/* Opens up a configuration log. Assumes all the structures are - * already initialized. Creates the log if not already done. - * - * Returns TRUE on success and FALSE on failure (unable to open output - * file) - */ - -static gboolean -do_load (ConfigLog *config_log) -{ - g_return_val_if_fail (config_log != NULL, FALSE); - g_return_val_if_fail (IS_CONFIG_LOG (config_log), FALSE); - - config_log->p->file_stream = fopen (config_log->p->filename, "r"); - config_log->p->first_old = NULL; - - return TRUE; -} - -/* Closes the input file for a given log and dumps and clears the - * cache - */ - -static void -do_unload (ConfigLog *config_log, gboolean write_log) -{ - g_return_if_fail (config_log != NULL); - g_return_if_fail (IS_CONFIG_LOG (config_log)); - - if (config_log->p->deleted) return; - - if (write_log) dump_log (config_log); - - if (config_log->p->file_stream) { - fclose (config_log->p->file_stream); - config_log->p->file_stream = NULL; - } - - if (config_log->p->filename) { - g_free (config_log->p->filename); - config_log->p->filename = NULL; - } - - g_list_foreach (config_log->p->log_data, (GFunc) config_log_entry_destroy, NULL); - g_list_free (config_log->p->log_data); - config_log->p->log_data = NULL; -} - -/* Returns the next id number in the sequence */ - -static gint -get_next_id (ConfigLog *config_log) -{ - if (config_log->p->log_data == NULL) { - if (load_log_entry (config_log, NULL) == NULL) - return 0; - } - - return ((ConfigLogEntry *) config_log->p->log_data->data)->id + 1; -} - -/* Return a newly allocated struct tm with all zeros */ - -static struct tm * -get_beginning_of_time (void) -{ - return g_new0 (struct tm, 1); -} - -/* Return a newly allocated struct tm with the current time */ - -static struct tm * -get_current_date (void) -{ - time_t current_time; - struct tm time_2, *time_1 = &time_2, *ret; - - current_time = time (NULL); - gmtime_r (¤t_time, time_1); - ret = g_new (struct tm, 1); - memcpy (ret, time_1, sizeof (struct tm)); - return ret; -} - -/* Write out a single log entry */ - -static void -write_log (FILE *output, ConfigLogEntry *entry) -{ - g_return_if_fail (output != NULL); - g_return_if_fail (entry != NULL); - g_return_if_fail (entry->id >= 0); - g_return_if_fail (entry->date != NULL); - g_return_if_fail (entry->backend_id != NULL); - - fprintf (output, "%08x %04d%02d%02d %02d:%02d:%02d %s\n", - entry->id, entry->date->tm_year + 1900, - entry->date->tm_mon + 1, entry->date->tm_mday, - entry->date->tm_hour, entry->date->tm_min, - entry->date->tm_sec, entry->backend_id); -} - -/* Writes out the entire current configuration log to the disk */ - -static void -dump_log (ConfigLog *config_log) -{ - char *filename_out; - GList *first; - FILE *input, *output; - - 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); - g_return_if_fail (IS_LOCATION (config_log->p->location)); - g_return_if_fail (location_get_path (config_log->p->location) != NULL); - - if (config_log->p->deleted) return; - - filename_out = g_concat_dir_and_file (location_get_path - (config_log->p->location), - "config.log.out"); - - output = fopen (filename_out, "w"); - - if (output == NULL) { - g_critical ("Could not open output file: %s", - g_strerror (errno)); - return; - } - - for (first = config_log->p->log_data; - first != config_log->p->first_old; - first = first->next) - write_log (output, first->data); - - if (config_log->p->file_stream != NULL && - ((config_log->p->first_old == NULL && config_log->p->log_data == NULL) || - (config_log->p->first_old != NULL && config_log->p->log_data != NULL))) - { - input = fopen (config_log->p->filename, "r"); - dump_file (input, output); - fclose (input); - } - - config_log->p->first_old = config_log->p->log_data; - - fclose (output); - - if (config_log->p->filename) - rename (filename_out, config_log->p->filename); -} - -/* Return TRUE if the config log has entries made by actual configuration - * changes, as opposed to default values placed there when the location was - * initialized - */ - -static gboolean -has_nondefaults (ConfigLog *config_log) -{ - ConfigLogEntry *first; - - if (config_log->p->log_data == NULL) - load_log_entry (config_log, config_log->p->log_data); - - if (config_log->p->log_data == NULL) - return FALSE; - - first = config_log->p->log_data->data; - - if (first->date->tm_year == 0) - return FALSE; - else - return TRUE; -} - -/* Deallocates the given config log entry structure */ - -static void -config_log_entry_destroy (ConfigLogEntry *entry) -{ - g_return_if_fail (entry != NULL); - g_return_if_fail (entry->date != NULL); - g_return_if_fail (entry->backend_id != NULL); - - g_free (entry->date); - g_free (entry->backend_id); - g_free (entry); -} - -/* Dumps the entire contents from one stream into another */ - -static void -dump_file (FILE *input, FILE *output) -{ - char buffer[4096]; - size_t len; - - g_return_if_fail (input != NULL); - g_return_if_fail (output != NULL); - - while (!feof (input)) { - len = fread (buffer, sizeof (char), 4096, input); - fwrite (buffer, sizeof (char), len, output); - } -} diff --git a/archiver/config-log.h b/archiver/config-log.h deleted file mode 100644 index aed9c8205..000000000 --- a/archiver/config-log.h +++ /dev/null @@ -1,90 +0,0 @@ -/* -*- mode: c; style: linux -*- */ - -/* config-log.h - * Copyright (C) 2000-2001 Ximian, Inc. - * - * Written by Bradford Hovinen (hovinen@ximian.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#ifndef __CONFIG_LOG_H -#define __CONFIG_LOG_H - -#include <gnome.h> -#include <stdio.h> -#include <time.h> - -#define CONFIG_LOG(obj) GTK_CHECK_CAST (obj, config_log_get_type (), ConfigLog) -#define CONFIG_LOG_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, config_log_get_type (), ConfigLogClass) -#define IS_CONFIG_LOG(obj) GTK_CHECK_TYPE (obj, config_log_get_type ()) - -typedef struct _ConfigLog ConfigLog; -typedef struct _ConfigLogClass ConfigLogClass; -typedef struct _ConfigLogPrivate ConfigLogPrivate; - -typedef struct _Location Location; - -typedef gint (*ConfigLogIteratorCB) (ConfigLog *, gint, gchar *, - struct tm *, gpointer); -typedef void (*GarbageCollectCB) (ConfigLog *, gchar *, gint, gpointer); - -struct _ConfigLog -{ - GtkObject object; - - ConfigLogPrivate *p; -}; - -struct _ConfigLogClass -{ - GtkObjectClass parent; -}; - -GType config_log_get_type (void); - -GtkObject *config_log_open (Location *location); -void config_log_delete (ConfigLog *config_log); - -gint config_log_get_rollback_id_for_date (ConfigLog *config_log, - struct tm *date, - const gchar *backend_id); -gint config_log_get_rollback_id_by_steps (ConfigLog *config_log, - guint steps, - const gchar *backend_id); - -const gchar *config_log_get_backend_id_for_id (ConfigLog *config_log, - gint id); -const struct tm *config_log_get_date_for_id (ConfigLog *config_log, - gint id); - -gint config_log_write_entry (ConfigLog *config_log, - const gchar *backend_id, - gboolean is_default_data); - -void config_log_iterate (ConfigLog *config_log, - ConfigLogIteratorCB callback, - gpointer data); - -void config_log_reset_filenames (ConfigLog *config_log); -void config_log_reload (ConfigLog *config_log); - -void config_log_garbage_collect (ConfigLog *config_log, - gchar *backend_id, - GarbageCollectCB callback, - gpointer data); - -#endif /* __CONFIG_LOG */ diff --git a/archiver/config-manager.c b/archiver/config-manager.c deleted file mode 100644 index 9b93839fe..000000000 --- a/archiver/config-manager.c +++ /dev/null @@ -1,54 +0,0 @@ -/* -*- mode: c; style: linux -*- */ - -/* config-manager.c - * Copyright (C) 2000-2001 Ximian, Inc. - * - * Written by Bradford Hovinen <hovinen@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <gnome.h> -#include <glade/glade.h> - -#include "config-manager-dialog.h" - -int -main (int argc, char **argv) -{ - GtkWidget *dialog; - - bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); - bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); - textdomain (GETTEXT_PACKAGE); - - gnome_init ("config-manager", VERSION, argc, argv); - glade_gnome_init (); - - dialog = config_manager_dialog_new (CM_DIALOG_USER_ONLY); - gtk_widget_show (dialog); - - gtk_signal_connect (GTK_OBJECT (dialog), "destroy", - gtk_main_quit, NULL); - - gtk_main (); - - return 0; -} diff --git a/archiver/config_archiverConf.sh.in b/archiver/config_archiverConf.sh.in deleted file mode 100644 index 0439c58d9..000000000 --- a/archiver/config_archiverConf.sh.in +++ /dev/null @@ -1,4 +0,0 @@ -CONFIG_ARCHIVER_LIBDIR="@CONFIG_ARCHIVER_LIBDIR@" -CONFIG_ARCHIVER_LIBS="@CONFIG_ARCHIVER_LIBS@" -CONFIG_ARCHIVER_INCLUDEDIR="@CONFIG_ARCHIVER_INCLUDEDIR@" -MODULE_VERSION="config-archiver-@VERSION@"
\ No newline at end of file diff --git a/archiver/default-global.xml b/archiver/default-global.xml deleted file mode 100644 index 0fe6fdeef..000000000 --- a/archiver/default-global.xml +++ /dev/null @@ -1,13 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1"?> - -<location> - <contains backend="boot-conf"/> - <contains backend="disks-conf"/> - <contains backend="memory-conf"/> - <contains backend="network-conf"/> - <contains backend="print-conf"/> - <contains backend="shares-conf"/> - <contains backend="time-conf"/> - <contains backend="users-conf"/> - <contains backend="display-conf"/> -</location> diff --git a/archiver/default-user.xml b/archiver/default-user.xml deleted file mode 100644 index 11472d498..000000000 --- a/archiver/default-user.xml +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1"?> - -<location> - <contains backend="background-properties"/> - <contains backend="bell-properties-capplet"/> - <contains backend="sound-properties"/> - <contains backend="keyboard-properties"/> - <contains backend="mouse-properties"/> - <contains backend="screensaver-properties-capplet"/> -</location> diff --git a/archiver/future-spec b/archiver/future-spec deleted file mode 100644 index 316fd1453..000000000 --- a/archiver/future-spec +++ /dev/null @@ -1,95 +0,0 @@ -Changes to the Helix Configuration Manager -Copyright (C) 2000 Ximian, Inc. -Written by Bradford Hovinen <hovinen@ximian.com> - -As it stands, capplets and Ximian Setup Tools are both run as separate -processes through the exec() facility. It is planned that the capplets -shall become Bonobo controls in the future, once the OAF/gnorba -compatibility problems are worked out. This changes the design of the -configuration system considerably, and several things should be done -to take full advantage of these changes. - -1. Capplets become Bonobo controls - -It stands to reason that the front ends for Ximian Setup Tools should -become Bonobo controls at the same time as capplets. They can each -implement the same interface (say, Bonobo::Capplet) with methods -getXML(), setXML(), ok(), cancel(), and init() and hence look the same -to the shell. This means that the front ends for the Ximian Setup Tools -run as the same user as XCM and respond in the same way as capplets do -to requests to embed them in the XCM shell window. This is essential -for a consistent user interface that will not result in end-user -confusion [1]. XCM itself may then export an interface that includes -the method runBackend(), to which the frontend supplies a stream of -XML that XCM passes through the root manager to the backend via a -standard pipe [2]. The backend is then responsible for running the -program that archives the XML -- there is no other way to place that -XML in a central, system-wide repository. I suggest, therefore, that -we modify the design of the current system to make that change, so -that we do not have to undo existing work later. - -2. Backends get CORBA interfaces through Perl/ORBit - -At this point, there must be a way for the root manager to forward -CORBA sockets to the user securely. This could be done by modifying -ORBit so as to give the running program very precise control over the -nature of the socket. Access could be granted specifically to the user -running the root manager by placing the socket in a directory owned by -that user with permissions no more lax than 0700. When the CORBA -interfaces are created, applications will be able to make use of it to -make system-wide changes as necessary (say, to add a new user during -the installation of a piece of software). This means that the -traditional rollback facilities must be extended to allow users to -roll back changes made by applications. In addition, the application -must treat the backend as a black box -- it should never be expected -to do anything unusual to support rollback, since buggy or -poorly-written applications would otherwise cause trouble for -unsuspecting users. - -At this point I suggest that each backend export two interfaces: one -that is universal to all backends and one that is specific to that -particular tool. The former may include the methods getXML(), -setXML(), and commit(). When changes are made through the -tool-specific interface, the tool decides whether or not to apply -those changes immediately or to queue them up until a commit() is -invoked. If changes are made through the backend's CORBA interface and -it is deactivated before a commit(), the backend must roll back those -changes under the assumption that they are not intended to be -permanent. - -Of course, this makes implementation of the cancel() interface on the -frontends very easy -- simply deactivate the backend without -commit()ing. ok() can be implemented by flushing any remaining -changes, calling commit(), and then deactivating the backend. The -frontend can and should use the CORBA interface to invoke changes -whenever they are made, as long as it makes sense. It is then the -backend that sets the policy of whether or not the updates are live, -as described above. The frontend must still be able to read XML, -though, since it is through that that it will get an initial -description of the setup with which to fill in the dialog. In -addition, since the frontend may be invoked to make changes to an -inactive location, it should be able to write out an XML description -of the dialog's contents so that those changes may be archived rather -than applied immediately. - -Notes - -[1] A visual cue that signals to the user that he is running a -system-wide configuration tool rather than a personal one would be -advantageous. Such could take the form of an icon on the dialog, a -layout or formatting convention for the dialog proper, or some sort of -coloring convention of some of the controls. However, simply having -the tool run with root's Gtk+ theme and ignoring the embedding -preference, as would be the case if we do not Bonobize the HST -frontends, is inconsistent as many users will leave their themes as -the default and elect not to embed capplets -- eliminating all visual -cues. In addition, it is not particularly lucid and many users will -merely be confused by the inconsistent interface. One may imagine many -users filing bug reports in the belief that the behavior is -erroneous. Hence, that solution is insufficient. - -[2] There must then be a method of multiplexing I/O throught the root -manager, as there may be multiple backends running concurrently. A -simple protocol could be implemented to do this, or a named pipe could -be created if done very carefully as to ensure a high degree of -security. diff --git a/archiver/location.c b/archiver/location.c deleted file mode 100644 index a39f21bd5..000000000 --- a/archiver/location.c +++ /dev/null @@ -1,1889 +0,0 @@ -/* -*- mode: c; style: linux -*- */ - -/* location.c - * Copyright (C) 2000-2001 Ximian, Inc. - * - * Written by Bradford Hovinen (hovinen@ximian.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <stdio.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <fcntl.h> -#include <unistd.h> -#include <tree.h> -#include <parser.h> -#include <errno.h> -#include <signal.h> - -#include "location.h" -#include "archive.h" -#include "util.h" -#include "archiver-client.h" - -static BonoboXObjectClass *parent_class; - -enum { - ARG_0, - ARG_LOCID, - ARG_LABEL, - ARG_ARCHIVE, - ARG_INHERITS -}; - -/* Note about backend containment in this location */ - -typedef struct _BackendNote BackendNote; - -struct _BackendNote -{ - gchar *backend_id; - ContainmentType type; -}; - -struct _LocationPrivate -{ - Archive *archive; - gchar *locid; - gchar *fullpath; - gchar *label; - - Location *parent; - GList *contains_list; /* List of BackendNotes */ - gboolean is_new; - gboolean contains_list_dirty; - gboolean deleted; - - ConfigLog *config_log; - - BonoboEventSource *es; -}; - -#define LOCATION_FROM_SERVANT(servant) (LOCATION (bonobo_object_from_servant (servant))) - -static void location_init (Location *location); -static void location_class_init (LocationClass *klass); - -static void location_set_arg (GtkObject *object, - GtkArg *arg, - guint arg_id); - -static void location_get_arg (GtkObject *object, - GtkArg *arg, - guint arg_id); - -static void location_destroy (GtkObject *object); -static void location_finalize (GtkObject *object); - -static gboolean location_do_rollback (Location *location, - gchar *backend_id, - xmlDocPtr xml_doc); - -static gint get_backends_cb (BackendList *backend_list, - gchar *backend_id, - Location *location); - -static gboolean do_create (Location *location); -static gboolean do_load (Location *location); -static gboolean load_metadata_file (Location *location, - char *filename, - gboolean is_default); -static void save_metadata (Location *location); -static void write_metadata_file (Location *location, - gchar *filename); - -static gint run_backend_proc (gchar *backend_id, - gboolean do_get, - pid_t *pid); - -static BackendNote *backend_note_new (const gchar *backend_id, - ContainmentType type); -static void backend_note_destroy (BackendNote *note); -static const BackendNote *find_note (Location *location, - const gchar *backend_id); - -static GList *create_backends_list (Location *location1, - Location *location2); -static GList *merge_backend_lists (GList *backends1, - GList *backends2); - -/* CORBA interface methods */ - -static CORBA_char * -impl_ConfigArchiver_Location_getStorageFilename (PortableServer_Servant servant, - const CORBA_char *backendId, - CORBA_boolean isDefaultData, - CORBA_Environment *ev) -{ - gchar *filename; - CORBA_char *ret; - - filename = location_get_storage_filename (LOCATION_FROM_SERVANT (servant), backendId, isDefaultData); - ret = CORBA_string_dup (filename); - g_free (filename); - - return ret; -} - -static CORBA_char * -impl_ConfigArchiver_Location_getRollbackFilename (PortableServer_Servant servant, - ConfigArchiver_Time timep, - CORBA_long steps, - const CORBA_char *backendId, - CORBA_boolean parentChain, - CORBA_Environment *ev) -{ - gchar *filename; - CORBA_char *ret; - struct tm timeb, *timeb_p = &timeb; - - if (timep != 0) - gmtime_r ((time_t *) &timep, timeb_p); - else - timeb_p = NULL; - - filename = location_get_rollback_filename (LOCATION_FROM_SERVANT (servant), timeb_p, steps, backendId, parentChain); - - if (filename != NULL) { - ret = CORBA_string_dup (filename); - g_free (filename); - } else { - ret = NULL; - bonobo_exception_set (ev, ex_ConfigArchiver_Location_RollbackDataNotFound); - } - - return ret; -} - -static void -impl_ConfigArchiver_Location_storageComplete (PortableServer_Servant servant, - const CORBA_char *filename, - CORBA_Environment *ev) -{ - location_storage_complete (LOCATION_FROM_SERVANT (servant), filename); -} - -static void -impl_ConfigArchiver_Location_rollbackBackends (PortableServer_Servant servant, - ConfigArchiver_Time timep, - CORBA_long steps, - const ConfigArchiver_StringSeq *backends, - CORBA_boolean parentChain, - CORBA_Environment *ev) -{ - GList *node = NULL; - unsigned int i; - struct tm timeb, *timeb_p = &timeb; - - for (i = 0; i < backends->_length; i++) - node = g_list_prepend (node, backends->_buffer[i]); - - if (timep != 0) - gmtime_r ((time_t *) &timep, &timeb); - else - timeb_p = NULL; - - location_rollback_backends_to (LOCATION_FROM_SERVANT (servant), timeb_p, steps, node, parentChain); - - g_list_free (node); -} - -static ConfigArchiver_Time -impl_ConfigArchiver_Location_getModificationTime (PortableServer_Servant servant, - const CORBA_char *backendId, - CORBA_Environment *ev) -{ - const struct tm *time_s; - struct tm *tmp_date; - ConfigArchiver_Time ret; - - time_s = location_get_modification_time (LOCATION_FROM_SERVANT (servant), backendId); - - if (time_s != NULL) { - tmp_date = dup_date (time_s); - ret = mktime (tmp_date); - g_free (tmp_date); - } else { - ret = 0; - } - - return ret; -} - -static ConfigArchiver_ContainmentType -impl_ConfigArchiver_Location_contains (PortableServer_Servant servant, - const CORBA_char *backendId, - CORBA_Environment *ev) -{ - return location_contains (LOCATION_FROM_SERVANT (servant), backendId); -} - -static CORBA_long -impl_ConfigArchiver_Location_addBackend (PortableServer_Servant servant, - const CORBA_char *backendId, - ConfigArchiver_ContainmentType containmentType, - CORBA_Environment *ev) -{ - return location_add_backend (LOCATION_FROM_SERVANT (servant), backendId, containmentType); -} - -static void -impl_ConfigArchiver_Location_removeBackend (PortableServer_Servant servant, - const CORBA_char *backendId, - CORBA_Environment *ev) -{ - location_remove_backend (LOCATION_FROM_SERVANT (servant), backendId); -} - -static CORBA_boolean -impl_ConfigArchiver_Location_doesBackendChange (PortableServer_Servant servant, - ConfigArchiver_Location location, - const CORBA_char *backendId, - CORBA_Environment *ev) -{ - Location *loc1, *loc2; - - loc1 = LOCATION_FROM_SERVANT (servant); - loc2 = LOCATION_FROM_SERVANT (location->servant); - - return location_does_backend_change (loc1, loc2, backendId); -} - -static void -impl_ConfigArchiver_Location_garbageCollect (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - location_garbage_collect (LOCATION_FROM_SERVANT (servant)); -} - -static void -impl_ConfigArchiver_Location_delete (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - location_delete (LOCATION_FROM_SERVANT (servant)); -} - -static ConfigArchiver_Location -impl_ConfigArchiver_Location__get_parent (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - Location *location = LOCATION_FROM_SERVANT (servant); - - if (location->p->parent != NULL) - return bonobo_object_dup_ref (BONOBO_OBJREF (location->p->parent), ev); - else - return CORBA_OBJECT_NIL; -} - -static CORBA_char * -impl_ConfigArchiver_Location__get_path (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - return CORBA_string_dup (LOCATION_FROM_SERVANT (servant)->p->fullpath); -} - -static ConfigArchiver_StringSeq * -impl_ConfigArchiver_Location__get_backendList (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - ConfigArchiver_StringSeq *ret; - Location *location; - GList *node; - guint i = 0; - - location = LOCATION_FROM_SERVANT (servant); - - ret = ConfigArchiver_StringSeq__alloc (); - ret->_length = g_list_length (location->p->contains_list); - ret->_buffer = CORBA_sequence_CORBA_string_allocbuf (ret->_length); - - for (node = location->p->contains_list; node != NULL; node = node->next) - ret->_buffer[i++] = CORBA_string_dup (((BackendNote *) node->data)->backend_id); - - return ret; -} - -static CORBA_char * -impl_ConfigArchiver_Location__get_label (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - return CORBA_string_dup (LOCATION_FROM_SERVANT (servant)->p->label); -} - -static CORBA_char * -impl_ConfigArchiver_Location__get_id (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - return CORBA_string_dup (LOCATION_FROM_SERVANT (servant)->p->locid); -} - -static void -impl_ConfigArchiver_Location__set_label (PortableServer_Servant servant, - const CORBA_char *label, - CORBA_Environment *ev) -{ - gtk_object_set (GTK_OBJECT (LOCATION_FROM_SERVANT (servant)), "label", label, NULL); -} - -static void -impl_ConfigArchiver_Location__set_id (PortableServer_Servant servant, - const CORBA_char *id, - CORBA_Environment *ev) -{ - gtk_object_set (GTK_OBJECT (LOCATION_FROM_SERVANT (servant)), "locid", id, NULL); -} - -BONOBO_X_TYPE_FUNC_FULL (Location, ConfigArchiver_Location, BONOBO_X_OBJECT_TYPE, location); - -static void -location_init (Location *location) -{ - location->p = g_new0 (LocationPrivate, 1); - location->p->archive = NULL; - location->p->locid = NULL; - location->p->is_new = FALSE; - location->p->contains_list_dirty = FALSE; - - location->p->es = bonobo_event_source_new (); - - bonobo_object_add_interface (BONOBO_OBJECT (location), BONOBO_OBJECT (location->p->es)); -} - -static void -location_class_init (LocationClass *klass) -{ - GtkObjectClass *object_class; - - object_class = GTK_OBJECT_CLASS (klass); - - object_class->destroy = location_destroy; - object_class->finalize = location_finalize; - object_class->set_arg = location_set_arg; - object_class->get_arg = location_get_arg; - - gtk_object_add_arg_type ("Location::archive", - GTK_TYPE_POINTER, - GTK_ARG_READWRITE, - ARG_ARCHIVE); - - gtk_object_add_arg_type ("Location::locid", - GTK_TYPE_POINTER, - GTK_ARG_READWRITE, - ARG_LOCID); - - gtk_object_add_arg_type ("Location::label", - GTK_TYPE_POINTER, - GTK_ARG_READWRITE, - ARG_LABEL); - - gtk_object_add_arg_type ("Location::inherits", - GTK_TYPE_POINTER, - GTK_ARG_READWRITE, - ARG_INHERITS); - - klass->do_rollback = location_do_rollback; - - klass->epv.getStorageFilename = impl_ConfigArchiver_Location_getStorageFilename; - klass->epv.getRollbackFilename = impl_ConfigArchiver_Location_getRollbackFilename; - klass->epv.storageComplete = impl_ConfigArchiver_Location_storageComplete; - klass->epv.rollbackBackends = impl_ConfigArchiver_Location_rollbackBackends; - klass->epv.getModificationTime = impl_ConfigArchiver_Location_getModificationTime; - klass->epv.contains = impl_ConfigArchiver_Location_contains; - klass->epv.addBackend = impl_ConfigArchiver_Location_addBackend; - klass->epv.removeBackend = impl_ConfigArchiver_Location_removeBackend; - klass->epv.doesBackendChange = impl_ConfigArchiver_Location_doesBackendChange; - klass->epv.garbageCollect = impl_ConfigArchiver_Location_garbageCollect; - klass->epv.delete = impl_ConfigArchiver_Location_delete; - - klass->epv._get_parent = impl_ConfigArchiver_Location__get_parent; - klass->epv._get_path = impl_ConfigArchiver_Location__get_path; - klass->epv._get_backendList = impl_ConfigArchiver_Location__get_backendList; - klass->epv._get_label = impl_ConfigArchiver_Location__get_label; - klass->epv._get_id = impl_ConfigArchiver_Location__get_id; - - klass->epv._set_label = impl_ConfigArchiver_Location__set_label; - klass->epv._set_id = impl_ConfigArchiver_Location__set_id; - - parent_class = gtk_type_class (BONOBO_X_OBJECT_TYPE); -} - -static void -location_set_arg (GtkObject *object, GtkArg *arg, guint arg_id) -{ - Location *location; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_LOCATION (object)); - g_return_if_fail (arg != NULL); - - location = LOCATION (object); - - switch (arg_id) { - case ARG_ARCHIVE: - g_return_if_fail (GTK_VALUE_POINTER (*arg) != NULL); - g_return_if_fail (IS_ARCHIVE (GTK_VALUE_POINTER (*arg))); - - location->p->archive = GTK_VALUE_POINTER (*arg); - bonobo_object_ref (BONOBO_OBJECT (location->p->archive)); - break; - - case ARG_LOCID: - if (GTK_VALUE_POINTER (*arg) != NULL) { - if (location->p->locid != NULL) - g_free (location->p->locid); - - location->p->locid = - g_strdup (GTK_VALUE_POINTER (*arg)); - - if (!strcmp (location->p->locid, "default") && - location->p->label == NULL) - location->p->label = g_strdup (_("Default Location")); - else if (location->p->label == NULL) - location->p->label = g_strdup (location->p->locid); - } - - break; - - case ARG_LABEL: - if (GTK_VALUE_POINTER (*arg) != NULL) { - if (location->p->label != NULL) - g_free (location->p->label); - - location->p->label = - g_strdup (GTK_VALUE_POINTER (*arg)); - } - - break; - - case ARG_INHERITS: - if (GTK_VALUE_POINTER (*arg) != NULL) { - g_return_if_fail (IS_LOCATION - (GTK_VALUE_POINTER (*arg))); - location->p->parent = - GTK_VALUE_POINTER (*arg); - bonobo_object_ref (BONOBO_OBJECT (location->p->parent)); - } - - default: - break; - } -} - -static void -location_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) -{ - Location *location; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_LOCATION (object)); - g_return_if_fail (arg != NULL); - - location = LOCATION (object); - - switch (arg_id) { - case ARG_ARCHIVE: - GTK_VALUE_POINTER (*arg) = location->p->archive; - break; - case ARG_LOCID: - GTK_VALUE_POINTER (*arg) = location->p->locid; - break; - case ARG_LABEL: - GTK_VALUE_POINTER (*arg) = location->p->label; - break; - case ARG_INHERITS: - GTK_VALUE_POINTER (*arg) = location->p->parent; - break; - default: - arg->type = GTK_TYPE_INVALID; - break; - } -} - -/** - * location_new: - * @archive: - * @locid: - * @inherits: - * - * Create a new location with the given name and parent identifier in the - * given archive - * - * Return value: Reference to location - **/ - -BonoboObject * -location_new (Archive *archive, const gchar *locid, const gchar *label, Location *inherits) -{ - GtkObject *object; - - g_return_val_if_fail (archive != NULL, NULL); - g_return_val_if_fail (IS_ARCHIVE (archive), NULL); - g_return_val_if_fail (locid != NULL, NULL); - - object = gtk_object_new (location_get_type (), - "archive", archive, - "locid", locid, - "label", label, - "inherits", inherits, - NULL); - - if (!do_create (LOCATION (object))) { - bonobo_object_unref (BONOBO_OBJECT (object)); - return NULL; - } - - LOCATION (object)->p->is_new = TRUE; - - save_metadata (LOCATION (object)); - - return BONOBO_OBJECT (object); -} - -/** - * location_open: - * @archive: - * @locid: - * - * Open the location with the given name from the given archive - * - * Return value: Reference of location - **/ - -BonoboObject * -location_open (Archive *archive, const gchar *locid) -{ - GtkObject *object; - - g_return_val_if_fail (archive != NULL, NULL); - g_return_val_if_fail (IS_ARCHIVE (archive), NULL); - g_return_val_if_fail (locid != NULL, NULL); - - object = gtk_object_new (location_get_type (), - "archive", archive, - "locid", locid, - NULL); - - if (!do_load (LOCATION (object))) { - bonobo_object_unref (BONOBO_OBJECT (object)); - return NULL; - } - - return BONOBO_OBJECT (object); -} - -static void -location_destroy (GtkObject *object) -{ - Location *location; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_LOCATION (object)); - - location = LOCATION (object); - - DEBUG_MSG ("Enter: %s", location->p->locid); - - save_metadata (location); - - if (location->p->config_log) - gtk_object_destroy (GTK_OBJECT (location->p->config_log)); - - if (location->p->parent) - bonobo_object_unref (BONOBO_OBJECT (location->p->parent)); - - archive_unregister_location (location->p->archive, location); - - bonobo_object_unref (BONOBO_OBJECT (location->p->archive)); - - GTK_OBJECT_CLASS (parent_class)->destroy (object); -} - -static void -location_finalize (GtkObject *object) -{ - Location *location; - GList *node; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_LOCATION (object)); - - location = LOCATION (object); - - for (node = location->p->contains_list; node; node = node->next) - backend_note_destroy (node->data); - g_list_free (location->p->contains_list); - - if (location->p->fullpath != NULL) - g_free (location->p->fullpath); - - if (location->p->label != NULL) - g_free (location->p->label); - - if (location->p->locid != NULL) - g_free (location->p->locid); - - g_free (location->p); - location->p = (LocationPrivate *) 0xdeadbeef; - - GTK_OBJECT_CLASS (parent_class)->finalize (object); -} - -/* Perform rollback for a given backend and id number. Return TRUE on - * success and FALSE otherwise. - * - * FIXME: Better error reporting - */ - -static gboolean -location_do_rollback (Location *location, gchar *backend_id, xmlDocPtr doc) -{ - int fd, status; - FILE *output; - pid_t pid; - - g_return_val_if_fail (location != NULL, FALSE); - g_return_val_if_fail (IS_LOCATION (location), FALSE); - g_return_val_if_fail (backend_id != NULL, FALSE); - g_return_val_if_fail (doc != NULL, FALSE); - - /* FIXME: Some mechanism for retrieving the factory defaults settings - * would be useful here - */ - if (doc == NULL) return FALSE; - - fd = run_backend_proc (backend_id, FALSE, &pid); - if (fd == -1) return FALSE; - - output = fdopen (fd, "w"); - xmlDocDump (output, doc); - - if (fflush (output) == EOF) - g_critical ("%s: Could not dump buffer: %s", - G_GNUC_FUNCTION, g_strerror (errno)); - - if (fclose (output) == EOF) { - g_critical ("%s: Could not close output stream: %s", - G_GNUC_FUNCTION, g_strerror (errno)); - return FALSE; - } - - waitpid (pid, &status, 0); - - return TRUE; -} - -static gint -data_delete_cb (ConfigLog *config_log, gint id, gchar *backend_id, - struct tm *date, Location *location) -{ - gchar *filename; - - filename = g_strdup_printf ("%s/%08x.xml", location->p->fullpath, id); - unlink (filename); - g_free (filename); - - return 0; -} - -void -location_delete (Location *location) -{ - gchar *metadata_filename; - - g_return_if_fail (location != NULL); - g_return_if_fail (IS_LOCATION (location)); - - metadata_filename = g_strconcat (location->p->fullpath, - "/location.xml", NULL); - unlink (metadata_filename); - g_free (metadata_filename); - - config_log_iterate (location->p->config_log, - (ConfigLogIteratorCB) data_delete_cb, location); - config_log_delete (location->p->config_log); - - if (rmdir (location->p->fullpath) == -1) - g_warning ("%s: Could not remove directory: %s\n", - G_GNUC_FUNCTION, g_strerror (errno)); - - location->p->deleted = TRUE; -} - -/** - * location_rollback_backends_to: - * @location: - * @date: - * @backends: - * @parent_chain: - * - * Roll back the list of backends specified to the given date, optionally - * chaining to the parent location. This destroys the list of backends given - * - * FIXME: To enforce some kind of ordering on backend application, just create - * a comparison function between backend ids that calls a BackendList method - * to see which item should go first, and then call g_list_sort with that on - * the backend list - **/ - -void -location_rollback_backends_to (Location *location, - struct tm *date, - gint steps, - GList *backends, - gboolean parent_chain) -{ - GList *node; - gchar *backend_id, *filename; - xmlDocPtr doc; - - g_return_if_fail (location != NULL); - g_return_if_fail (IS_LOCATION (location)); - g_return_if_fail (location->p->config_log != NULL); - g_return_if_fail (IS_CONFIG_LOG (location->p->config_log)); - - for (node = backends; node; node = node->next) { - backend_id = node->data; - filename = location_get_rollback_filename - (location, date, steps, backend_id, parent_chain); - if (filename == NULL) continue; - - doc = xmlParseFile (filename); - g_free (filename); - if (doc == NULL) continue; - - LOCATION_CLASS (GTK_OBJECT (location)->klass)->do_rollback - (location, backend_id, doc); - xmlFreeDoc (doc); - } -} - -/** - * location_get_storage_filename: - * @location: - * @backend_id: - * - * Finds a new storage filename for storing rollback data from the backend id - **/ - -gchar * -location_get_storage_filename (Location *location, - const gchar *backend_id, - gboolean is_default) -{ - guint id; - - g_return_val_if_fail (location != NULL, NULL); - g_return_val_if_fail (IS_LOCATION (location), NULL); - g_return_val_if_fail (backend_id != NULL, NULL); - - id = config_log_write_entry (location->p->config_log, backend_id, is_default); - - return g_strdup_printf ("%s/%08x.xml", location->p->fullpath, id); -} - -/** - * location_get_rollback_filename: - * @location: - * @date: - * @steps: - * @backend_id: - * @parent_chain: - * - * Get the filename for the rollback data for the date or number of steps, and - * backend id given. String should be freed after use. Returns NULL if no data - * were found. - **/ - -gchar * -location_get_rollback_filename (Location *location, - struct tm *date, - gint steps, - const gchar *backend_id, - gboolean parent_chain) -{ - gint id; - - g_return_val_if_fail (location != NULL, NULL); - g_return_val_if_fail (IS_LOCATION (location), NULL); - g_return_val_if_fail (location->p->config_log != NULL, NULL); - g_return_val_if_fail (IS_CONFIG_LOG (location->p->config_log), NULL); - - if (steps > 0) - id = config_log_get_rollback_id_by_steps - (location->p->config_log, steps, backend_id); - else - id = config_log_get_rollback_id_for_date - (location->p->config_log, date, backend_id); - - if (id != -1) - return g_strdup_printf ("%s/%08x.xml", location->p->fullpath, id); - else if (parent_chain && location->p->parent != NULL) - return location_get_rollback_filename - (location->p->parent, date, steps, backend_id, parent_chain); - else - return NULL; -} - -/** - * location_storage_complete: - * @location: - * @filename: - * - * Notify the location object that storage of the rollback data at the given - * filename is complete - **/ - -void -location_storage_complete (Location *location, const gchar *filename) -{ - const gchar *tmp; - const gchar *backend_id; - guint id; - BonoboArg *value; - - tmp = strrchr (filename, '/'); - - if (tmp == NULL) - return; - - sscanf (tmp + 1, "%x", &id); - - backend_id = config_log_get_backend_id_for_id - (location->p->config_log, id); - - value = bonobo_arg_new (BONOBO_ARG_STRING); - BONOBO_ARG_SET_STRING (value, backend_id); - bonobo_event_source_notify_listeners - (location->p->es, "ConfigArchiver/Location:newRollbackData", value, NULL); - bonobo_arg_release (value); -} - -/** - * location_store: - * @location: - * @backend_id: - * @input: - * @store_type: STORE_FULL means blindly store the data, without - * modification. STORE_COMPARE_PARENT means subtract the settings the parent - * has that are different and store the result. STORE_MASK_PREVIOUS means - * store only those settings that are reflected in the previous logged data; - * if there do not exist such data, act as in - * STORE_COMPARE_PARENT. STORE_DEFAULT means these are default data. - * - * Store configuration data from the given stream in the location under the - * given backend id - * - * Return value: 0 on success, -1 if it cannot parse the XML, and -2 if no - * data were supplied - **/ - -gint -location_store (Location *location, gchar *backend_id, FILE *input, - StoreType store_type) -{ - xmlDocPtr doc; - char buffer[2048]; - int t = 0; - GString *doc_str; - - g_return_val_if_fail (location != NULL, -2); - g_return_val_if_fail (IS_LOCATION (location), -2); - - fflush (input); - - fcntl (fileno (input), F_SETFL, 0); - - doc_str = g_string_new (""); - - while ((t = read (fileno (input), buffer, sizeof (buffer) - 1)) != 0) { - buffer[t] = '\0'; - g_string_append (doc_str, buffer); - } - - if (doc_str->len > 0) { - doc = xmlParseDoc (doc_str->str); - - if (doc == NULL) { - g_string_free (doc_str, TRUE); - return -1; - } - - location_store_xml (location, backend_id, doc, store_type); - xmlFreeDoc (doc); - } else { - return -2; - } - - g_string_free (doc_str, TRUE); - - return 0; -} - -/** - * location_store_xml: - * @location: - * @backend_id: - * @input: - * @store_type: STORE_FULL means blindly store the data, without - * modification. STORE_COMPARE_PARENT means subtract the settings the parent - * has that are different and store the result. STORE_MASK_PREVIOUS means - * store only those settings that are reflected in the previous logged data; - * if there do not exist such data, act as in STORE_COMPARE_PARENT - * - * Store configuration data from the given XML document object in the location - * under the given backend id - **/ - -void -location_store_xml (Location *location, - gchar *backend_id, - xmlDocPtr xml_doc, - ConfigArchiver_StoreType store_type) -{ - CORBA_Environment ev; - - g_return_if_fail (location != NULL); - g_return_if_fail (IS_LOCATION (location)); - g_return_if_fail (xml_doc != NULL); - - CORBA_exception_init (&ev); - location_client_store_xml (BONOBO_OBJREF (location), backend_id, xml_doc, store_type, &ev); - CORBA_exception_free (&ev); -} - -/** - * location_get_modification_time: - * @location: - * @backend_id: - * - * Get the time the particular backend was last modified (archived) - **/ - -const struct tm * -location_get_modification_time (Location *location, - const gchar *backend_id) -{ - gint id; - - id = config_log_get_rollback_id_by_steps (location->p->config_log, 0, backend_id); - - if (id < 0) - return NULL; - else - return config_log_get_date_for_id (location->p->config_log, id); -} - -/** - * location_contains: - * @location: - * @backend_id: - * - * Determine if a location specifies configuration for the given backend - * - * Return value: Containment type, as defined in the enum - **/ - -ContainmentType -location_contains (Location *location, const gchar *backend_id) -{ - BackendList *list; - - g_return_val_if_fail (location != NULL, FALSE); - g_return_val_if_fail (IS_LOCATION (location), FALSE); - - if (location->p->parent == NULL) { - list = archive_get_backend_list (location->p->archive); - - if (backend_list_contains (list, backend_id)) - return ConfigArchiver_CONTAIN_FULL; - else - return ConfigArchiver_CONTAIN_NONE; - } else { - const BackendNote *note = find_note (location, backend_id); - - if (note != NULL) - return note->type; - else - return ConfigArchiver_CONTAIN_NONE; - } -} - -/** - * location_add_backend: - * @location: - * @backend_id: - * - * Adds a backend id to the location's metadata, so that the location - * specifies configuration for that backend - * - * Returns: 0 on success, -1 if the location is toplevel, -2 if the backend is - * not registered with the master list, -3 if the type specified was "NONE" - **/ - -gint -location_add_backend (Location *location, - const gchar *backend_id, - ContainmentType type) -{ - g_return_val_if_fail (location != NULL, -1); - g_return_val_if_fail (IS_LOCATION (location), -1); - g_return_val_if_fail (backend_id != NULL, -2); - - if (location->p->parent == NULL) return -1; - - if (type == ConfigArchiver_CONTAIN_NONE) return -3; - - if (!backend_list_contains - (archive_get_backend_list (location->p->archive), backend_id)) - return -2; - - location->p->contains_list = - g_list_append (location->p->contains_list, - backend_note_new (backend_id, type)); - location->p->contains_list_dirty = TRUE; - - save_metadata (location); - - return 0; -} - -/** - * location_remove_backend: - * @location: - * @backend_id: - * - * Removes a backend id from the location's metadata, so that the location no - * longer specifies configuration for that backend - **/ - -void -location_remove_backend (Location *location, const gchar *backend_id) -{ - GList *node; - BackendNote *note; - - g_return_if_fail (location != NULL); - g_return_if_fail (IS_LOCATION (location)); - g_return_if_fail (backend_id != NULL); - - if (location->p->parent == NULL) return; - - for (node = location->p->contains_list; node; node = node->next) { - note = node->data; - - if (!strcmp (note->backend_id, backend_id)) { - backend_note_destroy (note); - location->p->contains_list = - g_list_remove_link (location->p->contains_list, - node); - location->p->contains_list_dirty = TRUE; - return; - } - } - - save_metadata (location); -} - -/** - * location_find_path_from_common_parent: - * @location: object - * @location1: The location with which to find the common parent with the - * object - * - * Finds the common parent between the two locations given and returns a GList - * of locations starting at the common parent (starts with NULL if there is no - * common parent) and leading to the location object on which this method is - * invoked - * - * Return value: A GList of locations - **/ - -GList * -location_find_path_from_common_parent (Location *location, - Location *location1) -{ - GList *list_node; - gint depth = 0, depth1 = 0; - Location *tmp; - - g_return_val_if_fail (location != NULL, NULL); - g_return_val_if_fail (IS_LOCATION (location), NULL); - g_return_val_if_fail (location1 != NULL, NULL); - g_return_val_if_fail (IS_LOCATION (location1), NULL); - - list_node = g_list_append (NULL, location); - - for (tmp = location; tmp; tmp = tmp->p->parent) depth++; - for (tmp = location1; tmp; tmp = tmp->p->parent) depth1++; - - while (depth > depth1) { - location = location->p->parent; - list_node = g_list_prepend (list_node, location); - depth--; - } - - while (depth1 > depth) { - location1 = location1->p->parent; - depth1--; - } - - while (location && location1 && location != location1) { - location = location->p->parent; - location1 = location1->p->parent; - list_node = g_list_prepend (list_node, location); - } - - return list_node; -} - -/** - * location_get_parent - * @location: - * - * Returns a reference to the location that this location inherits - * - * Return value: Reference to parent location - **/ - -Location * -location_get_parent (Location *location) -{ - g_return_val_if_fail (location != NULL, NULL); - g_return_val_if_fail (IS_LOCATION (location), NULL); - - return location->p->parent; -} - -/** - * location_get_path: - * @location: - * - * Get the filesystem path to location data - * - * Return value: String with path; should not be freed - **/ - -const gchar * -location_get_path (Location *location) -{ - g_return_val_if_fail (location != NULL, NULL); - g_return_val_if_fail (IS_LOCATION (location), NULL); - - return location->p->fullpath; -} - -/** - * location_get_label: - * @location: - * - * Get the human-readable label associated with the location - * - * Return value: String containing label; should not be freed - **/ - -const gchar * -location_get_label (Location *location) -{ - g_return_val_if_fail (location != NULL, NULL); - g_return_val_if_fail (IS_LOCATION (location), NULL); - - return location->p->label; -} - -/** - * location_get_id: - * @location: - * - * Get the location id - * - * Return value: String containing location id; should not be freed - **/ - -const gchar * -location_get_id (Location *location) -{ - g_return_val_if_fail (location != NULL, NULL); - g_return_val_if_fail (IS_LOCATION (location), NULL); - - return location->p->locid; -} - -/** - * location_foreach_backend: - * @location: - * @callback: - * @data: - * - * Invokes the function callback on every backend handled by this location - **/ - -void -location_foreach_backend (Location *location, LocationBackendCB callback, - gpointer data) -{ - GList *node; - BackendNote *note; - - g_return_if_fail (location != NULL); - g_return_if_fail (IS_LOCATION (location)); - g_return_if_fail (callback != NULL); - - for (node = location->p->contains_list; node; node = node->next) { - note = node->data; - if (callback (location, note->backend_id, data)) break; - } -} - -/** - * location_set_id: - * @location: - * @name: - * - * Sets the name (or id) of the location - **/ - -void -location_set_id (Location *location, const gchar *locid) -{ - gchar *new_fullpath; - - g_return_if_fail (location != NULL); - g_return_if_fail (IS_LOCATION (location)); - g_return_if_fail (locid != NULL); - - gtk_object_set (GTK_OBJECT (location), "locid", locid, NULL); - - new_fullpath = g_concat_dir_and_file (archive_get_prefix - (location->p->archive), - locid); - - if (rename (location->p->fullpath, new_fullpath) == -1) { - g_message ("Could not rename %s to %s: %s", - location->p->fullpath, new_fullpath, - g_strerror (errno)); - } - - g_free (location->p->fullpath); - location->p->fullpath = new_fullpath; - - config_log_reset_filenames (location->p->config_log); -} - -/** - * location_get_changed_backends: - * @location: - * @location1: - * - * Get a list of backends that change from location to location1 - **/ - -GList * -location_get_changed_backends (Location *location, Location *location1) -{ - GList *backends1, *backends2; - - g_return_val_if_fail (location != NULL, NULL); - g_return_val_if_fail (IS_LOCATION (location), NULL); - g_return_val_if_fail (location1 != NULL, NULL); - g_return_val_if_fail (IS_LOCATION (location1), NULL); - - backends1 = create_backends_list (location, location1); - backends2 = create_backends_list (location1, location); - - return merge_backend_lists (backends1, backends2); -} - -/** - * location_does_backend_change: - * @location: - * @location1: - * @backend_id: - * - * Return TRUE if a backend changes when changing from location to location1; - * FALSE otherwise - **/ - -gboolean -location_does_backend_change (Location *location, - Location *location1, - const gchar *backend_id) -{ - GList *backends; - gboolean ret; - gchar *str; - - g_return_val_if_fail (location != NULL, FALSE); - g_return_val_if_fail (IS_LOCATION (location), FALSE); - g_return_val_if_fail (location1 != NULL, FALSE); - g_return_val_if_fail (IS_LOCATION (location1), FALSE); - g_return_val_if_fail (backend_id != NULL, FALSE); - - backends = location_get_changed_backends (location, location1); - str = g_strdup (backend_id); - ret = !(g_list_find_custom (backends, str, - (GCompareFunc) strcmp) == NULL); - g_free (str); - g_list_free (backends); - - return ret; -} - -/* location_get_config_log: - * @location: - * - * Returns the config log object for this location - */ - -ConfigLog * -location_get_config_log (Location *location) -{ - g_return_val_if_fail (location != NULL, FALSE); - g_return_val_if_fail (IS_LOCATION (location), FALSE); - - return 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 - * - * Return value: 0 on success and -1 if any of the backends failed - **/ - -gint -location_store_full_snapshot (Location *location) -{ - int fd; - gint ret; - FILE *pipe; - GList *c; - BackendNote *note; - - g_return_val_if_fail (location != NULL, -1); - g_return_val_if_fail (IS_LOCATION (location), -1); - - for (c = location->p->contains_list; c; c = c->next) { - note = c->data; - DEBUG_MSG ("Storing %s", note->backend_id); - - fd = run_backend_proc (note->backend_id, TRUE, NULL); - pipe = fdopen (fd, "r"); - ret = location_store (location, note->backend_id, - pipe, ConfigArchiver_STORE_DEFAULT); - fclose (pipe); - - if (ret < 0) - return -1; - } - - return 0; -} - -/** - * location_garbage_collect: - * @location: - * - * Iterates through backends and eliminates excess archived data from the - * configuration log and the XML archive - **/ - -static void -garbage_collect_cb (ConfigLog *config_log, gchar *backend_id, gint id, Location *location) -{ - gchar *filename; - - filename = g_strdup_printf ("%s/%08x.xml", location->p->fullpath, id); - DEBUG_MSG ("Removing %s", filename); - unlink (filename); - g_free (filename); -} - -void -location_garbage_collect (Location *location) -{ - GList *node; - BackendNote *note; - - g_return_if_fail (location != NULL); - g_return_if_fail (IS_LOCATION (location)); - - for (node = location->p->contains_list; node != NULL; node = node->next) { - note = node->data; - config_log_garbage_collect (location->p->config_log, - note->backend_id, - (GarbageCollectCB) garbage_collect_cb, - location); - } -} - -/** - * location_is_deleted: - * @location: - * - * Returns TRUE iff the location is marked deleted - **/ - -gboolean -location_is_deleted (const Location *location) -{ - return location->p->deleted; -} - -static gint -get_backends_cb (BackendList *backend_list, gchar *backend_id, - Location *location) -{ - location->p->contains_list = - g_list_prepend (location->p->contains_list, - backend_note_new (backend_id, FALSE)); - return 0; -} - -/* Construct the directory structure for a given location - * - * FIXME: Better error reporting */ - -static gboolean -do_create (Location *location) -{ - gint ret = 0; - - g_return_val_if_fail (location != NULL, FALSE); - g_return_val_if_fail (IS_LOCATION (location), FALSE); - g_return_val_if_fail (location->p->archive != NULL, FALSE); - g_return_val_if_fail (IS_ARCHIVE (location->p->archive), FALSE); - g_return_val_if_fail (location->p->locid != NULL, FALSE); - - if (location->p->parent == NULL) - backend_list_foreach - (archive_get_backend_list (location->p->archive), - (BackendCB) get_backends_cb, - location); - - if (g_file_test (archive_get_prefix (location->p->archive), - G_FILE_TEST_ISDIR) == FALSE) - return FALSE; - - if (location->p->fullpath) g_free (location->p->fullpath); - - location->p->fullpath = - g_concat_dir_and_file (archive_get_prefix - (location->p->archive), - location->p->locid); - - if (g_file_test (location->p->fullpath, G_FILE_TEST_ISDIR) == FALSE) - ret = mkdir (location->p->fullpath, - S_IREAD | S_IWRITE | S_IEXEC); - - if (ret == -1) return FALSE; - - location->p->config_log = CONFIG_LOG (config_log_open (location)); - - return TRUE; -} - -/* Load data for a location into the structure. Assumes all the - * structures are already initialized. - * - * Returns TRUE on success and FALSE on failure (directory not present - * or config metadata not present) - */ - -static gboolean -do_load (Location *location) -{ - gchar *metadata_filename; - - g_return_val_if_fail (location != NULL, FALSE); - g_return_val_if_fail (IS_LOCATION (location), FALSE); - g_return_val_if_fail (location->p->archive != NULL, FALSE); - g_return_val_if_fail (IS_ARCHIVE (location->p->archive), FALSE); - g_return_val_if_fail (location->p->locid != NULL, FALSE); - - if (location->p->fullpath) g_free (location->p->fullpath); - - location->p->fullpath = g_concat_dir_and_file - (archive_get_prefix (location->p->archive), location->p->locid); - - if (g_file_test (location->p->fullpath, G_FILE_TEST_ISDIR) == FALSE) - return FALSE; - - metadata_filename = - g_concat_dir_and_file (location->p->fullpath, "location.xml"); - - if (!load_metadata_file (location, metadata_filename, FALSE)) - return FALSE; - - g_free (metadata_filename); - - location->p->config_log = CONFIG_LOG (config_log_open (location)); - - if (location->p->config_log == NULL) - return FALSE; - - return TRUE; -} - -static gboolean -load_metadata_file (Location *location, char *filename, gboolean is_default) -{ - xmlDocPtr doc; - xmlNodePtr root_node, node; - char *inherits_str = NULL, *label_str = NULL, *contains_str, *type_str; - GList *list_head = NULL, *list_tail = NULL; - BackendNote *note; - ContainmentType type; - - g_return_val_if_fail (location != NULL, FALSE); - g_return_val_if_fail (IS_LOCATION (location), FALSE); - g_return_val_if_fail (location->p->archive != NULL, FALSE); - g_return_val_if_fail (IS_ARCHIVE (location->p->archive), FALSE); - g_return_val_if_fail (filename != NULL, FALSE); - - doc = xmlParseFile (filename); - - if (!doc) - return FALSE; - - root_node = xmlDocGetRootElement (doc); - - if (strcmp (root_node->name, "location")) { - xmlFreeDoc (doc); - return FALSE; - } - - for (node = root_node->childs; node; node = node->next) { - if (!strcmp (node->name, "inherits")) { - inherits_str = xmlGetProp (node, "location"); - - if (inherits_str == NULL) - g_warning ("Bad location config: " \ - "inherits element with no " \ - "location attribute"); - } - else if (!strcmp (node->name, "label")) { - label_str = xmlNodeGetContent (node); - } - else if (!strcmp (node->name, "contains")) { - contains_str = xmlGetProp (node, "backend"); - type_str = xmlGetProp (node, "type"); - - if (contains_str != NULL) { - if (!strcmp (type_str, "full")) - type = ConfigArchiver_CONTAIN_FULL; - else if (!strcmp (type_str, "partial")) - type = ConfigArchiver_CONTAIN_PARTIAL; - else { - type = ConfigArchiver_CONTAIN_NONE; - g_warning ("Bad type attribute"); - } - - note = backend_note_new (contains_str, type); - list_tail = g_list_append (list_tail, note); - if (list_head == NULL) - list_head = list_tail; - else - list_tail = list_tail->next; - } else { - g_warning ("Bad location config: " \ - "contains element with no " \ - "backend attribute"); - } - } - } - - xmlFreeDoc (doc); - - location->p->contains_list = list_head; - - if (!is_default) { - if (inherits_str != NULL) { - location->p->parent = - archive_get_location (location->p->archive, - inherits_str); - } else { - if (list_head != NULL) { - g_warning ("Top-level locations should not " \ - "have contains lists"); - g_list_foreach (list_head, (GFunc) g_free, - NULL); - g_list_free (list_head); - } - - backend_list_foreach - (archive_get_backend_list - (location->p->archive), - (BackendCB) get_backends_cb, - location); - } - } - - if (label_str != NULL) { - if (location->p->label != NULL) - g_free (location->p->label); - - location->p->label = label_str; - } - - return TRUE; -} - -static void -save_metadata (Location *location) -{ - gchar *metadata_filename; - - if (location->p->deleted || (!location->p->is_new && !location->p->contains_list_dirty)) - return; - - location->p->is_new = FALSE; - - metadata_filename = - g_concat_dir_and_file (location->p->fullpath, - "location.xml"); - - write_metadata_file (location, metadata_filename); - - g_free (metadata_filename); - - location->p->contains_list_dirty = FALSE; -} - -static void -write_metadata_file (Location *location, gchar *filename) -{ - GList *node; - xmlDocPtr doc; - xmlNodePtr root_node, child_node; - BackendNote *note; - - doc = xmlNewDoc ("1.0"); - root_node = xmlNewDocNode (doc, NULL, "location", NULL); - - if (location->p->parent) { - g_return_if_fail - (location->p->parent->p->locid != NULL); - - child_node = xmlNewChild (root_node, NULL, "inherits", NULL); - xmlNewProp (child_node, "location", - location->p->parent->p->locid); - - for (node = location->p->contains_list; node; - node = node->next) - { - note = node->data; - child_node = xmlNewChild (root_node, NULL, - "contains", NULL); - xmlNewProp (child_node, "backend", note->backend_id); - - if (note->type == ConfigArchiver_CONTAIN_PARTIAL) - xmlNewProp (child_node, "type", "partial"); - else if (note->type == ConfigArchiver_CONTAIN_FULL) - xmlNewProp (child_node, "type", "full"); - } - } - - xmlNewChild (root_node, NULL, "label", location->p->label); - - xmlDocSetRootElement (doc, root_node); - - /* FIXME: Report errors here */ - xmlSaveFile (filename, doc); - xmlFreeDoc (doc); -} - -/* 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, gboolean do_get, pid_t *pid_r) -{ - 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; - } - else if (pid == 0) { - int i; - - dup2 (fd[c_fd], c_fd); - close (fd[p_fd]); - for (i = 3; i < FOPEN_MAX; i++) close (i); - - if (strstr (backend_id, "-conf")) - args[0] = g_concat_dir_and_file (XST_BACKEND_LOCATION, - backend_id); - else - args[0] = gnome_is_program_in_path (backend_id); - - args[1] = do_get ? "--get" : "--set"; - args[2] = NULL; - - if (args[0] == NULL) { - g_warning ("Backend not in path: %s", backend_id); - close (c_fd); - exit (-1); - } - - execv (args[0], args); - - g_warning ("Could not launch backend %s: %s", - args[0], g_strerror (errno)); - exit (-1); - return 0; - } else { - if (pid_r != NULL) - *pid_r = pid; - - close (fd[c_fd]); - return fd[p_fd]; - } -} - -static BackendNote * -backend_note_new (const gchar *backend_id, ContainmentType type) -{ - BackendNote *note; - - note = g_new0 (BackendNote, 1); - note->backend_id = g_strdup (backend_id); - note->type = type; - - return note; -} - -static void -backend_note_destroy (BackendNote *note) -{ - g_free (note->backend_id); - g_free (note); -} - -static const BackendNote * -find_note (Location *location, const gchar *backend_id) -{ - GList *node; - - for (node = location->p->contains_list; node; node = node->next) - if (!strcmp (((BackendNote *)node->data)->backend_id, - backend_id)) - return node->data; - - return NULL; -} - -/* Create a list of backends that differ between location1 and the common - * parent of location1 and location2 */ - -static GList * -create_backends_list (Location *location1, Location *location2) -{ - Location *loc; - GList *location_path, *tail = NULL, *c, *tmp; - - location_path = location_find_path_from_common_parent - (location1, location2); - - /* Skip the first entry -- it is the common parent */ - tmp = location_path; - location_path = location_path->next; - g_list_free_1 (tmp); - - while (location_path != NULL) { - if (location_path->data != NULL) { - loc = LOCATION (location_path->data); - for (c = loc->p->contains_list; c; c = c->next) - tail = g_list_prepend - (tail, ((BackendNote *)c->data)->backend_id); - } - - tmp = location_path; - location_path = location_path->next; - g_list_free_1 (tmp); - } - - return g_list_reverse (tail); -} - -/* Merge two backend lists, eliminating duplicates */ - -static GList * -merge_backend_lists (GList *backends1, GList *backends2) -{ - GList *head = NULL, *tail = NULL, *tmp; - int res; - - backends1 = g_list_sort (backends1, (GCompareFunc) strcmp); - backends2 = g_list_sort (backends2, (GCompareFunc) strcmp); - - while (backends1 && backends2) { - res = strcmp (backends1->data, backends2->data); - - if (res < 0) { - if (tail != NULL) tail->next = backends1; - else head = backends1; - tail = backends1; - backends1 = backends1->next; - } - else if (res > 0) { - if (tail != NULL) tail->next = backends2; - else head = backends2; - tail = backends2; - backends2 = backends2->next; - } else { - if (tail != NULL) tail->next = backends1; - else head = backends1; - tail = backends1; - backends1 = backends1->next; - tmp = backends2; - backends2 = backends2->next; - g_list_free_1 (tmp); - } - } - - if (backends1 != NULL) { - if (tail != NULL) tail->next = backends1; - else head = backends1; - } - else { - if (tail != NULL) tail->next = backends2; - else head = backends2; - } - - return head; -} diff --git a/archiver/location.h b/archiver/location.h deleted file mode 100644 index 8bc2527d8..000000000 --- a/archiver/location.h +++ /dev/null @@ -1,144 +0,0 @@ -/* -*- mode: c; style: linux -*- */ - -/* location.h - * Copyright (C) 2000-2001 Ximian, Inc. - * - * Written by Bradford Hovinen (hovinen@ximian.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#ifndef __LOCATION_H -#define __LOCATION_H - -#include <gnome.h> -#include <tree.h> -#include <bonobo.h> - -#include "ConfigArchiver.h" - -#include "config-log.h" - -#define LOCATION(obj) GTK_CHECK_CAST (obj, location_get_type (), Location) -#define LOCATION_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, location_get_type (), LocationClass) -#define IS_LOCATION(obj) GTK_CHECK_TYPE (obj, location_get_type ()) - -typedef struct _LocationClass LocationClass; -typedef struct _LocationPrivate LocationPrivate; -typedef struct _Archive Archive; - -typedef ConfigArchiver_ContainmentType ContainmentType; -typedef ConfigArchiver_StoreType StoreType; - -typedef int (*LocationBackendCB) (Location *, gchar *, gpointer); - -struct _Location -{ - BonoboXObject object; - - LocationPrivate *p; -}; - -struct _LocationClass -{ - BonoboXObjectClass parent; - - POA_ConfigArchiver_Location__epv epv; - - gboolean (*do_rollback) (Location *location, - gchar *backend_id, - xmlDocPtr xml_doc); -}; - -GType location_get_type (void); - -BonoboObject *location_new (Archive *archive, - const gchar *locid, - const gchar *label, - Location *parent); -BonoboObject *location_open (Archive *archive, - const gchar *locid); - -void location_delete (Location *location); - -gchar *location_get_storage_filename (Location *location, - const gchar *backend_id, - gboolean is_default); -gchar *location_get_rollback_filename (Location *location, - struct tm *date, - gint steps, - const gchar *backend_id, - gboolean parent_chain); - -void location_storage_complete (Location *location, - const gchar *filename); - -gint location_store (Location *location, - gchar *backend_id, - FILE *input, - ConfigArchiver_StoreType store_type); -void location_store_xml (Location *location, - gchar *backend_id, - xmlDocPtr xml_doc, - ConfigArchiver_StoreType store_type); - -void location_rollback_backends_to (Location *location, - struct tm *date, - gint steps, - GList *backends, - gboolean parent_chain); - -const struct tm *location_get_modification_time (Location *location, - const gchar *backend_id); - -ContainmentType location_contains (Location *location, - const gchar *backend_id); -gint location_add_backend (Location *location, - const gchar *backend_id, - ContainmentType type); -void location_remove_backend (Location *location, - const gchar *backend_id); - -void location_foreach_backend (Location *location, - LocationBackendCB callback, - gpointer data); - -GList *location_find_path_from_common_parent (Location *location, - Location *location2); - -Location *location_get_parent (Location *location); -const gchar *location_get_path (Location *location); -const gchar *location_get_label (Location *location); -const gchar *location_get_id (Location *location); - -void location_set_id (Location *location, - const gchar *locid); - -gint location_store_full_snapshot (Location *location); - -GList *location_get_changed_backends (Location *location, - Location *location1); -gboolean location_does_backend_change (Location *location, - Location *location1, - const gchar *backend_id); - -ConfigLog *location_get_config_log (Location *location); - -void location_garbage_collect (Location *location); - -gboolean location_is_deleted (const Location *location); - -#endif /* __LOCATION */ diff --git a/archiver/main.c b/archiver/main.c deleted file mode 100644 index ccac48fdd..000000000 --- a/archiver/main.c +++ /dev/null @@ -1,384 +0,0 @@ -/* -*- mode: c; style: linux -*- */ - -/* main.c - * Copyright (C) 2000-2001 Ximian, Inc. - * - * Written by Bradford Hovinen (hovinen@ximian.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <stdio.h> -#include <time.h> -#include <sys/time.h> -#include <sys/file.h> -#include <unistd.h> -#include <errno.h> - -#include <gnome.h> - -#include "util.h" -#include "archive.h" - -/* Variables resulting from command line parsing */ - -static gboolean store; -static gboolean rollback; -static gboolean change_location; -static gboolean rename_location; -static gboolean push_config; -static gboolean garbage_collect; - -static gboolean add_location; -static gboolean remove_location; -static gboolean add_backend; -static gboolean remove_backend; - -static gboolean global; -static const gchar *location_id; - -static gchar *backend_id; - -static gboolean compare_parent; -static gboolean mask_previous; - -static gchar *date_str; -static gboolean all; -static gchar *revision_id; -static gboolean last; -static guint steps; -static gboolean show; - -static gchar *parent_str; -static gchar *new_name; - -static gboolean contain_full; -static gboolean contain_partial; -static gboolean master; - -static struct poptOption archiver_operations[] = { - {"store", 's', POPT_ARG_NONE, &store, 0, - N_("Store XML data in the archive")}, - {"rollback", 'r', POPT_ARG_NONE, &rollback, 0, - N_("Roll back the configuration to a given point")}, - {"change-location", 'c', POPT_ARG_NONE, &change_location, 0, - N_("Change the location profile to the given one")}, - {"push-config", 'p', POPT_ARG_NONE, &push_config, 0, - N_("Push configuration data out to client machines (UNIMPLEMENTED)")}, - {"rename-location", '\0', POPT_ARG_NONE, &rename_location, 0, - N_("Rename a location to a new name")}, - {"add-location", '\0', POPT_ARG_NONE, &add_location, 0, - N_("Add a new location to the archive")}, - {"remove-location", '\0', POPT_ARG_NONE, &remove_location, 0, - N_("Remove a location from the archive")}, - {"add-backend", '\0', POPT_ARG_NONE, &add_backend, 0, - N_("Add a given backend to the given location")}, - {"remove-backend", '\0', POPT_ARG_NONE, &remove_backend, 0, - N_("Remove the given backend from the given location")}, - {"garbage-collect", '\0', POPT_ARG_NONE, &garbage_collect, 0, - N_("Perform garbage collection on the given location")}, - {NULL, '\0', 0, NULL, 0} -}; - -static struct poptOption global_options[] = { - {"global", 'g', POPT_ARG_NONE, &global, 0, - N_("Use the global repository")}, - {"location", 'l', POPT_ARG_STRING, &location_id, 0, - N_("Identifier of location profile on which to operate"), - N_("LOCATION")}, - {"backend", 'b', POPT_ARG_STRING, &backend_id, 0, - N_("Backend being used for this operation"), N_("BACKEND_ID")}, - {NULL, '\0', 0, NULL, 0} -}; - -static struct poptOption store_options[] = { - {"compare-parent", '\0', POPT_ARG_NONE, &compare_parent, 0, - N_("Store only the differences with the parent location's config")}, - {"mask-previous", '\0', POPT_ARG_NONE, &mask_previous, 0, - N_("Store only those settings set in the previous config")}, - {NULL, '\0', 0, NULL, 0} -}; - -static struct poptOption rollback_options[] = { - {"date", 'd', POPT_ARG_STRING, &date_str, 0, - N_("Date to which to roll back"), N_("DATE")}, - {"all", 'a', POPT_ARG_NONE, &all, 0, - N_("Roll back all configuration items")}, - {"revision-id", 'i', POPT_ARG_INT, &revision_id, 0, - N_("Roll back to the revision REVISION_ID"), N_("REVISION_ID")}, - {"last", 't', POPT_ARG_NONE, &last, 0, - N_("Roll back to the last known revision")}, - {"steps", '\0', POPT_ARG_INT, &steps, 0, - N_("Roll back by STEPS revisions"), N_("STEPS")}, - {"show", 'h', POPT_ARG_NONE, &show, 0, - N_("Don't run the backend, just dump the output")}, - {NULL, '\0', 0, NULL, 0} -}; - -static struct poptOption add_rename_location_options[] = { - {"parent", '\0', POPT_ARG_STRING, &parent_str, 0, - N_("Parent location for the new location"), N_("PARENT")}, - {"new-name", '\0', POPT_ARG_STRING, &new_name, 0, - N_("New name to assign to the location"), N_("NEW_NAME")}, - {NULL, '\0', 0, NULL, 0} -}; - -static struct poptOption add_remove_backend_options[] = { - {"master", '\0', POPT_ARG_NONE, &master, 0, - N_("Add/remove this backend to/from the master backend list")}, - {"full", '\0', POPT_ARG_NONE, &contain_full, 0, - N_("Full containment")}, - {"partial", '\0', POPT_ARG_NONE, &contain_partial, 0, - N_("Partial containment")}, - {NULL, '\0', 0, NULL, 0} -}; - -static void -do_store (Location *location) -{ - StoreType type; - - if (!backend_id) { - fprintf (stderr, "No backend specified\n"); - return; - } - - if (mask_previous) - type = STORE_MASK_PREVIOUS; - else if (compare_parent) - type = STORE_COMPARE_PARENT; - else - type = STORE_FULL; - - location_store (location, backend_id, stdin, type); -} - -static void -do_rollback (Location *location) -{ - gint id; - struct tm *date = NULL; - - if (date_str) - date = parse_date (date_str); - else if (last || steps > 0) - date = NULL; - else if (!revision_id) { - fprintf (stderr, "No date specified\n"); - return; - } - - if (all) { - location_rollback_all_to (location, date, TRUE); - } - else if (backend_id && (date || last)) { - /* FIXME: Need to support specifying multiple backends */ - if (show) - location_dump_rollback_data (location, date, 0, - backend_id, TRUE, stdout); - else - location_rollback_backend_to (location, date, - backend_id, TRUE); - } - else if (backend_id && steps) { - if (show) - location_dump_rollback_data (location, NULL, steps, - backend_id, TRUE, stdout); - else - location_rollback_backend_by (location, steps, - backend_id, TRUE); - } - else if (revision_id) { - sscanf (revision_id, "%x", &id); - if (id >= 0) - location_rollback_id (location, id); - else - fprintf (stderr, "Bad id specified\n"); - } else { - g_message ("No backend specified\n"); - return; - } -} - -static void -do_change_location (Archive *archive, Location *location) -{ - archive_set_current_location (archive, location); -} - -static void -do_rename_location (Archive *archive, Location *location) -{ - gboolean is_current; - - if (new_name == NULL) { - fprintf (stderr, - "You did not specify a new name. Try --help\n"); - } else { - if (!strcmp (location_get_id (location), - archive_get_current_location_id (archive))) - is_current = TRUE; - else - is_current = FALSE; - - location_set_id (location, new_name); - - if (is_current) - archive_set_current_location_id (archive, new_name); - } -} - -static void -do_add_location (Archive *archive) -{ - GtkObject *location; - Location *parent_location = NULL; - - if (location_id == NULL) { - fprintf (stderr, - "Error: You did not specify a location name\n"); - return; - } - - if (parent_str != NULL) { - parent_location = archive_get_location (archive, parent_str); - - if (parent_location == NULL && !strcmp (parent_str, "default")) - parent_location = - LOCATION - (location_new (archive, "default", NULL)); - } - - location = location_new (archive, location_id, parent_location); -} - -static void -do_remove_location (Location *location) -{ - location_delete (location); -} - -static void -do_add_backend (Location *location) -{ - ContainmentType type; - - if (contain_full && contain_partial) { - fprintf (stderr, "Error: Cannot have both full and partial " - "containment\n"); - return; - } - else if (contain_partial) { - type = CONTAIN_PARTIAL; - } else { - type = CONTAIN_FULL; - } - - location_add_backend (location, backend_id, type); -} - -static void -do_remove_backend (Location *location) -{ - location_remove_backend (location, backend_id); -} - -static void -do_garbage_collect (Location *location) -{ - location_garbage_collect (location); -} - -int -main (int argc, char **argv) -{ - Archive *archive; - Location *location = NULL; - - /* For Electric Fence */ - free (malloc (1)); - - bindtextdomain (PACKAGE, GNOMELOCALEDIR); - bind_textdomain_codeset (PACKAGE, "UTF-8"); - textdomain (PACKAGE); - - gnomelib_register_popt_table (global_options, - _("Global archiver options")); - gnomelib_register_popt_table (archiver_operations, - _("Archiver commands")); - gnomelib_register_popt_table (store_options, - _("Options for storing data")); - gnomelib_register_popt_table (rollback_options, - _("Options for rolling back")); - gnomelib_register_popt_table (add_rename_location_options, - _("Options for adding or renaming " \ - "locations")); - gnomelib_register_popt_table (add_remove_backend_options, - _("Options for adding and removing " \ - "backends")); - - gtk_type_init (); - gnomelib_init ("archiver", VERSION); - gnomelib_parse_args (argc, argv, 0); - - archive = ARCHIVE (archive_load (global)); - - if (archive == NULL) { - fprintf (stderr, "Could not open archive\n"); - return -1; - } - - if (!add_location) { - if (location_id == NULL) - location_id = - archive_get_current_location_id (archive); - - location = archive_get_location (archive, location_id); - - if (location == NULL) { - fprintf (stderr, "Error: Could not open location %s\n", - location_id); - return -1; - } - } - - if (store) - do_store (location); - else if (rollback) - do_rollback (location); - else if (change_location) - do_change_location (archive, location); - else if (rename_location) - do_rename_location (archive, location); - else if (add_location) - do_add_location (archive); - else if (remove_location) - do_remove_location (location); - else if (add_backend) - do_add_backend (location); - else if (remove_backend) - do_remove_backend (location); - else if (garbage_collect) - do_garbage_collect (location); - - archive_close (archive); - - return 0; -} diff --git a/archiver/tests/ChangeLog b/archiver/tests/ChangeLog deleted file mode 100644 index 6534b933a..000000000 --- a/archiver/tests/ChangeLog +++ /dev/null @@ -1,125 +0,0 @@ -2004-10-14 Jody Goldberg <jody@gnome.org> - - * Release 2.8.1 - -2004-04-15 Jody Goldberg <jody@gnome.org> - - * Release 2.6.1 - -2004-04-01 Jody Goldberg <jody@gnome.org> - - * Release 2.6.0.3 - -2004-03-30 Jody Goldberg <jody@gnome.org> - - * Release 2.6.0.1 - -2004-03-23 Jody Goldberg <jody@gnome.org> - - * Release 2.6.0 - -2004-03-11 Jody Goldberg <jody@gnome.org> - - * Release 2.5.4 - -2004-02-13 Jody Goldberg <jody@gnome.org> - - * Release 2.5.3 - -2004-01-14 Jody Goldberg <jody@gnome.org> - - * Release 2.5.2 - -2003-12-30 Jody Goldberg <jody@gnome.org> - - * Release 2.5.1.1 - -2003-12-30 Jody Goldberg <jody@gnome.org> - - * Release 2.5.1 - -2003-10-28 Jody Goldberg <jody@gnome.org> - - * Release 2.5.0 - -2003-07-07 Jody Goldberg <jody@gnome.org> - - * Release 2.3.4 - -2003-06-24 Jody Goldberg <jody@gnome.org> - - * Release 2.3.3 - -2003-05-07 Jody Goldberg <jody@gnome.org> - - * Release 2.3.1 - -Tue Feb 4 17:09:18 2003 Jonathan Blandford <jrb@redhat.com> - - * Release 2.2.0.1 - -Tue Jan 21 01:15:14 2003 Jonathan Blandford <jrb@gnome.org> - - * Release 2.2.0 - -Thu Jan 16 02:41:09 2003 Jonathan Blandford <jrb@gnome.org> - - * Release 2.1.7 - -2003-01-10 Jody Goldberg <jody@gnome.org> - - * Release 2.1.6 - -2002-12-18 Jody Goldberg <jody@gnome.org> - - * Release 2.1.5 - -2002-11-23 Jody Goldberg <jody@gnome.org> - - * Release 2.1.3 - -2002-11-02 Jody Goldberg <jody@gnome.org> - - * Release 2.1.2 - -2002-10-21 Jody Goldberg <jody@gnome.org> - - * Release 2.1.1 - -2002-10-01 Jody Goldberg <jody@gnome.org> - - * Release 2.1.0.1 - -2002-08-21 Jody Goldberg <jody@gnome.org> - - * Release 2.1.0 - -2002-06-17 Jody Goldberg <jody@gnome.org> - - * Release 2.0.0 - -2001-07-27 Bradford Hovinen <hovinen@ximian.com> - - * RELEASE : 1.5.2 - -2001-07-20 Chema Celorio <chema@celorio.com> - - * RELEASE : 1.5.0 - -2001-05-24 Arturo Espinosa Aldama <arturo@ximian.com> - - * 0.5 RELEASE - -2001-05-09 Arturo Espinosa Aldama <arturo@ximian.com> - - * 0.4 RELEASE - -2001-02-20 Bradford Hovinen <hovinen@ximian.com> - - * test-3.sh: Created - * test-2.sh: Removed parts dealing with partial containment - -2001-02-19 Bradford Hovinen <hovinen@ximian.com> - - * Added test-1.sh and test-2.sh, the first two tests in the test suite - diff --git a/archiver/tests/README b/archiver/tests/README deleted file mode 100644 index d629f202d..000000000 --- a/archiver/tests/README +++ /dev/null @@ -1,48 +0,0 @@ -This is a test suite for the archiver. It is designed to ease the pain -of formulating the (rather complex) tests the check all the -functionality of the archiver. Simply loading up the GUI and playing -around with it is not enough, since one wrong move can destroy a -person's configuration. - -Tests: The test suite checks the following functionality: - - 1. On an account or machine where data have never been - archived, the default location and archive are properly - and automatically set up without user intervention. - - 2. Locations inheriting the default location are created - and destroyed properly. - - 3. Backends can be added and removed from non-toplevel - locations, with both full and partial containment. Any - attempt to do so on a toplevel location results in an - error. - - 4. Rollback data may be stored on both the base and derived - locations. When stored in the derived location where the - backend is marked with partial containment, the rollback - data represent only the differences between the derived and - parent configurations. The most recent configuration from - the parent location is used for making this determination. - - 5. When rolling a backend back in a derived location, if the - backend is not marked as contained in the derived location, - the data are retrieved from the location's parent - recursively. If the backend is marked as partially - contained, then the XML data are merged with the parent's - data. - - 6. Changing the current location correctly invokes the - rollback algorithm - - 7. Rolling back by date and by number of steps works in a - manner similar to the above. - - 8. Logs accurately represent the data archived. - - 9. Backends are invoked properly and data are sent to them - properly. - - 10. All erroneous input should result in an error and not a - crash. The program should return an appropriate error - condition. diff --git a/archiver/tests/test-1.sh b/archiver/tests/test-1.sh deleted file mode 100755 index 7588dad99..000000000 --- a/archiver/tests/test-1.sh +++ /dev/null @@ -1,187 +0,0 @@ -#!/bin/sh -# -# test-1.sh -# Copyright (C) 2001 Ximian, Inc. -# Written by Bradford Hovinen <hovinen@ximian.com> -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. -# -# Test suite, part I -# -# Given an archive to work with (global or per-user): -# -# - Destroy the entire archive forcibly (rm -rf) -# - Store backend data in the archive -# - Check to see that a new archive has been created with default -# location "Default", and that the data have been properly stored -# there - -XIMIAN_ARCHIVER=${XIMIAN_ARCHIVER:-'../ximian-archiver'} - -function get_unused_tmpfile () { - tmp_file_no=0 - - while [ -e "/tmp/$1-$tmp_file_no" ]; do - let 'tmp_file_no=tmp_file_no+1' - done - - echo "/tmp/$1-$tmp_file_no"; -} - -function run_command () { - if [ "x$use_gdb" == "xyes" ]; then - commands_file=`get_unused_tmpfile gdb-commands-file` - echo "set args $extra_args $@" >$commands_file - gdb ../.libs/lt-ximian-archiver -x $commands_file - else - echo "Running archiver program with the following command line:" - echo $XIMIAN_ARCHIVER $extra_args $@ - $XIMIAN_ARCHIVER $extra_args $@ - echo - fi -} - -if [ "x$1" == "x" ]; then - echo "Usage: test-1.sh --global|--per-user [--gdb]" - exit 1 -fi - -for test_option; do - case "$test_option" in - --global) - extra_args="--global" - archive_dir=/usr/share/ximian-config - ;; - - --per-user) - extra_args="" - archive_dir=$HOME/.gnome/ximian-config - ;; - - --gdb) - use_gdb=yes - ;; - - *) - echo "Usage: test-1.sh --global|--per-user [--gdb]" - exit 1 - esac -done - -if [ -d $archive_dir ]; then - mv $archive_dir "$archive_dir-backup" -fi - -############################################################################## -# Test proper -############################################################################## - -archiver_test_data_file=`get_unused_tmpfile ximian-archiver-test-data`; - -cat >$archiver_test_data_file <<EOF -<?xml version="1.0"?> -<background-properties> - <bg-color1>#111128</bg-color1> - <bg-color2>#796dff</bg-color2> - <enabled/> - <wallpaper/> - <gradient/> - <orientation>vertical</orientation> - <wallpaper-type>0</wallpaper-type> - <wallpaper-filename>/home/hovinen/media/Propaganda/Vol3/9a.jpg</wallpaper-filename> - <wallpaper-sel-path>./</wallpaper-sel-path> - <auto-apply/> - <adjust-opacity/> - <opacity>172</opacity> -</background-properties> -EOF - -run_command --store --backend=background-properties-capplet \ - <$archiver_test_data_file - -############################################################################## -# Results check -############################################################################## - -echo -n "Checking whether default location was created properly..." - -if [ -d "$archive_dir/default" ]; then - echo "yes -- good" -else - echo "no -- error" -fi - -echo -n "Checking whether the XML data snapshot was created..." - -if [ -f "$archive_dir/default/00000000.xml" ]; then - echo "yes -- good" -else - echo "no -- error" -fi - -echo -n "Checking whether the XML data match the XML data given..." - -differences_file=`get_unused_tmpfile differences` - -diff -u $archive_dir/default/00000000.xml $archiver_test_data_file \ - >$differences_file - -if [ ! -s $differences_file ]; then - echo "yes -- good" -else - echo "no -- error" - echo "Differences are as follows:" - cat $differences_file - echo -fi - -rm -f $differences_file - -echo -n "Checking if the config log data are correct..." - -config_log_id=`awk '{print $1}' $archive_dir/default/config.log` -config_log_backend=`awk '{print $4}' $archive_dir/default/config.log` - -if [ "x$config_log_id" == "x00000000" -a \ - "x$config_log_backend" == "xbackground-properties-capplet" ]; then - echo "yes -- good" -else - echo "no -- error" - echo "Config log is as follows:" - cat $archive_dir/default/config.log - echo -fi - -############################################################################## -# Putting the results together -############################################################################## - -rm -f $archiver_test_data_file - -results_dir="ximian-config-results-`date +%Y%m%d`" -results_dir=`get_unused_tmpfile $results_dir` -mkdir $results_dir - -(cd $archive_dir && tar cf - *) | (cd $results_dir && tar xf -) -rm -rf $archive_dir - -if [ -d "$archive_dir-backup" ]; then - mv "$archive_dir-backup" $archive_dir -fi - -echo -echo "Test complete" -echo "Resulting archive data in $results_dir" diff --git a/archiver/tests/test-2.sh b/archiver/tests/test-2.sh deleted file mode 100755 index deac5de62..000000000 --- a/archiver/tests/test-2.sh +++ /dev/null @@ -1,219 +0,0 @@ -#!/bin/sh -# -# test-2.sh -# Copyright (C) 2001 Ximian, Inc. -# Written by Bradford Hovinen <hovinen@ximian.com> -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. -# -# Test suite, part II -# -# Given an archive to work with (global or per-user): -# -# - Destroy the entire archive forcibly (rm -rf) -# - Create a new location inheriting from the default location -# (the default location should be created automatically in this case) -# - Sets the new location as the current one -# - Stores data for a backend not contained in the new location -# (this should pass the data through to default) -# - Adds a backend to the new location (full containment) -# - Stores data for that backend in the new location - -XIMIAN_ARCHIVER=${XIMIAN_ARCHIVER:-'../ximian-archiver'} - -function get_unused_tmpfile () { - tmp_file_no=0 - - while [ -e "/tmp/$1-$tmp_file_no" ]; do - let 'tmp_file_no=tmp_file_no+1' - done - - echo "/tmp/$1-$tmp_file_no"; -} - -function run_command () { - input_param=$1 - shift - - if [ "x$use_gdb" == "xyes" ]; then - commands_file=`get_unused_tmpfile gdb-commands-file` - echo "set args $extra_args $@ <$input_param" >$commands_file - gdb ../.libs/ximian-archiver -x $commands_file - rm -f $commands_file - else - echo "Running archiver program with the following command line:" >&2 - echo "$XIMIAN_ARCHIVER $extra_args $@ <$input_param" >&2 - $XIMIAN_ARCHIVER $extra_args $@ <$input_param - echo - fi -} - -if [ "x$1" == "x" ]; then - echo "Usage: test-2.sh --global|--per-user [--gdb]" - exit 1 -fi - -for test_option; do - case "$test_option" in - --global) - extra_args="--global" - archive_dir=/usr/share/ximian-config - ;; - - --per-user) - extra_args="" - archive_dir=$HOME/.gnome/ximian-config - ;; - - --gdb) - use_gdb=yes - ;; - - *) - echo "Error -- invalid option: $test_option" - exit 1 - esac -done - -if [ -d $archive_dir ]; then - mv $archive_dir "$archive_dir-backup" -fi - -############################################################################## -# Test proper -############################################################################## - -# Test 1: Creating a new location - -run_command /dev/null --add-location --parent=default --location=Boston-Office -run_command /dev/null --change-location --location=Boston-Office - -# Test 2: Storing data that should "pass through" to the parent - -archiver_test_data_file1=`get_unused_tmpfile ximian-archiver-test-data`; - -cat >$archiver_test_data_file1 <<EOF -<?xml version="1.0"?> -<background-properties> - <bg-color1>#111128</bg-color1> - <bg-color2>#796dff</bg-color2> - <enabled/> - <wallpaper/> - <gradient/> - <orientation>vertical</orientation> - <wallpaper-type>0</wallpaper-type> - <wallpaper-filename>/home/hovinen/media/Propaganda/Vol3/9a.jpg</wallpaper-filename> - <wallpaper-sel-path>./</wallpaper-sel-path> - <auto-apply/> - <adjust-opacity/> - <opacity>172</opacity> -</background-properties> - -EOF - -run_command $archiver_test_data_file1 \ - --store --backend=background-properties-capplet - -# Test 3: Adding a backend (full containment) and storing data that -# should be stored in the child location - -run_command /dev/null --add-backend --full \ - --backend=keyboard-properties-capplet - -archiver_test_data_file2=`get_unused_tmpfile ximian-archiver-test-data`; - -cat >$archiver_test_data_file2 <<EOF -<?xml version="1.0"?> -<keyboard-properties> - <rate>255</rate> - <delay>0</delay> - <repeat/> - <volume>0</volume> -</keyboard-properties> - -EOF - -run_command $archiver_test_data_file2 \ - --store --backend=keyboard-properties-capplet - -# Test 5: Retrieve the background properties data previously stored -# and compare it with the data we have here to see if everything is ok - -archiver_test_data_file3=`get_unused_tmpfile ximian-archiver-test-data` - -run_command /dev/null --rollback --show --last \ - --backend=background-properties-capplet \ - >$archiver_test_data_file3 - -############################################################################## -# Results check -############################################################################## - -echo -n "Checking whether default location was created properly..." - -if [ -d "$archive_dir/default" ]; then - echo "yes -- good" -else - echo "no -- error" -fi - -echo -n "Checking whether derived location was created properly..." - -if [ -d "$archive_dir/Boston-Office" ]; then - echo "yes -- good" -else - echo "no -- error" -fi - -echo -n "Checking whether the XML data retrieved match the XML data given..." - -differences_file=`get_unused_tmpfile differences` - -diff -u $archiver_test_data_file3 $archiver_test_data_file1 >$differences_file - -if [ ! -s $differences_file ]; then - echo "yes -- good" -else - echo "no -- error" - echo "Differences are as follows:" - cat $differences_file - echo -fi - -rm -f $differences_file - -############################################################################## -# Putting the results together -############################################################################## - -rm -f $archiver_test_data_file1 -rm -f $archiver_test_data_file2 -rm -f $archiver_test_data_file3 - -results_dir="ximian-config-results-`date +%Y%m%d`" -results_dir=`get_unused_tmpfile $results_dir` -mkdir $results_dir - -(cd $archive_dir && tar cf - *) | (cd $results_dir && tar xf -) -rm -rf $archive_dir - -if [ -d "$archive_dir-backup" ]; then - mv "$archive_dir-backup" $archive_dir -fi - -echo -echo "Test complete" -echo "Resulting archive data in $results_dir" diff --git a/archiver/tests/test-3.sh b/archiver/tests/test-3.sh deleted file mode 100755 index f1f46da40..000000000 --- a/archiver/tests/test-3.sh +++ /dev/null @@ -1,245 +0,0 @@ -#!/bin/sh -# -# test-3.sh -# Copyright (C) 2001 Ximian, Inc. -# Written by Bradford Hovinen <hovinen@ximian.com> -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. -# -# Test suite, part III -# -# Given an archive to work with (global or per-user): -# -# - Destroy the entire archive forcibly (rm -rf) -# - Create a new location inheriting from the default location -# (the default location should be created automatically in this case) -# - Sets the new location as the current one -# - Stores data for a particular backend, so that it should pass -# through to the parent location -# - Adds that backend to the new location (partial containment) -# - Stores data for that backend in the new location, so that the -# nodes should be subtracted -# - Retrieves the data for that backend from the new location, so -# that the nodes should be merged - -XIMIAN_ARCHIVER=${XIMIAN_ARCHIVER:-'../ximian-archiver'} - -function get_unused_tmpfile () { - tmp_file_no=0 - - while [ -e "/tmp/$1-$tmp_file_no" ]; do - let 'tmp_file_no=tmp_file_no+1' - done - - echo "/tmp/$1-$tmp_file_no"; -} - -function run_command () { - input_param=$1 - shift - - if [ "x$use_gdb" == "xyes" ]; then - commands_file=`get_unused_tmpfile gdb-commands-file` - echo "set args $extra_args $@ <$input_param" >$commands_file - gdb ../.libs/ximian-archiver -x $commands_file - rm -f $commands_file - else - echo "Running archiver program with the following command line:" >&2 - echo "$XIMIAN_ARCHIVER $extra_args $@ <$input_param" >&2 - $XIMIAN_ARCHIVER $extra_args $@ <$input_param - echo - fi -} - -if [ "x$1" == "x" ]; then - echo "Usage: test-2.sh --global|--per-user [--gdb]" - exit 1 -fi - -for test_option; do - case "$test_option" in - --global) - extra_args="--global" - archive_dir=/usr/share/ximian-config - ;; - - --per-user) - extra_args="" - archive_dir=$HOME/.gnome/ximian-config - ;; - - --gdb) - use_gdb=yes - ;; - - *) - echo "Error -- invalid option: $test_option" - exit 1 - esac -done - -if [ -d $archive_dir ]; then - mv $archive_dir "$archive_dir-backup" -fi - -############################################################################## -# Test proper -############################################################################## - -run_command /dev/null --add-location --parent=default --location=Boston-Office -run_command /dev/null --change-location --location=Boston-Office - -# Test 1: Adding a backend (partial containment) and storing data that -# should be stored in the child location -# -# Note: These are not real data - -archiver_test_data_file1=`get_unused_tmpfile ximian-archiver-test-data`; - -cat >$archiver_test_data_file1 <<EOF -<?xml version="1.0"?> -<mouse-properties> - <acceleration>7</acceleration> - <threshold>1</threshold> - <fake-node id="1"> - <another-node>data</another-node> - </fake-node> - <fake-node id="2"> - <my-node>blah blah blah</my-node> - <another-node>more data</another-node> - </fake-node> -</mouse-properties> - -EOF - -run_command $archiver_test_data_file1 \ - --store --backend=mouse-properties-capplet - -run_command /dev/null --add-backend --partial \ - --backend=mouse-properties-capplet - -archiver_test_data_file2=`get_unused_tmpfile ximian-archiver-test-data`; - -cat >$archiver_test_data_file2 <<EOF -<?xml version="1.0"?> -<mouse-properties> - <acceleration>7</acceleration> - <threshold>3</threshold> - <fake-node id="1"> - <another-node>data</another-node> - </fake-node> - <fake-node id="2"> - <my-node>blah blah blah</my-node> - <another-node>different data</another-node> - </fake-node> -</mouse-properties> - -EOF - -run_command $archiver_test_data_file2 \ - --store --backend=mouse-properties-capplet --compare-parent - -# This should be the resulting file: - -archiver_test_data_file2_correct=`get_unused_tmpfile ximian-archiver-check`; - -cat >$archiver_test_data_file2_correct <<EOF -<?xml version="1.0"?> -<mouse-properties> - <threshold>3</threshold> - <fake-node id="2"> - <another-node>different data</another-node> - </fake-node> -</mouse-properties> -EOF - -# Test 2: Retrieve the mouse properties data from the location manager -# to see if node merging works properly - -archiver_test_data_file3=`get_unused_tmpfile ximian-archiver-test-data` - -run_command /dev/null --rollback --last --show \ - --backend=mouse-properties-capplet >$archiver_test_data_file3 - -############################################################################## -# Results check -############################################################################## - -echo -n "Checking whether the XML data match the XML data given..." - -differences_file=`get_unused_tmpfile differences` - -diff -u "$archive_dir/Boston-Office/00000000.xml" \ - $archiver_test_data_file2_correct \ - >$differences_file - -if [ ! -s $differences_file ]; then - echo "yes -- good" -else - echo "no -- error" - echo "Differences are as follows:" - cat $differences_file - echo -fi - -rm -f $differences_file - -echo -n "Checking whether the XML data retrieved match the XML data given..." - -differences_file=`get_unused_tmpfile differences` - -diff -u $archiver_test_data_file3 $archiver_test_data_file2 >$differences_file - -if [ ! -s $differences_file ]; then - echo "yes -- good" -else - echo "no -- error" - echo "Check manually to see whether this is correct. Nodes may be" - echo "out of order." - echo "File retrieved is as follows:" - cat $archiver_test_data_file3 - echo - echo "File is supposed to be as follows:" - cat $archiver_test_data_file2 - echo -fi - -rm -f $differences_file - -############################################################################## -# Putting the results together -############################################################################## - -rm -f $archiver_test_data_file1 -rm -f $archiver_test_data_file2 -rm -f $archiver_test_data_file3 -rm -f $archiver_test_data_file4 -rm -f $archiver_test_data_file5 - -results_dir="ximian-config-results-`date +%Y%m%d`" -results_dir=`get_unused_tmpfile $results_dir` -mkdir $results_dir - -(cd $archive_dir && tar cf - *) | (cd $results_dir && tar xf -) -rm -rf $archive_dir - -if [ -d "$archive_dir-backup" ]; then - mv "$archive_dir-backup" $archive_dir -fi - -echo -echo "Test complete" -echo "Resulting archive data in $results_dir" diff --git a/archiver/util.c b/archiver/util.c deleted file mode 100644 index b1759cd62..000000000 --- a/archiver/util.c +++ /dev/null @@ -1,113 +0,0 @@ -/* -*- mode: c; style: linux -*- */ - -/* util.c - * Copyright (C) 2000-2001 Ximian, Inc. - * - * Written by Bradford Hovinen (hovinen@ximian.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <ctype.h> -#include <stdlib.h> -#include <string.h> - -#include "util.h" - -/* Read a fixed-digit number from a string, advancing the string - * pointer. Return TRUE if the extraction was successful, FALSE if - * there was no number to extract or if the number was too short. - */ - -gboolean -extract_number (char **str, int *number, int digits) -{ - char buf[64]; - - if (!isdigit (**str)) return FALSE; - if (digits > 63) digits = 63; - - strncpy (buf, *str, digits); - buf[digits] = '\0'; - *number = atoi (buf); - if (strlen (buf) < digits) return FALSE; - *str += digits; - return TRUE; -} - -struct tm * -parse_date (char *str) -{ - struct tm *date; - gboolean ok; - gint value; - - ok = extract_number (&str, &value, 4); - if (!ok) return NULL; - - date = g_new (struct tm, 1); - date->tm_isdst = 0; - date->tm_year = value - 1900; - date->tm_mon = 11; - date->tm_mday = 31; - date->tm_hour = 23; - date->tm_min = 59; - date->tm_sec = 59; - - if (extract_number (&str, &value, 2)) - date->tm_mon = value - 1; - else - return date; - - if (extract_number (&str, &value, 2)) - date->tm_mday = value; - else - return date; - - if (extract_number (&str, &value, 2)) - date->tm_hour = value; - else - return date; - - if (extract_number (&str, &value, 2)) - date->tm_min = value; - else - return date; - - if (extract_number (&str, &value, 2)) - date->tm_sec = value; - -#ifdef __USE_BSD - date->tm_zone = "GMT"; - date->tm_gmtoff = 0; -#endif - - return date; -} - -struct tm * -dup_date (const struct tm *date) -{ - struct tm *date1; - - date1 = g_new (struct tm, 1); - memcpy (date1, date, sizeof (struct tm)); - return date1; -} diff --git a/archiver/util.h b/archiver/util.h deleted file mode 100644 index c800d833a..000000000 --- a/archiver/util.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -*- mode: c; style: linux -*- */ - -/* util.h - * Copyright (C) 2000-2001 Ximian, Inc. - * - * Written by Bradford Hovinen (hovinen@ximian.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#ifndef __UTIL_H -#define __UTIL_H - -#include <time.h> -#include <glib.h> - -/* Uncomment this if you want debugs: */ -#define DEBUG_ME_MORE - -#ifdef DEBUG_ME_MORE -# 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 -#else -/* This was redefined here because it was messing with the frontend->backend - * talk. Arturo */ -# define DEBUG_MSG(str, args...) -#endif - -gboolean extract_number (char **str, int *number, int digits); -struct tm *parse_date (char *str); -struct tm *dup_date (const struct tm *date); - -#endif /* __UTIL_H */ diff --git a/archiver/versioning-spec b/archiver/versioning-spec deleted file mode 100644 index 2cd6bd912..000000000 --- a/archiver/versioning-spec +++ /dev/null @@ -1,193 +0,0 @@ -Configuration rollback, location management, and cluster support -Copyright (C) 2001 Ximian, Inc. -Written by Bradford Hovinen <hovinen@ximian.com> - -I. Basic architecture - -A. Components - -1. Ximian Configuration Manager - -The GUI shell, here referred to as the Ximian Configuration Manager -(XCM), acts as launching point for the capplets and Ximian Tools, -and a control center for managing rollback, location management, and -clustering. It launches other components and knows how to find -archived configuration data for rollback. When rollback or a change of -location is required, it invokes the required backends or capplets -with the --set option and feeds the required XML to them. - -2. Capplets - -Capplets handle user configuration; they combine the front and back -ends into one process. They will eventually run as Bonobo controls -implementing the Bonobo::Capplet interface, but for now they are run -as regular processes. They all support the --get and --set command -line options (which will be methods in the Bonobo::Capplet -interface). --get returns an XML description of the capplet's state -for archival purposes and --set takes an XML description of the -capplet's state and applies those settings to the desktop. - -3. Ximian Setup Tools (XSTs) - -These programs are for system-wide configuration and must run as root -in order to apply changes. They may also run as a regular user in -`read-only' mode. They have separate front- and backends, the former -typically written in C and the latter normally written in Perl. This -facilitates in-place modification of existing configuration files -without the need for creating out own separate, incompatible way of -configuring the system. The backends support the --get and --set -arguments, analogous to the arguments in capplets mentioned above. - -2. Root manager - -The root manager process runs as root and is launched through -gnome-su. It accepts on stdin a set of programs to launch, one per -line, with command line arguments. XCM uses it to launch Ximian Setup -Tools so that they run as root, without needing to ask the user for a -password each time a tool is run. The root manager is run exactly once -through console-helper the first time a tool that must be run as root -is invoked. On subsequent occasions the command to start the tool is -passed to the root manager through stdin. - -3. The script do-changes - -do-changes is responsible for archiving changes made to the system's -configuration and passing them on to the backend, if appropriate. It -accepts a stream of XML on stdin and stores this XML in the -configuration archive directory. If a backend is specified on the -command line, it also spawns the backend process with the --set option -and feeds the XML to it through stdin. - -II. Configuration process - -When a user makes changes to either his own configuration or that of -the system, those changes must be archived so that the system may be -rolled back in the future. In the case of capplets, the capplet -currently dumps an XML snapshot of its current state to the script -do-changes when the user clicks `Ok'. do-changes then archives the -state in ~/.gnome/config/<location>/<revision> where <location> is the -name of the active location (cf. section IV) and <revision> is -incremented after each change. - -When the capplets are converted into Bonobo controls, the situation -will be slightly different. XCM will be the recipient of the `Ok' -signal, so it will invoke the OKClicked() method of the -Bonobo::Capplet interface on the appropriate capplet. It will also -invoke the GetXML() method of the same interface in order to retrieve -an XML snapshot of the state and store that snapshot with -do-changes. Hence, much of the action moves from the capplet to XCM. - -In the case of Ximian Setup Tools, the frontend passes the XML through -the do-changes script to the backend whenever the `Ok' button is -clicked. It passes to do-changes the argument --backend <backend name> -so that do-changes will also invoke the indicated backend and pass the -XML to it. - -III. Rollback process - -From within the XCM, the user may elect to roll back either his -personal configuration or that of the system to a particular -date. XCM looks for a revision directory in the current location -profile with the most recent modification date that is not more recent -than the date specified by the user. XCM also has a list of what -capplets (or XSTs) constitute a complete snapshot of the system's -configuration. In order to perform a complete rollback, it backtracks -through the revision directories, picking up XML snapshots of capplets -until it has a complete set and applies them through the --set -method. In the case of XSTs, the XCM knows how to invoke the backend -and does so as necessary. - -IV. Location management - -The system may have one or more profiles, each giving different system -configurations. For example, a user may own a laptop and wish to hook -that laptop up to different networks at different times. Each network -may be located in a different time zone, have different network -configuration parameters (e.g., DHCP vs. static IPs), and use different -default printers. When the user hooks his laptop up in a particular -network, it would be advantageous to switch to that network's -configuration with a minimum of hassle. - -As mentioned above, configuration data is stored in separate -directories corresponding to the name of a given location. XCM has the -ability to apply a set of configuration files from a given location in -a manner similar to the rollback procedure described above. When the -user selects an alternative configuration, it simply goes through the -revision history for that location, pulls a complete set of -configuration files, and applies them. The procedure is similar for -both capplets and XSTs. - -In addition, locations may be expressed hierarchically. For example, a -user might specify a location called `Boston' that describes language, -time zone, currency, and other locale data, and another location called -`Boston Office' that includes network parameters. `Boston Office' -inherits its locale data from `Boston', overriding the latter's -network configuration. - -To implement this, each location directory contains some metadata that -describes what configuration data is valid for it and what other -configuration it inherits from. There are one or more root -configurations that contain a complete set of data. When applying a -new location, XCM looks first at that location's directory, pulling a -complete set of all the configuration data defined by that location, -and then goes to the next level up in the location hierarchy and does -the same thing. It also keeps track of the common subtree root between -the old and new locations so that only the configuration items that -actually change are collected. - -From a user's perspective, the XCM will present a tree showing the -existing locations. Users may create a new location derived from an -existing one. When the user elects to configure a particular location, -the XCM shell includes icons that are grayed out, indicating that -those configuration items are not set in this particular location. If -the user attempts to change them, they become specific to that -particular location and are recolored accordingly. - -V. Clustering - -A single server may archive the configuration for a large number of -individual workstations, providing configuration data to each of the -clients on demand. An administrator can then push configuration -updates out to each machine with the press of a button, rather than -having to go to each machine and update it manually. - -To enable this, each client machine will run a daemon that accepts -configuration data pushed out by the server. Some sort of public key -signing will be implemented to ensure that this is done securely. On -the server end, a series of host groups is maintained, each one -containing a set of hosts. These form the top two levels of a -configuration hierarchy not unlike what is described above. Each host -may override certain configuration values for the cluster as a -whole. The cluster may also have multiple `locations', e.g. for -configuring a computer lab for computer science during one class and -for math during another. Locations may be selected down to the -granularity of a single host, or for the entire cluster at -once. Cluster-wide configurations occur between the cluster and host -level in the configuration hierarchy. - -VI. Issues - -1. We need a way to get an XML state without actually applying -changes, so that the user can configure a location without switching -to it. - -2. Can we make the XST frontends Bonobo controls, and can we have them -run as the regular user rather than as root? This would ensure that -certain user interface preferences, such as themes, are kept -consistent for a given user between capplets and XSTs. The way to -implement this is to have a method on the XCM interface called -RunBackend() which returns a BonoboObject referring to the backend -that implements the Bonobo::XSTBackend interface, which is similar to -the Bonobo::Capplet interface mentioned above. The interface defines -the GetXML and SetXML methods. The object should also implement -another, XST-specific interface to facilitate setting specific -configuration variables, so that live update may be implemented. The -root manager must then be extended to support some sort of secure -forwarding, allowing the user to access that particular CORBA object. - -3. If we make the XSTs into Bonobo controls, can we give them the same -Bonobo::Capplet interface that is given to the Capplets? This would -make everything a bit simpler from the XCM's perspective, since it -then does not need to know the difference between Capplets and -XSTs -- it then only needs to implement the RunBackend() method for -the benefit of the XSTs. |