summaryrefslogtreecommitdiff
path: root/src/librc/librc.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2008-10-10 08:37:21 +0000
committerRoy Marples <roy@marples.name>2008-10-10 08:37:21 +0000
commitd6da8e8c48feb8faf9287fc86fbbf0890c37a87c (patch)
treee6cdf21f0f3a3270b705fe14b876f92b14b38dbf /src/librc/librc.c
parent247766695cd7c5e8d83dff72f7eb7e6578bf57b8 (diff)
downloadopenrc-d6da8e8c48feb8faf9287fc86fbbf0890c37a87c.tar.gz
openrc-d6da8e8c48feb8faf9287fc86fbbf0890c37a87c.tar.bz2
openrc-d6da8e8c48feb8faf9287fc86fbbf0890c37a87c.tar.xz
sysinit is now a real runlevel that handles things like udev, dmesg and
mounting various bits in /dev and /sys. init.sh JUST mounts /lib/rc/init.d (and /proc for Linux systems) To make development of this easier we now return an empty RC_STRINGLIST instead of a NULL for empty things. If you don't have a udev init script installed, don't reboot your box OR roll back to an older OpenRC version.
Diffstat (limited to 'src/librc/librc.c')
-rw-r--r--src/librc/librc.c246
1 files changed, 122 insertions, 124 deletions
diff --git a/src/librc/librc.c b/src/librc/librc.c
index e97425e..b625b06 100644
--- a/src/librc/librc.c
+++ b/src/librc/librc.c
@@ -67,7 +67,8 @@ static const rc_service_state_name_t rc_service_state_names[] = {
#define LS_INITD 0x01
#define LS_DIR 0x02
-static RC_STRINGLIST *ls_dir(const char *dir, int options)
+static RC_STRINGLIST *
+ls_dir(const char *dir, int options)
{
DIR *dp;
struct dirent *d;
@@ -77,15 +78,15 @@ static RC_STRINGLIST *ls_dir(const char *dir, int options)
char file[PATH_MAX];
int r;
+ list = rc_stringlist_new();
if ((dp = opendir(dir)) == NULL)
- return NULL;
-
+ return list;
while (((d = readdir(dp)) != NULL)) {
if (d->d_name[0] != '.') {
if (options & LS_INITD) {
/* Check that our file really exists.
- * This is important as a service maybe in a runlevel, but
- * could also have been removed. */
+ * This is important as a service maybe in a
+ * runlevel, but could have been removed. */
snprintf(file, sizeof(file), "%s/%s",
dir, d->d_name);
r = stat(file, &buf);
@@ -104,17 +105,15 @@ static RC_STRINGLIST *ls_dir(const char *dir, int options)
! S_ISDIR(buf.st_mode))
continue;
}
- if (! list)
- list = rc_stringlist_new();
rc_stringlist_add(list, d->d_name);
}
}
closedir(dp);
-
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;
@@ -127,16 +126,17 @@ static bool rm_dir(const char *pathname, bool top)
errno = 0;
while (((d = readdir(dp)) != NULL) && errno == 0) {
- if (strcmp(d->d_name, ".") != 0 && strcmp(d->d_name, "..") != 0) {
- snprintf(file, sizeof(file), "%s/%s", pathname, d->d_name);
-
+ if (strcmp(d->d_name, ".") != 0 &&
+ strcmp(d->d_name, "..") != 0)
+ {
+ snprintf(file, sizeof(file),
+ "%s/%s", pathname, d->d_name);
if (stat(file, &s) != 0) {
retval = false;
break;
}
-
if (S_ISDIR(s.st_mode)) {
- if (! rm_dir(file, true))
+ if (!rm_dir(file, true))
{
retval = false;
break;
@@ -151,7 +151,7 @@ static bool rm_dir(const char *pathname, bool top)
}
closedir(dp);
- if (! retval)
+ if (!retval)
return false;
if (top && rmdir(pathname) != 0)
@@ -162,7 +162,8 @@ static bool rm_dir(const char *pathname, bool top)
/* 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 = NULL;
@@ -171,12 +172,12 @@ static bool file_regex(const char *file, const char *regex)
bool retval = false;
int result;
- if (! (fp = fopen(file, "r")))
+ if (!(fp = fopen(file, "r")))
return false;
if ((result = regcomp(&re, regex, REG_EXTENDED | REG_NOSUB)) != 0) {
fclose(fp);
- line = xmalloc(sizeof (char) * BUFSIZ);
+ line = xmalloc(sizeof(char) * BUFSIZ);
regerror(result, &re, line, BUFSIZ);
fprintf(stderr, "file_regex: %s", line);
free(line);
@@ -197,8 +198,8 @@ static bool file_regex(const char *file, const char *regex)
}
#endif
-
-const char *rc_sys(void)
+const char *
+rc_sys(void)
{
#ifdef PREFIX
return RC_SYS_PREFIX;
@@ -242,7 +243,8 @@ const char *rc_sys(void)
}
librc_hidden_def(rc_sys)
-static const char *rc_parse_service_state(RC_SERVICE state)
+static const char *
+rc_parse_service_state(RC_SERVICE state)
{
int i;
@@ -250,17 +252,18 @@ static const char *rc_parse_service_state(RC_SERVICE state)
if (rc_service_state_names[i].state == state)
return rc_service_state_names[i].name;
}
-
return NULL;
}
-bool rc_runlevel_starting(void)
+bool
+rc_runlevel_starting(void)
{
return exists(RC_STARTING);
}
librc_hidden_def(rc_runlevel_starting)
-bool rc_runlevel_stopping(void)
+bool
+rc_runlevel_stopping(void)
{
return exists(RC_STOPPING);
}
@@ -272,15 +275,17 @@ RC_STRINGLIST *rc_runlevel_list(void)
}
librc_hidden_def(rc_runlevel_list)
-char *rc_runlevel_get(void)
+char *
+rc_runlevel_get(void)
{
FILE *fp;
char *runlevel = NULL;
+ size_t i;
if ((fp = fopen(RC_RUNLEVEL, "r"))) {
runlevel = xmalloc(sizeof(char) * PATH_MAX);
if (fgets(runlevel, PATH_MAX, fp)) {
- int i = strlen(runlevel) - 1;
+ i = strlen(runlevel) - 1;
if (runlevel[i] == '\n')
runlevel[i] = 0;
} else
@@ -288,7 +293,7 @@ char *rc_runlevel_get(void)
fclose(fp);
}
- if (! runlevel || ! *runlevel) {
+ if (!runlevel || !*runlevel) {
free(runlevel);
runlevel = xstrdup(RC_LEVEL_SYSINIT);
}
@@ -297,11 +302,12 @@ char *rc_runlevel_get(void)
}
librc_hidden_def(rc_runlevel_get)
-bool rc_runlevel_set(const char *runlevel)
+bool
+rc_runlevel_set(const char *runlevel)
{
FILE *fp = fopen(RC_RUNLEVEL, "w");
- if (! fp)
+ if (!fp)
return false;
fprintf(fp, "%s", runlevel);
fclose(fp);
@@ -309,14 +315,14 @@ bool rc_runlevel_set(const char *runlevel)
}
librc_hidden_def(rc_runlevel_set)
-bool rc_runlevel_exists(const char *runlevel)
+bool
+rc_runlevel_exists(const char *runlevel)
{
char path[PATH_MAX];
struct stat buf;
- if (! runlevel)
+ if (!runlevel)
return false;
-
snprintf(path, sizeof(path), "%s/%s", RC_RUNLEVELDIR, runlevel);
if (stat(path, &buf) == 0 && S_ISDIR(buf.st_mode))
return true;
@@ -325,14 +331,15 @@ bool rc_runlevel_exists(const char *runlevel)
librc_hidden_def(rc_runlevel_exists)
/* Resolve a service name to it's full path */
-char *rc_service_resolve(const char *service)
+char *
+rc_service_resolve(const char *service)
{
char buffer[PATH_MAX];
char file[PATH_MAX];
int r;
struct stat buf;
- if (! service)
+ if (!service)
return NULL;
if (service[0] == '/')
@@ -377,14 +384,15 @@ char *rc_service_resolve(const char *service)
}
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;
int len;
struct stat buf;
- if (! service)
+ if (!service)
return false;
len = strlen(service);
@@ -395,7 +403,7 @@ bool rc_service_exists(const char *service)
service[len - 1] == 'h')
return false;
- if (! (file = rc_service_resolve(service)))
+ if (!(file = rc_service_resolve(service)))
return false;
if (stat(file, &buf) == 0 && buf.st_mode & S_IXUGO)
@@ -406,7 +414,8 @@ bool rc_service_exists(const char *service)
librc_hidden_def(rc_service_exists)
#define OPTSTR ". '%s'; echo \"${opts}\""
-RC_STRINGLIST *rc_service_extra_commands(const char *service)
+RC_STRINGLIST *
+rc_service_extra_commands(const char *service)
{
char *svc;
char *cmd = NULL;
@@ -418,10 +427,9 @@ RC_STRINGLIST *rc_service_extra_commands(const char *service)
FILE *fp;
size_t l;
- if (! (svc = rc_service_resolve(service)))
+ if (!(svc = rc_service_resolve(service)))
return NULL;
-
l = strlen(OPTSTR) + strlen(svc) + 1;
cmd = xmalloc(sizeof(char) * l);
snprintf(cmd, l, OPTSTR, svc);
@@ -431,7 +439,7 @@ RC_STRINGLIST *rc_service_extra_commands(const char *service)
rc_getline(&buffer, &len, fp);
p = buffer;
while ((token = strsep(&p, " "))) {
- if (! commands)
+ if (!commands)
commands = rc_stringlist_new();
rc_stringlist_add(commands, token);
}
@@ -444,7 +452,8 @@ RC_STRINGLIST *rc_service_extra_commands(const char *service)
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;
@@ -453,7 +462,7 @@ char *rc_service_description(const char *service, const char *option)
FILE *fp;
size_t l;
- if (! (svc = rc_service_resolve(service)))
+ if (!(svc = rc_service_resolve(service)))
return NULL;
if (!option)
@@ -472,7 +481,8 @@ char *rc_service_description(const char *service, const char *option)
}
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[PATH_MAX];
@@ -482,7 +492,8 @@ bool rc_service_in_runlevel(const char *service, const char *runlevel)
}
librc_hidden_def(rc_service_in_runlevel)
-bool rc_service_mark(const char *service, const RC_SERVICE state)
+bool
+rc_service_mark(const char *service, const RC_SERVICE state)
{
char file[PATH_MAX];
int i = 0;
@@ -496,11 +507,10 @@ bool rc_service_mark(const char *service, const RC_SERVICE state)
RC_STRING *dir;
int serrno;
- if (! init)
+ if (!init)
return false;
base = basename_c(service);
-
if (state != RC_SERVICE_STOPPED) {
if (!exists(init)) {
free(init);
@@ -583,29 +593,26 @@ bool rc_service_mark(const char *service, const RC_SERVICE state)
if (state == RC_SERVICE_STARTED || state == RC_SERVICE_STOPPED) {
snprintf(file, sizeof(file), RC_SVCDIR "/%s", "scheduled");
dirs = ls_dir(file, 0);
- if (dirs) {
- TAILQ_FOREACH(dir, dirs, entries) {
- snprintf(was, sizeof(was), "%s/%s/%s",
- file, dir->value, base);
- unlink(was);
-
- /* Try and remove the dir - we don't care about errors */
- snprintf(was, sizeof(was), "%s/%s",
- file, dir->value);
- serrno = errno;
- rmdir(was);
- errno = serrno;
- }
- rc_stringlist_free(dirs);
+ TAILQ_FOREACH(dir, dirs, entries) {
+ snprintf(was, sizeof(was), "%s/%s/%s",
+ file, dir->value, base);
+ unlink(was);
+
+ /* Try and remove the dir; we don't care about errors */
+ snprintf(was, sizeof(was), "%s/%s", file, dir->value);
+ serrno = errno;
+ rmdir(was);
+ errno = serrno;
}
+ rc_stringlist_free(dirs);
}
-
free(init);
return true;
}
librc_hidden_def(rc_service_mark)
-RC_SERVICE rc_service_state(const char *service)
+RC_SERVICE
+rc_service_state(const char *service)
{
int i;
int state = RC_SERVICE_STOPPED;
@@ -627,25 +634,24 @@ RC_SERVICE rc_service_state(const char *service)
if (state & RC_SERVICE_STOPPED) {
dirs = ls_dir(RC_SVCDIR "/scheduled", 0);
- if (dirs) {
- TAILQ_FOREACH (dir, dirs, entries) {
- snprintf(file, sizeof(file),
- RC_SVCDIR "/scheduled/%s/%s",
- dir->value, service);
- if (exists(file)) {
- state |= RC_SERVICE_SCHEDULED;
- break;
- }
+ TAILQ_FOREACH (dir, dirs, entries) {
+ snprintf(file, sizeof(file),
+ RC_SVCDIR "/scheduled/%s/%s",
+ dir->value, service);
+ if (exists(file)) {
+ state |= RC_SERVICE_SCHEDULED;
+ break;
}
- rc_stringlist_free(dirs);
}
+ rc_stringlist_free(dirs);
}
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;
@@ -663,8 +669,9 @@ char *rc_service_value_get(const char *service, const char *option)
}
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 file[PATH_MAX];
@@ -685,8 +692,8 @@ bool rc_service_value_set(const char *service, const char *option,
librc_hidden_def(rc_service_value_set)
-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 file[PATH_MAX];
char *p = file;
@@ -703,32 +710,34 @@ bool rc_service_schedule_start(const char *service,
return false;
init = rc_service_resolve(service_to_start);
- snprintf(p, sizeof(file) - (p - file), "/%s", basename_c(service_to_start));
+ snprintf(p, sizeof(file) - (p - file),
+ "/%s", basename_c(service_to_start));
retval = (exists(file) || symlink(init, file) == 0);
free(init);
-
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[PATH_MAX];
snprintf(dir, sizeof(dir), RC_SVCDIR "/scheduled/%s",
basename_c(service));
- if (! rm_dir(dir, true) && errno == ENOENT)
+ if (!rm_dir(dir, true) && errno == ENOENT)
return true;
return false;
}
librc_hidden_def(rc_service_schedule_clear)
-RC_STRINGLIST *rc_services_in_runlevel(const char *runlevel)
+RC_STRINGLIST *
+rc_services_in_runlevel(const char *runlevel)
{
char dir[PATH_MAX];
- RC_STRINGLIST *list;
+ RC_STRINGLIST *list = NULL;
- if (! runlevel) {
+ if (!runlevel) {
#ifdef RC_PKG_INITDIR
RC_STRINGLIST *pkg = ls_dir(RC_PKG_INITDIR, LS_INITD);
#endif
@@ -739,36 +748,32 @@ RC_STRINGLIST *rc_services_in_runlevel(const char *runlevel)
list = ls_dir(RC_INITDIR, LS_INITD);
#ifdef RC_PKG_INITDIR
- if (pkg) {
- TAILQ_CONCAT(list, pkg, entries);
- free(pkg);
- }
+ TAILQ_CONCAT(list, pkg, entries);
+ free(pkg);
#endif
#ifdef RC_LOCAL_INITDIR
- if (local) {
- TAILQ_CONCAT(list, local, entries);
- free(local);
- }
+ TAILQ_CONCAT(list, local, entries);
+ free(local);
#endif
return list;
}
/* These special levels never contain any services */
- if (strcmp(runlevel, RC_LEVEL_SYSINIT) == 0 ||
- strcmp(runlevel, RC_LEVEL_SINGLE) == 0) {
- return NULL;
+ if (strcmp(runlevel, RC_LEVEL_SINGLE) != 0) {
+ snprintf(dir, sizeof(dir), RC_RUNLEVELDIR "/%s", runlevel);
+ list = ls_dir(dir, LS_INITD);
}
-
- snprintf(dir, sizeof(dir), RC_RUNLEVELDIR "/%s", runlevel);
- list = ls_dir(dir, LS_INITD);
+ if (!list)
+ list = rc_stringlist_new();
return list;
}
librc_hidden_def(rc_services_in_runlevel)
-RC_STRINGLIST *rc_services_in_state(RC_SERVICE state)
+RC_STRINGLIST *
+rc_services_in_state(RC_SERVICE state)
{
RC_STRINGLIST *services;
- RC_STRINGLIST *list = NULL;
+ RC_STRINGLIST *list;
RC_STRINGLIST *dirs;
RC_STRING *d;
char dir[PATH_MAX];
@@ -780,28 +785,26 @@ RC_STRINGLIST *rc_services_in_state(RC_SERVICE state)
if (state != RC_SERVICE_SCHEDULED)
return ls_dir(dir, LS_INITD);
-
dirs = ls_dir(dir, 0);
+ list = rc_stringlist_new();
if (! dirs)
- return NULL;
+ return list;
TAILQ_FOREACH(d, dirs, entries) {
snprintf(p, sizeof(dir) - (p - dir), "/%s", d->value);
services = ls_dir(dir, LS_INITD);
- if (! list)
- services = list;
- else if (services) {
+ if (services) {
TAILQ_CONCAT(list, services, entries);
free(services);
}
}
rc_stringlist_free(dirs);
-
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;
@@ -811,7 +814,7 @@ bool rc_service_add(const char *runlevel, const char *service)
char binit[PATH_MAX];
char *i;
- if (! rc_runlevel_exists(runlevel)) {
+ if (!rc_runlevel_exists(runlevel)) {
errno = ENOENT;
return false;
}
@@ -827,12 +830,11 @@ bool rc_service_add(const char *runlevel, const char *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) {
+ if (strcmp(runlevel, RC_LEVEL_BOOT) == 0) {
p = realpath(dirname(init), path);
- if (! *p) {
+ if (!*p) {
free(init);
return false;
-
}
if (strcmp(path, RC_INITDIR) != 0) {
free(init);
@@ -849,7 +851,8 @@ bool rc_service_add(const char *runlevel, const char *service)
}
librc_hidden_def(rc_service_add)
-bool rc_service_delete (const char *runlevel, const char *service)
+bool
+rc_service_delete(const char *runlevel, const char *service)
{
char file[PATH_MAX];
@@ -861,32 +864,27 @@ bool rc_service_delete (const char *runlevel, const char *service)
}
librc_hidden_def(rc_service_delete)
-RC_STRINGLIST *rc_services_scheduled_by(const char *service)
+RC_STRINGLIST *
+rc_services_scheduled_by(const char *service)
{
RC_STRINGLIST *dirs = ls_dir(RC_SVCDIR "/scheduled", 0);
- RC_STRINGLIST *list = NULL;
+ RC_STRINGLIST *list = rc_stringlist_new();
RC_STRING *dir;
char file[PATH_MAX];
- if (! dirs)
- return NULL;
-
TAILQ_FOREACH (dir, dirs, entries) {
snprintf(file, sizeof(file), RC_SVCDIR "/scheduled/%s/%s",
dir->value, service);
- if (exists(file)) {
- if (! list)
- list = rc_stringlist_new();
+ if (exists(file))
rc_stringlist_add(list, file);
- }
}
rc_stringlist_free(dirs);
-
return list;
}
librc_hidden_def(rc_services_scheduled_by)
-RC_STRINGLIST *rc_services_scheduled(const char *service)
+RC_STRINGLIST *
+rc_services_scheduled(const char *service)
{
char dir[PATH_MAX];