diff --git a/release/sysinstall/doc.c b/release/sysinstall/doc.c index 8b2c20d097ca..49fe7983c3e7 100644 --- a/release/sysinstall/doc.c +++ b/release/sysinstall/doc.c @@ -1,88 +1,88 @@ /* * The new sysinstall program. * * This is probably the last program in the `sysinstall' line - the next * generation being essentially a complete rewrite. * - * $Id: doc.c,v 1.1 1995/10/20 07:03:40 jkh Exp $ + * $Id: doc.c,v 1.2 1995/10/20 14:24:41 jkh Exp $ * * Jordan Hubbard * * My contributions are in the public domain. * * Parts of this file are also blatently stolen from Poul-Henning Kamp's * previous version of sysinstall, and as such fall under his "BEERWARE license" * so buy him a beer if you like it! Buy him a beer for me, too! * Heck, get him completely drunk and send me pictures! :-) */ #include "sysinstall.h" /* * This is called from the main menu. Try to find a copy of Lynx from somewhere * and fire it up on the first copy of the handbook we can find. */ int docBrowser(char *junk) { - char *browser = variable_get(BROWSER_PACKAGE); + char *browser = variable_get(VAR_BROWSER_PACKAGE); /* Make sure we were started at a reasonable time */ if (!strcmp(variable_get(SYSTEM_STATE), "init")) { msgConfirm("Sorry, it's not possible to invoke the browser until the system\n" "is installed completely enough to support a copy of %s.", browser); return RET_FAIL; } if (!mediaVerify()) return RET_FAIL; /* First, make sure we have whatever browser we've chosen is here */ if (package_extract(mediaDevice, browser) != RET_SUCCESS) { msgConfirm("Unable to install the %s HTML browser package. You may\n" "wish to verify that your media is configured correctly and\n" "try again.", browser); return RET_FAIL; } - if (!file_executable(variable_get(BROWSER_BINARY))) { + if (!file_executable(variable_get(VAR_BROWSER_BINARY))) { if (!msgYesNo("Hmmm. The %s package claims to have installed, but I can't\n" "find its binary in %s! You may wish to try a different\n" "location to load the package from (go to Media menu) and see if that\n" "makes a difference.\n\n" "I suggest that we remove the version that was extracted since it does\n" "not appear to be correct. Would you like me to do that now?")) - vsystem("pkg_delete %s %s", !strcmp(variable_get(CPIO_VERBOSITY_LEVEL), "high") ? "-v" : "", browser); + vsystem("pkg_delete %s %s", !strcmp(variable_get(VAR_CPIO_VERBOSITY), "high") ? "-v" : "", browser); return RET_FAIL; } /* Run browser on the appropriate doc */ dmenuOpenSimple(&MenuHTMLDoc); return RET_SUCCESS; } /* Try to show one of the documents requested from the HTML doc menu */ int docShowDocument(char *str) { - char *browser = variable_get(BROWSER_BINARY); + char *browser = variable_get(VAR_BROWSER_BINARY); if (!file_executable(browser)) { msgConfirm("Can't find the browser in %s! Please ensure that it's\n" "properly set in the Options editor.", browser); return RET_FAIL; } if (!strcmp(str, "Home")) vsystem("%s http://www.freebsd.org", browser); else if (!strcmp(str, "Other")) { } else { char target[512]; sprintf(target, "/usr/share/doc/%s/%s.html", str, str); if (file_readable(target)) vsystem("%s file:%s", browser, target); else vsystem("%s http://www.freebsd.org/%s"); } return RET_SUCCESS; } diff --git a/release/sysinstall/index.c b/release/sysinstall/index.c index 8cf6fa0e66d9..8b9dcfc4fd78 100644 --- a/release/sysinstall/index.c +++ b/release/sysinstall/index.c @@ -1,569 +1,569 @@ /* * The new sysinstall program. * * This is probably the last program in the `sysinstall' line - the next * generation being essentially a complete rewrite. * - * $Id: index.c,v 1.13 1995/10/20 21:57:08 jkh Exp $ + * $Id: index.c,v 1.14 1995/10/21 14:06:44 jkh Exp $ * * Copyright (c) 1995 * Jordan Hubbard. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * verbatim and that no modifications are made prior to this * point in the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Jordan Hubbard * for the FreeBSD Project. * 4. The name of Jordan Hubbard or the FreeBSD project may not be used to * endorse or promote products derived from this software without specific * prior written permission. * * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include #include #include #include #include #include #include "sysinstall.h" /* Macros and magic values */ #define MAX_MENU 13 #define _MAX_DESC 62 /* Smarter strdup */ inline char * _strdup(char *ptr) { return ptr ? strdup(ptr) : NULL; } static char *descrs[] = { "Package Selection", "To mark a package or select a category, move to it and press SPACE.\n" "To unmark a package, press SPACE again. When you want to commit your\n" "marks, press [ENTER]. To go to a previous menu, select UP item or Cancel.\n" "To search for a package by name, press ESC.", "Package Targets", "These are the packages you've selected for extraction.\n\n" "If you're sure of these choices, select OK.\n" "If not, select Cancel to go back to the package selection menu.\n", "All", "All available packages in all categories.", "applications", "User application software.", "archivers", "Utilities for archiving and unarchiving data.", "audio", "Audio utilities - most require a supported sound card.", "benchmarks", "Utilities for measuring system performance.", "benchmarking", "Utilities for measuring system performance.", "cad", "Computer Aided Design utilities.", "comms", "Communications utilities.", "databases", "Database software.", "devel", "Software development utilities and libraries.", "development", "Software development utilities and libraries.", "documentation", "Document preparation utilities.", "editors", "Common text editors.", "emulation", "Utilities for emulating other OS types.", "emulators", "Utilities for emulating other OS types.", "games", "Various and sundry amusements.", "graphics", "Graphics libraries and utilities.", "japanese", "Ported software for the Japanese market.", "lang", "Computer languages.", "languages", "Computer languages.", "libraries", "Software development libraries.", "mail", "Electronic mail packages and utilities.", "math", "Mathematical computation software.", "net", "Networking utilities.", "networking", "Networking utilities.", "news", "USENET News support software.", "numeric", "Mathematical computation software.", "orphans", "Packages without a home elsewhere.", "plan9", "Software from the plan9 Operating System.", "print", "Utilities for dealing with printing.", "printing", "Utilities for dealing with printing.", "programming", "Software development utilities and libraries.", "russian", "Ported software for the Russian market.", "security", "System security software.", "shells", "Various shells (tcsh, bash, etc).", "sysutils", "Various system utilities.", "troff", "TROFF Text formatting utilities.", "utils", "Various user utilities.", "utilities", "Various user utilities.", "x11", "X Window System based utilities.", NULL, NULL, }; static char * fetch_desc(char *name) { int i; for (i = 0; descrs[i]; i += 2) { if (!strcmp(descrs[i], name)) return descrs[i + 1]; } return "No description provided"; } static PkgNodePtr new_pkg_node(char *name, node_type type) { PkgNodePtr tmp = safe_malloc(sizeof(PkgNode)); tmp->name = _strdup(name); tmp->type = type; return tmp; } static IndexEntryPtr new_index(char *name, char *pathto, char *prefix, char *comment, char *descr, char *maint) { IndexEntryPtr tmp = safe_malloc(sizeof(IndexEntry)); tmp->name = _strdup(name); tmp->path = _strdup(pathto); tmp->prefix = _strdup(prefix); tmp->comment = _strdup(comment); tmp->descrfile = _strdup(descr); tmp->maintainer = _strdup(maint); return tmp; } static void index_register(PkgNodePtr top, char *where, IndexEntryPtr ptr) { PkgNodePtr p, q; for (q = NULL, p = top->kids; p; p = p->next) { if (!strcmp(p->name, where)) { q = p; break; } } if (!p) { /* Add new category */ q = new_pkg_node(where, PLACE); q->desc = fetch_desc(where); q->next = top->kids; top->kids = q; } p = new_pkg_node(ptr->name, PACKAGE); p->desc = ptr->comment; p->data = ptr; p->next = q->kids; q->kids = p; } static int copy_to_sep(char *to, char *from, int sep) { char *tok; tok = strchr(from, sep); if (!tok) { fprintf(stderr, "missing '%c' token.\n", sep); *to = '\0'; return 0; } *tok = '\0'; strcpy(to, from); return tok + 1 - from; } static int readline(int fd, char *buf, int max) { int rv, i = 0; char ch; while ((rv = read(fd, &ch, 1)) == 1 && ch != '\n' && i < max) buf[i++] = ch; if (i < max) buf[i] = '\0'; return rv; } int index_parse(int fd, char *name, char *pathto, char *prefix, char *comment, char *descr, char *maint, char *cats, char *keys) { char line[1024]; char *cp; int i; i = readline(fd, line, 1024); if (i <= 0) return EOF; cp = line; cp += copy_to_sep(name, cp, '|'); cp += copy_to_sep(pathto, cp, '|'); cp += copy_to_sep(prefix, cp, '|'); cp += copy_to_sep(comment, cp, '|'); cp += copy_to_sep(descr, cp, '|'); cp += copy_to_sep(maint, cp, '|'); cp += copy_to_sep(cats, cp, '|'); strcpy(keys, cp); return 0; } int index_get(char *fname, PkgNodePtr papa) { int i, fd; fd = open(fname, O_RDONLY); if (fd < 0) { fprintf(stderr, "Unable to open index file `%s' for reading.\n", fname); i = -1; } else i = index_read(fd, papa); close(fd); return i; } int index_read(int fd, PkgNodePtr papa) { char name[127], pathto[255], prefix[255], comment[255], descr[127], maint[127], cats[511], keys[511]; while (index_parse(fd, name, pathto, prefix, comment, descr, maint, cats, keys) != EOF) { char *cp, *cp2, tmp[511]; IndexEntryPtr idx; idx = new_index(name, pathto, prefix, comment, descr, maint); /* For now, we only add things to menus if they're in categories. Keywords are ignored */ for (cp = strcpy(tmp, cats); (cp2 = strchr(cp, ' ')) != NULL; cp = cp2 + 1) { *cp2 = '\0'; index_register(papa, cp, idx); } index_register(papa, cp, idx); /* Add to special "All" category */ index_register(papa, "All", idx); } return 0; } void index_init(PkgNodePtr top, PkgNodePtr plist) { top->next = top->kids = NULL; top->name = "Package Selection"; top->type = PLACE; top->desc = fetch_desc(top->name); plist->next = plist->kids = NULL; plist->name = "Package Targets"; plist->type = PLACE; plist->desc = fetch_desc(plist->name); } void index_entry_free(IndexEntryPtr top) { safe_free(top->name); safe_free(top->path); safe_free(top->prefix); safe_free(top->comment); safe_free(top->descrfile); safe_free(top->maintainer); free(top); } void index_node_free(PkgNodePtr top, PkgNodePtr plist) { PkgNodePtr tmp; tmp = plist; while (tmp) { PkgNodePtr tmp2 = tmp->next; safe_free(tmp); tmp = tmp2; } for (tmp = top; tmp; tmp = tmp->next) { free(tmp->name); if (tmp->type == PACKAGE && tmp->data) index_entry_free((IndexEntryPtr)tmp->data); if (tmp->kids) index_node_free(tmp->kids, NULL); } } void index_print(PkgNodePtr top, int level) { int i; while (top) { for (i = 0; i < level; i++) putchar('\t'); printf("name [%s]: %s\n", top->type == PLACE ? "place" : "package", top->name); for (i = 0; i < level; i++) putchar('\t'); printf("desc: %s\n", top->desc); if (top->kids) index_print(top->kids, level + 1); top = top->next; } } /* Swap one node for another */ static void swap_nodes(PkgNodePtr a, PkgNodePtr b) { PkgNode tmp; tmp = *a; *a = *b; a->next = tmp.next; tmp.next = b->next; *b = tmp; } /* Use a disgustingly simplistic bubble sort to put our lists in order */ void index_sort(PkgNodePtr top) { PkgNodePtr p, q; /* Sort everything at the top level */ for (p = top->kids; p; p = p->next) { for (q = top->kids; q; q = q->next) { if (q->next && strcmp(q->name, q->next->name) > 0) swap_nodes(q, q->next); } } /* Now sub-sort everything n levels down */ for (p = top->kids; p; p = p->next) { if (p->kids) index_sort(p); } } /* * No, we don't free n because someone else is still pointing at it. * It's just clone linked from another location, which we're adjusting. */ void index_delete(PkgNodePtr n) { if (n->next) *n = *(n->next); else /* Kludgy end sentinal */ n->name = NULL; } PkgNodePtr index_search(PkgNodePtr top, char *str, PkgNodePtr *tp) { PkgNodePtr p, sp; for (p = top->kids; p && p->name; p = p->next) { /* Subtract out the All category from searches */ if (!strcmp(p->name, "All")) continue; /* If tp == NULL, we're looking for an exact package match */ if (!tp && !strcmp(p->name, str)) return p; /* If tp, we're looking for both a package and a pointer to the place it's in */ if (tp && strstr(p->name, str)) { *tp = top; return p; } /* The usual recursion-out-of-laziness ploy */ if (p->kids) if ((sp = index_search(p, str, tp)) != NULL) return sp; } if (p && !p->name) p = NULL; return p; } /* Work function for seeing if name x is in result string y */ static Boolean is_selected_in(char *name, char *result) { Boolean ret = FALSE; while (*result) { char *cp; cp = index(result, '\n'); if (!cp) { ret = !strcmp(name, result); break; } else { ret = !strncmp(name, result, cp - result - 1); if (ret) break; } result = cp + 1; } return ret; } int index_menu(PkgNodePtr top, PkgNodePtr plist, int *pos, int *scroll) { int n, rval, maxname; int curr, max; PkgNodePtr sp, kp; char **nitems; char result[127]; Boolean hasPackages; curr = max = 0; hasPackages = FALSE; nitems = NULL; n = maxname = 0; /* Figure out if this menu is full of "leaves" or "branches" */ for (kp = top->kids; kp && kp->name; kp = kp->next) { int len; ++n; if (kp->type == PACKAGE && plist) { hasPackages = TRUE; if ((len = strlen(kp->name)) > maxname) maxname = len; } } if (!n && plist) { msgConfirm("The %s menu is empty.", top->name); return RET_DONE; } dialog_clear(); while (1) { n = 0; kp = top->kids; if (!hasPackages && kp && kp->name && plist) { nitems = item_add_pair(nitems, "UP", "", &curr, &max); ++n; } while (kp && kp->name) { /* Brutally adjust description to fit in menu */ if (strlen(kp->desc) > (_MAX_DESC - maxname)) kp->desc[_MAX_DESC - maxname] = '\0'; nitems = item_add_pair(nitems, kp->name, kp->desc, &curr, &max); if (hasPackages) { if (kp->type == PACKAGE && plist) nitems = item_add(nitems, index_search(plist, kp->name, NULL) ? "ON" : "OFF", &curr, &max); else nitems = item_add(nitems, "OFF", &curr, &max); } ++n; kp = kp->next; } nitems = item_add(nitems, NULL, &curr, &max); if (hasPackages) rval = dialog_checklist(top->name, top->desc, -1, -1, n > MAX_MENU ? MAX_MENU : n, n, (unsigned char **)nitems, result); else /* It's a categories menu */ rval = dialog_menu(top->name, top->desc, -1, -1, n > MAX_MENU ? MAX_MENU : n, n, (unsigned char **)nitems, result, pos, scroll); items_free(nitems, &curr, &max); if (!rval && plist && strcmp(result, "UP")) { for (kp = top->kids; kp; kp = kp->next) { if (kp->type == PACKAGE) { sp = index_search(plist, kp->name, NULL); if (is_selected_in(kp->name, result)) { if (!sp) { PkgNodePtr n = (PkgNodePtr)safe_malloc(sizeof(PkgNode)); *n = *kp; n->next = plist->kids; plist->kids = n; standout(); mvprintw(23, 0, "Selected packages were added to selection list\n", kp->name); standend(); refresh(); } } else if (sp) { standout(); mvprintw(23, 0, "Deleting unselected packages from selection list\n", kp->name); standend(); refresh(); index_delete(sp); } } else if (!strcmp(kp->name, result)) { /* Not a package, must be a directory */ int p, s; p = s = 0; index_menu(kp, plist, &p, &s); } } } else if (rval == -1 && plist) { static char *cp; PkgNodePtr menu; /* Search */ if ((cp = msgGetInput(cp, "Search by package name. Please enter search string:")) != NULL) { PkgNodePtr p = index_search(top, cp, &menu); if (p) { int pos, scroll; /* These need to be set to point at the found item, actually. Hmmm! */ pos = scroll = 0; index_menu(menu, plist, &pos, &scroll); } else msgConfirm("Search string: %s yielded no hits.", cp); } } else { dialog_clear(); return rval ? RET_FAIL : RET_SUCCESS; } } } int index_extract(Device *dev, PkgNodePtr plist) { PkgNodePtr tmp; int status = RET_SUCCESS; for (tmp = plist->kids; tmp; tmp = tmp->next) { if (package_extract(dev, tmp->name) != RET_SUCCESS) { - if (variable_get(OPT_NO_CONFIRM)) + if (variable_get(VAR_NO_CONFIRM)) msgNotify("Unable to locate package %s..", tmp->name); else msgConfirm("Unable to locate package %s..", tmp->name); status = RET_FAIL; } } return status; } diff --git a/release/sysinstall/installPreconfig.c b/release/sysinstall/installPreconfig.c index 53a3e95ae15e..7a261cdf57e2 100644 --- a/release/sysinstall/installPreconfig.c +++ b/release/sysinstall/installPreconfig.c @@ -1,201 +1,201 @@ /* * The new sysinstall program. * * This is probably the last program in the `sysinstall' line - the next * generation being essentially a complete rewrite. * - * $Id: installPreconfig.c,v 1.2 1995/10/20 16:49:46 jkh Exp $ + * $Id: installPreconfig.c,v 1.4 1995/10/20 21:57:16 jkh Exp $ * * Copyright (c) 1995 * Jordan Hubbard. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * verbatim and that no modifications are made prior to this * point in the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Jordan Hubbard * for the FreeBSD Project. * 4. The name of Jordan Hubbard or the FreeBSD project may not be used to * endorse or promote products derived from this software without specific * prior written permission. * * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include "sysinstall.h" #include #include #include #include #include #include #include #define MSDOSFS #include #undef MSDOSFS #include #include #include static struct _word { char *name; int (*handler)(char *str); } resWords[] = { { "diskPartitionEditor", diskPartitionEditor }, { "diskPartitionWrite", diskPartitionWrite }, { "diskLabelEditor", diskLabelEditor }, { "diskLabelCommit", diskLabelCommit }, { "distReset", distReset }, { "distSetDeveloper", distSetDeveloper }, { "distSetXDeveloper", distSetXDeveloper }, { "distSetKernDeveloper", distSetKernDeveloper }, { "distSetMinimum", distSetMinimum }, { "distSetEverything", distSetEverything }, { "distSetDES", distSetDES }, { "distSetSrc", distSetSrc }, { "distSetXF86", distSetXF86 }, { "distExtractAll", distExtractAll }, { "docBrowser", docBrowser }, { "docShowDocument", docShowDocument }, { "installCommit", installCommit }, { "installExpress", installExpress }, { "installUpgrade", installUpgrade }, { "installPreconfig", installPreconfig }, { "installFixup", installFixup }, { "installFinal", installFinal }, { "installFilesystems", installFilesystems }, { "mediaSetCDROM", mediaSetCDROM }, { "mediaSetFloppy", mediaSetFloppy }, { "mediaSetDOS", mediaSetDOS }, { "mediaSetTape", mediaSetTape }, { "mediaSetFTP", mediaSetFTP }, { "mediaSetFTPActive", mediaSetFTPActive }, { "mediaSetFTPPassive", mediaSetFTPPassive }, { "mediaSetUFS", mediaSetUFS }, { "mediaSetNFS", mediaSetNFS }, { "mediaSetFtpUserPass", mediaSetFtpUserPass }, { "mediaSetCPIOVerbosity", mediaSetCPIOVerbosity }, { "mediaGetType", mediaGetType }, { "tcpInstallDevice", tcpInstallDevice }, { NULL, NULL }, }; static int call_possible_resword(char *name, char *value, int *status) { int i, rval; rval = 0; for (i = 0; resWords[i].name; i++) { if (!strcmp(name, resWords[i].name)) { *status = resWords[i].handler(value); rval = 1; break; } } return rval; } /* From the top menu - try to mount the floppy and read a configuration file from it */ int installPreconfig(char *str) { struct ufs_args u_args; struct msdosfs_args m_args; int fd, i; char buf[128]; char *cfg_file; memset(&u_args, 0, sizeof(u_args)); u_args.fspec = "/dev/fd0"; Mkdir("/mnt2", NULL); memset(&m_args, 0, sizeof(m_args)); m_args.fspec = "/dev/fd0"; m_args.uid = m_args.gid = 0; m_args.mask = 0777; i = RET_FAIL; while (1) { - if (!(cfg_file = variable_get_value(CONFIG_FILE, + if (!(cfg_file = variable_get_value(VAR_CONFIG_FILE, "Please insert the floppy containing this configuration file\n" "into drive A now and press [ENTER]."))) break; if (mount(MOUNT_UFS, "/mnt2", MNT_RDONLY, (caddr_t)&u_args) == -1) { if (mount(MOUNT_MSDOS, "/mnt2", MNT_RDONLY, (caddr_t)&m_args) == -1) { if (msgYesNo("Unable to mount the configuration floppy - do you want to try again?")) break; else continue; } } fnord: if (!cfg_file) break; sprintf(buf, "/mnt2/%s", cfg_file); msgDebug("Attempting to open configuration file: %s\n", buf); fd = open(buf, O_RDONLY); if (fd == -1) { if (msgYesNo("Unable to find the configuration file `%s' - do you want to\n" "try again?", buf)) { unmount("/mnt2", 0); break; } else goto fnord; } else { Attribs *cattr = safe_malloc(sizeof(Attribs) * MAX_ATTRIBS); int i, j; if (attr_parse(cattr, fd) == RET_FAIL) msgConfirm("Cannot parse configuration file %s! Please verify your media.", cfg_file); else { i = RET_SUCCESS; for (j = 0; cattr[j].name[0]; j++) { int status; if (call_possible_resword(cattr[j].name, cattr[j].value, &status)) { if (status != RET_SUCCESS) { msgDebug("macro call to %s(%s) returns %d status!\n", cattr[j].name, cattr[j].value, status); i = status; } } else variable_set2(cattr[j].name, cattr[j].value); } if (i == RET_SUCCESS) msgConfirm("Configuration file %s loaded successfully!\n" "Some parameters may now have new default values.", buf); else if (i == RET_FAIL) msgConfirm("Configuration file %s loaded with some errors.\n", buf); } close(fd); safe_free(cattr); unmount("/mnt2", 0); break; } } return i; } diff --git a/release/sysinstall/options.c b/release/sysinstall/options.c index 11c7671391bf..dbc32f89f020 100644 --- a/release/sysinstall/options.c +++ b/release/sysinstall/options.c @@ -1,286 +1,286 @@ /* * The new sysinstall program. * * This is probably the last attempt in the `sysinstall' line, the next * generation being slated for what's essentially a complete rewrite. * - * $Id: options.c,v 1.20 1995/10/21 14:06:59 jkh Exp $ + * $Id: options.c,v 1.22 1995/10/21 18:28:07 jkh Exp $ * * Copyright (c) 1995 * Jordan Hubbard. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * verbatim and that no modifications are made prior to this * point in the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Jordan Hubbard * for the FreeBSD Project. * 4. The name of Jordan Hubbard or the FreeBSD project may not be used to * endorse or promote products derived from this software without specific * prior written permission. * * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include "sysinstall.h" #include static char * varCheck(Option opt) { char *cp = NULL; if (opt.aux) cp = variable_get((char *)opt.aux); if (!cp) return "NO"; return cp; } /* Show our little logo */ static char * resetLogo(char *str) { return "[WHAP!]"; } static char * mediaCheck(Option opt) { if (mediaDevice) { switch(mediaDevice->type) { case DEVICE_TYPE_UFS: case DEVICE_TYPE_DISK: return "File system"; case DEVICE_TYPE_FLOPPY: return "Floppy"; case DEVICE_TYPE_FTP: return "FTP"; case DEVICE_TYPE_CDROM: return "CDROM"; case DEVICE_TYPE_TAPE: return "Tape"; case DEVICE_TYPE_DOS: return "DOS"; case DEVICE_TYPE_NFS: return "NFS"; case DEVICE_TYPE_NONE: case DEVICE_TYPE_NETWORK: case DEVICE_TYPE_ANY: default: return ""; } } return ""; } #define TAPE_PROMPT "Please enter the tape block size in 512 byte blocks" #define RELNAME_PROMPT "Please specify the release you wish to load" #define BPKG_PROMPT "Please specify the name of the HTML browser package:" #define BBIN_PROMPT "Please specify a full pathname to the HTML browser binary:" #define CONFIG_PROMPT "Please specify the name of a configuration file" static Option Options[] = { { "NFS Secure", "NFS server talks only on a secure port", - OPT_IS_VAR, NULL, OPT_NFS_SECURE, varCheck }, + OPT_IS_VAR, NULL, VAR_NFS_SECURE, varCheck }, { "NFS Slow", "User is using a slow PC or ethernet card", - OPT_IS_VAR, NULL, OPT_SLOW_ETHER, varCheck }, + OPT_IS_VAR, NULL, VAR_SLOW_ETHER, varCheck }, { "Debugging", "Emit extra debugging output on VTY2 (ALT-F2)", - OPT_IS_VAR, NULL, OPT_DEBUG, varCheck }, + OPT_IS_VAR, NULL, VAR_DEBUG, varCheck }, { "Yes to All", "Assume \"Yes\" answers to all non-critical dialogs", - OPT_IS_VAR, NULL, OPT_NO_CONFIRM, varCheck }, + OPT_IS_VAR, NULL, VAR_NO_CONFIRM, varCheck }, { "FTP OnError", "What to do when FTP requests fail: abort, retry, reselect.", - OPT_IS_FUNC, mediaSetFtpOnError, OPT_FTP_ONERROR, varCheck }, + OPT_IS_FUNC, mediaSetFtpOnError, VAR_FTP_ONERROR, varCheck }, { "FTP username", "Username and password to use instead of anonymous", - OPT_IS_FUNC, mediaSetFtpUserPass, FTP_USER, varCheck }, + OPT_IS_FUNC, mediaSetFtpUserPass, VAR_FTP_USER, varCheck }, { "Tape Blocksize", "Tape media block size in 512 byte blocks", - OPT_IS_VAR, TAPE_PROMPT, TAPE_BLOCKSIZE, varCheck }, + OPT_IS_VAR, TAPE_PROMPT, VAR_TAPE_BLOCKSIZE, varCheck }, { "Extract Detail", "How verbosely to display file name information during extractions", - OPT_IS_FUNC, mediaSetCPIOVerbosity, CPIO_VERBOSITY_LEVEL, varCheck }, + OPT_IS_FUNC, mediaSetCPIOVerbosity, VAR_CPIO_VERBOSITY, varCheck }, { "Release Name", "Which release to attempt to load from installation media", - OPT_IS_VAR, RELNAME_PROMPT, RELNAME, varCheck }, + OPT_IS_VAR, RELNAME_PROMPT, VAR_RELNAME, varCheck }, { "Browser Pkg", "This is the browser package that will be used for viewing HTML", - OPT_IS_VAR, BPKG_PROMPT, BROWSER_PACKAGE, varCheck }, + OPT_IS_VAR, BPKG_PROMPT, VAR_BROWSER_PACKAGE, varCheck }, { "Browser Exec", "This is the path to the main binary of the browser package", - OPT_IS_VAR, BBIN_PROMPT, BROWSER_BINARY, varCheck }, + OPT_IS_VAR, BBIN_PROMPT, VAR_BROWSER_BINARY, varCheck }, { "Config File", "Name of default configuration file for Load command (top menu)", - OPT_IS_VAR, CONFIG_PROMPT, CONFIG_FILE, varCheck }, + OPT_IS_VAR, CONFIG_PROMPT, VAR_CONFIG_FILE, varCheck }, { "Media Type", "The current installation media type.", - OPT_IS_FUNC, mediaGetType, MEDIA_TYPE, mediaCheck }, + OPT_IS_FUNC, mediaGetType, VAR_MEDIA_TYPE, mediaCheck }, { "Use Defaults", "Reset all values to startup defaults", OPT_IS_FUNC, installVarDefaults, 0, resetLogo }, { NULL }, }; #define OPT_START_ROW 4 #define OPT_END_ROW 20 #define OPT_NAME_COL 0 #define OPT_VALUE_COL 16 #define GROUP_OFFSET 40 static char * value_of(Option opt) { static char ival[40]; switch (opt.type) { case OPT_IS_STRING: return (char *)opt.data; case OPT_IS_INT: sprintf(ival, "%d", (int)opt.data); return ival; case OPT_IS_FUNC: case OPT_IS_VAR: if (opt.check) return opt.check(opt); else return "<*>"; } return ""; } static void fire(Option opt) { if (opt.type == OPT_IS_FUNC) { int (*cp)(char *) = opt.data; cp(NULL); } else if (opt.type == OPT_IS_VAR) { if (opt.data) { (void)variable_get_value(opt.aux, opt.data); dialog_clear(); } else if (variable_get(opt.aux)) variable_unset(opt.aux); else variable_set2(opt.aux, "YES"); } if (opt.check) opt.check(opt); clear(); refresh(); } int optionsEditor(char *str) { int i, optcol, optrow, key; static int currOpt = 0; dialog_clear(); clear(); while (1) { /* Whap up the header */ attrset(A_REVERSE); mvaddstr(0, 0, "Options Editor"); attrset(A_NORMAL); for (i = 0; i < 2; i++) { mvaddstr(OPT_START_ROW - 2, OPT_NAME_COL + (i * GROUP_OFFSET), "Name"); mvaddstr(OPT_START_ROW - 1, OPT_NAME_COL + (i * GROUP_OFFSET), "----"); mvaddstr(OPT_START_ROW - 2, OPT_VALUE_COL + (i * GROUP_OFFSET), "Value"); mvaddstr(OPT_START_ROW - 1, OPT_VALUE_COL + (i * GROUP_OFFSET), "-----"); } /* And the footer */ mvprintw(OPT_END_ROW + 0, 0, "Use SPACE to select/toggle an option, arrow keys to move,"); mvprintw(OPT_END_ROW + 1, 0, "? or F1 for more help. When you're done, type Q to Quit."); optrow = OPT_START_ROW; optcol = OPT_NAME_COL; for (i = 0; Options[i].name; i++) { /* Names are painted somewhat gratuitously each time, but it's easier this way */ mvprintw(optrow, OPT_NAME_COL + optcol, Options[i].name); if (currOpt == i) standout(); mvprintw(optrow++, OPT_VALUE_COL + optcol, value_of(Options[i])); if (currOpt == i) standend(); if (optrow == OPT_END_ROW) { optrow = OPT_START_ROW; optcol += GROUP_OFFSET; } clrtoeol(); } standout(); mvaddstr(OPT_END_ROW + 3, 0, Options[currOpt].desc); standend(); clrtoeol(); move(0, 14); /* Start the edit loop */ key = toupper(getch()); switch (key) { case KEY_F(1): case '?': systemDisplayHelp("options"); break; case KEY_UP: if (currOpt) --currOpt; else beep(); continue; case KEY_DOWN: if (Options[currOpt + 1].name) ++currOpt; else beep(); continue; case KEY_HOME: currOpt = 0; continue; case KEY_END: while (Options[currOpt + 1].name) ++currOpt; continue; case ' ': dialog_clear(); fire(Options[currOpt]); dialog_clear(); clear(); continue; case 'Q': clear(); dialog_clear(); return RET_SUCCESS; default: beep(); } } /* NOTREACHED */ return RET_SUCCESS; } diff --git a/release/sysinstall/package.c b/release/sysinstall/package.c index f72813a3f0bc..c2eb28590f67 100644 --- a/release/sysinstall/package.c +++ b/release/sysinstall/package.c @@ -1,200 +1,200 @@ /* * The new sysinstall program. * * This is probably the last program in the `sysinstall' line - the next * generation being essentially a complete rewrite. * - * $Id: package.c,v 1.7 1995/10/20 22:36:06 jkh Exp $ + * $Id: package.c,v 1.8 1995/10/21 20:03:07 jkh Exp $ * * Copyright (c) 1995 * Jordan Hubbard. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * verbatim and that no modifications are made prior to this * point in the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Jordan Hubbard * for the FreeBSD Project. * 4. The name of Jordan Hubbard or the FreeBSD project may not be used to * endorse or promote products derived from this software without specific * prior written permission. * * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include #include #include #include #include #include #include #include "sysinstall.h" static char *make_playpen(char *pen, size_t sz); /* Extract a package based on a namespec and a media device */ int package_extract(Device *dev, char *name) { char path[511]; char pen[FILENAME_MAX]; char *where; int i, fd, ret; /* Check to make sure it's not already there */ if (!vsystem("pkg_info -e %s", name)) return RET_SUCCESS; if (!dev->init(dev)) { msgConfirm("Unable to initialize media type for package add."); return RET_FAIL; } ret = RET_FAIL; sprintf(path, "packages/All/%s%s", name, strstr(name, ".tgz") ? "" : ".tgz"); msgDebug("pkg_extract: Attempting to fetch %s\n", path); fd = dev->get(dev, path, TRUE); if (fd >= 0) { pid_t tpid; msgNotify("Fetching %s from %s", path, dev->name); pen[0] = '\0'; if ((where = make_playpen(pen, 0)) != NULL) { if (isDebug()) msgDebug("Working in temporary directory %s, will return to %s\n", pen, where); tpid = fork(); if (!tpid) { dup2(fd, 0); - i = vsystem("tar %s-xzf -", !strcmp(variable_get(CPIO_VERBOSITY_LEVEL), "high") ? "-v " : ""); + i = vsystem("tar %s-xzf -", !strcmp(variable_get(VAR_CPIO_VERBOSITY), "high") ? "-v " : ""); if (isDebug()) msgDebug("tar command returns %d status\n", i); exit(i); } else { int pstat; tpid = waitpid(tpid, &pstat, 0); if (vsystem("(pwd; cat +CONTENTS) | pkg_add %s-S", - !strcmp(variable_get(CPIO_VERBOSITY_LEVEL), "high") ? "-v " : "")) + !strcmp(variable_get(VAR_CPIO_VERBOSITY), "high") ? "-v " : "")) msgConfirm("An error occurred while trying to pkg_add %s.\n" "Please check debugging screen for possible further details.", path); else ret = RET_SUCCESS; close(fd); } if (chdir(where) == -1) msgFatal("Unable to get back to where I was before, Jojo! (That was: %s)", where); vsystem("rm -rf %s", pen); if (isDebug()) msgDebug("Nuked pen: %s\n", pen); } else msgConfirm("Unable to find a temporary location to unpack this stuff in.\n" "You must simply not have enough space or you've configured your\n" "system oddly. Sorry!"); dev->close(dev, fd); if (dev->type == DEVICE_TYPE_TAPE) unlink(path); } else msgDebug("pkg_extract: get operation returned %d\n", fd); return ret; } static size_t min_free(char *tmpdir) { struct statfs buf; if (statfs(tmpdir, &buf) != 0) { msgDebug("Error in statfs, errno = %d\n", errno); return -1; } return buf.f_bavail * buf.f_bsize; } /* Find a good place to play. */ static char * find_play_pen(char *pen, size_t sz) { struct stat sb; if (pen[0] && stat(pen, &sb) != RET_FAIL && (min_free(pen) >= sz)) return pen; else if (stat("/var/tmp", &sb) != RET_FAIL && min_free("/var/tmp") >= sz) strcpy(pen, "/var/tmp/instmp.XXXXXX"); else if (stat("/tmp", &sb) != RET_FAIL && min_free("/tmp") >= sz) strcpy(pen, "/tmp/instmp.XXXXXX"); else if ((stat("/usr/tmp", &sb) == RET_SUCCESS || mkdir("/usr/tmp", 01777) == RET_SUCCESS) && min_free("/usr/tmp") >= sz) strcpy(pen, "/usr/tmp/instmp.XXXXXX"); else { msgConfirm("Can't find enough temporary space to extract the files, please try\n" "This again after your system is up (you can run /stand/sysinstall\n" "directly) and you've had a chance to point /var/tmp somewhere with\n" "sufficient temporary space available."); return NULL; } return pen; } /* * Make a temporary directory to play in and chdir() to it, returning * pathname of previous working directory. */ static char * make_playpen(char *pen, size_t sz) { static char Previous[FILENAME_MAX]; if (!find_play_pen(pen, sz)) return NULL; if (!mktemp(pen)) { msgConfirm("Can't mktemp '%s'.", pen); return NULL; } if (mkdir(pen, 0755) == RET_FAIL) { msgConfirm("Can't mkdir '%s'.", pen); return NULL; } if (isDebug()) { if (sz) msgDebug("Requested space: %d bytes, free space: %d bytes in %s\n", (int)sz, min_free(pen), pen); } if (min_free(pen) < sz) { rmdir(pen); msgConfirm("Not enough free space to create: `%s'\n" "Please try this again after your system is up (you can run\n" "/stand/sysinstall directly) and you've had a chance to point\n" "/var/tmp somewhere with sufficient temporary space available."); return NULL; } if (!getcwd(Previous, FILENAME_MAX)) { msgConfirm("getcwd"); return NULL; } if (chdir(pen) == RET_FAIL) msgConfirm("Can't chdir to '%s'.", pen); return Previous; } diff --git a/usr.sbin/sysinstall/doc.c b/usr.sbin/sysinstall/doc.c index 8b2c20d097ca..49fe7983c3e7 100644 --- a/usr.sbin/sysinstall/doc.c +++ b/usr.sbin/sysinstall/doc.c @@ -1,88 +1,88 @@ /* * The new sysinstall program. * * This is probably the last program in the `sysinstall' line - the next * generation being essentially a complete rewrite. * - * $Id: doc.c,v 1.1 1995/10/20 07:03:40 jkh Exp $ + * $Id: doc.c,v 1.2 1995/10/20 14:24:41 jkh Exp $ * * Jordan Hubbard * * My contributions are in the public domain. * * Parts of this file are also blatently stolen from Poul-Henning Kamp's * previous version of sysinstall, and as such fall under his "BEERWARE license" * so buy him a beer if you like it! Buy him a beer for me, too! * Heck, get him completely drunk and send me pictures! :-) */ #include "sysinstall.h" /* * This is called from the main menu. Try to find a copy of Lynx from somewhere * and fire it up on the first copy of the handbook we can find. */ int docBrowser(char *junk) { - char *browser = variable_get(BROWSER_PACKAGE); + char *browser = variable_get(VAR_BROWSER_PACKAGE); /* Make sure we were started at a reasonable time */ if (!strcmp(variable_get(SYSTEM_STATE), "init")) { msgConfirm("Sorry, it's not possible to invoke the browser until the system\n" "is installed completely enough to support a copy of %s.", browser); return RET_FAIL; } if (!mediaVerify()) return RET_FAIL; /* First, make sure we have whatever browser we've chosen is here */ if (package_extract(mediaDevice, browser) != RET_SUCCESS) { msgConfirm("Unable to install the %s HTML browser package. You may\n" "wish to verify that your media is configured correctly and\n" "try again.", browser); return RET_FAIL; } - if (!file_executable(variable_get(BROWSER_BINARY))) { + if (!file_executable(variable_get(VAR_BROWSER_BINARY))) { if (!msgYesNo("Hmmm. The %s package claims to have installed, but I can't\n" "find its binary in %s! You may wish to try a different\n" "location to load the package from (go to Media menu) and see if that\n" "makes a difference.\n\n" "I suggest that we remove the version that was extracted since it does\n" "not appear to be correct. Would you like me to do that now?")) - vsystem("pkg_delete %s %s", !strcmp(variable_get(CPIO_VERBOSITY_LEVEL), "high") ? "-v" : "", browser); + vsystem("pkg_delete %s %s", !strcmp(variable_get(VAR_CPIO_VERBOSITY), "high") ? "-v" : "", browser); return RET_FAIL; } /* Run browser on the appropriate doc */ dmenuOpenSimple(&MenuHTMLDoc); return RET_SUCCESS; } /* Try to show one of the documents requested from the HTML doc menu */ int docShowDocument(char *str) { - char *browser = variable_get(BROWSER_BINARY); + char *browser = variable_get(VAR_BROWSER_BINARY); if (!file_executable(browser)) { msgConfirm("Can't find the browser in %s! Please ensure that it's\n" "properly set in the Options editor.", browser); return RET_FAIL; } if (!strcmp(str, "Home")) vsystem("%s http://www.freebsd.org", browser); else if (!strcmp(str, "Other")) { } else { char target[512]; sprintf(target, "/usr/share/doc/%s/%s.html", str, str); if (file_readable(target)) vsystem("%s file:%s", browser, target); else vsystem("%s http://www.freebsd.org/%s"); } return RET_SUCCESS; } diff --git a/usr.sbin/sysinstall/index.c b/usr.sbin/sysinstall/index.c index 8cf6fa0e66d9..8b9dcfc4fd78 100644 --- a/usr.sbin/sysinstall/index.c +++ b/usr.sbin/sysinstall/index.c @@ -1,569 +1,569 @@ /* * The new sysinstall program. * * This is probably the last program in the `sysinstall' line - the next * generation being essentially a complete rewrite. * - * $Id: index.c,v 1.13 1995/10/20 21:57:08 jkh Exp $ + * $Id: index.c,v 1.14 1995/10/21 14:06:44 jkh Exp $ * * Copyright (c) 1995 * Jordan Hubbard. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * verbatim and that no modifications are made prior to this * point in the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Jordan Hubbard * for the FreeBSD Project. * 4. The name of Jordan Hubbard or the FreeBSD project may not be used to * endorse or promote products derived from this software without specific * prior written permission. * * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include #include #include #include #include #include #include "sysinstall.h" /* Macros and magic values */ #define MAX_MENU 13 #define _MAX_DESC 62 /* Smarter strdup */ inline char * _strdup(char *ptr) { return ptr ? strdup(ptr) : NULL; } static char *descrs[] = { "Package Selection", "To mark a package or select a category, move to it and press SPACE.\n" "To unmark a package, press SPACE again. When you want to commit your\n" "marks, press [ENTER]. To go to a previous menu, select UP item or Cancel.\n" "To search for a package by name, press ESC.", "Package Targets", "These are the packages you've selected for extraction.\n\n" "If you're sure of these choices, select OK.\n" "If not, select Cancel to go back to the package selection menu.\n", "All", "All available packages in all categories.", "applications", "User application software.", "archivers", "Utilities for archiving and unarchiving data.", "audio", "Audio utilities - most require a supported sound card.", "benchmarks", "Utilities for measuring system performance.", "benchmarking", "Utilities for measuring system performance.", "cad", "Computer Aided Design utilities.", "comms", "Communications utilities.", "databases", "Database software.", "devel", "Software development utilities and libraries.", "development", "Software development utilities and libraries.", "documentation", "Document preparation utilities.", "editors", "Common text editors.", "emulation", "Utilities for emulating other OS types.", "emulators", "Utilities for emulating other OS types.", "games", "Various and sundry amusements.", "graphics", "Graphics libraries and utilities.", "japanese", "Ported software for the Japanese market.", "lang", "Computer languages.", "languages", "Computer languages.", "libraries", "Software development libraries.", "mail", "Electronic mail packages and utilities.", "math", "Mathematical computation software.", "net", "Networking utilities.", "networking", "Networking utilities.", "news", "USENET News support software.", "numeric", "Mathematical computation software.", "orphans", "Packages without a home elsewhere.", "plan9", "Software from the plan9 Operating System.", "print", "Utilities for dealing with printing.", "printing", "Utilities for dealing with printing.", "programming", "Software development utilities and libraries.", "russian", "Ported software for the Russian market.", "security", "System security software.", "shells", "Various shells (tcsh, bash, etc).", "sysutils", "Various system utilities.", "troff", "TROFF Text formatting utilities.", "utils", "Various user utilities.", "utilities", "Various user utilities.", "x11", "X Window System based utilities.", NULL, NULL, }; static char * fetch_desc(char *name) { int i; for (i = 0; descrs[i]; i += 2) { if (!strcmp(descrs[i], name)) return descrs[i + 1]; } return "No description provided"; } static PkgNodePtr new_pkg_node(char *name, node_type type) { PkgNodePtr tmp = safe_malloc(sizeof(PkgNode)); tmp->name = _strdup(name); tmp->type = type; return tmp; } static IndexEntryPtr new_index(char *name, char *pathto, char *prefix, char *comment, char *descr, char *maint) { IndexEntryPtr tmp = safe_malloc(sizeof(IndexEntry)); tmp->name = _strdup(name); tmp->path = _strdup(pathto); tmp->prefix = _strdup(prefix); tmp->comment = _strdup(comment); tmp->descrfile = _strdup(descr); tmp->maintainer = _strdup(maint); return tmp; } static void index_register(PkgNodePtr top, char *where, IndexEntryPtr ptr) { PkgNodePtr p, q; for (q = NULL, p = top->kids; p; p = p->next) { if (!strcmp(p->name, where)) { q = p; break; } } if (!p) { /* Add new category */ q = new_pkg_node(where, PLACE); q->desc = fetch_desc(where); q->next = top->kids; top->kids = q; } p = new_pkg_node(ptr->name, PACKAGE); p->desc = ptr->comment; p->data = ptr; p->next = q->kids; q->kids = p; } static int copy_to_sep(char *to, char *from, int sep) { char *tok; tok = strchr(from, sep); if (!tok) { fprintf(stderr, "missing '%c' token.\n", sep); *to = '\0'; return 0; } *tok = '\0'; strcpy(to, from); return tok + 1 - from; } static int readline(int fd, char *buf, int max) { int rv, i = 0; char ch; while ((rv = read(fd, &ch, 1)) == 1 && ch != '\n' && i < max) buf[i++] = ch; if (i < max) buf[i] = '\0'; return rv; } int index_parse(int fd, char *name, char *pathto, char *prefix, char *comment, char *descr, char *maint, char *cats, char *keys) { char line[1024]; char *cp; int i; i = readline(fd, line, 1024); if (i <= 0) return EOF; cp = line; cp += copy_to_sep(name, cp, '|'); cp += copy_to_sep(pathto, cp, '|'); cp += copy_to_sep(prefix, cp, '|'); cp += copy_to_sep(comment, cp, '|'); cp += copy_to_sep(descr, cp, '|'); cp += copy_to_sep(maint, cp, '|'); cp += copy_to_sep(cats, cp, '|'); strcpy(keys, cp); return 0; } int index_get(char *fname, PkgNodePtr papa) { int i, fd; fd = open(fname, O_RDONLY); if (fd < 0) { fprintf(stderr, "Unable to open index file `%s' for reading.\n", fname); i = -1; } else i = index_read(fd, papa); close(fd); return i; } int index_read(int fd, PkgNodePtr papa) { char name[127], pathto[255], prefix[255], comment[255], descr[127], maint[127], cats[511], keys[511]; while (index_parse(fd, name, pathto, prefix, comment, descr, maint, cats, keys) != EOF) { char *cp, *cp2, tmp[511]; IndexEntryPtr idx; idx = new_index(name, pathto, prefix, comment, descr, maint); /* For now, we only add things to menus if they're in categories. Keywords are ignored */ for (cp = strcpy(tmp, cats); (cp2 = strchr(cp, ' ')) != NULL; cp = cp2 + 1) { *cp2 = '\0'; index_register(papa, cp, idx); } index_register(papa, cp, idx); /* Add to special "All" category */ index_register(papa, "All", idx); } return 0; } void index_init(PkgNodePtr top, PkgNodePtr plist) { top->next = top->kids = NULL; top->name = "Package Selection"; top->type = PLACE; top->desc = fetch_desc(top->name); plist->next = plist->kids = NULL; plist->name = "Package Targets"; plist->type = PLACE; plist->desc = fetch_desc(plist->name); } void index_entry_free(IndexEntryPtr top) { safe_free(top->name); safe_free(top->path); safe_free(top->prefix); safe_free(top->comment); safe_free(top->descrfile); safe_free(top->maintainer); free(top); } void index_node_free(PkgNodePtr top, PkgNodePtr plist) { PkgNodePtr tmp; tmp = plist; while (tmp) { PkgNodePtr tmp2 = tmp->next; safe_free(tmp); tmp = tmp2; } for (tmp = top; tmp; tmp = tmp->next) { free(tmp->name); if (tmp->type == PACKAGE && tmp->data) index_entry_free((IndexEntryPtr)tmp->data); if (tmp->kids) index_node_free(tmp->kids, NULL); } } void index_print(PkgNodePtr top, int level) { int i; while (top) { for (i = 0; i < level; i++) putchar('\t'); printf("name [%s]: %s\n", top->type == PLACE ? "place" : "package", top->name); for (i = 0; i < level; i++) putchar('\t'); printf("desc: %s\n", top->desc); if (top->kids) index_print(top->kids, level + 1); top = top->next; } } /* Swap one node for another */ static void swap_nodes(PkgNodePtr a, PkgNodePtr b) { PkgNode tmp; tmp = *a; *a = *b; a->next = tmp.next; tmp.next = b->next; *b = tmp; } /* Use a disgustingly simplistic bubble sort to put our lists in order */ void index_sort(PkgNodePtr top) { PkgNodePtr p, q; /* Sort everything at the top level */ for (p = top->kids; p; p = p->next) { for (q = top->kids; q; q = q->next) { if (q->next && strcmp(q->name, q->next->name) > 0) swap_nodes(q, q->next); } } /* Now sub-sort everything n levels down */ for (p = top->kids; p; p = p->next) { if (p->kids) index_sort(p); } } /* * No, we don't free n because someone else is still pointing at it. * It's just clone linked from another location, which we're adjusting. */ void index_delete(PkgNodePtr n) { if (n->next) *n = *(n->next); else /* Kludgy end sentinal */ n->name = NULL; } PkgNodePtr index_search(PkgNodePtr top, char *str, PkgNodePtr *tp) { PkgNodePtr p, sp; for (p = top->kids; p && p->name; p = p->next) { /* Subtract out the All category from searches */ if (!strcmp(p->name, "All")) continue; /* If tp == NULL, we're looking for an exact package match */ if (!tp && !strcmp(p->name, str)) return p; /* If tp, we're looking for both a package and a pointer to the place it's in */ if (tp && strstr(p->name, str)) { *tp = top; return p; } /* The usual recursion-out-of-laziness ploy */ if (p->kids) if ((sp = index_search(p, str, tp)) != NULL) return sp; } if (p && !p->name) p = NULL; return p; } /* Work function for seeing if name x is in result string y */ static Boolean is_selected_in(char *name, char *result) { Boolean ret = FALSE; while (*result) { char *cp; cp = index(result, '\n'); if (!cp) { ret = !strcmp(name, result); break; } else { ret = !strncmp(name, result, cp - result - 1); if (ret) break; } result = cp + 1; } return ret; } int index_menu(PkgNodePtr top, PkgNodePtr plist, int *pos, int *scroll) { int n, rval, maxname; int curr, max; PkgNodePtr sp, kp; char **nitems; char result[127]; Boolean hasPackages; curr = max = 0; hasPackages = FALSE; nitems = NULL; n = maxname = 0; /* Figure out if this menu is full of "leaves" or "branches" */ for (kp = top->kids; kp && kp->name; kp = kp->next) { int len; ++n; if (kp->type == PACKAGE && plist) { hasPackages = TRUE; if ((len = strlen(kp->name)) > maxname) maxname = len; } } if (!n && plist) { msgConfirm("The %s menu is empty.", top->name); return RET_DONE; } dialog_clear(); while (1) { n = 0; kp = top->kids; if (!hasPackages && kp && kp->name && plist) { nitems = item_add_pair(nitems, "UP", "", &curr, &max); ++n; } while (kp && kp->name) { /* Brutally adjust description to fit in menu */ if (strlen(kp->desc) > (_MAX_DESC - maxname)) kp->desc[_MAX_DESC - maxname] = '\0'; nitems = item_add_pair(nitems, kp->name, kp->desc, &curr, &max); if (hasPackages) { if (kp->type == PACKAGE && plist) nitems = item_add(nitems, index_search(plist, kp->name, NULL) ? "ON" : "OFF", &curr, &max); else nitems = item_add(nitems, "OFF", &curr, &max); } ++n; kp = kp->next; } nitems = item_add(nitems, NULL, &curr, &max); if (hasPackages) rval = dialog_checklist(top->name, top->desc, -1, -1, n > MAX_MENU ? MAX_MENU : n, n, (unsigned char **)nitems, result); else /* It's a categories menu */ rval = dialog_menu(top->name, top->desc, -1, -1, n > MAX_MENU ? MAX_MENU : n, n, (unsigned char **)nitems, result, pos, scroll); items_free(nitems, &curr, &max); if (!rval && plist && strcmp(result, "UP")) { for (kp = top->kids; kp; kp = kp->next) { if (kp->type == PACKAGE) { sp = index_search(plist, kp->name, NULL); if (is_selected_in(kp->name, result)) { if (!sp) { PkgNodePtr n = (PkgNodePtr)safe_malloc(sizeof(PkgNode)); *n = *kp; n->next = plist->kids; plist->kids = n; standout(); mvprintw(23, 0, "Selected packages were added to selection list\n", kp->name); standend(); refresh(); } } else if (sp) { standout(); mvprintw(23, 0, "Deleting unselected packages from selection list\n", kp->name); standend(); refresh(); index_delete(sp); } } else if (!strcmp(kp->name, result)) { /* Not a package, must be a directory */ int p, s; p = s = 0; index_menu(kp, plist, &p, &s); } } } else if (rval == -1 && plist) { static char *cp; PkgNodePtr menu; /* Search */ if ((cp = msgGetInput(cp, "Search by package name. Please enter search string:")) != NULL) { PkgNodePtr p = index_search(top, cp, &menu); if (p) { int pos, scroll; /* These need to be set to point at the found item, actually. Hmmm! */ pos = scroll = 0; index_menu(menu, plist, &pos, &scroll); } else msgConfirm("Search string: %s yielded no hits.", cp); } } else { dialog_clear(); return rval ? RET_FAIL : RET_SUCCESS; } } } int index_extract(Device *dev, PkgNodePtr plist) { PkgNodePtr tmp; int status = RET_SUCCESS; for (tmp = plist->kids; tmp; tmp = tmp->next) { if (package_extract(dev, tmp->name) != RET_SUCCESS) { - if (variable_get(OPT_NO_CONFIRM)) + if (variable_get(VAR_NO_CONFIRM)) msgNotify("Unable to locate package %s..", tmp->name); else msgConfirm("Unable to locate package %s..", tmp->name); status = RET_FAIL; } } return status; } diff --git a/usr.sbin/sysinstall/options.c b/usr.sbin/sysinstall/options.c index 11c7671391bf..dbc32f89f020 100644 --- a/usr.sbin/sysinstall/options.c +++ b/usr.sbin/sysinstall/options.c @@ -1,286 +1,286 @@ /* * The new sysinstall program. * * This is probably the last attempt in the `sysinstall' line, the next * generation being slated for what's essentially a complete rewrite. * - * $Id: options.c,v 1.20 1995/10/21 14:06:59 jkh Exp $ + * $Id: options.c,v 1.22 1995/10/21 18:28:07 jkh Exp $ * * Copyright (c) 1995 * Jordan Hubbard. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * verbatim and that no modifications are made prior to this * point in the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Jordan Hubbard * for the FreeBSD Project. * 4. The name of Jordan Hubbard or the FreeBSD project may not be used to * endorse or promote products derived from this software without specific * prior written permission. * * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include "sysinstall.h" #include static char * varCheck(Option opt) { char *cp = NULL; if (opt.aux) cp = variable_get((char *)opt.aux); if (!cp) return "NO"; return cp; } /* Show our little logo */ static char * resetLogo(char *str) { return "[WHAP!]"; } static char * mediaCheck(Option opt) { if (mediaDevice) { switch(mediaDevice->type) { case DEVICE_TYPE_UFS: case DEVICE_TYPE_DISK: return "File system"; case DEVICE_TYPE_FLOPPY: return "Floppy"; case DEVICE_TYPE_FTP: return "FTP"; case DEVICE_TYPE_CDROM: return "CDROM"; case DEVICE_TYPE_TAPE: return "Tape"; case DEVICE_TYPE_DOS: return "DOS"; case DEVICE_TYPE_NFS: return "NFS"; case DEVICE_TYPE_NONE: case DEVICE_TYPE_NETWORK: case DEVICE_TYPE_ANY: default: return ""; } } return ""; } #define TAPE_PROMPT "Please enter the tape block size in 512 byte blocks" #define RELNAME_PROMPT "Please specify the release you wish to load" #define BPKG_PROMPT "Please specify the name of the HTML browser package:" #define BBIN_PROMPT "Please specify a full pathname to the HTML browser binary:" #define CONFIG_PROMPT "Please specify the name of a configuration file" static Option Options[] = { { "NFS Secure", "NFS server talks only on a secure port", - OPT_IS_VAR, NULL, OPT_NFS_SECURE, varCheck }, + OPT_IS_VAR, NULL, VAR_NFS_SECURE, varCheck }, { "NFS Slow", "User is using a slow PC or ethernet card", - OPT_IS_VAR, NULL, OPT_SLOW_ETHER, varCheck }, + OPT_IS_VAR, NULL, VAR_SLOW_ETHER, varCheck }, { "Debugging", "Emit extra debugging output on VTY2 (ALT-F2)", - OPT_IS_VAR, NULL, OPT_DEBUG, varCheck }, + OPT_IS_VAR, NULL, VAR_DEBUG, varCheck }, { "Yes to All", "Assume \"Yes\" answers to all non-critical dialogs", - OPT_IS_VAR, NULL, OPT_NO_CONFIRM, varCheck }, + OPT_IS_VAR, NULL, VAR_NO_CONFIRM, varCheck }, { "FTP OnError", "What to do when FTP requests fail: abort, retry, reselect.", - OPT_IS_FUNC, mediaSetFtpOnError, OPT_FTP_ONERROR, varCheck }, + OPT_IS_FUNC, mediaSetFtpOnError, VAR_FTP_ONERROR, varCheck }, { "FTP username", "Username and password to use instead of anonymous", - OPT_IS_FUNC, mediaSetFtpUserPass, FTP_USER, varCheck }, + OPT_IS_FUNC, mediaSetFtpUserPass, VAR_FTP_USER, varCheck }, { "Tape Blocksize", "Tape media block size in 512 byte blocks", - OPT_IS_VAR, TAPE_PROMPT, TAPE_BLOCKSIZE, varCheck }, + OPT_IS_VAR, TAPE_PROMPT, VAR_TAPE_BLOCKSIZE, varCheck }, { "Extract Detail", "How verbosely to display file name information during extractions", - OPT_IS_FUNC, mediaSetCPIOVerbosity, CPIO_VERBOSITY_LEVEL, varCheck }, + OPT_IS_FUNC, mediaSetCPIOVerbosity, VAR_CPIO_VERBOSITY, varCheck }, { "Release Name", "Which release to attempt to load from installation media", - OPT_IS_VAR, RELNAME_PROMPT, RELNAME, varCheck }, + OPT_IS_VAR, RELNAME_PROMPT, VAR_RELNAME, varCheck }, { "Browser Pkg", "This is the browser package that will be used for viewing HTML", - OPT_IS_VAR, BPKG_PROMPT, BROWSER_PACKAGE, varCheck }, + OPT_IS_VAR, BPKG_PROMPT, VAR_BROWSER_PACKAGE, varCheck }, { "Browser Exec", "This is the path to the main binary of the browser package", - OPT_IS_VAR, BBIN_PROMPT, BROWSER_BINARY, varCheck }, + OPT_IS_VAR, BBIN_PROMPT, VAR_BROWSER_BINARY, varCheck }, { "Config File", "Name of default configuration file for Load command (top menu)", - OPT_IS_VAR, CONFIG_PROMPT, CONFIG_FILE, varCheck }, + OPT_IS_VAR, CONFIG_PROMPT, VAR_CONFIG_FILE, varCheck }, { "Media Type", "The current installation media type.", - OPT_IS_FUNC, mediaGetType, MEDIA_TYPE, mediaCheck }, + OPT_IS_FUNC, mediaGetType, VAR_MEDIA_TYPE, mediaCheck }, { "Use Defaults", "Reset all values to startup defaults", OPT_IS_FUNC, installVarDefaults, 0, resetLogo }, { NULL }, }; #define OPT_START_ROW 4 #define OPT_END_ROW 20 #define OPT_NAME_COL 0 #define OPT_VALUE_COL 16 #define GROUP_OFFSET 40 static char * value_of(Option opt) { static char ival[40]; switch (opt.type) { case OPT_IS_STRING: return (char *)opt.data; case OPT_IS_INT: sprintf(ival, "%d", (int)opt.data); return ival; case OPT_IS_FUNC: case OPT_IS_VAR: if (opt.check) return opt.check(opt); else return "<*>"; } return ""; } static void fire(Option opt) { if (opt.type == OPT_IS_FUNC) { int (*cp)(char *) = opt.data; cp(NULL); } else if (opt.type == OPT_IS_VAR) { if (opt.data) { (void)variable_get_value(opt.aux, opt.data); dialog_clear(); } else if (variable_get(opt.aux)) variable_unset(opt.aux); else variable_set2(opt.aux, "YES"); } if (opt.check) opt.check(opt); clear(); refresh(); } int optionsEditor(char *str) { int i, optcol, optrow, key; static int currOpt = 0; dialog_clear(); clear(); while (1) { /* Whap up the header */ attrset(A_REVERSE); mvaddstr(0, 0, "Options Editor"); attrset(A_NORMAL); for (i = 0; i < 2; i++) { mvaddstr(OPT_START_ROW - 2, OPT_NAME_COL + (i * GROUP_OFFSET), "Name"); mvaddstr(OPT_START_ROW - 1, OPT_NAME_COL + (i * GROUP_OFFSET), "----"); mvaddstr(OPT_START_ROW - 2, OPT_VALUE_COL + (i * GROUP_OFFSET), "Value"); mvaddstr(OPT_START_ROW - 1, OPT_VALUE_COL + (i * GROUP_OFFSET), "-----"); } /* And the footer */ mvprintw(OPT_END_ROW + 0, 0, "Use SPACE to select/toggle an option, arrow keys to move,"); mvprintw(OPT_END_ROW + 1, 0, "? or F1 for more help. When you're done, type Q to Quit."); optrow = OPT_START_ROW; optcol = OPT_NAME_COL; for (i = 0; Options[i].name; i++) { /* Names are painted somewhat gratuitously each time, but it's easier this way */ mvprintw(optrow, OPT_NAME_COL + optcol, Options[i].name); if (currOpt == i) standout(); mvprintw(optrow++, OPT_VALUE_COL + optcol, value_of(Options[i])); if (currOpt == i) standend(); if (optrow == OPT_END_ROW) { optrow = OPT_START_ROW; optcol += GROUP_OFFSET; } clrtoeol(); } standout(); mvaddstr(OPT_END_ROW + 3, 0, Options[currOpt].desc); standend(); clrtoeol(); move(0, 14); /* Start the edit loop */ key = toupper(getch()); switch (key) { case KEY_F(1): case '?': systemDisplayHelp("options"); break; case KEY_UP: if (currOpt) --currOpt; else beep(); continue; case KEY_DOWN: if (Options[currOpt + 1].name) ++currOpt; else beep(); continue; case KEY_HOME: currOpt = 0; continue; case KEY_END: while (Options[currOpt + 1].name) ++currOpt; continue; case ' ': dialog_clear(); fire(Options[currOpt]); dialog_clear(); clear(); continue; case 'Q': clear(); dialog_clear(); return RET_SUCCESS; default: beep(); } } /* NOTREACHED */ return RET_SUCCESS; } diff --git a/usr.sbin/sysinstall/package.c b/usr.sbin/sysinstall/package.c index f72813a3f0bc..c2eb28590f67 100644 --- a/usr.sbin/sysinstall/package.c +++ b/usr.sbin/sysinstall/package.c @@ -1,200 +1,200 @@ /* * The new sysinstall program. * * This is probably the last program in the `sysinstall' line - the next * generation being essentially a complete rewrite. * - * $Id: package.c,v 1.7 1995/10/20 22:36:06 jkh Exp $ + * $Id: package.c,v 1.8 1995/10/21 20:03:07 jkh Exp $ * * Copyright (c) 1995 * Jordan Hubbard. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * verbatim and that no modifications are made prior to this * point in the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Jordan Hubbard * for the FreeBSD Project. * 4. The name of Jordan Hubbard or the FreeBSD project may not be used to * endorse or promote products derived from this software without specific * prior written permission. * * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include #include #include #include #include #include #include #include "sysinstall.h" static char *make_playpen(char *pen, size_t sz); /* Extract a package based on a namespec and a media device */ int package_extract(Device *dev, char *name) { char path[511]; char pen[FILENAME_MAX]; char *where; int i, fd, ret; /* Check to make sure it's not already there */ if (!vsystem("pkg_info -e %s", name)) return RET_SUCCESS; if (!dev->init(dev)) { msgConfirm("Unable to initialize media type for package add."); return RET_FAIL; } ret = RET_FAIL; sprintf(path, "packages/All/%s%s", name, strstr(name, ".tgz") ? "" : ".tgz"); msgDebug("pkg_extract: Attempting to fetch %s\n", path); fd = dev->get(dev, path, TRUE); if (fd >= 0) { pid_t tpid; msgNotify("Fetching %s from %s", path, dev->name); pen[0] = '\0'; if ((where = make_playpen(pen, 0)) != NULL) { if (isDebug()) msgDebug("Working in temporary directory %s, will return to %s\n", pen, where); tpid = fork(); if (!tpid) { dup2(fd, 0); - i = vsystem("tar %s-xzf -", !strcmp(variable_get(CPIO_VERBOSITY_LEVEL), "high") ? "-v " : ""); + i = vsystem("tar %s-xzf -", !strcmp(variable_get(VAR_CPIO_VERBOSITY), "high") ? "-v " : ""); if (isDebug()) msgDebug("tar command returns %d status\n", i); exit(i); } else { int pstat; tpid = waitpid(tpid, &pstat, 0); if (vsystem("(pwd; cat +CONTENTS) | pkg_add %s-S", - !strcmp(variable_get(CPIO_VERBOSITY_LEVEL), "high") ? "-v " : "")) + !strcmp(variable_get(VAR_CPIO_VERBOSITY), "high") ? "-v " : "")) msgConfirm("An error occurred while trying to pkg_add %s.\n" "Please check debugging screen for possible further details.", path); else ret = RET_SUCCESS; close(fd); } if (chdir(where) == -1) msgFatal("Unable to get back to where I was before, Jojo! (That was: %s)", where); vsystem("rm -rf %s", pen); if (isDebug()) msgDebug("Nuked pen: %s\n", pen); } else msgConfirm("Unable to find a temporary location to unpack this stuff in.\n" "You must simply not have enough space or you've configured your\n" "system oddly. Sorry!"); dev->close(dev, fd); if (dev->type == DEVICE_TYPE_TAPE) unlink(path); } else msgDebug("pkg_extract: get operation returned %d\n", fd); return ret; } static size_t min_free(char *tmpdir) { struct statfs buf; if (statfs(tmpdir, &buf) != 0) { msgDebug("Error in statfs, errno = %d\n", errno); return -1; } return buf.f_bavail * buf.f_bsize; } /* Find a good place to play. */ static char * find_play_pen(char *pen, size_t sz) { struct stat sb; if (pen[0] && stat(pen, &sb) != RET_FAIL && (min_free(pen) >= sz)) return pen; else if (stat("/var/tmp", &sb) != RET_FAIL && min_free("/var/tmp") >= sz) strcpy(pen, "/var/tmp/instmp.XXXXXX"); else if (stat("/tmp", &sb) != RET_FAIL && min_free("/tmp") >= sz) strcpy(pen, "/tmp/instmp.XXXXXX"); else if ((stat("/usr/tmp", &sb) == RET_SUCCESS || mkdir("/usr/tmp", 01777) == RET_SUCCESS) && min_free("/usr/tmp") >= sz) strcpy(pen, "/usr/tmp/instmp.XXXXXX"); else { msgConfirm("Can't find enough temporary space to extract the files, please try\n" "This again after your system is up (you can run /stand/sysinstall\n" "directly) and you've had a chance to point /var/tmp somewhere with\n" "sufficient temporary space available."); return NULL; } return pen; } /* * Make a temporary directory to play in and chdir() to it, returning * pathname of previous working directory. */ static char * make_playpen(char *pen, size_t sz) { static char Previous[FILENAME_MAX]; if (!find_play_pen(pen, sz)) return NULL; if (!mktemp(pen)) { msgConfirm("Can't mktemp '%s'.", pen); return NULL; } if (mkdir(pen, 0755) == RET_FAIL) { msgConfirm("Can't mkdir '%s'.", pen); return NULL; } if (isDebug()) { if (sz) msgDebug("Requested space: %d bytes, free space: %d bytes in %s\n", (int)sz, min_free(pen), pen); } if (min_free(pen) < sz) { rmdir(pen); msgConfirm("Not enough free space to create: `%s'\n" "Please try this again after your system is up (you can run\n" "/stand/sysinstall directly) and you've had a chance to point\n" "/var/tmp somewhere with sufficient temporary space available."); return NULL; } if (!getcwd(Previous, FILENAME_MAX)) { msgConfirm("getcwd"); return NULL; } if (chdir(pen) == RET_FAIL) msgConfirm("Can't chdir to '%s'.", pen); return Previous; }