From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from pigeon.gentoo.org ([208.92.234.80] helo=lists.gentoo.org) by finch.gentoo.org with esmtp (Exim 4.60) (envelope-from ) id 1S70ll-0001b1-A6 for garchives@archives.gentoo.org; Mon, 12 Mar 2012 08:38:17 +0000 Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 8C49DE0B3C; Mon, 12 Mar 2012 08:38:05 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) by pigeon.gentoo.org (Postfix) with ESMTP id 4E11CE0B3C for ; Mon, 12 Mar 2012 08:38:05 +0000 (UTC) Received: from hornbill.gentoo.org (hornbill.gentoo.org [94.100.119.163]) (using TLSv1 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 042FA1BC012 for ; Mon, 12 Mar 2012 08:38:04 +0000 (UTC) Received: from localhost.localdomain (localhost [127.0.0.1]) by hornbill.gentoo.org (Postfix) with ESMTP id B4F5AE5402 for ; Mon, 12 Mar 2012 08:38:02 +0000 (UTC) From: "Robin H. Johnson" To: gentoo-commits@lists.gentoo.org Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Robin H. Johnson" Message-ID: <1331541451.c75352af3d787377c4aa62baa1331f37db3d1d97.robbat2@gentoo> Subject: [gentoo-commits] proj/openrc:master commit in: sh/ X-VCS-Repository: proj/openrc X-VCS-Files: sh/.gitignore sh/Makefile sh/tmpfiles.sh.in X-VCS-Directories: sh/ X-VCS-Committer: robbat2 X-VCS-Committer-Name: Robin H. Johnson X-VCS-Revision: c75352af3d787377c4aa62baa1331f37db3d1d97 X-VCS-Branch: master Date: Mon, 12 Mar 2012 08:38:02 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: quoted-printable X-Archives-Salt: 5fe23940-86e5-4513-aff9-f79ac37eb609 X-Archives-Hash: 31cd7b6b39979344d625564f3970f964 commit: c75352af3d787377c4aa62baa1331f37db3d1d97 Author: Robin H. Johnson gentoo org> AuthorDate: Mon Mar 12 08:28:44 2012 +0000 Commit: Robin H. Johnson gentoo org> CommitDate: Mon Mar 12 08:37:31 2012 +0000 URL: http://git.overlays.gentoo.org/gitweb/?p=3Dproj/openrc.git;a=3D= commit;h=3Dc75352af sh/tmpfiles: tmpfiles.d support. This is the baseline support for tmpfiles.d. Still missing: - SELinux relabel, pending upstream clarification - LIBDIR vs multilib systems, pending upstream clarification - Whitespace in paths? - Clean support not implemented - "x" exclude type not implemented X-Gentoo-Bug: 396003 X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=3D396003 Signed-off-by: Robin H. Johnson gentoo.org> --- sh/.gitignore | 1 + sh/Makefile | 4 +- sh/tmpfiles.sh.in | 286 +++++++++++++++++++++++++++++++++++++++++++++++= ++++++ 3 files changed, 289 insertions(+), 2 deletions(-) diff --git a/sh/.gitignore b/sh/.gitignore index f67b992..3f6ef3f 100644 --- a/sh/.gitignore +++ b/sh/.gitignore @@ -9,3 +9,4 @@ init-early.sh ifwatchd-carrier.sh ifwatchd-nocarrier.sh udhcpc-hook.sh +tmpfiles.sh diff --git a/sh/Makefile b/sh/Makefile index 15b24d0..4df8fde 100644 --- a/sh/Makefile +++ b/sh/Makefile @@ -1,8 +1,8 @@ DIR=3D ${LIBEXECDIR}/sh SRCS=3D init.sh.in functions.sh.in gendepends.sh.in init-common-post.sh.= in \ - rc-functions.sh.in runscript.sh.in ${SRCS-${OS}} + rc-functions.sh.in runscript.sh.in tmpfiles.sh.in ${SRCS-${OS}} INC=3D init-common-post.sh rc-mount.sh functions.sh rc-functions.sh -BIN=3D gendepends.sh init.sh runscript.sh ${BIN-${OS}} +BIN=3D gendepends.sh init.sh runscript.sh tmpfiles.sh ${BIN-${OS}} =20 INSTALLAFTER=3D _installafter =20 diff --git a/sh/tmpfiles.sh.in b/sh/tmpfiles.sh.in new file mode 100755 index 0000000..9c73897 --- /dev/null +++ b/sh/tmpfiles.sh.in @@ -0,0 +1,286 @@ +#!/bin/sh +# This is a reimplementation of the systemd tmpfiles.d code +# Control creation, deletion, and cleaning of volatile and temporary fil= es +# +# Copyright (c) 2012 Gentoo Foundation +# +# This instance based on the Arch Linux version: +# http://projects.archlinux.org/initscripts.git/tree/arch-tmpfiles +# As of 2012/01/01 +# +# See the tmpfiles.d manpage as well: +# http://0pointer.de/public/systemd-man/tmpfiles.d.html +# This script should match the manpage as of 2012/03/12 +# + +warninvalid() { + printf "tmpfiles: ignoring invalid entry on line %d of \`%s'\n" "$LINEN= UM" "$FILE" + error=3D$(( error+1 )) +} >&2 + +relabel() { + local paths=3D$1 mode=3D$2 uid=3D$3 gid=3D$4 + + for path in ${paths}; do + if [ -e $path ]; then + [ $uid !=3D '-' ] && chown $CHOPTS "$uid" "$path" + [ $gid !=3D '-' ] && chgrp $CHOPTS "$gid" "$path" + [ $mode !=3D '-' ] && chmod $CHOPTS "$mode" "$path" + # TODO: SELinux relabel + fi + done +} +_b() { + # Create a block device node if it doesn't exist yet + local path=3D$1 mode=3D$2 uid=3D$3 gid=3D$4 age=3D$5 arg=3D$6 + [ ! -e "$path" ] && mknod $path b ${arg%:*} ${arg#*:} +} + +_c() { + # Create a character device node if it doesn't exist yet + local path=3D$1 mode=3D$2 uid=3D$3 gid=3D$4 age=3D$5 arg=3D$6 + [ ! -e "$path" ] && mknod $path c ${arg%:*} ${arg#*:} +} + + +_f() { + # Create a file if it doesn't exist yet + local path=3D$1 mode=3D$2 uid=3D$3 gid=3D$4 age=3D$5 arg=3D$6 + + [ $CREATE -gt 0 ] || return 0 + + if [ ! -e $path ]; then + install -m"$mode" -o"$uid" -g"$gid" /dev/null "$path" + [ -n "$arg" ] && _w "$@" + fi +} + +_F() { + # Create or truncate a file + local path=3D$1 mode=3D$2 uid=3D$3 gid=3D$4 age=3D$5 arg=3D$6 + + [ $CREATE -gt 0 ] || return 0 + + install -m"$mode" -o"$uid" -g"$gid" /dev/null "$path" + [ -n "$arg" ] && _w "$@" +} + +_d() { + # Create a directory if it doesn't exist yet + local path=3D$1 mode=3D$2 uid=3D$3 gid=3D$4 + + [ $CREATE -gt 0 ] || return 0 + + if [ ! -d "$path" ]; then + install -d -m"$mode" -o"$uid" -g"$gid" "$path" + fi +} + +_D() { + # Create or empty a directory + local path=3D$1 mode=3D$2 uid=3D$3 gid=3D$4 + + if [ -d $path ] && [ $REMOVE -gt 0 ]; then + find "$path" -mindepth 1 -maxdepth 1 -xdev -exec rm -rf {} + + fi + + if [ $CREATE -gt 0 ]; then + install -d -m"$mode" -o"$uid" -g"$gid" "$path" + fi +} + +_L() { + # Create a symlink if it doesn't exist yet + local path=3D$1 mode=3D$2 uid=3D$3 gid=3D$4 age=3D$5 arg=3D$6 + [ ! -e "$path" ] && ln -s "$args" "$path" +} + +_p() { + # Create a named pipe (FIFO) if it doesn't exist yet + local path=3D$1 mode=3D$2 uid=3D$3 gid=3D$4 + + [ $CREATE -gt 0 ] || return 0 + + 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 cl= ean-up as + # controlled with the Age parameter. Note that lines of this type do no= t + # 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 remo= ve + # non-empty directories, use R for that. Lines of this type accept shel= l-style + # globs in place of normal path names. + local path + local paths=3D$1 + + [ $REMOVE -gt 0 ] || return 0 + + 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 dire= ctory). + # Lines of this type accept shell-style globs in place of normal path n= ames. + local path + local paths=3D$1 + + [ $REMOVE -gt 0 ] || return 0 + + for path in "${paths}"; do + [ -d $path ] && rm -rf --one-file-system "$path" + done +} + +_w() { + # Write the argument parameter to a file, if it exists. + local path=3D$1 mode=3D$2 uid=3D$3 gid=3D$4 age=3D$5 arg=3D$6 + [ -f "$path" ] && echo "$arg" >>"$path" +} + +_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 i= n + # place of normal path names. + [ $CREATE -gt 0 ] || return 0 + + relabel "$@" +} + +_Z() { + # Recursively set ownership, access mode and relabel security context o= f 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=3D-R relabel "$@" +} + +CREATE=3D0 REMOVE=3D0 CLEAN=3D0 VERBOSE=3D0 DRYRUN=3D0 error=3D0 LINENO=3D= 0 +FILE=3D +fragments=3D +# TODO: The systemd spec explicitly says /usr/lib/, but it should probab= ly be +# OUTSIDE of lib entirely, or at the very least handle multilib systems = better. +tmpfiles_dirs=3D'/usr/lib64/tmpfiles.d/ /usr/lib/tmpfiles.d/ /etc/tmpfil= es.d/ /run/tmpfiles.d/' +tmpfiles_basenames=3D'' +tmpfiles_d=3D'' +# Build a list of sorted unique basenames +# directories declared later in the tmpfiles_d array will override earli= er +# 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/ba= r.conf' +for d in ${tmpfiles_dirs} ; do + [ -d $d ] && for f in ${d}/*.conf ; do + [ -f $f ] && tmpfiles_basenames=3D"${tmpfiles_basenames}\n${f##*/}" + done # for f in ${d} +done # for d in ${tmpfiles_dirs} +tmpfiles_basenames=3D"`printf "${tmpfiles_basenames}\n" | sort | uniq`" + +for b in $tmpfiles_basenames ; do + real_f=3D'' + for d in $tmpfiles_dirs ; do + f=3D${d}/${b} + [ -f "${f}" ] && real_f=3D$f + done + [ -f "${real_f}" ] && tmpfiles_d=3D"${tmpfiles_d} ${real_f}" +done + +while [ $# -gt 0 ]; do + case $1 in + --create) CREATE=3D1 ;; + --remove) REMOVE=3D1 ;; + --clean) CLEAN=3D1 ;; # TODO: Not implemented + --verbose) VERBOSE=3D1 ;; + --dryrun|--dry-run) DRYRUN=3D1 ;; + esac + shift +done + +if [ $(( CREATE + REMOVE )) -ne 1 ] ; then + printf 'usage: %s [--create] [--remove]\n' "${0##*/}" + exit 1 +fi + +error=3D0 + +# loop through the gathered fragments, sorted globally by filename. +# `/run/tmpfiles/foo.conf' will always be read after `/etc/tmpfiles.d/ba= r.conf' +for FILE in $tmpfiles_d ; do + LINENUM=3D0 + + ### 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! + + # TODO: Sorry, we don't handle whitespace in paths. + while read line; do + LINENUM=3D$(( LINENUM+1 )) + + # This will fix up whitespace and comment lines + # skip over comments and empty lines + set -- $line + + if [ -z "$1" -o -z "$2" ]; then + continue + fi + + # whine about invalid entries + case $1 in + f|F|w|d|D|p|L|c|b|x|r|R|z|Z) ;; + *) warninvalid ; continue ;; + esac + + cmd=3D$1 + path=3D$2 + + # fall back on defaults when parameters are passed as '-' + if [ "$3" =3D '-' -o "$3" =3D '' ]; then + case ${1} in + p|f|F) mode=3D0644 ;; + d|D) mode=3D0755 ;; + z|Z|x|r|R|L) ;; + esac + else + mode=3D$3 + fi + uid=3D$4 + gid=3D$5 + age=3D$6 + arg=3D$7 + + [ ${4} =3D '-' ] && uid=3D0 + [ ${5} =3D '-' ] && gid=3D0 + [ ${6} =3D '-' ] && age=3D0 + [ ${7} =3D '-' ] && arg=3D'' + set -- "$path" "$mode" "$uid" "$gid" "$age" "$arg" + + [ "$VERBOSE" -eq "1" ] && echo _$cmd "$@" + if [ "${DRYRUN}" -eq "0" ]; then + _$cmd "$@" + rc=3D$? + [ $rc -ne 0 ] && error=3D$((error + 1)) + fi + done <$FILE +done + +exit $error + +# vim: set ts=3D2 sw=3D2 sts=3D2 noet ft=3Dsh: