From 720220a3c3c42b92734e2a92f9094348451e187b Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Sat, 21 Apr 2018 22:51:28 +0200 Subject: [PATCH] Add flags to selectively skip fields in service files Signed-off-by: David Oberhollenzer --- cmd/service/dumpscript.c | 2 +- cmd/service/list.c | 2 +- initd/main.c | 2 +- lib/include/service.h | 11 ++++++++-- lib/src/rdsvc.c | 45 ++++++++++++++++++++++++++-------------- lib/src/svcscan.c | 4 ++-- 6 files changed, 43 insertions(+), 23 deletions(-) diff --git a/cmd/service/dumpscript.c b/cmd/service/dumpscript.c index 880631f..eaff509 100644 --- a/cmd/service/dumpscript.c +++ b/cmd/service/dumpscript.c @@ -49,7 +49,7 @@ static service_t *try_load(const char *directory, const char *filename) if (type != S_IFREG && type != S_IFLNK) return NULL; - svc = rdsvc(dirfd, filename); + svc = rdsvc(dirfd, filename, 0); close(dirfd); return svc; } diff --git a/cmd/service/list.c b/cmd/service/list.c index b9e342a..ad4cf00 100644 --- a/cmd/service/list.c +++ b/cmd/service/list.c @@ -63,7 +63,7 @@ static int cmd_list(int argc, char **argv) if (check_arguments(argv[0], argc, 1, 2)) return EXIT_FAILURE; - if (svcscan(SVCDIR, &list)) { + if (svcscan(SVCDIR, &list, 0)) { fprintf(stderr, "Error while reading services from %s\n", SVCDIR); ret = EXIT_FAILURE; diff --git a/initd/main.c b/initd/main.c index 05f9271..a1d6906 100644 --- a/initd/main.c +++ b/initd/main.c @@ -193,7 +193,7 @@ int main(void) return EXIT_FAILURE; } - if (svcscan(SVCDIR, &cfg)) { + if (svcscan(SVCDIR, &cfg, 0)) { fputs("Error reading service list from " SVCDIR "\n" "Trying to continue anyway\n", stderr); } diff --git a/lib/include/service.h b/lib/include/service.h index c68ff90..49c5432 100644 --- a/lib/include/service.h +++ b/lib/include/service.h @@ -44,6 +44,13 @@ enum { TGT_MAX }; +enum { + RDSVC_NO_FNAME = 0x01, /* do not store a copy of the filename */ + RDSVC_NO_EXEC = 0x02, /* do not store executable script */ + RDSVC_NO_CTTY = 0x04, /* do not store the controlling tty */ + RDSVC_NO_DEPS = 0x08, /* do not store dependencies */ +}; + typedef struct exec_t { struct exec_t *next; int argc; /* number of elements in argument vector */ @@ -83,7 +90,7 @@ typedef struct { /* Read a service from a file. */ -service_t *rdsvc(int dirfd, const char *filename); +service_t *rdsvc(int dirfd, const char *filename, int flags); void delsvc(service_t *svc); @@ -94,7 +101,7 @@ void delsvc(service_t *svc); Returns 0 on success, -1 on failure. The function takes care of printing error messages on failure. */ -int svcscan(const char *directory, service_list_t *list); +int svcscan(const char *directory, service_list_t *list, int flags); void del_svc_list(service_list_t *list); diff --git a/lib/src/rdsvc.c b/lib/src/rdsvc.c index ef3465f..546962d 100644 --- a/lib/src/rdsvc.c +++ b/lib/src/rdsvc.c @@ -204,15 +204,17 @@ static const struct svc_param { unsigned int allow_block : 1; + int flags; + int (*handle)(service_t *svc, char *arg, rdline_t *rd); } svc_params[] = { - { "description", 0, svc_desc }, - { "exec", 1, svc_exec }, - { "type", 0, svc_type }, - { "target", 0, svc_target }, - { "tty", 0, svc_tty }, - { "before", 0, svc_before }, - { "after", 0, svc_after }, + { "description", 0, 0, svc_desc }, + { "exec", 1, RDSVC_NO_EXEC, svc_exec }, + { "type", 0, 0, svc_type }, + { "target", 0, 0, svc_target }, + { "tty", 0, RDSVC_NO_CTTY, svc_tty }, + { "before", 0, RDSVC_NO_DEPS, svc_before }, + { "after", 0, RDSVC_NO_DEPS, svc_after }, }; static int splitkv(rdline_t *rd, char **k, char **v) @@ -257,7 +259,7 @@ static const struct svc_param *find_param(rdline_t *rd, const char *name) } -service_t *rdsvc(int dirfd, const char *filename) +service_t *rdsvc(int dirfd, const char *filename, int flags) { const struct svc_param *p; const char *arg, *args[1]; @@ -289,9 +291,11 @@ service_t *rdsvc(int dirfd, const char *filename) if (svc == NULL) goto fail_oom; - svc->fname = strdup(filename); - if (svc->fname == NULL) - goto fail_oom; + if (!(flags & RDSVC_NO_FNAME)) { + svc->fname = strdup(filename); + if (svc->fname == NULL) + goto fail_oom; + } memcpy(svc->name, filename, nlen); @@ -306,13 +310,19 @@ service_t *rdsvc(int dirfd, const char *filename) if (p->allow_block && *value == '{') { for (++value; *value == ' '; ++value) ; - if (*value != '\0' && p->handle(svc, value, &rd)) - goto fail; + + if (!(flags & p->flags)) { + if (*value != '\0' && + p->handle(svc, value, &rd)) { + goto fail; + } + } while ((ret = rdline(&rd)) == 0) { if (strcmp(rd.buffer, "}") == 0) break; - + if (flags & p->flags) + continue; if (p->handle(svc, rd.buffer, &rd)) goto fail; } @@ -321,8 +331,11 @@ service_t *rdsvc(int dirfd, const char *filename) goto fail; if (ret > 0) goto fail_bra; - } else if (p->handle(svc, value, &rd)) { - goto fail; + } else { + if (flags & p->flags) + continue; + if (p->handle(svc, value, &rd)) + goto fail; } } diff --git a/lib/src/svcscan.c b/lib/src/svcscan.c index 32c1dee..f4c7ef1 100644 --- a/lib/src/svcscan.c +++ b/lib/src/svcscan.c @@ -27,7 +27,7 @@ #include "service.h" -int svcscan(const char *directory, service_list_t *list) +int svcscan(const char *directory, service_list_t *list, int flags) { int i, dfd, type, ret = 0; struct dirent *ent; @@ -82,7 +82,7 @@ int svcscan(const char *directory, service_list_t *list) if (type != S_IFREG && type != S_IFLNK) continue; - svc = rdsvc(dfd, ent->d_name); + svc = rdsvc(dfd, ent->d_name, flags); if (svc == NULL) { ret = -1; continue;