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