diff --git a/man/runscript.8 b/man/runscript.8 index 64da26c7..2889970e 100644 --- a/man/runscript.8 +++ b/man/runscript.8 @@ -465,6 +465,12 @@ show() .Ed .Sh BUGS +Because of the way we load our configuration files and the need to handle +more than one service directory, you can only use symlinks in service +directories to other services in the same directory. +You cannot symlink to a service in a different directory even if it is +another service directory. +.Pp is_older_than should return 0 on success. Instead we return 1 to be compliant with Gentoo baselayout. Users are encouraged to use the is_newer_than function which returns correctly. diff --git a/sh/runscript.sh.in b/sh/runscript.sh.in index 4032cb84..07f96d84 100644 --- a/sh/runscript.sh.in +++ b/sh/runscript.sh.in @@ -16,23 +16,6 @@ sourcex() fi } -loadconfig() -{ - # If we're net.eth0 or openvpn.work then load net or openvpn config - _c=${RC_SVCNAME%%.*} - if [ -n "$_c" -a "$_c" != "$RC_SVCNAME" ]; then - if ! sourcex -e "$1/$_c.$RC_RUNLEVEL"; then - sourcex -e "$1/$_c" - fi - fi - unset _c - - # Overlay with our specific config - if ! sourcex -e "$1/$RC_SVCNAME.$RC_RUNLEVEL"; then - sourcex -e "$1/$RC_SVCNAME" - fi -} - sourcex "@SYSCONFDIR@/init.d/functions.sh" sourcex "@LIBEXECDIR@/sh/rc-functions.sh" @@ -195,9 +178,21 @@ status() yesno $RC_DEBUG && set -x -if ! loadconfig "${RC_SERVICE%/*}/../conf.d"; then - loadconfig "@SYSCONFDIR@/conf.d" +_conf_d=${RC_SERVICE%/*}/../conf.d +# If we're net.eth0 or openvpn.work then load net or openvpn config +_c=${RC_SVCNAME%%.*} +if [ -n "$_c" -a "$_c" != "$RC_SVCNAME" ]; then + if ! sourcex -e "$_conf_d/$_c.$RC_RUNLEVEL"; then + sourcex -e "$_conf_d/$_c" + fi fi +unset _c + +# Overlay with our specific config +if ! sourcex -e "$_conf_d/$RC_SVCNAME.$RC_RUNLEVEL"; then + sourcex -e "$_conf_d/$RC_SVCNAME" +fi +unset _conf_d # Load any system overrides sourcex -e "@SYSCONFDIR@/rc.conf" diff --git a/src/rc/runscript.c b/src/rc/runscript.c index 33065004..b460cc3c 100644 --- a/src/rc/runscript.c +++ b/src/rc/runscript.c @@ -1100,7 +1100,8 @@ runscript(int argc, char **argv) bool doneone = false; int retval, opt, depoptions = RC_DEP_TRACE; RC_STRING *svc; - char *save = NULL; + char path[PATH_MAX], lnk[PATH_MAX]; + char *dir, *save = NULL, *saveLnk = NULL; char pidstr[10]; size_t l = 0, ll; struct stat stbuf; @@ -1119,7 +1120,40 @@ runscript(int argc, char **argv) atexit(cleanup); - service = xstrdup(argv[1]); + /* We need to work out the real full path to our service. + * This works fine, provided that we ONLY allow multiplexed services + * to exist in the same directory as the master link. + * Also, the master link as to be a real file in the init dir. */ + if (!realpath(argv[1], path)) { + fprintf(stderr, "realpath: %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } + memset(lnk, 0, sizeof(lnk)); + if (readlink(argv[1], lnk, sizeof(lnk)-1)) { + dir = dirname(path); + if (strchr(lnk, '/')) { + save = xstrdup(dir); + saveLnk = xstrdup(lnk); + dir = dirname(saveLnk); + if (strcmp(dir, save) == 0) + file = basename_c(argv[1]); + else + file = basename_c(lnk); + dir = save; + } else + file = basename_c(argv[1]); + ll = strlen(dir) + strlen(file) + 2; + service = xmalloc(ll); + snprintf(service, ll, "%s/%s", dir, file); + if (stat(service, &stbuf) != 0) { + free(service); + service = xstrdup(lnk); + } + free(save); + free(saveLnk); + } + if (!service) + service = xstrdup(path); applet = basename_c(service); if (argc < 3)