~ubuntu-branches/ubuntu/oneiric/gconf/oneiric-proposed

« back to all changes in this revision

Viewing changes to gconf/gconf-database.c

  • Committer: Bazaar Package Importer
  • Author(s): Takuo KITAME
  • Date: 2002-03-17 01:51:39 UTC
  • Revision ID: james.westby@ubuntu.com-20020317015139-z4f8fdg1hoe049g0
Tags: upstream-1.0.9
ImportĀ upstreamĀ versionĀ 1.0.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* GConf
 
2
 * Copyright (C) 1999, 2000 Red Hat Inc.
 
3
 *
 
4
 * This library is free software; you can redistribute it and/or
 
5
 * modify it under the terms of the GNU Library General Public
 
6
 * License as published by the Free Software Foundation; either
 
7
 * version 2 of the License, or (at your option) any later version.
 
8
 *
 
9
 * This library is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
12
 * Library General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU Library General Public
 
15
 * License along with this library; if not, write to the
 
16
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
17
 * Boston, MA 02111-1307, USA.
 
18
 */
 
19
 
 
20
#include "gconf-database.h"
 
21
#include "gconf-listeners.h"
 
22
#include "gconf-sources.h"
 
23
#include "gconf-locale.h"
 
24
#include "gconfd.h"
 
25
#include <unistd.h>
 
26
#include <liboaf/liboaf.h>
 
27
#include <time.h>
 
28
#include <stdlib.h>
 
29
 
 
30
/* This makes hash table safer when debugging */
 
31
#ifndef GCONF_ENABLE_DEBUG
 
32
#define safe_g_hash_table_insert g_hash_table_insert
 
33
#else
 
34
static void
 
35
safe_g_hash_table_insert(GHashTable* ht, gpointer key, gpointer value)
 
36
{
 
37
  gpointer oldkey = NULL, oldval = NULL;
 
38
 
 
39
  if (g_hash_table_lookup_extended(ht, key, &oldkey, &oldval))
 
40
    {
 
41
      gconf_log(GCL_WARNING, "Hash key `%s' is already in the table!",
 
42
                (gchar*) key);
 
43
      return;
 
44
    }
 
45
  else
 
46
    {
 
47
      g_hash_table_insert(ht, key, value);
 
48
    }
 
49
}
 
50
#endif
 
51
 
 
52
/*
 
53
 * Forward decls
 
54
 */
 
55
 
 
56
static GConfLocaleList* locale_cache_lookup(const gchar* locale);
 
57
 
 
58
typedef struct _Listener Listener;
 
59
 
 
60
struct _Listener {
 
61
  ConfigListener obj;
 
62
};
 
63
 
 
64
static Listener* listener_new(ConfigListener obj);
 
65
static void      listener_destroy(Listener* l);
 
66
 
 
67
/*
 
68
 * CORBA implementation of ConfigDatabase
 
69
 */
 
70
 
 
71
static CORBA_unsigned_long
 
72
impl_ConfigDatabase_add_listener(PortableServer_Servant servant,
 
73
                                 const CORBA_char * where,
 
74
                                 const ConfigListener who,
 
75
                                 CORBA_Environment * ev)
 
76
{
 
77
  GConfDatabase *db = (GConfDatabase*) servant;
 
78
 
 
79
  if (gconfd_check_in_shutdown (ev))
 
80
    return 0;
 
81
  
 
82
  return gconf_database_add_listener (db, who, where);
 
83
}
 
84
 
 
85
static void
 
86
impl_ConfigDatabase_remove_listener(PortableServer_Servant servant,
 
87
                                    CORBA_unsigned_long cnxn,
 
88
                                    CORBA_Environment * ev)
 
89
{
 
90
  GConfDatabase *db = (GConfDatabase*) servant;
 
91
 
 
92
  if (gconfd_check_in_shutdown (ev))
 
93
    return;
 
94
  
 
95
  gconf_database_remove_listener (db, cnxn);
 
96
}
 
97
 
 
98
static ConfigValue*
 
99
impl_ConfigDatabase_lookup_with_locale(PortableServer_Servant servant,
 
100
                                       const CORBA_char * key,
 
101
                                       const CORBA_char * locale,
 
102
                                       CORBA_boolean use_schema_default,
 
103
                                       CORBA_boolean * value_is_default,
 
104
                                       CORBA_boolean * value_is_writable,
 
105
                                       CORBA_Environment * ev)
 
106
{
 
107
  GConfDatabase *db = (GConfDatabase*) servant;
 
108
  GConfValue* val;
 
109
  GError* error = NULL;
 
110
  GConfLocaleList* locale_list;
 
111
  gboolean is_default = FALSE;
 
112
  gboolean is_writable = TRUE;
 
113
 
 
114
  if (gconfd_check_in_shutdown (ev))
 
115
    return invalid_corba_value ();
 
116
  
 
117
  locale_list = locale_cache_lookup(locale);
 
118
  
 
119
  val = gconf_database_query_value(db, key, locale_list->list,
 
120
                                   use_schema_default,
 
121
                                   NULL,
 
122
                                   &is_default,
 
123
                                   &is_writable,
 
124
                                   &error);
 
125
 
 
126
  *value_is_default = is_default;
 
127
  *value_is_writable = is_writable;
 
128
  
 
129
  gconf_locale_list_unref(locale_list);
 
130
  
 
131
  if (val != NULL)
 
132
    {
 
133
      ConfigValue* cval = corba_value_from_gconf_value(val);
 
134
 
 
135
      gconf_value_free(val);
 
136
 
 
137
      g_return_val_if_fail(error == NULL, cval);
 
138
      
 
139
      return cval;
 
140
    }
 
141
  else
 
142
    {
 
143
      gconf_set_exception(&error, ev);
 
144
 
 
145
      return invalid_corba_value();
 
146
    }
 
147
}
 
148
 
 
149
static ConfigValue *
 
150
impl_ConfigDatabase_lookup(PortableServer_Servant servant,
 
151
                           const CORBA_char * key,
 
152
                           CORBA_Environment * ev)
 
153
{
 
154
  if (gconfd_check_in_shutdown (ev))
 
155
    return invalid_corba_value ();
 
156
  
 
157
  return impl_ConfigDatabase_lookup_with_locale (servant, key,
 
158
                                                 NULL, TRUE, NULL,
 
159
                                                 NULL, ev);
 
160
}
 
161
 
 
162
static ConfigValue*
 
163
impl_ConfigDatabase_lookup_default_value(PortableServer_Servant servant,
 
164
                                         const CORBA_char * key,
 
165
                                         const CORBA_char * locale,
 
166
                                         CORBA_Environment * ev)
 
167
{
 
168
  GConfDatabase *db = (GConfDatabase*) servant;
 
169
  GConfValue* val;
 
170
  GError* error = NULL;
 
171
  GConfLocaleList* locale_list;  
 
172
 
 
173
  if (gconfd_check_in_shutdown (ev))
 
174
    return invalid_corba_value ();
 
175
  
 
176
  locale_list = locale_cache_lookup(locale);
 
177
  
 
178
  val = gconf_database_query_default_value(db, key,
 
179
                                           locale_list->list,
 
180
                                           NULL,
 
181
                                           &error);
 
182
 
 
183
  gconf_locale_list_unref(locale_list);
 
184
  
 
185
  if (val != NULL)
 
186
    {
 
187
      ConfigValue* cval = corba_value_from_gconf_value(val);
 
188
 
 
189
      gconf_value_free(val);
 
190
 
 
191
      g_return_val_if_fail(error == NULL, cval);
 
192
      
 
193
      return cval;
 
194
    }
 
195
  else
 
196
    {
 
197
      gconf_set_exception(&error, ev);
 
198
 
 
199
      return invalid_corba_value();
 
200
    }
 
201
}
 
202
 
 
203
static void
 
204
impl_ConfigDatabase_batch_lookup(PortableServer_Servant servant,
 
205
                                 const ConfigDatabase_KeyList * keys,
 
206
                                 const CORBA_char * locale,
 
207
                                 ConfigDatabase_ValueList ** values,
 
208
                                 ConfigDatabase_IsDefaultList ** is_defaults,
 
209
                                 ConfigDatabase_IsWritableList ** is_writables,
 
210
                                 CORBA_Environment * ev)
 
211
{
 
212
  if (gconfd_check_in_shutdown (ev))
 
213
    return;
 
214
}
 
215
 
 
216
static void
 
217
impl_ConfigDatabase_set(PortableServer_Servant servant,
 
218
                        const CORBA_char * key,
 
219
                        const ConfigValue * value,
 
220
                        CORBA_Environment * ev)
 
221
{
 
222
  GConfDatabase *db = (GConfDatabase*) servant;
 
223
  gchar* str;
 
224
  GConfValue* val;
 
225
  GError* error = NULL;
 
226
 
 
227
  if (gconfd_check_in_shutdown (ev))
 
228
    return;
 
229
  
 
230
  if (value->_d == InvalidVal)
 
231
    {
 
232
      gconf_log(GCL_ERR, _("Received invalid value in set request"));
 
233
      return;
 
234
    }
 
235
 
 
236
  val = gconf_value_from_corba_value(value);
 
237
 
 
238
  if (val == NULL)
 
239
    {
 
240
      gconf_log(GCL_ERR, _("Couldn't make sense of CORBA value received in set request for key `%s'"), key);
 
241
      return;
 
242
    }
 
243
      
 
244
  str = gconf_value_to_string(val);
 
245
 
 
246
#if 0
 
247
  /* reduce traffice to the logfile */
 
248
  gconf_log(GCL_DEBUG, "Received request to set key `%s' to `%s'", key, str);
 
249
#endif
 
250
  
 
251
  g_free(str);
 
252
 
 
253
  
 
254
  gconf_database_set(db, key, val, value, &error);
 
255
 
 
256
  gconf_set_exception(&error, ev);
 
257
 
 
258
  gconf_value_free(val);
 
259
}
 
260
 
 
261
static void
 
262
impl_ConfigDatabase_unset_with_locale(PortableServer_Servant servant,
 
263
                                      const CORBA_char * key,
 
264
                                      const CORBA_char * locale,
 
265
                                      CORBA_Environment * ev)
 
266
{
 
267
  GConfDatabase *db = (GConfDatabase*) servant;
 
268
  GError* error = NULL;
 
269
 
 
270
  if (gconfd_check_in_shutdown (ev))
 
271
    return;
 
272
  
 
273
  gconf_database_unset(db, key, locale, &error);
 
274
 
 
275
  gconf_set_exception(&error, ev);
 
276
}
 
277
 
 
278
static void
 
279
impl_ConfigDatabase_unset(PortableServer_Servant servant,
 
280
                          const CORBA_char * key,
 
281
                          CORBA_Environment * ev)
 
282
{
 
283
  if (gconfd_check_in_shutdown (ev))
 
284
    return;
 
285
  
 
286
  /* This is a cheat, since const CORBA_char* isn't normally NULL */
 
287
  impl_ConfigDatabase_unset_with_locale (servant, key, NULL, ev);
 
288
}
 
289
 
 
290
static void
 
291
impl_ConfigDatabase_batch_change (PortableServer_Servant servant,
 
292
                                  const CORBA_char * locale,
 
293
                                  const ConfigDatabase_KeyList * keys,
 
294
                                  const ConfigDatabase_ValueList * values,
 
295
                                  CORBA_Environment * ev)
 
296
{
 
297
  if (gconfd_check_in_shutdown (ev))
 
298
    return;
 
299
}
 
300
 
 
301
static CORBA_boolean
 
302
impl_ConfigDatabase_dir_exists(PortableServer_Servant servant,
 
303
                               const CORBA_char * dir,
 
304
                               CORBA_Environment * ev)
 
305
{
 
306
  GConfDatabase *db = (GConfDatabase*) servant;
 
307
  CORBA_boolean retval;
 
308
  GError* error = NULL;  
 
309
 
 
310
  if (gconfd_check_in_shutdown (ev))
 
311
    return CORBA_FALSE;
 
312
  
 
313
  retval =
 
314
    gconf_database_dir_exists (db, dir, &error) ? CORBA_TRUE : CORBA_FALSE;
 
315
 
 
316
  gconf_set_exception(&error, ev);
 
317
 
 
318
  return retval;
 
319
}
 
320
 
 
321
static void
 
322
impl_ConfigDatabase_remove_dir(PortableServer_Servant servant,
 
323
                               const CORBA_char * dir,
 
324
                               CORBA_Environment * ev)
 
325
{
 
326
  GConfDatabase *db = (GConfDatabase*) servant;
 
327
  GError* error = NULL;  
 
328
 
 
329
  if (gconfd_check_in_shutdown (ev))
 
330
    return;
 
331
  
 
332
  gconf_database_remove_dir(db, dir, &error);
 
333
 
 
334
  gconf_set_exception(&error, ev);
 
335
}
 
336
 
 
337
static void
 
338
impl_ConfigDatabase_all_entries(PortableServer_Servant servant,
 
339
                                const CORBA_char * dir,
 
340
                                const CORBA_char * locale,
 
341
                                ConfigDatabase_KeyList ** keys,
 
342
                                ConfigDatabase_ValueList ** values,
 
343
                                ConfigDatabase_IsDefaultList ** is_defaults,
 
344
                                ConfigDatabase_IsWritableList ** is_writables,
 
345
                                CORBA_Environment * ev)
 
346
{
 
347
  GConfDatabase *db = (GConfDatabase*) servant;
 
348
  GSList* pairs;
 
349
  guint n;
 
350
  GSList* tmp;
 
351
  guint i;
 
352
  GError* error = NULL;
 
353
  GConfLocaleList* locale_list;  
 
354
 
 
355
  if (gconfd_check_in_shutdown (ev))
 
356
    return;
 
357
  
 
358
  locale_list = locale_cache_lookup(locale);
 
359
  
 
360
  pairs = gconf_database_all_entries(db, dir, locale_list->list, &error);
 
361
  
 
362
  gconf_locale_list_unref(locale_list);
 
363
 
 
364
  if (error != NULL)
 
365
    {
 
366
      gconf_set_exception(&error, ev);
 
367
      return;
 
368
    }
 
369
  
 
370
  n = g_slist_length(pairs);
 
371
 
 
372
  *keys= ConfigDatabase_KeyList__alloc();
 
373
  (*keys)->_buffer = CORBA_sequence_CORBA_string_allocbuf(n);
 
374
  (*keys)->_length = n;
 
375
  (*keys)->_maximum = n;
 
376
  (*keys)->_release = CORBA_TRUE; /* free buffer */
 
377
  
 
378
  *values= ConfigDatabase_ValueList__alloc();
 
379
  (*values)->_buffer = CORBA_sequence_ConfigValue_allocbuf(n);
 
380
  (*values)->_length = n;
 
381
  (*values)->_maximum = n;
 
382
  (*values)->_release = CORBA_TRUE; /* free buffer */
 
383
 
 
384
  *is_defaults = ConfigDatabase_IsDefaultList__alloc();
 
385
  (*is_defaults)->_buffer = CORBA_sequence_CORBA_boolean_allocbuf(n);
 
386
  (*is_defaults)->_length = n;
 
387
  (*is_defaults)->_maximum = n;
 
388
  (*is_defaults)->_release = CORBA_TRUE; /* free buffer */
 
389
 
 
390
  *is_writables = ConfigDatabase_IsWritableList__alloc();
 
391
  (*is_writables)->_buffer = CORBA_sequence_CORBA_boolean_allocbuf(n);
 
392
  (*is_writables)->_length = n;
 
393
  (*is_writables)->_maximum = n;
 
394
  (*is_writables)->_release = CORBA_TRUE; /* free buffer */
 
395
  
 
396
  tmp = pairs;
 
397
  i = 0;
 
398
 
 
399
  while (tmp != NULL)
 
400
    {
 
401
      GConfEntry* p = tmp->data;
 
402
 
 
403
      g_assert(p != NULL);
 
404
      g_assert(p->key != NULL);
 
405
 
 
406
      (*keys)->_buffer[i] = CORBA_string_dup(p->key);
 
407
      fill_corba_value_from_gconf_value(p->value, &((*values)->_buffer[i]));
 
408
      (*is_defaults)->_buffer[i] = gconf_entry_get_is_default(p);
 
409
      (*is_writables)->_buffer[i] = gconf_entry_get_is_writable(p);
 
410
      
 
411
      gconf_entry_free(p);
 
412
 
 
413
      ++i;
 
414
      tmp = g_slist_next(tmp);
 
415
    }
 
416
  
 
417
  g_assert(i == n);
 
418
 
 
419
  g_slist_free(pairs);
 
420
}
 
421
 
 
422
static void
 
423
impl_ConfigDatabase_all_dirs(PortableServer_Servant servant,
 
424
                             const CORBA_char * dir,
 
425
                             ConfigDatabase_KeyList ** keys,
 
426
                             CORBA_Environment * ev)
 
427
{
 
428
  GConfDatabase *db = (GConfDatabase*) servant;
 
429
  GSList* subdirs;
 
430
  guint n;
 
431
  GSList* tmp;
 
432
  guint i;
 
433
  GError* error = NULL;
 
434
 
 
435
  if (gconfd_check_in_shutdown (ev))
 
436
    return;
 
437
  
 
438
  subdirs = gconf_database_all_dirs (db, dir, &error);
 
439
 
 
440
  if (error != NULL)
 
441
    {
 
442
      /* I think this is right anyway... */
 
443
      gconf_set_exception (&error, ev);
 
444
      *keys = NULL;
 
445
      return;
 
446
    }
 
447
  
 
448
  n = g_slist_length (subdirs);
 
449
 
 
450
  *keys = ConfigDatabase_KeyList__alloc();
 
451
  (*keys)->_buffer = CORBA_sequence_CORBA_string_allocbuf(n);
 
452
  (*keys)->_length = n;
 
453
  (*keys)->_maximum = n;
 
454
  (*keys)->_release = CORBA_TRUE; /* free buffer */
 
455
  
 
456
  tmp = subdirs;
 
457
  i = 0;
 
458
 
 
459
  while (tmp != NULL)
 
460
    {
 
461
      gchar* subdir = tmp->data;
 
462
 
 
463
      (*keys)->_buffer[i] = CORBA_string_dup (subdir);
 
464
 
 
465
      g_free (subdir);
 
466
 
 
467
      ++i;
 
468
      tmp = g_slist_next (tmp);
 
469
    }
 
470
  
 
471
  g_assert (i == n);
 
472
  
 
473
  g_slist_free (subdirs);
 
474
}
 
475
 
 
476
static void
 
477
impl_ConfigDatabase_set_schema(PortableServer_Servant servant,
 
478
                               const CORBA_char * key,
 
479
                               const CORBA_char * schema_key,
 
480
                               CORBA_Environment * ev)
 
481
{
 
482
  GConfDatabase *db = (GConfDatabase*) servant;
 
483
  GError* error = NULL;
 
484
 
 
485
  if (gconfd_check_in_shutdown (ev))
 
486
    return;
 
487
  
 
488
  gconf_database_set_schema(db, key, schema_key, &error);
 
489
 
 
490
  gconf_set_exception(&error, ev);
 
491
}
 
492
 
 
493
static void
 
494
impl_ConfigDatabase_sync(PortableServer_Servant servant,
 
495
                         CORBA_Environment * ev)
 
496
{
 
497
  GConfDatabase *db = (GConfDatabase*) servant;
 
498
  GError* error = NULL;
 
499
 
 
500
  if (gconfd_check_in_shutdown (ev))
 
501
    return;
 
502
  
 
503
  gconf_database_sync(db, &error);
 
504
 
 
505
  gconf_set_exception(&error, ev);
 
506
}
 
507
 
 
508
static void
 
509
impl_ConfigDatabase_clear_cache(PortableServer_Servant servant,
 
510
                                CORBA_Environment * ev)
 
511
{
 
512
  GConfDatabase *db = (GConfDatabase*) servant;
 
513
  GError* error = NULL;
 
514
 
 
515
  if (gconfd_check_in_shutdown (ev))
 
516
    return;
 
517
  
 
518
  gconf_log(GCL_DEBUG, _("Received request to drop all cached data"));  
 
519
  
 
520
  gconf_database_clear_cache(db, &error);
 
521
 
 
522
  gconf_set_exception(&error, ev);
 
523
}
 
524
 
 
525
static void
 
526
impl_ConfigDatabase_synchronous_sync(PortableServer_Servant servant,
 
527
                                     CORBA_Environment * ev)
 
528
{
 
529
  GConfDatabase *db = (GConfDatabase*) servant;
 
530
  GError* error = NULL;
 
531
 
 
532
  if (gconfd_check_in_shutdown (ev))
 
533
    return;
 
534
  
 
535
  gconf_log(GCL_DEBUG, _("Received request to sync synchronously"));
 
536
  
 
537
  
 
538
  gconf_database_synchronous_sync(db, &error);
 
539
 
 
540
  gconf_set_exception(&error, ev);
 
541
}
 
542
 
 
543
 
 
544
static ConfigValue*
 
545
impl_ConfigDatabase2_lookup_with_schema_name(PortableServer_Servant servant,
 
546
                                             const CORBA_char * key,
 
547
                                             const CORBA_char * locale,
 
548
                                             CORBA_boolean use_schema_default,
 
549
                                             CORBA_char    **schema_name,
 
550
                                             CORBA_boolean * value_is_default,
 
551
                                             CORBA_boolean * value_is_writable,
 
552
                                             CORBA_Environment * ev)
 
553
{
 
554
  GConfDatabase *db = (GConfDatabase*) servant;
 
555
  GConfValue* val;
 
556
  GError* error = NULL;
 
557
  GConfLocaleList* locale_list;
 
558
  gboolean is_default = FALSE;
 
559
  gboolean is_writable = TRUE;
 
560
  char *s;
 
561
  ConfigValue* cval;
 
562
  
 
563
  if (gconfd_check_in_shutdown (ev))
 
564
    return invalid_corba_value ();
 
565
  
 
566
  locale_list = locale_cache_lookup(locale);
 
567
 
 
568
  s = NULL;
 
569
  val = gconf_database_query_value(db, key, locale_list->list,
 
570
                                   use_schema_default,
 
571
                                   &s,
 
572
                                   &is_default,
 
573
                                   &is_writable,
 
574
                                   &error);
 
575
 
 
576
  *value_is_default = is_default;
 
577
  *value_is_writable = is_writable;
 
578
 
 
579
  if (s)
 
580
    *schema_name = CORBA_string_dup (s);
 
581
  else
 
582
    *schema_name = CORBA_string_dup ("");
 
583
 
 
584
  g_free (s);
 
585
  
 
586
  gconf_locale_list_unref(locale_list);
 
587
  
 
588
  if (val != NULL)
 
589
    {
 
590
      cval = corba_value_from_gconf_value(val);
 
591
      gconf_value_free(val);
 
592
      g_return_val_if_fail(error == NULL, cval);
 
593
    }
 
594
  else
 
595
    {
 
596
      cval = invalid_corba_value();
 
597
    }
 
598
 
 
599
  gconf_log (GCL_DEBUG, "In lookup_with_schema_name returning schema name '%s' error '%s'",
 
600
             *schema_name, error ? error->message : "none");
 
601
  
 
602
  if (error != NULL)
 
603
    {
 
604
      gconf_set_exception (&error, ev);
 
605
    }
 
606
 
 
607
  return cval;
 
608
}
 
609
 
 
610
static void
 
611
impl_ConfigDatabase2_all_entries_with_schema_name(PortableServer_Servant servant,
 
612
                                                  const CORBA_char * dir,
 
613
                                                  const CORBA_char * locale,
 
614
                                                  ConfigDatabase_KeyList ** keys,
 
615
                                                  ConfigDatabase_ValueList ** values,
 
616
                                                  ConfigDatabase2_SchemaNameList **schema_names,
 
617
                                                  ConfigDatabase_IsDefaultList   **is_defaults,
 
618
                                                  ConfigDatabase_IsWritableList  **is_writables,
 
619
                                                  CORBA_Environment * ev)
 
620
{
 
621
  GConfDatabase *db = (GConfDatabase*) servant;
 
622
  GSList* pairs;
 
623
  guint n;
 
624
  GSList* tmp;
 
625
  guint i;
 
626
  GError* error = NULL;
 
627
  GConfLocaleList* locale_list;  
 
628
 
 
629
  if (gconfd_check_in_shutdown (ev))
 
630
    return;
 
631
  
 
632
  locale_list = locale_cache_lookup(locale);
 
633
  
 
634
  pairs = gconf_database_all_entries(db, dir, locale_list->list, &error);
 
635
  
 
636
  gconf_locale_list_unref(locale_list);
 
637
 
 
638
  if (error != NULL)
 
639
    {
 
640
      gconf_set_exception(&error, ev);
 
641
      return;
 
642
    }
 
643
  
 
644
  n = g_slist_length(pairs);
 
645
 
 
646
  *keys= ConfigDatabase_KeyList__alloc();
 
647
  (*keys)->_buffer = CORBA_sequence_CORBA_string_allocbuf(n);
 
648
  (*keys)->_length = n;
 
649
  (*keys)->_maximum = n;
 
650
  (*keys)->_release = CORBA_TRUE; /* free buffer */
 
651
  
 
652
  *values= ConfigDatabase_ValueList__alloc();
 
653
  (*values)->_buffer = CORBA_sequence_ConfigValue_allocbuf(n);
 
654
  (*values)->_length = n;
 
655
  (*values)->_maximum = n;
 
656
  (*values)->_release = CORBA_TRUE; /* free buffer */
 
657
 
 
658
  *schema_names = ConfigDatabase2_SchemaNameList__alloc();
 
659
  (*schema_names)->_buffer = CORBA_sequence_CORBA_string_allocbuf(n);
 
660
  (*schema_names)->_length = n;
 
661
  (*schema_names)->_maximum = n;
 
662
  (*schema_names)->_release = CORBA_TRUE; /* free buffer */
 
663
  
 
664
  *is_defaults = ConfigDatabase_IsDefaultList__alloc();
 
665
  (*is_defaults)->_buffer = CORBA_sequence_CORBA_boolean_allocbuf(n);
 
666
  (*is_defaults)->_length = n;
 
667
  (*is_defaults)->_maximum = n;
 
668
  (*is_defaults)->_release = CORBA_TRUE; /* free buffer */
 
669
 
 
670
  *is_writables = ConfigDatabase_IsWritableList__alloc();
 
671
  (*is_writables)->_buffer = CORBA_sequence_CORBA_boolean_allocbuf(n);
 
672
  (*is_writables)->_length = n;
 
673
  (*is_writables)->_maximum = n;
 
674
  (*is_writables)->_release = CORBA_TRUE; /* free buffer */
 
675
  
 
676
  tmp = pairs;
 
677
  i = 0;
 
678
 
 
679
  while (tmp != NULL)
 
680
    {
 
681
      GConfEntry* p = tmp->data;
 
682
 
 
683
      g_assert(p != NULL);
 
684
      g_assert(p->key != NULL);
 
685
 
 
686
      (*keys)->_buffer[i] = CORBA_string_dup(p->key);
 
687
      fill_corba_value_from_gconf_value(p->value, &((*values)->_buffer[i]));
 
688
      (*schema_names)->_buffer[i] = CORBA_string_dup (gconf_entry_get_schema_name (p));
 
689
      if ((*schema_names)->_buffer[i] == NULL)
 
690
        (*schema_names)->_buffer[i] = CORBA_string_dup ("");
 
691
      (*is_defaults)->_buffer[i] = gconf_entry_get_is_default(p);
 
692
      (*is_writables)->_buffer[i] = gconf_entry_get_is_writable(p);
 
693
      
 
694
      gconf_entry_free(p);
 
695
 
 
696
      ++i;
 
697
      tmp = g_slist_next(tmp);
 
698
    }
 
699
  
 
700
  g_assert(i == n);
 
701
 
 
702
  g_slist_free(pairs);
 
703
}
 
704
 
 
705
static PortableServer_ServantBase__epv base_epv = {
 
706
  NULL,
 
707
  NULL,
 
708
  NULL
 
709
};
 
710
 
 
711
static POA_ConfigDatabase__epv server_epv = { 
 
712
  NULL,
 
713
  impl_ConfigDatabase_add_listener,
 
714
  impl_ConfigDatabase_remove_listener,
 
715
  impl_ConfigDatabase_lookup,
 
716
  impl_ConfigDatabase_lookup_with_locale,
 
717
  impl_ConfigDatabase_lookup_default_value,
 
718
  impl_ConfigDatabase_batch_lookup,
 
719
  impl_ConfigDatabase_set,
 
720
  impl_ConfigDatabase_unset,
 
721
  impl_ConfigDatabase_unset_with_locale,
 
722
  impl_ConfigDatabase_batch_change,
 
723
  impl_ConfigDatabase_dir_exists,
 
724
  impl_ConfigDatabase_remove_dir,
 
725
  impl_ConfigDatabase_all_entries,
 
726
  impl_ConfigDatabase_all_dirs,
 
727
  impl_ConfigDatabase_set_schema,
 
728
  impl_ConfigDatabase_sync,
 
729
  impl_ConfigDatabase_clear_cache,
 
730
  impl_ConfigDatabase_synchronous_sync
 
731
};
 
732
 
 
733
static POA_ConfigDatabase2__epv server2_epv = { 
 
734
  NULL,
 
735
  impl_ConfigDatabase2_lookup_with_schema_name,
 
736
  impl_ConfigDatabase2_all_entries_with_schema_name
 
737
};
 
738
 
 
739
static POA_ConfigDatabase2__vepv poa_server_vepv = { &base_epv, &server_epv, &server2_epv };
 
740
 
 
741
static void gconf_database_really_sync(GConfDatabase* db);
 
742
 
 
743
GConfDatabase*
 
744
gconf_database_new (GConfSources  *sources)
 
745
{
 
746
  GConfDatabase* db;
 
747
  CORBA_Environment ev;
 
748
  PortableServer_ObjectId* objid;
 
749
  
 
750
  db = g_new0 (GConfDatabase, 1);
 
751
 
 
752
  db->servant._private = NULL;
 
753
  db->servant.vepv = &poa_server_vepv;
 
754
 
 
755
  CORBA_exception_init (&ev);
 
756
  
 
757
  POA_ConfigDatabase2__init (&db->servant, &ev);
 
758
 
 
759
  objid =
 
760
    PortableServer_POA_activate_object(gconf_get_poa (),
 
761
                                       &db->servant,
 
762
                                       &ev);
 
763
  
 
764
  db->objref = PortableServer_POA_servant_to_reference(gconf_get_poa (),
 
765
                                                       &db->servant,
 
766
                                                       &ev);
 
767
  if (CORBA_Object_is_nil(db->objref, &ev))
 
768
    {
 
769
      gconf_log(GCL_ERR,
 
770
                _("Fatal error: failed to get object reference for ConfigDatabase"));
 
771
 
 
772
      exit (1);
 
773
    }
 
774
 
 
775
  CORBA_free (objid);
 
776
 
 
777
  db->listeners = gconf_listeners_new();
 
778
 
 
779
  db->sources = sources;
 
780
 
 
781
  db->last_access = time(NULL);
 
782
 
 
783
  db->sync_idle = 0;
 
784
  db->sync_timeout = 0;
 
785
 
 
786
  db->persistent_name = NULL;
 
787
  
 
788
  return db;
 
789
}
 
790
 
 
791
void
 
792
gconf_database_free (GConfDatabase *db)
 
793
{
 
794
  PortableServer_ObjectId *oid;
 
795
  CORBA_Environment ev;
 
796
 
 
797
  CORBA_exception_init (&ev);
 
798
  
 
799
  CORBA_Object_release (db->objref, &ev);
 
800
 
 
801
  CORBA_exception_free (&ev);
 
802
  
 
803
  oid = PortableServer_POA_servant_to_id (gconf_get_poa(), &db->servant, &ev);
 
804
 
 
805
  CORBA_exception_free (&ev);
 
806
  
 
807
  PortableServer_POA_deactivate_object (gconf_get_poa (), oid, &ev);
 
808
 
 
809
  CORBA_exception_free (&ev);
 
810
  
 
811
  POA_ConfigDatabase2__fini (&db->servant, &ev);
 
812
 
 
813
  CORBA_free (oid);
 
814
 
 
815
  CORBA_exception_free (&ev);
 
816
  
 
817
  if (db->listeners != NULL)
 
818
    {
 
819
      gboolean need_sync = FALSE;
 
820
      
 
821
      g_assert(db->sources != NULL);
 
822
 
 
823
      if (db->sync_idle != 0)
 
824
        {
 
825
          g_source_remove(db->sync_idle);
 
826
          db->sync_idle = 0;
 
827
          need_sync = TRUE;
 
828
        }
 
829
 
 
830
      if (db->sync_timeout != 0)
 
831
        {
 
832
          g_source_remove(db->sync_timeout);
 
833
          db->sync_timeout = 0;
 
834
          need_sync = TRUE;
 
835
        }
 
836
 
 
837
      if (need_sync)
 
838
        gconf_database_really_sync(db);
 
839
      
 
840
      gconf_listeners_free(db->listeners);
 
841
      gconf_sources_free(db->sources);
 
842
    }
 
843
 
 
844
  g_free (db->persistent_name);
 
845
  
 
846
  g_free (db);
 
847
}
 
848
  
 
849
static gboolean
 
850
client_alive_predicate (const gchar* location,
 
851
                        guint        cnxn_id,
 
852
                        gpointer     listener_data,
 
853
                        gpointer     user_data)
 
854
{
 
855
  Listener *l = listener_data;
 
856
  CORBA_Environment ev;
 
857
 
 
858
  CORBA_exception_init (&ev);
 
859
  
 
860
  ConfigListener_ping (l->obj, &ev);
 
861
 
 
862
  if (ev._major != CORBA_NO_EXCEPTION)
 
863
    {
 
864
      gconf_log (GCL_DEBUG, "Removing stale listener %u, client not alive",
 
865
                 cnxn_id);
 
866
      
 
867
      CORBA_exception_free (&ev);
 
868
 
 
869
      return TRUE;
 
870
    }
 
871
  else
 
872
    return FALSE;
 
873
}
 
874
 
 
875
void
 
876
gconf_database_drop_dead_listeners (GConfDatabase *db)
 
877
{
 
878
  if (db->listeners)
 
879
    {
 
880
      gconf_listeners_remove_if (db->listeners,
 
881
                                 client_alive_predicate,
 
882
                                 NULL);
 
883
    }
 
884
}
 
885
 
 
886
static gint
 
887
gconf_database_sync_idle (GConfDatabase* db)
 
888
{
 
889
  db->sync_idle = 0;
 
890
 
 
891
  /* could have been added before reaching the
 
892
     idle */
 
893
  if (db->sync_timeout != 0)
 
894
    {
 
895
      g_source_remove (db->sync_timeout);
 
896
      db->sync_timeout = 0;
 
897
    }
 
898
  
 
899
  gconf_database_really_sync (db);
 
900
  
 
901
  /* Remove the idle function by returning FALSE */
 
902
  return FALSE; 
 
903
}
 
904
 
 
905
static gint
 
906
gconf_database_sync_timeout(GConfDatabase* db)
 
907
{
 
908
  db->sync_timeout = 0;
 
909
  
 
910
  /* Install the sync idle */
 
911
  if (db->sync_idle == 0)
 
912
    db->sync_idle = g_idle_add((GSourceFunc)gconf_database_sync_idle, db);
 
913
 
 
914
  gconf_log(GCL_DEBUG, "Sync queued one minute after changes occurred");
 
915
  
 
916
  /* Remove the timeout function by returning FALSE */
 
917
  return FALSE;
 
918
}
 
919
 
 
920
static void
 
921
gconf_database_really_sync(GConfDatabase* db)
 
922
{
 
923
  GError* error = NULL;
 
924
  
 
925
  if (!gconf_database_synchronous_sync(db, &error))
 
926
    {
 
927
      g_return_if_fail(error != NULL);
 
928
 
 
929
      gconf_log(GCL_ERR, _("Failed to sync one or more sources: %s"), 
 
930
                error->message);
 
931
      g_error_free(error);
 
932
    }
 
933
  else
 
934
    {
 
935
      gconf_log(GCL_DEBUG, "Sync completed without errors");
 
936
    }
 
937
}
 
938
 
 
939
static void
 
940
gconf_database_sync_nowish(GConfDatabase* db)
 
941
{
 
942
  /* Go ahead and sync as soon as the event loop quiets down */
 
943
 
 
944
  /* remove the scheduled sync */
 
945
  if (db->sync_timeout != 0)
 
946
    {
 
947
      g_source_remove(db->sync_timeout);
 
948
      db->sync_timeout = 0;
 
949
    }
 
950
 
 
951
  /* Schedule immediate post-quietdown sync */
 
952
  if (db->sync_idle == 0)
 
953
    db->sync_idle = g_idle_add((GSourceFunc)gconf_database_sync_idle, db);
 
954
}
 
955
 
 
956
static void
 
957
gconf_database_schedule_sync(GConfDatabase* db)
 
958
{
 
959
  /* Plan to sync within a minute or so */
 
960
  if (db->sync_idle != 0)
 
961
    return;
 
962
  else if (db->sync_timeout != 0)
 
963
    return;
 
964
  else
 
965
    {
 
966
      /* 1 minute timeout */
 
967
      db->sync_timeout = g_timeout_add(60000, (GSourceFunc)gconf_database_sync_timeout, db);
 
968
    }
 
969
}
 
970
 
 
971
CORBA_unsigned_long
 
972
gconf_database_readd_listener   (GConfDatabase       *db,
 
973
                                 ConfigListener       who,
 
974
                                 const gchar         *where)
 
975
{
 
976
  Listener* l;
 
977
  guint cnxn;
 
978
 
 
979
  gconfd_need_log_cleanup ();
 
980
  
 
981
  g_assert(db->listeners != NULL);
 
982
 
 
983
  db->last_access = time(NULL);
 
984
  
 
985
  l = listener_new(who);
 
986
 
 
987
  cnxn = gconf_listeners_add (db->listeners, where, l,
 
988
                              (GFreeFunc)listener_destroy);
 
989
 
 
990
  gconf_log (GCL_DEBUG, "Added listener %u", cnxn);
 
991
  
 
992
  return cnxn;
 
993
}
 
994
 
 
995
CORBA_unsigned_long
 
996
gconf_database_add_listener    (GConfDatabase       *db,
 
997
                                ConfigListener       who,
 
998
                                const gchar         *where)
 
999
{
 
1000
  GError *err;
 
1001
  CORBA_unsigned_long cnxn;
 
1002
 
 
1003
  gconfd_need_log_cleanup ();
 
1004
  
 
1005
  cnxn = gconf_database_readd_listener (db, who, where);
 
1006
  
 
1007
  err = NULL;
 
1008
  if (!gconfd_logfile_change_listener (db, TRUE, cnxn,
 
1009
                                       who, where, &err))
 
1010
    {
 
1011
      /* This error is not fatal; we basically ignore it.
 
1012
       * Because it's likely the right thing for the client
 
1013
       * app to simply continue.
 
1014
       */
 
1015
      gconf_log (GCL_WARNING, _("Failed to log addition of listener (%s); will not be able to restore this listener on gconfd restart, resulting in unreliable notification of configuration changes."), err->message);
 
1016
      g_error_free (err);
 
1017
    }
 
1018
  
 
1019
  return cnxn;
 
1020
}
 
1021
 
 
1022
void
 
1023
gconf_database_remove_listener (GConfDatabase       *db,
 
1024
                                CORBA_unsigned_long  cnxn)
 
1025
{
 
1026
  Listener *l = NULL;
 
1027
  GError *err;
 
1028
  const gchar *location = NULL;
 
1029
 
 
1030
  gconfd_need_log_cleanup ();
 
1031
  
 
1032
  g_assert(db->listeners != NULL);
 
1033
  
 
1034
  db->last_access = time(NULL);
 
1035
 
 
1036
  gconf_log(GCL_DEBUG, "Removing listener %u", (guint)cnxn);
 
1037
 
 
1038
  if (!gconf_listeners_get_data (db->listeners, cnxn,
 
1039
                                 (gpointer*)&l,
 
1040
                                 &location))
 
1041
    {
 
1042
      gconf_log (GCL_WARNING, _("Listener ID %lu doesn't exist"),
 
1043
                 (gulong) cnxn);
 
1044
      return;
 
1045
    }
 
1046
  
 
1047
  err = NULL;
 
1048
  if (!gconfd_logfile_change_listener (db, FALSE, cnxn,
 
1049
                                       l->obj, location, &err))
 
1050
    {
 
1051
      gconf_log (GCL_WARNING, _("Failed to log removal of listener to logfile (most likely harmless, may result in a notification weirdly reappearing): %s"),
 
1052
                 err->message);
 
1053
      g_error_free (err);
 
1054
    }
 
1055
  
 
1056
  /* calls destroy notify */
 
1057
  gconf_listeners_remove(db->listeners, cnxn);
 
1058
}
 
1059
 
 
1060
typedef struct _ListenerNotifyClosure ListenerNotifyClosure;
 
1061
 
 
1062
struct _ListenerNotifyClosure {
 
1063
  GConfDatabase* db;
 
1064
  const ConfigValue* value;
 
1065
  gboolean is_default;
 
1066
  gboolean is_writable;
 
1067
  GSList* dead;
 
1068
  CORBA_Environment ev;
 
1069
};
 
1070
 
 
1071
static void
 
1072
notify_listeners_cb(GConfListeners* listeners,
 
1073
                    const gchar* all_above_key,
 
1074
                    guint cnxn_id,
 
1075
                    gpointer listener_data,
 
1076
                    gpointer user_data)
 
1077
{
 
1078
  Listener* l = listener_data;
 
1079
  ListenerNotifyClosure* closure = user_data;
 
1080
  
 
1081
  ConfigListener_notify(l->obj,
 
1082
                        closure->db->objref,
 
1083
                        cnxn_id, 
 
1084
                        (gchar*)all_above_key,
 
1085
                        closure->value,
 
1086
                        closure->is_default,
 
1087
                        closure->is_writable,
 
1088
                        &closure->ev);
 
1089
  
 
1090
  if(closure->ev._major != CORBA_NO_EXCEPTION) 
 
1091
    {
 
1092
      gconf_log (GCL_DEBUG, "Failed to notify listener %u, removing: %s", 
 
1093
                 cnxn_id, CORBA_exception_id (&closure->ev));
 
1094
      CORBA_exception_free (&closure->ev);
 
1095
      
 
1096
      /* Dead listeners need to be forgotten */
 
1097
      closure->dead = g_slist_prepend(closure->dead, GUINT_TO_POINTER(cnxn_id));
 
1098
    }
 
1099
  else
 
1100
    {
 
1101
      gconf_log (GCL_DEBUG, "Notified listener %u of change to key `%s'",
 
1102
                 cnxn_id, all_above_key);
 
1103
    }
 
1104
}
 
1105
 
 
1106
void
 
1107
gconf_database_notify_listeners (GConfDatabase       *db,
 
1108
                                 const gchar         *key,
 
1109
                                 const ConfigValue   *value,
 
1110
                                 gboolean             is_default,
 
1111
                                 gboolean             is_writable)
 
1112
{
 
1113
  ListenerNotifyClosure closure;
 
1114
  GSList* tmp;
 
1115
  
 
1116
  g_return_if_fail(db != NULL);
 
1117
 
 
1118
  closure.db = db;
 
1119
  closure.value = value;
 
1120
  closure.is_default = is_default;
 
1121
  closure.is_writable = is_writable;
 
1122
  closure.dead = NULL;
 
1123
  
 
1124
  CORBA_exception_init(&closure.ev);
 
1125
  
 
1126
  gconf_listeners_notify(db->listeners, key, notify_listeners_cb, &closure);
 
1127
 
 
1128
  tmp = closure.dead;
 
1129
 
 
1130
  if (tmp)
 
1131
    gconfd_need_log_cleanup ();
 
1132
  
 
1133
  while (tmp != NULL)
 
1134
    {
 
1135
      guint dead = GPOINTER_TO_UINT(tmp->data);
 
1136
      
 
1137
      gconf_listeners_remove(db->listeners, dead);
 
1138
 
 
1139
      tmp = g_slist_next(tmp);
 
1140
    }
 
1141
}
 
1142
 
 
1143
GConfValue*
 
1144
gconf_database_query_value (GConfDatabase  *db,
 
1145
                            const gchar    *key,
 
1146
                            const gchar   **locales,
 
1147
                            gboolean        use_schema_default,
 
1148
                            char          **schema_name,
 
1149
                            gboolean       *value_is_default,
 
1150
                            gboolean       *value_is_writable,
 
1151
                            GError    **err)
 
1152
{
 
1153
  GConfValue* val;
 
1154
  
 
1155
  g_return_val_if_fail(err == NULL || *err == NULL, NULL);
 
1156
  g_assert(db->listeners != NULL);
 
1157
  
 
1158
  db->last_access = time(NULL);
 
1159
  
 
1160
  val = gconf_sources_query_value(db->sources, key, locales,
 
1161
                                  use_schema_default,
 
1162
                                  value_is_default,
 
1163
                                  value_is_writable,
 
1164
                                  schema_name,
 
1165
                                  err);
 
1166
  
 
1167
  if (err && *err != NULL)
 
1168
    {
 
1169
      gconf_log(GCL_ERR, _("Error getting value for `%s': %s"),
 
1170
                key, (*err)->message);
 
1171
    }
 
1172
  
 
1173
  return val;
 
1174
}
 
1175
 
 
1176
GConfValue*
 
1177
gconf_database_query_default_value (GConfDatabase  *db,
 
1178
                                    const gchar    *key,
 
1179
                                    const gchar   **locales,
 
1180
                                    gboolean       *is_writable,
 
1181
                                    GError    **err)
 
1182
{  
 
1183
  g_return_val_if_fail(err == NULL || *err == NULL, NULL);
 
1184
  g_assert(db->listeners != NULL);
 
1185
  
 
1186
  db->last_access = time(NULL);
 
1187
 
 
1188
  return gconf_sources_query_default_value(db->sources, key, locales,
 
1189
                                           is_writable,
 
1190
                                           err);
 
1191
}
 
1192
 
 
1193
void
 
1194
gconf_database_set   (GConfDatabase      *db,
 
1195
                      const gchar        *key,
 
1196
                      GConfValue         *value,
 
1197
                      const ConfigValue  *cvalue,
 
1198
                      GError        **err)
 
1199
{
 
1200
  GError *error = NULL;
 
1201
  
 
1202
  g_assert(db->listeners != NULL);
 
1203
  g_return_if_fail(err == NULL || *err == NULL);
 
1204
  
 
1205
  db->last_access = time(NULL);
 
1206
 
 
1207
#if 0
 
1208
  /* this really churns the logfile, so we avoid it */
 
1209
  gconf_log(GCL_DEBUG, "Received request to set key `%s'", key);
 
1210
#endif
 
1211
  
 
1212
  gconf_sources_set_value(db->sources, key, value, &error);
 
1213
 
 
1214
  if (error)
 
1215
    {
 
1216
      gconf_log(GCL_ERR, _("Error setting value for `%s': %s"),
 
1217
                key, error->message);
 
1218
      
 
1219
      g_propagate_error (err, error);
 
1220
 
 
1221
      return;
 
1222
    }
 
1223
  else
 
1224
    {
 
1225
      gconf_database_schedule_sync(db);
 
1226
      
 
1227
      gconf_database_notify_listeners(db, key, cvalue,
 
1228
                                      /* Can't possibly be the default,
 
1229
                                         since we just set it,
 
1230
                                         and must be writable since
 
1231
                                         setting it succeeded.
 
1232
                                      */
 
1233
                                      FALSE,
 
1234
                                      TRUE);
 
1235
    }
 
1236
}
 
1237
 
 
1238
void
 
1239
gconf_database_unset (GConfDatabase      *db,
 
1240
                      const gchar        *key,
 
1241
                      const gchar        *locale,
 
1242
                      GError        **err)
 
1243
{
 
1244
  ConfigValue* val;
 
1245
  GError* error = NULL;
 
1246
  
 
1247
  g_return_if_fail(err == NULL || *err == NULL);
 
1248
  
 
1249
  g_assert(db->listeners != NULL);
 
1250
  
 
1251
  db->last_access = time(NULL);
 
1252
  
 
1253
  gconf_log(GCL_DEBUG, "Received request to unset key `%s'", key);
 
1254
 
 
1255
  gconf_sources_unset_value(db->sources, key, locale, &error);
 
1256
 
 
1257
  if (error != NULL)
 
1258
    {
 
1259
      gconf_log(GCL_ERR, _("Error unsetting `%s': %s"),
 
1260
                key, error->message);
 
1261
 
 
1262
      if (err)
 
1263
        *err = error;
 
1264
      else
 
1265
        g_error_free(error);
 
1266
 
 
1267
      error = NULL;
 
1268
    }
 
1269
  else
 
1270
    {
 
1271
      GConfValue* def_value;
 
1272
      const gchar* locale_list[] = { NULL, NULL };
 
1273
      gboolean is_writable = TRUE;
 
1274
      
 
1275
      locale_list[0] = locale;
 
1276
      def_value = gconf_database_query_default_value(db,
 
1277
                                                     key,
 
1278
                                                     locale_list,
 
1279
                                                     &is_writable,
 
1280
                                                     err);
 
1281
 
 
1282
      if (err && *err)
 
1283
        gconf_log(GCL_ERR, _("Error getting default value for `%s': %s"),
 
1284
                  key, (*err)->message);
 
1285
 
 
1286
      if (def_value != NULL)
 
1287
        {
 
1288
          val = corba_value_from_gconf_value(def_value);
 
1289
          gconf_value_free(def_value);
 
1290
        }
 
1291
      else
 
1292
        {
 
1293
          val = invalid_corba_value();
 
1294
        }
 
1295
          
 
1296
      gconf_database_schedule_sync(db);
 
1297
 
 
1298
      gconf_database_notify_listeners(db, key, val, TRUE, is_writable);
 
1299
      
 
1300
      CORBA_free(val);
 
1301
    }
 
1302
}
 
1303
 
 
1304
gboolean
 
1305
gconf_database_dir_exists  (GConfDatabase  *db,
 
1306
                            const gchar    *dir,
 
1307
                            GError    **err)
 
1308
{
 
1309
  gboolean ret;
 
1310
  
 
1311
  g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
 
1312
  
 
1313
  g_assert(db->listeners != NULL);
 
1314
  
 
1315
  db->last_access = time(NULL);
 
1316
  
 
1317
  gconf_log(GCL_DEBUG, "Received dir_exists request for `%s'", dir);
 
1318
  
 
1319
  ret = gconf_sources_dir_exists(db->sources, dir, err);
 
1320
  
 
1321
  if (err && *err != NULL)
 
1322
    {
 
1323
      gconf_log(GCL_ERR, _("Error checking existence of `%s': %s"),
 
1324
                 dir, (*err)->message);
 
1325
      ret = FALSE;
 
1326
    }
 
1327
 
 
1328
  return ret;
 
1329
}
 
1330
 
 
1331
void
 
1332
gconf_database_remove_dir  (GConfDatabase  *db,
 
1333
                            const gchar    *dir,
 
1334
                            GError    **err)
 
1335
{  
 
1336
  g_return_if_fail(err == NULL || *err == NULL);
 
1337
  g_assert(db->listeners != NULL);
 
1338
  
 
1339
  db->last_access = time(NULL);
 
1340
  
 
1341
  gconf_log(GCL_DEBUG, "Received request to remove dir `%s'", dir);
 
1342
  
 
1343
  gconf_sources_remove_dir(db->sources, dir, err);
 
1344
 
 
1345
  if (err && *err != NULL)
 
1346
    {
 
1347
      gconf_log(GCL_ERR, _("Error removing dir `%s': %s"),
 
1348
                 dir, (*err)->message);
 
1349
    }
 
1350
  else
 
1351
    {
 
1352
      gconf_database_schedule_sync(db);
 
1353
    }
 
1354
}
 
1355
 
 
1356
GSList*
 
1357
gconf_database_all_entries (GConfDatabase  *db,
 
1358
                            const gchar    *dir,
 
1359
                            const gchar   **locales,
 
1360
                            GError    **err)
 
1361
{
 
1362
  GSList* entries;
 
1363
  
 
1364
  g_return_val_if_fail(err == NULL || *err == NULL, NULL);
 
1365
  
 
1366
  g_assert(db->listeners != NULL);
 
1367
  
 
1368
  db->last_access = time(NULL);
 
1369
  
 
1370
  entries = gconf_sources_all_entries(db->sources, dir, locales, err);
 
1371
 
 
1372
  if (err && *err != NULL)
 
1373
    {
 
1374
      gconf_log(GCL_ERR, _("Failed to get all entries in `%s': %s"),
 
1375
                 dir, (*err)->message);
 
1376
    }
 
1377
 
 
1378
  return entries;
 
1379
}
 
1380
 
 
1381
GSList*
 
1382
gconf_database_all_dirs (GConfDatabase  *db,
 
1383
                         const gchar    *dir,
 
1384
                         GError    **err)
 
1385
{
 
1386
  GSList* subdirs;
 
1387
  
 
1388
  g_return_val_if_fail(err == NULL || *err == NULL, NULL);
 
1389
  
 
1390
  g_assert(db->listeners != NULL);
 
1391
  
 
1392
  db->last_access = time(NULL);
 
1393
    
 
1394
  gconf_log(GCL_DEBUG, "Received request to list all subdirs in `%s'", dir);
 
1395
 
 
1396
  subdirs = gconf_sources_all_dirs (db->sources, dir, err);
 
1397
 
 
1398
  if (err && *err != NULL)
 
1399
    {
 
1400
      gconf_log(GCL_ERR, _("Error listing dirs in `%s': %s"),
 
1401
                 dir, (*err)->message);
 
1402
    }
 
1403
  return subdirs;
 
1404
}
 
1405
 
 
1406
void
 
1407
gconf_database_set_schema (GConfDatabase  *db,
 
1408
                           const gchar    *key,
 
1409
                           const gchar    *schema_key,
 
1410
                           GError    **err)
 
1411
{
 
1412
  g_return_if_fail(err == NULL || *err == NULL);
 
1413
  g_assert(db->listeners != NULL);
 
1414
  
 
1415
  db->last_access = time(NULL);
 
1416
  
 
1417
  gconf_sources_set_schema(db->sources, key, schema_key, err);
 
1418
 
 
1419
  if (err && *err != NULL)
 
1420
    {
 
1421
      gconf_log(GCL_ERR, _("Error setting schema for `%s': %s"),
 
1422
                key, (*err)->message);
 
1423
    }
 
1424
  else
 
1425
    {
 
1426
      gconf_database_schedule_sync(db);
 
1427
    }
 
1428
}
 
1429
 
 
1430
void
 
1431
gconf_database_sync (GConfDatabase  *db,
 
1432
                     GError    **err)
 
1433
{
 
1434
  g_assert(db->listeners != NULL);
 
1435
  
 
1436
  db->last_access = time(NULL);
 
1437
  
 
1438
  gconf_log(GCL_DEBUG, "Received suggestion to sync all config data");
 
1439
 
 
1440
  gconf_database_sync_nowish(db);
 
1441
}
 
1442
 
 
1443
gboolean
 
1444
gconf_database_synchronous_sync (GConfDatabase  *db,
 
1445
                                 GError    **err)
 
1446
{  
 
1447
  /* remove the scheduled syncs */
 
1448
  if (db->sync_timeout != 0)
 
1449
    {
 
1450
      g_source_remove(db->sync_timeout);
 
1451
      db->sync_timeout = 0;
 
1452
    }
 
1453
 
 
1454
  if (db->sync_idle != 0)
 
1455
    {
 
1456
      g_source_remove(db->sync_idle);
 
1457
      db->sync_idle = 0;
 
1458
    }
 
1459
 
 
1460
  db->last_access = time(NULL);
 
1461
  
 
1462
  return gconf_sources_sync_all(db->sources, err);
 
1463
}
 
1464
 
 
1465
void
 
1466
gconf_database_clear_cache (GConfDatabase  *db,
 
1467
                            GError    **err)
 
1468
{
 
1469
  g_assert(db->listeners != NULL);
 
1470
 
 
1471
  db->last_access = time(NULL);
 
1472
 
 
1473
  gconf_sources_clear_cache(db->sources);
 
1474
}
 
1475
 
 
1476
const gchar*
 
1477
gconf_database_get_persistent_name (GConfDatabase *db)
 
1478
{
 
1479
  if (db->persistent_name == NULL)
 
1480
    {
 
1481
      if (db->sources->sources)
 
1482
        db->persistent_name =
 
1483
          g_strdup (((GConfSource*)db->sources->sources->data)->address);
 
1484
      else
 
1485
        db->persistent_name = g_strdup ("empty");
 
1486
    }
 
1487
 
 
1488
  return db->persistent_name;
 
1489
}
 
1490
 
 
1491
struct ForeachData
 
1492
{
 
1493
  GString *str;
 
1494
  gchar *db_name;
 
1495
};
 
1496
 
 
1497
static void
 
1498
listener_save_foreach (const gchar* location,
 
1499
                       guint cnxn_id,
 
1500
                       gpointer listener_data,
 
1501
                       gpointer user_data)
 
1502
{
 
1503
  struct ForeachData *fd = user_data;
 
1504
  Listener* l = listener_data;
 
1505
  CORBA_ORB orb;
 
1506
  CORBA_Environment ev;
 
1507
  gchar *ior;
 
1508
  gchar *s;
 
1509
  
 
1510
  s = g_strdup_printf ("ADD %u %s ", cnxn_id, fd->db_name);
 
1511
 
 
1512
  g_string_append (fd->str, s);
 
1513
 
 
1514
  g_free (s);
 
1515
 
 
1516
  s = gconf_quote_string (location);
 
1517
  g_string_append (fd->str, s);
 
1518
  g_free (s);
 
1519
  g_string_append_c (fd->str, ' ');
 
1520
  
 
1521
  orb = gconf_orb_get ();
 
1522
 
 
1523
  CORBA_exception_init (&ev);
 
1524
  
 
1525
  ior = CORBA_ORB_object_to_string(orb, l->obj, &ev);
 
1526
 
 
1527
  s = gconf_quote_string (ior);
 
1528
 
 
1529
  g_string_append (fd->str, s);
 
1530
 
 
1531
  g_free (s);
 
1532
  
 
1533
  CORBA_free(ior);
 
1534
 
 
1535
  g_string_append_c (fd->str, '\n');
 
1536
}
 
1537
 
 
1538
void
 
1539
gconf_database_log_listeners_to_string (GConfDatabase *db,
 
1540
                                        gboolean is_default,
 
1541
                                        GString *str)
 
1542
{
 
1543
  struct ForeachData fd;
 
1544
 
 
1545
  fd.str = str;
 
1546
  
 
1547
  if (is_default)
 
1548
    fd.db_name = gconf_quote_string ("def");
 
1549
  else
 
1550
    {
 
1551
      fd.db_name =
 
1552
        gconf_quote_string (gconf_database_get_persistent_name (db));
 
1553
    }
 
1554
        
 
1555
  gconf_listeners_foreach (db->listeners,
 
1556
                           listener_save_foreach,
 
1557
                           &fd);
 
1558
 
 
1559
  g_free (fd.db_name);
 
1560
}
 
1561
 
 
1562
/*
 
1563
 * Locale hash
 
1564
 */
 
1565
 
 
1566
static GConfLocaleCache* locale_cache = NULL;
 
1567
 
 
1568
static GConfLocaleList*
 
1569
locale_cache_lookup(const gchar* locale)
 
1570
{
 
1571
  GConfLocaleList* locale_list;
 
1572
  
 
1573
  if (locale_cache == NULL)
 
1574
    locale_cache = gconf_locale_cache_new();
 
1575
 
 
1576
  locale_list = gconf_locale_cache_get_list(locale_cache, locale);
 
1577
 
 
1578
  g_assert(locale_list != NULL);
 
1579
  g_assert(locale_list->list != NULL);
 
1580
  
 
1581
  return locale_list;
 
1582
}
 
1583
 
 
1584
void
 
1585
gconfd_locale_cache_expire(void)
 
1586
{
 
1587
  if (locale_cache != NULL)
 
1588
    gconf_locale_cache_expire(locale_cache, 60 * 30); /* 60 sec * 30 min */
 
1589
}
 
1590
 
 
1591
void
 
1592
gconfd_locale_cache_drop(void)
 
1593
{
 
1594
  if (locale_cache != NULL)
 
1595
    {
 
1596
      gconf_locale_cache_free(locale_cache);
 
1597
      locale_cache = NULL;
 
1598
    }
 
1599
}
 
1600
 
 
1601
/*
 
1602
 * The listener object
 
1603
 */
 
1604
 
 
1605
static Listener* 
 
1606
listener_new(ConfigListener obj)
 
1607
{
 
1608
  Listener* l;
 
1609
  CORBA_Environment ev;
 
1610
 
 
1611
  CORBA_exception_init(&ev);
 
1612
 
 
1613
  l = g_new0(Listener, 1);
 
1614
 
 
1615
  l->obj = CORBA_Object_duplicate(obj, &ev);
 
1616
 
 
1617
  return l;
 
1618
}
 
1619
 
 
1620
static void      
 
1621
listener_destroy(Listener* l)
 
1622
 
 
1623
{  
 
1624
  CORBA_Environment ev;
 
1625
 
 
1626
  CORBA_exception_init(&ev);
 
1627
  CORBA_Object_release(l->obj, &ev);
 
1628
  g_free(l);
 
1629
}