1*74a4d8c2SCharles.Forsyth #include "u.h"
2*74a4d8c2SCharles.Forsyth #include "../port/lib.h"
3*74a4d8c2SCharles.Forsyth #include "mem.h"
4*74a4d8c2SCharles.Forsyth #include "dat.h"
5*74a4d8c2SCharles.Forsyth #include "fns.h"
6*74a4d8c2SCharles.Forsyth #include "../port/error.h"
7*74a4d8c2SCharles.Forsyth
8*74a4d8c2SCharles.Forsyth extern Rootdata rootdata[];
9*74a4d8c2SCharles.Forsyth extern Dirtab roottab[];
10*74a4d8c2SCharles.Forsyth extern int rootmaxq;
11*74a4d8c2SCharles.Forsyth
12*74a4d8c2SCharles.Forsyth static Chan*
rootattach(char * spec)13*74a4d8c2SCharles.Forsyth rootattach(char *spec)
14*74a4d8c2SCharles.Forsyth {
15*74a4d8c2SCharles.Forsyth int i;
16*74a4d8c2SCharles.Forsyth ulong len;
17*74a4d8c2SCharles.Forsyth Rootdata *r;
18*74a4d8c2SCharles.Forsyth
19*74a4d8c2SCharles.Forsyth if(*spec)
20*74a4d8c2SCharles.Forsyth error(Ebadspec);
21*74a4d8c2SCharles.Forsyth for (i = 0; i < rootmaxq; i++){
22*74a4d8c2SCharles.Forsyth r = &rootdata[i];
23*74a4d8c2SCharles.Forsyth if (r->sizep){
24*74a4d8c2SCharles.Forsyth len = *r->sizep;
25*74a4d8c2SCharles.Forsyth r->size = len;
26*74a4d8c2SCharles.Forsyth roottab[i].length = len;
27*74a4d8c2SCharles.Forsyth }
28*74a4d8c2SCharles.Forsyth }
29*74a4d8c2SCharles.Forsyth return devattach('/', spec);
30*74a4d8c2SCharles.Forsyth }
31*74a4d8c2SCharles.Forsyth
32*74a4d8c2SCharles.Forsyth static int
rootgen(Chan * c,char * name,Dirtab * tab,int nd,int s,Dir * dp)33*74a4d8c2SCharles.Forsyth rootgen(Chan *c, char *name, Dirtab *tab, int nd, int s, Dir *dp)
34*74a4d8c2SCharles.Forsyth {
35*74a4d8c2SCharles.Forsyth int p, i;
36*74a4d8c2SCharles.Forsyth Rootdata *r;
37*74a4d8c2SCharles.Forsyth
38*74a4d8c2SCharles.Forsyth if(s == DEVDOTDOT){
39*74a4d8c2SCharles.Forsyth p = rootdata[c->qid.path].dotdot;
40*74a4d8c2SCharles.Forsyth c->qid.path = p;
41*74a4d8c2SCharles.Forsyth c->qid.type = QTDIR;
42*74a4d8c2SCharles.Forsyth name = "#/";
43*74a4d8c2SCharles.Forsyth if(p != 0){
44*74a4d8c2SCharles.Forsyth for(i = 0; i < rootmaxq; i++)
45*74a4d8c2SCharles.Forsyth if(roottab[i].qid.path == c->qid.path){
46*74a4d8c2SCharles.Forsyth name = roottab[i].name;
47*74a4d8c2SCharles.Forsyth break;
48*74a4d8c2SCharles.Forsyth }
49*74a4d8c2SCharles.Forsyth }
50*74a4d8c2SCharles.Forsyth devdir(c, c->qid, name, 0, eve, 0555, dp);
51*74a4d8c2SCharles.Forsyth return 1;
52*74a4d8c2SCharles.Forsyth }
53*74a4d8c2SCharles.Forsyth if(name != nil){
54*74a4d8c2SCharles.Forsyth isdir(c);
55*74a4d8c2SCharles.Forsyth r = &rootdata[(int)c->qid.path];
56*74a4d8c2SCharles.Forsyth tab = r->ptr;
57*74a4d8c2SCharles.Forsyth for(i=0; i<r->size; i++, tab++)
58*74a4d8c2SCharles.Forsyth if(strcmp(tab->name, name) == 0){
59*74a4d8c2SCharles.Forsyth devdir(c, tab->qid, tab->name, tab->length, eve, tab->perm, dp);
60*74a4d8c2SCharles.Forsyth return 1;
61*74a4d8c2SCharles.Forsyth }
62*74a4d8c2SCharles.Forsyth return -1;
63*74a4d8c2SCharles.Forsyth }
64*74a4d8c2SCharles.Forsyth if(s >= nd)
65*74a4d8c2SCharles.Forsyth return -1;
66*74a4d8c2SCharles.Forsyth tab += s;
67*74a4d8c2SCharles.Forsyth devdir(c, tab->qid, tab->name, tab->length, eve, tab->perm, dp);
68*74a4d8c2SCharles.Forsyth return 1;
69*74a4d8c2SCharles.Forsyth }
70*74a4d8c2SCharles.Forsyth
71*74a4d8c2SCharles.Forsyth static Walkqid*
rootwalk(Chan * c,Chan * nc,char ** name,int nname)72*74a4d8c2SCharles.Forsyth rootwalk(Chan *c, Chan *nc, char **name, int nname)
73*74a4d8c2SCharles.Forsyth {
74*74a4d8c2SCharles.Forsyth ulong p;
75*74a4d8c2SCharles.Forsyth
76*74a4d8c2SCharles.Forsyth p = c->qid.path;
77*74a4d8c2SCharles.Forsyth if(nname == 0)
78*74a4d8c2SCharles.Forsyth p = rootdata[p].dotdot;
79*74a4d8c2SCharles.Forsyth return devwalk(c, nc, name, nname, rootdata[p].ptr, rootdata[p].size, rootgen);
80*74a4d8c2SCharles.Forsyth }
81*74a4d8c2SCharles.Forsyth
82*74a4d8c2SCharles.Forsyth static int
rootstat(Chan * c,uchar * dp,int n)83*74a4d8c2SCharles.Forsyth rootstat(Chan *c, uchar *dp, int n)
84*74a4d8c2SCharles.Forsyth {
85*74a4d8c2SCharles.Forsyth int p;
86*74a4d8c2SCharles.Forsyth
87*74a4d8c2SCharles.Forsyth p = rootdata[c->qid.path].dotdot;
88*74a4d8c2SCharles.Forsyth return devstat(c, dp, n, rootdata[p].ptr, rootdata[p].size, rootgen);
89*74a4d8c2SCharles.Forsyth }
90*74a4d8c2SCharles.Forsyth
91*74a4d8c2SCharles.Forsyth static Chan*
rootopen(Chan * c,int omode)92*74a4d8c2SCharles.Forsyth rootopen(Chan *c, int omode)
93*74a4d8c2SCharles.Forsyth {
94*74a4d8c2SCharles.Forsyth int p;
95*74a4d8c2SCharles.Forsyth
96*74a4d8c2SCharles.Forsyth p = rootdata[c->qid.path].dotdot;
97*74a4d8c2SCharles.Forsyth return devopen(c, omode, rootdata[p].ptr, rootdata[p].size, rootgen);
98*74a4d8c2SCharles.Forsyth }
99*74a4d8c2SCharles.Forsyth
100*74a4d8c2SCharles.Forsyth /*
101*74a4d8c2SCharles.Forsyth * sysremove() knows this is a nop
102*74a4d8c2SCharles.Forsyth */
103*74a4d8c2SCharles.Forsyth static void
rootclose(Chan *)104*74a4d8c2SCharles.Forsyth rootclose(Chan*)
105*74a4d8c2SCharles.Forsyth {
106*74a4d8c2SCharles.Forsyth }
107*74a4d8c2SCharles.Forsyth
108*74a4d8c2SCharles.Forsyth static long
rootread(Chan * c,void * buf,long n,vlong offset)109*74a4d8c2SCharles.Forsyth rootread(Chan *c, void *buf, long n, vlong offset)
110*74a4d8c2SCharles.Forsyth {
111*74a4d8c2SCharles.Forsyth ulong p, len;
112*74a4d8c2SCharles.Forsyth uchar *data;
113*74a4d8c2SCharles.Forsyth
114*74a4d8c2SCharles.Forsyth p = c->qid.path;
115*74a4d8c2SCharles.Forsyth if(c->qid.type & QTDIR)
116*74a4d8c2SCharles.Forsyth return devdirread(c, buf, n, rootdata[p].ptr, rootdata[p].size, rootgen);
117*74a4d8c2SCharles.Forsyth len = rootdata[p].size;
118*74a4d8c2SCharles.Forsyth if(offset < 0 || offset >= len)
119*74a4d8c2SCharles.Forsyth return 0;
120*74a4d8c2SCharles.Forsyth if(offset+n > len)
121*74a4d8c2SCharles.Forsyth n = len - offset;
122*74a4d8c2SCharles.Forsyth data = rootdata[p].ptr;
123*74a4d8c2SCharles.Forsyth memmove(buf, data+offset, n);
124*74a4d8c2SCharles.Forsyth return n;
125*74a4d8c2SCharles.Forsyth }
126*74a4d8c2SCharles.Forsyth
127*74a4d8c2SCharles.Forsyth static long
rootwrite(Chan *,void *,long,vlong)128*74a4d8c2SCharles.Forsyth rootwrite(Chan*, void*, long, vlong)
129*74a4d8c2SCharles.Forsyth {
130*74a4d8c2SCharles.Forsyth error(Eperm);
131*74a4d8c2SCharles.Forsyth return 0;
132*74a4d8c2SCharles.Forsyth }
133*74a4d8c2SCharles.Forsyth
134*74a4d8c2SCharles.Forsyth Dev rootdevtab = {
135*74a4d8c2SCharles.Forsyth '/',
136*74a4d8c2SCharles.Forsyth "root",
137*74a4d8c2SCharles.Forsyth
138*74a4d8c2SCharles.Forsyth devreset,
139*74a4d8c2SCharles.Forsyth devinit,
140*74a4d8c2SCharles.Forsyth devshutdown,
141*74a4d8c2SCharles.Forsyth rootattach,
142*74a4d8c2SCharles.Forsyth rootwalk,
143*74a4d8c2SCharles.Forsyth rootstat,
144*74a4d8c2SCharles.Forsyth rootopen,
145*74a4d8c2SCharles.Forsyth devcreate,
146*74a4d8c2SCharles.Forsyth rootclose,
147*74a4d8c2SCharles.Forsyth rootread,
148*74a4d8c2SCharles.Forsyth devbread,
149*74a4d8c2SCharles.Forsyth rootwrite,
150*74a4d8c2SCharles.Forsyth devbwrite,
151*74a4d8c2SCharles.Forsyth devremove,
152*74a4d8c2SCharles.Forsyth devwstat,
153*74a4d8c2SCharles.Forsyth };
154