2 # updatedb -- build a locate pathname database
3 # Copyright (C) 1994, 1996, 1997, 2000, 2001, 2003, 2004, 2005, 2006,
4 # 2010, 2011 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
25 updatedb (@PACKAGE_NAME@) @VERSION@
26 Copyright (C) 2007,2008,2009,2010 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.
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>."
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
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
76 case "${dbformat:+yes}_${old}" in
78 echo "The --dbformat and --old cannot both be specified." >&2
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
95 # Default, use LOCATE02
100 frcode_options="$frcode_options -S 1"
103 echo "Unsupported locate database format ${dbformat}: Supported formats are:" >&2
104 echo "LOCATE02, slocate, old" >&2
112 print_option="-print0"
113 frcode_options="$frcode_options -0"
116 print_option="-print"
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
129 if su "$1" -s $SHELL -c false < /dev/null ; then
133 if su "$1" -s $SHELL -c true < /dev/null ; then
137 # su is unconditionally failing. We won't be able to
138 # figure out what is wrong, so be conservative.
145 # You can set these in the environment, or use command-line options,
146 # to override their defaults:
148 # Any global options for find?
151 # What shell shoud we use? We should use a POSIX-ish sh.
154 # Non-network directories to put in the database.
157 # Network (NFS, AFS, RFS, etc.) directories to put in the database.
160 # Directories to not put in the database, which would otherwise be.
171 # Trailing slashes result in regex items that are never matched, which
172 # is not what the user will expect. Therefore we now reject such
174 for p in $PRUNEPATHS; do
176 /*/) echo "$0: $p: pruned paths should not contain trailing slashes" >&2
181 # The same, in the form of a regex that find can use.
182 test -z "$PRUNEREGEX" &&
183 PRUNEREGEX=`echo $PRUNEPATHS|sed -e 's,^,\\\(^,' -e 's, ,$\\\)\\\|\\\(^,g' -e 's,$,$\\\),'`
185 # The database file to build.
186 : ${LOCATE_DB=@LOCATE_DB@}
188 # Directory to hold intermediate files.
189 if test -d /var/tmp; then
191 elif test -d /usr/tmp; then
198 # The user to search network directories as.
201 # The directory containing the subprograms.
202 if test -n "$LIBEXECDIR" ; then
203 : LIBEXECDIR already set, do nothing
205 : ${LIBEXECDIR=@libexecdir@}
208 # The directory containing find.
209 if test -n "$BINDIR" ; then
210 : BINDIR already set, do nothing
215 # The names of the utilities to run to build the database.
216 : ${find:=${BINDIR}/@find@}
217 : ${frcode:=${LIBEXECDIR}/@frcode@}
218 : ${bigram:=${LIBEXECDIR}/@bigram@}
219 : ${code:=${LIBEXECDIR}/@code@}
222 # This implementation is adapted from the GNU Autoconf manual.
225 (umask 077 && mktemp -d "$TMPDIR/updatedbXXXXXX") 2>/dev/null
227 test -n "$tmp" && test -d "$tmp"
229 # This method is less secure than mktemp -d, but it's a fallback.
231 # We use $$ as well as $RANDOM since $RANDOM may not be available.
232 # We also add a time-dependent suffix. This is actually somewhat
233 # predictable, but then so is $$. POSIX does not require date to
235 ts=`date +%N%S || date +%S 2>/dev/null`
236 tmp="$TMPDIR"/updatedb"$$"-"${RANDOM:-}${ts}"
237 (umask 077 && mkdir "$tmp")
243 if test -x "$1" ; then
246 eval echo "updatedb needs to be able to execute $1, but cannot." >&2
251 for binary in $find $frcode $bigram $code
278 if test -n "$PRUNEFS"; then
279 prunefs_exp=`echo $PRUNEFS |sed -e 's/\([^ ][^ ]*\)/-o -fstype \1/g' \
280 -e 's/-o //' -e 's/$/ -o/'`
285 # Make and code the file list.
286 # Sort case insensitively for users' convenience.
289 trap 'rm -f $LOCATE_DB.n; exit' HUP TERM
291 if test $old = no; then
292 # LOCATE02 or slocate format
295 if test -n "$SEARCHPATHS"; then
296 if [ "$LOCALUSER" != "" ]; then
298 su $LOCALUSER `select_shell $LOCALUSER` -c \
299 "$find $SEARCHPATHS $FINDOPTIONS \
301 -type d -regex '$PRUNEREGEX' \\) -prune -o $print_option"
304 $find $SEARCHPATHS $FINDOPTIONS \
306 -type d -regex "$PRUNEREGEX" \) -prune -o $print_option
310 if test -n "$NETPATHS"; then
312 if [ "$myuid" = 0 ]; then
314 su $NETUSER `select_shell $NETUSER` -c \
315 "$find $NETPATHS $FINDOPTIONS \\( -type d -regex '$PRUNEREGEX' -prune \\) -o $print_option" ||
319 $find $NETPATHS $FINDOPTIONS \( -type d -regex "$PRUNEREGEX" -prune \) -o $print_option ||
323 } | $sort -f | $frcode $frcode_options > $LOCATE_DB.n
329 echo "Failed to generate $LOCATE_DB.n" >&2
334 # To avoid breaking locate while this script is running, put the
335 # results in a temp file, then rename it atomically.
336 if test -s $LOCATE_DB.n; then
337 chmod 644 ${LOCATE_DB}.n
338 mv ${LOCATE_DB}.n $LOCATE_DB
340 echo "updatedb: new database would be empty" >&2
346 if temp_directory="`make_tempdir`"; then
347 bigrams="${temp_directory}"/bigrams
348 filelist="${temp_directory}"/filelist
350 echo "failed to create temporary directory" >&2
355 trap 'rm -f $LOCATE_DB.n; rm -rf "${temp_directory}"; exit' HUP TERM
357 # Alphabetize subdirectories before file entries using tr. James Woods says:
358 # "to get everything in monotonic collating sequence, to avoid some
359 # breakage i'll have to think about."
362 if test -n "$SEARCHPATHS"; then
363 if [ "$LOCALUSER" != "" ]; then
365 su $LOCALUSER `select_shell $LOCALUSER` -c \
366 "$find $SEARCHPATHS $FINDOPTIONS \
368 -type d -regex '$PRUNEREGEX' \) -prune -o $print_option" || exit $?
371 $find $SEARCHPATHS $FINDOPTIONS \
373 -type d -regex "$PRUNEREGEX" \) -prune -o $print_option || exit $?
377 if test -n "$NETPATHS"; then
379 if [ "$myuid" = 0 ]; then
381 su $NETUSER `select_shell $NETUSER` -c \
382 "$find $NETPATHS $FINDOPTIONS \\( -type d -regex '$PRUNEREGEX' -prune \\) -o $print_option" ||
386 $find $NETPATHS $FINDOPTIONS \( -type d -regex "$PRUNEREGEX" -prune \) -o $print_option ||
390 } | tr / '\001' | $sort -f | tr '\001' / > "$filelist"
392 # Compute the (at most 128) most common bigrams in the file list.
393 $bigram $bigram_opts < $filelist | sort | uniq -c | sort -nr |
394 awk '{ if (NR <= 128) print $2 }' | tr -d '\012' > "$bigrams"
396 # Code the file list.
397 $code "$bigrams" < "$filelist" > $LOCATE_DB.n
399 rm -rf "${temp_directory}"
401 # To reduce the chances of breaking locate while this script is running,
402 # put the results in a temp file, then rename it atomically.
403 if test -s $LOCATE_DB.n; then
404 chmod 644 ${LOCATE_DB}.n
405 mv ${LOCATE_DB}.n $LOCATE_DB
407 echo "updatedb: new database would be empty" >&2