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 "$@" \)