xref: /plan9/sys/src/cmd/unix/drawterm/kern/devroot.c (revision 0d601874851962e88c6c60fdd2e637bba04e13c2)
18ccd4a63SDavid du Colombier #include	"u.h"
28ccd4a63SDavid du Colombier #include	"lib.h"
38ccd4a63SDavid du Colombier #include	"dat.h"
48ccd4a63SDavid du Colombier #include	"fns.h"
58ccd4a63SDavid du Colombier #include	"error.h"
68ccd4a63SDavid du Colombier 
78ccd4a63SDavid du Colombier enum
88ccd4a63SDavid du Colombier {
98ccd4a63SDavid du Colombier 	Qdir = 0,
108ccd4a63SDavid du Colombier 	Qboot = 0x1000,
118ccd4a63SDavid du Colombier 	Qmnt = 0x2000,
128ccd4a63SDavid du Colombier 	Qfactotum,
138ccd4a63SDavid du Colombier 
148ccd4a63SDavid du Colombier 	Nrootfiles = 32,
158ccd4a63SDavid du Colombier 	Nbootfiles = 32,
168ccd4a63SDavid du Colombier 	Nmntfiles = 2,
178ccd4a63SDavid du Colombier };
188ccd4a63SDavid du Colombier 
198ccd4a63SDavid du Colombier typedef struct Dirlist Dirlist;
208ccd4a63SDavid du Colombier struct Dirlist
218ccd4a63SDavid du Colombier {
228ccd4a63SDavid du Colombier 	uint base;
238ccd4a63SDavid du Colombier 	Dirtab *dir;
248ccd4a63SDavid du Colombier 	uchar **data;
258ccd4a63SDavid du Colombier 	int ndir;
268ccd4a63SDavid du Colombier 	int mdir;
278ccd4a63SDavid du Colombier };
288ccd4a63SDavid du Colombier 
298ccd4a63SDavid du Colombier static Dirtab rootdir[Nrootfiles] = {
308ccd4a63SDavid du Colombier 	"#/",		{Qdir, 0, QTDIR},	0,		DMDIR|0555,
318ccd4a63SDavid du Colombier 	"boot",	{Qboot, 0, QTDIR},	0,		DMDIR|0555,
328ccd4a63SDavid du Colombier 	"mnt",	{Qmnt, 0, QTDIR},	0,		DMDIR|0555,
338ccd4a63SDavid du Colombier };
348ccd4a63SDavid du Colombier static uchar *rootdata[Nrootfiles];
358ccd4a63SDavid du Colombier static Dirlist rootlist =
368ccd4a63SDavid du Colombier {
378ccd4a63SDavid du Colombier 	0,
388ccd4a63SDavid du Colombier 	rootdir,
398ccd4a63SDavid du Colombier 	rootdata,
408ccd4a63SDavid du Colombier 	3,
418ccd4a63SDavid du Colombier 	Nrootfiles
428ccd4a63SDavid du Colombier };
438ccd4a63SDavid du Colombier 
448ccd4a63SDavid du Colombier static Dirtab bootdir[Nbootfiles] = {
458ccd4a63SDavid du Colombier 	"boot",	{Qboot, 0, QTDIR},	0,		DMDIR|0555,
468ccd4a63SDavid du Colombier };
478ccd4a63SDavid du Colombier static uchar *bootdata[Nbootfiles];
488ccd4a63SDavid du Colombier static Dirlist bootlist =
498ccd4a63SDavid du Colombier {
508ccd4a63SDavid du Colombier 	Qboot,
518ccd4a63SDavid du Colombier 	bootdir,
528ccd4a63SDavid du Colombier 	bootdata,
538ccd4a63SDavid du Colombier 	1,
548ccd4a63SDavid du Colombier 	Nbootfiles
558ccd4a63SDavid du Colombier };
568ccd4a63SDavid du Colombier 
57*0d601874SDavid du Colombier static uchar *mntdata[Nmntfiles];
588ccd4a63SDavid du Colombier static Dirtab mntdir[Nmntfiles] = {
598ccd4a63SDavid du Colombier 	"mnt",	{Qmnt, 0, QTDIR},	0,		DMDIR|0555,
608ccd4a63SDavid du Colombier 	"factotum",	{Qfactotum, 0, QTDIR},	0,	DMDIR|0555,
618ccd4a63SDavid du Colombier };
628ccd4a63SDavid du Colombier static Dirlist mntlist =
638ccd4a63SDavid du Colombier {
648ccd4a63SDavid du Colombier 	Qmnt,
658ccd4a63SDavid du Colombier 	mntdir,
66*0d601874SDavid du Colombier 	mntdata,
678ccd4a63SDavid du Colombier 	2,
688ccd4a63SDavid du Colombier 	Nmntfiles
698ccd4a63SDavid du Colombier };
708ccd4a63SDavid du Colombier 
718ccd4a63SDavid du Colombier /*
728ccd4a63SDavid du Colombier  *  add a file to the list
738ccd4a63SDavid du Colombier  */
748ccd4a63SDavid du Colombier static void
addlist(Dirlist * l,char * name,uchar * contents,ulong len,int perm)758ccd4a63SDavid du Colombier addlist(Dirlist *l, char *name, uchar *contents, ulong len, int perm)
768ccd4a63SDavid du Colombier {
778ccd4a63SDavid du Colombier 	Dirtab *d;
788ccd4a63SDavid du Colombier 
798ccd4a63SDavid du Colombier 	if(l->ndir >= l->mdir)
808ccd4a63SDavid du Colombier 		panic("too many root files");
818ccd4a63SDavid du Colombier 	l->data[l->ndir] = contents;
828ccd4a63SDavid du Colombier 	d = &l->dir[l->ndir];
838ccd4a63SDavid du Colombier 	strcpy(d->name, name);
848ccd4a63SDavid du Colombier 	d->length = len;
858ccd4a63SDavid du Colombier 	d->perm = perm;
868ccd4a63SDavid du Colombier 	d->qid.type = 0;
878ccd4a63SDavid du Colombier 	d->qid.vers = 0;
888ccd4a63SDavid du Colombier 	d->qid.path = ++l->ndir + l->base;
898ccd4a63SDavid du Colombier 	if(perm & DMDIR)
908ccd4a63SDavid du Colombier 		d->qid.type |= QTDIR;
918ccd4a63SDavid du Colombier }
928ccd4a63SDavid du Colombier 
938ccd4a63SDavid du Colombier /*
948ccd4a63SDavid du Colombier  *  add a root file
958ccd4a63SDavid du Colombier  */
968ccd4a63SDavid du Colombier void
addbootfile(char * name,uchar * contents,ulong len)978ccd4a63SDavid du Colombier addbootfile(char *name, uchar *contents, ulong len)
988ccd4a63SDavid du Colombier {
998ccd4a63SDavid du Colombier 	addlist(&bootlist, name, contents, len, 0555);
1008ccd4a63SDavid du Colombier }
1018ccd4a63SDavid du Colombier 
1028ccd4a63SDavid du Colombier /*
1038ccd4a63SDavid du Colombier  *  add a root directory
1048ccd4a63SDavid du Colombier  */
1058ccd4a63SDavid du Colombier static void
addrootdir(char * name)1068ccd4a63SDavid du Colombier addrootdir(char *name)
1078ccd4a63SDavid du Colombier {
1088ccd4a63SDavid du Colombier 	addlist(&rootlist, name, nil, 0, DMDIR|0555);
1098ccd4a63SDavid du Colombier }
1108ccd4a63SDavid du Colombier 
1118ccd4a63SDavid du Colombier static void
rootreset(void)1128ccd4a63SDavid du Colombier rootreset(void)
1138ccd4a63SDavid du Colombier {
1148ccd4a63SDavid du Colombier 	addrootdir("bin");
1158ccd4a63SDavid du Colombier 	addrootdir("dev");
1168ccd4a63SDavid du Colombier 	addrootdir("env");
1178ccd4a63SDavid du Colombier 	addrootdir("fd");
1188ccd4a63SDavid du Colombier 	addrootdir("net");
1198ccd4a63SDavid du Colombier 	addrootdir("net.alt");
1208ccd4a63SDavid du Colombier 	addrootdir("proc");
1218ccd4a63SDavid du Colombier 	addrootdir("root");
1228ccd4a63SDavid du Colombier 	addrootdir("srv");
1238ccd4a63SDavid du Colombier }
1248ccd4a63SDavid du Colombier 
1258ccd4a63SDavid du Colombier static Chan*
rootattach(char * spec)1268ccd4a63SDavid du Colombier rootattach(char *spec)
1278ccd4a63SDavid du Colombier {
1288ccd4a63SDavid du Colombier 	return devattach('/', spec);
1298ccd4a63SDavid du Colombier }
1308ccd4a63SDavid du Colombier 
1318ccd4a63SDavid du Colombier static int
rootgen(Chan * c,char * name,Dirtab * dirt,int ndirt,int s,Dir * dp)1328ccd4a63SDavid du Colombier rootgen(Chan *c, char *name, Dirtab *dirt, int ndirt, int s, Dir *dp)
1338ccd4a63SDavid du Colombier {
1348ccd4a63SDavid du Colombier 	int t;
1358ccd4a63SDavid du Colombier 	Dirtab *d;
1368ccd4a63SDavid du Colombier 	Dirlist *l;
1378ccd4a63SDavid du Colombier 
1388ccd4a63SDavid du Colombier 	USED(dirt);
1398ccd4a63SDavid du Colombier 	USED(ndirt);
1408ccd4a63SDavid du Colombier 
1418ccd4a63SDavid du Colombier 	switch((int)c->qid.path){
1428ccd4a63SDavid du Colombier 	case Qdir:
1438ccd4a63SDavid du Colombier 		if(s == DEVDOTDOT){
1448ccd4a63SDavid du Colombier 			Qid tqiddir = {Qdir, 0, QTDIR};
1458ccd4a63SDavid du Colombier 			devdir(c, tqiddir, "#/", 0, eve, 0555, dp);
1468ccd4a63SDavid du Colombier 			return 1;
1478ccd4a63SDavid du Colombier 		}
1488ccd4a63SDavid du Colombier 		return devgen(c, name, rootlist.dir, rootlist.ndir, s, dp);
1498ccd4a63SDavid du Colombier 	case Qmnt:
1508ccd4a63SDavid du Colombier 		if(s == DEVDOTDOT){
1518ccd4a63SDavid du Colombier 			Qid tqiddir = {Qdir, 0, QTDIR};
1528ccd4a63SDavid du Colombier 			devdir(c, tqiddir, "#/", 0, eve, 0555, dp);
1538ccd4a63SDavid du Colombier 			return 1;
1548ccd4a63SDavid du Colombier 		}
1558ccd4a63SDavid du Colombier 		return devgen(c, name, mntlist.dir, mntlist.ndir, s, dp);
1568ccd4a63SDavid du Colombier 	case Qboot:
1578ccd4a63SDavid du Colombier 		if(s == DEVDOTDOT){
1588ccd4a63SDavid du Colombier 			Qid tqiddir = {Qdir, 0, QTDIR};
1598ccd4a63SDavid du Colombier 			devdir(c, tqiddir, "#/", 0, eve, 0555, dp);
1608ccd4a63SDavid du Colombier 			return 1;
1618ccd4a63SDavid du Colombier 		}
1628ccd4a63SDavid du Colombier 		return devgen(c, name, bootlist.dir, bootlist.ndir, s, dp);
1638ccd4a63SDavid du Colombier 	default:
1648ccd4a63SDavid du Colombier 		if(s == DEVDOTDOT){
1658ccd4a63SDavid du Colombier 			Qid tqiddir = {Qdir, 0, QTDIR};
1668ccd4a63SDavid du Colombier 			tqiddir.path = c->qid.path&0xF000;
1678ccd4a63SDavid du Colombier 			devdir(c, tqiddir, "#/", 0, eve, 0555, dp);
1688ccd4a63SDavid du Colombier 			return 1;
1698ccd4a63SDavid du Colombier 		}
1708ccd4a63SDavid du Colombier 		if(s != 0)
1718ccd4a63SDavid du Colombier 			return -1;
1728ccd4a63SDavid du Colombier 		switch((int)c->qid.path & 0xF000){
1738ccd4a63SDavid du Colombier 		case Qdir:
1748ccd4a63SDavid du Colombier 			t = c->qid.path-1;
1758ccd4a63SDavid du Colombier 			l = &rootlist;
1768ccd4a63SDavid du Colombier 			break;
1778ccd4a63SDavid du Colombier 		case Qboot:
1788ccd4a63SDavid du Colombier 			t = c->qid.path - Qboot - 1;
1798ccd4a63SDavid du Colombier 			l = &bootlist;
1808ccd4a63SDavid du Colombier 			break;
1818ccd4a63SDavid du Colombier 		case Qmnt:
1828ccd4a63SDavid du Colombier 			t = c->qid.path - Qmnt - 1;
1838ccd4a63SDavid du Colombier 			l = &mntlist;
1848ccd4a63SDavid du Colombier 			break;
1858ccd4a63SDavid du Colombier 		default:
1868ccd4a63SDavid du Colombier 			return -1;
1878ccd4a63SDavid du Colombier 		}
1888ccd4a63SDavid du Colombier 		if(t >= l->ndir)
1898ccd4a63SDavid du Colombier 			return -1;
1908ccd4a63SDavid du Colombier if(t < 0){
1918ccd4a63SDavid du Colombier print("rootgen %llud %d %d\n", c->qid.path, s, t);
1928ccd4a63SDavid du Colombier panic("whoops");
1938ccd4a63SDavid du Colombier }
1948ccd4a63SDavid du Colombier 		d = &l->dir[t];
1958ccd4a63SDavid du Colombier 		devdir(c, d->qid, d->name, d->length, eve, d->perm, dp);
1968ccd4a63SDavid du Colombier 		return 1;
1978ccd4a63SDavid du Colombier 	}
1988ccd4a63SDavid du Colombier 	return -1;
1998ccd4a63SDavid du Colombier }
2008ccd4a63SDavid du Colombier 
2018ccd4a63SDavid du Colombier static Walkqid*
rootwalk(Chan * c,Chan * nc,char ** name,int nname)2028ccd4a63SDavid du Colombier rootwalk(Chan *c, Chan *nc, char **name, int nname)
2038ccd4a63SDavid du Colombier {
2048ccd4a63SDavid du Colombier 	return devwalk(c,  nc, name, nname, nil, 0, rootgen);
2058ccd4a63SDavid du Colombier }
2068ccd4a63SDavid du Colombier 
2078ccd4a63SDavid du Colombier static int
rootstat(Chan * c,uchar * dp,int n)2088ccd4a63SDavid du Colombier rootstat(Chan *c, uchar *dp, int n)
2098ccd4a63SDavid du Colombier {
2108ccd4a63SDavid du Colombier 	return devstat(c, dp, n, nil, 0, rootgen);
2118ccd4a63SDavid du Colombier }
2128ccd4a63SDavid du Colombier 
2138ccd4a63SDavid du Colombier static Chan*
rootopen(Chan * c,int omode)2148ccd4a63SDavid du Colombier rootopen(Chan *c, int omode)
2158ccd4a63SDavid du Colombier {
2168ccd4a63SDavid du Colombier 	return devopen(c, omode, nil, 0, devgen);
2178ccd4a63SDavid du Colombier }
2188ccd4a63SDavid du Colombier 
2198ccd4a63SDavid du Colombier /*
2208ccd4a63SDavid du Colombier  * sysremove() knows this is a nop
2218ccd4a63SDavid du Colombier  */
2228ccd4a63SDavid du Colombier static void
rootclose(Chan * c)2238ccd4a63SDavid du Colombier rootclose(Chan *c)
2248ccd4a63SDavid du Colombier {
2258ccd4a63SDavid du Colombier 	USED(c);
2268ccd4a63SDavid du Colombier }
2278ccd4a63SDavid du Colombier 
2288ccd4a63SDavid du Colombier static long
rootread(Chan * c,void * buf,long n,vlong off)2298ccd4a63SDavid du Colombier rootread(Chan *c, void *buf, long n, vlong off)
2308ccd4a63SDavid du Colombier {
2318ccd4a63SDavid du Colombier 	ulong t;
2328ccd4a63SDavid du Colombier 	Dirtab *d;
2338ccd4a63SDavid du Colombier 	Dirlist *l;
2348ccd4a63SDavid du Colombier 	uchar *data;
2358ccd4a63SDavid du Colombier 	ulong offset = off;
2368ccd4a63SDavid du Colombier 
2378ccd4a63SDavid du Colombier 	t = c->qid.path;
2388ccd4a63SDavid du Colombier 	switch(t){
2398ccd4a63SDavid du Colombier 	case Qdir:
2408ccd4a63SDavid du Colombier 	case Qboot:
2418ccd4a63SDavid du Colombier 	case Qmnt:
2428ccd4a63SDavid du Colombier 		return devdirread(c, buf, n, nil, 0, rootgen);
2438ccd4a63SDavid du Colombier 	}
2448ccd4a63SDavid du Colombier 
2458ccd4a63SDavid du Colombier 	if(t&Qboot)
2468ccd4a63SDavid du Colombier 		l = &bootlist;
2478ccd4a63SDavid du Colombier 	else if(t&Qmnt)
2488ccd4a63SDavid du Colombier 		l = &mntlist;
2498ccd4a63SDavid du Colombier 	else
2508ccd4a63SDavid du Colombier 		l = &bootlist;
2518ccd4a63SDavid du Colombier 	t &= 0xFFF;
2528ccd4a63SDavid du Colombier 	t--;
2538ccd4a63SDavid du Colombier 
2548ccd4a63SDavid du Colombier 	if(t >= l->ndir)
2558ccd4a63SDavid du Colombier 		error(Egreg);
2568ccd4a63SDavid du Colombier 
2578ccd4a63SDavid du Colombier 	d = &l->dir[t];
2588ccd4a63SDavid du Colombier 	data = l->data[t];
2598ccd4a63SDavid du Colombier 	if(offset >= d->length)
2608ccd4a63SDavid du Colombier 		return 0;
2618ccd4a63SDavid du Colombier 	if(offset+n > d->length)
2628ccd4a63SDavid du Colombier 		n = d->length - offset;
2638ccd4a63SDavid du Colombier 	memmove(buf, data+offset, n);
2648ccd4a63SDavid du Colombier 	return n;
2658ccd4a63SDavid du Colombier }
2668ccd4a63SDavid du Colombier 
2678ccd4a63SDavid du Colombier static long
rootwrite(Chan * c,void * v,long n,vlong o)2688ccd4a63SDavid du Colombier rootwrite(Chan *c, void *v, long n, vlong o)
2698ccd4a63SDavid du Colombier {
2708ccd4a63SDavid du Colombier 	USED(c);
2718ccd4a63SDavid du Colombier 	USED(v);
2728ccd4a63SDavid du Colombier 	USED(n);
2738ccd4a63SDavid du Colombier 	USED(o);
2748ccd4a63SDavid du Colombier 
2758ccd4a63SDavid du Colombier 	error(Egreg);
2768ccd4a63SDavid du Colombier 	return 0;
2778ccd4a63SDavid du Colombier }
2788ccd4a63SDavid du Colombier 
2798ccd4a63SDavid du Colombier Dev rootdevtab = {
2808ccd4a63SDavid du Colombier 	'/',
2818ccd4a63SDavid du Colombier 	"root",
2828ccd4a63SDavid du Colombier 
2838ccd4a63SDavid du Colombier 	rootreset,
2848ccd4a63SDavid du Colombier 	devinit,
2858ccd4a63SDavid du Colombier 	devshutdown,
2868ccd4a63SDavid du Colombier 	rootattach,
2878ccd4a63SDavid du Colombier 	rootwalk,
2888ccd4a63SDavid du Colombier 	rootstat,
2898ccd4a63SDavid du Colombier 	rootopen,
2908ccd4a63SDavid du Colombier 	devcreate,
2918ccd4a63SDavid du Colombier 	rootclose,
2928ccd4a63SDavid du Colombier 	rootread,
2938ccd4a63SDavid du Colombier 	devbread,
2948ccd4a63SDavid du Colombier 	rootwrite,
2958ccd4a63SDavid du Colombier 	devbwrite,
2968ccd4a63SDavid du Colombier 	devremove,
2978ccd4a63SDavid du Colombier 	devwstat,
2988ccd4a63SDavid du Colombier };
2998ccd4a63SDavid du Colombier 
300