💾 Archived View for perplexing.space › 2020 › files › gemini-monitor.sh captured on 2021-12-03 at 14:04:38.

View Raw

More Information

➡️ Next capture (2022-07-17)

-=-=-=-=-=-=-

#!/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