cvsimport
[findutils.git] / locate / updatedb.sh
blob9f4e4d94cf32cc7057db65bc0121c6ab7ee829a2
1 #! /bin/sh
2 # updatedb -- build a locate pathname database
3 # Copyright (C) 1994, 1996, 1997, 2000, 2001, 2003, 2004, 2005, 2006
4 # Free Software Foundation, Inc.
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 # csh original by James Woods; sh conversion by David MacKenzie.
21 #exec 2> /tmp/updatedb-trace.txt
22 #set -x
24 version='
25 updatedb (@PACKAGE_NAME@) @VERSION@
26 Copyright (C) 2007 Free Software Foundation, Inc.
27 License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
28 This is free software: you are free to change and redistribute it.
29 There is NO WARRANTY, to the extent permitted by law.
31 Written by Eric B. Decker, James Youngman, and Kevin Dalley.
35 usage="\
36 Usage: $0 [--findoptions='-option1 -option2...']
37 [--localpaths='dir1 dir2...'] [--netpaths='dir1 dir2...']
38 [--prunepaths='dir1 dir2...'] [--prunefs='fs1 fs2...']
39 [--output=dbfile] [--netuser=user] [--localuser=user]
40 [--old-format] [--dbformat] [--version] [--help]
42 Report bugs to <bug-findutils@gnu.org>."
43 changeto=/
44 old=no
45 for arg
47 # If we are unable to fork, the back-tick operator will
48 # fail (and the shell will emit an error message). When
49 # this happens, we exit with error value 71 (EX_OSERR).
50 # Alternative candidate - 75, EX_TEMPFAIL.
51 opt=`echo $arg|sed 's/^\([^=]*\).*/\1/'` || exit 71
52 val=`echo $arg|sed 's/^[^=]*=\(.*\)/\1/'` || exit 71
53 case "$opt" in
54 --findoptions) FINDOPTIONS="$val" ;;
55 --localpaths) SEARCHPATHS="$val" ;;
56 --netpaths) NETPATHS="$val" ;;
57 --prunepaths) PRUNEPATHS="$val" ;;
58 --prunefs) PRUNEFS="$val" ;;
59 --output) LOCATE_DB="$val" ;;
60 --netuser) NETUSER="$val" ;;
61 --localuser) LOCALUSER="$val" ;;
62 --old-format) old=yes ;;
63 --changecwd) changeto="$val" ;;
64 --dbformat) dbformat="$val" ;;
65 --version) fail=0; echo "$version" || fail=1; exit $fail ;;
66 --help) fail=0; echo "$usage" || fail=1; exit $fail ;;
67 *) echo "updatedb: invalid option $opt
68 $usage" >&2
69 exit 1 ;;
70 esac
71 done
76 case "${dbformat:+yes}_${old}" in
77 yes_yes)
78 echo "The --dbformat and --old cannot both be specified." >&2
79 exit 1
81 *)
83 esac
85 if test "$old" = yes || test "$dbformat" = "old" ; then
86 echo "Warning: future versions of findutils will shortly discontinue support for the old locate database format." >&2
87 old=yes
88 sort="@SORT@"
89 print_option="-print"
90 frcode_options=""
91 else
92 frcode_options=""
93 case "$dbformat" in
94 "")
95 # Default, use LOCATE02
97 LOCATE02)
99 slocate)
100 frcode_options="$frcode_options -S 1"
103 echo "Unsupported locate database format ${dbformat}: Supported formats are:" >&2
104 echo "LOCATE02, slocate, old" >&2
105 exit 1
106 esac
109 if @SORT_SUPPORTS_Z@
110 then
111 sort="@SORT@ -z"
112 print_option="-print0"
113 frcode_options="$frcode_options -0"
114 else
115 sort="@SORT@"
116 print_option="-print"
120 getuid() {
121 # format of "id" output is ...
122 # uid=1(daemon) gid=1(other)
123 # for `id's that don't understand -u
124 id | cut -d'(' -f 1 | cut -d'=' -f2
127 # figure out if su supports the -s option
128 select_shell() {
129 if su "$1" -s $SHELL -c false < /dev/null ; then
130 # No.
131 echo ""
132 else
133 if su "$1" -s $SHELL -c true < /dev/null ; then
134 # Yes.
135 echo "-s $SHELL"
136 else
137 # su is unconditionally failing. We won't be able to
138 # figure out what is wrong, so be conservative.
139 echo ""
145 # You can set these in the environment, or use command-line options,
146 # to override their defaults:
148 # Any global options for find?
149 : ${FINDOPTIONS=}
151 # What shell shoud we use? We should use a POSIX-ish sh.
152 : ${SHELL="/bin/sh"}
154 # Non-network directories to put in the database.
155 : ${SEARCHPATHS="/"}
157 # Network (NFS, AFS, RFS, etc.) directories to put in the database.
158 : ${NETPATHS=}
160 # Directories to not put in the database, which would otherwise be.
161 : ${PRUNEPATHS="/tmp /usr/tmp /var/tmp /afs /amd /sfs /proc"}
163 # Trailing slashes result in regex items that are never matched, which
164 # is not what the user will expect. Therefore we now reject such
165 # constructs.
166 for p in $PRUNEPATHS; do
167 case "$p" in
168 /*/) echo "$0: $p: pruned paths should not contain trailing slashes" >&2
169 exit 1
170 esac
171 done
173 # The same, in the form of a regex that find can use.
174 test -z "$PRUNEREGEX" &&
175 PRUNEREGEX=`echo $PRUNEPATHS|sed -e 's,^,\\\(^,' -e 's, ,$\\\)\\\|\\\(^,g' -e 's,$,$\\\),'`
177 # The database file to build.
178 : ${LOCATE_DB=@LOCATE_DB@}
180 # Directory to hold intermediate files.
181 if test -d /var/tmp; then
182 : ${TMPDIR=/var/tmp}
183 elif test -d /usr/tmp; then
184 : ${TMPDIR=/usr/tmp}
185 else
186 : ${TMPDIR=/tmp}
188 export TMPDIR
190 # The user to search network directories as.
191 : ${NETUSER=daemon}
193 # The directory containing the subprograms.
194 if test -n "$LIBEXECDIR" ; then
195 : LIBEXECDIR already set, do nothing
196 else
197 : ${LIBEXECDIR=@libexecdir@}
200 # The directory containing find.
201 if test -n "$BINDIR" ; then
202 : BINDIR already set, do nothing
203 else
204 : ${BINDIR=@bindir@}
207 # The names of the utilities to run to build the database.
208 : ${find:=${BINDIR}/@find@}
209 : ${frcode:=${LIBEXECDIR}/@frcode@}
210 : ${bigram:=${LIBEXECDIR}/@bigram@}
211 : ${code:=${LIBEXECDIR}/@code@}
214 checkbinary () {
215 if test -x "$1" ; then
216 : ok
217 else
218 eval echo "updatedb needs to be able to execute $1, but cannot." >&2
219 exit 1
223 for binary in $find $frcode $bigram $code
225 checkbinary $binary
226 done
229 PATH=/bin:/usr/bin:${BINDIR}; export PATH
231 : ${PRUNEFS="nfs NFS proc afs proc smbfs autofs iso9660 ncpfs coda devpts ftpfs devfs mfs sysfs shfs"}
233 if test -n "$PRUNEFS"; then
234 prunefs_exp=`echo $PRUNEFS |sed -e 's/\([^ ][^ ]*\)/-o -fstype \1/g' \
235 -e 's/-o //' -e 's/$/ -o/'`
236 else
237 prunefs_exp=''
240 # Make and code the file list.
241 # Sort case insensitively for users' convenience.
243 rm -f $LOCATE_DB.n
244 trap 'rm -f $LOCATE_DB.n; exit' HUP TERM
246 if test $old = no; then
247 # LOCATE02 or slocate format
248 if {
249 cd "$changeto"
250 if test -n "$SEARCHPATHS"; then
251 if [ "$LOCALUSER" != "" ]; then
252 # : A1
253 su $LOCALUSER `select_shell $LOCALUSER` -c \
254 "$find $SEARCHPATHS $FINDOPTIONS \
255 \\( $prunefs_exp \
256 -type d -regex '$PRUNEREGEX' \\) -prune -o $print_option"
257 else
258 # : A2
259 $find $SEARCHPATHS $FINDOPTIONS \
260 \( $prunefs_exp \
261 -type d -regex "$PRUNEREGEX" \) -prune -o $print_option
265 if test -n "$NETPATHS"; then
266 myuid=`getuid`
267 if [ "$myuid" = 0 ]; then
268 # : A3
269 su $NETUSER `select_shell $NETUSER` -c \
270 "$find $NETPATHS $FINDOPTIONS \\( -type d -regex '$PRUNEREGEX' -prune \\) -o $print_option" ||
271 exit $?
272 else
273 # : A4
274 $find $NETPATHS $FINDOPTIONS \( -type d -regex "$PRUNEREGEX" -prune \) -o $print_option ||
275 exit $?
278 } | $sort -f | $frcode $frcode_options > $LOCATE_DB.n
279 then
280 : OK so far
281 true
282 else
283 rv=$?
284 echo "Failed to generate $LOCATE_DB.n" >&2
285 rm -f $LOCATE_DB.n
286 exit $rv
289 # To avoid breaking locate while this script is running, put the
290 # results in a temp file, then rename it atomically.
291 if test -s $LOCATE_DB.n; then
292 chmod 644 ${LOCATE_DB}.n
293 mv ${LOCATE_DB}.n $LOCATE_DB
294 else
295 echo "updatedb: new database would be empty" >&2
296 rm -f $LOCATE_DB.n
299 else # old
301 if ! bigrams=`mktemp -t updatedbXXXXXXXXX`; then
302 echo mktemp failed >&2
303 exit 1
306 if ! filelist=`mktemp -t updatedbXXXXXXXXX`; then
307 echo mktemp failed >&2
308 exit 1
311 rm -f $LOCATE_DB.n
312 trap 'rm -f $bigrams $filelist $LOCATE_DB.n; exit' HUP TERM
314 # Alphabetize subdirectories before file entries using tr. James Woods says:
315 # "to get everything in monotonic collating sequence, to avoid some
316 # breakage i'll have to think about."
318 cd "$changeto"
319 if test -n "$SEARCHPATHS"; then
320 if [ "$LOCALUSER" != "" ]; then
321 # : A5
322 su $LOCALUSER `select_shell $LOCALUSER` -c \
323 "$find $SEARCHPATHS $FINDOPTIONS \
324 \( $prunefs_exp \
325 -type d -regex '$PRUNEREGEX' \) -prune -o $print_option" || exit $?
326 else
327 # : A6
328 $find $SEARCHPATHS $FINDOPTIONS \
329 \( $prunefs_exp \
330 -type d -regex "$PRUNEREGEX" \) -prune -o $print_option || exit $?
334 if test -n "$NETPATHS"; then
335 myuid=`getuid`
336 if [ "$myuid" = 0 ]; then
337 # : A7
338 su $NETUSER `select_shell $NETUSER` -c \
339 "$find $NETPATHS $FINDOPTIONS \\( -type d -regex '$PRUNEREGEX' -prune \\) -o $print_option" ||
340 exit $?
341 else
342 # : A8
343 $find $NETPATHS $FINDOPTIONS \( -type d -regex "$PRUNEREGEX" -prune \) -o $print_option ||
344 exit $?
347 } | tr / '\001' | $sort -f | tr '\001' / > $filelist
349 # Compute the (at most 128) most common bigrams in the file list.
350 $bigram $bigram_opts < $filelist | sort | uniq -c | sort -nr |
351 awk '{ if (NR <= 128) print $2 }' | tr -d '\012' > $bigrams
353 # Code the file list.
354 $code $bigrams < $filelist > $LOCATE_DB.n
356 rm -f $bigrams $filelist
358 # To reduce the chances of breaking locate while this script is running,
359 # put the results in a temp file, then rename it atomically.
360 if test -s $LOCATE_DB.n; then
361 chmod 644 ${LOCATE_DB}.n
362 mv ${LOCATE_DB}.n $LOCATE_DB
363 else
364 echo "updatedb: new database would be empty" >&2
365 rm -f $LOCATE_DB.n
370 exit 0