diff --git a/api.c b/api.c index e46af9d6..853cfe06 100644 --- a/api.c +++ b/api.c @@ -45,50 +45,7 @@ uev_t api_watcher; static int call(int (*action)(svc_t *), char *buf, size_t len) { - int result = 0; - char *input, *token, *pos; - - input = sanitize(buf, len); - if (!input) - return -1; - - token = strtok_r(input, " ", &pos); - while (token) { - svc_t *svc; - char *ptr = strchr(token, ':'); - - if (isdigit(token[0])) { - int job = atonum(token); - - 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 { - if (!ptr) { - svc = svc_named_iterator(1, token); - while (svc) { - result += action(svc); - svc = svc_named_iterator(0, token); - } - } else { - *ptr++ = 0; - result += action(svc_find_by_nameid(token, atonum(ptr))); - } - } - - token = strtok_r(NULL, " ", &pos); - } - - return result; + return svc_parse_jobstr(buf, len, action, NULL); } static int service_block(svc_t *svc) diff --git a/svc.c b/svc.c index 5400a87c..7a3001b7 100644 --- a/svc.c +++ b/svc.c @@ -22,6 +22,7 @@ * THE SOFTWARE. */ +#include /* isdigit() */ #include #include #include @@ -29,6 +30,7 @@ #include "finit.h" #include "svc.h" #include "helpers.h" +#include "util.h" /* Each svc_t needs a unique job# */ static int jobcounter = 1; @@ -565,6 +567,76 @@ int svc_is_unique(svc_t *svc) return unique; } +/* + * Used by api.c (to start/stop/restart) and initctl.c (for input validation) + */ +int svc_parse_jobstr(char *str, size_t len, int (*found)(svc_t *), int (not_found)(char *, int)) +{ + int result = 0; + char *input, *token, *pos; + + input = sanitize(str, len); + if (!input) + return -1; + + token = strtok_r(input, " ", &pos); + while (token) { + int id = 1; + svc_t *svc; + char *ptr = strchr(token, ':'); + + if (isdigit(token[0])) { + int job = atonum(token); + + if (!ptr) { + svc = svc_job_iterator(1, job); + if (!svc && not_found) + result += not_found(NULL, job); + + while (svc) { + if (found) + result += found(svc); + svc = svc_job_iterator(0, job); + } + } else { + *ptr++ = 0; + id = atonum(ptr); + job = atonum(token); + + svc = svc_find_by_jobid(job, id); + if (!svc && not_found) + result += not_found(token, id); + else if (found) + result += found(svc); + } + } else { + if (!ptr) { + svc = svc_named_iterator(1, token); + if (!svc && not_found) + result += not_found(token, id); + + while (svc) { + if (found) + result += found(svc); + svc = svc_named_iterator(0, token); + } + } else { + *ptr++ = 0; + id = atonum(ptr); + + svc = svc_find_by_nameid(token, id); + if (!svc && not_found) + result += not_found(token, id); + else if (found) + result += found(svc); + } + } + + token = strtok_r(NULL, " ", &pos); + } + + return result; +} /** * Local Variables: diff --git a/svc.h b/svc.h index 51d1bf65..a2e434bb 100644 --- a/svc.h +++ b/svc.h @@ -171,6 +171,8 @@ const char *svc_dirtystr (svc_t *svc); int svc_next_id (char *cmd); int svc_is_unique (svc_t *svc); +int svc_parse_jobstr (char *str, size_t len, int (*found)(svc_t *), int (not_found)(char *, int)); + static inline int svc_in_runlevel (svc_t *svc, int runlevel) { return svc && ISSET(svc->runlevels, runlevel); } static inline int svc_has_sighup (svc_t *svc) { return svc && 0 != svc->sighup; }