~ubuntu-branches/ubuntu/quantal/gconf/quantal

« back to all changes in this revision

Viewing changes to gconf/gconf-backend.c

  • Committer: Bazaar Package Importer
  • Author(s): Josselin Mouette
  • Date: 2007-11-01 18:47:26 UTC
  • mto: (7.1.1 lenny) (1.2.1) (76.1.1 oneiric-proposed)
  • mto: This revision was merged to the branch mainline in revision 7.
  • Revision ID: james.westby@ubuntu.com-20071101184726-e3e4cxfcp41tz6ui
Tags: upstream-2.20.1
ImportĀ upstreamĀ versionĀ 2.20.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
#include <sys/stat.h>
27
27
#include <unistd.h>
28
28
 
 
29
 
 
30
/* Don't allow special characters in configuration source addresses.
 
31
 * The important one here is not to allow ';' because we use that
 
32
 * internally as a list delimiter. See GCONF_DATABASE_LIST_DELIM
 
33
 */
 
34
static const char invalid_chars[] = 
 
35
#ifndef G_OS_WIN32
 
36
  /* Space is common in user names (and thus home directories) on Windows */
 
37
  " "
 
38
#endif
 
39
  "\t\r\n\"$&<>,+=#!()'|{}[]?~`;%\\";
 
40
 
 
41
static gboolean
 
42
gconf_address_valid (const char  *address,
 
43
                     char      **why_invalid)
 
44
{
 
45
  const char *s;
 
46
 
 
47
  g_return_val_if_fail (address != NULL, FALSE);
 
48
 
 
49
  if (why_invalid)
 
50
    *why_invalid = NULL;
 
51
 
 
52
  s = address;
 
53
  while (*s)
 
54
    {
 
55
      const char *inv = invalid_chars;
 
56
 
 
57
      while (*inv)
 
58
        {
 
59
          if (*inv == *s)
 
60
            {
 
61
              if (why_invalid)
 
62
                *why_invalid = g_strdup_printf(_("`%c' is an invalid character in a configuration storage address"), *s);
 
63
              return FALSE;
 
64
            }
 
65
          ++inv;
 
66
        }
 
67
 
 
68
      ++s;
 
69
    }
 
70
 
 
71
  return TRUE;
 
72
}
 
73
 
29
74
gchar* 
30
75
gconf_address_backend(const gchar* address)
31
76
{
70
115
      else
71
116
        {
72
117
          ++start;
 
118
#ifdef G_OS_WIN32
 
119
          return _gconf_win32_replace_prefix (start);
 
120
#else
73
121
          return g_strdup(start);
 
122
#endif
74
123
        }
75
124
    }
76
125
}
136
185
 
137
186
  g_free(back);
138
187
 
139
 
  if (gconf_file_exists(retval))
 
188
  if (g_file_test(retval, G_FILE_TEST_EXISTS))
140
189
    {
141
190
      g_free(file);
142
191
 
156
205
 
157
206
      g_free(dir);
158
207
      
159
 
      if (gconf_file_exists(retval))
 
208
      if (g_file_test(retval, G_FILE_TEST_EXISTS))
160
209
        {
161
210
          g_free(file);
162
211
          return retval;
178
227
 
179
228
static GHashTable* loaded_backends = NULL;
180
229
 
 
230
static gboolean
 
231
gconf_backend_verify_vtable (GConfBackendVTable  *vtable,
 
232
                             GConfBackendVTable  *vtable_copy,
 
233
                             const char          *backend_name,                     
 
234
                             GError             **err)
 
235
{
 
236
  int i;
 
237
  struct
 
238
  {
 
239
    char  *name;
 
240
    gsize  offset;
 
241
  } required_vtable_functions[] = {
 
242
    { "shutdown",        G_STRUCT_OFFSET(GConfBackendVTable, shutdown)        },
 
243
    { "resolve_address", G_STRUCT_OFFSET(GConfBackendVTable, resolve_address) },
 
244
    { "query_value",     G_STRUCT_OFFSET(GConfBackendVTable, query_value)     },
 
245
    { "query_metainfo",  G_STRUCT_OFFSET(GConfBackendVTable, query_metainfo)  },
 
246
    { "set_value",       G_STRUCT_OFFSET(GConfBackendVTable, set_value)       },
 
247
    { "all_entries",     G_STRUCT_OFFSET(GConfBackendVTable, all_entries)     },
 
248
    { "all_subdirs",     G_STRUCT_OFFSET(GConfBackendVTable, all_subdirs)     },
 
249
    { "unset_value",     G_STRUCT_OFFSET(GConfBackendVTable, unset_value)     },
 
250
    { "dir_exists",      G_STRUCT_OFFSET(GConfBackendVTable, dir_exists)      },
 
251
    { "remove_dir",      G_STRUCT_OFFSET(GConfBackendVTable, remove_dir)      },
 
252
    { "set_schema",      G_STRUCT_OFFSET(GConfBackendVTable, set_schema)      },
 
253
    { "sync_all",        G_STRUCT_OFFSET(GConfBackendVTable, sync_all)        },
 
254
    { "destroy_source",  G_STRUCT_OFFSET(GConfBackendVTable, destroy_source)  },
 
255
    { "blow_away_locks", G_STRUCT_OFFSET(GConfBackendVTable, blow_away_locks) }
 
256
  };
 
257
 
 
258
  if (!vtable)
 
259
    {
 
260
      gconf_set_error(err,
 
261
                      GCONF_ERROR_FAILED, _("Backend `%s' failed return a vtable\n"),
 
262
                      backend_name);
 
263
      return FALSE;
 
264
    }
 
265
 
 
266
  /* Create a copy in case vtable size doesn't match */
 
267
  memcpy(vtable_copy, vtable, MIN(vtable->vtable_size, sizeof(GConfBackendVTable)));
 
268
 
 
269
  vtable_copy->vtable_size = sizeof(GConfBackendVTable);
 
270
 
 
271
  for (i = 0; i < G_N_ELEMENTS(required_vtable_functions); i++)
 
272
    {
 
273
      if (G_STRUCT_MEMBER_P(vtable_copy, required_vtable_functions[i].offset) == NULL)
 
274
        {
 
275
          gconf_set_error(err,
 
276
                          GCONF_ERROR_FAILED, _("Backend `%s' missing required vtable member `%s'\n"),
 
277
                          backend_name,
 
278
                          required_vtable_functions[i].name);
 
279
          return FALSE;
 
280
        }
 
281
    }
 
282
 
 
283
  return TRUE;
 
284
}
 
285
 
181
286
GConfBackend* 
182
287
gconf_get_backend(const gchar* address, GError** err)
183
288
{
184
289
  GConfBackend* backend;
185
290
  gchar* name;
 
291
  gchar* why_invalid;
186
292
 
187
293
  if (loaded_backends == NULL)
188
294
    {
189
295
      loaded_backends = g_hash_table_new(g_str_hash, g_str_equal);
190
296
    }
 
297
 
 
298
  why_invalid = NULL;
 
299
  if (!gconf_address_valid (address, &why_invalid))
 
300
    {
 
301
      g_assert (why_invalid != NULL);
 
302
      gconf_set_error (err, GCONF_ERROR_BAD_ADDRESS, _("Bad address `%s': %s"),
 
303
                       address, why_invalid);
 
304
      g_free (why_invalid);
 
305
      return NULL;
 
306
    }
 
307
 
191
308
  name = gconf_address_backend(address);
192
309
      
193
310
  if (name == NULL)
219
336
          if (!g_module_supported())
220
337
            g_error(_("GConf won't work without dynamic module support (gmodule)"));
221
338
              
222
 
          module = g_module_open(file, 0);
 
339
          module = g_module_open(file, G_MODULE_BIND_LAZY);
223
340
              
224
341
          g_free(file);
225
342
          
226
343
          if (module == NULL)
227
344
            {
228
 
              gchar* error = g_module_error();
229
345
              gconf_set_error(err,
230
346
                              GCONF_ERROR_FAILED, _("Error opening module `%s': %s\n"),
231
 
                              name, error);
 
347
                              name, g_module_error());
232
348
              g_free(name);
233
349
              return NULL;
234
350
            }
237
353
                               "gconf_backend_get_vtable", 
238
354
                               (gpointer*)&get_vtable))
239
355
            {
 
356
              gconf_set_error(err,
 
357
                              GCONF_ERROR_FAILED, _("Error initializing module `%s': %s\n"),
 
358
                              name, g_module_error());
 
359
              g_module_close(module);
240
360
              g_free(name);
241
361
              return NULL;
242
362
            }
245
365
 
246
366
          backend->module = module;
247
367
 
248
 
          backend->vtable = (*get_vtable)();
 
368
          if (!gconf_backend_verify_vtable((*get_vtable)(), &backend->vtable, name, err))
 
369
            {
 
370
              g_module_close(module);
 
371
              g_free(name);
 
372
              g_free(backend);
 
373
              return NULL;
 
374
            }
249
375
              
250
376
          backend->name = name;
251
377
 
287
413
    {
288
414
      GError* error = NULL;
289
415
      
290
 
      (*backend->vtable->shutdown)(&error);
 
416
      (*backend->vtable.shutdown)(&error);
291
417
 
292
418
      if (error != NULL)
293
419
        {
319
445
  gchar** iter;
320
446
  GConfSource* retval;
321
447
 
322
 
  retval = (*backend->vtable->resolve_address)(address, err);
 
448
  retval = (*backend->vtable.resolve_address)(address, err);
323
449
 
324
450
  if (retval == NULL)
325
451
    return NULL;
353
479
  return retval;
354
480
}
355
481
 
356
 
 
357
 
 
 
482
void
 
483
gconf_blow_away_locks (const gchar* address)
 
484
{
 
485
  GConfBackend* backend;
 
486
 
 
487
  backend = gconf_get_backend (address, NULL);
 
488
 
 
489
  if (backend != NULL)
 
490
    {
 
491
      (*backend->vtable.blow_away_locks) (address);
 
492
    }
 
493
}