From 4936e5afeff3ff98af43fb8aa154703b13cea987 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 10 Sep 1997 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1997-09-10 --- boot/key.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++-- pc/devfloppy.c | 16 +++--- 2 files changed, 147 insertions(+), 13 deletions(-) diff --git a/boot/key.c b/boot/key.c index 660d157ee260e26e0734acee9b603e98c4098096..3a894adb3feda010944dfbd3c1c00c131ac11799 100644 --- a/boot/key.c +++ b/boot/key.c @@ -3,6 +3,8 @@ #include #include <../boot/boot.h> +static long finddosfile(int, char*); + static void check(void *x, int len, uchar sum, char *msg) { @@ -24,7 +26,6 @@ key(int islocal, Method *mp) char buf[1024]; Nvrsafe *safe; char password[20]; - Dir d; USED(islocal); USED(mp); @@ -42,14 +43,15 @@ key(int islocal, Method *mp) fd = open("#w/sd0nvram", ORDWR); if(fd < 0){ fd = open("#f/fd0disk", ORDWR); + if(fd < 0) + fd = open("#f/fd1disk", ORDWR); if(fd >= 0){ - if(dirfstat(fd, &d) >= 0){ - safeoff = d.length - 512; - safelen = 512; - } else { + safeoff = finddosfile(fd, "plan9.nvr"); + if(safeoff < 0){ close(fd); fd = -1; } + safelen = 512; } } } else { @@ -93,3 +95,135 @@ key(int islocal, Method *mp) if(writefile("#c/hostdomain", safe->authdom, strlen(safe->authdom)) < 0) fatal("#c/hostdomain"); } + +typedef struct Dosboot Dosboot; +struct Dosboot{ + uchar magic[3]; /* really an xx86 JMP instruction */ + uchar version[8]; + uchar sectsize[2]; + uchar clustsize; + uchar nresrv[2]; + uchar nfats; + uchar rootsize[2]; + uchar volsize[2]; + uchar mediadesc; + uchar fatsize[2]; + uchar trksize[2]; + uchar nheads[2]; + uchar nhidden[4]; + uchar bigvolsize[4]; + uchar driveno; + uchar reserved0; + uchar bootsig; + uchar volid[4]; + uchar label[11]; + uchar type[8]; +}; +#define GETSHORT(p) (((p)[1]<<8) | (p)[0]) +#define GETLONG(p) ((GETSHORT((p)+2) << 16) | GETSHORT((p))) + +typedef struct Dosdir Dosdir; +struct Dosdir +{ + char name[8]; + char ext[3]; + uchar attr; + uchar reserved[10]; + uchar time[2]; + uchar date[2]; + uchar start[2]; + uchar length[4]; +}; + +static char* +dosparse(char *from, char *to, int len) +{ + char c; + + memset(to, ' ', len); + if(from == 0) + return 0; + while(len-- > 0){ + c = *from++; + if(c == '.') + return from; + if(c == 0) + break; + if(c >= 'a' && c <= 'z') + *to++ = c + 'A' - 'a'; + else + *to++ = c; + } + return 0; +} + +/* + * return offset of first file block + * + * This is a very simplistic dos file system. It only + * works on floppies, only looks in the root, and only + * returns a pointer to the first block of a file. + * + * This exists for cpu servers that have no hard disk + * or nvram to store the key on. + * + * Please don't make this any smarter: it stays resident + * and I'ld prefer not to waste the space on something that + * runs only at boottime -- presotto. + */ +static long +finddosfile(int fd, char *file) +{ + uchar secbuf[512]; + char name[8]; + char ext[3]; + Dosboot *b; + Dosdir *root, *dp; + int nroot, sectsize, rootoff, rootsects, n; + + /* dos'ize file name */ + file = dosparse(file, name, 8); + dosparse(file, ext, 3); + + /* read boot block, check for sanity */ + b = (Dosboot*)secbuf; + if(read(fd, secbuf, sizeof(secbuf)) != sizeof(secbuf)) + return -1; + if(b->magic[0] != 0xEB || b->magic[1] != 0x3C || b->magic[2] != 0x90) + return -1; + sectsize = GETSHORT(b->sectsize); + if(sectsize != 512) + return -1; + rootoff = (1 + b->nfats*GETSHORT(b->fatsize)) * sectsize; + if(seek(fd, rootoff, 0) < 0) + return -1; + nroot = GETSHORT(b->rootsize); + rootsects = (nroot*sizeof(Dosdir)+sectsize-1)/sectsize; + if(rootsects <= 0 || rootsects > 20) + return -1; + + /* + * read root. it is contiguous to make stuff like + * this easier + */ + root = malloc(rootsects*sectsize); + if(read(fd, root, rootsects*sectsize) != rootsects*sectsize) + return -1; + n = -1; + for(dp = root; dp < &root[nroot]; dp++) + if(memcmp(name, dp->name, 8) == 0 && memcmp(ext, dp->ext, 3) == 0){ + n = GETSHORT(dp->start); + break; + } + free(root); + + if(n < 0) + return -1; + + /* + * dp->start is in cluster units, not sectors. The first + * cluster is cluster 2 which starts immediately after the + * root directory + */ + return rootoff + rootsects*sectsize + (n-2)*sectsize*b->clustsize; +} diff --git a/pc/devfloppy.c b/pc/devfloppy.c index 149ce55f190b3c3e910c47be820c9f9549d0b15f..f39eeaa60d8bec5e691de44590d42d031816d766 100644 --- a/pc/devfloppy.c +++ b/pc/devfloppy.c @@ -104,14 +104,14 @@ static void floppywait(void); static long floppyxfer(FDrive*, int, void*, long, long); Dirtab floppydir[]={ - "fd0disk", {Qdata + 0}, 0, 0666, - "fd0ctl", {Qctl + 0}, 0, 0666, - "fd1disk", {Qdata + 1}, 0, 0666, - "fd1ctl", {Qctl + 1}, 0, 0666, - "fd2disk", {Qdata + 2}, 0, 0666, - "fd2ctl", {Qctl + 2}, 0, 0666, - "fd3disk", {Qdata + 3}, 0, 0666, - "fd3ctl", {Qctl + 3}, 0, 0666, + "fd0disk", {Qdata + 0}, 0, 0660, + "fd0ctl", {Qctl + 0}, 0, 0660, + "fd1disk", {Qdata + 1}, 0, 0660, + "fd1ctl", {Qctl + 1}, 0, 0660, + "fd2disk", {Qdata + 2}, 0, 0660, + "fd2ctl", {Qctl + 2}, 0, 0660, + "fd3disk", {Qdata + 3}, 0, 0660, + "fd3ctl", {Qctl + 3}, 0, 0660, }; #define NFDIR 2 /* directory entries/drive */