├── .github └── workflows │ └── run_test.yml ├── LICENSE ├── _wgetpaste ├── test ├── red.txt ├── red_no_ansi.txt ├── test.sh ├── test.txt └── test_ansi.sh ├── wgetpaste └── wgetpaste.spec /.github/workflows/run_test.yml: -------------------------------------------------------------------------------- 1 | name: 'wgetpaste test runner' 2 | on: [pull_request, push] 3 | jobs: 4 | run-test: 5 | name: 'Run test/test.sh' 6 | runs-on: ubuntu-latest 7 | steps: 8 | - uses: actions/checkout@v3 9 | - run: test/test.sh 10 | shell: bash 11 | run-test-ansi: 12 | name: 'Run test/test_ansi.sh' 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v3 16 | - name: 'Install ansifilter' 17 | run: | 18 | sudo apt-get update 19 | sudo apt-get install ansifilter 20 | - run: test/test_ansi.sh 21 | shell: bash 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2007-2016 Bo Ørsted Andresen 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /_wgetpaste: -------------------------------------------------------------------------------- 1 | #compdef wgetpaste 2 | 3 | # vim: set et sw=2 sts=2 ts=2 ft=zsh : 4 | # ZSH completion for `wgetpaste`, http://wgetpaste.zlin.dk 5 | # Written by Ingmar Vanhassel 6 | 7 | 8 | (( ${+functions[_wgetpaste_services]} )) || 9 | _wgetpaste_services() 10 | { 11 | local -a _services 12 | _services=( $(_call_program service wgetpaste --list-services --completions --verbose 2>/dev/null) ) 13 | _describe -t service 'what service should be used' \ 14 | _services 15 | } 16 | 17 | (( ${+functions[_wgetpaste_languages]} )) || 18 | _wgetpaste_languages() 19 | { 20 | local -a _languages 21 | _languages=( ${(f)"$(_call_program language wgetpaste --list-languages --completions 2>/dev/null)"} ) 22 | _describe -t language 'what language to post as' \ 23 | _languages 24 | } 25 | 26 | (( ${+functions[_wgetpaste_expiration]} )) || 27 | _wgetpaste_expiration() 28 | { 29 | local -a _expiration 30 | _expiration=( ${(f)"$(_call_program expiration wgetpaste --list-expiration --completions 2>/dev/null)"} ) 31 | _describe -t expiration 'when should your paste expire' \ 32 | _expiration 33 | } 34 | 35 | _arguments -s : \ 36 | '(--language -l)'{--language,-l}'[set language]:language:_wgetpaste_languages' \ 37 | '(--description -d)'{--description,-d}'[set description]:description: ' \ 38 | '(--nick -n)'{--nick,-n}'[set nick]:nick:_users' \ 39 | '(--service -s)'{--service,-s}'[set service to use]:service:_wgetpaste_services' \ 40 | '(--expiration -e)'{--expiration,-e}'[set when your paste should expire]:expiration:_wgetpaste_expiration' \ 41 | '(--list-services -S)'{--list-services,-S}'[list supported pastebin services]' \ 42 | '(--list-languages -L)'{--list-languages,-L}'[list languages supported by the specified service]' \ 43 | '(--list-expiration -E)'{--list-expiration,-E}'[list expiration setting supported by the specified service]' \ 44 | '(--tinyurl -u)'{--tinyurl,-u}'[convert input url to tinyurl]:url:_urls' \ 45 | '(--command -c)'{--command,-c}'[paste a command and its output]:command:_command' \ 46 | '(--info -i)'{--info,-i}'[append the output of `emerge --info`]' \ 47 | '(--info-only -I)'{--info-only,-I}'[paste the output of `emerge --info` only]' \ 48 | '(--xcut -x)'{--xcut,-x}'[read input from clipboard]' \ 49 | '(--xpaste -X)'{--xpaste,-X}'[write resulting url to the X primary selection buffer]' \ 50 | '(--xclippaste -C)'{--xclippaste,-C}'[write resulting url to the X clipboard selection buffer]' \ 51 | '(--raw -r)'{--raw,-r}'[show url for the raw paste]' \ 52 | '(--tee -t)'{--tee,-t}'[use tee to show what is being pasted]' \ 53 | '(--quiet -q)'{--quiet,-q}'[show the url only]' \ 54 | '(--verbose -v)'{--verbose,-v}'[show wget stderr output if no url is received]' \ 55 | '--debug[be very verbose]' \ 56 | '(--help -h)'{--help,-h}'[show help and exit]' \ 57 | '(--ignore-configs,-g)'{--ignore-configs,-g}'[ignore /etc/wgetpaste.conf, ~/.wgetpaste.conf etc]' \ 58 | '--version[show version information and exit]' \ 59 | '*:file:_files' && 60 | return 61 | 62 | -------------------------------------------------------------------------------- /test/red.txt: -------------------------------------------------------------------------------- 1 | red text 2 | -------------------------------------------------------------------------------- /test/red_no_ansi.txt: -------------------------------------------------------------------------------- 1 | red text 2 | -------------------------------------------------------------------------------- /test/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # wgetpaste test script 4 | # Exit code: number of mismatched downloads or 1 for general failure 5 | # Copyright (C) 2021-2022 Oskari Pirhonen 6 | 7 | # Don't assume the test is being run from the same directory as the script 8 | TEST_DIR="$(dirname "$0")" 9 | TEST_FILE="$TEST_DIR/test.txt" 10 | DL_DIR="$(mktemp -q --tmpdir -d wgetpaste_test.XXXXX)" 11 | # Services to hard skip 12 | # Pre-declare as map to maintain type even if empty 13 | # key -> value := service -> reason 14 | declare -A HARD_SKIPS 15 | HARD_SKIPS=(['codepad']='always times out') 16 | HARD_SKIP_COUNT=0 17 | # Services expected to require an authorization token 18 | AUTH_SKIPS=('gists' 'snippets') 19 | AUTH_SKIP_COUNT=0 20 | FAIL_SKIP_COUNT=0 21 | DL_COUNT=0 22 | DL_MISMATCH=0 23 | 24 | # Test that temp directory was created 25 | if [ ! -d "$DL_DIR" ]; then 26 | echo "Failed to create temporary download directory: $DL_DIR" 27 | exit 1 28 | fi 29 | echo "Using download directory: $DL_DIR" 30 | 31 | # Post test file into each service (if possible) 32 | # Download the resulting paste into /tmp/wgetpaste_test.XXXXX/.txt 33 | for serv in $("$TEST_DIR"/../wgetpaste -S --completions); do 34 | # Hard skips 35 | for hs in "${!HARD_SKIPS[@]}"; do 36 | if [ "$serv" == "$hs" ]; then 37 | echo "HARD SKIP on $serv -- reason: ${HARD_SKIPS[$serv]}" 38 | HARD_SKIP_COUNT=$((HARD_SKIP_COUNT + 1)) 39 | continue 2 40 | fi 41 | done 42 | 43 | # Log errors to analyze the reason 44 | # Use verbose output to get more meaningful errors 45 | # Log deleted at the end of each loop unless error other than 401 46 | echo -n "Posting to $serv: " 47 | ERROR_LOG="$DL_DIR/$serv-error.log" 48 | URL="$("$TEST_DIR"/../wgetpaste -r -s "$serv" -v "$TEST_FILE" 2>"$ERROR_LOG")" 49 | STATUS="$?" 50 | 51 | # Skip failed posts (eg, not authorized for GitHub/GitLab, service error) 52 | if [ "$STATUS" -ne 0 ]; then 53 | if (grep -iq "HTTP.*401.*Unauthorized" "$ERROR_LOG"); then 54 | # Check if a 401 is expected behavior. If it isn't, mark as fail 55 | for as in "${AUTH_SKIPS[@]}"; do 56 | if [ "$serv" == "$as" ]; then 57 | echo "SKIPPING, needs authorization..." 58 | AUTH_SKIP_COUNT=$((AUTH_SKIP_COUNT + 1)) 59 | rm "$ERROR_LOG" 60 | continue 2 61 | fi 62 | done 63 | echo "UNEXPECTED 401, skipping..." 64 | FAIL_SKIP_COUNT=$((FAIL_SKIP_COUNT + 1)) 65 | else 66 | echo "SKIPPING, failed to post..." 67 | FAIL_SKIP_COUNT=$((FAIL_SKIP_COUNT + 1)) 68 | fi 69 | 70 | continue 71 | fi 72 | echo "SUCCESS!" 73 | 74 | echo -n "Downloading from $serv: " 75 | if ! (wget -q "$URL" -O "$DL_DIR/$serv.txt" 2>>"$ERROR_LOG"); then 76 | echo "FAILED, skipping..." 77 | FAIL_SKIP_COUNT=$((FAIL_SKIP_COUNT + 1)) 78 | continue 79 | fi 80 | echo "SUCCESS!" 81 | DL_COUNT=$((DL_COUNT + 1)) 82 | rm "$ERROR_LOG" 83 | done 84 | 85 | # Test if any files were downloaded 86 | if [ "$DL_COUNT" -eq 0 ]; then 87 | echo "No files downloaded!" 88 | rm -rf "$DL_DIR" 89 | exit 1 90 | fi 91 | 92 | # Compare downloaded files 93 | for dl_file in "$DL_DIR"/*.txt; do 94 | echo -n "Testing file $dl_file: " 95 | # Ignore missing trailing newline in downloaded file 96 | if (diff -q -Z "$TEST_FILE" "$dl_file" &>/dev/null); then 97 | echo "SUCCESS!" 98 | else 99 | echo "FAILED!" 100 | DL_MISMATCH=$((DL_MISMATCH + 1)) 101 | fi 102 | done 103 | 104 | echo "Total mismatches: $DL_MISMATCH" 105 | echo "Total skips: $((HARD_SKIP_COUNT + AUTH_SKIP_COUNT + FAIL_SKIP_COUNT))" 106 | 107 | # Print non-auth failure logs 108 | if [ "$FAIL_SKIP_COUNT" -ne 0 ]; then 109 | for log in "$DL_DIR"/*.log; do 110 | echo "$(basename "$log"):" 111 | cat "$log" 112 | done 113 | fi 114 | 115 | # Delete download directory if all tests succeeded 116 | if [ "$DL_MISMATCH" -eq 0 ]; then 117 | echo "Deleting download directory" 118 | rm -rf "$DL_DIR" 119 | fi 120 | 121 | exit "$DL_MISMATCH" 122 | -------------------------------------------------------------------------------- /test/test.txt: -------------------------------------------------------------------------------- 1 | wgetpaste test data 2 | 3 | test common string escapes used in programming languages 4 | #include 5 | 6 | int main (void) { 7 | printf("test bell\a\n"); 8 | printf("test backspace\bE\n"); 9 | printf("test escape\e[31m red text\e[m end red text\n"); 10 | printf("test form feed\f"); 11 | printf("test newline\n"); 12 | printf("test carriage return\rA\n"); 13 | printf("test tab\tend tab\n"); 14 | printf("test vertical tab\vend vertical tab\n"); 15 | printf("test backslash\\\n"); 16 | printf("test single quote\'\n"); 17 | printf("test double quote\"\n"); 18 | printf("test question mark\?\n"); 19 | printf("test octal (A) \101\n"); 20 | printf("test octal (null)\n\0not printed"); 21 | printf("test hex (A) \x41\n"); 22 | printf("test unicode < 0x10000 (acute A) \u00c1\n"); 23 | printf("test unicode (acute A) \U000000c1\n"); 24 | 25 | printf("test literal tab end tab\n"); 26 | } 27 | -------------------------------------------------------------------------------- /test/test_ansi.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # wgetpaste test script (stripping ANSI codes) 4 | # Based on test/test.sh 5 | # Exit code: number of mismatched downloads or 1 for general failure 6 | # Copyright (C) 2022 Oskari Pirhonen 7 | 8 | # Don't assume the test is being run from the same directory as the script 9 | TEST_DIR="$(dirname "$0")" 10 | ANSI_FILE="$TEST_DIR/red.txt" 11 | NOANSI_FILE="$TEST_DIR/red_no_ansi.txt" 12 | DL_DIR="$(mktemp -q --tmpdir -d wgetpaste_test_ansi.XXXXX)" 13 | # Services to hard skip 14 | # Pre-declare as map to maintain type even if empty 15 | # key -> value := service -> reason 16 | declare -A HARD_SKIPS 17 | HARD_SKIPS=(['codepad']='always times out') 18 | # Services expected to require an authorization token 19 | AUTH_SKIPS=('gists' 'snippets') 20 | # Used to save the first working service 21 | WORKING= 22 | FAILED_PASTE=0 23 | DL_MISMATCH=0 24 | 25 | # Test that temp directory was created 26 | if [ ! -d "$DL_DIR" ]; then 27 | echo "Failed to create temporary download directory: $DL_DIR" 28 | exit 1 29 | fi 30 | echo "Using download directory: $DL_DIR" 31 | 32 | # Post test file into each service until one succeeds 33 | for serv in $("$TEST_DIR"/../wgetpaste -S --completions); do 34 | # Hard skips 35 | for hs in "${!HARD_SKIPS[@]}"; do 36 | if [ "$serv" == "$hs" ]; then 37 | echo "HARD SKIP on $serv -- reason: ${HARD_SKIPS[$serv]}" 38 | continue 2 39 | fi 40 | done 41 | 42 | # Log errors to analyze the reason 43 | # Use verbose output to get more meaningful errors 44 | # Log deleted at the end of each loop unless error other than 401 45 | echo -n "Posting to $serv: " 46 | ERROR_LOG="$DL_DIR/$serv-error.log" 47 | URL="$("$TEST_DIR"/../wgetpaste -r -s "$serv" -v "$ANSI_FILE" 2>"$ERROR_LOG")" 48 | STATUS="$?" 49 | 50 | # Skip failed posts (eg, not authorized for GitHub/GitLab, service error) 51 | if [ "$STATUS" -ne 0 ]; then 52 | if (grep -iq "HTTP.*401.*Unauthorized" "$ERROR_LOG"); then 53 | # Check if a 401 is expected behavior. If it isn't, mark as fail 54 | for as in "${AUTH_SKIPS[@]}"; do 55 | if [ "$serv" == "$as" ]; then 56 | echo "SKIPPING, needs authorization..." 57 | rm "$ERROR_LOG" 58 | continue 2 59 | fi 60 | done 61 | echo "UNEXPECTED 401, skipping..." 62 | else 63 | echo "SKIPPING, failed to post..." 64 | fi 65 | 66 | continue 67 | fi 68 | echo "SUCCESS!" 69 | 70 | echo -n "Downloading from $serv: " 71 | if ! (wget -q "$URL" -O "/dev/null" 2>>"$ERROR_LOG"); then 72 | echo "FAILED, skipping..." 73 | continue 74 | fi 75 | echo "SUCCESS!" 76 | rm "$ERROR_LOG" 77 | 78 | # This is the service we want to use 79 | echo "Using service $serv" 80 | WORKING="$serv" 81 | break 82 | done 83 | 84 | # Test if we have a working service 85 | if [ -z "$WORKING" ]; then 86 | echo "No working service found!" 87 | for log in "$DL_DIR"/*.log; do 88 | echo "$(basename "$log"):" 89 | cat "$log" 90 | done 91 | rm -rf "$DL_DIR" 92 | exit 1 93 | fi 94 | 95 | # Paste stuff. Use a short timeout between requests (we're friendly after all!) 96 | sleep 1 97 | echo -n "Pasting command output with ANSI stripping (cat): " 98 | ERROR_LOG="$DL_DIR/command-noansi-error.log" 99 | URL="$("$TEST_DIR"/../wgetpaste -N -r -s "$WORKING" -v -c "cat $ANSI_FILE" 2>"$ERROR_LOG")" 100 | if [ $? -ne 0 ]; then 101 | echo "FAILED!" 102 | FAILED_PASTE=$((FAILED_PASTE + 1)) 103 | else 104 | echo "SUCCESS!" 105 | 106 | echo -n "Downloading: " 107 | if ! (wget -q "$URL" -O "$DL_DIR/command-noansi.txt" 2>>"$ERROR_LOG"); then 108 | echo "FAILED!" 109 | FAILED_PASTE=$((FAILED_PASTE + 1)) 110 | else 111 | echo "SUCCESS" 112 | rm "$ERROR_LOG" 113 | 114 | echo "Removing 'command run' header" 115 | sed -i -e '1d' "$DL_DIR/command-noansi.txt" 116 | fi 117 | fi 118 | sleep 1 119 | echo -n "Pasting command output without ANSI stripping (cat): " 120 | ERROR_LOG="$DL_DIR/command-ansi-error.log" 121 | URL="$("$TEST_DIR"/../wgetpaste -A -r -s "$WORKING" -v -c "cat $ANSI_FILE" 2>"$ERROR_LOG")" 122 | if [ $? -ne 0 ]; then 123 | echo "FAILED!" 124 | FAILED_PASTE=$((FAILED_PASTE + 1)) 125 | else 126 | echo "SUCCESS!" 127 | 128 | echo -n "Downloading: " 129 | if ! (wget -q "$URL" -O "$DL_DIR/command-ansi.txt" 2>>"$ERROR_LOG"); then 130 | echo "FAILED!" 131 | FAILED_PASTE=$((FAILED_PASTE + 1)) 132 | else 133 | echo "SUCCESS" 134 | rm "$ERROR_LOG" 135 | 136 | echo "Removing 'command run' header" 137 | sed -i -e '1d' "$DL_DIR/command-ansi.txt" 138 | fi 139 | fi 140 | 141 | sleep 1 142 | echo -n "Pasting stdin with ANSI stripping (cat | wgetpaste): " 143 | ERROR_LOG="$DL_DIR/stdin-noansi-error.log" 144 | URL="$(cat "$ANSI_FILE" | "$TEST_DIR"/../wgetpaste -N -r -s "$WORKING" -v 2>"$ERROR_LOG")" 145 | if [ $? -ne 0 ]; then 146 | echo "FAILED!" 147 | FAILED_PASTE=$((FAILED_PASTE + 1)) 148 | else 149 | echo "SUCCESS!" 150 | 151 | echo -n "Downloading: " 152 | if ! (wget -q "$URL" -O "$DL_DIR/stdin-noansi.txt" 2>>"$ERROR_LOG"); then 153 | echo "FAILED!" 154 | FAILED_PASTE=$((FAILED_PASTE + 1)) 155 | else 156 | echo "SUCCESS!" 157 | rm "$ERROR_LOG" 158 | fi 159 | fi 160 | sleep 1 161 | echo -n "Pasting stdin without ANSI stripping (cat | wgetpaste): " 162 | ERROR_LOG="$DL_DIR/stdin-ansi-error.log" 163 | URL="$(cat "$ANSI_FILE" | "$TEST_DIR"/../wgetpaste -A -r -s "$WORKING" -v 2>"$ERROR_LOG")" 164 | if [ $? -ne 0 ]; then 165 | echo "FAILED!" 166 | FAILED_PASTE=$((FAILED_PASTE + 1)) 167 | else 168 | echo "SUCCESS!" 169 | 170 | echo -n "Downloading: " 171 | if ! (wget -q "$URL" -O "$DL_DIR/stdin-ansi.txt" 2>>"$ERROR_LOG"); then 172 | echo "FAILED!" 173 | FAILED_PASTE=$((FAILED_PASTE + 1)) 174 | else 175 | echo "SUCCESS!" 176 | rm "$ERROR_LOG" 177 | fi 178 | fi 179 | 180 | sleep 1 181 | echo -n "Pasting a file with ANSI stripping: " 182 | ERROR_LOG="$DL_DIR/file-noansi-error.log" 183 | URL="$("$TEST_DIR"/../wgetpaste -N -r -s "$WORKING" -v "$ANSI_FILE" 2>"$ERROR_LOG")" 184 | if [ $? -ne 0 ]; then 185 | echo "FAILED!" 186 | FAILED_PASTE=$((FAILED_PASTE + 1)) 187 | else 188 | echo "SUCCESS!" 189 | 190 | echo -n "Downloading: " 191 | if ! (wget -q "$URL" -O "$DL_DIR/file-noansi.txt" 2>>"$ERROR_LOG"); then 192 | echo "FAILED!" 193 | FAILED_PASTE=$((FAILED_PASTE + 1)) 194 | else 195 | echo "SUCCESS!" 196 | rm "$ERROR_LOG" 197 | fi 198 | fi 199 | sleep 1 200 | echo -n "Pasting a file without ANSI stripping: " 201 | ERROR_LOG="$DL_DIR/file-ansi-error.log" 202 | URL="$("$TEST_DIR"/../wgetpaste -A -r -s "$WORKING" -v "$ANSI_FILE" 2>"$ERROR_LOG")" 203 | if [ $? -ne 0 ]; then 204 | echo "FAILED!" 205 | FAILED_PASTE=$((FAILED_PASTE + 1)) 206 | else 207 | echo "SUCCESS!" 208 | 209 | echo -n "Downloading: " 210 | if ! (wget -q "$URL" -O "$DL_DIR/file-ansi.txt" 2>>"$ERROR_LOG"); then 211 | echo "FAILED!" 212 | FAILED_PASTE=$((FAILED_PASTE + 1)) 213 | else 214 | echo "SUCCESS!" 215 | rm "$ERROR_LOG" 216 | fi 217 | fi 218 | 219 | # Compare downloaded files 220 | for dl_file in "$DL_DIR"/*-noansi.txt; do 221 | echo -n "Testing file $dl_file: " 222 | # Ignore missing trailing newline and extra empty lines in downloaded file 223 | if (diff -q -Z -B "$NOANSI_FILE" "$dl_file" &>/dev/null); then 224 | echo "SUCCESS!" 225 | else 226 | echo "FAILED!" 227 | DL_MISMATCH=$((DL_MISMATCH + 1)) 228 | fi 229 | done 230 | for dl_file in "$DL_DIR"/*-ansi.txt; do 231 | echo -n "Testing file $dl_file: " 232 | # Ignore missing trailing newline and extra empty lines in downloaded file 233 | if (diff -q -Z -B "$ANSI_FILE" "$dl_file" &>/dev/null); then 234 | echo "SUCCESS!" 235 | else 236 | echo "FAILED!" 237 | DL_MISMATCH=$((DL_MISMATCH + 1)) 238 | fi 239 | done 240 | 241 | echo "Total failed pastes: $FAILED_PASTE" 242 | echo "Total mismatches: $DL_MISMATCH" 243 | 244 | # Print failure logs 245 | if [ $FAILED_PASTE -ne 0 ]; then 246 | for log in "$DL_DIR"/*.log; do 247 | echo "$(basename "$log"):" 248 | cat "$log" 249 | done 250 | # Delete download directory if all tests succeeded 251 | elif [ $DL_MISMATCH -eq 0 ]; then 252 | echo "Deleting download directory" 253 | rm -rf "$DL_DIR" 254 | fi 255 | 256 | exit "$DL_MISMATCH" 257 | -------------------------------------------------------------------------------- /wgetpaste: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # A Script that automates pasting to a number of pastebin services 3 | # relying only on bash, sed, coreutils (mktemp/sort/tr/wc/whoami/tee) and wget 4 | # Copyright (c) 2007-2016 Bo Ørsted Andresen 5 | 6 | VERSION="2.33" 7 | 8 | # don't inherit LANGUAGE from the env 9 | unset LANGUAGE 10 | 11 | # escape and new line characters 12 | E=$'\e' 13 | N=$'\n' 14 | 15 | # generic post function 16 | POST_generic() { 17 | local post nick description language expiration cvt_tabs input nr extra f 18 | post=$1 19 | nick=$2 20 | description=$3 21 | language=$4 22 | expiration=$5 23 | cvt_tabs=$6 24 | input=$7 25 | 26 | nr=${post//[^ ]} 27 | [[ 6 = ${#nr} ]] || die "\"${SERVICE}\" is not supported by POST_${SERVICE}()." 28 | extra=${post%% *} 29 | [[ '%' = $extra ]] || echo -n "$extra&" 30 | e() { 31 | post="$1" 32 | shift 33 | while [[ -n $1 ]]; do 34 | f=${post%% *} 35 | [[ '%' != $f ]] && echo -n "$f=${!1}" && [[ $# -gt 1 ]] && echo -n "&" 36 | shift 37 | post=${post#$f } 38 | done 39 | } 40 | e "${post#$extra }" nick description language expiration cvt_tabs input 41 | } 42 | 43 | ### services 44 | SERVICES="0x0 bpaste codepad dpaste gists ix_io pgz snippets" 45 | # 0x0 46 | ENGINE_0x0=0x0 47 | URL_0x0="http://0x0.st" 48 | SIZE_0x0="536870912 536%MB" 49 | # bpaste 50 | ENGINE_bpaste=pinnwand 51 | URL_bpaste="https://bpa.st/api/v1/paste" 52 | DEFAULT_EXPIRATION_bpaste="1week" 53 | DEFAULT_LANGUAGE_bpaste="text" 54 | # codepad 55 | ENGINE_codepad=codepad 56 | URL_codepad="http://codepad.org/" 57 | SIZE_codepad="64000 64%KB" 58 | # dpaste 59 | ENGINE_dpaste=dpaste 60 | URL_dpaste="http://dpaste.com/api/v2/" 61 | SIZE_dpaste="250000 250%kB" 62 | DESCRIPTION_SIZE_dpaste="50" 63 | DEFAULT_EXPIRATION_dpaste="1" 64 | # gists 65 | ENGINE_gists=gists 66 | URL_gists="https://api.github.com/gists" 67 | # ix_io 68 | ENGINE_ix_io=ix_io 69 | URL_ix_io="http://ix.io" 70 | SIZE_ix_io="1000000 1%MB" 71 | # paste.gentoo.zip 72 | ENGINE_pgz=pgz 73 | URL_pgz="https://paste.gentoo.zip" 74 | SIZE_pgz="2000000 2%MB" 75 | # snippets 76 | ENGINE_snippets=snippets 77 | URL_snippets="https://gitlab.com/api/v4/snippets" 78 | ADDITIONAL_HEADERS_snippets=("Content-Type: application/json") 79 | # sprunge 80 | ENGINE_sprunge=sprunge 81 | URL_sprunge="http://sprunge.us" 82 | SIZE_sprunge="1000000 1%MB" 83 | # tinyurl 84 | ENGINE_tinyurl=tinyurl 85 | URL_tinyurl="http://tinyurl.com/ api-create.php" 86 | REGEX_RAW_tinyurl='s|^\(http://[^/]*/\)\([[:alnum:]]*\)$|\1\2|' 87 | 88 | ### engines 89 | # 0x0 90 | escape_description_0x0() { echo "$*"; } 91 | escape_input_0x0() { echo "$*"; } 92 | POST_0x0() { 93 | local filename="${2}" 94 | local content="${6}" boundary="WGETPASTE-yuLr+iHOSQ+trEgDcj9UVq5R302bid" 95 | echo "--$boundary" 96 | echo "Content-Disposition: form-data; name=\"file\"; filename=\"${filename}\"" 97 | echo "" 98 | echo "${content}" 99 | echo "--${boundary}--" 100 | ADDITIONAL_HEADERS_0x0=("Content-Type: multipart/form-data; boundary=${boundary}") 101 | } 102 | REGEX_RAW_0x0='s|^http.*|\0|' 103 | REGEX_URL_0x0='s|^http.*|\0|p' 104 | LANGUAGES_codepad="C C++ D Haskell Lua OCaml PHP Perl Plain%Text Python Ruby Scheme Tcl" 105 | # codepad 106 | POST_codepad() { 107 | POST_generic "submit % % lang % % code" "$1" "$2" "$3" "$4" "$5" "$6" 108 | } 109 | REGEX_URL_codepad='s|^--.*\(http://codepad.org/[^ ]\+\)|\1|p' 110 | REGEX_RAW_codepad='s|^\(http://[^/]*/\)\([[:alnum:]]*\)$|\1\2/raw.rb|' 111 | # dpaste 112 | LANGUAGES_dpaste="Plain%Text Apache%Config Bash CSS Diff Django%Template/HTML Haskell JavaScript \ 113 | Python Python%Interactive/Traceback Ruby Ruby%HTML%(ERB) SQL XML" 114 | LANGUAGE_VALUES_dpaste="% Apache Bash Css Diff DjangoTemplate Haskell JScript Python PythonConsole \ 115 | Ruby Rhtml Sql Xml" 116 | EXPIRATIONS_dpaste=$(printf "%s " {1..365}) 117 | escape_description_dpaste() { echo "$*"; } 118 | escape_input_dpaste() { echo "$*"; } 119 | POST_dpaste() { 120 | local title="${2}" 121 | local syntax="${3}" 122 | local expiry_days="${4}" 123 | local content="${6}" 124 | local boundary="WGETPASTE-cK7MKXxfDNm87mXJzyX0kpKaCkiaQC" 125 | echo -e "--$boundary\r" 126 | echo -e "Content-Disposition: form-data; name=\"title\"\r" 127 | echo -e "\r" 128 | echo -e "${title}\r" 129 | echo -e "--$boundary\r" 130 | echo -e "Content-Disposition: form-data; name=\"syntax\"\r" 131 | echo -e "\r" 132 | echo -e "${syntax}\r" 133 | echo -e "--$boundary\r" 134 | echo -e "Content-Disposition: form-data; name=\"expiry_days\"\r" 135 | echo -e "\r" 136 | echo -e "${expiry_days}\r" 137 | echo -e "--$boundary\r" 138 | echo -e "Content-Disposition: form-data; name=\"content\"\r" 139 | echo -e "\r" 140 | echo -n "${content}" 141 | echo -e "\r\n--${boundary}--\r" 142 | ADDITIONAL_HEADERS_dpaste=("Content-Type: multipart/form-data; boundary=${boundary}") 143 | } 144 | REGEX_RAW_dpaste='s|^http.*|\0.txt|' 145 | REGEX_URL_dpaste='s|^http.*|\0|p' 146 | # gists 147 | LANGUAGES_gists="ActionScript Ada Apex AppleScript Arc Arduino ASP Assembly 148 | Augeas AutoHotkey Batchfile Befunge BlitzMax Boo Brainfuck Bro C C# C++ 149 | C2hs%Haskell ChucK Clojure CMake C-ObjDump CoffeeScript ColdFusion Common%Lisp 150 | Coq Cpp-ObjDump CSS Cucumber Cython D Darcs%Patch Dart DCPU-16%ASM Delphi Diff 151 | D-ObjDump Dylan eC Ecere%Projects Eiffel Elixir Emacs%Lisp Erlang F# Factor 152 | Fancy Fantom FORTRAN GAS Genshi Gentoo%Ebuild Gentoo%Eclass Gettext%Catalog Go 153 | Gosu Groff Groovy Groovy%Server%Pages Haml Haskell HaXe HTML HTML+Django 154 | HTML+ERB HTML+PHP INI Io Ioke IRC%log Java JavaScript Java%Server%Pages JSON 155 | Julia Kotlin LilyPond Literate%Haskell LLVM Logtalk Lua Makefile Mako Markdown 156 | Matlab Max/MSP MiniD Mirah Moocode mupad Myghty Nemerle Nimrod Nu NumPy ObjDump 157 | Objective-C Objective-J OCaml ooc Opa OpenCL OpenEdge%ABL Parrot Parrot%Assembly 158 | Parrot%Internal%Representation Perl PHP Plain%Text PowerShell Prolog Puppet 159 | Pure%Data Python Python%traceback R Racket Raw%token%data Rebol Redcode 160 | reStructuredText RHTML Ruby Rust Sage Sass Scala Scheme Scilab SCSS Self Shell 161 | Smalltalk Smarty SQL Standard%ML SuperCollider Tcl Tcsh Tea TeX Textile Turing 162 | Twig Vala Verilog VHDL VimL Visual%Basic XML XQuery XS YAML Auto" 163 | LANGUAGE_VALUES_gists="as adb cls scpt arc ino asp asm aug ahk bat befunge bmx 164 | boo b bro c cs cpp chs ck clj cmake c-objdump coffee cfm lisp v cppobjdump css 165 | feature pyx d darcspatch dart dasm16 pas diff d-objdump dylan ec epj e ex el erl 166 | fs factor fy fan f90 s kid ebuild eclass po go gs man groovy gsp haml hs hx html 167 | mustache erb phtml cfg io ik weechatlog java js jsp json jl kt ly lhs ll lgt lua 168 | mak mako md matlab mxt minid duby moo mu myt n nim nu numpy objdump m j ml ooc 169 | opa cl p parrot pasm pir pl aw txt ps1 pl pp pd py pytb r rkt raw r cw rst rhtml 170 | rb rs sage sass scala scm sci scss self sh st tpl sql sml sc tcl tcsh tea tex 171 | textile t twig vala v vhd vim vb xml xq xs yml auto" 172 | DEFAULT_LANGUAGE_gists="Auto" 173 | REGEX_URL_gists='s|^.*"html_url": "\([^"]\+gist[^"]\+\)".*$|\1|p' 174 | REGEX_RAW_gists='s|^\(https://gist.github.com\)\(/.*\)$|\1\2/raw|' 175 | escape_description_gists() { sed -e 's|"|\\"|g' -e 's|\x1b|\\u001b|g' -e 's|\r||g' <<< "$*"; } 176 | escape_input_gists() { sed -e 's|\\|\\\\|g' -e 's|\x1b|\\u001b|g' -e 's|\r||g' -e 's|\t|\\t|g' -e 's|"|\\"|g' -e 's|$|\\n|' <<< "$*" | tr -d '\n'; } 177 | POST_gists() { 178 | local description="${2}" language="${3}" content="${6}" 179 | [[ "$language" = auto ]] && language="" || language=".$language" 180 | echo "{\"description\":\"${description}\",\"public\":\"${PUBLIC_gists}\",\"files\":{\"${description//\/}${language}\":{\"content\":\"${content}\"}}" 181 | } 182 | # ix_io 183 | escape_description_ix_io() { echo "$*"; } 184 | escape_input_ix_io() { echo "$*"; } 185 | POST_ix_io() { 186 | local content="${6}" boundary="WGETPASTE-f62efc3064678a57c6f442ca2f83ff" 187 | echo "--$boundary" 188 | echo "Content-Disposition: form-data; name=\"f:1\"" 189 | echo "" 190 | echo "${content}" 191 | echo "--${boundary}--" 192 | ADDITIONAL_HEADERS_ix_io=("Content-Type: multipart/form-data; boundary=${boundary}") 193 | } 194 | REGEX_RAW_ix_io='s|^http.*|\0|' 195 | REGEX_URL_ix_io='s|^http.*|\0|p' 196 | # lodgeit 197 | LANGUAGES_lodgeit="ABAP ActionScript ActionScript%3 Ada ANTLR ANTLR%With%ActionScript%Target \ 198 | ANTLR%With%CPP%Target ANTLR%With%C#%Target ANTLR%With%Java%Target ANTLR%With%ObjectiveC%Target \ 199 | ANTLR%With%Perl%Target ANTLR%With%Python%Target ANTLR%With%Ruby%Target ApacheConf AppleScript \ 200 | aspx-cs aspx-vb Asymptote Bash Bash%Session Batchfile BBCode Befunge Boo Brainfuck C C# C++ \ 201 | cfstatement Cheetah Clojure CMake c-objdump CoffeeScript Common%Lisp cpp-objdump Creole%Wiki CSS \ 202 | CSS+Django/Jinja CSS+Genshi%Text CSS+Mako CSS+Myghty CSS+PHP CSS+Ruby CSS+Smarty CSV Cython D \ 203 | Darcs%Patch Debian%Control%file Debian%Sourcelist Delphi Django/Jinja d-objdump Dylan Embedded%Ragel \ 204 | ERB Erlang Erlang%erl%session Evoque Felix Fortran GAS GCC%Messages Genshi Genshi%Text \ 205 | Gettext%Catalog Gherkin GLSL Gnuplot Go Groff Haml Haskell haXe HTML HTML+Cheetah HTML+Django/Jinja \ 206 | HTML+Evoque HTML+Genshi HTML+Mako HTML+Myghty HTML+PHP HTML+Smarty INI Io IRC%logs Java \ 207 | javac%Messages JavaScript JavaScript+Cheetah JavaScript+Django/Jinja JavaScript+Genshi%Text \ 208 | JavaScript+Mako JavaScript+Myghty JavaScript+PHP JavaScript+Ruby JavaScript+Smarty Java%Server%Page \ 209 | Lighttpd%configuration%file Literate%Haskell LLVM Logtalk Lua Makefile Mako Matlab Matlab%session \ 210 | MiniD Modelica Modula-2 MoinMoin/Trac%Wiki%markup MOOCode Multi-File MuPAD MXML Myghty MySQL NASM \ 211 | Newspeak Nginx%configuration%file NumPy objdump Objective-C Objective-J OCaml Ooc Perl PHP \ 212 | Plain%Text POVRay Prolog Python Python%3 Python%3.0%Traceback Python%console%session \ 213 | Python%Traceback Ragel Ragel%in%C%Host Ragel%in%CPP%Host Ragel%in%D%Host Ragel%in%Java%Host \ 214 | Ragel%in%Objective%C%Host Ragel%in%Ruby%Host Raw%token%data RConsole REBOL Redcode reStructuredText \ 215 | RHTML Ruby Ruby%irb%session S Sass Scala Scheme Smalltalk Smarty SQL sqlite3con SquidConf Tcl Tcsh \ 216 | TeX Unified%Diff Vala VB.net VimL XML XML+Cheetah XML+Django/Jinja XML+Evoque XML+Mako XML+Myghty \ 217 | XML+PHP XML+Ruby XML+Smarty XSLT YAML" 218 | LANGUAGE_VALUES_lodgeit="abap as as3 ada antlr antlr-as antlr-cpp antlr-csharp antlr-java antlr-objc \ 219 | antlr-perl antlr-python antlr-ruby apacheconf applescript aspx-cs aspx-vb asy bash console bat \ 220 | bbcode befunge boo brainfuck c csharp cpp cfs cheetah clojure cmake c-objdump coffee-script \ 221 | common-lisp cpp-objdump creole css css+django css+genshitext css+mako css+myghty css+php css+erb \ 222 | css+smarty csv cython d dpatch control sourceslist delphi django d-objdump dylan ragel-em erb erlang \ 223 | erl evoque felix fortran gas gcc-messages genshi genshitext pot Cucumber glsl gnuplot go groff haml \ 224 | haskell hx html html+cheetah html+django html+evoque html+genshi html+mako html+myghty html+php \ 225 | html+smarty ini io irc java javac-messages js js+cheetah js+django js+genshitext js+mako js+myghty \ 226 | js+php js+erb js+smarty jsp lighty lhs llvm logtalk lua make mako matlab matlabsession minid \ 227 | modelica modula2 trac-wiki moocode multi mupad mxml myghty mysql nasm newspeak nginx numpy objdump \ 228 | objective-c objective-j ocaml ooc perl php text pov prolog python python3 py3tb pycon pytb ragel \ 229 | ragel-c ragel-cpp ragel-d ragel-java ragel-objc ragel-ruby raw rconsole rebol redcode rst rhtml rb \ 230 | rbcon splus sass scala scheme smalltalk smarty sql sqlite3 squidconf tcl tcsh tex diff vala vb.net \ 231 | vim xml xml+cheetah xml+django xml+evoque xml+mako xml+myghty xml+php xml+erb xml+smarty xslt yaml" 232 | POST_lodgeit() { 233 | POST_generic "submit=Paste! % % language % % code" "$1" "$2" "$3" "$4" "$5" "$6" 234 | } 235 | REGEX_RAW_lodgeit='s|^\(https\?://[^/]*/\)show\(/[[:alnum:]]*/\)$|\1raw\2|' 236 | # paste.gentoo.zip 237 | escape_input_pgz() { echo "$*"; } 238 | POST_pgz() { 239 | local content="${6}" 240 | local boundary="WGETPASTE-3d8dfd9bff2b12a7410328d2ec1ed145" 241 | echo "--${boundary}" 242 | echo "Content-Disposition: form-data; name=\"file\"" 243 | echo "" 244 | echo "${content}" 245 | echo "--${boundary}--" 246 | ADDITIONAL_HEADERS_pgz=("Content-Type: multipart/form-data; boundary=${boundary}") 247 | } 248 | REGEX_RAW_pgz='s|^http.*|\0|' 249 | REGEX_URL_pgz='s|^http.*|\0|p' 250 | # pinnwand 251 | LANGUAGES_pinnwand="ABAP ActionScript%3 ActionScript Ada ANTLR ANTLR%With%ActionScript%Target \ 252 | ANTLR%With%CPP%Target ANTLR%With%C#%Target ANTLR%With%Java%Target ANTLR%With%ObjectiveC%Target \ 253 | ANTLR%With%Perl%Target ANTLR%With%Python%Target ANTLR%With%Ruby%Target ApacheConf AppleScript \ 254 | AspectJ aspx-cs aspx-vb Asymptote autohotkey AutoIt Awk Base%Makefile Bash Bash%Session Batchfile \ 255 | BBCode Befunge BlitzMax Boo Brainfuck Bro BUGS ca65 CBM%BASIC%V2 C C++ C# Ceylon CFEngine3 \ 256 | cfstatement Cheetah Clojure CMake c-objdump COBOL COBOLFree CoffeeScript Coldfusion%HTML Common%Lisp \ 257 | Coq cpp-objdump Croc CSS CSS+Django/Jinja CSS+Genshi%Text CSS+Lasso CSS+Mako CSS+Myghty CSS+PHP \ 258 | CSS+Ruby CSS+Smarty CUDA Cython Darcs%Patch Dart D Debian%Control%file Debian%Sourcelist Delphi dg \ 259 | Diff Django/Jinja d-objdump DTD Duel Dylan DylanLID Dylan%session eC ECL Elixir Elixir%iex%session \ 260 | Embedded%Ragel ERB Erlang Erlang%erl%session Evoque Factor Fancy Fantom Felix Fortran FoxPro FSharp \ 261 | GAS Genshi Genshi%Text Gettext%Catalog Gherkin GLSL Gnuplot Go GoodData-CL Gosu Gosu%Template Groff \ 262 | Groovy Haml Haskell haXe HTML+Cheetah HTML+Django/Jinja HTML+Evoque HTML+Genshi HTML HTML+Lasso \ 263 | HTML+Mako HTML+Myghty HTML+PHP HTML+Smarty HTML+Velocity HTTP Hxml Hybris IDL INI Io Ioke IRC%logs \ 264 | Jade JAGS Java JavaScript+Cheetah JavaScript+Django/Jinja JavaScript+Genshi%Text JavaScript \ 265 | JavaScript+Lasso JavaScript+Mako JavaScript+Myghty JavaScript+PHP JavaScript+Ruby JavaScript+Smarty \ 266 | Java%Server%Page JSON Julia%console Julia Kconfig Koka Kotlin Lasso Lighttpd%configuration%file \ 267 | Literate%Haskell LiveScript LLVM Logos Logtalk Lua Makefile Mako MAQL Mason Matlab Matlab%session \ 268 | MiniD Modelica Modula-2 MoinMoin/Trac%Wiki%markup Monkey MOOCode MoonScript Mscgen MuPAD MXML Myghty \ 269 | MySQL NASM Nemerle NewLisp Newspeak Nginx%configuration%file Nimrod NSIS NumPy objdump Objective-C++ \ 270 | Objective-C Objective-J OCaml Octave Ooc Opa OpenEdge%ABL Perl PHP PL/pgSQL \ 271 | PostgreSQL%console%(psql) PostgreSQL%SQL%dialect PostScript POVRay PowerShell Prolog Properties \ 272 | Protocol%Buffer Puppet PyPy%Log Python%3.0%Traceback Python%3 Python%console%session Python \ 273 | Python%Traceback QML Racket Ragel%in%C%Host Ragel%in%CPP%Host Ragel%in%D%Host Ragel%in%Java%Host \ 274 | Ragel%in%Objective%C%Host Ragel%in%Ruby%Host Ragel Raw%token%data RConsole Rd REBOL Redcode reg \ 275 | reStructuredText RHTML RobotFramework RPMSpec Ruby%irb%session Ruby Rust Sass Scala \ 276 | Scalate%Server%Page Scaml Scheme Scilab SCSS Shell%Session Smali Smalltalk Smarty Snobol SourcePawn \ 277 | sqlite3con SQL SquidConf S Standard%ML Stan systemverilog Tcl Tcsh Tea TeX Text%only Text Treetop \ 278 | TypeScript UrbiScript Vala VB.net Velocity verilog VGL vhdl VimL XML+Cheetah XML+Django/Jinja \ 279 | XML+Evoque XML+Lasso XML+Mako XML+Myghty XML+PHP XML+Ruby XML+Smarty XML+Velocity XML XQuery XSLT \ 280 | Xtend YAML" 281 | LANGUAGE_VALUES_pinnwand="abap as3 as ada antlr antlr-as antlr-cpp antlr-csharp antlr-java \ 282 | antlr-objc antlr-perl antlr-python antlr-ruby apacheconf applescript aspectj aspx-cs aspx-vb asy ahk \ 283 | autoit awk basemake bash console bat bbcode befunge blitzmax boo brainfuck bro bugs ca65 cbmbas c \ 284 | cpp csharp ceylon cfengine3 cfs cheetah clojure cmake c-objdump cobol cobolfree coffee-script cfm \ 285 | common-lisp coq cpp-objdump croc css css+django css+genshitext css+lasso css+mako css+myghty css+php \ 286 | css+erb css+smarty cuda cython dpatch dart d control sourceslist delphi dg diff django d-objdump dtd \ 287 | duel dylan dylan-lid dylan-console ec ecl elixir iex ragel-em erb erlang erl evoque factor fancy fan \ 288 | felix fortran Clipper fsharp gas genshi genshitext pot Cucumber glsl gnuplot go gooddata-cl gosu gst \ 289 | groff groovy haml haskell hx html+cheetah html+django html+evoque html+genshi html html+lasso \ 290 | html+mako html+myghty html+php html+smarty html+velocity http haxeml hybris idl ini io ioke irc jade \ 291 | jags java js+cheetah js+django js+genshitext js js+lasso js+mako js+myghty js+php js+erb js+smarty \ 292 | jsp json jlcon julia kconfig koka kotlin lasso lighty lhs live-script llvm logos logtalk lua make \ 293 | mako maql mason matlab matlabsession minid modelica modula2 trac-wiki monkey moocode moon mscgen \ 294 | mupad mxml myghty mysql nasm nemerle newlisp newspeak nginx nimrod nsis numpy objdump objective-c++ \ 295 | objective-c objective-j ocaml octave ooc opa openedge perl php plpgsql psql postgresql postscript \ 296 | pov powershell prolog properties protobuf puppet pypylog py3tb python3 pycon python pytb qml racket \ 297 | ragel-c ragel-cpp ragel-d ragel-java ragel-objc ragel-ruby ragel raw rconsole rd rebol redcode \ 298 | registry rst rhtml RobotFramework spec rbcon rb rust sass scala ssp scaml scheme scilab scss \ 299 | shell-session smali smalltalk smarty snobol sp sqlite3 sql squidconf splus sml stan systemverilog \ 300 | tcl tcsh tea tex text text treetop ts urbiscript vala vb.net velocity verilog vgl vhdl vim \ 301 | xml+cheetah xml+django xml+evoque xml+lasso xml+mako xml+myghty xml+php xml+erb xml+smarty \ 302 | xml+velocity xml xquery xslt xtend yaml" 303 | EXPIRATIONS_pinnwand="1day 1week" 304 | REGEX_URL_pinnwand='s|^.*"link": "\([^"]\+bpa.st[^"]\+\)".*$|\1|p' 305 | REGEX_RAW_pinnwand='s|^\(https://bpa.st\)\(/.*\)$|\1/raw\2|' 306 | escape_description_pinnwand() { sed -e 's|"|\\"|g' -e 's|\x1b|\\u001b|g' -e 's|\r||g' <<< "$*"; } 307 | escape_input_pinnwand() { sed -e 's|\\|\\\\|g' -e 's|\x1b|\\u001b|g' -e 's|\r||g' -e 's|\t|\\t|g' -e 's|"|\\"|g' -e 's|$|\\n|' <<< "$*" | tr -d '\n'; } 308 | POST_pinnwand() { 309 | local description="${2}" language="${3}" expiration="${4}" content="${6}" 310 | echo "{\"expiry\": \"${expiration}\", \"files\": [ {\"name\": \"${description}\", \"lexer\": \"${language}\", \"content\": \"${content}\"} ] }" 311 | } 312 | # snippets 313 | REGEX_URL_snippets='s|.*"web_url":"\([^"]*\)".*|\1|p' 314 | REGEX_RAW_snippets='s|^\(.*/snippets\)\(/.*\)$|\1\2/raw|' 315 | escape_description_snippets() { sed -e 's|"|\\"|g' -e 's|\x1b|\\u001b|g' -e 's|\r||g' <<< "$*"; } 316 | escape_input_snippets() { sed -e 's|\\|\\\\|g' -e 's|\x1b|\\u001b|g' -e 's|\r||g' -e 's|\t|\\t|g' -e 's|"|\\"|g' -e 's|$|\\n|' <<< "$*" | tr -d '\n'; } 317 | POST_snippets() { 318 | local description="${2}" content="${6}" 319 | echo "{\"title\": \"${description}\", \"content\": \"${content}\", \"description\": \"${description}\", \"file_name\": \"${description}\", \"visibility\": \"${VISIBILITY_snippets}\" }" 320 | } 321 | # sprunge 322 | escape_description_sprunge() { echo "$*"; } 323 | escape_input_sprunge() { echo "$*"; } 324 | POST_sprunge() { 325 | local content="${6}" boundary="WGETPASTE-1sQZYb7qiSkT18ZwWPNg18gEmHRztv" 326 | echo "--$boundary" 327 | echo "Content-Disposition: form-data; name=\"sprunge\"" 328 | echo "" 329 | echo "${content}" 330 | echo "--${boundary}--" 331 | ADDITIONAL_HEADERS_sprunge=("Content-Type: multipart/form-data; boundary=${boundary}") 332 | } 333 | REGEX_RAW_sprunge='s|^http.*|\0|' 334 | REGEX_URL_sprunge='s|^http.*|\0|p' 335 | 336 | ### errors 337 | die() { 338 | echo "$@" >&2 339 | exit 1 340 | } 341 | 342 | requiredarg() { 343 | [[ -z $2 ]] && die "$0: option $1 requires an argument" 344 | ((args++)) 345 | } 346 | 347 | notreadable() { 348 | die "The input source: \"$1\" is not readable. Please specify a readable input source." 349 | } 350 | 351 | noxclip() { 352 | cat <&2 353 | Could not find xclip on your system. In order to use --x$1 you must either 354 | emerge x11-misc/xclip or define x_$1() globally in /etc/wgetpaste.conf or 355 | per user in ~/.wgetpaste.conf to use another program (such as e.g. xcut or 356 | klipper) to $2 your clipboard. 357 | 358 | EOF 359 | exit 1 360 | } 361 | 362 | ### conversions 363 | 364 | # make comparison of specified languages and expirations case-insensitive 365 | tolower() { 366 | tr '[:upper:]' '[:lower:]' <<< "$*" 367 | } 368 | 369 | compare_tolower() { 370 | [[ $(tolower "$1") == $(tolower "$2") ]] 371 | } 372 | 373 | # escape % (used for escaping), & (used as separator in POST data), + (used as space in POST data), space and ; 374 | escape() { 375 | sed -e 's|%|%25|g' -e 's|&|%26|g' -e 's|+|%2b|g' -e 's|;|%3b|g' -e 's| |+|g' <<< "$*" || die "sed failed" 376 | } 377 | 378 | # if possible convert URL to raw 379 | converttoraw() { 380 | local regex 381 | regex=REGEX_RAW_$ENGINE 382 | if [[ -n ${!regex} ]]; then 383 | RAWURL=$(sed -e "${!regex}" <<< "$URL") 384 | [[ -n $RAWURL ]] && return 0 385 | echo "Conversion to raw url failed." >&2 386 | else 387 | echo "Raw download of pastes is not supported by $(getrecipient)." >&2 388 | fi 389 | return 1 390 | } 391 | 392 | # strip ANSI codes if NOANSI is set, otherwise pass the data through without 393 | # transforming it 394 | # 395 | # accepts files as args for use with pasting the contents of said file 396 | # (file checked at the call site) 397 | NOANSI= 398 | strip_ansi() { 399 | if [[ $NOANSI ]]; then 400 | "$(type -P ansifilter)" "$@" 401 | else 402 | cat "$@" 403 | fi 404 | } 405 | 406 | ### verification 407 | verifyservice() { 408 | for s in $SERVICES; do 409 | compare_tolower "$s" "$*" && return 0 410 | done 411 | echo "\"$*\" is not a supported service.$N" >&2 412 | showservices >&2 413 | exit 1 414 | } 415 | 416 | verifylanguage() { 417 | local i j l lang count v values 418 | lang=LANGUAGES_$ENGINE 419 | count=LANGUAGE_COUNT_$ENGINE 420 | values=LANGUAGE_VALUES_$ENGINE 421 | if [[ -n ${!lang} ]]; then 422 | ((i=0)) 423 | for l in ${!lang}; do 424 | if compare_tolower "$LANGUAGE" "${l//\%/ }"; then 425 | if [[ -n ${!count} ]]; then 426 | ((LANGUAGE=i+1)) 427 | elif [[ -n ${!values} ]]; then 428 | ((j=0)) 429 | for v in ${!values}; do 430 | if [[ i -eq j ]]; then 431 | if [[ ${v} == \% ]]; then 432 | LANGUAGE= 433 | else 434 | LANGUAGE=${v//\%/ } 435 | fi 436 | break 437 | fi 438 | ((j++)) 439 | done 440 | fi 441 | return 0 442 | fi 443 | ((i++)) 444 | done 445 | else 446 | [[ $LANGUAGESET = 0 ]] || return 0 447 | fi 448 | echo "\"$LANGUAGE\" is not a supported language for $(getrecipient).$N" >&2 449 | showlanguages >&2 450 | exit 1 451 | } 452 | 453 | verifyexpiration() { 454 | local i j e expiration count v values 455 | expiration=EXPIRATIONS_$ENGINE 456 | count=EXPIRATION_COUNT_$ENGINE 457 | values=EXPIRATION_VALUES_$ENGINE 458 | if [[ -n ${!expiration} ]]; then 459 | ((i=0)) 460 | for e in ${!expiration}; do 461 | if compare_tolower "${EXPIRATION}" "${e//\%/ }"; then 462 | if [[ -n ${!count} ]]; then 463 | ((EXPIRATION=i+1)) 464 | elif [[ -n {!values} ]]; then 465 | ((j=0)) 466 | for v in ${!values}; do 467 | if [[ i -eq j ]]; then 468 | if [[ ${v} == \% ]]; then 469 | EXPIRATION= 470 | else 471 | EXPIRATION=${v//\%/ } 472 | fi 473 | break 474 | fi 475 | ((j++)) 476 | done 477 | fi 478 | return 0 479 | fi 480 | ((i++)) 481 | done 482 | else 483 | [[ $EXPIRATIONSET = 0 ]] || return 0 484 | fi 485 | echo "\"$EXPIRATION\" is not a supported expiration option for $(getrecipient).$N" >&2 486 | showexpirations >&2 487 | exit 1 488 | } 489 | 490 | # verify that the pastebin service did not return a known error url. otherwise print a helpful error message 491 | verifyurl() { 492 | dieifknown() { 493 | [[ -n ${!1%% *} && ${!1%% *} == $URL ]] && die "${!1#* }" 494 | } 495 | local t 496 | for t in ${!TOO*}; do 497 | [[ $t == TOO*_$SERVICE ]] && dieifknown "$t" 498 | done 499 | } 500 | 501 | # print a warning if failure is predictable due to the mere size of the paste. note that this is only a warning 502 | # printed. it does not abort. 503 | warnings() { 504 | warn() { 505 | if [[ -n $2 && $1 -gt $2 ]]; then 506 | echo "Pasting > ${3//\%/ } often tend to fail with $SERVICE. Use --verbose or --debug to see the" 507 | echo "error output from wget if it fails. Alternatively use another pastebin service." 508 | fi 509 | } 510 | local size lines 511 | size=SIZE_$SERVICE 512 | warn "$SIZE" "${!size% *}" "${!size#* }" 513 | lines=LINES_$SERVICE 514 | warn "$LINES" "${!lines}" "${!lines} lines" 515 | } 516 | 517 | ### input 518 | getfilenames() { 519 | for f in "$@"; do 520 | [[ -f $f ]] || die "$0: $f No such file found." 521 | SOURCE="files" 522 | FILES[${#FILES[*]}]="$f" 523 | done 524 | } 525 | 526 | x_cut() { 527 | if [[ -x $(type -P xclip) ]]; then 528 | xclip -o || die "xclip failed." 529 | else 530 | noxclip cut "read from" 531 | fi 532 | } 533 | 534 | ### output 535 | usage() { 536 | cat <&2 && exit 1 643 | for l in ${!lang}; do 644 | [[ ${l//\%/ } = $DEFAULT_LANGUAGE ]] && d="*" || d=" " 645 | echo " $d${l//\%/ }" 646 | done | sort 647 | } 648 | 649 | showexpirations() { 650 | local e expiration info d 651 | expiration=EXPIRATIONS_$ENGINE 652 | [[ -n $COMPLETIONS ]] && printlist ${!expiration} && exit 0 653 | echo "Expiration options supported by $(getrecipient) (case sensitive):" 654 | info=EXPIRATION_INFO_$SERVICE 655 | [[ -z ${!expiration} ]] && echo "$N${!info}\"$ENGINE\" has no support for setting expiration." >&2 && exit 1 656 | for e in ${!expiration}; do 657 | [[ ${e//\%/ } = $DEFAULT_EXPIRATION ]] && d="*" || d=" " 658 | echo " $d${e//\%/ }" 659 | done 660 | } 661 | 662 | showurl() { 663 | [[ $QUIET ]] || echo -n "Your ${2}paste can be seen here: " >&2 664 | echo "$1" 665 | [[ $XPASTE ]] && x_paste "$1" primary 666 | [[ $XCLIPPASTE ]] && x_paste "$1" clipboard 667 | } 668 | 669 | x_paste() { 670 | if [[ -x $(type -P xclip) ]]; then 671 | echo -n "$1" | xclip -selection $2 -loops 10 &>/dev/null || die "xclip failed." 672 | else 673 | noxclip paste "write to" 674 | fi 675 | } 676 | 677 | ### Posting helper functions 678 | 679 | # get the url to post to 680 | getrecipient() { 681 | local urls target serv 682 | for s in $SERVICES tinyurl; do 683 | if [[ $s == $SERVICE ]]; then 684 | urls=URL_$SERVICE 685 | if [[ RAW == $1 ]]; then 686 | [[ ${!urls} = ${!urls#* } ]] || target=${!urls#* } 687 | else 688 | serv="$SERVICE: " 689 | fi 690 | echo "${serv}${!urls% *}${target}" 691 | return 0 692 | fi 693 | done 694 | die "Failed to get url for \"$SERVICE\"." 695 | } 696 | 697 | # generate POST data 698 | postdata() { 699 | local post 700 | post=POST_$ENGINE 701 | if [[ function != $(type -t $post) ]]; then 702 | die "\"${SERVICE}\" is not supported by ${FUNCNAME}()." 703 | fi 704 | $post "$NICK" "$DESCRIPTION" "$LANGUAGE" "$EXPIRATION" "$CVT_TABS" "$INPUT" 705 | } 706 | 707 | # get url from response from server 708 | geturl() { 709 | local regex location 710 | regex=REGEX_URL_$ENGINE 711 | location=REGEX_LOC_$ENGINE 712 | 713 | if [[ -n ${!regex} ]]; then 714 | [[ needstdout = $1 ]] && return 0 715 | sed -n -e "${!regex}" <<< "$*" 716 | elif [[ -n ${!location} ]]; then 717 | [[ needstdout = $1 ]] && return 1 718 | sed -n -e "s|^.*Location: ${!location}|p" <<< "$*" 719 | else 720 | [[ needstdout = $1 ]] && return 1 721 | svc_url=URL_$SERVICE 722 | sed -n -e "s|^.*Location: \\(${!svc_url}[^ ]*\\).*$|\\1|p" <<< "$*" 723 | fi | tail -n1 724 | } 725 | 726 | # read the config files 727 | load_configs() { 728 | if [[ ! $IGNORECONFIGS ]]; then 729 | # compatibility code 730 | local f deprecated= 731 | for f in {/etc/,~/.}wgetpaste{.d/*.bash,}; do 732 | if [[ -f $f ]]; then 733 | if [[ -z $deprecated ]]; then 734 | echo "The config files for wgetpaste have changed to *.conf.$N" >&2 735 | deprecated=0 736 | fi 737 | echo "Please move ${f} to ${f%.bash}.conf" >&2 738 | source "$f" || die "Failed to source $f" 739 | fi 740 | done 741 | [[ -n $deprecated ]] && echo >&2 742 | # new locations override old ones in case they collide 743 | for f in {/etc/,~/.}wgetpaste{.d/*,}.conf; do 744 | if [[ -f $f ]]; then 745 | source "$f" || die "Failed to source $f" 746 | fi 747 | done 748 | fi 749 | } 750 | 751 | ### get runtime options 752 | 753 | # separate groups of short options. replace --foo=bar with --foo bar 754 | while [[ -n $1 ]]; do 755 | case "$1" in 756 | -- ) 757 | for arg in "$@"; do 758 | ARGS[${#ARGS[*]}]="$arg" 759 | done 760 | break 761 | ;; 762 | --debug ) 763 | set -x 764 | DEBUG=0 765 | ;; 766 | --*=* ) 767 | ARGS[${#ARGS[*]}]="${1%%=*}" 768 | ARGS[${#ARGS[*]}]="${1#*=}" 769 | ;; 770 | --* ) 771 | ARGS[${#ARGS[*]}]="$1" 772 | ;; 773 | -* ) 774 | for shortarg in $(sed -e 's|.| -&|g' <<< "${1#-}"); do 775 | ARGS[${#ARGS[*]}]="$shortarg" 776 | done 777 | ;; 778 | * ) 779 | ARGS[${#ARGS[*]}]="$1" 780 | esac 781 | shift 782 | done 783 | 784 | # set the separated options as input options. 785 | set -- "${ARGS[@]}" 786 | 787 | load_configs 788 | 789 | while [[ -n $1 ]]; do 790 | ((args=1)) 791 | case "$1" in 792 | -- ) 793 | shift && getfilenames "$@" && break 794 | ;; 795 | -A | --ansi ) 796 | NOANSI= 797 | ;; 798 | -c | --command ) 799 | requiredarg "$@" 800 | SOURCE="command" 801 | COMMANDS[${#COMMANDS[*]}]="$2" 802 | ;; 803 | --completions ) 804 | COMPLETIONS=0 805 | ;; 806 | -d | --description ) 807 | requiredarg "$@" 808 | DESCRIPTION="$2" 809 | ;; 810 | -e | --expiration ) 811 | requiredarg "$@" 812 | EXPIRATIONSET=0 813 | EXPIRATION="$2" 814 | ;; 815 | -E | --list-expiration ) 816 | LISTEXPIRATION=0 817 | ;; 818 | -h | --help ) 819 | USAGE=0 820 | ;; 821 | -g | --ignore-configs ) 822 | IGNORECONFIGS=0 823 | ;; 824 | -i | --info ) 825 | INFO=0 826 | ;; 827 | -I | --info-only ) 828 | SOURCE=info 829 | ;; 830 | -l | --language ) 831 | requiredarg "$@" 832 | LANGUAGESET=0 833 | LANGUAGE="$2" 834 | ;; 835 | -L | --list-languages ) 836 | LISTLANGUAGES=0 837 | ;; 838 | -n | --nick ) 839 | requiredarg "$@" 840 | NICK=$(escape "$2") 841 | ;; 842 | -N | --no-ansi ) 843 | NOANSI=0 844 | ;; 845 | -q | --quiet) 846 | QUIET=0 847 | ;; 848 | -r | --raw ) 849 | RAW=0 850 | ;; 851 | -s | --service ) 852 | requiredarg "$@" 853 | SERVICESET="$2" 854 | ;; 855 | -S | --list-services ) 856 | SHOWSERVICES=0 857 | ;; 858 | -t | --tee ) 859 | TEE=0 860 | ;; 861 | -u | --tinyurl ) 862 | requiredarg "$@" 863 | SERVICE=tinyurl 864 | SOURCE="url" 865 | INPUTURL="$2" 866 | ;; 867 | -v | --verbose ) 868 | VERBOSE=0 869 | ;; 870 | --version ) 871 | echo "$0, version $VERSION" && exit 0 872 | ;; 873 | -x | --xcut ) 874 | SOURCE=xcut 875 | ;; 876 | -X | --xpaste ) 877 | XPASTE=0 878 | ;; 879 | -C | --xclippaste ) 880 | XCLIPPASTE=0 881 | ;; 882 | -* ) 883 | die "$0: unrecognized option \`$1'" 884 | ;; 885 | *) 886 | getfilenames "$1" 887 | ;; 888 | esac 889 | shift $args 890 | done 891 | 892 | # ensure ansifilter exists if requested 893 | if [[ $NOANSI ]]; then 894 | [[ -n "$(type -p ansifilter)" ]] || die "-N/--no-ansi requires app-text/ansifilter to be installed" 895 | fi 896 | 897 | ### defaults 898 | [[ $SERVICESET ]] && verifyservice "$SERVICESET" && SERVICE=$(escape "$SERVICESET") 899 | DEFAULT_NICK=${DEFAULT_NICK:-$(whoami)} || die "whoami failed" 900 | DEFAULT_SERVICE=${DEFAULT_SERVICE:-bpaste} 901 | DEFAULT_LANGUAGE=${DEFAULT_LANGUAGE:-Plain Text} 902 | DEFAULT_EXPIRATION=${DEFAULT_EXPIRATION:-1 month} 903 | SERVICE=${SERVICE:-${DEFAULT_SERVICE}} 904 | ENGINE=ENGINE_$SERVICE 905 | ENGINE="${!ENGINE}" 906 | default="DEFAULT_NICK_$SERVICE" && [[ -n ${!default} ]] && DEFAULT_NICK=${!default} 907 | default="DEFAULT_LANGUAGE_$SERVICE" && [[ -n ${!default} ]] && DEFAULT_LANGUAGE=${!default} 908 | default="DEFAULT_EXPIRATION_$SERVICE" && [[ -n ${!default} ]] && DEFAULT_EXPIRATION=${!default} 909 | NICK=${NICK:-$(escape "${DEFAULT_NICK}")} 910 | [[ -z $SOURCE ]] && SOURCE="stdin" 911 | CVT_TABS=No 912 | 913 | PUBLIC_gists=${PUBLIC_gists:-true} 914 | [[ "${PUBLIC_gists}" = "true" || "${PUBLIC_gists}" = "false" ]] || die "Invalid setting for PUBLIC_gists. Can either be 'true' or 'false' not '${PUBLIC_gists}'" 915 | 916 | VISIBILITY_snippets=${VISIBILITY_snippets:-public} 917 | [[ "${VISIBILITY_snippets}" = "public" || "${VISIBILITY_snippets}" = "private" || "${VISIBILITY_snippets}" = "internal" ]] || die "Invalid setting for VISIBILITY_snippets. Can either be 'public', 'private' or 'internal' not '${VISIBILITY_snippets}'" 918 | 919 | INFO_COMMAND=${INFO_COMMAND:-"emerge --info"} 920 | INFO_ARGS=${INFO_ARGS:-"--ignore-default-opts"} 921 | 922 | ### everything below this should be independent of which service is being used... 923 | 924 | # show listings if requested 925 | [[ $USAGE ]] && usage && exit 0 926 | [[ $SHOWSERVICES ]] && showservices && exit 0 927 | [[ $LISTLANGUAGES ]] && showlanguages && exit 0 928 | [[ $LISTEXPIRATION ]] && showexpirations && exit 0 929 | 930 | # language and expiration need to be verified before they are escaped but after service and defaults 931 | # have been selected 932 | LANGUAGE=${LANGUAGE:-${DEFAULT_LANGUAGE}} 933 | verifylanguage 934 | LANGUAGE=$(escape "$LANGUAGE") 935 | EXPIRATION=${EXPIRATION:-${DEFAULT_EXPIRATION}} 936 | verifyexpiration 937 | EXPIRATION=$(escape "$EXPIRATION") 938 | 939 | # set prompt 940 | if [[ 0 -eq $UID ]]; then 941 | PS1="#" 942 | else 943 | PS1=$ 944 | fi 945 | 946 | # set default description 947 | size=DESCRIPTION_SIZE_$SERVICE 948 | if [[ -z $DESCRIPTION ]]; then 949 | case "$SOURCE" in 950 | info ) 951 | DESCRIPTION="$PS1 $INFO_COMMAND;" 952 | ;; 953 | command ) 954 | DESCRIPTION="$PS1" 955 | for c in "${COMMANDS[@]}"; do 956 | DESCRIPTION="$DESCRIPTION $c;" 957 | done 958 | ;; 959 | files ) 960 | DESCRIPTION="${FILES[@]}" 961 | ;; 962 | * ) 963 | DESCRIPTION="$SOURCE" 964 | ;; 965 | esac 966 | if [[ -n ${!size} && ${#DESCRIPTION} -gt ${!size} ]]; then 967 | DESCRIPTION="${DESCRIPTION: -${!size}}" 968 | fi 969 | else 970 | if [[ -n ${!size} && ${#DESCRIPTION} -gt ${!size} ]]; then 971 | die "Your description (${#DESCRIPTION} bytes) is too long. Shorten it to fit within ${!size} bytes." 972 | fi 973 | fi 974 | 975 | # create tmpfile for use with tee 976 | if [[ $TEE ]]; then 977 | TMPF=$(mktemp -q --tmpdir wgetpaste.XXXXXX) 978 | [[ -f $TMPF ]] || die "Could not create a temporary file for use with tee." 979 | fi 980 | 981 | # read input 982 | case "$SOURCE" in 983 | url ) 984 | INPUT="${INPUTURL}" 985 | ;; 986 | command ) 987 | for c in "${COMMANDS[@]}"; do 988 | if [[ $TEE ]]; then 989 | echo "$PS1 $c$N$(bash -c "$c" 2>&1 | strip_ansi)$N" | tee -a "$TMPF" 990 | else 991 | INPUT="$INPUT$PS1 $c$N$(bash -c "$c" 2>&1 | strip_ansi)$N$N" 992 | fi 993 | done 994 | ;; 995 | info ) 996 | if [[ $TEE ]]; then 997 | echo "$PS1 $INFO_COMMAND$N$($INFO_COMMAND $INFO_ARGS 2>&1 | strip_ansi)" | tee "$TMPF" 998 | else 999 | INPUT="$PS1 $INFO_COMMAND$N$($INFO_COMMAND $INFO_ARGS 2>&1 | strip_ansi)" 1000 | fi 1001 | ;; 1002 | xcut ) 1003 | if [[ $TEE ]]; then 1004 | x_cut | strip_ansi | tee "$TMPF" 1005 | else 1006 | INPUT="$(x_cut | strip_ansi)" 1007 | fi 1008 | ;; 1009 | stdin ) 1010 | if [[ $TEE ]]; then 1011 | strip_ansi | tee "$TMPF" 1012 | else 1013 | INPUT="$(strip_ansi)" 1014 | fi 1015 | ;; 1016 | files ) 1017 | if [[ ${#FILES[@]} -gt 1 ]]; then 1018 | for f in "${FILES[@]}"; do 1019 | [[ -r $f ]] || notreadable "$f" 1020 | if [[ $TEE ]]; then 1021 | echo "$PS1 cat $f$N$(strip_ansi "$f")$N" | tee -a "$TMPF" 1022 | else 1023 | INPUT="$INPUT$PS1 cat $f$N$(strip_ansi "$f")$N$N" 1024 | fi 1025 | done 1026 | else 1027 | [[ -r $FILES ]] || notreadable "$FILES" 1028 | if [[ $TEE ]]; then 1029 | strip_ansi "$FILES" | tee "$TMPF" 1030 | else 1031 | INPUT=$(strip_ansi "$FILES") 1032 | fi 1033 | fi 1034 | ;; 1035 | esac 1036 | NOINPUT="No input read. Nothing to paste. Aborting." 1037 | if [[ $TEE ]]; then 1038 | [[ 0 -eq $(wc -c < "$TMPF") ]] && die "$NOINPUT" 1039 | else 1040 | [[ -z $INPUT ]] && die "$NOINPUT" 1041 | fi 1042 | 1043 | # append info if needed 1044 | if [[ $INFO ]]; then 1045 | DESCRIPTION="$DESCRIPTION $PS1 $INFO_COMMAND;" 1046 | if [[ $TEE ]]; then 1047 | echo "$N$PS1 $INFO_COMMAND$N$($INFO_COMMAND $INFO_ARGS 2>&1 | strip_ansi)" | tee -a "$TMPF" 1048 | else 1049 | INPUT="$INPUT$N$PS1 $INFO_COMMAND$N$($INFO_COMMAND $INFO_ARGS 2>&1 | strip_ansi)" 1050 | fi 1051 | fi 1052 | 1053 | # now that tee has done its job read data into INPUT 1054 | [[ $TEE ]] && INPUT=$(<"$TMPF") && echo 1055 | 1056 | # escape DESCRIPTION and INPUT 1057 | if [[ function = $(type -t escape_description_$ENGINE) ]]; then 1058 | DESCRIPTION=$(escape_description_$ENGINE "$DESCRIPTION") 1059 | else 1060 | DESCRIPTION=$(escape "$DESCRIPTION") 1061 | fi 1062 | if [[ function = $(type -t escape_input_$ENGINE) ]]; then 1063 | INPUT=$(escape_input_$ENGINE "$INPUT") 1064 | else 1065 | INPUT=$(escape "$INPUT") 1066 | fi 1067 | 1068 | # print friendly warnings if max sizes have been specified for the pastebin service and the size exceeds that 1069 | SIZE=$(wc -c <<< "$INPUT") 1070 | LINES=$(wc -l <<< "$INPUT") 1071 | warnings >&2 1072 | 1073 | # set recipient 1074 | RECIPIENT=$(getrecipient RAW) 1075 | 1076 | if [[ $SERVICE == tinyurl ]]; then 1077 | URL=$(LC_ALL=C wget -qO - "$RECIPIENT?url=$INPUT") 1078 | else 1079 | # create temp file (wget is much more reliable reading 1080 | # large input via --post-file rather than --post-data) 1081 | [[ -f $TMPF ]] || TMPF=$(mktemp -q --tmpdir wgetpaste.XXXXXX) 1082 | if [[ -f $TMPF ]]; then 1083 | postdata > "$TMPF" || die "Failed to write to temporary file: \"$TMPF\"." 1084 | WGETARGS="--post-file=$TMPF" 1085 | else 1086 | # fall back to using --post-data if the temporary file could not be created 1087 | # TABs and new lines need to be escaped for wget to interpret it as one string 1088 | WGETARGS="--post-data=$(postdata | sed -e 's|$|%0a|g' -e 's|\t|%09|g' | tr -d '\n')" 1089 | fi 1090 | 1091 | header="HEADER_$SERVICE" 1092 | if [[ -n "${!header}" ]]; then 1093 | WGETEXTRAHEADER="--header=${!header}" 1094 | else 1095 | WGETEXTRAHEADER="" 1096 | fi 1097 | 1098 | # build additional headers 1099 | additional_headers="ADDITIONAL_HEADERS_$SERVICE" 1100 | WGETADDITIONALHEADERS=() 1101 | if [[ -n "${!additional_headers}" ]]; then 1102 | tmp=$additional_headers[@] 1103 | for i in "${!tmp}" 1104 | do 1105 | WGETADDITIONALHEADERS+=("--header=${i}") 1106 | done 1107 | fi 1108 | 1109 | # paste it 1110 | WGETARGS="--tries=5 --timeout=60 $WGETARGS" 1111 | if geturl needstdout ; then 1112 | OUTPUT=$(LC_ALL=C wget -O - $WGETARGS ${WGETEXTRAHEADER:+"$WGETEXTRAHEADER"} ${WGETADDITIONALHEADERS[@]:+"${WGETADDITIONALHEADERS[@]}"} $RECIPIENT 2>&1) 1113 | else 1114 | OUTPUT=$(LC_ALL=C wget -O /dev/null $WGETARGS ${WGETEXTRAHEADER:+"$WGETEXTRAHEADER"} ${WGETADDITIONALHEADERS[@]:+"${WGETADDITIONALHEADERS[@]}"} $RECIPIENT 2>&1) 1115 | fi 1116 | 1117 | # clean temporary file if it was created 1118 | if [[ -f $TMPF ]]; then 1119 | if [[ $DEBUG ]]; then 1120 | echo "Left temporary file: \"$TMPF\" alone for debugging purposes." 1121 | else 1122 | rm "$TMPF" || echo "Failed to remove temporary file: \"$TMPF\"." >&2 1123 | fi 1124 | fi 1125 | 1126 | # get the url 1127 | URL=$(geturl "$OUTPUT") 1128 | fi 1129 | 1130 | # verify that the pastebin service did not return a known error url such as toofast.html from rafb 1131 | verifyurl 1132 | 1133 | # handle the case when there was no location returned 1134 | if [[ -z $URL ]]; then 1135 | if [[ $DEBUG || $VERBOSE ]]; then 1136 | die "Apparently nothing was received. Perhaps the connection failed.$N$OUTPUT" 1137 | else 1138 | echo "Apparently nothing was received. Perhaps the connection failed. Enable --verbose or" >&2 1139 | die "--debug to get the output from wget that can help diagnose it correctly." 1140 | fi 1141 | fi 1142 | 1143 | # converttoraw() sets RAWURL upon success. 1144 | if [[ $RAW ]] && converttoraw; then 1145 | showurl "$RAWURL" "raw " 1146 | else 1147 | showurl "$URL" 1148 | fi 1149 | 1150 | exit 0 1151 | -------------------------------------------------------------------------------- /wgetpaste.spec: -------------------------------------------------------------------------------- 1 | Name: wgetpaste 2 | Version: 2.33 3 | Release: 1%{?dist} 4 | Summary: Command-line interface to various paste-bins 5 | 6 | License: MIT 7 | URL: http://%{name}.zlin.dk/ 8 | Source0: %{url}/%{name}-%{version}.tar.bz2 9 | 10 | Requires: bash sed wget 11 | 12 | BuildArch: noarch 13 | 14 | %description 15 | Command-line interface to various paste-bins 16 | 17 | %prep 18 | %setup -q 19 | 20 | %build 21 | 22 | %install 23 | rm -rf $RPM_BUILD_ROOT 24 | mkdir -p %{buildroot}/%{_bindir} 25 | 26 | install -m 0755 %{name} %{buildroot}/%{_bindir}/%{name} 27 | sed -i -e "s:/usr/bin/env bash:/bin/bash:" %{buildroot}/%{_bindir}/%{name} 28 | 29 | %files 30 | %{_bindir}/%{name} 31 | %license LICENSE 32 | 33 | 34 | %changelog 35 | * Tue Oct 1 2019 Wulf C. Krueger 2.29-1 36 | - Update to 2.29 37 | 38 | * Wed Mar 21 2018 Wulf C. Krueger 2.28-1 39 | - Initial package 40 | --------------------------------------------------------------------------------