summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgpalmer <gpalmer@FreeBSD.org>1995-05-20 18:38:39 +0000
committergpalmer <gpalmer@FreeBSD.org>1995-05-20 18:38:39 +0000
commit51b03e481e6d60acb3d707ec823c559b74dd6aba (patch)
tree18fe56df1a842a05650660c47d6020e7fb4299d3
parent35f00efaaa39994e78164b0682091943c0b84286 (diff)
downloadFreeBSD-src-51b03e481e6d60acb3d707ec823c559b74dd6aba.zip
FreeBSD-src-51b03e481e6d60acb3d707ec823c559b74dd6aba.tar.gz
Bring in my latest changes. The CDROM strategy should now work, and a
(hopefully) generic fs extraction system is in place. Now the other methods :-(
-rw-r--r--release/sysinstall/media_strategy.c250
1 files changed, 227 insertions, 23 deletions
diff --git a/release/sysinstall/media_strategy.c b/release/sysinstall/media_strategy.c
index b603a21..bd923b6 100644
--- a/release/sysinstall/media_strategy.c
+++ b/release/sysinstall/media_strategy.c
@@ -4,7 +4,7 @@
* This is probably the last attempt in the `sysinstall' line, the next
* generation being slated to essentially a complete rewrite.
*
- * $Id: media_strategy.c,v 1.2 1995/05/20 03:49:09 gpalmer Exp $
+ * $Id: media_strategy.c,v 1.1 1995/05/17 14:39:53 jkh Exp $
*
* Copyright (c) 1995
* Jordan Hubbard. All rights reserved.
@@ -51,6 +51,7 @@
#include <sys/wait.h>
#include <sys/param.h>
#include <sys/dkbad.h>
+#include <sys/mman.h>
#define MSDOSFS
#define CD9660
@@ -60,10 +61,198 @@
#undef CD9660
#undef NFS
-int
-genericGetDist(char *dist, char *source)
+#define MAX_ATTRIBS 20
+#define MAX_NAME 511
+#define MAX_VALUE 4095
+
+struct attribs {
+ char *name;
+ char *value;
+};
+
+static int lno;
+static int num_attribs;
+
+static int
+attr_parse(struct attribs **attr, char *file)
+{
+ char hold_n[MAX_NAME+1];
+ char hold_v[MAX_VALUE+1];
+ int n, v, ch = 0;
+ enum { LOOK, COMMENT, NAME, VALUE, COMMIT } state;
+ FILE *fp;
+
+ num_attribs = n = v = lno = 0;
+ state = LOOK;
+
+ if ((fp=fopen(file, "r")) == NULL)
+ {
+ msgFatal("Cannot open the information file `%s': %s (%d)", file, strerror(errno), errno);
+ return 0;
+ }
+
+ while (state == COMMIT || (ch = fgetc(fp)) != EOF) {
+ /* Count lines */
+ if (ch == '\n')
+ ++lno;
+ switch(state) {
+ case LOOK:
+ if (isspace(ch))
+ continue;
+ /* Allow shell or lisp style comments */
+ else if (ch == '#' || ch == ';') {
+ state = COMMENT;
+ continue;
+ }
+ else if (isalpha(ch)) {
+ hold_n[n++] = ch;
+ state = NAME;
+ }
+ else {
+ msgConfirm("Invalid character '%c' at line %d\n", ch, lno);
+ return 0;
+ }
+ break;
+
+ case COMMENT:
+ if (ch == '\n')
+ state = LOOK;
+ break;
+
+ case NAME:
+ if (ch == '\n') {
+ hold_n[n] = '\0';
+ hold_v[v = 0] = '\0';
+ state = COMMIT;
+ }
+ else if (isspace(ch))
+ continue;
+ else if (ch == '=') {
+ hold_n[n] = '\0';
+ state = VALUE;
+ }
+ else
+ hold_n[n++] = ch;
+ break;
+
+ case VALUE:
+ if (v == 0 && isspace(ch))
+ continue;
+ else if (ch == '{') {
+ /* multiline value */
+ while ((ch = fgetc(fp)) != '}') {
+ if (ch == EOF) {
+ msgConfirm("Unexpected EOF on line %d", lno);
+ return 0;
+ }
+ else {
+ if (v == MAX_VALUE) {
+ msgConfirm("Value length overflow at line %d",
+ lno);
+ return 0;
+ }
+ hold_v[v++] = ch;
+ }
+ }
+ hold_v[v] = '\0';
+ state = COMMIT;
+ }
+ else if (ch == '\n') {
+ hold_v[v] = '\0';
+ state = COMMIT;
+ }
+ else {
+ if (v == MAX_VALUE) {
+ msgConfirm("Value length overflow at line %d", lno);
+ return 0;
+ }
+ else
+ hold_v[v++] = ch;
+ }
+ break;
+
+ case COMMIT:
+ attr[num_attribs]->name = strdup(hold_n);
+ attr[num_attribs++]->value = strdup(hold_v);
+ state = LOOK;
+ v = n = 0;
+ break;
+
+ default:
+ msgConfirm("Unknown state at line %d??\n", lno);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static const char *
+attr_match(struct attribs *attr, char *name)
{
- return 0;
+ int n = 0;
+
+ while((strcmp(attr[n].name, name)!=0) && (n < num_attribs))
+ n++;
+
+ if (strcmp(attr[n].name, name))
+ return((const char *) attr[n].value);
+ return NULL;
+}
+
+static int
+genericGetDist(char *path, struct attribs *dist_attrib)
+{
+ int fd;
+ char buf[512];
+ struct stat sb;
+ int pfd[2], pid, numchunks;
+
+ snprintf(buf, 512, "%s.tgz", path);
+
+ if (stat(buf, &sb) == 0)
+ {
+ fd = open(buf, O_RDONLY, 0);
+ return(fd);
+ }
+
+ snprintf(buf, 512, "%s.aa", path);
+ if (stat(buf, &sb) != 0)
+ {
+ msgConfirm("Cannot find file(s) for distribution in ``%s''!\n", path);
+ return 0;
+ }
+
+ numchunks = atoi(attr_match(dist_attrib, "pieces"));
+ pipe(pfd);
+ pid = fork();
+ if (!pid)
+ {
+ caddr_t memory;
+ int chunk = 0;
+
+ dup2(pfd[1], 1); close(pfd[1]);
+ close(pfd[0]);
+
+ while (chunk < numchunks)
+ {
+ int fd;
+
+ snprintf(buf, 512, "%s.%c%c", path, (chunk / 26), (chunk % 26));
+ if ((fd = open(buf, O_RDONLY)) == NULL)
+ msgFatal("Cannot find file `%s'!\n", buf);
+
+ fstat(fd, &sb);
+ memory = mmap(0, sb.st_size, PROT_READ, MAP_SHARED, fd, (off_t) 0);
+ if (memory == (caddr_t) -1)
+ msgFatal("mmap error: %s\n", strerror(errno));
+
+ write(1, memory, sb.st_size);
+ munmap(memory, sb.st_size);
+ ++chunk;
+ }
+ }
+ close(pfd[1]);
+ return(pfd[0]);
}
/* Various media "strategy" routines */
@@ -100,19 +289,35 @@ Is this a 2.0.5 CDROM?\n");
return FALSE;
}
}
-
return TRUE;
}
Boolean
mediaGetCDROM(char *dist)
{
- return TRUE;
+ char buf[PATH_MAX];
+ struct attribs *dist_attr;
+
+ dist_attr = safe_malloc(sizeof(struct attribs) * MAX_ATTRIBS);
+
+ snprintf(buf, PATH_MAX, "/mnt/stand/info/%s.inf", dist);
+ if (attr_parse(&dist_attr, buf) == 0)
+ {
+ msgConfirm("Cannot load information file for distribution\n");
+ return FALSE;
+ }
+
+ snprintf(buf, PATH_MAX, "/mnt/cdrom/%s", dist);
+
+ return genericGetDist(buf, dist_attr);
}
void
mediaCloseCDROM(Device *dev)
{
+ if (unmount("/mnt/cdrom", 0) != 0)
+ msgConfirm("Could not unmount the CDROM: %s\n", strerror(errno));
+
return;
}
@@ -135,69 +340,68 @@ mediaCloseFloppy(Device *dev)
}
Boolean
-mediaInitDOS(Device *dev)
+mediaInitTape(Device *dev)
{
return TRUE;
}
Boolean
-mediaGetDOS(char *dist)
+mediaGetTape(char *dist)
{
return TRUE;
}
void
-mediaCloseDOS(Device *dev)
+mediaCloseTape(Device *dev)
{
return;
}
Boolean
-mediaInitTape(Device *dev)
+mediaInitNetwork(Device *dev)
{
return TRUE;
}
Boolean
-mediaGetTape(char *dist)
+mediaGetNetwork(char *dist)
{
return TRUE;
}
void
-mediaCloseTape(Device *dev)
+mediaCloseNetwork(Device *dev)
{
- return;
}
Boolean
-mediaInitNetwork(Device *dev)
+mediaInitUFS(Device *dev)
{
return TRUE;
}
Boolean
-mediaGetNetwork(char *dist)
+mediaGetUFS(char *dist)
{
return TRUE;
}
-void
-mediaCloseNetwork(Device *dev)
-{
-}
+/* UFS has no close routine since this is handled at the device level */
+
Boolean
-mediaInitUFS(Device *dev)
+mediaInitDOS(Device *dev)
{
return TRUE;
}
Boolean
-mediaGetUFS(char *dist)
+mediaGetDOS(char *dist)
{
return TRUE;
}
-/* UFS has no close routine since this is handled at the device level */
-
+void
+mediaCloseDOS(Device *dev)
+{
+}
OpenPOWER on IntegriCloud