mirror of
https://github.com/troglobit/finit.git
synced 2026-10-02 14:02:52 +07:00
Followup to 'initctl with process name as well as JOBID'
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
@@ -41,12 +41,18 @@
|
||||
|
||||
uev_t api_watcher;
|
||||
|
||||
/* Allowed characters in job/id/name */
|
||||
static int isallowed(int ch)
|
||||
{
|
||||
return isalnum(ch) || isspace(ch) || ch == ':';
|
||||
}
|
||||
|
||||
/* Sanitize user input, make sure to NUL terminate. */
|
||||
static char *sanitize(char *arg, size_t len)
|
||||
{
|
||||
size_t i = 0;
|
||||
|
||||
while ((isalnum(arg[i]) || isspace(arg[i])) && i < len)
|
||||
while (isallowed(arg[i]) && i < len)
|
||||
i++;
|
||||
|
||||
if (i + 1 < len) {
|
||||
@@ -57,79 +63,65 @@ static char *sanitize(char *arg, size_t len)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static svc_t *convert(int noid, char *arg, size_t len)
|
||||
{
|
||||
int job, id = 1;
|
||||
char *token, *ptr;
|
||||
|
||||
arg = sanitize(arg, len);
|
||||
if (!arg)
|
||||
return NULL;
|
||||
|
||||
if (noid && (ptr = strchr(arg, ':')))
|
||||
ptr = 0;
|
||||
|
||||
token = strtok(arg, ":");
|
||||
if (!token) {
|
||||
job = atoi(arg);
|
||||
} else {
|
||||
job = atoi(token);
|
||||
token = strtok(NULL, "");
|
||||
if (token)
|
||||
id = atoi(token);
|
||||
}
|
||||
|
||||
_d("Got job %d id %d ...", job, id);
|
||||
return svc_find_by_jobid(job, id);
|
||||
}
|
||||
|
||||
static int call(int (*action)(svc_t *), char *buf, size_t len)
|
||||
{
|
||||
int result = 0;
|
||||
char *job = strtok(sanitize(buf, len), " ");
|
||||
char *input, *token, *pos;
|
||||
|
||||
while (job) {
|
||||
input = sanitize(buf, len);
|
||||
if (!input)
|
||||
return -1;
|
||||
|
||||
token = strtok_r(input, " ", &pos);
|
||||
while (token) {
|
||||
svc_t *svc;
|
||||
|
||||
if (isdigit(job[0]))
|
||||
result += action(convert(0, job, len));
|
||||
else
|
||||
for (svc = svc_named_iterator(1, job); svc; svc = svc_named_iterator(0, job))
|
||||
result += action(svc);
|
||||
if (isdigit(token[0])) {
|
||||
int job = atonum(token);
|
||||
char *ptr = strchr(token, ':');
|
||||
|
||||
job = strtok(NULL, " ");
|
||||
if (!ptr) {
|
||||
svc = svc_job_iterator(1, job);
|
||||
while (svc) {
|
||||
result += action(svc);
|
||||
svc = svc_job_iterator(0, job);
|
||||
}
|
||||
} else {
|
||||
*ptr++ = 0;
|
||||
job = atonum(token);
|
||||
result += action(svc_find_by_jobid(job, atonum(ptr)));
|
||||
}
|
||||
|
||||
} else {
|
||||
svc = svc_named_iterator(1, token);
|
||||
while (svc) {
|
||||
result += action(svc);
|
||||
svc = svc_named_iterator(0, token);
|
||||
}
|
||||
}
|
||||
|
||||
token = strtok_r(NULL, " ", &pos);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int do_start(char *buf, size_t len)
|
||||
{
|
||||
return call(service_start, buf, len);
|
||||
}
|
||||
|
||||
static int do_stop(char *buf, size_t len)
|
||||
{
|
||||
return call(service_stop, buf, len);
|
||||
}
|
||||
|
||||
static int do_reload(char *buf, size_t len)
|
||||
{
|
||||
return call(service_reload, buf, len);
|
||||
}
|
||||
|
||||
static int do_restart(char *buf, size_t len)
|
||||
{
|
||||
return call(service_restart, buf, len);
|
||||
}
|
||||
static int do_start (char *buf, size_t len) { return call(service_start, buf, len); }
|
||||
static int do_stop (char *buf, size_t len) { return call(service_stop, buf, len); }
|
||||
static int do_reload (char *buf, size_t len) { return call(service_reload, buf, len); }
|
||||
static int do_restart(char *buf, size_t len) { return call(service_restart, buf, len); }
|
||||
|
||||
static int do_query_inetd(char *buf, size_t len)
|
||||
{
|
||||
char *input = sanitize(buf, len);
|
||||
svc_t *svc;
|
||||
|
||||
svc = convert(1, buf, len);
|
||||
if (!input)
|
||||
return -1;
|
||||
|
||||
svc = svc_find_by_jobid(atonum(input), 1);
|
||||
if (!svc || !svc_is_inetd(svc)) {
|
||||
_e("Cannot %s svc %s ...", !svc ? "find" : "query, not an inetd", buf);
|
||||
_e("Cannot %s svc %s ...", !svc ? "find" : "query, not an inetd", input);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -151,7 +143,6 @@ static void cb(uev_t *w, void *UNUSED(arg), int UNUSED(events))
|
||||
int result = 0;
|
||||
ssize_t len;
|
||||
|
||||
memset(&rq, 0, sizeof(rq));
|
||||
len = read(sd, &rq, sizeof(rq));
|
||||
if (len <= 0) {
|
||||
if (-1 == len) {
|
||||
|
||||
@@ -115,6 +115,9 @@ int atonum(char *str)
|
||||
int val;
|
||||
char *end;
|
||||
|
||||
if (!str)
|
||||
return -1;
|
||||
|
||||
errno = 0;
|
||||
val = strtol(str, &end, 10);
|
||||
if (errno || end == str)
|
||||
|
||||
@@ -195,6 +195,29 @@ svc_t *svc_named_iterator(int first, char *cmd)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* svc_job_iterator - Iterates over all instances of a service.
|
||||
* @first: Get first &svc_t object, or next until end.
|
||||
* @job: Job to look for.
|
||||
*
|
||||
* Returns:
|
||||
* The first matching &svc_t when @first is set, otherwise the next
|
||||
* &svc_t instance with the same @job until the end when %NULL is
|
||||
* returned.
|
||||
*/
|
||||
svc_t *svc_job_iterator(int first, int job)
|
||||
{
|
||||
svc_t *svc;
|
||||
|
||||
for (svc = svc_iterator(first); svc; svc = svc_iterator(0)) {
|
||||
if (svc->job == job)
|
||||
return svc;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* svc_foreach - Run a callback for each registered service
|
||||
* @cb: Callback to run for each service
|
||||
|
||||
@@ -122,6 +122,7 @@ svc_t *svc_iterator (int first);
|
||||
svc_t *svc_inetd_iterator (int first);
|
||||
svc_t *svc_dynamic_iterator (int first);
|
||||
svc_t *svc_named_iterator (int first, char *cmd);
|
||||
svc_t *svc_job_iterator (int first, int job);
|
||||
|
||||
void svc_foreach (void (*cb)(svc_t *));
|
||||
void svc_foreach_dynamic (void (*cb)(svc_t *));
|
||||
|
||||
Reference in New Issue
Block a user