1f6f386f87372b1fc88e5e6efc0f7e30615d74f2
[pkgusr] / usr / bin / forall_direntries_from
1 #!/bin/bash
2 ## Originally...
3 # Copyright (c) 2004 Matthias S. Benkmann <article AT winterdrache DOT de>
4 # You may do everything with this code except misrepresent its origin.
5 # PROVIDED `AS IS' WITH ABSOLUTELY NO WARRANTY OF ANY KIND!
6
7 # Copyright (C) 2014 Steve Youngs <steve@steveyoungs.com>
8 ## Loads of minor tweaks --SY.
9
10 # The following list should contain the mount points of all
11 # filesystems that are to be scanned as a space-separated list within
12 # parentheses. / will usually be in this list and if you have /usr on
13 # a separate partition, it will also be in this list. Other
14 # non-special filesystems where package users could own files should
15 # also be put in this list. Mount points whose filesystems are
16 # special, such as procfs or sysfs must not be in this list. While a
17 # simple find on those special filesystems should be harmless,
18 # operations such as "-exec grep something" are NOT SAFE and may have
19 # HARMFUL SIDE-EFFECTS, especially when performed as root.
20
21 ## Bastard settings
22 # fs_to_scan=(/ /opt /usr /var)
23
24 fs_to_scan=(/)
25
26 # Files with a path prefix found in the following list are ignored. This
27 # list will usually contain the parent directory of your package users'
28 # home directories, because normally you don't want to scan those. You
29 # can also add other directories that will never contain package user
30 # files, such as /home. This reduces scan time.
31
32 # Directories that are on separate filesystems (separate from the ones
33 # listed in fs_to_scan above) don't need to be listed here because of
34 # the -xdev option used in the find command.
35
36 ## Bastard settings
37 ## My /usr/src is NOT included here because it is on a separate
38 ## filesystem
39 # prune_prefixes=(\
40 #     /{,*/{,*/}}lost+found \
41 #     /etc/apache/ssl.key \
42 #     /etc/audisp/plugins.d \
43 #     /etc/cups/ssl \
44 #     /etc/firewall \
45 #     /etc/mail/{auth,spamassassin} \
46 #     /etc/pam.d \
47 #     /etc/polkit-1/rules.d \
48 #     /etc/skel \
49 #     /etc/ssl/private \
50 #     /etc/sudoers.d \
51 #     /opt/pgsql/data \
52 #     /opt/sql-ledger/{spool,templates,users,css} \
53 #     /root \
54 #     /usr/lib/deprecated \
55 #     /usr/lib/pkgusr \
56 #     /usr/share/polkit-1/rules.d \
57 #     /var/{cache,chroot,db,run,snmp,spool} \
58 #     /var/lib/{bluetooth,xdm} \
59 #     /var/lib/{sasl,sudo,net-snmp,udisks{,2},NetworkManager} \
60 #     /var/lib/{sshd,nfs,spamassassin,portables,private,pulse,machines} \
61 #     /var/lib/colord/.cache \
62 #     /var/log \
63 #     /var/tmp) #NO TRAILING SLASHES!!!!
64
65 prune_prefixes=(\
66     /home \
67     /root \
68     /usr/lib/pkgusr \
69     /usr/src) #NO TRAILING SLASHES!!!!
70
71 ## NOTE: 
72 # If you are scanning MS-DOS, CD-ROM, or AFS volumes you need
73 # to set $NOLEAF here to '-noleaf'.  Setting this does significantly
74 # slow down the search so only do so if you really need to.
75
76 # NOLEAF='-noleaf'
77 NOLEAF=
78
79 if [ $# -lt 1 -o "$1" = "--help" ]; then
80     echo 1>&2
81     echo 1>&2 'USAGE: '"${0##*/}"' <user_or_group_name> [<find-commands>]'
82     echo 1>&2
83     echo 1>&2 '  If <find-commands> contains no action other than -prune, -print will be'
84     echo 1>&2 '    executed for all matching files.'
85     echo 1>&2 '  Entries will be matched if group and/or user equals <user_or_group_name>'
86     echo 1>&2 '    (numeric UID/GID allowed).'
87     echo 1>&2 '  All matching entries will be acted on, including device special files, so'
88     echo 1>&2 '    you should be extra careful with the <find-commands> you provide!'
89     echo 1>&2
90     exit 1
91 fi
92
93 # suppress ugly debug output from shell
94 trap ':' SIGPIPE
95
96 ugname="$1"
97 shift 1  # remove user_or_group_name from argument list
98
99 ugmatcher=(-false)
100 # test if find accepts ugname as a user, and append to ugmatcher if it does
101 if find / -maxdepth 0 -user "$ugname" >/dev/null 2>&1 ; then
102     ugmatcher[${#ugmatcher[@]}]="-or"
103     ugmatcher[${#ugmatcher[@]}]="-user"
104     ugmatcher[${#ugmatcher[@]}]="$ugname"
105 fi
106 # test if find accepts ugname as a group, and append to ugmatcher if it does
107 if find / -maxdepth 0 -group "$ugname" >/dev/null 2>&1 ; then
108     ugmatcher[${#ugmatcher[@]}]="-or"
109     ugmatcher[${#ugmatcher[@]}]="-group"
110     ugmatcher[${#ugmatcher[@]}]="$ugname"
111 fi
112
113 # if find accepted ugname as neither user nor group, then exit
114 if [ "${#ugmatcher[@]}" = 1 ]; then
115     echo 1>&2 'find does not accept `'"$ugname'"' as group or user name'
116     exit 1
117 fi
118
119 # construct find commands that match the prune_prefixes. Each prefix will be
120 # matched as -path <prefix> -or -path <prefix>/*
121 # so that the directory itself and all subdirectories are matched.
122 y=(\( -false)
123 for ((i=0; $i<${#prune_prefixes[@]}; i=$i+1))
124 do
125     y[${#y[@]}]='-or'
126     y[${#y[@]}]=-path
127     y[${#y[@]}]="${prune_prefixes[$i]}"
128     y[${#y[@]}]='-or'
129     y[${#y[@]}]=-path
130     y[${#y[@]}]="${prune_prefixes[$i]}/*"
131 done
132 y[${#y[@]}]=')'
133
134 # The uninstall_package script sets this to `-ignore_readdir_race' so
135 # that find doesn't print errors when things it is searching for
136 # disappear.
137 # IGNORE_READDIR_RACE='-ignore_readdir_race'
138 IGNORE_READDIR_RACE=
139
140 # In the following find command, the part
141 # -not ( ( "${y[@]}" -prune ) -or "${y[@]}" )
142 # is responsible for preventing the files that match prune_prefixes from
143 # being processed. The 2nd "${y[@]}" may seem redundant, but it isn't, because
144 # -prune has no effect and is always false when -depth is used.
145 # The -true before "$@" ensures that -depth can be passed as only parameter.
146
147 find "${fs_to_scan[@]}" -xdev $NOLEAF $IGNORE_READDIR_RACE \
148     -not \( \( "${y[@]}" -prune \) -or "${y[@]}" \) \
149     -and \( "${ugmatcher[@]}" \) -and \( -true "$@" \)