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
+