From: mwolson_admin Date: Sun, 22 Jun 2008 23:42:09 +0000 (-0400) Subject: Initial check-in of Amazon S3 helper scripts. X-Git-Url: http://git.hcoop.net/clinton/scripts.git/commitdiff_plain/7f2282a74f5b371ce22c5f7b5b334012ffcf2362 Initial check-in of Amazon S3 helper scripts. --- diff --git a/s3-common-functions b/s3-common-functions new file mode 100644 index 0000000..4d035ca --- /dev/null +++ b/s3-common-functions @@ -0,0 +1,334 @@ +#! /usr/bin/env bash +cat > /dev/null << EndOfLicence +s3-bash +Copyright 2007 Raphael James Cohn + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except +in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License +is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +or implied. See the License for the specific language governing permissions and limitations under +the License. +EndOfLicence + +# Pragmas +set -u +set -e + +# Constants +readonly version="0.02" +readonly userSpecifiedDataErrorExitCode=1 +readonly invalidCommandLineOption=2 +readonly internalErrorExitCode=3 +readonly invalidEnvironmentExitCode=4 +readonly ipadXorByte=0x36 +readonly opadXorByte=0x5c + +# Command-like aliases +readonly sha1="openssl dgst -sha1 -binary" +readonly base64encode="openssl enc -base64 -e -in" +readonly base64decode="openssl enc -base64 -d -in" + +# Globals +declare -a temporaryFiles + +function base64EncodedMD5 +{ + openssl dgst -md5 -binary "$1" | openssl enc -e -base64 +} + +function printErrorMessage +{ + printf "%s: %s\n" "$1" "$2" 1>&2 +} + +function printErrorHelpAndExit +{ + printErrorMessage "$weAreKnownAs" "$1" + printHelpAndExit $2 +} + +function checkProgramIsInEnvironment +{ + if [ ! -x "$(which $1)" ]; then + printErrorHelpAndExit "Environment Error: $1 not found on the path or not executable" $invalidEnvironmentExitCode + fi +} + +# Do not use this from directly. Due to a bug in bash, array assignments do not work when the function is used with command substitution +function createTemporaryFile +{ + local temporaryFile="$(mktemp "$temporaryDirectory/$$.$1.XXXXXXXX")" || printErrorHelpAndExit "Environment Error: Could not create a temporary file. Please check you /tmp folder permissions allow files and folders to be created and disc space." $invalidEnvironmentExitCode + local length="${#temporaryFiles[@]}" + temporaryFiles[$length]="$temporaryFile" +} + +function mostRecentTemporaryFile +{ + local length="${#temporaryFiles[@]}" + local lastIndex + ((lastIndex = --length)) + echo "${temporaryFiles[$lastIndex]}" +} + +function deleteTemporaryFile +{ + rm -f "$1" || printErrorHelpAndExit "Environment Error: Could not delete a temporary file ($1)." $invalidEnvironmentExitCode +} + +function removeTemporaryFiles +{ + length="${#temporaryFiles[@]}" + if [ $length -eq 0 ]; then + return + fi + for temporaryFile in ${temporaryFiles[@]}; do + deleteTemporaryFile "$temporaryFile" + done + temporaryFiles=() + length="${#temporaryFiles[@]}" +} + +function checkEnvironment +{ + programs=(openssl curl od dd printf sed awk sort mktemp rm grep cp ls env bash) + for program in "${programs[@]}"; do + checkProgramIsInEnvironment "$program" + done + + local temporaryFolder="${TMPDIR:-/tmp}" + if [ ! -x "$temporaryFolder" ]; then + printErrorHelpAndExit "Environment Error: The temporary directory ($temporaryFolder) does not exist. Please set the TMPDIR environment variable to your temporary directory" $invalidEnvironmentExitCode + fi + readonly temporaryDirectory="$temporaryFolder/s3-bash/$weAreKnownAs" + mkdir -p "$temporaryDirectory" || printErrorHelpAndExit "Environment Error: Could not create a temporary directory ($temporaryDiectory). Please check you /tmp folder permissions allow files and folders to be created and you have sufficient disc space" $invalidEnvironmentExitCode + + #Check we can create and delete temporary files + createTemporaryFile "check" + temporaryFileCheck="$(mostRecentTemporaryFile)" + echo "Checking we can write to temporary files. If this is still here then we could not delete temporary files." > "$temporaryFileCheck" + removeTemporaryFiles +} + +function setErrorTraps +{ + trap "removeTemporaryFiles; exit $internalErrorExitCode" INT TERM EXIT +} + +function unsetErrorTraps +{ + trap - INT TERM EXIT +} + +function verifyUrl +{ + if [ -z "$url" ]; then + printErrorHelpAndExit "URL not specified" $userSpecifiedDataErrorExitCode + elif echo $url | grep -q http://; then + printErrorHelpAndExit "URL starts with http://" $userSpecifiedDataErrorExitCode + elif echo $url | grep -q https://; then + printErrorHelpAndExit "URL starts with https://" $userSpecifiedDataErrorExitCode + elif echo $url | grep -v ^/; then + printErrorHelpAndExit "URL does not start with /" $userSpecifiedDataErrorExitCode + fi +} + +function appendHash +{ + local fileToHash="$1" + local fileToWriteTo="$2" + $sha1 "$fileToHash" >> "$fileToWriteTo" +} + +function writeHash +{ + local fileToHash="$1" + local fileToWriteTo="$2" + $sha1 -out "$fileToWriteTo" "$fileToHash" +} + +function checkAwsKey +{ + local originalKeyFile="$1" + local keySize="$(ls -l "$originalKeyFile" | awk '{ print $5 }')" + if [ ! $keySize -eq 40 ]; then + printErrorHelpAndExit "We do not understand Amazon AWS secret keys which are not 40 bytes long. Have you included a carriage return or line feed by mistake at the end of the secret key file?" $userSpecifiedDataErrorExitCode + fi +} + +function padDecodedKeyTo +{ + local originalKeyFile="$1" + local keyFile="$2" + cp "$originalKeyFile" "$keyFile" + + local keySize=$(ls -l "$keyFile" | awk '{ print $5 }') + if [ $keySize -lt 64 ]; then + local zerosToWrite=$((64 - $keySize)) + dd if=/dev/zero of=$keyFile bs=1 count=$zerosToWrite seek=$keySize 2> /dev/null + elif [ $keySize -gt 64 ]; then + echo "Warning: Support for hashing keys bigger than the SHA1 block size of 64 bytes is untested" 1>&2 + writeHash "$originalKeyFile" "$keyFile" + local keySize=$(ls -l "$keyFile" | awk '{ print $5 }') + if [ $keySize -lt 64 ]; then + local zerosToWrite=$((64 - $keySize)) + dd if=/dev/zero of=$keyFile bs=1 count=$zerosToWrite seek=$keySize 2> /dev/null + fi + exit 1 + else + : + fi +} + +function writeLongAsByte +{ + local byte="$1" + local file="$2" + printf "\\$(printf "%o" $byte)" >> "$file" +} + +function readBytesAndXorAndWriteAsBytesTo +{ + local inputFile="$1" + local xorByte=$2 + local outputFile="$3" + + od -v -A n -t uC "$inputFile" | awk '{ OFS="\n"; for (i = 1; i <= NF; i++) print $i }' | + while read byte; do + ((xord = byte ^ xorByte)) + writeLongAsByte $xord "$outputFile" + done +} + +function writeHexByte +{ + local byte="$1" + local file="$2" + printf "\\$(printf "%o" 0x$byte)" >> "$file" +} + +function writeHexString +{ + local hexString="$1" + for byte in $(echo $hexString | sed 's/../& /g'); do + writeHexByte "$byte" "$2" + done +} + +function writeStringToSign +{ + local outputFile="$1" + echo $verb >> "$outputFile" + echo "$contentMD5" >> "$outputFile" + echo "$contentType" >> "$outputFile" + echo "$currentDateTime" >> "$outputFile" + + writeStringToSignAmazonHeaders "$outputFile" + + urlPath="$(echo "$url" | awk 'BEGIN { FS="[?]"} { print $1 }')" + urlQueryString="$(echo "$url" | awk 'BEGIN { FS="[?]"} { print $2 }')" + printf "$urlPath" >> "$outputFile" + if [ "$urlQueryString" = "acl" ] || [ "$urlQueryString" = "torrent" ]; then + printf "?" >> "$outputFile" + printf "$urlQueryString" >> "$outputFile" + fi +} + +function writeStringToSignAmazonHeaders() +{ + local outputFile="$1" + + #Convert all headers to lower case + #sort + #Strip ": " to ":" + #Add LF to each header + awk 'BEGIN { FS=": " } NF == 2 { print tolower($1) ":" $2 }' "$amazonHeaderFile" | sort >> "$outputFile" + #TODO: RFC 2616, section 4.2 (combine repeated headers' values) + #TODO: Unfold long lines (not supported elsewhere) +} + +function computeAwsAuthorizationHeader +{ + checkAwsKey "$awsAccessSecretKeyIdFile" + + createTemporaryFile "key" + local tempKeyFile="$(mostRecentTemporaryFile)" + + createTemporaryFile "ipad" + local ipadHashingFile="$(mostRecentTemporaryFile)" + + createTemporaryFile "opad" + local opadHashingFile="$(mostRecentTemporaryFile)" + + createTemporaryFile "HMAC-SHA1" + local hmacSha1File="$(mostRecentTemporaryFile)" + + padDecodedKeyTo "$awsAccessSecretKeyIdFile" "$tempKeyFile" + readBytesAndXorAndWriteAsBytesTo "$tempKeyFile" ipadXorByte "$ipadHashingFile" + + writeStringToSign "$ipadHashingFile" + + readBytesAndXorAndWriteAsBytesTo "$tempKeyFile" opadXorByte "$opadHashingFile" + appendHash "$ipadHashingFile" "$opadHashingFile" + writeHash "$opadHashingFile" "$hmacSha1File" + + local signature="$($base64encode "$hmacSha1File")" + + echo "Authorization: AWS $awsAccessKeyId:$signature" +} + +function writeAmazonHeadersForCurl +{ + if [ ! -e "$amazonHeaderFile" ]; then + printErrorHelpAndExit "Amazon Header file does not exist" $userSpecifiedDataErrorExitCode + elif grep -q ^X-Amz-Date: "$amazonHeaderFile"; then + printErrorHelpAndExit "X-Amz-Date header not allowed" $userSpecifiedDataErrorExitCode + fi + # Consider using sed... + awk 'BEGIN { ORS=" "; FS="\0" } { print "--header \"" $1 "\""}' "$amazonHeaderFile" >> "$1" +} + +function runCurl +{ + local verbAndAnyData="$1" + local fullUrl="$protocol://s3.amazonaws.com$url" + createTemporaryFile "curl" + local tempCurlCommand="$(mostRecentTemporaryFile)" + local cleanUpCommand="rm -f "$tempCurlCommand"" + + echo "#! /usr/bin/env bash" >> "$tempCurlCommand" + printf "curl %s %s --dump-header \"%s\" " "$verbose" "$verbAndAnyData" "$dumpHeaderFile" >> "$tempCurlCommand" + writeAmazonHeadersForCurl "$tempCurlCommand" + printf " --header \"%s\"" "Date: $currentDateTime" >> "$tempCurlCommand" + printf " --header \"%s\"" "$authorizationHeader" >> "$tempCurlCommand" + if [ ! -z "$contentType" ]; then + printf " --header \"Content-Type: %s\"" "$contentType" >> "$tempCurlCommand" + fi + if [ ! -z "$contentMD5" ]; then + printf " --header \"Content-MD5: %s\"" "$contentMD5" >> "$tempCurlCommand" + fi + printf " \"%s\"\n" "$fullUrl" >> "$tempCurlCommand" + + unsetErrorTraps + exec env bash "$tempCurlCommand" +} + +function initialise +{ + setErrorTraps + checkEnvironment +} + +function main +{ + initialise + parseOptions "$@" + readonly currentDateTime="$(LC_TIME=C date "+%a, %d %h %Y %T %z")" + prepareToRunCurl + readonly authorizationHeader="$(computeAwsAuthorizationHeader)" + runCurl "$verbToPass" +} diff --git a/s3-delete b/s3-delete new file mode 100755 index 0000000..02aee65 --- /dev/null +++ b/s3-delete @@ -0,0 +1,106 @@ +#! /usr/bin/env bash +cat > /dev/null << EndOfLicence +s3-bash +Copyright 2007 Raphael James Cohn + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except +in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License +is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +or implied. See the License for the specific language governing permissions and limitations under +the License. +EndOfLicence + +# Pragmas +set -u +set -e + +function printHelpAndExit +{ + exitCode=$1 + printf "%s: version %s\n" "$weAreKnownAs" "$version" + printf "Part of s3-bash. Latest version is at %s\n" 'http://code.google.com/p/s3-bash/' + printf "Usage %s: -h\n" "$weAreKnownAs" + printf "Usage %s: [-vS] [-H file] [-a file] -k key -s file url\n" "$weAreKnownAs" + printf " Option\tType\tRequirement\tDescription\n" + printf " -h\t\tprecedent\tprint this help\n" + printf " -v\t\toptional\tverbose output\n" + printf " -k\tstring\tmandatory\tAWS Access Key Id\n" + printf " -s\tfile\tmandatory\tAWS Secret Access Key Id File\n" + printf " -S\t\toptional\tUse https\n" + printf " -H\tfile\toptional\tFile to write response headers to\n" + printf " -a\tfile\toptional\tFile to read Amazon custom headers from (X-Amz-Date is not allowed)\n" + printf " \turl\tmandatory\trelative url including bucket name and leading slash, eg /bucket/path/to/object?acl. Assumed to be already encoded\n" + printf "\n" + printf "Notes\n" + printf "Specify proxies using a ~/.curlrc file\n" + exit $exitCode +} + +function parseOptions +{ + verbose="" + url="" + awsAccessKeyId="" + awsAccessSecretKeyIdFile="" + protocol="http" + dumpHeaderFile="/dev/null" + amazonHeaderFile="/dev/null" + while getopts "hvk:s:SH:T:a:" optionName; do + case "$optionName" in + h) printHelpAndExit 0;; + v) verbose="-v";; + k) awsAccessKeyId="$OPTARG";; + s) awsAccessSecretKeyIdFile="$OPTARG" + if [ ! -e "$awsAccessSecretKeyIdFile" ]; then + printErrorHelpAndExit "AWS Secret Key Id file does not exist" $userSpecifiedDataErrorExitCode + fi;; + S) protocol="https";; + H) dumpHeaderFile="$OPTARG";; + a) amazonHeaderFile="$OPTARG";; + [?]) printErrorHelpAndExit "Option not recognised" $userSpecifiedDataErrorExitCode;; + esac + done + if [ 1 -eq $OPTIND ]; then + printErrorHelpAndExit "Internal Error: parseOptions or a parent method in the call stack was not called with $"@"." $internalErrorExitCode + fi + let "toShift = $OPTIND - 1" + shift $toShift + if [ $# -eq 0 ]; then + printErrorHelpAndExit "URL not specified" $userSpecifiedDataErrorExitCode + fi + url="$1" + verifyUrl + + if [ -z "$awsAccessSecretKeyIdFile" ]; then + printErrorHelpAndExit "AWS Secret Access Key file not specified" $userSpecifiedDataErrorExitCode + elif [ -z "$awsAccessKeyId" ]; then + printErrorHelpAndExit "AWS Access Key Id not specified" $userSpecifiedDataErrorExitCode + fi +} + +function prepareToRunCurl +{ + readonly verb="DELETE" + readonly verbToPass="-X DELETE" + readonly contentMD5="" + readonly contentType="" +} + +readonly weAreKnownAs="$(basename $0)" +readonly ourPath="$(dirname $0)" + +readonly commonFunctions="$ourPath/s3-common-functions" +if [ -e "$commonFunctions" ]; then + source "$commonFunctions" +else + version="Unknown" + invalidEnvironmentExitCode=4 + printHelpAndExit "$weAreKnownAs: Could not locate file s3-common-functions" $invalidEnvironmentExitCode +fi + +main "$@" diff --git a/s3-get b/s3-get new file mode 100755 index 0000000..caaa205 --- /dev/null +++ b/s3-get @@ -0,0 +1,108 @@ +#! /usr/bin/env bash +cat > /dev/null << EndOfLicence +s3-bash +Copyright 2007 Raphael James Cohn + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except +in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License +is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +or implied. See the License for the specific language governing permissions and limitations under +the License. +EndOfLicence + +# Pragmas +set -u +set -e + +function printHelpAndExit +{ + exitCode=$1 + printf "%s: version %s\n" "$weAreKnownAs" "$version" + printf "Part of s3-bash. Latest version is at %s\n" 'http://code.google.com/p/s3-bash/' + printf "Usage %s: -h\n" "$weAreKnownAs" + printf "Usage %s: [-vS] [-H file] [-a file] -k key -s file url\n" "$weAreKnownAs" + printf " Option\tType\tRequirement\tDescription\n" + printf " -h\t\tprecedent\tprint this help\n" + printf " -v\t\toptional\tverbose output\n" + printf " -k\tstring\tmandatory\tAWS Access Key Id\n" + printf " -s\tfile\tmandatory\tAWS Secret Access Key Id File\n" + printf " -S\t\toptional\tUse https\n" + printf " -H\tfile\toptional\tFile to write response headers to\n" + printf " -a\tfile\toptional\tFile to read Amazon custom headers from (X-Amz-Date is not allowed)\n" + printf " \turl\tmandatory\trelative url including bucket name and leading slash, eg /bucket/path/to/object?acl. Assumed to be already encoded\n" + printf "\n" + printf "Notes\n" + printf "Specify proxies using a ~/.curlrc file\n" + printf "Content is returned on stdout\n" + exit $exitCode +} + +function parseOptions +{ + verbose="" + url="" + awsAccessKeyId="" + awsAccessSecretKeyIdFile="" + protocol="http" + dumpHeaderFile="/dev/null" + amazonHeaderFile="/dev/null" + while getopts "hvk:s:SH:a:" optionName; do + case "$optionName" in + h) printHelpAndExit 0;; + v) verbose="-v";; + k) awsAccessKeyId="$OPTARG";; + s) awsAccessSecretKeyIdFile="$OPTARG" + if [ ! -e "$awsAccessSecretKeyIdFile" ]; then + printErrorHelpAndExit "AWS Secret Key Id file does not exist" $userSpecifiedDataErrorExitCode + fi;; + S) protocol="https";; + H) dumpHeaderFile="$OPTARG";; + a) amazonHeaderFile="$OPTARG" + ;; + [?]) printErrorHelpAndExit "Option not recognised" $userSpecifiedDataErrorExitCode;; + esac + done + if [ 1 -eq $OPTIND ]; then + printErrorHelpAndExit "Internal Error: parseOptions or a parent method in the call stack was not called with $"@"." $internalErrorExitCode + fi + let "toShift = $OPTIND - 1" + shift $toShift + if [ $# -eq 0 ]; then + printErrorHelpAndExit "URL not specified" $userSpecifiedDataErrorExitCode + fi + url="$1" + verifyUrl + + if [ -z "$awsAccessSecretKeyIdFile" ]; then + printErrorHelpAndExit "AWS Secret Access Key file not specified" $userSpecifiedDataErrorExitCode + elif [ -z "$awsAccessKeyId" ]; then + printErrorHelpAndExit "AWS Access Key Id not specified" $userSpecifiedDataErrorExitCode + fi +} + +function prepareToRunCurl +{ + readonly verb="GET" + readonly verbToPass="--get" + readonly contentMD5="" + readonly contentType="" +} + +readonly weAreKnownAs="$(basename $0)" +readonly ourPath="$(dirname $0)" + +readonly commonFunctions="$ourPath/s3-common-functions" +if [ -e "$commonFunctions" ]; then + source "$commonFunctions" +else + version="Unknown" + invalidEnvironmentExitCode=4 + printErrorHelpAndExit "$weAreKnownAs: Could not locate file s3-common-functions" $invalidEnvironmentExitCode +fi + +main "$@" diff --git a/s3-put b/s3-put new file mode 100755 index 0000000..87af77b --- /dev/null +++ b/s3-put @@ -0,0 +1,119 @@ +#! /usr/bin/env bash +cat > /dev/null << EndOfLicence +s3-bash +Copyright 2007 Raphael James Cohn + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except +in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License +is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +or implied. See the License for the specific language governing permissions and limitations under +the License. +EndOfLicence + +# Pragmas +set -u +set -e + +function printHelpAndExit +{ + exitCode=$1 + printf "%s: version %s\n" "$weAreKnownAs" "$version" + printf "Part of s3-bash. Latest version is at %s\n" 'http://code.google.com/p/s3-bash/' + printf "Usage %s: -h\n" "$weAreKnownAs" + printf "Usage %s: [-vS] [-H file] [-a file] -k key -s file -T file url\n" "$weAreKnownAs" + printf " Option\tType\tRequirement\tDescription\n" + printf " -h\t\tprecedent\tprint this help\n" + printf " -v\t\toptional\tverbose output\n" + printf " -k\tstring\tmandatory\tAWS Access Key Id\n" + printf " -s\tfile\tmandatory\tAWS Secret Access Key Id File\n" + printf " -T\tfile\tmandatory\tFile (or stdin with -) to PUT\n" + printf " -S\t\toptional\tUse https\n" + printf " -H\tfile\toptional\tFile to write response headers to\n" + printf " -a\tfile\toptional\tFile to read Amazon custom headers from (X-Amz-Date is not allowed)\n" + printf " -c\tMIME\toptional\tMIME Content type. Default is text/plain\n" + printf " \turl\tmandatory\trelative url including bucket name and leading slash, eg /bucket/path/to/object?acl. Assumed to be already encoded\n" + printf "\n" + printf "Notes\n" + printf "Specify proxies using a ~/.curlrc file\n" + printf "Specify content to PUT using stdin using option -T -\n" + exit $exitCode +} + +function parseOptions +{ + verbose="" + url="" + awsAccessKeyId="" + awsAccessSecretKeyIdFile="" + protocol="http" + fileToUpload="" + dumpHeaderFile="/dev/null" + amazonHeaderFile="/dev/null" + contentType="text/plain" + while getopts "hvk:s:SH:T:a:c:" optionName; do + case "$optionName" in + h) printHelpAndExit 0;; + v) verbose="-v";; + k) awsAccessKeyId="$OPTARG";; + s) awsAccessSecretKeyIdFile="$OPTARG" + if [ ! -e "$awsAccessSecretKeyIdFile" ]; then + printErrorHelpAndExit "AWS Secret Key Id file does not exist" $userSpecifiedDataErrorExitCode + fi;; + S) protocol="https";; + H) dumpHeaderFile="$OPTARG";; + T) fileToUpload="$OPTARG";; + a) amazonHeaderFile="$OPTARG";; + c) contentType="$OPTARG";; + [?]) printErrorHelpAndExit "Option not recognised" $userSpecifiedDataErrorExitCode;; + esac + done + if [ 1 -eq $OPTIND ]; then + printErrorHelpAndExit "Internal Error: parseOptions or a parent method in the call stack was not called with $"@"." $internalErrorExitCode + fi + let "toShift = $OPTIND - 1" + shift $toShift + if [ $# -eq 0 ]; then + printErrorHelpAndExit "URL not specified" $userSpecifiedDataErrorExitCode + fi + url="$1" + verifyUrl + + if [ -z "$awsAccessSecretKeyIdFile" ]; then + printErrorHelpAndExit "AWS Secret Access Key file not specified" $userSpecifiedDataErrorExitCode + elif [ -z "$awsAccessKeyId" ]; then + printErrorHelpAndExit "AWS Access Key Id not specified" $userSpecifiedDataErrorExitCode + elif [ -z "$fileToUpload" ]; then + printErrorHelpAndExit "File to upload not specified" $userSpecifiedDataErrorExitCode + fi +} + +function prepareToRunCurl +{ + readonly verb="PUT" + if [ ! "-" = "$fileToUpload" ]; then + readonly contentMD5="$(base64EncodedMD5 "$fileToUpload")" + readonly verbToPass="-T \"$fileToUpload\"" + else + readonly contentMD5="" + readonly verbToPass="-T -" + fi +} + +readonly weAreKnownAs="$(basename $0)" +readonly ourPath="$(dirname $0)" + +readonly commonFunctions="$ourPath/s3-common-functions" +if [ -e "$commonFunctions" ]; then + source "$commonFunctions" +else + version="Unknown" + invalidEnvironmentExitCode=4 + printErrorHelpAndExit "$weAreKnownAs: Could not locate file s3-common-functions" $invalidEnvironmentExitCode +fi + +main "$@"