xref: /netbsd-src/external/gpl3/autoconf/dist/build-aux/gnupload (revision d874e91932377fc40d53f102e48fc3ee6f4fe9de)
1#!/bin/sh
2# Sign files and upload them.
3
4scriptversion=2012-01-15.15; # UTC
5
6# Copyright (C) 2004-2012 Free Software Foundation, Inc.
7#
8# This program is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation; either version 2, or (at your option)
11# any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
21# Originally written by Alexandre Duret-Lutz <adl@gnu.org>.
22# The master copy of this file is maintained in the gnulib Git repository.
23# Please send bug reports and feature requests to bug-gnulib@gnu.org.
24
25set -e
26
27GPG='gpg --batch --no-tty'
28conffile=.gnuploadrc
29to=
30dry_run=false
31symlink_files=
32delete_files=
33delete_symlinks=
34collect_var=
35dbg=
36nl='
37'
38
39usage="Usage: $0 [OPTION]... [CMD] FILE... [[CMD] FILE...]
40
41Sign all FILES, and process them at selected destinations according to CMD.
42<http://www.gnu.org/prep/maintain/html_node/Automated-FTP-Uploads.html>
43explains further.
44
45Commands:
46  --delete                 delete FILES from destination
47  --symlink                create symbolic links
48  --rmsymlink              remove symbolic links
49  --                       treat the remaining arguments as files to upload
50
51Options:
52  --help                   print this help text and exit
53  --to DEST                specify one destination for FILES
54                           (multiple --to options are allowed)
55  --user NAME              sign with key NAME
56  --symlink-regex[=EXPR]   use sed script EXPR to compute symbolic link names
57  --dry-run                do nothing, show what would have been done
58  --version                output version information and exit
59
60If --symlink-regex is given without EXPR, then the link target name
61is created by replacing the version information with '-latest', e.g.:
62
63  foo-1.3.4.tar.gz -> foo-latest.tar.gz
64
65Recognized destinations are:
66  alpha.gnu.org:DIRECTORY
67  savannah.gnu.org:DIRECTORY
68  savannah.nongnu.org:DIRECTORY
69  ftp.gnu.org:DIRECTORY
70                           build directive files and upload files by FTP
71  download.gnu.org.ua:{alpha|ftp}/DIRECTORY
72                           build directive files and upload files by SFTP
73  [user@]host:DIRECTORY    upload files with scp
74
75Options and commands are applied in order.  If the file $conffile exists
76in the current working directory, its contents are prepended to the
77actual command line options.  Use this to keep your defaults.  Comments
78(#) and empty lines in $conffile are allowed.
79
80Examples:
811. Upload foobar-1.0.tar.gz to ftp.gnu.org:
82  gnupload --to ftp.gnu.org:foobar foobar-1.0.tar.gz
83
842. Upload foobar-1.0.tar.gz and foobar-1.0.tar.xz to ftp.gnu.org:
85  gnupload --to ftp.gnu.org:foobar foobar-1.0.tar.gz foobar-1.0.tar.xz
86
873. Same as above, and also create symbolic links to foobar-latest.tar.*:
88  gnupload --to ftp.gnu.org:foobar \\
89           --symlink-regex \\
90           foobar-1.0.tar.gz foobar-1.0.tar.xz
91
924. Upload foobar-0.9.90.tar.gz to two sites:
93  gnupload --to alpha.gnu.org:foobar \\
94           --to sources.redhat.com:~ftp/pub/foobar \\
95           foobar-0.9.90.tar.gz
96
975. Delete oopsbar-0.9.91.tar.gz and upload foobar-0.9.91.tar.gz
98   (the -- terminates the list of files to delete):
99  gnupload --to alpha.gnu.org:foobar \\
100           --to sources.redhat.com:~ftp/pub/foobar \\
101           --delete oopsbar-0.9.91.tar.gz \\
102           -- foobar-0.9.91.tar.gz
103
104gnupload uses the ncftpput program to do the transfers; if you don't
105happen to have an ncftp package installed, the ncftpput-ftp script in
106the build-aux/ directory of the gnulib package
107(http://savannah.gnu.org/projects/gnulib) may serve as a replacement.
108
109Send patches and bug reports to <bug-gnulib@gnu.org>."
110
111# Read local configuration file
112if test -r "$conffile"; then
113  echo "$0: Reading configuration file $conffile"
114  conf=`sed 's/#.*$//;/^$/d' "$conffile" | tr "\015$nl" '  '`
115  eval set x "$conf \"\$@\""
116  shift
117fi
118
119while test -n "$1"; do
120  case $1 in
121  -*)
122    collect_var=
123    case $1 in
124    --help)
125      echo "$usage"
126      exit $?
127      ;;
128    --to)
129      if test -z "$2"; then
130        echo "$0: Missing argument for --to" 1>&2
131        exit 1
132      else
133        to="$to $2"
134        shift
135      fi
136      ;;
137    --user)
138      if test -z "$2"; then
139        echo "$0: Missing argument for --user" 1>&2
140        exit 1
141      else
142        GPG="$GPG --local-user $2"
143        shift
144      fi
145      ;;
146    --delete)
147      collect_var=delete_files
148      ;;
149    --rmsymlink)
150      collect_var=delete_symlinks
151      ;;
152    --symlink-regex=*)
153      symlink_expr=`expr "$1" : '[^=]*=\(.*\)'`
154      ;;
155    --symlink-regex)
156      symlink_expr='s|-[0-9][0-9\.]*\(-[0-9][0-9]*\)\{0,1\}\.|-latest.|'
157      ;;
158    --symlink)
159      collect_var=symlink_files
160      ;;
161    --dry-run|-n)
162      dry_run=:
163      ;;
164    --version)
165      echo "gnupload $scriptversion"
166      exit $?
167      ;;
168    --)
169      shift
170      break
171      ;;
172    -*)
173      echo "$0: Unknown option '$1', try '$0 --help'" 1>&2
174      exit 1
175      ;;
176    esac
177    ;;
178  *)
179    if test -z "$collect_var"; then
180      break
181    else
182      eval "$collect_var=\"\$$collect_var $1\""
183    fi
184    ;;
185  esac
186  shift
187done
188
189dprint()
190{
191  echo "Running $* ..."
192}
193
194if $dry_run; then
195  dbg=dprint
196fi
197
198if test -z "$to"; then
199  echo "$0: Missing destination sites" >&2
200  exit 1
201fi
202
203if test -n "$symlink_files"; then
204  x=`echo "$symlink_files" | sed 's/[^ ]//g;s/  //g'`
205  if test -n "$x"; then
206    echo "$0: Odd number of symlink arguments" >&2
207    exit 1
208  fi
209fi
210
211if test $# = 0; then
212  if test -z "${symlink_files}${delete_files}${delete_symlinks}"; then
213    echo "$0: No file to upload" 1>&2
214    exit 1
215  fi
216else
217  # Make sure all files exist.  We don't want to ask
218  # for the passphrase if the script will fail.
219  for file
220  do
221    if test ! -f $file; then
222      echo "$0: Cannot find '$file'" 1>&2
223      exit 1
224    elif test -n "$symlink_expr"; then
225      linkname=`echo $file | sed "$symlink_expr"`
226      if test -z "$linkname"; then
227        echo "$0: symlink expression produces empty results" >&2
228        exit 1
229      elif test "$linkname" = $file; then
230        echo "$0: symlink expression does not alter file name" >&2
231        exit 1
232      fi
233    fi
234  done
235fi
236
237# Make sure passphrase is not exported in the environment.
238unset passphrase
239
240# Reset PATH to be sure that echo is a built-in.  We will later use
241# 'echo $passphrase' to output the passphrase, so it is important that
242# it is a built-in (third-party programs tend to appear in 'ps'
243# listings with their arguments...).
244# Remember this script runs with 'set -e', so if echo is not built-in
245# it will exit now.
246PATH=/empty echo -n "Enter GPG passphrase: "
247stty -echo
248read -r passphrase
249stty echo
250echo
251
252if test $# -ne 0; then
253  for file
254  do
255    echo "Signing $file ..."
256    rm -f $file.sig
257    echo "$passphrase" | $dbg $GPG --passphrase-fd 0 -ba -o $file.sig $file
258  done
259fi
260
261
262# mkdirective DESTDIR BASE FILE STMT
263# Arguments: See upload, below
264mkdirective ()
265{
266  stmt="$4"
267  if test -n "$3"; then
268    stmt="
269filename: $3$stmt"
270  fi
271
272  cat >${2}.directive<<EOF
273version: 1.1
274directory: $1
275comment: gnupload v. $scriptversion$stmt
276EOF
277  if $dry_run; then
278    echo "File ${2}.directive:"
279    cat ${2}.directive
280    echo "File ${2}.directive:" | sed 's/./-/g'
281  fi
282}
283
284mksymlink ()
285{
286  while test $# -ne 0
287  do
288    echo "symlink: $1 $2"
289    shift
290    shift
291  done
292}
293
294# upload DEST DESTDIR BASE FILE STMT FILES
295# Arguments:
296#  DEST     Destination site;
297#  DESTDIR  Destination directory;
298#  BASE     Base name for the directive file;
299#  FILE     Name of the file to distribute (may be empty);
300#  STMT     Additional statements for the directive file;
301#  FILES    List of files to upload.
302upload ()
303{
304  dest=$1
305  destdir=$2
306  base=$3
307  file=$4
308  stmt=$5
309  files=$6
310
311  rm -f $base.directive $base.directive.asc
312  case $dest in
313    alpha.gnu.org:*)
314      mkdirective "$destdir" "$base" "$file" "$stmt"
315      echo "$passphrase" | $dbg $GPG --passphrase-fd 0 --clearsign $base.directive
316      $dbg ncftpput ftp-upload.gnu.org /incoming/alpha $files $base.directive.asc
317      ;;
318    ftp.gnu.org:*)
319      mkdirective "$destdir" "$base" "$file" "$stmt"
320      echo "$passphrase" | $dbg $GPG --passphrase-fd 0 --clearsign $base.directive
321      $dbg ncftpput ftp-upload.gnu.org /incoming/ftp $files $base.directive.asc
322      ;;
323    savannah.gnu.org:*)
324      if test -z "$files"; then
325        echo "$0: warning: standalone directives not applicable for $dest" >&2
326      fi
327      $dbg ncftpput savannah.gnu.org /incoming/savannah/$destdir $files
328      ;;
329    savannah.nongnu.org:*)
330      if test -z "$files"; then
331        echo "$0: warning: standalone directives not applicable for $dest" >&2
332      fi
333      $dbg ncftpput savannah.nongnu.org /incoming/savannah/$destdir $files
334      ;;
335    download.gnu.org.ua:alpha/*|download.gnu.org.ua:ftp/*)
336      destdir_p1=`echo "$destdir" | sed 's,^[^/]*/,,'`
337      destdir_topdir=`echo "$destdir" | sed 's,/.*,,'`
338      mkdirective "$destdir_p1" "$base" "$file" "$stmt"
339      echo "$passphrase" | $dbg $GPG --passphrase-fd 0 --clearsign $base.directive
340      for f in $files $base.directive.asc
341      do
342        echo put $f
343      done | $dbg sftp -b - puszcza.gnu.org.ua:/incoming/$destdir_topdir
344      ;;
345    /*)
346      dest_host=`echo "$dest" | sed 's,:.*,,'`
347      mkdirective "$destdir" "$base" "$file" "$stmt"
348      echo "$passphrase" | $dbg $GPG --passphrase-fd 0 --clearsign $base.directive
349      $dbg cp $files $base.directive.asc $dest_host
350      ;;
351    *)
352      if test -z "$files"; then
353        echo "$0: warning: standalone directives not applicable for $dest" >&2
354      fi
355      $dbg scp $files $dest
356      ;;
357  esac
358  rm -f $base.directive $base.directive.asc
359}
360
361#####
362# Process any standalone directives
363stmt=
364if test -n "$symlink_files"; then
365  stmt="$stmt
366`mksymlink $symlink_files`"
367fi
368
369for file in $delete_files
370do
371  stmt="$stmt
372archive: $file"
373done
374
375for file in $delete_symlinks
376do
377  stmt="$stmt
378rmsymlink: $file"
379done
380
381if test -n "$stmt"; then
382  for dest in $to
383  do
384    destdir=`echo $dest | sed 's/[^:]*://'`
385    upload "$dest" "$destdir" "`hostname`-$$" "" "$stmt"
386  done
387fi
388
389# Process actual uploads
390for dest in $to
391do
392  for file
393  do
394    echo "Uploading $file to $dest ..."
395    stmt=
396    files="$file $file.sig"
397    destdir=`echo $dest | sed 's/[^:]*://'`
398    if test -n "$symlink_expr"; then
399      linkname=`echo $file | sed "$symlink_expr"`
400      stmt="$stmt
401symlink: $file $linkname
402symlink: $file.sig $linkname.sig"
403    fi
404    upload "$dest" "$destdir" "$file" "$file" "$stmt" "$files"
405  done
406done
407
408exit 0
409
410# Local variables:
411# eval: (add-hook 'write-file-hooks 'time-stamp)
412# time-stamp-start: "scriptversion="
413# time-stamp-format: "%:y-%02m-%02d.%02H"
414# time-stamp-time-zone: "UTC"
415# time-stamp-end: "; # UTC"
416# End:
417