xref: /plan9/sys/src/9/port/devroot.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
13e12c5d1SDavid du Colombier #include	"u.h"
23e12c5d1SDavid du Colombier #include	"../port/lib.h"
33e12c5d1SDavid du Colombier #include	"mem.h"
43e12c5d1SDavid du Colombier #include	"dat.h"
53e12c5d1SDavid du Colombier #include	"fns.h"
63e12c5d1SDavid du Colombier #include	"../port/error.h"
73e12c5d1SDavid du Colombier #include	"devtab.h"
83e12c5d1SDavid du Colombier 
93e12c5d1SDavid du Colombier enum{
10*219b2ee8SDavid du Colombier 	Qdir=	0,
113e12c5d1SDavid du Colombier 	Qbin,
123e12c5d1SDavid du Colombier 	Qdev,
133e12c5d1SDavid du Colombier 	Qenv,
143e12c5d1SDavid du Colombier 	Qproc,
153e12c5d1SDavid du Colombier 	Qnet,
16*219b2ee8SDavid du Colombier 	Qboot,		/* readable files */
173e12c5d1SDavid du Colombier 
18*219b2ee8SDavid du Colombier 	Nfiles=13,	/* max root files */
193e12c5d1SDavid du Colombier };
203e12c5d1SDavid du Colombier 
213e12c5d1SDavid du Colombier extern ulong	bootlen;
223e12c5d1SDavid du Colombier extern uchar	bootcode[];
233e12c5d1SDavid du Colombier 
24*219b2ee8SDavid du Colombier Dirtab rootdir[Nfiles]={
253e12c5d1SDavid du Colombier 		"bin",		{Qbin|CHDIR},	0,	0777,
263e12c5d1SDavid du Colombier 		"dev",		{Qdev|CHDIR},	0,	0777,
273e12c5d1SDavid du Colombier 		"env",		{Qenv|CHDIR},	0,	0777,
283e12c5d1SDavid du Colombier 		"proc",		{Qproc|CHDIR},	0,	0777,
293e12c5d1SDavid du Colombier 		"net",		{Qnet|CHDIR},	0,	0777,
303e12c5d1SDavid du Colombier };
313e12c5d1SDavid du Colombier 
32*219b2ee8SDavid du Colombier static uchar	*rootdata[Nfiles];
33*219b2ee8SDavid du Colombier static int	nroot = Qboot - 1;
34*219b2ee8SDavid du Colombier 
35*219b2ee8SDavid du Colombier /*
36*219b2ee8SDavid du Colombier  *  add a root file
37*219b2ee8SDavid du Colombier  */
38*219b2ee8SDavid du Colombier void
39*219b2ee8SDavid du Colombier addrootfile(char *name, uchar *contents, ulong len)
403e12c5d1SDavid du Colombier {
41*219b2ee8SDavid du Colombier 	Dirtab *d;
423e12c5d1SDavid du Colombier 
433e12c5d1SDavid du Colombier 
44*219b2ee8SDavid du Colombier 	if(nroot >= Nfiles)
45*219b2ee8SDavid du Colombier 		panic("too many root files");
46*219b2ee8SDavid du Colombier 	rootdata[nroot] = contents;
47*219b2ee8SDavid du Colombier 	d = &rootdir[nroot];
48*219b2ee8SDavid du Colombier 	strcpy(d->name, name);
49*219b2ee8SDavid du Colombier 	d->length = len;
50*219b2ee8SDavid du Colombier 	d->perm = 0555;
51*219b2ee8SDavid du Colombier 	d->qid.path = nroot+1;
52*219b2ee8SDavid du Colombier 	nroot++;
533e12c5d1SDavid du Colombier }
543e12c5d1SDavid du Colombier 
553e12c5d1SDavid du Colombier void
563e12c5d1SDavid du Colombier rootreset(void)
573e12c5d1SDavid du Colombier {
58*219b2ee8SDavid du Colombier 	addrootfile("boot", bootcode, bootlen);	/* always have a boot file */
593e12c5d1SDavid du Colombier }
603e12c5d1SDavid du Colombier 
613e12c5d1SDavid du Colombier void
623e12c5d1SDavid du Colombier rootinit(void)
633e12c5d1SDavid du Colombier {
643e12c5d1SDavid du Colombier }
653e12c5d1SDavid du Colombier 
663e12c5d1SDavid du Colombier Chan*
673e12c5d1SDavid du Colombier rootattach(char *spec)
683e12c5d1SDavid du Colombier {
693e12c5d1SDavid du Colombier 	return devattach('/', spec);
703e12c5d1SDavid du Colombier }
713e12c5d1SDavid du Colombier 
723e12c5d1SDavid du Colombier Chan*
733e12c5d1SDavid du Colombier rootclone(Chan *c, Chan *nc)
743e12c5d1SDavid du Colombier {
753e12c5d1SDavid du Colombier 	return devclone(c, nc);
763e12c5d1SDavid du Colombier }
773e12c5d1SDavid du Colombier 
783e12c5d1SDavid du Colombier int
793e12c5d1SDavid du Colombier rootwalk(Chan *c, char *name)
803e12c5d1SDavid du Colombier {
813e12c5d1SDavid du Colombier 	if(strcmp(name, "..") == 0) {
823e12c5d1SDavid du Colombier 		c->qid.path = Qdir|CHDIR;
833e12c5d1SDavid du Colombier 		return 1;
843e12c5d1SDavid du Colombier 	}
853e12c5d1SDavid du Colombier 	if((c->qid.path & ~CHDIR) != Qdir)
863e12c5d1SDavid du Colombier 		return 0;
87*219b2ee8SDavid du Colombier 	return devwalk(c, name, rootdir, nroot, devgen);
883e12c5d1SDavid du Colombier }
893e12c5d1SDavid du Colombier 
903e12c5d1SDavid du Colombier void
913e12c5d1SDavid du Colombier rootstat(Chan *c, char *dp)
923e12c5d1SDavid du Colombier {
93*219b2ee8SDavid du Colombier 	devstat(c, dp, rootdir, nroot, devgen);
943e12c5d1SDavid du Colombier }
953e12c5d1SDavid du Colombier 
963e12c5d1SDavid du Colombier Chan*
973e12c5d1SDavid du Colombier rootopen(Chan *c, int omode)
983e12c5d1SDavid du Colombier {
99*219b2ee8SDavid du Colombier 	return devopen(c, omode, rootdir, nroot, devgen);
1003e12c5d1SDavid du Colombier }
1013e12c5d1SDavid du Colombier 
1023e12c5d1SDavid du Colombier void
1033e12c5d1SDavid du Colombier rootcreate(Chan *c, char *name, int omode, ulong perm)
1043e12c5d1SDavid du Colombier {
1053e12c5d1SDavid du Colombier 	USED(c, name, omode, perm);
1063e12c5d1SDavid du Colombier 	error(Eperm);
1073e12c5d1SDavid du Colombier }
1083e12c5d1SDavid du Colombier 
1093e12c5d1SDavid du Colombier /*
1103e12c5d1SDavid du Colombier  * sysremove() knows this is a nop
1113e12c5d1SDavid du Colombier  */
1123e12c5d1SDavid du Colombier void
1133e12c5d1SDavid du Colombier rootclose(Chan *c)
1143e12c5d1SDavid du Colombier {
1153e12c5d1SDavid du Colombier 	USED(c);
1163e12c5d1SDavid du Colombier }
1173e12c5d1SDavid du Colombier 
1183e12c5d1SDavid du Colombier long
1193e12c5d1SDavid du Colombier rootread(Chan *c, void *buf, long n, ulong offset)
1203e12c5d1SDavid du Colombier {
121*219b2ee8SDavid du Colombier 	ulong t;
122*219b2ee8SDavid du Colombier 	Dirtab *d;
123*219b2ee8SDavid du Colombier 	uchar *data;
1243e12c5d1SDavid du Colombier 
125*219b2ee8SDavid du Colombier 	t = c->qid.path & ~CHDIR;
126*219b2ee8SDavid du Colombier 	if(t == Qdir)
127*219b2ee8SDavid du Colombier 		return devdirread(c, buf, n, rootdir, nroot, devgen);
128*219b2ee8SDavid du Colombier 	if(t < Qboot)
1293e12c5d1SDavid du Colombier 		return 0;
130*219b2ee8SDavid du Colombier 
131*219b2ee8SDavid du Colombier 	d = &rootdir[t-1];
132*219b2ee8SDavid du Colombier 	data = rootdata[t-1];
133*219b2ee8SDavid du Colombier 	if(offset >= d->length)
134*219b2ee8SDavid du Colombier 		return 0;
135*219b2ee8SDavid du Colombier 	if(offset+n > d->length)
136*219b2ee8SDavid du Colombier 		n = d->length - offset;
137*219b2ee8SDavid du Colombier 	memmove(buf, data+offset, n);
1383e12c5d1SDavid du Colombier 	return n;
1393e12c5d1SDavid du Colombier }
1403e12c5d1SDavid du Colombier 
1413e12c5d1SDavid du Colombier long
1423e12c5d1SDavid du Colombier rootwrite(Chan *c, void *buf, long n, ulong offset)
1433e12c5d1SDavid du Colombier {
1443e12c5d1SDavid du Colombier 	USED(c, buf, n, offset);
1453e12c5d1SDavid du Colombier 	error(Egreg);
1463e12c5d1SDavid du Colombier 	return 0;	/* not reached */
1473e12c5d1SDavid du Colombier }
1483e12c5d1SDavid du Colombier 
1493e12c5d1SDavid du Colombier void
1503e12c5d1SDavid du Colombier rootremove(Chan *c)
1513e12c5d1SDavid du Colombier {
1523e12c5d1SDavid du Colombier 	USED(c);
1533e12c5d1SDavid du Colombier 	error(Eperm);
1543e12c5d1SDavid du Colombier }
1553e12c5d1SDavid du Colombier 
1563e12c5d1SDavid du Colombier void
1573e12c5d1SDavid du Colombier rootwstat(Chan *c, char *dp)
1583e12c5d1SDavid du Colombier {
1593e12c5d1SDavid du Colombier 	USED(c, dp);
1603e12c5d1SDavid du Colombier 	error(Eperm);
1613e12c5d1SDavid du Colombier }
162