From 93449d4bbb2c58fc81396a2fffff36d3a89f2fdc Mon Sep 17 00:00:00 2001 From: Gary Palmer Date: Sat, 20 May 1995 18:38:39 +0000 Subject: [PATCH] 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 :-( --- release/sysinstall/media_strategy.c | 252 +++++++++++++++++++++++++--- 1 file changed, 228 insertions(+), 24 deletions(-) diff --git a/release/sysinstall/media_strategy.c b/release/sysinstall/media_strategy.c index b603a217df3..bd923b6ed36 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 #include #include +#include #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) { - return 0; + 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) +{ + 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; } @@ -134,24 +339,6 @@ mediaCloseFloppy(Device *dev) return; } -Boolean -mediaInitDOS(Device *dev) -{ - return TRUE; -} - -Boolean -mediaGetDOS(char *dist) -{ - return TRUE; -} - -void -mediaCloseDOS(Device *dev) -{ - return; -} - Boolean mediaInitTape(Device *dev) { @@ -201,3 +388,20 @@ mediaGetUFS(char *dist) /* UFS has no close routine since this is handled at the device level */ + +Boolean +mediaInitDOS(Device *dev) +{ + return TRUE; +} + +Boolean +mediaGetDOS(char *dist) +{ + return TRUE; +} + +void +mediaCloseDOS(Device *dev) +{ +}