Compare commits
	
		
			3 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					5dce6f57d9 | ||
| 
						 | 
					8122e2d8f4 | ||
| 
						 | 
					ff07754be2 | 
							
								
								
									
										14
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								.travis.yml
									
									
									
									
									
								
							@@ -1,14 +0,0 @@
 | 
				
			|||||||
# Travis build integration.
 | 
					 | 
				
			||||||
# https://docs.travis-ci.com/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
language: c
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
os:
 | 
					 | 
				
			||||||
  - linux
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
compiler:
 | 
					 | 
				
			||||||
  - gcc
 | 
					 | 
				
			||||||
  - clang
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
script:
 | 
					 | 
				
			||||||
  - ./test/travis.sh
 | 
					 | 
				
			||||||
@@ -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.40.3
 | 
					VERSION=	0.33.1
 | 
				
			||||||
PKG=		${NAME}-${VERSION}
 | 
					PKG=		${NAME}-${VERSION}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										99
									
								
								NEWS.md
									
									
									
									
									
								
							
							
						
						
									
										99
									
								
								NEWS.md
									
									
									
									
									
								
							@@ -1,105 +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.40
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
In this version, the keymaps and termencoding services on Linux needed
 | 
					 | 
				
			||||||
to be modified so they do not write to the root file system. This was
 | 
					 | 
				
			||||||
done so they can run earlier in the boot sequence. AS a result, you will
 | 
					 | 
				
			||||||
need to add save-termencoding and save-keymaps to your boot runlevel.
 | 
					 | 
				
			||||||
This can be done as follows:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
# rc-update add save-keymaps boot
 | 
					 | 
				
			||||||
# rc-update add save-termencoding boot
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## OpenRC 0.39
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This version removes the support for addons.
 | 
					 | 
				
			||||||
The only place I know that this was used was Gentoo Baselayout 1.x, so
 | 
					 | 
				
			||||||
it shouldn't affect anyone since baselayout-1 has been dead for a few
 | 
					 | 
				
			||||||
years.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Since all supported Linux kernel versions now make efivarfs immutable
 | 
					 | 
				
			||||||
and all of the tools that access efivarfs are aware of this, we no
 | 
					 | 
				
			||||||
longer mount efivarfs read-only. See the following github issue for more
 | 
					 | 
				
			||||||
information:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
https://github.com/openrc/openrc/issues/238
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This version adds timed shutdown and cancelation of shutdown to
 | 
					 | 
				
			||||||
openrc-shutdown. Shutdowns can now be delayed for a certain amount of
 | 
					 | 
				
			||||||
time or scheduled for an exact time.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
supervise-daemon supports health checks, which are a periodic way to make sure a
 | 
					 | 
				
			||||||
service is healthy. For more information on setting this up, please see
 | 
					 | 
				
			||||||
supervise-daemon-guide.md.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The --first-time switch has been added to all modprobe commands in the
 | 
					 | 
				
			||||||
modules service. This means that, on Linux, you will see failures if a
 | 
					 | 
				
			||||||
module was loaded by an initramfs or device manager before this service
 | 
					 | 
				
			||||||
runs. These messages are harmless, but to clean them up, you should adjust your
 | 
					 | 
				
			||||||
modules autoload configuration.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## OpenRC 0.37
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
start-stop-daemon now supports logging stdout and stderr of daemons to
 | 
					 | 
				
			||||||
processes instead of files. These processes are defined by the
 | 
					 | 
				
			||||||
output_logger and error_logger variables in standard service scripts, or
 | 
					 | 
				
			||||||
by the  -3/--output-logger or -4/--error-logger switches if you use
 | 
					 | 
				
			||||||
start-stop-daemon directly. For more information on this, see the
 | 
					 | 
				
			||||||
start-stop-daemon man page.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## OpenRC 0.36
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
In this release, the modules-load service has been combined into the
 | 
					 | 
				
			||||||
modules service since there is no reason I know of to keep them
 | 
					 | 
				
			||||||
separate. However, modules also provides modules-load in case you were
 | 
					 | 
				
			||||||
using modules-load in  your dependencies.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The consolefont, keymaps, numlock and procfs service scripts no longer
 | 
					 | 
				
			||||||
have a dependency on localmount.
 | 
					 | 
				
			||||||
If you are a linux user and are still separaating / from /usr,
 | 
					 | 
				
			||||||
you will need to add the following line to the appropriate conf.d files:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
rc_need="localmount"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 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
 | 
					 | 
				
			||||||
@@ -8,6 +8,11 @@
 | 
				
			|||||||
#modules_2="ipv6"
 | 
					#modules_2="ipv6"
 | 
				
			||||||
#modules="ohci1394"
 | 
					#modules="ohci1394"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Linux users can give modules a different name when they load - the new name
 | 
				
			||||||
 | 
					# will also be used to pick arguments below.
 | 
				
			||||||
 | 
					# This is not supported on FreeBSD.
 | 
				
			||||||
 | 
					#modules="dummy:dummy1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Linux users can give the modules some arguments if needed, per version
 | 
					# Linux users can give the modules some arguments if needed, per version
 | 
				
			||||||
# if necessary.
 | 
					# if necessary.
 | 
				
			||||||
# Again, the most specific versioned variable will take precedence.
 | 
					# Again, the most specific versioned variable will take precedence.
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										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_cgroup_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,12 +83,121 @@ 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 `sysinit`, `boot`, and `default`,
 | 
					The default startup uses the runlevels `boot`, `sysinit` and `default`, in that 
 | 
				
			||||||
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`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -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
 | 
				
			||||||
@@ -162,9 +268,10 @@ stopped, by using:
 | 
				
			|||||||
The `rc_cgroup_cleanup` setting can be changed to yes to make this
 | 
					The `rc_cgroup_cleanup` setting can be changed to yes to make this
 | 
				
			||||||
happen automatically when the service is stopped.
 | 
					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
 | 
				
			||||||
@@ -174,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.
 | 
				
			||||||
							
								
								
									
										3
									
								
								init.d/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								init.d/.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,6 +1,5 @@
 | 
				
			|||||||
agetty
 | 
					agetty
 | 
				
			||||||
binfmt
 | 
					binfmt
 | 
				
			||||||
cgroups
 | 
					 | 
				
			||||||
modules-load
 | 
					modules-load
 | 
				
			||||||
bootmisc
 | 
					bootmisc
 | 
				
			||||||
fsck
 | 
					fsck
 | 
				
			||||||
@@ -41,8 +40,6 @@ rc-enabled
 | 
				
			|||||||
rpcbind
 | 
					rpcbind
 | 
				
			||||||
runsvdir
 | 
					runsvdir
 | 
				
			||||||
savecore
 | 
					savecore
 | 
				
			||||||
save-keymaps
 | 
					 | 
				
			||||||
save-termencoding
 | 
					 | 
				
			||||||
swap-blk
 | 
					swap-blk
 | 
				
			||||||
swclock
 | 
					swclock
 | 
				
			||||||
syslogd
 | 
					syslogd
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,12 +19,11 @@ SRCS-FreeBSD=	hostid.in modules.in moused.in newsyslog.in pf.in rarpd.in \
 | 
				
			|||||||
		rc-enabled.in rpcbind.in savecore.in syslogd.in
 | 
							rc-enabled.in rpcbind.in savecore.in syslogd.in
 | 
				
			||||||
# These are FreeBSD specific
 | 
					# These are FreeBSD specific
 | 
				
			||||||
SRCS-FreeBSD+=	adjkerntz.in devd.in dumpon.in encswap.in ipfw.in \
 | 
					SRCS-FreeBSD+=	adjkerntz.in devd.in dumpon.in encswap.in ipfw.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 \
 | 
						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 save-keymaps.in \
 | 
						numlock.in procfs.in net-online.in sysfs.in termencoding.in
 | 
				
			||||||
	save-termencoding.in sysfs.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 \
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,11 +12,11 @@
 | 
				
			|||||||
description="start agetty on a terminal line"
 | 
					description="start agetty on a terminal line"
 | 
				
			||||||
supervisor=supervise-daemon
 | 
					supervisor=supervise-daemon
 | 
				
			||||||
port="${RC_SVCNAME#*.}"
 | 
					port="${RC_SVCNAME#*.}"
 | 
				
			||||||
respawn_period="${respawn_period:-60}"
 | 
					 | 
				
			||||||
term_type="${term_type:-linux}"
 | 
					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
 | 
				
			||||||
@@ -29,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
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -13,7 +13,7 @@ description="Sets a font for the consoles."
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
depend()
 | 
					depend()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	need termencoding
 | 
						need localmount termencoding
 | 
				
			||||||
	after hotplug bootmisc modules
 | 
						after hotplug bootmisc modules
 | 
				
			||||||
	keyword -docker -lxc -openvz -prefix -systemd-nspawn -uml -vserver -xenu
 | 
						keyword -docker -lxc -openvz -prefix -systemd-nspawn -uml -vserver -xenu
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,8 +13,8 @@ description="Applies a keymap for the consoles."
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
depend()
 | 
					depend()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	need termencoding
 | 
						need localmount termencoding
 | 
				
			||||||
	after devfs
 | 
						after bootmisc clock
 | 
				
			||||||
	keyword -docker -lxc -openvz -prefix -systemd-nspawn -uml -vserver -xenu
 | 
						keyword -docker -lxc -openvz -prefix -systemd-nspawn -uml -vserver -xenu
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -68,5 +68,10 @@ start()
 | 
				
			|||||||
		echo "altgr keycode 18 = U+20AC" | loadkeys -q -
 | 
							echo "altgr keycode 18 = U+20AC" | loadkeys -q -
 | 
				
			||||||
		eend $?
 | 
							eend $?
 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
	return 0
 | 
					
 | 
				
			||||||
 | 
						# Save the keymapping for use immediately at boot
 | 
				
			||||||
 | 
						if checkpath -W "$RC_LIBEXECDIR"; then
 | 
				
			||||||
 | 
							mkdir -p "$RC_LIBEXECDIR"/console
 | 
				
			||||||
 | 
							dumpkeys >"$RC_LIBEXECDIR"/console/keymap
 | 
				
			||||||
 | 
						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
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										72
									
								
								init.d/modules-load.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								init.d/modules-load.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,72 @@
 | 
				
			|||||||
 | 
					#!@SBINDIR@/openrc-run
 | 
				
			||||||
 | 
					# Copyright (c) 2016 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="Loads a list of modules from systemd-compatible locations."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					depend()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						keyword -docker -lxc -openvz -prefix -systemd-nspawn -vserver
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					find_modfiles()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						local dirs="/usr/lib/modules-load.d /run/modules-load.d /etc/modules-load.d"
 | 
				
			||||||
 | 
						local basenames files fn x y
 | 
				
			||||||
 | 
						for x in $dirs; do
 | 
				
			||||||
 | 
							[ ! -d $x ] && continue
 | 
				
			||||||
 | 
							for y in $x/*.conf; do
 | 
				
			||||||
 | 
								[ -f $y ] && basenames="${basenames}\n${y##*/}"
 | 
				
			||||||
 | 
							done
 | 
				
			||||||
 | 
						done
 | 
				
			||||||
 | 
						basenames=$(printf "$basenames" | sort -u)
 | 
				
			||||||
 | 
						for x in $basenames; do
 | 
				
			||||||
 | 
							for y in $dirs; do
 | 
				
			||||||
 | 
								[ -r $y/$x ] &&
 | 
				
			||||||
 | 
									fn=$y/$x
 | 
				
			||||||
 | 
							done
 | 
				
			||||||
 | 
							files="$files $fn"
 | 
				
			||||||
 | 
						done
 | 
				
			||||||
 | 
						echo $files
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					load_modules()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						local file m modules rc x
 | 
				
			||||||
 | 
						file=$1
 | 
				
			||||||
 | 
						[ -z "$file" ] && return 0
 | 
				
			||||||
 | 
						while read m x; do
 | 
				
			||||||
 | 
							case $m in
 | 
				
			||||||
 | 
								\;*) continue ;;
 | 
				
			||||||
 | 
								\#*) continue ;;
 | 
				
			||||||
 | 
								*) modules="$modules $m"
 | 
				
			||||||
 | 
								;;
 | 
				
			||||||
 | 
							esac
 | 
				
			||||||
 | 
						done < $file
 | 
				
			||||||
 | 
						for x in $modules; do
 | 
				
			||||||
 | 
							ebegin "Loading module $x"
 | 
				
			||||||
 | 
							case "$RC_UNAME" in
 | 
				
			||||||
 | 
								FreeBSD) kldload "$x"; rc=$? ;;
 | 
				
			||||||
 | 
								Linux) modprobe --use-blacklist -q "$x"; rc=$? ;;
 | 
				
			||||||
 | 
								*) ;;
 | 
				
			||||||
 | 
							esac
 | 
				
			||||||
 | 
							eend $rc "Failed to load $x"
 | 
				
			||||||
 | 
						done
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					start()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						local x
 | 
				
			||||||
 | 
						files=$(find_modfiles)
 | 
				
			||||||
 | 
						for x in $files; do
 | 
				
			||||||
 | 
							load_modules $x
 | 
				
			||||||
 | 
						done
 | 
				
			||||||
 | 
						return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -14,66 +14,10 @@ description="Loads a user defined list of kernel modules."
 | 
				
			|||||||
depend()
 | 
					depend()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	use isapnp
 | 
						use isapnp
 | 
				
			||||||
	provide modules-load
 | 
						want modules-load
 | 
				
			||||||
	keyword -docker -lxc -openvz -prefix -systemd-nspawn -vserver
 | 
						keyword -docker -lxc -openvz -prefix -systemd-nspawn -vserver
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
find_modfiles()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	local dirs="/usr/lib/modules-load.d /run/modules-load.d /etc/modules-load.d"
 | 
					 | 
				
			||||||
	local basenames files fn x y
 | 
					 | 
				
			||||||
	for x in $dirs; do
 | 
					 | 
				
			||||||
		[ ! -d $x ] && continue
 | 
					 | 
				
			||||||
		for y in $x/*.conf; do
 | 
					 | 
				
			||||||
			[ -f $y ] && basenames="${basenames}\n${y##*/}"
 | 
					 | 
				
			||||||
		done
 | 
					 | 
				
			||||||
	done
 | 
					 | 
				
			||||||
	basenames=$(printf "$basenames" | sort -u)
 | 
					 | 
				
			||||||
	for x in $basenames; do
 | 
					 | 
				
			||||||
		for y in $dirs; do
 | 
					 | 
				
			||||||
			[ -r $y/$x ] &&
 | 
					 | 
				
			||||||
				fn=$y/$x
 | 
					 | 
				
			||||||
		done
 | 
					 | 
				
			||||||
		files="$files $fn"
 | 
					 | 
				
			||||||
	done
 | 
					 | 
				
			||||||
	echo $files
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
load_modules()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	local file m modules rc x
 | 
					 | 
				
			||||||
	file=$1
 | 
					 | 
				
			||||||
	[ -z "$file" ] && return 0
 | 
					 | 
				
			||||||
	while read m x; do
 | 
					 | 
				
			||||||
		case $m in
 | 
					 | 
				
			||||||
			\;*) continue ;;
 | 
					 | 
				
			||||||
			\#*) continue ;;
 | 
					 | 
				
			||||||
			*) modules="$modules $m"
 | 
					 | 
				
			||||||
			;;
 | 
					 | 
				
			||||||
		esac
 | 
					 | 
				
			||||||
	done < $file
 | 
					 | 
				
			||||||
	for x in $modules; do
 | 
					 | 
				
			||||||
		ebegin "Loading module $x"
 | 
					 | 
				
			||||||
		case "$RC_UNAME" in
 | 
					 | 
				
			||||||
			FreeBSD) kldload "$x"; rc=$? ;;
 | 
					 | 
				
			||||||
			Linux) modprobe --first-time -q --use-blacklist "$x"; rc=$? ;;
 | 
					 | 
				
			||||||
			*) ;;
 | 
					 | 
				
			||||||
		esac
 | 
					 | 
				
			||||||
		eend $rc "Failed to load $x"
 | 
					 | 
				
			||||||
	done
 | 
					 | 
				
			||||||
	return 0
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
modules_load_d()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	local x
 | 
					 | 
				
			||||||
	files=$(find_modfiles)
 | 
					 | 
				
			||||||
	for x in $files; do
 | 
					 | 
				
			||||||
		load_modules $x
 | 
					 | 
				
			||||||
	done
 | 
					 | 
				
			||||||
	return 0
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
FreeBSD_modules()
 | 
					FreeBSD_modules()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	local cnt=0 x
 | 
						local cnt=0 x
 | 
				
			||||||
@@ -104,7 +48,7 @@ Linux_modules()
 | 
				
			|||||||
		x=${x%.*}
 | 
							x=${x%.*}
 | 
				
			||||||
	done
 | 
						done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	local list= x= xx= y= args=
 | 
						local list= x= xx= y= args= mpargs= a=
 | 
				
			||||||
	for x in $kv_variant_list ; do
 | 
						for x in $kv_variant_list ; do
 | 
				
			||||||
		eval list=\$modules_$(shell_var "$x")
 | 
							eval list=\$modules_$(shell_var "$x")
 | 
				
			||||||
		[ -n "$list" ] && break
 | 
							[ -n "$list" ] && break
 | 
				
			||||||
@@ -113,13 +57,24 @@ Linux_modules()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	[ -n "$list" ] && ebegin "Loading kernel modules"
 | 
						[ -n "$list" ] && ebegin "Loading kernel modules"
 | 
				
			||||||
	for x in $list; do
 | 
						for x in $list; do
 | 
				
			||||||
 | 
							a=${x#*:}
 | 
				
			||||||
 | 
							if [ "$a" = "$x" ]; then
 | 
				
			||||||
 | 
								unset mpargs
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								x=${x%%:*}
 | 
				
			||||||
 | 
								mpargs="-o $a"
 | 
				
			||||||
 | 
							fi
 | 
				
			||||||
 | 
							aa=$(shell_var "$a")
 | 
				
			||||||
		xx=$(shell_var "$x")
 | 
							xx=$(shell_var "$x")
 | 
				
			||||||
		for y in $kv_variant_list ; do
 | 
							for y in $kv_variant_list ; do
 | 
				
			||||||
 | 
								eval args=\$module_${aa}_args_$(shell_var "$y")
 | 
				
			||||||
 | 
								[ -n "${args}" ] && break
 | 
				
			||||||
			eval args=\$module_${xx}_args_$(shell_var "$y")
 | 
								eval args=\$module_${xx}_args_$(shell_var "$y")
 | 
				
			||||||
			[ -n "${args}" ] && break
 | 
								[ -n "${args}" ] && break
 | 
				
			||||||
		done
 | 
							done
 | 
				
			||||||
 | 
							[ -z "$args" ] && eval args=\$module_${aa}_args
 | 
				
			||||||
		[ -z "$args" ] && eval args=\$module_${xx}_args
 | 
							[ -z "$args" ] && eval args=\$module_${xx}_args
 | 
				
			||||||
		eval modprobe --first-time --use-blacklist --verbose "$x" "$args"
 | 
							eval modprobe --use-blacklist --verbose "$mpargs" "$x" "$args"
 | 
				
			||||||
	done
 | 
						done
 | 
				
			||||||
	[ -n "$list" ] && eend
 | 
						[ -n "$list" ] && eend
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -127,10 +82,7 @@ Linux_modules()
 | 
				
			|||||||
start()
 | 
					start()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	case "$RC_UNAME" in
 | 
						case "$RC_UNAME" in
 | 
				
			||||||
		FreeBSD|Linux)
 | 
							FreeBSD|Linux) ${RC_UNAME}_modules ;;
 | 
				
			||||||
			modules_load_d
 | 
					 | 
				
			||||||
			${RC_UNAME}_modules
 | 
					 | 
				
			||||||
			;;
 | 
					 | 
				
			||||||
		*) ;;
 | 
							*) ;;
 | 
				
			||||||
	esac
 | 
						esac
 | 
				
			||||||
	return 0
 | 
						return 0
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,7 +13,7 @@ description="Delays until the network is online or a specific timeout"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
depend()
 | 
					depend()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	after modules net
 | 
						after modules
 | 
				
			||||||
	need sysfs
 | 
						need sysfs
 | 
				
			||||||
	provide network-online
 | 
						provide network-online
 | 
				
			||||||
	keyword -docker -jail -lxc -openvz -prefix -systemd-nspawn -uml -vserver
 | 
						keyword -docker -jail -lxc -openvz -prefix -systemd-nspawn -uml -vserver
 | 
				
			||||||
@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,6 +15,7 @@ ttyn=${rc_tty_number:-${RC_TTY_NUMBER:-12}}
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
depend()
 | 
					depend()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						need localmount
 | 
				
			||||||
	keyword -docker -lxc -openvz -prefix -systemd-nspawn -vserver
 | 
						keyword -docker -lxc -openvz -prefix -systemd-nspawn -vserver
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,6 +16,7 @@ depend()
 | 
				
			|||||||
	after clock
 | 
						after clock
 | 
				
			||||||
	use devfs
 | 
						use devfs
 | 
				
			||||||
	want modules
 | 
						want modules
 | 
				
			||||||
 | 
						need localmount
 | 
				
			||||||
	keyword -docker -lxc -openvz -prefix -systemd-nspawn -vserver
 | 
						keyword -docker -lxc -openvz -prefix -systemd-nspawn -vserver
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -26,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"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,28 +0,0 @@
 | 
				
			|||||||
#!@SBINDIR@/openrc-run
 | 
					 | 
				
			||||||
# Copyright (c) 2018 Sony Interactive Entertainment, Inc.
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# 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="Save the keymap for use as early as possible"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
depend()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	need termencoding
 | 
					 | 
				
			||||||
	after bootmisc clock keymaps
 | 
					 | 
				
			||||||
	keyword -docker -lxc -openvz -prefix -systemd-nspawn -uml -vserver -xenu
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
start()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	# Save the keymapping for use immediately at boot
 | 
					 | 
				
			||||||
	ebegin "Saving key mapping"
 | 
					 | 
				
			||||||
	if checkpath -W "$RC_LIBEXECDIR"; then
 | 
					 | 
				
			||||||
		mkdir -p "$RC_LIBEXECDIR"/console
 | 
					 | 
				
			||||||
		dumpkeys >"$RC_LIBEXECDIR"/console/keymap
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
	eend $? "Unable to save keymapping"
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,35 +0,0 @@
 | 
				
			|||||||
#!@SBINDIR@/openrc-run
 | 
					 | 
				
			||||||
# Copyright (c) 2018 Sony Interactive Entertainment, Inc.
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# 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="Configures terminal encoding."
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ttyn=${rc_tty_number:-${RC_TTY_NUMBER:-12}}
 | 
					 | 
				
			||||||
: ${unicode:=${UNICODE}}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
depend()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	keyword -docker -lxc -openvz -prefix -systemd-nspawn -uml -vserver -xenu
 | 
					 | 
				
			||||||
	use root
 | 
					 | 
				
			||||||
	after bootmisc clock termencoding
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
start()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	ebegin "Saving terminal encoding"
 | 
					 | 
				
			||||||
	# Save the encoding for use immediately at boot
 | 
					 | 
				
			||||||
	if checkpath -W "$RC_LIBEXECDIR"; then
 | 
					 | 
				
			||||||
		mkdir -p "$RC_LIBEXECDIR"/console
 | 
					 | 
				
			||||||
		if yesno ${unicode:-${UNICODE}}; then
 | 
					 | 
				
			||||||
			echo "" > "$RC_LIBEXECDIR"/console/unicode
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			rm -f "$RC_LIBEXECDIR"/console/unicode
 | 
					 | 
				
			||||||
		fi
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
	eend 0
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -49,7 +49,7 @@ start()
 | 
				
			|||||||
	fi
 | 
						fi
 | 
				
			||||||
	ebegin "Saving dependency cache"
 | 
						ebegin "Saving dependency cache"
 | 
				
			||||||
	local rc=0 save=
 | 
						local rc=0 save=
 | 
				
			||||||
	for x in depconfig deptree rc.log shutdowntime softlevel; do
 | 
						for x in shutdowntime softlevel rc.log; do
 | 
				
			||||||
		[ -e "$RC_SVCDIR/$x" ] && save="$save $RC_SVCDIR/$x"
 | 
							[ -e "$RC_SVCDIR/$x" ] && save="$save $RC_SVCDIR/$x"
 | 
				
			||||||
	done
 | 
						done
 | 
				
			||||||
	if [ -n "$save" ]; then
 | 
						if [ -n "$save" ]; then
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										114
									
								
								init.d/sysfs.in
									
									
									
									
									
								
							
							
						
						
									
										114
									
								
								init.d/sysfs.in
									
									
									
									
									
								
							@@ -101,17 +101,128 @@ mount_misc()
 | 
				
			|||||||
	if [ -d /sys/firmware/efi/efivars ] &&
 | 
						if [ -d /sys/firmware/efi/efivars ] &&
 | 
				
			||||||
		! mountinfo -q /sys/firmware/efi/efivars; then
 | 
							! mountinfo -q /sys/firmware/efi/efivars; then
 | 
				
			||||||
		ebegin "Mounting efivarfs filesystem"
 | 
							ebegin "Mounting efivarfs filesystem"
 | 
				
			||||||
		mount -n -t efivarfs -o ${sysfs_opts} \
 | 
							mount -n -t efivarfs -o ro \
 | 
				
			||||||
			efivarfs /sys/firmware/efi/efivars 2> /dev/null
 | 
								efivarfs /sys/firmware/efi/efivars 2> /dev/null
 | 
				
			||||||
		eend 0
 | 
							eend 0
 | 
				
			||||||
	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
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,7 +17,8 @@ ttyn=${rc_tty_number:-${RC_TTY_NUMBER:-12}}
 | 
				
			|||||||
depend()
 | 
					depend()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	keyword -docker -lxc -openvz -prefix -systemd-nspawn -uml -vserver -xenu
 | 
						keyword -docker -lxc -openvz -prefix -systemd-nspawn -uml -vserver -xenu
 | 
				
			||||||
	after devfs
 | 
						use root
 | 
				
			||||||
 | 
						after bootmisc clock
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
start()
 | 
					start()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
@@ -111,17 +111,11 @@ The path to the s6 service directory if you are monitoring this service
 | 
				
			|||||||
with S6. The default is /var/svc.d/${RC_SVCNAME}.
 | 
					with S6. The default is /var/svc.d/${RC_SVCNAME}.
 | 
				
			||||||
.It Ar s6_svwait_options_start
 | 
					.It Ar s6_svwait_options_start
 | 
				
			||||||
The options to pass to s6-svwait when starting the service via s6.
 | 
					The options to pass to s6-svwait when starting the service via s6.
 | 
				
			||||||
.It Ar s6_force_kill
 | 
					 | 
				
			||||||
Should we force-kill this service if s6_service_timeout_stop expires
 | 
					 | 
				
			||||||
but the service doesn't go down during shutdown? The default is yes.
 | 
					 | 
				
			||||||
.It Ar s6_service_timeout_stop
 | 
					.It Ar s6_service_timeout_stop
 | 
				
			||||||
The amount of time, in milliseconds, s6-svc should wait for the service
 | 
					The amount of time, in milliseconds, s6-svc should wait for the service
 | 
				
			||||||
to go down when stopping the service. The default is 60000.
 | 
					to go down when stopping the service. The default is 10000.
 | 
				
			||||||
.It Ar start_stop_daemon_args
 | 
					.It Ar start_stop_daemon_args
 | 
				
			||||||
List of arguments passed to start-stop-daemon when starting the daemon.
 | 
					List of arguments passed to start-stop-daemon when starting the daemon.
 | 
				
			||||||
.It Ar supervise_daemon_args
 | 
					 | 
				
			||||||
List of arguments passed to supervise-daemon when starting the daemon.
 | 
					 | 
				
			||||||
If undefined, start_stop_daemon_args is used as a fallback.
 | 
					 | 
				
			||||||
.It Ar command
 | 
					.It Ar command
 | 
				
			||||||
Daemon to start or stop via
 | 
					Daemon to start or stop via
 | 
				
			||||||
.Nm start-stop-daemon
 | 
					.Nm start-stop-daemon
 | 
				
			||||||
@@ -155,46 +149,11 @@ Set this to "true", "yes" or "1" (case-insensitive) if you want
 | 
				
			|||||||
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 output_logger
 | 
					 | 
				
			||||||
This is a process which will be used to log the standard output from the
 | 
					 | 
				
			||||||
service.  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 command must be executable as a shell
 | 
					 | 
				
			||||||
command inside the chroot if the
 | 
					 | 
				
			||||||
.Pa chroot
 | 
					 | 
				
			||||||
variable is set. Keep in mind also that this command works by accepting
 | 
					 | 
				
			||||||
the stdout of the service on stdin.
 | 
					 | 
				
			||||||
An example of a command that can be run this way is logger if you want
 | 
					 | 
				
			||||||
your service output to go to syslog.
 | 
					 | 
				
			||||||
.It Ar error_logger
 | 
					 | 
				
			||||||
The same thing as
 | 
					 | 
				
			||||||
.Pa output_logger
 | 
					 | 
				
			||||||
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
 | 
				
			||||||
@@ -239,8 +198,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
 | 
				
			||||||
@@ -490,7 +447,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
 | 
				
			||||||
@@ -507,7 +463,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
 | 
				
			||||||
@@ -522,7 +477,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
 | 
				
			||||||
@@ -614,7 +569,7 @@ rc_net_tap1_provide="!net"
 | 
				
			|||||||
# It's also possible to negate keywords. This is mainly useful for prefix
 | 
					# It's also possible to negate keywords. This is mainly useful for prefix
 | 
				
			||||||
# users testing OpenRC.
 | 
					# users testing OpenRC.
 | 
				
			||||||
rc_keyword="!-prefix"
 | 
					rc_keyword="!-prefix"
 | 
				
			||||||
# This can also be used to block a script from running in all
 | 
					# This can also be used to block a script from runining in all
 | 
				
			||||||
# containers except one or two
 | 
					# containers except one or two
 | 
				
			||||||
rc_keyword="!-containers !-docker"
 | 
					rc_keyword="!-containers !-docker"
 | 
				
			||||||
.Ed
 | 
					.Ed
 | 
				
			||||||
@@ -753,8 +708,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,7 +16,6 @@
 | 
				
			|||||||
.Nd bring the system down
 | 
					.Nd bring the system down
 | 
				
			||||||
.Sh SYNOPSIS
 | 
					.Sh SYNOPSIS
 | 
				
			||||||
.Nm
 | 
					.Nm
 | 
				
			||||||
.Op Fl c , -cancel
 | 
					 | 
				
			||||||
.Op Fl d , -no-write
 | 
					.Op Fl d , -no-write
 | 
				
			||||||
.Op Fl D , -dry-run
 | 
					.Op Fl D , -dry-run
 | 
				
			||||||
.Op Fl H , -halt
 | 
					.Op Fl H , -halt
 | 
				
			||||||
@@ -33,8 +32,6 @@ is the utility that communicates with
 | 
				
			|||||||
to bring down the system or instruct openrc-init to re-execute itself.
 | 
					to bring down the system or instruct openrc-init to re-execute itself.
 | 
				
			||||||
It supports the following options:
 | 
					It supports the following options:
 | 
				
			||||||
.Bl -tag -width "poweroff"
 | 
					.Bl -tag -width "poweroff"
 | 
				
			||||||
.It Fl c , -cancel
 | 
					 | 
				
			||||||
Cancel a pending shutdown.
 | 
					 | 
				
			||||||
.It Fl d , -no-write
 | 
					.It Fl d , -no-write
 | 
				
			||||||
Do not write the wtmp boot record.
 | 
					Do not write the wtmp boot record.
 | 
				
			||||||
.It Fl D , -dry-run
 | 
					.It Fl D , -dry-run
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,18 +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
 | 
					 | 
				
			||||||
.Fl d , -debug
 | 
					 | 
				
			||||||
.Ar service cmd
 | 
					 | 
				
			||||||
.Op Ar ...
 | 
					 | 
				
			||||||
.Nm
 | 
					 | 
				
			||||||
.Fl D , -nodeps
 | 
					 | 
				
			||||||
.Ar service cmd
 | 
					 | 
				
			||||||
.Op Ar ...
 | 
					 | 
				
			||||||
.Nm
 | 
					 | 
				
			||||||
.Op Fl i , -ifexists
 | 
					.Op Fl i , -ifexists
 | 
				
			||||||
.Ar service cmd
 | 
					.Ar service cmd
 | 
				
			||||||
.Op Ar ...
 | 
					.Op Ar ...
 | 
				
			||||||
@@ -40,21 +28,9 @@
 | 
				
			|||||||
.Ar service cmd
 | 
					.Ar service cmd
 | 
				
			||||||
.Op Ar ...
 | 
					.Op Ar ...
 | 
				
			||||||
.Nm
 | 
					.Nm
 | 
				
			||||||
.Op Fl s , -ifstarted
 | 
					 | 
				
			||||||
.Ar service cmd
 | 
					 | 
				
			||||||
.Op Ar ...
 | 
					 | 
				
			||||||
.Nm
 | 
					 | 
				
			||||||
.Op Fl S , -ifstopped
 | 
					 | 
				
			||||||
.Ar service cmd
 | 
					 | 
				
			||||||
.Op Ar ...
 | 
					 | 
				
			||||||
.Nm
 | 
					 | 
				
			||||||
.Fl e , -exists
 | 
					.Fl e , -exists
 | 
				
			||||||
.Ar service
 | 
					.Ar service
 | 
				
			||||||
.Nm
 | 
					.Nm
 | 
				
			||||||
.Fl Z , -dry-run
 | 
					 | 
				
			||||||
.Ar service cmd
 | 
					 | 
				
			||||||
.Op Ar ...
 | 
					 | 
				
			||||||
.Nm
 | 
					 | 
				
			||||||
.Fl l , -list
 | 
					.Fl l , -list
 | 
				
			||||||
.Nm
 | 
					.Nm
 | 
				
			||||||
.Fl r , -resolve
 | 
					.Fl r , -resolve
 | 
				
			||||||
@@ -88,15 +64,6 @@ return 0 if it can find
 | 
				
			|||||||
otherwise -1.
 | 
					otherwise -1.
 | 
				
			||||||
.Fl r , -resolve
 | 
					.Fl r , -resolve
 | 
				
			||||||
does the same and also prints the full path of the service to stdout.
 | 
					does the same and also prints the full path of the service to stdout.
 | 
				
			||||||
.Pp
 | 
					 | 
				
			||||||
.Fl d , -debug
 | 
					 | 
				
			||||||
sets -x when running the service script(s).
 | 
					 | 
				
			||||||
.Pp
 | 
					 | 
				
			||||||
.Fl D , -nodeps
 | 
					 | 
				
			||||||
ignores dependencies when running the service.
 | 
					 | 
				
			||||||
.Pp
 | 
					 | 
				
			||||||
.Fl Z , -dry-run
 | 
					 | 
				
			||||||
displays commands rather than executing them.
 | 
					 | 
				
			||||||
.Sh SEE ALSO
 | 
					.Sh SEE ALSO
 | 
				
			||||||
.Xr openrc 8 ,
 | 
					.Xr openrc 8 ,
 | 
				
			||||||
.Xr stdout 3
 | 
					.Xr stdout 3
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,8 +43,6 @@ List all defined runlevels.
 | 
				
			|||||||
Show all manually started services.
 | 
					Show all manually started services.
 | 
				
			||||||
.It Fl r , -runlevel
 | 
					.It Fl r , -runlevel
 | 
				
			||||||
Print the current runlevel name.
 | 
					Print the current runlevel name.
 | 
				
			||||||
.It Fl S , -supervised
 | 
					 | 
				
			||||||
Show all supervised services.
 | 
					 | 
				
			||||||
.It Fl s , -servicelist
 | 
					.It Fl s , -servicelist
 | 
				
			||||||
Show all services.
 | 
					Show all services.
 | 
				
			||||||
.It Fl u , -unused
 | 
					.It Fl u , -unused
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -131,34 +131,9 @@ Modifies the scheduling priority of the daemon.
 | 
				
			|||||||
.It Fl 1 , -stdout Ar logfile
 | 
					.It Fl 1 , -stdout Ar logfile
 | 
				
			||||||
Redirect the standard output of the process to logfile when started with
 | 
					Redirect the standard output of the process to logfile when started with
 | 
				
			||||||
.Fl background .
 | 
					.Fl background .
 | 
				
			||||||
The logfile Must be an absolute pathname, but relative to the path
 | 
					Must be an absolute pathname, but relative to the path optionally given with
 | 
				
			||||||
optionally given with
 | 
					 | 
				
			||||||
.Fl r , -chroot .
 | 
					.Fl r , -chroot .
 | 
				
			||||||
The logfile can also be a named pipe.
 | 
					The logfile can also be a named pipe.
 | 
				
			||||||
.It Fl 2 , -stderr Ar logfile
 | 
					 | 
				
			||||||
Redirect the standard error of the process to logfile when started with
 | 
					 | 
				
			||||||
.Fl background .
 | 
					 | 
				
			||||||
The logfile must be an absolute pathname, but relative to the path
 | 
					 | 
				
			||||||
optionally given with
 | 
					 | 
				
			||||||
.Fl r , -chroot .
 | 
					 | 
				
			||||||
The logfile can also be a named pipe.
 | 
					 | 
				
			||||||
.It Fl 3 , -stdout-logger Ar cmd
 | 
					 | 
				
			||||||
Run cmd as a child process redirecting the standard output to the
 | 
					 | 
				
			||||||
standard input of cmd when started with
 | 
					 | 
				
			||||||
.Fl background .
 | 
					 | 
				
			||||||
Cmd must be an absolute pathname, but relative to the path optionally given with
 | 
					 | 
				
			||||||
.Fl r , -chroot .
 | 
					 | 
				
			||||||
This process must be prepared to accept input on stdin and be able to
 | 
					 | 
				
			||||||
log it or send it to another location.
 | 
					 | 
				
			||||||
.It Fl 4 , -stderr-logger Ar cmd
 | 
					 | 
				
			||||||
Run cmd as a child process and 
 | 
					 | 
				
			||||||
Redirect the standard error of the process to the standard input of cmd
 | 
					 | 
				
			||||||
when started with
 | 
					 | 
				
			||||||
.Fl background .
 | 
					 | 
				
			||||||
Cmd must be an absolute pathname, but relative to the path optionally given with
 | 
					 | 
				
			||||||
.Fl r , -chroot .
 | 
					 | 
				
			||||||
This process must be prepared to accept input on stdin and be able to
 | 
					 | 
				
			||||||
log it or send it to another location.
 | 
					 | 
				
			||||||
.It Fl w , -wait Ar milliseconds
 | 
					.It Fl w , -wait Ar milliseconds
 | 
				
			||||||
Wait
 | 
					Wait
 | 
				
			||||||
.Ar milliseconds
 | 
					.Ar milliseconds
 | 
				
			||||||
@@ -176,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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,11 +16,6 @@
 | 
				
			|||||||
.Nd starts a daemon and restarts it if it crashes
 | 
					.Nd starts a daemon and restarts it if it crashes
 | 
				
			||||||
.Sh SYNOPSIS
 | 
					.Sh SYNOPSIS
 | 
				
			||||||
.Nm
 | 
					.Nm
 | 
				
			||||||
servicename
 | 
					 | 
				
			||||||
.Fl a , -healthcheck-timer
 | 
					 | 
				
			||||||
.Ar seconds
 | 
					 | 
				
			||||||
.Fl A , -healthcheck-delay
 | 
					 | 
				
			||||||
.Ar seconds
 | 
					 | 
				
			||||||
.Fl D , -respawn-delay
 | 
					.Fl D , -respawn-delay
 | 
				
			||||||
.Ar seconds
 | 
					.Ar seconds
 | 
				
			||||||
.Fl d , -chdir
 | 
					.Fl d , -chdir
 | 
				
			||||||
@@ -37,6 +32,8 @@ servicename
 | 
				
			|||||||
.Ar count
 | 
					.Ar count
 | 
				
			||||||
.Fl N , -nicelevel
 | 
					.Fl N , -nicelevel
 | 
				
			||||||
.Ar level
 | 
					.Ar level
 | 
				
			||||||
 | 
					.Fl p , -pidfile
 | 
				
			||||||
 | 
					.Ar pidfile
 | 
				
			||||||
.Fl P , -respawn-period
 | 
					.Fl P , -respawn-period
 | 
				
			||||||
.Ar seconds
 | 
					.Ar seconds
 | 
				
			||||||
.Fl R , -retry
 | 
					.Fl R , -retry
 | 
				
			||||||
@@ -54,15 +51,10 @@ servicename
 | 
				
			|||||||
.Op Fl -
 | 
					.Op Fl -
 | 
				
			||||||
.Op Ar arguments
 | 
					.Op Ar arguments
 | 
				
			||||||
.Nm
 | 
					.Nm
 | 
				
			||||||
servicename
 | 
					 | 
				
			||||||
.Fl K , -stop
 | 
					.Fl K , -stop
 | 
				
			||||||
.Ar daemon
 | 
					.Ar daemon
 | 
				
			||||||
.Fl r , -chroot
 | 
					.Fl p , -pidfile
 | 
				
			||||||
.Ar chrootpath
 | 
					.Ar pidfile
 | 
				
			||||||
.Nm
 | 
					 | 
				
			||||||
servicename
 | 
					 | 
				
			||||||
.Fl s , -signal
 | 
					 | 
				
			||||||
.Ar signal
 | 
					 | 
				
			||||||
.Fl r , -chroot
 | 
					.Fl r , -chroot
 | 
				
			||||||
.Ar chrootpath
 | 
					.Ar chrootpath
 | 
				
			||||||
.Sh DESCRIPTION
 | 
					.Sh DESCRIPTION
 | 
				
			||||||
@@ -70,15 +62,22 @@ servicename
 | 
				
			|||||||
provides a consistent method of starting, stopping and restarting
 | 
					provides a consistent method of starting, stopping and restarting
 | 
				
			||||||
daemons. If
 | 
					daemons. If
 | 
				
			||||||
.Fl K , -stop
 | 
					.Fl K , -stop
 | 
				
			||||||
or
 | 
					 | 
				
			||||||
.Fl s , -signal
 | 
					 | 
				
			||||||
is not provided, then we assume we are starting the daemon.
 | 
					is not provided, then we assume we are starting the daemon.
 | 
				
			||||||
.Nm
 | 
					.Nm
 | 
				
			||||||
only works with daemons which do not fork. If your daemon has options to
 | 
					only works with daemons which do not fork. Also, it uses its own pid
 | 
				
			||||||
tell it not to fork, it should be configured to not fork.
 | 
					file, so the daemon should not write a pid file, or the pid file passed
 | 
				
			||||||
 | 
					to 
 | 
				
			||||||
 | 
					.Nm
 | 
				
			||||||
 | 
					should not be the one the daemon writes.
 | 
				
			||||||
.Pp
 | 
					.Pp
 | 
				
			||||||
Here are the options to specify the daemon and how it should start or stop:
 | 
					Here are the options to specify the daemon and how it should start or stop:
 | 
				
			||||||
.Bl -tag -width indent
 | 
					.Bl -tag -width indent
 | 
				
			||||||
 | 
					.It Fl p , -pidfile Ar pidfile
 | 
				
			||||||
 | 
					When starting, we write a
 | 
				
			||||||
 | 
					.Ar pidfile
 | 
				
			||||||
 | 
					so we know which supervisor to stop.  When stopping we only stop the pid(s)
 | 
				
			||||||
 | 
					listed in the
 | 
				
			||||||
 | 
					.Ar pidfile .
 | 
				
			||||||
.It Fl u , -user Ar user Ns Op : Ns Ar group
 | 
					.It Fl u , -user Ar user Ns Op : Ns Ar group
 | 
				
			||||||
Start the daemon as the
 | 
					Start the daemon as the
 | 
				
			||||||
.Ar user
 | 
					.Ar user
 | 
				
			||||||
@@ -91,11 +90,6 @@ Print the action(s) that are taken just before doing them.
 | 
				
			|||||||
.Pp
 | 
					.Pp
 | 
				
			||||||
The options are as follows:
 | 
					The options are as follows:
 | 
				
			||||||
.Bl -tag -width indent
 | 
					.Bl -tag -width indent
 | 
				
			||||||
.Fl a , -healthcheck-timer Ar seconds
 | 
					 | 
				
			||||||
Run the healthcheck() command, possibly followed by the unhealthy()
 | 
					 | 
				
			||||||
command every time this number of seconds passes.
 | 
					 | 
				
			||||||
.Fl A , -healthcheck-delay Ar seconds
 | 
					 | 
				
			||||||
Wait this long before the first health check.
 | 
					 | 
				
			||||||
.It Fl D , -respawn-delay Ar seconds
 | 
					.It Fl D , -respawn-delay Ar seconds
 | 
				
			||||||
wait this number of seconds before restarting a daemon after it crashes.
 | 
					wait this number of seconds before restarting a daemon after it crashes.
 | 
				
			||||||
The default is 0.
 | 
					The default is 0.
 | 
				
			||||||
@@ -112,31 +106,23 @@ Data can be from 0 to 7 inclusive.
 | 
				
			|||||||
.It Fl k , -umask Ar mode
 | 
					.It Fl k , -umask Ar mode
 | 
				
			||||||
Set the umask of the daemon.
 | 
					Set the umask of the daemon.
 | 
				
			||||||
.It Fl m , -respawn-max Ar count
 | 
					.It Fl m , -respawn-max Ar count
 | 
				
			||||||
Sets the maximum number of times a daemon will be respawned. If a daemon
 | 
					Sets the maximum number of times a daemon will be respawned during a
 | 
				
			||||||
crashes more than this number of times,
 | 
					respawn period. If a daemon dies more than this number of times during a
 | 
				
			||||||
 | 
					respawn period,
 | 
				
			||||||
.Nm
 | 
					.Nm
 | 
				
			||||||
will give up and exit. The default is 10 and 0 means unlimited.
 | 
					will give up trying to respawn it and exit. The default is 10, and 0
 | 
				
			||||||
.Pp
 | 
					means unlimited.
 | 
				
			||||||
If respawn-period is also set, more than respawn-max crashes must occur
 | 
					 | 
				
			||||||
during respawn-period seconds to cause
 | 
					 | 
				
			||||||
.Nm
 | 
					 | 
				
			||||||
to give up and exit.
 | 
					 | 
				
			||||||
.It Fl N , -nicelevel Ar level
 | 
					.It Fl N , -nicelevel Ar level
 | 
				
			||||||
Modifies the scheduling priority of the daemon.
 | 
					Modifies the scheduling priority of the daemon.
 | 
				
			||||||
.It Fl P , -respawn-period Ar seconds
 | 
					.It Fl P , -respawn-period Ar seconds
 | 
				
			||||||
Sets the length of a respawn period. See the
 | 
					Sets the length of a respawn period. The default is 10 seconds. See the
 | 
				
			||||||
description of --respawn-max for more information.
 | 
					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 and chdir should be relative to the chroot.
 | 
					as the path to the daemon, chdir and pidfile, should be relative to the chroot.
 | 
				
			||||||
.It Fl  , -signal Ar signal
 | 
					 | 
				
			||||||
Instruct a supervisor to signal the process it is supervising. The
 | 
					 | 
				
			||||||
process to communicate with is determined by the name of the service
 | 
					 | 
				
			||||||
taken from the RC_SVCNAME environment variable.
 | 
					 | 
				
			||||||
.It Fl u , -user Ar user
 | 
					.It Fl u , -user Ar user
 | 
				
			||||||
Start the daemon as the specified user.
 | 
					Start the daemon as the specified user.
 | 
				
			||||||
.It Fl 1 , -stdout Ar logfile
 | 
					.It Fl 1 , -stdout Ar logfile
 | 
				
			||||||
@@ -149,6 +135,7 @@ The same thing as
 | 
				
			|||||||
.Fl 1 , -stdout
 | 
					.Fl 1 , -stdout
 | 
				
			||||||
but with the standard error output.
 | 
					but with the standard error output.
 | 
				
			||||||
.El
 | 
					.El
 | 
				
			||||||
 | 
					.El
 | 
				
			||||||
.Sh ENVIRONMENT
 | 
					.Sh ENVIRONMENT
 | 
				
			||||||
.Va SSD_NICELEVEL
 | 
					.Va SSD_NICELEVEL
 | 
				
			||||||
can also set the scheduling priority of the daemon, but the command line
 | 
					can also set the scheduling priority of the daemon, but the command line
 | 
				
			||||||
@@ -170,16 +157,15 @@ make sure the settings mmake sense. For example, a respawn period of 5
 | 
				
			|||||||
seconds with a respawn max of 10 and a respawn delay of 1 second leads
 | 
					seconds with a respawn max of 10 and a respawn delay of 1 second leads
 | 
				
			||||||
to infinite respawning since there can never be 10 respawns within 5
 | 
					to infinite respawning since there can never be 10 respawns within 5
 | 
				
			||||||
seconds.
 | 
					seconds.
 | 
				
			||||||
.Sh NOTE
 | 
					 | 
				
			||||||
Invoking supervise-daemon requires both the RC_SVCNAME  environment
 | 
					 | 
				
			||||||
variable to be set and the name of the service as the first argument on
 | 
					 | 
				
			||||||
the command line, so it is best to invoke it inside a service script
 | 
					 | 
				
			||||||
rather than manually.
 | 
					 | 
				
			||||||
.Sh SEE ALSO
 | 
					.Sh SEE ALSO
 | 
				
			||||||
.Xr chdir 2 ,
 | 
					.Xr chdir 2 ,
 | 
				
			||||||
.Xr chroot 2 ,
 | 
					.Xr chroot 2 ,
 | 
				
			||||||
.Xr getopt 3 ,
 | 
					.Xr getopt 3 ,
 | 
				
			||||||
.Xr nice 2 ,
 | 
					.Xr nice 2 ,
 | 
				
			||||||
 | 
					.Xr rc_find_pids 3
 | 
				
			||||||
 | 
					.Sh BUGS
 | 
				
			||||||
 | 
					.Nm
 | 
				
			||||||
 | 
					cannot stop an interpreted daemon that no longer exists without a pidfile.
 | 
				
			||||||
.Sh HISTORY
 | 
					.Sh HISTORY
 | 
				
			||||||
.Nm
 | 
					.Nm
 | 
				
			||||||
first appeared in Debian.
 | 
					first appeared in Debian.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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 -D_POSIX_C_SOURCE=200809L
 | 
					CPPFLAGS+=	-D_DEFAULT_SOURCE -D_XOPEN_SOURCE=700
 | 
				
			||||||
LIBDL=		-Wl,-Bdynamic -ldl
 | 
					LIBDL=		-Wl,-Bdynamic -ldl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ifeq (${MKSELINUX},yes)
 | 
					ifeq (${MKSELINUX},yes)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										11
									
								
								mk/sys.mk
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								mk/sys.mk
									
									
									
									
									
								
							@@ -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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -45,22 +44,20 @@ SBINDIR?=		${PREFIX}/sbin
 | 
				
			|||||||
SBINMODE?=		0755
 | 
					SBINMODE?=		0755
 | 
				
			||||||
 | 
					
 | 
				
			||||||
INCDIR?=		${UPREFIX}/include
 | 
					INCDIR?=		${UPREFIX}/include
 | 
				
			||||||
INCMODE?=		0644
 | 
					INCMODE?=		0444
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_LIBNAME_SH=		case `readlink /lib` in /lib64|lib64) echo "lib64";; *) echo "lib";; esac
 | 
					_LIBNAME_SH=		case `readlink /lib` in /lib64|lib64) echo "lib64";; *) echo "lib";; esac
 | 
				
			||||||
_LIBNAME:=		$(shell ${_LIBNAME_SH})
 | 
					_LIBNAME:=		$(shell ${_LIBNAME_SH})
 | 
				
			||||||
LIBNAME?=		${_LIBNAME}
 | 
					LIBNAME?=		${_LIBNAME}
 | 
				
			||||||
LIBDIR?=		${UPREFIX}/${LIBNAME}
 | 
					LIBDIR?=		${UPREFIX}/${LIBNAME}
 | 
				
			||||||
LIBMODE?=		0644
 | 
					LIBMODE?=		0444
 | 
				
			||||||
SHLIBDIR?=		${PREFIX}/${LIBNAME}
 | 
					SHLIBDIR?=		${PREFIX}/${LIBNAME}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
LIBEXECDIR?=		${PREFIX}/libexec/rc
 | 
					LIBEXECDIR?=		${PREFIX}/libexec/rc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MANPREFIX?=		${UPREFIX}/share
 | 
					MANPREFIX?=		${UPREFIX}/share
 | 
				
			||||||
MANDIR?=		${MANPREFIX}/man
 | 
					MANDIR?=		${MANPREFIX}/man
 | 
				
			||||||
MANMODE?=		0644
 | 
					MANMODE?=		0444
 | 
				
			||||||
 | 
					 | 
				
			||||||
BASHCOMPDIR?=		${UPREFIX}/share/bash-completion/completions
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
DATADIR?=		${UPREFIX}/share/openrc
 | 
					DATADIR?=		${UPREFIX}/share/openrc
 | 
				
			||||||
DATAMODE?=		0644
 | 
					DATAMODE?=		0644
 | 
				
			||||||
@@ -68,4 +65,4 @@ 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.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,10 +36,9 @@ BOOT-FreeBSD+=	hostid modules newsyslog savecore syslogd
 | 
				
			|||||||
# FreeBSD specific stuff
 | 
					# FreeBSD specific stuff
 | 
				
			||||||
BOOT-FreeBSD+=	adjkerntz dumpon syscons
 | 
					BOOT-FreeBSD+=	adjkerntz dumpon syscons
 | 
				
			||||||
 | 
					
 | 
				
			||||||
BOOT-Linux+=	binfmt hwclock keymaps modules mtab procfs save-keymaps \
 | 
					BOOT-Linux+=	binfmt hwclock keymaps modules mtab procfs termencoding
 | 
				
			||||||
	save-termencoding 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
 | 
				
			||||||
@@ -40,10 +39,6 @@ s6_service_path - the path to the s6 service directory. The default is
 | 
				
			|||||||
s6_svwait_options_start - the options to pass to s6-svwait when starting
 | 
					s6_svwait_options_start - the options to pass to s6-svwait when starting
 | 
				
			||||||
the service. If this is not set, s6-svwait will not be called.
 | 
					the service. If this is not set, s6-svwait will not be called.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
s6_force_kill - Should we try to force kill this service if the
 | 
					 | 
				
			||||||
s6_service_timeout_stop timeout expires when shutting down this service?
 | 
					 | 
				
			||||||
The default is yes.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
s6_service_timeout_stop - the amount of time, in milliseconds, s6-svc
 | 
					s6_service_timeout_stop - the amount of time, in milliseconds, s6-svc
 | 
				
			||||||
should wait for a service to go down when stopping.
 | 
					should wait for a service to go down when stopping.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,495 +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.
 | 
					 | 
				
			||||||
							
								
								
									
										1
									
								
								sh/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								sh/.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,6 @@
 | 
				
			|||||||
functions.sh
 | 
					functions.sh
 | 
				
			||||||
gendepends.sh
 | 
					gendepends.sh
 | 
				
			||||||
 | 
					rc-functions.sh
 | 
				
			||||||
openrc-run.sh
 | 
					openrc-run.sh
 | 
				
			||||||
cgroup-release-agent.sh
 | 
					cgroup-release-agent.sh
 | 
				
			||||||
init.sh
 | 
					init.sh
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
DIR=	${LIBEXECDIR}/sh
 | 
					DIR=	${LIBEXECDIR}/sh
 | 
				
			||||||
SRCS=	init.sh.in functions.sh.in gendepends.sh.in \
 | 
					SRCS=	init.sh.in functions.sh.in gendepends.sh.in \
 | 
				
			||||||
	openrc-run.sh.in ${SRCS-${OS}}
 | 
						openrc-run.sh.in rc-functions.sh.in ${SRCS-${OS}}
 | 
				
			||||||
INC=	rc-mount.sh functions.sh rc-functions.sh runit.sh s6.sh \
 | 
					INC=	rc-mount.sh functions.sh rc-functions.sh runit.sh s6.sh \
 | 
				
			||||||
		start-stop-daemon.sh supervise-daemon.sh
 | 
							start-stop-daemon.sh supervise-daemon.sh
 | 
				
			||||||
BIN=	gendepends.sh init.sh openrc-run.sh ${BIN-${OS}}
 | 
					BIN=	gendepends.sh init.sh openrc-run.sh ${BIN-${OS}}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -46,7 +46,7 @@ yesno()
 | 
				
			|||||||
	case "$value" in
 | 
						case "$value" in
 | 
				
			||||||
		[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) return 0;;
 | 
							[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) return 0;;
 | 
				
			||||||
		[Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0) return 1;;
 | 
							[Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0) return 1;;
 | 
				
			||||||
		*) vewarn "\$$1 is not set properly"; return 2;;
 | 
							*) vewarn "\$$1 is not set properly"; return 1;;
 | 
				
			||||||
	esac
 | 
						esac
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -133,10 +133,11 @@ _status()
 | 
				
			|||||||
	elif service_inactive; then
 | 
						elif service_inactive; then
 | 
				
			||||||
		ewarn "status: inactive"
 | 
							ewarn "status: inactive"
 | 
				
			||||||
		return 16
 | 
							return 16
 | 
				
			||||||
	elif service_crashed; then
 | 
					 | 
				
			||||||
		eerror "status: crashed"
 | 
					 | 
				
			||||||
		return 32
 | 
					 | 
				
			||||||
	elif service_started; then
 | 
						elif service_started; then
 | 
				
			||||||
 | 
							if service_crashed; then
 | 
				
			||||||
 | 
								eerror "status: crashed"
 | 
				
			||||||
 | 
								return 32
 | 
				
			||||||
 | 
							fi
 | 
				
			||||||
		einfo "status: started"
 | 
							einfo "status: started"
 | 
				
			||||||
		return 0
 | 
							return 0
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
@@ -259,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
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -202,21 +203,15 @@ cgroup_cleanup()
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	cgroup_running || return 0
 | 
						cgroup_running || return 0
 | 
				
			||||||
	ebegin "starting cgroups cleanup"
 | 
						ebegin "starting cgroups cleanup"
 | 
				
			||||||
	local pids loops=0
 | 
						local pids
 | 
				
			||||||
	pids="$(cgroup_get_pids)"
 | 
						pids="$(cgroup_get_pids)"
 | 
				
			||||||
	if [ -n "${pids}" ]; then
 | 
						if [ -n "${pids}" ]; then
 | 
				
			||||||
		kill -s CONT ${pids} 2> /dev/null
 | 
					 | 
				
			||||||
		kill -s "${stopsig:-TERM}" ${pids} 2> /dev/null
 | 
							kill -s "${stopsig:-TERM}" ${pids} 2> /dev/null
 | 
				
			||||||
 | 
							kill -s CONT ${pids} 2> /dev/null
 | 
				
			||||||
		yesno "${rc_send_sighup:-no}" &&
 | 
							yesno "${rc_send_sighup:-no}" &&
 | 
				
			||||||
			kill -s HUP ${pids} 2> /dev/null
 | 
								kill -s HUP ${pids} 2> /dev/null
 | 
				
			||||||
		kill -s "${stopsig:-TERM}" ${pids} 2> /dev/null
 | 
							sleep "${rc_timeout_stopsec:-90}"
 | 
				
			||||||
		while [ -n "$(cgroup_get_pids)" ] &&
 | 
							yesno "${rc_send_sigkill:-yes}" &&
 | 
				
			||||||
			[ "${loops}" -lt "${rc_timeout_stopsec:-90}" ]; do
 | 
					 | 
				
			||||||
			loops=$((loops+1))
 | 
					 | 
				
			||||||
			sleep 1
 | 
					 | 
				
			||||||
		done
 | 
					 | 
				
			||||||
		pids="$(cgroup_get_pids)"
 | 
					 | 
				
			||||||
		[ -n "${pids}" ] && yesno "${rc_send_sigkill:-yes}" &&
 | 
					 | 
				
			||||||
			kill -s KILL ${pids} 2> /dev/null
 | 
								kill -s KILL ${pids} 2> /dev/null
 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
	cgroup2_remove
 | 
						cgroup2_remove
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,6 +2,42 @@
 | 
				
			|||||||
# Copyright (c) 2007-2009 Roy Marples <roy@marples.name>
 | 
					# Copyright (c) 2007-2009 Roy Marples <roy@marples.name>
 | 
				
			||||||
# Released under the 2-clause BSD license.
 | 
					# Released under the 2-clause BSD license.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					has_addon()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						[ -e /@LIB@/rc/addons/"$1".sh -o -e /@LIB@/rcscripts/addons/"$1".sh ]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_addon_warn()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						eindent
 | 
				
			||||||
 | 
						ewarn "$RC_SVCNAME uses addon code which is deprecated"
 | 
				
			||||||
 | 
						ewarn "and may not be available in the future."
 | 
				
			||||||
 | 
						eoutdent
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import_addon()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if [ -e /@LIB@/rc/addons/"$1".sh ]; then
 | 
				
			||||||
 | 
							_addon_warn
 | 
				
			||||||
 | 
							. /@LIB@/rc/addons/"$1".sh
 | 
				
			||||||
 | 
						elif [ -e /@LIB@/rcscripts/addons/"$1".sh ]; then
 | 
				
			||||||
 | 
							_addon_warn
 | 
				
			||||||
 | 
							. /@LIB@/rcscripts/addons/"$1".sh
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return 1
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					start_addon()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						( import_addon "$1-start" )
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					stop_addon()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						( import_addon "$1-stop" )
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
net_fs_list="afs ceph cifs coda davfs fuse fuse.sshfs gfs glusterfs lustre
 | 
					net_fs_list="afs ceph cifs coda davfs fuse fuse.sshfs gfs glusterfs lustre
 | 
				
			||||||
ncpfs nfs nfs4 ocfs2 shfs smbfs"
 | 
					ncpfs nfs nfs4 ocfs2 shfs smbfs"
 | 
				
			||||||
is_net_fs()
 | 
					is_net_fs()
 | 
				
			||||||
							
								
								
									
										20
									
								
								sh/s6.sh
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								sh/s6.sh
									
									
									
									
									
								
							@@ -12,20 +12,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[ -z "${s6_service_path}" ] && s6_service_path="/var/svc.d/${RC_SVCNAME}"
 | 
					[ -z "${s6_service_path}" ] && s6_service_path="/var/svc.d/${RC_SVCNAME}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_s6_force_kill() {
 | 
					 | 
				
			||||||
	local pid
 | 
					 | 
				
			||||||
	s6_service_link="${RC_SVCDIR}/s6-scan/${s6_service_path##*/}"
 | 
					 | 
				
			||||||
	pid="${3%)}"
 | 
					 | 
				
			||||||
	[ -z "${pid}" ] && return 0
 | 
					 | 
				
			||||||
	if kill -0 "${pid}" 2> /dev/null; then
 | 
					 | 
				
			||||||
		ewarn "Sending DOWN & KILL for ${RC_SVCNAME}"
 | 
					 | 
				
			||||||
		s6-svc -dk "${s6_service_link}"
 | 
					 | 
				
			||||||
		sleep 1
 | 
					 | 
				
			||||||
		kill -0 "${pid}" 2>/dev/null && return 1
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
	return 0
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
s6_start()
 | 
					s6_start()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if [ ! -d "${s6_service_path}" ]; then
 | 
						if [ ! -d "${s6_service_path}" ]; then
 | 
				
			||||||
@@ -55,11 +41,7 @@ s6_stop()
 | 
				
			|||||||
 fi
 | 
					 fi
 | 
				
			||||||
	s6_service_link="${RC_SVCDIR}/s6-scan/${s6_service_path##*/}"
 | 
						s6_service_link="${RC_SVCDIR}/s6-scan/${s6_service_path##*/}"
 | 
				
			||||||
	ebegin "Stopping ${name:-$RC_SVCNAME}"
 | 
						ebegin "Stopping ${name:-$RC_SVCNAME}"
 | 
				
			||||||
	s6-svc -d -wD -T ${s6_service_timeout_stop:-60000} "${s6_service_link}"
 | 
						s6-svc -wD -d -T ${s6_service_timeout_stop:-10000} "${s6_service_link}"
 | 
				
			||||||
	set -- $(s6-svstat "${s6_service_link}")
 | 
					 | 
				
			||||||
	[ "$1" = "up" ] &&
 | 
					 | 
				
			||||||
		yesno "${s6_force_kill:-yes}" &&
 | 
					 | 
				
			||||||
			_s6_force_kill "$@"
 | 
					 | 
				
			||||||
	set -- $(s6-svstat "${s6_service_link}")
 | 
						set -- $(s6-svstat "${s6_service_link}")
 | 
				
			||||||
	[ "$1" = "down" ]
 | 
						[ "$1" = "down" ]
 | 
				
			||||||
	eend $? "Failed to stop ${name:-$RC_SVCNAME}"
 | 
						eend $? "Failed to stop ${name:-$RC_SVCNAME}"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -38,25 +38,15 @@ ssd_start()
 | 
				
			|||||||
		service_inactive && _inactive=true
 | 
							service_inactive && _inactive=true
 | 
				
			||||||
		mark_service_inactive
 | 
							mark_service_inactive
 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
	[ -n "$output_logger" ] &&
 | 
					 | 
				
			||||||
		output_logger_arg="--stdout-logger \"$output_logger\""
 | 
					 | 
				
			||||||
	[ -n "$error_logger" ] &&
 | 
					 | 
				
			||||||
		error_logger_arg="--stderr-logger \"$error_logger\""
 | 
					 | 
				
			||||||
	#the eval call is necessary for cases like:
 | 
						#the eval call is necessary for cases like:
 | 
				
			||||||
	# command_args="this \"is a\" test"
 | 
						# command_args="this \"is a\" test"
 | 
				
			||||||
	# to work properly.
 | 
						# to work properly.
 | 
				
			||||||
	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 \
 | 
					 | 
				
			||||||
		${output_logger_arg} \
 | 
					 | 
				
			||||||
		${error_logger_arg} \
 | 
					 | 
				
			||||||
		${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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,8 +10,6 @@
 | 
				
			|||||||
# 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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extra_commands="healthcheck unhealthy ${extra_commands}"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
supervise_start()
 | 
					supervise_start()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if [ -z "$command" ]; then
 | 
						if [ -z "$command" ]; then
 | 
				
			||||||
@@ -24,21 +22,15 @@ supervise_start()
 | 
				
			|||||||
	# The eval call is necessary for cases like:
 | 
						# The eval call is necessary for cases like:
 | 
				
			||||||
	# command_args="this \"is a\" test"
 | 
						# command_args="this \"is a\" test"
 | 
				
			||||||
	# to work properly.
 | 
						# to work properly.
 | 
				
			||||||
	eval supervise-daemon "${RC_SVCNAME}" --start \
 | 
						eval supervise-daemon --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 \
 | 
				
			||||||
		${healthcheck_delay:+--healthcheck-delay} $healthcheck_delay \
 | 
					 | 
				
			||||||
		${healthcheck_timer:+--healthcheck-timer} $healthcheck_timer \
 | 
					 | 
				
			||||||
		${command_user+--user} $command_user \
 | 
							${command_user+--user} $command_user \
 | 
				
			||||||
		${umask+--umask} $umask \
 | 
							$supervise_daemon_args \
 | 
				
			||||||
		${supervise_daemon_args:-${start_stop_daemon_args}} \
 | 
					 | 
				
			||||||
		$command \
 | 
							$command \
 | 
				
			||||||
		-- $command_args $command_args_foreground
 | 
							-- $command_args $command_args_foreground
 | 
				
			||||||
	rc=$?
 | 
						rc=$?
 | 
				
			||||||
@@ -55,58 +47,16 @@ supervise_stop()
 | 
				
			|||||||
	local startpidfile="$(service_get_value "pidfile")"
 | 
						local startpidfile="$(service_get_value "pidfile")"
 | 
				
			||||||
	chroot="${startchroot:-$chroot}"
 | 
						chroot="${startchroot:-$chroot}"
 | 
				
			||||||
	pidfile="${startpidfile:-$pidfile}"
 | 
						pidfile="${startpidfile:-$pidfile}"
 | 
				
			||||||
 | 
						[ -n "$pidfile" ] || return 0
 | 
				
			||||||
	ebegin "Stopping ${name:-$RC_SVCNAME}"
 | 
						ebegin "Stopping ${name:-$RC_SVCNAME}"
 | 
				
			||||||
	supervise-daemon "${RC_SVCNAME}" --stop \
 | 
						supervise-daemon --stop \
 | 
				
			||||||
		${pidfile:+--pidfile} $chroot$pidfile
 | 
							${pidfile:+--pidfile} $chroot$pidfile \
 | 
				
			||||||
 | 
							${stopsig:+--signal} $stopsig
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	eend $? "Failed to stop ${name:-$RC_SVCNAME}"
 | 
						eend $? "Failed to stop ${name:-$RC_SVCNAME}"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_check_supervised()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	local child_pid start_time
 | 
					 | 
				
			||||||
	child_pid="$(service_get_value "child_pid")"
 | 
					 | 
				
			||||||
	start_time="$(service_get_value "start_time")"
 | 
					 | 
				
			||||||
	if [ -n "${child_pid}" ] && [ -n "${start_time}" ]; then
 | 
					 | 
				
			||||||
		return 1
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
	return 0
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
supervise_status()
 | 
					supervise_status()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if service_stopping; then
 | 
						_status
 | 
				
			||||||
		ewarn "status: stopping"
 | 
					 | 
				
			||||||
		return 4
 | 
					 | 
				
			||||||
	elif service_starting; then
 | 
					 | 
				
			||||||
		ewarn "status: starting"
 | 
					 | 
				
			||||||
		return 8
 | 
					 | 
				
			||||||
	elif service_inactive; then
 | 
					 | 
				
			||||||
		ewarn "status: inactive"
 | 
					 | 
				
			||||||
		return 16
 | 
					 | 
				
			||||||
	elif service_started; then
 | 
					 | 
				
			||||||
		if service_crashed; then
 | 
					 | 
				
			||||||
			if ! _check_supervised; then
 | 
					 | 
				
			||||||
				eerror "status: unsupervised"
 | 
					 | 
				
			||||||
				return 64
 | 
					 | 
				
			||||||
			fi
 | 
					 | 
				
			||||||
			eerror "status: crashed"
 | 
					 | 
				
			||||||
			return 32
 | 
					 | 
				
			||||||
		fi
 | 
					 | 
				
			||||||
		einfo "status: started"
 | 
					 | 
				
			||||||
		return 0
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		einfo "status: stopped"
 | 
					 | 
				
			||||||
		return 3
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
healthcheck()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return 0
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
unhealthy()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return 0
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -47,7 +47,6 @@ bool rc_conf_yesno(const char *var);
 | 
				
			|||||||
void env_filter(void);
 | 
					void env_filter(void);
 | 
				
			||||||
void env_config(void);
 | 
					void env_config(void);
 | 
				
			||||||
int signal_setup(int sig, void (*handler)(int));
 | 
					int signal_setup(int sig, void (*handler)(int));
 | 
				
			||||||
int signal_setup_restart(int sig, void (*handler)(int));
 | 
					 | 
				
			||||||
int svc_lock(const char *);
 | 
					int svc_lock(const char *);
 | 
				
			||||||
int svc_unlock(const char *, int);
 | 
					int svc_unlock(const char *, int);
 | 
				
			||||||
pid_t exec_service(const char *, const char *);
 | 
					pid_t exec_service(const char *, const char *);
 | 
				
			||||||
@@ -66,6 +65,9 @@ int parse_mode(mode_t *, char *);
 | 
				
			|||||||
/* Handy function so we can wrap einfo around our deptree */
 | 
					/* Handy function so we can wrap einfo around our deptree */
 | 
				
			||||||
RC_DEPTREE *_rc_deptree_load (int, int *);
 | 
					RC_DEPTREE *_rc_deptree_load (int, int *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Test to see if we can see pid 1 or not */
 | 
				
			||||||
 | 
					bool _rc_can_find_pids(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RC_SERVICE lookup_service_state(const char *service);
 | 
					RC_SERVICE lookup_service_state(const char *service);
 | 
				
			||||||
void from_time_t(char *time_string, time_t tv);
 | 
					void from_time_t(char *time_string, time_t tv);
 | 
				
			||||||
time_t to_time_t(char *timestring);
 | 
					time_t to_time_t(char *timestring);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -883,7 +883,7 @@ eindent(void)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	char *env = getenv("EINFO_INDENT");
 | 
						char *env = getenv("EINFO_INDENT");
 | 
				
			||||||
	int amount = 0;
 | 
						int amount = 0;
 | 
				
			||||||
	char *num;
 | 
						char num[10];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (env) {
 | 
						if (env) {
 | 
				
			||||||
		errno = 0;
 | 
							errno = 0;
 | 
				
			||||||
@@ -894,9 +894,8 @@ eindent(void)
 | 
				
			|||||||
	amount += INDENT_WIDTH;
 | 
						amount += INDENT_WIDTH;
 | 
				
			||||||
	if (amount > INDENT_MAX)
 | 
						if (amount > INDENT_MAX)
 | 
				
			||||||
		amount = INDENT_MAX;
 | 
							amount = INDENT_MAX;
 | 
				
			||||||
	xasprintf(&num, "%08d", amount);
 | 
						snprintf(num, 10, "%08d", amount);
 | 
				
			||||||
	setenv("EINFO_INDENT", num, 1);
 | 
						setenv("EINFO_INDENT", num, 1);
 | 
				
			||||||
	free(num);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
hidden_def(eindent)
 | 
					hidden_def(eindent)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -904,7 +903,7 @@ void eoutdent(void)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	char *env = getenv("EINFO_INDENT");
 | 
						char *env = getenv("EINFO_INDENT");
 | 
				
			||||||
	int amount = 0;
 | 
						int amount = 0;
 | 
				
			||||||
	char *num = NULL;
 | 
						char num[10];
 | 
				
			||||||
	int serrno = errno;
 | 
						int serrno = errno;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!env)
 | 
						if (!env)
 | 
				
			||||||
@@ -918,9 +917,8 @@ void eoutdent(void)
 | 
				
			|||||||
	if (amount <= 0)
 | 
						if (amount <= 0)
 | 
				
			||||||
		unsetenv("EINFO_INDENT");
 | 
							unsetenv("EINFO_INDENT");
 | 
				
			||||||
	else {
 | 
						else {
 | 
				
			||||||
		xasprintf(&num, "%08d", amount);
 | 
							snprintf(num, 10, "%08d", amount);
 | 
				
			||||||
		setenv("EINFO_INDENT", num, 1);
 | 
							setenv("EINFO_INDENT", num, 1);
 | 
				
			||||||
		free(num);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	errno = serrno;
 | 
						errno = serrno;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,13 +23,13 @@
 | 
				
			|||||||
static bool
 | 
					static bool
 | 
				
			||||||
pid_is_exec(pid_t pid, const char *exec)
 | 
					pid_is_exec(pid_t pid, const char *exec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char *buffer = NULL;
 | 
						char buffer[32];
 | 
				
			||||||
	FILE *fp;
 | 
						FILE *fp;
 | 
				
			||||||
	int c;
 | 
						int c;
 | 
				
			||||||
	bool retval = false;
 | 
						bool retval = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	exec = basename_c(exec);
 | 
						exec = basename_c(exec);
 | 
				
			||||||
	xasprintf(&buffer, "/proc/%d/stat", pid);
 | 
						snprintf(buffer, sizeof(buffer), "/proc/%d/stat", pid);
 | 
				
			||||||
	if ((fp = fopen(buffer, "r"))) {
 | 
						if ((fp = fopen(buffer, "r"))) {
 | 
				
			||||||
		while ((c = getc(fp)) != EOF && c != '(')
 | 
							while ((c = getc(fp)) != EOF && c != '(')
 | 
				
			||||||
			;
 | 
								;
 | 
				
			||||||
@@ -41,27 +41,23 @@ pid_is_exec(pid_t pid, const char *exec)
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		fclose(fp);
 | 
							fclose(fp);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	free(buffer);
 | 
					 | 
				
			||||||
	return retval;
 | 
						return retval;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool
 | 
					static bool
 | 
				
			||||||
pid_is_argv(pid_t pid, const char *const *argv)
 | 
					pid_is_argv(pid_t pid, const char *const *argv)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char *cmdline = NULL;
 | 
						char cmdline[32];
 | 
				
			||||||
	int fd;
 | 
						int fd;
 | 
				
			||||||
	char buffer[PATH_MAX];
 | 
						char buffer[PATH_MAX];
 | 
				
			||||||
	char *p;
 | 
						char *p;
 | 
				
			||||||
	ssize_t bytes;
 | 
						ssize_t bytes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	xasprintf(&cmdline, "/proc/%u/cmdline", pid);
 | 
						snprintf(cmdline, sizeof(cmdline), "/proc/%u/cmdline", pid);
 | 
				
			||||||
	if ((fd = open(cmdline, O_RDONLY)) < 0) {
 | 
						if ((fd = open(cmdline, O_RDONLY)) < 0)
 | 
				
			||||||
		free(cmdline);
 | 
					 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	bytes = read(fd, buffer, sizeof(buffer));
 | 
						bytes = read(fd, buffer, sizeof(buffer));
 | 
				
			||||||
	close(fd);
 | 
						close(fd);
 | 
				
			||||||
	free(cmdline);
 | 
					 | 
				
			||||||
	if (bytes == -1)
 | 
						if (bytes == -1)
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -84,15 +80,12 @@ rc_find_pids(const char *exec, const char *const *argv, uid_t uid, pid_t pid)
 | 
				
			|||||||
	DIR *procdir;
 | 
						DIR *procdir;
 | 
				
			||||||
	struct dirent *entry;
 | 
						struct dirent *entry;
 | 
				
			||||||
	FILE *fp;
 | 
						FILE *fp;
 | 
				
			||||||
	int rc;
 | 
					 | 
				
			||||||
	bool container_pid = false;
 | 
						bool container_pid = false;
 | 
				
			||||||
	bool openvz_host = false;
 | 
						bool openvz_host = false;
 | 
				
			||||||
	char *line = NULL;
 | 
						char *line = NULL;
 | 
				
			||||||
	char my_ns[30];
 | 
					 | 
				
			||||||
	char proc_ns[30];
 | 
					 | 
				
			||||||
	size_t len = 0;
 | 
						size_t len = 0;
 | 
				
			||||||
	pid_t p;
 | 
						pid_t p;
 | 
				
			||||||
	char *buffer = NULL;
 | 
						char buffer[PATH_MAX];
 | 
				
			||||||
	struct stat sb;
 | 
						struct stat sb;
 | 
				
			||||||
	pid_t openrc_pid = 0;
 | 
						pid_t openrc_pid = 0;
 | 
				
			||||||
	char *pp;
 | 
						char *pp;
 | 
				
			||||||
@@ -138,14 +131,6 @@ rc_find_pids(const char *exec, const char *const *argv, uid_t uid, pid_t pid)
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset(my_ns, 0, sizeof(my_ns));
 | 
					 | 
				
			||||||
	memset(proc_ns, 0, sizeof(proc_ns));
 | 
					 | 
				
			||||||
	if (exists("/proc/self/ns/pid")) {
 | 
					 | 
				
			||||||
		rc = readlink("/proc/self/ns/pid", my_ns, sizeof(my_ns));
 | 
					 | 
				
			||||||
		if (rc <= 0)
 | 
					 | 
				
			||||||
			my_ns[0] = '\0';
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	while ((entry = readdir(procdir)) != NULL) {
 | 
						while ((entry = readdir(procdir)) != NULL) {
 | 
				
			||||||
		if (sscanf(entry->d_name, "%d", &p) != 1)
 | 
							if (sscanf(entry->d_name, "%d", &p) != 1)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
@@ -153,22 +138,10 @@ rc_find_pids(const char *exec, const char *const *argv, uid_t uid, pid_t pid)
 | 
				
			|||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		if (pid != 0 && pid != p)
 | 
							if (pid != 0 && pid != p)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		xasprintf(&buffer, "/proc/%d/ns/pid", p);
 | 
					 | 
				
			||||||
		if (exists(buffer)) {
 | 
					 | 
				
			||||||
			rc = readlink(buffer, proc_ns, sizeof(proc_ns));
 | 
					 | 
				
			||||||
			if (rc <= 0)
 | 
					 | 
				
			||||||
				proc_ns[0] = '\0';
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		free(buffer);
 | 
					 | 
				
			||||||
		if (strlen(my_ns) && strlen (proc_ns) && strcmp(my_ns, proc_ns))
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
		if (uid) {
 | 
							if (uid) {
 | 
				
			||||||
			xasprintf(&buffer, "/proc/%d", p);
 | 
								snprintf(buffer, sizeof(buffer), "/proc/%d", p);
 | 
				
			||||||
			if (stat(buffer, &sb) != 0 || sb.st_uid != uid) {
 | 
								if (stat(buffer, &sb) != 0 || sb.st_uid != uid)
 | 
				
			||||||
				free(buffer);
 | 
					 | 
				
			||||||
				continue;
 | 
									continue;
 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			free(buffer);
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (exec && !pid_is_exec(p, exec))
 | 
							if (exec && !pid_is_exec(p, exec))
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
@@ -177,10 +150,9 @@ rc_find_pids(const char *exec, const char *const *argv, uid_t uid, pid_t pid)
 | 
				
			|||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		/* If this is an OpenVZ host, filter out container processes */
 | 
							/* If this is an OpenVZ host, filter out container processes */
 | 
				
			||||||
		if (openvz_host) {
 | 
							if (openvz_host) {
 | 
				
			||||||
			xasprintf(&buffer, "/proc/%d/status", p);
 | 
								snprintf(buffer, sizeof(buffer), "/proc/%d/status", p);
 | 
				
			||||||
			if (exists(buffer)) {
 | 
								if (exists(buffer)) {
 | 
				
			||||||
				fp = fopen(buffer, "r");
 | 
									fp = fopen(buffer, "r");
 | 
				
			||||||
				free(buffer);
 | 
					 | 
				
			||||||
				if (! fp)
 | 
									if (! fp)
 | 
				
			||||||
					continue;
 | 
										continue;
 | 
				
			||||||
				while (! feof(fp)) {
 | 
									while (! feof(fp)) {
 | 
				
			||||||
@@ -324,13 +296,12 @@ _match_daemon(const char *path, const char *file, RC_STRINGLIST *match)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	char *line = NULL;
 | 
						char *line = NULL;
 | 
				
			||||||
	size_t len = 0;
 | 
						size_t len = 0;
 | 
				
			||||||
	char *ffile = NULL;
 | 
						char ffile[PATH_MAX];
 | 
				
			||||||
	FILE *fp;
 | 
						FILE *fp;
 | 
				
			||||||
	RC_STRING *m;
 | 
						RC_STRING *m;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	xasprintf(&ffile, "%s/%s", path, file);
 | 
						snprintf(ffile, sizeof(ffile), "%s/%s", path, file);
 | 
				
			||||||
	fp = fopen(ffile, "r");
 | 
						fp = fopen(ffile, "r");
 | 
				
			||||||
	free(ffile);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!fp)
 | 
						if (!fp)
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
@@ -356,22 +327,29 @@ _match_list(const char *exec, const char *const *argv, const char *pidfile)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	RC_STRINGLIST *match = rc_stringlist_new();
 | 
						RC_STRINGLIST *match = rc_stringlist_new();
 | 
				
			||||||
	int i = 0;
 | 
						int i = 0;
 | 
				
			||||||
 | 
						size_t l;
 | 
				
			||||||
	char *m;
 | 
						char *m;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (exec) {
 | 
						if (exec) {
 | 
				
			||||||
		xasprintf(&m, "exec=%s", exec);
 | 
							l = strlen(exec) + 6;
 | 
				
			||||||
 | 
							m = xmalloc(sizeof(char) * l);
 | 
				
			||||||
 | 
							snprintf(m, l, "exec=%s", exec);
 | 
				
			||||||
		rc_stringlist_add(match, m);
 | 
							rc_stringlist_add(match, m);
 | 
				
			||||||
		free(m);
 | 
							free(m);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while (argv && argv[i]) {
 | 
						while (argv && argv[i]) {
 | 
				
			||||||
		xasprintf(&m, "argv_0=%s", argv[i++]);
 | 
							l = strlen(*argv) + strlen("argv_=") + 16;
 | 
				
			||||||
 | 
							m = xmalloc(sizeof(char) * l);
 | 
				
			||||||
 | 
							snprintf(m, l, "argv_0=%s", argv[i++]);
 | 
				
			||||||
		rc_stringlist_add(match, m);
 | 
							rc_stringlist_add(match, m);
 | 
				
			||||||
		free(m);
 | 
							free(m);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (pidfile) {
 | 
						if (pidfile) {
 | 
				
			||||||
		xasprintf(&m, "pidfile=%s", pidfile);
 | 
							l = strlen(pidfile) + 9;
 | 
				
			||||||
 | 
							m = xmalloc(sizeof(char) * l);
 | 
				
			||||||
 | 
							snprintf(m, l, "pidfile=%s", pidfile);
 | 
				
			||||||
		rc_stringlist_add(match, m);
 | 
							rc_stringlist_add(match, m);
 | 
				
			||||||
		free(m);
 | 
							free(m);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -384,8 +362,8 @@ rc_service_daemon_set(const char *service, const char *exec,
 | 
				
			|||||||
    const char *const *argv,
 | 
					    const char *const *argv,
 | 
				
			||||||
    const char *pidfile, bool started)
 | 
					    const char *pidfile, bool started)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char *dirpath = NULL;
 | 
						char dirpath[PATH_MAX];
 | 
				
			||||||
	char *file = NULL;
 | 
						char file[PATH_MAX];
 | 
				
			||||||
	int nfiles = 0;
 | 
						int nfiles = 0;
 | 
				
			||||||
	char oldfile[PATH_MAX] = { '\0' };
 | 
						char oldfile[PATH_MAX] = { '\0' };
 | 
				
			||||||
	bool retval = false;
 | 
						bool retval = false;
 | 
				
			||||||
@@ -400,7 +378,8 @@ rc_service_daemon_set(const char *service, const char *exec,
 | 
				
			|||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	xasprintf(&dirpath, RC_SVCDIR "/daemons/%s", basename_c(service));
 | 
						snprintf(dirpath, sizeof(dirpath), RC_SVCDIR "/daemons/%s",
 | 
				
			||||||
 | 
						    basename_c(service));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Regardless, erase any existing daemon info */
 | 
						/* Regardless, erase any existing daemon info */
 | 
				
			||||||
	if ((dp = opendir(dirpath))) {
 | 
						if ((dp = opendir(dirpath))) {
 | 
				
			||||||
@@ -409,7 +388,8 @@ rc_service_daemon_set(const char *service, const char *exec,
 | 
				
			|||||||
			if (d->d_name[0] == '.')
 | 
								if (d->d_name[0] == '.')
 | 
				
			||||||
				continue;
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			xasprintf(&file, "%s/%s", dirpath, d->d_name);
 | 
								snprintf(file, sizeof(file), "%s/%s",
 | 
				
			||||||
 | 
								    dirpath, d->d_name);
 | 
				
			||||||
			nfiles++;
 | 
								nfiles++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (!*oldfile) {
 | 
								if (!*oldfile) {
 | 
				
			||||||
@@ -422,7 +402,6 @@ rc_service_daemon_set(const char *service, const char *exec,
 | 
				
			|||||||
				rename(file, oldfile);
 | 
									rename(file, oldfile);
 | 
				
			||||||
				strlcpy(oldfile, file, sizeof(oldfile));
 | 
									strlcpy(oldfile, file, sizeof(oldfile));
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			free(file);
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		closedir(dp);
 | 
							closedir(dp);
 | 
				
			||||||
		rc_stringlist_free(match);
 | 
							rc_stringlist_free(match);
 | 
				
			||||||
@@ -431,7 +410,8 @@ rc_service_daemon_set(const char *service, const char *exec,
 | 
				
			|||||||
	/* Now store our daemon info */
 | 
						/* Now store our daemon info */
 | 
				
			||||||
	if (started) {
 | 
						if (started) {
 | 
				
			||||||
		if (mkdir(dirpath, 0755) == 0 || errno == EEXIST) {
 | 
							if (mkdir(dirpath, 0755) == 0 || errno == EEXIST) {
 | 
				
			||||||
			xasprintf(&file, "%s/%03d", dirpath, nfiles + 1);
 | 
								snprintf(file, sizeof(file), "%s/%03d",
 | 
				
			||||||
 | 
								    dirpath, nfiles + 1);
 | 
				
			||||||
			if ((fp = fopen(file, "w"))) {
 | 
								if ((fp = fopen(file, "w"))) {
 | 
				
			||||||
				fprintf(fp, "exec=");
 | 
									fprintf(fp, "exec=");
 | 
				
			||||||
				if (exec)
 | 
									if (exec)
 | 
				
			||||||
@@ -447,12 +427,10 @@ rc_service_daemon_set(const char *service, const char *exec,
 | 
				
			|||||||
				fclose(fp);
 | 
									fclose(fp);
 | 
				
			||||||
				retval = true;
 | 
									retval = true;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			free(file);
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else
 | 
						} else
 | 
				
			||||||
		retval = true;
 | 
							retval = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	free(dirpath);
 | 
					 | 
				
			||||||
	return retval;
 | 
						return retval;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
librc_hidden_def(rc_service_daemon_set)
 | 
					librc_hidden_def(rc_service_daemon_set)
 | 
				
			||||||
@@ -461,8 +439,8 @@ bool
 | 
				
			|||||||
rc_service_started_daemon(const char *service,
 | 
					rc_service_started_daemon(const char *service,
 | 
				
			||||||
    const char *exec, const char *const *argv, int indx)
 | 
					    const char *exec, const char *const *argv, int indx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char *dirpath = NULL;
 | 
						char dirpath[PATH_MAX];
 | 
				
			||||||
	char *file = NULL;
 | 
						char file[16];
 | 
				
			||||||
	RC_STRINGLIST *match;
 | 
						RC_STRINGLIST *match;
 | 
				
			||||||
	bool retval = false;
 | 
						bool retval = false;
 | 
				
			||||||
	DIR *dp;
 | 
						DIR *dp;
 | 
				
			||||||
@@ -471,13 +449,13 @@ rc_service_started_daemon(const char *service,
 | 
				
			|||||||
	if (!service || !exec)
 | 
						if (!service || !exec)
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	xasprintf(&dirpath, RC_SVCDIR "/daemons/%s", basename_c(service));
 | 
						snprintf(dirpath, sizeof(dirpath), RC_SVCDIR "/daemons/%s",
 | 
				
			||||||
 | 
						    basename_c(service));
 | 
				
			||||||
	match = _match_list(exec, argv, NULL);
 | 
						match = _match_list(exec, argv, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (indx > 0) {
 | 
						if (indx > 0) {
 | 
				
			||||||
		xasprintf(&file, "%03d", indx);
 | 
							snprintf(file, sizeof(file), "%03d", indx);
 | 
				
			||||||
		retval = _match_daemon(dirpath, file, match);
 | 
							retval = _match_daemon(dirpath, file, match);
 | 
				
			||||||
		free(file);
 | 
					 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		if ((dp = opendir(dirpath))) {
 | 
							if ((dp = opendir(dirpath))) {
 | 
				
			||||||
			while ((d = readdir(dp))) {
 | 
								while ((d = readdir(dp))) {
 | 
				
			||||||
@@ -492,7 +470,6 @@ rc_service_started_daemon(const char *service,
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rc_stringlist_free(match);
 | 
						rc_stringlist_free(match);
 | 
				
			||||||
	free(dirpath);
 | 
					 | 
				
			||||||
	return retval;
 | 
						return retval;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
librc_hidden_def(rc_service_started_daemon)
 | 
					librc_hidden_def(rc_service_started_daemon)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -237,9 +237,13 @@ static void rc_config_set_value(RC_STRINGLIST *config, char *value)
 | 
				
			|||||||
		if (token[i] == '\n')
 | 
							if (token[i] == '\n')
 | 
				
			||||||
			token[i] = 0;
 | 
								token[i] = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		xasprintf(&newline, "%s=%s", entry, token);
 | 
							i = strlen(entry) + strlen(token) + 2;
 | 
				
			||||||
 | 
							newline = xmalloc(sizeof(char) * i);
 | 
				
			||||||
 | 
							snprintf(newline, i, "%s=%s", entry, token);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		xasprintf(&newline, "%s=", entry);
 | 
							i = strlen(entry) + 2;
 | 
				
			||||||
 | 
							newline = xmalloc(sizeof(char) * i);
 | 
				
			||||||
 | 
							snprintf(newline, i, "%s=", entry);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	replaced = false;
 | 
						replaced = false;
 | 
				
			||||||
@@ -277,6 +281,7 @@ static RC_STRINGLIST *rc_config_kcl(RC_STRINGLIST *config)
 | 
				
			|||||||
	char *tmp = NULL;
 | 
						char *tmp = NULL;
 | 
				
			||||||
	char *value = NULL;
 | 
						char *value = NULL;
 | 
				
			||||||
	size_t varlen = 0;
 | 
						size_t varlen = 0;
 | 
				
			||||||
 | 
						size_t len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	overrides = rc_stringlist_new();
 | 
						overrides = rc_stringlist_new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -294,7 +299,9 @@ static RC_STRINGLIST *rc_config_kcl(RC_STRINGLIST *config)
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (value != NULL) {
 | 
							if (value != NULL) {
 | 
				
			||||||
			xasprintf(&tmp, "%s=%s", override->value, value);
 | 
								len = varlen + strlen(value) + 2;
 | 
				
			||||||
 | 
								tmp = xmalloc(sizeof(char) * len);
 | 
				
			||||||
 | 
								snprintf(tmp, len, "%s=%s", override->value, value);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -50,7 +50,6 @@ static const rc_service_state_name_t rc_service_state_names[] = {
 | 
				
			|||||||
	{ RC_SERVICE_HOTPLUGGED,  "hotplugged" },
 | 
						{ RC_SERVICE_HOTPLUGGED,  "hotplugged" },
 | 
				
			||||||
	{ RC_SERVICE_FAILED,      "failed" },
 | 
						{ RC_SERVICE_FAILED,      "failed" },
 | 
				
			||||||
	{ RC_SERVICE_SCHEDULED,   "scheduled"},
 | 
						{ RC_SERVICE_SCHEDULED,   "scheduled"},
 | 
				
			||||||
	{ RC_SERVICE_CRASHED,     "crashed"},
 | 
					 | 
				
			||||||
	{ 0, NULL}
 | 
						{ 0, NULL}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -849,10 +848,6 @@ rc_service_state(const char *service)
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (state & RC_SERVICE_STARTED) {
 | 
					 | 
				
			||||||
		if (rc_service_daemons_crashed(service) && errno != EACCES)
 | 
					 | 
				
			||||||
			state |= RC_SERVICE_CRASHED;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (state & RC_SERVICE_STOPPED) {
 | 
						if (state & RC_SERVICE_STOPPED) {
 | 
				
			||||||
		dirs = ls_dir(RC_SVCDIR "/scheduled", 0);
 | 
							dirs = ls_dir(RC_SVCDIR "/scheduled", 0);
 | 
				
			||||||
		TAILQ_FOREACH(dir, dirs, entries) {
 | 
							TAILQ_FOREACH(dir, dirs, entries) {
 | 
				
			||||||
@@ -899,15 +894,12 @@ rc_service_value_set(const char *service, const char *option,
 | 
				
			|||||||
		return false;
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	snprintf(p, sizeof(file) - (p - file), "/%s", option);
 | 
						snprintf(p, sizeof(file) - (p - file), "/%s", option);
 | 
				
			||||||
	if (value) {
 | 
						if (!(fp = fopen(file, "w")))
 | 
				
			||||||
		if (!(fp = fopen(file, "w")))
 | 
							return false;
 | 
				
			||||||
			return false;
 | 
						if (value)
 | 
				
			||||||
		fprintf(fp, "%s", value);
 | 
							fprintf(fp, "%s", value);
 | 
				
			||||||
		fclose(fp);
 | 
						fclose(fp);
 | 
				
			||||||
	} else {
 | 
						return true;
 | 
				
			||||||
		unlink(file);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
		return true;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
librc_hidden_def(rc_service_value_set)
 | 
					librc_hidden_def(rc_service_value_set)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -188,8 +188,7 @@ typedef enum
 | 
				
			|||||||
	/* Optional states service could also be in */
 | 
						/* Optional states service could also be in */
 | 
				
			||||||
	RC_SERVICE_FAILED      = 0x0200,
 | 
						RC_SERVICE_FAILED      = 0x0200,
 | 
				
			||||||
	RC_SERVICE_SCHEDULED   = 0x0400,
 | 
						RC_SERVICE_SCHEDULED   = 0x0400,
 | 
				
			||||||
	RC_SERVICE_WASINACTIVE = 0x0800,
 | 
						RC_SERVICE_WASINACTIVE = 0x0800
 | 
				
			||||||
	RC_SERVICE_CRASHED     = 0x1000,
 | 
					 | 
				
			||||||
} RC_SERVICE;
 | 
					} RC_SERVICE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*! Add the service to the runlevel
 | 
					/*! Add the service to the runlevel
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								src/rc/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								src/rc/.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -56,7 +56,6 @@ mark_service_inactive
 | 
				
			|||||||
mark_service_wasinactive
 | 
					mark_service_wasinactive
 | 
				
			||||||
mark_service_hotplugged
 | 
					mark_service_hotplugged
 | 
				
			||||||
mark_service_failed
 | 
					mark_service_failed
 | 
				
			||||||
mark_service_crashed
 | 
					 | 
				
			||||||
rc-abort
 | 
					rc-abort
 | 
				
			||||||
rc
 | 
					rc
 | 
				
			||||||
openrc
 | 
					openrc
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,8 +5,8 @@ include ${MK}/os.mk
 | 
				
			|||||||
SRCS=	checkpath.c do_e.c do_mark_service.c do_service.c \
 | 
					SRCS=	checkpath.c do_e.c do_mark_service.c do_service.c \
 | 
				
			||||||
		do_value.c fstabinfo.c is_newer_than.c is_older_than.c \
 | 
							do_value.c fstabinfo.c is_newer_than.c is_older_than.c \
 | 
				
			||||||
		mountinfo.c openrc-run.c rc-abort.c rc.c \
 | 
							mountinfo.c openrc-run.c rc-abort.c rc.c \
 | 
				
			||||||
		rc-depend.c rc-logger.c rc-misc.c rc-pipes.c \
 | 
							rc-depend.c rc-logger.c rc-misc.c rc-plugin.c \
 | 
				
			||||||
		rc-plugin.c rc-service.c rc-status.c rc-update.c \
 | 
							rc-service.c rc-status.c rc-update.c \
 | 
				
			||||||
		shell_var.c start-stop-daemon.c supervise-daemon.c swclock.c _usage.c
 | 
							shell_var.c start-stop-daemon.c supervise-daemon.c swclock.c _usage.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ifeq (${MKSELINUX},yes)
 | 
					ifeq (${MKSELINUX},yes)
 | 
				
			||||||
@@ -14,7 +14,7 @@ SRCS+=		rc-selinux.c
 | 
				
			|||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ifeq (${OS},Linux)
 | 
					ifeq (${OS},Linux)
 | 
				
			||||||
SRCS+=		kill_all.c openrc-init.c openrc-shutdown.c broadcast.c rc-wtmp.c
 | 
					SRCS+=		kill_all.c openrc-init.c openrc-shutdown.c rc-wtmp.c
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CLEANFILES=	version.h rc-selinux.o
 | 
					CLEANFILES=	version.h rc-selinux.o
 | 
				
			||||||
@@ -41,7 +41,6 @@ RC_SBINPROGS=	mark_service_starting mark_service_started \
 | 
				
			|||||||
		mark_service_stopping mark_service_stopped \
 | 
							mark_service_stopping mark_service_stopped \
 | 
				
			||||||
		mark_service_inactive mark_service_wasinactive \
 | 
							mark_service_inactive mark_service_wasinactive \
 | 
				
			||||||
		mark_service_hotplugged mark_service_failed \
 | 
							mark_service_hotplugged mark_service_failed \
 | 
				
			||||||
		mark_service_crashed \
 | 
					 | 
				
			||||||
		rc-abort swclock
 | 
							rc-abort swclock
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ifeq (${OS},Linux)
 | 
					ifeq (${OS},Linux)
 | 
				
			||||||
@@ -124,8 +123,7 @@ is_older_than: is_older_than.o rc-misc.o
 | 
				
			|||||||
mark_service_starting mark_service_started \
 | 
					mark_service_starting mark_service_started \
 | 
				
			||||||
mark_service_stopping mark_service_stopped \
 | 
					mark_service_stopping mark_service_stopped \
 | 
				
			||||||
mark_service_inactive mark_service_wasinactive \
 | 
					mark_service_inactive mark_service_wasinactive \
 | 
				
			||||||
mark_service_hotplugged mark_service_failed \
 | 
					mark_service_hotplugged mark_service_failed: do_mark_service.o rc-misc.o
 | 
				
			||||||
mark_service_crashed: do_mark_service.o rc-misc.o
 | 
					 | 
				
			||||||
	${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
 | 
						${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
mountinfo: mountinfo.o _usage.o rc-misc.o
 | 
					mountinfo: mountinfo.o _usage.o rc-misc.o
 | 
				
			||||||
@@ -134,7 +132,7 @@ mountinfo: mountinfo.o _usage.o rc-misc.o
 | 
				
			|||||||
openrc rc: rc.o rc-logger.o rc-misc.o rc-plugin.o _usage.o
 | 
					openrc rc: rc.o rc-logger.o rc-misc.o rc-plugin.o _usage.o
 | 
				
			||||||
	${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
 | 
						${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
openrc-shutdown: openrc-shutdown.o rc-misc.o _usage.o broadcast.o rc-wtmp.o
 | 
					openrc-shutdown: openrc-shutdown.o _usage.o rc-wtmp.o
 | 
				
			||||||
	${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
 | 
						${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
openrc-run runscript: openrc-run.o _usage.o rc-misc.o rc-plugin.o
 | 
					openrc-run runscript: openrc-run.o _usage.o rc-misc.o rc-plugin.o
 | 
				
			||||||
@@ -158,10 +156,10 @@ rc-service: rc-service.o _usage.o rc-misc.o
 | 
				
			|||||||
rc-update: rc-update.o _usage.o rc-misc.o
 | 
					rc-update: rc-update.o _usage.o rc-misc.o
 | 
				
			||||||
	${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
 | 
						${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
start-stop-daemon: start-stop-daemon.o _usage.o rc-misc.o rc-pipes.o rc-schedules.o
 | 
					start-stop-daemon: start-stop-daemon.o _usage.o rc-misc.o rc-schedules.o
 | 
				
			||||||
	${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
 | 
						${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
supervise-daemon: supervise-daemon.o _usage.o rc-misc.o rc-plugin.o rc-schedules.o
 | 
					supervise-daemon: supervise-daemon.o _usage.o rc-misc.o rc-schedules.o
 | 
				
			||||||
	${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
 | 
						${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
service_get_value service_set_value get_options save_options: do_value.o rc-misc.o
 | 
					service_get_value service_set_value get_options save_options: do_value.o rc-misc.o
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,209 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 * broadcast.c
 | 
					 | 
				
			||||||
 * broadcast a message to every logged in user
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Copyright 2018 Sony Interactive Entertainment Inc.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * 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.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#include <ctype.h>
 | 
					 | 
				
			||||||
#include <sys/types.h>
 | 
					 | 
				
			||||||
#include <sys/stat.h>
 | 
					 | 
				
			||||||
#include <sys/sysmacros.h>
 | 
					 | 
				
			||||||
#include <limits.h>
 | 
					 | 
				
			||||||
#include <stdlib.h>
 | 
					 | 
				
			||||||
#include <string.h>
 | 
					 | 
				
			||||||
#include <time.h>
 | 
					 | 
				
			||||||
#include <unistd.h>
 | 
					 | 
				
			||||||
#include <stdio.h>
 | 
					 | 
				
			||||||
#include <utmpx.h>
 | 
					 | 
				
			||||||
#include <pwd.h>
 | 
					 | 
				
			||||||
#include <fcntl.h>
 | 
					 | 
				
			||||||
#include <signal.h>
 | 
					 | 
				
			||||||
#include <setjmp.h>
 | 
					 | 
				
			||||||
#include <paths.h>
 | 
					 | 
				
			||||||
#include <sys/utsname.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "broadcast.h"
 | 
					 | 
				
			||||||
#include "helpers.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef _PATH_DEV
 | 
					 | 
				
			||||||
# define _PATH_DEV	"/dev/"
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef UT_LINESIZE
 | 
					 | 
				
			||||||
#define UT_LINESIZE __UT_LINESIZE
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static sigjmp_buf jbuf;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 *	Alarm handler
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
/*ARGSUSED*/
 | 
					 | 
				
			||||||
# ifdef __GNUC__
 | 
					 | 
				
			||||||
static void handler(int arg __attribute__((unused)))
 | 
					 | 
				
			||||||
# else
 | 
					 | 
				
			||||||
static void handler(int arg)
 | 
					 | 
				
			||||||
# endif
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	siglongjmp(jbuf, 1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void getuidtty(char **userp, char **ttyp)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct passwd 		*pwd;
 | 
					 | 
				
			||||||
	uid_t			uid;
 | 
					 | 
				
			||||||
	char			*tty;
 | 
					 | 
				
			||||||
	static char		uidbuf[32];
 | 
					 | 
				
			||||||
	static char		ttynm[UT_LINESIZE + 4];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	uid = getuid();
 | 
					 | 
				
			||||||
	if ((pwd = getpwuid(uid)) != NULL) {
 | 
					 | 
				
			||||||
		uidbuf[0] = 0;
 | 
					 | 
				
			||||||
		strncat(uidbuf, pwd->pw_name, sizeof(uidbuf) - 1);
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		if (uid)
 | 
					 | 
				
			||||||
			sprintf(uidbuf, "uid %d", (int) uid);
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			sprintf(uidbuf, "root");
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ((tty = ttyname(0)) != NULL) {
 | 
					 | 
				
			||||||
		const size_t plen = strlen(_PATH_DEV);
 | 
					 | 
				
			||||||
		if (strncmp(tty, _PATH_DEV, plen) == 0) {
 | 
					 | 
				
			||||||
			tty += plen;
 | 
					 | 
				
			||||||
			if (tty[0] == '/')
 | 
					 | 
				
			||||||
				tty++;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		snprintf(ttynm, sizeof(ttynm), "(%.*s) ",
 | 
					 | 
				
			||||||
				 UT_LINESIZE, tty);
 | 
					 | 
				
			||||||
	} else
 | 
					 | 
				
			||||||
		ttynm[0] = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	*userp = uidbuf;
 | 
					 | 
				
			||||||
	*ttyp  = ttynm;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 *	Check whether the given filename looks like a tty device.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static int file_isatty(const char *fname)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct stat		st;
 | 
					 | 
				
			||||||
	int			major;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (stat(fname, &st) < 0)
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (st.st_nlink != 1 || !S_ISCHR(st.st_mode))
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 *	It would be an impossible task to list all major/minors
 | 
					 | 
				
			||||||
	 *	of tty devices here, so we just exclude the obvious
 | 
					 | 
				
			||||||
	 *	majors of which just opening has side-effects:
 | 
					 | 
				
			||||||
	 *	printers and tapes.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	major = major(st.st_dev);
 | 
					 | 
				
			||||||
	if (major == 1 || major == 2 || major == 6 || major == 9 ||
 | 
					 | 
				
			||||||
	    major == 12 || major == 16 || major == 21 || major == 27 ||
 | 
					 | 
				
			||||||
	    major == 37 || major == 96 || major == 97 || major == 206 ||
 | 
					 | 
				
			||||||
	    major == 230)
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 *	broadcast function.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void broadcast(char *text)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	char *tty;
 | 
					 | 
				
			||||||
	char *user;
 | 
					 | 
				
			||||||
	struct utsname name;
 | 
					 | 
				
			||||||
	time_t t;
 | 
					 | 
				
			||||||
	char	*date;
 | 
					 | 
				
			||||||
	char *p;
 | 
					 | 
				
			||||||
	char *line = NULL;
 | 
					 | 
				
			||||||
	struct sigaction sa;
 | 
					 | 
				
			||||||
	volatile int fd;
 | 
					 | 
				
			||||||
	FILE *tp;
 | 
					 | 
				
			||||||
	int	flags;
 | 
					 | 
				
			||||||
	char *term = NULL;
 | 
					 | 
				
			||||||
	struct utmpx *utmp;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	getuidtty(&user, &tty);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * Get and report current hostname, to make it easier to find out
 | 
					 | 
				
			||||||
	 * which machine is being shut down.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	uname(&name);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Get the time */
 | 
					 | 
				
			||||||
	time(&t);
 | 
					 | 
				
			||||||
	date = ctime(&t);
 | 
					 | 
				
			||||||
	p = strchr(date, '\n');
 | 
					 | 
				
			||||||
	if (p)
 | 
					 | 
				
			||||||
		*p = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	xasprintf(&line, "\007\r\nBroadcast message from %s@%s %s(%s):\r\n\r\n",
 | 
					 | 
				
			||||||
			user, name.nodename, tty, date);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 *	Fork to avoid hanging in a write()
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	if (fork() != 0)
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	memset(&sa, 0, sizeof(sa));
 | 
					 | 
				
			||||||
	sa.sa_handler = handler;
 | 
					 | 
				
			||||||
	sigemptyset(&sa.sa_mask);
 | 
					 | 
				
			||||||
	sigaction(SIGALRM, &sa, NULL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	setutxent();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	while ((utmp = getutxent()) != NULL) {
 | 
					 | 
				
			||||||
		if (utmp->ut_type != USER_PROCESS || utmp->ut_user[0] == 0)
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
		if (strncmp(utmp->ut_line, _PATH_DEV, strlen(_PATH_DEV)) == 0)
 | 
					 | 
				
			||||||
			xasprintf(&term, "%s", utmp->ut_line);
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			xasprintf(&term, "%s%s", _PATH_DEV, utmp->ut_line);
 | 
					 | 
				
			||||||
		if (strstr(term, "/../")) {
 | 
					 | 
				
			||||||
			free(term);
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/*
 | 
					 | 
				
			||||||
		 *	Open it non-delay
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		if (sigsetjmp(jbuf, 1) == 0) {
 | 
					 | 
				
			||||||
			alarm(2);
 | 
					 | 
				
			||||||
			flags = O_WRONLY|O_NDELAY|O_NOCTTY;
 | 
					 | 
				
			||||||
			if (file_isatty(term) && (fd = open(term, flags)) >= 0) {
 | 
					 | 
				
			||||||
				if (isatty(fd) && (tp = fdopen(fd, "w")) != NULL) {
 | 
					 | 
				
			||||||
					fputs(line, tp);
 | 
					 | 
				
			||||||
					fputs(text, tp);
 | 
					 | 
				
			||||||
					fflush(tp);
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		alarm(0);
 | 
					 | 
				
			||||||
		if (fd >= 0)
 | 
					 | 
				
			||||||
			close(fd);
 | 
					 | 
				
			||||||
		if (tp != NULL)
 | 
					 | 
				
			||||||
			fclose(tp);
 | 
					 | 
				
			||||||
		free(term);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	endutxent();
 | 
					 | 
				
			||||||
	free(line);
 | 
					 | 
				
			||||||
	exit(0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,16 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 * Copyright 2018 Sony Interactive Entertainment Inc.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * 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.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef BROADCAST_H
 | 
					 | 
				
			||||||
#define BROADCAST_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void broadcast(char *text);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
@@ -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;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -269,13 +235,11 @@ int main(int argc, char **argv)
 | 
				
			|||||||
		switch (opt) {
 | 
							switch (opt) {
 | 
				
			||||||
		case 'D':
 | 
							case 'D':
 | 
				
			||||||
			trunc = true;
 | 
								trunc = true;
 | 
				
			||||||
			/* falls through */
 | 
					 | 
				
			||||||
		case 'd':
 | 
							case 'd':
 | 
				
			||||||
			type = inode_dir;
 | 
								type = inode_dir;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case 'F':
 | 
							case 'F':
 | 
				
			||||||
			trunc = true;
 | 
								trunc = true;
 | 
				
			||||||
			/* falls through */
 | 
					 | 
				
			||||||
		case 'f':
 | 
							case 'f':
 | 
				
			||||||
			type = inode_file;
 | 
								type = inode_file;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -68,7 +68,9 @@ int main(int argc, char **argv)
 | 
				
			|||||||
		ok = rc_service_started_daemon(service, exec, NULL, idx);
 | 
							ok = rc_service_started_daemon(service, exec, NULL, idx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	} else if (strcmp(applet, "service_crashed") == 0) {
 | 
						} else if (strcmp(applet, "service_crashed") == 0) {
 | 
				
			||||||
		ok = ( rc_service_daemons_crashed(service) && errno != EACCES);
 | 
							ok = (_rc_can_find_pids() &&
 | 
				
			||||||
 | 
							    rc_service_daemons_crashed(service) &&
 | 
				
			||||||
 | 
							    errno != EACCES);
 | 
				
			||||||
	} else
 | 
						} else
 | 
				
			||||||
		eerrorx("%s: unknown applet", applet);
 | 
							eerrorx("%s: unknown applet", applet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -58,14 +58,14 @@ static int mount_proc(void)
 | 
				
			|||||||
	if (exists("/proc/version"))
 | 
						if (exists("/proc/version"))
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	pid = fork();
 | 
						pid = fork();
 | 
				
			||||||
	switch (pid) {
 | 
						switch(pid) {
 | 
				
			||||||
		case -1:
 | 
							case -1:
 | 
				
			||||||
			syslog(LOG_ERR, "Unable to fork");
 | 
								syslog(LOG_ERR, "Unable to fork");
 | 
				
			||||||
			return -1;
 | 
								return -1;
 | 
				
			||||||
			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);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,23 +24,17 @@
 | 
				
			|||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <time.h>
 | 
					 | 
				
			||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
#include <sys/types.h>
 | 
					#include <sys/types.h>
 | 
				
			||||||
#include <sys/stat.h>
 | 
					#include <sys/stat.h>
 | 
				
			||||||
#include <sys/reboot.h>
 | 
					#include <sys/reboot.h>
 | 
				
			||||||
#include <sys/wait.h>
 | 
					#include <sys/wait.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef HAVE_SELINUX
 | 
					 | 
				
			||||||
#  include <selinux/selinux.h>
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "helpers.h"
 | 
					#include "helpers.h"
 | 
				
			||||||
#include "rc.h"
 | 
					#include "rc.h"
 | 
				
			||||||
#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)
 | 
				
			||||||
@@ -49,7 +43,7 @@ static pid_t do_openrc(const char *runlevel)
 | 
				
			|||||||
	sigset_t signals;
 | 
						sigset_t signals;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pid = fork();
 | 
						pid = fork();
 | 
				
			||||||
	switch (pid) {
 | 
						switch(pid) {
 | 
				
			||||||
		case -1:
 | 
							case -1:
 | 
				
			||||||
			perror("fork");
 | 
								perror("fork");
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
@@ -59,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:
 | 
				
			||||||
@@ -94,22 +88,19 @@ 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;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_shutdown(const char *runlevel, int cmd)
 | 
					static void handle_shutdown(const char *runlevel, int cmd)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	pid_t pid;
 | 
						pid_t pid;
 | 
				
			||||||
	struct timespec ts;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pid = do_openrc(runlevel);
 | 
						pid = do_openrc(runlevel);
 | 
				
			||||||
	while (waitpid(pid, NULL, 0) != pid);
 | 
						while (waitpid(pid, NULL, 0) != pid);
 | 
				
			||||||
	printf("Sending the final term signal\n");
 | 
						printf("Sending the final term signal\n");
 | 
				
			||||||
	kill(-1, SIGTERM);
 | 
						kill(-1, SIGTERM);
 | 
				
			||||||
	ts.tv_sec = 3;
 | 
						sleep(3);
 | 
				
			||||||
	ts.tv_nsec = 0;
 | 
					 | 
				
			||||||
	nanosleep(&ts, NULL);
 | 
					 | 
				
			||||||
	printf("Sending the final kill signal\n");
 | 
						printf("Sending the final kill signal\n");
 | 
				
			||||||
	kill(-1, SIGKILL);
 | 
						kill(-1, SIGKILL);
 | 
				
			||||||
	sync();
 | 
						sync();
 | 
				
			||||||
@@ -143,7 +134,7 @@ static void reap_zombies(void)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static void signal_handler(int sig)
 | 
					static void signal_handler(int sig)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	switch (sig) {
 | 
						switch(sig) {
 | 
				
			||||||
		case SIGINT:
 | 
							case SIGINT:
 | 
				
			||||||
			handle_shutdown("reboot", RB_AUTOBOOT);
 | 
								handle_shutdown("reboot", RB_AUTOBOOT);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
@@ -165,36 +156,10 @@ int main(int argc, char **argv)
 | 
				
			|||||||
	bool reexec = false;
 | 
						bool reexec = false;
 | 
				
			||||||
	sigset_t signals;
 | 
						sigset_t signals;
 | 
				
			||||||
	struct sigaction sa;
 | 
						struct sigaction sa;
 | 
				
			||||||
#ifdef HAVE_SELINUX
 | 
					 | 
				
			||||||
	int			enforce = 0;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (getpid() != 1)
 | 
						if (getpid() != 1)
 | 
				
			||||||
		return 1;
 | 
							return 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef HAVE_SELINUX
 | 
					 | 
				
			||||||
	if (getenv("SELINUX_INIT") == NULL) {
 | 
					 | 
				
			||||||
		if (is_selinux_enabled() != 1) {
 | 
					 | 
				
			||||||
			if (selinux_init_load_policy(&enforce) == 0) {
 | 
					 | 
				
			||||||
				putenv("SELINUX_INIT=YES");
 | 
					 | 
				
			||||||
				execv(argv[0], argv);
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				if (enforce > 0) {
 | 
					 | 
				
			||||||
					/*
 | 
					 | 
				
			||||||
					 * SELinux in enforcing mode but load_policy failed
 | 
					 | 
				
			||||||
					 * At this point, we probably can't open /dev/console,
 | 
					 | 
				
			||||||
					 * so log() won't work
 | 
					 | 
				
			||||||
					 */
 | 
					 | 
				
			||||||
					fprintf(stderr,"Unable to load SELinux Policy.\n");
 | 
					 | 
				
			||||||
					fprintf(stderr,"Machine is  in enforcing mode.\n");
 | 
					 | 
				
			||||||
					fprintf(stderr,"Halting now.\n");
 | 
					 | 
				
			||||||
					exit(1);
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	printf("OpenRC init version %s starting\n", VERSION);
 | 
						printf("OpenRC init version %s starting\n", VERSION);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (argc > 1)
 | 
						if (argc > 1)
 | 
				
			||||||
@@ -218,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
 | 
				
			||||||
@@ -1268,9 +1255,6 @@ int main(int argc, char **argv)
 | 
				
			|||||||
		case_RC_COMMON_GETOPT
 | 
							case_RC_COMMON_GETOPT
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (rc_yesno(getenv("RC_NODEPS")))
 | 
					 | 
				
			||||||
		deps = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* If we're changing runlevels and not called by rc then we cannot
 | 
						/* If we're changing runlevels and not called by rc then we cannot
 | 
				
			||||||
	   work with any dependencies */
 | 
						   work with any dependencies */
 | 
				
			||||||
	if (deps && getenv("RC_PID") == NULL &&
 | 
						if (deps && getenv("RC_PID") == NULL &&
 | 
				
			||||||
@@ -1285,8 +1269,6 @@ int main(int argc, char **argv)
 | 
				
			|||||||
		unsetenv("IN_BACKGROUND");
 | 
							unsetenv("IN_BACKGROUND");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (rc_yesno(getenv("IN_DRYRUN")))
 | 
					 | 
				
			||||||
	dry_run = true;
 | 
					 | 
				
			||||||
	if (rc_yesno(getenv("IN_HOTPLUG"))) {
 | 
						if (rc_yesno(getenv("IN_HOTPLUG"))) {
 | 
				
			||||||
		if (!service_plugable())
 | 
							if (!service_plugable())
 | 
				
			||||||
			eerrorx("%s: not allowed to be hotplugged", applet);
 | 
								eerrorx("%s: not allowed to be hotplugged", applet);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,24 +25,20 @@
 | 
				
			|||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <syslog.h>
 | 
					 | 
				
			||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
#include <sys/types.h>
 | 
					#include <sys/types.h>
 | 
				
			||||||
#include <sys/utsname.h>
 | 
					#include <sys/utsname.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "broadcast.h"
 | 
					 | 
				
			||||||
#include "einfo.h"
 | 
					#include "einfo.h"
 | 
				
			||||||
#include "rc.h"
 | 
					#include "rc.h"
 | 
				
			||||||
#include "helpers.h"
 | 
					#include "helpers.h"
 | 
				
			||||||
#include "rc-misc.h"
 | 
					 | 
				
			||||||
#include "_usage.h"
 | 
					#include "_usage.h"
 | 
				
			||||||
#include "rc-wtmp.h"
 | 
					#include "rc-wtmp.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const char *applet = NULL;
 | 
					const char *applet = NULL;
 | 
				
			||||||
const char *extraopts = NULL;
 | 
					const char *extraopts = NULL;
 | 
				
			||||||
const char *getoptstring = "cdDfFHKpRrsw" getoptstring_COMMON;
 | 
					const char *getoptstring = "dDHKpRrsw" getoptstring_COMMON;
 | 
				
			||||||
const struct option longopts[] = {
 | 
					const struct option longopts[] = {
 | 
				
			||||||
	{ "cancel",        no_argument, NULL, 'c'},
 | 
					 | 
				
			||||||
	{ "no-write",        no_argument, NULL, 'd'},
 | 
						{ "no-write",        no_argument, NULL, 'd'},
 | 
				
			||||||
	{ "dry-run",        no_argument, NULL, 'D'},
 | 
						{ "dry-run",        no_argument, NULL, 'D'},
 | 
				
			||||||
	{ "halt",        no_argument, NULL, 'H'},
 | 
						{ "halt",        no_argument, NULL, 'H'},
 | 
				
			||||||
@@ -55,7 +51,6 @@ const struct option longopts[] = {
 | 
				
			|||||||
	longopts_COMMON
 | 
						longopts_COMMON
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
const char * const longopts_help[] = {
 | 
					const char * const longopts_help[] = {
 | 
				
			||||||
	"cancel a pending shutdown",
 | 
					 | 
				
			||||||
	"do not write wtmp record",
 | 
						"do not write wtmp record",
 | 
				
			||||||
	"print actions instead of executing them",
 | 
						"print actions instead of executing them",
 | 
				
			||||||
	"halt the system",
 | 
						"halt the system",
 | 
				
			||||||
@@ -69,12 +64,8 @@ const char * const longopts_help[] = {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
const char *usagestring = NULL;
 | 
					const char *usagestring = NULL;
 | 
				
			||||||
const char *exclusive = "Select one of "
 | 
					const char *exclusive = "Select one of "
 | 
				
			||||||
	"--cancel, --halt, --kexec, --poweroff, --reexec, --reboot, --single or \n"
 | 
					"--halt, --kexec, --poweroff, --reexec, --reboot, --single or --write-only";
 | 
				
			||||||
	"--write-only";
 | 
					 | 
				
			||||||
const char *nologin_file = RC_SYSCONFDIR"/nologin";
 | 
					 | 
				
			||||||
const char *shutdown_pid = "/run/openrc-shutdown.pid";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool do_cancel = false;
 | 
					 | 
				
			||||||
static bool do_dryrun = false;
 | 
					static bool do_dryrun = false;
 | 
				
			||||||
static bool do_halt = false;
 | 
					static bool do_halt = false;
 | 
				
			||||||
static bool do_kexec = false;
 | 
					static bool do_kexec = false;
 | 
				
			||||||
@@ -85,40 +76,6 @@ static bool do_single = false;
 | 
				
			|||||||
static bool do_wtmp = true;
 | 
					static bool do_wtmp = true;
 | 
				
			||||||
static bool do_wtmp_only = false;
 | 
					static bool do_wtmp_only = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void cancel_shutdown(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	pid_t pid;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pid = get_pid(applet, shutdown_pid);
 | 
					 | 
				
			||||||
	if (pid <= 0)
 | 
					 | 
				
			||||||
		eerrorx("%s: Unable to cancel shutdown", applet);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (kill(pid, SIGTERM) != -1)
 | 
					 | 
				
			||||||
		einfo("%s: shutdown canceled", applet);
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		eerrorx("%s: Unable to cancel shutdown", applet);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 *	Create the nologin file.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static void create_nologin(int mins)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	FILE *fp;
 | 
					 | 
				
			||||||
	time_t t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	time(&t);
 | 
					 | 
				
			||||||
	t += 60 * mins;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ((fp = fopen(nologin_file, "w")) != NULL) {
 | 
					 | 
				
			||||||
  		fprintf(fp, "\rThe system is going down on %s\r\n", ctime(&t));
 | 
					 | 
				
			||||||
  		fclose(fp);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Send a command to our init
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static void send_cmd(const char *cmd)
 | 
					static void send_cmd(const char *cmd)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	FILE *fifo;
 | 
						FILE *fifo;
 | 
				
			||||||
@@ -142,57 +99,16 @@ static void send_cmd(const char *cmd)
 | 
				
			|||||||
	fclose(fifo);
 | 
						fclose(fifo);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * sleep without being interrupted.
 | 
					 | 
				
			||||||
 * The idea for this code came from sysvinit.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static void sleep_no_interrupt(int seconds)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct timespec duration;
 | 
					 | 
				
			||||||
	struct timespec remaining;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	duration.tv_sec = seconds;
 | 
					 | 
				
			||||||
	duration.tv_nsec = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	while (nanosleep(&duration, &remaining) < 0 && errno == EINTR)
 | 
					 | 
				
			||||||
		duration = remaining;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void stop_shutdown(int sig)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	(void) sig;
 | 
					 | 
				
			||||||
	unlink(nologin_file);
 | 
					 | 
				
			||||||
	unlink(shutdown_pid);
 | 
					 | 
				
			||||||
einfo("Shutdown canceled");
 | 
					 | 
				
			||||||
exit(0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int main(int argc, char **argv)
 | 
					int main(int argc, char **argv)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char *ch = NULL;
 | 
					 | 
				
			||||||
	int opt;
 | 
						int opt;
 | 
				
			||||||
	int cmd_count = 0;
 | 
						int cmd_count = 0;
 | 
				
			||||||
	int hour = 0;
 | 
					 | 
				
			||||||
	int min = 0;
 | 
					 | 
				
			||||||
	int shutdown_delay = 0;
 | 
					 | 
				
			||||||
	struct sigaction sa;
 | 
					 | 
				
			||||||
	struct tm *lt;
 | 
					 | 
				
			||||||
	time_t tv;
 | 
					 | 
				
			||||||
	bool need_warning = false;
 | 
					 | 
				
			||||||
	char *msg = NULL;
 | 
					 | 
				
			||||||
	char *state = NULL;
 | 
					 | 
				
			||||||
	char *time_arg = NULL;
 | 
					 | 
				
			||||||
	FILE *fp;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	applet = basename_c(argv[0]);
 | 
						applet = basename_c(argv[0]);
 | 
				
			||||||
	while ((opt = getopt_long(argc, argv, getoptstring,
 | 
						while ((opt = getopt_long(argc, argv, getoptstring,
 | 
				
			||||||
		    longopts, (int *) 0)) != -1)
 | 
							    longopts, (int *) 0)) != -1)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		switch (opt) {
 | 
							switch (opt) {
 | 
				
			||||||
			case 'c':
 | 
					 | 
				
			||||||
				do_cancel = true;
 | 
					 | 
				
			||||||
			cmd_count++;
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
			case 'd':
 | 
								case 'd':
 | 
				
			||||||
				do_wtmp = false;
 | 
									do_wtmp = false;
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
@@ -201,17 +117,14 @@ int main(int argc, char **argv)
 | 
				
			|||||||
			break;
 | 
								break;
 | 
				
			||||||
		case 'H':
 | 
							case 'H':
 | 
				
			||||||
			do_halt = true;
 | 
								do_halt = true;
 | 
				
			||||||
			xasprintf(&state, "%s", "halt");
 | 
					 | 
				
			||||||
			cmd_count++;
 | 
								cmd_count++;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case 'K':
 | 
							case 'K':
 | 
				
			||||||
			do_kexec = true;
 | 
								do_kexec = true;
 | 
				
			||||||
			xasprintf(&state, "%s", "reboot");
 | 
					 | 
				
			||||||
			cmd_count++;
 | 
								cmd_count++;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case 'p':
 | 
							case 'p':
 | 
				
			||||||
			do_poweroff = true;
 | 
								do_poweroff = true;
 | 
				
			||||||
			xasprintf(&state, "%s", "power off");
 | 
					 | 
				
			||||||
			cmd_count++;
 | 
								cmd_count++;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case 'R':
 | 
							case 'R':
 | 
				
			||||||
@@ -220,12 +133,10 @@ int main(int argc, char **argv)
 | 
				
			|||||||
			break;
 | 
								break;
 | 
				
			||||||
		case 'r':
 | 
							case 'r':
 | 
				
			||||||
			do_reboot = true;
 | 
								do_reboot = true;
 | 
				
			||||||
			xasprintf(&state, "%s", "reboot");
 | 
					 | 
				
			||||||
			cmd_count++;
 | 
								cmd_count++;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case 's':
 | 
							case 's':
 | 
				
			||||||
			do_single = true;
 | 
								do_single = true;
 | 
				
			||||||
			xasprintf(&state, "%s", "go down for maintenance");
 | 
					 | 
				
			||||||
			cmd_count++;
 | 
								cmd_count++;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case 'w':
 | 
							case 'w':
 | 
				
			||||||
@@ -235,91 +146,12 @@ int main(int argc, char **argv)
 | 
				
			|||||||
		case_RC_COMMON_GETOPT
 | 
							case_RC_COMMON_GETOPT
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (geteuid() != 0)
 | 
						if (geteuid() != 0 && ! do_dryrun)
 | 
				
			||||||
		eerrorx("%s: you must be root\n", applet);
 | 
							eerrorx("%s: you must be root\n", applet);
 | 
				
			||||||
	if (cmd_count != 1) {
 | 
						if (cmd_count != 1) {
 | 
				
			||||||
		eerror("%s: %s\n", applet, exclusive);
 | 
							eerror("%s: %s\n", applet, exclusive);
 | 
				
			||||||
		usage(EXIT_FAILURE);
 | 
							usage(EXIT_FAILURE);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (do_cancel) {
 | 
					 | 
				
			||||||
		cancel_shutdown();
 | 
					 | 
				
			||||||
		exit(EXIT_SUCCESS);
 | 
					 | 
				
			||||||
	} else if (do_reexec) {
 | 
					 | 
				
			||||||
		send_cmd("reexec");
 | 
					 | 
				
			||||||
		exit(EXIT_SUCCESS);
 | 
					 | 
				
			||||||
	} else if (do_wtmp_only) {
 | 
					 | 
				
			||||||
		log_wtmp("shutdown", "~~", 0, RUN_LVL, "~~");
 | 
					 | 
				
			||||||
		exit(EXIT_SUCCESS);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (optind >= argc) {
 | 
					 | 
				
			||||||
		eerror("%s: No shutdown time specified", applet);
 | 
					 | 
				
			||||||
		usage(EXIT_FAILURE);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	time_arg = argv[optind];
 | 
					 | 
				
			||||||
	if (*time_arg == '+')
 | 
					 | 
				
			||||||
		time_arg++;
 | 
					 | 
				
			||||||
	if (strcasecmp(time_arg, "now") == 0)
 | 
					 | 
				
			||||||
		strcpy(time_arg, "0");
 | 
					 | 
				
			||||||
	for (ch=time_arg; *ch; ch++)
 | 
					 | 
				
			||||||
		if ((*ch < '0' || *ch > '9') && *ch != ':') {
 | 
					 | 
				
			||||||
			eerror("%s: invalid time %s", applet, time_arg);
 | 
					 | 
				
			||||||
			usage(EXIT_FAILURE);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	if (strchr(time_arg, ':')) {
 | 
					 | 
				
			||||||
		if ((sscanf(time_arg, "%2d:%2d", &hour, &min) != 2) ||
 | 
					 | 
				
			||||||
				(hour > 23) || (min > 59)) {
 | 
					 | 
				
			||||||
			eerror("%s: invalid time %s", applet, time_arg);
 | 
					 | 
				
			||||||
			usage(EXIT_FAILURE);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		time(&tv);
 | 
					 | 
				
			||||||
		lt = localtime(&tv);
 | 
					 | 
				
			||||||
		shutdown_delay = (hour * 60 + min) - (lt->tm_hour * 60 + lt->tm_min);
 | 
					 | 
				
			||||||
		if (shutdown_delay < 0)
 | 
					 | 
				
			||||||
			shutdown_delay += 1440;
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		shutdown_delay = atoi(time_arg);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	fp = fopen(shutdown_pid, "w");
 | 
					 | 
				
			||||||
	if (!fp)
 | 
					 | 
				
			||||||
		eerrorx("%s: fopen `%s': %s", applet, shutdown_pid, strerror(errno));
 | 
					 | 
				
			||||||
	fprintf(fp, "%d\n", getpid());
 | 
					 | 
				
			||||||
	fclose(fp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	openlog(applet, LOG_PID, LOG_DAEMON);
 | 
					 | 
				
			||||||
	memset(&sa, 0, sizeof(sa));
 | 
					 | 
				
			||||||
	sa.sa_handler = stop_shutdown;
 | 
					 | 
				
			||||||
	sigemptyset(&sa.sa_mask);
 | 
					 | 
				
			||||||
	sigaction(SIGINT, &sa, NULL);
 | 
					 | 
				
			||||||
	sigaction(SIGTERM, &sa, NULL);
 | 
					 | 
				
			||||||
	while (shutdown_delay > 0) {
 | 
					 | 
				
			||||||
		need_warning = false;
 | 
					 | 
				
			||||||
		if (shutdown_delay > 180)
 | 
					 | 
				
			||||||
			need_warning = (shutdown_delay % 60 == 0);
 | 
					 | 
				
			||||||
		else if (shutdown_delay > 60)
 | 
					 | 
				
			||||||
			need_warning = (shutdown_delay % 30 == 0);
 | 
					 | 
				
			||||||
		else if	(shutdown_delay > 10)
 | 
					 | 
				
			||||||
			need_warning = (shutdown_delay % 15 == 0);
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			need_warning = true;
 | 
					 | 
				
			||||||
		if (shutdown_delay <= 5)
 | 
					 | 
				
			||||||
			create_nologin(shutdown_delay);
 | 
					 | 
				
			||||||
		if (need_warning) {
 | 
					 | 
				
			||||||
		xasprintf(&msg, "\rThe system will %s in %d minutes\r\n",
 | 
					 | 
				
			||||||
		          state, shutdown_delay);
 | 
					 | 
				
			||||||
			broadcast(msg);
 | 
					 | 
				
			||||||
			free(msg);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		sleep_no_interrupt(60);
 | 
					 | 
				
			||||||
		shutdown_delay--;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	xasprintf(&msg, "\rThe system will %s now\r\n", state);
 | 
					 | 
				
			||||||
	broadcast(msg);
 | 
					 | 
				
			||||||
	syslog(LOG_NOTICE, "The system will %s now", state);
 | 
					 | 
				
			||||||
	unlink(nologin_file);
 | 
					 | 
				
			||||||
	unlink(shutdown_pid);
 | 
					 | 
				
			||||||
	if (do_halt)
 | 
						if (do_halt)
 | 
				
			||||||
		send_cmd("halt");
 | 
							send_cmd("halt");
 | 
				
			||||||
	else if (do_kexec)
 | 
						else if (do_kexec)
 | 
				
			||||||
@@ -328,6 +160,10 @@ int main(int argc, char **argv)
 | 
				
			|||||||
		send_cmd("poweroff");
 | 
							send_cmd("poweroff");
 | 
				
			||||||
	else if (do_reboot)
 | 
						else if (do_reboot)
 | 
				
			||||||
		send_cmd("reboot");
 | 
							send_cmd("reboot");
 | 
				
			||||||
 | 
						else if (do_reexec)
 | 
				
			||||||
 | 
							send_cmd("reexec");
 | 
				
			||||||
 | 
						else if (do_wtmp_only)
 | 
				
			||||||
 | 
							log_wtmp("shutdown", "~~", 0, RUN_LVL, "~~");
 | 
				
			||||||
	else if (do_single)
 | 
						else if (do_single)
 | 
				
			||||||
		send_cmd("single");
 | 
							send_cmd("single");
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -87,8 +87,6 @@ write_log(int logfd, const char *buffer, size_t bytes)
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!in_escape) {
 | 
							if (!in_escape) {
 | 
				
			||||||
			if (!isprint((int) *p) && *p != '\n')
 | 
					 | 
				
			||||||
				goto cont;
 | 
					 | 
				
			||||||
			if (write(logfd, p++, 1) == -1)
 | 
								if (write(logfd, p++, 1) == -1)
 | 
				
			||||||
				eerror("write: %s", strerror(errno));
 | 
									eerror("write: %s", strerror(errno));
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -51,8 +51,7 @@ rc_conf_yesno(const char *setting)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static const char *const env_whitelist[] = {
 | 
					static const char *const env_whitelist[] = {
 | 
				
			||||||
	"EERROR_QUIET", "EINFO_QUIET",
 | 
						"EERROR_QUIET", "EINFO_QUIET",
 | 
				
			||||||
	"IN_BACKGROUND", "IN_DRYRUN", "IN_HOTPLUG",
 | 
						"IN_BACKGROUND", "IN_HOTPLUG",
 | 
				
			||||||
	"RC_DEBUG", "RC_NODEPS",
 | 
					 | 
				
			||||||
	"LANG", "LC_MESSAGES", "TERM",
 | 
						"LANG", "LC_MESSAGES", "TERM",
 | 
				
			||||||
	"EINFO_COLOR", "EINFO_VERBOSE",
 | 
						"EINFO_COLOR", "EINFO_VERBOSE",
 | 
				
			||||||
	NULL
 | 
						NULL
 | 
				
			||||||
@@ -132,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 */
 | 
				
			||||||
@@ -172,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;
 | 
				
			||||||
@@ -182,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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -219,27 +217,14 @@ signal_setup(int sig, void (*handler)(int))
 | 
				
			|||||||
	return sigaction(sig, &sa, NULL);
 | 
						return sigaction(sig, &sa, NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					 | 
				
			||||||
signal_setup_restart(int sig, void (*handler)(int))
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct sigaction sa;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	memset(&sa, 0, sizeof (sa));
 | 
					 | 
				
			||||||
	sigemptyset(&sa.sa_mask);
 | 
					 | 
				
			||||||
	sa.sa_handler = handler;
 | 
					 | 
				
			||||||
	sa.sa_flags = SA_RESTART;
 | 
					 | 
				
			||||||
	return sigaction(sig, &sa, NULL);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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) {
 | 
				
			||||||
@@ -253,12 +238,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;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -362,7 +346,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;
 | 
				
			||||||
@@ -384,10 +368,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
 | 
				
			||||||
@@ -411,6 +392,34 @@ RC_DEPTREE * _rc_deptree_load(int force, int *regen)
 | 
				
			|||||||
	return rc_deptree_load();
 | 
						return rc_deptree_load();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool _rc_can_find_pids(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						RC_PIDLIST *pids;
 | 
				
			||||||
 | 
						RC_PID *pid;
 | 
				
			||||||
 | 
						RC_PID *pid2;
 | 
				
			||||||
 | 
						bool retval = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (geteuid() == 0)
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* If we cannot see process 1, then we don't test to see if
 | 
				
			||||||
 | 
						 * services crashed or not */
 | 
				
			||||||
 | 
						pids = rc_find_pids(NULL, NULL, 0, 1);
 | 
				
			||||||
 | 
						if (pids) {
 | 
				
			||||||
 | 
							pid = LIST_FIRST(pids);
 | 
				
			||||||
 | 
							if (pid) {
 | 
				
			||||||
 | 
								retval = true;
 | 
				
			||||||
 | 
								while (pid) {
 | 
				
			||||||
 | 
									pid2 = LIST_NEXT(pid, entries);
 | 
				
			||||||
 | 
									free(pid);
 | 
				
			||||||
 | 
									pid = pid2;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							free(pids);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return retval;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct {
 | 
					static const struct {
 | 
				
			||||||
	const char * const name;
 | 
						const char * const name;
 | 
				
			||||||
	RC_SERVICE bit;
 | 
						RC_SERVICE bit;
 | 
				
			||||||
@@ -423,7 +432,6 @@ static const struct {
 | 
				
			|||||||
	{ "service_hotplugged",  RC_SERVICE_HOTPLUGGED,  },
 | 
						{ "service_hotplugged",  RC_SERVICE_HOTPLUGGED,  },
 | 
				
			||||||
	{ "service_wasinactive", RC_SERVICE_WASINACTIVE, },
 | 
						{ "service_wasinactive", RC_SERVICE_WASINACTIVE, },
 | 
				
			||||||
	{ "service_failed",      RC_SERVICE_FAILED,      },
 | 
						{ "service_failed",      RC_SERVICE_FAILED,      },
 | 
				
			||||||
	{ "service_crashed",     RC_SERVICE_CRASHED,     },
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RC_SERVICE lookup_service_state(const char *service)
 | 
					RC_SERVICE lookup_service_state(const char *service)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,56 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 * rc-pipes.c
 | 
					 | 
				
			||||||
 * Helper to handle spawning processes and connecting them to pipes.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Copyright (c) 2018 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.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <stdlib.h>
 | 
					 | 
				
			||||||
#include <unistd.h>
 | 
					 | 
				
			||||||
#include <sys/types.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "rc-pipes.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const int pipe_read_end = 0;
 | 
					 | 
				
			||||||
static const int pipe_write_end = 1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Starts a command with stdin redirected from a pipe
 | 
					 | 
				
			||||||
 * Returns the write end of the pipe or -1
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
int rc_pipe_command(char *cmd)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	int pfd[2];
 | 
					 | 
				
			||||||
	pid_t pid;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (pipe(pfd) < 0)
 | 
					 | 
				
			||||||
		return -1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pid = fork();
 | 
					 | 
				
			||||||
	if (pid > 0) {
 | 
					 | 
				
			||||||
		/* parent */
 | 
					 | 
				
			||||||
		close(pfd[pipe_read_end]);
 | 
					 | 
				
			||||||
		return pfd[pipe_write_end];
 | 
					 | 
				
			||||||
	} else if (pid == 0) {
 | 
					 | 
				
			||||||
		/* child */
 | 
					 | 
				
			||||||
		close(pfd[pipe_write_end]);
 | 
					 | 
				
			||||||
		if (pfd[pipe_read_end] != STDIN_FILENO) {
 | 
					 | 
				
			||||||
			if (dup2(pfd[pipe_read_end], STDIN_FILENO) < 0)
 | 
					 | 
				
			||||||
				exit(1);
 | 
					 | 
				
			||||||
			close(pfd[pipe_read_end]);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		execl("/bin/sh", "sh", "-c", cmd, NULL);
 | 
					 | 
				
			||||||
		exit(1);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return -1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,18 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 * Copyright (c) 2018 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.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef RC_PIPES_H
 | 
					 | 
				
			||||||
#define RC_PIPES_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int rc_pipe_command(char *cmd);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
@@ -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;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,7 +28,6 @@
 | 
				
			|||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <syslog.h>
 | 
					 | 
				
			||||||
#include <time.h>
 | 
					#include <time.h>
 | 
				
			||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
#include <sys/stat.h>
 | 
					#include <sys/stat.h>
 | 
				
			||||||
@@ -271,11 +270,8 @@ int do_stop(const char *applet, const char *exec, const char *const *argv,
 | 
				
			|||||||
			einfo("Would send signal %d to PID %d", sig, pi->pid);
 | 
								einfo("Would send signal %d to PID %d", sig, pi->pid);
 | 
				
			||||||
			nkilled++;
 | 
								nkilled++;
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			if (sig) {
 | 
								if (!quiet)
 | 
				
			||||||
				syslog(LOG_DEBUG, "Sending signal %d to PID %d", sig, pi->pid);
 | 
									ebeginv("Sending signal %d to PID %d", sig, pi->pid);
 | 
				
			||||||
				if (!quiet)
 | 
					 | 
				
			||||||
					ebeginv("Sending signal %d to PID %d", sig, pi->pid);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			errno = 0;
 | 
								errno = 0;
 | 
				
			||||||
			killed = (kill(pi->pid, sig) == 0 ||
 | 
								killed = (kill(pi->pid, sig) == 0 ||
 | 
				
			||||||
			    errno == ESRCH ? true : false);
 | 
								    errno == ESRCH ? true : false);
 | 
				
			||||||
@@ -283,9 +279,6 @@ int do_stop(const char *applet, const char *exec, const char *const *argv,
 | 
				
			|||||||
				eendv(killed ? 0 : 1,
 | 
									eendv(killed ? 0 : 1,
 | 
				
			||||||
				"%s: failed to send signal %d to PID %d: %s",
 | 
									"%s: failed to send signal %d to PID %d: %s",
 | 
				
			||||||
				applet, sig, pi->pid, strerror(errno));
 | 
									applet, sig, pi->pid, strerror(errno));
 | 
				
			||||||
			else if (!killed)
 | 
					 | 
				
			||||||
				syslog(LOG_ERR, "Failed to send signal %d to PID %d: %s",
 | 
					 | 
				
			||||||
						sig, pi->pid, strerror(errno));
 | 
					 | 
				
			||||||
			if (!killed) {
 | 
								if (!killed) {
 | 
				
			||||||
				nkilled = -1;
 | 
									nkilled = -1;
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
@@ -314,21 +307,12 @@ 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)))
 | 
						if (exec)
 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (exec) {
 | 
					 | 
				
			||||||
		einfov("Will stop %s", exec);
 | 
							einfov("Will stop %s", exec);
 | 
				
			||||||
		syslog(LOG_DEBUG, "Will stop %s", exec);
 | 
						if (pid > 0)
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (pid > 0) {
 | 
					 | 
				
			||||||
		einfov("Will stop PID %d", pid);
 | 
							einfov("Will stop PID %d", pid);
 | 
				
			||||||
		syslog(LOG_DEBUG, "Will stop PID %d", pid);
 | 
						if (uid)
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (uid) {
 | 
					 | 
				
			||||||
		einfov("Will stop processes owned by UID %d", uid);
 | 
							einfov("Will stop processes owned by UID %d", uid);
 | 
				
			||||||
		syslog(LOG_DEBUG, "Will stop processes owned by UID %d", uid);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (argv && *argv) {
 | 
						if (argv && *argv) {
 | 
				
			||||||
		einfovn("Will stop processes of `");
 | 
							einfovn("Will stop processes of `");
 | 
				
			||||||
		if (rc_yesno(getenv("EINFO_VERBOSE"))) {
 | 
							if (rc_yesno(getenv("EINFO_VERBOSE"))) {
 | 
				
			||||||
@@ -364,9 +348,8 @@ int run_stop_schedule(const char *applet,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			tkilled += nkilled;
 | 
								tkilled += nkilled;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case SC_FOREVER:
 | 
					 | 
				
			||||||
		case SC_TIMEOUT:
 | 
							case SC_TIMEOUT:
 | 
				
			||||||
			if (item->type == SC_TIMEOUT && item->value < 1) {
 | 
								if (item->value < 1) {
 | 
				
			||||||
				item = NULL;
 | 
									item = NULL;
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -374,7 +357,7 @@ int run_stop_schedule(const char *applet,
 | 
				
			|||||||
			ts.tv_sec = 0;
 | 
								ts.tv_sec = 0;
 | 
				
			||||||
			ts.tv_nsec = POLL_INTERVAL;
 | 
								ts.tv_nsec = POLL_INTERVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			for (nsecs = 0; item->type == SC_FOREVER || nsecs < item->value; nsecs++) {
 | 
								for (nsecs = 0; nsecs < item->value; nsecs++) {
 | 
				
			||||||
				for (nloops = 0;
 | 
									for (nloops = 0;
 | 
				
			||||||
				     nloops < ONE_SECOND / POLL_INTERVAL;
 | 
									     nloops < ONE_SECOND / POLL_INTERVAL;
 | 
				
			||||||
				     nloops++)
 | 
									     nloops++)
 | 
				
			||||||
@@ -389,7 +372,10 @@ int run_stop_schedule(const char *applet,
 | 
				
			|||||||
							printf("\n");
 | 
												printf("\n");
 | 
				
			||||||
							progressed = false;
 | 
												progressed = false;
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
						if (errno != EINTR) {
 | 
											if (errno == EINTR)
 | 
				
			||||||
 | 
												eerror("%s: caught an"
 | 
				
			||||||
 | 
												    " interrupt", applet);
 | 
				
			||||||
 | 
											else {
 | 
				
			||||||
							eerror("%s: nanosleep: %s",
 | 
												eerror("%s: nanosleep: %s",
 | 
				
			||||||
							    applet, strerror(errno));
 | 
												    applet, strerror(errno));
 | 
				
			||||||
							return 0;
 | 
												return 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,35 +29,23 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const char *applet = NULL;
 | 
					const char *applet = NULL;
 | 
				
			||||||
const char *extraopts = NULL;
 | 
					const char *extraopts = NULL;
 | 
				
			||||||
const char *getoptstring = "cdDe:ilr:INsSZ" getoptstring_COMMON;
 | 
					const char *getoptstring = "e:ilr:IN" getoptstring_COMMON;
 | 
				
			||||||
const struct option longopts[] = {
 | 
					const struct option longopts[] = {
 | 
				
			||||||
	{ "debug",     0, NULL, 'd' },
 | 
					 | 
				
			||||||
	{ "nodeps",     0, NULL, 'D' },
 | 
					 | 
				
			||||||
	{ "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' },
 | 
				
			||||||
	{ "ifstarted", 0, NULL, 's' },
 | 
					 | 
				
			||||||
	{ "ifstopped", 0, NULL, 'S' },
 | 
					 | 
				
			||||||
	{ "list",     0, NULL, 'l' },
 | 
						{ "list",     0, NULL, 'l' },
 | 
				
			||||||
	{ "resolve",  1, NULL, 'r' },
 | 
						{ "resolve",  1, NULL, 'r' },
 | 
				
			||||||
	{ "dry-run",     0, NULL, 'Z' },
 | 
					 | 
				
			||||||
	longopts_COMMON
 | 
						longopts_COMMON
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
const char * const longopts_help[] = {
 | 
					const char * const longopts_help[] = {
 | 
				
			||||||
	"set xtrace when running the command",
 | 
					 | 
				
			||||||
	"ignore dependencies",
 | 
					 | 
				
			||||||
	"tests if the service exists or not",
 | 
						"tests if the service exists or not",
 | 
				
			||||||
	"if the service is crashed run the command",
 | 
						"if the service exists then run the command",
 | 
				
			||||||
	"if the service exists run the command",
 | 
						"if the service is inactive then run the command",
 | 
				
			||||||
	"if the service is inactive run the command",
 | 
						"if the service is not started then run the command",
 | 
				
			||||||
	"if the service is not started run the command",
 | 
					 | 
				
			||||||
	"if the service is started run the command",
 | 
					 | 
				
			||||||
	"if the service is stopped run the command",
 | 
					 | 
				
			||||||
	"list all available services",
 | 
						"list all available services",
 | 
				
			||||||
	"resolve the service name to an init script",
 | 
						"resolve the service name to an init script",
 | 
				
			||||||
	"dry run (show what would happen)",
 | 
					 | 
				
			||||||
	longopts_help_COMMON
 | 
						longopts_help_COMMON
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
const char *usagestring = ""							\
 | 
					const char *usagestring = ""							\
 | 
				
			||||||
@@ -73,12 +61,9 @@ 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;
 | 
				
			||||||
	bool if_started = false;
 | 
					 | 
				
			||||||
	bool if_stopped = false;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	applet = basename_c(argv[0]);
 | 
						applet = basename_c(argv[0]);
 | 
				
			||||||
	/* Ensure that we are only quiet when explicitly told to be */
 | 
						/* Ensure that we are only quiet when explicitly told to be */
 | 
				
			||||||
@@ -88,21 +73,12 @@ int main(int argc, char **argv)
 | 
				
			|||||||
		    longopts, (int *) 0)) != -1)
 | 
							    longopts, (int *) 0)) != -1)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		switch (opt) {
 | 
							switch (opt) {
 | 
				
			||||||
		case 'd':
 | 
					 | 
				
			||||||
			setenv("RC_DEBUG", "yes", 1);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case 'D':
 | 
					 | 
				
			||||||
			setenv("RC_NODEPS", "yes", 1);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case 'e':
 | 
							case 'e':
 | 
				
			||||||
			service = rc_service_resolve(optarg);
 | 
								service = rc_service_resolve(optarg);
 | 
				
			||||||
			opt = service ? EXIT_SUCCESS : EXIT_FAILURE;
 | 
								opt = service ? EXIT_SUCCESS : EXIT_FAILURE;
 | 
				
			||||||
			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;
 | 
				
			||||||
@@ -130,15 +106,6 @@ int main(int argc, char **argv)
 | 
				
			|||||||
			free(service);
 | 
								free(service);
 | 
				
			||||||
			return EXIT_SUCCESS;
 | 
								return EXIT_SUCCESS;
 | 
				
			||||||
			/* NOTREACHED */
 | 
								/* NOTREACHED */
 | 
				
			||||||
		case 's':
 | 
					 | 
				
			||||||
			if_started = true;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case 'S':
 | 
					 | 
				
			||||||
			if_stopped = true;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case 'Z':
 | 
					 | 
				
			||||||
			setenv("IN_DRYRUN", "yes", 1);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		case_RC_COMMON_GETOPT
 | 
							case_RC_COMMON_GETOPT
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -154,16 +121,10 @@ 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))
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	if (if_started && ! (state & RC_SERVICE_STARTED))
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
	if (if_stopped && ! (state & RC_SERVICE_STOPPED))
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
	*argv = service;
 | 
						*argv = service;
 | 
				
			||||||
	execv(*argv, argv);
 | 
						execv(*argv, argv);
 | 
				
			||||||
	eerrorx("%s: %s", applet, strerror(errno));
 | 
						eerrorx("%s: %s", applet, strerror(errno));
 | 
				
			||||||
 
 | 
				
			|||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user