Improve style for KNF
This commit is contained in:
parent
6953474655
commit
ade85d4bd8
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
einfo.c
|
einfo.c
|
||||||
Informational functions
|
Informational functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2007-2008 Roy Marples <roy@marples.name>
|
* Copyright 2007-2008 Roy Marples <roy@marples.name>
|
||||||
@ -110,10 +110,10 @@ hidden_proto(ewendv)
|
|||||||
#define UP "\033[A"
|
#define UP "\033[A"
|
||||||
|
|
||||||
#define _GET_CAP(_d, _c) strlcpy(_d, tgoto(_c, 0, 0), sizeof(_d));
|
#define _GET_CAP(_d, _c) strlcpy(_d, tgoto(_c, 0, 0), sizeof(_d));
|
||||||
#define _ASSIGN_CAP(_v) { \
|
#define _ASSIGN_CAP(_v) do { \
|
||||||
_v = p; \
|
_v = p; \
|
||||||
p += strlcpy(p, tmp, sizeof(ebuffer) - (p - ebuffer)) + 1; \
|
p += strlcpy(p, tmp, sizeof(ebuffer) - (p - ebuffer)) + 1; \
|
||||||
}
|
} while (0)
|
||||||
|
|
||||||
/* A pointer to a string to prefix to einfo/ewarn/eerror messages */
|
/* A pointer to a string to prefix to einfo/ewarn/eerror messages */
|
||||||
static const char *_eprefix = NULL;
|
static const char *_eprefix = NULL;
|
||||||
@ -497,7 +497,7 @@ colour_terminal(FILE * EINFO_RESTRICT f)
|
|||||||
_GET_CAP(tmp, _me);
|
_GET_CAP(tmp, _me);
|
||||||
|
|
||||||
if (tmp[0])
|
if (tmp[0])
|
||||||
_ASSIGN_CAP(ecolors_str[i])
|
_ASSIGN_CAP(ecolors_str[i]);
|
||||||
else
|
else
|
||||||
ecolors_str[i] = &nullstr;
|
ecolors_str[i] = &nullstr;
|
||||||
}
|
}
|
||||||
@ -624,13 +624,13 @@ ecolor(ECOLOR color)
|
|||||||
return _ecolor(f, color);
|
return _ecolor(f, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LASTCMD(_cmd) { \
|
#define LASTCMD(_cmd) { \
|
||||||
unsetenv("EINFO_LASTCMD"); \
|
unsetenv("EINFO_LASTCMD"); \
|
||||||
setenv("EINFO_LASTCMD", _cmd, 1); \
|
setenv("EINFO_LASTCMD", _cmd, 1); \
|
||||||
}
|
}
|
||||||
|
|
||||||
static int EINFO_PRINTF(3, 0)
|
static int EINFO_PRINTF(3, 0)
|
||||||
_einfo(FILE *f, ECOLOR color, const char *EINFO_RESTRICT fmt, va_list va)
|
_einfo(FILE *f, ECOLOR color, const char *EINFO_RESTRICT fmt, va_list va)
|
||||||
{
|
{
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
char *last = getenv("EINFO_LASTCMD");
|
char *last = getenv("EINFO_LASTCMD");
|
||||||
@ -836,8 +836,8 @@ _eend(FILE * EINFO_RESTRICT fp, int col, ECOLOR color, const char *msg)
|
|||||||
* valuable columns when running on 80 column screens. */
|
* valuable columns when running on 80 column screens. */
|
||||||
if (cols > 0 && colour_terminal(fp)) {
|
if (cols > 0 && colour_terminal(fp)) {
|
||||||
fprintf(fp, "%s%s %s[%s%s%s]%s\n", up, tgoto(goto_column, 0, cols),
|
fprintf(fp, "%s%s %s[%s%s%s]%s\n", up, tgoto(goto_column, 0, cols),
|
||||||
ecolor(ECOLOR_BRACKET), ecolor(color), msg,
|
ecolor(ECOLOR_BRACKET), ecolor(color), msg,
|
||||||
ecolor(ECOLOR_BRACKET), ecolor(ECOLOR_NORMAL));
|
ecolor(ECOLOR_BRACKET), ecolor(ECOLOR_NORMAL));
|
||||||
} else {
|
} else {
|
||||||
if (col > 0)
|
if (col > 0)
|
||||||
for (i = 0; i < cols - col; i++)
|
for (i = 0; i < cols - col; i++)
|
||||||
@ -847,7 +847,8 @@ _eend(FILE * EINFO_RESTRICT fp, int col, ECOLOR color, const char *msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int EINFO_PRINTF(3, 0)
|
static int EINFO_PRINTF(3, 0)
|
||||||
_do_eend(const char *cmd, int retval, const char *EINFO_RESTRICT fmt, va_list ap)
|
_do_eend(const char *cmd, int retval,
|
||||||
|
const char *EINFO_RESTRICT fmt, va_list ap)
|
||||||
{
|
{
|
||||||
int col = 0;
|
int col = 0;
|
||||||
FILE *fp = stdout;
|
FILE *fp = stdout;
|
||||||
@ -864,8 +865,8 @@ _do_eend(const char *cmd, int retval, const char *EINFO_RESTRICT fmt, va_list ap
|
|||||||
va_end(apc);
|
va_end(apc);
|
||||||
}
|
}
|
||||||
_eend(fp, col,
|
_eend(fp, col,
|
||||||
retval == 0 ? ECOLOR_GOOD : ECOLOR_BAD,
|
retval == 0 ? ECOLOR_GOOD : ECOLOR_BAD,
|
||||||
retval == 0 ? OK : NOT_OK);
|
retval == 0 ? OK : NOT_OK);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
librc-daemon
|
librc-daemon
|
||||||
Finds PID for given daemon criteria
|
Finds PID for given daemon criteria
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2007-2009 Roy Marples <roy@marples.name>
|
* Copyright 2007-2009 Roy Marples <roy@marples.name>
|
||||||
@ -32,7 +32,8 @@
|
|||||||
#include "librc.h"
|
#include "librc.h"
|
||||||
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
static bool pid_is_exec(pid_t pid, const char *exec)
|
static bool
|
||||||
|
pid_is_exec(pid_t pid, const char *exec)
|
||||||
{
|
{
|
||||||
char buffer[32];
|
char buffer[32];
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
@ -55,7 +56,8 @@ static bool pid_is_exec(pid_t pid, const char *exec)
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool pid_is_argv(pid_t pid, const char *const *argv)
|
static bool
|
||||||
|
pid_is_argv(pid_t pid, const char *const *argv)
|
||||||
{
|
{
|
||||||
char cmdline[32];
|
char cmdline[32];
|
||||||
int fd;
|
int fd;
|
||||||
@ -84,8 +86,8 @@ static bool pid_is_argv(pid_t pid, const char *const *argv)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
RC_PIDLIST *rc_find_pids(const char *exec, const char *const *argv,
|
RC_PIDLIST *
|
||||||
uid_t uid, pid_t pid)
|
rc_find_pids(const char *exec, const char *const *argv, uid_t uid, pid_t pid)
|
||||||
{
|
{
|
||||||
DIR *procdir;
|
DIR *procdir;
|
||||||
struct dirent *entry;
|
struct dirent *entry;
|
||||||
@ -101,15 +103,15 @@ RC_PIDLIST *rc_find_pids(const char *exec, const char *const *argv,
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
We never match RC_RUNSCRIPT_PID if present so we avoid the below
|
We never match RC_RUNSCRIPT_PID if present so we avoid the below
|
||||||
scenario
|
scenario
|
||||||
|
|
||||||
/etc/init.d/ntpd stop does
|
/etc/init.d/ntpd stop does
|
||||||
start-stop-daemon --stop --name ntpd
|
start-stop-daemon --stop --name ntpd
|
||||||
catching /etc/init.d/ntpd stop
|
catching /etc/init.d/ntpd stop
|
||||||
|
|
||||||
nasty
|
nasty
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((pp = getenv("RC_RUNSCRIPT_PID"))) {
|
if ((pp = getenv("RC_RUNSCRIPT_PID"))) {
|
||||||
if (sscanf(pp, "%d", &runscript_pid) != 1)
|
if (sscanf(pp, "%d", &runscript_pid) != 1)
|
||||||
@ -170,8 +172,8 @@ librc_hidden_def(rc_find_pids)
|
|||||||
# define _KVM_FLAGS O_RDONLY
|
# define _KVM_FLAGS O_RDONLY
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
RC_PIDLIST *rc_find_pids(const char *exec, const char *const *argv,
|
RC_PIDLIST *
|
||||||
uid_t uid, pid_t pid)
|
rc_find_pids(const char *exec, const char *const *argv, uid_t uid, pid_t pid)
|
||||||
{
|
{
|
||||||
static kvm_t *kd = NULL;
|
static kvm_t *kd = NULL;
|
||||||
char errbuf[_POSIX2_LINE_MAX];
|
char errbuf[_POSIX2_LINE_MAX];
|
||||||
@ -187,7 +189,7 @@ RC_PIDLIST *rc_find_pids(const char *exec, const char *const *argv,
|
|||||||
int match;
|
int match;
|
||||||
|
|
||||||
if ((kd = kvm_openfiles(_KVM_PATH, _KVM_PATH,
|
if ((kd = kvm_openfiles(_KVM_PATH, _KVM_PATH,
|
||||||
NULL, _KVM_FLAGS, errbuf)) == NULL)
|
NULL, _KVM_FLAGS, errbuf)) == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "kvm_open: %s\n", errbuf);
|
fprintf(stderr, "kvm_open: %s\n", errbuf);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -249,8 +251,8 @@ librc_hidden_def(rc_find_pids)
|
|||||||
# error "Platform not supported!"
|
# error "Platform not supported!"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static bool _match_daemon(const char *path, const char *file,
|
static bool
|
||||||
RC_STRINGLIST *match)
|
_match_daemon(const char *path, const char *file, RC_STRINGLIST *match)
|
||||||
{
|
{
|
||||||
char *line = NULL;
|
char *line = NULL;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
@ -266,10 +268,10 @@ static bool _match_daemon(const char *path, const char *file,
|
|||||||
|
|
||||||
while ((rc_getline(&line, &len, fp))) {
|
while ((rc_getline(&line, &len, fp))) {
|
||||||
TAILQ_FOREACH(m, match, entries)
|
TAILQ_FOREACH(m, match, entries)
|
||||||
if (strcmp(line, m->value) == 0) {
|
if (strcmp(line, m->value) == 0) {
|
||||||
TAILQ_REMOVE(match, m, entries);
|
TAILQ_REMOVE(match, m, entries);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!TAILQ_FIRST(match))
|
if (!TAILQ_FIRST(match))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -280,8 +282,8 @@ static bool _match_daemon(const char *path, const char *file,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static RC_STRINGLIST *_match_list(const char *exec, const char* const* argv,
|
static RC_STRINGLIST *
|
||||||
const char *pidfile)
|
_match_list(const char *exec, const char* const* argv, const char *pidfile)
|
||||||
{
|
{
|
||||||
RC_STRINGLIST *match = rc_stringlist_new();
|
RC_STRINGLIST *match = rc_stringlist_new();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@ -315,9 +317,10 @@ static RC_STRINGLIST *_match_list(const char *exec, const char* const* argv,
|
|||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rc_service_daemon_set(const char *service, const char *exec,
|
bool
|
||||||
const char *const *argv,
|
rc_service_daemon_set(const char *service, const char *exec,
|
||||||
const char *pidfile, bool started)
|
const char *const *argv,
|
||||||
|
const char *pidfile, bool started)
|
||||||
{
|
{
|
||||||
char dirpath[PATH_MAX];
|
char dirpath[PATH_MAX];
|
||||||
char file[PATH_MAX];
|
char file[PATH_MAX];
|
||||||
@ -336,7 +339,7 @@ bool rc_service_daemon_set(const char *service, const char *exec,
|
|||||||
}
|
}
|
||||||
|
|
||||||
snprintf(dirpath, sizeof(dirpath), RC_SVCDIR "/daemons/%s",
|
snprintf(dirpath, sizeof(dirpath), RC_SVCDIR "/daemons/%s",
|
||||||
basename_c(service));
|
basename_c(service));
|
||||||
|
|
||||||
/* Regardless, erase any existing daemon info */
|
/* Regardless, erase any existing daemon info */
|
||||||
if ((dp = opendir(dirpath))) {
|
if ((dp = opendir(dirpath))) {
|
||||||
@ -346,7 +349,7 @@ bool rc_service_daemon_set(const char *service, const char *exec,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
snprintf(file, sizeof(file), "%s/%s",
|
snprintf(file, sizeof(file), "%s/%s",
|
||||||
dirpath, d->d_name);
|
dirpath, d->d_name);
|
||||||
nfiles++;
|
nfiles++;
|
||||||
|
|
||||||
if (!*oldfile) {
|
if (!*oldfile) {
|
||||||
@ -368,7 +371,7 @@ bool rc_service_daemon_set(const char *service, const char *exec,
|
|||||||
if (started) {
|
if (started) {
|
||||||
if (mkdir(dirpath, 0755) == 0 || errno == EEXIST) {
|
if (mkdir(dirpath, 0755) == 0 || errno == EEXIST) {
|
||||||
snprintf(file, sizeof(file), "%s/%03d",
|
snprintf(file, sizeof(file), "%s/%03d",
|
||||||
dirpath, nfiles + 1);
|
dirpath, nfiles + 1);
|
||||||
if ((fp = fopen(file, "w"))) {
|
if ((fp = fopen(file, "w"))) {
|
||||||
fprintf(fp, "exec=");
|
fprintf(fp, "exec=");
|
||||||
if (exec)
|
if (exec)
|
||||||
@ -392,9 +395,9 @@ bool rc_service_daemon_set(const char *service, const char *exec,
|
|||||||
}
|
}
|
||||||
librc_hidden_def(rc_service_daemon_set)
|
librc_hidden_def(rc_service_daemon_set)
|
||||||
|
|
||||||
bool rc_service_started_daemon(const char *service,
|
bool
|
||||||
const char *exec, const char *const *argv,
|
rc_service_started_daemon(const char *service,
|
||||||
int indx)
|
const char *exec, const char *const *argv, int indx)
|
||||||
{
|
{
|
||||||
char dirpath[PATH_MAX];
|
char dirpath[PATH_MAX];
|
||||||
char file[16];
|
char file[16];
|
||||||
@ -407,7 +410,7 @@ bool rc_service_started_daemon(const char *service,
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
snprintf(dirpath, sizeof(dirpath), RC_SVCDIR "/daemons/%s",
|
snprintf(dirpath, sizeof(dirpath), RC_SVCDIR "/daemons/%s",
|
||||||
basename_c(service));
|
basename_c(service));
|
||||||
match = _match_list(exec, argv, NULL);
|
match = _match_list(exec, argv, NULL);
|
||||||
|
|
||||||
if (indx > 0) {
|
if (indx > 0) {
|
||||||
@ -431,7 +434,8 @@ bool rc_service_started_daemon(const char *service,
|
|||||||
}
|
}
|
||||||
librc_hidden_def(rc_service_started_daemon)
|
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[PATH_MAX];
|
char dirpath[PATH_MAX];
|
||||||
DIR *dp;
|
DIR *dp;
|
||||||
@ -456,7 +460,7 @@ bool rc_service_daemons_crashed(const char *service)
|
|||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
path += snprintf(dirpath, sizeof(dirpath), RC_SVCDIR "/daemons/%s",
|
path += snprintf(dirpath, sizeof(dirpath), RC_SVCDIR "/daemons/%s",
|
||||||
basename_c(service));
|
basename_c(service));
|
||||||
|
|
||||||
if (!(dp = opendir(dirpath)))
|
if (!(dp = opendir(dirpath)))
|
||||||
return false;
|
return false;
|
||||||
@ -466,7 +470,7 @@ bool rc_service_daemons_crashed(const char *service)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
snprintf(path, sizeof(dirpath) - (path - dirpath), "/%s",
|
snprintf(path, sizeof(dirpath) - (path - dirpath), "/%s",
|
||||||
d->d_name);
|
d->d_name);
|
||||||
fp = fopen(dirpath, "r");
|
fp = fopen(dirpath, "r");
|
||||||
if (!fp)
|
if (!fp)
|
||||||
break;
|
break;
|
||||||
@ -529,19 +533,19 @@ bool rc_service_daemons_crashed(const char *service)
|
|||||||
/* We need to flatten our linked list into an array */
|
/* We need to flatten our linked list into an array */
|
||||||
i = 0;
|
i = 0;
|
||||||
TAILQ_FOREACH(s, list, entries)
|
TAILQ_FOREACH(s, list, entries)
|
||||||
i++;
|
i++;
|
||||||
argv = xmalloc(sizeof(char *) * (i + 1));
|
argv = xmalloc(sizeof(char *) * (i + 1));
|
||||||
i = 0;
|
i = 0;
|
||||||
TAILQ_FOREACH(s, list, entries)
|
TAILQ_FOREACH(s, list, entries)
|
||||||
argv[i++] = s->value;
|
argv[i++] = s->value;
|
||||||
argv[i] = '\0';
|
argv[i] = '\0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!retval) {
|
if (!retval) {
|
||||||
if ((pids = rc_find_pids(exec,
|
if ((pids = rc_find_pids(exec,
|
||||||
(const char *const *)argv,
|
(const char *const *)argv,
|
||||||
0, pid)))
|
0, pid)))
|
||||||
{
|
{
|
||||||
p1 = LIST_FIRST(pids);
|
p1 = LIST_FIRST(pids);
|
||||||
while (p1) {
|
while (p1) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
rc-misc.c
|
rc-misc.c
|
||||||
rc misc functions
|
rc misc functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2007-2008 Roy Marples <roy@marples.name>
|
* Copyright 2007-2008 Roy Marples <roy@marples.name>
|
||||||
@ -31,7 +31,8 @@
|
|||||||
|
|
||||||
#include "librc.h"
|
#include "librc.h"
|
||||||
|
|
||||||
bool rc_yesno(const char *value)
|
bool
|
||||||
|
rc_yesno(const char *value)
|
||||||
{
|
{
|
||||||
if (!value) {
|
if (!value) {
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
@ -54,7 +55,8 @@ bool rc_yesno(const char *value)
|
|||||||
}
|
}
|
||||||
librc_hidden_def(rc_yesno)
|
librc_hidden_def(rc_yesno)
|
||||||
|
|
||||||
ssize_t rc_getline(char **line, size_t *len, FILE *fp)
|
ssize_t
|
||||||
|
rc_getline(char **line, size_t *len, FILE *fp)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
size_t last = 0;
|
size_t last = 0;
|
||||||
@ -78,7 +80,8 @@ ssize_t rc_getline(char **line, size_t *len, FILE *fp)
|
|||||||
}
|
}
|
||||||
librc_hidden_def(rc_getline)
|
librc_hidden_def(rc_getline)
|
||||||
|
|
||||||
RC_STRINGLIST *rc_config_list(const char *file)
|
RC_STRINGLIST *
|
||||||
|
rc_config_list(const char *file)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char *buffer = NULL;
|
char *buffer = NULL;
|
||||||
@ -116,7 +119,8 @@ RC_STRINGLIST *rc_config_list(const char *file)
|
|||||||
}
|
}
|
||||||
librc_hidden_def(rc_config_list)
|
librc_hidden_def(rc_config_list)
|
||||||
|
|
||||||
RC_STRINGLIST *rc_config_load(const char *file)
|
RC_STRINGLIST *
|
||||||
|
rc_config_load(const char *file)
|
||||||
{
|
{
|
||||||
RC_STRINGLIST *list;
|
RC_STRINGLIST *list;
|
||||||
RC_STRINGLIST *config;
|
RC_STRINGLIST *config;
|
||||||
@ -172,7 +176,7 @@ RC_STRINGLIST *rc_config_load(const char *file)
|
|||||||
TAILQ_FOREACH(cline, config, entries) {
|
TAILQ_FOREACH(cline, config, entries) {
|
||||||
p = strchr(cline->value, '=');
|
p = strchr(cline->value, '=');
|
||||||
if (p && strncmp(entry, cline->value,
|
if (p && strncmp(entry, cline->value,
|
||||||
(size_t)(p - cline->value)) == 0)
|
(size_t)(p - cline->value)) == 0)
|
||||||
{
|
{
|
||||||
/* We have a match now - to save time we directly replace it */
|
/* We have a match now - to save time we directly replace it */
|
||||||
free(cline->value);
|
free(cline->value);
|
||||||
@ -194,7 +198,8 @@ RC_STRINGLIST *rc_config_load(const char *file)
|
|||||||
}
|
}
|
||||||
librc_hidden_def(rc_config_load)
|
librc_hidden_def(rc_config_load)
|
||||||
|
|
||||||
char *rc_config_value(RC_STRINGLIST *list, const char *entry)
|
char *
|
||||||
|
rc_config_value(RC_STRINGLIST *list, const char *entry)
|
||||||
{
|
{
|
||||||
RC_STRING *line;
|
RC_STRING *line;
|
||||||
char *p;
|
char *p;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
librc-strlist.h
|
librc-strlist.h
|
||||||
String list functions to make using queue(3) a little easier.
|
String list functions to make using queue(3) a little easier.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2007-2008 Roy Marples <roy@marples.name>
|
* Copyright 2007-2008 Roy Marples <roy@marples.name>
|
||||||
@ -31,7 +31,8 @@
|
|||||||
|
|
||||||
#include "librc.h"
|
#include "librc.h"
|
||||||
|
|
||||||
RC_STRINGLIST *rc_stringlist_new(void)
|
RC_STRINGLIST *
|
||||||
|
rc_stringlist_new(void)
|
||||||
{
|
{
|
||||||
RC_STRINGLIST *l = xmalloc(sizeof(*l));
|
RC_STRINGLIST *l = xmalloc(sizeof(*l));
|
||||||
TAILQ_INIT(l);
|
TAILQ_INIT(l);
|
||||||
@ -39,7 +40,8 @@ RC_STRINGLIST *rc_stringlist_new(void)
|
|||||||
}
|
}
|
||||||
librc_hidden_def(rc_stringlist_new)
|
librc_hidden_def(rc_stringlist_new)
|
||||||
|
|
||||||
RC_STRING *rc_stringlist_add (RC_STRINGLIST *list, const char *value)
|
RC_STRING *
|
||||||
|
rc_stringlist_add (RC_STRINGLIST *list, const char *value)
|
||||||
{
|
{
|
||||||
RC_STRING *s = xmalloc(sizeof(*s));
|
RC_STRING *s = xmalloc(sizeof(*s));
|
||||||
|
|
||||||
@ -49,51 +51,55 @@ RC_STRING *rc_stringlist_add (RC_STRINGLIST *list, const char *value)
|
|||||||
}
|
}
|
||||||
librc_hidden_def(rc_stringlist_add)
|
librc_hidden_def(rc_stringlist_add)
|
||||||
|
|
||||||
RC_STRING *rc_stringlist_addu (RC_STRINGLIST *list, const char *value)
|
RC_STRING *
|
||||||
|
rc_stringlist_addu (RC_STRINGLIST *list, const char *value)
|
||||||
{
|
{
|
||||||
RC_STRING *s;
|
RC_STRING *s;
|
||||||
|
|
||||||
TAILQ_FOREACH(s, list, entries)
|
TAILQ_FOREACH(s, list, entries)
|
||||||
if (strcmp(s->value, value) == 0) {
|
if (strcmp(s->value, value) == 0) {
|
||||||
errno = EEXIST;
|
errno = EEXIST;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc_stringlist_add(list, value);
|
return rc_stringlist_add(list, value);
|
||||||
}
|
}
|
||||||
librc_hidden_def(rc_stringlist_addu)
|
librc_hidden_def(rc_stringlist_addu)
|
||||||
|
|
||||||
bool rc_stringlist_delete(RC_STRINGLIST *list, const char *value)
|
bool
|
||||||
|
rc_stringlist_delete(RC_STRINGLIST *list, const char *value)
|
||||||
{
|
{
|
||||||
RC_STRING *s;
|
RC_STRING *s;
|
||||||
|
|
||||||
TAILQ_FOREACH(s, list, entries)
|
TAILQ_FOREACH(s, list, entries)
|
||||||
if (strcmp(s->value, value) == 0) {
|
if (strcmp(s->value, value) == 0) {
|
||||||
TAILQ_REMOVE(list, s, entries);
|
TAILQ_REMOVE(list, s, entries);
|
||||||
free (s->value);
|
free (s->value);
|
||||||
free (s);
|
free (s);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
errno = EEXIST;
|
errno = EEXIST;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
librc_hidden_def(rc_stringlist_delete)
|
librc_hidden_def(rc_stringlist_delete)
|
||||||
|
|
||||||
RC_STRING *rc_stringlist_find(RC_STRINGLIST *list, const char *value)
|
RC_STRING *
|
||||||
|
rc_stringlist_find(RC_STRINGLIST *list, const char *value)
|
||||||
{
|
{
|
||||||
RC_STRING *s;
|
RC_STRING *s;
|
||||||
|
|
||||||
if (list) {
|
if (list) {
|
||||||
TAILQ_FOREACH(s, list, entries)
|
TAILQ_FOREACH(s, list, entries)
|
||||||
if (strcmp(s->value, value) == 0)
|
if (strcmp(s->value, value) == 0)
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
librc_hidden_def(rc_stringlist_find)
|
librc_hidden_def(rc_stringlist_find)
|
||||||
|
|
||||||
RC_STRINGLIST *rc_stringlist_split(const char *value, const char *sep)
|
RC_STRINGLIST *
|
||||||
|
rc_stringlist_split(const char *value, const char *sep)
|
||||||
{
|
{
|
||||||
RC_STRINGLIST *list = rc_stringlist_new();
|
RC_STRINGLIST *list = rc_stringlist_new();
|
||||||
char *d = xstrdup(value);
|
char *d = xstrdup(value);
|
||||||
@ -107,7 +113,8 @@ RC_STRINGLIST *rc_stringlist_split(const char *value, const char *sep)
|
|||||||
}
|
}
|
||||||
librc_hidden_def(rc_stringlist_split)
|
librc_hidden_def(rc_stringlist_split)
|
||||||
|
|
||||||
void rc_stringlist_sort(RC_STRINGLIST **list)
|
void
|
||||||
|
rc_stringlist_sort(RC_STRINGLIST **list)
|
||||||
{
|
{
|
||||||
RC_STRINGLIST *l = *list;
|
RC_STRINGLIST *l = *list;
|
||||||
RC_STRINGLIST *new = rc_stringlist_new();
|
RC_STRINGLIST *new = rc_stringlist_new();
|
||||||
@ -119,7 +126,7 @@ void rc_stringlist_sort(RC_STRINGLIST **list)
|
|||||||
TAILQ_FOREACH_SAFE(s, l, entries, sn) {
|
TAILQ_FOREACH_SAFE(s, l, entries, sn) {
|
||||||
TAILQ_REMOVE(l, s, entries);
|
TAILQ_REMOVE(l, s, entries);
|
||||||
last = NULL;
|
last = NULL;
|
||||||
TAILQ_FOREACH (n, new, entries) {
|
TAILQ_FOREACH(n, new, entries) {
|
||||||
if (strcmp (s->value, n->value) < 0)
|
if (strcmp (s->value, n->value) < 0)
|
||||||
break;
|
break;
|
||||||
last = n;
|
last = n;
|
||||||
@ -136,7 +143,8 @@ void rc_stringlist_sort(RC_STRINGLIST **list)
|
|||||||
}
|
}
|
||||||
librc_hidden_def(rc_stringlist_sort)
|
librc_hidden_def(rc_stringlist_sort)
|
||||||
|
|
||||||
void rc_stringlist_free(RC_STRINGLIST *list)
|
void
|
||||||
|
rc_stringlist_free(RC_STRINGLIST *list)
|
||||||
{
|
{
|
||||||
RC_STRING *s1;
|
RC_STRING *s1;
|
||||||
RC_STRING *s2;
|
RC_STRING *s2;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
librc
|
librc
|
||||||
core RC functions
|
core RC functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2007-2008 Roy Marples <roy@marples.name>
|
* Copyright 2007-2008 Roy Marples <roy@marples.name>
|
||||||
@ -33,13 +33,13 @@ const char librc_copyright[] = "Copyright (c) 2007-2008 Roy Marples";
|
|||||||
|
|
||||||
#include "librc.h"
|
#include "librc.h"
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
#include <sys/sysctl.h>
|
# include <sys/sysctl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define RC_RUNLEVEL RC_SVCDIR "/softlevel"
|
#define RC_RUNLEVEL RC_SVCDIR "/softlevel"
|
||||||
|
|
||||||
#ifndef S_IXUGO
|
#ifndef S_IXUGO
|
||||||
# define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH)
|
# define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* File stream used for plugins to write environ vars to */
|
/* File stream used for plugins to write environ vars to */
|
||||||
@ -88,7 +88,7 @@ ls_dir(const char *dir, int options)
|
|||||||
* This is important as a service maybe in a
|
* This is important as a service maybe in a
|
||||||
* runlevel, but could have been removed. */
|
* runlevel, but could have been removed. */
|
||||||
snprintf(file, sizeof(file), "%s/%s",
|
snprintf(file, sizeof(file), "%s/%s",
|
||||||
dir, d->d_name);
|
dir, d->d_name);
|
||||||
r = stat(file, &buf);
|
r = stat(file, &buf);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
continue;
|
continue;
|
||||||
@ -130,7 +130,7 @@ rm_dir(const char *pathname, bool top)
|
|||||||
strcmp(d->d_name, "..") != 0)
|
strcmp(d->d_name, "..") != 0)
|
||||||
{
|
{
|
||||||
snprintf(file, sizeof(file),
|
snprintf(file, sizeof(file),
|
||||||
"%s/%s", pathname, d->d_name);
|
"%s/%s", pathname, d->d_name);
|
||||||
if (stat(file, &s) != 0) {
|
if (stat(file, &s) != 0) {
|
||||||
retval = false;
|
retval = false;
|
||||||
break;
|
break;
|
||||||
@ -229,12 +229,12 @@ rc_sys(void)
|
|||||||
} else if (file_regex("/proc/cpuinfo", "UML"))
|
} else if (file_regex("/proc/cpuinfo", "UML"))
|
||||||
return RC_SYS_UML;
|
return RC_SYS_UML;
|
||||||
else if (file_regex("/proc/self/status",
|
else if (file_regex("/proc/self/status",
|
||||||
"(s_context|VxID):[[:space:]]*[1-9]"))
|
"(s_context|VxID):[[:space:]]*[1-9]"))
|
||||||
return RC_SYS_VSERVER;
|
return RC_SYS_VSERVER;
|
||||||
else if (exists("/proc/vz/veinfo") && !exists("/proc/vz/version"))
|
else if (exists("/proc/vz/veinfo") && !exists("/proc/vz/version"))
|
||||||
return RC_SYS_OPENVZ;
|
return RC_SYS_OPENVZ;
|
||||||
else if (file_regex("/proc/self/status",
|
else if (file_regex("/proc/self/status",
|
||||||
"envID:[[:space:]]*[1-9]"))
|
"envID:[[:space:]]*[1-9]"))
|
||||||
return RC_SYS_OPENVZ; /* old test */
|
return RC_SYS_OPENVZ; /* old test */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -349,7 +349,7 @@ rc_service_resolve(const char *service)
|
|||||||
snprintf(file, sizeof(file), RC_SVCDIR "/%s/%s", "started", service);
|
snprintf(file, sizeof(file), RC_SVCDIR "/%s/%s", "started", service);
|
||||||
if (lstat(file, &buf) || ! S_ISLNK(buf.st_mode)) {
|
if (lstat(file, &buf) || ! S_ISLNK(buf.st_mode)) {
|
||||||
snprintf(file, sizeof(file), RC_SVCDIR "/%s/%s",
|
snprintf(file, sizeof(file), RC_SVCDIR "/%s/%s",
|
||||||
"inactive", service);
|
"inactive", service);
|
||||||
if (lstat(file, &buf) || ! S_ISLNK(buf.st_mode))
|
if (lstat(file, &buf) || ! S_ISLNK(buf.st_mode))
|
||||||
*file = '\0';
|
*file = '\0';
|
||||||
}
|
}
|
||||||
@ -497,7 +497,7 @@ rc_service_in_runlevel(const char *service, const char *runlevel)
|
|||||||
char file[PATH_MAX];
|
char file[PATH_MAX];
|
||||||
|
|
||||||
snprintf(file, sizeof(file), RC_RUNLEVELDIR "/%s/%s",
|
snprintf(file, sizeof(file), RC_RUNLEVELDIR "/%s/%s",
|
||||||
runlevel, basename_c(service));
|
runlevel, basename_c(service));
|
||||||
return exists(file);
|
return exists(file);
|
||||||
}
|
}
|
||||||
librc_hidden_def(rc_service_in_runlevel)
|
librc_hidden_def(rc_service_in_runlevel)
|
||||||
@ -528,7 +528,7 @@ rc_service_mark(const char *service, const RC_SERVICE state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
snprintf(file, sizeof(file), RC_SVCDIR "/%s/%s",
|
snprintf(file, sizeof(file), RC_SVCDIR "/%s/%s",
|
||||||
rc_parse_service_state(state), base);
|
rc_parse_service_state(state), base);
|
||||||
if (exists(file))
|
if (exists(file))
|
||||||
unlink(file);
|
unlink(file);
|
||||||
i = symlink(init, file);
|
i = symlink(init, file);
|
||||||
@ -549,22 +549,22 @@ rc_service_mark(const char *service, const RC_SERVICE state)
|
|||||||
s = rc_service_state_names[i].state;
|
s = rc_service_state_names[i].state;
|
||||||
|
|
||||||
if ((s != skip_state &&
|
if ((s != skip_state &&
|
||||||
s != RC_SERVICE_STOPPED &&
|
s != RC_SERVICE_STOPPED &&
|
||||||
s != RC_SERVICE_HOTPLUGGED &&
|
s != RC_SERVICE_HOTPLUGGED &&
|
||||||
s != RC_SERVICE_SCHEDULED) &&
|
s != RC_SERVICE_SCHEDULED) &&
|
||||||
(! skip_wasinactive || s != RC_SERVICE_WASINACTIVE))
|
(! skip_wasinactive || s != RC_SERVICE_WASINACTIVE))
|
||||||
{
|
{
|
||||||
snprintf(file, sizeof(file), RC_SVCDIR "/%s/%s",
|
snprintf(file, sizeof(file), RC_SVCDIR "/%s/%s",
|
||||||
rc_service_state_names[i].name, base);
|
rc_service_state_names[i].name, base);
|
||||||
if (exists(file)) {
|
if (exists(file)) {
|
||||||
if ((state == RC_SERVICE_STARTING ||
|
if ((state == RC_SERVICE_STARTING ||
|
||||||
state == RC_SERVICE_STOPPING) &&
|
state == RC_SERVICE_STOPPING) &&
|
||||||
s == RC_SERVICE_INACTIVE)
|
s == RC_SERVICE_INACTIVE)
|
||||||
{
|
{
|
||||||
snprintf(was, sizeof(was),
|
snprintf(was, sizeof(was),
|
||||||
RC_SVCDIR "/%s/%s",
|
RC_SVCDIR "/%s/%s",
|
||||||
rc_parse_service_state(RC_SERVICE_WASINACTIVE),
|
rc_parse_service_state(RC_SERVICE_WASINACTIVE),
|
||||||
base);
|
base);
|
||||||
if (symlink(init, was) == -1)
|
if (symlink(init, was) == -1)
|
||||||
return false;
|
return false;
|
||||||
skip_wasinactive = true;
|
skip_wasinactive = true;
|
||||||
@ -583,18 +583,18 @@ rc_service_mark(const char *service, const RC_SERVICE state)
|
|||||||
state == RC_SERVICE_INACTIVE)
|
state == RC_SERVICE_INACTIVE)
|
||||||
{
|
{
|
||||||
snprintf(file, sizeof(file), RC_SVCDIR "/%s/%s",
|
snprintf(file, sizeof(file), RC_SVCDIR "/%s/%s",
|
||||||
"exclusive", base);
|
"exclusive", base);
|
||||||
unlink(file);
|
unlink(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove any options and daemons the service may have stored */
|
/* Remove any options and daemons the service may have stored */
|
||||||
if (state == RC_SERVICE_STOPPED) {
|
if (state == RC_SERVICE_STOPPED) {
|
||||||
snprintf(file, sizeof(file), RC_SVCDIR "/%s/%s",
|
snprintf(file, sizeof(file), RC_SVCDIR "/%s/%s",
|
||||||
"options", base);
|
"options", base);
|
||||||
rm_dir(file, true);
|
rm_dir(file, true);
|
||||||
|
|
||||||
snprintf(file, sizeof(file), RC_SVCDIR "/%s/%s",
|
snprintf(file, sizeof(file), RC_SVCDIR "/%s/%s",
|
||||||
"daemons", base);
|
"daemons", base);
|
||||||
rm_dir(file, true);
|
rm_dir(file, true);
|
||||||
|
|
||||||
rc_service_schedule_clear(service);
|
rc_service_schedule_clear(service);
|
||||||
@ -606,7 +606,7 @@ rc_service_mark(const char *service, const RC_SERVICE state)
|
|||||||
dirs = ls_dir(file, 0);
|
dirs = ls_dir(file, 0);
|
||||||
TAILQ_FOREACH(dir, dirs, entries) {
|
TAILQ_FOREACH(dir, dirs, entries) {
|
||||||
snprintf(was, sizeof(was), "%s/%s/%s",
|
snprintf(was, sizeof(was), "%s/%s/%s",
|
||||||
file, dir->value, base);
|
file, dir->value, base);
|
||||||
unlink(was);
|
unlink(was);
|
||||||
|
|
||||||
/* Try and remove the dir; we don't care about errors */
|
/* Try and remove the dir; we don't care about errors */
|
||||||
@ -634,7 +634,7 @@ rc_service_state(const char *service)
|
|||||||
|
|
||||||
for (i = 0; rc_service_state_names[i].name; i++) {
|
for (i = 0; rc_service_state_names[i].name; i++) {
|
||||||
snprintf(file, sizeof(file), RC_SVCDIR "/%s/%s",
|
snprintf(file, sizeof(file), RC_SVCDIR "/%s/%s",
|
||||||
rc_service_state_names[i].name, base);
|
rc_service_state_names[i].name, base);
|
||||||
if (exists(file)) {
|
if (exists(file)) {
|
||||||
if (rc_service_state_names[i].state <= 0x10)
|
if (rc_service_state_names[i].state <= 0x10)
|
||||||
state = rc_service_state_names[i].state;
|
state = rc_service_state_names[i].state;
|
||||||
@ -647,8 +647,8 @@ rc_service_state(const char *service)
|
|||||||
dirs = ls_dir(RC_SVCDIR "/scheduled", 0);
|
dirs = ls_dir(RC_SVCDIR "/scheduled", 0);
|
||||||
TAILQ_FOREACH (dir, dirs, entries) {
|
TAILQ_FOREACH (dir, dirs, entries) {
|
||||||
snprintf(file, sizeof(file),
|
snprintf(file, sizeof(file),
|
||||||
RC_SVCDIR "/scheduled/%s/%s",
|
RC_SVCDIR "/scheduled/%s/%s",
|
||||||
dir->value, service);
|
dir->value, service);
|
||||||
if (exists(file)) {
|
if (exists(file)) {
|
||||||
state |= RC_SERVICE_SCHEDULED;
|
state |= RC_SERVICE_SCHEDULED;
|
||||||
break;
|
break;
|
||||||
@ -670,7 +670,7 @@ rc_service_value_get(const char *service, const char *option)
|
|||||||
char file[PATH_MAX];
|
char file[PATH_MAX];
|
||||||
|
|
||||||
snprintf(file, sizeof(file), RC_SVCDIR "/options/%s/%s",
|
snprintf(file, sizeof(file), RC_SVCDIR "/options/%s/%s",
|
||||||
service, option);
|
service, option);
|
||||||
if ((fp = fopen(file, "r"))) {
|
if ((fp = fopen(file, "r"))) {
|
||||||
rc_getline(&line, &len, fp);
|
rc_getline(&line, &len, fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
@ -682,7 +682,7 @@ librc_hidden_def(rc_service_value_get)
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
rc_service_value_set(const char *service, const char *option,
|
rc_service_value_set(const char *service, const char *option,
|
||||||
const char *value)
|
const char *value)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char file[PATH_MAX];
|
char file[PATH_MAX];
|
||||||
@ -716,13 +716,13 @@ rc_service_schedule_start(const char *service, const char *service_to_start)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
p += snprintf(file, sizeof(file), RC_SVCDIR "/scheduled/%s",
|
p += snprintf(file, sizeof(file), RC_SVCDIR "/scheduled/%s",
|
||||||
basename_c(service));
|
basename_c(service));
|
||||||
if (mkdir(file, 0755) != 0 && errno != EEXIST)
|
if (mkdir(file, 0755) != 0 && errno != EEXIST)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
init = rc_service_resolve(service_to_start);
|
init = rc_service_resolve(service_to_start);
|
||||||
snprintf(p, sizeof(file) - (p - file),
|
snprintf(p, sizeof(file) - (p - file),
|
||||||
"/%s", basename_c(service_to_start));
|
"/%s", basename_c(service_to_start));
|
||||||
retval = (exists(file) || symlink(init, file) == 0);
|
retval = (exists(file) || symlink(init, file) == 0);
|
||||||
free(init);
|
free(init);
|
||||||
return retval;
|
return retval;
|
||||||
@ -735,7 +735,7 @@ rc_service_schedule_clear(const char *service)
|
|||||||
char dir[PATH_MAX];
|
char dir[PATH_MAX];
|
||||||
|
|
||||||
snprintf(dir, sizeof(dir), RC_SVCDIR "/scheduled/%s",
|
snprintf(dir, sizeof(dir), RC_SVCDIR "/scheduled/%s",
|
||||||
basename_c(service));
|
basename_c(service));
|
||||||
if (!rm_dir(dir, true) && errno == ENOENT)
|
if (!rm_dir(dir, true) && errno == ENOENT)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
@ -791,7 +791,7 @@ rc_services_in_state(RC_SERVICE state)
|
|||||||
char *p = dir;
|
char *p = dir;
|
||||||
|
|
||||||
p += snprintf(dir, sizeof(dir), RC_SVCDIR "/%s",
|
p += snprintf(dir, sizeof(dir), RC_SVCDIR "/%s",
|
||||||
rc_parse_service_state(state));
|
rc_parse_service_state(state));
|
||||||
|
|
||||||
if (state != RC_SERVICE_SCHEDULED)
|
if (state != RC_SERVICE_SCHEDULED)
|
||||||
return ls_dir(dir, LS_INITD);
|
return ls_dir(dir, LS_INITD);
|
||||||
@ -837,7 +837,7 @@ rc_service_add(const char *runlevel, const char *service)
|
|||||||
|
|
||||||
i = init = rc_service_resolve(service);
|
i = init = rc_service_resolve(service);
|
||||||
snprintf(file, sizeof(file), RC_RUNLEVELDIR "/%s/%s",
|
snprintf(file, sizeof(file), RC_RUNLEVELDIR "/%s/%s",
|
||||||
runlevel, basename_c(service));
|
runlevel, basename_c(service));
|
||||||
|
|
||||||
/* We need to ensure that only things in /etc/init.d are added
|
/* We need to ensure that only things in /etc/init.d are added
|
||||||
* to the boot runlevel */
|
* to the boot runlevel */
|
||||||
@ -868,7 +868,7 @@ rc_service_delete(const char *runlevel, const char *service)
|
|||||||
char file[PATH_MAX];
|
char file[PATH_MAX];
|
||||||
|
|
||||||
snprintf(file, sizeof(file), RC_RUNLEVELDIR "/%s/%s",
|
snprintf(file, sizeof(file), RC_RUNLEVELDIR "/%s/%s",
|
||||||
runlevel, basename_c(service));
|
runlevel, basename_c(service));
|
||||||
if (unlink(file) == 0)
|
if (unlink(file) == 0)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
@ -885,7 +885,7 @@ rc_services_scheduled_by(const char *service)
|
|||||||
|
|
||||||
TAILQ_FOREACH (dir, dirs, entries) {
|
TAILQ_FOREACH (dir, dirs, entries) {
|
||||||
snprintf(file, sizeof(file), RC_SVCDIR "/scheduled/%s/%s",
|
snprintf(file, sizeof(file), RC_SVCDIR "/scheduled/%s/%s",
|
||||||
dir->value, service);
|
dir->value, service);
|
||||||
if (exists(file))
|
if (exists(file))
|
||||||
rc_stringlist_add(list, file);
|
rc_stringlist_add(list, file);
|
||||||
}
|
}
|
||||||
@ -900,7 +900,7 @@ rc_services_scheduled(const char *service)
|
|||||||
char dir[PATH_MAX];
|
char dir[PATH_MAX];
|
||||||
|
|
||||||
snprintf(dir, sizeof(dir), RC_SVCDIR "/scheduled/%s",
|
snprintf(dir, sizeof(dir), RC_SVCDIR "/scheduled/%s",
|
||||||
basename_c(service));
|
basename_c(service));
|
||||||
return ls_dir(dir, LS_INITD);
|
return ls_dir(dir, LS_INITD);
|
||||||
}
|
}
|
||||||
librc_hidden_def(rc_services_scheduled)
|
librc_hidden_def(rc_services_scheduled)
|
||||||
|
@ -25,15 +25,16 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#if lint
|
#if lint
|
||||||
# define _noreturn
|
# define _noreturn
|
||||||
#endif
|
#endif
|
||||||
#if __GNUC__ > 2 || defined(__INTEL_COMPILER)
|
#if __GNUC__ > 2 || defined(__INTEL_COMPILER)
|
||||||
# define _noreturn __attribute__ ((__noreturn__))
|
# define _noreturn __attribute__ ((__noreturn__))
|
||||||
#else
|
#else
|
||||||
# define _noreturn
|
# define _noreturn
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_noreturn static void usage(int exit_status)
|
_noreturn static void
|
||||||
|
usage(int exit_status)
|
||||||
{
|
{
|
||||||
const char * const has_arg[] = { "", "<arg>", "[arg]" };
|
const char * const has_arg[] = { "", "<arg>", "[arg]" };
|
||||||
int i;
|
int i;
|
||||||
@ -53,7 +54,7 @@ _noreturn static void usage(int exit_status)
|
|||||||
printf("\n\nOptions: [" getoptstring "]\n");
|
printf("\n\nOptions: [" getoptstring "]\n");
|
||||||
for (i = 0; longopts[i].name; ++i) {
|
for (i = 0; longopts[i].name; ++i) {
|
||||||
len = printf(" -%c, --%s %s", longopts[i].val, longopts[i].name,
|
len = printf(" -%c, --%s %s", longopts[i].val, longopts[i].name,
|
||||||
has_arg[longopts[i].has_arg]);
|
has_arg[longopts[i].has_arg]);
|
||||||
|
|
||||||
lo = p = xstrdup(longopts_help[i]);
|
lo = p = xstrdup(longopts_help[i]);
|
||||||
while ((token = strsep(&p, "\n"))) {
|
while ((token = strsep(&p, "\n"))) {
|
||||||
|
@ -26,17 +26,17 @@
|
|||||||
|
|
||||||
#define getoptstring_COMMON "Chqv"
|
#define getoptstring_COMMON "Chqv"
|
||||||
|
|
||||||
#define longopts_COMMON \
|
#define longopts_COMMON \
|
||||||
{ "help", 0, NULL, 'h'}, \
|
{ "help", 0, NULL, 'h'}, \
|
||||||
{ "nocolor", 0, NULL, 'C'}, \
|
{ "nocolor", 0, NULL, 'C'}, \
|
||||||
{ "verbose", 0, NULL, 'v'}, \
|
{ "verbose", 0, NULL, 'v'}, \
|
||||||
{ "quiet", 0, NULL, 'q'}, \
|
{ "quiet", 0, NULL, 'q'}, \
|
||||||
{ NULL, 0, NULL, 0 }
|
{ NULL, 0, NULL, 0 }
|
||||||
|
|
||||||
#define longopts_help_COMMON \
|
#define longopts_help_COMMON \
|
||||||
"Display this help output", \
|
"Display this help output", \
|
||||||
"Disable color output", \
|
"Disable color output", \
|
||||||
"Run verbosely", \
|
"Run verbosely", \
|
||||||
"Run quietly"
|
"Run quietly"
|
||||||
|
|
||||||
#define case_RC_COMMON_getopt_case_C setenv ("EINFO_COLOR", "NO", 1);
|
#define case_RC_COMMON_getopt_case_C setenv ("EINFO_COLOR", "NO", 1);
|
||||||
@ -45,9 +45,9 @@
|
|||||||
#define case_RC_COMMON_getopt_case_q setenv ("EINFO_QUIET", "YES", 1);
|
#define case_RC_COMMON_getopt_case_q setenv ("EINFO_QUIET", "YES", 1);
|
||||||
#define case_RC_COMMON_getopt_default usage (EXIT_FAILURE);
|
#define case_RC_COMMON_getopt_default usage (EXIT_FAILURE);
|
||||||
|
|
||||||
#define case_RC_COMMON_GETOPT \
|
#define case_RC_COMMON_GETOPT \
|
||||||
case 'C': case_RC_COMMON_getopt_case_C; break; \
|
case 'C': case_RC_COMMON_getopt_case_C; break; \
|
||||||
case 'h': case_RC_COMMON_getopt_case_h; break; \
|
case 'h': case_RC_COMMON_getopt_case_h; break; \
|
||||||
case 'v': case_RC_COMMON_getopt_case_v; break; \
|
case 'v': case_RC_COMMON_getopt_case_v; break; \
|
||||||
case 'q': case_RC_COMMON_getopt_case_q; break; \
|
case 'q': case_RC_COMMON_getopt_case_q; break; \
|
||||||
default: case_RC_COMMON_getopt_default; break;
|
default: case_RC_COMMON_getopt_default; break;
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
checkpath.c
|
checkpath.c
|
||||||
Checks for the existance of a file or directory and creates it
|
Checks for the existance of a file or directory and creates it
|
||||||
if necessary. It can also correct its ownership.
|
if necessary. It can also correct its ownership.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2007-2008 Roy Marples <roy@marples.name>
|
* Copyright 2007-2008 Roy Marples <roy@marples.name>
|
||||||
@ -49,7 +49,8 @@
|
|||||||
|
|
||||||
extern const char *applet;
|
extern const char *applet;
|
||||||
|
|
||||||
static int do_check(char *path, uid_t uid, gid_t gid, mode_t mode, int file)
|
static int
|
||||||
|
do_check(char *path, uid_t uid, gid_t gid, mode_t mode, int file)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
int fd;
|
int fd;
|
||||||
@ -57,8 +58,9 @@ static int do_check(char *path, uid_t uid, gid_t gid, mode_t mode, int file)
|
|||||||
if (stat(path, &st)) {
|
if (stat(path, &st)) {
|
||||||
if (file) {
|
if (file) {
|
||||||
einfo("%s: creating file", path);
|
einfo("%s: creating file", path);
|
||||||
if (! mode)
|
if (!mode)
|
||||||
mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;
|
mode = S_IRUSR | S_IWUSR | S_IRGRP |
|
||||||
|
S_IWGRP | S_IROTH;
|
||||||
if ((fd = open(path, O_CREAT, mode)) == -1) {
|
if ((fd = open(path, O_CREAT, mode)) == -1) {
|
||||||
eerror("%s: open: %s", applet, strerror(errno));
|
eerror("%s: open: %s", applet, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
@ -66,17 +68,18 @@ static int do_check(char *path, uid_t uid, gid_t gid, mode_t mode, int file)
|
|||||||
close (fd);
|
close (fd);
|
||||||
} else {
|
} else {
|
||||||
einfo("%s: creating directory", path);
|
einfo("%s: creating directory", path);
|
||||||
if (! mode)
|
if (!mode)
|
||||||
mode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH;
|
mode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH;
|
||||||
if (mkdir(path, mode)) {
|
if (mkdir(path, mode)) {
|
||||||
eerror("%s: mkdir: %s", applet, strerror (errno));
|
eerror("%s: mkdir: %s", applet,
|
||||||
|
strerror (errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
mode = 0;
|
mode = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((file && S_ISDIR(st.st_mode)) ||
|
if ((file && S_ISDIR(st.st_mode)) ||
|
||||||
(! file && ! S_ISDIR(st.st_mode)))
|
(!file && !S_ISDIR(st.st_mode)))
|
||||||
{
|
{
|
||||||
if (file)
|
if (file)
|
||||||
eerror("%s: is a directory", path);
|
eerror("%s: is a directory", path);
|
||||||
@ -106,8 +109,8 @@ static int do_check(char *path, uid_t uid, gid_t gid, mode_t mode, int file)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_owner(struct passwd **user, struct group **group,
|
static int
|
||||||
const char *owner)
|
parse_owner(struct passwd **user, struct group **group, const char *owner)
|
||||||
{
|
{
|
||||||
char *u = xstrdup (owner);
|
char *u = xstrdup (owner);
|
||||||
char *g = strchr (u, ':');
|
char *g = strchr (u, ':');
|
||||||
@ -122,7 +125,7 @@ static int parse_owner(struct passwd **user, struct group **group,
|
|||||||
*user = getpwuid((uid_t) id);
|
*user = getpwuid((uid_t) id);
|
||||||
else
|
else
|
||||||
*user = getpwnam(u);
|
*user = getpwnam(u);
|
||||||
if (! *user)
|
if (*user == NULL)
|
||||||
retval = -1;
|
retval = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,7 +134,7 @@ static int parse_owner(struct passwd **user, struct group **group,
|
|||||||
*group = getgrgid((gid_t) id);
|
*group = getgrgid((gid_t) id);
|
||||||
else
|
else
|
||||||
*group = getgrnam(g);
|
*group = getgrnam(g);
|
||||||
if (! *group)
|
if (*group == NULL)
|
||||||
retval = -1;
|
retval = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,7 +161,8 @@ static const char * const longopts_help[] = {
|
|||||||
};
|
};
|
||||||
#include "_usage.c"
|
#include "_usage.c"
|
||||||
|
|
||||||
int checkpath(int argc, char **argv)
|
int
|
||||||
|
checkpath(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int opt;
|
int opt;
|
||||||
uid_t uid = geteuid();
|
uid_t uid = geteuid();
|
||||||
@ -170,7 +174,7 @@ int checkpath(int argc, char **argv)
|
|||||||
int retval = EXIT_SUCCESS;
|
int retval = EXIT_SUCCESS;
|
||||||
|
|
||||||
while ((opt = getopt_long(argc, argv, getoptstring,
|
while ((opt = getopt_long(argc, argv, getoptstring,
|
||||||
longopts, (int *) 0)) != -1)
|
longopts, (int *) 0)) != -1)
|
||||||
{
|
{
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'd':
|
case 'd':
|
||||||
@ -181,14 +185,16 @@ int checkpath(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
if (parse_mode(&mode, optarg) != 0)
|
if (parse_mode(&mode, optarg) != 0)
|
||||||
eerrorx("%s: invalid mode `%s'", applet, optarg);
|
eerrorx("%s: invalid mode `%s'",
|
||||||
|
applet, optarg);
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
if (parse_owner(&pw, &gr, optarg) != 0)
|
if (parse_owner(&pw, &gr, optarg) != 0)
|
||||||
eerrorx("%s: owner `%s' not found", applet, optarg);
|
eerrorx("%s: owner `%s' not found",
|
||||||
|
applet, optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case_RC_COMMON_GETOPT
|
case_RC_COMMON_GETOPT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
fstabinfo.c
|
fstabinfo.c
|
||||||
Gets information about /etc/fstab.
|
Gets information about /etc/fstab.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2007-2008 Roy Marples <roy@marples.name>
|
* Copyright 2007-2008 Roy Marples <roy@marples.name>
|
||||||
@ -42,31 +42,31 @@
|
|||||||
Okay, we could use getfsent but the man page says use getmntent instead
|
Okay, we could use getfsent but the man page says use getmntent instead
|
||||||
AND we don't have getfsent on uclibc or dietlibc for some odd reason. */
|
AND we don't have getfsent on uclibc or dietlibc for some odd reason. */
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
#define HAVE_GETMNTENT
|
# define HAVE_GETMNTENT
|
||||||
#include <mntent.h>
|
# include <mntent.h>
|
||||||
#define ENT mntent
|
# define ENT mntent
|
||||||
#define START_ENT fp = setmntent ("/etc/fstab", "r");
|
# define START_ENT fp = setmntent ("/etc/fstab", "r");
|
||||||
#define GET_ENT getmntent (fp)
|
# define GET_ENT getmntent (fp)
|
||||||
#define GET_ENT_FILE(_name) getmntfile (_name)
|
# define GET_ENT_FILE(_name) getmntfile (_name)
|
||||||
#define END_ENT endmntent (fp)
|
# define END_ENT endmntent (fp)
|
||||||
#define ENT_BLOCKDEVICE(_ent) ent->mnt_fsname
|
# define ENT_BLOCKDEVICE(_ent) ent->mnt_fsname
|
||||||
#define ENT_FILE(_ent) ent->mnt_dir
|
# define ENT_FILE(_ent) ent->mnt_dir
|
||||||
#define ENT_TYPE(_ent) ent->mnt_type
|
# define ENT_TYPE(_ent) ent->mnt_type
|
||||||
#define ENT_OPTS(_ent) ent->mnt_opts
|
# define ENT_OPTS(_ent) ent->mnt_opts
|
||||||
#define ENT_PASS(_ent) ent->mnt_passno
|
# define ENT_PASS(_ent) ent->mnt_passno
|
||||||
#else
|
#else
|
||||||
#define HAVE_GETFSENT
|
# define HAVE_GETFSENT
|
||||||
#include <fstab.h>
|
# include <fstab.h>
|
||||||
#define ENT fstab
|
# define ENT fstab
|
||||||
#define START_ENT
|
# define START_ENT
|
||||||
#define GET_ENT getfsent ()
|
# define GET_ENT getfsent ()
|
||||||
#define GET_ENT_FILE(_name) getfsfile (_name)
|
# define GET_ENT_FILE(_name) getfsfile (_name)
|
||||||
#define END_ENT endfsent ()
|
# define END_ENT endfsent ()
|
||||||
#define ENT_BLOCKDEVICE(_ent) ent->fs_spec
|
# define ENT_BLOCKDEVICE(_ent) ent->fs_spec
|
||||||
#define ENT_TYPE(_ent) ent->fs_vfstype
|
# define ENT_TYPE(_ent) ent->fs_vfstype
|
||||||
#define ENT_FILE(_ent) ent->fs_file
|
# define ENT_FILE(_ent) ent->fs_file
|
||||||
#define ENT_OPTS(_ent) ent->fs_mntops
|
# define ENT_OPTS(_ent) ent->fs_mntops
|
||||||
#define ENT_PASS(_ent) ent->fs_passno
|
# define ENT_PASS(_ent) ent->fs_passno
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "builtins.h"
|
#include "builtins.h"
|
||||||
@ -93,7 +93,8 @@ getmntfile(const char *file)
|
|||||||
|
|
||||||
extern const char *applet;
|
extern const char *applet;
|
||||||
|
|
||||||
static int do_mount(struct ENT *ent)
|
static int
|
||||||
|
do_mount(struct ENT *ent)
|
||||||
{
|
{
|
||||||
char *argv[8];
|
char *argv[8];
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
@ -176,7 +177,7 @@ fstabinfo(int argc, char **argv)
|
|||||||
unsetenv("EINFO_QUIET");
|
unsetenv("EINFO_QUIET");
|
||||||
|
|
||||||
while ((opt = getopt_long(argc, argv, getoptstring,
|
while ((opt = getopt_long(argc, argv, getoptstring,
|
||||||
longopts, (int *) 0)) != -1)
|
longopts, (int *) 0)) != -1)
|
||||||
{
|
{
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'M':
|
case 'M':
|
||||||
@ -199,7 +200,7 @@ fstabinfo(int argc, char **argv)
|
|||||||
case '>':
|
case '>':
|
||||||
if (sscanf(optarg + 1, "%d", &i) != 1)
|
if (sscanf(optarg + 1, "%d", &i) != 1)
|
||||||
eerrorx("%s: invalid passno %s",
|
eerrorx("%s: invalid passno %s",
|
||||||
argv[0], optarg + 1);
|
argv[0], optarg + 1);
|
||||||
|
|
||||||
filtered = true;
|
filtered = true;
|
||||||
opt = optarg[0];
|
opt = optarg[0];
|
||||||
@ -212,7 +213,7 @@ fstabinfo(int argc, char **argv)
|
|||||||
(opt == '<' && i > p && p != 0) ||
|
(opt == '<' && i > p && p != 0) ||
|
||||||
(opt == '>' && i < p && p != 0))
|
(opt == '>' && i < p && p != 0))
|
||||||
rc_stringlist_add(files,
|
rc_stringlist_add(files,
|
||||||
ENT_FILE(ent));
|
ENT_FILE(ent));
|
||||||
}
|
}
|
||||||
END_ENT;
|
END_ENT;
|
||||||
break;
|
break;
|
||||||
@ -222,7 +223,7 @@ fstabinfo(int argc, char **argv)
|
|||||||
output = OUTPUT_PASSNO;
|
output = OUTPUT_PASSNO;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 't':
|
case 't':
|
||||||
filtered = true;
|
filtered = true;
|
||||||
@ -230,13 +231,14 @@ fstabinfo(int argc, char **argv)
|
|||||||
START_ENT;
|
START_ENT;
|
||||||
while ((ent = GET_ENT))
|
while ((ent = GET_ENT))
|
||||||
if (strcmp(token, ENT_TYPE(ent)) == 0)
|
if (strcmp(token, ENT_TYPE(ent)) == 0)
|
||||||
rc_stringlist_add(files, ENT_FILE(ent));
|
rc_stringlist_add(files,
|
||||||
|
ENT_FILE(ent));
|
||||||
END_ENT;
|
END_ENT;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case_RC_COMMON_GETOPT
|
case_RC_COMMON_GETOPT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optind < argc) {
|
if (optind < argc) {
|
||||||
@ -246,7 +248,8 @@ fstabinfo(int argc, char **argv)
|
|||||||
if (strcmp(argv[i], file->value) == 0)
|
if (strcmp(argv[i], file->value) == 0)
|
||||||
break;
|
break;
|
||||||
if (i >= argc)
|
if (i >= argc)
|
||||||
rc_stringlist_delete(files, file->value);
|
rc_stringlist_delete(files,
|
||||||
|
file->value);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while (optind < argc)
|
while (optind < argc)
|
||||||
@ -290,10 +293,10 @@ fstabinfo(int argc, char **argv)
|
|||||||
|
|
||||||
case OUTPUT_MOUNTARGS:
|
case OUTPUT_MOUNTARGS:
|
||||||
printf("-o %s -t %s %s %s\n",
|
printf("-o %s -t %s %s %s\n",
|
||||||
ENT_OPTS(ent),
|
ENT_OPTS(ent),
|
||||||
ENT_TYPE(ent),
|
ENT_TYPE(ent),
|
||||||
ENT_BLOCKDEVICE(ent),
|
ENT_BLOCKDEVICE(ent),
|
||||||
file->value);
|
file->value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OUTPUT_OPTIONS:
|
case OUTPUT_OPTIONS:
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
mountinfo.c
|
mountinfo.c
|
||||||
Obtains information about mounted filesystems.
|
Obtains information about mounted filesystems.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2007-2008 Roy Marples <roy@marples.name>
|
* Copyright 2007-2008 Roy Marples <roy@marples.name>
|
||||||
@ -33,15 +33,15 @@
|
|||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
|
||||||
#if defined(__DragonFly__) || defined(__FreeBSD__)
|
#if defined(__DragonFly__) || defined(__FreeBSD__)
|
||||||
# include <sys/ucred.h>
|
# include <sys/ucred.h>
|
||||||
# include <sys/mount.h>
|
# include <sys/mount.h>
|
||||||
# define F_FLAGS f_flags
|
# define F_FLAGS f_flags
|
||||||
#elif defined(BSD)
|
#elif defined(BSD)
|
||||||
# include <sys/statvfs.h>
|
# include <sys/statvfs.h>
|
||||||
# define statfs statvfs
|
# define statfs statvfs
|
||||||
# define F_FLAGS f_flag
|
# define F_FLAGS f_flag
|
||||||
#elif defined (__linux__)
|
#elif defined (__linux__)
|
||||||
#include <mntent.h>
|
# include <mntent.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@ -84,9 +84,10 @@ struct args {
|
|||||||
net_opts netdev;
|
net_opts netdev;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int process_mount(RC_STRINGLIST *list, struct args *args,
|
static int
|
||||||
char *from, char *to, char *fstype, char *options,
|
process_mount(RC_STRINGLIST *list, struct args *args,
|
||||||
int netdev)
|
char *from, char *to, char *fstype, char *options,
|
||||||
|
int netdev)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
RC_STRING *s;
|
RC_STRING *s;
|
||||||
@ -105,7 +106,7 @@ static int process_mount(RC_STRINGLIST *list, struct args *args,
|
|||||||
if (netdev != 0)
|
if (netdev != 0)
|
||||||
return 1;
|
return 1;
|
||||||
} else if (args->netdev == net_no &&
|
} else if (args->netdev == net_no &&
|
||||||
(netdev != -1 || TAILQ_FIRST(args->mounts)))
|
(netdev != -1 || TAILQ_FIRST(args->mounts)))
|
||||||
{
|
{
|
||||||
if (netdev != 1)
|
if (netdev != 1)
|
||||||
return 1;
|
return 1;
|
||||||
@ -134,8 +135,8 @@ static int process_mount(RC_STRINGLIST *list, struct args *args,
|
|||||||
|
|
||||||
if (TAILQ_FIRST(args->mounts)) {
|
if (TAILQ_FIRST(args->mounts)) {
|
||||||
TAILQ_FOREACH(s, args->mounts, entries)
|
TAILQ_FOREACH(s, args->mounts, entries)
|
||||||
if (strcmp(s->value, to) == 0)
|
if (strcmp(s->value, to) == 0)
|
||||||
break;
|
break;
|
||||||
if (! s)
|
if (! s)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -211,7 +212,8 @@ static struct opt {
|
|||||||
{ 0, NULL }
|
{ 0, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
static RC_STRINGLIST *find_mounts(struct args *args)
|
static RC_STRINGLIST *
|
||||||
|
find_mounts(struct args *args)
|
||||||
{
|
{
|
||||||
struct statfs *mnts;
|
struct statfs *mnts;
|
||||||
int nmnts;
|
int nmnts;
|
||||||
@ -238,9 +240,11 @@ static RC_STRINGLIST *find_mounts(struct args *args)
|
|||||||
if (! options)
|
if (! options)
|
||||||
options = xstrdup(o->o_name);
|
options = xstrdup(o->o_name);
|
||||||
else {
|
else {
|
||||||
l = strlen(options) + strlen(o->o_name) + 2;
|
l = strlen(options) +
|
||||||
|
strlen(o->o_name) + 2;
|
||||||
tmp = xmalloc(sizeof (char) * l);
|
tmp = xmalloc(sizeof (char) * l);
|
||||||
snprintf(tmp, l, "%s,%s", options, o->o_name);
|
snprintf(tmp, l, "%s,%s", options,
|
||||||
|
o->o_name);
|
||||||
free(options);
|
free(options);
|
||||||
options = tmp;
|
options = tmp;
|
||||||
}
|
}
|
||||||
@ -249,11 +253,11 @@ static RC_STRINGLIST *find_mounts(struct args *args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
process_mount(list, args,
|
process_mount(list, args,
|
||||||
mnts[i].f_mntfromname,
|
mnts[i].f_mntfromname,
|
||||||
mnts[i].f_mntonname,
|
mnts[i].f_mntonname,
|
||||||
mnts[i].f_fstypename,
|
mnts[i].f_fstypename,
|
||||||
options,
|
options,
|
||||||
netdev);
|
netdev);
|
||||||
|
|
||||||
free(options);
|
free(options);
|
||||||
options = NULL;
|
options = NULL;
|
||||||
@ -263,7 +267,8 @@ static RC_STRINGLIST *find_mounts(struct args *args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#elif defined (__linux__)
|
#elif defined (__linux__)
|
||||||
static struct mntent *getmntfile(const char *file)
|
static struct mntent *
|
||||||
|
getmntfile(const char *file)
|
||||||
{
|
{
|
||||||
struct mntent *ent = NULL;
|
struct mntent *ent = NULL;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
@ -277,7 +282,8 @@ static struct mntent *getmntfile(const char *file)
|
|||||||
return ent;
|
return ent;
|
||||||
}
|
}
|
||||||
|
|
||||||
static RC_STRINGLIST *find_mounts(struct args *args)
|
static RC_STRINGLIST *
|
||||||
|
find_mounts(struct args *args)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
@ -321,7 +327,8 @@ static RC_STRINGLIST *find_mounts(struct args *args)
|
|||||||
# error "Operating system not supported!"
|
# error "Operating system not supported!"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static regex_t *get_regex(const char *string)
|
static regex_t *
|
||||||
|
get_regex(const char *string)
|
||||||
{
|
{
|
||||||
regex_t *reg = xmalloc(sizeof (*reg));
|
regex_t *reg = xmalloc(sizeof (*reg));
|
||||||
int result;
|
int result;
|
||||||
@ -373,7 +380,8 @@ static const char * const longopts_help[] = {
|
|||||||
};
|
};
|
||||||
#include "_usage.c"
|
#include "_usage.c"
|
||||||
|
|
||||||
int mountinfo(int argc, char **argv)
|
int
|
||||||
|
mountinfo(int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct args args;
|
struct args args;
|
||||||
regex_t *point_regex = NULL;
|
regex_t *point_regex = NULL;
|
||||||
@ -387,10 +395,10 @@ int mountinfo(int argc, char **argv)
|
|||||||
/* Ensure that we are only quiet when explicitly told to be */
|
/* Ensure that we are only quiet when explicitly told to be */
|
||||||
unsetenv("EINFO_QUIET");
|
unsetenv("EINFO_QUIET");
|
||||||
|
|
||||||
#define DO_REG(_var) \
|
#define DO_REG(_var) \
|
||||||
if (_var) free(_var); \
|
if (_var) free(_var); \
|
||||||
_var = get_regex(optarg);
|
_var = get_regex(optarg);
|
||||||
#define REG_FREE(_var) \
|
#define REG_FREE(_var) \
|
||||||
if (_var) { regfree(_var); free(_var); }
|
if (_var) { regfree(_var); free(_var); }
|
||||||
|
|
||||||
memset (&args, 0, sizeof(args));
|
memset (&args, 0, sizeof(args));
|
||||||
@ -399,7 +407,7 @@ int mountinfo(int argc, char **argv)
|
|||||||
args.mounts = rc_stringlist_new();
|
args.mounts = rc_stringlist_new();
|
||||||
|
|
||||||
while ((opt = getopt_long(argc, argv, getoptstring,
|
while ((opt = getopt_long(argc, argv, getoptstring,
|
||||||
longopts, (int *) 0)) != -1)
|
longopts, (int *) 0)) != -1)
|
||||||
{
|
{
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'e':
|
case 'e':
|
||||||
@ -442,13 +450,14 @@ int mountinfo(int argc, char **argv)
|
|||||||
args.mount_type = mount_from;
|
args.mount_type = mount_from;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case_RC_COMMON_GETOPT
|
case_RC_COMMON_GETOPT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (optind < argc) {
|
while (optind < argc) {
|
||||||
if (argv[optind][0] != '/')
|
if (argv[optind][0] != '/')
|
||||||
eerrorx("%s: `%s' is not a mount point", argv[0], argv[optind]);
|
eerrorx("%s: `%s' is not a mount point",
|
||||||
|
argv[0], argv[optind]);
|
||||||
rc_stringlist_add(args.mounts, argv[optind++]);
|
rc_stringlist_add(args.mounts, argv[optind++]);
|
||||||
}
|
}
|
||||||
nodes = find_mounts(&args);
|
nodes = find_mounts(&args);
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
rc-applets.c
|
rc-applets.c
|
||||||
|
|
||||||
Handle multicall applets for use in our init scripts.
|
Handle multicall applets for use in our init scripts.
|
||||||
Basically this makes us a lot faster for the most part, and removes
|
Basically this makes us a lot faster for the most part, and removes
|
||||||
any shell incompatabilities we might otherwise encounter.
|
any shell incompatabilities we might otherwise encounter.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2007-2009 Roy Marples <roy@marples.name>
|
* Copyright 2007-2009 Roy Marples <roy@marples.name>
|
||||||
@ -60,7 +60,8 @@
|
|||||||
/* Applet is first parsed in rc.c - no point in doing it again */
|
/* Applet is first parsed in rc.c - no point in doing it again */
|
||||||
extern const char *applet;
|
extern const char *applet;
|
||||||
|
|
||||||
static int syslog_decode(char *name, CODE *codetab)
|
static int
|
||||||
|
syslog_decode(char *name, CODE *codetab)
|
||||||
{
|
{
|
||||||
CODE *c;
|
CODE *c;
|
||||||
|
|
||||||
@ -74,7 +75,8 @@ static int syslog_decode(char *name, CODE *codetab)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_e(int argc, char **argv)
|
static int
|
||||||
|
do_e(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int retval = EXIT_SUCCESS;
|
int retval = EXIT_SUCCESS;
|
||||||
int i;
|
int i;
|
||||||
@ -93,12 +95,12 @@ static int do_e(int argc, char **argv)
|
|||||||
|
|
||||||
if (strcmp(applet, "eval_ecolors") == 0) {
|
if (strcmp(applet, "eval_ecolors") == 0) {
|
||||||
printf("GOOD='%s'\nWARN='%s'\nBAD='%s'\nHILITE='%s'\nBRACKET='%s'\nNORMAL='%s'\n",
|
printf("GOOD='%s'\nWARN='%s'\nBAD='%s'\nHILITE='%s'\nBRACKET='%s'\nNORMAL='%s'\n",
|
||||||
ecolor(ECOLOR_GOOD),
|
ecolor(ECOLOR_GOOD),
|
||||||
ecolor(ECOLOR_WARN),
|
ecolor(ECOLOR_WARN),
|
||||||
ecolor(ECOLOR_BAD),
|
ecolor(ECOLOR_BAD),
|
||||||
ecolor(ECOLOR_HILITE),
|
ecolor(ECOLOR_HILITE),
|
||||||
ecolor(ECOLOR_BRACKET),
|
ecolor(ECOLOR_BRACKET),
|
||||||
ecolor(ECOLOR_NORMAL));
|
ecolor(ECOLOR_NORMAL));
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,9 +122,10 @@ static int do_e(int argc, char **argv)
|
|||||||
argv++;
|
argv++;
|
||||||
}
|
}
|
||||||
} else if (strcmp(applet, "esyslog") == 0 ||
|
} else if (strcmp(applet, "esyslog") == 0 ||
|
||||||
strcmp(applet, "elog") == 0) {
|
strcmp(applet, "elog") == 0) {
|
||||||
p = strchr(argv[0], '.');
|
p = strchr(argv[0], '.');
|
||||||
if (!p || (level = syslog_decode(p + 1, prioritynames)) == -1)
|
if (!p ||
|
||||||
|
(level = syslog_decode(p + 1, prioritynames)) == -1)
|
||||||
eerrorx("%s: invalid log level `%s'", applet, argv[0]);
|
eerrorx("%s: invalid log level `%s'", applet, argv[0]);
|
||||||
|
|
||||||
if (argc < 3)
|
if (argc < 3)
|
||||||
@ -160,7 +163,7 @@ static int do_e(int argc, char **argv)
|
|||||||
if (timercmp(&now, &stop, <))
|
if (timercmp(&now, &stop, <))
|
||||||
continue;
|
continue;
|
||||||
eendv(EXIT_FAILURE,
|
eendv(EXIT_FAILURE,
|
||||||
"timed out waiting for %s", argv[i]);
|
"timed out waiting for %s", argv[i]);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
eendv(EXIT_SUCCESS, NULL);
|
eendv(EXIT_SUCCESS, NULL);
|
||||||
@ -251,7 +254,8 @@ static int do_e(int argc, char **argv)
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_service(int argc, char **argv)
|
static int
|
||||||
|
do_service(int argc, char **argv)
|
||||||
{
|
{
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
char *service;
|
char *service;
|
||||||
@ -263,7 +267,7 @@ static int do_service(int argc, char **argv)
|
|||||||
else
|
else
|
||||||
service = getenv("RC_SVCNAME");
|
service = getenv("RC_SVCNAME");
|
||||||
|
|
||||||
if (! service || *service == '\0')
|
if (service == NULL || *service == '\0')
|
||||||
eerrorx("%s: no service specified", applet);
|
eerrorx("%s: no service specified", applet);
|
||||||
|
|
||||||
if (strcmp(applet, "service_started") == 0)
|
if (strcmp(applet, "service_started") == 0)
|
||||||
@ -297,15 +301,16 @@ static int do_service(int argc, char **argv)
|
|||||||
|
|
||||||
} else if (strcmp(applet, "service_crashed") == 0) {
|
} else if (strcmp(applet, "service_crashed") == 0) {
|
||||||
ok = (_rc_can_find_pids() &&
|
ok = (_rc_can_find_pids() &&
|
||||||
rc_service_daemons_crashed(service) &&
|
rc_service_daemons_crashed(service) &&
|
||||||
errno != EACCES);
|
errno != EACCES);
|
||||||
} else
|
} else
|
||||||
eerrorx("%s: unknown applet", applet);
|
eerrorx("%s: unknown applet", applet);
|
||||||
|
|
||||||
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
|
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_mark_service(int argc, char **argv)
|
static int
|
||||||
|
do_mark_service(int argc, char **argv)
|
||||||
{
|
{
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
char *svcname = getenv("RC_SVCNAME");
|
char *svcname = getenv("RC_SVCNAME");
|
||||||
@ -320,7 +325,7 @@ static int do_mark_service(int argc, char **argv)
|
|||||||
else
|
else
|
||||||
service = getenv("RC_SVCNAME");
|
service = getenv("RC_SVCNAME");
|
||||||
|
|
||||||
if (! service || *service == '\0')
|
if (service == NULL || *service == '\0')
|
||||||
eerrorx("%s: no service specified", applet);
|
eerrorx("%s: no service specified", applet);
|
||||||
|
|
||||||
if (strcmp(applet, "mark_service_started") == 0)
|
if (strcmp(applet, "mark_service_started") == 0)
|
||||||
@ -340,22 +345,22 @@ static int do_mark_service(int argc, char **argv)
|
|||||||
else
|
else
|
||||||
eerrorx("%s: unknown applet", applet);
|
eerrorx("%s: unknown applet", applet);
|
||||||
|
|
||||||
/* If we're marking ourselves then we need to inform our parent runscript
|
/* If we're marking ourselves then we need to inform our parent
|
||||||
process so they do not mark us based on our exit code */
|
runscript process so they do not mark us based on our exit code */
|
||||||
if (ok && svcname && strcmp(svcname, service) == 0) {
|
if (ok && svcname && strcmp(svcname, service) == 0) {
|
||||||
runscript_pid = getenv("RC_RUNSCRIPT_PID");
|
runscript_pid = getenv("RC_RUNSCRIPT_PID");
|
||||||
if (runscript_pid && sscanf(runscript_pid, "%d", &pid) == 1)
|
if (runscript_pid && sscanf(runscript_pid, "%d", &pid) == 1)
|
||||||
if (kill(pid, SIGHUP) != 0)
|
if (kill(pid, SIGHUP) != 0)
|
||||||
eerror("%s: failed to signal parent %d: %s",
|
eerror("%s: failed to signal parent %d: %s",
|
||||||
applet, pid, strerror(errno));
|
applet, pid, strerror(errno));
|
||||||
|
|
||||||
/* Remove the exclusive time test. This ensures that it's not
|
/* Remove the exclusive time test. This ensures that it's not
|
||||||
in control as well */
|
in control as well */
|
||||||
l = strlen(RC_SVCDIR "/exclusive") + strlen(svcname) +
|
l = strlen(RC_SVCDIR "/exclusive") + strlen(svcname) +
|
||||||
strlen(runscript_pid) + 4;
|
strlen(runscript_pid) + 4;
|
||||||
mtime = xmalloc(l);
|
mtime = xmalloc(l);
|
||||||
snprintf(mtime, l, RC_SVCDIR "/exclusive/%s.%s",
|
snprintf(mtime, l, RC_SVCDIR "/exclusive/%s.%s",
|
||||||
svcname, runscript_pid);
|
svcname, runscript_pid);
|
||||||
if (exists(mtime) && unlink(mtime) != 0)
|
if (exists(mtime) && unlink(mtime) != 0)
|
||||||
eerror("%s: unlink: %s", applet, strerror(errno));
|
eerror("%s: unlink: %s", applet, strerror(errno));
|
||||||
free(mtime);
|
free(mtime);
|
||||||
@ -364,13 +369,14 @@ static int do_mark_service(int argc, char **argv)
|
|||||||
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
|
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_value(int argc, char **argv)
|
static int
|
||||||
|
do_value(int argc, char **argv)
|
||||||
{
|
{
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
char *service = getenv("RC_SVCNAME");
|
char *service = getenv("RC_SVCNAME");
|
||||||
char *option;
|
char *option;
|
||||||
|
|
||||||
if (! service)
|
if (service == NULL)
|
||||||
eerrorx("%s: no service specified", applet);
|
eerrorx("%s: no service specified", applet);
|
||||||
|
|
||||||
if (argc < 2 || ! argv[1] || *argv[1] == '\0')
|
if (argc < 2 || ! argv[1] || *argv[1] == '\0')
|
||||||
@ -386,7 +392,7 @@ static int do_value(int argc, char **argv)
|
|||||||
ok = true;
|
ok = true;
|
||||||
}
|
}
|
||||||
} else if (strcmp(applet, "service_set_value") == 0 ||
|
} else if (strcmp(applet, "service_set_value") == 0 ||
|
||||||
strcmp(applet, "save_options") == 0)
|
strcmp(applet, "save_options") == 0)
|
||||||
ok = rc_service_value_set(service, argv[1], argv[2]);
|
ok = rc_service_value_set(service, argv[1], argv[2]);
|
||||||
else
|
else
|
||||||
eerrorx("%s: unknown applet", applet);
|
eerrorx("%s: unknown applet", applet);
|
||||||
@ -394,7 +400,8 @@ static int do_value(int argc, char **argv)
|
|||||||
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
|
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_shell_var(int argc, char **argv)
|
static int
|
||||||
|
do_shell_var(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char *p;
|
char *p;
|
||||||
@ -402,10 +409,8 @@ static int do_shell_var(int argc, char **argv)
|
|||||||
|
|
||||||
for (i = 1; i < argc; i++) {
|
for (i = 1; i < argc; i++) {
|
||||||
p = argv[i];
|
p = argv[i];
|
||||||
|
|
||||||
if (i != 1)
|
if (i != 1)
|
||||||
putchar(' ');
|
putchar(' ');
|
||||||
|
|
||||||
while (*p) {
|
while (*p) {
|
||||||
c = (unsigned char)*p++;
|
c = (unsigned char)*p++;
|
||||||
if (! isalnum(c))
|
if (! isalnum(c))
|
||||||
@ -414,11 +419,11 @@ static int do_shell_var(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void run_applets(int argc, char **argv)
|
void
|
||||||
|
run_applets(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int i = 2;
|
int i = 2;
|
||||||
char *p;
|
char *p;
|
||||||
@ -436,7 +441,7 @@ void run_applets(int argc, char **argv)
|
|||||||
else if (strcmp(applet, "rc-status") == 0)
|
else if (strcmp(applet, "rc-status") == 0)
|
||||||
exit(rc_status(argc, argv));
|
exit(rc_status(argc, argv));
|
||||||
else if (strcmp(applet, "rc-update") == 0 ||
|
else if (strcmp(applet, "rc-update") == 0 ||
|
||||||
strcmp(applet, "update-rc") == 0)
|
strcmp(applet, "update-rc") == 0)
|
||||||
exit(rc_update(argc, argv));
|
exit(rc_update(argc, argv));
|
||||||
else if (strcmp(applet, "runscript") == 0)
|
else if (strcmp(applet, "runscript") == 0)
|
||||||
exit(runscript(argc, argv));
|
exit(runscript(argc, argv));
|
||||||
@ -498,7 +503,7 @@ void run_applets(int argc, char **argv)
|
|||||||
if (p && sscanf(p, "%d", &pid) == 1) {
|
if (p && sscanf(p, "%d", &pid) == 1) {
|
||||||
if (kill(pid, SIGUSR1) != 0)
|
if (kill(pid, SIGUSR1) != 0)
|
||||||
eerrorx("rc-abort: failed to signal parent %d: %s",
|
eerrorx("rc-abort: failed to signal parent %d: %s",
|
||||||
pid, strerror(errno));
|
pid, strerror(errno));
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
rc-depend
|
rc-depend
|
||||||
rc service dependency and ordering
|
rc service dependency and ordering
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2007-2009 Roy Marples <roy@marples.name>
|
* Copyright 2007-2009 Roy Marples <roy@marples.name>
|
||||||
@ -85,7 +85,7 @@ _rc_deptree_load(int force, int *regen) {
|
|||||||
if (st.st_mtime < t) {
|
if (st.st_mtime < t) {
|
||||||
eerror("Clock skew detected with `%s'", file);
|
eerror("Clock skew detected with `%s'", file);
|
||||||
eerrorn("Adjusting mtime of `" RC_DEPTREE_CACHE
|
eerrorn("Adjusting mtime of `" RC_DEPTREE_CACHE
|
||||||
"' to %s", ctime(&t));
|
"' to %s", ctime(&t));
|
||||||
fp = fopen(RC_DEPTREE_SKEWED, "w");
|
fp = fopen(RC_DEPTREE_SKEWED, "w");
|
||||||
if (fp != NULL) {
|
if (fp != NULL) {
|
||||||
fprintf(fp, "%s\n", file);
|
fprintf(fp, "%s\n", file);
|
||||||
@ -144,7 +144,7 @@ rc_depend(int argc, char **argv)
|
|||||||
|
|
||||||
types = rc_stringlist_new();
|
types = rc_stringlist_new();
|
||||||
while ((opt = getopt_long(argc, argv, getoptstring,
|
while ((opt = getopt_long(argc, argv, getoptstring,
|
||||||
longopts, (int *) 0)) != -1)
|
longopts, (int *) 0)) != -1)
|
||||||
{
|
{
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'a':
|
case 'a':
|
||||||
@ -167,8 +167,8 @@ rc_depend(int argc, char **argv)
|
|||||||
options &= RC_DEP_TRACE;
|
options &= RC_DEP_TRACE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case_RC_COMMON_GETOPT
|
case_RC_COMMON_GETOPT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(deptree = _rc_deptree_load(update, NULL)))
|
if (!(deptree = _rc_deptree_load(update, NULL)))
|
||||||
@ -185,7 +185,7 @@ rc_depend(int argc, char **argv)
|
|||||||
depends = rc_deptree_depends(deptree, NULL, list, runlevel, 0);
|
depends = rc_deptree_depends(deptree, NULL, list, runlevel, 0);
|
||||||
if (!depends && errno == ENOENT)
|
if (!depends && errno == ENOENT)
|
||||||
eerror("no dependency info for service `%s'",
|
eerror("no dependency info for service `%s'",
|
||||||
argv[optind]);
|
argv[optind]);
|
||||||
else
|
else
|
||||||
rc_stringlist_add(services, argv[optind]);
|
rc_stringlist_add(services, argv[optind]);
|
||||||
|
|
||||||
@ -210,7 +210,7 @@ rc_depend(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
depends = rc_deptree_depends(deptree, types, services,
|
depends = rc_deptree_depends(deptree, types, services,
|
||||||
runlevel, options);
|
runlevel, options);
|
||||||
|
|
||||||
if (TAILQ_FIRST(depends)) {
|
if (TAILQ_FIRST(depends)) {
|
||||||
TAILQ_FOREACH(s, depends, entries) {
|
TAILQ_FOREACH(s, depends, entries) {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
rc-logger.c
|
rc-logger.c
|
||||||
Spawns a logging daemon to capture stdout and stderr so we can log
|
Spawns a logging daemon to capture stdout and stderr so we can log
|
||||||
them to a buffer and/or files.
|
them to a buffer and/or files.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2007-2008 Roy Marples <roy@marples.name>
|
* Copyright 2007-2008 Roy Marples <roy@marples.name>
|
||||||
@ -46,11 +46,11 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
# include <pty.h>
|
# include <pty.h>
|
||||||
#elif defined(__NetBSD__) || defined(__OpenBSD__)
|
#elif defined(__NetBSD__) || defined(__OpenBSD__)
|
||||||
# include <util.h>
|
# include <util.h>
|
||||||
#else
|
#else
|
||||||
# include <libutil.h>
|
# include <libutil.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "einfo.h"
|
#include "einfo.h"
|
||||||
@ -60,7 +60,7 @@
|
|||||||
|
|
||||||
#define LOGFILE RC_SVCDIR "/rc.log"
|
#define LOGFILE RC_SVCDIR "/rc.log"
|
||||||
#define PERMLOG "/var/log/rc.log"
|
#define PERMLOG "/var/log/rc.log"
|
||||||
#define MOVELOG "cat " LOGFILE " 2>/dev/null >>" PERMLOG " && " \
|
#define MOVELOG "cat " LOGFILE " 2>/dev/null >>" PERMLOG " && " \
|
||||||
"rm -f " LOGFILE
|
"rm -f " LOGFILE
|
||||||
|
|
||||||
static int signal_pipe[2] = { -1, -1 };
|
static int signal_pipe[2] = { -1, -1 };
|
||||||
@ -78,11 +78,12 @@ pid_t rc_logger_pid = -1;
|
|||||||
int rc_logger_tty = -1;
|
int rc_logger_tty = -1;
|
||||||
bool rc_in_logger = false;
|
bool rc_in_logger = false;
|
||||||
|
|
||||||
static void write_log(int logfd, const char *buffer, size_t bytes)
|
static void
|
||||||
|
write_log(int logfd, const char *buffer, size_t bytes)
|
||||||
{
|
{
|
||||||
const char *p = buffer;
|
const char *p = buffer;
|
||||||
|
|
||||||
while ((size_t) (p - buffer) < bytes) {
|
while ((size_t)(p - buffer) < bytes) {
|
||||||
switch (*p) {
|
switch (*p) {
|
||||||
case '\r':
|
case '\r':
|
||||||
goto cont;
|
goto cont;
|
||||||
@ -110,7 +111,9 @@ cont:
|
|||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void write_time(FILE *f, const char *s)
|
|
||||||
|
static void
|
||||||
|
write_time(FILE *f, const char *s)
|
||||||
{
|
{
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
struct tm *tm = localtime(&now);
|
struct tm *tm = localtime(&now);
|
||||||
@ -119,7 +122,8 @@ static void write_time(FILE *f, const char *s)
|
|||||||
fflush(f);
|
fflush(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rc_logger_close(void)
|
void
|
||||||
|
rc_logger_close(void)
|
||||||
{
|
{
|
||||||
int sig = SIGTERM;
|
int sig = SIGTERM;
|
||||||
|
|
||||||
@ -138,7 +142,8 @@ void rc_logger_close(void)
|
|||||||
dup2(fd_stderr, STDERR_FILENO);
|
dup2(fd_stderr, STDERR_FILENO);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rc_logger_open(const char *level)
|
void
|
||||||
|
rc_logger_open(const char *level)
|
||||||
{
|
{
|
||||||
int slave_tty;
|
int slave_tty;
|
||||||
struct termios tt;
|
struct termios tt;
|
||||||
@ -157,7 +162,7 @@ void rc_logger_open(const char *level)
|
|||||||
eerrorx("pipe: %s", strerror(errno));
|
eerrorx("pipe: %s", strerror(errno));
|
||||||
for (i = 0; i < 2; i++)
|
for (i = 0; i < 2; i++)
|
||||||
if ((s = fcntl (signal_pipe[i], F_GETFD, 0) == -1 ||
|
if ((s = fcntl (signal_pipe[i], F_GETFD, 0) == -1 ||
|
||||||
fcntl (signal_pipe[i], F_SETFD, s | FD_CLOEXEC) == -1))
|
fcntl (signal_pipe[i], F_SETFD, s | FD_CLOEXEC) == -1))
|
||||||
eerrorx("fcntl: %s", strerror (errno));
|
eerrorx("fcntl: %s", strerror (errno));
|
||||||
|
|
||||||
if (isatty(STDOUT_FILENO)) {
|
if (isatty(STDOUT_FILENO)) {
|
||||||
@ -202,36 +207,38 @@ void rc_logger_open(const char *level)
|
|||||||
if (rc_logger_tty >= 0)
|
if (rc_logger_tty >= 0)
|
||||||
fd[1].fd = rc_logger_tty;
|
fd[1].fd = rc_logger_tty;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if ((s = poll(fd, rc_logger_tty >= 0 ? 2 : 1, -1)) == -1) {
|
if ((s = poll(fd,
|
||||||
|
rc_logger_tty >= 0 ? 2 : 1, -1)) == -1)
|
||||||
|
{
|
||||||
eerror("poll: %s", strerror(errno));
|
eerror("poll: %s", strerror(errno));
|
||||||
break;
|
break;
|
||||||
}
|
} else if (s == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (s > 0) {
|
if (fd[1].revents & (POLLIN | POLLHUP)) {
|
||||||
if (fd[1].revents & (POLLIN | POLLHUP)) {
|
memset(buffer, 0, BUFSIZ);
|
||||||
memset(buffer, 0, BUFSIZ);
|
bytes = read(rc_logger_tty, buffer, BUFSIZ);
|
||||||
bytes = read(rc_logger_tty, buffer, BUFSIZ);
|
write(STDOUT_FILENO, buffer, bytes);
|
||||||
write(STDOUT_FILENO, buffer, bytes);
|
|
||||||
|
|
||||||
if (log)
|
if (log)
|
||||||
write_log(fileno (log), buffer, bytes);
|
write_log(fileno (log), buffer, bytes);
|
||||||
else {
|
else {
|
||||||
if (logbuf_size - logbuf_len < bytes) {
|
if (logbuf_size - logbuf_len < bytes) {
|
||||||
logbuf_size += BUFSIZ * 10;
|
logbuf_size += BUFSIZ * 10;
|
||||||
logbuf = xrealloc(logbuf,
|
logbuf = xrealloc(logbuf,
|
||||||
sizeof(char ) *
|
sizeof(char ) *
|
||||||
logbuf_size);
|
logbuf_size);
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(logbuf + logbuf_len, buffer, bytes);
|
|
||||||
logbuf_len += bytes;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Only SIGTERMS signals come down this pipe */
|
memcpy(logbuf + logbuf_len,
|
||||||
if (fd[0].revents & (POLLIN | POLLHUP))
|
buffer, bytes);
|
||||||
break;
|
logbuf_len += bytes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Only SIGTERMS signals come down this pipe */
|
||||||
|
if (fd[0].revents & (POLLIN | POLLHUP))
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
free(buffer);
|
free(buffer);
|
||||||
if (logbuf) {
|
if (logbuf) {
|
||||||
@ -246,10 +253,9 @@ void rc_logger_open(const char *level)
|
|||||||
fclose(log);
|
fclose(log);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try and cat our new logfile to a more permament location and then
|
/* Try and cat our new logfile to a more permament location
|
||||||
* punt it */
|
and then punt it */
|
||||||
system(MOVELOG);
|
system(MOVELOG);
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
librc-misc.c
|
librc-misc.c
|
||||||
rc misc functions
|
rc misc functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2007-2008 Roy Marples <roy@marples.name>
|
* Copyright 2007-2008 Roy Marples <roy@marples.name>
|
||||||
@ -34,8 +34,8 @@
|
|||||||
#include <sys/utsname.h>
|
#include <sys/utsname.h>
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
#include <sys/sysinfo.h>
|
# include <sys/sysinfo.h>
|
||||||
#include <regex.h>
|
# include <regex.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -244,7 +244,8 @@ env_config(void)
|
|||||||
if (sys)
|
if (sys)
|
||||||
setenv("RC_SYS", sys, 1);
|
setenv("RC_SYS", sys, 1);
|
||||||
|
|
||||||
/* Some scripts may need to take a different code path if Linux/FreeBSD, etc
|
/* Some scripts may need to take a different code path if
|
||||||
|
Linux/FreeBSD, etc
|
||||||
To save on calling uname, we store it in an environment variable */
|
To save on calling uname, we store it in an environment variable */
|
||||||
if (uname(&uts) == 0)
|
if (uname(&uts) == 0)
|
||||||
setenv("RC_UNAME", uts.sysname, 1);
|
setenv("RC_UNAME", uts.sysname, 1);
|
||||||
@ -346,7 +347,7 @@ exec_service(const char *service, const char *arg)
|
|||||||
/* Safe to run now */
|
/* Safe to run now */
|
||||||
execl(file, file, "--lockfd", sfd, arg, (char *) NULL);
|
execl(file, file, "--lockfd", sfd, arg, (char *) NULL);
|
||||||
fprintf(stderr, "unable to exec `%s': %s\n",
|
fprintf(stderr, "unable to exec `%s': %s\n",
|
||||||
file, strerror(errno));
|
file, strerror(errno));
|
||||||
svc_unlock(basename_c(service), fd);
|
svc_unlock(basename_c(service), fd);
|
||||||
_exit(EXIT_FAILURE);
|
_exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
librc-plugin.c
|
librc-plugin.c
|
||||||
Simple plugin handler
|
Simple plugin handler
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2007-2008 Roy Marples <roy@marples.name>
|
* Copyright 2007-2008 Roy Marples <roy@marples.name>
|
||||||
@ -62,7 +62,8 @@ typedef struct plugin
|
|||||||
TAILQ_HEAD(, plugin) plugins;
|
TAILQ_HEAD(, plugin) plugins;
|
||||||
|
|
||||||
#ifndef __FreeBSD__
|
#ifndef __FreeBSD__
|
||||||
dlfunc_t dlfunc(void * __restrict handle, const char * __restrict symbol)
|
dlfunc_t
|
||||||
|
dlfunc(void * __restrict handle, const char * __restrict symbol)
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
void *d;
|
void *d;
|
||||||
@ -74,7 +75,8 @@ dlfunc_t dlfunc(void * __restrict handle, const char * __restrict symbol)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void rc_plugin_load(void)
|
void
|
||||||
|
rc_plugin_load(void)
|
||||||
{
|
{
|
||||||
DIR *dp;
|
DIR *dp;
|
||||||
struct dirent *d;
|
struct dirent *d;
|
||||||
@ -89,7 +91,7 @@ void rc_plugin_load(void)
|
|||||||
|
|
||||||
TAILQ_INIT(&plugins);
|
TAILQ_INIT(&plugins);
|
||||||
|
|
||||||
if (! (dp = opendir(RC_PLUGINDIR)))
|
if (!(dp = opendir(RC_PLUGINDIR)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
while ((d = readdir(dp))) {
|
while ((d = readdir(dp))) {
|
||||||
@ -98,14 +100,16 @@ void rc_plugin_load(void)
|
|||||||
|
|
||||||
snprintf(file, sizeof(file), RC_PLUGINDIR "/%s", d->d_name);
|
snprintf(file, sizeof(file), RC_PLUGINDIR "/%s", d->d_name);
|
||||||
h = dlopen(file, RTLD_LAZY);
|
h = dlopen(file, RTLD_LAZY);
|
||||||
if (! h) {
|
if (h == NULL) {
|
||||||
eerror("dlopen: %s", dlerror());
|
eerror("dlopen: %s", dlerror());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
fptr = (int (*)(RC_HOOK, const char*))dlfunc(h, RC_PLUGIN_HOOK);
|
fptr = (int (*)(RC_HOOK, const char*))
|
||||||
if (! fptr) {
|
dlfunc(h, RC_PLUGIN_HOOK);
|
||||||
eerror("%s: cannot find symbol `%s'", d->d_name, RC_PLUGIN_HOOK);
|
if (fptr == NULL) {
|
||||||
|
eerror("%s: cannot find symbol `%s'",
|
||||||
|
d->d_name, RC_PLUGIN_HOOK);
|
||||||
dlclose(h);
|
dlclose(h);
|
||||||
} else {
|
} else {
|
||||||
plugin = xmalloc(sizeof(*plugin));
|
plugin = xmalloc(sizeof(*plugin));
|
||||||
@ -118,7 +122,8 @@ void rc_plugin_load(void)
|
|||||||
closedir(dp);
|
closedir(dp);
|
||||||
}
|
}
|
||||||
|
|
||||||
int rc_waitpid(pid_t pid)
|
int
|
||||||
|
rc_waitpid(pid_t pid)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
@ -131,7 +136,8 @@ int rc_waitpid(pid_t pid)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rc_plugin_run(RC_HOOK hook, const char *value)
|
void
|
||||||
|
rc_plugin_run(RC_HOOK hook, const char *value)
|
||||||
{
|
{
|
||||||
PLUGIN *plugin;
|
PLUGIN *plugin;
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
@ -234,7 +240,8 @@ void rc_plugin_run(RC_HOOK hook, const char *value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rc_plugin_unload(void)
|
void
|
||||||
|
rc_plugin_unload(void)
|
||||||
{
|
{
|
||||||
PLUGIN *plugin = TAILQ_FIRST(&plugins);
|
PLUGIN *plugin = TAILQ_FIRST(&plugins);
|
||||||
PLUGIN *next;
|
PLUGIN *next;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
rc-service.c
|
rc-service.c
|
||||||
Finds all OpenRC services
|
Finds all OpenRC services
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2008 Roy Marples <roy@marples.name>
|
* Copyright 2008 Roy Marples <roy@marples.name>
|
||||||
@ -70,7 +70,7 @@ rc_service(int argc, char **argv)
|
|||||||
unsetenv("EINFO_QUIET");
|
unsetenv("EINFO_QUIET");
|
||||||
|
|
||||||
while ((opt = getopt_long(argc, argv, getoptstring,
|
while ((opt = getopt_long(argc, argv, getoptstring,
|
||||||
longopts, (int *) 0)) != -1)
|
longopts, (int *) 0)) != -1)
|
||||||
{
|
{
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'e':
|
case 'e':
|
||||||
@ -87,7 +87,7 @@ rc_service(int argc, char **argv)
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
rc_stringlist_sort(&list);
|
rc_stringlist_sort(&list);
|
||||||
TAILQ_FOREACH(s, list, entries)
|
TAILQ_FOREACH(s, list, entries)
|
||||||
printf("%s\n", s->value);
|
printf("%s\n", s->value);
|
||||||
#ifdef DEBUG_MEMORY
|
#ifdef DEBUG_MEMORY
|
||||||
rc_stringlist_free(list);
|
rc_stringlist_free(list);
|
||||||
#endif
|
#endif
|
||||||
@ -104,8 +104,8 @@ rc_service(int argc, char **argv)
|
|||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
|
|
||||||
case_RC_COMMON_GETOPT
|
case_RC_COMMON_GETOPT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
argc -= optind;
|
argc -= optind;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
rc-update
|
rc-update
|
||||||
Manage init scripts and runlevels
|
Manage init scripts and runlevels
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2007-2009 Roy Marples <roy@marples.name>
|
* Copyright 2007-2009 Roy Marples <roy@marples.name>
|
||||||
@ -57,19 +57,21 @@ add(const char *runlevel, const char *service)
|
|||||||
|
|
||||||
if (!rc_service_exists(service)) {
|
if (!rc_service_exists(service)) {
|
||||||
if (errno == ENOEXEC)
|
if (errno == ENOEXEC)
|
||||||
eerror("%s: service `%s' is not executeable", applet, service);
|
eerror("%s: service `%s' is not executeable",
|
||||||
|
applet, service);
|
||||||
else
|
else
|
||||||
eerror("%s: service `%s' does not exist", applet, service);
|
eerror("%s: service `%s' does not exist",
|
||||||
|
applet, service);
|
||||||
} else if (rc_service_in_runlevel(service, runlevel)) {
|
} else if (rc_service_in_runlevel(service, runlevel)) {
|
||||||
ewarn ("%s: %s already installed in runlevel `%s'; skipping",
|
ewarn ("%s: %s already installed in runlevel `%s'; skipping",
|
||||||
applet, service, runlevel);
|
applet, service, runlevel);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
} else if (rc_service_add(runlevel, service)) {
|
} else if (rc_service_add(runlevel, service)) {
|
||||||
einfo ("%s added to runlevel %s", service, runlevel);
|
einfo ("%s added to runlevel %s", service, runlevel);
|
||||||
retval = 1;
|
retval = 1;
|
||||||
} else
|
} else
|
||||||
eerror("%s: failed to add service `%s' to runlevel `%s': %s",
|
eerror("%s: failed to add service `%s' to runlevel `%s': %s",
|
||||||
applet, service, runlevel, strerror (errno));
|
applet, service, runlevel, strerror (errno));
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
@ -87,10 +89,10 @@ delete(const char *runlevel, const char *service)
|
|||||||
|
|
||||||
if (errno == ENOENT)
|
if (errno == ENOENT)
|
||||||
eerror ("%s: service `%s' is not in the runlevel `%s'",
|
eerror ("%s: service `%s' is not in the runlevel `%s'",
|
||||||
applet, service, runlevel);
|
applet, service, runlevel);
|
||||||
else
|
else
|
||||||
eerror ("%s: failed to remove service `%s' from runlevel `%s': %s",
|
eerror ("%s: failed to remove service `%s' from runlevel `%s': %s",
|
||||||
applet, service, runlevel, strerror (errno));
|
applet, service, runlevel, strerror (errno));
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
@ -112,7 +114,7 @@ show(RC_STRINGLIST *runlevels, bool verbose)
|
|||||||
|
|
||||||
TAILQ_FOREACH(runlevel, runlevels, entries) {
|
TAILQ_FOREACH(runlevel, runlevels, entries) {
|
||||||
if (rc_service_in_runlevel(service->value,
|
if (rc_service_in_runlevel(service->value,
|
||||||
runlevel->value))
|
runlevel->value))
|
||||||
{
|
{
|
||||||
rc_stringlist_add(in, runlevel->value);
|
rc_stringlist_add(in, runlevel->value);
|
||||||
inone = true;
|
inone = true;
|
||||||
@ -127,7 +129,7 @@ show(RC_STRINGLIST *runlevels, bool verbose)
|
|||||||
if (inone || verbose) {
|
if (inone || verbose) {
|
||||||
printf(" %20s |", service->value);
|
printf(" %20s |", service->value);
|
||||||
TAILQ_FOREACH(runlevel, in, entries)
|
TAILQ_FOREACH(runlevel, in, entries)
|
||||||
printf (" %s", runlevel->value);
|
printf (" %s", runlevel->value);
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
}
|
}
|
||||||
rc_stringlist_free(in);
|
rc_stringlist_free(in);
|
||||||
@ -137,9 +139,9 @@ show(RC_STRINGLIST *runlevels, bool verbose)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#include "_usage.h"
|
#include "_usage.h"
|
||||||
#define usagestring "" \
|
#define usagestring "" \
|
||||||
"Usage: rc-update [options] add service <runlevel>\n" \
|
"Usage: rc-update [options] add service <runlevel>\n" \
|
||||||
" rc-update [options] del service <runlevel>\n" \
|
" rc-update [options] del service <runlevel>\n" \
|
||||||
" rc-update [options] show"
|
" rc-update [options] show"
|
||||||
#define getoptstring "u" getoptstring_COMMON
|
#define getoptstring "u" getoptstring_COMMON
|
||||||
static const struct option longopts[] = {
|
static const struct option longopts[] = {
|
||||||
@ -172,13 +174,13 @@ rc_update(int argc, char **argv)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
while ((opt = getopt_long(argc, argv, getoptstring,
|
while ((opt = getopt_long(argc, argv, getoptstring,
|
||||||
longopts, (int *)0)) != -1)
|
longopts, (int *)0)) != -1)
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'u':
|
case 'u':
|
||||||
_rc_deptree_load(-1, &ret);
|
_rc_deptree_load(-1, &ret);
|
||||||
return ret;
|
return ret;
|
||||||
case_RC_COMMON_GETOPT
|
case_RC_COMMON_GETOPT
|
||||||
}
|
}
|
||||||
|
|
||||||
verbose = rc_yesno(getenv ("EINFO_VERBOSE"));
|
verbose = rc_yesno(getenv ("EINFO_VERBOSE"));
|
||||||
|
|
||||||
@ -192,14 +194,15 @@ rc_update(int argc, char **argv)
|
|||||||
if (strcmp(argv[optind], "add") == 0)
|
if (strcmp(argv[optind], "add") == 0)
|
||||||
action = DOADD;
|
action = DOADD;
|
||||||
else if (strcmp(argv[optind], "delete") == 0 ||
|
else if (strcmp(argv[optind], "delete") == 0 ||
|
||||||
strcmp(argv[optind], "del") == 0)
|
strcmp(argv[optind], "del") == 0)
|
||||||
action = DODELETE;
|
action = DODELETE;
|
||||||
else if (strcmp(argv[optind], "show") == 0)
|
else if (strcmp(argv[optind], "show") == 0)
|
||||||
action = DOSHOW;
|
action = DOSHOW;
|
||||||
if (action)
|
if (action)
|
||||||
optind++;
|
optind++;
|
||||||
else
|
else
|
||||||
eerrorx("%s: invalid command `%s'", applet, argv[optind]);
|
eerrorx("%s: invalid command `%s'",
|
||||||
|
applet, argv[optind]);
|
||||||
}
|
}
|
||||||
if (!action)
|
if (!action)
|
||||||
action = DOSHOW;
|
action = DOSHOW;
|
||||||
@ -219,7 +222,7 @@ rc_update(int argc, char **argv)
|
|||||||
else {
|
else {
|
||||||
rc_stringlist_free(runlevels);
|
rc_stringlist_free(runlevels);
|
||||||
eerrorx ("%s: `%s' is not a valid runlevel",
|
eerrorx ("%s: `%s' is not a valid runlevel",
|
||||||
applet, argv[optind]);
|
applet, argv[optind]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,13 +257,13 @@ rc_update(int argc, char **argv)
|
|||||||
|
|
||||||
if (!TAILQ_FIRST(runlevels)) {
|
if (!TAILQ_FIRST(runlevels)) {
|
||||||
free(runlevels);
|
free(runlevels);
|
||||||
eerrorx ("%s: no runlevels found", applet);
|
eerrorx("%s: no runlevels found", applet);
|
||||||
}
|
}
|
||||||
|
|
||||||
TAILQ_FOREACH(runlevel, runlevels, entries) {
|
TAILQ_FOREACH(runlevel, runlevels, entries) {
|
||||||
if (!rc_runlevel_exists(runlevel->value)) {
|
if (!rc_runlevel_exists(runlevel->value)) {
|
||||||
eerror ("%s: runlevel `%s' does not exist",
|
eerror ("%s: runlevel `%s' does not exist",
|
||||||
applet, runlevel->value);
|
applet, runlevel->value);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,8 +276,8 @@ rc_update(int argc, char **argv)
|
|||||||
if (retval == EXIT_SUCCESS &&
|
if (retval == EXIT_SUCCESS &&
|
||||||
num_updated == 0 && action & DODELETE)
|
num_updated == 0 && action & DODELETE)
|
||||||
ewarnx("%s: service `%s' not found in any"
|
ewarnx("%s: service `%s' not found in any"
|
||||||
" of the specified runlevels",
|
" of the specified runlevels",
|
||||||
applet, service);
|
applet, service);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
138
src/rc/rc.c
138
src/rc/rc.c
@ -44,7 +44,7 @@ const char rc_copyright[] = "Copyright (c) 2007-2008 Roy Marples";
|
|||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
# include <asm/setup.h> /* for COMMAND_LINE_SIZE */
|
# include <asm/setup.h> /* for COMMAND_LINE_SIZE */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@ -108,17 +108,17 @@ clean_failed(void)
|
|||||||
while ((d = readdir(dp))) {
|
while ((d = readdir(dp))) {
|
||||||
if (d->d_name[0] == '.' &&
|
if (d->d_name[0] == '.' &&
|
||||||
(d->d_name[1] == '\0' ||
|
(d->d_name[1] == '\0' ||
|
||||||
(d->d_name[1] == '.' && d->d_name[2] == '\0')))
|
(d->d_name[1] == '.' && d->d_name[2] == '\0')))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
l = strlen(RC_SVCDIR "/failed/") +
|
l = strlen(RC_SVCDIR "/failed/") +
|
||||||
strlen(d->d_name) + 1;
|
strlen(d->d_name) + 1;
|
||||||
path = xmalloc(sizeof(char) * l);
|
path = xmalloc(sizeof(char) * l);
|
||||||
snprintf(path, l, RC_SVCDIR "/failed/%s", d->d_name);
|
snprintf(path, l, RC_SVCDIR "/failed/%s", d->d_name);
|
||||||
if (path) {
|
if (path) {
|
||||||
if (unlink(path))
|
if (unlink(path))
|
||||||
eerror("%s: unlink `%s': %s",
|
eerror("%s: unlink `%s': %s",
|
||||||
applet, path, strerror(errno));
|
applet, path, strerror(errno));
|
||||||
free(path);
|
free(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -217,8 +217,8 @@ read_key(bool block)
|
|||||||
if (!isatty(fd))
|
if (!isatty(fd))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Now save our terminal settings. We need to restore them at exit as we
|
/* Now save our terminal settings. We need to restore them at exit as
|
||||||
* will be changing it for non-blocking reads for Interactive */
|
we will be changing it for non-blocking reads for Interactive */
|
||||||
if (!termios_orig) {
|
if (!termios_orig) {
|
||||||
termios_orig = xmalloc(sizeof(*termios_orig));
|
termios_orig = xmalloc(sizeof(*termios_orig));
|
||||||
tcgetattr(fd, termios_orig);
|
tcgetattr(fd, termios_orig);
|
||||||
@ -301,7 +301,7 @@ run_program(const char *prog)
|
|||||||
|
|
||||||
execl(prog, prog, (char *) NULL);
|
execl(prog, prog, (char *) NULL);
|
||||||
eerror("%s: unable to exec `%s': %s", applet, prog,
|
eerror("%s: unable to exec `%s': %s", applet, prog,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
_exit(EXIT_FAILURE);
|
_exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,7 +323,7 @@ sulogin(bool cont)
|
|||||||
{
|
{
|
||||||
execl("/sbin/halt", "/sbin/halt", "-f", (char *) NULL);
|
execl("/sbin/halt", "/sbin/halt", "-f", (char *) NULL);
|
||||||
eerrorx("%s: unable to exec `/sbin/halt': %s",
|
eerrorx("%s: unable to exec `/sbin/halt': %s",
|
||||||
applet, strerror(errno));
|
applet, strerror(errno));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (!cont) {
|
if (!cont) {
|
||||||
@ -343,7 +343,7 @@ single_user(void)
|
|||||||
rc_logger_close();
|
rc_logger_close();
|
||||||
execl(SHUTDOWN, SHUTDOWN, "now", (char *) NULL);
|
execl(SHUTDOWN, SHUTDOWN, "now", (char *) NULL);
|
||||||
eerrorx("%s: unable to exec `" SHUTDOWN "': %s",
|
eerrorx("%s: unable to exec `" SHUTDOWN "': %s",
|
||||||
applet, strerror(errno));
|
applet, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
@ -359,7 +359,7 @@ set_krunlevel(const char *level)
|
|||||||
if (exists(RC_KRUNLEVEL) &&
|
if (exists(RC_KRUNLEVEL) &&
|
||||||
unlink(RC_KRUNLEVEL) != 0)
|
unlink(RC_KRUNLEVEL) != 0)
|
||||||
eerror("unlink `%s': %s", RC_KRUNLEVEL,
|
eerror("unlink `%s': %s", RC_KRUNLEVEL,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -409,11 +409,11 @@ remove_pid(pid_t pid)
|
|||||||
RC_PID *p;
|
RC_PID *p;
|
||||||
|
|
||||||
LIST_FOREACH(p, &service_pids, entries)
|
LIST_FOREACH(p, &service_pids, entries)
|
||||||
if (p->pid == pid) {
|
if (p->pid == pid) {
|
||||||
LIST_REMOVE(p, entries);
|
LIST_REMOVE(p, entries);
|
||||||
free(p);
|
free(p);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -484,7 +484,7 @@ handle_signal(int sig)
|
|||||||
|
|
||||||
/* Kill any running services we have started */
|
/* Kill any running services we have started */
|
||||||
LIST_FOREACH(pi, &service_pids, entries)
|
LIST_FOREACH(pi, &service_pids, entries)
|
||||||
kill(pi->pid, SIGTERM);
|
kill(pi->pid, SIGTERM);
|
||||||
|
|
||||||
/* Notify plugins we are aborting */
|
/* Notify plugins we are aborting */
|
||||||
rc_plugin_run(RC_HOOK_ABORT, NULL);
|
rc_plugin_run(RC_HOOK_ABORT, NULL);
|
||||||
@ -514,15 +514,15 @@ do_sysinit()
|
|||||||
|
|
||||||
uname(&uts);
|
uname(&uts);
|
||||||
printf("\n %sOpenRC %s" VERSION "%s is starting up %s",
|
printf("\n %sOpenRC %s" VERSION "%s is starting up %s",
|
||||||
ecolor(ECOLOR_GOOD), ecolor(ECOLOR_HILITE),
|
ecolor(ECOLOR_GOOD), ecolor(ECOLOR_HILITE),
|
||||||
ecolor(ECOLOR_NORMAL), ecolor(ECOLOR_BRACKET));
|
ecolor(ECOLOR_NORMAL), ecolor(ECOLOR_BRACKET));
|
||||||
#ifdef BRANDING
|
#ifdef BRANDING
|
||||||
printf(BRANDING " (%s)", uts.machine);
|
printf(BRANDING " (%s)", uts.machine);
|
||||||
#else
|
#else
|
||||||
printf("%s %s (%s)",
|
printf("%s %s (%s)",
|
||||||
uts.sysname,
|
uts.sysname,
|
||||||
uts.release,
|
uts.release,
|
||||||
uts.machine);
|
uts.machine);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((sys = rc_sys()))
|
if ((sys = rc_sys()))
|
||||||
@ -533,7 +533,7 @@ do_sysinit()
|
|||||||
if (!rc_yesno(getenv ("EINFO_QUIET")) &&
|
if (!rc_yesno(getenv ("EINFO_QUIET")) &&
|
||||||
rc_conf_yesno("rc_interactive"))
|
rc_conf_yesno("rc_interactive"))
|
||||||
printf("Press %sI%s to enter interactive boot mode\n\n",
|
printf("Press %sI%s to enter interactive boot mode\n\n",
|
||||||
ecolor(ECOLOR_GOOD), ecolor(ECOLOR_NORMAL));
|
ecolor(ECOLOR_GOOD), ecolor(ECOLOR_NORMAL));
|
||||||
|
|
||||||
setenv("RC_RUNLEVEL", RC_LEVEL_SYSINIT, 1);
|
setenv("RC_RUNLEVEL", RC_LEVEL_SYSINIT, 1);
|
||||||
run_program(INITSH);
|
run_program(INITSH);
|
||||||
@ -611,13 +611,14 @@ do_stop_services(const char *newlevel, bool parallel)
|
|||||||
if (!svc1) {
|
if (!svc1) {
|
||||||
tmplist = rc_stringlist_new();
|
tmplist = rc_stringlist_new();
|
||||||
rc_stringlist_add(tmplist, service->value);
|
rc_stringlist_add(tmplist, service->value);
|
||||||
deporder = rc_deptree_depends(deptree, types_n, tmplist,
|
deporder = rc_deptree_depends(deptree, types_n,
|
||||||
newlevel ? newlevel : runlevel,
|
tmplist, newlevel ? newlevel : runlevel,
|
||||||
RC_DEP_STRICT | RC_DEP_TRACE);
|
RC_DEP_STRICT | RC_DEP_TRACE);
|
||||||
rc_stringlist_free(tmplist);
|
rc_stringlist_free(tmplist);
|
||||||
svc2 = NULL;
|
svc2 = NULL;
|
||||||
TAILQ_FOREACH(svc1, deporder, entries) {
|
TAILQ_FOREACH(svc1, deporder, entries) {
|
||||||
svc2 = rc_stringlist_find(start_services, svc1->value);
|
svc2 = rc_stringlist_find(start_services,
|
||||||
|
svc1->value);
|
||||||
if (svc2)
|
if (svc2)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -661,21 +662,21 @@ do_start_services(bool parallel)
|
|||||||
interactive = want_interactive();
|
interactive = want_interactive();
|
||||||
|
|
||||||
if (interactive) {
|
if (interactive) {
|
||||||
interactive_retry:
|
interactive_retry:
|
||||||
printf("\n");
|
printf("\n");
|
||||||
einfo("About to start the service %s",
|
einfo("About to start the service %s",
|
||||||
service->value);
|
service->value);
|
||||||
eindent();
|
eindent();
|
||||||
einfo("1) Start the service\t\t2) Skip the service");
|
einfo("1) Start the service\t\t2) Skip the service");
|
||||||
einfo("3) Continue boot process\t\t4) Exit to shell");
|
einfo("3) Continue boot process\t\t4) Exit to shell");
|
||||||
eoutdent();
|
eoutdent();
|
||||||
interactive_option:
|
interactive_option:
|
||||||
switch (read_key(true)) {
|
switch (read_key(true)) {
|
||||||
case '1': break;
|
case '1': break;
|
||||||
case '2': continue;
|
case '2': continue;
|
||||||
case '3': interactive = false; break;
|
case '3': interactive = false; break;
|
||||||
case '4': sulogin(true); goto interactive_retry;
|
case '4': sulogin(true); goto interactive_retry;
|
||||||
default: goto interactive_option;
|
default: goto interactive_option;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -693,7 +694,7 @@ interactive_option:
|
|||||||
/* Store our interactive status for boot */
|
/* Store our interactive status for boot */
|
||||||
if (interactive &&
|
if (interactive &&
|
||||||
(strcmp(runlevel, RC_LEVEL_SYSINIT) == 0 ||
|
(strcmp(runlevel, RC_LEVEL_SYSINIT) == 0 ||
|
||||||
strcmp(runlevel, getenv("RC_BOOTLEVEL")) == 0))
|
strcmp(runlevel, getenv("RC_BOOTLEVEL")) == 0))
|
||||||
mark_interactive();
|
mark_interactive();
|
||||||
else {
|
else {
|
||||||
if (exists(INTERACTIVE))
|
if (exists(INTERACTIVE))
|
||||||
@ -711,17 +712,17 @@ handle_bad_signal(int sig)
|
|||||||
pid_t crashed_pid = getpid();
|
pid_t crashed_pid = getpid();
|
||||||
|
|
||||||
switch (fork()) {
|
switch (fork()) {
|
||||||
case -1:
|
case -1:
|
||||||
_exit(sig);
|
_exit(sig);
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
case 0:
|
case 0:
|
||||||
sprintf(pid, "%i", crashed_pid);
|
sprintf(pid, "%i", crashed_pid);
|
||||||
printf("\nAuto launching gdb!\n\n");
|
printf("\nAuto launching gdb!\n\n");
|
||||||
_exit(execlp("gdb", "gdb", "--quiet", "--pid", pid,
|
_exit(execlp("gdb", "gdb", "--quiet", "--pid", pid,
|
||||||
"-ex", "bt full", NULL));
|
"-ex", "bt full", NULL));
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
default:
|
default:
|
||||||
wait(&status);
|
wait(&status);
|
||||||
}
|
}
|
||||||
_exit(1);
|
_exit(1);
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
@ -737,7 +738,8 @@ static const struct option longopts[] = {
|
|||||||
longopts_COMMON
|
longopts_COMMON
|
||||||
};
|
};
|
||||||
static const char * const longopts_help[] = {
|
static const char * const longopts_help[] = {
|
||||||
"override the next runlevel to change into\nwhen leaving single user or boot runlevels",
|
"override the next runlevel to change into\n"
|
||||||
|
"when leaving single user or boot runlevels",
|
||||||
"runs the service specified with the rest\nof the arguments",
|
"runs the service specified with the rest\nof the arguments",
|
||||||
"output the RC system type, if any",
|
"output the RC system type, if any",
|
||||||
longopts_help_COMMON
|
longopts_help_COMMON
|
||||||
@ -783,9 +785,9 @@ main(int argc, char **argv)
|
|||||||
printf(" [%s]", bootlevel);
|
printf(" [%s]", bootlevel);
|
||||||
printf(") " VERSION
|
printf(") " VERSION
|
||||||
#ifdef BRANDING
|
#ifdef BRANDING
|
||||||
" (" BRANDING ")"
|
" (" BRANDING ")"
|
||||||
#endif
|
#endif
|
||||||
"\n");
|
"\n");
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -806,7 +808,7 @@ main(int argc, char **argv)
|
|||||||
argc++;
|
argc++;
|
||||||
argv--;
|
argv--;
|
||||||
while ((opt = getopt_long(argc, argv, getoptstring,
|
while ((opt = getopt_long(argc, argv, getoptstring,
|
||||||
longopts, (int *) 0)) != -1)
|
longopts, (int *) 0)) != -1)
|
||||||
{
|
{
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'o':
|
case 'o':
|
||||||
@ -825,7 +827,7 @@ main(int argc, char **argv)
|
|||||||
newlevel = rc_service_resolve(optarg);
|
newlevel = rc_service_resolve(optarg);
|
||||||
if (!newlevel)
|
if (!newlevel)
|
||||||
eerrorx("%s: service `%s' does not exist",
|
eerrorx("%s: service `%s' does not exist",
|
||||||
applet, optarg);
|
applet, optarg);
|
||||||
argv += optind - 1;
|
argv += optind - 1;
|
||||||
*argv = newlevel;
|
*argv = newlevel;
|
||||||
execv(*argv, argv);
|
execv(*argv, argv);
|
||||||
@ -837,8 +839,8 @@ main(int argc, char **argv)
|
|||||||
printf("%s\n", bootlevel);
|
printf("%s\n", bootlevel);
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
case_RC_COMMON_GETOPT
|
case_RC_COMMON_GETOPT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
newlevel = argv[optind++];
|
newlevel = argv[optind++];
|
||||||
@ -886,7 +888,7 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
if (newlevel &&
|
if (newlevel &&
|
||||||
(strcmp(newlevel, RC_LEVEL_SHUTDOWN) == 0 ||
|
(strcmp(newlevel, RC_LEVEL_SHUTDOWN) == 0 ||
|
||||||
strcmp(newlevel, RC_LEVEL_SINGLE) == 0))
|
strcmp(newlevel, RC_LEVEL_SINGLE) == 0))
|
||||||
{
|
{
|
||||||
going_down = true;
|
going_down = true;
|
||||||
if (!exists(RC_KRUNLEVEL))
|
if (!exists(RC_KRUNLEVEL))
|
||||||
@ -895,10 +897,10 @@ main(int argc, char **argv)
|
|||||||
setenv("RC_RUNLEVEL", newlevel, 1);
|
setenv("RC_RUNLEVEL", newlevel, 1);
|
||||||
setenv("RC_GOINGDOWN", "YES", 1);
|
setenv("RC_GOINGDOWN", "YES", 1);
|
||||||
} else {
|
} else {
|
||||||
/* We should not use krunevel in sysinit or the boot runlevel */
|
/* We should not use krunevel in sysinit or boot runlevels */
|
||||||
if (!newlevel ||
|
if (!newlevel ||
|
||||||
(strcmp(newlevel, RC_LEVEL_SYSINIT) != 0 &&
|
(strcmp(newlevel, RC_LEVEL_SYSINIT) != 0 &&
|
||||||
strcmp(newlevel, getenv("RC_BOOTLEVEL")) != 0))
|
strcmp(newlevel, getenv("RC_BOOTLEVEL")) != 0))
|
||||||
{
|
{
|
||||||
if (get_krunlevel(krunlevel, sizeof(krunlevel))) {
|
if (get_krunlevel(krunlevel, sizeof(krunlevel))) {
|
||||||
newlevel = krunlevel;
|
newlevel = krunlevel;
|
||||||
@ -960,7 +962,7 @@ main(int argc, char **argv)
|
|||||||
if (errno == EACCES)
|
if (errno == EACCES)
|
||||||
eerrorx("%s: superuser access required", applet);
|
eerrorx("%s: superuser access required", applet);
|
||||||
eerrorx("%s: failed to create stopping dir `%s': %s",
|
eerrorx("%s: failed to create stopping dir `%s': %s",
|
||||||
applet, RC_STOPPING, strerror(errno));
|
applet, RC_STOPPING, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Build a list of all services to stop and then work out the
|
/* Build a list of all services to stop and then work out the
|
||||||
@ -982,7 +984,7 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
if (stop_services) {
|
if (stop_services) {
|
||||||
tmplist = rc_deptree_depends(deptree, types_nua, stop_services,
|
tmplist = rc_deptree_depends(deptree, types_nua, stop_services,
|
||||||
runlevel, depoptions | RC_DEP_STOP);
|
runlevel, depoptions | RC_DEP_STOP);
|
||||||
rc_stringlist_free(stop_services);
|
rc_stringlist_free(stop_services);
|
||||||
stop_services = tmplist;
|
stop_services = tmplist;
|
||||||
}
|
}
|
||||||
@ -990,7 +992,7 @@ main(int argc, char **argv)
|
|||||||
/* Load our list of start services */
|
/* Load our list of start services */
|
||||||
hotplugged_services = rc_services_in_state(RC_SERVICE_HOTPLUGGED);
|
hotplugged_services = rc_services_in_state(RC_SERVICE_HOTPLUGGED);
|
||||||
start_services = rc_services_in_runlevel(newlevel ?
|
start_services = rc_services_in_runlevel(newlevel ?
|
||||||
newlevel : runlevel);
|
newlevel : runlevel);
|
||||||
if (strcmp(newlevel ? newlevel : runlevel, RC_LEVEL_SHUTDOWN) != 0 &&
|
if (strcmp(newlevel ? newlevel : runlevel, RC_LEVEL_SHUTDOWN) != 0 &&
|
||||||
strcmp(newlevel ? newlevel : runlevel, RC_LEVEL_SYSINIT) != 0)
|
strcmp(newlevel ? newlevel : runlevel, RC_LEVEL_SYSINIT) != 0)
|
||||||
{
|
{
|
||||||
@ -998,10 +1000,10 @@ main(int argc, char **argv)
|
|||||||
TAILQ_CONCAT(start_services, tmplist, entries);
|
TAILQ_CONCAT(start_services, tmplist, entries);
|
||||||
free(tmplist);
|
free(tmplist);
|
||||||
if (strcmp(newlevel ? newlevel : runlevel,
|
if (strcmp(newlevel ? newlevel : runlevel,
|
||||||
RC_LEVEL_SINGLE) != 0)
|
RC_LEVEL_SINGLE) != 0)
|
||||||
{
|
{
|
||||||
if (strcmp(newlevel ? newlevel : runlevel,
|
if (strcmp(newlevel ? newlevel : runlevel,
|
||||||
bootlevel) != 0)
|
bootlevel) != 0)
|
||||||
{
|
{
|
||||||
tmplist = rc_services_in_runlevel(bootlevel);
|
tmplist = rc_services_in_runlevel(bootlevel);
|
||||||
TAILQ_CONCAT(start_services, tmplist, entries);
|
TAILQ_CONCAT(start_services, tmplist, entries);
|
||||||
@ -1009,9 +1011,9 @@ main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
if (hotplugged_services) {
|
if (hotplugged_services) {
|
||||||
TAILQ_FOREACH(service, hotplugged_services,
|
TAILQ_FOREACH(service, hotplugged_services,
|
||||||
entries)
|
entries)
|
||||||
rc_stringlist_addu(start_services,
|
rc_stringlist_addu(start_services,
|
||||||
service->value);
|
service->value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1027,7 +1029,7 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
/* Notify the plugins we have finished */
|
/* Notify the plugins we have finished */
|
||||||
rc_plugin_run(RC_HOOK_RUNLEVEL_STOP_OUT,
|
rc_plugin_run(RC_HOOK_RUNLEVEL_STOP_OUT,
|
||||||
going_down ? newlevel : runlevel);
|
going_down ? newlevel : runlevel);
|
||||||
hook_out = 0;
|
hook_out = 0;
|
||||||
|
|
||||||
rmdir(RC_STOPPING);
|
rmdir(RC_STOPPING);
|
||||||
@ -1054,14 +1056,14 @@ main(int argc, char **argv)
|
|||||||
/* Re-add our hotplugged services if they stopped */
|
/* Re-add our hotplugged services if they stopped */
|
||||||
if (hotplugged_services)
|
if (hotplugged_services)
|
||||||
TAILQ_FOREACH(service, hotplugged_services, entries)
|
TAILQ_FOREACH(service, hotplugged_services, entries)
|
||||||
rc_service_mark(service->value, RC_SERVICE_HOTPLUGGED);
|
rc_service_mark(service->value, RC_SERVICE_HOTPLUGGED);
|
||||||
|
|
||||||
/* Order the services to start */
|
/* Order the services to start */
|
||||||
if (start_services) {
|
if (start_services) {
|
||||||
rc_stringlist_sort(&start_services);
|
rc_stringlist_sort(&start_services);
|
||||||
deporder = rc_deptree_depends(deptree, types_nua,
|
deporder = rc_deptree_depends(deptree, types_nua,
|
||||||
start_services, runlevel,
|
start_services, runlevel,
|
||||||
depoptions | RC_DEP_START);
|
depoptions | RC_DEP_START);
|
||||||
rc_stringlist_free(start_services);
|
rc_stringlist_free(start_services);
|
||||||
start_services = deporder;
|
start_services = deporder;
|
||||||
}
|
}
|
||||||
|
@ -54,11 +54,11 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
# include <pty.h>
|
# include <pty.h>
|
||||||
#elif defined(__NetBSD__) || defined(__OpenBSD__)
|
#elif defined(__NetBSD__) || defined(__OpenBSD__)
|
||||||
# include <util.h>
|
# include <util.h>
|
||||||
#else
|
#else
|
||||||
# include <libutil.h>
|
# include <libutil.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "builtins.h"
|
#include "builtins.h"
|
||||||
@ -121,9 +121,9 @@ setup_selinux(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
selinux_run_init_old = (void (*)(void))
|
selinux_run_init_old = (void (*)(void))
|
||||||
dlfunc(lib_handle, "selinux_runscript");
|
dlfunc(lib_handle, "selinux_runscript");
|
||||||
selinux_run_init_new = (void (*)(int, char **))
|
selinux_run_init_new = (void (*)(int, char **))
|
||||||
dlfunc(lib_handle, "selinux_runscript2");
|
dlfunc(lib_handle, "selinux_runscript2");
|
||||||
|
|
||||||
/* Use new run_init if it exists, else fall back to old */
|
/* Use new run_init if it exists, else fall back to old */
|
||||||
if (selinux_run_init_new)
|
if (selinux_run_init_new)
|
||||||
@ -154,7 +154,7 @@ handle_signal(int sig)
|
|||||||
if (signal_pipe[1] > -1) {
|
if (signal_pipe[1] > -1) {
|
||||||
if (write(signal_pipe[1], &sig, sizeof(sig)) == -1)
|
if (write(signal_pipe[1], &sig, sizeof(sig)) == -1)
|
||||||
eerror("%s: send: %s",
|
eerror("%s: send: %s",
|
||||||
service, strerror(errno));
|
service, strerror(errno));
|
||||||
} else
|
} else
|
||||||
rc_waitpid(-1);
|
rc_waitpid(-1);
|
||||||
break;
|
break;
|
||||||
@ -217,16 +217,16 @@ start_services(RC_STRINGLIST *list)
|
|||||||
{
|
{
|
||||||
TAILQ_FOREACH(svc, list, entries) {
|
TAILQ_FOREACH(svc, list, entries) {
|
||||||
if (!(rc_service_state(svc->value) &
|
if (!(rc_service_state(svc->value) &
|
||||||
RC_SERVICE_STOPPED))
|
RC_SERVICE_STOPPED))
|
||||||
continue;
|
continue;
|
||||||
if (state & RC_SERVICE_INACTIVE ||
|
if (state & RC_SERVICE_INACTIVE ||
|
||||||
state & RC_SERVICE_WASINACTIVE)
|
state & RC_SERVICE_WASINACTIVE)
|
||||||
{
|
{
|
||||||
rc_service_schedule_start(service,
|
rc_service_schedule_start(service,
|
||||||
svc->value);
|
svc->value);
|
||||||
ewarn("WARNING: %s is scheduled to started"
|
ewarn("WARNING: %s is scheduled to started"
|
||||||
" when %s has started",
|
" when %s has started",
|
||||||
svc->value, applet);
|
svc->value, applet);
|
||||||
} else
|
} else
|
||||||
service_start(svc->value);
|
service_start(svc->value);
|
||||||
}
|
}
|
||||||
@ -269,10 +269,10 @@ cleanup(void)
|
|||||||
rc_plugin_run(hook_out, applet);
|
rc_plugin_run(hook_out, applet);
|
||||||
if (hook_out == RC_HOOK_SERVICE_START_DONE)
|
if (hook_out == RC_HOOK_SERVICE_START_DONE)
|
||||||
rc_plugin_run(RC_HOOK_SERVICE_START_OUT,
|
rc_plugin_run(RC_HOOK_SERVICE_START_OUT,
|
||||||
applet);
|
applet);
|
||||||
else if (hook_out == RC_HOOK_SERVICE_STOP_DONE)
|
else if (hook_out == RC_HOOK_SERVICE_STOP_DONE)
|
||||||
rc_plugin_run(RC_HOOK_SERVICE_STOP_OUT,
|
rc_plugin_run(RC_HOOK_SERVICE_STOP_OUT,
|
||||||
applet);
|
applet);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (restart_services)
|
if (restart_services)
|
||||||
@ -369,7 +369,7 @@ svc_exec(const char *arg1, const char *arg2)
|
|||||||
eerrorx("%s: pipe: %s", service, applet);
|
eerrorx("%s: pipe: %s", service, applet);
|
||||||
for (i = 0; i < 2; i++)
|
for (i = 0; i < 2; i++)
|
||||||
if ((flags = fcntl(signal_pipe[i], F_GETFD, 0) == -1 ||
|
if ((flags = fcntl(signal_pipe[i], F_GETFD, 0) == -1 ||
|
||||||
fcntl(signal_pipe[i], F_SETFD, flags | FD_CLOEXEC) == -1))
|
fcntl(signal_pipe[i], F_SETFD, flags | FD_CLOEXEC) == -1))
|
||||||
eerrorx("%s: fcntl: %s", service, strerror(errno));
|
eerrorx("%s: fcntl: %s", service, strerror(errno));
|
||||||
|
|
||||||
/* Open a pty for our prefixed output
|
/* Open a pty for our prefixed output
|
||||||
@ -387,11 +387,11 @@ svc_exec(const char *arg1, const char *arg2)
|
|||||||
openpty(&master_tty, &slave_tty, NULL, &tt, &ws);
|
openpty(&master_tty, &slave_tty, NULL, &tt, &ws);
|
||||||
if (master_tty >= 0 &&
|
if (master_tty >= 0 &&
|
||||||
(flags = fcntl(master_tty, F_GETFD, 0)) == 0)
|
(flags = fcntl(master_tty, F_GETFD, 0)) == 0)
|
||||||
fcntl(master_tty, F_SETFD, flags | FD_CLOEXEC);
|
fcntl(master_tty, F_SETFD, flags | FD_CLOEXEC);
|
||||||
|
|
||||||
if (slave_tty >=0 &&
|
if (slave_tty >=0 &&
|
||||||
(flags = fcntl(slave_tty, F_GETFD, 0)) == 0)
|
(flags = fcntl(slave_tty, F_GETFD, 0)) == 0)
|
||||||
fcntl(slave_tty, F_SETFD, flags | FD_CLOEXEC);
|
fcntl(slave_tty, F_SETFD, flags | FD_CLOEXEC);
|
||||||
}
|
}
|
||||||
|
|
||||||
service_pid = fork();
|
service_pid = fork();
|
||||||
@ -405,17 +405,17 @@ svc_exec(const char *arg1, const char *arg2)
|
|||||||
|
|
||||||
if (exists(RC_SVCDIR "/runscript.sh")) {
|
if (exists(RC_SVCDIR "/runscript.sh")) {
|
||||||
execl(RC_SVCDIR "/runscript.sh",
|
execl(RC_SVCDIR "/runscript.sh",
|
||||||
RC_SVCDIR "/runscript.sh",
|
RC_SVCDIR "/runscript.sh",
|
||||||
service, arg1, arg2, (char *) NULL);
|
service, arg1, arg2, (char *) NULL);
|
||||||
eerror("%s: exec `" RC_SVCDIR "/runscript.sh': %s",
|
eerror("%s: exec `" RC_SVCDIR "/runscript.sh': %s",
|
||||||
service, strerror(errno));
|
service, strerror(errno));
|
||||||
_exit(EXIT_FAILURE);
|
_exit(EXIT_FAILURE);
|
||||||
} else {
|
} else {
|
||||||
execl(RC_LIBDIR "/sh/runscript.sh",
|
execl(RC_LIBDIR "/sh/runscript.sh",
|
||||||
RC_LIBDIR "/sh/runscript.sh",
|
RC_LIBDIR "/sh/runscript.sh",
|
||||||
service, arg1, arg2, (char *) NULL);
|
service, arg1, arg2, (char *) NULL);
|
||||||
eerror("%s: exec `" RC_LIBDIR "/sh/runscript.sh': %s",
|
eerror("%s: exec `" RC_LIBDIR "/sh/runscript.sh': %s",
|
||||||
service, strerror(errno));
|
service, strerror(errno));
|
||||||
_exit(EXIT_FAILURE);
|
_exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -434,7 +434,7 @@ svc_exec(const char *arg1, const char *arg2)
|
|||||||
if ((s = poll(fd, master_tty >= 0 ? 2 : 1, -1)) == -1) {
|
if ((s = poll(fd, master_tty >= 0 ? 2 : 1, -1)) == -1) {
|
||||||
if (errno != EINTR) {
|
if (errno != EINTR) {
|
||||||
eerror("%s: poll: %s",
|
eerror("%s: poll: %s",
|
||||||
service, strerror(errno));
|
service, strerror(errno));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -488,7 +488,7 @@ svc_wait(const char *svc)
|
|||||||
rc_stringlist_free(keywords);
|
rc_stringlist_free(keywords);
|
||||||
|
|
||||||
snprintf(file, sizeof(file), RC_SVCDIR "/exclusive/%s",
|
snprintf(file, sizeof(file), RC_SVCDIR "/exclusive/%s",
|
||||||
basename_c(svc));
|
basename_c(svc));
|
||||||
|
|
||||||
interval.tv_sec = 0;
|
interval.tv_sec = 0;
|
||||||
interval.tv_nsec = WAIT_INTERVAL;
|
interval.tv_nsec = WAIT_INTERVAL;
|
||||||
@ -521,7 +521,7 @@ svc_wait(const char *svc)
|
|||||||
timespecsub(&warn, &interval, &warn);
|
timespecsub(&warn, &interval, &warn);
|
||||||
if (warn.tv_sec <= 0) {
|
if (warn.tv_sec <= 0) {
|
||||||
ewarn("%s: waiting for %s (%zu)", applet, svc,
|
ewarn("%s: waiting for %s (%zu)", applet, svc,
|
||||||
timeout.tv_sec);
|
timeout.tv_sec);
|
||||||
warn.tv_sec = WARN_TIMEOUT;
|
warn.tv_sec = WARN_TIMEOUT;
|
||||||
warn.tv_nsec = 0;
|
warn.tv_nsec = 0;
|
||||||
}
|
}
|
||||||
@ -593,7 +593,7 @@ svc_start(bool deps)
|
|||||||
rc_service_mark(service, RC_SERVICE_HOTPLUGGED);
|
rc_service_mark(service, RC_SERVICE_HOTPLUGGED);
|
||||||
if (strcmp(runlevel, RC_LEVEL_SYSINIT) == 0)
|
if (strcmp(runlevel, RC_LEVEL_SYSINIT) == 0)
|
||||||
ewarnx("WARNING: %s will be started in the"
|
ewarnx("WARNING: %s will be started in the"
|
||||||
" next runlevel", applet);
|
" next runlevel", applet);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exclusive_fd == -1)
|
if (exclusive_fd == -1)
|
||||||
@ -607,14 +607,14 @@ svc_start(bool deps)
|
|||||||
ewarnx("WARNING: %s is already starting", applet);
|
ewarnx("WARNING: %s is already starting", applet);
|
||||||
}
|
}
|
||||||
fcntl(exclusive_fd, F_SETFD,
|
fcntl(exclusive_fd, F_SETFD,
|
||||||
fcntl(exclusive_fd, F_GETFD, 0) | FD_CLOEXEC);
|
fcntl(exclusive_fd, F_GETFD, 0) | FD_CLOEXEC);
|
||||||
|
|
||||||
if (state & RC_SERVICE_STARTED) {
|
if (state & RC_SERVICE_STARTED) {
|
||||||
ewarn("WARNING: %s has already been started", applet);
|
ewarn("WARNING: %s has already been started", applet);
|
||||||
return;
|
return;
|
||||||
} else if (state & RC_SERVICE_INACTIVE && ! background)
|
} else if (state & RC_SERVICE_INACTIVE && ! background)
|
||||||
ewarnx("WARNING: %s has already started, but is inactive",
|
ewarnx("WARNING: %s has already started, but is inactive",
|
||||||
applet);
|
applet);
|
||||||
|
|
||||||
rc_service_mark(service, RC_SERVICE_STARTING);
|
rc_service_mark(service, RC_SERVICE_STARTING);
|
||||||
hook_out = RC_HOOK_SERVICE_START_OUT;
|
hook_out = RC_HOOK_SERVICE_START_OUT;
|
||||||
@ -631,7 +631,7 @@ svc_start(bool deps)
|
|||||||
setup_types();
|
setup_types();
|
||||||
|
|
||||||
services = rc_deptree_depends(deptree, types_b, applet_list,
|
services = rc_deptree_depends(deptree, types_b, applet_list,
|
||||||
runlevel, 0);
|
runlevel, 0);
|
||||||
if (TAILQ_FIRST(services)) {
|
if (TAILQ_FIRST(services)) {
|
||||||
eerrorn("ERROR: `%s' needs ", applet);
|
eerrorn("ERROR: `%s' needs ", applet);
|
||||||
first = true;
|
first = true;
|
||||||
@ -648,11 +648,11 @@ svc_start(bool deps)
|
|||||||
services = NULL;
|
services = NULL;
|
||||||
|
|
||||||
need_services = rc_deptree_depends(deptree, types_n,
|
need_services = rc_deptree_depends(deptree, types_n,
|
||||||
applet_list, runlevel,
|
applet_list, runlevel,
|
||||||
depoptions);
|
depoptions);
|
||||||
use_services = rc_deptree_depends(deptree, types_nu,
|
use_services = rc_deptree_depends(deptree, types_nu,
|
||||||
applet_list, runlevel,
|
applet_list, runlevel,
|
||||||
depoptions);
|
depoptions);
|
||||||
|
|
||||||
if (!rc_runlevel_starting()) {
|
if (!rc_runlevel_starting()) {
|
||||||
TAILQ_FOREACH(svc, use_services, entries) {
|
TAILQ_FOREACH(svc, use_services, entries) {
|
||||||
@ -673,7 +673,7 @@ svc_start(bool deps)
|
|||||||
|
|
||||||
/* Now wait for them to start */
|
/* Now wait for them to start */
|
||||||
services = rc_deptree_depends(deptree, types_nua, applet_list,
|
services = rc_deptree_depends(deptree, types_nua, applet_list,
|
||||||
runlevel, depoptions);
|
runlevel, depoptions);
|
||||||
/* We use tmplist to hold our scheduled by list */
|
/* We use tmplist to hold our scheduled by list */
|
||||||
tmplist = rc_stringlist_new();
|
tmplist = rc_stringlist_new();
|
||||||
TAILQ_FOREACH(svc, services, entries) {
|
TAILQ_FOREACH(svc, services, entries) {
|
||||||
@ -687,15 +687,15 @@ svc_start(bool deps)
|
|||||||
state & RC_SERVICE_WASINACTIVE)
|
state & RC_SERVICE_WASINACTIVE)
|
||||||
{
|
{
|
||||||
if (!rc_stringlist_find(need_services,
|
if (!rc_stringlist_find(need_services,
|
||||||
svc->value) &&
|
svc->value) &&
|
||||||
!rc_stringlist_find(use_services,
|
!rc_stringlist_find(use_services,
|
||||||
svc->value))
|
svc->value))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!svc_wait(svc->value))
|
if (!svc_wait(svc->value))
|
||||||
eerror("%s: timed out waiting for %s",
|
eerror("%s: timed out waiting for %s",
|
||||||
applet, svc->value);
|
applet, svc->value);
|
||||||
state = rc_service_state(svc->value);
|
state = rc_service_state(svc->value);
|
||||||
if (state & RC_SERVICE_STARTED)
|
if (state & RC_SERVICE_STARTED)
|
||||||
continue;
|
continue;
|
||||||
@ -706,8 +706,8 @@ svc_start(bool deps)
|
|||||||
rc_stringlist_add(tmplist, svc->value);
|
rc_stringlist_add(tmplist, svc->value);
|
||||||
} else if (!TAILQ_FIRST(tmplist))
|
} else if (!TAILQ_FIRST(tmplist))
|
||||||
eerrorx("ERROR: cannot start %s as"
|
eerrorx("ERROR: cannot start %s as"
|
||||||
" %s would not start",
|
" %s would not start",
|
||||||
applet, svc->value);
|
applet, svc->value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -723,11 +723,11 @@ svc_start(bool deps)
|
|||||||
TAILQ_FOREACH(svc, tmplist, entries) {
|
TAILQ_FOREACH(svc, tmplist, entries) {
|
||||||
rc_service_schedule_start(svc->value, service);
|
rc_service_schedule_start(svc->value, service);
|
||||||
use_services = rc_deptree_depend(deptree,
|
use_services = rc_deptree_depend(deptree,
|
||||||
"iprovide",
|
"iprovide",
|
||||||
svc->value);
|
svc->value);
|
||||||
TAILQ_FOREACH(svc2, use_services, entries)
|
TAILQ_FOREACH(svc2, use_services, entries)
|
||||||
rc_service_schedule_start(svc2->value,
|
rc_service_schedule_start(svc2->value,
|
||||||
service);
|
service);
|
||||||
rc_stringlist_free(use_services);
|
rc_stringlist_free(use_services);
|
||||||
use_services = NULL;
|
use_services = NULL;
|
||||||
len += strlen(svc->value) + 2;
|
len += strlen(svc->value) + 2;
|
||||||
@ -740,12 +740,12 @@ svc_start(bool deps)
|
|||||||
if (p != tmp)
|
if (p != tmp)
|
||||||
p += snprintf(p, len, ", ");
|
p += snprintf(p, len, ", ");
|
||||||
p += snprintf(p, len - (p - tmp),
|
p += snprintf(p, len - (p - tmp),
|
||||||
"%s", svc->value);
|
"%s", svc->value);
|
||||||
}
|
}
|
||||||
rc_stringlist_free(tmplist);
|
rc_stringlist_free(tmplist);
|
||||||
tmplist = NULL;
|
tmplist = NULL;
|
||||||
ewarnx("WARNING: %s is scheduled to start when "
|
ewarnx("WARNING: %s is scheduled to start when "
|
||||||
"%s has started", applet, tmp);
|
"%s has started", applet, tmp);
|
||||||
free(tmp);
|
free(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -766,7 +766,7 @@ svc_start(bool deps)
|
|||||||
else {
|
else {
|
||||||
if (rc_service_state(service) & RC_SERVICE_INACTIVE)
|
if (rc_service_state(service) & RC_SERVICE_INACTIVE)
|
||||||
ewarnx("WARNING: %s has started, but is inactive",
|
ewarnx("WARNING: %s has started, but is inactive",
|
||||||
applet);
|
applet);
|
||||||
}
|
}
|
||||||
|
|
||||||
rc_service_mark(service, RC_SERVICE_STARTED);
|
rc_service_mark(service, RC_SERVICE_STARTED);
|
||||||
@ -777,8 +777,8 @@ svc_start(bool deps)
|
|||||||
/* Now start any scheduled services */
|
/* Now start any scheduled services */
|
||||||
services = rc_services_scheduled(service);
|
services = rc_services_scheduled(service);
|
||||||
TAILQ_FOREACH(svc, services, entries)
|
TAILQ_FOREACH(svc, services, entries)
|
||||||
if (rc_service_state(svc->value) & RC_SERVICE_STOPPED)
|
if (rc_service_state(svc->value) & RC_SERVICE_STOPPED)
|
||||||
service_start(svc->value);
|
service_start(svc->value);
|
||||||
rc_stringlist_free(services);
|
rc_stringlist_free(services);
|
||||||
services = NULL;
|
services = NULL;
|
||||||
|
|
||||||
@ -788,9 +788,9 @@ svc_start(bool deps)
|
|||||||
TAILQ_FOREACH(svc, tmplist, entries) {
|
TAILQ_FOREACH(svc, tmplist, entries) {
|
||||||
services = rc_services_scheduled(svc->value);
|
services = rc_services_scheduled(svc->value);
|
||||||
TAILQ_FOREACH(svc2, services, entries)
|
TAILQ_FOREACH(svc2, services, entries)
|
||||||
if (rc_service_state(svc2->value) &
|
if (rc_service_state(svc2->value) &
|
||||||
RC_SERVICE_STOPPED)
|
RC_SERVICE_STOPPED)
|
||||||
service_start(svc2->value);
|
service_start(svc2->value);
|
||||||
rc_stringlist_free(services);
|
rc_stringlist_free(services);
|
||||||
services = NULL;
|
services = NULL;
|
||||||
}
|
}
|
||||||
@ -829,7 +829,7 @@ svc_stop(bool deps)
|
|||||||
eerrorx("ERROR: %s has been stopped by something else", applet);
|
eerrorx("ERROR: %s has been stopped by something else", applet);
|
||||||
}
|
}
|
||||||
fcntl(exclusive_fd, F_SETFD,
|
fcntl(exclusive_fd, F_SETFD,
|
||||||
fcntl(exclusive_fd, F_GETFD, 0) | FD_CLOEXEC);
|
fcntl(exclusive_fd, F_GETFD, 0) | FD_CLOEXEC);
|
||||||
|
|
||||||
if (state & RC_SERVICE_STOPPED) {
|
if (state & RC_SERVICE_STOPPED) {
|
||||||
ewarn("WARNING: %s is already stopped", applet);
|
ewarn("WARNING: %s is already stopped", applet);
|
||||||
@ -859,7 +859,7 @@ svc_stop(bool deps)
|
|||||||
setup_types();
|
setup_types();
|
||||||
|
|
||||||
services = rc_deptree_depends(deptree, types_m, applet_list,
|
services = rc_deptree_depends(deptree, types_m, applet_list,
|
||||||
runlevel, depoptions);
|
runlevel, depoptions);
|
||||||
tmplist = rc_stringlist_new();
|
tmplist = rc_stringlist_new();
|
||||||
TAILQ_FOREACH_REVERSE(svc, services, rc_stringlist, entries) {
|
TAILQ_FOREACH_REVERSE(svc, services, rc_stringlist, entries) {
|
||||||
state = rc_service_state(svc->value);
|
state = rc_service_state(svc->value);
|
||||||
@ -898,14 +898,14 @@ svc_stop(bool deps)
|
|||||||
* if a dependant failed */
|
* if a dependant failed */
|
||||||
if (runlevel &&
|
if (runlevel &&
|
||||||
(strcmp(runlevel,
|
(strcmp(runlevel,
|
||||||
RC_LEVEL_SHUTDOWN) == 0 ||
|
RC_LEVEL_SHUTDOWN) == 0 ||
|
||||||
strcmp(runlevel,
|
strcmp(runlevel,
|
||||||
RC_LEVEL_SINGLE) == 0))
|
RC_LEVEL_SINGLE) == 0))
|
||||||
continue;
|
continue;
|
||||||
rc_service_mark(service, RC_SERVICE_FAILED);
|
rc_service_mark(service, RC_SERVICE_FAILED);
|
||||||
}
|
}
|
||||||
eerrorx("ERROR: cannot stop %s as %s "
|
eerrorx("ERROR: cannot stop %s as %s "
|
||||||
"is still up", applet, svc->value);
|
"is still up", applet, svc->value);
|
||||||
}
|
}
|
||||||
rc_stringlist_free(tmplist);
|
rc_stringlist_free(tmplist);
|
||||||
tmplist = NULL;
|
tmplist = NULL;
|
||||||
@ -914,7 +914,7 @@ svc_stop(bool deps)
|
|||||||
/* We now wait for other services that may use us and are
|
/* We now wait for other services that may use us and are
|
||||||
* stopping. This is important when a runlevel stops */
|
* stopping. This is important when a runlevel stops */
|
||||||
services = rc_deptree_depends(deptree, types_mua, applet_list,
|
services = rc_deptree_depends(deptree, types_mua, applet_list,
|
||||||
runlevel, depoptions);
|
runlevel, depoptions);
|
||||||
TAILQ_FOREACH(svc, services, entries) {
|
TAILQ_FOREACH(svc, services, entries) {
|
||||||
if (rc_service_state(svc->value) & RC_SERVICE_STOPPED)
|
if (rc_service_state(svc->value) & RC_SERVICE_STOPPED)
|
||||||
continue;
|
continue;
|
||||||
@ -1062,7 +1062,7 @@ runscript(int argc, char **argv)
|
|||||||
|
|
||||||
if (stat(argv[1], &stbuf) != 0) {
|
if (stat(argv[1], &stbuf) != 0) {
|
||||||
fprintf(stderr, "runscript `%s': %s\n",
|
fprintf(stderr, "runscript `%s': %s\n",
|
||||||
argv[1], strerror(errno));
|
argv[1], strerror(errno));
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1158,7 +1158,7 @@ runscript(int argc, char **argv)
|
|||||||
|
|
||||||
/* Right then, parse any options there may be */
|
/* Right then, parse any options there may be */
|
||||||
while ((opt = getopt_long(argc, argv, getoptstring,
|
while ((opt = getopt_long(argc, argv, getoptstring,
|
||||||
longopts, (int *)0)) != -1)
|
longopts, (int *)0)) != -1)
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'd':
|
case 'd':
|
||||||
setenv("RC_DEBUG", "YES", 1);
|
setenv("RC_DEBUG", "YES", 1);
|
||||||
@ -1175,8 +1175,8 @@ runscript(int argc, char **argv)
|
|||||||
case 'D':
|
case 'D':
|
||||||
deps = false;
|
deps = false;
|
||||||
break;
|
break;
|
||||||
case_RC_COMMON_GETOPT
|
case_RC_COMMON_GETOPT
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we're changing runlevels and not called by rc then we cannot
|
/* If we're changing runlevels and not called by rc then we cannot
|
||||||
work with any dependencies */
|
work with any dependencies */
|
||||||
@ -1238,12 +1238,12 @@ runscript(int argc, char **argv)
|
|||||||
eprefix(save);
|
eprefix(save);
|
||||||
prefix = save;
|
prefix = save;
|
||||||
} else if (strcmp(optarg, "ineed") == 0 ||
|
} else if (strcmp(optarg, "ineed") == 0 ||
|
||||||
strcmp(optarg, "iuse") == 0 ||
|
strcmp(optarg, "iuse") == 0 ||
|
||||||
strcmp(optarg, "needsme") == 0 ||
|
strcmp(optarg, "needsme") == 0 ||
|
||||||
strcmp(optarg, "usesme") == 0 ||
|
strcmp(optarg, "usesme") == 0 ||
|
||||||
strcmp(optarg, "iafter") == 0 ||
|
strcmp(optarg, "iafter") == 0 ||
|
||||||
strcmp(optarg, "ibefore") == 0 ||
|
strcmp(optarg, "ibefore") == 0 ||
|
||||||
strcmp(optarg, "iprovide") == 0)
|
strcmp(optarg, "iprovide") == 0)
|
||||||
{
|
{
|
||||||
errno = 0;
|
errno = 0;
|
||||||
if (rc_conf_yesno("rc_depend_strict") ||
|
if (rc_conf_yesno("rc_depend_strict") ||
|
||||||
@ -1257,11 +1257,11 @@ runscript(int argc, char **argv)
|
|||||||
tmplist = rc_stringlist_new();
|
tmplist = rc_stringlist_new();
|
||||||
rc_stringlist_add(tmplist, optarg);
|
rc_stringlist_add(tmplist, optarg);
|
||||||
services = rc_deptree_depends(deptree, tmplist,
|
services = rc_deptree_depends(deptree, tmplist,
|
||||||
applet_list,
|
applet_list,
|
||||||
runlevel, depoptions);
|
runlevel, depoptions);
|
||||||
rc_stringlist_free(tmplist);
|
rc_stringlist_free(tmplist);
|
||||||
TAILQ_FOREACH(svc, services, entries)
|
TAILQ_FOREACH(svc, services, entries)
|
||||||
printf("%s ", svc->value);
|
printf("%s ", svc->value);
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
rc_stringlist_free(services);
|
rc_stringlist_free(services);
|
||||||
services = NULL;
|
services = NULL;
|
||||||
@ -1297,20 +1297,20 @@ runscript(int argc, char **argv)
|
|||||||
RC_SERVICE_INACTIVE)
|
RC_SERVICE_INACTIVE)
|
||||||
{
|
{
|
||||||
TAILQ_FOREACH(svc,
|
TAILQ_FOREACH(svc,
|
||||||
restart_services,
|
restart_services,
|
||||||
entries)
|
entries)
|
||||||
if (rc_service_state(svc->value) &
|
if (rc_service_state(svc->value) &
|
||||||
RC_SERVICE_STOPPED)
|
RC_SERVICE_STOPPED)
|
||||||
rc_service_schedule_start(service, svc->value);
|
rc_service_schedule_start(service, svc->value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (strcmp(optarg, "zap") == 0) {
|
} else if (strcmp(optarg, "zap") == 0) {
|
||||||
einfo("Manually resetting %s to stopped state",
|
einfo("Manually resetting %s to stopped state",
|
||||||
applet);
|
applet);
|
||||||
if (!rc_service_mark(applet,
|
if (!rc_service_mark(applet,
|
||||||
RC_SERVICE_STOPPED))
|
RC_SERVICE_STOPPED))
|
||||||
eerrorx("rc_service_mark: %s",
|
eerrorx("rc_service_mark: %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
unhotplug();
|
unhotplug();
|
||||||
} else
|
} else
|
||||||
svc_exec(optarg, NULL);
|
svc_exec(optarg, NULL);
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
start-stop-daemon
|
start-stop-daemon
|
||||||
Starts, stops, tests and signals daemons
|
Starts, stops, tests and signals daemons
|
||||||
|
|
||||||
This is essentially a ground up re-write of Debians
|
This is essentially a ground up re-write of Debians
|
||||||
start-stop-daemon for cleaner code and to integrate into our RC
|
start-stop-daemon for cleaner code and to integrate into our RC
|
||||||
system so we can monitor daemons a little.
|
system so we can monitor daemons a little.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2007-2009 Roy Marples <roy@marples.name>
|
* Copyright 2007-2009 Roy Marples <roy@marples.name>
|
||||||
@ -75,9 +75,9 @@ static struct pam_conv conv = { NULL, NULL};
|
|||||||
|
|
||||||
/* Some libc implementations don't define this */
|
/* Some libc implementations don't define this */
|
||||||
#ifndef LIST_FOREACH_SAFE
|
#ifndef LIST_FOREACH_SAFE
|
||||||
#define LIST_FOREACH_SAFE(var, head, field, tvar) \
|
#define LIST_FOREACH_SAFE(var, head, field, tvar) \
|
||||||
for ((var) = LIST_FIRST((head)); \
|
for ((var) = LIST_FIRST((head)); \
|
||||||
(var) && ((tvar) = LIST_NEXT((var), field), 1); \
|
(var) && ((tvar) = LIST_NEXT((var), field), 1); \
|
||||||
(var) = (tvar))
|
(var) = (tvar))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -85,12 +85,12 @@ static struct pam_conv conv = { NULL, NULL};
|
|||||||
typedef struct scheduleitem
|
typedef struct scheduleitem
|
||||||
{
|
{
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
SC_TIMEOUT,
|
SC_TIMEOUT,
|
||||||
SC_SIGNAL,
|
SC_SIGNAL,
|
||||||
SC_GOTO,
|
SC_GOTO,
|
||||||
SC_FOREVER
|
SC_FOREVER
|
||||||
} type;
|
} type;
|
||||||
int value;
|
int value;
|
||||||
struct scheduleitem *gotoitem;
|
struct scheduleitem *gotoitem;
|
||||||
TAILQ_ENTRY(scheduleitem) entries;
|
TAILQ_ENTRY(scheduleitem) entries;
|
||||||
@ -103,7 +103,8 @@ static char *changeuser, *ch_root, *ch_dir;
|
|||||||
|
|
||||||
extern char **environ;
|
extern char **environ;
|
||||||
|
|
||||||
static void free_schedulelist(void)
|
static void
|
||||||
|
free_schedulelist(void)
|
||||||
{
|
{
|
||||||
SCHEDULEITEM *s1 = TAILQ_FIRST(&schedule);
|
SCHEDULEITEM *s1 = TAILQ_FIRST(&schedule);
|
||||||
SCHEDULEITEM *s2;
|
SCHEDULEITEM *s2;
|
||||||
@ -117,7 +118,8 @@ static void free_schedulelist(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_MEMORY
|
#ifdef DEBUG_MEMORY
|
||||||
static void cleanup(void)
|
static void
|
||||||
|
cleanup(void)
|
||||||
{
|
{
|
||||||
free(changeuser);
|
free(changeuser);
|
||||||
free(nav);
|
free(nav);
|
||||||
@ -125,7 +127,8 @@ static void cleanup(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int parse_signal(const char *sig)
|
static int
|
||||||
|
parse_signal(const char *sig)
|
||||||
{
|
{
|
||||||
typedef struct signalpair
|
typedef struct signalpair
|
||||||
{
|
{
|
||||||
@ -181,7 +184,8 @@ static int parse_signal(const char *sig)
|
|||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
|
|
||||||
static SCHEDULEITEM *parse_schedule_item(const char *string)
|
static SCHEDULEITEM *
|
||||||
|
parse_schedule_item(const char *string)
|
||||||
{
|
{
|
||||||
const char *after_hyph;
|
const char *after_hyph;
|
||||||
int sig;
|
int sig;
|
||||||
@ -195,21 +199,21 @@ static SCHEDULEITEM *parse_schedule_item(const char *string)
|
|||||||
item->type = SC_TIMEOUT;
|
item->type = SC_TIMEOUT;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
if (sscanf(string, "%d", &item->value) != 1)
|
if (sscanf(string, "%d", &item->value) != 1)
|
||||||
eerrorx("%s: invalid timeout value in schedule `%s'", applet,
|
eerrorx("%s: invalid timeout value in schedule `%s'",
|
||||||
string);
|
applet, string);
|
||||||
} else if ((after_hyph = string + (string[0] == '-')) &&
|
} else if ((after_hyph = string + (string[0] == '-')) &&
|
||||||
((sig = parse_signal(after_hyph)) != -1))
|
((sig = parse_signal(after_hyph)) != -1))
|
||||||
{
|
{
|
||||||
item->type = SC_SIGNAL;
|
item->type = SC_SIGNAL;
|
||||||
item->value = (int)sig;
|
item->value = (int)sig;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
eerrorx("%s: invalid schedule item `%s'", applet, string);
|
eerrorx("%s: invalid schedule item `%s'", applet, string);
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void parse_schedule(const char *string, int timeout)
|
static void
|
||||||
|
parse_schedule(const char *string, int timeout)
|
||||||
{
|
{
|
||||||
char buffer[20];
|
char buffer[20];
|
||||||
const char *slash;
|
const char *slash;
|
||||||
@ -238,7 +242,8 @@ static void parse_schedule(const char *string, int timeout)
|
|||||||
TAILQ_INSERT_TAIL(&schedule, item, entries);
|
TAILQ_INSERT_TAIL(&schedule, item, entries);
|
||||||
if (string) {
|
if (string) {
|
||||||
if (sscanf(string, "%d", &item->value) != 1)
|
if (sscanf(string, "%d", &item->value) != 1)
|
||||||
eerrorx("%s: invalid timeout value in schedule", applet);
|
eerrorx("%s: invalid timeout in schedule",
|
||||||
|
applet);
|
||||||
} else
|
} else
|
||||||
item->value = 5;
|
item->value = 5;
|
||||||
|
|
||||||
@ -251,8 +256,9 @@ static void parse_schedule(const char *string, int timeout)
|
|||||||
else
|
else
|
||||||
len = strlen(string);
|
len = strlen(string);
|
||||||
|
|
||||||
if (len >= (ptrdiff_t) sizeof(buffer))
|
if (len >= (ptrdiff_t)sizeof(buffer))
|
||||||
eerrorx("%s: invalid schedule item, far too long", applet);
|
eerrorx("%s: invalid schedule item, far too long",
|
||||||
|
applet);
|
||||||
|
|
||||||
memcpy(buffer, string, len);
|
memcpy(buffer, string, len);
|
||||||
buffer[len] = 0;
|
buffer[len] = 0;
|
||||||
@ -263,7 +269,7 @@ static void parse_schedule(const char *string, int timeout)
|
|||||||
if (item->type == SC_FOREVER) {
|
if (item->type == SC_FOREVER) {
|
||||||
if (repeatat)
|
if (repeatat)
|
||||||
eerrorx("%s: invalid schedule, `forever' "
|
eerrorx("%s: invalid schedule, `forever' "
|
||||||
"appears more than once", applet);
|
"appears more than once", applet);
|
||||||
|
|
||||||
repeatat = item;
|
repeatat = item;
|
||||||
continue;
|
continue;
|
||||||
@ -281,7 +287,8 @@ static void parse_schedule(const char *string, int timeout)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static pid_t get_pid(const char *pidfile, bool quiet)
|
static pid_t
|
||||||
|
get_pid(const char *pidfile, bool quiet)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
@ -291,7 +298,8 @@ static pid_t get_pid(const char *pidfile, bool quiet)
|
|||||||
|
|
||||||
if ((fp = fopen(pidfile, "r")) == NULL) {
|
if ((fp = fopen(pidfile, "r")) == NULL) {
|
||||||
if (!quiet)
|
if (!quiet)
|
||||||
eerror("%s: fopen `%s': %s", applet, pidfile, strerror(errno));
|
eerror("%s: fopen `%s': %s",
|
||||||
|
applet, pidfile, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,9 +316,10 @@ static pid_t get_pid(const char *pidfile, bool quiet)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* return number of processed killed, -1 on error */
|
/* return number of processed killed, -1 on error */
|
||||||
static int do_stop(const char *exec, const char *const *argv,
|
static int
|
||||||
pid_t pid, uid_t uid,int sig,
|
do_stop(const char *exec, const char *const *argv,
|
||||||
bool quiet, bool verbose, bool test)
|
pid_t pid, uid_t uid,int sig,
|
||||||
|
bool quiet, bool verbose, bool test)
|
||||||
{
|
{
|
||||||
RC_PIDLIST *pids;
|
RC_PIDLIST *pids;
|
||||||
RC_PID *pi;
|
RC_PID *pi;
|
||||||
@ -330,19 +339,19 @@ static int do_stop(const char *exec, const char *const *argv,
|
|||||||
if (test) {
|
if (test) {
|
||||||
if (!quiet)
|
if (!quiet)
|
||||||
einfo("Would send signal %d to PID %d",
|
einfo("Would send signal %d to PID %d",
|
||||||
sig, pi->pid);
|
sig, pi->pid);
|
||||||
nkilled++;
|
nkilled++;
|
||||||
} else {
|
} else {
|
||||||
if (verbose)
|
if (verbose)
|
||||||
ebegin("Sending signal %d to PID %d",
|
ebegin("Sending signal %d to PID %d",
|
||||||
sig, pi->pid);
|
sig, pi->pid);
|
||||||
errno = 0;
|
errno = 0;
|
||||||
killed = (kill(pi->pid, sig) == 0 ||
|
killed = (kill(pi->pid, sig) == 0 ||
|
||||||
errno == ESRCH ? true : false);
|
errno == ESRCH ? true : false);
|
||||||
if (verbose)
|
if (verbose)
|
||||||
eend(killed ? 0 : 1,
|
eend(killed ? 0 : 1,
|
||||||
"%s: failed to send signal %d to PID %d: %s",
|
"%s: failed to send signal %d to PID %d: %s",
|
||||||
applet, sig, pi->pid, strerror(errno));
|
applet, sig, pi->pid, strerror(errno));
|
||||||
if (!killed) {
|
if (!killed) {
|
||||||
nkilled = -1;
|
nkilled = -1;
|
||||||
} else {
|
} else {
|
||||||
@ -357,9 +366,10 @@ static int do_stop(const char *exec, const char *const *argv,
|
|||||||
return nkilled;
|
return nkilled;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int run_stop_schedule(const char *exec, const char *const *argv,
|
static int
|
||||||
const char *pidfile, uid_t uid,
|
run_stop_schedule(const char *exec, const char *const *argv,
|
||||||
bool quiet, bool verbose, bool test)
|
const char *pidfile, uid_t uid,
|
||||||
|
bool quiet, bool verbose, bool test)
|
||||||
{
|
{
|
||||||
SCHEDULEITEM *item = TAILQ_FIRST(&schedule);
|
SCHEDULEITEM *item = TAILQ_FIRST(&schedule);
|
||||||
int nkilled = 0;
|
int nkilled = 0;
|
||||||
@ -403,12 +413,12 @@ static int run_stop_schedule(const char *exec, const char *const *argv,
|
|||||||
case SC_SIGNAL:
|
case SC_SIGNAL:
|
||||||
nrunning = 0;
|
nrunning = 0;
|
||||||
nkilled = do_stop(exec, argv, pid, uid, item->value,
|
nkilled = do_stop(exec, argv, pid, uid, item->value,
|
||||||
quiet, verbose, test);
|
quiet, verbose, test);
|
||||||
if (nkilled == 0) {
|
if (nkilled == 0) {
|
||||||
if (tkilled == 0) {
|
if (tkilled == 0) {
|
||||||
if (! quiet)
|
if (! quiet)
|
||||||
eerror("%s: no matching "
|
eerror("%s: no matching "
|
||||||
"processes found", applet);
|
"processes found", applet);
|
||||||
}
|
}
|
||||||
return tkilled;
|
return tkilled;
|
||||||
}
|
}
|
||||||
@ -429,24 +439,26 @@ static int run_stop_schedule(const char *exec, const char *const *argv,
|
|||||||
|
|
||||||
while (nloops) {
|
while (nloops) {
|
||||||
if ((nrunning = do_stop(exec, argv, pid,
|
if ((nrunning = do_stop(exec, argv, pid,
|
||||||
uid, 0, true, false, true)) == 0)
|
uid, 0, true, false, true)) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (nanosleep(&ts, NULL) == -1) {
|
if (nanosleep(&ts, NULL) == -1) {
|
||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
eerror("%s: caught an interrupt", applet);
|
eerror("%s: caught an"
|
||||||
|
" interrupt", applet);
|
||||||
else {
|
else {
|
||||||
eerror("%s: nanosleep: %s",
|
eerror("%s: nanosleep: %s",
|
||||||
applet, strerror(errno));
|
applet, strerror(errno));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nloops --;
|
nloops --;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
eerror("%s: invalid schedule item `%d'", applet, item->type);
|
eerror("%s: invalid schedule item `%d'",
|
||||||
|
applet, item->type);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -459,15 +471,18 @@ static int run_stop_schedule(const char *exec, const char *const *argv,
|
|||||||
|
|
||||||
if (! quiet) {
|
if (! quiet) {
|
||||||
if (nrunning == 1)
|
if (nrunning == 1)
|
||||||
eerror("%s: %d process refused to stop", applet, nrunning);
|
eerror("%s: %d process refused to stop",
|
||||||
|
applet, nrunning);
|
||||||
else
|
else
|
||||||
eerror("%s: %d process(es) refused to stop", applet, nrunning);
|
eerror("%s: %d process(es) refused to stop",
|
||||||
|
applet, nrunning);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -nrunning;
|
return -nrunning;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_signal(int sig)
|
static void
|
||||||
|
handle_signal(int sig)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
int serrno = errno;
|
int serrno = errno;
|
||||||
@ -492,7 +507,8 @@ static void handle_signal(int sig)
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
if (waitpid(-1, &status, WNOHANG) < 0) {
|
if (waitpid(-1, &status, WNOHANG) < 0) {
|
||||||
if (errno != ECHILD)
|
if (errno != ECHILD)
|
||||||
eerror("%s: waitpid: %s", applet, strerror(errno));
|
eerror("%s: waitpid: %s",
|
||||||
|
applet, strerror(errno));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -606,7 +622,8 @@ static const char * const longopts_help[] = {
|
|||||||
};
|
};
|
||||||
#include "_usage.c"
|
#include "_usage.c"
|
||||||
|
|
||||||
int start_stop_daemon(int argc, char **argv)
|
int
|
||||||
|
start_stop_daemon(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int devnull_fd = -1;
|
int devnull_fd = -1;
|
||||||
#ifdef TIOCNOTTY
|
#ifdef TIOCNOTTY
|
||||||
@ -674,7 +691,7 @@ int start_stop_daemon(int argc, char **argv)
|
|||||||
if ((tmp = getenv("SSD_NICELEVEL")))
|
if ((tmp = getenv("SSD_NICELEVEL")))
|
||||||
if (sscanf(tmp, "%d", &nicelevel) != 1)
|
if (sscanf(tmp, "%d", &nicelevel) != 1)
|
||||||
eerror("%s: invalid nice level `%s' (SSD_NICELEVEL)",
|
eerror("%s: invalid nice level `%s' (SSD_NICELEVEL)",
|
||||||
applet, tmp);
|
applet, tmp);
|
||||||
|
|
||||||
/* Get our user name and initial dir */
|
/* Get our user name and initial dir */
|
||||||
p = getenv("USER");
|
p = getenv("USER");
|
||||||
@ -692,7 +709,7 @@ int start_stop_daemon(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
while ((opt = getopt_long(argc, argv, getoptstring, longopts,
|
while ((opt = getopt_long(argc, argv, getoptstring, longopts,
|
||||||
(int *) 0)) != -1)
|
(int *) 0)) != -1)
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'K': /* --stop */
|
case 'K': /* --stop */
|
||||||
stop = true;
|
stop = true;
|
||||||
@ -700,7 +717,7 @@ int start_stop_daemon(int argc, char **argv)
|
|||||||
case 'N': /* --nice */
|
case 'N': /* --nice */
|
||||||
if (sscanf(optarg, "%d", &nicelevel) != 1)
|
if (sscanf(optarg, "%d", &nicelevel) != 1)
|
||||||
eerrorx("%s: invalid nice level `%s'",
|
eerrorx("%s: invalid nice level `%s'",
|
||||||
applet, optarg);
|
applet, optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'R': /* --retry <schedule>|<timeout> */
|
case 'R': /* --retry <schedule>|<timeout> */
|
||||||
@ -717,44 +734,44 @@ int start_stop_daemon(int argc, char **argv)
|
|||||||
|
|
||||||
case 'u': /* --user <username>|<uid> */
|
case 'u': /* --user <username>|<uid> */
|
||||||
case 'c': /* --chuid <username>|<uid> */
|
case 'c': /* --chuid <username>|<uid> */
|
||||||
{
|
{
|
||||||
p = optarg;
|
p = optarg;
|
||||||
tmp = strsep(&p, ":");
|
tmp = strsep(&p, ":");
|
||||||
changeuser = xstrdup(tmp);
|
changeuser = xstrdup(tmp);
|
||||||
|
if (sscanf(tmp, "%d", &tid) != 1)
|
||||||
|
pw = getpwnam(tmp);
|
||||||
|
else
|
||||||
|
pw = getpwuid((uid_t)tid);
|
||||||
|
|
||||||
|
if (pw == NULL)
|
||||||
|
eerrorx("%s: user `%s' not found",
|
||||||
|
applet, tmp);
|
||||||
|
uid = pw->pw_uid;
|
||||||
|
home = pw->pw_dir;
|
||||||
|
unsetenv("HOME");
|
||||||
|
if (pw->pw_dir)
|
||||||
|
setenv("HOME", pw->pw_dir, 1);
|
||||||
|
unsetenv("USER");
|
||||||
|
if (pw->pw_name)
|
||||||
|
setenv("USER", pw->pw_name, 1);
|
||||||
|
if (gid == 0)
|
||||||
|
gid = pw->pw_gid;
|
||||||
|
|
||||||
|
if (p) {
|
||||||
|
tmp = strsep (&p, ":");
|
||||||
if (sscanf(tmp, "%d", &tid) != 1)
|
if (sscanf(tmp, "%d", &tid) != 1)
|
||||||
pw = getpwnam(tmp);
|
gr = getgrnam(tmp);
|
||||||
else
|
else
|
||||||
pw = getpwuid((uid_t)tid);
|
gr = getgrgid((gid_t) tid);
|
||||||
|
|
||||||
if (pw == NULL)
|
if (gr == NULL)
|
||||||
eerrorx("%s: user `%s' not found",
|
eerrorx("%s: group `%s'"
|
||||||
applet, tmp);
|
" not found",
|
||||||
uid = pw->pw_uid;
|
applet, tmp);
|
||||||
home = pw->pw_dir;
|
gid = gr->gr_gid;
|
||||||
unsetenv("HOME");
|
|
||||||
if (pw->pw_dir)
|
|
||||||
setenv("HOME", pw->pw_dir, 1);
|
|
||||||
unsetenv("USER");
|
|
||||||
if (pw->pw_name)
|
|
||||||
setenv("USER", pw->pw_name, 1);
|
|
||||||
if (gid == 0)
|
|
||||||
gid = pw->pw_gid;
|
|
||||||
|
|
||||||
if (p) {
|
|
||||||
tmp = strsep (&p, ":");
|
|
||||||
if (sscanf(tmp, "%d", &tid) != 1)
|
|
||||||
gr = getgrnam(tmp);
|
|
||||||
else
|
|
||||||
gr = getgrgid((gid_t) tid);
|
|
||||||
|
|
||||||
if (gr == NULL)
|
|
||||||
eerrorx("%s: group `%s'"
|
|
||||||
" not found",
|
|
||||||
applet, tmp);
|
|
||||||
gid = gr->gr_gid;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case 'd': /* --chdir /new/dir */
|
case 'd': /* --chdir /new/dir */
|
||||||
ch_dir = optarg;
|
ch_dir = optarg;
|
||||||
@ -771,7 +788,7 @@ int start_stop_daemon(int argc, char **argv)
|
|||||||
gr = getgrgid((gid_t)tid);
|
gr = getgrgid((gid_t)tid);
|
||||||
if (gr == NULL)
|
if (gr == NULL)
|
||||||
eerrorx("%s: group `%s' not found",
|
eerrorx("%s: group `%s' not found",
|
||||||
applet, optarg);
|
applet, optarg);
|
||||||
gid = gr->gr_gid;
|
gid = gr->gr_gid;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -782,7 +799,7 @@ int start_stop_daemon(int argc, char **argv)
|
|||||||
case 'k':
|
case 'k':
|
||||||
if (parse_mode(&numask, optarg))
|
if (parse_mode(&numask, optarg))
|
||||||
eerrorx("%s: invalid mode `%s'",
|
eerrorx("%s: invalid mode `%s'",
|
||||||
applet, optarg);
|
applet, optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'm': /* --make-pidfile */
|
case 'm': /* --make-pidfile */
|
||||||
@ -819,7 +836,7 @@ int start_stop_daemon(int argc, char **argv)
|
|||||||
case 'w':
|
case 'w':
|
||||||
if (sscanf(optarg, "%d", &start_wait) != 1)
|
if (sscanf(optarg, "%d", &start_wait) != 1)
|
||||||
eerrorx("%s: `%s' not a number",
|
eerrorx("%s: `%s' not a number",
|
||||||
applet, optarg);
|
applet, optarg);
|
||||||
break;
|
break;
|
||||||
case 'x': /* --exec <executable> */
|
case 'x': /* --exec <executable> */
|
||||||
exec = optarg;
|
exec = optarg;
|
||||||
@ -834,7 +851,7 @@ int start_stop_daemon(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case_RC_COMMON_GETOPT
|
case_RC_COMMON_GETOPT
|
||||||
}
|
}
|
||||||
|
|
||||||
endpwent();
|
endpwent();
|
||||||
argc -= optind;
|
argc -= optind;
|
||||||
@ -873,25 +890,25 @@ int start_stop_daemon(int argc, char **argv)
|
|||||||
sig = SIGTERM;
|
sig = SIGTERM;
|
||||||
if (!*argv && !pidfile && !name && !uid)
|
if (!*argv && !pidfile && !name && !uid)
|
||||||
eerrorx("%s: --stop needs --exec, --pidfile,"
|
eerrorx("%s: --stop needs --exec, --pidfile,"
|
||||||
" --name or --user", applet);
|
" --name or --user", applet);
|
||||||
if (background)
|
if (background)
|
||||||
eerrorx("%s: --background is only relevant with"
|
eerrorx("%s: --background is only relevant with"
|
||||||
" --start", applet);
|
" --start", applet);
|
||||||
if (makepidfile)
|
if (makepidfile)
|
||||||
eerrorx("%s: --make-pidfile is only relevant with"
|
eerrorx("%s: --make-pidfile is only relevant with"
|
||||||
" --start", applet);
|
" --start", applet);
|
||||||
if (redirect_stdout || redirect_stderr)
|
if (redirect_stdout || redirect_stderr)
|
||||||
eerrorx("%s: --stdout and --stderr are only relevant"
|
eerrorx("%s: --stdout and --stderr are only relevant"
|
||||||
" with --start", applet);
|
" with --start", applet);
|
||||||
} else {
|
} else {
|
||||||
if (!exec)
|
if (!exec)
|
||||||
eerrorx("%s: nothing to start", applet);
|
eerrorx("%s: nothing to start", applet);
|
||||||
if (makepidfile && !pidfile)
|
if (makepidfile && !pidfile)
|
||||||
eerrorx("%s: --make-pidfile is only relevant with"
|
eerrorx("%s: --make-pidfile is only relevant with"
|
||||||
" --pidfile", applet);
|
" --pidfile", applet);
|
||||||
if ((redirect_stdout || redirect_stderr) && !background)
|
if ((redirect_stdout || redirect_stderr) && !background)
|
||||||
eerrorx("%s: --stdout and --stderr are only relevant"
|
eerrorx("%s: --stdout and --stderr are only relevant"
|
||||||
" with --background", applet);
|
" with --background", applet);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Expand ~ */
|
/* Expand ~ */
|
||||||
@ -908,10 +925,10 @@ int start_stop_daemon(int argc, char **argv)
|
|||||||
/* Full or relative path */
|
/* Full or relative path */
|
||||||
if (ch_root)
|
if (ch_root)
|
||||||
snprintf(exec_file, sizeof(exec_file),
|
snprintf(exec_file, sizeof(exec_file),
|
||||||
"%s/%s", ch_root, exec);
|
"%s/%s", ch_root, exec);
|
||||||
else
|
else
|
||||||
snprintf(exec_file, sizeof(exec_file),
|
snprintf(exec_file, sizeof(exec_file),
|
||||||
"%s", exec);
|
"%s", exec);
|
||||||
} else {
|
} else {
|
||||||
/* Something in $PATH */
|
/* Something in $PATH */
|
||||||
p = tmp = xstrdup(getenv("PATH"));
|
p = tmp = xstrdup(getenv("PATH"));
|
||||||
@ -919,11 +936,11 @@ int start_stop_daemon(int argc, char **argv)
|
|||||||
while ((token = strsep(&p, ":"))) {
|
while ((token = strsep(&p, ":"))) {
|
||||||
if (ch_root)
|
if (ch_root)
|
||||||
snprintf(exec_file, sizeof(exec_file),
|
snprintf(exec_file, sizeof(exec_file),
|
||||||
"%s/%s/%s",
|
"%s/%s/%s",
|
||||||
ch_root, token, exec);
|
ch_root, token, exec);
|
||||||
else
|
else
|
||||||
snprintf(exec_file, sizeof(exec_file),
|
snprintf(exec_file, sizeof(exec_file),
|
||||||
"%s/%s", token, exec);
|
"%s/%s", token, exec);
|
||||||
if (exists(exec_file))
|
if (exists(exec_file))
|
||||||
break;
|
break;
|
||||||
*exec_file = '\0';
|
*exec_file = '\0';
|
||||||
@ -933,7 +950,7 @@ int start_stop_daemon(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
if (start && !exists(exec_file)) {
|
if (start && !exists(exec_file)) {
|
||||||
eerror("%s: %s does not exist", applet,
|
eerror("%s: %s does not exist", applet,
|
||||||
*exec_file ? exec_file : exec);
|
*exec_file ? exec_file : exec);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -984,7 +1001,7 @@ int start_stop_daemon(int argc, char **argv)
|
|||||||
else
|
else
|
||||||
parse_schedule(NULL, sig);
|
parse_schedule(NULL, sig);
|
||||||
i = run_stop_schedule(exec, (const char *const *)margv,
|
i = run_stop_schedule(exec, (const char *const *)margv,
|
||||||
pidfile, uid, quiet, verbose, test);
|
pidfile, uid, quiet, verbose, test);
|
||||||
|
|
||||||
if (i < 0)
|
if (i < 0)
|
||||||
/* We failed to stop something */
|
/* We failed to stop something */
|
||||||
@ -1000,8 +1017,8 @@ int start_stop_daemon(int argc, char **argv)
|
|||||||
unlink(pidfile);
|
unlink(pidfile);
|
||||||
if (svcname)
|
if (svcname)
|
||||||
rc_service_daemon_set(svcname, exec,
|
rc_service_daemon_set(svcname, exec,
|
||||||
(const char *const *)argv,
|
(const char *const *)argv,
|
||||||
pidfile, false);
|
pidfile, false);
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1011,7 +1028,7 @@ int start_stop_daemon(int argc, char **argv)
|
|||||||
pid = 0;
|
pid = 0;
|
||||||
|
|
||||||
if (do_stop(exec, (const char * const *)margv, pid, uid,
|
if (do_stop(exec, (const char * const *)margv, pid, uid,
|
||||||
0, true, false, true) > 0)
|
0, true, false, true) > 0)
|
||||||
eerrorx("%s: %s is already running", applet, exec);
|
eerrorx("%s: %s is already running", applet, exec);
|
||||||
|
|
||||||
if (test) {
|
if (test) {
|
||||||
@ -1067,30 +1084,35 @@ int start_stop_daemon(int argc, char **argv)
|
|||||||
|
|
||||||
if (nicelevel) {
|
if (nicelevel) {
|
||||||
if (setpriority(PRIO_PROCESS, mypid, nicelevel) == -1)
|
if (setpriority(PRIO_PROCESS, mypid, nicelevel) == -1)
|
||||||
eerrorx("%s: setpritory %d: %s", applet, nicelevel,
|
eerrorx("%s: setpritory %d: %s",
|
||||||
strerror(errno));
|
applet, nicelevel,
|
||||||
|
strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ch_root && chroot(ch_root) < 0)
|
if (ch_root && chroot(ch_root) < 0)
|
||||||
eerrorx("%s: chroot `%s': %s", applet, ch_root, strerror(errno));
|
eerrorx("%s: chroot `%s': %s",
|
||||||
|
applet, ch_root, strerror(errno));
|
||||||
|
|
||||||
if (ch_dir && chdir(ch_dir) < 0)
|
if (ch_dir && chdir(ch_dir) < 0)
|
||||||
eerrorx("%s: chdir `%s': %s", applet, ch_dir, strerror(errno));
|
eerrorx("%s: chdir `%s': %s",
|
||||||
|
applet, ch_dir, strerror(errno));
|
||||||
|
|
||||||
if (makepidfile && pidfile) {
|
if (makepidfile && pidfile) {
|
||||||
fp = fopen(pidfile, "w");
|
fp = fopen(pidfile, "w");
|
||||||
if (! fp)
|
if (! fp)
|
||||||
eerrorx("%s: fopen `%s': %s", applet, pidfile,
|
eerrorx("%s: fopen `%s': %s", applet, pidfile,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
fprintf(fp, "%d\n", mypid);
|
fprintf(fp, "%d\n", mypid);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_PAM
|
#ifdef HAVE_PAM
|
||||||
if (changeuser != NULL)
|
if (changeuser != NULL)
|
||||||
pamr = pam_start("start-stop-daemon", changeuser, &conv, &pamh);
|
pamr = pam_start("start-stop-daemon",
|
||||||
|
changeuser, &conv, &pamh);
|
||||||
else
|
else
|
||||||
pamr = pam_start("start-stop-daemon", "nobody", &conv, &pamh);
|
pamr = pam_start("start-stop-daemon",
|
||||||
|
"nobody", &conv, &pamh);
|
||||||
|
|
||||||
if (pamr == PAM_SUCCESS)
|
if (pamr == PAM_SUCCESS)
|
||||||
pamr = pam_authenticate(pamh, PAM_SILENT);
|
pamr = pam_authenticate(pamh, PAM_SILENT);
|
||||||
@ -1099,15 +1121,19 @@ int start_stop_daemon(int argc, char **argv)
|
|||||||
if (pamr == PAM_SUCCESS)
|
if (pamr == PAM_SUCCESS)
|
||||||
pamr = pam_open_session(pamh, PAM_SILENT);
|
pamr = pam_open_session(pamh, PAM_SILENT);
|
||||||
if (pamr != PAM_SUCCESS)
|
if (pamr != PAM_SUCCESS)
|
||||||
eerrorx("%s: pam error: %s", applet, pam_strerror(pamh, pamr));
|
eerrorx("%s: pam error: %s",
|
||||||
|
applet, pam_strerror(pamh, pamr));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (gid && setgid(gid))
|
if (gid && setgid(gid))
|
||||||
eerrorx("%s: unable to set groupid to %d", applet, gid);
|
eerrorx("%s: unable to set groupid to %d",
|
||||||
|
applet, gid);
|
||||||
if (changeuser && initgroups(changeuser, gid))
|
if (changeuser && initgroups(changeuser, gid))
|
||||||
eerrorx("%s: initgroups (%s, %d)", applet, changeuser, gid);
|
eerrorx("%s: initgroups (%s, %d)",
|
||||||
|
applet, changeuser, gid);
|
||||||
if (uid && setuid(uid))
|
if (uid && setuid(uid))
|
||||||
eerrorx ("%s: unable to set userid to %d", applet, uid);
|
eerrorx ("%s: unable to set userid to %d",
|
||||||
|
applet, uid);
|
||||||
|
|
||||||
/* Close any fd's to the passwd database */
|
/* Close any fd's to the passwd database */
|
||||||
endpwent();
|
endpwent();
|
||||||
@ -1137,8 +1163,8 @@ int start_stop_daemon(int argc, char **argv)
|
|||||||
|
|
||||||
TAILQ_FOREACH(env, env_list, entries) {
|
TAILQ_FOREACH(env, env_list, entries) {
|
||||||
if ((strncmp(env->value, "RC_", 3) == 0 &&
|
if ((strncmp(env->value, "RC_", 3) == 0 &&
|
||||||
strncmp(env->value, "RC_SERVICE=", 10) != 0 &&
|
strncmp(env->value, "RC_SERVICE=", 10) != 0 &&
|
||||||
strncmp(env->value, "RC_SVCNAME=", 10) != 0) ||
|
strncmp(env->value, "RC_SVCNAME=", 10) != 0) ||
|
||||||
strncmp(env->value, "SSD_NICELEVEL=", 14) == 0)
|
strncmp(env->value, "SSD_NICELEVEL=", 14) == 0)
|
||||||
{
|
{
|
||||||
p = strchr(env->value, '=');
|
p = strchr(env->value, '=');
|
||||||
@ -1179,16 +1205,20 @@ int start_stop_daemon(int argc, char **argv)
|
|||||||
stdout_fd = devnull_fd;
|
stdout_fd = devnull_fd;
|
||||||
stderr_fd = devnull_fd;
|
stderr_fd = devnull_fd;
|
||||||
if (redirect_stdout) {
|
if (redirect_stdout) {
|
||||||
if ((stdout_fd = open(redirect_stdout, O_WRONLY | O_CREAT | O_APPEND,
|
if ((stdout_fd = open(redirect_stdout,
|
||||||
S_IRUSR | S_IWUSR)) == -1)
|
O_WRONLY | O_CREAT | O_APPEND,
|
||||||
eerrorx("%s: unable to open the logfile for stdout `%s': %s",
|
S_IRUSR | S_IWUSR)) == -1)
|
||||||
applet, redirect_stdout, strerror(errno));
|
eerrorx("%s: unable to open the logfile"
|
||||||
|
" for stdout `%s': %s",
|
||||||
|
applet, redirect_stdout, strerror(errno));
|
||||||
}
|
}
|
||||||
if (redirect_stderr) {
|
if (redirect_stderr) {
|
||||||
if ((stderr_fd = open(redirect_stderr, O_WRONLY | O_CREAT | O_APPEND,
|
if ((stderr_fd = open(redirect_stderr,
|
||||||
S_IRUSR | S_IWUSR)) == -1)
|
O_WRONLY | O_CREAT | O_APPEND,
|
||||||
eerrorx("%s: unable to open the logfile for stderr `%s': %s",
|
S_IRUSR | S_IWUSR)) == -1)
|
||||||
applet, redirect_stderr, strerror(errno));
|
eerrorx("%s: unable to open the logfile"
|
||||||
|
" for stderr `%s': %s",
|
||||||
|
applet, redirect_stderr, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We don't redirect stdin as some daemons may need it */
|
/* We don't redirect stdin as some daemons may need it */
|
||||||
@ -1207,7 +1237,7 @@ int start_stop_daemon(int argc, char **argv)
|
|||||||
pam_close_session(pamh, PAM_SILENT);
|
pam_close_session(pamh, PAM_SILENT);
|
||||||
#endif
|
#endif
|
||||||
eerrorx("%s: failed to exec `%s': %s",
|
eerrorx("%s: failed to exec `%s': %s",
|
||||||
applet, exec,strerror(errno));
|
applet, exec,strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parent process */
|
/* Parent process */
|
||||||
@ -1220,13 +1250,15 @@ int start_stop_daemon(int argc, char **argv)
|
|||||||
do {
|
do {
|
||||||
pid = waitpid(spid, &i, 0);
|
pid = waitpid(spid, &i, 0);
|
||||||
if (pid < 1) {
|
if (pid < 1) {
|
||||||
eerror("waitpid %d: %s", spid, strerror(errno));
|
eerror("waitpid %d: %s",
|
||||||
|
spid, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} while (!WIFEXITED(i) && !WIFSIGNALED(i));
|
} while (!WIFEXITED(i) && !WIFSIGNALED(i));
|
||||||
if (!WIFEXITED(i) || WEXITSTATUS(i) != 0) {
|
if (!WIFEXITED(i) || WEXITSTATUS(i) != 0) {
|
||||||
if (!quiet)
|
if (!quiet)
|
||||||
eerrorx("%s: failed to start `%s'", applet, exec);
|
eerrorx("%s: failed to start `%s'",
|
||||||
|
applet, exec);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
pid = spid;
|
pid = spid;
|
||||||
@ -1236,7 +1268,7 @@ int start_stop_daemon(int argc, char **argv)
|
|||||||
We do this as some badly written daemons fork and then barf */
|
We do this as some badly written daemons fork and then barf */
|
||||||
if (start_wait == 0 &&
|
if (start_wait == 0 &&
|
||||||
((p = getenv("SSD_STARTWAIT")) ||
|
((p = getenv("SSD_STARTWAIT")) ||
|
||||||
(p = rc_conf_value("rc_start_wait"))))
|
(p = rc_conf_value("rc_start_wait"))))
|
||||||
{
|
{
|
||||||
if (sscanf(p, "%u", &start_wait) != 1)
|
if (sscanf(p, "%u", &start_wait) != 1)
|
||||||
start_wait = 0;
|
start_wait = 0;
|
||||||
@ -1253,7 +1285,7 @@ int start_stop_daemon(int argc, char **argv)
|
|||||||
eerror("%s: caught an interrupt", applet);
|
eerror("%s: caught an interrupt", applet);
|
||||||
else {
|
else {
|
||||||
eerror("%s: nanosleep: %s",
|
eerror("%s: nanosleep: %s",
|
||||||
applet, strerror(errno));
|
applet, strerror(errno));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1265,14 +1297,14 @@ int start_stop_daemon(int argc, char **argv)
|
|||||||
pid = get_pid(pidfile, true);
|
pid = get_pid(pidfile, true);
|
||||||
if (pid == -1) {
|
if (pid == -1) {
|
||||||
eerrorx("%s: did not "
|
eerrorx("%s: did not "
|
||||||
"create a valid"
|
"create a valid"
|
||||||
" pid in `%s'",
|
" pid in `%s'",
|
||||||
applet, pidfile);
|
applet, pidfile);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
pid = 0;
|
pid = 0;
|
||||||
if (do_stop(exec, (const char *const *)margv,
|
if (do_stop(exec, (const char *const *)margv,
|
||||||
pid, uid, 0, true, false, true) > 0)
|
pid, uid, 0, true, false, true) > 0)
|
||||||
alive = true;
|
alive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1281,8 +1313,8 @@ int start_stop_daemon(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (svcname)
|
if (svcname)
|
||||||
rc_service_daemon_set(svcname, exec, (const char *const *)margv,
|
rc_service_daemon_set(svcname, exec,
|
||||||
pidfile, true);
|
(const char *const *)margv, pidfile, true);
|
||||||
|
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
|
Loading…
Reference in New Issue
Block a user