Compare commits
40 Commits
openrc-0.4
...
openrc-0.4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3fc17f5966 | ||
|
|
522ab21fbf | ||
|
|
3d7b56f2e2 | ||
|
|
6bb44be2a3 | ||
|
|
415fe87d8c | ||
|
|
4f163f9b9a | ||
|
|
417a817d25 | ||
|
|
30a7a3a9bf | ||
|
|
5208a1de29 | ||
|
|
abcc4c5c72 | ||
|
|
fcf1cce549 | ||
|
|
3d37005a3d | ||
|
|
2243c01390 | ||
|
|
a52472c3c3 | ||
|
|
f23822e082 | ||
|
|
8a9a2d5fe9 | ||
|
|
a33554ab18 | ||
|
|
baf0ce64f5 | ||
|
|
26f70a5277 | ||
|
|
36c53e7551 | ||
|
|
5ca3345534 | ||
|
|
0298e4ffa0 | ||
|
|
a063035b37 | ||
|
|
213cef1739 | ||
|
|
386ee57432 | ||
|
|
631acff7aa | ||
|
|
877a328179 | ||
|
|
1efa64cae8 | ||
|
|
22959c3963 | ||
|
|
2464f9e93b | ||
|
|
d91201cb94 | ||
|
|
1c5ec9d161 | ||
|
|
f4b8366942 | ||
|
|
438665357b | ||
|
|
7ad40abf64 | ||
|
|
7e12abe035 | ||
|
|
4dba5b1ff1 | ||
|
|
1ff289e305 | ||
|
|
53e2bec385 | ||
|
|
9d9f17aa52 |
2
Makefile
2
Makefile
@@ -3,7 +3,7 @@
|
||||
# All rights reserved. Released under the 2-clause BSD license.
|
||||
|
||||
NAME= openrc
|
||||
VERSION= 0.4.0
|
||||
VERSION= 0.4.2
|
||||
PKG= ${NAME}-${VERSION}
|
||||
|
||||
SUBDIR= conf.d doc etc init.d man net sh src
|
||||
|
||||
@@ -29,7 +29,7 @@ cleanup_tmp_dir()
|
||||
if yesno ${wipe_tmp:-${WIPE_TMP:-yes}}; then
|
||||
ebegin "Wiping ${dir} directory"
|
||||
local startopts="-x . -depth"
|
||||
[ "${RC_UNAME}" = "Linux" ] && startopts=". -xdev -depth"
|
||||
[ "${RC_UNAME}" = Linux ] && startopts=". -xdev -depth"
|
||||
|
||||
# Faster than find
|
||||
rm -rf -- [b-ikm-pr-zA-Z0-9\.]*
|
||||
@@ -131,7 +131,7 @@ start()
|
||||
|
||||
if ${logw} || dir_writeable /var/log; then
|
||||
# Create an 'after-boot' dmesg log
|
||||
if [ "${RC_SYS}" != "VSERVER" -a "${RC_SYS}" != "OPENVZ" ]; then
|
||||
if [ "${RC_SYS}" != VSERVER -a "${RC_SYS}" != OPENVZ ]; then
|
||||
dmesg > /var/log/dmesg
|
||||
chmod 640 /var/log/dmesg
|
||||
fi
|
||||
@@ -144,9 +144,12 @@ start()
|
||||
stop()
|
||||
{
|
||||
# Write a halt record if we're shutting down
|
||||
case "${RC_RUNLEVEL}" in
|
||||
reboot|shutdown) [ "${RC_UNAME}" = "Linux" ] && halt -w;;
|
||||
esac
|
||||
if [ "${RC_RUNLEVEL}" = shutdown ]; then
|
||||
[ "${RC_UNAME}" = Linux ] && halt -w
|
||||
if [ "${RC_SYS}" = OPENVZ ]; then
|
||||
yesno ${RC_REBOOT} && printf "" >/reboot
|
||||
fi
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ description="Mount system critical filesystems in /dev."
|
||||
|
||||
depend() {
|
||||
use dev
|
||||
keyword noprefix
|
||||
keyword noprefix novserver
|
||||
}
|
||||
|
||||
start() {
|
||||
|
||||
@@ -7,6 +7,7 @@ description="Set the dmesg level for a cleaner boot"
|
||||
depend()
|
||||
{
|
||||
before dev modules
|
||||
keyword novserver
|
||||
}
|
||||
|
||||
start()
|
||||
|
||||
@@ -25,6 +25,11 @@ _reboot() {
|
||||
fi
|
||||
}
|
||||
|
||||
_forcefsck()
|
||||
{
|
||||
[ -e /forcefsck ] || get_bootparam forcefsck
|
||||
}
|
||||
|
||||
start()
|
||||
{
|
||||
local fsck_opts= p= check_extra=
|
||||
@@ -33,7 +38,7 @@ start()
|
||||
ewarn "Skipping fsck due to /fastboot"
|
||||
return 0
|
||||
fi
|
||||
if [ -e /forcefsck ] || get_bootparam forcefsck; then
|
||||
if _forcefsck; then
|
||||
fsck_opts="${fsck_opts} -f"
|
||||
check_extra="(check forced)"
|
||||
fi
|
||||
@@ -92,6 +97,7 @@ stop()
|
||||
# Fake function so we always shutdown correctly.
|
||||
_abort() { return 0; }
|
||||
_reboot() { return 0; }
|
||||
_forcefsck() { return 1; }
|
||||
|
||||
yesno "${fsck_shutdown}" && start
|
||||
return 0
|
||||
|
||||
@@ -595,7 +595,7 @@ ${routes}"
|
||||
fi
|
||||
fi
|
||||
|
||||
local OIFS="${IFS}" SIFS=${IFS-y}
|
||||
local OIFS="${IFS}" SIFS="${IFS-y}"
|
||||
local IFS="$__IFS"
|
||||
for cmd in ${routes}; do
|
||||
unset IFS
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
#!@PREFIX@/sbin/runscript
|
||||
# Copyright 2007-2008 Roy Marples <roy@marples.name>
|
||||
# Copyright 2007-2009 Roy Marples <roy@marples.name>
|
||||
# All rights reserved. Released under the 2-clause BSD license.
|
||||
|
||||
description="Saves the caches OpenRC uses to non volatile storage"
|
||||
|
||||
start()
|
||||
{
|
||||
if [ -e "${RC_SVCDIR}"/clock-skewed ]; then
|
||||
ewarn "WARNING: clock skew detected!"
|
||||
if ! yesno "savecache_skewed"; then
|
||||
eerror "Not saving deptree cache"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
ebegin "Saving dependency cache"
|
||||
if [ ! -d "${RC_LIBDIR}"/cache ]; then
|
||||
rm -rf "${RC_LIBDIR}"/cache
|
||||
|
||||
@@ -6,7 +6,7 @@ description="Mount the sys filesystem."
|
||||
|
||||
depend()
|
||||
{
|
||||
keyword noprefix
|
||||
keyword noprefix novserver
|
||||
}
|
||||
|
||||
mount_sys()
|
||||
|
||||
@@ -61,4 +61,4 @@ does the same and also prints the full path of the service to stdout.
|
||||
.Xr rc 8 ,
|
||||
.Xr stdout 3
|
||||
.Sh AUTHORS
|
||||
.An Roy Marples" <roy@marples.name>
|
||||
.An Roy Marples <roy@marples.name>
|
||||
|
||||
@@ -61,4 +61,4 @@ Show information only for the named
|
||||
.Xr rc 8 ,
|
||||
.Xr rc-update 8
|
||||
.Sh AUTHORS
|
||||
.An Roy Marples" <roy@marples.name>
|
||||
.An Roy Marples <roy@marples.name>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.\" Copyright 2007-2008 Roy Marples
|
||||
.\" Copyright 2007-2009 Roy Marples
|
||||
.\" All rights reserved
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
@@ -22,7 +22,7 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd Jan 15, 2008
|
||||
.Dd Jan 10, 2009
|
||||
.Dt RC-UPDATE 8 SMM
|
||||
.Os OpenRC
|
||||
.Sh NAME
|
||||
@@ -38,6 +38,7 @@
|
||||
.Ar service
|
||||
.Op Ar runlevel ...
|
||||
.Nm
|
||||
.Op Fl u , -update
|
||||
.Op Fl v , -verbose
|
||||
.Ar show
|
||||
.Op Ar runlevel ...
|
||||
@@ -53,7 +54,7 @@ or
|
||||
directories. They must also conform to the OpenRC runscript standard.
|
||||
.Pp
|
||||
.Bl -tag -width "Fl a , -delete service"
|
||||
.It Fl a , -add Ar service
|
||||
.It Ar add Ar service
|
||||
Add the
|
||||
.Ar service
|
||||
to the
|
||||
@@ -72,9 +73,13 @@ Show all enabled services and the runlevels they belong to. If you specify
|
||||
runlevels to show, then only those will be included in the output.
|
||||
.It Fl v , -verbose
|
||||
Show all services.
|
||||
.It Fl u , -update
|
||||
Forces an update of the dependency tree cache.
|
||||
This may be needed in the even of clock skew (a file in /etc is newer than the
|
||||
system clock).
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr rc 8 ,
|
||||
.Xr rc-status 8
|
||||
.Sh AUTHORS
|
||||
.An Roy Marples" <roy@marples.name>
|
||||
.An Roy Marples <roy@marples.name>
|
||||
|
||||
10
man/rc.8
10
man/rc.8
@@ -1,4 +1,4 @@
|
||||
.\" Copyright 2007-2008 Roy Marples
|
||||
.\" Copyright 2007-2009 Roy Marples
|
||||
.\" All rights reserved
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
@@ -22,7 +22,7 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd November 03, 2008
|
||||
.Dd January 13, 2009
|
||||
.Dt RC 8 SMM
|
||||
.Os OpenRC
|
||||
.Sh NAME
|
||||
@@ -65,8 +65,10 @@ All services in the boot and sysinit runlevels are automatically included
|
||||
in all other runlevels except for those listed here.
|
||||
.It Ar single
|
||||
Stops all services except for those in the sysinit runlevel.
|
||||
.It Ar reboot
|
||||
Changes to the shutdown runlevel and then reboots the host.
|
||||
.It Ar shutdown
|
||||
Changes to the single runlevel and then halts the host.
|
||||
Changes to the shutdown runlevel and then halts the host.
|
||||
.El
|
||||
.Pp
|
||||
You should not call any of these runlevels yourself.
|
||||
@@ -81,4 +83,4 @@ and let them call these special runlevels.
|
||||
.Xr init 8 ,
|
||||
.Xr shutdown 8
|
||||
.Sh AUTHORS
|
||||
.An Roy Marples <roy@marples.name>
|
||||
.An Roy Marples Aq roy@marples.name
|
||||
|
||||
@@ -70,4 +70,4 @@ is set to
|
||||
.Xr rc_stringlist_free 3 ,
|
||||
.Xr sh 1
|
||||
.Sh AUTHORS
|
||||
.An Roy Marples" <roy@marples.name>
|
||||
.An Roy Marples <roy@marples.name>
|
||||
|
||||
@@ -110,4 +110,4 @@ when done.
|
||||
.Xr rc_stringlist_free 3 ,
|
||||
.Xr runscript 8
|
||||
.Sh AUTHORS
|
||||
.An Roy Marples" <roy@marples.name>
|
||||
.An Roy Marples <roy@marples.name>
|
||||
|
||||
@@ -67,4 +67,4 @@ Each RC_PID should be freed in the list as well as the list itself when done.
|
||||
.Xr free 3 ,
|
||||
.Xr queue 3
|
||||
.Sh AUTHORS
|
||||
.An Roy Marples" <roy@marples.name>
|
||||
.An Roy Marples <roy@marples.name>
|
||||
|
||||
@@ -48,4 +48,4 @@ Plugins can affect the parent environemnt by writing NULL separated strings to
|
||||
.Xr rc 8 ,
|
||||
.Xr runscript 8
|
||||
.Sh AUTHORS
|
||||
.An Roy Marples" <roy@marples.name>
|
||||
.An Roy Marples <roy@marples.name>
|
||||
|
||||
@@ -63,4 +63,4 @@ Rinse and repeat for the other verbose functions.
|
||||
.Xr free 3
|
||||
.Xr rc_stringlist_free 3
|
||||
.Sh AUTHORS
|
||||
.An Roy Marples" <roy@marples.name>
|
||||
.An Roy Marples <roy@marples.name>
|
||||
|
||||
@@ -227,4 +227,4 @@ normally holds the volatile state data for services on a RAM backed disk.
|
||||
.Xr rc_stringlist_free 3 ,
|
||||
.Xr start-stop-daemon 8
|
||||
.Sh AUTHORS
|
||||
.An Roy Marples" <roy@marples.name>
|
||||
.An Roy Marples <roy@marples.name>
|
||||
|
||||
@@ -85,4 +85,4 @@ itself.
|
||||
.Xr queue 3 ,
|
||||
.Xr strcmp 3
|
||||
.Sh AUTHORS
|
||||
.An Roy Marples" <roy@marples.name>
|
||||
.An Roy Marples <roy@marples.name>
|
||||
|
||||
@@ -461,4 +461,4 @@ Users are encouraged to use the is_newer_than function which returns correctly.
|
||||
.Xr start-stop-daemon 8 ,
|
||||
.Xr uname 1
|
||||
.Sh AUTHORS
|
||||
.An Roy Marples" <roy@marples.name>
|
||||
.An Roy Marples <roy@marples.name>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.\" Copyright 2007-2008 Roy Marples
|
||||
.\" Copyright 2007-2009 Roy Marples
|
||||
.\" All rights reserved
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
@@ -22,7 +22,7 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd September 27, 2008
|
||||
.Dd January 1, 2009
|
||||
.Dt START-STOP-DAEMON 8 SMM
|
||||
.Os OpenRC
|
||||
.Sh NAME
|
||||
@@ -116,6 +116,10 @@ chdir to this directory before starting the daemon.
|
||||
.It Fl r , -chroot Ar path
|
||||
chroot to this directory before starting the daemon. All other paths, such
|
||||
as the path to the daemon, chdir and pidfile, should be relative to the chroot.
|
||||
.It Fl c , -chuid Ar user
|
||||
Same as the
|
||||
.Fl u , -user
|
||||
option.
|
||||
.It Fl e , -env Ar VAR=VALUE
|
||||
Set the environment variable VAR to VALUE.
|
||||
.It Fl g , -group Ar group
|
||||
@@ -185,4 +189,4 @@ first appeared in Debian.
|
||||
This is a complete re-implementation with the process finding code in the
|
||||
OpenRC library (librc, -lrc) so other programs can make use of it.
|
||||
.Sh AUTHORS
|
||||
.An Roy Marples" <roy@marples.name>
|
||||
.An Roy Marples <roy@marples.name>
|
||||
|
||||
21
mk/dist.mk
21
mk/dist.mk
@@ -5,9 +5,28 @@
|
||||
DISTPREFIX?= ${NAME}-${VERSION}
|
||||
DISTFILE?= ${DISTPREFIX}.tar.bz2
|
||||
|
||||
CLEANFILES+= ${DISTFILE}
|
||||
CLEANFILES+= ${NAME}-*.tar.bz2
|
||||
|
||||
_SNAP_SH= date -u +%Y%m%d%H%M
|
||||
_SNAP!= ${_SNAP_SH}
|
||||
SNAP= ${_SNAP}$(shell ${_SNAP_SH})
|
||||
SNAPDIR= ${DISTPREFIX}-${SNAP}
|
||||
SNAPFILE= ${SNAPDIR}.tar.bz2
|
||||
|
||||
dist:
|
||||
svn export . ${DISTPREFIX}
|
||||
tar cjpf ${DISTFILE} ${DISTPREFIX}
|
||||
rm -rf ${DISTPREFIX}
|
||||
|
||||
snapshot:
|
||||
rm -rf /tmp/${SNAPDIR}
|
||||
mkdir /tmp/${SNAPDIR}
|
||||
cp -RPp * /tmp/${SNAPDIR}
|
||||
(cd /tmp/${SNAPDIR}; make clean)
|
||||
find /tmp/${SNAPDIR} -name .svn -exec rm -rf -- {} \; 2>/dev/null || true
|
||||
tar -cvjpf ${SNAPFILE} -C /tmp ${SNAPDIR}
|
||||
rm -rf /tmp/${SNAPDIR}
|
||||
ls -l ${SNAPFILE}
|
||||
|
||||
snap: snapshot
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2007-2008 Roy Marples <roy@marples.name>
|
||||
# Copyright 2007-2009 Roy Marples <roy@marples.name>
|
||||
# All rights reserved. Released under the 2-clause BSD license.
|
||||
|
||||
wpa_supplicant_depend()
|
||||
@@ -45,7 +45,7 @@ fi
|
||||
|
||||
wpa_supplicant_pre_start()
|
||||
{
|
||||
local opts= cfgfile= ctrl_dir= wireless=true
|
||||
local opts= cliopts= cfgfile= ctrl_dir= wireless=true
|
||||
local wpas=/usr/sbin/wpa_supplicant wpac=/usr/bin/wpa_cli
|
||||
local actfile=/etc/wpa_supplicant/wpa_cli.sh
|
||||
|
||||
@@ -57,6 +57,8 @@ wpa_supplicant_pre_start()
|
||||
[ -e "${actfile}" ] || unset wpac
|
||||
|
||||
eval opts=\$wpa_supplicant_${IFVAR}
|
||||
eval cliopts=\$wpa_cli_${IFVAR}
|
||||
[ -z "${cliopts}" ] && cliopts=${wpa_cli}
|
||||
case " ${opts} " in
|
||||
*" -Dwired "*) wireless=false;;
|
||||
*) _is_wireless || return 0;;
|
||||
@@ -105,7 +107,15 @@ wpa_supplicant_pre_start()
|
||||
fi
|
||||
|
||||
# Work out where the ctrl_interface dir is if it's not specified
|
||||
local ctrl_dir=$(sed -n -e 's/[[:space:]]*#.*//g;s/[[:space:]]*$//g;s/^ctrl_interface=//p' "${cfgfile}")
|
||||
local ctrl_dir=$(sed -e 's/^ *//' \
|
||||
-e '/^ctrl_interface=/!d' \
|
||||
-e 's/^ctrl_interface=//' \
|
||||
-e 's/^ *//' \
|
||||
-e 's/^DIR=//' \
|
||||
-e 's/^ *//' \
|
||||
-e 's/GROUP=.*//' \
|
||||
-e 's/ *$//' \
|
||||
"${cfgfile}")
|
||||
if [ -z "${ctrl_dir}" ]; then
|
||||
ctrl_dir=${opts##* -C}
|
||||
if [ -n "${ctrl_dir}" -a "${ctrl_dir}" != "${opts}" ]; then
|
||||
@@ -120,7 +130,6 @@ wpa_supplicant_pre_start()
|
||||
fi
|
||||
service_set_value ctrl_dir "${ctrl_dir}"
|
||||
|
||||
|
||||
if [ -n "${wpac}" ]; then
|
||||
opts="${opts} -W"
|
||||
elif service_started devd; then
|
||||
@@ -150,7 +159,7 @@ wpa_supplicant_pre_start()
|
||||
ebegin "Starting wpa_cli on" "${IFACE}"
|
||||
start-stop-daemon --start --exec "${wpac}" \
|
||||
--pidfile "/var/run/wpa_cli-${IFACE}.pid" \
|
||||
-- -a "${actfile}" -p "${ctrl_dir}" -i "${IFACE}" \
|
||||
-- ${cliopts} -a "${actfile}" -p "${ctrl_dir}" -i "${IFACE}" \
|
||||
-P "/var/run/wpa_cli-${IFACE}.pid" -B
|
||||
if eend $?; then
|
||||
ebegin "Backgrounding ..."
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
# Copyright 2007-2008 Roy Marples <roy@marples.name>
|
||||
# All rights reserved. Released under the 2-clause BSD license.
|
||||
|
||||
retval=0
|
||||
|
||||
# mount $svcdir as something we can write to if it's not rw
|
||||
# mount $RC_SVCDIR as something we can write to if it's not rw
|
||||
# On vservers, / is always rw at this point, so we need to clean out
|
||||
# the old service state data
|
||||
RC_SVCDIR=${RC_SVCDIR:-/@LIB@/rc/init.d}
|
||||
if [ "${RC_SVCDIR}" != "/" ] && mkdir "${RC_SVCDIR}/.test.$$" 2>/dev/null; then
|
||||
rmdir "${RC_SVCDIR}/.test.$$"
|
||||
rm -rf "${RC_SVCDIR}"/*
|
||||
else
|
||||
mount_svcdir
|
||||
retval=$?
|
||||
fi
|
||||
case "$(rc --sys)" in
|
||||
OPENVZ|VSERVER) rm -rf "${RC_SVCDIR}"/*;;
|
||||
*) if mountinfo --quiet "${RC_SVCDIR}"; then
|
||||
rm -rf "${RC_SVCDIR}"/*
|
||||
else
|
||||
mount_svcdir
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
retval=$?
|
||||
|
||||
if [ -e "${RC_LIBDIR}"/cache/deptree ]; then
|
||||
cp -p "${RC_LIBDIR}"/cache/* "${RC_SVCDIR}" 2>/dev/null
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2007-2008 Roy Marples <roy@marples.name>
|
||||
* Copyright 2007-2009 Roy Marples <roy@marples.name>
|
||||
* All rights reserved
|
||||
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -41,6 +41,7 @@
|
||||
#define RC_LEVEL_DEFAULT "default"
|
||||
|
||||
#define RC_DEPTREE_CACHE RC_SVCDIR "/deptree"
|
||||
#define RC_DEPTREE_SKEWED RC_SVCDIR "/clock-skewed"
|
||||
#define RC_KRUNLEVEL RC_SVCDIR "/krunlevel"
|
||||
#define RC_STARTING RC_SVCDIR "/rc.starting"
|
||||
#define RC_STOPPING RC_SVCDIR "/rc.stopping"
|
||||
@@ -84,6 +85,11 @@
|
||||
(var) = (tvar))
|
||||
#endif
|
||||
|
||||
#ifdef __GLIBC__
|
||||
# if ! defined (__UCLIBC__) && ! defined (__dietlibc__)
|
||||
# define strlcpy(dst, src, size) snprintf(dst, size, "%s", src)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
_unused static void *xmalloc (size_t size)
|
||||
{
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2007-2008 Roy Marples <roy@marples.name>
|
||||
* Copyright 2007-2009 Roy Marples <roy@marples.name>
|
||||
* All rights reserved
|
||||
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -31,32 +31,7 @@
|
||||
|
||||
#include "librc.h"
|
||||
|
||||
#ifdef __GLIBC__
|
||||
# if ! defined (__UCLIBC__) && ! defined (__dietlibc__)
|
||||
static size_t strlcpy(char *dst, const char *src, size_t size)
|
||||
{
|
||||
const char *s = src;
|
||||
size_t n = size;
|
||||
|
||||
if (n && --n)
|
||||
do {
|
||||
if (!(*dst++ = *src++))
|
||||
break;
|
||||
} while (--n);
|
||||
|
||||
if (!n) {
|
||||
if (size)
|
||||
*dst = '\0';
|
||||
while (*src++);
|
||||
}
|
||||
|
||||
return src - s - 1;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__linux__)
|
||||
|
||||
static bool pid_is_exec(pid_t pid, const char *exec)
|
||||
{
|
||||
char buffer[32];
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2007-2008 Roy Marples <roy@marples.name>
|
||||
* Copyright 2007-2009 Roy Marples <roy@marples.name>
|
||||
* All rights reserved
|
||||
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -544,7 +544,8 @@ rc_deptree_order(const RC_DEPTREE *deptree, const char *runlevel, int options)
|
||||
librc_hidden_def(rc_deptree_order)
|
||||
|
||||
static bool
|
||||
mtime_check(const char *source, const char *target, bool newer)
|
||||
mtime_check(const char *source, const char *target, bool newer,
|
||||
time_t *rel, char *file)
|
||||
{
|
||||
struct stat buf;
|
||||
time_t mtime;
|
||||
@@ -565,16 +566,32 @@ mtime_check(const char *source, const char *target, bool newer)
|
||||
|
||||
if (newer) {
|
||||
if (mtime < buf.st_mtime)
|
||||
return false;
|
||||
retval = false;
|
||||
if (rel != NULL) {
|
||||
if (*rel < buf.st_mtime) {
|
||||
if (file)
|
||||
strlcpy(file, target, PATH_MAX);
|
||||
*rel = buf.st_mtime;
|
||||
}
|
||||
} else
|
||||
return retval;
|
||||
} else {
|
||||
if (mtime > buf.st_mtime)
|
||||
return false;
|
||||
retval = false;
|
||||
if (rel != NULL) {
|
||||
if (*rel > buf.st_mtime) {
|
||||
if (file)
|
||||
strlcpy(file, target, PATH_MAX);
|
||||
*rel = buf.st_mtime;
|
||||
}
|
||||
} else
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* If not a dir then reset errno */
|
||||
if (!(dp = opendir(target))) {
|
||||
errno = serrno;
|
||||
return true;
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Check all the entries in the dir */
|
||||
@@ -582,26 +599,30 @@ mtime_check(const char *source, const char *target, bool newer)
|
||||
if (d->d_name[0] == '.')
|
||||
continue;
|
||||
snprintf(path, sizeof(path), "%s/%s", target, d->d_name);
|
||||
retval = mtime_check(source, path, newer);
|
||||
if (!retval)
|
||||
break;
|
||||
if (!mtime_check(source, path, newer, rel, file)) {
|
||||
retval = false;
|
||||
if (rel == NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
closedir(dp);
|
||||
return retval;
|
||||
}
|
||||
|
||||
bool
|
||||
rc_newer_than(const char *source, const char *target)
|
||||
rc_newer_than(const char *source, const char *target,
|
||||
time_t *newest, char *file)
|
||||
{
|
||||
|
||||
return mtime_check(source, target, true);
|
||||
return mtime_check(source, target, true, newest, file);
|
||||
}
|
||||
librc_hidden_def(rc_newer_than)
|
||||
|
||||
bool
|
||||
rc_older_than(const char *source, const char *target)
|
||||
rc_older_than(const char *source, const char *target,
|
||||
time_t *oldest, char *file)
|
||||
{
|
||||
return mtime_check(source, target, false);
|
||||
return mtime_check(source, target, false, oldest, file);
|
||||
}
|
||||
librc_hidden_def(rc_older_than)
|
||||
|
||||
@@ -638,7 +659,7 @@ static const char *const depdirs[] =
|
||||
};
|
||||
|
||||
bool
|
||||
rc_deptree_update_needed(void)
|
||||
rc_deptree_update_needed(time_t *newest, char *file)
|
||||
{
|
||||
bool newer = false;
|
||||
RC_STRINGLIST *config;
|
||||
@@ -652,31 +673,39 @@ rc_deptree_update_needed(void)
|
||||
|
||||
/* Quick test to see if anything we use has changed and we have
|
||||
* data in our deptree */
|
||||
if (!existss(RC_DEPTREE_CACHE) ||
|
||||
!rc_newer_than(RC_DEPTREE_CACHE, RC_INITDIR) ||
|
||||
!rc_newer_than(RC_DEPTREE_CACHE, RC_CONFDIR) ||
|
||||
if (!existss(RC_DEPTREE_CACHE))
|
||||
return true;
|
||||
if (!rc_newer_than(RC_DEPTREE_CACHE, RC_INITDIR, newest, file))
|
||||
newer = true;
|
||||
if (!rc_newer_than(RC_DEPTREE_CACHE, RC_CONFDIR, newest, file))
|
||||
newer = true;
|
||||
#ifdef RC_PKG_INITDIR
|
||||
!rc_newer_than(RC_DEPTREE_CACHE, RC_PKG_INITDIR) ||
|
||||
if (!rc_newer_than(RC_DEPTREE_CACHE, RC_PKG_INITDIR, newest, file))
|
||||
newer = true;
|
||||
#endif
|
||||
#ifdef RC_PKG_CONFDIR
|
||||
!rc_newer_than(RC_DEPTREE_CACHE, RC_PKG_CONFDIR) ||
|
||||
if (!rc_newer_than(RC_DEPTREE_CACHE, RC_PKG_CONFDIR, newest, file))
|
||||
newer = true;
|
||||
#endif
|
||||
#ifdef RC_LOCAL_INITDIR
|
||||
!rc_newer_than(RC_DEPTREE_CACHE, RC_LOCAL_INITDIR) ||
|
||||
if (!rc_newer_than(RC_DEPTREE_CACHE, RC_LOCAL_INITDIR, newest, file))
|
||||
newer = true;
|
||||
#endif
|
||||
#ifdef RC_LOCAL_CONFDIR
|
||||
!rc_newer_than(RC_DEPTREE_CACHE, RC_LOCAL_CONFDIR) ||
|
||||
if (!rc_newer_than(RC_DEPTREE_CACHE, RC_LOCAL_CONFDIR, newest, file))
|
||||
newer = true;
|
||||
#endif
|
||||
!rc_newer_than(RC_DEPTREE_CACHE, "/etc/rc.conf"))
|
||||
return true;
|
||||
if (!rc_newer_than(RC_DEPTREE_CACHE, "/etc/rc.conf", newest, file))
|
||||
newer = true;
|
||||
|
||||
/* Some init scripts dependencies change depending on config files
|
||||
* outside of baselayout, like syslog-ng, so we check those too. */
|
||||
config = rc_config_list(RC_DEPCONFIG);
|
||||
TAILQ_FOREACH(s, config, entries) {
|
||||
if (!rc_newer_than(RC_DEPTREE_CACHE, s->value)) {
|
||||
if (!rc_newer_than(RC_DEPTREE_CACHE, s->value, newest, file)) {
|
||||
newer = true;
|
||||
break;
|
||||
if (newest == NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
rc_stringlist_free(config);
|
||||
|
||||
@@ -66,7 +66,8 @@ ssize_t rc_getline(char **line, size_t *len, FILE *fp)
|
||||
}
|
||||
p = *line + last;
|
||||
memset(p, 0, BUFSIZ);
|
||||
fgets(p, BUFSIZ, fp);
|
||||
if (fgets(p, BUFSIZ, fp) == NULL)
|
||||
break;
|
||||
last += strlen(p);
|
||||
if (last && (*line)[last - 1] == '\n') {
|
||||
(*line)[last - 1] = '\0';
|
||||
|
||||
@@ -555,7 +555,8 @@ rc_service_mark(const char *service, const RC_SERVICE state)
|
||||
RC_SVCDIR "/%s/%s",
|
||||
rc_parse_service_state(RC_SERVICE_WASINACTIVE),
|
||||
base);
|
||||
symlink(init, was);
|
||||
if (symlink(init, was) == -1)
|
||||
return false;
|
||||
skip_wasinactive = true;
|
||||
}
|
||||
if (unlink(file) == -1) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2007-2008 Roy Marples <roy@marples.name>
|
||||
* Copyright 2007-2009 Roy Marples <roy@marples.name>
|
||||
* All rights reserved
|
||||
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -304,25 +304,37 @@ typedef void *RC_DEPTREE;
|
||||
|
||||
/*! Check to see if source is newer than target.
|
||||
* If target is a directory then we traverse it and it's children.
|
||||
* @return true if source is newer than target, otherwise false */
|
||||
bool rc_newer_than(const char *, const char *);
|
||||
* @param source
|
||||
* @param target
|
||||
* @param mtime of newest target
|
||||
* @param filename of the newest target (needs mtime param)
|
||||
* @return true if source is newer than target, otherwise false */
|
||||
bool rc_newer_than(const char *, const char *, time_t *, char *);
|
||||
|
||||
/*! Check to see if source is newer than target.
|
||||
/*! Check to see if source is older than target.
|
||||
* If target is a directory then we traverse it and it's children.
|
||||
* @return true if source is newer than target, otherwise false */
|
||||
bool rc_older_than(const char *, const char *);
|
||||
* @param source
|
||||
* @param target
|
||||
* @param mtime of oldest target
|
||||
* @param filename of the oldest target (needs mtime param)
|
||||
* @return true if source is older than target, otherwise false */
|
||||
bool rc_older_than(const char *, const char *, time_t *, char *);
|
||||
|
||||
/*! Update the cached dependency tree if it's older than any init script,
|
||||
* its configuration file or an external configuration file the init script
|
||||
* has specified.
|
||||
* time_t returns the time of the newest file that the dependency tree
|
||||
* will be checked against.
|
||||
* @return true if successful, otherwise false */
|
||||
bool rc_deptree_update(void);
|
||||
|
||||
/*! Check if the cached dependency tree is older than any init script,
|
||||
* its configuration file or an external configuration file the init script
|
||||
* has specified.
|
||||
* @param mtime of newest file
|
||||
* @param buffer of PATH_MAX to store newest file
|
||||
* @return true if it needs updating, otherwise false */
|
||||
bool rc_deptree_update_needed(void);
|
||||
bool rc_deptree_update_needed(time_t *, char *);
|
||||
|
||||
/*! Load the cached dependency tree and return a pointer to it.
|
||||
* This pointer should be freed with rc_deptree_free when done.
|
||||
|
||||
@@ -43,11 +43,12 @@ include ${MK}/${MKTERMCAP}.mk
|
||||
LDADD+= ${LIBDL} ${LIBKVM}
|
||||
include ${MK}/${MKPAM}.mk
|
||||
|
||||
_SVNVER_SH= if type svnversion >/dev/null 2>&1; then \
|
||||
echo "-svn-$$(svnversion)"; \
|
||||
else \
|
||||
echo ""; \
|
||||
fi
|
||||
_SVNVER_SH= ret=""; \
|
||||
if type svnversion >/dev/null 2>&1; then \
|
||||
svnver="$$(LC_ALL=C svnversion)"; \
|
||||
[ "$${svnver}" != exported ] && ret="-svn-$${svnver}"; \
|
||||
fi; \
|
||||
echo "$${ret}";
|
||||
_SVNVER!= ${_SVNVER_SH}
|
||||
SVNVER= ${_SVNVER}$(shell ${_SVNVER_SH})
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2007-2008 Roy Marples <roy@marples.name>
|
||||
* Copyright 2007-2009 Roy Marples <roy@marples.name>
|
||||
* All rights reserved
|
||||
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -39,7 +39,7 @@ int start_stop_daemon(int, char **);
|
||||
void run_applets(int, char **);
|
||||
|
||||
/* Handy function so we can wrap einfo around our deptree */
|
||||
RC_DEPTREE *_rc_deptree_load (int *);
|
||||
RC_DEPTREE *_rc_deptree_load (int, int *);
|
||||
|
||||
/* Test to see if we can see pid 1 or not */
|
||||
bool _rc_can_find_pids(void);
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2007-2008 Roy Marples <roy@marples.name>
|
||||
* Copyright 2007-2009 Roy Marples <roy@marples.name>
|
||||
* All rights reserved
|
||||
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -451,7 +451,7 @@ void run_applets(int argc, char **argv)
|
||||
if (argc < 3)
|
||||
exit (EXIT_FAILURE);
|
||||
while (i < argc) {
|
||||
if (!rc_newer_than(argv[1], argv[i++]))
|
||||
if (!rc_newer_than(argv[1], argv[i++], NULL, NULL))
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
@@ -461,7 +461,7 @@ void run_applets(int argc, char **argv)
|
||||
if (argc < 3)
|
||||
exit (EXIT_FAILURE);
|
||||
while (i < argc) {
|
||||
if (!rc_newer_than(argv[1], argv[i++]))
|
||||
if (!rc_newer_than(argv[1], argv[i++], NULL, NULL))
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
exit(EXIT_SUCCESS);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2007-2008 Roy Marples <roy@marples.name>
|
||||
* Copyright 2007-2009 Roy Marples <roy@marples.name>
|
||||
* All rights reserved
|
||||
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -29,17 +29,21 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <getopt.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
#include <limits.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <utime.h>
|
||||
|
||||
#include "builtins.h"
|
||||
#include "einfo.h"
|
||||
@@ -49,13 +53,19 @@
|
||||
extern const char *applet;
|
||||
|
||||
RC_DEPTREE *
|
||||
_rc_deptree_load(int *regen) {
|
||||
_rc_deptree_load(int force, int *regen) {
|
||||
int fd;
|
||||
int retval;
|
||||
int serrno = errno;
|
||||
int merrno;
|
||||
time_t t;
|
||||
char file[PATH_MAX];
|
||||
struct stat st;
|
||||
struct utimbuf ut;
|
||||
FILE *fp;
|
||||
|
||||
if (rc_deptree_update_needed()) {
|
||||
t = 0;
|
||||
if (rc_deptree_update_needed(&t, file) || force != 0) {
|
||||
/* Test if we have permission to update the deptree */
|
||||
fd = open(RC_DEPTREE_CACHE, O_WRONLY);
|
||||
merrno = errno;
|
||||
@@ -67,8 +77,30 @@ _rc_deptree_load(int *regen) {
|
||||
if (regen)
|
||||
*regen = 1;
|
||||
ebegin("Caching service dependencies");
|
||||
retval = rc_deptree_update();
|
||||
eend (retval ? 0 : -1, "Failed to update the dependency tree");
|
||||
retval = rc_deptree_update() ? 0 : -1;
|
||||
eend (retval, "Failed to update the dependency tree");
|
||||
|
||||
if (retval == 0) {
|
||||
stat(RC_DEPTREE_CACHE, &st);
|
||||
if (st.st_mtime < t) {
|
||||
eerror("Clock skew detected with `%s'", file);
|
||||
eerrorn("Adjusting mtime of `" RC_DEPTREE_CACHE
|
||||
"' to %s", ctime(&t));
|
||||
fp = fopen(RC_DEPTREE_SKEWED, "w");
|
||||
if (fp != NULL) {
|
||||
fprintf(fp, "%s\n", file);
|
||||
fclose(fp);
|
||||
}
|
||||
ut.actime = t;
|
||||
ut.modtime = t;
|
||||
utime(RC_DEPTREE_CACHE, &ut);
|
||||
} else {
|
||||
if (exists(RC_DEPTREE_SKEWED))
|
||||
unlink(RC_DEPTREE_SKEWED);
|
||||
}
|
||||
}
|
||||
if (force == -1 && regen != NULL)
|
||||
*regen = retval;
|
||||
}
|
||||
return rc_deptree_load();
|
||||
}
|
||||
@@ -104,9 +136,8 @@ rc_depend(int argc, char **argv)
|
||||
RC_STRINGLIST *depends;
|
||||
RC_STRING *s;
|
||||
RC_DEPTREE *deptree = NULL;
|
||||
int options = RC_DEP_TRACE;
|
||||
int options = RC_DEP_TRACE, update = 0;
|
||||
bool first = true;
|
||||
bool update = false;
|
||||
char *runlevel = xstrdup(getenv("RC_RUNLEVEL"));
|
||||
int opt;
|
||||
char *token;
|
||||
@@ -130,7 +161,7 @@ rc_depend(int argc, char **argv)
|
||||
rc_stringlist_add(types, token);
|
||||
break;
|
||||
case 'u':
|
||||
update = true;
|
||||
update = 1;
|
||||
break;
|
||||
case 'T':
|
||||
options &= RC_DEP_TRACE;
|
||||
@@ -140,15 +171,7 @@ rc_depend(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (update) {
|
||||
ebegin("Caching service dependencies");
|
||||
update = rc_deptree_update();
|
||||
eend(update ? 0 : -1, "%s: %s", applet, strerror(errno));
|
||||
if (!update)
|
||||
eerrorx("Failed to update the dependency tree");
|
||||
}
|
||||
|
||||
if (!(deptree = _rc_deptree_load(NULL)))
|
||||
if (!(deptree = _rc_deptree_load(update, NULL)))
|
||||
eerrorx("failed to load deptree");
|
||||
|
||||
if (!runlevel)
|
||||
|
||||
@@ -112,11 +112,10 @@ rc_conf_yesno(const char *setting)
|
||||
}
|
||||
|
||||
static const char *const env_whitelist[] = {
|
||||
"PATH", "SHELL", "USER", "HOME", "TERM",
|
||||
"CONSOLE", "PATH", "SHELL", "USER", "HOME", "TERM",
|
||||
"LANG", "LC_CTYPE", "LC_NUMERIC", "LC_TIME", "LC_COLLATE",
|
||||
"LC_MONETARY", "LC_MESSAGES", "LC_PAPER", "LC_NAME", "LC_ADDRESS",
|
||||
"LC_TELEPHONE", "LC_MEASUREMENT", "LC_IDENTIFICATION", "LC_ALL",
|
||||
"INIT_HALT", "INIT_VERSION", "RUNLEVEL", "PREVLEVEL", "CONSOLE",
|
||||
"IN_HOTPLUG", "IN_BACKGROUND", "RC_INTERFACE_KEEP_CONFIG",
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2007-2008 Roy Marples <roy@marples.name>
|
||||
* Copyright 2007-2009 Roy Marples <roy@marples.name>
|
||||
* All rights reserved
|
||||
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -140,7 +140,7 @@ print_services(const char *runlevel, RC_STRINGLIST *svcs)
|
||||
if (!svcs)
|
||||
return;
|
||||
if (!deptree)
|
||||
deptree = _rc_deptree_load(NULL);
|
||||
deptree = _rc_deptree_load(0, NULL);
|
||||
if (!deptree) {
|
||||
TAILQ_FOREACH(s, svcs, entries)
|
||||
if (!runlevel ||
|
||||
@@ -260,7 +260,7 @@ rc_status(int argc, char **argv)
|
||||
}
|
||||
|
||||
/* Output the services in the order in which they would start */
|
||||
deptree = _rc_deptree_load(NULL);
|
||||
deptree = _rc_deptree_load(0, NULL);
|
||||
|
||||
TAILQ_FOREACH(l, levels, entries) {
|
||||
print_level(l->value);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2007-2008 Roy Marples <roy@marples.name>
|
||||
* Copyright 2007-2009 Roy Marples <roy@marples.name>
|
||||
* All rights reserved
|
||||
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -50,7 +50,8 @@ extern const char *applet;
|
||||
* 0 = no changes (nothing to do)
|
||||
* 1+ = number of runlevels updated
|
||||
*/
|
||||
static int add (const char *runlevel, const char *service)
|
||||
static int
|
||||
add(const char *runlevel, const char *service)
|
||||
{
|
||||
int retval = -1;
|
||||
|
||||
@@ -70,7 +71,8 @@ static int add (const char *runlevel, const char *service)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int delete (const char *runlevel, const char *service)
|
||||
static int
|
||||
delete(const char *runlevel, const char *service)
|
||||
{
|
||||
int retval = -1;
|
||||
|
||||
@@ -90,7 +92,8 @@ static int delete (const char *runlevel, const char *service)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void show (RC_STRINGLIST *runlevels, bool verbose)
|
||||
static void
|
||||
show(RC_STRINGLIST *runlevels, bool verbose)
|
||||
{
|
||||
RC_STRINGLIST *services = rc_services_in_runlevel(NULL);
|
||||
RC_STRING *service;
|
||||
@@ -135,11 +138,13 @@ static void show (RC_STRINGLIST *runlevels, bool verbose)
|
||||
"Usage: rc-update [options] add service <runlevel>\n" \
|
||||
" rc-update [options] del service <runlevel>\n" \
|
||||
" rc-update [options] show"
|
||||
#define getoptstring getoptstring_COMMON
|
||||
#define getoptstring "u" getoptstring_COMMON
|
||||
static const struct option longopts[] = {
|
||||
{ "update", 0, NULL, 'u' },
|
||||
longopts_COMMON
|
||||
};
|
||||
static const char * const longopts_help[] = {
|
||||
"Force an update of the dependency tree",
|
||||
longopts_help_COMMON
|
||||
};
|
||||
#include "_usage.c"
|
||||
@@ -148,7 +153,8 @@ static const char * const longopts_help[] = {
|
||||
#define DODELETE (1 << 2)
|
||||
#define DOSHOW (1 << 3)
|
||||
|
||||
int rc_update(int argc, char **argv)
|
||||
int
|
||||
rc_update(int argc, char **argv)
|
||||
{
|
||||
RC_STRINGLIST *runlevels;
|
||||
RC_STRING *runlevel;
|
||||
@@ -163,8 +169,11 @@ int rc_update(int argc, char **argv)
|
||||
int ret;
|
||||
|
||||
while ((opt = getopt_long(argc, argv, getoptstring,
|
||||
longopts, (int *) 0)) != -1)
|
||||
longopts, (int *)0)) != -1)
|
||||
switch (opt) {
|
||||
case 'u':
|
||||
_rc_deptree_load(-1, &ret);
|
||||
return ret;
|
||||
case_RC_COMMON_GETOPT
|
||||
}
|
||||
|
||||
@@ -189,7 +198,7 @@ int rc_update(int argc, char **argv)
|
||||
else
|
||||
eerrorx("%s: invalid command `%s'", applet, argv[optind]);
|
||||
}
|
||||
if (! action)
|
||||
if (!action)
|
||||
action = DOSHOW;
|
||||
|
||||
runlevels = rc_stringlist_new();
|
||||
@@ -215,14 +224,14 @@ int rc_update(int argc, char **argv)
|
||||
if (action & DOSHOW) {
|
||||
if (service)
|
||||
rc_stringlist_add(runlevels, service);
|
||||
if (! TAILQ_FIRST(runlevels)) {
|
||||
if (!TAILQ_FIRST(runlevels)) {
|
||||
free(runlevels);
|
||||
runlevels = rc_runlevel_list();
|
||||
}
|
||||
|
||||
show (runlevels, verbose);
|
||||
} else {
|
||||
if (! service)
|
||||
if (!service)
|
||||
eerror ("%s: no service specified", applet);
|
||||
else {
|
||||
if (action & DOADD) {
|
||||
@@ -231,22 +240,22 @@ int rc_update(int argc, char **argv)
|
||||
actfunc = delete;
|
||||
} else {
|
||||
rc_stringlist_free(runlevels);
|
||||
eerrorx ("%s: invalid action", applet);
|
||||
eerrorx("%s: invalid action", applet);
|
||||
}
|
||||
|
||||
if (! TAILQ_FIRST(runlevels)) {
|
||||
if (!TAILQ_FIRST(runlevels)) {
|
||||
p = rc_runlevel_get();
|
||||
rc_stringlist_add(runlevels, p);
|
||||
free(p);
|
||||
}
|
||||
|
||||
if (! TAILQ_FIRST(runlevels)) {
|
||||
if (!TAILQ_FIRST(runlevels)) {
|
||||
free(runlevels);
|
||||
eerrorx ("%s: no runlevels found", applet);
|
||||
}
|
||||
|
||||
TAILQ_FOREACH (runlevel, runlevels, entries) {
|
||||
if (! rc_runlevel_exists(runlevel->value)) {
|
||||
TAILQ_FOREACH(runlevel, runlevels, entries) {
|
||||
if (!rc_runlevel_exists(runlevel->value)) {
|
||||
eerror ("%s: runlevel `%s' does not exist",
|
||||
applet, runlevel->value);
|
||||
continue;
|
||||
|
||||
20
src/rc/rc.c
20
src/rc/rc.c
@@ -9,7 +9,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2007-2008 Roy Marples <roy@marples.name>
|
||||
* Copyright 2007-2009 Roy Marples <roy@marples.name>
|
||||
* All rights reserved
|
||||
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -842,10 +842,14 @@ main(int argc, char **argv)
|
||||
}
|
||||
|
||||
newlevel = argv[optind++];
|
||||
/* For compat with old system */
|
||||
/* To make life easier, we only have the shutdown runlevel as
|
||||
* nothing really needs to know that we're rebooting.
|
||||
* But for those that do, you can test against RC_REBOOT. */
|
||||
if (newlevel) {
|
||||
if (strcmp(newlevel, "reboot") == 0)
|
||||
if (strcmp(newlevel, "reboot") == 0) {
|
||||
newlevel = UNCONST(RC_LEVEL_SHUTDOWN);
|
||||
setenv("RC_REBOOT", "YES", 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable logging */
|
||||
@@ -918,8 +922,8 @@ main(int argc, char **argv)
|
||||
free(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (going_down) {
|
||||
@@ -944,8 +948,10 @@ main(int argc, char **argv)
|
||||
}
|
||||
|
||||
/* Load our deptree */
|
||||
if ((deptree = _rc_deptree_load(®en)) == NULL)
|
||||
if ((deptree = _rc_deptree_load(0, ®en)) == NULL)
|
||||
eerrorx("failed to load deptree");
|
||||
if (exists(RC_DEPTREE_SKEWED))
|
||||
ewarn("WARNING: clock skew detected!");
|
||||
|
||||
/* Clean the failed services state dir */
|
||||
clean_failed();
|
||||
@@ -1062,7 +1068,7 @@ main(int argc, char **argv)
|
||||
|
||||
#ifdef __linux__
|
||||
/* mark any services skipped as started */
|
||||
proc = p = proc_getent("noinitd");
|
||||
proc = p = proc_getent("noinit");
|
||||
if (proc) {
|
||||
while ((token = strsep(&p, ",")))
|
||||
rc_service_mark(token, RC_SERVICE_STARTED);
|
||||
@@ -1083,7 +1089,7 @@ main(int argc, char **argv)
|
||||
|
||||
#ifdef __linux__
|
||||
/* mark any services skipped as stopped */
|
||||
proc = p = proc_getent("noinitd");
|
||||
proc = p = proc_getent("noinit");
|
||||
if (proc) {
|
||||
while ((token = strsep(&p, ",")))
|
||||
rc_service_mark(token, RC_SERVICE_STOPPED);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2007-2008 Roy Marples <roy@marples.name>
|
||||
* Copyright 2007-2009 Roy Marples <roy@marples.name>
|
||||
* All rights reserved
|
||||
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -717,9 +717,9 @@ svc_start(bool deps)
|
||||
exit(EXIT_FAILURE);
|
||||
background = true;
|
||||
rc_service_mark(service, RC_SERVICE_HOTPLUGGED);
|
||||
if (rc_runlevel_starting())
|
||||
ewarnx("WARNING: %s will be started when the runlevel"
|
||||
" has finished.", applet);
|
||||
if (strcmp(runlevel, RC_LEVEL_SYSINIT) == 0)
|
||||
ewarnx("WARNING: %s will be started in the"
|
||||
" next runlevel", applet);
|
||||
}
|
||||
|
||||
if (state & RC_SERVICE_STARTED) {
|
||||
@@ -748,7 +748,7 @@ svc_start(bool deps)
|
||||
depoptions |= RC_DEP_STRICT;
|
||||
|
||||
if (deps) {
|
||||
if (!deptree && ((deptree = _rc_deptree_load(NULL)) == NULL))
|
||||
if (!deptree && ((deptree = _rc_deptree_load(0, NULL)) == NULL))
|
||||
eerrorx("failed to load deptree");
|
||||
if (!types_b)
|
||||
setup_types();
|
||||
@@ -977,7 +977,7 @@ svc_stop(bool deps)
|
||||
if (rc_conf_yesno("rc_depend_strict") || errno == ENOENT)
|
||||
depoptions |= RC_DEP_STRICT;
|
||||
|
||||
if (!deptree && ((deptree = _rc_deptree_load(NULL)) == NULL))
|
||||
if (!deptree && ((deptree = _rc_deptree_load(0, NULL)) == NULL))
|
||||
eerrorx("failed to load deptree");
|
||||
|
||||
if (!types_m)
|
||||
@@ -1236,7 +1236,7 @@ runscript(int argc, char **argv)
|
||||
/* Change dir to / to ensure all init scripts don't use stuff in pwd */
|
||||
chdir("/");
|
||||
|
||||
if ((runlevel = xstrdup (getenv ("RC_RUNLEVEL"))) == NULL) {
|
||||
if ((runlevel = xstrdup(getenv("RC_RUNLEVEL"))) == NULL) {
|
||||
env_filter();
|
||||
env_config();
|
||||
runlevel = rc_runlevel_get();
|
||||
@@ -1289,7 +1289,7 @@ runscript(int argc, char **argv)
|
||||
longopts, (int *)0)) != -1)
|
||||
switch (opt) {
|
||||
case 'd':
|
||||
setenv("RC_DEBUG", "yes", 1);
|
||||
setenv("RC_DEBUG", "YES", 1);
|
||||
break;
|
||||
case 's':
|
||||
if (!(rc_service_state(service) & RC_SERVICE_STARTED))
|
||||
@@ -1368,7 +1368,7 @@ runscript(int argc, char **argv)
|
||||
depoptions |= RC_DEP_STRICT;
|
||||
|
||||
if (!deptree &&
|
||||
((deptree = _rc_deptree_load(NULL)) == NULL))
|
||||
((deptree = _rc_deptree_load(0, NULL)) == NULL))
|
||||
eerrorx("failed to load deptree");
|
||||
|
||||
tmplist = rc_stringlist_new();
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2007-2008 Roy Marples <roy@marples.name>
|
||||
* Copyright 2007-2009 Roy Marples <roy@marples.name>
|
||||
* All rights reserved
|
||||
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -368,6 +368,7 @@ static int run_stop_schedule(const char *exec, const char *const *argv,
|
||||
long nloops;
|
||||
struct timespec ts;
|
||||
pid_t pid = 0;
|
||||
const char *const *p;
|
||||
|
||||
if (verbose) {
|
||||
if (exec)
|
||||
@@ -376,8 +377,15 @@ static int run_stop_schedule(const char *exec, const char *const *argv,
|
||||
einfo("Will stop PID in pidfile `%s'", pidfile);
|
||||
if (uid)
|
||||
einfo("Will stop processes owned by UID %d", uid);
|
||||
if (argv && *argv)
|
||||
einfo("Will stop processes of `%s'", *argv);
|
||||
if (argv && *argv) {
|
||||
einfon("Will stop processes of `");
|
||||
for (p = argv; p && *p; p++) {
|
||||
if (p != argv)
|
||||
printf(" ");
|
||||
printf("%s", *p);
|
||||
}
|
||||
printf("'\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (pidfile) {
|
||||
@@ -618,6 +626,7 @@ int start_stop_daemon(int argc, char **argv)
|
||||
char *startas = NULL;
|
||||
char *name = NULL;
|
||||
char *pidfile = NULL;
|
||||
char *retry = NULL;
|
||||
int sig = 0;
|
||||
int nicelevel = 0;
|
||||
bool background = false;
|
||||
@@ -636,8 +645,6 @@ int start_stop_daemon(int argc, char **argv)
|
||||
RC_STRINGLIST *env_list;
|
||||
RC_STRING *env;
|
||||
char *tmp, *newpath, *np;
|
||||
bool sethome = false;
|
||||
bool setuser = false;
|
||||
char *p;
|
||||
char *token;
|
||||
char exec_file[PATH_MAX];
|
||||
@@ -665,12 +672,19 @@ int start_stop_daemon(int argc, char **argv)
|
||||
eerror("%s: invalid nice level `%s' (SSD_NICELEVEL)",
|
||||
applet, tmp);
|
||||
|
||||
/* Get our initial dir */
|
||||
/* Get our user name and initial dir */
|
||||
p = getenv("USER");
|
||||
home = getenv("HOME");
|
||||
if (!home) {
|
||||
if (home == NULL || p == NULL) {
|
||||
pw = getpwuid(getuid());
|
||||
if (pw)
|
||||
home = pw->pw_dir;
|
||||
if (pw != NULL) {
|
||||
if (p == NULL)
|
||||
setenv("USER", pw->pw_name, 1);
|
||||
if (home == NULL) {
|
||||
setenv("HOME", pw->pw_dir, 1);
|
||||
home = pw->pw_dir;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while ((opt = getopt_long(argc, argv, getoptstring, longopts,
|
||||
@@ -686,7 +700,7 @@ int start_stop_daemon(int argc, char **argv)
|
||||
break;
|
||||
|
||||
case 'R': /* --retry <schedule>|<timeout> */
|
||||
parse_schedule(optarg, sig);
|
||||
retry = optarg;
|
||||
break;
|
||||
|
||||
case 'S': /* --start */
|
||||
@@ -706,14 +720,20 @@ int start_stop_daemon(int argc, char **argv)
|
||||
if (sscanf(tmp, "%d", &tid) != 1)
|
||||
pw = getpwnam(tmp);
|
||||
else
|
||||
pw = getpwuid((uid_t) tid);
|
||||
pw = getpwuid((uid_t)tid);
|
||||
|
||||
if (!pw)
|
||||
if (pw == NULL)
|
||||
eerrorx("%s: user `%s' not found",
|
||||
applet, tmp);
|
||||
uid = pw->pw_uid;
|
||||
home = pw->pw_dir;
|
||||
if (!gid)
|
||||
unsetenv("HOME");
|
||||
if (pw->pw_dir)
|
||||
setenv("HOME", pw->pw_dir, 1);
|
||||
unsetenv("USER");
|
||||
if (pw->pw_name)
|
||||
setenv("USER", pw->pw_name, 1);
|
||||
if (gid == 0)
|
||||
gid = pw->pw_gid;
|
||||
|
||||
if (p) {
|
||||
@@ -723,7 +743,7 @@ int start_stop_daemon(int argc, char **argv)
|
||||
else
|
||||
gr = getgrgid((gid_t) tid);
|
||||
|
||||
if (!gr)
|
||||
if (gr == NULL)
|
||||
eerrorx("%s: group `%s'"
|
||||
" not found",
|
||||
applet, tmp);
|
||||
@@ -737,27 +757,18 @@ int start_stop_daemon(int argc, char **argv)
|
||||
break;
|
||||
|
||||
case 'e': /* --env */
|
||||
if (putenv(optarg) == 0) {
|
||||
if (strncmp("HOME=", optarg, 5) == 0) {
|
||||
sethome = true;
|
||||
home = strchr(optarg, '=') + 1;
|
||||
} else if (strncmp("USER=", optarg, 5) == 0)
|
||||
setuser = true;
|
||||
}
|
||||
putenv(optarg);
|
||||
break;
|
||||
|
||||
case 'g': /* --group <group>|<gid> */
|
||||
{
|
||||
if (sscanf(optarg, "%d", &tid) != 1)
|
||||
gr = getgrnam(optarg);
|
||||
else
|
||||
gr = getgrgid((gid_t) tid);
|
||||
|
||||
if (!gr)
|
||||
eerrorx("%s: group `%s' not found",
|
||||
applet, optarg);
|
||||
gid = gr->gr_gid;
|
||||
}
|
||||
if (sscanf(optarg, "%d", &tid) != 1)
|
||||
gr = getgrnam(optarg);
|
||||
else
|
||||
gr = getgrgid((gid_t)tid);
|
||||
if (gr == NULL)
|
||||
eerrorx("%s: group `%s' not found",
|
||||
applet, optarg);
|
||||
gid = gr->gr_gid;
|
||||
break;
|
||||
|
||||
case 'k':
|
||||
@@ -840,13 +851,15 @@ int start_stop_daemon(int argc, char **argv)
|
||||
exec = name;
|
||||
if (name && start)
|
||||
*argv = name;
|
||||
} else if (name && (start || **argv))
|
||||
} else if (name)
|
||||
*--argv = name;
|
||||
else
|
||||
else if (exec)
|
||||
*--argv = exec;
|
||||
|
||||
if (stop || sig) {
|
||||
if ( !*argv && !pidfile && !name && !uid)
|
||||
if (stop || sig != 0) {
|
||||
if (sig == 0)
|
||||
sig = SIGTERM;
|
||||
if (!*argv && !pidfile && !name && !uid)
|
||||
eerrorx("%s: --stop needs --exec, --pidfile,"
|
||||
" --name or --user", applet);
|
||||
if (background)
|
||||
@@ -869,70 +882,44 @@ int start_stop_daemon(int argc, char **argv)
|
||||
" with --background", applet);
|
||||
}
|
||||
|
||||
if (stop || sig) {
|
||||
if (!sig)
|
||||
sig = SIGTERM;
|
||||
if (!stop)
|
||||
oknodo = true;
|
||||
if (!TAILQ_FIRST(&schedule)) {
|
||||
if (test || oknodo)
|
||||
parse_schedule("0", sig);
|
||||
else
|
||||
parse_schedule(NULL, sig);
|
||||
}
|
||||
i = run_stop_schedule(exec, (const char *const *)argv,
|
||||
pidfile, uid, quiet, verbose, test);
|
||||
|
||||
if (i < 0)
|
||||
/* We failed to stop something */
|
||||
exit(EXIT_FAILURE);
|
||||
if (test || oknodo)
|
||||
return i > 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
|
||||
/* Even if we have not actually killed anything, we should
|
||||
* remove information about it as it may have unexpectedly
|
||||
* crashed out. We should also return success as the end
|
||||
* result would be the same. */
|
||||
if (pidfile && exists(pidfile))
|
||||
unlink(pidfile);
|
||||
if (svcname)
|
||||
rc_service_daemon_set(svcname, exec,
|
||||
(const char *const *)argv,
|
||||
pidfile, false);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
/* Expand ~ */
|
||||
if (ch_dir && *ch_dir == '~')
|
||||
ch_dir = expand_home(home, ch_dir);
|
||||
if (ch_root && *ch_root == '~')
|
||||
ch_root = expand_home(home, ch_root);
|
||||
if (*exec == '~')
|
||||
exec = expand_home(home, exec);
|
||||
if (exec) {
|
||||
if (*exec == '~')
|
||||
exec = expand_home(home, exec);
|
||||
|
||||
/* Validate that the binary exists if we are starting */
|
||||
if (*exec == '/' || *exec == '.') {
|
||||
/* Full or relative path */
|
||||
if (ch_root)
|
||||
snprintf(exec_file, sizeof(exec_file), "%s/%s", ch_root, exec);
|
||||
else
|
||||
snprintf(exec_file, sizeof(exec_file), "%s", exec);
|
||||
} else {
|
||||
/* Something in $PATH */
|
||||
p = tmp = xstrdup(getenv("PATH"));
|
||||
*exec_file = '\0';
|
||||
while ((token = strsep(&p, ":"))) {
|
||||
/* Validate that the binary exists if we are starting */
|
||||
if (*exec == '/' || *exec == '.') {
|
||||
/* Full or relative path */
|
||||
if (ch_root)
|
||||
snprintf(exec_file, sizeof(exec_file), "%s/%s/%s", ch_root, token, exec);
|
||||
snprintf(exec_file, sizeof(exec_file),
|
||||
"%s/%s", ch_root, exec);
|
||||
else
|
||||
snprintf(exec_file, sizeof(exec_file), "%s/%s", token, exec);
|
||||
if (exists(exec_file))
|
||||
break;
|
||||
snprintf(exec_file, sizeof(exec_file),
|
||||
"%s", exec);
|
||||
} else {
|
||||
/* Something in $PATH */
|
||||
p = tmp = xstrdup(getenv("PATH"));
|
||||
*exec_file = '\0';
|
||||
while ((token = strsep(&p, ":"))) {
|
||||
if (ch_root)
|
||||
snprintf(exec_file, sizeof(exec_file),
|
||||
"%s/%s/%s",
|
||||
ch_root, token, exec);
|
||||
else
|
||||
snprintf(exec_file, sizeof(exec_file),
|
||||
"%s/%s", token, exec);
|
||||
if (exists(exec_file))
|
||||
break;
|
||||
*exec_file = '\0';
|
||||
}
|
||||
free(tmp);
|
||||
}
|
||||
free(tmp);
|
||||
}
|
||||
if (!exists(exec_file)) {
|
||||
if (start && !exists(exec_file)) {
|
||||
eerror("%s: %s does not exist", applet,
|
||||
*exec_file ? exec_file : exec);
|
||||
exit(EXIT_FAILURE);
|
||||
@@ -971,9 +958,41 @@ int start_stop_daemon(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
margv = nav ? nav : argv;
|
||||
|
||||
if (stop || sig) {
|
||||
if (sig == 0)
|
||||
sig = SIGTERM;
|
||||
if (!stop)
|
||||
oknodo = true;
|
||||
if (retry)
|
||||
parse_schedule(retry, sig);
|
||||
else if (test || oknodo)
|
||||
parse_schedule("0", sig);
|
||||
else
|
||||
parse_schedule(NULL, sig);
|
||||
i = run_stop_schedule(exec, (const char *const *)margv,
|
||||
pidfile, uid, quiet, verbose, test);
|
||||
|
||||
if (i < 0)
|
||||
/* We failed to stop something */
|
||||
exit(EXIT_FAILURE);
|
||||
if (test || oknodo)
|
||||
return i > 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
|
||||
/* Even if we have not actually killed anything, we should
|
||||
* remove information about it as it may have unexpectedly
|
||||
* crashed out. We should also return success as the end
|
||||
* result would be the same. */
|
||||
if (pidfile && exists(pidfile))
|
||||
unlink(pidfile);
|
||||
if (svcname)
|
||||
rc_service_daemon_set(svcname, exec,
|
||||
(const char *const *)argv,
|
||||
pidfile, false);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
if (pidfile)
|
||||
pid = get_pid(pidfile, true);
|
||||
else
|
||||
@@ -1072,23 +1091,8 @@ int start_stop_daemon(int argc, char **argv)
|
||||
eerrorx("%s: unable to set groupid to %d", applet, gid);
|
||||
if (changeuser && initgroups(changeuser, gid))
|
||||
eerrorx("%s: initgroups (%s, %d)", applet, changeuser, gid);
|
||||
if (uid) {
|
||||
if (setuid(uid))
|
||||
eerrorx ("%s: unable to set userid to %d", applet, uid);
|
||||
pw = getpwuid(uid);
|
||||
if (pw) {
|
||||
if (!sethome) {
|
||||
unsetenv("HOME");
|
||||
if (pw->pw_dir)
|
||||
setenv("HOME", pw->pw_dir, 1);
|
||||
}
|
||||
if (!setuser) {
|
||||
unsetenv("USER");
|
||||
if (pw->pw_name)
|
||||
setenv("USER", pw->pw_name, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (uid && setuid(uid))
|
||||
eerrorx ("%s: unable to set userid to %d", applet, uid);
|
||||
|
||||
/* Close any fd's to the passwd database */
|
||||
endpwent();
|
||||
|
||||
Reference in New Issue
Block a user