Mercurial > pkg
diff previous-work/more_control_helpers/bin/forall_direntries_from @ 1:d6bef198ae71
add work by Matthias S. Benkmann which is the inspiration for this project.
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Tue, 08 Jan 2013 11:45:01 +0000 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/previous-work/more_control_helpers/bin/forall_direntries_from Tue Jan 08 11:45:01 2013 +0000 1.3 @@ -0,0 +1,101 @@ 1.4 +#!/bin/bash 1.5 +# Copyright (c) 2004 Matthias S. Benkmann <article AT winterdrache DOT de> 1.6 +# You may do everything with this code except misrepresent its origin. 1.7 +# PROVIDED `AS IS' WITH ABSOLUTELY NO WARRANTY OF ANY KIND! 1.8 + 1.9 +#The following list should contain the mount points of all filesystems 1.10 +#that are to be scanned as a space-separated list within parentheses. 1.11 +#/ will usually be in this list and if you have /usr 1.12 +#on a separate partition, it will also be in this list. Other non-special 1.13 +#filesystems where package users could own files should also be put in this 1.14 +#list. 1.15 +#Mount points whose filesystems are special, such as procfs or sysfs must 1.16 +#not be in this list. While a simple find on those special filesystems should 1.17 +#be harmless, operations such as "-exec grep something" are NOT SAFE and may 1.18 +#have HARMFUL SIDE-EFFECTS, especially when performed as root. 1.19 +fs_to_scan=(/) 1.20 + 1.21 +#Files with a path prefix found in the following list are ignored. 1.22 +#This list will usually contain the parent directory of your package users' 1.23 +#home directories, because normally you don't want to scan those. You can 1.24 +#also add other directories that will never contain package user files, such 1.25 +#as /home. This reduces scan time. 1.26 +#NOTE: The LFS-6.0 book uses a ramfs mounted on /dev and with that setup 1.27 +#/dev does not need to be in the prune list. But since there is no requirement 1.28 +#that /dev have its on filesystem it's better to prune it explicitly. 1.29 +prune_prefixes=(/home /usr/src /dev /tools) #NO TRAILING SLASHES!!!! 1.30 + 1.31 +if [ $# -lt 1 -o "$1" = "--help" ]; then 1.32 + echo 1>&2 1.33 + echo 1>&2 'USAGE: '"${0##*/}"' <user_or_group_name> [<find-commands>]' 1.34 + echo 1>&2 1.35 + echo 1>&2 ' If <find-commands> contains no action other than -prune, -print will be' 1.36 + echo 1>&2 ' executed for all matching files.' 1.37 + echo 1>&2 ' Entries will be matched if group and/or user equals <user_or_group_name>' 1.38 + echo 1>&2 ' (numeric UID/GID allowed).' 1.39 + echo 1>&2 ' All matching entries will be acted on, including device special files, so' 1.40 + echo 1>&2 ' you should be extra careful with the <find-commands> you provide!' 1.41 + echo 1>&2 1.42 + exit 1 1.43 +fi 1.44 + 1.45 +#suppress ugly debug output from shell 1.46 +trap ':' SIGPIPE 1.47 + 1.48 +ugname="$1" 1.49 +shift 1 #remove user_or_group_name from argument list 1.50 + 1.51 +# Recent versions of find issue a warning if "-depth" is listed after a 1.52 +# non-option argument. To prevent this warning if -depth is passed to 1.53 +# this script, we pick up the "-depth" argument here to move it to the 1.54 +# front later on. 1.55 +depth="" 1.56 +if [ "_$1" = "_-depth" ]; then 1.57 + depth=-depth 1.58 + shift 1 1.59 +fi 1.60 + 1.61 +ugmatcher=(-false) 1.62 +#test if find accepts ugname as a user, and append to ugmatcher if it does 1.63 +if find / -maxdepth 0 -user "$ugname" >/dev/null 2>&1 ; then 1.64 + ugmatcher[${#ugmatcher[@]}]="-or" 1.65 + ugmatcher[${#ugmatcher[@]}]="-user" 1.66 + ugmatcher[${#ugmatcher[@]}]="$ugname" 1.67 +fi 1.68 +#test if find accepts ugname as a group, and append to ugmatcher if it does 1.69 +if find / -maxdepth 0 -group "$ugname" >/dev/null 2>&1 ; then 1.70 + ugmatcher[${#ugmatcher[@]}]="-or" 1.71 + ugmatcher[${#ugmatcher[@]}]="-group" 1.72 + ugmatcher[${#ugmatcher[@]}]="$ugname" 1.73 +fi 1.74 + 1.75 +#if find accepted ugname as neither user nor group, then exit 1.76 +if [ "${#ugmatcher[@]}" = 1 ]; then 1.77 + echo 1>&2 'find does not accept `'"$ugname'"' as group or user name' 1.78 + exit 1 1.79 +fi 1.80 + 1.81 +#construct find commands that match the prune_prefixes. Each prefix will be 1.82 +#matched as -path <prefix> -or -path <prefix>/* 1.83 +#so that the directory itself and all subdirectories are matched. 1.84 +y=(\( -false) 1.85 +for ((i=0; $i<${#prune_prefixes[@]}; i=$i+1)) 1.86 +do 1.87 + y[${#y[@]}]='-or' 1.88 + y[${#y[@]}]=-path 1.89 + y[${#y[@]}]="${prune_prefixes[$i]}" 1.90 + y[${#y[@]}]='-or' 1.91 + y[${#y[@]}]=-path 1.92 + y[${#y[@]}]="${prune_prefixes[$i]}/*" 1.93 +done 1.94 +y[${#y[@]}]=')' 1.95 + 1.96 +#In the following find command, the part 1.97 +# -not ( ( "${y[@]}" -prune ) -or "${y[@]}" ) 1.98 +#is responsible for preventing the files that match prune_prefixes from 1.99 +#being processed. The 2nd "${y[@]}" may seem redundant, but it isn't, because 1.100 +#-prune has no effect and is always false when -depth is used. 1.101 +#The -true before "$@" ensures that -depth can be passed as only parameter. 1.102 +find "${fs_to_scan[@]}" $depth -xdev -noleaf \ 1.103 + -not \( \( "${y[@]}" -prune \) -or "${y[@]}" \) \ 1.104 + -and \( "${ugmatcher[@]}" \) -and \( -true "$@" \)