pastebin - collaborative debugging tool
nrubsig.kpaste.net RSS

Difference between
modified post 6486f08ef by Anonymous on Wed 31st Jan 2024 14:02
original post ed8aa by Anonymous on Wed 31st Jan 2024 13:43
Download diff
Show old version | new version | both versions

    
11
#!/bin/ksh93
22
33
#
44
# MIT License
55
#
66
# Copyright (c) 2024 Roland Mainz <roland.mainz@nrubsig.org>
77
#
88
# Permission is hereby granted, free of charge, to any person obtaining a copy
99
# of this software and associated documentation files (the "Software"), to deal
1010
# in the Software without restriction, including without limitation the rights
1111
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1212
# copies of the Software, and to permit persons to whom the Software is
1313
# furnished to do so, subject to the following conditions:
1414
#
1515
# The above copyright notice and this permission notice shall be included in all
1616
# copies or substantial portions of the Software.
1717
#
1818
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1919
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2020
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2121
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2222
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2323
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2424
# SOFTWARE.
2525
#
2626
2727
#
2828
# nfsurlconv.ksh - convert host/port/path from/to a nfs://-URL
2929
3030
#
3131
# Written by Roland Mainz <roland.mainz@nrubsig.org>
3232
#
3333
3434
function usage
3535
{
3636
	(( OPTIND=0 ))
3737
	getopts -a "${1}" "${2}" OPT '-?'
3838
	return 2
3939
}
4040
4141
#
4242
# parse_rfc1738_url - parse RFC 1838 URLs
4343
#
4444
# Output variables are named after RFC 1838 Section 5 ("BNF for
4545
# specific URL schemes")
4646
#
4747
function parse_rfc1738_url
4848
{
4949
	set -o nounset
5050
5151
	typeset url="$2"
5252
	typeset leftover
5353
	nameref data="$1" # output compound variable
5454
5555
	# ~(E) is POSIX extended regular expression matching (instead
5656
	# of shell pattern), "x" means "multiline", "l" means "left
5757
	# anchor", "r" means "right anchor"
5858
	leftover="${url/~(Elrx)
5959
		(.+?)				# scheme
6060
		:\/\/				# '://'
6161
		(				# login
6262
			(?:
6363
				(.+?)		# user (optional)
6464
				(?::(.+))?	# password (optional)
6565
				@
6666
			)?
6767
			(			# hostport
6868
				(.+?)		# host
6969
				(?::([[:digit:]]+))? # port (optional)
7070
			)
7171
		)
7272
		(?:\/(.*?))?/X}"		# path (optional)
7373
7474
	# All parsed data should be captured via eregex in .sh.match - if
7575
	# there is anything left (except the 'X') then the input string did
7676
	# not properly match the eregex
7777
	[[ "$leftover" == 'X' ]] ||
7878
		{ print -u2 -f $"%s: Parser error, leftover=%q\n" \
7979
			"$0" "$leftover" ; return 1 ; }
8080
8181
	data.url="${.sh.match[0]}"
8282
	data.scheme="${.sh.match[1]}"
8383
	data.login="${.sh.match[2]}"
8484
	# FIXME: This should use [[ ! -v .sh.match[3] ]], but ksh93u has bugs
8585
	[[ "${.sh.match[3]-}" != '' ]] && data.user="${.sh.match[3]}"
8686
	[[ "${.sh.match[4]-}" != '' ]] && data.password="${.sh.match[4]}"
8787
	data.hostport="${.sh.match[5]}"
8888
	data.host="${.sh.match[6]}"
8989
	[[ "${.sh.match[7]-}" != '' ]] && integer data.port="${.sh.match[7]}"
9090
	[[ "${.sh.match[8]-}" != '' ]] && data.uripath="${.sh.match[8]}"
9191
9292
	if [[ -v data.uripath ]] ; then
9393
		data.path="${ printf "${data.uripath//~(E)(?:%([[:xdigit:]][[:xdigit:]]))/\\x\1}" ; }"
9494
	fi
9595
9696
	return 0
9797
}
9898
9999
100100
function parse_sshnfs_url
101101
{
102102
	typeset url="$2"
103103
	nameref data="$1"
104104
105105
	parse_rfc1738_url data "$url" || return 1
106106
107107
	[[ "${data.scheme}" == ~(Elr)(ssh\+nfs|nfs) ]] || \
108108
		{ print -u2 -f $"%s: Not a nfs:// or ssh+nfs:// url\n" "$0" ; return 1 ; }
109109
	[[ "${data.host}" != '' ]] || { print -u2 -f $"%s: NFS hostname missing\n" "$0" ; return 1 ; }
110110
	[[ "${data.uripath}" != '' ]] || { print -u2 -f $"%s: NFS path missing\n" "$0" ; return 1 ; }
111111
	[[ "${data.uripath}" == /* ]] || { print -u2 -f $"%s: NFS path (%q) must be absolute\n" "$0" "${data.uripath}" ; return 1 ; }
112112
	[[ "${data.uripath}" != //* ]] || { print -u2 -f $"%s: NFS path (%q) should not start with '//' \n" "$0" "${data.uripath}" ; return 1 ; }
113113
114114
	return 0
115115
}
116116
117117
118118
function urlencodestr
119119
{
120120
	set -o nounset
121121
122122
	nameref out_encodedstr=$1
123123
	typeset in_str="$2"
124124
	typeset ch ch_hexval dummy
125125
	integer ch_num
126126
	typeset url=''
127127
128128
	#
129129
	# URLs encode non-ASCII characters as UTF-8 on byte-level,
130130
	# while POSIX shells (ksh93, bash, etc.) operate on
131131
	# characters (which *MAY* be - like UTF-8 - encoded as
132132
	# multibyte characters, but may use a different encoding
133133
	# like ISO8859-1 or GB18030).
134134
	# The code below solves that by using iconv(1) to
135135
	# convert everything into UTF-8 bytes, then convert the
136136
	# bytes via od(1) into pairs of { position, hexadecimal
137137
	# character value ("hexval") }, and then turn these to
138138
	# ASCII ("ch") / numeric ASCII ("ch_num") values
139139
	# (this assumes that the current LC_CTYPE is
140140
	# ASCII-compatible)
141141
	#
142142
	printf '%s' "$in_str" | \
143143
		iconv -t 'UTF-8' | \
144144
		od -t x1 -w1 -v | \
145145
		while read dummy ch_hexval ; do
146146
		[[ "$ch_hexval" != '' ]] || break
147147
148148
		ch_num="${ printf "%d" "0x$ch_hexval" ; }"
149149
		if (( ch_num <= 127 )) ; then
150150
			typeset ch="${ printf "\x$ch_hexval" ; }"
151151
		else
152152
			#
153153
			# character is outside ASCII, shell may
154154
			# not be able to represent this
155155
			#
156156
			[[ -v ch ]] && unset ch
157157
		fi
158158
159159
		#
160160
		# From RFC 1738 ("Uniform Resource Locators (URL)"):
161161
		# unsafe characters in URLS:
162162
		# "{", "}", "|", "\", "^", "~", "[", "]", and "`"
163163
		# characters which must always be encoded:
164164
		# "#", "%"
165165
		# characters which must be encoded because they have a special meaning:
166166
		# ";", "/", "?", ":", "@", "=" and "&"
167167
		# Only alphanumerics, "$-_.+!*'()," and reserved characters
168168
		# ("/" for nfs://-URLS) are allowed
169169
		#
170170
		if (( ch_num > 127 )) || [[ "$ch" != ~(Elr)[/$-_.+!*\'(),[:alnum:]] ]] ; then
171171
			url+="%$ch_hexval"
172172
		else
173173
			url+="$ch"
174174
		fi
175175
	done
176176
177177
	#printf 'str=%q\n' "$url"
178178
	out_encodedstr="$url"
179179
	return 0
180180
}
181181
182182
183183
function hostname_port_path_to_nfsurl
184184
{
185185
	set -o nounset
186186
187187
	typeset hostname="$1"
188188
	integer port="$2"
189189
	typeset path="$3"
190190
191191
	typeset enc_path
192192
	typeset enc_hostname
193193
194194
	urlencodestr enc_hostname "$hostname"
195195
	urlencodestr enc_path "$path"
196196
	if (( port == 2049 )) ; then
197197
		printf 'url=nfs://%s/%s\n' "$enc_hostname" "$enc_path"
198198
	else
199199
		printf 'url=nfs://%s:%d/%s\n' "$enc_hostname" port "$enc_path"
200200
	fi
201201
	return 0
202202
}
203203
204204
function main
205205
{
206206
	set -o nounset
207207
208208
	# fixme: Need better text layout for $ nfsurlconv --man #
209209
	typeset -r nfsurlconv_usage=$'+
210210
	[-?\n@(#)\$Id: nfsurlconv (Roland Mainz) 2024-01-31 \$\n]
211211
	[-author?Roland Mainz <roland.mainz@nrubsig.org>]
212212
	[+NAME?nfsurlconv - convert hostname,port,path from/to a nfs://-URL]
213213
	[+DESCRIPTION?\bnfsurlconv\b convert { hostname, port, path } from/to a nfs://-URL.]
214214
	[D:debug?Enable debugging.]
215215
216-
	hostnameportpath2nfsurl [options]
216+
	hostnameportpath2nfsurl hostname port path
217-
	hostnamepath2nfsurl [options]
217+
	hostnamepath2nfsurl hostname path
218-
	url2hostnameportpath [options]
218+
	url2hostnameportpath url
219-
	url2hostportpath [options]
219+
	url2hostportpath url
220-
	url2compound [options]
220+
	url2compound url
221221
	--man
222222
223223
	[+EXAMPLES]{
224224
		[+?Example 1:][+?Convert hostname bbb, port 12049 and path /a/b/c to a nfs://-URL]{
225225
[+\n$ nfsurlconv hostnameportpath2nfsurl bbb 12049 "/a/b/c"
226226
url=nfs:://bbb::12049//a/b/c
227227
]
228228
}
229229
		[+?Example 2:][+?Convert URL nfs://bbb:12049//a/b/c to ( hostname=, port=, path= )]{
230230
[+\n$ nfsurlconv.ksh url2hostnameportpath nfs:://bbb//a/b/c
231231
hostname=bbb
232232
port=2049
233233
path=/a/b/c
234234
]
235235
}
236236
		[+?Example 3:][+?Convert URL nfs://bbb:12049//a/b/c to ( hostport=, path= )]{
237237
[+\n$ nfsurlconv.ksh url2hostportpath nfs:://bbb//a/b/c
238238
hostport=bbb
239239
path=/a/b/c
240240
]
241241
}
242242
	}
243243
	[+SEE ALSO?\bksh93\b(1),\bssh\b(1),\bmount.nfs\b(8),\bnfs\b(5)]
244244
	'
245245
246246
	compound c
247247
	typeset -a c.args
248248
	integer saved_optind_m1	# saved OPTIND-1
249249
250250
	c.args=( "$@" )
251251
252252
	#
253253
	# Argument parsing
254254
	#
255255
	while getopts -a "${progname}" "${nfsurlconv_usage}" OPT "${c.args[@]}" ; do
256256
		case "${OPT}" in
257257
			'D')
258258
				# fixme: Implement debugging option
259259
				;;
260260
			*)
261261
				usage "${progname}" "${nfsurlconv_usage}"
262262
				return $?
263263
				;;
264264
		esac
265265
	done
266266
267267
	(( saved_optind_m1=OPTIND-1 ))
268268
269269
	# remove options we just parsed from c.args
270270
	for ((i=0 ; i < saved_optind_m1 ; i++)) ; do
271271
		unset c.args[$i]
272272
	done
273273
274274
	#
275275
	# c.args mighth be a sparse array (e.g. "([1]=aaa [2]=bbb [4]=ccc)")
276276
	# right now after we removed processed options/arguments.
277277
	# For easier processing below we "reflow" the array back to a
278278
	# normal linear layout (e.g. ([0]=aaa [1]=bbb [2]=ccc)
279279
	#
280280
	c.args=( "${c.args[@]}" )
281281
282-
	typeset mode="$1"
282+
	typeset mode="${c.args[0]-}"
283283
284284
	case "$mode" in
285+
		# fixme: add "hostportpath2nfsurl"
285287
		'hostnameportpath2nfsurl')
286288
			hostname_port_path_to_nfsurl "${@:2}"
287289
			return $?
288290
			;;
289291
		'hostnamepath2nfsurl')
290292
			hostname_port_path_to_nfsurl "${@:2:1}" 2049 "${@:3:1}"
291293
			return $?
292294
			;;
293295
		'url2hostnameportpath')
294296
			compound urldata
295297
296298
			parse_sshnfs_url urldata "${@:2:1}" || return 1
297299
			printf 'hostname=%s\n' "${urldata.host}"
298300
			printf 'port=%s\n' "${urldata.port-2049}"
299301
			printf 'path=%s\n' "${urldata.path-}"
300302
			return 0
301303
			;;
302304
		'url2hostportpath')
303305
			compound urldata
304306
305307
			parse_sshnfs_url urldata "${@:2:1}" || return 1
306308
			printf 'hostport=%s\n' "${urldata.hostport}"
307309
			printf 'path=%s\n' "${urldata.path-}"
308310
			return 0
309311
			;;
310312
		'url2compound')
311313
			compound urldata
312314
313315
			parse_sshnfs_url urldata "${@:2:1}" || return 1
314316
			print -v urldata
315317
			return 0
316318
			;;
317319
		*)
318320
			print -u2 -f $"Unknown mode %q\n" "$mode"
319321
			usage "${progname}" "${nfsurlconv_usage}"
320322
			return 2
321323
			;;
322324
	esac
323325
324326
	return 2
325327
}
326328
327329
#
328330
# main
329331
#
330332
builtin cat
331333
builtin mkdir
332334
builtin basename
333335
334336
typeset progname="${ basename "${0}" ; }"
335337
336338
main "$@"
337339
exit $?
338340
339341
# EOF.
340342

Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at