Update site to 'responsive' html/css code.

This commit is contained in:
Darren 'Tadgy' Austin 2024-08-09 01:30:32 +01:00
commit f98793316b
19 changed files with 1199 additions and 1123 deletions

119
cgi-bin/searchapi.cgi Executable file
View file

@ -0,0 +1,119 @@
#!/bin/bash
# Configuration.
STORAGE_PREFIX="/storage/md0"
LOCATE_DB="/tmp/mirrors.db"
DEF_RESULTS=500
MAX_RESULTS=3000
MAX_CONCURRENT=10
IGNORE_REGEXES=('^/\.sandbox.*' '^/\.lftp.*' '^/dead\.letter' '.*\.rsync-tmp.*')
# Extglob is required.
shopt -s extglob
# Output an error in processing.
die() {
# $1 = The error code to output.
# 0 = Success.
# 1 = Temporary error (eg, max concurrent).
# 2 = Perminant error.
# $2 = The error message to output (if any).
printf "%s: %s%b" "Status" "${1:-2}" "\0"
[[ -n "$2" ]] && printf "%s: %s%b" "Error" "$2" "\0"
exit 1
}
# Initial headers.
#printf "%s: %s\\n" "Content-type" "text/plain"
printf "%s: %s\\n" "Content-type" "application/octet-stream"
printf "%s: %s\\n" "Cache-Control" "no-cache, no-store, must-revalidate"
printf "%s: %s\\n" "Pragma" "no-cache"
printf "%s: %s\\n\\n" "Expires" "1"
# Limit the number of concurrent searches to avoid DoS.
if (( $(lsof -t "$LOCATE_DB" | wc -l) > (MAX_CONCURRENT - 1) )); then
die "1" "Too many concurrent searches!"
else
# Lock the DB for the lsof count above.
# shellcheck disable=SC2015
exec 9<"$LOCATE_DB" && flock -s -E 10 -w 2 9 || die "1" "Too many concurrent searches!"
# shellcheck disable=SC2154
while read -r -d '&' QUERY; do
# If the read returned an empty string, skip.
[[ -z "$QUERY" ]] && continue
# Extract the key and value to temporary variables.
KEY="${QUERY%%=*}"
VALUE="${QUERY#*=}"
# Check the key is valid as a variable name.
[[ ! "$KEY" =~ ^[[:digit:]_]*[[:alnum:]_]*$ ]] && die "2" "Invalid query - don't try to be clever :)"
# Define the variable from the key name.
declare "QS_$KEY"="$VALUE"
done <<<"${QUERY_STRING,,}&" # The & at the end is required.
# Remove spaces from beginning and end of query.
QS_q="${QS_q/##+(+)}"
QS_q="${QS_q/%%+(+)}"
# Squash multiple +s in query.
QS_q="${QS_q//+(+)/+}"
# Convert any +s in the path and query into spaces.
QS_p="${QS_p//+/ }"
QS_q="${QS_q//+/ }"
# Don't allow /s in the query.
# [[ "$QS_q" == */* ]] || [[ "$QS_q" == *%2F* ]] && die "2" "Searches may not include the '/' character."
# Convert path and query from %-encoded form.
QS_p="$(printf "%b" "${QS_p//%/\\x}")"
QS_q="$(printf "%b" "${QS_q//%/\\x}")"
# Adjust 'QS_q' for the locate command by wrapping search elements in *.
QS_q="*${QS_q// /* *}*"
# Adjust 'QS_l' to not go over maximum limit of results, or use default if not supplied.
[[ -z "$QS_l" ]] && QS_l="$DEF_RESULTS"
(( QS_l > MAX_RESULTS )) && QS_l="$MAX_RESULTS"
# Give success status as checks have passed.
printf "%s: %s%b" "Status" "0" "\0"
I=1
# shellcheck disable=SC2154
while read -r -d $'\0' ITEM; do
# Only show specified number of items.
(( I == (QS_l + 1) )) && break
# Remove paths we don't want the user to see.
while read -r -d " " REGEX; do
[[ "${ITEM/$STORAGE_PREFIX}" =~ $REGEX ]] && continue 2
done <<<"${IGNORE_REGEXES[@]}"
# Don't list the path searched for.
[[ "${ITEM/$STORAGE_PREFIX}" == "$QS_p" ]] && continue
# List the item.
if [[ -f "$ITEM" ]]; then
# File type.
printf "%s %s%b" "f" "${ITEM/$STORAGE_PREFIX}" "\0"
elif [[ -d "$ITEM" ]]; then
# Directory type.
printf "%s %s%b" "d" "${ITEM/$STORAGE_PREFIX}" "\0"
elif [[ -L "$ITEM" ]]; then
# Symbolic link type.
printf "%s %s%b" "l" "${ITEM/$STORAGE_PREFIX}" "\0"
elif [[ -e "$ITEM" ]]; then
# Other type.
printf "%s %s%b" "o" "${ITEM/$STORAGE_PREFIX}" "\0"
else
# Stale file in database.
printf "%s %s%b" "?" "${ITEM/$STORAGE_PREFIX}" "\0"
fi
(( I++ ))
done < <(locate -0 -A -d "$LOCATE_DB" -i -l "$(( QS_l * 2 ))" "$STORAGE_PREFIX/${QS_p/#+(\/)}" $QS_q | sort)
fi