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.135 1999/02/07 12:57:04 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 { "compat22", "/", &Dists, DIST_COMPAT22, NULL },
80 { "ports", "/usr", &Dists, DIST_PORTS, NULL },
81 { "XF86333", "/usr", &Dists, DIST_XF86, XF86DistTable },
85 /* The DES distribution (not for export!) */
86 static Distribution DESDistTable[] = {
87 { "des", "/", &DESDists, DIST_DES_DES, NULL },
88 { "krb", "/", &DESDists, DIST_DES_KERBEROS, NULL },
89 { "ssecure", "/usr/src", &DESDists, DIST_DES_SSECURE, NULL },
90 { "scrypto", "/usr/src", &DESDists, DIST_DES_SCRYPTO, NULL },
91 { "skerbero", "/usr/src", &DESDists, DIST_DES_SKERBEROS, NULL },
95 /* The /usr/src distribution */
96 static Distribution SrcDistTable[] = {
97 { "sbase", "/usr/src", &SrcDists, DIST_SRC_BASE, NULL },
98 { "scontrib", "/usr/src", &SrcDists, DIST_SRC_CONTRIB, NULL },
99 { "sgnu", "/usr/src", &SrcDists, DIST_SRC_GNU, NULL },
100 { "setc", "/usr/src", &SrcDists, DIST_SRC_ETC, NULL },
101 { "sgames", "/usr/src", &SrcDists, DIST_SRC_GAMES, NULL },
102 { "sinclude", "/usr/src", &SrcDists, DIST_SRC_INCLUDE, NULL },
103 { "slib", "/usr/src", &SrcDists, DIST_SRC_LIB, NULL },
104 { "slibexec", "/usr/src", &SrcDists, DIST_SRC_LIBEXEC, 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 },
115 /* The XFree86 distribution */
116 static Distribution XF86DistTable[] = {
117 { "XF86333", "/usr/X11R6", &XF86Dists, DIST_XF86_FONTS, XF86FontDistTable },
118 { "XF86333", "/usr/X11R6", &XF86Dists, DIST_XF86_SERVER, XF86ServerDistTable },
119 { "Xsrc1", "/usr/X11R6/src", &XF86Dists, DIST_XF86_SRC, NULL },
120 { "Xsrcctrb", "/usr/X11R6/src", &XF86Dists, DIST_XF86_CSRC, NULL },
121 { "Xbin", "/usr/X11R6", &XF86Dists, DIST_XF86_BIN, NULL },
122 { "Xcfg", "/usr/X11R6", &XF86Dists, DIST_XF86_CFG, NULL },
123 { "Xdoc", "/usr/X11R6", &XF86Dists, DIST_XF86_DOC, NULL },
124 { "Xhtml", "/usr/X11R6", &XF86Dists, DIST_XF86_HTML, NULL },
125 { "Xlib", "/usr/X11R6", &XF86Dists, DIST_XF86_LIB, NULL },
126 { "Xlk98", "/usr/X11R6", &XF86Dists, DIST_XF86_LKIT98, NULL },
127 { "Xlkit", "/usr/X11R6", &XF86Dists, DIST_XF86_LKIT, NULL },
128 { "Xman", "/usr/X11R6", &XF86Dists, DIST_XF86_MAN, NULL },
129 { "Xprog", "/usr/X11R6", &XF86Dists, DIST_XF86_PROG, NULL },
130 { "Xps", "/usr/X11R6", &XF86Dists, DIST_XF86_PS, NULL },
131 { "Xset", "/usr/X11R6", &XF86Dists, DIST_XF86_SET, NULL },
132 { "X9set", "/usr/X11R6", &XF86Dists, DIST_XF86_9SET, NULL },
136 /* The XFree86 server distribution */
137 static Distribution XF86ServerDistTable[] = {
138 { "PC98-Servers/X9480", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9480, NULL },
139 { "PC98-Servers/X9EGC", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9EGC, NULL },
140 { "PC98-Servers/X9GA9", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9GA9, NULL },
141 { "PC98-Servers/X9GAN", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9GAN, NULL },
142 { "PC98-Servers/X9LPW", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9LPW, NULL },
143 { "PC98-Servers/X9MGA", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9MGA, NULL },
144 { "PC98-Servers/X9NKV", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9NKV, NULL },
145 { "PC98-Servers/X9NS3", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9NS3, NULL },
146 { "PC98-Servers/X9SPW", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9SPW, NULL },
147 { "PC98-Servers/X9SVG", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9SVG, NULL },
148 { "PC98-Servers/X9TGU", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9TGU, NULL },
149 { "PC98-Servers/X9WEP", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9WEP, NULL },
150 { "PC98-Servers/X9WS", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9WS, NULL },
151 { "PC98-Servers/X9WSN", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9WSN, NULL },
152 { "Servers/X8514", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_8514, NULL },
153 { "Servers/XAGX", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_AGX, NULL },
154 { "Servers/XI128", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_I128, NULL },
155 { "Servers/XMa8", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_MACH8, NULL },
156 { "Servers/XMa32", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_MACH32,NULL },
157 { "Servers/XMa64", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_MACH64,NULL },
158 { "Servers/XMono", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_MONO, NULL },
159 { "Servers/XP9K", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_P9000, NULL },
160 { "Servers/XS3", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_S3, NULL },
161 { "Servers/XS3V", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_S3V, NULL },
162 { "Servers/XSVGA", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_SVGA, NULL },
163 { "Servers/XVG16", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_VGA16, NULL },
164 { "Servers/XW32", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_W32, NULL },
165 { "Xnest", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_NEST, NULL },
169 /* The XFree86 font distribution */
170 static Distribution XF86FontDistTable[] = {
171 { "Xfnts", "/usr/X11R6", &XF86FontDists, DIST_XF86_FONTS_MISC, NULL },
172 { "Xf100", "/usr/X11R6", &XF86FontDists, DIST_XF86_FONTS_100, NULL },
173 { "Xfcyr", "/usr/X11R6", &XF86FontDists, DIST_XF86_FONTS_CYR, NULL },
174 { "Xfscl", "/usr/X11R6", &XF86FontDists, DIST_XF86_FONTS_SCALE, NULL },
175 { "Xfnon", "/usr/X11R6", &XF86FontDists, DIST_XF86_FONTS_NON, NULL },
176 { "Xfsrv", "/usr/X11R6", &XF86FontDists, DIST_XF86_FONTS_SERVER, NULL },
180 static int distMaybeSetDES(dialogMenuItem *self);
181 static int distMaybeSetPorts(dialogMenuItem *self);
185 distVerifyFlags(void)
190 if (DESDists & DIST_DES_KERBEROS)
191 DESDists |= DIST_DES_DES;
194 if (XF86Dists & DIST_XF86_SET)
195 XF86ServerDists |= DIST_XF86_SERVER_VGA16;
197 XF86Dists |= DIST_XF86_SERVER;
199 XF86Dists |= DIST_XF86_FONTS;
200 if (XF86Dists || XF86ServerDists || XF86FontDists)
202 if (Dists & DIST_XF86)
203 Dists |= DIST_COMPAT22;
205 msgDebug("Dist Masks: Dists: %0x, DES: %0x, Srcs: %0x\nXServer: %0x, XFonts: %0x, XDists: %0x\n",
206 Dists, DESDists, SrcDists, XF86ServerDists, XF86FontDists, XF86Dists);
210 distReset(dialogMenuItem *self)
218 return DITEM_SUCCESS | DITEM_REDRAW;
222 distConfig(dialogMenuItem *self)
228 if ((cp = variable_get(VAR_DIST_MAIN)) != NULL)
231 if ((cp = variable_get(VAR_DIST_DES)) != NULL)
234 if ((cp = variable_get(VAR_DIST_SRC)) != NULL)
237 if ((cp = variable_get(VAR_DIST_X11)) != NULL)
238 XF86Dists = atoi(cp);
240 if ((cp = variable_get(VAR_DIST_XSERVER)) != NULL)
241 XF86ServerDists = atoi(cp);
243 if ((cp = variable_get(VAR_DIST_XFONTS)) != NULL)
244 XF86FontDists = atoi(cp);
246 return DITEM_SUCCESS | DITEM_REDRAW;
250 distSetDeveloper(dialogMenuItem *self)
255 Dists = _DIST_DEVELOPER;
256 SrcDists = DIST_SRC_ALL;
257 i = distMaybeSetDES(self) | distMaybeSetPorts(self);
263 distSetXDeveloper(dialogMenuItem *self)
267 i = distSetDeveloper(self);
269 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;
270 XF86ServerDists = DIST_XF86_SERVER_SVGA | DIST_XF86_SERVER_VGA16;
271 XF86FontDists = DIST_XF86_FONTS_MISC;
272 i |= distSetXF86(NULL);
278 distSetKernDeveloper(dialogMenuItem *self)
283 Dists = _DIST_DEVELOPER;
284 SrcDists = DIST_SRC_SYS;
285 i = distMaybeSetDES(self) | distMaybeSetPorts(self);
291 distSetUser(dialogMenuItem *self)
297 i = distMaybeSetDES(self) | distMaybeSetPorts(self);
303 distSetXUser(dialogMenuItem *self)
307 i = distSetUser(self);
309 XF86ServerDists = DIST_XF86_SERVER_SVGA | DIST_XF86_SERVER_VGA16;
310 XF86Dists = DIST_XF86_BIN | DIST_XF86_SET | DIST_XF86_CFG | DIST_XF86_LIB | DIST_XF86_MAN | DIST_XF86_SERVER | DIST_XF86_FONTS;
311 XF86FontDists = DIST_XF86_FONTS_MISC;
312 i |= distSetXF86(NULL);
318 distSetMinimum(dialogMenuItem *self)
322 return DITEM_SUCCESS | DITEM_REDRAW;
326 distSetEverything(dialogMenuItem *self)
330 Dists = DIST_ALL | DIST_XF86;
331 SrcDists = DIST_SRC_ALL;
332 XF86Dists = DIST_XF86_ALL;
333 XF86ServerDists = DIST_XF86_SERVER_ALL;
334 XF86FontDists = DIST_XF86_FONTS_ALL;
335 i = distMaybeSetDES(self) | distMaybeSetPorts(self);
341 distSetDES(dialogMenuItem *self)
345 if (!dmenuOpenSimple(&MenuDESDistributions, FALSE))
350 return i | DITEM_RESTORE;
354 distMaybeSetDES(dialogMenuItem *self)
356 int i = DITEM_SUCCESS;
358 dialog_clear_norefresh();
359 if (!msgYesNo("Do wish to install DES cryptographic software?\n\n"
360 "If you choose No, FreeBSD will use an MD5 based password scheme which,\n"
361 "while perhaps more secure, is not interoperable with the traditional\n"
362 "UNIX DES passwords on other non-FreeBSD systems.\n\n"
363 "Please do NOT choose Yes at this point if you are outside the\n"
364 "United States and Canada yet are installing from a U.S. FTP server.\n"
365 "This will violate U.S. export restrictions and possibly get the\n"
366 "server site into trouble! In such cases, install everything but the\n"
367 "DES distribution from the U.S. server then switch your media type to\n"
368 "point to an international FTP server, using the Custom installation\n"
369 "option to select and extract the DES distribution in a second pass.")) {
370 if (!dmenuOpenSimple(&MenuDESDistributions, FALSE))
374 return i | DITEM_RESTORE;
378 distMaybeSetPorts(dialogMenuItem *self)
380 dialog_clear_norefresh();
381 if (!msgYesNo("Would you like to install the FreeBSD ports collection?\n\n"
382 "This will give you ready access to over 2000 ported software packages,\n"
383 "though at a cost of around 50MB of disk space when \"clean\" and possibly\n"
384 "much more than that if a lot of the distribution tarballs are loaded\n"
385 "(unless you have the extra CDs available from a FreeBSD CDROM distribution\n"
386 "and can mount them on /cdrom, in which case this is far less of a problem).\n\n"
387 "The ports collection is a very valuable resource and, if you have at least\n"
388 "100MB to spare in your /usr partition, well worth having around.\n\n"
389 "For more information on the ports collection & the latest ports, visit:\n"
390 " http://www.freebsd.org/ports\n"))
393 Dists &= ~DIST_PORTS;
394 return DITEM_SUCCESS | DITEM_RESTORE;
398 distSetByName(Distribution *dist, char *name)
400 int i, status = FALSE;
402 /* Loop through current set */
403 for (i = 0; dist[i].my_name; i++) {
404 /* This is shorthand for "dist currently disabled" */
407 if (!strcmp(dist[i].my_name, name)) {
408 *(dist[i].my_mask) |= dist[i].my_bit;
411 if (dist[i].my_dist) {
412 if (distSetByName(dist[i].my_dist, name)) {
421 /* Just for the dispatch stuff */
423 distSetCustom(dialogMenuItem *self)
425 char *cp, *cp2, *tmp;
427 if (!(tmp = variable_get(VAR_DISTS))) {
428 msgDebug("distSetCustom() called without %s variable set.\n", VAR_DISTS);
429 return DITEM_FAILURE;
432 cp = alloca(strlen(tmp) + 1);
434 msgFatal("Couldn't alloca() %d bytes!\n", strlen(tmp) + 1);
437 if ((cp2 = index(cp, ' ')) != NULL)
439 if (!distSetByName(DistTable, cp))
440 msgDebug("distSetCustom: Warning, no such release \"%s\"\n", cp);
444 return DITEM_SUCCESS;
448 distSetSrc(dialogMenuItem *self)
452 if (!dmenuOpenSimple(&MenuSrcDistributions, FALSE))
457 return i | DITEM_RESTORE;
461 distSetXF86(dialogMenuItem *self)
463 int i = DITEM_SUCCESS;
465 if (!dmenuOpenSimple(&MenuXF86Select, FALSE))
468 return i | DITEM_RESTORE;
471 static Boolean got_intr = FALSE;
473 /* timeout handler */
477 msgDebug("User generated interrupt.\n");
482 check_for_interrupt(void)
492 distExtract(char *parent, Distribution *me)
494 int i, status, total, intr;
495 int cpid, zpid, fd2, chunk, numchunks;
496 char *path, *dist, buf[BUFSIZ];
499 WINDOW *w = savescr();
500 struct timeval start, stop;
501 struct sigaction old, new;
504 dialog_clear_norefresh();
506 msgDebug("distExtract: parent: %s, me: %s\n", parent ? parent : "(none)", me->my_name);
508 /* Make ^C fake a sudden timeout */
509 new.sa_handler = handle_intr;
512 sigaction(SIGINT, &new, &old);
514 /* Loop through to see if we're in our parent's plans */
515 for (i = 0; me[i].my_name; i++) {
516 dist = me[i].my_name;
517 path = parent ? parent : dist;
519 /* If our bit isn't set, go to the next */
520 if (!(me[i].my_bit & *(me[i].my_mask)))
523 /* This is shorthand for "dist currently disabled" */
525 *(me[i].my_mask) &= ~(me[i].my_bit);
529 /* Recurse if we actually have a sub-distribution */
531 if ((status = distExtract(dist, me[i].my_dist)) == TRUE)
532 *(me[i].my_mask) &= ~(me[i].my_bit);
537 * Try to get distribution as multiple pieces, locating and parsing an
538 * info file which tells us how many we need for this distribution.
541 snprintf(buf, sizeof buf, "%s/%s.inf", path, dist);
544 fp = mediaDevice->get(mediaDevice, buf, TRUE);
545 intr = check_for_interrupt();
546 if (fp == (FILE *)IO_ERROR || intr) { /* Hard error, can't continue */
547 if (!msgYesNo("Unable to open %s: %s.\nReinitialize media?",
548 buf, !intr ? "I/O error." : "User interrupt.")) {
549 mediaDevice->shutdown(mediaDevice);
550 if (!mediaDevice->init(mediaDevice)) {
563 properties dist_attr;
566 msgDebug("Parsing attributes file for distribution %s\n", dist);
568 dist_attr = properties_read(fileno(fp));
569 intr = check_for_interrupt();
570 if (intr || !dist_attr) {
571 msgConfirm("Cannot parse information file for the %s distribution: %s\n"
572 "Please verify that your media is valid and try again.",
573 dist, !intr ? "I/O error" : "User interrupt");
576 tmp = property_find(dist_attr, "Pieces");
578 numchunks = strtol(tmp, 0, 0);
581 properties_free(dist_attr);
586 /* Try to get the distribution as a single file */
587 snprintf(buf, sizeof buf, "%s/%s.tgz", path, dist);
589 * Passing TRUE as 3rd parm to get routine makes this a "probing" get, for which errors
590 * are not considered too significant.
593 fp = mediaDevice->get(mediaDevice, buf, TRUE);
594 intr = check_for_interrupt();
595 if (fp == (FILE *)IO_ERROR || intr) { /* Hard error, can't continue */
596 if (intr) /* result of an interrupt */
597 msgConfirm("Unable to open %s: User interrupt", buf);
599 msgConfirm("Unable to open %s: I/O error", buf);
600 mediaDevice->shutdown(mediaDevice);
601 if (!mediaDevice->init(mediaDevice)) {
609 char *dir = root_bias(me[i].my_dir);
611 msgNotify("Extracting %s into %s directory...", dist, dir);
612 status = mediaExtractDist(dir, dist, fp);
620 /* Fall through from "we got the attribute file, now get the pieces" step */
625 msgDebug("Attempting to extract distribution from %u chunks.\n", numchunks);
628 (void)gettimeofday(&start, (struct timezone *)0);
630 /* We have one or more chunks, initialize unpackers... */
631 mediaExtractDistBegin(root_bias(me[i].my_dir), &fd2, &zpid, &cpid);
633 /* And go for all the chunks */
634 for (chunk = 0; chunk < numchunks; chunk++) {
635 int n, retval, last_msg;
641 snprintf(buf, sizeof buf, "%s/%s.%c%c", path, dist, (chunk / 26) + 'a', (chunk % 26) + 'a');
643 msgDebug("trying for piece %d of %d: %s\n", chunk + 1, numchunks, buf);
644 fp = mediaDevice->get(mediaDevice, buf, FALSE);
645 intr = check_for_interrupt();
646 if (fp <= (FILE *)0 || intr) {
648 msgConfirm("Failed to find %s on this media. Reinitializing media.", buf);
650 msgConfirm("failed to retreive piece file %s.\n"
651 "%s: Reinitializing media.", buf, !intr ? "I/O error" : "User interrupt");
652 mediaDevice->shutdown(mediaDevice);
653 if (!mediaDevice->init(mediaDevice))
659 snprintf(prompt, sizeof prompt, "Extracting %s into %s directory...", dist, root_bias(me[i].my_dir));
660 dialog_gauge("Progress", prompt, 8, 15, 6, 50, (int)((float)(chunk + 1) / numchunks * 100));
665 n = fread(buf, 1, BUFSIZ, fp);
666 if (check_for_interrupt()) {
667 msgConfirm("Media read error: User interrupt.");
675 /* Print statistics about how we're doing */
676 (void) gettimeofday(&stop, (struct timezone *)0);
677 stop.tv_sec = stop.tv_sec - start.tv_sec;
678 stop.tv_usec = stop.tv_usec - start.tv_usec;
679 if (stop.tv_usec < 0)
680 stop.tv_sec--, stop.tv_usec += 1000000;
681 seconds = stop.tv_sec + (stop.tv_usec / 1000000.0);
685 if (seconds != last_msg) {
687 msgInfo("%10d bytes read from %s dist, chunk %2d of %2d @ %.1f KB/sec.",
688 total, dist, chunk + 1, numchunks, (total / seconds) / 1024.0);
690 retval = write(fd2, buf, n);
693 dialog_clear_norefresh();
694 msgConfirm("Write failure on transfer! (wrote %d bytes of %d bytes)", retval, n);
701 status = mediaExtractDistEnd(zpid, cpid);
706 mediaExtractDistEnd(zpid, cpid);
712 msgConfirm("Unable to transfer all components of the %s distribution.\n"
713 "If this is a CDROM install, it may be because export restrictions prohibit\n"
714 "DES code from being shipped from the U.S. Try to get this code from a\n"
715 "local FTP site instead!", me[i].my_name);
718 status = msgYesNo("Unable to transfer the %s distribution from\n%s.\n\n"
719 "Do you want to try to retrieve it again?",
720 me[i].my_name, mediaDevice->name);
726 /* If extract was successful, remove ourselves from further consideration */
728 *(me[i].my_mask) &= ~(me[i].my_bit);
732 sigaction(SIGINT, &old, NULL); /* Restore signal handler */
738 printSelected(char *buf, int selected, Distribution *me, int *col)
742 /* Loop through to see if we're in our parent's plans */
743 for (i = 0; me[i].my_name; i++) {
745 /* If our bit isn't set, go to the next */
746 if (!(me[i].my_bit & selected))
749 /* This is shorthand for "dist currently disabled" */
753 *col += strlen(me[i].my_name);
758 sprintf(&buf[strlen(buf)], " %s", me[i].my_name);
759 /* Recurse if have a sub-distribution */
761 printSelected(buf, *(me[i].my_mask), me[i].my_dist, col);
766 distExtractAll(dialogMenuItem *self)
768 int old_dists, retries = 0, status = DITEM_SUCCESS;
773 if (!dmenuOpenSimple(&MenuSubDistributions, FALSE) || !Dists)
774 return DITEM_FAILURE | DITEM_RESTORE;
777 if (!mediaVerify() || !mediaDevice->init(mediaDevice))
778 return DITEM_FAILURE;
783 dialog_clear_norefresh();
784 msgNotify("Attempting to install all selected distributions..");
786 /* Try for 3 times around the loop, then give up. */
787 while (Dists && ++retries < 3)
788 distExtract(NULL, DistTable);
790 /* Only do bin fixup if bin dist was successfully extracted */
791 if ((old_dists & DIST_BIN) && !(Dists & DIST_BIN))
792 status |= installFixupBin(self);
793 if (old_dists & DIST_XF86)
794 status |= installFixupXFree(self);
800 printSelected(buf, Dists, DistTable, &col);
801 dialog_clear_norefresh();
802 msgConfirm("Couldn't extract the following distributions. This may\n"
803 "be because they were not available on the installation\n"
804 "media you've chosen:\n\n\t%s", buf);
805 status |= DITEM_RESTORE;