70
70
struct stat *statbuf)
71
71
__attribute__ ((warn_unused_result));
73
static int conf_reload_path (ConfSource *source, const char *path)
74
__attribute__ ((warn_unused_result));
73
static int conf_reload_path (ConfSource *source, const char *path,
74
const char *override_path)
75
__attribute__ ((warn_unused_result));
77
static inline int is_conf_file (const char *path)
78
__attribute__ ((warn_unused_result));
80
static inline int is_conf_file_std (const char *path)
81
__attribute__ ((warn_unused_result));
83
static inline int is_conf_file_override(const char *path)
84
__attribute__ ((warn_unused_result));
98
* @path: path to check.
100
* Determine if specified path contains a legitimate
101
* configuration file name.
103
* Returns: TRUE if @path contains a valid configuration file name,
108
is_conf_file_std (const char *path)
110
char *ptr = strrchr (path, '.');
112
if (ptr && IS_CONF_EXT_STD (ptr))
119
* is_conf_file_override:
120
* @path: path to check.
122
* Determine if specified path contains a legitimate
123
* override file name.
125
* Returns: TRUE if @path contains a valid override file name,
130
is_conf_file_override (const char *path)
132
char *ptr = strrchr (path, '.');
134
if (ptr && IS_CONF_EXT_OVERRIDE (ptr))
142
* @path: path to check.
144
* Determine if specified path contains a legitimate
145
* configuration file or override file name.
147
* Returns: TRUE if @path contains a valid configuration
148
* file or override file name, else FALSE.
152
is_conf_file (const char *path)
154
char *ptr = strrchr (path, '.');
156
if (ptr && (ptr > path) && (ptr[-1] != '/') && IS_CONF_EXT (ptr))
163
* Convert a configuration file name to an override file name and vice
166
* For example, if @path is "foo.conf", this function will return
167
* "foo.override", whereas if @path is "foo.override", it will return
170
* Note that this function should be static, but isn't to allow the
171
* tests to access it.
173
* @parent: parent of returned path,
174
* @path: path to a configuration file.
176
* Returns: newly allocated toggled path, or NULL on error.
179
toggle_conf_name (const void *parent,
187
ext = strrchr (path, '.');
191
new_ext = IS_CONF_EXT_STD (ext)
195
len = strlen (new_ext);
197
new_path = NIH_MUST (nih_strndup (parent, path, (ext - path) + len));
199
memcpy (new_path + (ext - path), new_ext, len);
90
208
* Initialise the conf_sources list.
501
642
* @is_dir: TRUE of @path is a directory.
503
644
* This is the file filter used for the jobs directory, we only care
504
* about paths with the ".conf" extension. Directories that
505
* match the nih_file_ignore() function are also ignored.
507
* Returns: FALSE if @path ends in ".conf", or is the original source,
645
* about paths with particular extensions (see IS_CONF_EXT).
647
* Directories that match the nih_file_ignore() function are also ignored.
649
* Returns: FALSE if @path ends in ".conf" or ".override",
650
* or is the original source, TRUE otherwise.
511
653
conf_dir_filter (ConfSource *source,
512
654
const char *path,
517
657
nih_assert (source != NULL);
518
658
nih_assert (path != NULL);
546
685
* After checking that it was a regular file that was changed, we reload it;
547
686
* we expect this to fail sometimes since the file may be only partially
551
690
conf_create_modify_handler (ConfSource *source,
553
692
const char *path,
554
693
struct stat *statbuf)
695
ConfFile *file = NULL;
696
const char *error_path = path;
697
nih_local char *new_path = NULL;
556
700
nih_assert (source != NULL);
557
701
nih_assert (watch != NULL);
558
702
nih_assert (path != NULL);
559
703
nih_assert (statbuf != NULL);
705
/* note that symbolic links are ignored */
561
706
if (! S_ISREG (statbuf->st_mode))
564
if (conf_reload_path (source, path) < 0) {
709
new_path = toggle_conf_name (NULL, path);
710
file = (ConfFile *)nih_hash_lookup (source->files, new_path);
712
if (is_conf_file_override (path)) {
714
/* override file has no corresponding conf file */
715
nih_debug ("Ignoring orphan override file %s", path);
719
/* reload conf file */
720
nih_debug ("Loading configuration file %s", new_path);
721
ret = conf_reload_path (source, new_path, NULL);
723
error_path = new_path;
727
/* overlay override settings */
728
nih_debug ("Loading override file %s for %s", path, new_path);
729
ret = conf_reload_path (source, new_path, path);
735
nih_debug ("Loading configuration and override files for %s", path);
738
nih_debug ("Loading configuration file %s", path);
739
ret = conf_reload_path (source, path, NULL);
745
/* ensure we ignore directory changes (which won't have overrides. */
746
if (is_conf_file_std (path)) {
748
if (stat (new_path, &st) == 0) {
749
/* overlay override settings */
750
nih_debug ("Loading override file %s for %s", new_path, path);
751
ret = conf_reload_path (source, path, new_path);
753
error_path = new_path;
567
767
err = nih_error_get ();
568
nih_error ("%s: %s: %s", path,
569
_("Error while loading configuration file"),
768
nih_error ("%s: %s: %s", error_path,
769
_("Error while loading configuration file"),
773
nih_unref (file, source);
617
nih_unref (file, source);
824
/* non-override files (and directories) are the simple case, so handle
827
if (! is_conf_file_override (path)) {
828
nih_unref (file, source);
832
/* if an override file is deleted for which there is a corresponding
833
* conf file, reload the conf file to remove any modifications
834
* introduced by the override file.
836
new_path = toggle_conf_name (NULL, path);
837
file = (ConfFile *)nih_hash_lookup (source->files, new_path);
840
nih_debug ("Reloading configuration for %s on deletion of overide (%s)",
843
if ( conf_reload_path (source, new_path, NULL) < 0 ) {
844
nih_warn ("%s: %s", new_path,
845
_("Unable to reload configuration after override deletion"));
637
867
const char *path,
638
868
struct stat *statbuf)
870
ConfFile *file = NULL;
871
nih_local char *new_path = NULL;
640
873
nih_assert (source != NULL);
641
874
nih_assert (dirname != NULL);
642
875
nih_assert (path != NULL);
643
876
nih_assert (statbuf != NULL);
878
/* We assume that CONF_EXT_STD files are visited before
879
* CONF_EXT_OVERRIDE files. Happily, this assumption is currently
880
* valid since CONF_EXT_STD comes before CONF_EXT_OVERRIDE if ordered
883
* If this were ever to change (for example if we decided to
884
* rename the CONF_EXT_OVERRIDE files to end in ".abc", say), the logic
885
* in this function would be erroneous since it would never be possible when
886
* visiting an override file (before a conf file) to lookup a conf file
887
* in the hash, since the conf file would not yet have been seen and thus would
888
* not exist in the hash (yet).
890
nih_assert (CONF_EXT_STD[1] < CONF_EXT_OVERRIDE[1]);
645
892
if (! S_ISREG (statbuf->st_mode))
648
if (conf_reload_path (source, path) < 0) {
651
err = nih_error_get ();
652
nih_error ("%s: %s: %s", path,
653
_("Error while loading configuration file"),
895
if (is_conf_file_std (path)) {
896
if (conf_reload_path (source, path, NULL) < 0) {
899
err = nih_error_get ();
900
nih_error ("%s: %s: %s", path,
901
_("Error while loading configuration file"),
908
new_path = toggle_conf_name (NULL, path);
909
file = (ConfFile *)nih_hash_lookup (source->files, new_path);
912
/* we're visiting an override file with an associated conf file that
913
* has already been loaded, so just overlay the override file. If
914
* there is no corresponding conf file, we ignore the override file.
916
if (conf_reload_path (source, new_path, path) < 0) {
919
err = nih_error_get ();
920
nih_error ("%s: %s: %s", new_path,
921
_("Error while reloading configuration file"),
663
932
* conf_reload_path:
664
933
* @source: configuration source,
665
* @path: path of file to be reloaded.
934
* @path: path of conf file to be reloaded.
935
* @override_path: if not NULL and @path refers to a path associated with @source,
936
* overlay the contents of @path into the existing @source entry for
937
* @path. If FALSE, discard any existing knowledge of @path.
667
* This function is used to parse the file at @path in the context of the
668
* given configuration @source. Necessary ConfFile structures are allocated
669
* and attached to @source as appropriate. CONF_FILE sources always have
670
* a single ConfFile when the file exists.
939
* This function is used to parse the file at @path (or @override_path) in the
940
* context of the given configuration @source. Necessary ConfFile structures
941
* are allocated and attached to @source as appropriate. CONF_FILE sources
942
* always have a single ConfFile when the file exists.
672
944
* If the file has been parsed before, then the existing item is deleted and
673
945
* freed if the file fails to load, or after the new item has been parsed.
674
* Items are not reused between reloads.
946
* Items are only reused between reloads if @override_path is
676
949
* Physical errors are returned, parse errors are not.
681
954
conf_reload_path (ConfSource *source,
956
const char *override_path)
958
ConfFile *file = NULL;
685
959
nih_local char *buf = NULL;
686
960
const char *start, *end;
687
961
nih_local char *name = NULL;
688
962
size_t len, pos, lineno;
689
963
NihError *err = NULL;
964
const char *path_to_load;
691
966
nih_assert (source != NULL);
692
967
nih_assert (path != NULL);
694
/* Look up the old file in memory, and then free it. In cases
695
* of failure, we discard it anyway, so there's no particular reason
969
path_to_load = (override_path ? override_path : path);
971
/* If there is no corresponding override file, look up the old
972
* conf file in memory, and then free it. In cases of failure,
973
* we discard it anyway, so there's no particular reason
696
974
* to keep it around anymore.
976
* Note: if @override_path has been specified, do not
977
* free the file if found, since we want to _update_ the
698
980
file = (ConfFile *)nih_hash_lookup (source->files, path);
981
if (! override_path && file)
700
982
nih_unref (file, source);
702
984
/* Read the file into memory for parsing, if this fails we don't
703
985
* bother creating a new ConfFile structure for it and bail out
706
buf = nih_file_read (NULL, path, &len);
988
buf = nih_file_read (NULL, path_to_load, &len);
710
/* Parse the file, storing the item in a new ConfFile structure. */
711
file = NIH_MUST (conf_file_new (source, path));
992
/* Create a new ConfFile structure (if no @override_path specified) */
993
file = (ConfFile *)nih_hash_lookup (source->files, path);
995
file = NIH_MUST (conf_file_new (source, path));
744
1035
/* Create a new job item and parse the buffer to produce
745
1036
* the job definition.
747
nih_debug ("Loading %s from %s", name, path);
748
file->job = parse_job (NULL, source->session,
749
name, buf, len, &pos, &lineno);
1038
if (override_path) {
1039
nih_debug ("Updating %s (%s) with %s",
1040
name, path, override_path);
1042
nih_debug ("Loading %s from %s", name, path);
1045
file->job = parse_job (NULL, source->session, file->job,
1046
name, buf, len, &pos, &lineno);
750
1048
if (file->job) {
751
1049
job_class_consider (file->job);
1192
debug_count_list_entries (const NihList *list)
1195
NIH_LIST_FOREACH (list, iter) {
1202
debug_count_hash_entries (const NihHash *hash)
1205
NIH_HASH_FOREACH_SAFE (hash, iter) {
1212
debug_show_job_class (const JobClass *job)
1215
char **env = (char **)job->env;
1216
char **export = (char **)job->export;
1220
nih_debug ("JobClass %p: name='%s', path='%s', task=%d, "
1221
"respawn=%d, console=%x, deleted=%d, debug=%d",
1222
job, job->name, job->path, job->task,
1223
job->respawn, job->console, job->deleted, job->debug);
1225
nih_debug ("\tstart_on=%p, stop_on=%p, emits=%p, process=%p",
1226
job->start_on, job->stop_on, job->emits, job->process);
1228
nih_debug ("\tauthor='%s', description='%s'",
1229
job->author, job->description);
1232
nih_debug ("\tenv:");
1235
nih_debug ("\t\tenv[%d]='%s' (len=%u+1)",
1236
i, *env, strlen (*env));
1241
nih_debug ("\tenv: none.");
1245
if (export && *export) {
1246
nih_debug ("\texport:");
1249
nih_debug ("\t\tenv[%d]='%s' (len=%u+1)",
1250
i, *export, strlen (*export));
1256
nih_debug ("\texport: none");
1261
debug_show_job_classes (void)
1263
nih_debug ("job_classes:");
1265
NIH_HASH_FOREACH_SAFE (job_classes, iter) {
1266
JobClass *job = (JobClass *)iter;
1267
debug_show_job_class (job);
1272
debug_show_event (const Event *event)
1276
nih_debug ("Event %p: name='%s', progress=%x, failed=%d, "
1277
"blockers=%d, blocking=%p",
1278
event, event->name, event->progress, event->failed,
1279
event->blockers, (void *)&event->blocking);
1283
debug_show_conf_file (const ConfFile *file)
1287
nih_debug ("ConfFile %p: path='%s', source=%p, flag=%x, job=%p",
1288
file, file->path, file->source, file->flag, file->job);
1290
/* Some ConfFile objects won't have any JobClass details, for example,
1291
* the ConfFile object associated with "/etc/init.conf".
1294
nih_debug ("ConfFile %p: job: no JobClass object.", file);
1298
nih_debug ("ConfFile %p: job:", file);
1299
debug_show_job_class (file->job);
1303
debug_show_conf_source (const ConfSource *source)
1305
nih_assert (source);
1307
nih_debug ("ConfSource %p: path='%s', type=%x, flag=%x",
1308
source, source->path, source->type, source->flag);
1310
nih_debug ("ConfSource %p files (%d):", source,
1311
debug_count_hash_entries (source->files));
1313
NIH_HASH_FOREACH (source->files, file_iter) {
1314
ConfFile *file = (ConfFile *)file_iter;
1315
debug_show_conf_file (file);
1320
debug_show_conf_sources (void)
1322
nih_assert (conf_sources);
1324
nih_debug ("conf_sources:");
1326
NIH_LIST_FOREACH (conf_sources, iter) {
1327
ConfSource *source = (ConfSource *)iter;
1328
debug_show_conf_source (source);