[*] First commit
This commit is contained in:
parent
6b057d3b3d
commit
a1f085aed4
|
@ -0,0 +1,10 @@
|
||||||
|
tags
|
||||||
|
*.tar.xz*
|
||||||
|
hostname.5
|
||||||
|
locale.conf.5
|
||||||
|
vconsole.conf.5
|
||||||
|
rc.conf.5
|
||||||
|
archlinux.7
|
||||||
|
arch-modules-load.8
|
||||||
|
rc.d.8
|
||||||
|
pkg/
|
|
@ -0,0 +1,73 @@
|
||||||
|
VER := 2022.11.13
|
||||||
|
|
||||||
|
DIRS := \
|
||||||
|
/etc/rc.d \
|
||||||
|
/etc/rc.d/functions.d \
|
||||||
|
/etc/logrotate.d \
|
||||||
|
/etc/profile.d \
|
||||||
|
/usr/lib/initscripts \
|
||||||
|
/usr/lib/tmpfiles.d \
|
||||||
|
/usr/bin \
|
||||||
|
/usr/share/bash-completion/completions \
|
||||||
|
/usr/share/zsh/site-functions \
|
||||||
|
/usr/share/man/man5 \
|
||||||
|
/usr/share/man/man8
|
||||||
|
|
||||||
|
CONFIGS := \
|
||||||
|
conf/inittab \
|
||||||
|
conf/rc.conf
|
||||||
|
|
||||||
|
SCRIPTS := \
|
||||||
|
scripts/rc.local \
|
||||||
|
scripts/rc.local.shutdown \
|
||||||
|
scripts/rc.multi \
|
||||||
|
scripts/rc.shutdown \
|
||||||
|
scripts/rc.single \
|
||||||
|
scripts/rc.sysinit
|
||||||
|
|
||||||
|
DAEMONS := \
|
||||||
|
daemon/hwclock \
|
||||||
|
daemon/network \
|
||||||
|
daemon/netfs
|
||||||
|
|
||||||
|
MAN_PAGES := \
|
||||||
|
man/rc.conf.5 \
|
||||||
|
man/rc.d.8
|
||||||
|
|
||||||
|
TOOLS := \
|
||||||
|
tools/arch-binfmt \
|
||||||
|
tools/arch-modules \
|
||||||
|
tools/arch-tmpfiles
|
||||||
|
|
||||||
|
all: doc
|
||||||
|
|
||||||
|
installdirs:
|
||||||
|
install -dm755 $(foreach DIR, $(DIRS), $(DESTDIR)$(DIR))
|
||||||
|
|
||||||
|
install: installdirs doc
|
||||||
|
install -m644 -t $(DESTDIR)/etc $(CONFIGS)
|
||||||
|
install -m755 -t $(DESTDIR)/etc $(SCRIPTS)
|
||||||
|
install -m644 -t $(DESTDIR)/etc/logrotate.d misc/bootlog
|
||||||
|
install -m644 -t $(DESTDIR)/etc/rc.d scripts/functions
|
||||||
|
install -m755 -t $(DESTDIR)/etc/rc.d $(DAEMONS)
|
||||||
|
install -m755 -t $(DESTDIR)/usr/bin tools/rc.d
|
||||||
|
install -m755 -t $(DESTDIR)/etc/profile.d misc/read_locale.sh
|
||||||
|
install -m644 -t $(DESTDIR)/usr/share/man/man5 $(filter %.5, $(MAN_PAGES))
|
||||||
|
install -m644 -t $(DESTDIR)/usr/share/man/man8 $(filter %.8, $(MAN_PAGES))
|
||||||
|
install -m755 -t $(DESTDIR)/usr/lib/initscripts $(TOOLS)
|
||||||
|
install -m644 conf/tmpfiles.conf $(DESTDIR)/usr/lib/tmpfiles.d/initscripts.conf
|
||||||
|
install -m644 -T completions/bash-completion $(DESTDIR)/usr/share/bash-completion/completions/rc.d
|
||||||
|
install -m644 -T completions/zsh-completion $(DESTDIR)/usr/share/zsh/site-functions/_rc.d
|
||||||
|
|
||||||
|
%.5: %.5.txt
|
||||||
|
a2x -d manpage -f manpage $<
|
||||||
|
|
||||||
|
%.8: %.8.txt
|
||||||
|
a2x -d manpage -f manpage $<
|
||||||
|
|
||||||
|
doc: $(MAN_PAGES)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(MAN_PAGES)
|
||||||
|
|
||||||
|
.PHONY: all installdirs install doc clean
|
|
@ -0,0 +1,24 @@
|
||||||
|
# rc.d bash completion by Seblu <seblu@seblu.net>
|
||||||
|
|
||||||
|
_rc_d()
|
||||||
|
{
|
||||||
|
local action cur prev
|
||||||
|
actions='help list start stop reload restart'
|
||||||
|
options='-s --started -S --stopped -a --auto -A --noauto'
|
||||||
|
_get_comp_words_by_ref cur prev
|
||||||
|
_get_first_arg
|
||||||
|
if [[ -z "$arg" ]]; then
|
||||||
|
COMPREPLY=($(compgen -W "${actions} ${options}" -- "$cur"))
|
||||||
|
elif [[ "$arg" == help ]]; then
|
||||||
|
COMPREPLY=()
|
||||||
|
elif [[ "$arg" == start ]]; then
|
||||||
|
COMPREPLY=($(comm -23 <(cd /etc/rc.d && compgen -f -X 'functions*' "$cur"|sort) <(cd /run/daemons/ && compgen -f "$cur"|sort)))
|
||||||
|
elif [[ "$arg" =~ stop|restart|reload ]]; then
|
||||||
|
COMPREPLY=($(cd /run/daemons/ && compgen -f "$cur"|sort))
|
||||||
|
else
|
||||||
|
COMPREPLY=($(compgen -W "${options} $(cd /etc/rc.d && compgen -f -X 'functions*')" -- "$cur"))
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
complete -F _rc_d rc.d
|
||||||
|
|
||||||
|
# vim: set ts=2 sw=2 ft=sh noet:
|
|
@ -0,0 +1,36 @@
|
||||||
|
#compdef rc.d
|
||||||
|
|
||||||
|
_rc.d () {
|
||||||
|
local curcontext="$curcontext" state line
|
||||||
|
typeset -A opt_args
|
||||||
|
|
||||||
|
_arguments "1: :->action" "*: :->service" {-s,--started} {-S,--stopped} {-a,--auto} {-A,--noauto}
|
||||||
|
case $state in
|
||||||
|
action)
|
||||||
|
_arguments "*:action:(list help start stop restart)"
|
||||||
|
;;
|
||||||
|
service)
|
||||||
|
local action="$words[2]"
|
||||||
|
curcontext="${curcontext%:*:*}:rc.d-${action}:"
|
||||||
|
|
||||||
|
case $action in
|
||||||
|
help)
|
||||||
|
_arguments "*: :"
|
||||||
|
;;
|
||||||
|
start)
|
||||||
|
_arguments "*: :($(comm -23 <(echo /etc/rc.d/*(N-*:t)|tr ' ' '\n') <(echo /run/daemons/*(N:t)|tr ' ' '\n')))"
|
||||||
|
;;
|
||||||
|
stop|restart|reload)
|
||||||
|
_arguments "*: :(/run/daemons/*(N:t))"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
_arguments "*: :(/etc/rc.d/*(N-*:t))"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
_rc.d "$@"
|
||||||
|
|
||||||
|
# vim: set ts=2 sw=2 ft=sh noet:
|
|
@ -0,0 +1,48 @@
|
||||||
|
#
|
||||||
|
# /etc/inittab
|
||||||
|
#
|
||||||
|
|
||||||
|
# Runlevels:
|
||||||
|
# 0 Halt
|
||||||
|
# 1(S) Single-user
|
||||||
|
# 2 Not used
|
||||||
|
# 3 Multi-user
|
||||||
|
# 4 Not used
|
||||||
|
# 5 X11
|
||||||
|
# 6 Reboot
|
||||||
|
|
||||||
|
## Only one of the following two lines can be uncommented!
|
||||||
|
# Boot to console
|
||||||
|
id:3:initdefault:
|
||||||
|
# Boot to X11
|
||||||
|
#id:5:initdefault:
|
||||||
|
|
||||||
|
rc::sysinit:/etc/rc.sysinit
|
||||||
|
rs:S1:wait:/etc/rc.single
|
||||||
|
rm:2345:wait:/etc/rc.multi
|
||||||
|
rh:06:wait:/etc/rc.shutdown
|
||||||
|
su:S:wait:/usr/bin/sulogin -p
|
||||||
|
|
||||||
|
# -8 options fixes umlauts problem on login
|
||||||
|
c1:2345:respawn:/usr/bin/agetty -8 -s 38400 tty1 linux
|
||||||
|
c2:2345:respawn:/usr/bin/agetty -8 -s 38400 tty2 linux
|
||||||
|
c3:2345:respawn:/usr/bin/agetty -8 -s 38400 tty3 linux
|
||||||
|
c4:2345:respawn:/usr/bin/agetty -8 -s 38400 tty4 linux
|
||||||
|
c5:2345:respawn:/usr/bin/agetty -8 -s 38400 tty5 linux
|
||||||
|
c6:2345:respawn:/usr/bin/agetty -8 -s 38400 tty6 linux
|
||||||
|
|
||||||
|
# Serial Virtual Console for KVM and others VMs
|
||||||
|
#s0:2345:respawn:/usr/bin/agetty -8 -s 9600 ttyS0 linux
|
||||||
|
|
||||||
|
# Hypervisor Virtual Console for Xen and KVM
|
||||||
|
#h0:2345:respawn:/usr/bin/agetty -8 -s 38400 hvc0 linux
|
||||||
|
|
||||||
|
ca::ctrlaltdel:/usr/bin/shutdown -t3 -r now
|
||||||
|
|
||||||
|
# Example lines for starting a login manager
|
||||||
|
x:5:respawn:/usr/bin/xdm -nodaemon
|
||||||
|
#x:5:respawn:/usr/bin/gdm -nodaemon
|
||||||
|
#x:5:respawn:/usr/bin/kdm -nodaemon
|
||||||
|
#x:5:respawn:/usr/bin/slim >/dev/null 2>&1
|
||||||
|
|
||||||
|
# End of file
|
|
@ -0,0 +1,99 @@
|
||||||
|
#
|
||||||
|
# /etc/rc.conf - Main Configuration for Arch Linux
|
||||||
|
#
|
||||||
|
# See 'man 5 rc.conf' for more details
|
||||||
|
#
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------
|
||||||
|
# LOCALIZATION
|
||||||
|
# -----------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# LOCALE: available languages can be listed with the 'locale -a' command
|
||||||
|
# HARDWARECLOCK: set to "", "UTC" or "localtime", any other value will result
|
||||||
|
# in the hardware clock being left untouched (useful for virtualization)
|
||||||
|
# Note: Using "localtime" is discouraged, using "" makes hwclock fall back
|
||||||
|
# to the value in /etc/adjfile
|
||||||
|
# TIMEZONE: timezones are found in /usr/share/zoneinfo
|
||||||
|
# Note: if unset, the value in /etc/localtime is used unchanged
|
||||||
|
# CONSOLEFONT: found in /usr/share/kbd/consolefonts (only needed for non-US)
|
||||||
|
# CONSOLEMAP: found in /usr/share/kbd/consoletrans
|
||||||
|
# KEYMAP: keymaps are found in /usr/share/kbd/keymaps
|
||||||
|
# USECOLOR: use ANSI color sequences in startup messages
|
||||||
|
#
|
||||||
|
#LOCALE="en_US.UTF-8"
|
||||||
|
#HARDWARECLOCK="UTC"
|
||||||
|
#TIMEZONE="Canada/Pacific"
|
||||||
|
#CONSOLEFONT="LatArCyrHeb-16"
|
||||||
|
#CONSOLEMAP=
|
||||||
|
#KEYMAP="no-latin1"
|
||||||
|
#USECOLOR="yes"
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------
|
||||||
|
# HARDWARE
|
||||||
|
# -----------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# Modules to load at boot-up. Prefix with a ! to blacklist.
|
||||||
|
#
|
||||||
|
#MODULES=()
|
||||||
|
|
||||||
|
# Scan for FakeRAID (dmraid) Volumes at startup
|
||||||
|
USEDMRAID="no"
|
||||||
|
|
||||||
|
# Scan for LVM volume groups at startup, required if you use LVM
|
||||||
|
USELVM="no"
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------
|
||||||
|
# NETWORKING
|
||||||
|
# -----------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# HOSTNAME: Hostname of machine. Should also be put in /etc/hosts
|
||||||
|
#
|
||||||
|
#HOSTNAME="localhost"
|
||||||
|
|
||||||
|
# Use 'ip addr' or 'ls /sys/class/net/' to see all available interfaces.
|
||||||
|
#
|
||||||
|
# Wired network setup
|
||||||
|
# - interface: name of device (required)
|
||||||
|
# - address: IP address (leave blank for DHCP)
|
||||||
|
# - netmask: subnet mask (ignored for DHCP) (optional, defaults to 255.255.255.0)
|
||||||
|
# - broadcast: broadcast address (ignored for DHCP) (optional)
|
||||||
|
# - gateway: default route (ignored for DHCP)
|
||||||
|
#
|
||||||
|
# Static IP example
|
||||||
|
# interface=eth0
|
||||||
|
# address=192.168.0.2
|
||||||
|
# netmask=255.255.255.0
|
||||||
|
# broadcast=192.168.0.255
|
||||||
|
# gateway=192.168.0.1
|
||||||
|
#
|
||||||
|
# DHCP example
|
||||||
|
# interface=eth0
|
||||||
|
# address=
|
||||||
|
# netmask=
|
||||||
|
# gateway=
|
||||||
|
|
||||||
|
#interface=
|
||||||
|
#address=
|
||||||
|
#netmask=
|
||||||
|
#broadcast=
|
||||||
|
#gateway=
|
||||||
|
|
||||||
|
# Setting this to "yes" will skip network shutdown.
|
||||||
|
# This is required if your root device is on NFS.
|
||||||
|
NETWORK_PERSIST="no"
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------
|
||||||
|
# DAEMONS
|
||||||
|
# -----------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# Daemons to start at boot-up (in this order)
|
||||||
|
# - prefix a daemon with a ! to disable it
|
||||||
|
# - prefix a daemon with a @ to start it up in the background
|
||||||
|
#
|
||||||
|
# If you are sure nothing else touches your hardware clock (such as ntpd or
|
||||||
|
# a dual-boot), you might want to enable 'hwclock'. Note that this will only
|
||||||
|
# make a difference if the hwclock program has been calibrated correctly.
|
||||||
|
#
|
||||||
|
# If you use a network filesystem you should enable 'netfs'.
|
||||||
|
#
|
||||||
|
DAEMONS=(syslog-ng network crond)
|
|
@ -0,0 +1,5 @@
|
||||||
|
#
|
||||||
|
# /usr/lib/tmpfiles.d/arch.conf
|
||||||
|
#
|
||||||
|
|
||||||
|
d /run/daemons 0755 root root -
|
|
@ -0,0 +1,26 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
. /etc/rc.conf
|
||||||
|
. /etc/rc.d/functions
|
||||||
|
|
||||||
|
case $HARDWARECLOCK in
|
||||||
|
UTC) HWCLOCK_PARAMS="--utc";;
|
||||||
|
localtime) HWCLOCK_PARAMS="--localtime";;
|
||||||
|
*) HWCLOCK_PARAMS="";;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
add_daemon hwclock;;
|
||||||
|
stop)
|
||||||
|
hwclock --adjust $HWCLOCK_PARAMS
|
||||||
|
rm_daemon hwclock
|
||||||
|
;;
|
||||||
|
restart)
|
||||||
|
$0 stop
|
||||||
|
sleep 2
|
||||||
|
$0 start
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "usage: $0 {start|stop|restart}"
|
||||||
|
esac
|
|
@ -0,0 +1,36 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# sourcing our current rc.conf requires this to be a bash script
|
||||||
|
. /etc/rc.conf
|
||||||
|
. /etc/rc.d/functions
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
stat_busy "Mounting network filesystems"
|
||||||
|
mount -a -t "$NETFS"
|
||||||
|
rc=$?
|
||||||
|
mount -a -O _netdev
|
||||||
|
(( rc || $? )) && stat_die
|
||||||
|
add_daemon netfs
|
||||||
|
stat_done
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
stat_busy "Unmounting network filesystems"
|
||||||
|
umount -a -f -O _netdev
|
||||||
|
rc=$?
|
||||||
|
umount -a -f -t "$NETFS"
|
||||||
|
(( rc || $? )) && stat_die
|
||||||
|
rm_daemon netfs
|
||||||
|
stat_done
|
||||||
|
;;
|
||||||
|
restart)
|
||||||
|
$0 stop
|
||||||
|
sleep 1
|
||||||
|
$0 start
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "usage: $0 {start|stop|restart}"
|
||||||
|
exit 1
|
||||||
|
esac
|
||||||
|
|
||||||
|
# vim: set ts=2 noet:
|
|
@ -0,0 +1,306 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
. /etc/rc.conf
|
||||||
|
. /etc/rc.d/functions
|
||||||
|
|
||||||
|
for s in wireless bonding bridges dhcpcd; do
|
||||||
|
[[ -f /etc/conf.d/$s ]] && . "/etc/conf.d/$s"
|
||||||
|
done
|
||||||
|
|
||||||
|
# helper function to determine if legacy network support is needed
|
||||||
|
need_legacy() {
|
||||||
|
# complain when `interface' is unset and `INTERFACES' has profiles enabled
|
||||||
|
if [[ -z $interface && ${INTERFACES[@]##!*} ]]; then
|
||||||
|
return 0 # need legacy
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 1 # enough present for iproute2 support
|
||||||
|
}
|
||||||
|
|
||||||
|
deprecated() {
|
||||||
|
print_depr "The legacy network settings format" "rc.conf(5)"
|
||||||
|
}
|
||||||
|
|
||||||
|
network_up() {
|
||||||
|
if [[ $address ]]; then
|
||||||
|
ip link set dev $interface up || return 1
|
||||||
|
ip addr add $address/${netmask:-24} broadcast ${broadcast:-+} dev $interface || return 1
|
||||||
|
[[ $gateway ]] && { ip route add default via $gateway || return 1; }
|
||||||
|
else
|
||||||
|
dhcpcd $DHCPCD_ARGS $interface || return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
network_down() {
|
||||||
|
if [[ ! -n $interface ]]; then
|
||||||
|
if [[ -f /run/dhcpcd.pid ]]; then
|
||||||
|
dhcpcd -qk || return 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [[ ! -n $address && -f /run/dhcpcd-$interface.pid ]]; then
|
||||||
|
dhcpcd -qk $interface || return 1
|
||||||
|
else
|
||||||
|
ip addr flush dev $interface || return 1
|
||||||
|
fi
|
||||||
|
ip link set dev $interface down || return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
ifup() {
|
||||||
|
local ifcfg=${!1}
|
||||||
|
|
||||||
|
if [[ ! $1 ]]; then
|
||||||
|
echo "usage: $0 ifup <interface_name>"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get the name of the interface from the first token in the string
|
||||||
|
if [[ $ifcfg = dhcp ]]; then
|
||||||
|
ifname=$1
|
||||||
|
else
|
||||||
|
ifname=${ifcfg%% *}
|
||||||
|
fi
|
||||||
|
|
||||||
|
ifconfig $ifname up
|
||||||
|
|
||||||
|
wi_up $1 || return 1
|
||||||
|
|
||||||
|
if [[ $ifcfg = dhcp ]]; then
|
||||||
|
# remove the .pid file if it exists
|
||||||
|
rm -f /run/dhcpcd-${1}.pid >/dev/null 2>&1
|
||||||
|
rm -f /run/dhcpcd-${1}.cache >/dev/null 2>&1
|
||||||
|
dhcpcd $DHCPCD_ARGS ${1}
|
||||||
|
else
|
||||||
|
ifconfig $ifcfg
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
wi_up() {
|
||||||
|
local iwcfg=wlan_$1
|
||||||
|
|
||||||
|
[[ ${!iwcfg} ]] || return 0
|
||||||
|
|
||||||
|
iwconfig ${!iwcfg}
|
||||||
|
[[ $WIRELESS_TIMEOUT ]] || WIRELESS_TIMEOUT=2
|
||||||
|
sleep $WIRELESS_TIMEOUT
|
||||||
|
|
||||||
|
bssid=$(iwgetid $1 -ra)
|
||||||
|
if [[ $bssid = 00:00:00:00:00:00 ]]; then
|
||||||
|
printhl "Could not associate $1 - try increasing WIRELESS_TIMEOUT and check network is WEP or has no security"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
ifdown() {
|
||||||
|
local ifcfg=${!1}
|
||||||
|
|
||||||
|
if [[ ! $1 ]]; then
|
||||||
|
echo "usage: $0 ifdown <interface_name>"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $ifcfg = dhcp && -f /run/dhcpcd-${1}.pid ]]; then
|
||||||
|
dhcpcd -k ${1} >/dev/null 2>&1
|
||||||
|
fi
|
||||||
|
# Always bring the interface itself down
|
||||||
|
ifconfig ${1} down >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
iflist() {
|
||||||
|
for ifline in ${INTERFACES[@]}; do
|
||||||
|
if [[ $ifline = ${ifline#!} ]]; then
|
||||||
|
printf " $ifline:\t"
|
||||||
|
else
|
||||||
|
printf "$ifline:\t"
|
||||||
|
fi
|
||||||
|
echo ${!ifline#!}
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
rtup() {
|
||||||
|
local routecfg=${!1}
|
||||||
|
|
||||||
|
if [[ ! $1 ]]; then
|
||||||
|
echo "usage: $0 rtup <route_name>"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $routecfg =~ :: ]]; then
|
||||||
|
route -A inet6 add $routecfg
|
||||||
|
else
|
||||||
|
route add $routecfg
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
rtdown() {
|
||||||
|
local routecfg=${!1}
|
||||||
|
|
||||||
|
if [[ ! $1 ]]; then
|
||||||
|
echo "usage: $0 rtdown <route_name>"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $routecfg =~ :: ]]; then
|
||||||
|
route -A inet6 del $routecfg
|
||||||
|
else
|
||||||
|
route del $routecfg
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
rtlist() {
|
||||||
|
for rtline in ${ROUTES[@]}; do
|
||||||
|
if [[ $rtline = ${rtline#!} ]]; then
|
||||||
|
printf " $rtline:\t"
|
||||||
|
else
|
||||||
|
printf "$rtline:\t"
|
||||||
|
fi
|
||||||
|
echo ${!rtline#!}
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
bond_up() {
|
||||||
|
for ifline in ${BOND_INTERFACES[@]}; do
|
||||||
|
if [[ $ifline = ${ifline#!} ]]; then
|
||||||
|
bondcfg="bond_$ifline"
|
||||||
|
if [[ ${!bondcfg} ]]; then
|
||||||
|
ifenslave $ifline ${!bondcfg} || error=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
bond_down() {
|
||||||
|
for ifline in ${BOND_INTERFACES[@]}; do
|
||||||
|
if [[ $ifline = ${ifline#!} ]]; then
|
||||||
|
bondcfg="bond_$ifline"
|
||||||
|
ifenslave -d $ifline ${!bondcfg} || error=1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
bridge_up() {
|
||||||
|
for br in ${BRIDGE_INTERFACES[@]}; do
|
||||||
|
if [[ $br = ${br#!} ]]; then
|
||||||
|
# if the bridge already exists, remove it
|
||||||
|
if [[ $(ifconfig $br 2>/dev/null) ]]; then
|
||||||
|
ifconfig $br down
|
||||||
|
brctl delbr $br
|
||||||
|
fi
|
||||||
|
brctl addbr $br
|
||||||
|
brifs="bridge_$br"
|
||||||
|
for brif in ${!brifs}; do
|
||||||
|
if [[ $brif = ${brif#!} ]]; then
|
||||||
|
for ifline in ${BOND_INTERFACES[@]}; do
|
||||||
|
if [[ $brif = $ifline && $ifline = ${ifline#!} ]]; then
|
||||||
|
ifup $ifline
|
||||||
|
bondcfg="bond_$ifline"
|
||||||
|
ifenslave $ifline ${!bondcfg} || error=1
|
||||||
|
unset bond_$ifline
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
brctl addif $br $brif || error=1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
bridge_down() {
|
||||||
|
for br in ${BRIDGE_INTERFACES[@]}; do
|
||||||
|
if [[ $br = ${br#!} ]]; then
|
||||||
|
brctl delbr $br
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
# deprecation check
|
||||||
|
need_legacy && deprecated
|
||||||
|
if ! ck_daemon network; then
|
||||||
|
echo "Network is already running. Try 'rc.d restart network'"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
stat_busy "Starting network"
|
||||||
|
error=0
|
||||||
|
if need_legacy; then
|
||||||
|
# bring up bridge interfaces
|
||||||
|
bridge_up
|
||||||
|
# bring up Ethernet interfaces
|
||||||
|
for ifline in ${INTERFACES[@]}; do
|
||||||
|
if [[ $ifline = ${ifline#!} ]]; then
|
||||||
|
ifup $ifline || error=1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
# bring up bond interfaces
|
||||||
|
bond_up
|
||||||
|
# bring up routes
|
||||||
|
for rtline in "${ROUTES[@]}"; do
|
||||||
|
if [ "$rtline" = "${rtline#!}" ]; then
|
||||||
|
rtup $rtline || error=1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
else
|
||||||
|
network_up
|
||||||
|
fi
|
||||||
|
if (( ! error )); then
|
||||||
|
add_daemon network
|
||||||
|
stat_done
|
||||||
|
else
|
||||||
|
stat_fail
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
# deprecation check
|
||||||
|
need_legacy && deprecated
|
||||||
|
if [[ $NETWORK_PERSIST =~ yes|YES && $RUNLEVEL == [06] ]]; then
|
||||||
|
status "Skipping network shutdown" true
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
stat_busy "Stopping network"
|
||||||
|
rm_daemon network
|
||||||
|
error=0
|
||||||
|
if need_legacy; then
|
||||||
|
for rtline in "${ROUTES[@]}"; do
|
||||||
|
if [[ $rtline = ${rtline#!} ]]; then
|
||||||
|
rtdown $rtline || error=1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
# bring down bond interfaces
|
||||||
|
bond_down
|
||||||
|
for ifline in ${INTERFACES[@]}; do
|
||||||
|
if [[ $ifline = ${ifline#!} ]]; then
|
||||||
|
ifdown $ifline || error=1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
# bring down bridge interfaces
|
||||||
|
bridge_down
|
||||||
|
else
|
||||||
|
network_down
|
||||||
|
fi
|
||||||
|
if (( ! error )); then
|
||||||
|
stat_done
|
||||||
|
else
|
||||||
|
stat_fail
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
restart)
|
||||||
|
$0 stop
|
||||||
|
sleep 2
|
||||||
|
$0 start
|
||||||
|
;;
|
||||||
|
ifup|ifdown|iflist|rtup|rtdown|rtlist)
|
||||||
|
# deprecation check
|
||||||
|
deprecated
|
||||||
|
$1 $2
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "usage: $0 {start|stop|restart}"
|
||||||
|
echo " $0 {ifup|ifdown|iflist|rtup|rtdown|rtlist}";;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# vim: set ts=2 sw=2 noet:
|
|
@ -0,0 +1,183 @@
|
||||||
|
/////
|
||||||
|
vim:set ts=4 sw=4 syntax=asciidoc noet:
|
||||||
|
/////
|
||||||
|
rc.conf(5)
|
||||||
|
==========
|
||||||
|
|
||||||
|
NAME
|
||||||
|
----
|
||||||
|
rc.conf - Arch Linux main configuration file
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
--------
|
||||||
|
/etc/rc.conf
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
-----------
|
||||||
|
The /etc/rc.conf file is the system configuration file for Arch-specific
|
||||||
|
settings. The format is bash. It contains several commonly-edited settings such
|
||||||
|
as time zone, keymap, kernel modules, daemons to load at start-up, etc. It is
|
||||||
|
split up in a few sections to categorize configuration settings: localization,
|
||||||
|
hardware, networking, and daemons.
|
||||||
|
|
||||||
|
LOCALIZATION[[L]]
|
||||||
|
-----------------
|
||||||
|
*LOCALE=*
|
||||||
|
|
||||||
|
This sets your system language, which will be used by all i18n-friendly applications and utilities.
|
||||||
|
See `locale -a` (or locale.gen) for available options.
|
||||||
|
|
||||||
|
If leave empty, LANG in /etc/locale.conf will be used. If unset in both, it falls back to the C locale.
|
||||||
|
|
||||||
|
*TIMEZONE=*
|
||||||
|
|
||||||
|
Specifies the time zone. The setting takes effect on boot by ensuring that /etc/localtime is a symlink
|
||||||
|
to the correct zoneinfo file. Possible time zones are the relative path to a zoneinfo file starting
|
||||||
|
from the directory /usr/share/zoneinfo. For example, a German time zone would be Europe/Berlin,
|
||||||
|
which refers to the file /usr/share/zoneinfo/Europe/Berlin.
|
||||||
|
|
||||||
|
Note: If empty, /etc/localtime is not changed. This is useful if /etc/localtime is maintained manually
|
||||||
|
or by a third-party tool, or if there is no reason to change it from what was set during install.
|
||||||
|
|
||||||
|
*HARDWARECLOCK=*
|
||||||
|
|
||||||
|
How to interpret/update the hardware clock. (used by hwclock)
|
||||||
|
|
||||||
|
Options:
|
||||||
|
|
||||||
|
- empty: fall back to the value in /etc/adjtime, which defaults to UTC.
|
||||||
|
- "UTC": allows operating systems to abstract local time and ease DST.
|
||||||
|
- "localtime": apply time zone (and DST) in hardwareclock.
|
||||||
|
Choose this if you dual-boot with an OS which cannot handle UTC BIOS times correctly, like Windows
|
||||||
|
(note that recent Windows versions can use UTC, which is preferable).
|
||||||
|
- any other value will result in the hardware clock being left untouched (useful for virtualization)
|
||||||
|
|
||||||
|
*CONSOLEFONT=*
|
||||||
|
|
||||||
|
Defines the console font to load with the setfont program on boot.
|
||||||
|
Possible fonts are found in /usr/share/kbd/consolefonts (only needed for non-US).
|
||||||
|
|
||||||
|
If both CONSOLEFONT and KEYMAP leave empty, FONT in /etc/vconsole.conf will be used.
|
||||||
|
|
||||||
|
*CONSOLEMAP=*
|
||||||
|
|
||||||
|
Defines the console map to load with the setfont program on boot. Possible maps are found in
|
||||||
|
/usr/share/kbd/consoletrans. Set this to a map suitable for the appropriate locale (8859-1 for Latin1,
|
||||||
|
for example) if you're using an UTF-8 locale and use programs that generate 8-bit output. If you're
|
||||||
|
using X11 for everyday work, don't bother, as it only affects the output of Linux console applications.
|
||||||
|
|
||||||
|
If both CONSOLEFONT and KEYMAP leave empty, FONT_MAP in /etc/vconsole.conf will be used.
|
||||||
|
|
||||||
|
*KEYMAP=*
|
||||||
|
|
||||||
|
Defines the keymap to load with the loadkeys program on boot. Possible keymaps are
|
||||||
|
found in /usr/share/kbd/keymaps. Please note that this setting is only valid for
|
||||||
|
your TTYs, not any graphical window managers or X.
|
||||||
|
|
||||||
|
If both CONSOLEFONT and KEYMAP leave empty, KEYMAP in /etc/vconsole.conf will be used.
|
||||||
|
|
||||||
|
*USECOLOR=*
|
||||||
|
|
||||||
|
Use ANSI color sequences in start-up messages, unless set to 'no'.
|
||||||
|
|
||||||
|
Default: 'yes'
|
||||||
|
|
||||||
|
HARDWARE[[H]]
|
||||||
|
-------------
|
||||||
|
*MODULES=*
|
||||||
|
|
||||||
|
Modules to load at boot-up.
|
||||||
|
|
||||||
|
Prefix with a ! to blacklist. Alternatively you can add following line in a
|
||||||
|
file in /etc/modprobe.d:
|
||||||
|
|
||||||
|
blacklist <module>
|
||||||
|
|
||||||
|
See man modprobe.d(5) for details.
|
||||||
|
|
||||||
|
If leave empty, contents of modules-load.d will be used.
|
||||||
|
|
||||||
|
*USEDMRAID=*
|
||||||
|
|
||||||
|
Scan for FakeRAID (dmraid) volumes at start-up.
|
||||||
|
|
||||||
|
Default: 'no'
|
||||||
|
|
||||||
|
*USELVM=*
|
||||||
|
|
||||||
|
Scan for LVM volume groups at start-up. This is required if you use LVM.
|
||||||
|
|
||||||
|
Default: 'no'
|
||||||
|
|
||||||
|
NETWORKING[[N]]
|
||||||
|
---------------
|
||||||
|
*HOSTNAME=*
|
||||||
|
|
||||||
|
Hostname of machine. Should also be put in /etc/hosts, unless nss-myhostname is used.
|
||||||
|
|
||||||
|
If leave empty, the contents of /etc/hostname (if exists) will be used.
|
||||||
|
|
||||||
|
The following settings help you setting up a wired network.
|
||||||
|
|
||||||
|
*interface=*
|
||||||
|
|
||||||
|
Name of device. Use `ip addr` or `ls /sys/class/net/` to see all available interfaces.
|
||||||
|
|
||||||
|
Required for manual configuration. If using DHCP, it can be left unset, see dhcpcd(5) for details.
|
||||||
|
|
||||||
|
*address=*
|
||||||
|
|
||||||
|
IP address.
|
||||||
|
|
||||||
|
Required for manual configuration. If left empty, DHCP will be used.
|
||||||
|
|
||||||
|
*netmask=*
|
||||||
|
|
||||||
|
Subnet mask.
|
||||||
|
|
||||||
|
Defaults to 255.255.255.0. Ignored when using DHCP.
|
||||||
|
|
||||||
|
*broadcast=*
|
||||||
|
|
||||||
|
Broadcast address.
|
||||||
|
|
||||||
|
Optional for manual configuration, ignored for DHCP.
|
||||||
|
|
||||||
|
*gateway=*
|
||||||
|
|
||||||
|
Default route.
|
||||||
|
|
||||||
|
Required for manual configuration, ignored for DHCP.
|
||||||
|
|
||||||
|
The following options might be needed for advanced use-cases.
|
||||||
|
|
||||||
|
*NETWORK_PERSIST=*
|
||||||
|
|
||||||
|
Setting this to "yes" will skip network shutdown. This is required if your
|
||||||
|
root device is on NFS.
|
||||||
|
|
||||||
|
DAEMONS[[D]]
|
||||||
|
------------
|
||||||
|
*DAEMONS=*
|
||||||
|
|
||||||
|
Daemons to start at boot-up (in this order)
|
||||||
|
|
||||||
|
- prefix a daemon with a ! to disable it
|
||||||
|
- prefix a daemon with a @ to start it up in the background
|
||||||
|
|
||||||
|
If you are sure nothing else touches your hardware clock (such as ntpd or
|
||||||
|
by dual-booting), you might want to enable 'hwclock'. Note that this will only
|
||||||
|
make a difference if the hwclock program has been calibrated correctly.
|
||||||
|
|
||||||
|
If you use a network filesystem, you should enable 'netfs'.
|
||||||
|
|
||||||
|
Default: (syslog-ng network crond)
|
||||||
|
|
||||||
|
SEE ALSO
|
||||||
|
--------
|
||||||
|
|
||||||
|
hostname(5), vconsole.conf(5), locale.conf(5), hwclock(8), modules-load.d(5), modprobe.d(5), ip(8), dhcpcd(8)
|
||||||
|
|
||||||
|
AUTHORS
|
||||||
|
-------
|
||||||
|
Written by Dieter Plaetinck, Tom Gundersen, and others.
|
|
@ -0,0 +1,97 @@
|
||||||
|
/////
|
||||||
|
vim:set ts=4 sw=4 syntax=asciidoc noet:
|
||||||
|
/////
|
||||||
|
rc.d(8)
|
||||||
|
=======
|
||||||
|
|
||||||
|
Name
|
||||||
|
----
|
||||||
|
rc.d - Initscripts power tool
|
||||||
|
|
||||||
|
Synopsis
|
||||||
|
--------
|
||||||
|
*rc.d <action> [options] [rc [rc] ...]*
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
The *rc.d* program controls and lists rc scripts on the system. An action may be
|
||||||
|
invoked on one or more scripts using *rc.d action rc1 rc2...*. See <<A,Actions>>
|
||||||
|
below for more information.
|
||||||
|
Use *rc.d list* to get the list of all rc scripts on the system.
|
||||||
|
|
||||||
|
Actions[[A]]
|
||||||
|
------------
|
||||||
|
The actions supported by a rc scripts may be different from script to script, but
|
||||||
|
commonly supported actions include:
|
||||||
|
|
||||||
|
*start*::
|
||||||
|
Starts the script if it is not already running.
|
||||||
|
|
||||||
|
*stop*::
|
||||||
|
Stops a running script.
|
||||||
|
|
||||||
|
*restart*::
|
||||||
|
Restarts a running script.
|
||||||
|
|
||||||
|
More uncommon actions are:
|
||||||
|
|
||||||
|
*reload*::
|
||||||
|
Signals the script to reload its configuration.
|
||||||
|
|
||||||
|
*status*::
|
||||||
|
Shows the status of the script.
|
||||||
|
|
||||||
|
Options[[O]]
|
||||||
|
------------
|
||||||
|
*-s, --started*::
|
||||||
|
Filter to started scripts.
|
||||||
|
|
||||||
|
*-S, --stopped*::
|
||||||
|
Filter to stopped scripts.
|
||||||
|
|
||||||
|
*-a, --auto*::
|
||||||
|
Filter to auto started scripts.
|
||||||
|
|
||||||
|
*-A, --noauto*::
|
||||||
|
Filter to manually started scripts.
|
||||||
|
|
||||||
|
Examples[[E]]
|
||||||
|
-------------
|
||||||
|
*rc.d list*::
|
||||||
|
List all scripts.
|
||||||
|
|
||||||
|
*rc.d list sshd gpm*::
|
||||||
|
List only *sshd* and *gpm* scripts.
|
||||||
|
|
||||||
|
*rc.d list --started gpm*::
|
||||||
|
List *gpm* script only if started.
|
||||||
|
|
||||||
|
*rc.d list --started --auto*::
|
||||||
|
List all auto started scripts.
|
||||||
|
|
||||||
|
*rc.d start sshd gpm*::
|
||||||
|
Starts *sshd* and *gpm* scripts.
|
||||||
|
|
||||||
|
*rc.d stop crond*::
|
||||||
|
Stops the *crond* script.
|
||||||
|
|
||||||
|
*rc.d restart crond*::
|
||||||
|
Restarts the *crond* script.
|
||||||
|
|
||||||
|
*rc.d restart --stopped crond*::
|
||||||
|
Restarts the *crond* script only if stopped.
|
||||||
|
|
||||||
|
*rc.d help*::
|
||||||
|
Display help.
|
||||||
|
|
||||||
|
Directories[[D]]
|
||||||
|
----------------
|
||||||
|
'/etc/rc.d'::
|
||||||
|
Directory containing available daemons on the system.
|
||||||
|
|
||||||
|
'/usr/lib/initscripts'::
|
||||||
|
Directory containing available initscripts plugins.
|
||||||
|
|
||||||
|
Authors
|
||||||
|
-------
|
||||||
|
Written by Sebastien Luttringer and Dave Reisner.
|
|
@ -0,0 +1,9 @@
|
||||||
|
/var/log/boot {
|
||||||
|
compress
|
||||||
|
rotate 1
|
||||||
|
size=+1024k
|
||||||
|
notifempty
|
||||||
|
missingok
|
||||||
|
copytruncate
|
||||||
|
noolddir
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
unset LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES \
|
||||||
|
LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT LC_IDENTIFICATION
|
||||||
|
|
||||||
|
LOCALE=$(. /etc/rc.conf 2>/dev/null; echo "$LOCALE")
|
||||||
|
|
||||||
|
if [ -n "$LOCALE" ]; then
|
||||||
|
LANG=$LOCALE
|
||||||
|
elif [ -n "$XDG_CONFIG_HOME" ] && [ -r "$XDG_CONFIG_HOME/locale.conf" ]; then
|
||||||
|
. "$XDG_CONFIG_HOME/locale.conf"
|
||||||
|
elif [ -n $HOME ] && [ -r $HOME/.config/locale.conf ]; then
|
||||||
|
. "$HOME/.config/locale.conf"
|
||||||
|
elif [ -r /etc/locale.conf ]; then
|
||||||
|
. /etc/locale.conf
|
||||||
|
fi
|
||||||
|
|
||||||
|
export LANG="${LANG:-C}"
|
||||||
|
[ -n "$LC_CTYPE" ] && export LC_CTYPE
|
||||||
|
[ -n "$LC_NUMERIC" ] && export LC_NUMERIC
|
||||||
|
[ -n "$LC_TIME" ] && export LC_TIME
|
||||||
|
[ -n "$LC_COLLATE" ] && export LC_COLLATE
|
||||||
|
[ -n "$LC_MONETARY" ] && export LC_MONETARY
|
||||||
|
[ -n "$LC_MESSAGES" ] && export LC_MESSAGES
|
||||||
|
[ -n "$LC_PAPER" ] && export LC_PAPER
|
||||||
|
[ -n "$LC_NAME" ] && export LC_NAME
|
||||||
|
[ -n "$LC_ADDRESS" ] && export LC_ADDRESS
|
||||||
|
[ -n "$LC_TELEPHONE" ] && export LC_TELEPHONE
|
||||||
|
[ -n "$LC_MEASUREMENT" ] && export LC_MEASUREMENT
|
||||||
|
[ -n "$LC_IDENTIFICATION" ] && export LC_IDENTIFICATION
|
|
@ -0,0 +1,834 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# initscripts functions
|
||||||
|
#
|
||||||
|
|
||||||
|
# sanitize PATH (will be overridden later when /etc/profile is sourced but is useful for udev)
|
||||||
|
export PATH="/usr/local/bin:/usr/bin"
|
||||||
|
|
||||||
|
# clear the TZ envvar, so daemons always respect /etc/localtime
|
||||||
|
unset TZ
|
||||||
|
|
||||||
|
RANDOM_SEED=/var/lib/misc/random-seed
|
||||||
|
|
||||||
|
[[ -z $LANG ]] && . /etc/profile.d/read_locale.sh
|
||||||
|
|
||||||
|
if [[ $1 == "start" ]]; then
|
||||||
|
if [[ $PARENT_DAEMON ]]; then
|
||||||
|
echo "NOTE: '${0##*/}' started as dependence of '$PARENT_DAEMON' but will be stopped first during shutdown"
|
||||||
|
else
|
||||||
|
export PARENT_DAEMON=${0##*/}
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# width:
|
||||||
|
calc_columns () {
|
||||||
|
STAT_COL=80
|
||||||
|
if [[ ! -t 1 ]]; then
|
||||||
|
USECOLOR=""
|
||||||
|
elif [[ -t 0 ]]; then
|
||||||
|
# stty will fail when stdin isn't a terminal
|
||||||
|
STAT_COL=$(stty size)
|
||||||
|
# stty gives "rows cols"; strip the rows number, we just want columns
|
||||||
|
STAT_COL=${STAT_COL##* }
|
||||||
|
elif tput cols &>/dev/null; then
|
||||||
|
# is /usr/share/terminfo already mounted, and TERM recognized?
|
||||||
|
STAT_COL=$(tput cols)
|
||||||
|
fi
|
||||||
|
if (( STAT_COL == 0 )); then
|
||||||
|
# if output was 0 (serial console), set default width to 80
|
||||||
|
STAT_COL=80
|
||||||
|
USECOLOR=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# we use 13 characters for our own stuff
|
||||||
|
STAT_COL=$(( STAT_COL - 13 ))
|
||||||
|
|
||||||
|
if [[ -t 1 ]]; then
|
||||||
|
SAVE_POSITION="\e[s"
|
||||||
|
RESTORE_POSITION="\e[u"
|
||||||
|
DEL_TEXT="\e[$(( STAT_COL + 4 ))G"
|
||||||
|
else
|
||||||
|
SAVE_POSITION=""
|
||||||
|
RESTORE_POSITION=""
|
||||||
|
DEL_TEXT=""
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
calc_columns
|
||||||
|
|
||||||
|
# disable colors on broken terminals
|
||||||
|
TERM_COLORS=$(tput colors 2>/dev/null)
|
||||||
|
if (( $? != 3 )); then
|
||||||
|
case $TERM_COLORS in
|
||||||
|
*[!0-9]*) USECOLOR="";;
|
||||||
|
[0-7]) USECOLOR="";;
|
||||||
|
'') USECOLOR="";;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
unset TERM_COLORS
|
||||||
|
|
||||||
|
unquote() {
|
||||||
|
local -r quotes=$'[\'"]'
|
||||||
|
|
||||||
|
if [[ ${1:0:1} = $quotes && ${1:(-1)} = "${1:0:1}" ]]; then
|
||||||
|
printf '%s' "${1:1:(-1)}"
|
||||||
|
else
|
||||||
|
printf '%s' "$1"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_envfile() {
|
||||||
|
local file=$1 validkeys=("${@:2}") ret=0 lineno=0 key= val=
|
||||||
|
local -r comments=$'[;#]*'
|
||||||
|
|
||||||
|
if [[ -z $file ]]; then
|
||||||
|
printf "error: no environment file specified\n"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f $file ]]; then
|
||||||
|
printf "error: cannot parse \`%s': No such file or directory\n" "$file"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -r $file ]]; then
|
||||||
|
printf "error: cannot read \`%s': Permission denied\n" "$file"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
while IFS='=' read -r key val; do
|
||||||
|
(( ++lineno ))
|
||||||
|
|
||||||
|
# trim whitespace, avoiding usage of a tempfile
|
||||||
|
key=$(echo "$key" | { read -r key; echo "$key"; })
|
||||||
|
|
||||||
|
# key must exist and line must not be a comment
|
||||||
|
[[ -z $key || ${key:0:1} = $comments ]] && continue
|
||||||
|
|
||||||
|
# trim whitespace, strip matching quotes
|
||||||
|
val=$(echo "$val" | { read -r val; unquote "$val"; })
|
||||||
|
|
||||||
|
if [[ -z $val ]]; then
|
||||||
|
printf "error: found key \`%s' without value on line %s of %s\n" \
|
||||||
|
"$key" "$lineno" "$file"
|
||||||
|
(( ++ret ))
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ignore invalid keys if we have a list of valid ones
|
||||||
|
if (( ${#validkeys[*]} )) && ! in_array "$key" "${validkeys[@]}"; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
export "$key=$val" || (( ++ret ))
|
||||||
|
done <"$file"
|
||||||
|
|
||||||
|
return $ret
|
||||||
|
}
|
||||||
|
|
||||||
|
# functions:
|
||||||
|
|
||||||
|
deltext() {
|
||||||
|
printf "${DEL_TEXT}"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_depr() {
|
||||||
|
printf "${C_FAIL} ${1} is deprecated. See ${2} for details.${C_CLEAR} \n"
|
||||||
|
}
|
||||||
|
|
||||||
|
printhl() {
|
||||||
|
printf "${C_OTHER}${PREFIX_HL} ${C_H1}${1}${C_CLEAR} \n"
|
||||||
|
}
|
||||||
|
|
||||||
|
printsep() {
|
||||||
|
printf "\n${C_SEPARATOR} ------------------------------\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
stat_bkgd() {
|
||||||
|
printf "${C_OTHER}${PREFIX_REG} ${C_MAIN}${1}${C_CLEAR} "
|
||||||
|
deltext
|
||||||
|
printf " ${C_OTHER}[${C_BKGD}BKGD${C_OTHER}]${C_CLEAR} \n"
|
||||||
|
}
|
||||||
|
|
||||||
|
stat_busy() {
|
||||||
|
printf "${C_OTHER}${PREFIX_REG} ${C_MAIN}${1}${C_CLEAR} "
|
||||||
|
printf "${SAVE_POSITION}"
|
||||||
|
deltext
|
||||||
|
printf " ${C_OTHER}[${C_BUSY}BUSY${C_OTHER}]${C_CLEAR} "
|
||||||
|
}
|
||||||
|
|
||||||
|
stat_append() {
|
||||||
|
printf "${RESTORE_POSITION}"
|
||||||
|
printf -- "${C_MAIN}${1}${C_CLEAR}"
|
||||||
|
printf "${SAVE_POSITION}"
|
||||||
|
}
|
||||||
|
|
||||||
|
stat_done() {
|
||||||
|
deltext
|
||||||
|
printf " ${C_OTHER}[${C_DONE}DONE${C_OTHER}]${C_CLEAR} \n"
|
||||||
|
}
|
||||||
|
|
||||||
|
stat_fail() {
|
||||||
|
deltext
|
||||||
|
printf " ${C_OTHER}[${C_FAIL}FAIL${C_OTHER}]${C_CLEAR} \n"
|
||||||
|
}
|
||||||
|
|
||||||
|
stat_die() {
|
||||||
|
stat_fail
|
||||||
|
exit ${1:-1}
|
||||||
|
}
|
||||||
|
|
||||||
|
status() {
|
||||||
|
local quiet
|
||||||
|
case $1 in
|
||||||
|
-q)
|
||||||
|
quiet=1
|
||||||
|
;;&
|
||||||
|
-v)
|
||||||
|
# NOOP: supported for backwards compat
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
stat_busy "$1"
|
||||||
|
shift
|
||||||
|
if (( quiet )); then
|
||||||
|
"$@" &>/dev/null
|
||||||
|
else
|
||||||
|
"$@"
|
||||||
|
fi
|
||||||
|
local ret=$?
|
||||||
|
(( ret == 0 )) && stat_done || stat_fail
|
||||||
|
return $ret
|
||||||
|
}
|
||||||
|
|
||||||
|
# usage : in_array( $needle, $haystack )
|
||||||
|
# return : 0 - found
|
||||||
|
# 1 - not found
|
||||||
|
in_array() {
|
||||||
|
local needle=$1; shift
|
||||||
|
local item
|
||||||
|
for item; do
|
||||||
|
[[ $item = "${needle}" ]] && return 0
|
||||||
|
done
|
||||||
|
return 1 # Not Found
|
||||||
|
}
|
||||||
|
|
||||||
|
# daemons:
|
||||||
|
|
||||||
|
add_daemon() {
|
||||||
|
[[ -d /run/daemons ]] || mkdir -p /run/daemons
|
||||||
|
>| /run/daemons/"$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
rm_daemon() {
|
||||||
|
rm -f /run/daemons/"$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
ck_daemon() {
|
||||||
|
[[ ! -f /run/daemons/$1 ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if $1 is a valid daemon name
|
||||||
|
have_daemon() {
|
||||||
|
if [[ ! -f /etc/rc.d/$1 || ! -x /etc/rc.d/$1 ]]; then
|
||||||
|
printf "error: /etc/rc.d/$1 does not exist or is not executable\n" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if $1 is started at boot
|
||||||
|
ck_autostart() {
|
||||||
|
local daemon
|
||||||
|
for daemon in "${DAEMONS[@]}"; do
|
||||||
|
[[ $1 = "${daemon#@}" ]] && return 1
|
||||||
|
done
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
start_daemon() {
|
||||||
|
have_daemon "$1" && /etc/rc.d/"$1" start
|
||||||
|
}
|
||||||
|
|
||||||
|
start_daemon_bkgd() {
|
||||||
|
stat_bkgd "Starting $1"
|
||||||
|
(start_daemon "$1") >/dev/null &
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_daemon() {
|
||||||
|
have_daemon "$1" && /etc/rc.d/"$1" stop
|
||||||
|
}
|
||||||
|
|
||||||
|
# Status functions
|
||||||
|
status_started() {
|
||||||
|
deltext
|
||||||
|
echo -ne "$C_OTHER[${C_STRT}STARTED$C_OTHER]$C_CLEAR "
|
||||||
|
}
|
||||||
|
|
||||||
|
status_stopped() {
|
||||||
|
deltext
|
||||||
|
echo -ne "$C_OTHER[${C_STRT}STOPPED$C_OTHER]$C_CLEAR "
|
||||||
|
}
|
||||||
|
|
||||||
|
ck_status() {
|
||||||
|
! ck_daemon "$1" && status_started || status_stopped
|
||||||
|
}
|
||||||
|
|
||||||
|
# Return PID of $1
|
||||||
|
get_pid() {
|
||||||
|
pidof -o %PPID $1 || return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if PID-file $1 is still the active PID-file for command $2
|
||||||
|
ck_pidfile() {
|
||||||
|
if [[ -f $1 ]]; then
|
||||||
|
local fpid ppid
|
||||||
|
read -r fpid <"$1"
|
||||||
|
ppid=$(get_pid "$2")
|
||||||
|
[[ $fpid = "${ppid}" ]] && return 0
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# PIDs to be omitted by killall5
|
||||||
|
declare -a omit_pids
|
||||||
|
|
||||||
|
add_omit_pids() {
|
||||||
|
omit_pids+=( $@ )
|
||||||
|
}
|
||||||
|
|
||||||
|
# Stop all daemons
|
||||||
|
# This function should *never* ever perform any other actions beside calling stop_daemon()!
|
||||||
|
# It might be used by a splash system etc. to get a list of daemons to be stopped.
|
||||||
|
stop_all_daemons() {
|
||||||
|
# Find daemons NOT in the DAEMONS array. Shut these down first
|
||||||
|
local daemon
|
||||||
|
for daemon in /run/daemons/*; do
|
||||||
|
[[ -f $daemon ]] || continue
|
||||||
|
daemon=${daemon##*/}
|
||||||
|
ck_autostart "$daemon" && stop_daemon "$daemon"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Shutdown daemons in reverse order
|
||||||
|
local i daemon
|
||||||
|
for (( i=${#DAEMONS[@]}-1; i>=0; i-- )); do
|
||||||
|
[[ ${DAEMONS[i]} = '!'* ]] && continue
|
||||||
|
daemon=${DAEMONS[i]#@}
|
||||||
|
ck_daemon "$daemon" || stop_daemon "$daemon"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1 - signal
|
||||||
|
# $2 - iterations
|
||||||
|
kill_all_wait() {
|
||||||
|
# Send SIGTERM/SIGKILL all processes and wait until killall5
|
||||||
|
# reports all done or timeout.
|
||||||
|
# Unfortunately killall5 does not support the 0 signal, so just
|
||||||
|
# use SIGCONT for checking (which should be ignored).
|
||||||
|
|
||||||
|
local i
|
||||||
|
|
||||||
|
killall5 -${1} ${omit_pids[@]/#/-o } &>/dev/null
|
||||||
|
|
||||||
|
for (( i=0; i<${2}; i++ )); do
|
||||||
|
|
||||||
|
sleep .25 # 1/4 second
|
||||||
|
|
||||||
|
# sending SIGCONT to processes to check if they are there
|
||||||
|
killall5 -18 ${omit_pids[@]/#/-o } &>/dev/null
|
||||||
|
|
||||||
|
if (( $? == 2 )); then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
kill_all() {
|
||||||
|
stat_busy "Sending SIGTERM to processes"
|
||||||
|
kill_all_wait 15 40
|
||||||
|
if (( $? == 0 )); then
|
||||||
|
stat_done
|
||||||
|
else
|
||||||
|
stat_fail
|
||||||
|
status "Sending SIGKILL to processes" kill_all_wait 9 60
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
print_welcome() {
|
||||||
|
# see os-release(5)
|
||||||
|
. /usr/lib/os-release
|
||||||
|
|
||||||
|
echo " "
|
||||||
|
printhl "${PRETTY_NAME}\n"
|
||||||
|
printhl "${C_H2}${HOME_URL}"
|
||||||
|
printsep
|
||||||
|
}
|
||||||
|
|
||||||
|
create_blacklist() {
|
||||||
|
# $* = list of blacklisted modules
|
||||||
|
|
||||||
|
stat_busy "Creating UDev blacklist"
|
||||||
|
|
||||||
|
mkdir -p /run/modprobe.d
|
||||||
|
echo "# Autogenerated from rc.conf at boot, do not edit" > /run/modprobe.d/modprobe-blacklist.conf
|
||||||
|
(( ${#*} )) && printf 'blacklist %s\n' "${*}" >> /run/modprobe.d/modprobe-blacklist.conf
|
||||||
|
|
||||||
|
(( $? == 0 )) && stat_done || stat_fail
|
||||||
|
}
|
||||||
|
|
||||||
|
# Start/trigger udev, load MODULES, and settle udev
|
||||||
|
udevd_modprobe() {
|
||||||
|
# $1 = where we are being called from.
|
||||||
|
# This is used to determine which hooks to run.
|
||||||
|
|
||||||
|
# Modules prefixed with ! should be blacklisted
|
||||||
|
local blacklist=(${MODULES[@]##[^!]*})
|
||||||
|
[[ $blacklist ]] && create_blacklist ${blacklist[@]/!/}
|
||||||
|
|
||||||
|
if [ -x /usr/lib/systemd/systemd-udevd ]; then
|
||||||
|
UDEVD_COMMAND=/usr/lib/systemd/systemd-udevd
|
||||||
|
elif [ -x /usr/bin/udevd ]; then
|
||||||
|
# For future forks with merged /usr/bin
|
||||||
|
UDEVD_COMMAND=/usr/bin/udevd
|
||||||
|
else
|
||||||
|
echo "Unable to find udevd binary"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
status "Starting udev daemon" $UDEVD_COMMAND --daemon
|
||||||
|
|
||||||
|
run_hook "$1_udevlaunched"
|
||||||
|
|
||||||
|
stat_busy "Triggering udev uevents"
|
||||||
|
udevadm trigger --action=add --type=subsystems
|
||||||
|
udevadm trigger --action=add --type=devices
|
||||||
|
stat_done
|
||||||
|
|
||||||
|
# Load modules from the MODULES array or modules-load.d
|
||||||
|
stat_busy "Loading user-specified modules"
|
||||||
|
if (( ${#MODULES[*]} )); then
|
||||||
|
local -a modules=(${MODULES[@]/!*/})
|
||||||
|
|
||||||
|
if [[ ${modules[@]} =~ [^\ ] ]]; then
|
||||||
|
modprobe -ab "${modules[@]}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
/usr/lib/initscripts/arch-modules
|
||||||
|
fi
|
||||||
|
(( $? == 0 )) && stat_done || stat_fail
|
||||||
|
|
||||||
|
status "Waiting for udev uevents to be processed" \
|
||||||
|
udevadm settle
|
||||||
|
|
||||||
|
run_hook "$1_udevsettled"
|
||||||
|
|
||||||
|
# in case loading a module changed the display mode
|
||||||
|
calc_columns
|
||||||
|
}
|
||||||
|
|
||||||
|
set_consolefont() {
|
||||||
|
#CONSOLEMAP in UTF-8 shouldn't be used
|
||||||
|
[[ $CONSOLEMAP && ${LOCALE,,} =~ utf ]] && CONSOLEMAP=""
|
||||||
|
local i
|
||||||
|
for i in /dev/tty[0-9]*; do
|
||||||
|
setfont ${CONSOLEMAP:+-m "${CONSOLEMAP}"} \
|
||||||
|
"$CONSOLEFONT" -C ${i} &>/dev/null
|
||||||
|
done
|
||||||
|
return $?
|
||||||
|
}
|
||||||
|
|
||||||
|
activate_vgs() {
|
||||||
|
[[ $USELVM = [yY][eE][sS] && -x $(type -P lvm) && -d /sys/block ]] || return 0
|
||||||
|
stat_busy "Activating LVM2 groups"
|
||||||
|
vgchange --sysinit -a y >/dev/null
|
||||||
|
(( $? == 0 )) && stat_done || stat_fail
|
||||||
|
}
|
||||||
|
|
||||||
|
do_unlock_legacy() {
|
||||||
|
# $1 = requested name
|
||||||
|
# $2 = source device
|
||||||
|
# $3 = password
|
||||||
|
# $4 = options
|
||||||
|
print_depr "The legacy crypttab format" "crypttab(5)"
|
||||||
|
local open=create a=$1 b=$2 failed=0
|
||||||
|
# Ordering of options is different if you are using LUKS vs. not.
|
||||||
|
# Use ugly swizzling to deal with it.
|
||||||
|
# isLuks only gives an exit code but no output to stdout or stderr.
|
||||||
|
if cryptsetup isLuks "$2" 2>/dev/null; then
|
||||||
|
open=luksOpen
|
||||||
|
a=$2
|
||||||
|
b=$1
|
||||||
|
fi
|
||||||
|
case $3 in
|
||||||
|
SWAP)
|
||||||
|
local _overwriteokay=0
|
||||||
|
if [[ -b $2 && -r $2 ]]; then
|
||||||
|
# This is DANGEROUS! If there is any known file system,
|
||||||
|
# partition table, RAID, or LVM volume on the device,
|
||||||
|
# we don't overwrite it.
|
||||||
|
#
|
||||||
|
# 'blkid' returns 2 if no valid signature has been found.
|
||||||
|
# Only in this case should we allow overwriting the device.
|
||||||
|
#
|
||||||
|
# This sanity check _should_ be sufficient, but it might not.
|
||||||
|
# This may cause data loss if it is not used carefully.
|
||||||
|
blkid -p "$2" &>/dev/null
|
||||||
|
(( $? == 2 )) && _overwriteokay=1
|
||||||
|
fi
|
||||||
|
if (( _overwriteokay == 0 )); then
|
||||||
|
false
|
||||||
|
elif cryptsetup -d /dev/urandom $4 $open "$a" "$b" >/dev/null; then
|
||||||
|
printf "creating swapspace..\n"
|
||||||
|
mkswap -f -L $1 /dev/mapper/$1 >/dev/null
|
||||||
|
fi;;
|
||||||
|
ASK)
|
||||||
|
printf "\nOpening '$1' volume:\n"
|
||||||
|
cryptsetup $4 $open "$a" "$b" < /dev/console;;
|
||||||
|
/dev*)
|
||||||
|
local ckdev=${3%%:*}
|
||||||
|
local cka=${3#*:}
|
||||||
|
local ckb=${cka#*:}
|
||||||
|
local cka=${cka%:*}
|
||||||
|
local ckfile=/dev/ckfile
|
||||||
|
local ckdir=/dev/ckdir
|
||||||
|
case ${cka} in
|
||||||
|
*[!0-9]*)
|
||||||
|
# Use a file on the device
|
||||||
|
# cka is not numeric: cka=filesystem, ckb=path
|
||||||
|
mkdir ${ckdir}
|
||||||
|
mount -r -t ${cka} ${ckdev} ${ckdir}
|
||||||
|
dd if=${ckdir}/${ckb} of=${ckfile} >/dev/null 2>&1
|
||||||
|
umount ${ckdir}
|
||||||
|
rmdir ${ckdir};;
|
||||||
|
*)
|
||||||
|
# Read raw data from the block device
|
||||||
|
# cka is numeric: cka=offset, ckb=length
|
||||||
|
dd if=${ckdev} of=${ckfile} bs=1 skip=${cka} count=${ckb} >/dev/null 2>&1;;
|
||||||
|
esac
|
||||||
|
cryptsetup -d ${ckfile} $4 $open "$a" "$b" >/dev/null
|
||||||
|
dd if=/dev/urandom of=${ckfile} bs=1 count=$(stat -c %s ${ckfile}) conv=notrunc >/dev/null 2>&1
|
||||||
|
rm ${ckfile};;
|
||||||
|
/*)
|
||||||
|
cryptsetup -d "$3" $4 $open "$a" "$b" >/dev/null;;
|
||||||
|
*)
|
||||||
|
echo "$3" | cryptsetup $4 $open "$a" "$b" >/dev/null;;
|
||||||
|
esac
|
||||||
|
return $?
|
||||||
|
}
|
||||||
|
|
||||||
|
do_unlock_systemd() {
|
||||||
|
local name=$1 device=$2 password=$3 options=$4 failed=0
|
||||||
|
|
||||||
|
if [ ! -x /usr/lib/systemd/systemd-cryptsetup ]; then
|
||||||
|
echo "Unable to find systemd-cryptsetup binary"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# lazily convert tags to udev symlinks
|
||||||
|
case $device in
|
||||||
|
UUID=*)
|
||||||
|
device=/dev/disk/by-uuid/$(unquote "${device#UUID=}")
|
||||||
|
;;
|
||||||
|
PARTUUID=*)
|
||||||
|
device=/dev/disk/by-partuuid/$(unquote "${device#PARTUUID=}")
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if ! /usr/lib/systemd/systemd-cryptsetup attach "$name" "$device" "$password" $options; then
|
||||||
|
failed=1
|
||||||
|
else
|
||||||
|
options=${options//,/ }
|
||||||
|
if in_array swap ${options[@]}; then
|
||||||
|
# create swap on the device only if no fs signature exists
|
||||||
|
blkid -p "$2" &>/dev/null
|
||||||
|
if (( $? != 2 )) || ! mkswap -f /dev/mapper/$name >/dev/null; then
|
||||||
|
failed=1
|
||||||
|
fi
|
||||||
|
elif in_array tmp ${options[@]}; then
|
||||||
|
# create fs on the device only if no fs signature exists
|
||||||
|
blkid -p "$2" &>/dev/null
|
||||||
|
if (( $? != 2 )) || ! mke2fs /dev/mapper/$name >/dev/null; then
|
||||||
|
failed=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
return $failed
|
||||||
|
}
|
||||||
|
|
||||||
|
do_unlock() {
|
||||||
|
local name=$1 device=$2 password=$3 options=$4
|
||||||
|
|
||||||
|
printf "${C_MAIN}Unlocking $1${C_CLEAR}\n"
|
||||||
|
|
||||||
|
if [[ ${options:0:2} =~ -. ]]; then
|
||||||
|
do_unlock_legacy "$name" "$device" "$password" "$options"
|
||||||
|
return $?
|
||||||
|
fi
|
||||||
|
|
||||||
|
case $password in
|
||||||
|
ASK|SWAP)
|
||||||
|
do_unlock_legacy "$name" "$device" "$password" "$options"
|
||||||
|
;;
|
||||||
|
/dev/*)
|
||||||
|
if [[ ${password##*:} == $password ]]; then
|
||||||
|
do_unlock_systemd "$name" "$device" "$password" "$options"
|
||||||
|
else
|
||||||
|
do_unlock_legacy "$name" "$device" "$password" "$options"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
/*|none|-|'')
|
||||||
|
do_unlock_systemd "$name" "$device" "$password" "$options"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
do_unlock_legacy "$name" "$device" "$password" "$options"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
failed=$?
|
||||||
|
if (( $failed )); then
|
||||||
|
printf "${C_FAIL}Unlocking of $1 failed.${C_CLEAR}\n"
|
||||||
|
fi
|
||||||
|
return $?
|
||||||
|
}
|
||||||
|
|
||||||
|
do_lock() {
|
||||||
|
#status "Detaching encrypted device ${1}" /usr/lib/systemd/systemd-cryptsetup detach "$1" >/dev/null
|
||||||
|
stat_busy "Detaching encrypted device ${1}"
|
||||||
|
if [ -x /usr/lib/systemd/systemd-cryptsetup ]; then
|
||||||
|
/usr/lib/systemd/systemd-cryptsetup detach "$1" >/dev/null
|
||||||
|
else
|
||||||
|
cryptsetup remove "$1" &>/dev/null
|
||||||
|
fi
|
||||||
|
(( $? == 0 )) && stat_done || stat_fail
|
||||||
|
}
|
||||||
|
|
||||||
|
read_crypttab() {
|
||||||
|
# $1 = function to call with the split out line from the crypttab
|
||||||
|
local line nspo failed=0
|
||||||
|
while read line <&3; do
|
||||||
|
[[ $line && $line != '#'* ]] || continue
|
||||||
|
eval nspo=("${line%#*}")
|
||||||
|
if $1 "${nspo[0]}" "${nspo[1]}" "${nspo[2]}" "${nspo[*]:3}"; then
|
||||||
|
crypto_unlocked=1
|
||||||
|
else
|
||||||
|
failed=1
|
||||||
|
fi
|
||||||
|
done 3< /etc/crypttab
|
||||||
|
return $failed
|
||||||
|
}
|
||||||
|
|
||||||
|
set_timezone() {
|
||||||
|
local tz=$1 zonefile=/usr/share/zoneinfo/$1
|
||||||
|
|
||||||
|
[[ $tz ]] || return 1
|
||||||
|
|
||||||
|
if [[ ! -e $zonefile ]]; then
|
||||||
|
printf "error: \`%s' is not a valid time zone\n" "$tz"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -L /etc/localtime && /etc/localtime -ef $zonefile ]]; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
ln -sf "/usr/share/zoneinfo/$tz" /etc/localtime
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Filesystem functions
|
||||||
|
# These can be overridden/reused for customizations like shutdown/loop-fsck.
|
||||||
|
NETFS="nfs,nfs4,smbfs,cifs,codafs,ncpfs,shfs,fuse,fuseblk,glusterfs,davfs,fuse.glusterfs"
|
||||||
|
|
||||||
|
# Check local filesystems
|
||||||
|
fsck_all() {
|
||||||
|
if [[ -f /forcefsck ]] || in_array forcefsck $(< /proc/cmdline); then
|
||||||
|
FORCEFSCK="-f"
|
||||||
|
elif [[ -f /fastboot ]] || in_array fastboot $(< /proc/cmdline); then
|
||||||
|
return 0
|
||||||
|
elif findmnt / --options rw &>/dev/null; then
|
||||||
|
IGNORE_MOUNTED="-M"
|
||||||
|
fi
|
||||||
|
|
||||||
|
fsck -A -T -C${FSCK_FD} -a -t no${NETFS//,/,no},noopts=_netdev ${IGNORE_MOUNTED} -- ${FORCEFSCK}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Single-user login and/or automatic reboot after fsck (if needed)
|
||||||
|
fsck_reboot() {
|
||||||
|
# $1 = exit code returned by fsck
|
||||||
|
# Ignore conditions 'FS errors corrected' and 'Cancelled by the user'
|
||||||
|
(( ($1 | 33) == 33 )) && return 0
|
||||||
|
if (( $1 & 2 )); then
|
||||||
|
echo
|
||||||
|
echo "********************** REBOOT REQUIRED *********************"
|
||||||
|
echo "* *"
|
||||||
|
echo "* The system will be rebooted automatically in 15 seconds. *"
|
||||||
|
echo "* *"
|
||||||
|
echo "************************************************************"
|
||||||
|
echo
|
||||||
|
sleep 15
|
||||||
|
else
|
||||||
|
echo
|
||||||
|
echo "***************** FILESYSTEM CHECK FAILED ****************"
|
||||||
|
echo "* *"
|
||||||
|
echo "* Please repair manually and reboot. Note that the root *"
|
||||||
|
echo "* file system is currently mounted read-only. To remount *"
|
||||||
|
echo "* it read-write, type: mount -o remount,rw / *"
|
||||||
|
echo "* When you exit the maintenance shell, the system will *"
|
||||||
|
echo "* reboot automatically. *"
|
||||||
|
echo "* *"
|
||||||
|
echo "************************************************************"
|
||||||
|
echo
|
||||||
|
sulogin -p
|
||||||
|
fi
|
||||||
|
echo "Automatic reboot in progress..."
|
||||||
|
umount -a
|
||||||
|
mount -o remount,ro /
|
||||||
|
reboot -f
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
mount_all() {
|
||||||
|
mount -a -t "no${NETFS//,/,no}" -O no_netdev
|
||||||
|
}
|
||||||
|
|
||||||
|
umount_all() {
|
||||||
|
# $1: restrict to fstype
|
||||||
|
|
||||||
|
findmnt -mrunRo TARGET,FSTYPE,OPTIONS / | {
|
||||||
|
while read -r target fstype options; do
|
||||||
|
# match only targeted fstypes
|
||||||
|
if [[ $1 && $1 != "$fstype" ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# do not unmount API filesystems
|
||||||
|
if [[ $target = /@(proc|sys|run|dev|dev/pts) ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# avoid networked devices
|
||||||
|
IFS=, read -ra opts <<< "$options"
|
||||||
|
if in_array _netdev "${opts[@]}"; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
mounts=("$target" "${mounts[@]}")
|
||||||
|
done
|
||||||
|
|
||||||
|
if (( ${#mounts[*]} )); then
|
||||||
|
umount -r "${mounts[@]}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
remove_leftover() {
|
||||||
|
status 'Removing leftover files' /usr/lib/initscripts/arch-tmpfiles --create --remove --clean --boot
|
||||||
|
}
|
||||||
|
|
||||||
|
bootlogd_stop() {
|
||||||
|
[[ -f /run/bootlogd.pid ]] || return 0
|
||||||
|
touch /var/log/boot
|
||||||
|
kill $(< /run/bootlogd.pid)
|
||||||
|
rm -f /run/bootlogd.pid
|
||||||
|
}
|
||||||
|
|
||||||
|
###############################
|
||||||
|
# Custom hooks in initscripts #
|
||||||
|
###############################
|
||||||
|
# Hooks can be used to include custom code in various places in the rc.* scripts
|
||||||
|
#
|
||||||
|
# To define a hook function, create a file with any name in functions.d containing:
|
||||||
|
# function_name() {
|
||||||
|
# ...
|
||||||
|
# }
|
||||||
|
# add_hook hook_name function_name
|
||||||
|
# It is allowed to register several hook functions for the same hook
|
||||||
|
# Is is also allowed to register the same hook function for several hooks
|
||||||
|
#
|
||||||
|
# Functions can be created for the following hooks:
|
||||||
|
# sysinit_start: at the beginning of rc.sysinit
|
||||||
|
# multi_start: at the beginning of rc.multi
|
||||||
|
# single_start: at the beginning of rc.single
|
||||||
|
# shutdown_start: at the beginning of rc.shutdown
|
||||||
|
# sysinit_end: at the end of rc.sysinit
|
||||||
|
# multi_end: at the end of rc.multi
|
||||||
|
# single_end: at the end of rc.single
|
||||||
|
# sysinit_udevlaunched: after udev has been launched in rc.sysinit (called from functions)
|
||||||
|
# single_udevlaunched: after udev has been launched in rc.single (called from functions)
|
||||||
|
# sysinit_udevsettled: after uevents have settled in rc.sysinit (called from functions)
|
||||||
|
# single_udevsettled: after uevents have settled in rc.single (called from functions)
|
||||||
|
# sysinit_prefsck: before local filesystems are checked in rc.sysinit
|
||||||
|
# sysinit_postfsck: after local filesystems are checked in rc.sysinit
|
||||||
|
# sysinit_premount: before local filesystems are mounted, but after root is mounted read-write in rc.sysinit
|
||||||
|
# sysinit_postmount: after local filesystems are mounted in rc.sysinit
|
||||||
|
# shutdown_prekillall: before all processes are being killed in rc.shutdown
|
||||||
|
# single_prekillall: before all processes are being killed in rc.single
|
||||||
|
# shutdown_postkillall: after all processes have been killed in rc.shutdown
|
||||||
|
# single_postkillall: after all processes have been killed in rc.single
|
||||||
|
# shutdown_preumount: after last filesystem write, but before filesystems are unmounted in rc.shutdown
|
||||||
|
# shutdown_postumount: after filesystems are unmounted in rc.shutdown
|
||||||
|
# shutdown_poweroff: directly before powering off in rc.shutdown
|
||||||
|
#
|
||||||
|
# Declare add_hook and run_hook as read-only to prevent overwriting them.
|
||||||
|
# Too bad we cannot do the same thing with hook_funcs
|
||||||
|
|
||||||
|
if (( RC_FUNCTIONS_HOOK_FUNCS_DEFINED != 1 )); then
|
||||||
|
declare -A hook_funcs
|
||||||
|
|
||||||
|
add_hook() {
|
||||||
|
[[ $1 && $2 ]] || return 1
|
||||||
|
hook_funcs[$1]+=" $2"
|
||||||
|
}
|
||||||
|
|
||||||
|
run_hook() {
|
||||||
|
[[ $1 ]] || return 1
|
||||||
|
local func
|
||||||
|
for func in ${hook_funcs["$1"]}; do
|
||||||
|
"${func}"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
declare -fr add_hook run_hook
|
||||||
|
declare -r RC_FUNCTIONS_HOOK_FUNCS_DEFINED=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# set colors
|
||||||
|
if [[ $USECOLOR != [nN][oO] ]]; then
|
||||||
|
if tput setaf 0 &>/dev/null; then
|
||||||
|
C_CLEAR=$(tput sgr0) # clear text
|
||||||
|
C_MAIN=${C_CLEAR}$(tput bold) # main text
|
||||||
|
C_OTHER=${C_MAIN}$(tput setaf 4) # prefix & brackets
|
||||||
|
C_SEPARATOR=${C_MAIN}$(tput setaf 0) # separator
|
||||||
|
C_BUSY=${C_CLEAR}$(tput setaf 6) # busy
|
||||||
|
C_FAIL=${C_MAIN}$(tput setaf 1) # failed
|
||||||
|
C_DONE=${C_MAIN} # completed
|
||||||
|
C_BKGD=${C_MAIN}$(tput setaf 5) # backgrounded
|
||||||
|
C_H1=${C_MAIN} # highlight text 1
|
||||||
|
C_H2=${C_MAIN}$(tput setaf 6) # highlight text 2
|
||||||
|
else
|
||||||
|
C_CLEAR="\e[m" # clear text
|
||||||
|
C_MAIN="\e[;1m" # main text
|
||||||
|
C_OTHER="\e[1;34m" # prefix & brackets
|
||||||
|
C_SEPARATOR="\e[1;30m" # separator
|
||||||
|
C_BUSY="\e[;36m" # busy
|
||||||
|
C_FAIL="\e[1;31m" # failed
|
||||||
|
C_DONE=${C_MAIN} # completed
|
||||||
|
C_BKGD="\e[1;35m" # backgrounded
|
||||||
|
C_H1=${C_MAIN} # highlight text 1
|
||||||
|
C_H2="\e[1;36m" # highlight text 2
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# prefixes:
|
||||||
|
|
||||||
|
PREFIX_REG="::"
|
||||||
|
PREFIX_HL=" >"
|
||||||
|
|
||||||
|
# Source additional functions at the end to allow overrides
|
||||||
|
for f in /etc/rc.d/functions.d/*; do
|
||||||
|
[[ -e $f ]] && . "$f"
|
||||||
|
done
|
||||||
|
|
||||||
|
# End of file
|
||||||
|
# vim: set ts=2 sw=2 noet:
|
|
@ -0,0 +1,6 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# /etc/rc.local: Local multi-user start-up script.
|
||||||
|
#
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# /etc/rc.local.shutdown: Local shutdown script.
|
||||||
|
#
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# /etc/rc.multi
|
||||||
|
#
|
||||||
|
|
||||||
|
. /etc/rc.conf
|
||||||
|
. /etc/rc.d/functions
|
||||||
|
|
||||||
|
run_hook multi_start
|
||||||
|
|
||||||
|
# Load sysctl config files
|
||||||
|
status "Configuring kernel parameters" sysctl -q --system
|
||||||
|
|
||||||
|
# Load additional binary formats
|
||||||
|
status "Configure additional binary formats" /usr/lib/initscripts/arch-binfmt
|
||||||
|
|
||||||
|
# Start daemons
|
||||||
|
for daemon in "${DAEMONS[@]}"; do
|
||||||
|
case ${daemon:0:1} in
|
||||||
|
'!') continue;; # Skip this daemon.
|
||||||
|
'@') start_daemon_bkgd "${daemon#@}";;
|
||||||
|
*) start_daemon "$daemon";;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
[[ -x /etc/rc.local ]] && /etc/rc.local
|
||||||
|
|
||||||
|
run_hook multi_end
|
||||||
|
|
||||||
|
bootlogd_stop
|
||||||
|
|
||||||
|
rm -f /run/nologin
|
||||||
|
|
||||||
|
# vim: set ts=2 sw=2 noet:
|
|
@ -0,0 +1,142 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# /etc/rc.shutdown
|
||||||
|
#
|
||||||
|
|
||||||
|
. /etc/rc.conf
|
||||||
|
. /etc/rc.d/functions
|
||||||
|
|
||||||
|
# don't let all the systemd tools be too verbose
|
||||||
|
export SYSTEMD_LOG_LEVEL="notice"
|
||||||
|
|
||||||
|
# avoid staircase effect
|
||||||
|
stty onlcr
|
||||||
|
|
||||||
|
echo " "
|
||||||
|
printhl "Initiating shutdown..."
|
||||||
|
echo " "
|
||||||
|
|
||||||
|
run_hook shutdown_start
|
||||||
|
|
||||||
|
[[ -x /etc/rc.local.shutdown ]] && /etc/rc.local.shutdown
|
||||||
|
|
||||||
|
stop_all_daemons
|
||||||
|
|
||||||
|
#status 'Saving random seed' /usr/lib/systemd/systemd-random-seed save
|
||||||
|
stat_busy "Saving Random Seed"
|
||||||
|
RANDOM_SEED=/var/lib/misc/random-seed
|
||||||
|
install -TDm 0600 /dev/null $RANDOM_SEED
|
||||||
|
POOL_FILE=/proc/sys/kernel/random/poolsize
|
||||||
|
if [[ -r $POOL_FILE ]]; then
|
||||||
|
read POOL_SIZE < $POOL_FILE
|
||||||
|
(( POOL_SIZE /= 8 ))
|
||||||
|
else
|
||||||
|
POOL_SIZE=512
|
||||||
|
fi
|
||||||
|
dd if=/dev/urandom of=$RANDOM_SEED count=1 bs=$POOL_SIZE &>/dev/null
|
||||||
|
stat_done
|
||||||
|
|
||||||
|
[[ $TIMEZONE ]] && status "Configuring time zone" set_timezone "$TIMEZONE"
|
||||||
|
|
||||||
|
# Write to wtmp file before unmounting
|
||||||
|
halt -w
|
||||||
|
|
||||||
|
# stop monitoring of LVM2 groups before unmounting filesystems
|
||||||
|
[[ $USELVM = [Yy][Ee][Ss] && -x $(type -P lvm) ]] &&
|
||||||
|
status "Deactivating monitoring of LVM2 groups" vgchange --monitor n
|
||||||
|
|
||||||
|
# any future uevents can and should be ignored
|
||||||
|
status "Shutting down udev" udevadm control --exit
|
||||||
|
|
||||||
|
run_hook shutdown_prekillall
|
||||||
|
|
||||||
|
kill_all
|
||||||
|
|
||||||
|
run_hook shutdown_postkillall
|
||||||
|
|
||||||
|
run_hook shutdown_preumount
|
||||||
|
|
||||||
|
# unmount any non-API partitions that are backed by swap; we don't want to
|
||||||
|
# move their contents into memory (waste of time and might caues OOM).
|
||||||
|
status "Unmounting swap-backed filesystems" umount_all "tmpfs"
|
||||||
|
|
||||||
|
# almost everything is dead now, so the swap should hopefully be relatively
|
||||||
|
# empty, and quick to switch off
|
||||||
|
status "Deactivating swap" swapoff -a
|
||||||
|
|
||||||
|
status "Unmounting non-API filesystems" umount_all
|
||||||
|
|
||||||
|
run_hook shutdown_postumount
|
||||||
|
|
||||||
|
# Kill non-root encrypted partition mappings
|
||||||
|
if [[ -f /etc/crypttab ]] && type -p cryptsetup >/dev/null; then
|
||||||
|
# Maybe someone has LVM on an encrypted block device
|
||||||
|
# executing an extra vgchange is errorless
|
||||||
|
[[ $USELVM = [Yy][Ee][Ss] ]] && vgchange --sysinit -a n &>/dev/null
|
||||||
|
read_crypttab do_lock
|
||||||
|
fi
|
||||||
|
|
||||||
|
[[ $USELVM = [Yy][Ee][Ss] && -x $(type -P lvm) ]] &&
|
||||||
|
status "Deactivating LVM2 groups" vgchange --sysinit -a n &>/dev/null
|
||||||
|
|
||||||
|
run_hook shutdown_poweroff
|
||||||
|
|
||||||
|
if [[ -x /run/initramfs/shutdown ]]; then
|
||||||
|
|
||||||
|
# decide what we want to do
|
||||||
|
if [[ $RUNLEVEL = 0 ]]; then
|
||||||
|
action="poweroff"
|
||||||
|
else
|
||||||
|
{ read kexec_loaded </sys/kernel/kexec_loaded; } 2>/dev/null
|
||||||
|
if (( kexec_loaded )); then
|
||||||
|
action="kexec"
|
||||||
|
else
|
||||||
|
action="reboot"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# make /run/initramfs a mount
|
||||||
|
mount --bind /run/initramfs /run/initramfs
|
||||||
|
|
||||||
|
# in case someone has shared our mountpoints, unshare them
|
||||||
|
mount --make-private /run/initramfs
|
||||||
|
mount --make-private /
|
||||||
|
|
||||||
|
# bind all API mounts
|
||||||
|
mkdir -p /run/initramfs/{sys,proc,dev,run,oldroot}
|
||||||
|
mount --bind /sys /run/initramfs/sys
|
||||||
|
mount --bind /proc /run/initramfs/proc
|
||||||
|
mount --bind /dev /run/initramfs/dev
|
||||||
|
mount --bind /run /run/initramfs/run
|
||||||
|
|
||||||
|
# enter shutdownramfs
|
||||||
|
cd /run/initramfs
|
||||||
|
pivot_root . oldroot
|
||||||
|
|
||||||
|
# reexec init
|
||||||
|
/oldroot/usr/bin/init u
|
||||||
|
|
||||||
|
# run /shutdown in the new root
|
||||||
|
exec chroot . /shutdown $action </dev/console >/dev/console 2>&1
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
status "Remounting root filesystem read-only" \
|
||||||
|
mount -o remount,ro /
|
||||||
|
|
||||||
|
# Power off or reboot
|
||||||
|
printsep
|
||||||
|
if [[ $RUNLEVEL = 0 ]]; then
|
||||||
|
printhl "${C_H2}POWER OFF"
|
||||||
|
poweroff -d -f -h -i
|
||||||
|
else
|
||||||
|
printhl "${C_H2}REBOOTING"
|
||||||
|
# if kexec is installed and a kernel is loaded, use it
|
||||||
|
[[ -x $(type -P kexec) ]] && kexec -e &>/dev/null
|
||||||
|
reboot -d -f -i
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# End of file
|
||||||
|
# vim: set ts=2 sw=2 noet:
|
|
@ -0,0 +1,41 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# /etc/rc.single: Single-user start-up script.
|
||||||
|
#
|
||||||
|
|
||||||
|
. /etc/rc.conf
|
||||||
|
. /etc/rc.d/functions
|
||||||
|
|
||||||
|
run_hook single_start
|
||||||
|
|
||||||
|
if [[ $PREVLEVEL != N ]]; then
|
||||||
|
|
||||||
|
stop_all_daemons
|
||||||
|
|
||||||
|
run_hook single_prekillall
|
||||||
|
|
||||||
|
kill_all
|
||||||
|
|
||||||
|
run_hook single_postkillall
|
||||||
|
|
||||||
|
# Start/trigger udev, load MODULES, and settle udev
|
||||||
|
udevd_modprobe single
|
||||||
|
|
||||||
|
# Removing leftover files
|
||||||
|
remove_leftover
|
||||||
|
fi
|
||||||
|
|
||||||
|
run_hook single_end
|
||||||
|
|
||||||
|
bootlogd_stop
|
||||||
|
|
||||||
|
if [[ $RUNLEVEL = 1 ]]; then
|
||||||
|
printsep
|
||||||
|
printhl "Entering single-user mode..."
|
||||||
|
# make sure /dev/initctl is in place
|
||||||
|
kill -HUP 1
|
||||||
|
exec init -t1 S
|
||||||
|
fi
|
||||||
|
|
||||||
|
# End of file
|
||||||
|
# vim: set ts=2 sw=2 noet:
|
|
@ -0,0 +1,195 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# /etc/rc.sysinit
|
||||||
|
#
|
||||||
|
|
||||||
|
unset HOSTNAME
|
||||||
|
|
||||||
|
. /etc/rc.conf
|
||||||
|
. /etc/rc.d/functions
|
||||||
|
|
||||||
|
LOCALE="$LANG"
|
||||||
|
LANG=C LC_ALL=C
|
||||||
|
|
||||||
|
if [[ -z $HOSTNAME && -s /etc/hostname ]]; then
|
||||||
|
HOSTNAME=$(< /etc/hostname)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# don't let all the systemd tools be too verbose
|
||||||
|
export SYSTEMD_LOG_LEVEL="notice"
|
||||||
|
|
||||||
|
# Prints distro name and URL
|
||||||
|
print_welcome
|
||||||
|
|
||||||
|
# mount the API filesystems
|
||||||
|
# /proc, /sys, /run, /dev, /run/lock, /dev/pts, /dev/shm
|
||||||
|
mountpoint -q /proc || mount -t proc proc /proc -o nosuid,noexec,nodev
|
||||||
|
mountpoint -q /sys || mount -t sysfs sys /sys -o nosuid,noexec,nodev
|
||||||
|
mountpoint -q /run || mount -t tmpfs run /run -o mode=0755,nosuid,nodev
|
||||||
|
mountpoint -q /dev || mount -t devtmpfs dev /dev -o mode=0755,nosuid
|
||||||
|
mkdir -p /dev/{pts,shm}
|
||||||
|
mountpoint -q /dev/pts || mount /dev/pts &>/dev/null || mount -t devpts devpts /dev/pts -o mode=0620,gid=5,nosuid,noexec
|
||||||
|
mountpoint -q /dev/shm || mount /dev/shm &>/dev/null || mount -t tmpfs shm /dev/shm -o mode=1777,nosuid,nodev
|
||||||
|
|
||||||
|
# log all console messages
|
||||||
|
bootlogd -p /run/bootlogd.pid
|
||||||
|
|
||||||
|
run_hook sysinit_start
|
||||||
|
|
||||||
|
if [[ $HOSTNAME ]]; then
|
||||||
|
stat_busy "Setting hostname: $HOSTNAME"
|
||||||
|
echo "$HOSTNAME" >| /proc/sys/kernel/hostname && stat_done || stat_fail
|
||||||
|
fi
|
||||||
|
|
||||||
|
HWCLOCK_PARAMS="--systz"
|
||||||
|
|
||||||
|
if [[ $HARDWARECLOCK ]]; then
|
||||||
|
|
||||||
|
[[ -f /etc/adjtime ]] && { read ; read ; read ADJTIME; } < /etc/adjtime
|
||||||
|
|
||||||
|
if [[ $ADJTIME == 'LOCAL' ]]; then
|
||||||
|
if [[ $HARDWARECLOCK == 'UTC' ]]; then
|
||||||
|
printf "${C_FAIL}/etc/rc.conf says the RTC is in UTC, but /etc/adjtime says it is in localtime.\n${C_OTHER}."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [[ $HARDWARECLOCK == 'LOCALTIME' ]]; then
|
||||||
|
printf "${C_FAIL}/etc/rc.conf says the RTC is in localtime, but hwclock (/etc/adjtime) thinks it is in UTC.\n${C_OTHER}."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
case $HARDWARECLOCK in
|
||||||
|
UTC) HWCLOCK_PARAMS+=" --utc --noadjfile";;
|
||||||
|
localtime) HWCLOCK_PARAMS+=" --localtime --noadjfile";;
|
||||||
|
*) HWCLOCK_PARAMS="";;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $HWCLOCK_PARAMS ]]; then
|
||||||
|
stat_busy "Adjusting system time and setting kernel time zone"
|
||||||
|
|
||||||
|
# Adjust the system time for time zone offset if rtc is not in UTC, as
|
||||||
|
# filesystem checks can depend on system time. This also sets the kernel
|
||||||
|
# time zone, used by e.g. vfat.
|
||||||
|
|
||||||
|
if [[ $TIMEZONE ]]; then
|
||||||
|
export TZ=$TIMEZONE
|
||||||
|
fi
|
||||||
|
|
||||||
|
hwclock $HWCLOCK_PARAMS && stat_done || stat_fail
|
||||||
|
|
||||||
|
unset TZ
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Start/trigger udev, load MODULES, and settle udev
|
||||||
|
udevd_modprobe sysinit
|
||||||
|
|
||||||
|
# this must be done after udev has loaded the KMS modules
|
||||||
|
#status 'Configuring virtual consoles' /usr/lib/systemd/systemd-vconsole-setup
|
||||||
|
if [[ ${LOCALE,,} =~ utf || $LOCALE == C ]]; then
|
||||||
|
stat_busy "Setting Consoles to UTF-8 mode"
|
||||||
|
# UTF-8 consoles are default since 2.6.24 kernel
|
||||||
|
# this code is needed not only for older kernels,
|
||||||
|
# but also when user has set vt.default_utf8=0 but LOCALE is *.UTF-8.
|
||||||
|
for i in /dev/tty[0-9]*; do
|
||||||
|
kbd_mode -u -C ${i}
|
||||||
|
printf "\e%%G" > ${i}
|
||||||
|
done
|
||||||
|
echo 1 >| /sys/module/vt/parameters/default_utf8
|
||||||
|
stat_done
|
||||||
|
else
|
||||||
|
stat_busy "Setting Consoles to legacy mode"
|
||||||
|
# make non-UTF-8 consoles work on 2.6.24 and newer kernels
|
||||||
|
for i in /dev/tty[0-9]*; do
|
||||||
|
kbd_mode -a -C ${i}
|
||||||
|
printf "\e%%@" > ${i}
|
||||||
|
done
|
||||||
|
echo 0 >| /sys/module/vt/parameters/default_utf8
|
||||||
|
stat_done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z $CONSOLEFONT && -z $CONSOLEMAP && -s /etc/vconsole.conf ]]; then
|
||||||
|
parse_envfile /etc/vconsole.conf "${vconsolevars[@]}"
|
||||||
|
[[ $FONT ]] && CONSOLEFONT=$FONT
|
||||||
|
[[ $FONT_MAP ]] && CONSOLEMAP=$FONT_MAP
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set console font and keymap if required
|
||||||
|
[[ $CONSOLEFONT ]] &&
|
||||||
|
status "Loading Console Font: $CONSOLEFONT" set_consolefont
|
||||||
|
[[ $KEYMAP ]] &&
|
||||||
|
status "Loading Keyboard Map: $KEYMAP" loadkeys -q $KEYMAP
|
||||||
|
|
||||||
|
# bring up the loopback interface
|
||||||
|
[[ -d /sys/class/net/lo ]] &&
|
||||||
|
status "Bringing up loopback interface" ip link set up dev lo
|
||||||
|
|
||||||
|
# FakeRAID devices detection
|
||||||
|
[[ $USEDMRAID = [Yy][Ee][Ss] && -x $(type -P dmraid) ]] &&
|
||||||
|
status "Activating FakeRAID arrays" dmraid -i -ay
|
||||||
|
|
||||||
|
# Activate LVM2 groups, if any
|
||||||
|
activate_vgs
|
||||||
|
|
||||||
|
# Set up non-root encrypted partition mappings
|
||||||
|
if [[ -f /etc/crypttab ]] && type -p cryptsetup >/dev/null; then
|
||||||
|
read_crypttab do_unlock
|
||||||
|
# Maybe someone has LVM on an encrypted block device
|
||||||
|
activate_vgs
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check filesystems
|
||||||
|
run_hook sysinit_prefsck
|
||||||
|
if [[ -x $(type -P fsck) ]]; then
|
||||||
|
stat_busy "Checking filesystems"
|
||||||
|
fsck_all >|"${FSCK_OUT:-/dev/stdout}" 2>|"${FSCK_ERR:-/dev/stdout}"
|
||||||
|
declare -r fsckret=$?
|
||||||
|
(( fsckret <= 1 )) && stat_done || stat_fail
|
||||||
|
else
|
||||||
|
declare -r fsckret=0
|
||||||
|
fi
|
||||||
|
run_hook sysinit_postfsck
|
||||||
|
|
||||||
|
# Single-user login and/or automatic reboot if needed
|
||||||
|
fsck_reboot $fsckret
|
||||||
|
|
||||||
|
#status "Remounting root and API filesystems" \
|
||||||
|
# /usr/lib/systemd/systemd-remount-fs
|
||||||
|
status "Remounting Root" \
|
||||||
|
mount -o remount /
|
||||||
|
|
||||||
|
# Now mount all the local filesystems
|
||||||
|
run_hook sysinit_premount
|
||||||
|
status "Mounting local filesystems" \
|
||||||
|
mount_all
|
||||||
|
run_hook sysinit_postmount
|
||||||
|
|
||||||
|
# Enable monitoring of LVM2 groups, now that the filesystems are mounted rw
|
||||||
|
[[ $USELVM = [Yy][Ee][Ss] && -x $(type -P lvm) && -d /sys/block ]] &&
|
||||||
|
status "Activating monitoring of LVM2 groups" \
|
||||||
|
vgchange --monitor y >/dev/null
|
||||||
|
|
||||||
|
status "Activating swap" swapon -a
|
||||||
|
|
||||||
|
[[ $TIMEZONE ]] && status "Configuring time zone" set_timezone "$TIMEZONE"
|
||||||
|
|
||||||
|
#status 'Initializing random seed' /usr/lib/systemd/systemd-random-seed load
|
||||||
|
[[ -f $RANDOM_SEED ]] &&
|
||||||
|
status "Initializing Random Seed" \
|
||||||
|
cp $RANDOM_SEED /dev/urandom
|
||||||
|
|
||||||
|
# Remove leftover files
|
||||||
|
remove_leftover
|
||||||
|
|
||||||
|
stat_busy "Saving dmesg log"
|
||||||
|
if [[ -e /proc/sys/kernel/dmesg_restrict ]] &&
|
||||||
|
(( $(< /proc/sys/kernel/dmesg_restrict) == 1 )); then
|
||||||
|
install -Tm 0600 <( dmesg ) /var/log/dmesg.log
|
||||||
|
else
|
||||||
|
install -Tm 0644 <( dmesg ) /var/log/dmesg.log
|
||||||
|
fi
|
||||||
|
(( $? == 0 )) && stat_done || stat_fail
|
||||||
|
|
||||||
|
run_hook sysinit_end
|
||||||
|
|
||||||
|
# End of file
|
||||||
|
# vim: set ts=2 sw=2 noet:
|
|
@ -0,0 +1,46 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# /usr/lib/initscripts/arch-binfmt
|
||||||
|
#
|
||||||
|
# Configure additional binary formats at boot
|
||||||
|
#
|
||||||
|
|
||||||
|
shopt -s nullglob
|
||||||
|
|
||||||
|
declare -a binfmt_d
|
||||||
|
# files given has argv supersede config files
|
||||||
|
if (( $# > 0 )); then
|
||||||
|
for arg; do [[ -r "$arg" ]] && binfmt_d+=("$arg"); done
|
||||||
|
else
|
||||||
|
binfmt_d=(
|
||||||
|
/usr/lib/binfmt.d/*.conf
|
||||||
|
/etc/binfmt.d/*.conf
|
||||||
|
/run/binfmt.d/*.conf
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check there is file to load
|
||||||
|
(( ${#binfmt_d[@]} > 0 )) || exit 0
|
||||||
|
|
||||||
|
# mount binfmt_misc if api filesystem is missing
|
||||||
|
mountpoint -q /proc/sys/fs/binfmt_misc ||
|
||||||
|
mount /proc/sys/fs/binfmt_misc &>/dev/null ||
|
||||||
|
mount -t binfmt_misc binfmt /proc/sys/fs/binfmt_misc
|
||||||
|
|
||||||
|
# files declared later in the binfmt_d array will override earlier
|
||||||
|
# Example: `/etc/binfmt.d/foo.conf' supersedes `/usr/lib/binfmt.d/foo.conf'.
|
||||||
|
declare -A fragments
|
||||||
|
for path in "${binfmt_d[@]}"; do
|
||||||
|
[[ -f $path ]] && fragments[${path##*/}]=$path
|
||||||
|
done
|
||||||
|
|
||||||
|
for path in "${fragments[@]}"; do
|
||||||
|
while read -r line; do
|
||||||
|
[[ ${line:0:1} == '#' ]] && continue
|
||||||
|
printf "%s" "$line" > /proc/sys/fs/binfmt_misc/register
|
||||||
|
done < "$path"
|
||||||
|
done
|
||||||
|
|
||||||
|
:
|
||||||
|
|
||||||
|
# vim: set ts=2 sw=2 noet:
|
|
@ -0,0 +1,42 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# /usr/lib/initscripts/arch-modules
|
||||||
|
#
|
||||||
|
# Configure kernel modules to load at boot following
|
||||||
|
# http://0pointer.de/public/systemd-man/modules-load.d.html
|
||||||
|
#
|
||||||
|
|
||||||
|
shopt -s nullglob
|
||||||
|
|
||||||
|
declare -a modules_d
|
||||||
|
# files given has argv supersede config files
|
||||||
|
if (( $# > 0 )); then
|
||||||
|
for arg; do [[ -r "$arg" ]] && modules_d+=("$arg"); done
|
||||||
|
else
|
||||||
|
modules_d=(
|
||||||
|
/usr/lib/modules-load.d/*.conf
|
||||||
|
/etc/modules-load.d/*.conf
|
||||||
|
/run/modules-load.d/*.conf
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check there is file to load
|
||||||
|
(( ${#modules_d[@]} > 0 )) || exit 0
|
||||||
|
|
||||||
|
# files declared later in the modules_d array will override earlier
|
||||||
|
# Example: `/etc/modules-load.d/foo.conf' supersedes `/usr/lib/modules-load.d/foo.conf'.
|
||||||
|
declare -A fragments
|
||||||
|
for path in "${modules_d[@]}"; do
|
||||||
|
[[ -f $path ]] && fragments[${path##*/}]=$path
|
||||||
|
done
|
||||||
|
|
||||||
|
for path in "${fragments[@]}"; do
|
||||||
|
while read -r line; do
|
||||||
|
[[ ${line:0:1} == [\#\;] ]] && continue
|
||||||
|
modprobe -ab "$line"
|
||||||
|
done < "$path"
|
||||||
|
done
|
||||||
|
|
||||||
|
:
|
||||||
|
|
||||||
|
# vim: set ts=2 sw=2 noet:
|
|
@ -0,0 +1,435 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# /usr/lib/initscripts/arch-tmpfiles
|
||||||
|
#
|
||||||
|
# Control creation, deletion, and cleaning of volatile and temporary files
|
||||||
|
#
|
||||||
|
|
||||||
|
warninvalid() {
|
||||||
|
local description=$1 file=${2:-${files[$TOTALNUM]}} linenum=${3:-${linenums[$TOTALNUM]}}
|
||||||
|
|
||||||
|
printf "%s:line %d: ignoring invalid entry: %s\n" "$file" "$linenum" "$description"
|
||||||
|
(( ++error ))
|
||||||
|
} >&2
|
||||||
|
|
||||||
|
checkparams() {
|
||||||
|
shift
|
||||||
|
local path=$1 mode=$2 uid=$3 gid=$4 age=$5
|
||||||
|
|
||||||
|
# mode must be valid octal and 3 or 4 digits
|
||||||
|
if [[ $mode != '-' ]]; then
|
||||||
|
if [[ ! $mode =~ ^[0-7]{3,4}$ ]]; then
|
||||||
|
warninvalid "invalid mode '$mode'"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# uid must be numeric or a valid user name
|
||||||
|
# don't try to resolve numeric IDs in case they don't exist
|
||||||
|
if [[ $uid != '-' ]]; then
|
||||||
|
if [[ $uid != +([0-9]) ]] && ! getent passwd "$uid" >/dev/null; then
|
||||||
|
warninvalid "unknown user '$uid'"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# gid must be numeric or a valid group name
|
||||||
|
# don't try to resolve numeric IDs in case they don't exist
|
||||||
|
if [[ $gid != '-' ]]; then
|
||||||
|
if [[ $gid != +([0-9]) ]] && ! getent group "$gid" >/dev/null; then
|
||||||
|
warninvalid "unknown group '$gid'"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# age must be list of numerics separated by the following postfixes:
|
||||||
|
# s, sec, m, min, h, d, w
|
||||||
|
# also it can be prefixed by '~'
|
||||||
|
if [[ $age != '-' ]]; then
|
||||||
|
if [[ ! $age =~ ^~?([0-9]+(s|sec|m|min|h|d|w)?)+$ ]]; then
|
||||||
|
warninvalid "invalid age '$age'"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
relabel() {
|
||||||
|
local -a paths=($1)
|
||||||
|
local mode=$2 uid=$3 gid=$4
|
||||||
|
|
||||||
|
for path in "${paths[@]}"; do
|
||||||
|
if [[ -e $path ]]; then
|
||||||
|
[[ $uid != '-' ]] && chown $CHOPTS "$uid" "$path"
|
||||||
|
[[ $gid != '-' ]] && chgrp $CHOPTS "$gid" "$path"
|
||||||
|
[[ $mode != '-' ]] && chmod $CHOPTS "$mode" "$path"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_age() {
|
||||||
|
local seconds=0
|
||||||
|
local numbers=(${1//[^0-9]/ })
|
||||||
|
local units=(${1//[0-9]/ })
|
||||||
|
|
||||||
|
for (( i = 0; i < ${#numbers[@]}; i++ )); do
|
||||||
|
if [ "${units[i]}" == "m" ] || [ "${units[i]}" == "min" ]; then
|
||||||
|
(( seconds += numbers[i] * 60 ))
|
||||||
|
elif [ "${units[i]}" == "h" ]; then
|
||||||
|
(( seconds += numbers[i] * 3600 ))
|
||||||
|
elif [ "${units[i]}" == "d" ]; then
|
||||||
|
(( seconds += numbers[i] * 86400 ))
|
||||||
|
elif [ "${units[i]}" == "w" ]; then
|
||||||
|
(( seconds += numbers[i] * 604800 ))
|
||||||
|
else
|
||||||
|
(( seconds += numbers[i] ))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo $seconds
|
||||||
|
}
|
||||||
|
|
||||||
|
in_list() {
|
||||||
|
local search=$1
|
||||||
|
|
||||||
|
for item in "${EXCLUDE_LIST[@]}"; do
|
||||||
|
[[ "$search" == $item ]] && return 0
|
||||||
|
done
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup_dir() {
|
||||||
|
local path=$1 age=$2
|
||||||
|
local depth=1
|
||||||
|
|
||||||
|
# keep first level
|
||||||
|
if [[ ${age:0:1} == '~' ]]; then
|
||||||
|
depth=2
|
||||||
|
age=${age#'~'}
|
||||||
|
fi
|
||||||
|
|
||||||
|
local age=$(parse_age $age)
|
||||||
|
local current_time=$(date +%s)
|
||||||
|
|
||||||
|
while read -d '' file; do
|
||||||
|
# don't try to remove directories which still contains some files
|
||||||
|
[[ -d "$file" && $(ls -A "$file") ]] && continue
|
||||||
|
|
||||||
|
local mod_time=$(stat -c %Y "$file")
|
||||||
|
if (( (current_time - mod_time) > age )); then
|
||||||
|
! in_list "$file" && rm -fd "$file"
|
||||||
|
fi
|
||||||
|
done < <(find -P "$path" -mindepth $depth -depth -xdev -print0)
|
||||||
|
}
|
||||||
|
|
||||||
|
_f() {
|
||||||
|
# Create a file if it doesn't exist yet
|
||||||
|
local path=$1 mode=$2 uid=$3 gid=$4
|
||||||
|
|
||||||
|
if [[ ! -e $path ]]; then
|
||||||
|
install -m"$mode" -o"$uid" -g"$gid" /dev/null "$path"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_F() {
|
||||||
|
# Create or truncate a file
|
||||||
|
local path=$1 mode=$2 uid=$3 gid=$4
|
||||||
|
|
||||||
|
install -m"$mode" -o"$uid" -g"$gid" /dev/null "$path"
|
||||||
|
}
|
||||||
|
|
||||||
|
_d() {
|
||||||
|
# Create a directory if it doesn't exist yet
|
||||||
|
local path=$1 mode=$2 uid=$3 gid=$4 age=$5
|
||||||
|
|
||||||
|
if (( CLEAN )); then
|
||||||
|
if [[ $age != '-' ]] && [[ -d "$path" ]]; then
|
||||||
|
cleanup_dir "$path" "$age"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if (( CREATE )); then
|
||||||
|
if [[ ! -d "$path" ]]; then
|
||||||
|
install -d -m"$mode" -o"$uid" -g"$gid" "$path"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_D() {
|
||||||
|
# Create or empty a directory
|
||||||
|
local path=$1 mode=$2 uid=$3 gid=$4
|
||||||
|
|
||||||
|
if [[ -d $path ]] && (( REMOVE )); then
|
||||||
|
find "$path" -mindepth 1 -maxdepth 1 -xdev -exec rm -rf {} +
|
||||||
|
fi
|
||||||
|
|
||||||
|
_d "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
_p() {
|
||||||
|
# Create a named pipe (FIFO) if it doesn't exist yet
|
||||||
|
local path=$1 mode=$2 uid=$3 gid=$4
|
||||||
|
|
||||||
|
if [[ ! -p "$path" ]]; then
|
||||||
|
mkfifo -m$mode "$path"
|
||||||
|
chown "$uid:$gid" "$path"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_x() {
|
||||||
|
# Ignore a path during cleaning. Use this type to exclude paths from clean-up as
|
||||||
|
# controlled with the Age parameter. Note that lines of this type do not
|
||||||
|
# influence the effect of r or R lines. Lines of this type accept shell-style
|
||||||
|
# globs in place of of normal path names.
|
||||||
|
local path=$1
|
||||||
|
|
||||||
|
EXCLUDE_LIST+=("$path*(/*)")
|
||||||
|
}
|
||||||
|
|
||||||
|
_X() {
|
||||||
|
# Ignore a path during cleanup. Use this type to prevent path removal as controlled
|
||||||
|
# with the Age parameter. Note that if path is a directory, content of a directory is not
|
||||||
|
# excluded from clean-up, only directory itself. Lines of this type accept
|
||||||
|
# shell-style globs in place of normal path names.
|
||||||
|
local path=$1
|
||||||
|
|
||||||
|
EXCLUDE_LIST+=("$path")
|
||||||
|
}
|
||||||
|
|
||||||
|
_r() {
|
||||||
|
# Remove a file or directory if it exists. This may not be used to remove
|
||||||
|
# non-empty directories, use R for that. Lines of this type accept shell-style
|
||||||
|
# globs in place of normal path names.
|
||||||
|
local path
|
||||||
|
local -a paths=($1)
|
||||||
|
|
||||||
|
for path in "${paths[@]}"; do
|
||||||
|
if [[ -f $path ]]; then
|
||||||
|
rm -f "$path"
|
||||||
|
elif [[ -d $path ]]; then
|
||||||
|
rmdir "$path"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
_R() {
|
||||||
|
# Recursively remove a path and all its subdirectories (if it is a directory).
|
||||||
|
# Lines of this type accept shell-style globs in place of normal path names.
|
||||||
|
local path
|
||||||
|
local -a paths=($1)
|
||||||
|
|
||||||
|
for path in "${paths[@]}"; do
|
||||||
|
[[ -d $path ]] && rm -rf --one-file-system "$path"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
_z() {
|
||||||
|
# Set ownership, access mode and relabel security context of a file or
|
||||||
|
# directory if it exists. Lines of this type accept shell-style globs in
|
||||||
|
# place of normal path names.
|
||||||
|
local -a paths=($1)
|
||||||
|
local mode=$2 uid=$3 gid=$4
|
||||||
|
|
||||||
|
relabel "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
_Z() {
|
||||||
|
# Recursively set ownership, access mode and relabel security context of a
|
||||||
|
# path and all its subdirectories (if it is a directory). Lines of this type
|
||||||
|
# accept shell-style globs in place of normal path names.
|
||||||
|
|
||||||
|
CHOPTS=-R relabel "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
_m() {
|
||||||
|
# If the specified file path exists, adjust its access mode, group and user to
|
||||||
|
# the specified values. If it does not exist, do nothing.
|
||||||
|
|
||||||
|
relabel "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
_w() {
|
||||||
|
# Write the argument parameter to a file, if the file exists. Lines of this
|
||||||
|
# type accept shell-style globs in place of normal path names. The argument
|
||||||
|
# parameter will be written without a trailing newline.
|
||||||
|
local path
|
||||||
|
local -a paths=($1)
|
||||||
|
local argument="$6"
|
||||||
|
|
||||||
|
for path in "${paths[@]}"; do
|
||||||
|
[[ -f $path ]] && echo -n "$argument" > "$path"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
_L() {
|
||||||
|
# Create a symlink if it does not exist yet.
|
||||||
|
local path=$1 source=$6
|
||||||
|
|
||||||
|
if [[ ! -e "$path" && -e "$source" ]]; then
|
||||||
|
ln -s "$source" "$path"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_L+() {
|
||||||
|
# Create a symlink if it does not exist yet. If a file already exists where the symlink is to be created, it will be removed and be replaced by the symlink.
|
||||||
|
local path=$1 source=$6
|
||||||
|
|
||||||
|
if [[ -e "$source" ]]; then
|
||||||
|
ln -sf "$source" "$path"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
process_lines ()
|
||||||
|
{
|
||||||
|
local actions="$1"
|
||||||
|
|
||||||
|
TOTALNUM=0
|
||||||
|
while read -a line; do
|
||||||
|
(( ++TOTALNUM ))
|
||||||
|
|
||||||
|
[[ "${line[0]:0:1}" != $actions ]] && continue
|
||||||
|
|
||||||
|
# fill empty parameters
|
||||||
|
[[ "${line[2]}" ]] || line[2]='-'
|
||||||
|
[[ "${line[3]}" ]] || line[3]='-'
|
||||||
|
[[ "${line[4]}" ]] || line[4]='-'
|
||||||
|
[[ "${line[5]}" ]] || line[5]='-'
|
||||||
|
|
||||||
|
# skip invalid entries
|
||||||
|
if ! checkparams "${line[@]}"; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# fall back on defaults when parameters are passed as '-'
|
||||||
|
if [[ ${line[2]} = '-' ]]; then
|
||||||
|
case ${line[0]} in
|
||||||
|
p|f|F) line[2]=0644 ;;
|
||||||
|
d|D) line[2]=0755 ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${line[0]}" = [pfFdD] ]]; then
|
||||||
|
[[ ${line[3]} = '-' ]] && line[3]='root'
|
||||||
|
[[ ${line[4]} = '-' ]] && line[4]='root'
|
||||||
|
fi
|
||||||
|
|
||||||
|
"_${line[@]}"
|
||||||
|
done < <(printf '%s\n' "${lines[@]}")
|
||||||
|
}
|
||||||
|
|
||||||
|
shopt -s nullglob
|
||||||
|
shopt -s extglob
|
||||||
|
|
||||||
|
declare -i CREATE=0 REMOVE=0 CLEAN=0 ONBOOT=0
|
||||||
|
declare -i error=0 LINENUM=0 TOTALNUM=0
|
||||||
|
declare FILE=
|
||||||
|
declare -A fragments
|
||||||
|
declare -a tmpfiles_d=(
|
||||||
|
/usr/lib/tmpfiles.d/*.conf
|
||||||
|
/etc/tmpfiles.d/*.conf
|
||||||
|
/run/tmpfiles.d/*.conf
|
||||||
|
)
|
||||||
|
declare -a EXCLUDE_LIST lines linenums files
|
||||||
|
|
||||||
|
while (( $# )); do
|
||||||
|
case $1 in
|
||||||
|
--create) CREATE=1 ;;
|
||||||
|
--remove) REMOVE=1 ;;
|
||||||
|
--clean) CLEAN=1 ;;
|
||||||
|
--boot) ONBOOT=1 ;;
|
||||||
|
*) break ;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
if (( !(CREATE + REMOVE + CLEAN) )); then
|
||||||
|
printf 'usage: %s [--create] [--remove] [--clean] [--boot] [FILES...]\n' "${0##*/}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# directories declared later in the tmpfiles_d array will override earlier
|
||||||
|
# directories, on a per file basis.
|
||||||
|
# Example: `/etc/tmpfiles.d/foo.conf' supersedes `/usr/lib/tmpfiles.d/foo.conf'.
|
||||||
|
for path in "${tmpfiles_d[@]}"; do
|
||||||
|
[[ -f $path ]] && fragments[${path##*/}]=${path%/*}
|
||||||
|
done
|
||||||
|
|
||||||
|
# catch errors in functions so we can exit with something meaningful
|
||||||
|
set -E
|
||||||
|
trap '(( ++error ))' ERR
|
||||||
|
|
||||||
|
# loop through the gathered fragments, sorted globally by filename.
|
||||||
|
# `/run/tmpfiles/foo.conf' will always be read after `/etc/tmpfiles.d/bar.conf'
|
||||||
|
while read -d '' fragment; do
|
||||||
|
LINENUM=0
|
||||||
|
|
||||||
|
# make sure that a fragment contains only a base filename
|
||||||
|
if [[ "$fragment" = /* ]] && [[ -f "$fragment" ]]; then
|
||||||
|
fragments[${fragment##*/}]=${fragment%/*}
|
||||||
|
fragment=${fragment##*/}
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z ${fragments[$fragment]} ]]; then
|
||||||
|
printf 'warning: %s does not found\n' "$fragment"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf -v FILE '%s/%s' "${fragments[$fragment]}" "$fragment"
|
||||||
|
|
||||||
|
### FILE FORMAT ###
|
||||||
|
# 0 1 2 3 4 5
|
||||||
|
# Type Path Mode UID GID Age
|
||||||
|
# d /run/user 0755 root root 10d
|
||||||
|
|
||||||
|
# omit read's -r flag to honor escapes here, so that whitespace can be
|
||||||
|
# escaped for paths. We will _not_ honor quoted paths. Also make sure that
|
||||||
|
# last line will be processed even if it does not contain terminating '\n'.
|
||||||
|
while read -a line || [[ -n "${line[@]}" ]]; do
|
||||||
|
(( ++LINENUM ))
|
||||||
|
|
||||||
|
# skip over comments and empty lines
|
||||||
|
if (( ! ${#line[*]} )) || [[ ${line[0]:0:1} = '#' ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# process the lines with unsafe operation marker only if --boot option is
|
||||||
|
# specified
|
||||||
|
if [[ "${line[0]}" == *! ]]; then
|
||||||
|
(( ONBOOT )) || continue
|
||||||
|
|
||||||
|
line[0]=${line[0]%!}
|
||||||
|
fi
|
||||||
|
|
||||||
|
# whine about invalid entries
|
||||||
|
if ! type -t _${line[0]} >/dev/null; then
|
||||||
|
warninvalid "unknown action '${line[0]}'" "$FILE" "$LINENUM"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# path cannot be empty
|
||||||
|
if [[ -z "${line[1]}" ]]; then
|
||||||
|
warninvalid "missed path" "$FILE" "$LINENUM"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
(( ++TOTALNUM ))
|
||||||
|
lines[$TOTALNUM]="${line[@]}"
|
||||||
|
linenums[$TOTALNUM]=$LINENUM
|
||||||
|
files[$TOTALNUM]="$FILE"
|
||||||
|
done <"$FILE"
|
||||||
|
done < <(printf '%s\0' "${@:-${!fragments[@]}}" | sort -z)
|
||||||
|
|
||||||
|
# Fill exclude list first
|
||||||
|
(( CLEAN )) && process_lines "[xX]"
|
||||||
|
|
||||||
|
process_lines "[dD]"
|
||||||
|
(( CREATE )) && process_lines "[fFpzZmwL]"
|
||||||
|
(( REMOVE )) && process_lines "[rR]"
|
||||||
|
|
||||||
|
exit $error
|
||||||
|
|
||||||
|
# vim: set ts=2 sw=2 noet:
|
|
@ -0,0 +1,132 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
. /etc/rc.conf
|
||||||
|
. /etc/rc.d/functions
|
||||||
|
|
||||||
|
# print usage and exit
|
||||||
|
usage() {
|
||||||
|
local name=${0##*/}
|
||||||
|
cat >&2 << EOF
|
||||||
|
usage: $name <action> [options] [daemons]
|
||||||
|
|
||||||
|
options:
|
||||||
|
-s, --started Filter started daemons
|
||||||
|
-S, --stopped Filter stopped daemons
|
||||||
|
-a, --auto Filter auto started daemons
|
||||||
|
-A, --noauto Filter manually started daemons
|
||||||
|
|
||||||
|
<daemons> is a space separated list of script in /etc/rc.d
|
||||||
|
<action> can be a start, stop, restart, reload, status, ...
|
||||||
|
WARNING: initscripts are free to implement or not the above actions.
|
||||||
|
|
||||||
|
e.g: $name list
|
||||||
|
$name list sshd gpm
|
||||||
|
$name list --started gpm
|
||||||
|
$name start sshd gpm
|
||||||
|
$name help
|
||||||
|
EOF
|
||||||
|
exit ${1:-1}
|
||||||
|
}
|
||||||
|
|
||||||
|
# filter list of daemons
|
||||||
|
filter_daemons() {
|
||||||
|
local -a new_daemons=()
|
||||||
|
for daemon in "${daemons[@]}"; do
|
||||||
|
# check if daemons is valid
|
||||||
|
if ! have_daemon "$daemon"; then
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
# check filter
|
||||||
|
(( ${filter[started]} )) && ck_daemon "$daemon" && continue
|
||||||
|
(( ${filter[stopped]} )) && ! ck_daemon "$daemon" && continue
|
||||||
|
(( ${filter[auto]} )) && ck_autostart "$daemon" && continue
|
||||||
|
(( ${filter[noauto]} )) && ! ck_autostart "$daemon" && continue
|
||||||
|
new_daemons+=("$daemon")
|
||||||
|
done
|
||||||
|
daemons=("${new_daemons[@]}")
|
||||||
|
}
|
||||||
|
|
||||||
|
(( $# < 1 )) && usage
|
||||||
|
|
||||||
|
# ret store the return code of rc.d
|
||||||
|
declare -i ret=0
|
||||||
|
# daemons store daemons on which action will be executed
|
||||||
|
declare -a daemons=()
|
||||||
|
# filter store current filter mode
|
||||||
|
declare -A filter=([started]=0 [stopped]=0 [auto]=0 [noauto]=0)
|
||||||
|
|
||||||
|
# parse options
|
||||||
|
argv=$(getopt -l 'started,stopped,auto,noauto' -- 'sSaA' "$@") || usage
|
||||||
|
eval set -- "$argv"
|
||||||
|
|
||||||
|
# create an initial daemon list
|
||||||
|
while [[ "$1" != -- ]]; do
|
||||||
|
case "$1" in
|
||||||
|
-s|--started) filter[started]=1 ;;
|
||||||
|
-S|--stopped) filter[stopped]=1 ;;
|
||||||
|
-a|--auto) filter[auto]=1 ;;
|
||||||
|
-A|--noauto) filter[noauto]=1 ;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
# remove --
|
||||||
|
shift
|
||||||
|
# get action
|
||||||
|
action=$1
|
||||||
|
shift
|
||||||
|
|
||||||
|
# get initial daemons list
|
||||||
|
for daemon; do
|
||||||
|
daemons+=("$daemon")
|
||||||
|
done
|
||||||
|
|
||||||
|
# going into script directory
|
||||||
|
cd /etc/rc.d
|
||||||
|
|
||||||
|
case $action in
|
||||||
|
help)
|
||||||
|
usage 0 2>&1
|
||||||
|
;;
|
||||||
|
list)
|
||||||
|
# list take all daemons by default
|
||||||
|
[[ -z $daemons ]] && for d in *; do [[ -f /etc/rc.d/"$d" && -x /etc/rc.d/"$d" ]] && daemons+=("$d"); done
|
||||||
|
filter_daemons
|
||||||
|
for daemon in "${daemons[@]}"; do
|
||||||
|
# print running / stopped status
|
||||||
|
if ! ck_daemon "$daemon"; then
|
||||||
|
s_status="${C_OTHER}[${C_DONE}STARTED${C_OTHER}]"
|
||||||
|
else
|
||||||
|
s_status="${C_OTHER}[${C_FAIL}STOPPED${C_OTHER}]"
|
||||||
|
fi
|
||||||
|
# print auto / manual status
|
||||||
|
if ! ck_autostart "$daemon"; then
|
||||||
|
s_auto="${C_OTHER}[${C_DONE}AUTO${C_OTHER}]"
|
||||||
|
else
|
||||||
|
s_auto="${C_OTHER}[${C_FAIL} ${C_OTHER}]"
|
||||||
|
fi
|
||||||
|
printf "$s_status$s_auto${C_CLEAR} $daemon\n"
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
# other actions need an explicit daemons list
|
||||||
|
[[ -z $daemons ]] && usage
|
||||||
|
filter_daemons
|
||||||
|
# set same environment variables as init
|
||||||
|
runlevel=$(/usr/bin/runlevel)
|
||||||
|
ENV=('PATH=/usr/bin'
|
||||||
|
"PREVLEVEL=${runlevel%% *}"
|
||||||
|
"RUNLEVEL=${runlevel##* }"
|
||||||
|
"CONSOLE=${CONSOLE:-/dev/console}"
|
||||||
|
"TERM=$TERM")
|
||||||
|
cd /
|
||||||
|
for daemon in "${daemons[@]}"; do
|
||||||
|
env -i "${ENV[@]}" "/etc/rc.d/$daemon" "$action"
|
||||||
|
(( ret += !! $? )) # clamp exit value to 0/1
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exit $ret
|
||||||
|
|
||||||
|
# vim: set ts=2 sw=2 ft=sh noet:
|
Loading…
Reference in New Issue