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