forked from curl/wcurl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
wcurl
executable file
·230 lines (193 loc) · 6.21 KB
/
wcurl
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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
#!/bin/sh
# wcurl - a simple wrapper around curl to easily download files.
#
# Requires curl >= 7.46.0 (2015)
#
# Copyright (C) Samuel Henrique, <samueloph@debian.org>.
# Copyright (C) Sergio Durigan Junior, <sergiodj@debian.org>
# Copyright (C) Ryan Carsten Schmidt <git@ryandesign.com>
# Copyright (C) Ben Zanin
#
# Permission to use, copy, modify, and distribute this software for any purpose
# with or without fee is hereby granted, provided that the above copyright
# notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN
# NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
# OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of a copyright holder shall not be
# used in advertising or otherwise to promote the sale, use or other dealings in
# this Software without prior written authorization of the copyright holder.
#
# SPDX-License-Identifier: curl
# Stop on errors and on usage of unset variables.
set -eu
VERSION="2024.07.10+dev"
PROGRAM_NAME="$(basename "$0")"
readonly PROGRAM_NAME
# Display the version.
print_version()
{
cat << _EOF_
${VERSION}
_EOF_
}
# Display the program usage.
usage()
{
cat << _EOF_
${PROGRAM_NAME} -- a simple wrapper around curl to easily download files.
Usage: ${PROGRAM_NAME} [--curl-options <CURL_OPTIONS>] [--dry-run] [--] <URL>...
${PROGRAM_NAME} [--curl-options=<CURL_OPTIONS>] [--dry-run] [--] <URL>...
${PROGRAM_NAME} -h|--help
${PROGRAM_NAME} -V|--version
Options:
--curl-options <CURL_OPTIONS>: Specify extra options to be
passed when invoking curl. May be
specified more than once.
--dry-run: Don't actually execute curl, just print what would be
invoked.
-V,--version: Print version information.
-h,--help: Print this usage message.
<URL>: The URL to be downloaded. May be specified more than once.
_EOF_
}
# Display an error message and bail out.
error()
{
printf "%s\n" "$*" > /dev/stderr
exit 1
}
# Extra curl options provided by the user.
# This will be set per-URL for every URL provided.
# Some options are global, but we are erroring on the side of needlesly setting
# them multiple times instead of causing issues with parameters that needs to
# be set per-URL.
CURL_OPTIONS=""
# The URLs to be downloaded.
URLS=""
# The parameters that will be passed per-URL to curl.
readonly PER_URL_PARAMETERS="\
--fail \
--globoff \
--location \
--proto-default https \
--remote-name-all \
--remote-time \
--retry 10 \
--retry-max-time 10 "
# Whether to invoke curl or not.
DRY_RUN="false"
# Sanitize parameters.
sanitize()
{
if [ -z "${URLS}" ]; then
error "You must provide at least one URL to download."
fi
readonly CURL_OPTIONS URLS DRY_RUN
}
# Execute curl with the list of URLs provided by the user.
exec_curl() {
CMD="curl "
# Store version to check if it supports --no-clobber and --parallel.
curl_version=$($CMD --version | cut -f2 -d' ' | head -n1)
# --no-clobber is only supported since 7.83.0.
# --parallel is only supported since 7.66.0.
if [ "$(echo "$curl_version" | cut -f1 -d.)" -ge 8 ]; then
CURL_HAS_NO_CLOBBER="--no-clobber"
CURL_HAS_PARALLEL="--parallel"
elif [ "$(echo "$curl_version" | cut -f1 -d.)" -eq 7 ];then
if [ "$(echo "$curl_version" | cut -f2 -d.)" -ge 83 ]; then
CURL_HAS_NO_CLOBBER="--no-clobber"
else
CURL_HAS_NO_CLOBBER=""
fi
if [ "$(echo "$curl_version" | cut -f2 -d.)" -ge 66 ]; then
CURL_HAS_PARALLEL="--parallel"
else
CURL_HAS_PARALLEL=""
fi
else
CURL_HAS_NO_CLOBBER=""
CURL_HAS_PARALLEL=""
fi
# Detecting whether we need --parallel. It's easier to rely on
# the shell's argument parsing.
# shellcheck disable=SC2086
set -- $URLS
if [ "$#" -gt 1 ]; then
CURL_PARALLEL="$CURL_HAS_PARALLEL"
else
CURL_PARALLEL=""
fi
# Start assembling the command.
#
# We use 'set --' here (again) because (a) we don't have arrays on
# POSIX shell, and (b) we need better control over the way we
# split arguments.
#
# shellcheck disable=SC2086
set -- ${CMD} ${CURL_PARALLEL}
NEXT_PARAMETER=""
for url in ${URLS}; do
# shellcheck disable=SC2086
set -- "$@" ${NEXT_PARAMETER} ${PER_URL_PARAMETERS} ${CURL_HAS_NO_CLOBBER} ${CURL_OPTIONS} "${url}"
NEXT_PARAMETER="--next"
done
if [ "${DRY_RUN}" = "false" ]; then
exec "$@"
else
printf "%s\n" "$@"
fi
}
# Use "${1-}" in order to avoid errors because of 'set -u'.
while [ -n "${1-}" ]; do
case "${1}" in
--curl-options=*)
opt=$(printf "%s\n" "${1}" | sed 's/^--curl-options=//')
CURL_OPTIONS="${CURL_OPTIONS} ${opt}"
;;
--curl-options)
shift
CURL_OPTIONS="${CURL_OPTIONS} ${1}"
;;
--dry-run)
DRY_RUN="true"
;;
-h|--help)
usage
exit 0
;;
-V|--version)
print_version
exit 0
;;
--)
# This is the start of the list of URLs.
shift
for url in "$@"; do
# Encode whitespaces into %20, since wget supports those URLs.
newurl=$(printf "%s\n" "${url}" | sed 's/ /%20/g')
URLS="${URLS} ${newurl}"
done
break
;;
-*)
error "Unknown option: '$1'."
;;
*)
# This must be a URL.
# Encode whitespaces into %20, since wget supports those URLs.
newurl=$(printf "%s\n" "${1}" | sed 's/ /%20/g')
URLS="${URLS} ${newurl}"
;;
esac
shift
done
sanitize
exec_curl