Compare commits

...

40 Commits

Author SHA1 Message Date
Roy Marples
292fe3a568 Release 0.2.2 2008-04-15 16:09:02 +00:00
Roy Marples
99d5046a56 Don't assume that we have a list returned. 2008-04-10 08:49:05 +00:00
Roy Marples
0e38dcc4d2 By default, rc-status now shows the statuses of the services in the current runlevel and any unassigned non stopped services, #52. 2008-04-09 22:56:32 +00:00
Roy Marples
9176b77c23 Merge branch 'master' of git@git.overlays.gentoo.org:proj/openrc 2008-04-09 19:02:41 +00:00
Roy Marples
fad61a7c4b Fix windowkeys. 2008-04-09 12:24:34 +00:00
Roy Marples
0e114abf5d Respect shutdown's fastboot. 2008-04-09 00:21:49 +00:00
Roy Marples
bc369085c7 More ltsp fixes. 2008-04-09 00:06:50 +00:00
Roy Marples
6d8b36e09d Fix netmout for nfs 2008-04-08 23:25:48 +00:00
Roy Marples
8759735711 Give an error when running zap as a generic user. 2008-04-08 22:57:42 +00:00
Roy Marples
034b9b7a12 Add a silly rc_runlevel function to appease SpanKY :) 2008-04-08 16:01:40 +00:00
Roy Marples
e82435c2f4 rc_runlevel is now the preferred kernel commandline option for choosing default runlevel. 2008-04-08 15:59:56 +00:00
Roy Marples
71dd280656 Fix rc-service --help output. 2008-04-07 11:48:32 +00:00
Roy Marples
594d98eddc Tests now work on NetBSD. 2008-04-07 09:37:14 +00:00
Roy Marples
dcdfdb442f Some systems are only detectable after /proc is mounted, so re-test if unknown. 2008-04-06 20:06:07 +00:00
Roy Marples
143239e143 Increase pidstr size to 10 chars. 2008-04-06 13:24:10 +00:00
Roy Marples
5d38d4d6e9 p could be null here. 2008-04-06 13:21:42 +00:00
Roy Marples
c18c4fc4cc Check list existance before iterating, Gentoo #216091. 2008-04-04 16:31:56 +00:00
Roy Marples
5ebe7f1349 Push out 0.2.1 to solve a few issues. 2008-04-02 16:35:28 +00:00
Roy Marples
6a227d0c45 Merge branch 'master' of git@git.overlays.gentoo.org:proj/openrc 2008-04-02 16:35:02 +00:00
Roy Marples
403abe73de Fix vlans, #49. 2008-04-01 21:34:31 +00:00
Roy Marples
be82e950d7 Merge branch 'master' of git@git.overlays.gentoo.org:proj/openrc 2008-03-31 16:31:43 +00:00
Roy Marples
3ca8387966 Document SSD_NICELEVEL. 2008-03-29 09:37:59 +00:00
Roy Marples
f5a9b42215 Restore noserver and noopenvz to sysctl. 2008-03-28 19:05:26 +00:00
Roy Marples
d370918f0c Merge branch 'master' of git@git.overlays.gentoo.org:proj/openrc 2008-03-28 16:21:59 +00:00
Roy Marples
e995404e3b Add XEN support to NetBSD. 2008-03-28 16:10:31 +00:00
Roy Marples
caa4704ce6 Merge branch 'master' of git@git.overlays.gentoo.org:proj/openrc 2008-03-28 16:05:11 +00:00
Roy Marples
17d28fde42 Support XEN on NetBSD 2008-03-28 16:04:48 +00:00
Roy Marples
b418f2e471 Allow our headers to be included by C++ programs easily. 2008-03-28 11:06:47 +00:00
Roy Marples
ee4e861796 Put some dir locations in rc.h so that 3rd party apps can become awware of them. 2008-03-28 10:46:12 +00:00
Roy Marples
11e33e81c8 Remove rc_service_start/stop from librc as they block and unmask signals. The application may not wish this behaviour and should fork/exec the service itself. 2008-03-28 08:42:05 +00:00
Roy Marples
5e8ed2aeca Tweak install of runlevels. 2008-03-27 19:55:03 +00:00
Roy Marples
742310744d We would sanitize $RC_LIBDIR/sbin as well. If it's really needed then rc-functions.sh will add it back. 2008-03-27 18:34:12 +00:00
Roy Marples
4e9b58b07d Sanitize the write rc dir. 2008-03-27 17:09:18 +00:00
Roy Marples
c564043f86 No need for the extra rc. 2008-03-27 16:59:33 +00:00
Roy Marples
b3d1182a2f Fix mulitlib issues. 2008-03-27 16:53:22 +00:00
Roy Marples
f6cb321f9f NetBSD doesn't work with this powerd. 2008-03-27 14:56:50 +00:00
Roy Marples
f85c6ca84c Make our messages similar 2008-03-27 14:03:37 +00:00
Roy Marples
d09f9f47eb Split terminal encoding out. 2008-03-27 13:49:49 +00:00
Roy Marples
b271ac5af5 Fix install of rc and rc.shutdown on the BSD's. 2008-03-27 09:33:20 +00:00
Roy Marples
fccff6a4ed Allow multiple ntp_servers without error, #47 2008-03-26 22:39:27 +00:00
46 changed files with 518 additions and 415 deletions

View File

@@ -3,7 +3,7 @@
# All rights reserved. Released under the 2-clause BSD license.
NAME= openrc
VERSION= 0.2
VERSION= 0.2.2
PKG= ${NAME}-${VERSION}
SUBDIR= conf.d doc etc init.d man net sh src

View File

@@ -1 +1 @@
CONF+= moused powerd rarpd savecore
CONF+= moused rarpd savecore

View File

@@ -1,4 +1,4 @@
SED_EXTRA= -e 's:@TERM@:cons25:g'
SRCS+= rc.conf.in rc.in rc.shutdown.in
CONF+= devd.conf
BIN+= rc.devd
BIN+= rc rc.shutdown rc.devd

View File

@@ -1,2 +1,3 @@
SED_EXTRA= -e 's:@TERM@:wsvt25:g'
SRCS+= rc.conf.in rc.in rc.shutdown.in
BIN+= rc rc.shutdown

View File

@@ -1,5 +1,5 @@
SRCS+= hwclock.in consolefont.in keymaps.in modules.in mtab.in numlock.in \
procfs.in
procfs.in termencoding.in
.SUFFIXES: .Linux.in
.Linux.in:

View File

@@ -11,11 +11,20 @@ depend()
keyword noprefix
}
dir_writeable()
{
mkdir "$1"/.test.$$ 2>/dev/null && rmdir "$1"/.test.$$
}
cleanup_tmp_dir()
{
local dir=$1
local dir="$1"
mkdir -p "${dir}"
if ! [ -d "${dir}" ]; then
mkdir -p "${dir}" || return $?
fi
dir_writeable "${dir}" || return 1
chmod +t "${dir}"
cd "${dir}"
if yesno ${wipe_tmp:-${WIPE_TMP:-yes}}; then
ebegin "Wiping ${dir} directory"
@@ -60,12 +69,7 @@ cleanup_tmp_dir()
start()
{
if ! mkdir /.test.$$ 2>/dev/null; then
ewarn "Skipping /var and /tmp initialization (ro root?)"
return 0
fi
rmdir /.test.$$
local logw=false
# Ensure that our basic dirs exist
for x in /var/log /var/run /tmp; do
if ! [ -d "${x}" ]; then
@@ -76,51 +80,60 @@ start()
fi
done
ebegin "Creating user login records"
cp /dev/null /var/run/utmp
[ -e /var/log/wtmp ] || cp /dev/null /var/log/wtmp
chmod 0644 /var/run/utmp /var/log/wtmp
eend 0
if dir_writeable /var/run; then
ebegin "Creating user login records"
cp /dev/null /var/run/utmp
if dir_writeable /var/log; then
logw=true
[ -e /var/log/wtmp ] || cp /dev/null /var/log/wtmp
chmod 0644 /var/run/utmp /var/log/wtmp
fi
eend 0
ebegin "Cleaning /var/run"
for x in $(find /var/run ! -type d ! -name utmp ! -name random-seed \
! -name ld-elf.so.hints ! -name ld.so.hints);
do
[ ! -f "${x}" ] && continue
# Do not remove pidfiles of already running daemons
case "${x}" in
*.pid)
start-stop-daemon --test --quiet --stop \
--pidfile "${x}"
[ $? -eq 0 ] && continue
ebegin "Cleaning /var/run"
for x in $(find /var/run ! -type d ! -name utmp \
! -name random-seed \
! -name ld-elf.so.hints ! -name ld.so.hints);
do
[ ! -f "${x}" ] && continue
# Do not remove pidfiles of already running daemons
case "${x}" in
*.pid)
start-stop-daemon --test --quiet \
--stop --pidfile "${x}" && continue
;;
esac
rm -f -- "${x}"
done
eend 0
esac
rm -f -- "${x}"
done
eend 0
fi
# Clean up /tmp directories
local tmp=
for tmp in ${wipe_tmp_dirs-/tmp}; do
cleanup_tmp_dir "${tmp}"
done
chmod +t /tmp /var/tmp
# Make sure our X11 stuff have the correct permissions
# Omit the chown as bootmisc is run before network is up
# and users may be using lame LDAP auth #139411
rm -rf /tmp/.ICE-unix /tmp/.X11-unix
mkdir -p /tmp/.ICE-unix /tmp/.X11-unix
chmod 1777 /tmp/.ICE-unix /tmp/.X11-unix
[ -x /sbin/restorecon ] && restorecon /tmp/.ICE-unix /tmp/.X11-unix
if dir_writeable /tmp; then
# Make sure our X11 stuff have the correct permissions
# Omit the chown as bootmisc is run before network is up
# and users may be using lame LDAP auth #139411
rm -rf /tmp/.ICE-unix /tmp/.X11-unix
mkdir -p /tmp/.ICE-unix /tmp/.X11-unix
chmod 1777 /tmp/.ICE-unix /tmp/.X11-unix
[ -x /sbin/restorecon ] && restorecon /tmp/.ICE-unix /tmp/.X11-unix
fi
# Create an 'after-boot' dmesg log
if [ "${RC_SYS}" != "VSERVER" -a "${RC_SYS}" != "OPENVZ" ]; then
dmesg > /var/log/dmesg
chmod 640 /var/log/dmesg
if ${logw} || dir_writeable /var/log; then
# Create an 'after-boot' dmesg log
if [ "${RC_SYS}" != "VSERVER" -a "${RC_SYS}" != "OPENVZ" ]; then
dmesg > /var/log/dmesg
chmod 640 /var/log/dmesg
fi
fi
rm -f /etc/nologin
return 0
}
stop()

View File

@@ -6,8 +6,7 @@ description="Sets a font for the consoles."
depend()
{
need localmount
need keymaps # sets up terminal encoding scheme
need localmount termencoding
after hotplug
keyword noopenvz noprefix nouml novserver noxenu
}
@@ -34,7 +33,7 @@ start()
return 0
fi
local x= param= sf_param= retval=0 ttydev=
local x= param= sf_param= retval=0 ttydev=/dev/tty
# Get additional parameters
if [ -n "${consoletranslation}" ]; then
@@ -45,11 +44,8 @@ start()
fi
# Set the console font
ebegin "Setting user font"
[ -d /dev/vc ] \
&& ttydev=/dev/vc/ \
|| ttydev=/dev/tty
ebegin "Setting console font [${consolefont}]"
[ -d /dev/vc ] && ttydev=/dev/vc/
x=1
while [ ${x} -le ${ttyn} ]; do
setfont ${consolefont} ${param} -C ${ttydev}${x} >/dev/null
@@ -61,17 +57,17 @@ start()
# Store the last font so we can use it ASAP on boot
if [ ${retval} -eq 0 -a -w "${RC_LIBDIR}" ]; then
mkdir -p "${RC_LIBDIR}"/console
for font in /usr/share/consolefonts/"${consolefont}".*; do
:
done
cp "${font}" "${RC_LIBDIR}"/console
echo "${font##*/}" > "${RC_LIBDIR}"/console/font
if yesno ${unicode:-${UNICODE}}; then
cp /dev/null "${RC_LIBDIR}"/console/unicode
echo "" > "${RC_LIBDIR}"/console/unicode
else
rm -f "${RC_LIBDIR}"/console/unicode
fi
fi
return ${retval}

View File

@@ -29,6 +29,11 @@ start()
{
local reboot_opts= fsck_opts= p=
if [ -e /fastboot ]; then
ewarn "Skipping fsck due to /fastboot"
return 0
fi
ebegin "Checking local filesystems"
for p in ${fsck_passno}; do
local IFS="${_IFS}"

View File

@@ -8,13 +8,13 @@ ttyn=${rc_tty_number:-${RC_TTY_NUMBER:-12}}
unicode=${unicode:-${UNICODE}}
keymap=${keymap:-${KEYMAP}}
extended_keymaps=${extended_keymaps:-${EXTENDED_KEYMAPS}}
windowskeys=${windowskeys:-${SET_WINDOWSKEYS}}
windowkeys=${windowkeys:-${SET_WINDOWSKEYS}}
fix_euro=${fix_euro:-${FIX_EURO}}
dumpkeys_charset=${dumpkeys_charset:-${DUMPKEYS_CHARSET}}
depend()
{
need localmount
need localmount termencoding
keyword noopenvz noprefix nouml novserver noxenu
}
@@ -25,43 +25,41 @@ start()
return 1
fi
local ttydev= n=
[ -d /dev/vc ] \
&& ttydev=/dev/vc/ \
|| ttydev=/dev/tty
local ttydev=/dev/tty n=
[ -d /dev/vc ] && ttydev=/dev/vc/
# Force linux keycodes for PPC.
if [ -f /proc/sys/dev/mac_hid/keyboard_sends_linux_keycodes ]; then
echo 1 > /proc/sys/dev/mac_hid/keyboard_sends_linux_keycodes
fi
ebegin "Loading key mappings"
local loadkeys_uni= wkeys=
yesno ${unicode} && loadkeys_uni="--unicode"
yesno ${windowskeys} && wkeys="windowkeys"
ebegin "Loading key mappings [${keymap}]"
local loadkeys_uni= wkeys= kmode="-a" msg="ASCII"
if yesno ${unicode}; then
loadkeys_uni="--unicode"
kmode="-u"
msg="UTF-8"
fi
yesno ${windowkeys} && wkeys="windowkeys"
loadkeys -q ${loadkeys_uni} ${wkeys} ${keymap} ${extended_keymaps}
eend $? "Error loading key mappings" || return $?
if yesno ${fix_euro}; then
ebegin "Fixing font for euro symbol"
# Fix some fonts displaying the Euro, #173528.
echo "altgr keycode 18 = U+20AC" | loadkeys -q
eend $?
fi
# Set terminal encoding to either ASCII or UNICODE.
# See utf-8(7) for more information.
local termencoding="%@" termmsg="ASCII" kmode="-a"
ebegin "Setting keyboard mode [${msg}]"
if yesno ${unicode}; then
dumpkeys ${dumpkeys_charset:+-c} \
${dumpkeys_charset} | loadkeys --unicode
termencoding="%G"
termmsg="UTF-8"
kmode="-u"
fi
ebegin "Setting terminal encoding to" ${termmsg}
n=1
while [ ${n} -le "${ttyn}" ]; do
printf "\033%s" "${termencoding}" >"${ttydev}${n}"
kbd_mode "${kmode}" -C "${ttydev}${n}"
n=$((${n} + 1))
done

View File

@@ -23,12 +23,12 @@ depend()
{
# Only have portmap as a dependency if there is a nfs mount in fstab
# that is set to mount at boot
local pmap=""
local pmap=
if need_portmap; then
pmap="${pmap} rpc.statd"
pmap="rpc.statd"
[ -x @SYSCONFDIR@/init.d/rpcbind ] \
&& pmap="rpcbind" \
|| pmap="portmap"
&& pmap="${pmap} rpcbind" \
|| pmap="${pmap} portmap"
fi
config /etc/fstab

View File

@@ -13,7 +13,7 @@ depend()
start()
{
if echo 2>/dev/null >/.test.$$; then
rm -f /.test.$$
rm -f /.test.$$ /fastboot
return 0
fi
@@ -23,4 +23,5 @@ start()
*) mount -u -o rw /;;
esac
eend $? "Root filesystem could not be mounted read/write"
rm -f /fastboot
}

View File

@@ -6,7 +6,7 @@ depend()
{
use hostname
before bootmisc logger
keyword noprefix
keyword noopenvz noprefix novserver
}
start()

35
init.d/termencoding.in Normal file
View File

@@ -0,0 +1,35 @@
#!@PREFIX@/sbin/runscript
# Copyright 2008 Roy Marples <roy@marples.name>
# All rights reserved. Released under the 2-clause BSD license.
description="Configures terminal encoding."
ttyn=${rc_tty_number:-${RC_TTY_NUMBER:-12}}
unicode=${unicode:-${UNICODE}}
depend()
{
keyword noopenvz noprefix nouml novserver noxenu
}
start()
{
local ttydev=/dev/tty n=
[ -d /dev/vc ] && ttydev=/dev/vc/
# Set terminal encoding to either ASCII or UNICODE.
# See utf-8(7) for more information.
local termencoding="%@" termmsg="ASCII"
if yesno ${unicode}; then
termencoding="%G"
termmsg="UTF-8"
fi
ebegin "Setting terminal encoding [${termmsg}]"
n=1
while [ ${n} -le "${ttyn}" ]; do
printf "\033%s" "${termencoding}" >"${ttydev}${n}"
n=$((${n} + 1))
done
eend 0
}

View File

@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd Feb 22, 2008
.Dd Arp 9, 2008
.Dt RC-STATUS 8 SMM
.Os OpenRC
.Sh NAME
@@ -36,7 +36,8 @@
.Nm
gathers and displays information about the status of services
in different runlevels. The default behavior is to show information
about the current runlevel, but any runlevel can be quickly examined.
about the current runlevel and any unassgined services that are not stopped,
but any runlevel can be quickly examined.
.Pp
The options are as follows:
.Bl -tag -width ".Fl test , test string"

View File

@@ -31,11 +31,10 @@
.Nm rc_service_mark , rc_service_extra_commands , rc_service_plugable ,
.Nm rc_service_resolve , rc_service_schedule_start , rc_services_scheduled_by ,
.Nm rc_service_schedule_clear , rc_service_state ,
.Nm rc_service_start , rc_service_stop ,
.Nm rc_service_started_daemon , rc_service_value_get , rc_service_value_set ,
.Nm rc_services_in_runlevel , rc_services_in_state , rc_services_scheduled ,
.Nm rc_service_daemons_crashed
.Nd functions to start, stop and query OpenRC services
.Nd functions to query OpenRC services
.Sh LIBRARY
Run Command library (librc, -lrc)
.Sh SYNOPSIS
@@ -66,8 +65,6 @@ Run Command library (librc, -lrc)
.Ft "RC_STRINGLIST *" Fn rc_services_scheduled_by "const char *service"
.Ft bool Fn rc_service_schedule_clear "const char *service"
.Ft RC_SERVICE Fn rc_service_state "const char *service"
.Ft pid_t Fn rc_service_start "const char *service"
.Ft pid_t Fn rc_service_stop "const char *service"
.Ft bool Fo rc_service_started_daemon
.Fa "const char *service"
.Fa "const char *exec"
@@ -176,16 +173,6 @@ clears these scheduled services for
.Fa service .
The return value is a bitmask, where more than one state can apply.
.Pp
.Fn rc_service_start
starts
.Fa service ,
returning the pid of new process.
.Pp
.Fn rc_service_stop
stops
.Fa service ,
returning the pid of new process.
.Pp
.Fn rc_service_started_daemon
checks to see if
.Fa service

View File

@@ -145,6 +145,10 @@ stopping schedule.
If not specified then a default value of SIGTERM/5 is
assumed.
.El
.Sh ENVIRONMENT
.Va SSD_NICELEVEL
can also set the scheduling priority of the daemon, but the command line
option takes precedence.
.Sh NOTE
.Nm
uses

View File

@@ -10,14 +10,3 @@ include ${MK}/os-${OS}.mk
RC_LIB= /$(LIBNAME)/rc
_PREFIX_SH= if test -n "${PREFIX}" && test "${PREFIX}" != "/"; then echo "-DPREFIX=\\\"${PREFIX}\\\""; else echo ""; fi
_PREFIX!= ${_PREFIX_SH}
CFLAGS+= ${_PREFIX}$(shell ${_PREFIX_SH})
_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})
_LCL_PREFIX_SH= if test -n "${LOCAL_PREFIX}" && test "${LOCAL_PREFIX}" != "/" && test "${LOCAL_PREFIX}" != "${PREFIX}"; then echo "-DLOCAL_PREFIX=\\\"${LOCAL_PREFIX}\\\""; else echo ""; fi
_LCL_PREFIX!= ${_LCL_PREFIX_SH}
CFLAGS+= ${_LCL_PREFIX}$(shell ${_LCL_PREFIX_SH})

View File

@@ -58,8 +58,8 @@ _system_ntp()
local servers= buffer= x=
eval servers=\$ntp_servers_${IFVAR}
[ -z ${servers} ] && servers=${ntp_servers}
[ -z ${servers} ] && return 0
[ -z "${servers}" ] && servers=${ntp_servers}
[ -z "${servers}" ] && return 0
buffer="# Generated by net-scripts for interface ${IFACE}\n"
buffer="${buffer}restrict default noquery notrust nomodify\n"

View File

@@ -66,7 +66,7 @@ vlan_pre_start()
vlan_post_start()
{
local vlans=
eval vlans=\$vlans_${IFACE}
eval vlans=\$vlans_${IFVAR}
[ -z "${vlans}" ] && return 0
_check_vlan || return 1
@@ -86,13 +86,13 @@ vlan_post_start()
yesno ${s:-yes} || continue
# We need to work out the interface name of our new vlan id
local ifname="$( \
sed -n -e 's/^\([^[:space:]]*\) *| '"${vlan}"' *| .*'"${iface}"'$/\1/p' \
local ifname="$(sed -n -e \
's/^\([^[:space:]]*\) *| '"${vlan}"' *| .*'"${iface}"'$/\1/p' \
/proc/net/vlan/config )"
mark_service_started "net.${ifname}"
(
export RC_SVCNAME="net.${ifname}"
start
start
) || mark_service_stopped "net.${ifname}"
done

View File

@@ -6,6 +6,8 @@ LEVELDIR= ${DESTDIR}/${SYSCONFDIR}/runlevels
BOOTDIR= ${LEVELDIR}/boot
DEFAULTDIR= ${LEVELDIR}/default
INITDIR= ../init.d
MK= ../mk
include ${MK}/sys.mk
include ${MK}/os.mk
@@ -19,7 +21,8 @@ install:
${INSTALL} -d ${BOOTDIR} || exit $$?; \
for x in ${BOOT}; do \
if test -n "${PREFIX}"; then \
grep -q "keyword .*noprefix" ${SYSCONFDIR}/init.d/"$$x" && continue; \
test "$$x" = "net.lo" -o "$$x" = "net.lo0" && continue; \
grep -q "keyword .*noprefix" ${INITDIR}/"$$x" && continue; \
fi; \
ln -snf ${PREFIX}/etc/init.d/"$$x" ${BOOTDIR}/"$$x" || exit $$?; \
done \
@@ -28,7 +31,7 @@ install:
${INSTALL} -d ${DEFAULTDIR} || exit $$?; \
for x in ${DEFAULT}; do \
if test -n "${PREFIX}"; then \
grep -q "keyword .*noprefix" ${SYSCONFDIR}/init.d/"$$x" && continue; \
grep -q "keyword .*noprefix" ${INITDIR}/"$$x" && continue; \
fi; \
ln -snf ${PREFIX}/etc/init.d/"$$x" ${DEFAULTDIR}/"$$x" || exit $$?; done \
fi

View File

@@ -1,2 +1,2 @@
BOOT+= hwclock consolefont keymaps modules mtab net.lo procfs
DEFAULT+= hdparm
BOOT+= hwclock consolefont keymaps modules mtab net.lo procfs \
termencoding

View File

@@ -38,12 +38,17 @@ yesno()
esac
}
rc_runlevel() {
rc-status --runlevel
}
_sanitize_path()
{
local IFS=":" p= path=
for p in ${PATH}; do
case "${p}" in
@PREFIX@/lib/rc/sbin|@PREFIX@/bin|@PREFIX@/sbin|/usr/bin|/usr/sbin);;
@PREFIX@/@LIB@/rc/bin|@PREFIX@/@LIB@/rc/sbin);;
@PREFIX@/bin|@PREFIX@/sbin|/usr/bin|/usr/sbin);;
@PKG_PREFIX@/bin|@PKG_PREFIX@/sbin);;
@LOCAL_PREFIX@/bin|@LOCAL_PREFIX@/sbin);;
*) path="${path}${path:+:}${p}";;
@@ -66,7 +71,7 @@ _PREFIX=@PREFIX@
_PKG_PREFIX=@PKG_PREFIX@
_LOCAL_PREFIX=@LOCAL_PREFIX@
_LOCAL_PREFIX=${_LOCAL_PREFIX:-/usr/local}
_PATH=@PREFIX@/lib/rc/bin
_PATH=@PREFIX@/@LIB@/rc/bin
case "${_PREFIX}" in
"${_PKG_PREFIX}"|"${_LOCAL_PREFIX}") ;;
*) _PATH="${_PATH}:${_PREFIX}/bin:${_PREFIX}/sbin";;
@@ -79,8 +84,9 @@ fi
if [ -n "${_LOCAL_PREFIX}" ]; then
_PATH="${_PATH}:${_LOCAL_PREFIX}/bin:${_LOCAL_PREFIX}/sbin"
fi
export PATH="${_PATH}:$(_sanitize_path "${PATH}")"
unset _sanitize_path _PREFIX _PKG_PREFIX _LOCAL_PREFIX _PATH
_path="$(_sanitize_path "${PATH}")"
export PATH="${_PATH}${_path:+:}${_path}"
unset _sanitize_path _PREFIX _PKG_PREFIX _LOCAL_PREFIX _PATH _path
for arg; do
case "${arg}" in
@@ -99,7 +105,7 @@ else
# the last ecmd
for _e in ebegin eend error errorn einfo einfon ewarn ewarnn ewend \
vebegin veend veinfo vewarn vewend; do
eval "${_e}() { local _r; @PREFIX@/lib/rc/bin/${_e} \"\$@\"; _r=$?; \
eval "${_e}() { local _r; @PREFIX@/@LIB@/rc/bin/${_e} \"\$@\"; _r=$?; \
export EINFO_LASTCMD=${_e}; return \$_r; }"
done
unset _e

View File

@@ -8,7 +8,7 @@ retval=0
# the old service state data
if [ "${RC_SVCDIR}" != "/" ] && mkdir "${RC_SVCDIR}/.test.$$" 2>/dev/null; then
rmdir "${RC_SVCDIR}/.test.$$"
for x in ${RC_SVCDIR:-/lib/rc/init.d}/*; do
for x in ${RC_SVCDIR:-/@LIB@/rc/init.d}/*; do
[ -e "${x}" ] || continue
case ${x##*/} in
depconfig|deptree|ksoftlevel|rc.log);;

View File

@@ -96,6 +96,9 @@ if ${mountproc}; then
fi
unset mountproc
# Re-load RC_SYS if empty now we have /proc mounted
[ -z "${RC_SYS}" ] && export RC_SYS="$(rc --sys)"
# Read off the kernel commandline to see if there's any special settings
# especially check to see if we need to set the CDBOOT environment variable
# Note: /proc MUST be mounted

View File

@@ -4,15 +4,15 @@
has_addon()
{
[ -e "${RC_LIBDIR}/addons/$1.sh" ] || [ -e /lib/rcscripts/addons/"$1".sh ]
[ -e "${RC_LIBDIR}/addons/$1.sh" ] || [ -e /@LIB@/rcscripts/addons/"$1".sh ]
}
import_addon()
{
if [ -e "${RC_LIBDIR}/addons/$1.sh" ]; then
. "${RC_LIBDIR}/addons/$1.sh"
elif [ -e /lib/rcscripts/addons/"$1".sh ]; then
. /lib/rcscripts/addons/"$1".sh
elif [ -e /@LIB@/rcscripts/addons/"$1".sh ]; then
. /@LIB@/rcscripts/addons/"$1".sh
else
return 1
fi
@@ -75,6 +75,6 @@ get_bootparam()
# Add our sbin to $PATH
case "${PATH}" in
@PREFIX@/lib/rc/sbin|@PREFIX@/lib/rc/sbin:*);;
*) export PATH="@PREFIX@/lib/rc/sbin:${PATH}";;
"${RC_LIBDIR}"/sbin|"${RC_LIBDIR}"/sbin:*);;
*) export PATH="${RC_LIBDIR}/sbin:${PATH}";;
esac

View File

@@ -9,17 +9,17 @@ tret=0
ebegin "Testing yesno()"
for f in yes YES Yes true TRUE True 1 ; do
if ! yesno ${f} ; then
((tret+=1))
tret=$((${tret} + 1))
echo "!${f}!"
fi
done
for f in no NO No false FALSE False 0 ; do
if yesno ${f} ; then
((tret+=1))
tret=$(({$tret} + 1))
echo "!${f}!"
fi
done
eend ${tret}
((ret+=tret))
ret=$((${ret} + ${tret}))
exit ${ret}

View File

@@ -37,45 +37,10 @@
#include <stdbool.h>
#include <string.h>
#ifndef LIB
# define LIB "lib"
#endif
#ifdef PREFIX
# define RC_PREFIX PREFIX
#else
# define RC_PREFIX
#endif
#ifndef SYSCONFDIR
# define SYSCONFDIR RC_PREFIX "/etc"
#endif
#define RC_LEVEL_BOOT "boot"
#define RC_LEVEL_DEFAULT "default"
#define RC_LIBDIR RC_PREFIX "/" LIB "/rc"
#define RC_SVCDIR RC_LIBDIR "/init.d"
#define RC_DEPTREE_CACHE RC_SVCDIR "/deptree"
#define RC_RUNLEVELDIR SYSCONFDIR "/runlevels"
#define RC_INITDIR SYSCONFDIR "/init.d"
#define RC_CONFDIR SYSCONFDIR "/conf.d"
/* PKG_PREFIX is where packages are installed if different from the base OS
* On Gentoo this is normally unset, on FreeBSD /usr/local and on NetBSD
* /usr/pkg. */
#ifdef PKG_PREFIX
# define RC_PKG_INITDIR PKG_PREFIX "/etc/init.d"
# define RC_PKG_CONFDIR PKG_PREFIX "/etc/conf.d"
#endif
/* LOCAL_PREFIX is for user written stuff, which the base OS and package
* manger don't touch. */
#ifdef LOCAL_PREFIX
# define RC_LOCAL_INITDIR LOCAL_PREFIX "/etc/init.d"
# define RC_LOCAL_CONFDIR LOCAL_PREFIX "/etc/conf.d"
#endif
#define RC_KRUNLEVEL RC_SVCDIR "/krunlevel"
#define RC_STARTING RC_SVCDIR "/rc.starting"
#define RC_STOPPING RC_SVCDIR "/rc.stopping"
@@ -85,8 +50,6 @@
#define RC_SVCDIR_STARTED RC_SVCDIR "/started"
#define RC_SVCDIR_COLDPLUGGED RC_SVCDIR "/coldplugged"
#define RC_PLUGINDIR RC_LIBDIR "/plugins"
#define ERRX fprintf (stderr, "out of memory\n"); exit (1)
#ifdef lint
@@ -98,7 +61,6 @@
# define _unused
#endif
/* Some libc implemntations don't have these */
#ifndef STAILQ_CONCAT
#define STAILQ_CONCAT(head1, head2) do { \
@@ -196,6 +158,10 @@ void env_filter(void);
void env_config(void);
bool service_plugable(const char *service);
int signal_setup(int sig, void (*handler)(int));
pid_t exec_service(const char *, const char *);
#define service_start(service) exec_service(service, "start");
#define service_stop(service) exec_service(service, "stop");
/* basename_c never modifies the argument. As such, if there is a trailing
* slash then an empty string is returned. */

View File

@@ -51,6 +51,8 @@
# endif
#endif
__BEGIN_DECLS
/*! @brief Color types to use */
typedef enum
{
@@ -141,4 +143,5 @@ void eoutdentv(void);
/*! @brief Prefix each einfo line with something */
void eprefix(const char * __EINFO_RESTRICT);
__END_DECLS
#endif

View File

@@ -13,3 +13,4 @@ librc.a
librc.so.1
librc.so
.depend
rc.h

View File

@@ -5,8 +5,6 @@ SRCS= librc.c librc-daemon.c librc-depend.c librc-misc.c \
INCS= rc.h
VERSION_MAP= rc.map
CFLAGS+= -DLIB=\"${LIBNAME}\"
CFLAGS+= -DSYSCONFDIR=\"${SYSCONFDIR}\"
LDADD+= ${LIBKVM}
CFLAGS+= -I../includes
@@ -15,3 +13,30 @@ MK= ../../mk
include ${MK}/lib.mk
include ${MK}/cc.mk
include ${MK}/debug.mk
# Massage our header file for our dirs
SED_CMD= -e 's:@PREFIX@:${PREFIX}:g'
SED_CMD+= -e 's:@LIB@:${LIBNAME}:g'
SED_CMD+= -e 's:@SYSCONFDIR@:${SYSCONFDIR}:g'
_PKG_PREFIX_SH= if test -n "${PKG_PREFIX}" && test "${PKG_PREFIX}" != "/" && test "${PKG_PREFIX}" != "${PREFIX}"; then \
echo "-e 's:@PKG_PREFIX@:${PKG_PREFIX}:g'"; \
else \
echo "-e 's:.*@PKG_PREFIX@.*:\#undef RC_PKG_PREFIX:g'"; \
fi
_PKG_PREFIX!= ${_PKG_PREFIX_SH}
SED_CMD+= ${_PKG_PREFIX}$(shell ${_PKG_PREFIX_SH})
_LCL_PREFIX_SH= if test -n "${LOCAL_PREFIX}" && test "${LOCAL_PREFIX}" != "/" && test "${LOCAL_PREFIX}" != "${PREFIX}"; then \
echo "-e 's:@LOCAL_PREFIX@:${LOCAL_PREFIX}:g'"; \
else \
echo "-e 's:@LOCAL_PREFIX@::g'"; \
fi
_LCL_PREFIX!= ${_LCL_PREFIX_SH}
SED_CMD+= ${_LCL_PREFIX}$(shell ${_LCL_PREFIX_SH})
.SUFFIXES: .h.in .h
.h.in.h:
${SED} ${SED_CMD} $< > $@
${SRCS}: rc.h
CLEANFILES+= rc.h

View File

@@ -478,17 +478,17 @@ RC_STRINGLIST *rc_deptree_depend(const RC_DEPTREE *deptree,
}
librc_hidden_def(rc_deptree_depend)
RC_STRINGLIST *rc_deptree_depends (const RC_DEPTREE *deptree,
const RC_STRINGLIST *types,
const RC_STRINGLIST *services,
const char *runlevel, int options)
RC_STRINGLIST *rc_deptree_depends(const RC_DEPTREE *deptree,
const RC_STRINGLIST *types,
const RC_STRINGLIST *services,
const char *runlevel, int options)
{
RC_STRINGLIST *sorted = NULL;
RC_STRINGLIST *visited = rc_stringlist_new();
RC_DEPINFO *di;
const RC_STRING *service;
bootlevel = getenv ("RC_BOOTLEVEL");
bootlevel = getenv("RC_BOOTLEVEL");
if (! bootlevel)
bootlevel = RC_LEVEL_BOOT;
@@ -515,7 +515,7 @@ RC_STRINGLIST *rc_deptree_order(const RC_DEPTREE *deptree,
RC_STRINGLIST *types;
RC_STRINGLIST *services;
bootlevel = getenv ("RC_BOOTLEVEL");
bootlevel = getenv("RC_BOOTLEVEL");
if (! bootlevel)
bootlevel = RC_LEVEL_BOOT;
@@ -525,8 +525,7 @@ RC_STRINGLIST *rc_deptree_order(const RC_DEPTREE *deptree,
strcmp (runlevel, RC_LEVEL_REBOOT) == 0)
{
list = rc_services_in_state(RC_SERVICE_STARTED);
list2 = rc_services_in_state (RC_SERVICE_INACTIVE);
list2 = rc_services_in_state(RC_SERVICE_INACTIVE);
if (list2) {
if (list) {
TAILQ_CONCAT(list, list2, entries);
@@ -534,8 +533,7 @@ RC_STRINGLIST *rc_deptree_order(const RC_DEPTREE *deptree,
} else
list = list2;
}
list2 = rc_services_in_state (RC_SERVICE_STARTING);
list2 = rc_services_in_state(RC_SERVICE_STARTING);
if (list2) {
if (list) {
TAILQ_CONCAT(list, list2, entries);
@@ -543,20 +541,28 @@ RC_STRINGLIST *rc_deptree_order(const RC_DEPTREE *deptree,
} else
list = list2;
}
TAILQ_CONCAT(list, list2, entries);
} else {
list = rc_services_in_runlevel (runlevel);
list = rc_services_in_runlevel(runlevel);
/* Add coldplugged services */
list2 = rc_services_in_state (RC_SERVICE_COLDPLUGGED);
TAILQ_CONCAT(list, list2, entries);
free(list2);
list2 = rc_services_in_state(RC_SERVICE_COLDPLUGGED);
if (list2) {
if (list) {
TAILQ_CONCAT(list, list2, entries);
free(list2);
} else
list = list2;
}
/* If we're not the boot runlevel then add that too */
if (strcmp (runlevel, bootlevel) != 0) {
list2 = rc_services_in_runlevel (bootlevel);
TAILQ_CONCAT(list, list2, entries);
free(list2);
if (list2) {
if (list) {
TAILQ_CONCAT(list, list2, entries);
free(list2);
} else
list = list2;
}
}
}
@@ -569,8 +575,8 @@ RC_STRINGLIST *rc_deptree_order(const RC_DEPTREE *deptree,
services = rc_deptree_depends(deptree, types, list, runlevel,
RC_DEP_STRICT | RC_DEP_TRACE | options);
rc_stringlist_free (list);
rc_stringlist_free (types);
rc_stringlist_free(list);
rc_stringlist_free(types);
return services;
}

View File

@@ -214,6 +214,13 @@ const char *rc_sys(void)
return RC_SYS_JAIL;
#endif
#ifdef __NetBSD__
if (exists("/kern/xen/privcmd"))
return RC_SYS_XEN0;
if (exists("/kern/xen"))
return RC_SYS_XENU;
#endif
#ifdef __linux__
if (exists("/proc/xen")) {
if (file_regex("/proc/xen/capabilities", "control_d"))
@@ -494,7 +501,7 @@ bool rc_service_mark(const char *service, const RC_SERVICE state)
base = basename_c(service);
if (state != RC_SERVICE_STOPPED) {
if (! exists(init)) {
if (!exists(init)) {
free(init);
return false;
}
@@ -540,7 +547,10 @@ bool rc_service_mark(const char *service, const RC_SERVICE state)
symlink(init, was);
skip_wasinactive = true;
}
unlink(file);
if (unlink(file) == -1) {
free(init);
return false;
}
}
}
}
@@ -673,95 +683,6 @@ bool rc_service_value_set(const char *service, const char *option,
}
librc_hidden_def(rc_service_value_set)
static pid_t _exec_service(const char *service, const char *arg)
{
char *file;
char fifo[PATH_MAX];
pid_t pid = -1;
sigset_t full;
sigset_t old;
struct sigaction sa;
file = rc_service_resolve(service);
if (! exists(file)) {
rc_service_mark(service, RC_SERVICE_STOPPED);
free(file);
return 0;
}
/* We create a fifo so that other services can wait until we complete */
snprintf(fifo, sizeof(fifo), RC_SVCDIR "/exclusive/%s",
basename_c(service));
if (mkfifo(fifo, 0600) != 0 && errno != EEXIST) {
free(file);
return -1;
}
/* We need to block signals until we have forked */
memset(&sa, 0, sizeof (sa));
sa.sa_handler = SIG_DFL;
sigemptyset(&sa.sa_mask);
sigfillset(&full);
sigprocmask(SIG_SETMASK, &full, &old);
if ((pid = fork()) == 0) {
/* Restore default handlers */
sigaction(SIGCHLD, &sa, NULL);
sigaction(SIGHUP, &sa, NULL);
sigaction(SIGINT, &sa, NULL);
sigaction(SIGQUIT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
sigaction(SIGUSR1, &sa, NULL);
sigaction(SIGWINCH, &sa, NULL);
/* Unmask signals */
sigprocmask(SIG_SETMASK, &old, NULL);
/* Safe to run now */
execl(file, file, arg, (char *) NULL);
fprintf(stderr, "unable to exec `%s': %s\n",
file, strerror(errno));
unlink(fifo);
_exit(EXIT_FAILURE);
}
if (pid == -1)
fprintf(stderr, "fork: %s\n",strerror (errno));
sigprocmask(SIG_SETMASK, &old, NULL);
free(file);
return pid;
}
pid_t rc_service_stop(const char *service)
{
RC_SERVICE state = rc_service_state(service);
if (state & RC_SERVICE_FAILED)
return -1;
if (state & RC_SERVICE_STOPPED)
return 0;
return _exec_service(service, "stop");
}
librc_hidden_def(rc_service_stop)
pid_t rc_service_start(const char *service)
{
RC_SERVICE state = rc_service_state(service);
if (state & RC_SERVICE_FAILED)
return -1;
if (! state & RC_SERVICE_STOPPED)
return 0;
return _exec_service(service, "start");
}
librc_hidden_def(rc_service_start)
bool rc_service_schedule_start(const char *service,
const char *service_to_start)

View File

@@ -104,8 +104,6 @@ librc_hidden_proto(rc_service_mark)
librc_hidden_proto(rc_service_resolve)
librc_hidden_proto(rc_service_schedule_clear)
librc_hidden_proto(rc_service_schedule_start)
librc_hidden_proto(rc_service_start)
librc_hidden_proto(rc_service_stop)
librc_hidden_proto(rc_services_in_runlevel)
librc_hidden_proto(rc_services_in_state)
librc_hidden_proto(rc_services_scheduled)

View File

@@ -32,6 +32,33 @@
#include <stdbool.h>
#include <stdio.h>
__BEGIN_DECLS
#define RC_SYSCONFDIR "@SYSCONFDIR@"
#define RC_LIBDIR "@PREFIX@/@LIB@/rc"
#define RC_SVCDIR RC_LIBDIR "/init.d"
#define RC_PLUGINDIR RC_LIBDIR "/plugins"
#define RC_RUNLEVELDIR RC_SYSCONFDIR "/runlevels"
#define RC_INITDIR RC_SYSCONFDIR "/init.d"
#define RC_CONFDIR RC_SYSCONFDIR "/conf.d"
/* PKG_PREFIX is where packages are installed if different from the base OS
* On Gentoo this is normally unset, on FreeBSD /usr/local and on NetBSD
* /usr/pkg. */
#define RC_PKG_PREFIX "@PKG_PREFIX@"
#ifdef RC_PKG_PREFIX
# define RC_PKG_INITDIR RC_PKG_PREFIX "/etc/init.d"
# define RC_PKG_CONFDIR RC_PKG_PREFIX "/etc/conf.d"
#endif
/* LOCAL_PREFIX is for user written stuff, which the base OS and package
* manger don't touch. */
#define RC_LOCAL_PREFIX "@LOCAL_PREFIX@"
#ifdef RC_LOCAL_PREFIX
# define RC_LOCAL_INITDIR RC_LOCAL_PREFIX "/etc/init.d"
# define RC_LOCAL_CONFDIR RC_LOCAL_PREFIX "/etc/conf.d"
#endif
/* A doubly linked list using queue(3) for ease of use */
typedef struct rc_string {
char *value;
@@ -172,16 +199,6 @@ bool rc_service_schedule_clear(const char *);
* @return state of the service */
RC_SERVICE rc_service_state(const char *);
/*! Start a service
* @param service to start
* @return pid of the service starting process */
pid_t rc_service_start(const char *);
/*! Stop a service
* @param service to stop
* @return pid of service stopping process */
pid_t rc_service_stop(const char *);
/*! Check if the service started the daemon
* @param service to check
* @param exec to check
@@ -447,4 +464,5 @@ typedef LIST_HEAD(rc_pidlist, rc_pid) RC_PIDLIST;
* @return NULL terminated list of pids */
RC_PIDLIST *rc_find_pids(const char *const *, const char *, uid_t, pid_t);
__END_DECLS
#endif

View File

@@ -32,8 +32,6 @@ global:
rc_service_resolve;
rc_service_schedule_clear;
rc_service_schedule_start;
rc_service_start;
rc_service_stop;
rc_services_in_runlevel;
rc_services_in_state;
rc_services_scheduled;

View File

@@ -39,8 +39,6 @@ include ${MK}/cc.mk
include ${MK}/debug.mk
CFLAGS+= -I../includes -I../librc -I../libeinfo
CFLAGS+= -DLIB=\"${LIBNAME}\"
CFLAGS+= -DSYSCONFDIR=\"${SYSCONFDIR}\"
include ${MK}/${MKTERMCAP}.mk
LDADD+= ${LIBDL} ${LIBKVM}

View File

@@ -110,7 +110,7 @@ static int do_e(int argc, char **argv)
} else if (strcmp(applet, "esyslog") == 0 ||
strcmp(applet, "elog") == 0) {
p = strchr(argv[0], '.');
if ((level = syslog_decode(p + 1, prioritynames)) == -1)
if (!p || (level = syslog_decode(p + 1, prioritynames)) == -1)
eerrorx("%s: invalid log level `%s'", applet, argv[0]);
if (argc < 3)

View File

@@ -43,16 +43,17 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "einfo.h"
#include "rc.h"
#include "rc-misc.h"
#define PROFILE_ENV SYSCONFDIR "/profile.env"
#define PROFILE_ENV RC_SYSCONFDIR "/profile.env"
#define SYS_WHITELIST RC_LIBDIR "/conf.d/env_whitelist"
#define USR_WHITELIST SYSCONFDIR "/conf.d/env_whitelist"
#define RC_CONF SYSCONFDIR "/rc.conf"
#define RC_CONF_OLD SYSCONFDIR "/conf.d/rc"
#define USR_WHITELIST RC_SYSCONFDIR "/conf.d/env_whitelist"
#define RC_CONF RC_SYSCONFDIR "/rc.conf"
#define RC_CONF_OLD RC_SYSCONFDIR "/conf.d/rc"
#define PATH_PREFIX RC_LIBDIR "/bin:/bin:/sbin:/usr/bin:/usr/sbin"
@@ -310,3 +311,65 @@ int signal_setup(int sig, void (*handler)(int))
sa.sa_handler = handler;
return sigaction(sig, &sa, NULL);
}
pid_t exec_service(const char *service, const char *arg)
{
char *file;
char fifo[PATH_MAX];
pid_t pid = -1;
sigset_t full;
sigset_t old;
struct sigaction sa;
file = rc_service_resolve(service);
if (! exists(file)) {
rc_service_mark(service, RC_SERVICE_STOPPED);
free(file);
return 0;
}
/* We create a fifo so that other services can wait until we complete */
snprintf(fifo, sizeof(fifo), RC_SVCDIR "/exclusive/%s",
basename_c(service));
if (mkfifo(fifo, 0600) != 0 && errno != EEXIST) {
free(file);
return -1;
}
/* We need to block signals until we have forked */
memset(&sa, 0, sizeof (sa));
sa.sa_handler = SIG_DFL;
sigemptyset(&sa.sa_mask);
sigfillset(&full);
sigprocmask(SIG_SETMASK, &full, &old);
if ((pid = fork()) == 0) {
/* Restore default handlers */
sigaction(SIGCHLD, &sa, NULL);
sigaction(SIGHUP, &sa, NULL);
sigaction(SIGINT, &sa, NULL);
sigaction(SIGQUIT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
sigaction(SIGUSR1, &sa, NULL);
sigaction(SIGWINCH, &sa, NULL);
/* Unmask signals */
sigprocmask(SIG_SETMASK, &old, NULL);
/* Safe to run now */
execl(file, file, arg, (char *) NULL);
fprintf(stderr, "unable to exec `%s': %s\n",
file, strerror(errno));
unlink(fifo);
_exit(EXIT_FAILURE);
}
if (pid == -1)
fprintf(stderr, "fork: %s\n",strerror (errno));
sigprocmask(SIG_SETMASK, &old, NULL);
free(file);
return pid;
}

View File

@@ -51,6 +51,7 @@ static const struct option longopts[] = {
longopts_COMMON
};
static const char * const longopts_help[] = {
"tests if the service exists or not",
"list all available services",
longopts_help_COMMON
};

View File

@@ -42,7 +42,8 @@
extern const char *applet;
static bool test_crashed = false;
static const char *const types_nua[] = { "ineed", "iuse", "iafter", NULL };
static RC_DEPTREE *deptree = NULL;
static RC_STRINGLIST *types = NULL;
bool _rc_can_find_pids(void)
{
@@ -73,7 +74,7 @@ bool _rc_can_find_pids(void)
return retval;
}
static void print_level(char *level)
static void print_level(const char *level)
{
printf ("Runlevel: ");
if (isatty(fileno(stdout)))
@@ -120,6 +121,46 @@ static void print_service(const char *service)
ebracket(cols, color, status);
}
static void print_services(const char *runlevel, RC_STRINGLIST *services)
{
RC_STRINGLIST *l = NULL;
RC_STRING *s, *t;
char *r = NULL;
if (! services)
return;
if (! deptree)
deptree = _rc_deptree_load(NULL);
if (! deptree) {
TAILQ_FOREACH(s, services, entries)
if (!runlevel ||
rc_service_in_runlevel(s->value, runlevel))
print_service(s->value);
return;
}
if (! types) {
types = rc_stringlist_new();
rc_stringlist_add(types, "ineed");
rc_stringlist_add(types, "iuse");
rc_stringlist_add(types, "iafter");
}
if (!runlevel)
r = rc_runlevel_get();
l = rc_deptree_depends(deptree, types, services, r ? r : runlevel,
RC_DEP_STRICT | RC_DEP_TRACE | RC_DEP_START);
free(r);
TAILQ_FOREACH(s, l, entries) {
TAILQ_FOREACH(t, services, entries)
if (strcmp(t->value, s->value) == 0)
break;
if (!t)
continue;
if (!runlevel || rc_service_in_runlevel(s->value, runlevel))
print_service(s->value);
}
rc_stringlist_free(l);
}
#include "_usage.h"
#define extraopts "[runlevel1] [runlevel2] ..."
#define getoptstring "alrsu" getoptstring_COMMON
@@ -143,16 +184,11 @@ static const char * const longopts_help[] = {
int rc_status(int argc, char **argv)
{
RC_DEPTREE *deptree = NULL;
RC_STRINGLIST *levels = NULL;
RC_STRINGLIST *services;
RC_STRINGLIST *types = NULL;
RC_STRINGLIST *ordered;
RC_STRING *s;
RC_STRING *l;
RC_STRING *s, *l, *t;
char *p;
int opt;
int depopts = RC_DEP_STRICT | RC_DEP_START | RC_DEP_TRACE;
test_crashed = _rc_can_find_pids();
@@ -166,35 +202,33 @@ int rc_status(int argc, char **argv)
levels = rc_runlevel_list();
TAILQ_FOREACH (l, levels, entries)
printf("%s\n", l->value);
rc_stringlist_free(levels);
exit(EXIT_SUCCESS);
goto exit;
/* NOTREACHED */
case 'r':
p = rc_runlevel_get ();
p = rc_runlevel_get();
printf("%s\n", p);
free(p);
exit(EXIT_SUCCESS);
goto exit;
/* NOTREACHED */
case 's':
services = rc_services_in_runlevel(NULL);
TAILQ_FOREACH(s, services, entries)
print_service(s->value);
rc_stringlist_free(services);
exit (EXIT_SUCCESS);
print_services(NULL, services);
goto exit;
/* NOTREACHED */
case 'u':
services = rc_services_in_runlevel(NULL);
levels = rc_runlevel_list();
TAILQ_FOREACH(s, services, entries) {
TAILQ_FOREACH_SAFE(s, services, entries, t) {
TAILQ_FOREACH(l, levels, entries)
if (rc_service_in_runlevel(s->value, l->value))
if (rc_service_in_runlevel(s->value, l->value)) {
TAILQ_REMOVE(services, s, entries);
free(s->value);
free(s);
break;
if (! l)
print_service(s->value);
}
}
rc_stringlist_free(levels);
rc_stringlist_free(services);
exit (EXIT_SUCCESS);
print_services(NULL, services);
goto exit;
/* NOTREACHED */
case_RC_COMMON_GETOPT
@@ -216,27 +250,34 @@ int rc_status(int argc, char **argv)
TAILQ_FOREACH(l, levels, entries) {
print_level(l->value);
services = rc_services_in_runlevel(l->value);
if (! services)
continue;
if (deptree) {
if (! types) {
types = rc_stringlist_new();
rc_stringlist_add(types, "ineed");
rc_stringlist_add(types, "iuse");
rc_stringlist_add(types, "iafter");
}
ordered = rc_deptree_depends(deptree, types, services,
l->value, depopts);
rc_stringlist_free(services);
services = ordered;
ordered = NULL;
}
TAILQ_FOREACH(s, services, entries)
if (rc_service_in_runlevel(s->value, l->value))
print_service(s->value);
print_services(l->value, services);
rc_stringlist_free(services);
services = NULL;
}
/* Show unassigned running too */
if (argc < 2) {
print_level("UNASSIGNED");
services = rc_services_in_runlevel(NULL);
rc_stringlist_free(levels);
levels = rc_runlevel_list();
TAILQ_FOREACH_SAFE(s, services, entries, t) {
TAILQ_FOREACH(l, levels, entries) {
if (rc_service_in_runlevel(s->value, l->value) ||
rc_service_state(s->value) & RC_SERVICE_STOPPED)
{
TAILQ_REMOVE(services, s, entries);
free(s->value);
free(s);
break;
}
}
}
print_services(NULL, services);
}
exit:
rc_stringlist_free(services);
rc_stringlist_free(types);
rc_stringlist_free(levels);
rc_deptree_free(deptree);

View File

@@ -691,12 +691,15 @@ static void do_newlevel(const char *newlevel)
run_script(INITSH);
#ifdef __linux__
/* If we requested a softlevel, save it now */
set_krunlevel(NULL);
if ((cmd = proc_getent("softlevel"))) {
/* If we requested a runlevel, save it now */
if ((cmd = proc_getent("rc_runlevel"))) {
set_krunlevel(cmd);
free(cmd);
}
} else if ((cmd = proc_getent("softlevel"))) {
set_krunlevel(cmd);
free(cmd);
} else
set_krunlevel(NULL);
#endif
/* Setup our coldplugged services now */
@@ -771,6 +774,7 @@ static void do_stop_services(const char *newlevel, bool going_down, bool paralle
pid_t pid;
RC_STRING *service, *svc1, *svc2;
RC_STRINGLIST *deporder, *tmplist;
RC_SERVICE state;
if (! types_n) {
types_n = rc_stringlist_new();
@@ -779,12 +783,13 @@ static void do_stop_services(const char *newlevel, bool going_down, bool paralle
TAILQ_FOREACH_REVERSE(service, stop_services, rc_stringlist, entries)
{
if (rc_service_state(service->value) & RC_SERVICE_STOPPED)
state = rc_service_state(service->value);
if (state & RC_SERVICE_STOPPED || state & RC_SERVICE_FAILED)
continue;
/* We always stop the service when in these runlevels */
if (going_down || ! start_services) {
pid = rc_service_stop(service->value);
pid = service_stop(service->value);
if (pid > 0 && ! parallel)
rc_waitpid(pid);
continue;
@@ -832,7 +837,7 @@ static void do_stop_services(const char *newlevel, bool going_down, bool paralle
}
/* After all that we can finally stop the blighter! */
pid = rc_service_stop(service->value);
pid = service_stop(service->value);
if (pid > 0) {
add_pid(pid);
if (! parallel) {
@@ -848,44 +853,47 @@ static void do_start_services(bool parallel)
RC_STRING *service;
pid_t pid;
bool interactive = false;
RC_SERVICE state;
if (! rc_yesno(getenv("EINFO_QUIET")))
interactive = exists(INTERACTIVE);
TAILQ_FOREACH(service, start_services, entries) {
if (rc_service_state(service->value) & RC_SERVICE_STOPPED) {
if (! interactive)
interactive = want_interactive();
state = rc_service_state(service->value);
if (!(state & RC_SERVICE_STOPPED) || state & RC_SERVICE_FAILED)
continue;
if (interactive) {
if (! interactive)
interactive = want_interactive();
if (interactive) {
interactive_retry:
printf("\n");
einfo("About to start the service %s",
service->value);
eindent();
einfo("1) Start the service\t\t2) Skip the service");
einfo("3) Continue boot process\t\t4) Exit to shell");
eoutdent();
printf("\n");
einfo("About to start the service %s",
service->value);
eindent();
einfo("1) Start the service\t\t2) Skip the service");
einfo("3) Continue boot process\t\t4) Exit to shell");
eoutdent();
interactive_option:
switch (read_key(true)) {
switch (read_key(true)) {
case '1': break;
case '2': continue;
case '3': interactive = false; break;
case '4': sulogin(true); goto interactive_retry;
default: goto interactive_option;
}
}
}
pid = rc_service_start(service->value);
/* Remember the pid if we're running in parallel */
if (pid > 0) {
add_pid(pid);
pid = service_start(service->value);
if (! parallel) {
rc_waitpid(pid);
remove_pid(pid);
}
/* Remember the pid if we're running in parallel */
if (pid > 0) {
add_pid(pid);
if (! parallel) {
rc_waitpid(pid);
remove_pid(pid);
}
}
}
@@ -930,11 +938,13 @@ static void handle_bad_signal(int sig)
static const struct option longopts[] = {
{ "override", 1, NULL, 'o' },
{ "service", 1, NULL, 's' },
{ "sys", 0, 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",
"output the RC system type, if any",
longopts_help_COMMON
};
#include "_usage.c"
@@ -949,7 +959,7 @@ int main(int argc, char **argv)
bool going_down = false;
int depoptions = RC_DEP_STRICT | RC_DEP_TRACE;
char krunlevel [PATH_MAX];
char pidstr[6];
char pidstr[10];
int opt;
bool parallel;
int regen = 0;
@@ -1023,6 +1033,12 @@ int main(int argc, char **argv)
execv(*argv, argv);
eerrorx("%s: %s", applet, strerror(errno));
/* NOTREACHED */
case 'S':
bootlevel = rc_sys();
if (bootlevel)
printf("%s\n", bootlevel);
exit(EXIT_SUCCESS);
/* NOTREACHED */
case_RC_COMMON_GETOPT
}
}
@@ -1036,7 +1052,7 @@ int main(int argc, char **argv)
snprintf(pidstr, sizeof(pidstr), "%d", getpid());
setenv("RC_PID", pidstr, 1);
/* Load current softlevel */
/* Load current runlevel */
bootlevel = getenv("RC_BOOTLEVEL");
runlevel = rc_runlevel_get();
@@ -1186,7 +1202,7 @@ int main(int argc, char **argv)
}
}
/* Save our softlevel now */
/* Save our runlevel now */
if (going_down)
rc_runlevel_set(newlevel);

View File

@@ -273,7 +273,7 @@ static void start_services(RC_STRINGLIST *list) {
" when %s has started",
svc->value, applet);
} else
rc_service_start(svc->value);
service_start(svc->value);
}
}
}
@@ -648,6 +648,19 @@ static void setup_types(void)
rc_stringlist_add(types_mua, "beforeme");
}
static bool in_list(RC_STRINGLIST *list, char *string)
{
RC_STRING *s;
if (! list)
return false;
TAILQ_FOREACH(s, list, entries)
if (strcmp(s->value, string) == 0)
return true;
return false;
}
static void svc_start(bool deps)
{
bool started;
@@ -727,7 +740,7 @@ static void svc_start(bool deps)
if (! rc_runlevel_starting() && use_services)
TAILQ_FOREACH(svc, use_services, entries)
if (rc_service_state(svc->value) & RC_SERVICE_STOPPED) {
pid_t pid = rc_service_start(svc->value);
pid_t pid = service_start(svc->value);
if (! rc_conf_yesno("rc_parallel"))
rc_waitpid(pid);
}
@@ -747,35 +760,29 @@ static void svc_start(bool deps)
/* Don't wait for services which went inactive but are now in
* starting state which we are after */
if (svcs & RC_SERVICE_STARTING &&
svcs & RC_SERVICE_WASINACTIVE) {
TAILQ_FOREACH(svc2, use_services, entries) {
if (strcmp (svc->value, svc2->value) == 0)
break;
}
if (! svc2)
svcs & RC_SERVICE_WASINACTIVE)
{
if (!in_list(need_services, svc->value) &&
!in_list(use_services, svc->value))
continue;
}
if (! svc_wait(svc->value))
eerror ("%s: timed out waiting for %s",
applet, svc->value);
if (! need_services)
continue;
if ((svcs = rc_service_state(svc->value)) & RC_SERVICE_STARTED)
continue;
TAILQ_FOREACH(svc2, need_services, entries) {
if (strcmp (svc->value, svc2->value) == 0) {
if (svcs & RC_SERVICE_INACTIVE ||
svcs & RC_SERVICE_WASINACTIVE)
{
if (! tmplist)
tmplist = rc_stringlist_new();
rc_stringlist_add(tmplist, svc->value);
} else
eerrorx("ERROR: cannot start %s as"
" %s would not start",
applet, svc->value);
}
if (in_list(need_services, svc->value)) {
if (svcs & RC_SERVICE_INACTIVE ||
svcs & RC_SERVICE_WASINACTIVE)
{
if (! tmplist)
tmplist = rc_stringlist_new();
rc_stringlist_add(tmplist, svc->value);
} else
eerrorx("ERROR: cannot start %s as"
" %s would not start",
applet, svc->value);
}
}
@@ -851,7 +858,7 @@ static void svc_start(bool deps)
if (services) {
TAILQ_FOREACH(svc, services, entries)
if (rc_service_state(svc->value) & RC_SERVICE_STOPPED)
rc_service_start(svc->value);
service_start(svc->value);
rc_stringlist_free(services);
services = NULL;
}
@@ -864,7 +871,7 @@ static void svc_start(bool deps)
if (services) {
TAILQ_FOREACH(svc2, services, entries)
if (rc_service_state(svc2->value) & RC_SERVICE_STOPPED)
rc_service_start(svc2->value);
service_start(svc2->value);
rc_stringlist_free(services);
services = NULL;
}
@@ -932,14 +939,14 @@ static void svc_stop(bool deps)
TAILQ_FOREACH_REVERSE(svc, services, rc_stringlist, entries) {
RC_SERVICE svcs = rc_service_state(svc->value);
if (svcs & RC_SERVICE_STARTED ||
svcs & RC_SERVICE_INACTIVE)
svcs & RC_SERVICE_INACTIVE)
{
svc_wait(svc->value);
svcs = rc_service_state(svc->value);
if (svcs & RC_SERVICE_STARTED ||
svcs & RC_SERVICE_INACTIVE)
svcs & RC_SERVICE_INACTIVE)
{
pid_t pid = rc_service_stop(svc->value);
pid_t pid = service_stop(svc->value);
if (! rc_conf_yesno("rc_parallel"))
rc_waitpid(pid);
if (! tmplist)
@@ -964,9 +971,9 @@ static void svc_stop(bool deps)
/* If shutting down, we should stop even
* if a dependant failed */
if (runlevel &&
(strcmp(runlevel, RC_LEVEL_SHUTDOWN) == 0 ||
strcmp(runlevel, RC_LEVEL_REBOOT) == 0 ||
strcmp(runlevel, RC_LEVEL_SINGLE) == 0))
(strcmp(runlevel, RC_LEVEL_SHUTDOWN) == 0 ||
strcmp(runlevel, RC_LEVEL_REBOOT) == 0 ||
strcmp(runlevel, RC_LEVEL_SINGLE) == 0))
continue;
rc_service_mark(service, RC_SERVICE_FAILED);
}
@@ -1077,7 +1084,7 @@ int runscript(int argc, char **argv)
{
bool deps = true;
bool doneone = false;
char pid[16];
char pidstr[10];
int retval;
int opt;
RC_STRING *svc;
@@ -1136,8 +1143,8 @@ int runscript(int argc, char **argv)
/* Set an env var so that we always know our pid regardless of any
subshells the init script may create so that our mark_service_*
functions can always instruct us of this change */
snprintf(pid, sizeof(pid), "%d", (int) getpid());
setenv("RC_RUNSCRIPT_PID", pid, 1);
snprintf(pidstr, sizeof(pidstr), "%d", (int) getpid());
setenv("RC_RUNSCRIPT_PID", pidstr, 1);
/* eprefix is kinda klunky, but it works for our purposes */
if (rc_conf_yesno("rc_parallel")) {
@@ -1299,7 +1306,8 @@ int runscript(int argc, char **argv)
}
} else if (strcmp(optarg, "zap") == 0) {
einfo("Manually resetting %s to stopped state", applet);
rc_service_mark(applet, RC_SERVICE_STOPPED);
if (!rc_service_mark(applet, RC_SERVICE_STOPPED))
eerrorx("rc_service_mark: %s", strerror(errno));
uncoldplug();
} else
svc_exec(optarg, NULL);

View File

@@ -2,6 +2,8 @@ all:
install:
gitignore:
check test::
./runtests.sh

View File

@@ -29,10 +29,8 @@ rc_service_mark
rc_service_resolve
rc_service_schedule_clear
rc_service_schedule_start
rc_service_start
rc_service_started_daemon
rc_service_state
rc_service_stop
rc_service_value_get
rc_service_value_set
rc_services_in_runlevel

View File

@@ -58,14 +58,10 @@ rc_service_schedule_clear
rc_service_schedule_clear@@RC_1.0
rc_service_schedule_start
rc_service_schedule_start@@RC_1.0
rc_service_start
rc_service_start@@RC_1.0
rc_service_started_daemon
rc_service_started_daemon@@RC_1.0
rc_service_state
rc_service_state@@RC_1.0
rc_service_stop
rc_service_stop@@RC_1.0
rc_service_value_get
rc_service_value_get@@RC_1.0
rc_service_value_set

View File

@@ -12,7 +12,9 @@ builddir=${builddir:-${srcdir}}
export LD_LIBRARY_PATH=${top_builddir}/src/libeinfo:${top_builddir}/src/librc:${LD_LIBRARY_PATH}
export PATH=${top_builddir}/src/rc:${PATH}
${MAKE:-make} -s -C ${top_srcdir}/src/rc links
cd ${top_srcdir}/src/rc
${MAKE:-make} links >/dev/null
cd -
. ${top_srcdir}/sh/functions.sh