#!/bin/sh # Sign files and upload them. scriptversion=2009-02-17.10 # 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 # the Free Software Foundation; either version 3, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Originally written by Alexandre Duret-Lutz . set -e GPG='gpg --batch --no-tty' to= dry_run= symlink_files= delete_files= delete_symlinks= collect_var= dbg= usage="Usage: $0 [OPTIONS]... [COMMAND] FILES... [[COMMAND] FILES...] Sign all FILES, and upload them to selected destinations, according to . 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-regex[=SED-EXPR] use SED-EXPR to create symbolic links --dry-run do nothing, show what would have been done --version output version information and exit If --symlink-re is given without SED-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 [user@]download.gnu.org.ua:{alpha|ftp}/DIRECTORY build directive files and upload files by SFTP [user@]host:DIRECTORY upload files with scp If the file .gnupload 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 .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-regex \\ 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-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 . Send patches to ." # Read local configuration file if test -r .gnupload; then echo "$0: Reading configuration file .gnupload" eval set -- "`sed 's/#.*$//;/^$/d' .gnupload | tr '\012\015' ' '` $@" fi while test -n "$1"; do case $1 in -*) 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-regex=*) symlink_expr=`expr "$1" : '[^=]*=\(.*\)'` shift ;; --symlink-regex) symlink_expr='s|-[0-9][0-9\.]*\(-[0-9][0-9]*\)\{0,1\}\.|-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 ;; *) if test -z "$collect_var"; then break else eval $collect_var=\"\$$collect_var \"$1\"\" shift fi ;; esac done 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 fi 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 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 done fi # Make sure passphrase is not exported in the environment. unset passphrase # Reset PATH to be sure that echo is a built-in. We will later use # `echo $passphrase' to output the passphrase, so it is important that # it is a built-in (third-party programs tend to appear in `ps' # listings with their arguments...). # Remember this script runs with `set -e', so if echo is not built-in # it will exit now. PATH=/empty echo -n "Enter GPG passphrase: " stty -echo read -r passphrase stty echo echo 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 BASE FILE STMT # Arguments: See upload, below mkdirective() { stmt="$4" if test -n "$3"; then stmt=" filename: $3$stmt" fi cat >${2}.directive<&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/*|download.gnu.org.ua:test/*) 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 - download.gnu.org.ua:/incoming/${destdir%%/*} ;; *@download.gnu.org.ua:alpha/*|*@download.gnu.org.ua:ftp/*|*@download.gnu.org.ua:test/*) user=${dest%%@*} 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 - ${user}@download.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 if test -n "$DESTDIR"; then mkdirective "$DESTDIR" "$base" "$file" "$stmt" echo "$passphrase" | $GPG --passphrase-fd 0 --clearsign $base.directive $dbg scp $files $base.directive.asc $dest else $dbg scp $files $dest fi ;; 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_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 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: