a76ac38480b38cba56703722389294d8faa8a5ed
[jigdo.git] / scripts / jigdo-lite
1 #! /bin/sh
2 # Poor man's jigdo - download and assemble Jigsaw Download files
3 # Copyright 2001-2005 Richard Atterer
4 # Portability improvements by J.A. Bezemer, Jan 2002
5 # License: GPL version 2
6
7 # These 4 variables can be overridden in ~/.jigdo-lite if necessary:
8 jigdoOpts="--cache jigdo-file-cache.db"
9 wgetOpts="--passive-ftp --dot-style=mega --continue --timeout=30"
10 mirrors="mirrors.jigdo"
11 tmpDir="."
12
13 filesPerFetch=10
14 maxMissing=30 # Don't try fallback servers if x% or more of files missing
15 rcFile="$HOME/.jigdo-lite"
16
17 if test "x$OSTYPE" = "xmsys"; then
18   windows=true
19   OSTYPE=Windows
20   mirrors="jigdo-bin/mirrors.jigdo"
21   rcFile="jigdo-lite-settings.txt"
22   egrep() { grep -E "$@"; }
23   expr() { echo "$(($@))"; }
24   filesPerFetch=5 # What's the command line length limit?
25   nl='\r\n'
26 else
27   windows=false
28   nl='\n'
29 fi
30 #______________________________________________________________________
31
32 # read with readline, only if running bash >=2.03 (-e gives error on POSIX)
33 readLine="read"
34 if test "x$BASH_VERSION" != "x"; then
35   if test "x${BASH_VERSION#[2-9].}" != "x$BASH_VERSION"; then
36     if test "x${BASH_VERSION#2.0[012]}" = "x$BASH_VERSION"; then
37       readLine="read -e -r"
38     fi
39   fi
40 else
41   # Non-bash: Check whether "read -r" supported
42   if (echo | read -r REPLY 2>/dev/null); then
43     readLine="read -r"
44   fi
45 fi
46 #______________________________________________________________________
47
48 # isURI <string>
49 # Returns 0 (true) if the supplied string is a HTTP/FTP URL, otherwise 1
50 isURI() {
51   case "$1" in
52     http:*|ftp:*|HTTP:*|FTP:*|file:*|FILE:*) return 0;;
53     *) return 1;
54   esac
55 }
56 #______________________________________________________________________
57
58 strEqual() { test "x$1" = "x$2"; }
59 strNotEqual() { test "x$1" != "x$2"; }
60 strEmpty() { test "x$1" = "x"; }
61 strNotEmpty() { test "x$1" != "x"; }
62 #______________________________________________________________________
63
64 # fetch <URL>...
65 # Download a file, storing it in the current dir
66 fetch() {
67   if test "$#" -eq 0; then return 0; fi
68   wget --user-agent="$userAgent" $wgetOpts "$@" || return 1
69 }
70 #______________________________________________________________________
71
72 # Given URLs, fetch them into $imageTmp, then merge them into image
73 fetchAndMerge() {
74   if test "$#" -eq 0; then return 0; fi
75   fetch --force-directories --directory-prefix="$imageTmp" -- "$@"
76   # Merge into the image
77   $jigdoFile $jigdoOpts --no-cache make-image --image="$image" \
78     --jigdo="$jigdoF" --template="$template" "$imageTmp"
79   jigdoErr="$?"
80   if test "$jigdoErr" -ge 3; then
81     echo "jigdo-file failed with code $jigdoErr - aborting."
82     $error 1
83   fi
84   # Delete imageTmp, to avoid taking up more space than necessary
85   rm -rf "$imageTmp"
86   return 0
87 }
88 #______________________________________________________________________
89
90 # Prompt user to input value, assign result to $REPLY. If user just
91 # presses Return, assign supplied default value instead.
92 # input <prompt string> <default value>
93 input() {
94   prompt=""
95   REPLY=""
96   if strNotEmpty "$2"; then prompt=" [$2]"; fi
97   printf "%s%s: " "$1" "$prompt"
98   if $nonInteractive; then echo; else $readLine REPLY; fi
99   if strEmpty "$REPLY"; then REPLY="$2"; fi
100 }
101 #______________________________________________________________________
102
103 # Read from $jigdoF and create a menu of images contained in the file.
104 # If invoked just as "imageMenu", print out the menu. If invoked as
105 # "imageMenu 5", set $image and $templateURI to the filename/URI of
106 # the 5th menu entry.
107 # The scan for [Image] sections stops when at least one such section
108 # has been read and a non-[Image] section follows. This is not
109 # correct, but speeds things up a lot because in many cases the large
110 # [Parts] section does not have to be scanned.
111 imageMenu() {
112   imageSel="$1"
113   curImageCount=0
114   section=""
115   exec 3<"$jigdoF"
116   l=""
117   while true; do
118     case "$l" in
119       "[Image]"*)
120         # Read image section contents
121         unset image templateURI templateMD5 shortInfo info
122         while $readLine l <&3; do
123           case "$l" in
124             "["*"]"*) break;;
125             Filename=*) image="`echo $l | sed -e 's/^Filename= *//; s%[['\\''\"$\\\`|&/]%%g'`";;
126             Template=*) templateURI="`echo $l | sed -e 's/^Template= *//; s%[['\\''\"$\\\`|&]%%g'`";;
127             Template-MD5Sum=*) templateMD5="`echo $l | sed -e 's/^Template-MD5Sum= *//; s%[['\\''\"$\\\`|&/]%%g'`";;
128             Template-MD5Sum=*) templateMD5="`echo $l | sed -e 's/^Template-MD5Sum= *//; s%[^a-zA-Z0-9_-]%%g'`";;
129             ShortInfo=*) shortInfo="`echo $l | sed -e 's/^ShortInfo= *//; s%[[$\\\`|]%%g'`";;
130             Info=*) info="`echo $l | sed -e 's/^Info= *//; s%[['\\''\"$\\\`|]%%g'`";;
131           esac
132         done
133         # Image section read, check for validity
134         if strNotEmpty "$image" && strNotEmpty "$templateURI"; then
135           curImageCount="`expr $curImageCount + 1`"
136           if strNotEmpty "$imageSel"; then
137             # Return info for image selected via $imageSel
138             if test "$imageSel" -eq "$curImageCount"; then exec 3<&-; return 0; fi
139           else
140             # Print image menu
141             if strEmpty "$shortInfo"; then
142               printf "%3d: %s\n" "$curImageCount" "$image"
143             else
144               printf "%3d: %s (%s)\n" "$curImageCount" "$shortInfo" "$image"
145             fi
146           fi
147         fi
148         case "$l" in "[Image]"*) continue;; esac
149         # Abort early, avoid reading [Parts]
150         imageCount="$curImageCount"; exec 3<&-; return 0;;
151       *)
152         # Skip other parts of the file
153         while $readLine l <&3; do
154             case "$l" in "["*"]"*) break;; esac
155         done
156         case "$l" in "["*"]"*) continue;; esac
157         imageCount="$curImageCount"; exec 3<&-; return 0;;
158     esac
159   done
160   imageCount="$curImageCount"
161   exec 3<&-
162   return 0
163 }
164 #______________________________________________________________________
165
166 # Output a horizontal rule
167 hrule() {
168   echo
169   echo "-----------------------------------------------------------------"
170 }
171 #______________________________________________________________________
172
173 # Download template, unless already present in current dir
174 fetchTemplate() {
175   if $fetchedTemplate; then return 0; fi
176   echo
177
178   template=`basename "$templateURI"`
179
180   if strEmpty "$templateMD5"; then
181     echo "[WARNING - \`Template-MD5Sum' missing from image section]"
182     echo
183   fi
184   if test -r "$template" && strNotEmpty "$templateMD5"; then
185     set -- `$jigdoFile md5sum --report=quiet "$template"`
186     if test "$1" = "$templateMD5"; then
187       echo "Not downloading .template file - \`$template' already present"
188       fetchedTemplate=true
189       return 0
190     fi
191 #  elif test -r "$template"; then
192 #    echo "Not downloading .template file - \`$template' already present"
193 #    fetchedTemplate=true
194 #    return 0
195   fi
196   if isURI "$templateURI"; then
197     # Absolute template URL
198     echo 'Downloading .template file'
199 #    rm -f "$template"
200     fetch --continue -- "$templateURI"
201   elif isURI "$url"; then
202     # Template URI is relative to absolute jigdo URL
203     echo 'Downloading .template file'
204 #    rm -f "$template"
205     fetch --continue -- `echo "$url" | sed 's%[^/]*$%%'`"$templateURI"
206   else
207     # Template URI is relative to local jigdo filename
208     if $windows; then
209       # This is a bit broken - we ought to replace / with \ in templateURI too
210       template=`echo "$url" | sed 's%[^\]*$%%'`"$templateURI"
211     else
212       template=`echo "$url" | sed 's%[^/]*$%%'`"$templateURI"
213     fi
214   fi
215   fetchedTemplate=true
216   # Does template exist now?
217   if test ! -r "$template"; then
218     echo "File \`$template' does not exist!"
219     $error 1
220   fi
221   if strEmpty "$templateMD5"; then return 0; fi
222   set -- `$jigdoFile md5sum --report=quiet "$template"`
223   if strEqual "$1" "$templateMD5"; then return 0; fi
224   echo "Error - template checksum mismatch!"
225   echo "The .template file does not belong to the .jigdo file - the"
226   echo "chances are high that the image generation process will break."
227   echo "I will abort now. If you know better than me and want this error"
228   echo "to be ignored, enter the string \"42\" to proceed."
229   echo
230   echo "Note that you might get this error if you resumed the download of a"
231   echo ".template file, and that .template file has changed on the server in"
232   echo "the meantime. In this case, you may be able to fix the problem by"
233   echo "deleting the .template file and restarting jigdo-lite."
234   input ""
235   case $REPLY in *42*) return 0;; esac
236   $error 1
237 }
238 #______________________________________________________________________
239
240 # Write $rcFile
241 saveOptions() {
242   printf "jigdo='%s'${nl}debianMirror='%s'${nl}nonusMirror='%s'${nl}" \
243     "$jigdo" "$debianMirror" "$nonusMirror" >"$rcFile"
244   printf "tmpDir='%s'${nl}jigdoOpts='%s'${nl}" \
245     "$tmpDir" "$jigdoOpts" >>"$rcFile"
246   printf "wgetOpts='%s'${nl}scanMenu='%s'${nl}" \
247     "$wgetOpts" "$scanMenu" >>"$rcFile"
248 }
249 #______________________________________________________________________
250
251 finished() {
252   hrule
253 echo "Finished!"
254 if $batch; then true; else
255 echo "The fact that you got this far is a strong indication that \`$image'"
256 echo "was generated correctly. I will perform an additional, final check,"
257 echo "which you can interrupt safely with Ctrl-C if you do not want to wait."
258 fi
259 echo
260   $jigdoFile verify --image="$image" --jigdo="$jigdoF" --template="$template" \
261     $jigdoOpts
262   return 0
263 }
264 #______________________________________________________________________
265
266 # $0 is an URL or filename. Download/process it.
267 selectImage() {
268   url="$1"
269
270   # Arg can be either URL or filename. Maybe download file
271   if isURI "$url"; then
272     jigdoF=`basename "$url"`
273     echo
274     if test -r "$jigdoF"; then
275       echo "Not downloading .jigdo file - \`$jigdoF' already present"
276     else
277       echo "Downloading .jigdo file"
278       fetch -- "$url"
279     fi
280   else
281     jigdoF="$url"
282   fi
283   # Does jigdo exist now?
284   if test ! -r "$jigdoF"; then
285     echo "File \`$jigdoF' does not exist!"
286     $error 1
287   fi
288   # Try to gunzip it. In case of error, assume that it wasn't gzipped
289   if gzip -cd "$jigdoF" >"$jigdoF.unpacked" 2>/dev/null; then
290     jigdoF="$jigdoF.unpacked"
291   else
292     rm -f "$jigdoF.unpacked"
293   fi
294   #________________________________________
295
296   if $batch; then
297     # Batch - download all images
298     hrule
299     echo "Images offered by \`$url':"
300     imageMenu # print out menu, set $imageCount
301     imageNr=1
302     while test "$imageNr" -le "$imageCount"; do
303       imageMenu "$imageNr" # set $image and $templateURI
304       hrule
305       if test "$imageCount" -eq 1; then
306         echo "Batch mode: Will download \`$image'"
307       else
308         echo "Batch mode: Will download \`$image' (image $imageNr out of $imageCount)"
309       fi
310       imageDownload
311       imageNr="`expr $imageNr + 1`"
312       askQuestions=false
313     done
314
315   else
316
317     # Interactive - ask
318     while true; do
319       hrule
320       echo "Images offered by \`$url':"
321       imageMenu # print out menu, set imageCount
322       if test "$imageCount" -eq 1; then
323         imageMenu "1" # set $image and $templateURI
324         imageDownload
325         break # Only 1 image - don't loop asking for images to download
326       else
327         input "Number of image to download" ""
328         if strEmpty "$REPLY"; then continue; fi
329         if test "$REPLY" -ge 1 -a "$REPLY" -le "$imageCount"; then
330           imageMenu "$REPLY" # set $image and $templateURI
331           imageDownload || return 1
332         fi
333       fi
334     done
335
336   fi
337   case "$jigdoF" in *.unpacked) rm -f "$jigdoF";; esac
338 }
339 #______________________________________________________________________
340
341 scanFiles() {
342   # If --scan on command line, never ask, just scan that path
343   if strNotEmpty "$opt_filesToScan"; then
344     echo "Path to scan: $opt_filesToScan"
345     if $batch; then return 0; fi
346     # Retrieve template if necessary, then supply files
347     fetchTemplate || return 1
348     $jigdoFile make-image --image="$image" --jigdo="$jigdoF" \
349       --template="$template" $jigdoOpts "$opt_filesToScan"
350     jigdoErr="$?"
351     if test "$jigdoErr" -eq 0 -a -r "$image"; then
352       finished
353       $error 0 # All files were present on local filesystem
354     elif test "$jigdoErr" -ge 3; then
355       echo "jigdo-file failed with code $jigdoErr - aborting."
356       $error 1
357     fi
358     return 0
359   fi
360
361   # Ask user for any parts on local filesystems
362   while true; do
363     hrule
364     echo "If you already have a previous version of the CD you are"
365     echo "downloading, jigdo can re-use files on the old CD that are also"
366     echo "present in the new image, and you do not need to download them"
367     if $windows; then
368     echo "again. Enter the path to the old CD ROM's contents (e.g. \`d:\\')."
369     else
370     echo "again. Mount the old CD ROM and enter the path it is mounted under"
371     echo "(e.g. \`/mnt/cdrom')."
372     fi
373     echo "Alternatively, just press enter if you want to start downloading"
374     echo "the remaining files."
375     shift "$#" # Solaris /bin/sh doesn't understand "set --"
376     set -- $scanMenu
377     if strNotEmpty "$1"; then
378       echo
379       echo "You can also enter a single digit from the list below to"
380       echo "select the respective entry for scanning:"
381       echo "  1: $1"
382       if strNotEmpty "$2"; then echo "  2: $2"; fi
383       if strNotEmpty "$3"; then echo "  3: $3"; fi
384       if strNotEmpty "$4"; then echo "  4: $4"; fi
385       if strNotEmpty "$5"; then echo "  5: $5"; fi
386     fi
387     input "Files to scan"; filesToScan="$REPLY"
388     if strEmpty "$filesToScan"; then return 0; fi
389     # Do not add supplied string to menu if...
390     case "$filesToScan" in
391       *" "*|*"'"*|*'`'*|*'"'*|*'$'*) ;; # ...it has bad chars
392       1) filesToScan="$1";;
393       2) filesToScan="$2";;
394       3) filesToScan="$3";;
395       4) filesToScan="$4";;
396       5) filesToScan="$5";;
397       *) case " $1 $2 $3 $4 $5 " in
398         *" $filesToScan "*) ;; # ...it is already in the menu
399         *)  set -- "$filesToScan" $scanMenu
400           scanMenu="$1 $2 $3 $4 $5"
401           saveOptions;;
402       esac;;
403     esac
404     if strEmpty "$filesToScan"; then continue; fi
405
406     # In batch mode, postpone template download, scan later
407     if $batch; then return 0; fi
408
409     # Retrieve template if necessary, then supply files
410     fetchTemplate || return 1
411     $jigdoFile make-image --image="$image" --jigdo="$jigdoF" \
412       --template="$template" $jigdoOpts "$filesToScan"
413     jigdoErr="$?"
414     if test "$jigdoErr" -eq 0 -a -r "$image"; then
415       finished
416       $error 0 # All files were present on local filesystem
417     elif test "$jigdoErr" -ge 3; then
418       echo "jigdo-file failed with code $jigdoErr - aborting."
419       $error 1
420     fi
421   done
422 }
423 #______________________________________________________________________
424
425 selectServers() {
426   if $askQuestions; then true; else return; fi
427
428   # Crude check for whether any entry in the [Parts] section uses a
429   # "Debian" or "Non-US" label. If yes, start Debian mirror selection
430   # below.
431   if $batch; then
432     # If in batch mode, always ask the server questions; even though
433     # the current .jigdo file might not use Debian servers, a later
434     # one might, but we can't ask then.
435     usesDebian=true
436     usesNonus=true
437   else
438     usesDebian=false
439     if egrep '^[^=]+= *["'\'']?Debian:' <"$jigdoF" >/dev/null; then
440       usesDebian=true
441     fi
442     usesNonus=false
443     if egrep '^[^=]+= *["'\'']?Non-US:' <"$jigdoF" >/dev/null; then
444       usesNonus=true
445     fi
446   fi
447
448   # Extra options to pass to jigdo-file for server selection
449   uriOpts=""
450
451   while $usesDebian; do
452     hrule
453     echo "The jigdo file refers to files stored on Debian mirrors. Please"
454     echo "choose a Debian mirror as follows: Either enter a complete URL"
455     echo "pointing to a mirror (in the form"
456     echo "\`ftp://ftp.debian.org/debian/'), or enter any regular expression"
457     echo "for searching through the list of mirrors: Try a two-letter"
458     echo "country code such as \`de', or a country name like \`United"
459     echo "States', or a server name like \`sunsite'."
460     input "Debian mirror" "$debianMirror"
461     # Special-case two-letter country codes
462     case "$REPLY" in [a-z][a-z]) REPLY="[. ]$REPLY[/. ]";; esac
463     if isURI "$REPLY"; then
464       # Turn any "file:/opt/mirror" into "file:/opt/mirror/"
465       debianMirror=`echo $REPLY | sed -e 's%^ *\([^ ]*[^/ ]\)/*\( .*\)*$%\1/%'`
466       saveOptions
467       uriOpts="--uri Debian='$debianMirror'"
468       break;
469     fi
470     egrep -i "$REPLY" "$mirrors" | sed -n -e 's/^Debian=//p'
471     echo
472     echo "An up-to-date copy of the above list is available at"
473     echo "ftp://ftp.debian.org/debian/README.mirrors.txt"
474   done
475
476   while $usesNonus; do
477     hrule
478     echo "The jigdo file also refers to the Non-US section of the Debian"
479     echo "archive. Please repeat the mirror selection for Non-US. Do not"
480     echo "simply copy the URL you entered above; this does not work because"
481     echo "the path on the servers differs!"
482     input "Debian non-US mirror" "$nonusMirror"
483     case "$REPLY" in [a-z][a-z]) REPLY="[. ]$REPLY[/. ]";; esac
484     if isURI "$REPLY"; then
485       # Turn any "file:/opt/mirror" into "file:/opt/mirror/"
486       nonusMirror=`echo $REPLY | sed -e 's%^ *\([^ ]*[^/ ]\)/*\( .*\)*$%\1/%'`
487       saveOptions
488       uriOpts="$uriOpts --uri Non-US='$nonusMirror'";
489       break;
490     fi
491     egrep -i "$REPLY" "$mirrors" | sed -n -e 's/^Non-US=//p'
492     echo
493     echo "An up-to-date copy of the above list is available at"
494     echo "ftp://ftp.debian.org/debian/README.non-US"
495   done
496 }
497 #______________________________________________________________________
498
499 # $image: image filename
500 # $templateURI: Absolute/relative URI from .jigdo file
501 # $info: Info=... entry from .jigdo file
502 imageDownload() {
503
504   fetchedTemplate=false
505
506   if strNotEmpty "$info"; then
507     printf "\nFurther information about \`%s':\n" "$image"
508     echo "$info"
509   fi
510   list="$image.list"
511
512   # Create name of temporary dir, by stripping extension from $image
513   imageTmp="`echo $image | sed 's%\.\(tmp|iso|raw\)%%'`"
514   if test -f "$imageTmp" -o "x$imageTmp" = "x$image"; then
515     imageTmp="$imageTmp.tmpdir"
516   fi
517
518   # Deal with leftover tmpdir from previous, interrupted download
519   if $askQuestions && test -d "$imageTmp"; then
520     hrule
521     echo "The temporary directory \`$imageTmp' already exists. Its contents"
522     echo "ARE GOING TO BE DELETED (possibly after having been copied to the"
523     echo "image, if they are of interest for it). If you do not want this"
524     echo "to happen, press Ctrl-C now. Otherwise, press Return to proceed."
525     input ""
526   fi
527
528   if $askQuestions; then
529     # Ask questions and scan dirs, set up $filesToScan
530     scanFiles || return 1
531     if $batch; then selectServers; fi
532   fi
533
534   if $batch && strNotEmpty "$filesToScan$opt_filesToScan"; then
535     # Retrieve template if necessary, then supply files. One of the
536     # two variables $filesToScan and $opt_filesToScan is always empty
537     fetchTemplate || return 1
538     $jigdoFile make-image --image="$image" --jigdo="$jigdoF" \
539       --template="$template" $jigdoOpts "$filesToScan$opt_filesToScan"
540     jigdoErr="$?"
541     if test "$jigdoErr" -eq 0 -a -r "$image"; then
542       finished
543       return 0 # All files were present on local filesystem
544     elif test "$jigdoErr" -ge 3; then
545       echo "jigdo-file failed with code $jigdoErr - aborting."
546       return 1
547     fi
548   fi
549
550   # Read any files from non-empty tmpDir. Don't delete tmpDir yet, as
551   # wget may resume some half-finished files
552   if test -d "$imageTmp"; then
553     fetchTemplate || return 1
554     # Merge into the image
555     $jigdoFile $jigdoOpts --no-cache make-image --image="$image" \
556       --jigdo="$jigdoF" --template="$template" "$imageTmp"
557   fi
558
559   # Download files and merge them into the image. We instruct wget to
560   # download 10 files at a time and then merge them. This way, compared
561   # to downloading everything, the peak disc space usage is not twice
562   # the size of the final image.
563   while true; do
564
565     if $batch; then true; else selectServers; fi
566     fetchTemplate || return 1
567     hrule
568
569     # If a "file:" URI was given instead of a server URL, try to merge
570     # any files into the image.
571     echo "Merging parts from \`file:' URIs, if any..."
572     $jigdoFile print-missing-all --image="$image" --jigdo="$jigdoF" \
573         --template="$template" $jigdoOpts $uriOpts \
574     | egrep -v '^([a-zA-Z0-9.+_-]+:|$)' \
575     | $jigdoFile make-image --image="$image" --jigdo="$jigdoF" \
576         --template="$template" $jigdoOpts --files-from=-
577     jigdoErr="$?"
578     if test "$jigdoErr" -ge 3; then
579       echo "jigdo-file failed with code $jigdoErr - aborting."
580       $error 1
581     fi
582
583     # First try to download all files using the first URL in the
584     # print-missing-all list. If any files remain missing, add another
585     # pass, this time try to download the missing files using the 2nd
586     # URL, and so on.
587     noMorePasses=false
588     for pass in x xx xxx xxxx xxxxx xxxxxx xxxxxxx xxxxxxxx; do
589       $jigdoFile print-missing-all --image="$image" --jigdo="$jigdoF" \
590         --template="$template" $jigdoOpts $uriOpts \
591       | egrep -i '^(http:|ftp:|$)' >"$list"
592       missingCount=`egrep '^$' <"$list" | wc -l | sed -e 's/ *//g'`
593       # Accumulate URLs in $@, pass them to fetchAndMerge in batches
594       shift "$#" # Solaris /bin/sh doesn't understand "set --"
595       count=""
596       exec 3<"$list"
597       while $readLine url <&3; do
598         count="x$count"
599         if strEmpty "$url"; then count=""; continue; fi
600         if test "$count" != "$pass"; then continue; fi
601         if $noMorePasses; then
602           hrule
603           echo "$missingCount files not found in previous pass, trying"
604           echo "alternative download locations:"
605           echo
606         fi
607         noMorePasses=false
608         set -- "$@" "$url"
609         if test "$#" -ge "$filesPerFetch"; then
610           if fetchAndMerge "$@"; then true; else exec 3<&-; return 1; fi
611           shift "$#" # Solaris /bin/sh doesn't understand "set --"
612         fi
613       done
614       exec 3<&-
615       if test "$#" -ge 1; then fetchAndMerge "$@" || return 1; fi
616       if $noMorePasses; then break; fi
617       if test -r "$image"; then break; fi
618       noMorePasses=true
619     done
620
621     rm -f "$list"
622     if test -r "$image"; then break; fi
623
624     hrule
625     echo "Aaargh - $missingCount files could not be downloaded. This should not"
626     echo "happen! Depending on the problem, it may help to retry downloading"
627     echo "the missing files."
628     if $batch; then return 1; fi
629     if $usesDebian || $usesNonus; then
630     echo "Also, you could try changing to another Debian or Non-US server,"
631     echo "in case the one you used is out of sync."
632     fi
633     echo
634     echo "However, if all the files downloaded without errors and you"
635     echo "still get this message, it means that the files changed on the"
636     echo "server, so the image cannot be generated."
637     if $usesDebian || $usesNonus; then
638     echo "As a last resort, you could try to complete the CD image download"
639     echo "by fetching the remaining data with rsync."
640     fi
641     echo
642     echo "Press Return to retry downloading the missing files."
643     echo "Press Ctrl-C to abort. (If you re-run jigdo-lite later, it will"
644     echo "resume from here, the downloaded data is not lost if you press"
645     echo "Ctrl-C now.)"
646     input ""
647
648   done
649   finished
650 }
651 #======================================================================
652
653 echo
654 echo 'Jigsaw Download "lite"'
655 echo "Copyright (C) 2001-2005  |  jigdo@"
656 echo "Richard Atterer          |  atterer.org"
657
658 jigdoFile="jigdo-file"
659 jigdo-file --version >/dev/null 2>/dev/null
660 if test "$?" -ne 0; then
661     # Using ./jigdo-file is possibly a security risk, so only use if
662     # nothing else is there
663     if test -x "./jigdo-file"; then jigdoFile="./jigdo-file"; fi
664 fi
665 jigdoFileSameDir="`dirname $0`/jigdo-file"
666 if test -x "$jigdoFileSameDir"; then jigdoFile="$jigdoFileSameDir"; fi
667
668 mirrorsSameDir="`dirname $0`/$mirrors"
669 if test -r "$mirrorsSameDir"; then mirrors="$mirrorsSameDir"; fi
670
671 # Check for programs
672 if $windows; then
673     jigdoFile=jigdo-file
674 else
675     for prog in wget egrep sed gzip wc expr; do
676         which "$prog" >/dev/null \
677             || echo "Could not find program \`$prog' - please install it!"
678     done
679 fi
680
681 userAgent="jigdo-lite/`$jigdoFile --version 2>/dev/null | ($readLine jf v ver; echo $ver)` (`wget --version 2>/dev/null | ($readLine ver; echo $ver)`; $OSTYPE)"
682
683 # Load preferences file, if present
684 if test -f "$rcFile"; then
685     echo "Loading settings from \`$rcFile'"
686     mirrorsX="$mirrors"
687     . "$rcFile"
688     mirrors="$mirrorsX"
689     # When upgrading from versions <0.6.9, update value of tmpDir
690     if strEqual "$tmpDir" "tmp" || strEqual "$tmpDir" "temp"; then
691         tmpDir="."
692     fi
693 fi
694
695 # If running for the first time, try to read mirror info from sources.list
696 if strEmpty "$debianMirror$nonusMirror" && test -f "/etc/apt/sources.list"; then
697     echo "Getting mirror information from /etc/apt/sources.list"
698     while $readLine deb url dist rest; do
699         case "$deb $dist" in
700             "deb "*/non-US)
701                 test "$nonusMirror" = "" && \
702                 nonusMirror=`echo "$url"|sed 's%^copy://%file://%; s%//*$%/%'`;;
703             "deb "*)
704                 test "$debianMirror" = "" && \
705                 debianMirror=`echo "$url"|sed 's%^copy://%file://%; s%//*$%/%'`;;
706         esac
707     done <"/etc/apt/sources.list"
708 fi
709 #________________________________________
710
711 # Process command line switches
712 batch=false
713 nonInteractive=false
714 while true; do
715   case "$1" in
716   --help|-h)
717     echo
718     echo "Usage: $0 [OPTIONS] [FILES or URLS...]"
719     echo "  -h  --help       Print this message"
720     echo "  -v  --version    Output version information"
721     echo "      --scan PATH  Don't ask for \"Files to scan\", use this path"
722     echo "      --noask      \"Press Return automatically\" for all "
723     echo "                   questions, accepting the offered defaults"
724     exit 0;;
725   --version|-v)
726     echo
727     echo "$userAgent"
728     exit 0;;
729   --scan)
730     opt_filesToScan="$2"
731     shift 2;;
732   --noask)
733     nonInteractive=true
734     shift 1;;
735   *)
736     break;;
737     esac
738 done
739 #________________________________________
740
741 # No cmd line argument => prompt user
742 if test "$#" -eq 0; then
743     hrule
744     echo "To resume a half-finished download, enter name of .jigdo file."
745     echo "To start a new download, enter URL of .jigdo file."
746     echo "You can also enter several URLs/filenames, separated with spaces,"
747     echo "or enumerate in {}, e.g. \`http://server/cd-{1_NONUS,2,3}.jigdo'"
748     input "jigdo" "$jigdo"
749     jigdo="$REPLY"
750     set -- "$REPLY"
751     saveOptions
752 fi
753 # Expand "a{b,c{x,y}}" into "ab acx acy". How's that for a sed script?
754 # Test cases:
755 # a{b,c{x,y},d{,2}}   FAILS
756 # fl{a,e,i,o,u}b
757 # {wo{x,}of}
758 # {a,b}x{1,2}
759 set -- `echo "$*" | sed '
760 :a
761 s%{\([^,]*\)}%\1%g
762 s%{\(\([^{},]*,\)*\)\([^{},]*\){\([^,{}]*\),\{0,1\}\([^{}]*\)}\([^{}]*\)}%{\1\3\4,\3{\5}\6}%
763 t a
764 :b
765 s%{\([^,]*\)}%\1%g
766 s%\([^{ ]*\){\([^,{}]*\),\{0,1\}\([^{}]*\)}\([^ ]*\)%\1\2\4 \1{\3}\4%
767 t b'`
768 if test "$#" -gt 1; then
769     hrule
770     echo "You have asked me to process several files/URLs:"
771     for file in "$@"; do echo "  $file"; done
772     batch=true
773     echo
774     echo "Entering batch mode"
775     error="return"
776 else
777     error="exit"
778 fi
779 #________________________________________
780
781 askQuestions=true
782 for url in "$@"; do
783     selectImage "$url"
784 done
785 exit 0