summaryrefslogtreecommitdiffstats
path: root/usr.sbin/sysinstall/config.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/sysinstall/config.c')
-rw-r--r--usr.sbin/sysinstall/config.c361
1 files changed, 257 insertions, 104 deletions
diff --git a/usr.sbin/sysinstall/config.c b/usr.sbin/sysinstall/config.c
index 75f0f9c..e49b574 100644
--- a/usr.sbin/sysinstall/config.c
+++ b/usr.sbin/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;
}
OpenPOWER on IntegriCloud