This is the same concept as systemd's tmpfiles handling, slightly
simplified to avoid timed re-triggering of file cleaning. Most of our
current file cleaning that takes place in rc.single and rc.sysinit is
replaced by this, with the exception that we hold onto the /var/lock and
/var/run for finer control, since we still check for the possibility of
these directories being symlinks and adjust accordingly.

Signed-off-by: Dave Reisner <[email protected]>
---
Tom and I talked about this tonight and I volunteered to hack it up. It's a
simple but fairly substantial framework for handling temporary files and
directories which is compatible with systemd. For more detail, see the man
page[1], but I've taken most of the relevant bits and added them to the main
tmpfiles script as documentation. It should be fairly self explanatory.

[1] http://0pointer.de/public/systemd-man/tmpfiles.d.html

 Makefile      |   13 ++++-
 arch-tmpfiles |  156 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 functions     |    6 +--
 tmpfiles.conf |   20 +++++++
 4 files changed, 190 insertions(+), 5 deletions(-)
 create mode 100755 arch-tmpfiles
 create mode 100644 tmpfiles.conf

diff --git a/Makefile b/Makefile
index c568b13..9fd2347 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,14 @@
 VER  := $(shell git describe)
-DIRS := /etc/rc.d /etc/conf.d /etc/rc.d/functions.d /etc/logrotate.d /sbin 
/etc/bash_completion.d /usr/share/zsh/site-functions
+DIRS := \
+       /etc/rc.d \
+       /etc/conf.d \
+       /etc/rc.d/functions.d \
+       /etc/logrotate.d \
+       /sbin \
+       /usr/lib/tmpfiles.d \
+       /usr/lib/initscripts \
+       /etc/bash_completion.d \
+       /usr/share/zsh/site-functions
 
 minilogd: minilogd.o
 
@@ -13,6 +22,8 @@ install: minilogd installdirs
        install -m644 -t $(DESTDIR)/etc/rc.d functions
        install -m755 -t $(DESTDIR)/etc/rc.d hwclock network netfs
        install -m755 -t $(DESTDIR)/sbin minilogd rc.d
+       install -m755 -t $(DESTDIR)/usr/lib/initscripts arch-tmpfiles
+       install -m644 tmpfiles.conf $(DESTDIR)/usr/lib/tmpfiles.d/arch.conf
        install -m644 -T bash-completion $(DESTDIR)/etc/bash_completion.d/rc.d
        install -m644 -T zsh-completion 
$(DESTDIR)/usr/share/zsh/site-functions/_rc.d
 
diff --git a/arch-tmpfiles b/arch-tmpfiles
new file mode 100755
index 0000000..194a44b
--- /dev/null
+++ b/arch-tmpfiles
@@ -0,0 +1,156 @@
+#!/bin/bash
+#
+# /usr/lib/initscripts/tmpfiles
+#
+# Control of creation, deletion, and cleaning of volatile and temporary files
+#
+
+_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" <(:) "$path"
+       fi
+}
+
+_F() {
+       # Create or truncate a file
+       local path=$1 mode=$2 uid=$3 gid=$4
+
+       install -m"$mode" -o"$uid" -g"$gid" <(:) "$path"
+}
+
+_d() {
+       # Create a directory if it doesn't exist yet
+       local path=$1 mode=$2 uid=$3 gid=$4
+
+       if [[ ! -d "$path" ]]; then
+               install -d -m"$mode" -o"$uid" -g"$gid" "$path"
+       fi
+}
+
+_D() {
+       # Create or empty a directory
+       local path=$1 mode=$2 uid=$3 gid=$4
+
+       if [[ -d $path ]]; then
+               (
+                       shopt -s dotglob
+                       rm --one-file-system -rf "$path"/*
+               )
+       fi
+       install -d -m"$mode" -o"$uid" -g"$gid" "$path"
+}
+
+_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.
+       :
+       # 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 -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 -a paths=($1)
+
+       for path in "${paths[@]}"; do
+               [[ -d $path ]] && rm -rf --one-file-system "$path"
+       done
+}
+
+shopt -s nullglob
+
+# catch errors in functions so we can exit with something meaningfully
+set -E
+trap '(( ++error ))' ERR
+
+declare -i error=0
+declare -A fragments
+declare -a tmpfiles_d=(
+       /usr/lib/tmpfiles.d/*.conf
+       /etc/tmpfiles.d/*.conf
+       /run/tmpfiles.d/*.conf
+)
+
+# 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
+       fragments[${path##*/}]=${path%/*}
+done
+
+# loop through the gathered fragments, sorted globally by filename
+while read -d '' fragment; do
+       declare -i i=0
+
+       printf -v file '%s/%s' "${fragments[$fragment]}" "$fragment"
+
+       ### FILE FORMAT ###
+       # XXX: We ignore the final 'Age' parameter
+       # 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.
+       while read -a line; do
+               (( ++i ))
+
+               # skip over comments and empty lines
+               if (( ! ${#line[*]} )) || [[ ${line[0]:0:1} = '#' ]]; then
+                       continue
+               fi
+
+               # whine about invalid entries
+               if ! type -t _${line[0]} >/dev/null; then
+                       printf "arch-tmpfiles: skipping malformed entry on line 
%d of \`%s'\n" "$i" "$file"
+                       (( ++error ))
+                       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
+               [[ ${line[3]} = '-' ]] && line[3]=0
+               [[ ${line[4]} = '-' ]] && line[4]=0
+
+               _${line[0]} "${line[@]:1}"
+       done <"$file"
+done < <(printf '%s\0' "${!fragments[@]}" | sort -z)
+
+exit $error
+
+# vim: set ts=2 sw=2 noet:
diff --git a/functions b/functions
index 1cfcf28..a894a46 100644
--- a/functions
+++ b/functions
@@ -420,15 +420,13 @@ mount_all() {
 
 remove_leftover() {
        stat_busy "Removing Leftover Files"
-               rm -rf /etc/{nologin,shutdownpid} /forcefsck /tmp/* /tmp/.[^.]* 
/tmp/..?* /var/run/daemons
+               # handle this separately until we declare the non-symlinks 
obsoleted
                [[ ! -L /var/lock ]] && rm -rf /var/lock/*
                if [[ ! -L /var/run && -d /var/run ]]; then
                        find /var/run/ \! -type d -delete
                        ln -s /run/daemons /var/run/daemons
                fi
-               install -Tm 0664 -o root -g utmp <(:) /var/run/utmp
-               # Keep {x,k,g}dm happy with xorg
-               mkdir -m 1777 /tmp/.{X11,ICE}-unix
+               /usr/lib/initscripts/arch-tmpfiles || stat_fail
        stat_done
 }
 
diff --git a/tmpfiles.conf b/tmpfiles.conf
new file mode 100644
index 0000000..d47a028
--- /dev/null
+++ b/tmpfiles.conf
@@ -0,0 +1,20 @@
+#
+# /usr/lib/tmpfiles.d/arch.conf
+#
+
+d /tmp/.X11-unix 1777 root root 10d
+d /tmp/.ICE-unix 1777 root root 10d
+d /tmp/.XIM-unix 1777 root root 10d
+d /tmp/.font-unix 1777 root root 10d
+d /tmp/.Test-unix 1777 root root 10d
+
+f /var/run/tmp 0664 - utmp
+
+r /tmp/.X[0-9]-lock
+r /etc/nologin
+r /etc/shutdownpid
+r /forcefsck
+
+D /tmp/
+D /var/run/daemons
+
-- 
1.7.6

Reply via email to