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