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