mirror of
https://github.com/troglobit/finit.git
synced 2026-10-02 05:52:48 +07:00
Add support to specify service ID as a string
Signed-off-by: Jonas Johansson <jonasj76@gmail.com>
This commit is contained in:
@@ -93,17 +93,16 @@ static int do_stop (char *buf, size_t len) { return call(stop, buf, len); }
|
||||
static int do_restart(char *buf, size_t len) { return call(restart, buf, len); }
|
||||
|
||||
static char query_buf[368];
|
||||
static int missing(char *job, int id)
|
||||
static int missing(char *job, char *id)
|
||||
{
|
||||
char buf[20];
|
||||
char idstr[13] = "";
|
||||
|
||||
if (!job)
|
||||
job = "";
|
||||
if (id > 1)
|
||||
snprintf(idstr, sizeof(idstr), ":%d", id);
|
||||
if (!id)
|
||||
id = "";
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s%s ", job, idstr);
|
||||
snprintf(buf, sizeof(buf), "%s:%s ", job, id);
|
||||
strlcat(query_buf, buf, sizeof(query_buf));
|
||||
|
||||
return 1;
|
||||
@@ -122,8 +121,9 @@ static int do_query(struct init_request *rq, size_t len)
|
||||
|
||||
static svc_t *do_find(char *buf, size_t len)
|
||||
{
|
||||
int id = 1;
|
||||
char *id = NULL;
|
||||
char *ptr, *input;
|
||||
svc_t *iter = NULL;
|
||||
|
||||
input = sanitize(buf, len);
|
||||
if (!input)
|
||||
@@ -132,11 +132,28 @@ static svc_t *do_find(char *buf, size_t len)
|
||||
ptr = strchr(input, ':');
|
||||
if (ptr) {
|
||||
*ptr++ = 0;
|
||||
id = atonum(ptr);
|
||||
id = ptr;
|
||||
}
|
||||
|
||||
if (isdigit(input[0]))
|
||||
return svc_find_by_jobid(atonum(input), id);
|
||||
if (isdigit(input[0])) {
|
||||
char *ep;
|
||||
long job = 0;
|
||||
|
||||
errno = 0;
|
||||
job = strtol(input, &ep, 10);
|
||||
if ((errno == ERANGE && (job == LONG_MAX || job == LONG_MIN)) ||
|
||||
(errno != 0 && job == 0) ||
|
||||
(input == ep))
|
||||
return NULL;
|
||||
|
||||
if (!id)
|
||||
return svc_job_iterator(&iter, 1, job);
|
||||
|
||||
return svc_find_by_jobid(job, id);
|
||||
}
|
||||
|
||||
if (!id)
|
||||
return svc_named_iterator(&iter, 1, input);
|
||||
|
||||
return svc_find_by_nameid(input, id);
|
||||
}
|
||||
|
||||
+1
-1
@@ -222,7 +222,7 @@ static void finalize(void)
|
||||
/*
|
||||
* Track bundled watchdogd in case a better one turns up
|
||||
*/
|
||||
svc = svc_find(FINIT_LIBPATH_ "/watchdogd", 1);
|
||||
svc = svc_find(FINIT_LIBPATH_ "/watchdogd", "1");
|
||||
if (svc)
|
||||
wdog = svc;
|
||||
|
||||
|
||||
+3
-1
@@ -169,6 +169,7 @@ static void socket_cb(uev_t *w, void *arg, int events)
|
||||
svc_t *svc = (svc_t *)arg, *task;
|
||||
const char *conn = " connection";
|
||||
char iifname[IF_NAMESIZE + 1] = "UNKNOWN";
|
||||
char id[MAX_ID_LEN];
|
||||
int stdin;
|
||||
|
||||
_d("%s: Got socket event ...", svc->cmd);
|
||||
@@ -194,7 +195,8 @@ static void socket_cb(uev_t *w, void *arg, int events)
|
||||
return;
|
||||
}
|
||||
|
||||
task = svc_new(svc->cmd, svc->inetd.next_id++, SVC_TYPE_INETD_CONN);
|
||||
snprintf(id, sizeof(id), "%d", svc->inetd.next_id++);
|
||||
task = svc_new(svc->cmd, id, SVC_TYPE_INETD_CONN);
|
||||
if (!task) {
|
||||
logit(LOG_CRIT, "%s: Unable to allocate service for inetd client", svc->cmd);
|
||||
if (svc->inetd.type == SOCK_STREAM)
|
||||
|
||||
+2
-2
@@ -438,12 +438,12 @@ static int show_status(char *arg)
|
||||
printheader(NULL, "# STATUS PID RUNLEVELS SERVICE DESCRIPTION", 0);
|
||||
|
||||
for (svc = client_svc_iterator(1); svc; svc = client_svc_iterator(0)) {
|
||||
char jobid[10], args[512] = "", *lvls;
|
||||
char jobid[20], args[512] = "", *lvls;
|
||||
|
||||
// if (svc_is_unique(svc))
|
||||
// snprintf(jobid, sizeof(jobid), "%d", svc->job);
|
||||
// else
|
||||
snprintf(jobid, sizeof(jobid), "%d:%d", svc->job, svc->id);
|
||||
snprintf(jobid, sizeof(jobid), "%d:%s", svc->job, svc->id);
|
||||
|
||||
printf("%-9s %7s ", jobid, svc_status(svc));
|
||||
if (svc_is_inetd(svc))
|
||||
|
||||
+14
-7
@@ -672,13 +672,14 @@ static void parse_cmdline_args(svc_t *svc, char *cmd)
|
||||
*/
|
||||
int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
||||
{
|
||||
int id = -1;
|
||||
char id_str[MAX_ID_LEN];
|
||||
#ifdef INETD_ENABLED
|
||||
int forking = 0;
|
||||
#endif
|
||||
int levels = 0;
|
||||
int manual = 0;
|
||||
char *line;
|
||||
char *id = NULL;
|
||||
char *username = NULL, *log = NULL, *pid = NULL;
|
||||
char *service = NULL, *proto = NULL, *ifaces = NULL;
|
||||
char *cmd, *desc, *runlevels = NULL, *cond = NULL;
|
||||
@@ -729,7 +730,7 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
||||
else if (cmd[0] == '<') /* <[!][cond][,cond..]> */
|
||||
cond = &cmd[1];
|
||||
else if (cmd[0] == ':') /* :ID */
|
||||
id = atoi(&cmd[1]);
|
||||
id = &cmd[1];
|
||||
#ifdef INETD_ENABLED
|
||||
else if (!strncasecmp(cmd, "nowait", 6))
|
||||
forking = 1;
|
||||
@@ -801,18 +802,24 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
||||
parse_cmdline_args(svc, cmd);
|
||||
goto inetd_setup;
|
||||
}
|
||||
if (id <= 0)
|
||||
id = svc_next_id(cmd);
|
||||
if (!id) {
|
||||
int n = svc_next_id_int(cmd);
|
||||
|
||||
if (n) {
|
||||
snprintf(id_str, sizeof(id_str), "%d", n);
|
||||
id = id_str;
|
||||
}
|
||||
}
|
||||
}
|
||||
recreate:
|
||||
#endif
|
||||
|
||||
if (id <= 0)
|
||||
id = 1;
|
||||
if (!id)
|
||||
id = "1";
|
||||
|
||||
svc = svc_find(cmd, id);
|
||||
if (!svc) {
|
||||
_d("Creating new svc for %s id #%d type %d", cmd, id, type);
|
||||
_d("Creating new svc for %s id #%s type %d", cmd, id, type);
|
||||
svc = svc_new(cmd, id, type);
|
||||
if (!svc) {
|
||||
_e("Out of memory, cannot register service %s", cmd);
|
||||
|
||||
@@ -77,7 +77,7 @@ static void svc_gc(void *arg)
|
||||
* Returns:
|
||||
* A pointer to a new &svc_t object, or %NULL if out of empty slots.
|
||||
*/
|
||||
svc_t *svc_new(char *cmd, int id, int type)
|
||||
svc_t *svc_new(char *cmd, char *id, int type)
|
||||
{
|
||||
int job = -1;
|
||||
svc_t *svc, *iter = NULL;
|
||||
@@ -98,7 +98,7 @@ svc_t *svc_new(char *cmd, int id, int type)
|
||||
|
||||
svc->type = type;
|
||||
svc->job = job;
|
||||
svc->id = id;
|
||||
strlcpy(svc->id, id, sizeof(svc->id));
|
||||
strlcpy(svc->cmd, cmd, sizeof(svc->cmd));
|
||||
|
||||
/* Default description, if missing */
|
||||
@@ -295,12 +295,12 @@ svc_t *svc_stop_completed(void)
|
||||
* Returns:
|
||||
* A pointer to an &svc_t object, or %NULL if not found.
|
||||
*/
|
||||
svc_t *svc_find(char *cmd, int id)
|
||||
svc_t *svc_find(char *cmd, char *id)
|
||||
{
|
||||
svc_t *svc, *iter = NULL;
|
||||
|
||||
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
|
||||
if (svc->id == id && !strncmp(svc->cmd, cmd, strlen(svc->cmd)))
|
||||
if (svc->id && !strcmp(svc->id, id) && !strncmp(svc->cmd, cmd, strlen(svc->cmd)))
|
||||
return svc;
|
||||
}
|
||||
|
||||
@@ -334,12 +334,12 @@ svc_t *svc_find_by_pid(pid_t pid)
|
||||
* Returns:
|
||||
* A pointer to an &svc_t object, or %NULL if not found.
|
||||
*/
|
||||
svc_t *svc_find_by_jobid(int job, int id)
|
||||
svc_t *svc_find_by_jobid(int job, char *id)
|
||||
{
|
||||
svc_t *svc, *iter = NULL;
|
||||
|
||||
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
|
||||
if (svc->job == job && svc->id == id)
|
||||
if (svc->job == job && svc->id && !strcmp(svc->id, id))
|
||||
return svc;
|
||||
}
|
||||
|
||||
@@ -354,12 +354,12 @@ svc_t *svc_find_by_jobid(int job, int id)
|
||||
* Returns:
|
||||
* A pointer to an &svc_t object, or %NULL if not found.
|
||||
*/
|
||||
svc_t *svc_find_by_nameid(char *name, int id)
|
||||
svc_t *svc_find_by_nameid(char *name, char *id)
|
||||
{
|
||||
svc_t *svc, *iter = NULL;
|
||||
|
||||
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
|
||||
if (svc->id == id && !strcmp(name, svc->name))
|
||||
if (svc->id && !strcmp(svc->id, id) && !strcmp(name, svc->name))
|
||||
return svc;
|
||||
}
|
||||
|
||||
@@ -496,18 +496,24 @@ int svc_enabled(svc_t *svc)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Same base service, return unique ID */
|
||||
int svc_next_id(char *cmd)
|
||||
/* Same base service, return unique ID as an integer */
|
||||
int svc_next_id_int(char *cmd)
|
||||
{
|
||||
int id = 0;
|
||||
int n = 1;
|
||||
svc_t *svc, *iter = NULL;
|
||||
|
||||
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
|
||||
if (!strcmp(svc->cmd, cmd) && id < svc->id)
|
||||
id = svc->id;
|
||||
char id[MAX_ID_LEN];
|
||||
|
||||
snprintf(id, sizeof(id), "%d", n);
|
||||
|
||||
if (!strcmp(svc->cmd, cmd) && svc->id && strcmp(svc->id, id))
|
||||
return n;
|
||||
|
||||
n++;
|
||||
}
|
||||
|
||||
return id + 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int svc_is_unique(svc_t *svc)
|
||||
@@ -534,7 +540,7 @@ int svc_is_unique(svc_t *svc)
|
||||
/*
|
||||
* 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 svc_parse_jobstr(char *str, size_t len, int (*found)(svc_t *), int (not_found)(char *, char *))
|
||||
{
|
||||
int result = 0;
|
||||
char *input, *token, *pos;
|
||||
@@ -545,17 +551,27 @@ int svc_parse_jobstr(char *str, size_t len, int (*found)(svc_t *), int (not_foun
|
||||
|
||||
token = strtok_r(input, " ", &pos);
|
||||
while (token) {
|
||||
int id = 1;
|
||||
char *id = NULL;
|
||||
svc_t *svc, *iter = NULL;
|
||||
char *ptr = strchr(token, ':');
|
||||
|
||||
if (isdigit(token[0])) {
|
||||
int job = atonum(token);
|
||||
char *ep;
|
||||
long job = 0;
|
||||
|
||||
errno = 0;
|
||||
job = strtol(token, &ep, 10);
|
||||
if ((errno == ERANGE && (job == LONG_MAX || job == LONG_MIN)) ||
|
||||
(errno != 0 && job == 0) ||
|
||||
(token == ep)) {
|
||||
result++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ptr) {
|
||||
svc = svc_job_iterator(&iter, 1, job);
|
||||
if (!svc && not_found)
|
||||
result += not_found(NULL, job);
|
||||
result += not_found(NULL, token);
|
||||
|
||||
while (svc) {
|
||||
if (found)
|
||||
@@ -564,8 +580,7 @@ int svc_parse_jobstr(char *str, size_t len, int (*found)(svc_t *), int (not_foun
|
||||
}
|
||||
} else {
|
||||
*ptr++ = 0;
|
||||
id = atonum(ptr);
|
||||
job = atonum(token);
|
||||
id = ptr;
|
||||
|
||||
svc = svc_find_by_jobid(job, id);
|
||||
if (!svc && not_found)
|
||||
@@ -586,7 +601,7 @@ int svc_parse_jobstr(char *str, size_t len, int (*found)(svc_t *), int (not_foun
|
||||
}
|
||||
} else {
|
||||
*ptr++ = 0;
|
||||
id = atonum(ptr);
|
||||
id = ptr;
|
||||
|
||||
svc = svc_find_by_nameid(token, id);
|
||||
if (!svc && not_found)
|
||||
|
||||
@@ -66,6 +66,7 @@ typedef enum {
|
||||
SVC_BLOCK_RESTARTING,
|
||||
} svc_block_t;
|
||||
|
||||
#define MAX_ID_LEN 16
|
||||
#define MAX_ARG_LEN 64
|
||||
#define MAX_STR_LEN 64
|
||||
#define MAX_COND_LEN (MAX_ARG_LEN * 3)
|
||||
@@ -86,7 +87,8 @@ typedef struct svc {
|
||||
TAILQ_ENTRY(svc) link;
|
||||
|
||||
/* Instance specifics */
|
||||
int job, id; /* JOB:ID */
|
||||
int job; /* JOB: */
|
||||
char id[MAX_ID_LEN]; /* :ID */
|
||||
|
||||
/* Limits and scoping */
|
||||
struct rlimit rlimit[RLIMIT_NLIMITS];
|
||||
@@ -145,13 +147,13 @@ typedef struct svc {
|
||||
struct timespec gc;
|
||||
} svc_t;
|
||||
|
||||
svc_t *svc_new (char *cmd, int id, int type);
|
||||
svc_t *svc_new (char *cmd, char *id, int type);
|
||||
int svc_del (svc_t *svc);
|
||||
|
||||
svc_t *svc_find (char *cmd, int id);
|
||||
svc_t *svc_find (char *cmd, char *id);
|
||||
svc_t *svc_find_by_pid (pid_t pid);
|
||||
svc_t *svc_find_by_jobid (int job, int id);
|
||||
svc_t *svc_find_by_nameid (char *name, int id);
|
||||
svc_t *svc_find_by_jobid (int job, char *id);
|
||||
svc_t *svc_find_by_nameid (char *name, char *id);
|
||||
svc_t *svc_find_by_pidfile (char *fn);
|
||||
|
||||
svc_t *svc_iterator (svc_t **iter, int first);
|
||||
@@ -172,10 +174,10 @@ int svc_clean_bootstrap (svc_t *svc);
|
||||
void svc_prune_bootstrap (void);
|
||||
|
||||
int svc_enabled (svc_t *svc);
|
||||
int svc_next_id (char *cmd);
|
||||
int svc_next_id_int (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));
|
||||
int svc_parse_jobstr (char *str, size_t len, int (*found)(svc_t *), int (not_found)(char *, char *));
|
||||
|
||||
static inline int svc_is_inetd (svc_t *svc) { return svc && SVC_TYPE_INETD == svc->type; }
|
||||
static inline int svc_is_inetd_conn(svc_t *svc) { return svc && SVC_TYPE_INETD_CONN == svc->type; }
|
||||
|
||||
Reference in New Issue
Block a user