1#!/bin/sh
2#
3# This script is used by busybox and procps-ng.
4#
5# With procps-ng, the "--system" option of sysctl also enables "--ignore", so
6# errors are not reported via syslog. Use the run_logger function to mimic the
7# --system behavior, still reporting errors via syslog. Users not interested
8# on error reports can add "-e" to SYSCTL_ARGS.
9#
10# busybox does not have a "--system" option neither reports errors via syslog,
11# so the scripting provides a consistent behavior between the implementations.
12# Testing the busybox sysctl exit code is fruitless, as at the moment, since
13# its exit status is zero even if errors happen. Hopefully this will be fixed
14# in a future busybox version.
15
16PROGRAM="sysctl"
17
18SYSCTL_ARGS=""
19
20# shellcheck source=/dev/null
21[ -r "/etc/default/$PROGRAM" ] && . "/etc/default/$PROGRAM"
22
23# Files are read from directories in the SYSCTL_SOURCES list, in the given
24# order. A file may be used more than once, since there can be multiple
25# symlinks to it. No attempt is made to prevent this.
26SYSCTL_SOURCES="/etc/sysctl.d/ /usr/local/lib/sysctl.d/ /usr/lib/sysctl.d/ /lib/sysctl.d/ /etc/sysctl.conf"
27
28# If the logger utility is available all messages are sent to syslog, except
29# for the final status. The file redirections do the following:
30#
31# - stdout is redirected to syslog with facility.level "kern.info"
32# - stderr is redirected to syslog with facility.level "kern.err"
33# - file dscriptor 4 is used to pass the result to the "start" function.
34#
35run_logger() {
36	# shellcheck disable=SC2086 # we need the word splitting
37	find $SYSCTL_SOURCES -maxdepth 1 -name '*.conf' -print0 2> /dev/null | \
38	xargs -0 -r -n 1 readlink -f | {
39		prog_status="OK"
40		while :; do
41			read -r file || {
42				echo "$prog_status" >&4
43				break
44			}
45			echo "* Applying $file ..."
46			/sbin/sysctl -p "$file" $SYSCTL_ARGS || prog_status="FAIL"
47		done 2>&1 >&3 | /usr/bin/logger -t sysctl -p kern.err
48	} 3>&1 | /usr/bin/logger -t sysctl -p kern.info
49}
50
51# If logger is not available all messages are sent to stdout/stderr.
52run_std() {
53	# shellcheck disable=SC2086 # we need the word splitting
54	find $SYSCTL_SOURCES -maxdepth 1 -name '*.conf' -print0 2> /dev/null | \
55	xargs -0 -r -n 1 readlink -f | {
56		prog_status="OK"
57		while :; do
58			read -r file || {
59				echo "$prog_status" >&4
60				break
61			}
62			echo "* Applying $file ..."
63			/sbin/sysctl -p "$file" $SYSCTL_ARGS || prog_status="FAIL"
64		done
65	}
66}
67
68if [ -x /usr/bin/logger ]; then
69	run_program="run_logger"
70else
71	run_program="run_std"
72fi
73
74start() {
75	printf '%s %s: ' "$1" "$PROGRAM"
76	status=$("$run_program" 4>&1)
77	echo "$status"
78	if [ "$status" = "OK" ]; then
79		return 0
80	fi
81	return 1
82}
83
84case "$1" in
85	start)
86		start "Running";;
87	restart|reload)
88		start "Rerunning";;
89	stop)
90		:;;
91	*)
92		echo "Usage: $0 {start|stop|restart|reload}"
93		exit 1
94esac
95