Blame


1 2277c5d7 2004-03-21 devnull #include "std.h"
2 2277c5d7 2004-03-21 devnull #include "dat.h"
3 2277c5d7 2004-03-21 devnull
4 2277c5d7 2004-03-21 devnull enum
5 2277c5d7 2004-03-21 devnull {
6 2277c5d7 2004-03-21 devnull Qroot,
7 2277c5d7 2004-03-21 devnull Qfactotum,
8 2277c5d7 2004-03-21 devnull Qrpc,
9 2277c5d7 2004-03-21 devnull Qkeylist,
10 2277c5d7 2004-03-21 devnull Qprotolist,
11 2277c5d7 2004-03-21 devnull Qconfirm,
12 2277c5d7 2004-03-21 devnull Qlog,
13 2277c5d7 2004-03-21 devnull Qctl,
14 2277c5d7 2004-03-21 devnull Qneedkey,
15 2277c5d7 2004-03-21 devnull Qconv,
16 2277c5d7 2004-03-21 devnull };
17 2277c5d7 2004-03-21 devnull
18 2277c5d7 2004-03-21 devnull Qid
19 2277c5d7 2004-03-21 devnull mkqid(int type, int path)
20 2277c5d7 2004-03-21 devnull {
21 2277c5d7 2004-03-21 devnull Qid q;
22 2277c5d7 2004-03-21 devnull
23 2277c5d7 2004-03-21 devnull q.type = type;
24 2277c5d7 2004-03-21 devnull q.path = path;
25 2277c5d7 2004-03-21 devnull q.vers = 0;
26 2277c5d7 2004-03-21 devnull return q;
27 2277c5d7 2004-03-21 devnull }
28 2277c5d7 2004-03-21 devnull
29 2277c5d7 2004-03-21 devnull static struct
30 2277c5d7 2004-03-21 devnull {
31 2277c5d7 2004-03-21 devnull char *name;
32 2277c5d7 2004-03-21 devnull int qidpath;
33 2277c5d7 2004-03-21 devnull ulong perm;
34 2277c5d7 2004-03-21 devnull } dirtab[] = {
35 2277c5d7 2004-03-21 devnull /* positions of confirm and needkey known below */
36 2277c5d7 2004-03-21 devnull "confirm", Qconfirm, 0600|DMEXCL,
37 2277c5d7 2004-03-21 devnull "needkey", Qneedkey, 0600|DMEXCL,
38 2277c5d7 2004-03-21 devnull "ctl", Qctl, 0600,
39 2277c5d7 2004-03-21 devnull "rpc", Qrpc, 0666,
40 2277c5d7 2004-03-21 devnull "proto", Qprotolist, 0444,
41 2277c5d7 2004-03-21 devnull "log", Qlog, 0600|DMEXCL,
42 2277c5d7 2004-03-21 devnull "conv", Qconv, 0400,
43 2277c5d7 2004-03-21 devnull };
44 2277c5d7 2004-03-21 devnull
45 2277c5d7 2004-03-21 devnull static void
46 2277c5d7 2004-03-21 devnull fillstat(Dir *dir, char *name, int type, int path, ulong perm)
47 2277c5d7 2004-03-21 devnull {
48 2277c5d7 2004-03-21 devnull dir->name = estrdup(name);
49 2277c5d7 2004-03-21 devnull dir->uid = estrdup(owner);
50 2277c5d7 2004-03-21 devnull dir->gid = estrdup(owner);
51 2277c5d7 2004-03-21 devnull dir->mode = perm;
52 2277c5d7 2004-03-21 devnull dir->length = 0;
53 2277c5d7 2004-03-21 devnull dir->qid = mkqid(type, path);
54 2277c5d7 2004-03-21 devnull dir->atime = time(0);
55 2277c5d7 2004-03-21 devnull dir->mtime = time(0);
56 2277c5d7 2004-03-21 devnull dir->muid = estrdup("");
57 2277c5d7 2004-03-21 devnull }
58 2277c5d7 2004-03-21 devnull
59 2277c5d7 2004-03-21 devnull static int
60 2277c5d7 2004-03-21 devnull rootdirgen(int n, Dir *dir, void *v)
61 2277c5d7 2004-03-21 devnull {
62 2277c5d7 2004-03-21 devnull USED(v);
63 2277c5d7 2004-03-21 devnull
64 2277c5d7 2004-03-21 devnull if(n > 0)
65 2277c5d7 2004-03-21 devnull return -1;
66 2277c5d7 2004-03-21 devnull
67 2277c5d7 2004-03-21 devnull fillstat(dir, factname, QTDIR, Qfactotum, DMDIR|0555);
68 2277c5d7 2004-03-21 devnull return 0;
69 2277c5d7 2004-03-21 devnull }
70 2277c5d7 2004-03-21 devnull
71 2277c5d7 2004-03-21 devnull static int
72 2277c5d7 2004-03-21 devnull fsdirgen(int n, Dir *dir, void *v)
73 2277c5d7 2004-03-21 devnull {
74 2277c5d7 2004-03-21 devnull USED(v);
75 2277c5d7 2004-03-21 devnull
76 2277c5d7 2004-03-21 devnull if(n >= nelem(dirtab))
77 2277c5d7 2004-03-21 devnull return -1;
78 2277c5d7 2004-03-21 devnull fillstat(dir, dirtab[n].name, 0, dirtab[n].qidpath, dirtab[n].perm);
79 2277c5d7 2004-03-21 devnull return 0;
80 2277c5d7 2004-03-21 devnull }
81 2277c5d7 2004-03-21 devnull
82 2277c5d7 2004-03-21 devnull static char*
83 2277c5d7 2004-03-21 devnull fswalk1(Fid *fid, char *name, Qid *qid)
84 2277c5d7 2004-03-21 devnull {
85 2277c5d7 2004-03-21 devnull int i;
86 2277c5d7 2004-03-21 devnull
87 2277c5d7 2004-03-21 devnull switch((int)fid->qid.path){
88 2277c5d7 2004-03-21 devnull default:
89 2277c5d7 2004-03-21 devnull return "fswalk1: cannot happen";
90 2277c5d7 2004-03-21 devnull case Qroot:
91 2277c5d7 2004-03-21 devnull if(strcmp(name, factname) == 0){
92 2277c5d7 2004-03-21 devnull *qid = mkqid(QTDIR, Qfactotum);
93 2277c5d7 2004-03-21 devnull fid->qid = *qid;
94 2277c5d7 2004-03-21 devnull return nil;
95 2277c5d7 2004-03-21 devnull }
96 2277c5d7 2004-03-21 devnull if(strcmp(name, "..") == 0){
97 2277c5d7 2004-03-21 devnull *qid = fid->qid;
98 2277c5d7 2004-03-21 devnull return nil;
99 2277c5d7 2004-03-21 devnull }
100 2277c5d7 2004-03-21 devnull return "not found";
101 2277c5d7 2004-03-21 devnull case Qfactotum:
102 2277c5d7 2004-03-21 devnull for(i=0; i<nelem(dirtab); i++)
103 2277c5d7 2004-03-21 devnull if(strcmp(name, dirtab[i].name) == 0){
104 2277c5d7 2004-03-21 devnull *qid = mkqid(0, dirtab[i].qidpath);
105 2277c5d7 2004-03-21 devnull fid->qid = *qid;
106 2277c5d7 2004-03-21 devnull return nil;
107 2277c5d7 2004-03-21 devnull }
108 2277c5d7 2004-03-21 devnull if(strcmp(name, "..") == 0){
109 2277c5d7 2004-03-21 devnull *qid = mkqid(QTDIR, Qroot);
110 2277c5d7 2004-03-21 devnull fid->qid = *qid;
111 2277c5d7 2004-03-21 devnull return nil;
112 2277c5d7 2004-03-21 devnull }
113 2277c5d7 2004-03-21 devnull return "not found";
114 2277c5d7 2004-03-21 devnull }
115 2277c5d7 2004-03-21 devnull }
116 2277c5d7 2004-03-21 devnull
117 2277c5d7 2004-03-21 devnull static void
118 2277c5d7 2004-03-21 devnull fsstat(Req *r)
119 2277c5d7 2004-03-21 devnull {
120 2277c5d7 2004-03-21 devnull int i, path;
121 2277c5d7 2004-03-21 devnull
122 2277c5d7 2004-03-21 devnull path = r->fid->qid.path;
123 2277c5d7 2004-03-21 devnull switch(path){
124 2277c5d7 2004-03-21 devnull case Qroot:
125 2277c5d7 2004-03-21 devnull fillstat(&r->d, "/", QTDIR, Qroot, 0555|DMDIR);
126 2277c5d7 2004-03-21 devnull break;
127 2277c5d7 2004-03-21 devnull case Qfactotum:
128 2277c5d7 2004-03-21 devnull fillstat(&r->d, "factotum", QTDIR, Qfactotum, 0555|DMDIR);
129 2277c5d7 2004-03-21 devnull break;
130 2277c5d7 2004-03-21 devnull default:
131 2277c5d7 2004-03-21 devnull for(i=0; i<nelem(dirtab); i++)
132 2277c5d7 2004-03-21 devnull if(dirtab[i].qidpath == path){
133 2277c5d7 2004-03-21 devnull fillstat(&r->d, dirtab[i].name, 0, dirtab[i].qidpath, dirtab[i].perm);
134 2277c5d7 2004-03-21 devnull goto Break2;
135 2277c5d7 2004-03-21 devnull }
136 2277c5d7 2004-03-21 devnull respond(r, "file not found");
137 2277c5d7 2004-03-21 devnull break;
138 2277c5d7 2004-03-21 devnull }
139 2277c5d7 2004-03-21 devnull Break2:
140 2277c5d7 2004-03-21 devnull respond(r, nil);
141 2277c5d7 2004-03-21 devnull }
142 2277c5d7 2004-03-21 devnull
143 2277c5d7 2004-03-21 devnull static int
144 2277c5d7 2004-03-21 devnull readlist(int off, int (*gen)(int, char*, uint), Req *r)
145 2277c5d7 2004-03-21 devnull {
146 2277c5d7 2004-03-21 devnull char *a, *ea;
147 2277c5d7 2004-03-21 devnull int n;
148 2277c5d7 2004-03-21 devnull
149 2277c5d7 2004-03-21 devnull a = r->ofcall.data;
150 2277c5d7 2004-03-21 devnull ea = a+r->ifcall.count;
151 2277c5d7 2004-03-21 devnull for(;;){
152 2277c5d7 2004-03-21 devnull n = (*gen)(off, a, ea-a);
153 2277c5d7 2004-03-21 devnull if(n == 0){
154 2277c5d7 2004-03-21 devnull r->ofcall.count = a - (char*)r->ofcall.data;
155 2277c5d7 2004-03-21 devnull return off;
156 2277c5d7 2004-03-21 devnull }
157 2277c5d7 2004-03-21 devnull a += n;
158 2277c5d7 2004-03-21 devnull off++;
159 2277c5d7 2004-03-21 devnull }
160 2277c5d7 2004-03-21 devnull return -1; /* not reached */
161 2277c5d7 2004-03-21 devnull }
162 2277c5d7 2004-03-21 devnull
163 2277c5d7 2004-03-21 devnull static int
164 2277c5d7 2004-03-21 devnull keylist(int i, char *a, uint nn)
165 2277c5d7 2004-03-21 devnull {
166 2277c5d7 2004-03-21 devnull int n;
167 2277c5d7 2004-03-21 devnull char buf[512];
168 2277c5d7 2004-03-21 devnull Key *k;
169 2277c5d7 2004-03-21 devnull
170 2277c5d7 2004-03-21 devnull if(i >= ring.nkey)
171 2277c5d7 2004-03-21 devnull return 0;
172 2277c5d7 2004-03-21 devnull
173 2277c5d7 2004-03-21 devnull k = ring.key[i];
174 2277c5d7 2004-03-21 devnull k->attr = sortattr(k->attr);
175 2277c5d7 2004-03-21 devnull n = snprint(buf, sizeof buf, "key %A %N\n", k->attr, k->privattr);
176 2277c5d7 2004-03-21 devnull if(n >= sizeof(buf)-5)
177 2277c5d7 2004-03-21 devnull strcpy(buf+sizeof(buf)-5, "...\n");
178 2277c5d7 2004-03-21 devnull n = strlen(buf);
179 2277c5d7 2004-03-21 devnull if(n > nn)
180 2277c5d7 2004-03-21 devnull return 0;
181 2277c5d7 2004-03-21 devnull memmove(a, buf, n);
182 2277c5d7 2004-03-21 devnull return n;
183 2277c5d7 2004-03-21 devnull }
184 2277c5d7 2004-03-21 devnull
185 2277c5d7 2004-03-21 devnull static int
186 2277c5d7 2004-03-21 devnull protolist(int i, char *a, uint n)
187 2277c5d7 2004-03-21 devnull {
188 2277c5d7 2004-03-21 devnull if(prototab[i] == nil)
189 2277c5d7 2004-03-21 devnull return 0;
190 2277c5d7 2004-03-21 devnull if(strlen(prototab[i]->name)+1 > n)
191 2277c5d7 2004-03-21 devnull return 0;
192 2277c5d7 2004-03-21 devnull n = strlen(prototab[i]->name)+1;
193 2277c5d7 2004-03-21 devnull memmove(a, prototab[i]->name, n-1);
194 2277c5d7 2004-03-21 devnull a[n-1] = '\n';
195 2277c5d7 2004-03-21 devnull return n;
196 2277c5d7 2004-03-21 devnull }
197 2277c5d7 2004-03-21 devnull
198 2277c5d7 2004-03-21 devnull /* BUG this is O(n^2) to fill in the list */
199 2277c5d7 2004-03-21 devnull static int
200 2277c5d7 2004-03-21 devnull convlist(int i, char *a, uint nn)
201 2277c5d7 2004-03-21 devnull {
202 2277c5d7 2004-03-21 devnull Conv *c;
203 2277c5d7 2004-03-21 devnull char buf[512];
204 2277c5d7 2004-03-21 devnull int n;
205 2277c5d7 2004-03-21 devnull
206 2277c5d7 2004-03-21 devnull for(c=conv; c && i-- > 0; c=c->next)
207 2277c5d7 2004-03-21 devnull ;
208 2277c5d7 2004-03-21 devnull
209 2277c5d7 2004-03-21 devnull if(c == nil)
210 2277c5d7 2004-03-21 devnull return 0;
211 2277c5d7 2004-03-21 devnull
212 2277c5d7 2004-03-21 devnull if(c->state)
213 2277c5d7 2004-03-21 devnull n = snprint(buf, sizeof buf, "conv state=%q %A\n", c->state, c->attr);
214 2277c5d7 2004-03-21 devnull else
215 2277c5d7 2004-03-21 devnull n = snprint(buf, sizeof buf, "conv state=closed err=%q\n", c->err);
216 2277c5d7 2004-03-21 devnull
217 2277c5d7 2004-03-21 devnull if(n >= sizeof(buf)-5)
218 2277c5d7 2004-03-21 devnull strcpy(buf+sizeof(buf)-5, "...\n");
219 2277c5d7 2004-03-21 devnull n = strlen(buf);
220 2277c5d7 2004-03-21 devnull if(n > nn)
221 2277c5d7 2004-03-21 devnull return 0;
222 2277c5d7 2004-03-21 devnull memmove(a, buf, n);
223 2277c5d7 2004-03-21 devnull return n;
224 2277c5d7 2004-03-21 devnull }
225 2277c5d7 2004-03-21 devnull
226 2277c5d7 2004-03-21 devnull static void
227 2277c5d7 2004-03-21 devnull fskickreply(Conv *c)
228 2277c5d7 2004-03-21 devnull {
229 2277c5d7 2004-03-21 devnull Req *r;
230 2277c5d7 2004-03-21 devnull
231 2277c5d7 2004-03-21 devnull if(c->hangup){
232 2277c5d7 2004-03-21 devnull if(c->req){
233 2277c5d7 2004-03-21 devnull respond(c->req, "hangup");
234 2277c5d7 2004-03-21 devnull c->req = nil;
235 2277c5d7 2004-03-21 devnull }
236 2277c5d7 2004-03-21 devnull return;
237 2277c5d7 2004-03-21 devnull }
238 2277c5d7 2004-03-21 devnull
239 2277c5d7 2004-03-21 devnull if(!c->req || !c->nreply)
240 2277c5d7 2004-03-21 devnull return;
241 2277c5d7 2004-03-21 devnull
242 2277c5d7 2004-03-21 devnull r = c->req;
243 2277c5d7 2004-03-21 devnull r->ofcall.count = c->nreply;
244 2277c5d7 2004-03-21 devnull r->ofcall.data = c->reply;
245 2277c5d7 2004-03-21 devnull if(r->ofcall.count > r->ifcall.count)
246 2277c5d7 2004-03-21 devnull r->ofcall.count = r->ifcall.count;
247 2277c5d7 2004-03-21 devnull respond(r, nil);
248 2277c5d7 2004-03-21 devnull c->req = nil;
249 2277c5d7 2004-03-21 devnull c->nreply = 0;
250 2277c5d7 2004-03-21 devnull }
251 2277c5d7 2004-03-21 devnull
252 2277c5d7 2004-03-21 devnull /*
253 2277c5d7 2004-03-21 devnull * Some of the file system work happens in the fs proc, but
254 2277c5d7 2004-03-21 devnull * fsopen, fsread, fswrite, fsdestroyfid, and fsflush happen in
255 2277c5d7 2004-03-21 devnull * the main proc so that they can access the various shared
256 2277c5d7 2004-03-21 devnull * data structures without worrying about locking.
257 2277c5d7 2004-03-21 devnull */
258 2277c5d7 2004-03-21 devnull static int inuse[nelem(dirtab)];
259 2277c5d7 2004-03-21 devnull int *confirminuse = &inuse[0];
260 2277c5d7 2004-03-21 devnull int *needkeyinuse = &inuse[1];
261 2277c5d7 2004-03-21 devnull static void
262 2277c5d7 2004-03-21 devnull fsopen(Req *r)
263 2277c5d7 2004-03-21 devnull {
264 2277c5d7 2004-03-21 devnull int i, *inusep, perm;
265 2277c5d7 2004-03-21 devnull static int need[4] = { 4, 2, 6, 1 };
266 2277c5d7 2004-03-21 devnull Conv *c;
267 2277c5d7 2004-03-21 devnull
268 2277c5d7 2004-03-21 devnull inusep = nil;
269 2277c5d7 2004-03-21 devnull perm = 5; /* directory */
270 2277c5d7 2004-03-21 devnull for(i=0; i<nelem(dirtab); i++)
271 2277c5d7 2004-03-21 devnull if(dirtab[i].qidpath == r->fid->qid.path){
272 2277c5d7 2004-03-21 devnull if(dirtab[i].perm & DMEXCL)
273 2277c5d7 2004-03-21 devnull inusep = &inuse[i];
274 2277c5d7 2004-03-21 devnull if(strcmp(r->fid->uid, owner) == 0)
275 2277c5d7 2004-03-21 devnull perm = dirtab[i].perm>>6;
276 2277c5d7 2004-03-21 devnull else
277 2277c5d7 2004-03-21 devnull perm = dirtab[i].perm;
278 2277c5d7 2004-03-21 devnull break;
279 2277c5d7 2004-03-21 devnull }
280 2277c5d7 2004-03-21 devnull
281 2277c5d7 2004-03-21 devnull if((r->ifcall.mode&~(OMASK|OTRUNC))
282 2277c5d7 2004-03-21 devnull || (need[r->ifcall.mode&3] & ~perm)){
283 2277c5d7 2004-03-21 devnull respond(r, "permission denied");
284 2277c5d7 2004-03-21 devnull return;
285 2277c5d7 2004-03-21 devnull }
286 2277c5d7 2004-03-21 devnull
287 2277c5d7 2004-03-21 devnull if(inusep){
288 2277c5d7 2004-03-21 devnull if(*inusep){
289 2277c5d7 2004-03-21 devnull respond(r, "file in use");
290 2277c5d7 2004-03-21 devnull return;
291 2277c5d7 2004-03-21 devnull }
292 2277c5d7 2004-03-21 devnull *inusep = 1;
293 2277c5d7 2004-03-21 devnull }
294 2277c5d7 2004-03-21 devnull
295 2277c5d7 2004-03-21 devnull if(r->fid->qid.path == Qrpc){
296 2277c5d7 2004-03-21 devnull if((c = convalloc(r->fid->uid)) == nil){
297 2277c5d7 2004-03-21 devnull char e[ERRMAX];
298 2277c5d7 2004-03-21 devnull
299 2277c5d7 2004-03-21 devnull rerrstr(e, sizeof e);
300 2277c5d7 2004-03-21 devnull respond(r, e);
301 2277c5d7 2004-03-21 devnull return;
302 2277c5d7 2004-03-21 devnull }
303 2277c5d7 2004-03-21 devnull c->kickreply = fskickreply;
304 2277c5d7 2004-03-21 devnull r->fid->aux = c;
305 2277c5d7 2004-03-21 devnull }
306 2277c5d7 2004-03-21 devnull
307 2277c5d7 2004-03-21 devnull respond(r, nil);
308 2277c5d7 2004-03-21 devnull }
309 2277c5d7 2004-03-21 devnull
310 2277c5d7 2004-03-21 devnull static void
311 2277c5d7 2004-03-21 devnull fsread(Req *r)
312 2277c5d7 2004-03-21 devnull {
313 2277c5d7 2004-03-21 devnull Conv *c;
314 2277c5d7 2004-03-21 devnull
315 2277c5d7 2004-03-21 devnull switch((int)r->fid->qid.path){
316 2277c5d7 2004-03-21 devnull default:
317 2277c5d7 2004-03-21 devnull respond(r, "fsread: cannot happen");
318 2277c5d7 2004-03-21 devnull break;
319 2277c5d7 2004-03-21 devnull case Qroot:
320 2277c5d7 2004-03-21 devnull dirread9p(r, rootdirgen, nil);
321 2277c5d7 2004-03-21 devnull respond(r, nil);
322 2277c5d7 2004-03-21 devnull break;
323 2277c5d7 2004-03-21 devnull case Qfactotum:
324 2277c5d7 2004-03-21 devnull dirread9p(r, fsdirgen, nil);
325 2277c5d7 2004-03-21 devnull respond(r, nil);
326 2277c5d7 2004-03-21 devnull break;
327 2277c5d7 2004-03-21 devnull case Qrpc:
328 2277c5d7 2004-03-21 devnull c = r->fid->aux;
329 2277c5d7 2004-03-21 devnull if(c->rpc.op == RpcUnknown){
330 2277c5d7 2004-03-21 devnull respond(r, "no rpc pending");
331 2277c5d7 2004-03-21 devnull break;
332 2277c5d7 2004-03-21 devnull }
333 2277c5d7 2004-03-21 devnull if(c->req){
334 2277c5d7 2004-03-21 devnull respond(r, "read already pending");
335 2277c5d7 2004-03-21 devnull break;
336 2277c5d7 2004-03-21 devnull }
337 2277c5d7 2004-03-21 devnull c->req = r;
338 2277c5d7 2004-03-21 devnull if(c->nreply)
339 2277c5d7 2004-03-21 devnull (*c->kickreply)(c);
340 2277c5d7 2004-03-21 devnull else
341 2277c5d7 2004-03-21 devnull rpcexec(c);
342 2277c5d7 2004-03-21 devnull break;
343 2277c5d7 2004-03-21 devnull case Qconfirm:
344 2277c5d7 2004-03-21 devnull confirmread(r);
345 2277c5d7 2004-03-21 devnull break;
346 2277c5d7 2004-03-21 devnull case Qlog:
347 2277c5d7 2004-03-21 devnull logread(r);
348 2277c5d7 2004-03-21 devnull break;
349 2277c5d7 2004-03-21 devnull case Qctl:
350 2277c5d7 2004-03-21 devnull r->fid->aux = (void*)readlist((int)r->fid->aux, keylist, r);
351 2277c5d7 2004-03-21 devnull respond(r, nil);
352 2277c5d7 2004-03-21 devnull break;
353 2277c5d7 2004-03-21 devnull case Qneedkey:
354 2277c5d7 2004-03-21 devnull needkeyread(r);
355 2277c5d7 2004-03-21 devnull break;
356 2277c5d7 2004-03-21 devnull case Qprotolist:
357 2277c5d7 2004-03-21 devnull r->fid->aux = (void*)readlist((int)r->fid->aux, protolist, r);
358 2277c5d7 2004-03-21 devnull respond(r, nil);
359 2277c5d7 2004-03-21 devnull break;
360 2277c5d7 2004-03-21 devnull case Qconv:
361 2277c5d7 2004-03-21 devnull r->fid->aux = (void*)readlist((int)r->fid->aux, convlist, r);
362 2277c5d7 2004-03-21 devnull respond(r, nil);
363 2277c5d7 2004-03-21 devnull break;
364 2277c5d7 2004-03-21 devnull }
365 2277c5d7 2004-03-21 devnull }
366 2277c5d7 2004-03-21 devnull
367 2277c5d7 2004-03-21 devnull static void
368 2277c5d7 2004-03-21 devnull fswrite(Req *r)
369 2277c5d7 2004-03-21 devnull {
370 2277c5d7 2004-03-21 devnull int ret;
371 2277c5d7 2004-03-21 devnull char err[ERRMAX], *s;
372 2277c5d7 2004-03-21 devnull int (*strfn)(char*);
373 2277c5d7 2004-03-21 devnull
374 2277c5d7 2004-03-21 devnull switch((int)r->fid->qid.path){
375 2277c5d7 2004-03-21 devnull default:
376 2277c5d7 2004-03-21 devnull respond(r, "fswrite: cannot happen");
377 2277c5d7 2004-03-21 devnull break;
378 2277c5d7 2004-03-21 devnull case Qrpc:
379 2277c5d7 2004-03-21 devnull if(rpcwrite(r->fid->aux, r->ifcall.data, r->ifcall.count) < 0){
380 2277c5d7 2004-03-21 devnull rerrstr(err, sizeof err);
381 2277c5d7 2004-03-21 devnull respond(r, err);
382 2277c5d7 2004-03-21 devnull }else{
383 2277c5d7 2004-03-21 devnull r->ofcall.count = r->ifcall.count;
384 2277c5d7 2004-03-21 devnull respond(r, nil);
385 2277c5d7 2004-03-21 devnull }
386 2277c5d7 2004-03-21 devnull break;
387 2277c5d7 2004-03-21 devnull case Qneedkey:
388 2277c5d7 2004-03-21 devnull strfn = needkeywrite;
389 2277c5d7 2004-03-21 devnull goto string;
390 2277c5d7 2004-03-21 devnull case Qctl:
391 2277c5d7 2004-03-21 devnull strfn = ctlwrite;
392 2277c5d7 2004-03-21 devnull goto string;
393 2277c5d7 2004-03-21 devnull case Qconfirm:
394 2277c5d7 2004-03-21 devnull strfn = confirmwrite;
395 2277c5d7 2004-03-21 devnull string:
396 2277c5d7 2004-03-21 devnull s = emalloc(r->ifcall.count+1);
397 2277c5d7 2004-03-21 devnull memmove(s, r->ifcall.data, r->ifcall.count);
398 2277c5d7 2004-03-21 devnull s[r->ifcall.count] = '\0';
399 2277c5d7 2004-03-21 devnull ret = (*strfn)(s);
400 2277c5d7 2004-03-21 devnull free(s);
401 2277c5d7 2004-03-21 devnull if(ret < 0){
402 2277c5d7 2004-03-21 devnull rerrstr(err, sizeof err);
403 2277c5d7 2004-03-21 devnull respond(r, err);
404 2277c5d7 2004-03-21 devnull }else{
405 2277c5d7 2004-03-21 devnull r->ofcall.count = r->ifcall.count;
406 2277c5d7 2004-03-21 devnull respond(r, nil);
407 2277c5d7 2004-03-21 devnull }
408 2277c5d7 2004-03-21 devnull break;
409 2277c5d7 2004-03-21 devnull }
410 2277c5d7 2004-03-21 devnull }
411 2277c5d7 2004-03-21 devnull
412 2277c5d7 2004-03-21 devnull static void
413 2277c5d7 2004-03-21 devnull fsflush(Req *r)
414 2277c5d7 2004-03-21 devnull {
415 2277c5d7 2004-03-21 devnull confirmflush(r);
416 2277c5d7 2004-03-21 devnull logflush(r);
417 2277c5d7 2004-03-21 devnull }
418 2277c5d7 2004-03-21 devnull
419 2277c5d7 2004-03-21 devnull static void
420 2277c5d7 2004-03-21 devnull fsdestroyfid(Fid *fid)
421 2277c5d7 2004-03-21 devnull {
422 2277c5d7 2004-03-21 devnull if(fid->qid.path == Qrpc){
423 2277c5d7 2004-03-21 devnull convhangup(fid->aux);
424 2277c5d7 2004-03-21 devnull convclose(fid->aux);
425 2277c5d7 2004-03-21 devnull }
426 2277c5d7 2004-03-21 devnull }
427 2277c5d7 2004-03-21 devnull
428 2277c5d7 2004-03-21 devnull static Channel *creq;
429 2277c5d7 2004-03-21 devnull static Channel *cfid, *cfidr;
430 2277c5d7 2004-03-21 devnull
431 2277c5d7 2004-03-21 devnull static void
432 2277c5d7 2004-03-21 devnull fsreqthread(void *v)
433 2277c5d7 2004-03-21 devnull {
434 2277c5d7 2004-03-21 devnull Req *r;
435 2277c5d7 2004-03-21 devnull
436 2277c5d7 2004-03-21 devnull USED(v);
437 2277c5d7 2004-03-21 devnull
438 2277c5d7 2004-03-21 devnull creq = chancreate(sizeof(Req*), 0);
439 2277c5d7 2004-03-21 devnull
440 2277c5d7 2004-03-21 devnull while((r = recvp(creq)) != nil){
441 2277c5d7 2004-03-21 devnull switch(r->ifcall.type){
442 2277c5d7 2004-03-21 devnull default:
443 2277c5d7 2004-03-21 devnull respond(r, "bug in fsreqthread");
444 2277c5d7 2004-03-21 devnull break;
445 2277c5d7 2004-03-21 devnull case Topen:
446 2277c5d7 2004-03-21 devnull fsopen(r);
447 2277c5d7 2004-03-21 devnull break;
448 2277c5d7 2004-03-21 devnull case Tread:
449 2277c5d7 2004-03-21 devnull fsread(r);
450 2277c5d7 2004-03-21 devnull break;
451 2277c5d7 2004-03-21 devnull case Twrite:
452 2277c5d7 2004-03-21 devnull fswrite(r);
453 2277c5d7 2004-03-21 devnull break;
454 2277c5d7 2004-03-21 devnull case Tflush:
455 2277c5d7 2004-03-21 devnull fsflush(r);
456 2277c5d7 2004-03-21 devnull break;
457 2277c5d7 2004-03-21 devnull }
458 2277c5d7 2004-03-21 devnull }
459 2277c5d7 2004-03-21 devnull }
460 2277c5d7 2004-03-21 devnull
461 2277c5d7 2004-03-21 devnull static void
462 2277c5d7 2004-03-21 devnull fsclunkthread(void *v)
463 2277c5d7 2004-03-21 devnull {
464 2277c5d7 2004-03-21 devnull Fid *f;
465 2277c5d7 2004-03-21 devnull
466 2277c5d7 2004-03-21 devnull USED(v);
467 2277c5d7 2004-03-21 devnull cfid = chancreate(sizeof(Fid*), 0);
468 2277c5d7 2004-03-21 devnull cfidr = chancreate(sizeof(Fid*), 0);
469 2277c5d7 2004-03-21 devnull
470 2277c5d7 2004-03-21 devnull while((f = recvp(cfid)) != nil){
471 2277c5d7 2004-03-21 devnull fsdestroyfid(f);
472 2277c5d7 2004-03-21 devnull sendp(cfidr, 0);
473 2277c5d7 2004-03-21 devnull }
474 2277c5d7 2004-03-21 devnull }
475 2277c5d7 2004-03-21 devnull
476 2277c5d7 2004-03-21 devnull static void
477 2277c5d7 2004-03-21 devnull fsproc(void *v)
478 2277c5d7 2004-03-21 devnull {
479 2277c5d7 2004-03-21 devnull USED(v);
480 2277c5d7 2004-03-21 devnull
481 2277c5d7 2004-03-21 devnull threadcreate(fsreqthread, nil, STACK);
482 2277c5d7 2004-03-21 devnull threadcreate(fsclunkthread, nil, STACK);
483 2277c5d7 2004-03-21 devnull threadexits(nil);
484 2277c5d7 2004-03-21 devnull }
485 2277c5d7 2004-03-21 devnull
486 2277c5d7 2004-03-21 devnull static void
487 2277c5d7 2004-03-21 devnull fsattach(Req *r)
488 2277c5d7 2004-03-21 devnull {
489 2277c5d7 2004-03-21 devnull static int first = 1;
490 2277c5d7 2004-03-21 devnull
491 2277c5d7 2004-03-21 devnull if(first){
492 2277c5d7 2004-03-21 devnull proccreate(fsproc, nil, STACK);
493 2277c5d7 2004-03-21 devnull first = 0;
494 2277c5d7 2004-03-21 devnull }
495 2277c5d7 2004-03-21 devnull
496 2277c5d7 2004-03-21 devnull r->fid->qid = mkqid(QTDIR, Qroot);
497 2277c5d7 2004-03-21 devnull r->ofcall.qid = r->fid->qid;
498 2277c5d7 2004-03-21 devnull respond(r, nil);
499 2277c5d7 2004-03-21 devnull }
500 2277c5d7 2004-03-21 devnull
501 2277c5d7 2004-03-21 devnull static void
502 2277c5d7 2004-03-21 devnull fssend(Req *r)
503 2277c5d7 2004-03-21 devnull {
504 2277c5d7 2004-03-21 devnull sendp(creq, r);
505 2277c5d7 2004-03-21 devnull }
506 2277c5d7 2004-03-21 devnull
507 2277c5d7 2004-03-21 devnull static void
508 2277c5d7 2004-03-21 devnull fssendclunk(Fid *f)
509 2277c5d7 2004-03-21 devnull {
510 2277c5d7 2004-03-21 devnull sendp(cfid, f);
511 2277c5d7 2004-03-21 devnull recvp(cfidr);
512 2277c5d7 2004-03-21 devnull }
513 2277c5d7 2004-03-21 devnull
514 2277c5d7 2004-03-21 devnull Srv fs = {
515 2277c5d7 2004-03-21 devnull .attach= fsattach,
516 2277c5d7 2004-03-21 devnull .walk1= fswalk1,
517 2277c5d7 2004-03-21 devnull .open= fssend,
518 2277c5d7 2004-03-21 devnull .read= fssend,
519 2277c5d7 2004-03-21 devnull .write= fssend,
520 2277c5d7 2004-03-21 devnull .stat= fsstat,
521 2277c5d7 2004-03-21 devnull .flush= fssend,
522 2277c5d7 2004-03-21 devnull .destroyfid= fssendclunk,
523 2277c5d7 2004-03-21 devnull };
524 2277c5d7 2004-03-21 devnull