apprentice.c (133359) | apprentice.c (139368) |
---|---|
1/* 2 * Copyright (c) Ian F. Darwin 1986-1995. 3 * Software written by Ian F. Darwin and others; 4 * maintained 1995-present by Christos Zoulas and others. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice immediately at the beginning of the file, without modification, 11 * this list of conditions, and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. | 1/* 2 * Copyright (c) Ian F. Darwin 1986-1995. 3 * Software written by Ian F. Darwin and others; 4 * maintained 1995-present by Christos Zoulas and others. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice immediately at the beginning of the file, without modification, 11 * this list of conditions, and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. |
15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Ian F. Darwin and others. 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. | |
20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 25 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) --- 17 unchanged lines hidden (view full) --- 45#include <fcntl.h> 46#include <sys/stat.h> 47#include <sys/param.h> 48#ifdef QUICK 49#include <sys/mman.h> 50#endif 51 52#ifndef lint | 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) --- 17 unchanged lines hidden (view full) --- 40#include <fcntl.h> 41#include <sys/stat.h> 42#include <sys/param.h> 43#ifdef QUICK 44#include <sys/mman.h> 45#endif 46 47#ifndef lint |
53FILE_RCSID("@(#)$Id: apprentice.c,v 1.78 2004/07/24 20:38:56 christos Exp $") | 48FILE_RCSID("@(#)$Id: apprentice.c,v 1.82 2004/11/24 18:56:04 christos Exp $") |
54#endif /* lint */ 55 56#define EATAB {while (isascii((unsigned char) *l) && \ 57 isspace((unsigned char) *l)) ++l;} 58#define LOWCASE(l) (isupper((unsigned char) (l)) ? \ 59 tolower((unsigned char) (l)) : (l)) 60/* 61 * Work around a bug in headers on Digital Unix. --- 12 unchanged lines hidden (view full) --- 74#ifndef MAP_FILE 75#define MAP_FILE 0 76#endif 77 78#ifndef MAXPATHLEN 79#define MAXPATHLEN 1024 80#endif 81 | 49#endif /* lint */ 50 51#define EATAB {while (isascii((unsigned char) *l) && \ 52 isspace((unsigned char) *l)) ++l;} 53#define LOWCASE(l) (isupper((unsigned char) (l)) ? \ 54 tolower((unsigned char) (l)) : (l)) 55/* 56 * Work around a bug in headers on Digital Unix. --- 12 unchanged lines hidden (view full) --- 69#ifndef MAP_FILE 70#define MAP_FILE 0 71#endif 72 73#ifndef MAXPATHLEN 74#define MAXPATHLEN 1024 75#endif 76 |
77#define IS_STRING(t) ((t) == FILE_STRING || (t) == FILE_PSTRING || \ 78 (t) == FILE_BESTRING16 || (t) == FILE_LESTRING16) 79 |
|
82private int getvalue(struct magic_set *ms, struct magic *, char **); 83private int hextoint(int); 84private char *getstr(struct magic_set *, char *, char *, int, int *); 85private int parse(struct magic_set *, struct magic **, uint32_t *, char *, int); 86private void eatsize(char **); 87private int apprentice_1(struct magic_set *, const char *, int, struct mlist *); 88private int apprentice_file(struct magic_set *, struct magic **, uint32_t *, 89 const char *, int); 90private void byteswap(struct magic *, uint32_t); 91private void bs1(struct magic *); 92private uint16_t swap2(uint16_t); 93private uint32_t swap4(uint32_t); | 80private int getvalue(struct magic_set *ms, struct magic *, char **); 81private int hextoint(int); 82private char *getstr(struct magic_set *, char *, char *, int, int *); 83private int parse(struct magic_set *, struct magic **, uint32_t *, char *, int); 84private void eatsize(char **); 85private int apprentice_1(struct magic_set *, const char *, int, struct mlist *); 86private int apprentice_file(struct magic_set *, struct magic **, uint32_t *, 87 const char *, int); 88private void byteswap(struct magic *, uint32_t); 89private void bs1(struct magic *); 90private uint16_t swap2(uint16_t); 91private uint32_t swap4(uint32_t); |
94private char *mkdbname(const char *, char *, size_t); | 92private char *mkdbname(const char *, char *, size_t, int); |
95private int apprentice_map(struct magic_set *, struct magic **, uint32_t *, 96 const char *); 97private int apprentice_compile(struct magic_set *, struct magic **, uint32_t *, 98 const char *); | 93private int apprentice_map(struct magic_set *, struct magic **, uint32_t *, 94 const char *); 95private int apprentice_compile(struct magic_set *, struct magic **, uint32_t *, 96 const char *); |
99private int check_format(struct magic *); | 97private int check_format(struct magic_set *, struct magic *); |
100 101private size_t maxmagic = 0; 102private size_t magicsize = sizeof(struct magic); 103 104#ifdef COMPILE_ONLY 105 106int main(int, char *[]); 107 --- 53 unchanged lines hidden (view full) --- 161 return -1; 162 rv = apprentice_compile(ms, &magic, &nmagic, fn); 163 free(magic); 164 return rv; 165 } 166#ifndef COMPILE_ONLY 167 if ((rv = apprentice_map(ms, &magic, &nmagic, fn)) == -1) { 168 if (ms->flags & MAGIC_CHECK) | 98 99private size_t maxmagic = 0; 100private size_t magicsize = sizeof(struct magic); 101 102#ifdef COMPILE_ONLY 103 104int main(int, char *[]); 105 --- 53 unchanged lines hidden (view full) --- 159 return -1; 160 rv = apprentice_compile(ms, &magic, &nmagic, fn); 161 free(magic); 162 return rv; 163 } 164#ifndef COMPILE_ONLY 165 if ((rv = apprentice_map(ms, &magic, &nmagic, fn)) == -1) { 166 if (ms->flags & MAGIC_CHECK) |
169 file_magwarn("using regular magic file `%s'", fn); | 167 file_magwarn(ms, "using regular magic file `%s'", fn); |
170 rv = apprentice_file(ms, &magic, &nmagic, fn, action); 171 if (rv != 0) 172 return -1; 173 mapped = 0; 174 } 175 176 if (rv == -1) 177 return rv; --- 114 unchanged lines hidden (view full) --- 292private int 293apprentice_file(struct magic_set *ms, struct magic **magicp, uint32_t *nmagicp, 294 const char *fn, int action) 295{ 296 private const char hdr[] = 297 "cont\toffset\ttype\topcode\tmask\tvalue\tdesc"; 298 FILE *f; 299 char line[BUFSIZ+1]; | 168 rv = apprentice_file(ms, &magic, &nmagic, fn, action); 169 if (rv != 0) 170 return -1; 171 mapped = 0; 172 } 173 174 if (rv == -1) 175 return rv; --- 114 unchanged lines hidden (view full) --- 290private int 291apprentice_file(struct magic_set *ms, struct magic **magicp, uint32_t *nmagicp, 292 const char *fn, int action) 293{ 294 private const char hdr[] = 295 "cont\toffset\ttype\topcode\tmask\tvalue\tdesc"; 296 FILE *f; 297 char line[BUFSIZ+1]; |
300 int lineno; | |
301 int errs = 0; 302 | 298 int errs = 0; 299 |
303 f = fopen(fn, "r"); | 300 f = fopen(ms->file = fn, "r"); |
304 if (f == NULL) { 305 if (errno != ENOENT) 306 file_error(ms, errno, "cannot read magic file `%s'", 307 fn); 308 return -1; 309 } 310 311 maxmagic = MAXMAGIS; --- 4 unchanged lines hidden (view full) --- 316 return -1; 317 } 318 319 /* print silly verbose header for USG compat. */ 320 if (action == FILE_CHECK) 321 (void)fprintf(stderr, "%s\n", hdr); 322 323 /* parse it */ | 301 if (f == NULL) { 302 if (errno != ENOENT) 303 file_error(ms, errno, "cannot read magic file `%s'", 304 fn); 305 return -1; 306 } 307 308 maxmagic = MAXMAGIS; --- 4 unchanged lines hidden (view full) --- 313 return -1; 314 } 315 316 /* print silly verbose header for USG compat. */ 317 if (action == FILE_CHECK) 318 (void)fprintf(stderr, "%s\n", hdr); 319 320 /* parse it */ |
324 for (lineno = 1; fgets(line, BUFSIZ, f) != NULL; lineno++) { | 321 for (ms->line = 1; fgets(line, BUFSIZ, f) != NULL; ms->line++) { 322 size_t len; |
325 if (line[0]=='#') /* comment, do not parse */ 326 continue; | 323 if (line[0]=='#') /* comment, do not parse */ 324 continue; |
327 if (strlen(line) <= (unsigned)1) /* null line, garbage, etc */ | 325 len = strlen(line); 326 if (len < 2) /* null line, garbage, etc */ |
328 continue; | 327 continue; |
329 line[strlen(line)-1] = '\0'; /* delete newline */ | 328 line[len - 1] = '\0'; /* delete newline */ |
330 if (parse(ms, magicp, nmagicp, line, action) != 0) 331 errs = 1; 332 } 333 334 (void)fclose(f); 335 if (errs) { 336 free(*magicp); 337 *magicp = NULL; --- 31 unchanged lines hidden (view full) --- 369 case FILE_LELDATE: 370 case FILE_LONG: 371 case FILE_BELONG: 372 case FILE_LELONG: 373 v = (int32_t) v; 374 break; 375 case FILE_STRING: 376 case FILE_PSTRING: | 329 if (parse(ms, magicp, nmagicp, line, action) != 0) 330 errs = 1; 331 } 332 333 (void)fclose(f); 334 if (errs) { 335 free(*magicp); 336 *magicp = NULL; --- 31 unchanged lines hidden (view full) --- 368 case FILE_LELDATE: 369 case FILE_LONG: 370 case FILE_BELONG: 371 case FILE_LELONG: 372 v = (int32_t) v; 373 break; 374 case FILE_STRING: 375 case FILE_PSTRING: |
376 case FILE_BESTRING16: 377 case FILE_LESTRING16: |
|
377 break; 378 case FILE_REGEX: 379 break; 380 default: 381 if (ms->flags & MAGIC_CHECK) | 378 break; 379 case FILE_REGEX: 380 break; 381 default: 382 if (ms->flags & MAGIC_CHECK) |
382 file_magwarn("cannot happen: m->type=%d\n", | 383 file_magwarn(ms, "cannot happen: m->type=%d\n", |
383 m->type); 384 return ~0U; 385 } 386 return v; 387} 388 389/* 390 * parse one line from magic file, put into magic[index++] if valid --- 39 unchanged lines hidden (view full) --- 430 ++l; /* step over */ 431 m->flag |= OFFADD; 432 } 433 434 /* get offset, then skip over it */ 435 m->offset = (uint32_t)strtoul(l, &t, 0); 436 if (l == t) 437 if (ms->flags & MAGIC_CHECK) | 384 m->type); 385 return ~0U; 386 } 387 return v; 388} 389 390/* 391 * parse one line from magic file, put into magic[index++] if valid --- 39 unchanged lines hidden (view full) --- 431 ++l; /* step over */ 432 m->flag |= OFFADD; 433 } 434 435 /* get offset, then skip over it */ 436 m->offset = (uint32_t)strtoul(l, &t, 0); 437 if (l == t) 438 if (ms->flags & MAGIC_CHECK) |
438 file_magwarn("offset %s invalid", l); | 439 file_magwarn(ms, "offset `%s' invalid", l); |
439 l = t; 440 441 if (m->flag & INDIR) { 442 m->in_type = FILE_LONG; 443 m->in_offset = 0; 444 /* 445 * read [.lbs][+-]nnnnn) 446 */ --- 17 unchanged lines hidden (view full) --- 464 case 'c': 465 case 'b': 466 case 'C': 467 case 'B': 468 m->in_type = FILE_BYTE; 469 break; 470 default: 471 if (ms->flags & MAGIC_CHECK) | 440 l = t; 441 442 if (m->flag & INDIR) { 443 m->in_type = FILE_LONG; 444 m->in_offset = 0; 445 /* 446 * read [.lbs][+-]nnnnn) 447 */ --- 17 unchanged lines hidden (view full) --- 465 case 'c': 466 case 'b': 467 case 'C': 468 case 'B': 469 m->in_type = FILE_BYTE; 470 break; 471 default: 472 if (ms->flags & MAGIC_CHECK) |
472 file_magwarn( 473 "indirect offset type %c invalid", | 473 file_magwarn(ms, 474 "indirect offset type `%c' invalid", |
474 *l); 475 break; 476 } 477 l++; 478 } 479 if (*l == '~') { 480 m->in_op = FILE_OPINVERSE; 481 l++; --- 33 unchanged lines hidden (view full) --- 515 break; 516 } 517 if (isdigit((unsigned char)*l)) 518 m->in_offset = (uint32_t)strtoul(l, &t, 0); 519 else 520 t = l; 521 if (*t++ != ')') 522 if (ms->flags & MAGIC_CHECK) | 475 *l); 476 break; 477 } 478 l++; 479 } 480 if (*l == '~') { 481 m->in_op = FILE_OPINVERSE; 482 l++; --- 33 unchanged lines hidden (view full) --- 516 break; 517 } 518 if (isdigit((unsigned char)*l)) 519 m->in_offset = (uint32_t)strtoul(l, &t, 0); 520 else 521 t = l; 522 if (*t++ != ')') 523 if (ms->flags & MAGIC_CHECK) |
523 file_magwarn("missing ')' in indirect offset"); | 524 file_magwarn(ms, 525 "missing ')' in indirect offset"); |
524 l = t; 525 } 526 527 528 while (isascii((unsigned char)*l) && isdigit((unsigned char)*l)) 529 ++l; 530 EATAB; 531 --- 8 unchanged lines hidden (view full) --- 540#define NLESHORT 7 541#define NLELONG 6 542#define NLEDATE 6 543#define NPSTRING 7 544#define NLDATE 5 545#define NBELDATE 7 546#define NLELDATE 7 547#define NREGEX 5 | 526 l = t; 527 } 528 529 530 while (isascii((unsigned char)*l) && isdigit((unsigned char)*l)) 531 ++l; 532 EATAB; 533 --- 8 unchanged lines hidden (view full) --- 542#define NLESHORT 7 543#define NLELONG 6 544#define NLEDATE 6 545#define NPSTRING 7 546#define NLDATE 5 547#define NBELDATE 7 548#define NLELDATE 7 549#define NREGEX 5 |
550#define NBESTRING16 10 551#define NLESTRING16 10 |
|
548 549 if (*l == 'u') { 550 ++l; 551 m->flag |= UNSIGNED; 552 } 553 554 /* get type, skip it */ 555 if (strncmp(l, "char", NBYTE)==0) { /* HP/UX compat */ --- 41 unchanged lines hidden (view full) --- 597 } else if (strncmp(l, "beldate", NBELDATE)==0) { 598 m->type = FILE_BELDATE; 599 l += NBELDATE; 600 } else if (strncmp(l, "leldate", NLELDATE)==0) { 601 m->type = FILE_LELDATE; 602 l += NLELDATE; 603 } else if (strncmp(l, "regex", NREGEX)==0) { 604 m->type = FILE_REGEX; | 552 553 if (*l == 'u') { 554 ++l; 555 m->flag |= UNSIGNED; 556 } 557 558 /* get type, skip it */ 559 if (strncmp(l, "char", NBYTE)==0) { /* HP/UX compat */ --- 41 unchanged lines hidden (view full) --- 601 } else if (strncmp(l, "beldate", NBELDATE)==0) { 602 m->type = FILE_BELDATE; 603 l += NBELDATE; 604 } else if (strncmp(l, "leldate", NLELDATE)==0) { 605 m->type = FILE_LELDATE; 606 l += NLELDATE; 607 } else if (strncmp(l, "regex", NREGEX)==0) { 608 m->type = FILE_REGEX; |
605 l += sizeof("regex"); | 609 l += NREGEX; 610 } else if (strncmp(l, "bestring16", NBESTRING16)==0) { 611 m->type = FILE_BESTRING16; 612 l += NBESTRING16; 613 } else if (strncmp(l, "lestring16", NLESTRING16)==0) { 614 m->type = FILE_LESTRING16; 615 l += NLESTRING16; |
606 } else { 607 if (ms->flags & MAGIC_CHECK) | 616 } else { 617 if (ms->flags & MAGIC_CHECK) |
608 file_magwarn("type %s invalid", l); | 618 file_magwarn(ms, "type `%s' invalid", l); |
609 return -1; 610 } 611 /* New-style anding: "0 byte&0x80 =0x80 dynamically linked" */ 612 /* New and improved: ~ & | ^ + - * / % -- exciting, isn't it? */ 613 if (*l == '~') { | 619 return -1; 620 } 621 /* New-style anding: "0 byte&0x80 =0x80 dynamically linked" */ 622 /* New and improved: ~ & | ^ + - * / % -- exciting, isn't it? */ 623 if (*l == '~') { |
614 if (FILE_STRING != m->type && FILE_PSTRING != m->type) | 624 if (!IS_STRING(m->type)) |
615 m->mask_op = FILE_OPINVERSE; 616 ++l; 617 } 618 if ((t = strchr(fops, *l)) != NULL) { 619 uint32_t op = (uint32_t)(t - fops); | 625 m->mask_op = FILE_OPINVERSE; 626 ++l; 627 } 628 if ((t = strchr(fops, *l)) != NULL) { 629 uint32_t op = (uint32_t)(t - fops); |
620 if (op != FILE_OPDIVIDE || 621 (FILE_STRING != m->type && FILE_PSTRING != m->type)) { | 630 if (op != FILE_OPDIVIDE || !IS_STRING(m->type)) { |
622 ++l; 623 m->mask_op |= op; 624 val = (uint32_t)strtoul(l, &l, 0); 625 m->mask = file_signextend(ms, m, val); 626 eatsize(&l); 627 } else { 628 m->mask = 0L; 629 while (!isspace((unsigned char)*++l)) { --- 5 unchanged lines hidden (view full) --- 635 m->mask |= STRING_COMPACT_BLANK; 636 break; 637 case CHAR_COMPACT_OPTIONAL_BLANK: 638 m->mask |= 639 STRING_COMPACT_OPTIONAL_BLANK; 640 break; 641 default: 642 if (ms->flags & MAGIC_CHECK) | 631 ++l; 632 m->mask_op |= op; 633 val = (uint32_t)strtoul(l, &l, 0); 634 m->mask = file_signextend(ms, m, val); 635 eatsize(&l); 636 } else { 637 m->mask = 0L; 638 while (!isspace((unsigned char)*++l)) { --- 5 unchanged lines hidden (view full) --- 644 m->mask |= STRING_COMPACT_BLANK; 645 break; 646 case CHAR_COMPACT_OPTIONAL_BLANK: 647 m->mask |= 648 STRING_COMPACT_OPTIONAL_BLANK; 649 break; 650 default: 651 if (ms->flags & MAGIC_CHECK) |
643 file_magwarn( 644 "string extension %c invalid", | 652 file_magwarn(ms, 653 "string extension `%c' invalid", |
645 *l); 646 return -1; 647 } 648 } 649 } 650 } 651 /* 652 * We used to set mask to all 1's here, instead let's just not do --- 11 unchanged lines hidden (view full) --- 664 m->reln = *l; 665 ++l; 666 if (*l == '=') { 667 /* HP compat: ignore &= etc. */ 668 ++l; 669 } 670 break; 671 case '!': | 654 *l); 655 return -1; 656 } 657 } 658 } 659 } 660 /* 661 * We used to set mask to all 1's here, instead let's just not do --- 11 unchanged lines hidden (view full) --- 673 m->reln = *l; 674 ++l; 675 if (*l == '=') { 676 /* HP compat: ignore &= etc. */ 677 ++l; 678 } 679 break; 680 case '!': |
672 if (m->type != FILE_STRING && m->type != FILE_PSTRING) { | 681 if (!IS_STRING(m->type)) { |
673 m->reln = *l; 674 ++l; 675 break; 676 } 677 /*FALLTHROUGH*/ 678 default: 679 if (*l == 'x' && isascii((unsigned char)l[1]) && 680 isspace((unsigned char)l[1])) { --- 27 unchanged lines hidden (view full) --- 708 ++l; 709 m->nospflag = 1; 710 } else 711 m->nospflag = 0; 712 while ((m->desc[i++] = *l++) != '\0' && i < MAXDESC) 713 /* NULLBODY */; 714 715 if (ms->flags & MAGIC_CHECK) { | 682 m->reln = *l; 683 ++l; 684 break; 685 } 686 /*FALLTHROUGH*/ 687 default: 688 if (*l == 'x' && isascii((unsigned char)l[1]) && 689 isspace((unsigned char)l[1])) { --- 27 unchanged lines hidden (view full) --- 717 ++l; 718 m->nospflag = 1; 719 } else 720 m->nospflag = 0; 721 while ((m->desc[i++] = *l++) != '\0' && i < MAXDESC) 722 /* NULLBODY */; 723 724 if (ms->flags & MAGIC_CHECK) { |
716 if (!check_format(m)) | 725 if (!check_format(ms, m)) |
717 return -1; 718 } 719#ifndef COMPILE_ONLY 720 if (action == FILE_CHECK) { 721 file_mdump(m); 722 } 723#endif 724 ++(*nmagicp); /* make room for next */ 725 return 0; 726} 727 728/* 729 * Check that the optional printf format in description matches 730 * the type of the magic. 731 */ 732private int | 726 return -1; 727 } 728#ifndef COMPILE_ONLY 729 if (action == FILE_CHECK) { 730 file_mdump(m); 731 } 732#endif 733 ++(*nmagicp); /* make room for next */ 734 return 0; 735} 736 737/* 738 * Check that the optional printf format in description matches 739 * the type of the magic. 740 */ 741private int |
733check_format(struct magic *m) | 742check_format(struct magic_set *ms, struct magic *m) |
734{ 735 static const char *formats[] = { FILE_FORMAT_STRING }; 736 static const char *names[] = { FILE_FORMAT_NAME }; 737 char *ptr; 738 739 for (ptr = m->desc; *ptr; ptr++) 740 if (*ptr == '%') 741 break; 742 if (*ptr == '\0') { 743 /* No format string; ok */ 744 return 1; 745 } 746 if (m->type >= sizeof(formats)/sizeof(formats[0])) { | 743{ 744 static const char *formats[] = { FILE_FORMAT_STRING }; 745 static const char *names[] = { FILE_FORMAT_NAME }; 746 char *ptr; 747 748 for (ptr = m->desc; *ptr; ptr++) 749 if (*ptr == '%') 750 break; 751 if (*ptr == '\0') { 752 /* No format string; ok */ 753 return 1; 754 } 755 if (m->type >= sizeof(formats)/sizeof(formats[0])) { |
747 file_magwarn("Internal error inconsistency between m->type" | 756 file_magwarn(ms, "Internal error inconsistency between m->type" |
748 " and format strings"); 749 return 0; 750 } 751 if (formats[m->type] == NULL) { | 757 " and format strings"); 758 return 0; 759 } 760 if (formats[m->type] == NULL) { |
752 file_magwarn("No format string for `%s' with description `%s'", 753 m->desc, names[m->type]); | 761 file_magwarn(ms, "No format string for `%s' with description " 762 "`%s'", m->desc, names[m->type]); |
754 return 0; 755 } 756 for (; *ptr; ptr++) { 757 if (*ptr == 'l' || *ptr == 'h') { 758 /* XXX: we should really fix this one day */ 759 continue; 760 } 761 if (islower((unsigned char)*ptr) || *ptr == 'X') 762 break; 763 } 764 if (*ptr == '\0') { 765 /* Missing format string; bad */ | 763 return 0; 764 } 765 for (; *ptr; ptr++) { 766 if (*ptr == 'l' || *ptr == 'h') { 767 /* XXX: we should really fix this one day */ 768 continue; 769 } 770 if (islower((unsigned char)*ptr) || *ptr == 'X') 771 break; 772 } 773 if (*ptr == '\0') { 774 /* Missing format string; bad */ |
766 file_magwarn("Invalid format `%s' for type `%s'", | 775 file_magwarn(ms, "Invalid format `%s' for type `%s'", |
767 m->desc, names[m->type]); 768 return 0; 769 } 770 if (strchr(formats[m->type], *ptr) == NULL) { | 776 m->desc, names[m->type]); 777 return 0; 778 } 779 if (strchr(formats[m->type], *ptr) == NULL) { |
771 file_magwarn("Printf format `%c' is not valid for type `%s'" | 780 file_magwarn(ms, "Printf format `%c' is not valid for type `%s'" |
772 " in description `%s'", 773 *ptr, names[m->type], m->desc); 774 return 0; 775 } 776 return 1; 777} 778 779/* 780 * Read a numeric value from a pointer, into the value union of a magic 781 * pointer, according to the magic type. Update the string pointer to point 782 * just after the number read. Return 0 for success, non-zero for failure. 783 */ 784private int 785getvalue(struct magic_set *ms, struct magic *m, char **p) 786{ 787 int slen; 788 789 switch (m->type) { | 781 " in description `%s'", 782 *ptr, names[m->type], m->desc); 783 return 0; 784 } 785 return 1; 786} 787 788/* 789 * Read a numeric value from a pointer, into the value union of a magic 790 * pointer, according to the magic type. Update the string pointer to point 791 * just after the number read. Return 0 for success, non-zero for failure. 792 */ 793private int 794getvalue(struct magic_set *ms, struct magic *m, char **p) 795{ 796 int slen; 797 798 switch (m->type) { |
799 case FILE_BESTRING16: 800 case FILE_LESTRING16: |
|
790 case FILE_STRING: 791 case FILE_PSTRING: 792 case FILE_REGEX: 793 *p = getstr(ms, *p, m->value.s, sizeof(m->value.s), &slen); 794 if (*p == NULL) { 795 if (ms->flags & MAGIC_CHECK) | 801 case FILE_STRING: 802 case FILE_PSTRING: 803 case FILE_REGEX: 804 *p = getstr(ms, *p, m->value.s, sizeof(m->value.s), &slen); 805 if (*p == NULL) { 806 if (ms->flags & MAGIC_CHECK) |
796 file_magwarn("cannot get string from `%s'", | 807 file_magwarn(ms, "cannot get string from `%s'", |
797 m->value.s); 798 return -1; 799 } 800 m->vallen = slen; 801 return 0; 802 default: 803 if (m->reln != 'x') { 804 m->value.l = file_signextend(ms, m, --- 215 unchanged lines hidden (view full) --- 1020 const char *fn) 1021{ 1022 int fd; 1023 struct stat st; 1024 uint32_t *ptr; 1025 uint32_t version; 1026 int needsbyteswap; 1027 char buf[MAXPATHLEN]; | 808 m->value.s); 809 return -1; 810 } 811 m->vallen = slen; 812 return 0; 813 default: 814 if (m->reln != 'x') { 815 m->value.l = file_signextend(ms, m, --- 215 unchanged lines hidden (view full) --- 1031 const char *fn) 1032{ 1033 int fd; 1034 struct stat st; 1035 uint32_t *ptr; 1036 uint32_t version; 1037 int needsbyteswap; 1038 char buf[MAXPATHLEN]; |
1028 char *dbname = mkdbname(fn, buf, sizeof(buf)); | 1039 char *dbname = mkdbname(fn, buf, sizeof(buf), 0); |
1029 void *mm = NULL; 1030 1031 if (dbname == NULL) 1032 return -1; 1033 1034 if ((fd = open(dbname, O_RDONLY)) == -1) 1035 return -1; 1036 --- 74 unchanged lines hidden (view full) --- 1111 * handle an mmaped file. 1112 */ 1113private int 1114apprentice_compile(struct magic_set *ms, struct magic **magicp, 1115 uint32_t *nmagicp, const char *fn) 1116{ 1117 int fd; 1118 char buf[MAXPATHLEN]; | 1040 void *mm = NULL; 1041 1042 if (dbname == NULL) 1043 return -1; 1044 1045 if ((fd = open(dbname, O_RDONLY)) == -1) 1046 return -1; 1047 --- 74 unchanged lines hidden (view full) --- 1122 * handle an mmaped file. 1123 */ 1124private int 1125apprentice_compile(struct magic_set *ms, struct magic **magicp, 1126 uint32_t *nmagicp, const char *fn) 1127{ 1128 int fd; 1129 char buf[MAXPATHLEN]; |
1119 char *dbname = mkdbname(fn, buf, sizeof(buf)); | 1130 char *dbname = mkdbname(fn, buf, sizeof(buf), 1); |
1120 1121 if (dbname == NULL) 1122 return -1; 1123 1124 if ((fd = open(dbname, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1) { 1125 file_error(ms, errno, "cannot open `%s'", dbname); 1126 return -1; 1127 } --- 19 unchanged lines hidden (view full) --- 1147 return 0; 1148} 1149 1150private const char ext[] = ".mgc"; 1151/* 1152 * make a dbname 1153 */ 1154private char * | 1131 1132 if (dbname == NULL) 1133 return -1; 1134 1135 if ((fd = open(dbname, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1) { 1136 file_error(ms, errno, "cannot open `%s'", dbname); 1137 return -1; 1138 } --- 19 unchanged lines hidden (view full) --- 1158 return 0; 1159} 1160 1161private const char ext[] = ".mgc"; 1162/* 1163 * make a dbname 1164 */ 1165private char * |
1155mkdbname(const char *fn, char *buf, size_t bufsiz) | 1166mkdbname(const char *fn, char *buf, size_t bufsiz, int strip) |
1156{ | 1167{ |
1157#ifdef notdef 1158 const char *p; 1159 if ((p = strrchr(fn, '/')) != NULL) 1160 fn = ++p; 1161#endif | 1168 if (strip) { 1169 const char *p; 1170 if ((p = strrchr(fn, '/')) != NULL) 1171 fn = ++p; 1172 } 1173 |
1162 (void)snprintf(buf, bufsiz, "%s%s", fn, ext); 1163 return buf; 1164} 1165 1166/* 1167 * Byteswap an mmap'ed file if needed 1168 */ 1169private void --- 38 unchanged lines hidden (view full) --- 1208 * byteswap a single magic entry 1209 */ 1210private void 1211bs1(struct magic *m) 1212{ 1213 m->cont_level = swap2(m->cont_level); 1214 m->offset = swap4((uint32_t)m->offset); 1215 m->in_offset = swap4((uint32_t)m->in_offset); | 1174 (void)snprintf(buf, bufsiz, "%s%s", fn, ext); 1175 return buf; 1176} 1177 1178/* 1179 * Byteswap an mmap'ed file if needed 1180 */ 1181private void --- 38 unchanged lines hidden (view full) --- 1220 * byteswap a single magic entry 1221 */ 1222private void 1223bs1(struct magic *m) 1224{ 1225 m->cont_level = swap2(m->cont_level); 1226 m->offset = swap4((uint32_t)m->offset); 1227 m->in_offset = swap4((uint32_t)m->in_offset); |
1216 if (m->type != FILE_STRING) | 1228 if (IS_STRING(m->type)) |
1217 m->value.l = swap4(m->value.l); 1218 m->mask = swap4(m->mask); 1219} | 1229 m->value.l = swap4(m->value.l); 1230 m->mask = swap4(m->mask); 1231} |