Compare commits
	
		
			34 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					422795e2ce | ||
| 
						 | 
					00ad99a292 | ||
| 
						 | 
					f026c2c541 | ||
| 
						 | 
					4d20309ffe | ||
| 
						 | 
					65439ba023 | ||
| 
						 | 
					86162f3f47 | ||
| 
						 | 
					b98e83ee91 | ||
| 
						 | 
					d59197fafe | ||
| 
						 | 
					b66c86c9ee | ||
| 
						 | 
					f7eb236f6f | ||
| 
						 | 
					1936d73eb1 | ||
| 
						 | 
					58872fc090 | ||
| 
						 | 
					fc35eb90ca | ||
| 
						 | 
					b18be3f970 | ||
| 
						 | 
					027438f775 | ||
| 
						 | 
					93e159ae85 | ||
| 
						 | 
					bcfcf50562 | ||
| 
						 | 
					d0097cc10f | ||
| 
						 | 
					eecf868e3c | ||
| 
						 | 
					a5cd486a7f | ||
| 
						 | 
					6e6b4ac5fa | ||
| 
						 | 
					558ff4d5fb | ||
| 
						 | 
					490f855aef | ||
| 
						 | 
					d1491e201d | ||
| 
						 | 
					3231af9375 | ||
| 
						 | 
					a5758e7aef | ||
| 
						 | 
					61a9393ce1 | ||
| 
						 | 
					161d22cb07 | ||
| 
						 | 
					3a96ca1c96 | ||
| 
						 | 
					934530914b | ||
| 
						 | 
					b717625cd2 | ||
| 
						 | 
					b475396134 | ||
| 
						 | 
					e7b1d898ca | ||
| 
						 | 
					5cd09a6f44 | 
@@ -1,5 +1,4 @@
 | 
				
			|||||||
Using Busybox as your Default Shell with OpenRC
 | 
					# Using Busybox as your Default Shell with OpenRC
 | 
				
			||||||
===============================================
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
If you have/bin/sh linked to busybox, you need to be aware of several
 | 
					If you have/bin/sh linked to busybox, you need to be aware of several
 | 
				
			||||||
incompatibilities between busybox's applets and the standalone
 | 
					incompatibilities between busybox's applets and the standalone
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,12 +1,11 @@
 | 
				
			|||||||
Features Scheduled for Removal
 | 
					# Features Scheduled for Removal
 | 
				
			||||||
==============================
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
The following is a list of files and features that are going to be removed in
 | 
					The following is a list of files and features that are going to be removed in
 | 
				
			||||||
the source tree.  Every entry should contain what exactly is going away, why it
 | 
					the source tree.  Every entry should contain what exactly is going away, why it
 | 
				
			||||||
is happening, and who is going to be doing the work.  When the feature is
 | 
					is happening, and who is going to be doing the work.  When the feature is
 | 
				
			||||||
removed, it should also be removed from this file.
 | 
					removed, it should also be removed from this file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Service pause action
 | 
					## Service pause action
 | 
				
			||||||
 | 
					
 | 
				
			||||||
When: 1.0
 | 
					When: 1.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -14,7 +13,7 @@ Why: The same affect can be obtained with the --nodeps option to stop.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Who:
 | 
					Who:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# start-stop-daemon options --startas, --chuid , --oknodo
 | 
					## start-stop-daemon options --startas, --chuid , --oknodo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
When: 1.0
 | 
					When: 1.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -26,7 +25,7 @@ Why: Obsolete or replaced by other options.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Who:
 | 
					Who:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# runscript and rc symbolic links
 | 
					## runscript and rc symbolic links
 | 
				
			||||||
 | 
					
 | 
				
			||||||
When: 1.0
 | 
					When: 1.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -35,7 +34,7 @@ Why: Deprecated in favor of openrc-run and openrc due to naming
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Who:
 | 
					Who:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# support for the opts variable in service scripts
 | 
					## support for the opts variable in service scripts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
When: 1.0
 | 
					When: 1.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -44,7 +43,7 @@ Why: Deprecated in favor of extra_commands, extra_started_commands
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Who:
 | 
					Who:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# support for local_start and local_stop
 | 
					## support for local_start and local_stop
 | 
				
			||||||
 | 
					
 | 
				
			||||||
When: 1.0
 | 
					When: 1.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -52,7 +51,7 @@ Why: Deprecated in favor of executable scripts in @SYSCONFDIR@/local.d
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Who:
 | 
					Who:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# the mtab service script
 | 
					## the mtab service script
 | 
				
			||||||
 | 
					
 | 
				
			||||||
When: force /etc/mtab to link to /proc/self/mounts in 1.0, remove
 | 
					When: force /etc/mtab to link to /proc/self/mounts in 1.0, remove
 | 
				
			||||||
	  service in 2.0
 | 
						  service in 2.0
 | 
				
			||||||
@@ -62,13 +61,13 @@ Why: /etc/mtab should be a symbolic link to /proc/self/mounts on modern
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Who:
 | 
					Who:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# C API Functions in rc.h
 | 
					## C API Functions in rc.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
If you have a c program that links to librc and uses functions from
 | 
					If you have a c program that links to librc and uses functions from
 | 
				
			||||||
there, this section will list API functions which are deprecated and
 | 
					there, this section will list API functions which are deprecated and
 | 
				
			||||||
will be removed along with the reason they are being removed.
 | 
					will be removed along with the reason they are being removed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## rc_getline()
 | 
					### rc_getline()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
When: 1.0
 | 
					When: 1.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,4 @@
 | 
				
			|||||||
OpenRC History
 | 
					# OpenRC History
 | 
				
			||||||
==============
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
This history of OpenRC was written by Daniel Robbins, Roy Marples, William
 | 
					This history of OpenRC was written by Daniel Robbins, Roy Marples, William
 | 
				
			||||||
Hubbs and others.
 | 
					Hubbs and others.
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										12
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								Makefile
									
									
									
									
									
								
							@@ -15,24 +15,12 @@ include ${TOP}/Makefile.inc
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
SUBDIR=		conf.d etc init.d local.d man scripts sh src support sysctl.d
 | 
					SUBDIR=		conf.d etc init.d local.d man scripts sh src support sysctl.d
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Build bash completion or not
 | 
					 | 
				
			||||||
MKBASHCOMP?=	no
 | 
					 | 
				
			||||||
ifeq (${MKBASHCOMP},yes)
 | 
					 | 
				
			||||||
SUBDIR+=	bash-completion
 | 
					 | 
				
			||||||
endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Build pkgconfig or not
 | 
					# Build pkgconfig or not
 | 
				
			||||||
MKPKGCONFIG?=	yes
 | 
					MKPKGCONFIG?=	yes
 | 
				
			||||||
ifeq (${MKPKGCONFIG},yes)
 | 
					ifeq (${MKPKGCONFIG},yes)
 | 
				
			||||||
SUBDIR+=	pkgconfig
 | 
					SUBDIR+=	pkgconfig
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Build zsh completion or not
 | 
					 | 
				
			||||||
MKZSHCOMP?=	no
 | 
					 | 
				
			||||||
ifeq (${MKZSHCOMP},yes)
 | 
					 | 
				
			||||||
SUBDIR+=	zsh-completion
 | 
					 | 
				
			||||||
endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# We need to ensure that runlevels is done last
 | 
					# We need to ensure that runlevels is done last
 | 
				
			||||||
SUBDIR+=	runlevels
 | 
					SUBDIR+=	runlevels
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,3 @@
 | 
				
			|||||||
NAME=		openrc
 | 
					NAME=		openrc
 | 
				
			||||||
VERSION=	0.35.5
 | 
					VERSION=	0.34.8
 | 
				
			||||||
PKG=		${NAME}-${VERSION}
 | 
					PKG=		${NAME}-${VERSION}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										35
									
								
								NEWS.md
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								NEWS.md
									
									
									
									
									
								
							@@ -1,41 +1,8 @@
 | 
				
			|||||||
OpenRC NEWS
 | 
					# OpenRC NEWS
 | 
				
			||||||
===========
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
This file will contain a list of notable changes for each release. Note
 | 
					This file will contain a list of notable changes for each release. Note
 | 
				
			||||||
the information in this file is in reverse order.
 | 
					the information in this file is in reverse order.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## OpenRC 0.35
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
In this version, the cgroups mounting logic has been moved from the
 | 
					 | 
				
			||||||
sysfs service to the cgroups service. This was done so cgroups can be
 | 
					 | 
				
			||||||
mounted inside an lxc/lxd container without using the other parts of the
 | 
					 | 
				
			||||||
sysfs service.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
?As a result of this change, if you are upgrading, you need to add
 | 
					 | 
				
			||||||
cgroups to your sysinit runlevel by running the following command as
 | 
					 | 
				
			||||||
root:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
# rc-update add cgroups sysinit
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
For more information, see the following issue:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
https://github.com/openrc/openrc/issues/187
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Consider this your second notification with regard to /etc/mtab being a
 | 
					 | 
				
			||||||
file instead of a symbolic link.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
In this version, the mtab service will complain loudly if you have
 | 
					 | 
				
			||||||
mtab_is_file set to yes and recommend that you change this to no and
 | 
					 | 
				
			||||||
restart the mtab service to migrate /etc/mtab to a symbolic link.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If there is a valid technical reason to keep /etc/mtab as a flat file
 | 
					 | 
				
			||||||
instead of a symbolic link to /proc/self/mounts, we are interested and
 | 
					 | 
				
			||||||
we will keep the support in that case. Please open an issue and let us
 | 
					 | 
				
			||||||
know however. Otherwise, consider this your final notice that the mtab
 | 
					 | 
				
			||||||
service will be removed in the future.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## OpenRC 0.33
 | 
					## OpenRC 0.33
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This version removes the "service" binary which was just a copy of
 | 
					This version removes the "service" binary which was just a copy of
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,4 @@
 | 
				
			|||||||
OpenRC README
 | 
					# OpenRC README
 | 
				
			||||||
=============
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
OpenRC is a dependency-based init system that works with the
 | 
					OpenRC is a dependency-based init system that works with the
 | 
				
			||||||
system-provided init program, normally `/sbin/init`. Currently, it does
 | 
					system-provided init program, normally `/sbin/init`. Currently, it does
 | 
				
			||||||
@@ -23,7 +22,6 @@ below arguments to the make command
 | 
				
			|||||||
PROGLDFLAGS=-static
 | 
					PROGLDFLAGS=-static
 | 
				
			||||||
LIBNAME=lib64
 | 
					LIBNAME=lib64
 | 
				
			||||||
DESTDIR=/tmp/openrc-image
 | 
					DESTDIR=/tmp/openrc-image
 | 
				
			||||||
MKBASHCOMP=no
 | 
					 | 
				
			||||||
MKNET=no
 | 
					MKNET=no
 | 
				
			||||||
MKPAM=pam
 | 
					MKPAM=pam
 | 
				
			||||||
MKPREFIX=yes
 | 
					MKPREFIX=yes
 | 
				
			||||||
@@ -33,7 +31,6 @@ MKSTATICLIBS=no
 | 
				
			|||||||
MKSYSVINIT=yes
 | 
					MKSYSVINIT=yes
 | 
				
			||||||
MKTERMCAP=ncurses
 | 
					MKTERMCAP=ncurses
 | 
				
			||||||
MKTERMCAP=termcap
 | 
					MKTERMCAP=termcap
 | 
				
			||||||
MKZSHCOMP=no
 | 
					 | 
				
			||||||
PKG_PREFIX=/usr/pkg
 | 
					PKG_PREFIX=/usr/pkg
 | 
				
			||||||
LOCAL_PREFIX=/usr/local
 | 
					LOCAL_PREFIX=/usr/local
 | 
				
			||||||
PREFIX=/usr/local
 | 
					PREFIX=/usr/local
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,4 @@
 | 
				
			|||||||
OpenRC Coding Style Guide
 | 
					# OpenRC Style Guide
 | 
				
			||||||
=========================
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
This is the openrc style manual.  It governs the coding style of all code
 | 
					This is the openrc style manual.  It governs the coding style of all code
 | 
				
			||||||
in this repository.  Follow it.  Contact openrc@gentoo.org for any questions
 | 
					in this repository.  Follow it.  Contact openrc@gentoo.org for any questions
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,4 @@
 | 
				
			|||||||
Setting up the agetty service in OpenRC
 | 
					# Setting up the agetty service in OpenRC
 | 
				
			||||||
=================================xxxxxx
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
The agetty service is an OpenRC specific way to monitor and respawn a
 | 
					The agetty service is an OpenRC specific way to monitor and respawn a
 | 
				
			||||||
getty, using agetty, on Linux. To use this method, make sure you aren't
 | 
					getty, using agetty, on Linux. To use this method, make sure you aren't
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,11 +0,0 @@
 | 
				
			|||||||
DIR=	${BASHCOMPDIR}
 | 
					 | 
				
			||||||
CONF=	openrc \
 | 
					 | 
				
			||||||
		openrc-service-script \
 | 
					 | 
				
			||||||
		rc-service \
 | 
					 | 
				
			||||||
		rc-status \
 | 
					 | 
				
			||||||
		rc-update \
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
MK=	../mk
 | 
					 | 
				
			||||||
include ${MK}/os.mk
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
include ${MK}/scripts.mk
 | 
					 | 
				
			||||||
@@ -1,24 +0,0 @@
 | 
				
			|||||||
# Copyright (c) 2017 The OpenRC Authors.
 | 
					 | 
				
			||||||
# See the Authors file at the top-level directory of this distribution and
 | 
					 | 
				
			||||||
# https://github.com/OpenRC/openrc/blob/master/AUTHORS
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# This file is part of OpenRC. It is subject to the license terms in
 | 
					 | 
				
			||||||
# the LICENSE file found in the top-level directory of this
 | 
					 | 
				
			||||||
# distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
 | 
					 | 
				
			||||||
# This file may not be copied, modified, propagated, or distributed
 | 
					 | 
				
			||||||
# except according to the terms contained in the LICENSE file.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# openrc completion command
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
_openrc()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	local cur
 | 
					 | 
				
			||||||
	COMPREPLY=()
 | 
					 | 
				
			||||||
	cur="${COMP_WORDS[COMP_CWORD]}"
 | 
					 | 
				
			||||||
	if [[ ${#COMP_WORDS[*]} -le 2 ]]; then
 | 
					 | 
				
			||||||
		COMPREPLY=($(compgen -W "$(rc-status --list)" -- $cur))
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
	return 0
 | 
					 | 
				
			||||||
} &&
 | 
					 | 
				
			||||||
complete -F _openrc openrc
 | 
					 | 
				
			||||||
@@ -1,29 +0,0 @@
 | 
				
			|||||||
# Copyright (c) 2017 The OpenRC Authors.
 | 
					 | 
				
			||||||
# See the Authors file at the top-level directory of this distribution and
 | 
					 | 
				
			||||||
# https://github.com/OpenRC/openrc/blob/master/AUTHORS
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# This file is part of OpenRC. It is subject to the license terms in
 | 
					 | 
				
			||||||
# the LICENSE file found in the top-level directory of this
 | 
					 | 
				
			||||||
# distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
 | 
					 | 
				
			||||||
# This file may not be copied, modified, propagated, or distributed
 | 
					 | 
				
			||||||
# except according to the terms contained in the LICENSE file.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
_openrc_service_script()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	local script="${COMP_WORDS[0]}"
 | 
					 | 
				
			||||||
	local cur="${COMP_WORDS[$COMP_CWORD]}"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if [[ ( -f "${script}" || -h "${script}" ) && -r "${script}" ]] \
 | 
					 | 
				
			||||||
	&& [[ "$(head -n 1 "${script}")" =~ \#\!.*/openrc-run ]]
 | 
					 | 
				
			||||||
	then
 | 
					 | 
				
			||||||
		[[ $COMP_CWORD -gt 1 ]] && return 1
 | 
					 | 
				
			||||||
		COMPREPLY=($(opts="start stop status restart pause zap ineed needsme iuse usesme broken"; \
 | 
					 | 
				
			||||||
			eval "$(grep '^opts=' "${script}")"; echo "${opts}"))
 | 
					 | 
				
			||||||
		[[ -n "$COMPREPLY" ]] || COMPREPLY=(start stop restart zap)
 | 
					 | 
				
			||||||
		COMPREPLY=($(compgen -W "${COMPREPLY[*]}" -- "${cur}"))
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		COMPREPLY=($(compgen -o default -- "${cur}"))
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
	return 0
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
complete -F _openrc_service_script */etc/init.d/*
 | 
					 | 
				
			||||||
@@ -1,113 +0,0 @@
 | 
				
			|||||||
# Copyright (c) 2017 The OpenRC Authors.
 | 
					 | 
				
			||||||
# See the Authors file at the top-level directory of this distribution and
 | 
					 | 
				
			||||||
# https://github.com/OpenRC/openrc/blob/master/AUTHORS
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# This file is part of OpenRC. It is subject to the license terms in
 | 
					 | 
				
			||||||
# the LICENSE file found in the top-level directory of this
 | 
					 | 
				
			||||||
# distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
 | 
					 | 
				
			||||||
# This file may not be copied, modified, propagated, or distributed
 | 
					 | 
				
			||||||
# except according to the terms contained in the LICENSE file.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# rc-service completion command
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
_rc_service()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	local cur prev numwords opts
 | 
					 | 
				
			||||||
	local words i x filename
 | 
					 | 
				
			||||||
	local action actionpos
 | 
					 | 
				
			||||||
	COMPREPLY=()
 | 
					 | 
				
			||||||
	cur="${COMP_WORDS[COMP_CWORD]}"
 | 
					 | 
				
			||||||
	prev="${COMP_WORDS[COMP_CWORD-1]}"
 | 
					 | 
				
			||||||
	numwords=${#COMP_WORDS[*]}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if [[ ${prev} == '>' || ${prev} == '<' ]] ; then
 | 
					 | 
				
			||||||
		COMPREPLY=($(compgen -f -- ${cur}))
 | 
					 | 
				
			||||||
		return 0
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	# find action
 | 
					 | 
				
			||||||
	for x in ${COMP_LINE} ; do
 | 
					 | 
				
			||||||
		if [[ ${x} =~ --(list|exists|resolve) ]] || [[ ${x} =~ -(l|e|r) ]]
 | 
					 | 
				
			||||||
		then
 | 
					 | 
				
			||||||
			action=${x}
 | 
					 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		fi
 | 
					 | 
				
			||||||
	done
 | 
					 | 
				
			||||||
	if [[ -n ${action} ]]; then
 | 
					 | 
				
			||||||
		for ((i = 0; i < ${numwords}; i++ )); do
 | 
					 | 
				
			||||||
			if [[ ${COMP_WORDS[${i}]} == "${action}" ]]; then
 | 
					 | 
				
			||||||
				actionpos=${i}
 | 
					 | 
				
			||||||
				break
 | 
					 | 
				
			||||||
			fi
 | 
					 | 
				
			||||||
		done
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		for ((i = 1; i < ${numwords}; i++ )); do
 | 
					 | 
				
			||||||
			if [[ ! ${COMP_WORDS[$i]} == -* ]]; then
 | 
					 | 
				
			||||||
				break
 | 
					 | 
				
			||||||
			fi
 | 
					 | 
				
			||||||
		done
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if [[ ${COMP_CWORD} -eq 3 ]]; then
 | 
					 | 
				
			||||||
		return 1
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	# check if an option was typed
 | 
					 | 
				
			||||||
	if [[ ${cur} == -* ]]; then
 | 
					 | 
				
			||||||
		if [[ ${cur} == --* ]]; then
 | 
					 | 
				
			||||||
			opts="--list --exists --resolve"
 | 
					 | 
				
			||||||
			COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
 | 
					 | 
				
			||||||
			return 0
 | 
					 | 
				
			||||||
		elif [[ ${cur} == -* ]]; then
 | 
					 | 
				
			||||||
			opts="-l -e -r"
 | 
					 | 
				
			||||||
			COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
 | 
					 | 
				
			||||||
			return 0
 | 
					 | 
				
			||||||
		fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		# NOTE: This slows things down!
 | 
					 | 
				
			||||||
		# (Adapted from bash_completion by Ian Macdonald <ian@caliban.org>)
 | 
					 | 
				
			||||||
		# This removes any options from the list of completions that have
 | 
					 | 
				
			||||||
		# already been specified on the command line.
 | 
					 | 
				
			||||||
		COMPREPLY=($(echo "${COMP_WORDS[@]}" | \
 | 
					 | 
				
			||||||
		(while read -d ' ' i; do
 | 
					 | 
				
			||||||
			[[ -z ${i} ]] && continue
 | 
					 | 
				
			||||||
			# flatten array with spaces on either side,
 | 
					 | 
				
			||||||
			# otherwise we cannot grep on word boundaries of
 | 
					 | 
				
			||||||
			# first and last word
 | 
					 | 
				
			||||||
			COMPREPLY=" ${COMPREPLY[@]} "
 | 
					 | 
				
			||||||
			# remove word from list of completions
 | 
					 | 
				
			||||||
			COMPREPLY=(${COMPREPLY/ ${i%% *} / })
 | 
					 | 
				
			||||||
		done
 | 
					 | 
				
			||||||
		echo ${COMPREPLY[@]})))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return 0
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		# no option was typed
 | 
					 | 
				
			||||||
		if [[ ${COMP_CWORD} -eq 1 ]]; then			  # if first word typed
 | 
					 | 
				
			||||||
			words="$(rc-service --list | grep ^${cur})"		  # complete for init scripts
 | 
					 | 
				
			||||||
			COMPREPLY=($(for i in ${words} ; do \
 | 
					 | 
				
			||||||
			[[ ${i} == ${cur}* ]] && echo ${i} ; \
 | 
					 | 
				
			||||||
			done))
 | 
					 | 
				
			||||||
			return 0
 | 
					 | 
				
			||||||
		elif [[ ${COMP_CWORD} -eq 2 ]] && [[ ${prev} != -* ]]; then # if second word typed and we didn't type in a function
 | 
					 | 
				
			||||||
			filename=$(rc-service --resolve ${prev})
 | 
					 | 
				
			||||||
			opts=$(cat ${filename} | grep "^\w*()" | sed "s/().*$//")	# Greps the functions included in the init script
 | 
					 | 
				
			||||||
			if [[ "x${opts}" == "x" ]] ; then			   # if no options found loosen the grep algorhythm
 | 
					 | 
				
			||||||
				opts=$(cat ${filename} | grep "\w*()" | sed "s/().*$//")
 | 
					 | 
				
			||||||
			fi
 | 
					 | 
				
			||||||
			COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
 | 
					 | 
				
			||||||
			return 0
 | 
					 | 
				
			||||||
		fi
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
	if [[ ${action} == '--exists' ]] || [[ ${action} == '-e' ]] || \
 | 
					 | 
				
			||||||
		[[ ${action} == '--resolve' ]]  || [[ ${action} == '-r' ]]; then
 | 
					 | 
				
			||||||
		words="$(rc-service --list | grep ^${cur})"
 | 
					 | 
				
			||||||
		COMPREPLY=($(for i in ${words} ; do \
 | 
					 | 
				
			||||||
			[[ ${i} == ${cur}* ]] && echo ${i} ; \
 | 
					 | 
				
			||||||
		done))
 | 
					 | 
				
			||||||
		return 0
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
	return 0
 | 
					 | 
				
			||||||
} &&
 | 
					 | 
				
			||||||
complete -F _rc_service rc-service
 | 
					 | 
				
			||||||
@@ -1,31 +0,0 @@
 | 
				
			|||||||
# Copyright (c) 2017 The OpenRC Authors.
 | 
					 | 
				
			||||||
# See the Authors file at the top-level directory of this distribution and
 | 
					 | 
				
			||||||
# https://github.com/OpenRC/openrc/blob/master/AUTHORS
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# This file is part of OpenRC. It is subject to the license terms in
 | 
					 | 
				
			||||||
# the LICENSE file found in the top-level directory of this
 | 
					 | 
				
			||||||
# distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
 | 
					 | 
				
			||||||
# This file may not be copied, modified, propagated, or distributed
 | 
					 | 
				
			||||||
# except according to the terms contained in the LICENSE file.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# rc-status completion command
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
_rcstatus()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	local cur
 | 
					 | 
				
			||||||
	cur="${COMP_WORDS[COMP_CWORD]}"
 | 
					 | 
				
			||||||
	if [[ $COMP_CWORD -eq 1 ]]; then
 | 
					 | 
				
			||||||
		if [[ "${cur}" == --* ]]; then
 | 
					 | 
				
			||||||
			COMPREPLY=($(compgen -W '--all --list --unused' -- ${cur}))
 | 
					 | 
				
			||||||
		elif [[ "${cur}" == -* ]]; then
 | 
					 | 
				
			||||||
			COMPREPLY=($(compgen -W '-a -l -u' -- ${cur}))
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			COMPREPLY=($(compgen -W "$(rc-status --list)" -- ${cur}))
 | 
					 | 
				
			||||||
		fi
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		unset COMPREPLY
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
	return 0
 | 
					 | 
				
			||||||
} &&
 | 
					 | 
				
			||||||
complete -F _rcstatus rc-status
 | 
					 | 
				
			||||||
@@ -1,42 +0,0 @@
 | 
				
			|||||||
# Copyright (c) 2017 The OpenRC Authors.
 | 
					 | 
				
			||||||
# See the Authors file at the top-level directory of this distribution and
 | 
					 | 
				
			||||||
# https://github.com/OpenRC/openrc/blob/master/AUTHORS
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# This file is part of OpenRC. It is subject to the license terms in
 | 
					 | 
				
			||||||
# the LICENSE file found in the top-level directory of this
 | 
					 | 
				
			||||||
# distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
 | 
					 | 
				
			||||||
# This file may not be copied, modified, propagated, or distributed
 | 
					 | 
				
			||||||
# except according to the terms contained in the LICENSE file.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# rc-update completion command
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
_rc_update()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	local cur show
 | 
					 | 
				
			||||||
	COMPREPLY=()
 | 
					 | 
				
			||||||
	cur="${COMP_WORDS[COMP_CWORD]}"
 | 
					 | 
				
			||||||
	if [[ $COMP_CWORD -eq 1 ]]; then
 | 
					 | 
				
			||||||
		if [[ "${cur}" == -* ]]; then
 | 
					 | 
				
			||||||
			COMPREPLY=($(compgen -W '-a -d -s' -- ${cur}))
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			COMPREPLY=($(compgen -W 'add del show' ${cur}))
 | 
					 | 
				
			||||||
		fi
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		if [[ "${COMP_WORDS[1]}" == "show" ]] || [[ "${COMP_WORDS[1]}" == "-s" ]]; then
 | 
					 | 
				
			||||||
			show="TRUE"
 | 
					 | 
				
			||||||
		fi
 | 
					 | 
				
			||||||
		if ([[ $COMP_CWORD -eq 3 ]] && [[ -z "$show" ]]) || \
 | 
					 | 
				
			||||||
			([[ $COMP_CWORD -eq 2 ]] && [[ -n "$show" ]]); then
 | 
					 | 
				
			||||||
		COMPREPLY=($(compgen -W "$(rc-status --list)" -- $cur))
 | 
					 | 
				
			||||||
		elif [[ $COMP_CWORD -eq 2 ]]; then
 | 
					 | 
				
			||||||
			COMPREPLY=($(compgen -W "$(rc-service --list)" $cur))
 | 
					 | 
				
			||||||
		elif [[ ${#COMP_WORDS[*]} -gt 2 ]] ; then
 | 
					 | 
				
			||||||
			COMPREPLY=($(compgen -W "$(rc-status --list)" -- $cur))
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			unset COMPREPLY
 | 
					 | 
				
			||||||
		fi
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
	return 0
 | 
					 | 
				
			||||||
} &&
 | 
					 | 
				
			||||||
complete -F _rc_update rc-update
 | 
					 | 
				
			||||||
							
								
								
									
										14
									
								
								conf.d/mtab
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								conf.d/mtab
									
									
									
									
									
								
							@@ -1,13 +1,5 @@
 | 
				
			|||||||
# As far as we are aware, there are no modern linux tools or use cases
 | 
					 | 
				
			||||||
# which require /etc/mtab to be a separate file from /proc/self/mounts,
 | 
					 | 
				
			||||||
# so this setting should be commented out.
 | 
					 | 
				
			||||||
# If it is set to yes, please comment it out and run this command:
 | 
					 | 
				
			||||||
# # rc-service mtab restart
 | 
					 | 
				
			||||||
# In the future, the mtab service will be removed since we are not aware
 | 
					 | 
				
			||||||
# of any need to manipulate /etc/mtab as a separate file from
 | 
					 | 
				
			||||||
# /proc/self/mounts.
 | 
					 | 
				
			||||||
# If you have a technical reason we should keep this support, please
 | 
					 | 
				
			||||||
# open an issue at https://github.com/openrc/openrc/issues and let us
 | 
					 | 
				
			||||||
# know about your situation.
 | 
					 | 
				
			||||||
# This setting controls whether /etc/mtab is a file or symbolic link.
 | 
					# This setting controls whether /etc/mtab is a file or symbolic link.
 | 
				
			||||||
 | 
					# Most of the time, you shouldn't touch this. However, if the default
 | 
				
			||||||
 | 
					# breaks your system in some way, please see the NEWS.md file that comes
 | 
				
			||||||
 | 
					# with OpenRC for the actions to take.
 | 
				
			||||||
# mtab_is_file=no
 | 
					# mtab_is_file=no
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -227,11 +227,6 @@ rc_tty_number=12
 | 
				
			|||||||
# /sys/fs/cgroup in hybrid or legacy mode.
 | 
					# /sys/fs/cgroup in hybrid or legacy mode.
 | 
				
			||||||
#rc_controller_cgroups="YES"
 | 
					#rc_controller_cgroups="YES"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# The following setting turns on the memory.use_hierarchy setting in the
 | 
					 | 
				
			||||||
# root memory cgroup for cgroups v1.
 | 
					 | 
				
			||||||
# It must be set to yes in this file if you want this functionality.
 | 
					 | 
				
			||||||
#rc_cggroup_memory_use_hierarchy="NO"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# The following settings allow you to set up values for the cgroups version 1
 | 
					# The following settings allow you to set up values for the cgroups version 1
 | 
				
			||||||
# controllers for your services.
 | 
					# controllers for your services.
 | 
				
			||||||
# They can be set in this file;, however, if you do this, the settings
 | 
					# They can be set in this file;, however, if you do this, the settings
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,3 @@
 | 
				
			|||||||
OpenRC Users Guide
 | 
					 | 
				
			||||||
==================
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Purpose and description
 | 
					# Purpose and description
 | 
				
			||||||
 | 
					
 | 
				
			||||||
OpenRC is an init system for Unixoid operating systems. It takes care of 
 | 
					OpenRC is an init system for Unixoid operating systems. It takes care of 
 | 
				
			||||||
@@ -30,8 +27,8 @@ openrc scans the runlevels (default: `/etc/runlevels`) and builds a dependency
 | 
				
			|||||||
graph, then starts the needed service scripts, either serialized (default) or in 
 | 
					graph, then starts the needed service scripts, either serialized (default) or in 
 | 
				
			||||||
parallel.
 | 
					parallel.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
When all the service scripts are started openrc terminates. There is no
 | 
					When all the init scripts are started openrc terminates. There is no persistent 
 | 
				
			||||||
persistent daemon. (Integration with tools like monit, runit or s6 can be done)
 | 
					daemon. (Integration with tools like monit, runit or s6 can be done)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Shutdown
 | 
					# Shutdown
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -66,7 +63,7 @@ own if needed. This allows, for example, to have a default runlevel with
 | 
				
			|||||||
disabled.
 | 
					disabled.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The `rc-status` helper will print all currently active runlevels and the state
 | 
					The `rc-status` helper will print all currently active runlevels and the state
 | 
				
			||||||
of services in them:
 | 
					of init scripts in them:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
# rc-status
 | 
					# rc-status
 | 
				
			||||||
@@ -77,7 +74,7 @@ Runlevel: default
 | 
				
			|||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
All runlevels are represented as folders in `/etc/runlevels/` with symlinks to 
 | 
					All runlevels are represented as folders in `/etc/runlevels/` with symlinks to 
 | 
				
			||||||
the actual service scripts.
 | 
					the actual init scripts.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Calling openrc with an argument (`openrc default`) will switch to that
 | 
					Calling openrc with an argument (`openrc default`) will switch to that
 | 
				
			||||||
runlevel; this will start and stop services as needed.
 | 
					runlevel; this will start and stop services as needed.
 | 
				
			||||||
@@ -86,13 +83,122 @@ Managing runlevels is usually done through the `rc-update` helper, but could of
 | 
				
			|||||||
course be done by hand if desired.
 | 
					course be done by hand if desired.
 | 
				
			||||||
e.g. `rc-update add nginx default` - add nginx to the default runlevel
 | 
					e.g. `rc-update add nginx default` - add nginx to the default runlevel
 | 
				
			||||||
Note: This will not auto-start nginx! You'd still have to trigger `rc` or run 
 | 
					Note: This will not auto-start nginx! You'd still have to trigger `rc` or run 
 | 
				
			||||||
the service script by hand.
 | 
					the initscript by hand.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
FIXME: Document stacked runlevels
 | 
					FIXME: Document stacked runlevels
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The default startup uses the runlevels `boot`, `sysinit` and `default`, in that 
 | 
					The default startup uses the runlevels `boot`, `sysinit` and `default`, in that 
 | 
				
			||||||
order. Shutdown uses the `shutdown` runlevel.
 | 
					order. Shutdown uses the `shutdown` runlevel.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Syntax of Service Scripts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Service scripts are shell scripts. OpenRC aims at using only the standardized 
 | 
				
			||||||
 | 
					POSIX sh subset for portability reasons. The default interpreter (build-time 
 | 
				
			||||||
 | 
					toggle) is `/bin/sh`, so using for example mksh is not a problem.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OpenRC has been tested with busybox sh, ash, dash, bash, mksh, zsh and possibly 
 | 
				
			||||||
 | 
					others. Using busybox sh has been difficult as it replaces commands with 
 | 
				
			||||||
 | 
					builtins that don't offer the expected features.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The interpreter for initscripts is `#!/sbin/openrc-run`.
 | 
				
			||||||
 | 
					Not using this interpreter will break the use of dependencies and is not 
 | 
				
			||||||
 | 
					supported. (iow: if you insist on using `#!/bin/sh` you're on your own)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					A `depend` function declares the dependencies of this service script.
 | 
				
			||||||
 | 
					All scripts must have start/stop/status functions, but defaults are provided.
 | 
				
			||||||
 | 
					Extra functions can be added easily:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					extra_commands="checkconfig"
 | 
				
			||||||
 | 
					checkconfig() {
 | 
				
			||||||
 | 
						doSomething
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This exports the checkconfig function so that `/etc/init.d/someservice 
 | 
				
			||||||
 | 
					checkconfig` will be available, and it "just" runs this function.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					While commands defined in `extra_commands` are always available, commands
 | 
				
			||||||
 | 
					defined in `extra_started_commands` will only work when the service is started
 | 
				
			||||||
 | 
					and those defined in `extra_stopped_commands` will only work when the service is
 | 
				
			||||||
 | 
					stopped. This can be used for implementing graceful reload and similar
 | 
				
			||||||
 | 
					behaviour.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Adding a restart function will not work, this is a design decision within 
 | 
				
			||||||
 | 
					OpenRC. Since there may be dependencies involved (e.g. network -> apache) a 
 | 
				
			||||||
 | 
					restart function is in general not going to work. 
 | 
				
			||||||
 | 
					restart is internally mapped to `stop()` + `start()` (plus handling dependencies).
 | 
				
			||||||
 | 
					If a service needs to behave differently when it is being restarted vs
 | 
				
			||||||
 | 
					started or stopped, it should test the `$RC_CMD` variable, for example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					[ "$RC_CMD" = restart ] && do_something
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# The Depend Function
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This function declares the dependencies for a service script. This
 | 
				
			||||||
 | 
					determines the order the service scripts start.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					depend() {
 | 
				
			||||||
 | 
						need net
 | 
				
			||||||
 | 
						use dns logger netmount
 | 
				
			||||||
 | 
						want coolservice
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`need` declares a hard dependency - net always needs to be started before this 
 | 
				
			||||||
 | 
						service does
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`use` is a soft dependency - if dns, logger or netmount is in this runlevel 
 | 
				
			||||||
 | 
						start it before, but we don't care if it's not in this runlevel.
 | 
				
			||||||
 | 
						`want` is between need and use - try to start coolservice if it is
 | 
				
			||||||
 | 
						installed on the system, regardless of whether it is in the
 | 
				
			||||||
 | 
						runlevel, but we don't care if it starts.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`before` declares that we need to be started before another service
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`after` declares that we need to be started after another service, without 
 | 
				
			||||||
 | 
						creating a dependency (so on calling stop the two are independent)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`provide` allows multiple implementations to provide one service type, e.g.:
 | 
				
			||||||
 | 
						`provide cron` is set in all cron-daemons, so any one of them started 
 | 
				
			||||||
 | 
						satisfies a cron dependency
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`keyword` allows platform-specific overrides, e.g. `keyword -lxc` makes this 
 | 
				
			||||||
 | 
						service script a noop in lxc containers. Useful for things like keymaps, 
 | 
				
			||||||
 | 
						module loading etc. that are either platform-specific or not available 
 | 
				
			||||||
 | 
						in containers/virtualization/...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FIXME: Anything missing in this list?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# The Default Functions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					All service scripts are assumed to have the following functions:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					start()
 | 
				
			||||||
 | 
					stop()
 | 
				
			||||||
 | 
					status()
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					There are default implementations in `lib/rc/sh/openrc-run.sh` - this allows very 
 | 
				
			||||||
 | 
					compact service scripts. These functions can be overridden per service script as 
 | 
				
			||||||
 | 
					needed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The default functions assume the following variables to be set in the service 
 | 
				
			||||||
 | 
					script:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					command=
 | 
				
			||||||
 | 
					command_args=
 | 
				
			||||||
 | 
					pidfile=
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Thus the 'smallest' service scripts can be half a dozen lines long
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# The Magic of `conf.d`
 | 
					# The Magic of `conf.d`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Most service scripts need default values. It would be fragile to
 | 
					Most service scripts need default values. It would be fragile to
 | 
				
			||||||
@@ -111,7 +217,7 @@ start() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The big advantage of this split is that most of the time editing of the service 
 | 
					The big advantage of this split is that most of the time editing of the init 
 | 
				
			||||||
script can be avoided.
 | 
					script can be avoided.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Start-Stop-Daemon
 | 
					# Start-Stop-Daemon
 | 
				
			||||||
@@ -165,7 +271,7 @@ happen automatically when the service is stopped.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# Caching
 | 
					# Caching
 | 
				
			||||||
 | 
					
 | 
				
			||||||
For performance reasons OpenRC keeps a cache of pre-parsed service metadata
 | 
					For performance reasons OpenRC keeps a cache of pre-parsed initscript metadata
 | 
				
			||||||
(e.g. `depend`). The default location for this is `/${RC_SVCDIR}/cache`.
 | 
					(e.g. `depend`). The default location for this is `/${RC_SVCDIR}/cache`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The cache uses `mtime` to check for file staleness. Should any service script
 | 
					The cache uses `mtime` to check for file staleness. Should any service script
 | 
				
			||||||
@@ -175,5 +281,5 @@ change it'll re-source the relevant files and update the cache
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
OpenRC has wrappers for many common output tasks in libeinfo.
 | 
					OpenRC has wrappers for many common output tasks in libeinfo.
 | 
				
			||||||
This allows to print colour-coded status notices and other things.
 | 
					This allows to print colour-coded status notices and other things.
 | 
				
			||||||
To make the output consistent the bundled service scripts all use ebegin/eend to 
 | 
					To make the output consistent the bundled initscripts all use ebegin/eend to 
 | 
				
			||||||
print nice messages.
 | 
					print nice messages.
 | 
				
			||||||
							
								
								
									
										1
									
								
								init.d/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								init.d/.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,6 +1,5 @@
 | 
				
			|||||||
agetty
 | 
					agetty
 | 
				
			||||||
binfmt
 | 
					binfmt
 | 
				
			||||||
cgroups
 | 
					 | 
				
			||||||
modules-load
 | 
					modules-load
 | 
				
			||||||
bootmisc
 | 
					bootmisc
 | 
				
			||||||
fsck
 | 
					fsck
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,10 +21,9 @@ SRCS-FreeBSD=	hostid.in modules.in moused.in newsyslog.in pf.in rarpd.in \
 | 
				
			|||||||
SRCS-FreeBSD+=	adjkerntz.in devd.in dumpon.in encswap.in ipfw.in \
 | 
					SRCS-FreeBSD+=	adjkerntz.in devd.in dumpon.in encswap.in ipfw.in \
 | 
				
			||||||
		modules-load.in mixer.in nscd.in powerd.in syscons.in
 | 
							modules-load.in mixer.in nscd.in powerd.in syscons.in
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SRCS-Linux=	agetty.in binfmt.in devfs.in cgroups.in dmesg.in hwclock.in \
 | 
					SRCS-Linux=	agetty.in binfmt.in devfs.in dmesg.in hwclock.in consolefont.in \
 | 
				
			||||||
	consolefont.in keymaps.in killprocs.in modules.in modules-load.in \
 | 
						keymaps.in killprocs.in modules.in modules-load.in mount-ro.in mtab.in \
 | 
				
			||||||
	mount-ro.in mtab.in numlock.in procfs.in net-online.in sysfs.in \
 | 
						numlock.in procfs.in net-online.in sysfs.in termencoding.in
 | 
				
			||||||
termencoding.in
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Generic BSD scripts
 | 
					# Generic BSD scripts
 | 
				
			||||||
SRCS-NetBSD=	hostid.in moused.in newsyslog.in pf.in rarpd.in rc-enabled.in \
 | 
					SRCS-NetBSD=	hostid.in moused.in newsyslog.in pf.in rarpd.in rc-enabled.in \
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,6 +16,7 @@ term_type="${term_type:-linux}"
 | 
				
			|||||||
command=/sbin/agetty
 | 
					command=/sbin/agetty
 | 
				
			||||||
command_args_foreground="${agetty_options} ${port} ${baud} ${term_type}"
 | 
					command_args_foreground="${agetty_options} ${port} ${baud} ${term_type}"
 | 
				
			||||||
pidfile="/run/${RC_SVCNAME}.pid"
 | 
					pidfile="/run/${RC_SVCNAME}.pid"
 | 
				
			||||||
 | 
					export EINFO_QUIET="${quiet:-yes}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
depend() {
 | 
					depend() {
 | 
				
			||||||
	after local
 | 
						after local
 | 
				
			||||||
@@ -28,12 +29,5 @@ start_pre() {
 | 
				
			|||||||
		eerror "symbolic links to it for the ports you want to start"
 | 
							eerror "symbolic links to it for the ports you want to start"
 | 
				
			||||||
		eerror "agetty on and add those to the appropriate runlevels."
 | 
							eerror "agetty on and add those to the appropriate runlevels."
 | 
				
			||||||
		return 1
 | 
							return 1
 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		export EINFO_QUIET="${quiet:-yes}"
 | 
					 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
stop_pre()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	export EINFO_QUIET="${quiet:-yes}"
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,149 +0,0 @@
 | 
				
			|||||||
#!@SBINDIR@/openrc-run
 | 
					 | 
				
			||||||
# Copyright (c) 2017 The OpenRC Authors.
 | 
					 | 
				
			||||||
# See the Authors file at the top-level directory of this distribution and
 | 
					 | 
				
			||||||
# https://github.com/OpenRC/openrc/blob/master/AUTHORS
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# This file is part of OpenRC. It is subject to the license terms in
 | 
					 | 
				
			||||||
# the LICENSE file found in the top-level directory of this
 | 
					 | 
				
			||||||
# distribution and at https://github.com/OpenRC/openrc/blob/master/LICENSE
 | 
					 | 
				
			||||||
# This file may not be copied, modified, propagated, or distributed
 | 
					 | 
				
			||||||
# except according to the terms contained in the LICENSE file.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
description="Mount the control groups."
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
cgroup_opts=nodev,noexec,nosuid
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
depend()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	keyword -docker -prefix -systemd-nspawn -vserver
 | 
					 | 
				
			||||||
	after sysfs
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
cgroup1_base()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	grep -qw cgroup /proc/filesystems || return 0
 | 
					 | 
				
			||||||
	if ! mountinfo -q /sys/fs/cgroup; then
 | 
					 | 
				
			||||||
		ebegin "Mounting cgroup filesystem"
 | 
					 | 
				
			||||||
		local opts="${cgroup_opts},mode=755,size=${rc_cgroupsize:-10m}"
 | 
					 | 
				
			||||||
		mount -n -t tmpfs -o "${opts}" cgroup_root /sys/fs/cgroup
 | 
					 | 
				
			||||||
		eend $?
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ! mountinfo -q /sys/fs/cgroup/openrc; then
 | 
					 | 
				
			||||||
		local agent="${RC_LIBEXECDIR}/sh/cgroup-release-agent.sh"
 | 
					 | 
				
			||||||
		mkdir /sys/fs/cgroup/openrc
 | 
					 | 
				
			||||||
		mount -n -t cgroup \
 | 
					 | 
				
			||||||
			-o none,${cgroup_opts},name=openrc,release_agent="$agent" \
 | 
					 | 
				
			||||||
			openrc /sys/fs/cgroup/openrc
 | 
					 | 
				
			||||||
		printf 1 > /sys/fs/cgroup/openrc/notify_on_release
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
	return 0
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
cgroup1_controllers()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	yesno "${rc_controller_cgroups:-YES}" && [ -e /proc/cgroups ]  &&
 | 
					 | 
				
			||||||
	grep -qw cgroup /proc/filesystems || return 0
 | 
					 | 
				
			||||||
	while read -r name _ _ enabled _; do
 | 
					 | 
				
			||||||
		case "${enabled}" in
 | 
					 | 
				
			||||||
			1)	mountinfo -q "/sys/fs/cgroup/${name}" && continue
 | 
					 | 
				
			||||||
				local x
 | 
					 | 
				
			||||||
				for x in $rc_cgroup_controllers; do
 | 
					 | 
				
			||||||
				[ "${name}" = "blkio" ] && [ "${x}" = "io" ] &&
 | 
					 | 
				
			||||||
					continue 2
 | 
					 | 
				
			||||||
				[ "${name}" = "${x}" ] &&
 | 
					 | 
				
			||||||
				continue 2
 | 
					 | 
				
			||||||
				done
 | 
					 | 
				
			||||||
				mkdir "/sys/fs/cgroup/${name}"
 | 
					 | 
				
			||||||
				mount -n -t cgroup -o "${cgroup_opts},${name}" \
 | 
					 | 
				
			||||||
					"${name}" "/sys/fs/cgroup/${name}"
 | 
					 | 
				
			||||||
				yesno "${rc_cgroup_memory_use_hierarchy:-no}" &&
 | 
					 | 
				
			||||||
					[ "${name}" = memory ] &&
 | 
					 | 
				
			||||||
					echo 1 > /sys/fs/cgroup/memory/memory.use_hierarchy
 | 
					 | 
				
			||||||
				;;
 | 
					 | 
				
			||||||
		esac
 | 
					 | 
				
			||||||
	done < /proc/cgroups
 | 
					 | 
				
			||||||
	return 0
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
cgroup2_base()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	grep -qw cgroup2 /proc/filesystems || return 0
 | 
					 | 
				
			||||||
	local base
 | 
					 | 
				
			||||||
	base="$(cgroup2_find_path)"
 | 
					 | 
				
			||||||
	mkdir -p "${base}"
 | 
					 | 
				
			||||||
	mount -t cgroup2 none -o "${cgroup_opts},nsdelegate" "${base}" 2> /dev/null ||
 | 
					 | 
				
			||||||
		mount -t cgroup2 none -o "${cgroup_opts}" "${base}"
 | 
					 | 
				
			||||||
	return 0
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
cgroup2_controllers()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	grep -qw cgroup2 /proc/filesystems || return 0
 | 
					 | 
				
			||||||
	local active cgroup_path x y
 | 
					 | 
				
			||||||
	cgroup_path="$(cgroup2_find_path)"
 | 
					 | 
				
			||||||
	[ -z "${cgroup_path}" ] && return 0
 | 
					 | 
				
			||||||
	[ -e "${cgroup_path}/cgroup.controllers" ] &&
 | 
					 | 
				
			||||||
	read -r active < "${cgroup_path}/cgroup.controllers"
 | 
					 | 
				
			||||||
	for x in ${rc_cgroup_controllers}; do
 | 
					 | 
				
			||||||
		for y in ${active}; do
 | 
					 | 
				
			||||||
		[ "$x" = "$y" ] &&
 | 
					 | 
				
			||||||
			[ -e "${cgroup_path}/cgroup.subtree_control" ]&&
 | 
					 | 
				
			||||||
			echo "+${x}"  > "${cgroup_path}/cgroup.subtree_control"
 | 
					 | 
				
			||||||
		done
 | 
					 | 
				
			||||||
	done
 | 
					 | 
				
			||||||
	return 0
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
cgroups_hybrid()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	cgroup1_base
 | 
					 | 
				
			||||||
	cgroup2_base
 | 
					 | 
				
			||||||
	cgroup2_controllers
 | 
					 | 
				
			||||||
	cgroup1_controllers
 | 
					 | 
				
			||||||
	return 0
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
cgroups_legacy()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	cgroup1_base
 | 
					 | 
				
			||||||
	cgroup1_controllers
 | 
					 | 
				
			||||||
	return 0
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
cgroups_unified()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	cgroup2_base
 | 
					 | 
				
			||||||
	cgroup2_controllers
 | 
					 | 
				
			||||||
	return 0
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
mount_cgroups()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	case "${rc_cgroup_mode:-hybrid}" in
 | 
					 | 
				
			||||||
	hybrid) cgroups_hybrid ;;
 | 
					 | 
				
			||||||
	legacy) cgroups_legacy ;;
 | 
					 | 
				
			||||||
	unified) cgroups_unified ;;
 | 
					 | 
				
			||||||
	esac
 | 
					 | 
				
			||||||
	return 0
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
restorecon_cgroups()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if [ -x /sbin/restorecon ]; then
 | 
					 | 
				
			||||||
		ebegin "Restoring SELinux contexts in /sys/fs/cgroup"
 | 
					 | 
				
			||||||
		restorecon -rF /sys/fs/cgroup >/dev/null 2>&1
 | 
					 | 
				
			||||||
		eend $?
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
	return 0
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
start()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	# set up kernel support for cgroups
 | 
					 | 
				
			||||||
	if [ -d /sys/fs/cgroup ]; then
 | 
					 | 
				
			||||||
		mount_cgroups
 | 
					 | 
				
			||||||
		restorecon_cgroups
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
	return 0
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -20,12 +20,9 @@ depend()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
mount_dev()
 | 
					mount_dev()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	local action conf_d_dir devfstype msg mountopts
 | 
						local action=--mount devfstype msg=Mounting
 | 
				
			||||||
	action=--mount
 | 
					 | 
				
			||||||
	conf_d_dir="${RC_SERVICE%/*/*}/conf.d"
 | 
					 | 
				
			||||||
	msg=Mounting
 | 
					 | 
				
			||||||
	# Some devices require exec, Bug #92921
 | 
						# Some devices require exec, Bug #92921
 | 
				
			||||||
	mountopts="exec,nosuid,mode=0755"
 | 
						local mountopts="exec,nosuid,mode=0755"
 | 
				
			||||||
	if yesno ${skip_mount_dev:-no} ; then
 | 
						if yesno ${skip_mount_dev:-no} ; then
 | 
				
			||||||
		einfo "/dev will not be mounted due to user request"
 | 
							einfo "/dev will not be mounted due to user request"
 | 
				
			||||||
		return 0
 | 
							return 0
 | 
				
			||||||
@@ -36,7 +33,7 @@ mount_dev()
 | 
				
			|||||||
		msg=Remounting
 | 
							msg=Remounting
 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
	if fstabinfo -q /dev; then
 | 
						if fstabinfo -q /dev; then
 | 
				
			||||||
		ebegin "$msg /dev according to fstab"
 | 
							ebegin "$msg /dev according to @SYSCONFDIR@/fstab"
 | 
				
			||||||
		fstabinfo -q $action /dev
 | 
							fstabinfo -q $action /dev
 | 
				
			||||||
		eend $?
 | 
							eend $?
 | 
				
			||||||
		return 0
 | 
							return 0
 | 
				
			||||||
@@ -57,7 +54,7 @@ mount_dev()
 | 
				
			|||||||
		ewarn "is no entry for /dev in fstab."
 | 
							ewarn "is no entry for /dev in fstab."
 | 
				
			||||||
		ewarn "This means /dev will not be mounted."
 | 
							ewarn "This means /dev will not be mounted."
 | 
				
			||||||
		ewarn "To avoid this message, set CONFIG_DEVTMPFS or CONFIG_TMPFS to y"
 | 
							ewarn "To avoid this message, set CONFIG_DEVTMPFS or CONFIG_TMPFS to y"
 | 
				
			||||||
		ewarn "in your kernel configuration or see ${conf_d_dir}/${RC_SVCNAME}"
 | 
							ewarn "in your kernel configuration or see @SYSCONFDIR@/conf.d/devfs"
 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
	return 0
 | 
						return 0
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,9 +20,9 @@ depend()
 | 
				
			|||||||
start()
 | 
					start()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	local h source x
 | 
						local h source x
 | 
				
			||||||
	if [ -s /etc/hostname ] && [ -r /etc/hostname ]; then
 | 
						if [ -s @SYSCONFDIR@/hostname ] && [ -r @SYSCONFDIR@/hostname ]; then
 | 
				
			||||||
		read h x </etc/hostname
 | 
							read h x <@SYSCONFDIR@/hostname
 | 
				
			||||||
		source="from /etc/hostname"
 | 
							source="from @SYSCONFDIR@/hostname"
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		# HOSTNAME variable used to be defined in caps in conf.d/hostname.
 | 
							# HOSTNAME variable used to be defined in caps in conf.d/hostname.
 | 
				
			||||||
		# It is also a magic variable in bash.
 | 
							# It is also a magic variable in bash.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -105,7 +105,7 @@ start()
 | 
				
			|||||||
			done
 | 
								done
 | 
				
			||||||
			[ -n "$modname" ] &&
 | 
								[ -n "$modname" ] &&
 | 
				
			||||||
				ewarn "The $modname module needs to be configured in" \
 | 
									ewarn "The $modname module needs to be configured in" \
 | 
				
			||||||
					"${RC_SERVICE%/*/*}/conf.d/modules or built in."
 | 
										"@SYSCONFDIR@/conf.d/modules or built in."
 | 
				
			||||||
		fi
 | 
							fi
 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,10 +9,7 @@
 | 
				
			|||||||
# This file may not be copied, modified, propagated, or distributed
 | 
					# This file may not be copied, modified, propagated, or distributed
 | 
				
			||||||
# except according to the terms contained in the LICENSE file.
 | 
					# except according to the terms contained in the LICENSE file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
conf_d_dir="${RC_SERVICE%/*/*}/conf.d"
 | 
					description="Executes user programs in @SYSCONFDIR@/local.d"
 | 
				
			||||||
local_d_dir="${RC_SERVICE%/*/*}/local.d"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
description="Executes user programs in ${local_d_dir}"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
depend()
 | 
					depend()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -22,12 +19,12 @@ depend()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
start()
 | 
					start()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	local file has_errors redirect retval
 | 
					 | 
				
			||||||
	has_errors=0
 | 
					 | 
				
			||||||
	yesno $rc_verbose || redirect='> /dev/null 2>&1'
 | 
					 | 
				
			||||||
	ebegin "Starting local"
 | 
						ebegin "Starting local"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						local file has_errors=0 redirect retval
 | 
				
			||||||
 | 
						yesno $rc_verbose || redirect='> /dev/null 2>&1'
 | 
				
			||||||
	eindent
 | 
						eindent
 | 
				
			||||||
	for file in "${local_d_dir}"/*.start; do
 | 
						for file in @SYSCONFDIR@/local.d/*.start; do
 | 
				
			||||||
		if [ -x "${file}" ]; then
 | 
							if [ -x "${file}" ]; then
 | 
				
			||||||
			vebegin "Executing \"${file}\""
 | 
								vebegin "Executing \"${file}\""
 | 
				
			||||||
			eval "${file}" $redirect
 | 
								eval "${file}" $redirect
 | 
				
			||||||
@@ -41,32 +38,32 @@ start()
 | 
				
			|||||||
	eoutdent
 | 
						eoutdent
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if command -v local_start >/dev/null 2>&1; then
 | 
						if command -v local_start >/dev/null 2>&1; then
 | 
				
			||||||
		ewarn "\"${conf_d_dir}/local\" should be removed."
 | 
							ewarn "\"@SYSCONFDIR@/conf.d/local\" should be removed."
 | 
				
			||||||
		ewarn "Please move the code from the local_start function"
 | 
							ewarn "Please move the code from the local_start function"
 | 
				
			||||||
		ewarn "to executable scripts with an .start extension"
 | 
							ewarn "to executable scripts with an .start extension"
 | 
				
			||||||
		ewarn "in \"${local_d_dir}\""
 | 
							ewarn "in \"@SYSCONFDIR@/local.d\""
 | 
				
			||||||
		local_start
 | 
							local_start
 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	eend ${has_errors}
 | 
						eend ${has_errors}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	# We have to end with a zero exit code, because a failed execution
 | 
						# We have to end with a zero exit code, because a failed execution
 | 
				
			||||||
	# of an executable ${local_d_dir}/*.start file shouldn't result in
 | 
						# of an executable @SYSCONFDIR@/local.d/*.start file shouldn't result in
 | 
				
			||||||
	# marking the local service as failed. Otherwise we are unable to
 | 
						# marking the local service as failed. Otherwise we are unable to
 | 
				
			||||||
	# execute any executable ${local_d_dir}/*.stop file, because a failed
 | 
						# execute any executable @SYSCONFDIR@/local.d/*.stop file, because a failed
 | 
				
			||||||
	# marked service cannot be stopped (and the stop function would
 | 
						# marked service cannot be stopped (and the stop function would
 | 
				
			||||||
	# actually call the executable ${local_d_dir}/*.stop file(s)).
 | 
						# actually call the executable @SYSCONFDIR@/local.d/*.stop file(s)).
 | 
				
			||||||
	return 0
 | 
						return 0
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
stop()
 | 
					stop()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	local file has_errors redirect retval
 | 
					 | 
				
			||||||
	has_errors=0
 | 
					 | 
				
			||||||
	yesno $rc_verbose || redirect='> /dev/null 2>&1'
 | 
					 | 
				
			||||||
	ebegin "Stopping local"
 | 
						ebegin "Stopping local"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						local file has_errors=0 redirect retval
 | 
				
			||||||
 | 
						yesno $rc_verbose || redirect='> /dev/null 2>&1'
 | 
				
			||||||
	eindent
 | 
						eindent
 | 
				
			||||||
	for file in "${local_d_dir}"/*.stop; do
 | 
						for file in @SYSCONFDIR@/local.d/*.stop; do
 | 
				
			||||||
		if [ -x "${file}" ]; then
 | 
							if [ -x "${file}" ]; then
 | 
				
			||||||
			vebegin "Executing \"${file}\""
 | 
								vebegin "Executing \"${file}\""
 | 
				
			||||||
			eval "${file}" $redirect
 | 
								eval "${file}" $redirect
 | 
				
			||||||
@@ -80,16 +77,16 @@ stop()
 | 
				
			|||||||
	eoutdent
 | 
						eoutdent
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if command -v local_stop >/dev/null 2>&1; then
 | 
						if command -v local_stop >/dev/null 2>&1; then
 | 
				
			||||||
		ewarn "\"${conf_d_dir}/local\" should be removed."
 | 
							ewarn "\"@SYSCONFDIR@/conf.d/local\" should be removed."
 | 
				
			||||||
		ewarn "Please move the code from the local_stop function"
 | 
							ewarn "Please move the code from the local_stop function"
 | 
				
			||||||
		ewarn "to executable scripts with an .stop extension"
 | 
							ewarn "to executable scripts with an .stop extension"
 | 
				
			||||||
		ewarn "in \"${local_d_dir}\""
 | 
							ewarn "in \"@SYSCONFDIR@/local.d\""
 | 
				
			||||||
		local_stop
 | 
							local_stop
 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	eend ${has_errors}
 | 
						eend ${has_errors}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	# An executable ${local_d_dir}/*.stop file which failed with a
 | 
						# An executable @SYSCONFDIR@/local.d/*.stop file which failed with a
 | 
				
			||||||
	# non-zero exit status is not a reason to mark this service
 | 
						# non-zero exit status is not a reason to mark this service
 | 
				
			||||||
	# as failed, therefore we have to end with a zero exit code.
 | 
						# as failed, therefore we have to end with a zero exit code.
 | 
				
			||||||
	return 0
 | 
						return 0
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,7 @@ description="Mounts disks and swap according to /etc/fstab."
 | 
				
			|||||||
depend()
 | 
					depend()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	need fsck
 | 
						need fsck
 | 
				
			||||||
	use lvm modules root
 | 
						use lvm modules mtab root
 | 
				
			||||||
	after clock lvm modules root
 | 
						after clock lvm modules root
 | 
				
			||||||
	keyword -docker -jail -lxc -prefix -systemd-nspawn -vserver
 | 
						keyword -docker -jail -lxc -prefix -systemd-nspawn -vserver
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,6 @@ description="Update /etc/mtab to match what the kernel knows about"
 | 
				
			|||||||
depend()
 | 
					depend()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	after clock
 | 
						after clock
 | 
				
			||||||
	before localmount
 | 
					 | 
				
			||||||
	need root
 | 
						need root
 | 
				
			||||||
	keyword -prefix -systemd-nspawn
 | 
						keyword -prefix -systemd-nspawn
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -31,10 +30,6 @@ start()
 | 
				
			|||||||
		einfo "Creating mtab symbolic link"
 | 
							einfo "Creating mtab symbolic link"
 | 
				
			||||||
		ln -snf /proc/self/mounts /etc/mtab
 | 
							ln -snf /proc/self/mounts /etc/mtab
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		ewarn "The ${RC_SVCNAME} service will be removed in the future."
 | 
					 | 
				
			||||||
		ewarn "Please change the mtab_is_file setting to no and run"
 | 
					 | 
				
			||||||
		ewarn "# rc-service mtab restart"
 | 
					 | 
				
			||||||
		ewarn "to create the mtab symbolic link."
 | 
					 | 
				
			||||||
		[ -L /etc/mtab ] && ewarn "Removing /etc/mtab symbolic link"
 | 
							[ -L /etc/mtab ] && ewarn "Removing /etc/mtab symbolic link"
 | 
				
			||||||
		rm -f /etc/mtab
 | 
							rm -f /etc/mtab
 | 
				
			||||||
		einfo "Creating mtab file"
 | 
							einfo "Creating mtab file"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,7 +23,6 @@ get_interfaces()
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	local ifname iftype
 | 
						local ifname iftype
 | 
				
			||||||
	for ifname in /sys/class/net/*; do
 | 
						for ifname in /sys/class/net/*; do
 | 
				
			||||||
		[ -h "${ifname}" ] && continue
 | 
					 | 
				
			||||||
		read iftype < ${ifname}/type
 | 
							read iftype < ${ifname}/type
 | 
				
			||||||
		[ "$iftype" = "1" ] && printf "%s " ${ifname##*/}
 | 
							[ "$iftype" = "1" ] && printf "%s " ${ifname##*/}
 | 
				
			||||||
	done
 | 
						done
 | 
				
			||||||
@@ -32,7 +31,7 @@ get_interfaces()
 | 
				
			|||||||
start ()
 | 
					start ()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	local carriers configured dev gateway ifcount infinite
 | 
						local carriers configured dev gateway ifcount infinite
 | 
				
			||||||
	local carrier operstate rc
 | 
						local rc state x
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ebegin "Checking to see if the network is online"
 | 
						ebegin "Checking to see if the network is online"
 | 
				
			||||||
	rc=0
 | 
						rc=0
 | 
				
			||||||
@@ -45,12 +44,10 @@ start ()
 | 
				
			|||||||
	ifcount=0
 | 
						ifcount=0
 | 
				
			||||||
 	for dev in ${interfaces}; do
 | 
					 	for dev in ${interfaces}; do
 | 
				
			||||||
		: $((ifcount += 1))
 | 
							: $((ifcount += 1))
 | 
				
			||||||
		read carrier < /sys/class/net/$dev/carrier 2> /dev/null ||
 | 
							read x < /sys/class/net/$dev/carrier
 | 
				
			||||||
			carrier=
 | 
							[ $x -eq 1 ] && : $((carriers += 1))
 | 
				
			||||||
		[ "$carrier" = 1 ] && : $((carriers += 1))
 | 
							read x < /sys/class/net/$dev/operstate
 | 
				
			||||||
		read operstate < /sys/class/net/$dev/operstate 2> /dev/null ||
 | 
							[ "$x" = up ] && : $((configured += 1))
 | 
				
			||||||
			operstate=
 | 
					 | 
				
			||||||
		[ "$operstate" = up ] && : $((configured += 1))
 | 
					 | 
				
			||||||
	done
 | 
						done
 | 
				
			||||||
	[ $configured -eq $ifcount ] && [ $carriers -ge 1 ] && break
 | 
						[ $configured -eq $ifcount ] && [ $carriers -ge 1 ] && break
 | 
				
			||||||
	sleep 1
 | 
						sleep 1
 | 
				
			||||||
@@ -64,12 +61,8 @@ start ()
 | 
				
			|||||||
 if [ $rc -eq 0 ] && yesno ${include_ping_test:-no}; then
 | 
					 if [ $rc -eq 0 ] && yesno ${include_ping_test:-no}; then
 | 
				
			||||||
 	ping_test_host="${ping_test_host:-google.com}"
 | 
					 	ping_test_host="${ping_test_host:-google.com}"
 | 
				
			||||||
 	if [ -n "$ping_test_host" ]; then
 | 
					 	if [ -n "$ping_test_host" ]; then
 | 
				
			||||||
		while $infinite || [ $timeout -gt 0 ]; do
 | 
							ping -c 1 $ping_test_host > /dev/null 2>&1
 | 
				
			||||||
			ping -c 1 $ping_test_host > /dev/null 2>&1
 | 
							rc=$?
 | 
				
			||||||
			rc=$?
 | 
					 | 
				
			||||||
			[ $rc -eq 0 ] && break
 | 
					 | 
				
			||||||
			: $((timeout -= 1))
 | 
					 | 
				
			||||||
		done
 | 
					 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
 fi
 | 
					 fi
 | 
				
			||||||
 eend $rc "The network is offline"
 | 
					 eend $rc "The network is offline"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -76,7 +76,7 @@ tentative()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	case "$RC_UNAME" in
 | 
						case "$RC_UNAME" in
 | 
				
			||||||
	Linux)
 | 
						Linux)
 | 
				
			||||||
		[ -n "$(command -v ip)" ] || return 1
 | 
							[ -x /sbin/ip ] || [ -x /bin/ip ] || return 1
 | 
				
			||||||
		[ -n "$(ip -f inet6 addr show tentative)" ]
 | 
							[ -n "$(ip -f inet6 addr show tentative)" ]
 | 
				
			||||||
		;;
 | 
							;;
 | 
				
			||||||
	*)
 | 
						*)
 | 
				
			||||||
@@ -174,7 +174,7 @@ runip()
 | 
				
			|||||||
routeflush()
 | 
					routeflush()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if [ "$RC_UNAME" = Linux ]; then
 | 
						if [ "$RC_UNAME" = Linux ]; then
 | 
				
			||||||
		if [ -n "$(command -v ip)"  ]; then
 | 
							if [ -x /sbin/ip ] || [ -x /bin/ip ]; then
 | 
				
			||||||
			ip route flush scope global
 | 
								ip route flush scope global
 | 
				
			||||||
			ip route delete default 2>/dev/null
 | 
								ip route delete default 2>/dev/null
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
@@ -346,7 +346,7 @@ stop()
 | 
				
			|||||||
		then
 | 
							then
 | 
				
			||||||
			veinfo "$int"
 | 
								veinfo "$int"
 | 
				
			||||||
			runargs /etc/ifdown."$int" "$downcmd"
 | 
								runargs /etc/ifdown."$int" "$downcmd"
 | 
				
			||||||
			if [ -n "$(command -v ip)" ]; then
 | 
								if [ -x /sbin/ip ] || [ -x /bin/ip ]; then
 | 
				
			||||||
				# We need to do this, otherwise we may
 | 
									# We need to do this, otherwise we may
 | 
				
			||||||
				# fail to add things correctly on restart
 | 
									# fail to add things correctly on restart
 | 
				
			||||||
				ip address flush dev "$int" 2>/dev/null
 | 
									ip address flush dev "$int" 2>/dev/null
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,8 +27,8 @@ start()
 | 
				
			|||||||
		[ ! -e /proc/sys/fs/binfmt_misc/register ]; then
 | 
							[ ! -e /proc/sys/fs/binfmt_misc/register ]; then
 | 
				
			||||||
		if ! grep -qs binfmt_misc /proc/filesystems &&
 | 
							if ! grep -qs binfmt_misc /proc/filesystems &&
 | 
				
			||||||
			modprobe -q binfmt-misc; then
 | 
								modprobe -q binfmt-misc; then
 | 
				
			||||||
			ewarn "The binfmt-misc module needs to be loaded by" \
 | 
								ewarn "The binfmt-misc module needs to be configured in" \
 | 
				
			||||||
				"the modules service or built in."
 | 
									"@SYSCONFDIR@/conf.d/modules or built in."
 | 
				
			||||||
		fi
 | 
							fi
 | 
				
			||||||
		if grep -qs binfmt_misc /proc/filesystems; then
 | 
							if grep -qs binfmt_misc /proc/filesystems; then
 | 
				
			||||||
			ebegin "Mounting misc binary format filesystem"
 | 
								ebegin "Mounting misc binary format filesystem"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
depend()
 | 
					depend()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	after clock root
 | 
						after clock
 | 
				
			||||||
	before localmount
 | 
						before localmount
 | 
				
			||||||
	keyword -docker -jail -lxc -openvz -prefix -systemd-nspawn -vserver
 | 
						keyword -docker -jail -lxc -openvz -prefix -systemd-nspawn -vserver
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,7 +21,7 @@ BSD_sysctl()
 | 
				
			|||||||
	[ -e /etc/sysctl.conf ] || return 0
 | 
						[ -e /etc/sysctl.conf ] || return 0
 | 
				
			||||||
	local retval=0 var= comments= conf=
 | 
						local retval=0 var= comments= conf=
 | 
				
			||||||
	eindent
 | 
						eindent
 | 
				
			||||||
	for conf in /etc/sysctl.conf /etc/sysctl.d/*.conf; do
 | 
						for conf in @SYSCONFDIR@/sysctl.conf @SYSCONFDIR@/sysctl.d/*.conf; do
 | 
				
			||||||
		if [ -r "$conf" ]; then
 | 
							if [ -r "$conf" ]; then
 | 
				
			||||||
			vebegin "applying $conf"
 | 
								vebegin "applying $conf"
 | 
				
			||||||
			while read var comments; do
 | 
								while read var comments; do
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										112
									
								
								init.d/sysfs.in
									
									
									
									
									
								
							
							
						
						
									
										112
									
								
								init.d/sysfs.in
									
									
									
									
									
								
							@@ -107,11 +107,122 @@ mount_misc()
 | 
				
			|||||||
	fi
 | 
						fi
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cgroup1_base()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						grep -qw cgroup /proc/filesystems || return 0
 | 
				
			||||||
 | 
						if ! mountinfo -q /sys/fs/cgroup; then
 | 
				
			||||||
 | 
							ebegin "Mounting cgroup filesystem"
 | 
				
			||||||
 | 
							local opts="${sysfs_opts},mode=755,size=${rc_cgroupsize:-10m}"
 | 
				
			||||||
 | 
							mount -n -t tmpfs -o "${opts}" cgroup_root /sys/fs/cgroup
 | 
				
			||||||
 | 
							eend $?
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ! mountinfo -q /sys/fs/cgroup/openrc; then
 | 
				
			||||||
 | 
							local agent="${RC_LIBEXECDIR}/sh/cgroup-release-agent.sh"
 | 
				
			||||||
 | 
							mkdir /sys/fs/cgroup/openrc
 | 
				
			||||||
 | 
							mount -n -t cgroup \
 | 
				
			||||||
 | 
								-o none,${sysfs_opts},name=openrc,release_agent="$agent" \
 | 
				
			||||||
 | 
								openrc /sys/fs/cgroup/openrc
 | 
				
			||||||
 | 
							printf 1 > /sys/fs/cgroup/openrc/notify_on_release
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
 | 
						return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cgroup1_controllers()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						yesno "${rc_controller_cgroups:-YES}" && [ -e /proc/cgroups ] || return 0
 | 
				
			||||||
 | 
						while read -r name _ _ enabled rest; do
 | 
				
			||||||
 | 
							case "${enabled}" in
 | 
				
			||||||
 | 
								1)	mountinfo -q "/sys/fs/cgroup/${name}" && continue
 | 
				
			||||||
 | 
									local x
 | 
				
			||||||
 | 
									for x in $rc_cgroup_controllers; do
 | 
				
			||||||
 | 
									[ "${name}" = "blkio" ] && [ "${x}" = "io" ] &&
 | 
				
			||||||
 | 
										continue 2
 | 
				
			||||||
 | 
									[ "${name}" = "${x}" ] &&
 | 
				
			||||||
 | 
									continue 2
 | 
				
			||||||
 | 
									done
 | 
				
			||||||
 | 
									mkdir "/sys/fs/cgroup/${name}"
 | 
				
			||||||
 | 
									mount -n -t cgroup -o "${sysfs_opts},${name}" \
 | 
				
			||||||
 | 
										"${name}" "/sys/fs/cgroup/${name}"
 | 
				
			||||||
 | 
									;;
 | 
				
			||||||
 | 
							esac
 | 
				
			||||||
 | 
						done < /proc/cgroups
 | 
				
			||||||
 | 
						return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cgroup2_base()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						local base
 | 
				
			||||||
 | 
						base="$(cgroup2_find_path)"
 | 
				
			||||||
 | 
						mkdir -p "${base}"
 | 
				
			||||||
 | 
						mount -t cgroup2 none -o "${sysfs_opts},nsdelegate" "${base}" 2> /dev/null ||
 | 
				
			||||||
 | 
							mount -t cgroup2 none -o "${sysfs_opts}" "${base}"
 | 
				
			||||||
 | 
						return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cgroup2_controllers()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						local active cgroup_path x y
 | 
				
			||||||
 | 
						cgroup_path="$(cgroup2_find_path)"
 | 
				
			||||||
 | 
						[ -z "${cgroup_path}" ] && return 0
 | 
				
			||||||
 | 
						[ -e "${cgroup_path}/cgroup.controllers" ] &&
 | 
				
			||||||
 | 
						read -r active < "${cgroup_path}/cgroup.controllers"
 | 
				
			||||||
 | 
						for x in ${rc_cgroup_controllers}; do
 | 
				
			||||||
 | 
							for y in ${active}; do
 | 
				
			||||||
 | 
							[ "$x" = "$y" ] &&
 | 
				
			||||||
 | 
								[ -e "${cgroup_path}/cgroup.subtree_control" ]&&
 | 
				
			||||||
 | 
								echo "+${x}"  > "${cgroup_path}/cgroup.subtree_control"
 | 
				
			||||||
 | 
							done
 | 
				
			||||||
 | 
						done
 | 
				
			||||||
 | 
						return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cgroups_hybrid()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						grep -qw cgroup /proc/filesystems || return 0
 | 
				
			||||||
 | 
						cgroup1_base
 | 
				
			||||||
 | 
						if grep -qw cgroup2 /proc/filesystems; then
 | 
				
			||||||
 | 
							cgroup2_base
 | 
				
			||||||
 | 
							cgroup2_controllers
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
 | 
						cgroup1_controllers
 | 
				
			||||||
 | 
						return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cgroups_legacy()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						grep -qw cgroup /proc/filesystems || return 0
 | 
				
			||||||
 | 
						cgroup1_base
 | 
				
			||||||
 | 
						cgroup1_controllers
 | 
				
			||||||
 | 
						return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cgroups_unified()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						cgroup2_base
 | 
				
			||||||
 | 
						cgroup2_controllers
 | 
				
			||||||
 | 
						return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					mount_cgroups()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						# set up kernel support for cgroups
 | 
				
			||||||
 | 
						if [ -d /sys/fs/cgroup ]; then
 | 
				
			||||||
 | 
							case "${rc_cgroup_mode:-hybrid}" in
 | 
				
			||||||
 | 
							hybrid) cgroups_hybrid ;;
 | 
				
			||||||
 | 
							legacy) cgroups_legacy ;;
 | 
				
			||||||
 | 
							unified) cgroups_unified ;;
 | 
				
			||||||
 | 
							esac
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
 | 
						return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
restorecon_sys()
 | 
					restorecon_sys()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if [ -x /sbin/restorecon ]; then
 | 
						if [ -x /sbin/restorecon ]; then
 | 
				
			||||||
		ebegin "Restoring SELinux contexts in /sys"
 | 
							ebegin "Restoring SELinux contexts in /sys"
 | 
				
			||||||
		restorecon -F /sys/devices/system/cpu/online >/dev/null 2>&1
 | 
							restorecon -F /sys/devices/system/cpu/online >/dev/null 2>&1
 | 
				
			||||||
 | 
							restorecon -rF /sys/fs/cgroup >/dev/null 2>&1
 | 
				
			||||||
		eend $?
 | 
							eend $?
 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -120,6 +231,7 @@ start()
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	mount_sys
 | 
						mount_sys
 | 
				
			||||||
	mount_misc
 | 
						mount_misc
 | 
				
			||||||
 | 
						mount_cgroups
 | 
				
			||||||
	restorecon_sys
 | 
						restorecon_sys
 | 
				
			||||||
	return 0
 | 
						return 0
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,7 @@
 | 
				
			|||||||
.\" This file may not be copied, modified, propagated, or distributed
 | 
					.\" This file may not be copied, modified, propagated, or distributed
 | 
				
			||||||
.\"    except according to the terms contained in the LICENSE file.
 | 
					.\"    except according to the terms contained in the LICENSE file.
 | 
				
			||||||
.\"
 | 
					.\"
 | 
				
			||||||
.Dd November 30, 2017
 | 
					.Dd December 31, 2011
 | 
				
			||||||
.Dt openrc-run 8 SMM
 | 
					.Dt openrc-run 8 SMM
 | 
				
			||||||
.Os OpenRC
 | 
					.Os OpenRC
 | 
				
			||||||
.Sh NAME
 | 
					.Sh NAME
 | 
				
			||||||
@@ -142,39 +142,21 @@ List of arguments to pass to the daemon when starting via
 | 
				
			|||||||
.Nm supervise-daemon .
 | 
					.Nm supervise-daemon .
 | 
				
			||||||
to force the daemon to stay in the foreground
 | 
					to force the daemon to stay in the foreground
 | 
				
			||||||
.It Ar command_background
 | 
					.It Ar command_background
 | 
				
			||||||
Set this to "true", "yes" or "1" (case-insensitive) if you want
 | 
					Set this to "true", "yes" or "1" (case-insensitive) if you want 
 | 
				
			||||||
.Xr start-stop-daemon 8
 | 
					.Xr start-stop-daemon 8
 | 
				
			||||||
to force the daemon into the background. This forces the
 | 
					to force the daemon into the background. This forces the
 | 
				
			||||||
"--make-pidfile" and "--pidfile" options, so the pidfile variable must be set.
 | 
					"--make-pidfile" and "--pidfile" options, so the pidfile variable must be set.
 | 
				
			||||||
.It Ar command_progress
 | 
					.It Ar command_progress
 | 
				
			||||||
Set this to "true", "yes" or "1" (case-insensitive) if you want
 | 
					Set this to "true", "yes" or "1" (case-insensitive) if you want 
 | 
				
			||||||
.Xr start-stop-daemon 8
 | 
					.Xr start-stop-daemon 8
 | 
				
			||||||
to display a progress meter when waiting for a daemon to stop.
 | 
					to display a progress meter when waiting for a daemon to stop.
 | 
				
			||||||
.It Ar command_user
 | 
					.It Ar command_user
 | 
				
			||||||
If the daemon does not support changing to a different user id, you can
 | 
					If the daemon does not support changing to a different user id, you can
 | 
				
			||||||
use this to change the user id, and optionally group id,  before
 | 
					use this to change the user id before
 | 
				
			||||||
.Xr start-stop-daemon 8
 | 
					.Xr start-stop-daemon 8
 | 
				
			||||||
or
 | 
					or
 | 
				
			||||||
.Xr supervise-daemon 8
 | 
					.Xr supervise-daemon 8
 | 
				
			||||||
launches the daemon.
 | 
					launches the daemon
 | 
				
			||||||
.It Ar output_log
 | 
					 | 
				
			||||||
This is the path to a file or named pipe where the standard output from
 | 
					 | 
				
			||||||
the service will be redirected. If you are starting this service with
 | 
					 | 
				
			||||||
.Xr start-stop-daemon 8 ,
 | 
					 | 
				
			||||||
,  you must set
 | 
					 | 
				
			||||||
.Pa command_background
 | 
					 | 
				
			||||||
to true. Keep in mind that this path will be inside the chroot if the
 | 
					 | 
				
			||||||
.Pa chroot
 | 
					 | 
				
			||||||
variable is set.
 | 
					 | 
				
			||||||
.It Ar error_log
 | 
					 | 
				
			||||||
The same thing as
 | 
					 | 
				
			||||||
.Pa output_log
 | 
					 | 
				
			||||||
but for the standard error output.
 | 
					 | 
				
			||||||
.It Ar directory
 | 
					 | 
				
			||||||
.Xr start-stop-daemon 8
 | 
					 | 
				
			||||||
and
 | 
					 | 
				
			||||||
.Xr supervise-daemon 8
 | 
					 | 
				
			||||||
will chdir to this directory before starting the daemon.
 | 
					 | 
				
			||||||
.It Ar chroot
 | 
					.It Ar chroot
 | 
				
			||||||
.Xr start-stop-daemon 8
 | 
					.Xr start-stop-daemon 8
 | 
				
			||||||
and
 | 
					and
 | 
				
			||||||
@@ -219,8 +201,6 @@ used along with in_background_fake to support re-entrant services.
 | 
				
			|||||||
.It Ar in_background_fake
 | 
					.It Ar in_background_fake
 | 
				
			||||||
Space separated list of commands which should always succeed when
 | 
					Space separated list of commands which should always succeed when
 | 
				
			||||||
in_background is yes.
 | 
					in_background is yes.
 | 
				
			||||||
.It Ar umask
 | 
					 | 
				
			||||||
Set the umask of the daemon.
 | 
					 | 
				
			||||||
.Pp
 | 
					.Pp
 | 
				
			||||||
Keep in mind that eval is used to process chroot, command, command_args_*,
 | 
					Keep in mind that eval is used to process chroot, command, command_args_*,
 | 
				
			||||||
command_user, pidfile and procname. This may affect how they are
 | 
					command_user, pidfile and procname. This may affect how they are
 | 
				
			||||||
@@ -470,7 +450,6 @@ Also, the -d, -f or -p options should not be specified along with this option.
 | 
				
			|||||||
.Pp
 | 
					.Pp
 | 
				
			||||||
The -q option suppresses all informational output. If it is specified
 | 
					The -q option suppresses all informational output. If it is specified
 | 
				
			||||||
twice, all error messages are suppressed as well.
 | 
					twice, all error messages are suppressed as well.
 | 
				
			||||||
.It Xo
 | 
					 | 
				
			||||||
.Ic fstabinfo
 | 
					.Ic fstabinfo
 | 
				
			||||||
.Op Fl M , -mount
 | 
					.Op Fl M , -mount
 | 
				
			||||||
.Op Fl R , -remount
 | 
					.Op Fl R , -remount
 | 
				
			||||||
@@ -487,7 +466,6 @@ remounted.
 | 
				
			|||||||
.Pp
 | 
					.Pp
 | 
				
			||||||
The -q option suppresses all informational output. If it is specified
 | 
					The -q option suppresses all informational output. If it is specified
 | 
				
			||||||
twice, all error messages are suppressed as well.
 | 
					twice, all error messages are suppressed as well.
 | 
				
			||||||
.It Xo
 | 
					 | 
				
			||||||
.Ic mountinfo
 | 
					.Ic mountinfo
 | 
				
			||||||
.Op Fl f, -fstype-regex Ar regex
 | 
					.Op Fl f, -fstype-regex Ar regex
 | 
				
			||||||
.Op Fl F, -skip-fstype-regex Ar regex
 | 
					.Op Fl F, -skip-fstype-regex Ar regex
 | 
				
			||||||
@@ -502,7 +480,7 @@ twice, all error messages are suppressed as well.
 | 
				
			|||||||
.Op Fl i, -options
 | 
					.Op Fl i, -options
 | 
				
			||||||
.Op Fl s, -fstype
 | 
					.Op Fl s, -fstype
 | 
				
			||||||
.Op Fl t, -node
 | 
					.Op Fl t, -node
 | 
				
			||||||
.Ar mount1 mount2 ...
 | 
					  .Ar mount1 mount2 ...
 | 
				
			||||||
.Xc
 | 
					.Xc
 | 
				
			||||||
The f, F, n, N, o, O, p, P, e and E options specify what you want to
 | 
					The f, F, n, N, o, O, p, P, e and E options specify what you want to
 | 
				
			||||||
search for or skip in the mounted file systems. The i, s and t options
 | 
					search for or skip in the mounted file systems. The i, s and t options
 | 
				
			||||||
@@ -733,8 +711,6 @@ Users are encouraged to use the is_newer_than function which returns correctly.
 | 
				
			|||||||
.Xr rc_plugin_hook 3 ,
 | 
					.Xr rc_plugin_hook 3 ,
 | 
				
			||||||
.Xr sh 1p ,
 | 
					.Xr sh 1p ,
 | 
				
			||||||
.Xr start-stop-daemon 8 ,
 | 
					.Xr start-stop-daemon 8 ,
 | 
				
			||||||
.Xr supervise-daemon 8 ,
 | 
					 | 
				
			||||||
.Xr uname 1
 | 
					.Xr uname 1
 | 
				
			||||||
.Sh AUTHORS
 | 
					.Sh AUTHORS
 | 
				
			||||||
.An Roy Marples <roy@marples.name>
 | 
					.An Roy Marples <roy@marples.name>
 | 
				
			||||||
.An William Hubbs <w.d.hubbs@gmail.com>
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,10 +16,6 @@
 | 
				
			|||||||
.Nd locate and run an OpenRC service with the given arguments
 | 
					.Nd locate and run an OpenRC service with the given arguments
 | 
				
			||||||
.Sh SYNOPSIS
 | 
					.Sh SYNOPSIS
 | 
				
			||||||
.Nm
 | 
					.Nm
 | 
				
			||||||
.Op Fl c , -ifcrashed
 | 
					 | 
				
			||||||
.Ar service cmd
 | 
					 | 
				
			||||||
.Op Ar ...
 | 
					 | 
				
			||||||
.Nm
 | 
					 | 
				
			||||||
.Op Fl i , -ifexists
 | 
					.Op Fl i , -ifexists
 | 
				
			||||||
.Ar service cmd
 | 
					.Ar service cmd
 | 
				
			||||||
.Op Ar ...
 | 
					.Op Ar ...
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -151,7 +151,6 @@ These options are only used for stopping daemons:
 | 
				
			|||||||
.It Fl R , -retry Ar timeout | Ar signal Ns / Ns Ar timeout
 | 
					.It Fl R , -retry Ar timeout | Ar signal Ns / Ns Ar timeout
 | 
				
			||||||
The retry specification can be either a timeout in seconds or multiple
 | 
					The retry specification can be either a timeout in seconds or multiple
 | 
				
			||||||
signal/timeout pairs (like SIGTERM/5).
 | 
					signal/timeout pairs (like SIGTERM/5).
 | 
				
			||||||
If this option is not given, the default is SIGTERM/5.
 | 
					 | 
				
			||||||
.El
 | 
					.El
 | 
				
			||||||
.Sh ENVIRONMENT
 | 
					.Sh ENVIRONMENT
 | 
				
			||||||
.Va SSD_IONICELEVEL
 | 
					.Va SSD_IONICELEVEL
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -120,7 +120,6 @@ description of --respawn-max for more information.
 | 
				
			|||||||
.It Fl R , -retry Ar timeout | Ar signal Ns / Ns Ar timeout
 | 
					.It Fl R , -retry Ar timeout | Ar signal Ns / Ns Ar timeout
 | 
				
			||||||
The retry specification can be either a timeout in seconds or multiple
 | 
					The retry specification can be either a timeout in seconds or multiple
 | 
				
			||||||
signal/timeout pairs (like SIGTERM/5).
 | 
					signal/timeout pairs (like SIGTERM/5).
 | 
				
			||||||
If this option is not given, the default is SIGTERM/5.
 | 
					 | 
				
			||||||
.It Fl r , -chroot Ar path
 | 
					.It Fl r , -chroot Ar path
 | 
				
			||||||
chroot to this directory before starting the daemon. All other paths, such
 | 
					chroot to this directory before starting the daemon. All other paths, such
 | 
				
			||||||
as the path to the daemon, chdir and pidfile, should be relative to the chroot.
 | 
					as the path to the daemon, chdir and pidfile, should be relative to the chroot.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,5 +11,3 @@
 | 
				
			|||||||
# Generic definitions
 | 
					# Generic definitions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
include ${MK}/os-BSD.mk
 | 
					include ${MK}/os-BSD.mk
 | 
				
			||||||
 | 
					 | 
				
			||||||
CPPFLAGS+=	-D_BSD_SOURCE
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,6 +13,6 @@
 | 
				
			|||||||
SFX=		.GNU-kFreeBSD.in
 | 
					SFX=		.GNU-kFreeBSD.in
 | 
				
			||||||
PKG_PREFIX?=	/usr
 | 
					PKG_PREFIX?=	/usr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CPPFLAGS+=	-D_BSD_SOURCE
 | 
					CPPFLAGS+=	-D_BSD_SOURCE -D_XOPEN_SOURCE=700
 | 
				
			||||||
LIBDL=		-Wl,-Bdynamic -ldl
 | 
					LIBDL=		-Wl,-Bdynamic -ldl
 | 
				
			||||||
LIBKVM?=
 | 
					LIBKVM?=
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,5 +11,5 @@
 | 
				
			|||||||
SFX=		.GNU.in
 | 
					SFX=		.GNU.in
 | 
				
			||||||
PKG_PREFIX?=	/usr
 | 
					PKG_PREFIX?=	/usr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CPPFLAGS+=	-D_DEFAULT_SOURCE -DMAXPATHLEN=4096 -DPATH_MAX=4096
 | 
					CPPFLAGS+=	-D_DEFAULT_SOURCE -D_XOPEN_SOURCE=700 -DMAXPATHLEN=4096 -DPATH_MAX=4096
 | 
				
			||||||
LIBDL=		-Wl,-Bdynamic -ldl
 | 
					LIBDL=		-Wl,-Bdynamic -ldl
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,7 @@
 | 
				
			|||||||
SFX=		.Linux.in
 | 
					SFX=		.Linux.in
 | 
				
			||||||
PKG_PREFIX?=	/usr
 | 
					PKG_PREFIX?=	/usr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CPPFLAGS+=	-D_DEFAULT_SOURCE
 | 
					CPPFLAGS+=	-D_DEFAULT_SOURCE -D_XOPEN_SOURCE=700
 | 
				
			||||||
LIBDL=		-Wl,-Bdynamic -ldl
 | 
					LIBDL=		-Wl,-Bdynamic -ldl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ifeq (${MKSELINUX},yes)
 | 
					ifeq (${MKSELINUX},yes)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -34,7 +34,6 @@ PICFLAG?=		-fPIC
 | 
				
			|||||||
SYSCONFDIR?=		${PREFIX}/etc
 | 
					SYSCONFDIR?=		${PREFIX}/etc
 | 
				
			||||||
INITDIR?=		${SYSCONFDIR}/init.d
 | 
					INITDIR?=		${SYSCONFDIR}/init.d
 | 
				
			||||||
CONFDIR?=		${SYSCONFDIR}/conf.d
 | 
					CONFDIR?=		${SYSCONFDIR}/conf.d
 | 
				
			||||||
CONFMODE?=		0644
 | 
					 | 
				
			||||||
LOCALDIR?=		${SYSCONFDIR}/local.d
 | 
					LOCALDIR?=		${SYSCONFDIR}/local.d
 | 
				
			||||||
SYSCTLDIR?=		${SYSCONFDIR}/sysctl.d
 | 
					SYSCTLDIR?=		${SYSCONFDIR}/sysctl.d
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -60,12 +59,10 @@ MANPREFIX?=		${UPREFIX}/share
 | 
				
			|||||||
MANDIR?=		${MANPREFIX}/man
 | 
					MANDIR?=		${MANPREFIX}/man
 | 
				
			||||||
MANMODE?=		0444
 | 
					MANMODE?=		0444
 | 
				
			||||||
 | 
					
 | 
				
			||||||
BASHCOMPDIR?=		${UPREFIX}/share/bash-completion/completions
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
DATADIR?=		${UPREFIX}/share/openrc
 | 
					DATADIR?=		${UPREFIX}/share/openrc
 | 
				
			||||||
DATAMODE?=		0644
 | 
					DATAMODE?=		0644
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DOCDIR?=		${UPREFIX}/share/doc
 | 
					DOCDIR?=		${UPREFIX}/share/doc
 | 
				
			||||||
DOCMODE?=		0644
 | 
					DOCMODE?=		0644
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ZSHCOMPDIR?=		${UPREFIX}/share/zsh/site-functions
 | 
					CONFMODE?=		0644
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,4 @@
 | 
				
			|||||||
Using runit with OpenRC
 | 
					# Using runit with OpenRC
 | 
				
			||||||
=======================
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Beginning with OpenRC-0.21, we support using runit [1] in place of
 | 
					Beginning with OpenRC-0.21, we support using runit [1] in place of
 | 
				
			||||||
start-stop-daemon for monitoring and restarting daemons.
 | 
					start-stop-daemon for monitoring and restarting daemons.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -38,7 +38,7 @@ BOOT-FreeBSD+=	adjkerntz dumpon syscons
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
BOOT-Linux+=	binfmt hwclock keymaps modules mtab procfs termencoding
 | 
					BOOT-Linux+=	binfmt hwclock keymaps modules mtab procfs termencoding
 | 
				
			||||||
SHUTDOWN-Linux=	killprocs mount-ro
 | 
					SHUTDOWN-Linux=	killprocs mount-ro
 | 
				
			||||||
SYSINIT-Linux=	devfs cgroups dmesg sysfs
 | 
					SYSINIT-Linux=	devfs dmesg sysfs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Generic BSD stuff
 | 
					# Generic BSD stuff
 | 
				
			||||||
BOOT-NetBSD+=	hostid newsyslog savecore syslogd
 | 
					BOOT-NetBSD+=	hostid newsyslog savecore syslogd
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,4 @@
 | 
				
			|||||||
Using S6 with OpenRC
 | 
					# Using S6 with OpenRC
 | 
				
			||||||
====================
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Beginning with OpenRC-0.16, we support using the s6 supervision suite
 | 
					Beginning with OpenRC-0.16, we support using the s6 supervision suite
 | 
				
			||||||
from Skarnet Software in place of start-stop-daemon for monitoring
 | 
					from Skarnet Software in place of start-stop-daemon for monitoring
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,493 +0,0 @@
 | 
				
			|||||||
OpenRC Service Script Writing Guide
 | 
					 | 
				
			||||||
===================================
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This document is aimed at developers or packagers who
 | 
					 | 
				
			||||||
write OpenRC service scripts, either for their own projects, or for
 | 
					 | 
				
			||||||
the packages they maintain. It contains advice, suggestions, tips,
 | 
					 | 
				
			||||||
tricks, hints, and counsel; cautions, warnings, heads-ups,
 | 
					 | 
				
			||||||
admonitions, proscriptions, enjoinders, and reprimands.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
It is intended to prevent common mistakes that are found "in the wild"
 | 
					 | 
				
			||||||
by pointing out those mistakes and suggesting alternatives.  Each
 | 
					 | 
				
			||||||
good/bad thing that you should/not do has a section devoted to it. We
 | 
					 | 
				
			||||||
don't consider anything exotic, and assume that you will use
 | 
					 | 
				
			||||||
start-stop-daemon to manage a fairly typical long-running UNIX
 | 
					 | 
				
			||||||
process.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Syntax of Service Scripts
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Service scripts are shell scripts. OpenRC aims at using only the standardized 
 | 
					 | 
				
			||||||
POSIX sh subset for portability reasons. The default interpreter (build-time 
 | 
					 | 
				
			||||||
toggle) is `/bin/sh`, so using for example mksh is not a problem.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
OpenRC has been tested with busybox sh, ash, dash, bash, mksh, zsh and possibly 
 | 
					 | 
				
			||||||
others. Using busybox sh has been difficult as it replaces commands with 
 | 
					 | 
				
			||||||
builtins that don't offer the expected features.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The interpreter for service scripts is `#!/sbin/openrc-run`.
 | 
					 | 
				
			||||||
Not using this interpreter will break the use of dependencies and is not 
 | 
					 | 
				
			||||||
supported. (iow: if you insist on using `#!/bin/sh` you're on your own)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
A `depend` function declares the dependencies of this service script.
 | 
					 | 
				
			||||||
All scripts must have start/stop/status functions, but defaults are provided and should be used unless you have a very strong reason not to use them.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Extra functions can be added easily:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
extra_commands="checkconfig"
 | 
					 | 
				
			||||||
checkconfig() {
 | 
					 | 
				
			||||||
	doSomething
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This exports the checkconfig function so that `/etc/init.d/someservice 
 | 
					 | 
				
			||||||
checkconfig` will be available, and it "just" runs this function.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
While commands defined in `extra_commands` are always available, commands
 | 
					 | 
				
			||||||
defined in `extra_started_commands` will only work when the service is started
 | 
					 | 
				
			||||||
and those defined in `extra_stopped_commands` will only work when the service is
 | 
					 | 
				
			||||||
stopped. This can be used for implementing graceful reload and similar
 | 
					 | 
				
			||||||
behaviour.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Adding a restart function will not work, this is a design decision within 
 | 
					 | 
				
			||||||
OpenRC. Since there may be dependencies involved (e.g. network -> apache) a 
 | 
					 | 
				
			||||||
restart function is in general not going to work. 
 | 
					 | 
				
			||||||
restart is internally mapped to `stop()` + `start()` (plus handling dependencies).
 | 
					 | 
				
			||||||
If a service needs to behave differently when it is being restarted vs
 | 
					 | 
				
			||||||
started or stopped, it should test the `$RC_CMD` variable, for example:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
[ "$RC_CMD" = restart ] && do_something
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# The Depend Function
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This function declares the dependencies for a service script. This
 | 
					 | 
				
			||||||
determines the order the service scripts start.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
depend() {
 | 
					 | 
				
			||||||
	need net
 | 
					 | 
				
			||||||
	use dns logger netmount
 | 
					 | 
				
			||||||
	want coolservice
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
`need` declares a hard dependency - net always needs to be started before this 
 | 
					 | 
				
			||||||
	service does
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
`use` is a soft dependency - if dns, logger or netmount is in this runlevel 
 | 
					 | 
				
			||||||
	start it before, but we don't care if it's not in this runlevel.
 | 
					 | 
				
			||||||
	`want` is between need and use - try to start coolservice if it is
 | 
					 | 
				
			||||||
	installed on the system, regardless of whether it is in the
 | 
					 | 
				
			||||||
	runlevel, but we don't care if it starts.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
`before` declares that we need to be started before another service
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
`after` declares that we need to be started after another service, without 
 | 
					 | 
				
			||||||
	creating a dependency (so on calling stop the two are independent)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
`provide` allows multiple implementations to provide one service type, e.g.:
 | 
					 | 
				
			||||||
	`provide cron` is set in all cron-daemons, so any one of them started 
 | 
					 | 
				
			||||||
	satisfies a cron dependency
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
`keyword` allows platform-specific overrides, e.g. `keyword -lxc` makes this 
 | 
					 | 
				
			||||||
	service script a noop in lxc containers. Useful for things like keymaps, 
 | 
					 | 
				
			||||||
	module loading etc. that are either platform-specific or not available 
 | 
					 | 
				
			||||||
	in containers/virtualization/...
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
FIXME: Anything missing in this list?
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# The Default Functions
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
All service scripts are assumed to have the following functions:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
start()
 | 
					 | 
				
			||||||
stop()
 | 
					 | 
				
			||||||
status()
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
There are default implementations in `lib/rc/sh/openrc-run.sh` - this allows very 
 | 
					 | 
				
			||||||
compact service scripts. These functions can be overridden per service script as 
 | 
					 | 
				
			||||||
needed.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The default functions assume the following variables to be set in the service 
 | 
					 | 
				
			||||||
script:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
command=
 | 
					 | 
				
			||||||
command_args=
 | 
					 | 
				
			||||||
pidfile=
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Thus the 'smallest' service scripts can be half a dozen lines long
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Don't write your own start/stop functions
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
OpenRC is capable of stopping and starting most daemons based on the
 | 
					 | 
				
			||||||
information that you give it. For a well-behaved daemon that
 | 
					 | 
				
			||||||
backgrounds itself and writes its own PID file by default, the
 | 
					 | 
				
			||||||
following OpenRC variables are likely all that you'll need:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  * command
 | 
					 | 
				
			||||||
  * command_args
 | 
					 | 
				
			||||||
  * pidfile
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Given those three pieces of information, OpenRC will be able to start
 | 
					 | 
				
			||||||
and stop the daemon on its own. The following is taken from an
 | 
					 | 
				
			||||||
[OpenNTPD](http://www.openntpd.org/) service script:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```sh
 | 
					 | 
				
			||||||
command="/usr/sbin/ntpd"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# The special RC_SVCNAME variable contains the name of this service.
 | 
					 | 
				
			||||||
pidfile="/run/${RC_SVCNAME}.pid"
 | 
					 | 
				
			||||||
command_args="-p ${pidfile}"
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If the daemon runs in the foreground by default but has options to
 | 
					 | 
				
			||||||
background itself and to create a pidfile, then you'll also need
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  * command_args_background
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
That variable should contain the flags needed to background your
 | 
					 | 
				
			||||||
daemon, and to make it write a PID file. Take for example the
 | 
					 | 
				
			||||||
following snippet of an
 | 
					 | 
				
			||||||
[NRPE](https://github.com/NagiosEnterprises/nrpe) service script:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```sh
 | 
					 | 
				
			||||||
command="/usr/bin/nrpe"
 | 
					 | 
				
			||||||
command_args="--config=/etc/nagios/nrpe.cfg"
 | 
					 | 
				
			||||||
command_args_background="--daemon"
 | 
					 | 
				
			||||||
pidfile="/run/${RC_SVCNAME}.pid"
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Since NRPE runs as *root* by default, it needs no special permissions
 | 
					 | 
				
			||||||
to write to `/run/nrpe.pid`. OpenRC takes care of starting and
 | 
					 | 
				
			||||||
stopping the daemon with the appropriate arguments, even passing the
 | 
					 | 
				
			||||||
`--daemon` flag during startup to force NRPE into the background (NRPE
 | 
					 | 
				
			||||||
knows how to write its own PID file).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
But what if the daemon isn't so well behaved? What if it doesn't know
 | 
					 | 
				
			||||||
how to background itself or create a pidfile? If it can do neither,
 | 
					 | 
				
			||||||
then use,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  * command_background=true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
which will additionally pass `--make-pidfile` to start-stop-daemon,
 | 
					 | 
				
			||||||
causing it to create the `$pidfile` for you (rather than the daemon
 | 
					 | 
				
			||||||
itself being responsible for creating the PID file).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If your daemon doesn't know how to change its own user or group, then
 | 
					 | 
				
			||||||
you can tell start-stop-daemon to launch it as an unprivileged user
 | 
					 | 
				
			||||||
with
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  * command_user="user:group"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Finally, if your daemon always forks into the background but fails to
 | 
					 | 
				
			||||||
create a PID file, then your only option is to use
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  * procname
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
With `procname`, OpenRC will try to find the running daemon by
 | 
					 | 
				
			||||||
matching the name of its process. That's not so reliable, but daemons
 | 
					 | 
				
			||||||
shouldn't background themselves without creating a PID file in the
 | 
					 | 
				
			||||||
first place. The next example is part of the [CA NetConsole
 | 
					 | 
				
			||||||
Daemon](https://oss.oracle.com/projects/cancd/) service script:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```sh
 | 
					 | 
				
			||||||
command="/usr/sbin/cancd"
 | 
					 | 
				
			||||||
command_args="-p ${CANCD_PORT}
 | 
					 | 
				
			||||||
              -l ${CANCD_LOG_DIR}
 | 
					 | 
				
			||||||
              -o ${CANCD_LOG_FORMAT}"
 | 
					 | 
				
			||||||
command_user="cancd"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# cancd daemonizes itself, but doesn't write a PID file and doesn't
 | 
					 | 
				
			||||||
# have an option to run in the foreground. So, the best we can do
 | 
					 | 
				
			||||||
# is try to match the process name when stopping it.
 | 
					 | 
				
			||||||
procname="cancd"
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
To recap, in order of preference:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  1. If the daemon backgrounds itself and creates its own PID file, use
 | 
					 | 
				
			||||||
     `pidfile`.
 | 
					 | 
				
			||||||
  2. If the daemon does not background itself (or has an option to run
 | 
					 | 
				
			||||||
     in the foreground) and does not create a PID file, then use
 | 
					 | 
				
			||||||
     `command_background=true` and `pidfile`.
 | 
					 | 
				
			||||||
  3. If the daemon backgrounds itself and does not create a PID file,
 | 
					 | 
				
			||||||
     use `procname` instead of `pidfile`. But, if your daemon has the
 | 
					 | 
				
			||||||
     option to run in the foreground, then you should do that instead
 | 
					 | 
				
			||||||
     (that would be the case in the previous item).
 | 
					 | 
				
			||||||
  4. The last case, where the daemon does not background itself but
 | 
					 | 
				
			||||||
     does create a PID file, doesn't make much sense. If there's a way
 | 
					 | 
				
			||||||
     to disable the daemon's PID file (or, to write it straight into the
 | 
					 | 
				
			||||||
     garbage), then do that, and use `command_background=true`.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Reloading your daemon's configuration
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Many daemons will reload their configuration files in response to a
 | 
					 | 
				
			||||||
signal. Suppose your daemon will reload its configuration in response
 | 
					 | 
				
			||||||
to a `SIGHUP`. It's possible to add a new "reload" command to your
 | 
					 | 
				
			||||||
service script that performs this action. First, tell the service
 | 
					 | 
				
			||||||
script about the new command.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```sh
 | 
					 | 
				
			||||||
extra_started_commands="reload"
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
We use `extra_started_commands` as opposed to `extra_commands` because
 | 
					 | 
				
			||||||
the "reload" action is only valid while the daemon is running (that
 | 
					 | 
				
			||||||
is, started). Now, start-stop-daemon can be used to send the signal to
 | 
					 | 
				
			||||||
the appropriate process (assuming you've defined the `pidfile`
 | 
					 | 
				
			||||||
variable elsewhere):
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```sh
 | 
					 | 
				
			||||||
reload() {
 | 
					 | 
				
			||||||
  ebegin "Reloading ${RC_SVCNAME}"
 | 
					 | 
				
			||||||
  start-stop-daemon --signal HUP --pidfile "${pidfile}"
 | 
					 | 
				
			||||||
  eend $?
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Don't restart/reload with a broken config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Often, users will start a daemon, make some configuration change, and
 | 
					 | 
				
			||||||
then attempt to restart the daemon. If the recent configuration change
 | 
					 | 
				
			||||||
contains a mistake, the result will be that the daemon is stopped but
 | 
					 | 
				
			||||||
then cannot be started again (due to the configuration error). It's
 | 
					 | 
				
			||||||
possible to prevent that situation with a function that checks for
 | 
					 | 
				
			||||||
configuration errors, and a combination of the `start_pre` and
 | 
					 | 
				
			||||||
`stop_pre` hooks.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```sh
 | 
					 | 
				
			||||||
checkconfig() {
 | 
					 | 
				
			||||||
  # However you want to check this...
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
start_pre() {
 | 
					 | 
				
			||||||
  # If this isn't a restart, make sure that the user's config isn't
 | 
					 | 
				
			||||||
  # busted before we try to start the daemon (this will produce
 | 
					 | 
				
			||||||
  # better error messages than if we just try to start it blindly).
 | 
					 | 
				
			||||||
  #
 | 
					 | 
				
			||||||
  # If, on the other hand, this *is* a restart, then the stop_pre
 | 
					 | 
				
			||||||
  # action will have ensured that the config is usable and we don't
 | 
					 | 
				
			||||||
  # need to do that again.
 | 
					 | 
				
			||||||
  if [ "${RC_CMD}" != "restart" ] ; then
 | 
					 | 
				
			||||||
    checkconfig || return $?
 | 
					 | 
				
			||||||
  fi
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
stop_pre() {
 | 
					 | 
				
			||||||
  # If this is a restart, check to make sure the user's config
 | 
					 | 
				
			||||||
  # isn't busted before we stop the running daemon.
 | 
					 | 
				
			||||||
  if [ "${RC_CMD}" = "restart" ] ; then
 | 
					 | 
				
			||||||
      checkconfig || return $?
 | 
					 | 
				
			||||||
  fi
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
To prevent a *reload* with a broken config, keep it simple:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```sh
 | 
					 | 
				
			||||||
reload() {
 | 
					 | 
				
			||||||
  checkconfig || return $?
 | 
					 | 
				
			||||||
  ebegin "Reloading ${RC_SVCNAME}"
 | 
					 | 
				
			||||||
  start-stop-daemon --signal HUP --pidfile "${pidfile}"
 | 
					 | 
				
			||||||
  eend $?
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## PID files should be writable only by root
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
PID files must be writable only by *root*, which means additionally
 | 
					 | 
				
			||||||
that they must live in a *root*-owned directory. This directory is
 | 
					 | 
				
			||||||
normally /run under Linux and /var/run under other operating systems.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Some daemons run as an unprivileged user account, and create their PID
 | 
					 | 
				
			||||||
files (as the unprivileged user) in a path like
 | 
					 | 
				
			||||||
`/var/run/foo/foo.pid`. That can usually be exploited by the unprivileged
 | 
					 | 
				
			||||||
user to kill *root* processes, since when a service is stopped, *root*
 | 
					 | 
				
			||||||
usually sends a SIGTERM to the contents of the PID file (which are
 | 
					 | 
				
			||||||
controlled by the unprivileged user). The main warning sign for that
 | 
					 | 
				
			||||||
problem is using `checkpath` to set ownership on the directory
 | 
					 | 
				
			||||||
containing the PID file. For example,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```sh
 | 
					 | 
				
			||||||
# BAD BAD BAD BAD BAD BAD BAD BAD
 | 
					 | 
				
			||||||
start_pre() {
 | 
					 | 
				
			||||||
  # Ensure that the pidfile directory is writable by the foo user/group.
 | 
					 | 
				
			||||||
  checkpath --directory --mode 0700 --owner foo:foo "/var/run/foo"
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
# BAD BAD BAD BAD BAD BAD BAD BAD
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If the *foo* user owns `/var/run/foo`, then he can put whatever he wants
 | 
					 | 
				
			||||||
in the `/var/run/foo/foo.pid` file. Even if *root* owns the PID file, the
 | 
					 | 
				
			||||||
*foo* user can delete it and replace it with his own. To avoid
 | 
					 | 
				
			||||||
security concerns, the PID file must be created as *root* and live in
 | 
					 | 
				
			||||||
a *root*-owned directory. If your daemon is responsible for forking
 | 
					 | 
				
			||||||
and writing its own PID file but the PID file is still owned by the
 | 
					 | 
				
			||||||
unprivileged runtime user, then you may have an upstream issue.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Once the PID file is being created as *root* (before dropping
 | 
					 | 
				
			||||||
privileges), it can be written directly to a *root*-owned
 | 
					 | 
				
			||||||
directory.  For example, the *foo* daemon might write
 | 
					 | 
				
			||||||
`/var/run/foo.pid`. No calls to checkpath are needed. Note: there is
 | 
					 | 
				
			||||||
nothing technically wrong with using a directory structure like
 | 
					 | 
				
			||||||
`/var/run/foo/foo.pid`, so long as *root* owns the PID file and the
 | 
					 | 
				
			||||||
directory containing it.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Ideally (see "Upstream your service scripts"), your service script
 | 
					 | 
				
			||||||
will be integrated upstream and the build system will determine the
 | 
					 | 
				
			||||||
appropriate directory for the pid file. For example,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```sh
 | 
					 | 
				
			||||||
pidfile="@piddir@/${RC_SVCNAME}.pid"
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
A decent example of this is the [Nagios core service
 | 
					 | 
				
			||||||
script](https://github.com/NagiosEnterprises/nagioscore/blob/master/openrc-init.in),
 | 
					 | 
				
			||||||
where the full path to the PID file is specified at build-time.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Don't let the user control the PID file location
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
It's usually a mistake to let the end user control the PID file
 | 
					 | 
				
			||||||
location through a conf.d variable, for a few reasons:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  1. When the PID file path is controlled by the user, you need to
 | 
					 | 
				
			||||||
     ensure that its parent directory exists and is writable. This
 | 
					 | 
				
			||||||
     adds unnecessary code to the service script.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  2. If the PID file path changes while the service is running, then
 | 
					 | 
				
			||||||
     you'll find yourself unable to stop the service.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  3. The directory that should contain the PID file is best determined
 | 
					 | 
				
			||||||
     by the upstream build system (see "Upstream your service scripts").
 | 
					 | 
				
			||||||
     On Linux, the preferred location these days is `/run`. Other systems
 | 
					 | 
				
			||||||
     still use `/var/run`, though, and a `./configure` script is the
 | 
					 | 
				
			||||||
     best place to decide which one you want.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  4. Nobody cares where the PID file is located, anyway.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Since OpenRC service names must be unique, a value of
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```sh
 | 
					 | 
				
			||||||
pidfile="/var/run/${RC_SVCNAME}.pid"
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
guarantees that your PID file has a unique name.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Upstream your service scripts (for packagers)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The ideal place for an OpenRC service script is **upstream**. Much like
 | 
					 | 
				
			||||||
systemd services, a well-crafted OpenRC service script should be
 | 
					 | 
				
			||||||
distribution-agnostic, and the best place for it is upstream. Why? For
 | 
					 | 
				
			||||||
two reasons. First, having it upstream means that there's a single
 | 
					 | 
				
			||||||
authoritative source for improvements. Second, a few paths in every
 | 
					 | 
				
			||||||
service script are dependent upon flags passed to the build system. For
 | 
					 | 
				
			||||||
example,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```sh
 | 
					 | 
				
			||||||
command=/usr/bin/foo
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
in an autotools-based build system should really be
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```sh
 | 
					 | 
				
			||||||
command=@bindir@/foo
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
so that the user's value of `--bindir` is respected. If you keep the
 | 
					 | 
				
			||||||
service script in your own distribution's repository, then you have to
 | 
					 | 
				
			||||||
keep the command path and package synchronized yourself, and that's no
 | 
					 | 
				
			||||||
fun.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Be wary of "need net" dependencies
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
There are two things you need to know about "need net" dependencies:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  1. They are not satisfied by the loopback interface, so "need net"
 | 
					 | 
				
			||||||
     requires some *other* interface to be up.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  2. Depending on the value of `rc_depend_strict` in `rc.conf`, the
 | 
					 | 
				
			||||||
     "need net" will be satisfied when either *any* non-loopback
 | 
					 | 
				
			||||||
     interface is up, or when *all* non-loopback interfaces are up.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The first item means that "need net" is wrong for daemons that are
 | 
					 | 
				
			||||||
happy with `0.0.0.0`, and the second point means that "need net" is
 | 
					 | 
				
			||||||
wrong for daemons that need a particular (for example, the WAN)
 | 
					 | 
				
			||||||
interface. We'll consider the two most common users of "need net";
 | 
					 | 
				
			||||||
network clients who access some network resource, and network servers
 | 
					 | 
				
			||||||
who provide them.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Network clients
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Network clients typically want the WAN interface to be up. That may
 | 
					 | 
				
			||||||
tempt you to depend on the WAN interface; but first, you should ask
 | 
					 | 
				
			||||||
yourself a question: does anything bad happen if the WAN interface is
 | 
					 | 
				
			||||||
not available? In other words, if the administrator wants to disable
 | 
					 | 
				
			||||||
the WAN, should the service be stopped? Usually the answer to that
 | 
					 | 
				
			||||||
question is "no," and in that case, you should forego the "net"
 | 
					 | 
				
			||||||
dependency entirely.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Suppose, for example, that your service retrieves virus signature
 | 
					 | 
				
			||||||
updates from the internet. In order to do its job correctly, it needs
 | 
					 | 
				
			||||||
a (working) internet connection. However, the service itself does not
 | 
					 | 
				
			||||||
require the WAN interface to be up: if it is, great; otherwise, the
 | 
					 | 
				
			||||||
worst that will happen is that a "server unavailable" warning will be
 | 
					 | 
				
			||||||
logged. The signature update service will not crash, and—perhaps more
 | 
					 | 
				
			||||||
importantly—you don't want it to terminate if the administrator turns
 | 
					 | 
				
			||||||
off the WAN interface for a second.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Network servers
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Network servers are generally easier to handle than their client
 | 
					 | 
				
			||||||
counterparts. Most server daemons listen on `0.0.0.0` (all addresses)
 | 
					 | 
				
			||||||
by default, and are therefore satisfied to have the loopback interface
 | 
					 | 
				
			||||||
present and operational. OpenRC ships with the loopback service in the
 | 
					 | 
				
			||||||
*boot* runlevel, and therefore most server daemons require no further
 | 
					 | 
				
			||||||
network dependencies.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The exceptions to this rule are those daemons who produce negative
 | 
					 | 
				
			||||||
side-effects when the WAN is unavailable. For example, the Nagios
 | 
					 | 
				
			||||||
server daemon will generate "the sky is falling" alerts for as long as
 | 
					 | 
				
			||||||
your monitored hosts are unreachable. So in that case, you should
 | 
					 | 
				
			||||||
require some other interface (often the WAN) to be up. A "need"
 | 
					 | 
				
			||||||
dependency would be appropriate, because you want Nagios to be
 | 
					 | 
				
			||||||
stopped before the network is taken down.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If your daemon can optionally be configured to listen on a particular
 | 
					 | 
				
			||||||
interface, then please see the "Depending on a particular interface"
 | 
					 | 
				
			||||||
section.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Depending on a particular interface
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If you need to depend on one particular interface, usually it's not
 | 
					 | 
				
			||||||
easy to determine programmatically what that interface is. For
 | 
					 | 
				
			||||||
example, if your *sshd* daemon listens on `192.168.1.100` (rather than
 | 
					 | 
				
			||||||
`0.0.0.0`), then you have two problems:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  1. Parsing `sshd_config` to figure that out; and
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  2. Determining which network service name corresponds to the
 | 
					 | 
				
			||||||
     interface for `192.168.1.100`.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
It's generally a bad idea to parse config files in your service
 | 
					 | 
				
			||||||
scripts, but the second problem is the harder one. Instead, the most
 | 
					 | 
				
			||||||
robust (i.e. the laziest) approach is to make the user specify the
 | 
					 | 
				
			||||||
dependency when he makes a change to sshd_config. Include something
 | 
					 | 
				
			||||||
like the following in the service configuration file,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```sh
 | 
					 | 
				
			||||||
# Specify the network service that corresponds to the "bind" setting
 | 
					 | 
				
			||||||
# in your configuration file. For example, if you bind to 127.0.0.1,
 | 
					 | 
				
			||||||
# this should be set to "loopback" which provides the loopback interface.
 | 
					 | 
				
			||||||
rc_need="loopback"
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This is a sensible default for daemons that are happy with `0.0.0.0`,
 | 
					 | 
				
			||||||
but lets the user specify something else, like `rc_need="net.wan"` if
 | 
					 | 
				
			||||||
he needs it. The burden is on the user to determine the appropriate
 | 
					 | 
				
			||||||
service whenever he changes the daemon's configuration file.
 | 
					 | 
				
			||||||
@@ -33,9 +33,6 @@ else
 | 
				
			|||||||
	kmode="-a"
 | 
						kmode="-a"
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Set the SELinux label on console before everything so we dont lose output
 | 
					 | 
				
			||||||
[ -x /sbin/restorecon ] && /sbin/restorecon -F /dev/console
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Try and set a font and as early as we can
 | 
					# Try and set a font and as early as we can
 | 
				
			||||||
if service_present "$RC_DEFAULTLEVEL" consolefont ||
 | 
					if service_present "$RC_DEFAULTLEVEL" consolefont ||
 | 
				
			||||||
   service_present "$RC_BOOTLEVEL" consolefont; then
 | 
					   service_present "$RC_BOOTLEVEL" consolefont; then
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -83,7 +83,6 @@ elif ! mountinfo -q /run; then
 | 
				
			|||||||
	fi
 | 
						fi
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[ -x /sbin/restorecon ] && /sbin/restorecon -rF /run
 | 
					 | 
				
			||||||
checkpath -d $RC_SVCDIR
 | 
					checkpath -d $RC_SVCDIR
 | 
				
			||||||
checkpath -d -m 0775 -o root:uucp /run/lock
 | 
					checkpath -d -m 0775 -o root:uucp /run/lock
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -260,14 +260,12 @@ for _cmd; do
 | 
				
			|||||||
		# Apply cgroups settings if defined
 | 
							# Apply cgroups settings if defined
 | 
				
			||||||
		if [ "$(command -v cgroup_add_service)" = "cgroup_add_service" ]
 | 
							if [ "$(command -v cgroup_add_service)" = "cgroup_add_service" ]
 | 
				
			||||||
		then
 | 
							then
 | 
				
			||||||
			if grep -qs /sys/fs/cgroup /proc/1/mountinfo
 | 
								if [ -d /sys/fs/cgroup -a ! -w /sys/fs/cgroup ]; then
 | 
				
			||||||
			then
 | 
									eerror "No permission to apply cgroup settings"
 | 
				
			||||||
				if [ -d /sys/fs/cgroup -a ! -w /sys/fs/cgroup ]; then
 | 
									break
 | 
				
			||||||
					eerror "No permission to apply cgroup settings"
 | 
					 | 
				
			||||||
					break
 | 
					 | 
				
			||||||
				fi
 | 
					 | 
				
			||||||
			fi
 | 
								fi
 | 
				
			||||||
			cgroup_add_service
 | 
								cgroup_add_service /sys/fs/cgroup/openrc
 | 
				
			||||||
 | 
								cgroup_add_service /sys/fs/cgroup/systemd/system
 | 
				
			||||||
		fi
 | 
							fi
 | 
				
			||||||
		[ "$(command -v cgroup_set_limits)" = "cgroup_set_limits" ] &&
 | 
							[ "$(command -v cgroup_set_limits)" = "cgroup_set_limits" ] &&
 | 
				
			||||||
			cgroup_set_limits
 | 
								cgroup_set_limits
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -184,17 +184,18 @@ cgroup2_set_limits()
 | 
				
			|||||||
	cgroup_path="$(cgroup2_find_path)"
 | 
						cgroup_path="$(cgroup2_find_path)"
 | 
				
			||||||
	[ -d "${cgroup_path}" ] || return 0
 | 
						[ -d "${cgroup_path}" ] || return 0
 | 
				
			||||||
	rc_cgroup_path="${cgroup_path}/${RC_SVCNAME}"
 | 
						rc_cgroup_path="${cgroup_path}/${RC_SVCNAME}"
 | 
				
			||||||
 | 
						local OIFS="$IFS"
 | 
				
			||||||
 | 
						IFS="
 | 
				
			||||||
 | 
					"
 | 
				
			||||||
	[ ! -d "${rc_cgroup_path}" ] && mkdir "${rc_cgroup_path}"
 | 
						[ ! -d "${rc_cgroup_path}" ] && mkdir "${rc_cgroup_path}"
 | 
				
			||||||
	[ -f "${rc_cgroup_path}"/cgroup.procs ] &&
 | 
						printf "%d" 0 > "${rc_cgroup_path}/cgroup.procs"
 | 
				
			||||||
		printf 0 > "${rc_cgroup_path}"/cgroup.procs
 | 
						echo "${rc_cgroup_settings}" | while IFS="$OIFS" read -r key value; do
 | 
				
			||||||
	[ -z "${rc_cgroup_settings}" ] && return 0
 | 
							[ -z "${key}" ] || [ -z "${value}" ] && continue
 | 
				
			||||||
	echo "${rc_cgroup_settings}" | while read -r key value; do
 | 
							[ ! -e "${rc_cgroup_path}/${key}" ] && continue
 | 
				
			||||||
		[ -z "${key}" ] && continue
 | 
							veinfo "${RC_SVCNAME}: cgroups: ${key} ${value}"
 | 
				
			||||||
		[ -z "${value}" ] && continue
 | 
							printf "%s" "${value}" > "${rc_cgroup_path}/${key}"
 | 
				
			||||||
		[ ! -f "${rc_cgroup_path}/${key}" ] && continue
 | 
					 | 
				
			||||||
		veinfo "${RC_SVCNAME}: cgroups: setting ${key} to ${value}"
 | 
					 | 
				
			||||||
		printf "%s\n" "${value}" > "${rc_cgroup_path}/${key}"
 | 
					 | 
				
			||||||
	done
 | 
						done
 | 
				
			||||||
 | 
						IFS="$OIFS"
 | 
				
			||||||
	return 0
 | 
						return 0
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -44,13 +44,9 @@ ssd_start()
 | 
				
			|||||||
	eval start-stop-daemon --start \
 | 
						eval start-stop-daemon --start \
 | 
				
			||||||
		--exec $command \
 | 
							--exec $command \
 | 
				
			||||||
		${chroot:+--chroot} $chroot \
 | 
							${chroot:+--chroot} $chroot \
 | 
				
			||||||
		${directory:+--chdir} $directory \
 | 
					 | 
				
			||||||
		${output_log+--stdout} $output_log \
 | 
					 | 
				
			||||||
		${error_log+--stderr} $error_log \
 | 
					 | 
				
			||||||
		${procname:+--name} $procname \
 | 
							${procname:+--name} $procname \
 | 
				
			||||||
		${pidfile:+--pidfile} $pidfile \
 | 
							${pidfile:+--pidfile} $pidfile \
 | 
				
			||||||
		${command_user+--user} $command_user \
 | 
							${command_user+--user} $command_user \
 | 
				
			||||||
		${umask+--umask} $umask \
 | 
					 | 
				
			||||||
		$_background $start_stop_daemon_args \
 | 
							$_background $start_stop_daemon_args \
 | 
				
			||||||
		-- $command_args $command_args_background
 | 
							-- $command_args $command_args_background
 | 
				
			||||||
	if eend $? "Failed to start ${name:-$RC_SVCNAME}"; then
 | 
						if eend $? "Failed to start ${name:-$RC_SVCNAME}"; then
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,16 +24,12 @@ supervise_start()
 | 
				
			|||||||
	# to work properly.
 | 
						# to work properly.
 | 
				
			||||||
	eval supervise-daemon "${RC_SVCNAME}" --start \
 | 
						eval supervise-daemon "${RC_SVCNAME}" --start \
 | 
				
			||||||
		${retry:+--retry} $retry \
 | 
							${retry:+--retry} $retry \
 | 
				
			||||||
		${directory:+--chdir} $directory  \
 | 
					 | 
				
			||||||
		${chroot:+--chroot} $chroot \
 | 
							${chroot:+--chroot} $chroot \
 | 
				
			||||||
		${output_log+--stdout} ${output_log} \
 | 
					 | 
				
			||||||
		${error_log+--stderr} $error_log \
 | 
					 | 
				
			||||||
		${pidfile:+--pidfile} $pidfile \
 | 
							${pidfile:+--pidfile} $pidfile \
 | 
				
			||||||
		${respawn_delay:+--respawn-delay} $respawn_delay \
 | 
							${respawn_delay:+--respawn-delay} $respawn_delay \
 | 
				
			||||||
		${respawn_max:+--respawn-max} $respawn_max \
 | 
							${respawn_max:+--respawn-max} $respawn_max \
 | 
				
			||||||
		${respawn_period:+--respawn-period} $respawn_period \
 | 
							${respawn_period:+--respawn-period} $respawn_period \
 | 
				
			||||||
		${command_user+--user} $command_user \
 | 
							${command_user+--user} $command_user \
 | 
				
			||||||
		${umask+--umask} $umask \
 | 
					 | 
				
			||||||
		$supervise_daemon_args \
 | 
							$supervise_daemon_args \
 | 
				
			||||||
		$command \
 | 
							$command \
 | 
				
			||||||
		-- $command_args $command_args_foreground
 | 
							-- $command_args $command_args_foreground
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,11 +28,9 @@
 | 
				
			|||||||
#if __GNUC__ > 2 || defined(__INTEL_COMPILER)
 | 
					#if __GNUC__ > 2 || defined(__INTEL_COMPILER)
 | 
				
			||||||
# define _dead __attribute__((__noreturn__))
 | 
					# define _dead __attribute__((__noreturn__))
 | 
				
			||||||
# define _unused __attribute__((__unused__))
 | 
					# define _unused __attribute__((__unused__))
 | 
				
			||||||
# define _xasprintf(a, b)  __attribute__((__format__(__printf__, a, b)))
 | 
					 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
# define _dead
 | 
					# define _dead
 | 
				
			||||||
# define _unused
 | 
					# define _unused
 | 
				
			||||||
# define _xasprintf(a, b)
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
 | 
					#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
 | 
				
			||||||
@@ -55,7 +53,6 @@
 | 
				
			|||||||
	} while (/* CONSTCOND */ 0)
 | 
						} while (/* CONSTCOND */ 0)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <stdarg.h>
 | 
					 | 
				
			||||||
#include <stdbool.h>
 | 
					#include <stdbool.h>
 | 
				
			||||||
#include <sys/stat.h>
 | 
					#include <sys/stat.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -99,10 +96,8 @@ _unused static char *xstrdup(const char *str)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#undef ERRX
 | 
					#undef ERRX
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/* basename_c never modifies the argument. As such, if there is a trailing
 | 
				
			||||||
 * basename_c never modifies the argument. As such, if there is a trailing
 | 
					 * slash then an empty string is returned. */
 | 
				
			||||||
 * slash then an empty string is returned.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
_unused static const char *basename_c(const char *path)
 | 
					_unused static const char *basename_c(const char *path)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const char *slash = strrchr(path, '/');
 | 
						const char *slash = strrchr(path, '/');
 | 
				
			||||||
@@ -126,49 +121,4 @@ _unused static bool existss(const char *pathname)
 | 
				
			|||||||
	return (stat(pathname, &buf) == 0 && buf.st_size != 0);
 | 
						return (stat(pathname, &buf) == 0 && buf.st_size != 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * This is an OpenRC specific version of the asprintf() function.
 | 
					 | 
				
			||||||
 * We do this to avoid defining the _GNU_SOURCE feature test macro on
 | 
					 | 
				
			||||||
 * glibc systems and to insure that we have a consistent function across
 | 
					 | 
				
			||||||
 * platforms. This also allows us to call our xmalloc and xrealloc
 | 
					 | 
				
			||||||
 * functions to handle memory allocation.
 | 
					 | 
				
			||||||
 * this function was originally written by Mike Frysinger.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
_unused _xasprintf(2,3) static int xasprintf(char **strp, const char *fmt, ...)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	va_list ap;
 | 
					 | 
				
			||||||
	int len;
 | 
					 | 
				
			||||||
	int memlen;
 | 
					 | 
				
			||||||
	char *ret;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * Start with a buffer size that should cover the vast majority of uses
 | 
					 | 
				
			||||||
	 * (path construction).
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	memlen = 4096;
 | 
					 | 
				
			||||||
	ret = xmalloc(memlen);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	va_start(ap, fmt);
 | 
					 | 
				
			||||||
	len = vsnprintf(ret, memlen, fmt, ap);
 | 
					 | 
				
			||||||
	va_end(ap);
 | 
					 | 
				
			||||||
	if (len >= memlen) {
 | 
					 | 
				
			||||||
		/*
 | 
					 | 
				
			||||||
		 * Output was truncated, so increase buffer to exactly what we need.
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		memlen = len + 1;
 | 
					 | 
				
			||||||
		ret = xrealloc(ret, memlen);
 | 
					 | 
				
			||||||
		va_start(ap, fmt);
 | 
					 | 
				
			||||||
		len = vsnprintf(ret, len + 1, fmt, ap);
 | 
					 | 
				
			||||||
		va_end(ap);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (len < 0 || len >= memlen) {
 | 
					 | 
				
			||||||
		/* Give up! */
 | 
					 | 
				
			||||||
		fprintf(stderr, "xasprintf: unable to format a buffer\n");
 | 
					 | 
				
			||||||
		free(ret);
 | 
					 | 
				
			||||||
		exit(1);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	*strp = ret;
 | 
					 | 
				
			||||||
	return len;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -542,41 +542,52 @@ rc_deptree_order(const RC_DEPTREE *deptree, const char *runlevel, int options)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
librc_hidden_def(rc_deptree_order)
 | 
					librc_hidden_def(rc_deptree_order)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Given a time, recurse the target path to find out if there are
 | 
					 | 
				
			||||||
   any older (or newer) files.   If false, sets the time to the
 | 
					 | 
				
			||||||
   oldest (or newest) found.
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
static bool
 | 
					static bool
 | 
				
			||||||
deep_mtime_check(const char *target, bool newer,
 | 
					mtime_check(const char *source, const char *target, bool newer,
 | 
				
			||||||
	    time_t *rel, char *file)
 | 
						    time_t *rel, char *file)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct stat buf;
 | 
						struct stat buf;
 | 
				
			||||||
 | 
						time_t mtime;
 | 
				
			||||||
	bool retval = true;
 | 
						bool retval = true;
 | 
				
			||||||
	DIR *dp;
 | 
						DIR *dp;
 | 
				
			||||||
	struct dirent *d;
 | 
						struct dirent *d;
 | 
				
			||||||
	char path[PATH_MAX];
 | 
						char path[PATH_MAX];
 | 
				
			||||||
	int serrno = errno;
 | 
						int serrno = errno;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* We have to exist */
 | 
				
			||||||
 | 
						if (stat(source, &buf) != 0)
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						mtime = buf.st_mtime;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* If target does not exist, return true to mimic shell test */
 | 
						/* If target does not exist, return true to mimic shell test */
 | 
				
			||||||
	if (stat(target, &buf) != 0)
 | 
						if (stat(target, &buf) != 0)
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (newer) {
 | 
						if (newer) {
 | 
				
			||||||
		if (*rel < buf.st_mtime) {
 | 
							if (mtime < buf.st_mtime) {
 | 
				
			||||||
 | 
								if (rel == NULL)
 | 
				
			||||||
 | 
									return false;
 | 
				
			||||||
			retval = false;
 | 
								retval = false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
			if (file)
 | 
							if (rel != NULL) {
 | 
				
			||||||
				strlcpy(file, target, PATH_MAX);
 | 
								if (*rel < buf.st_mtime) {
 | 
				
			||||||
			*rel = buf.st_mtime;
 | 
									if (file)
 | 
				
			||||||
 | 
										strlcpy(file, target, PATH_MAX);
 | 
				
			||||||
 | 
									*rel = buf.st_mtime;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		if (*rel > buf.st_mtime) {
 | 
							if (mtime > buf.st_mtime) {
 | 
				
			||||||
 | 
								if (rel == NULL)
 | 
				
			||||||
 | 
									return false;
 | 
				
			||||||
			retval = false;
 | 
								retval = false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
			if (file)
 | 
							if (rel != NULL) {
 | 
				
			||||||
				strlcpy(file, target, PATH_MAX);
 | 
								if (*rel > buf.st_mtime) {
 | 
				
			||||||
			*rel = buf.st_mtime;
 | 
									if (file)
 | 
				
			||||||
 | 
										strlcpy(file, target, PATH_MAX);
 | 
				
			||||||
 | 
									*rel = buf.st_mtime;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -591,38 +602,16 @@ deep_mtime_check(const char *target, bool newer,
 | 
				
			|||||||
		if (d->d_name[0] == '.')
 | 
							if (d->d_name[0] == '.')
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		snprintf(path, sizeof(path), "%s/%s", target, d->d_name);
 | 
							snprintf(path, sizeof(path), "%s/%s", target, d->d_name);
 | 
				
			||||||
		if (!deep_mtime_check(path, newer, rel, file)) {
 | 
							if (!mtime_check(source, path, newer, rel, file)) {
 | 
				
			||||||
			retval = false;
 | 
								retval = false;
 | 
				
			||||||
 | 
								if (rel == NULL)
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	closedir(dp);
 | 
						closedir(dp);
 | 
				
			||||||
	return retval;
 | 
						return retval;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Recursively check if target is older/newer than source.
 | 
					 | 
				
			||||||
 * If false, return the filename and most different time (if
 | 
					 | 
				
			||||||
 * the return value arguments are non-null).
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static bool
 | 
					 | 
				
			||||||
mtime_check(const char *source, const char *target, bool newer,
 | 
					 | 
				
			||||||
	    time_t *rel, char *file)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct stat buf;
 | 
					 | 
				
			||||||
	time_t mtime;
 | 
					 | 
				
			||||||
	bool retval = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* We have to exist */
 | 
					 | 
				
			||||||
	if (stat(source, &buf) != 0)
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
	mtime = buf.st_mtime;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    retval = deep_mtime_check(target,newer,&mtime,file);
 | 
					 | 
				
			||||||
    if (rel) {
 | 
					 | 
				
			||||||
        *rel = mtime;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return retval;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool
 | 
					bool
 | 
				
			||||||
rc_newer_than(const char *source, const char *target,
 | 
					rc_newer_than(const char *source, const char *target,
 | 
				
			||||||
	      time_t *newest, char *file)
 | 
						      time_t *newest, char *file)
 | 
				
			||||||
@@ -681,8 +670,6 @@ rc_deptree_update_needed(time_t *newest, char *file)
 | 
				
			|||||||
	RC_STRINGLIST *config;
 | 
						RC_STRINGLIST *config;
 | 
				
			||||||
	RC_STRING *s;
 | 
						RC_STRING *s;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	struct stat buf;
 | 
					 | 
				
			||||||
	time_t mtime;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Create base directories if needed */
 | 
						/* Create base directories if needed */
 | 
				
			||||||
	for (i = 0; depdirs[i]; i++)
 | 
						for (i = 0; depdirs[i]; i++)
 | 
				
			||||||
@@ -690,48 +677,42 @@ rc_deptree_update_needed(time_t *newest, char *file)
 | 
				
			|||||||
			fprintf(stderr, "mkdir `%s': %s\n", depdirs[i], strerror(errno));
 | 
								fprintf(stderr, "mkdir `%s': %s\n", depdirs[i], strerror(errno));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Quick test to see if anything we use has changed and we have
 | 
						/* Quick test to see if anything we use has changed and we have
 | 
				
			||||||
	 * data in our deptree. */
 | 
						 * data in our deptree */
 | 
				
			||||||
 | 
						if (!existss(RC_DEPTREE_CACHE))
 | 
				
			||||||
	if (stat(RC_DEPTREE_CACHE, &buf) == 0) {
 | 
							return true;
 | 
				
			||||||
		mtime = buf.st_mtime;
 | 
						if (!rc_newer_than(RC_DEPTREE_CACHE, RC_INITDIR, newest, file))
 | 
				
			||||||
	} else {
 | 
							return true;
 | 
				
			||||||
		/* No previous cache found.
 | 
						if (!rc_newer_than(RC_DEPTREE_CACHE, RC_CONFDIR, newest, file))
 | 
				
			||||||
		 * We still run the scan, in case of clock skew; we still need to return
 | 
							return true;
 | 
				
			||||||
		 * the newest time.
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		newer = true;
 | 
					 | 
				
			||||||
		mtime = time(NULL);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	newer |= !deep_mtime_check(RC_INITDIR,true,&mtime,file);
 | 
					 | 
				
			||||||
	newer |= !deep_mtime_check(RC_CONFDIR,true,&mtime,file);
 | 
					 | 
				
			||||||
#ifdef RC_PKG_INITDIR
 | 
					#ifdef RC_PKG_INITDIR
 | 
				
			||||||
    newer |= !deep_mtime_check(RC_PKG_INITDIR,true,&mtime,file);
 | 
						if (!rc_newer_than(RC_DEPTREE_CACHE, RC_PKG_INITDIR, newest, file))
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#ifdef RC_PKG_CONFDIR
 | 
					#ifdef RC_PKG_CONFDIR
 | 
				
			||||||
    newer |= !deep_mtime_check(RC_PKG_CONFDIR,true,&mtime,file);
 | 
						if (!rc_newer_than(RC_DEPTREE_CACHE, RC_PKG_CONFDIR, newest, file))
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#ifdef RC_LOCAL_INITDIRs
 | 
					#ifdef RC_LOCAL_INITDIR
 | 
				
			||||||
    newer |= !deep_mtime_check(RC_LOCAL_INITDIR,true,&mtime,file);
 | 
						if (!rc_newer_than(RC_DEPTREE_CACHE, RC_LOCAL_INITDIR, newest, file))
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#ifdef RC_LOCAL_CONFDIR
 | 
					#ifdef RC_LOCAL_CONFDIR
 | 
				
			||||||
    newer |= !deep_mtime_check(RC_LOCAL_CONFDIR,true,&mtime,file);
 | 
						if (!rc_newer_than(RC_DEPTREE_CACHE, RC_LOCAL_CONFDIR, newest, file))
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    newer |= !deep_mtime_check(RC_CONF,true,&mtime,file);
 | 
						if (!rc_newer_than(RC_DEPTREE_CACHE, RC_CONF, newest, file))
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Some init scripts dependencies change depending on config files
 | 
						/* Some init scripts dependencies change depending on config files
 | 
				
			||||||
	 * outside of baselayout, like syslog-ng, so we check those too. */
 | 
						 * outside of baselayout, like syslog-ng, so we check those too. */
 | 
				
			||||||
	config = rc_config_list(RC_DEPCONFIG);
 | 
						config = rc_config_list(RC_DEPCONFIG);
 | 
				
			||||||
	TAILQ_FOREACH(s, config, entries) {
 | 
						TAILQ_FOREACH(s, config, entries) {
 | 
				
			||||||
		newer |= !deep_mtime_check(s->value, true, &mtime, file);
 | 
							if (!rc_newer_than(RC_DEPTREE_CACHE, s->value, newest, file)) {
 | 
				
			||||||
 | 
								newer = true;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	rc_stringlist_free(config);
 | 
						rc_stringlist_free(config);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Return newest file time, if requested */
 | 
					 | 
				
			||||||
	if ((newer) && (newest != NULL)) {
 | 
					 | 
				
			||||||
	    *newest = mtime;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return newer;
 | 
						return newer;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
librc_hidden_def(rc_deptree_update_needed)
 | 
					librc_hidden_def(rc_deptree_update_needed)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -73,32 +73,25 @@ static int do_check(char *path, uid_t uid, gid_t gid, mode_t mode,
 | 
				
			|||||||
	inode_t type, bool trunc, bool chowner, bool selinux_on)
 | 
						inode_t type, bool trunc, bool chowner, bool selinux_on)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct stat st;
 | 
						struct stat st;
 | 
				
			||||||
	int fd;
 | 
						int fd, flags;
 | 
				
			||||||
	int flags;
 | 
					 | 
				
			||||||
	int r;
 | 
						int r;
 | 
				
			||||||
	int readfd;
 | 
					 | 
				
			||||||
	int readflags;
 | 
					 | 
				
			||||||
	int u;
 | 
						int u;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset(&st, 0, sizeof(st));
 | 
						memset(&st, 0, sizeof(st));
 | 
				
			||||||
	flags = O_CREAT|O_NDELAY|O_WRONLY|O_NOCTTY;
 | 
						if (lstat(path, &st) || trunc) {
 | 
				
			||||||
	readflags = O_NDELAY|O_NOCTTY|O_RDONLY;
 | 
					 | 
				
			||||||
#ifdef O_CLOEXEC
 | 
					 | 
				
			||||||
	flags |= O_CLOEXEC;
 | 
					 | 
				
			||||||
	readflags |= O_CLOEXEC;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#ifdef O_NOFOLLOW
 | 
					 | 
				
			||||||
	flags |= O_NOFOLLOW;
 | 
					 | 
				
			||||||
	readflags |= O_NOFOLLOW;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
	if (trunc)
 | 
					 | 
				
			||||||
		flags |= O_TRUNC;
 | 
					 | 
				
			||||||
	readfd = open(path, readflags);
 | 
					 | 
				
			||||||
	if (readfd == -1 || (type == inode_file && trunc)) {
 | 
					 | 
				
			||||||
		if (type == inode_file) {
 | 
							if (type == inode_file) {
 | 
				
			||||||
			einfo("%s: creating file", path);
 | 
								einfo("%s: creating file", path);
 | 
				
			||||||
			if (!mode) /* 664 */
 | 
								if (!mode) /* 664 */
 | 
				
			||||||
				mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;
 | 
									mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;
 | 
				
			||||||
 | 
								flags = O_CREAT|O_NDELAY|O_WRONLY|O_NOCTTY;
 | 
				
			||||||
 | 
					#ifdef O_CLOEXEC
 | 
				
			||||||
 | 
								flags |= O_CLOEXEC;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifdef O_NOFOLLOW
 | 
				
			||||||
 | 
								flags |= O_NOFOLLOW;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
								if (trunc)
 | 
				
			||||||
 | 
									flags |= O_TRUNC;
 | 
				
			||||||
			u = umask(0);
 | 
								u = umask(0);
 | 
				
			||||||
			fd = open(path, flags, mode);
 | 
								fd = open(path, flags, mode);
 | 
				
			||||||
			umask(u);
 | 
								umask(u);
 | 
				
			||||||
@@ -106,9 +99,7 @@ static int do_check(char *path, uid_t uid, gid_t gid, mode_t mode,
 | 
				
			|||||||
				eerror("%s: open: %s", applet, strerror(errno));
 | 
									eerror("%s: open: %s", applet, strerror(errno));
 | 
				
			||||||
				return -1;
 | 
									return -1;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (readfd != -1 && trunc)
 | 
								close (fd);
 | 
				
			||||||
				close(readfd);
 | 
					 | 
				
			||||||
			readfd = fd;
 | 
					 | 
				
			||||||
		} else if (type == inode_dir) {
 | 
							} else if (type == inode_dir) {
 | 
				
			||||||
			einfo("%s: creating directory", path);
 | 
								einfo("%s: creating directory", path);
 | 
				
			||||||
			if (!mode) /* 775 */
 | 
								if (!mode) /* 775 */
 | 
				
			||||||
@@ -122,12 +113,7 @@ static int do_check(char *path, uid_t uid, gid_t gid, mode_t mode,
 | 
				
			|||||||
				    strerror (errno));
 | 
									    strerror (errno));
 | 
				
			||||||
				return -1;
 | 
									return -1;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			readfd = open(path, readflags);
 | 
								mode = 0;
 | 
				
			||||||
			if (readfd == -1) {
 | 
					 | 
				
			||||||
				eerror("%s: unable to open directory: %s", applet,
 | 
					 | 
				
			||||||
						strerror(errno));
 | 
					 | 
				
			||||||
				return -1;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		} else if (type == inode_fifo) {
 | 
							} else if (type == inode_fifo) {
 | 
				
			||||||
			einfo("%s: creating fifo", path);
 | 
								einfo("%s: creating fifo", path);
 | 
				
			||||||
			if (!mode) /* 600 */
 | 
								if (!mode) /* 600 */
 | 
				
			||||||
@@ -140,76 +126,56 @@ static int do_check(char *path, uid_t uid, gid_t gid, mode_t mode,
 | 
				
			|||||||
				    strerror (errno));
 | 
									    strerror (errno));
 | 
				
			||||||
				return -1;
 | 
									return -1;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			readfd = open(path, readflags);
 | 
					 | 
				
			||||||
			if (readfd == -1) {
 | 
					 | 
				
			||||||
				eerror("%s: unable to open fifo: %s", applet,
 | 
					 | 
				
			||||||
						strerror(errno));
 | 
					 | 
				
			||||||
				return -1;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						} else {
 | 
				
			||||||
	if (fstat(readfd, &st) != -1) {
 | 
					 | 
				
			||||||
		if (type != inode_dir && S_ISDIR(st.st_mode)) {
 | 
							if (type != inode_dir && S_ISDIR(st.st_mode)) {
 | 
				
			||||||
			eerror("%s: is a directory", path);
 | 
								eerror("%s: is a directory", path);
 | 
				
			||||||
			close(readfd);
 | 
					 | 
				
			||||||
			return 1;
 | 
								return 1;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (type != inode_file && S_ISREG(st.st_mode)) {
 | 
							if (type != inode_file && S_ISREG(st.st_mode)) {
 | 
				
			||||||
			eerror("%s: is a file", path);
 | 
								eerror("%s: is a file", path);
 | 
				
			||||||
			close(readfd);
 | 
					 | 
				
			||||||
			return 1;
 | 
								return 1;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (type != inode_fifo && S_ISFIFO(st.st_mode)) {
 | 
							if (type != inode_fifo && S_ISFIFO(st.st_mode)) {
 | 
				
			||||||
			eerror("%s: is a fifo", path);
 | 
								eerror("%s: is a fifo", path);
 | 
				
			||||||
			close(readfd);
 | 
					 | 
				
			||||||
			return -1;
 | 
								return -1;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (mode && (st.st_mode & 0777) != mode) {
 | 
					 | 
				
			||||||
			if ((type != inode_dir) && (st.st_nlink > 1)) {
 | 
					 | 
				
			||||||
				eerror("%s: chmod: %s %s", applet, "Too many hard links to", path);
 | 
					 | 
				
			||||||
				close(readfd);
 | 
					 | 
				
			||||||
				return -1;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if (S_ISLNK(st.st_mode)) {
 | 
					 | 
				
			||||||
				eerror("%s: chmod: %s %s", applet, path, " is a symbolic link");
 | 
					 | 
				
			||||||
				close(readfd);
 | 
					 | 
				
			||||||
				return -1;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			einfo("%s: correcting mode", path);
 | 
					 | 
				
			||||||
			if (fchmod(readfd, mode)) {
 | 
					 | 
				
			||||||
				eerror("%s: chmod: %s", applet, strerror(errno));
 | 
					 | 
				
			||||||
				close(readfd);
 | 
					 | 
				
			||||||
				return -1;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (chowner && (st.st_uid != uid || st.st_gid != gid)) {
 | 
					 | 
				
			||||||
			if ((type != inode_dir) && (st.st_nlink > 1)) {
 | 
					 | 
				
			||||||
				eerror("%s: chown: %s %s", applet, "Too many hard links to", path);
 | 
					 | 
				
			||||||
				close(readfd);
 | 
					 | 
				
			||||||
				return -1;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if (S_ISLNK(st.st_mode)) {
 | 
					 | 
				
			||||||
				eerror("%s: chown: %s %s", applet, path, " is a symbolic link");
 | 
					 | 
				
			||||||
				close(readfd);
 | 
					 | 
				
			||||||
				return -1;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			einfo("%s: correcting owner", path);
 | 
					 | 
				
			||||||
			if (fchown(readfd, uid, gid)) {
 | 
					 | 
				
			||||||
				eerror("%s: chown: %s", applet, strerror(errno));
 | 
					 | 
				
			||||||
				close(readfd);
 | 
					 | 
				
			||||||
				return -1;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (selinux_on)
 | 
					 | 
				
			||||||
			selinux_util_label(path);
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		eerror("fstat: %s: %s", path, strerror(errno));
 | 
					 | 
				
			||||||
		close(readfd);
 | 
					 | 
				
			||||||
		return -1;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	close(readfd);
 | 
					
 | 
				
			||||||
 | 
						if (mode && (st.st_mode & 0777) != mode) {
 | 
				
			||||||
 | 
							if ((type != inode_dir) && (st.st_nlink > 1)) {
 | 
				
			||||||
 | 
								eerror("%s: chmod: %s %s", applet, "Too many hard links to", path);
 | 
				
			||||||
 | 
								return -1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (S_ISLNK(st.st_mode)) {
 | 
				
			||||||
 | 
								eerror("%s: chmod: %s %s", applet, path, " is a symbolic link");
 | 
				
			||||||
 | 
								return -1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							einfo("%s: correcting mode", path);
 | 
				
			||||||
 | 
							if (chmod(path, mode)) {
 | 
				
			||||||
 | 
								eerror("%s: chmod: %s", applet, strerror(errno));
 | 
				
			||||||
 | 
								return -1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (chowner && (st.st_uid != uid || st.st_gid != gid)) {
 | 
				
			||||||
 | 
							if ((type != inode_dir) && (st.st_nlink > 1)) {
 | 
				
			||||||
 | 
								eerror("%s: chown: %s %s", applet, "Too many hard links to", path);
 | 
				
			||||||
 | 
								return -1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (S_ISLNK(st.st_mode)) {
 | 
				
			||||||
 | 
								eerror("%s: chown: %s %s", applet, path, " is a symbolic link");
 | 
				
			||||||
 | 
								return -1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							einfo("%s: correcting owner", path);
 | 
				
			||||||
 | 
							if (chown(path, uid, gid)) {
 | 
				
			||||||
 | 
								eerror("%s: chown: %s", applet, strerror(errno));
 | 
				
			||||||
 | 
								return -1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (selinux_on)
 | 
				
			||||||
 | 
							selinux_util_label(path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -141,7 +141,7 @@ do_mount(struct ENT *ent, bool remount)
 | 
				
			|||||||
		/* NOTREACHED */
 | 
							/* NOTREACHED */
 | 
				
			||||||
	case 0:
 | 
						case 0:
 | 
				
			||||||
		execvp(argv[0], argv);
 | 
							execvp(argv[0], argv);
 | 
				
			||||||
		eerror("%s: execvp: %s", applet, strerror(errno));
 | 
							eerror("%s: execv: %s", applet, strerror(errno));
 | 
				
			||||||
		_exit(EXIT_FAILURE);
 | 
							_exit(EXIT_FAILURE);
 | 
				
			||||||
		/* NOTREACHED */
 | 
							/* NOTREACHED */
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -65,7 +65,7 @@ static int mount_proc(void)
 | 
				
			|||||||
			break;
 | 
								break;
 | 
				
			||||||
		case 0:
 | 
							case 0:
 | 
				
			||||||
			/* attempt to mount /proc */
 | 
								/* attempt to mount /proc */
 | 
				
			||||||
			execlp("mount", "mount", "-t", "proc", "proc", "/proc", NULL);
 | 
								execl("mount", "mount", "-t", "proc", "proc", "/proc", NULL);
 | 
				
			||||||
			syslog(LOG_ERR, "Unable to execute mount");
 | 
								syslog(LOG_ERR, "Unable to execute mount");
 | 
				
			||||||
			exit(1);
 | 
								exit(1);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
@@ -87,11 +87,10 @@ static int mount_proc(void)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static bool is_user_process(pid_t pid)
 | 
					static bool is_user_process(pid_t pid)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char *buf = NULL;
 | 
						char buf[PATH_MAX+1];
 | 
				
			||||||
	FILE *fp;
 | 
						FILE *fp;
 | 
				
			||||||
	char *path = NULL;
 | 
						char path[PATH_MAX+1];
 | 
				
			||||||
	pid_t temp_pid;
 | 
						pid_t temp_pid;
 | 
				
			||||||
	size_t size;
 | 
					 | 
				
			||||||
	bool user_process = true;
 | 
						bool user_process = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while (pid >0 && user_process) {
 | 
						while (pid >0 && user_process) {
 | 
				
			||||||
@@ -99,9 +98,8 @@ static bool is_user_process(pid_t pid)
 | 
				
			|||||||
			user_process = false;
 | 
								user_process = false;
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		xasprintf(&path, "/proc/%d/status", pid);
 | 
							snprintf(path, sizeof(path), "/proc/%d/status", pid);
 | 
				
			||||||
		fp = fopen(path, "r");
 | 
							fp = fopen(path, "r");
 | 
				
			||||||
		free(path);
 | 
					 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * if we could not open the file, the process disappeared, which
 | 
							 * if we could not open the file, the process disappeared, which
 | 
				
			||||||
		 * leaves us no way to determine for sure whether it was a user
 | 
							 * leaves us no way to determine for sure whether it was a user
 | 
				
			||||||
@@ -114,14 +112,11 @@ static bool is_user_process(pid_t pid)
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		temp_pid = -1;
 | 
							temp_pid = -1;
 | 
				
			||||||
		while (! feof(fp)) {
 | 
							while (! feof(fp)) {
 | 
				
			||||||
			buf = NULL;
 | 
								buf[0] = 0;
 | 
				
			||||||
			if (getline(&buf, &size, fp) != -1) {
 | 
								if (fgets(buf, sizeof(buf), fp))
 | 
				
			||||||
				sscanf(buf, "PPid: %d", &temp_pid);
 | 
									sscanf(buf, "PPid: %d", &temp_pid);
 | 
				
			||||||
				free(buf);
 | 
								else
 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				free(buf);
 | 
					 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		fclose(fp);
 | 
							fclose(fp);
 | 
				
			||||||
		if (temp_pid == -1) {
 | 
							if (temp_pid == -1) {
 | 
				
			||||||
@@ -140,7 +135,7 @@ static int signal_processes(int sig, RC_STRINGLIST *omits, bool dryrun)
 | 
				
			|||||||
	sigset_t oldsigs;
 | 
						sigset_t oldsigs;
 | 
				
			||||||
	DIR *dir;
 | 
						DIR *dir;
 | 
				
			||||||
	struct dirent	*d;
 | 
						struct dirent	*d;
 | 
				
			||||||
	char *buf = NULL;
 | 
						char buf[PATH_MAX+1];
 | 
				
			||||||
	pid_t pid;
 | 
						pid_t pid;
 | 
				
			||||||
	int sendcount = 0;
 | 
						int sendcount = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -175,11 +170,7 @@ static int signal_processes(int sig, RC_STRINGLIST *omits, bool dryrun)
 | 
				
			|||||||
			continue;
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Is this a process we have been requested to omit? */
 | 
							/* Is this a process we have been requested to omit? */
 | 
				
			||||||
		if (buf) {
 | 
							sprintf(buf, "%d", pid);
 | 
				
			||||||
			free(buf);
 | 
					 | 
				
			||||||
			buf = NULL;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		xasprintf(&buf, "%d", pid);
 | 
					 | 
				
			||||||
		if (rc_stringlist_find(omits, buf))
 | 
							if (rc_stringlist_find(omits, buf))
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -248,6 +248,7 @@ find_mounts(struct args *args)
 | 
				
			|||||||
	struct opt *o;
 | 
						struct opt *o;
 | 
				
			||||||
	int netdev;
 | 
						int netdev;
 | 
				
			||||||
	char *tmp;
 | 
						char *tmp;
 | 
				
			||||||
 | 
						size_t l;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((nmnts = getmntinfo(&mnts, MNT_NOWAIT)) == 0)
 | 
						if ((nmnts = getmntinfo(&mnts, MNT_NOWAIT)) == 0)
 | 
				
			||||||
		eerrorx("getmntinfo: %s", strerror (errno));
 | 
							eerrorx("getmntinfo: %s", strerror (errno));
 | 
				
			||||||
@@ -263,7 +264,11 @@ find_mounts(struct args *args)
 | 
				
			|||||||
				if (! options)
 | 
									if (! options)
 | 
				
			||||||
					options = xstrdup(o->o_name);
 | 
										options = xstrdup(o->o_name);
 | 
				
			||||||
				else {
 | 
									else {
 | 
				
			||||||
					xasprintf(&tmp, "%s,%s", options, o->o_name);
 | 
										l = strlen(options) +
 | 
				
			||||||
 | 
										    strlen(o->o_name) + 2;
 | 
				
			||||||
 | 
										tmp = xmalloc(sizeof (char) * l);
 | 
				
			||||||
 | 
										snprintf(tmp, l, "%s,%s", options,
 | 
				
			||||||
 | 
										    o->o_name);
 | 
				
			||||||
					free(options);
 | 
										free(options);
 | 
				
			||||||
					options = tmp;
 | 
										options = tmp;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@@ -310,7 +315,6 @@ find_mounts(struct args *args)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	FILE *fp;
 | 
						FILE *fp;
 | 
				
			||||||
	char *buffer;
 | 
						char *buffer;
 | 
				
			||||||
	size_t size;
 | 
					 | 
				
			||||||
	char *p;
 | 
						char *p;
 | 
				
			||||||
	char *from;
 | 
						char *from;
 | 
				
			||||||
	char *to;
 | 
						char *to;
 | 
				
			||||||
@@ -325,8 +329,8 @@ find_mounts(struct args *args)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	list = rc_stringlist_new();
 | 
						list = rc_stringlist_new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	buffer = NULL;
 | 
						buffer = xmalloc(sizeof(char) * PATH_MAX * 3);
 | 
				
			||||||
	while (getline(&buffer, &size, fp) != -1) {
 | 
						while (fgets(buffer, PATH_MAX * 3, fp)) {
 | 
				
			||||||
		netdev = -1;
 | 
							netdev = -1;
 | 
				
			||||||
		p = buffer;
 | 
							p = buffer;
 | 
				
			||||||
		from = strsep(&p, " ");
 | 
							from = strsep(&p, " ");
 | 
				
			||||||
@@ -342,8 +346,6 @@ find_mounts(struct args *args)
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		process_mount(list, args, from, to, fst, opts, netdev);
 | 
							process_mount(list, args, from, to, fst, opts, netdev);
 | 
				
			||||||
		free(buffer);
 | 
					 | 
				
			||||||
		buffer = NULL;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	free(buffer);
 | 
						free(buffer);
 | 
				
			||||||
	fclose(fp);
 | 
						fclose(fp);
 | 
				
			||||||
@@ -378,7 +380,7 @@ int main(int argc, char **argv)
 | 
				
			|||||||
	regex_t *skip_point_regex = NULL;
 | 
						regex_t *skip_point_regex = NULL;
 | 
				
			||||||
	RC_STRINGLIST *nodes;
 | 
						RC_STRINGLIST *nodes;
 | 
				
			||||||
	RC_STRING *s;
 | 
						RC_STRING *s;
 | 
				
			||||||
	char *real_path = NULL;
 | 
						char real_path[PATH_MAX + 1];
 | 
				
			||||||
	int opt;
 | 
						int opt;
 | 
				
			||||||
	int result;
 | 
						int result;
 | 
				
			||||||
	char *this_path;
 | 
						char *this_path;
 | 
				
			||||||
@@ -448,12 +450,9 @@ int main(int argc, char **argv)
 | 
				
			|||||||
			eerrorx("%s: `%s' is not a mount point",
 | 
								eerrorx("%s: `%s' is not a mount point",
 | 
				
			||||||
			    argv[0], argv[optind]);
 | 
								    argv[0], argv[optind]);
 | 
				
			||||||
		this_path = argv[optind++];
 | 
							this_path = argv[optind++];
 | 
				
			||||||
		real_path = realpath(this_path, NULL);
 | 
							if (realpath(this_path, real_path))
 | 
				
			||||||
		if (real_path)
 | 
					 | 
				
			||||||
			this_path = real_path;
 | 
								this_path = real_path;
 | 
				
			||||||
		rc_stringlist_add(args.mounts, this_path);
 | 
							rc_stringlist_add(args.mounts, this_path);
 | 
				
			||||||
		free(real_path);
 | 
					 | 
				
			||||||
		real_path = NULL;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	nodes = find_mounts(&args);
 | 
						nodes = find_mounts(&args);
 | 
				
			||||||
	rc_stringlist_free(args.mounts);
 | 
						rc_stringlist_free(args.mounts);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,7 +35,6 @@
 | 
				
			|||||||
#include "rc-wtmp.h"
 | 
					#include "rc-wtmp.h"
 | 
				
			||||||
#include "version.h"
 | 
					#include "version.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char *path_default = "/sbin:/usr/sbin:/bin:/usr/bin";
 | 
					 | 
				
			||||||
static const char *rc_default_runlevel = "default";
 | 
					static const char *rc_default_runlevel = "default";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static pid_t do_openrc(const char *runlevel)
 | 
					static pid_t do_openrc(const char *runlevel)
 | 
				
			||||||
@@ -54,7 +53,7 @@ static pid_t do_openrc(const char *runlevel)
 | 
				
			|||||||
			sigemptyset(&signals);
 | 
								sigemptyset(&signals);
 | 
				
			||||||
			sigprocmask(SIG_SETMASK, &signals, NULL);
 | 
								sigprocmask(SIG_SETMASK, &signals, NULL);
 | 
				
			||||||
			printf("Starting %s runlevel\n", runlevel);
 | 
								printf("Starting %s runlevel\n", runlevel);
 | 
				
			||||||
			execlp("openrc", "openrc", runlevel, NULL);
 | 
								execl("/sbin/openrc", "/sbin/openrc", runlevel, NULL);
 | 
				
			||||||
			perror("exec");
 | 
								perror("exec");
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
@@ -89,7 +88,7 @@ static void init(const char *default_runlevel)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static void handle_reexec(char *my_name)
 | 
					static void handle_reexec(char *my_name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	execlp(my_name, my_name, "reexec", NULL);
 | 
						execl(my_name, my_name, "reexec", NULL);
 | 
				
			||||||
	return;
 | 
						return;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -184,9 +183,6 @@ int main(int argc, char **argv)
 | 
				
			|||||||
	sigaction(SIGINT, &sa, NULL);
 | 
						sigaction(SIGINT, &sa, NULL);
 | 
				
			||||||
	reboot(RB_DISABLE_CAD);
 | 
						reboot(RB_DISABLE_CAD);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* set default path */
 | 
					 | 
				
			||||||
	setenv("PATH", path_default, 1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (! reexec)
 | 
						if (! reexec)
 | 
				
			||||||
		init(default_runlevel);
 | 
							init(default_runlevel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -109,7 +109,7 @@ static void
 | 
				
			|||||||
handle_signal(int sig)
 | 
					handle_signal(int sig)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int serrno = errno;
 | 
						int serrno = errno;
 | 
				
			||||||
	char *signame = NULL;
 | 
						char signame[10] = { '\0' };
 | 
				
			||||||
	struct winsize ws;
 | 
						struct winsize ws;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (sig) {
 | 
						switch (sig) {
 | 
				
			||||||
@@ -134,22 +134,20 @@ handle_signal(int sig)
 | 
				
			|||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case SIGINT:
 | 
						case SIGINT:
 | 
				
			||||||
		if (!signame)
 | 
							if (!signame[0])
 | 
				
			||||||
			xasprintf(&signame, "SIGINT");
 | 
								snprintf(signame, sizeof(signame), "SIGINT");
 | 
				
			||||||
		/* FALLTHROUGH */
 | 
							/* FALLTHROUGH */
 | 
				
			||||||
	case SIGTERM:
 | 
						case SIGTERM:
 | 
				
			||||||
		if (!signame)
 | 
							if (!signame[0])
 | 
				
			||||||
			xasprintf(&signame, "SIGTERM");
 | 
								snprintf(signame, sizeof(signame), "SIGTERM");
 | 
				
			||||||
		/* FALLTHROUGH */
 | 
							/* FALLTHROUGH */
 | 
				
			||||||
	case SIGQUIT:
 | 
						case SIGQUIT:
 | 
				
			||||||
		if (!signame)
 | 
							if (!signame[0])
 | 
				
			||||||
			xasprintf(&signame, "SIGQUIT");
 | 
								snprintf(signame, sizeof(signame), "SIGQUIT");
 | 
				
			||||||
		/* Send the signal to our children too */
 | 
							/* Send the signal to our children too */
 | 
				
			||||||
		if (service_pid > 0)
 | 
							if (service_pid > 0)
 | 
				
			||||||
			kill(service_pid, sig);
 | 
								kill(service_pid, sig);
 | 
				
			||||||
		eerror("%s: caught %s, aborting", applet, signame);
 | 
							eerrorx("%s: caught %s, aborting", applet, signame);
 | 
				
			||||||
		free(signame);
 | 
					 | 
				
			||||||
		exit(EXIT_FAILURE);
 | 
					 | 
				
			||||||
		/* NOTREACHED */
 | 
							/* NOTREACHED */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
@@ -163,12 +161,11 @@ handle_signal(int sig)
 | 
				
			|||||||
static void
 | 
					static void
 | 
				
			||||||
unhotplug()
 | 
					unhotplug()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char *file = NULL;
 | 
						char file[PATH_MAX];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	xasprintf(&file, RC_SVCDIR "/hotplugged/%s", applet);
 | 
						snprintf(file, sizeof(file), RC_SVCDIR "/hotplugged/%s", applet);
 | 
				
			||||||
	if (exists(file) && unlink(file) != 0)
 | 
						if (exists(file) && unlink(file) != 0)
 | 
				
			||||||
		eerror("%s: unlink `%s': %s", applet, file, strerror(errno));
 | 
							eerror("%s: unlink `%s': %s", applet, file, strerror(errno));
 | 
				
			||||||
	free(file);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
@@ -488,7 +485,7 @@ svc_exec(const char *arg1, const char *arg2)
 | 
				
			|||||||
static bool
 | 
					static bool
 | 
				
			||||||
svc_wait(const char *svc)
 | 
					svc_wait(const char *svc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char *file = NULL;
 | 
						char file[PATH_MAX];
 | 
				
			||||||
	int fd;
 | 
						int fd;
 | 
				
			||||||
	bool forever = false;
 | 
						bool forever = false;
 | 
				
			||||||
	RC_STRINGLIST *keywords;
 | 
						RC_STRINGLIST *keywords;
 | 
				
			||||||
@@ -501,7 +498,8 @@ svc_wait(const char *svc)
 | 
				
			|||||||
		forever = true;
 | 
							forever = true;
 | 
				
			||||||
	rc_stringlist_free(keywords);
 | 
						rc_stringlist_free(keywords);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	xasprintf(&file, RC_SVCDIR "/exclusive/%s", basename_c(svc));
 | 
						snprintf(file, sizeof(file), RC_SVCDIR "/exclusive/%s",
 | 
				
			||||||
 | 
						    basename_c(svc));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	interval.tv_sec = 0;
 | 
						interval.tv_sec = 0;
 | 
				
			||||||
	interval.tv_nsec = WAIT_INTERVAL;
 | 
						interval.tv_nsec = WAIT_INTERVAL;
 | 
				
			||||||
@@ -514,29 +512,23 @@ svc_wait(const char *svc)
 | 
				
			|||||||
		if (fd != -1) {
 | 
							if (fd != -1) {
 | 
				
			||||||
			if (flock(fd, LOCK_SH | LOCK_NB) == 0) {
 | 
								if (flock(fd, LOCK_SH | LOCK_NB) == 0) {
 | 
				
			||||||
				close(fd);
 | 
									close(fd);
 | 
				
			||||||
				free(file);
 | 
					 | 
				
			||||||
				return true;
 | 
									return true;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			close(fd);
 | 
								close(fd);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (errno == ENOENT) {
 | 
							if (errno == ENOENT)
 | 
				
			||||||
			free(file);
 | 
					 | 
				
			||||||
			return true;
 | 
								return true;
 | 
				
			||||||
		}
 | 
							if (errno != EWOULDBLOCK)
 | 
				
			||||||
		if (errno != EWOULDBLOCK) {
 | 
								eerrorx("%s: open `%s': %s", applet, file,
 | 
				
			||||||
			eerror("%s: open `%s': %s", applet, file,
 | 
					 | 
				
			||||||
			    strerror(errno));
 | 
								    strerror(errno));
 | 
				
			||||||
			free(file);
 | 
					 | 
				
			||||||
			exit(EXIT_FAILURE);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (nanosleep(&interval, NULL) == -1) {
 | 
							if (nanosleep(&interval, NULL) == -1) {
 | 
				
			||||||
			if (errno != EINTR)
 | 
								if (errno != EINTR)
 | 
				
			||||||
				goto finish;
 | 
									return false;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (!forever) {
 | 
							if (!forever) {
 | 
				
			||||||
			timespecsub(&timeout, &interval, &timeout);
 | 
								timespecsub(&timeout, &interval, &timeout);
 | 
				
			||||||
			if (timeout.tv_sec <= 0)
 | 
								if (timeout.tv_sec <= 0)
 | 
				
			||||||
				goto finish;
 | 
									return false;
 | 
				
			||||||
			timespecsub(&warn, &interval, &warn);
 | 
								timespecsub(&warn, &interval, &warn);
 | 
				
			||||||
			if (warn.tv_sec <= 0) {
 | 
								if (warn.tv_sec <= 0) {
 | 
				
			||||||
				ewarn("%s: waiting for %s (%d seconds)",
 | 
									ewarn("%s: waiting for %s (%d seconds)",
 | 
				
			||||||
@@ -546,8 +538,6 @@ svc_wait(const char *svc)
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
finish:
 | 
					 | 
				
			||||||
	free(file);
 | 
					 | 
				
			||||||
	return false;
 | 
						return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1115,10 +1105,9 @@ int main(int argc, char **argv)
 | 
				
			|||||||
	bool runscript = false;
 | 
						bool runscript = false;
 | 
				
			||||||
	int retval, opt, depoptions = RC_DEP_TRACE;
 | 
						int retval, opt, depoptions = RC_DEP_TRACE;
 | 
				
			||||||
	RC_STRING *svc;
 | 
						RC_STRING *svc;
 | 
				
			||||||
	char *path = NULL;
 | 
						char path[PATH_MAX], lnk[PATH_MAX];
 | 
				
			||||||
	char *lnk = NULL;
 | 
					 | 
				
			||||||
	char *dir, *save = NULL, *saveLnk = NULL;
 | 
						char *dir, *save = NULL, *saveLnk = NULL;
 | 
				
			||||||
	char *pidstr = NULL;
 | 
						char pidstr[10];
 | 
				
			||||||
	size_t l = 0, ll;
 | 
						size_t l = 0, ll;
 | 
				
			||||||
 	const char *file;
 | 
					 	const char *file;
 | 
				
			||||||
	struct stat stbuf;
 | 
						struct stat stbuf;
 | 
				
			||||||
@@ -1145,14 +1134,12 @@ int main(int argc, char **argv)
 | 
				
			|||||||
	 * This works fine, provided that we ONLY allow multiplexed services
 | 
						 * This works fine, provided that we ONLY allow multiplexed services
 | 
				
			||||||
	 * to exist in the same directory as the master link.
 | 
						 * to exist in the same directory as the master link.
 | 
				
			||||||
	 * Also, the master link as to be a real file in the init dir. */
 | 
						 * Also, the master link as to be a real file in the init dir. */
 | 
				
			||||||
	path = realpath(argv[1], NULL);
 | 
						if (!realpath(argv[1], path)) {
 | 
				
			||||||
	if (!path) {
 | 
					 | 
				
			||||||
		fprintf(stderr, "realpath: %s\n", strerror(errno));
 | 
							fprintf(stderr, "realpath: %s\n", strerror(errno));
 | 
				
			||||||
		exit(EXIT_FAILURE);
 | 
							exit(EXIT_FAILURE);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	lnk = xmalloc(4096);
 | 
						memset(lnk, 0, sizeof(lnk));
 | 
				
			||||||
	memset(lnk, 0, 4096);
 | 
						if (readlink(argv[1], lnk, sizeof(lnk)-1)) {
 | 
				
			||||||
	if (readlink(argv[1], lnk, 4096)) {
 | 
					 | 
				
			||||||
		dir = dirname(path);
 | 
							dir = dirname(path);
 | 
				
			||||||
		if (strchr(lnk, '/')) {
 | 
							if (strchr(lnk, '/')) {
 | 
				
			||||||
			save = xstrdup(dir);
 | 
								save = xstrdup(dir);
 | 
				
			||||||
@@ -1166,7 +1153,8 @@ int main(int argc, char **argv)
 | 
				
			|||||||
		} else
 | 
							} else
 | 
				
			||||||
			file = basename_c(argv[1]);
 | 
								file = basename_c(argv[1]);
 | 
				
			||||||
		ll = strlen(dir) + strlen(file) + 2;
 | 
							ll = strlen(dir) + strlen(file) + 2;
 | 
				
			||||||
		xasprintf(&service, "%s/%s", dir, file);
 | 
							service = xmalloc(ll);
 | 
				
			||||||
 | 
							snprintf(service, ll, "%s/%s", dir, file);
 | 
				
			||||||
		if (stat(service, &stbuf) != 0) {
 | 
							if (stat(service, &stbuf) != 0) {
 | 
				
			||||||
			free(service);
 | 
								free(service);
 | 
				
			||||||
			service = xstrdup(lnk);
 | 
								service = xstrdup(lnk);
 | 
				
			||||||
@@ -1174,7 +1162,6 @@ int main(int argc, char **argv)
 | 
				
			|||||||
		free(save);
 | 
							free(save);
 | 
				
			||||||
		free(saveLnk);
 | 
							free(saveLnk);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	free(lnk);
 | 
					 | 
				
			||||||
	if (!service)
 | 
						if (!service)
 | 
				
			||||||
		service = xstrdup(path);
 | 
							service = xstrdup(path);
 | 
				
			||||||
	applet = basename_c(service);
 | 
						applet = basename_c(service);
 | 
				
			||||||
@@ -1198,7 +1185,7 @@ int main(int argc, char **argv)
 | 
				
			|||||||
	/* Set an env var so that we always know our pid regardless of any
 | 
						/* 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_*
 | 
						   subshells the init script may create so that our mark_service_*
 | 
				
			||||||
	   functions can always instruct us of this change */
 | 
						   functions can always instruct us of this change */
 | 
				
			||||||
	xasprintf(&pidstr, "%d", (int) getpid());
 | 
						snprintf(pidstr, sizeof(pidstr), "%d", (int) getpid());
 | 
				
			||||||
	setenv("RC_OPENRC_PID", pidstr, 1);
 | 
						setenv("RC_OPENRC_PID", pidstr, 1);
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * RC_RUNSCRIPT_PID is deprecated, but we will keep it for a while
 | 
						 * RC_RUNSCRIPT_PID is deprecated, but we will keep it for a while
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -131,8 +131,7 @@ env_config(void)
 | 
				
			|||||||
	char *npp;
 | 
						char *npp;
 | 
				
			||||||
	char *tok;
 | 
						char *tok;
 | 
				
			||||||
	const char *sys = rc_sys();
 | 
						const char *sys = rc_sys();
 | 
				
			||||||
	char *buffer = NULL;
 | 
						char buffer[PATH_MAX];
 | 
				
			||||||
	size_t size = 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Ensure our PATH is prefixed with the system locations first
 | 
						/* Ensure our PATH is prefixed with the system locations first
 | 
				
			||||||
	   for a little extra security */
 | 
						   for a little extra security */
 | 
				
			||||||
@@ -171,7 +170,8 @@ env_config(void)
 | 
				
			|||||||
	free(e);
 | 
						free(e);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((fp = fopen(RC_KRUNLEVEL, "r"))) {
 | 
						if ((fp = fopen(RC_KRUNLEVEL, "r"))) {
 | 
				
			||||||
		if (getline(&buffer, &size, fp) != -1) {
 | 
							memset(buffer, 0, sizeof (buffer));
 | 
				
			||||||
 | 
							if (fgets(buffer, sizeof (buffer), fp)) {
 | 
				
			||||||
			l = strlen (buffer) - 1;
 | 
								l = strlen (buffer) - 1;
 | 
				
			||||||
			if (buffer[l] == '\n')
 | 
								if (buffer[l] == '\n')
 | 
				
			||||||
				buffer[l] = 0;
 | 
									buffer[l] = 0;
 | 
				
			||||||
@@ -181,7 +181,6 @@ env_config(void)
 | 
				
			|||||||
	} else
 | 
						} else
 | 
				
			||||||
		setenv("RC_DEFAULTLEVEL", RC_LEVEL_DEFAULT, 1);
 | 
							setenv("RC_DEFAULTLEVEL", RC_LEVEL_DEFAULT, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	free(buffer);
 | 
					 | 
				
			||||||
	if (sys)
 | 
						if (sys)
 | 
				
			||||||
		setenv("RC_SYS", sys, 1);
 | 
							setenv("RC_SYS", sys, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -233,12 +232,11 @@ signal_setup_restart(int sig, void (*handler)(int))
 | 
				
			|||||||
int
 | 
					int
 | 
				
			||||||
svc_lock(const char *applet)
 | 
					svc_lock(const char *applet)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char *file = NULL;
 | 
						char file[PATH_MAX];
 | 
				
			||||||
	int fd;
 | 
						int fd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	xasprintf(&file, RC_SVCDIR "/exclusive/%s", applet);
 | 
						snprintf(file, sizeof(file), RC_SVCDIR "/exclusive/%s", applet);
 | 
				
			||||||
	fd = open(file, O_WRONLY | O_CREAT | O_NONBLOCK, 0664);
 | 
						fd = open(file, O_WRONLY | O_CREAT | O_NONBLOCK, 0664);
 | 
				
			||||||
	free(file);
 | 
					 | 
				
			||||||
	if (fd == -1)
 | 
						if (fd == -1)
 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
	if (flock(fd, LOCK_EX | LOCK_NB) == -1) {
 | 
						if (flock(fd, LOCK_EX | LOCK_NB) == -1) {
 | 
				
			||||||
@@ -252,12 +250,11 @@ svc_lock(const char *applet)
 | 
				
			|||||||
int
 | 
					int
 | 
				
			||||||
svc_unlock(const char *applet, int fd)
 | 
					svc_unlock(const char *applet, int fd)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char *file = NULL;
 | 
						char file[PATH_MAX];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	xasprintf(&file, RC_SVCDIR "/exclusive/%s", applet);
 | 
						snprintf(file, sizeof(file), RC_SVCDIR "/exclusive/%s", applet);
 | 
				
			||||||
	close(fd);
 | 
						close(fd);
 | 
				
			||||||
	unlink(file);
 | 
						unlink(file);
 | 
				
			||||||
	free(file);
 | 
					 | 
				
			||||||
	return -1;
 | 
						return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -361,7 +358,7 @@ RC_DEPTREE * _rc_deptree_load(int force, int *regen)
 | 
				
			|||||||
	int serrno = errno;
 | 
						int serrno = errno;
 | 
				
			||||||
	int merrno;
 | 
						int merrno;
 | 
				
			||||||
	time_t t;
 | 
						time_t t;
 | 
				
			||||||
	char *file = NULL;
 | 
						char file[PATH_MAX];
 | 
				
			||||||
	struct stat st;
 | 
						struct stat st;
 | 
				
			||||||
	struct utimbuf ut;
 | 
						struct utimbuf ut;
 | 
				
			||||||
	FILE *fp;
 | 
						FILE *fp;
 | 
				
			||||||
@@ -383,10 +380,7 @@ RC_DEPTREE * _rc_deptree_load(int force, int *regen)
 | 
				
			|||||||
		eend (retval, "Failed to update the dependency tree");
 | 
							eend (retval, "Failed to update the dependency tree");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (retval == 0) {
 | 
							if (retval == 0) {
 | 
				
			||||||
			if (stat(RC_DEPTREE_CACHE, &st) != 0) {
 | 
								stat(RC_DEPTREE_CACHE, &st);
 | 
				
			||||||
				eerror("stat(%s): %s", RC_DEPTREE_CACHE, strerror(errno));
 | 
					 | 
				
			||||||
				return NULL;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if (st.st_mtime < t) {
 | 
								if (st.st_mtime < t) {
 | 
				
			||||||
				eerror("Clock skew detected with `%s'", file);
 | 
									eerror("Clock skew detected with `%s'", file);
 | 
				
			||||||
				eerrorn("Adjusting mtime of `" RC_DEPTREE_CACHE
 | 
									eerrorn("Adjusting mtime of `" RC_DEPTREE_CACHE
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -68,7 +68,7 @@ rc_plugin_load(void)
 | 
				
			|||||||
	DIR *dp;
 | 
						DIR *dp;
 | 
				
			||||||
	struct dirent *d;
 | 
						struct dirent *d;
 | 
				
			||||||
	PLUGIN *plugin;
 | 
						PLUGIN *plugin;
 | 
				
			||||||
	char *file = NULL;
 | 
						char file[PATH_MAX];
 | 
				
			||||||
	void *h;
 | 
						void *h;
 | 
				
			||||||
	int (*fptr)(RC_HOOK, const char *);
 | 
						int (*fptr)(RC_HOOK, const char *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -85,9 +85,8 @@ rc_plugin_load(void)
 | 
				
			|||||||
		if (d->d_name[0] == '.')
 | 
							if (d->d_name[0] == '.')
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		xasprintf(&file, RC_PLUGINDIR "/%s",  d->d_name);
 | 
							snprintf(file, sizeof(file), RC_PLUGINDIR "/%s",  d->d_name);
 | 
				
			||||||
		h = dlopen(file, RTLD_LAZY);
 | 
							h = dlopen(file, RTLD_LAZY);
 | 
				
			||||||
		free(file);
 | 
					 | 
				
			||||||
		if (h == NULL) {
 | 
							if (h == NULL) {
 | 
				
			||||||
			eerror("dlopen: %s", dlerror());
 | 
								eerror("dlopen: %s", dlerror());
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -307,9 +307,6 @@ int run_stop_schedule(const char *applet,
 | 
				
			|||||||
	const char *const *p;
 | 
						const char *const *p;
 | 
				
			||||||
	bool progressed = false;
 | 
						bool progressed = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!(pid > 0 || exec || uid || (argv && *argv)))
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (exec)
 | 
						if (exec)
 | 
				
			||||||
		einfov("Will stop %s", exec);
 | 
							einfov("Will stop %s", exec);
 | 
				
			||||||
	if (pid > 0)
 | 
						if (pid > 0)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -256,19 +256,19 @@ static int read_context_file(const char *filename, char **context)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	int ret = -1;
 | 
						int ret = -1;
 | 
				
			||||||
	FILE *fp;
 | 
						FILE *fp;
 | 
				
			||||||
	char *filepath = NULL;
 | 
						char filepath[PATH_MAX];
 | 
				
			||||||
	char *line = NULL;
 | 
						char *line = NULL;
 | 
				
			||||||
	char *p;
 | 
						char *p;
 | 
				
			||||||
	char *p2;
 | 
						char *p2;
 | 
				
			||||||
	size_t len = 0;
 | 
						size_t len = 0;
 | 
				
			||||||
	ssize_t read;
 | 
						ssize_t read;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	xasprintf(&filepath, "%s/%s", selinux_contexts_path(), filename);
 | 
						memset(filepath, '\0', PATH_MAX);
 | 
				
			||||||
 | 
						snprintf(filepath, PATH_MAX - 1, "%s/%s", selinux_contexts_path(), filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fp = fopen(filepath, "r");
 | 
						fp = fopen(filepath, "r");
 | 
				
			||||||
	if (fp == NULL) {
 | 
						if (fp == NULL) {
 | 
				
			||||||
		eerror("Failed to open context file: %s", filename);
 | 
							eerror("Failed to open context file: %s", filename);
 | 
				
			||||||
		free(filepath);
 | 
					 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -294,7 +294,6 @@ static int read_context_file(const char *filename, char **context)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	free(line);
 | 
						free(line);
 | 
				
			||||||
	free(filepath);
 | 
					 | 
				
			||||||
	fclose(fp);
 | 
						fclose(fp);
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,10 +29,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const char *applet = NULL;
 | 
					const char *applet = NULL;
 | 
				
			||||||
const char *extraopts = NULL;
 | 
					const char *extraopts = NULL;
 | 
				
			||||||
const char *getoptstring = "ce:ilr:IN" getoptstring_COMMON;
 | 
					const char *getoptstring = "e:ilr:IN" getoptstring_COMMON;
 | 
				
			||||||
const struct option longopts[] = {
 | 
					const struct option longopts[] = {
 | 
				
			||||||
	{ "exists",   1, NULL, 'e' },
 | 
						{ "exists",   1, NULL, 'e' },
 | 
				
			||||||
	{ "ifcrashed", 0, NULL, 'c' },
 | 
					 | 
				
			||||||
	{ "ifexists", 0, NULL, 'i' },
 | 
						{ "ifexists", 0, NULL, 'i' },
 | 
				
			||||||
	{ "ifinactive", 0, NULL, 'I' },
 | 
						{ "ifinactive", 0, NULL, 'I' },
 | 
				
			||||||
	{ "ifnotstarted", 0, NULL, 'N' },
 | 
						{ "ifnotstarted", 0, NULL, 'N' },
 | 
				
			||||||
@@ -42,7 +41,6 @@ const struct option longopts[] = {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
const char * const longopts_help[] = {
 | 
					const char * const longopts_help[] = {
 | 
				
			||||||
	"tests if the service exists or not",
 | 
						"tests if the service exists or not",
 | 
				
			||||||
	"if the service is crashed then run the command",
 | 
					 | 
				
			||||||
	"if the service exists then run the command",
 | 
						"if the service exists then run the command",
 | 
				
			||||||
	"if the service is inactive then run the command",
 | 
						"if the service is inactive then run the command",
 | 
				
			||||||
	"if the service is not started then run the command",
 | 
						"if the service is not started then run the command",
 | 
				
			||||||
@@ -63,7 +61,6 @@ int main(int argc, char **argv)
 | 
				
			|||||||
	RC_STRINGLIST *list;
 | 
						RC_STRINGLIST *list;
 | 
				
			||||||
	RC_STRING *s;
 | 
						RC_STRING *s;
 | 
				
			||||||
	RC_SERVICE state;
 | 
						RC_SERVICE state;
 | 
				
			||||||
	bool if_crashed = false;
 | 
					 | 
				
			||||||
	bool if_exists = false;
 | 
						bool if_exists = false;
 | 
				
			||||||
	bool if_inactive = false;
 | 
						bool if_inactive = false;
 | 
				
			||||||
	bool if_notstarted = false;
 | 
						bool if_notstarted = false;
 | 
				
			||||||
@@ -82,9 +79,6 @@ int main(int argc, char **argv)
 | 
				
			|||||||
			free(service);
 | 
								free(service);
 | 
				
			||||||
			return opt;
 | 
								return opt;
 | 
				
			||||||
			/* NOTREACHED */
 | 
								/* NOTREACHED */
 | 
				
			||||||
		case 'c':
 | 
					 | 
				
			||||||
			if_crashed = true;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case 'i':
 | 
							case 'i':
 | 
				
			||||||
			if_exists = true;
 | 
								if_exists = true;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
@@ -127,8 +121,6 @@ int main(int argc, char **argv)
 | 
				
			|||||||
		eerrorx("%s: service `%s' does not exist", applet, *argv);
 | 
							eerrorx("%s: service `%s' does not exist", applet, *argv);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	state = rc_service_state(*argv);
 | 
						state = rc_service_state(*argv);
 | 
				
			||||||
	if (if_crashed &&  ! (rc_service_daemons_crashed(*argv) && errno != EACCES))
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
	if (if_inactive && ! (state & RC_SERVICE_INACTIVE))
 | 
						if (if_inactive && ! (state & RC_SERVICE_INACTIVE))
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	if (if_notstarted && (state & RC_SERVICE_STARTED))
 | 
						if (if_notstarted && (state & RC_SERVICE_STARTED))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -166,7 +166,7 @@ show(RC_STRINGLIST *runlevels, bool verbose)
 | 
				
			|||||||
	RC_STRING *runlevel;
 | 
						RC_STRING *runlevel;
 | 
				
			||||||
	RC_STRINGLIST *in;
 | 
						RC_STRINGLIST *in;
 | 
				
			||||||
	bool inone;
 | 
						bool inone;
 | 
				
			||||||
	char *buffer = NULL;
 | 
						char buffer[PATH_MAX];
 | 
				
			||||||
	size_t l;
 | 
						size_t l;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rc_stringlist_sort(&services);
 | 
						rc_stringlist_sort(&services);
 | 
				
			||||||
@@ -182,11 +182,9 @@ show(RC_STRINGLIST *runlevels, bool verbose)
 | 
				
			|||||||
				inone = true;
 | 
									inone = true;
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				l = strlen(runlevel->value);
 | 
									l = strlen(runlevel->value);
 | 
				
			||||||
				buffer = xmalloc(l+1);
 | 
					 | 
				
			||||||
				memset (buffer, ' ', l);
 | 
									memset (buffer, ' ', l);
 | 
				
			||||||
				buffer[l] = 0;
 | 
									buffer[l] = 0;
 | 
				
			||||||
				rc_stringlist_add (in, buffer);
 | 
									rc_stringlist_add (in, buffer);
 | 
				
			||||||
				free(buffer);
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										27
									
								
								src/rc/rc.c
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								src/rc/rc.c
									
									
									
									
									
								
							@@ -78,6 +78,9 @@ const char *usagestring = ""					\
 | 
				
			|||||||
#define INITSH                  RC_LIBEXECDIR "/sh/init.sh"
 | 
					#define INITSH                  RC_LIBEXECDIR "/sh/init.sh"
 | 
				
			||||||
#define INITEARLYSH             RC_LIBEXECDIR "/sh/init-early.sh"
 | 
					#define INITEARLYSH             RC_LIBEXECDIR "/sh/init-early.sh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SHUTDOWN                "/sbin/shutdown"
 | 
				
			||||||
 | 
					#define SULOGIN                 "/sbin/sulogin"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define INTERACTIVE             RC_SVCDIR "/interactive"
 | 
					#define INTERACTIVE             RC_SVCDIR "/interactive"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define DEVBOOT			"/dev/.rcboot"
 | 
					#define DEVBOOT			"/dev/.rcboot"
 | 
				
			||||||
@@ -285,8 +288,8 @@ open_shell(void)
 | 
				
			|||||||
	/* VSERVER systems cannot really drop to shells */
 | 
						/* VSERVER systems cannot really drop to shells */
 | 
				
			||||||
	if (sys && strcmp(sys, RC_SYS_VSERVER) == 0)
 | 
						if (sys && strcmp(sys, RC_SYS_VSERVER) == 0)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		execlp("halt", "halt", "-f", (char *) NULL);
 | 
							execl("/sbin/halt", "/sbin/halt", "-f", (char *) NULL);
 | 
				
			||||||
		eerrorx("%s: unable to exec `halt -f': %s",
 | 
							eerrorx("%s: unable to exec `/sbin/halt': %s",
 | 
				
			||||||
		    applet, strerror(errno));
 | 
							    applet, strerror(errno));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@@ -333,26 +336,26 @@ set_krunlevel(const char *level)
 | 
				
			|||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static char *get_krunlevel(void)
 | 
					static size_t
 | 
				
			||||||
 | 
					get_krunlevel(char *buffer, int buffer_len)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char *buffer = NULL;
 | 
					 | 
				
			||||||
	FILE *fp;
 | 
						FILE *fp;
 | 
				
			||||||
	size_t i = 0;
 | 
						size_t i = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!exists(RC_KRUNLEVEL))
 | 
						if (!exists(RC_KRUNLEVEL))
 | 
				
			||||||
		return NULL;
 | 
							return 0;
 | 
				
			||||||
	if (!(fp = fopen(RC_KRUNLEVEL, "r"))) {
 | 
						if (!(fp = fopen(RC_KRUNLEVEL, "r"))) {
 | 
				
			||||||
		eerror("fopen `%s': %s", RC_KRUNLEVEL, strerror(errno));
 | 
							eerror("fopen `%s': %s", RC_KRUNLEVEL, strerror(errno));
 | 
				
			||||||
		return NULL;
 | 
							return 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (getline(&buffer, &i, fp) != -1) {
 | 
						if (fgets(buffer, buffer_len, fp)) {
 | 
				
			||||||
		i = strlen(buffer);
 | 
							i = strlen(buffer);
 | 
				
			||||||
		if (buffer[i - 1] == '\n')
 | 
							if (buffer[i - 1] == '\n')
 | 
				
			||||||
			buffer[i - 1] = 0;
 | 
								buffer[i - 1] = 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	fclose(fp);
 | 
						fclose(fp);
 | 
				
			||||||
	return buffer;
 | 
						return i;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
@@ -502,9 +505,6 @@ do_sysinit()
 | 
				
			|||||||
	 * sys */
 | 
						 * sys */
 | 
				
			||||||
	if ((sys = rc_sys()))
 | 
						if ((sys = rc_sys()))
 | 
				
			||||||
		setenv("RC_SYS", sys, 1);
 | 
							setenv("RC_SYS", sys, 1);
 | 
				
			||||||
	/* force an update of the dependency tree */
 | 
					 | 
				
			||||||
	if ((main_deptree = _rc_deptree_load(1, NULL)) == NULL)
 | 
					 | 
				
			||||||
		eerrorx("failed to load deptree");
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool
 | 
					static bool
 | 
				
			||||||
@@ -743,7 +743,7 @@ int main(int argc, char **argv)
 | 
				
			|||||||
	RC_STRING *service;
 | 
						RC_STRING *service;
 | 
				
			||||||
	bool going_down = false;
 | 
						bool going_down = false;
 | 
				
			||||||
	int depoptions = RC_DEP_STRICT | RC_DEP_TRACE;
 | 
						int depoptions = RC_DEP_STRICT | RC_DEP_TRACE;
 | 
				
			||||||
	char *krunlevel = NULL;
 | 
						char krunlevel [PATH_MAX];
 | 
				
			||||||
	char pidstr[10];
 | 
						char pidstr[10];
 | 
				
			||||||
	int opt;
 | 
						int opt;
 | 
				
			||||||
	bool parallel;
 | 
						bool parallel;
 | 
				
			||||||
@@ -892,8 +892,7 @@ int main(int argc, char **argv)
 | 
				
			|||||||
		    (strcmp(newlevel, RC_LEVEL_SYSINIT) != 0 &&
 | 
							    (strcmp(newlevel, RC_LEVEL_SYSINIT) != 0 &&
 | 
				
			||||||
			strcmp(newlevel, getenv("RC_BOOTLEVEL")) != 0))
 | 
								strcmp(newlevel, getenv("RC_BOOTLEVEL")) != 0))
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			krunlevel = get_krunlevel();
 | 
								if (get_krunlevel(krunlevel, sizeof(krunlevel))) {
 | 
				
			||||||
			if (krunlevel) {
 | 
					 | 
				
			||||||
				newlevel = krunlevel;
 | 
									newlevel = krunlevel;
 | 
				
			||||||
				set_krunlevel(NULL);
 | 
									set_krunlevel(NULL);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -254,7 +254,6 @@ int main(int argc, char **argv)
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int opt;
 | 
						int opt;
 | 
				
			||||||
	size_t size = 0;
 | 
					 | 
				
			||||||
	bool start = false;
 | 
						bool start = false;
 | 
				
			||||||
	bool stop = false;
 | 
						bool stop = false;
 | 
				
			||||||
	bool oknodo = false;
 | 
						bool oknodo = false;
 | 
				
			||||||
@@ -288,10 +287,10 @@ int main(int argc, char **argv)
 | 
				
			|||||||
	char *tmp, *newpath, *np;
 | 
						char *tmp, *newpath, *np;
 | 
				
			||||||
	char *p;
 | 
						char *p;
 | 
				
			||||||
	char *token;
 | 
						char *token;
 | 
				
			||||||
	char *exec_file = NULL;
 | 
						char exec_file[PATH_MAX];
 | 
				
			||||||
	struct passwd *pw;
 | 
						struct passwd *pw;
 | 
				
			||||||
	struct group *gr;
 | 
						struct group *gr;
 | 
				
			||||||
	char *line = NULL;
 | 
						char line[130];
 | 
				
			||||||
	FILE *fp;
 | 
						FILE *fp;
 | 
				
			||||||
	size_t len;
 | 
						size_t len;
 | 
				
			||||||
	mode_t numask = 022;
 | 
						mode_t numask = 022;
 | 
				
			||||||
@@ -578,22 +577,26 @@ int main(int argc, char **argv)
 | 
				
			|||||||
		if (*exec == '/' || *exec == '.') {
 | 
							if (*exec == '/' || *exec == '.') {
 | 
				
			||||||
			/* Full or relative path */
 | 
								/* Full or relative path */
 | 
				
			||||||
			if (ch_root)
 | 
								if (ch_root)
 | 
				
			||||||
				xasprintf(&exec_file, "%s/%s", ch_root, exec);
 | 
									snprintf(exec_file, sizeof(exec_file),
 | 
				
			||||||
 | 
									    "%s/%s", ch_root, exec);
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
				xasprintf(&exec_file, "%s", exec);
 | 
									snprintf(exec_file, sizeof(exec_file),
 | 
				
			||||||
 | 
									    "%s", exec);
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			/* Something in $PATH */
 | 
								/* Something in $PATH */
 | 
				
			||||||
			p = tmp = xstrdup(getenv("PATH"));
 | 
								p = tmp = xstrdup(getenv("PATH"));
 | 
				
			||||||
			exec_file = NULL;
 | 
								*exec_file = '\0';
 | 
				
			||||||
			while ((token = strsep(&p, ":"))) {
 | 
								while ((token = strsep(&p, ":"))) {
 | 
				
			||||||
				if (ch_root)
 | 
									if (ch_root)
 | 
				
			||||||
					xasprintf(&exec_file, "%s/%s/%s", ch_root, token, exec);
 | 
										snprintf(exec_file, sizeof(exec_file),
 | 
				
			||||||
 | 
										    "%s/%s/%s",
 | 
				
			||||||
 | 
										    ch_root, token, exec);
 | 
				
			||||||
				else
 | 
									else
 | 
				
			||||||
					xasprintf(&exec_file, "%s/%s", token, exec);
 | 
										snprintf(exec_file, sizeof(exec_file),
 | 
				
			||||||
				if (exec_file && exists(exec_file))
 | 
										    "%s/%s", token, exec);
 | 
				
			||||||
 | 
									if (exists(exec_file))
 | 
				
			||||||
					break;
 | 
										break;
 | 
				
			||||||
				free(exec_file);
 | 
									*exec_file = '\0';
 | 
				
			||||||
				exec_file = NULL;
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			free(tmp);
 | 
								free(tmp);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -601,7 +604,6 @@ int main(int argc, char **argv)
 | 
				
			|||||||
	if (start && !exists(exec_file)) {
 | 
						if (start && !exists(exec_file)) {
 | 
				
			||||||
		eerror("%s: %s does not exist", applet,
 | 
							eerror("%s: %s does not exist", applet,
 | 
				
			||||||
		    *exec_file ? exec_file : exec);
 | 
							    *exec_file ? exec_file : exec);
 | 
				
			||||||
		free(exec_file);
 | 
					 | 
				
			||||||
		exit(EXIT_FAILURE);
 | 
							exit(EXIT_FAILURE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -615,10 +617,7 @@ int main(int argc, char **argv)
 | 
				
			|||||||
	if (interpreted && !pidfile) {
 | 
						if (interpreted && !pidfile) {
 | 
				
			||||||
		fp = fopen(exec_file, "r");
 | 
							fp = fopen(exec_file, "r");
 | 
				
			||||||
		if (fp) {
 | 
							if (fp) {
 | 
				
			||||||
			line = NULL;
 | 
								p = fgets(line, sizeof(line), fp);
 | 
				
			||||||
			if (getline(&line, &size, fp) == -1)
 | 
					 | 
				
			||||||
				eerrorx("%s: %s", applet, strerror(errno));
 | 
					 | 
				
			||||||
			p = line;
 | 
					 | 
				
			||||||
			fclose(fp);
 | 
								fclose(fp);
 | 
				
			||||||
			if (p != NULL && line[0] == '#' && line[1] == '!') {
 | 
								if (p != NULL && line[0] == '#' && line[1] == '!') {
 | 
				
			||||||
				p = line + 2;
 | 
									p = line + 2;
 | 
				
			||||||
@@ -630,8 +629,7 @@ int main(int argc, char **argv)
 | 
				
			|||||||
				if (p[len] == '\n')
 | 
									if (p[len] == '\n')
 | 
				
			||||||
					p[len] = '\0';
 | 
										p[len] = '\0';
 | 
				
			||||||
				token = strsep(&p, " ");
 | 
									token = strsep(&p, " ");
 | 
				
			||||||
				free(exec_file);
 | 
									strncpy(exec_file, token, sizeof(exec_file));
 | 
				
			||||||
				xasprintf(&exec_file, "%s", token);
 | 
					 | 
				
			||||||
				opt = 0;
 | 
									opt = 0;
 | 
				
			||||||
				for (nav = argv; *nav; nav++)
 | 
									for (nav = argv; *nav; nav++)
 | 
				
			||||||
					opt++;
 | 
										opt++;
 | 
				
			||||||
@@ -659,15 +657,8 @@ int main(int argc, char **argv)
 | 
				
			|||||||
			parse_schedule(applet, "0", sig);
 | 
								parse_schedule(applet, "0", sig);
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			parse_schedule(applet, NULL, sig);
 | 
								parse_schedule(applet, NULL, sig);
 | 
				
			||||||
		if (pidfile) {
 | 
					 | 
				
			||||||
			pid = get_pid(applet, pidfile);
 | 
					 | 
				
			||||||
			if (pid == -1)
 | 
					 | 
				
			||||||
				exit(EXIT_FAILURE);
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			pid = 0;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		i = run_stop_schedule(applet, exec, (const char *const *)margv,
 | 
							i = run_stop_schedule(applet, exec, (const char *const *)margv,
 | 
				
			||||||
		    pid, uid, test, progress, false);
 | 
							    get_pid(applet, pidfile), uid, test, progress, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (i < 0)
 | 
							if (i < 0)
 | 
				
			||||||
			/* We failed to stop something */
 | 
								/* We failed to stop something */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -159,7 +159,7 @@ static void cleanup(void)
 | 
				
			|||||||
	free(changeuser);
 | 
						free(changeuser);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void re_exec_supervisor(void)
 | 
					static void re_exec(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	syslog(LOG_WARNING, "Re-executing for %s", svcname);
 | 
						syslog(LOG_WARNING, "Re-executing for %s", svcname);
 | 
				
			||||||
	execlp("supervise-daemon", "supervise-daemon", svcname, "--reexec",
 | 
						execlp("supervise-daemon", "supervise-daemon", svcname, "--reexec",
 | 
				
			||||||
@@ -180,7 +180,7 @@ static void handle_signal(int sig)
 | 
				
			|||||||
	/* Restore errno */
 | 
						/* Restore errno */
 | 
				
			||||||
	errno = serrno;
 | 
						errno = serrno;
 | 
				
			||||||
	if (! exiting)
 | 
						if (! exiting)
 | 
				
			||||||
		re_exec_supervisor();
 | 
							re_exec();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static char * expand_home(const char *home, const char *path)
 | 
					static char * expand_home(const char *home, const char *path)
 | 
				
			||||||
@@ -224,23 +224,6 @@ static char * expand_home(const char *home, const char *path)
 | 
				
			|||||||
	return nh;
 | 
						return nh;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static char *make_cmdline(char **argv)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	char **c;
 | 
					 | 
				
			||||||
	char *cmdline = NULL;
 | 
					 | 
				
			||||||
	size_t len = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for (c = argv; c && *c; c++)
 | 
					 | 
				
			||||||
		len += (strlen(*c) + 1);
 | 
					 | 
				
			||||||
	cmdline = xmalloc(len+1);
 | 
					 | 
				
			||||||
	memset(cmdline, 0, len+1);
 | 
					 | 
				
			||||||
	for (c = argv; c && *c; c++) {
 | 
					 | 
				
			||||||
		strcat(cmdline, *c);
 | 
					 | 
				
			||||||
		strcat(cmdline, " ");
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return cmdline;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void child_process(char *exec, char **argv)
 | 
					static void child_process(char *exec, char **argv)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	RC_STRINGLIST *env_list;
 | 
						RC_STRINGLIST *env_list;
 | 
				
			||||||
@@ -251,7 +234,8 @@ static void child_process(char *exec, char **argv)
 | 
				
			|||||||
	size_t len;
 | 
						size_t len;
 | 
				
			||||||
	char *newpath;
 | 
						char *newpath;
 | 
				
			||||||
	char *np;
 | 
						char *np;
 | 
				
			||||||
	char *cmdline = NULL;
 | 
						char **c;
 | 
				
			||||||
 | 
						char cmdline[PATH_MAX];
 | 
				
			||||||
	time_t start_time;
 | 
						time_t start_time;
 | 
				
			||||||
	char start_count_string[20];
 | 
						char start_count_string[20];
 | 
				
			||||||
	char start_time_string[20];
 | 
						char start_time_string[20];
 | 
				
			||||||
@@ -411,9 +395,15 @@ static void child_process(char *exec, char **argv)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	for (i = getdtablesize() - 1; i >= 3; --i)
 | 
						for (i = getdtablesize() - 1; i >= 3; --i)
 | 
				
			||||||
		fcntl(i, F_SETFD, FD_CLOEXEC);
 | 
							fcntl(i, F_SETFD, FD_CLOEXEC);
 | 
				
			||||||
	cmdline = make_cmdline(argv);
 | 
					
 | 
				
			||||||
 | 
						*cmdline = '\0';
 | 
				
			||||||
 | 
						c = argv;
 | 
				
			||||||
 | 
						while (c && *c) {
 | 
				
			||||||
 | 
							strcat(cmdline, *c);
 | 
				
			||||||
 | 
							strcat(cmdline, " ");
 | 
				
			||||||
 | 
							c++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	syslog(LOG_INFO, "Child command line: %s", cmdline);
 | 
						syslog(LOG_INFO, "Child command line: %s", cmdline);
 | 
				
			||||||
	free(cmdline);
 | 
					 | 
				
			||||||
	execvp(exec, argv);
 | 
						execvp(exec, argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef HAVE_PAM
 | 
					#ifdef HAVE_PAM
 | 
				
			||||||
@@ -445,9 +435,7 @@ static void supervisor(char *exec, char **argv)
 | 
				
			|||||||
	signal_setup_restart(SIGUSR1, handle_signal);
 | 
						signal_setup_restart(SIGUSR1, handle_signal);
 | 
				
			||||||
	signal_setup_restart(SIGUSR2, handle_signal);
 | 
						signal_setup_restart(SIGUSR2, handle_signal);
 | 
				
			||||||
	signal_setup_restart(SIGBUS, handle_signal);
 | 
						signal_setup_restart(SIGBUS, handle_signal);
 | 
				
			||||||
#ifdef SIGPOLL
 | 
					 | 
				
			||||||
	signal_setup_restart(SIGPOLL, handle_signal);
 | 
						signal_setup_restart(SIGPOLL, handle_signal);
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
	signal_setup_restart(SIGPROF, handle_signal);
 | 
						signal_setup_restart(SIGPROF, handle_signal);
 | 
				
			||||||
	signal_setup_restart(SIGSYS, handle_signal);
 | 
						signal_setup_restart(SIGSYS, handle_signal);
 | 
				
			||||||
	signal_setup_restart(SIGTRAP, handle_signal);
 | 
						signal_setup_restart(SIGTRAP, handle_signal);
 | 
				
			||||||
@@ -458,9 +446,7 @@ static void supervisor(char *exec, char **argv)
 | 
				
			|||||||
	signal_setup_restart(SIGEMT, handle_signal);
 | 
						signal_setup_restart(SIGEMT, handle_signal);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	signal_setup_restart(SIGIO, handle_signal);
 | 
						signal_setup_restart(SIGIO, handle_signal);
 | 
				
			||||||
#ifdef SIGPWR
 | 
					 | 
				
			||||||
	signal_setup_restart(SIGPWR, handle_signal);
 | 
						signal_setup_restart(SIGPWR, handle_signal);
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#ifdef SIGUNUSED
 | 
					#ifdef SIGUNUSED
 | 
				
			||||||
	signal_setup_restart(SIGUNUSED, handle_signal);
 | 
						signal_setup_restart(SIGUNUSED, handle_signal);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@@ -561,8 +547,8 @@ int main(int argc, char **argv)
 | 
				
			|||||||
	char *token;
 | 
						char *token;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	int n;
 | 
						int n;
 | 
				
			||||||
	char *exec_file = NULL;
 | 
						char exec_file[PATH_MAX];
 | 
				
			||||||
	char *varbuf = NULL;
 | 
						char name[PATH_MAX];
 | 
				
			||||||
	struct timespec ts;
 | 
						struct timespec ts;
 | 
				
			||||||
	struct passwd *pw;
 | 
						struct passwd *pw;
 | 
				
			||||||
	struct group *gr;
 | 
						struct group *gr;
 | 
				
			||||||
@@ -571,7 +557,7 @@ int main(int argc, char **argv)
 | 
				
			|||||||
	int child_argc = 0;
 | 
						int child_argc = 0;
 | 
				
			||||||
	char **child_argv = NULL;
 | 
						char **child_argv = NULL;
 | 
				
			||||||
	char *str = NULL;
 | 
						char *str = NULL;
 | 
				
			||||||
	char *cmdline = NULL;
 | 
						char cmdline[PATH_MAX];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	applet = basename_c(argv[0]);
 | 
						applet = basename_c(argv[0]);
 | 
				
			||||||
	atexit(cleanup);
 | 
						atexit(cleanup);
 | 
				
			||||||
@@ -581,8 +567,7 @@ int main(int argc, char **argv)
 | 
				
			|||||||
	openlog(applet, LOG_PID, LOG_DAEMON);
 | 
						openlog(applet, LOG_PID, LOG_DAEMON);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (argc >= 1 && svcname && strcmp(argv[1], svcname))
 | 
						if (argc >= 1 && svcname && strcmp(argv[1], svcname))
 | 
				
			||||||
		eerrorx("%s: the first argument is %s and must be %s",
 | 
							eerrorx("%s: the first argument must be %s", applet, svcname);
 | 
				
			||||||
				applet, argv[1], svcname);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((tmp = getenv("SSD_NICELEVEL")))
 | 
						if ((tmp = getenv("SSD_NICELEVEL")))
 | 
				
			||||||
		if (sscanf(tmp, "%d", &nicelevel) != 1)
 | 
							if (sscanf(tmp, "%d", &nicelevel) != 1)
 | 
				
			||||||
@@ -604,7 +589,13 @@ int main(int argc, char **argv)
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cmdline = make_cmdline(argv);
 | 
						*cmdline = '\0';
 | 
				
			||||||
 | 
						c = argv;
 | 
				
			||||||
 | 
						while (c && *c) {
 | 
				
			||||||
 | 
							strcat(cmdline, *c);
 | 
				
			||||||
 | 
							strcat(cmdline, " ");
 | 
				
			||||||
 | 
							c++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if (svcname) {
 | 
						if (svcname) {
 | 
				
			||||||
		argc--;
 | 
							argc--;
 | 
				
			||||||
		argv++;
 | 
							argv++;
 | 
				
			||||||
@@ -766,11 +757,9 @@ int main(int argc, char **argv)
 | 
				
			|||||||
		child_argv = xmalloc((child_argc + 1) * sizeof(char *));
 | 
							child_argv = xmalloc((child_argc + 1) * sizeof(char *));
 | 
				
			||||||
		memset(child_argv, 0, (child_argc + 1) * sizeof(char *));
 | 
							memset(child_argv, 0, (child_argc + 1) * sizeof(char *));
 | 
				
			||||||
		for (x = 0; x < child_argc; x++) {
 | 
							for (x = 0; x < child_argc; x++) {
 | 
				
			||||||
			xasprintf(&varbuf, "argv_%d", x);
 | 
								sprintf(name, "argv_%d", x);
 | 
				
			||||||
			str = rc_service_value_get(svcname, varbuf);
 | 
								str = rc_service_value_get(svcname, name);
 | 
				
			||||||
			child_argv[x] = str;
 | 
								child_argv[x] = str;
 | 
				
			||||||
			free(varbuf);
 | 
					 | 
				
			||||||
			varbuf = NULL;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		free(str);
 | 
							free(str);
 | 
				
			||||||
		str = rc_service_value_get(svcname, "child_pid");
 | 
							str = rc_service_value_get(svcname, "child_pid");
 | 
				
			||||||
@@ -799,31 +788,32 @@ int main(int argc, char **argv)
 | 
				
			|||||||
			if (*exec == '/' || *exec == '.') {
 | 
								if (*exec == '/' || *exec == '.') {
 | 
				
			||||||
				/* Full or relative path */
 | 
									/* Full or relative path */
 | 
				
			||||||
				if (ch_root)
 | 
									if (ch_root)
 | 
				
			||||||
					xasprintf(&exec_file, "%s/%s", ch_root, exec);
 | 
										snprintf(exec_file, sizeof(exec_file),
 | 
				
			||||||
 | 
									    	"%s/%s", ch_root, exec);
 | 
				
			||||||
				else
 | 
									else
 | 
				
			||||||
					xasprintf(&exec_file, "%s", exec);
 | 
										snprintf(exec_file, sizeof(exec_file),
 | 
				
			||||||
 | 
									    "%s", exec);
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				/* Something in $PATH */
 | 
									/* Something in $PATH */
 | 
				
			||||||
				p = tmp = xstrdup(getenv("PATH"));
 | 
									p = tmp = xstrdup(getenv("PATH"));
 | 
				
			||||||
				exec_file = NULL;
 | 
									*exec_file = '\0';
 | 
				
			||||||
				while ((token = strsep(&p, ":"))) {
 | 
									while ((token = strsep(&p, ":"))) {
 | 
				
			||||||
					if (ch_root)
 | 
										if (ch_root)
 | 
				
			||||||
						xasprintf(&exec_file, "%s/%s/%s", ch_root, token, exec);
 | 
											snprintf(exec_file, sizeof(exec_file),
 | 
				
			||||||
 | 
										    	"%s/%s/%s",
 | 
				
			||||||
 | 
										    	ch_root, token, exec);
 | 
				
			||||||
					else
 | 
										else
 | 
				
			||||||
						xasprintf(&exec_file, "%s/%s", token, exec);
 | 
											snprintf(exec_file, sizeof(exec_file),
 | 
				
			||||||
					if (exec_file && exists(exec_file))
 | 
										    	"%s/%s", token, exec);
 | 
				
			||||||
 | 
										if (exists(exec_file))
 | 
				
			||||||
						break;
 | 
											break;
 | 
				
			||||||
					free(exec_file);
 | 
										*exec_file = '\0';
 | 
				
			||||||
					exec_file = NULL;
 | 
					 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				free(tmp);
 | 
									free(tmp);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (!exists(exec_file)) {
 | 
								if ( !exists(exec_file))
 | 
				
			||||||
				eerror("%s: %s does not exist", applet,
 | 
									eerrorx("%s: %s does not exist", applet,
 | 
				
			||||||
				    *exec_file ? exec_file : exec);
 | 
									    *exec_file ? exec_file : exec);
 | 
				
			||||||
				free(exec_file);
 | 
					 | 
				
			||||||
				exit(EXIT_FAILURE);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		} else
 | 
							} else
 | 
				
			||||||
			eerrorx("%s: nothing to start", applet);
 | 
								eerrorx("%s: nothing to start", applet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -846,8 +836,6 @@ int main(int argc, char **argv)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		einfov("Detaching to start `%s'", exec);
 | 
							einfov("Detaching to start `%s'", exec);
 | 
				
			||||||
		syslog(LOG_INFO, "Supervisor command line: %s", cmdline);
 | 
							syslog(LOG_INFO, "Supervisor command line: %s", cmdline);
 | 
				
			||||||
		free(cmdline);
 | 
					 | 
				
			||||||
		cmdline = NULL;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Remove existing pidfile */
 | 
							/* Remove existing pidfile */
 | 
				
			||||||
		if (pidfile)
 | 
							if (pidfile)
 | 
				
			||||||
@@ -860,13 +848,12 @@ int main(int argc, char **argv)
 | 
				
			|||||||
		fclose(fp);
 | 
							fclose(fp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		rc_service_value_set(svcname, "pidfile", pidfile);
 | 
							rc_service_value_set(svcname, "pidfile", pidfile);
 | 
				
			||||||
		varbuf = NULL;
 | 
							sprintf(name, "%i", respawn_delay);
 | 
				
			||||||
		xasprintf(&varbuf, "%i", respawn_delay);
 | 
							rc_service_value_set(svcname, "respawn_delay", name);
 | 
				
			||||||
		rc_service_value_set(svcname, "respawn_delay", varbuf);
 | 
							sprintf(name, "%i", respawn_max);
 | 
				
			||||||
		xasprintf(&varbuf, "%i", respawn_max);
 | 
							rc_service_value_set(svcname, "respawn_max", name);
 | 
				
			||||||
		rc_service_value_set(svcname, "respawn_max", varbuf);
 | 
							sprintf(name, "%i", respawn_period);
 | 
				
			||||||
		xasprintf(&varbuf, "%i", respawn_period);
 | 
							rc_service_value_set(svcname, "respawn_period", name);
 | 
				
			||||||
		rc_service_value_set(svcname, "respawn_period", varbuf);
 | 
					 | 
				
			||||||
		child_pid = fork();
 | 
							child_pid = fork();
 | 
				
			||||||
		if (child_pid == -1)
 | 
							if (child_pid == -1)
 | 
				
			||||||
			eerrorx("%s: fork: %s", applet, strerror(errno));
 | 
								eerrorx("%s: fork: %s", applet, strerror(errno));
 | 
				
			||||||
@@ -884,16 +871,13 @@ int main(int argc, char **argv)
 | 
				
			|||||||
			c = argv;
 | 
								c = argv;
 | 
				
			||||||
			x = 0;
 | 
								x = 0;
 | 
				
			||||||
			while (c && *c) {
 | 
								while (c && *c) {
 | 
				
			||||||
				varbuf = NULL;
 | 
									snprintf(name, sizeof(name), "argv_%-d",x);
 | 
				
			||||||
				xasprintf(&varbuf, "argv_%-d",x);
 | 
									rc_service_value_set(svcname, name, *c);
 | 
				
			||||||
				rc_service_value_set(svcname, varbuf, *c);
 | 
					 | 
				
			||||||
				free(varbuf);
 | 
					 | 
				
			||||||
				varbuf = NULL;
 | 
					 | 
				
			||||||
				x++;
 | 
									x++;
 | 
				
			||||||
				c++;
 | 
									c++;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			xasprintf(&varbuf, "%d", x);
 | 
								sprintf(name, "%d", x);
 | 
				
			||||||
				rc_service_value_set(svcname, "argc", varbuf);
 | 
									rc_service_value_set(svcname, "argc", name);
 | 
				
			||||||
			rc_service_value_set(svcname, "exec", exec);
 | 
								rc_service_value_set(svcname, "exec", exec);
 | 
				
			||||||
			supervisor(exec, argv);
 | 
								supervisor(exec, argv);
 | 
				
			||||||
		} else
 | 
							} else
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,4 @@
 | 
				
			|||||||
Using supervise-daemon
 | 
					# Using supervise-daemon
 | 
				
			||||||
======================
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Beginning with OpenRC-0.21 we have our own daemon supervisor,
 | 
					Beginning with OpenRC-0.21 we have our own daemon supervisor,
 | 
				
			||||||
supervise-daemon., which can start a daemon and restart it if it
 | 
					supervise-daemon., which can start a daemon and restart it if it
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,4 @@
 | 
				
			|||||||
deptree2dot - Graph the OpenRC Dependency Tree
 | 
					# deptree2dot - Graph the OpenRC Dependency Tree
 | 
				
			||||||
==============================================
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
This utility can be used to graph the OpenRC dependency tree. It
 | 
					This utility can be used to graph the OpenRC dependency tree. It
 | 
				
			||||||
requires perl5.x and converts the tree to a .dot file which can be
 | 
					requires perl5.x and converts the tree to a .dot file which can be
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,5 +7,7 @@ BIN=	${OBJS}
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
MK=	../../mk
 | 
					MK=	../../mk
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SED_EXTRA+= -e 's:@VARBASE@:/var:g'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
include ${MK}/os.mk
 | 
					include ${MK}/os.mk
 | 
				
			||||||
include ${MK}/scripts.mk
 | 
					include ${MK}/scripts.mk
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,3 @@
 | 
				
			|||||||
Example OpenRC Service Scripts
 | 
					 | 
				
			||||||
##############################
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The service scripts in this directory are meant as examples only.
 | 
					The service scripts in this directory are meant as examples only.
 | 
				
			||||||
They are not installed by default as the scripts will need tweaking on a
 | 
					They are not installed by default as the scripts will need tweaking on a
 | 
				
			||||||
per distro basis. They are also non essential to the operation of the system.
 | 
					per distro basis. They are also non essential to the operation of the system.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
command=@PKG_PREFIX@/sbin/avahi-dnsconfd
 | 
					command=@PKG_PREFIX@/sbin/avahi-dnsconfd
 | 
				
			||||||
command_args="$avahi_dnsconfd_args -D"
 | 
					command_args="$avahi_dnsconfd_args -D"
 | 
				
			||||||
pidfile=/var/run/avahi-dnsconfd.pid
 | 
					pidfile=@VARBASE@/run/avahi-dnsconfd.pid
 | 
				
			||||||
name="Avahi DNS Configuration Daemon"
 | 
					name="Avahi DNS Configuration Daemon"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
depend()
 | 
					depend()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
command=@PKG_PREFIX@/sbin/avahi-daemon
 | 
					command=@PKG_PREFIX@/sbin/avahi-daemon
 | 
				
			||||||
command_args="$avahid_args -D"
 | 
					command_args="$avahid_args -D"
 | 
				
			||||||
pidfile=/var/run/avahi-daemon/pid
 | 
					pidfile=@VARBASE@/run/avahi-daemon/pid
 | 
				
			||||||
name="Avahi Service Advertisement Daemon"
 | 
					name="Avahi Service Advertisement Daemon"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
depend()
 | 
					depend()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,7 +10,7 @@
 | 
				
			|||||||
# except according to the terms contained in the LICENSE file.
 | 
					# except according to the terms contained in the LICENSE file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
command=@PKG_PREFIX@/bin/dbus-daemon
 | 
					command=@PKG_PREFIX@/bin/dbus-daemon
 | 
				
			||||||
pidfile=/var/run/dbus/pid
 | 
					pidfile=@VARBASE@/run/dbus/pid
 | 
				
			||||||
command_args="${dbusd_args---system}"
 | 
					command_args="${dbusd_args---system}"
 | 
				
			||||||
name="Message Bus Daemon"
 | 
					name="Message Bus Daemon"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
command=@PKG_PREFIX@/sbin/dnsmasq
 | 
					command=@PKG_PREFIX@/sbin/dnsmasq
 | 
				
			||||||
command_args=$dnsmasq_args
 | 
					command_args=$dnsmasq_args
 | 
				
			||||||
pidfile=/var/run/dnsmasq.pid
 | 
					pidfile=@VARBASE@/run/dnsmasq.pid
 | 
				
			||||||
required_files=/etc/dnsmasq.conf
 | 
					required_files=/etc/dnsmasq.conf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extra_started_commands="reload"
 | 
					extra_started_commands="reload"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,7 +10,7 @@
 | 
				
			|||||||
# except according to the terms contained in the LICENSE file.
 | 
					# except according to the terms contained in the LICENSE file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
command=@PKG_PREFIX@/sbin/hald
 | 
					command=@PKG_PREFIX@/sbin/hald
 | 
				
			||||||
pidfile=/var/run/hald/hald.pid
 | 
					pidfile=@VARBASE@/run/hald/hald.pid
 | 
				
			||||||
command_args=$hald_args
 | 
					command_args=$hald_args
 | 
				
			||||||
name="Hardware Abstraction Layer Daemon"
 | 
					name="Hardware Abstraction Layer Daemon"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
command=/usr/sbin/named
 | 
					command=/usr/sbin/named
 | 
				
			||||||
command_args=$named_args
 | 
					command_args=$named_args
 | 
				
			||||||
pidfile=/var/run/named.pid
 | 
					pidfile=@VARBASE@/run/named.pid
 | 
				
			||||||
name="Domain Name server"
 | 
					name="Domain Name server"
 | 
				
			||||||
extra_started_commands="reload"
 | 
					extra_started_commands="reload"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -20,7 +20,7 @@ uid=named
 | 
				
			|||||||
case "$RC_UNAME" in
 | 
					case "$RC_UNAME" in
 | 
				
			||||||
	FreeBSD)
 | 
						FreeBSD)
 | 
				
			||||||
		uid=bind
 | 
							uid=bind
 | 
				
			||||||
		pidfile=/var/run/named/pid
 | 
							pidfile=@VARBASE@/run/named/pid
 | 
				
			||||||
		;;
 | 
							;;
 | 
				
			||||||
	Linux)
 | 
						Linux)
 | 
				
			||||||
		uid=bind
 | 
							uid=bind
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,7 @@ name="OpenVPN"
 | 
				
			|||||||
[ "$vpn" != openvpn ] && name="$name ($vpn)"
 | 
					[ "$vpn" != openvpn ] && name="$name ($vpn)"
 | 
				
			||||||
command=@PKG_PREFIX@/sbin/openvpn
 | 
					command=@PKG_PREFIX@/sbin/openvpn
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pidfile=/var/run/"$RC_SVCNAME".pid
 | 
					pidfile=@VARBASE@/run/"$RC_SVCNAME".pid
 | 
				
			||||||
: ${openvpn_dir:=@PKG_PREFIX@/etc/openvpn}
 | 
					: ${openvpn_dir:=@PKG_PREFIX@/etc/openvpn}
 | 
				
			||||||
: ${openvpn_config:=$openvpn_dir/$vpn.conf}
 | 
					: ${openvpn_config:=$openvpn_dir/$vpn.conf}
 | 
				
			||||||
command_args="$openvpn_args --daemon --config $openvpn_config"
 | 
					command_args="$openvpn_args --daemon --config $openvpn_config"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,7 +10,7 @@
 | 
				
			|||||||
# except according to the terms contained in the LICENSE file.
 | 
					# except according to the terms contained in the LICENSE file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
command=@PKG_PREFIX@/sbin/polkitd
 | 
					command=@PKG_PREFIX@/sbin/polkitd
 | 
				
			||||||
pidfile=/var/run/polkitd/polkitd.pid
 | 
					pidfile=@VARBASE@/run/polkitd/polkitd.pid
 | 
				
			||||||
command_args="$polkitd_args"
 | 
					command_args="$polkitd_args"
 | 
				
			||||||
name="PolicyKit Daemon"
 | 
					name="PolicyKit Daemon"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
command=/usr/sbin/sshd
 | 
					command=/usr/sbin/sshd
 | 
				
			||||||
command_args=$sshd_args
 | 
					command_args=$sshd_args
 | 
				
			||||||
pidfile=/var/run/sshd.pid
 | 
					pidfile=@VARBASE@/run/sshd.pid
 | 
				
			||||||
required_files=/etc/ssh/sshd_config
 | 
					required_files=/etc/ssh/sshd_config
 | 
				
			||||||
 | 
					
 | 
				
			||||||
depend()
 | 
					depend()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,3 @@
 | 
				
			|||||||
Example OpenVPN Scripts
 | 
					 | 
				
			||||||
=======================
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
These handy scripts setup any dns information that OpenVPN may push.
 | 
					These handy scripts setup any dns information that OpenVPN may push.
 | 
				
			||||||
They also handle the interaction with OpenRC so that the OpenVPN service
 | 
					They also handle the interaction with OpenRC so that the OpenVPN service
 | 
				
			||||||
can become "inactive". This means that when it starts, it goes inactive and
 | 
					can become "inactive". This means that when it starts, it goes inactive and
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,2 @@
 | 
				
			|||||||
OpenRC Sysvinit Support
 | 
					 | 
				
			||||||
========================
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Here's a sample inittab for use with sysvinit for Linux based systems.
 | 
					Here's a sample inittab for use with sysvinit for Linux based systems.
 | 
				
			||||||
We don't install it by default as sysvinit packages normally own this file.
 | 
					We don't install it by default as sysvinit packages normally own this file.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +0,0 @@
 | 
				
			|||||||
DIR=	${ZSHCOMPDIR}
 | 
					 | 
				
			||||||
CONF=	_openrc \
 | 
					 | 
				
			||||||
		_rc-service \
 | 
					 | 
				
			||||||
		_rc-status \
 | 
					 | 
				
			||||||
		_rc-update \
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
MK=	../mk
 | 
					 | 
				
			||||||
include ${MK}/os.mk
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
include ${MK}/scripts.mk
 | 
					 | 
				
			||||||
@@ -1,7 +0,0 @@
 | 
				
			|||||||
#compdef openrc
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if (( CURRENT == 2 )); then
 | 
					 | 
				
			||||||
	_values "runlevels" $(rc-status --list)
 | 
					 | 
				
			||||||
fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# vim: set et sw=2 ts=2 ft=zsh:
 | 
					 | 
				
			||||||
@@ -1,27 +0,0 @@
 | 
				
			|||||||
#compdef rc-service
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if (( CURRENT == 2 )); then
 | 
					 | 
				
			||||||
  _arguments -s \
 | 
					 | 
				
			||||||
    '(-e --exists)'{-e,--exists}"[tests if the service exists or not]" \
 | 
					 | 
				
			||||||
    '(-l --list)'{-l,--list}'[list all available services]' \
 | 
					 | 
				
			||||||
    '(-r --resolve)'{-r,--resolve}'[resolve the service name to an init script]' \
 | 
					 | 
				
			||||||
    '(-C --nocolor)'{-C,--nocolor}'[Disable color output]' \
 | 
					 | 
				
			||||||
    '(-v --verbose)'{-v,--verbose}'[Run verbosely]' \
 | 
					 | 
				
			||||||
    '(-q --quiet)'{-q,--quiet}'[Run quietly]'
 | 
					 | 
				
			||||||
  _values "service" $(rc-service --list)
 | 
					 | 
				
			||||||
else
 | 
					 | 
				
			||||||
  case $words[2] in
 | 
					 | 
				
			||||||
    -e|--exists|-r|--resolve)
 | 
					 | 
				
			||||||
      (( CURRENT > 3 )) && return 0
 | 
					 | 
				
			||||||
	  _values "service" $(rc-service --list)
 | 
					 | 
				
			||||||
      ;;
 | 
					 | 
				
			||||||
    -*)
 | 
					 | 
				
			||||||
          return 0
 | 
					 | 
				
			||||||
          ;;
 | 
					 | 
				
			||||||
    *)
 | 
					 | 
				
			||||||
      _values "action" stop start restart describe zap
 | 
					 | 
				
			||||||
  ;;
 | 
					 | 
				
			||||||
  esac
 | 
					 | 
				
			||||||
fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# vim: set et sw=2 ts=2 ft=zsh:
 | 
					 | 
				
			||||||
@@ -1,18 +0,0 @@
 | 
				
			|||||||
#compdef rc-status
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
_arguments -s \
 | 
					 | 
				
			||||||
  {'(--all)-a','(-a)--all'}'[Show services at all runlevels]' \
 | 
					 | 
				
			||||||
  {'(--crashed)-c','(-c)--crashed'}'[Show crashed services]' \
 | 
					 | 
				
			||||||
  {'(--list)-l','(-l)--list'}'[Show list of runlevels]' \
 | 
					 | 
				
			||||||
  {'(--runlevel)-r','(-r)--runlevel'}'[Show the name of the current runlevel]' \
 | 
					 | 
				
			||||||
  {'(--servicelist)-s','(-s)--servicelist'}'[Show all services]' \
 | 
					 | 
				
			||||||
  {'(--unused)-u','(-u)--unused'}'[Show services not assigned to any run level]' \
 | 
					 | 
				
			||||||
  {'(--help)-h','(-h)--help'}'[Print this help output]' \
 | 
					 | 
				
			||||||
  {'(--nocolor)-C','(-C)--nocolor'}'[Disable color output]' \
 | 
					 | 
				
			||||||
  {'(--version)-V','(-V)--version'}'[Display software version]' \
 | 
					 | 
				
			||||||
  {'(--verbose)-v','(-v)--verbose'}'[Run verbosely]' \
 | 
					 | 
				
			||||||
  {'(--quiet)-q','(-q)--quiet'}'[Run quietly (Does not affect errors)]'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
_values 'runlevels' $(rc-status --list)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# vim: set et sw=2 ts=2 ft=zsh:
 | 
					 | 
				
			||||||
@@ -1,31 +0,0 @@
 | 
				
			|||||||
#compdef rc-update
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
local used_init
 | 
					 | 
				
			||||||
used_init=(${=${(M)${(f)"$(rc-update show 2>/dev/null)"}:#*|*[a-z]*}% |*})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if (( CURRENT == 2 )); then
 | 
					 | 
				
			||||||
  _values "rc-update actions" \
 | 
					 | 
				
			||||||
    'add[Add script to a runlevel]' \
 | 
					 | 
				
			||||||
    'del[Delete script from a runlevel]' \
 | 
					 | 
				
			||||||
    'show[Show scripts in  a runlevel]' \
 | 
					 | 
				
			||||||
    '-a[Process all runlevels]' \
 | 
					 | 
				
			||||||
    '-s[Stack a runlevel instead of a service]'
 | 
					 | 
				
			||||||
elif (( CURRENT == 3 )); then
 | 
					 | 
				
			||||||
  case "$words[2]" in
 | 
					 | 
				
			||||||
    add)
 | 
					 | 
				
			||||||
      _values "service" $(rc-service --list)
 | 
					 | 
				
			||||||
      ;;
 | 
					 | 
				
			||||||
    del)
 | 
					 | 
				
			||||||
      _values "service" $used_init
 | 
					 | 
				
			||||||
      ;;
 | 
					 | 
				
			||||||
    show)
 | 
					 | 
				
			||||||
      _values "runlevels" $(rc-status --list) \
 | 
					 | 
				
			||||||
        '-v[Show all service scripts]' \
 | 
					 | 
				
			||||||
        '--verbose[Show all service scripts]'
 | 
					 | 
				
			||||||
      ;;
 | 
					 | 
				
			||||||
  esac
 | 
					 | 
				
			||||||
elif (( CURRENT == 4 )); then
 | 
					 | 
				
			||||||
  _values "runlevels" $(rc-status --list)
 | 
					 | 
				
			||||||
fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# vim: set et sw=2 ts=2 ft=zsh:
 | 
					 | 
				
			||||||
		Reference in New Issue
	
	Block a user