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