diff options
Diffstat (limited to 'build-aux/gnupload')
-rwxr-xr-x | build-aux/gnupload | 361 |
1 files changed, 276 insertions, 85 deletions
diff --git a/build-aux/gnupload b/build-aux/gnupload index 5d4289ffc9..7c34784e41 100755 --- a/build-aux/gnupload +++ b/build-aux/gnupload @@ -1,9 +1,9 @@ #!/bin/sh # Sign files and upload them. -scriptversion=2009-01-30.00 +scriptversion=2009-03-05.20 -# Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 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 @@ -23,101 +23,193 @@ scriptversion=2009-01-30.00 set -e GPG='gpg --batch --no-tty' +conffile=.gnuploadrc to= -delete=false +dry_run=false +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 (or delete them from) selected -destinations, according to +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 - --delete delete FILES from destination instead of uploading + --symlink-regex[=EXPR] use sed script EXPR to compute symbolic link names + --dry-run do nothing, show what would have been done --version output version information and exit +If --symlink-regex is given without EXPR, then the link target name +is created by replacing the version information with \`-latest', e.g.: + + foo-1.3.4.tar.gz -> foo-latest.tar.gz + Recognized destinations are: alpha.gnu.org:DIRECTORY savannah.gnu.org:DIRECTORY savannah.nongnu.org:DIRECTORY ftp.gnu.org:DIRECTORY build directive files and upload files by FTP + download.gnu.org.ua:{alpha|ftp}/DIRECTORY + build directive files and upload files by SFTP [user@]host:DIRECTORY upload files with scp -Deletion only works for ftp.gnu.org and alpha.gnu.org (using the -archive: directive). Otherwise it is a no-op. Deleting a file foo also -deletes foo.sig; do not specify the .sig explicitly. +Options and commands are applied in order. If the file $conffile exists +in the current working directory, its contents are prepended to the +actual command line options. Use this to keep your defaults. Comments +(#) and empty lines in $conffile are allowed. -Simple single-target single-file examples: - gnupload --to alpha.gnu.org:automake automake-1.8.2b.tar.gz - gnupload --to ftp.gnu.org:automake automake-1.8.3.tar.gz - gnupload --to alpha.gnu.org:automake --delete automake-oops.tar.gz +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 -Multiple-target multiple-file example: +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-regex \\ automake-1.8.2b.tar.gz automake-1.8.2b.tar.bz2 -You can get the latest version of this script from savannah: -<http://git.savannah.gnu.org/cgit/automake.git/plain/lib/gnupload> +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-1.8.2b.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 test -r "$conffile"; then + echo "$0: Reading configuration file $conffile" + eval set x "`sed 's/#.*$//;/^$/d' \"$conffile\" | tr '\012\015' ' '` \"\$@\"" + shift +fi + while test -n "$1"; do case $1 in - --delete) - delete=true - shift - ;; + -*) + collect_var= + case $1 in --help) echo "$usage" exit $? ;; --to) if test -z "$2"; then - echo "$0: Missing argument for --to" 1>&2 + echo "$0: Missing argument for --to" 1>&2 exit 1 else to="$to $2" - shift 2 + shift fi ;; --user) if test -z "$2"; then - echo "$0: Missing argument for --user" 1>&2 + echo "$0: Missing argument for --user" 1>&2 exit 1 else GPG="$GPG --local-user $2" - shift 2 + shift fi ;; + --delete) + collect_var=delete_files + ;; + --rmsymlink) + collect_var=delete_symlinks + ;; + --symlink-regex=*) + symlink_expr=`expr "$1" : '[^=]*=\(.*\)'` + ;; + --symlink-regex) + symlink_expr='s|-[0-9][0-9\.]*\(-[0-9][0-9]*\)\{0,1\}\.|-latest.|' + ;; + --symlink) + collect_var=symlink_files + ;; + --dry-run|-n) + dry_run=: + ;; --version) echo "gnupload $scriptversion" exit $? ;; + --) + shift + break + ;; -*) echo "$0: Unknown option \`$1', try \`$0 --help'" 1>&2 exit 1 ;; - *) + esac + ;; + *) + if test -z "$collect_var"; then break - ;; + else + eval "$collect_var=\"\$$collect_var $1\"" + fi + ;; esac + shift done -if test $# = 0; then - echo "$0: No file to upload or delete" 1>&2 +dprint() +{ + echo "Running $*..." +} + +if $dry_run; then + dbg=dprint +fi + +if test -z "$to"; then + echo "$0: Missing destination sites" >&2 exit 1 -else - : fi -if $delete; then :; else +if test -n "$symlink_files"; then + x=`echo "$symlink_files" | sed 's/[^ ]//g;s/ //g'` + if test -n "$x"; then + echo "$0: Odd number of symlink arguments" >&2 + exit 1 + 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 @@ -125,8 +217,15 @@ if $delete; then :; else if test ! -f $file; then echo "$0: Cannot find \`$file'" 1>&2 exit 1 - else - : + 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 done fi @@ -146,72 +245,164 @@ read -r passphrase stty echo echo -# Nothing to sign if deleting. -if $delete; then :; else +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 + echo "$passphrase" | $dbg $GPG --passphrase-fd 0 -ba -o $file.sig $file + done +fi + + +# 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 +comment: gnupload v. $scriptversion$stmt +EOF + if $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" | $dbg $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" | $dbg $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/*) + destdir_p1=`echo "$destdir" | sed 's,^[^/]*/,,'` + destdir_topdir=`echo "$destdir" | sed 's,/.*,,'` + mkdirective "$destdir_p1" "$base" "$file" "$stmt" + echo "$passphrase" | $dbg $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_topdir + ;; + /*) + dest_host=`echo "$dest" | sed 's,:.*,,'` + mkdirective "$destdir" "$base" "$file" "$stmt" + echo "$passphrase" | $dbg $GPG --passphrase-fd 0 --clearsign $base.directive + $dbg cp $files $base.directive.asc $dest_host + ;; + *) + 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 - # Prepare arguments. - if $delete; then - echo "Removing $file from $dest..." - files= # nothing to upload if deleting - directive="archive: $file" - else - echo "Uploading $file to $dest..." - files="$file $file.sig" - directive="filename: "`basename -- "$file"` - fi + echo "Uploading $file to $dest..." + stmt= + files="$file $file.sig" destdir=`echo $dest | sed 's/[^:]*://'` - - case $dest in - alpha.gnu.org:*) - rm -f $file.directive $file.directive.asc - cat >$file.directive<<EOF -version: 1.1 -directory: $destdir -$directive -EOF - 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 - cat >$file.directive<<EOF -version: 1.1 -directory: $destdir -$directive -EOF - 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:*) - # We only know how to implement delete for {ftp,alpha}.gnu.org. - $delete \ - || ncftpput savannah.gnu.org /incoming/savannah/$destdir $files - ;; - savannah.nongnu.org:*) - $delete \ - || ncftpput savannah.nongnu.org /incoming/savannah/$destdir $files - ;; - *) - $delete \ - || scp $files $dest - ;; - esac + if test -n "$symlink_expr"; then + linkname=`echo $file | sed "$symlink_expr"` + stmt="$stmt +symlink: $file $linkname +symlink: $file.sig $linkname.sig" + fi + upload "$dest" "$destdir" "$file" "$file" "$stmt" "$files" done done +exit 0 + # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" |