diff options
author | gpalmer <gpalmer@FreeBSD.org> | 1995-05-20 18:38:39 +0000 |
---|---|---|
committer | gpalmer <gpalmer@FreeBSD.org> | 1995-05-20 18:38:39 +0000 |
commit | 51b03e481e6d60acb3d707ec823c559b74dd6aba (patch) | |
tree | 18fe56df1a842a05650660c47d6020e7fb4299d3 | |
parent | 35f00efaaa39994e78164b0682091943c0b84286 (diff) | |
download | FreeBSD-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.c | 250 |
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) +{ +} |