~kris/9p

9hist

4936e5afeff3ff98af43fb8aa154703b13cea987 — David du Colombier 29 years ago fe24661
Plan 9 from Bell Labs 1997-09-10
2 files changed, 147 insertions(+), 13 deletions(-)

M boot/key.c
M pc/devfloppy.c
M boot/key.c => boot/key.c +139 -5
@@ 3,6 3,8 @@
#include <auth.h>
#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;
}

M pc/devfloppy.c => pc/devfloppy.c +8 -8
@@ 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 */