Imported Upstream version 4.5.10
[platform/upstream/findutils.git] / locate / updatedb.sh
1 #! /bin/sh
2 # updatedb -- build a locate pathname database
3 # Copyright (C) 1994, 1996, 1997, 2000, 2001, 2003, 2004, 2005, 2006,
4 # 2010 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
21 #exec 2> /tmp/updatedb-trace.txt
22 #set -x
23
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.
30
31 Written by Eric B. Decker, James Youngman, and Kevin Dalley.
32 '
33
34
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]
41
42 Report bugs to <bug-findutils@gnu.org>."
43 changeto=/
44 old=no
45 for arg
46 do
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
72
73
74
75
76 case "${dbformat:+yes}_${old}" in
77     yes_yes)
78         echo "The --dbformat and --old cannot both be specified." >&2
79         exit 1
80         ;;
81         *)
82         ;;
83 esac
84
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
96             ;;
97         LOCATE02)
98             ;;
99         slocate)
100             frcode_options="$frcode_options -S 1"
101             ;;
102         *)
103             echo "Unsupported locate database format ${dbformat}: Supported formats are:" >&2
104             echo "LOCATE02, slocate, old" >&2
105             exit 1
106     esac
107
108
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"
117     fi
118 fi
119
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
125 }
126
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 ""
140         fi
141     fi
142 }
143
144
145 # You can set these in the environment, or use command-line options,
146 # to override their defaults:
147
148 # Any global options for find?
149 : ${FINDOPTIONS=}
150
151 # What shell shoud we use?  We should use a POSIX-ish sh.
152 : ${SHELL="/bin/sh"}
153
154 # Non-network directories to put in the database.
155 : ${SEARCHPATHS="/"}
156
157 # Network (NFS, AFS, RFS, etc.) directories to put in the database.
158 : ${NETPATHS=}
159
160 # Directories to not put in the database, which would otherwise be.
161 : ${PRUNEPATHS="/tmp /usr/tmp /var/tmp /afs /amd /sfs /proc"}
162
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
172
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,$,$\\\),'`
176
177 # The database file to build.
178 : ${LOCATE_DB=@LOCATE_DB@}
179
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}
187 fi
188 export TMPDIR
189
190 # The user to search network directories as.
191 : ${NETUSER=daemon}
192
193 # The directory containing the subprograms.
194 if test -n "$LIBEXECDIR" ; then
195     : LIBEXECDIR already set, do nothing
196 else
197     : ${LIBEXECDIR=@libexecdir@}
198 fi
199
200 # The directory containing find.
201 if test -n "$BINDIR" ; then
202     : BINDIR already set, do nothing
203 else
204     : ${BINDIR=@bindir@}
205 fi
206
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@}
212
213
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
220     fi
221 }
222
223 for binary in $find $frcode $bigram $code
224 do
225   checkbinary $binary
226 done
227
228
229 PATH=/bin:/usr/bin:${BINDIR}; export PATH
230
231 : ${PRUNEFS="nfs NFS proc afs smbfs autofs iso9660 ncpfs coda devpts ftpfs devfs mfs sysfs shfs"}
232
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=''
238 fi
239
240 # Make and code the file list.
241 # Sort case insensitively for users' convenience.
242
243 rm -f $LOCATE_DB.n
244 trap 'rm -f $LOCATE_DB.n; exit' HUP TERM
245
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
262   fi
263 fi
264
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 $?
276   fi
277 fi
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
287 fi
288
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
297 fi
298
299 else # old
300
301 if ! bigrams=`mktemp -t updatedbXXXXXXXXX`; then
302     echo mktemp failed >&2
303     exit 1
304 fi
305
306 if ! filelist=`mktemp -t updatedbXXXXXXXXX`; then
307     echo mktemp failed >&2
308     exit 1
309 fi
310
311 rm -f $LOCATE_DB.n
312 trap 'rm -f $bigrams $filelist $LOCATE_DB.n; exit' HUP TERM
313
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."
317 {
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 $?
331   fi
332 fi
333
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 $?
345   fi
346 fi
347 } | tr / '\001' | $sort -f | tr '\001' / > $filelist
348
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
352
353 # Code the file list.
354 $code $bigrams < $filelist > $LOCATE_DB.n
355
356 rm -f $bigrams $filelist
357
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
366 fi
367
368 fi
369
370 exit 0