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