summaryrefslogtreecommitdiff
path: root/archiver/config-log.c
diff options
context:
space:
mode:
Diffstat (limited to 'archiver/config-log.c')
-rw-r--r--archiver/config-log.c1071
1 files changed, 0 insertions, 1071 deletions
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 (&current_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);
- }
-}