Mercurial > pkg
comparison previous-work/more_control_helpers/bin/list_package @ 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 |
comparison
equal
deleted
inserted
replaced
0:0b7a589f6e9a | 1:d6bef198ae71 |
---|---|
1 #!/bin/bash | |
2 # Copyright (c) 2004 Matthias S. Benkmann <article AT winterdrache DOT de> | |
3 # You may do everything with this code except misrepresent its origin. | |
4 # PROVIDED `AS IS' WITH ABSOLUTELY NO WARRANTY OF ANY KIND! | |
5 | |
6 if [ $# -lt 1 -o \( $# -gt 1 -a "z$1" != "z:man" -a "z$1" != "z:mani" -a "z$1" != "z:lib" \) -o "$1" = "--help" ]; then | |
7 echo 1>&2 | |
8 echo 1>&2 'USAGE: '"${0##*/}"' <user_or_group_name>' | |
9 echo 1>&2 | |
10 echo 1>&2 ' Entries will be matched if group and/or user equals <user_or_group_name>' | |
11 echo 1>&2 ' (numeric UID/GID allowed).' | |
12 echo 1>&2 ' This script uses `forall_direntries_from'"'"' and `list_suspicious_files_from'"'." | |
13 echo 1>&2 | |
14 echo 1>&2 ' NOTE: Several minutes may pass before you see the first output.' | |
15 echo 1>&2 ' You should probably redirect output to a file for later reference.' | |
16 echo 1>&2 | |
17 echo 1>&2 ' WARNING! This program is for listing files from package users only!' | |
18 echo 1>&2 ' Do NOT use it to list files from untrusted users!' | |
19 echo 1>&2 ' An untrusted user could set up a manipulated manpage to exploit' | |
20 echo 1>&2 ' a bug in man when it is used to extract the summary!' | |
21 exit 1 | |
22 fi | |
23 | |
24 # KNOWN BUGS: | |
25 # - when extracting summaries from manpages, candidate manpages are considered | |
26 # in alphabetic order rather than the order used by the man command. | |
27 # The problem with this is that section 8, which contains manpages for | |
28 # admin commands, will be considered after lower-numbered sections. | |
29 # In the rare case that an admin command has the same name as a topic from | |
30 # a lower-numbered manpage installed by the same package, the summary will | |
31 # be taken from the wrong manpage. | |
32 # An example for such a clash are the faillog.5 and faillog.8 manpages from | |
33 # the shadow package. | |
34 # Because this problem is difficult to fix, rare and easily spotted (since | |
35 # the manpage that should have provided the summary will be listed under | |
36 # EXTRA MANPAGES) I won't fix it. | |
37 | |
38 ugname="$1" | |
39 | |
40 #suppress ugly debug output from shell | |
41 trap ':' SIGPIPE | |
42 | |
43 if [ $# -gt 1 ]; then | |
44 name="${2##*/}" | |
45 case "$1" in | |
46 :man) | |
47 name=${name%.gz} | |
48 name=${name%.bz2} | |
49 name=${name%.*} | |
50 echo $'command\2'"$name"$'\2man\2'"$2" ;; | |
51 :mani) | |
52 name=${name%.gz} | |
53 name=${name%.bz2} | |
54 name=${name%.*} | |
55 echo $'command\2'"$name"$'\2mani\2'"$2" ;; | |
56 :lib) | |
57 name=${name%.a} | |
58 name=${name%%.so*} | |
59 echo "lib $name" | |
60 ;; | |
61 esac | |
62 exit 0 | |
63 fi | |
64 | |
65 sanitize() { tr -c '[:print:]' '?' ; } | |
66 | |
67 # $1: <commandname> | |
68 # $2: command\2<commandname>\2cmd\2(-><linktarget>) | |
69 # $3: command\2<commandname>\2man[i]\2<manpage_path> or <empty> | |
70 expand_command() | |
71 { | |
72 sep=$'\2' | |
73 cmdname="$1" | |
74 cmdline="$2" | |
75 manline="$3" | |
76 linktarget="${cmdline##*${sep}}" | |
77 | |
78 if [ -z "$manline" ]; then | |
79 description='No manpage' | |
80 #the "l" at the beginning is just to make it sort after "lib" | |
81 echo -n "lmanlessbin $cmdname" | sanitize | |
82 echo | |
83 | |
84 else # if [ ! -z "$manline" ]; then | |
85 manpage=${manline##*${sep}} | |
86 manpagedir=${manpage%/*} | |
87 wsc='[[:space:],]\+' | |
88 # The cd $manpagedir is a workaround for a bug in man-db that causes it | |
89 # to attempt to resolve paths relative to cwd. | |
90 # The `t l;d;:l;n;b l' in the sed command is voodoo magic to make sed | |
91 # output only the first match but to keep eating up all input. I use this | |
92 # instead of `| head -n 1', because head breaks the pipe after doing | |
93 # its 1 line output, which (if it happens before sed has processed the | |
94 # complete input) freaks out man and causes it to emit a totally | |
95 # silly error message including "No such file or directory", which is | |
96 # annoying when you do testing without suppressing man's errors. | |
97 # The $'s/.\b\\(.\\)/\\1/g;s/\x1b[^m]\\+m//g' removes the backspace-based | |
98 # as well as ESC-based formatting from man's output. | |
99 description="$( { cd "$manpagedir/.." 2>/dev/null ; | |
100 COLUMNS=300 man "$manpage" 2>/dev/null || | |
101 echo " $name - Broken manpage" ; } | | |
102 sed $'s/.\b\\(.\\)/\\1/g;s/\x1b[^m]\\+m//g' | | |
103 sed -n "/^NAME/,/^[A-Z]/s/^.*${wsc}${cmdname}${wsc}.*-\+${wsc}\(.*\)/\1/p;t l;d;:l;n;b l" )" | |
104 if [ -z "$description" ]; then | |
105 description="$( cd "$manpagedir/.." 2>/dev/null ; | |
106 COLUMNS=300 man "$manpage" 2>/dev/null | | |
107 sed $'s/.\b\\(.\\)/\\1/g;s/\x1b[^m]\\+m//g' | | |
108 sed -n "s/^.*${wsc}..*${wsc}.*-\+${wsc}\(.*\)/\1/p;t l;d;:l;n;b l" )" | |
109 fi | |
110 test -z "$description" && description="Weird manpage" | |
111 fi | |
112 | |
113 echo -n "binexe $cmdname" | sanitize | |
114 test "$linktarget" != '(->)' && echo -n "$linktarget" | sanitize | |
115 echo | |
116 #the "lx" in "lxdescription" is just to make sure it sorts after "lmanlessbin" | |
117 echo -n "lxdescription $cmdname: $description" | sanitize | |
118 echo | |
119 } | |
120 | |
121 # NOTE: The -path and -lname stuff at the beginning of the following is | |
122 # there to make sure that none of the lines output by find contains | |
123 # a) \n or \r, because that would mess up post-processing the output | |
124 # line-by-line. | |
125 # b) \x7f, because this character triggers one of the nastier bash-bugs | |
126 # wrt string handling | |
127 # c) \2, because I use this as separator within the lines | |
128 # (Why \2 and not \0 or \1 ? Because bash can't cope with \0 at all and has | |
129 # bugs related to \1.) | |
130 # | |
131 # Because of this, having the final section called "ALL FILES" is technically | |
132 # a lie, because files with a path containing one of the abovementioned | |
133 # characters will not appear in output. | |
134 # However, a) no sane package contains such files | |
135 # b) they will be listed in the output from list_suspicious_files | |
136 cmd=(\( -path $'*\n*' -or -path $'*\r*' -or -path $'*\x7f*' | |
137 -or -path $'*\2*' | |
138 -or -lname $'*\n*' -or -lname $'*\r*' -or -lname $'*\x7f*' | |
139 -or -lname $'*\2*' | |
140 \) | |
141 -or | |
142 \( | |
143 \( -printf "zall %p\n" \) , | |
144 \( | |
145 \( -type f -or -xtype f \) -and | |
146 \( | |
147 \( -perm -u+x \( -path "*/bin/*" -or -path "*/sbin/*" \) -printf 'command\2%f\2cmd\2(->%l)\n' \) | |
148 -or \( -path "*/man/man*/*" -exec "$0" ":man" {} \; \) | |
149 -or \( -path "*/man/*/man*/*" -exec "$0" ":mani" {} \; \) | |
150 -or \( \( -name "lib*.so" -or -name "lib*.a" -or -name "lib*.so.*" \) -path "*/lib/*" -exec "$0" ":lib" {} \; \) | |
151 -or \( -type f -perm -u+x -not \( \( -name "lib*.so" -or -name "lib*.a" -or -name "lib*.so.*" \) -path "*/lib/*" \) -printf "nobinexe %p\n" \) | |
152 \) | |
153 \) | |
154 \) | |
155 ) | |
156 | |
157 forall_direntries_from "$ugname" "${cmd[@]}" | sort -u | | |
158 { | |
159 sep=$'\2' | |
160 hold='' | |
161 for((;;)) | |
162 do | |
163 if [ -z "$hold" ]; then | |
164 read -r line || break | |
165 else | |
166 line="$hold" | |
167 hold='' | |
168 fi | |
169 | |
170 case "z$line" in | |
171 zcommand${sep}*${sep}cmd${sep}*) | |
172 cmdname=${line#command${sep}} | |
173 cmdname=${cmdname%%${sep}*} | |
174 read -r hold | |
175 case "z$hold" in | |
176 zcommand${sep}${cmdname}${sep}man${sep}*|zcommand${sep}${cmdname}${sep}mani${sep}*) | |
177 expand_command "$cmdname" "$line" "$hold" | |
178 hold='' | |
179 ;; | |
180 | |
181 z*) | |
182 expand_command "$cmdname" "$line" "" | |
183 ;; | |
184 esac | |
185 ;; | |
186 | |
187 zcommand${sep}*${sep}man${sep}*|command${sep}*${sep}mani${sep}*) | |
188 | |
189 echo -n "manextra ${line##*${sep}}" | sanitize | |
190 echo | |
191 ;; | |
192 | |
193 z*) | |
194 echo -n "$line" | sanitize | |
195 echo | |
196 ;; | |
197 esac | |
198 | |
199 done | |
200 } | sort | #no -u here, bc. the above processing may equalize different files | |
201 { | |
202 # (1) binexe: Executables (in *bin/) | |
203 # (2) lib: Libraries (in *lib/*) | |
204 # (3) lmanlessbin: Executables (in *bin/) without manpages | |
205 # (4) lxdescription: Summaries for executables (in *bin/) | |
206 # (5) manextra: Extra manpages | |
207 # full paths, no perms | |
208 # (6) nobinexe: Executables not in *bin/ (excluding *lib/*.so and *lib/*.so.*) | |
209 # full paths, no perms | |
210 # (7) zall: All files | |
211 # full paths, no perms | |
212 | |
213 curstate='' | |
214 while read -r line | |
215 do | |
216 newstate="${line%% *}" | |
217 if [ "$newstate" != "$curstate" ]; then | |
218 curstate="$newstate" | |
219 case "$curstate" in | |
220 binexe) | |
221 echo 'EXECUTABLES (in */bin or */sbin)' | |
222 echo -n " ${line#binexe }" | |
223 ;; | |
224 lib) | |
225 echo | |
226 echo | |
227 echo 'LIBRARIES (lib*.a or lib*.so)' | |
228 echo -n " ${line#lib }" | |
229 ;; | |
230 lmanlessbin) | |
231 echo | |
232 echo | |
233 echo 'EXECUTABLES WITH NO MANPAGE (in */bin or */sbin)' | |
234 echo -n " ${line#lmanlessbin }" | |
235 ;; | |
236 lxdescription) | |
237 echo | |
238 echo | |
239 echo 'MANPAGE SUMMARIES OF EXECUTABLES (in */bin or */sbin)' | |
240 echo " ${line#lxdescription }" | |
241 ;; | |
242 manextra) | |
243 echo | |
244 echo 'EXTRA MANPAGES' | |
245 echo " ${line#manextra }" | |
246 ;; | |
247 nobinexe) | |
248 echo | |
249 echo 'EXTRA EXECUTABLES (not in */bin or */sbin)' | |
250 echo " ${line#nobinexe }" | |
251 ;; | |
252 zall) | |
253 echo | |
254 echo 'ALL FILES' | |
255 echo " ${line#zall }" | |
256 ;; | |
257 *) | |
258 echo | |
259 echo | |
260 echo 'UNEXPECTED LINE' | |
261 echo " $line" | |
262 ;; | |
263 | |
264 esac | |
265 else | |
266 case "$curstate" in | |
267 binexe) echo -n ", ${line#binexe }" | |
268 ;; | |
269 lib) echo -n ", ${line#lib }" | |
270 ;; | |
271 lmanlessbin) echo -n ", ${line#lmanlessbin }" | |
272 ;; | |
273 lxdescription) echo " ${line#lxdescription }" | |
274 ;; | |
275 manextra) echo " ${line#manextra }" | |
276 ;; | |
277 nobinexe) echo " ${line#nobinexe }" | |
278 ;; | |
279 zall) echo " ${line#zall }" | |
280 ;; | |
281 *) | |
282 echo | |
283 echo 'UNEXPECTED LINE' | |
284 echo " $line" | |
285 ;; | |
286 esac | |
287 fi | |
288 done | |
289 } | |
290 | |
291 list_suspicious_files_from "$ugname" |