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.143 1999/07/19 11:58:01 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[] = {
144 { "PC98-Servers/X9480", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9480, NULL },
145 { "PC98-Servers/X9EGC", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9EGC, NULL },
146 { "PC98-Servers/X9GA9", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9GA9, NULL },
147 { "PC98-Servers/X9GAN", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9GAN, NULL },
148 { "PC98-Servers/X9LPW", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9LPW, NULL },
149 { "PC98-Servers/X9MGA", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9MGA, NULL },
150 { "PC98-Servers/X9NKV", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9NKV, NULL },
151 { "PC98-Servers/X9NS3", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9NS3, NULL },
152 { "PC98-Servers/X9SPW", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9SPW, NULL },
153 { "PC98-Servers/X9SVG", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9SVG, NULL },
154 { "PC98-Servers/X9TGU", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9TGU, NULL },
155 { "PC98-Servers/X9WEP", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9WEP, NULL },
156 { "PC98-Servers/X9WS", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9WS, NULL },
157 { "PC98-Servers/X9WSN", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9WSN, NULL },
159 { "Servers/X3DL", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_3DL, NULL },
160 { "Servers/X8514", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_8514, NULL },
161 { "Servers/XAGX", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_AGX, NULL },
162 { "Servers/XI128", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_I128, NULL },
163 { "Servers/XMa8", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_MACH8, NULL },
164 { "Servers/XMa32", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_MACH32,NULL },
165 { "Servers/XMa64", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_MACH64,NULL },
166 { "Servers/XMono", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_MONO, NULL },
167 { "Servers/XP9K", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_P9000, NULL },
168 { "Servers/XS3", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_S3, NULL },
169 { "Servers/XS3V", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_S3V, NULL },
170 { "Servers/XSVGA", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_SVGA, NULL },
171 { "Servers/XVG16", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_VGA16, NULL },
172 { "Servers/XW32", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_W32, NULL },
174 { "Servers/XTGA", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_TGA, NULL },
179 /* The XFree86 font distribution */
180 static Distribution XF86FontDistTable[] = {
181 { "Xfnts", "/usr/X11R6", &XF86FontDists, DIST_XF86_FONTS_MISC, NULL },
182 { "Xf100", "/usr/X11R6", &XF86FontDists, DIST_XF86_FONTS_100, NULL },
183 { "Xfcyr", "/usr/X11R6", &XF86FontDists, DIST_XF86_FONTS_CYR, NULL },
184 { "Xfscl", "/usr/X11R6", &XF86FontDists, DIST_XF86_FONTS_SCALE, NULL },
185 { "Xfnon", "/usr/X11R6", &XF86FontDists, DIST_XF86_FONTS_NON, NULL },
186 { "Xfsrv", "/usr/X11R6", &XF86FontDists, DIST_XF86_FONTS_SERVER, NULL },
190 static int distMaybeSetDES(dialogMenuItem *self);
191 static int distMaybeSetPorts(dialogMenuItem *self);
195 distVerifyFlags(void)
200 if (DESDists & DIST_DES_KERBEROS)
201 DESDists |= DIST_DES_DES;
204 if (XF86Dists & DIST_XF86_SET)
205 XF86ServerDists |= DIST_XF86_SERVER_VGA16;
207 XF86Dists |= DIST_XF86_SERVER;
209 XF86Dists |= DIST_XF86_FONTS;
210 if (XF86Dists || XF86ServerDists || XF86FontDists) {
213 Dists |= DIST_COMPAT22; /* For certain old X applications */
217 msgDebug("Dist Masks: Dists: %0x, DES: %0x, Srcs: %0x\nXServer: %0x, XFonts: %0x, XDists: %0x\n",
218 Dists, DESDists, SrcDists, XF86ServerDists, XF86FontDists, XF86Dists);
222 distReset(dialogMenuItem *self)
230 return DITEM_SUCCESS | DITEM_REDRAW;
234 distConfig(dialogMenuItem *self)
240 if ((cp = variable_get(VAR_DIST_MAIN)) != NULL)
243 if ((cp = variable_get(VAR_DIST_DES)) != NULL)
246 if ((cp = variable_get(VAR_DIST_SRC)) != NULL)
249 if ((cp = variable_get(VAR_DIST_X11)) != NULL)
250 XF86Dists = atoi(cp);
252 if ((cp = variable_get(VAR_DIST_XSERVER)) != NULL)
253 XF86ServerDists = atoi(cp);
255 if ((cp = variable_get(VAR_DIST_XFONTS)) != NULL)
256 XF86FontDists = atoi(cp);
258 return DITEM_SUCCESS | DITEM_REDRAW;
265 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;
266 XF86ServerDists = DIST_XF86_SERVER_SVGA | DIST_XF86_SERVER_VGA16;
267 XF86FontDists = DIST_XF86_FONTS_MISC;
268 return distSetXF86(NULL);
272 distSetDeveloper(dialogMenuItem *self)
277 Dists = _DIST_DEVELOPER;
278 SrcDists = DIST_SRC_ALL;
279 i = distMaybeSetDES(self) | distMaybeSetPorts(self);
285 distSetXDeveloper(dialogMenuItem *self)
289 i = distSetDeveloper(self);
296 distSetKernDeveloper(dialogMenuItem *self)
301 Dists = _DIST_DEVELOPER;
302 SrcDists = DIST_SRC_SYS;
303 i = distMaybeSetDES(self) | distMaybeSetPorts(self);
309 distSetXKernDeveloper(dialogMenuItem *self)
313 i = distSetKernDeveloper(self);
320 distSetUser(dialogMenuItem *self)
326 i = distMaybeSetDES(self) | distMaybeSetPorts(self);
332 distSetXUser(dialogMenuItem *self)
336 i = distSetUser(self);
343 distSetMinimum(dialogMenuItem *self)
347 return DITEM_SUCCESS | DITEM_REDRAW;
351 distSetEverything(dialogMenuItem *self)
355 Dists = DIST_ALL | DIST_XF86;
356 SrcDists = DIST_SRC_ALL;
357 XF86Dists = DIST_XF86_ALL;
358 XF86ServerDists = DIST_XF86_SERVER_ALL;
359 XF86FontDists = DIST_XF86_FONTS_ALL;
360 i = distMaybeSetDES(self) | distMaybeSetPorts(self);
366 distSetDES(dialogMenuItem *self)
370 if (!dmenuOpenSimple(&MenuDESDistributions, FALSE))
375 return i | DITEM_RESTORE;
379 distMaybeSetDES(dialogMenuItem *self)
381 int i = DITEM_SUCCESS;
383 dialog_clear_norefresh();
384 if (!msgYesNo("Do wish to install DES cryptographic software?\n\n"
385 "If you choose No, FreeBSD will use an MD5 based password scheme which,\n"
386 "while perhaps more secure, is not interoperable with the traditional\n"
387 "UNIX DES passwords on other non-FreeBSD systems.\n\n"
388 "Please do NOT choose Yes at this point if you are outside the\n"
389 "United States and Canada yet are installing from a U.S. FTP server.\n"
390 "This will violate U.S. export restrictions and possibly get the\n"
391 "server site into trouble! In such cases, install everything but the\n"
392 "DES distribution from the U.S. server then switch your media type to\n"
393 "point to an international FTP server, using the Custom installation\n"
394 "option to select and extract the DES distribution in a second pass.")) {
395 if (!dmenuOpenSimple(&MenuDESDistributions, FALSE))
399 return i | DITEM_RESTORE;
403 distMaybeSetPorts(dialogMenuItem *self)
405 dialog_clear_norefresh();
406 if (!msgYesNo("Would you like to install the FreeBSD ports collection?\n\n"
407 "This will give you ready access to over 2000 ported software packages,\n"
408 "though at a cost of around 90MB of disk space when \"clean\" and possibly\n"
409 "much more than that if a lot of the distribution tarballs are loaded\n"
410 "(unless you have the extra CDs available from a FreeBSD CDROM distribution\n"
411 "and can mount them on /cdrom, in which case this is far less of a problem).\n\n"
412 "The ports collection is a very valuable resource and, if you have at least\n"
413 "100MB to spare in your /usr partition, well worth having around.\n\n"
414 "For more information on the ports collection & the latest ports, visit:\n"
415 " http://www.freebsd.org/ports\n"))
418 Dists &= ~DIST_PORTS;
419 return DITEM_SUCCESS | DITEM_RESTORE;
423 distSetByName(Distribution *dist, char *name)
425 int i, status = FALSE;
427 /* Loop through current set */
428 for (i = 0; dist[i].my_name; i++) {
429 /* This is shorthand for "dist currently disabled" */
432 if (!strcmp(dist[i].my_name, name)) {
433 *(dist[i].my_mask) |= dist[i].my_bit;
436 if (dist[i].my_dist) {
437 if (distSetByName(dist[i].my_dist, name)) {
446 /* Just for the dispatch stuff */
448 distSetCustom(dialogMenuItem *self)
450 char *cp, *cp2, *tmp;
452 if (!(tmp = variable_get(VAR_DISTS))) {
453 msgDebug("distSetCustom() called without %s variable set.\n", VAR_DISTS);
454 return DITEM_FAILURE;
457 cp = alloca(strlen(tmp) + 1);
459 msgFatal("Couldn't alloca() %d bytes!\n", strlen(tmp) + 1);
462 if ((cp2 = index(cp, ' ')) != NULL)
464 if (!distSetByName(DistTable, cp))
465 msgDebug("distSetCustom: Warning, no such release \"%s\"\n", cp);
469 return DITEM_SUCCESS;
473 distSetSrc(dialogMenuItem *self)
477 if (!dmenuOpenSimple(&MenuSrcDistributions, FALSE))
482 return i | DITEM_RESTORE;
486 distSetXF86(dialogMenuItem *self)
488 int i = DITEM_SUCCESS;
490 if (!dmenuOpenSimple(&MenuXF86Select, FALSE))
493 return i | DITEM_RESTORE;
496 static Boolean got_intr = FALSE;
498 /* timeout handler */
502 msgDebug("User generated interrupt.\n");
507 check_for_interrupt(void)
517 distExtract(char *parent, Distribution *me)
519 int i, status, total, intr;
520 int cpid, zpid, fd2, chunk, numchunks;
521 char *path, *dist, buf[BUFSIZ];
524 WINDOW *w = savescr();
525 struct timeval start, stop;
526 struct sigaction old, new;
529 dialog_clear_norefresh();
531 msgDebug("distExtract: parent: %s, me: %s\n", parent ? parent : "(none)", me->my_name);
533 /* Make ^C fake a sudden timeout */
534 new.sa_handler = handle_intr;
537 sigaction(SIGINT, &new, &old);
539 /* Loop through to see if we're in our parent's plans */
540 for (i = 0; me[i].my_name; i++) {
541 dist = me[i].my_name;
542 path = parent ? parent : dist;
544 /* If our bit isn't set, go to the next */
545 if (!(me[i].my_bit & *(me[i].my_mask)))
548 /* This is shorthand for "dist currently disabled" */
550 *(me[i].my_mask) &= ~(me[i].my_bit);
554 /* Recurse if we actually have a sub-distribution */
556 if ((status = distExtract(dist, me[i].my_dist)) == TRUE)
557 *(me[i].my_mask) &= ~(me[i].my_bit);
562 * Try to get distribution as multiple pieces, locating and parsing an
563 * info file which tells us how many we need for this distribution.
566 snprintf(buf, sizeof buf, "%s/%s.inf", path, dist);
569 fp = mediaDevice->get(mediaDevice, buf, TRUE);
570 intr = check_for_interrupt();
571 if (fp == (FILE *)IO_ERROR || intr) { /* Hard error, can't continue */
572 if (!msgYesNo("Unable to open %s: %s.\nReinitialize media?",
573 buf, !intr ? "I/O error." : "User interrupt.")) {
574 mediaDevice->shutdown(mediaDevice);
575 if (!mediaDevice->init(mediaDevice)) {
588 properties dist_attr;
591 msgDebug("Parsing attributes file for distribution %s\n", dist);
593 dist_attr = properties_read(fileno(fp));
594 intr = check_for_interrupt();
595 if (intr || !dist_attr) {
596 msgConfirm("Cannot parse information file for the %s distribution: %s\n"
597 "Please verify that your media is valid and try again.",
598 dist, !intr ? "I/O error" : "User interrupt");
601 tmp = property_find(dist_attr, "Pieces");
603 numchunks = strtol(tmp, 0, 0);
606 properties_free(dist_attr);
611 /* Try to get the distribution as a single file */
612 snprintf(buf, sizeof buf, "%s/%s.tgz", path, dist);
614 * Passing TRUE as 3rd parm to get routine makes this a "probing" get, for which errors
615 * are not considered too significant.
618 fp = mediaDevice->get(mediaDevice, buf, TRUE);
619 intr = check_for_interrupt();
620 if (fp == (FILE *)IO_ERROR || intr) { /* Hard error, can't continue */
621 if (intr) /* result of an interrupt */
622 msgConfirm("Unable to open %s: User interrupt", buf);
624 msgConfirm("Unable to open %s: I/O error", buf);
625 mediaDevice->shutdown(mediaDevice);
626 if (!mediaDevice->init(mediaDevice)) {
634 char *dir = root_bias(me[i].my_dir);
636 msgNotify("Extracting %s into %s directory...", dist, dir);
637 status = mediaExtractDist(dir, dist, fp);
645 /* Fall through from "we got the attribute file, now get the pieces" step */
650 msgDebug("Attempting to extract distribution from %u chunks.\n", numchunks);
653 (void)gettimeofday(&start, (struct timezone *)0);
655 /* We have one or more chunks, initialize unpackers... */
656 mediaExtractDistBegin(root_bias(me[i].my_dir), &fd2, &zpid, &cpid);
658 /* And go for all the chunks */
659 for (chunk = 0; chunk < numchunks; chunk++) {
660 int n, retval, last_msg;
666 snprintf(buf, sizeof buf, "%s/%s.%c%c", path, dist, (chunk / 26) + 'a', (chunk % 26) + 'a');
668 msgDebug("trying for piece %d of %d: %s\n", chunk + 1, numchunks, buf);
669 fp = mediaDevice->get(mediaDevice, buf, FALSE);
670 intr = check_for_interrupt();
671 if (fp <= (FILE *)0 || intr) {
673 msgConfirm("Failed to find %s on this media. Reinitializing media.", buf);
675 msgConfirm("failed to retreive piece file %s.\n"
676 "%s: Reinitializing media.", buf, !intr ? "I/O error" : "User interrupt");
677 mediaDevice->shutdown(mediaDevice);
678 if (!mediaDevice->init(mediaDevice))
684 snprintf(prompt, sizeof prompt, "Extracting %s into %s directory...", dist, root_bias(me[i].my_dir));
685 dialog_gauge("Progress", prompt, 8, 15, 6, 50, (int)((float)(chunk + 1) / numchunks * 100));
690 n = fread(buf, 1, BUFSIZ, fp);
691 if (check_for_interrupt()) {
692 msgConfirm("Media read error: User interrupt.");
700 /* Print statistics about how we're doing */
701 (void) gettimeofday(&stop, (struct timezone *)0);
702 stop.tv_sec = stop.tv_sec - start.tv_sec;
703 stop.tv_usec = stop.tv_usec - start.tv_usec;
704 if (stop.tv_usec < 0)
705 stop.tv_sec--, stop.tv_usec += 1000000;
706 seconds = stop.tv_sec + (stop.tv_usec / 1000000.0);
710 if (seconds != last_msg) {
712 msgInfo("%10d bytes read from %s dist, chunk %2d of %2d @ %.1f KB/sec.",
713 total, dist, chunk + 1, numchunks, (total / seconds) / 1024.0);
715 retval = write(fd2, buf, n);
718 dialog_clear_norefresh();
719 msgConfirm("Write failure on transfer! (wrote %d bytes of %d bytes)", retval, n);
726 status = mediaExtractDistEnd(zpid, cpid);
731 mediaExtractDistEnd(zpid, cpid);
737 msgConfirm("Unable to transfer all components of the %s distribution.\n"
738 "If this is a CDROM install, it may be because export restrictions prohibit\n"
739 "DES code from being shipped from the U.S. Try to get this code from a\n"
740 "local FTP site instead!", me[i].my_name);
743 status = msgYesNo("Unable to transfer the %s distribution from\n%s.\n\n"
744 "Do you want to try to retrieve it again?",
745 me[i].my_name, mediaDevice->name);
751 /* If extract was successful, remove ourselves from further consideration */
753 *(me[i].my_mask) &= ~(me[i].my_bit);
757 sigaction(SIGINT, &old, NULL); /* Restore signal handler */
763 printSelected(char *buf, int selected, Distribution *me, int *col)
767 /* Loop through to see if we're in our parent's plans */
768 for (i = 0; me[i].my_name; i++) {
770 /* If our bit isn't set, go to the next */
771 if (!(me[i].my_bit & selected))
774 /* This is shorthand for "dist currently disabled" */
778 *col += strlen(me[i].my_name);
783 sprintf(&buf[strlen(buf)], " %s", me[i].my_name);
784 /* Recurse if have a sub-distribution */
786 printSelected(buf, *(me[i].my_mask), me[i].my_dist, col);
791 distExtractAll(dialogMenuItem *self)
793 int old_dists, retries = 0, status = DITEM_SUCCESS;
798 if (!dmenuOpenSimple(&MenuSubDistributions, FALSE) || !Dists)
799 return DITEM_FAILURE | DITEM_RESTORE;
802 if (!mediaVerify() || !mediaDevice->init(mediaDevice))
803 return DITEM_FAILURE;
808 dialog_clear_norefresh();
809 msgNotify("Attempting to install all selected distributions..");
811 /* Try for 3 times around the loop, then give up. */
812 while (Dists && ++retries < 3)
813 distExtract(NULL, DistTable);
815 /* Only do bin fixup if bin dist was successfully extracted */
816 if ((old_dists & DIST_BIN) && !(Dists & DIST_BIN))
817 status |= installFixupBin(self);
818 if (old_dists & DIST_XF86)
819 status |= installFixupXFree(self);
825 printSelected(buf, Dists, DistTable, &col);
826 dialog_clear_norefresh();
827 msgConfirm("Couldn't extract the following distributions. This may\n"
828 "be because they were not available on the installation\n"
829 "media you've chosen:\n\n\t%s", buf);
830 status |= DITEM_RESTORE;