diff --git a/init.d/bootmisc.in b/init.d/bootmisc.in index a19a10b1..c6894e42 100644 --- a/init.d/bootmisc.in +++ b/init.d/bootmisc.in @@ -126,7 +126,7 @@ start() stop() { # Write a halt record if we're shutting down - case "${RC_SOFTLEVEL}" in + case "${RC_RUNLEVEL}" in reboot|shutdown) [ "${RC_UNAME}" = "Linux" ] && halt -w;; esac diff --git a/init.d/fsck.in b/init.d/fsck.in index d03e1417..5bf9ba8a 100644 --- a/init.d/fsck.in +++ b/init.d/fsck.in @@ -19,7 +19,7 @@ _abort() { # We should only reboot when first booting _reboot() { - if [ "${RC_SOFTLEVEL}" = "${RC_BOOTLEVEL}" ]; then + if [ "${RC_RUNLEVEL}" = "${RC_BOOTLEVEL}" ]; then reboot "$@" _abort || return 1 fi diff --git a/man/Makefile b/man/Makefile index 0357d27a..b8f0e42e 100644 --- a/man/Makefile +++ b/man/Makefile @@ -1,7 +1,8 @@ MAN3= einfo.3 \ rc_config.3 rc_deptree.3 rc_find_pids.3 rc_plugin_hook.3 \ rc_runlevel.3 rc_service.3 rc_stringlist.3 -MAN8= rc-status.8 rc-update.8 rc.8 runscript.8 start-stop-daemon.8 +MAN8= rc-service.8 rc-status.8 rc-update.8 rc.8 runscript.8 \ + start-stop-daemon.8 # Handy macro to create symlinks # This does rely on correctly formatting our manpages! diff --git a/man/rc-service.8 b/man/rc-service.8 new file mode 100644 index 00000000..840f22b8 --- /dev/null +++ b/man/rc-service.8 @@ -0,0 +1,42 @@ +.\" Copyright 2008 Roy Marples +.\" All rights reserved +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd Mar 19, 2008 +.Dt RC-SERVICE 8 SMM +.Os OpenRC +.Sh NAME +.Nm rc-service +.Nd locate and run an OpenRC service with the given arguments +.Sh SYNOPSIS +.Nm +.Ar service cmd +.Op Ar ... +.Sh DESCRIPTION +Service scripts could be in different places on different systems. +.Nm +locates the specified service and runs it with the given arguments. +.Sh SEE ALSO +.Xr rc 8 , +.Sh AUTHORS +.An "Roy Marples" Aq roy@marples.name diff --git a/man/runscript.8 b/man/runscript.8 index cd457b5a..7aaf9646 100644 --- a/man/runscript.8 +++ b/man/runscript.8 @@ -278,7 +278,7 @@ sets the following environment variables for use in the service scripts: .Bl -tag -width "RC_DEFAULTLEVEL" .It Va SVCNAME Name of the service. -.It Va RC_SOFTLEVEL +.It Va RC_RUNLEVEL Current runlevel that rc is in. .It Va RC_BOOTLEVEL Boot runlevel chosen. Default is boot. @@ -293,7 +293,7 @@ The result of `uname -s`. .Sh FILES .Pp Configuration files, relative to the location of the service. -If a file ending with .${RC_SOFTLEVEL} exists then we use that instead. +If a file ending with .${RC_RUNLEVEL} exists then we use that instead. .Bl -ohang .It Pa ../conf.d/${SVCNAME%%.*} mulitplexed configuration file. diff --git a/mk/os.mk b/mk/os.mk index 7b395cd8..7993820b 100644 --- a/mk/os.mk +++ b/mk/os.mk @@ -13,7 +13,7 @@ _PREFIX_SH= if test -n "${PREFIX}" && test "${PREFIX}" != "/"; then echo "-DPREF _PREFIX!= ${_PREFIX_SH} CFLAGS+= ${_PREFIX}$(shell ${_PREFIX_SH}) -_PKG_PREFIX_SH= if test -n "${PKG_PREFIX}" && test "${PKG_PREFIX}" != "/"; then echo "-DPKG_PREFIX=\\\"${PKG_PREFIX}\\\""; else echo ""; fi +_PKG_PREFIX_SH= if test -n "${PKG_PREFIX}" && test "${PKG_PREFIX}" != "/" && test "${PKG_PREFIX}" != "${PREFIX}"; then echo "-DPKG_PREFIX=\\\"${PKG_PREFIX}\\\""; else echo ""; fi _PKG_PREFIX!= ${_PKG_PREFIX_SH} CFLAGS+= ${_PKG_PREFIX}$(shell ${_PKG_PREFIX_SH}) diff --git a/sh/runscript.sh.in b/sh/runscript.sh.in index be69bb9b..0df0aa0e 100644 --- a/sh/runscript.sh.in +++ b/sh/runscript.sh.in @@ -47,8 +47,8 @@ _conf_d=${1%/*}/../conf.d # If we're net.eth0 or openvpn.work then load net or openvpn config _c=${SVCNAME%%.*} if [ -n "${_c}" -a "${_c}" != "${SVCNAME}" ]; then - if [ -e "${_conf_d}/${_c}.${RC_SOFTLEVEL}" ]; then - . "${_conf_d}/${_c}.${RC_SOFTLEVEL}" + if [ -e "${_conf_d}/${_c}.${RC_RUNLEVEL}" ]; then + . "${_conf_d}/${_c}.${RC_RUNLEVEL}" elif [ -e "${_conf_d}/${_c}" ]; then . "${_conf_d}//${_c}" fi @@ -56,8 +56,8 @@ fi unset _c # Overlay with our specific config -if [ -e "${_conf_d}/${SVCNAME}.${RC_SOFTLEVEL}" ]; then - . "${_conf_d}/${SVCNAME}.${RC_SOFTLEVEL}" +if [ -e "${_conf_d}/${SVCNAME}.${RC_RUNLEVEL}" ]; then + . "${_conf_d}/${SVCNAME}.${RC_RUNLEVEL}" elif [ -e "${_conf_d}/${SVCNAME}" ]; then . "${_conf_d}/${SVCNAME}" fi diff --git a/src/includes/rc-misc.h b/src/includes/rc-misc.h index 9a706175..81ffbc64 100644 --- a/src/includes/rc-misc.h +++ b/src/includes/rc-misc.h @@ -76,7 +76,7 @@ # define RC_LOCAL_CONFDIR LOCAL_PREFIX SYSCONFDIR "/conf.d" #endif -#define RC_KSOFTLEVEL RC_SVCDIR "/ksoftlevel" +#define RC_KRUNLEVEL RC_SVCDIR "/krunlevel" #define RC_STARTING RC_SVCDIR "/rc.starting" #define RC_STOPPING RC_SVCDIR "/rc.stopping" diff --git a/src/librc/librc.c b/src/librc/librc.c index f2b7758d..8ce9469d 100644 --- a/src/librc/librc.c +++ b/src/librc/librc.c @@ -37,7 +37,7 @@ const char librc_copyright[] = "Copyright (c) 2007-2008 Roy Marples"; #endif #include -#define SOFTLEVEL RC_SVCDIR "/softlevel" +#define RC_RUNLEVEL RC_SVCDIR "/softlevel" #ifndef S_IXUGO # define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH) @@ -268,7 +268,7 @@ char *rc_runlevel_get(void) FILE *fp; char *runlevel = NULL; - if ((fp = fopen(SOFTLEVEL, "r"))) { + if ((fp = fopen(RC_RUNLEVEL, "r"))) { runlevel = xmalloc(sizeof(char) * PATH_MAX); if (fgets(runlevel, PATH_MAX, fp)) { int i = strlen(runlevel) - 1; @@ -290,7 +290,7 @@ librc_hidden_def(rc_runlevel_get) bool rc_runlevel_set(const char *runlevel) { - FILE *fp = fopen(SOFTLEVEL, "w"); + FILE *fp = fopen(RC_RUNLEVEL, "w"); if (! fp) return false; diff --git a/src/rc/Makefile b/src/rc/Makefile index 8c43da85..d2c71207 100644 --- a/src/rc/Makefile +++ b/src/rc/Makefile @@ -11,7 +11,7 @@ SBINDIR= ${PREFIX}/sbin LINKDIR= ${PREFIX}/${LIBNAME}/${PROG} BINLINKS= rc-status -SBINLINKS= rc-update runscript start-stop-daemon +SBINLINKS= rc-service rc-update runscript start-stop-daemon RC_BINLINKS= einfon einfo ewarnn ewarn eerrorn eerror ebegin eend ewend \ eindent eoutdent esyslog eval_ecolors \ veinfo vewarn vebegin veend vewend veindent veoutdent \ diff --git a/src/rc/rc-applets.c b/src/rc/rc-applets.c index 96b392d8..821832cd 100644 --- a/src/rc/rc-applets.c +++ b/src/rc/rc-applets.c @@ -362,6 +362,18 @@ static int do_shell_var(int argc, char **argv) return EXIT_SUCCESS; } +static int rc_service(_unused int argc, char **argv) +{ + char *service = rc_service_resolve(argv[1]); + + if (!service) + eerrorx("%s: service `%s' does not exist", applet, optarg); + + *++argv = service; + execv(*argv, argv); + eerrorx("%s: %s", applet, strerror(errno)); + /* NOTREACHED */ +} void run_applets(int argc, char **argv) { @@ -377,6 +389,8 @@ void run_applets(int argc, char **argv) exit(mountinfo(argc, argv)); else if (strcmp(applet, "rc-depend") == 0) exit(rc_depend(argc, argv)); + else if (strcmp(applet, "rc-service") == 0) + exit(rc_service(argc, argv)); else if (strcmp(applet, "rc-status") == 0) exit(rc_status(argc, argv)); else if (strcmp(applet, "rc-update") == 0 || diff --git a/src/rc/rc-depend.c b/src/rc/rc-depend.c index 33a50f06..908cf3a5 100644 --- a/src/rc/rc-depend.c +++ b/src/rc/rc-depend.c @@ -107,7 +107,7 @@ int rc_depend(int argc, char **argv) int options = RC_DEP_TRACE; bool first = true; bool update = false; - char *runlevel = xstrdup(getenv("RC_SOFTLEVEL")); + char *runlevel = xstrdup(getenv("RC_RUNLEVEL")); int opt; char *token; diff --git a/src/rc/rc-misc.c b/src/rc/rc-misc.c index 7c5d1014..e802ee4f 100644 --- a/src/rc/rc-misc.c +++ b/src/rc/rc-misc.c @@ -224,7 +224,7 @@ void env_config(void) setenv("RC_RUNLEVEL", e, 1); free(e); - if ((fp = fopen(RC_KSOFTLEVEL, "r"))) { + if ((fp = fopen(RC_KRUNLEVEL, "r"))) { memset(buffer, 0, sizeof (buffer)); if (fgets(buffer, sizeof (buffer), fp)) { l = strlen (buffer) - 1; diff --git a/src/rc/rc.c b/src/rc/rc.c index fab23255..85ab5578 100644 --- a/src/rc/rc.c +++ b/src/rc/rc.c @@ -367,14 +367,14 @@ static bool set_ksoftlevel(const char *level) strcmp(level, RC_LEVEL_SINGLE) == 0 || strcmp(level, RC_LEVEL_SYSINIT) == 0) { - if (exists(RC_KSOFTLEVEL) && - unlink(RC_KSOFTLEVEL) != 0) - eerror("unlink `%s': %s", RC_KSOFTLEVEL, strerror(errno)); + if (exists(RC_KRUNLEVEL) && + unlink(RC_KRUNLEVEL) != 0) + eerror("unlink `%s': %s", RC_KRUNLEVEL, strerror(errno)); return false; } - if (! (fp = fopen(RC_KSOFTLEVEL, "w"))) { - eerror("fopen `%s': %s", RC_KSOFTLEVEL, strerror(errno)); + if (! (fp = fopen(RC_KRUNLEVEL, "w"))) { + eerror("fopen `%s': %s", RC_KRUNLEVEL, strerror(errno)); return false; } @@ -388,11 +388,11 @@ static int get_ksoftlevel(char *buffer, int buffer_len) FILE *fp; int i = 0; - if (! exists(RC_KSOFTLEVEL)) + if (! exists(RC_KRUNLEVEL)) return 0; - if (! (fp = fopen(RC_KSOFTLEVEL, "r"))) { - eerror("fopen `%s': %s", RC_KSOFTLEVEL, strerror(errno)); + if (! (fp = fopen(RC_KRUNLEVEL, "r"))) { + eerror("fopen `%s': %s", RC_KRUNLEVEL, strerror(errno)); return -1; } @@ -683,7 +683,7 @@ static void do_newlevel(const char *newlevel) printf("Press %sI%s to enter interactive boot mode\n\n", ecolor(ECOLOR_GOOD), ecolor(ECOLOR_NORMAL)); - setenv("RC_SOFTLEVEL", newlevel, 1); + setenv("RC_RUNLEVEL", newlevel, 1); rc_plugin_run(RC_HOOK_RUNLEVEL_START_IN, newlevel); hook_out = RC_HOOK_RUNLEVEL_START_OUT; run_script(INITSH); @@ -902,10 +902,12 @@ interactive_option: #define getoptstring "o:" getoptstring_COMMON static const struct option longopts[] = { { "override", 1, NULL, 'o' }, + { "service", 1, NULL, 's' }, longopts_COMMON }; static const char * const longopts_help[] = { "override the next runlevel to change into\nwhen leaving single user or boot runlevels", + "runs the service specified with the rest\nof the arguments", longopts_help_COMMON }; #include "_usage.c" @@ -958,8 +960,7 @@ int main(int argc, char **argv) chdir("/"); /* RUNLEVEL is set by sysvinit as is a magic number - * RC_SOFTLEVEL is set by us and is the name for this magic number - * even though all our userland documentation refers to runlevel */ + * RC_RUNLEVEL is set by us and is the name for this magic number */ RUNLEVEL = getenv("RUNLEVEL"); PREVLEVEL = getenv("PREVLEVEL"); @@ -979,6 +980,16 @@ int main(int argc, char **argv) optarg = NULL; exit(set_ksoftlevel(optarg) ? EXIT_SUCCESS : EXIT_FAILURE); /* NOTREACHED */ + case 's': + newlevel = rc_service_resolve(optarg); + if (!newlevel) + eerrorx("%s: service `%s' does not exist", + applet, optarg); + argv += optind - 1; + *argv = newlevel; + execv(*argv, argv); + eerrorx("%s: %s", applet, strerror(errno)); + /* NOTREACHED */ case_RC_COMMON_GETOPT } }