diff options
Diffstat (limited to 'upload/gnupload')
-rwxr-xr-x | upload/gnupload | 418 |
1 files changed, 286 insertions, 132 deletions
diff --git a/upload/gnupload b/upload/gnupload index 7be012b..8e3e392 100755 --- a/upload/gnupload +++ b/upload/gnupload @@ -1,9 +1,9 @@ #!/bin/sh # Sign files and upload them. -scriptversion=2008-10-15.22 +scriptversion=2009-01-23.23 -# Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation +# Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -25,22 +25,33 @@ set -e GPG='gpg --batch --no-tty' to= DRY_RUN= +SYMLINK_FILES= +DELETE_FILES= +DELETE_SYMLINKS= +COLLECT_VAR= +DBG= -usage="Usage: $0 [OPTIONS]... FILES... +usage="Usage: $0 [OPTIONS]... [COMMAND] FILES... [[COMMAND] FILES...] Sign all FILES, and upload them to selected destinations, according to <http://www.gnu.org/prep/maintain/html_node/Automated-FTP-Uploads.html>. +Commands: + --delete delete FILES from destination + --symlink create symbolic links + --rmsymlink remove symbolic links + -- treat the remaining arguments as files to upload + Options: --help print this help text and exit --to DEST specify one destination for FILES (multiple --to options are allowed) --user NAME sign with key NAME - --symlink[=SED-EXPR] use SED-EXPR to create symbolic links + --symlink-re[=SED-EXPR] use SED-EXPR to create symbolic links --dry-run do nothing, show everything --version output version information and exit -If --symlink without SED-EXPR is given, symlink target name is +If --symlink-re without SED-EXPR is given, symlink target name is created by replacing version information with the word \`-latest', e.g.: @@ -56,89 +67,168 @@ Recognized destinations are: build directive files and upload files by SFTP [user@]host:DIRECTORY upload files with scp -Example: +If the file .gnupload exists in the current working directory, its contents +is prepended to the actual command line options. Use this to keep your +defaults. Comments (#) and empty lines in .gnupload are allowed. + +Examples: +1. Upload automake-1.8.2b.tar.gz and automake-1.8.2b.tar.bz2 to two sites: + gnupload --to sources.redhat.com:~ftp/pub/automake \\ + --to alpha.gnu.org:automake \\ + automake-1.8.2b.tar.gz automake-1.8.2b.tar.bz2 + +2. Same as above, but also create symbolic links to automake-latest.tar.*: + gnupload --to sources.redhat.com:~ftp/pub/automake \\ + --to alpha.gnu.org:automake \\ + --symlink-re \\ + automake-1.8.2b.tar.gz automake-1.8.2b.tar.bz2 + +3. Symlink automake-1.8.2b.tar.gz to automake-latest.tar.gz and +automake-1.8.2b.tar.bz2 to automake-latest.tar.bz2 on both sites: + + gnupload --to sources.redhat.com:~ftp/pub/automake \\ + --to alpha.gnu.org:automake \\ + --symlink automake-1.8.2b.tar.gz automake-latest.tar.gz \\ + automake-latest.tar.bz2 automake-latest.tar.bz2 + +4. Delete automake-1.8.2a.tar.gz and .bz2, remove symlink +automake-latest.tar.gz and upload automake-1.8.2b.tar.gz: + gnupload --to sources.redhat.com:~ftp/pub/automake \\ --to alpha.gnu.org:automake \\ + --delete automake-1.8.2a.tar.gz automake-1.8.2a.tar.bz2 \\ + --rmsymlink automake-latest.tar.gz \\ + -- \\ automake-1.8.2b.tar.gz automake-1.8.2b.tar.bz2 Report bugs to <bug-automake@gnu.org>. Send patches to <automake-patches@gnu.org>." +# Read local configuration file +if [ -r .gnupload ]; then + echo "$0: Reading configuration file .gnupload" + eval set -- "`sed 's/#.*$//;/^$/d' .gnupload | tr '\n' ' '` $*" +fi + while test -n "$1"; do case $1 in - --help) - echo "$usage" - exit $? - ;; - --to) - if test -z "$2"; then - echo "$0: Missing argument for --to" 1>&2 - exit 1 - else - to="$to $2" - shift 2 - fi + -*) COLLECT_VAR= + case $1 in + --help) + echo "$usage" + exit $? + ;; + --to) + if test -z "$2"; then + echo "$0: Missing argument for --to" 1>&2 + exit 1 + else + to="$to $2" + shift 2 + fi + ;; + --user) + if test -z "$2"; then + echo "$0: Missing argument for --user" 1>&2 + exit 1 + else + GPG="$GPG --local-user $2" + shift 2 + fi + ;; + --delete) + COLLECT_VAR=DELETE_FILES + shift + ;; + --rmsymlink) + COLLECT_VAR=DELETE_SYMLINKS + shift + ;; + --symlink-re=*) + SYMLINK_EXPR=${1##--symlink=} + shift + ;; + --symlink-re) + SYMLINK_EXPR='s|-[0-9][0-9\.]*\(-[0-9][0-9]*\)\?\.|-latest.|' + shift + ;; + --symlink) + COLLECT_VAR=SYMLINK_FILES + shift + ;; + --dry-run|-n) + DRY_RUN=1 + shift + ;; + --version) + echo "gnupload $scriptversion" + exit $? + ;; + --) + shift + break + ;; + -*) + echo "$0: Unknown option \`$1', try \`$0 --help'" 1>&2 + exit 1 + ;; + esac ;; - --user) - if test -z "$2"; then - echo "$0: Missing argument for --user" 1>&2 - exit 1 + *) if test -z "$COLLECT_VAR"; then + break else - GPG="$GPG --local-user $2" - shift 2 + eval $COLLECT_VAR=\"\$$COLLECT_VAR $1\" + shift fi ;; - --symlink=*) - SYMLINK=${1##--symlink=} - shift - ;; - --symlink) - SYMLINK='s|-[0-9][0-9\.]*\(-[0-9][0-9]*\)\?\.|-latest.|' - shift - ;; - --dry-run|-n) - DRY_RUN=1 - shift - ;; - --version) - echo "gnupload $scriptversion" - exit $? - ;; - -*) - echo "$0: Unknown option \`$1', try \`$0 --help'" 1>&2 - exit 1 - ;; - *) - break - ;; - esac + esac done -if test $# = 0; then - echo "$0: No file to upload" 1>&2 +dprint() { + echo "Running $*..." +} + +if test -n "$DRY_RUN"; then + DBG=dprint +fi + +if test -z "$to"; then + echo "$0: Missing destination sites" >&2 exit 1 -else - : fi -# Make sure all files exist. We don't want to ask -# for the passphrase if the script will fail. -for file -do - if test ! -f $file; then - echo "$0: Cannot find \`$file'" 1>&2 +if test -n "$SYMLINK_FILES"; then + if test -n "`echo "$SYMLINK_FILES" | sed 's/[^ ]//g;s/ //g'`"; then + echo "$0: Odd number of symlink arguments" >&2 exit 1 - elif test -n "$SYMLINK"; then - linkname=`echo $file | sed "$SYMLINK"` - if test -z "$linkname"; then - echo "$0: symlink expression produces empty results" >&2 - exit 1 - elif test $linkname = $file; then - echo "$0: symlink expression does not alter file name" >&2 + fi +fi + +if test $# = 0; then + if test -z "${SYMLINK_FILES}${DELETE_FILES}${DELETE_SYMLINKS}"; then + echo "$0: No file to upload" 1>&2 + exit 1 + fi +else + # Make sure all files exist. We don't want to ask + # for the passphrase if the script will fail. + for file + do + if test ! -f $file; then + echo "$0: Cannot find \`$file'" 1>&2 exit 1 + elif test -n "$SYMLINK_EXPR"; then + linkname=`echo $file | sed "$SYMLINK_EXPR"` + if test -z "$linkname"; then + echo "$0: symlink expression produces empty results" >&2 + exit 1 + elif test $linkname = $file; then + echo "$0: symlink expression does not alter file name" >&2 + exit 1 + fi fi - fi -done + done +fi # Make sure passphrase is not exported in the environment. unset passphrase @@ -155,88 +245,152 @@ read -r passphrase stty echo echo -for file -do - echo "Signing $file..." - rm -f $file.sig - echo $passphrase | $GPG --passphrase-fd 0 -ba -o $file.sig $file -done +if test $# -ne 0; then + for file + do + echo "Signing $file..." + rm -f $file.sig + echo $passphrase | $GPG --passphrase-fd 0 -ba -o $file.sig $file + done +fi -# mkdirective DESTDIR FILE-NAME LINKNAME +# mkdirective DESTDIR BASE FILE STMT +# Arguments: See upload, below mkdirective() { + stmt="$4" + if test -n "$3"; then + stmt=" +filename: $3$stmt" + fi + cat >${2}.directive<<EOF version: 1.1 directory: $1 -filename: $2 -comment: Gray's gnupload v. $scriptversion -EOF - if test -n "$3"; then - cat >>${2}.directive<<EOF -rmsymlink: $3 -symlink: $2 $3 -rmsymlink: ${3}.sig -symlink: ${2}.sig ${3}.sig +comment: Gray's gnupload v. $scriptversion$stmt EOF + if test -n "$DRY_RUN"; then + echo "File ${2}.directive:" + cat ${2}.directive + echo "File ${2}.directive:" | sed 's/./-/g' fi } +mksymlink() { + while test $# -ne 0 + do + echo "symlink: $1 $2" + shift + shift + done +} + +# upload DEST DESTDIR BASE FILE STMT FILES +# Arguments: +# DEST Destination site; +# DESTDIR Destination directory; +# BASE Base name for the directive file; +# FILE Name of the file to distribute (may be empty); +# STMT Additional statements for the directive file; +# FILES List of files to upload. +upload() { + dest=$1 + destdir=$2 + base=$3 + file=$4 + stmt=$5 + files=$6 + + rm -f $base.directive $base.directive.asc + case $dest in + alpha.gnu.org:*) + mkdirective "$destdir" "$base" "$file" "$stmt" + echo "$passphrase" | $GPG --passphrase-fd 0 --clearsign $base.directive + $DBG ncftpput ftp-upload.gnu.org /incoming/alpha $files $base.directive.asc + ;; + ftp.gnu.org:*) + mkdirective "$destdir" "$base" "$file" "$stmt" + echo "$passphrase" | $GPG --passphrase-fd 0 --clearsign $base.directive + $DBG ncftpput ftp-upload.gnu.org /incoming/ftp $files $base.directive.asc + ;; + savannah.gnu.org:*) + if test -z "$files"; then + echo "$0: warning: standalone directives not applicable for $dest" >&2 + fi + $DBG ncftpput savannah.gnu.org /incoming/savannah/$destdir $files + ;; + savannah.nongnu.org:*) + if test -z "$files"; then + echo "$0: warning: standalone directives not applicable for $dest" >&2 + fi + $DBG ncftpput savannah.nongnu.org /incoming/savannah/$destdir $files + ;; + download.gnu.org.ua:alpha/*|download.gnu.org.ua:ftp/*) + mkdirective "${destdir#*/}" "$base" "$file" "$stmt" + echo "$passphrase" | $GPG --passphrase-fd 0 --clearsign $base.directive + for f in $files $base.directive.asc + do + echo put $f + done | $DBG sftp -b - puszcza.gnu.org.ua:/incoming/${destdir%%/*} + ;; + /*) + mkdirective "$destdir" "$base" "$file" "$stmt" + echo "$passphrase" | $GPG --passphrase-fd 0 --clearsign $base.directive + $DBG cp $files $base.directive.asc ${dest%%:*} + ;; + *) + if test -z "$files"; then + echo "$0: warning: standalone directives not applicable for $dest" >&2 + fi + $DBG scp $files $dest + ;; + esac + rm -f $base.directive $base.directive.asc +} + +##### +# Process any standalone directives +stmt= +if test -n "$SYMLINK_FILES"; then + stmt="$stmt +`mksymlink $SYMLINK_FILES`" +fi + +for file in $DELETE_FILES +do + stmt="$stmt +archive: $file" +done + +for file in $DELETE_SYMLINKS +do + stmt="$stmt +rmsymlink: $file" +done + +if test -n "$stmt"; then + for dest in $to + do + destdir=`echo $dest | sed 's/[^:]*://'` + upload "$dest" "$destdir" "`hostname`-$$" "" "$stmt" + done +fi + +# Process actual uploads for dest in $to do for file do echo "Uploading $file to $dest..." + stmt= files="$file $file.sig" destdir=`echo $dest | sed 's/[^:]*://'` - if test -n "$SYMLINK"; then - linkname=`echo $file | sed "$SYMLINK"` - fi - if test -n "$DRY_RUN"; then - echo "Uploading $file and $file.sig to $dest" - if test -n "$linkname"; then - echo "Linking $file to $linkname" - fi - continue + if test -n "$SYMLINK_EXPR"; then + linkname=`echo $file | sed "$SYMLINK_EXPR"` + stmt="$stmt +symlink: $file $linkname +symlink: $file.sig $linkname.sig" fi - case $dest in - alpha.gnu.org:*) - rm -f $file.directive $file.directive.asc - mkdirective "$destdir" "$file" "$linkname" - echo "$passphrase" | $GPG --passphrase-fd 0 --clearsign $file.directive - ncftpput ftp-upload.gnu.org /incoming/alpha $files $file.directive.asc - rm -f $file.directive $file.directive.asc - ;; - ftp.gnu.org:*) - rm -f $file.directive $file.directive.asc - mkdirective "$destdir" "$file" "$linkname" - echo "$passphrase" | $GPG --passphrase-fd 0 --clearsign $file.directive - ncftpput ftp-upload.gnu.org /incoming/ftp $files $file.directive.asc - rm -f $file.directive $file.directive.asc - ;; - savannah.gnu.org:*) - ncftpput savannah.gnu.org /incoming/savannah/$destdir $files - ;; - savannah.nongnu.org:*) - ncftpput savannah.nongnu.org /incoming/savannah/$destdir $files - ;; - download.gnu.org.ua:alpha/*|download.gnu.org.ua:ftp/*) - rm -f $file.directive $file.directive.asc - mkdirective "${destdir#*/}" "$file" "$linkname" - echo "$passphrase" | $GPG --passphrase-fd 0 --clearsign $file.directive - for f in $files $file.directive.asc - do - echo put $f - done | sftp -b - puszcza.gnu.org.ua:/incoming/${destdir%%/*} - rm -f $file.directive $file.directive.asc - ;; - /*) - mkdirective "$destdir" "$file" "$linkname" - echo "$passphrase" | $GPG --passphrase-fd 0 --clearsign $file.directive - cp $files $file.directive.asc ${dest%%:*} - rm -f $file.directive $file.directive.asc;; - *) - scp $files $dest - ;; - esac + upload "$dest" "$destdir" "$file" "$file" "$stmt" "$files" done done |