xref: /freebsd/contrib/file/src/file.h (revision c2931133)
1b6cee71dSXin LI /*
2b6cee71dSXin LI  * Copyright (c) Ian F. Darwin 1986-1995.
3b6cee71dSXin LI  * Software written by Ian F. Darwin and others;
4b6cee71dSXin LI  * maintained 1995-present by Christos Zoulas and others.
5b6cee71dSXin LI  *
6b6cee71dSXin LI  * Redistribution and use in source and binary forms, with or without
7b6cee71dSXin LI  * modification, are permitted provided that the following conditions
8b6cee71dSXin LI  * are met:
9b6cee71dSXin LI  * 1. Redistributions of source code must retain the above copyright
10b6cee71dSXin LI  *    notice immediately at the beginning of the file, without modification,
11b6cee71dSXin LI  *    this list of conditions, and the following disclaimer.
12b6cee71dSXin LI  * 2. Redistributions in binary form must reproduce the above copyright
13b6cee71dSXin LI  *    notice, this list of conditions and the following disclaimer in the
14b6cee71dSXin LI  *    documentation and/or other materials provided with the distribution.
15b6cee71dSXin LI  *
16b6cee71dSXin LI  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17b6cee71dSXin LI  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18b6cee71dSXin LI  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19b6cee71dSXin LI  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20b6cee71dSXin LI  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21b6cee71dSXin LI  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22b6cee71dSXin LI  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23b6cee71dSXin LI  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24b6cee71dSXin LI  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25b6cee71dSXin LI  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26b6cee71dSXin LI  * SUCH DAMAGE.
27b6cee71dSXin LI  */
28b6cee71dSXin LI /*
29b6cee71dSXin LI  * file.h - definitions for file(1) program
30c2931133SXin LI  * @(#)$File: file.h,v 1.161 2014/12/04 15:56:46 christos Exp $
31b6cee71dSXin LI  */
32b6cee71dSXin LI 
33b6cee71dSXin LI #ifndef __file_h__
34b6cee71dSXin LI #define __file_h__
35b6cee71dSXin LI 
36b6cee71dSXin LI #ifdef HAVE_CONFIG_H
37b6cee71dSXin LI #include <config.h>
38b6cee71dSXin LI #endif
39b6cee71dSXin LI 
40b6cee71dSXin LI #ifdef WIN32
41b6cee71dSXin LI   #ifdef _WIN64
42b6cee71dSXin LI     #define SIZE_T_FORMAT "I64"
43b6cee71dSXin LI   #else
44b6cee71dSXin LI     #define SIZE_T_FORMAT ""
45b6cee71dSXin LI   #endif
46b6cee71dSXin LI   #define INT64_T_FORMAT "I64"
47b6cee71dSXin LI #else
48b6cee71dSXin LI   #define SIZE_T_FORMAT "z"
49b6cee71dSXin LI   #define INT64_T_FORMAT "ll"
50b6cee71dSXin LI #endif
51b6cee71dSXin LI 
52b6cee71dSXin LI #include <stdio.h>	/* Include that here, to make sure __P gets defined */
53b6cee71dSXin LI #include <errno.h>
54b6cee71dSXin LI #include <fcntl.h>	/* For open and flags */
55b6cee71dSXin LI #ifdef HAVE_STDINT_H
56b6cee71dSXin LI #ifndef __STDC_LIMIT_MACROS
57b6cee71dSXin LI #define __STDC_LIMIT_MACROS
58b6cee71dSXin LI #endif
59b6cee71dSXin LI #include <stdint.h>
60b6cee71dSXin LI #endif
61b6cee71dSXin LI #ifdef HAVE_INTTYPES_H
62b6cee71dSXin LI #include <inttypes.h>
63b6cee71dSXin LI #endif
64b6cee71dSXin LI #include <regex.h>
65b6cee71dSXin LI #include <time.h>
66b6cee71dSXin LI #include <sys/types.h>
67c2931133SXin LI #ifndef WIN32
68b6cee71dSXin LI #include <sys/param.h>
69c2931133SXin LI #endif
70b6cee71dSXin LI /* Do this here and now, because struct stat gets re-defined on solaris */
71b6cee71dSXin LI #include <sys/stat.h>
72b6cee71dSXin LI #include <stdarg.h>
73b6cee71dSXin LI 
74b6cee71dSXin LI #define ENABLE_CONDITIONALS
75b6cee71dSXin LI 
76b6cee71dSXin LI #ifndef MAGIC
77b6cee71dSXin LI #define MAGIC "/etc/magic"
78b6cee71dSXin LI #endif
79b6cee71dSXin LI 
80b6cee71dSXin LI #if defined(__EMX__) || defined (WIN32)
81b6cee71dSXin LI #define PATHSEP	';'
82b6cee71dSXin LI #else
83b6cee71dSXin LI #define PATHSEP	':'
84b6cee71dSXin LI #endif
85b6cee71dSXin LI 
86b6cee71dSXin LI #define private static
87b6cee71dSXin LI 
88b6cee71dSXin LI #if HAVE_VISIBILITY && !defined(WIN32)
89b6cee71dSXin LI #define public  __attribute__ ((__visibility__("default")))
90b6cee71dSXin LI #ifndef protected
91b6cee71dSXin LI #define protected __attribute__ ((__visibility__("hidden")))
92b6cee71dSXin LI #endif
93b6cee71dSXin LI #else
94b6cee71dSXin LI #define public
95b6cee71dSXin LI #ifndef protected
96b6cee71dSXin LI #define protected
97b6cee71dSXin LI #endif
98b6cee71dSXin LI #endif
99b6cee71dSXin LI 
100b6cee71dSXin LI #ifndef __arraycount
101b6cee71dSXin LI #define __arraycount(a) (sizeof(a) / sizeof(a[0]))
102b6cee71dSXin LI #endif
103b6cee71dSXin LI 
104b6cee71dSXin LI #ifndef __GNUC_PREREQ__
105b6cee71dSXin LI #ifdef __GNUC__
106b6cee71dSXin LI #define	__GNUC_PREREQ__(x, y)						\
107b6cee71dSXin LI 	((__GNUC__ == (x) && __GNUC_MINOR__ >= (y)) ||			\
108b6cee71dSXin LI 	 (__GNUC__ > (x)))
109b6cee71dSXin LI #else
110b6cee71dSXin LI #define	__GNUC_PREREQ__(x, y)	0
111b6cee71dSXin LI #endif
112b6cee71dSXin LI #endif
113b6cee71dSXin LI 
114b6cee71dSXin LI #ifndef __GNUC__
115b6cee71dSXin LI #ifndef __attribute__
116b6cee71dSXin LI #define __attribute__(a)
117b6cee71dSXin LI #endif
118b6cee71dSXin LI #endif
119b6cee71dSXin LI 
120b6cee71dSXin LI #ifndef MIN
121b6cee71dSXin LI #define	MIN(a,b)	(((a) < (b)) ? (a) : (b))
122b6cee71dSXin LI #endif
123b6cee71dSXin LI 
124b6cee71dSXin LI #ifndef MAX
125b6cee71dSXin LI #define	MAX(a,b)	(((a) > (b)) ? (a) : (b))
126b6cee71dSXin LI #endif
127b6cee71dSXin LI 
128b6cee71dSXin LI #ifndef HOWMANY
129b6cee71dSXin LI # define HOWMANY (256 * 1024)	/* how much of the file to look at */
130b6cee71dSXin LI #endif
131b6cee71dSXin LI #define MAXMAGIS 8192		/* max entries in any one magic file
132b6cee71dSXin LI 				   or directory */
133b6cee71dSXin LI #define MAXDESC	64		/* max len of text description/MIME type */
134b6cee71dSXin LI #define MAXMIME	80		/* max len of text MIME type */
135b6cee71dSXin LI #define MAXstring 64		/* max len of "string" types */
136b6cee71dSXin LI 
137b6cee71dSXin LI #define MAGICNO		0xF11E041C
138b6cee71dSXin LI #define VERSIONNO	12
139b6cee71dSXin LI #define FILE_MAGICSIZE	248
140b6cee71dSXin LI 
141b6cee71dSXin LI #define	FILE_LOAD	0
142b6cee71dSXin LI #define FILE_CHECK	1
143b6cee71dSXin LI #define FILE_COMPILE	2
144b6cee71dSXin LI #define FILE_LIST	3
145b6cee71dSXin LI 
146b6cee71dSXin LI union VALUETYPE {
147b6cee71dSXin LI 	uint8_t b;
148b6cee71dSXin LI 	uint16_t h;
149b6cee71dSXin LI 	uint32_t l;
150b6cee71dSXin LI 	uint64_t q;
151b6cee71dSXin LI 	uint8_t hs[2];	/* 2 bytes of a fixed-endian "short" */
152b6cee71dSXin LI 	uint8_t hl[4];	/* 4 bytes of a fixed-endian "long" */
153b6cee71dSXin LI 	uint8_t hq[8];	/* 8 bytes of a fixed-endian "quad" */
154b6cee71dSXin LI 	char s[MAXstring];	/* the search string or regex pattern */
155b6cee71dSXin LI 	unsigned char us[MAXstring];
156b6cee71dSXin LI 	float f;
157b6cee71dSXin LI 	double d;
158b6cee71dSXin LI };
159b6cee71dSXin LI 
160b6cee71dSXin LI struct magic {
161b6cee71dSXin LI 	/* Word 1 */
162b6cee71dSXin LI 	uint16_t cont_level;	/* level of ">" */
163b6cee71dSXin LI 	uint8_t flag;
164b6cee71dSXin LI #define INDIR		0x01	/* if '(...)' appears */
165b6cee71dSXin LI #define OFFADD		0x02	/* if '>&' or '>...(&' appears */
166b6cee71dSXin LI #define INDIROFFADD	0x04	/* if '>&(' appears */
167b6cee71dSXin LI #define UNSIGNED	0x08	/* comparison is unsigned */
168b6cee71dSXin LI #define NOSPACE		0x10	/* suppress space character before output */
169b6cee71dSXin LI #define BINTEST		0x20	/* test is for a binary type (set only
170b6cee71dSXin LI 				   for top-level tests) */
171b6cee71dSXin LI #define TEXTTEST	0x40	/* for passing to file_softmagic */
172b6cee71dSXin LI 
173b6cee71dSXin LI 	uint8_t factor;
174b6cee71dSXin LI 
175b6cee71dSXin LI 	/* Word 2 */
176b6cee71dSXin LI 	uint8_t reln;		/* relation (0=eq, '>'=gt, etc) */
177b6cee71dSXin LI 	uint8_t vallen;		/* length of string value, if any */
178b6cee71dSXin LI 	uint8_t type;		/* comparison type (FILE_*) */
179b6cee71dSXin LI 	uint8_t in_type;	/* type of indirection */
180b6cee71dSXin LI #define 			FILE_INVALID	0
181b6cee71dSXin LI #define 			FILE_BYTE	1
182b6cee71dSXin LI #define				FILE_SHORT	2
183b6cee71dSXin LI #define				FILE_DEFAULT	3
184b6cee71dSXin LI #define				FILE_LONG	4
185b6cee71dSXin LI #define				FILE_STRING	5
186b6cee71dSXin LI #define				FILE_DATE	6
187b6cee71dSXin LI #define				FILE_BESHORT	7
188b6cee71dSXin LI #define				FILE_BELONG	8
189b6cee71dSXin LI #define				FILE_BEDATE	9
190b6cee71dSXin LI #define				FILE_LESHORT	10
191b6cee71dSXin LI #define				FILE_LELONG	11
192b6cee71dSXin LI #define				FILE_LEDATE	12
193b6cee71dSXin LI #define				FILE_PSTRING	13
194b6cee71dSXin LI #define				FILE_LDATE	14
195b6cee71dSXin LI #define				FILE_BELDATE	15
196b6cee71dSXin LI #define				FILE_LELDATE	16
197b6cee71dSXin LI #define				FILE_REGEX	17
198b6cee71dSXin LI #define				FILE_BESTRING16	18
199b6cee71dSXin LI #define				FILE_LESTRING16	19
200b6cee71dSXin LI #define				FILE_SEARCH	20
201b6cee71dSXin LI #define				FILE_MEDATE	21
202b6cee71dSXin LI #define				FILE_MELDATE	22
203b6cee71dSXin LI #define				FILE_MELONG	23
204b6cee71dSXin LI #define				FILE_QUAD	24
205b6cee71dSXin LI #define				FILE_LEQUAD	25
206b6cee71dSXin LI #define				FILE_BEQUAD	26
207b6cee71dSXin LI #define				FILE_QDATE	27
208b6cee71dSXin LI #define				FILE_LEQDATE	28
209b6cee71dSXin LI #define				FILE_BEQDATE	29
210b6cee71dSXin LI #define				FILE_QLDATE	30
211b6cee71dSXin LI #define				FILE_LEQLDATE	31
212b6cee71dSXin LI #define				FILE_BEQLDATE	32
213b6cee71dSXin LI #define				FILE_FLOAT	33
214b6cee71dSXin LI #define				FILE_BEFLOAT	34
215b6cee71dSXin LI #define				FILE_LEFLOAT	35
216b6cee71dSXin LI #define				FILE_DOUBLE	36
217b6cee71dSXin LI #define				FILE_BEDOUBLE	37
218b6cee71dSXin LI #define				FILE_LEDOUBLE	38
219b6cee71dSXin LI #define				FILE_BEID3	39
220b6cee71dSXin LI #define				FILE_LEID3	40
221b6cee71dSXin LI #define				FILE_INDIRECT	41
222b6cee71dSXin LI #define				FILE_QWDATE	42
223b6cee71dSXin LI #define				FILE_LEQWDATE	43
224b6cee71dSXin LI #define				FILE_BEQWDATE	44
225b6cee71dSXin LI #define				FILE_NAME	45
226b6cee71dSXin LI #define				FILE_USE	46
227b6cee71dSXin LI #define				FILE_CLEAR	47
228b6cee71dSXin LI #define				FILE_NAMES_SIZE	48 /* size of array to contain all names */
229b6cee71dSXin LI 
230b6cee71dSXin LI #define IS_STRING(t) \
231b6cee71dSXin LI 	((t) == FILE_STRING || \
232b6cee71dSXin LI 	 (t) == FILE_PSTRING || \
233b6cee71dSXin LI 	 (t) == FILE_BESTRING16 || \
234b6cee71dSXin LI 	 (t) == FILE_LESTRING16 || \
235b6cee71dSXin LI 	 (t) == FILE_REGEX || \
236b6cee71dSXin LI 	 (t) == FILE_SEARCH || \
237b6cee71dSXin LI 	 (t) == FILE_NAME || \
238b6cee71dSXin LI 	 (t) == FILE_USE)
239b6cee71dSXin LI 
240b6cee71dSXin LI #define FILE_FMT_NONE 0
241b6cee71dSXin LI #define FILE_FMT_NUM  1 /* "cduxXi" */
242b6cee71dSXin LI #define FILE_FMT_STR  2 /* "s" */
243b6cee71dSXin LI #define FILE_FMT_QUAD 3 /* "ll" */
244b6cee71dSXin LI #define FILE_FMT_FLOAT 4 /* "eEfFgG" */
245b6cee71dSXin LI #define FILE_FMT_DOUBLE 5 /* "eEfFgG" */
246b6cee71dSXin LI 
247b6cee71dSXin LI 	/* Word 3 */
248b6cee71dSXin LI 	uint8_t in_op;		/* operator for indirection */
249b6cee71dSXin LI 	uint8_t mask_op;	/* operator for mask */
250b6cee71dSXin LI #ifdef ENABLE_CONDITIONALS
251b6cee71dSXin LI 	uint8_t cond;		/* conditional type */
252b6cee71dSXin LI #else
253b6cee71dSXin LI 	uint8_t dummy;
254b6cee71dSXin LI #endif
255b6cee71dSXin LI 	uint8_t factor_op;
256b6cee71dSXin LI #define		FILE_FACTOR_OP_PLUS	'+'
257b6cee71dSXin LI #define		FILE_FACTOR_OP_MINUS	'-'
258b6cee71dSXin LI #define		FILE_FACTOR_OP_TIMES	'*'
259b6cee71dSXin LI #define		FILE_FACTOR_OP_DIV	'/'
260b6cee71dSXin LI #define		FILE_FACTOR_OP_NONE	'\0'
261b6cee71dSXin LI 
262b6cee71dSXin LI #define				FILE_OPS	"&|^+-*/%"
263b6cee71dSXin LI #define				FILE_OPAND	0
264b6cee71dSXin LI #define				FILE_OPOR	1
265b6cee71dSXin LI #define				FILE_OPXOR	2
266b6cee71dSXin LI #define				FILE_OPADD	3
267b6cee71dSXin LI #define				FILE_OPMINUS	4
268b6cee71dSXin LI #define				FILE_OPMULTIPLY	5
269b6cee71dSXin LI #define				FILE_OPDIVIDE	6
270b6cee71dSXin LI #define				FILE_OPMODULO	7
271b6cee71dSXin LI #define				FILE_OPS_MASK	0x07 /* mask for above ops */
272b6cee71dSXin LI #define				FILE_UNUSED_1	0x08
273b6cee71dSXin LI #define				FILE_UNUSED_2	0x10
274b6cee71dSXin LI #define				FILE_UNUSED_3	0x20
275b6cee71dSXin LI #define				FILE_OPINVERSE	0x40
276b6cee71dSXin LI #define				FILE_OPINDIRECT	0x80
277b6cee71dSXin LI 
278b6cee71dSXin LI #ifdef ENABLE_CONDITIONALS
279b6cee71dSXin LI #define				COND_NONE	0
280b6cee71dSXin LI #define				COND_IF		1
281b6cee71dSXin LI #define				COND_ELIF	2
282b6cee71dSXin LI #define				COND_ELSE	3
283b6cee71dSXin LI #endif /* ENABLE_CONDITIONALS */
284b6cee71dSXin LI 
285b6cee71dSXin LI 	/* Word 4 */
286b6cee71dSXin LI 	uint32_t offset;	/* offset to magic number */
287b6cee71dSXin LI 	/* Word 5 */
288b6cee71dSXin LI 	int32_t in_offset;	/* offset from indirection */
289b6cee71dSXin LI 	/* Word 6 */
290b6cee71dSXin LI 	uint32_t lineno;	/* line number in magic file */
291b6cee71dSXin LI 	/* Word 7,8 */
292b6cee71dSXin LI 	union {
293b6cee71dSXin LI 		uint64_t _mask;	/* for use with numeric and date types */
294b6cee71dSXin LI 		struct {
295b6cee71dSXin LI 			uint32_t _count;	/* repeat/line count */
296b6cee71dSXin LI 			uint32_t _flags;	/* modifier flags */
297b6cee71dSXin LI 		} _s;		/* for use with string types */
298b6cee71dSXin LI 	} _u;
299b6cee71dSXin LI #define num_mask _u._mask
300b6cee71dSXin LI #define str_range _u._s._count
301b6cee71dSXin LI #define str_flags _u._s._flags
302b6cee71dSXin LI 	/* Words 9-16 */
303b6cee71dSXin LI 	union VALUETYPE value;	/* either number or string */
304b6cee71dSXin LI 	/* Words 17-32 */
305b6cee71dSXin LI 	char desc[MAXDESC];	/* description */
306b6cee71dSXin LI 	/* Words 33-52 */
307b6cee71dSXin LI 	char mimetype[MAXMIME]; /* MIME type */
308b6cee71dSXin LI 	/* Words 53-54 */
309b6cee71dSXin LI 	char apple[8];
310b6cee71dSXin LI };
311b6cee71dSXin LI 
312b6cee71dSXin LI #define BIT(A)   (1 << (A))
313b6cee71dSXin LI #define STRING_COMPACT_WHITESPACE		BIT(0)
314b6cee71dSXin LI #define STRING_COMPACT_OPTIONAL_WHITESPACE	BIT(1)
315b6cee71dSXin LI #define STRING_IGNORE_LOWERCASE			BIT(2)
316b6cee71dSXin LI #define STRING_IGNORE_UPPERCASE			BIT(3)
317b6cee71dSXin LI #define REGEX_OFFSET_START			BIT(4)
318b6cee71dSXin LI #define STRING_TEXTTEST				BIT(5)
319b6cee71dSXin LI #define STRING_BINTEST				BIT(6)
320b6cee71dSXin LI #define PSTRING_1_BE				BIT(7)
321b6cee71dSXin LI #define PSTRING_1_LE				BIT(7)
322b6cee71dSXin LI #define PSTRING_2_BE				BIT(8)
323b6cee71dSXin LI #define PSTRING_2_LE				BIT(9)
324b6cee71dSXin LI #define PSTRING_4_BE				BIT(10)
325b6cee71dSXin LI #define PSTRING_4_LE				BIT(11)
326b6cee71dSXin LI #define REGEX_LINE_COUNT			BIT(11)
327b6cee71dSXin LI #define PSTRING_LEN	\
328b6cee71dSXin LI     (PSTRING_1_BE|PSTRING_2_LE|PSTRING_2_BE|PSTRING_4_LE|PSTRING_4_BE)
329b6cee71dSXin LI #define PSTRING_LENGTH_INCLUDES_ITSELF		BIT(12)
330b6cee71dSXin LI #define	STRING_TRIM				BIT(13)
331b6cee71dSXin LI #define CHAR_COMPACT_WHITESPACE			'W'
332b6cee71dSXin LI #define CHAR_COMPACT_OPTIONAL_WHITESPACE	'w'
333b6cee71dSXin LI #define CHAR_IGNORE_LOWERCASE			'c'
334b6cee71dSXin LI #define CHAR_IGNORE_UPPERCASE			'C'
335b6cee71dSXin LI #define CHAR_REGEX_OFFSET_START			's'
336b6cee71dSXin LI #define CHAR_TEXTTEST				't'
337b6cee71dSXin LI #define	CHAR_TRIM				'T'
338b6cee71dSXin LI #define CHAR_BINTEST				'b'
339b6cee71dSXin LI #define CHAR_PSTRING_1_BE			'B'
340b6cee71dSXin LI #define CHAR_PSTRING_1_LE			'B'
341b6cee71dSXin LI #define CHAR_PSTRING_2_BE			'H'
342b6cee71dSXin LI #define CHAR_PSTRING_2_LE			'h'
343b6cee71dSXin LI #define CHAR_PSTRING_4_BE			'L'
344b6cee71dSXin LI #define CHAR_PSTRING_4_LE			'l'
345b6cee71dSXin LI #define CHAR_PSTRING_LENGTH_INCLUDES_ITSELF     'J'
346b6cee71dSXin LI #define STRING_IGNORE_CASE		(STRING_IGNORE_LOWERCASE|STRING_IGNORE_UPPERCASE)
347b6cee71dSXin LI #define STRING_DEFAULT_RANGE		100
348b6cee71dSXin LI 
349b6cee71dSXin LI 
350b6cee71dSXin LI /* list of magic entries */
351b6cee71dSXin LI struct mlist {
352b6cee71dSXin LI 	struct magic *magic;		/* array of magic entries */
353b6cee71dSXin LI 	uint32_t nmagic;		/* number of entries in array */
354b6cee71dSXin LI 	void *map;			/* internal resources used by entry */
355b6cee71dSXin LI 	struct mlist *next, *prev;
356b6cee71dSXin LI };
357b6cee71dSXin LI 
358b6cee71dSXin LI #ifdef __cplusplus
359b6cee71dSXin LI #define CAST(T, b)	static_cast<T>(b)
360b6cee71dSXin LI #define RCAST(T, b)	reinterpret_cast<T>(b)
361b6cee71dSXin LI #else
362b6cee71dSXin LI #define CAST(T, b)	(T)(b)
363b6cee71dSXin LI #define RCAST(T, b)	(T)(b)
364b6cee71dSXin LI #endif
365b6cee71dSXin LI 
366b6cee71dSXin LI struct level_info {
367b6cee71dSXin LI 	int32_t off;
368b6cee71dSXin LI 	int got_match;
369b6cee71dSXin LI #ifdef ENABLE_CONDITIONALS
370b6cee71dSXin LI 	int last_match;
371b6cee71dSXin LI 	int last_cond;	/* used for error checking by parse() */
372b6cee71dSXin LI #endif
373b6cee71dSXin LI };
374b6cee71dSXin LI 
375b6cee71dSXin LI #define MAGIC_SETS	2
376b6cee71dSXin LI 
377b6cee71dSXin LI struct magic_set {
378b6cee71dSXin LI 	struct mlist *mlist[MAGIC_SETS];	/* list of regular entries */
379b6cee71dSXin LI 	struct cont {
380b6cee71dSXin LI 		size_t len;
381b6cee71dSXin LI 		struct level_info *li;
382b6cee71dSXin LI 	} c;
383b6cee71dSXin LI 	struct out {
384b6cee71dSXin LI 		char *buf;		/* Accumulation buffer */
385b6cee71dSXin LI 		char *pbuf;		/* Printable buffer */
386b6cee71dSXin LI 	} o;
387b6cee71dSXin LI 	uint32_t offset;
388b6cee71dSXin LI 	int error;
389b6cee71dSXin LI 	int flags;			/* Control magic tests. */
390b6cee71dSXin LI 	int event_flags;		/* Note things that happened. */
391b6cee71dSXin LI #define 		EVENT_HAD_ERR		0x01
392b6cee71dSXin LI 	const char *file;
393b6cee71dSXin LI 	size_t line;			/* current magic line number */
394b6cee71dSXin LI 
395b6cee71dSXin LI 	/* data for searches */
396b6cee71dSXin LI 	struct {
397b6cee71dSXin LI 		const char *s;		/* start of search in original source */
398b6cee71dSXin LI 		size_t s_len;		/* length of search region */
399b6cee71dSXin LI 		size_t offset;		/* starting offset in source: XXX - should this be off_t? */
400b6cee71dSXin LI 		size_t rm_len;		/* match length */
401b6cee71dSXin LI 	} search;
402b6cee71dSXin LI 
403b6cee71dSXin LI 	/* FIXME: Make the string dynamically allocated so that e.g.
404b6cee71dSXin LI 	   strings matched in files can be longer than MAXstring */
405b6cee71dSXin LI 	union VALUETYPE ms_value;	/* either number or string */
406c2931133SXin LI 	uint16_t indir_max;
407c2931133SXin LI 	uint16_t name_max;
408c2931133SXin LI 	uint16_t elf_shnum_max;
409c2931133SXin LI 	uint16_t elf_phnum_max;
410c2931133SXin LI #define	FILE_INDIR_MAX			15
411c2931133SXin LI #define	FILE_NAME_MAX			30
412c2931133SXin LI #define	FILE_ELF_SHNUM_MAX		32768
413c2931133SXin LI #define	FILE_ELF_PHNUM_MAX		128
414b6cee71dSXin LI };
415b6cee71dSXin LI 
416b6cee71dSXin LI /* Type for Unicode characters */
417b6cee71dSXin LI typedef unsigned long unichar;
418b6cee71dSXin LI 
419b6cee71dSXin LI struct stat;
420b6cee71dSXin LI #define FILE_T_LOCAL	1
421b6cee71dSXin LI #define FILE_T_WINDOWS	2
422b6cee71dSXin LI protected const char *file_fmttime(uint64_t, int, char *);
423b6cee71dSXin LI protected struct magic_set *file_ms_alloc(int);
424b6cee71dSXin LI protected void file_ms_free(struct magic_set *);
425b6cee71dSXin LI protected int file_buffer(struct magic_set *, int, const char *, const void *,
426b6cee71dSXin LI     size_t);
427b6cee71dSXin LI protected int file_fsmagic(struct magic_set *, const char *, struct stat *);
428b6cee71dSXin LI protected int file_pipe2file(struct magic_set *, int, const void *, size_t);
429b6cee71dSXin LI protected int file_vprintf(struct magic_set *, const char *, va_list)
430b6cee71dSXin LI     __attribute__((__format__(__printf__, 2, 0)));
431b6cee71dSXin LI protected size_t file_printedlen(const struct magic_set *);
432b6cee71dSXin LI protected int file_replace(struct magic_set *, const char *, const char *);
433b6cee71dSXin LI protected int file_printf(struct magic_set *, const char *, ...)
434b6cee71dSXin LI     __attribute__((__format__(__printf__, 2, 3)));
435b6cee71dSXin LI protected int file_reset(struct magic_set *);
436b6cee71dSXin LI protected int file_tryelf(struct magic_set *, int, const unsigned char *,
437b6cee71dSXin LI     size_t);
438b6cee71dSXin LI protected int file_trycdf(struct magic_set *, int, const unsigned char *,
439b6cee71dSXin LI     size_t);
440b6cee71dSXin LI #if HAVE_FORK
441b6cee71dSXin LI protected int file_zmagic(struct magic_set *, int, const char *,
442b6cee71dSXin LI     const unsigned char *, size_t);
443b6cee71dSXin LI #endif
444b6cee71dSXin LI protected int file_ascmagic(struct magic_set *, const unsigned char *, size_t,
445b6cee71dSXin LI     int);
446b6cee71dSXin LI protected int file_ascmagic_with_encoding(struct magic_set *,
447b6cee71dSXin LI     const unsigned char *, size_t, unichar *, size_t, const char *,
448b6cee71dSXin LI     const char *, int);
449b6cee71dSXin LI protected int file_encoding(struct magic_set *, const unsigned char *, size_t,
450b6cee71dSXin LI     unichar **, size_t *, const char **, const char **, const char **);
451b6cee71dSXin LI protected int file_is_tar(struct magic_set *, const unsigned char *, size_t);
452b6cee71dSXin LI protected int file_softmagic(struct magic_set *, const unsigned char *, size_t,
453c2931133SXin LI     uint16_t, uint16_t *, int, int);
454b6cee71dSXin LI protected int file_apprentice(struct magic_set *, const char *, int);
455c2931133SXin LI protected int buffer_apprentice(struct magic_set *, struct magic **,
456c2931133SXin LI     size_t *, size_t);
457b6cee71dSXin LI protected int file_magicfind(struct magic_set *, const char *, struct mlist *);
458b6cee71dSXin LI protected uint64_t file_signextend(struct magic_set *, struct magic *,
459b6cee71dSXin LI     uint64_t);
460b6cee71dSXin LI protected void file_badread(struct magic_set *);
461b6cee71dSXin LI protected void file_badseek(struct magic_set *);
462b6cee71dSXin LI protected void file_oomem(struct magic_set *, size_t);
463b6cee71dSXin LI protected void file_error(struct magic_set *, int, const char *, ...)
464b6cee71dSXin LI     __attribute__((__format__(__printf__, 3, 4)));
465b6cee71dSXin LI protected void file_magerror(struct magic_set *, const char *, ...)
466b6cee71dSXin LI     __attribute__((__format__(__printf__, 2, 3)));
467b6cee71dSXin LI protected void file_magwarn(struct magic_set *, const char *, ...)
468b6cee71dSXin LI     __attribute__((__format__(__printf__, 2, 3)));
469b6cee71dSXin LI protected void file_mdump(struct magic *);
470b6cee71dSXin LI protected void file_showstr(FILE *, const char *, size_t);
471b6cee71dSXin LI protected size_t file_mbswidth(const char *);
472b6cee71dSXin LI protected const char *file_getbuffer(struct magic_set *);
473b6cee71dSXin LI protected ssize_t sread(int, void *, size_t, int);
474b6cee71dSXin LI protected int file_check_mem(struct magic_set *, unsigned int);
475b6cee71dSXin LI protected int file_looks_utf8(const unsigned char *, size_t, unichar *,
476b6cee71dSXin LI     size_t *);
477b6cee71dSXin LI protected size_t file_pstring_length_size(const struct magic *);
478b6cee71dSXin LI protected size_t file_pstring_get_length(const struct magic *, const char *);
479b6cee71dSXin LI #ifdef __EMX__
480b6cee71dSXin LI protected int file_os2_apptype(struct magic_set *, const char *, const void *,
481b6cee71dSXin LI     size_t);
482b6cee71dSXin LI #endif /* __EMX__ */
483b6cee71dSXin LI 
484c2931133SXin LI #if defined(HAVE_LOCALE_H)
485c2931133SXin LI #include <locale.h>
486c2931133SXin LI #endif
487c2931133SXin LI #if defined(HAVE_XLOCALE_H)
488c2931133SXin LI #include <xlocale.h>
489c2931133SXin LI #endif
490c2931133SXin LI 
491b6cee71dSXin LI typedef struct {
492b6cee71dSXin LI 	const char *pat;
493c2931133SXin LI #if defined(HAVE_NEWLOCALE) && defined(HAVE_USELOCALE) && defined(HAVE_FREELOCALE)
494c2931133SXin LI #define USE_C_LOCALE
495c2931133SXin LI 	locale_t old_lc_ctype;
496c2931133SXin LI 	locale_t c_lc_ctype;
497c2931133SXin LI #endif
498b6cee71dSXin LI 	int rc;
499b6cee71dSXin LI 	regex_t rx;
500b6cee71dSXin LI } file_regex_t;
501b6cee71dSXin LI 
502b6cee71dSXin LI protected int file_regcomp(file_regex_t *, const char *, int);
503b6cee71dSXin LI protected int file_regexec(file_regex_t *, const char *, size_t, regmatch_t *,
504b6cee71dSXin LI     int);
505b6cee71dSXin LI protected void file_regfree(file_regex_t *);
506b6cee71dSXin LI protected void file_regerror(file_regex_t *, int, struct magic_set *);
507b6cee71dSXin LI 
5082c4f1647SXin LI typedef struct {
5092c4f1647SXin LI 	char *buf;
5102c4f1647SXin LI 	uint32_t offset;
5112c4f1647SXin LI } file_pushbuf_t;
5122c4f1647SXin LI 
5132c4f1647SXin LI protected file_pushbuf_t *file_push_buffer(struct magic_set *);
5142c4f1647SXin LI protected char  *file_pop_buffer(struct magic_set *, file_pushbuf_t *);
5152c4f1647SXin LI 
516b6cee71dSXin LI #ifndef COMPILE_ONLY
517b6cee71dSXin LI extern const char *file_names[];
518b6cee71dSXin LI extern const size_t file_nnames;
519b6cee71dSXin LI #endif
520b6cee71dSXin LI 
521b6cee71dSXin LI #ifndef HAVE_STRERROR
522b6cee71dSXin LI extern int sys_nerr;
523b6cee71dSXin LI extern char *sys_errlist[];
524b6cee71dSXin LI #define strerror(e) \
525b6cee71dSXin LI 	(((e) >= 0 && (e) < sys_nerr) ? sys_errlist[(e)] : "Unknown error")
526b6cee71dSXin LI #endif
527b6cee71dSXin LI 
528b6cee71dSXin LI #ifndef HAVE_STRTOUL
529b6cee71dSXin LI #define strtoul(a, b, c)	strtol(a, b, c)
530b6cee71dSXin LI #endif
531b6cee71dSXin LI 
532b6cee71dSXin LI #ifndef HAVE_PREAD
533b6cee71dSXin LI ssize_t pread(int, void *, size_t, off_t);
534b6cee71dSXin LI #endif
535b6cee71dSXin LI #ifndef HAVE_VASPRINTF
536b6cee71dSXin LI int vasprintf(char **, const char *, va_list);
537b6cee71dSXin LI #endif
538b6cee71dSXin LI #ifndef HAVE_ASPRINTF
539b6cee71dSXin LI int asprintf(char **, const char *, ...);
540b6cee71dSXin LI #endif
541b6cee71dSXin LI 
542b6cee71dSXin LI #ifndef HAVE_STRLCPY
543b6cee71dSXin LI size_t strlcpy(char *, const char *, size_t);
544b6cee71dSXin LI #endif
545b6cee71dSXin LI #ifndef HAVE_STRLCAT
546b6cee71dSXin LI size_t strlcat(char *, const char *, size_t);
547b6cee71dSXin LI #endif
548b6cee71dSXin LI #ifndef HAVE_STRCASESTR
549b6cee71dSXin LI char *strcasestr(const char *, const char *);
550b6cee71dSXin LI #endif
551b6cee71dSXin LI #ifndef HAVE_GETLINE
552b6cee71dSXin LI ssize_t getline(char **, size_t *, FILE *);
553b6cee71dSXin LI ssize_t getdelim(char **, size_t *, int, FILE *);
554b6cee71dSXin LI #endif
555b6cee71dSXin LI #ifndef HAVE_CTIME_R
556b6cee71dSXin LI char   *ctime_r(const time_t *, char *);
557b6cee71dSXin LI #endif
558b6cee71dSXin LI #ifndef HAVE_ASCTIME_R
559b6cee71dSXin LI char   *asctime_r(const struct tm *, char *);
560b6cee71dSXin LI #endif
561b6cee71dSXin LI #ifndef HAVE_FMTCHECK
562b6cee71dSXin LI const char *fmtcheck(const char *, const char *)
563b6cee71dSXin LI      __attribute__((__format_arg__(2)));
564b6cee71dSXin LI #endif
565b6cee71dSXin LI 
566b6cee71dSXin LI #if defined(HAVE_MMAP) && defined(HAVE_SYS_MMAN_H) && !defined(QUICK)
567b6cee71dSXin LI #define QUICK
568b6cee71dSXin LI #endif
569b6cee71dSXin LI 
570b6cee71dSXin LI #ifndef O_BINARY
571b6cee71dSXin LI #define O_BINARY	0
572b6cee71dSXin LI #endif
573b6cee71dSXin LI 
574b6cee71dSXin LI #ifndef __cplusplus
575b6cee71dSXin LI #if defined(__GNUC__) && (__GNUC__ >= 3)
576b6cee71dSXin LI #define FILE_RCSID(id) \
577b6cee71dSXin LI static const char rcsid[] __attribute__((__used__)) = id;
578b6cee71dSXin LI #else
579b6cee71dSXin LI #define FILE_RCSID(id) \
580b6cee71dSXin LI static const char *rcsid(const char *p) { \
581b6cee71dSXin LI 	return rcsid(p = id); \
582b6cee71dSXin LI }
583b6cee71dSXin LI #endif
584b6cee71dSXin LI #else
585b6cee71dSXin LI #define FILE_RCSID(id)
586b6cee71dSXin LI #endif
587b6cee71dSXin LI 
588b6cee71dSXin LI #endif /* __file_h__ */
589