initctl: extend semantics for enable/disable cmd

A system may, or may not, have the available/ and enabled/
subdirectories in /etc/finit.d.  This is up to distros but
we support the following, example uses /etc/finit.d as the
FINIT_RCSD base directory:

 1. No subdirectories
    - enable: nop
    - disable: nop
 2. Only available/
    - enable: checks if there's a service in available/
      then symlinks to /etc/finit.d/
    - disable: checks if service in /etc/finit.d is a
      symlink, then removes it
 3. Both available/ and enabled/
    - enable: relative symlink in enabled/ is created if
      service is available in available/
    - disable: symlink in enabled/ is removed if exists

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg committed 2021-02-27 19:22:50 +01:00
1 parent e9ed90cb34
commit 83cdb884d9
1 file changed
+29 -21
+29 -21
View File
@@ -161,54 +161,62 @@ static char *conf(char *path, size_t len, char *name, int creat)
int serv_enable(char *arg) int serv_enable(char *arg)
{ {
char corr[40]; char corr[40];
char link[256];
char path[256]; char path[256];
int ena;
if (!arg || !arg[0]) if (!arg || !arg[0]) {
return serv_list(NULL); warnx("missing argument to enable, may be one of:");
return serv_list("available");
}
if (!strstr(arg, ".conf")) { if (!strstr(arg, ".conf")) {
snprintf(corr, sizeof(corr), "%s.conf", arg); snprintf(corr, sizeof(corr), "%s.conf", arg);
arg = corr; arg = corr;
} }
pushd(FINIT_RCSD); if (chdir(FINIT_RCSD))
if (mkdir("enabled", 0755) && EEXIST != errno) err(1, "failed cd %s", FINIT_RCSD);
err(1, "Failed creating %s/enabled directory", FINIT_RCSD);
snprintf(path, sizeof(path), "%s/%s", available, arg); if (icreate && mkdir("enabled", 0755) && EEXIST != errno)
err(1, "failed creating %s/enabled directory", FINIT_RCSD);
ena = !chdir("enabled"); /* System *may* have enabled/ dir. */
snprintf(path, sizeof(path), "%savailable/%s", ena ? "../" : "", arg);
if (!fexist(path)) if (!fexist(path))
errx(1, "Cannot find %s", path); errx(1, "cannot find %s", conf(path, sizeof(path), arg, 0));
snprintf(link, sizeof(link), "%s/%s", enabled, arg); if (fexist(arg))
if (fexist(link)) errx(1, "%s already enabled", arg);
errx(1, "%s already exists", link);
return symlink(path, link) != 0; return symlink(path, arg) != 0;
} }
int serv_disable(char *arg) int serv_disable(char *arg)
{ {
char corr[40];
char link[256];
struct stat st; struct stat st;
char corr[40];
if (!arg || !arg[0]) if (!arg || !arg[0]) {
return serv_list(NULL); warnx("missing argument to disable, may be one of:");
return serv_list("enabled");
}
if (!strstr(arg, ".conf")) { if (!strstr(arg, ".conf")) {
snprintf(corr, sizeof(corr), "%s.conf", arg); snprintf(corr, sizeof(corr), "%s.conf", arg);
arg = corr; arg = corr;
} }
snprintf(link, sizeof(link), "%s/%s", enabled, arg); if (chdir(FINIT_RCSD))
if (stat(link, &st)) err(1, "failed cd %s", FINIT_RCSD);
err(1, "Cannot find %s", link); chdir("enabled"); /* System *may* have enabled/ dir. */
if (stat(arg, &st))
errx(1, "%s not (an) enabled (service).", arg);
if ((st.st_mode & S_IFMT) == S_IFLNK) if ((st.st_mode & S_IFMT) == S_IFLNK)
errx(1, "%s is not a symlink, move manually to %s first", link, available); errx(1, "cannot disable %s, not a symlink.", arg);
return remove(link) != 0; return remove(arg) != 0;
} }
int serv_touch(char *arg) int serv_touch(char *arg)