]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/file/file.h
Record that base/vendor/file/dist@186675 was merged.
[FreeBSD/FreeBSD.git] / contrib / file / file.h
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  *  
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)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 /*
29  * file.h - definitions for file(1) program
30  * @(#)$File: file.h,v 1.108 2008/07/16 18:00:57 christos Exp $
31  */
32
33 #ifndef __file_h__
34 #define __file_h__
35
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif
39
40 #include <stdio.h>      /* Include that here, to make sure __P gets defined */
41 #include <errno.h>
42 #include <fcntl.h>      /* For open and flags */
43 #ifdef HAVE_STDINT_H
44 #include <stdint.h>
45 #endif
46 #ifdef HAVE_INTTYPES_H
47 #include <inttypes.h>
48 #endif
49 #include <regex.h>
50 #include <sys/types.h>
51 /* Do this here and now, because struct stat gets re-defined on solaris */
52 #include <sys/stat.h>
53 #include <stdarg.h>
54
55 #define ENABLE_CONDITIONALS
56
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
72
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 __GNUC__
84 #ifndef __attribute__
85 #define __attribute__(a)
86 #endif
87 #endif
88
89 #ifndef MIN
90 #define MIN(a,b)        (((a) < (b)) ? (a) : (b))
91 #endif
92
93 #ifndef MAX
94 #define MAX(a,b)        (((a) > (b)) ? (a) : (b))
95 #endif
96
97 #ifndef HOWMANY
98 # define HOWMANY (256 * 1024)   /* how much of the file to look at */
99 #endif
100 #define MAXMAGIS 8192           /* max entries in any one magic file
101                                    or directory */
102 #define MAXDESC 64              /* max leng of text description/MIME type */
103 #define MAXstring 32            /* max leng of "string" types */
104
105 #define MAGICNO         0xF11E041C
106 #define VERSIONNO       6
107 #define FILE_MAGICSIZE  (32 * 6)
108
109 #define FILE_LOAD       0
110 #define FILE_CHECK      1
111 #define FILE_COMPILE    2
112
113 union VALUETYPE {
114         uint8_t b;
115         uint16_t h;
116         uint32_t l;
117         uint64_t q;
118         uint8_t hs[2];  /* 2 bytes of a fixed-endian "short" */
119         uint8_t hl[4];  /* 4 bytes of a fixed-endian "long" */
120         uint8_t hq[8];  /* 8 bytes of a fixed-endian "quad" */
121         char s[MAXstring];      /* the search string or regex pattern */
122         unsigned char us[MAXstring];
123         float f;
124         double d;
125 }; 
126
127 struct magic {
128         /* Word 1 */
129         uint16_t cont_level;    /* level of ">" */
130         uint8_t flag;
131 #define INDIR           0x01    /* if '(...)' appears */
132 #define OFFADD          0x02    /* if '>&' or '>...(&' appears */
133 #define INDIROFFADD     0x04    /* if '>&(' appears */
134 #define UNSIGNED        0x08    /* comparison is unsigned */
135 #define NOSPACE         0x10    /* suppress space character before output */
136 #define BINTEST         0x20    /* test is for a binary type (set only
137                                    for top-level tests) */
138 #define TEXTTEST        0       /* for passing to file_softmagic */
139
140         uint8_t factor;
141
142         /* Word 2 */
143         uint8_t reln;           /* relation (0=eq, '>'=gt, etc) */
144         uint8_t vallen;         /* length of string value, if any */
145         uint8_t type;           /* comparison type (FILE_*) */
146         uint8_t in_type;        /* type of indirection */
147 #define                         FILE_INVALID    0
148 #define                         FILE_BYTE       1
149 #define                         FILE_SHORT      2
150 #define                         FILE_DEFAULT    3
151 #define                         FILE_LONG       4
152 #define                         FILE_STRING     5
153 #define                         FILE_DATE       6
154 #define                         FILE_BESHORT    7
155 #define                         FILE_BELONG     8
156 #define                         FILE_BEDATE     9
157 #define                         FILE_LESHORT    10
158 #define                         FILE_LELONG     11
159 #define                         FILE_LEDATE     12
160 #define                         FILE_PSTRING    13
161 #define                         FILE_LDATE      14
162 #define                         FILE_BELDATE    15
163 #define                         FILE_LELDATE    16
164 #define                         FILE_REGEX      17
165 #define                         FILE_BESTRING16 18
166 #define                         FILE_LESTRING16 19
167 #define                         FILE_SEARCH     20
168 #define                         FILE_MEDATE     21
169 #define                         FILE_MELDATE    22
170 #define                         FILE_MELONG     23
171 #define                         FILE_QUAD       24
172 #define                         FILE_LEQUAD     25
173 #define                         FILE_BEQUAD     26
174 #define                         FILE_QDATE      27
175 #define                         FILE_LEQDATE    28
176 #define                         FILE_BEQDATE    29
177 #define                         FILE_QLDATE     30
178 #define                         FILE_LEQLDATE   31
179 #define                         FILE_BEQLDATE   32
180 #define                         FILE_FLOAT      33
181 #define                         FILE_BEFLOAT    34
182 #define                         FILE_LEFLOAT    35
183 #define                         FILE_DOUBLE     36
184 #define                         FILE_BEDOUBLE   37
185 #define                         FILE_LEDOUBLE   38
186 #define                         FILE_NAMES_SIZE 39/* size of array to contain all names */
187
188 #define IS_STRING(t) \
189         ((t) == FILE_STRING || \
190          (t) == FILE_PSTRING || \
191          (t) == FILE_BESTRING16 || \
192          (t) == FILE_LESTRING16 || \
193          (t) == FILE_REGEX || \
194          (t) == FILE_SEARCH || \
195          (t) == FILE_DEFAULT)
196
197 #define FILE_FMT_NONE 0
198 #define FILE_FMT_NUM  1 /* "cduxXi" */
199 #define FILE_FMT_STR  2 /* "s" */
200 #define FILE_FMT_QUAD 3 /* "ll" */
201 #define FILE_FMT_FLOAT 4 /* "eEfFgG" */
202 #define FILE_FMT_DOUBLE 5 /* "eEfFgG" */
203
204         /* Word 3 */
205         uint8_t in_op;          /* operator for indirection */
206         uint8_t mask_op;        /* operator for mask */
207 #ifdef ENABLE_CONDITIONALS
208         uint8_t cond;           /* conditional type */
209 #else
210         uint8_t dummy;
211 #endif
212         uint8_t factor_op;      
213 #define         FILE_FACTOR_OP_PLUS     '+'
214 #define         FILE_FACTOR_OP_MINUS    '-'
215 #define         FILE_FACTOR_OP_TIMES    '*'
216 #define         FILE_FACTOR_OP_DIV      '/'
217 #define         FILE_FACTOR_OP_NONE     '\0'
218
219 #define                         FILE_OPS        "&|^+-*/%"
220 #define                         FILE_OPAND      0
221 #define                         FILE_OPOR       1
222 #define                         FILE_OPXOR      2
223 #define                         FILE_OPADD      3
224 #define                         FILE_OPMINUS    4
225 #define                         FILE_OPMULTIPLY 5
226 #define                         FILE_OPDIVIDE   6
227 #define                         FILE_OPMODULO   7
228 #define                         FILE_OPS_MASK   0x07 /* mask for above ops */
229 #define                         FILE_UNUSED_1   0x08
230 #define                         FILE_UNUSED_2   0x10
231 #define                         FILE_UNUSED_3   0x20
232 #define                         FILE_OPINVERSE  0x40
233 #define                         FILE_OPINDIRECT 0x80
234
235 #ifdef ENABLE_CONDITIONALS
236 #define                         COND_NONE       0
237 #define                         COND_IF         1
238 #define                         COND_ELIF       2
239 #define                         COND_ELSE       3
240 #endif /* ENABLE_CONDITIONALS */
241
242         /* Word 4 */
243         uint32_t offset;        /* offset to magic number */
244         /* Word 5 */
245         int32_t in_offset;      /* offset from indirection */
246         /* Word 6 */
247         uint32_t lineno;        /* line number in magic file */
248         /* Word 7,8 */
249         union {
250                 uint64_t _mask; /* for use with numeric and date types */
251                 struct {
252                         uint32_t _count;        /* repeat/line count */
253                         uint32_t _flags;        /* modifier flags */
254                 } _s;           /* for use with string types */
255         } _u;
256 #define num_mask _u._mask
257 #define str_range _u._s._count
258 #define str_flags _u._s._flags
259         /* Words 9-16 */
260         union VALUETYPE value;          /* either number or string */
261         /* Words 17..31 */
262         char desc[MAXDESC];     /* description */
263         /* Words 32..47 */
264         char mimetype[MAXDESC]; /* MIME type */
265 };
266
267 #define BIT(A)   (1 << (A))
268 #define STRING_COMPACT_BLANK            BIT(0)
269 #define STRING_COMPACT_OPTIONAL_BLANK   BIT(1)
270 #define STRING_IGNORE_LOWERCASE         BIT(2)
271 #define STRING_IGNORE_UPPERCASE         BIT(3)
272 #define REGEX_OFFSET_START              BIT(4)
273 #define CHAR_COMPACT_BLANK              'B'
274 #define CHAR_COMPACT_OPTIONAL_BLANK     'b'
275 #define CHAR_IGNORE_LOWERCASE           'c'
276 #define CHAR_IGNORE_UPPERCASE           'C'
277 #define CHAR_REGEX_OFFSET_START         's'
278 #define STRING_IGNORE_CASE              (STRING_IGNORE_LOWERCASE|STRING_IGNORE_UPPERCASE)
279 #define STRING_DEFAULT_RANGE            100
280
281
282 /* list of magic entries */
283 struct mlist {
284         struct magic *magic;            /* array of magic entries */
285         uint32_t nmagic;                        /* number of entries in array */
286         int mapped;  /* allocation type: 0 => apprentice_file
287                       *                  1 => apprentice_map + malloc
288                       *                  2 => apprentice_map + mmap */
289         struct mlist *next, *prev;
290 };
291
292 #ifdef __cplusplus
293 #define CAST(T, b)      static_cast<T>(b)
294 #else
295 #define CAST(T, b)      (b)
296 #endif
297
298 struct level_info {
299         int32_t off;
300         int got_match;
301 #ifdef ENABLE_CONDITIONALS
302         int last_match;
303         int last_cond;  /* used for error checking by parse() */
304 #endif
305 } *li;
306 struct magic_set {
307         struct mlist *mlist;
308         struct cont {
309                 size_t len;
310                 struct level_info *li;
311         } c;
312         struct out {
313                 char *buf;              /* Accumulation buffer */
314                 char *pbuf;             /* Printable buffer */
315         } o;
316         uint32_t offset;
317         int error;
318         int flags;
319         int haderr;
320         const char *file;
321         size_t line;                    /* current magic line number */
322
323         /* data for searches */
324         struct {
325                 const char *s;          /* start of search in original source */
326                 size_t s_len;           /* length of search region */
327                 size_t offset;          /* starting offset in source: XXX - should this be off_t? */
328                 size_t rm_len;          /* match length */
329         } search;
330
331         /* FIXME: Make the string dynamically allocated so that e.g.
332            strings matched in files can be longer than MAXstring */
333         union VALUETYPE ms_value;       /* either number or string */
334 };
335
336 /* Type for Unicode characters */
337 typedef unsigned long unichar;
338
339 struct stat;
340 protected const char *file_fmttime(uint32_t, int);
341 protected int file_buffer(struct magic_set *, int, const char *, const void *,
342     size_t);
343 protected int file_fsmagic(struct magic_set *, const char *, struct stat *);
344 protected int file_pipe2file(struct magic_set *, int, const void *, size_t);
345 protected int file_vprintf(struct magic_set *, const char *, va_list);
346 protected int file_printf(struct magic_set *, const char *, ...)
347     __attribute__((__format__(__printf__, 2, 3)));
348 protected int file_reset(struct magic_set *);
349 protected int file_tryelf(struct magic_set *, int, const unsigned char *,
350     size_t);
351 protected int file_zmagic(struct magic_set *, int, const char *,
352     const unsigned char *, size_t);
353 protected int file_ascmagic(struct magic_set *, const unsigned char *, size_t);
354 protected int file_is_tar(struct magic_set *, const unsigned char *, size_t);
355 protected int file_softmagic(struct magic_set *, const unsigned char *, size_t, int);
356 protected struct mlist *file_apprentice(struct magic_set *, const char *, int);
357 protected uint64_t file_signextend(struct magic_set *, struct magic *,
358     uint64_t);
359 protected void file_delmagic(struct magic *, int type, size_t entries);
360 protected void file_badread(struct magic_set *);
361 protected void file_badseek(struct magic_set *);
362 protected void file_oomem(struct magic_set *, size_t);
363 protected void file_error(struct magic_set *, int, const char *, ...)
364     __attribute__((__format__(__printf__, 3, 4)));
365 protected void file_magerror(struct magic_set *, const char *, ...)
366     __attribute__((__format__(__printf__, 2, 3)));
367 protected void file_magwarn(struct magic_set *, const char *, ...)
368     __attribute__((__format__(__printf__, 2, 3)));
369 protected void file_mdump(struct magic *);
370 protected void file_showstr(FILE *, const char *, size_t);
371 protected size_t file_mbswidth(const char *);
372 protected const char *file_getbuffer(struct magic_set *);
373 protected ssize_t sread(int, void *, size_t, int);
374 protected int file_check_mem(struct magic_set *, unsigned int);
375 protected int file_looks_utf8(const unsigned char *, size_t, unichar *, size_t *);
376
377 #ifndef COMPILE_ONLY
378 extern const char *file_names[];
379 extern const size_t file_nnames;
380 #endif
381
382 #ifndef HAVE_STRERROR
383 extern int sys_nerr;
384 extern char *sys_errlist[];
385 #define strerror(e) \
386         (((e) >= 0 && (e) < sys_nerr) ? sys_errlist[(e)] : "Unknown error")
387 #endif
388
389 #ifndef HAVE_STRTOUL
390 #define strtoul(a, b, c)        strtol(a, b, c)
391 #endif
392
393 #ifndef HAVE_VASPRINTF
394 int vasprintf(char **, const char *, va_list);
395 #endif
396 #ifndef HAVE_ASPRINTF
397 int asprintf(char **ptr, const char *format_string, ...);
398 #endif
399
400 #if defined(HAVE_MMAP) && defined(HAVE_SYS_MMAN_H) && !defined(QUICK)
401 #define QUICK
402 #endif
403
404 #ifndef O_BINARY
405 #define O_BINARY        0
406 #endif
407
408 #ifndef __cplusplus
409 #ifdef __GNUC__
410 static const char *rcsid(const char *) __attribute__((__used__));
411 #endif
412 #define FILE_RCSID(id) \
413 static const char *rcsid(const char *p) { \
414         return rcsid(p = id); \
415 }
416 #else
417 #define FILE_RCSID(id)
418 #endif
419
420 #endif /* __file_h__ */