Add lawn-hark.sh script from pazz0. - gopher-lawn - The gopher lawn gopher directory project.
 (HTM) git clone git://bitreich.org/gopher-lawn/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/gopher-lawn/
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) Tags
       ---
 (DIR) commit ee7a798530add04897221c9b89c3212a41836375
 (DIR) parent 3c4d6c01eaac78599e65e5cc246ba8ed7f554765
 (HTM) Author: Christoph Lohmann <20h@r-36.net>
       Date:   Wed, 30 Aug 2023 21:03:27 +0200
       
       Add lawn-hark.sh script from pazz0.
       
       Diffstat:
         A lawn-hark/lawn-hark.sh              |     234 +++++++++++++++++++++++++++++++
       
       1 file changed, 234 insertions(+), 0 deletions(-)
       ---
 (DIR) diff --git a/lawn-hark/lawn-hark.sh b/lawn-hark/lawn-hark.sh
       @@ -0,0 +1,234 @@
       +#!/bin/bash
       +#
       +# Originally written by pazz0.
       +#
       +
       +errorthreshold=3
       +timeout=15
       +onionsocksproxy="127.0.0.1:9050"
       +
       +function tcpdial() {
       +        if [ -z "${1##*.onion}" ];
       +        then
       +                nc -w "${timeout}" -X 5 -x "${onionsocksproxy}" "$1" "$2" \
       +                        2>/dev/null
       +        else
       +                nc -w "${timeout}" "$1" "$2" 2>/dev/null
       +        fi
       +}
       +
       +function checkgopher() {
       +        if [ "$#" -gt 3 ];
       +        then
       +                data="$(printf "%s\t%s\r\n" "$3" "$4" \
       +                        | tcpdial "$1" "$2" \
       +                        | dd bs=128 count=1 2>/dev/null)"
       +        else
       +                data="$(printf "%s\r\n" "$3" \
       +                        | tcpdial "$1" "$2" \
       +                        | dd bs=128 count=1 2>/dev/null)"
       +        fi
       +
       +        if [ -z "${data}" ];
       +        then
       +                printf "Can't connect, timeout or no content\n"
       +                return 1
       +        fi
       +
       +        if [ -z "${data##3?*        *}" ];
       +        then
       +                printf "Got type '3' on first line\n"
       +                return 1
       +        fi
       +
       +        if [ -z "${data##Error: File or directory not found!*}" ] \
       +                || [ -z "${data##Error: Access denied!*}" ];
       +        then
       +                printf "Got Gophernicus error\n"
       +                return 1
       +        fi
       +
       +        return 0
       +}
       +
       +function checkhttp() {
       +        # max. one redirect (2) for http->https things
       +        bc="$(curl -L --max-redirs 2 -m "${timeout}" -f "$1" 2>/dev/null \
       +                | dd bs=16 count=1 2>/dev/null \
       +                | wc -c \
       +                | xargs)"
       +        if [ "${bc}" -eq 0 ];
       +        then
       +                printf "Can't connect, timout, too many redirects or no content\n"
       +                return 1
       +        fi
       +
       +        return 0
       +}
       +
       +function checkcso() {
       +        bc="$(printf "status\r\n" \
       +                | tcpdial "$1" "$2" \
       +                | dd bs=16 count=1 2>/dev/null \
       +                | wc -c \
       +                | xargs)"
       +        if [ "${bc}" -eq 0 ];
       +        then
       +                printf "Can't connect, timeout or no content\n"
       +                return 1
       +        fi
       +
       +        return 0
       +}
       +
       +function checkraw() {
       +        bc="$(tcpdial "$1" "$2" \
       +                | dd bs=16 count=1 2>/dev/null \
       +                | wc -c \
       +                | xargs)"
       +        if [ "${bc}" -eq 0 ];
       +        then
       +                printf "Can't connect, timeout or no content\n"
       +                return 1
       +        fi
       +
       +        return 0
       +}
       +
       +checktime="$(date +%s)" 
       +statedir="$1"
       +
       +if [ -z "${statedir}" ];
       +then
       +        printf "You need to specify a state dir.\n" >&2
       +        exit 1
       +fi
       +
       +mkdir -p "${statedir}"
       +if [ ! -d "${statedir}" ];
       +then
       +        printf "%s is not a directory! Aborting.\n" "${statedir}" >&2
       +        exit 1
       +fi
       +
       +shift
       +
       +for f;
       +do
       +        type=""
       +        selector=""
       +        host=""
       +        port=""
       +
       +        while read -r line;
       +        do
       +                value="$(printf '%s\n' "${line}" \
       +                        | cut -f 2- -d ':' \
       +                        | sed -n 's/^[[:space:]]*\(.*\)$/\1/p')"
       +                case "${line}" in
       +                Type:* )
       +                        type="${value}"
       +                        ;;
       +                Selector:* )
       +                        selector="${value}"
       +                        ;;
       +                Host:* )
       +                        host="${value}"
       +                        ;;
       +                Port:* )
       +                        port="${value}"
       +                        ;;
       +                esac
       +        done < "$f"
       +
       +        if [ -z "${type}" ] \
       +                || [ -z "${host}" ] \
       +                || [ -z "${port}" ];
       +        then
       +                printf "ERROR\t%s\tInvalid entry!\n" "${f}" >&2
       +                continue
       +        fi
       +
       +        #printf "DEBUG\t%s\tchecking\t%s\t%s\t%s\t%s\n" "${f}" "${type}" "${selector}" "${host}" "${port}"
       +
       +        case "${type}" in
       +        cso )
       +                error="$(checkcso "${host}" "${port}")"
       +                ;;
       +        telnet )
       +                error="$(checkraw "${host}" "${port}")"
       +                ;;
       +        error )
       +                error="Type = 'error'"
       +                ;;
       +        link )
       +                if [ -n "${selector}" ] && [ -z "${selector##URL:*}" ];
       +                then
       +                        url="${selector##URL:}"
       +                        case "${url}" in
       +                        http://* | https://* )
       +                                error="$(checkhttp "${url}")"
       +                                ;;
       +                        ssh://* )
       +                                sshhost="${url##ssh://}"
       +                                sshhost="${sshhost##*@}"
       +                                sshhost="${sshhost%%/*}"
       +                                sshport="22"
       +                                if [ -z "${sshhost##*:*}" ];
       +                                then
       +                                        sshport="${sshhost##*:}"
       +                                        sshhost="${sshhost%%:*}"
       +                                fi
       +                                error="$(checkraw "${sshhost}" "${sshport}")"
       +                                ;;
       +                        * )
       +                                printf "TODO\t%s\tCan't handle %s\n" "${f}" "${url}"
       +                                continue
       +                                ;;
       +                        esac
       +                else
       +                        error="$(checkgopher "${host}" "${port}" "${selector}")"
       +                fi
       +                ;;
       +        search )
       +                error="$(checkgopher "${host}" "${port}" "${selector}" "")"
       +                ;;
       +        text | uuencoded | * )
       +                error="$(checkgopher "${host}" "${port}" "${selector}")"
       +                ;;
       +        esac
       +
       +        lastcheck=""
       +        errorcount=0
       +        statefile="${statedir}/$(basename "$f")"
       +        if [ -f "${statefile}" ];
       +        then
       +                IFS="        " read -r lastcheck errorcount < "${statefile}"
       +        fi
       +
       +        if [ -n "${error}" ];
       +        then
       +                errorcount=$((errorcount + 1))
       +        else
       +                errorcount=0
       +        fi
       +
       +        if [ ${errorcount} -ge ${errorthreshold} ];
       +        then
       +                printf "ERROR\t%s\t%s\n" "${f}" "${error}" >&2
       +        fi
       +
       +        printf "%s\t%s\n" "${checktime}" "${errorcount}" > "${statefile}"
       +done
       +
       +# garbage collection
       +find "${statedir}" -type f | while read -r f;
       +do
       +        IFS="        " read -r lastcheck errorcount < "${f}"
       +
       +        if [ ${lastcheck} -ne ${checktime} ];
       +        then
       +                rm -f "${f}"
       +        fi
       +done
       +