2 * The new sysinstall program.
4 * This is probably the last attempt in the `sysinstall' line, the next
5 * generation being slated to 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"
40 #include <sys/socket.h>
41 #include <sys/param.h>
42 #include <sys/mount.h>
43 #include <sys/errno.h>
44 #include <sys/fcntl.h>
49 #include <netinet/in.h>
50 #include <arpa/inet.h>
53 static Boolean got_intr = FALSE;
54 static Boolean ftp_skip_resolve = FALSE;
55 static Boolean http_skip_resolve = FALSE;
61 msgDebug("User generated interrupt.\n");
66 check_for_interrupt(void)
76 genericHook(dialogMenuItem *self, DeviceType type)
80 devs = deviceFind(self->prompt, type);
82 mediaDevice = devs[0];
83 return (devs ? DITEM_LEAVE_MENU : DITEM_FAILURE);
87 cdromHook(dialogMenuItem *self)
89 return genericHook(self, DEVICE_TYPE_CDROM);
95 static Boolean initted = FALSE;
99 cp = variable_get(VAR_MEDIA_TIMEOUT);
101 time = MEDIA_TIMEOUT;
108 _res.retry = 2; /* 2 times seems a reasonable number to me */
109 _res.retrans = time / 2; /* so spend half our alloted time on each try */
117 char *cp = variable_get(VAR_CPIO_VERBOSITY);
119 if (cp && !strcmp(cp, "high"))
127 if (!mediaDevice || !mediaVerify() || !DEVICE_INIT(mediaDevice))
128 return DITEM_FAILURE;
129 return DITEM_SUCCESS;
136 DEVICE_SHUTDOWN(mediaDevice);
141 * Return 1 if we successfully found and set the installation type to
145 mediaSetCDROM(dialogMenuItem *self)
151 devs = deviceFind(NULL, DEVICE_TYPE_CDROM);
152 cnt = deviceCount(devs);
154 if (self) /* Interactive? */
155 msgConfirm("No CD/DVD devices found! Please check that your system's\n"
156 "configuration is correct and that the CD/DVD drive is of a supported\n"
157 "type. For more information, consult the hardware guide\n"
159 return DITEM_FAILURE | DITEM_CONTINUE;
165 menu = deviceCreateMenu(&MenuMediaCDROM, DEVICE_TYPE_CDROM, cdromHook, NULL);
167 msgFatal("Unable to create CDROM menu! Something is seriously wrong.");
168 status = dmenuOpenSimple(menu, FALSE);
171 return DITEM_FAILURE;
174 mediaDevice = devs[0];
175 return (mediaDevice ? DITEM_SUCCESS | DITEM_LEAVE_MENU : DITEM_FAILURE);
179 floppyHook(dialogMenuItem *self)
181 return genericHook(self, DEVICE_TYPE_FLOPPY);
185 * Return 1 if we successfully found and set the installation type to
189 mediaSetFloppy(dialogMenuItem *self)
195 devs = deviceFind(NULL, DEVICE_TYPE_FLOPPY);
196 cnt = deviceCount(devs);
198 msgConfirm("No floppy devices found! Please check that your system's configuration\n"
199 "is correct. For more information, consult the hardware guide in the Doc\n"
201 return DITEM_FAILURE | DITEM_CONTINUE;
207 menu = deviceCreateMenu(&MenuMediaFloppy, DEVICE_TYPE_FLOPPY, floppyHook, NULL);
209 msgFatal("Unable to create Floppy menu! Something is seriously wrong.");
210 status = dmenuOpenSimple(menu, FALSE);
213 return DITEM_FAILURE;
216 mediaDevice = devs[0];
218 mediaDevice->private = NULL;
219 return (mediaDevice ? DITEM_LEAVE_MENU : DITEM_FAILURE);
223 USBHook(dialogMenuItem *self)
225 return genericHook(self, DEVICE_TYPE_USB);
230 * Attempt to use USB as the installation media type.
233 mediaSetUSB(dialogMenuItem *self)
239 devs = deviceFind(NULL, DEVICE_TYPE_USB);
240 cnt = deviceCount(devs);
243 msgConfirm("No USB devices found (try Options/Re-scan Devices)");
244 return DITEM_FAILURE | DITEM_CONTINUE;
250 menu = deviceCreateMenu(&MenuMediaUSB, DEVICE_TYPE_USB, USBHook,
253 msgFatal("Unable to create USB menu! Something is " \
255 status = dmenuOpenSimple(menu, FALSE);
258 return DITEM_FAILURE;
261 mediaDevice = devs[0];
263 mediaDevice->private = NULL;
264 if (!variable_get(VAR_NONINTERACTIVE))
265 msgConfirm("Using USB device: %s", mediaDevice->name);
266 return (mediaDevice ? DITEM_LEAVE_MENU : DITEM_FAILURE);
270 DOSHook(dialogMenuItem *self)
272 return genericHook(self, DEVICE_TYPE_DOS);
276 * Return 1 if we successfully found and set the installation type to
277 * be a DOS partition.
280 mediaSetDOS(dialogMenuItem *self)
286 devs = deviceFind(NULL, DEVICE_TYPE_DOS);
287 cnt = deviceCount(devs);
289 msgConfirm("No DOS primary partitions found! This installation method is unavailable");
290 return DITEM_FAILURE | DITEM_CONTINUE;
296 menu = deviceCreateMenu(&MenuMediaDOS, DEVICE_TYPE_DOS, DOSHook, NULL);
298 msgFatal("Unable to create DOS menu! Something is seriously wrong.");
299 status = dmenuOpenSimple(menu, FALSE);
302 return DITEM_FAILURE;
305 mediaDevice = devs[0];
306 return (mediaDevice ? DITEM_LEAVE_MENU : DITEM_FAILURE);
310 * Return 0 if we successfully found and set the installation type to
314 mediaSetFTP(dialogMenuItem *self)
316 static Device ftpDevice;
317 char *cp, hbuf[MAXHOSTNAMELEN], *hostname, *dir;
318 struct addrinfo hints, *res;
322 static Device *networkDev = NULL;
325 cp = variable_get(VAR_FTP_PATH);
326 /* If we've been through here before ... */
327 if (networkDev && cp && msgYesNo("Re-use old FTP site selection values?"))
330 if (!dmenuOpenSimple(&MenuMediaFTP, FALSE))
331 return DITEM_FAILURE;
333 cp = variable_get(VAR_FTP_PATH);
336 return DITEM_FAILURE;
337 else if (!strcmp(cp, "other")) {
338 variable_set2(VAR_FTP_PATH, "ftp://", 0);
339 cp = variable_get_value(VAR_FTP_PATH, "Please specify the URL of a FreeBSD distribution on a\n"
340 "remote ftp site. This site must accept either anonymous\n"
341 "ftp or you should have set an ftp username and password\n"
342 "in the Options screen.\n\n"
343 "A URL looks like this: ftp://<hostname>/<path>\n"
344 "Where <path> is relative to the anonymous ftp directory or the\n"
345 "home directory of the user being logged in as.", 0);
346 if (!cp || !*cp || !strcmp(cp, "ftp://")) {
347 variable_unset(VAR_FTP_PATH);
348 return DITEM_FAILURE;
351 if (urllen >= sizeof(ftpDevice.name)) {
352 msgConfirm("Length of specified URL is %zu characters. Allowable maximum is %zu.",
353 urllen,sizeof(ftpDevice.name)-1);
354 variable_unset(VAR_FTP_PATH);
355 return DITEM_FAILURE;
358 if (strncmp("ftp://", cp, 6)) {
359 msgConfirm("Sorry, %s is an invalid URL!", cp);
360 variable_unset(VAR_FTP_PATH);
361 return DITEM_FAILURE;
363 SAFE_STRCPY(ftpDevice.name, cp);
364 SAFE_STRCPY(hbuf, cp + 6);
367 if (!networkDev || msgYesNo("You've already done the network configuration once,\n"
368 "would you like to skip over it now?") != 0) {
370 DEVICE_SHUTDOWN(networkDev);
371 if (!(networkDev = tcpDeviceSelect())) {
372 variable_unset(VAR_FTP_PATH);
373 return DITEM_FAILURE;
376 if (!DEVICE_INIT(networkDev)) {
378 msgDebug("mediaSetFTP: Net device init failed.\n");
379 variable_unset(VAR_FTP_PATH);
380 return DITEM_FAILURE;
382 if (*hostname == '[' && (cp = index(hostname + 1, ']')) != NULL &&
383 (*++cp == '\0' || *cp == '/' || *cp == ':')) {
388 cp = index(hostname, ':');
389 if (cp != NULL && *cp == ':') {
391 FtpPort = strtol(cp, 0, 0);
395 if ((dir = index(cp ? cp : hostname, '/')) != NULL)
398 msgDebug("hostname = `%s'\n", hostname);
399 msgDebug("dir = `%s'\n", dir ? dir : "/");
400 msgDebug("port # = `%d'\n", FtpPort);
402 if (!ftp_skip_resolve && variable_get(VAR_NAMESERVER)) {
403 msgNotify("Looking up host %s.", hostname);
405 msgDebug("Starting DNS.\n");
408 msgDebug("Looking up hostname, %s, using getaddrinfo(AI_NUMERICHOST).\n", hostname);
409 af = variable_cmp(VAR_IPV6_ENABLE, "YES") ? AF_INET : AF_UNSPEC;
410 memset(&hints, 0, sizeof(hints));
411 hints.ai_family = af;
412 hints.ai_socktype = SOCK_STREAM;
413 hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
414 if (getaddrinfo(hostname, NULL, &hints, &res) != 0) {
416 msgDebug("Looking up hostname, %s, using getaddrinfo().\n",
418 hints.ai_flags = AI_PASSIVE;
419 if (getaddrinfo(hostname, NULL, &hints, &res) != 0) {
420 msgConfirm("Cannot resolve hostname `%s'! Are you sure that"
421 " your\nname server, gateway and network interface are"
422 " correctly configured?", hostname);
424 DEVICE_SHUTDOWN(networkDev);
426 variable_unset(VAR_FTP_PATH);
427 return DITEM_FAILURE;
432 msgDebug("Found DNS entry for %s successfully..\n", hostname);
434 variable_set2(VAR_FTP_HOST, hostname, 0);
435 variable_set2(VAR_FTP_DIR, dir ? dir : "/", 0);
436 variable_set2(VAR_FTP_PORT, itoa(FtpPort), 0);
437 ftpDevice.type = DEVICE_TYPE_FTP;
438 ftpDevice.init = mediaInitFTP;
439 ftpDevice.get = mediaGetFTP;
440 ftpDevice.shutdown = mediaShutdownFTP;
441 ftpDevice.private = networkDev;
442 mediaDevice = &ftpDevice;
443 return DITEM_SUCCESS | DITEM_LEAVE_MENU | DITEM_RESTORE;
447 mediaSetFTPActive(dialogMenuItem *self)
449 variable_set2(VAR_FTP_STATE, "active", 0);
450 return mediaSetFTP(self);
454 mediaSetFTPPassive(dialogMenuItem *self)
456 variable_set2(VAR_FTP_STATE, "passive", 0);
457 return mediaSetFTP(self);
460 int mediaSetHTTP(dialogMenuItem *self)
464 char *cp, *idx, hbuf[MAXHOSTNAMELEN], *hostname;
466 int what = DITEM_RESTORE;
469 tmp = ftp_skip_resolve;
470 ftp_skip_resolve = TRUE;
471 result = mediaSetFTP(self);
472 ftp_skip_resolve = tmp;
474 if (DITEM_STATUS(result) != DITEM_SUCCESS)
477 cp = variable_get_value(VAR_HTTP_PROXY,
478 "Please enter the address of the HTTP proxy in this format:\n"
479 " hostname:port (the ':port' is optional, default is 3128)",0);
481 return DITEM_FAILURE;
482 SAFE_STRCPY(hbuf, cp);
484 if (*hostname == '[' && (idx = index(hostname + 1, ']')) != NULL &&
485 (*++idx == '\0' || *idx == ':')) {
489 idx = index(hostname, ':');
490 if (idx == NULL || *idx != ':')
491 HttpPort = 3128; /* try this as default */
494 HttpPort = strtol(idx, 0, 0);
497 variable_set2(VAR_HTTP_HOST, hostname, 0);
498 variable_set2(VAR_HTTP_PORT, itoa(HttpPort), 0);
500 msgDebug("VAR_FTP_PATH : %s\n",variable_get(VAR_FTP_PATH));
501 msgDebug("VAR_HTTP_HOST, _PORT: %s:%s\n",variable_get(VAR_HTTP_HOST),
502 variable_get(VAR_HTTP_PORT));
505 /* mediaDevice has been set by mediaSetFTP(), overwrite partly: */
506 mediaDevice->type = DEVICE_TYPE_HTTP;
507 mediaDevice->init = mediaInitHTTP;
508 mediaDevice->get = mediaGetHTTP;
509 mediaDevice->shutdown = dummyShutdown;
510 return DITEM_SUCCESS | DITEM_LEAVE_MENU | what;
514 * Return 0 if we successfully found and set the installation type to
518 mediaSetHTTPDirect(dialogMenuItem *self)
520 static Device httpDevice;
521 char *cp, hbuf[MAXPATHLEN], *hostname, *dir;
522 struct addrinfo hints, *res;
526 static Device *networkDev = NULL;
529 cp = variable_get(VAR_HTTP_PATH);
530 /* If we've been through here before ... */
531 if (networkDev && cp && msgYesNo("Re-use old HTTP site selection values?"))
534 if (!dmenuOpenSimple(&MenuMediaHTTPDirect, FALSE))
535 return DITEM_FAILURE;
537 cp = variable_get(VAR_HTTP_PATH);
540 return DITEM_FAILURE;
541 else if (!strcmp(cp, "other")) {
542 variable_set2(VAR_HTTP_PATH, "http://", 0);
543 cp = variable_get_value(VAR_HTTP_PATH, "Please specify the URL of a FreeBSD distribution on a\n"
544 "remote http site.\n"
545 "A URL looks like this: http://<hostname>/<path>", 0);
546 if (!cp || !*cp || !strcmp(cp, "http://")) {
547 variable_unset(VAR_HTTP_PATH);
548 return DITEM_FAILURE;
551 if (urllen >= sizeof(httpDevice.name)) {
552 msgConfirm("Length of specified URL is %zu characters. Allowable maximum is %zu.",
553 urllen,sizeof(httpDevice.name)-1);
554 variable_unset(VAR_HTTP_PATH);
555 return DITEM_FAILURE;
558 if (strncmp("http://", cp, 7)) {
559 msgConfirm("Sorry, %s is an invalid URL!", cp);
560 variable_unset(VAR_HTTP_PATH);
561 return DITEM_FAILURE;
563 SAFE_STRCPY(httpDevice.name, cp);
564 SAFE_STRCPY(hbuf, cp + 7);
567 if (!networkDev || msgYesNo("You've already done the network configuration once,\n"
568 "would you like to skip over it now?") != 0) {
570 DEVICE_SHUTDOWN(networkDev);
571 if (!(networkDev = tcpDeviceSelect())) {
572 variable_unset(VAR_HTTP_PATH);
573 return DITEM_FAILURE;
576 if (!DEVICE_INIT(networkDev)) {
578 msgDebug("mediaSetHTTPDirect: Net device init failed.\n");
579 variable_unset(VAR_HTTP_PATH);
580 return DITEM_FAILURE;
582 if (*hostname == '[' && (cp = index(hostname + 1, ']')) != NULL &&
583 (*++cp == '\0' || *cp == '/' || *cp == ':')) {
588 cp = index(hostname, ':');
589 if (cp != NULL && *cp == ':') {
591 HttpPort = strtol(cp, 0, 0);
595 if ((dir = index(cp ? cp : hostname, '/')) != NULL)
598 msgDebug("hostname = `%s'\n", hostname);
599 msgDebug("dir = `%s'\n", dir ? dir : "/");
600 msgDebug("port # = `%d'\n", HttpPort);
602 if (!http_skip_resolve && variable_get(VAR_NAMESERVER)) {
603 msgNotify("Looking up host %s.", hostname);
605 msgDebug("Starting DNS.\n");
608 msgDebug("Looking up hostname, %s, using getaddrinfo(AI_NUMERICHOST).\n", hostname);
609 af = variable_cmp(VAR_IPV6_ENABLE, "YES") ? AF_INET : AF_UNSPEC;
610 memset(&hints, 0, sizeof(hints));
611 hints.ai_family = af;
612 hints.ai_socktype = SOCK_STREAM;
613 hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
614 if (getaddrinfo(hostname, NULL, &hints, &res) != 0) {
616 msgDebug("Looking up hostname, %s, using getaddrinfo().\n",
618 hints.ai_flags = AI_PASSIVE;
619 if (getaddrinfo(hostname, NULL, &hints, &res) != 0) {
620 msgConfirm("Cannot resolve hostname `%s'! Are you sure that"
621 " your\nname server, gateway and network interface are"
622 " correctly configured?", hostname);
624 DEVICE_SHUTDOWN(networkDev);
626 variable_unset(VAR_HTTP_PATH);
627 return DITEM_FAILURE;
632 msgDebug("Found DNS entry for %s successfully..\n", hostname);
634 variable_set2(VAR_HTTP_HOST, hostname, 0);
635 variable_set2(VAR_HTTP_DIR, dir ? dir : "/", 0);
636 variable_set2(VAR_HTTP_PORT, itoa(HttpPort), 0);
637 httpDevice.type = DEVICE_TYPE_HTTP_DIRECT;
638 httpDevice.init = mediaInitHTTPDirect;
639 httpDevice.get = mediaGetHTTPDirect;
640 httpDevice.shutdown = dummyShutdown;
641 httpDevice.private = networkDev;
642 mediaDevice = &httpDevice;
643 return DITEM_SUCCESS | DITEM_LEAVE_MENU | DITEM_RESTORE;
648 mediaSetUFS(dialogMenuItem *self)
650 static Device ufsDevice;
655 cp = variable_get_value(VAR_UFS_PATH, "Enter a fully qualified pathname for the directory\n"
656 "containing the FreeBSD distribution files:", 0);
658 return DITEM_FAILURE;
660 /* If they gave us a CDROM or something, try and pick a better name */
662 strcpy(ufsDevice.name, "ufs");
664 strcpy(ufsDevice.name, st.f_fstypename);
666 ufsDevice.type = DEVICE_TYPE_UFS;
667 ufsDevice.init = dummyInit;
668 ufsDevice.get = mediaGetUFS;
669 ufsDevice.shutdown = dummyShutdown;
670 ufsDevice.private = strdup(cp);
671 mediaDevice = &ufsDevice;
672 return DITEM_LEAVE_MENU;
676 mediaSetNFS(dialogMenuItem *self)
678 static Device nfsDevice;
679 static Device *networkDev = NULL;
681 char hostname[MAXPATHLEN];
685 cp = variable_get_value(VAR_NFS_PATH, "Please enter the full NFS file specification for the remote\n"
686 "host and directory containing the FreeBSD distribution files.\n"
687 "This should be in the format: hostname:/some/freebsd/dir", 0);
689 return DITEM_FAILURE;
690 SAFE_STRCPY(hostname, cp);
691 if (!(idx = index(hostname, ':'))) {
692 msgConfirm("Invalid NFS path specification. Must be of the form:\n"
693 "host:/full/pathname/to/FreeBSD/distdir");
694 return DITEM_FAILURE;
696 pathlen = strlen(hostname);
697 if (pathlen >= sizeof(nfsDevice.name)) {
698 msgConfirm("Length of specified NFS path is %zu characters. Allowable maximum is %zu.",
699 pathlen,sizeof(nfsDevice.name)-1);
700 variable_unset(VAR_NFS_PATH);
701 return DITEM_FAILURE;
703 SAFE_STRCPY(nfsDevice.name, hostname);
705 if (!networkDev || msgYesNo("You've already done the network configuration once,\n"
706 "would you like to skip over it now?") != 0) {
708 DEVICE_SHUTDOWN(networkDev);
709 if (!(networkDev = tcpDeviceSelect()))
710 return DITEM_FAILURE;
712 if (!DEVICE_INIT(networkDev)) {
714 msgDebug("mediaSetNFS: Net device init failed\n");
716 if (variable_get(VAR_NAMESERVER)) {
718 if ((inet_addr(hostname) == INADDR_NONE) && (gethostbyname(hostname) == NULL)) {
719 msgConfirm("Cannot resolve hostname `%s'! Are you sure that your\n"
720 "name server, gateway and network interface are correctly configured?", hostname);
722 DEVICE_SHUTDOWN(networkDev);
724 variable_unset(VAR_NFS_PATH);
725 return DITEM_FAILURE;
729 msgDebug("Found DNS entry for %s successfully..\n", hostname);
732 variable_set2(VAR_NFS_HOST, hostname, 0);
733 nfsDevice.type = DEVICE_TYPE_NFS;
734 nfsDevice.init = mediaInitNFS;
735 nfsDevice.get = mediaGetNFS;
736 nfsDevice.shutdown = mediaShutdownNFS;
737 nfsDevice.private = networkDev;
738 mediaDevice = &nfsDevice;
739 return DITEM_LEAVE_MENU;
743 mediaExtractDistBegin(char *dir, int *fd, int *zpid, int *cpid)
745 int i, pfd[2],qfd[2];
755 char *unzipper = RunningAsInit ? "/stand/" UNZIPPER
756 : "/usr/bin/" UNZIPPER;
758 dup2(qfd[0], 0); close(qfd[0]);
759 dup2(pfd[1], 1); close(pfd[1]);
764 open("/dev/null", O_WRONLY);
768 i = execl(unzipper, unzipper, (char *)0);
770 msgDebug("%s command returns %d status\n", unzipper, i);
777 char *cpio = RunningAsInit ? "/stand/cpio" : "/usr/bin/cpio";
779 dup2(pfd[0], 0); close(pfd[0]);
787 close(1); open("/dev/null", O_WRONLY);
790 if (strlen(cpioVerbosity()))
791 i = execl(cpio, cpio, "-idum", cpioVerbosity(), (char *)0);
793 i = execl(cpio, cpio, "-idum", (char *)0);
795 msgDebug("%s command returns %d status\n", cpio, i);
804 mediaExtractDistEnd(int zpid, int cpid)
808 i = waitpid(zpid, &j, 0);
809 /* Don't check exit status - gunzip seems to return a bogus one! */
812 msgDebug("wait for %s returned status of %d!\n", UNZIPPER, i);
815 i = waitpid(cpid, &j, 0);
816 if (i < 0 || WEXITSTATUS(j)) {
818 msgDebug("cpio returned error status of %d!\n", WEXITSTATUS(j));
825 mediaExtractDist(char *dir, char *dist, FILE *fp)
827 int i, j, total, seconds, zpid, cpid, pfd[2], qfd[2];
829 struct timeval start, stop;
830 struct sigaction new, old;
837 pipe(pfd); /* read end */
838 pipe(qfd); /* write end */
841 char *unzipper = RunningAsInit ? "/stand/" UNZIPPER
842 : "/usr/bin/" UNZIPPER;
846 dup2(qfd[0], 0); close(qfd[0]);
849 dup2(pfd[1], 1); close(pfd[1]);
855 open("/dev/null", O_WRONLY);
857 i = execl(unzipper, unzipper, (char *)0);
859 msgDebug("%s command returns %d status\n", unzipper, i);
864 char *cpio = RunningAsInit ? "/stand/cpio" : "/usr/bin/cpio";
867 dup2(pfd[0], 0); close(pfd[0]);
868 close (qfd[0]); close(qfd[1]);
875 dup2(open("/dev/null", O_WRONLY), 1);
878 if (strlen(cpioVerbosity()))
879 i = execl(cpio, cpio, "-idum", cpioVerbosity(), (char *)0);
881 i = execl(cpio, cpio, "-idum", "--block-size", (char *)0);
883 msgDebug("%s command returns %d status\n", cpio, i);
886 close(pfd[0]); close(pfd[1]);
890 (void)gettimeofday(&start, (struct timezone *)0);
892 /* Make ^C abort the current transfer rather than the whole show */
893 new.sa_handler = handle_intr;
895 (void)sigemptyset(&new.sa_mask);
896 sigaction(SIGINT, &new, &old);
898 while ((i = fread(buf, 1, BUFSIZ, fp)) > 0) {
899 if (check_for_interrupt()) {
900 msgConfirm("Failure to read from media: User interrupt.");
903 if (write(qfd[1], buf, i) != i) {
904 msgConfirm("Write error on transfer to cpio process, try of %d bytes.", i);
908 (void)gettimeofday(&stop, (struct timezone *)0);
909 stop.tv_sec = stop.tv_sec - start.tv_sec;
910 stop.tv_usec = stop.tv_usec - start.tv_usec;
911 if (stop.tv_usec < 0)
912 stop.tv_sec--, stop.tv_usec += 1000000;
913 seconds = stop.tv_sec + (stop.tv_usec / 1000000.0);
917 msgInfo("%10d bytes read from %s dist @ %.1f KB/sec.",
918 total, dist, (total / seconds) / 1024.0);
921 sigaction(SIGINT, &old, NULL); /* restore sigint */
924 i = waitpid(zpid, &j, 0);
925 /* Don't check exit status - gunzip seems to return a bogus one! */
928 msgDebug("wait for %s returned status of %d!\n", UNZIPPER, i);
931 i = waitpid(cpid, &j, 0);
932 if (i < 0 || WEXITSTATUS(j)) {
934 msgDebug("cpio returned error status of %d!\n", WEXITSTATUS(j));
941 mediaGetType(dialogMenuItem *self)
943 return ((dmenuOpenSimple(&MenuMedia, FALSE) && mediaDevice) ? DITEM_SUCCESS : DITEM_FAILURE);
946 /* Return TRUE if all the media variables are set up correctly */
951 return (DITEM_STATUS(mediaGetType(NULL)) == DITEM_SUCCESS);
955 /* Set the FTP username and password fields */
957 mediaSetFTPUserPass(dialogMenuItem *self)
961 if (variable_get_value(VAR_FTP_USER, "Please enter the username you wish to login as:", 0)) {
962 DialogInputAttrs |= DITEM_NO_ECHO;
963 pass = variable_get_value(VAR_FTP_PASS, "Please enter the password for this user:", 0);
964 DialogInputAttrs &= ~DITEM_NO_ECHO;
968 return (pass ? DITEM_SUCCESS : DITEM_FAILURE);
971 /* Set CPIO verbosity level */
973 mediaSetCPIOVerbosity(dialogMenuItem *self)
975 char *cp = variable_get(VAR_CPIO_VERBOSITY);
978 msgConfirm("CPIO Verbosity is not set to anything!");
979 return DITEM_FAILURE;
982 if (!strcmp(cp, "low"))
983 variable_set2(VAR_CPIO_VERBOSITY, "high", 0);
984 else /* must be "high" - wrap around */
985 variable_set2(VAR_CPIO_VERBOSITY, "low", 0);
987 return DITEM_SUCCESS;
990 /* A generic open which follows a well-known "path" of places to look */
992 mediaGenericGet(char *base, const char *file)
996 snprintf(buf, PATH_MAX, "%s/%s", base, file);
997 if (file_readable(buf))
998 return fopen(buf, "r");
999 snprintf(buf, PATH_MAX, "%s/FreeBSD/%s", base, file);
1000 if (file_readable(buf))
1001 return fopen(buf, "r");
1002 snprintf(buf, PATH_MAX, "%s/releases/%s", base, file);
1003 if (file_readable(buf))
1004 return fopen(buf, "r");
1005 snprintf(buf, PATH_MAX, "%s/%s/%s", base, variable_get(VAR_RELNAME), file);
1006 if (file_readable(buf))
1007 return fopen(buf, "r");
1008 snprintf(buf, PATH_MAX, "%s/releases/%s/%s", base, variable_get(VAR_RELNAME), file);
1009 return fopen(buf, "r");