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. 5# 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. 10# 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. 15# 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/>. 18 19# csh original by James Woods; sh conversion by David MacKenzie. 20 21usage="\ 22Usage: $0 [--findoptions='-option1 -option2...'] 23 [--localpaths='dir1 dir2...'] [--netpaths='dir1 dir2...'] 24 [--prunepaths='dir1 dir2...'] [--prunefs='fs1 fs2...'] 25 [--output=dbfile] [--netuser=user] [--localuser=user] 26 [--old-format] [--version] [--help] 27 28Report bugs to <bug-findutils@gnu.org>." 29changeto=/ 30old=no 31for arg 32do 33 # If we are unable to fork, the back-tick operator will 34 # fail (and the shell will emit an error message). When 35 # this happens, we exit with error value 71 (EX_OSERR). 36 # Alternative candidate - 75, EX_TEMPFAIL. 37 opt=`echo $arg|sed 's/^\([^=]*\).*/\1/'` || exit 71 38 val=`echo $arg|sed 's/^[^=]*=\(.*\)/\1/'` || exit 71 39 case "$opt" in 40 --findoptions) FINDOPTIONS="$val" ;; 41 --localpaths) SEARCHPATHS="$val" ;; 42 --netpaths) NETPATHS="$val" ;; 43 --prunepaths) PRUNEPATHS="$val" ;; 44 --prunefs) PRUNEFS="$val" ;; 45 --output) LOCATE_DB="$val" ;; 46 --netuser) NETUSER="$val" ;; 47 --localuser) LOCALUSER="$val" ;; 48 --old-format) old=yes ;; 49 --changecwd) changeto="$val" ;; 50 --version) echo "GNU updatedb version @VERSION@"; exit 0 ;; 51 --help) echo "$usage"; exit 0 ;; 52 *) echo "updatedb: invalid option $opt 53$usage" >&2 54 exit 1 ;; 55 esac 56done 57 58if test "$old" = yes; then 59 echo "Warning: future versions of findutils will shortly discontinue support for the old locate database format." >&2 60 61 sort="@SORT@" 62 print_option="-print" 63 frcode_options="" 64else 65 if @SORT_SUPPORTS_Z@ 66 then 67 sort="@SORT@ -z" 68 print_option="-print0" 69 frcode_options="-0" 70 else 71 sort="@SORT@" 72 print_option="-print" 73 frcode_options="" 74 fi 75fi 76 77getuid() { 78 # format of "id" output is ... 79 # uid=1(daemon) gid=1(other) 80 # for `id's that don't understand -u 81 id | cut -d'(' -f 1 | cut -d'=' -f2 82} 83 84# figure out if su supports the -s option 85select_shell() { 86 if su "$1" -s $SHELL -c false < /dev/null ; then 87 # No. 88 echo "" 89 else 90 if su "$1" -s $SHELL -c true < /dev/null ; then 91 # Yes. 92 echo "-s $SHELL" 93 else 94 # su is unconditionally failing. We won't be able to 95 # figure out what is wrong, so be conservative. 96 echo "" 97 fi 98 fi 99} 100 101 102# You can set these in the environment, or use command-line options, 103# to override their defaults: 104 105# Any global options for find? 106: ${FINDOPTIONS=} 107 108# What shell shoud we use? We should use a POSIX-ish sh. 109: ${SHELL="/bin/sh"} 110 111# Non-network directories to put in the database. 112: ${SEARCHPATHS="/"} 113 114# Network (NFS, AFS, RFS, etc.) directories to put in the database. 115: ${NETPATHS=} 116 117# Directories to not put in the database, which would otherwise be. 118: ${PRUNEPATHS="/tmp /usr/tmp /var/tmp /afs /amd /sfs"} 119 120# Trailing slashes result in regex items that are never matched, which 121# is not what the user will expect. Therefore we now reject such 122# constructs. 123for p in $PRUNEPATHS; do 124 case "$p" in 125 /*/) echo "$0: $p: pruned paths should not contain trailing slashes" >&2 126 exit 1 127 esac 128done 129 130# The same, in the form of a regex that find can use. 131test -z "$PRUNEREGEX" && 132 PRUNEREGEX=`echo $PRUNEPATHS|sed -e 's,^,\\\(^,' -e 's, ,$\\\)\\\|\\\(^,g' -e 's,$,$\\\),'` 133 134# The database file to build. 135: ${LOCATE_DB=@LOCATE_DB@} 136 137# Directory to hold intermediate files. 138if test -d /var/tmp; then 139 : ${TMPDIR=/var/tmp} 140elif test -d /usr/tmp; then 141 : ${TMPDIR=/usr/tmp} 142else 143 : ${TMPDIR=/tmp} 144fi 145export TMPDIR 146 147# The user to search network directories as. 148: ${NETUSER=daemon} 149 150# The directory containing the subprograms. 151if test -n "$LIBEXECDIR" ; then 152 : LIBEXECDIR already set, do nothing 153else 154 : ${LIBEXECDIR=@libexecdir@} 155fi 156 157# The directory containing find. 158if test -n "$BINDIR" ; then 159 : BINDIR already set, do nothing 160else 161 : ${BINDIR=@bindir@} 162fi 163 164# The names of the utilities to run to build the database. 165: ${find:=${BINDIR}/@find@} 166: ${frcode:=${LIBEXECDIR}/@frcode@} 167: ${bigram:=${LIBEXECDIR}/@bigram@} 168: ${code:=${LIBEXECDIR}/@code@} 169 170 171PATH=/bin:/usr/bin:${BINDIR}; export PATH 172 173: ${PRUNEFS="nfs NFS proc afs proc smbfs autofs iso9660 ncpfs coda devpts ftpfs devfs mfs sysfs shfs"} 174 175if test -n "$PRUNEFS"; then 176prunefs_exp=`echo $PRUNEFS |sed -e 's/\([^ ][^ ]*\)/-o -fstype \1/g' \ 177 -e 's/-o //' -e 's/$/ -o/'` 178else 179 prunefs_exp='' 180fi 181 182# Make and code the file list. 183# Sort case insensitively for users' convenience. 184 185rm -f $LOCATE_DB.n 186trap 'rm -f $LOCATE_DB.n; exit' HUP TERM 187 188if test $old = no; then 189 190# FIXME figure out how to sort null-terminated strings, and use -print0. 191if { 192cd "$changeto" 193if test -n "$SEARCHPATHS"; then 194 if [ "$LOCALUSER" != "" ]; then 195 # : A1 196 su $LOCALUSER `select_shell $LOCALUSER` -c \ 197 "$find $SEARCHPATHS $FINDOPTIONS \ 198 \\( $prunefs_exp \ 199 -type d -regex '$PRUNEREGEX' \\) -prune -o $print_option" 200 else 201 # : A2 202 $find $SEARCHPATHS $FINDOPTIONS \ 203 \( $prunefs_exp \ 204 -type d -regex "$PRUNEREGEX" \) -prune -o $print_option 205 fi 206fi 207 208if test -n "$NETPATHS"; then 209myuid=`getuid` 210if [ "$myuid" = 0 ]; then 211 # : A3 212 su $NETUSER `select_shell $NETUSER` -c \ 213 "$find $NETPATHS $FINDOPTIONS \\( -type d -regex '$PRUNEREGEX' -prune \\) -o $print_option" || 214 exit $? 215 else 216 # : A4 217 $find $NETPATHS $FINDOPTIONS \( -type d -regex "$PRUNEREGEX" -prune \) -o $print_option || 218 exit $? 219 fi 220fi 221} | $sort -f | $frcode $frcode_options > $LOCATE_DB.n 222then 223 # OK so far 224 true 225else 226 rv=$? 227 echo "Failed to generate $LOCATE_DB.n" >&2 228 rm -f $LOCATE_DB.n 229 exit $rv 230fi 231 232# To avoid breaking locate while this script is running, put the 233# results in a temp file, then rename it atomically. 234if test -s $LOCATE_DB.n; then 235 rm -f $LOCATE_DB 236 mv $LOCATE_DB.n $LOCATE_DB 237 chmod 644 $LOCATE_DB 238else 239 echo "updatedb: new database would be empty" >&2 240 rm -f $LOCATE_DB.n 241fi 242 243else # old 244 245if ! bigrams=`mktemp -t updatedbXXXXXXXXX`; then 246 echo tempfile failed 247 exit 1 248fi 249 250if ! filelist=`mktemp -t updatedbXXXXXXXXX`; then 251 echo tempfile failed 252 exit 1 253fi 254 255rm -f $LOCATE_DB.n 256trap 'rm -f $bigrams $filelist $LOCATE_DB.n; exit' HUP TERM 257 258# Alphabetize subdirectories before file entries using tr. James Woods says: 259# "to get everything in monotonic collating sequence, to avoid some 260# breakage i'll have to think about." 261{ 262cd "$changeto" 263if test -n "$SEARCHPATHS"; then 264 if [ "$LOCALUSER" != "" ]; then 265 # : A5 266 su $LOCALUSER `select_shell $LOCALUSER` -c \ 267 "$find $SEARCHPATHS $FINDOPTIONS \ 268 \( $prunefs_exp \ 269 -type d -regex '$PRUNEREGEX' \) -prune -o $print_option" || exit $? 270 else 271 # : A6 272 $find $SEARCHPATHS $FINDOPTIONS \ 273 \( $prunefs_exp \ 274 -type d -regex "$PRUNEREGEX" \) -prune -o $print_option || exit $? 275 fi 276fi 277 278if test -n "$NETPATHS"; then 279 myuid=`getuid` 280 if [ "$myuid" = 0 ]; then 281 # : A7 282 su $NETUSER `select_shell $NETUSER` -c \ 283 "$find $NETPATHS $FINDOPTIONS \\( -type d -regex '$PRUNEREGEX' -prune \\) -o $print_option" || 284 exit $? 285 else 286 # : A8 287 $find $NETPATHS $FINDOPTIONS \( -type d -regex "$PRUNEREGEX" -prune \) -o $print_option || 288 exit $? 289 fi 290fi 291} | tr / '\001' | $sort -f | tr '\001' / > $filelist 292 293# Compute the (at most 128) most common bigrams in the file list. 294$bigram $bigram_opts < $filelist | sort | uniq -c | sort -nr | 295 awk '{ if (NR <= 128) print $2 }' | tr -d '\012' > $bigrams 296 297# Code the file list. 298$code $bigrams < $filelist > $LOCATE_DB.n 299 300rm -f $bigrams $filelist 301 302# To reduce the chances of breaking locate while this script is running, 303# put the results in a temp file, then rename it atomically. 304if test -s $LOCATE_DB.n; then 305 rm -f $LOCATE_DB 306 mv $LOCATE_DB.n $LOCATE_DB 307 chmod 644 $LOCATE_DB 308else 309 echo "updatedb: new database would be empty" >&2 310 rm -f $LOCATE_DB.n 311fi 312 313fi 314 315exit 0 316