GConfSource* gconf_backend_resolve_address (GConfBackend* backend, const gchar* address, GError** err) { gchar** flags; gchar** iter; GConfSource* retval; retval = (*backend->vtable.resolve_address)(address, err); if (retval == NULL) return NULL; flags = gconf_address_flags(address); if (flags == NULL) return retval; /* FIXME this is now already done in the XML backend, * so the following code is pointless, except that I think * the BDB backend isn't fixed. The reason it needs to go in * the backend is so that we don't try to get a lock on read-only sources. */ iter = flags; while (*iter) { if (strcmp(*iter, "readonly") == 0) { retval->flags &= ~(GCONF_SOURCE_ALL_WRITEABLE); retval->flags |= GCONF_SOURCE_NEVER_WRITEABLE; } /* no need to handle readwrite because backends should always default to "maximum read/write privileges" */ ++iter; } g_strfreev(flags); return retval; }
static GConfSource* resolve_address (const gchar* address, GError** err) { struct stat statbuf; gchar* root_dir; XMLSource* xsource; GConfSource* source; gint flags = 0; GConfLock* lock = NULL; guint dir_mode = 0700; guint file_mode = 0600; gchar** address_flags; gchar** iter; gboolean force_readonly; root_dir = get_dir_from_address (address, err); if (root_dir == NULL) return NULL; if (g_stat (root_dir, &statbuf) == 0) { /* Already exists, base our dir_mode on it */ dir_mode = _gconf_mode_t_to_mode (statbuf.st_mode); /* dir_mode without search bits */ file_mode = dir_mode & (~0111); } else if (g_mkdir (root_dir, dir_mode) < 0) { /* Error out even on EEXIST - shouldn't happen anyway */ gconf_set_error (err, GCONF_ERROR_FAILED, _("Could not make directory `%s': %s"), (gchar *)root_dir, g_strerror (errno)); g_free (root_dir); return NULL; } force_readonly = FALSE; address_flags = gconf_address_flags (address); if (address_flags) { iter = address_flags; while (*iter) { if (strcmp (*iter, "readonly") == 0) { force_readonly = TRUE; break; } ++iter; } } g_strfreev (address_flags); { /* See if we're writable */ gboolean writable; int fd; gchar* testfile; writable = FALSE; if (!force_readonly) { testfile = g_strconcat(root_dir, "/.testing.writeability", NULL); fd = g_open(testfile, O_CREAT|O_WRONLY, S_IRWXU); if (fd >= 0) { writable = TRUE; close(fd); } g_unlink(testfile); g_free(testfile); } if (writable) flags |= GCONF_SOURCE_ALL_WRITEABLE; /* We only do locking if it's writable, * and if not using local locks, * which is sort of broken but close enough */ if (writable && !gconf_use_local_locks ()) { gchar* lockdir; lockdir = get_lock_dir_from_root_dir (root_dir); lock = gconf_get_lock(lockdir, err); if (lock != NULL) gconf_log(GCL_DEBUG, "Acquired lock directory `%s'", lockdir); g_free(lockdir); if (lock == NULL) { g_free(root_dir); return NULL; } } } { /* see if we're readable */ gboolean readable = FALSE; GDir* d; d = g_dir_open(root_dir, 0, NULL); if (d != NULL) { readable = TRUE; g_dir_close(d); } if (readable) flags |= GCONF_SOURCE_ALL_READABLE; } if (!(flags & GCONF_SOURCE_ALL_READABLE) && !(flags & GCONF_SOURCE_ALL_WRITEABLE)) { gconf_set_error(err, GCONF_ERROR_BAD_ADDRESS, _("Can't read from or write to the XML root directory in the address \"%s\""), address); g_free(root_dir); return NULL; } /* Create the new source */ xsource = xs_new(root_dir, dir_mode, file_mode, lock); gconf_log(GCL_DEBUG, _("Directory/file permissions for XML source at root %s are: %o/%o"), root_dir, dir_mode, file_mode); source = (GConfSource*)xsource; source->flags = flags; g_free(root_dir); return source; }