Annotation of src/usr.bin/file/file.h, Revision 1.19
1.19 ! chl 1: /* $OpenBSD: file.h,v 1.18 2007/11/26 09:28:34 martynas Exp $ */
1.1 deraadt 2: /*
1.12 ian 3: * Copyright (c) Ian F. Darwin 1986-1995.
4: * Software written by Ian F. Darwin and others;
5: * maintained 1995-present by Christos Zoulas and others.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice immediately at the beginning of the file, without modification,
12: * this list of conditions, and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: *
17: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
21: * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27: * SUCH DAMAGE.
1.1 deraadt 28: */
1.16 tedu 29: /*
30: * file.h - definitions for file(1) program
1.19 ! chl 31: * @(#)$Id: file.h,v 1.18 2007/11/26 09:28:34 martynas Exp $
1.16 tedu 32: */
1.1 deraadt 33:
1.3 millert 34: #ifndef __file_h__
35: #define __file_h__
36:
1.11 ian 37: #ifdef HAVE_CONFIG_H
38: #include "config.h"
39: #endif
40:
1.16 tedu 41: #include <stdio.h> /* Include that here, to make sure __P gets defined */
1.11 ian 42: #include <errno.h>
1.19 ! chl 43: #include <fcntl.h> /* For open and flags */
1.11 ian 44: #ifdef HAVE_STDINT_H
45: #include <stdint.h>
1.16 tedu 46: #endif
47: #ifdef HAVE_INTTYPES_H
1.11 ian 48: #include <inttypes.h>
49: #endif
1.19 ! chl 50: #include <regex.h>
! 51: #include <sys/types.h>
1.16 tedu 52: /* Do this here and now, because struct stat gets re-defined on solaris */
53: #include <sys/stat.h>
54:
1.19 ! chl 55: #define ENABLE_CONDITIONALS
! 56:
1.16 tedu 57: #ifndef MAGIC
58: #define MAGIC "/etc/magic"
59: #endif
60:
61: #ifdef __EMX__
62: #define PATHSEP ';'
63: #else
64: #define PATHSEP ':'
65: #endif
66:
67: #define private static
68: #ifndef protected
69: #define protected
70: #endif
71: #define public
1.11 ian 72:
1.19 ! chl 73: #ifndef __GNUC_PREREQ__
! 74: #ifdef __GNUC__
! 75: #define __GNUC_PREREQ__(x, y) \
! 76: ((__GNUC__ == (x) && __GNUC_MINOR__ >= (y)) || \
! 77: (__GNUC__ > (x)))
! 78: #else
! 79: #define __GNUC_PREREQ__(x, y) 0
! 80: #endif
! 81: #endif
! 82:
! 83: #ifndef MIN
! 84: #define MIN(a,b) (((a) < (b)) ? (a) : (b))
! 85: #endif
! 86:
1.1 deraadt 87: #ifndef HOWMANY
1.19 ! chl 88: # define HOWMANY (256 * 1024) /* how much of the file to look at */
1.1 deraadt 89: #endif
1.19 ! chl 90: #define MAXMAGIS 8192 /* max entries in /etc/magic */
1.16 tedu 91: #define MAXDESC 64 /* max leng of text description */
1.1 deraadt 92: #define MAXstring 32 /* max leng of "string" types */
93:
1.16 tedu 94: #define MAGICNO 0xF11E041C
1.19 ! chl 95: #define VERSIONNO 4
1.16 tedu 96: #define FILE_MAGICSIZE (32 * 4)
97:
98: #define FILE_LOAD 0
99: #define FILE_CHECK 1
100: #define FILE_COMPILE 2
101:
1.1 deraadt 102: struct magic {
1.16 tedu 103: /* Word 1 */
104: uint16_t cont_level; /* level of ">" */
1.18 martynas 105: uint8_t nospflag; /* suppress space character */
1.16 tedu 106: uint8_t flag;
1.19 ! chl 107: #define INDIR 1 /* if '(...)' appears */
! 108: #define OFFADD 2 /* if '>&' or '>...(&' appears */
! 109: #define INDIROFFADD 4 /* if '>&(' appears */
! 110: #define UNSIGNED 8 /* comparison is unsigned */
! 111:
1.16 tedu 112: /* Word 2 */
113: uint8_t reln; /* relation (0=eq, '>'=gt, etc) */
114: uint8_t vallen; /* length of string value, if any */
115: uint8_t type; /* int, short, long or string. */
116: uint8_t in_type; /* type of indirrection */
1.19 ! chl 117: #define FILE_INVALID 0
1.16 tedu 118: #define FILE_BYTE 1
119: #define FILE_SHORT 2
1.19 ! chl 120: #define FILE_DEFAULT 3
1.16 tedu 121: #define FILE_LONG 4
122: #define FILE_STRING 5
123: #define FILE_DATE 6
124: #define FILE_BESHORT 7
125: #define FILE_BELONG 8
126: #define FILE_BEDATE 9
127: #define FILE_LESHORT 10
128: #define FILE_LELONG 11
129: #define FILE_LEDATE 12
130: #define FILE_PSTRING 13
131: #define FILE_LDATE 14
132: #define FILE_BELDATE 15
133: #define FILE_LELDATE 16
134: #define FILE_REGEX 17
1.19 ! chl 135: #define FILE_BESTRING16 18
! 136: #define FILE_LESTRING16 19
! 137: #define FILE_SEARCH 20
! 138: #define FILE_MEDATE 21
! 139: #define FILE_MELDATE 22
! 140: #define FILE_MELONG 23
! 141: #define FILE_QUAD 24
! 142: #define FILE_LEQUAD 25
! 143: #define FILE_BEQUAD 26
! 144: #define FILE_QDATE 27
! 145: #define FILE_LEQDATE 28
! 146: #define FILE_BEQDATE 29
! 147: #define FILE_QLDATE 30
! 148: #define FILE_LEQLDATE 31
! 149: #define FILE_BEQLDATE 32
! 150: #define FILE_NAMES_SIZE 33/* size of array to contain all names */
! 151:
! 152: #define IS_STRING(t) \
! 153: ((t) == FILE_STRING || \
! 154: (t) == FILE_PSTRING || \
! 155: (t) == FILE_BESTRING16 || \
! 156: (t) == FILE_LESTRING16 || \
! 157: (t) == FILE_REGEX || \
! 158: (t) == FILE_SEARCH || \
! 159: (t) == FILE_DEFAULT)
! 160:
! 161: #define FILE_FMT_NONE 0
! 162: #define FILE_FMT_NUM 1 /* "cduxXi" */
! 163: #define FILE_FMT_STR 2 /* "s" */
! 164: #define FILE_FMT_QUAD 3 /* "ll" */
! 165:
1.16 tedu 166: /* Word 3 */
167: uint8_t in_op; /* operator for indirection */
168: uint8_t mask_op; /* operator for mask */
1.19 ! chl 169: #ifdef ENABLE_CONDITIONALS
! 170: uint8_t cond; /* conditional type */
! 171: uint8_t dummy1;
! 172: #else
1.16 tedu 173: uint8_t dummy1;
174: uint8_t dummy2;
1.19 ! chl 175: #endif
! 176:
1.16 tedu 177: #define FILE_OPS "&|^+-*/%"
178: #define FILE_OPAND 0
179: #define FILE_OPOR 1
180: #define FILE_OPXOR 2
181: #define FILE_OPADD 3
182: #define FILE_OPMINUS 4
183: #define FILE_OPMULTIPLY 5
184: #define FILE_OPDIVIDE 6
185: #define FILE_OPMODULO 7
1.19 ! chl 186: #define FILE_OPS_MASK 0x07 /* mask for above ops */
! 187: #define FILE_UNUSED_1 0x08
! 188: #define FILE_UNUSED_2 0x10
! 189: #define FILE_UNUSED_3 0x20
! 190: #define FILE_OPINVERSE 0x40
! 191: #define FILE_OPINDIRECT 0x80
! 192:
! 193: #ifdef ENABLE_CONDITIONALS
! 194: #define COND_NONE 0
! 195: #define COND_IF 1
! 196: #define COND_ELIF 2
! 197: #define COND_ELSE 3
! 198: #endif /* ENABLE_CONDITIONALS */
! 199:
1.16 tedu 200: /* Word 4 */
201: uint32_t offset; /* offset to magic number */
202: /* Word 5 */
1.19 ! chl 203: int32_t in_offset; /* offset from indirection */
1.16 tedu 204: /* Word 6 */
1.19 ! chl 205: uint32_t lineno; /* line number in magic file */
! 206: /* Word 7,8 */
! 207: union {
! 208: uint64_t _mask; /* for use with numeric and date types */
! 209: struct {
! 210: uint32_t _count; /* repeat/line count */
! 211: uint32_t _flags; /* modifier flags */
! 212: } _s; /* for use with string types */
! 213: } _u;
! 214: #define num_mask _u._mask
! 215: #define str_count _u._s._count
! 216: #define str_flags _u._s._flags
! 217:
1.16 tedu 218: /* Words 9-16 */
1.1 deraadt 219: union VALUETYPE {
1.16 tedu 220: uint8_t b;
221: uint16_t h;
1.10 itojun 222: uint32_t l;
1.19 ! chl 223: uint64_t q;
1.16 tedu 224: uint8_t hs[2]; /* 2 bytes of a fixed-endian "short" */
225: uint8_t hl[4]; /* 4 bytes of a fixed-endian "long" */
1.19 ! chl 226: uint8_t hq[8]; /* 8 bytes of a fixed-endian "quad" */
! 227: char s[MAXstring]; /* the search string or regex pattern */
1.1 deraadt 228: } value; /* either number or string */
1.16 tedu 229: /* Words 17..31 */
1.1 deraadt 230: char desc[MAXDESC]; /* description */
231: };
232:
1.16 tedu 233: #define BIT(A) (1 << (A))
1.19 ! chl 234: #define STRING_COMPACT_BLANK BIT(0)
! 235: #define STRING_COMPACT_OPTIONAL_BLANK BIT(1)
! 236: #define STRING_IGNORE_LOWERCASE BIT(2)
! 237: #define STRING_IGNORE_UPPERCASE BIT(3)
! 238: #define REGEX_OFFSET_START BIT(4)
1.16 tedu 239: #define CHAR_COMPACT_BLANK 'B'
240: #define CHAR_COMPACT_OPTIONAL_BLANK 'b'
1.19 ! chl 241: #define CHAR_IGNORE_LOWERCASE 'c'
! 242: #define CHAR_IGNORE_UPPERCASE 'C'
! 243: #define CHAR_REGEX_OFFSET_START 's'
! 244: #define STRING_IGNORE_CASE (STRING_IGNORE_LOWERCASE|STRING_IGNORE_UPPERCASE)
1.16 tedu 245:
246:
247: /* list of magic entries */
248: struct mlist {
249: struct magic *magic; /* array of magic entries */
250: uint32_t nmagic; /* number of entries in array */
251: int mapped; /* allocation type: 0 => apprentice_file
252: * 1 => apprentice_map + malloc
253: * 2 => apprentice_map + mmap */
254: struct mlist *next, *prev;
255: };
1.1 deraadt 256:
1.16 tedu 257: struct magic_set {
1.19 ! chl 258: struct mlist *mlist;
! 259: struct cont {
! 260: size_t len;
! 261: struct level_info {
! 262: int32_t off;
! 263: int got_match;
! 264: #ifdef ENABLE_CONDITIONALS
! 265: int last_match;
! 266: int last_cond; /* used for error checking by parse() */
! 267: #endif
! 268: } *li;
! 269: } c;
! 270: struct out {
! 271: /* Accumulation buffer */
! 272: char *buf;
! 273: char *ptr;
! 274: size_t left;
! 275: size_t size;
! 276: /* Printable buffer */
! 277: char *pbuf;
! 278: size_t psize;
! 279: } o;
! 280: uint32_t offset;
! 281: int error;
! 282: int flags;
! 283: int haderr;
! 284: const char *file;
! 285: size_t line; /* current magic line number */
! 286:
! 287: /* data for searches */
! 288: struct {
! 289: const char *s; /* start of search in original source */
! 290: size_t s_len; /* length of search region */
! 291: size_t offset; /* starting offset in source: XXX - should this be off_t? */
! 292: size_t rm_len; /* match length */
! 293: } search;
! 294:
! 295: union VALUETYPE ms_value; /* either number or string */
1.16 tedu 296: };
1.1 deraadt 297:
1.16 tedu 298: struct stat;
1.19 ! chl 299: protected const char *file_fmttime(uint32_t, int);
! 300: protected int file_buffer(struct magic_set *, int, const char *, const void *,
! 301: size_t);
1.16 tedu 302: protected int file_fsmagic(struct magic_set *, const char *, struct stat *);
303: protected int file_pipe2file(struct magic_set *, int, const void *, size_t);
304: protected int file_printf(struct magic_set *, const char *, ...);
305: protected int file_reset(struct magic_set *);
1.19 ! chl 306: protected int file_tryelf(struct magic_set *, int, const unsigned char *,
! 307: size_t);
! 308: protected int file_zmagic(struct magic_set *, int, const char *,
! 309: const unsigned char *, size_t);
1.16 tedu 310: protected int file_ascmagic(struct magic_set *, const unsigned char *, size_t);
311: protected int file_is_tar(struct magic_set *, const unsigned char *, size_t);
312: protected int file_softmagic(struct magic_set *, const unsigned char *, size_t);
313: protected struct mlist *file_apprentice(struct magic_set *, const char *, int);
1.19 ! chl 314: protected uint64_t file_signextend(struct magic_set *, struct magic *,
! 315: uint64_t);
1.16 tedu 316: protected void file_delmagic(struct magic *, int type, size_t entries);
317: protected void file_badread(struct magic_set *);
318: protected void file_badseek(struct magic_set *);
1.19 ! chl 319: protected void file_oomem(struct magic_set *, size_t);
1.16 tedu 320: protected void file_error(struct magic_set *, int, const char *, ...);
1.19 ! chl 321: protected void file_magerror(struct magic_set *, const char *, ...);
! 322: protected void file_magwarn(struct magic_set *, const char *, ...);
1.16 tedu 323: protected void file_mdump(struct magic *);
324: protected void file_showstr(FILE *, const char *, size_t);
325: protected size_t file_mbswidth(const char *);
326: protected const char *file_getbuffer(struct magic_set *);
1.19 ! chl 327: protected ssize_t sread(int, void *, size_t, int);
! 328: protected int file_check_mem(struct magic_set *, unsigned int);
! 329:
! 330: #ifndef COMPILE_ONLY
! 331: extern const char *file_names[];
! 332: extern const size_t file_nnames;
! 333: #endif
! 334:
! 335: #ifndef HAVE_STRERROR
! 336: extern int sys_nerr;
! 337: extern char *sys_errlist[];
! 338: #define strerror(e) \
! 339: (((e) >= 0 && (e) < sys_nerr) ? sys_errlist[(e)] : "Unknown error")
! 340: #endif
! 341:
! 342: #ifndef HAVE_STRTOUL
! 343: #define strtoul(a, b, c) strtol(a, b, c)
! 344: #endif
! 345:
! 346: #ifndef HAVE_SNPRINTF
! 347: int snprintf(char *, size_t, const char *, ...);
! 348: #endif
1.16 tedu 349:
350: #if defined(HAVE_MMAP) && defined(HAVE_SYS_MMAN_H) && !defined(QUICK)
351: #define QUICK
352: #endif
353:
1.19 ! chl 354: #ifndef O_BINARY
! 355: #define O_BINARY 0
! 356: #endif
! 357:
1.16 tedu 358: #define FILE_RCSID(id) \
359: static const char *rcsid(const char *p) { \
360: return rcsid(p = id); \
361: }
1.3 millert 362:
363: #endif /* __file_h__ */