├── Makefile ├── README.md ├── bin ├── doc.sh ├── lint.sh └── test.sh ├── doc ├── 0x0.1 └── 0x0.1.pdf └── src └── 0x0 /Makefile: -------------------------------------------------------------------------------- 1 | PREFIX = /usr/local 2 | 3 | install: 4 | mkdir -p $(PREFIX)/bin 5 | cp src/0x0 $(PREFIX)/bin 6 | 7 | mkdir -p $(PREFIX)/man/man1 8 | cp doc/0x0.1 $(PREFIX)/man/man1 9 | 10 | .PHONY: test 11 | test: 12 | bin/test.sh 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 0x0 2 | A portable POSIX shell CLI to the https://0x0.st file sharing and URL shortening service. 3 | 4 | The main documentation is the man page which you can view at [0x0(1)](https://github.com/fossegrim/0x0/raw/master/doc/0x0.1.pdf) or with `man 0x0`. 5 | 6 | --- 7 | 8 | 0x0 is written in portable shell and should run anywhere cURL is installed. You most likely already have cURL, otherwise you should install it. It's in your repositories. 9 | 10 | `make install` installs the executable to `$(PREFIX)/bin` and the manual to `$(PREFIX)/man/man1`, `$(PREFIX)` defaulting to `/usr/local`. For most Unix-likes this is the correct locations. The notable exception is MacOS. It does not search `/usr/local/man` for manuals by default. Instead they go in `/usr/share/man` or `/usr/local/share/man`. Deal with it. 11 | -------------------------------------------------------------------------------- /bin/doc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright (c) 2020 Olav Fosse 4 | # 5 | # Permission to use, copy, modify, and distribute this software for any purpose 6 | # with or without fee is hereby granted, provided that the above copyright 7 | # notice and this permission notice appear in all copies. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 10 | # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 | # AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 12 | # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 | # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 14 | # OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 | # PERFORMANCE OF THIS SOFTWARE. 16 | # 17 | 18 | mandoc -Tlint -Wstyle doc/0x0.1 || exit 1 19 | mandoc -Tpdf doc/0x0.1 > doc/0x0.1.pdf || exit 1 20 | mandoc doc/0x0.1 || exit 1 21 | -------------------------------------------------------------------------------- /bin/lint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright (c) 2020 Olav Fosse 4 | # 5 | # Permission to use, copy, modify, and distribute this software for any purpose 6 | # with or without fee is hereby granted, provided that the above copyright 7 | # notice and this permission notice appear in all copies. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 10 | # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 | # AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 12 | # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 | # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 14 | # OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 | # PERFORMANCE OF THIS SOFTWARE. 16 | # 17 | 18 | shellcheck bin/* src/* 19 | -------------------------------------------------------------------------------- /bin/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright (c) 2020 Olav Fosse 4 | # 5 | # Permission to use, copy, modify, and distribute this software for any purpose 6 | # with or without fee is hereby granted, provided that the above copyright 7 | # notice and this permission notice appear in all copies. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 10 | # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 | # AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 12 | # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 | # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 14 | # OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 | # PERFORMANCE OF THIS SOFTWARE. 16 | # 17 | 18 | # ---Constants--- 19 | USAGE="$(cat << EOF 20 | usage: 0x0 file [-nv] filename 21 | 0x0 shorten [-nv] URL 22 | 0x0 url [-nv] URL 23 | EOF 24 | )" 25 | 26 | PATH0X0="$PWD/src/0x0" 27 | 28 | # ---Globals--- 29 | ALL_GREEN=true 30 | 31 | # ---Helpers--- 32 | fail() { 33 | [ "$FAIL_FAST" = true ] && exit 1 34 | 35 | ALL_GREEN=false 36 | echo 37 | } 38 | 39 | test_exact () { 40 | assertion="$1" 41 | command="$2" 42 | expected_output="$3" 43 | expected_exit_code="$4" 44 | 45 | actual_output="$($command 2>&1)" 46 | actual_exit_code="$?" 47 | 48 | [ "$actual_output" = "$expected_output" ] && [ "$actual_exit_code" = "$expected_exit_code" ] && return 49 | 50 | echo '---ASSERTION---' 51 | printf '"%s"\n' "$assertion" 52 | echo '---COMMAND---' 53 | printf '"%s"\n' "$command" 54 | echo '---EXPECTED OUTPUT---' 55 | printf '"%s"\n' "$expected_output" 56 | echo '---ACTUAL OUTPUT---' 57 | printf '"%s"\n' "$actual_output" 58 | echo '---EXPECTED EXIT CODE---' 59 | printf '"%s"\n' "$expected_exit_code" 60 | echo '---ACTUAL EXIT CODE---' 61 | printf '"%s"\n' "$actual_exit_code" 62 | fail 63 | } 64 | 65 | test_pattern () { 66 | assertion="$1" 67 | command="$2" 68 | expected_output_pattern="$3" 69 | expected_exit_code="$4" 70 | 71 | actual_output="$($command 2>&1)" 72 | actual_exit_code="$?" 73 | 74 | # shellcheck disable=SC2254 75 | case "$actual_output" in 76 | $expected_output_pattern) 77 | [ "$actual_exit_code" = "$expected_exit_code" ] && return 78 | ;; 79 | *) 80 | esac 81 | 82 | echo '---ASSERTION---' 83 | printf '"%s"\n' "$assertion" 84 | echo '---COMMAND---' 85 | printf '"%s"\n' "$command" 86 | echo '---EXPECTED OUTPUT PATTERN---' 87 | printf '"%s"\n' "$expected_output_pattern" 88 | echo '---ACTUAL OUTPUT---' 89 | printf '"%s"\n' "$actual_output" 90 | echo '---EXPECTED EXIT CODE---' 91 | printf '"%s"\n' "$expected_exit_code" 92 | echo '---ACTUAL EXIT CODE---' 93 | printf '"%s"\n' "$actual_exit_code" 94 | fail 95 | } 96 | 97 | # ---Tests--- 98 | # Test 1 99 | assertion='Error when too few arguments are passed' 100 | command="$PATH0X0 file" 101 | expected_output="$USAGE" 102 | expected_exit_code=1 103 | 104 | test_exact "$assertion" "$command" "$expected_output" "$expected_exit_code" 105 | 106 | unset assertion 107 | unset command 108 | unset expected_output 109 | unset expected_exit_code 110 | 111 | # Test 2 112 | assertion='Error when too many arguments are passed' 113 | command="$PATH0X0 file file1 file2" 114 | expected_output="$USAGE" 115 | expected_exit_code=1 116 | 117 | test_exact "$assertion" "$command" "$expected_output" "$expected_exit_code" 118 | 119 | unset assertion 120 | unset command 121 | unset expected_output 122 | unset expected_exit_code 123 | 124 | # Test 3 125 | # HACK I was not able to escape the command properly, so the test helpers cannot be used 126 | assertion='File is uploaded from stdin' 127 | expected_output_pattern='https://0x0.st/*.txt' 128 | expected_exit_code=0 129 | actual_output="$(echo "I want to share this with my friends on irc" | $PATH0X0 file - 2>&1)" 130 | actual_exit_code="$?" 131 | 132 | local_fail() { 133 | echo '---ASSERTION---' 134 | printf '"%s"\n' "$assertion" 135 | echo '---COMMAND---' 136 | printf '"%s"\n' "echo "I want to share this with my friends on irc" | $PATH0X0 file -" 137 | echo '---EXPECTED OUTPUT PATTERN---' 138 | printf '"%s"\n' "$expected_output_pattern" 139 | echo '---ACTUAL OUTPUT---' 140 | printf '"%s"\n' "$actual_output" 141 | echo '---EXPECTED EXIT CODE---' 142 | printf '"%s"\n' "$expected_exit_code" 143 | echo '---ACTUAL EXIT CODE---' 144 | printf '"%s"\n' "$actual_exit_code" 145 | fail 146 | } 147 | 148 | # shellcheck disable=SC2254 149 | case "$actual_output" in 150 | $expected_output_pattern) 151 | [ "$actual_exit_code" != "$expected_exit_code" ] && local_fail 152 | ;; 153 | *) 154 | local_fail 155 | esac 156 | 157 | unset assertion 158 | unset expected_output_pattern 159 | unset expected_exit_code 160 | unset actual_output 161 | unset actual_exit_code 162 | 163 | # Test 4 164 | assertion='File is uploaded from disk' 165 | file_name='/tmp/0x0.temp' 166 | command="$PATH0X0 file $file_name" 167 | expected_output_pattern='https://0x0.st/*.temp' 168 | expected_exit_code=0 169 | 170 | echo '#!/bin/sh' >> "$file_name" 171 | echo 'echo hello, world' >> "$file_name" 172 | 173 | test_pattern "$assertion" "$command" "$expected_output_pattern" "$expected_exit_code" 174 | 175 | rm "$file_name" 176 | 177 | unset assertion 178 | unset file_name 179 | unset command 180 | unset expected_output_pattern 181 | unset expected_exit_code 182 | 183 | # Test 5 184 | assertion='File is uploaded from URL' 185 | command="$PATH0X0 url https://fossegr.im" 186 | expected_output_pattern='https://0x0.st/*.html' 187 | expected_exit_code=0 188 | 189 | test_pattern "$assertion" "$command" "$expected_output_pattern" "$expected_exit_code" 190 | 191 | unset assertion 192 | unset command 193 | unset expected_output_pattern 194 | unset expected_exit_code 195 | 196 | # Test 6 197 | assertion='URL is shortened' 198 | command="$PATH0X0 shorten https://fossegr.im/" 199 | expected_output_pattern='https://0x0.st/*' 200 | expected_exit_code=0 201 | 202 | test_pattern "$assertion" "$command" "$expected_output_pattern" "$expected_exit_code" 203 | 204 | unset assertion 205 | unset command 206 | unset expected_output_pattern 207 | unset expected_exit_code 208 | 209 | # Test 7 210 | assertion='Error when attempt to upload non-existant file' 211 | file="/tmp/non-existant-file" 212 | command="$PATH0X0 file $file" 213 | expected_output="error: $file does not exist" 214 | expected_exit_code=1 215 | 216 | test_exact "$assertion" "$command" "$expected_output" "$expected_exit_code" 217 | 218 | unset assertion 219 | unset file 220 | unset command 221 | unset expected_output 222 | unset expected_exit_code 223 | 224 | # Test 8 225 | assertion='Directory is uploaded as a tarball' 226 | directory='/tmp/directory-to-tarball.temp' 227 | command="$PATH0X0 file $directory" 228 | expected_output_pattern='https://0x0.st/*.tar' 229 | expected_exit_code=0 230 | 231 | mkdir -p "$directory" 232 | echo 'Welcome to my tarball' > "$directory/README" 233 | echo 'lorem ipsum dolor sit amet' > "$directory/lorem" 234 | 235 | test_pattern "$assertion" "$command" "$expected_output_pattern" "$expected_exit_code" 236 | 237 | rm -rf "$directory" 238 | 239 | unset assertion 240 | unset directory 241 | unset command 242 | unset expected_output_pattern 243 | unset expected_exit_code 244 | 245 | # Test 9 246 | assertion='Error when attempt to upload url with no protocol' 247 | command="$PATH0X0 url fossegr.im" 248 | expected_output="error: invalid url" 249 | expected_exit_code=1 250 | 251 | test_exact "$assertion" "$command" "$expected_output" "$expected_exit_code" 252 | 253 | unset assertion 254 | unset command 255 | unset expected_output 256 | unset expected_exit_code 257 | 258 | # Test 10 259 | assertion='Error when attempt to upload url without domain extension' 260 | command="$PATH0X0 url https://fossegr" 261 | expected_output="error: invalid url" 262 | expected_exit_code=1 263 | 264 | test_exact "$assertion" "$command" "$expected_output" "$expected_exit_code" 265 | 266 | unset assertion 267 | unset command 268 | unset expected_output 269 | unset expected_exit_code 270 | 271 | # Test 11 272 | assertion='500 Internal Server Error when non existant, but valid url is uploaded' 273 | command="$PATH0X0 url https://non.existant.website" 274 | expected_output='error: 500 Internal Server Error' 275 | expected_exit_code=1 276 | 277 | test_exact "$assertion" "$command" "$expected_output" "$expected_exit_code" 278 | 279 | unset assertion 280 | unset command 281 | unset expected_output 282 | unset expected_exit_code 283 | 284 | # Test 12 285 | # curl -F treats commas and semicolons differently 286 | # this makes sure it is escaped properly 287 | assertion='Uploads file with semicolon and comma in filename' 288 | filename='/tmp/,dont;name,your;files,like;this,' 289 | command="$PATH0X0 file $filename" 290 | expected_output_pattern='https://0x0.st/*' 291 | expected_exit_code=0 292 | 293 | echo 'Bad file name' > "$filename" 294 | 295 | test_pattern "$assertion" "$command" "$expected_output_pattern" "$expected_exit_code" 296 | 297 | rm "$filename" 298 | 299 | unset assertion 300 | unset filename 301 | unset command 302 | unset expected_output_pattern 303 | unset expected_exit_code 304 | 305 | # Test 13 306 | assertion='Usage is printed when invoked with no arguments' 307 | command="$PATH0X0" 308 | expected_output="$USAGE" 309 | expected_exit_code=1 310 | 311 | test_exact "$assertion" "$command" "$expected_output" "$expected_exit_code" 312 | 313 | unset assertion 314 | unset command 315 | unset expected_output 316 | unset expected_exit_code 317 | 318 | # Test 14 319 | assertion='Print curl commands when -v option is passed' 320 | filename='/tmp/0x0.temp' 321 | command="$PATH0X0 file -v $filename" 322 | expected_output_pattern="curl -Ss -w status_code=%{http_code} https://0x0.st \"-Ffile=@\"$filename\"\" 323 | https://0x0.st/*.temp" 324 | expected_exit_code=0 325 | 326 | echo "random file content" > "$filename" 327 | 328 | test_pattern "$assertion" "$command" "$expected_output_pattern" "$expected_exit_code" 329 | 330 | rm "$filename" 331 | 332 | unset assertion 333 | unset filename 334 | unset command 335 | unset expected_output_pattern 336 | unset expected_exit_code 337 | 338 | # Test 15 339 | assertion='Print tar and curl commands when -v option is passed' 340 | directory='/tmp/directory-to-tarball.temp' 341 | command="$PATH0X0 file -v $directory" 342 | expected_output_pattern="tar cf - \"/tmp/directory-to-tarball.temp\" 343 | curl -Ss -w status_code=%{http_code} https://0x0.st \"-Ffile=@\"-\"\" 344 | https://0x0.st/*.tar" 345 | expected_exit_code=0 346 | 347 | mkdir -p "$directory" 348 | echo 'Welcome to my tarball' > "$directory/README" 349 | echo 'lorem ipsum dolor sit amet' > "$directory/lorem" 350 | 351 | test_pattern "$assertion" "$command" "$expected_output_pattern" "$expected_exit_code" 352 | 353 | rm -rf "$directory" 354 | 355 | unset assertion 356 | unset directory 357 | unset command 358 | unset expected_output_pattern 359 | unset expected_exit_code 360 | 361 | # Test 16 362 | assertion='Print curl commands when -v option is passed but should not execute curl commands when -n is passed' 363 | filename='/tmp/0x0.temp' 364 | command="$PATH0X0 file -v -n $filename" 365 | expected_output_pattern="curl -Ss -w status_code=%{http_code} https://0x0.st \"-Ffile=@\"$filename\"\"" 366 | expected_exit_code=0 367 | 368 | echo "garbage content" >> "$filename" 369 | 370 | test_pattern "$assertion" "$command" "$expected_output_pattern" "$expected_exit_code" 371 | 372 | unset assertion 373 | unset filename 374 | unset command 375 | unset expected_output_pattern 376 | unset expected_exit_code 377 | 378 | # Test 17 379 | assertion='Print tar and curl commands when -v option is passed but should not execute tar or curl commands when -n is passed' 380 | directory='/tmp/directory-to-tarball.temp' 381 | command="$PATH0X0 file -v -n $directory" 382 | expected_output_pattern="tar cf - \"/tmp/directory-to-tarball.temp\" 383 | curl -Ss -w status_code=%{http_code} https://0x0.st \"-Ffile=@\"-\"\"" 384 | expected_exit_code=0 385 | 386 | mkdir -p "$directory" 387 | echo 'Welcome to my tarball' > "$directory/README" 388 | echo 'lorem ipsum dolor sit amet' > "$directory/lorem" 389 | 390 | test_pattern "$assertion" "$command" "$expected_output_pattern" "$expected_exit_code" 391 | 392 | rm -rf "$directory" 393 | 394 | unset assertion 395 | unset directory 396 | unset command 397 | unset expected_output_pattern 398 | unset expected_exit_code 399 | 400 | # Test 18 401 | assertion="Uploads file with flag-like filename provided it is preceded by --" 402 | command="$PATH0X0 file -- -a" 403 | expected_output_pattern='https://0x0.st/*.txt' 404 | expected_exit_code=0 405 | 406 | echo 'testy test' > /tmp/-a 407 | cd /tmp 408 | 409 | test_pattern "$assertion" "$command" "$expected_output_pattern" "$expected_exit_code" 410 | 411 | rm /tmp/-a 412 | 413 | unset assertion 414 | unset command 415 | unset expected_output_pattern 416 | unset expected_exit_code 417 | 418 | # Test 19 419 | assertion="Fails on invalid flags" 420 | command="$PATH0X0 file -x file-that-im-too-lazy-to-create-it-should-not-matter-for-this-test-anyhow" 421 | expected_output="$USAGE" 422 | expected_exit_code=1 423 | 424 | test_exact "$assertion" "$command" "$expected_output" "$expected_exit_code" 425 | 426 | unset assertion 427 | unset command 428 | unset expected_output_pattern 429 | unset expected_exit_code 430 | 431 | # ---Report--- 432 | if [ "$ALL_GREEN" = true ]; then 433 | echo 'All tests passed' 434 | fi 435 | -------------------------------------------------------------------------------- /doc/0x0.1: -------------------------------------------------------------------------------- 1 | .\" 2 | .\" Copyright (c) 2020 Olav Fosse 3 | .\" 4 | .\" Permission to use, copy, modify, and distribute this software for any 5 | .\" purpose with or without fee is hereby granted, provided that the above 6 | .\" copyright notice and this permission notice appear in all copies. 7 | .\" 8 | .\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | .\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | .\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | .\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | .\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | .\" 16 | .Dd October 15, 2021 17 | .Dt 0X0 1 18 | .Os 19 | .Sh NAME 20 | .Nm 0x0 21 | .Nd interface with 22 | .Lk https://0x0.st 23 | .Sh SYNOPSIS 24 | .Nm 0x0 Cm file Oo Fl nv Oc Ar filename 25 | .Nm 0x0 Cm shorten Oo Fl nv Oc Ar URL 26 | .Nm 0x0 Cm url Oo Fl nv Oc Ar URL 27 | .Sh DESCRIPTION 28 | The 29 | .Nm 30 | utility is an interface to the 31 | .Lk https://0x0.st 32 | file hosting and URL shortening service. 33 | .Pp 34 | The command modifiers are as follows. 35 | .Bl -tag -width Ds 36 | .It Cm file Ar filename 37 | Upload the local file 38 | .Ar filename Ns \&. 39 | If 40 | .Ar filename 41 | is a directory, a tarball of the directory is uploaded. 42 | If 43 | .Ar filename 44 | is -, stdin is uploaded. 45 | .It Cm shorten Ar URL 46 | Shorten 47 | .Ar URL , 48 | i.e return a short URL that redirects to 49 | .Ar URL 50 | when opened. 51 | Supported protocols are http and https. 52 | .It Cm url Ar URL 53 | Upload the remote file at 54 | .Ar URL . 55 | Supported protocols are http and https. 56 | .El 57 | .Pp 58 | The options are as follows: 59 | .Bl -tag -width Ds 60 | .It Fl n 61 | Do not execute the 62 | .Xr curl 1 63 | or 64 | .Xr tar 1 65 | commands. 66 | .It Fl v 67 | Output the 68 | .Xr curl 1 69 | and 70 | .Xr tar 1 71 | commands that are executed, or would be if 72 | .Fl n 73 | was not passed. 74 | .El 75 | .Sh ENVIRONMENT 76 | .\" The reason we do not call the variable 0X0INSTANCE is that it is illegal to use 0 in a variable 77 | .Bl -tag -width NULLPOINTERINSTANCE 78 | .It Ev NULLPOINTERINSTANCE 79 | Any non-empty value of the environment variable 80 | .Ev NULLPOINTERINSTANCE 81 | is used instead of the standard 0x0 instance 82 | .Lk https://0x0.st . 83 | See the 84 | .Sx INSTANCES 85 | section for a list of known working instances. 86 | .El 87 | .Sh INSTANCES 88 | .Lk https://0x0.st , 89 | .Lk https://ttm.sh 90 | .Sh EXIT STATUS 91 | .Ex -std 0x0 92 | .Sh EXAMPLES 93 | Upload the source code of 94 | .Bd -literal -offset indent 95 | $ 0x0 file "$(which 0x0)" 96 | .Lk https://0x0.st/iU8B.bin 97 | .Ed 98 | .Pp 99 | Output the 100 | .Xr curl 1 101 | command 102 | .Nm 103 | uses in the previous example without executing it: 104 | .Bd -literal -offset indent 105 | $ 0x0 file -nv "$(which 0x0)" 106 | curl -Ss -w status_code=%{http_code} https://0x0.st "-Ffile=@"/usr/local/bin/0x0"" 107 | .Ed 108 | .Pp 109 | Upload a diff: 110 | .Bd -literal -offset indent 111 | $ diff old new | 0x0 file - 112 | .Lk https://0x0.st/iU8L.txt 113 | .Ed 114 | .Pp 115 | Shorten a URL: 116 | .Bd -literal -offset indent 117 | $ 0x0 shorten https://why-openbsd.rocks 118 | .Lk https://0x0.st/PmsW 119 | .Ed 120 | .Pp 121 | Upload a remote file: 122 | .Bd -literal -offset indent 123 | $ 0x0 url http://www.openbsd.org/art/puffy/ppuf800X725.gif 124 | .Lk https://0x0.st/iU8n.gif 125 | .Ed 126 | .Sh SEE ALSO 127 | .Xr curl 1 , 128 | .Xr tar 1 129 | .Pp 130 | .Lk https://0x0.st , 131 | .Lk https://ttm.sh , 132 | .Lk https://github.com/olavfosse/0x0 133 | .Sh AUTHORS 134 | .An Olav Fosse Aq Mt post@olavfosse.no 135 | -------------------------------------------------------------------------------- /doc/0x0.1.pdf: -------------------------------------------------------------------------------- 1 | %PDF-1.1 2 | 1 0 obj 3 | << 4 | >> 5 | endobj 6 | 3 0 obj 7 | << 8 | /Type /Font 9 | /Subtype /Type1 10 | /Name /F0 11 | /BaseFont /Times-Roman 12 | >> 13 | endobj 14 | 4 0 obj 15 | << 16 | /Type /Font 17 | /Subtype /Type1 18 | /Name /F1 19 | /BaseFont /Times-Bold 20 | >> 21 | endobj 22 | 5 0 obj 23 | << 24 | /Type /Font 25 | /Subtype /Type1 26 | /Name /F2 27 | /BaseFont /Times-Italic 28 | >> 29 | endobj 30 | 6 0 obj 31 | << 32 | /Type /Font 33 | /Subtype /Type1 34 | /Name /F3 35 | /BaseFont /Times-BoldItalic 36 | >> 37 | endobj 38 | 7 0 obj 39 | << 40 | /Length 8 0 R 41 | >> 42 | stream 43 | BT 44 | /F1 11 Tf 45 | 68.024 702.988 Td 46 | (NAME) Tj 47 | ET 48 | BT 49 | /F1 11 Tf 50 | 81.774 687.599 Td 51 | (0x0) Tj 52 | ET 53 | /F0 11 Tf 54 | BT 55 | /F0 11 Tf 56 | 101.024 687.599 Td 57 | (-) Tj 58 | ET 59 | BT 60 | /F0 11 Tf 61 | 107.437 687.599 Td 62 | (interface) Tj 63 | ET 64 | BT 65 | /F0 11 Tf 66 | 148.665 687.599 Td 67 | (with) Tj 68 | ET 69 | /F1 11 Tf 70 | BT 71 | /F1 11 Tf 72 | 170.973 687.599 Td 73 | (https://0x0.st) Tj 74 | ET 75 | BT 76 | /F1 11 Tf 77 | 68.024 656.821 Td 78 | (SYNOPSIS) Tj 79 | ET 80 | BT 81 | /F1 11 Tf 82 | 81.774 641.432 Td 83 | (0x0) Tj 84 | ET 85 | BT 86 | /F1 11 Tf 87 | 101.024 641.432 Td 88 | (file) Tj 89 | ET 90 | BT 91 | /F1 11 Tf 92 | 118.437 641.432 Td 93 | ([-nv]) Tj 94 | ET 95 | /F2 11 Tf 96 | BT 97 | /F2 11 Tf 98 | 143.792 641.432 Td 99 | (filename) Tj 100 | ET 101 | /F1 11 Tf 102 | BT 103 | /F1 11 Tf 104 | 81.774 626.043 Td 105 | (0x0) Tj 106 | ET 107 | BT 108 | /F1 11 Tf 109 | 101.024 626.043 Td 110 | (shorten) Tj 111 | ET 112 | BT 113 | /F1 11 Tf 114 | 139.216 626.043 Td 115 | ([-nv]) Tj 116 | ET 117 | /F2 11 Tf 118 | BT 119 | /F2 11 Tf 120 | 164.571 626.043 Td 121 | (URL) Tj 122 | ET 123 | /F1 11 Tf 124 | BT 125 | /F1 11 Tf 126 | 81.774 610.654 Td 127 | (0x0) Tj 128 | ET 129 | BT 130 | /F1 11 Tf 131 | 101.024 610.654 Td 132 | (url) Tj 133 | ET 134 | BT 135 | /F1 11 Tf 136 | 117.832 610.654 Td 137 | ([-nv]) Tj 138 | ET 139 | /F2 11 Tf 140 | BT 141 | /F2 11 Tf 142 | 143.187 610.654 Td 143 | (URL) Tj 144 | ET 145 | /F1 11 Tf 146 | BT 147 | /F1 11 Tf 148 | 68.024 579.876 Td 149 | (DESCRIPTION) Tj 150 | ET 151 | /F0 11 Tf 152 | BT 153 | /F0 11 Tf 154 | 81.774 564.487 Td 155 | (The) Tj 156 | ET 157 | /F1 11 Tf 158 | BT 159 | /F1 11 Tf 160 | 101.629 564.487 Td 161 | (0x0) Tj 162 | ET 163 | /F0 11 Tf 164 | BT 165 | /F0 11 Tf 166 | 120.879 564.487 Td 167 | (utility) Tj 168 | ET 169 | BT 170 | /F0 11 Tf 171 | 149.919 564.487 Td 172 | (is) Tj 173 | ET 174 | BT 175 | /F0 11 Tf 176 | 160.006 564.487 Td 177 | (an) Tj 178 | ET 179 | BT 180 | /F0 11 Tf 181 | 173.140 564.487 Td 182 | (interface) Tj 183 | ET 184 | BT 185 | /F0 11 Tf 186 | 214.368 564.487 Td 187 | (to) Tj 188 | ET 189 | BT 190 | /F0 11 Tf 191 | 225.676 564.487 Td 192 | (the) Tj 193 | ET 194 | /F1 11 Tf 195 | BT 196 | /F1 11 Tf 197 | 241.868 564.487 Td 198 | (https://0x0.st) Tj 199 | ET 200 | /F0 11 Tf 201 | BT 202 | /F0 11 Tf 203 | 305.426 564.487 Td 204 | (file) Tj 205 | ET 206 | BT 207 | /F0 11 Tf 208 | 322.839 564.487 Td 209 | (hosting) Tj 210 | ET 211 | BT 212 | /F0 11 Tf 213 | 357.984 564.487 Td 214 | (and) Tj 215 | ET 216 | BT 217 | /F0 11 Tf 218 | 376.618 564.487 Td 219 | (URL) Tj 220 | ET 221 | BT 222 | /F0 11 Tf 223 | 401.368 564.487 Td 224 | (shortening) Tj 225 | ET 226 | BT 227 | /F0 11 Tf 228 | 450.560 564.487 Td 229 | (service.) Tj 230 | ET 231 | BT 232 | /F0 11 Tf 233 | 81.774 533.709 Td 234 | (The) Tj 235 | ET 236 | BT 237 | /F0 11 Tf 238 | 101.629 533.709 Td 239 | (command) Tj 240 | ET 241 | BT 242 | /F0 11 Tf 243 | 147.763 533.709 Td 244 | (modifiers) Tj 245 | ET 246 | BT 247 | /F0 11 Tf 248 | 192.676 533.709 Td 249 | (are) Tj 250 | ET 251 | BT 252 | /F0 11 Tf 253 | 208.857 533.709 Td 254 | (as) Tj 255 | ET 256 | BT 257 | /F0 11 Tf 258 | 220.770 533.709 Td 259 | (follows.) Tj 260 | ET 261 | /F1 11 Tf 262 | BT 263 | /F1 11 Tf 264 | 81.774 502.931 Td 265 | (file) Tj 266 | ET 267 | /F2 11 Tf 268 | BT 269 | /F2 11 Tf 270 | 99.187 502.931 Td 271 | (filename) Tj 272 | ET 273 | /F0 11 Tf 274 | BT 275 | /F0 11 Tf 276 | 120.274 487.542 Td 277 | (Upload) Tj 278 | ET 279 | BT 280 | /F0 11 Tf 281 | 155.408 487.542 Td 282 | (the) Tj 283 | ET 284 | BT 285 | /F0 11 Tf 286 | 171.600 487.542 Td 287 | (local) Tj 288 | ET 289 | BT 290 | /F0 11 Tf 291 | 195.734 487.542 Td 292 | (file) Tj 293 | ET 294 | /F2 11 Tf 295 | BT 296 | /F2 11 Tf 297 | 213.147 487.542 Td 298 | (filename) Tj 299 | ET 300 | /F0 11 Tf 301 | BT 302 | /F0 11 Tf 303 | 251.031 487.542 Td 304 | (.) Tj 305 | ET 306 | BT 307 | /F0 11 Tf 308 | 256.531 487.542 Td 309 | (If) Tj 310 | ET 311 | /F2 11 Tf 312 | BT 313 | /F2 11 Tf 314 | 266.607 487.542 Td 315 | (filename) Tj 316 | ET 317 | /F0 11 Tf 318 | BT 319 | /F0 11 Tf 320 | 307.241 487.542 Td 321 | (is) Tj 322 | ET 323 | BT 324 | /F0 11 Tf 325 | 317.328 487.542 Td 326 | (a) Tj 327 | ET 328 | BT 329 | /F0 11 Tf 330 | 324.962 487.542 Td 331 | (directory,) Tj 332 | ET 333 | BT 334 | /F0 11 Tf 335 | 370.172 487.542 Td 336 | (a) Tj 337 | ET 338 | BT 339 | /F0 11 Tf 340 | 377.806 487.542 Td 341 | (tarball) Tj 342 | ET 343 | BT 344 | /F0 11 Tf 345 | 408.661 487.542 Td 346 | (of) Tj 347 | ET 348 | BT 349 | /F0 11 Tf 350 | 420.574 487.542 Td 351 | (the) Tj 352 | ET 353 | BT 354 | /F0 11 Tf 355 | 436.766 487.542 Td 356 | (directory) Tj 357 | ET 358 | BT 359 | /F0 11 Tf 360 | 479.226 487.542 Td 361 | (is) Tj 362 | ET 363 | BT 364 | /F0 11 Tf 365 | 489.313 487.542 Td 366 | (uploaded.) Tj 367 | ET 368 | BT 369 | /F0 11 Tf 370 | 120.274 472.153 Td 371 | (If) Tj 372 | ET 373 | /F2 11 Tf 374 | BT 375 | /F2 11 Tf 376 | 130.350 472.153 Td 377 | (filename) Tj 378 | ET 379 | /F0 11 Tf 380 | BT 381 | /F0 11 Tf 382 | 170.984 472.153 Td 383 | (is) Tj 384 | ET 385 | BT 386 | /F0 11 Tf 387 | 181.071 472.153 Td 388 | (-,) Tj 389 | ET 390 | BT 391 | /F0 11 Tf 392 | 190.234 472.153 Td 393 | (stdin) Tj 394 | ET 395 | BT 396 | /F0 11 Tf 397 | 214.379 472.153 Td 398 | (is) Tj 399 | ET 400 | BT 401 | /F0 11 Tf 402 | 224.466 472.153 Td 403 | (uploaded.) Tj 404 | ET 405 | /F1 11 Tf 406 | BT 407 | /F1 11 Tf 408 | 81.774 441.375 Td 409 | (shorten) Tj 410 | ET 411 | /F2 11 Tf 412 | BT 413 | /F2 11 Tf 414 | 119.966 441.375 Td 415 | (URL) Tj 416 | ET 417 | /F0 11 Tf 418 | BT 419 | /F0 11 Tf 420 | 120.274 425.986 Td 421 | (Shorten) Tj 422 | ET 423 | /F2 11 Tf 424 | BT 425 | /F2 11 Tf 426 | 157.245 425.986 Td 427 | (URL) Tj 428 | ET 429 | /F0 11 Tf 430 | BT 431 | /F0 11 Tf 432 | 178.024 425.986 Td 433 | (,) Tj 434 | ET 435 | BT 436 | /F0 11 Tf 437 | 183.524 425.986 Td 438 | (i.e) Tj 439 | ET 440 | BT 441 | /F0 11 Tf 442 | 196.966 425.986 Td 443 | (return) Tj 444 | ET 445 | BT 446 | /F0 11 Tf 447 | 225.984 425.986 Td 448 | (a) Tj 449 | ET 450 | BT 451 | /F0 11 Tf 452 | 233.618 425.986 Td 453 | (short) Tj 454 | ET 455 | BT 456 | /F0 11 Tf 457 | 258.368 425.986 Td 458 | (URL) Tj 459 | ET 460 | BT 461 | /F0 11 Tf 462 | 283.118 425.986 Td 463 | (that) Tj 464 | ET 465 | BT 466 | /F0 11 Tf 467 | 302.368 425.986 Td 468 | (redirects) Tj 469 | ET 470 | BT 471 | /F0 11 Tf 472 | 342.991 425.986 Td 473 | (to) Tj 474 | ET 475 | /F2 11 Tf 476 | BT 477 | /F2 11 Tf 478 | 354.299 425.986 Td 479 | (URL) Tj 480 | ET 481 | /F0 11 Tf 482 | BT 483 | /F0 11 Tf 484 | 377.828 425.986 Td 485 | (when) Tj 486 | ET 487 | BT 488 | /F0 11 Tf 489 | 404.404 425.986 Td 490 | (opened.) Tj 491 | ET 492 | BT 493 | /F0 11 Tf 494 | 444.422 425.986 Td 495 | (Supported) Tj 496 | ET 497 | BT 498 | /F0 11 Tf 499 | 492.393 425.986 Td 500 | (protocols) Tj 501 | ET 502 | BT 503 | /F0 11 Tf 504 | 120.274 410.597 Td 505 | (are) Tj 506 | ET 507 | BT 508 | /F0 11 Tf 509 | 136.455 410.597 Td 510 | (http) Tj 511 | ET 512 | BT 513 | /F0 11 Tf 514 | 156.321 410.597 Td 515 | (and) Tj 516 | ET 517 | BT 518 | /F0 11 Tf 519 | 174.955 410.597 Td 520 | (https.) Tj 521 | ET 522 | /F1 11 Tf 523 | BT 524 | /F1 11 Tf 525 | 81.774 379.819 Td 526 | (url) Tj 527 | ET 528 | /F2 11 Tf 529 | BT 530 | /F2 11 Tf 531 | 98.582 379.819 Td 532 | (URL) Tj 533 | ET 534 | /F0 11 Tf 535 | BT 536 | /F0 11 Tf 537 | 120.274 364.430 Td 538 | (Upload) Tj 539 | ET 540 | BT 541 | /F0 11 Tf 542 | 155.408 364.430 Td 543 | (the) Tj 544 | ET 545 | BT 546 | /F0 11 Tf 547 | 171.600 364.430 Td 548 | (remote) Tj 549 | ET 550 | BT 551 | /F0 11 Tf 552 | 204.897 364.430 Td 553 | (file) Tj 554 | ET 555 | BT 556 | /F0 11 Tf 557 | 222.310 364.430 Td 558 | (at) Tj 559 | ET 560 | /F2 11 Tf 561 | BT 562 | /F2 11 Tf 563 | 233.002 364.430 Td 564 | (URL) Tj 565 | ET 566 | /F0 11 Tf 567 | BT 568 | /F0 11 Tf 569 | 253.781 364.430 Td 570 | (.) Tj 571 | ET 572 | BT 573 | /F0 11 Tf 574 | 262.031 364.430 Td 575 | (Supported) Tj 576 | ET 577 | BT 578 | /F0 11 Tf 579 | 310.002 364.430 Td 580 | (protocols) Tj 581 | ET 582 | BT 583 | /F0 11 Tf 584 | 353.694 364.430 Td 585 | (are) Tj 586 | ET 587 | BT 588 | /F0 11 Tf 589 | 369.875 364.430 Td 590 | (http) Tj 591 | ET 592 | BT 593 | /F0 11 Tf 594 | 389.741 364.430 Td 595 | (and) Tj 596 | ET 597 | BT 598 | /F0 11 Tf 599 | 408.375 364.430 Td 600 | (https.) Tj 601 | ET 602 | BT 603 | /F0 11 Tf 604 | 81.774 333.652 Td 605 | (The) Tj 606 | ET 607 | BT 608 | /F0 11 Tf 609 | 101.629 333.652 Td 610 | (options) Tj 611 | ET 612 | BT 613 | /F0 11 Tf 614 | 136.774 333.652 Td 615 | (are) Tj 616 | ET 617 | BT 618 | /F0 11 Tf 619 | 152.955 333.652 Td 620 | (as) Tj 621 | ET 622 | BT 623 | /F0 11 Tf 624 | 164.868 333.652 Td 625 | (follows:) Tj 626 | ET 627 | /F1 11 Tf 628 | BT 629 | /F1 11 Tf 630 | 81.774 302.874 Td 631 | (-n) Tj 632 | ET 633 | /F0 11 Tf 634 | BT 635 | /F0 11 Tf 636 | 120.890 302.874 Td 637 | (Do) Tj 638 | ET 639 | BT 640 | /F0 11 Tf 641 | 137.082 302.874 Td 642 | (not) Tj 643 | ET 644 | BT 645 | /F0 11 Tf 646 | 153.890 302.874 Td 647 | (execute) Tj 648 | ET 649 | BT 650 | /F0 11 Tf 651 | 190.234 302.874 Td 652 | (the) Tj 653 | ET 654 | BT 655 | /F0 11 Tf 656 | 206.426 302.874 Td 657 | (curl\(1\)) Tj 658 | ET 659 | BT 660 | /F0 11 Tf 661 | 239.107 302.874 Td 662 | (or) Tj 663 | ET 664 | BT 665 | /F0 11 Tf 666 | 251.020 302.874 Td 667 | (tar\(1\)) Tj 668 | ET 669 | BT 670 | /F0 11 Tf 671 | 278.201 302.874 Td 672 | (commands.) Tj 673 | ET 674 | /F1 11 Tf 675 | BT 676 | /F1 11 Tf 677 | 81.774 272.096 Td 678 | (-v) Tj 679 | ET 680 | /F0 11 Tf 681 | BT 682 | /F0 11 Tf 683 | 120.274 272.096 Td 684 | (Output) Tj 685 | ET 686 | BT 687 | /F0 11 Tf 688 | 153.582 272.096 Td 689 | (the) Tj 690 | ET 691 | BT 692 | /F0 11 Tf 693 | 169.774 272.096 Td 694 | (curl\(1\)) Tj 695 | ET 696 | BT 697 | /F0 11 Tf 698 | 202.455 272.096 Td 699 | (and) Tj 700 | ET 701 | BT 702 | /F0 11 Tf 703 | 221.089 272.096 Td 704 | (tar\(1\)) Tj 705 | ET 706 | BT 707 | /F0 11 Tf 708 | 248.270 272.096 Td 709 | (commands) Tj 710 | ET 711 | BT 712 | /F0 11 Tf 713 | 298.683 272.096 Td 714 | (that) Tj 715 | ET 716 | BT 717 | /F0 11 Tf 718 | 317.933 272.096 Td 719 | (are) Tj 720 | ET 721 | BT 722 | /F0 11 Tf 723 | 334.114 272.096 Td 724 | (executed,) Tj 725 | ET 726 | BT 727 | /F0 11 Tf 728 | 378.708 272.096 Td 729 | (or) Tj 730 | ET 731 | BT 732 | /F0 11 Tf 733 | 390.621 272.096 Td 734 | (would) Tj 735 | ET 736 | BT 737 | /F0 11 Tf 738 | 420.871 272.096 Td 739 | (be) Tj 740 | ET 741 | BT 742 | /F0 11 Tf 743 | 434.005 272.096 Td 744 | (if) Tj 745 | ET 746 | /F1 11 Tf 747 | BT 748 | /F1 11 Tf 749 | 443.476 272.096 Td 750 | (-n) Tj 751 | ET 752 | /F0 11 Tf 753 | BT 754 | /F0 11 Tf 755 | 456.005 272.096 Td 756 | (was) Tj 757 | ET 758 | BT 759 | /F0 11 Tf 760 | 475.860 272.096 Td 761 | (not) Tj 762 | ET 763 | BT 764 | /F0 11 Tf 765 | 492.668 272.096 Td 766 | (passed.) Tj 767 | ET 768 | /F1 11 Tf 769 | BT 770 | /F1 11 Tf 771 | 68.024 241.318 Td 772 | (ENVIRONMENT) Tj 773 | ET 774 | /F0 11 Tf 775 | BT 776 | /F0 11 Tf 777 | 81.774 225.929 Td 778 | (NULLPOINTERINSTANCE) Tj 779 | ET 780 | BT 781 | /F0 11 Tf 782 | 217.426 225.929 Td 783 | (Any) Tj 784 | ET 785 | BT 786 | /F0 11 Tf 787 | 239.118 225.929 Td 788 | (non-empty) Tj 789 | ET 790 | BT 791 | /F0 11 Tf 792 | 289.531 225.929 Td 793 | (value) Tj 794 | ET 795 | BT 796 | /F0 11 Tf 797 | 316.107 225.929 Td 798 | (of) Tj 799 | ET 800 | BT 801 | /F0 11 Tf 802 | 328.020 225.929 Td 803 | (the) Tj 804 | ET 805 | BT 806 | /F0 11 Tf 807 | 344.212 225.929 Td 808 | (environment) Tj 809 | ET 810 | BT 811 | /F0 11 Tf 812 | 402.567 225.929 Td 813 | (variable) Tj 814 | ET 815 | BT 816 | /F0 11 Tf 817 | 217.426 210.540 Td 818 | (NULLPOINTERINSTANCE) Tj 819 | ET 820 | BT 821 | /F0 11 Tf 822 | 350.328 210.540 Td 823 | (is) Tj 824 | ET 825 | BT 826 | /F0 11 Tf 827 | 360.415 210.540 Td 828 | (used) Tj 829 | ET 830 | BT 831 | /F0 11 Tf 832 | 383.328 210.540 Td 833 | (instead) Tj 834 | ET 835 | BT 836 | /F0 11 Tf 837 | 417.241 210.540 Td 838 | (of) Tj 839 | ET 840 | BT 841 | /F0 11 Tf 842 | 429.154 210.540 Td 843 | (the) Tj 844 | ET 845 | BT 846 | /F0 11 Tf 847 | 445.346 210.540 Td 848 | (standard) Tj 849 | ET 850 | BT 851 | /F0 11 Tf 852 | 485.364 210.540 Td 853 | (0x0) Tj 854 | ET 855 | BT 856 | /F0 11 Tf 857 | 504.614 210.540 Td 858 | (instance) Tj 859 | ET 860 | /F1 11 Tf 861 | BT 862 | /F1 11 Tf 863 | 217.426 195.151 Td 864 | (https://0x0.st) Tj 865 | ET 866 | /F0 11 Tf 867 | BT 868 | /F0 11 Tf 869 | 278.234 195.151 Td 870 | (.) Tj 871 | ET 872 | BT 873 | /F0 11 Tf 874 | 283.734 195.151 Td 875 | (See) Tj 876 | ET 877 | BT 878 | /F0 11 Tf 879 | 302.368 195.151 Td 880 | (the) Tj 881 | ET 882 | /F2 11 Tf 883 | BT 884 | /F2 11 Tf 885 | 318.560 195.151 Td 886 | (INSTANCES) Tj 887 | ET 888 | /F0 11 Tf 889 | BT 890 | /F0 11 Tf 891 | 377.542 195.151 Td 892 | (section) Tj 893 | ET 894 | BT 895 | /F0 11 Tf 896 | 411.455 195.151 Td 897 | (for) Tj 898 | ET 899 | BT 900 | /F0 11 Tf 901 | 427.031 195.151 Td 902 | (a) Tj 903 | ET 904 | BT 905 | /F0 11 Tf 906 | 434.665 195.151 Td 907 | (list) Tj 908 | ET 909 | BT 910 | /F0 11 Tf 911 | 450.868 195.151 Td 912 | (of) Tj 913 | ET 914 | BT 915 | /F0 11 Tf 916 | 462.781 195.151 Td 917 | (known) Tj 918 | ET 919 | BT 920 | /F0 11 Tf 921 | 495.473 195.151 Td 922 | (working) Tj 923 | ET 924 | BT 925 | /F0 11 Tf 926 | 217.426 179.762 Td 927 | (instances.) Tj 928 | ET 929 | /F1 11 Tf 930 | BT 931 | /F1 11 Tf 932 | 68.024 148.984 Td 933 | (INSTANCES) Tj 934 | ET 935 | BT 936 | /F1 11 Tf 937 | 81.774 133.595 Td 938 | (https://0x0.st) Tj 939 | ET 940 | /F0 11 Tf 941 | BT 942 | /F0 11 Tf 943 | 142.582 133.595 Td 944 | (,) Tj 945 | ET 946 | /F1 11 Tf 947 | BT 948 | /F1 11 Tf 949 | 148.082 133.595 Td 950 | (https://ttm.sh) Tj 951 | ET 952 | BT 953 | /F1 11 Tf 954 | 68.024 102.817 Td 955 | (EXIT) Tj 956 | ET 957 | BT 958 | /F1 11 Tf 959 | 97.669 102.817 Td 960 | (STATUS) Tj 961 | ET 962 | /F0 11 Tf 963 | BT 964 | /F0 11 Tf 965 | 68.024 739.233 Td 966 | (0X0\(1\)) Tj 967 | ET 968 | BT 969 | /F0 11 Tf 970 | 245.498 739.233 Td 971 | (General) Tj 972 | ET 973 | BT 974 | /F0 11 Tf 975 | 283.063 739.233 Td 976 | (Commands) Tj 977 | ET 978 | BT 979 | /F0 11 Tf 980 | 335.929 739.233 Td 981 | (Manual) Tj 982 | ET 983 | BT 984 | /F0 11 Tf 985 | 512.490 739.233 Td 986 | (0X0\(1\)) Tj 987 | ET 988 | BT 989 | /F0 11 Tf 990 | 68.024 36.245 Td 991 | (Debian) Tj 992 | ET 993 | BT 994 | /F0 11 Tf 995 | 269.170 36.245 Td 996 | (October) Tj 997 | ET 998 | BT 999 | /F0 11 Tf 1000 | 307.351 36.245 Td 1001 | (15,) Tj 1002 | ET 1003 | BT 1004 | /F0 11 Tf 1005 | 323.851 36.245 Td 1006 | (2021) Tj 1007 | ET 1008 | BT 1009 | /F0 11 Tf 1010 | 512.490 36.245 Td 1011 | (Debian) Tj 1012 | ET 1013 | endstream 1014 | endobj 1015 | 8 0 obj 1016 | 8980 1017 | endobj 1018 | 9 0 obj 1019 | << 1020 | /ProcSet [/PDF /Text] 1021 | /Font << 1022 | /F0 3 0 R 1023 | /F1 4 0 R 1024 | /F2 5 0 R 1025 | /F3 6 0 R 1026 | >> 1027 | >> 1028 | endobj 1029 | 10 0 obj 1030 | << 1031 | /Type /Page 1032 | /Parent 2 0 R 1033 | /Resources 9 0 R 1034 | /Contents 7 0 R 1035 | >> 1036 | endobj 1037 | 11 0 obj 1038 | << 1039 | /Length 12 0 R 1040 | >> 1041 | stream 1042 | BT 1043 | /F0 11 Tf 1044 | 81.774 702.988 Td 1045 | (The) Tj 1046 | ET 1047 | /F1 11 Tf 1048 | BT 1049 | /F1 11 Tf 1050 | 101.629 702.988 Td 1051 | (0x0) Tj 1052 | ET 1053 | /F0 11 Tf 1054 | BT 1055 | /F0 11 Tf 1056 | 120.879 702.988 Td 1057 | (utility) Tj 1058 | ET 1059 | BT 1060 | /F0 11 Tf 1061 | 149.919 702.988 Td 1062 | (exits) Tj 1063 | ET 1064 | BT 1065 | /F0 11 Tf 1066 | 173.448 702.988 Td 1067 | (0) Tj 1068 | ET 1069 | BT 1070 | /F0 11 Tf 1071 | 181.698 702.988 Td 1072 | (on) Tj 1073 | ET 1074 | BT 1075 | /F0 11 Tf 1076 | 195.448 702.988 Td 1077 | (success,) Tj 1078 | ET 1079 | BT 1080 | /F0 11 Tf 1081 | 233.937 702.988 Td 1082 | (and) Tj 1083 | ET 1084 | BT 1085 | /F0 11 Tf 1086 | 252.571 702.988 Td 1087 | (>0) Tj 1088 | ET 1089 | BT 1090 | /F0 11 Tf 1091 | 267.025 702.988 Td 1092 | (if) Tj 1093 | ET 1094 | BT 1095 | /F0 11 Tf 1096 | 276.496 702.988 Td 1097 | (an) Tj 1098 | ET 1099 | BT 1100 | /F0 11 Tf 1101 | 289.630 702.988 Td 1102 | (error) Tj 1103 | ET 1104 | BT 1105 | /F0 11 Tf 1106 | 313.753 702.988 Td 1107 | (occurs.) Tj 1108 | ET 1109 | /F1 11 Tf 1110 | BT 1111 | /F1 11 Tf 1112 | 68.024 672.210 Td 1113 | (EXAMPLES) Tj 1114 | ET 1115 | /F0 11 Tf 1116 | BT 1117 | /F0 11 Tf 1118 | 81.774 656.821 Td 1119 | (Upload) Tj 1120 | ET 1121 | BT 1122 | /F0 11 Tf 1123 | 116.908 656.821 Td 1124 | (the) Tj 1125 | ET 1126 | BT 1127 | /F0 11 Tf 1128 | 133.100 656.821 Td 1129 | (source) Tj 1130 | ET 1131 | BT 1132 | /F0 11 Tf 1133 | 164.560 656.821 Td 1134 | (code) Tj 1135 | ET 1136 | BT 1137 | /F0 11 Tf 1138 | 188.078 656.821 Td 1139 | (of) Tj 1140 | ET 1141 | BT 1142 | /F0 11 Tf 1143 | 98.274 626.043 Td 1144 | ($) Tj 1145 | ET 1146 | BT 1147 | /F0 11 Tf 1148 | 106.524 626.043 Td 1149 | (0x0) Tj 1150 | ET 1151 | BT 1152 | /F0 11 Tf 1153 | 125.774 626.043 Td 1154 | (file) Tj 1155 | ET 1156 | BT 1157 | /F0 11 Tf 1158 | 143.187 626.043 Td 1159 | ("$\(which) Tj 1160 | ET 1161 | BT 1162 | /F0 11 Tf 1163 | 186.472 626.043 Td 1164 | (0x0\)") Tj 1165 | ET 1166 | /F1 11 Tf 1167 | BT 1168 | /F1 11 Tf 1169 | 98.274 610.654 Td 1170 | (https://0x0.st/iU8B.bin) Tj 1171 | ET 1172 | /F0 11 Tf 1173 | BT 1174 | /F0 11 Tf 1175 | 81.774 579.876 Td 1176 | (Output) Tj 1177 | ET 1178 | BT 1179 | /F0 11 Tf 1180 | 115.082 579.876 Td 1181 | (the) Tj 1182 | ET 1183 | BT 1184 | /F0 11 Tf 1185 | 131.274 579.876 Td 1186 | (curl\(1\)) Tj 1187 | ET 1188 | BT 1189 | /F0 11 Tf 1190 | 163.955 579.876 Td 1191 | (command) Tj 1192 | ET 1193 | /F1 11 Tf 1194 | BT 1195 | /F1 11 Tf 1196 | 210.089 579.876 Td 1197 | (0x0) Tj 1198 | ET 1199 | /F0 11 Tf 1200 | BT 1201 | /F0 11 Tf 1202 | 229.339 579.876 Td 1203 | (uses) Tj 1204 | ET 1205 | BT 1206 | /F0 11 Tf 1207 | 251.031 579.876 Td 1208 | (in) Tj 1209 | ET 1210 | BT 1211 | /F0 11 Tf 1212 | 262.339 579.876 Td 1213 | (the) Tj 1214 | ET 1215 | BT 1216 | /F0 11 Tf 1217 | 278.531 579.876 Td 1218 | (previous) Tj 1219 | ET 1220 | BT 1221 | /F0 11 Tf 1222 | 319.165 579.876 Td 1223 | (example) Tj 1224 | ET 1225 | BT 1226 | /F0 11 Tf 1227 | 359.183 579.876 Td 1228 | (without) Tj 1229 | ET 1230 | BT 1231 | /F0 11 Tf 1232 | 395.549 579.876 Td 1233 | (executing) Tj 1234 | ET 1235 | BT 1236 | /F0 11 Tf 1237 | 441.067 579.876 Td 1238 | (it:) Tj 1239 | ET 1240 | BT 1241 | /F0 11 Tf 1242 | 98.274 549.098 Td 1243 | ($) Tj 1244 | ET 1245 | BT 1246 | /F0 11 Tf 1247 | 106.524 549.098 Td 1248 | (0x0) Tj 1249 | ET 1250 | BT 1251 | /F0 11 Tf 1252 | 125.774 549.098 Td 1253 | (file) Tj 1254 | ET 1255 | BT 1256 | /F0 11 Tf 1257 | 143.187 549.098 Td 1258 | (-nv) Tj 1259 | ET 1260 | BT 1261 | /F0 11 Tf 1262 | 160.600 549.098 Td 1263 | ("$\(which) Tj 1264 | ET 1265 | BT 1266 | /F0 11 Tf 1267 | 203.885 549.098 Td 1268 | (0x0\)") Tj 1269 | ET 1270 | BT 1271 | /F0 11 Tf 1272 | 98.274 533.709 Td 1273 | (curl) Tj 1274 | ET 1275 | BT 1276 | /F0 11 Tf 1277 | 118.129 533.709 Td 1278 | (-Ss) Tj 1279 | ET 1280 | BT 1281 | /F0 11 Tf 1282 | 134.937 533.709 Td 1283 | (-w) Tj 1284 | ET 1285 | BT 1286 | /F0 11 Tf 1287 | 149.292 533.709 Td 1288 | (status_code=%{http_code}) Tj 1289 | ET 1290 | BT 1291 | /F0 11 Tf 1292 | 272.679 533.709 Td 1293 | (https://0x0.st) Tj 1294 | ET 1295 | BT 1296 | /F0 11 Tf 1297 | 332.585 533.709 Td 1298 | ("-Ffile=@"/usr/local/bin/0x0"") Tj 1299 | ET 1300 | BT 1301 | /F0 11 Tf 1302 | 81.774 502.931 Td 1303 | (Upload) Tj 1304 | ET 1305 | BT 1306 | /F0 11 Tf 1307 | 116.908 502.931 Td 1308 | (a) Tj 1309 | ET 1310 | BT 1311 | /F0 11 Tf 1312 | 124.542 502.931 Td 1313 | (diff:) Tj 1314 | ET 1315 | BT 1316 | /F0 11 Tf 1317 | 98.274 472.153 Td 1318 | ($) Tj 1319 | ET 1320 | BT 1321 | /F0 11 Tf 1322 | 106.524 472.153 Td 1323 | (diff) Tj 1324 | ET 1325 | BT 1326 | /F0 11 Tf 1327 | 125.158 472.153 Td 1328 | (old) Tj 1329 | ET 1330 | BT 1331 | /F0 11 Tf 1332 | 141.966 472.153 Td 1333 | (new) Tj 1334 | ET 1335 | BT 1336 | /F0 11 Tf 1337 | 163.042 472.153 Td 1338 | (|) Tj 1339 | ET 1340 | BT 1341 | /F0 11 Tf 1342 | 167.992 472.153 Td 1343 | (0x0) Tj 1344 | ET 1345 | BT 1346 | /F0 11 Tf 1347 | 187.242 472.153 Td 1348 | (file) Tj 1349 | ET 1350 | BT 1351 | /F0 11 Tf 1352 | 204.655 472.153 Td 1353 | (-) Tj 1354 | ET 1355 | /F1 11 Tf 1356 | BT 1357 | /F1 11 Tf 1358 | 98.274 456.764 Td 1359 | (https://0x0.st/iU8L.txt) Tj 1360 | ET 1361 | /F0 11 Tf 1362 | BT 1363 | /F0 11 Tf 1364 | 81.774 425.986 Td 1365 | (Shorten) Tj 1366 | ET 1367 | BT 1368 | /F0 11 Tf 1369 | 118.745 425.986 Td 1370 | (a) Tj 1371 | ET 1372 | BT 1373 | /F0 11 Tf 1374 | 126.379 425.986 Td 1375 | (URL:) Tj 1376 | ET 1377 | BT 1378 | /F0 11 Tf 1379 | 98.274 395.208 Td 1380 | ($) Tj 1381 | ET 1382 | BT 1383 | /F0 11 Tf 1384 | 106.524 395.208 Td 1385 | (0x0) Tj 1386 | ET 1387 | BT 1388 | /F0 11 Tf 1389 | 125.774 395.208 Td 1390 | (shorten) Tj 1391 | ET 1392 | BT 1393 | /F0 11 Tf 1394 | 160.908 395.208 Td 1395 | (https://why-openbsd.rocks) Tj 1396 | ET 1397 | /F1 11 Tf 1398 | BT 1399 | /F1 11 Tf 1400 | 98.274 379.819 Td 1401 | (https://0x0.st/PmsW) Tj 1402 | ET 1403 | /F0 11 Tf 1404 | BT 1405 | /F0 11 Tf 1406 | 81.774 349.041 Td 1407 | (Upload) Tj 1408 | ET 1409 | BT 1410 | /F0 11 Tf 1411 | 116.908 349.041 Td 1412 | (a) Tj 1413 | ET 1414 | BT 1415 | /F0 11 Tf 1416 | 124.542 349.041 Td 1417 | (remote) Tj 1418 | ET 1419 | BT 1420 | /F0 11 Tf 1421 | 157.839 349.041 Td 1422 | (file:) Tj 1423 | ET 1424 | BT 1425 | /F0 11 Tf 1426 | 98.274 318.263 Td 1427 | ($) Tj 1428 | ET 1429 | BT 1430 | /F0 11 Tf 1431 | 106.524 318.263 Td 1432 | (0x0) Tj 1433 | ET 1434 | BT 1435 | /F0 11 Tf 1436 | 125.774 318.263 Td 1437 | (url) Tj 1438 | ET 1439 | BT 1440 | /F0 11 Tf 1441 | 140.745 318.263 Td 1442 | (http://www.openbsd.org/art/puffy/ppuf800X725.gif) Tj 1443 | ET 1444 | /F1 11 Tf 1445 | BT 1446 | /F1 11 Tf 1447 | 98.274 302.874 Td 1448 | (https://0x0.st/iU8n.gif) Tj 1449 | ET 1450 | BT 1451 | /F1 11 Tf 1452 | 68.024 272.096 Td 1453 | (SEE) Tj 1454 | ET 1455 | BT 1456 | /F1 11 Tf 1457 | 91.564 272.096 Td 1458 | (ALSO) Tj 1459 | ET 1460 | /F0 11 Tf 1461 | BT 1462 | /F0 11 Tf 1463 | 81.774 256.707 Td 1464 | (curl\(1\),) Tj 1465 | ET 1466 | BT 1467 | /F0 11 Tf 1468 | 117.205 256.707 Td 1469 | (tar\(1\)) Tj 1470 | ET 1471 | /F1 11 Tf 1472 | BT 1473 | /F1 11 Tf 1474 | 81.774 225.929 Td 1475 | (https://0x0.st) Tj 1476 | ET 1477 | /F0 11 Tf 1478 | BT 1479 | /F0 11 Tf 1480 | 142.582 225.929 Td 1481 | (,) Tj 1482 | ET 1483 | /F1 11 Tf 1484 | BT 1485 | /F1 11 Tf 1486 | 148.082 225.929 Td 1487 | (https://ttm.sh) Tj 1488 | ET 1489 | /F0 11 Tf 1490 | BT 1491 | /F0 11 Tf 1492 | 211.332 225.929 Td 1493 | (,) Tj 1494 | ET 1495 | /F1 11 Tf 1496 | BT 1497 | /F1 11 Tf 1498 | 216.832 225.929 Td 1499 | (https://github.com/olavfosse/0x0) Tj 1500 | ET 1501 | BT 1502 | /F1 11 Tf 1503 | 68.024 195.151 Td 1504 | (AUTHORS) Tj 1505 | ET 1506 | /F0 11 Tf 1507 | BT 1508 | /F0 11 Tf 1509 | 81.774 179.762 Td 1510 | (Olav) Tj 1511 | ET 1512 | BT 1513 | /F0 11 Tf 1514 | 105.908 179.762 Td 1515 | (Fosse) Tj 1516 | ET 1517 | BT 1518 | /F0 11 Tf 1519 | 133.716 179.762 Td 1520 | (<) Tj 1521 | ET 1522 | /F2 11 Tf 1523 | BT 1524 | /F2 11 Tf 1525 | 139.920 179.762 Td 1526 | (post@olavfosse.no) Tj 1527 | ET 1528 | /F0 11 Tf 1529 | BT 1530 | /F0 11 Tf 1531 | 223.069 179.762 Td 1532 | (>) Tj 1533 | ET 1534 | /F0 11 Tf 1535 | BT 1536 | /F0 11 Tf 1537 | 68.024 739.233 Td 1538 | (0X0\(1\)) Tj 1539 | ET 1540 | BT 1541 | /F0 11 Tf 1542 | 245.498 739.233 Td 1543 | (General) Tj 1544 | ET 1545 | BT 1546 | /F0 11 Tf 1547 | 283.063 739.233 Td 1548 | (Commands) Tj 1549 | ET 1550 | BT 1551 | /F0 11 Tf 1552 | 335.929 739.233 Td 1553 | (Manual) Tj 1554 | ET 1555 | BT 1556 | /F0 11 Tf 1557 | 512.490 739.233 Td 1558 | (0X0\(1\)) Tj 1559 | ET 1560 | BT 1561 | /F0 11 Tf 1562 | 68.024 36.245 Td 1563 | (Debian) Tj 1564 | ET 1565 | BT 1566 | /F0 11 Tf 1567 | 269.170 36.245 Td 1568 | (October) Tj 1569 | ET 1570 | BT 1571 | /F0 11 Tf 1572 | 307.351 36.245 Td 1573 | (15,) Tj 1574 | ET 1575 | BT 1576 | /F0 11 Tf 1577 | 323.851 36.245 Td 1578 | (2021) Tj 1579 | ET 1580 | BT 1581 | /F0 11 Tf 1582 | 512.490 36.245 Td 1583 | (Debian) Tj 1584 | ET 1585 | endstream 1586 | endobj 1587 | 12 0 obj 1588 | 5166 1589 | endobj 1590 | 13 0 obj 1591 | << 1592 | /ProcSet [/PDF /Text] 1593 | /Font << 1594 | /F0 3 0 R 1595 | /F1 4 0 R 1596 | /F2 5 0 R 1597 | /F3 6 0 R 1598 | >> 1599 | >> 1600 | endobj 1601 | 14 0 obj 1602 | << 1603 | /Type /Page 1604 | /Parent 2 0 R 1605 | /Resources 13 0 R 1606 | /Contents 11 0 R 1607 | >> 1608 | endobj 1609 | 2 0 obj 1610 | << 1611 | /Type /Pages 1612 | /MediaBox [0 0 612 790] 1613 | /Count 2 1614 | /Kids [ 10 0 R 14 0 R] 1615 | >> 1616 | endobj 1617 | 15 0 obj 1618 | << 1619 | /Type /Catalog 1620 | /Pages 2 0 R 1621 | >> 1622 | endobj 1623 | xref 1624 | 0 16 1625 | 0000000000 65535 f 1626 | 0000000009 00000 n 1627 | 0000015011 00000 n 1628 | 0000000030 00000 n 1629 | 0000000112 00000 n 1630 | 0000000193 00000 n 1631 | 0000000276 00000 n 1632 | 0000000363 00000 n 1633 | 0000009395 00000 n 1634 | 0000009415 00000 n 1635 | 0000009510 00000 n 1636 | 0000009591 00000 n 1637 | 0000014811 00000 n 1638 | 0000014832 00000 n 1639 | 0000014928 00000 n 1640 | 0000015101 00000 n 1641 | trailer 1642 | << 1643 | /Size 16 1644 | /Root 15 0 R 1645 | /Info 1 0 R 1646 | >> 1647 | startxref 1648 | 15151 1649 | %%EOF 1650 | -------------------------------------------------------------------------------- /src/0x0: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright (c) 2020 Olav Fosse 4 | # 5 | # Permission to use, copy, modify, and distribute this software for any purpose 6 | # with or without fee is hereby granted, provided that the above copyright 7 | # notice and this permission notice appear in all copies. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 10 | # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 | # AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 12 | # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 | # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 14 | # OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 | # PERFORMANCE OF THIS SOFTWARE. 16 | # 17 | 18 | # ---Constants--- 19 | USAGE="$(cat << EOF 20 | usage: 0x0 file [-nv] filename 21 | 0x0 shorten [-nv] URL 22 | 0x0 url [-nv] URL 23 | EOF 24 | )" 25 | 26 | # ---Helpers--- 27 | instance() { 28 | if [ -n "$NULLPOINTERINSTANCE" ]; then 29 | echo "$NULLPOINTERINSTANCE" 30 | else 31 | echo "https://0x0.st" 32 | fi 33 | } 34 | 35 | is_valid_url() { 36 | url="$1" 37 | 38 | case "$url" in 39 | http://*.* | https://*.* ) 40 | ;; 41 | * ) 42 | return 1 43 | esac 44 | } 45 | 46 | exit_with_error() { 47 | message="$1" 48 | 49 | printf '%s\n' "$message" 1>&2 50 | exit 1 51 | } 52 | 53 | get_full_status_code() { 54 | numeral_status_code="$1" 55 | 56 | case "$numeral_status_code" in 57 | 400) 58 | printf '400 Bad Request' 59 | ;; 60 | 403) 61 | printf '403 Forbidden' 62 | ;; 63 | 500) 64 | printf '500 Internal Server Error' 65 | ;; 66 | *) 67 | # Fallback to numeral status code 68 | printf '%s' "$1" 69 | esac 70 | } 71 | 72 | form_string() { 73 | # Returns properly escaped form string. See curl(1) 74 | type="$1" # file/url/shorten 75 | file_or_url="$2" 76 | 77 | # shellcheck disable=SC2039 78 | if [ "$type" = file ]; then 79 | printf -- '-Ffile=@"%s"' "$file_or_url" 80 | else 81 | printf -- '-F%s="%s"' "$type" "$file_or_url" 82 | fi 83 | } 84 | 85 | request() { 86 | type="$1" 87 | file_or_url="$2" 88 | execute="$3" 89 | verbose="$4" 90 | 91 | form_string="$(form_string "$type" "$file_or_url")" 92 | 93 | # NB: The command is repeated two places. 94 | # This is bad, but I couldn't get it to print and run correctly at the same time when putting it in a variable. 95 | if "$verbose"; then 96 | echo curl -Ss -w status_code=%{http_code} \"$(instance)\" \"$form_string\" 97 | fi 98 | if "$execute"; then 99 | output="$(curl -Ss -w status_code=%{http_code} "$(instance)" "$form_string")" || exit 1 100 | code="$(echo "$output" | tail -n 1 | sed s/status_code=//g)" 101 | response="$(echo "$output" | grep -vE 'status_code=.*')" # Remove status_code line 102 | 103 | case "$code" in 104 | 4** | 5**) 105 | exit_with_error "error: $(get_full_status_code "$code")" 106 | ;; 107 | *) 108 | echo "$response" 109 | esac 110 | fi 111 | } 112 | 113 | # ---Dispatch handlers--- 114 | dispatch_file() { 115 | file="$1" 116 | execute="$2" 117 | verbose="$3" 118 | 119 | if [ "$file" = - ]; then 120 | request file - "$execute" "$verbose" 121 | elif [ -d "$file" ]; then 122 | # NB: The command is repeated two places. 123 | # This is bad, but I couldn't get it to print and run correctly at the same time when putting it in a variable. 124 | if "$verbose"; then 125 | echo tar cf - \"$file\" 126 | fi 127 | if "$execute"; then 128 | # stderr is redirected to /dev/null to prevent the following from being displayed 129 | # tar: Removing leading / from absolute path names in the archive 130 | tar cf - "$file" 2> /dev/null | request file - "$execute" "$verbose" || exit_with_error 'error: tar archival failed' 131 | else 132 | # NB: This branch is not redundant. 133 | # it is required because although we will not execute the command, we may still print it in case $verbose is true 134 | request file - "$execute" "$verbose" 135 | fi 136 | elif [ -e "$file" ]; then 137 | request file "$file" "$execute" "$verbose" 138 | else 139 | exit_with_error "error: $file does not exist" 140 | fi 141 | } 142 | 143 | dispatch_url() { 144 | url="$1" 145 | execute="$2" 146 | verbose="$3" 147 | 148 | is_valid_url "$url" || exit_with_error 'error: invalid url' 149 | 150 | request url "$url" "$execute" "$verbose" 151 | } 152 | 153 | dispatch_shorten() { 154 | url="$1" 155 | execute="$2" 156 | verbose="$3" 157 | 158 | is_valid_url "$url" || exit_with_error 'error: invalid url' 159 | 160 | request shorten "$url" "$execute" "$verbose" 161 | } 162 | 163 | # ---Dispatcher--- 164 | dispatch() { 165 | command_modifier="$1" 166 | 167 | # shift fails if there are no arguments to shift. 168 | [ "$#" = 0 ] && exit_with_error "$USAGE" 169 | shift 170 | 171 | execute=true 172 | verbose=false 173 | while getopts ":nv" flag; do 174 | case "$flag" in 175 | n) execute=false;; 176 | v) verbose=true;; 177 | ?) exit_with_error "$USAGE" 178 | esac 179 | done 180 | 181 | # Shift away the processed options 182 | shift $((OPTIND-1)) 183 | 184 | # Only continue if exactly one file or url is passed 185 | [ "$#" -eq 1 ] || exit_with_error "$USAGE" 186 | file_or_url="$1" 187 | 188 | case "$command_modifier" in 189 | file) 190 | dispatch_file "$file_or_url" "$execute" "$verbose" 191 | ;; 192 | url) 193 | dispatch_url "$file_or_url" "$execute" "$verbose" 194 | ;; 195 | shorten) 196 | dispatch_shorten "$file_or_url" "$execute" "$verbose" 197 | ;; 198 | *) 199 | exit_with_error "$USAGE" 200 | esac 201 | } 202 | 203 | # ---Entry point--- 204 | dispatch "$@" 205 | --------------------------------------------------------------------------------