Introduction
Introduction Statistics Contact Development Disclaimer Help
convM2S.c - 9base - revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log
Files
Refs
README
LICENSE
---
convM2S.c (5598B)
---
1 #include <u.h>
2 #include <libc.h>
3 #include <fcall.h>
4
5 static
6 uchar*
7 gstring(uchar *p, uchar *ep, char **s)
8 {
9 uint n;
10
11 if(p+BIT16SZ > ep)
12 return nil;
13 n = GBIT16(p);
14 p += BIT16SZ - 1;
15 if(p+n+1 > ep)
16 return nil;
17 /* move it down, on top of count, to make room for '\0' */
18 memmove(p, p + 1, n);
19 p[n] = '\0';
20 *s = (char*)p;
21 p += n+1;
22 return p;
23 }
24
25 static
26 uchar*
27 gqid(uchar *p, uchar *ep, Qid *q)
28 {
29 if(p+QIDSZ > ep)
30 return nil;
31 q->type = GBIT8(p);
32 p += BIT8SZ;
33 q->vers = GBIT32(p);
34 p += BIT32SZ;
35 q->path = GBIT64(p);
36 p += BIT64SZ;
37 return p;
38 }
39
40 /*
41 * no syntactic checks.
42 * three causes for error:
43 * 1. message size field is incorrect
44 * 2. input buffer too short for its own data (counts too long, etc.)
45 * 3. too many names or qids
46 * gqid() and gstring() return nil if they would reach beyond buffer.
47 * main switch statement checks range and also can fall through
48 * to test at end of routine.
49 */
50 uint
51 convM2Su(uchar *ap, uint nap, Fcall *f, int dotu)
52 {
53 uchar *p, *ep;
54 uint i, size;
55
56 p = ap;
57 ep = p + nap;
58
59 if(p+BIT32SZ+BIT8SZ+BIT16SZ > ep)
60 return 0;
61 size = GBIT32(p);
62 p += BIT32SZ;
63
64 if(size < BIT32SZ+BIT8SZ+BIT16SZ)
65 return 0;
66
67 f->type = GBIT8(p);
68 p += BIT8SZ;
69 f->tag = GBIT16(p);
70 p += BIT16SZ;
71
72 switch(f->type)
73 {
74 default:
75 return 0;
76
77 case Tversion:
78 if(p+BIT32SZ > ep)
79 return 0;
80 f->msize = GBIT32(p);
81 p += BIT32SZ;
82 p = gstring(p, ep, &f->version);
83 break;
84
85 case Tflush:
86 if(p+BIT16SZ > ep)
87 return 0;
88 f->oldtag = GBIT16(p);
89 p += BIT16SZ;
90 break;
91
92 case Tauth:
93 if(p+BIT32SZ > ep)
94 return 0;
95 f->afid = GBIT32(p);
96 p += BIT32SZ;
97 p = gstring(p, ep, &f->uname);
98 if(p == nil)
99 break;
100 p = gstring(p, ep, &f->aname);
101 if(p == nil)
102 break;
103 f->uidnum = NOUID;
104 if(dotu){
105 if(p+BIT32SZ > ep)
106 return 0;
107 f->uidnum = GBIT32(p);
108 p += BIT32SZ;
109 }
110 break;
111
112 case Tattach:
113 if(p+BIT32SZ > ep)
114 return 0;
115 f->fid = GBIT32(p);
116 p += BIT32SZ;
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 == nil)
123 break;
124 p = gstring(p, ep, &f->aname);
125 if(p == nil)
126 break;
127 f->uidnum = NOUID;
128 if(dotu){
129 if(p+BIT32SZ > ep)
130 return 0;
131 f->uidnum = GBIT32(p);
132 p += BIT32SZ;
133 }
134 break;
135
136 case Twalk:
137 if(p+BIT32SZ+BIT32SZ+BIT16SZ > ep)
138 return 0;
139 f->fid = GBIT32(p);
140 p += BIT32SZ;
141 f->newfid = GBIT32(p);
142 p += BIT32SZ;
143 f->nwname = GBIT16(p);
144 p += BIT16SZ;
145 if(f->nwname > MAXWELEM)
146 return 0;
147 for(i=0; i<f->nwname; i++){
148 p = gstring(p, ep, &f->wname[i]);
149 if(p == nil)
150 break;
151 }
152 break;
153
154 case Topen:
155 case Topenfd:
156 if(p+BIT32SZ+BIT8SZ > ep)
157 return 0;
158 f->fid = GBIT32(p);
159 p += BIT32SZ;
160 f->mode = GBIT8(p);
161 p += BIT8SZ;
162 break;
163
164 case Tcreate:
165 if(p+BIT32SZ > ep)
166 return 0;
167 f->fid = GBIT32(p);
168 p += BIT32SZ;
169 p = gstring(p, ep, &f->name);
170 if(p == nil)
171 break;
172 if(p+BIT32SZ+BIT8SZ > ep)
173 return 0;
174 f->perm = GBIT32(p);
175 p += BIT32SZ;
176 f->mode = GBIT8(p);
177 p += BIT8SZ;
178 if(dotu)
179 p = gstring(p, ep, &f->extension);
180 break;
181
182 case Tread:
183 if(p+BIT32SZ+BIT64SZ+BIT32SZ > ep)
184 return 0;
185 f->fid = GBIT32(p);
186 p += BIT32SZ;
187 f->offset = GBIT64(p);
188 p += BIT64SZ;
189 f->count = GBIT32(p);
190 p += BIT32SZ;
191 break;
192
193 case Twrite:
194 if(p+BIT32SZ+BIT64SZ+BIT32SZ > ep)
195 return 0;
196 f->fid = GBIT32(p);
197 p += BIT32SZ;
198 f->offset = GBIT64(p);
199 p += BIT64SZ;
200 f->count = GBIT32(p);
201 p += BIT32SZ;
202 if(p+f->count > ep)
203 return 0;
204 f->data = (char*)p;
205 p += f->count;
206 break;
207
208 case Tclunk:
209 case Tremove:
210 if(p+BIT32SZ > ep)
211 return 0;
212 f->fid = GBIT32(p);
213 p += BIT32SZ;
214 break;
215
216 case Tstat:
217 if(p+BIT32SZ > ep)
218 return 0;
219 f->fid = GBIT32(p);
220 p += BIT32SZ;
221 break;
222
223 case Twstat:
224 if(p+BIT32SZ+BIT16SZ > ep)
225 return 0;
226 f->fid = GBIT32(p);
227 p += BIT32SZ;
228 f->nstat = GBIT16(p);
229 p += BIT16SZ;
230 if(p+f->nstat > ep)
231 return 0;
232 f->stat = p;
233 p += f->nstat;
234 break;
235
236 /*
237 */
238 case Rversion:
239 if(p+BIT32SZ > ep)
240 return 0;
241 f->msize = GBIT32(p);
242 p += BIT32SZ;
243 p = gstring(p, ep, &f->version);
244 break;
245
246 case Rerror:
247 p = gstring(p, ep, &f->ename);
248 f->errornum = 0;
249 if(dotu){
250 if(p+BIT32SZ > ep)
251 return 0;
252 f->errornum = GBIT32(p);
253 p += BIT32SZ;
254 }
255 break;
256
257 case Rflush:
258 break;
259
260 case Rauth:
261 p = gqid(p, ep, &f->aqid);
262 if(p == nil)
263 break;
264 break;
265
266 case Rattach:
267 p = gqid(p, ep, &f->qid);
268 if(p == nil)
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 == nil)
282 break;
283 }
284 break;
285
286 case Ropen:
287 case Ropenfd:
288 case Rcreate:
289 p = gqid(p, ep, &f->qid);
290 if(p == nil)
291 break;
292 if(p+BIT32SZ > ep)
293 return 0;
294 f->iounit = GBIT32(p);
295 p += BIT32SZ;
296 if(f->type == Ropenfd){
297 if(p+BIT32SZ > ep)
298 return 0;
299 f->unixfd = GBIT32(p);
300 p += BIT32SZ;
301 }
302 break;
303
304 case Rread:
305 if(p+BIT32SZ > ep)
306 return 0;
307 f->count = GBIT32(p);
308 p += BIT32SZ;
309 if(p+f->count > ep)
310 return 0;
311 f->data = (char*)p;
312 p += f->count;
313 break;
314
315 case Rwrite:
316 if(p+BIT32SZ > ep)
317 return 0;
318 f->count = GBIT32(p);
319 p += BIT32SZ;
320 break;
321
322 case Rclunk:
323 case Rremove:
324 break;
325
326 case Rstat:
327 if(p+BIT16SZ > ep)
328 return 0;
329 f->nstat = GBIT16(p);
330 p += BIT16SZ;
331 if(p+f->nstat > ep)
332 return 0;
333 f->stat = p;
334 p += f->nstat;
335 break;
336
337 case Rwstat:
338 break;
339 }
340
341 if(p==nil || p>ep)
342 return 0;
343 if(ap+size == p)
344 return size;
345 return 0;
346 }
347
348 uint
349 convM2S(uchar *ap, uint nap, Fcall *f)
350 {
351 return convM2Su(ap, nap, f, 0);
352 }
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.