1046 lines · 20.2 KB · C
RawDownload
/*  * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #include "all.h"#include "io.h" static void	dowormcopy(void);static int	dodevcopy(void); struct {	char*	icharp;	char*	charp;	int	error;	int	newconf;	/* clear before start */	int	modconf;	/* write back when done */	int	nextiter;	int	lastiter;	int	diriter;	Device*	lastcw;	Device*	devlist;} f; static Device* confdev;static int copyworm = 0, copydev = 0;static char *src, *dest; static int resetparams; Fspar fspar[] = {	{ "blocksize",	RBUFSIZE, },	{ "daddrbits",	sizeof(Off)*8, },	{ "indirblks",	NIBLOCK, },	{ "dirblks",	NDBLOCK, },	{ "namelen",	NAMELEN, },	{ nil, 0, },}; intdevcmpr(Device *d1, Device *d2){	while (d1 != d2) {		if(d1 == nil || d2 == nil || d1->type != d2->type)			return 1; 		switch(d1->type) {		default:			print("can't compare dev: %Z\n", d1);			panic("devcmp");			return 1; 		case Devmcat:		case Devmlev:		case Devmirr:			d1 = d1->cat.first;			d2 = d2->cat.first;			while(d1 && d2) {				if(devcmpr(d1, d2))					return 1;				d1 = d1->link;				d2 = d2->link;			}			break; 		case Devnone:			return 0; 		case Devro:			d1 = d1->ro.parent;			d2 = d2->ro.parent;			break; 		case Devjuke:		case Devcw:			if(devcmpr(d1->cw.c, d2->cw.c))				return 1;			d1 = d1->cw.w;			d2 = d2->cw.w;			break; 		case Devfworm:			d1 = d1->fw.fw;			d2 = d2->fw.fw;			break; 		case Devwren:		case Devworm:		case Devlworm:			if(d1->wren.ctrl == d2->wren.ctrl)			if(d1->wren.targ == d2->wren.targ)			if(d1->wren.lun == d2->wren.lun)				return 0;			return 1; 		case Devpart:			if(d1->part.base == d2->part.base)			if(d1->part.size == d2->part.size) {				d1 = d1->part.d;				d2 = d2->part.d;				break;			}			return 1;		}	}	return 0;} voidcdiag(char *s, int c1){ 	f.charp--;	if(f.error == 0) {		print("config diag: %s -- <%c>\n", s, c1);		f.error = 1;	}} intcnumb(void){	int c, n; 	c = *f.charp++;	if(c == '<') {		n = f.nextiter;		if(n >= 0) {			f.nextiter = n+f.diriter;			if(n == f.lastiter) {				f.nextiter = -1;				f.lastiter = -1;			}			do {				c = *f.charp++;			} while (c != '>');			return n;		}		n = cnumb();		if(*f.charp++ != '-') {			cdiag("- expected", f.charp[-1]);			return 0;		}		c = cnumb();		if(*f.charp++ != '>') {			cdiag("> expected", f.charp[-1]);			return 0;		}		f.lastiter = c;		f.diriter = 1;		if(n > c)			f.diriter = -1;		f.nextiter = n+f.diriter;		return n;	}	if(!isascii(c) || !isdigit(c)) {		cdiag("number expected", c);		return 0;	}	n = 0;	while(isascii(c) && isdigit(c)) {		n = n*10 + (c-'0');		c = *f.charp++;	}	f.charp--;	return n;} Device*config1(int c){	Device *d, *t;	int m; 	d = malloc(sizeof(Device));	do {		t = config();		if(d->cat.first == 0)			d->cat.first = t;		else			d->cat.last->link = t;		d->cat.last = t;		if(f.error)			return devnone;		m = *f.charp;		if(c == '(' && m == ')')			d->type = Devmcat;		else if(c == '[' && m == ']')			d->type = Devmlev;		else if(c == '{' && m == '}')			d->type = Devmirr;	} while (d->type == 0);	f.charp++;	if(d->cat.first == d->cat.last)		d = d->cat.first;	return d;} static voidmap(Device *d){	Map *map; 	if (d->type != Devwren || d->wren.mapped)		return;	for (map = devmap; map != nil; map = map->next)		if (devcmpr(d, map->fdev) == 0)			break;	if (map == nil)		return;	if (access(map->to, AEXIST) >= 0){ print("map: mapped wren %Z to existing file %s\n", d, map->to); // DEBUG		d->wren.file = map->to;		/* wren -> file mapping */}	else if (map->tdev != nil){ print("map: mapped wren %Z to dev %Z\n", d, map->tdev); // DEBUG		*d = *map->tdev;		/* wren -> wren mapping */}	else		print("bad mapping %Z to %s; no such file or device",			d, map->to);	d->wren.mapped = 1;} Device*config(void){	int c, m;	Device *d;	char *icp; 	if(f.error)		return devnone;	d = malloc(sizeof(Device)); 	c = *f.charp++;	switch(c) {	default:		cdiag("unknown type", c);		return devnone; 	case '(':	/* (d+) one or multiple cat */	case '[':	/* [d+] one or multiple interleave */	case '{':	/* {d+} a mirrored device and optional mirrors */		return config1(c); 	case 'f':	/* fd fake worm */		d->type = Devfworm;		d->fw.fw = config();		break; 	case 'n':		d->type = Devnone;		break; 	case 'w':	/* w[#.]#[.#] wren	[ctrl] unit [lun] */	case 'r':	/* r# worm side */	case 'l':	/* l# labelled-worm side */		icp = f.charp;		d->type = Devwren;		d->wren.ctrl = 0;		d->wren.targ = cnumb();		d->wren.lun = 0;		m = *f.charp;		if(m == '.') {			f.charp++;			d->wren.lun = cnumb();			m = *f.charp;			if(m == '.') {				f.charp++;				d->wren.ctrl = d->wren.targ;				d->wren.targ = d->wren.lun;				d->wren.lun = cnumb();			}		}		if(f.nextiter >= 0)			f.charp = icp-1;		if(c == 'r')		/* worms are virtual and not uniqued */			d->type = Devworm;		else if(c == 'l')			d->type = Devlworm;		else			map(d);		/* subject wrens to optional mapping */		break; 	case 'o':	/* o ro part of last cw */		if(f.lastcw == 0) {			cdiag("no cw to match", c);			return devnone;		}		return f.lastcw->cw.ro; 	case 'j':	/* DD jukebox */		d->type = Devjuke;		d->j.j = config();		d->j.m = config();		break; 	case 'c':	/* cache/worm */		d->type = Devcw;		d->cw.c = config();		d->cw.w = config();		d->cw.ro = malloc(sizeof(Device));		d->cw.ro->type = Devro;		d->cw.ro->ro.parent = d;		f.lastcw = d;		break; 	case 'p':	/* pd#.# partition base% size% */		d->type = Devpart;		d->part.d = config();		d->part.base = cnumb();		c = *f.charp++;		if(c != '.')			cdiag("dot expected", c);		d->part.size = cnumb();		break; 	case 'x':	/* xD swab a device's metadata */		d->type = Devswab;		d->swab.d = config();		break;	}	d->dlink = f.devlist;	f.devlist = d;	return d;} Device*iconfig(char *s){	Device *d; 	f.nextiter = -1;	f.lastiter = -1;	f.error = 0;	f.icharp = s;	f.charp = f.icharp;	d = config();	if(*f.charp) {		cdiag("junk on end", *f.charp);		f.error = 1;	}	return d;} inttestconfig(char *s){	iconfig(s);	return f.error;} /* * if b is a prefix of a, return 0. */intastrcmp(char *a, char *b){	int n, c; 	n = strlen(b);	if(memcmp(a, b, n) != 0)		return 1;	c = a[n];	if(c == '\0')		return 0;	if(a[n+1])		return 1;	if(isascii(c) && isdigit(c))		return 0;	return 1;} static Fspar *getpar(char *name){	Fspar *fsp; 	for (fsp = fspar; fsp->name != nil; fsp++)		if (strcmp(name, fsp->name) == 0)			return fsp;	return nil;} /* * continue to parse obsolete keywords so that old configurations can * still work. */voidmergeconf(Iobuf *p){	char word[Maxword+1];	char *cp;	Filsys *fs;	Fspar *fsp; 	for (cp = p->iobuf; *cp != '\0'; cp++) {		cp = getwrd(word, cp);		if(word[0] == '\0')			break;		else if (word[0] == '#')			while (*cp != '\n' && *cp != '\0')				cp++;		else if(strcmp(word, "service") == 0) {			cp = getwrd(word, cp);			if(service[0] == 0)				strncpy(service, word, sizeof service);		} else if(strcmp(word, "ipauth") == 0)	/* obsolete */			cp = getwrd(word, cp);		else if(astrcmp(word, "ip") == 0)	/* obsolete */			cp = getwrd(word, cp);		else if(astrcmp(word, "ipgw") == 0)	/* obsolete */			cp = getwrd(word, cp);		else if(astrcmp(word, "ipsntp") == 0)	/* obsolete */			cp = getwrd(word, cp);		else if(astrcmp(word, "ipmask") == 0)	/* obsolete */			cp = getwrd(word, cp);		else if(strcmp(word, "filsys") == 0) {			cp = getwrd(word, cp);			for(fs = filsys; fs < filsys + nelem(filsys) - 1 &&			    fs->name; fs++)				if(strcmp(fs->name, word) == 0)					break;			if (fs >= filsys + nelem(filsys) - 1)				panic("out of filsys structures");			if (fs->name && strcmp(fs->name, word) == 0 &&			    fs->flags & FEDIT)				cp = getwrd(word, cp);	/* swallow conf */			else {				fs->name = strdup(word);				cp = getwrd(word, cp);				if (word[0] == '\0')					fs->conf = nil;				else					fs->conf = strdup(word);			}		} else if ((fsp = getpar(word)) != nil) {			cp = getwrd(word, cp);			if (!isascii(word[0]) || !isdigit(word[0]))				print("bad %s value: %s", fsp->name, word);			else				fsp->declared = atol(word);		} else {			putbuf(p);			panic("unknown keyword in config block: %s", word);		} 		if(*cp != '\n') {			putbuf(p);			panic("syntax error in config block at `%s'", word);		}	}} voidcmd_printconf(int, char *[]){	char *p, *s;	Iobuf *iob; 	iob = getbuf(confdev, 0, Brd);	if(iob == nil)		return;	if(checktag(iob, Tconfig, 0)){		putbuf(iob);		return;	} 	print("config %s\n", nvrgetconfig());	for(s = p = iob->iobuf; *p != 0 && p < iob->iobuf+BUFSIZE; ){		if(*p++ != '\n')			continue;		if (strncmp(s, "ip", 2) != 0)	/* don't print obsolete cmds */			print("%.*s", (int)(p-s), s);		s = p;	}	if(p != s)		print("%.*s", (int)(p-s), s);	print("end\n"); 	putbuf(iob);} voidsysinit(void){	int error;	char *cp, *ep;	Device *d;	Filsys *fs;	Fspar *fsp;	Iobuf *p; 	cons.chan = fs_chaninit(Devcon, 1, 0); 

Lines 1–500 of 1046.