💾 Archived View for perplexing.space › 2020 › files › gemini-monitor.sh captured on 2021-12-03 at 14:04:38.
-=-=-=-=-=-=-
#!/usr/bin/env bash set -euo pipefail TEMPDIR=$(mktemp -d) trap 'rm -rf "$TEMPDIR"' EXIT case $(uname) in Linux) STATFLAGS="-c %Y";; NetBSD|OpenBSD) STATFLAGS="-f %m";; *) echo "I do not know the correct stat flags for this OS";; esac formatRequest() { # (hostname) printf "gemini://%s:1965/\r\n" "$1" } dummyResponse() { echo "99 not a real response" } geminiFetch() { # (hostname) for PROG in openssl gnutls-cli do if command -v $PROG 2&>1 then case $PROG in # the fallback value is weird but necessary(?) to avoid empty reads gnutls-cli) formatRequest "$1" | gnutls-cli --insecure --logfile=/dev/null "$1:1965" 2>/dev/null || dummyResponse;; openssl) formatRequest "$1" | openssl s_client -quiet "$1:1965" 2>/dev/null || dummyResponse;; *) echo "no available program for TLS-stuff";; esac break fi done } successResponse() { # (hostname) geminiFetch "$1" | \ head -n1 | \ while read -s -r -d' ' do if [ "$REPLY" -eq 20 ] then return 0 else return 1 fi done } retryingCheck() { # (hostname) for attempt in 1 2 3 do if successResponse $1 then return 0 else if [ $attempt -eq 3 ] then return 1 fi sleep 10 fi done } requiresCheck() { # (tempfile path) if [ "$(date '+%s')" -ge "$(stat $STATFLAGS "$1")" ] then return 0 else return 1 fi } while read -s -r _hostname _email do echo -n "$_email" > "$TEMPDIR/$_hostname" touch -mt "$(date -d'-1 hour' '+%Y%m%d%H%M.%S')" "$TEMPDIR/$_hostname" done while true do for HOST in $TEMPDIR/* do if requiresCheck $HOST then if ! retryingCheck $(basename $HOST) then echo "multiple failed requests at: $(date)" | mail -s "$(basename $HOST) not responding" "$(cat $HOST)" fi touch -mt "$(date -d'+1 hour' '+%Y%m%d%H%M.%S')" "$HOST" fi done sleep 60 done