aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2007-07-10 19:09:41 +0000
committerRoy Marples <roy@marples.name>2007-07-10 19:09:41 +0000
commit05201b514b99d636af8067e442b2c6ab04e6d530 (patch)
tree9f41b80b1540b297ba38adc294cb700f92af4aa6
parent445918685e559babf219cbfc775b9c582b52a2fc (diff)
init scripts and their extra options can now have descriptions, #184327.
-rw-r--r--ChangeLog1
-rwxr-xr-xinit.d.BSD/clock3
-rwxr-xr-xinit.d.Linux/clock3
-rwxr-xr-xinit.d.Linux/consolefont2
-rwxr-xr-xinit.d.Linux/keymaps2
-rwxr-xr-xinit.d.Linux/modules2
-rwxr-xr-xinit.d.Linux/numlock2
-rwxr-xr-xinit.d/checkfs3
-rwxr-xr-xinit.d/checkroot3
-rwxr-xr-xinit.d/hostname2
-rwxr-xr-xinit.d/local3
-rwxr-xr-xinit.d/localmount4
-rwxr-xr-xinit.d/netmount2
-rwxr-xr-xinit.d/rmnologin2
-rwxr-xr-xinit.d/urandom2
-rwxr-xr-xsh/net.sh2
-rwxr-xr-xsh/rc-help.sh10
-rwxr-xr-xsh/runscript.sh21
-rw-r--r--src/librc.c76
-rw-r--r--src/librc.h2
-rw-r--r--src/rc.h2
-rw-r--r--src/runscript.c112
22 files changed, 201 insertions, 60 deletions
diff --git a/ChangeLog b/ChangeLog
index 89adcb20..f3aec0fd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,7 @@
10 Jul 2007; Roy Marples <uberlord@gentoo.org>:
+ init scripts and their extra options can now have descriptions, #184327.
We no longer care about numerical runlevels, #184733.
09 Jul 2007; Roy Marples <uberlord@gentoo.org>:
diff --git a/init.d.BSD/clock b/init.d.BSD/clock
index 0baa2884..17e6f1d9 100755
--- a/init.d.BSD/clock
+++ b/init.d.BSD/clock
@@ -4,6 +4,9 @@
opts="save"
+description="Sets the local clock to UTC or Local Time."
+description_save="Saves the current time in the BIOS."
+
depend() {
# BSD adjkerntz needs to be able to write to /etc
if [ "${CLOCK}" = "UTC" -a -e /etc/wall_cmos_clock ] ||
diff --git a/init.d.Linux/clock b/init.d.Linux/clock
index a74bb289..144ecbcb 100755
--- a/init.d.Linux/clock
+++ b/init.d.Linux/clock
@@ -4,6 +4,9 @@
opts="save"
+description="Sets the local clock to UTC or Local Time."
+description_save="Saves the current time in the BIOS."
+
depend() {
case "${CLOCK_ADJTIME}" in
"") before *;;
diff --git a/init.d.Linux/consolefont b/init.d.Linux/consolefont
index dc568059..33d5676a 100755
--- a/init.d.Linux/consolefont
+++ b/init.d.Linux/consolefont
@@ -2,6 +2,8 @@
# Copyright 1999-2007 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
+description="Sets a font for the consoles."
+
depend() {
need localmount
need keymaps # sets up terminal encoding scheme
diff --git a/init.d.Linux/keymaps b/init.d.Linux/keymaps
index 1e0f28fa..17485124 100755
--- a/init.d.Linux/keymaps
+++ b/init.d.Linux/keymaps
@@ -2,6 +2,8 @@
# Copyright 1999-2007 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
+description="Applies a keymap for the consoles."
+
depend() {
need localmount
}
diff --git a/init.d.Linux/modules b/init.d.Linux/modules
index 090bd7c9..53ad52ae 100755
--- a/init.d.Linux/modules
+++ b/init.d.Linux/modules
@@ -2,6 +2,8 @@
# Copyright 1999-2007 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
+description="Loads a user defined list of kernel modules."
+
depend() {
need checkroot
use isapnp
diff --git a/init.d.Linux/numlock b/init.d.Linux/numlock
index 9597475a..3326e132 100755
--- a/init.d.Linux/numlock
+++ b/init.d.Linux/numlock
@@ -2,6 +2,8 @@
# Copyright 1999-2007 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
+description="Turns numlock on for the consoles."
+
depend() {
need localmount
}
diff --git a/init.d/checkfs b/init.d/checkfs
index d2929edd..54bdce94 100755
--- a/init.d/checkfs
+++ b/init.d/checkfs
@@ -2,6 +2,9 @@
# Copyright 1999-2007 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
+description="Check filesystems according to /etc/fstab for errors and \
+optionally repair them."
+
depend() {
need checkroot
after modules
diff --git a/init.d/checkroot b/init.d/checkroot
index d6dcd4f7..a7a8b3eb 100755
--- a/init.d/checkroot
+++ b/init.d/checkroot
@@ -2,6 +2,9 @@
# Copyright 1999-2007 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
+description="Check the root filesystem according to /etc/fstab for errors \
+and optionally repair them."
+
do_mtab() {
# Don't create mtab if /etc is readonly
if ! touch /etc/mtab 2> /dev/null ; then
diff --git a/init.d/hostname b/init.d/hostname
index 4e804520..35cf1068 100755
--- a/init.d/hostname
+++ b/init.d/hostname
@@ -2,6 +2,8 @@
# Copyright 1999-2007 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
+description="Sets the hostname of the machine."
+
depend() {
need checkroot
}
diff --git a/init.d/local b/init.d/local
index 77d02668..60556e4c 100755
--- a/init.d/local
+++ b/init.d/local
@@ -2,6 +2,9 @@
# Copyright 1999-2007 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
+description="Executes user command in /etc/conf.d/local.start when starting \
+and /etc/conf.d/local.stop when stopping."
+
depend() {
after *
}
diff --git a/init.d/localmount b/init.d/localmount
index 456aee34..02688488 100755
--- a/init.d/localmount
+++ b/init.d/localmount
@@ -2,6 +2,10 @@
# Copyright 1999-2007 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
+description="Mounts disks and swap according to /etc/fstab."
+[ -e /proc/filessystems ] && description="${description} Also mounts various filesystems in /proc."
+[ -x /sbin/dumpon ] && description="${description} Also configures saving kernel dumps to swap."
+
depend() {
need checkfs
}
diff --git a/init.d/netmount b/init.d/netmount
index a2f71302..61b7a6c6 100755
--- a/init.d/netmount
+++ b/init.d/netmount
@@ -2,6 +2,8 @@
# Copyright 1999-2007 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
+description="Mounts network shares according to /etc/fstab."
+
have_nfs() {
local IFS=\n x=
set -- $(fstabinfo --fstype nfs,nfs4)
diff --git a/init.d/rmnologin b/init.d/rmnologin
index 0c1691f7..3ebd6dfd 100755
--- a/init.d/rmnologin
+++ b/init.d/rmnologin
@@ -2,6 +2,8 @@
# Copyright 1999-2007 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
+description="Removes a file which blocks logins until this service has run."
+
depend() {
need localmount
}
diff --git a/init.d/urandom b/init.d/urandom
index ecded0a5..3d083766 100755
--- a/init.d/urandom
+++ b/init.d/urandom
@@ -4,6 +4,8 @@
URANDOM_SEED=${URANDOM_SEED:-/var/run/random-seed}
+description="Initializes the random number generator."
+
depend() {
need localmount
}
diff --git a/sh/net.sh b/sh/net.sh
index 039b586b..21c57e04 100755
--- a/sh/net.sh
+++ b/sh/net.sh
@@ -8,6 +8,8 @@ _config_vars="config routes"
[ -z "${IN_BACKGROUND}" ] && IN_BACKGROUND=false
+description="Configures network interfaces."
+
depend() {
local IFACE=${SVCNAME#*.}
local IFVAR=$(echo -n "${IFACE}" | sed -e 's/[^[:alnum:]]/_/g')
diff --git a/sh/rc-help.sh b/sh/rc-help.sh
index 97ca53f4..8edbb8ef 100755
--- a/sh/rc-help.sh
+++ b/sh/rc-help.sh
@@ -32,7 +32,7 @@ else
NL=
fi
-default_opts="start stop restart pause zap"
+default_opts="describe start stop restart pause zap"
extra_opts="$(. "${myscript}" 2>/dev/null ; echo "${opts}")"
if [ "${BE_VERBOSE}" = "yes" ] ; then
@@ -48,6 +48,9 @@ ${CYAN}Normal Options:${OFF}"
if [ "${BE_VERBOSE}" = "yes" ] ; then
printf "
+ ${GREEN}describe${OFF}
+ Describe what the service and any extra options do.
+
${GREEN}start${OFF}
Start service, as well as the services it depends on (if not already
started).
@@ -68,11 +71,6 @@ printf "
${GREEN}conditionalrestart|condrestart${OFF}
Same as 'restart', but only if the service has already been started.
- ${GREEN}pause${OFF}
- Same as 'stop', but the services that depends on it, will not be
- stopped. This is useful for stopping a network interface without
- stopping all the network services that depend on 'net'.
-
${GREEN}zap${OFF}
Reset a service that is currently stopped, but still marked as started,
to the stopped state. Basically for killing zombie services.
diff --git a/sh/runscript.sh b/sh/runscript.sh
index 6b679c21..1520db42 100755
--- a/sh/runscript.sh
+++ b/sh/runscript.sh
@@ -17,6 +17,25 @@ if [ -z "$1" -o -z "$2" ] ; then
exit 1
fi
+# Descript the init script to the user
+describe() {
+ if [ -n "${description}" ] ; then
+ einfo "${description}"
+ else
+ ewarn "No description for ${SVCNAME}"
+ fi
+
+ local svc= desc=
+ for svc in ${opts} ; do
+ eval desc=\$description_${svc}
+ if [ -n "${desc}" ] ; then
+ einfo "${HILITE}${svc}${NORMAL}: ${desc}"
+ else
+ ewarn "${HILITE}${svc}${NORMAL}: no description"
+ fi
+ done
+}
+
[ "${RC_DEBUG}" = "yes" ] && set -x
# If we're net.eth0 or openvpn.work then load net or openvpn config
@@ -50,7 +69,7 @@ shift
while [ -n "$1" ] ; do
# See if we have the required function and run it
- for rc_x in start stop ${opts} ; do
+ for rc_x in describe start stop ${opts} ; do
if [ "${rc_x}" = "$1" ] ; then
if type "$1" >/dev/null 2>/dev/null ; then
unset rc_x
diff --git a/src/librc.c b/src/librc.c
index 6392426b..4ee82f01 100644
--- a/src/librc.c
+++ b/src/librc.c
@@ -172,6 +172,82 @@ bool rc_service_exists (const char *service)
}
librc_hidden_def(rc_service_exists)
+char **rc_service_options (const char *service)
+{
+ char *svc;
+ char cmd[PATH_MAX];
+ char buffer[RC_LINEBUFFER];
+ char **opts = NULL;
+ char *token;
+ char *p = buffer;
+ FILE *fp;
+
+ if (! rc_service_exists (service))
+ return (NULL);
+
+ svc = rc_resolve_service (service);
+
+ snprintf (cmd, sizeof (cmd), ". '%s'; echo \"${opts}\"", svc);
+ if (! (fp = popen (cmd, "r"))) {
+ eerror ("popen `%s': %s", svc, strerror (errno));
+ free (svc);
+ return (NULL);
+ }
+
+ if (fgets (buffer, RC_LINEBUFFER, fp)) {
+ if (buffer[strlen (buffer) - 1] == '\n')
+ buffer[strlen (buffer) - 1] = '\0';
+ while ((token = strsep (&p, " ")))
+ opts = rc_strlist_addsort (opts, token);
+ }
+ pclose (fp);
+ return (opts);
+}
+librc_hidden_def(rc_service_options)
+
+char *rc_service_description (const char *service, const char *function)
+{
+ char *svc;
+ char cmd[PATH_MAX];
+ char buffer[RC_LINEBUFFER];
+ char *desc = NULL;
+ FILE *fp;
+ int i;
+
+ if (! rc_service_exists (service))
+ return (NULL);
+
+ svc = rc_resolve_service (service);
+
+ if (! function)
+ function = "";
+
+ snprintf (cmd, sizeof (cmd), ". '%s'; echo \"${description%s%s}\"",
+ svc, function ? "_" : "", function);
+ if (! (fp = popen (cmd, "r"))) {
+ eerror ("popen `%s': %s", svc, strerror (errno));
+ free (svc);
+ return (NULL);
+ }
+ free (svc);
+
+ while (fgets (buffer, RC_LINEBUFFER, fp)) {
+ if (! desc) {
+ desc = rc_xmalloc (strlen (buffer) + 1);
+ *desc = '\0';
+ } else {
+ desc = rc_xrealloc (desc, strlen (desc) + strlen (buffer) + 1);
+ }
+ i = strlen (desc);
+ memcpy (desc + i, buffer, strlen (buffer));
+ memset (desc + i + strlen (buffer), 0, 1);
+ }
+
+ pclose (fp);
+ return (desc);
+}
+librc_hidden_def(rc_service_description)
+
bool rc_service_in_runlevel (const char *service, const char *runlevel)
{
char *file;
diff --git a/src/librc.h b/src/librc.h
index cbf26d95..ec126aba 100644
--- a/src/librc.h
+++ b/src/librc.h
@@ -84,8 +84,10 @@ librc_hidden_proto(rc_schedule_start_service)
librc_hidden_proto(rc_service_add)
librc_hidden_proto(rc_service_daemons_crashed)
librc_hidden_proto(rc_service_delete)
+librc_hidden_proto(rc_service_description)
librc_hidden_proto(rc_service_exists)
librc_hidden_proto(rc_service_in_runlevel)
+librc_hidden_proto(rc_service_options)
librc_hidden_proto(rc_services_in_runlevel)
librc_hidden_proto(rc_services_in_state)
librc_hidden_proto(rc_services_scheduled)
diff --git a/src/rc.h b/src/rc.h
index 125bb1f8..8300f725 100644
--- a/src/rc.h
+++ b/src/rc.h
@@ -44,6 +44,8 @@ typedef enum
char *rc_resolve_service (const char *service);
bool rc_service_exists (const char *service);
+char **rc_service_options (const char *service);
+char *rc_service_description (const char *service, const char *function);
bool rc_service_in_runlevel (const char *service, const char *runlevel);
bool rc_service_state (const char *service, rc_service_state_t state);
bool rc_mark_service (const char *service, rc_service_state_t state);
diff --git a/src/runscript.c b/src/runscript.c
index b439d2b3..2e41d59e 100644
--- a/src/runscript.c
+++ b/src/runscript.c
@@ -1182,8 +1182,6 @@ int main (int argc, char **argv)
if (strcmp (optarg, "status") != 0 &&
strcmp (optarg, "help") != 0) {
/* Only root should be able to run us */
- if (geteuid () != 0)
- eerrorx ("%s: root access required", applet);
}
/* Export the command we're running.
@@ -1194,43 +1192,7 @@ int main (int argc, char **argv)
setenv ("RC_CMD", optarg, 1);
doneone = true;
- if (strcmp (optarg, "conditionalrestart") == 0 ||
- strcmp (optarg, "condrestart") == 0)
- {
- if (rc_service_state (service, rc_service_started))
- svc_restart (deps);
- }
- else if (strcmp (optarg, "restart") == 0)
- svc_restart (deps);
- else if (strcmp (optarg, "start") == 0)
- svc_start (deps);
- else if (strcmp (optarg, "status") == 0) {
- rc_service_state_t r = svc_status (service);
- retval = (int) r;
- } else if (strcmp (optarg, "stop") == 0) {
- if (in_background)
- get_started_services ();
-
- svc_stop (deps);
-
- if (! in_background &&
- ! rc_runlevel_stopping () &&
- rc_service_state (service, rc_service_stopped))
- uncoldplug ();
-
- if (in_background &&
- rc_service_state (service, rc_service_inactive))
- {
- int j;
- STRLIST_FOREACH (restart_services, svc, j)
- if (rc_service_state (svc, rc_service_stopped))
- rc_schedule_start_service (service, svc);
- }
- } else if (strcmp (optarg, "zap") == 0) {
- einfo ("Manually resetting %s to stopped state", applet);
- rc_mark_service (applet, rc_service_stopped);
- uncoldplug ();
- } else if (strcmp (optarg, "help") == 0) {
+ if (strcmp (optarg, "help") == 0) {
execl (RCSCRIPT_HELP, RCSCRIPT_HELP, service, "help", (char *) NULL);
eerrorx ("%s: failed to exec `" RCSCRIPT_HELP "': %s",
applet, strerror (errno));
@@ -1239,8 +1201,8 @@ int main (int argc, char **argv)
strcmp (optarg, "needsme") == 0 ||
strcmp (optarg, "usesme") == 0 ||
strcmp (optarg, "iafter") == 0 ||
- strcmp (optarg, "ibefore") == 0
- strcmp (optorg, "iprovide") == 0) {
+ strcmp (optarg, "ibefore") == 0 ||
+ strcmp (optarg, "iprovide") == 0) {
if (! deptree && ((deptree = rc_load_deptree ()) == NULL))
eerrorx ("failed to load deptree");
@@ -1253,21 +1215,65 @@ int main (int argc, char **argv)
STRLIST_FOREACH (services, svc, i)
printf ("%s%s", i == 1 ? "" : " ", svc);
printf ("\n");
- }else
- svc_exec (optarg, NULL);
+ } else if (strcmp (optarg, "status") == 0) {
+ rc_service_state_t r = svc_status (service);
+ retval = (int) r;
+ } else if (strcmp (optarg, "help") == 0) {
+ execl (RCSCRIPT_HELP, RCSCRIPT_HELP, service, "help", (char *) NULL);
+ eerrorx ("%s: failed to exec `" RCSCRIPT_HELP "': %s",
+ applet, strerror (errno));
+ } else {
+ if (geteuid () != 0)
+ eerrorx ("%s: root access required", applet);
- /* Flush our buffered output if any */
- eflush ();
+ if (strcmp (optarg, "conditionalrestart") == 0 ||
+ strcmp (optarg, "condrestart") == 0)
+ {
+ if (rc_service_state (service, rc_service_started))
+ svc_restart (deps);
+ } else if (strcmp (optarg, "restart") == 0) {
+ svc_restart (deps);
+ } else if (strcmp (optarg, "start") == 0) {
+ svc_start (deps);
+ } else if (strcmp (optarg, "stop") == 0) {
+ if (in_background)
+ get_started_services ();
- /* We should ensure this list is empty after an action is done */
- rc_strlist_free (restart_services);
- restart_services = NULL;
- }
+ svc_stop (deps);
- if (! doneone) {
- execl (RCSCRIPT_HELP, RCSCRIPT_HELP, service, (char *) NULL);
- eerrorx ("%s: failed to exec `" RCSCRIPT_HELP "': %s",
- applet, strerror (errno));
+ if (! in_background &&
+ ! rc_runlevel_stopping () &&
+ rc_service_state (service, rc_service_stopped))
+ uncoldplug ();
+
+ if (in_background &&
+ rc_service_state (service, rc_service_inactive))
+ {
+ int j;
+ STRLIST_FOREACH (restart_services, svc, j)
+ if (rc_service_state (svc, rc_service_stopped))
+ rc_schedule_start_service (service, svc);
+ }
+ } else if (strcmp (optarg, "zap") == 0) {
+ einfo ("Manually resetting %s to stopped state", applet);
+ rc_mark_service (applet, rc_service_stopped);
+ uncoldplug ();
+ }else
+ svc_exec (optarg, NULL);
+
+ /* Flush our buffered output if any */
+ eflush ();
+
+ /* We should ensure this list is empty after an action is done */
+ rc_strlist_free (restart_services);
+ restart_services = NULL;
+ }
+
+ if (! doneone) {
+ execl (RCSCRIPT_HELP, RCSCRIPT_HELP, service, (char *) NULL);
+ eerrorx ("%s: failed to exec `" RCSCRIPT_HELP "': %s",
+ applet, strerror (errno));
+ }
}
return (retval);