summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2008-04-29 10:25:45 +0000
committerRoy Marples <roy@marples.name>2008-04-29 10:25:45 +0000
commit5ba6f0a62817f6031936b8880a15c404840924bb (patch)
treeed204dc8379bc6088f743f480c14bf416fc0ded6
parent5a59542629084aee819576ba41af28bd525e856f (diff)
downloadopenrc-5ba6f0a62817f6031936b8880a15c404840924bb.tar.gz
openrc-5ba6f0a62817f6031936b8880a15c404840924bb.tar.bz2
openrc-5ba6f0a62817f6031936b8880a15c404840924bb.tar.xz
We need to ensure that the init script started is correct, translating symlinks. This has a new rule - multiplexed services must exist in the same dir as the master sript. So we need to ensuret that net.lo(0) is the real script and not a symlink itself. This fixes Gentoo #219526.
-rw-r--r--init.d/.gitignore4
-rw-r--r--init.d/Makefile7
-rw-r--r--init.d/Makefile.FreeBSD2
-rw-r--r--init.d/Makefile.Linux2
-rw-r--r--init.d/Makefile.NetBSD2
-rw-r--r--init.d/net.lo.in (renamed from sh/net.sh.in)0
-rw-r--r--mk/scripts.mk4
-rw-r--r--sh/.gitignore2
-rw-r--r--sh/Makefile6
-rw-r--r--sh/Makefile.FreeBSD2
-rw-r--r--sh/Makefile.Linux1
-rw-r--r--sh/Makefile.NetBSD1
-rw-r--r--src/rc/runscript.c77
13 files changed, 80 insertions, 30 deletions
diff --git a/init.d/.gitignore b/init.d/.gitignore
index e04a53f..1087212 100644
--- a/init.d/.gitignore
+++ b/init.d/.gitignore
@@ -26,3 +26,7 @@ mixer
nscd
powerd
syscons
+net.lo
+ttys
+swap-blk
+wscons
diff --git a/init.d/Makefile b/init.d/Makefile
index a9f62e2..b670eac 100644
--- a/init.d/Makefile
+++ b/init.d/Makefile
@@ -3,7 +3,14 @@ SRCS= bootmisc.in fsck.in halt.sh.in hostname.in local.in localmount.in \
netmount.in root.in swap.in sysctl.in urandom.in
BIN= ${OBJS}
+INSTALLAFTER= _installafter
+CLEANFILES+= net.lo
+TARGETS+= net.lo
+
MK= ../mk
include ${MK}/os.mk
include Makefile.${OS}
include ${MK}/scripts.mk
+
+_installafter: net.lo
+ ${INSTALL} -m ${BINMODE} net.lo ${DESTDIR}/${INITDIR}/${NET_LO}
diff --git a/init.d/Makefile.FreeBSD b/init.d/Makefile.FreeBSD
index 8bcb969..3cd6feb 100644
--- a/init.d/Makefile.FreeBSD
+++ b/init.d/Makefile.FreeBSD
@@ -1,3 +1,5 @@
+NET_LO= net.lo0
+
# Generic BSD scripts
SRCS+= hostid.in moused.in newsyslog.in pf.in rarpd.in rc-enabled.in \
rpcbind.in savecore.in syslogd.in
diff --git a/init.d/Makefile.Linux b/init.d/Makefile.Linux
index 0e476b5..ae9e6ba 100644
--- a/init.d/Makefile.Linux
+++ b/init.d/Makefile.Linux
@@ -1,3 +1,5 @@
+NET_LO= net.lo
+
SRCS+= hwclock.in consolefont.in keymaps.in modules.in mtab.in numlock.in \
procfs.in termencoding.in
diff --git a/init.d/Makefile.NetBSD b/init.d/Makefile.NetBSD
index 0bf2f65..2d1141b 100644
--- a/init.d/Makefile.NetBSD
+++ b/init.d/Makefile.NetBSD
@@ -1,3 +1,5 @@
+NET_LO= net.lo0
+
# Generic BSD scripts
SRCS+= hostid.in moused.in newsyslog.in pf.in rarpd.in rc-enabled.in \
rpcbind.in savecore.in syslogd.in
diff --git a/sh/net.sh.in b/init.d/net.lo.in
index 8f53a86..8f53a86 100644
--- a/sh/net.sh.in
+++ b/init.d/net.lo.in
diff --git a/mk/scripts.mk b/mk/scripts.mk
index ced1844..f65c142 100644
--- a/mk/scripts.mk
+++ b/mk/scripts.mk
@@ -22,9 +22,9 @@ SED_REPLACE= -e 's:@SHELL@:${SH}:g' -e 's:@LIB@:${LIBNAME}:g' -e 's:@SYSCONFDIR
.in:
${SED} ${SED_REPLACE} ${SED_EXTRA} $< > $@
-all: ${OBJS}
+all: ${OBJS} ${TARGETS}
-realinstall: ${BIN} ${CONF} ${CONF_APPEND}
+realinstall: ${BIN} ${CONF} ${INC}
@if test -n "${DIR}"; then \
${ECHO} ${INSTALL} -d ${DESTDIR}/${DIR}; \
${INSTALL} -d ${DESTDIR}/${DIR} || exit $$?; \
diff --git a/sh/.gitignore b/sh/.gitignore
index 91d8a14..028281d 100644
--- a/sh/.gitignore
+++ b/sh/.gitignore
@@ -4,3 +4,5 @@ net.sh
rc-functions.sh
runscript.sh
init.sh
+ifwatchd-carrier.sh
+ifwatchd-nocarrier.sh
diff --git a/sh/Makefile b/sh/Makefile
index cc4aa35..efca980 100644
--- a/sh/Makefile
+++ b/sh/Makefile
@@ -1,8 +1,8 @@
DIR= ${PREFIX}/${RC_LIB}/sh
-SRCS= functions.sh.in gendepends.sh.in net.sh.in \
+SRCS= functions.sh.in gendepends.sh.in \
rc-functions.sh.in runscript.sh.in
INC= init-common-post.sh rc-mount.sh functions.sh rc-functions.sh
-BIN= gendepends.sh init.sh net.sh runscript.sh
+BIN= gendepends.sh init.sh runscript.sh
INSTALLAFTER= _installafter
@@ -13,8 +13,6 @@ include ${MK}/scripts.mk
_installafter:
${INSTALL} -d ${DESTDIR}/${INITDIR}
- @# Provide an init script for the loopback interface
- ln -snf ${PREFIX}/${RC_LIB}/sh/net.sh ${DESTDIR}/${INITDIR}/${NET_LO} || exit $$?
@# Put functions.sh into the init.d dir so 3rd party apps don't have to
@# be multilib aware
ln -snf ${PREFIX}/${RC_LIB}/sh/functions.sh ${DESTDIR}/${INITDIR} || exit $$?
diff --git a/sh/Makefile.FreeBSD b/sh/Makefile.FreeBSD
index 93a00a0..d4e6b86 100644
--- a/sh/Makefile.FreeBSD
+++ b/sh/Makefile.FreeBSD
@@ -1,7 +1,5 @@
SRCS+= init.sh.in
-NET_LO= net.lo0
-
.SUFFIXES: .sh.BSD.in
.sh.BSD.in.sh:
${SED} ${SED_REPLACE} ${SED_EXTRA} $< > $@
diff --git a/sh/Makefile.Linux b/sh/Makefile.Linux
index b73b466..bb48f42 100644
--- a/sh/Makefile.Linux
+++ b/sh/Makefile.Linux
@@ -1,4 +1,3 @@
-NET_LO= net.lo
SRCS+= init.sh.in init-early.sh.in
BIN+= init-early.sh
diff --git a/sh/Makefile.NetBSD b/sh/Makefile.NetBSD
index 0e4200a..bd44393 100644
--- a/sh/Makefile.NetBSD
+++ b/sh/Makefile.NetBSD
@@ -1,6 +1,5 @@
SRCS+= init.sh.in
-NET_LO= net.lo0
SRCS+= ifwatchd-carrier.sh.in ifwatchd-nocarrier.sh.in
BIN+= ifwatchd-carrier.sh ifwatchd-nocarrier.sh
diff --git a/src/rc/runscript.c b/src/rc/runscript.c
index 4ecf305..af140d6 100644
--- a/src/rc/runscript.c
+++ b/src/rc/runscript.c
@@ -39,6 +39,7 @@
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
+#include <libgen.h>
#include <limits.h>
#include <signal.h>
#include <stdio.h>
@@ -707,7 +708,8 @@ static void svc_start(bool deps)
hook_out = RC_HOOK_SERVICE_START_OUT;
rc_plugin_run(RC_HOOK_SERVICE_START_IN, applet);
- if (rc_conf_yesno("rc_depend_strict"))
+ errno = 0;
+ if (rc_conf_yesno("rc_depend_strict") || errno == ENOENT)
depoptions |= RC_DEP_STRICT;
if (deps) {
@@ -933,8 +935,8 @@ static void svc_stop(bool deps)
ewarn ("WARNING: you are stopping a boot service");
if (deps && ! (state & RC_SERVICE_WASINACTIVE)) {
-
- if (rc_conf_yesno("rc_depend_strict"))
+ errno = 0;
+ if (rc_conf_yesno("rc_depend_strict") || errno == ENOENT)
depoptions |= RC_DEP_STRICT;
if (! deptree && ((deptree = _rc_deptree_load(NULL)) == NULL))
@@ -1102,39 +1104,73 @@ int runscript(int argc, char **argv)
int retval;
int opt;
RC_STRING *svc;
- char dir[PATH_MAX];
+ char path[PATH_MAX];
+ char lnk[PATH_MAX];
size_t l = 0;
size_t ll;
- char *save;
+ char *dir, *save;
+ const char *file;
int depoptions = RC_DEP_TRACE;
+ struct stat stbuf;
/* Show help if insufficient args */
if (argc < 2 || ! exists(argv[1])) {
- fprintf(stderr, "runscript is not meant to be to run directly\n");
+ fprintf(stderr, "runscript should not be run directly\n");
exit(EXIT_FAILURE);
}
- applet = basename_c(argv[1]);
- if (argc < 3)
- usage(EXIT_FAILURE);
-
- if (*argv[1] == '/')
- service = xstrdup(argv[1]);
- else {
- getcwd(dir, sizeof(dir));
- l = strlen(dir) + strlen(argv[1]) + 2;
- service = xmalloc(sizeof (char) * l);
- snprintf(service, l, "%s/%s", dir, argv[1]);
+ if (stat(argv[1], &stbuf) != 0) {
+ fprintf(stderr, "runscript `%s': %s\n",
+ argv[1], strerror(errno));
+ exit(EXIT_FAILURE);
}
atexit(cleanup);
+ /* We need to work out the real full path to our service.
+ * This works fine, provided that we ONLY allow mulitplexed 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);
+ dir = dirname(lnk);
+ if (strcmp(dir, save) == 0)
+ file = basename_c(argv[1]);
+ else
+ file = basename_c(lnk);
+ free(save);
+ dir = dirname(path);
+ } 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);
+ }
+ }
+ if (!service)
+ service = xstrdup(path);
+ applet = basename_c(service);
+
+ if (argc < 3)
+ usage(EXIT_FAILURE);
+
/* Change dir to / to ensure all init scripts don't use stuff in pwd */
chdir("/");
#ifdef __linux__
- /* coldplug events can trigger init scripts, but we don't want to run them
- until after rc sysinit has completed so we punt them to the boot runlevel */
+ /* coldplug events can trigger init scripts, but we don't want to run
+ * them until after rc sysinit has completed so we punt them to the
+ * boot runlevel */
if (exists("/dev/.rcsysinit")) {
eerror("%s: cannot run until sysvinit completes", applet);
if (mkdir("/dev/.rcboot", 0755) != 0 && errno != EEXIST)
@@ -1264,7 +1300,8 @@ int runscript(int argc, char **argv)
strcmp(optarg, "ibefore") == 0 ||
strcmp(optarg, "iprovide") == 0)
{
- if (rc_conf_yesno("rc_depend_strict"))
+ errno = 0;
+ if (rc_conf_yesno("rc_depend_strict") || errno == ENOENT)
depoptions |= RC_DEP_STRICT;
if (! deptree && ((deptree = _rc_deptree_load(NULL)) == NULL))