Commits

TZ86  committed a37a05a

arch-tmpfiles: implement exclude list (x and X actions)

thanks to Connor Behan again!

  • Participants
  • Parent commits 11f7262

Comments (0)

Files changed (2)

 * Implement parser for new crypttab format.
+* arch-tmpfiles: proper handling of nested exclude rules (for example: x /dir-*; X /dir-*/tmp)

File tools/arch-tmpfiles

 	echo $seconds
 }
 
+in_list() {
+	local search=$1
+
+	for item in "${EXCLUDE_LIST[@]}"; do
+		[[ "$search" == $item ]] && return 0
+	done
+
+	return 1
+}
+
 _f() {
 	# Create a file if it doesn't exist yet
 	local path=$1 mode=$2 uid=$3 gid=$4
 			local mod_time=$(stat -c %Y "$path")
 			if (( (current_time - mod_time) > age )); then
 				for file in $(find -P "$path" -mindepth 1 | sort -r); do
-					rm -fd "$file"
+					! in_list "$file" && rm -fd "$file"
 				done
 			fi
 		fi
 	# 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
+	local path=$1
+
+	if ! checkparams 1 "$@"; then
+		warninvalid
+		return
+	fi
+
+	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
+
+	if ! checkparams 1 "$@"; then
+		warninvalid
+		return
+	fi
+
+	EXCLUDE_LIST+=("$path")
 }
 
 _r() {
 	CHOPTS=-R relabel "$@"
 }
 
+process_lines ()
+{
+	local actions="$1"
+
+	TOTALNUM=0
+	while read -a line; do
+		(( ++TOTALNUM ))
+
+		[[ "${line[0]}" != $actions ]] && continue
+
+		LINENUM=${linenums[$TOTALNUM]}
+		FILE="${files[$TOTALNUM]}"
+		"_${line[@]}"
+	done < <(printf '%s\n' "${lines[@]}")
+}
+
 shopt -s nullglob
+shopt -s extglob
 
-declare -i CREATE=0 REMOVE=0 CLEAN=0 error=0 LINENO=0
+declare -i CREATE=0 REMOVE=0 CLEAN=0 error=0 LINENUM=0 TOTALNUM=0
 declare FILE=
 declare -A fragments
 declare -a tmpfiles_d=(
 	/etc/tmpfiles.d/*.conf
 	/run/tmpfiles.d/*.conf
 )
+declare -a EXCLUDE_LIST lines linenums files
 
 while (( $# )); do
 	case $1 in
 		[[ ${line[3]} = '-' ]] && line[3]='root'
 		[[ ${line[4]} = '-' ]] && line[4]='root'
 
-		"_${line[@]}"
+		(( ++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 "[^xX]"
+
 exit $error
 
 # vim: set ts=2 sw=2 noet: