xref: /plan9/sys/src/9/port/devroot.c (revision 9acf08355bbda9b28aaf3d1ea7fa4e1adfa4d13f)
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 
86a9fc400SDavid du Colombier enum
96a9fc400SDavid du Colombier {
10219b2ee8SDavid du Colombier 	Qdir = 0,
116a9fc400SDavid du Colombier 	Qboot = 0x1000,
123e12c5d1SDavid du Colombier 
136a9fc400SDavid du Colombier 	Nrootfiles = 32,
1461201b97SDavid du Colombier 	Nbootfiles = 32,
153e12c5d1SDavid du Colombier };
163e12c5d1SDavid du Colombier 
176a9fc400SDavid du Colombier typedef struct Dirlist Dirlist;
186a9fc400SDavid du Colombier struct Dirlist
196a9fc400SDavid du Colombier {
206a9fc400SDavid du Colombier 	uint base;
216a9fc400SDavid du Colombier 	Dirtab *dir;
226a9fc400SDavid du Colombier 	uchar **data;
236a9fc400SDavid du Colombier 	int ndir;
246a9fc400SDavid du Colombier 	int mdir;
257dd7cddfSDavid du Colombier };
267dd7cddfSDavid du Colombier 
276a9fc400SDavid du Colombier static Dirtab rootdir[Nrootfiles] = {
286a9fc400SDavid du Colombier 	"#/",		{Qdir, 0, QTDIR},	0,		DMDIR|0555,
296a9fc400SDavid du Colombier 	"boot",	{Qboot, 0, QTDIR},	0,		DMDIR|0555,
306a9fc400SDavid du Colombier };
316a9fc400SDavid du Colombier static uchar *rootdata[Nrootfiles];
326a9fc400SDavid du Colombier static Dirlist rootlist =
336a9fc400SDavid du Colombier {
346a9fc400SDavid du Colombier 	0,
356a9fc400SDavid du Colombier 	rootdir,
366a9fc400SDavid du Colombier 	rootdata,
376a9fc400SDavid du Colombier 	2,
386a9fc400SDavid du Colombier 	Nrootfiles
396a9fc400SDavid du Colombier };
406a9fc400SDavid du Colombier 
416a9fc400SDavid du Colombier static Dirtab bootdir[Nbootfiles] = {
426a9fc400SDavid du Colombier 	"boot",	{Qboot, 0, QTDIR},	0,		DMDIR|0555,
436a9fc400SDavid du Colombier };
446a9fc400SDavid du Colombier static uchar *bootdata[Nbootfiles];
456a9fc400SDavid du Colombier static Dirlist bootlist =
466a9fc400SDavid du Colombier {
476a9fc400SDavid du Colombier 	Qboot,
486a9fc400SDavid du Colombier 	bootdir,
496a9fc400SDavid du Colombier 	bootdata,
506a9fc400SDavid du Colombier 	1,
516a9fc400SDavid du Colombier 	Nbootfiles
526a9fc400SDavid du Colombier };
53219b2ee8SDavid du Colombier 
54219b2ee8SDavid du Colombier /*
556a9fc400SDavid du Colombier  *  add a file to the list
56219b2ee8SDavid du Colombier  */
577dd7cddfSDavid du Colombier static void
addlist(Dirlist * l,char * name,uchar * contents,ulong len,int perm)586a9fc400SDavid du Colombier addlist(Dirlist *l, char *name, uchar *contents, ulong len, int perm)
593e12c5d1SDavid du Colombier {
60219b2ee8SDavid du Colombier 	Dirtab *d;
613e12c5d1SDavid du Colombier 
626a9fc400SDavid du Colombier 	if(l->ndir >= l->mdir)
63219b2ee8SDavid du Colombier 		panic("too many root files");
646a9fc400SDavid du Colombier 	l->data[l->ndir] = contents;
656a9fc400SDavid du Colombier 	d = &l->dir[l->ndir];
66219b2ee8SDavid du Colombier 	strcpy(d->name, name);
67219b2ee8SDavid du Colombier 	d->length = len;
687dd7cddfSDavid du Colombier 	d->perm = perm;
699a747e4fSDavid du Colombier 	d->qid.type = 0;
709a747e4fSDavid du Colombier 	d->qid.vers = 0;
716a9fc400SDavid du Colombier 	d->qid.path = ++l->ndir + l->base;
729a747e4fSDavid du Colombier 	if(perm & DMDIR)
739a747e4fSDavid du Colombier 		d->qid.type |= QTDIR;
743e12c5d1SDavid du Colombier }
753e12c5d1SDavid du Colombier 
767dd7cddfSDavid du Colombier /*
777dd7cddfSDavid du Colombier  *  add a root file
787dd7cddfSDavid du Colombier  */
793e12c5d1SDavid du Colombier void
addbootfile(char * name,uchar * contents,ulong len)806a9fc400SDavid du Colombier addbootfile(char *name, uchar *contents, ulong len)
817dd7cddfSDavid du Colombier {
826a9fc400SDavid du Colombier 	addlist(&bootlist, name, contents, len, 0555);
837dd7cddfSDavid du Colombier }
847dd7cddfSDavid du Colombier 
857dd7cddfSDavid du Colombier /*
866a9fc400SDavid du Colombier  *  add a root directory
877dd7cddfSDavid du Colombier  */
887dd7cddfSDavid du Colombier static void
addrootdir(char * name)897dd7cddfSDavid du Colombier addrootdir(char *name)
907dd7cddfSDavid du Colombier {
916a9fc400SDavid du Colombier 	addlist(&rootlist, name, nil, 0, DMDIR|0555);
927dd7cddfSDavid du Colombier }
937dd7cddfSDavid du Colombier 
947dd7cddfSDavid du Colombier static void
rootreset(void)953e12c5d1SDavid du Colombier rootreset(void)
963e12c5d1SDavid du Colombier {
977dd7cddfSDavid du Colombier 	addrootdir("bin");
987dd7cddfSDavid du Colombier 	addrootdir("dev");
997dd7cddfSDavid du Colombier 	addrootdir("env");
1009a747e4fSDavid du Colombier 	addrootdir("fd");
1019a747e4fSDavid du Colombier 	addrootdir("mnt");
1027dd7cddfSDavid du Colombier 	addrootdir("net");
1037dd7cddfSDavid du Colombier 	addrootdir("net.alt");
1047dd7cddfSDavid du Colombier 	addrootdir("proc");
1057dd7cddfSDavid du Colombier 	addrootdir("root");
1067dd7cddfSDavid du Colombier 	addrootdir("srv");
1073e12c5d1SDavid du Colombier }
1083e12c5d1SDavid du Colombier 
1097dd7cddfSDavid du Colombier static Chan*
rootattach(char * spec)1103e12c5d1SDavid du Colombier rootattach(char *spec)
1113e12c5d1SDavid du Colombier {
1123e12c5d1SDavid du Colombier 	return devattach('/', spec);
1133e12c5d1SDavid du Colombier }
1143e12c5d1SDavid du Colombier 
1156a9fc400SDavid du Colombier static int
rootgen(Chan * c,char * name,Dirtab *,int,int s,Dir * dp)1166a9fc400SDavid du Colombier rootgen(Chan *c, char *name, Dirtab*, int, int s, Dir *dp)
1176a9fc400SDavid du Colombier {
1186a9fc400SDavid du Colombier 	int t;
1196a9fc400SDavid du Colombier 	Dirtab *d;
1206a9fc400SDavid du Colombier 	Dirlist *l;
1216a9fc400SDavid du Colombier 
1226a9fc400SDavid du Colombier 	switch((int)c->qid.path){
1236a9fc400SDavid du Colombier 	case Qdir:
124fb7f0c93SDavid du Colombier 		if(s == DEVDOTDOT){
125fb7f0c93SDavid du Colombier 			devdir(c, (Qid){Qdir, 0, QTDIR}, "#/", 0, eve, 0555, dp);
126fb7f0c93SDavid du Colombier 			return 1;
127fb7f0c93SDavid du Colombier 		}
1286a9fc400SDavid du Colombier 		return devgen(c, name, rootlist.dir, rootlist.ndir, s, dp);
1296a9fc400SDavid du Colombier 	case Qboot:
1306a9fc400SDavid du Colombier 		if(s == DEVDOTDOT){
1316a9fc400SDavid du Colombier 			devdir(c, (Qid){Qdir, 0, QTDIR}, "#/", 0, eve, 0555, dp);
1326a9fc400SDavid du Colombier 			return 1;
1336a9fc400SDavid du Colombier 		}
1346a9fc400SDavid du Colombier 		return devgen(c, name, bootlist.dir, bootlist.ndir, s, dp);
1356a9fc400SDavid du Colombier 	default:
1367abd426fSDavid du Colombier 		if(s == DEVDOTDOT){
1377abd426fSDavid du Colombier 			if((int)c->qid.path < Qboot)
1387abd426fSDavid du Colombier 				devdir(c, (Qid){Qdir, 0, QTDIR}, "#/", 0, eve, 0555, dp);
1397abd426fSDavid du Colombier 			else
1407abd426fSDavid du Colombier 				devdir(c, (Qid){Qboot, 0, QTDIR}, "#/", 0, eve, 0555, dp);
1417abd426fSDavid du Colombier 			return 1;
1427abd426fSDavid du Colombier 		}
143fb7f0c93SDavid du Colombier 		if(s != 0)
144fb7f0c93SDavid du Colombier 			return -1;
1456a9fc400SDavid du Colombier 		if((int)c->qid.path < Qboot){
1466a9fc400SDavid du Colombier 			t = c->qid.path-1;
1476a9fc400SDavid du Colombier 			l = &rootlist;
1486a9fc400SDavid du Colombier 		}else{
1496a9fc400SDavid du Colombier 			t = c->qid.path - Qboot - 1;
1506a9fc400SDavid du Colombier 			l = &bootlist;
1516a9fc400SDavid du Colombier 		}
1526a9fc400SDavid du Colombier 		if(t >= l->ndir)
1536a9fc400SDavid du Colombier 			return -1;
1547abd426fSDavid du Colombier if(t < 0){
1557abd426fSDavid du Colombier print("rootgen %llud %d %d\n", c->qid.path, s, t);
1567abd426fSDavid du Colombier panic("whoops");
1577abd426fSDavid du Colombier }
1586a9fc400SDavid du Colombier 		d = &l->dir[t];
1596a9fc400SDavid du Colombier 		devdir(c, d->qid, d->name, d->length, eve, d->perm, dp);
1606a9fc400SDavid du Colombier 		return 1;
1616a9fc400SDavid du Colombier 	}
1626a9fc400SDavid du Colombier }
1636a9fc400SDavid du Colombier 
1649a747e4fSDavid du Colombier static Walkqid*
rootwalk(Chan * c,Chan * nc,char ** name,int nname)1659a747e4fSDavid du Colombier rootwalk(Chan *c, Chan *nc, char **name, int nname)
1663e12c5d1SDavid du Colombier {
1676a9fc400SDavid du Colombier 	return devwalk(c,  nc, name, nname, nil, 0, rootgen);
1683e12c5d1SDavid du Colombier }
1693e12c5d1SDavid du Colombier 
1709a747e4fSDavid du Colombier static int
rootstat(Chan * c,uchar * dp,int n)1719a747e4fSDavid du Colombier rootstat(Chan *c, uchar *dp, int n)
1723e12c5d1SDavid du Colombier {
1736a9fc400SDavid du Colombier 	return devstat(c, dp, n, nil, 0, rootgen);
1743e12c5d1SDavid du Colombier }
1753e12c5d1SDavid du Colombier 
1767dd7cddfSDavid du Colombier static Chan*
rootopen(Chan * c,int omode)1773e12c5d1SDavid du Colombier rootopen(Chan *c, int omode)
1783e12c5d1SDavid du Colombier {
1796a9fc400SDavid du Colombier 	return devopen(c, omode, nil, 0, devgen);
1803e12c5d1SDavid du Colombier }
1813e12c5d1SDavid du Colombier 
1823e12c5d1SDavid du Colombier /*
1833e12c5d1SDavid du Colombier  * sysremove() knows this is a nop
1843e12c5d1SDavid du Colombier  */
1857dd7cddfSDavid du Colombier static void
rootclose(Chan *)1869a747e4fSDavid du Colombier rootclose(Chan*)
1873e12c5d1SDavid du Colombier {
1887dd7cddfSDavid du Colombier }
1897dd7cddfSDavid du Colombier 
1907dd7cddfSDavid du Colombier static long
rootread(Chan * c,void * buf,long n,vlong off)1917dd7cddfSDavid du Colombier rootread(Chan *c, void *buf, long n, vlong off)
1923e12c5d1SDavid du Colombier {
193219b2ee8SDavid du Colombier 	ulong t;
194219b2ee8SDavid du Colombier 	Dirtab *d;
1956a9fc400SDavid du Colombier 	Dirlist *l;
196219b2ee8SDavid du Colombier 	uchar *data;
1977dd7cddfSDavid du Colombier 	ulong offset = off;
1983e12c5d1SDavid du Colombier 
1999a747e4fSDavid du Colombier 	t = c->qid.path;
2007dd7cddfSDavid du Colombier 	switch(t){
2017dd7cddfSDavid du Colombier 	case Qdir:
2026a9fc400SDavid du Colombier 	case Qboot:
2036a9fc400SDavid du Colombier 		return devdirread(c, buf, n, nil, 0, rootgen);
2047dd7cddfSDavid du Colombier 	}
205219b2ee8SDavid du Colombier 
2066a9fc400SDavid du Colombier 	if(t<Qboot)
2076a9fc400SDavid du Colombier 		l = &rootlist;
2086a9fc400SDavid du Colombier 	else{
2096a9fc400SDavid du Colombier 		t -= Qboot;
2106a9fc400SDavid du Colombier 		l = &bootlist;
2116a9fc400SDavid du Colombier 	}
2126a9fc400SDavid du Colombier 
213fb7f0c93SDavid du Colombier 	t--;
214fb7f0c93SDavid du Colombier 	if(t >= l->ndir)
215fb7f0c93SDavid du Colombier 		error(Egreg);
216fb7f0c93SDavid du Colombier 
217fb7f0c93SDavid du Colombier 	d = &l->dir[t];
218fb7f0c93SDavid du Colombier 	data = l->data[t];
219219b2ee8SDavid du Colombier 	if(offset >= d->length)
220219b2ee8SDavid du Colombier 		return 0;
221219b2ee8SDavid du Colombier 	if(offset+n > d->length)
222219b2ee8SDavid du Colombier 		n = d->length - offset;
223*e288d156SDavid du Colombier #ifdef asdf
224*e288d156SDavid du Colombier print("[%d] kaddr %.8ulx base %.8ulx offset %ld (%.8ulx), n %d %.8ulx %.8ulx %.8ulx\n",
225*e288d156SDavid du Colombier 		t, buf, data, offset, offset, n,
226*e288d156SDavid du Colombier 		((ulong*)(data+offset))[0],
227*e288d156SDavid du Colombier 		((ulong*)(data+offset))[1],
228*e288d156SDavid du Colombier 		((ulong*)(data+offset))[2]);
229*e288d156SDavid du Colombier #endif asdf
230219b2ee8SDavid du Colombier 	memmove(buf, data+offset, n);
2313e12c5d1SDavid du Colombier 	return n;
2323e12c5d1SDavid du Colombier }
2333e12c5d1SDavid du Colombier 
2347dd7cddfSDavid du Colombier static long
rootwrite(Chan *,void *,long,vlong)2356a9fc400SDavid du Colombier rootwrite(Chan*, void*, long, vlong)
2363e12c5d1SDavid du Colombier {
2373e12c5d1SDavid du Colombier 	error(Egreg);
2387dd7cddfSDavid du Colombier 	return 0;
2393e12c5d1SDavid du Colombier }
2403e12c5d1SDavid du Colombier 
2417dd7cddfSDavid du Colombier Dev rootdevtab = {
2427dd7cddfSDavid du Colombier 	'/',
2437dd7cddfSDavid du Colombier 	"root",
2447dd7cddfSDavid du Colombier 
2457dd7cddfSDavid du Colombier 	rootreset,
2467dd7cddfSDavid du Colombier 	devinit,
2479a747e4fSDavid du Colombier 	devshutdown,
2487dd7cddfSDavid du Colombier 	rootattach,
2497dd7cddfSDavid du Colombier 	rootwalk,
2507dd7cddfSDavid du Colombier 	rootstat,
2517dd7cddfSDavid du Colombier 	rootopen,
252223a736eSDavid du Colombier 	devcreate,
2537dd7cddfSDavid du Colombier 	rootclose,
2547dd7cddfSDavid du Colombier 	rootread,
2557dd7cddfSDavid du Colombier 	devbread,
2567dd7cddfSDavid du Colombier 	rootwrite,
2577dd7cddfSDavid du Colombier 	devbwrite,
2587dd7cddfSDavid du Colombier 	devremove,
2597dd7cddfSDavid du Colombier 	devwstat,
2607dd7cddfSDavid du Colombier };
2616a9fc400SDavid du Colombier 
262