]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/port/devroot.c
bind devshr to /shr
[plan9front.git] / sys / src / 9 / port / devroot.c
1 #include        "u.h"
2 #include        "../port/lib.h"
3 #include        "mem.h"
4 #include        "dat.h"
5 #include        "fns.h"
6 #include        "../port/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         addrootdir("shr");
108 }
109
110 static Chan*
111 rootattach(char *spec)
112 {
113         return devattach('/', spec);
114 }
115
116 static int
117 rootgen(Chan *c, char *name, Dirtab*, int, int s, Dir *dp)
118 {
119         int t;
120         Dirtab *d;
121         Dirlist *l;
122
123         switch((int)c->qid.path){
124         case Qdir:
125                 if(s == DEVDOTDOT){
126                         devdir(c, (Qid){Qdir, 0, QTDIR}, "#/", 0, eve, 0555, dp);
127                         return 1;
128                 }
129                 return devgen(c, name, rootlist.dir, rootlist.ndir, s, dp);
130         case Qboot:
131                 if(s == DEVDOTDOT){
132                         devdir(c, (Qid){Qdir, 0, QTDIR}, "#/", 0, eve, 0555, dp);
133                         return 1;
134                 }
135                 return devgen(c, name, bootlist.dir, bootlist.ndir, s, dp);
136         default:
137                 if(s == DEVDOTDOT){
138                         if((int)c->qid.path < Qboot)
139                                 devdir(c, (Qid){Qdir, 0, QTDIR}, "#/", 0, eve, 0555, dp);
140                         else
141                                 devdir(c, (Qid){Qboot, 0, QTDIR}, "#/", 0, eve, 0555, dp);
142                         return 1;
143                 }
144                 if(s != 0)
145                         return -1;
146                 if((int)c->qid.path < Qboot){
147                         t = c->qid.path-1;
148                         l = &rootlist;
149                 }else{
150                         t = c->qid.path - Qboot - 1;
151                         l = &bootlist;
152                 }
153                 if(t >= l->ndir)
154                         return -1;
155 if(t < 0){
156 print("rootgen %llud %d %d\n", c->qid.path, s, t);
157 panic("whoops");
158 }
159                 d = &l->dir[t];
160                 devdir(c, d->qid, d->name, d->length, eve, d->perm, dp);
161                 return 1;
162         }
163 }
164
165 static Walkqid*
166 rootwalk(Chan *c, Chan *nc, char **name, int nname)
167 {
168         return devwalk(c,  nc, name, nname, nil, 0, rootgen);
169 }
170
171 static int
172 rootstat(Chan *c, uchar *dp, int n)
173 {
174         return devstat(c, dp, n, nil, 0, rootgen);
175 }
176
177 static Chan*
178 rootopen(Chan *c, int omode)
179 {
180         return devopen(c, omode, nil, 0, devgen);
181 }
182
183 /*
184  * sysremove() knows this is a nop
185  */
186 static void
187 rootclose(Chan*)
188 {
189 }
190
191 static long
192 rootread(Chan *c, void *buf, long n, vlong off)
193 {
194         ulong t;
195         Dirtab *d;
196         Dirlist *l;
197         uchar *data;
198         ulong offset = off;
199
200         t = c->qid.path;
201         switch(t){
202         case Qdir:
203         case Qboot:
204                 return devdirread(c, buf, n, nil, 0, rootgen);
205         }
206
207         if(t<Qboot)
208                 l = &rootlist;
209         else{
210                 t -= Qboot;
211                 l = &bootlist;
212         }
213
214         t--;
215         if(t >= l->ndir)
216                 error(Egreg);
217
218         d = &l->dir[t];
219         data = l->data[t];
220         if(offset >= d->length)
221                 return 0;
222         if(offset+n > d->length)
223                 n = d->length - offset;
224 #ifdef asdf
225 print("[%d] kaddr %.8ulx base %.8ulx offset %ld (%.8ulx), n %d %.8ulx %.8ulx %.8ulx\n", 
226                 t, buf, data, offset, offset, n,
227                 ((ulong*)(data+offset))[0],
228                 ((ulong*)(data+offset))[1],
229                 ((ulong*)(data+offset))[2]);
230 #endif asdf
231         memmove(buf, data+offset, n);
232         return n;
233 }
234
235 static long
236 rootwrite(Chan*, void*, long, vlong)
237 {
238         error(Egreg);
239         return 0;
240 }
241
242 Dev rootdevtab = {
243         '/',
244         "root",
245
246         rootreset,
247         devinit,
248         devshutdown,
249         rootattach,
250         rootwalk,
251         rootstat,
252         rootopen,
253         devcreate,
254         rootclose,
255         rootread,
256         devbread,
257         rootwrite,
258         devbwrite,
259         devremove,
260         devwstat,
261 };
262