Deleted Added
full compact
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 ---