55
55
#include "errors.h"
60
* @parent: parent for jobs,
61
* @prefix: prefix for job names.
63
* Data pointed passed to the config file watcher function.
65
typedef struct watch_info {
71
58
/* Prototypes for static functions */
72
static int cfg_stanza_description (Job *job, NihConfigStanza *stanza,
73
const char *file, size_t len,
74
size_t *pos, size_t *lineno);
75
static int cfg_stanza_author (Job *job, NihConfigStanza *stanza,
76
const char *file, size_t len,
77
size_t *pos, size_t *lineno);
78
static int cfg_stanza_version (Job *job, NihConfigStanza *stanza,
79
const char *file, size_t len,
80
size_t *pos, size_t *lineno);
81
static int cfg_stanza_emits (Job *job, NihConfigStanza *stanza,
82
const char *file, size_t len,
83
size_t *pos, size_t *lineno);
84
static int cfg_stanza_on (Job *job, NihConfigStanza *stanza,
85
const char *file, size_t len,
86
size_t *pos, size_t *lineno);
87
static int cfg_stanza_start (Job *job, NihConfigStanza *stanza,
88
const char *file, size_t len,
89
size_t *pos, size_t *lineno);
90
static int cfg_stanza_stop (Job *job, NihConfigStanza *stanza,
91
const char *file, size_t len,
92
size_t *pos, size_t *lineno);
93
static int cfg_stanza_exec (Job *job, NihConfigStanza *stanza,
94
const char *file, size_t len,
95
size_t *pos, size_t *lineno);
96
static int cfg_stanza_daemon (Job *job, NihConfigStanza *stanza,
97
const char *file, size_t len,
98
size_t *pos, size_t *lineno);
99
static int cfg_stanza_respawn (Job *job, NihConfigStanza *stanza,
100
const char *file, size_t len,
101
size_t *pos, size_t *lineno);
102
static int cfg_stanza_script (Job *job, NihConfigStanza *stanza,
103
const char *file, size_t len,
104
size_t *pos, size_t *lineno);
105
static int cfg_stanza_instance (Job *job, NihConfigStanza *stanza,
106
const char *file, size_t len,
107
size_t *pos, size_t *lineno);
108
static int cfg_stanza_pid (Job *job, NihConfigStanza *stanza,
109
const char *file, size_t len,
110
size_t *pos, size_t *lineno);
111
static int cfg_stanza_kill (Job *job, NihConfigStanza *stanza,
112
const char *file, size_t len,
113
size_t *pos, size_t *lineno);
114
static int cfg_stanza_normalexit (Job *job, NihConfigStanza *stanza,
115
const char *file, size_t len,
116
size_t *pos, size_t *lineno);
117
static int cfg_stanza_console (Job *job, NihConfigStanza *stanza,
118
const char *file, size_t len,
119
size_t *pos, size_t *lineno);
120
static int cfg_stanza_env (Job *job, NihConfigStanza *stanza,
121
const char *file, size_t len,
122
size_t *pos, size_t *lineno);
123
static int cfg_stanza_umask (Job *job, NihConfigStanza *stanza,
124
const char *file, size_t len,
125
size_t *pos, size_t *lineno);
126
static int cfg_stanza_nice (Job *job, NihConfigStanza *stanza,
127
const char *file, size_t len,
128
size_t *pos, size_t *lineno);
129
static int cfg_stanza_limit (Job *job, NihConfigStanza *stanza,
130
const char *file, size_t len,
131
size_t *pos, size_t *lineno);
132
static int cfg_stanza_chroot (Job *job, NihConfigStanza *stanza,
133
const char *file, size_t len,
134
size_t *pos, size_t *lineno);
135
static int cfg_stanza_chdir (Job *job, NihConfigStanza *stanza,
136
const char *file, size_t len,
137
size_t *pos, size_t *lineno);
59
static int cfg_stanza_description (Job *job, NihConfigStanza *stanza,
60
const char *file, size_t len,
61
size_t *pos, size_t *lineno);
62
static int cfg_stanza_author (Job *job, NihConfigStanza *stanza,
63
const char *file, size_t len,
64
size_t *pos, size_t *lineno);
65
static int cfg_stanza_version (Job *job, NihConfigStanza *stanza,
66
const char *file, size_t len,
67
size_t *pos, size_t *lineno);
68
static int cfg_stanza_emits (Job *job, NihConfigStanza *stanza,
69
const char *file, size_t len,
70
size_t *pos, size_t *lineno);
71
static int cfg_stanza_on (Job *job, NihConfigStanza *stanza,
72
const char *file, size_t len,
73
size_t *pos, size_t *lineno);
74
static int cfg_stanza_start (Job *job, NihConfigStanza *stanza,
75
const char *file, size_t len,
76
size_t *pos, size_t *lineno);
77
static int cfg_stanza_stop (Job *job, NihConfigStanza *stanza,
78
const char *file, size_t len,
79
size_t *pos, size_t *lineno);
80
static int cfg_stanza_exec (Job *job, NihConfigStanza *stanza,
81
const char *file, size_t len,
82
size_t *pos, size_t *lineno);
83
static int cfg_stanza_daemon (Job *job, NihConfigStanza *stanza,
84
const char *file, size_t len,
85
size_t *pos, size_t *lineno);
86
static int cfg_stanza_respawn (Job *job, NihConfigStanza *stanza,
87
const char *file, size_t len,
88
size_t *pos, size_t *lineno);
89
static int cfg_stanza_script (Job *job, NihConfigStanza *stanza,
90
const char *file, size_t len,
91
size_t *pos, size_t *lineno);
92
static int cfg_stanza_instance (Job *job, NihConfigStanza *stanza,
93
const char *file, size_t len,
94
size_t *pos, size_t *lineno);
95
static int cfg_stanza_pid (Job *job, NihConfigStanza *stanza,
96
const char *file, size_t len,
97
size_t *pos, size_t *lineno);
98
static int cfg_stanza_kill (Job *job, NihConfigStanza *stanza,
99
const char *file, size_t len,
100
size_t *pos, size_t *lineno);
101
static int cfg_stanza_normalexit (Job *job, NihConfigStanza *stanza,
102
const char *file, size_t len,
103
size_t *pos, size_t *lineno);
104
static int cfg_stanza_console (Job *job, NihConfigStanza *stanza,
105
const char *file, size_t len,
106
size_t *pos, size_t *lineno);
107
static int cfg_stanza_env (Job *job, NihConfigStanza *stanza,
108
const char *file, size_t len,
109
size_t *pos, size_t *lineno);
110
static int cfg_stanza_umask (Job *job, NihConfigStanza *stanza,
111
const char *file, size_t len,
112
size_t *pos, size_t *lineno);
113
static int cfg_stanza_nice (Job *job, NihConfigStanza *stanza,
114
const char *file, size_t len,
115
size_t *pos, size_t *lineno);
116
static int cfg_stanza_limit (Job *job, NihConfigStanza *stanza,
117
const char *file, size_t len,
118
size_t *pos, size_t *lineno);
119
static int cfg_stanza_chroot (Job *job, NihConfigStanza *stanza,
120
const char *file, size_t len,
121
size_t *pos, size_t *lineno);
122
static int cfg_stanza_chdir (Job *job, NihConfigStanza *stanza,
123
const char *file, size_t len,
124
size_t *pos, size_t *lineno);
139
static void cfg_watcher (WatchInfo *info, NihFileWatch *watch,
140
uint32_t events, const char *name);
126
static char *cfg_job_name (const void *parent,
127
const char *dirname, const char *path);
128
static void cfg_create_modify_handler (void *data, NihWatch *watch,
130
static void cfg_delete_handler (void *data, NihWatch *watch,
132
static int cfg_visitor (void *data, const char *path);
1616
1608
* cfg_watch_dir:
1617
* @parent: parent of jobs,
1618
* @dirname: directory to watch,
1619
* @prefix: prefix to append to job names.
1609
* @dirname: directory to watch.
1621
1611
* Watch @dirname for creation or modification of configuration files or
1622
1612
* sub-directories and parse them whenever they exist. This also performs
1623
1613
* the initial parsing of jobs in the directory.
1625
* Jobs are named by joining @prefix and the name of the file under @dir,
1626
* @prefix may be NULL.
1628
* If @parent is not NULL, it should be a pointer to another allocated
1629
* block which will be used as the parent for this block. When @parent
1630
* is freed, the returned block will be freed too. If you have clean-up
1631
* that would need to be run, you can assign a destructor function using
1632
* the nih_alloc_set_destructor() function.
1634
1615
* Returns: zero on success, negative value on raised error.
1637
cfg_watch_dir (const void *parent,
1638
const char *dirname,
1618
cfg_watch_dir (const char *dirname)
1644
NihFileWatch *watch;
1646
1622
nih_assert (dirname != NULL);
1648
1624
nih_info (_("Reading configuration from %s"), dirname);
1650
NIH_MUST (info = nih_new (NULL, WatchInfo));
1651
info->parent = parent;
1652
info->prefix = prefix ? nih_strdup (info, prefix) : NULL;
1654
/* FIXME we don't handle move yet */
1656
/* Add a watch so we can keep up to date */
1657
watch = nih_file_add_watch (NULL, dirname,
1658
(IN_CREATE | IN_DELETE | IN_MODIFY),
1659
(NihFileWatcher)cfg_watcher, info);
1626
/* Use inotify to keep up to date about changes. It's not critical
1627
* for this to fail, but we do bitch about it.
1629
watch = nih_watch_new (NULL, dirname, TRUE, (NihFileFilter)NULL,
1630
(NihCreateHandler)cfg_create_modify_handler,
1631
(NihModifyHandler)cfg_create_modify_handler,
1632
(NihDeleteHandler)cfg_delete_handler, NULL);
1665
/* Read through any files already in the directory */
1666
dir = opendir (dirname);
1668
nih_error_raise_system ();
1673
/* Just call the watcher function */
1674
while ((ent = readdir (dir)) != NULL)
1675
cfg_watcher (info, watch, IN_CREATE, ent->d_name);
1684
* @info: watch information,
1685
* @watch: watch that generated the event,
1686
* @events: events that occurred,
1687
* @name: name of file that changed.
1689
* This function is called whenever a configuration file directory we are
1690
* watching changes. It arranges for the job to be parsed, or the new
1691
* directory to be watched.
1694
cfg_watcher (WatchInfo *info,
1695
NihFileWatch *watch,
1699
struct stat statbuf;
1700
char *filename, *jobname;
1702
nih_assert (watch != NULL);
1704
/* If this watch is now being ignored, free the info and watch */
1705
if (events & IN_IGNORED) {
1706
nih_debug ("Ceasing watching %s", watch->path);
1708
nih_list_free (&watch->entry);
1713
/* Otherwise name should be set and shouldn't begin . */
1717
if ((name[0] == '\0') || strchr (name, '.') || strchr (name, '~')) {
1718
nih_debug ("Ignored %s/%s", watch->path, name);
1722
/* FIXME better name checking required */
1724
/* FIXME we don't handle DELETE yet ... that should probably mark
1725
* the running job as an instance or delete a stopped one
1636
err = nih_error_get ();
1637
nih_error ("%s: %s: %s", dirname,
1638
_("Unable to watch configuration directory"),
1643
/* Parse all files that we find right now. If this fails, on the
1644
* other hand, it is a problem (though we may have parsed something).
1727
if (events & IN_DELETE) {
1728
nih_debug ("Delete of %s/%s (ignored)", watch->path, name);
1732
/* Construct filename and job name (also new prefix) */
1733
NIH_MUST (filename = nih_sprintf (NULL, "%s/%s", watch->path, name));
1735
NIH_MUST (jobname = nih_sprintf (NULL, "%s/%s",
1736
info->prefix, name));
1738
NIH_MUST (jobname = nih_strdup (NULL, name));
1741
/* Check we can stat it */
1742
if (stat (filename, &statbuf) < 0) {
1743
/* Bah, ignore the error */
1745
} else if (S_ISDIR (statbuf.st_mode)) {
1746
/* It's a directory, watch it */
1747
cfg_watch_dir (info->parent, filename, jobname);
1749
} else if (S_ISREG (statbuf.st_mode)) {
1750
/* It's a file, we parse it */
1751
cfg_read_job (info->parent, filename, jobname);
1757
nih_free (filename);
1646
if (nih_dir_walk (dirname, S_IFREG, (NihFileFilter)NULL,
1647
(NihFileVisitor)cfg_visitor, NULL) < 0)
1656
* @parent: parent for new string,
1657
* @dirname: top-level directory being watched,
1658
* @path: full path to file.
1660
* Constructs a job name for a given file by removing @dirname from the
1663
* If @parent is not NULL, it should be a pointer to another allocated
1664
* block which will be used as the parent for this block. When @parent
1665
* is freed, the returned block will be freed too. If you have clean-up
1666
* that would need to be run, you can assign a destructor function using
1667
* the nih_alloc_set_destructor() function.
1669
* Returns: newly allocated job name or NULL if insufficient memory.
1672
cfg_job_name (const void *parent,
1673
const char *dirname,
1676
nih_assert (dirname != NULL);
1677
nih_assert (path != NULL);
1679
/* Remove dirname from the front */
1680
if (! strncmp (path, dirname, strlen (dirname)))
1681
path += strlen (dirname);
1683
/* Remove slashes */
1684
while (*path == '/')
1687
/* Construct job name */
1688
return nih_strdup (parent, path);
1692
* cfg_create_modify_handler:
1694
* @watch: NihWatch for directory tree,
1695
* @path: full path to file.
1697
* This function is called whenever a new job file is created in a directory
1698
* we're watching, or modified. We attempt to parse the file as a valid job;
1699
* though it's pretty common for these to fail since it's probably empty or
1700
* only partially written.
1703
cfg_create_modify_handler (void *data,
1709
nih_assert (watch != NULL);
1710
nih_assert (path != NULL);
1712
NIH_MUST (name = cfg_job_name (NULL, watch->path, path));
1714
cfg_read_job (NULL, path, name);
1720
* cfg_delete_handler:
1722
* @watch: NihWatch for directory tree,
1723
* @path: full path to file.
1725
* This function is called whenever a job file is deleted from a directory
1729
cfg_delete_handler (void *data,
1733
nih_assert (watch != NULL);
1734
nih_assert (path != NULL);
1736
nih_debug ("Delete of %s (ignored)", path);
1742
* @path: full path to file.
1744
* This function is called for each file under a configuration directory
1745
* whether or not we're watching it for changes; we parse the file to get
1746
* the initial set of jobs.
1748
* Returns: always zero.
1751
cfg_visitor (void *data,
1756
nih_assert (path != NULL);
1758
NIH_MUST (name = cfg_job_name (NULL, path, path));
1760
cfg_read_job (NULL, path, name);