gnome-control-center/archiver/backend-list.c
Bradford Hovinen afc3333a5a Added test-1.sh and test-2.sh, the first two tests in the test suite
2001-02-19  Bradford Hovinen  <hovinen@ximian.com>

	* Added test-1.sh and test-2.sh, the first two tests in the test suite

	* 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-02-20 02:43:35 +00:00

311 lines
7.3 KiB
C

/* -*- 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;
};
static GtkObjectClass *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);
guint
backend_list_get_type (void)
{
static guint backend_list_type = 0;
if (!backend_list_type) {
GtkTypeInfo backend_list_info = {
"BackendList",
sizeof (BackendList),
sizeof (BackendListClass),
(GtkClassInitFunc) backend_list_class_init,
(GtkObjectInitFunc) backend_list_init,
(GtkArgSetFunc) NULL,
(GtkArgGetFunc) NULL
};
backend_list_type =
gtk_type_unique (gtk_object_get_type (),
&backend_list_info);
}
return backend_list_type;
}
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;
parent_class = GTK_OBJECT_CLASS
(gtk_type_class (gtk_object_get_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);
}
GtkObject *
backend_list_new (gboolean is_global)
{
return gtk_object_new (backend_list_get_type (),
"is-global", is_global,
NULL);
}
gboolean
backend_list_contains (BackendList *backend_list, 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, 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, backend_id);
}
void
backend_list_remove (BackendList *backend_list, 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_remove (backend_list->p->backend_ids, backend_id);
}
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);
}