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.142 1999/07/16 22:03:26 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 },
77 { "compat1x", "/", &Dists, DIST_COMPAT1X, NULL },
78 { "compat20", "/", &Dists, DIST_COMPAT20, NULL },
79 { "compat21", "/", &Dists, DIST_COMPAT21, NULL },
80 { "compat22", "/", &Dists, DIST_COMPAT22, NULL },
82 { "compat3x", "/", &Dists, DIST_COMPAT3X, NULL },
85 { "ports", "/usr", &Dists, DIST_PORTS, NULL },
86 { "XF86334", "/usr", &Dists, DIST_XF86, XF86DistTable },
90 /* The DES distribution (not for export!) */
91 static Distribution DESDistTable[] = {
92 { "des", "/", &DESDists, DIST_DES_DES, NULL },
93 { "krb", "/", &DESDists, DIST_DES_KERBEROS, NULL },
94 { "ssecure", "/usr/src", &DESDists, DIST_DES_SSECURE, NULL },
95 { "scrypto", "/usr/src", &DESDists, DIST_DES_SCRYPTO, NULL },
96 { "skerbero", "/usr/src", &DESDists, DIST_DES_SKERBEROS, NULL },
100 /* The /usr/src distribution */
101 static Distribution SrcDistTable[] = {
102 { "sbase", "/usr/src", &SrcDists, DIST_SRC_BASE, NULL },
103 { "scontrib", "/usr/src", &SrcDists, DIST_SRC_CONTRIB, NULL },
104 { "sgnu", "/usr/src", &SrcDists, DIST_SRC_GNU, NULL },
105 { "setc", "/usr/src", &SrcDists, DIST_SRC_ETC, NULL },
106 { "sgames", "/usr/src", &SrcDists, DIST_SRC_GAMES, NULL },
107 { "sinclude", "/usr/src", &SrcDists, DIST_SRC_INCLUDE, NULL },
108 { "slib", "/usr/src", &SrcDists, DIST_SRC_LIB, NULL },
109 { "slibexec", "/usr/src", &SrcDists, DIST_SRC_LIBEXEC, NULL },
110 { "srelease", "/usr/src", &SrcDists, DIST_SRC_RELEASE, NULL },
111 { "sbin", "/usr/src", &SrcDists, DIST_SRC_BIN, NULL },
112 { "ssbin", "/usr/src", &SrcDists, DIST_SRC_SBIN, NULL },
113 { "sshare", "/usr/src", &SrcDists, DIST_SRC_SHARE, NULL },
114 { "ssys", "/usr/src", &SrcDists, DIST_SRC_SYS, NULL },
115 { "subin", "/usr/src", &SrcDists, DIST_SRC_UBIN, NULL },
116 { "susbin", "/usr/src", &SrcDists, DIST_SRC_USBIN, NULL },
120 /* The XFree86 distribution */
121 static Distribution XF86DistTable[] = {
122 { "XF86334", "/usr/X11R6", &XF86Dists, DIST_XF86_FONTS, XF86FontDistTable },
123 { "XF86334", "/usr/X11R6", &XF86Dists, DIST_XF86_SERVER, XF86ServerDistTable },
124 { "Xsrc1", "/usr/X11R6/src", &XF86Dists, DIST_XF86_SRC, NULL },
125 { "Xsrcctrb", "/usr/X11R6/src", &XF86Dists, DIST_XF86_CSRC, NULL },
126 { "Xbin", "/usr/X11R6", &XF86Dists, DIST_XF86_BIN, NULL },
127 { "Xcfg", "/usr/X11R6", &XF86Dists, DIST_XF86_CFG, NULL },
128 { "Xdoc", "/usr/X11R6", &XF86Dists, DIST_XF86_DOC, NULL },
129 { "Xhtml", "/usr/X11R6", &XF86Dists, DIST_XF86_HTML, NULL },
130 { "Xlib", "/usr/X11R6", &XF86Dists, DIST_XF86_LIB, NULL },
131 { "Xlk98", "/usr/X11R6", &XF86Dists, DIST_XF86_LKIT98, NULL },
132 { "Xlkit", "/usr/X11R6", &XF86Dists, DIST_XF86_LKIT, NULL },
133 { "Xman", "/usr/X11R6", &XF86Dists, DIST_XF86_MAN, NULL },
134 { "Xprog", "/usr/X11R6", &XF86Dists, DIST_XF86_PROG, NULL },
135 { "Xps", "/usr/X11R6", &XF86Dists, DIST_XF86_PS, NULL },
136 { "Xset", "/usr/X11R6", &XF86Dists, DIST_XF86_SET, NULL },
137 { "X9set", "/usr/X11R6", &XF86Dists, DIST_XF86_9SET, NULL },
141 /* The XFree86 server distribution */
142 static Distribution XF86ServerDistTable[] = {
143 { "PC98-Servers/X9480", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9480, NULL },
144 { "PC98-Servers/X9EGC", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9EGC, NULL },
145 { "PC98-Servers/X9GA9", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9GA9, NULL },
146 { "PC98-Servers/X9GAN", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9GAN, NULL },
147 { "PC98-Servers/X9LPW", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9LPW, NULL },
148 { "PC98-Servers/X9MGA", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9MGA, NULL },
149 { "PC98-Servers/X9NKV", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9NKV, NULL },
150 { "PC98-Servers/X9NS3", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9NS3, NULL },
151 { "PC98-Servers/X9SPW", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9SPW, NULL },
152 { "PC98-Servers/X9SVG", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9SVG, NULL },
153 { "PC98-Servers/X9TGU", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9TGU, NULL },
154 { "PC98-Servers/X9WEP", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9WEP, NULL },
155 { "PC98-Servers/X9WS", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9WS, NULL },
156 { "PC98-Servers/X9WSN", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9WSN, NULL },
157 { "Servers/X3DL", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_3DL, NULL },
158 { "Servers/X8514", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_8514, NULL },
159 { "Servers/XAGX", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_AGX, NULL },
160 { "Servers/XI128", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_I128, NULL },
161 { "Servers/XMa8", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_MACH8, NULL },
162 { "Servers/XMa32", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_MACH32,NULL },
163 { "Servers/XMa64", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_MACH64,NULL },
164 { "Servers/XMono", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_MONO, NULL },
165 { "Servers/XP9K", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_P9000, NULL },
166 { "Servers/XS3", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_S3, NULL },
167 { "Servers/XS3V", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_S3V, NULL },
168 { "Servers/XSVGA", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_SVGA, NULL },
169 { "Servers/XVG16", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_VGA16, NULL },
170 { "Servers/XW32", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_W32, NULL },
174 /* The XFree86 font distribution */
175 static Distribution XF86FontDistTable[] = {
176 { "Xfnts", "/usr/X11R6", &XF86FontDists, DIST_XF86_FONTS_MISC, NULL },
177 { "Xf100", "/usr/X11R6", &XF86FontDists, DIST_XF86_FONTS_100, NULL },
178 { "Xfcyr", "/usr/X11R6", &XF86FontDists, DIST_XF86_FONTS_CYR, NULL },
179 { "Xfscl", "/usr/X11R6", &XF86FontDists, DIST_XF86_FONTS_SCALE, NULL },
180 { "Xfnon", "/usr/X11R6", &XF86FontDists, DIST_XF86_FONTS_NON, NULL },
181 { "Xfsrv", "/usr/X11R6", &XF86FontDists, DIST_XF86_FONTS_SERVER, NULL },
185 static int distMaybeSetDES(dialogMenuItem *self);
186 static int distMaybeSetPorts(dialogMenuItem *self);
190 distVerifyFlags(void)
195 if (DESDists & DIST_DES_KERBEROS)
196 DESDists |= DIST_DES_DES;
199 if (XF86Dists & DIST_XF86_SET)
200 XF86ServerDists |= DIST_XF86_SERVER_VGA16;
202 XF86Dists |= DIST_XF86_SERVER;
204 XF86Dists |= DIST_XF86_FONTS;
205 if (XF86Dists || XF86ServerDists || XF86FontDists) {
208 Dists |= DIST_COMPAT22; /* For certain old X applications */
212 msgDebug("Dist Masks: Dists: %0x, DES: %0x, Srcs: %0x\nXServer: %0x, XFonts: %0x, XDists: %0x\n",
213 Dists, DESDists, SrcDists, XF86ServerDists, XF86FontDists, XF86Dists);
217 distReset(dialogMenuItem *self)
225 return DITEM_SUCCESS | DITEM_REDRAW;
229 distConfig(dialogMenuItem *self)
235 if ((cp = variable_get(VAR_DIST_MAIN)) != NULL)
238 if ((cp = variable_get(VAR_DIST_DES)) != NULL)
241 if ((cp = variable_get(VAR_DIST_SRC)) != NULL)
244 if ((cp = variable_get(VAR_DIST_X11)) != NULL)
245 XF86Dists = atoi(cp);
247 if ((cp = variable_get(VAR_DIST_XSERVER)) != NULL)
248 XF86ServerDists = atoi(cp);
250 if ((cp = variable_get(VAR_DIST_XFONTS)) != NULL)
251 XF86FontDists = atoi(cp);
253 return DITEM_SUCCESS | DITEM_REDRAW;
260 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;
261 XF86ServerDists = DIST_XF86_SERVER_SVGA | DIST_XF86_SERVER_VGA16;
262 XF86FontDists = DIST_XF86_FONTS_MISC;
263 return distSetXF86(NULL);
267 distSetDeveloper(dialogMenuItem *self)
272 Dists = _DIST_DEVELOPER;
273 SrcDists = DIST_SRC_ALL;
274 i = distMaybeSetDES(self) | distMaybeSetPorts(self);
280 distSetXDeveloper(dialogMenuItem *self)
284 i = distSetDeveloper(self);
291 distSetKernDeveloper(dialogMenuItem *self)
296 Dists = _DIST_DEVELOPER;
297 SrcDists = DIST_SRC_SYS;
298 i = distMaybeSetDES(self) | distMaybeSetPorts(self);
304 distSetXKernDeveloper(dialogMenuItem *self)
308 i = distSetKernDeveloper(self);
315 distSetUser(dialogMenuItem *self)
321 i = distMaybeSetDES(self) | distMaybeSetPorts(self);
327 distSetXUser(dialogMenuItem *self)
331 i = distSetUser(self);
338 distSetMinimum(dialogMenuItem *self)
342 return DITEM_SUCCESS | DITEM_REDRAW;
346 distSetEverything(dialogMenuItem *self)
350 Dists = DIST_ALL | DIST_XF86;
351 SrcDists = DIST_SRC_ALL;
352 XF86Dists = DIST_XF86_ALL;
353 XF86ServerDists = DIST_XF86_SERVER_ALL;
354 XF86FontDists = DIST_XF86_FONTS_ALL;
355 i = distMaybeSetDES(self) | distMaybeSetPorts(self);
361 distSetDES(dialogMenuItem *self)
365 if (!dmenuOpenSimple(&MenuDESDistributions, FALSE))
370 return i | DITEM_RESTORE;
374 distMaybeSetDES(dialogMenuItem *self)
376 int i = DITEM_SUCCESS;
378 dialog_clear_norefresh();
379 if (!msgYesNo("Do wish to install DES cryptographic software?\n\n"
380 "If you choose No, FreeBSD will use an MD5 based password scheme which,\n"
381 "while perhaps more secure, is not interoperable with the traditional\n"
382 "UNIX DES passwords on other non-FreeBSD systems.\n\n"
383 "Please do NOT choose Yes at this point if you are outside the\n"
384 "United States and Canada yet are installing from a U.S. FTP server.\n"
385 "This will violate U.S. export restrictions and possibly get the\n"
386 "server site into trouble! In such cases, install everything but the\n"
387 "DES distribution from the U.S. server then switch your media type to\n"
388 "point to an international FTP server, using the Custom installation\n"
389 "option to select and extract the DES distribution in a second pass.")) {
390 if (!dmenuOpenSimple(&MenuDESDistributions, FALSE))
394 return i | DITEM_RESTORE;
398 distMaybeSetPorts(dialogMenuItem *self)
400 dialog_clear_norefresh();
401 if (!msgYesNo("Would you like to install the FreeBSD ports collection?\n\n"
402 "This will give you ready access to over 2000 ported software packages,\n"
403 "though at a cost of around 90MB of disk space when \"clean\" and possibly\n"
404 "much more than that if a lot of the distribution tarballs are loaded\n"
405 "(unless you have the extra CDs available from a FreeBSD CDROM distribution\n"
406 "and can mount them on /cdrom, in which case this is far less of a problem).\n\n"
407 "The ports collection is a very valuable resource and, if you have at least\n"
408 "100MB to spare in your /usr partition, well worth having around.\n\n"
409 "For more information on the ports collection & the latest ports, visit:\n"
410 " http://www.freebsd.org/ports\n"))
413 Dists &= ~DIST_PORTS;
414 return DITEM_SUCCESS | DITEM_RESTORE;
418 distSetByName(Distribution *dist, char *name)
420 int i, status = FALSE;
422 /* Loop through current set */
423 for (i = 0; dist[i].my_name; i++) {
424 /* This is shorthand for "dist currently disabled" */
427 if (!strcmp(dist[i].my_name, name)) {
428 *(dist[i].my_mask) |= dist[i].my_bit;
431 if (dist[i].my_dist) {
432 if (distSetByName(dist[i].my_dist, name)) {
441 /* Just for the dispatch stuff */
443 distSetCustom(dialogMenuItem *self)
445 char *cp, *cp2, *tmp;
447 if (!(tmp = variable_get(VAR_DISTS))) {
448 msgDebug("distSetCustom() called without %s variable set.\n", VAR_DISTS);
449 return DITEM_FAILURE;
452 cp = alloca(strlen(tmp) + 1);
454 msgFatal("Couldn't alloca() %d bytes!\n", strlen(tmp) + 1);
457 if ((cp2 = index(cp, ' ')) != NULL)
459 if (!distSetByName(DistTable, cp))
460 msgDebug("distSetCustom: Warning, no such release \"%s\"\n", cp);
464 return DITEM_SUCCESS;
468 distSetSrc(dialogMenuItem *self)
472 if (!dmenuOpenSimple(&MenuSrcDistributions, FALSE))
477 return i | DITEM_RESTORE;
481 distSetXF86(dialogMenuItem *self)
483 int i = DITEM_SUCCESS;
485 if (!dmenuOpenSimple(&MenuXF86Select, FALSE))
488 return i | DITEM_RESTORE;
491 static Boolean got_intr = FALSE;
493 /* timeout handler */
497 msgDebug("User generated interrupt.\n");
502 check_for_interrupt(void)
512 distExtract(char *parent, Distribution *me)
514 int i, status, total, intr;
515 int cpid, zpid, fd2, chunk, numchunks;
516 char *path, *dist, buf[BUFSIZ];
519 WINDOW *w = savescr();
520 struct timeval start, stop;
521 struct sigaction old, new;
524 dialog_clear_norefresh();
526 msgDebug("distExtract: parent: %s, me: %s\n", parent ? parent : "(none)", me->my_name);
528 /* Make ^C fake a sudden timeout */
529 new.sa_handler = handle_intr;
532 sigaction(SIGINT, &new, &old);
534 /* Loop through to see if we're in our parent's plans */
535 for (i = 0; me[i].my_name; i++) {
536 dist = me[i].my_name;
537 path = parent ? parent : dist;
539 /* If our bit isn't set, go to the next */
540 if (!(me[i].my_bit & *(me[i].my_mask)))
543 /* This is shorthand for "dist currently disabled" */
545 *(me[i].my_mask) &= ~(me[i].my_bit);
549 /* Recurse if we actually have a sub-distribution */
551 if ((status = distExtract(dist, me[i].my_dist)) == TRUE)
552 *(me[i].my_mask) &= ~(me[i].my_bit);
557 * Try to get distribution as multiple pieces, locating and parsing an
558 * info file which tells us how many we need for this distribution.
561 snprintf(buf, sizeof buf, "%s/%s.inf", path, dist);
564 fp = mediaDevice->get(mediaDevice, buf, TRUE);
565 intr = check_for_interrupt();
566 if (fp == (FILE *)IO_ERROR || intr) { /* Hard error, can't continue */
567 if (!msgYesNo("Unable to open %s: %s.\nReinitialize media?",
568 buf, !intr ? "I/O error." : "User interrupt.")) {
569 mediaDevice->shutdown(mediaDevice);
570 if (!mediaDevice->init(mediaDevice)) {
583 properties dist_attr;
586 msgDebug("Parsing attributes file for distribution %s\n", dist);
588 dist_attr = properties_read(fileno(fp));
589 intr = check_for_interrupt();
590 if (intr || !dist_attr) {
591 msgConfirm("Cannot parse information file for the %s distribution: %s\n"
592 "Please verify that your media is valid and try again.",
593 dist, !intr ? "I/O error" : "User interrupt");
596 tmp = property_find(dist_attr, "Pieces");
598 numchunks = strtol(tmp, 0, 0);
601 properties_free(dist_attr);
606 /* Try to get the distribution as a single file */
607 snprintf(buf, sizeof buf, "%s/%s.tgz", path, dist);
609 * Passing TRUE as 3rd parm to get routine makes this a "probing" get, for which errors
610 * are not considered too significant.
613 fp = mediaDevice->get(mediaDevice, buf, TRUE);
614 intr = check_for_interrupt();
615 if (fp == (FILE *)IO_ERROR || intr) { /* Hard error, can't continue */
616 if (intr) /* result of an interrupt */
617 msgConfirm("Unable to open %s: User interrupt", buf);
619 msgConfirm("Unable to open %s: I/O error", buf);
620 mediaDevice->shutdown(mediaDevice);
621 if (!mediaDevice->init(mediaDevice)) {
629 char *dir = root_bias(me[i].my_dir);
631 msgNotify("Extracting %s into %s directory...", dist, dir);
632 status = mediaExtractDist(dir, dist, fp);
640 /* Fall through from "we got the attribute file, now get the pieces" step */
645 msgDebug("Attempting to extract distribution from %u chunks.\n", numchunks);
648 (void)gettimeofday(&start, (struct timezone *)0);
650 /* We have one or more chunks, initialize unpackers... */
651 mediaExtractDistBegin(root_bias(me[i].my_dir), &fd2, &zpid, &cpid);
653 /* And go for all the chunks */
654 for (chunk = 0; chunk < numchunks; chunk++) {
655 int n, retval, last_msg;
661 snprintf(buf, sizeof buf, "%s/%s.%c%c", path, dist, (chunk / 26) + 'a', (chunk % 26) + 'a');
663 msgDebug("trying for piece %d of %d: %s\n", chunk + 1, numchunks, buf);
664 fp = mediaDevice->get(mediaDevice, buf, FALSE);
665 intr = check_for_interrupt();
666 if (fp <= (FILE *)0 || intr) {
668 msgConfirm("Failed to find %s on this media. Reinitializing media.", buf);
670 msgConfirm("failed to retreive piece file %s.\n"
671 "%s: Reinitializing media.", buf, !intr ? "I/O error" : "User interrupt");
672 mediaDevice->shutdown(mediaDevice);
673 if (!mediaDevice->init(mediaDevice))
679 snprintf(prompt, sizeof prompt, "Extracting %s into %s directory...", dist, root_bias(me[i].my_dir));
680 dialog_gauge("Progress", prompt, 8, 15, 6, 50, (int)((float)(chunk + 1) / numchunks * 100));
685 n = fread(buf, 1, BUFSIZ, fp);
686 if (check_for_interrupt()) {
687 msgConfirm("Media read error: User interrupt.");
695 /* Print statistics about how we're doing */
696 (void) gettimeofday(&stop, (struct timezone *)0);
697 stop.tv_sec = stop.tv_sec - start.tv_sec;
698 stop.tv_usec = stop.tv_usec - start.tv_usec;
699 if (stop.tv_usec < 0)
700 stop.tv_sec--, stop.tv_usec += 1000000;
701 seconds = stop.tv_sec + (stop.tv_usec / 1000000.0);
705 if (seconds != last_msg) {
707 msgInfo("%10d bytes read from %s dist, chunk %2d of %2d @ %.1f KB/sec.",
708 total, dist, chunk + 1, numchunks, (total / seconds) / 1024.0);
710 retval = write(fd2, buf, n);
713 dialog_clear_norefresh();
714 msgConfirm("Write failure on transfer! (wrote %d bytes of %d bytes)", retval, n);
721 status = mediaExtractDistEnd(zpid, cpid);
726 mediaExtractDistEnd(zpid, cpid);
732 msgConfirm("Unable to transfer all components of the %s distribution.\n"
733 "If this is a CDROM install, it may be because export restrictions prohibit\n"
734 "DES code from being shipped from the U.S. Try to get this code from a\n"
735 "local FTP site instead!", me[i].my_name);
738 status = msgYesNo("Unable to transfer the %s distribution from\n%s.\n\n"
739 "Do you want to try to retrieve it again?",
740 me[i].my_name, mediaDevice->name);
746 /* If extract was successful, remove ourselves from further consideration */
748 *(me[i].my_mask) &= ~(me[i].my_bit);
752 sigaction(SIGINT, &old, NULL); /* Restore signal handler */
758 printSelected(char *buf, int selected, Distribution *me, int *col)
762 /* Loop through to see if we're in our parent's plans */
763 for (i = 0; me[i].my_name; i++) {
765 /* If our bit isn't set, go to the next */
766 if (!(me[i].my_bit & selected))
769 /* This is shorthand for "dist currently disabled" */
773 *col += strlen(me[i].my_name);
778 sprintf(&buf[strlen(buf)], " %s", me[i].my_name);
779 /* Recurse if have a sub-distribution */
781 printSelected(buf, *(me[i].my_mask), me[i].my_dist, col);
786 distExtractAll(dialogMenuItem *self)
788 int old_dists, retries = 0, status = DITEM_SUCCESS;
793 if (!dmenuOpenSimple(&MenuSubDistributions, FALSE) || !Dists)
794 return DITEM_FAILURE | DITEM_RESTORE;
797 if (!mediaVerify() || !mediaDevice->init(mediaDevice))
798 return DITEM_FAILURE;
803 dialog_clear_norefresh();
804 msgNotify("Attempting to install all selected distributions..");
806 /* Try for 3 times around the loop, then give up. */
807 while (Dists && ++retries < 3)
808 distExtract(NULL, DistTable);
810 /* Only do bin fixup if bin dist was successfully extracted */
811 if ((old_dists & DIST_BIN) && !(Dists & DIST_BIN))
812 status |= installFixupBin(self);
813 if (old_dists & DIST_XF86)
814 status |= installFixupXFree(self);
820 printSelected(buf, Dists, DistTable, &col);
821 dialog_clear_norefresh();
822 msgConfirm("Couldn't extract the following distributions. This may\n"
823 "be because they were not available on the installation\n"
824 "media you've chosen:\n\n\t%s", buf);
825 status |= DITEM_RESTORE;