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)) {
448 distUnsetByName(Distribution *dist, char *name)
450 int i, status = FALSE;
452 /* Loop through current set */
453 for (i = 0; dist[i].my_name; i++) {
454 /* This is shorthand for "dist currently disabled" */
457 if (!strcmp(dist[i].my_name, name)) {
458 *(dist[i].my_mask) &= ~(dist[i].my_bit);
461 if (dist[i].my_dist) {
462 if (distUnsetByName(dist[i].my_dist, name)) {
470 /* Just for the dispatch stuff */
472 distSetCustom(dialogMenuItem *self)
474 char *cp, *cp2, *tmp;
476 if (!(tmp = variable_get(VAR_DISTS))) {
477 msgDebug("distSetCustom() called without %s variable set.\n", VAR_DISTS);
478 return DITEM_FAILURE;
481 cp = alloca(strlen(tmp) + 1);
483 msgFatal("Couldn't alloca() %d bytes!\n", strlen(tmp) + 1);
486 if ((cp2 = index(cp, ' ')) != NULL)
488 if (!distSetByName(DistTable, cp))
489 msgDebug("distSetCustom: Warning, no such release \"%s\"\n", cp);
493 return DITEM_SUCCESS;
496 /* Just for the dispatch stuff */
498 distUnsetCustom(dialogMenuItem *self)
500 char *cp, *cp2, *tmp;
502 if (!(tmp = variable_get(VAR_DISTS))) {
503 msgDebug("distUnsetCustom() called without %s variable set.\n", VAR_DISTS);
504 return DITEM_FAILURE;
507 cp = alloca(strlen(tmp) + 1);
509 msgFatal("Couldn't alloca() %d bytes!\n", strlen(tmp) + 1);
512 if ((cp2 = index(cp, ' ')) != NULL)
514 if (!distUnsetByName(DistTable, cp))
515 msgDebug("distUnsetCustom: Warning, no such release \"%s\"\n", cp);
518 return DITEM_SUCCESS;
522 distSetSrc(dialogMenuItem *self)
526 if (!dmenuOpenSimple(&MenuSrcDistributions, FALSE))
531 return i | DITEM_RESTORE;
535 distSetXF86(dialogMenuItem *self)
537 int i = DITEM_SUCCESS;
539 if (!dmenuOpenSimple(&MenuXF86Select, FALSE))
542 return i | DITEM_RESTORE;
545 static Boolean got_intr = FALSE;
547 /* timeout handler */
551 msgDebug("User generated interrupt.\n");
556 check_for_interrupt(void)
566 distExtract(char *parent, Distribution *me)
568 int i, status, total, intr;
569 int cpid, zpid, fd2, chunk, numchunks;
570 char *path, *dist, buf[BUFSIZ];
573 WINDOW *w = savescr();
574 struct timeval start, stop;
575 struct sigaction old, new;
578 dialog_clear_norefresh();
580 msgDebug("distExtract: parent: %s, me: %s\n", parent ? parent : "(none)", me->my_name);
582 /* Make ^C fake a sudden timeout */
583 new.sa_handler = handle_intr;
585 (void)sigemptyset(&new.sa_mask);
586 sigaction(SIGINT, &new, &old);
588 /* Loop through to see if we're in our parent's plans */
589 for (i = 0; me[i].my_name; i++) {
590 dist = me[i].my_name;
591 path = parent ? parent : dist;
593 /* If our bit isn't set, go to the next */
594 if (!(me[i].my_bit & *(me[i].my_mask)))
597 /* This is shorthand for "dist currently disabled" */
599 *(me[i].my_mask) &= ~(me[i].my_bit);
603 /* Recurse if we actually have a sub-distribution */
605 if ((status = distExtract(dist, me[i].my_dist)) == TRUE)
606 *(me[i].my_mask) &= ~(me[i].my_bit);
611 * Try to get distribution as multiple pieces, locating and parsing an
612 * info file which tells us how many we need for this distribution.
615 snprintf(buf, sizeof buf, "%s/%s.inf", path, dist);
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 (!msgYesNo("Unable to open %s: %s.\nReinitialize media?",
622 buf, !intr ? "I/O error." : "User interrupt.")) {
623 mediaDevice->shutdown(mediaDevice);
624 if (!mediaDevice->init(mediaDevice)) {
637 properties dist_attr;
640 msgDebug("Parsing attributes file for distribution %s\n", dist);
642 dist_attr = properties_read(fileno(fp));
643 intr = check_for_interrupt();
644 if (intr || !dist_attr) {
645 msgConfirm("Cannot parse information file for the %s distribution: %s\n"
646 "Please verify that your media is valid and try again.",
647 dist, !intr ? "I/O error" : "User interrupt");
650 tmp = property_find(dist_attr, "Pieces");
652 numchunks = strtol(tmp, 0, 0);
655 properties_free(dist_attr);
660 /* Try to get the distribution as a single file */
661 snprintf(buf, sizeof buf, "%s/%s.tgz", path, dist);
663 * Passing TRUE as 3rd parm to get routine makes this a "probing" get, for which errors
664 * are not considered too significant.
667 fp = mediaDevice->get(mediaDevice, buf, TRUE);
668 intr = check_for_interrupt();
669 if (fp == (FILE *)IO_ERROR || intr) { /* Hard error, can't continue */
670 if (intr) /* result of an interrupt */
671 msgConfirm("Unable to open %s: User interrupt", buf);
673 msgConfirm("Unable to open %s: I/O error", buf);
674 mediaDevice->shutdown(mediaDevice);
675 if (!mediaDevice->init(mediaDevice)) {
683 char *dir = root_bias(me[i].my_dir);
685 msgNotify("Extracting %s into %s directory...", dist, dir);
686 status = mediaExtractDist(dir, dist, fp);
694 /* Fall through from "we got the attribute file, now get the pieces" step */
699 msgDebug("Attempting to extract distribution from %u chunks.\n", numchunks);
702 (void)gettimeofday(&start, (struct timezone *)0);
704 /* We have one or more chunks, initialize unpackers... */
705 mediaExtractDistBegin(root_bias(me[i].my_dir), &fd2, &zpid, &cpid);
707 /* And go for all the chunks */
708 for (chunk = 0; chunk < numchunks; chunk++) {
709 int n, retval, last_msg;
715 snprintf(buf, sizeof buf, "%s/%s.%c%c", path, dist, (chunk / 26) + 'a', (chunk % 26) + 'a');
717 msgDebug("trying for piece %d of %d: %s\n", chunk + 1, numchunks, buf);
718 fp = mediaDevice->get(mediaDevice, buf, FALSE);
719 intr = check_for_interrupt();
720 if (fp <= (FILE *)0 || intr) {
722 msgConfirm("Failed to find %s on this media. Reinitializing media.", buf);
724 msgConfirm("failed to retreive piece file %s.\n"
725 "%s: Reinitializing media.", buf, !intr ? "I/O error" : "User interrupt");
726 mediaDevice->shutdown(mediaDevice);
727 if (!mediaDevice->init(mediaDevice))
733 snprintf(prompt, sizeof prompt, "Extracting %s into %s directory...", dist, root_bias(me[i].my_dir));
734 dialog_gauge("Progress", prompt, 8, 15, 6, 50, (int)((float)(chunk + 1) / numchunks * 100));
739 n = fread(buf, 1, BUFSIZ, fp);
740 if (check_for_interrupt()) {
741 msgConfirm("Media read error: User interrupt.");
749 /* Print statistics about how we're doing */
750 (void) gettimeofday(&stop, (struct timezone *)0);
751 stop.tv_sec = stop.tv_sec - start.tv_sec;
752 stop.tv_usec = stop.tv_usec - start.tv_usec;
753 if (stop.tv_usec < 0)
754 stop.tv_sec--, stop.tv_usec += 1000000;
755 seconds = stop.tv_sec + (stop.tv_usec / 1000000.0);
759 if (seconds != last_msg) {
761 msgInfo("%10d bytes read from %s dist, chunk %2d of %2d @ %.1f KB/sec.",
762 total, dist, chunk + 1, numchunks, (total / seconds) / 1024.0);
764 retval = write(fd2, buf, n);
767 dialog_clear_norefresh();
768 msgConfirm("Write failure on transfer! (wrote %d bytes of %d bytes)", retval, n);
775 status = mediaExtractDistEnd(zpid, cpid);
780 mediaExtractDistEnd(zpid, cpid);
786 msgConfirm("Unable to transfer all components of the %s distribution.\n"
787 "If this is a CDROM install, it may be because export restrictions prohibit\n"
788 "DES code from being shipped from the U.S. Try to get this code from a\n"
789 "local FTP site instead!", me[i].my_name);
792 status = msgYesNo("Unable to transfer the %s distribution from\n%s.\n\n"
793 "Do you want to try to retrieve it again?",
794 me[i].my_name, mediaDevice->name);
800 /* If extract was successful, remove ourselves from further consideration */
802 *(me[i].my_mask) &= ~(me[i].my_bit);
806 sigaction(SIGINT, &old, NULL); /* Restore signal handler */
812 printSelected(char *buf, int selected, Distribution *me, int *col)
816 /* Loop through to see if we're in our parent's plans */
817 for (i = 0; me[i].my_name; i++) {
819 /* If our bit isn't set, go to the next */
820 if (!(me[i].my_bit & selected))
823 /* This is shorthand for "dist currently disabled" */
827 *col += strlen(me[i].my_name);
832 sprintf(&buf[strlen(buf)], " %s", me[i].my_name);
833 /* Recurse if have a sub-distribution */
835 printSelected(buf, *(me[i].my_mask), me[i].my_dist, col);
840 distExtractAll(dialogMenuItem *self)
842 int old_dists, retries = 0, status = DITEM_SUCCESS;
847 if (!dmenuOpenSimple(&MenuSubDistributions, FALSE) || !Dists)
848 return DITEM_FAILURE | DITEM_RESTORE;
851 if (!mediaVerify() || !mediaDevice->init(mediaDevice))
852 return DITEM_FAILURE;
857 dialog_clear_norefresh();
858 msgNotify("Attempting to install all selected distributions..");
860 /* Try for 3 times around the loop, then give up. */
861 while (Dists && ++retries < 3)
862 distExtract(NULL, DistTable);
864 /* Only do bin fixup if bin dist was successfully extracted */
865 if ((old_dists & DIST_BIN) && !(Dists & DIST_BIN))
866 status |= installFixupBin(self);
867 if (old_dists & DIST_XF86)
868 status |= installFixupXFree(self);
874 printSelected(buf, Dists, DistTable, &col);
875 dialog_clear_norefresh();
876 msgConfirm("Couldn't extract the following distributions. This may\n"
877 "be because they were not available on the installation\n"
878 "media you've chosen:\n\n\t%s", buf);
879 status |= DITEM_RESTORE;