troglobit / finit

Fast init for Linux. Cookies included
https://troglobit.com/projects/finit/
MIT License
632 stars 63 forks source link

Don't use relative paths in serv_enable() #339

Closed JackNewman12 closed 1 year ago

JackNewman12 commented 1 year ago

This is a minor point and might not even be worth fixing but I noticed that enabling a service does not work if the available and enabled folders are not next to each other.

For example you could have a read-only list of services in the system, and then link them into a tmpfs to enable them as required by configuration options:

/etc/finit.d/available/ (read-only system)
/etc/finit.d/enabled/  -symlinks->  /var/run/enabled_services

When serv_enable ends up trying to link to the available service via ../available which can't be found since /var/run/available does not exist.

I did a quick hack to get this working on my end. But I think I have broken the System *may* have enabled/ dir edge-case.

diff --git a/src/serv.c b/src/serv.c
index 1cb88f38e..86513572f 100644
--- a/src/serv.c
+++ b/src/serv.c
@@ -229,7 +229,7 @@ int serv_enable(char *arg)
 {
    char corr[40];
    char path[256];
-   int ena;
+   char argpath[256];

    if (!arg || !arg[0]) {
        WARNX("missing argument to enable, may be one of:");
@@ -246,16 +246,16 @@ int serv_enable(char *arg)

    if (icreate && mkdir("enabled", 0755) && EEXIST != errno)
        ERR(73, "failed creating %s/enabled directory", finit_rcsd);
-   ena = !chdir("enabled");   /* System *may* have enabled/ dir. */

-   snprintf(path, sizeof(path), "%savailable/%s", ena ? "../" : "", arg);
+   snprintf(path, sizeof(path), "%s/available/%s", finit_rcsd, arg);
    if (!fexist(path))
        ERRX(72, "cannot find %s", conf(path, sizeof(path), arg, 0));

    if (fexist(arg))
        ERRX(1, "%s already enabled", arg);

-   return symlink(path, arg) != 0;
+   snprintf(argpath, sizeof(argpath), "%s/enabled/%s", finit_rcsd, arg);
+   return symlink(path, argpath) != 0;
 }

 int do_disable(char *arg, int check)
troglobit commented 1 year ago

Yeah I've been a bit too liberal with what's optional in /etc/finit.d, resulting in a lot of "System may have ...". I think it's time to nail down the Apache-style layout.

I like your idea here, since it solves another use-case, so I'll look into adopting it for the 4.4. release (which admittedly is very late already), but I'll have to clean up some of the other logic in initctl as well.