vx32

Local 9vx git repository for patches.
git clone git://r-36.net/vx32
Log | Files | Refs

devroot.c (4237B)


      1 #include	"u.h"
      2 #include	"lib.h"
      3 #include	"mem.h"
      4 #include	"dat.h"
      5 #include	"fns.h"
      6 #include	"error.h"
      7 
      8 enum
      9 {
     10 	Qdir = 0,
     11 	Qboot = 0x1000,
     12 
     13 	Nrootfiles = 32,
     14 	Nbootfiles = 32,
     15 };
     16 
     17 typedef struct Dirlist Dirlist;
     18 struct Dirlist
     19 {
     20 	uint base;
     21 	Dirtab *dir;
     22 	uchar **data;
     23 	int ndir;
     24 	int mdir;
     25 };
     26 
     27 static Dirtab rootdir[Nrootfiles] = {
     28 	"#/",		{Qdir, 0, QTDIR},	0,		DMDIR|0555,
     29 	"boot",	{Qboot, 0, QTDIR},	0,		DMDIR|0555,
     30 };
     31 static uchar *rootdata[Nrootfiles];
     32 static Dirlist rootlist = 
     33 {
     34 	0,
     35 	rootdir,
     36 	rootdata,
     37 	2,
     38 	Nrootfiles
     39 };
     40 
     41 static Dirtab bootdir[Nbootfiles] = {
     42 	"boot",	{Qboot, 0, QTDIR},	0,		DMDIR|0555,
     43 };
     44 static uchar *bootdata[Nbootfiles];
     45 static Dirlist bootlist =
     46 {
     47 	Qboot,
     48 	bootdir,
     49 	bootdata,
     50 	1,
     51 	Nbootfiles
     52 };
     53 
     54 /*
     55  *  add a file to the list
     56  */
     57 static void
     58 addlist(Dirlist *l, char *name, uchar *contents, ulong len, int perm)
     59 {
     60 	Dirtab *d;
     61 
     62 	if(l->ndir >= l->mdir)
     63 		panic("too many root files");
     64 	l->data[l->ndir] = contents;
     65 	d = &l->dir[l->ndir];
     66 	strcpy(d->name, name);
     67 	d->length = len;
     68 	d->perm = perm;
     69 	d->qid.type = 0;
     70 	d->qid.vers = 0;
     71 	d->qid.path = ++l->ndir + l->base;
     72 	if(perm & DMDIR)
     73 		d->qid.type |= QTDIR;
     74 }
     75 
     76 /*
     77  *  add a root file
     78  */
     79 void
     80 addbootfile(char *name, uchar *contents, ulong len)
     81 {
     82 	addlist(&bootlist, name, contents, len, 0555);
     83 }
     84 
     85 /*
     86  *  add a root directory
     87  */
     88 static void
     89 addrootdir(char *name)
     90 {
     91 	addlist(&rootlist, name, nil, 0, DMDIR|0555);
     92 }
     93 
     94 static void
     95 rootreset(void)
     96 {
     97 	addrootdir("bin");
     98 	addrootdir("dev");
     99 	addrootdir("env");
    100 	addrootdir("fd");
    101 	addrootdir("mnt");
    102 	addrootdir("net");
    103 	addrootdir("net.alt");
    104 	addrootdir("proc");
    105 	addrootdir("root");
    106 	addrootdir("srv");
    107 }
    108 
    109 static Chan*
    110 rootattach(char *spec)
    111 {
    112 	return devattach('/', spec);
    113 }
    114 
    115 static int
    116 rootgen(Chan *c, char *name, Dirtab *dt, int i, int s, Dir *dp)
    117 {
    118 	int t;
    119 	Dirtab *d;
    120 	Dirlist *l;
    121 
    122 	switch((int)c->qid.path){
    123 	case Qdir:
    124 		if(s == DEVDOTDOT){
    125 			devdir(c, (Qid){Qdir, 0, QTDIR}, "#/", 0, eve, 0555, dp);
    126 			return 1;
    127 		}
    128 		return devgen(c, name, rootlist.dir, rootlist.ndir, s, dp);
    129 	case Qboot:
    130 		if(s == DEVDOTDOT){
    131 			devdir(c, (Qid){Qdir, 0, QTDIR}, "#/", 0, eve, 0555, dp);
    132 			return 1;
    133 		}
    134 		return devgen(c, name, bootlist.dir, bootlist.ndir, s, dp);
    135 	default:
    136 		if(s == DEVDOTDOT){
    137 			if((int)c->qid.path < Qboot)
    138 				devdir(c, (Qid){Qdir, 0, QTDIR}, "#/", 0, eve, 0555, dp);
    139 			else
    140 				devdir(c, (Qid){Qboot, 0, QTDIR}, "#/", 0, eve, 0555, dp);
    141 			return 1;
    142 		}
    143 		if(s != 0)
    144 			return -1;
    145 		if((int)c->qid.path < Qboot){
    146 			t = c->qid.path-1;
    147 			l = &rootlist;
    148 		}else{
    149 			t = c->qid.path - Qboot - 1;
    150 			l = &bootlist;
    151 		}
    152 		if(t >= l->ndir)
    153 			return -1;
    154 if(t < 0){
    155 print("rootgen %llud %d %d\n", c->qid.path, s, t);
    156 panic("whoops");
    157 }
    158 		d = &l->dir[t];
    159 		devdir(c, d->qid, d->name, d->length, eve, d->perm, dp);
    160 		return 1;
    161 	}
    162 }
    163 
    164 static Walkqid*
    165 rootwalk(Chan *c, Chan *nc, char **name, int nname)
    166 {
    167 	return devwalk(c,  nc, name, nname, nil, 0, rootgen);
    168 }
    169 
    170 static int
    171 rootstat(Chan *c, uchar *dp, int n)
    172 {
    173 	return devstat(c, dp, n, nil, 0, rootgen);
    174 }
    175 
    176 static Chan*
    177 rootopen(Chan *c, int omode)
    178 {
    179 	return devopen(c, omode, nil, 0, devgen);
    180 }
    181 
    182 /*
    183  * sysremove() knows this is a nop
    184  */
    185 static void
    186 rootclose(Chan *c)
    187 {
    188 }
    189 
    190 static long
    191 rootread(Chan *c, void *buf, long n, vlong off)
    192 {
    193 	ulong t;
    194 	Dirtab *d;
    195 	Dirlist *l;
    196 	uchar *data;
    197 	ulong offset = off;
    198 
    199 	t = c->qid.path;
    200 	switch(t){
    201 	case Qdir:
    202 	case Qboot:
    203 		return devdirread(c, buf, n, nil, 0, rootgen);
    204 	}
    205 
    206 	if(t<Qboot)
    207 		l = &rootlist;
    208 	else{
    209 		t -= Qboot;
    210 		l = &bootlist;
    211 	}
    212 
    213 	t--;
    214 	if(t >= l->ndir)
    215 		error(Egreg);
    216 
    217 	d = &l->dir[t];
    218 	data = l->data[t];
    219 	if(offset >= d->length)
    220 		return 0;
    221 	if(offset+n > d->length)
    222 		n = d->length - offset;
    223 #ifdef asdf
    224 print("[%d] kaddr %.8ulx base %.8ulx offset %ld (%.8ulx), n %d %.8ulx %.8ulx %.8ulx\n", 
    225 		t, buf, data, offset, offset, n,
    226 		((ulong*)(data+offset))[0],
    227 		((ulong*)(data+offset))[1],
    228 		((ulong*)(data+offset))[2]);
    229 #endif
    230 	memmove(buf, data+offset, n);
    231 	return n;
    232 }
    233 
    234 static long
    235 rootwrite(Chan *c, void *v, long l, vlong vl)
    236 {
    237 	error(Egreg);
    238 	return 0;
    239 }
    240 
    241 Dev rootdevtab = {
    242 	'/',
    243 	"root",
    244 
    245 	rootreset,
    246 	devinit,
    247 	devshutdown,
    248 	rootattach,
    249 	rootwalk,
    250 	rootstat,
    251 	rootopen,
    252 	devcreate,
    253 	rootclose,
    254 	rootread,
    255 	devbread,
    256 	rootwrite,
    257 	devbwrite,
    258 	devremove,
    259 	devwstat,
    260 };
    261