diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile | 27 | ||||
-rw-r--r-- | fb-helper.c | 429 | ||||
-rw-r--r-- | fb.in | 461 |
4 files changed, 5 insertions, 913 deletions
@@ -1,3 +1,2 @@ dist fb -fb-helper @@ -2,49 +2,32 @@ VERSION:=$(shell git describe --dirty | sed 's/^v//; s/-/./g') PREFIX=/usr MANDIR=$(PREFIX)/share/man BINDIR=$(PREFIX)/bin -LIBDIR=$(PREFIX)/lib -MY_LIBDIR=$(LIBDIR)/fb-client -CC?=cc -CFLAGS:=-std=c99 -O2 -Wall -Wextra -pedantic $(CFLAGS) -LIBCURL:=$(shell pkg-config --silence-errors --libs --cflags libcurl) - -ifdef LIBCURL -all: fb fb-helper -else + all: fb -endif -fb: fb.in +fb: fb.py @[ -n "$(VERSION)" ] || (echo "Error: version detection failed"; exit 1) - sed 's|@VERSION@|$(VERSION)|; s|@LIBDIR@|$(MY_LIBDIR)|' $< > $@ + sed 's|@VERSION@|$(VERSION)|' $< > $@ chmod 755 $@ -fb-helper: fb-helper.c - $(CC) $(CFLAGS) $(LDFLAGS) -DVERSION=\"$(VERSION)\" -o $@ $< $(LIBCURL) - clean: - rm -f fb fb-helper + rm -f fb rm -rf dist install: all install -dm755 $(DESTDIR)$(BINDIR) install -m755 fb $(DESTDIR)$(BINDIR)/fb -ifdef LIBCURL - install -dm755 $(DESTDIR)$(MY_LIBDIR) - install -m755 fb-helper $(DESTDIR)$(MY_LIBDIR)/fb-helper -endif install -dm755 $(DESTDIR)$(MANDIR)/man1 install -m644 fb.1 $(DESTDIR)$(MANDIR)/man1/fb.1 uninstall: rm -f $(DESTDIR)$(BINDIR)/fb - rm -rf $(DESTDIR)$(MY_LIBDIR) rm -f $(DESTDIR)$(MANDIR)/man1/fb.1 dist: all @[ -n "$(VERSION)" ] || (echo "Error: version detection failed"; exit 1) mkdir -p dist/fb-$(VERSION) - cp -a fb-helper.c fb{,.in} fb.1 COPYING Makefile dist/fb-$(VERSION) + cp -a fb{,.py} fb.1 COPYING Makefile dist/fb-$(VERSION) sed -i 's/^VERSION:=.*$$/VERSION:='$(VERSION)'/' dist/fb-$(VERSION)/Makefile cd dist; tar -czf fb-$(VERSION).tar.gz fb-$(VERSION) diff --git a/fb-helper.c b/fb-helper.c deleted file mode 100644 index 3dd6dbb..0000000 --- a/fb-helper.c +++ /dev/null @@ -1,429 +0,0 @@ -/* - * Description: This is intended as a helper for fb only. - * - * Synopsis: ./fb-helper <action> <URL> <file> - * - * action can be: - * d = download <URL> - * u = upload <file> to <URL> - * - * Author: Florian "Bluewind" Pritz <flo@xssn.at> - * - * Licensed under GPLv3 - * (see COPYING for full license text) - */ - -#define _POSIX_C_SOURCE 2 - -#include <stdio.h> -#include <sys/time.h> -#include <sys/stat.h> -#include <libgen.h> -#include <string.h> -#include <stdlib.h> -#include <time.h> -#include <unistd.h> - -#include <curl/curl.h> -#include <curl/easy.h> - -#define FORMAT_BYTES_BUFFER 16 -#define FORMAT_TIME_BUFFER 16 -#define SAMPLE_COUNT 15 - -#define UNUSED __attribute__((unused)) - -struct sample { - size_t size; - double time; -}; - -/* struct which holds the persistent data for progress_callback */ -struct progressData { - struct timeval last; - double ullast; - int lastStringLength; - struct sample samples[SAMPLE_COUNT]; - int current_sample; -}; - -struct options { - int debug; - char *url; - char *file; - char *apikeyfile; -}; - -/* load the contents of file fn into data */ -int load_file(const char *fn, char **data, size_t *data_size) -{ - FILE *fp; - size_t buf_size = 1024*1024; /* use 1MiB chunks */ - - fp = fopen(fn, "rb"); - if (fp == NULL) { - perror("load_file"); - return 1; - } - - /* read the file in buf_size chunks and appened the data to *data */ - while (!feof(fp)) { - char *tmp; - tmp = realloc(*data, *data_size + buf_size); - if (tmp == NULL) { - perror("load_file"); - return 1; - } - *data = tmp; - - *data_size += fread(*data + *data_size, sizeof(char), buf_size, fp); - - if (ferror(fp)) { - perror("load_file"); - return 1; - } - } - - fclose(fp); - - return 0; -} - -void format_bytes(char *buf, int bufsize, double bytes) -{ - double size = bytes; - int suffix_pos = 0; - static const char *suffix[] = {"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"}; - static const int suffix_count = sizeof(suffix) / sizeof(suffix[0]); - static const double boundary = 2048.0; - - for(suffix_pos = 0; suffix_pos + 1 < suffix_count; suffix_pos++) { - if(size <= boundary && size >= -boundary) { - break; - } - size /= 1024.0; - } - - // don't print decimals for bytes - if (suffix_pos != 0) - snprintf(buf, bufsize, "%.2f%s", size, suffix[suffix_pos]); - else - snprintf(buf, bufsize, "%.0f%s", size, suffix[suffix_pos]); -} - -void format_time(char *buf, int bufsize, time_t time) -{ - int seconds = 0; - int minutes = 0; - int hours = 0; - - seconds = time%60; - minutes = (time/60)%60; - hours = time/60/60; - - if (hours > 0) { - snprintf(buf, bufsize, "%d:%02d:%02d", hours, minutes, seconds); - } else { - snprintf(buf, bufsize, "%02d:%02d", minutes, seconds); - } -} - -int progress_callback( - void *cb_data, - double UNUSED dltotal, double UNUSED dlnow, - double ultotal, double ulnow -){ - struct timeval now; - struct progressData *data = (struct progressData *)cb_data; - double timeSpent = 0; - int printed = 0; - char speed[FORMAT_BYTES_BUFFER]; - char total[FORMAT_BYTES_BUFFER]; - char eta[FORMAT_TIME_BUFFER]; - time_t time_remaining = 0; - - double ulspeed = 0.0; - size_t sample_total = 0; - double sample_time = 0.0; - - if (0 == ulnow) - return 0; - - /* upload complete; clean up */ - if (ulnow >= ultotal) { - fprintf(stderr, "%*s\r", data->lastStringLength + 1, ""); - return 0; - } - - gettimeofday(&now, NULL); - - /* calculate time between this and the last call in seconds */ - timeSpent = - (double)(now.tv_sec - data->last.tv_sec) + - (double)(now.tv_usec - data->last.tv_usec) / 1E6; - - /* don't refresh too often, catch if time went backwards */ - if (timeSpent < 0.2 && timeSpent > -1.0) - return 0; - - /* save a sample every time we update and average over all samples - * to reduce jumpiness */ - data->samples[data->current_sample].size = ulnow - data->ullast; - data->samples[data->current_sample].time = timeSpent; - - data->current_sample++; - if (data->current_sample >= SAMPLE_COUNT) { - data->current_sample = 0; - } - - for (int i = 0; i < SAMPLE_COUNT; i++) { - if (data->samples[i].size != 0) { - sample_total += data->samples[i].size; - sample_time += data->samples[i].time; - } - } - - ulspeed = sample_total / sample_time; - - if (ulspeed < 1) { - snprintf(eta, sizeof(eta), "stalling"); - } else { - time_remaining = (ultotal - ulnow) / ulspeed; - format_time(eta, sizeof(eta), time_remaining); - } - - format_bytes((char *)&total, sizeof(total), ulnow); - format_bytes((char *)&speed, sizeof(speed), ulspeed); - - /* print the progress */ - printed = fprintf(stderr, - "\r%s/s uploaded: %.1f%% = %s; ETA: %s", - speed, /* upload speed */ - ulnow * 100.0 / ultotal, /* percent uploaded */ - total, /* total data uploaded */ - eta - ); - - /* pad the string if the last one was longer to remove left over characters */ - if (data->lastStringLength > printed) - fprintf(stderr, "%*s", data->lastStringLength - printed, ""); - - /* save current values for the next run */ - data->ullast = ulnow; - data->last = now; - data->lastStringLength = printed; - - return 0; -} - -void display_help() -{ - printf("Usage: fb-helper <options>\n"); - printf("\n"); - printf("Options:\n"); - printf(" -D Print debugging information\n"); - printf(" -h This help\n"); - printf(" -u <url> URL of pastebin or URL to download\n"); - printf(" -f <file> File to upload to URL\n"); - printf(" -F key=value Post key=value\n"); - printf(" -a <file> Path to API key file\n"); -} - -int main(int argc, char *argv[]) -{ - CURL *curl = NULL; - CURLcode res; - - struct curl_httppost *formpost = NULL; - struct curl_httppost *lastptr = NULL; - struct curl_slist *headerlist = NULL; - static const char buf[] = "Expect:"; - - char *userAgent = "fb-client/"VERSION; - - struct progressData cb_data = { - .last = {.tv_sec = 0, .tv_usec = 0}, - .ullast = 0.0, - .lastStringLength = 0, - .current_sample = 0 - }; - - char *data = NULL; - - int ret = 0; - - int opt; - struct options options = { - .debug = 0, - .file = NULL, - .url = NULL, - .apikeyfile = NULL - }; - - if (argc == 1) { - display_help(); - exit(0); - } - - while ((opt = getopt(argc, argv, "Du:f:F:m:a:h")) != -1) { - switch (opt) { - case 'D': options.debug = 1; break; - - case 'u': options.url = optarg; break; - - case 'f': options.file = optarg; break; - - case 'F': - { - char *save = NULL; - char *key = strtok_r(optarg, "=", &save); - char *value = strtok_r(save, "=", &save); - - curl_formadd(&formpost, - &lastptr, - CURLFORM_COPYNAME, key, - CURLFORM_PTRCONTENTS, value, - CURLFORM_END); - } - break; - - case 'a': options.apikeyfile = optarg; break; - - case 'h': - display_help(); - exit(0); - break; - - default: - fprintf(stderr, "Error: unknown option %c", opt); - exit(1); - } - } - - /* initialize curl */ - if (curl_global_init(CURL_GLOBAL_ALL) != 0) { - fprintf(stderr, "Error initializing curl"); - ret = 10; - goto cleanup; - } - - curl = curl_easy_init(); - if(!curl) { - fprintf(stderr, "Error initializing curl"); - ret = 1; - goto cleanup; - } - - if (options.debug > 0) { - curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); - } - - if (options.apikeyfile) { - curl_formadd(&formpost, - &lastptr, - CURLFORM_COPYNAME, "apikey", - CURLFORM_FILECONTENT, options.apikeyfile, - CURLFORM_END); - } else { - /* use .netrc settings for authentication if available */ - curl_easy_setopt(curl, CURLOPT_NETRC, CURL_NETRC_OPTIONAL); - } - - - /* if we have a file to upload, add it as a POST request */ - if (options.file) { - struct stat statbuf; - - if(stat(options.file, &statbuf) == -1) { - fprintf(stderr, "fb-helper: %s: ", options.file); - perror(NULL); - ret = 1; - goto cleanup; - } - - /* load files with 0 size (/proc files for example) into memory so we can - * determine their real length */ - if (statbuf.st_size == 0) { - size_t data_size = 0; - - if (load_file(options.file, &data, &data_size) != 0) { - ret = 1; - goto cleanup; - } - - if (data_size == 0) { - fprintf(stderr, "Error: skipping 0-byte file: \"%s\"\n", options.file); - ret = 1; - goto cleanup; - } - - /* Fill in the file upload field */ - curl_formadd(&formpost, - &lastptr, - CURLFORM_COPYNAME, "file", - CURLFORM_BUFFER, basename(options.file), - CURLFORM_BUFFERPTR, data, - CURLFORM_BUFFERLENGTH, (char *)data_size, - CURLFORM_END); - } else { - /* Fill in the file upload field */ - curl_formadd(&formpost, - &lastptr, - CURLFORM_COPYNAME, "file", - CURLFORM_FILE, options.file, - CURLFORM_END); - } - - if (isatty(fileno(stderr)) == 1) { - /* display progress bar*/ - curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); - curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &cb_data); - curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_callback); - } - } - - curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost); - - /* initialize custom header list (stating that Expect: 100-continue is not - wanted */ - headerlist = curl_slist_append(headerlist, buf); - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist); - - curl_easy_setopt(curl, CURLOPT_URL, options.url); - curl_easy_setopt(curl, CURLOPT_USERAGENT, userAgent); - - /* bail if the upload stalls for 30 seconds */ - curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 1L); - curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, 30L); - - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10L); - - curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, ""); - - /* save time for progress calculation */ - gettimeofday(&cb_data.last, NULL); - - /* run the request */ - res = curl_easy_perform(curl); - - /* handle curl errors */ - if (res != 0) { - fprintf(stderr, "\n%s\n", curl_easy_strerror(res)); - ret = 1; - goto cleanup; - } - -cleanup: - if (curl) - curl_easy_cleanup(curl); - - if (formpost) - curl_formfree(formpost); - - curl_slist_free_all (headerlist); - curl_global_cleanup(); - free(data); - - return ret; -} @@ -1,461 +0,0 @@ -#!/bin/bash -#---------------------------------------------------- -# Author: Florian "Bluewind" Pritz <flo@xssn.at> -# Contributor: Moritz Wilhelmy -# -# Licensed under GPLv3 -# (see COPYING for full license text) -# -#---------------------------------------------------- -# Optional dependency: xclip -#---------------------------------------------------- - -pastebin="https://paste.xinu.at" -warnsize=10485760 -libdir="@LIBDIR@" - -# the calling conventions for stat(1) are highly system dependent -stat='stat -c %s' # GNU stat(1) is the default since most people have it - -clipboard_cmd=xclip - -case "`uname -s`" in - *BSD) stat='stat -f %z';; - Minix) stat='stat -size';; - Darwin) - stat='stat -f %z' - clipboard_cmd=pbcopy - ;; -esac - -if [ -z "$XDG_CONFIG_HOME" ]; then - XDG_CONFIG_HOME="$HOME/.config" -fi - -apikey_file="$XDG_CONFIG_HOME/fb-client/apikey" - -config_file="$XDG_CONFIG_HOME/fb-client/config" -if [ -e "$config_file" ]; then - . "$config_file" -fi - -version="@VERSION@" -delete= -extension="" -filename="stdin" -get= -multipaste= -multipaste_ids=() -tar= -compress=0 -display_history= -create_apikey= -clipboard="" -exitcode=0 -debug= -useragent="fb-client/shell-$version" -default_curlopts=(-# -L -A "$useragent" --speed-time 30 --speed-limit 1 --connect-timeout 10) - -base64_encode() { - if type base64 2>&1 >/dev/null; then - printf "%s" "$1" | base64 - elif type openssl 2>&1 >/dev/null; then - printf "%s" "$1" | openssl enc -base64 - else - printf "%s\n" "Warning: can't find base64 nor openssl executable" >&2 - printf "%s\n" " filename of uploaded file will be set to stdin" >&2 - printf "%s\n" "stdin" - fi -} - -request_helper() { - # available modes are: d, u, m - mode=$1 - url=$2 - file=$3 - - # if available use the external helper, else fall back to calling curl - if [ -x "$libdir/fb-helper" ]; then - helperopts=(-u "$url") - - if [ "$debug" ]; then - helperopts+=(-D) - fi - - if [ -e "$apikey_file" ]; then - helperopts+=(-a $apikey_file) - fi - - if [ "$mode" = "u" ]; then - helperopts+=(-f "$file") - fi - - if [ "$mode" = "m" ]; then - for id in "${multipaste_ids[@]}"; do - helperopts+=(-F "ids[]=$id") - done - fi - $libdir/fb-helper "${helperopts[@]}" - else - curlopts=(${default_curlopts[@]}) - - require_executable curl - - if [ -e "$apikey_file" ]; then - curlopts+=("-F" "apikey=<${apikey_file}") - else - curlopts+=("-n") - fi - - if [ "$debug" ]; then - curlopts+=("-v") - fi - - if [ "$mode" = "m" ]; then - for id in "${multipaste_ids[@]}"; do - curlopts+=(-F "ids[]=$id") - done - fi - - if [ "$mode" = "d" ]; then - curlopts+=("-s") - fi - - if [ "$mode" = "u" ]; then - basefilename=`basename -- "$file"` - if [ "`$stat -- "$file"`" -eq "0" ] || printf "%s" "$basefilename" | grep -F -q ","; then - if [ "`wc -c < "$file"`" -eq "0" ]; then - printf "%s\n" "Error: skipping 0-byte file: \"$file\"" >&2 - return 1 - fi - base64fn="`base64_encode "$basefilename"`" - curl "${curlopts[@]}" -F "file=@-" -F "filename=$base64fn" "$url" < "$file" -o /dev/stdout - else - curl "${curlopts[@]}" -F "file=@$file" "$url" -o /dev/stdout - fi - else - curl "${curlopts[@]}" "$url" - fi - fi -} - -require_executable() { - if ! type $1 >/dev/null; then - printf "%s\n" "Error: $1 not found. Please install." >&2 - exit 1 - fi -} - -is_url() { - if printf "%s" "$i" | grep -qE "^(f|ht)tp(s)?://.+"; then - return 0 - fi - return 1 -} - -is_pastebin_url() { - if printf "%s" "$i" | grep -qE "^$pastebin.+"; then - return 0 - fi - - return 1 -} - -do_tar_upload() { - if [ "$compress" = "1" ]; then - file="$tmpdir/$filename.tar.gz" - tar -cf - -- "$@" | gzip -n -c > "$file" || return 1 - elif [ "$compress" = "2" ]; then - file="$tmpdir/$filename.tar.xz" - tar -cf - -- "$@" | xz -c > "$file" || return 1 - else - file="$tmpdir/$filename.tar" - tar -cf "$file" -- "$@" || return 1 - fi - compress=0 - do_upload "$file" || return 1 -} - -do_upload() { - local extra="" - file="$1" - basefilename="`basename -- "$file"`" - basedirname="`dirname -- "$file"`" - - if [ ! -r "$file" ]; then - # sh doesn't have perror so this message can't be more precise - printf "%s\n" "Error: File \"$file\" is not readable/not found." >&2 - return 1 - fi - - if [ -d "$file" ]; then - cd "$basedirname" - if [ "$compress" = "1" ]; then - file="$tmpdir/$basefilename.tar.gz" - tar -cf - -- "$basefilename" | gzip -n -c > "$file" || return 1 - elif [ "$compress" = "2" ]; then - file="$tmpdir/$basefilename.tar.xz" - tar -cf - -- "$basefilename" | xz -c > "$file" || return 1 - else - file="$tmpdir/$basefilename.tar" - tar -cf "$file" -- "$basefilename" || return 1 - fi - else - if [ "$compress" = "1" ]; then - gzip -n -c -- "$file" > "$tmpdir/$basefilename.gz" || return 1 - file="$tmpdir/$basefilename.gz" - elif [ "$compress" = "2" ]; then - xz -c -- "$file" > "$tmpdir/$basefilename.xz" || return 1 - file="$tmpdir/$basefilename.xz" - fi - fi - - tmpfile=`mktemp "$tmpdir/data.XXXXXX"` - if [ "`$stat -- "$file"`" -gt "$warnsize" ]; then - warnsize=`request_helper d "$pastebin/file/get_max_size"` - if [ "`$stat -- "$file"`" -gt "$warnsize" ]; then - printf "%s\n" "Warning: Your upload is too big and would be rejected. Maximum size is: $warnsize bytes. Skipping..." >&2 - return 1 - fi - fi - - request_helper u "$pastebin/file/do_upload" "$file" > $tmpfile || return 1 - - sed '$d' $tmpfile >&2 - url=`tail -1 $tmpfile`"$extension" - rm "$tmpfile" - printf "%s\n" "$url" - if printf "%s" "$url" | grep -qE "^https?://"; then - if [ -z "$clipboard" ]; then - clipboard="$url" - else - clipboard="$clipboard $url" - fi - fi -} - -read_stdin() { - if tty -s; then - printf "%s\n" "^C to exit, ^D to send" - fi - cat > "$1" -} - -read_string() { - read -r tmp - echo "$tmp" -} - -id_from_arg() { - local regex="https?:\/\/[^\/]+\/([^\/]+).*" - if [[ $1 =~ $regex ]]; then - printf "%s" "${BASH_REMATCH[1]}" - else - printf "%s" "$1" - fi -} - -create_apikey() { - if [ -z "$HOST" ]; then - HOST=`hostname` - fi - - require_executable curl - - printf "%s" "Username: " - read_string | tr -d "\n" > "$tmpdir/username" - - printf "%s" "Password: " - stty -echo - read_string | tr -d "\n" > "$tmpdir/password" - stty echo - printf "\n" - - curlopts=(${default_curlopts[@]}) - if [ "$debug" ]; then - curlopts+=(-v) - fi - - curl "${curlopts[@]}" -w "%{http_code}\n" -s -F "username=<$tmpdir/username" -F "password=<$tmpdir/password" -F "comment=fb-client $USER@$HOST" "$pastebin/user/create_apikey" > "$tmpdir/api-result" - - rm "$tmpdir/username" "$tmpdir/password" - - status_code=`tail -n 1 "$tmpdir/api-result"` - - if [ "$status_code" == "200" ]; then - if [ ! -d "$XDG_CONFIG_HOME/fb-client/" ]; then - mkdir -p "$XDG_CONFIG_HOME/fb-client" - fi - head -n 1 "$tmpdir/api-result" > "$apikey_file" - return 0 - fi - - echo "Failed to generate API key:" >&2 - sed '$d' "$tmpdir/api-result" >&2 - - return 1 -} - -help() { - cat <<! -fb-client version $version -usage: [cat |] `basename "$0"` [switches] [options] [<file(s)|ID(s)|folder(s)>] - - Upload/nopaste file(s)/stdin to paste.xinu.at and copy URL(s) to clipboard. - - Switches: - -d <ID(s)> delete the IDs - -g <ID(s)> download the IDs and output on stdout (use with care!) - -m create a multipaste - -h this help - -v show the client version - -H display an upload history - -a create a new api key - - Options: - -e <extension> extension for default highlighting (e.g. "diff") - -n <file name> file name to use for upload when reading from stdin - Defaults to "stdin" - -t upload a tar file containing all files (and directories) - -c compress the file being uploaded with gz or xz if used 2 times - When used in conjunction with -g this decompresses the download - -D show debugging information -! -} - -if ! type getopts >/dev/null 2>&1; then - printf "%s\n" "Error: getopts is not supported by your shell" >&2 - exit 1 -fi - -while getopts "e:n:gmdhHatcvD" option; do - case $option in - e) extension="$OPTARG";; - n) filename="$OPTARG";; - g) get=1;; - m) multipaste=1;; - c) compress=`expr $compress + 1`;; - t) tar=1;; - d) delete=1;; - H) display_history=1;; - a) create_apikey=1;; - v) printf "%s\n" "$version"; exit 0;; - D) debug=1;; - h|\?) help; exit 0;; - esac -done - -shift `expr $OPTIND - 1` - -if [[ "$#" -gt 1 && ! "$tar" ]]; then - multipaste=1 -fi - -if [ "$compress" = "1" ]; then - require_executable gzip -elif [ "$compress" = "2" ]; then - require_executable xz -fi - -tmpdir="`mktemp -dt "fb.XXXXXX"`" -trap "rm -rf '${tmpdir}'" EXIT TERM - -if [ "$delete" ] || [ "$get" ]; then - if [ $# -eq 0 ]; then - printf "%s\n" "Error: no ID specified" >&2 - exit 1 - fi - for i in "$@"; do - i=$(id_from_arg "$i") - if [ "$delete" ]; then - request_helper d "$pastebin/file/delete/$i" || exitcode=1 - - elif [ "$get" ]; then - if [ "$compress" = "1" ]; then - request_helper d "$pastebin/$i" | gzip -cd || exitcode=1 - elif [ "$compress" = "2" ]; then - request_helper d "$pastebin/$i" | xz -cd || exitcode=1 - else - request_helper d "$pastebin/$i" || exitcode=1 - fi - fi - done -elif [ "$display_history" ]; then - request_helper d "$pastebin/file/upload_history" || exitcode=1 -elif [ "$create_apikey" ]; then - create_apikey - exit $? -elif [ $# -eq 0 ]; then - if [ "$tar" ]; then - printf "%s\n" "Error: -t is not supported when operating on stdin" >&2 - exit 1 - fi - read_stdin "$tmpdir/$filename" - do_upload "$tmpdir/$filename" || exitcode=1 -else - if [ "$tar" ]; then - have_url= - for i in "$@"; do - if is_url "$i"; then - have_url=1 - fi - done - if [ "$have_url" ]; then - # TODO: support -t when passing URLs as arguments - printf "%s\n" "Error: -t is not yet supported when operating on a URL" >&2 - exit 1 - else - do_tar_upload "$@" || exitcode=1 - fi - else - for i in "$@"; do - if is_url "$i"; then - if [ "$multipaste" ]; then - if is_pastebin_url "$i"; then - multipaste_ids+=("$(id_from_arg "$i")") - continue - fi - fi - - cd $tmpdir - if ! request_helper d "$i" > "`basename "$i"`"; then - exitcode=1 - continue - fi - for f in *; do - if ! do_upload "$f"; then - exitcode=1 - fi - rm -f -- "$f" - done - else - do_upload "$i" || exitcode=1 - fi - done - fi - - if [ "$multipaste" ]; then - for url in $clipboard; do - id="$(id_from_arg "$url")" - multipaste_ids+=("$id") - done - - tmpfile=`mktemp "$tmpdir/data.XXXXXX"` - request_helper m "$pastebin/file/do_multipaste" > $tmpfile || exitcode=1 - - sed '$d' $tmpfile >&2 - url=`tail -1 $tmpfile`"$extension" - printf "%s\n" "$url" - if printf "%s" "$url" | grep -qE "^https?://"; then - clipboard="$url" - fi - fi -fi - -if [ "$clipboard" != "" ]; then - type $clipboard_cmd >/dev/null 2>&1 && printf "%s" "$clipboard" | nohup $clipboard_cmd >/dev/null 2>&1 -fi - -exit $exitcode - -#vim: set noet: |