Below is the file 'ldb-backend.c' from this revision. You can also download the file.

/* GConf ldb backend
 * Copyright (C) 1999, 2000, 2002 Red Hat Inc.
 * Copyright (C) 2005 Grahame Bowland.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/*
 * designed for correctness, speed. uses ldb for local storage.
 */

#include <gconf/gconf-backend.h>
#include <gconf/gconf-internals.h>
#include <gconf/gconf.h>
#include <glib.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pwd.h>

/* ldb irritatingly needs headers it doesn't include itself */
#include <stdint.h>
#include <stdarg.h>
#include "talloc.h"
#include <ldb.h>

#define ROOT_DIRECTORY_PARENT			-1
#define ROOT_DIRECTORY_NAME			""

/* used for columns, they indicate which gconf type we're actually storing */
#define T_STRING				"s"
#define T_INT					"i"
#define T_FLOAT					"f"
#define T_BOOL					"b"
#define T_SCHEMA				"c"
#define T_LIST					"l"
#define T_PAIR					"p"

/*
 * VTable functions
 */

 /* shutdown() is a BSD libc function */
static void           x_shutdown      (GError           **err);
static GConfSource*   resolve_address (const char        *address,
                                       GError           **err);
static void           lock            (GConfSource       *source,
                                       GError           **err);
static void           unlock          (GConfSource       *source,
                                       GError           **err);
static gboolean       readable        (GConfSource       *source,
                                       const char        *key,
                                       GError           **err);
static gboolean       writable        (GConfSource       *source,
                                       const char        *key,
                                       GError           **err);
static GConfValue*    query_value     (GConfSource       *source,
                                       const char        *key,
                                       const char       **locales,
                                       char             **schema_name,
                                       GError           **err);
static GConfMetaInfo* query_metainfo  (GConfSource       *source,
                                       const char        *key,
                                       GError           **err);
static void           set_value       (GConfSource       *source,
                                       const char        *key,
                                       const GConfValue  *value,
                                       GError           **err);
static GSList*        all_entries     (GConfSource       *source,
                                       const char        *dir,
                                       const char       **locales,
                                       GError           **err);
static GSList*        all_subdirs     (GConfSource       *source,
                                       const char        *dir,
                                       GError           **err);
static void           unset_value     (GConfSource       *source,
                                       const char        *key,
                                       const char        *locale,
                                       GError           **err);
static gboolean       dir_exists      (GConfSource       *source,
                                       const char        *dir,
                                       GError           **err);
static void           remove_dir      (GConfSource       *source,
                                       const char        *dir,
                                       GError           **err);
static void           set_schema      (GConfSource       *source,
                                       const char        *key,
                                       const char        *schema_key,
                                       GError           **err);
static gboolean       sync_all        (GConfSource       *source,
                                       GError           **err);
static void           destroy_source  (GConfSource       *source);
static void           clear_cache     (GConfSource       *source);
static void           blow_away_locks (const char        *address);

typedef struct
{
	GConfSource source; /* inherit from GConfSource */
	gchar *dbfile;
	GConfLock* lock;
	struct ldb_context *ldb;
} LdbSource;

/* create a new LdbSource, if possible.
 * otherwise, return NULL
 */
static LdbSource *
ldb_new (const char *dbfile, GConfLock *lock)
{
	LdbSource *ss;
	mode_t m;
	int rv;

	g_return_val_if_fail (dbfile != NULL, NULL);

	ss = g_new0 (LdbSource, 1);
	ss->dbfile = g_strdup (dbfile);
	ss->lock = lock;
	/* if the database does not exist, ldb will create it. we must make sure
	 * it is created in with secure permissions
	 */
	m = umask(077);
	ss->ldb = ldb_init (NULL);
	if (ss->ldb != NULL) {
		ldb_connect (ss->ldb, ss->dbfile, 0, (const char **)NULL);
	}
	umask(m);

	if (rv) {
		gconf_log (GCL_ERR, _("Couldn't open database \"%s\"\n"), ss->dbfile);
		g_free (ss->dbfile);
		g_free (ss);
		return NULL;
	}
	return ss;
}

static void
ldb_destroy (LdbSource *ss)
{
	GError* error = NULL;
	g_return_if_fail (ss != NULL);

	if (ss->lock != NULL && !gconf_release_lock (ss->lock, &error)) {
		gconf_log (GCL_ERR, _("Failed to give up lock on database \"%s\" : %s"),
				ss->dbfile, error->message);
		g_error_free (error);
		error = NULL;
	}

	talloc_free (ss->ldb);
	g_free (ss->dbfile);
	g_free (ss);
}

/* public methods are all below this line */

static GConfBackendVTable markup_vtable = {
  sizeof (GConfBackendVTable),
  x_shutdown,
  resolve_address,
  lock,
  unlock,
  readable,
  writable,
  query_value,
  query_metainfo,
  set_value,
  all_entries,
  all_subdirs,
  unset_value,
  dir_exists,
  remove_dir,
  set_schema,
  sync_all,
  destroy_source,
  clear_cache,
  blow_away_locks,
  NULL, /* set_notify_func */
  NULL, /* add_listener    */
  NULL  /* remove_listener */
};

static void
x_shutdown (GError **err)
{
  gconf_log (GCL_DEBUG, _("Unloading ldb backend module."));
}

static void
lock (GConfSource *source,
      GError **err)
{

}

static void
unlock (GConfSource *source,
        GError **err)
{


}

static gboolean
readable (GConfSource *source,
          const char  *key,
          GError     **err)
{
  return TRUE;
}

static gboolean
writable (GConfSource  *source,
          const char   *key,
          GError      **err)
{
  return TRUE;
}

static GConfValue*
query_value (GConfSource *source,
             const char  *key,
             const char **locales,
             char       **schema_name,
             GError     **err)
{
	gconf_log (GCL_DEBUG, "query_value: %s", key);

	return NULL;
}

static GConfMetaInfo*
query_metainfo (GConfSource *source,
                const char  *key,
                GError     **err)
{
	gconf_log (GCL_DEBUG, "query_metainfo: %s", key);

	return NULL;
}

static void
set_value (GConfSource      *source,
           const char       *key,
           const GConfValue *value,
           GError          **err)
{
	gconf_log (GCL_DEBUG, "set_value: %s", key);
}

/* all entries in the directory pointed to by key */
static GSList*
all_entries (GConfSource *source,
             const char  *key,
             const char **locales,
             GError     **err)
{
	gconf_log (GCL_DEBUG, "all_entries: %s", key);

	return NULL;
}

/* all subdirectories of the directory pointed to by key */
static GSList*
all_subdirs (GConfSource *source,
             const char  *key,
             GError     **err)
{
	gconf_log (GCL_DEBUG, "all_subdirs: %s", key);

	return NULL;
}

static void
unset_value (GConfSource *source,
             const char  *key,
             const char  *locale,
             GError     **err)
{
	gconf_log (GCL_DEBUG, "unset_value: %s", key);

}

static gboolean
dir_exists (GConfSource *source,
            const char  *key,
            GError     **err)
{
	gconf_log (GCL_DEBUG, "dir_exists: %s", key);

	return FALSE;
}

static void
remove_dir (GConfSource *source,
            const char  *key,
            GError     **err)
{
	gconf_log (GCL_DEBUG, "remove_dir: %s", key);

}

static void
set_schema (GConfSource *source,
            const char  *key,
            const char  *schema_name,
            GError     **err)
{
	gconf_log (GCL_DEBUG, "set_schema: %s", key);

}

static gboolean
sync_all (GConfSource *source,
          GError     **err)
{

	return FALSE;
}

static void
destroy_source (GConfSource *source)
{
	ldb_destroy ((LdbSource *)source);
}

static void
clear_cache (GConfSource *source)
{

}

static void
blow_away_locks (const char *address)
{

}

static GConfSource*
resolve_address (const char *address,
                 GError    **err)
{
	LdbSource *new_source;
	GConfLock *lock;
	char *dbfile;

	gconf_log (GCL_DEBUG, "ldb module initialising, address=%s", address);

	dbfile = gconf_address_resource (address);
	if (!dbfile)
		return NULL;

	/* for now, let's ignore locking; ldb does it anyway
	 * and probably better than we'd manage
	 */
	lock = NULL;

	new_source = ldb_new (dbfile, lock);
	if (!new_source) {
		return NULL;
	}
	((GConfSource *)new_source)->flags = 0;
	gconf_log (GCL_ERR, "ldb dbfile at: %s\n", dbfile);

	g_free (dbfile);

	return (GConfSource *)new_source;
}

/**************** EXPORT *********************/

/* Initializer */

G_MODULE_EXPORT const char*
g_module_check_init (GModule *module)
{
  gconf_log (GCL_DEBUG, _("Initializing Markup backend module"));

  return NULL;
}

G_MODULE_EXPORT GConfBackendVTable*
gconf_backend_get_vtable (void)
{
  return &markup_vtable;
}