157
162
gboolean notfound = FALSE;
159
if (stat(xml_filename, &s) != 0)
164
if (g_stat(xml_filename, &s) != 0)
161
166
if (errno != ENOENT)
163
gconf_set_error(err, GCONF_ERROR_FAILED,
164
_("Could not stat `%s': %s"),
165
xml_filename, strerror(errno));
168
gconf_set_error (err, GCONF_ERROR_FAILED,
169
_("Could not stat `%s': %s"),
170
xml_filename, g_strerror(errno));
271
dir_sync_pending (Dir *d)
280
dir_sync_pending (Dir *d)
286
dir_child_removed (Dir *d,
287
const char *child_name)
291
/* dirty because we need to consider removing
292
* this directory, it may have become empty.
296
if (d->need_rescan_subdirs)
297
return; /* subdir_names is totally invalid anyhow */
299
tmp = d->subdir_names;
302
if (strcmp (tmp->data, child_name) == 0)
304
char *tofree = tmp->data;
306
d->subdir_names = g_slist_remove (d->subdir_names,
318
dir_child_added (Dir *d,
319
const char *child_name)
321
if (d->need_rescan_subdirs)
324
if (g_slist_find_custom (d->subdir_names,
326
(GCompareFunc) strcmp) == NULL)
327
d->subdir_names = g_slist_prepend (d->subdir_names,
328
g_strdup (child_name));
331
/* directories auto-disappear when they're empty */
336
dir_load_doc (d, NULL);
338
if (d->need_rescan_subdirs)
339
dir_rescan_subdirs (d, NULL);
342
d->subdir_names == NULL &&
343
g_hash_table_size (d->entry_cache) == 0;
346
/* for info on why this is used rather than xmlDocDump or xmlSaveFile
347
* and friends, see http://bugzilla.gnome.org/show_bug.cgi?id=108329 */
349
gconf_xml_doc_dump (FILE *fp, xmlDocPtr doc)
354
xmlDocDumpFormatMemory (doc, (xmlChar **) &xmlbuf, &n, TRUE);
361
if (fwrite (xmlbuf, sizeof (xmlChar), n, fp) < n)
369
/* From the fflush(3) man page:
371
* Note that fflush() only flushes the user space buffers provided by the
372
* C library. To ensure that the data is physically stored on disk the
373
* kernel buffers must be flushed too, e.g. with sync(2) or fsync(2).
376
/* flush user-space buffers */
377
if (fflush (fp) != 0)
380
if ((fd = fileno (fp)) == -1)
384
/* sync kernel-space buffers to disk */
385
if (fsync (fd) == -1)
277
dir_sync (Dir* d, GError** err)
279
397
gboolean retval = TRUE;
281
/* note that if we are deleted but already
282
synced, this returns now, making the
283
dircache's recursive delete tactic reasonably
289
/* We should have a doc if dirty is TRUE */
290
g_assert(d->doc != NULL);
292
d->last_access = time(NULL);
405
gconf_log (GCL_DEBUG, "Syncing dir \"%s\"", d->key);
407
d->last_access = time (NULL);
296
if (unlink(d->xml_filename) != 0)
298
gconf_set_error(err, GCONF_ERROR_FAILED, _("Failed to delete `%s': %s"),
299
d->xml_filename, strerror(errno));
303
if (rmdir(d->fs_dirname) != 0)
305
gconf_set_error(err, GCONF_ERROR_FAILED, _("Failed to delete `%s': %s"),
306
d->fs_dirname, strerror(errno));
411
gconf_log (GCL_DEBUG, "Deleting useless dir \"%s\"",
414
if (g_unlink (d->xml_filename) != 0)
416
gconf_set_error (err, GCONF_ERROR_FAILED, _("Failed to delete \"%s\": %s"),
417
d->xml_filename, g_strerror (errno));
421
if (strcmp (d->key, "/") != 0) /* don't delete root dir */
423
if (g_rmdir (d->fs_dirname) != 0)
425
gconf_set_error (err, GCONF_ERROR_FAILED, _("Failed to delete \"%s\": %s"),
426
d->fs_dirname, g_strerror (errno));
312
436
gboolean old_existed = FALSE;
313
437
gchar* tmp_filename;
314
438
gchar* old_filename;
441
/* We should have a doc if deleted is FALSE */
442
g_assert(d->doc != NULL);
316
444
/* First make sure entry values are synced to their
320
448
tmp_filename = g_strconcat(d->fs_dirname, "/%gconf.xml.tmp", NULL);
321
449
old_filename = g_strconcat(d->fs_dirname, "/%gconf.xml.old", NULL);
323
if (xmlSaveFile(tmp_filename, d->doc) < 0)
451
outfile = g_fopen (tmp_filename, "w");
325
gboolean recovered = FALSE;
327
455
/* Try to solve the problem by creating the FS dir */
328
if (!gconf_file_exists(d->fs_dirname))
456
if (!g_file_test (d->fs_dirname, G_FILE_TEST_EXISTS))
330
458
if (create_fs_dir(d->fs_dirname, d->xml_filename,
332
460
d->dir_mode, d->file_mode,
335
if (xmlSaveFile(tmp_filename, d->doc) >= 0)
462
outfile = g_fopen (tmp_filename, "w");
342
/* I think libxml may mangle errno, but we might as well
343
try. Don't set error if it's already set by some
467
/* Don't set error if it's already set by some
345
470
if (err && *err == NULL)
346
471
gconf_set_error(err, GCONF_ERROR_FAILED, _("Failed to write file `%s': %s"),
347
tmp_filename, strerror(errno));
472
tmp_filename, g_strerror(errno));
481
/* Set permissions on the new file */
482
if (fchmod (fileno (outfile), d->file_mode) != 0)
484
gconf_set_error(err, GCONF_ERROR_FAILED,
485
_("Failed to set mode on `%s': %s"),
486
tmp_filename, g_strerror(errno));
489
goto failed_end_of_sync;
493
if (gconf_xml_doc_dump (outfile, d->doc) < 0)
495
gconf_set_error (err, GCONF_ERROR_FAILED,
496
_("Failed to write XML data to `%s': %s"),
497
tmp_filename, g_strerror (errno));
500
goto failed_end_of_sync;
503
if (fclose (outfile) < 0)
505
gconf_set_error (err, GCONF_ERROR_FAILED,
506
_("Failed to close file `%s': %s"),
507
tmp_filename, g_strerror (errno));
511
goto failed_end_of_sync;
355
517
/* Set permissions on the new file */
356
518
if (chmod (tmp_filename, d->file_mode) != 0)
358
520
gconf_set_error(err, GCONF_ERROR_FAILED,
359
521
_("Failed to set mode on `%s': %s"),
360
tmp_filename, strerror(errno));
522
tmp_filename, g_strerror(errno));
363
525
goto failed_end_of_sync;
366
old_existed = gconf_file_exists(d->xml_filename);
529
old_existed = g_file_test (d->xml_filename, G_FILE_TEST_EXISTS);
370
if (rename(d->xml_filename, old_filename) < 0)
533
if (g_rename(d->xml_filename, old_filename) < 0)
372
535
gconf_set_error(err, GCONF_ERROR_FAILED,
373
536
_("Failed to rename `%s' to `%s': %s"),
374
d->xml_filename, old_filename, strerror(errno));
537
d->xml_filename, old_filename, g_strerror(errno));
377
540
goto failed_end_of_sync;
381
if (rename(tmp_filename, d->xml_filename) < 0)
544
if (g_rename(tmp_filename, d->xml_filename) < 0)
383
546
gconf_set_error(err, GCONF_ERROR_FAILED, _("Failed to rename `%s' to `%s': %s"),
384
tmp_filename, d->xml_filename, strerror(errno));
547
tmp_filename, d->xml_filename, g_strerror(errno));
386
549
/* Put the original file back, so this isn't a total disaster. */
387
if (rename(old_filename, d->xml_filename) < 0)
550
if (g_rename(old_filename, d->xml_filename) < 0)
389
552
gconf_set_error(err, GCONF_ERROR_FAILED, _("Failed to restore `%s' from `%s': %s"),
390
d->xml_filename, old_filename, strerror(errno));
553
d->xml_filename, old_filename, g_strerror(errno));
652
842
guint subdir_len;
654
844
if (d->doc == NULL)
655
dir_load_doc(d, err);
845
dir_load_doc (d, err);
657
847
if (d->doc == NULL)
659
g_return_val_if_fail( (err == NULL) || (*err != NULL), NULL );
849
g_return_val_if_fail ((err == NULL) || (*err != NULL), FALSE);
853
if (!d->need_rescan_subdirs)
856
g_slist_foreach (d->subdir_names, (GFunc) g_free, NULL);
857
g_slist_free (d->subdir_names);
858
d->subdir_names = NULL;
663
dp = opendir(d->fs_dirname);
860
dp = g_dir_open (d->fs_dirname, 0, NULL);
864
d->need_rescan_subdirs = FALSE;
668
868
len = strlen(d->fs_dirname);
669
869
subdir_len = PATH_MAX - len;
677
877
*fullpath_end = '\0';
679
while ((dent = readdir(dp)) != NULL)
879
while ((dent = g_dir_read_name(dp)) != NULL)
681
/* ignore ., .., and all dot-files */
682
if (dent->d_name[0] == '.')
881
/* ignore all dot-files */
685
len = strlen(dent->d_name);
687
887
if (len < subdir_len)
689
strcpy(fullpath_end, dent->d_name);
889
strcpy(fullpath_end, dent);
690
890
strncpy(fullpath_end+len, "/%gconf.xml", subdir_len - len);
693
893
continue; /* Shouldn't ever happen since PATH_MAX is available */
695
if (stat(fullpath, &statbuf) < 0)
895
if (g_stat(fullpath, &statbuf) < 0)
697
897
/* This is some kind of cruft, not an XML directory */
701
retval = g_slist_prepend(retval, g_strdup(dent->d_name));
901
retval = g_slist_prepend (retval, g_strdup(dent));
704
904
/* if this fails, we really can't do a thing about it
705
and it's not a meaningful error */
905
* and it's not a meaningful error
708
909
g_free (fullpath);
911
d->subdir_names = retval;
912
d->need_rescan_subdirs = FALSE;
918
dir_all_subdirs (Dir* d, GError** err)
920
if (!dir_rescan_subdirs (d, err))
923
return copy_string_list (d->subdir_names);
714
dir_set_schema (Dir* d,
715
const gchar* relative_key,
716
const gchar* schema_key,
927
dir_set_schema (Dir *d,
928
const gchar *relative_key,
929
const gchar *schema_key,
721
934
if (d->doc == NULL)
722
dir_load_doc(d, err);
935
dir_load_doc (d, err);
724
937
if (d->doc == NULL)
726
g_return_if_fail( (err == NULL) || (*err != NULL) );
939
g_return_if_fail ((err == NULL) || (*err != NULL));
731
d->last_access = time(NULL);
944
d->last_access = time (NULL);
733
e = g_hash_table_lookup(d->entry_cache, relative_key);
946
e = g_hash_table_lookup (d->entry_cache, relative_key);
736
e = dir_make_new_entry(d, relative_key);
738
entry_set_mod_time(e, d->last_access);
740
entry_set_schema_name(e, schema_key);
949
e = dir_make_new_entry (d, relative_key);
951
entry_set_mod_time (e, d->last_access);
953
entry_set_schema_name (e, schema_key);
742
955
if (schema_key == NULL)
743
dir_forget_entry_if_useless(d, e);
747
dir_mark_deleted(Dir* d)
755
/* go ahead and free the XML document */
763
dir_is_deleted (Dir* d)
956
dir_forget_entry_if_useless (d, e);
815
1008
if (xml_already_exists)
816
d->doc = xmlParseFile(d->xml_filename);
818
/* We recover from these errors instead of passing them up */
1011
gboolean error_was_fatal;
1013
error_was_fatal = FALSE;
1015
d->doc = my_xml_parse_file (d->xml_filename, &tmp_err);
1017
if (tmp_err != NULL)
1019
gconf_log (GCL_WARNING,
1020
"%s", tmp_err->message);
1022
/* file errors are assumed to be some kind of
1023
* blowup, like out of file descriptors, so
1024
* we play it safe and don't touch anything
1026
if (tmp_err->domain == G_FILE_ERROR)
1027
error_was_fatal = TRUE;
1029
g_error_free (tmp_err);
1032
if (error_was_fatal)
1036
/* We recover from parse errors instead of passing them up */
820
1038
/* This has the potential to just blow away an entire corrupted
821
config file; but I think that is better than the alternatives
822
(disabling config for a directory because the document is mangled)
1039
* config file; but I think that is better than the alternatives
1040
* (disabling config for a directory because the document is mangled).
1042
* Parse errors really should not happen from an XML file we created
1043
* ourselves anyway...
825
1046
/* Also we create empty %gconf.xml files when we create a new dir,
826
and those return a parse error */
1047
* and those return a parse error, though they should be trapped
1048
* by the statbuf.st_size == 0 check above.
828
1051
if (d->doc == NULL)
830
1053
if (xml_already_exists)
831
need_backup = TRUE; /* we want to save whatever broken stuff was in the file */
1054
need_backup = TRUE; /* rather uselessly save whatever broken stuff was in the file */
833
1056
/* Create a new doc */
835
d->doc = xmlNewDoc("1.0");
1058
d->doc = xmlNewDoc((xmlChar *)"1.0");
838
if (d->doc->root == NULL)
1061
if (d->doc->xmlRootNode == NULL)
840
1063
/* fill it in */
841
d->doc->root = xmlNewDocNode(d->doc, NULL, "gconf", NULL);
1064
d->doc->xmlRootNode = xmlNewDocNode(d->doc, NULL, "gconf", NULL);
843
else if (strcmp(d->doc->root->name, "gconf") != 0)
1066
else if (strcmp((char*)d->doc->xmlRootNode->name, "gconf") != 0)
845
1068
xmlFreeDoc(d->doc);
846
d->doc = xmlNewDoc("1.0");
847
d->doc->root = xmlNewDocNode(d->doc, NULL, "gconf", NULL);
1069
d->doc = xmlNewDoc((xmlChar*)"1.0");
1070
d->doc->xmlRootNode = xmlNewDocNode(d->doc, NULL, (xmlChar *)"gconf", NULL);
848
1071
need_backup = TRUE; /* save broken stuff */
888
1111
g_return_val_if_fail(d->doc != NULL, NULL);
889
g_return_val_if_fail(d->doc->root != NULL, NULL);
1112
g_return_val_if_fail(d->doc->xmlRootNode != NULL, NULL);
891
1114
e = entry_new(relative_key);
893
entry_set_node(e, xmlNewChild(d->doc->root, NULL, "entry", NULL));
1116
entry_set_node(e, xmlNewChild(d->doc->xmlRootNode, NULL, (xmlChar *)"entry", NULL));
895
1118
safe_g_hash_table_insert(d->entry_cache, (gchar*)entry_get_name(e), e);
1043
1266
gconf_log(GCL_DEBUG, "Making directory %s", dir);
1045
if (mkdir(dir, dir_mode) < 0)
1268
if (g_mkdir(dir, dir_mode) < 0)
1047
1270
if (errno != EEXIST)
1049
1272
gconf_set_error(err, GCONF_ERROR_FAILED,
1050
_("Could not make directory `%s': %s"),
1051
(gchar*)dir, strerror(errno));
1273
_("Could not make directory \"%s\": %s"),
1274
(gchar*)dir, g_strerror(errno));
1059
1282
/* don't truncate the file, it may well already exist */
1060
fd = open(xml_filename, O_CREAT | O_WRONLY, file_mode);
1283
fd = g_open(xml_filename, O_CREAT | O_WRONLY, file_mode);
1062
1285
gconf_log(GCL_DEBUG, "Creating XML file %s", xml_filename);
1066
1289
gconf_set_error(err, GCONF_ERROR_FAILED, _("Failed to create file `%s': %s"),
1067
xml_filename, strerror(errno));
1290
xml_filename, g_strerror(errno));