lawn-hark.sh - 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
       ---
       lawn-hark.sh (4426B)
       ---
            1 #!/bin/bash
            2 #
            3 # Originally written by pazz0.
            4 #
            5 
            6 errorthreshold=3
            7 timeout=15
            8 maxworkers=8
            9 onionsocksproxy="127.0.0.1:9050"
           10 
           11 function tcpdial() {
           12         if [ -z "${1##*.onion}" ];
           13         then
           14                 nc -w "${timeout}" -X 5 -x "${onionsocksproxy}" "$1" "$2" \
           15                         2>/dev/null
           16         else
           17                 nc -w "${timeout}" "$1" "$2" 2>/dev/null
           18         fi
           19 }
           20 
           21 function checkgopher() {
           22         if [ "$#" -gt 3 ];
           23         then
           24                 data="$(printf "%s\t%s\r\n" "$3" "$4" \
           25                         | tcpdial "$1" "$2" \
           26                         | dd bs=128 count=1 2>/dev/null)"
           27         else
           28                 data="$(printf "%s\r\n" "$3" \
           29                         | tcpdial "$1" "$2" \
           30                         | dd bs=128 count=1 2>/dev/null)"
           31         fi
           32 
           33         if [ -z "${data}" ];
           34         then
           35                 printf "Can't connect, timeout or no content\n"
           36                 return 1
           37         fi
           38 
           39         if [ -z "${data##3?*        *}" ];
           40         then
           41                 printf "Got type '3' on first line\n"
           42                 return 1
           43         fi
           44 
           45         if [ -z "${data##Error: File or directory not found!*}" ] \
           46                 || [ -z "${data##Error: Access denied!*}" ];
           47         then
           48                 printf "Got Gophernicus error\n"
           49                 return 1
           50         fi
           51 
           52         return 0
           53 }
           54 
           55 function checkhttp() {
           56         # max. one redirect (2) for http->https things
           57         bc="$(curl -L --max-redirs 2 -m "${timeout}" -f "$1" 2>/dev/null \
           58                 | dd bs=16 count=1 2>/dev/null \
           59                 | wc -c \
           60                 | xargs)"
           61         if [ "${bc}" -eq 0 ];
           62         then
           63                 printf "Can't connect, timout, too many redirects or no content\n"
           64                 return 1
           65         fi
           66 
           67         return 0
           68 }
           69 
           70 function checkcso() {
           71         bc="$(printf "status\r\n" \
           72                 | tcpdial "$1" "$2" \
           73                 | dd bs=16 count=1 2>/dev/null \
           74                 | wc -c \
           75                 | xargs)"
           76         if [ "${bc}" -eq 0 ];
           77         then
           78                 printf "Can't connect, timeout or no content\n"
           79                 return 1
           80         fi
           81 
           82         return 0
           83 }
           84 
           85 function checkraw() {
           86         bc="$(tcpdial "$1" "$2" \
           87                 | dd bs=16 count=1 2>/dev/null \
           88                 | wc -c \
           89                 | xargs)"
           90         if [ "${bc}" -eq 0 ];
           91         then
           92                 printf "Can't connect, timeout or no content\n"
           93                 return 1
           94         fi
           95 
           96         return 0
           97 }
           98 
           99 program="$(readlink -f "$0")"
          100 
          101 if [ "${LAWNHARK_WORKER}" = "1" ];
          102 then
          103         statedir="$1"
          104         checktime="$2"
          105         f="$3"
          106 
          107         type=""
          108         selector=""
          109         host=""
          110         port=""
          111 
          112         while read -r line;
          113         do
          114                 value="$(printf '%s\n' "${line}" \
          115                         | cut -f 2- -d ':' \
          116                         | sed -n 's/^[[:space:]]*\(.*\)$/\1/p')"
          117                 case "${line}" in
          118                 Type:* )
          119                         type="${value}"
          120                         ;;
          121                 Selector:* )
          122                         selector="${value}"
          123                         ;;
          124                 Host:* )
          125                         host="${value}"
          126                         ;;
          127                 Port:* )
          128                         port="${value}"
          129                         ;;
          130                 esac
          131         done < "$f"
          132 
          133         if [ -z "${type}" ] \
          134                 || [ -z "${host}" ] \
          135                 || [ -z "${port}" ];
          136         then
          137                 flock -x "${program}" printf "ERROR\t%s\tInvalid entry!\n" "${f}" >&2
          138                 exit
          139         fi
          140 
          141         case "${type}" in
          142         cso )
          143                 error="$(checkcso "${host}" "${port}")"
          144                 ;;
          145         telnet )
          146                 error="$(checkraw "${host}" "${port}")"
          147                 ;;
          148         error )
          149                 error="Type = 'error'"
          150                 ;;
          151         link )
          152                 if [ -n "${selector}" ] && [ -z "${selector##URL:*}" ];
          153                 then
          154                         url="${selector##URL:}"
          155                         case "${url}" in
          156                         http://* | https://* )
          157                                 error="$(checkhttp "${url}")"
          158                                 ;;
          159                         ssh://* )
          160                                 sshhost="${url##ssh://}"
          161                                 sshhost="${sshhost##*@}"
          162                                 sshhost="${sshhost%%/*}"
          163                                 sshport="22"
          164                                 if [ -z "${sshhost##*:*}" ];
          165                                 then
          166                                         sshport="${sshhost##*:}"
          167                                         sshhost="${sshhost%%:*}"
          168                                 fi
          169                                 error="$(checkraw "${sshhost}" "${sshport}")"
          170                                 ;;
          171                         * )
          172                                 flock -x "${program}" printf "TODO\t%s\tCan't handle %s\n" "${f}" "${url}" >&2
          173                                 exit
          174                                 ;;
          175                         esac
          176                 else
          177                         error="$(checkgopher "${host}" "${port}" "${selector}")"
          178                 fi
          179                 ;;
          180         search )
          181                 error="$(checkgopher "${host}" "${port}" "${selector}" "")"
          182                 ;;
          183         text | uuencoded | * )
          184                 error="$(checkgopher "${host}" "${port}" "${selector}")"
          185                 ;;
          186         esac
          187 
          188         lastcheck=""
          189         errorcount=0
          190         statefile="${statedir}/$(basename "$f")"
          191         if [ -f "${statefile}" ];
          192         then
          193                 IFS="        " read -r lastcheck errorcount < "${statefile}"
          194         fi
          195 
          196         if [ -n "${error}" ];
          197         then
          198                 errorcount=$((errorcount + 1))
          199         else
          200                 errorcount=0
          201         fi
          202 
          203         if [ ${errorcount} -ge ${errorthreshold} ];
          204         then
          205                 flock -x "${program}" printf "ERROR\t%s\t%s\n" "${f}" "${error}" >&2
          206         fi
          207 
          208         printf "%s\t%s\n" "${checktime}" "${errorcount}" > "${statefile}"
          209 else
          210         checktime="$(date +%s)" 
          211         statedir="$1"
          212 
          213         if [ -z "${statedir}" ];
          214         then
          215                 printf "You need to specify a state dir.\n" >&2
          216                 exit 1
          217         fi
          218 
          219         mkdir -p "${statedir}"
          220         if [ ! -d "${statedir}" ];
          221         then
          222                 printf "%s is not a directory! Aborting.\n" "${statedir}" >&2
          223                 exit 1
          224         fi
          225 
          226         shift
          227 
          228         for f;
          229         do
          230                 printf "%s\0" "${f}"
          231         done | LAWNHARK_WORKER=1 xargs -r -0 -P "${maxworkers}" -L1 "${program}" "${statedir}" "${checktime}"
          232 
          233         # garbage collection
          234         find "${statedir}" -type f | while read -r f;
          235         do
          236                 IFS="        " read -r lastcheck errorcount < "${f}"
          237 
          238                 if [ ${lastcheck} -ne ${checktime} ];
          239                 then
          240                         rm -f "${f}"
          241                 fi
          242         done
          243 fi