diff options
author | Sergey Poznyakoff <gray@nxc.no> | 2017-08-14 16:50:19 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@nxc.no> | 2017-08-14 17:17:39 +0300 |
commit | c5ec9d5c9139eae5f1db11caf3ad5065f6665996 (patch) | |
tree | 846dfbe79865fd0e06e79e15e3493b27efa8a201 | |
parent | d5757191d8b6102b522709ad042188f8ba318ba5 (diff) | |
download | nssync-c5ec9d5c9139eae5f1db11caf3ad5065f6665996.tar.gz nssync-c5ec9d5c9139eae5f1db11caf3ad5065f6665996.tar.bz2 |
Use runcap to run the external reload command
-rw-r--r-- | src/nssync.c | 87 |
1 files changed, 77 insertions, 10 deletions
diff --git a/src/nssync.c b/src/nssync.c index a0084b8..5dea11c 100644 --- a/src/nssync.c +++ b/src/nssync.c @@ -17,6 +17,7 @@ #include "nssync.h" #include <sys/stat.h> #include <fcntl.h> +#include "runcap.h" int lint_mode; int dry_run_mode; @@ -449,6 +450,79 @@ check_pidfile() atexit(remove_pidfile); } +struct linemon_closure +{ + char const *prefix; +}; + +static void +linemon(const char *ptr, size_t len, void *data) +{ + struct linemon_closure *clos = data; + if (ptr[len-1] != '\n') + error("[%s]: %*.*s\\", + clos->prefix, (int)len, (int)len, ptr); + else + error("[%s]: %*.*s", + clos->prefix, (int)(len - 1), (int)(len - 1), ptr); +} + +int +dns_reload(void) +{ + int c; + struct runcap rc; + char *argv[4]; + struct linemon_closure closure[2]; + + debug(1,("about to run %s", reload_command)); + if (dry_run_mode) + return 0; + + argv[0] = "/bin/sh"; + argv[1] = "-c"; + argv[2] = reload_command; + argv[3] = NULL; + + closure[0].prefix = "STDOUT"; + rc.rc_cap[RUNCAP_STDOUT].sc_linemon = linemon; + rc.rc_cap[RUNCAP_STDOUT].sc_monarg = &closure[0]; + closure[1].prefix = "STDERR"; + rc.rc_cap[RUNCAP_STDERR].sc_linemon = linemon; + rc.rc_cap[RUNCAP_STDERR].sc_monarg = &closure[1]; + + rc.rc_timeout = 10; /* FIXME */ + rc.rc_argv = argv; + + c = runcap(&rc, + RCF_STDOUT_LINEMON | RCF_STDERR_LINEMON | RCF_TIMEOUT); + + if (c) { + error("can't run \"%s\": %s", reload_command, strerror(errno)); + } else if (WIFEXITED(rc.rc_status)) { + int status = WEXITSTATUS(rc.rc_status); + if (status) { + error("command \"%s\" returned %d", + reload_command, status); + c = 1; + } + } else if (WIFSIGNALED(rc.rc_status)) { + error("command \"%s\" terminated on signal %d", + reload_command, WTERMSIG(rc.rc_status)); + c = 1; + } else if (WIFSTOPPED(rc.rc_status)) { + error("command \"%s\" got stopped", reload_command); + c = 1; + } else { + error("command \"%s\" terminated with unrecognized status %d", + reload_command, rc.rc_status); + c = 1; + } + runcap_free(&rc); + return c; +} + + int nssync() { @@ -476,16 +550,9 @@ nssync() if (error_count) return -1; - if (changed_zones) { - debug(1,("about to run %s", reload_command)); - if (!dry_run_mode) { - int rc = system(reload_command); - if (rc) { - debug(1,("reload command returned %d", rc)); - exit(EX_UNAVAILABLE); - } - } - } + if (changed_zones) + //FIXME: set error if it returns !0 + dns_reload(); } int |