You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

wgetpaste 22KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829
  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-2009 Bo Ørsted Andresen <bo.andresen@zlin.dk>
  5. # Distributed in the public domain. Do with it whatever you want.
  6. VERSION="2.18"
  7. # don't inherit LANGUAGE from the env
  8. unset LANGUAGE
  9. # escape and new line characters
  10. E=$'\e'
  11. N=$'\n'
  12. ### services
  13. SERVICES="ca codepad dpaste osl pocoo"
  14. # ca
  15. ENGINE_ca=ca
  16. URL_ca="http://pastebin.ca/"
  17. SIZE_ca="1024000 1%MB"
  18. # codepad
  19. ENGINE_codepad=codepad
  20. URL_codepad="http://codepad.org/"
  21. SIZE_codepad="64000 64%KB"
  22. # dpaste
  23. ENGINE_dpaste=dpaste
  24. URL_dpaste="http://dpaste.com/"
  25. SIZE_dpaste="25000 25%kB"
  26. DESCRIPTION_SIZE_dpaste="50"
  27. DEFAULT_EXPIRATION_dpaste="30 days"
  28. # osl
  29. ENGINE_osl=osl
  30. URL_osl="http://pastebin.osuosl.org/ pastebin.php"
  31. # pocoo
  32. ENGINE_pocoo=pocoo
  33. URL_pocoo="http://paste.pocoo.org/"
  34. # tinyurl
  35. ENGINE_tinyurl=tinyurl
  36. URL_tinyurl="http://tinyurl.com/ api-create.php"
  37. REGEX_RAW_tinyurl='s|^\(http://[^/]*/\)\([[:alnum:]]*\)$|\1\2|'
  38. ### engines
  39. # ca
  40. LANGUAGES_ca="Plain%Text Asterisk%Configuration C C++ PHP Perl Java VB C# Ruby Python Pascal \
  41. mIRC PL/I XML SQL Scheme ActionScript Ada Apache%Configuration Assembly%(NASM) ASP Bash CSS \
  42. Delphi HTML%4.0%Strict JavaScript LISP Lua Microprocessor%ASM Objective%C VB.NET"
  43. LANGUAGE_COUNT_ca=0
  44. EXPIRATIONS_ca="Never 5%minutes 10%minutes 15%minutes 30%minutes 45%minutes 1%hour 2%hours \
  45. 4%hours 8%hours 12%hours 1%day 2%days 3%days 1%week 2%weeks 3%weeks 1%month 2%months \
  46. 3%months 4%months 5%months 6%months 1%year"
  47. POST_ca="s=Submit+Post name description type expiry % content"
  48. REGEX_URL_ca='s|^.*content="[0-9]*;\(http://[^/]*/[0-9]*\)".*$|\1|p'
  49. REGEX_RAW_ca='s|^\(http://[^/]*/\)\([0-9]*\)$|\1raw/\2|'
  50. # codepad
  51. LANGUAGES_codepad="C C++ D Haskell Lua OCaml PHP Perl Plain%Text Python Ruby Scheme Tcl"
  52. POST_codepad="submit % % lang % % code"
  53. REGEX_URL_codepad='s|^--.*\(http://codepad.org/[^ ]\+\)|\1|p'
  54. REGEX_RAW_codepad='s|^\(http://[^/]*/\)\([[:alnum:]]*\)$|\1\2/raw.rb|'
  55. # dpaste
  56. LANGUAGES_dpaste="Plain%Text Apache%Config Bash CSS Diff Django%Template/HTML Haskell JavaScript \
  57. Python Python%Interactive/Traceback Ruby Ruby%HTML%(ERB) SQL XML"
  58. LANGUAGE_VALUES_dpaste="% Apache Bash Css Diff DjangoTemplate Haskell JScript Python PythonConsole \
  59. Ruby Rhtml Sql Xml"
  60. EXPIRATIONS_dpaste="30%days 30%days%after%last%view"
  61. EXPIRATION_VALUES_dpaste="off on"
  62. POST_dpaste="submit=Paste+it poster title language hold % content"
  63. REGEX_RAW_dpaste='s|^\(http://[^/]*/\)[^0-9]*\([0-9]*/\)$|\1\2plain/|'
  64. # osl
  65. LANGUAGES_osl="Plain%Text ActionScript Ada Apache%Log%File AppleScript Assembly%(NASM) \
  66. ASP Bash C C%for%Macs CAD%DCL CAD%Lisp C++ C# ColdFusion CSS D Delphi Diff DOS Eiffel Fortran \
  67. FreeBasic Game%Maker HTML%4.0%Strict INI%file Java Javascript Lisp Lua MatLab Microprocessor%ASM \
  68. MySQL NullSoft%Installer Objective%C OCaml Openoffice.org%BASIC Oracle%8 Pascal Perl PHP Python \
  69. QBasic Robots.txt Ruby Scheme Smarty SQL TCL VB VB.NET VisualFoxPro XML"
  70. LANGUAGE_VALUES_osl="text actionscript ada apache applescript asm asp bash c c_mac caddcl \
  71. cadlisp cpp csharp cfm css d delphi diff dos eiffel fortran freebasic gml html4strict ini java \
  72. javascript lisp lua matlab mpasm mysql nsis objc ocaml oobas oracle8 pascal perl php python \
  73. qbasic robots ruby scheme smarty sql tcl vb vbnet visualfoxpro xml"
  74. EXPIRATIONS_osl="Never 1%day 1%month"
  75. EXPIRATION_VALUES_osl="f d m"
  76. POST_osl="paste=Send poster % format expiry % code2"
  77. REGEX_RAW_osl='s|^\(http://[^/]*/\)\([0-9]*\)$|\1pastebin.php?dl=\2|'
  78. # pocoo
  79. LANGUAGES_pocoo="Apache%Config%(.htaccess) Bash Batch%(.bat) Boo C C# C++ Clojure Creole%Wiki CSS \
  80. CSV D Debian%control-files Django%/%Jinja%Templates Dylan Erlang eRuby%/%rhtml GAS GCC%Messages \
  81. Genshi%Templates Gettext%catalogs GL%Shader%language Haskell HTML INI%File Interactive%Ruby IO \
  82. IRC%Logs Java javac%Messages JavaScript JSP Lighttpd Literate%Haskell LLVM Lua Mako%Templates Matlab \
  83. Matlab%Session MiniD Multi-File Myghty%Templates MySQL Nasm Nginx Object-Pascal OCaml Perl PHP \
  84. PHP%(inline) Povray Python Python%Console%Sessions Python%Tracebacks reStructuredText Ruby Scala \
  85. Scheme Smalltalk Smarty sources.list SQL SquidConf TeX%/%LaTeX Plain%Text Unified%Diff Vim XML XSLT YAML"
  86. LANGUAGE_VALUES_pocoo="apache bash bat boo c csharp cpp clojure creole css csv d control html+django \
  87. dylan erlang rhtml gas gcc-messages html+genshi gettext glsl haskell html ini irb io irc java \
  88. javac-messages js jsp lighttpd literate-haskell llvm lua html+mako matlab matlabsession minid multi \
  89. html+myghty mysql nasm nginx objectpascal ocaml perl html+php php povray python pycon pytb rst ruby \
  90. scala scheme smalltalk smarty sourceslist sql squidconf tex text diff vim xml xslt yaml"
  91. POST_pocoo="submit=Paste! % % language % % code"
  92. REGEX_RAW_pocoo='s|^\(http://[^/]*/\)show\(/[0-9]*/\)$|\1raw\2|'
  93. ### errors
  94. die() {
  95. echo "$@" >&2
  96. exit 1
  97. }
  98. requiredarg() {
  99. [[ -z $2 ]] && die "$0: option $1 requires an argument"
  100. ((args++))
  101. }
  102. notreadable() {
  103. die "The input source: \"$1\" is not readable. Please specify a readable input source."
  104. }
  105. noxclip() {
  106. cat <<EOF >&2
  107. Could not find xclip on your system. In order to use --x$1 you must either
  108. emerge x11-misc/xclip or define x_$1() globally in /etc/wgetpaste.conf or
  109. per user in ~/.wgetpaste.conf to use another program (such as e.g. xcut or
  110. klipper) to $2 your clipboard.
  111. EOF
  112. exit 1
  113. }
  114. ### conversions
  115. # escape % (used for escaping), & (used as separator in POST data), + (used as space in POST data), space and ;
  116. escape() {
  117. sed -e 's|%|%25|g' -e 's|&|%26|g' -e 's|+|%2b|g' -e 's|;|%3b|g' -e 's| |+|g' <<< "$*" || die "sed failed"
  118. }
  119. # if possible convert URL to raw
  120. converttoraw() {
  121. local regex
  122. regex=REGEX_RAW_$ENGINE
  123. if [[ -n ${!regex} ]]; then
  124. RAWURL=$(sed -e "${!regex}" <<< "$URL")
  125. [[ -n $RAWURL ]] && return 0
  126. echo "Convertion to raw url failed." >&2
  127. else
  128. echo "Raw download of pastes is not supported by $(getrecipient)." >&2
  129. fi
  130. return 1
  131. }
  132. ### verification
  133. verifyservice() {
  134. for s in $SERVICES; do
  135. [[ $s == $* ]] && return 0
  136. done
  137. echo "\"$*\" is not a supported service.$N" >&2
  138. showservices >&2
  139. exit 1
  140. }
  141. verifylanguage() {
  142. local i j l lang count v values
  143. lang=LANGUAGES_$ENGINE
  144. count=LANGUAGE_COUNT_$ENGINE
  145. values=LANGUAGE_VALUES_$ENGINE
  146. if [[ -n ${!lang} ]]; then
  147. ((i=0))
  148. for l in ${!lang}; do
  149. if [[ $LANGUAGE == ${l//\%/ } ]]; then
  150. if [[ -n ${!count} ]]; then
  151. ((LANGUAGE=i+1))
  152. elif [[ -n ${!values} ]]; then
  153. ((j=0))
  154. for v in ${!values}; do
  155. if [[ i -eq j ]]; then
  156. if [[ ${v} == \% ]]; then
  157. LANGUAGE=
  158. else
  159. LANGUAGE=${v//\%/ }
  160. fi
  161. break
  162. fi
  163. ((j++))
  164. done
  165. fi
  166. return 0
  167. fi
  168. ((i++))
  169. done
  170. else
  171. [[ $LANGUAGESET = 0 ]] || return 0
  172. fi
  173. echo "\"$LANGUAGE\" is not a supported language for $(getrecipient).$N" >&2
  174. showlanguages >&2
  175. exit 1
  176. }
  177. verifyexpiration() {
  178. local i j e expiration count v values
  179. expiration=EXPIRATIONS_$ENGINE
  180. count=EXPIRATION_COUNT_$ENGINE
  181. values=EXPIRATION_VALUES_$ENGINE
  182. if [[ -n ${!expiration} ]]; then
  183. ((i=0))
  184. for e in ${!expiration}; do
  185. if [[ ${EXPIRATION} == ${e//\%/ } ]]; then
  186. if [[ -n ${!count} ]]; then
  187. ((EXPIRATION=i+1))
  188. elif [[ -n {!values} ]]; then
  189. ((j=0))
  190. for v in ${!values}; do
  191. if [[ i -eq j ]]; then
  192. if [[ ${v} == \% ]]; then
  193. EXPIRATION=
  194. else
  195. EXPIRATION=${v//\%/ }
  196. fi
  197. break
  198. fi
  199. ((j++))
  200. done
  201. fi
  202. return 0
  203. fi
  204. ((i++))
  205. done
  206. else
  207. [[ $EXPIRATIONSET = 0 ]] || return 0
  208. fi
  209. echo "\"$EXPIRATION\" is not a supported expiration option for $(getrecipient).$N" >&2
  210. showexpirations >&2
  211. exit 1
  212. }
  213. # verify that the pastebin service did not return a known error url. otherwise print a helpful error message
  214. verifyurl() {
  215. dieifknown() {
  216. [[ -n ${!1%% *} && ${!1%% *} == $URL ]] && die "${!1#* }"
  217. }
  218. local t
  219. for t in ${!TOO*}; do
  220. [[ $t == TOO*_$SERVICE ]] && dieifknown "$t"
  221. done
  222. }
  223. # print a warning if failure is predictable due to the mere size of the paste. note that this is only a warning
  224. # printed. it does not abort.
  225. warnings() {
  226. warn() {
  227. if [[ -n $2 && $1 -gt $2 ]]; then
  228. echo "Pasting > ${3//\%/ } often tend to fail with $SERVICE. Use --verbose or --debug to see the"
  229. echo "error output from wget if it fails. Alternatively use another pastebin service."
  230. fi
  231. }
  232. local size lines
  233. size=SIZE_$SERVICE
  234. warn "$SIZE" "${!size% *}" "${!size#* }"
  235. lines=LINES_$SERVICE
  236. warn "$LINES" "${!lines}" "${!lines} lines"
  237. }
  238. ### input
  239. getfilenames() {
  240. for f in "$@"; do
  241. [[ -f $f ]] || die "$0: $f No such file found."
  242. SOURCE="files"
  243. FILES[${#FILES[*]}]="$f"
  244. done
  245. }
  246. x_cut() {
  247. if [[ -x $(type -P xclip) ]]; then
  248. xclip -o || die "xclip failed."
  249. else
  250. noxclip cut "read from"
  251. fi
  252. }
  253. ### output
  254. usage() {
  255. cat <<EOF
  256. Usage: $0 [options] [file[s]]
  257. Options:
  258. -l, --language LANG set language (defaults to "$DEFAULT_LANGUAGE")
  259. -d, --description DESCRIPTION set description (defaults to "stdin" or filename)
  260. -n, --nick NICK set nick (defaults to your username)
  261. -s, --service SERVICE set service to use (defaults to "$DEFAULT_SERVICE")
  262. -e, --expiration EXPIRATION set when it should expire (defaults to "$DEFAULT_EXPIRATION")
  263. -S, --list-services list supported pastebin services
  264. -L, --list-languages list languages supported by the specified service
  265. -E, --list-expiration list expiration setting supported by the specified service
  266. -u, --tinyurl URL convert input url to tinyurl
  267. -c, --command COMMAND paste COMMAND and the output of COMMAND
  268. -i, --info append the output of \`$INFO_COMMAND\`
  269. -I, --info-only paste the output of \`$INFO_COMMAND\` only
  270. -x, --xcut read input from clipboard (requires x11-misc/xclip)
  271. -X, --xpaste write resulting url to the X primary selection buffer (requires x11-misc/xclip)
  272. -C, --xclippaste write resulting url to the X clipboard selection buffer (requires x11-misc/xclip)
  273. -r, --raw show url for the raw paste (no syntax highlighting or html)
  274. -t, --tee use tee to show what is being pasted
  275. -v, --verbose show wget stderr output if no url is received
  276. --completions emit output suitable for shell completions (only affects --list-*)
  277. --debug be *very* verbose (implies -v)
  278. -h, --help show this help
  279. -g, --ignore-configs ignore /etc/wgetpaste.conf, ~/.wgetpaste.conf etc.
  280. --version show version information
  281. Defaults (DEFAULT_{NICK,LANGUAGE,EXPIRATION}[_\${SERVICE}] and DEFAULT_SERVICE)
  282. can be overridden globally in /etc/wgetpaste.conf or /etc/wgetpaste.d/*.conf or
  283. per user in any of ~/.wgetpaste.conf or ~/.wgetpaste.d/*.conf.
  284. EOF
  285. }
  286. showservices() {
  287. local max s IND INDV engine url d
  288. if [[ -n $COMPLETIONS ]]; then
  289. for s in $SERVICES; do
  290. if [[ -n $VERBOSE ]]; then
  291. d=URL_$s && echo "$s:${!d% *}"
  292. else
  293. echo "$s"
  294. fi
  295. done
  296. exit 0
  297. fi
  298. echo "Services supported: (case sensitive):"
  299. max=4
  300. for s in $SERVICES; do
  301. [[ ${#s} -gt $max ]] && max=${#s}
  302. done
  303. ((IND=6+max))
  304. if [[ $VERBOSE ]]; then
  305. max=0
  306. for s in $SERVICES; do
  307. s=URL_$s
  308. s=${!s% *}
  309. [[ ${#s} -gt $max ]] && max=${#s}
  310. done
  311. ((INDV=3+max+IND))
  312. engine=" $E[${INDV}G| Pastebin engine:"
  313. fi
  314. echo " Name: $E[${IND}G| Url:$engine"
  315. echo -ne " "; for((s=3;s<${INDV:-${IND}}+17;s++)); do (( $s == IND-1 || $s == INDV-1 )) && echo -ne "|" || echo -ne "="; done; echo
  316. for s in $SERVICES; do
  317. [[ $s = $DEFAULT_SERVICE ]] && d="*" || d=" "
  318. [[ $VERBOSE ]] && engine=ENGINE_$s && engine="$E[${INDV}G| ${!engine}"
  319. url=URL_$s
  320. url=${!url% *}
  321. echo " $d$s $E[${IND}G| $url$engine"
  322. done | sort
  323. }
  324. printlist() {
  325. while [[ -n $1 ]]; do
  326. echo "${1//\%/ }"
  327. shift
  328. done
  329. }
  330. showlanguages() {
  331. local l lang d
  332. lang=LANGUAGES_$ENGINE
  333. [[ -n $COMPLETIONS ]] && printlist ${!lang} | sort && exit 0
  334. echo "Languages supported by $(getrecipient) (case sensitive):"
  335. [[ -z ${!lang} ]] && echo "$N\"$ENGINE\" has no support for setting language." >&2 && exit 1
  336. for l in ${!lang}; do
  337. [[ ${l//\%/ } = $DEFAULT_LANGUAGE ]] && d="*" || d=" "
  338. echo " $d${l//\%/ }"
  339. done | sort
  340. }
  341. showexpirations() {
  342. local e expiration info d
  343. expiration=EXPIRATIONS_$ENGINE
  344. [[ -n $COMPLETIONS ]] && printlist ${!expiration} && exit 0
  345. echo "Expiration options supported by $(getrecipient) (case sensitive):"
  346. info=EXPIRATION_INFO_$SERVICE
  347. [[ -z ${!expiration} ]] && echo "$N${!info}\"$ENGINE\" has no support for setting expiration." >&2 && exit 1
  348. for e in ${!expiration}; do
  349. [[ ${e//\%/ } = $DEFAULT_EXPIRATION ]] && d="*" || d=" "
  350. echo " $d${e//\%/ }"
  351. done
  352. }
  353. showurl() {
  354. echo "Your ${2}paste can be seen here: $1"
  355. [[ $XPASTE ]] && x_paste "$1" primary
  356. [[ $XCLIPPASTE ]] && x_paste "$1" clipboard
  357. }
  358. x_paste() {
  359. if [[ -x $(type -P xclip) ]]; then
  360. echo -n "$1" | xclip -selection $2 -loops 10 &>/dev/null || die "xclip failed."
  361. else
  362. noxclip paste "write to"
  363. fi
  364. }
  365. ### Posting helper functions
  366. # get the url to post to
  367. getrecipient() {
  368. local urls target serv
  369. for s in $SERVICES tinyurl; do
  370. if [[ $s == $SERVICE ]]; then
  371. urls=URL_$SERVICE
  372. if [[ RAW == $1 ]]; then
  373. [[ ${!urls} = ${!urls#* } ]] || target=${!urls#* }
  374. else
  375. serv="$SERVICE: "
  376. fi
  377. echo "${serv}${!urls% *}${target}"
  378. return 0
  379. fi
  380. done
  381. die "Failed to get url for \"$SERVICE\"."
  382. }
  383. # generate POST data
  384. postdata() {
  385. local post nr extra f
  386. post=POST_$ENGINE
  387. nr=${!post//[^ ]}
  388. [[ 6 = ${#nr} ]] || die "\"${SERVICE}\" is not supported by ${FUNCNAME}()."
  389. extra=${!post%% *}
  390. [[ '%' = $extra ]] || echo -n "$extra&"
  391. e() {
  392. post="$1"
  393. shift
  394. while [[ -n $1 ]]; do
  395. f=${post%% *}
  396. [[ '%' != $f ]] && echo -n "$f=${!1}" && [[ $# -gt 1 ]] && echo -n "&"
  397. shift
  398. post=${post#$f }
  399. done
  400. }
  401. e "${!post#$extra }" NICK DESCRIPTION LANGUAGE EXPIRATION CVT_TABS INPUT
  402. }
  403. # get url from response from server
  404. geturl() {
  405. local regex
  406. regex=REGEX_URL_$ENGINE
  407. if [[ -n ${!regex} ]]; then
  408. [[ needstdout = $1 ]] && return 0
  409. sed -n -e "${!regex}" <<< "$*"
  410. else
  411. [[ needstdout = $1 ]] && return 1
  412. sed -n -e 's|^.*Location: \(http://[^ ]*\).*$|\1|p' <<< "$*"
  413. fi
  414. }
  415. ### read cli options
  416. # separate groups of short options. replace --foo=bar with --foo bar
  417. while [[ -n $1 ]]; do
  418. case "$1" in
  419. -- )
  420. for arg in "$@"; do
  421. ARGS[${#ARGS[*]}]="$arg"
  422. done
  423. break
  424. ;;
  425. --debug )
  426. set -x
  427. DEBUG=0
  428. ;;
  429. --*=* )
  430. ARGS[${#ARGS[*]}]="${1%%=*}"
  431. ARGS[${#ARGS[*]}]="${1#*=}"
  432. ;;
  433. --* )
  434. ARGS[${#ARGS[*]}]="$1"
  435. ;;
  436. -* )
  437. for shortarg in $(sed -e 's|.| -&|g' <<< "${1#-}"); do
  438. ARGS[${#ARGS[*]}]="$shortarg"
  439. done
  440. ;;
  441. * )
  442. ARGS[${#ARGS[*]}]="$1"
  443. esac
  444. shift
  445. done
  446. # set the separated options as input options.
  447. set -- "${ARGS[@]}"
  448. while [[ -n $1 ]]; do
  449. ((args=1))
  450. case "$1" in
  451. -- )
  452. shift && getfilenames "$@" && break
  453. ;;
  454. -c | --command )
  455. requiredarg "$@"
  456. SOURCE="command"
  457. COMMANDS[${#COMMANDS[*]}]="$2"
  458. ;;
  459. --completions )
  460. COMPLETIONS=0
  461. ;;
  462. -d | --description )
  463. requiredarg "$@"
  464. DESCRIPTION="$2"
  465. ;;
  466. -e | --expiration )
  467. requiredarg "$@"
  468. EXPIRATIONSET=0
  469. EXPIRATION="$2"
  470. ;;
  471. -E | --list-expiration )
  472. LISTEXPIRATION=0
  473. ;;
  474. -h | --help )
  475. USAGE=0
  476. ;;
  477. -g | --ignore-configs )
  478. IGNORECONFIGS=0
  479. ;;
  480. -i | --info )
  481. INFO=0
  482. ;;
  483. -I | --info-only )
  484. SOURCE=info
  485. ;;
  486. -l | --language )
  487. requiredarg "$@"
  488. LANGUAGESET=0
  489. LANGUAGE="$2"
  490. ;;
  491. -L | --list-languages )
  492. LISTLANGUAGES=0
  493. ;;
  494. -n | --nick )
  495. requiredarg "$@"
  496. NICK=$(escape "$2")
  497. ;;
  498. -r | --raw )
  499. RAW=0
  500. ;;
  501. -s | --service )
  502. requiredarg "$@"
  503. SERVICESET="$2"
  504. ;;
  505. -S | --list-services )
  506. SHOWSERVICES=0
  507. ;;
  508. -t | --tee )
  509. TEE=0
  510. ;;
  511. -u | --tinyurl )
  512. requiredarg "$@"
  513. SERVICE=tinyurl
  514. SOURCE="url"
  515. INPUTURL="$2"
  516. ;;
  517. -v | --verbose )
  518. VERBOSE=0
  519. ;;
  520. --version )
  521. echo "$0, version $VERSION" && exit 0
  522. ;;
  523. -x | --xcut )
  524. SOURCE=xcut
  525. ;;
  526. -X | --xpaste )
  527. XPASTE=0
  528. ;;
  529. -C | --xclippaste )
  530. XCLIPPASTE=0
  531. ;;
  532. -* )
  533. die "$0: unrecognized option \`$1'"
  534. ;;
  535. *)
  536. getfilenames "$1"
  537. ;;
  538. esac
  539. shift $args
  540. done
  541. ### defaults
  542. load_configs() {
  543. if [[ ! $IGNORECONFIGS ]]; then
  544. # compatibility code
  545. local f deprecated=
  546. for f in {/etc/,~/.}wgetpaste{.d/*.bash,}; do
  547. if [[ -f $f ]]; then
  548. if [[ -z $deprecated ]]; then
  549. echo "The config files for wgetpaste have changed to *.conf.$N" >&2
  550. deprecated=0
  551. fi
  552. echo "Please move ${f} to ${f/%.bash/.conf}" >&2
  553. source "$f" || die "Failed to source $f"
  554. fi
  555. done
  556. [[ -n $deprecated ]] && echo >&2
  557. # new locations override old ones in case they collide
  558. for f in {/etc/,~/.}wgetpaste{.d/*,}.conf; do
  559. if [[ -f $f ]]; then
  560. source "$f" || die "Failed to source $f"
  561. fi
  562. done
  563. fi
  564. }
  565. load_configs
  566. [[ $SERVICESET ]] && verifyservice "$SERVICESET" && SERVICE=$(escape "$SERVICESET")
  567. DEFAULT_NICK=${DEFAULT_NICK:-$(whoami)} || die "whoami failed"
  568. DEFAULT_SERVICE=${DEFAULT_SERVICE:-pocoo}
  569. DEFAULT_LANGUAGE=${DEFAULT_LANGUAGE:-Plain Text}
  570. DEFAULT_EXPIRATION=${DEFAULT_EXPIRATION:-1 month}
  571. SERVICE=${SERVICE:-${DEFAULT_SERVICE}}
  572. ENGINE=ENGINE_$SERVICE
  573. ENGINE="${!ENGINE}"
  574. default="DEFAULT_NICK_$SERVICE" && [[ -n ${!default} ]] && DEFAULT_NICK=${!default}
  575. default="DEFAULT_LANGUAGE_$SERVICE" && [[ -n ${!default} ]] && DEFAULT_LANGUAGE=${!default}
  576. default="DEFAULT_EXPIRATION_$SERVICE" && [[ -n ${!default} ]] && DEFAULT_EXPIRATION=${!default}
  577. NICK=${NICK:-$(escape "${DEFAULT_NICK}")}
  578. [[ -z $SOURCE ]] && SOURCE="stdin"
  579. CVT_TABS=No
  580. INFO_COMMAND=${INFO_COMMAND:-"emerge --info"}
  581. INFO_ARGS=${INFO_ARGS:-"--ignore-default-opts"}
  582. ### everything below this should be independent of which service is being used...
  583. # show listings if requested
  584. [[ $USAGE ]] && usage && exit 0
  585. [[ $SHOWSERVICES ]] && showservices && exit 0
  586. [[ $LISTLANGUAGES ]] && showlanguages && exit 0
  587. [[ $LISTEXPIRATION ]] && showexpirations && exit 0
  588. # language and expiration need to be verified before they are escaped but after service and defaults
  589. # have been selected
  590. LANGUAGE=${LANGUAGE:-${DEFAULT_LANGUAGE}}
  591. verifylanguage
  592. LANGUAGE=$(escape "$LANGUAGE")
  593. EXPIRATION=${EXPIRATION:-${DEFAULT_EXPIRATION}}
  594. verifyexpiration
  595. EXPIRATION=$(escape "$EXPIRATION")
  596. # set prompt
  597. if [[ 0 -eq $UID ]]; then
  598. PS1="#"
  599. else
  600. PS1=$
  601. fi
  602. # set default description
  603. size=DESCRIPTION_SIZE_$SERVICE
  604. if [[ -z $DESCRIPTION ]]; then
  605. case "$SOURCE" in
  606. info )
  607. DESCRIPTION="$PS1 $INFO_COMMAND;"
  608. ;;
  609. command )
  610. DESCRIPTION="$PS1"
  611. for c in "${COMMANDS[@]}"; do
  612. DESCRIPTION="$DESCRIPTION $c;"
  613. done
  614. ;;
  615. files )
  616. DESCRIPTION="${FILES[@]}"
  617. ;;
  618. * )
  619. DESCRIPTION="$SOURCE"
  620. ;;
  621. esac
  622. if [[ -n ${!size} && ${#DESCRIPTION} -gt ${!size} ]]; then
  623. DESCRIPTION="${DESCRIPTION: -${!size}}"
  624. fi
  625. else
  626. if [[ -n ${!size} && ${#DESCRIPTION} -gt ${!size} ]]; then
  627. die "Your description (${#DESCRIPTION} bytes) is too long. Shorten it to fit within ${!size} bytes."
  628. fi
  629. fi
  630. # create tmpfile for use with tee
  631. if [[ $TEE ]]; then
  632. TMPF=$(mktemp /tmp/wgetpaste.XXXXXX)
  633. [[ -f $TMPF ]] || die "Could not create a temporary file for use with tee."
  634. fi
  635. # read input
  636. case "$SOURCE" in
  637. url )
  638. INPUT="${INPUTURL}"
  639. ;;
  640. command )
  641. for c in "${COMMANDS[@]}"; do
  642. if [[ $TEE ]]; then
  643. echo "$PS1 $c$N$(bash -c "$c" 2>&1)$N" | tee -a "$TMPF"
  644. else
  645. INPUT="$INPUT$PS1 $c$N$(bash -c "$c" 2>&1)$N$N"
  646. fi
  647. done
  648. ;;
  649. info )
  650. if [[ $TEE ]]; then
  651. echo "$PS1 $INFO_COMMAND$N$($INFO_COMMAND $INFO_ARGS 2>&1)" | tee "$TMPF"
  652. else
  653. INPUT="$PS1 $INFO_COMMAND$N$($INFO_COMMAND $INFO_ARGS 2>&1)"
  654. fi
  655. ;;
  656. xcut )
  657. if [[ $TEE ]]; then
  658. x_cut | tee "$TMPF"
  659. else
  660. INPUT="$(x_cut)"
  661. fi
  662. ;;
  663. stdin )
  664. if [[ $TEE ]]; then
  665. tee "$TMPF"
  666. else
  667. INPUT="$(cat)"
  668. fi
  669. ;;
  670. files )
  671. if [[ ${#FILES[@]} -gt 1 ]]; then
  672. for f in "${FILES[@]}"; do
  673. [[ -r $f ]] || notreadable "$f"
  674. if [[ $TEE ]]; then
  675. echo "$PS1 cat $f$N$(<"$f")$N" | tee -a "$TMPF"
  676. else
  677. INPUT="$INPUT$PS1 cat $f$N$(<"$f")$N$N"
  678. fi
  679. done
  680. else
  681. [[ -r $FILES ]] || notreadable "$FILES"
  682. if [[ $TEE ]]; then
  683. tee "$TMPF" < "$FILES"
  684. else
  685. INPUT=$(<"$FILES")
  686. fi
  687. fi
  688. ;;
  689. esac
  690. NOINPUT="No input read. Nothing to paste. Aborting."
  691. if [[ $TEE ]]; then
  692. [[ 0 -eq $(wc -c < "$TMPF") ]] && die "$NOINPUT"
  693. else
  694. [[ -z $INPUT ]] && die "$NOINPUT"
  695. fi
  696. # append info if needed
  697. if [[ $INFO ]]; then
  698. DESCRIPTION="$DESCRIPTION $PS1 $INFO_COMMAND;"
  699. if [[ $TEE ]]; then
  700. echo "$N$PS1 $INFO_COMMAND$N$($INFO_COMMAND $INFO_ARGS 2>&1)" | tee -a "$TMPF"
  701. else
  702. INPUT="$INPUT$N$PS1 $INFO_COMMAND$N$($INFO_COMMAND $INFO_ARGS 2>&1)"
  703. fi
  704. fi
  705. # now that tee has done its job read data into INPUT
  706. [[ $TEE ]] && INPUT=$(<"$TMPF") && echo
  707. # escape DESCRIPTION and INPUT
  708. DESCRIPTION=$(escape "$DESCRIPTION")
  709. INPUT=$(escape "$INPUT")
  710. # print friendly warnings if max sizes have been specified for the pastebin service and the size exceeds that
  711. SIZE=$(wc -c <<< "$INPUT")
  712. LINES=$(wc -l <<< "$INPUT")
  713. warnings >&2
  714. # set recipient
  715. RECIPIENT=$(getrecipient RAW)
  716. if [[ $SERVICE == tinyurl ]]; then
  717. URL=$(LC_ALL=C wget -qO - "$RECIPIENT?url=$INPUT")
  718. else
  719. # create temp file (wget is much more reliable reading
  720. # large input via --post-file rather than --post-data)
  721. [[ -f $TMPF ]] || TMPF=$(mktemp /tmp/wgetpaste.XXXXXX)
  722. if [[ -f $TMPF ]]; then
  723. postdata > "$TMPF" || die "Failed to write to temporary file: \"$TMPF\"."
  724. WGETARGS="--post-file=$TMPF"
  725. else
  726. # fall back to using --post-data if the temporary file could not be created
  727. # TABs and new lines need to be escaped for wget to interpret it as one string
  728. WGETARGS="--post-data=$(postdata | sed -e 's|$|%0a|g' -e 's|\t|%09|g' | tr -d '\n')"
  729. fi
  730. # paste it
  731. WGETARGS="--tries=5 --timeout=60 $WGETARGS"
  732. if geturl needstdout || [[ $DEBUG || ! -w /dev/null ]]; then
  733. OUTPUT=$(LC_ALL=C wget -O - $WGETARGS $RECIPIENT 2>&1)
  734. else
  735. OUTPUT=$(LC_ALL=C wget -O /dev/null $WGETARGS $RECIPIENT 2>&1)
  736. fi
  737. # clean temporary file if it was created
  738. if [[ -f $TMPF ]]; then
  739. if [[ $DEBUG ]]; then
  740. echo "Left temporary file: \"$TMPF\" alone for debugging purposes."
  741. else
  742. rm "$TMPF" || echo "Failed to remove temporary file: \"$TMPF\"." >&2
  743. fi
  744. fi
  745. # get the url
  746. URL=$(geturl "$OUTPUT")
  747. fi
  748. # verify that the pastebin service did not return a known error url such as toofast.html from rafb
  749. verifyurl
  750. # handle the case when there was no location returned
  751. if [[ -z $URL ]]; then
  752. if [[ $DEBUG || $VERBOSE ]]; then
  753. die "Apparently nothing was received. Perhaps the connection failed.$N$OUTPUT"
  754. else
  755. echo "Apparently nothing was received. Perhaps the connection failed. Enable --verbose or" >&2
  756. die "--debug to get the output from wget that can help diagnose it correctly."
  757. fi
  758. fi
  759. # converttoraw() sets RAWURL upon success.
  760. if [[ $RAW ]] && converttoraw; then
  761. showurl "$RAWURL" "raw "
  762. else
  763. showurl "$URL"
  764. fi
  765. exit 0