Compare commits
	
		
			146 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					3d30b6fdda | ||
| 
						 | 
					4574b5d8e4 | ||
| 
						 | 
					6b42019697 | ||
| 
						 | 
					42408e7488 | ||
| 
						 | 
					957140cb78 | ||
| 
						 | 
					536794dfad | ||
| 
						 | 
					7ac2080e31 | ||
| 
						 | 
					12e1e88475 | ||
| 
						 | 
					c45fe9fba5 | ||
| 
						 | 
					961c479e1d | ||
| 
						 | 
					f9c92d7822 | ||
| 
						 | 
					97689d6c44 | ||
| 
						 | 
					439cce426d | ||
| 
						 | 
					bfdafe4463 | ||
| 
						 | 
					179ff285ca | ||
| 
						 | 
					f9bbbfbf4b | ||
| 
						 | 
					59a175541d | ||
| 
						 | 
					65b13eb86f | ||
| 
						 | 
					fda9dcd1f2 | ||
| 
						 | 
					6f180e9424 | ||
| 
						 | 
					88e5d98d05 | ||
| 
						 | 
					1433552435 | ||
| 
						 | 
					554ccab718 | ||
| 
						 | 
					228b3c6c99 | ||
| 
						 | 
					965de92b37 | ||
| 
						 | 
					b85d771e1f | ||
| 
						 | 
					cf9286d2d8 | ||
| 
						 | 
					9934e9f96e | ||
| 
						 | 
					f1e5510ccf | ||
| 
						 | 
					1b72c3a7ab | ||
| 
						 | 
					c4785f1b99 | ||
| 
						 | 
					e447562aaa | ||
| 
						 | 
					c199c5cf6e | ||
| 
						 | 
					5bfb592d75 | ||
| 
						 | 
					b2c4eb97b5 | ||
| 
						 | 
					e740913fcb | ||
| 
						 | 
					1bc34a39cd | ||
| 
						 | 
					c1cd3c9830 | ||
| 
						 | 
					86efc43d0e | ||
| 
						 | 
					cd53239701 | ||
| 
						 | 
					92662ddc44 | ||
| 
						 | 
					1b6a35488d | ||
| 
						 | 
					1eccb7f5e6 | ||
| 
						 | 
					fe37fc9322 | ||
| 
						 | 
					edf5f830e3 | ||
| 
						 | 
					863e1a5c87 | ||
| 
						 | 
					0b9c3c0803 | ||
| 
						 | 
					a3c721b682 | ||
| 
						 | 
					3f82d5b1a3 | ||
| 
						 | 
					0b4732520f | ||
| 
						 | 
					bbd3acfc67 | ||
| 
						 | 
					910e3e2a0e | ||
| 
						 | 
					5f04dcc951 | ||
| 
						 | 
					8f52c64c37 | ||
| 
						 | 
					09d405fb3e | ||
| 
						 | 
					36e4e04ba9 | ||
| 
						 | 
					eb8831a141 | ||
| 
						 | 
					0b5cb3abcb | ||
| 
						 | 
					f6ed2c660c | ||
| 
						 | 
					002bcf0b67 | ||
| 
						 | 
					b9241988a7 | ||
| 
						 | 
					5ae4d4edb5 | ||
| 
						 | 
					95b2948e6e | ||
| 
						 | 
					b73d326387 | ||
| 
						 | 
					476272be0c | ||
| 
						 | 
					63a5ee3d8c | ||
| 
						 | 
					36cc40a9d6 | ||
| 
						 | 
					ae5e38dce5 | ||
| 
						 | 
					5858f980c8 | ||
| 
						 | 
					db96295e00 | ||
| 
						 | 
					f5ed484920 | ||
| 
						 | 
					00f90f2b0e | ||
| 
						 | 
					b405681926 | ||
| 
						 | 
					d5700d036a | ||
| 
						 | 
					616f756ca8 | ||
| 
						 | 
					17cfb41d81 | ||
| 
						 | 
					1bc87b7a7c | ||
| 
						 | 
					f3be11a00d | ||
| 
						 | 
					406ab2a4ca | ||
| 
						 | 
					7878a53542 | ||
| 
						 | 
					084e6b5e20 | ||
| 
						 | 
					a7bd13145b | ||
| 
						 | 
					28ecb38515 | ||
| 
						 | 
					91737be1ab | ||
| 
						 | 
					fb6ffc5713 | ||
| 
						 | 
					01acbe3c27 | ||
| 
						 | 
					aa5c3ccd0b | ||
| 
						 | 
					d795ea183f | ||
| 
						 | 
					5af3944440 | ||
| 
						 | 
					01bcdb43b6 | ||
| 
						 | 
					bcd1975fe7 | ||
| 
						 | 
					57e194df4f | ||
| 
						 | 
					dacd0ab189 | ||
| 
						 | 
					7cfe93d032 | ||
| 
						 | 
					893df75e30 | ||
| 
						 | 
					c80d6bb2ed | ||
| 
						 | 
					bfe38c98a8 | ||
| 
						 | 
					e8a76ad6e6 | ||
| 
						 | 
					7d63049adb | ||
| 
						 | 
					dc0b3157a9 | ||
| 
						 | 
					2f6b5b7ef4 | ||
| 
						 | 
					eb3635dd1f | ||
| 
						 | 
					459783bbad | ||
| 
						 | 
					a28bdc7e5c | ||
| 
						 | 
					bcae7d03b4 | ||
| 
						 | 
					ccc2b71145 | ||
| 
						 | 
					78c0693c50 | ||
| 
						 | 
					ddf4a3a7a0 | ||
| 
						 | 
					a6568c304f | ||
| 
						 | 
					d6a5264a9d | ||
| 
						 | 
					9f227e8b49 | ||
| 
						 | 
					3bb5450320 | ||
| 
						 | 
					a689fdb7be | ||
| 
						 | 
					fc4f15d6cd | ||
| 
						 | 
					19f329d2f4 | ||
| 
						 | 
					0b86c06c3c | ||
| 
						 | 
					fea9d9a7f0 | ||
| 
						 | 
					9dfd2b2737 | ||
| 
						 | 
					de295bd0c6 | ||
| 
						 | 
					6f44445958 | ||
| 
						 | 
					52dcb4aaa3 | ||
| 
						 | 
					c6d6ed0c9c | ||
| 
						 | 
					b778c72f81 | ||
| 
						 | 
					32715e1144 | ||
| 
						 | 
					ec04e08707 | ||
| 
						 | 
					dd05e60ced | ||
| 
						 | 
					9ef74594df | ||
| 
						 | 
					59e9637647 | ||
| 
						 | 
					35077afb68 | ||
| 
						 | 
					02b064a591 | ||
| 
						 | 
					839083bb52 | ||
| 
						 | 
					1364e6631c | ||
| 
						 | 
					953172c6c6 | ||
| 
						 | 
					0525de4f18 | ||
| 
						 | 
					9380347f04 | ||
| 
						 | 
					112b69860f | ||
| 
						 | 
					d21dde73ba | ||
| 
						 | 
					9b08de926b | ||
| 
						 | 
					f60d42e901 | ||
| 
						 | 
					9e5ce59a21 | ||
| 
						 | 
					95dc83bfbc | ||
| 
						 | 
					14b153c1a4 | ||
| 
						 | 
					3cc4c01485 | ||
| 
						 | 
					414f398498 | ||
| 
						 | 
					107b23819d | ||
| 
						 | 
					d2b3144070 | 
@@ -4,8 +4,8 @@
 | 
			
		||||
test_task:
 | 
			
		||||
  freebsd_instance:
 | 
			
		||||
    matrix:
 | 
			
		||||
      image: freebsd-13-0-release-amd64
 | 
			
		||||
      image: freebsd-12-3-release-amd64
 | 
			
		||||
      image: freebsd-13-2-release-amd64
 | 
			
		||||
      image: freebsd-13-3-release-amd64
 | 
			
		||||
  env:
 | 
			
		||||
    OS: FreeBSD
 | 
			
		||||
  procfs_script: >
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										142
									
								
								CODE_OF_CONDUCT.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								CODE_OF_CONDUCT.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,142 @@
 | 
			
		||||
# OpenRC Code of Conduct
 | 
			
		||||
 | 
			
		||||
This code of conduct outlines our expectations for participants within the
 | 
			
		||||
community, as well as steps for reporting unacceptable behavior. We are
 | 
			
		||||
committed to providing a welcoming and inspiring community for all and
 | 
			
		||||
expect our code of conduct to be honored. Anyone who violates this code
 | 
			
		||||
of conduct may be banned from the community.
 | 
			
		||||
 | 
			
		||||
## Our Pledge
 | 
			
		||||
 | 
			
		||||
We as members, contributors, and leaders pledge to make participation in our
 | 
			
		||||
community a harassment-free experience for everyone, regardless of age, body
 | 
			
		||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
 | 
			
		||||
identity and expression, level of experience, education, socio-economic status,
 | 
			
		||||
nationality, personal appearance, race, caste, color, religion, or sexual
 | 
			
		||||
identity and orientation.
 | 
			
		||||
 | 
			
		||||
We pledge to act and interact in ways that contribute to an open, welcoming,
 | 
			
		||||
diverse, inclusive, and healthy community.
 | 
			
		||||
 | 
			
		||||
## Our Standards
 | 
			
		||||
 | 
			
		||||
Examples of behavior that contributes to a positive environment for our
 | 
			
		||||
community include:
 | 
			
		||||
 | 
			
		||||
* Demonstrating empathy and kindness toward other people
 | 
			
		||||
* Being respectful of differing opinions, viewpoints, and experiences
 | 
			
		||||
* Giving and gracefully accepting constructive feedback
 | 
			
		||||
* Accepting responsibility and apologizing to those affected by our mistakes,
 | 
			
		||||
  and learning from the experience
 | 
			
		||||
* Focusing on what is best not just for us as individuals, but for the overall
 | 
			
		||||
  community
 | 
			
		||||
 | 
			
		||||
Examples of unacceptable behavior include:
 | 
			
		||||
 | 
			
		||||
* The use of sexualized language or imagery, and sexual attention or advances of
 | 
			
		||||
  any kind
 | 
			
		||||
* Trolling, insulting or derogatory comments, and personal or political attacks
 | 
			
		||||
* Public or private harassment
 | 
			
		||||
* Publishing others' private information, such as a physical or email address,
 | 
			
		||||
  without their explicit permission
 | 
			
		||||
* Other conduct which could reasonably be considered inappropriate in a
 | 
			
		||||
  professional setting
 | 
			
		||||
 | 
			
		||||
## Enforcement Responsibilities
 | 
			
		||||
 | 
			
		||||
Community leaders are responsible for clarifying and enforcing our standards of
 | 
			
		||||
acceptable behavior and will take appropriate and fair corrective action in
 | 
			
		||||
response to any behavior that they deem inappropriate, threatening, offensive,
 | 
			
		||||
or harmful.
 | 
			
		||||
 | 
			
		||||
Community leaders have the right and responsibility to remove, edit, or reject
 | 
			
		||||
comments, commits, code, wiki edits, issues, and other contributions that are
 | 
			
		||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
 | 
			
		||||
decisions when appropriate.
 | 
			
		||||
 | 
			
		||||
## Scope
 | 
			
		||||
 | 
			
		||||
This Code of Conduct applies within all community spaces, and also applies when
 | 
			
		||||
an individual is officially representing the community in public spaces.
 | 
			
		||||
Examples of representing our community include using an official e-mail address,
 | 
			
		||||
posting via an official social media account, or acting as an appointed
 | 
			
		||||
representative at an online or offline event.
 | 
			
		||||
 | 
			
		||||
## Enforcement
 | 
			
		||||
 | 
			
		||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
 | 
			
		||||
reported to the community leaders responsible for enforcement via integrated
 | 
			
		||||
"Report Content" functionality.
 | 
			
		||||
See the GitHub documentation for more details:
 | 
			
		||||
https://docs.github.com/en/communities/maintaining-your-safety-on-github/reporting-abuse-or-spam
 | 
			
		||||
 | 
			
		||||
All complaints will be reviewed and investigated promptly and fairly.
 | 
			
		||||
 | 
			
		||||
All community leaders are obligated to respect the privacy and security of the
 | 
			
		||||
reporter of any incident.
 | 
			
		||||
 | 
			
		||||
## Enforcement Guidelines
 | 
			
		||||
 | 
			
		||||
Community leaders will follow these Community Impact Guidelines in determining
 | 
			
		||||
the consequences for any action they deem in violation of this Code of Conduct:
 | 
			
		||||
 | 
			
		||||
### 1. Correction
 | 
			
		||||
 | 
			
		||||
**Community Impact**: Use of inappropriate language or other behavior deemed
 | 
			
		||||
unprofessional or unwelcome in the community.
 | 
			
		||||
 | 
			
		||||
**Consequence**: A private, written warning from community leaders, providing
 | 
			
		||||
clarity around the nature of the violation and an explanation of why the
 | 
			
		||||
behavior was inappropriate. A public apology may be requested.
 | 
			
		||||
 | 
			
		||||
### 2. Warning
 | 
			
		||||
 | 
			
		||||
**Community Impact**: A violation through a single incident or series of
 | 
			
		||||
actions.
 | 
			
		||||
 | 
			
		||||
**Consequence**: A warning with consequences for continued behavior. No
 | 
			
		||||
interaction with the people involved, including unsolicited interaction with
 | 
			
		||||
those enforcing the Code of Conduct, for a specified period of time. This
 | 
			
		||||
includes avoiding interactions in community spaces as well as external channels
 | 
			
		||||
like social media. Violating these terms may lead to a temporary or permanent
 | 
			
		||||
ban.
 | 
			
		||||
 | 
			
		||||
### 3. Temporary Ban
 | 
			
		||||
 | 
			
		||||
**Community Impact**: A serious violation of community standards, including
 | 
			
		||||
sustained inappropriate behavior.
 | 
			
		||||
 | 
			
		||||
**Consequence**: A temporary ban from any sort of interaction or public
 | 
			
		||||
communication with the community for a specified period of time. No public or
 | 
			
		||||
private interaction with the people involved, including unsolicited interaction
 | 
			
		||||
with those enforcing the Code of Conduct, is allowed during this period.
 | 
			
		||||
Violating these terms may lead to a permanent ban.
 | 
			
		||||
 | 
			
		||||
### 4. Permanent Ban
 | 
			
		||||
 | 
			
		||||
**Community Impact**: Demonstrating a pattern of violation of community
 | 
			
		||||
standards, including sustained inappropriate behavior, harassment of an
 | 
			
		||||
individual, or aggression toward or disparagement of classes of individuals.
 | 
			
		||||
 | 
			
		||||
**Consequence**: A permanent ban from any sort of public interaction within the
 | 
			
		||||
community.
 | 
			
		||||
 | 
			
		||||
## Attribution
 | 
			
		||||
 | 
			
		||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
 | 
			
		||||
version 2.1, available at
 | 
			
		||||
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
 | 
			
		||||
 | 
			
		||||
Community Impact Guidelines were inspired by
 | 
			
		||||
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
 | 
			
		||||
 | 
			
		||||
For answers to common questions about this code of conduct, see the FAQ at
 | 
			
		||||
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
 | 
			
		||||
[https://www.contributor-covenant.org/translations][translations].
 | 
			
		||||
 | 
			
		||||
[homepage]: https://www.contributor-covenant.org
 | 
			
		||||
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
 | 
			
		||||
[Mozilla CoC]: https://github.com/mozilla/diversity
 | 
			
		||||
[FAQ]: https://www.contributor-covenant.org/faq
 | 
			
		||||
[translations]: https://www.contributor-covenant.org/translations
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								LICENSE
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								LICENSE
									
									
									
									
									
								
							@@ -1,5 +1,5 @@
 | 
			
		||||
Copyright (c) 2007-2008, Roy Marples <roy@marples.name>
 | 
			
		||||
Copyright (c) 2007-2015, the OpenRC authors
 | 
			
		||||
Copyright (c) 2007-2023, the OpenRC authors
 | 
			
		||||
All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										78
									
								
								NEWS.md
									
									
									
									
									
								
							
							
						
						
									
										78
									
								
								NEWS.md
									
									
									
									
									
								
							@@ -4,6 +4,84 @@ OpenRC NEWS
 | 
			
		||||
This file will contain a list of notable changes for each release. Note
 | 
			
		||||
the information in this file is in reverse order.
 | 
			
		||||
 | 
			
		||||
## OpenRC 0.54
 | 
			
		||||
 | 
			
		||||
This release drops the support for the split-usr build option.
 | 
			
		||||
Also, it drops the support for ncurses/termcap and uses ansi codes
 | 
			
		||||
directly for color support on terminals that support them.
 | 
			
		||||
 | 
			
		||||
## OpenRC 0.53
 | 
			
		||||
 | 
			
		||||
The names of cgroups for services started by OpenRC are now prefixed by
 | 
			
		||||
"openrc." This is done because some services, like docker, create their
 | 
			
		||||
own cgroups.
 | 
			
		||||
 | 
			
		||||
It is now possible to override the mount options used to mount the
 | 
			
		||||
cgroups filesystems.
 | 
			
		||||
## OpenRC 0.52
 | 
			
		||||
 | 
			
		||||
This release drops the "runscript" and "rc" binaries.
 | 
			
		||||
These binaries have been deprecated for multiple years, so it should be
 | 
			
		||||
fine to remove them at this point.
 | 
			
		||||
 | 
			
		||||
There was an issue before this release with the default setting for
 | 
			
		||||
cgroups being inconsistent. This is fixed.
 | 
			
		||||
 | 
			
		||||
Start-stop-daemon did not work correctly on Linux 6.6 systems.
 | 
			
		||||
This has been fixed in this release as well.
 | 
			
		||||
 | 
			
		||||
## OpenRC 0.51
 | 
			
		||||
 | 
			
		||||
The default RC_CGROUP_MODE has been updated to unified.
 | 
			
		||||
This benefits users since it will assign each service to its own cgroup,
 | 
			
		||||
making resource nanagement better over all.
 | 
			
		||||
 | 
			
		||||
OUTPUT_LOGGER and ERROR_LOGGER have been implemented for
 | 
			
		||||
supervise-daemon. For mor einformation on these settings, please check
 | 
			
		||||
the man page.
 | 
			
		||||
 | 
			
		||||
## OpenRC 0.50
 | 
			
		||||
 | 
			
		||||
This is a bug fix release which fixes a significant performance issue on
 | 
			
		||||
musl libc systems.
 | 
			
		||||
 | 
			
		||||
## OpenRC 0.49
 | 
			
		||||
 | 
			
		||||
This release adds support for glibc's builtin 
 | 
			
		||||
strlcpy, strlcat etc functions, which will be in posix next.
 | 
			
		||||
Also, it fixes completions.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## OpenRC 0.48
 | 
			
		||||
 | 
			
		||||
This release is a maintenance release; it has no user-facing changes.
 | 
			
		||||
 | 
			
		||||
## OpenRC 0.47
 | 
			
		||||
 | 
			
		||||
This release is primarily an internal cleanup release.
 | 
			
		||||
The only user-visible difference is that unicode is now on by default.
 | 
			
		||||
 | 
			
		||||
## OpenRC 0.46
 | 
			
		||||
 | 
			
		||||
The path for the reference file for the swclock service is now
 | 
			
		||||
configurable in conf.d/swclock.
 | 
			
		||||
 | 
			
		||||
In the past, if supervise_daemon_args was not set *or empty*, it defaulted to
 | 
			
		||||
`start_stop_daemon_args`. This was bad because supervise-daemon doesn't
 | 
			
		||||
accept the same options as `start-stop-daemon`. So if we set e.g.
 | 
			
		||||
`start_stop_daemon_args="--wait 50"`, but not `supervise_daemon_args`,
 | 
			
		||||
and the user adds `supervisor=supervise-daemon` to the corresponding
 | 
			
		||||
conf.d/<service> file, the service will fail to start due to
 | 
			
		||||
unrecognized option "wait".
 | 
			
		||||
It would be best to remove this fallback, but that might break some
 | 
			
		||||
existing scripts that depend on it. So we are changing it to
 | 
			
		||||
use `start_stop_daemon_args` as the default for `supervise_daemon_args`
 | 
			
		||||
only if `supervise_daemon_args` is not set at all, but not if it's
 | 
			
		||||
empty.
 | 
			
		||||
 | 
			
		||||
This fallback will be dropped in a future release.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## OpenRC 0.45
 | 
			
		||||
 | 
			
		||||
The old make-based build system is removed in this release.
 | 
			
		||||
 
 | 
			
		||||
@@ -85,29 +85,26 @@ _rc_service()
 | 
			
		||||
	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} ; \
 | 
			
		||||
			# complete for init scripts
 | 
			
		||||
			COMPREPLY=($(for i in $(rc-service --list) ; 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
 | 
			
		||||
			rc-service --exists "$prev" || return
 | 
			
		||||
			shopt -s extglob
 | 
			
		||||
			while read -r _ line; do
 | 
			
		||||
				if [[ $line == +([[:alnum:]_]):* ]]; then
 | 
			
		||||
					opts+="${line%%:*} "
 | 
			
		||||
				fi
 | 
			
		||||
			done < <(rc-service "$prev" describe 2>&1)
 | 
			
		||||
			shopt -u extglob
 | 
			
		||||
			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} ; \
 | 
			
		||||
		COMPREPLY=($(for i in $(rc-service --list) ; do \
 | 
			
		||||
			[[ ${i} == "${cur}"* ]] && echo ${i} ; \
 | 
			
		||||
		done))
 | 
			
		||||
		return 0
 | 
			
		||||
	fi
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								conf.d/cgroups
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								conf.d/cgroups
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
# override cgroup mount options
 | 
			
		||||
#cgroup_opts=nodev,noexec,nosuid
 | 
			
		||||
@@ -7,6 +7,7 @@ conf_common = [
 | 
			
		||||
  'localmount',
 | 
			
		||||
  'netmount',
 | 
			
		||||
  'swap',
 | 
			
		||||
  'swclock',
 | 
			
		||||
  ]
 | 
			
		||||
 | 
			
		||||
conf_net = [
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								conf.d/swclock
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								conf.d/swclock
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
# This is the location of the reference file swclock uses to set the
 | 
			
		||||
# system date and time.
 | 
			
		||||
# This is the default path. If you are using it, you do not need to
 | 
			
		||||
# uncomment it. If you are using the default and have /var on its own
 | 
			
		||||
# file system, you need to add the appropriate rc_after setting.
 | 
			
		||||
# swclock_file=/var/lib/misc/openrc-shutdowntime
 | 
			
		||||
							
								
								
									
										17
									
								
								etc/rc.conf
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								etc/rc.conf
									
									
									
									
									
								
							@@ -88,8 +88,8 @@
 | 
			
		||||
# MISC CONFIGURATION VARIABLES
 | 
			
		||||
# There variables are shared between many init scripts
 | 
			
		||||
 | 
			
		||||
# Set unicode to YES to turn on unicode support for keyboards and screens.
 | 
			
		||||
#unicode="NO"
 | 
			
		||||
# Set unicode to NO to turn off unicode support for keyboards and screens.
 | 
			
		||||
#unicode="YES"
 | 
			
		||||
 | 
			
		||||
# This is how long fuser should wait for a remote server to respond. The
 | 
			
		||||
# default is 60 seconds, but  it can be adjusted here.
 | 
			
		||||
@@ -97,8 +97,8 @@
 | 
			
		||||
 | 
			
		||||
# Below is the default list of network fstypes.
 | 
			
		||||
#
 | 
			
		||||
# afs ceph cifs coda davfs fuse fuse.sshfs gfs glusterfs lustre ncpfs
 | 
			
		||||
# nfs nfs4 ocfs2 shfs smbfs
 | 
			
		||||
# afs ceph cifs coda davfs fuse fuse.glusterfs fuse.sshfs gfs glusterfs lustre
 | 
			
		||||
# ncpfs nfs nfs4 ocfs2 shfs smbfs
 | 
			
		||||
#
 | 
			
		||||
# If you would like to add to this list, you can do so by adding your
 | 
			
		||||
# own fstypes to the following variable.
 | 
			
		||||
@@ -116,12 +116,13 @@
 | 
			
		||||
 | 
			
		||||
# Some daemons are started and stopped via start-stop-daemon.
 | 
			
		||||
# We can set some things on a per service basis, like the nicelevel.
 | 
			
		||||
#SSD_NICELEVEL="0"
 | 
			
		||||
# These need to be exported
 | 
			
		||||
#export SSD_NICELEVEL="0"
 | 
			
		||||
# Or the ionice level. The format is class[:data] , just like the
 | 
			
		||||
# --ionice start-stop-daemon parameter.
 | 
			
		||||
#SSD_IONICELEVEL="0:0"
 | 
			
		||||
#export SSD_IONICELEVEL="0:0"
 | 
			
		||||
# Or the OOM score adjustment.
 | 
			
		||||
#SSD_OOM_SCORE_ADJ="0"
 | 
			
		||||
#export SSD_OOM_SCORE_ADJ="0"
 | 
			
		||||
 | 
			
		||||
# Pass ulimit parameters
 | 
			
		||||
# If you are using bash in POSIX mode for your shell, note that the
 | 
			
		||||
@@ -198,7 +199,7 @@ rc_tty_number=12
 | 
			
		||||
# cgroups version 1 on /sys/fs/cgroup.
 | 
			
		||||
# "legacy" mounts cgroups version 1 on /sys/fs/cgroup
 | 
			
		||||
# "unified" mounts cgroups version 2 on /sys/fs/cgroup
 | 
			
		||||
#rc_cgroup_mode="hybrid"
 | 
			
		||||
#rc_cgroup_mode="unified"
 | 
			
		||||
 | 
			
		||||
# This is a list of controllers which should be enabled for cgroups version 2
 | 
			
		||||
# when hybrid mode is being used.
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@
 | 
			
		||||
 | 
			
		||||
description="Mount the control groups."
 | 
			
		||||
 | 
			
		||||
cgroup_opts=nodev,noexec,nosuid
 | 
			
		||||
: "${cgroup_opts:="nodev,noexec,nosuid"}"
 | 
			
		||||
 | 
			
		||||
depend()
 | 
			
		||||
{
 | 
			
		||||
@@ -87,7 +87,7 @@ cgroup2_controllers()
 | 
			
		||||
	[ ! -e "${cgroup_path}/cgroup.subtree_control" ]&& return 0
 | 
			
		||||
	read -r active < "${cgroup_path}/cgroup.controllers"
 | 
			
		||||
	for x in ${active}; do
 | 
			
		||||
	case "$rc_cgroup_mode" in
 | 
			
		||||
	case "${rc_cgroup_mode:-unified}" in
 | 
			
		||||
		unified)
 | 
			
		||||
			echo "+${x}"  > "${cgroup_path}/cgroup.subtree_control"
 | 
			
		||||
			;;
 | 
			
		||||
@@ -128,7 +128,7 @@ cgroups_unified()
 | 
			
		||||
 | 
			
		||||
mount_cgroups()
 | 
			
		||||
{
 | 
			
		||||
	case "${rc_cgroup_mode:-hybrid}" in
 | 
			
		||||
	case "${rc_cgroup_mode:-unified}" in
 | 
			
		||||
	hybrid) cgroups_hybrid ;;
 | 
			
		||||
	legacy) cgroups_legacy ;;
 | 
			
		||||
	unified) cgroups_unified ;;
 | 
			
		||||
 
 | 
			
		||||
@@ -19,20 +19,18 @@ depend()
 | 
			
		||||
 | 
			
		||||
start()
 | 
			
		||||
{
 | 
			
		||||
	local h source x
 | 
			
		||||
	if [ -s /etc/hostname ] && [ -r /etc/hostname ]; then
 | 
			
		||||
		read h x </etc/hostname
 | 
			
		||||
		source="from /etc/hostname"
 | 
			
		||||
	else
 | 
			
		||||
		# HOSTNAME variable used to be defined in caps in conf.d/hostname.
 | 
			
		||||
		# It is also a magic variable in bash.
 | 
			
		||||
		h=${hostname:-${HOSTNAME}} # checkbashisms: false positive (HOSTNAME var)
 | 
			
		||||
	local h source
 | 
			
		||||
	if read -r h _ 2> /dev/null < @SYSCONFDIR@/hostname; then
 | 
			
		||||
		source="@SYSCONFDIR@/hostname"
 | 
			
		||||
	elif [ -n "${hostname}" ]; then
 | 
			
		||||
		h=${hostname}
 | 
			
		||||
		source="@SYSCONFDIR@/conf.d/${RC_SVCNAME}"
 | 
			
		||||
	fi
 | 
			
		||||
	if [ -z "$h" ]; then
 | 
			
		||||
		einfo "Using default system hostname"
 | 
			
		||||
		return 0
 | 
			
		||||
	fi
 | 
			
		||||
	ebegin "Setting hostname to $h $source"
 | 
			
		||||
	ebegin "Setting hostname to $h from $source"
 | 
			
		||||
	hostname "$h"
 | 
			
		||||
	eend $? "Failed to set the hostname"
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -72,7 +72,7 @@ get_noadjfile()
 | 
			
		||||
{
 | 
			
		||||
	if ! yesno $clock_adjfile; then
 | 
			
		||||
		# Some implementations don't handle adjustments
 | 
			
		||||
		if LC_ALL=C hwclock --help 2>&1 | grep -q "\-\-noadjfile"; then
 | 
			
		||||
		if LC_ALL=C hwclock --help 2>&1 | grep -q -e "--noadjfile"; then
 | 
			
		||||
			echo --noadjfile
 | 
			
		||||
		fi
 | 
			
		||||
	fi
 | 
			
		||||
 
 | 
			
		||||
@@ -42,7 +42,7 @@ start()
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	local wkeys= kmode="-a" msg="ASCII"
 | 
			
		||||
	if yesno $unicode; then
 | 
			
		||||
	if yesno ${unicode:-yes}; then
 | 
			
		||||
		kmode="-u"
 | 
			
		||||
		msg="UTF-8"
 | 
			
		||||
	fi
 | 
			
		||||
 
 | 
			
		||||
@@ -56,10 +56,10 @@ load_modules()
 | 
			
		||||
		ebegin "Loading module $x"
 | 
			
		||||
		case "$RC_UNAME" in
 | 
			
		||||
			FreeBSD) kldload "$x"; rc=$? ;;
 | 
			
		||||
			Linux) modprobe --first-time -q --use-blacklist "$x"; rc=$? ;;
 | 
			
		||||
			Linux) modprobe --first-time --use-blacklist --verbose "$x"; rc=$? ;;
 | 
			
		||||
			*) ;;
 | 
			
		||||
		esac
 | 
			
		||||
		eend $rc "Failed to load $x"
 | 
			
		||||
		eend
 | 
			
		||||
	done
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
@@ -80,9 +80,10 @@ FreeBSD_modules()
 | 
			
		||||
	for x in $modules; do
 | 
			
		||||
		ebegin "Loading module $x"
 | 
			
		||||
		kldload "$x"
 | 
			
		||||
		eend $? "Failed to load $x" && : $(( cnt += 1 ))
 | 
			
		||||
		eend && : $(( cnt += 1 ))
 | 
			
		||||
	done
 | 
			
		||||
	einfo "Autoloaded $cnt module(s)"
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Linux_modules()
 | 
			
		||||
@@ -122,6 +123,7 @@ Linux_modules()
 | 
			
		||||
		eval modprobe --first-time --use-blacklist --verbose "$x" "$args"
 | 
			
		||||
	done
 | 
			
		||||
	[ -n "$list" ] && eend
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
start()
 | 
			
		||||
 
 | 
			
		||||
@@ -49,9 +49,7 @@ start()
 | 
			
		||||
	local mountpoint
 | 
			
		||||
	for mountpoint in $(fstabinfo); do
 | 
			
		||||
		case "${mountpoint}" in
 | 
			
		||||
			/)
 | 
			
		||||
			;;
 | 
			
		||||
			/*)
 | 
			
		||||
			/*) # Don't remount swap etc.
 | 
			
		||||
				mountinfo -q "${mountpoint}" && \
 | 
			
		||||
					fstabinfo --remount "${mountpoint}"
 | 
			
		||||
			;;
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,7 @@ start()
 | 
			
		||||
	# Save the encoding for use immediately at boot
 | 
			
		||||
	if checkpath -W "$RC_LIBEXECDIR"; then
 | 
			
		||||
		mkdir -p "$RC_LIBEXECDIR"/console
 | 
			
		||||
		if yesno ${unicode:-${UNICODE}}; then
 | 
			
		||||
		if yesno ${unicode:-yes}; then
 | 
			
		||||
			echo "" > "$RC_LIBEXECDIR"/console/unicode
 | 
			
		||||
		else
 | 
			
		||||
			rm -f "$RC_LIBEXECDIR"/console/unicode
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,7 @@
 | 
			
		||||
# except according to the terms contained in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
description="Sets the local clock to the mtime of a given file."
 | 
			
		||||
swclock_file="${swclock_file:-/var/lib/misc/openrc-shutdowntime}"
 | 
			
		||||
 | 
			
		||||
depend()
 | 
			
		||||
{
 | 
			
		||||
@@ -22,7 +23,7 @@ depend()
 | 
			
		||||
start()
 | 
			
		||||
{
 | 
			
		||||
	ebegin "Setting the local clock based on last shutdown time"
 | 
			
		||||
	if ! swclock 2> /dev/null; then
 | 
			
		||||
	if ! swclock "${swclock_file}" 2> /dev/null; then
 | 
			
		||||
	swclock --warn @SBINDIR@/openrc-run
 | 
			
		||||
	fi
 | 
			
		||||
	eend $?
 | 
			
		||||
@@ -31,6 +32,6 @@ start()
 | 
			
		||||
stop()
 | 
			
		||||
{
 | 
			
		||||
	ebegin "Saving the shutdown time"
 | 
			
		||||
	swclock --save
 | 
			
		||||
	swclock --save "${swclock_file}"
 | 
			
		||||
	eend $?
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,7 @@ start()
 | 
			
		||||
	# Set terminal encoding to either ASCII or UNICODE.
 | 
			
		||||
	# See utf-8(7) for more information.
 | 
			
		||||
	local termencoding="%@" termmsg="ASCII"
 | 
			
		||||
	if yesno ${unicode}; then
 | 
			
		||||
	if yesno ${unicode:-yes}; then
 | 
			
		||||
		termencoding="%G"
 | 
			
		||||
		termmsg="UTF-8"
 | 
			
		||||
	fi
 | 
			
		||||
@@ -43,7 +43,7 @@ start()
 | 
			
		||||
	# Save the encoding for use immediately at boot
 | 
			
		||||
	if checkpath -W "$RC_LIBEXECDIR"; then
 | 
			
		||||
		mkdir -p "$RC_LIBEXECDIR"/console
 | 
			
		||||
		if yesno ${unicode:-${UNICODE}}; then
 | 
			
		||||
		if yesno ${unicode:-yes}; then
 | 
			
		||||
			echo "" > "$RC_LIBEXECDIR"/console/unicode
 | 
			
		||||
		else
 | 
			
		||||
			rm -f "$RC_LIBEXECDIR"/console/unicode
 | 
			
		||||
 
 | 
			
		||||
@@ -158,13 +158,6 @@ is true.
 | 
			
		||||
prefixes the string
 | 
			
		||||
.Fa prefix
 | 
			
		||||
to the above functions.
 | 
			
		||||
.Sh IMPLEMENTATION NOTES
 | 
			
		||||
einfo can optionally be linked against the
 | 
			
		||||
.Lb libtermcap
 | 
			
		||||
so that we can correctly query the connected console for our color and
 | 
			
		||||
cursor escape codes.
 | 
			
		||||
If not, then we have a hard coded list of terminals we know about that support
 | 
			
		||||
the commonly used codes for color and cursor position.
 | 
			
		||||
.Sh ENVIRONMENT
 | 
			
		||||
.Va EINFO_QUIET
 | 
			
		||||
when set to true makes the
 | 
			
		||||
 
 | 
			
		||||
@@ -37,11 +37,11 @@ Brings up any system specific stuff such as
 | 
			
		||||
and optionally
 | 
			
		||||
.Pa /sys
 | 
			
		||||
for Linux based systems. It also mounts
 | 
			
		||||
.Pa /lib/rc/init.d
 | 
			
		||||
.Pa /run/openrc
 | 
			
		||||
as a ramdisk using tmpfs where available unless / is mounted rw at boot.
 | 
			
		||||
.Nm
 | 
			
		||||
uses
 | 
			
		||||
.Pa /lib/rc/init.d
 | 
			
		||||
.Pa /run/openrc
 | 
			
		||||
to hold state information about the services it runs.
 | 
			
		||||
sysinit always runs when the host first starts should not be run again.
 | 
			
		||||
.It Ar boot
 | 
			
		||||
 
 | 
			
		||||
@@ -47,7 +47,7 @@ services.
 | 
			
		||||
.Pp
 | 
			
		||||
.Fn rc_deptree_update
 | 
			
		||||
updates the service dependency tree, normally
 | 
			
		||||
.Pa /lib/rc/init.d/deptree .
 | 
			
		||||
.Pa /run/openrc/deptree .
 | 
			
		||||
.Fn rc_deptree_update_needed
 | 
			
		||||
checks to see if the dependency tree needs updated based on the mtime of it
 | 
			
		||||
compared to
 | 
			
		||||
 
 | 
			
		||||
@@ -204,7 +204,7 @@ When a function fails it should either return false or NULL and set
 | 
			
		||||
.Va errno
 | 
			
		||||
unless specified otherwise as above.
 | 
			
		||||
.Sh FILES
 | 
			
		||||
.Pa /lib/rc/init.d
 | 
			
		||||
.Pa /run/openrc
 | 
			
		||||
normally holds the volatile state data for services on a RAM backed disk.
 | 
			
		||||
.Sh SEE ALSO
 | 
			
		||||
.Xr errno 3 ,
 | 
			
		||||
 
 | 
			
		||||
@@ -84,6 +84,8 @@ Print the action(s) that would be taken, but don't actually do anything.
 | 
			
		||||
The return value is set as if the command was taken and worked.
 | 
			
		||||
.It Fl v , -verbose
 | 
			
		||||
Print the action(s) that are taken just before doing them.
 | 
			
		||||
.It Fl q , -quiet
 | 
			
		||||
Run quietly (repeat to suppress errors).
 | 
			
		||||
.It Fl P , -progress
 | 
			
		||||
Echo a . to the console for each second elapsed whilst waiting.
 | 
			
		||||
.El
 | 
			
		||||
@@ -183,10 +185,6 @@ Wait
 | 
			
		||||
after starting and check that daemon is still running.
 | 
			
		||||
Useful for daemons that check configuration after forking or stopping race
 | 
			
		||||
conditions where the pidfile is written out after forking.
 | 
			
		||||
.It Fl 2 , -stderr Ar logfile
 | 
			
		||||
The same thing as
 | 
			
		||||
.Fl 1 , -stdout
 | 
			
		||||
but with the standard error output.
 | 
			
		||||
.El
 | 
			
		||||
.Pp
 | 
			
		||||
These options are only used for stopping daemons:
 | 
			
		||||
 
 | 
			
		||||
@@ -158,6 +158,23 @@ The logfile can also be a named pipe.
 | 
			
		||||
The same thing as
 | 
			
		||||
.Fl 1 , -stdout
 | 
			
		||||
but with the standard error output.
 | 
			
		||||
.It Fl -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 -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 -capabilities Ar cap-list
 | 
			
		||||
Start the daemon with the listed inheritable, ambient and bounding capabilities.
 | 
			
		||||
The format is the same as in cap_iab(3).
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										39
									
								
								meson.build
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								meson.build
									
									
									
									
									
								
							@@ -1,5 +1,5 @@
 | 
			
		||||
project('OpenRC', 'c',
 | 
			
		||||
  version : '0.45',
 | 
			
		||||
  version : '0.54',
 | 
			
		||||
  license: 'BSD-2',
 | 
			
		||||
  default_options : [
 | 
			
		||||
    'c_std=c99',
 | 
			
		||||
@@ -36,7 +36,7 @@ endif
 | 
			
		||||
option_os = get_option('os')
 | 
			
		||||
if option_os == ''
 | 
			
		||||
  uname = find_program('uname')
 | 
			
		||||
  r = run_command(uname, '-s')
 | 
			
		||||
  r = run_command(uname, '-s', check: true)
 | 
			
		||||
  os = r.stdout().strip()
 | 
			
		||||
  os = '-'.join(os.split('/'))
 | 
			
		||||
else
 | 
			
		||||
@@ -83,16 +83,9 @@ else
 | 
			
		||||
  pkg_prefix = option_pkg_prefix
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
if get_option('split-usr') == 'auto'
 | 
			
		||||
  split_usr = run_command('test', '-L', '/bin').returncode() != 0
 | 
			
		||||
else
 | 
			
		||||
  split_usr = get_option('split-usr') == 'true'
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
rootprefix = get_option('rootprefix')
 | 
			
		||||
rootprefix_default = fs.is_symlink('/bin') ? '/usr' : '/'
 | 
			
		||||
if rootprefix == ''
 | 
			
		||||
rootprefix = rootprefix_default
 | 
			
		||||
rootprefix = '/'
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
bindir = rootprefix / get_option('bindir')
 | 
			
		||||
@@ -133,15 +126,6 @@ else
 | 
			
		||||
  cc_selinux_flags = []
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
termcap = get_option('termcap')
 | 
			
		||||
if termcap != ''
 | 
			
		||||
  termcap_dep = dependency(termcap)
 | 
			
		||||
  termcap_flags = '-DHAVE_TERMCAP'
 | 
			
		||||
  else
 | 
			
		||||
  termcap_dep = []
 | 
			
		||||
  termcap_flags = []
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
if get_option('buildtype').startswith('debug')
 | 
			
		||||
  cc_debug_flags = ['-DRC_DEBUG']
 | 
			
		||||
else
 | 
			
		||||
@@ -176,7 +160,10 @@ cc_warning_flags_test = [
 | 
			
		||||
  '-Wsequence-point',
 | 
			
		||||
  '-Wshadow',
 | 
			
		||||
  '-Wwrite-strings',
 | 
			
		||||
  '-Werror=implicit-int',
 | 
			
		||||
  '-Werror=implicit-function-declaration',
 | 
			
		||||
  '-Werror=int-conversion',
 | 
			
		||||
  '-Werror=incompatible-function-pointer-types',
 | 
			
		||||
  ]
 | 
			
		||||
cc_warning_flags = cc.get_supported_arguments(cc_warning_flags_test)
 | 
			
		||||
cc_flags = [cc_debug_flags, cc_os_flags, cc_warning_flags]
 | 
			
		||||
@@ -192,6 +179,16 @@ if cc.compiles(malloc_attribute_test, name : 'malloc attribute with arguments')
 | 
			
		||||
  add_project_arguments('-DHAVE_MALLOC_EXTENDED_ATTRIBUTE', language: 'c')
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
if cc.has_function('close_range', prefix: '#define _GNU_SOURCE\n#include <unistd.h>')
 | 
			
		||||
  add_project_arguments('-DHAVE_CLOSE_RANGE', language: 'c')
 | 
			
		||||
elif cc.has_header('linux/close_range.h')
 | 
			
		||||
  add_project_arguments('-DHAVE_LINUX_CLOSE_RANGE_H', language: 'c')
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
if cc.has_function('strlcpy', prefix: '#define _GNU_SOURCE\n#include <string.h>')
 | 
			
		||||
  add_project_arguments('-DHAVE_STRLCPY', language: 'c')
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
incdir = include_directories('src/shared')
 | 
			
		||||
einfo_incdir = include_directories('src/libeinfo')
 | 
			
		||||
rc_incdir = include_directories('src/librc')
 | 
			
		||||
@@ -226,4 +223,6 @@ meson.add_install_script('tools/meson_runlevels.sh',
 | 
			
		||||
  get_option('sysvinit') ? 'yes' : 'no')
 | 
			
		||||
meson.add_install_script('tools/meson_final.sh',
 | 
			
		||||
  rc_libexecdir,
 | 
			
		||||
  os)
 | 
			
		||||
  sbindir,
 | 
			
		||||
  os,
 | 
			
		||||
  get_option('sysvinit') ? 'yes' : 'no')
 | 
			
		||||
 
 | 
			
		||||
@@ -26,14 +26,7 @@ option('selinux', type : 'feature', value : 'auto',
 | 
			
		||||
  description : 'enable SELinux support')
 | 
			
		||||
option('shell', type : 'string', value : '/bin/sh',
 | 
			
		||||
  description : 'Default posix compatible shell')
 | 
			
		||||
option('split-usr', type : 'combo',
 | 
			
		||||
  choices : ['auto', 'true', 'false'],
 | 
			
		||||
  description : '''/bin, /sbin aren't symlinks into /usr''')
 | 
			
		||||
option('sysvinit', type : 'boolean', value : false,
 | 
			
		||||
  description : 'enable SysVinit compatibility (linux only)')
 | 
			
		||||
option('termcap', type : 'combo',
 | 
			
		||||
  choices :
 | 
			
		||||
    [ '', 'ncurses', 'termcap' ],
 | 
			
		||||
  description : 'the termcap library to use')
 | 
			
		||||
option('zsh-completions', type : 'boolean',
 | 
			
		||||
  description : 'install zsh completions')
 | 
			
		||||
 
 | 
			
		||||
@@ -79,6 +79,7 @@ elif ! mountinfo -q /run; then
 | 
			
		||||
			exit 1
 | 
			
		||||
		fi
 | 
			
		||||
	fi
 | 
			
		||||
	eend
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
checkpath -d "$RC_SVCDIR"
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,7 @@ cgroup_get_pids()
 | 
			
		||||
	cgroup_pids=
 | 
			
		||||
	cgroup_procs="$(cgroup2_find_path)"
 | 
			
		||||
	if [ -n "${cgroup_procs}" ]; then
 | 
			
		||||
		cgroup_procs="${cgroup_procs}/${RC_SVCNAME}/cgroup.procs"
 | 
			
		||||
		cgroup_procs="${cgroup_procs}/openrc.${RC_SVCNAME}/cgroup.procs"
 | 
			
		||||
	else
 | 
			
		||||
		cgroup_procs="/sys/fs/cgroup/openrc/${RC_SVCNAME}/tasks"
 | 
			
		||||
	fi
 | 
			
		||||
@@ -154,7 +154,7 @@ cgroup_set_limits()
 | 
			
		||||
cgroup2_find_path()
 | 
			
		||||
{
 | 
			
		||||
	if grep -qw cgroup2 /proc/filesystems; then
 | 
			
		||||
		case "${rc_cgroup_mode:-hybrid}" in
 | 
			
		||||
		case "${rc_cgroup_mode:-unified}" in
 | 
			
		||||
			hybrid) printf "/sys/fs/cgroup/unified" ;;
 | 
			
		||||
			unified) printf "/sys/fs/cgroup" ;;
 | 
			
		||||
		esac
 | 
			
		||||
@@ -167,7 +167,7 @@ cgroup2_remove()
 | 
			
		||||
	local cgroup_path rc_cgroup_path
 | 
			
		||||
	cgroup_path="$(cgroup2_find_path)"
 | 
			
		||||
	[ -z "${cgroup_path}" ] && return 0
 | 
			
		||||
	rc_cgroup_path="${cgroup_path}/${RC_SVCNAME}"
 | 
			
		||||
	rc_cgroup_path="${cgroup_path}/openrc.${RC_SVCNAME}"
 | 
			
		||||
	[ ! -d "${rc_cgroup_path}" ] ||
 | 
			
		||||
		[ ! -e "${rc_cgroup_path}"/cgroup.events ] &&
 | 
			
		||||
		return 0
 | 
			
		||||
@@ -191,7 +191,7 @@ cgroup2_set_limits()
 | 
			
		||||
	cgroup_path="$(cgroup2_find_path)"
 | 
			
		||||
	[ -z "${cgroup_path}" ] && return 0
 | 
			
		||||
	mountinfo -q "${cgroup_path}"|| return 0
 | 
			
		||||
	rc_cgroup_path="${cgroup_path}/${RC_SVCNAME}"
 | 
			
		||||
	rc_cgroup_path="${cgroup_path}/openrc.${RC_SVCNAME}"
 | 
			
		||||
	[ ! -d "${rc_cgroup_path}" ] && mkdir "${rc_cgroup_path}"
 | 
			
		||||
	[ -f "${rc_cgroup_path}"/cgroup.procs ] &&
 | 
			
		||||
		printf 0 > "${rc_cgroup_path}"/cgroup.procs
 | 
			
		||||
@@ -210,7 +210,7 @@ cgroup2_kill_cgroup() {
 | 
			
		||||
	local cgroup_path
 | 
			
		||||
	cgroup_path="$(cgroup2_find_path)"
 | 
			
		||||
	[ -z "${cgroup_path}" ] && return 1
 | 
			
		||||
	rc_cgroup_path="${cgroup_path}/${RC_SVCNAME}"
 | 
			
		||||
	rc_cgroup_path="${cgroup_path}/openrc.${RC_SVCNAME}"
 | 
			
		||||
	if [ -f "${rc_cgroup_path}"/cgroup.kill ]; then
 | 
			
		||||
		printf "%d" 1 > "${rc_cgroup_path}"/cgroup.kill
 | 
			
		||||
	fi
 | 
			
		||||
 
 | 
			
		||||
@@ -2,8 +2,10 @@
 | 
			
		||||
# Copyright (c) 2007-2009 Roy Marples <roy@marples.name>
 | 
			
		||||
# Released under the 2-clause BSD license.
 | 
			
		||||
 | 
			
		||||
net_fs_list="afs ceph cifs coda davfs fuse fuse.sshfs gfs glusterfs lustre
 | 
			
		||||
ncpfs nfs nfs4 ocfs2 shfs smbfs"
 | 
			
		||||
net_fs_list="
 | 
			
		||||
	afs ceph cifs coda davfs fuse fuse.glusterfs fuse.sshfs gfs glusterfs lustre
 | 
			
		||||
	ncpfs nfs nfs4 ocfs2 shfs smbfs
 | 
			
		||||
"
 | 
			
		||||
is_net_fs()
 | 
			
		||||
{
 | 
			
		||||
	[ -z "$1" ] && return 1
 | 
			
		||||
 
 | 
			
		||||
@@ -47,8 +47,8 @@ ssd_start()
 | 
			
		||||
		${directory:+--chdir} $directory \
 | 
			
		||||
		${output_log+--stdout} $output_log \
 | 
			
		||||
		${error_log+--stderr} $error_log \
 | 
			
		||||
		${output_logger:+--stdout-logger} "$output_logger" \
 | 
			
		||||
		${error_logger:+--stderr-logger} "$error_logger" \
 | 
			
		||||
		${output_logger:+--stdout-logger \"$output_logger\"} \
 | 
			
		||||
		${error_logger:+--stderr-logger \"$error_logger\"} \
 | 
			
		||||
		${capabilities+--capabilities} "$capabilities" \
 | 
			
		||||
		${secbits:+--secbits} "$secbits" \
 | 
			
		||||
		${no_new_privs:+--no-new-privs} \
 | 
			
		||||
 
 | 
			
		||||
@@ -30,6 +30,8 @@ supervise_start()
 | 
			
		||||
		${chroot:+--chroot} $chroot \
 | 
			
		||||
		${output_log+--stdout} ${output_log} \
 | 
			
		||||
		${error_log+--stderr} $error_log \
 | 
			
		||||
		${output_logger:+--stdout-logger \"$output_logger\"} \
 | 
			
		||||
		${error_logger:+--stderr-logger \"$error_logger\"} \
 | 
			
		||||
		${pidfile:+--pidfile} $pidfile \
 | 
			
		||||
		${respawn_delay:+--respawn-delay} $respawn_delay \
 | 
			
		||||
		${respawn_max:+--respawn-max} $respawn_max \
 | 
			
		||||
@@ -38,10 +40,10 @@ supervise_start()
 | 
			
		||||
		${healthcheck_timer:+--healthcheck-timer} $healthcheck_timer \
 | 
			
		||||
		${capabilities+--capabilities} "$capabilities" \
 | 
			
		||||
		${secbits:+--secbits} "$secbits" \
 | 
			
		||||
		${no_new_privs:+--no_new_privs} \
 | 
			
		||||
		${no_new_privs:+--no-new-privs} \
 | 
			
		||||
		${command_user+--user} $command_user \
 | 
			
		||||
		${umask+--umask} $umask \
 | 
			
		||||
		${supervise_daemon_args:-${start_stop_daemon_args}} \
 | 
			
		||||
		${supervise_daemon_args-${start_stop_daemon_args}} \
 | 
			
		||||
		$command \
 | 
			
		||||
		-- $command_args $command_args_foreground
 | 
			
		||||
	rc=$?
 | 
			
		||||
 
 | 
			
		||||
@@ -17,25 +17,24 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define _GNU_SOURCE
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <getopt.h>
 | 
			
		||||
#include <grp.h>
 | 
			
		||||
#include <libgen.h>
 | 
			
		||||
#include <pwd.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include "einfo.h"
 | 
			
		||||
#include "rc.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
#include "selinux.h"
 | 
			
		||||
#include "_usage.h"
 | 
			
		||||
#include "helpers.h"
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
	inode_unknown = 0,
 | 
			
		||||
@@ -89,7 +88,7 @@ static int get_dirfd(char *path, bool symlinks)
 | 
			
		||||
 | 
			
		||||
	if (!path || *path != '/')
 | 
			
		||||
		eerrorx("%s: empty or relative path", applet);
 | 
			
		||||
	dirfd = openat(dirfd, "/", O_RDONLY);
 | 
			
		||||
	dirfd = openat(AT_FDCWD, "/", O_RDONLY);
 | 
			
		||||
	if (dirfd == -1)
 | 
			
		||||
		eerrorx("%s: unable to open the root directory: %s",
 | 
			
		||||
				applet, strerror(errno));
 | 
			
		||||
@@ -285,7 +284,7 @@ static int do_check(char *path, uid_t uid, gid_t gid, mode_t mode,
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (mode && (st.st_mode & 0777) != mode) {
 | 
			
		||||
		if (mode && (st.st_mode & 07777) != mode) {
 | 
			
		||||
			if ((type != inode_dir) && (st.st_nlink > 1)) {
 | 
			
		||||
				eerror("%s: chmod: Too many hard links to %s", applet, path);
 | 
			
		||||
				close(readfd);
 | 
			
		||||
 
 | 
			
		||||
@@ -12,20 +12,17 @@
 | 
			
		||||
 | 
			
		||||
#define SYSLOG_NAMES
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <syslog.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <strings.h>
 | 
			
		||||
 | 
			
		||||
#include "einfo.h"
 | 
			
		||||
#include "helpers.h"
 | 
			
		||||
@@ -81,7 +78,7 @@ int main(int argc, char **argv)
 | 
			
		||||
		if (strcmp(applet, "eend") == 0 ||
 | 
			
		||||
		    strcmp(applet, "ewend") == 0 ||
 | 
			
		||||
		    strcmp(applet, "veend") == 0 ||
 | 
			
		||||
		    strcmp(applet, "vweend") == 0 ||
 | 
			
		||||
		    strcmp(applet, "vewend") == 0 ||
 | 
			
		||||
		    strcmp(applet, "ewaitfile") == 0)
 | 
			
		||||
		{
 | 
			
		||||
			errno = 0;
 | 
			
		||||
 
 | 
			
		||||
@@ -16,13 +16,14 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <getopt.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <spawn.h>
 | 
			
		||||
 | 
			
		||||
/* Yay for linux and its non liking of POSIX functions.
 | 
			
		||||
   Okay, we could use getfsent but the man page says use getmntent instead
 | 
			
		||||
@@ -30,6 +31,7 @@
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
#  define HAVE_GETMNTENT
 | 
			
		||||
#  include <mntent.h>
 | 
			
		||||
 | 
			
		||||
#  define ENT mntent
 | 
			
		||||
#  define START_ENT fp = setmntent ("/etc/fstab", "r");
 | 
			
		||||
#  define GET_ENT getmntent (fp)
 | 
			
		||||
@@ -43,6 +45,7 @@
 | 
			
		||||
#else
 | 
			
		||||
#  define HAVE_GETFSENT
 | 
			
		||||
#  include <fstab.h>
 | 
			
		||||
 | 
			
		||||
#  define ENT fstab
 | 
			
		||||
#  define START_ENT
 | 
			
		||||
#  define GET_ENT getfsent ()
 | 
			
		||||
@@ -58,8 +61,10 @@
 | 
			
		||||
#include "einfo.h"
 | 
			
		||||
#include "queue.h"
 | 
			
		||||
#include "rc.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
#include "_usage.h"
 | 
			
		||||
#include "helpers.h"
 | 
			
		||||
 | 
			
		||||
extern char **environ;
 | 
			
		||||
 | 
			
		||||
const char *applet = NULL;
 | 
			
		||||
const char *extraopts = NULL;
 | 
			
		||||
@@ -110,7 +115,7 @@ do_mount(struct ENT *ent, bool remount)
 | 
			
		||||
{
 | 
			
		||||
	char *argv[10];
 | 
			
		||||
	pid_t pid;
 | 
			
		||||
	int status;
 | 
			
		||||
	int status, err;
 | 
			
		||||
 | 
			
		||||
	argv[0] = UNCONST("mount");
 | 
			
		||||
	argv[1] = UNCONST("-o");
 | 
			
		||||
@@ -135,23 +140,14 @@ do_mount(struct ENT *ent, bool remount)
 | 
			
		||||
		argv[8] = NULL;
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
	switch (pid = vfork()) {
 | 
			
		||||
	case -1:
 | 
			
		||||
		eerrorx("%s: vfork: %s", applet, strerror(errno));
 | 
			
		||||
		/* NOTREACHED */
 | 
			
		||||
	case 0:
 | 
			
		||||
		execvp(argv[0], argv);
 | 
			
		||||
		eerror("%s: execvp: %s", applet, strerror(errno));
 | 
			
		||||
		_exit(EXIT_FAILURE);
 | 
			
		||||
		/* NOTREACHED */
 | 
			
		||||
	default:
 | 
			
		||||
		waitpid(pid, &status, 0);
 | 
			
		||||
	err = posix_spawnp(&pid, argv[0], NULL, NULL, argv, environ);
 | 
			
		||||
	if (err)
 | 
			
		||||
		eerrorx("%s: posix_spawnp: %s", applet, strerror(err));
 | 
			
		||||
	while (waitpid(pid, &status, 0) < 0 && errno == EINTR);
 | 
			
		||||
	if (WIFEXITED(status))
 | 
			
		||||
		return WEXITSTATUS(status);
 | 
			
		||||
	else
 | 
			
		||||
		return -1;
 | 
			
		||||
		/* NOTREACHED */
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define OUTPUT_FILE      (1 << 1)
 | 
			
		||||
 
 | 
			
		||||
@@ -10,13 +10,9 @@
 | 
			
		||||
 *    except according to the terms contained in the LICENSE file.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#include "rc.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
 | 
			
		||||
int main(int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -10,13 +10,9 @@
 | 
			
		||||
 *    except according to the terms contained in the LICENSE file.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#include "rc.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
 | 
			
		||||
int main(int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,6 @@
 | 
			
		||||
#include <dirent.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <getopt.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
@@ -28,11 +27,12 @@
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
 | 
			
		||||
#include "einfo.h"
 | 
			
		||||
#include "rc.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
#include "_usage.h"
 | 
			
		||||
#include "helpers.h"
 | 
			
		||||
 | 
			
		||||
const char *applet = NULL;
 | 
			
		||||
const char *extraopts = "[signal number]";
 | 
			
		||||
 
 | 
			
		||||
@@ -13,13 +13,8 @@
 | 
			
		||||
#ifndef __EINFO_H__
 | 
			
		||||
#define __EINFO_H__
 | 
			
		||||
 | 
			
		||||
#if defined(__GNUC__)
 | 
			
		||||
# define EINFO_PRINTF(a, b)  __attribute__((__format__(__printf__, a, b)))
 | 
			
		||||
# define EINFO_XPRINTF(a, b) __attribute__((__noreturn__,__format__(__printf__, a, b)))
 | 
			
		||||
#else
 | 
			
		||||
# define EINFO_PRINTF(a, b)
 | 
			
		||||
# define EINFO_XPRINTF(a, b)
 | 
			
		||||
#endif
 | 
			
		||||
#define EINFO_PRINTF(a, b)  __attribute__((__format__(__printf__, a, b)))
 | 
			
		||||
#define EINFO_XPRINTF(a, b) __attribute__((__noreturn__, __format__(__printf__, a, b)))
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
@@ -74,22 +69,22 @@ void elog(int, const char * EINFO_RESTRICT, ...) EINFO_PRINTF(2, 3);
 | 
			
		||||
 * The x suffix means function will exit() returning failure.
 | 
			
		||||
 */
 | 
			
		||||
/*@{*/
 | 
			
		||||
int einfon(const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
 | 
			
		||||
int ewarnn(const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
 | 
			
		||||
int eerrorn(const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
 | 
			
		||||
int einfo(const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
 | 
			
		||||
int ewarn(const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
 | 
			
		||||
void ewarnx(const char * __EINFO_RESTRICT, ...) EINFO_XPRINTF(1, 2);
 | 
			
		||||
int eerror(const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
 | 
			
		||||
void eerrorx(const char * __EINFO_RESTRICT, ...) EINFO_XPRINTF(1, 2);
 | 
			
		||||
int einfon(const char * EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
 | 
			
		||||
int ewarnn(const char * EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
 | 
			
		||||
int eerrorn(const char * EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
 | 
			
		||||
int einfo(const char * EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
 | 
			
		||||
int ewarn(const char * EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
 | 
			
		||||
void ewarnx(const char * EINFO_RESTRICT, ...) EINFO_XPRINTF(1, 2);
 | 
			
		||||
int eerror(const char * EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
 | 
			
		||||
void eerrorx(const char * EINFO_RESTRICT, ...) EINFO_XPRINTF(1, 2);
 | 
			
		||||
 | 
			
		||||
int einfovn(const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
 | 
			
		||||
int ewarnvn(const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
 | 
			
		||||
int ebeginvn(const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
 | 
			
		||||
int eendvn(int, const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(2, 3);
 | 
			
		||||
int ewendvn(int, const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(2, 3);
 | 
			
		||||
int einfov(const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
 | 
			
		||||
int ewarnv(const char * __EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
 | 
			
		||||
int einfovn(const char * EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
 | 
			
		||||
int ewarnvn(const char * EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
 | 
			
		||||
int ebeginvn(const char * EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
 | 
			
		||||
int eendvn(int, const char * EINFO_RESTRICT, ...) EINFO_PRINTF(2, 3);
 | 
			
		||||
int ewendvn(int, const char * EINFO_RESTRICT, ...) EINFO_PRINTF(2, 3);
 | 
			
		||||
int einfov(const char * EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
 | 
			
		||||
int ewarnv(const char * EINFO_RESTRICT, ...) EINFO_PRINTF(1, 2);
 | 
			
		||||
/*@}*/
 | 
			
		||||
 | 
			
		||||
/*! @ingroup ebegin
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007-2015 The OpenRC Authors.
 | 
			
		||||
 * Copyright (c) 2007-2024 The OpenRC Authors.
 | 
			
		||||
 * See the Authors file at the top-level directory of this distribution and
 | 
			
		||||
 * https://github.com/OpenRC/openrc/blob/HEAD/AUTHORS
 | 
			
		||||
 *
 | 
			
		||||
@@ -15,24 +15,17 @@
 | 
			
		||||
 *    except according to the terms contained in the LICENSE file.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/ioctl.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <strings.h>
 | 
			
		||||
#include <syslog.h>
 | 
			
		||||
#ifdef HAVE_TERMCAP
 | 
			
		||||
# include <termcap.h>
 | 
			
		||||
#endif
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include "einfo.h"
 | 
			
		||||
@@ -57,8 +50,7 @@
 | 
			
		||||
#define HILITE                  6
 | 
			
		||||
#define BRACKET                 4
 | 
			
		||||
 | 
			
		||||
/* We fallback to these escape codes if termcap isn't available
 | 
			
		||||
 * like say /usr isn't mounted */
 | 
			
		||||
/* ANSI escape codes which mimic termcap */
 | 
			
		||||
#define AF "\033[3%dm"
 | 
			
		||||
#define CE "\033[K"
 | 
			
		||||
#define CH "\033[%dC"
 | 
			
		||||
@@ -101,13 +93,7 @@ static char *goto_column = NULL;
 | 
			
		||||
static const char *term = NULL;
 | 
			
		||||
static bool term_is_cons25 = false;
 | 
			
		||||
 | 
			
		||||
/* Termcap buffers and pointers
 | 
			
		||||
 * Static buffers suck hard, but some termcap implementations require them */
 | 
			
		||||
#ifdef HAVE_TERMCAP
 | 
			
		||||
static char termcapbuf[2048];
 | 
			
		||||
static char tcapbuf[512];
 | 
			
		||||
#else
 | 
			
		||||
/* No curses support, so we hardcode a list of colour capable terms
 | 
			
		||||
/* Hardcoded list of colour capable terms
 | 
			
		||||
 * Only terminals without "color" in the name need to be explicitly listed */
 | 
			
		||||
static const char *const color_terms[] = {
 | 
			
		||||
	"Eterm",
 | 
			
		||||
@@ -146,13 +132,11 @@ static const char *const color_terms[] = {
 | 
			
		||||
	"wsvt25",
 | 
			
		||||
	"xterm",
 | 
			
		||||
	"xterm-debian",
 | 
			
		||||
	"xterm-kitty",
 | 
			
		||||
	NULL
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* strlcat and strlcpy are nice, shame glibc does not define them */
 | 
			
		||||
#ifdef __GLIBC__
 | 
			
		||||
#  if !defined (__UCLIBC__) && !defined (__dietlibc__)
 | 
			
		||||
#ifndef HAVE_STRLCPY
 | 
			
		||||
static size_t
 | 
			
		||||
strlcat(char *dst, const char *src, size_t size)
 | 
			
		||||
{
 | 
			
		||||
@@ -180,7 +164,6 @@ strlcat(char *dst, const char *src, size_t size)
 | 
			
		||||
 | 
			
		||||
	return dst_n + (s - src);
 | 
			
		||||
}
 | 
			
		||||
#  endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static bool
 | 
			
		||||
@@ -243,7 +226,6 @@ is_verbose(void)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Fake tgoto call - very crapy, but works for our needs */
 | 
			
		||||
#ifndef HAVE_TERMCAP
 | 
			
		||||
static char *
 | 
			
		||||
tgoto(const char *cap, int col, int line)
 | 
			
		||||
{
 | 
			
		||||
@@ -306,7 +288,6 @@ tgoto(const char *cap, int col, int line)
 | 
			
		||||
	*p = '\0';
 | 
			
		||||
	return buf;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static bool
 | 
			
		||||
colour_terminal(FILE * EINFO_RESTRICT f)
 | 
			
		||||
@@ -319,9 +300,6 @@ colour_terminal(FILE * EINFO_RESTRICT f)
 | 
			
		||||
	const char *bold;
 | 
			
		||||
	char tmp[100];
 | 
			
		||||
	unsigned int i = 0;
 | 
			
		||||
#ifdef HAVE_TERMCAP
 | 
			
		||||
	char *bp;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	if (f && !isatty(fileno(f)))
 | 
			
		||||
		return false;
 | 
			
		||||
@@ -343,25 +321,6 @@ colour_terminal(FILE * EINFO_RESTRICT f)
 | 
			
		||||
	if (strcmp(term, "cons25") == 0)
 | 
			
		||||
		term_is_cons25 = true;
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_TERMCAP
 | 
			
		||||
	/* Check termcap to see if we can do colour or not */
 | 
			
		||||
	if (tgetent(termcapbuf, term) == 1) {
 | 
			
		||||
		bp = tcapbuf;
 | 
			
		||||
		_af = tgetstr("AF", &bp);
 | 
			
		||||
		_ce = tgetstr("ce", &bp);
 | 
			
		||||
		_ch = tgetstr("ch", &bp);
 | 
			
		||||
		/* Our ch use also works with RI .... for now */
 | 
			
		||||
		if (!_ch)
 | 
			
		||||
			_ch = tgetstr("RI", &bp);
 | 
			
		||||
		_md = tgetstr("md", &bp);
 | 
			
		||||
		_me = tgetstr("me", &bp);
 | 
			
		||||
		_up = tgetstr("up", &bp);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Cheat here as vanilla BSD has the whole termcap info in /usr
 | 
			
		||||
	 * which is not available to us when we boot */
 | 
			
		||||
	if (term_is_cons25 || strcmp(term, "wsvt25") == 0) {
 | 
			
		||||
#else
 | 
			
		||||
	if (strstr(term, "color"))
 | 
			
		||||
		in_colour = 1;
 | 
			
		||||
 | 
			
		||||
@@ -376,7 +335,7 @@ colour_terminal(FILE * EINFO_RESTRICT f)
 | 
			
		||||
		in_colour = 0;
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	if (!_af)
 | 
			
		||||
		_af = AF;
 | 
			
		||||
	if (!_ce)
 | 
			
		||||
@@ -389,19 +348,6 @@ colour_terminal(FILE * EINFO_RESTRICT f)
 | 
			
		||||
		_me = ME;
 | 
			
		||||
	if (!_up)
 | 
			
		||||
		_up = UP;
 | 
			
		||||
#ifdef HAVE_TERMCAP
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!_af || !_ce || !_me || !_md || !_up) {
 | 
			
		||||
		in_colour = 0;
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Many termcap databases don't have ch or RI even though they
 | 
			
		||||
	 * do work */
 | 
			
		||||
	if (!_ch)
 | 
			
		||||
		_ch = CH;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* Now setup our colours */
 | 
			
		||||
	p = ebuffer;
 | 
			
		||||
@@ -677,15 +623,14 @@ ewarn(const char *EINFO_RESTRICT fmt, ...)
 | 
			
		||||
void
 | 
			
		||||
ewarnx(const char *EINFO_RESTRICT fmt, ...)
 | 
			
		||||
{
 | 
			
		||||
	int retval;
 | 
			
		||||
	va_list ap;
 | 
			
		||||
 | 
			
		||||
	if (fmt && !is_quiet()) {
 | 
			
		||||
		va_start(ap, fmt);
 | 
			
		||||
		elogv(LOG_WARNING, fmt, ap);
 | 
			
		||||
		retval = _ewarnvn(fmt, ap);
 | 
			
		||||
		_ewarnvn(fmt, ap);
 | 
			
		||||
		va_end(ap);
 | 
			
		||||
		retval += fprintf(stderr, "\n");
 | 
			
		||||
		fprintf(stderr, "\n");
 | 
			
		||||
	}
 | 
			
		||||
	exit(EXIT_FAILURE);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,7 @@
 | 
			
		||||
libeinfo_version = '1'
 | 
			
		||||
 | 
			
		||||
libeinfo = library('einfo', ['libeinfo.c'],
 | 
			
		||||
  c_args : termcap_flags,
 | 
			
		||||
  include_directories : incdir,
 | 
			
		||||
  dependencies : termcap_dep,
 | 
			
		||||
  link_depends : 'einfo.map',
 | 
			
		||||
  version : libeinfo_version,
 | 
			
		||||
  install : true,
 | 
			
		||||
 
 | 
			
		||||
@@ -15,10 +15,21 @@
 | 
			
		||||
 *    except according to the terms contained in the LICENSE file.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <dirent.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include "queue.h"
 | 
			
		||||
#include "librc.h"
 | 
			
		||||
#include "helpers.h"
 | 
			
		||||
 | 
			
		||||
#if defined(__linux__) || (defined (__FreeBSD_kernel__) && defined(__GLIBC__)) \
 | 
			
		||||
	|| defined(__GNU__)
 | 
			
		||||
@@ -391,7 +402,7 @@ rc_service_daemon_set(const char *service, const char *exec,
 | 
			
		||||
	bool retval = false;
 | 
			
		||||
	DIR *dp;
 | 
			
		||||
	struct dirent *d;
 | 
			
		||||
	RC_STRINGLIST *match;
 | 
			
		||||
	RC_STRINGLIST *match, *renamelist;
 | 
			
		||||
	int i = 0;
 | 
			
		||||
	FILE *fp;
 | 
			
		||||
 | 
			
		||||
@@ -405,11 +416,17 @@ rc_service_daemon_set(const char *service, const char *exec,
 | 
			
		||||
	/* Regardless, erase any existing daemon info */
 | 
			
		||||
	if ((dp = opendir(dirpath))) {
 | 
			
		||||
		match = _match_list(exec, argv, pidfile);
 | 
			
		||||
		renamelist = rc_stringlist_new();
 | 
			
		||||
		while ((d = readdir(dp))) {
 | 
			
		||||
			if (d->d_name[0] == '.')
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			xasprintf(&file, "%s/%s", dirpath, d->d_name);
 | 
			
		||||
			if (rc_stringlist_find(renamelist, file)) {
 | 
			
		||||
				free(file);
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			nfiles++;
 | 
			
		||||
 | 
			
		||||
			if (!*oldfile) {
 | 
			
		||||
@@ -421,11 +438,15 @@ rc_service_daemon_set(const char *service, const char *exec,
 | 
			
		||||
			} else {
 | 
			
		||||
				rename(file, oldfile);
 | 
			
		||||
				strlcpy(oldfile, file, sizeof(oldfile));
 | 
			
		||||
				/* Add renamed file to renamelist, as this new file name could
 | 
			
		||||
				 * be read again from readdir() */
 | 
			
		||||
				rc_stringlist_add(renamelist, oldfile);
 | 
			
		||||
			}
 | 
			
		||||
			free(file);
 | 
			
		||||
		}
 | 
			
		||||
		closedir(dp);
 | 
			
		||||
		rc_stringlist_free(match);
 | 
			
		||||
		rc_stringlist_free(renamelist);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Now store our daemon info */
 | 
			
		||||
 
 | 
			
		||||
@@ -16,9 +16,22 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/utsname.h>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <dirent.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include "queue.h"
 | 
			
		||||
#include "librc.h"
 | 
			
		||||
#include "helpers.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
 | 
			
		||||
#define GENDEP          RC_LIBEXECDIR "/sh/gendepends.sh"
 | 
			
		||||
 | 
			
		||||
@@ -1074,6 +1087,6 @@ rc_deptree_update(void)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	rc_stringlist_free(config);
 | 
			
		||||
	rc_deptree_free(deptree);
 | 
			
		||||
	free(deptree);
 | 
			
		||||
	return retval;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -16,11 +16,21 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <fnmatch.h>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <dirent.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <strings.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
 | 
			
		||||
#include "queue.h"
 | 
			
		||||
#include "librc.h"
 | 
			
		||||
#include "helpers.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
rc_yesno(const char *value)
 | 
			
		||||
@@ -117,7 +127,7 @@ rc_getline(char **line, size_t *len, FILE *fp)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *
 | 
			
		||||
rc_proc_getent(const char *ent _unused)
 | 
			
		||||
rc_proc_getent(const char *ent RC_UNUSED)
 | 
			
		||||
{
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
	FILE *fp;
 | 
			
		||||
@@ -277,6 +287,7 @@ static RC_STRINGLIST *rc_config_kcl(RC_STRINGLIST *config)
 | 
			
		||||
	overrides = rc_stringlist_new();
 | 
			
		||||
 | 
			
		||||
	/* A list of variables which may be overridden on the kernel command line */
 | 
			
		||||
	rc_stringlist_add(overrides, "rc_interactive");
 | 
			
		||||
	rc_stringlist_add(overrides, "rc_parallel");
 | 
			
		||||
 | 
			
		||||
	TAILQ_FOREACH(override, overrides, entries) {
 | 
			
		||||
 
 | 
			
		||||
@@ -15,8 +15,14 @@
 | 
			
		||||
 *    except according to the terms contained in the LICENSE file.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "queue.h"
 | 
			
		||||
#include "librc.h"
 | 
			
		||||
#include "helpers.h"
 | 
			
		||||
 | 
			
		||||
RC_STRINGLIST *
 | 
			
		||||
rc_stringlist_new(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -15,9 +15,26 @@
 | 
			
		||||
 *    except according to the terms contained in the LICENSE file.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <helpers.h>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <dirent.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <libgen.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#include <regex.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <sys/param.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include "queue.h"
 | 
			
		||||
#include "librc.h"
 | 
			
		||||
#include <helpers.h>
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
#include "rc.h"
 | 
			
		||||
#ifdef __FreeBSD__
 | 
			
		||||
#  include <sys/sysctl.h>
 | 
			
		||||
#endif
 | 
			
		||||
@@ -232,7 +249,7 @@ detect_prefix(const char *systype)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char *
 | 
			
		||||
detect_container(const char *systype _unused)
 | 
			
		||||
detect_container(const char *systype RC_UNUSED)
 | 
			
		||||
{
 | 
			
		||||
#ifdef __FreeBSD__
 | 
			
		||||
	if (systype) {
 | 
			
		||||
@@ -296,7 +313,7 @@ detect_container(const char *systype _unused)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char *
 | 
			
		||||
detect_vm(const char *systype _unused)
 | 
			
		||||
detect_vm(const char *systype RC_UNUSED)
 | 
			
		||||
{
 | 
			
		||||
#ifdef __NetBSD__
 | 
			
		||||
	if (systype) {
 | 
			
		||||
@@ -755,8 +772,10 @@ rc_service_mark(const char *service, const RC_SERVICE state)
 | 
			
		||||
					    RC_SVCDIR "/%s/%s",
 | 
			
		||||
					    rc_parse_service_state(RC_SERVICE_WASINACTIVE),
 | 
			
		||||
					    base);
 | 
			
		||||
					if (symlink(init, was) == -1)
 | 
			
		||||
					if (symlink(init, was) == -1) {
 | 
			
		||||
						free(init);
 | 
			
		||||
						return false;
 | 
			
		||||
					}
 | 
			
		||||
					skip_wasinactive = true;
 | 
			
		||||
				}
 | 
			
		||||
				if (unlink(file) == -1) {
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,6 @@
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <dirent.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
 
 | 
			
		||||
@@ -10,24 +10,18 @@
 | 
			
		||||
 *    except according to the terms contained in the LICENSE file.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <syslog.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 | 
			
		||||
#include "einfo.h"
 | 
			
		||||
#include "rc.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
#include "helpers.h"
 | 
			
		||||
 | 
			
		||||
const char *applet = NULL;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -15,15 +15,14 @@
 | 
			
		||||
 *    except according to the terms contained in the LICENSE file.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/param.h>
 | 
			
		||||
 | 
			
		||||
#if defined(__DragonFly__) || defined(__FreeBSD__)
 | 
			
		||||
#  include <sys/ucred.h>
 | 
			
		||||
#  include <sys/mount.h>
 | 
			
		||||
 | 
			
		||||
#  define F_FLAGS f_flags
 | 
			
		||||
#elif defined(BSD) && !defined(__GNU__)
 | 
			
		||||
#  include <sys/statvfs.h>
 | 
			
		||||
 | 
			
		||||
#  define statfs statvfs
 | 
			
		||||
#  define F_FLAGS f_flag
 | 
			
		||||
#elif defined(__linux__) || (defined(__FreeBSD_kernel__) && \
 | 
			
		||||
@@ -33,17 +32,19 @@
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <getopt.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#include <regex.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include "einfo.h"
 | 
			
		||||
#include "queue.h"
 | 
			
		||||
#include "rc.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
#include "_usage.h"
 | 
			
		||||
#include "helpers.h"
 | 
			
		||||
 | 
			
		||||
const char *applet = NULL;
 | 
			
		||||
const char *procmounts = "/proc/mounts";
 | 
			
		||||
 
 | 
			
		||||
@@ -27,16 +27,16 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <sys/reboot.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
#include <utmp.h>
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_SELINUX
 | 
			
		||||
#  include <selinux/selinux.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "helpers.h"
 | 
			
		||||
#include "rc.h"
 | 
			
		||||
#include "plugin.h"
 | 
			
		||||
#include "wtmp.h"
 | 
			
		||||
 
 | 
			
		||||
@@ -6,12 +6,3 @@ executable('openrc-run',
 | 
			
		||||
  include_directories: [incdir, einfo_incdir, rc_incdir],
 | 
			
		||||
  install: true,
 | 
			
		||||
  install_dir: sbindir)
 | 
			
		||||
 | 
			
		||||
executable('runscript',
 | 
			
		||||
  ['openrc-run.c', misc_c, plugin_c, selinux_c, usage_c, version_h],
 | 
			
		||||
  c_args : [cc_audit_flags, cc_branding_flags, cc_pam_flags, cc_selinux_flags],
 | 
			
		||||
  link_with: [libeinfo, librc],
 | 
			
		||||
  dependencies: [audit_dep, dl_dep, pam_dep, pam_misc_dep, selinux_dep, util_dep, crypt_dep],
 | 
			
		||||
  include_directories: [incdir, einfo_incdir, rc_incdir],
 | 
			
		||||
  install: true,
 | 
			
		||||
  install_dir: sbindir)
 | 
			
		||||
 
 | 
			
		||||
@@ -15,28 +15,26 @@
 | 
			
		||||
 *    except according to the terms contained in the LICENSE file.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/ioctl.h>
 | 
			
		||||
#include <sys/file.h>
 | 
			
		||||
#include <sys/param.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <fnmatch.h>
 | 
			
		||||
#include <getopt.h>
 | 
			
		||||
#include <libgen.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#include <poll.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <sys/ioctl.h>
 | 
			
		||||
#include <sys/file.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
#include <termios.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
 | 
			
		||||
#if defined(__linux__) || (defined(__FreeBSD_kernel__) && defined(__GLIBC__)) \
 | 
			
		||||
	|| defined(__GNU__)
 | 
			
		||||
@@ -54,6 +52,7 @@
 | 
			
		||||
#include "plugin.h"
 | 
			
		||||
#include "selinux.h"
 | 
			
		||||
#include "_usage.h"
 | 
			
		||||
#include "helpers.h"
 | 
			
		||||
 | 
			
		||||
#define PREFIX_LOCK	RC_SVCDIR "/prefix.lock"
 | 
			
		||||
 | 
			
		||||
@@ -62,7 +61,7 @@
 | 
			
		||||
#define WARN_TIMEOUT	10		/* warn about this every N seconds */
 | 
			
		||||
 | 
			
		||||
const char *applet = NULL;
 | 
			
		||||
const char *extraopts = "stop | start | restart | describe | zap";
 | 
			
		||||
const char *extraopts = "stop | start | restart | status | describe | zap";
 | 
			
		||||
const char getoptstring[] = "dDsSvl:Z" getoptstring_COMMON;
 | 
			
		||||
const struct option longopts[] = {
 | 
			
		||||
	{ "debug",      0, NULL, 'd'},
 | 
			
		||||
@@ -108,8 +107,9 @@ static RC_STRINGLIST *deptypes_mwua;	/* need+want+use+after deps for stopping */
 | 
			
		||||
static void
 | 
			
		||||
handle_signal(int sig)
 | 
			
		||||
{
 | 
			
		||||
	int serrno = errno;
 | 
			
		||||
	char *signame = NULL;
 | 
			
		||||
	int serrno = errno, status;
 | 
			
		||||
	pid_t pid;
 | 
			
		||||
	const char *signame = NULL;
 | 
			
		||||
	struct winsize ws;
 | 
			
		||||
 | 
			
		||||
	switch (sig) {
 | 
			
		||||
@@ -118,12 +118,13 @@ handle_signal(int sig)
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case SIGCHLD:
 | 
			
		||||
		if (signal_pipe[1] > -1) {
 | 
			
		||||
			if (write(signal_pipe[1], &sig, sizeof(sig)) == -1)
 | 
			
		||||
		while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
 | 
			
		||||
			if (signal_pipe[1] > -1 && pid == service_pid) {
 | 
			
		||||
				if (write(signal_pipe[1], &status, sizeof(status)) == -1)
 | 
			
		||||
					eerror("%s: send: %s",
 | 
			
		||||
					    service, strerror(errno));
 | 
			
		||||
		} else
 | 
			
		||||
			rc_waitpid(-1);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case SIGWINCH:
 | 
			
		||||
@@ -135,20 +136,19 @@ handle_signal(int sig)
 | 
			
		||||
 | 
			
		||||
	case SIGINT:
 | 
			
		||||
		if (!signame)
 | 
			
		||||
			xasprintf(&signame, "SIGINT");
 | 
			
		||||
			signame = "SIGINT";
 | 
			
		||||
		/* FALLTHROUGH */
 | 
			
		||||
	case SIGTERM:
 | 
			
		||||
		if (!signame)
 | 
			
		||||
			xasprintf(&signame, "SIGTERM");
 | 
			
		||||
			signame = "SIGTERM";
 | 
			
		||||
		/* FALLTHROUGH */
 | 
			
		||||
	case SIGQUIT:
 | 
			
		||||
		if (!signame)
 | 
			
		||||
			xasprintf(&signame, "SIGQUIT");
 | 
			
		||||
			signame = "SIGQUIT";
 | 
			
		||||
		/* Send the signal to our children too */
 | 
			
		||||
		if (service_pid > 0)
 | 
			
		||||
			kill(service_pid, sig);
 | 
			
		||||
		eerror("%s: caught %s, aborting", applet, signame);
 | 
			
		||||
		free(signame);
 | 
			
		||||
		exit(EXIT_FAILURE);
 | 
			
		||||
		/* NOTREACHED */
 | 
			
		||||
 | 
			
		||||
@@ -161,7 +161,7 @@ handle_signal(int sig)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
unhotplug()
 | 
			
		||||
unhotplug(void)
 | 
			
		||||
{
 | 
			
		||||
	char *file = NULL;
 | 
			
		||||
 | 
			
		||||
@@ -440,6 +440,7 @@ svc_exec(const char *arg1, const char *arg2)
 | 
			
		||||
			if (errno != EINTR) {
 | 
			
		||||
				eerror("%s: poll: %s",
 | 
			
		||||
				    service, strerror(errno));
 | 
			
		||||
				ret = -1;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
@@ -450,10 +451,21 @@ svc_exec(const char *arg1, const char *arg2)
 | 
			
		||||
				write_prefix(buffer, bytes, &prefixed);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			/* Only SIGCHLD signals come down this pipe */
 | 
			
		||||
			if (fd[0].revents & (POLLIN | POLLHUP))
 | 
			
		||||
			/* signal_pipe receives service_pid's exit status */
 | 
			
		||||
			if (fd[0].revents & (POLLIN | POLLHUP)) {
 | 
			
		||||
				if ((s = read(signal_pipe[0], &ret, sizeof(ret))) != sizeof(ret)) {
 | 
			
		||||
					eerror("%s: receive failed: %s", service,
 | 
			
		||||
						s < 0 ? strerror(errno) : "short read");
 | 
			
		||||
					ret = -1;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				ret = WEXITSTATUS(ret);
 | 
			
		||||
				if (ret != 0 && errno == ECHILD)
 | 
			
		||||
					/* killall5 -9 could cause this */
 | 
			
		||||
					ret = 0;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	free(buffer);
 | 
			
		||||
@@ -475,11 +487,6 @@ svc_exec(const char *arg1, const char *arg2)
 | 
			
		||||
		master_tty = -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret = rc_waitpid(service_pid);
 | 
			
		||||
	ret = WEXITSTATUS(ret);
 | 
			
		||||
	if (ret != 0 && errno == ECHILD)
 | 
			
		||||
		/* killall5 -9 could cause this */
 | 
			
		||||
		ret = 0;
 | 
			
		||||
	service_pid = 0;
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
@@ -614,7 +621,7 @@ svc_start_check(void)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (exclusive_fd == -1)
 | 
			
		||||
		exclusive_fd = svc_lock(applet);
 | 
			
		||||
		exclusive_fd = svc_lock(applet, !deps);
 | 
			
		||||
	if (exclusive_fd == -1) {
 | 
			
		||||
		if (errno == EACCES)
 | 
			
		||||
			eerrorx("%s: superuser access required", applet);
 | 
			
		||||
@@ -645,7 +652,7 @@ svc_start_deps(void)
 | 
			
		||||
	bool first;
 | 
			
		||||
	RC_STRING *svc, *svc2;
 | 
			
		||||
	RC_SERVICE state;
 | 
			
		||||
	int depoptions = RC_DEP_TRACE, n;
 | 
			
		||||
	int depoptions = RC_DEP_TRACE;
 | 
			
		||||
	size_t len;
 | 
			
		||||
	char *p, *tmp;
 | 
			
		||||
	pid_t pid;
 | 
			
		||||
@@ -755,7 +762,6 @@ svc_start_deps(void)
 | 
			
		||||
		rc_stringlist_free(use_services);
 | 
			
		||||
		use_services = NULL;
 | 
			
		||||
		len = 0;
 | 
			
		||||
		n = 0;
 | 
			
		||||
		TAILQ_FOREACH(svc, tmplist, entries) {
 | 
			
		||||
			rc_service_schedule_start(svc->value, service);
 | 
			
		||||
			use_services = rc_deptree_depend(deptree,
 | 
			
		||||
@@ -765,7 +771,6 @@ svc_start_deps(void)
 | 
			
		||||
			rc_stringlist_free(use_services);
 | 
			
		||||
			use_services = NULL;
 | 
			
		||||
			len += strlen(svc->value) + 2;
 | 
			
		||||
			n++;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		len += 5;
 | 
			
		||||
@@ -788,7 +793,7 @@ svc_start_deps(void)
 | 
			
		||||
	services = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void svc_start_real()
 | 
			
		||||
static void svc_start_real(void)
 | 
			
		||||
{
 | 
			
		||||
	bool started;
 | 
			
		||||
	RC_STRING *svc, *svc2;
 | 
			
		||||
@@ -868,7 +873,7 @@ svc_stop_check(RC_SERVICE *state)
 | 
			
		||||
		exit(EXIT_FAILURE);
 | 
			
		||||
 | 
			
		||||
	if (exclusive_fd == -1)
 | 
			
		||||
		exclusive_fd = svc_lock(applet);
 | 
			
		||||
		exclusive_fd = svc_lock(applet, !deps);
 | 
			
		||||
	if (exclusive_fd == -1) {
 | 
			
		||||
		if (errno == EACCES)
 | 
			
		||||
			eerrorx("%s: superuser access required", applet);
 | 
			
		||||
@@ -1045,26 +1050,6 @@ svc_stop(void)
 | 
			
		||||
static void
 | 
			
		||||
svc_restart(void)
 | 
			
		||||
{
 | 
			
		||||
	/* This is hairy and a better way needs to be found I think!
 | 
			
		||||
	 * The issue is this - openvpn need net and dns. net can restart
 | 
			
		||||
	 * dns via resolvconf, so you could have openvpn trying to restart
 | 
			
		||||
	 * dnsmasq which in turn is waiting on net which in turn is waiting
 | 
			
		||||
	 * on dnsmasq.
 | 
			
		||||
	 * The work around is for resolvconf to restart its services with
 | 
			
		||||
	 * --nodeps which means just that.
 | 
			
		||||
	 * The downside is that there is a small window when our status is
 | 
			
		||||
	 * invalid.
 | 
			
		||||
	 * One workaround would be to introduce a new status,
 | 
			
		||||
	 * or status locking. */
 | 
			
		||||
	if (!deps) {
 | 
			
		||||
		RC_SERVICE state = rc_service_state(service);
 | 
			
		||||
		if (state & RC_SERVICE_STARTED || state & RC_SERVICE_INACTIVE)
 | 
			
		||||
			svc_exec("stop", "start");
 | 
			
		||||
		else
 | 
			
		||||
			svc_exec("start", NULL);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!(rc_service_state(service) & RC_SERVICE_STOPPED)) {
 | 
			
		||||
		get_started_services();
 | 
			
		||||
		svc_stop();
 | 
			
		||||
@@ -1112,7 +1097,6 @@ service_plugable(void)
 | 
			
		||||
int main(int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
	bool doneone = false;
 | 
			
		||||
	bool runscript = false;
 | 
			
		||||
	int retval, opt, depoptions = RC_DEP_TRACE;
 | 
			
		||||
	RC_STRING *svc;
 | 
			
		||||
	char *path = NULL;
 | 
			
		||||
@@ -1130,8 +1114,6 @@ int main(int argc, char **argv)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	applet = basename_c(argv[0]);
 | 
			
		||||
	if (strcmp(applet, "runscript") == 0)
 | 
			
		||||
		runscript = true;
 | 
			
		||||
 | 
			
		||||
	if (stat(argv[1], &stbuf) != 0) {
 | 
			
		||||
		fprintf(stderr, "openrc-run `%s': %s\n",
 | 
			
		||||
@@ -1165,7 +1147,6 @@ int main(int argc, char **argv)
 | 
			
		||||
			dir = save;
 | 
			
		||||
		} else
 | 
			
		||||
			file = basename_c(argv[1]);
 | 
			
		||||
		ll = strlen(dir) + strlen(file) + 2;
 | 
			
		||||
		xasprintf(&service, "%s/%s", dir, file);
 | 
			
		||||
		if (stat(service, &stbuf) != 0) {
 | 
			
		||||
			free(service);
 | 
			
		||||
@@ -1305,9 +1286,6 @@ int main(int argc, char **argv)
 | 
			
		||||
	applet_list = rc_stringlist_new();
 | 
			
		||||
	rc_stringlist_add(applet_list, applet);
 | 
			
		||||
 | 
			
		||||
	if (runscript)
 | 
			
		||||
		ewarn("%s uses runscript, please convert to openrc-run.", service);
 | 
			
		||||
 | 
			
		||||
	/* Now run each option */
 | 
			
		||||
	retval = EXIT_SUCCESS;
 | 
			
		||||
	while (optind < argc) {
 | 
			
		||||
 
 | 
			
		||||
@@ -12,24 +12,23 @@
 | 
			
		||||
 * 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 <utmp.h>
 | 
			
		||||
#include <utmpx.h>
 | 
			
		||||
#include <pwd.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <paths.h>
 | 
			
		||||
#include <pwd.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <setjmp.h>
 | 
			
		||||
#include <paths.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <sys/sysmacros.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/utsname.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <utmpx.h>
 | 
			
		||||
 | 
			
		||||
#include "broadcast.h"
 | 
			
		||||
#include "helpers.h"
 | 
			
		||||
@@ -43,12 +42,7 @@ static sigjmp_buf jbuf;
 | 
			
		||||
/*
 | 
			
		||||
 *	Alarm handler
 | 
			
		||||
 */
 | 
			
		||||
/*ARGSUSED*/
 | 
			
		||||
# ifdef __GNUC__
 | 
			
		||||
static void handler(int arg __attribute__((unused)))
 | 
			
		||||
# else
 | 
			
		||||
static void handler(int arg)
 | 
			
		||||
# endif
 | 
			
		||||
RC_NORETURN static void handler(int arg RC_UNUSED)
 | 
			
		||||
{
 | 
			
		||||
	siglongjmp(jbuf, 1);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,7 @@
 | 
			
		||||
 *    except according to the terms contained in the LICENSE file.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <getopt.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
@@ -26,9 +27,11 @@
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <syslog.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/utsname.h>
 | 
			
		||||
#include <strings.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include <utmp.h>
 | 
			
		||||
 | 
			
		||||
#include "broadcast.h"
 | 
			
		||||
#include "einfo.h"
 | 
			
		||||
@@ -167,13 +170,13 @@ static void sleep_no_interrupt(int seconds)
 | 
			
		||||
		duration = remaining;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void stop_shutdown(int sig)
 | 
			
		||||
RC_NORETURN static void stop_shutdown(int sig)
 | 
			
		||||
{
 | 
			
		||||
	(void) sig;
 | 
			
		||||
	unlink(nologin_file);
 | 
			
		||||
	unlink(shutdown_pid);
 | 
			
		||||
einfo("Shutdown canceled");
 | 
			
		||||
exit(0);
 | 
			
		||||
	einfo("Shutdown cancelled");
 | 
			
		||||
	exit(0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main(int argc, char **argv)
 | 
			
		||||
@@ -304,7 +307,6 @@ int main(int argc, char **argv)
 | 
			
		||||
	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)
 | 
			
		||||
@@ -313,6 +315,7 @@ int main(int argc, char **argv)
 | 
			
		||||
			need_warning = (shutdown_delay % 15 == 0);
 | 
			
		||||
		else
 | 
			
		||||
			need_warning = true;
 | 
			
		||||
 | 
			
		||||
		if (shutdown_delay <= 5)
 | 
			
		||||
			create_nologin(shutdown_delay);
 | 
			
		||||
		if (need_warning) {
 | 
			
		||||
 
 | 
			
		||||
@@ -17,11 +17,10 @@
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include "einfo.h"
 | 
			
		||||
#include "sysvinit.h"
 | 
			
		||||
 
 | 
			
		||||
@@ -6,12 +6,3 @@ executable('openrc',
 | 
			
		||||
  include_directories: [incdir, einfo_incdir, rc_incdir],
 | 
			
		||||
  install: true,
 | 
			
		||||
  install_dir: sbindir)
 | 
			
		||||
 | 
			
		||||
executable('rc',
 | 
			
		||||
  ['rc.c', 'rc-logger.c', misc_c, plugin_c, usage_c, version_h],
 | 
			
		||||
  c_args : cc_branding_flags,
 | 
			
		||||
  link_with: [libeinfo, librc],
 | 
			
		||||
  dependencies: [dl_dep, util_dep],
 | 
			
		||||
  include_directories: [incdir, einfo_incdir, rc_incdir],
 | 
			
		||||
  install: true,
 | 
			
		||||
  install_dir: sbindir)
 | 
			
		||||
 
 | 
			
		||||
@@ -16,10 +16,7 @@
 | 
			
		||||
 *    except according to the terms contained in the LICENSE file.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/ioctl.h>
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <poll.h>
 | 
			
		||||
@@ -27,6 +24,9 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/ioctl.h>
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
#include <termios.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
@@ -42,9 +42,9 @@
 | 
			
		||||
 | 
			
		||||
#include "einfo.h"
 | 
			
		||||
#include "rc-logger.h"
 | 
			
		||||
#include "queue.h"
 | 
			
		||||
#include "rc.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
#include "helpers.h"
 | 
			
		||||
 | 
			
		||||
#define TMPLOG RC_SVCDIR "/rc.log"
 | 
			
		||||
#define DEFAULTLOG "/var/log/rc.log"
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,9 @@
 | 
			
		||||
#ifndef RC_LOGGER_H
 | 
			
		||||
#define RC_LOGGER_H
 | 
			
		||||
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 | 
			
		||||
extern pid_t rc_logger_pid;
 | 
			
		||||
extern int rc_logger_tty;
 | 
			
		||||
extern bool rc_in_logger;
 | 
			
		||||
 
 | 
			
		||||
@@ -20,26 +20,21 @@
 | 
			
		||||
 *    except according to the terms contained in the LICENSE file.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/ioctl.h>
 | 
			
		||||
#include <sys/param.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <sys/utsname.h>
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <dirent.h>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <getopt.h>
 | 
			
		||||
#include <libgen.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#include <pwd.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <strings.h>
 | 
			
		||||
#include <sys/ioctl.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/utsname.h>
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
#include <termios.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
@@ -49,9 +44,9 @@
 | 
			
		||||
#include "rc-logger.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
#include "plugin.h"
 | 
			
		||||
 | 
			
		||||
#include "version.h"
 | 
			
		||||
#include "_usage.h"
 | 
			
		||||
#include "helpers.h"
 | 
			
		||||
 | 
			
		||||
const char *extraopts = NULL;
 | 
			
		||||
const char getoptstring[] = "a:no:s:S" getoptstring_COMMON;
 | 
			
		||||
@@ -64,8 +59,7 @@ const struct option longopts[] = {
 | 
			
		||||
};
 | 
			
		||||
const char * const longopts_help[] = {
 | 
			
		||||
	"do not stop any services",
 | 
			
		||||
	"override the next runlevel to change into\n",
 | 
			
		||||
	"when leaving single user or boot runlevels",
 | 
			
		||||
	"override the next runlevel to change into\nwhen leaving single user or boot runlevels",
 | 
			
		||||
	"runs the service specified with the rest\nof the arguments",
 | 
			
		||||
	"output the RC system type, if any",
 | 
			
		||||
	longopts_help_COMMON
 | 
			
		||||
@@ -93,6 +87,7 @@ static RC_HOOK hook_out;
 | 
			
		||||
struct termios *termios_orig = NULL;
 | 
			
		||||
 | 
			
		||||
RC_PIDLIST service_pids;
 | 
			
		||||
RC_PIDLIST free_these_pids;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
clean_failed(void)
 | 
			
		||||
@@ -122,8 +117,7 @@ clean_failed(void)
 | 
			
		||||
static void
 | 
			
		||||
cleanup(void)
 | 
			
		||||
{
 | 
			
		||||
	RC_PID *p1 = LIST_FIRST(&service_pids);
 | 
			
		||||
	RC_PID *p2;
 | 
			
		||||
	RC_PID *p, *tmp;
 | 
			
		||||
 | 
			
		||||
	if (!rc_in_logger && !rc_in_plugin &&
 | 
			
		||||
	    applet && (strcmp(applet, "rc") == 0 || strcmp(applet, "openrc") == 0))
 | 
			
		||||
@@ -145,10 +139,13 @@ cleanup(void)
 | 
			
		||||
		rc_logger_close();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	while (p1) {
 | 
			
		||||
		p2 = LIST_NEXT(p1, entries);
 | 
			
		||||
		free(p1);
 | 
			
		||||
		p1 = p2;
 | 
			
		||||
	LIST_FOREACH_SAFE(p, &service_pids, entries, tmp) {
 | 
			
		||||
		LIST_REMOVE(p, entries);
 | 
			
		||||
		free(p);
 | 
			
		||||
	}
 | 
			
		||||
	LIST_FOREACH_SAFE(p, &free_these_pids, entries, tmp) {
 | 
			
		||||
		LIST_REMOVE(p, entries);
 | 
			
		||||
		free(p);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	rc_stringlist_free(main_hotplugged_services);
 | 
			
		||||
@@ -350,22 +347,46 @@ static char *get_krunlevel(void)
 | 
			
		||||
static void
 | 
			
		||||
add_pid(pid_t pid)
 | 
			
		||||
{
 | 
			
		||||
	sigset_t sset, old;
 | 
			
		||||
	RC_PID *p = xmalloc(sizeof(*p));
 | 
			
		||||
	p->pid = pid;
 | 
			
		||||
 | 
			
		||||
	/* this list will be accessed inside the SIGCHLD signal handler.
 | 
			
		||||
	 * so we need to ensure that the SIGCHLD handler doesn't get invoked
 | 
			
		||||
	 * while the list is at an inconsistent state.
 | 
			
		||||
	 */
 | 
			
		||||
	sigemptyset(&sset);
 | 
			
		||||
	sigaddset(&sset, SIGCHLD);
 | 
			
		||||
	sigprocmask(SIG_SETMASK, &sset, &old);
 | 
			
		||||
	LIST_INSERT_HEAD(&service_pids, p, entries);
 | 
			
		||||
	sigprocmask(SIG_SETMASK, &old, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
remove_pid(pid_t pid)
 | 
			
		||||
remove_pid(pid_t pid, bool inside_signal)
 | 
			
		||||
{
 | 
			
		||||
	RC_PID *p;
 | 
			
		||||
	sigset_t sset, old;
 | 
			
		||||
	RC_PID *p, *tmp;
 | 
			
		||||
 | 
			
		||||
	LIST_FOREACH(p, &service_pids, entries)
 | 
			
		||||
	/* same rationale for blocking SIGCHLD as add_pid() */
 | 
			
		||||
	sigemptyset(&sset);
 | 
			
		||||
	sigaddset(&sset, SIGCHLD);
 | 
			
		||||
	sigprocmask(SIG_SETMASK, &sset, &old);
 | 
			
		||||
	LIST_FOREACH(p, &service_pids, entries) {
 | 
			
		||||
		if (p->pid == pid) {
 | 
			
		||||
			LIST_REMOVE(p, entries);
 | 
			
		||||
		    free(p);
 | 
			
		||||
		    return;
 | 
			
		||||
			LIST_INSERT_HEAD(&free_these_pids, p, entries);
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	/* only call free if we're not inside a signal handler */
 | 
			
		||||
	if (!inside_signal) {
 | 
			
		||||
		LIST_FOREACH_SAFE(p, &free_these_pids, entries, tmp) {
 | 
			
		||||
			LIST_REMOVE(p, entries);
 | 
			
		||||
			free(p);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	sigprocmask(SIG_SETMASK, &old, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -383,7 +404,7 @@ static void
 | 
			
		||||
handle_signal(int sig)
 | 
			
		||||
{
 | 
			
		||||
	int serrno = errno;
 | 
			
		||||
	char *signame = NULL;
 | 
			
		||||
	const char *signame = NULL;
 | 
			
		||||
	pid_t pid;
 | 
			
		||||
	RC_PID *pi;
 | 
			
		||||
	int status = 0;
 | 
			
		||||
@@ -403,7 +424,7 @@ handle_signal(int sig)
 | 
			
		||||
 | 
			
		||||
		/* Remove that pid from our list */
 | 
			
		||||
		if (pid > 0)
 | 
			
		||||
			remove_pid(pid);
 | 
			
		||||
			remove_pid(pid, true);
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case SIGWINCH:
 | 
			
		||||
@@ -415,15 +436,15 @@ handle_signal(int sig)
 | 
			
		||||
 | 
			
		||||
	case SIGINT:
 | 
			
		||||
		if (!signame)
 | 
			
		||||
			xasprintf(&signame, "SIGINT");
 | 
			
		||||
			signame = "SIGINT";
 | 
			
		||||
		/* FALLTHROUGH */
 | 
			
		||||
	case SIGTERM:
 | 
			
		||||
		if (!signame)
 | 
			
		||||
			xasprintf(&signame, "SIGTERM");
 | 
			
		||||
			signame = "SIGTERM";
 | 
			
		||||
		/* FALLTHROUGH */
 | 
			
		||||
	case SIGQUIT:
 | 
			
		||||
		if (!signame)
 | 
			
		||||
			xasprintf(&signame, "SIGQUIT");
 | 
			
		||||
			signame = "SIGQUIT";
 | 
			
		||||
		eerrorx("%s: caught %s, aborting", applet, signame);
 | 
			
		||||
		/* NOTREACHED */
 | 
			
		||||
	case SIGUSR1:
 | 
			
		||||
@@ -453,7 +474,7 @@ handle_signal(int sig)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
do_sysinit()
 | 
			
		||||
do_sysinit(void)
 | 
			
		||||
{
 | 
			
		||||
	struct utsname uts;
 | 
			
		||||
	const char *sys;
 | 
			
		||||
@@ -506,8 +527,7 @@ runlevel_config(const char *service, const char *level)
 | 
			
		||||
	char *conf, *dir;
 | 
			
		||||
	bool retval;
 | 
			
		||||
 | 
			
		||||
	dir = dirname(init);
 | 
			
		||||
	dir = dirname(init);
 | 
			
		||||
	dir = dirname(dirname(init));
 | 
			
		||||
	xasprintf(&conf, "%s/conf.d/%s.%s", dir, service, level);
 | 
			
		||||
	retval = exists(conf);
 | 
			
		||||
	free(conf);
 | 
			
		||||
@@ -613,7 +633,7 @@ stop:
 | 
			
		||||
			add_pid(pid);
 | 
			
		||||
			if (!parallel) {
 | 
			
		||||
				rc_waitpid(pid);
 | 
			
		||||
				remove_pid(pid);
 | 
			
		||||
				remove_pid(pid, false);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -679,7 +699,7 @@ do_start_services(const RC_STRINGLIST *start_services, bool parallel)
 | 
			
		||||
			add_pid(pid);
 | 
			
		||||
			if (!parallel) {
 | 
			
		||||
				rc_waitpid(pid);
 | 
			
		||||
				remove_pid(pid);
 | 
			
		||||
				remove_pid(pid, false);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -697,7 +717,7 @@ do_start_services(const RC_STRINGLIST *start_services, bool parallel)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef RC_DEBUG
 | 
			
		||||
static void
 | 
			
		||||
RC_NORETURN static void
 | 
			
		||||
handle_bad_signal(int sig)
 | 
			
		||||
{
 | 
			
		||||
	char pid[10];
 | 
			
		||||
@@ -752,6 +772,7 @@ int main(int argc, char **argv)
 | 
			
		||||
 | 
			
		||||
	applet = basename_c(argv[0]);
 | 
			
		||||
	LIST_INIT(&service_pids);
 | 
			
		||||
	LIST_INIT(&free_these_pids);
 | 
			
		||||
	atexit(cleanup);
 | 
			
		||||
	if (!applet)
 | 
			
		||||
		eerrorx("arguments required");
 | 
			
		||||
@@ -816,8 +837,6 @@ int main(int argc, char **argv)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (strcmp(applet, "rc") == 0)
 | 
			
		||||
		ewarn("rc is deprecated, please use openrc instead.");
 | 
			
		||||
	newlevel = argv[optind++];
 | 
			
		||||
	/* To make life easier, we only have the shutdown runlevel as
 | 
			
		||||
	 * nothing really needs to know that we're rebooting.
 | 
			
		||||
 
 | 
			
		||||
@@ -10,20 +10,11 @@
 | 
			
		||||
 *    except according to the terms contained in the LICENSE file.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <syslog.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include "einfo.h"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -15,27 +15,20 @@
 | 
			
		||||
 *    except according to the terms contained in the LICENSE file.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <getopt.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <utime.h>
 | 
			
		||||
 | 
			
		||||
#include "einfo.h"
 | 
			
		||||
#include "queue.h"
 | 
			
		||||
#include "rc.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
#include "_usage.h"
 | 
			
		||||
#include "helpers.h"
 | 
			
		||||
 | 
			
		||||
const char *applet = NULL;
 | 
			
		||||
const char *extraopts = NULL;
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,9 @@
 | 
			
		||||
 *    except according to the terms contained in the LICENSE file.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <getopt.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
@@ -24,8 +26,8 @@
 | 
			
		||||
#include "einfo.h"
 | 
			
		||||
#include "queue.h"
 | 
			
		||||
#include "rc.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
#include "_usage.h"
 | 
			
		||||
#include "helpers.h"
 | 
			
		||||
 | 
			
		||||
const char *applet = NULL;
 | 
			
		||||
const char *extraopts = NULL;
 | 
			
		||||
 
 | 
			
		||||
@@ -16,17 +16,21 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <getopt.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <strings.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
 | 
			
		||||
#include "einfo.h"
 | 
			
		||||
#include "queue.h"
 | 
			
		||||
#include "rc.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
#include "_usage.h"
 | 
			
		||||
#include "helpers.h"
 | 
			
		||||
 | 
			
		||||
enum format_t {
 | 
			
		||||
	FORMAT_DEFAULT,
 | 
			
		||||
@@ -61,8 +65,8 @@ const char * const longopts_help[] = {
 | 
			
		||||
	longopts_help_COMMON
 | 
			
		||||
};
 | 
			
		||||
const char *usagestring = ""						\
 | 
			
		||||
	"Usage: rc-status [options] -f ini <runlevel>...\n"		\
 | 
			
		||||
	"   or: rc-status [options] [-a | -c | -l | -m | -r | -s | -u]";
 | 
			
		||||
	"Usage: rc-status [options] [-f ini] <runlevel>...\n"		\
 | 
			
		||||
	"   or: rc-status [options] [-f ini] [-a | -c | -l | -m | -r | -s | -u]";
 | 
			
		||||
 | 
			
		||||
static RC_DEPTREE *deptree;
 | 
			
		||||
static RC_STRINGLIST *types;
 | 
			
		||||
@@ -293,6 +297,7 @@ int main(int argc, char **argv)
 | 
			
		||||
			TAILQ_FOREACH(l, levels, entries)
 | 
			
		||||
				printf("%s\n", l->value);
 | 
			
		||||
			goto exit;
 | 
			
		||||
			/* NOTREACHED */
 | 
			
		||||
		case 'm':
 | 
			
		||||
			services = rc_services_in_runlevel(NULL);
 | 
			
		||||
			levels = rc_runlevel_list();
 | 
			
		||||
@@ -312,8 +317,9 @@ int main(int argc, char **argv)
 | 
			
		||||
					free(s->value);
 | 
			
		||||
					free(s);
 | 
			
		||||
				}
 | 
			
		||||
			print_services(NULL, services, FORMAT_DEFAULT);
 | 
			
		||||
			print_services(NULL, services, format);
 | 
			
		||||
			goto exit;
 | 
			
		||||
			/* NOTREACHED */
 | 
			
		||||
		case 'r':
 | 
			
		||||
			runlevel = rc_runlevel_get();
 | 
			
		||||
			printf("%s\n", runlevel);
 | 
			
		||||
@@ -324,12 +330,12 @@ int main(int argc, char **argv)
 | 
			
		||||
			TAILQ_FOREACH_SAFE(s, services, entries, t)
 | 
			
		||||
				if (!rc_service_value_get(s->value, "child_pid"))
 | 
			
		||||
					TAILQ_REMOVE(services, s, entries);
 | 
			
		||||
			print_services(NULL, services, FORMAT_DEFAULT);
 | 
			
		||||
			print_services(NULL, services, format);
 | 
			
		||||
			goto exit;
 | 
			
		||||
			/* NOTREACHED */
 | 
			
		||||
		case 's':
 | 
			
		||||
			services = rc_services_in_runlevel(NULL);
 | 
			
		||||
			print_services(NULL, services, FORMAT_DEFAULT);
 | 
			
		||||
			print_services(NULL, services, format);
 | 
			
		||||
			goto exit;
 | 
			
		||||
			/* NOTREACHED */
 | 
			
		||||
		case 'u':
 | 
			
		||||
@@ -344,7 +350,7 @@ int main(int argc, char **argv)
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
			}
 | 
			
		||||
			print_services(NULL, services, FORMAT_DEFAULT);
 | 
			
		||||
			print_services(NULL, services, format);
 | 
			
		||||
			goto exit;
 | 
			
		||||
			/* NOTREACHED */
 | 
			
		||||
 | 
			
		||||
@@ -444,6 +450,7 @@ int main(int argc, char **argv)
 | 
			
		||||
		 * be added to the list
 | 
			
		||||
		 */
 | 
			
		||||
		unsetenv("RC_SVCNAME");
 | 
			
		||||
 | 
			
		||||
		print_level("Dynamic", "needed/wanted", format);
 | 
			
		||||
		print_services(NULL, nservices, format);
 | 
			
		||||
		print_level("Dynamic", "manual", format);
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,6 @@
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <getopt.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
@@ -29,6 +28,7 @@
 | 
			
		||||
#include "rc.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
#include "_usage.h"
 | 
			
		||||
#include "helpers.h"
 | 
			
		||||
 | 
			
		||||
const char *applet = NULL;
 | 
			
		||||
const char *extraopts = NULL;
 | 
			
		||||
@@ -88,7 +88,7 @@ delete(const char *runlevel, const char *service)
 | 
			
		||||
 | 
			
		||||
	errno = 0;
 | 
			
		||||
	if (rc_service_delete(runlevel, service)) {
 | 
			
		||||
		einfo("service %s removed from runlevel %s",
 | 
			
		||||
		einfo("service %s deleted from runlevel %s",
 | 
			
		||||
		    service, runlevel);
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
@@ -97,7 +97,7 @@ delete(const char *runlevel, const char *service)
 | 
			
		||||
		eerror("%s: service `%s' is not in the runlevel `%s'",
 | 
			
		||||
		    applet, service, runlevel);
 | 
			
		||||
	else
 | 
			
		||||
		eerror("%s: failed to remove service `%s' from runlevel `%s': %s",
 | 
			
		||||
		eerror("%s: failed to delete service `%s' from runlevel `%s': %s",
 | 
			
		||||
		    applet, service, runlevel, strerror (errno));
 | 
			
		||||
 | 
			
		||||
	return retval;
 | 
			
		||||
@@ -144,7 +144,7 @@ static int
 | 
			
		||||
delstack(const char *runlevel, const char *stack)
 | 
			
		||||
{
 | 
			
		||||
	if (rc_runlevel_unstack(runlevel, stack)) {
 | 
			
		||||
		einfo("runlevel %s removed from runlevel %s", stack, runlevel);
 | 
			
		||||
		einfo("runlevel %s deleted from runlevel %s", stack, runlevel);
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -152,7 +152,7 @@ delstack(const char *runlevel, const char *stack)
 | 
			
		||||
		eerror("%s: runlevel `%s' is not in the runlevel `%s'",
 | 
			
		||||
		    applet, stack, runlevel);
 | 
			
		||||
	else
 | 
			
		||||
		eerror("%s: failed to remove runlevel `%s' from runlevel `%s': %s",
 | 
			
		||||
		eerror("%s: failed to delete runlevel `%s' from runlevel `%s': %s",
 | 
			
		||||
		    applet, stack, runlevel, strerror (errno));
 | 
			
		||||
 | 
			
		||||
	return -1;
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2022 The OpenRC Authors.
 | 
			
		||||
 * Copyright (c) 2022-2023 The OpenRC Authors.
 | 
			
		||||
 * See the Authors file at the top-level directory of this distribution and
 | 
			
		||||
 * https://github.com/OpenRC/openrc/blob/HEAD/AUTHORS
 | 
			
		||||
 *
 | 
			
		||||
@@ -30,12 +30,12 @@
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <endian.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#include "rc.h"
 | 
			
		||||
#include "einfo.h"
 | 
			
		||||
#include "helpers.h"
 | 
			
		||||
#include "_usage.h"
 | 
			
		||||
@@ -455,7 +455,7 @@ int main(int argc, char **argv)
 | 
			
		||||
	static const char seedrng_prefix[] = "SeedRNG v1 Old+New Prefix";
 | 
			
		||||
	static const char seedrng_failure[] = "SeedRNG v1 No New Seed Failure";
 | 
			
		||||
	int opt, fd, dfd, program_ret = 0;
 | 
			
		||||
	char *seed_dir = NULL;
 | 
			
		||||
	const char *seed_dir = NULL;
 | 
			
		||||
	uint8_t new_seed[MAX_SEED_LEN];
 | 
			
		||||
	size_t new_seed_len;
 | 
			
		||||
	bool new_seed_creditable;
 | 
			
		||||
@@ -470,7 +470,7 @@ int main(int argc, char **argv)
 | 
			
		||||
		switch (opt) {
 | 
			
		||||
		case LONGOPT_SEED_DIR:
 | 
			
		||||
			if (!seed_dir)
 | 
			
		||||
				seed_dir = xstrdup(optarg);
 | 
			
		||||
				seed_dir = optarg;
 | 
			
		||||
			break;
 | 
			
		||||
		case LONGOPT_SKIP_CREDIT:
 | 
			
		||||
			skip_credit = true;
 | 
			
		||||
@@ -479,7 +479,7 @@ int main(int argc, char **argv)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if (!seed_dir)
 | 
			
		||||
		seed_dir = xstrdup(DEFAULT_SEED_DIR);
 | 
			
		||||
		seed_dir = DEFAULT_SEED_DIR;
 | 
			
		||||
	if (getuid())
 | 
			
		||||
		eerrorx("%s: superuser access is required", applet);
 | 
			
		||||
	umask(0077);
 | 
			
		||||
 
 | 
			
		||||
@@ -10,24 +10,16 @@
 | 
			
		||||
 *    except according to the terms contained in the LICENSE file.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <syslog.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include "einfo.h"
 | 
			
		||||
#include "rc.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
#include "helpers.h"
 | 
			
		||||
 | 
			
		||||
const char *applet = NULL;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -13,19 +13,13 @@
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "rc.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
#include "_usage.h"
 | 
			
		||||
#include "version.h"
 | 
			
		||||
#include "helpers.h"
 | 
			
		||||
 | 
			
		||||
#if lint
 | 
			
		||||
#  define _noreturn
 | 
			
		||||
#endif
 | 
			
		||||
#if __GNUC__ > 2 || defined(__INTEL_COMPILER)
 | 
			
		||||
#  define _noreturn __attribute__ ((__noreturn__))
 | 
			
		||||
#else
 | 
			
		||||
#  define _noreturn
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void set_quiet_options(void)
 | 
			
		||||
{
 | 
			
		||||
@@ -42,7 +36,7 @@ void set_quiet_options(void)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
_noreturn void show_version(void)
 | 
			
		||||
RC_NORETURN void show_version(void)
 | 
			
		||||
{
 | 
			
		||||
	const char *systype = NULL;
 | 
			
		||||
 | 
			
		||||
@@ -57,7 +51,7 @@ _noreturn void show_version(void)
 | 
			
		||||
	exit(EXIT_SUCCESS);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
_noreturn void usage(int exit_status)
 | 
			
		||||
RC_NORETURN void usage(int exit_status)
 | 
			
		||||
{
 | 
			
		||||
	const char * const has_arg[] = { "", "<arg>", "[arg]" };
 | 
			
		||||
	int i;
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,7 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <getopt.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#define getoptstring_COMMON "ChqVv"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -18,29 +18,27 @@
 | 
			
		||||
#ifndef __HELPERS_H__
 | 
			
		||||
#define __HELPERS_H__
 | 
			
		||||
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
 | 
			
		||||
#define ERRX fprintf (stderr, "out of memory\n"); exit (1)
 | 
			
		||||
 | 
			
		||||
#define UNCONST(a)		((void *)(unsigned long)(const void *)(a))
 | 
			
		||||
#define UNCONST(a)		((void *)(uintptr_t)(const void *)(a))
 | 
			
		||||
 | 
			
		||||
#ifdef lint
 | 
			
		||||
# define _unused
 | 
			
		||||
#endif
 | 
			
		||||
#if __GNUC__ > 2 || defined(__INTEL_COMPILER)
 | 
			
		||||
# define _dead __attribute__((__noreturn__))
 | 
			
		||||
# define _unused __attribute__((__unused__))
 | 
			
		||||
# define _xasprintf(a, b)  __attribute__((__format__(__printf__, a, b)))
 | 
			
		||||
#else
 | 
			
		||||
# define _dead
 | 
			
		||||
# define _unused
 | 
			
		||||
# define _xasprintf(a, b)
 | 
			
		||||
#endif
 | 
			
		||||
#define RC_UNUSED __attribute__((__unused__))
 | 
			
		||||
#define RC_NORETURN __attribute__((__noreturn__))
 | 
			
		||||
#define RC_PRINTF(a, b)  __attribute__((__format__(__printf__, a, b)))
 | 
			
		||||
 | 
			
		||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
 | 
			
		||||
 | 
			
		||||
#ifdef __GLIBC__
 | 
			
		||||
#  if !defined (__UCLIBC__) && !defined (__dietlibc__)
 | 
			
		||||
#ifndef HAVE_STRLCPY
 | 
			
		||||
#    define strlcpy(dst, src, size) snprintf(dst, size, "%s", src)
 | 
			
		||||
#  endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef timespecsub
 | 
			
		||||
@@ -55,11 +53,7 @@
 | 
			
		||||
	} while (/* CONSTCOND */ 0)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
 | 
			
		||||
_unused static void *xmalloc (size_t size)
 | 
			
		||||
RC_UNUSED static void *xmalloc (size_t size)
 | 
			
		||||
{
 | 
			
		||||
	void *value = malloc(size);
 | 
			
		||||
 | 
			
		||||
@@ -70,7 +64,7 @@ _unused static void *xmalloc (size_t size)
 | 
			
		||||
	/* NOTREACHED */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
_unused static void *xrealloc(void *ptr, size_t size)
 | 
			
		||||
RC_UNUSED static void *xrealloc(void *ptr, size_t size)
 | 
			
		||||
{
 | 
			
		||||
	void *value = realloc(ptr, size);
 | 
			
		||||
 | 
			
		||||
@@ -81,7 +75,7 @@ _unused static void *xrealloc(void *ptr, size_t size)
 | 
			
		||||
	/* NOTREACHED */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
_unused static char *xstrdup(const char *str)
 | 
			
		||||
RC_UNUSED static char *xstrdup(const char *str)
 | 
			
		||||
{
 | 
			
		||||
	char *value;
 | 
			
		||||
 | 
			
		||||
@@ -103,7 +97,7 @@ _unused static char *xstrdup(const char *str)
 | 
			
		||||
 * basename_c never modifies the argument. As such, if there is a trailing
 | 
			
		||||
 * slash then an empty string is returned.
 | 
			
		||||
 */
 | 
			
		||||
_unused static const char *basename_c(const char *path)
 | 
			
		||||
RC_UNUSED static const char *basename_c(const char *path)
 | 
			
		||||
{
 | 
			
		||||
	const char *slash = strrchr(path, '/');
 | 
			
		||||
 | 
			
		||||
@@ -112,14 +106,14 @@ _unused static const char *basename_c(const char *path)
 | 
			
		||||
	return (path);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
_unused static bool exists(const char *pathname)
 | 
			
		||||
RC_UNUSED static bool exists(const char *pathname)
 | 
			
		||||
{
 | 
			
		||||
	struct stat buf;
 | 
			
		||||
 | 
			
		||||
	return (stat(pathname, &buf) == 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
_unused static bool existss(const char *pathname)
 | 
			
		||||
RC_UNUSED static bool existss(const char *pathname)
 | 
			
		||||
{
 | 
			
		||||
	struct stat buf;
 | 
			
		||||
 | 
			
		||||
@@ -129,12 +123,12 @@ _unused static bool existss(const char *pathname)
 | 
			
		||||
/*
 | 
			
		||||
 * 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
 | 
			
		||||
 * glibc systems and to ensure 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, ...)
 | 
			
		||||
RC_UNUSED RC_PRINTF(2,3) static int xasprintf(char **strp, const char *fmt, ...)
 | 
			
		||||
{
 | 
			
		||||
	va_list ap;
 | 
			
		||||
	int len;
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,10 @@ schedules_c = files([
 | 
			
		||||
  'schedules.c',
 | 
			
		||||
  ])
 | 
			
		||||
 | 
			
		||||
pipes_c = files([
 | 
			
		||||
	'pipes.c',
 | 
			
		||||
	])
 | 
			
		||||
 | 
			
		||||
if selinux_dep.found()
 | 
			
		||||
  selinux_c = files([
 | 
			
		||||
    'selinux.c',
 | 
			
		||||
 
 | 
			
		||||
@@ -15,22 +15,30 @@
 | 
			
		||||
 *    except according to the terms contained in the LICENSE file.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/file.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/utsname.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
#  include <sys/sysinfo.h>
 | 
			
		||||
#ifdef HAVE_CLOSE_RANGE
 | 
			
		||||
/* For close_range() */
 | 
			
		||||
# define _GNU_SOURCE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#ifdef HAVE_LINUX_CLOSE_RANGE_H
 | 
			
		||||
#  include <linux/close_range.h>
 | 
			
		||||
#endif
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <sys/file.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
#  include <sys/syscall.h> /* for close_range */
 | 
			
		||||
#  include <sys/sysinfo.h>
 | 
			
		||||
#endif
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/utsname.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <utime.h>
 | 
			
		||||
@@ -40,6 +48,7 @@
 | 
			
		||||
#include "rc.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
#include "version.h"
 | 
			
		||||
#include "helpers.h"
 | 
			
		||||
 | 
			
		||||
extern char **environ;
 | 
			
		||||
 | 
			
		||||
@@ -234,7 +243,7 @@ signal_setup_restart(int sig, void (*handler)(int))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
svc_lock(const char *applet)
 | 
			
		||||
svc_lock(const char *applet, bool ignore_lock_failure)
 | 
			
		||||
{
 | 
			
		||||
	char *file = NULL;
 | 
			
		||||
	int fd;
 | 
			
		||||
@@ -245,6 +254,14 @@ svc_lock(const char *applet)
 | 
			
		||||
	if (fd == -1)
 | 
			
		||||
		return -1;
 | 
			
		||||
	if (flock(fd, LOCK_EX | LOCK_NB) == -1) {
 | 
			
		||||
		if (ignore_lock_failure) {
 | 
			
		||||
			/* Two services with a need b, and b's start()
 | 
			
		||||
			 * calling restart --no-deps on a would cause
 | 
			
		||||
			 * harmless errors: just ignore them.
 | 
			
		||||
			 * See https://github.com/OpenRC/openrc/issues/224
 | 
			
		||||
			 */
 | 
			
		||||
			exit(EXIT_SUCCESS);
 | 
			
		||||
		}
 | 
			
		||||
		eerror("Call to flock failed: %s", strerror(errno));
 | 
			
		||||
		close(fd);
 | 
			
		||||
		return -1;
 | 
			
		||||
@@ -274,7 +291,7 @@ exec_service(const char *service, const char *arg)
 | 
			
		||||
	sigset_t old;
 | 
			
		||||
	struct sigaction sa;
 | 
			
		||||
 | 
			
		||||
	fd = svc_lock(basename_c(service));
 | 
			
		||||
	fd = svc_lock(basename_c(service), false);
 | 
			
		||||
	if (fd == -1)
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
@@ -492,3 +509,30 @@ pid_t get_pid(const char *applet,const char *pidfile)
 | 
			
		||||
 | 
			
		||||
	return pid;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifndef HAVE_CLOSE_RANGE
 | 
			
		||||
static inline int close_range(int first RC_UNUSED,
 | 
			
		||||
			      int last RC_UNUSED,
 | 
			
		||||
			      unsigned int flags RC_UNUSED)
 | 
			
		||||
{
 | 
			
		||||
#ifdef SYS_close_range
 | 
			
		||||
	return syscall(SYS_close_range, first, last, flags);
 | 
			
		||||
#else
 | 
			
		||||
	errno = ENOSYS;
 | 
			
		||||
	return -1;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef CLOSE_RANGE_CLOEXEC
 | 
			
		||||
# define CLOSE_RANGE_CLOEXEC	(1U << 2)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
cloexec_fds_from(int first)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
	if (close_range(first, UINT_MAX, CLOSE_RANGE_CLOEXEC) < 0) {
 | 
			
		||||
		for (i = getdtablesize() - 1; i >= first; --i)
 | 
			
		||||
			fcntl(i, F_SETFD, FD_CLOEXEC);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,7 @@
 | 
			
		||||
#define __RC_MISC_H__
 | 
			
		||||
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
@@ -27,6 +28,7 @@
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include "helpers.h"
 | 
			
		||||
#include "rc.h"
 | 
			
		||||
 | 
			
		||||
#define RC_LEVEL_BOOT           "boot"
 | 
			
		||||
#define RC_LEVEL_DEFAULT        "default"
 | 
			
		||||
@@ -48,7 +50,7 @@ void env_filter(void);
 | 
			
		||||
void env_config(void);
 | 
			
		||||
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 *, bool);
 | 
			
		||||
int svc_unlock(const char *, int);
 | 
			
		||||
pid_t exec_service(const char *, const char *);
 | 
			
		||||
 | 
			
		||||
@@ -71,4 +73,6 @@ void from_time_t(char *time_string, time_t tv);
 | 
			
		||||
time_t to_time_t(char *timestring);
 | 
			
		||||
pid_t get_pid(const char *applet, const char *pidfile);
 | 
			
		||||
 | 
			
		||||
void cloexec_fds_from(int);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -16,8 +16,8 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include "pipes.h"
 | 
			
		||||
 | 
			
		||||
@@ -17,12 +17,10 @@
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
 | 
			
		||||
#include <dirent.h>
 | 
			
		||||
#include <dlfcn.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
@@ -32,8 +30,8 @@
 | 
			
		||||
#include "einfo.h"
 | 
			
		||||
#include "queue.h"
 | 
			
		||||
#include "rc.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
#include "plugin.h"
 | 
			
		||||
#include "helpers.h"
 | 
			
		||||
 | 
			
		||||
#define RC_PLUGIN_HOOK "rc_plugin_hook"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,11 @@
 | 
			
		||||
#ifndef __LIBRC_PLUGIN_H__
 | 
			
		||||
#define __LIBRC_PLUGIN_H__
 | 
			
		||||
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 | 
			
		||||
#include "rc.h"
 | 
			
		||||
 | 
			
		||||
/* A simple flag to say if we're in a plugin process or not.
 | 
			
		||||
 * Mainly used in atexit code. */
 | 
			
		||||
extern bool rc_in_plugin;
 | 
			
		||||
 
 | 
			
		||||
@@ -30,16 +30,11 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <syslog.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
 | 
			
		||||
#include "einfo.h"
 | 
			
		||||
#include "queue.h"
 | 
			
		||||
#include "rc.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
#include "schedules.h"
 | 
			
		||||
#include "helpers.h"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,9 @@
 | 
			
		||||
#ifndef __RC_SCHEDULES_H
 | 
			
		||||
#define __RC_SCHEDULES_H
 | 
			
		||||
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 | 
			
		||||
void free_schedulelist(void);
 | 
			
		||||
int parse_signal(const char *applet, const char *sig);
 | 
			
		||||
void parse_schedule(const char *applet, const char *string, int timeout);
 | 
			
		||||
 
 | 
			
		||||
@@ -15,14 +15,12 @@
 | 
			
		||||
 *    except according to the terms contained in the LICENSE file.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/utsname.h>
 | 
			
		||||
#include <utmp.h>
 | 
			
		||||
 | 
			
		||||
#include "wtmp.h"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,7 @@
 | 
			
		||||
#define __RC_WTMP_H__
 | 
			
		||||
 | 
			
		||||
#include <utmp.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 | 
			
		||||
void log_wtmp(const char *user, const char *id, pid_t pid, int type,
 | 
			
		||||
		const char *line);
 | 
			
		||||
 
 | 
			
		||||
@@ -10,14 +10,9 @@
 | 
			
		||||
 *    except according to the terms contained in the LICENSE file.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
int main(int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
executable('start-stop-daemon',
 | 
			
		||||
  ['start-stop-daemon.c', 'pipes.c', misc_c, schedules_c,
 | 
			
		||||
  ['start-stop-daemon.c', pipes_c, misc_c, schedules_c,
 | 
			
		||||
	selinux_c, usage_c, version_h],
 | 
			
		||||
  c_args : [cc_audit_flags, cc_branding_flags, cc_pam_flags, cc_cap_flags, cc_selinux_flags],
 | 
			
		||||
  link_with: [libeinfo, librc],
 | 
			
		||||
 
 | 
			
		||||
@@ -26,47 +26,44 @@
 | 
			
		||||
# define _GNU_SOURCE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/ioctl.h>
 | 
			
		||||
#include <sys/resource.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <termios.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
#include <sys/syscall.h> /* For io priority */
 | 
			
		||||
#include <sys/prctl.h> /* For prctl */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <getopt.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#include <grp.h>
 | 
			
		||||
#include <pwd.h>
 | 
			
		||||
#include <sched.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <sys/ioctl.h>
 | 
			
		||||
#include <sys/resource.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
# include <sys/syscall.h> /* For io priority */
 | 
			
		||||
# include <sys/prctl.h> /* For prctl */
 | 
			
		||||
#endif
 | 
			
		||||
#include <termios.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_PAM
 | 
			
		||||
#include <security/pam_appl.h>
 | 
			
		||||
# include <security/pam_appl.h>
 | 
			
		||||
 | 
			
		||||
/* We are not supporting authentication conversations */
 | 
			
		||||
static struct pam_conv conv = { NULL, NULL};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CAP
 | 
			
		||||
#include <sys/capability.h>
 | 
			
		||||
# include <sys/capability.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <sched.h>
 | 
			
		||||
 | 
			
		||||
#include "einfo.h"
 | 
			
		||||
#include "queue.h"
 | 
			
		||||
#include "rc.h"
 | 
			
		||||
@@ -182,9 +179,9 @@ extern char **environ;
 | 
			
		||||
# define SYS_ioprio_set __NR_ioprio_set
 | 
			
		||||
#endif
 | 
			
		||||
#if !defined(__DragonFly__)
 | 
			
		||||
static inline int ioprio_set(int which _unused,
 | 
			
		||||
			     int who _unused,
 | 
			
		||||
			     int ioprio _unused)
 | 
			
		||||
static inline int ioprio_set(int which RC_UNUSED,
 | 
			
		||||
			     int who RC_UNUSED,
 | 
			
		||||
			     int ioprio RC_UNUSED)
 | 
			
		||||
{
 | 
			
		||||
#ifdef SYS_ioprio_set
 | 
			
		||||
	return syscall(SYS_ioprio_set, which, who, ioprio);
 | 
			
		||||
@@ -207,20 +204,20 @@ handle_signal(int sig)
 | 
			
		||||
{
 | 
			
		||||
	int status;
 | 
			
		||||
	int serrno = errno;
 | 
			
		||||
	char *signame = NULL;
 | 
			
		||||
	const char *signame = NULL;
 | 
			
		||||
 | 
			
		||||
	switch (sig) {
 | 
			
		||||
	case SIGINT:
 | 
			
		||||
		if (!signame)
 | 
			
		||||
			xasprintf(&signame, "SIGINT");
 | 
			
		||||
			signame = "SIGINT";
 | 
			
		||||
		/* FALLTHROUGH */
 | 
			
		||||
	case SIGTERM:
 | 
			
		||||
		if (!signame)
 | 
			
		||||
			xasprintf(&signame, "SIGTERM");
 | 
			
		||||
			signame = "SIGTERM";
 | 
			
		||||
		/* FALLTHROUGH */
 | 
			
		||||
	case SIGQUIT:
 | 
			
		||||
		if (!signame)
 | 
			
		||||
			xasprintf(&signame, "SIGQUIT");
 | 
			
		||||
			signame = "SIGQUIT";
 | 
			
		||||
		eerrorx("%s: caught %s, aborting", applet, signame);
 | 
			
		||||
		/* NOTREACHED */
 | 
			
		||||
 | 
			
		||||
@@ -239,9 +236,6 @@ handle_signal(int sig)
 | 
			
		||||
		eerror("%s: caught unknown signal %d", applet, sig);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* free signame */
 | 
			
		||||
	free(signame);
 | 
			
		||||
 | 
			
		||||
	/* Restore errno */
 | 
			
		||||
	errno = serrno;
 | 
			
		||||
}
 | 
			
		||||
@@ -354,6 +348,9 @@ int main(int argc, char **argv)
 | 
			
		||||
#ifdef PR_SET_NO_NEW_PRIVS
 | 
			
		||||
	bool no_new_privs = false;
 | 
			
		||||
#endif
 | 
			
		||||
	int pipefd[2];
 | 
			
		||||
	char readbuf[1];
 | 
			
		||||
	ssize_t ss;
 | 
			
		||||
 | 
			
		||||
	applet = basename_c(argv[0]);
 | 
			
		||||
	atexit(cleanup);
 | 
			
		||||
@@ -864,12 +861,17 @@ int main(int argc, char **argv)
 | 
			
		||||
	if (background)
 | 
			
		||||
		signal_setup(SIGCHLD, handle_signal);
 | 
			
		||||
 | 
			
		||||
	/* Use a pipe to sync the parent/child processes. */
 | 
			
		||||
	if (pipe2(pipefd, O_CLOEXEC) == -1)
 | 
			
		||||
		eerrorx("%s: pipe2: %s", applet, strerror(errno));
 | 
			
		||||
 | 
			
		||||
	if ((pid = fork()) == -1)
 | 
			
		||||
		eerrorx("%s: fork: %s", applet, strerror(errno));
 | 
			
		||||
 | 
			
		||||
	/* Child process - lets go! */
 | 
			
		||||
	if (pid == 0) {
 | 
			
		||||
		pid_t mypid = getpid();
 | 
			
		||||
		close(pipefd[0]); /* Close the read end of the pipe. */
 | 
			
		||||
		umask(numask);
 | 
			
		||||
 | 
			
		||||
#ifdef TIOCNOTTY
 | 
			
		||||
@@ -878,11 +880,23 @@ int main(int argc, char **argv)
 | 
			
		||||
 | 
			
		||||
		devnull_fd = open("/dev/null", O_RDWR);
 | 
			
		||||
 | 
			
		||||
		/* Must call setsid() before setting autogroup nicelevel
 | 
			
		||||
		 * but after opening tty_fd. */
 | 
			
		||||
		setsid();
 | 
			
		||||
 | 
			
		||||
		if (nicelevel != INT_MIN) {
 | 
			
		||||
			if (setpriority(PRIO_PROCESS, mypid, nicelevel) == -1)
 | 
			
		||||
				eerrorx("%s: setpriority %d: %s",
 | 
			
		||||
				    applet, nicelevel,
 | 
			
		||||
				    strerror(errno));
 | 
			
		||||
			/* Open in "r+" mode to avoid creating if non-existent. */
 | 
			
		||||
			fp = fopen("/proc/self/autogroup", "r+");
 | 
			
		||||
			if (fp) {
 | 
			
		||||
				fprintf(fp, "%d\n", nicelevel);
 | 
			
		||||
				fclose(fp);
 | 
			
		||||
			} else if (errno != ENOENT)
 | 
			
		||||
				eerrorx("%s: autogroup nice %d: %s", applet,
 | 
			
		||||
				    nicelevel, strerror(errno));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (ionicec != -1 &&
 | 
			
		||||
@@ -1084,8 +1098,7 @@ int main(int argc, char **argv)
 | 
			
		||||
				|| rc_yesno(getenv("EINFO_QUIET")))
 | 
			
		||||
			dup2(stderr_fd, STDERR_FILENO);
 | 
			
		||||
 | 
			
		||||
		for (i = getdtablesize() - 1; i >= 3; --i)
 | 
			
		||||
			close(i);
 | 
			
		||||
		cloexec_fds_from(3);
 | 
			
		||||
 | 
			
		||||
		if (scheduler != NULL) {
 | 
			
		||||
			int scheduler_index;
 | 
			
		||||
@@ -1118,7 +1131,6 @@ int main(int argc, char **argv)
 | 
			
		||||
				eerrorx("Failed to set scheduler parameters: %s", strerror(errno));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		setsid();
 | 
			
		||||
		execvp(exec, argv);
 | 
			
		||||
#ifdef HAVE_PAM
 | 
			
		||||
		if (changeuser != NULL && pamr == PAM_SUCCESS)
 | 
			
		||||
@@ -1129,6 +1141,18 @@ int main(int argc, char **argv)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Parent process */
 | 
			
		||||
 | 
			
		||||
	close(pipefd[1]); /* Close the write end of the pipe. */
 | 
			
		||||
 | 
			
		||||
	/* The child never writes to the pipe, so this read will block until
 | 
			
		||||
	 * the child calls exec or exits. */
 | 
			
		||||
	while ((ss = read(pipefd[0], readbuf, 1)) == -1 && errno == EINTR);
 | 
			
		||||
	if (ss == -1)
 | 
			
		||||
		eerrorx("%s: failed to read from pipe: %s",
 | 
			
		||||
			applet, strerror(errno));
 | 
			
		||||
 | 
			
		||||
	close(pipefd[0]);
 | 
			
		||||
 | 
			
		||||
	if (!background) {
 | 
			
		||||
		/* As we're not backgrounding the process, wait for our pid
 | 
			
		||||
		 * to return */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
executable('supervise-daemon',
 | 
			
		||||
  ['supervise-daemon.c', misc_c, plugin_c, schedules_c, usage_c, version_h],
 | 
			
		||||
  ['supervise-daemon.c', pipes_c, misc_c, plugin_c, schedules_c, usage_c, version_h],
 | 
			
		||||
  c_args : [cc_branding_flags, cc_pam_flags, cc_cap_flags, cc_selinux_flags],
 | 
			
		||||
  link_with: [libeinfo, librc],
 | 
			
		||||
  dependencies: [dl_dep, pam_dep, cap_dep, util_dep, selinux_dep],
 | 
			
		||||
 
 | 
			
		||||
@@ -22,20 +22,6 @@
 | 
			
		||||
#define ONE_SECOND    1000000000
 | 
			
		||||
#define ONE_MS           1000000
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/ioctl.h>
 | 
			
		||||
#include <sys/resource.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <termios.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
#include <sys/syscall.h> /* For io priority */
 | 
			
		||||
#include <sys/prctl.h> /* For prctl */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <getopt.h>
 | 
			
		||||
@@ -47,7 +33,17 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <strings.h>
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
# include <sys/syscall.h> /* For io priority */
 | 
			
		||||
# include <sys/prctl.h> /* For prctl */
 | 
			
		||||
#endif
 | 
			
		||||
#include <syslog.h>
 | 
			
		||||
#include <sys/ioctl.h>
 | 
			
		||||
#include <sys/resource.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
@@ -66,6 +62,7 @@ static struct pam_conv conv = { NULL, NULL};
 | 
			
		||||
#include "queue.h"
 | 
			
		||||
#include "rc.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
#include "pipes.h"
 | 
			
		||||
#include "plugin.h"
 | 
			
		||||
#include "schedules.h"
 | 
			
		||||
#include "_usage.h"
 | 
			
		||||
@@ -83,6 +80,8 @@ enum {
 | 
			
		||||
  LONGOPT_OOM_SCORE_ADJ,
 | 
			
		||||
  LONGOPT_NO_NEW_PRIVS,
 | 
			
		||||
  LONGOPT_SECBITS,
 | 
			
		||||
  LONGOPT_STDERR_LOGGER,
 | 
			
		||||
  LONGOPT_STDOUT_LOGGER,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const char *applet = NULL;
 | 
			
		||||
@@ -114,6 +113,8 @@ const struct option longopts[] = {
 | 
			
		||||
	{ "user",         1, NULL, 'u'},
 | 
			
		||||
	{ "stdout",       1, NULL, '1'},
 | 
			
		||||
	{ "stderr",       1, NULL, '2'},
 | 
			
		||||
	{ "stdout-logger",1, NULL, LONGOPT_STDOUT_LOGGER},
 | 
			
		||||
	{ "stderr-logger",1, NULL, LONGOPT_STDERR_LOGGER},
 | 
			
		||||
	{ "reexec",       0, NULL, '3'},
 | 
			
		||||
	longopts_COMMON
 | 
			
		||||
};
 | 
			
		||||
@@ -142,6 +143,8 @@ const char * const longopts_help[] = {
 | 
			
		||||
	"Change the process user",
 | 
			
		||||
	"Redirect stdout to file",
 | 
			
		||||
	"Redirect stderr to file",
 | 
			
		||||
	"Redirect stdout to process",
 | 
			
		||||
	"Redirect stderr to process",
 | 
			
		||||
	"reexec (used internally)",
 | 
			
		||||
	longopts_help_COMMON
 | 
			
		||||
};
 | 
			
		||||
@@ -164,6 +167,8 @@ static int stdout_fd;
 | 
			
		||||
static int stderr_fd;
 | 
			
		||||
static char *redirect_stderr = NULL;
 | 
			
		||||
static char *redirect_stdout = NULL;
 | 
			
		||||
static char *stderr_process = NULL;
 | 
			
		||||
static char *stdout_process = NULL;
 | 
			
		||||
#ifdef TIOCNOTTY
 | 
			
		||||
static int tty_fd = -1;
 | 
			
		||||
#endif
 | 
			
		||||
@@ -191,8 +196,8 @@ extern char **environ;
 | 
			
		||||
# define SYS_ioprio_set __NR_ioprio_set
 | 
			
		||||
#endif
 | 
			
		||||
#if !defined(__DragonFly__)
 | 
			
		||||
static inline int ioprio_set(int which _unused, int who _unused,
 | 
			
		||||
			     int ioprio _unused)
 | 
			
		||||
static inline int ioprio_set(int which RC_UNUSED, int who RC_UNUSED,
 | 
			
		||||
			     int ioprio RC_UNUSED)
 | 
			
		||||
{
 | 
			
		||||
#ifdef SYS_ioprio_set
 | 
			
		||||
	return syscall(SYS_ioprio_set, which, who, ioprio);
 | 
			
		||||
@@ -207,7 +212,7 @@ static void cleanup(void)
 | 
			
		||||
	free(changeuser);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void re_exec_supervisor(void)
 | 
			
		||||
RC_NORETURN static void re_exec_supervisor(void)
 | 
			
		||||
{
 | 
			
		||||
	syslog(LOG_WARNING, "Re-executing for %s", svcname);
 | 
			
		||||
	execlp("supervise-daemon", "supervise-daemon", svcname, "--reexec",
 | 
			
		||||
@@ -353,7 +358,7 @@ static pid_t exec_command(const char *cmd)
 | 
			
		||||
	return pid;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void child_process(char *exec, char **argv)
 | 
			
		||||
RC_NORETURN static void child_process(char *exec, char **argv)
 | 
			
		||||
{
 | 
			
		||||
	RC_STRINGLIST *env_list;
 | 
			
		||||
	RC_STRING *env;
 | 
			
		||||
@@ -391,6 +396,14 @@ static void child_process(char *exec, char **argv)
 | 
			
		||||
		if (setpriority(PRIO_PROCESS, getpid(), nicelevel) == -1)
 | 
			
		||||
			eerrorx("%s: setpriority %d: %s", applet, nicelevel,
 | 
			
		||||
					strerror(errno));
 | 
			
		||||
		/* Open in "r+" mode to avoid creating if non-existent. */
 | 
			
		||||
		fp = fopen("/proc/self/autogroup", "r+");
 | 
			
		||||
		if (fp) {
 | 
			
		||||
			fprintf(fp, "%d\n", nicelevel);
 | 
			
		||||
			fclose(fp);
 | 
			
		||||
		} else if (errno != ENOENT)
 | 
			
		||||
			eerrorx("%s: autogroup nice %d: %s", applet,
 | 
			
		||||
			    nicelevel, strerror(errno));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (ionicec != -1 && ioprio_set(1, getpid(), ionicec | ioniced) == -1)
 | 
			
		||||
@@ -545,6 +558,12 @@ static void child_process(char *exec, char **argv)
 | 
			
		||||
			eerrorx("%s: unable to open the logfile"
 | 
			
		||||
				    " for stdout `%s': %s",
 | 
			
		||||
				    applet, redirect_stdout, strerror(errno));
 | 
			
		||||
	} else if (stdout_process) {
 | 
			
		||||
		stdout_fd = rc_pipe_command(stdout_process);
 | 
			
		||||
		if (stdout_fd == -1)
 | 
			
		||||
			eerrorx("%s: unable to open the logging process"
 | 
			
		||||
			    " for stdout `%s': %s",
 | 
			
		||||
			    applet, stdout_process, strerror(errno));
 | 
			
		||||
	}
 | 
			
		||||
	if (redirect_stderr) {
 | 
			
		||||
		if ((stderr_fd = open(redirect_stderr,
 | 
			
		||||
@@ -553,16 +572,22 @@ static void child_process(char *exec, char **argv)
 | 
			
		||||
			eerrorx("%s: unable to open the logfile"
 | 
			
		||||
			    " for stderr `%s': %s",
 | 
			
		||||
			    applet, redirect_stderr, strerror(errno));
 | 
			
		||||
	} else if (stderr_process) {
 | 
			
		||||
		stderr_fd = rc_pipe_command(stderr_process);
 | 
			
		||||
		if (stderr_fd == -1)
 | 
			
		||||
			eerrorx("%s: unable to open the logging process"
 | 
			
		||||
			    " for stderr `%s': %s",
 | 
			
		||||
			    applet, stderr_process, strerror(errno));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dup2(stdin_fd, STDIN_FILENO);
 | 
			
		||||
	if (redirect_stdout || rc_yesno(getenv("EINFO_QUIET")))
 | 
			
		||||
	if (redirect_stdout || stdout_process || rc_yesno(getenv("EINFO_QUIET")))
 | 
			
		||||
		dup2(stdout_fd, STDOUT_FILENO);
 | 
			
		||||
	if (redirect_stderr || rc_yesno(getenv("EINFO_QUIET")))
 | 
			
		||||
	if (redirect_stderr || stderr_process || rc_yesno(getenv("EINFO_QUIET")))
 | 
			
		||||
		dup2(stderr_fd, STDERR_FILENO);
 | 
			
		||||
 | 
			
		||||
	for (i = getdtablesize() - 1; i >= 3; --i)
 | 
			
		||||
		fcntl(i, F_SETFD, FD_CLOEXEC);
 | 
			
		||||
	cloexec_fds_from(3);
 | 
			
		||||
 | 
			
		||||
	cmdline = make_cmdline(argv);
 | 
			
		||||
	syslog(LOG_INFO, "Child command line: %s", cmdline);
 | 
			
		||||
	free(cmdline);
 | 
			
		||||
@@ -575,7 +600,7 @@ static void child_process(char *exec, char **argv)
 | 
			
		||||
	eerrorx("%s: failed to exec `%s': %s", applet, exec,strerror(errno));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void supervisor(char *exec, char **argv)
 | 
			
		||||
RC_NORETURN static void supervisor(char *exec, char **argv)
 | 
			
		||||
{
 | 
			
		||||
	FILE *fp;
 | 
			
		||||
	char buf[2048];
 | 
			
		||||
@@ -1035,6 +1060,14 @@ int main(int argc, char **argv)
 | 
			
		||||
			reexec = true;
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case LONGOPT_STDOUT_LOGGER:   /* --stdout-logger "command to run for stdout logging" */
 | 
			
		||||
			stdout_process = optarg;
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case LONGOPT_STDERR_LOGGER:  /* --stderr-logger "command to run for stderr logging" */
 | 
			
		||||
			stderr_process = optarg;
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case_RC_COMMON_GETOPT
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -19,22 +19,18 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <getopt.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <utime.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "einfo.h"
 | 
			
		||||
#include "rc.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
#include "_usage.h"
 | 
			
		||||
#include "helpers.h"
 | 
			
		||||
 | 
			
		||||
#define RC_SHUTDOWNTIME    RC_SVCDIR "/shutdowntime"
 | 
			
		||||
 | 
			
		||||
const char *applet = NULL;
 | 
			
		||||
const char *extraopts = "file";
 | 
			
		||||
@@ -54,7 +50,7 @@ const char *usagestring = NULL;
 | 
			
		||||
int main(int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
	int opt, sflag = 0, wflag = 0;
 | 
			
		||||
	const char *file = RC_SHUTDOWNTIME;
 | 
			
		||||
	const char *file = NULL;
 | 
			
		||||
	struct stat sb;
 | 
			
		||||
	struct timeval tv;
 | 
			
		||||
 | 
			
		||||
@@ -75,16 +71,16 @@ int main(int argc, char **argv)
 | 
			
		||||
 | 
			
		||||
	if (optind < argc)
 | 
			
		||||
		file = argv[optind++];
 | 
			
		||||
	else
 | 
			
		||||
		eerrorx("swclock: Reference file was not specified");
 | 
			
		||||
 | 
			
		||||
	if (sflag) {
 | 
			
		||||
		if (stat(file, &sb) == -1) {
 | 
			
		||||
			opt = open(file, O_WRONLY | O_CREAT, 0644);
 | 
			
		||||
			if (opt == -1)
 | 
			
		||||
		int fd = open(file, O_WRONLY | O_CREAT, 0644);
 | 
			
		||||
		if (fd == -1)
 | 
			
		||||
			eerrorx("swclock: open: %s", strerror(errno));
 | 
			
		||||
			close(opt);
 | 
			
		||||
		} else
 | 
			
		||||
			if (utime(file, NULL) == -1)
 | 
			
		||||
				eerrorx("swclock: utime: %s", strerror(errno));
 | 
			
		||||
		if (futimens(fd, NULL) == -1)
 | 
			
		||||
			eerrorx("swclock: futimens: %s", strerror(errno));
 | 
			
		||||
		close(fd);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -12,24 +12,14 @@
 | 
			
		||||
 | 
			
		||||
#define SYSLOG_NAMES
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <syslog.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include "einfo.h"
 | 
			
		||||
#include "rc.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
#include "helpers.h"
 | 
			
		||||
 | 
			
		||||
const char *applet = NULL;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,55 +1,54 @@
 | 
			
		||||
Using supervise-daemon
 | 
			
		||||
======================
 | 
			
		||||
# Using supervise-daemon
 | 
			
		||||
 | 
			
		||||
Beginning with OpenRC-0.21 we have our own daemon supervisor,
 | 
			
		||||
supervise-daemon., which can start a daemon and restart it if it
 | 
			
		||||
`supervise-daemon`, which can start a daemon and restart it if it
 | 
			
		||||
terminates unexpectedly.
 | 
			
		||||
 | 
			
		||||
The following is a brief guide on using this capability.
 | 
			
		||||
 | 
			
		||||
* Use Default start, stop and status functions
 | 
			
		||||
* **Use Default start, stop and status functions**.
 | 
			
		||||
  If you write your own start, stop and status functions in your service
 | 
			
		||||
  script, none of this will work. You must allow OpenRC to use the default
 | 
			
		||||
  functions.
 | 
			
		||||
 | 
			
		||||
* Daemons must not fork
 | 
			
		||||
  Any daemon that you would like to have monitored by supervise-daemon
 | 
			
		||||
* **Daemons must not fork**.
 | 
			
		||||
  Any daemon that you would like to have monitored by `supervise-daemon`
 | 
			
		||||
  must not fork. Instead, it must stay in the foreground. If the daemon
 | 
			
		||||
  forks, the supervisor will be unable to monitor it.
 | 
			
		||||
 | 
			
		||||
  If the daemon can be configured to not fork, this should be done in the
 | 
			
		||||
  daemon's configuration file, or by adding a command line option that
 | 
			
		||||
  instructs it not to fork to the command_args_foreground variable shown
 | 
			
		||||
  instructs it not to fork to the `command_args_foreground` variable shown
 | 
			
		||||
  below.
 | 
			
		||||
 | 
			
		||||
# Health Checks
 | 
			
		||||
## Health checks
 | 
			
		||||
 | 
			
		||||
Health checks are a way to make sure a service monitored by
 | 
			
		||||
supervise-daemon stays healthy. To configure a health check for a
 | 
			
		||||
service, you need to write a healthcheck() function, and optionally an
 | 
			
		||||
unhealthy() function in the service script. Also, you will need to set
 | 
			
		||||
the healthcheck_timer and optionally healthcheck_delay variables.
 | 
			
		||||
`supervise-daemon` stays healthy. To configure a health check for a
 | 
			
		||||
service, you need to write a `healthcheck()` function, and optionally an
 | 
			
		||||
`unhealthy()` function in the service script. Also, you will need to set
 | 
			
		||||
the `healthcheck_timer` and optionally `healthcheck_delay` variables.
 | 
			
		||||
 | 
			
		||||
## healthcheck() function
 | 
			
		||||
### healthcheck() function
 | 
			
		||||
 | 
			
		||||
The healthcheck() function is run repeatedly based on the settings of
 | 
			
		||||
the healthcheck_* variables. This function should return zero if the
 | 
			
		||||
The `healthcheck()` function is run repeatedly based on the settings of
 | 
			
		||||
the `healthcheck_*` variables. This function should return zero if the
 | 
			
		||||
service is currently healthy or non-zero otherwise.
 | 
			
		||||
 | 
			
		||||
## unhealthy() function
 | 
			
		||||
### unhealthy() function
 | 
			
		||||
 | 
			
		||||
If the healthcheck() function returns non-zero, the unhealthy() function
 | 
			
		||||
If the `healthcheck()` function returns non-zero, the `unhealthy()` function
 | 
			
		||||
is run, then the service is restarted. Since the service will be
 | 
			
		||||
restarted by the supervisor, the unhealthy function should not try to
 | 
			
		||||
restart it; the purpose of the function is to allow any cleanup tasks
 | 
			
		||||
other than restarting the service to be run.
 | 
			
		||||
 | 
			
		||||
# Variable Settings
 | 
			
		||||
## Variable settings
 | 
			
		||||
 | 
			
		||||
The most important setting is the supervisor variable. At the top of
 | 
			
		||||
your service script, you should set this variable as follows:
 | 
			
		||||
 | 
			
		||||
``` sh
 | 
			
		||||
```sh
 | 
			
		||||
supervisor=supervise-daemon
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
@@ -57,7 +56,7 @@ Several other variables affect the way services behave under
 | 
			
		||||
supervise-daemon. They are documented on the  openrc-run man page, but I
 | 
			
		||||
will list them here for convenience:
 | 
			
		||||
 | 
			
		||||
``` sh
 | 
			
		||||
```sh
 | 
			
		||||
command_args_foreground="arguments"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
@@ -65,21 +64,21 @@ This 	should be used if the daemon you want to monitor
 | 
			
		||||
forks and goes to the background by default. This should be set to the
 | 
			
		||||
command line option that instructs the daemon to stay in the foreground.
 | 
			
		||||
 | 
			
		||||
``` sh
 | 
			
		||||
```sh
 | 
			
		||||
healthcheck_delay=seconds
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This is the delay, in seconds, before the first health check is run.
 | 
			
		||||
If it is not set, we use the value of healthcheck_timer.
 | 
			
		||||
If it is not set, we use the value of `healthcheck_timer`.
 | 
			
		||||
 | 
			
		||||
``` sh
 | 
			
		||||
```sh
 | 
			
		||||
healthcheck_timer=seconds
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This is the  number of seconds between health checks. If it is not set,
 | 
			
		||||
no health checks will be run.
 | 
			
		||||
 | 
			
		||||
``` sh
 | 
			
		||||
```sh
 | 
			
		||||
respawn_delay
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
@@ -87,7 +86,7 @@ This is the number of seconds to delay before attempting to respawn a
 | 
			
		||||
supervised process after it dies unexpectedly.
 | 
			
		||||
The default is to respawn immediately.
 | 
			
		||||
 | 
			
		||||
``` sh
 | 
			
		||||
```sh
 | 
			
		||||
respawn_max=x
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
@@ -95,17 +94,17 @@ This is the maximum number of times to respawn a supervised process
 | 
			
		||||
during the given respawn period.
 | 
			
		||||
The default is 10. 0 means unlimited.
 | 
			
		||||
 | 
			
		||||
``` sh
 | 
			
		||||
```sh
 | 
			
		||||
respawn_period=seconds
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This works in conjunction with respawn_max and respawn_delay above to
 | 
			
		||||
This works in conjunction with `respawn_max` and `respawn_delay` above to
 | 
			
		||||
decide if a process should not be respawned for some reason.
 | 
			
		||||
 | 
			
		||||
For example, if respawn period is 10 and respawn_max is 2, the process
 | 
			
		||||
For example, if respawn period is 10 and `respawn_max` is 2, the process
 | 
			
		||||
would need to die 3 times within 10 seconds to no longer be respawned.
 | 
			
		||||
Note that respawn_delay will delay all of this, so in the above scenario
 | 
			
		||||
a respawn_delay of greater than 5 will cause infinite respawns.
 | 
			
		||||
Note that `respawn_delay` will delay all of this, so in the above scenario
 | 
			
		||||
a `respawn_delay` of greater than 5 will cause infinite respawns.
 | 
			
		||||
 | 
			
		||||
By default, this is unset and respawn_max applies to the entire lifetime
 | 
			
		||||
By default, this is unset and `respawn_max` applies to the entire lifetime
 | 
			
		||||
of the service.
 | 
			
		||||
 
 | 
			
		||||
@@ -4,10 +4,14 @@ set -e
 | 
			
		||||
set -u
 | 
			
		||||
 | 
			
		||||
rc_libexecdir="$1"
 | 
			
		||||
os="$2"
 | 
			
		||||
sbindir="$2"
 | 
			
		||||
os="$3"
 | 
			
		||||
sysvinit="$4"
 | 
			
		||||
 | 
			
		||||
if [ ${os} != Linux ]; then
 | 
			
		||||
if [ "${os}" != Linux ]; then
 | 
			
		||||
	install -d "${DESTDIR}/${rc_libexecdir}"/init.d
 | 
			
		||||
fi
 | 
			
		||||
install -d "${DESTDIR}/${rc_libexecdir}"/tmp
 | 
			
		||||
install -m 644 "${MESON_BUILD_ROOT}/src/shared/version" "${DESTDIR}/${rc_libexecdir}"
 | 
			
		||||
if [ "${os}" = Linux ] && [ "${sysvinit}" = yes ]; then
 | 
			
		||||
	ln -sf openrc-init "${DESTDIR}/${sbindir}"/init
 | 
			
		||||
fi
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user