1#!/usr/bin/env bash
2#
3# Copyright 2019, The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#     http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17# Warning and exit when failed to meet the requirements.
18[ "$(uname -s)" != "Darwin" ] && { echo "This program runs on Darwin only."; exit 0; }
19[ "$UID" -eq 0 ] && { echo "Running with root user is not supported."; exit 0; }
20
21function usage() {
22    echo "###########################################"
23    echo "Usage: $prog [-U|-e|-n|-o||-l|-f|-h]"
24    echo "  -U: The PATH of the search root."
25    echo "  -e: The PATH that unwanted to be searched."
26    echo "  -n: The name of directories that won't be cached."
27    echo "  -o: The PATH of the generated database."
28    echo "  -l: No effect. For compatible with Linux mlocate."
29    echo "  -f: Filesystems which should not search for."
30    echo "  -h: This usage helper."
31    echo
32    echo "################ [EXAMPLE] ################"
33    echo "$prog -U \$ANDROID_BUILD_TOP -n .git -l 0 \\"
34    echo " -e \"\$ANDROID_BUILD_TOP/out \$ANDROID_BUILD_TOP/.repo\" \\"
35    echo " -o \"\$ANDROID_HOST_OUT/locate.database\""
36    echo
37    echo "locate -d \$ANDROID_HOST_OUT/locate.database atest.py"
38    echo "locate -d \$ANDROID_HOST_OUT/locate.database contrib/res/config"
39}
40
41function mktempdir() {
42    TMPDIR=/tmp
43    if ! TMPDIR=`mktemp -d $TMPDIR/locateXXXXXXXXXX`; then
44        exit 1
45    fi
46    temp=$TMPDIR/_updatedb$$
47}
48
49function _updatedb_main() {
50    # 0. Disable default features of bash.
51    set -o noglob   # Disable * expension before passing arguments to find.
52    set -o errtrace # Sub-shells inherit error trap.
53
54    # 1. Get positional arguments and set variables.
55    prog=$(basename $0)
56    while getopts 'U:n:e:o:l:f:h' option; do
57        case $option in
58            U) SEARCHROOT="$OPTARG";; # Search root.
59            e) PRUNEPATHS="$OPTARG";; # Paths to be excluded.
60            n) PRUNENAMES="$OPTARG";; # Dirnames to be pruned.
61            o) DATABASE="$OPTARG";;   # the output of the DB.
62            l) ;;                     # No effect.
63            f) PRUNEFS="$OPTARG";;    # Disallow network filesystems.
64            *) usage; exit 0;;
65        esac
66    done
67
68    : ${SEARCHROOT:="$ANDROID_BUILD_TOP"}
69    if [ -z "$SEARCHROOT" ]; then
70        echo 'Either $SEARCHROOT or $ANDROID_BUILD_TOP is required.'
71        exit 0
72    fi
73
74    if [ -n "$ANDROID_BUILD_TOP" ]; then
75        PRUNEPATHS="$PRUNEPATHS $ANDROID_BUILD_TOP/out"
76    fi
77
78    PRUNENAMES="$PRUNENAMES *.class *.pyc .gitignore"
79    : ${DATABASE:=/tmp/locate.database}
80    : ${PRUNEFS:="nfs afp smb"}
81
82    # 2. Assemble excludes strings.
83    excludes=""
84    or=""
85    sortarg="-presort"
86    for fs in $PRUNEFS; do
87        excludes="$excludes $or -fstype $fs -prune"
88        or="-o"
89    done
90    for path in $PRUNEPATHS; do
91        excludes="$excludes $or -path $path -prune"
92    done
93    for file in $PRUNENAMES; do
94        excludes="$excludes $or -name $file -prune"
95    done
96
97    # 3. Find and create locate database.
98    # Delete $temp when trapping specified return values.
99    mktempdir
100    trap 'rm -rf $temp $TMPDIR; exit' 0 1 2 3 5 10 15
101    if find -s $SEARCHROOT $excludes $or -print 2>/dev/null -true |
102        /usr/libexec/locate.mklocatedb $sortarg > $temp 2>/dev/null; then
103            case x"`find $temp -size 257c -print`" in
104                x) cat $temp > $DATABASE;;
105                *) echo "$prog: database $temp is found empty."
106                   exit 1;;
107            esac
108    fi
109}
110
111_updatedb_main "$@"
112