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.
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 { "local", "/", &Dists, DIST_LOCAL, NULL },
87 { "XF86335", "/usr", &Dists, DIST_XF86, XF86DistTable },
91 /* The DES distribution (not for export!) */
92 static Distribution DESDistTable[] = {
93 { "des", "/", &DESDists, DIST_DES_DES, NULL },
94 { "krb4", "/", &DESDists, DIST_DES_KERBEROS4, NULL },
95 { "ssecure", "/usr/src", &DESDists, DIST_DES_SSECURE, NULL },
96 { "scrypto", "/usr/src", &DESDists, DIST_DES_SCRYPTO, NULL },
97 { "skerbero", "/usr/src", &DESDists, DIST_DES_SKERBEROS, NULL },
101 /* The /usr/src distribution */
102 static Distribution SrcDistTable[] = {
103 { "sbase", "/usr/src", &SrcDists, DIST_SRC_BASE, NULL },
104 { "scontrib", "/usr/src", &SrcDists, DIST_SRC_CONTRIB, NULL },
105 { "sgnu", "/usr/src", &SrcDists, DIST_SRC_GNU, NULL },
106 { "setc", "/usr/src", &SrcDists, DIST_SRC_ETC, NULL },
107 { "sgames", "/usr/src", &SrcDists, DIST_SRC_GAMES, NULL },
108 { "sinclude", "/usr/src", &SrcDists, DIST_SRC_INCLUDE, NULL },
109 { "slib", "/usr/src", &SrcDists, DIST_SRC_LIB, NULL },
110 { "slibexec", "/usr/src", &SrcDists, DIST_SRC_LIBEXEC, NULL },
111 { "srelease", "/usr/src", &SrcDists, DIST_SRC_RELEASE, NULL },
112 { "sbin", "/usr/src", &SrcDists, DIST_SRC_BIN, NULL },
113 { "ssbin", "/usr/src", &SrcDists, DIST_SRC_SBIN, NULL },
114 { "sshare", "/usr/src", &SrcDists, DIST_SRC_SHARE, NULL },
115 { "ssys", "/usr/src", &SrcDists, DIST_SRC_SYS, NULL },
116 { "subin", "/usr/src", &SrcDists, DIST_SRC_UBIN, NULL },
117 { "susbin", "/usr/src", &SrcDists, DIST_SRC_USBIN, NULL },
121 /* The XFree86 distribution */
122 static Distribution XF86DistTable[] = {
123 { "XF86335", "/usr/X11R6", &XF86Dists, DIST_XF86_FONTS, XF86FontDistTable },
124 { "XF86335", "/usr/X11R6", &XF86Dists, DIST_XF86_SERVER, XF86ServerDistTable },
125 { "Xsrc1", "/usr/X11R6/src", &XF86Dists, DIST_XF86_SRC, NULL },
126 { "Xsrcctrb", "/usr/X11R6/src", &XF86Dists, DIST_XF86_CSRC, NULL },
127 { "Xbin", "/usr/X11R6", &XF86Dists, DIST_XF86_BIN, NULL },
128 { "Xcfg", "/usr/X11R6", &XF86Dists, DIST_XF86_CFG, NULL },
129 { "Xdoc", "/usr/X11R6", &XF86Dists, DIST_XF86_DOC, NULL },
130 { "Xhtml", "/usr/X11R6", &XF86Dists, DIST_XF86_HTML, NULL },
131 { "Xlib", "/usr/X11R6", &XF86Dists, DIST_XF86_LIB, NULL },
132 { "Xlk98", "/usr/X11R6", &XF86Dists, DIST_XF86_LKIT98, NULL },
133 { "Xlkit", "/usr/X11R6", &XF86Dists, DIST_XF86_LKIT, NULL },
134 { "Xman", "/usr/X11R6", &XF86Dists, DIST_XF86_MAN, NULL },
135 { "Xprog", "/usr/X11R6", &XF86Dists, DIST_XF86_PROG, NULL },
136 { "Xps", "/usr/X11R6", &XF86Dists, DIST_XF86_PS, NULL },
137 { "Xset", "/usr/X11R6", &XF86Dists, DIST_XF86_SET, NULL },
138 { "X9set", "/usr/X11R6", &XF86Dists, DIST_XF86_9SET, NULL },
142 /* The XFree86 server distribution */
143 static Distribution XF86ServerDistTable[] = {
145 { "PC98-Servers/X9480", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9480, NULL },
146 { "PC98-Servers/X9EGC", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9EGC, NULL },
147 { "PC98-Servers/X9GA9", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9GA9, NULL },
148 { "PC98-Servers/X9GAN", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9GAN, NULL },
149 { "PC98-Servers/X9LPW", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9LPW, NULL },
150 { "PC98-Servers/X9MGA", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9MGA, NULL },
151 { "PC98-Servers/X9NKV", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9NKV, NULL },
152 { "PC98-Servers/X9NS3", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9NS3, NULL },
153 { "PC98-Servers/X9SPW", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9SPW, NULL },
154 { "PC98-Servers/X9SVG", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9SVG, NULL },
155 { "PC98-Servers/X9TGU", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9TGU, NULL },
156 { "PC98-Servers/X9WEP", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9WEP, NULL },
157 { "PC98-Servers/X9WS", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9WS, NULL },
158 { "PC98-Servers/X9WSN", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_9WSN, NULL },
160 { "Servers/X3DL", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_3DL, NULL },
161 { "Servers/X8514", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_8514, NULL },
162 { "Servers/XAGX", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_AGX, NULL },
163 { "Servers/XI128", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_I128, NULL },
164 { "Servers/XMa8", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_MACH8, NULL },
165 { "Servers/XMa32", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_MACH32,NULL },
166 { "Servers/XMa64", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_MACH64,NULL },
167 { "Servers/XMono", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_MONO, NULL },
168 { "Servers/XP9K", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_P9000, NULL },
169 { "Servers/XS3", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_S3, NULL },
170 { "Servers/XS3V", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_S3V, NULL },
171 { "Servers/XSVGA", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_SVGA, NULL },
172 { "Servers/XVG16", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_VGA16, NULL },
173 { "Servers/XW32", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_W32, NULL },
175 { "Servers/XTGA", "/usr/X11R6", &XF86ServerDists, DIST_XF86_SERVER_TGA, NULL },
180 /* The XFree86 font distribution */
181 static Distribution XF86FontDistTable[] = {
182 { "Xfnts", "/usr/X11R6", &XF86FontDists, DIST_XF86_FONTS_MISC, NULL },
183 { "Xf100", "/usr/X11R6", &XF86FontDists, DIST_XF86_FONTS_100, NULL },
184 { "Xfcyr", "/usr/X11R6", &XF86FontDists, DIST_XF86_FONTS_CYR, NULL },
185 { "Xfscl", "/usr/X11R6", &XF86FontDists, DIST_XF86_FONTS_SCALE, NULL },
186 { "Xfnon", "/usr/X11R6", &XF86FontDists, DIST_XF86_FONTS_NON, NULL },
187 { "Xfsrv", "/usr/X11R6", &XF86FontDists, DIST_XF86_FONTS_SERVER, NULL },
191 static int distMaybeSetDES(dialogMenuItem *self);
192 static int distMaybeSetPorts(dialogMenuItem *self);
196 distVerifyFlags(void)
201 if (DESDists & DIST_DES_KERBEROS4)
202 DESDists |= DIST_DES_DES;
205 if (XF86Dists & DIST_XF86_SET)
206 XF86ServerDists |= DIST_XF86_SERVER_VGA16;
208 XF86Dists |= DIST_XF86_SERVER;
210 XF86Dists |= DIST_XF86_FONTS;
211 if (XF86Dists || XF86ServerDists || XF86FontDists) {
214 Dists |= DIST_COMPAT22; /* For certain old X applications */
218 msgDebug("Dist Masks: Dists: %0x, DES: %0x, Srcs: %0x\nXServer: %0x, XFonts: %0x, XDists: %0x\n",
219 Dists, DESDists, SrcDists, XF86ServerDists, XF86FontDists, XF86Dists);
223 distReset(dialogMenuItem *self)
231 return DITEM_SUCCESS | DITEM_REDRAW;
235 distConfig(dialogMenuItem *self)
241 if ((cp = variable_get(VAR_DIST_MAIN)) != NULL)
244 if ((cp = variable_get(VAR_DIST_DES)) != NULL)
247 if ((cp = variable_get(VAR_DIST_SRC)) != NULL)
250 if ((cp = variable_get(VAR_DIST_X11)) != NULL)
251 XF86Dists = atoi(cp);
253 if ((cp = variable_get(VAR_DIST_XSERVER)) != NULL)
254 XF86ServerDists = atoi(cp);
256 if ((cp = variable_get(VAR_DIST_XFONTS)) != NULL)
257 XF86FontDists = atoi(cp);
259 return DITEM_SUCCESS | DITEM_REDRAW;
266 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;
267 XF86ServerDists = DIST_XF86_SERVER_SVGA | DIST_XF86_SERVER_VGA16;
268 XF86FontDists = DIST_XF86_FONTS_MISC;
269 return distSetXF86(NULL);
273 distSetDeveloper(dialogMenuItem *self)
278 Dists = _DIST_DEVELOPER;
279 SrcDists = DIST_SRC_ALL;
280 i = distMaybeSetDES(self) | distMaybeSetPorts(self);
286 distSetXDeveloper(dialogMenuItem *self)
290 i = distSetDeveloper(self);
297 distSetKernDeveloper(dialogMenuItem *self)
302 Dists = _DIST_DEVELOPER;
303 SrcDists = DIST_SRC_SYS;
304 i = distMaybeSetDES(self) | distMaybeSetPorts(self);
310 distSetXKernDeveloper(dialogMenuItem *self)
314 i = distSetKernDeveloper(self);
321 distSetUser(dialogMenuItem *self)
327 i = distMaybeSetDES(self) | distMaybeSetPorts(self);
333 distSetXUser(dialogMenuItem *self)
337 i = distSetUser(self);
344 distSetMinimum(dialogMenuItem *self)
348 return DITEM_SUCCESS | DITEM_REDRAW;
352 distSetEverything(dialogMenuItem *self)
356 Dists = DIST_ALL | DIST_XF86;
357 SrcDists = DIST_SRC_ALL;
358 XF86Dists = DIST_XF86_ALL;
359 XF86ServerDists = DIST_XF86_SERVER_ALL;
360 XF86FontDists = DIST_XF86_FONTS_ALL;
361 i = distMaybeSetDES(self) | distMaybeSetPorts(self);
367 distSetDES(dialogMenuItem *self)
371 if (!dmenuOpenSimple(&MenuDESDistributions, FALSE))
376 return i | DITEM_RESTORE;
380 distMaybeSetDES(dialogMenuItem *self)
382 int i = DITEM_SUCCESS;
384 dialog_clear_norefresh();
385 if (!msgYesNo("Do wish to install DES cryptographic software?\n\n"
386 "If you choose No, FreeBSD will use an MD5 based password scheme which,\n"
387 "while perhaps more secure, is not interoperable with the traditional\n"
388 "UNIX DES passwords on other non-FreeBSD systems.\n\n"
389 "Please do NOT choose Yes at this point if you are outside the\n"
390 "United States and Canada yet are installing from a U.S. FTP server.\n"
391 "This will violate U.S. export restrictions and possibly get the\n"
392 "server site into trouble! In such cases, install everything but the\n"
393 "DES distribution from the U.S. server then switch your media type to\n"
394 "point to an international FTP server, using the Custom installation\n"
395 "option to select and extract the DES distribution in a second pass.")) {
396 if (!dmenuOpenSimple(&MenuDESDistributions, FALSE))
400 return i | DITEM_RESTORE;
404 distMaybeSetPorts(dialogMenuItem *self)
406 dialog_clear_norefresh();
407 if (!msgYesNo("Would you like to install the FreeBSD ports collection?\n\n"
408 "This will give you ready access to over 2000 ported software packages,\n"
409 "though at a cost of around 90MB of disk space when \"clean\" and possibly\n"
410 "much more than that if a lot of the distribution tarballs are loaded\n"
411 "(unless you have the extra CDs available from a FreeBSD CDROM distribution\n"
412 "and can mount them on /cdrom, in which case this is far less of a problem).\n\n"
413 "The ports collection is a very valuable resource and, if you have at least\n"
414 "100MB to spare in your /usr partition, well worth having around.\n\n"
415 "For more information on the ports collection & the latest ports, visit:\n"
416 " http://www.freebsd.org/ports\n"))
419 Dists &= ~DIST_PORTS;
420 return DITEM_SUCCESS | DITEM_RESTORE;
424 distSetByName(Distribution *dist, char *name)
426 int i, status = FALSE;
428 /* Loop through current set */
429 for (i = 0; dist[i].my_name; i++) {
430 /* This is shorthand for "dist currently disabled" */
433 if (!strcmp(dist[i].my_name, name)) {
434 *(dist[i].my_mask) |= dist[i].my_bit;
437 if (dist[i].my_dist) {
438 if (distSetByName(dist[i].my_dist, name)) {
447 /* Just for the dispatch stuff */
449 distSetCustom(dialogMenuItem *self)
451 char *cp, *cp2, *tmp;
453 if (!(tmp = variable_get(VAR_DISTS))) {
454 msgDebug("distSetCustom() called without %s variable set.\n", VAR_DISTS);
455 return DITEM_FAILURE;
458 cp = alloca(strlen(tmp) + 1);
460 msgFatal("Couldn't alloca() %d bytes!\n", strlen(tmp) + 1);
463 if ((cp2 = index(cp, ' ')) != NULL)
465 if (!distSetByName(DistTable, cp))
466 msgDebug("distSetCustom: Warning, no such release \"%s\"\n", cp);
470 return DITEM_SUCCESS;
474 distSetSrc(dialogMenuItem *self)
478 if (!dmenuOpenSimple(&MenuSrcDistributions, FALSE))
483 return i | DITEM_RESTORE;
487 distSetXF86(dialogMenuItem *self)
489 int i = DITEM_SUCCESS;
491 if (!dmenuOpenSimple(&MenuXF86Select, FALSE))
494 return i | DITEM_RESTORE;
497 static Boolean got_intr = FALSE;
499 /* timeout handler */
503 msgDebug("User generated interrupt.\n");
508 check_for_interrupt(void)
518 distExtract(char *parent, Distribution *me)
520 int i, status, total, intr;
521 int cpid, zpid, fd2, chunk, numchunks;
522 char *path, *dist, buf[BUFSIZ];
525 WINDOW *w = savescr();
526 struct timeval start, stop;
527 struct sigaction old, new;
530 dialog_clear_norefresh();
532 msgDebug("distExtract: parent: %s, me: %s\n", parent ? parent : "(none)", me->my_name);
534 /* Make ^C fake a sudden timeout */
535 new.sa_handler = handle_intr;
537 (void)sigemptyset(&new.sa_mask);
538 sigaction(SIGINT, &new, &old);
540 /* Loop through to see if we're in our parent's plans */
541 for (i = 0; me[i].my_name; i++) {
542 dist = me[i].my_name;
543 path = parent ? parent : dist;
545 /* If our bit isn't set, go to the next */
546 if (!(me[i].my_bit & *(me[i].my_mask)))
549 /* This is shorthand for "dist currently disabled" */
551 *(me[i].my_mask) &= ~(me[i].my_bit);
555 /* Recurse if we actually have a sub-distribution */
557 if ((status = distExtract(dist, me[i].my_dist)) == TRUE)
558 *(me[i].my_mask) &= ~(me[i].my_bit);
563 * Try to get distribution as multiple pieces, locating and parsing an
564 * info file which tells us how many we need for this distribution.
567 snprintf(buf, sizeof buf, "%s/%s.inf", path, dist);
570 fp = mediaDevice->get(mediaDevice, buf, TRUE);
571 intr = check_for_interrupt();
572 if (fp == (FILE *)IO_ERROR || intr) { /* Hard error, can't continue */
573 if (!msgYesNo("Unable to open %s: %s.\nReinitialize media?",
574 buf, !intr ? "I/O error." : "User interrupt.")) {
575 mediaDevice->shutdown(mediaDevice);
576 if (!mediaDevice->init(mediaDevice)) {
589 properties dist_attr;
592 msgDebug("Parsing attributes file for distribution %s\n", dist);
594 dist_attr = properties_read(fileno(fp));
595 intr = check_for_interrupt();
596 if (intr || !dist_attr) {
597 msgConfirm("Cannot parse information file for the %s distribution: %s\n"
598 "Please verify that your media is valid and try again.",
599 dist, !intr ? "I/O error" : "User interrupt");
602 tmp = property_find(dist_attr, "Pieces");
604 numchunks = strtol(tmp, 0, 0);
607 properties_free(dist_attr);
612 /* Try to get the distribution as a single file */
613 snprintf(buf, sizeof buf, "%s/%s.tgz", path, dist);
615 * Passing TRUE as 3rd parm to get routine makes this a "probing" get, for which errors
616 * are not considered too significant.
619 fp = mediaDevice->get(mediaDevice, buf, TRUE);
620 intr = check_for_interrupt();
621 if (fp == (FILE *)IO_ERROR || intr) { /* Hard error, can't continue */
622 if (intr) /* result of an interrupt */
623 msgConfirm("Unable to open %s: User interrupt", buf);
625 msgConfirm("Unable to open %s: I/O error", buf);
626 mediaDevice->shutdown(mediaDevice);
627 if (!mediaDevice->init(mediaDevice)) {
635 char *dir = root_bias(me[i].my_dir);
637 msgNotify("Extracting %s into %s directory...", dist, dir);
638 status = mediaExtractDist(dir, dist, fp);
646 /* Fall through from "we got the attribute file, now get the pieces" step */
651 msgDebug("Attempting to extract distribution from %u chunks.\n", numchunks);
654 (void)gettimeofday(&start, (struct timezone *)0);
656 /* We have one or more chunks, initialize unpackers... */
657 mediaExtractDistBegin(root_bias(me[i].my_dir), &fd2, &zpid, &cpid);
659 /* And go for all the chunks */
660 for (chunk = 0; chunk < numchunks; chunk++) {
661 int n, retval, last_msg;
667 snprintf(buf, sizeof buf, "%s/%s.%c%c", path, dist, (chunk / 26) + 'a', (chunk % 26) + 'a');
669 msgDebug("trying for piece %d of %d: %s\n", chunk + 1, numchunks, buf);
670 fp = mediaDevice->get(mediaDevice, buf, FALSE);
671 intr = check_for_interrupt();
672 if (fp <= (FILE *)0 || intr) {
674 msgConfirm("Failed to find %s on this media. Reinitializing media.", buf);
676 msgConfirm("failed to retreive piece file %s.\n"
677 "%s: Reinitializing media.", buf, !intr ? "I/O error" : "User interrupt");
678 mediaDevice->shutdown(mediaDevice);
679 if (!mediaDevice->init(mediaDevice))
685 snprintf(prompt, sizeof prompt, "Extracting %s into %s directory...", dist, root_bias(me[i].my_dir));
686 dialog_gauge("Progress", prompt, 8, 15, 6, 50, (int)((float)(chunk + 1) / numchunks * 100));
691 n = fread(buf, 1, BUFSIZ, fp);
692 if (check_for_interrupt()) {
693 msgConfirm("Media read error: User interrupt.");
701 /* Print statistics about how we're doing */
702 (void) gettimeofday(&stop, (struct timezone *)0);
703 stop.tv_sec = stop.tv_sec - start.tv_sec;
704 stop.tv_usec = stop.tv_usec - start.tv_usec;
705 if (stop.tv_usec < 0)
706 stop.tv_sec--, stop.tv_usec += 1000000;
707 seconds = stop.tv_sec + (stop.tv_usec / 1000000.0);
711 if (seconds != last_msg) {
713 msgInfo("%10d bytes read from %s dist, chunk %2d of %2d @ %.1f KB/sec.",
714 total, dist, chunk + 1, numchunks, (total / seconds) / 1024.0);
716 retval = write(fd2, buf, n);
719 dialog_clear_norefresh();
720 msgConfirm("Write failure on transfer! (wrote %d bytes of %d bytes)", retval, n);
727 status = mediaExtractDistEnd(zpid, cpid);
732 mediaExtractDistEnd(zpid, cpid);
738 msgConfirm("Unable to transfer all components of the %s distribution.\n"
739 "If this is a CDROM install, it may be because export restrictions prohibit\n"
740 "DES code from being shipped from the U.S. Try to get this code from a\n"
741 "local FTP site instead!", me[i].my_name);
744 status = msgYesNo("Unable to transfer the %s distribution from\n%s.\n\n"
745 "Do you want to try to retrieve it again?",
746 me[i].my_name, mediaDevice->name);
752 /* If extract was successful, remove ourselves from further consideration */
754 *(me[i].my_mask) &= ~(me[i].my_bit);
758 sigaction(SIGINT, &old, NULL); /* Restore signal handler */
764 printSelected(char *buf, int selected, Distribution *me, int *col)
768 /* Loop through to see if we're in our parent's plans */
769 for (i = 0; me[i].my_name; i++) {
771 /* If our bit isn't set, go to the next */
772 if (!(me[i].my_bit & selected))
775 /* This is shorthand for "dist currently disabled" */
779 *col += strlen(me[i].my_name);
784 sprintf(&buf[strlen(buf)], " %s", me[i].my_name);
785 /* Recurse if have a sub-distribution */
787 printSelected(buf, *(me[i].my_mask), me[i].my_dist, col);
792 distExtractAll(dialogMenuItem *self)
794 int old_dists, retries = 0, status = DITEM_SUCCESS;
799 if (!dmenuOpenSimple(&MenuSubDistributions, FALSE) || !Dists)
800 return DITEM_FAILURE | DITEM_RESTORE;
803 if (!mediaVerify() || !mediaDevice->init(mediaDevice))
804 return DITEM_FAILURE;
809 dialog_clear_norefresh();
810 msgNotify("Attempting to install all selected distributions..");
812 /* Try for 3 times around the loop, then give up. */
813 while (Dists && ++retries < 3)
814 distExtract(NULL, DistTable);
816 /* Only do bin fixup if bin dist was successfully extracted */
817 if ((old_dists & DIST_BIN) && !(Dists & DIST_BIN))
818 status |= installFixupBin(self);
819 if (old_dists & DIST_XF86)
820 status |= installFixupXFree(self);
826 printSelected(buf, Dists, DistTable, &col);
827 dialog_clear_norefresh();
828 msgConfirm("Couldn't extract the following distributions. This may\n"
829 "be because they were not available on the installation\n"
830 "media you've chosen:\n\n\t%s", buf);
831 status |= DITEM_RESTORE;