-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrfcreader.in
executable file
·187 lines (180 loc) · 5.48 KB
/
rfcreader.in
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#!/bin/bash
##
## vim:foldmethod=marker:nowrap:
##
##--- Help
## usage: SCNAME [-f] rfcnum|rfcname [rfcnum|rfcname ...]
##
## where "rfcnum" is the numerical part of the rfc you want to
## see,
## "rfcname" is a name if a rfc file (for instance
## "rfc-index") and
## "-f" forces the retrieval.
##
## This script tries to retrieve the rfcs in question from configurable sources.
## First it tries to find them in the paths found in the environment variable
## "RFCPATHS" (by default "@RFCCACHEDIR@", multiple paths separated by
## colons), then it tries to retrieve them from selected URLs found in
## "RFCSOURCES" (by default "http://www.rfc-editor.org/rfc/", multiple sources
## separated by spaces).
## The RFCs retrieved from a RFCSOURCES are either permanently stored in the
## first writable directory in RFCPATHS or written to the "TMPDIR" (by default
## "/tmp") and deleted after the used viewer has terminated.
## On the local system the comma separated extensions in RFCEXTENSIONS are
## tried otherwise the first extension found in RFCEXTENSIONS is tried for
## remote retrieval.
##--- Help end
##
##--- Set some traps
trap 'test -n "${files2del}" && rm -f ${files2del}' INT QUIT ABRT KILL TERM EXIT
##--- Whats the name of this script?
SCNAME="${0##*/}"
##--- Some presets which might be overwritten
: ${RFCPATHS:='@RFCCACHEDIR@'}
: ${RFCEXTENSIONS:=".txt.gz .txt .html"}
: ${RFCSOURCES:='http://www.rfc-editor.org/rfc/ http://www.rfc-editor.org/rfc/std http://www.rfc-editor.org/rfc/bcp http://www.rfc-editor.org/rfc/fyi ftp://ftp.isi.edu/in-notes/'}
: ${RFCPAGER:="${PAGER:-less}"}
: ${TMPDIR:="/tmp"}
##--- Some special variables
RFCSFOUND=''
rfcpaths="$(echo "${RFCPATHS}" | tr : " ")"
files2del=''
prefix='rfc'
##--- Option switches
opt_force=''
opt_help=''
##--- Some functions
function help () {
sed -r '
/^##--- Help$/,/^##--- Help end$/ {
s/^## //
s/HELP_SCNAME/'"${SCNAME}"'/g
}
1,/^##--- Help$/ d
/^##--- Help end$/,$ d' < $0
}
function findrfc () {
# usage: findrfc rfcname
# where "rfcname" is the name of one RFC you want to retrieve.
# Returns a string which is the path and name of the locally found
# rfc and return code zero or nothing a the return code ten. It
# processes the global variable "rfcpaths" and "RFCEXTENSIONS".
local rfcname="${1}" fullname='' retval='10'
# Process all the paths in "RFCPATHS".
for trypath in ${rfcpaths}; do
# And try them with all the extensions in "RFCEXTENSIONS".
for ext in ${RFCEXTENSIONS}; do
# Construct the filename to test for.
fullname="${trypath}/${rfcname}${ext}"
# If the constructed name exists print this name, set
# the return code to zero and end the two for loops.
test -r ${fullname} && \
{ echo "${fullname}"; retval='0'; break 2; }
done
done
return ${retval}
}
function findwritable () {
# usage: findwritable
# No arguments are processed. Returns either the last path in RFCPATHS
# which is writable for the current UID and return code zero or nothing
# and return code ten.
local retval='10' result=''
# Process all the seperate paths in RFCPATHS.
for pathname in ${rfcpaths}; do
# If we find a path which is writable print this one, set
# return code to zero and break the current for loop.
test -w ${pathname} && { result="${pathname}"; retval='0'; }
done
echo "${result}"
return ${retval}
}
function makename () {
local retval='10' rfcname="${1}" varname="${2}" ext="${3}" writabledir=''
local constructedname=''
if writabledir="$(findwritable)"; then
echo "${varname}='${writabledir}/${rfcname}${ext}'"
else
constructedname="${TMPDIR}/${rfcname}.${$}${ext}"
echo "files2del='${files2del:+${files2del} }${constructedname}'; ${varname}='${constructedname}'"
fi
}
function retrieverfc () {
local retval='10' rfcname="${1}" varname="${2}"
local localname=''; extension=''
for resource in ${RFCSOURCES}; do
for extension in ${RFCEXTENSIONS}; do
eval $(makename ${rfcname} localname ${extension})
if curl --location --silent --fail --output ${localname} "${resource}${rfcname}${extension}"; then
echo "files2del='${files2del}'; ${varname}='${localname}'"
retval='0'
break 2
fi
done
done
return ${retval}
}
function showrfc () {
local rfcfile="${1}"
test "${RFCPAGER##*/}" = "less" && RFCPAGEROPTS="'${rfcfile##*/}', lines %lt-%lb of %L"
$RFCPAGER${RFCPAGEROPTS:+ -PM"${RFCPAGEROPTS}"} ${rfcfile}
}
##--- Main program
process_opts="1"
while [ -n "${process_opts}" ]; do
case "${1}" in
-f|--force)
opt_force='1';;
--help|-h)
opt_help='1';;
--)
process_opts='';;
-*)
echo "$SCNAME: Unknown option '${1}'"
exit 10;;
*)
process_opts='';;
esac
test -n "$process_opts" && shift
done
if [ -n "$opt_help" ]; then
help
exit 0
fi
for rfcname in $*; do
case "${rfcname}" in
[0-9]*)
rfcname="${prefix}${rfcname}";;
*)
:
;;
esac
found="$(findrfc ${rfcname})"
if [ $? -eq 0 -a -z "${opt_force}" ]; then
RFCSFOUND="${RFCSFOUND:+${RFCSFOUND} }${found}"
else
if eval $(retrieverfc ${rfcname} found); then
RFCSFOUND="${RFCSFOUND:+$RFCSFOUND }${found}"
else
echo "${SCNAME}: rfc '${rfcname}' not found" >&2
fi
fi
done
for rfcfile in ${RFCSFOUND}; do
if [ -n "${firstshown}" ]; then
if REPLY="$(read -ersp "--${SCNAME}-- next: ${rfcfile##*/} [ view (return) | skip (Ctrl-D) | quit (Ctrl-C) ]" || REPLY='skiped'; echo "${REPLY}")"; then
if [ "${REPLY}" == "skiped" ]; then
echo
continue
elif [ -z "${REPLY}" ]; then
showrfc "${rfcfile}"
fi
else
echo
break
fi
else
showrfc "${rfcfile}"
fi
firstshown='1'
done