use guile eval for elisp tree-il
[bpt/guile.git] / build-aux / gnupload
CommitLineData
c84bdaf6
LC
1#!/bin/sh
2# Sign files and upload them.
3
5e69ceb7 4scriptversion=2013-03-19.17; # UTC
c84bdaf6 5
5e69ceb7 6# Copyright (C) 2004-2014 Free Software Foundation, Inc.
c84bdaf6
LC
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 3, 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>.
f0007cad
LC
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.
c84bdaf6
LC
24
25set -e
26
27GPG='gpg --batch --no-tty'
28conffile=.gnuploadrc
29to=
30dry_run=false
005de2e8 31replace=
c84bdaf6
LC
32symlink_files=
33delete_files=
34delete_symlinks=
35collect_var=
36dbg=
a927b6c1
LC
37nl='
38'
c84bdaf6 39
61cd9dc9 40usage="Usage: $0 [OPTION]... [CMD] FILE... [[CMD] FILE...]
c84bdaf6 41
5e69ceb7
MW
42Sign all FILES, and process them at the destinations specified with --to.
43If CMD is not given, it defaults to uploading. See examples below.
c84bdaf6
LC
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:
5e69ceb7 52 --to DEST specify a destination DEST for FILES
c84bdaf6
LC
53 (multiple --to options are allowed)
54 --user NAME sign with key NAME
005de2e8 55 --replace allow replacements of existing files
c84bdaf6
LC
56 --symlink-regex[=EXPR] use sed script EXPR to compute symbolic link names
57 --dry-run do nothing, show what would have been done
005de2e8 58 (including the constructed directive file)
c84bdaf6 59 --version output version information and exit
5e69ceb7 60 --help print this help text and exit
c84bdaf6
LC
61
62If --symlink-regex is given without EXPR, then the link target name
f0007cad 63is created by replacing the version information with '-latest', e.g.:
c84bdaf6
LC
64 foo-1.3.4.tar.gz -> foo-latest.tar.gz
65
66Recognized destinations are:
67 alpha.gnu.org:DIRECTORY
68 savannah.gnu.org:DIRECTORY
69 savannah.nongnu.org:DIRECTORY
70 ftp.gnu.org:DIRECTORY
71 build directive files and upload files by FTP
72 download.gnu.org.ua:{alpha|ftp}/DIRECTORY
73 build directive files and upload files by SFTP
74 [user@]host:DIRECTORY upload files with scp
75
76Options and commands are applied in order. If the file $conffile exists
77in the current working directory, its contents are prepended to the
78actual command line options. Use this to keep your defaults. Comments
79(#) and empty lines in $conffile are allowed.
80
5e69ceb7
MW
81<http://www.gnu.org/prep/maintain/html_node/Automated-FTP-Uploads.html>
82gives some further background.
83
c84bdaf6 84Examples:
1cd4fffc
LC
851. Upload foobar-1.0.tar.gz to ftp.gnu.org:
86 gnupload --to ftp.gnu.org:foobar foobar-1.0.tar.gz
c84bdaf6 87
1cd4fffc
LC
882. Upload foobar-1.0.tar.gz and foobar-1.0.tar.xz to ftp.gnu.org:
89 gnupload --to ftp.gnu.org:foobar foobar-1.0.tar.gz foobar-1.0.tar.xz
c84bdaf6 90
1cd4fffc
LC
913. Same as above, and also create symbolic links to foobar-latest.tar.*:
92 gnupload --to ftp.gnu.org:foobar \\
93 --symlink-regex \\
94 foobar-1.0.tar.gz foobar-1.0.tar.xz
95
964. Upload foobar-0.9.90.tar.gz to two sites:
97 gnupload --to alpha.gnu.org:foobar \\
98 --to sources.redhat.com:~ftp/pub/foobar \\
99 foobar-0.9.90.tar.gz
100
1015. Delete oopsbar-0.9.91.tar.gz and upload foobar-0.9.91.tar.gz
102 (the -- terminates the list of files to delete):
103 gnupload --to alpha.gnu.org:foobar \\
104 --to sources.redhat.com:~ftp/pub/foobar \\
105 --delete oopsbar-0.9.91.tar.gz \\
106 -- foobar-0.9.91.tar.gz
c84bdaf6 107
5e69ceb7 108gnupload executes a program ncftpput to do the transfers; if you don't
61cd9dc9
LC
109happen to have an ncftp package installed, the ncftpput-ftp script in
110the build-aux/ directory of the gnulib package
111(http://savannah.gnu.org/projects/gnulib) may serve as a replacement.
112
f0007cad 113Send patches and bug reports to <bug-gnulib@gnu.org>."
c84bdaf6
LC
114
115# Read local configuration file
116if test -r "$conffile"; then
117 echo "$0: Reading configuration file $conffile"
a927b6c1
LC
118 conf=`sed 's/#.*$//;/^$/d' "$conffile" | tr "\015$nl" ' '`
119 eval set x "$conf \"\$@\""
c84bdaf6
LC
120 shift
121fi
122
123while test -n "$1"; do
124 case $1 in
125 -*)
126 collect_var=
127 case $1 in
128 --help)
129 echo "$usage"
130 exit $?
131 ;;
132 --to)
133 if test -z "$2"; then
134 echo "$0: Missing argument for --to" 1>&2
135 exit 1
5e69ceb7
MW
136 elif echo "$2" | grep 'ftp-upload\.gnu\.org' >/dev/null; then
137 echo "$0: Use ftp.gnu.org:PKGNAME or alpha.gnu.org:PKGNAME" >&2
138 echo "$0: for the destination, not ftp-upload.gnu.org (which" >&2
139 echo "$0: is used for direct ftp uploads, not with gnupload)." >&2
140 echo "$0: See --help and its examples if need be." >&2
141 exit 1
c84bdaf6
LC
142 else
143 to="$to $2"
144 shift
145 fi
146 ;;
147 --user)
148 if test -z "$2"; then
149 echo "$0: Missing argument for --user" 1>&2
150 exit 1
151 else
152 GPG="$GPG --local-user $2"
153 shift
154 fi
155 ;;
156 --delete)
157 collect_var=delete_files
158 ;;
005de2e8
LC
159 --replace)
160 replace="replace: true"
161 ;;
c84bdaf6
LC
162 --rmsymlink)
163 collect_var=delete_symlinks
164 ;;
165 --symlink-regex=*)
166 symlink_expr=`expr "$1" : '[^=]*=\(.*\)'`
167 ;;
168 --symlink-regex)
169 symlink_expr='s|-[0-9][0-9\.]*\(-[0-9][0-9]*\)\{0,1\}\.|-latest.|'
170 ;;
171 --symlink)
172 collect_var=symlink_files
173 ;;
174 --dry-run|-n)
175 dry_run=:
176 ;;
177 --version)
178 echo "gnupload $scriptversion"
179 exit $?
180 ;;
181 --)
182 shift
183 break
184 ;;
185 -*)
f0007cad 186 echo "$0: Unknown option '$1', try '$0 --help'" 1>&2
c84bdaf6
LC
187 exit 1
188 ;;
189 esac
190 ;;
191 *)
192 if test -z "$collect_var"; then
193 break
194 else
195 eval "$collect_var=\"\$$collect_var $1\""
196 fi
197 ;;
198 esac
199 shift
200done
201
202dprint()
203{
a927b6c1 204 echo "Running $* ..."
c84bdaf6
LC
205}
206
207if $dry_run; then
208 dbg=dprint
209fi
210
211if test -z "$to"; then
212 echo "$0: Missing destination sites" >&2
213 exit 1
214fi
215
216if test -n "$symlink_files"; then
217 x=`echo "$symlink_files" | sed 's/[^ ]//g;s/ //g'`
218 if test -n "$x"; then
219 echo "$0: Odd number of symlink arguments" >&2
220 exit 1
221 fi
222fi
223
224if test $# = 0; then
225 if test -z "${symlink_files}${delete_files}${delete_symlinks}"; then
226 echo "$0: No file to upload" 1>&2
227 exit 1
228 fi
229else
230 # Make sure all files exist. We don't want to ask
231 # for the passphrase if the script will fail.
232 for file
233 do
234 if test ! -f $file; then
f0007cad 235 echo "$0: Cannot find '$file'" 1>&2
c84bdaf6
LC
236 exit 1
237 elif test -n "$symlink_expr"; then
238 linkname=`echo $file | sed "$symlink_expr"`
239 if test -z "$linkname"; then
240 echo "$0: symlink expression produces empty results" >&2
241 exit 1
242 elif test "$linkname" = $file; then
243 echo "$0: symlink expression does not alter file name" >&2
244 exit 1
245 fi
246 fi
247 done
248fi
249
250# Make sure passphrase is not exported in the environment.
251unset passphrase
af07e104
AW
252unset passphrase_fd_0
253GNUPGHOME=${GNUPGHOME:-$HOME/.gnupg}
c84bdaf6
LC
254
255# Reset PATH to be sure that echo is a built-in. We will later use
f0007cad
LC
256# 'echo $passphrase' to output the passphrase, so it is important that
257# it is a built-in (third-party programs tend to appear in 'ps'
c84bdaf6 258# listings with their arguments...).
f0007cad 259# Remember this script runs with 'set -e', so if echo is not built-in
c84bdaf6 260# it will exit now.
af07e104 261if $dry_run || grep -q "^use-agent" $GNUPGHOME/gpg.conf; then :; else
005de2e8
LC
262 PATH=/empty echo -n "Enter GPG passphrase: "
263 stty -echo
264 read -r passphrase
265 stty echo
266 echo
af07e104 267 passphrase_fd_0="--passphrase-fd 0"
005de2e8 268fi
c84bdaf6
LC
269
270if test $# -ne 0; then
271 for file
272 do
a927b6c1 273 echo "Signing $file ..."
c84bdaf6 274 rm -f $file.sig
af07e104 275 echo "$passphrase" | $dbg $GPG $passphrase_fd_0 -ba -o $file.sig $file
c84bdaf6
LC
276 done
277fi
278
279
280# mkdirective DESTDIR BASE FILE STMT
281# Arguments: See upload, below
282mkdirective ()
283{
284 stmt="$4"
285 if test -n "$3"; then
286 stmt="
287filename: $3$stmt"
288 fi
289
290 cat >${2}.directive<<EOF
005de2e8 291version: 1.2
c84bdaf6
LC
292directory: $1
293comment: gnupload v. $scriptversion$stmt
294EOF
295 if $dry_run; then
296 echo "File ${2}.directive:"
297 cat ${2}.directive
298 echo "File ${2}.directive:" | sed 's/./-/g'
299 fi
300}
301
302mksymlink ()
303{
304 while test $# -ne 0
305 do
306 echo "symlink: $1 $2"
307 shift
308 shift
309 done
310}
311
312# upload DEST DESTDIR BASE FILE STMT FILES
313# Arguments:
314# DEST Destination site;
315# DESTDIR Destination directory;
316# BASE Base name for the directive file;
317# FILE Name of the file to distribute (may be empty);
318# STMT Additional statements for the directive file;
319# FILES List of files to upload.
320upload ()
321{
322 dest=$1
323 destdir=$2
324 base=$3
325 file=$4
326 stmt=$5
327 files=$6
328
329 rm -f $base.directive $base.directive.asc
330 case $dest in
331 alpha.gnu.org:*)
332 mkdirective "$destdir" "$base" "$file" "$stmt"
af07e104 333 echo "$passphrase" | $dbg $GPG $passphrase_fd_0 --clearsign $base.directive
c84bdaf6
LC
334 $dbg ncftpput ftp-upload.gnu.org /incoming/alpha $files $base.directive.asc
335 ;;
336 ftp.gnu.org:*)
337 mkdirective "$destdir" "$base" "$file" "$stmt"
af07e104 338 echo "$passphrase" | $dbg $GPG $passphrase_fd_0 --clearsign $base.directive
c84bdaf6
LC
339 $dbg ncftpput ftp-upload.gnu.org /incoming/ftp $files $base.directive.asc
340 ;;
341 savannah.gnu.org:*)
342 if test -z "$files"; then
343 echo "$0: warning: standalone directives not applicable for $dest" >&2
344 fi
345 $dbg ncftpput savannah.gnu.org /incoming/savannah/$destdir $files
346 ;;
347 savannah.nongnu.org:*)
348 if test -z "$files"; then
349 echo "$0: warning: standalone directives not applicable for $dest" >&2
350 fi
351 $dbg ncftpput savannah.nongnu.org /incoming/savannah/$destdir $files
352 ;;
353 download.gnu.org.ua:alpha/*|download.gnu.org.ua:ftp/*)
354 destdir_p1=`echo "$destdir" | sed 's,^[^/]*/,,'`
355 destdir_topdir=`echo "$destdir" | sed 's,/.*,,'`
356 mkdirective "$destdir_p1" "$base" "$file" "$stmt"
af07e104 357 echo "$passphrase" | $dbg $GPG $passphrase_fd_0 --clearsign $base.directive
c84bdaf6
LC
358 for f in $files $base.directive.asc
359 do
360 echo put $f
361 done | $dbg sftp -b - puszcza.gnu.org.ua:/incoming/$destdir_topdir
362 ;;
363 /*)
364 dest_host=`echo "$dest" | sed 's,:.*,,'`
365 mkdirective "$destdir" "$base" "$file" "$stmt"
af07e104 366 echo "$passphrase" | $dbg $GPG $passphrase_fd_0 --clearsign $base.directive
c84bdaf6
LC
367 $dbg cp $files $base.directive.asc $dest_host
368 ;;
369 *)
370 if test -z "$files"; then
371 echo "$0: warning: standalone directives not applicable for $dest" >&2
372 fi
373 $dbg scp $files $dest
374 ;;
375 esac
376 rm -f $base.directive $base.directive.asc
377}
378
379#####
380# Process any standalone directives
381stmt=
382if test -n "$symlink_files"; then
383 stmt="$stmt
384`mksymlink $symlink_files`"
385fi
386
387for file in $delete_files
388do
389 stmt="$stmt
390archive: $file"
391done
392
393for file in $delete_symlinks
394do
395 stmt="$stmt
396rmsymlink: $file"
397done
398
399if test -n "$stmt"; then
400 for dest in $to
401 do
402 destdir=`echo $dest | sed 's/[^:]*://'`
403 upload "$dest" "$destdir" "`hostname`-$$" "" "$stmt"
404 done
405fi
406
407# Process actual uploads
408for dest in $to
409do
410 for file
411 do
a927b6c1 412 echo "Uploading $file to $dest ..."
c84bdaf6 413 stmt=
005de2e8
LC
414 #
415 # allowing file replacement is all or nothing.
416 if test -n "$replace"; then stmt="$stmt
417$replace"
418 fi
419 #
c84bdaf6
LC
420 files="$file $file.sig"
421 destdir=`echo $dest | sed 's/[^:]*://'`
422 if test -n "$symlink_expr"; then
423 linkname=`echo $file | sed "$symlink_expr"`
424 stmt="$stmt
425symlink: $file $linkname
426symlink: $file.sig $linkname.sig"
427 fi
428 upload "$dest" "$destdir" "$file" "$file" "$stmt" "$files"
429 done
430done
431
432exit 0
433
434# Local variables:
435# eval: (add-hook 'write-file-hooks 'time-stamp)
436# time-stamp-start: "scriptversion="
437# time-stamp-format: "%:y-%02m-%02d.%02H"
438# time-stamp-time-zone: "UTC"
439# time-stamp-end: "; # UTC"
440# End: