2 * The new sysinstall program.
4 * This is probably the last program in the `sysinstall' line - the next
5 * generation being essentially a complete rewrite.
7 * $Id: dist.c,v 1.128 1998/10/14 11:23:48 jkh Exp $
10 * Jordan Hubbard. All rights reserved.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer,
17 * verbatim and that no modifications are made prior to this
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
23 * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 #include "sysinstall.h"
43 unsigned int DESDists;
44 unsigned int SrcDists;
45 unsigned int XF86Dists;
46 unsigned int XF86ServerDists;
47 unsigned int XF86FontDists;
49 typedef struct _dist {
52 unsigned int *my_mask;
54 struct _dist *my_dist;
57 extern Distribution DistTable[];
58 extern Distribution DESDistTable[];
59 extern Distribution SrcDistTable[];
60 extern Distribution XF86DistTable[];
61 extern Distribution XF86FontDistTable[];
62 extern Distribution XF86ServerDistTable[];
64 /* The top-level distribution categories */
65 static Distribution DistTable[] = {
66 { "bin", "/", &Dists, DIST_BIN, NULL },
67 { "doc", "/", &Dists, DIST_DOC, NULL },
68 { "games", "/", &Dists, DIST_GAMES, NULL },
69 { "manpages", "/", &Dists, DIST_MANPAGES, NULL },
70 { "catpages", "/", &Dists, DIST_CATPAGES, NULL },
71 { "proflibs", "/", &Dists, DIST_PROFLIBS, NULL },
72 { "dict", "/", &Dists, DIST_DICT, NULL },
73 { "info", "/", &Dists, DIST_INFO, NULL },
74 { "src", "/", &Dists, DIST_SRC, SrcDistTable },
75 { "des", "/", &Dists, DIST_DES, DESDistTable },
76 { "compat1x", "/", &Dists, DIST_COMPAT1X, NULL },
77 { "compat20", "/", &Dists, DIST_COMPAT20, NULL },
78 { "compat21", "/", &Dists, DIST_COMPAT21, NULL },
79 { "ports", "/usr", &Dists, DIST_PORTS, NULL },
80 { "XF86332", "/usr", &Dists, DIST_XF86, XF86DistTable },
84 /* The DES distribution (not for export!) */
85 static Distribution DESDistTable[] = {
86 { "des", "/", &DESDists, DIST_DES_DES, NULL },
87 { "krb", "/", &DESDists, DIST_DES_KERBEROS, NULL },
88 { "ssecure", "/usr/src", &DESDists, DIST_DES_SSECURE, NULL },
89 { "scrypto", "/usr/src", &DESDists, DIST_DES_SCRYPTO, NULL },
90 { "skerbero", "/usr/src", &DESDists, DIST_DES_SKERBEROS, NULL },
94 /* The /usr/src distribution */
95 static Distribution SrcDistTable[] = {
96 { "sbase", "/usr/src", &SrcDists, DIST_SRC_BASE, NULL },
97 { "scontrib", "/usr/src", &SrcDists, DIST_SRC_CONTRIB, NULL },
98 { "sgnu", "/usr/src", &SrcDists, DIST_SRC_GNU, NULL },
99 { "setc", "/usr/src", &SrcDists, DIST_SRC_ETC, NULL },
100 { "sgames", "/usr/src", &SrcDists, DIST_SRC_GAMES, NULL },
101 { "sinclude", "/usr/src", &SrcDists, DIST_SRC_INCLUDE, NULL },
102 { "slib", "/usr/src", &SrcDists, DIST_SRC_LIB, NULL },
103 { "slibexec", "/usr/src", &SrcDists, DIST_SRC_LIBEXEC, NULL },
104 { "slkm", "/usr/src", &SrcDists, DIST_SRC_LKM, NULL },
105 { "srelease", "/usr/src", &SrcDists, DIST_SRC_RELEASE, NULL },
106 { "sbin", "/usr/src", &SrcDists, DIST_SRC_BIN, NULL },
107 { "ssbin", "/usr/src", &SrcDists, DIST_SRC_SBIN, NULL },
108 { "sshare", "/usr/src", &SrcDists, DIST_SRC_SHARE, NULL },
109 { "ssys", "/usr/src", &SrcDists, DIST_SRC_SYS, NULL },
110 { "subin", "/usr/src", &SrcDists, DIST_SRC_UBIN, NULL },
111 { "susbin", "/usr/src", &SrcDists, DIST_SRC_USBIN, NULL },
112 { "ssmailcf", "/usr/src", &SrcDists, DIST_SRC_SMAILCF, NULL },
116 /* The XFree86 distribution */
117 static Distribution XF86DistTable[] = {
118 { "XF86332", "/usr/X11R6", &XF86Dists, DIST_XF86_FONTS, XF86FontDistTable },
119 { "XF86332", "/usr/X11R6", &XF86Dists, DIST_XF86_SERVER, XF86ServerDistTable },
120 { "Xsrc1", "/usr/X11R6/src", &XF86Dists, DIST_XF86_SRC, NULL },
121 { "Xsrcctrb", "/usr/X11R6/src", &XF86Dists, DIST_XF86_CSRC, NULL },
122 { "Xbin", "/usr/X11R6", &XF86Dists, DIST_XF86_BIN, NULL },
123 { "Xcfg", "/usr/X11R6", &XF86Dists, DIST_XF86_CFG, NULL },
124 { "Xdoc", "/usr/X11R6", &XF86Dists, DIST_XF86_DOC, NULL },
125 { "Xhtml", "/usr/X11R6", &XF86Dists, DIST_XF86_HTML, NULL },
126 { "Xlib", "/usr/X11R6", &XF86Dists, DIST_XF86_LIB, NULL },
127 { "Xlk98", "/usr/X11R6", &XF86Dists, DIST_XF86_LKIT98, NULL },
128 { "Xlkit", "/usr/X11R6", &XF86Dists, DIST_XF86_LKIT, NULL },
129 { "Xman", "/usr/X11R6", &XF86Dists, DIST_XF86_MAN, NULL },
130 { "Xprog", "/usr/X11R6", &XF86Dists, DIST_XF86_PROG, NULL },
131 { "Xps", "/usr/X11R6", &XF86Dists, DIST_XF86_PS, NULL },
132 { "Xset", "/usr/X11R6", &XF86Dists, DIST_XF86_SET, NULL },
133 { "X9set", "/usr/X11R6", &XF86Dists, DIST_XF86_9SET, NULL },
137 /* The XFree86 server distribution */
138 static Distribution XF86ServerDistTable[] = {
139 { "PC98-Servers/X9480", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9480, NULL },
140 { "PC98-Servers/X9EGC", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9EGC, NULL },
141 { "PC98-Servers/X9GA9", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9GA9, NULL },
142 { "PC98-Servers/X9GAN", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9GAN, NULL },
143 { "PC98-Servers/X9LPW", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9LPW, NULL },
144 { "PC98-Servers/X9MGA", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9MGA, NULL },
145 { "PC98-Servers/X9NKV", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9NKV, NULL },
146 { "PC98-Servers/X9NS3", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9NS3, NULL },
147 { "PC98-Servers/X9SPW", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9SPW, NULL },
148 { "PC98-Servers/X9SVG", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9SVG, NULL },
149 { "PC98-Servers/X9TGU", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9TGU, NULL },
150 { "PC98-Servers/X9WEP", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9WEP, NULL },
151 { "PC98-Servers/X9WS", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9WS, NULL },
152 { "PC98-Servers/X9WSN", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9WSN, NULL },
153 { "Servers/X8514", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_8514, NULL },
154 { "Servers/XAGX", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_AGX, NULL },
155 { "Servers/XI128", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_I128, NULL },
156 { "Servers/XMa8", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_MACH8, NULL },
157 { "Servers/XMa32", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_MACH32,NULL },
158 { "Servers/XMa64", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_MACH64,NULL },
159 { "Servers/XMono", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_MONO, NULL },
160 { "Servers/XP9K", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_P9000, NULL },
161 { "Servers/XS3", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_S3, NULL },
162 { "Servers/XS3V", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_S3V, NULL },
163 { "Servers/XSVGA", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_SVGA, NULL },
164 { "Servers/XVG16", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_VGA16, NULL },
165 { "Servers/XW32", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_W32, NULL },
166 { "Xnest", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_NEST, NULL },
170 /* The XFree86 font distribution */
171 static Distribution XF86FontDistTable[] = {
172 { "Xfnts", "/usr/X11R6", &XF86FontDists, DIST_XF86_FONTS_MISC, NULL },
173 { "Xf100", "/usr/X11R6", &XF86FontDists, DIST_XF86_FONTS_100, NULL },
174 { "Xfcyr", "/usr/X11R6", &XF86FontDists, DIST_XF86_FONTS_CYR, NULL },
175 { "Xfscl", "/usr/X11R6", &XF86FontDists, DIST_XF86_FONTS_SCALE, NULL },
176 { "Xfnon", "/usr/X11R6", &XF86FontDists, DIST_XF86_FONTS_NON, NULL },
177 { "Xfsrv", "/usr/X11R6", &XF86FontDists, DIST_XF86_FONTS_SERVER, NULL },
181 static int distMaybeSetDES(dialogMenuItem *self);
182 static int distMaybeSetPorts(dialogMenuItem *self);
186 distVerifyFlags(void)
191 if (DESDists & DIST_DES_KERBEROS)
192 DESDists |= DIST_DES_DES;
195 if (XF86Dists & DIST_XF86_SET)
196 XF86ServerDists |= DIST_XF86_SERVER_VGA16;
198 XF86Dists |= DIST_XF86_SERVER;
200 XF86Dists |= DIST_XF86_FONTS;
201 if (XF86Dists || XF86ServerDists || XF86FontDists)
204 msgDebug("Dist Masks: Dists: %0x, DES: %0x, Srcs: %0x\nXServer: %0x, XFonts: %0x, XDists: %0x\n",
205 Dists, DESDists, SrcDists, XF86ServerDists, XF86FontDists, XF86Dists);
209 distReset(dialogMenuItem *self)
217 return DITEM_SUCCESS | DITEM_REDRAW;
221 distConfig(dialogMenuItem *self)
227 if ((cp = variable_get(VAR_DIST_MAIN)) != NULL)
230 if ((cp = variable_get(VAR_DIST_DES)) != NULL)
233 if ((cp = variable_get(VAR_DIST_SRC)) != NULL)
236 if ((cp = variable_get(VAR_DIST_X11)) != NULL)
237 XF86Dists = atoi(cp);
239 if ((cp = variable_get(VAR_DIST_XSERVER)) != NULL)
240 XF86ServerDists = atoi(cp);
242 if ((cp = variable_get(VAR_DIST_XFONTS)) != NULL)
243 XF86FontDists = atoi(cp);
245 return DITEM_SUCCESS | DITEM_REDRAW;
249 distSetDeveloper(dialogMenuItem *self)
254 Dists = _DIST_DEVELOPER;
255 SrcDists = DIST_SRC_ALL;
256 i = distMaybeSetDES(self) | distMaybeSetPorts(self);
262 distSetXDeveloper(dialogMenuItem *self)
266 i = distSetDeveloper(self);
268 XF86Dists = DIST_XF86_BIN | DIST_XF86_SET | DIST_XF86_CFG | DIST_XF86_LIB | DIST_XF86_PROG | DIST_XF86_MAN | DIST_XF86_SERVER | DIST_XF86_FONTS;
269 XF86ServerDists = DIST_XF86_SERVER_SVGA | DIST_XF86_SERVER_VGA16;
270 XF86FontDists = DIST_XF86_FONTS_MISC;
271 i |= distSetXF86(NULL);
277 distSetKernDeveloper(dialogMenuItem *self)
282 Dists = _DIST_DEVELOPER;
283 SrcDists = DIST_SRC_SYS;
284 i = distMaybeSetDES(self) | distMaybeSetPorts(self);
290 distSetUser(dialogMenuItem *self)
296 i = distMaybeSetDES(self) | distMaybeSetPorts(self);
302 distSetXUser(dialogMenuItem *self)
306 i = distSetUser(self);
308 XF86ServerDists = DIST_XF86_SERVER_SVGA | DIST_XF86_SERVER_VGA16;
309 XF86Dists = DIST_XF86_BIN | DIST_XF86_SET | DIST_XF86_CFG | DIST_XF86_LIB | DIST_XF86_MAN | DIST_XF86_SERVER | DIST_XF86_FONTS;
310 XF86FontDists = DIST_XF86_FONTS_MISC;
311 i |= distSetXF86(NULL);
317 distSetMinimum(dialogMenuItem *self)
321 return DITEM_SUCCESS | DITEM_REDRAW;
325 distSetEverything(dialogMenuItem *self)
329 Dists = DIST_ALL | DIST_XF86;
330 SrcDists = DIST_SRC_ALL;
331 XF86Dists = DIST_XF86_ALL;
332 XF86ServerDists = DIST_XF86_SERVER_ALL;
333 XF86FontDists = DIST_XF86_FONTS_ALL;
334 i = distMaybeSetDES(self) | distMaybeSetPorts(self);
340 distSetDES(dialogMenuItem *self)
344 if (!dmenuOpenSimple(&MenuDESDistributions, FALSE))
349 return i | DITEM_RESTORE;
353 distMaybeSetDES(dialogMenuItem *self)
355 int i = DITEM_SUCCESS;
357 dialog_clear_norefresh();
358 if (!msgYesNo("Do wish to install DES cryptographic software?\n\n"
359 "If you choose No, FreeBSD will use an MD5 based password scheme which,\n"
360 "while perhaps more secure, is not interoperable with the traditional\n"
361 "UNIX DES passwords on other non-FreeBSD systems.\n\n"
362 "Please do NOT choose Yes at this point if you are outside the\n"
363 "United States and Canada yet are installing from a U.S. FTP server.\n"
364 "This will violate U.S. export restrictions and possibly get the\n"
365 "server site into trouble! In such cases, install everything but the\n"
366 "DES distribution from the U.S. server then switch your media type to\n"
367 "point to an international FTP server, using the Custom installation\n"
368 "option to select and extract the DES distribution in a second pass.")) {
369 if (!dmenuOpenSimple(&MenuDESDistributions, FALSE))
373 return i | DITEM_RESTORE;
377 distMaybeSetPorts(dialogMenuItem *self)
379 dialog_clear_norefresh();
380 if (!msgYesNo("Would you like to install the FreeBSD ports collection?\n\n"
381 "This will give you ready access to over 1000 ported software packages,\n"
382 "though at a cost of around 35MB of disk space when \"clean\" and possibly\n"
383 "much more than that if a lot of the distribution tarballs are loaded\n"
384 "(unless you have the 4th CD from a FreeBSD CDROM distribution available\n"
385 "and can mount it on /cdrom, in which case this is far less of a problem).\n\n"
386 "The ports collection is a very valuable resource and, if you have at least\n"
387 "100MB to spare in your /usr partition, well worth having around.\n\n"
388 "For more information on the ports collection & the latest ports, visit:\n"
389 " http://www.freebsd.org/ports\n"))
392 Dists &= ~DIST_PORTS;
393 return DITEM_SUCCESS | DITEM_RESTORE;
397 distSetByName(Distribution *dist, char *name)
399 int i, status = FALSE;
401 /* Loop through current set */
402 for (i = 0; dist[i].my_name; i++) {
403 /* This is shorthand for "dist currently disabled" */
406 if (!strcmp(dist[i].my_name, name)) {
407 *(dist[i].my_mask) |= dist[i].my_bit;
410 if (dist[i].my_dist) {
411 if (distSetByName(dist[i].my_dist, name)) {
420 /* Just for the dispatch stuff */
422 distSetCustom(dialogMenuItem *self)
424 char *cp, *cp2, *tmp;
426 if (!(tmp = variable_get(VAR_DISTS))) {
427 msgDebug("distSetCustom() called without %s variable set.\n", VAR_DISTS);
428 return DITEM_FAILURE;
431 cp = alloca(strlen(tmp) + 1);
433 msgFatal("Couldn't alloca() %d bytes!\n", strlen(tmp) + 1);
436 if ((cp2 = index(cp, ' ')) != NULL)
438 if (!distSetByName(DistTable, cp))
439 msgDebug("distSetCustom: Warning, no such release \"%s\"\n", cp);
443 return DITEM_SUCCESS;
447 distSetSrc(dialogMenuItem *self)
451 if (!dmenuOpenSimple(&MenuSrcDistributions, FALSE))
456 return i | DITEM_RESTORE;
460 distSetXF86(dialogMenuItem *self)
462 int i = DITEM_SUCCESS;
464 if (!dmenuOpenSimple(&MenuXF86Select, FALSE))
467 return i | DITEM_RESTORE;
470 static Boolean got_intr = FALSE;
472 /* timeout handler */
476 msgDebug("User generated interrupt.\n");
481 check_for_interrupt(void)
491 distExtract(char *parent, Distribution *me)
493 int i, status, total, intr;
494 int cpid, zpid, fd2, chunk, numchunks;
495 char *path, *dist, buf[BUFSIZ];
498 WINDOW *w = savescr();
499 struct timeval start, stop;
500 struct sigaction old, new;
503 dialog_clear_norefresh();
505 msgDebug("distExtract: parent: %s, me: %s\n", parent ? parent : "(none)", me->my_name);
507 /* Make ^C fake a sudden timeout */
508 new.sa_handler = handle_intr;
511 sigaction(SIGINT, &new, &old);
513 /* Loop through to see if we're in our parent's plans */
514 for (i = 0; me[i].my_name; i++) {
515 dist = me[i].my_name;
516 path = parent ? parent : dist;
518 /* If our bit isn't set, go to the next */
519 if (!(me[i].my_bit & *(me[i].my_mask)))
522 /* This is shorthand for "dist currently disabled" */
524 *(me[i].my_mask) &= ~(me[i].my_bit);
528 /* Recurse if we actually have a sub-distribution */
530 if ((status = distExtract(dist, me[i].my_dist)) == TRUE)
531 *(me[i].my_mask) &= ~(me[i].my_bit);
536 * Try to get distribution as multiple pieces, locating and parsing an
537 * info file which tells us how many we need for this distribution.
540 snprintf(buf, sizeof buf, "%s/%s.inf", path, dist);
543 fp = mediaDevice->get(mediaDevice, buf, TRUE);
544 intr = check_for_interrupt();
545 if (fp == (FILE *)IO_ERROR || intr) { /* Hard error, can't continue */
546 if (!msgYesNo("Unable to open %s: %s.\nReinitialize media?",
547 buf, !intr ? "I/O error." : "User interrupt.")) {
548 mediaDevice->shutdown(mediaDevice);
549 if (!mediaDevice->init(mediaDevice)) {
562 properties dist_attr;
565 msgDebug("Parsing attributes file for distribution %s\n", dist);
567 dist_attr = properties_read(fileno(fp));
568 intr = check_for_interrupt();
569 if (intr || !dist_attr) {
570 msgConfirm("Cannot parse information file for the %s distribution: %s\n"
571 "Please verify that your media is valid and try again.",
572 dist, !intr ? "I/O error" : "User interrupt");
575 tmp = property_find(dist_attr, "Pieces");
577 numchunks = strtol(tmp, 0, 0);
580 properties_free(dist_attr);
585 /* Try to get the distribution as a single file */
586 snprintf(buf, sizeof buf, "%s/%s.tgz", path, dist);
588 * Passing TRUE as 3rd parm to get routine makes this a "probing" get, for which errors
589 * are not considered too significant.
592 fp = mediaDevice->get(mediaDevice, buf, TRUE);
593 intr = check_for_interrupt();
594 if (fp == (FILE *)IO_ERROR || intr) { /* Hard error, can't continue */
595 if (intr) /* result of an interrupt */
596 msgConfirm("Unable to open %s: User interrupt", buf);
598 msgConfirm("Unable to open %s: I/O error", buf);
599 mediaDevice->shutdown(mediaDevice);
600 if (!mediaDevice->init(mediaDevice)) {
608 char *dir = root_bias(me[i].my_dir);
610 msgNotify("Extracting %s into %s directory...", dist, dir);
611 status = mediaExtractDist(dir, dist, fp);
619 /* Fall through from "we got the attribute file, now get the pieces" step */
624 msgDebug("Attempting to extract distribution from %u chunks.\n", numchunks);
627 (void)gettimeofday(&start, (struct timezone *)0);
629 /* We have one or more chunks, initialize unpackers... */
630 mediaExtractDistBegin(root_bias(me[i].my_dir), &fd2, &zpid, &cpid);
632 /* And go for all the chunks */
633 for (chunk = 0; chunk < numchunks; chunk++) {
634 int n, retval, last_msg;
640 snprintf(buf, sizeof buf, "%s/%s.%c%c", path, dist, (chunk / 26) + 'a', (chunk % 26) + 'a');
642 msgDebug("trying for piece %d of %d: %s\n", chunk + 1, numchunks, buf);
643 fp = mediaDevice->get(mediaDevice, buf, FALSE);
644 intr = check_for_interrupt();
645 if (fp <= (FILE *)0 || intr) {
647 msgConfirm("Failed to find %s on this media. Reinitializing media.", buf);
649 msgConfirm("failed to retreive piece file %s.\n"
650 "%s: Reinitializing media.", buf, !intr ? "I/O error" : "User interrupt");
651 mediaDevice->shutdown(mediaDevice);
652 if (!mediaDevice->init(mediaDevice))
658 snprintf(prompt, sizeof prompt, "Extracting %s into %s directory...", dist, root_bias(me[i].my_dir));
659 dialog_gauge("Progress", prompt, 8, 15, 6, 50, (int)((float)(chunk + 1) / numchunks * 100));
664 n = fread(buf, 1, BUFSIZ, fp);
665 if (check_for_interrupt()) {
666 msgConfirm("Media read error: User interrupt.");
674 /* Print statistics about how we're doing */
675 (void) gettimeofday(&stop, (struct timezone *)0);
676 stop.tv_sec = stop.tv_sec - start.tv_sec;
677 stop.tv_usec = stop.tv_usec - start.tv_usec;
678 if (stop.tv_usec < 0)
679 stop.tv_sec--, stop.tv_usec += 1000000;
680 seconds = stop.tv_sec + (stop.tv_usec / 1000000.0);
684 if (seconds != last_msg) {
686 msgInfo("%10d bytes read from %s dist, chunk %2d of %2d @ %.1f KB/sec.",
687 total, dist, chunk + 1, numchunks, (total / seconds) / 1024.0);
689 retval = write(fd2, buf, n);
692 dialog_clear_norefresh();
693 msgConfirm("Write failure on transfer! (wrote %d bytes of %d bytes)", retval, n);
700 status = mediaExtractDistEnd(zpid, cpid);
705 mediaExtractDistEnd(zpid, cpid);
711 msgConfirm("Unable to transfer all components of the %s distribution.\n"
712 "If this is a CDROM install, it may be because export restrictions prohibit\n"
713 "DES code from being shipped from the U.S. Try to get this code from a\n"
714 "local FTP site instead!", me[i].my_name);
717 status = msgYesNo("Unable to transfer the %s distribution from\n%s.\n\n"
718 "Do you want to try to retrieve it again?",
719 me[i].my_name, mediaDevice->name);
725 /* If extract was successful, remove ourselves from further consideration */
727 *(me[i].my_mask) &= ~(me[i].my_bit);
731 sigaction(SIGINT, &old, NULL); /* Restore signal handler */
737 printSelected(char *buf, int selected, Distribution *me, int *col)
741 /* Loop through to see if we're in our parent's plans */
742 for (i = 0; me[i].my_name; i++) {
744 /* If our bit isn't set, go to the next */
745 if (!(me[i].my_bit & selected))
748 /* This is shorthand for "dist currently disabled" */
752 *col += strlen(me[i].my_name);
757 sprintf(&buf[strlen(buf)], " %s", me[i].my_name);
758 /* Recurse if have a sub-distribution */
760 printSelected(buf, *(me[i].my_mask), me[i].my_dist, col);
765 distExtractAll(dialogMenuItem *self)
772 if (!dmenuOpenSimple(&MenuSubDistributions, FALSE) || !Dists)
773 return DITEM_FAILURE | DITEM_RESTORE;
776 if (!mediaVerify() || !mediaDevice->init(mediaDevice))
777 return DITEM_FAILURE;
780 dialog_clear_norefresh();
781 msgNotify("Attempting to install all selected distributions..");
782 /* Try for 3 times around the loop, then give up. */
783 while (Dists && ++retries < 3)
784 distExtract(NULL, DistTable);
790 printSelected(buf, Dists, DistTable, &col);
791 dialog_clear_norefresh();
792 msgConfirm("Couldn't extract the following distributions. This may\n"
793 "be because they were not available on the installation\n"
794 "media you've chosen:\n\n\t%s", buf);
795 return DITEM_SUCCESS | DITEM_RESTORE;
797 return DITEM_SUCCESS;