#!/bin/bash # Configuration options STORAGE_PREFIX="/storage/md0" HEADER="/data/sites/slackware.uk/html/search_header.html" FOOTER="/data/sites/slackware.uk/html/search_footer.html" LOCATEDB="/tmp/mirrors.db" LIMIT=1000 MAX_CONCURRENT=5 # Extglob is required. shopt -s extglob # Output an error in processing. die() { echo "

Error: $1


" exit 1 } # A content type is required for CGI scripts. echo -ne "Content-type: text/html\r\n\r\n" # Include the header in the output. # Note: The header cannot include PHP scripting. cat "$HEADER" # Limit the number of concurrent searches to avoid DoS. if (( $(lsof -t "$LOCATEDB" | wc -l) > MAX_CONCURRENT - 1 )); then die "Too many concurrent searches - please try your search again in a few moments." else exec 9<"$LOCATEDB" && flock -s -E 10 -w 2 9 || die "Too many concurrent searches - please try your search again in a few moments." fi while read -r -d '&'; do # If the read returned an empty string, skip. [[ -z "$REPLY" ]] && continue # Extract the key and value to temporary variables. KEY="${REPLY%%=*}" VALUE="${REPLY##*=}" # Check the key is valid as a variable name. [[ ! "$KEY" =~ ^[[:alpha:]]+[[:digit:]_]*[[:alnum:]_]*$ ]] && die "Invalid key - please try your search again." # Remove spaces from beginning and end of value. : "${VALUE/#+(+)}" : "${_/%+(+)}" # Squash multiple spaces in value and add *s. : "${_//+(+)/+}" # Convert values from %-encoded form. : "${_//%/\\x}" # Define the variable from the key name. declare $KEY="$(echo -e "${_//+/ }")" done <<<"${QUERY_STRING,,}&" # Take a copy of q before it's modified, for the heading. Q_COPY="${q:-(empty)}" # Adjust 'q' for the locate command by wrapping search elements in *s. : "*${q// /* *}*" q="${_//\/*/*}" # HTML boilerplate. cat <
Showing search results for: $Q_COPY

Searches may contain multiple terms, include (basic) globs, and descend down from the current directory.

EOF I=1 COUNT=0 while read -r; do # Only show 1000 items to prevent long load times. (( I == LIMIT + 1 )) && break # Remove paths we don't want the user to see. [[ "${REPLY/$STORAGE_PREFIX}" =~ ^/\.sandbox.* ]] && continue [[ "${REPLY/$STORAGE_PREFIX}" =~ ^/\.lftp.* ]] && continue [[ "${REPLY/$STORAGE_PREFIX}" =~ ^/dead\.letter ]] && continue [[ "${REPLY/$STORAGE_PREFIX}" =~ .*\.rsync-tmp.* ]] && continue # List the item. echo " • ${REPLY/$STORAGE_PREFIX}
" (( I++ )) (( COUNT++ )) done < <(locate -A -d "$LOCATEDB" -i -l "$(( LIMIT * 2 ))" "$STORAGE_PREFIX/${p##/}" $q | sort) # If there's no results, tell the user. if (( COUNT == 0 )); then echo " No results - try to widen your search." elif (( COUNT == LIMIT )); then echo " Maximum $LIMIT items shown - try to refine your search." else echo " $COUNT items found." fi # HTML boilerplate. cat <
EOF # Include footer. cat "$FOOTER"