Compare commits
	
		
			98 Commits
		
	
	
		
			openrc-0.2
			...
			openrc-0.2
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | b41c864fc3 | ||
|   | c409dd0570 | ||
|   | aaaa0b50d8 | ||
|   | ca6f289c80 | ||
|   | f640ecaebb | ||
|   | 75eff5a86b | ||
|   | eeadc618fb | ||
|   | bb069e1618 | ||
|   | 3a592fa31b | ||
|   | 6b77cc624f | ||
|   | 328215e841 | ||
|   | b03282b901 | ||
|   | 08081f7ef4 | ||
|   | 8ca8e00a89 | ||
|   | 1df3ab05b5 | ||
|   | 775df18a70 | ||
|   | 148caecc7e | ||
|   | d0f7a63487 | ||
|   | b7e598ad91 | ||
|   | 5c114d9430 | ||
|   | f13ea77491 | ||
|   | a89171ee9b | ||
|   | 6d5d655b52 | ||
|   | 0f51f3e863 | ||
|   | be8f8d0ac0 | ||
|   | d667da8e5c | ||
|   | 9894669742 | ||
|   | b732df31ef | ||
|   | 762dc3d197 | ||
|   | 30fe99dead | ||
|   | 2d75eb7976 | ||
|   | 3663cf1e2a | ||
|   | 766ec96e3d | ||
|   | a854fe6d61 | ||
|   | 619b0b4f37 | ||
|   | c8248d05a0 | ||
|   | 5ae702339e | ||
|   | d384502e57 | ||
|   | bdaca0baf5 | ||
|   | 5188fd2592 | ||
|   | 5b800030f1 | ||
|   | 208443fa0e | ||
|   | a818eebf7b | ||
|   | 10910876d1 | ||
|   | 35b4978152 | ||
|   | cedd81801a | ||
|   | e273b4e08e | ||
|   | 50cff8ebc8 | ||
|   | aec83494d6 | ||
|   | 5ba6f0a628 | ||
|   | 5a59542629 | ||
|   | 52711bdca7 | ||
|   | 53902cefb8 | ||
|   | 75f991068d | ||
|   | e499e58310 | ||
|   | b08b6cd91b | ||
|   | 3c2b93fc9c | ||
|   | b5d829789f | ||
|   | 1e3442f95d | ||
|   | 2bda1871a1 | ||
|   | d3b111bd58 | ||
|   | dbea63b76d | ||
|   | 6a5287dbb5 | ||
|   | df8eeba2fb | ||
|   | 54fce42c6f | ||
|   | 54d7aa39dd | ||
|   | dc5d63aa97 | ||
|   | bab5d7767d | ||
|   | 799686e40d | ||
|   | d83ae59cca | ||
|   | 18b4108755 | ||
|   | e96347523f | ||
|   | f0aacec02e | ||
|   | 57e1dd7389 | ||
|   | c89b3763fb | ||
|   | 425abe40c5 | ||
|   | 725b9dc89c | ||
|   | 22d650c450 | ||
|   | 809ac86c69 | ||
|   | b3310e8e10 | ||
|   | 29369c44c1 | ||
|   | 292fe3a568 | ||
|   | 99d5046a56 | ||
|   | 0e38dcc4d2 | ||
|   | 9176b77c23 | ||
|   | fad61a7c4b | ||
|   | 0e114abf5d | ||
|   | bc369085c7 | ||
|   | 6d8b36e09d | ||
|   | 8759735711 | ||
|   | 034b9b7a12 | ||
|   | e82435c2f4 | ||
|   | 71dd280656 | ||
|   | 594d98eddc | ||
|   | dcdfdb442f | ||
|   | 143239e143 | ||
|   | 5d38d4d6e9 | ||
|   | c18c4fc4cc | 
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							| @@ -3,7 +3,7 @@ | ||||
| # All rights reserved. Released under the 2-clause BSD license. | ||||
|  | ||||
| NAME=		openrc | ||||
| VERSION=	0.2.1 | ||||
| VERSION=	0.2.5 | ||||
| PKG=		${NAME}-${VERSION} | ||||
|  | ||||
| SUBDIR=		conf.d doc etc init.d man net sh src | ||||
|   | ||||
| @@ -87,6 +87,10 @@ | ||||
| # is how long we wait for carrier. The current default is 3 seconds | ||||
| #carrier_timeout_eth0=-1 | ||||
|  | ||||
| # You may wish to disable the interface being brought down when stopping. | ||||
| # This is only of use for WakeOnLan. | ||||
| #ifdown_eth0="NO" | ||||
|  | ||||
| ############################################################################## | ||||
| # OPTIONAL MODULES | ||||
|  | ||||
|   | ||||
| @@ -120,6 +120,10 @@ | ||||
| # tables you may have to set a global metric as the due to a simple read of | ||||
| # the routing table taking over a minute at a time. | ||||
|  | ||||
| # You may wish to disable the interface being brought down when stopping. | ||||
| # This is only of use for WakeOnLan. | ||||
| #ifdown_eth0="NO" | ||||
|  | ||||
| ############################################################################## | ||||
| # OPTIONAL MODULES | ||||
|  | ||||
|   | ||||
| @@ -3,5 +3,8 @@ SRCS=	avahi-dnsconfd.in avahid.in dbus.in hald.in named.in ntpd.in \ | ||||
| 	openvpn.in polkitd.in sshd.in | ||||
|  | ||||
| MK=	../mk | ||||
|  | ||||
| SED_EXTRA+= -e 's:@VARBASE@:/var:g' | ||||
|  | ||||
| include ${MK}/scripts.mk | ||||
| include Makefile.${OS} | ||||
|   | ||||
| @@ -3,7 +3,7 @@ | ||||
| # All rights reserved. Released under the 2-clause BSD license. | ||||
|  | ||||
| command=@PKG_PREFIX@/bin/dbus-daemon | ||||
| pidfile=@VARBASE@/run/dbus/dbus.pid | ||||
| pidfile=@VARBASE@/run/dbus/pid | ||||
| command_args="${dbusd_args---system}" | ||||
| name="Message Bus Daemon" | ||||
|  | ||||
|   | ||||
| @@ -4,12 +4,22 @@ | ||||
|  | ||||
| command=/usr/sbin/named | ||||
| command_args=${named_args} | ||||
| pidfile=@VARBASE@/run/named/pid | ||||
| pidfile=@VARBASE@/run/named.pid | ||||
| name="Domain Name server" | ||||
| extra_started_commands="reload" | ||||
|  | ||||
| namedb=/etc/namedb | ||||
| named_uid=${named_uid:-bind} | ||||
| uid=named | ||||
| case "${RC_UNAME}" in | ||||
| 	FreeBSD) | ||||
| 		uid=bind | ||||
| 		pidfile=@VARBASE@/run/named/pid | ||||
| 		;; | ||||
| 	Linux) | ||||
| 		uid=bind | ||||
| 		;; | ||||
| esac | ||||
| named_uid=${named_uid:-${uid}} | ||||
|  | ||||
| depend() | ||||
| { | ||||
|   | ||||
							
								
								
									
										13
									
								
								init.d/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										13
									
								
								init.d/.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -26,3 +26,16 @@ mixer | ||||
| nscd | ||||
| powerd | ||||
| syscons | ||||
| net.lo | ||||
| ttys | ||||
| swap-blk | ||||
| wscons | ||||
| consolefont | ||||
| hwclock | ||||
| keymaps | ||||
| modules | ||||
| mtab | ||||
| numlock | ||||
| procfs | ||||
| termencoding | ||||
| devdb | ||||
|   | ||||
| @@ -3,7 +3,14 @@ SRCS=	bootmisc.in fsck.in halt.sh.in hostname.in local.in localmount.in \ | ||||
| 	netmount.in root.in swap.in sysctl.in urandom.in | ||||
| BIN=	${OBJS} | ||||
|  | ||||
| INSTALLAFTER=	_installafter | ||||
| CLEANFILES+=	net.lo | ||||
| TARGETS+=	net.lo | ||||
|  | ||||
| MK=	../mk | ||||
| include ${MK}/os.mk | ||||
| include Makefile.${OS} | ||||
| include ${MK}/scripts.mk | ||||
|  | ||||
| _installafter: realinstall | ||||
| 	${INSTALL} -m ${BINMODE} net.lo ${DESTDIR}/${INITDIR}/${NET_LO} | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| NET_LO=	net.lo0 | ||||
|  | ||||
| # Generic BSD scripts | ||||
| SRCS+=	hostid.in moused.in newsyslog.in pf.in rarpd.in rc-enabled.in \ | ||||
| 	rpcbind.in savecore.in syslogd.in | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| NET_LO=	net.lo | ||||
|  | ||||
| SRCS+=	hwclock.in consolefont.in keymaps.in modules.in mtab.in numlock.in \ | ||||
| 	procfs.in termencoding.in | ||||
|  | ||||
|   | ||||
| @@ -1,9 +1,11 @@ | ||||
| NET_LO=	net.lo0 | ||||
|  | ||||
| # Generic BSD scripts | ||||
| SRCS+=	hostid.in moused.in newsyslog.in pf.in rarpd.in rc-enabled.in \ | ||||
| 	rpcbind.in savecore.in syslogd.in | ||||
|  | ||||
| # These are NetBSD specific | ||||
| SRCS+=	swap-blk.in ttys.in wscons.in | ||||
| SRCS+=	devdb.in swap-blk.in ttys.in wscons.in | ||||
|  | ||||
| .SUFFIXES:	.BSD.in | ||||
| .BSD.in: | ||||
|   | ||||
| @@ -11,21 +11,25 @@ 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" | ||||
| 		local startopts="-x . -depth" delete="-exec rm -rf -- {} ;" | ||||
|  | ||||
| 		if [ "${RC_UNAME}" = "Linux" ]; then | ||||
| 			startopts=". -xdev -depth" | ||||
| 			# busybox find / rm cannot handle -- | ||||
| 			delete="-delete" | ||||
| 		fi | ||||
| 		local startopts="-x . -depth" | ||||
| 		[ "${RC_UNAME}" = "Linux" ] && startopts=". -xdev -depth" | ||||
|  | ||||
| 		# Faster than find | ||||
| 		rm -rf -- [b-ikm-pr-zA-Z0-9\.]* | ||||
| @@ -45,8 +49,7 @@ cleanup_tmp_dir() | ||||
| 			! -path "./journal/*" \ | ||||
| 			! -path "./.private" \ | ||||
| 			! -path "./.private/*" \ | ||||
| 			${delete} \ | ||||
| 			-type d -prune | ||||
| 			-exec rm -rf {} \; | ||||
| 		eend 0 | ||||
| 	else | ||||
| 		ebegin "Cleaning ${dir} directory" | ||||
| @@ -60,12 +63,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 +74,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 dev.db \ | ||||
| 			! -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() | ||||
|   | ||||
							
								
								
									
										21
									
								
								init.d/devdb.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								init.d/devdb.in
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| #!@PREFIX@/sbin/runscript | ||||
| # Copyright 2008 Roy Marples <roy@marples.name> | ||||
| # All rights reserved. Released under the 2-clause BSD license. | ||||
|  | ||||
| description="Creates the dev database" | ||||
|  | ||||
| depend() | ||||
| { | ||||
| 	need localmount | ||||
| } | ||||
|  | ||||
| start() | ||||
| { | ||||
| 	ebegin "Bulding the dev database" | ||||
| 	if [ /var/run/dev.db -nt /dev ]; then | ||||
| 		: | ||||
| 	else | ||||
| 		dev_mkdb | ||||
| 	fi | ||||
| 	eend $? | ||||
| } | ||||
| @@ -3,7 +3,7 @@ | ||||
| # All rights reserved. Released under the 2-clause BSD license. | ||||
|  | ||||
| description="Check and repair filesystems according to /etc/fstab" | ||||
| _ISF=" | ||||
| _IFS=" | ||||
| " | ||||
|  | ||||
| depend() | ||||
| @@ -27,20 +27,32 @@ _reboot() { | ||||
|  | ||||
| start() | ||||
| { | ||||
| 	local reboot_opts= fsck_opts= p= | ||||
| 	local reboot_opts= fsck_opts= p= check_extra= | ||||
|  | ||||
| 	ebegin "Checking local filesystems" | ||||
| 	if [ -e /fastboot ]; then | ||||
| 		ewarn "Skipping fsck due to /fastboot" | ||||
| 		return 0 | ||||
| 	fi | ||||
| 	if [ -e /forcefsck ]; then | ||||
| 		fsck_opts="${fsck_opts} -f" | ||||
| 		check_extra="(check forced)" | ||||
| 	fi | ||||
|  | ||||
| 	if [ -n "${fsck_passno}" ]; then | ||||
| 		check_extra="[passno ${fsck_passno}] ${check_extra}" | ||||
| 	fi | ||||
| 	ebegin "Checking local filesystems ${check_extra}" | ||||
| 	for p in ${fsck_passno}; do | ||||
| 		local IFS="${_IFS}" | ||||
| 		case "${p}" in | ||||
| 			[0-9]*) p="=${p}";; | ||||
| 		esac | ||||
| 		set -- "$@" "$(fstabinfo --passno "${p}")" | ||||
| 		set -- "$@" $(fstabinfo --passno "${p}") | ||||
| 		unset IFS | ||||
| 	done | ||||
|  | ||||
| 	if [ "${RC_UNAME}" = "Linux" ]; then | ||||
| 		fsck_opts="-C0 -T" | ||||
| 		fsck_opts="${fsck_opts} -C0 -T" | ||||
| 		if [ -z "${fsck_passno}" ]; then | ||||
| 			fsck_args=${fsck_args--A -p} | ||||
| 			if echo 2>/dev/null >/.test.$$; then | ||||
| @@ -51,7 +63,7 @@ start() | ||||
| 		reboot_opts="-f" | ||||
| 	fi | ||||
|  | ||||
| 	trap : QUIT | ||||
| 	trap : INT QUIT | ||||
| 	fsck ${fsck_args--p} ${fsck_opts} "$@" | ||||
| 	case $? in | ||||
| 		0)       eend 0; return 0;; | ||||
|   | ||||
| @@ -28,6 +28,7 @@ sync; sync | ||||
| #   1) we don't need (and by default can't) umount anything (VServer) or | ||||
| #   2) the host utils take care of all umounting stuff (OpenVZ) | ||||
| if [ "${RC_SYS}" = "VSERVER" -o "${RC_SYS}" = "OPENVZ" ]; then | ||||
| 	[ "${RC_SYS}" = "OPENVZ" -a "$1" = "reboot" ] && echo "" > /reboot | ||||
| 	if [ -e @SYSCONFDIR@/init.d/"$1".sh ]; then | ||||
| 		. @SYSCONFDIR@/init.d/"$1".sh | ||||
| 	else | ||||
|   | ||||
| @@ -8,7 +8,7 @@ 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}} | ||||
|  | ||||
| @@ -40,7 +40,7 @@ start() | ||||
| 		kmode="-u" | ||||
| 		msg="UTF-8" | ||||
| 	fi | ||||
| 	yesno ${windowskeys} && wkeys="windowkeys" | ||||
| 	yesno ${windowkeys} && wkeys="windowkeys" | ||||
| 	loadkeys -q ${loadkeys_uni} ${wkeys} ${keymap} ${extended_keymaps}  | ||||
| 	eend $? "Error loading key mappings" || return $? | ||||
|  | ||||
|   | ||||
| @@ -28,7 +28,7 @@ depend() | ||||
| 		*) after net.lo net.lo0;; | ||||
| 	esac | ||||
| 
 | ||||
| 	if type depend_${IFVAR} >/dev/null 2>&1; then | ||||
| 	if [ "$(command -v "depend_${IFVAR}")" = "depend_${IFVAR}" ]; then | ||||
| 		depend_${IFVAR} | ||||
| 	fi | ||||
| 
 | ||||
| @@ -344,7 +344,7 @@ _load_modules() | ||||
| 		# Wrap our provides | ||||
| 		local f= | ||||
| 		for f in pre_start start post_start; do  | ||||
| 			eval "${provides}_${f}() { type ${mod}_${f} >/dev/null 2>&1 || return 0; ${mod}_${f} \"\$@\"; }" | ||||
| 			eval "${provides}_${f}() { [ "$(command -v "${mod}_${f}")" = "${mod}_${f}" ] || return 0; ${mod}_${f} \"\$@\"; }" | ||||
| 		done | ||||
| 
 | ||||
| 		eval module_${mod}_provides="${provides}" | ||||
| @@ -358,7 +358,7 @@ _load_modules() | ||||
| 			eval x=\$module_${mod}_provides | ||||
| 			[ -z "${x}" ] && continue | ||||
| 			for f in pre_start start post_start; do  | ||||
| 				eval "${x}_${f}() { type ${mod}_${f} >/dev/null 2>&1 || return 0; ${mod}_${f} \"\$@\"; }" | ||||
| 				eval "${x}_${f}() { [ "$(command -v "${mod}_${f}")" = "${mod}_${f}" ] || return 0; ${mod}_${f} \"\$@\"; }" | ||||
| 			done | ||||
| 			eval module_${x}_providedby="${mod}" | ||||
| 			;; | ||||
| @@ -462,7 +462,7 @@ start() | ||||
| 	# We up the iface twice if we have a preup to ensure it's up if | ||||
| 	# available in preup and afterwards incase the user inadvertently | ||||
| 	# brings it down | ||||
| 	if type preup >/dev/null 2>&1; then | ||||
| 	if [ "$(command -v preup)" = "preup" ]; then | ||||
| 		_up 2>/dev/null | ||||
| 		ebegin "Running preup" | ||||
| 		eindent | ||||
| @@ -473,7 +473,7 @@ start() | ||||
| 	_up 2>/dev/null | ||||
| 	 | ||||
| 	for module in ${MODULES}; do | ||||
| 		if type "${module}_pre_start" >/dev/null 2>&1; then | ||||
| 		if [ "$(command -v "${module}_pre_start")" = "${module}_pre_start" ]; then | ||||
| 			${module}_pre_start || exit $? | ||||
| 		fi | ||||
| 	done | ||||
| @@ -522,7 +522,7 @@ start() | ||||
| 			null) :;; | ||||
| 			[0-9]*|*:*) _add_address ${config};; | ||||
| 			*) | ||||
| 				if type "${config}_start" >/dev/null 2>&1; then | ||||
| 				if [ "$(command -v "${config}_start")" = "${config}_start" ]; then | ||||
| 					"${config}"_start | ||||
| 				else | ||||
| 					eerror "nothing provides \`${config}'" | ||||
| @@ -547,7 +547,7 @@ start() | ||||
| 	done | ||||
| 
 | ||||
| 	if ! ${oneworked}; then | ||||
| 		if type failup >/dev/null 2>&1; then | ||||
| 		if [ "$(command -v failup)" = "failup" ]; then | ||||
| 			ebegin "Running failup" | ||||
| 			eindent | ||||
| 			failup | ||||
| @@ -600,12 +600,12 @@ ${routes}" | ||||
| 	fi | ||||
| 
 | ||||
| 	for module in ${MODULES}; do | ||||
| 		if type "${module}_post_start" >/dev/null 2>&1; then | ||||
| 		if [ "$(command -v "${module}_post_start")" = "${module}_post_start" ]; then | ||||
| 			${module}_post_start || exit $? | ||||
| 		fi | ||||
| 	done | ||||
| 
 | ||||
| 	if type postup >/dev/null 2>&1; then | ||||
| 	if [ "$(command -v postup)" = "postup" ]; then | ||||
| 		ebegin "Running postup" | ||||
| 		eindent | ||||
| 		postup  | ||||
| @@ -628,7 +628,7 @@ stop() | ||||
| 		_load_modules false | ||||
| 	fi | ||||
| 
 | ||||
| 	if type predown >/dev/null 2>&1; then | ||||
| 	if [ "$(command -v predown)" = "predown" ]; then | ||||
| 		ebegin "Running predown" | ||||
| 		eindent | ||||
| 		predown || return 1 | ||||
| @@ -641,35 +641,40 @@ stop() | ||||
| 	fi | ||||
| 
 | ||||
| 	for module in ${MODULES}; do | ||||
| 		if type "${module}_pre_stop" >/dev/null 2>&1; then | ||||
| 		if [ "$(command -v "${module}_pre_stop")" = "${module}_pre_stop" ]; then | ||||
| 			${module}_pre_stop || exit $? | ||||
| 		fi | ||||
| 	done | ||||
| 
 | ||||
| 	for module in ${MODULES}; do | ||||
| 		if type "${module}_stop" >/dev/null 2>&1; then | ||||
| 		if [ "$(command -v "${module}_stop")" = "${module}_stop" ]; then | ||||
| 			${module}_stop | ||||
| 		fi | ||||
| 	done | ||||
| 
 | ||||
| 	# Only delete addresses for non PPP interfaces | ||||
| 	if ! type is_ppp >/dev/null 2>&1 || ! is_ppp; then | ||||
| 	if ! [ "$(command -v is_ppp)" = "is_ppp" ] || ! is_ppp; then | ||||
| 		_delete_addresses "${IFACE}" | ||||
| 	fi | ||||
| 
 | ||||
| 	for module in ${MODULES}; do | ||||
| 		if type "${module}_post_stop" >/dev/null 2>&1; then | ||||
| 		if [ "$(command -v "${module}_post_stop")" = "${module}_post_stop" ]; then | ||||
| 			${module}_post_stop | ||||
| 		fi | ||||
| 	done | ||||
| 
 | ||||
| 	! yesno ${IN_BACKGROUND} && \ | ||||
| 	[ "${IFACE}" != "lo" -a "${IFACE}" != "lo0" ] && \ | ||||
| 	_down 2>/dev/null | ||||
| 	# If not in background, and not loopback then bring the interface down | ||||
| 	# unless overridden. | ||||
| 	if ! yesno ${IN_BACKGROUND} && \ | ||||
| 	[ "${IFACE}" != "lo" -a "${IFACE}" != "lo0" ]; then | ||||
| 		eval module=\$ifdown_${IFVAR} | ||||
| 		module=${module:-YES} | ||||
| 		yesno ${module} && _down 2>/dev/null | ||||
| 	fi | ||||
| 
 | ||||
| 	type resolvconf >/dev/null 2>&1 && resolvconf -d "${IFACE}" 2>/dev/null | ||||
| 
 | ||||
| 	if type postdown >/dev/null 2>&1; then | ||||
| 	if [ "$(command -v "postdown")" = "postdown" ]; then | ||||
| 		ebegin "Running postdown" | ||||
| 		eindent | ||||
| 		postdown | ||||
| @@ -23,17 +23,18 @@ 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 | ||||
| 	need net ${pmap} | ||||
| 	use afc-client amd autofs dns nfs nfsmount portmap rpcbind rpc.statd | ||||
| 	use afc-client amd autofs openvpn | ||||
| 	use dns nfs nfsmount portmap rpcbind rpc.statd | ||||
| 	keyword nojail noopenvz noprefix novserver | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -26,7 +26,7 @@ start() | ||||
| 		local usbfs=$(grep -Fow usbfs /proc/filesystems || | ||||
| 					  grep -Fow usbdevfs /proc/filesystems) | ||||
| 		if [ -n "${usbfs}" ]; then | ||||
| 			ebegin "Mounting USB device filesystem (${usbfs})" | ||||
| 			ebegin "Mounting USB device filesystem [${usbfs}]" | ||||
| 			local usbgid="$(getent group usb | \ | ||||
| 				sed -e 's/.*:.*:\(.*\):.*/\1/')" | ||||
| 			mount -t ${usbfs} \ | ||||
|   | ||||
| @@ -13,7 +13,7 @@ depend() | ||||
| start() | ||||
| { | ||||
| 	if echo 2>/dev/null >/.test.$$; then | ||||
| 		rm -f /.test.$$ | ||||
| 		rm -f /.test.$$ /fastboot /forcefsck | ||||
| 		return 0 | ||||
| 	fi | ||||
|  | ||||
| @@ -22,5 +22,7 @@ start() | ||||
| 		Linux)	mount -n -o remount,rw /;; | ||||
| 		*)	mount -u -o rw /;; | ||||
| 	esac | ||||
| 	eend $? "Root filesystem could not be mounted read/write" | ||||
| 	if eend $? "Root filesystem could not be mounted read/write"; then | ||||
| 		rm -f /fastboot /forcefsck | ||||
| 	fi | ||||
| } | ||||
|   | ||||
| @@ -49,10 +49,10 @@ start() { | ||||
|  | ||||
| 	local v= f= | ||||
| 	for v in font8x16 font8x14 font8x8; do | ||||
| 		f=$(eval \$"${v}") | ||||
| 		eval f=\$${v} | ||||
| 		if [ -n "${f}" ]; then | ||||
| 			ebegin "Setting font ${f}" | ||||
| 			vidcontrol -f ${v##FONT} ${f} | ||||
| 			vidcontrol -f ${v##font} ${f} | ||||
| 			eend $? | ||||
| 		fi | ||||
| 	done | ||||
|   | ||||
| @@ -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" | ||||
|   | ||||
| @@ -22,9 +22,9 @@ SED_REPLACE=		-e 's:@SHELL@:${SH}:g' -e 's:@LIB@:${LIBNAME}:g' -e 's:@SYSCONFDIR | ||||
| .in: | ||||
| 	${SED} ${SED_REPLACE} ${SED_EXTRA} $< > $@ | ||||
|  | ||||
| all: ${OBJS} | ||||
| all: ${OBJS} ${TARGETS} | ||||
|  | ||||
| realinstall: ${BIN} ${CONF} ${CONF_APPEND} | ||||
| realinstall: ${BIN} ${CONF} ${INC} | ||||
| 	@if test -n "${DIR}"; then \ | ||||
| 		${ECHO} ${INSTALL} -d ${DESTDIR}/${DIR}; \ | ||||
| 		${INSTALL} -d ${DESTDIR}/${DIR} || exit $$?; \ | ||||
|   | ||||
| @@ -15,20 +15,41 @@ _config_vars="$_config_vars dhcp dhcpcd" | ||||
|  | ||||
| dhcpcd_start() | ||||
| { | ||||
| 	local args= opt= opts= pidfile="/var/run/dhcpcd-${IFACE}.pid" | ||||
|  | ||||
| 	local args= opt= opts= pidfile="/var/run/dhcpcd-${IFACE}.pid" new=true | ||||
| 	eval args=\$dhcpcd_${IFVAR} | ||||
|  | ||||
| 	# Get our options | ||||
| 	eval opts=\$dhcp_${IFVAR} | ||||
| 	[ -z "${opts}" ] && opts=${dhcp} | ||||
|  | ||||
| 	case "$(dhcpcd --version)" in | ||||
| 		"dhcpcd "[123]*) new=false;; | ||||
| 	esac | ||||
|  | ||||
| 	# Map some generic options to dhcpcd | ||||
| 	for opt in ${opts}; do | ||||
| 		case "${opt}" in | ||||
| 			nodns) args="${args} -R";; | ||||
| 			nontp) args="${args} -N";; | ||||
| 			nonis) args="${args} -Y";; | ||||
| 			nodns) | ||||
| 				if ${new}; then | ||||
| 					args="${args} -C resolv.conf" | ||||
| 				else | ||||
| 					args="${args} -R" | ||||
| 				fi | ||||
| 				;; | ||||
| 			nontp) | ||||
| 				if ${new}; then | ||||
| 					args="${args} -C ntp.conf" | ||||
| 				else | ||||
| 					args="${args} -N" | ||||
| 				fi | ||||
| 				;; | ||||
| 			nonis) | ||||
| 				if ${new}; then | ||||
| 					args="${args} -C yp.conf" | ||||
| 				else | ||||
| 					args="${args} -Y" | ||||
| 				fi | ||||
| 				;; | ||||
| 			nogateway) args="${args} -G";; | ||||
| 			nosendhost) args="${args} -h ''"; | ||||
| 		esac | ||||
|   | ||||
| @@ -151,9 +151,12 @@ _delete_addresses() | ||||
| { | ||||
| 	einfo "Removing addresses" | ||||
| 	eindent | ||||
| 	LC_ALL=C ifconfig "${IFACE}" | while read inet address rest; do | ||||
| 	LC_ALL=C ifconfig "${IFACE}" | while read inet address ali rest; do | ||||
| 		case "${inet}" in | ||||
| 			inet|inet6) | ||||
| 				if [ "${address}" = "alias" ]; then | ||||
| 					address="${ali}" | ||||
| 				fi | ||||
| 				case "${address}" in | ||||
| 					*"%${IFACE}"|::1) continue;; | ||||
| 					127.0.0.1) [ "${IFACE}" = "lo0" ] && continue;; | ||||
|   | ||||
| @@ -56,7 +56,7 @@ _set_flag() | ||||
| _get_mac_address() | ||||
| { | ||||
| 	local mac=$(LC_ALL=C ifconfig "${IFACE}" | \ | ||||
| 	sed -n -e 's/.* HWaddr \(..:..:..:..:..:..\).*/\1/p') | ||||
| 	sed -n -e 's/.* \(HWaddr\|ether\) \(..:..:..:..:..:..\).*/\2/p') | ||||
|  | ||||
| 	case "${mac}" in | ||||
| 		00:00:00:00:00:00);; | ||||
| @@ -77,7 +77,7 @@ _set_mac_address() | ||||
| _get_inet_address() | ||||
| { | ||||
| 	set -- $(LC_ALL=C ifconfig "${IFACE}" | | ||||
| 	sed -n -e 's/.*inet addr:\([^ ]*\).*Mask:\([^ ]*\).*/\1 \2/p') | ||||
| 	sed -n -e 's/.*\(inet addr:\|inet \)\([^ ]*\).*\(Mask:\|netmask \)\([^ ]*\).*/\2 \4/p') | ||||
| 	[ -z "$1" ] && return 1 | ||||
|  | ||||
| 	echo -n "$1" | ||||
| @@ -145,7 +145,7 @@ _add_address() | ||||
| 	# IPv4 is tricky - ifconfig requires an aliased device | ||||
| 	# for multiple addresses | ||||
| 	local iface="${IFACE}" | ||||
| 	if LC_ALL=C ifconfig "${iface}" | grep -Eq "\<inet addr:.*"; then | ||||
| 	if LC_ALL=C ifconfig "${iface}" | grep -Eq '\<inet (addr:)?.*'; then | ||||
| 		# Get the last alias made for the interface and add 1 to it | ||||
| 		i=$(ifconfig | sed '1!G;h;$!d' | grep -m 1 -o "^${iface}:[0-9]*" \ | ||||
| 			| sed -n -e 's/'"${iface}"'://p') | ||||
| @@ -234,8 +234,12 @@ _delete_addresses() | ||||
| 	# Remove IPv6 addresses | ||||
| 	local addr= | ||||
| 	for addr in $(LC_ALL=C ifconfig "${IFACE}" | \ | ||||
| 		sed -n -e 's/^.*inet6 addr: \([^ ]*\) Scope:[^L].*/\1/p'); do | ||||
| 		[ "${addr}" = "::1/128" -a "${IFACE}" = "lo" ] && continue | ||||
| 		sed -n -e 's/^.*\(inet6 addr:\|inet6\) \([^ ]*\) .*\(Scope:[^L]\|scopeid [^<]*<[^l]\).*/\2/p'); do | ||||
| 		if [ "${IFACE}" = "lo" ]; then | ||||
| 			case "${addr}" in | ||||
| 				"::1/128"|"/128") continue;; | ||||
| 			esac | ||||
| 		fi | ||||
| 		einfo "${addr}" | ||||
| 		ifconfig "${IFACE}" inet6 del "${addr}" | ||||
| 	done | ||||
|   | ||||
| @@ -10,12 +10,12 @@ iproute2_depend() | ||||
|  | ||||
| _up() | ||||
| { | ||||
| 	ip link set up dev "${IFACE}" | ||||
| 	ip link set "${IFACE}" up | ||||
| } | ||||
|  | ||||
| _down() | ||||
| { | ||||
| 	ip link set down dev "${IFACE}" | ||||
| 	ip link set "${IFACE}" down | ||||
| } | ||||
|  | ||||
| _exists() | ||||
| @@ -78,7 +78,7 @@ _get_mac_address() | ||||
|  | ||||
| _set_mac_address() | ||||
| { | ||||
| 	ip link set address "$1" dev "${IFACE}" | ||||
| 	ip link set "${IFACE}" address "$1" | ||||
| } | ||||
|  | ||||
| _get_inet_addresses() | ||||
| @@ -126,7 +126,7 @@ _add_address() | ||||
| 			;; | ||||
| 	esac | ||||
|  | ||||
| 	ip addr add dev "${IFACE}" "$@" | ||||
| 	ip addr add "$@" dev "${IFACE}" | ||||
| } | ||||
|  | ||||
| _add_route() | ||||
| @@ -184,12 +184,12 @@ iproute2_pre_start() | ||||
| 	# MTU support | ||||
| 	local mtu= | ||||
| 	eval mtu=\$mtu_${IFVAR} | ||||
| 	[ -n "${mtu}" ] && ip link set mtu "${mtu}" dev "${IFACE}" | ||||
| 	[ -n "${mtu}" ] && ip link set "${IFACE}" mtu "${mtu}" | ||||
|  | ||||
| 	# TX Queue Length support | ||||
| 	local len= | ||||
| 	eval len=\$txqueuelen_${IFVAR} | ||||
| 	[ -n "${len}" ] && ip link set txqueuelen "${len}" dev "${IFACE}" | ||||
| 	[ -n "${len}" ] && ip link set "${IFACE}" txqueuelen "${len}" | ||||
|  | ||||
| 	local tunnel= | ||||
| 	eval tunnel=\$iptunnel_${IFVAR} | ||||
| @@ -208,6 +208,8 @@ iproute2_pre_start() | ||||
|  | ||||
| _iproute2_ipv6_tentative() | ||||
| { | ||||
| 	# Only check tentative when we have a carrier. | ||||
| 	LC_ALL=C ip link show dev "${IFACE}" | grep -q "NO-CARRIER" && return 1 | ||||
| 	LC_ALL=C ip addr show dev "${IFACE}" | \ | ||||
| 		grep -q "^[[:space:]]*inet6 .* tentative" | ||||
| } | ||||
|   | ||||
| @@ -414,8 +414,9 @@ iwconfig_connect_preferred() | ||||
| 	[ $# = 0 ] && eval set -- $(_flatten_array "preferred_aps") | ||||
| 	[ $# = 0 ] && return 1 | ||||
|  | ||||
| 	local ssid= i=0 mode= mac= caps= freq= chan= | ||||
| 	local ssid= i= mode= mac= caps= freq= chan= | ||||
| 	for ssid; do | ||||
| 		i=0 | ||||
| 		while [ ${i} -le ${APS} ]  ; do | ||||
| 			eval e=\$SSID_${i} | ||||
| 			if [ "${e}" = "${ssid}" ] ; then | ||||
| @@ -484,7 +485,7 @@ iwconfig_defaults() | ||||
|  | ||||
| iwconfig_configure() | ||||
| { | ||||
| 	local x APS | ||||
| 	local x= APS=-1 | ||||
| 	eval SSID=\$ssid_${IFVAR} | ||||
|  | ||||
| 	# Setup ad-hoc mode? | ||||
|   | ||||
| @@ -206,9 +206,13 @@ iwconfig_wait_for_association() | ||||
| 		# Use sysfs if we can | ||||
| 		if [ -e /sys/class/net/"${IFACE}"/carrier ]; then | ||||
| 			if [ "$(cat /sys/class/net/"${IFACE}"/carrier)" = "1" ]; then | ||||
| 				# Double check we have an ssid. This is mainly for buggy | ||||
| 				# prism54 drivers that always set their carrier on :/ | ||||
| 				[ -n "$(iwgetid --raw "${IFACE}")" ] && return 0 | ||||
| 				# Double check we have an ssid and a non-zero | ||||
| 				# mac address.  This is mainly for buggy | ||||
| 				# prism54 drivers that always set their | ||||
| 				# carrier on or buggy madwifi drivers that | ||||
| 				# sometimes have carrier on and ssid set | ||||
| 				# without being associated.  :/ | ||||
| 				[ -n "$(iwgetid --raw "${IFACE}")" ] && [ "$(iwgetid --ap --raw "${IFACE}")" != "00:00:00:00:00:00" ] && return 0 | ||||
| 			fi | ||||
| 		else | ||||
| 			local atest= | ||||
| @@ -525,7 +529,7 @@ iwconfig_force_preferred() | ||||
| 			i=$((${i} + 1)) | ||||
| 		done | ||||
| 		if ! ${found_AP}; then | ||||
| 			SSID=${e} | ||||
| 			SSID=${ssid} | ||||
| 			iwconfig_associate && return 0 | ||||
| 		fi | ||||
| 	done | ||||
| @@ -610,7 +614,7 @@ iwconfig_defaults() | ||||
|  | ||||
| iwconfig_configure() | ||||
| { | ||||
| 	local x= APS= | ||||
| 	local x= APS=-1 | ||||
| 	eval SSID=\$ssid_${IFVAR} | ||||
|  | ||||
| 	# Support old variable | ||||
|   | ||||
| @@ -78,11 +78,9 @@ wpa_supplicant_pre_start() | ||||
| 	service_set_value "SSID" "" | ||||
| 	ebegin "Starting wpa_supplicant on ${IFVAR}" | ||||
|  | ||||
| 	if [ -x /sbin/iwconfig ]; then | ||||
| 		local x= | ||||
| 		for x in txpower rate rts frag; do | ||||
| 			iwconfig "${IFACE}" "${x}" auto 2>/dev/null | ||||
| 		done | ||||
| 	if type iwconfig_defaults >/dev/null 2>&1; then | ||||
| 		iwconfig_defaults | ||||
| 		iwconfig_user_config | ||||
| 	fi | ||||
|  | ||||
| 	cfgfile=${opts##* -c} | ||||
|   | ||||
| @@ -2,4 +2,4 @@ | ||||
| BOOT+=		hostid net.lo0 newsyslog savecore syslogd | ||||
|  | ||||
| # NetBSD specific stuff | ||||
| BOOT+=		swap-blk ttys wscons | ||||
| BOOT+=		devdb swap-blk ttys wscons | ||||
|   | ||||
							
								
								
									
										2
									
								
								sh/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								sh/.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -4,3 +4,5 @@ net.sh | ||||
| rc-functions.sh | ||||
| runscript.sh | ||||
| init.sh | ||||
| ifwatchd-carrier.sh | ||||
| ifwatchd-nocarrier.sh | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| DIR=	${PREFIX}/${RC_LIB}/sh | ||||
| SRCS=	functions.sh.in gendepends.sh.in net.sh.in \ | ||||
| SRCS=	functions.sh.in gendepends.sh.in \ | ||||
| 	rc-functions.sh.in runscript.sh.in | ||||
| INC=	init-common-post.sh rc-mount.sh functions.sh rc-functions.sh | ||||
| BIN=	gendepends.sh init.sh net.sh runscript.sh | ||||
| BIN=	gendepends.sh init.sh runscript.sh | ||||
|  | ||||
| INSTALLAFTER=	_installafter | ||||
|  | ||||
| @@ -13,8 +13,6 @@ include ${MK}/scripts.mk | ||||
|  | ||||
| _installafter: | ||||
| 	${INSTALL} -d ${DESTDIR}/${INITDIR} | ||||
| 	@# Provide an init script for the loopback interface | ||||
| 	ln -snf ${PREFIX}/${RC_LIB}/sh/net.sh ${DESTDIR}/${INITDIR}/${NET_LO} || exit $$? | ||||
| 	@# Put functions.sh into the init.d dir so 3rd party apps don't have to | ||||
| 	@# be multilib aware | ||||
| 	ln -snf ${PREFIX}/${RC_LIB}/sh/functions.sh ${DESTDIR}/${INITDIR} || exit $$? | ||||
|   | ||||
| @@ -1,7 +1,5 @@ | ||||
| SRCS+=		init.sh.in | ||||
|  | ||||
| NET_LO=		net.lo0 | ||||
|  | ||||
| .SUFFIXES:	.sh.BSD.in | ||||
| .sh.BSD.in.sh: | ||||
| 	${SED} ${SED_REPLACE} ${SED_EXTRA} $< > $@ | ||||
|   | ||||
| @@ -1,4 +1,3 @@ | ||||
| NET_LO=		net.lo | ||||
| SRCS+=		init.sh.in init-early.sh.in | ||||
| BIN+=		init-early.sh | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| SRCS+=		init.sh.in | ||||
|  | ||||
| NET_LO=		net.lo0 | ||||
| SRCS+=		ifwatchd-carrier.sh.in ifwatchd-nocarrier.sh.in | ||||
| BIN+=		ifwatchd-carrier.sh ifwatchd-nocarrier.sh | ||||
|  | ||||
|   | ||||
| @@ -38,6 +38,10 @@ yesno() | ||||
| 	esac | ||||
| } | ||||
|  | ||||
| rc_runlevel() { | ||||
|     rc-status --runlevel | ||||
| } | ||||
|  | ||||
| _sanitize_path() | ||||
| { | ||||
| 	local IFS=":" p= path= | ||||
|   | ||||
| @@ -48,12 +48,14 @@ do | ||||
|  | ||||
| 	cd "${_dir}" | ||||
| 	for RC_SERVICE in *; do | ||||
| 		[ -x "${RC_SERVICE}" ] || continue | ||||
| 		[ -x "${RC_SERVICE}" -a -f "${RC_SERVICE}" ] || continue | ||||
|  | ||||
| 		# Only generate dependencies for runscripts | ||||
| 		read one two < "${RC_SERVICE}" | ||||
| 		[ "${one}" = "#!@PREFIX@/sbin/runscript" ] || continue | ||||
| 		unset one two | ||||
| 		read one two three < "${RC_SERVICE}" | ||||
| 		[ "${one}" = "#!@PREFIX@/sbin/runscript" ] || \ | ||||
| 		[ "${one}" = "#!" -a "${two}" = "@PREFIX@/sbin/runscript" ] || \ | ||||
| 		continue | ||||
| 		unset one two three | ||||
|  | ||||
| 		export RC_SVCNAME=${RC_SERVICE##*/} | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -20,6 +20,7 @@ fi | ||||
|  | ||||
| # So daemons know where to recall us if needed | ||||
| export RC_SERVICE="$1" | ||||
| shift | ||||
|  | ||||
| # Compat | ||||
| export SVCNAME=${RC_SVCNAME} | ||||
| @@ -44,9 +45,49 @@ describe() | ||||
| 	done | ||||
| } | ||||
|  | ||||
| # Template start / stop functions | ||||
| start() | ||||
| { | ||||
| 	[ -n "${command}" ] || return 0 | ||||
| 	local _background= | ||||
| 	ebegin "Starting ${name:-${RC_SVCNAME}}" | ||||
| 	if yesno "${command_background}"; then  | ||||
| 		_background="--background --pidfile" | ||||
| 	fi | ||||
| 	if yesno "${start_inactive}"; then | ||||
| 		local _inactive=false | ||||
| 		service_inactive && _inactive=true | ||||
| 		mark_service_inactive | ||||
| 	fi | ||||
| 	start-stop-daemon --start \ | ||||
| 		--exec ${command} \ | ||||
| 		${procname:+--name} ${procname} \ | ||||
| 		${pidfile:+--pidfile} ${pidfile} \ | ||||
| 		${_background} ${start_stop_daemon_args} \ | ||||
| 		-- ${command_args} | ||||
| 	eend $? "Failed to start ${RC_SVCNAME}" && return 0 | ||||
| 	if yesno "${start_inactive}"; then | ||||
| 		if ! ${_inactive}; then | ||||
| 			mark_service_stopped | ||||
| 		fi | ||||
| 	fi | ||||
| 	return 1 | ||||
| } | ||||
|  | ||||
| stop() | ||||
| { | ||||
| 	[ -n "${command}" -o -n "${procname}" -o -n "${pidfile}" ] || return 0 | ||||
| 	ebegin "Stopping ${name:-${RC_SVCNAME}}" | ||||
| 	start-stop-daemon --stop \ | ||||
| 		${command:+--exec} ${command} \ | ||||
| 		${procname:+--name} ${procname} \ | ||||
| 		${pidfile:+--pidfile} ${pidfile} | ||||
| 	eend $? "Failed to stop ${RC_SVCNAME}" | ||||
| } | ||||
|  | ||||
| yesno ${RC_DEBUG} && set -x | ||||
|  | ||||
| _conf_d=${1%/*}/../conf.d | ||||
| _conf_d=${RC_SERVICE%/*}/../conf.d | ||||
| # If we're net.eth0 or openvpn.work then load net or openvpn config | ||||
| _c=${RC_SVCNAME%%.*} | ||||
| if [ -n "${_c}" -a "${_c}" != "${RC_SVCNAME}" ]; then | ||||
| @@ -73,8 +114,7 @@ unset _conf_d | ||||
| [ -n "${rc_ulimit:-${RC_ULIMIT}}" ] && ulimit ${rc_ulimit:-${RC_ULIMIT}} | ||||
|  | ||||
| # Load our script | ||||
| . $1 | ||||
| shift | ||||
| . "${RC_SERVICE}" | ||||
|  | ||||
| for _d in ${required_dirs}; do | ||||
| 	if [ ! -d ${_d} ]; then | ||||
| @@ -92,58 +132,12 @@ for _f in ${required_files}; do | ||||
| done | ||||
| unset _f | ||||
|  | ||||
| # If we have a default command then supply a default start function | ||||
| if [ -n "${command}" ]; then | ||||
| 	if ! type start >/dev/null 2>&1; then | ||||
| 		start() { | ||||
| 			local _background= | ||||
| 			ebegin "Starting ${name:-${RC_SVCNAME}}" | ||||
| 			if yesno "${command_background}"; then  | ||||
| 				_background="--background --pidfile" | ||||
| 			fi | ||||
| 			if yesno "${start_inactive}"; then | ||||
| 				local _inactive=false | ||||
| 				service_inactive && _inactive=true | ||||
| 				mark_service_inactive | ||||
| 			fi | ||||
| 			start-stop-daemon --start \ | ||||
| 				--exec ${command} \ | ||||
| 				${procname:+--name} ${procname} \ | ||||
| 				${pidfile:+--pidfile} ${pidfile} \ | ||||
| 				${_background} ${start_stop_daemon_args} \ | ||||
| 				-- ${command_args} | ||||
| 			eend $? "Failed to start ${RC_SVCNAME}" && return 0 | ||||
| 			if yesno "${start_inactive}"; then | ||||
| 				if ! ${_inactive}; then | ||||
| 			   		mark_service_stopped | ||||
| 				fi | ||||
| 			fi | ||||
| 			return 1 | ||||
| 		} | ||||
| 	fi | ||||
| fi | ||||
|  | ||||
| # If we have a default command, procname or pidfile then supply a default stop  | ||||
| # function | ||||
| if [ -n "${command}" -o -n "${procname}" -o -n "${pidfile}" ]; then | ||||
| 	if ! type stop >/dev/null 2>&1; then | ||||
| 		stop() { | ||||
| 			ebegin "Stopping ${name:-${RC_SVCNAME}}" | ||||
| 			start-stop-daemon --stop \ | ||||
| 				${command:+--exec} ${command} \ | ||||
| 				${procname:+--name} ${procname} \ | ||||
| 				${pidfile:+--pidfile} ${pidfile} | ||||
| 			eend $? "Failed to stop ${RC_SVCNAME}" | ||||
| 		} | ||||
| 	fi | ||||
| fi | ||||
|  | ||||
| while [ -n "$1" ]; do | ||||
| 	# See if we have the required function and run it | ||||
| 	for _cmd in describe start stop ${extra_commands:-${opts}} \ | ||||
| 		${extra_started_commands}; do | ||||
| 		if [ "${_cmd}" = "$1" ]; then | ||||
| 			if type "$1" >/dev/null 2>&1; then | ||||
| 			if [ "$(command -v "$1")" = "$1" ]; then | ||||
| 				# If we're in the background, we may wish to | ||||
| 				# fake some commands. We do this so we can | ||||
| 				# "start" ourselves from inactive which then | ||||
| @@ -168,11 +162,11 @@ while [ -n "$1" ]; do | ||||
| 					fi | ||||
| 				done | ||||
| 				unset _cmd | ||||
| 				if type "$1"_pre >/dev/null 2>&1; then | ||||
| 				if [ "$(command -v "$1_pre")" = "$1_pre" ]; then | ||||
| 					"$1"_pre || exit $? | ||||
| 				fi | ||||
| 				"$1" || exit $? | ||||
| 				if type "$1"_post >/dev/null 2>&1; then | ||||
| 				if [ "$(command -v "$1_post")" = "$1_post" ]; then | ||||
| 					"$1"_post || exit $? | ||||
| 				fi | ||||
| 				shift | ||||
|   | ||||
| @@ -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} | ||||
|   | ||||
| @@ -56,76 +56,53 @@ static size_t strlcpy(char *dst, const char *src, size_t size) | ||||
| #endif | ||||
|  | ||||
| #if defined(__linux__) | ||||
|  | ||||
| static bool pid_is_cmd(pid_t pid, const char *cmd) | ||||
| { | ||||
| 	char buffer[32]; | ||||
| 	FILE *fp; | ||||
| 	int c; | ||||
| 	bool retval = false; | ||||
|  | ||||
| 	snprintf(buffer, sizeof(buffer), "/proc/%d/stat", pid); | ||||
| 	if ((fp = fopen(buffer, "r")) == NULL) | ||||
| 		return false; | ||||
|  | ||||
| 	while ((c = getc(fp)) != EOF && c != '(') | ||||
| 		; | ||||
|  | ||||
| 	if (c != '(') { | ||||
| 	if ((fp = fopen(buffer, "r"))) { | ||||
| 		while ((c = getc(fp)) != EOF && c != '(') | ||||
| 			; | ||||
| 		if (c == '(') { | ||||
| 			while ((c = getc(fp)) != EOF && c == *cmd) | ||||
| 				cmd++; | ||||
| 			if (c == ')' && *cmd == '\0') | ||||
| 				retval = true; | ||||
| 		} | ||||
| 		fclose(fp); | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	while ((c = getc(fp)) != EOF && c == *cmd) | ||||
| 		cmd++; | ||||
|  | ||||
| 	fclose(fp); | ||||
|  | ||||
| 	return (c == ')' && *cmd == '\0') ? true : false; | ||||
| 	return retval; | ||||
| } | ||||
|  | ||||
| static bool pid_is_exec(pid_t pid, const char *const *argv) | ||||
| { | ||||
| 	char cmdline[32]; | ||||
| 	int fd; | ||||
| 	char buffer[PATH_MAX]; | ||||
| 	char *p; | ||||
| 	int fd = -1; | ||||
| 	int r; | ||||
|  | ||||
| 	/* Check it's the right binary */ | ||||
| 	snprintf (cmdline, sizeof (cmdline), "/proc/%u/exe", pid); | ||||
| 	memset (buffer, 0, sizeof (buffer)); | ||||
| 	if (readlink(cmdline, buffer, sizeof(buffer)) != -1) { | ||||
| 		if (strcmp(*argv, buffer) == 0) | ||||
| 			return true; | ||||
|  | ||||
| 		/* We should cater for deleted binaries too */ | ||||
| 		if (strlen(buffer) > 10) { | ||||
| 			p = buffer + (strlen(buffer) - 10); | ||||
| 			if (strcmp(p, " (deleted)") == 0) { | ||||
| 				*p = 0; | ||||
| 				if (strcmp(buffer, *argv) == 0) | ||||
| 					return true; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	ssize_t bytes; | ||||
|  | ||||
| 	snprintf(cmdline, sizeof(cmdline), "/proc/%u/cmdline", pid); | ||||
| 	if ((fd = open(cmdline, O_RDONLY)) < 0) | ||||
| 		return false; | ||||
|  | ||||
| 	r = read(fd, buffer, sizeof(buffer)); | ||||
| 	bytes = read(fd, buffer, sizeof(buffer)); | ||||
| 	close(fd); | ||||
| 	if (bytes == -1) | ||||
| 		return false; | ||||
|  | ||||
| 	if (r == -1) | ||||
| 		return 0; | ||||
|  | ||||
| 	buffer[r] = 0; | ||||
| 	buffer[bytes] = '\0'; | ||||
| 	p = buffer; | ||||
| 	while (*argv) { | ||||
| 		if (strcmp(*argv, p) != 0) | ||||
| 			return false; | ||||
| 		argv++; | ||||
| 		p += strlen(p) + 1; | ||||
| 		if ((unsigned) (p - buffer) > sizeof (buffer)) | ||||
| 		if ((unsigned)(p - buffer) > sizeof(buffer)) | ||||
| 			return false; | ||||
| 	} | ||||
| 	return true; | ||||
| @@ -561,14 +538,13 @@ bool rc_service_daemons_crashed(const char *service) | ||||
| 			if ((fp = fopen(pidfile, "r"))) { | ||||
| 				if (fscanf(fp, "%d", &pid) == 1) | ||||
| 					retval = false; | ||||
| 				 | ||||
| 				fclose (fp); | ||||
| 			} | ||||
| 			free(pidfile); | ||||
| 			pidfile = NULL; | ||||
|  | ||||
| 			/* We have the pid, so no need to match on name */ | ||||
| 			free (name); | ||||
| 			free(name); | ||||
| 			name = NULL; | ||||
| 		} else { | ||||
| 			if (exec) { | ||||
|   | ||||
| @@ -431,12 +431,11 @@ static void visit_service(const RC_DEPTREE *deptree, | ||||
| 		TAILQ_FOREACH(service, dt->services, entries) { | ||||
| 			if (!(di = get_depinfo(deptree, service->value))) | ||||
| 				continue; | ||||
|  | ||||
| 			provided = get_provided(di, runlevel, options); | ||||
| 			TAILQ_FOREACH(p, provided, entries) | ||||
| 				if (strcmp (p->value, depinfo->service) == 0) { | ||||
| 					//visit_service (deptree, types, sorted, visited, di, | ||||
| 					//	       runlevel, options | RC_DEP_TRACE); | ||||
| 					visit_service (deptree, types, sorted, visited, di, | ||||
| 						       runlevel, options | RC_DEP_TRACE); | ||||
| 					break; | ||||
| 				} | ||||
| 			rc_stringlist_free(provided); | ||||
| @@ -478,17 +477,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 +514,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 +524,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 +532,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 +540,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 +574,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; | ||||
| } | ||||
| @@ -649,6 +654,7 @@ static const char *const depdirs[] = | ||||
| 	RC_SVCDIR "/options", | ||||
| 	RC_SVCDIR "/exclusive", | ||||
| 	RC_SVCDIR "/scheduled", | ||||
| 	RC_SVCDIR "/tmp", | ||||
| 	NULL | ||||
| }; | ||||
|  | ||||
| @@ -841,7 +847,7 @@ bool rc_deptree_update(void) | ||||
| 		nosys[0] = 'n'; | ||||
| 		nosys[1] = 'o'; | ||||
| 		for (i = 0; i < len; i++) | ||||
| 			nosys[i + 2] = (char) tolower((int) sys[i]); | ||||
| 			nosys[i + 2] = (char)tolower((unsigned char)sys[i]); | ||||
| 		nosys[i + 2] = '\0'; | ||||
|  | ||||
| 		STAILQ_FOREACH_SAFE(depinfo, deptree, entries, depinfo_np) | ||||
|   | ||||
| @@ -31,38 +31,35 @@ | ||||
|  | ||||
| #include "librc.h" | ||||
|  | ||||
| bool rc_yesno (const char *value) | ||||
| bool rc_yesno(const char *value) | ||||
| { | ||||
| 	if (! value) { | ||||
| 	if (!value) { | ||||
| 		errno = ENOENT; | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	if (strcasecmp (value, "yes") == 0 || | ||||
| 	    strcasecmp (value, "y") == 0 || | ||||
| 	    strcasecmp (value, "true") == 0 || | ||||
| 	    strcasecmp (value, "1") == 0) | ||||
| 	if (strcasecmp(value, "yes") == 0 || | ||||
| 	    strcasecmp(value, "y") == 0 || | ||||
| 	    strcasecmp(value, "true") == 0 || | ||||
| 	    strcasecmp(value, "1") == 0) | ||||
| 		return true; | ||||
|  | ||||
| 	if (strcasecmp (value, "no") != 0 && | ||||
| 	    strcasecmp (value, "n") != 0 && | ||||
| 	    strcasecmp (value, "false") != 0 && | ||||
| 	    strcasecmp (value, "0") != 0) | ||||
| 	if (strcasecmp(value, "no") != 0 && | ||||
| 	    strcasecmp(value, "n") != 0 && | ||||
| 	    strcasecmp(value, "false") != 0 && | ||||
| 	    strcasecmp(value, "0") != 0) | ||||
| 		errno = EINVAL; | ||||
|  | ||||
| 	return false; | ||||
| } | ||||
| librc_hidden_def(rc_yesno) | ||||
|  | ||||
| ssize_t rc_getline (char **line, size_t *len, FILE *fp) | ||||
| ssize_t rc_getline(char **line, size_t *len, FILE *fp) | ||||
| { | ||||
| 	char *p; | ||||
| 	size_t last = 0; | ||||
|  | ||||
| 	if (feof(fp)) | ||||
| 		return 0; | ||||
|  | ||||
| 	do { | ||||
| 	while(!feof(fp)) { | ||||
| 		if (*line == NULL || last != 0) { | ||||
| 			*len += BUFSIZ; | ||||
| 			*line = xrealloc(*line, *len); | ||||
| @@ -71,12 +68,11 @@ ssize_t rc_getline (char **line, size_t *len, FILE *fp) | ||||
| 		memset(p, 0, BUFSIZ); | ||||
| 		fgets(p, BUFSIZ, fp); | ||||
| 		last += strlen(p); | ||||
| 	} while (! feof(fp) && (*line)[last - 1] != '\n'); | ||||
|  | ||||
| 	/* Trim the trailing newline */ | ||||
| 	if (**line && (*line)[last - 1] == '\n') | ||||
| 		(*line)[last - 1] = '\0'; | ||||
|  | ||||
| 		if (last && (*line)[last - 1] == '\n') { | ||||
| 			(*line)[last - 1] = '\0'; | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	return last; | ||||
| } | ||||
| librc_hidden_def(rc_getline) | ||||
| @@ -108,7 +104,7 @@ RC_STRINGLIST *rc_config_list(const char *file) | ||||
| 				if (token[strlen(token) - 1] == '\n') | ||||
| 					token[strlen(token) - 1] = 0; | ||||
|  | ||||
| 				if (! list) | ||||
| 				if (!list) | ||||
| 					list = rc_stringlist_new(); | ||||
| 				rc_stringlist_add(list, token); | ||||
| 			} | ||||
| @@ -135,7 +131,7 @@ RC_STRINGLIST *rc_config_load(const char *file) | ||||
| 	char *p; | ||||
|  | ||||
| 	list = rc_config_list(file); | ||||
| 	if (! list) | ||||
| 	if (!list) | ||||
| 		return NULL; | ||||
|  | ||||
| 	config = rc_stringlist_new(); | ||||
| @@ -157,15 +153,15 @@ RC_STRINGLIST *rc_config_load(const char *file) | ||||
|  | ||||
| 		/* Drop a newline if that's all we have */ | ||||
| 		if (token) { | ||||
| 			i = strlen (token) - 1; | ||||
| 			i = strlen(token) - 1; | ||||
| 			if (token[i] == '\n') | ||||
| 				token[i] = 0; | ||||
|  | ||||
| 			i = strlen (entry) + strlen (token) + 2; | ||||
| 			i = strlen(entry) + strlen(token) + 2; | ||||
| 			newline = xmalloc(sizeof(char) * i); | ||||
| 			snprintf(newline, i, "%s=%s", entry, token); | ||||
| 		} else { | ||||
| 			i = strlen (entry) + 2; | ||||
| 			i = strlen(entry) + 2; | ||||
| 			newline = xmalloc(sizeof(char) * i); | ||||
| 			snprintf(newline, i, "%s=", entry); | ||||
| 		} | ||||
| @@ -176,7 +172,7 @@ RC_STRINGLIST *rc_config_load(const char *file) | ||||
| 		TAILQ_FOREACH(cline, config, entries) { | ||||
| 			p = strchr(cline->value, '='); | ||||
| 			if (p && strncmp(entry, cline->value, | ||||
| 					  (size_t) (p - cline->value)) == 0) | ||||
| 					  (size_t)(p - cline->value)) == 0) | ||||
| 			{ | ||||
| 				/* We have a match now - to save time we directly replace it */ | ||||
| 				free(cline->value); | ||||
| @@ -186,7 +182,7 @@ RC_STRINGLIST *rc_config_load(const char *file) | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if (! replaced) { | ||||
| 		if (!replaced) { | ||||
| 			rc_stringlist_add(config, newline); | ||||
| 			free(newline); | ||||
| 		} | ||||
|   | ||||
| @@ -501,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; | ||||
| 		} | ||||
| @@ -547,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; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|   | ||||
| @@ -55,13 +55,13 @@ install: all | ||||
| 	${INSTALL} -d ${DESTDIR}${SBINDIR} | ||||
| 	${INSTALL} -m ${BINMODE} ${PROG} ${DESTDIR}${SBINDIR} | ||||
| 	${INSTALL} -d ${DESTDIR}${BINDIR} | ||||
| 	for x in ${BINLINKS}; do ln -fs ${DESTDIR}${SBINDIR}/${PROG} ${DESTDIR}${BINDIR}/$$x; done | ||||
| 	for x in ${BINLINKS}; do ln -fs ${SBINDIR}/${PROG} ${DESTDIR}${BINDIR}/$$x; done | ||||
| 	${INSTALL} -d ${DESTDIR}${SBINDIR} | ||||
| 	for x in ${SBINLINKS}; do ln -fs ${PROG} ${DESTDIR}${SBINDIR}/$$x; done | ||||
| 	${INSTALL} -d ${DESTDIR}${LINKDIR}/bin | ||||
| 	for x in $(RC_BINLINKS); do ln -fs ${DESTDIR}${SBINDIR}/${PROG} ${DESTDIR}${LINKDIR}/bin/$$x; done | ||||
| 	for x in $(RC_BINLINKS); do ln -fs ${SBINDIR}/${PROG} ${DESTDIR}${LINKDIR}/bin/$$x; done | ||||
| 	${INSTALL} -d ${DESTDIR}${LINKDIR}/sbin | ||||
| 	for x in ${RC_SBINLINKS}; do ln -fs ${DESTDIR}${SBINDIR}/${PROG} ${DESTDIR}${LINKDIR}/sbin/$$x; done | ||||
| 	for x in ${RC_SBINLINKS}; do ln -fs ${SBINDIR}/${PROG} ${DESTDIR}${LINKDIR}/sbin/$$x; done | ||||
| 	if test "${MKPAM}" = pam; then \ | ||||
| 		${INSTALL} -d ${DESTDIR}${PAMDIR}; \ | ||||
| 		${INSTALL} -m ${PAMMODE} start-stop-daemon.pam ${DESTDIR}${PAMDIR}/start-stop-daemon; \ | ||||
|   | ||||
| @@ -137,8 +137,9 @@ static const struct option longopts[] = { | ||||
| 	longopts_COMMON | ||||
| }; | ||||
| static const char * const longopts_help[] = { | ||||
| 	"Mounts the filesytem from the mountpoint", | ||||
| 	"Extract the block device", | ||||
| 	"Mounts the filesytem from the mountpoint",  | ||||
| 	"Show arguments needed to mount the entry", | ||||
| 	"Extract the options field", | ||||
| 	"Extract or query the pass number field", | ||||
| 	"List entries with matching file system type", | ||||
| @@ -158,7 +159,7 @@ int fstabinfo(int argc, char **argv) | ||||
| 	struct ENT *ent; | ||||
| 	int result = EXIT_SUCCESS; | ||||
| 	char *token; | ||||
| 	int i; | ||||
| 	int i, p; | ||||
| 	int opt; | ||||
| 	int output = OUTPUT_FILE; | ||||
| 	RC_STRINGLIST *files = rc_stringlist_new(); | ||||
| @@ -199,13 +200,17 @@ int fstabinfo(int argc, char **argv) | ||||
| 						argv[0], optarg + 1); | ||||
|  | ||||
| 				filtered = true; | ||||
| 				opt = optarg[0]; | ||||
| 				START_ENT; | ||||
| 				while ((ent = GET_ENT)) { | ||||
| 					if (((optarg[0] == '=' && i == ENT_PASS(ent)) || | ||||
| 					     (optarg[0] == '<' && i > ENT_PASS(ent)) || | ||||
| 					     (optarg[0] == '>' && i < ENT_PASS(ent))) && | ||||
| 					    strcmp(ENT_FILE(ent), "none") != 0) | ||||
| 						rc_stringlist_add(files, ENT_FILE(ent)); | ||||
| 					if (strcmp(ENT_FILE(ent), "none") == 0) | ||||
| 						continue; | ||||
| 					p = ENT_PASS(ent); | ||||
| 					if ((opt == '=' && i == p) || | ||||
| 					    (opt == '<' && i > p && p != 0) || | ||||
| 					    (opt == '>' && i < p && p != 0)) | ||||
| 						rc_stringlist_add(files, | ||||
| 								  ENT_FILE(ent)); | ||||
| 				} | ||||
| 				END_ENT; | ||||
| 				break; | ||||
|   | ||||
| @@ -58,7 +58,7 @@ static int syslog_decode(char *name, CODE *codetab) | ||||
| { | ||||
| 	CODE *c; | ||||
|  | ||||
| 	if (isdigit((int) *name)) | ||||
| 	if (isdigit((unsigned char)*name)) | ||||
| 		return atoi(name); | ||||
|  | ||||
| 	for (c = codetab; c->c_name; c++) | ||||
| @@ -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) | ||||
| @@ -351,7 +351,7 @@ static int do_shell_var(int argc, char **argv) | ||||
| 			putchar(' '); | ||||
|  | ||||
| 		while (*p) { | ||||
| 			c = *p++; | ||||
| 			c = (unsigned char)*p++; | ||||
| 			if (! isalnum(c)) | ||||
| 				c = '_'; | ||||
| 			putchar(c); | ||||
|   | ||||
| @@ -103,7 +103,7 @@ static void write_log(int logfd, const char *buffer, size_t bytes) | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		if (! in_term || isalpha((int) *p)) | ||||
| 		if (! in_term || isalpha((unsigned char)*p)) | ||||
| 			in_escape = in_term = false; | ||||
| cont: | ||||
| 		p++; | ||||
|   | ||||
| @@ -93,8 +93,8 @@ char *rc_conf_value(const char *setting) | ||||
| 			TAILQ_FOREACH(s, rc_conf, entries) { | ||||
| 				p = s->value; | ||||
| 				while (p && *p && *p != '=') { | ||||
| 					if (isupper((int) *p)) | ||||
| 						*p = tolower((int) *p); | ||||
| 					if (isupper((unsigned char)*p)) | ||||
| 						*p = tolower((unsigned char)*p); | ||||
| 					p++; | ||||
| 				} | ||||
| 			} | ||||
| @@ -224,6 +224,7 @@ void env_config(void) | ||||
|  | ||||
| 	setenv("RC_LIBDIR", RC_LIBDIR, 1); | ||||
| 	setenv("RC_SVCDIR", RC_SVCDIR, 1); | ||||
| 	setenv("RC_TMPDIR", RC_SVCDIR "/tmp", 1); | ||||
| 	setenv("RC_BOOTLEVEL", RC_LEVEL_BOOT, 1); | ||||
| 	e = rc_runlevel_get(); | ||||
| 	setenv("RC_RUNLEVEL", e, 1); | ||||
|   | ||||
| @@ -120,17 +120,15 @@ void rc_plugin_load(void) | ||||
|  | ||||
| int rc_waitpid(pid_t pid) | ||||
| { | ||||
| 	int status = 0; | ||||
| 	pid_t savedpid = pid; | ||||
| 	int retval = -1; | ||||
| 	int status; | ||||
|  | ||||
| 	errno = 0; | ||||
| 	while ((pid = waitpid(savedpid, &status, 0)) > 0) { | ||||
| 		if (pid == savedpid) | ||||
| 			retval = WIFEXITED(status) ? WEXITSTATUS(status) : EXIT_FAILURE; | ||||
| 	while (waitpid(pid, &status, 0) == -1) { | ||||
| 		if (errno != EINTR) { | ||||
| 			status = -1; | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return retval; | ||||
| 	return status; | ||||
| } | ||||
|  | ||||
| void rc_plugin_run(RC_HOOK hook, const char *value) | ||||
|   | ||||
| @@ -51,7 +51,9 @@ static const struct option longopts[] = { | ||||
| 	longopts_COMMON | ||||
| }; | ||||
| static const char * const longopts_help[] = { | ||||
| 	"tests if the service exists or not", | ||||
| 	"list all available services", | ||||
| 	"resolve the service name to an init script", | ||||
| 	longopts_help_COMMON | ||||
| }; | ||||
| #include "_usage.c" | ||||
|   | ||||
| @@ -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))) | ||||
| @@ -102,9 +103,13 @@ static void print_service(const char *service) | ||||
| 		snprintf(status, sizeof(status), "inactive "); | ||||
| 		color = ECOLOR_WARN; | ||||
| 	} else if (state & RC_SERVICE_STARTED) { | ||||
| 		if (test_crashed && rc_service_daemons_crashed(service)) | ||||
| 		errno = 0; | ||||
| 		if (test_crashed && | ||||
| 		    rc_service_daemons_crashed(service) && | ||||
| 		    errno != EACCES) | ||||
| 		{ | ||||
| 			snprintf(status, sizeof(status), " crashed "); | ||||
| 		else { | ||||
| 		} else { | ||||
| 			snprintf(status, sizeof(status), " started "); | ||||
| 			color = ECOLOR_GOOD; | ||||
| 		} | ||||
| @@ -120,6 +125,48 @@ 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); | ||||
| 	if (!l) | ||||
| 		return; | ||||
| 	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 +190,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_STRINGLIST *services = NULL; | ||||
| 	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 +208,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 +256,35 @@ 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 && | ||||
| 	    (services = rc_services_in_runlevel(NULL))) | ||||
| 	{ | ||||
| 		print_level("UNASSIGNED"); | ||||
| 		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); | ||||
|   | ||||
							
								
								
									
										151
									
								
								src/rc/rc.c
									
									
									
									
									
								
							
							
						
						
									
										151
									
								
								src/rc/rc.c
									
									
									
									
									
								
							| @@ -146,7 +146,7 @@ static void cleanup(void) | ||||
| 		rc_plugin_unload(); | ||||
|  | ||||
| 		if (! rc_in_plugin && termios_orig) { | ||||
| 			tcsetattr(fileno(stdin), TCSANOW, termios_orig); | ||||
| 			tcsetattr(STDIN_FILENO, TCSANOW, termios_orig); | ||||
| 			free(termios_orig); | ||||
| 		} | ||||
|  | ||||
| @@ -215,7 +215,7 @@ static char read_key(bool block) | ||||
| { | ||||
| 	struct termios termios; | ||||
| 	char c = 0; | ||||
| 	int fd = fileno(stdin); | ||||
| 	int fd = STDIN_FILENO; | ||||
|  | ||||
| 	if (! isatty(fd)) | ||||
| 		return false; | ||||
| @@ -277,34 +277,12 @@ static void mark_interactive(void) | ||||
| 		fclose(fp); | ||||
| } | ||||
|  | ||||
| static void sulogin(bool cont) | ||||
| static void run_program(const char *prog) | ||||
| { | ||||
| 	int status = 0; | ||||
| 	struct sigaction sa; | ||||
| 	sigset_t full; | ||||
| 	sigset_t old; | ||||
| 	pid_t pid; | ||||
| #ifdef __linux__ | ||||
| 	const char *sys = rc_sys(); | ||||
|  | ||||
| 	/* VSERVER and OPENVZ systems cannot do a sulogin */ | ||||
| 	if (sys && (strcmp(sys, "VSERVER") == 0 || strcmp(sys, "OPENVZ") == 0)) { | ||||
| 		execl("/sbin/halt", "/sbin/halt", "-f", (char *) NULL); | ||||
| 		eerrorx("%s: unable to exec `/sbin/halt': %s", | ||||
| 			applet, strerror(errno)); | ||||
| 	} | ||||
| #endif | ||||
|  | ||||
| 	if (! cont) { | ||||
| 		rc_logger_close(); | ||||
| #ifdef __linux__ | ||||
| 		execl("/sbin/sulogin", "/sbin/sulogin", (char *) NULL); | ||||
| 		eerrorx("%s: unable to exec `/sbin/sulogin': %s", | ||||
| 			applet, strerror(errno)); | ||||
| #else | ||||
| 		exit(EXIT_SUCCESS); | ||||
| #endif | ||||
| 	} | ||||
|  | ||||
| 	/* We need to block signals until we have forked */ | ||||
| 	memset(&sa, 0, sizeof(sa)); | ||||
| @@ -312,7 +290,7 @@ static void sulogin(bool cont) | ||||
| 	sigemptyset(&sa.sa_mask); | ||||
| 	sigfillset(&full); | ||||
| 	sigprocmask(SIG_SETMASK, &full, &old); | ||||
| 	pid = vfork(); | ||||
| 	pid = fork(); | ||||
|  | ||||
| 	if (pid == -1) | ||||
| 		eerrorx("%s: fork: %s", applet, strerror(errno)); | ||||
| @@ -330,23 +308,50 @@ static void sulogin(bool cont) | ||||
| 		sigprocmask(SIG_SETMASK, &old, NULL); | ||||
|  | ||||
| 		if (termios_orig) | ||||
| 			tcsetattr(fileno(stdin), TCSANOW, termios_orig); | ||||
| 			tcsetattr(STDIN_FILENO, TCSANOW, termios_orig); | ||||
|  | ||||
| #ifdef __linux__ | ||||
| 		execl(SULOGIN, SULOGIN, (char *) NULL); | ||||
| 		eerror("%s: unable to exec `%s': %s", applet, SULOGIN, | ||||
| 		execl(prog, prog, (char *) NULL); | ||||
| 		eerror("%s: unable to exec `%s': %s", applet, prog, | ||||
| 		       strerror(errno)); | ||||
| #else | ||||
| 		execl("/bin/sh", "/bin/sh", (char *) NULL); | ||||
| 		eerror("%s: unable to exec `/bin/sh': %s", applet, | ||||
| 		       strerror(errno)); | ||||
| #endif | ||||
| 		_exit(EXIT_FAILURE); | ||||
| 	} | ||||
|  | ||||
| 	/* Unmask signals and wait for child */ | ||||
| 	sigprocmask(SIG_SETMASK, &old, NULL); | ||||
| 	waitpid(pid, &status, 0); | ||||
| 	if (rc_waitpid(pid) == -1) | ||||
| 		eerrorx("%s: failed to exec `%s'", applet, prog); | ||||
| } | ||||
|  | ||||
| static void sulogin(bool cont) | ||||
| { | ||||
| #ifdef __linux__ | ||||
| 	const char *sys = rc_sys(); | ||||
|  | ||||
| 	/* VSERVER and OPENVZ systems cannot do a sulogin */ | ||||
| 	if (sys && (strcmp(sys, "VSERVER") == 0 || strcmp(sys, "OPENVZ") == 0)) { | ||||
| 		execl("/sbin/halt", "/sbin/halt", "-f", (char *) NULL); | ||||
| 		eerrorx("%s: unable to exec `/sbin/halt': %s", | ||||
| 			applet, strerror(errno)); | ||||
| 	} | ||||
| #endif | ||||
|  | ||||
| 	if (! cont) { | ||||
| 		rc_logger_close(); | ||||
| #ifdef __linux__ | ||||
| 		if (RUNLEVEL && strcmp(RUNLEVEL, "S") == 0) { | ||||
| 			execl("/sbin/sulogin", "/sbin/sulogin", (char *) NULL); | ||||
| 			eerrorx("%s: unable to exec `/sbin/sulogin': %s", | ||||
| 				applet, strerror(errno)); | ||||
| 		} | ||||
| #endif | ||||
| 		exit(EXIT_SUCCESS); | ||||
| 	} | ||||
|  | ||||
| #ifdef __linux__ | ||||
| 	run_program(SULOGIN); | ||||
| #else | ||||
| 	run_program("/bin/sh"); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| static void single_user(void) | ||||
| @@ -449,7 +454,7 @@ static void handle_signal(int sig) | ||||
| 					eerror("waitpid: %s", strerror(errno)); | ||||
| 				return; | ||||
| 			} | ||||
| 		} while (! WIFEXITED(status) && ! WIFSIGNALED(status)); | ||||
| 		} while (!WIFEXITED(status) && !WIFSIGNALED(status)); | ||||
|  | ||||
| 		/* Remove that pid from our list */ | ||||
| 		if (pid > 0) | ||||
| @@ -511,31 +516,6 @@ static void handle_signal(int sig) | ||||
| 	errno = serrno; | ||||
| } | ||||
|  | ||||
| static void run_script(const char *script) | ||||
| { | ||||
| 	int status = 0; | ||||
| 	pid_t pid = vfork(); | ||||
| 	pid_t wpid; | ||||
|  | ||||
| 	if (pid < 0) | ||||
| 		eerrorx("%s: vfork: %s", applet, strerror(errno)); | ||||
| 	else if (pid == 0) { | ||||
| 		execl(script, script, (char *) NULL); | ||||
| 		eerror("%s: unable to exec `%s': %s", | ||||
| 			script, applet, strerror(errno)); | ||||
| 		_exit(EXIT_FAILURE); | ||||
| 	} | ||||
|  | ||||
| 	do { | ||||
| 		wpid = waitpid(pid, &status, 0); | ||||
| 		if (wpid < 1) | ||||
| 			eerror("waitpid: %s", strerror(errno)); | ||||
| 	} while (! WIFEXITED(status) && ! WIFSIGNALED(status)); | ||||
|  | ||||
| 	if (! WIFEXITED(status) || ! WEXITSTATUS(status) == 0) | ||||
| 		eerrorx("%s: failed to exec `%s'", applet, script); | ||||
| } | ||||
|  | ||||
| static void do_coldplug(void) | ||||
| { | ||||
| 	size_t l; | ||||
| @@ -582,7 +562,7 @@ static void do_coldplug(void) | ||||
| 			    strncmp(d->d_name, "ums", 3) == 0) | ||||
| 			{ | ||||
| 				p = d->d_name + 3; | ||||
| 				if (p && isdigit((int) *p)) { | ||||
| 				if (p && isdigit((unsigned char)*p)) { | ||||
| 					l = strlen("moused.") + strlen(d->d_name) + 1; | ||||
| 					service = xmalloc(sizeof(char) * l); | ||||
| 					snprintf (service, l, "moused.%s", d->d_name); | ||||
| @@ -635,7 +615,7 @@ static void do_coldplug(void) | ||||
| 	if (coldplugged_services) | ||||
| 		TAILQ_FOREACH(s, coldplugged_services, entries) | ||||
| 			printf(" %s", s->value); | ||||
| 	printf ("%s\n", ecolor(ECOLOR_NORMAL)); | ||||
| 	printf("%s\n", ecolor(ECOLOR_NORMAL)); | ||||
| } | ||||
|  | ||||
| static void do_newlevel(const char *newlevel) | ||||
| @@ -660,7 +640,7 @@ static void do_newlevel(const char *newlevel) | ||||
| 		 * This should just setup the console to use the correct | ||||
| 		 * font. Maybe it should setup the keyboard too? */ | ||||
| 		if (exists(INITEARLYSH)) | ||||
| 			run_script(INITEARLYSH); | ||||
| 			run_program(INITEARLYSH); | ||||
|  | ||||
| 		uname(&uts); | ||||
| 		printf("\n   %sOpenRC %s" VERSION "%s is starting up %s", | ||||
| @@ -688,15 +668,18 @@ static void do_newlevel(const char *newlevel) | ||||
| 		setenv("RC_RUNLEVEL", newlevel, 1); | ||||
| 		rc_plugin_run(RC_HOOK_RUNLEVEL_START_IN, newlevel); | ||||
| 		hook_out = RC_HOOK_RUNLEVEL_START_OUT; | ||||
| 		run_script(INITSH); | ||||
| 		run_program(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 */ | ||||
| @@ -751,17 +734,18 @@ static void do_newlevel(const char *newlevel) | ||||
| static bool runlevel_config(const char *service, const char *level) | ||||
| { | ||||
| 	char *init = rc_service_resolve(service); | ||||
| 	char *conf; | ||||
| 	char *conf, *dir; | ||||
| 	size_t l; | ||||
| 	bool retval; | ||||
|  | ||||
| 	init = dirname(init); | ||||
| 	init = dirname(init); | ||||
| 	l = strlen(init) + strlen(level) + strlen(service) + 10; | ||||
| 	dir = dirname(init); | ||||
| 	dir = dirname(init); | ||||
| 	l = strlen(dir) + strlen(level) + strlen(service) + 10; | ||||
| 	conf = xmalloc(sizeof(char) * l); | ||||
| 	snprintf(conf, l, "%s/conf.d/%s.%s", init, service, level); | ||||
| 	snprintf(conf, l, "%s/conf.d/%s.%s", dir, service, level); | ||||
| 	retval = exists(conf); | ||||
| 	free(conf); | ||||
| 	free(init); | ||||
|  | ||||
| 	return retval; | ||||
| } | ||||
| @@ -817,7 +801,8 @@ static void do_stop_services(const char *newlevel, bool going_down, bool paralle | ||||
| 			tmplist = rc_stringlist_new(); | ||||
| 			rc_stringlist_add(tmplist, service->value); | ||||
| 			deporder = rc_deptree_depends(deptree, types_n, tmplist, | ||||
| 						      runlevel, RC_DEP_STRICT); | ||||
| 						      runlevel, | ||||
| 						      RC_DEP_STRICT | RC_DEP_TRACE); | ||||
| 			rc_stringlist_free(tmplist); | ||||
| 			svc2 = NULL; | ||||
| 			TAILQ_FOREACH (svc1, deporder, entries) { | ||||
| @@ -935,11 +920,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" | ||||
| @@ -954,7 +941,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; | ||||
| @@ -1028,6 +1015,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 | ||||
| 		} | ||||
| 	} | ||||
| @@ -1041,7 +1034,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(); | ||||
|  | ||||
| @@ -1191,7 +1184,7 @@ int main(int argc, char **argv) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/* Save our softlevel now */ | ||||
| 	/* Save our runlevel now */ | ||||
| 	if (going_down) | ||||
| 		rc_runlevel_set(newlevel); | ||||
|  | ||||
|   | ||||
| @@ -39,6 +39,7 @@ | ||||
| #include <errno.h> | ||||
| #include <fcntl.h> | ||||
| #include <getopt.h> | ||||
| #include <libgen.h> | ||||
| #include <limits.h> | ||||
| #include <signal.h> | ||||
| #include <stdio.h> | ||||
| @@ -156,7 +157,7 @@ static void handle_signal(int sig) | ||||
| 			if (write(signal_pipe[1], &sig, sizeof(sig)) == -1) | ||||
| 				eerror("%s: send: %s", service, strerror(errno)); | ||||
| 		} else | ||||
| 			rc_waitpid (-1); | ||||
| 			rc_waitpid(-1); | ||||
| 		break; | ||||
|  | ||||
| 	case SIGWINCH: | ||||
| @@ -559,8 +560,10 @@ static RC_SERVICE svc_status(void) | ||||
| 		snprintf(status, sizeof(status), "inactive"); | ||||
| 		e = &ewarn; | ||||
| 	} else if (state & RC_SERVICE_STARTED) { | ||||
| 		errno = 0; | ||||
| 		if (_rc_can_find_pids() && | ||||
| 		    rc_service_daemons_crashed(service)) | ||||
| 		    rc_service_daemons_crashed(service) && | ||||
| 		    errno != EACCES) | ||||
| 		{ | ||||
| 			snprintf(status, sizeof(status), "crashed"); | ||||
| 			e = &eerror; | ||||
| @@ -648,6 +651,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; | ||||
| @@ -692,7 +708,8 @@ static void svc_start(bool deps) | ||||
| 	hook_out = RC_HOOK_SERVICE_START_OUT; | ||||
| 	rc_plugin_run(RC_HOOK_SERVICE_START_IN, applet); | ||||
|  | ||||
| 	if (rc_conf_yesno("rc_depend_strict")) | ||||
| 	errno = 0; | ||||
| 	if (rc_conf_yesno("rc_depend_strict") || errno == ENOENT) | ||||
| 		depoptions |= RC_DEP_STRICT; | ||||
|  | ||||
| 	if (deps) { | ||||
| @@ -725,57 +742,60 @@ static void svc_start(bool deps) | ||||
| 				runlevel, depoptions); | ||||
|  | ||||
| 		if (! rc_runlevel_starting() && use_services) | ||||
| 			TAILQ_FOREACH(svc, use_services, entries) | ||||
| 				if (rc_service_state(svc->value) & RC_SERVICE_STOPPED) { | ||||
| 			TAILQ_FOREACH(svc, use_services, entries) { | ||||
| 				state = rc_service_state(svc->value); | ||||
| 				/* Don't stop failed services again. | ||||
| 				 * If you remove this check, ensure that the | ||||
| 				 * exclusive file isn't created. */ | ||||
| 				if (state & RC_SERVICE_FAILED && | ||||
| 				    rc_runlevel_starting()) | ||||
| 					continue; | ||||
| 				if (state & RC_SERVICE_STOPPED) { | ||||
| 					pid_t pid = service_start(svc->value); | ||||
| 					if (! rc_conf_yesno("rc_parallel")) | ||||
| 						rc_waitpid(pid); | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 		/* Now wait for them to start */ | ||||
| 		services = rc_deptree_depends(deptree, types_nua, applet_list, | ||||
| 				runlevel, depoptions); | ||||
| 					      runlevel, depoptions); | ||||
|  | ||||
| 		if (services) { | ||||
| 			/* We use tmplist to hold our scheduled by list */ | ||||
| 			tmplist = NULL; | ||||
| 			TAILQ_FOREACH(svc, services, entries) { | ||||
| 				RC_SERVICE svcs = rc_service_state(svc->value); | ||||
| 				if (svcs & RC_SERVICE_STARTED) | ||||
| 				state = rc_service_state(svc->value); | ||||
| 				if (state & RC_SERVICE_STARTED) | ||||
| 					continue; | ||||
|  | ||||
| 				/* 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) | ||||
| 				if (state & RC_SERVICE_STARTING && | ||||
| 				    state & RC_SERVICE_WASINACTIVE) | ||||
| 				{ | ||||
| 					if (!in_list(need_services, svc->value) && | ||||
| 					    !in_list(use_services, svc->value)) | ||||
| 						continue; | ||||
| 				} | ||||
|  | ||||
| 				if (! svc_wait(svc->value)) | ||||
| 				if (!svc_wait(svc->value)) | ||||
| 					eerror ("%s: timed out waiting for %s", | ||||
| 						applet, svc->value); | ||||
| 				state = rc_service_state(svc->value); | ||||
| 				if (state & RC_SERVICE_STARTED) | ||||
| 					continue; | ||||
| 				if (in_list(need_services, svc->value)) { | ||||
| 					if (state & RC_SERVICE_INACTIVE || | ||||
| 					    state & 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 (! 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); | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| @@ -857,11 +877,13 @@ static void svc_start(bool deps) | ||||
| 	} | ||||
|  | ||||
| 	/* Do the same for any services we provide */ | ||||
| 	tmplist = rc_deptree_depend(deptree, "iprovide", applet); | ||||
| 	if (tmplist) { | ||||
| 		TAILQ_FOREACH(svc, tmplist, entries) { | ||||
| 			services = rc_services_scheduled(svc->value); | ||||
| 			if (services) { | ||||
| 	if (deptree) { | ||||
| 		tmplist = rc_deptree_depend(deptree, "iprovide", applet); | ||||
| 		if (tmplist) { | ||||
| 			TAILQ_FOREACH(svc, tmplist, entries) { | ||||
| 				services = rc_services_scheduled(svc->value); | ||||
| 				if (! services) | ||||
| 					continue; | ||||
| 				TAILQ_FOREACH(svc2, services, entries) | ||||
| 					if (rc_service_state(svc2->value) & RC_SERVICE_STOPPED) | ||||
| 						service_start(svc2->value); | ||||
| @@ -915,8 +937,8 @@ static void svc_stop(bool deps) | ||||
| 		ewarn ("WARNING: you are stopping a boot service"); | ||||
|  | ||||
| 	if (deps && ! (state & RC_SERVICE_WASINACTIVE)) { | ||||
|  | ||||
| 		if (rc_conf_yesno("rc_depend_strict")) | ||||
| 		errno = 0; | ||||
| 		if (rc_conf_yesno("rc_depend_strict") || errno == ENOENT) | ||||
| 			depoptions |= RC_DEP_STRICT; | ||||
|  | ||||
| 		if (! deptree && ((deptree = _rc_deptree_load(NULL)) == NULL)) | ||||
| @@ -925,19 +947,24 @@ static void svc_stop(bool deps) | ||||
| 		if (! types_m) | ||||
| 			setup_types(); | ||||
|  | ||||
| 		tmplist = NULL; | ||||
| 		services = rc_deptree_depends(deptree, types_m, applet_list, | ||||
| 					      runlevel, depoptions); | ||||
| 		if (services) { | ||||
| 			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) | ||||
| 				state = rc_service_state(svc->value); | ||||
| 				/* Don't stop failed services again. | ||||
| 				 * If you remove this check, ensure that the | ||||
| 				 * exclusive file isn't created. */ | ||||
| 				if (state & RC_SERVICE_FAILED && | ||||
| 				    rc_runlevel_stopping()) | ||||
| 					continue; | ||||
| 				if (state & RC_SERVICE_STARTED || | ||||
| 				    state & RC_SERVICE_INACTIVE) | ||||
| 				{ | ||||
| 					svc_wait(svc->value); | ||||
| 					svcs = rc_service_state(svc->value); | ||||
| 					if (svcs & RC_SERVICE_STARTED || | ||||
| 							svcs & RC_SERVICE_INACTIVE) | ||||
| 					state = rc_service_state(svc->value); | ||||
| 					if (state & RC_SERVICE_STARTED || | ||||
| 					    state & RC_SERVICE_INACTIVE) | ||||
| 					{ | ||||
| 						pid_t pid = service_stop(svc->value); | ||||
| 						if (! rc_conf_yesno("rc_parallel")) | ||||
| @@ -956,21 +983,18 @@ static void svc_stop(bool deps) | ||||
| 			TAILQ_FOREACH(svc, tmplist, entries) { | ||||
| 				if (rc_service_state(svc->value) & RC_SERVICE_STOPPED) | ||||
| 					continue; | ||||
|  | ||||
| 				/* We used to loop 3 times here - maybe re-do this if needed */ | ||||
| 				svc_wait(svc->value); | ||||
| 				if (! (rc_service_state(svc->value) & RC_SERVICE_STOPPED)) { | ||||
| 					if (rc_runlevel_stopping()) { | ||||
| 						/* 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); | ||||
| 					} | ||||
|  | ||||
| 					eerrorx("ERROR: cannot stop %s as %s is still up", | ||||
| 							applet, svc->value); | ||||
| 				} | ||||
| @@ -1077,43 +1101,77 @@ 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; | ||||
| 	char dir[PATH_MAX]; | ||||
| 	char path[PATH_MAX]; | ||||
| 	char lnk[PATH_MAX]; | ||||
| 	size_t l = 0; | ||||
| 	size_t ll; | ||||
| 	char *save; | ||||
| 	char *dir, *save = NULL; | ||||
| 	const char *file; | ||||
| 	int depoptions = RC_DEP_TRACE; | ||||
| 	struct stat stbuf; | ||||
|  | ||||
| 	/* Show help if insufficient args */ | ||||
| 	if (argc < 2 || ! exists(argv[1])) { | ||||
| 		fprintf(stderr, "runscript is not meant to be to run directly\n"); | ||||
| 		fprintf(stderr, "runscript should not be run directly\n"); | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
|  | ||||
| 	applet = basename_c(argv[1]); | ||||
| 	if (argc < 3) | ||||
| 		usage(EXIT_FAILURE); | ||||
|  | ||||
| 	if (*argv[1] == '/') | ||||
| 		service = xstrdup(argv[1]); | ||||
| 	else { | ||||
| 		getcwd(dir, sizeof(dir)); | ||||
| 		l = strlen(dir) + strlen(argv[1]) + 2; | ||||
| 		service = xmalloc(sizeof (char) * l); | ||||
| 		snprintf(service, l, "%s/%s", dir, argv[1]); | ||||
| 	if (stat(argv[1], &stbuf) != 0) { | ||||
| 		fprintf(stderr, "runscript `%s': %s\n", | ||||
| 			argv[1], strerror(errno)); | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
|  | ||||
| 	atexit(cleanup); | ||||
|  | ||||
| 	/* We need to work out the real full path to our service. | ||||
| 	 * This works fine, provided that we ONLY allow mulitplexed services | ||||
| 	 * to exist in the same directory as the master link. | ||||
| 	 * Also, the master link as to be a real file in the init dir. */ | ||||
| 	if (!realpath(argv[1], path)) { | ||||
| 		fprintf(stderr, "realpath: %s\n", strerror(errno)); | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
| 	memset(lnk, 0, sizeof(lnk)); | ||||
| 	if (readlink(argv[1], lnk, sizeof(lnk)-1)) { | ||||
| 		dir = dirname(path); | ||||
| 		if (strchr(lnk, '/')) { | ||||
| 			save = xstrdup(dir); | ||||
| 			dir = dirname(lnk); | ||||
| 			if (strcmp(dir, save) == 0) | ||||
| 				file = basename_c(argv[1]); | ||||
| 			else | ||||
| 				file = basename_c(lnk); | ||||
| 			dir = save;  | ||||
| 		} else | ||||
| 			file = basename_c(argv[1]); | ||||
| 		ll = strlen(dir) + strlen(file) + 2; | ||||
| 		service = xmalloc(ll); | ||||
| 		snprintf(service, ll, "%s/%s", dir, file); | ||||
| 		if (stat(service, &stbuf) != 0) { | ||||
| 			free(service); | ||||
| 			service = xstrdup(lnk); | ||||
| 		} | ||||
| 		free(save); | ||||
| 	} | ||||
| 	if (!service) | ||||
| 		service = xstrdup(path); | ||||
| 	applet = basename_c(service); | ||||
|  | ||||
| 	if (argc < 3) | ||||
| 		usage(EXIT_FAILURE); | ||||
|  | ||||
| 	/* Change dir to / to ensure all init scripts don't use stuff in pwd */ | ||||
| 	chdir("/"); | ||||
|  | ||||
| #ifdef __linux__ | ||||
| 	/* coldplug events can trigger init scripts, but we don't want to run them | ||||
| 	   until after rc sysinit has completed so we punt them to the boot runlevel */ | ||||
| 	/* coldplug events can trigger init scripts, but we don't want to run | ||||
| 	 * them until after rc sysinit has completed so we punt them to the | ||||
| 	 * boot runlevel */ | ||||
| 	if (exists("/dev/.rcsysinit")) { | ||||
| 		eerror("%s: cannot run until sysvinit completes", applet); | ||||
| 		if (mkdir("/dev/.rcboot", 0755) != 0 && errno != EEXIST) | ||||
| @@ -1136,18 +1194,22 @@ 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")) { | ||||
| 		/* Get the longest service name */ | ||||
| 		services = rc_services_in_runlevel(NULL); | ||||
| 		TAILQ_FOREACH(svc, services, entries) { | ||||
| 			ll = strlen(svc->value); | ||||
| 			if (ll > l) | ||||
| 				l = ll; | ||||
| 		} | ||||
| 		if (services) { | ||||
| 			TAILQ_FOREACH(svc, services, entries) { | ||||
| 				ll = strlen(svc->value); | ||||
| 				if (ll > l) | ||||
| 					l = ll; | ||||
| 			} | ||||
| 			rc_stringlist_free(services); | ||||
| 			services = NULL; | ||||
| 		} else l = strlen(applet); | ||||
|  | ||||
| 		/* Make our prefix string */ | ||||
| 		prefix = xmalloc(sizeof(char) * l + 1); | ||||
| @@ -1235,6 +1297,7 @@ int runscript(int argc, char **argv) | ||||
| 			prefix = NULL; | ||||
| 			svc_exec(optarg, NULL); | ||||
| 			eprefix(save); | ||||
| 			prefix = save; | ||||
| 		} else if (strcmp(optarg, "ineed") == 0 || | ||||
| 			   strcmp(optarg, "iuse") == 0 || | ||||
| 			   strcmp(optarg, "needsme") == 0 || | ||||
| @@ -1243,7 +1306,8 @@ int runscript(int argc, char **argv) | ||||
| 			   strcmp(optarg, "ibefore") == 0 || | ||||
| 			   strcmp(optarg, "iprovide") == 0) | ||||
| 		{ | ||||
| 			if (rc_conf_yesno("rc_depend_strict")) | ||||
| 			errno = 0; | ||||
| 			if (rc_conf_yesno("rc_depend_strict") || errno == ENOENT) | ||||
| 				depoptions |= RC_DEP_STRICT; | ||||
|  | ||||
| 			if (! deptree && ((deptree = _rc_deptree_load(NULL)) == NULL)) | ||||
| @@ -1299,7 +1363,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); | ||||
|   | ||||
| @@ -190,7 +190,7 @@ static SCHEDULEITEM *parse_schedule_item(const char *string) | ||||
| 	item->gotoitem = NULL; | ||||
| 	if (strcmp(string,"forever") == 0) | ||||
| 		item->type = SC_FOREVER; | ||||
| 	else if (isdigit((int) string[0])) { | ||||
| 	else if (isdigit((unsigned char)string[0])) { | ||||
| 		item->type = SC_TIMEOUT; | ||||
| 		errno = 0; | ||||
| 		if (sscanf(string, "%d", &item->value) != 1) | ||||
| @@ -308,7 +308,7 @@ static pid_t get_pid(const char *pidfile, bool quiet) | ||||
|  | ||||
| /* return number of processed killed, -1 on error */ | ||||
| static int do_stop(const char *const *argv, const char *cmd, | ||||
| 		   const char *pidfile, uid_t uid,int sig, | ||||
| 		   pid_t pid, uid_t uid,int sig, | ||||
| 		   bool quiet, bool verbose, bool test) | ||||
| { | ||||
| 	RC_PIDLIST *pids; | ||||
| @@ -316,13 +316,10 @@ static int do_stop(const char *const *argv, const char *cmd, | ||||
| 	RC_PID *np; | ||||
| 	bool killed; | ||||
| 	int nkilled = 0; | ||||
| 	pid_t pid = 0; | ||||
|  | ||||
| 	if (pidfile) { | ||||
| 		if ((pid = get_pid(pidfile, quiet)) == -1) | ||||
| 			return quiet ? 0 : -1; | ||||
| 	if (pid) | ||||
| 		pids = rc_find_pids(NULL, NULL, 0, pid); | ||||
| 	} else | ||||
| 	else | ||||
| 		pids = rc_find_pids(argv, cmd, uid, pid); | ||||
|  | ||||
| 	if (! pids) | ||||
| @@ -369,6 +366,7 @@ static int run_stop_schedule(const char *const *argv, const char *cmd, | ||||
| 	int nrunning = 0; | ||||
| 	long nloops; | ||||
| 	struct timespec ts; | ||||
| 	pid_t pid = 0; | ||||
|  | ||||
| 	if (verbose) { | ||||
| 		if (pidfile) | ||||
| @@ -381,6 +379,12 @@ static int run_stop_schedule(const char *const *argv, const char *cmd, | ||||
| 			einfo("Will stop processes called `%s'", cmd); | ||||
| 	} | ||||
|  | ||||
| 	if (pidfile) { | ||||
| 		pid = get_pid(pidfile, quiet); | ||||
| 		if (pid == -1) | ||||
| 			return 0; | ||||
| 	} | ||||
|  | ||||
| 	while (item) { | ||||
| 		switch (item->type) { | ||||
| 		case SC_GOTO: | ||||
| @@ -389,7 +393,7 @@ static int run_stop_schedule(const char *const *argv, const char *cmd, | ||||
|  | ||||
| 		case SC_SIGNAL: | ||||
| 			nrunning = 0; | ||||
| 			nkilled = do_stop(argv, cmd, pidfile, uid, item->value, | ||||
| 			nkilled = do_stop(argv, cmd, pid, uid, item->value, | ||||
| 					  quiet, verbose, test); | ||||
| 			if (nkilled == 0) { | ||||
| 				if (tkilled == 0) { | ||||
| @@ -415,9 +419,9 @@ static int run_stop_schedule(const char *const *argv, const char *cmd, | ||||
| 			ts.tv_nsec = POLL_INTERVAL; | ||||
|  | ||||
| 			while (nloops) { | ||||
| 				if ((nrunning = do_stop(argv, cmd, pidfile, | ||||
| 				if ((nrunning = do_stop(argv, cmd, pid, | ||||
| 							uid, 0, true, false, true)) == 0) | ||||
| 					return true; | ||||
| 					return 0; | ||||
|  | ||||
| 				if (nanosleep(&ts, NULL) == -1) { | ||||
| 					if (errno == EINTR) | ||||
| @@ -852,7 +856,12 @@ int start_stop_daemon(int argc, char **argv) | ||||
| 		exit(EXIT_SUCCESS); | ||||
| 	} | ||||
|  | ||||
| 	if (do_stop((const char * const *)argv, cmd, pidfile, uid, | ||||
| 	if (pidfile) { | ||||
| 		pid = get_pid(pidfile, true); | ||||
| 	} else | ||||
| 		pid = 0; | ||||
|  | ||||
| 	if (do_stop((const char * const *)argv, cmd, pid, uid, | ||||
| 		    0, true, false, true) > 0) | ||||
| 		eerrorx("%s: %s is already running", applet, exec); | ||||
|  | ||||
| @@ -1112,16 +1121,18 @@ int start_stop_daemon(int argc, char **argv) | ||||
| 			} else { | ||||
| 				if (pidfile) { | ||||
| 					/* The pidfile may not have been written yet - give it some time */ | ||||
| 					if (get_pid(pidfile, true) == -1) { | ||||
| 					if ((pid = get_pid(pidfile, true)) == -1) { | ||||
| 						if (! nloopsp) | ||||
| 							eerrorx("%s: did not create a valid pid in `%s'", | ||||
| 								applet, pidfile); | ||||
| 						alive = true; | ||||
| 						pid = 0; | ||||
| 					} else | ||||
| 						nloopsp = 0; | ||||
| 				} | ||||
| 				} else | ||||
| 					pid = 0; | ||||
| 				if (do_stop((const char *const *)argv, cmd, | ||||
| 					    pidfile, uid, 0, true, false, true) > 0) | ||||
| 					    pid, uid, 0, true, false, true) > 0) | ||||
| 					alive = true; | ||||
| 			} | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user