All pastes #375582 Raw Edit

zlin

public shellscript v1 · immutable
#375582 ·published 2007-02-28 12:32 UTC
rendered paste body
#!/bin/bash# A Script that automates pasting to a number of pastebin services# relying only on bash v3, sed, coreutils (mktemp/sort/wc/whoami) and wget# Author: Bo Ørsted Andresen, bo.andresen@zlin.dk##########################################################################VERSION="1.9"### helper functions# show an error message and diedie() {	echo "$*" 1>&2	exit 1}# show that an option ${1} is not supported, run function that shows valid options ${3} and diefail() {	if [[ "${2}" == "service" ]]; then		echo "\"$1\" is not a supported $2." 1>&2	else		echo "\"$1\" is not a supported $2 for ${SERVICE}: $(get_recipient)." 1>&2	fi	echo 1>&2	${3} 1>&2	exit 1}# escape % (used for escaping), & (used as separator in POST data), + (used as space in POST data) and spaceescape() {	echo "$*" | sed -e 's|%|%25|g' -e 's|&|%26|g' -e 's|+|%2b|g' -e 's| |+|g'}	### defaults# The following defaults can be overridden in either /etc/wgetpaste or ~/.wgetpaste.# Only those four variables should be set in those files.## If add_to_clipboard() is defined as a function in one of those files it will be called with# the url where your paste can be seen as an argument. You may use xclip, xcut, klipper or# whatever your window manager provides for adding it to your clipboard.## Likewise if get_from_clipboard() is defined as a funciont in one of those files it will be# called to retrieve input from your clipboard when --xcut is used.[[ -f /etc/wgetpaste ]] && . /etc/wgetpaste[[ -f ~/.wgetpaste ]] && . ~/.wgetpasteDEFAULT_NICK="${DEFAULT_NICK:-$(whoami)}"DEFAULT_SERVICE="${DEFAULT_SERVICE:-rafb}"DEFAULT_LANGUAGE="${DEFAULT_LANGUAGE:-Plain Text}"### usageshow_usage() {	echo "Usage: $0 [options] [file]"	echo	echo "Options:"	echo "    -l, --language LANG           set language (defaults to \"${DEFAULT_LANGUAGE}\")"	echo "    -d, --description DESCRIPTION set description (defaults to \"stdin\" or filename)"	echo "    -n, --nick NICK               set nick (defaults to your username))"	echo "    -s, --service SERVICE         set service to use (defaults to \"${DEFAULT_SERVICE}\")"	echo	echo "    -S, --list-services           list supported pastebin services"	echo "    -L, --list-languages          list languages supported by the specified service"	echo	echo "    -x, --xcut                    read input from clipboard (requires configuration)"	echo	echo "    -v, --verbose                 show wget stderr output if no url is received"	echo "        --debug                   be *very* verbose (implies -v)"	echo	echo "    -h, --help                    show this help"	echo "        --version                 show version information"	echo	echo "Defaults can be overridden globally in /etc/wgetpaste or per user in ~/.wgetpaste."	echo "Only the vars DEFAULT_{NICK,SERVICE,LANGUAGE} should be set in those files."}### servicesSERVICES=(ca rafb sh)SERVICE_URLS=(http://pastebin.ca http://rafb.net/paste/paste.php http://sh.nu/p/)# 4 (base indentation) + max service length + 2 (space + dash)INDENTATION=10show_services() {	echo 'Services supported (case sensitive):'	for index in ${!SERVICES[*]}; do		echo "    ${SERVICES[index]} "$'\e'"[${INDENTATION}G- ${SERVICE_URLS[index]}"	done}verify_service() {	for index in ${!SERVICES[*]}; do		[[ "$*" == "${SERVICES[index]}" ]] && return 0	done	fail "$*" "service" "show_services"}### languages# rafbrafb_LANGUAGES=(C C89 C99 C++ C\# Java Pascal Perl PHP PL\/I Python Ruby SQL VB Plain\ Text)# ca - ordering is important here as their value is set as their number in the orderca_LANGUAGES=(Plain\ Text Asterisk\ Configuration C C++ PHP Perl Java VB C\# Ruby \Python Pascal mIRC PL/I XML SQL Scheme ActionScript Ada 	\Apache\ Configuration Assembly\ \(NASM\) ASP Bash CSS Delphi HTML\ 6\.0\ Strict JavaScript \LISP Lua Microprocessor\ ASM Objective\ C VB\.NET)show_languages() {	echo "Languages supported by ${SERVICE}: $(get_recipient) (case sensitive):"	case "${SERVICE}" in		ca | rafb )		for index in $(eval "echo \${!${SERVICE}_LANGUAGES[*]}"); do			echo "    $(eval "echo \${${SERVICE}_LANGUAGES[index]}")"		done | sort		;;		* )		echo 1>&2		echo "\"${SERVICE}\" has no support for any specific languages." 1>&2	esac}# this is in place because rafb.net (probably others too) rejects any paste with an invalid languageverify_language() {	case "${SERVICE}" in		ca )		let "i = 0"		for index in ${!ca_LANGUAGES[*]}; do			let "i = i +1"			[[ "${LANGUAGE}" == "${ca_LANGUAGES[index]}" ]] && LANGUAGE="${i}" && return 0		done		;;		rafb )		for index in ${!rafb_LANGUAGES[*]}; do			[[ "${LANGUAGE}" == "${rafb_LANGUAGES[index]}" ]] && return 0		done		;;		* )		[[ ! ${LANGUAGE_SET} ]] && return 0		;;	esac	fail "${LANGUAGE}" "language" "show_languages"}### Posting helper functions# get the url to post to for any given serviceget_recipient() {	for index in ${!SERVICES[*]}; do		[[ "${SERVICE}" == "${SERVICES[index]}" ]] && echo "${SERVICE_URLS[index]}" && return 0	done	echo "Failed to get url for \"${SERVICE}\"." 1>&2	exit 1}# print a warning if failure is predictable due to the mere size of the paste. sh seems to be the most reliable# service in that regard. for now no warning will be printed for that. note that this is only a warning printed.# it doesn't abort or anything.warn_size() {	print_warning() {		echo "Pasting > ${1} often tend to fail with ${SERVICE}. Use --verbose or --debug to see the"		echo "error output from wget if it fails. Alternatively use another pastebin service like e.g. sh."	}	case "${SERVICE}" in		rafb )		[[ ${SIZE} -gt 512000 ]] && print_warning "512 kb"		;;		ca )		[[ ${SIZE} -gt 1024000 ]] && print_warning "1 MB"		;;	esac}# POST datapost_data() {	case "${SERVICE}" in		ca )		echo "name=${NICK}&type=${LANGUAGE}&description=${DESCRIPTION}&expiry=${EXPIRATION}&s=Submit+Post&content=${INPUT}"		;;		rafb )		echo "nick=${NICK}&lang=${LANGUAGE}&desc=${DESCRIPTION}&cvt_tabs=${CVT_TABS}&text=${INPUT}"		;;		sh )		echo "poster=${NICK}&code=${INPUT}"		;;		* )		echo "\"${SERVICE}\" is not supported by ${FUNCNAME}()." 1>&2		exit 1		;;	esac}# indicate if ${SERVICE} needs stdout output from wget to get the resulting urlneed_stdout() {	case "${SERVICE}" in		# this service needs to use a regex to retrieve the url from stdout		ca )		return 0		;;		# these services read the reply from Location: which goes to stderr		rafb | sh )		return 1		;;		* )		echo "\"${SERVICE}\" is not supported by ${FUNCNAME}()." 1>&2		exit 1		;;	esac}# get the urlget_url() {	case "${SERVICE}" in		ca )		echo "$*" | sed -n 's|^.*content="[0-9]*;\(http://pastebin.ca/[0-9]*\)".*$|\1|p'		;;		rafb | sh )		echo "$*" | sed -n 's|^.*Location:\ \(http://[^\ ]\+\).*$|\1|p'		;;		* )		echo "\"${SERVICE}\" is not supported by ${FUNCNAME}()." 1>&2		exit 1		;;	esac}# verify that the pastebin service didn't return a known error url such as toofast.html from rafbverify_url() {	case "${SERVICE}" in		rafb )		if [[ "${URL}" == "http://rafb.net/p/toofast.html" ]]; then			echo "You must wait at least 10 seconds between each paste! Try again in 10 seconds." 1>&2			exit 1		fi		;;	esac}### read cli options# if you know a better option (like getopts) which provides the same features# please let me know how.while [[ ! -z "${1}" ]]; do	case "${1}" in		--debug )		DEBUG=true		set -x		shift		;;		--description=* )		[[ -z "${1#*=}" ]] && show_usage 1>&2 && exit 1		DESCRIPTION="$(escape "${1#*=}")"		shift		;;		-d | --description )		[[ -z "${2}" ]] && show_usage 1>&2 && exit 1		DESCRIPTION="$(escape "${2}")"		shift 2		;;		-h | --help )		show_usage		exit 0		;;		--language=* )		[[ -z "${1#*=}" ]] && show_usage 1>&2 && exit 1		LANGUAGE_SET=true		LANGUAGE="${1#*=}"		shift		;;		-l | --language )		[[ -z "${2}" ]] && show_usage 1>&2 && exit 1		LANGUAGE_SET=true		LANGUAGE="${2}"		shift 2		;;		-L | --list-languages )		LIST_LANGUAGES=true		shift		;;		--nick=* )		[[ -z "${1#*=}" ]] && show_usage 1>&2 && exit 1		NICK="$(escape "${1#*=}")"		shift		;;		-n | --nick )		[[ -z "${2}" ]] && show_usage 1>&2 && exit 1		NICK="$(escape "${2}")"		shift 2		;;		--service=* )		[[ -z "${1#*=}" ]] && show_usage 1>&2 && exit 1		verify_service "${1#*=}"		SERVICE="$(escape "${1#*=}")"		shift		;;		-s | --service )		[[ -z "${2}" ]] && show_usage 1>&2 && exit 1		verify_service "${2}"		SERVICE="$(escape "${2}")"		shift 2		;;		-S | --list-services )		show_services		exit 0		;;		-v | --verbose )		VERBOSE=true		shift		;;		--version )		echo "$0, version ${VERSION}"		exit 0		;;		-x | --xcut )		XCUT=true		SOURCE="xcut"		shift		;;		*)		if [[ -f "${1}" ]]; then			SOURCE="${1}"			shift		else			show_usage 1>&2			exit 1		fi		;;	esacdone### everything below this should be independent of which service is being used...# set default service, nick, source and tabs convertionSERVICE="${SERVICE:-${DEFAULT_SERVICE}}"NICK="${NICK:-$(escape "${DEFAULT_NICK}")}"SOURCE="${SOURCE:-/dev/stdin}"CVT_TABS="No"# show languages if requested (needs to be done after the right service is selected)[[ ${LIST_LANGUAGES} ]] && show_languages && exit 0# language needs to be verified before it is escaped but after service is selectedLANGUAGE="${LANGUAGE:-${DEFAULT_LANGUAGE}}"verify_languageLANGUAGE="$(escape "${LANGUAGE}")"# set default descriptionif [[ -z "${DESCRIPTION}" ]]; then	if [[ "${SOURCE}" == "/dev/stdin" ]]; then		DESCRIPTION="stdin"	else		DESCRIPTION="$(escape "${SOURCE}")"	fifi# handle the case where the input source (defaulting to /dev/stdin) isn't readable verboselyif [[ ! ${XCUT} ]] && [[ ! -r "${SOURCE}" ]]; then	echo "The input source: \"${SOURCE}\" is not readable. Please specify a readable input source." 1>&2	echo 1>&2	show_usage 1>&2	exit 1fi# read inputif [[ ${XCUT} ]]; then	if [[ "$(type -t get_from_clipboard)" == "function" ]]; then		INPUT="$(escape "$(get_from_clipboard)")"	else		echo "You need to define get_from_clipboard() in /etc/wgetpaste or ~/.wgetpaste to use --xcut." 1>&2		echo "If you want to use e.g. xclip simply emerge xclip and define it like this:" 1>&2		echo 1>&2		echo -e "get_from_clipboard() {\n    xclip -o\n}\n" 1>&2		echo "Likewise if you want the resulting url stored in your clipboard using e.g. xclip" 1>&2		echo "define it like this:" 1>&2		echo 1>&2		echo -e "add_to_clipboard() {\n    xclip \"\$*\"\n}\n" 1>&2		echo "Use whatever your window manager provides to alter your clipboard." 1>&2		exit 1	fielse	INPUT="$(escape "$( < "${SOURCE}" )")"fi[[ -z "${INPUT}" ]] && die "No input read. Nothing to paste. Aborting."# print a friendly warning if the size makes failure predictable for the specified pastebin service.SIZE=$(echo "${INPUT}" | wc -c)warn_size 1>&2# create temp file (wget is much more reliable reading large input from a file than from the cli directlyTEMPFILE="$(mktemp /tmp/wgetpaste.XXXXXX)"[[ -f "${TEMPFILE}" ]] || die "Failed to create a temporary file." 1>&2# write paste data to the temporary filepost_data > "${TEMPFILE}" || die "Failed to write to temporary file: \"${TEMPFILE}\"."# set recipientRECIPIENT="$(get_recipient)"# paste itWGET_ARGS="--tries=5 --timeout=60 --post-file=${TEMPFILE}"if ! need_stdout && [[ ! ${DEBUG} ]] && [[ -w /dev/null ]]; then	OUTPUT="$(wget -O /dev/null ${WGET_ARGS} ${RECIPIENT} 2>&1)"else	OUTPUT="$(wget -O - ${WGET_ARGS} ${RECIPIENT} 2>&1)"fi# clean temporary fileif [[ ! ${DEBUG} ]]; then	rm "${TEMPFILE}" || echo "Failed to remove temporary file: \"${TEMPFILE}\"." 1>&2else	echo "Left temporary file: \"${TEMPFILE}\" alone for debugging purposes."fi# get the urlURL="$(get_url "${OUTPUT}")"# verify that the pastebin service didn't return a known error url such as toofast.html from rafb# uses ${SERVICE} and ${URL}.verify_url# handle the case when there was no location returnedif [[ -z "${URL}" ]]; then	if [[ ${DEBUG} ]] || [[ ${VERBOSE} ]]; then		echo "Apparently nothing was received. Perhaps the connection failed." 1>&2		echo "${OUTPUT}" 1>&2	else		echo "Apparently nothing was received. Perhaps the connection failed. Enable --verbose or" 1>&2		echo "--debug to get the output from wget that can help diagnose it correctly." 1>&2	fi	exit 1fi# add_to_clipboard() may be defined in /etc/wgetpaste or ~/.wgetpaste and can be used to add# ${URL} to your clipboard using xclip, xcut, klipper or whatever your window manager provides# for that task.[[ "$(type -t add_to_clipboard)" == "function" ]] && add_to_clipboard "${URL}"echo "Your paste can be seen here: ${URL}"exit 0