diff --git a/.travis.yml b/.travis.yml index fa7638f6..81540442 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,12 +35,12 @@ addons: branch_pattern: dev install: - - wget https://github.com/troglobit/libuev/releases/download/v2.2.0/libuev-2.2.0.tar.xz - - wget https://github.com/troglobit/libite/releases/download/v2.0.1/libite-2.0.1.tar.xz - - tar xf libuev-2.2.0.tar.xz - - tar xf libite-2.0.1.tar.xz - - (cd libuev-2.2.0 && ./configure --prefix=/tmp && make && make install-strip) - - (cd libite-2.0.1 && ./configure --prefix=/tmp && make && make install-strip) + - wget https://github.com/troglobit/libuev/releases/download/v2.3.2/libuev-2.3.2.tar.xz + - wget https://github.com/troglobit/libite/releases/download/v2.3.1/libite-2.3.1.tar.gz + - tar xf libuev-2.3.2.tar.xz + - tar xf libite-2.3.1.tar.gz + - (cd libuev-2.3.2 && ./configure --prefix=/tmp && make && make install-strip) + - (cd libite-2.3.1 && ./configure --prefix=/tmp && make && make install-strip) # Custom build script for the time being, no "make test" yet script: diff --git a/contrib/debian/finit.d/available/acpid.conf b/contrib/debian/finit.d/available/acpid.conf index 8a255dac..b23bf099 100644 --- a/contrib/debian/finit.d/available/acpid.conf +++ b/contrib/debian/finit.d/available/acpid.conf @@ -1,3 +1,3 @@ # Handle PWR button to shutdown/reboot -- useful in Qemu (virt-manager) -# Depends on rsyslogd having started. Redirect any output to log. -service [2345] env:-/etc/default/acpid log acpid -f $OPTIONS -- ACPI daemon +# Depends on a syslog daemon having started. Redirect any output to log. +service [2345] env:-/etc/default/acpid log acpid -f $OPTIONS -- ACPI daemon diff --git a/contrib/debian/finit.d/available/rsyslogd.conf b/contrib/debian/finit.d/available/rsyslogd.conf index 5ca6e9f8..80e72cda 100644 --- a/contrib/debian/finit.d/available/rsyslogd.conf +++ b/contrib/debian/finit.d/available/rsyslogd.conf @@ -1,2 +1,3 @@ # Start rsyslogd as soon as possible, should always run -service [S12345] env:-/etc/default/rsyslog rsyslogd -n $RSYSLOGD_OPTIONS -- Reliable syslog daemon +# Provides pid/syslogd condition +service [S12345] name:syslogd env:-/etc/default/rsyslog rsyslogd -n $RSYSLOGD_OPTIONS -- Reliable syslog daemon diff --git a/doc/build.md b/doc/build.md index d38f8ace..3ca69bc4 100644 --- a/doc/build.md +++ b/doc/build.md @@ -29,8 +29,8 @@ optional plugins to enable. It depends on two external libraries: The configure script checks for all dependencies, including the correct version of the above mentioned libraries. Currently requried versions: -- libite v2.0.1 -- libuEv v2.1.0 +- libite v2.3.1 +- libuEv v2.3.2 Configure diff --git a/src/exec.c b/src/exec.c index 155eaf2d..14558500 100644 --- a/src/exec.c +++ b/src/exec.c @@ -38,6 +38,7 @@ #include "conf.h" #include "helpers.h" #include "sig.h" +#include "util.h" #include "utmp-api.h" #define NUM_ARGS 16 diff --git a/src/helpers.h b/src/helpers.h index 7c734d9f..e4fc1595 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -103,17 +103,6 @@ static inline int create(char *path, mode_t mode, uid_t uid, gid_t gid) return 0; } -/* paste dir/file into buf */ -static inline int paste(char *buf, size_t len, const char *dir, const char *file) -{ - if (!dir) - dir = ""; - if (!file) - file = ""; - - return snprintf(buf, len, "%s%s%s", dir, fisslashdir(dir) ? "" : "/", file); -} - int ismnt (char *file, char *dir, char *mode); int fismnt (char *dir); diff --git a/src/initctl.c b/src/initctl.c index 3efbb3b2..59d86fb5 100644 --- a/src/initctl.c +++ b/src/initctl.c @@ -655,12 +655,14 @@ static int usage(int rc) " help This help text\n" " version Show Finit version\n" "\n" - " ls|list List all .conf in /etc/finit.d/\n" + " ls | list List all .conf in /etc/finit.d/\n" + " create Create .conf in /etc/finit.d/available/\n" " enable Enable .conf in /etc/finit.d/available/\n" " disable Disable .conf in /etc/finit.d/[enabled/]\n" " touch Mark .conf in /etc/finit.d/ for reload\n" " reload Reload *.conf in /etc/finit.d/ (activates changes)\n" -// " reload [:ID] Reload (SIGHUP) service by job# or name\n" +// " reload [:ID] Reload (SIGHUP) service by job# or name\n" + " edit Edit .conf in /etc/finit.d/available/\n" "\n" " cond show Show condition status\n" " cond dump Dump all conditions and their status\n" @@ -710,6 +712,8 @@ int main(int argc, char *argv[]) { "enable", serv_enable }, { "disable", serv_disable }, { "touch", serv_touch }, + { "edit", serv_edit }, + { "create", serv_creat }, { "reload", do_reload }, { "cond", do_cond }, diff --git a/src/pid.h b/src/pid.h index 6bf96ce2..7f0bd0cb 100644 --- a/src/pid.h +++ b/src/pid.h @@ -26,6 +26,7 @@ #define FINIT_PID_H_ #include "svc.h" +#include "util.h" int pid_alive (pid_t pid); char *pid_get_name (pid_t pid, char *name, size_t len); diff --git a/src/serv.c b/src/serv.c index 71874810..a07dd7e2 100644 --- a/src/serv.c +++ b/src/serv.c @@ -27,6 +27,7 @@ #include /* Definition of AT_* constants */ #include #include +#include #include #include "util.h" @@ -199,6 +200,57 @@ int serv_touch(char *arg) return 0; } +static int do_edit(char *arg, int creat) +{ + char *editor[] = { + "sensible-editor", + "editor", + "${VISUAL:-${EDITOR}}", + "mg", + "vi" + }; + char corr[40]; + char path[256]; + + if (!arg || !arg[0]) + return serv_list(NULL); + + if (!strstr(arg, ".conf")) { + snprintf(corr, sizeof(corr), "%s.conf", arg); + arg = corr; + } + + pushd(FINIT_RCSD); + if (mkdir("available", 0755) && EEXIST != errno) + err(1, "Failed creating %s/available directory", FINIT_RCSD); + + snprintf(path, sizeof(path), "%s/%s", available, arg); + if (!fexist(path)) { + if (!creat) + return serv_list(NULL); + + /* XXX: fill with template/commented-out examples */ + } + + for (size_t i = 0; i < NELEMS(editor); i++) { + if (systemf("%s %s 2>/dev/null", editor[i], path)) + continue; + return 0; + } + + return 1; +} + +int serv_edit(char *arg) +{ + return do_edit(arg, 0); +} + +int serv_creat(char *arg) +{ + return do_edit(arg, 1); +} + /** * Local Variables: * indent-tabs-mode: t diff --git a/src/serv.h b/src/serv.h index e52c42c3..be9febd4 100644 --- a/src/serv.h +++ b/src/serv.h @@ -28,6 +28,8 @@ int serv_list (char *arg); int serv_enable (char *arg); int serv_disable (char *arg); int serv_touch (char *arg); +int serv_edit (char *arg); +int serv_creat (char *arg); #endif /* FINIT_SERV_H_ */ diff --git a/src/service.c b/src/service.c index 116f1528..6cefdc7c 100644 --- a/src/service.c +++ b/src/service.c @@ -486,18 +486,37 @@ static int service_start(svc_t *svc) int rc; if ((rc = wordexp(svc->cmd, &we, 0))) { + _e("%s: failed wordexp(%s): %d", svc->cmd, svc->cmd, rc); nomem: - _e("%s: failed wordexp(): %d", svc->cmd, rc); wordfree(&we); _exit(1); } for (i = 0; i < MAX_NUM_SVC_ARGS; i++) { - if (strlen(svc->args[i]) == 0) + char *arg = svc->args[i]; + size_t len = strlen(arg); + char str[len + 2]; + char ch = *arg; + + if (len == 0) break; - if ((rc = wordexp(svc->args[i], &we, WRDE_APPEND))) + /* + * Escape forbidden characters in wordexp() + * but allowed in Finit run/task stanzas, + * + * XXX: escapes only leading characters ... + */ + if (strchr("|<>&:", ch)) + sprintf(str, "\\"); + else + str[0] = 0; + strlcat(str, arg, sizeof(str)); + + if ((rc = wordexp(str, &we, WRDE_APPEND))) { + _e("%s: failed wordexp(%s): %d", svc->cmd, str, rc); goto nomem; + } } if (we.we_wordc > MAX_NUM_SVC_ARGS) { diff --git a/src/util.h b/src/util.h index e65cd8c2..84c32379 100644 --- a/src/util.h +++ b/src/util.h @@ -31,6 +31,7 @@ #include #include #endif +#include #ifndef RB_SW_SUSPEND /* Since Linux 2.5.18, but not in GLIBC until 2.19 */ #define RB_SW_SUSPEND 0xd000fce2 @@ -64,6 +65,17 @@ static inline char *strterm(char *str, size_t len) return str; } +/* paste dir/file into buf */ +static inline int paste(char *buf, size_t len, const char *dir, const char *file) +{ + if (!dir) + dir = ""; + if (!file) + file = ""; + + return snprintf(buf, len, "%s%s%s", dir, fisslashdir(dir) ? "" : "/", file); +} + #endif /* FINIT_UTIL_H_ */ /**