summaryrefslogtreecommitdiff
path: root/src/librc/librc.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2008-03-16 17:00:56 +0000
committerRoy Marples <roy@marples.name>2008-03-16 17:00:56 +0000
commitcb9da6a262b60255cd037f20b4cde3ab2c8a1e6a (patch)
treec5c57d5adedf009fdb02b53677e2cdf940bdb47c /src/librc/librc.c
parent40e12f6ba026af9c24d5c3d8e36512719ed5faee (diff)
downloadopenrc-cb9da6a262b60255cd037f20b4cde3ab2c8a1e6a.tar.gz
openrc-cb9da6a262b60255cd037f20b4cde3ab2c8a1e6a.tar.bz2
openrc-cb9da6a262b60255cd037f20b4cde3ab2c8a1e6a.tar.xz
Remove null terminated char ** lists in favour of RC_STRINGLIST, using TAILQ from queue(3). Refactor code style around the BSD KNF.
Diffstat (limited to 'src/librc/librc.c')
-rw-r--r--src/librc/librc.c843
1 files changed, 428 insertions, 415 deletions
diff --git a/src/librc/librc.c b/src/librc/librc.c
index 7344e37..301a388 100644
--- a/src/librc/librc.c
+++ b/src/librc/librc.c
@@ -47,7 +47,7 @@ const char librc_copyright[] = "Copyright (c) 2007-2008 Roy Marples";
FILE *rc_environ_fd = NULL;
typedef struct rc_service_state_name {
- rc_service_state_t state;
+ RC_SERVICE state;
const char *name;
} rc_service_state_name_t;
@@ -68,49 +68,53 @@ static const rc_service_state_name_t rc_service_state_names[] = {
#define LS_INITD 0x01
#define LS_DIR 0x02
-static char **ls_dir (const char *dir, int options)
+static RC_STRINGLIST *ls_dir(const char *dir, int options)
{
DIR *dp;
struct dirent *d;
- char **list = NULL;
+ RC_STRINGLIST *list;
struct stat buf;
+ size_t l;
+ char *file;
+ int r;
- if ((dp = opendir (dir)) == NULL)
- return (NULL);
+ if ((dp = opendir(dir)) == NULL)
+ return NULL;
- while (((d = readdir (dp)) != NULL)) {
+ list = rc_stringlist_new();
+ while (((d = readdir(dp)) != NULL)) {
if (d->d_name[0] != '.') {
if (options & LS_INITD) {
- int l = strlen (d->d_name);
-
/* Check that our file really exists.
* This is important as a service maybe in a runlevel, but
* could also have been removed. */
- char *file = rc_strcatpaths (dir, d->d_name, NULL);
- int ok = stat (file, &buf);
- free (file);
- if (ok != 0)
+ file = rc_strcatpaths(dir, d->d_name, NULL);
+ r = stat(file, &buf);
+ free(file);
+ if (r != 0)
continue;
/* .sh files are not init scripts */
+ l = strlen(d->d_name);
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) {
- if (stat (d->d_name, &buf) == 0 && ! S_ISDIR (buf.st_mode))
+ if (stat(d->d_name, &buf) == 0 &&
+ ! S_ISDIR(buf.st_mode))
continue;
}
- rc_strlist_addsort (&list, d->d_name);
+ rc_stringlist_add(list, d->d_name);
}
}
- closedir (dp);
+ closedir(dp);
- return (list);
+ return list;
}
-static bool rm_dir (const char *pathname, bool top)
+static bool rm_dir(const char *pathname, bool top)
{
DIR *dp;
struct dirent *d;
@@ -118,49 +122,49 @@ static bool rm_dir (const char *pathname, bool top)
struct stat s;
bool retval = true;
- if ((dp = opendir (pathname)) == NULL)
- return (false);
+ if ((dp = opendir(pathname)) == NULL)
+ return false;
errno = 0;
- while (((d = readdir (dp)) != NULL) && errno == 0) {
- if (strcmp (d->d_name, ".") != 0 && strcmp (d->d_name, "..") != 0) {
- free (tmp);
- tmp = rc_strcatpaths (pathname, d->d_name, (char *) NULL);
+ while (((d = readdir(dp)) != NULL) && errno == 0) {
+ if (strcmp(d->d_name, ".") != 0 && strcmp(d->d_name, "..") != 0) {
+ free(tmp);
+ tmp = rc_strcatpaths(pathname, d->d_name, (char *) NULL);
- if (stat (tmp, &s) != 0) {
+ if (stat(tmp, &s) != 0) {
retval = false;
break;
}
- if (S_ISDIR (s.st_mode)) {
- if (! rm_dir (tmp, true))
+ if (S_ISDIR(s.st_mode)) {
+ if (! rm_dir(tmp, true))
{
retval = false;
break;
}
} else {
- if (unlink (tmp)) {
+ if (unlink(tmp)) {
retval = false;
break;
}
}
}
}
- closedir (dp);
- free (tmp);
+ closedir(dp);
+ free(tmp);
if (! retval)
- return (false);
+ return false;
- if (top && rmdir (pathname) != 0)
- return (false);
+ if (top && rmdir(pathname) != 0)
+ return false;
- return (true);
+ return true;
}
/* Other systems may need this at some point, but for now it's Linux only */
#ifdef __linux__
-static bool file_regex (const char *file, const char *regex)
+static bool file_regex(const char *file, const char *regex)
{
FILE *fp;
char *line;
@@ -168,153 +172,153 @@ static bool file_regex (const char *file, const char *regex)
bool retval = false;
int result;
- if (! (fp = fopen (file, "r")))
- return (false);
+ if (! (fp = fopen(file, "r")))
+ return false;
- if ((result = regcomp (&re, regex, REG_EXTENDED | REG_NOSUB)) != 0) {
- fclose (fp);
- line = xmalloc (sizeof (char) * BUFSIZ);
- regerror (result, &re, line, BUFSIZ);
- fprintf (stderr, "file_regex: %s", line);
- free (line);
- return (false);
+ if ((result = regcomp(&re, regex, REG_EXTENDED | REG_NOSUB)) != 0) {
+ fclose(fp);
+ line = xmalloc(sizeof (char) * BUFSIZ);
+ regerror(result, &re, line, BUFSIZ);
+ fprintf(stderr, "file_regex: %s", line);
+ free(line);
+ return false;
}
- while ((line = rc_getline (fp))) {
- if (regexec (&re, line, 0, NULL, 0) == 0)
+ while ((line = rc_getline(fp))) {
+ if (regexec(&re, line, 0, NULL, 0) == 0)
retval = true;
- free (line);
+ free(line);
if (retval)
break;
}
- fclose (fp);
- regfree (&re);
+ fclose(fp);
+ regfree(&re);
- return (retval);
+ return retval;
}
#endif
-const char *rc_sys (void)
+const char *rc_sys(void)
{
#ifdef PREFIX
- return (RC_SYS_PREFIX);
+ return RC_SYS_PREFIX;
#else
#ifdef __FreeBSD__
int jailed = 0;
- size_t len = sizeof (jailed);
+ size_t len = sizeof(jailed);
- if (sysctlbyname ("security.jail.jailed", &jailed, &len, NULL, 0) == 0)
+ if (sysctlbyname("security.jail.jailed", &jailed, &len, NULL, 0) == 0)
if (jailed == 1)
- return (RC_SYS_JAIL);
+ return RC_SYS_JAIL;
#endif
#ifdef __linux__
- if (exists ("/proc/xen")) {
- if (file_regex ("/proc/xen/capabilities", "control_d"))
- return (RC_SYS_XEN0);
- return (RC_SYS_XENU);
- } else if (file_regex ("/proc/cpuinfo", "UML"))
- return (RC_SYS_UML);
- else if (file_regex ("/proc/self/status",
- "(s_context|VxID):[[:space:]]*[1-9]"))
- return (RC_SYS_VSERVER);
- else if (file_regex ("/proc/self/status",
- "envID:[[:space:]]*[1-9]"))
- return (RC_SYS_OPENVZ);
+ if (exists("/proc/xen")) {
+ if (file_regex("/proc/xen/capabilities", "control_d"))
+ return RC_SYS_XEN0;
+ return RC_SYS_XENU;
+ } else if (file_regex("/proc/cpuinfo", "UML"))
+ return RC_SYS_UML;
+ else if (file_regex("/proc/self/status",
+ "(s_context|VxID):[[:space:]]*[1-9]"))
+ return RC_SYS_VSERVER;
+ else if (file_regex("/proc/self/status",
+ "envID:[[:space:]]*[1-9]"))
+ return RC_SYS_OPENVZ;
#endif
- return (NULL);
+ return NULL;
#endif /* PREFIX */
}
-static const char *rc_parse_service_state (rc_service_state_t state)
+static const char *rc_parse_service_state(RC_SERVICE state)
{
int i;
for (i = 0; rc_service_state_names[i].name; i++) {
if (rc_service_state_names[i].state == state)
- return (rc_service_state_names[i].name);
+ return rc_service_state_names[i].name;
}
- return (NULL);
+ return NULL;
}
-bool rc_runlevel_starting (void)
+bool rc_runlevel_starting(void)
{
- return (exists (RC_STARTING));
+ return exists(RC_STARTING);
}
librc_hidden_def(rc_runlevel_starting)
-bool rc_runlevel_stopping (void)
+bool rc_runlevel_stopping(void)
{
- return (exists (RC_STOPPING));
+ return exists(RC_STOPPING);
}
librc_hidden_def(rc_runlevel_stopping)
-char **rc_runlevel_list (void)
+RC_STRINGLIST *rc_runlevel_list(void)
{
- return (ls_dir (RC_RUNLEVELDIR, LS_DIR));
+ return ls_dir(RC_RUNLEVELDIR, LS_DIR);
}
librc_hidden_def(rc_runlevel_list)
-char *rc_runlevel_get (void)
+char *rc_runlevel_get(void)
{
FILE *fp;
char *runlevel = NULL;
- if ((fp = fopen (SOFTLEVEL, "r"))) {
- runlevel = xmalloc (sizeof (char) * PATH_MAX);
- if (fgets (runlevel, PATH_MAX, fp)) {
- int i = strlen (runlevel) - 1;
+ if ((fp = fopen(SOFTLEVEL, "r"))) {
+ runlevel = xmalloc(sizeof(char) * PATH_MAX);
+ if (fgets(runlevel, PATH_MAX, fp)) {
+ int i = strlen(runlevel) - 1;
if (runlevel[i] == '\n')
runlevel[i] = 0;
} else
*runlevel = '\0';
- fclose (fp);
+ fclose(fp);
}
if (! runlevel || ! *runlevel) {
- free (runlevel);
- runlevel = xstrdup (RC_LEVEL_SYSINIT);
+ free(runlevel);
+ runlevel = xstrdup(RC_LEVEL_SYSINIT);
}
- return (runlevel);
+ return runlevel;
}
librc_hidden_def(rc_runlevel_get)
-bool rc_runlevel_set (const char *runlevel)
+bool rc_runlevel_set(const char *runlevel)
{
- FILE *fp = fopen (SOFTLEVEL, "w");
+ FILE *fp = fopen(SOFTLEVEL, "w");
if (! fp)
- return (false);
- fprintf (fp, "%s", runlevel);
- fclose (fp);
- return (true);
+ return false;
+ fprintf(fp, "%s", runlevel);
+ fclose(fp);
+ return true;
}
librc_hidden_def(rc_runlevel_set)
-bool rc_runlevel_exists (const char *runlevel)
+bool rc_runlevel_exists(const char *runlevel)
{
char *path;
struct stat buf;
bool retval = false;
if (! runlevel)
- return (false);
+ return false;
- path = rc_strcatpaths (RC_RUNLEVELDIR, runlevel, (char *) NULL);
- if (stat (path, &buf) == 0 && S_ISDIR (buf.st_mode))
+ path = rc_strcatpaths(RC_RUNLEVELDIR, runlevel, (char *) NULL);
+ if (stat(path, &buf) == 0 && S_ISDIR(buf.st_mode))
retval = true;
- free (path);
- return (retval);
+ free(path);
+ return retval;
}
librc_hidden_def(rc_runlevel_exists)
- /* Resolve a service name to it's full path */
-char *rc_service_resolve (const char *service)
+/* Resolve a service name to it's full path */
+char *rc_service_resolve(const char *service)
{
char buffer[PATH_MAX];
char *file;
@@ -322,53 +326,53 @@ char *rc_service_resolve (const char *service)
struct stat buf;
if (! service)
- return (NULL);
+ return NULL;
if (service[0] == '/')
- return (xstrdup (service));
+ return xstrdup(service);
/* First check started services */
- file = rc_strcatpaths (RC_SVCDIR, "started", service, (char *) NULL);
- if (lstat (file, &buf) || ! S_ISLNK (buf.st_mode)) {
- free (file);
- file = rc_strcatpaths (RC_SVCDIR, "inactive", service, (char *) NULL);
- if (lstat (file, &buf) || ! S_ISLNK (buf.st_mode)) {
- free (file);
+ file = rc_strcatpaths(RC_SVCDIR, "started", service, (char *) NULL);
+ if (lstat(file, &buf) || ! S_ISLNK(buf.st_mode)) {
+ free(file);
+ file = rc_strcatpaths(RC_SVCDIR, "inactive", service, (char *) NULL);
+ if (lstat(file, &buf) || ! S_ISLNK(buf.st_mode)) {
+ free(file);
file = NULL;
}
}
- memset (buffer, 0, sizeof (buffer));
+ memset(buffer, 0, sizeof(buffer));
/* Nope, so lets see if the user has written it */
#ifdef RC_LOCAL_INITDIR
- snprintf (buffer, sizeof (buffer), RC_LOCAL_INITDIR "/%s", service);
- if (stat (buffer, &buf) == 0)
- return (xstrdup (buffer));
+ snprintf(buffer, sizeof(buffer), RC_LOCAL_INITDIR "/%s", service);
+ if (stat(buffer, &buf) == 0)
+ return xstrdup(buffer);
#endif
if (file) {
- r = readlink (file, buffer, sizeof (buffer));
- free (file);
+ r = readlink(file, buffer, sizeof(buffer));
+ free(file);
if (r > 0)
- return (xstrdup (buffer));
+ return xstrdup(buffer);
}
- snprintf (buffer, sizeof (buffer), RC_INITDIR "/%s", service);
+ snprintf(buffer, sizeof(buffer), RC_INITDIR "/%s", service);
/* So we don't exist in /etc/init.d - check RC_PKG_INITDIR */
#ifdef RC_PKG_INITDIR
- if (stat (buffer, &buf) != 0) {
- snprintf (buffer, sizeof (buffer), RC_PKG_INITDIR "/%s", service);
- if (stat (buffer, &buf) != 0)
- return (NULL);
+ if (stat(buffer, &buf) != 0) {
+ snprintf(buffer, sizeof(buffer), RC_PKG_INITDIR "/%s", service);
+ if (stat(buffer, &buf) != 0)
+ return NULL;
}
#endif
- return (xstrdup (buffer));
+ return xstrdup(buffer);
}
librc_hidden_def(rc_service_resolve)
-bool rc_service_exists (const char *service)
+bool rc_service_exists(const char *service)
{
char *file;
bool retval = false;
@@ -376,59 +380,62 @@ bool rc_service_exists (const char *service)
struct stat buf;
if (! service)
- return (false);
+ return false;
- len = strlen (service);
+ len = strlen(service);
/* .sh files are not init scripts */
if (len > 2 && service[len - 3] == '.' &&
service[len - 2] == 's' &&
service[len - 1] == 'h')
- return (false);
+ return false;
- if (! (file = rc_service_resolve (service)))
- return (false);
+ if (! (file = rc_service_resolve(service)))
+ return false;
- if (stat (file, &buf) == 0 && buf.st_mode & S_IXUGO)
+ if (stat(file, &buf) == 0 && buf.st_mode & S_IXUGO)
retval = true;
- free (file);
- return (retval);
+ free(file);
+ return retval;
}
librc_hidden_def(rc_service_exists)
#define OPTSTR ". '%s'; echo \"${opts}\""
-char **rc_service_extra_commands (const char *service)
+RC_STRINGLIST *rc_service_extra_commands(const char *service)
{
char *svc;
char *cmd = NULL;
char *buffer = NULL;
- char **commands = NULL;
+ RC_STRINGLIST *commands;
char *token;
char *p;
FILE *fp;
size_t l;
- if (! (svc = rc_service_resolve (service)))
- return (NULL);
-
- l = strlen (OPTSTR) + strlen (svc) + 1;
- cmd = xmalloc (sizeof (char) * l);
- snprintf (cmd, l, OPTSTR, svc);
- free (svc);
- if ((fp = popen (cmd, "r"))) {
- p = buffer = rc_getline (fp);
- while ((token = strsep (&p, " ")))
- rc_strlist_addsort (&commands, token);
- pclose (fp);
- free (buffer);
- }
- free (cmd);
- return (commands);
+ if (! (svc = rc_service_resolve(service)))
+ return NULL;
+
+ commands = rc_stringlist_new();
+
+ l = strlen(OPTSTR) + strlen(svc) + 1;
+ cmd = xmalloc(sizeof(char) * l);
+ snprintf(cmd, l, OPTSTR, svc);
+ free(svc);
+
+ if ((fp = popen(cmd, "r"))) {
+ p = buffer = rc_getline(fp);
+ while ((token = strsep(&p, " ")))
+ rc_stringlist_add(commands, token);
+ pclose(fp);
+ free(buffer);
+ }
+ free(cmd);
+ return commands;
}
librc_hidden_def(rc_service_extra_commands)
#define DESCSTR ". '%s'; echo \"${description%s%s}\""
-char *rc_service_description (const char *service, const char *option)
+char *rc_service_description(const char *service, const char *option)
{
char *svc;
char *cmd;
@@ -436,85 +443,90 @@ char *rc_service_description (const char *service, const char *option)
FILE *fp;
size_t l;
- if (! (svc = rc_service_resolve (service)))
- return (NULL);
+ if (! (svc = rc_service_resolve(service)))
+ return NULL;
if (! option)
option = "";
- l = strlen (DESCSTR) + strlen (svc) + strlen (option) + 2;
- cmd = xmalloc (sizeof (char) * l);
- snprintf (cmd, l, DESCSTR, svc, option ? "_" : "", option);
- free (svc);
- if ((fp = popen (cmd, "r"))) {
- desc = rc_getline (fp);
- pclose (fp);
+ l = strlen(DESCSTR) + strlen(svc) + strlen(option) + 2;
+ cmd = xmalloc(sizeof(char) * l);
+ snprintf(cmd, l, DESCSTR, svc, option ? "_" : "", option);
+ free(svc);
+ if ((fp = popen(cmd, "r"))) {
+ desc = rc_getline(fp);
+ pclose(fp);
}
- free (cmd);
- return (desc);
+ free(cmd);
+ return desc;
}
librc_hidden_def(rc_service_description)
-bool rc_service_in_runlevel (const char *service, const char *runlevel)
+bool rc_service_in_runlevel(const char *service, const char *runlevel)
{
char *file;
bool retval;
if (! runlevel || ! service)
- return (false);
+ return false;
- file = rc_strcatpaths (RC_RUNLEVELDIR, runlevel, basename_c (service),
- (char *) NULL);
- retval = exists (file);
- free (file);
+ file = rc_strcatpaths(RC_RUNLEVELDIR, runlevel, basename_c(service),
+ (char *) NULL);
+ retval = exists(file);
+ free(file);
- return (retval);
+ return retval;
}
librc_hidden_def(rc_service_in_runlevel)
-bool rc_service_mark (const char *service, const rc_service_state_t state)
+bool rc_service_mark(const char *service, const RC_SERVICE state)
{
char *file;
int i = 0;
int skip_state = -1;
const char *base;
- char *init = rc_service_resolve (service);
+ char *init = rc_service_resolve(service);
bool skip_wasinactive = false;
+ int s;
+ char *was;
+ RC_STRINGLIST *dirs;
+ RC_STRING *dir;
+ int serrno;
if (! init)
- return (false);
+ return false;
- base = basename_c (service);
+ base = basename_c(service);
if (state != RC_SERVICE_STOPPED) {
- if (! exists (init)) {
- free (init);
- return (false);
+ if (! exists(init)) {
+ free(init);
+ return false;
}
- file = rc_strcatpaths (RC_SVCDIR, rc_parse_service_state (state), base,
- (char *) NULL);
- if (exists (file))
- unlink (file);
- i = symlink (init, file);
- if (i != 0) {
- free (file);
- free (init);
- return (false);
+ file = rc_strcatpaths(RC_SVCDIR, rc_parse_service_state (state), base,
+ (char *) NULL);
+ if (exists(file))
+ unlink(file);
+ i = symlink(init, file);
+ if (i != 0) {
+ free(file);
+ free(init);
+ return false;
}
- free (file);
+ free(file);
skip_state = state;
}
if (state == RC_SERVICE_COLDPLUGGED || state == RC_SERVICE_FAILED) {
- free (init);
- return (true);
+ free(init);
+ return true;
}
/* Remove any old states now */
for (i = 0; rc_service_state_names[i].name; i++) {
- int s = rc_service_state_names[i].state;
+ s = rc_service_state_names[i].state;
if ((s != skip_state &&
s != RC_SERVICE_STOPPED &&
@@ -522,24 +534,24 @@ bool rc_service_mark (const char *service, const rc_service_state_t state)
s != RC_SERVICE_SCHEDULED) &&
(! skip_wasinactive || s != RC_SERVICE_WASINACTIVE))
{
- file = rc_strcatpaths (RC_SVCDIR, rc_parse_service_state (s), base,
- (char *) NULL);
- if (exists (file)) {
+ file = rc_strcatpaths(RC_SVCDIR, rc_parse_service_state(s), base,
+ (char *) NULL);
+ if (exists(file)) {
if ((state == RC_SERVICE_STARTING ||
state == RC_SERVICE_STOPPING) &&
s == RC_SERVICE_INACTIVE)
{
- char *wasfile = rc_strcatpaths (RC_SVCDIR,
- rc_parse_service_state (RC_SERVICE_WASINACTIVE),
- base, (char *) NULL);
+ was = rc_strcatpaths(RC_SVCDIR,
+ rc_parse_service_state(RC_SERVICE_WASINACTIVE),
+ base, (char *) NULL);
- symlink (init, wasfile);
+ symlink(init, was);
skip_wasinactive = true;
- free (wasfile);
+ free(was);
}
- unlink (file);
+ unlink(file);
}
- free (file);
+ free(file);
}
}
@@ -548,126 +560,133 @@ bool rc_service_mark (const char *service, const rc_service_state_t state)
state == RC_SERVICE_STOPPED ||
state == RC_SERVICE_INACTIVE)
{
- file = rc_strcatpaths (RC_SVCDIR, "exclusive", base, (char *) NULL);
- unlink (file);
- free (file);
+ file = rc_strcatpaths(RC_SVCDIR, "exclusive", base, (char *) NULL);
+ unlink(file);
+ free(file);
}
/* Remove any options and daemons the service may have stored */
if (state == RC_SERVICE_STOPPED) {
- char *dir = rc_strcatpaths (RC_SVCDIR, "options", base, (char *) NULL);
- rm_dir (dir, true);
- free (dir);
+ file = rc_strcatpaths(RC_SVCDIR, "options", base, (char *) NULL);
+ rm_dir(file, true);
+ free(file);
- dir = rc_strcatpaths (RC_SVCDIR, "daemons", base, (char *) NULL);
- rm_dir (dir, true);
- free (dir);
+ file = rc_strcatpaths(RC_SVCDIR, "daemons", base, (char *) NULL);
+ rm_dir(file, true);
+ free(file);
- rc_service_schedule_clear (service);
+ rc_service_schedule_clear(service);
}
/* 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 = ls_dir (sdir, 0);
- char *dir;
- int serrno;
+ file = rc_strcatpaths(RC_SVCDIR, "scheduled", (char *) NULL);
+ dirs = ls_dir(file, 0);
- STRLIST_FOREACH (dirs, dir, i) {
- char *bdir = rc_strcatpaths (sdir, dir, (char *) NULL);
- file = rc_strcatpaths (bdir, base, (char *) NULL);
- unlink (file);
- free (file);
+ TAILQ_FOREACH(dir, dirs, entries) {
+ was = rc_strcatpaths(file, dir->value, base, (char *) NULL);
+ unlink(was);
+ free(was);
/* Try and remove the dir - we don't care about errors */
+ was = rc_strcatpaths(file, dir->value, (char *) NULL);
serrno = errno;
- rmdir (bdir);
+ rmdir(was);
errno = serrno;
- free (bdir);
+ free(was);
}
- rc_strlist_free (dirs);
- free (sdir);
+ rc_stringlist_free(dirs);
}
- free (init);
- return (true);
+ free(init);
+ return true;
}
librc_hidden_def(rc_service_mark)
-rc_service_state_t rc_service_state (const char *service)
+RC_SERVICE rc_service_state(const char *service)
{
int i;
int state = RC_SERVICE_STOPPED;
+ char *file;
+ RC_STRINGLIST *dirs;
+ RC_STRING *dir;
for (i = 0; rc_service_state_names[i].name; i++) {
- char *file = rc_strcatpaths (RC_SVCDIR, rc_service_state_names[i].name,
- basename_c (service), (char*) NULL);
- if (exists (file)) {
+ file = rc_strcatpaths(RC_SVCDIR, rc_service_state_names[i].name,
+ basename_c(service), (char*) NULL);
+ if (exists(file)) {
if (rc_service_state_names[i].state <= 0x10)
state = rc_service_state_names[i].state;
else
state |= rc_service_state_names[i].state;
}
- free (file);
+ free(file);
}
if (state & RC_SERVICE_STOPPED) {
- char **services = rc_services_scheduled_by (service);
- if (services) {
- state |= RC_SERVICE_SCHEDULED;
- free (services);
+ dirs = ls_dir(RC_SVCDIR "/scheduled", 0);
+ TAILQ_FOREACH (dir, dirs, entries) {
+ file = rc_strcatpaths(RC_SVCDIR, "scheduled",
+ dir->value,
+ service, (char *) NULL);
+ if (exists(file))
+ state |= RC_SERVICE_SCHEDULED;
+ free(file);
+ if (state & RC_SERVICE_SCHEDULED)
+ break;
}
+ rc_stringlist_free(dirs);
}
- return (state);
+ return state;
}
librc_hidden_def(rc_service_state)
-char *rc_service_value_get (const char *service, const char *option)
+char *rc_service_value_get(const char *service, const char *option)
{
FILE *fp;
char *line = NULL;
- char *file = rc_strcatpaths (RC_SVCDIR, "options", service, option,
- (char *) NULL);
+ char *file = rc_strcatpaths(RC_SVCDIR, "options", service, option,
+ (char *) NULL);
- if ((fp = fopen (file, "r"))) {
- line = rc_getline (fp);
- fclose (fp);
+ if ((fp = fopen(file, "r"))) {
+ line = rc_getline(fp);
+ fclose(fp);
}
- free (file);
+ free(file);
- return (line);
+ return line;
}
librc_hidden_def(rc_service_value_get)
-bool rc_service_value_set (const char *service, const char *option,
- const char *value)
+bool rc_service_value_set(const char *service, const char *option,
+ const char *value)
{
FILE *fp;
- char *path = rc_strcatpaths (RC_SVCDIR, "options", service, (char *) NULL);
- char *file = rc_strcatpaths (path, option, (char *) NULL);
+ char *path = rc_strcatpaths(RC_SVCDIR, "options", service, (char *) NULL);
+ char *file = rc_strcatpaths(path, option, (char *) NULL);
bool retval = false;
- if (mkdir (path, 0755) != 0 && errno != EEXIST) {
- free (path);
- free (file);
- return (false);
+ if (mkdir(path, 0755) != 0 && errno != EEXIST) {
+ free(path);
+ free(file);
+ return false;
}
- if ((fp = fopen (file, "w"))) {
+ if ((fp = fopen(file, "w"))) {
if (value)
- fprintf (fp, "%s", value);
- fclose (fp);
+ fprintf(fp, "%s", value);
+ fclose(fp);
retval = true;
}
- free (path);
- free (file);
- return (retval);
+ free(path);
+ free(file);
+ return retval;
}
librc_hidden_def(rc_service_value_set)
-static pid_t _exec_service (const char *service, const char *arg)
+static pid_t _exec_service(const char *service, const char *arg)
{
char *file;
char *fifo;
@@ -676,92 +695,92 @@ static pid_t _exec_service (const char *service, const char *arg)
sigset_t old;
struct sigaction sa;
- file = rc_service_resolve (service);
- if (! exists (file)) {
- rc_service_mark (service, RC_SERVICE_STOPPED);
- free (file);
- return (0);
+ file = rc_service_resolve(service);
+ if (! exists(file)) {
+ rc_service_mark(service, RC_SERVICE_STOPPED);
+ free(file);
+ return 0;
}
/* We create a fifo so that other services can wait until we complete */
- fifo = rc_strcatpaths (RC_SVCDIR, "exclusive", basename_c (service),
- (char *) NULL);
+ fifo = rc_strcatpaths(RC_SVCDIR, "exclusive", basename_c(service),
+ (char *) NULL);
- if (mkfifo (fifo, 0600) != 0 && errno != EEXIST) {
- free (fifo);
- free (file);
- return (-1);
+ if (mkfifo(fifo, 0600) != 0 && errno != EEXIST) {
+ free(fifo);
+ free(file);
+ return -1;
}
/* We need to block signals until we have forked */
- memset (&sa, 0, sizeof (sa));
+ memset(&sa, 0, sizeof (sa));
sa.sa_handler = SIG_DFL;
- sigemptyset (&sa.sa_mask);
- sigfillset (&full);
- sigprocmask (SIG_SETMASK, &full, &old);
+ sigemptyset(&sa.sa_mask);
+ sigfillset(&full);
+ sigprocmask(SIG_SETMASK, &full, &old);
- if ((pid = fork ()) == 0) {
+ if ((pid = fork()) == 0) {
/* Restore default handlers */
- sigaction (SIGCHLD, &sa, NULL);
- sigaction (SIGHUP, &sa, NULL);
- sigaction (SIGINT, &sa, NULL);
- sigaction (SIGQUIT, &sa, NULL);
- sigaction (SIGTERM, &sa, NULL);
- sigaction (SIGUSR1, &sa, NULL);
- sigaction (SIGWINCH, &sa, NULL);
+ sigaction(SIGCHLD, &sa, NULL);
+ sigaction(SIGHUP, &sa, NULL);
+ sigaction(SIGINT, &sa, NULL);
+ sigaction(SIGQUIT, &sa, NULL);
+ sigaction(SIGTERM, &sa, NULL);
+ sigaction(SIGUSR1, &sa, NULL);
+ sigaction(SIGWINCH, &sa, NULL);
/* Unmask signals */
- sigprocmask (SIG_SETMASK, &old, NULL);
+ sigprocmask(SIG_SETMASK, &old, NULL);
/* Safe to run now */
- execl (file, file, arg, (char *) NULL);
- fprintf (stderr, "unable to exec `%s': %s\n",
- file, strerror (errno));
- unlink (fifo);
- _exit (EXIT_FAILURE);
+ execl(file, file, arg, (char *) NULL);
+ fprintf(stderr, "unable to exec `%s': %s\n",
+ file, strerror(errno));
+ unlink(fifo);
+ _exit(EXIT_FAILURE);
}
if (pid == -1)
- fprintf (stderr, "fork: %s\n", strerror (errno));
+ fprintf(stderr, "fork: %s\n",strerror (errno));
- sigprocmask (SIG_SETMASK, &old, NULL);
+ sigprocmask(SIG_SETMASK, &old, NULL);
- free (fifo);
- free (file);
+ free(fifo);
+ free(file);
- return (pid);
+ return pid;
}
-pid_t rc_service_stop (const char *service)
+pid_t rc_service_stop(const char *service)
{
- rc_service_state_t state = rc_service_state (service);
+ RC_SERVICE state = rc_service_state(service);
if (state & RC_SERVICE_FAILED)
- return (-1);
+ return -1;
if (state & RC_SERVICE_STOPPED)
- return (0);
+ return 0;
- return (_exec_service (service, "stop"));
+ return _exec_service(service, "stop");
}
librc_hidden_def(rc_service_stop)
-pid_t rc_service_start (const char *service)
+pid_t rc_service_start(const char *service)
{
- rc_service_state_t state = rc_service_state (service);
+ RC_SERVICE state = rc_service_state(service);
if (state & RC_SERVICE_FAILED)
- return (-1);
+ return -1;
if (! state & RC_SERVICE_STOPPED)
- return (0);
+ return 0;
- return (_exec_service (service, "start"));
+ return _exec_service(service, "start");
}
librc_hidden_def(rc_service_start)
-bool rc_service_schedule_start (const char *service,
- const char *service_to_start)
+bool rc_service_schedule_start(const char *service,
+ const char *service_to_start)
{
char *dir;
char *init;
@@ -769,162 +788,156 @@ bool rc_service_schedule_start (const char *service,
bool retval;
/* service may be a provided service, like net */
- if (! service || ! rc_service_exists (service_to_start))
- return (false);
+ if (! service || ! rc_service_exists(service_to_start))
+ return false;
- dir = rc_strcatpaths (RC_SVCDIR, "scheduled", basename_c (service),
- (char *) NULL);
- if (mkdir (dir, 0755) != 0 && errno != EEXIST) {
- free (dir);
- return (false);
+ dir = rc_strcatpaths(RC_SVCDIR, "scheduled", basename_c(service),
+ (char *) NULL);
+ if (mkdir(dir, 0755) != 0 && errno != EEXIST) {
+ free(dir);
+ return false;
}
- init = rc_service_resolve (service_to_start);
- file = rc_strcatpaths (dir, basename_c (service_to_start), (char *) NULL);
- retval = (exists (file) || symlink (init, file) == 0);
- free (init);
- free (file);
- free (dir);
+ init = rc_service_resolve(service_to_start);
+ file = rc_strcatpaths(dir, basename_c(service_to_start), (char *) NULL);
+ retval = (exists(file) || symlink(init, file) == 0);
+ free(init);
+ free(file);
+ free(dir);
- return (retval);
+ return retval;
}
librc_hidden_def(rc_service_schedule_start)
-bool rc_service_schedule_clear (const char *service)
+bool rc_service_schedule_clear(const char *service)
{
- char *dir = rc_strcatpaths (RC_SVCDIR, "scheduled", basename_c (service),
- (char *) NULL);
+ char *dir = rc_strcatpaths(RC_SVCDIR, "scheduled", basename_c(service),
+ (char *) NULL);
bool retval;
- if (! (retval = rm_dir (dir, true)) && errno == ENOENT)
+ if (! (retval = rm_dir(dir, true)) && errno == ENOENT)
retval = true;
- free (dir);
- return (retval);
+ free(dir);
+ return retval;
}
librc_hidden_def(rc_service_schedule_clear)
-
-char **rc_services_in_runlevel (const char *runlevel)
+RC_STRINGLIST *rc_services_in_runlevel(const char *runlevel)
{
char *dir;
- char **list = NULL;
+ RC_STRINGLIST *list;
if (! runlevel) {
-#if defined(RC_PKG_INITDIR) || defined(RC_LOCAL_INITDIR)
- int i;
-#endif
#ifdef RC_PKG_INITDIR
- char **pkg = ls_dir (RC_PKG_INITDIR, LS_INITD);
+ RC_STRINGLIST *pkg = ls_dir(RC_PKG_INITDIR, LS_INITD);
#endif
#ifdef RC_LOCAL_INITDIR
- char **local = ls_dir (RC_LOCAL_INITDIR, LS_INITD);
+ RC_STRINGLIST *local = ls_dir(RC_LOCAL_INITDIR, LS_INITD);
#endif
- list = ls_dir (RC_INITDIR, LS_INITD);
+ list = ls_dir(RC_INITDIR, LS_INITD);
#ifdef RC_PKG_INITDIR
- STRLIST_FOREACH (pkg, dir, i)
- rc_strlist_addsortu (&list, dir);
- rc_strlist_free (pkg);
+ if (pkg) {
+ TAILQ_CONCAT(list, pkg);
+ free(pkg);
+ }
#endif
#ifdef RC_LOCAL_DIR
- STRLIST_FOREACH (local, dir, i)
- rc_strlist_addsortu (&list, dir);
- rc_strlist_free (local);
+ if (local) {
+ TAILQ_CONCAT(list, local);
+ free(local);
+ }
#endif
- return (list);
+ return list;
}
/* These special levels never contain any services */
- if (strcmp (runlevel, RC_LEVEL_SYSINIT) == 0 ||
- strcmp (runlevel, RC_LEVEL_SINGLE) == 0)
- return (NULL);
-
- dir = rc_strcatpaths (RC_RUNLEVELDIR, runlevel, (char *) NULL);
- list = ls_dir (dir, LS_INITD);
- free (dir);
- return (list);
+ if (strcmp(runlevel, RC_LEVEL_SYSINIT) == 0 ||
+ strcmp(runlevel, RC_LEVEL_SINGLE) == 0) {
+ list = rc_stringlist_new();
+ return list;
+ }
+
+ dir = rc_strcatpaths(RC_RUNLEVELDIR, runlevel, (char *) NULL);
+ list = ls_dir(dir, LS_INITD);
+ free(dir);
+ return list;
}
librc_hidden_def(rc_services_in_runlevel)
-char **rc_services_in_state (rc_service_state_t state)
+RC_STRINGLIST *rc_services_in_state(RC_SERVICE state)
{
- char *dir = rc_strcatpaths (RC_SVCDIR, rc_parse_service_state (state),
- (char *) NULL);
- char **list = NULL;
+ char *dir = rc_strcatpaths(RC_SVCDIR, rc_parse_service_state(state),
+ (char *) NULL);
+ RC_STRINGLIST *services;
+ RC_STRINGLIST *list;
+ RC_STRINGLIST *dirs;
+ RC_STRING *d;
+ char *p;
if (state == RC_SERVICE_SCHEDULED) {
- 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 = ls_dir (p, LS_INITD);
- char *e;
- int j;
-
- STRLIST_FOREACH (entries, e, j)
- rc_strlist_addsortu (&list, e);
-
- if (entries)
- free (entries);
+ dirs = ls_dir(dir, 0);
+ list = rc_stringlist_new();
+ TAILQ_FOREACH(d, dirs, entries) {
+ p = rc_strcatpaths(dir, d->value, (char *) NULL);
+ services = ls_dir(p, LS_INITD);
+ free(p);
+ TAILQ_CONCAT(list, services);
+ free(services);
}
-
- if (dirs)
- free (dirs);
+ rc_stringlist_free(dirs);
} else {
- list = ls_dir (dir, LS_INITD);
+ list = ls_dir(dir, LS_INITD);
}
- free (dir);
- return (list);
+ free(dir);
+ return list;
}
librc_hidden_def(rc_services_in_state)
-bool rc_service_add (const char *runlevel, const char *service)
+bool rc_service_add(const char *runlevel, const char *service)
{
bool retval;
char *init;
char *file;
+ char path[MAXPATHLEN] = { '\0' };
+ char *p;
- if (! rc_runlevel_exists (runlevel)) {
+ if (! rc_runlevel_exists(runlevel)) {
errno = ENOENT;
- return (false);
+ return false;
}
- if (rc_service_in_runlevel (service, runlevel)) {
+ if (rc_service_in_runlevel(service, runlevel)) {
errno = EEXIST;
- return (false);
+ return false;
}
- init = rc_service_resolve (service);
+ init = rc_service_resolve(service);
/* We need to ensure that only things in /etc/init.d are added
* to the boot runlevel */
if (strcmp (runlevel, RC_LEVEL_BOOT) == 0) {
- char tmp[MAXPATHLEN] = { '\0' };
- char *p;
-
- p = realpath (dirname (init), tmp);
- free (init);
+ p = realpath(dirname (init), path);
+ free(init);
if (! *p)
- return (false);
+ return false;
- retval = (strcmp (tmp, RC_INITDIR) == 0);
+ retval = (strcmp(path, RC_INITDIR) == 0);
if (! retval) {
errno = EPERM;
- return (false);
+ return false;
}
- init = rc_strcatpaths (RC_INITDIR, service, (char *) NULL);
+ init = rc_strcatpaths(RC_INITDIR, service, (char *) NULL);
}
- file = rc_strcatpaths (RC_RUNLEVELDIR, runlevel, basename_c (service),
- (char *) NULL);
- retval = (symlink (init, file) == 0);
- free (init);
- free (file);
- return (retval);
+ file = rc_strcatpaths(RC_RUNLEVELDIR, runlevel, basename_c(service),
+ (char *) NULL);
+ retval = (symlink(init, file) == 0);
+ free(init);
+ free(file);
+ return retval;
}
librc_hidden_def(rc_service_add)
@@ -934,46 +947,46 @@ bool rc_service_delete (const char *runlevel, const char *service)
bool retval = false;
if (! runlevel || ! service)
- return (false);
+ return false;
- file = rc_strcatpaths (RC_RUNLEVELDIR, runlevel, basename_c (service),
+ file = rc_strcatpaths (RC_RUNLEVELDIR, runlevel, basename_c(service),
(char *) NULL);
- if (unlink (file) == 0)
+ if (unlink(file) == 0)
retval = true;
- free (file);
- return (retval);
+ free(file);
+ return retval;
}
librc_hidden_def(rc_service_delete)
-char **rc_services_scheduled_by (const char *service)
+RC_STRINGLIST *rc_services_scheduled_by(const char *service)
{
- char **dirs = ls_dir (RC_SVCDIR "/scheduled", 0);
- char **list = NULL;
- char *dir;
- int i;
+ RC_STRINGLIST *dirs = ls_dir(RC_SVCDIR "/scheduled", 0);
+ RC_STRINGLIST *list;
+ RC_STRING *dir;
+ char *file;
- STRLIST_FOREACH (dirs, dir, i) {
- char *file = rc_strcatpaths (RC_SVCDIR, "scheduled", dir, service,
- (char *) NULL);
- if (exists (file))
- rc_strlist_add (&list, file);
- free (file);
+ list = rc_stringlist_new();
+ TAILQ_FOREACH (dir, dirs, entries) {
+ file = rc_strcatpaths(RC_SVCDIR, "scheduled", dir->value,
+ service, (char *) NULL);
+ if (exists(file))
+ rc_stringlist_add(list, file);
+ free(file);
}
- rc_strlist_free (dirs);
+ rc_stringlist_free(dirs);
- return (list);
+ return list;
}
librc_hidden_def(rc_services_scheduled_by)
-char **rc_services_scheduled (const char *service)
+RC_STRINGLIST *rc_services_scheduled(const char *service)
{
- char *dir = rc_strcatpaths (RC_SVCDIR, "scheduled", basename_c (service),
- (char *) NULL);
- char **list = NULL;
+ char *dir = rc_strcatpaths(RC_SVCDIR, "scheduled", basename_c(service),
+ (char *) NULL);
+ RC_STRINGLIST *list = ls_dir(dir, LS_INITD);
- list = ls_dir (dir, LS_INITD);
- free (dir);
- return (list);
+ free(dir);
+ return list;
}
librc_hidden_def(rc_services_scheduled)