From 6302579f2242830d2ab88930194d978707c174a9 Mon Sep 17 00:00:00 2001 From: "C. McEnroe" Date: Sun, 16 Aug 2020 23:01:25 -0400 Subject: [PATCH] Add drop command --- catsit.8 | 8 ++++++-- catsit.sh | 2 +- daemon.c | 11 ++++++++--- daemon.h | 1 + service.c | 8 ++++++++ 5 files changed, 24 insertions(+), 6 deletions(-) diff --git a/catsit.8 b/catsit.8 index d901359..ae4de38 100644 --- a/catsit.8 +++ b/catsit.8 @@ -1,4 +1,4 @@ -.Dd August 15, 2020 +.Dd August 16, 2020 .Dt CATSIT 8 .Os . @@ -9,7 +9,7 @@ .Sh SYNOPSIS .Nm .Op Fl c Ar control -.Cm start|stop|restart|status Ns | Ns Ar signal +.Cm start|stop|restart|status|drop Ns | Ns Ar signal .Ar service ... . .Sh DESCRIPTION @@ -55,6 +55,10 @@ then stopped services will be started. .It Cm status Log the current status of any matching services. . +.It Cm drop +Drop any matching stopped services +from the services list. +. .It Ar signal Send the named signal to the processes of any matching started services. diff --git a/catsit.sh b/catsit.sh index 0e2a7e1..6433109 100644 --- a/catsit.sh +++ b/catsit.sh @@ -27,7 +27,7 @@ fi [ $# -lt 2 ] && die 'service name required' action=$(echo "${1}" | tr 'A-Z' 'a-z') -for valid in start stop restart status $(kill -l | tr 'A-Z' 'a-z'); do +for valid in start stop restart status drop $(kill -l | tr 'A-Z' 'a-z'); do [ "${action}" = "${valid}" ] && break done if [ "${action}" != "${valid}" ]; then diff --git a/daemon.c b/daemon.c index 0e15c12..969675f 100644 --- a/daemon.c +++ b/daemon.c @@ -126,6 +126,7 @@ static void parseControl(char *command) { return; } + bool drop = false; Action *fn = NULL; int signal = 0; if (!strcmp(action, "start")) { @@ -136,6 +137,8 @@ static void parseControl(char *command) { fn = serviceRestart; } else if (!strcmp(action, "status")) { fn = serviceStatus; + } else if (!strcmp(action, "drop")) { + drop = true; } else { for (int i = 1; i < NSIG; ++i) { if (strcasecmp(action, sys_signame[i])) continue; @@ -143,7 +146,7 @@ static void parseControl(char *command) { break; } } - if (!fn && !signal) { + if (!drop && !fn && !signal) { syslog(LOG_NOTICE, "unknown action or signal %s", action); return; } @@ -151,10 +154,12 @@ static void parseControl(char *command) { while (command) { bool found = false; char *pattern = strsep(&command, WS); - for (size_t i = 0; i < services.len; ++i) { + for (size_t i = services.len - 1; i < services.len; --i) { struct Service *service = &services.ptr[i]; if (fnmatch(pattern, service->name, 0)) continue; - if (signal) { + if (drop) { + serviceDrop(i); + } else if (signal) { serviceSignal(service, signal); } else { fn(service); diff --git a/daemon.h b/daemon.h index 0398db9..b397f8e 100644 --- a/daemon.h +++ b/daemon.h @@ -130,6 +130,7 @@ extern struct Services { } services; int serviceAdd(const char *name, const char *command); +void serviceDrop(size_t index); void serviceStatus(struct Service *service); void serviceStart(struct Service *service); void serviceStop(struct Service *service); diff --git a/service.c b/service.c index 78890b8..9a3b157 100644 --- a/service.c +++ b/service.c @@ -119,6 +119,14 @@ err: return -1; } +void serviceDrop(size_t index) { + struct Service *service = &services.ptr[index]; + if (service->state != Stop) return; + syslog(LOG_NOTICE, "%s[] dropped", service->name); + serviceFree(service); + services.ptr[index] = services.ptr[--services.len]; +} + void serviceStatus(struct Service *service) { if (service->state == Stop && service->intent == Stop) { syslog(LOG_NOTICE, "%s[] is stopped", service->name);