lawn-hark.sh - gopher-lawn - The gopher lawn gopher directory project.
HTML 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