Print this page
10476 file(1) could be smatch clean
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/file/magicutils.c
+++ new/usr/src/cmd/file/magicutils.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
↓ open down ↓ |
21 lines elided |
↑ open up ↑ |
22 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
27 27 /* All Rights Reserved */
28 28
29 29 /* Copyright (c) 1987, 1988 Microsoft Corporation */
30 30 /* All Rights Reserved */
31 31
32 -#pragma ident "%Z%%M% %I% %E% SMI"
33 -
34 32 #include <stdio.h>
35 33 #include <stdlib.h>
36 34 #include <string.h>
37 35 #include <ctype.h>
38 36 #include <errno.h>
39 37 #include <limits.h>
40 38 #include <inttypes.h>
41 39 #include <sys/types.h>
42 40 #include <libintl.h>
43 41
44 42 /*
45 43 * Types
46 44 */
47 45
48 46 #define BYTE 1
49 47 #define SHORT 2
50 48 #define LONG 4
51 49 #define LLONG 8
52 50 #define UBYTE 16
53 51 #define USHORT 32
54 52 #define ULONG 64
55 53 #define ULLONG 128
56 54 #define STR 256
57 55
58 56 /*
59 57 * Opcodes
60 58 */
61 59
62 60 #define EQ 0
63 61 #define GT 1
64 62 #define LT 2
65 63 #define STRC 3 /* string compare */
66 64 #define ANY 4
67 65 #define AND 5
68 66 #define NSET 6 /* True if bit is not set */
69 67 #define SUB 64 /* or'ed in, SUBstitution string, for example */
70 68 /* %ld, %s, %lo mask: with bit 6 on, used to locate */
71 69 /* print formats */
72 70 /*
73 71 * Misc
74 72 */
75 73
76 74 #define BSZ 128
77 75 #define NENT 200
78 76
79 77 /*
80 78 * Structure of magic file entry
81 79 */
82 80
83 81 struct entry {
84 82 char e_level; /* 0 or 1 */
85 83 off_t e_off; /* in bytes */
86 84 uint32_t e_type; /* BYTE, SHORT, STR, et al */
87 85 char e_opcode; /* EQ, GT, LT, ANY, AND, NSET */
88 86 uint64_t e_mask; /* if non-zero, mask value with this */
89 87 union {
90 88 uint64_t num;
91 89 char *str;
92 90 } e_value;
93 91 const char *e_str;
94 92 };
95 93
96 94 /* Non-localized string giving name of command. Defined in file.c */
97 95 extern const char *File;
98 96
99 97 typedef struct entry Entry;
100 98
101 99 static Entry *mtab1; /* 1st magic table, applied before default tests */
102 100
103 101 /*
104 102 * 2nd magic table, includes default tests and magic entries
105 103 * to be applied after default position-sensitive tests
106 104 */
107 105 static Entry *mtab2;
108 106
109 107 static Entry *mend1; /* one past last-allocated entry in mtab1 */
110 108 static Entry *mend2; /* one past last-allocated entry in mtab2 */
111 109
112 110 static Entry *ep1; /* current entry in mtab1 */
113 111 static Entry *ep2; /* current entry in mtab2 */
114 112
115 113 static char *
116 114 getstr(char *p, char *file)
117 115 {
118 116 char *newstr;
119 117 char *s;
120 118 long val;
121 119 int base;
122 120
123 121 newstr = (char *)malloc((strlen(p) + 1) * sizeof (char));
124 122 if (newstr == NULL) {
125 123 int err = errno;
126 124 (void) fprintf(stderr, gettext("%s: malloc failed: %s\n"),
127 125 File, strerror(err));
128 126 return (NULL);
129 127 }
130 128
131 129 s = newstr;
132 130 while (*p != '\0') {
133 131 if (*p != '\\') {
134 132 *s++ = *p++;
135 133 continue;
136 134 }
137 135 p++;
138 136 if (*p == '\0')
139 137 break;
140 138 if (isdigit(*p)) {
141 139 if (*p == '0' && (*(p+1) == 'x' || *(p+1) == 'X')) {
142 140 /* hex */
143 141 base = 16;
144 142 } else {
145 143 base = 8;
146 144 }
147 145 errno = 0;
148 146 val = strtol(p, &p, base);
149 147 if (val > UCHAR_MAX || val < 0 || errno != 0) {
150 148 (void) fprintf(stderr, gettext("%s: %s: magic "
151 149 "table invalid string value\n"), File,
152 150 file);
153 151 return (NULL);
154 152 }
155 153 *s++ = (char)val;
156 154 } else {
157 155 /* escape the character */
158 156 switch (*p) {
159 157 case 'n':
160 158 *s = '\n';
161 159 break;
162 160 case 'r':
163 161 *s = '\r';
164 162 break;
165 163 case 'a':
166 164 *s = '\a';
167 165 break;
168 166 case 'b':
169 167 *s = '\b';
170 168 break;
171 169 case 'f':
172 170 *s = '\f';
173 171 break;
174 172 case 't':
175 173 *s = '\t';
176 174 break;
177 175 case 'v':
178 176 *s = '\v';
179 177 break;
180 178 default:
181 179 *s = *p;
182 180 break;
183 181 }
184 182 p++;
185 183 s++;
186 184 }
187 185 }
188 186 *s = '\0';
189 187 return (newstr);
190 188 }
191 189
192 190 /*
193 191 * f_mkmtab - fills mtab array of magic table entries with
194 192 * values from the file magfile.
195 193 * May be called more than once if multiple magic
196 194 * files were specified.
197 195 * Stores entries sequentially in one of two magic
198 196 * tables: mtab1, if first = 1; mtab2 otherwise.
199 197 *
200 198 * If -c option is specified, cflg is non-zero, and
201 199 * f_mkmtab() reports on errors in the magic file.
202 200 *
203 201 * Two magic tables may need to be created. The first
204 202 * one (mtab1) contains magic entries to be checked before
205 203 * the programmatic default position-sensitive tests in
206 204 * def_position_tests().
207 205 * The second one (mtab2) should start with the default
208 206 * /etc/magic file entries and is to be checked after
209 207 * the programmatic default position-sensitive tests in
210 208 * def_position_tests(). The parameter "first" would
211 209 * be 1 for the former set of tables, 0 for the latter
212 210 * set of magic tables.
213 211 * No mtab2 should be created if file will not be
214 212 * applying default tests; in that case, all magic table
215 213 * entries should be in mtab1.
216 214 *
217 215 * f_mkmtab returns 0 on success, -1 on error. The calling
218 216 * program is not expected to proceed after f_mkmtab()
219 217 * returns an error.
220 218 */
221 219
222 220 int
223 221 f_mkmtab(char *magfile, int cflg, int first)
224 222 {
225 223 Entry *mtab; /* generic magic table pointer */
226 224 Entry *ep; /* current magic table entry */
227 225 Entry *mend; /* one past last-allocated entry of mtab */
228 226 FILE *fp;
229 227 int lcnt = 0;
230 228 char buf[BSZ];
231 229 size_t tbsize;
232 230 size_t oldsize;
233 231
234 232 if (first) {
235 233 mtab = mtab1;
↓ open down ↓ |
192 lines elided |
↑ open up ↑ |
236 234 mend = mend1;
237 235 ep = ep1;
238 236 } else {
239 237 mtab = mtab2;
240 238 mend = mend2;
241 239 ep = ep2;
242 240 }
243 241
244 242 /* mtab may have been allocated on a previous f_mkmtab call */
245 243 if (mtab == (Entry *)NULL) {
246 - if ((mtab = calloc(sizeof (Entry), NENT)) == NULL) {
244 + if ((mtab = calloc(NENT, sizeof (Entry))) == NULL) {
247 245 int err = errno;
248 246 (void) fprintf(stderr, gettext("%s: malloc "
249 247 "failed: %s\n"), File, strerror(err));
250 248 return (-1);
251 249 }
252 250
253 251 ep = mtab;
254 252 mend = &mtab[NENT];
255 253 }
256 254
257 255 errno = 0;
258 256 if ((fp = fopen(magfile, "r")) == NULL) {
259 257 int err = errno;
260 258 (void) fprintf(stderr, gettext("%s: %s: cannot open magic "
261 259 "file: %s\n"), File, magfile, err ? strerror(err) : "");
262 260 return (-1);
263 261 }
264 262 while (fgets(buf, BSZ, fp) != NULL) {
265 263 char *p = buf;
266 264 char *p2;
267 265 char *p3;
268 266 char opc;
269 267
270 268 /*
271 269 * ensure we have one extra entry allocated
272 270 * to mark end of the table, after the while loop
273 271 */
274 272 if (ep >= (mend - 1)) {
275 273 oldsize = mend - mtab;
276 274 tbsize = (NENT + oldsize) * sizeof (Entry);
277 275 if ((mtab = realloc(mtab, tbsize)) == NULL) {
278 276 int err = errno;
279 277 (void) fprintf(stderr, gettext("%s: malloc "
280 278 "failed: %s\n"), File, strerror(err));
281 279 return (-1);
282 280 } else {
283 281 (void) memset(mtab + oldsize, 0,
284 282 sizeof (Entry) * NENT);
285 283 mend = &mtab[tbsize / sizeof (Entry)];
286 284 ep = &mtab[oldsize-1];
287 285 }
288 286 }
289 287
290 288 lcnt++;
291 289 if (*p == '\n' || *p == '#')
292 290 continue;
293 291
294 292
295 293 /* LEVEL */
296 294 if (*p == '>') {
297 295 ep->e_level = 1;
298 296 p++;
299 297 }
300 298 /* OFFSET */
301 299 p2 = strchr(p, '\t');
302 300 if (p2 == NULL) {
303 301 if (cflg)
304 302 (void) fprintf(stderr, gettext("%s: %s: format "
305 303 "error, no tab after %s on line %d\n"),
306 304 File, magfile, p, lcnt);
307 305 continue;
308 306 }
309 307 *p2++ = NULL;
310 308 ep->e_off = strtol((const char *)p, (char **)NULL, 0);
311 309 while (*p2 == '\t')
312 310 p2++;
313 311 /* TYPE */
314 312 p = p2;
315 313 p2 = strchr(p, '\t');
316 314 if (p2 == NULL) {
317 315 if (cflg)
318 316 (void) fprintf(stderr, gettext("%s: %s: format "
319 317 "error, no tab after %s on line %d\n"),
320 318 File, magfile, p, lcnt);
321 319 continue;
322 320 }
323 321 *p2++ = NULL;
324 322 p3 = strchr(p, '&');
325 323 if (p3 != NULL) {
326 324 *p3++ = '\0';
327 325 ep->e_mask = strtoull((const char *)p3, (char **)NULL,
328 326 0); /* returns 0 or ULLONG_MAX on error */
329 327 } else {
330 328 ep->e_mask = 0ULL;
331 329 }
332 330 switch (*p) {
333 331 case 'd':
334 332 if (*(p+1) == NULL) {
335 333 /* d */
336 334 ep->e_type = LONG;
337 335 } else if (*(p+2) == NULL) { /* d? */
338 336 switch (*(p+1)) {
339 337 case 'C':
340 338 case '1':
341 339 /* dC, d1 */
342 340 ep->e_type = BYTE;
343 341 break;
344 342 case 'S':
345 343 case '2':
346 344 /* dS, d2 */
347 345 ep->e_type = SHORT;
348 346 break;
349 347 case 'I':
350 348 case 'L':
351 349 case '4':
352 350 /* dI, dL, d4 */
353 351 ep->e_type = LONG;
354 352 break;
355 353 case '8':
356 354 /* d8 */
357 355 ep->e_type = LLONG;
358 356 break;
359 357 default:
360 358 ep->e_type = LONG;
361 359 break;
362 360 }
363 361 }
364 362 break;
365 363 case 'l':
366 364 if (*(p+1) == 'l') { /* llong */
367 365 ep->e_type = LLONG;
368 366 } else { /* long */
369 367 ep->e_type = LONG;
370 368 }
371 369 break;
372 370 case 's':
373 371 if (*(p+1) == 'h') {
374 372 /* short */
375 373 ep->e_type = SHORT;
376 374 } else {
377 375 /* s or string */
378 376 ep->e_type = STR;
379 377 }
380 378 break;
381 379 case 'u':
382 380 if (*(p+1) == NULL) {
383 381 /* u */
384 382 ep->e_type = ULONG;
385 383 } else if (*(p+2) == NULL) { /* u? */
386 384 switch (*(p+1)) {
387 385 case 'C':
388 386 case '1':
389 387 /* uC, u1 */
390 388 ep->e_type = UBYTE;
391 389 break;
392 390 case 'S':
393 391 case '2':
394 392 /* uS, u2 */
395 393 ep->e_type = USHORT;
396 394 break;
397 395 case 'I':
398 396 case 'L':
399 397 case '4':
400 398 /* uI, uL, u4 */
401 399 ep->e_type = ULONG;
402 400 break;
403 401 case '8':
404 402 /* u8 */
405 403 ep->e_type = ULLONG;
406 404 break;
407 405 default:
408 406 ep->e_type = ULONG;
409 407 break;
410 408 }
411 409 } else { /* u?* */
412 410 switch (*(p+1)) {
413 411 case 'b': /* ubyte */
414 412 ep->e_type = UBYTE;
415 413 break;
416 414 case 's': /* ushort */
417 415 ep->e_type = USHORT;
418 416 break;
419 417 case 'l':
420 418 if (*(p+2) == 'l') {
421 419 /* ullong */
422 420 ep->e_type = ULLONG;
423 421 } else {
424 422 /* ulong */
425 423 ep->e_type = ULONG;
426 424 }
427 425 break;
428 426 default:
429 427 /* default, same as "u" */
430 428 ep->e_type = ULONG;
431 429 break;
432 430 }
433 431 }
434 432 break;
435 433 default:
436 434 /* retain (undocumented) default type */
437 435 ep->e_type = BYTE;
438 436 break;
439 437 }
440 438 if (ep->e_type == 0) {
441 439 ep->e_type = BYTE; /* default */
442 440 }
443 441 while (*p2 == '\t')
444 442 p2++;
445 443 /* OP-VALUE */
446 444 p = p2;
447 445 p2 = strchr(p, '\t');
448 446 if (p2 == NULL) {
449 447 if (cflg)
450 448 (void) fprintf(stderr, gettext("%s: %s: format "
451 449 "error, no tab after %s on line %d\n"),
452 450 File, magfile, p, lcnt);
453 451 continue;
454 452 }
455 453 *p2++ = NULL;
456 454 if (ep->e_type != STR) {
457 455 opc = *p++;
458 456 switch (opc) {
459 457 case '=':
460 458 ep->e_opcode = EQ;
461 459 break;
462 460
463 461 case '>':
464 462 ep->e_opcode = GT;
465 463 break;
466 464
467 465 case '<':
468 466 ep->e_opcode = LT;
469 467 break;
470 468
471 469 case 'x':
472 470 ep->e_opcode = ANY;
473 471 break;
474 472
475 473 case '&':
476 474 ep->e_opcode = AND;
477 475 break;
478 476
479 477 case '^':
480 478 ep->e_opcode = NSET;
481 479 break;
482 480 default: /* EQ (i.e. 0) is default */
483 481 p--; /* since global ep->e_opcode=0 */
484 482 }
485 483 }
486 484 if (ep->e_opcode != ANY) {
487 485 if (ep->e_type != STR) {
488 486 ep->e_value.num = strtoull((const char *)p,
489 487 (char **)NULL, 0);
490 488 } else if ((ep->e_value.str =
491 489 getstr(p, magfile)) == NULL) {
492 490 return (-1);
493 491 }
494 492 }
495 493 p2 += strspn(p2, "\t");
496 494 /* STRING */
497 495 if ((ep->e_str = strdup(p2)) == NULL) {
498 496 int err = errno;
499 497 (void) fprintf(stderr, gettext("%s: malloc "
500 498 "failed: %s\n"), File, strerror(err));
501 499 return (-1);
502 500 } else {
503 501 if ((p = strchr(ep->e_str, '\n')) != NULL)
504 502 *p = '\0';
505 503 if (strchr(ep->e_str, '%') != NULL)
506 504 ep->e_opcode |= SUB;
507 505 }
508 506 ep++;
509 507 } /* end while (fgets) */
510 508
511 509 ep->e_off = -1L; /* mark end of table */
512 510 if (first) {
513 511 mtab1 = mtab;
514 512 mend1 = mend;
515 513 ep1 = ep;
516 514 } else {
517 515 mtab2 = mtab;
518 516 mend2 = mend;
519 517 ep2 = ep;
520 518 }
521 519 if (fclose(fp) != 0) {
522 520 int err = errno;
523 521 (void) fprintf(stderr, gettext("%s: fclose failed: %s\n"),
524 522 File, strerror(err));
525 523 return (-1);
526 524 }
527 525 return (0);
528 526 }
529 527
530 528 /*
531 529 * Check for Magic Table entries in the file.
532 530 *
533 531 * Since there may be two sets of magic tables, first = 1
534 532 * for the first magic table (mtab1) and 0 for the second magic
535 533 * table (mtab2).
536 534 */
537 535 int
538 536 f_ckmtab(char *buf, int bufsize, int first)
539 537 {
540 538 int result;
541 539 Entry *mtab;
542 540 Entry *ep;
543 541 char *p;
544 542 int lev1 = 0;
545 543
546 544 uint16_t u16_val;
547 545 uint32_t u32_val;
548 546 uint64_t u64_val;
549 547
550 548 if (first) {
551 549 mtab = mtab1;
552 550 } else {
553 551 mtab = mtab2;
554 552 }
555 553
556 554 if (mtab == (Entry *)NULL) {
557 555 return (0); /* no magic file tests in this table */
558 556 }
559 557
560 558 for (ep = mtab; ep->e_off != -1L; ep++) { /* -1 offset marks end of */
561 559 if (lev1) { /* valid magic file entries */
562 560 if (ep->e_level != 1)
563 561 break;
564 562 } else if (ep->e_level == 1) {
565 563 continue;
566 564 }
567 565 if (ep->e_off > (off_t)bufsize)
568 566 continue;
569 567 p = &buf[ep->e_off];
570 568 switch (ep->e_type) {
571 569 case STR:
572 570 {
573 571 if (strncmp(p, ep->e_value.str,
574 572 strlen(ep->e_value.str)))
575 573 continue;
576 574 if (lev1) {
577 575 (void) putchar(' ');
578 576 }
579 577 if (ep->e_opcode & SUB)
580 578 (void) printf(ep->e_str,
581 579 ep->e_value.str);
582 580 else
583 581 (void) printf(ep->e_str);
584 582 lev1 = 1;
585 583 continue;
586 584 /*
587 585 * We've matched the string and printed the message;
588 586 * no STR processing occurs beyond this point.
589 587 */
590 588 }
591 589
592 590 case BYTE:
593 591 case UBYTE:
594 592 u64_val = (uint64_t)(uint8_t)(*p);
595 593 break;
596 594
597 595 case SHORT:
598 596 case USHORT:
599 597 (void) memcpy(&u16_val, p, sizeof (uint16_t));
600 598 u64_val = (uint64_t)u16_val;
601 599 break;
602 600
603 601 case LONG:
604 602 case ULONG:
605 603 (void) memcpy(&u32_val, p, sizeof (uint32_t));
606 604 u64_val = (uint64_t)u32_val;
607 605 break;
608 606
609 607 case LLONG:
610 608 case ULLONG:
611 609 (void) memcpy(&(u64_val), p, sizeof (uint64_t));
612 610 break;
613 611
614 612 }
615 613
616 614 if (ep->e_mask) {
617 615 u64_val &= ep->e_mask;
618 616 }
619 617
620 618 /*
621 619 * Compare the values according to the size and sign
622 620 * of the type. For =, &, and ^ operators, the sign
623 621 * does not have any effect, so these are always compared
624 622 * unsigned. Only for < and > operators is the
625 623 * sign significant.
626 624 * If the file value was masked, the compare should
627 625 * be unsigned.
628 626 */
629 627 switch (ep->e_opcode & ~SUB) {
630 628 case EQ:
631 629 switch (ep->e_type) {
632 630 case BYTE:
633 631 case UBYTE:
634 632 if ((uint8_t)u64_val !=
635 633 (uint8_t)(ep->e_value.num))
636 634 continue;
637 635 break;
638 636 case SHORT:
639 637 case USHORT:
640 638 if ((uint16_t)u64_val !=
641 639 (uint16_t)(ep->e_value.num))
642 640 continue;
643 641 break;
644 642 case LONG:
645 643 case ULONG:
646 644 if ((uint32_t)u64_val !=
647 645 (uint32_t)(ep->e_value.num))
648 646 continue;
649 647 break;
650 648 case LLONG:
651 649 case ULLONG:
652 650 if (u64_val != ep->e_value.num)
653 651 continue;
654 652 break;
655 653 default:
656 654 continue;
657 655 }
658 656 break;
659 657 case GT:
660 658 switch (ep->e_type) {
661 659 case BYTE:
662 660 if (ep->e_mask == 0) {
663 661 if ((int8_t)u64_val <=
664 662 (int8_t)(ep->e_value.num))
665 663 continue;
666 664 break;
667 665 }
668 666 /*FALLTHROUGH*/
669 667 case UBYTE:
670 668 if ((uint8_t)u64_val <=
671 669 (uint8_t)(ep->e_value.num))
672 670 continue;
673 671 break;
674 672 case SHORT:
675 673 if (ep->e_mask == 0) {
676 674 if ((int16_t)u64_val <=
677 675 (int16_t)(ep->e_value.num))
678 676 continue;
679 677 break;
680 678 }
681 679 /*FALLTHROUGH*/
682 680 case USHORT:
683 681 if ((uint16_t)u64_val <=
684 682 (uint16_t)(ep->e_value.num))
685 683 continue;
686 684 break;
687 685 case LONG:
688 686 if (ep->e_mask == 0) {
689 687 if ((int32_t)u64_val <=
690 688 (int32_t)(ep->e_value.num))
691 689 continue;
692 690 break;
693 691 }
694 692 /*FALLTHROUGH*/
695 693 case ULONG:
696 694 if ((uint32_t)u64_val <=
697 695 (uint32_t)(ep->e_value.num))
698 696 continue;
699 697 break;
700 698 case LLONG:
701 699 if (ep->e_mask == 0) {
702 700 if ((int64_t)u64_val <=
703 701 (int64_t)(ep->e_value.num))
704 702 continue;
705 703 break;
706 704 }
707 705 /*FALLTHROUGH*/
708 706 case ULLONG:
709 707 if (u64_val <= ep->e_value.num)
710 708 continue;
711 709 break;
712 710 default:
713 711 continue;
714 712 }
715 713 break;
716 714 case LT:
717 715 switch (ep->e_type) {
718 716 case BYTE:
719 717 if (ep->e_mask == 0) {
720 718 if ((int8_t)u64_val >=
721 719 (int8_t)(ep->e_value.num))
722 720 continue;
723 721 break;
724 722 }
725 723 /*FALLTHROUGH*/
726 724 case UBYTE:
727 725 if ((uint8_t)u64_val >=
728 726 (uint8_t)(ep->e_value.num))
729 727 continue;
730 728 break;
731 729 case SHORT:
732 730 if (ep->e_mask == 0) {
733 731 if ((int16_t)u64_val >=
734 732 (int16_t)(ep->e_value.num))
735 733 continue;
736 734 break;
737 735 }
738 736 /*FALLTHROUGH*/
739 737 case USHORT:
740 738 if ((uint16_t)u64_val >=
741 739 (uint16_t)(ep->e_value.num))
742 740 continue;
743 741 break;
744 742 case LONG:
745 743 if (ep->e_mask == 0) {
746 744 if ((int32_t)u64_val >=
747 745 (int32_t)(ep->e_value.num))
748 746 continue;
749 747 break;
750 748 }
751 749 /*FALLTHROUGH*/
752 750 case ULONG:
753 751 if ((uint32_t)u64_val >=
754 752 (uint32_t)(ep->e_value.num))
755 753 continue;
756 754 break;
757 755 case LLONG:
758 756 if (ep->e_mask == 0) {
759 757 if ((int64_t)u64_val >=
760 758 (int64_t)(ep->e_value.num))
761 759 continue;
762 760 break;
763 761 }
764 762 /*FALLTHROUGH*/
765 763 case ULLONG:
766 764 if (u64_val >= ep->e_value.num)
767 765 continue;
768 766 break;
769 767 default:
770 768 continue;
771 769 }
772 770 break;
773 771 case AND:
774 772 switch (ep->e_type) {
775 773 case BYTE:
776 774 case UBYTE:
777 775 if (((uint8_t)u64_val &
778 776 (uint8_t)(ep->e_value.num)) ==
779 777 (uint8_t)(ep->e_value.num))
780 778 break;
781 779 continue;
782 780 case SHORT:
783 781 case USHORT:
784 782 if (((uint16_t)u64_val &
785 783 (uint16_t)(ep->e_value.num)) ==
786 784 (uint16_t)(ep->e_value.num))
787 785 break;
788 786 continue;
789 787 case LONG:
790 788 case ULONG:
791 789 if (((uint32_t)u64_val &
792 790 (uint32_t)(ep->e_value.num)) ==
793 791 (uint32_t)(ep->e_value.num))
794 792 break;
795 793 continue;
796 794 case LLONG:
797 795 case ULLONG:
798 796 if ((u64_val & ep->e_value.num) ==
799 797 ep->e_value.num)
800 798 break;
801 799 continue;
802 800 default:
803 801 continue;
804 802 }
805 803 break;
806 804 case NSET:
807 805 switch (ep->e_type) {
808 806 case BYTE:
809 807 case UBYTE:
810 808 if (((uint8_t)u64_val &
811 809 (uint8_t)(ep->e_value.num)) !=
812 810 (uint8_t)(ep->e_value.num))
813 811 break;
814 812 continue;
815 813 case SHORT:
816 814 case USHORT:
817 815 if (((uint16_t)u64_val &
818 816 (uint16_t)(ep->e_value.num)) !=
819 817 (uint16_t)(ep->e_value.num))
820 818 break;
821 819 continue;
822 820 case LONG:
823 821 case ULONG:
824 822 if (((uint32_t)u64_val &
825 823 (uint32_t)(ep->e_value.num)) !=
826 824 (uint32_t)(ep->e_value.num))
827 825 break;
828 826 continue;
829 827 case LLONG:
830 828 case ULLONG:
831 829 if ((u64_val & ep->e_value.num) !=
832 830 ep->e_value.num)
833 831 break;
834 832 continue;
835 833 default:
836 834 continue;
837 835 }
838 836 break;
839 837 case ANY: /* matches anything */
840 838 break;
841 839 default: /* shouldn't occur; ignore it */
842 840 continue;
843 841 }
844 842 if (lev1)
845 843 (void) putchar(' ');
846 844 if (ep->e_opcode & SUB) {
847 845 switch (ep->e_type) {
848 846 case LLONG:
849 847 #ifdef XPG4
850 848 if (ep->e_mask == 0) {
851 849 (void) printf(ep->e_str,
852 850 (int64_t)u64_val);
853 851 break;
854 852 }
855 853 #endif /* XPG4 */
856 854 /*FALLTHROUGH*/
857 855 case ULLONG:
858 856 (void) printf(ep->e_str, u64_val);
859 857 break;
860 858 case LONG:
861 859 #ifdef XPG4
862 860 if (ep->e_mask == 0) {
863 861 (void) printf(ep->e_str,
864 862 (int32_t)u64_val);
865 863 break;
866 864 }
867 865 #endif /* XPG4 */
868 866 /*FALLTHROUGH*/
869 867 case ULONG:
870 868 (void) printf(ep->e_str,
871 869 (uint32_t)u64_val);
872 870 break;
873 871 case SHORT:
874 872 #ifdef XPG4
875 873 if (ep->e_mask == 0) {
876 874 (void) printf(ep->e_str,
877 875 (int16_t)u64_val);
878 876 break;
879 877 }
880 878 #endif /* XPG4 */
881 879 /*FALLTHROUGH*/
882 880 case USHORT:
883 881 (void) printf(ep->e_str,
884 882 (uint16_t)u64_val);
885 883 break;
886 884 case BYTE:
887 885 #ifdef XPG4
888 886 if (ep->e_mask == 0) {
889 887 (void) printf(ep->e_str,
890 888 (int8_t)u64_val);
891 889 break;
892 890 }
893 891 #endif /* XPG4 */
894 892 /*FALLTHROUGH*/
895 893 case UBYTE:
896 894 (void) printf(ep->e_str,
897 895 (uint8_t)u64_val);
898 896 break;
899 897 case STR:
900 898 /*
901 899 * Note: Currently can't get type
902 900 * STR here because we already
903 901 * did a 'continue' out of the
904 902 * loop earlier for case STR
905 903 */
906 904 break;
907 905 }
908 906 } else
909 907 (void) printf(ep->e_str);
910 908 lev1 = 1;
911 909 }
912 910 result = lev1 ? (int)(1 + ep - mtab) : 0;
913 911
914 912 return (result);
915 913 }
916 914
917 915 static void
918 916 showstr(char *s, int width)
919 917 {
920 918 char c;
921 919
922 920 while ((c = *s++) != '\0')
923 921 if (c >= 040 && c < 0176) {
924 922 (void) putchar(c);
925 923 width--;
926 924 } else {
927 925 (void) putchar('\\');
928 926 switch (c) {
929 927
930 928 case '\n':
931 929 (void) putchar('n');
932 930 width -= 2;
933 931 break;
934 932
935 933 case '\r':
936 934 (void) putchar('r');
937 935 width -= 2;
938 936 break;
939 937
940 938 case '\a':
941 939 (void) putchar('a');
942 940 width -= 2;
943 941 break;
944 942
945 943 case '\b':
946 944 (void) putchar('b');
947 945 width -= 2;
948 946 break;
949 947
950 948 case '\t':
951 949 (void) putchar('t');
952 950 width -= 2;
953 951 break;
954 952
955 953 case '\f':
956 954 (void) putchar('f');
957 955 width -= 2;
958 956 break;
959 957
960 958 case '\v':
961 959 (void) putchar('v');
962 960 width -= 2;
963 961 break;
964 962
965 963 default:
966 964 (void) printf("%.3o", c & 0377);
967 965 width -= 4;
968 966 break;
969 967 }
970 968 }
971 969 while (width >= 0) {
972 970 (void) putchar(' ');
973 971 width--;
974 972 };
975 973 }
976 974
977 975 static char *
978 976 type_to_name(Entry *ep)
979 977 {
980 978 static char buf[20];
981 979 char *s;
982 980
983 981 switch (ep->e_type) {
984 982 case BYTE:
985 983 s = "byte";
986 984 break;
987 985 case SHORT:
988 986 s = "short";
989 987 break;
990 988 case LONG:
991 989 s = "long";
992 990 break;
993 991 case LLONG:
994 992 s = "llong";
995 993 break;
996 994 case UBYTE:
997 995 s = "ubyte";
998 996 break;
999 997 case USHORT:
1000 998 s = "ushort";
1001 999 break;
1002 1000 case ULONG:
1003 1001 s = "ulong";
1004 1002 break;
1005 1003 case ULLONG:
1006 1004 s = "ullong";
1007 1005 break;
1008 1006 case STR:
1009 1007 return ("string");
1010 1008 default:
1011 1009 /* more of an emergency measure .. */
1012 1010 (void) sprintf(buf, "%d", ep->e_type);
1013 1011 return (buf);
1014 1012 }
1015 1013 if (ep->e_mask) {
1016 1014 (void) snprintf(buf, sizeof (buf), "%s&0x%llx", s, ep->e_mask);
1017 1015 return (buf);
1018 1016 } else
1019 1017 return (s);
1020 1018 }
1021 1019
1022 1020 static char
1023 1021 op_to_name(char op)
1024 1022 {
1025 1023 char c;
1026 1024
1027 1025 switch (op & ~SUB) {
1028 1026
1029 1027 case EQ:
1030 1028 case STRC:
1031 1029 c = '=';
1032 1030 break;
1033 1031
1034 1032 case GT:
1035 1033 c = '>';
1036 1034 break;
1037 1035
1038 1036 case LT:
1039 1037 c = '<';
1040 1038 break;
1041 1039
1042 1040 case ANY:
1043 1041 c = 'x';
1044 1042 break;
1045 1043
1046 1044 case AND:
1047 1045 c = '&';
1048 1046 break;
1049 1047
1050 1048 case NSET:
1051 1049 c = '^';
1052 1050 break;
1053 1051
1054 1052 default:
1055 1053 c = '?';
1056 1054 break;
1057 1055 }
1058 1056
1059 1057 return (c);
1060 1058 }
1061 1059
1062 1060 /*
1063 1061 * f_prtmtab - Prints out a header, then entries from both magic
1064 1062 * tables, mtab1 and mtab2, if any exist.
1065 1063 */
1066 1064 void
1067 1065 f_prtmtab(void)
1068 1066 {
1069 1067 Entry *mtab;
1070 1068 Entry *ep;
1071 1069 int count;
1072 1070
1073 1071 (void) printf("%-7s %-7s %-10s %-7s %-11s %s\n",
1074 1072 "level", "off", "type", "opcode", "value", "string");
1075 1073 for (mtab = mtab1, count = 1; count <= 2; count++, mtab = mtab2) {
1076 1074 if (mtab == (Entry *)NULL) {
1077 1075 continue;
1078 1076 }
1079 1077 for (ep = mtab; ep->e_off != -1L; ep++) {
1080 1078 (void) printf("%-7d %-7ld %-10s %-7c ",
1081 1079 ep->e_level,
1082 1080 ep->e_off, type_to_name(ep),
1083 1081 op_to_name(ep->e_opcode));
1084 1082 if (ep->e_type == STR) {
1085 1083 showstr(ep->e_value.str, 10);
1086 1084 } else { /* numeric */
1087 1085 (void) printf("%-#11llo", ep->e_value.num);
1088 1086 }
1089 1087 (void) printf(" %s", ep->e_str);
1090 1088 if (ep->e_opcode & SUB)
1091 1089 (void) printf("\tsubst");
1092 1090 (void) printf("\n");
1093 1091 }
1094 1092 }
1095 1093 }
1096 1094
1097 1095 intmax_t
1098 1096 f_getmaxoffset(int first)
1099 1097 {
1100 1098 Entry *mtab;
1101 1099 Entry *ep;
1102 1100 intmax_t cur;
1103 1101 intmax_t max = 0;
1104 1102
1105 1103 if (first) {
1106 1104 mtab = mtab1;
1107 1105 } else {
1108 1106 mtab = mtab2;
1109 1107 }
1110 1108 if (mtab == (Entry *)NULL) {
1111 1109 return (0);
1112 1110 }
1113 1111 for (ep = mtab; ep->e_off != -1L; ep++) {
1114 1112 cur = ep->e_off;
1115 1113 switch (ep->e_type) {
1116 1114 case STR:
1117 1115 cur += strlen(ep->e_value.str);
1118 1116 break;
1119 1117 case BYTE:
1120 1118 case UBYTE:
1121 1119 cur += sizeof (uchar_t);
1122 1120 break;
1123 1121 case SHORT:
1124 1122 case USHORT:
1125 1123 cur += sizeof (uint16_t);
1126 1124 break;
1127 1125 case LONG:
1128 1126 case ULONG:
1129 1127 cur += sizeof (uint32_t);
1130 1128 break;
1131 1129 case LLONG:
1132 1130 case ULLONG:
1133 1131 cur += sizeof (uint64_t);
1134 1132 break;
1135 1133 }
1136 1134 if (cur <= INT_MAX && cur > max) {
1137 1135 max = cur;
1138 1136 }
1139 1137 }
1140 1138
1141 1139 return (max);
1142 1140 }
↓ open down ↓ |
886 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX