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
2021-02-27 19:22:50 +01:00
parent e9ed90cb34
commit 83cdb884d9
+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)
{
char corr[40];
char link[256];
char path[256];
int ena;
if (!arg || !arg[0])
return serv_list(NULL);
if (!arg || !arg[0]) {
warnx("missing argument to enable, may be one of:");
return serv_list("available");
}
if (!strstr(arg, ".conf")) {
snprintf(corr, sizeof(corr), "%s.conf", arg);
arg = corr;
}
pushd(FINIT_RCSD);
if (mkdir("enabled", 0755) && EEXIST != errno)
err(1, "Failed creating %s/enabled directory", FINIT_RCSD);
if (chdir(FINIT_RCSD))
err(1, "failed cd %s", 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))
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(link))
errx(1, "%s already exists", link);
if (fexist(arg))
errx(1, "%s already enabled", arg);
return symlink(path, link) != 0;
return symlink(path, arg) != 0;
}
int serv_disable(char *arg)
{
char corr[40];
char link[256];
struct stat st;
char corr[40];
if (!arg || !arg[0])
return serv_list(NULL);
if (!arg || !arg[0]) {
warnx("missing argument to disable, may be one of:");
return serv_list("enabled");
}
if (!strstr(arg, ".conf")) {
snprintf(corr, sizeof(corr), "%s.conf", arg);
arg = corr;
}
snprintf(link, sizeof(link), "%s/%s", enabled, arg);
if (stat(link, &st))
err(1, "Cannot find %s", link);
if (chdir(FINIT_RCSD))
err(1, "failed cd %s", FINIT_RCSD);
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)
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)