Punt rc_ls_dir
This commit is contained in:
parent
efe6e76cc1
commit
05b8eff319
@ -12,6 +12,7 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
@ -90,8 +91,8 @@ static const char * const longopts_help[] = {
|
||||
|
||||
int env_update (int argc, char **argv)
|
||||
{
|
||||
char **files = rc_ls_dir (ENVDIR, 0);
|
||||
char *file;
|
||||
DIR *dp;
|
||||
struct dirent *d;
|
||||
char **envs = NULL;
|
||||
char *env;
|
||||
int i = 0;
|
||||
@ -108,6 +109,9 @@ int env_update (int argc, char **argv)
|
||||
bool ldconfig = true;
|
||||
bool fork_ldconfig = false;
|
||||
int nents = 0;
|
||||
char *path;
|
||||
char **entries = NULL;
|
||||
struct stat buf;
|
||||
|
||||
applet = argv[0];
|
||||
|
||||
@ -126,45 +130,50 @@ int env_update (int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (! files)
|
||||
eerrorx ("%s: no files in " ENVDIR " to process", applet);
|
||||
if (! (dp = opendir (ENVDIR)))
|
||||
eerrorx ("%s: opendir `" ENVDIR "': %s", applet, strerror (errno));
|
||||
|
||||
STRLIST_FOREACH (files, file, i) {
|
||||
char *path = rc_strcatpaths (ENVDIR, file, (char *) NULL);
|
||||
char **entries = NULL;
|
||||
struct stat buf;
|
||||
while ((d = readdir (dp))) {
|
||||
if (d->d_name[0] == '.')
|
||||
continue;
|
||||
|
||||
j = strlen (file);
|
||||
if (stat (file, &buf) == 0 && S_ISDIR (buf.st_mode) == 0 &&
|
||||
j = strlen (d->d_name);
|
||||
if (stat (d->d_name, &buf) == 0 && S_ISDIR (buf.st_mode) == 0 &&
|
||||
j > 2 &&
|
||||
*file >= '0' &&
|
||||
*file <= '9' &&
|
||||
*(file + 1) >= '0' &&
|
||||
*(file + 1) <= '9' &&
|
||||
*(file + j - 1) != '~' &&
|
||||
(j < 4 || strcmp (file + j - 4, ".bak") != 0) &&
|
||||
(j < 5 || strcmp (file + j - 5, ".core") != 0))
|
||||
d->d_name[0] >= '0' &&
|
||||
d->d_name[0] <= '9' &&
|
||||
d->d_name[1] >= '0' &&
|
||||
d->d_name[1] <= '9' &&
|
||||
d->d_name[j - 1] != '~' &&
|
||||
(j < 4 || strcmp (d->d_name + j - 4, ".bak") != 0) &&
|
||||
(j < 5 || strcmp (d->d_name + j - 5, ".core") != 0))
|
||||
{
|
||||
path = rc_strcatpaths (ENVDIR, d->d_name, (char *) NULL);
|
||||
entries = rc_config_load (path);
|
||||
free (path);
|
||||
free (path);
|
||||
|
||||
STRLIST_FOREACH (entries, entry, j) {
|
||||
char *tmpent = rc_xstrdup (entry);
|
||||
char *value = tmpent;
|
||||
char *var = strsep (&value, "=");
|
||||
STRLIST_FOREACH (entries, entry, j) {
|
||||
char *tmpent = rc_xstrdup (entry);
|
||||
char *value = tmpent;
|
||||
char *var = strsep (&value, "=");
|
||||
|
||||
if (strcmp (var, "COLON_SEPARATED") == 0)
|
||||
while ((var = strsep (&value, " ")))
|
||||
rc_strlist_addu (&mycolons, var);
|
||||
else if (strcmp (var, "SPACE_SEPARATED") == 0)
|
||||
while ((var = strsep (&value, " ")))
|
||||
rc_strlist_addu (&myspaces, var);
|
||||
else
|
||||
rc_strlist_add (&config, entry);
|
||||
free (tmpent);
|
||||
if (strcmp (var, "COLON_SEPARATED") == 0)
|
||||
while ((var = strsep (&value, " ")))
|
||||
rc_strlist_addu (&mycolons, var);
|
||||
else if (strcmp (var, "SPACE_SEPARATED") == 0)
|
||||
while ((var = strsep (&value, " ")))
|
||||
rc_strlist_addu (&myspaces, var);
|
||||
else
|
||||
rc_strlist_add (&config, entry);
|
||||
free (tmpent);
|
||||
}
|
||||
rc_strlist_free (entries);
|
||||
}
|
||||
|
||||
rc_strlist_free (entries);
|
||||
}
|
||||
closedir (dp);
|
||||
|
||||
if (! config)
|
||||
eerrorx ("%s: nothing to process", applet);
|
||||
|
||||
STRLIST_FOREACH (config, entry, i) {
|
||||
char *tmpent = rc_xstrdup (entry);
|
||||
@ -241,7 +250,6 @@ int env_update (int argc, char **argv)
|
||||
rc_strlist_free (mycolons);
|
||||
rc_strlist_free (myspaces);
|
||||
rc_strlist_free (config);
|
||||
rc_strlist_free (files);
|
||||
|
||||
if ((fp = fopen (PROFILE_ENV, "w")) == NULL)
|
||||
eerrorx ("%s: fopen `%s': %s", applet, PROFILE_ENV, strerror (errno));
|
||||
@ -288,11 +296,8 @@ int env_update (int argc, char **argv)
|
||||
return (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
while ((file = strsep (&ldent, ":"))) {
|
||||
if (strlen (file) == 0)
|
||||
continue;
|
||||
|
||||
if (rc_strlist_addu (&ldents, file))
|
||||
while ((env = strsep (&ldent, ":"))) {
|
||||
if (*env && rc_strlist_addu (&ldents, env))
|
||||
nents++;
|
||||
}
|
||||
|
||||
|
@ -289,9 +289,7 @@ bool rc_service_daemon_set (const char *service, const char *exec,
|
||||
{
|
||||
char *svc;
|
||||
char *dirpath;
|
||||
char **files = NULL;
|
||||
char *file;
|
||||
char *ffile = NULL;
|
||||
char *file = NULL;
|
||||
int i;
|
||||
char *mexec;
|
||||
char *mname;
|
||||
@ -299,6 +297,8 @@ bool rc_service_daemon_set (const char *service, const char *exec,
|
||||
int nfiles = 0;
|
||||
char *oldfile = NULL;
|
||||
bool retval = false;
|
||||
DIR *dp;
|
||||
struct dirent *d;
|
||||
|
||||
if (! exec && ! name && ! pidfile) {
|
||||
errno = EINVAL;
|
||||
@ -331,25 +331,30 @@ bool rc_service_daemon_set (const char *service, const char *exec,
|
||||
mpidfile = rc_xstrdup ("pidfile=");
|
||||
|
||||
/* Regardless, erase any existing daemon info */
|
||||
files = rc_ls_dir (dirpath, 0);
|
||||
STRLIST_FOREACH (files, file, i) {
|
||||
ffile = rc_strcatpaths (dirpath, file, (char *) NULL);
|
||||
nfiles++;
|
||||
if ((dp = opendir (dirpath))) {
|
||||
while ((d = readdir (dp))) {
|
||||
if (d->d_name[0] == '.')
|
||||
continue;
|
||||
file = rc_strcatpaths (dirpath, d->d_name, (char *) NULL);
|
||||
nfiles++;
|
||||
|
||||
if (! oldfile) {
|
||||
if (_match_daemon (dirpath, file, mexec, mname, mpidfile)) {
|
||||
unlink (ffile);
|
||||
oldfile = ffile;
|
||||
nfiles--;
|
||||
if (! oldfile) {
|
||||
if (_match_daemon (dirpath, d->d_name,
|
||||
mexec, mname, mpidfile))
|
||||
{
|
||||
unlink (file);
|
||||
oldfile = file;
|
||||
nfiles--;
|
||||
}
|
||||
} else {
|
||||
rename (file, oldfile);
|
||||
free (oldfile);
|
||||
oldfile = file;
|
||||
}
|
||||
} else {
|
||||
rename (ffile, oldfile);
|
||||
free (oldfile);
|
||||
oldfile = ffile;
|
||||
}
|
||||
free (file);
|
||||
closedir (dp);
|
||||
}
|
||||
free (ffile);
|
||||
rc_strlist_free (files);
|
||||
|
||||
/* Now store our daemon info */
|
||||
if (started) {
|
||||
@ -387,6 +392,8 @@ bool rc_service_started_daemon (const char *service, const char *exec,
|
||||
char *mexec;
|
||||
bool retval = false;
|
||||
char *svc;
|
||||
DIR *dp;
|
||||
struct dirent *d;
|
||||
|
||||
if (! service || ! exec)
|
||||
return (false);
|
||||
@ -407,13 +414,16 @@ bool rc_service_started_daemon (const char *service, const char *exec,
|
||||
retval = _match_daemon (dirpath, file, mexec, NULL, NULL);
|
||||
free (file);
|
||||
} else {
|
||||
char **files = rc_ls_dir (dirpath, 0);
|
||||
STRLIST_FOREACH (files, file, i) {
|
||||
retval = _match_daemon (dirpath, file, mexec, NULL, NULL);
|
||||
if (retval)
|
||||
break;
|
||||
if ((dp = opendir (dirpath))) {
|
||||
while ((d = readdir (dp))) {
|
||||
if (d->d_name[0] == ',')
|
||||
continue;
|
||||
retval = _match_daemon (dirpath, d->d_name, mexec, NULL, NULL);
|
||||
if (retval)
|
||||
break;
|
||||
}
|
||||
closedir (dp);
|
||||
}
|
||||
rc_strlist_free (files);
|
||||
}
|
||||
|
||||
free (dirpath);
|
||||
@ -425,10 +435,9 @@ librc_hidden_def(rc_service_started_daemon)
|
||||
bool rc_service_daemons_crashed (const char *service)
|
||||
{
|
||||
char *dirpath;
|
||||
char **files;
|
||||
char *file;
|
||||
DIR *dp;
|
||||
struct dirent *d;
|
||||
char *path;
|
||||
int i;
|
||||
FILE *fp;
|
||||
char buffer[RC_LINEBUFFER];
|
||||
char *exec = NULL;
|
||||
@ -449,10 +458,16 @@ bool rc_service_daemons_crashed (const char *service)
|
||||
(char *) NULL);
|
||||
free (svc);
|
||||
|
||||
if (! (dp = opendir (dirpath)))
|
||||
return (false);
|
||||
|
||||
memset (buffer, 0, sizeof (buffer));
|
||||
files = rc_ls_dir (dirpath, 0);
|
||||
STRLIST_FOREACH (files, file, i) {
|
||||
path = rc_strcatpaths (dirpath, file, (char *) NULL);
|
||||
|
||||
while ((d = readdir (dp))) {
|
||||
if (d->d_name[0] == '.')
|
||||
continue;
|
||||
|
||||
path = rc_strcatpaths (dirpath, d->d_name, (char *) NULL);
|
||||
fp = fopen (path, "r");
|
||||
free (path);
|
||||
if (! fp)
|
||||
@ -530,7 +545,7 @@ bool rc_service_daemons_crashed (const char *service)
|
||||
free (exec);
|
||||
free (name);
|
||||
free (dirpath);
|
||||
rc_strlist_free (files);
|
||||
closedir (dp);
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
@ -497,13 +497,13 @@ char **rc_deptree_order_services (rc_depinfo_t *deptree, const char *runlevel,
|
||||
strcmp (runlevel, RC_LEVEL_SHUTDOWN) == 0 ||
|
||||
strcmp (runlevel, RC_LEVEL_REBOOT) == 0)
|
||||
{
|
||||
list = rc_ls_dir (RC_SVCDIR_STARTING, RC_LS_INITD);
|
||||
list = rc_services_in_state (RC_SERVICE_STARTED);
|
||||
|
||||
tmp = rc_ls_dir (RC_SVCDIR_INACTIVE, RC_LS_INITD);
|
||||
tmp = rc_services_in_state (RC_SERVICE_INACTIVE);
|
||||
rc_strlist_join (&list, tmp);
|
||||
rc_strlist_free (tmp);
|
||||
|
||||
tmp = rc_ls_dir (RC_SVCDIR_INACTIVE, RC_LS_INITD);
|
||||
tmp = rc_services_in_state (RC_SERVICE_STARTING);
|
||||
rc_strlist_join (&list, tmp);
|
||||
rc_strlist_free (tmp);
|
||||
reverse = true;
|
||||
@ -511,18 +511,15 @@ char **rc_deptree_order_services (rc_depinfo_t *deptree, const char *runlevel,
|
||||
list = rc_services_in_runlevel (runlevel);
|
||||
|
||||
/* Add coldplugged services */
|
||||
tmp = rc_ls_dir (RC_SVCDIR_COLDPLUGGED, RC_LS_INITD);
|
||||
tmp = rc_services_in_state (RC_SERVICE_COLDPLUGGED);
|
||||
rc_strlist_join (&list, tmp);
|
||||
rc_strlist_free (tmp);
|
||||
|
||||
/* If we're not the boot runlevel then add that too */
|
||||
if (strcmp (runlevel, bootlevel) != 0) {
|
||||
char *path = rc_strcatpaths (RC_RUNLEVELDIR, bootlevel,
|
||||
(char *) NULL);
|
||||
tmp = rc_ls_dir (path, RC_LS_INITD);
|
||||
tmp = rc_services_in_runlevel (bootlevel);
|
||||
rc_strlist_join (&list, tmp);
|
||||
rc_strlist_free (tmp);
|
||||
free (path);
|
||||
}
|
||||
}
|
||||
|
||||
@ -547,10 +544,10 @@ static bool is_newer_than (const char *file, const char *target)
|
||||
{
|
||||
struct stat buf;
|
||||
time_t mtime;
|
||||
char **targets;
|
||||
char *t;
|
||||
int i;
|
||||
bool newer = true;
|
||||
DIR *dp;
|
||||
struct dirent *d;
|
||||
char *path;
|
||||
|
||||
if (stat (file, &buf) != 0 || buf.st_size == 0)
|
||||
return (false);
|
||||
@ -564,16 +561,21 @@ static bool is_newer_than (const char *file, const char *target)
|
||||
if (mtime < buf.st_mtime)
|
||||
return (false);
|
||||
|
||||
targets = rc_ls_dir (target, 0);
|
||||
STRLIST_FOREACH (targets, t, i)
|
||||
{
|
||||
char *path = rc_strcatpaths (target, t, (char *) NULL);
|
||||
if (! (dp = opendir (target)))
|
||||
return (true);
|
||||
|
||||
while ((d = readdir (dp))) {
|
||||
if (d->d_name[0] == '.')
|
||||
continue;
|
||||
|
||||
path = rc_strcatpaths (target, d->d_name, (char *) NULL);
|
||||
newer = is_newer_than (file, path);
|
||||
free (path);
|
||||
if (! newer)
|
||||
break;
|
||||
}
|
||||
rc_strlist_free (targets);
|
||||
closedir (dp);
|
||||
|
||||
return (newer);
|
||||
}
|
||||
|
||||
|
@ -94,47 +94,6 @@ char *rc_strcatpaths (const char *path1, const char *paths, ...)
|
||||
}
|
||||
librc_hidden_def(rc_strcatpaths)
|
||||
|
||||
char **rc_ls_dir (const char *dir, int options)
|
||||
{
|
||||
DIR *dp;
|
||||
struct dirent *d;
|
||||
char **list = NULL;
|
||||
|
||||
if ((dp = opendir (dir)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
errno = 0;
|
||||
while (((d = readdir (dp)) != NULL) && errno == 0) {
|
||||
if (d->d_name[0] != '.') {
|
||||
if (options & RC_LS_INITD) {
|
||||
int l = strlen (d->d_name);
|
||||
char *init = rc_strcatpaths (RC_INITDIR, d->d_name,
|
||||
(char *) NULL);
|
||||
bool ok = rc_exists (init);
|
||||
free (init);
|
||||
if (! ok)
|
||||
continue;
|
||||
|
||||
/* .sh files are not init scripts */
|
||||
if (l > 2 && d->d_name[l - 3] == '.' &&
|
||||
d->d_name[l - 2] == 's' &&
|
||||
d->d_name[l - 1] == 'h')
|
||||
continue;
|
||||
}
|
||||
if (options & RC_LS_DIR) {
|
||||
struct stat buf;
|
||||
|
||||
if (stat (d->d_name, &buf) == 0 && ! S_ISDIR (buf.st_mode))
|
||||
continue;
|
||||
}
|
||||
rc_strlist_addsort (&list, d->d_name);
|
||||
}
|
||||
}
|
||||
closedir (dp);
|
||||
|
||||
return (list);
|
||||
}
|
||||
librc_hidden_def(rc_ls_dir)
|
||||
|
||||
bool rc_rm_dir (const char *pathname, bool top)
|
||||
{
|
||||
|
62
src/librc.c
62
src/librc.c
@ -42,6 +42,50 @@ static const rc_service_state_name_t rc_service_state_names[] = {
|
||||
{ 0, NULL}
|
||||
};
|
||||
|
||||
|
||||
#define LS_INITD 0x01
|
||||
#define LS_DIR 0x02
|
||||
static char **ls_dir (const char *dir, int options)
|
||||
{
|
||||
DIR *dp;
|
||||
struct dirent *d;
|
||||
char **list = NULL;
|
||||
|
||||
if ((dp = opendir (dir)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
errno = 0;
|
||||
while (((d = readdir (dp)) != NULL) && errno == 0) {
|
||||
if (d->d_name[0] != '.') {
|
||||
if (options & LS_INITD) {
|
||||
int l = strlen (d->d_name);
|
||||
char *init = rc_strcatpaths (RC_INITDIR, d->d_name,
|
||||
(char *) NULL);
|
||||
bool ok = rc_exists (init);
|
||||
free (init);
|
||||
if (! ok)
|
||||
continue;
|
||||
|
||||
/* .sh files are not init scripts */
|
||||
if (l > 2 && d->d_name[l - 3] == '.' &&
|
||||
d->d_name[l - 2] == 's' &&
|
||||
d->d_name[l - 1] == 'h')
|
||||
continue;
|
||||
}
|
||||
if (options & LS_DIR) {
|
||||
struct stat buf;
|
||||
|
||||
if (stat (d->d_name, &buf) == 0 && ! S_ISDIR (buf.st_mode))
|
||||
continue;
|
||||
}
|
||||
rc_strlist_addsort (&list, d->d_name);
|
||||
}
|
||||
}
|
||||
closedir (dp);
|
||||
|
||||
return (list);
|
||||
}
|
||||
|
||||
static const char *rc_parse_service_state (rc_service_state_t state)
|
||||
{
|
||||
int i;
|
||||
@ -68,7 +112,7 @@ librc_hidden_def(rc_runlevel_stopping)
|
||||
|
||||
char **rc_runlevel_list (void)
|
||||
{
|
||||
return (rc_ls_dir (RC_RUNLEVELDIR, RC_LS_DIR));
|
||||
return (ls_dir (RC_RUNLEVELDIR, LS_DIR));
|
||||
}
|
||||
librc_hidden_def(rc_runlevel_list)
|
||||
|
||||
@ -376,7 +420,7 @@ bool rc_service_mark (const char *service, const rc_service_state_t state)
|
||||
/* These are final states, so remove us from scheduled */
|
||||
if (state == RC_SERVICE_STARTED || state == RC_SERVICE_STOPPED) {
|
||||
char *sdir = rc_strcatpaths (RC_SVCDIR, "scheduled", (char *) NULL);
|
||||
char **dirs = rc_ls_dir (sdir, 0);
|
||||
char **dirs = ls_dir (sdir, 0);
|
||||
char *dir;
|
||||
int serrno;
|
||||
|
||||
@ -657,7 +701,7 @@ char **rc_services_in_runlevel (const char *runlevel)
|
||||
char **list = NULL;
|
||||
|
||||
if (! runlevel)
|
||||
return (rc_ls_dir (RC_INITDIR, RC_LS_INITD));
|
||||
return (ls_dir (RC_INITDIR, LS_INITD));
|
||||
|
||||
/* These special levels never contain any services */
|
||||
if (strcmp (runlevel, RC_LEVEL_SYSINIT) == 0 ||
|
||||
@ -665,7 +709,7 @@ char **rc_services_in_runlevel (const char *runlevel)
|
||||
return (NULL);
|
||||
|
||||
dir = rc_strcatpaths (RC_RUNLEVELDIR, runlevel, (char *) NULL);
|
||||
list = rc_ls_dir (dir, RC_LS_INITD);
|
||||
list = ls_dir (dir, LS_INITD);
|
||||
free (dir);
|
||||
return (list);
|
||||
}
|
||||
@ -678,13 +722,13 @@ char **rc_services_in_state (rc_service_state_t state)
|
||||
char **list = NULL;
|
||||
|
||||
if (state == RC_SERVICE_SCHEDULED) {
|
||||
char **dirs = rc_ls_dir (dir, 0);
|
||||
char **dirs = ls_dir (dir, 0);
|
||||
char *d;
|
||||
int i;
|
||||
|
||||
STRLIST_FOREACH (dirs, d, i) {
|
||||
char *p = rc_strcatpaths (dir, d, (char *) NULL);
|
||||
char **entries = rc_ls_dir (p, RC_LS_INITD);
|
||||
char **entries = ls_dir (p, LS_INITD);
|
||||
char *e;
|
||||
int j;
|
||||
|
||||
@ -698,7 +742,7 @@ char **rc_services_in_state (rc_service_state_t state)
|
||||
if (dirs)
|
||||
free (dirs);
|
||||
} else {
|
||||
list = rc_ls_dir (dir, RC_LS_INITD);
|
||||
list = ls_dir (dir, LS_INITD);
|
||||
}
|
||||
|
||||
free (dir);
|
||||
@ -758,7 +802,7 @@ librc_hidden_def(rc_service_delete)
|
||||
|
||||
char **rc_services_scheduled_by (const char *service)
|
||||
{
|
||||
char **dirs = rc_ls_dir (RC_SVCDIR "/scheduled", 0);
|
||||
char **dirs = ls_dir (RC_SVCDIR "/scheduled", 0);
|
||||
char **list = NULL;
|
||||
char *dir;
|
||||
int i;
|
||||
@ -784,7 +828,7 @@ char **rc_services_scheduled (const char *service)
|
||||
char **list = NULL;
|
||||
|
||||
free (svc);
|
||||
list = rc_ls_dir (dir, RC_LS_INITD);
|
||||
list = ls_dir (dir, LS_INITD);
|
||||
free (dir);
|
||||
return (list);
|
||||
}
|
||||
|
@ -65,7 +65,6 @@ librc_hidden_proto(rc_env_config)
|
||||
librc_hidden_proto(rc_env_filter)
|
||||
librc_hidden_proto(rc_exists)
|
||||
librc_hidden_proto(rc_find_pids)
|
||||
librc_hidden_proto(rc_ls_dir)
|
||||
librc_hidden_proto(rc_rm_dir)
|
||||
librc_hidden_proto(rc_runlevel_exists)
|
||||
librc_hidden_proto(rc_runlevel_get)
|
||||
|
@ -29,7 +29,7 @@ rc_depinfo_t *_rc_deptree_load (void) {
|
||||
|
||||
ebegin ("Caching service dependencies");
|
||||
retval = rc_deptree_update ();
|
||||
eend (retval, "Failed to update the dependency tree");
|
||||
eend (retval ? 0 : -1, "Failed to update the dependency tree");
|
||||
}
|
||||
|
||||
return (rc_deptree_load ());
|
||||
|
@ -5,6 +5,7 @@
|
||||
Released under the GPLv2
|
||||
*/
|
||||
|
||||
#include <dirent.h>
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
@ -49,10 +50,12 @@ dlfunc_t dlfunc (void * __restrict handle, const char * __restrict symbol)
|
||||
|
||||
void rc_plugin_load (void)
|
||||
{
|
||||
char **files;
|
||||
char *file;
|
||||
int i;
|
||||
DIR *dp;
|
||||
struct dirent *d;
|
||||
plugin_t *plugin = plugins;
|
||||
char *p;
|
||||
void *h;
|
||||
int (*fptr) (rc_hook_t, const char *);
|
||||
|
||||
/* Don't load plugins if we're in one */
|
||||
if (rc_in_plugin)
|
||||
@ -61,15 +64,15 @@ void rc_plugin_load (void)
|
||||
/* Ensure some sanity here */
|
||||
rc_plugin_unload ();
|
||||
|
||||
if (! rc_exists (RC_PLUGINDIR))
|
||||
if (! (dp = opendir (RC_PLUGINDIR)))
|
||||
return;
|
||||
|
||||
files = rc_ls_dir (RC_PLUGINDIR, 0);
|
||||
STRLIST_FOREACH (files, file, i) {
|
||||
char *p = rc_strcatpaths (RC_PLUGINDIR, file, NULL);
|
||||
void *h = dlopen (p, RTLD_LAZY);
|
||||
int (*fptr) (rc_hook_t, const char *);
|
||||
while ((d = readdir (dp))) {
|
||||
if (d->d_name[0] == '.')
|
||||
continue;
|
||||
|
||||
p = rc_strcatpaths (RC_PLUGINDIR, d->d_name, NULL);
|
||||
h = dlopen (p, RTLD_LAZY);
|
||||
free (p);
|
||||
if (! h) {
|
||||
eerror ("dlopen: %s", dlerror ());
|
||||
@ -78,7 +81,7 @@ void rc_plugin_load (void)
|
||||
|
||||
fptr = (int (*)(rc_hook_t, const char*)) dlfunc (h, RC_PLUGIN_HOOK);
|
||||
if (! fptr) {
|
||||
eerror ("%s: cannot find symbol `%s'", file, RC_PLUGIN_HOOK);
|
||||
eerror ("%s: cannot find symbol `%s'", d->d_name, RC_PLUGIN_HOOK);
|
||||
dlclose (h);
|
||||
} else {
|
||||
if (plugin) {
|
||||
@ -88,13 +91,12 @@ void rc_plugin_load (void)
|
||||
plugin = plugins = rc_xmalloc (sizeof (plugin_t));
|
||||
|
||||
memset (plugin, 0, sizeof (plugin_t));
|
||||
plugin->name = rc_xstrdup (file);
|
||||
plugin->name = rc_xstrdup (d->d_name);
|
||||
plugin->handle = h;
|
||||
plugin->hook = fptr;
|
||||
}
|
||||
}
|
||||
|
||||
rc_strlist_free (files);
|
||||
closedir (dp);
|
||||
}
|
||||
|
||||
void rc_plugin_run (rc_hook_t hook, const char *value)
|
||||
|
100
src/rc.c
100
src/rc.c
@ -20,6 +20,7 @@
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/wait.h>
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
#include <ctype.h>
|
||||
#include <getopt.h>
|
||||
#include <libgen.h>
|
||||
@ -331,7 +332,7 @@ static int do_mark_service (int argc, char **argv)
|
||||
eerror ("%s: failed to signal parent %d: %s",
|
||||
applet, pid, strerror (errno));
|
||||
|
||||
/* Remove the exclsive time test. This ensures that it's not
|
||||
/* Remove the exclusive time test. This ensures that it's not
|
||||
in control as well */
|
||||
l = strlen (RC_SVCDIR "exclusive") +
|
||||
strlen (svcname) +
|
||||
@ -420,7 +421,7 @@ static char read_key (bool block)
|
||||
struct termios termios;
|
||||
char c = 0;
|
||||
int fd = fileno (stdin);
|
||||
|
||||
|
||||
if (! isatty (fd))
|
||||
return (false);
|
||||
|
||||
@ -736,6 +737,8 @@ int main (int argc, char **argv)
|
||||
char ksoftbuffer [PATH_MAX];
|
||||
char pidstr[6];
|
||||
int opt;
|
||||
DIR *dp;
|
||||
struct dirent *d;
|
||||
|
||||
atexit (cleanup);
|
||||
if (argv[0])
|
||||
@ -1032,18 +1035,14 @@ int main (int argc, char **argv)
|
||||
its coldplugging thing. runscript knows when we're not ready so it
|
||||
stores a list of coldplugged services in DEVBOOT for us to pick up
|
||||
here when we are ready for them */
|
||||
start_services = rc_ls_dir (DEVBOOT, RC_LS_INITD);
|
||||
if (start_services) {
|
||||
if ((dp = opendir (DEVBOOT))) {
|
||||
while ((d = readdir (dp))) {
|
||||
if (rc_service_exists (d->d_name) &&
|
||||
rc_service_plugable (d->d_name))
|
||||
rc_service_mark (d->d_name, RC_SERVICE_COLDPLUGGED);
|
||||
}
|
||||
closedir (dp);
|
||||
rc_rm_dir (DEVBOOT, true);
|
||||
|
||||
STRLIST_FOREACH (start_services, service, i)
|
||||
if (rc_service_plugable (service))
|
||||
rc_service_mark (service, RC_SERVICE_COLDPLUGGED);
|
||||
/* We need to dump this list now.
|
||||
This may seem redunant, but only Linux needs this and saves on
|
||||
code bloat. */
|
||||
rc_strlist_free (start_services);
|
||||
start_services = NULL;
|
||||
}
|
||||
#else
|
||||
/* BSD's on the other hand populate /dev automagically and use devd.
|
||||
@ -1057,50 +1056,52 @@ int main (int argc, char **argv)
|
||||
{
|
||||
#if defined(__DragonFly__) || defined(__FreeBSD__)
|
||||
/* The net interfaces are easy - they're all in net /dev/net :) */
|
||||
start_services = rc_ls_dir ("/dev/net", 0);
|
||||
STRLIST_FOREACH (start_services, service, i) {
|
||||
j = (strlen ("net.") + strlen (service) + 1);
|
||||
tmp = rc_xmalloc (sizeof (char *) * j);
|
||||
snprintf (tmp, j, "net.%s", service);
|
||||
if (rc_service_exists (tmp) && rc_service_plugable (tmp))
|
||||
rc_service_mark (tmp, RC_SERVICE_COLDPLUGGED);
|
||||
CHAR_FREE (tmp);
|
||||
if ((dp = opendir ("/dev/net"))) {
|
||||
while ((d = readdir (dp))) {
|
||||
i = (strlen ("net.") + strlen (d->d_name) + 1);
|
||||
tmp = rc_xmalloc (sizeof (char *) * i);
|
||||
snprintf (tmp, i, "net.%s", d->d_name);
|
||||
if (rc_service_exists (d->d_name) &&
|
||||
rc_service_plugable (d->d_name))
|
||||
rc_service_mark (d->d_name, RC_SERVICE_COLDPLUGGED);
|
||||
CHAR_FREE (tmp);
|
||||
}
|
||||
closedir (dp);
|
||||
}
|
||||
rc_strlist_free (start_services);
|
||||
#endif
|
||||
|
||||
/* The mice are a little more tricky.
|
||||
If we coldplug anything else, we'll probably do it here. */
|
||||
start_services = rc_ls_dir ("/dev", 0);
|
||||
STRLIST_FOREACH (start_services, service, i) {
|
||||
if (strncmp (service, "psm", 3) == 0 ||
|
||||
strncmp (service, "ums", 3) == 0)
|
||||
{
|
||||
char *p = service + 3;
|
||||
if (p && isdigit (*p)) {
|
||||
j = (strlen ("moused.") + strlen (service) + 1);
|
||||
tmp = rc_xmalloc (sizeof (char *) * j);
|
||||
snprintf (tmp, j, "moused.%s", service);
|
||||
if (rc_service_exists (tmp) && rc_service_plugable (tmp))
|
||||
rc_service_mark (tmp, RC_SERVICE_COLDPLUGGED);
|
||||
CHAR_FREE (tmp);
|
||||
if ((dp == opendir ("/dev"))) {
|
||||
while ((d = readdir (dp))) {
|
||||
if (strncmp (d->d_name, "psm", 3) == 0 ||
|
||||
strncmp (d->d_name, "ums", 3) == 0)
|
||||
{
|
||||
char *p = d->d_name + 3;
|
||||
if (p && isdigit (*p)) {
|
||||
i = (strlen ("moused.") + strlen (d->d_name) + 1);
|
||||
tmp = rc_xmalloc (sizeof (char *) * i);
|
||||
snprintf (tmp, i, "moused.%s", d->d_name);
|
||||
if (rc_service_exists (tmp) && rc_service_plugable (tmp))
|
||||
rc_service_mark (tmp, RC_SERVICE_COLDPLUGGED);
|
||||
CHAR_FREE (tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir (dp);
|
||||
}
|
||||
rc_strlist_free (start_services);
|
||||
start_services = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Build a list of all services to stop and then work out the
|
||||
correct order for stopping them */
|
||||
stop_services = rc_ls_dir (RC_SVCDIR_STARTING, RC_LS_INITD);
|
||||
|
||||
tmplist = rc_ls_dir (RC_SVCDIR_INACTIVE, RC_LS_INITD);
|
||||
stop_services = rc_services_in_state (RC_SERVICE_STARTING);
|
||||
|
||||
tmplist = rc_services_in_state (RC_SERVICE_INACTIVE);
|
||||
rc_strlist_join (&stop_services, tmplist);
|
||||
rc_strlist_free (tmplist);
|
||||
|
||||
tmplist = rc_ls_dir (RC_SVCDIR_STARTED, RC_LS_INITD);
|
||||
tmplist = rc_services_in_state (RC_SERVICE_STARTED);
|
||||
rc_strlist_join (&stop_services, tmplist);
|
||||
rc_strlist_free (tmplist);
|
||||
|
||||
@ -1110,7 +1111,7 @@ int main (int argc, char **argv)
|
||||
rc_strlist_add (&types, "iafter");
|
||||
|
||||
deporder = rc_deptree_depends (deptree, types, stop_services,
|
||||
runlevel, depoptions | RC_DEP_STOP);
|
||||
runlevel, depoptions | RC_DEP_STOP);
|
||||
|
||||
rc_strlist_free (stop_services);
|
||||
rc_strlist_free (types);
|
||||
@ -1120,7 +1121,7 @@ int main (int argc, char **argv)
|
||||
rc_strlist_reverse (stop_services);
|
||||
|
||||
/* Load our list of coldplugged services */
|
||||
coldplugged_services = rc_ls_dir (RC_SVCDIR_COLDPLUGGED, RC_LS_INITD);
|
||||
coldplugged_services = rc_services_in_state (RC_SERVICE_COLDPLUGGED);
|
||||
|
||||
/* Load our start services now.
|
||||
We have different rules dependent on runlevel. */
|
||||
@ -1133,15 +1134,12 @@ int main (int argc, char **argv)
|
||||
}
|
||||
printf ("\n");
|
||||
}
|
||||
tmp = rc_strcatpaths (RC_RUNLEVELDIR, newlevel ? newlevel : runlevel,
|
||||
(char *) NULL);
|
||||
tmplist = rc_ls_dir (tmp, RC_LS_INITD);
|
||||
tmplist = rc_services_in_runlevel (newlevel ? newlevel : runlevel);
|
||||
rc_strlist_join (&start_services, tmplist);
|
||||
rc_strlist_free (tmplist);
|
||||
CHAR_FREE (tmp);
|
||||
} else {
|
||||
/* Store our list of coldplugged services */
|
||||
tmplist = rc_ls_dir (RC_SVCDIR_COLDPLUGGED, RC_LS_INITD);
|
||||
tmplist = rc_services_in_state (RC_SERVICE_COLDPLUGGED);
|
||||
rc_strlist_join (&coldplugged_services, tmplist);
|
||||
rc_strlist_free (tmplist);
|
||||
if (strcmp (newlevel ? newlevel : runlevel, RC_LEVEL_SINGLE) != 0 &&
|
||||
@ -1155,7 +1153,7 @@ int main (int argc, char **argv)
|
||||
tmplist = rc_services_in_runlevel (newlevel ? newlevel : runlevel);
|
||||
rc_strlist_join (&start_services, tmplist);
|
||||
rc_strlist_free (tmplist);
|
||||
|
||||
|
||||
STRLIST_FOREACH (coldplugged_services, service, i)
|
||||
rc_strlist_add (&start_services, service);
|
||||
|
||||
@ -1229,7 +1227,7 @@ int main (int argc, char **argv)
|
||||
going to be started depends on us */
|
||||
rc_strlist_add (&stopdeps, service);
|
||||
deporder = rc_deptree_depends (deptree, types, stopdeps,
|
||||
runlevel, RC_DEP_STRICT);
|
||||
runlevel, RC_DEP_STRICT);
|
||||
rc_strlist_free (stopdeps);
|
||||
stopdeps = NULL;
|
||||
found = false;
|
||||
@ -1299,7 +1297,7 @@ int main (int argc, char **argv)
|
||||
rc_strlist_add (&types, "iuse");
|
||||
rc_strlist_add (&types, "iafter");
|
||||
deporder = rc_deptree_depends (deptree, types, start_services,
|
||||
runlevel, depoptions | RC_DEP_START);
|
||||
runlevel, depoptions | RC_DEP_START);
|
||||
rc_strlist_free (types);
|
||||
types = NULL;
|
||||
rc_strlist_free (start_services);
|
||||
|
11
src/rc.h
11
src/rc.h
@ -438,17 +438,6 @@ char *rc_strcatpaths (const char *path1, const char *paths, ...) SENTINEL;
|
||||
* @return true if it matches true, yes or 1, false if otherwise. */
|
||||
bool rc_env_bool (const char *variable);
|
||||
|
||||
/*! @name rc_ls_dir options */
|
||||
/*! Ensure that an init.d service exists for each file returned */
|
||||
#define RC_LS_INITD 0x01
|
||||
#define RC_LS_DIR 0x02
|
||||
|
||||
/*! Return a NULL terminted sorted list of the contents of the directory
|
||||
* @param dir to list
|
||||
* @param options any options to apply
|
||||
* @return NULL terminated list */
|
||||
char **rc_ls_dir (const char *dir, int options);
|
||||
|
||||
/*! Remove a directory
|
||||
* @param pathname to remove
|
||||
* @param top remove the top level directory too
|
||||
|
@ -14,7 +14,6 @@ global:
|
||||
rc_env_filter;
|
||||
rc_environ_fd;
|
||||
rc_find_pids;
|
||||
rc_ls_dir;
|
||||
rc_rm_dir;
|
||||
rc_runlevel_exists;
|
||||
rc_runlevel_get;
|
||||
|
Loading…
Reference in New Issue
Block a user