diff options
Diffstat (limited to 'release/sysinstall/config.c')
-rw-r--r-- | release/sysinstall/config.c | 361 |
1 files changed, 257 insertions, 104 deletions
diff --git a/release/sysinstall/config.c b/release/sysinstall/config.c index 75f0f9c..e49b574 100644 --- a/release/sysinstall/config.c +++ b/release/sysinstall/config.c @@ -4,7 +4,7 @@ * This is probably the last program in the `sysinstall' line - the next * generation being essentially a complete rewrite. * - * $Id: config.c,v 1.16.2.2 1995/07/21 11:45:36 rgrimes Exp $ + * $Id: config.c,v 1.17 1995/09/18 16:52:22 peter Exp $ * * Copyright (c) 1995 * Jordan Hubbard. All rights reserved. @@ -50,34 +50,53 @@ static int nchunks; /* arg to sort */ static int -chunk_compare(const void *p1, const void *p2) +chunk_compare(Chunk *c1, Chunk *c2) { - Chunk *c1, *c2; - - c1 = (Chunk *)p1; - c2 = (Chunk *)p2; - if (!c1->private && !c2->private) + if (!c1 && !c2) return 0; - else if (c1->private && !c2->private) + else if (!c1 && c2) + return 1; + else if (c1 && !c2) return -1; - else if (!c1->private && c2->private) + else if (!c1->private && !c2->private) + return 0; + else if (c1->private && !c2->private) return 1; + else if (!c1->private && c2->private) + return -1; else - return strcmp(((PartInfo *)c1->private)->mountpoint, ((PartInfo *)c2->private)->mountpoint); + return strcmp(((PartInfo *)(c1->private))->mountpoint, ((PartInfo *)(c2->private))->mountpoint); +} + +static void +chunk_sort(void) +{ + int i, j; + + for (i = 0; i < nchunks; i++) { + for (j = 0; j < nchunks; j++) { + if (chunk_compare(chunk_list[j], chunk_list[j + 1]) > 0) { + Chunk *tmp = chunk_list[j]; + + chunk_list[j] = chunk_list[j + 1]; + chunk_list[j + 1] = tmp; + } + } + } } static char * -nameof(Chunk *c1) +name_of(Chunk *c1) { - static char rootname[64]; + static char rootname[32]; /* Our boot blocks can't deal with root partitions on slices - need the compatbility name */ if (c1->type == part && c1->flags & CHUNK_IS_ROOT) { - sprintf(rootname, "%sa", c1->disk->name); - return rootname; + sprintf(rootname, "%sa", c1->disk->name); + return rootname; } else - return c1->name; + return c1->name; } static char * @@ -126,7 +145,7 @@ seq_num(Chunk *c1) return 0; } -void +int configFstab(void) { Device **devs; @@ -137,14 +156,20 @@ configFstab(void) if (!RunningAsInit) { if (file_readable("/etc/fstab")) - return; - else - msgConfirm("Attempting to rebuild your /etc/fstab file.\nWarning: If you had any CD devices in use before running\nsysinstall then they may NOT be found in this run!"); + return RET_SUCCESS; + else { + dialog_clear(); + msgConfirm("Attempting to rebuild your /etc/fstab file. Warning: If you had\n" + "any CD devices in use before running sysinstall then they may NOT\n" + "be found by this run!"); + } } + devs = deviceFind(NULL, DEVICE_TYPE_DISK); if (!devs) { + dialog_clear(); msgConfirm("No disks found!"); - return; + return RET_FAIL; } /* Record all the chunks */ @@ -166,20 +191,21 @@ configFstab(void) chunk_list[nchunks++] = c1; } } - - /* Sort them puppies! */ - qsort(chunk_list, nchunks, sizeof(Chunk *), chunk_compare); + chunk_list[nchunks] = 0; + chunk_sort(); fstab = fopen("/etc/fstab", "w"); if (!fstab) { - msgConfirm("Unable to create a new /etc/fstab file!\nManual intervention will be required."); - return; + dialog_clear(); + msgConfirm("Unable to create a new /etc/fstab file! Manual intervention\n" + "will be required."); + return RET_FAIL; } /* Go for the burn */ msgDebug("Generating /etc/fstab file\n"); for (i = 0; i < nchunks; i++) - fprintf(fstab, "/dev/%s\t\t\t%s\t\t%s\t%s %d %d\n", nameof(chunk_list[i]), mount_point(chunk_list[i]), + fprintf(fstab, "/dev/%s\t\t\t%s\t\t%s\t%s %d %d\n", name_of(chunk_list[i]), mount_point(chunk_list[i]), fstype(chunk_list[i]), fstype_short(chunk_list[i]), seq_num(chunk_list[i]), seq_num(chunk_list[i])); Mkdir("/proc", NULL); fprintf(fstab, "proc\t\t\t\t/proc\t\tprocfs\trw 0 0\n"); @@ -190,8 +216,12 @@ configFstab(void) /* Write the first one out as /cdrom */ if (cnt) { - Mkdir("/cdrom", NULL); - fprintf(fstab, "/dev/%s\t\t\t/cdrom\t\tcd9660\tro 0 0\n", devs[0]->name); + if (Mkdir("/cdrom", NULL)) { + dialog_clear(); + msgConfirm("Unable to make mount point for: /cdrom"); + } + else + fprintf(fstab, "/dev/%s\t\t\t/cdrom\t\tcd9660\tro,noauto 0 0\n", devs[0]->name); } /* Write the others out as /cdrom<n> */ @@ -199,185 +229,308 @@ configFstab(void) char cdname[10]; sprintf(cdname, "/cdrom%d", i); - Mkdir(cdname, NULL); - fprintf(fstab, "/dev/%s\t\t\t%s\t\tcd9660\tro 0 0\n", devs[i]->name, cdname); + if (Mkdir(cdname, NULL)) { + dialog_clear(); + msgConfirm("Unable to make mount point for: %s", cdname); + } + else + fprintf(fstab, "/dev/%s\t\t\t%s\t\tcd9660\tro,noauto 0 0\n", devs[i]->name, cdname); } fclose(fstab); if (isDebug()) msgDebug("Wrote out /etc/fstab file\n"); + return RET_SUCCESS; } /* * This sucks in /etc/sysconfig, substitutes anything needing substitution, then * writes it all back out. It's pretty gross and needs re-writing at some point. */ + +#define MAX_LINES 2000 /* Some big number we're not likely to ever reach - I'm being really lazy here, I know */ void configSysconfig(void) { FILE *fp; - char *lines[5001]; /* Some big number we're not likely to ever reach - I'm being really lazy here, I know */ + char *lines[MAX_LINES], *cp; char line[256]; Variable *v; - int i, nlines = 0; + int i, nlines; fp = fopen("/etc/sysconfig", "r"); if (!fp) { - msgConfirm("Unable to open /etc/sysconfig file! Things may work\nrather strangely as a result of this."); + dialog_clear(); + msgConfirm("Unable to open /etc/sysconfig file! Things may work\n" + "rather strangely as a result of this."); return; } - for (i = 0; i < 5000; i++) { + msgNotify("Writing configuration changes to /etc/sysconfig file.."); + + nlines = 0; + /* Read in the entire file */ + for (i = 0; i < MAX_LINES; i++) { if (!fgets(line, 255, fp)) break; lines[nlines++] = strdup(line); } - lines[nlines] = NULL; - fclose(fp); + msgDebug("Read %d lines from sysconfig.\n", nlines); + /* Now do variable substitutions */ for (v = VarHead; v; v = v->next) { for (i = 0; i < nlines; i++) { - char modify[256], *cp; + char tmp[256]; - if (lines[i][0] == '#' || lines[i][0] == ';') + /* Skip the comments */ + if (lines[i][0] == '#') continue; - strncpy(modify, lines[i], 255); - cp = index(modify, '='); + strcpy(tmp, lines[i]); + cp = index(tmp, '='); if (!cp) continue; *(cp++) = '\0'; - if (!strcmp(modify, v->name)) { + if (!strcmp(tmp, v->name)) { free(lines[i]); - lines[i] = (char *)malloc(strlen(v->name) + strlen(v->value) + 3); + lines[i] = (char *)malloc(strlen(v->name) + strlen(v->value) + 5); sprintf(lines[i], "%s=\"%s\"\n", v->name, v->value); + msgDebug("Variable substitution on: %s\n", lines[i]); } - } } + + /* Now write it all back out again */ + fclose(fp); fp = fopen("/etc/sysconfig", "w"); - if (!fp) { - msgConfirm("Unable to re-write /etc/sysconfig file! Things may work\nrather strangely as a result of this."); - return; - } for (i = 0; i < nlines; i++) { - fprintf(fp, lines[i]); - free(lines[i]); + static Boolean firstTime = TRUE; + fprintf(fp, lines[i]); /* Stand by for bogus special case handling - we try to dump the interface specs here */ - if (!strncmp(lines[i], VAR_INTERFACES, strlen(VAR_INTERFACES))) { + if (firstTime && !strncmp(lines[i], VAR_INTERFACES, strlen(VAR_INTERFACES))) { Device **devp; int j, cnt; devp = deviceFind(NULL, DEVICE_TYPE_NETWORK); cnt = deviceCount(devp); for (j = 0; j < cnt; j++) { - if (devp[j]->private && strncmp(devp[j]->name, "cuaa", 4)) { - char iname[64]; + char iname[255]; - snprintf(iname, 64, "%s%s", VAR_IFCONFIG, devp[j]->name); - if (getenv(iname)) - fprintf(fp, "%s=\"%s\"\n", iname, getenv(iname)); + snprintf(iname, 255, "%s%s", VAR_IFCONFIG, devp[j]->name); + if ((cp = variable_get(iname))) { + fprintf(fp, "%s=\"%s\"\n", iname, cp); } } + firstTime = FALSE; } + free(lines[i]); } fclose(fp); - - /* If we're an NFS server, we need an exports file */ - if (getenv("nfs_server") && !file_readable("/etc/exports")) { - msgConfirm("You have chosen to be an NFS server but have not yet configured\nthe /etc/exports file. The format for an exports entry is:\n <mountpoint> <opts> <host [..host]>\nWhere <mounpoint> is the name of a filesystem as specified\nin the Label editor, <opts> is a list of special options we\nwon't concern ourselves with here (``man exports'' when the\nsystem is fully installed) and <host> is one or more host\nnames who are allowed to mount this file system. Press\n[ENTER] now to invoke the editor on /etc/exports"); - systemExecute("vi /etc/exports"); - } } int configSaverTimeout(char *str) { - char *val; - - val = msgGetInput("60", "Enter time-out period in seconds for screen saver"); - if (val) - variable_set2("blanktime", val); - return 0; + return variable_get_value(VAR_BLANKTIME, "Enter time-out period in seconds for screen saver") + ? RET_SUCCESS : RET_FAIL; } int configNTP(char *str) { - char *val; - - val = msgGetInput(NULL, "Enter the name of an NTP server"); - if (val) - variable_set2("ntpdate", val); - return 0; + return variable_get_value(VAR_NTPDATE, "Enter the name of an NTP server") ? RET_SUCCESS : RET_FAIL; } void configResolv(void) { FILE *fp; - char *cp; + char *cp, *dp, *hp; if (!RunningAsInit && file_readable("/etc/resolv.conf")) return; - if (!getenv(VAR_NAMESERVER)) { - if (mediaDevice && (mediaDevice->type == DEVICE_TYPE_NFS || mediaDevice->type == DEVICE_TYPE_FTP)) - msgConfirm("Warning: Missing name server value - network operations\nmay fail as a result!"); + if (!variable_get(VAR_NAMESERVER)) { + if (mediaDevice && (mediaDevice->type == DEVICE_TYPE_NFS || mediaDevice->type == DEVICE_TYPE_FTP)) { + dialog_clear(); + msgConfirm("Warning: Missing name server value - network operations\n" + "may fail as a result!"); + } goto skip; } - Mkdir("/etc", NULL); + if (Mkdir("/etc", NULL)) { + dialog_clear(); + msgConfirm("Unable to create /etc directory. Network configuration\n" + "files will therefore not be written!"); + return; + } fp = fopen("/etc/resolv.conf", "w"); if (!fp) { + dialog_clear(); msgConfirm("Unable to open /etc/resolv.conf! You will need to do this manually."); return; } - if (getenv(VAR_DOMAINNAME)) - fprintf(fp, "domain\t%s\n", getenv(VAR_DOMAINNAME)); - fprintf(fp, "nameserver\t%s\n", getenv(VAR_NAMESERVER)); + if (variable_get(VAR_DOMAINNAME)) + fprintf(fp, "domain\t%s\n", variable_get(VAR_DOMAINNAME)); + fprintf(fp, "nameserver\t%s\n", variable_get(VAR_NAMESERVER)); fclose(fp); if (isDebug()) msgDebug("Wrote out /etc/resolv.conf\n"); skip: - /* Tack ourselves at the end of /etc/hosts */ - cp = getenv(VAR_IPADDR); - if (cp && *cp != '0' && getenv(VAR_HOSTNAME)) { - fp = fopen("/etc/hosts", "a"); - fprintf(fp, "%s\t\t%s\n", cp, getenv(VAR_HOSTNAME)); + /* Tack ourselves into /etc/hosts */ + cp = variable_get(VAR_IPADDR); + dp = variable_get(VAR_DOMAINNAME); + if (cp && *cp != '0' && (hp = variable_get(VAR_HOSTNAME))) { + char cp2[255]; + + (void)vsystem("hostname %s", hp); + fp = fopen("/etc/hosts", "w"); + if (!index(hp, '.')) + cp2[0] = '\0'; + else { + strcpy(cp2, hp); + *(index(cp2, '.')) = '\0'; + } + fprintf(fp, "127.0.0.1\t\tlocalhost.%s localhost\n", dp ? dp : "my.domain"); + fprintf(fp, "%s\t\t%s %s\n", cp, hp, cp2); fclose(fp); if (isDebug()) - msgDebug("Appended entry for %s to /etc/hosts\n", cp); + msgDebug("Wrote entry for %s to /etc/hosts\n", cp); } } int configRoutedFlags(char *str) { - char *val; - - val = msgGetInput("-q", "Specify the flags for routed; -q is the default, -s is\na good choice for gateway machines."); - if (val) - variable_set2("routedflags", val); - return 0; + return variable_get_value(VAR_ROUTEDFLAGS, + "Specify the flags for routed; -q is the default, -s is\n" + "a good choice for gateway machines.") ? RET_SUCCESS : RET_FAIL; } int configPackages(char *str) { - Boolean onCD; - - /* If we're running as init, we know that a CD in the drive is probably ours */ - onCD = file_readable("/cdrom/packages"); - if (!onCD && RunningAsInit) { - if (mediaSetCDROM(NULL)) { - if ((*mediaDevice->init)(mediaDevice)) - onCD = TRUE; + PkgNode top, plist; + int fd; + + if (!mediaVerify()) + return RET_FAIL; + + if (!mediaDevice->init(mediaDevice)) + return RET_FAIL; + + msgNotify("Attempting to fetch packages/INDEX file from selected media."); + fd = mediaDevice->get(mediaDevice, "packages/INDEX", TRUE); + if (fd < 0) { + dialog_clear(); + msgConfirm("Unable to get packages/INDEX file from selected media.\n" + "This may be because the packages collection is not available at\n" + "on the distribution media you've chosen (most likely an FTP site\n" + "without the packages collection mirrored). Please verify media\n" + "(or path to media) and try again. If your local site does not\n" + "carry the packages collection, then we recommend either a CD\n" + "distribution or the master distribution on ftp.freebsd.org."); + return RET_FAIL; + } + msgNotify("Got INDEX successfully, now building packages menu.."); + index_init(&top, &plist); + if (index_read(fd, &top)) { + dialog_clear(); + msgConfirm("I/O or format error on packages/INDEX file.\n" + "Please verify media (or path to media) and try again."); + mediaDevice->close(mediaDevice, fd); + return RET_FAIL; + } + mediaDevice->close(mediaDevice, fd); + index_sort(&top); + while (1) { + int ret, pos, scroll; + + /* Bring up the packages menu */ + pos = scroll = 0; + index_menu(&top, &plist, &pos, &scroll); + + if (plist.kids) { + /* Now show the packing list menu */ + pos = scroll = 0; + ret = index_menu(&plist, NULL, &pos, &scroll); + if (ret == RET_DONE) + break; + else if (ret != RET_FAIL) { + index_extract(mediaDevice, &plist); + break; + } + } + else { + dialog_clear(); + msgConfirm("No packages were selected for extraction."); + break; } } - /* XXX Construct some sort of menu here using an INDEX file from /cdrom/packages XXX */ - return 0; + index_node_free(&top, &plist); + mediaDevice->shutdown(mediaDevice); + return RET_SUCCESS; } int configPorts(char *str) { - return 0; + char *cp, *dist = NULL; /* Shut up compiler */ + + if (!variable_get(VAR_PORTS_PATH)) + variable_set2(VAR_PORTS_PATH, dist = "/cdrom/ports"); + while (!directoryExists(dist)) { + dist = variable_get_value(VAR_PORTS_PATH, + "Unable to locate a ports tree on CDROM. Please specify the\n" + "location of the master ports directory you wish to create the\n" + "link tree to."); + if (!dist) + break; + } + if (dist) { + cp = msgGetInput("/usr/ports", + "Where would you like to create the link tree?\n" + "(press [ENTER] for default location). The link tree should\n" + "reside in a directory with as much free space as possible,\n" + "as you'll need space to compile any ports."); + if (!cp || !*cp) + return RET_FAIL; + if (Mkdir(cp, NULL)) { + dialog_clear(); + msgConfirm("Unable to make the %s directory!", cp); + return RET_FAIL; + } + else { + if (strcmp(cp, "/usr/ports")) { + unlink("/usr/ports"); + if (symlink(cp, "/usr/ports") == -1) { + msgConfirm("Unable to create a symlink from /usr/ports to %s!\n" + "I can't continue, sorry!", cp); + return RET_FAIL; + } + else { + msgConfirm("NOTE: This directory is also now symlinked to /usr/ports\n" + "which, for a variety of reasons, is the directory the ports\n" + "framework expects to find its files in. You should refer to\n" + "/usr/ports instead of %s directly when you're working in the\n" + "ports collection.", cp); + } + } + msgNotify("Making a link tree from %s to %s.", dist, cp); + if (lndir(dist, cp) != RET_SUCCESS) { + dialog_clear(); + msgConfirm("The lndir function returned an error status and may not have.\n" + "successfully generated the link tree. You may wish to inspect\n" + "the /usr/ports directory carefully for any missing link files."); + } + else { + msgConfirm("The /usr/ports directory is now ready to use. When the system comes\n" + "up fully, you can cd to this directory and type `make' in any sub-\n" + "directory for which you'd like to compile a port. You can also\n" + "cd to /usr/ports and type `make print-index' for a complete list of all\n" + "ports in the hierarchy."); + } + } + } + else + return RET_FAIL; + return RET_SUCCESS; } |