about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xbollux.sh264
-rwxr-xr-xpage48
-rw-r--r--test16
-rw-r--r--winch13
-rwxr-xr-xwrap31
5 files changed, 0 insertions, 372 deletions
diff --git a/bollux.sh b/bollux.sh deleted file mode 100755 index 84786b6..0000000 --- a/bollux.sh +++ /dev/null
@@ -1,264 +0,0 @@
1#!/usr/bin/env bash
2# bollux: bash gemini client
3# Author: Case Duckworth <acdw@acdw.net>
4# License: MIT
5# Version: -0.9
6
7PRGN="${0##*/}"
8PORT=1965
9LOG_LEVEL=3 # higher=more important.
10
11clean() {
12 # '\e[?7h': re-enable line wrapping
13 # '\e[2J': clear the screen
14 # '\e[;r': reset the scroll area
15 # '\e[?1049l': swap back to primary screen
16 printf '\e[?7h\e[2J\e[;r\e[?1049l'
17 exit
18}
19
20refresh() {
21 # grab the terminal size
22 shopt -s checkwinsize
23 (
24 :
25 :
26 )
27 # '\e[?1049h': Swap to the alternate buffer.
28 # '\e[?7l': Disable line wrapping.
29 # '\e[2J': Clear the screen.
30 # '\e[3;%sr': Set the scroll area.
31 # '\e[999H': Move the cursor to the bottom.
32 printf '\e[?1049h\e[?7l\e[2J\e[3;%sr\e[999H' "$((LINES - 1))"
33}
34
35resize() {
36 refresh
37 # '\e7': Save the cursor position.
38 # '\e[?25l': Hide the cursor.
39 # '\r': Move the cursor to column 0.
40 # '\e[999B': Move the cursor to the bottom.
41 # '\e[A': Move the cursor up a line.
42 printf '\e7\e[?25l\r\e[999B\e[A'
43}
44
45bollux() {
46 if [[ -n "$1" ]]; then
47 loc="$1"
48 else
49 read -rp "GO> " loc
50 fi
51
52 log 2 "location: $loc"
53 log 2 "address: $(address "$loc")"
54 log 2 "server: $(server "$loc")"
55
56 address "$loc" |
57 download "$(server "$loc")" |
58 handle
59}
60
61log() {
62 case "$1" in
63 [0-9]*)
64 lvl="$1"
65 shift
66 ;;
67 *) lvl=5 ;;
68 esac
69 if ((lvl >= LOG_LEVEL)); then
70 if [[ "$2" == - ]]; then
71 while IFS= read -r line; do
72 printf '\e[33m%s\e[0m:\t%s\n' "$PRGN" "$line" >&2
73 done
74 else
75 printf '\e[34m%s\e[0m:\t%s\n' "bollux" "$*" >&2
76 fi
77 fi
78}
79
80download() {
81 # usage:
82 # echo REQUEST | download SERVER
83 # download SERVER REQUEST
84 serv="$1"
85 req=
86 if (($# == 2)); then
87 req="$2"
88 else
89 req="$(cat)"
90 fi
91 t="$(mktemp)"
92 openssl s_client -crlf -ign_eof -quiet -connect "$serv" <<<"$req" 2>"$t"
93 log 1 <"$t"
94 rm "$t"
95}
96
97address() {
98 addr="$1"
99 if [[ "$addr" != gemini://* ]]; then
100 addr="gemini://$addr"
101 fi
102 echo "$addr" | trim
103}
104
105server() {
106 serv="${1#*://}"
107 serv="${serv%%/*}"
108 if [[ "$serv" != *:* ]]; then
109 serv="$serv:$PORT"
110 fi
111 echo "$serv" | trim
112}
113
114trim() {
115 sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'
116}
117
118display() {
119 echo
120 cat
121 echo
122}
123
124handle() {
125 # cf. gemini://gemini.circumlunar.space/docs/spec-spec.txt
126 resp="$(cat)"
127 head="$(head -n1 <<<"$resp")"
128 body="$(tail -n+2 <<<"$resp")"
129 stat="$(awk '{print $1}' <<<"$head")"
130 smsg="$(
131 awk '{for(i=2;i<=NF;i++)printf "%s ",$i;printf "\n";}' <<<"$head"
132 )"
133
134 log "[$stat] $smsg"
135
136 case "$stat" in
137 10) # INPUT
138 # As per definition of single-digit code 1 in 1.3.2.
139 NOT_IMPLEMENTED
140 ;;
141 20) # SUCCESS
142 # As per definition of single-digit code 2 in 1.3.2.
143 display <<<"$body"
144 ;;
145 21) # SUCCESS - END OF CLIENT CERTIFICATE SESSION
146 # The request was handled successfully and a response body will
147 # follow the response header. The <META> line is a MIME media
148 # type which applies to the response body. In addition, the
149 # server is signalling the end of a transient client certificate
150 # session which was previously initiated with a status 61
151 # response. The client should immediately and permanently
152 # delete the certificate and accompanying private key which was
153 # used in this request.
154 display <<<"$body"
155 NOT_FULLY_IMPLEMENTED
156 ;;
157 30) # REDIRECT - TEMPORARY
158 # As per definition of single-digit code 3 in 1.3.2.
159 exec "$0" "$smsg"
160 ;;
161 31) # REDIRECT - PERMANENT
162 # The requested resource should be consistently requested from
163 # the new URL provided in future. Tools like search engine
164 # indexers or content aggregators should update their
165 # configurations to avoid requesting the old URL, and end-user
166 # clients may automatically update bookmarks, etc. Note that
167 # clients which only pay attention to the initial digit of
168 # status codes will treat this as a temporary redirect. They
169 # will still end up at the right place, they just won't be able
170 # to make use of the knowledge that this redirect is permanent,
171 # so they'll pay a small performance penalty by having to follow
172 # the redirect each time.
173 exec "$0" "$smsg"
174 NOT_FULLY_IMPLEMENTED
175 ;;
176 4*) # 40 - TEMPORARY FAILURE
177 # As per definition of single-digit code 4 in 1.3.2.
178 # 41 - SERVER UNAVAILABLE
179 # The server is unavailable due to overload or maintenance.
180 # (cf HTTP 503)
181 # 42 - CGI ERROR
182 # A CGI process, or similar system for generating dynamic
183 # content, died unexpectedly or timed out.
184 # 43 - PROXY ERROR
185 # A proxy request failed because the server was unable to
186 # successfully complete a transaction with the remote host.
187 # (cf HTTP 502, 504)
188 # 44 - SLOW DOWN
189 # Rate limiting is in effect. <META> is an integer number of
190 # seconds which the client must wait before another request is
191 # made to this server.
192 # (cf HTTP 429)
193 printf 'OH SHIT!\n%s\t%s\n' "$stat" "$smsg" >&2
194 NOT_IMPLEMENTED
195 ;;
196 5*) # 50 - PERMANENT FAILURE
197 # As per definition of single-digit code 5 in 1.3.2.
198 # 51 - NOT FOUND
199 # The requested resource could not be found but may be available
200 # in the future.
201 # (cf HTTP 404)
202 # (struggling to remember this important status code? Easy:
203 # you can't find things hidden at Area 51!)
204 # 52 - GONE
205 # The resource requested is no longer available and will not be
206 # available again. Search engines and similar tools should
207 # remove this resource from their indices. Content aggregators
208 # should stop requesting the resource and convey to their human
209 # users that the subscribed resource is gone.
210 # (cf HTTP 410)
211 # 53 - PROXY REQUEST REFUSED
212 # The request was for a resource at a domain not served by the
213 # server and the server does not accept proxy requests.
214 # 59 - BAD REQUEST
215 # The server was unable to parse the client's request,
216 # presumably due to a malformed request.
217 # (cf HTTP 400)
218 printf 'OH SHIT!\n%s\t%s\n' "$stat" "$smsg" >&2
219 NOT_IMPLEMENTED
220 ;;
221 6*) # 60 - CLIENT CERTIFICATE REQUIRED
222 # As per definition of single-digit code 6 in 1.3.2.
223 # 61 - TRANSIENT CERTIFICATE REQUESTED
224 # The server is requesting the initiation of a transient client
225 # certificate session, as described in 1.4.3. The client should
226 # ask the user if they want to accept this and, if so, generate
227 # a disposable key/cert pair and re-request the resource using it.
228 # The key/cert pair should be destroyed when the client quits,
229 # or some reasonable time after it was last used (24 hours?
230 # Less?)
231 # 62 - AUTHORISED CERTIFICATE REQUIRED
232 # This resource is protected and a client certificate which the
233 # server accepts as valid must be used - a disposable key/cert
234 # generated on the fly in response to this status is not
235 # appropriate as the server will do something like compare the
236 # certificate fingerprint against a white-list of allowed
237 # certificates. The client should ask the user if they want to
238 # use a pre-existing certificate from a stored "key chain".
239 # 63 - CERTIFICATE NOT ACCEPTED
240 # The supplied client certificate is not valid for accessing the
241 # requested resource.
242 # 64 - FUTURE CERTIFICATE REJECTED
243 # The supplied client certificate was not accepted because its
244 # validity start date is in the future.
245 # 65 - EXPIRED CERTIFICTE REJECTED
246 # The supplied client certificate was not accepted because its
247 # expiry date has passed.
248 printf 'OH SHIT!\n%s\t%s\n' "$stat" "$smsg" >&2
249 NOT_IMPLEMENTED
250 ;;
251 esac
252}
253
254NOT_IMPLEMENTED() {
255 log "NOT IMPLEMENTED!!!" >&2
256 exit 127
257}
258NOT_FULLY_IMPLEMENTED() {
259 log "NOT FULLY IMPLEMENTED!!!" >&2
260}
261
262if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
263 bollux "$@"
264fi
diff --git a/page b/page deleted file mode 100755 index c478d7a..0000000 --- a/page +++ /dev/null
@@ -1,48 +0,0 @@
1#!/bin/bash
2# pager
3
4. ./wrap
5
6cleanup() {
7 tput reset
8 exit
9}
10
11refresh() {
12 shopt -s checkwinsize
13 (
14 :
15 :
16 )
17 printf '\e[?1049h\e?7l\e[2J\e[3;%sr\e[999H' "$((LINES - 1))"
18}
19
20resize() {
21 refresh
22
23 printf '\e7\e[?25l\e[H'
24 _wrap "$file"
25 printf '\e[999H\e[?25h'
26}
27
28_wrap() {
29 wrap "$COLUMNS" <"$1"
30}
31
32main() {
33 refresh
34
35 file="$1"
36 resize
37
38 trap resize WINCH
39 trap cleanup INT
40
41 while :; do
42 :
43 done
44}
45
46if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
47 main "$@"
48fi
diff --git a/test b/test deleted file mode 100644 index adbf833..0000000 --- a/test +++ /dev/null
@@ -1,16 +0,0 @@
1Your bones don't break, mine do. That's clear. Your cells react to bacteria and viruses differently than mine. You don't get sick, I do. That's also clear. But for some reason, you and I react the exact same way to water. We swallow it too fast, we choke. We get some in our lungs, we drown. However unreal it may seem, we are connected, you and I. We're on the same curve, just on opposite ends.
2
3Съешь же ещё этих мягких французских булок, да выпей чаю Съешь же ещё этих мягких французских булок, да выпей чаю Съешь же ещё этих мягких французских булок, да выпей чаю Съешь же ещё этих мягких французских булок, да выпей чаю Съешь же ещё этих мягких французских булок, да выпей чаю Съешь же ещё этих мягких французских булок, да выпей чаю Съешь же ещё этих мягких французских булок, да выпей чаю Съешь же ещё этих мягких французских булок, да выпей чаю Съешь же ещё этих мягких французских булок, да выпей чаю
4
5写ラんごる仏際定諭ムトウヨ検発ホキナシ属沢こずドら除賞ソキイヨ整報ラケト堀生ばす見戦おうたみ意入ネヘ成43差リ旅世がうリト内処輪察るドを。成ラ定迎るに難討事子よまゅや名6汗ミ制要質ぴご日歩ル古捕際くクそを経日そた報底肉くも。入ち大5員ム食激シ負未ミ夜常ヲメヱム拒手ヨヌクユ街先為ち太要ゅ復大ばゅでく安3会就携ヘキ活郵ゆぼ光属がにぐ能表キヨニ覃月スエマ経協たそぽ。
6
7航ーい町9久ょな丸断ぱ見下ら料75載と談作ドけおッ信田チ子初分著ルハユツ統真レ供約的治チシ最板植稿息き。禁ユセカヱ資事オ価界願の安貸めげさす薬記もー掲小リナマ止全たじつ警際著ムタヱス社4質で別五比智ねおこつ。87上え応政でルトは商構ヨカ能件カハ万禁かこり優斜もさばぞ帳渡レマコヱ月委ノメ冬況殿69上ぼょきほ部芝亨拙リ。
8
9川よリっへ政少たにやし済手け安宗ずょ年常だて社行受ニリ問済えゃ前石評リレ属価び州幕なぞてほ知害さら月平エス権芸マ裏臍マ護躍るたス報裁再能労め。起ル著目ちが条舞ばよ黙明イ王王こざ絵49金はっき書牛三県ムア堀47此カ会橋君恵康ほイす。変フアハ省葉禁ト需気わ医42講レヲミア米細ト抗選席ゆ京9料こゆ焼深タフカサ側氷モムワマ応7祭ず。
10
11ლორემ იფსუმ დოლორ სით ამეთ, ეა მედიოცრემ თჰეოფჰრასთუს სით. ნო დუო ჰინც დიცით თამყუამ. ენიმ ზრილ ფერ ეა, ასსუმ ნოსთრუმ ფერციფით ვის იდ. სედ სუმმო ფრიმის თე, ეამ ნო ენიმ მოლესთიაე. ფაცილისის ფერიცულის მეა ინ, ფრი ეა დეცორე ცომფლეცთითურ. ეამ იუვარეთ ვივენდო სცრიფთორემ ეუ, ნამ ეხ იგნოთა ვერთერემ, ეხ დუო ეროს სოლეთ.
12
13უთ უნუმ ფაულო ასსუევერით ჰას, სეა ჰინც სანცთუს ფუისსეთ თე. მეი ნონუმy ნუმყუამ ეთ, თოლლით მუნერე ინსოლენს ეუ დუო. ლაბორე დელეცთუს ირაცუნდია ყუი ეა. ყუო ლეგერე ვერეარ დიცერეთ იდ, ნოვუმ ვიდერერ ოფფიციის ეი სით.
14
15ფრო ნულლამ ფერციფითურ სცრიფსერით ნო. დელეცთუს აცცომმოდარე იდ ნეც, იისყუე ვულფუთათე ნე ჰის. ეროს უბიყუე იმფედით ან ნეც, თიმეამ ადმოდუმ ფრაესენთ მელ ან. თალე ენიმ ყუი ნე, ყუი ფონდერუმ ადიფისცინგ ვითუფერათა ეი. ეუ ფოფულო გრაეცი ფერთინახ ფრი.
16
diff --git a/winch b/winch deleted file mode 100644 index 845aa57..0000000 --- a/winch +++ /dev/null
@@ -1,13 +0,0 @@
1#!/usr/bin/env bash
2
3winch() {
4shopt -s checkwinsize; (:;:)
5
6printf '\e[?25l\e[H\e[K%s %sx%s\e[8' "winch!" "$COLUMNS" "$LINES"
7}
8
9trap winch WINCH
10
11while : ; do
12 :
13done
diff --git a/wrap b/wrap deleted file mode 100755 index 011aa58..0000000 --- a/wrap +++ /dev/null
@@ -1,31 +0,0 @@
1#!/usr/bin/env bash
2
3wrap() {
4 local width="$1"
5 local len=0
6
7 while read -r -a line; do
8 for word in "${line[@]}"; do
9 ((len += "${#word}" + 1))
10 #printf '%s' "$len"
11 if ((len >= width)); then
12 printf '\n'
13 # ruler "$width"
14 len=${#word}
15 fi
16 printf '%s ' "$word"
17 done
18 done
19 printf '\n'
20}
21
22ruler() {
23 for ((i = 0; i < $1; i++)); do
24 printf '%s' "${2:--}"
25 done
26 printf '\n'
27}
28
29if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
30 wrap "$@"
31fi