apprentice.c (267897) | apprentice.c (275698) |
---|---|
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: --- 18 unchanged lines hidden (view full) --- 27 */ 28/* 29 * apprentice - make one pass through /etc/magic, learning its secrets. 30 */ 31 32#include "file.h" 33 34#ifndef lint | 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: --- 18 unchanged lines hidden (view full) --- 27 */ 28/* 29 * apprentice - make one pass through /etc/magic, learning its secrets. 30 */ 31 32#include "file.h" 33 34#ifndef lint |
35FILE_RCSID("@(#)$File: apprentice.c,v 1.211 2014/06/03 19:01:34 christos Exp $") | 35FILE_RCSID("@(#)$File: apprentice.c,v 1.227 2014/11/28 02:46:39 christos Exp $") |
36#endif /* lint */ 37 38#include "magic.h" 39#include <stdlib.h> 40#ifdef HAVE_UNISTD_H 41#include <unistd.h> 42#endif 43#ifdef HAVE_STDDEF_H --- 37 unchanged lines hidden (view full) --- 81 82#ifndef MAP_FILE 83#define MAP_FILE 0 84#endif 85 86#define ALLOC_CHUNK (size_t)10 87#define ALLOC_INCR (size_t)200 88 | 36#endif /* lint */ 37 38#include "magic.h" 39#include <stdlib.h> 40#ifdef HAVE_UNISTD_H 41#include <unistd.h> 42#endif 43#ifdef HAVE_STDDEF_H --- 37 unchanged lines hidden (view full) --- 81 82#ifndef MAP_FILE 83#define MAP_FILE 0 84#endif 85 86#define ALLOC_CHUNK (size_t)10 87#define ALLOC_INCR (size_t)200 88 |
89#define MAP_TYPE_MMAP 0 90#define MAP_TYPE_MALLOC 1 91#define MAP_TYPE_USER 2 92 |
|
89struct magic_entry { 90 struct magic *mp; 91 uint32_t cont_count; 92 uint32_t max_count; 93}; 94 95struct magic_entry_set { 96 struct magic_entry *me; 97 uint32_t count; 98 uint32_t max; 99}; 100 101struct magic_map { 102 void *p; 103 size_t len; | 93struct magic_entry { 94 struct magic *mp; 95 uint32_t cont_count; 96 uint32_t max_count; 97}; 98 99struct magic_entry_set { 100 struct magic_entry *me; 101 uint32_t count; 102 uint32_t max; 103}; 104 105struct magic_map { 106 void *p; 107 size_t len; |
108 int type; |
|
104 struct magic *magic[MAGIC_SETS]; 105 uint32_t nmagic[MAGIC_SETS]; 106}; 107 108int file_formats[FILE_NAMES_SIZE]; 109const size_t file_nformats = FILE_NAMES_SIZE; 110const char *file_names[FILE_NAMES_SIZE]; 111const size_t file_nnames = FILE_NAMES_SIZE; --- 14 unchanged lines hidden (view full) --- 126private struct mlist *mlist_alloc(void); 127private void mlist_free(struct mlist *); 128private void byteswap(struct magic *, uint32_t); 129private void bs1(struct magic *); 130private uint16_t swap2(uint16_t); 131private uint32_t swap4(uint32_t); 132private uint64_t swap8(uint64_t); 133private char *mkdbname(struct magic_set *, const char *, int); | 109 struct magic *magic[MAGIC_SETS]; 110 uint32_t nmagic[MAGIC_SETS]; 111}; 112 113int file_formats[FILE_NAMES_SIZE]; 114const size_t file_nformats = FILE_NAMES_SIZE; 115const char *file_names[FILE_NAMES_SIZE]; 116const size_t file_nnames = FILE_NAMES_SIZE; --- 14 unchanged lines hidden (view full) --- 131private struct mlist *mlist_alloc(void); 132private void mlist_free(struct mlist *); 133private void byteswap(struct magic *, uint32_t); 134private void bs1(struct magic *); 135private uint16_t swap2(uint16_t); 136private uint32_t swap4(uint32_t); 137private uint64_t swap8(uint64_t); 138private char *mkdbname(struct magic_set *, const char *, int); |
139private struct magic_map *apprentice_buf(struct magic_set *, struct magic *, 140 size_t); |
|
134private struct magic_map *apprentice_map(struct magic_set *, const char *); | 141private struct magic_map *apprentice_map(struct magic_set *, const char *); |
142private int check_buffer(struct magic_set *, struct magic_map *, const char *); |
|
135private void apprentice_unmap(struct magic_map *); 136private int apprentice_compile(struct magic_set *, struct magic_map *, 137 const char *); 138private int check_format_type(const char *, int); 139private int check_format(struct magic_set *, struct magic *); 140private int get_op(char); 141private int parse_mime(struct magic_set *, struct magic_entry *, const char *); 142private int parse_strength(struct magic_set *, struct magic_entry *, const char *); --- 248 unchanged lines hidden (view full) --- 391 assert(p - type_tbl == FILE_NAMES_SIZE); 392} 393 394private int 395add_mlist(struct mlist *mlp, struct magic_map *map, size_t idx) 396{ 397 struct mlist *ml; 398 | 143private void apprentice_unmap(struct magic_map *); 144private int apprentice_compile(struct magic_set *, struct magic_map *, 145 const char *); 146private int check_format_type(const char *, int); 147private int check_format(struct magic_set *, struct magic *); 148private int get_op(char); 149private int parse_mime(struct magic_set *, struct magic_entry *, const char *); 150private int parse_strength(struct magic_set *, struct magic_entry *, const char *); --- 248 unchanged lines hidden (view full) --- 399 assert(p - type_tbl == FILE_NAMES_SIZE); 400} 401 402private int 403add_mlist(struct mlist *mlp, struct magic_map *map, size_t idx) 404{ 405 struct mlist *ml; 406 |
407 mlp->map = idx == 0 ? map : NULL; |
|
399 if ((ml = CAST(struct mlist *, malloc(sizeof(*ml)))) == NULL) 400 return -1; 401 | 408 if ((ml = CAST(struct mlist *, malloc(sizeof(*ml)))) == NULL) 409 return -1; 410 |
402 ml->map = idx == 0 ? map : NULL; | 411 ml->map = NULL; |
403 ml->magic = map->magic[idx]; 404 ml->nmagic = map->nmagic[idx]; 405 406 mlp->prev->next = ml; 407 ml->prev = mlp->prev; 408 ml->next = mlp; 409 mlp->prev = ml; 410 return 0; 411} 412 413/* 414 * Handle one file or directory. 415 */ 416private int 417apprentice_1(struct magic_set *ms, const char *fn, int action) 418{ | 412 ml->magic = map->magic[idx]; 413 ml->nmagic = map->nmagic[idx]; 414 415 mlp->prev->next = ml; 416 ml->prev = mlp->prev; 417 ml->next = mlp; 418 mlp->prev = ml; 419 return 0; 420} 421 422/* 423 * Handle one file or directory. 424 */ 425private int 426apprentice_1(struct magic_set *ms, const char *fn, int action) 427{ |
419#ifndef COMPILE_ONLY 420 struct mlist *ml; 421#endif /* COMPILE_ONLY */ | |
422 struct magic_map *map; 423#ifndef COMPILE_ONLY | 428 struct magic_map *map; 429#ifndef COMPILE_ONLY |
430 struct mlist *ml; |
|
424 size_t i; | 431 size_t i; |
425#endif /* COMPILE_ONLY */ | 432#endif |
426 427 if (magicsize != FILE_MAGICSIZE) { 428 file_error(ms, 0, "magic element size %lu != %lu", 429 (unsigned long)sizeof(*map->magic[0]), 430 (unsigned long)FILE_MAGICSIZE); 431 return -1; 432 } 433 --- 12 unchanged lines hidden (view full) --- 446 map = apprentice_load(ms, fn, action); 447 if (map == NULL) 448 return -1; 449 } 450 451 for (i = 0; i < MAGIC_SETS; i++) { 452 if (add_mlist(ms->mlist[i], map, i) == -1) { 453 file_oomem(ms, sizeof(*ml)); | 433 434 if (magicsize != FILE_MAGICSIZE) { 435 file_error(ms, 0, "magic element size %lu != %lu", 436 (unsigned long)sizeof(*map->magic[0]), 437 (unsigned long)FILE_MAGICSIZE); 438 return -1; 439 } 440 --- 12 unchanged lines hidden (view full) --- 453 map = apprentice_load(ms, fn, action); 454 if (map == NULL) 455 return -1; 456 } 457 458 for (i = 0; i < MAGIC_SETS; i++) { 459 if (add_mlist(ms->mlist[i], map, i) == -1) { 460 file_oomem(ms, sizeof(*ml)); |
454 apprentice_unmap(map); 455 return -1; | 461 goto fail; |
456 } 457 } 458 459 if (action == FILE_LIST) { 460 for (i = 0; i < MAGIC_SETS; i++) { | 462 } 463 } 464 465 if (action == FILE_LIST) { 466 for (i = 0; i < MAGIC_SETS; i++) { |
461 printf("Set %zu:\nBinary patterns:\n", i); | 467 printf("Set %" SIZE_T_FORMAT "u:\nBinary patterns:\n", 468 i); |
462 apprentice_list(ms->mlist[i], BINTEST); 463 printf("Text patterns:\n"); 464 apprentice_list(ms->mlist[i], TEXTTEST); 465 } 466 } | 469 apprentice_list(ms->mlist[i], BINTEST); 470 printf("Text patterns:\n"); 471 apprentice_list(ms->mlist[i], TEXTTEST); 472 } 473 } |
467#endif /* COMPILE_ONLY */ 468 | |
469 return 0; | 474 return 0; |
475fail: 476 for (i = 0; i < MAGIC_SETS; i++) { 477 mlist_free(ms->mlist[i]); 478 ms->mlist[i] = NULL; 479 } 480 return -1; 481#else 482 return 0; 483#endif /* COMPILE_ONLY */ |
|
470} 471 472protected void 473file_ms_free(struct magic_set *ms) 474{ 475 size_t i; 476 if (ms == NULL) 477 return; --- 27 unchanged lines hidden (view full) --- 505 goto free; 506 507 ms->event_flags = 0; 508 ms->error = -1; 509 for (i = 0; i < MAGIC_SETS; i++) 510 ms->mlist[i] = NULL; 511 ms->file = "unknown"; 512 ms->line = 0; | 484} 485 486protected void 487file_ms_free(struct magic_set *ms) 488{ 489 size_t i; 490 if (ms == NULL) 491 return; --- 27 unchanged lines hidden (view full) --- 519 goto free; 520 521 ms->event_flags = 0; 522 ms->error = -1; 523 for (i = 0; i < MAGIC_SETS; i++) 524 ms->mlist[i] = NULL; 525 ms->file = "unknown"; 526 ms->line = 0; |
527 ms->indir_max = FILE_INDIR_MAX; 528 ms->name_max = FILE_NAME_MAX; 529 ms->elf_shnum_max = FILE_ELF_SHNUM_MAX; 530 ms->elf_phnum_max = FILE_ELF_PHNUM_MAX; |
|
513 return ms; 514free: 515 free(ms); 516 return NULL; 517} 518 519private void 520apprentice_unmap(struct magic_map *map) 521{ 522 if (map == NULL) 523 return; | 531 return ms; 532free: 533 free(ms); 534 return NULL; 535} 536 537private void 538apprentice_unmap(struct magic_map *map) 539{ 540 if (map == NULL) 541 return; |
524 if (map->p != NULL) { | 542 543 switch (map->type) { |
525#ifdef QUICK | 544#ifdef QUICK |
526 if (map->len) | 545 case MAP_TYPE_MMAP: 546 if (map->p) |
527 (void)munmap(map->p, map->len); | 547 (void)munmap(map->p, map->len); |
528 else | 548 break; |
529#endif | 549#endif |
550 case MAP_TYPE_MALLOC: |
|
530 free(map->p); | 551 free(map->p); |
531 } else { 532 uint32_t j; 533 for (j = 0; j < MAGIC_SETS; j++) 534 free(map->magic[j]); | 552 break; 553 case MAP_TYPE_USER: 554 break; 555 default: 556 abort(); |
535 } 536 free(map); 537} 538 539private struct mlist * 540mlist_alloc(void) 541{ 542 struct mlist *mlist; 543 if ((mlist = CAST(struct mlist *, calloc(1, sizeof(*mlist)))) == NULL) { 544 return NULL; 545 } 546 mlist->next = mlist->prev = mlist; 547 return mlist; 548} 549 550private void 551mlist_free(struct mlist *mlist) 552{ | 557 } 558 free(map); 559} 560 561private struct mlist * 562mlist_alloc(void) 563{ 564 struct mlist *mlist; 565 if ((mlist = CAST(struct mlist *, calloc(1, sizeof(*mlist)))) == NULL) { 566 return NULL; 567 } 568 mlist->next = mlist->prev = mlist; 569 return mlist; 570} 571 572private void 573mlist_free(struct mlist *mlist) 574{ |
553 struct mlist *ml; | 575 struct mlist *ml, *next; |
554 555 if (mlist == NULL) 556 return; 557 | 576 577 if (mlist == NULL) 578 return; 579 |
558 for (ml = mlist->next; ml != mlist;) { 559 struct mlist *next = ml->next; | 580 ml = mlist->next; 581 for (ml = mlist->next; (next = ml->next) != NULL; ml = next) { |
560 if (ml->map) 561 apprentice_unmap(ml->map); 562 free(ml); | 582 if (ml->map) 583 apprentice_unmap(ml->map); 584 free(ml); |
563 ml = next; | 585 if (ml == mlist) 586 break; |
564 } | 587 } |
565 free(ml); | |
566} 567 | 588} 589 |
590#ifndef COMPILE_ONLY 591/* void **bufs: an array of compiled magic files */ 592protected int 593buffer_apprentice(struct magic_set *ms, struct magic **bufs, 594 size_t *sizes, size_t nbufs) 595{ 596 size_t i, j; 597 struct mlist *ml; 598 struct magic_map *map; 599 600 if (nbufs == 0) 601 return -1; 602 603 if (ms->mlist[0] != NULL) 604 file_reset(ms); 605 606 init_file_tables(); 607 608 for (i = 0; i < MAGIC_SETS; i++) { 609 mlist_free(ms->mlist[i]); 610 if ((ms->mlist[i] = mlist_alloc()) == NULL) { 611 file_oomem(ms, sizeof(*ms->mlist[i])); 612 goto fail; 613 } 614 } 615 616 for (i = 0; i < nbufs; i++) { 617 map = apprentice_buf(ms, bufs[i], sizes[i]); 618 if (map == NULL) 619 goto fail; 620 621 for (j = 0; j < MAGIC_SETS; j++) { 622 if (add_mlist(ms->mlist[j], map, j) == -1) { 623 file_oomem(ms, sizeof(*ml)); 624 goto fail; 625 } 626 } 627 } 628 629 return 0; 630fail: 631 for (i = 0; i < MAGIC_SETS; i++) { 632 mlist_free(ms->mlist[i]); 633 ms->mlist[i] = NULL; 634 } 635 return -1; 636} 637#endif 638 |
|
568/* const char *fn: list of magic files and directories */ 569protected int 570file_apprentice(struct magic_set *ms, const char *fn, int action) 571{ 572 char *p, *mfn; 573 int file_err, errs = -1; 574 size_t i; 575 --- 9 unchanged lines hidden (view full) --- 585 file_oomem(ms, strlen(fn)); 586 return -1; 587 } 588 589 for (i = 0; i < MAGIC_SETS; i++) { 590 mlist_free(ms->mlist[i]); 591 if ((ms->mlist[i] = mlist_alloc()) == NULL) { 592 file_oomem(ms, sizeof(*ms->mlist[i])); | 639/* const char *fn: list of magic files and directories */ 640protected int 641file_apprentice(struct magic_set *ms, const char *fn, int action) 642{ 643 char *p, *mfn; 644 int file_err, errs = -1; 645 size_t i; 646 --- 9 unchanged lines hidden (view full) --- 656 file_oomem(ms, strlen(fn)); 657 return -1; 658 } 659 660 for (i = 0; i < MAGIC_SETS; i++) { 661 mlist_free(ms->mlist[i]); 662 if ((ms->mlist[i] = mlist_alloc()) == NULL) { 663 file_oomem(ms, sizeof(*ms->mlist[i])); |
593 if (i != 0) { 594 --i; 595 do 596 mlist_free(ms->mlist[i]); 597 while (i != 0); | 664 while (i-- > 0) { 665 mlist_free(ms->mlist[i]); 666 ms->mlist[i] = NULL; |
598 } 599 free(mfn); 600 return -1; 601 } 602 } 603 fn = mfn; 604 605 while (fn) { --- 706 unchanged lines hidden (view full) --- 1312 if (!(m->flag & UNSIGNED)) { 1313 switch(m->type) { 1314 /* 1315 * Do not remove the casts below. They are 1316 * vital. When later compared with the data, 1317 * the sign extension must have happened. 1318 */ 1319 case FILE_BYTE: | 667 } 668 free(mfn); 669 return -1; 670 } 671 } 672 fn = mfn; 673 674 while (fn) { --- 706 unchanged lines hidden (view full) --- 1381 if (!(m->flag & UNSIGNED)) { 1382 switch(m->type) { 1383 /* 1384 * Do not remove the casts below. They are 1385 * vital. When later compared with the data, 1386 * the sign extension must have happened. 1387 */ 1388 case FILE_BYTE: |
1320 v = (char) v; | 1389 v = (signed char) v; |
1321 break; 1322 case FILE_SHORT: 1323 case FILE_BESHORT: 1324 case FILE_LESHORT: 1325 v = (short) v; 1326 break; 1327 case FILE_DATE: 1328 case FILE_BEDATE: --- 735 unchanged lines hidden (view full) --- 2064 return 0; 2065out: 2066 m->factor_op = FILE_FACTOR_OP_NONE; 2067 m->factor = 0; 2068 return -1; 2069} 2070 2071private int | 1390 break; 1391 case FILE_SHORT: 1392 case FILE_BESHORT: 1393 case FILE_LESHORT: 1394 v = (short) v; 1395 break; 1396 case FILE_DATE: 1397 case FILE_BEDATE: --- 735 unchanged lines hidden (view full) --- 2133 return 0; 2134out: 2135 m->factor_op = FILE_FACTOR_OP_NONE; 2136 m->factor = 0; 2137 return -1; 2138} 2139 2140private int |
2141goodchar(unsigned char x, const char *extra) 2142{ 2143 return (isascii(x) && isalnum(x)) || strchr(extra, x); 2144} 2145 2146private int |
|
2072parse_extra(struct magic_set *ms, struct magic_entry *me, const char *line, | 2147parse_extra(struct magic_set *ms, struct magic_entry *me, const char *line, |
2073 off_t off, size_t len, const char *name, int nt) | 2148 off_t off, size_t len, const char *name, const char *extra, int nt) |
2074{ 2075 size_t i; 2076 const char *l = line; 2077 struct magic *m = &me->mp[me->cont_count == 0 ? 0 : me->cont_count - 1]; 2078 char *buf = (char *)m + off; 2079 2080 if (buf[0] != '\0') { 2081 len = nt ? strlen(buf) : len; --- 4 unchanged lines hidden (view full) --- 2086 2087 if (*m->desc == '\0') { 2088 file_magwarn(ms, "Current entry does not yet have a " 2089 "description for adding a %s type", name); 2090 return -1; 2091 } 2092 2093 EATAB; | 2149{ 2150 size_t i; 2151 const char *l = line; 2152 struct magic *m = &me->mp[me->cont_count == 0 ? 0 : me->cont_count - 1]; 2153 char *buf = (char *)m + off; 2154 2155 if (buf[0] != '\0') { 2156 len = nt ? strlen(buf) : len; --- 4 unchanged lines hidden (view full) --- 2161 2162 if (*m->desc == '\0') { 2163 file_magwarn(ms, "Current entry does not yet have a " 2164 "description for adding a %s type", name); 2165 return -1; 2166 } 2167 2168 EATAB; |
2094 for (i = 0; *l && ((isascii((unsigned char)*l) && 2095 isalnum((unsigned char)*l)) || strchr("-+/.", *l)) && 2096 i < len; buf[i++] = *l++) | 2169 for (i = 0; *l && i < len && goodchar(*l, extra); buf[i++] = *l++) |
2097 continue; 2098 2099 if (i == len && *l) { 2100 if (nt) 2101 buf[len - 1] = '\0'; 2102 if (ms->flags & MAGIC_CHECK) 2103 file_magwarn(ms, "%s type `%s' truncated %" 2104 SIZE_T_FORMAT "u", name, line, i); 2105 } else { | 2170 continue; 2171 2172 if (i == len && *l) { 2173 if (nt) 2174 buf[len - 1] = '\0'; 2175 if (ms->flags & MAGIC_CHECK) 2176 file_magwarn(ms, "%s type `%s' truncated %" 2177 SIZE_T_FORMAT "u", name, line, i); 2178 } else { |
2179 if (!isspace((unsigned char)*l) && !goodchar(*l, extra)) 2180 file_magwarn(ms, "%s type `%s' has bad char '%c'", 2181 name, line, *l); |
|
2106 if (nt) 2107 buf[i] = '\0'; 2108 } 2109 2110 if (i > 0) 2111 return 0; | 2182 if (nt) 2183 buf[i] = '\0'; 2184 } 2185 2186 if (i > 0) 2187 return 0; |
2112 else 2113 return -1; | 2188 2189 file_magerror(ms, "Bad magic entry '%s'", line); 2190 return -1; |
2114} 2115 2116/* 2117 * Parse an Apple CREATOR/TYPE annotation from magic file and put it into 2118 * magic[index - 1] 2119 */ 2120private int 2121parse_apple(struct magic_set *ms, struct magic_entry *me, const char *line) 2122{ 2123 struct magic *m = &me->mp[0]; 2124 2125 return parse_extra(ms, me, line, offsetof(struct magic, apple), | 2191} 2192 2193/* 2194 * Parse an Apple CREATOR/TYPE annotation from magic file and put it into 2195 * magic[index - 1] 2196 */ 2197private int 2198parse_apple(struct magic_set *ms, struct magic_entry *me, const char *line) 2199{ 2200 struct magic *m = &me->mp[0]; 2201 2202 return parse_extra(ms, me, line, offsetof(struct magic, apple), |
2126 sizeof(m->apple), "APPLE", 0); | 2203 sizeof(m->apple), "APPLE", "!+-./", 0); |
2127} 2128 2129/* 2130 * parse a MIME annotation line from magic file, put into magic[index - 1] 2131 * if valid 2132 */ 2133private int 2134parse_mime(struct magic_set *ms, struct magic_entry *me, const char *line) 2135{ 2136 struct magic *m = &me->mp[0]; 2137 2138 return parse_extra(ms, me, line, offsetof(struct magic, mimetype), | 2204} 2205 2206/* 2207 * parse a MIME annotation line from magic file, put into magic[index - 1] 2208 * if valid 2209 */ 2210private int 2211parse_mime(struct magic_set *ms, struct magic_entry *me, const char *line) 2212{ 2213 struct magic *m = &me->mp[0]; 2214 2215 return parse_extra(ms, me, line, offsetof(struct magic, mimetype), |
2139 sizeof(m->mimetype), "MIME", 1); | 2216 sizeof(m->mimetype), "MIME", "+-/.", 1); |
2140} 2141 2142private int 2143check_format_type(const char *ptr, int type) 2144{ 2145 int quad = 0, h; 2146 if (*ptr == '\0') { 2147 /* Missing format string; bad */ --- 544 unchanged lines hidden (view full) --- 2692 default: 2693 break; 2694 } 2695 2696 *p = l; 2697} 2698 2699/* | 2217} 2218 2219private int 2220check_format_type(const char *ptr, int type) 2221{ 2222 int quad = 0, h; 2223 if (*ptr == '\0') { 2224 /* Missing format string; bad */ --- 544 unchanged lines hidden (view full) --- 2769 default: 2770 break; 2771 } 2772 2773 *p = l; 2774} 2775 2776/* |
2777 * handle a buffer containing a compiled file. 2778 */ 2779private struct magic_map * 2780apprentice_buf(struct magic_set *ms, struct magic *buf, size_t len) 2781{ 2782 struct magic_map *map; 2783 2784 if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL) { 2785 file_oomem(ms, sizeof(*map)); 2786 return NULL; 2787 } 2788 map->len = len; 2789 map->p = buf; 2790 map->type = MAP_TYPE_USER; 2791 if (check_buffer(ms, map, "buffer") != 0) { 2792 apprentice_unmap(map); 2793 return NULL; 2794 } 2795 return map; 2796} 2797 2798/* |
|
2700 * handle a compiled file. 2701 */ 2702 2703private struct magic_map * 2704apprentice_map(struct magic_set *ms, const char *fn) 2705{ 2706 int fd; 2707 struct stat st; | 2799 * handle a compiled file. 2800 */ 2801 2802private struct magic_map * 2803apprentice_map(struct magic_set *ms, const char *fn) 2804{ 2805 int fd; 2806 struct stat st; |
2708 uint32_t *ptr; 2709 uint32_t version, entries, nentries; 2710 int needsbyteswap; | |
2711 char *dbname = NULL; 2712 struct magic_map *map; | 2807 char *dbname = NULL; 2808 struct magic_map *map; |
2713 size_t i; | |
2714 2715 fd = -1; 2716 if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL) { 2717 file_oomem(ms, sizeof(*map)); 2718 goto error; 2719 } 2720 2721 dbname = mkdbname(ms, fn, 0); --- 15 unchanged lines hidden (view full) --- 2737 2738 map->len = (size_t)st.st_size; 2739#ifdef QUICK 2740 if ((map->p = mmap(0, (size_t)st.st_size, PROT_READ|PROT_WRITE, 2741 MAP_PRIVATE|MAP_FILE, fd, (off_t)0)) == MAP_FAILED) { 2742 file_error(ms, errno, "cannot map `%s'", dbname); 2743 goto error; 2744 } | 2809 2810 fd = -1; 2811 if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL) { 2812 file_oomem(ms, sizeof(*map)); 2813 goto error; 2814 } 2815 2816 dbname = mkdbname(ms, fn, 0); --- 15 unchanged lines hidden (view full) --- 2832 2833 map->len = (size_t)st.st_size; 2834#ifdef QUICK 2835 if ((map->p = mmap(0, (size_t)st.st_size, PROT_READ|PROT_WRITE, 2836 MAP_PRIVATE|MAP_FILE, fd, (off_t)0)) == MAP_FAILED) { 2837 file_error(ms, errno, "cannot map `%s'", dbname); 2838 goto error; 2839 } |
2840 map->type = MAP_TYPE_MMAP; |
|
2745#else 2746 if ((map->p = CAST(void *, malloc(map->len))) == NULL) { 2747 file_oomem(ms, map->len); 2748 goto error; 2749 } 2750 if (read(fd, map->p, map->len) != (ssize_t)map->len) { 2751 file_badread(ms); 2752 goto error; 2753 } | 2841#else 2842 if ((map->p = CAST(void *, malloc(map->len))) == NULL) { 2843 file_oomem(ms, map->len); 2844 goto error; 2845 } 2846 if (read(fd, map->p, map->len) != (ssize_t)map->len) { 2847 file_badread(ms); 2848 goto error; 2849 } |
2754 map->len = 0; | 2850 map->type = MAP_TYPE_MALLOC; |
2755#define RET 1 2756#endif 2757 (void)close(fd); 2758 fd = -1; | 2851#define RET 1 2852#endif 2853 (void)close(fd); 2854 fd = -1; |
2855 2856 if (check_buffer(ms, map, dbname) != 0) 2857 goto error; 2858 2859 free(dbname); 2860 return map; 2861 2862error: 2863 if (fd != -1) 2864 (void)close(fd); 2865 apprentice_unmap(map); 2866 free(dbname); 2867 return NULL; 2868} 2869 2870private int 2871check_buffer(struct magic_set *ms, struct magic_map *map, const char *dbname) 2872{ 2873 uint32_t *ptr; 2874 uint32_t entries, nentries; 2875 uint32_t version; 2876 int i, needsbyteswap; 2877 |
|
2759 ptr = CAST(uint32_t *, map->p); 2760 if (*ptr != MAGICNO) { 2761 if (swap4(*ptr) != MAGICNO) { 2762 file_error(ms, 0, "bad magic in `%s'", dbname); | 2878 ptr = CAST(uint32_t *, map->p); 2879 if (*ptr != MAGICNO) { 2880 if (swap4(*ptr) != MAGICNO) { 2881 file_error(ms, 0, "bad magic in `%s'", dbname); |
2763 goto error; | 2882 return -1; |
2764 } 2765 needsbyteswap = 1; 2766 } else 2767 needsbyteswap = 0; 2768 if (needsbyteswap) 2769 version = swap4(ptr[1]); 2770 else 2771 version = ptr[1]; 2772 if (version != VERSIONNO) { 2773 file_error(ms, 0, "File %s supports only version %d magic " 2774 "files. `%s' is version %d", VERSION, 2775 VERSIONNO, dbname, version); | 2883 } 2884 needsbyteswap = 1; 2885 } else 2886 needsbyteswap = 0; 2887 if (needsbyteswap) 2888 version = swap4(ptr[1]); 2889 else 2890 version = ptr[1]; 2891 if (version != VERSIONNO) { 2892 file_error(ms, 0, "File %s supports only version %d magic " 2893 "files. `%s' is version %d", VERSION, 2894 VERSIONNO, dbname, version); |
2776 goto error; | 2895 return -1; |
2777 } | 2896 } |
2778 entries = (uint32_t)(st.st_size / sizeof(struct magic)); 2779 if ((off_t)(entries * sizeof(struct magic)) != st.st_size) { 2780 file_error(ms, 0, "Size of `%s' %" INT64_T_FORMAT "u is not " | 2897 entries = (uint32_t)(map->len / sizeof(struct magic)); 2898 if ((entries * sizeof(struct magic)) != map->len) { 2899 file_error(ms, 0, "Size of `%s' %" SIZE_T_FORMAT "u is not " |
2781 "a multiple of %" SIZE_T_FORMAT "u", | 2900 "a multiple of %" SIZE_T_FORMAT "u", |
2782 dbname, (unsigned long long)st.st_size, 2783 sizeof(struct magic)); 2784 goto error; | 2901 dbname, map->len, sizeof(struct magic)); 2902 return -1; |
2785 } 2786 map->magic[0] = CAST(struct magic *, map->p) + 1; 2787 nentries = 0; 2788 for (i = 0; i < MAGIC_SETS; i++) { 2789 if (needsbyteswap) 2790 map->nmagic[i] = swap4(ptr[i + 2]); 2791 else 2792 map->nmagic[i] = ptr[i + 2]; 2793 if (i != MAGIC_SETS - 1) 2794 map->magic[i + 1] = map->magic[i] + map->nmagic[i]; 2795 nentries += map->nmagic[i]; 2796 } 2797 if (entries != nentries + 1) { 2798 file_error(ms, 0, "Inconsistent entries in `%s' %u != %u", 2799 dbname, entries, nentries + 1); | 2903 } 2904 map->magic[0] = CAST(struct magic *, map->p) + 1; 2905 nentries = 0; 2906 for (i = 0; i < MAGIC_SETS; i++) { 2907 if (needsbyteswap) 2908 map->nmagic[i] = swap4(ptr[i + 2]); 2909 else 2910 map->nmagic[i] = ptr[i + 2]; 2911 if (i != MAGIC_SETS - 1) 2912 map->magic[i + 1] = map->magic[i] + map->nmagic[i]; 2913 nentries += map->nmagic[i]; 2914 } 2915 if (entries != nentries + 1) { 2916 file_error(ms, 0, "Inconsistent entries in `%s' %u != %u", 2917 dbname, entries, nentries + 1); |
2800 goto error; | 2918 return -1; |
2801 } 2802 if (needsbyteswap) 2803 for (i = 0; i < MAGIC_SETS; i++) 2804 byteswap(map->magic[i], map->nmagic[i]); | 2919 } 2920 if (needsbyteswap) 2921 for (i = 0; i < MAGIC_SETS; i++) 2922 byteswap(map->magic[i], map->nmagic[i]); |
2805 free(dbname); 2806 return map; 2807 2808error: 2809 if (fd != -1) 2810 (void)close(fd); 2811 apprentice_unmap(map); 2812 free(dbname); 2813 return NULL; | 2923 return 0; |
2814} 2815 2816/* 2817 * handle an mmaped file. 2818 */ 2819private int 2820apprentice_compile(struct magic_set *ms, struct magic_map *map, const char *fn) 2821{ --- 261 unchanged lines hidden --- | 2924} 2925 2926/* 2927 * handle an mmaped file. 2928 */ 2929private int 2930apprentice_compile(struct magic_set *ms, struct magic_map *map, const char *fn) 2931{ --- 261 unchanged lines hidden --- |