summaryrefslogtreecommitdiff
path: root/xi/bin
diff options
context:
space:
mode:
authordavidovski <david@davidovski.xyz>2022-03-01 23:14:41 +0000
committerdavidovski <david@davidovski.xyz>2022-03-01 23:14:41 +0000
commitea4267fac55c7d8a6093a6b03ff0e9c795786d3e (patch)
tree04905981b9d5ad7a4710c472faf920f3c5e28375 /xi/bin
parentefee4ebf43e376a7cd8b8abcef0c70aa90427bb4 (diff)
reorganised
Diffstat (limited to 'xi/bin')
-rwxr-xr-xxi/bin/ifdown100
-rwxr-xr-xxi/bin/ifup136
-rwxr-xr-xxi/bin/modules-load19
-rwxr-xr-xxi/bin/tmpfiles592
4 files changed, 847 insertions, 0 deletions
diff --git a/xi/bin/ifdown b/xi/bin/ifdown
new file mode 100755
index 0000000..a133c25
--- /dev/null
+++ b/xi/bin/ifdown
@@ -0,0 +1,100 @@
+#!/bin/bash
+########################################################################
+# Begin /sbin/ifdown
+#
+# Description : Interface Down
+#
+# Authors : Nathan Coulson - nathan@linuxfromscratch.org
+# Kevin P. Fleming - kpfleming@linuxfromscratch.org
+# Update : Bruce Dubbs - bdubbs@linuxfromscratch.org
+#
+# Version : LFS 7.0
+#
+# Notes : the IFCONFIG variable is passed to the scripts found
+# in the /lib/services directory, to indicate what file the
+# service should source to get interface specifications.
+#
+########################################################################
+
+RELEASE="7.0"
+
+USAGE="Usage: $0 [ -hV ] [--help] [--version] interface"
+VERSTR="LFS ifdown, version ${RELEASE}"
+
+while [ $# -gt 0 ]; do
+ case "$1" in
+ --help | -h) help="y"; break ;;
+
+ --version | -V) echo "${VERSTR}"; exit 0 ;;
+
+ -*) echo "ifup: ${1}: invalid option" >&2
+ echo "${USAGE}" >& 2
+ exit 2 ;;
+
+ *) break ;;
+ esac
+done
+
+if [ -n "$help" ]; then
+ echo "${VERSTR}"
+ echo "${USAGE}"
+ echo
+ cat << HERE_EOF
+ifdown is used to bring down a network interface. The interface
+parameter, e.g. eth0 or eth0:2, must match the trailing part of the
+interface specifications file, e.g. /etc/sysconfig/ifconfig.eth0:2.
+
+HERE_EOF
+ exit 0
+fi
+
+file=/etc/sysconfig/ifconfig.${1}
+
+# Skip backup files
+[ "${file}" = "${file%""~""}" ] || exit 0
+
+#. /lib/lsb/init-functions
+
+if [ ! -r "${file}" ]; then
+ echo "${file} is missing or cannot be accessed."
+ exit 1
+fi
+
+. ${file}
+
+if [ "$IFACE" = "" ]; then
+ echo "${file} does not define an interface [IFACE]."
+ exit 1
+fi
+
+# We only need to first service to bring down the interface
+S=`echo ${SERVICE} | cut -f1 -d" "`
+
+if ip link show ${IFACE} > /dev/null 2>&1; then
+ if [ -n "${S}" -a -x "/lib/services/${S}" ]; then
+ IFCONFIG=${file} /lib/services/${S} ${IFACE} down
+ else
+ MSG="Unable to process ${file}. Either "
+ MSG="${MSG}the SERVICE variable was not set "
+ MSG="${MSG}or the specified service cannot be executed."
+ echo "$MSG"
+ exit 1
+ fi
+else
+ echo "Interface ${1} doesn't exist."
+fi
+
+# Leave the interface up if there are additional interfaces in the device
+link_status=`ip link show ${IFACE} 2>/dev/null`
+
+if [ -n "${link_status}" ]; then
+ if [ "$(echo "${link_status}" | grep UP)" != "" ]; then
+ if [ "$(ip addr show ${IFACE} | grep 'inet ')" == "" ]; then
+ echo "Bringing down the ${IFACE} interface..."
+ ip link set ${IFACE} down
+ #evaluate_retval
+ fi
+ fi
+fi
+
+# End /sbin/ifdown
diff --git a/xi/bin/ifup b/xi/bin/ifup
new file mode 100755
index 0000000..7466150
--- /dev/null
+++ b/xi/bin/ifup
@@ -0,0 +1,136 @@
+#!/bin/sh
+########################################################################
+# Begin /sbin/ifup
+#
+# Description : Interface Up
+#
+# Authors : Nathan Coulson - nathan@linuxfromscratch.org
+# Kevin P. Fleming - kpfleming@linuxfromscratch.org
+# Update : Bruce Dubbs - bdubbs@linuxfromscratch.org
+#
+# Version : LFS 7.2
+#
+# Notes : The IFCONFIG variable is passed to the SERVICE script
+# in the /lib/services directory, to indicate what file the
+# service should source to get interface specifications.
+#
+########################################################################
+
+up()
+{
+ if ip link show $1 > /dev/null 2>&1; then
+ link_status=`ip link show $1`
+
+ if [ -n "${link_status}" ]; then
+ if ! echo "${link_status}" | grep -q UP; then
+ ip link set $1 up
+ fi
+ fi
+
+ else
+ echo "Interface ${IFACE} doesn't exist."
+ exit 1
+ fi
+}
+
+RELEASE="7.2"
+
+USAGE="Usage: $0 [ -hV ] [--help] [--version] interface"
+VERSTR="LFS ifup, version ${RELEASE}"
+
+while [ $# -gt 0 ]; do
+ case "$1" in
+ --help | -h) help="y"; break ;;
+
+ --version | -V) echo "${VERSTR}"; exit 0 ;;
+
+ -*) echo "ifup: ${1}: invalid option" >&2
+ echo "${USAGE}" >& 2
+ exit 2 ;;
+
+ *) break ;;
+ esac
+done
+
+if [ -n "$help" ]; then
+ echo "${VERSTR}"
+ echo "${USAGE}"
+ echo
+ cat << HERE_EOF
+ifup is used to bring up a network interface. The interface
+parameter, e.g. eth0 or eth0:2, must match the trailing part of the
+interface specifications file, e.g. /etc/sysconfig/ifconfig.eth0:2.
+
+HERE_EOF
+ exit 0
+fi
+
+file=/etc/sysconfig/ifconfig.${1}
+
+# Skip backup files
+[ "${file}" = "${file%""~""}" ] || exit 0
+
+#. /lib/lsb/init-functions
+
+echo "Bringing up the ${1} interface... "
+
+if [ ! -r "${file}" ]; then
+ echo "${file} is missing or cannot be accessed."
+ exit 1
+fi
+
+. $file
+
+if [ "$IFACE" = "" ]; then
+ echo "${file} does not define an interface [IFACE]."
+ exit 1
+fi
+
+# Do not process this service if started by boot, and ONBOOT
+# is not set to yes
+if [ "${IN_BOOT}" = "1" -a "${ONBOOT}" != "yes" ]; then
+ echo "skipped"
+ exit 0
+fi
+
+for S in ${SERVICE}; do
+ if [ ! -x "/lib/services/${S}" ]; then
+ echo "Unable to process ${file}. Either "
+ echo "${MSG}the SERVICE '${S} was not present "
+ echo "${MSG}or cannot be executed."
+ echo "$MSG"
+ exit 1
+ fi
+done
+
+# Create/configure the interface
+for S in ${SERVICE}; do
+ IFCONFIG=${file} /lib/services/${S} ${IFACE} up
+done
+
+# Bring up the interface and any components
+for I in $IFACE $INTERFACE_COMPONENTS; do up $I; done
+
+# Set MTU if requested. Check if MTU has a "good" value.
+if test -n "${MTU}"; then
+ if [[ ${MTU} =~ ^[0-9]+$ ]] && [[ $MTU -ge 68 ]] ; then
+ for I in $IFACE $INTERFACE_COMPONENTS; do
+ ip link set dev $I mtu $MTU;
+ done
+ else
+ echo "Invalid MTU $MTU"
+ fi
+fi
+
+# Set the route default gateway if requested
+if [ -n "${GATEWAY}" ]; then
+ if ip route | grep -q default; then
+ echo "Gateway already setup; skipping."
+ else
+ echo "Setting up default gateway..."
+ ip route add default via ${GATEWAY} dev ${IFACE}
+ #evaluate_retval
+ fi
+fi
+
+# End /sbin/ifup
diff --git a/xi/bin/modules-load b/xi/bin/modules-load
new file mode 100755
index 0000000..35e73b8
--- /dev/null
+++ b/xi/bin/modules-load
@@ -0,0 +1,19 @@
+#!/bin/sh
+# modules-load [-n] [-v] - modules-load.d(5) compatible kernel module loader
+
+export PATH=/bin:/sbin
+
+{
+# Parameters passed as modules-load= or rd.modules-load= in kernel command line.
+sed -nr 's/,/\n/;s/(.* |^)(rd\.)?modules-load=([^ ]*).*/\3/p' /proc/cmdline
+
+# Find files /{etc,run,usr/lib}/modules-load.d/*.conf in that order.
+find -L /etc/modules-load.d /run/modules-load.d /usr/lib/modules-load.d \
+ -maxdepth 1 -name '*.conf' -printf '%p %P\n' 2>/dev/null |
+# Load each basename only once.
+ sort -k2 -s | uniq -f1 | cut -d' ' -f1 |
+# Read the files, output all non-empty, non-comment lines.
+ tr '\012' '\0' | xargs -0 -r grep -h -v -e '^[#;]' -e '^$'
+} |
+# Call modprobe on the list of modules
+tr '\012' '\0' | xargs -0 -r modprobe -ab "$@"
diff --git a/xi/bin/tmpfiles b/xi/bin/tmpfiles
new file mode 100755
index 0000000..5e4ee0a
--- /dev/null
+++ b/xi/bin/tmpfiles
@@ -0,0 +1,592 @@
+#!/bin/sh
+# This is a reimplementation of the systemd tmpfiles.d code
+# Control creation, deletion, and cleaning of volatile and temporary files
+#
+# Copyright (c) 2012 Gentoo Foundation
+# Released under the 2-clause BSD license.
+#
+# This instance is a pure-POSIX sh version, written by Robin H Johnson
+# <robbat2@gentoo.org>, based on the Arch Linux version as of 2012/01/01:
+# http://projects.archlinux.org/initscripts.git/tree/arch-tmpfiles
+#
+# See the tmpfiles.d manpage as well:
+# https://www.freedesktop.org/software/systemd/man/tmpfiles.d.html
+# This script should match the old manpage
+# http://0pointer.de/public/systemd-man/tmpfiles.d.html
+# as of 2012/03/12 and also implements some more recent features
+#
+
+DRYRUN=0
+
+checkprefix() {
+ n=$1
+ shift
+ for x in "$@"; do
+ case ${n} in
+ ${x}*) return 0 ;;
+ esac
+ done
+ return 1
+}
+
+warninvalid() {
+ printf "tmpfiles: ignoring invalid entry on line %d of \`%s'\n" "${LINENUM}" "${FILE}"
+ error=$(( error+1 ))
+} >&2
+
+invalid_option() {
+ printf "tmpfiles: invalid option '%s'\n" "$1" >&2
+ exit 1
+}
+
+dryrun_or_real() {
+ local dryrun=
+ if [ ${DRYRUN} -eq 1 ]; then
+ dryrun="echo"
+ fi
+ ${dryrun} "$@"
+}
+
+_chattr() {
+ local attr="$2"
+ case ${attr} in
+ [+-=]*) : ;;
+ '') return ;;
+ *) attr="+${attr}" ;;
+ esac
+ local IFS=
+ dryrun_or_real chattr "$1" "${attr}" -- "$3"
+}
+
+_setfacl() {
+ dryrun_or_real setfacl -P "$1" "$2" "$3" -- "$4"
+}
+
+relabel() {
+ local path
+ local paths=$1 mode=$2 uid=$3 gid=$4
+ local status
+
+ status=0
+ for path in ${paths}; do
+ if [ -e "${path}" ]; then
+ if [ -x /sbin/restorecon ]; then
+ dryrun_or_real restorecon ${CHOPTS} "${path}" || status="$?"
+ fi
+ if [ "${uid}" != '-' ]; then
+ dryrun_or_real chown ${CHOPTS} "${uid}" "${path}" || status="$?"
+ fi
+ if [ "${gid}" != '-' ]; then
+ dryrun_or_real chgrp ${CHOPTS} "${gid}" "${path}" || status="$?"
+ fi
+ if [ "${mode}" != '-' ]; then
+ dryrun_or_real chmod ${CHOPTS} "${mode}" "${path}" || status="$?"
+ fi
+ fi
+ done
+ return ${status}
+}
+
+splitpath() {
+ local path=$1
+ while [ -n "${path}" ]; do
+ printf '%s\n' "${path}"
+ path=${path%/*}
+ done
+}
+
+_restorecon() {
+ local path=$1
+ if [ -x /sbin/restorecon ]; then
+ dryrun_or_real restorecon -F "$(splitpath "${path}")"
+ fi
+}
+
+createdirectory() {
+ local mode="$1" uid="$2" gid="$3" path="$4"
+ [ -d "${path}" ] || dryrun_or_real mkdir -p "${path}"
+ if [ "${uid}" = - ]; then
+ uid=root
+ fi
+ if [ "${gid}" = - ]; then
+ gid=root
+ fi
+ if [ "${mode}" = - ]; then
+ mode=0755
+ fi
+ dryrun_or_real chown ${uid} "${path}"
+ dryrun_or_real chgrp ${gid} "${path}"
+ dryrun_or_real chmod ${mode} "${path}"
+}
+
+createfile() {
+ local mode="$1" uid="$2" gid="$3" path="$4"
+ dryrun_or_real touch "${path}"
+ if [ "${uid}" = - ]; then
+ uid=root
+ fi
+ if [ "${gid}" = - ]; then
+ gid=root
+ fi
+ if [ "${mode}" = - ]; then
+ mode=0644
+ fi
+ dryrun_or_real chown ${uid} "${path}"
+ dryrun_or_real chgrp ${gid} "${path}"
+ dryrun_or_real chmod ${mode} "${path}"
+}
+
+createpipe() {
+ local mode="$1" uid="$2" gid="$3" path="$4"
+ dryrun_or_real mkfifo "${path}"
+ if [ "${uid}" = - ]; then
+ uid=root
+ fi
+ if [ "${gid}" = - ]; then
+ gid=root
+ fi
+ if [ "${mode}" = - ]; then
+ mode=0644
+ fi
+ dryrun_or_real chown ${uid} "${path}"
+ dryrun_or_real chgrp ${gid} "${path}"
+ dryrun_or_real chmod ${mode} "${path}"
+}
+
+_b() {
+ # Create a block device node if it doesn't exist yet
+ local path=$1 mode=$2 uid=$3 gid=$4 age=$5 arg=$6
+ if [ "${uid}" = - ]; then
+ uid=root
+ fi
+ if [ "${gid}" = - ]; then
+ gid=root
+ fi
+ if [ "${mode}" = - ]; then
+ mode=0644
+ fi
+ if [ ! -e "${path}" ]; then
+ dryrun_or_real mknod -m ${mode} "${path}" b "${arg%:*}" "${arg#*:}"
+ _restorecon "${path}"
+ dryrun_or_real chown ${uid} "${path}"
+ dryrun_or_real chgrp ${gid} "${path}"
+ fi
+}
+
+_c() {
+ # Create a character device node if it doesn't exist yet
+ local path=$1 mode=$2 uid=$3 gid=$4 age=$5 arg=$6
+ if [ "${uid}" = - ]; then
+ uid=root
+ fi
+ if [ "${gid}" = - ]; then
+ gid=root
+ fi
+ if [ "${mode}" = - ]; then
+ mode=0644
+ fi
+ if [ ! -e "${path}" ]; then
+ dryrun_or_real mknod -m ${mode} "${path}" c "${arg%:*}" "${arg#*:}"
+ _restorecon "${path}"
+ dryrun_or_real chown ${uid} "${path}"
+ dryrun_or_real chgrp ${gid} "${path}"
+ fi
+}
+
+_C() {
+ # recursively copy a file or directory
+ local path=$1 mode=$2 uid=$3 gid=$4 age=$5 arg=$6
+ if [ ! -e "${path}" ]; then
+ dryrun_or_real cp -r "${arg}" "${path}"
+ _restorecon "${path}"
+ if [ "${uid}" != '-' ]; then
+ dryrun_or_real chown "${uid}" "${path}"
+ fi
+ if [ "${gid}" != '-' ]; then
+ dryrun_or_real chgrp "${gid}" "${path}"
+ fi
+ if [ "${mode}" != '-' ]; then
+ dryrun_or_real chmod "${mode}" "${path}"
+ fi
+ fi
+}
+
+_f() {
+ # Create a file if it doesn't exist yet
+ local path=$1 mode=$2 uid=$3 gid=$4 age=$5 arg=$6
+
+ [ "${CREATE}" -gt 0 ] || return 0
+
+ if [ ! -e "${path}" ]; then
+ createfile "${mode}" "${uid}" "${gid}" "${path}"
+ if [ -n "${arg}" ]; then
+ _w "$@"
+ fi
+ fi
+}
+
+_F() {
+ # Create or truncate a file
+ local path=$1 mode=$2 uid=$3 gid=$4 age=$5 arg=$6
+
+ [ "${CREATE}" -gt 0 ] || return 0
+
+ dryrun_or_real rm -f "${path}"
+ createfile "${mode}" "${uid}" "${gid}" "${path}"
+ if [ -n "${arg}" ]; then
+ _w "$@"
+ fi
+}
+
+_d() {
+ # Create a directory if it doesn't exist yet
+ local path=$1 mode=$2 uid=$3 gid=$4
+
+ if [ "${CREATE}" -gt 0 ]; then
+ createdirectory "${mode}" "${uid}" "${gid}" "${path}"
+ _restorecon "${path}"
+ fi
+}
+
+_D() {
+ # Create or empty a directory
+ local path=$1 mode=$2 uid=$3 gid=$4
+
+ if [ -d "${path}" ] && [ "${REMOVE}" -gt 0 ]; then
+ dryrun_or_real find "${path}" -mindepth 1 -maxdepth 1 -xdev -exec rm -rf {} +
+ _restorecon "${path}"
+ fi
+
+ if [ "${CREATE}" -gt 0 ]; then
+ createdirectory "${mode}" "${uid}" "${gid}" "${path}"
+ _restorecon "${path}"
+ fi
+}
+
+_v() {
+ # Create a subvolume if the path does not exist yet and the file system
+ # supports this (btrfs). Otherwise create a normal directory.
+ # TODO: Implement btrfs subvol creation.
+ _d "$@"
+}
+
+_q() {
+ # Similar to _v. However, make sure that the subvolume will be assigned
+ # to the same higher-level quota groups as the subvolume it has
+ # been created in.
+ # TODO: Implement btrfs subvol creation.
+ _d "$@"
+}
+
+_Q() {
+ # Similar to q. However, instead of copying the higher-level quota
+ # group assignments from the parent as-is, the lowest quota group
+ # of the parent subvolume is determined that is not the
+ # leaf quota group.
+ # TODO: Implement btrfs subvol creation.
+ _d "$@"
+}
+
+_a() {
+ # Set/add file/directory ACL. Lines of this type accept
+ # shell-style globs in place of normal path names.
+ # The format of the argument field matches setfacl
+ local ACTION='--remove-all --set'
+ [ "${FORCE}" -gt 0 ] && ACTION='--modify'
+ _setfacl '' "${ACTION}" "$6" "$1"
+}
+
+_A() {
+ # Recursively set/add file/directory ACL. Lines of this type accept
+ # shell-syle globs in place of normal path names.
+ # Does not follow symlinks
+ local ACTION='--remove-all --set'
+ [ "${FORCE}" -gt 0 ] && ACTION='--modify'
+ _setfacl -R "${ACTION}" "$6" "$1"
+}
+
+_h() {
+ # Set file/directory attributes. Lines of this type accept
+ # shell-style globs in place of normal path names.
+ # The format of the argument field matches chattr
+ _chattr '' "$6" "$1"
+}
+
+_H() {
+ # Recursively set file/directory attributes. Lines of this type accept
+ # shell-syle globs in place of normal path names.
+ # Does not follow symlinks
+ _chattr -R "$6" "$1"
+}
+
+_L() {
+ # Create a symlink if it doesn't exist yet
+ local path=$1 mode=$2 uid=$3 gid=$4 age=$5 arg=$6
+ if [ ! -e "${path}" ]; then
+ dryrun_or_real ln -s "${arg}" "${path}"
+ fi
+ _restorecon "${path}"
+}
+
+_p() {
+ # Create a named pipe (FIFO) if it doesn't exist yet
+ local path=$1 mode=$2 uid=$3 gid=$4
+
+ [ "${CREATE}" -gt 0 ] || return 0
+
+ if [ ! -p "${path}" ]; then
+ createpipe "${mode}" "${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.
+ :
+ # XXX: we don't implement this
+}
+
+_X() {
+ # Ignore a path during cleanup. Use this type to prevent path
+ # removal as controled with the age parameter. Note that if path is
+ # a directory, the content of the directory is not excluded from
+ # clean-up, only the directory itself.
+ # Lines of this type accept shell-style globs in place of normal path names.
+ :
+ # XXX: we don't implement this
+}
+
+_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 paths=$1
+ local status
+
+ [ "${REMOVE}" -gt 0 ] || return 0
+
+ status=0
+ for path in ${paths}; do
+ if [ -f "${path}" ]; then
+ dryrun_or_real rm -f "${path}" || status="$?"
+ elif [ -d "${path}" ]; then
+ dryrun_or_real rmdir "${path}" || status="$?"
+ fi
+ done
+ return ${status}
+}
+
+_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 paths=$1
+ local status
+
+ [ "${REMOVE}" -gt 0 ] || return 0
+
+ status=0
+ for path in ${paths}; do
+ if [ -d "${path}" ]; then
+ dryrun_or_real rm -rf --one-file-system "${path}" || status="$?"
+ fi
+ done
+ return ${status}
+}
+
+_w() {
+ # Write the argument parameter to a file, if it exists.
+ local path=$1 mode=$2 uid=$3 gid=$4 age=$5 arg=$6
+ if [ -f "${path}" ]; then
+ if [ ${DRYRUN} -eq 1 ]; then
+ echo "echo \"${arg}\" >>\"${path}\""
+ else
+ echo "${arg}" >>"${path}"
+ fi
+ fi
+}
+
+_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.
+ [ "${CREATE}" -gt 0 ] || return 0
+
+ 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.
+ [ "${CREATE}" -gt 0 ] || return 0
+
+ CHOPTS=-R relabel "$@"
+}
+
+usage() {
+ printf 'usage: %s [--exclude-prefix=path] [--prefix=path] [--boot] [--create] [--remove] [--clean] [--verbose] [--dry-run]\n' "${0##*/}"
+ exit "${1:-0}"
+}
+
+version() {
+ # We don't record the version info anywhere currently.
+ echo "opentmpfiles"
+ exit 0
+}
+
+BOOT=0 CREATE=0 REMOVE=0 CLEAN=0 VERBOSE=0 DRYRUN=0 error=0 LINENO=0
+EXCLUDE=
+PREFIX=
+FILES=
+
+while [ $# -gt 0 ]; do
+ case $1 in
+ --boot) BOOT=1 ;;
+ --create) CREATE=1 ;;
+ --remove) REMOVE=1 ;;
+ --clean) CLEAN=1 ;; # TODO: Not implemented
+ --verbose) VERBOSE=1 ;;
+ --dryrun|--dry-run) DRYRUN=1 ;;
+ --exclude-prefix=*) EXCLUDE="${EXCLUDE}${1##--exclude-prefix=} " ;;
+ --prefix=*) PREFIX="${PREFIX}${1##--prefix=} " ;;
+ -h|--help) usage ;;
+ --version) version ;;
+ -*) invalid_option "$1" ;;
+ *) FILES="${FILES} $1"
+ esac
+ shift
+done
+
+if [ $(( CLEAN )) -eq 1 ] ; then
+ printf '%s clean mode is not implemented\n' "${0##*/}"
+ exit 1
+fi
+
+if [ "${CREATE}${REMOVE}" = '00' ]; then
+ usage 1 >&2
+fi
+
+# XXX: The harcoding of /usr/lib/ is an explicit choice by upstream
+tmpfiles_dirs='/usr/lib/tmpfiles.d /run/tmpfiles.d /etc/tmpfiles.d'
+tmpfiles_basenames=''
+
+if [ -z "${FILES}" ]; then
+ # Build a list of sorted unique basenames
+ # directories declared later in the tmpfiles_d array will override earlier
+ # directories, on a per file basename basis.
+ # `/etc/tmpfiles.d/foo.conf' supersedes `/usr/lib/tmpfiles.d/foo.conf'.
+ # `/run/tmpfiles/foo.conf' will always be read after `/etc/tmpfiles.d/bar.conf'
+ for d in ${tmpfiles_dirs} ; do
+ [ -d "${d}" ] && for f in "${d}"/*.conf ; do
+ case "${f##*/}" in
+ systemd.conf|systemd-*.conf) continue;;
+ esac
+ [ -f "${f}" ] && tmpfiles_basenames="${tmpfiles_basenames}\n${f##*/}"
+ done # for f in ${d}
+ done # for d in ${tmpfiles_dirs}
+ # shellcheck disable=SC2059
+ FILES="$(printf "${tmpfiles_basenames}" | sort -u )"
+fi
+
+tmpfiles_d=''
+
+for b in ${FILES} ; do
+ if [ "${b##*/}" != "${b}" ]; then
+ # The user specified a path on the command line
+ # Just pass it through unaltered
+ tmpfiles_d="${tmpfiles_d} ${b}"
+ else
+ real_f=''
+ for d in ${tmpfiles_dirs} ; do
+ f=${d}/${b}
+ [ -f "${f}" ] && real_f=${f}
+ done
+ [ -f "${real_f}" ] && tmpfiles_d="${tmpfiles_d} ${real_f}"
+ fi
+done
+
+error=0
+
+# loop through the gathered fragments, sorted globally by filename.
+# `/run/tmpfiles/foo.conf' will always be read after `/etc/tmpfiles.d/bar.conf'
+FILE=
+for FILE in ${tmpfiles_d} ; do
+ LINENUM=0
+
+ ### FILE FORMAT ###
+ # XXX: We ignore the 'Age' parameter
+ # 1 2 3 4 5 6 7
+ # Cmd Path Mode UID GID Age Argument
+ # d /run/user 0755 root root 10d -
+ # Mode, UID, GID, Age, Argument may be omitted!
+ # If Cmd ends with !, the line is only processed if --boot is passed
+
+ # XXX: Upstream says whitespace is NOT permitted in the Path argument.
+ # But IS allowed when globs are expanded for the x/r/R/z/Z types.
+ while read -r cmd path mode uid gid age arg rest; do
+ LINENUM=$(( LINENUM+1 ))
+ FORCE=0
+
+ # Unless we have both command and path, skip this line.
+ if [ -z "${cmd}" ] || [ -z "${path}" ]; then
+ continue
+ fi
+
+ case ${cmd} in
+ \#*) continue ;;
+ esac
+
+ while [ ${#cmd} -gt 1 ]; do
+ case ${cmd} in
+ *!) cmd=${cmd%!}; [ "${BOOT}" -eq "1" ] || continue 2 ;;
+ *+) cmd=${cmd%+}; FORCE=1; ;;
+ *) warninvalid ; continue 2 ;;
+ esac
+ done
+
+ # whine about invalid entries
+ case ${cmd} in
+ f|F|w|d|D|v|p|L|c|C|b|x|X|r|R|z|Z|q|Q|h|H|a|A) ;;
+ *) warninvalid ; continue ;;
+ esac
+
+ # fall back on defaults when parameters are passed as '-'
+ if [ "${mode}" = '-' ] || [ "${mode}" = '' ]; then
+ case "${cmd}" in
+ p|f|F) mode=0644 ;;
+ d|D|v) mode=0755 ;;
+ C|z|Z|x|r|R|L) ;;
+ esac
+ fi
+
+ [ "${uid}" = '-' ] || [ "${uid}" = '' ] && uid=0
+ [ "${gid}" = '-' ] || [ "${gid}" = '' ] && gid=0
+ [ "${age}" = '-' ] || [ "${age}" = '' ] && age=0
+ [ "${arg}" = '-' ] || [ "${arg}" = '' ] && arg=''
+ set -- "${path}" "${mode}" "${uid}" "${gid}" "${age}" "${arg}"
+
+ [ -n "${EXCLUDE}" ] && checkprefix "${path}" "${EXCLUDE}" && continue
+ [ -n "${PREFIX}" ] && ! checkprefix "${path}" "${PREFIX}" && continue
+
+ if [ "${FORCE}" -gt 0 ]; then
+ case ${cmd} in
+ p|L|c|b) [ -f "${path}" ] && dryrun_or_real rm -f "${path}"
+ esac
+ fi
+
+ [ "${VERBOSE}" -eq "1" ] && echo "_${cmd}" "$@"
+ "_${cmd}" "$@"
+ rc=$?
+ if [ "${DRYRUN}" -eq "0" ]; then
+ [ ${rc} -ne 0 ] && error=$((error + 1))
+ fi
+ done <"${FILE}"
+done
+
+exit ${error}
+
+# vim: set ts=2 sw=2 sts=2 noet ft=sh: