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