Idenfity devices by name, not by char [1/3]
[akaros.git] / kern / src / ns / convM2S.c
1 // INFERNO
2 #include <vfs.h>
3 #include <kfs.h>
4 #include <slab.h>
5 #include <kmalloc.h>
6 #include <kref.h>
7 #include <string.h>
8 #include <stdio.h>
9 #include <assert.h>
10 #include <error.h>
11 #include <cpio.h>
12 #include <pmap.h>
13 #include <smp.h>
14 #include <ip.h>
15
16 static
17 uint8_t *gstring(uint8_t * p, uint8_t * ep, char **s)
18 {
19         unsigned int n;
20
21         if (p + BIT16SZ > ep)
22                 return NULL;
23         n = GBIT16(p);
24         p += BIT16SZ - 1;
25         if (p + n + 1 > ep)
26                 return NULL;
27         /* move it down, on top of count, to make room for '\0' */
28         memmove(p, p + 1, n);
29         p[n] = '\0';
30         *s = (char *)p;
31         p += n + 1;
32         return p;
33 }
34
35 static
36 uint8_t *gqid(uint8_t * p, uint8_t * ep, struct qid *q)
37 {
38         if (p + QIDSZ > ep)
39                 return NULL;
40         q->type = GBIT8(p);
41         p += BIT8SZ;
42         q->vers = GBIT32(p);
43         p += BIT32SZ;
44         q->path = GBIT64(p);
45         p += BIT64SZ;
46         return p;
47 }
48
49 void init_empty_dir(struct dir *d)
50 {
51         d->type = ~0;
52         d->dev = ~0;
53         d->qid.path = ~0;
54         d->qid.vers = ~0;
55         d->qid.type = ~0;
56         d->mode = ~0;
57         d->atime = ~0;
58         d->mtime = ~0;
59         d->length = ~0;
60         d->name = "";
61         d->uid = "";
62         d->gid = "";
63         d->muid = "";
64 }
65
66 /*
67  * no syntactic checks.
68  * three causes for error:
69  *  1. message size field is incorrect
70  *  2. input buffer too short for its own data (counts too long, etc.)
71  *  3. too many names or qids
72  * gqid() and gstring() return NULL if they would reach beyond buffer.
73  * main switch statement checks range and also can fall through
74  * to test at end of routine.
75  */
76 unsigned int convM2S(uint8_t * ap, unsigned int nap, struct fcall *f)
77 {
78         uint8_t *p, *ep;
79         unsigned int i, size;
80
81         p = ap;
82         ep = p + nap;
83
84         if (p + BIT32SZ + BIT8SZ + BIT16SZ > ep)
85                 return 0;
86         size = GBIT32(p);
87         p += BIT32SZ;
88
89         if (size < BIT32SZ + BIT8SZ + BIT16SZ)
90                 return 0;
91
92         f->type = GBIT8(p);
93         p += BIT8SZ;
94         f->tag = GBIT16(p);
95         p += BIT16SZ;
96
97         switch (f->type) {
98                 default:
99                         return 0;
100
101                 case Tversion:
102                         if (p + BIT32SZ > ep)
103                                 return 0;
104                         f->msize = GBIT32(p);
105                         p += BIT32SZ;
106                         p = gstring(p, ep, &f->version);
107                         break;
108
109                 case Tflush:
110                         if (p + BIT16SZ > ep)
111                                 return 0;
112                         f->oldtag = GBIT16(p);
113                         p += BIT16SZ;
114                         break;
115
116                 case Tauth:
117                         if (p + BIT32SZ > ep)
118                                 return 0;
119                         f->afid = GBIT32(p);
120                         p += BIT32SZ;
121                         p = gstring(p, ep, &f->uname);
122                         if (p == NULL)
123                                 break;
124                         p = gstring(p, ep, &f->aname);
125                         if (p == NULL)
126                                 break;
127                         break;
128
129                 case Tattach:
130                         if (p + BIT32SZ > ep)
131                                 return 0;
132                         f->fid = GBIT32(p);
133                         p += BIT32SZ;
134                         if (p + BIT32SZ > ep)
135                                 return 0;
136                         f->afid = GBIT32(p);
137                         p += BIT32SZ;
138                         p = gstring(p, ep, &f->uname);
139                         if (p == NULL)
140                                 break;
141                         p = gstring(p, ep, &f->aname);
142                         if (p == NULL)
143                                 break;
144                         break;
145
146                 case Twalk:
147                         if (p + BIT32SZ + BIT32SZ + BIT16SZ > ep)
148                                 return 0;
149                         f->fid = GBIT32(p);
150                         p += BIT32SZ;
151                         f->newfid = GBIT32(p);
152                         p += BIT32SZ;
153                         f->nwname = GBIT16(p);
154                         p += BIT16SZ;
155                         if (f->nwname > MAXWELEM)
156                                 return 0;
157                         for (i = 0; i < f->nwname; i++) {
158                                 p = gstring(p, ep, &f->wname[i]);
159                                 if (p == NULL)
160                                         break;
161                         }
162                         break;
163
164                 case Topen:
165                         if (p + BIT32SZ + BIT8SZ > ep)
166                                 return 0;
167                         f->fid = GBIT32(p);
168                         p += BIT32SZ;
169                         f->mode = GBIT8(p);
170                         p += BIT8SZ;
171                         break;
172
173                 case Tcreate:
174                         if (p + BIT32SZ > ep)
175                                 return 0;
176                         f->fid = GBIT32(p);
177                         p += BIT32SZ;
178                         p = gstring(p, ep, &f->name);
179                         if (p == NULL)
180                                 break;
181                         if (p + BIT32SZ + BIT8SZ > ep)
182                                 return 0;
183                         f->perm = GBIT32(p);
184                         p += BIT32SZ;
185                         f->mode = GBIT8(p);
186                         p += BIT8SZ;
187                         break;
188
189                 case Tread:
190                         if (p + BIT32SZ + BIT64SZ + BIT32SZ > ep)
191                                 return 0;
192                         f->fid = GBIT32(p);
193                         p += BIT32SZ;
194                         f->offset = GBIT64(p);
195                         p += BIT64SZ;
196                         f->count = GBIT32(p);
197                         p += BIT32SZ;
198                         break;
199
200                 case Twrite:
201                         if (p + BIT32SZ + BIT64SZ + BIT32SZ > ep)
202                                 return 0;
203                         f->fid = GBIT32(p);
204                         p += BIT32SZ;
205                         f->offset = GBIT64(p);
206                         p += BIT64SZ;
207                         f->count = GBIT32(p);
208                         p += BIT32SZ;
209                         if (p + f->count > ep)
210                                 return 0;
211                         f->data = (char *)p;
212                         p += f->count;
213                         break;
214
215                 case Tclunk:
216                 case Tremove:
217                         if (p + BIT32SZ > ep)
218                                 return 0;
219                         f->fid = GBIT32(p);
220                         p += BIT32SZ;
221                         break;
222
223                 case Tstat:
224                         if (p + BIT32SZ > ep)
225                                 return 0;
226                         f->fid = GBIT32(p);
227                         p += BIT32SZ;
228                         break;
229
230                 case Twstat:
231                         if (p + BIT32SZ + BIT16SZ > ep)
232                                 return 0;
233                         f->fid = GBIT32(p);
234                         p += BIT32SZ;
235                         f->nstat = GBIT16(p);
236                         p += BIT16SZ;
237                         if (p + f->nstat > ep)
238                                 return 0;
239                         f->stat = p;
240                         p += f->nstat;
241                         break;
242
243 /*
244  */
245                 case Rversion:
246                         if (p + BIT32SZ > ep)
247                                 return 0;
248                         f->msize = GBIT32(p);
249                         p += BIT32SZ;
250                         p = gstring(p, ep, &f->version);
251                         break;
252
253                 case Rerror:
254                         p = gstring(p, ep, &f->ename);
255                         break;
256
257                 case Rflush:
258                         break;
259
260                 case Rauth:
261                         p = gqid(p, ep, &f->aqid);
262                         if (p == NULL)
263                                 break;
264                         break;
265
266                 case Rattach:
267                         p = gqid(p, ep, &f->qid);
268                         if (p == NULL)
269                                 break;
270                         break;
271
272                 case Rwalk:
273                         if (p + BIT16SZ > ep)
274                                 return 0;
275                         f->nwqid = GBIT16(p);
276                         p += BIT16SZ;
277                         if (f->nwqid > MAXWELEM)
278                                 return 0;
279                         for (i = 0; i < f->nwqid; i++) {
280                                 p = gqid(p, ep, &f->wqid[i]);
281                                 if (p == NULL)
282                                         break;
283                         }
284                         break;
285
286                 case Ropen:
287                 case Rcreate:
288                         p = gqid(p, ep, &f->qid);
289                         if (p == NULL)
290                                 break;
291                         if (p + BIT32SZ > ep)
292                                 return 0;
293                         f->iounit = GBIT32(p);
294                         p += BIT32SZ;
295                         break;
296
297                 case Rread:
298                         if (p + BIT32SZ > ep)
299                                 return 0;
300                         f->count = GBIT32(p);
301                         p += BIT32SZ;
302                         if (p + f->count > ep)
303                                 return 0;
304                         f->data = (char *)p;
305                         p += f->count;
306                         break;
307
308                 case Rwrite:
309                         if (p + BIT32SZ > ep)
310                                 return 0;
311                         f->count = GBIT32(p);
312                         p += BIT32SZ;
313                         break;
314
315                 case Rclunk:
316                 case Rremove:
317                         break;
318
319                 case Rstat:
320                         if (p + BIT16SZ > ep)
321                                 return 0;
322                         f->nstat = GBIT16(p);
323                         p += BIT16SZ;
324                         if (p + f->nstat > ep)
325                                 return 0;
326                         f->stat = p;
327                         p += f->nstat;
328                         break;
329
330                 case Rwstat:
331                         break;
332         }
333
334         if (p == NULL || p > ep)
335                 return 0;
336         if (ap + size == p)
337                 return size;
338         return 0;
339 }