Remove null terminated char ** lists in favour of RC_STRINGLIST, using TAILQ from queue(3). Refactor code style around the BSD KNF.
This commit is contained in:
4
src/librc/.gitignore
vendored
4
src/librc/.gitignore
vendored
@@ -3,12 +3,12 @@ librc.o
|
||||
librc-daemon.o
|
||||
librc-depend.o
|
||||
librc-misc.o
|
||||
librc-strlist.o
|
||||
librc-stringlist.o
|
||||
librc.So
|
||||
librc-daemon.So
|
||||
librc-depend.So
|
||||
librc-misc.So
|
||||
librc-strlist.So
|
||||
librc-stringlist.So
|
||||
librc.a
|
||||
librc.so.1
|
||||
librc.so
|
||||
|
||||
@@ -4,7 +4,7 @@ include ${MK}/os.mk
|
||||
LIB= rc
|
||||
SHLIB_MAJOR= 1
|
||||
SRCS= librc.c librc-daemon.c librc-depend.c librc-misc.c \
|
||||
librc-strlist.c
|
||||
librc-stringlist.c
|
||||
INCS= rc.h
|
||||
VERSION_MAP= rc.map
|
||||
|
||||
|
||||
@@ -32,33 +32,33 @@
|
||||
#include "librc.h"
|
||||
|
||||
#if defined(__linux__)
|
||||
static bool pid_is_cmd (pid_t pid, const char *cmd)
|
||||
static bool pid_is_cmd(pid_t pid, const char *cmd)
|
||||
{
|
||||
char buffer[32];
|
||||
FILE *fp;
|
||||
int c;
|
||||
|
||||
snprintf(buffer, sizeof (buffer), "/proc/%d/stat", pid);
|
||||
if ((fp = fopen (buffer, "r")) == NULL)
|
||||
return (false);
|
||||
snprintf(buffer, sizeof(buffer), "/proc/%d/stat", pid);
|
||||
if ((fp = fopen(buffer, "r")) == NULL)
|
||||
return false;
|
||||
|
||||
while ((c = getc (fp)) != EOF && c != '(')
|
||||
while ((c = getc(fp)) != EOF && c != '(')
|
||||
;
|
||||
|
||||
if (c != '(') {
|
||||
fclose(fp);
|
||||
return (false);
|
||||
return false;
|
||||
}
|
||||
|
||||
while ((c = getc (fp)) != EOF && c == *cmd)
|
||||
while ((c = getc(fp)) != EOF && c == *cmd)
|
||||
cmd++;
|
||||
|
||||
fclose (fp);
|
||||
fclose(fp);
|
||||
|
||||
return ((c == ')' && *cmd == '\0') ? true : false);
|
||||
return (c == ')' && *cmd == '\0') ? true : false;
|
||||
}
|
||||
|
||||
static bool pid_is_exec (pid_t pid, const char *const *argv)
|
||||
static bool pid_is_exec(pid_t pid, const char *const *argv)
|
||||
{
|
||||
char cmdline[32];
|
||||
char buffer[PATH_MAX];
|
||||
@@ -66,31 +66,30 @@ static bool pid_is_exec (pid_t pid, const char *const *argv)
|
||||
int fd = -1;
|
||||
int r;
|
||||
|
||||
/* Check it's the right binary */
|
||||
snprintf (cmdline, sizeof (cmdline), "/proc/%u/exe", pid);
|
||||
memset (buffer, 0, sizeof (buffer));
|
||||
#if 0
|
||||
if (readlink (cmdline, buffer, sizeof (buffer)) != -1) {
|
||||
if (strcmp (exec, buffer) == 0)
|
||||
return (true);
|
||||
if (readlink(cmdline, buffer, sizeof(buffer)) != -1) {
|
||||
if (strcmp(*argv, buffer) == 0)
|
||||
return true;
|
||||
|
||||
/* We should cater for deleted binaries too */
|
||||
if (strlen (buffer) > 10) {
|
||||
p = buffer + (strlen (buffer) - 10);
|
||||
if (strcmp (p, " (deleted)") == 0) {
|
||||
if (strlen(buffer) > 10) {
|
||||
p = buffer + (strlen(buffer) - 10);
|
||||
if (strcmp(p, " (deleted)") == 0) {
|
||||
*p = 0;
|
||||
if (strcmp (buffer, exec) == 0)
|
||||
return (true);
|
||||
if (strcmp(buffer, *argv) == 0)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
snprintf (cmdline, sizeof (cmdline), "/proc/%u/cmdline", pid);
|
||||
if ((fd = open (cmdline, O_RDONLY)) < 0)
|
||||
return (false);
|
||||
snprintf(cmdline, sizeof(cmdline), "/proc/%u/cmdline", pid);
|
||||
if ((fd = open(cmdline, O_RDONLY)) < 0)
|
||||
return false;
|
||||
|
||||
r = read (fd, buffer, sizeof (buffer));
|
||||
close (fd);
|
||||
r = read(fd, buffer, sizeof(buffer));
|
||||
close(fd);
|
||||
|
||||
if (r == -1)
|
||||
return 0;
|
||||
@@ -98,18 +97,18 @@ static bool pid_is_exec (pid_t pid, const char *const *argv)
|
||||
buffer[r] = 0;
|
||||
p = buffer;
|
||||
while (*argv) {
|
||||
if (strcmp (*argv, p) != 0)
|
||||
return (false);
|
||||
if (strcmp(*argv, p) != 0)
|
||||
return false;
|
||||
argv++;
|
||||
p += strlen (p) + 1;
|
||||
p += strlen(p) + 1;
|
||||
if ((unsigned) (p - buffer) > sizeof (buffer))
|
||||
return (false);
|
||||
return false;
|
||||
}
|
||||
return (true);
|
||||
return true;
|
||||
}
|
||||
|
||||
pid_t *rc_find_pids (const char *const *argv, const char *cmd,
|
||||
uid_t uid, pid_t pid)
|
||||
pid_t *rc_find_pids(const char *const *argv, const char *cmd,
|
||||
uid_t uid, pid_t pid)
|
||||
{
|
||||
DIR *procdir;
|
||||
struct dirent *entry;
|
||||
@@ -122,8 +121,8 @@ pid_t *rc_find_pids (const char *const *argv, const char *cmd,
|
||||
pid_t runscript_pid = 0;
|
||||
char *pp;
|
||||
|
||||
if ((procdir = opendir ("/proc")) == NULL)
|
||||
return (NULL);
|
||||
if ((procdir = opendir("/proc")) == NULL)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
We never match RC_RUNSCRIPT_PID if present so we avoid the below
|
||||
@@ -136,13 +135,13 @@ pid_t *rc_find_pids (const char *const *argv, const char *cmd,
|
||||
nasty
|
||||
*/
|
||||
|
||||
if ((pp = getenv ("RC_RUNSCRIPT_PID"))) {
|
||||
if (sscanf (pp, "%d", &runscript_pid) != 1)
|
||||
if ((pp = getenv("RC_RUNSCRIPT_PID"))) {
|
||||
if (sscanf(pp, "%d", &runscript_pid) != 1)
|
||||
runscript_pid = 0;
|
||||
}
|
||||
|
||||
while ((entry = readdir (procdir)) != NULL) {
|
||||
if (sscanf (entry->d_name, "%d", &p) != 1)
|
||||
while ((entry = readdir(procdir)) != NULL) {
|
||||
if (sscanf(entry->d_name, "%d", &p) != 1)
|
||||
continue;
|
||||
|
||||
if (runscript_pid != 0 && runscript_pid == p)
|
||||
@@ -152,23 +151,23 @@ pid_t *rc_find_pids (const char *const *argv, const char *cmd,
|
||||
continue;
|
||||
|
||||
if (uid) {
|
||||
snprintf (buffer, sizeof (buffer), "/proc/%d", p);
|
||||
if (stat (buffer, &sb) != 0 || sb.st_uid != uid)
|
||||
snprintf(buffer, sizeof(buffer), "/proc/%d", p);
|
||||
if (stat(buffer, &sb) != 0 || sb.st_uid != uid)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cmd && ! pid_is_cmd (p, cmd))
|
||||
if (cmd && ! pid_is_cmd(p, cmd))
|
||||
continue;
|
||||
|
||||
if (argv && ! cmd && ! pid_is_exec (p, (const char *const *)argv))
|
||||
if (argv && ! cmd && ! pid_is_exec(p, (const char *const *)argv))
|
||||
continue;
|
||||
|
||||
tmp = realloc (pids, sizeof (pid_t) * (npids + 2));
|
||||
tmp = realloc(pids, sizeof (pid_t) * (npids + 2));
|
||||
if (! tmp) {
|
||||
free (pids);
|
||||
closedir (procdir);
|
||||
free(pids);
|
||||
closedir(procdir);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
return NULL;
|
||||
}
|
||||
pids = tmp;
|
||||
|
||||
@@ -176,9 +175,9 @@ pid_t *rc_find_pids (const char *const *argv, const char *cmd,
|
||||
pids[npids + 1] = 0;
|
||||
npids++;
|
||||
}
|
||||
closedir (procdir);
|
||||
closedir(procdir);
|
||||
|
||||
return (pids);
|
||||
return pids;
|
||||
}
|
||||
librc_hidden_def(rc_find_pids)
|
||||
|
||||
@@ -206,8 +205,8 @@ librc_hidden_def(rc_find_pids)
|
||||
# define _KVM_FLAGS O_RDONLY
|
||||
# endif
|
||||
|
||||
pid_t *rc_find_pids (const char *const *argv, const char *cmd,
|
||||
uid_t uid, pid_t pid)
|
||||
pid_t *rc_find_pids(const char *const *argv, const char *cmd,
|
||||
uid_t uid, pid_t pid)
|
||||
{
|
||||
static kvm_t *kd = NULL;
|
||||
char errbuf[_POSIX2_LINE_MAX];
|
||||
@@ -218,44 +217,45 @@ pid_t *rc_find_pids (const char *const *argv, const char *cmd,
|
||||
char **pargv;
|
||||
pid_t *pids = NULL;
|
||||
pid_t *tmp;
|
||||
pid_t p;
|
||||
const char *const *arg;
|
||||
int npids = 0;
|
||||
int match;
|
||||
|
||||
if ((kd = kvm_openfiles (_KVM_PATH, _KVM_PATH,
|
||||
NULL, _KVM_FLAGS, errbuf)) == NULL)
|
||||
if ((kd = kvm_openfiles(_KVM_PATH, _KVM_PATH,
|
||||
NULL, _KVM_FLAGS, errbuf)) == NULL)
|
||||
{
|
||||
fprintf (stderr, "kvm_open: %s\n", errbuf);
|
||||
return (NULL);
|
||||
fprintf(stderr, "kvm_open: %s\n", errbuf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef _KVM_GETPROC2
|
||||
kp = kvm_getproc2 (kd, KERN_PROC_ALL, 0, sizeof(*kp), &processes);
|
||||
kp = kvm_getproc2(kd, KERN_PROC_ALL, 0, sizeof(*kp), &processes);
|
||||
#else
|
||||
kp = kvm_getprocs (kd, KERN_PROC_PROC, 0, &processes);
|
||||
kp = kvm_getprocs(kd, KERN_PROC_PROC, 0, &processes);
|
||||
#endif
|
||||
if ((kp == NULL && processes > 0) || (kp != NULL && processes < 0)) {
|
||||
fprintf (stderr, "kvm_getprocs: %s\n", kvm_geterr (kd));
|
||||
kvm_close (kd);
|
||||
return (NULL);
|
||||
fprintf(stderr, "kvm_getprocs: %s\n", kvm_geterr(kd));
|
||||
kvm_close(kd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < processes; i++) {
|
||||
pid_t p = _GET_KINFO_PID (kp[i]);
|
||||
p = _GET_KINFO_PID(kp[i]);
|
||||
if (pid != 0 && pid != p)
|
||||
continue;
|
||||
|
||||
if (uid != 0 && uid != _GET_KINFO_UID (kp[i]))
|
||||
if (uid != 0 && uid != _GET_KINFO_UID(kp[i]))
|
||||
continue;
|
||||
|
||||
if (cmd) {
|
||||
if (! _GET_KINFO_COMM (kp[i]) ||
|
||||
strcmp (cmd, _GET_KINFO_COMM (kp[i])) != 0)
|
||||
if (! _GET_KINFO_COMM(kp[i]) ||
|
||||
strcmp(cmd, _GET_KINFO_COMM(kp[i])) != 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (argv && *argv && ! cmd) {
|
||||
pargv = _KVM_GETARGV (kd, &kp[i], pargc);
|
||||
pargv = _KVM_GETARGV(kd, &kp[i], pargc);
|
||||
if (! pargv || ! *pargv)
|
||||
continue;
|
||||
|
||||
@@ -263,7 +263,7 @@ pid_t *rc_find_pids (const char *const *argv, const char *cmd,
|
||||
match = 1;
|
||||
|
||||
while (*arg && *pargv)
|
||||
if (strcmp (*arg++, *pargv++) != 0) {
|
||||
if (strcmp(*arg++, *pargv++) != 0) {
|
||||
match = 0;
|
||||
break;
|
||||
}
|
||||
@@ -272,12 +272,12 @@ pid_t *rc_find_pids (const char *const *argv, const char *cmd,
|
||||
continue;
|
||||
}
|
||||
|
||||
tmp = realloc (pids, sizeof (pid_t) * (npids + 2));
|
||||
tmp = realloc(pids, sizeof(pid_t) * (npids + 2));
|
||||
if (! tmp) {
|
||||
free (pids);
|
||||
kvm_close (kd);
|
||||
free(pids);
|
||||
kvm_close(kd);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
return NULL;
|
||||
}
|
||||
pids = tmp;
|
||||
|
||||
@@ -285,9 +285,9 @@ pid_t *rc_find_pids (const char *const *argv, const char *cmd,
|
||||
pids[npids + 1] = 0;
|
||||
npids++;
|
||||
}
|
||||
kvm_close (kd);
|
||||
kvm_close(kd);
|
||||
|
||||
return (pids);
|
||||
return pids;
|
||||
}
|
||||
librc_hidden_def(rc_find_pids)
|
||||
|
||||
@@ -295,67 +295,72 @@ librc_hidden_def(rc_find_pids)
|
||||
# error "Platform not supported!"
|
||||
#endif
|
||||
|
||||
static bool _match_daemon (const char *path, const char *file, char **match)
|
||||
static bool _match_daemon(const char *path, const char *file,
|
||||
RC_STRINGLIST *match)
|
||||
{
|
||||
char *line;
|
||||
char *ffile = rc_strcatpaths (path, file, (char *) NULL);
|
||||
char *ffile = rc_strcatpaths(path, file, (char *) NULL);
|
||||
FILE *fp;
|
||||
RC_STRING *m;
|
||||
|
||||
fp = fopen (ffile, "r");
|
||||
free (ffile);
|
||||
fp = fopen(ffile, "r");
|
||||
free(ffile);
|
||||
|
||||
if (! fp)
|
||||
return (false);
|
||||
return false;
|
||||
|
||||
while ((line = rc_getline (fp))) {
|
||||
rc_strlist_delete (&match, line);
|
||||
if (! match || !*match)
|
||||
while ((line = rc_getline(fp))) {
|
||||
TAILQ_FOREACH(m, match, entries)
|
||||
if (strcmp(line, m->value) == 0) {
|
||||
TAILQ_REMOVE(match, m, entries);
|
||||
break;
|
||||
}
|
||||
if (! TAILQ_FIRST(match))
|
||||
break;
|
||||
}
|
||||
fclose (fp);
|
||||
if (match && *match)
|
||||
return (false);
|
||||
return (true);
|
||||
fclose(fp);
|
||||
if (TAILQ_FIRST(match))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static char **_match_list (const char* const* argv,
|
||||
const char *name, const char *pidfile)
|
||||
static RC_STRINGLIST *_match_list(const char* const* argv,
|
||||
const char *name, const char *pidfile)
|
||||
{
|
||||
char **match = NULL;
|
||||
RC_STRINGLIST *match = rc_stringlist_new();
|
||||
int i = 0;
|
||||
size_t l;
|
||||
char *m;
|
||||
|
||||
while (argv && argv[i]) {
|
||||
l = strlen (*argv) + strlen ("argv_=") + 16;
|
||||
m = xmalloc (sizeof (char) * l);
|
||||
snprintf (m, l, "argv_0=%s", argv[i++]);
|
||||
rc_strlist_add (&match, m);
|
||||
free (m);
|
||||
l = strlen(*argv) + strlen("argv_=") + 16;
|
||||
m = xmalloc(sizeof(char) * l);
|
||||
snprintf(m, l, "argv_0=%s", argv[i++]);
|
||||
rc_stringlist_add(match, m);
|
||||
free(m);
|
||||
}
|
||||
|
||||
if (name) {
|
||||
l = strlen (name) + 6;
|
||||
m = xmalloc (sizeof (char) * l);
|
||||
snprintf (m, l, "name=%s", name);
|
||||
rc_strlist_add (&match, m);
|
||||
free (m);
|
||||
l = strlen(name) + 6;
|
||||
m = xmalloc(sizeof (char) * l);
|
||||
snprintf(m, l, "name=%s", name);
|
||||
rc_stringlist_add(match, m);
|
||||
free(m);
|
||||
}
|
||||
|
||||
if (pidfile) {
|
||||
l = strlen (pidfile) + 9;
|
||||
m = xmalloc (sizeof (char) * l);
|
||||
snprintf (m, l, "pidfile=%s", pidfile);
|
||||
rc_strlist_add (&match, m);
|
||||
l = strlen(pidfile) + 9;
|
||||
m = xmalloc(sizeof (char) * l);
|
||||
snprintf(m, l, "pidfile=%s", pidfile);
|
||||
rc_stringlist_add(match, m);
|
||||
free (m);
|
||||
}
|
||||
|
||||
return (match);
|
||||
return match;
|
||||
}
|
||||
|
||||
bool rc_service_daemon_set (const char *service, const char *const *argv,
|
||||
const char *name, const char *pidfile,
|
||||
bool started)
|
||||
bool rc_service_daemon_set(const char *service, const char *const *argv,
|
||||
const char *name, const char *pidfile, bool started)
|
||||
{
|
||||
char *dirpath;
|
||||
char *file = NULL;
|
||||
@@ -364,123 +369,123 @@ bool rc_service_daemon_set (const char *service, const char *const *argv,
|
||||
bool retval = false;
|
||||
DIR *dp;
|
||||
struct dirent *d;
|
||||
char **match = NULL;
|
||||
RC_STRINGLIST *match;
|
||||
int i = 0;
|
||||
char buffer[10];
|
||||
FILE *fp;
|
||||
|
||||
if (! (argv && *argv) && ! name && ! pidfile) {
|
||||
if (!(argv && *argv) && ! name && ! pidfile) {
|
||||
errno = EINVAL;
|
||||
return (false);
|
||||
return false;
|
||||
}
|
||||
|
||||
dirpath = rc_strcatpaths (RC_SVCDIR, "daemons",
|
||||
basename_c (service), (char *) NULL);
|
||||
dirpath = rc_strcatpaths(RC_SVCDIR, "daemons",
|
||||
basename_c(service), (char *) NULL);
|
||||
|
||||
match = _match_list (argv, name, pidfile);
|
||||
match = _match_list(argv, name, pidfile);
|
||||
|
||||
/* Regardless, erase any existing daemon info */
|
||||
if ((dp = opendir (dirpath))) {
|
||||
while ((d = readdir (dp))) {
|
||||
if ((dp = opendir(dirpath))) {
|
||||
while ((d = readdir(dp))) {
|
||||
if (d->d_name[0] == '.')
|
||||
continue;
|
||||
file = rc_strcatpaths (dirpath, d->d_name, (char *) NULL);
|
||||
file = rc_strcatpaths(dirpath, d->d_name, (char *) NULL);
|
||||
nfiles++;
|
||||
|
||||
if (! oldfile) {
|
||||
if (_match_daemon (dirpath, d->d_name, match)) {
|
||||
if (_match_daemon(dirpath, d->d_name, match)) {
|
||||
unlink (file);
|
||||
oldfile = file;
|
||||
nfiles--;
|
||||
}
|
||||
} else {
|
||||
rename (file, oldfile);
|
||||
free (oldfile);
|
||||
rename(file, oldfile);
|
||||
free(oldfile);
|
||||
oldfile = file;
|
||||
}
|
||||
}
|
||||
free (file);
|
||||
closedir (dp);
|
||||
free(file);
|
||||
closedir(dp);
|
||||
}
|
||||
|
||||
/* Now store our daemon info */
|
||||
if (started) {
|
||||
char buffer[10];
|
||||
FILE *fp;
|
||||
|
||||
if (mkdir (dirpath, 0755) == 0 || errno == EEXIST) {
|
||||
snprintf (buffer, sizeof (buffer), "%03d", nfiles + 1);
|
||||
file = rc_strcatpaths (dirpath, buffer, (char *) NULL);
|
||||
if ((fp = fopen (file, "w"))) {
|
||||
if (mkdir(dirpath, 0755) == 0 || errno == EEXIST) {
|
||||
snprintf(buffer, sizeof(buffer), "%03d", nfiles + 1);
|
||||
file = rc_strcatpaths(dirpath, buffer, (char *) NULL);
|
||||
if ((fp = fopen(file, "w"))) {
|
||||
while (argv && argv[i]) {
|
||||
fprintf (fp, "argv_%d=%s\n", i, argv[i]);
|
||||
fprintf(fp, "argv_%d=%s\n", i, argv[i]);
|
||||
i++;
|
||||
}
|
||||
fprintf (fp, "name=");
|
||||
fprintf(fp, "name=");
|
||||
if (name)
|
||||
fprintf (fp, "%s", name);
|
||||
fprintf (fp, "\npidfile=");
|
||||
fprintf(fp, "%s", name);
|
||||
fprintf(fp, "\npidfile=");
|
||||
if (pidfile)
|
||||
fprintf (fp, "%s", pidfile);
|
||||
fprintf (fp, "\n");
|
||||
fclose (fp);
|
||||
fprintf(fp, "%s", pidfile);
|
||||
fprintf(fp, "\n");
|
||||
fclose(fp);
|
||||
retval = true;
|
||||
}
|
||||
free (file);
|
||||
free(file);
|
||||
}
|
||||
} else
|
||||
retval = true;
|
||||
|
||||
rc_strlist_free (match);
|
||||
free (dirpath);
|
||||
rc_stringlist_free(match);
|
||||
free(dirpath);
|
||||
|
||||
return (retval);
|
||||
return retval;
|
||||
}
|
||||
librc_hidden_def(rc_service_daemon_set)
|
||||
|
||||
bool rc_service_started_daemon (const char *service, const char *const *argv,
|
||||
int indx)
|
||||
bool
|
||||
rc_service_started_daemon (const char *service, const char *const *argv,
|
||||
int indx)
|
||||
{
|
||||
char *dirpath;
|
||||
char *file;
|
||||
size_t l;
|
||||
char **match;
|
||||
RC_STRINGLIST *match;
|
||||
bool retval = false;
|
||||
DIR *dp;
|
||||
struct dirent *d;
|
||||
|
||||
if (! service || ! (argv && *argv))
|
||||
return (false);
|
||||
if (!service || !(argv && *argv))
|
||||
return false;
|
||||
|
||||
dirpath = rc_strcatpaths (RC_SVCDIR, "daemons", basename_c (service),
|
||||
(char *) NULL);
|
||||
dirpath = rc_strcatpaths(RC_SVCDIR, "daemons", basename_c(service),
|
||||
(char *) NULL);
|
||||
|
||||
match = _match_list (argv, NULL, NULL);
|
||||
match = _match_list(argv, NULL, NULL);
|
||||
|
||||
if (indx > 0) {
|
||||
l = sizeof (char) * 10;
|
||||
file = xmalloc (l);
|
||||
snprintf (file, l, "%03d", indx);
|
||||
retval = _match_daemon (dirpath, file, match);
|
||||
free (file);
|
||||
file = xmalloc(l);
|
||||
snprintf(file, l, "%03d", indx);
|
||||
retval = _match_daemon(dirpath, file, match);
|
||||
free(file);
|
||||
} else {
|
||||
if ((dp = opendir (dirpath))) {
|
||||
while ((d = readdir (dp))) {
|
||||
if ((dp = opendir(dirpath))) {
|
||||
while ((d = readdir(dp))) {
|
||||
if (d->d_name[0] == '.')
|
||||
continue;
|
||||
retval = _match_daemon (dirpath, d->d_name, match);
|
||||
retval = _match_daemon(dirpath, d->d_name, match);
|
||||
if (retval)
|
||||
break;
|
||||
}
|
||||
closedir (dp);
|
||||
closedir(dp);
|
||||
}
|
||||
}
|
||||
|
||||
free (dirpath);
|
||||
rc_strlist_free (match);
|
||||
return (retval);
|
||||
free(dirpath);
|
||||
rc_stringlist_free(match);
|
||||
return retval;
|
||||
}
|
||||
librc_hidden_def(rc_service_started_daemon)
|
||||
|
||||
bool rc_service_daemons_crashed (const char *service)
|
||||
bool rc_service_daemons_crashed(const char *service)
|
||||
{
|
||||
char *dirpath;
|
||||
DIR *dp;
|
||||
@@ -497,116 +502,123 @@ bool rc_service_daemons_crashed (const char *service)
|
||||
char *p;
|
||||
char *token;
|
||||
bool retval = false;
|
||||
RC_STRINGLIST *list;
|
||||
RC_STRING *s;
|
||||
size_t i;
|
||||
|
||||
if (! service)
|
||||
return (false);
|
||||
dirpath = rc_strcatpaths(RC_SVCDIR, "daemons", basename_c(service),
|
||||
(char *) NULL);
|
||||
|
||||
dirpath = rc_strcatpaths (RC_SVCDIR, "daemons", basename_c (service),
|
||||
(char *) NULL);
|
||||
|
||||
if (! (dp = opendir (dirpath))) {
|
||||
free (dirpath);
|
||||
return (false);
|
||||
if (! (dp = opendir(dirpath))) {
|
||||
free(dirpath);
|
||||
return false;
|
||||
}
|
||||
|
||||
while ((d = readdir (dp))) {
|
||||
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);
|
||||
path = rc_strcatpaths(dirpath, d->d_name, (char *) NULL);
|
||||
fp = fopen(path, "r");
|
||||
free(path);
|
||||
if (! fp)
|
||||
break;
|
||||
|
||||
while ((line = rc_getline (fp))) {
|
||||
list = rc_stringlist_new();
|
||||
|
||||
while ((line = rc_getline(fp))) {
|
||||
p = line;
|
||||
if ((token = strsep (&p, "=")) == NULL || ! p) {
|
||||
free (line);
|
||||
if ((token = strsep(&p, "=")) == NULL || ! p) {
|
||||
free(line);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strlen (p) == 0) {
|
||||
free (line);
|
||||
if (! *p) {
|
||||
free(line);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strncmp (token, "argv_", 5) == 0) {
|
||||
rc_strlist_add (&argv, p);
|
||||
} else if (strcmp (token, "exec") == 0) {
|
||||
if (strncmp(token, "argv_", 5) == 0) {
|
||||
rc_stringlist_add(list, p);
|
||||
} else if (strcmp(token, "exec") == 0) {
|
||||
if (exec)
|
||||
free (exec);
|
||||
exec = xstrdup (p);
|
||||
} else if (strcmp (token, "name") == 0) {
|
||||
free(exec);
|
||||
exec = xstrdup(p);
|
||||
} else if (strcmp(token, "name") == 0) {
|
||||
if (name)
|
||||
free (name);
|
||||
name = xstrdup (p);
|
||||
} else if (strcmp (token, "pidfile") == 0) {
|
||||
free(name);
|
||||
name = xstrdup(p);
|
||||
} else if (strcmp(token, "pidfile") == 0) {
|
||||
if (pidfile)
|
||||
free (pidfile);
|
||||
pidfile = xstrdup (p);
|
||||
free(pidfile);
|
||||
pidfile = xstrdup(p);
|
||||
}
|
||||
free (line);
|
||||
free(line);
|
||||
}
|
||||
fclose (fp);
|
||||
fclose(fp);
|
||||
|
||||
pid = 0;
|
||||
if (pidfile) {
|
||||
if (! exists (pidfile)) {
|
||||
if (! exists(pidfile)) {
|
||||
retval = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((fp = fopen (pidfile, "r")) == NULL) {
|
||||
if ((fp = fopen(pidfile, "r")) == NULL) {
|
||||
retval = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (fscanf (fp, "%d", &pid) != 1) {
|
||||
if (fscanf(fp, "%d", &pid) != 1) {
|
||||
fclose (fp);
|
||||
retval = true;
|
||||
break;
|
||||
}
|
||||
|
||||
fclose (fp);
|
||||
free (pidfile);
|
||||
fclose(fp);
|
||||
free(pidfile);
|
||||
pidfile = NULL;
|
||||
|
||||
/* We have the pid, so no need to match on name */
|
||||
rc_strlist_free (argv);
|
||||
argv = NULL;
|
||||
rc_stringlist_free(list);
|
||||
list = NULL;
|
||||
free (exec);
|
||||
exec = NULL;
|
||||
free (name);
|
||||
name = NULL;
|
||||
}
|
||||
|
||||
if (exec && ! argv) {
|
||||
rc_strlist_add (&argv, exec);
|
||||
free (exec);
|
||||
} else {
|
||||
if (exec && ! TAILQ_FIRST(list)) {
|
||||
rc_stringlist_add(list, exec);
|
||||
}
|
||||
free(exec);
|
||||
exec = NULL;
|
||||
|
||||
/* We need to flatten our linked list into an array */
|
||||
i = 0;
|
||||
TAILQ_FOREACH(s, list, entries)
|
||||
i++;
|
||||
argv = xmalloc(sizeof(char *) * (i + 1));
|
||||
i = 0;
|
||||
TAILQ_FOREACH(s, list, entries)
|
||||
argv[i++] = s->value;
|
||||
argv[i] = '\0';
|
||||
}
|
||||
|
||||
if ((pids = rc_find_pids ((const char *const *)argv, name, 0, pid)) == NULL) {
|
||||
if ((pids = rc_find_pids((const char *const *)argv, name, 0, pid)) == NULL)
|
||||
retval = true;
|
||||
break;
|
||||
}
|
||||
free (pids);
|
||||
|
||||
rc_strlist_free (argv);
|
||||
free(pids);
|
||||
free(argv);
|
||||
argv = NULL;
|
||||
free (exec);
|
||||
exec = NULL;
|
||||
free (name);
|
||||
rc_stringlist_free(list);
|
||||
free(name);
|
||||
name = NULL;
|
||||
if (retval)
|
||||
break;
|
||||
}
|
||||
|
||||
rc_strlist_free (argv);
|
||||
free (exec);
|
||||
free (name);
|
||||
free (dirpath);
|
||||
closedir (dp);
|
||||
free(dirpath);
|
||||
closedir(dp);
|
||||
|
||||
return (retval);
|
||||
return retval;
|
||||
}
|
||||
librc_hidden_def(rc_service_daemons_crashed)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* librc-depend.h
|
||||
* Internal header file for dependency structures
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2007-2008 Roy Marples
|
||||
* All rights reserved
|
||||
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LIBRC_DEPEND_H
|
||||
#define _LIBRC_DEPEND_H
|
||||
|
||||
/*! @name Dependency structures
|
||||
* private to librc - rc.h exposes them just a pointers */
|
||||
|
||||
/*! Singly linked list of dependency types that list the services the
|
||||
* type is for */
|
||||
typedef struct rc_deptype
|
||||
{
|
||||
/*! ineed, iuse, iafter, etc */
|
||||
char *type;
|
||||
/*! NULL terminated list of services */
|
||||
char **services;
|
||||
/*! Next dependency type */
|
||||
struct rc_deptype *next;
|
||||
} rc_deptype_t;
|
||||
|
||||
/*! Singly linked list of services and their dependencies */
|
||||
typedef struct rc_depinfo
|
||||
{
|
||||
/*! Name of service */
|
||||
char *service;
|
||||
/*! Dependencies */
|
||||
rc_deptype_t *depends;
|
||||
/*! Next service dependency type */
|
||||
struct rc_depinfo *next;
|
||||
} rc_depinfo_t;
|
||||
|
||||
#endif
|
||||
@@ -35,14 +35,14 @@ bool rc_yesno (const char *value)
|
||||
{
|
||||
if (! value) {
|
||||
errno = ENOENT;
|
||||
return (false);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strcasecmp (value, "yes") == 0 ||
|
||||
strcasecmp (value, "y") == 0 ||
|
||||
strcasecmp (value, "true") == 0 ||
|
||||
strcasecmp (value, "1") == 0)
|
||||
return (true);
|
||||
return true;
|
||||
|
||||
if (strcasecmp (value, "no") != 0 &&
|
||||
strcasecmp (value, "n") != 0 &&
|
||||
@@ -50,7 +50,7 @@ bool rc_yesno (const char *value)
|
||||
strcasecmp (value, "0") != 0)
|
||||
errno = EINVAL;
|
||||
|
||||
return (false);
|
||||
return false;
|
||||
}
|
||||
librc_hidden_def(rc_yesno)
|
||||
|
||||
@@ -64,7 +64,7 @@ char *rc_strcatpaths (const char *path1, const char *paths, ...)
|
||||
char *pathp;
|
||||
|
||||
if (! path1 || ! paths)
|
||||
return (NULL);
|
||||
return NULL;
|
||||
|
||||
length = strlen (path1) + strlen (paths) + 1;
|
||||
if (*paths != '/')
|
||||
@@ -101,7 +101,7 @@ char *rc_strcatpaths (const char *path1, const char *paths, ...)
|
||||
|
||||
*pathp++ = 0;
|
||||
|
||||
return (path);
|
||||
return path;
|
||||
}
|
||||
librc_hidden_def(rc_strcatpaths)
|
||||
|
||||
@@ -113,7 +113,7 @@ char *rc_getline (FILE *fp)
|
||||
size_t last = 0;
|
||||
|
||||
if (feof (fp))
|
||||
return (NULL);
|
||||
return NULL;
|
||||
|
||||
do {
|
||||
len += BUFSIZ;
|
||||
@@ -128,74 +128,78 @@ char *rc_getline (FILE *fp)
|
||||
if (*line && line[--last] == '\n')
|
||||
line[last] = '\0';
|
||||
|
||||
return (line);
|
||||
return line;
|
||||
}
|
||||
librc_hidden_def(rc_getline)
|
||||
|
||||
char **rc_config_list (const char *file)
|
||||
RC_STRINGLIST *rc_config_list(const char *file)
|
||||
{
|
||||
FILE *fp;
|
||||
char *buffer;
|
||||
char *p;
|
||||
char *token;
|
||||
char **list = NULL;
|
||||
RC_STRINGLIST *list;
|
||||
|
||||
if (! (fp = fopen (file, "r")))
|
||||
return (NULL);
|
||||
if (!(fp = fopen(file, "r")))
|
||||
return NULL;
|
||||
|
||||
while ((p = buffer = rc_getline (fp))) {
|
||||
list = rc_stringlist_new();
|
||||
|
||||
while ((p = buffer = rc_getline(fp))) {
|
||||
/* Strip leading spaces/tabs */
|
||||
while ((*p == ' ') || (*p == '\t'))
|
||||
p++;
|
||||
|
||||
/* Get entry - we do not want comments */
|
||||
token = strsep (&p, "#");
|
||||
if (token && (strlen (token) > 1)) {
|
||||
token = strsep(&p, "#");
|
||||
if (token && (strlen(token) > 1)) {
|
||||
/* If not variable assignment then skip */
|
||||
if (strchr (token, '=')) {
|
||||
if (strchr(token, '=')) {
|
||||
/* Stip the newline if present */
|
||||
if (token[strlen (token) - 1] == '\n')
|
||||
token[strlen (token) - 1] = 0;
|
||||
if (token[strlen(token) - 1] == '\n')
|
||||
token[strlen(token) - 1] = 0;
|
||||
|
||||
rc_strlist_add (&list, token);
|
||||
rc_stringlist_add(list, token);
|
||||
}
|
||||
}
|
||||
free (buffer);
|
||||
free(buffer);
|
||||
}
|
||||
fclose (fp);
|
||||
fclose(fp);
|
||||
|
||||
return (list);
|
||||
return list;
|
||||
}
|
||||
librc_hidden_def(rc_config_list)
|
||||
|
||||
char **rc_config_load (const char *file)
|
||||
RC_STRINGLIST *rc_config_load(const char *file)
|
||||
{
|
||||
char **list = NULL;
|
||||
char **config = NULL;
|
||||
RC_STRINGLIST *list = NULL;
|
||||
RC_STRINGLIST *config = NULL;
|
||||
char *token;
|
||||
char *line;
|
||||
char *linep;
|
||||
char *linetok;
|
||||
RC_STRING *line;
|
||||
RC_STRING *cline;
|
||||
size_t i = 0;
|
||||
int j;
|
||||
bool replaced;
|
||||
char *entry;
|
||||
char *newline;
|
||||
char *p;
|
||||
|
||||
list = rc_config_list (file);
|
||||
STRLIST_FOREACH (list, line, j) {
|
||||
config = rc_stringlist_new();
|
||||
|
||||
list = rc_config_list(file);
|
||||
TAILQ_FOREACH(line, list, entries) {
|
||||
/* Get entry */
|
||||
if (! (token = strsep (&line, "=")))
|
||||
p = line->value;
|
||||
if (! (token = strsep(&p, "=")))
|
||||
continue;
|
||||
|
||||
entry = xstrdup (token);
|
||||
/* Preserve shell coloring */
|
||||
if (*line == '$')
|
||||
token = line;
|
||||
if (*p == '$')
|
||||
token = line->value;
|
||||
else
|
||||
do {
|
||||
/* Bash variables are usually quoted */
|
||||
token = strsep (&line, "\"\'");
|
||||
token = strsep(&p, "\"\'");
|
||||
} while (token && *token == '\0');
|
||||
|
||||
/* Drop a newline if that's all we have */
|
||||
@@ -205,57 +209,54 @@ char **rc_config_load (const char *file)
|
||||
token[i] = 0;
|
||||
|
||||
i = strlen (entry) + strlen (token) + 2;
|
||||
newline = xmalloc (sizeof (char) * i);
|
||||
snprintf (newline, i, "%s=%s", entry, token);
|
||||
newline = xmalloc(sizeof(char) * i);
|
||||
snprintf(newline, i, "%s=%s", entry, token);
|
||||
} else {
|
||||
i = strlen (entry) + 2;
|
||||
newline = xmalloc (sizeof (char) * i);
|
||||
snprintf (newline, i, "%s=", entry);
|
||||
newline = xmalloc(sizeof(char) * i);
|
||||
snprintf(newline, i, "%s=", entry);
|
||||
}
|
||||
|
||||
replaced = false;
|
||||
/* In shells the last item takes precedence, so we need to remove
|
||||
any prior values we may already have */
|
||||
STRLIST_FOREACH (config, line, i) {
|
||||
char *tmp = xstrdup (line);
|
||||
linep = tmp;
|
||||
linetok = strsep (&linep, "=");
|
||||
if (strcmp (linetok, entry) == 0) {
|
||||
TAILQ_FOREACH(cline, config, entries) {
|
||||
p = strchr(cline->value, '=');
|
||||
if (p && strncmp(entry, cline->value,
|
||||
(size_t) (p - cline->value)) == 0)
|
||||
{
|
||||
/* We have a match now - to save time we directly replace it */
|
||||
free (config[i - 1]);
|
||||
config[i - 1] = newline;
|
||||
free(cline->value);
|
||||
cline->value = newline;
|
||||
replaced = true;
|
||||
free (tmp);
|
||||
break;
|
||||
}
|
||||
free (tmp);
|
||||
}
|
||||
|
||||
if (! replaced) {
|
||||
rc_strlist_addsort (&config, newline);
|
||||
free (newline);
|
||||
rc_stringlist_add(config, newline);
|
||||
free(newline);
|
||||
}
|
||||
free (entry);
|
||||
free(entry);
|
||||
}
|
||||
rc_strlist_free (list);
|
||||
rc_stringlist_free(list);
|
||||
|
||||
return (config);
|
||||
return config;
|
||||
}
|
||||
librc_hidden_def(rc_config_load)
|
||||
|
||||
char *rc_config_value (const char *const *list, const char *entry)
|
||||
char *rc_config_value(RC_STRINGLIST *list, const char *entry)
|
||||
{
|
||||
const char *line;
|
||||
int i;
|
||||
RC_STRING *line;
|
||||
char *p;
|
||||
|
||||
STRLIST_FOREACH (list, line, i) {
|
||||
p = strchr (line, '=');
|
||||
if (p && strncmp (entry, line, (size_t) (p - line)) == 0)
|
||||
return (p += 1);
|
||||
TAILQ_FOREACH(line, list, entries) {
|
||||
p = strchr(line->value, '=');
|
||||
if (p &&
|
||||
strncmp(entry, line->value, (size_t)(p - line->value)) == 0)
|
||||
return p += 1;
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
return NULL;
|
||||
}
|
||||
librc_hidden_def(rc_config_value)
|
||||
|
||||
|
||||
@@ -1,230 +0,0 @@
|
||||
/*
|
||||
librc-strlist.h
|
||||
String list functions for using char ** arrays
|
||||
|
||||
Based on a previous implementation by Martin Schlemmer
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2007-2008 Roy Marples
|
||||
* All rights reserved
|
||||
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "librc.h"
|
||||
|
||||
static char *_rc_strlist_add (char ***list, const char *item, bool uniq)
|
||||
{
|
||||
char **newlist;
|
||||
char **lst = *list;
|
||||
int i = 0;
|
||||
|
||||
if (! item)
|
||||
return (NULL);
|
||||
|
||||
while (lst && lst[i]) {
|
||||
if (uniq && strcmp (lst[i], item) == 0) {
|
||||
errno = EEXIST;
|
||||
return (NULL);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
newlist = xrealloc (lst, sizeof (char *) * (i + 2));
|
||||
newlist[i] = xstrdup (item);
|
||||
newlist[i + 1] = NULL;
|
||||
|
||||
*list = newlist;
|
||||
return (newlist[i]);
|
||||
}
|
||||
|
||||
char *rc_strlist_add (char ***list, const char *item)
|
||||
{
|
||||
return (_rc_strlist_add (list, item, false));
|
||||
}
|
||||
librc_hidden_def(rc_strlist_add)
|
||||
|
||||
char *rc_strlist_addu (char ***list, const char *item)
|
||||
{
|
||||
return (_rc_strlist_add (list, item, true));
|
||||
}
|
||||
librc_hidden_def(rc_strlist_addu)
|
||||
|
||||
static char *_rc_strlist_addsort (char ***list, const char *item,
|
||||
int (*sortfunc) (const char *s1,
|
||||
const char *s2),
|
||||
bool uniq)
|
||||
{
|
||||
char **newlist;
|
||||
char **lst = *list;
|
||||
int i = 0;
|
||||
char *tmp1;
|
||||
char *tmp2;
|
||||
char *retval;
|
||||
|
||||
if (! item)
|
||||
return (NULL);
|
||||
|
||||
while (lst && lst[i]) {
|
||||
if (uniq && strcmp (lst[i], item) == 0) {
|
||||
errno = EEXIST;
|
||||
return (NULL);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
newlist = xrealloc (lst, sizeof (char *) * (i + 2));
|
||||
|
||||
if (! i)
|
||||
newlist[i] = NULL;
|
||||
newlist[i + 1] = NULL;
|
||||
|
||||
i = 0;
|
||||
while (newlist[i] && sortfunc (newlist[i], item) < 0)
|
||||
i++;
|
||||
|
||||
tmp1 = newlist[i];
|
||||
retval = newlist[i] = xstrdup (item);
|
||||
do {
|
||||
i++;
|
||||
tmp2 = newlist[i];
|
||||
newlist[i] = tmp1;
|
||||
tmp1 = tmp2;
|
||||
} while (tmp1);
|
||||
|
||||
*list = newlist;
|
||||
return (retval);
|
||||
}
|
||||
|
||||
char *rc_strlist_addsort (char ***list, const char *item)
|
||||
{
|
||||
return (_rc_strlist_addsort (list, item, strcoll, false));
|
||||
}
|
||||
librc_hidden_def(rc_strlist_addsort)
|
||||
|
||||
char *rc_strlist_addsortc (char ***list, const char *item)
|
||||
{
|
||||
return (_rc_strlist_addsort (list, item, strcmp, false));
|
||||
}
|
||||
librc_hidden_def(rc_strlist_addsortc)
|
||||
|
||||
char *rc_strlist_addsortu (char ***list, const char *item)
|
||||
{
|
||||
return (_rc_strlist_addsort (list, item, strcmp, true));
|
||||
}
|
||||
librc_hidden_def(rc_strlist_addsortu)
|
||||
|
||||
bool rc_strlist_delete (char ***list, const char *item)
|
||||
{
|
||||
char **lst = *list;
|
||||
int i = 0;
|
||||
|
||||
if (!lst || ! item)
|
||||
return (false);
|
||||
|
||||
while (lst[i]) {
|
||||
if (strcmp (lst[i], item) == 0) {
|
||||
free (lst[i]);
|
||||
do {
|
||||
lst[i] = lst[i + 1];
|
||||
i++;
|
||||
} while (lst[i]);
|
||||
return (true);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
errno = ENOENT;
|
||||
return (false);
|
||||
}
|
||||
librc_hidden_def(rc_strlist_delete)
|
||||
|
||||
char *rc_strlist_join (char ***list1, char **list2)
|
||||
{
|
||||
char **lst1 = *list1;
|
||||
char **newlist;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
|
||||
if (! list2)
|
||||
return (NULL);
|
||||
|
||||
while (lst1 && lst1[i])
|
||||
i++;
|
||||
|
||||
while (list2[j])
|
||||
j++;
|
||||
|
||||
newlist = xrealloc (lst1, sizeof (char *) * (i + j + 1));
|
||||
|
||||
j = 0;
|
||||
while (list2[j]) {
|
||||
newlist[i] = list2[j];
|
||||
/* Take the item off the 2nd list as it's only a shallow copy */
|
||||
list2[j] = NULL;
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
newlist[i] = NULL;
|
||||
|
||||
*list1 = newlist;
|
||||
return (newlist[i == 0 ? 0 : i - 1]);
|
||||
}
|
||||
librc_hidden_def(rc_strlist_join)
|
||||
|
||||
void rc_strlist_reverse (char **list)
|
||||
{
|
||||
char *item;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
|
||||
if (! list)
|
||||
return;
|
||||
|
||||
while (list[j])
|
||||
j++;
|
||||
j--;
|
||||
|
||||
while (i < j && list[i] && list[j]) {
|
||||
item = list[i];
|
||||
list[i] = list[j];
|
||||
list[j] = item;
|
||||
i++;
|
||||
j--;
|
||||
}
|
||||
}
|
||||
librc_hidden_def(rc_strlist_reverse)
|
||||
|
||||
void rc_strlist_free (char **list)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if (! list)
|
||||
return;
|
||||
|
||||
while (list[i])
|
||||
free (list[i++]);
|
||||
|
||||
free (list);
|
||||
}
|
||||
librc_hidden_def(rc_strlist_free)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -64,10 +64,8 @@
|
||||
#include <kvm.h>
|
||||
#endif
|
||||
|
||||
#include "librc-depend.h"
|
||||
#include "rc.h"
|
||||
#include "rc-misc.h"
|
||||
#include "strlist.h"
|
||||
|
||||
#include "hidden-visibility.h"
|
||||
#define librc_hidden_proto(x) hidden_proto(x)
|
||||
@@ -115,15 +113,11 @@ librc_hidden_proto(rc_service_state)
|
||||
librc_hidden_proto(rc_service_value_get)
|
||||
librc_hidden_proto(rc_service_value_set)
|
||||
librc_hidden_proto(rc_strcatpaths)
|
||||
librc_hidden_proto(rc_strlist_add)
|
||||
librc_hidden_proto(rc_strlist_addu)
|
||||
librc_hidden_proto(rc_strlist_addsort)
|
||||
librc_hidden_proto(rc_strlist_addsortc)
|
||||
librc_hidden_proto(rc_strlist_addsortu)
|
||||
librc_hidden_proto(rc_strlist_delete)
|
||||
librc_hidden_proto(rc_strlist_free)
|
||||
librc_hidden_proto(rc_strlist_join)
|
||||
librc_hidden_proto(rc_strlist_reverse)
|
||||
librc_hidden_proto(rc_stringlist_add)
|
||||
librc_hidden_proto(rc_stringlist_addu)
|
||||
librc_hidden_proto(rc_stringlist_delete)
|
||||
librc_hidden_proto(rc_stringlist_free)
|
||||
librc_hidden_proto(rc_stringlist_sort)
|
||||
librc_hidden_proto(rc_yesno)
|
||||
|
||||
#endif
|
||||
|
||||
200
src/librc/rc.h
200
src/librc/rc.h
@@ -32,15 +32,24 @@
|
||||
# if (GCC_VERSION >= 3005)
|
||||
# define SENTINEL __attribute__ ((__sentinel__))
|
||||
# endif
|
||||
# define DEPRECATED __attribute__ ((deprecated))
|
||||
#endif
|
||||
#ifndef SENTINEL
|
||||
# define SENTINEL
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/queue.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* A doubly linked list using queue(3) for ease of use */
|
||||
typedef struct rc_string {
|
||||
char *value;
|
||||
TAILQ_ENTRY(rc_string) entries;
|
||||
} RC_STRING;
|
||||
typedef TAILQ_HEAD(rc_stringlist, rc_string) RC_STRINGLIST;
|
||||
|
||||
/*! @name Reserved runlevel names */
|
||||
#define RC_LEVEL_SYSINIT "sysinit"
|
||||
#define RC_LEVEL_SINGLE "single"
|
||||
@@ -49,30 +58,30 @@
|
||||
|
||||
/*! Return the current runlevel.
|
||||
* @return the current runlevel */
|
||||
char *rc_runlevel_get (void);
|
||||
char *rc_runlevel_get(void);
|
||||
|
||||
/*! Checks if the runlevel exists or not
|
||||
* @param runlevel to check
|
||||
* @return true if the runlevel exists, otherwise false */
|
||||
bool rc_runlevel_exists (const char *runlevel);
|
||||
bool rc_runlevel_exists(const char *);
|
||||
|
||||
/*! Return a NULL terminated list of runlevels
|
||||
* @return a NULL terminated list of runlevels */
|
||||
char **rc_runlevel_list (void);
|
||||
RC_STRINGLIST *rc_runlevel_list(void);
|
||||
|
||||
/*! Set the runlevel.
|
||||
* This just changes the stored runlevel and does not start or stop any
|
||||
* services.
|
||||
* @param runlevel to store */
|
||||
bool rc_runlevel_set (const char *runlevel);
|
||||
bool rc_runlevel_set(const char *);
|
||||
|
||||
/*! Is the runlevel starting?
|
||||
* @return true if yes, otherwise false */
|
||||
bool rc_runlevel_starting (void);
|
||||
bool rc_runlevel_starting(void);
|
||||
|
||||
/*! Is the runlevel stopping?
|
||||
* @return true if yes, otherwise false */
|
||||
bool rc_runlevel_stopping (void);
|
||||
bool rc_runlevel_stopping(void);
|
||||
|
||||
/*! @name RC
|
||||
* A service can be given as a full path or just its name.
|
||||
@@ -97,19 +106,19 @@ typedef enum
|
||||
RC_SERVICE_FAILED = 0x0200,
|
||||
RC_SERVICE_SCHEDULED = 0x0400,
|
||||
RC_SERVICE_WASINACTIVE = 0x0800
|
||||
} rc_service_state_t;
|
||||
} RC_SERVICE;
|
||||
|
||||
/*! Add the service to the runlevel
|
||||
* @param runlevel to add to
|
||||
* @param service to add
|
||||
* @return true if successful, otherwise false */
|
||||
bool rc_service_add (const char *runlevel, const char *service);
|
||||
bool rc_service_add(const char *, const char *);
|
||||
|
||||
/*! Remove the service from the runlevel
|
||||
* @param runlevel to remove from
|
||||
* @param service to remove
|
||||
* @return true if sucessful, otherwise false */
|
||||
bool rc_service_delete (const char *runlevel, const char *service);
|
||||
bool rc_service_delete(const char *, const char *);
|
||||
|
||||
/*! Save the arguments to find a running daemon
|
||||
* @param service to save arguments for
|
||||
@@ -117,116 +126,113 @@ bool rc_service_delete (const char *runlevel, const char *service);
|
||||
* @param name of the process (optional)
|
||||
* @param pidfile of the process (optional)
|
||||
* @param started if true, add the arguments otherwise remove existing matching arguments */
|
||||
bool rc_service_daemon_set (const char *service, const char *const *argv,
|
||||
const char *name, const char *pidfile,
|
||||
bool started);
|
||||
bool rc_service_daemon_set(const char *, const char *const *, const char *, const char *,
|
||||
bool);
|
||||
|
||||
/*! Returns a description of what the service and/or option does.
|
||||
* @param service to check
|
||||
* @param option to check (if NULL, service description)
|
||||
* @return a newly allocated pointer to the description */
|
||||
char *rc_service_description (const char *service, const char *option);
|
||||
char *rc_service_description(const char *, const char *);
|
||||
|
||||
/*! Checks if a service exists or not.
|
||||
* @param service to check
|
||||
* @return true if service exists, otherwise false */
|
||||
bool rc_service_exists (const char *service);
|
||||
bool rc_service_exists(const char *);
|
||||
|
||||
/*! Checks if a service is in a runlevel
|
||||
* @param service to check
|
||||
* @param runlevel it should be in
|
||||
* @return true if service is in the runlevel, otherwise false */
|
||||
bool rc_service_in_runlevel (const char *service, const char *runlevel);
|
||||
bool rc_service_in_runlevel(const char *, const char *);
|
||||
|
||||
/*! Marks the service state
|
||||
* @param service to mark
|
||||
* @param state service should be in
|
||||
* @return true if service state change was successful, otherwise false */
|
||||
bool rc_service_mark (const char *service, rc_service_state_t state);
|
||||
bool rc_service_mark(const char *, RC_SERVICE);
|
||||
|
||||
/*! Lists the extra commands a service has
|
||||
* @param service to load the commands from
|
||||
* @return NULL terminated string list of commands */
|
||||
char **rc_service_extra_commands (const char *service);
|
||||
RC_STRINGLIST *rc_service_extra_commands(const char *);
|
||||
|
||||
/*! Resolves a service name to its full path.
|
||||
* @param service to check
|
||||
* @return pointer to full path of service */
|
||||
char *rc_service_resolve (const char *service);
|
||||
char *rc_service_resolve(const char *);
|
||||
|
||||
/*! Schedule a service to be started when another service starts
|
||||
* @param service that starts the scheduled service when started
|
||||
* @param service_to_start service that will be started */
|
||||
bool rc_service_schedule_start (const char *service,
|
||||
const char *service_to_start);
|
||||
bool rc_service_schedule_start(const char *, const char *);
|
||||
|
||||
/*! Return a NULL terminated list of services that are scheduled to start
|
||||
* when the given service has started
|
||||
* @param service to check
|
||||
* @return NULL terminated list of services scheduled to start */
|
||||
char **rc_services_scheduled_by (const char *service);
|
||||
RC_STRINGLIST *rc_services_scheduled_by(const char *);
|
||||
|
||||
/*! Clear the list of services scheduled to be started by this service
|
||||
* @param service to clear
|
||||
* @return true if no errors, otherwise false */
|
||||
bool rc_service_schedule_clear (const char *service);
|
||||
bool rc_service_schedule_clear(const char *);
|
||||
|
||||
/*! Checks if a service in in a state
|
||||
* @param service to check
|
||||
* @return state of the service */
|
||||
rc_service_state_t rc_service_state (const char *service);
|
||||
RC_SERVICE rc_service_state(const char *);
|
||||
|
||||
/*! Start a service
|
||||
* @param service to start
|
||||
* @return pid of the service starting process */
|
||||
pid_t rc_service_start (const char *service);
|
||||
pid_t rc_service_start(const char *);
|
||||
|
||||
/*! Stop a service
|
||||
* @param service to stop
|
||||
* @return pid of service stopping process */
|
||||
pid_t rc_service_stop (const char *service);
|
||||
pid_t rc_service_stop(const char *);
|
||||
|
||||
/*! Check if the service started the daemon
|
||||
* @param service to check
|
||||
* @param exec to check
|
||||
* @param indx of the daemon (optional - 1st daemon, 2nd daemon, etc)
|
||||
* @return true if started by this service, otherwise false */
|
||||
bool rc_service_started_daemon (const char *service, const char *const *argv,
|
||||
int indx);
|
||||
bool rc_service_started_daemon(const char *, const char *const *, int);
|
||||
|
||||
/*! Return a saved value for a service
|
||||
* @param service to check
|
||||
* @param option to load
|
||||
* @return saved value */
|
||||
char *rc_service_value_get (const char *service, const char *option);
|
||||
char *rc_service_value_get(const char *, const char *);
|
||||
|
||||
/*! Save a persistent value for a service
|
||||
* @param service to save for
|
||||
* @param option to save
|
||||
* @param value of the option
|
||||
* @return true if saved, otherwise false */
|
||||
bool rc_service_value_set (const char *service, const char *option,
|
||||
const char *value);
|
||||
bool rc_service_value_set(const char *, const char *, const char *);
|
||||
|
||||
/*! List the services in a runlevel
|
||||
* @param runlevel to list
|
||||
* @return NULL terminated list of services */
|
||||
char **rc_services_in_runlevel (const char *runlevel);
|
||||
RC_STRINGLIST *rc_services_in_runlevel(const char *);
|
||||
|
||||
/*! List the services in a state
|
||||
* @param state to list
|
||||
* @return NULL terminated list of services */
|
||||
char **rc_services_in_state (rc_service_state_t state);
|
||||
RC_STRINGLIST *rc_services_in_state(RC_SERVICE);
|
||||
|
||||
/*! List the services shceduled to start when this one does
|
||||
* @param service to check
|
||||
* @return NULL terminated list of services */
|
||||
char **rc_services_scheduled (const char *service);
|
||||
RC_STRINGLIST *rc_services_scheduled(const char *);
|
||||
|
||||
/*! Checks that all daemons started with start-stop-daemon by the service
|
||||
* are still running.
|
||||
* @param service to check
|
||||
* @return true if all daemons started are still running, otherwise false */
|
||||
bool rc_service_daemons_crashed (const char *service);
|
||||
bool rc_service_daemons_crashed(const char *);
|
||||
|
||||
/*! @name System types
|
||||
* OpenRC can support some special sub system types, normally virtualization.
|
||||
@@ -238,7 +244,7 @@ bool rc_service_daemons_crashed (const char *service);
|
||||
#define RC_SYS_VSERVER "VSERVER"
|
||||
#define RC_SYS_XEN0 "XEN0"
|
||||
#define RC_SYS_XENU "XENU"
|
||||
const char *rc_sys (void);
|
||||
const char *rc_sys(void);
|
||||
|
||||
/*! @name Dependency options
|
||||
* These options can change the services found by the rc_get_depinfo and
|
||||
@@ -256,40 +262,67 @@ const char *rc_sys (void);
|
||||
* We analyse each init script and cache the resultant dependency tree.
|
||||
* This tree can be accessed using the below functions. */
|
||||
|
||||
#ifndef _IN_LIBRC
|
||||
#ifdef _IN_LIBRC
|
||||
/*! @name Dependency structures
|
||||
* private to librc */
|
||||
|
||||
/*! Singly linked list of dependency types that list the services the
|
||||
* type is for */
|
||||
typedef struct rc_deptype
|
||||
{
|
||||
/*! ineed, iuse, iafter, etc */
|
||||
char *type;
|
||||
/*! list of services */
|
||||
RC_STRINGLIST *services;
|
||||
/*! list of types */
|
||||
STAILQ_ENTRY(rc_deptype) entries;
|
||||
} RC_DEPTYPE;
|
||||
|
||||
/*! Singly linked list of services and their dependencies */
|
||||
typedef struct rc_depinfo
|
||||
{
|
||||
/*! Name of service */
|
||||
char *service;
|
||||
/*! Dependencies */
|
||||
STAILQ_HEAD(, rc_deptype) depends;
|
||||
/*! List of entries */
|
||||
STAILQ_ENTRY(rc_depinfo) entries;
|
||||
} RC_DEPINFO;
|
||||
|
||||
typedef STAILQ_HEAD(,rc_depinfo) RC_DEPTREE;
|
||||
#else
|
||||
/* Handles to internal structures */
|
||||
typedef void *rc_depinfo_t;
|
||||
typedef void *RC_DEPTREE;
|
||||
#endif
|
||||
|
||||
/*! Check to see if source is newer than target.
|
||||
* If target is a directory then we traverse it and it's children.
|
||||
* @return true if source is newer than target, otherwise false */
|
||||
bool rc_newer_than (const char *source, const char *target);
|
||||
bool rc_newer_than(const char *, const char *);
|
||||
|
||||
/*! Update the cached dependency tree if it's older than any init script,
|
||||
* its configuration file or an external configuration file the init script
|
||||
* has specified.
|
||||
* @return true if successful, otherwise false */
|
||||
bool rc_deptree_update (void);
|
||||
bool rc_deptree_update(void);
|
||||
|
||||
/*! Check if the cached dependency tree is older than any init script,
|
||||
* its configuration file or an external configuration file the init script
|
||||
* has specified.
|
||||
* @return true if it needs updating, otherwise false */
|
||||
bool rc_deptree_update_needed (void);
|
||||
bool rc_deptree_update_needed(void);
|
||||
|
||||
/*! Load the cached dependency tree and return a pointer to it.
|
||||
* This pointer should be freed with rc_deptree_free when done.
|
||||
* @return pointer to the dependency tree */
|
||||
rc_depinfo_t *rc_deptree_load (void);
|
||||
RC_DEPTREE *rc_deptree_load(void);
|
||||
|
||||
/*! List the depend for the type of service
|
||||
* @param deptree to search
|
||||
* @param type to use (keywords, etc)
|
||||
* @param service to check
|
||||
* @return NULL terminated list of services in order */
|
||||
char **rc_deptree_depend (const rc_depinfo_t *deptree,
|
||||
const char *type, const char *service);
|
||||
RC_STRINGLIST *rc_deptree_depend(const RC_DEPTREE *, const char *, const char *);
|
||||
|
||||
/*! List all the services in order that the given services have
|
||||
* for the given types and options.
|
||||
@@ -298,10 +331,8 @@ char **rc_deptree_depend (const rc_depinfo_t *deptree,
|
||||
* @param services to check
|
||||
* @param options to pass
|
||||
* @return NULL terminated list of services in order */
|
||||
char **rc_deptree_depends (const rc_depinfo_t *deptree,
|
||||
const char *const *types,
|
||||
const char *const *services, const char *runlevel,
|
||||
int options);
|
||||
RC_STRINGLIST *rc_deptree_depends(const RC_DEPTREE *, const RC_STRINGLIST *,
|
||||
const RC_STRINGLIST *, const char *, int);
|
||||
|
||||
/*! List all the services that should be stoppned and then started, in order,
|
||||
* for the given runlevel, including sysinit and boot services where
|
||||
@@ -310,12 +341,11 @@ char **rc_deptree_depends (const rc_depinfo_t *deptree,
|
||||
* @param runlevel to change into
|
||||
* @param options to pass
|
||||
* @return NULL terminated list of services in order */
|
||||
char **rc_deptree_order (const rc_depinfo_t *deptree, const char *runlevel,
|
||||
int options);
|
||||
RC_STRINGLIST *rc_deptree_order(const RC_DEPTREE *, const char *, int);
|
||||
|
||||
/*! Free a deptree and its information
|
||||
* @param deptree to free */
|
||||
void rc_deptree_free (rc_depinfo_t *deptree);
|
||||
void rc_deptree_free(RC_DEPTREE *);
|
||||
|
||||
/*! @name Plugins
|
||||
* For each plugin loaded we will call rc_plugin_hook with the below
|
||||
@@ -347,13 +377,13 @@ typedef enum
|
||||
RC_HOOK_SERVICE_START_NOW = 106,
|
||||
RC_HOOK_SERVICE_START_DONE = 107,
|
||||
RC_HOOK_SERVICE_START_OUT = 108
|
||||
} rc_hook_t;
|
||||
} RC_HOOK;
|
||||
|
||||
/*! Plugin entry point
|
||||
* @param hook point
|
||||
* @param name of runlevel or service
|
||||
* @return 0 for success otherwise -1 */
|
||||
int rc_plugin_hook (rc_hook_t hook, const char *name);
|
||||
int rc_plugin_hook(RC_HOOK, const char *);
|
||||
|
||||
/*! Plugins should write FOO=BAR to this fd to set any environment
|
||||
* variables they wish. Variables should be separated by NULLs. */
|
||||
@@ -362,91 +392,64 @@ extern FILE *rc_environ_fd;
|
||||
/*! @name Configuration
|
||||
* These functions help to deal with shell based configuration files */
|
||||
/*! Return a line from a file, stripping the trailing newline. */
|
||||
char *rc_getline (FILE *fp);
|
||||
char *rc_getline(FILE *);
|
||||
|
||||
/*! Return a NULL terminated list of non comment lines from a file. */
|
||||
char **rc_config_list (const char *file);
|
||||
RC_STRINGLIST *rc_config_list(const char *);
|
||||
|
||||
/*! Return a NULL terminated list of key=value lines from a file. */
|
||||
char **rc_config_load (const char *file);
|
||||
RC_STRINGLIST *rc_config_load(const char *);
|
||||
|
||||
/*! Return the value of the entry from a key=value list. */
|
||||
char *rc_config_value (const char *const *list, const char *entry);
|
||||
char *rc_config_value(RC_STRINGLIST *, const char *);
|
||||
|
||||
/*! Check if a variable is a boolean and return it's value.
|
||||
* If variable is not a boolean then we set errno to be ENOENT when it does
|
||||
* not exist or EINVAL if it's not a boolean.
|
||||
* @param variable to check
|
||||
* @return true if it matches true, yes or 1, false if otherwise. */
|
||||
bool rc_yesno (const char *variable);
|
||||
bool rc_yesno(const char *);
|
||||
|
||||
/*! @name String List functions
|
||||
* Handy functions for dealing with string arrays of char **.
|
||||
* It's safe to assume that any function here that uses char ** is a string
|
||||
* list that can be manipulated with the below functions. Every string list
|
||||
* should be released with a call to rc_strlist_free. */
|
||||
* Every string list should be released with a call to rc_stringlist_free. */
|
||||
|
||||
/*! Create a new stringlinst
|
||||
* @return pointer to new list */
|
||||
RC_STRINGLIST *rc_stringlist_new(void);
|
||||
|
||||
/*! Duplicate the item, add it to end of the list and return a pointer to it.
|
||||
* @param list to add the item too
|
||||
* @param item to add.
|
||||
* @return pointer to newly added item */
|
||||
char *rc_strlist_add (char ***list, const char *item);
|
||||
RC_STRING *rc_stringlist_add(RC_STRINGLIST *, const char *);
|
||||
|
||||
/*! If the item does not exist in the list, duplicate it, add it to the
|
||||
* list and then return a pointer to it.
|
||||
* @param list to add the item too
|
||||
* @param item to add.
|
||||
* @return pointer to newly added item */
|
||||
char *rc_strlist_addu (char ***list, const char *item);
|
||||
|
||||
/*! Duplicate the item, add it to the list at the point based on locale and
|
||||
* then return a pointer to it.
|
||||
* @param list to add the item too
|
||||
* @param item to add.
|
||||
* @return pointer to newly added item */
|
||||
char *rc_strlist_addsort (char ***list, const char *item);
|
||||
|
||||
/*! Duplicate the item, add it to the list at the point based on C locale and
|
||||
* then return a pointer to it.
|
||||
* @param list to add the item too
|
||||
* @param item to add.
|
||||
* @return pointer to newly added item */
|
||||
char *rc_strlist_addsortc (char ***list, const char *item);
|
||||
|
||||
/*! If the item does not exist in the list, duplicate it, add it to the
|
||||
* list based on locale and then return a pointer to it.
|
||||
* @param list to add the item too
|
||||
* @param item to add.
|
||||
* @return pointer to newly added item */
|
||||
char *rc_strlist_addsortu (char ***list, const char *item);
|
||||
RC_STRING *rc_stringlist_addu(RC_STRINGLIST *, const char *);
|
||||
|
||||
/*! Free the item and remove it from the list. Return 0 on success otherwise -1.
|
||||
* @param list to add the item too
|
||||
* @param item to add.
|
||||
* @return true on success, otherwise false */
|
||||
bool rc_strlist_delete (char ***list, const char *item);
|
||||
bool rc_stringlist_delete(RC_STRINGLIST *, const char *);
|
||||
|
||||
/*! Moves the contents of list2 onto list1, so list2 is effectively emptied.
|
||||
* Returns a pointer to the last item on the new list.
|
||||
* @param list1 to append to
|
||||
* @param list2 to move from
|
||||
* @return pointer to the last item on the list */
|
||||
char *rc_strlist_join (char ***list1, char **list2);
|
||||
|
||||
/*! Reverses the contents of the list.
|
||||
* @param list to reverse */
|
||||
void rc_strlist_reverse (char **list);
|
||||
/*! Sort the list according to C locale
|
||||
* @param list to sort */
|
||||
void rc_stringlist_sort(RC_STRINGLIST **);
|
||||
|
||||
/*! Frees each item on the list and the list itself.
|
||||
* @param list to free */
|
||||
void rc_strlist_free (char **list);
|
||||
void rc_stringlist_free(RC_STRINGLIST *);
|
||||
|
||||
/*! Concatenate paths adding '/' if needed. The resultant pointer should be
|
||||
* freed when finished with.
|
||||
* @param path1 starting path
|
||||
* @param paths NULL terminated list of paths to add
|
||||
* @return pointer to the new path */
|
||||
char *rc_strcatpaths (const char *path1, const char *paths, ...) SENTINEL;
|
||||
char *rc_strcatpaths(const char *, const char *, ...) SENTINEL;
|
||||
|
||||
/*! Find processes based on criteria.
|
||||
* All of these are optional.
|
||||
@@ -457,7 +460,6 @@ char *rc_strcatpaths (const char *path1, const char *paths, ...) SENTINEL;
|
||||
* @param uid to check for
|
||||
* @param pid to check for
|
||||
* @return NULL terminated list of pids */
|
||||
pid_t *rc_find_pids (const char *const *argv, const char *cmd,
|
||||
uid_t uid, pid_t pid);
|
||||
pid_t *rc_find_pids(const char *const *, const char *, uid_t, pid_t);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -43,15 +43,12 @@ global:
|
||||
rc_service_value_get;
|
||||
rc_service_value_set;
|
||||
rc_strcatpaths;
|
||||
rc_strlist_add;
|
||||
rc_strlist_addu;
|
||||
rc_strlist_addsort;
|
||||
rc_strlist_addsortc;
|
||||
rc_strlist_addsortu;
|
||||
rc_strlist_delete;
|
||||
rc_strlist_free;
|
||||
rc_strlist_join;
|
||||
rc_strlist_reverse;
|
||||
rc_stringlist_add;
|
||||
rc_stringlist_addu;
|
||||
rc_stringlist_delete;
|
||||
rc_stringlist_new;
|
||||
rc_stringlist_sort;
|
||||
rc_stringlist_free;
|
||||
rc_sys;
|
||||
rc_yesno;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user