1 | /************************************************************************** |
---|
2 | * |
---|
3 | * Copyright (c) 2013 Alcatel-Lucent |
---|
4 | * |
---|
5 | * Alcatel Lucent licenses this file to You under the Apache License, |
---|
6 | * Version 2.0 (the "License"); you may not use this file except in |
---|
7 | * compliance with the License. A copy of the License is contained the |
---|
8 | * file LICENSE at the top level of this repository. |
---|
9 | * You may also obtain a copy of the License at: |
---|
10 | * |
---|
11 | * http://www.apache.org/licenses/LICENSE-2.0 |
---|
12 | * |
---|
13 | * Unless required by applicable law or agreed to in writing, software |
---|
14 | * distributed under the License is distributed on an "AS IS" BASIS, |
---|
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
---|
16 | * See the License for the specific language governing permissions and |
---|
17 | * limitations under the License. |
---|
18 | * |
---|
19 | ************************************************************************** |
---|
20 | * |
---|
21 | * struct.c: |
---|
22 | * |
---|
23 | * This command allows the user to build a structure into memory based |
---|
24 | * on a structure set up in the definition file ("structfile"). |
---|
25 | * |
---|
26 | * Original author: Ed Sutter (ed.sutter@alcatel-lucent.com) |
---|
27 | * |
---|
28 | */ |
---|
29 | #include "config.h" |
---|
30 | #include "tfs.h" |
---|
31 | #include "tfsprivate.h" |
---|
32 | #include <ctype.h> |
---|
33 | #include "genlib.h" |
---|
34 | #include "stddefs.h" |
---|
35 | #include "cli.h" |
---|
36 | #include "ether.h" |
---|
37 | #include <stdarg.h> |
---|
38 | |
---|
39 | #if INCLUDE_STRUCT |
---|
40 | |
---|
41 | #define OPENBRACE '{' |
---|
42 | #define CLOSEBRACE '}' |
---|
43 | #define PTRSIZE 4 |
---|
44 | |
---|
45 | int structsize(char *name); |
---|
46 | |
---|
47 | struct mbrtype { |
---|
48 | char *type; |
---|
49 | int size; |
---|
50 | }; |
---|
51 | |
---|
52 | struct mbrtype types[] = { |
---|
53 | { "long", 4 }, |
---|
54 | { "short", 2 }, |
---|
55 | { "char", 1 }, |
---|
56 | { 0, -1 } |
---|
57 | }; |
---|
58 | |
---|
59 | static int struct_sfd; |
---|
60 | static ulong struct_base; |
---|
61 | static char *struct_fname; |
---|
62 | static char struct_verbose; |
---|
63 | static char struct_scriptisstructfile; |
---|
64 | |
---|
65 | /* err_general(), err_nostruct(), err_nomember(): |
---|
66 | * Error processing functions... |
---|
67 | */ |
---|
68 | static void |
---|
69 | err_general(int errnum,int linenum, long tfsloc) |
---|
70 | { |
---|
71 | printf("%s: err%d at ln %d\n",struct_fname,errnum,linenum); |
---|
72 | tfsseek(struct_sfd,tfsloc,TFS_BEGIN); |
---|
73 | } |
---|
74 | |
---|
75 | static void |
---|
76 | err_nostruct(char *structname, long tfsloc) |
---|
77 | { |
---|
78 | printf("%s: can't find struct '%s'\n",struct_fname,structname); |
---|
79 | tfsseek(struct_sfd,tfsloc,TFS_BEGIN); |
---|
80 | } |
---|
81 | |
---|
82 | static void |
---|
83 | err_nomember(char *structname, char *mbrname, long tfsloc) |
---|
84 | { |
---|
85 | printf("%s: member '%s' not in struct '%s'\n", |
---|
86 | struct_fname,mbrname,structname); |
---|
87 | tfsseek(struct_sfd,tfsloc,TFS_BEGIN); |
---|
88 | } |
---|
89 | |
---|
90 | /* struct_printf(): |
---|
91 | * Use this function instead of "if (struct_verbose) printf(...)" |
---|
92 | * all over the place. |
---|
93 | */ |
---|
94 | static int |
---|
95 | struct_printf(int mask, char *fmt, ...) |
---|
96 | { |
---|
97 | int tot; |
---|
98 | va_list argp; |
---|
99 | |
---|
100 | if (!(struct_verbose & mask)) |
---|
101 | return(0); |
---|
102 | |
---|
103 | va_start(argp,fmt); |
---|
104 | tot = vsnprintf(0,0,fmt,argp); |
---|
105 | va_end(argp); |
---|
106 | return(tot); |
---|
107 | } |
---|
108 | |
---|
109 | /* struct_prleft(): |
---|
110 | * Print all characters of the incoming string up to the |
---|
111 | * end of the string or the first occurrence of the equals sign. |
---|
112 | * Then print the formatted string that follows. |
---|
113 | */ |
---|
114 | static int |
---|
115 | struct_prleft(int mask, char *str, char *fmt, ...) |
---|
116 | { |
---|
117 | int tot = 0; |
---|
118 | va_list argp; |
---|
119 | |
---|
120 | if (!(struct_verbose & mask)) |
---|
121 | return(tot); |
---|
122 | |
---|
123 | while((*str) && (*str != '=')) { |
---|
124 | tot++; |
---|
125 | putchar(*str++); |
---|
126 | } |
---|
127 | |
---|
128 | va_start(argp,fmt); |
---|
129 | tot += vsnprintf(0,0,fmt,argp); |
---|
130 | va_end(argp); |
---|
131 | return(tot); |
---|
132 | } |
---|
133 | |
---|
134 | /* skipline(): |
---|
135 | * If the line is filled with only whitespace, or if the first non-whitespace |
---|
136 | * character is a poundsign, return 1; else return 0. |
---|
137 | */ |
---|
138 | static int |
---|
139 | skipline(char *line) |
---|
140 | { |
---|
141 | if (struct_scriptisstructfile) { |
---|
142 | if (strncmp(line,"###>>",5) == 0) { |
---|
143 | strcpy(line,line+5); |
---|
144 | return(0); |
---|
145 | } |
---|
146 | else |
---|
147 | return(1); |
---|
148 | } |
---|
149 | else { |
---|
150 | while(isspace(*line)) line++; |
---|
151 | |
---|
152 | switch(*line) { |
---|
153 | case 0: |
---|
154 | case '#': |
---|
155 | return(1); |
---|
156 | } |
---|
157 | return(0); |
---|
158 | } |
---|
159 | } |
---|
160 | |
---|
161 | /* typesize(): |
---|
162 | * Given the incoming type name, return the size of that symbol. |
---|
163 | * Take into account the possibility of it being a pointer (leading '*') |
---|
164 | * or an array (trailing [xx]). |
---|
165 | */ |
---|
166 | static int |
---|
167 | typesize(char *typename, char *name) |
---|
168 | { |
---|
169 | char *np; |
---|
170 | struct mbrtype *mp; |
---|
171 | int nlen, ptr, arraysize; |
---|
172 | |
---|
173 | ptr = 0; |
---|
174 | arraysize = 1; |
---|
175 | |
---|
176 | struct_printf(4,"typesize(%s,%s)\n",typename,name); |
---|
177 | |
---|
178 | if (name[0] == '*') |
---|
179 | ptr = 1; |
---|
180 | |
---|
181 | nlen = strlen(name); |
---|
182 | np = name+nlen-1; |
---|
183 | if (*np == ']') { |
---|
184 | while(*np && (*np != '[')) np--; |
---|
185 | if (*np == 0) |
---|
186 | return(-1); |
---|
187 | arraysize = atoi(np+1); |
---|
188 | } |
---|
189 | |
---|
190 | mp = types; |
---|
191 | while(mp->type) { |
---|
192 | if (strncmp(mp->type,typename,strlen(mp->type)) == 0) |
---|
193 | break; |
---|
194 | mp++; |
---|
195 | } |
---|
196 | |
---|
197 | if (ptr) |
---|
198 | return(PTRSIZE * arraysize); |
---|
199 | |
---|
200 | return(mp->size * arraysize); |
---|
201 | } |
---|
202 | |
---|
203 | /* structline(): |
---|
204 | * Assume that the incoming line is text within a structure definition |
---|
205 | * from the structure file. Parse it, expecting either two or three |
---|
206 | * tokens (2 if the member is a basic type, 3 if the member is another |
---|
207 | * structure). Return the count and pointers to each token. |
---|
208 | */ |
---|
209 | static int |
---|
210 | structline(char *line, char **type, char **name) |
---|
211 | { |
---|
212 | int tot; |
---|
213 | char *cp, *token1, *token2, *token3; |
---|
214 | |
---|
215 | cp = line; |
---|
216 | while(isspace(*cp)) cp++; |
---|
217 | token1 = cp; |
---|
218 | while(!isspace(*cp)) cp++; |
---|
219 | *cp++ = 0; |
---|
220 | |
---|
221 | if (!strcmp(token1,"struct")) { |
---|
222 | while(isspace(*cp)) cp++; |
---|
223 | token2 = cp; |
---|
224 | while(!isspace(*cp)) cp++; |
---|
225 | *cp++ = 0; |
---|
226 | while(isspace(*cp)) cp++; |
---|
227 | token3 = cp; |
---|
228 | while((!isspace(*cp)) && (*cp != ';')) cp++; |
---|
229 | if (*cp != ';') |
---|
230 | return(-1); |
---|
231 | *cp++ = 0; |
---|
232 | *type = token2; |
---|
233 | *name = token3; |
---|
234 | tot = 3; |
---|
235 | } |
---|
236 | else { |
---|
237 | while(isspace(*cp)) cp++; |
---|
238 | token2 = cp; |
---|
239 | while((!isspace(*cp)) && (*cp != ';')) cp++; |
---|
240 | if (*cp != ';') |
---|
241 | return(-1); |
---|
242 | *cp++ = 0; |
---|
243 | *type = token1; |
---|
244 | *name = token2; |
---|
245 | tot = 2; |
---|
246 | } |
---|
247 | struct_printf(4,"structline: type='%s', name='%s'\n",*type,*name); |
---|
248 | return(tot); |
---|
249 | |
---|
250 | } |
---|
251 | |
---|
252 | /* structsize(): |
---|
253 | * Assuming the incoming string is a pointer to some structure definition |
---|
254 | * in the structure file, parse the file and figure out how big the |
---|
255 | * structure is. Return the size of successful; else return -1 to indicate |
---|
256 | * some kind of parsing error. |
---|
257 | */ |
---|
258 | int |
---|
259 | structsize(char *structname) |
---|
260 | { |
---|
261 | long loc; |
---|
262 | int offset, slen, lno, size; |
---|
263 | char line[80], *cp, *cp1, *type, *name; |
---|
264 | |
---|
265 | struct_printf(4,"structsize(%s)\n",structname); |
---|
266 | |
---|
267 | loc = tfstell(struct_sfd); |
---|
268 | |
---|
269 | if (tfsseek(struct_sfd,0,TFS_BEGIN) < 0) { |
---|
270 | tfsseek(struct_sfd,loc,TFS_BEGIN); |
---|
271 | return(-1); |
---|
272 | } |
---|
273 | |
---|
274 | offset = 0; |
---|
275 | slen = strlen(structname); |
---|
276 | lno = 0; |
---|
277 | while(tfsgetline(struct_sfd,line,sizeof(line)) > 0) { |
---|
278 | lno++; |
---|
279 | if (skipline(line)) |
---|
280 | continue; |
---|
281 | if (!strncmp(line,"struct ",7)) { |
---|
282 | cp = line+7; |
---|
283 | while(isspace(*cp)) cp++; |
---|
284 | if ((!strncmp(structname,cp,slen)) && (isspace(cp[slen]))) { |
---|
285 | cp1 = cp+slen; |
---|
286 | while(isspace(*cp1)) cp1++; |
---|
287 | if (*cp1 != OPENBRACE) { |
---|
288 | err_general(1,lno,loc); |
---|
289 | return(-1); |
---|
290 | } |
---|
291 | |
---|
292 | while(tfsgetline(struct_sfd,line,sizeof(line)) > 0) { |
---|
293 | lno++; |
---|
294 | if (skipline(line)) |
---|
295 | continue; |
---|
296 | if (line[0] == CLOSEBRACE) { |
---|
297 | tfsseek(struct_sfd,loc,TFS_BEGIN); |
---|
298 | return(offset); |
---|
299 | } |
---|
300 | switch(structline(line,&type,&name)) { |
---|
301 | case 2: |
---|
302 | if ((size = typesize(type,name)) < 0) { |
---|
303 | err_general(2,lno,loc); |
---|
304 | return(-1); |
---|
305 | } |
---|
306 | break; |
---|
307 | case 3: |
---|
308 | if ((size = structsize(type)) < 0) { |
---|
309 | err_general(3,lno,loc); |
---|
310 | return(-1); |
---|
311 | } |
---|
312 | break; |
---|
313 | default: |
---|
314 | err_general(4,lno,loc); |
---|
315 | return(-1); |
---|
316 | } |
---|
317 | offset += size; |
---|
318 | } |
---|
319 | err_general(5,lno,loc); |
---|
320 | return(-1); |
---|
321 | } |
---|
322 | } |
---|
323 | } |
---|
324 | err_nostruct(structname,loc); |
---|
325 | return(-1); |
---|
326 | } |
---|
327 | |
---|
328 | int |
---|
329 | membertype(char *structname, char *mbrname, char *mbrtype) |
---|
330 | { |
---|
331 | long loc; |
---|
332 | int rc, slen, lno; |
---|
333 | char line[80], *cp, *cp1, *type, *name; |
---|
334 | |
---|
335 | struct_printf(4,"membertype(%s,%s)\n",structname,mbrname); |
---|
336 | |
---|
337 | loc = tfstell(struct_sfd); |
---|
338 | |
---|
339 | if (tfsseek(struct_sfd,0,TFS_BEGIN) < 0) { |
---|
340 | tfsseek(struct_sfd,loc,TFS_BEGIN); |
---|
341 | return(-1); |
---|
342 | } |
---|
343 | |
---|
344 | slen = strlen(structname); |
---|
345 | lno = 0; |
---|
346 | while(tfsgetline(struct_sfd,line,sizeof(line)) > 0) { |
---|
347 | lno++; |
---|
348 | if (skipline(line)) |
---|
349 | continue; |
---|
350 | if (!strncmp(line,"struct ",7)) { |
---|
351 | cp = line+7; |
---|
352 | while(isspace(*cp)) cp++; |
---|
353 | if ((!strncmp(structname,cp,slen)) && (isspace(cp[slen]))) { |
---|
354 | cp1 = cp+slen; |
---|
355 | while(isspace(*cp1)) cp1++; |
---|
356 | if (*cp1 != OPENBRACE) { |
---|
357 | err_general(6,lno,loc); |
---|
358 | return(-1); |
---|
359 | } |
---|
360 | |
---|
361 | while(tfsgetline(struct_sfd,line,sizeof(line)) > 0) { |
---|
362 | lno++; |
---|
363 | if (skipline(line)) |
---|
364 | continue; |
---|
365 | if (line[0] == CLOSEBRACE) { |
---|
366 | err_nomember(structname,mbrname,loc); |
---|
367 | return(-1); |
---|
368 | } |
---|
369 | if ((rc = structline(line,&type,&name)) < 0) { |
---|
370 | err_general(7,lno,loc); |
---|
371 | return(-1); |
---|
372 | } |
---|
373 | if (!strcmp(name,mbrname)) { |
---|
374 | tfsseek(struct_sfd,loc,TFS_BEGIN); |
---|
375 | if (mbrtype) |
---|
376 | strcpy(mbrtype,type); |
---|
377 | return(rc); |
---|
378 | } |
---|
379 | } |
---|
380 | err_general(8,lno,loc); |
---|
381 | return(-1); |
---|
382 | } |
---|
383 | } |
---|
384 | } |
---|
385 | err_nostruct(structname,loc); |
---|
386 | return(-1); |
---|
387 | } |
---|
388 | |
---|
389 | /* memberoffset(): |
---|
390 | * Return the offset into the structure at which point the member resides. |
---|
391 | * If mbrsize is non-zero, then assume it is a pointer to an integer |
---|
392 | * into which this function will also load the size of the member. |
---|
393 | */ |
---|
394 | int |
---|
395 | memberoffset(char *structname, char *mbrname, int *mbrsize) |
---|
396 | { |
---|
397 | long loc; |
---|
398 | int offset, slen, size, lno; |
---|
399 | char line[80], *cp, *cp1, *type, *name; |
---|
400 | |
---|
401 | struct_printf(4,"memberoffset(%s,%s)\n",structname,mbrname); |
---|
402 | |
---|
403 | loc = tfstell(struct_sfd); |
---|
404 | |
---|
405 | if (tfsseek(struct_sfd,0,TFS_BEGIN) < 0) { |
---|
406 | tfsseek(struct_sfd,loc,TFS_BEGIN); |
---|
407 | return(-1); |
---|
408 | } |
---|
409 | |
---|
410 | offset = 0; |
---|
411 | slen = strlen(structname); |
---|
412 | lno = 0; |
---|
413 | while(tfsgetline(struct_sfd,line,sizeof(line)) > 0) { |
---|
414 | lno++; |
---|
415 | if (skipline(line)) |
---|
416 | continue; |
---|
417 | if (!strncmp(line,"struct ",7)) { |
---|
418 | cp = line+7; |
---|
419 | while(isspace(*cp)) cp++; |
---|
420 | if ((!strncmp(structname,cp,slen)) && (isspace(cp[slen]))) { |
---|
421 | cp1 = cp+slen; |
---|
422 | while(isspace(*cp1)) cp1++; |
---|
423 | if (*cp1 != OPENBRACE) { |
---|
424 | err_general(9,lno,loc); |
---|
425 | return(-1); |
---|
426 | } |
---|
427 | |
---|
428 | while(tfsgetline(struct_sfd,line,sizeof(line)) > 0) { |
---|
429 | lno++; |
---|
430 | if (skipline(line)) |
---|
431 | continue; |
---|
432 | if (line[0] == '#') |
---|
433 | continue; |
---|
434 | if (line[0] == CLOSEBRACE) { |
---|
435 | err_nomember(structname,mbrname,loc); |
---|
436 | return(-1); |
---|
437 | } |
---|
438 | switch(structline(line,&type,&name)) { |
---|
439 | case 2: |
---|
440 | if ((size = typesize(type,name)) < 0) { |
---|
441 | err_general(10,lno,loc); |
---|
442 | return(-1); |
---|
443 | } |
---|
444 | break; |
---|
445 | case 3: |
---|
446 | if ((size = structsize(type)) < 0) { |
---|
447 | err_general(11,lno,loc); |
---|
448 | return(-1); |
---|
449 | } |
---|
450 | break; |
---|
451 | default: |
---|
452 | err_general(12,lno,loc); |
---|
453 | return(-1); |
---|
454 | } |
---|
455 | if (!strcmp(name,mbrname)) { |
---|
456 | tfsseek(struct_sfd,loc,TFS_BEGIN); |
---|
457 | if (mbrsize) |
---|
458 | *mbrsize = size; |
---|
459 | return(offset); |
---|
460 | } |
---|
461 | offset += size; |
---|
462 | } |
---|
463 | err_general(13,lno,loc); |
---|
464 | return(-1); |
---|
465 | } |
---|
466 | } |
---|
467 | } |
---|
468 | err_nostruct(structname,loc); |
---|
469 | return(-1); |
---|
470 | } |
---|
471 | |
---|
472 | char *StructHelp[] = { |
---|
473 | "Build a structure in memory", |
---|
474 | "-[b:f:v] {struct.mbr[=val]} [struct.mbr1[=val1]] ...", |
---|
475 | #if INCLUDE_VERBOSEHELP |
---|
476 | "Options:", |
---|
477 | " -b{addr} base address of structure (overrides STRUCTBASE)", |
---|
478 | " -f{fname} structure definition filename (overrides STRUCTFILE)", |
---|
479 | " -v additive verbosity", |
---|
480 | "", |
---|
481 | "Notes:", |
---|
482 | " * The 'val' can be a normal value or a processed function...", |
---|
483 | " strcpy(str|src), strcat(str|src), memcpy(src,size)", |
---|
484 | " sizeof(structtype), tagsiz(str1,str2), e2b(enet), i2l(ip)", |
---|
485 | " * If '=val' is not specified, then the size and offset of the", |
---|
486 | " specified structure/member is loaded into STRUCTSIZE and", |
---|
487 | " STRUCTOFFSET shellvars respectively.", |
---|
488 | #endif |
---|
489 | 0, |
---|
490 | }; |
---|
491 | |
---|
492 | int |
---|
493 | StructCmd(int argc,char *argv[]) |
---|
494 | { |
---|
495 | unsigned long lval, dest; |
---|
496 | char copy[CMDLINESIZE], type[32]; |
---|
497 | char *eq, *dot, *str, *mbr, *env, *equation; |
---|
498 | int opt, i, offset, mbrtype, rc, size, processlval; |
---|
499 | |
---|
500 | struct_fname = 0; |
---|
501 | struct_verbose = 0; |
---|
502 | struct_base = 0xffffffff; |
---|
503 | while((opt=getopt(argc,argv,"b:f:v")) != -1) { |
---|
504 | switch(opt) { |
---|
505 | case 'b': |
---|
506 | struct_base = strtoul(optarg,0,0); |
---|
507 | break; |
---|
508 | case 'f': |
---|
509 | struct_fname = optarg; |
---|
510 | break; |
---|
511 | case 'v': |
---|
512 | struct_verbose++; |
---|
513 | break; |
---|
514 | default: |
---|
515 | return(CMD_PARAM_ERROR); |
---|
516 | } |
---|
517 | } |
---|
518 | |
---|
519 | if (argc < optind + 1) |
---|
520 | return(CMD_PARAM_ERROR); |
---|
521 | |
---|
522 | /* If base and/or filename are not set, get them from environment |
---|
523 | * variables... |
---|
524 | */ |
---|
525 | if (struct_base == 0xffffffff) { |
---|
526 | if ((env = getenv("STRUCTBASE")) == 0) { |
---|
527 | printf("No struct base\n"); |
---|
528 | return(CMD_FAILURE); |
---|
529 | } |
---|
530 | struct_base = strtoul(env,0,0); |
---|
531 | } |
---|
532 | if (struct_fname == 0) { |
---|
533 | if ((struct_fname = getenv("STRUCTFILE")) == 0) { |
---|
534 | printf("No struct filename\n"); |
---|
535 | return(CMD_FAILURE); |
---|
536 | } |
---|
537 | } |
---|
538 | |
---|
539 | struct_sfd = tfsopen(struct_fname,TFS_RDONLY,0); |
---|
540 | |
---|
541 | if (struct_sfd < 0) { |
---|
542 | printf("Can't find file '%s'\n",struct_fname); |
---|
543 | return(CMD_FAILURE); |
---|
544 | } |
---|
545 | |
---|
546 | /* If the specified structure description file is the currently |
---|
547 | * running script, then set a flag so that this code will look |
---|
548 | * for the "###>>" prefix as a required line prefix in the |
---|
549 | * structure file. |
---|
550 | */ |
---|
551 | if (strcmp(struct_fname,tfsscriptname()) == 0) |
---|
552 | struct_scriptisstructfile = 1; |
---|
553 | else |
---|
554 | struct_scriptisstructfile = 0; |
---|
555 | |
---|
556 | /* Assume each command line argument is some "struct=val" statement, |
---|
557 | * and process each one... |
---|
558 | */ |
---|
559 | for(i=optind;i<argc;i++) { |
---|
560 | equation = argv[i]; |
---|
561 | |
---|
562 | /* Make a copy of the argument so we can modify it. |
---|
563 | * (no need to check length because sizeof(copy) is CMDLINESIZE). |
---|
564 | */ |
---|
565 | strcpy(copy,equation); |
---|
566 | |
---|
567 | /* Check for equal sign... |
---|
568 | */ |
---|
569 | if ((eq = strchr(copy,'='))) |
---|
570 | *eq = 0; |
---|
571 | |
---|
572 | /* Start parsing and processing the structure request... |
---|
573 | */ |
---|
574 | offset = mbrtype = 0; |
---|
575 | dot = strchr(copy,'.'); |
---|
576 | if (!dot) { |
---|
577 | size = structsize(copy); |
---|
578 | } |
---|
579 | else { |
---|
580 | while(dot) { |
---|
581 | *dot++ = 0; |
---|
582 | mbr = dot; |
---|
583 | str = dot-2; |
---|
584 | while((*str != 0) && (str != copy) && (*str != '.')) |
---|
585 | str--; |
---|
586 | if (str != copy) |
---|
587 | str++; |
---|
588 | while((dot != 0) && (*dot != '.')) |
---|
589 | dot++; |
---|
590 | *dot = 0; |
---|
591 | |
---|
592 | if (mbrtype == 3) |
---|
593 | str = type; |
---|
594 | |
---|
595 | if ((rc = memberoffset(str,mbr,&size)) < 0) |
---|
596 | goto done; |
---|
597 | |
---|
598 | if ((mbrtype = membertype(str,mbr,type)) < 0) |
---|
599 | goto done; |
---|
600 | |
---|
601 | offset += rc; |
---|
602 | *dot = '.'; |
---|
603 | dot = strchr(mbr,'.'); |
---|
604 | } |
---|
605 | } |
---|
606 | |
---|
607 | shell_sprintf("STRUCTOFFSET","0x%lx",offset); |
---|
608 | shell_sprintf("STRUCTSIZE","0x%lx",size); |
---|
609 | |
---|
610 | /* If there is no "right half" of the equation, then just |
---|
611 | * continue here... |
---|
612 | */ |
---|
613 | if (!eq) |
---|
614 | continue; |
---|
615 | |
---|
616 | /* At this point we have the size of the member and its offset |
---|
617 | * from the base, so now we parse the "val" side of the |
---|
618 | * equation... |
---|
619 | */ |
---|
620 | |
---|
621 | /* Check for functions (sizeof, strcpy, enet, ip, etc...). |
---|
622 | * If found, then something other than just normal lval processing |
---|
623 | * is done... |
---|
624 | */ |
---|
625 | eq++; |
---|
626 | lval = processlval = 0; |
---|
627 | dest = struct_base + offset; |
---|
628 | if (!strncmp(eq,"sizeof(",7)) { |
---|
629 | char *cp; |
---|
630 | |
---|
631 | eq += 7; |
---|
632 | cp = eq; |
---|
633 | if ((cp = strchr(cp,')')) == 0) |
---|
634 | goto paramerr; |
---|
635 | *cp=0; |
---|
636 | lval = structsize(eq); |
---|
637 | processlval = 1; |
---|
638 | } |
---|
639 | else if (!strncmp(eq,"i2l(",4)) { |
---|
640 | char *cp, *cp1; |
---|
641 | |
---|
642 | eq += 4; |
---|
643 | cp = cp1 = eq; |
---|
644 | if ((cp1 = strchr(cp,')')) == 0) |
---|
645 | goto paramerr; |
---|
646 | *cp1 = 0; |
---|
647 | if (struct_verbose & 1) { |
---|
648 | } |
---|
649 | struct_printf(3,"i2l(0x%lx,%s)\n", dest, cp); |
---|
650 | |
---|
651 | if (IpToBin(cp,(uchar *)dest) < 0) |
---|
652 | goto paramerr; |
---|
653 | } |
---|
654 | else if (!strncmp(eq,"e2b(",4)) { |
---|
655 | char *cp, *cp1; |
---|
656 | |
---|
657 | cp = cp1 = eq+4; |
---|
658 | if ((cp1 = strchr(cp,')')) == 0) |
---|
659 | goto paramerr; |
---|
660 | *cp1 = 0; |
---|
661 | struct_printf(3,"e2b(0x%lx,%s)\n", dest, cp); |
---|
662 | |
---|
663 | if (EtherToBin(cp,(uchar *)dest) < 0) |
---|
664 | goto paramerr; |
---|
665 | } |
---|
666 | else if (!strncmp(eq,"tagsiz(",7)) { |
---|
667 | char *comma, *paren; |
---|
668 | int siz1, siz2; |
---|
669 | |
---|
670 | eq += 7; |
---|
671 | comma = eq; |
---|
672 | if ((comma = strchr(comma,',')) == 0) |
---|
673 | goto paramerr; |
---|
674 | *comma++ = 0; |
---|
675 | if ((paren = strrchr(comma,')')) == 0) |
---|
676 | goto paramerr; |
---|
677 | *paren = 0; |
---|
678 | if ((siz1=structsize(eq)) < 0) |
---|
679 | goto paramerr; |
---|
680 | if ((siz2=structsize(comma)) < 0) |
---|
681 | goto paramerr; |
---|
682 | lval = (siz1+siz2)/4; |
---|
683 | processlval = 1; |
---|
684 | } |
---|
685 | else if (!strncmp(eq,"memcpy(",7)) { |
---|
686 | int len; |
---|
687 | char *comma, *cp; |
---|
688 | |
---|
689 | eq += 7; |
---|
690 | comma = eq; |
---|
691 | if ((comma = strchr(comma,',')) == 0) |
---|
692 | goto paramerr; |
---|
693 | *comma++ = 0; |
---|
694 | cp = comma; |
---|
695 | cp = (char *)strtoul(eq,0,0); |
---|
696 | len = (int)strtoul(comma,0,0); |
---|
697 | struct_printf(3,"memcpy(0x%lx,0x%lx,%d)\n",dest,(long)cp,len); |
---|
698 | memcpy((void *)dest,(void *)cp,len); |
---|
699 | } |
---|
700 | else if (!strncmp(eq,"strcpy(",7)) { |
---|
701 | char *cp, *cp1; |
---|
702 | |
---|
703 | eq += 7; |
---|
704 | cp = cp1 = eq; |
---|
705 | if ((cp1 = strrchr(cp,')')) == 0) |
---|
706 | goto paramerr; |
---|
707 | *cp1 = 0; |
---|
708 | |
---|
709 | |
---|
710 | if (!strncmp(cp,"0x",2)) { |
---|
711 | cp = (char *)strtoul(eq,0,0); |
---|
712 | struct_printf(3,"strcpy(0x%lx,0x%lx)\n",dest,(long)cp); |
---|
713 | } |
---|
714 | else { |
---|
715 | struct_prleft(1,equation," = \"%s\"\n",cp); |
---|
716 | struct_printf(2,"strcpy(0x%lx,%s)\n", dest,cp); |
---|
717 | } |
---|
718 | strcpy((char *)dest,cp); |
---|
719 | } |
---|
720 | else if (!strncmp(eq,"strcat(",7)) { |
---|
721 | char *cp, *cp1; |
---|
722 | |
---|
723 | eq += 7; |
---|
724 | cp = cp1 = eq; |
---|
725 | if ((cp1 = strrchr(cp,')')) == 0) |
---|
726 | goto paramerr; |
---|
727 | *cp1 = 0; |
---|
728 | |
---|
729 | if (!strncmp(cp,"0x",2)) { |
---|
730 | cp = (char *)strtoul(eq,0,0); |
---|
731 | struct_printf(3,"strcat(0x%lx,0x%lx)\n",dest,(long)cp); |
---|
732 | } |
---|
733 | else { |
---|
734 | struct_prleft(1,equation," += \"%s\"\n",cp); |
---|
735 | struct_printf(2,"strcat(0x%lx,%s)\n", dest,cp); |
---|
736 | } |
---|
737 | strcat((char *)dest,cp); |
---|
738 | } |
---|
739 | else { |
---|
740 | lval = strtoul(eq,0,0); |
---|
741 | processlval = 1; |
---|
742 | } |
---|
743 | |
---|
744 | if (processlval) { |
---|
745 | switch(size) { |
---|
746 | case 1: |
---|
747 | struct_prleft(1,equation," = %d (0x%x)\n", |
---|
748 | (uchar)lval,(uchar)lval); |
---|
749 | struct_printf(2,"*(uchar *)0x%lx = %d (0x%x)\n", |
---|
750 | dest,(uchar)lval,(uchar)lval); |
---|
751 | *(uchar *)(dest) = (uchar)lval; |
---|
752 | break; |
---|
753 | case 2: |
---|
754 | struct_prleft(1,equation," = %d (0x%x)\n", |
---|
755 | (ushort)lval,(ushort)lval); |
---|
756 | struct_printf(2,"*(ushort *)0x%lx = %d (0x%x)\n", |
---|
757 | dest,(ushort)lval,(ushort)lval); |
---|
758 | *(ushort *)dest = (ushort)lval; |
---|
759 | break; |
---|
760 | case 4: |
---|
761 | struct_prleft(1,equation," = %ld (0x%lx)\n", |
---|
762 | (ulong)lval,(ulong)lval); |
---|
763 | struct_printf(2,"*(ulong *)0x%lx = %d (0x%x)\n", |
---|
764 | dest,lval,lval); |
---|
765 | *(ulong *)dest = lval; |
---|
766 | break; |
---|
767 | default: |
---|
768 | struct_printf(3,"memset(0x%lx,0x%x,%d)\n", |
---|
769 | dest,(uchar)lval,size); |
---|
770 | memset((void *)dest,lval,size); |
---|
771 | break; |
---|
772 | } |
---|
773 | } |
---|
774 | } |
---|
775 | done: |
---|
776 | tfsclose(struct_sfd,0); |
---|
777 | return(CMD_SUCCESS); |
---|
778 | |
---|
779 | paramerr: |
---|
780 | tfsclose(struct_sfd,0); |
---|
781 | return(CMD_PARAM_ERROR); |
---|
782 | } |
---|
783 | #endif |
---|