summaryrefslogtreecommitdiff
path: root/build-aux/gnupload
diff options
context:
space:
mode:
Diffstat (limited to 'build-aux/gnupload')
-rwxr-xr-xbuild-aux/gnupload480
1 files changed, 480 insertions, 0 deletions
diff --git a/build-aux/gnupload b/build-aux/gnupload
new file mode 100755
index 0000000..b97e566
--- /dev/null
+++ b/build-aux/gnupload
@@ -0,0 +1,480 @@
+#!/bin/sh
+# Sign files and upload them.
+
+scriptversion=2022-01-27.18; # UTC
+
+# Copyright (C) 2004-2022 Free Software Foundation, Inc.
+#
+# 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 2, 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 <https://www.gnu.org/licenses/>.
+
+# Originally written by Alexandre Duret-Lutz <adl@gnu.org>.
+# The master copy of this file is maintained in the gnulib Git repository.
+# Please send bug reports and feature requests to bug-gnulib@gnu.org.
+
+set -e
+
+GPG=gpg
+# Choose the proper version of gpg, so as to avoid a
+# "gpg-agent is not available in this session" error
+# when gpg-agent is version 2 but gpg is still version 1.
+# FIXME-2020: remove, once all major distros ship gpg version 2 as /usr/bin/gpg
+gpg_agent_version=`(gpg-agent --version) 2>/dev/null | sed -e '2,$d' -e 's/^[^0-9]*//'`
+case "$gpg_agent_version" in
+ 2.*)
+ gpg_version=`(gpg --version) 2>/dev/null | sed -e '2,$d' -e 's/^[^0-9]*//'`
+ case "$gpg_version" in
+ 1.*)
+ if (type gpg2) >/dev/null 2>/dev/null; then
+ # gpg2 is present.
+ GPG=gpg2
+ else
+ # gpg2 is missing. Ubuntu users should install the package 'gnupg2'.
+ echo "WARNING: Using 'gpg', which is too old. You should install 'gpg2'." 1>&2
+ fi
+ ;;
+ esac
+ ;;
+esac
+
+GPG="${GPG} --batch --no-tty"
+conffile=.gnuploadrc
+to=
+dry_run=false
+replace=
+symlink_files=
+delete_files=
+delete_symlinks=
+collect_var=
+dbg=
+nl='
+'
+
+usage="Usage: $0 [OPTION]... [CMD] FILE... [[CMD] FILE...]
+
+Sign all FILES, and process them at the destinations specified with --to.
+If CMD is not given, it defaults to uploading. See examples below.
+
+Commands:
+ --delete delete FILES from destination
+ --symlink create symbolic links
+ --rmsymlink remove symbolic links
+ -- treat the remaining arguments as files to upload
+
+Options:
+ --to DEST specify a destination DEST for FILES
+ (multiple --to options are allowed)
+ --user NAME sign with key NAME
+ --replace allow replacements of existing files
+ --symlink-regex[=EXPR] use sed script EXPR to compute symbolic link names
+ -n, --dry-run do nothing, show what would have been done
+ (including the constructed directive file)
+ --version output version information and exit
+ -h, --help print this help text 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
+
+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.
+
+<https://www.gnu.org/prep/maintain/html_node/Automated-FTP-Uploads.html>
+gives some further background.
+
+Examples:
+1. Upload foobar-1.0.tar.gz to ftp.gnu.org:
+ gnupload --to ftp.gnu.org:foobar foobar-1.0.tar.gz
+
+2. Upload foobar-1.0.tar.gz and foobar-1.0.tar.xz to ftp.gnu.org:
+ gnupload --to ftp.gnu.org:foobar foobar-1.0.tar.gz foobar-1.0.tar.xz
+
+3. Same as above, and also create symbolic links to foobar-latest.tar.*:
+ gnupload --to ftp.gnu.org:foobar \\
+ --symlink-regex \\
+ foobar-1.0.tar.gz foobar-1.0.tar.xz
+
+4. Create a symbolic link foobar-latest.tar.gz -> foobar-1.0.tar.gz
+ and likewise for the corresponding .sig file:
+ gnupload --to ftp.gnu.org:foobar \\
+ --symlink foobar-1.0.tar.gz foobar-latest.tar.gz \\
+ foobar-1.0.tar.gz.sig foobar-latest.tar.gz.sig
+ or (equivalent):
+ gnupload --to ftp.gnu.org:foobar \\
+ --symlink foobar-1.0.tar.gz foobar-latest.tar.gz \\
+ --symlink foobar-1.0.tar.gz.sig foobar-latest.tar.gz.sig
+
+5. Upload foobar-0.9.90.tar.gz to two sites:
+ gnupload --to alpha.gnu.org:foobar \\
+ --to sources.redhat.com:~ftp/pub/foobar \\
+ foobar-0.9.90.tar.gz
+
+6. Delete oopsbar-0.9.91.tar.gz and upload foobar-0.9.91.tar.gz
+ (the -- terminates the list of files to delete):
+ gnupload --to alpha.gnu.org:foobar \\
+ --to sources.redhat.com:~ftp/pub/foobar \\
+ --delete oopsbar-0.9.91.tar.gz \\
+ -- foobar-0.9.91.tar.gz
+
+gnupload executes a program ncftpput to do the transfers; if you don't
+happen to have an ncftp package installed, the ncftpput-ftp script in
+the build-aux/ directory of the gnulib package
+(https://savannah.gnu.org/projects/gnulib) may serve as a replacement.
+
+Send patches and bug reports to <bug-gnulib@gnu.org>."
+
+copyright_year=`echo "$scriptversion" | sed -e 's/[^0-9].*//'`
+copyright="Copyright (C) ${copyright_year} Free Software Foundation, Inc.
+License GPLv2+: GNU GPL version 2 or later <https://gnu.org/licenses/gpl.html>.
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law."
+
+# Read local configuration file
+if test -r "$conffile"; then
+ echo "$0: Reading configuration file $conffile"
+ conf=`sed 's/#.*$//;/^$/d' "$conffile" | tr "\015$nl" ' '`
+ eval set x "$conf \"\$@\""
+ shift
+fi
+
+while test -n "$1"; do
+ case $1 in
+ -*)
+ collect_var=
+ case $1 in
+ -h | --help)
+ echo "$usage"
+ exit $?
+ ;;
+ --to)
+ if test -z "$2"; then
+ echo "$0: Missing argument for --to" 1>&2
+ exit 1
+ elif echo "$2" | grep 'ftp-upload\.gnu\.org' >/dev/null; then
+ echo "$0: Use ftp.gnu.org:PKGNAME or alpha.gnu.org:PKGNAME" >&2
+ echo "$0: for the destination, not ftp-upload.gnu.org (which" >&2
+ echo "$0: is used for direct ftp uploads, not with gnupload)." >&2
+ echo "$0: See --help and its examples if need be." >&2
+ exit 1
+ else
+ to="$to $2"
+ shift
+ fi
+ ;;
+ --user)
+ if test -z "$2"; then
+ echo "$0: Missing argument for --user" 1>&2
+ exit 1
+ else
+ GPG="$GPG --local-user $2"
+ shift
+ fi
+ ;;
+ --delete)
+ collect_var=delete_files
+ ;;
+ --replace)
+ replace="replace: true"
+ ;;
+ --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
+ ;;
+ -n | --dry-run)
+ dry_run=:
+ ;;
+ --version)
+ echo "gnupload $scriptversion"
+ echo "$copyright"
+ exit 0
+ ;;
+ --)
+ 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
+
+dprint()
+{
+ echo "Running $* ..."
+}
+
+if $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
+unset passphrase_fd_0
+GNUPGHOME=${GNUPGHOME:-$HOME/.gnupg}
+
+# 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.
+if $dry_run || grep -q "^use-agent" $GNUPGHOME/gpg.conf; then :; else
+ PATH=/empty echo -n "Enter GPG passphrase: "
+ stty -echo
+ read -r passphrase
+ stty echo
+ echo
+ passphrase_fd_0="--passphrase-fd 0"
+fi
+
+if test $# -ne 0; then
+ for file
+ do
+ echo "Signing $file ..."
+ rm -f $file.sig
+ 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.2
+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
+ echo "Uploading $file to $dest ..."
+ stmt=
+ #
+ # allowing file replacement is all or nothing.
+ if test -n "$replace"; then stmt="$stmt
+$replace"
+ fi
+ #
+ 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
+
+exit 0
+
+# Local variables:
+# eval: (add-hook 'before-save-hook 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC0"
+# time-stamp-end: "; # UTC"
+# End: