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 30898496eeSXin LI * @(#)$File: file.h,v 1.247 2023/07/27 19:40:22 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 392726a701SXin LI 4040427ccaSGordon Tetlow #ifdef HAVE_STDINT_H 412726a701SXin LI #include <stdint.h> 422726a701SXin LI #endif 432726a701SXin LI 442726a701SXin LI #ifdef HAVE_INTTYPES_H 452726a701SXin LI #include <inttypes.h> 462726a701SXin LI #endif 472726a701SXin LI 4840427ccaSGordon Tetlow #ifndef __STDC_LIMIT_MACROS 4940427ccaSGordon Tetlow #define __STDC_LIMIT_MACROS 5040427ccaSGordon Tetlow #endif 5148c779cdSXin LI #ifndef __STDC_FORMAT_MACROS 5248c779cdSXin LI #define __STDC_FORMAT_MACROS 5348c779cdSXin LI #endif 54b6cee71dSXin LI 552726a701SXin LI #ifdef _WIN32 562726a701SXin LI # ifdef PRIu32 572726a701SXin LI # ifdef _WIN64 582726a701SXin LI # define SIZE_T_FORMAT PRIu64 592726a701SXin LI # else 602726a701SXin LI # define SIZE_T_FORMAT PRIu32 612726a701SXin LI # endif 622726a701SXin LI # define INT64_T_FORMAT PRIi64 632726a701SXin LI # define INTMAX_T_FORMAT PRIiMAX 642726a701SXin LI # else 65b6cee71dSXin LI # ifdef _WIN64 66b6cee71dSXin LI # define SIZE_T_FORMAT "I64" 67b6cee71dSXin LI # else 68b6cee71dSXin LI # define SIZE_T_FORMAT "" 69b6cee71dSXin LI # endif 70b6cee71dSXin LI # define INT64_T_FORMAT "I64" 719ce06829SXin LI # define INTMAX_T_FORMAT "I64" 722726a701SXin LI # endif 73b6cee71dSXin LI #else 74b6cee71dSXin LI # define SIZE_T_FORMAT "z" 75b6cee71dSXin LI # define INT64_T_FORMAT "ll" 769ce06829SXin LI # define INTMAX_T_FORMAT "j" 77b6cee71dSXin LI #endif 78b6cee71dSXin LI 79b6cee71dSXin LI #include <stdio.h> /* Include that here, to make sure __P gets defined */ 80b6cee71dSXin LI #include <errno.h> 81b6cee71dSXin LI #include <fcntl.h> /* For open and flags */ 82b6cee71dSXin LI #include <regex.h> 83b6cee71dSXin LI #include <time.h> 84b6cee71dSXin LI #include <sys/types.h> 85c2931133SXin LI #ifndef WIN32 86b6cee71dSXin LI #include <sys/param.h> 87c2931133SXin LI #endif 88b6cee71dSXin LI /* Do this here and now, because struct stat gets re-defined on solaris */ 89b6cee71dSXin LI #include <sys/stat.h> 90b6cee71dSXin LI #include <stdarg.h> 91a4d6d3b8SXin LI #include <locale.h> 92a4d6d3b8SXin LI #if defined(HAVE_XLOCALE_H) 93a4d6d3b8SXin LI #include <xlocale.h> 94a4d6d3b8SXin LI #endif 95b6cee71dSXin LI 96b6cee71dSXin LI #define ENABLE_CONDITIONALS 97b6cee71dSXin LI 98b6cee71dSXin LI #ifndef MAGIC 99b6cee71dSXin LI #define MAGIC "/etc/magic" 100b6cee71dSXin LI #endif 101b6cee71dSXin LI 102b6cee71dSXin LI #if defined(__EMX__) || defined (WIN32) 103b6cee71dSXin LI #define PATHSEP ';' 104b6cee71dSXin LI #else 105b6cee71dSXin LI #define PATHSEP ':' 106b6cee71dSXin LI #endif 107b6cee71dSXin LI 108898496eeSXin LI #define file_private static 109b6cee71dSXin LI 110b6cee71dSXin LI #if HAVE_VISIBILITY && !defined(WIN32) 111898496eeSXin LI #define file_public __attribute__ ((__visibility__("default"))) 112898496eeSXin LI #ifndef file_protected 113898496eeSXin LI #define file_protected __attribute__ ((__visibility__("hidden"))) 114b6cee71dSXin LI #endif 115b6cee71dSXin LI #else 116898496eeSXin LI #define file_public 117898496eeSXin LI #ifndef file_protected 118898496eeSXin LI #define file_protected 119b6cee71dSXin LI #endif 120b6cee71dSXin LI #endif 121b6cee71dSXin LI 122b6cee71dSXin LI #ifndef __arraycount 123b6cee71dSXin LI #define __arraycount(a) (sizeof(a) / sizeof(a[0])) 124b6cee71dSXin LI #endif 125b6cee71dSXin LI 126b6cee71dSXin LI #ifndef __GNUC_PREREQ__ 127b6cee71dSXin LI #ifdef __GNUC__ 128b6cee71dSXin LI #define __GNUC_PREREQ__(x, y) \ 129b6cee71dSXin LI ((__GNUC__ == (x) && __GNUC_MINOR__ >= (y)) || \ 130b6cee71dSXin LI (__GNUC__ > (x))) 131b6cee71dSXin LI #else 132b6cee71dSXin LI #define __GNUC_PREREQ__(x, y) 0 133b6cee71dSXin LI #endif 134b6cee71dSXin LI #endif 135b6cee71dSXin LI 136b6cee71dSXin LI #ifndef __GNUC__ 137b6cee71dSXin LI #ifndef __attribute__ 138b6cee71dSXin LI #define __attribute__(a) 139b6cee71dSXin LI #endif 140b6cee71dSXin LI #endif 141b6cee71dSXin LI 142b6cee71dSXin LI #ifndef MIN 143b6cee71dSXin LI #define MIN(a,b) (((a) < (b)) ? (a) : (b)) 144b6cee71dSXin LI #endif 145b6cee71dSXin LI 146b6cee71dSXin LI #ifndef MAX 147b6cee71dSXin LI #define MAX(a,b) (((a) > (b)) ? (a) : (b)) 148b6cee71dSXin LI #endif 149b6cee71dSXin LI 15043a5ec4eSXin LI #ifndef O_CLOEXEC 15143a5ec4eSXin LI # define O_CLOEXEC 0 15243a5ec4eSXin LI #endif 15343a5ec4eSXin LI 15443a5ec4eSXin LI #ifndef FD_CLOEXEC 15543a5ec4eSXin LI # define FD_CLOEXEC 1 15643a5ec4eSXin LI #endif 15743a5ec4eSXin LI 158898496eeSXin LI 159898496eeSXin LI /* 160898496eeSXin LI * Dec 31, 23:59:59 9999 161898496eeSXin LI * we need to make sure that we don't exceed 9999 because some libc 162898496eeSXin LI * implementations like muslc crash otherwise 163898496eeSXin LI */ 164898496eeSXin LI #define MAX_CTIME CAST(time_t, 0x3afff487cfULL) 165898496eeSXin LI 1662726a701SXin LI #define FILE_BADSIZE CAST(size_t, ~0ul) 167b6cee71dSXin LI #define MAXDESC 64 /* max len of text description/MIME type */ 168b6cee71dSXin LI #define MAXMIME 80 /* max len of text MIME type */ 1692726a701SXin LI #define MAXstring 128 /* max len of "string" types */ 170b6cee71dSXin LI 171b6cee71dSXin LI #define MAGICNO 0xF11E041C 172a2dfb722SXin LI #define VERSIONNO 18 1732726a701SXin LI #define FILE_MAGICSIZE 376 1742726a701SXin LI 1752726a701SXin LI #define FILE_GUID_SIZE sizeof("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX") 176b6cee71dSXin LI 177b6cee71dSXin LI #define FILE_LOAD 0 178b6cee71dSXin LI #define FILE_CHECK 1 179b6cee71dSXin LI #define FILE_COMPILE 2 180b6cee71dSXin LI #define FILE_LIST 3 181b6cee71dSXin LI 182a4d6d3b8SXin LI typedef regex_t file_regex_t; 183a4d6d3b8SXin LI 18458a0f0d0SEitan Adler struct buffer { 18558a0f0d0SEitan Adler int fd; 18658a0f0d0SEitan Adler struct stat st; 18758a0f0d0SEitan Adler const void *fbuf; 18858a0f0d0SEitan Adler size_t flen; 18958a0f0d0SEitan Adler off_t eoff; 19058a0f0d0SEitan Adler void *ebuf; 19158a0f0d0SEitan Adler size_t elen; 19258a0f0d0SEitan Adler }; 19358a0f0d0SEitan Adler 194b6cee71dSXin LI union VALUETYPE { 195b6cee71dSXin LI uint8_t b; 196b6cee71dSXin LI uint16_t h; 197b6cee71dSXin LI uint32_t l; 198b6cee71dSXin LI uint64_t q; 199b6cee71dSXin LI uint8_t hs[2]; /* 2 bytes of a fixed-endian "short" */ 200b6cee71dSXin LI uint8_t hl[4]; /* 4 bytes of a fixed-endian "long" */ 201b6cee71dSXin LI uint8_t hq[8]; /* 8 bytes of a fixed-endian "quad" */ 202b6cee71dSXin LI char s[MAXstring]; /* the search string or regex pattern */ 203b6cee71dSXin LI unsigned char us[MAXstring]; 2042726a701SXin LI uint64_t guid[2]; 205b6cee71dSXin LI float f; 206b6cee71dSXin LI double d; 207b6cee71dSXin LI }; 208b6cee71dSXin LI 209b6cee71dSXin LI struct magic { 210b6cee71dSXin LI /* Word 1 */ 211b6cee71dSXin LI uint16_t cont_level; /* level of ">" */ 212b6cee71dSXin LI uint8_t flag; 213b6cee71dSXin LI #define INDIR 0x01 /* if '(...)' appears */ 214b6cee71dSXin LI #define OFFADD 0x02 /* if '>&' or '>...(&' appears */ 215b6cee71dSXin LI #define INDIROFFADD 0x04 /* if '>&(' appears */ 216b6cee71dSXin LI #define UNSIGNED 0x08 /* comparison is unsigned */ 217b6cee71dSXin LI #define NOSPACE 0x10 /* suppress space character before output */ 218b6cee71dSXin LI #define BINTEST 0x20 /* test is for a binary type (set only 219b6cee71dSXin LI for top-level tests) */ 220b6cee71dSXin LI #define TEXTTEST 0x40 /* for passing to file_softmagic */ 2212726a701SXin LI #define OFFNEGATIVE 0x80 /* relative to the end of file */ 222b6cee71dSXin LI 223b6cee71dSXin LI uint8_t factor; 224b6cee71dSXin LI 225b6cee71dSXin LI /* Word 2 */ 226b6cee71dSXin LI uint8_t reln; /* relation (0=eq, '>'=gt, etc) */ 227b6cee71dSXin LI uint8_t vallen; /* length of string value, if any */ 228b6cee71dSXin LI uint8_t type; /* comparison type (FILE_*) */ 229b6cee71dSXin LI uint8_t in_type; /* type of indirection */ 230b6cee71dSXin LI #define FILE_INVALID 0 231b6cee71dSXin LI #define FILE_BYTE 1 232b6cee71dSXin LI #define FILE_SHORT 2 233b6cee71dSXin LI #define FILE_DEFAULT 3 234b6cee71dSXin LI #define FILE_LONG 4 235b6cee71dSXin LI #define FILE_STRING 5 236b6cee71dSXin LI #define FILE_DATE 6 237b6cee71dSXin LI #define FILE_BESHORT 7 238b6cee71dSXin LI #define FILE_BELONG 8 239b6cee71dSXin LI #define FILE_BEDATE 9 240b6cee71dSXin LI #define FILE_LESHORT 10 241b6cee71dSXin LI #define FILE_LELONG 11 242b6cee71dSXin LI #define FILE_LEDATE 12 243b6cee71dSXin LI #define FILE_PSTRING 13 244b6cee71dSXin LI #define FILE_LDATE 14 245b6cee71dSXin LI #define FILE_BELDATE 15 246b6cee71dSXin LI #define FILE_LELDATE 16 247b6cee71dSXin LI #define FILE_REGEX 17 248b6cee71dSXin LI #define FILE_BESTRING16 18 249b6cee71dSXin LI #define FILE_LESTRING16 19 250b6cee71dSXin LI #define FILE_SEARCH 20 251b6cee71dSXin LI #define FILE_MEDATE 21 252b6cee71dSXin LI #define FILE_MELDATE 22 253b6cee71dSXin LI #define FILE_MELONG 23 254b6cee71dSXin LI #define FILE_QUAD 24 255b6cee71dSXin LI #define FILE_LEQUAD 25 256b6cee71dSXin LI #define FILE_BEQUAD 26 257b6cee71dSXin LI #define FILE_QDATE 27 258b6cee71dSXin LI #define FILE_LEQDATE 28 259b6cee71dSXin LI #define FILE_BEQDATE 29 260b6cee71dSXin LI #define FILE_QLDATE 30 261b6cee71dSXin LI #define FILE_LEQLDATE 31 262b6cee71dSXin LI #define FILE_BEQLDATE 32 263b6cee71dSXin LI #define FILE_FLOAT 33 264b6cee71dSXin LI #define FILE_BEFLOAT 34 265b6cee71dSXin LI #define FILE_LEFLOAT 35 266b6cee71dSXin LI #define FILE_DOUBLE 36 267b6cee71dSXin LI #define FILE_BEDOUBLE 37 268b6cee71dSXin LI #define FILE_LEDOUBLE 38 269b6cee71dSXin LI #define FILE_BEID3 39 270b6cee71dSXin LI #define FILE_LEID3 40 271b6cee71dSXin LI #define FILE_INDIRECT 41 272b6cee71dSXin LI #define FILE_QWDATE 42 273b6cee71dSXin LI #define FILE_LEQWDATE 43 274b6cee71dSXin LI #define FILE_BEQWDATE 44 275b6cee71dSXin LI #define FILE_NAME 45 276b6cee71dSXin LI #define FILE_USE 46 277b6cee71dSXin LI #define FILE_CLEAR 47 2783e41d09dSXin LI #define FILE_DER 48 2792726a701SXin LI #define FILE_GUID 49 2802726a701SXin LI #define FILE_OFFSET 50 28143a5ec4eSXin LI #define FILE_BEVARINT 51 28243a5ec4eSXin LI #define FILE_LEVARINT 52 283a4d6d3b8SXin LI #define FILE_MSDOSDATE 53 284a4d6d3b8SXin LI #define FILE_LEMSDOSDATE 54 285a4d6d3b8SXin LI #define FILE_BEMSDOSDATE 55 286a4d6d3b8SXin LI #define FILE_MSDOSTIME 56 287a4d6d3b8SXin LI #define FILE_LEMSDOSTIME 57 288a4d6d3b8SXin LI #define FILE_BEMSDOSTIME 58 289a2dfb722SXin LI #define FILE_OCTAL 59 290a2dfb722SXin LI #define FILE_NAMES_SIZE 60 /* size of array to contain all names */ 291b6cee71dSXin LI 292b6cee71dSXin LI #define IS_STRING(t) \ 293b6cee71dSXin LI ((t) == FILE_STRING || \ 294b6cee71dSXin LI (t) == FILE_PSTRING || \ 295b6cee71dSXin LI (t) == FILE_BESTRING16 || \ 296b6cee71dSXin LI (t) == FILE_LESTRING16 || \ 297b6cee71dSXin LI (t) == FILE_REGEX || \ 298b6cee71dSXin LI (t) == FILE_SEARCH || \ 2994460e5b0SXin LI (t) == FILE_INDIRECT || \ 300b6cee71dSXin LI (t) == FILE_NAME || \ 301a2dfb722SXin LI (t) == FILE_USE || \ 302a2dfb722SXin LI (t) == FILE_OCTAL) 303b6cee71dSXin LI 304b6cee71dSXin LI #define FILE_FMT_NONE 0 305b6cee71dSXin LI #define FILE_FMT_NUM 1 /* "cduxXi" */ 306b6cee71dSXin LI #define FILE_FMT_STR 2 /* "s" */ 307b6cee71dSXin LI #define FILE_FMT_QUAD 3 /* "ll" */ 308b6cee71dSXin LI #define FILE_FMT_FLOAT 4 /* "eEfFgG" */ 309b6cee71dSXin LI #define FILE_FMT_DOUBLE 5 /* "eEfFgG" */ 310b6cee71dSXin LI 311b6cee71dSXin LI /* Word 3 */ 312b6cee71dSXin LI uint8_t in_op; /* operator for indirection */ 313b6cee71dSXin LI uint8_t mask_op; /* operator for mask */ 314b6cee71dSXin LI #ifdef ENABLE_CONDITIONALS 315b6cee71dSXin LI uint8_t cond; /* conditional type */ 316b6cee71dSXin LI #else 317b6cee71dSXin LI uint8_t dummy; 318b6cee71dSXin LI #endif 319b6cee71dSXin LI uint8_t factor_op; 320b6cee71dSXin LI #define FILE_FACTOR_OP_PLUS '+' 321b6cee71dSXin LI #define FILE_FACTOR_OP_MINUS '-' 322b6cee71dSXin LI #define FILE_FACTOR_OP_TIMES '*' 323b6cee71dSXin LI #define FILE_FACTOR_OP_DIV '/' 324b6cee71dSXin LI #define FILE_FACTOR_OP_NONE '\0' 325b6cee71dSXin LI 326b6cee71dSXin LI #define FILE_OPS "&|^+-*/%" 327b6cee71dSXin LI #define FILE_OPAND 0 328b6cee71dSXin LI #define FILE_OPOR 1 329b6cee71dSXin LI #define FILE_OPXOR 2 330b6cee71dSXin LI #define FILE_OPADD 3 331b6cee71dSXin LI #define FILE_OPMINUS 4 332b6cee71dSXin LI #define FILE_OPMULTIPLY 5 333b6cee71dSXin LI #define FILE_OPDIVIDE 6 334b6cee71dSXin LI #define FILE_OPMODULO 7 335b6cee71dSXin LI #define FILE_OPS_MASK 0x07 /* mask for above ops */ 336b6cee71dSXin LI #define FILE_UNUSED_1 0x08 337b6cee71dSXin LI #define FILE_UNUSED_2 0x10 338a5d223e6SXin LI #define FILE_OPSIGNED 0x20 339b6cee71dSXin LI #define FILE_OPINVERSE 0x40 340b6cee71dSXin LI #define FILE_OPINDIRECT 0x80 341b6cee71dSXin LI 342b6cee71dSXin LI #ifdef ENABLE_CONDITIONALS 343b6cee71dSXin LI #define COND_NONE 0 344b6cee71dSXin LI #define COND_IF 1 345b6cee71dSXin LI #define COND_ELIF 2 346b6cee71dSXin LI #define COND_ELSE 3 347b6cee71dSXin LI #endif /* ENABLE_CONDITIONALS */ 348b6cee71dSXin LI 349b6cee71dSXin LI /* Word 4 */ 35058a0f0d0SEitan Adler int32_t offset; /* offset to magic number */ 351b6cee71dSXin LI /* Word 5 */ 352b6cee71dSXin LI int32_t in_offset; /* offset from indirection */ 353b6cee71dSXin LI /* Word 6 */ 354b6cee71dSXin LI uint32_t lineno; /* line number in magic file */ 355b6cee71dSXin LI /* Word 7,8 */ 356b6cee71dSXin LI union { 357b6cee71dSXin LI uint64_t _mask; /* for use with numeric and date types */ 358b6cee71dSXin LI struct { 359b6cee71dSXin LI uint32_t _count; /* repeat/line count */ 360b6cee71dSXin LI uint32_t _flags; /* modifier flags */ 361b6cee71dSXin LI } _s; /* for use with string types */ 362b6cee71dSXin LI } _u; 363b6cee71dSXin LI #define num_mask _u._mask 364b6cee71dSXin LI #define str_range _u._s._count 365b6cee71dSXin LI #define str_flags _u._s._flags 3669ce06829SXin LI /* Words 9-24 */ 367b6cee71dSXin LI union VALUETYPE value; /* either number or string */ 3689ce06829SXin LI /* Words 25-40 */ 369b6cee71dSXin LI char desc[MAXDESC]; /* description */ 3709ce06829SXin LI /* Words 41-60 */ 371b6cee71dSXin LI char mimetype[MAXMIME]; /* MIME type */ 3729ce06829SXin LI /* Words 61-62 */ 3735f0216bdSXin LI char apple[8]; /* APPLE CREATOR/TYPE */ 3749ce06829SXin LI /* Words 63-78 */ 3755f0216bdSXin LI char ext[64]; /* Popular extensions */ 376b6cee71dSXin LI }; 377b6cee71dSXin LI 378b6cee71dSXin LI #define BIT(A) (1 << (A)) 379b6cee71dSXin LI #define STRING_COMPACT_WHITESPACE BIT(0) 380b6cee71dSXin LI #define STRING_COMPACT_OPTIONAL_WHITESPACE BIT(1) 381b6cee71dSXin LI #define STRING_IGNORE_LOWERCASE BIT(2) 382b6cee71dSXin LI #define STRING_IGNORE_UPPERCASE BIT(3) 383b6cee71dSXin LI #define REGEX_OFFSET_START BIT(4) 384b6cee71dSXin LI #define STRING_TEXTTEST BIT(5) 385b6cee71dSXin LI #define STRING_BINTEST BIT(6) 386b6cee71dSXin LI #define PSTRING_1_BE BIT(7) 387b6cee71dSXin LI #define PSTRING_1_LE BIT(7) 388b6cee71dSXin LI #define PSTRING_2_BE BIT(8) 389b6cee71dSXin LI #define PSTRING_2_LE BIT(9) 390b6cee71dSXin LI #define PSTRING_4_BE BIT(10) 391b6cee71dSXin LI #define PSTRING_4_LE BIT(11) 392b6cee71dSXin LI #define REGEX_LINE_COUNT BIT(11) 393b6cee71dSXin LI #define PSTRING_LEN \ 394b6cee71dSXin LI (PSTRING_1_BE|PSTRING_2_LE|PSTRING_2_BE|PSTRING_4_LE|PSTRING_4_BE) 395b6cee71dSXin LI #define PSTRING_LENGTH_INCLUDES_ITSELF BIT(12) 396b6cee71dSXin LI #define STRING_TRIM BIT(13) 39743a5ec4eSXin LI #define STRING_FULL_WORD BIT(14) 398b6cee71dSXin LI #define CHAR_COMPACT_WHITESPACE 'W' 399b6cee71dSXin LI #define CHAR_COMPACT_OPTIONAL_WHITESPACE 'w' 400b6cee71dSXin LI #define CHAR_IGNORE_LOWERCASE 'c' 401b6cee71dSXin LI #define CHAR_IGNORE_UPPERCASE 'C' 402b6cee71dSXin LI #define CHAR_REGEX_OFFSET_START 's' 403b6cee71dSXin LI #define CHAR_TEXTTEST 't' 404b6cee71dSXin LI #define CHAR_TRIM 'T' 40543a5ec4eSXin LI #define CHAR_FULL_WORD 'f' 406b6cee71dSXin LI #define CHAR_BINTEST 'b' 407b6cee71dSXin LI #define CHAR_PSTRING_1_BE 'B' 408b6cee71dSXin LI #define CHAR_PSTRING_1_LE 'B' 409b6cee71dSXin LI #define CHAR_PSTRING_2_BE 'H' 410b6cee71dSXin LI #define CHAR_PSTRING_2_LE 'h' 411b6cee71dSXin LI #define CHAR_PSTRING_4_BE 'L' 412b6cee71dSXin LI #define CHAR_PSTRING_4_LE 'l' 413b6cee71dSXin LI #define CHAR_PSTRING_LENGTH_INCLUDES_ITSELF 'J' 414b6cee71dSXin LI #define STRING_IGNORE_CASE (STRING_IGNORE_LOWERCASE|STRING_IGNORE_UPPERCASE) 415b6cee71dSXin LI #define STRING_DEFAULT_RANGE 100 416b6cee71dSXin LI 4174460e5b0SXin LI #define INDIRECT_RELATIVE BIT(0) 4184460e5b0SXin LI #define CHAR_INDIRECT_RELATIVE 'r' 419b6cee71dSXin LI 420b6cee71dSXin LI /* list of magic entries */ 421b6cee71dSXin LI struct mlist { 422b6cee71dSXin LI struct magic *magic; /* array of magic entries */ 423a4d6d3b8SXin LI file_regex_t **magic_rxcomp; /* array of compiled regexps */ 424a4d6d3b8SXin LI size_t nmagic; /* number of entries in array */ 425b6cee71dSXin LI void *map; /* internal resources used by entry */ 426b6cee71dSXin LI struct mlist *next, *prev; 427b6cee71dSXin LI }; 428b6cee71dSXin LI 429b6cee71dSXin LI #ifdef __cplusplus 430b6cee71dSXin LI #define CAST(T, b) static_cast<T>(b) 431b6cee71dSXin LI #define RCAST(T, b) reinterpret_cast<T>(b) 4323e41d09dSXin LI #define CCAST(T, b) const_cast<T>(b) 433b6cee71dSXin LI #else 4343e41d09dSXin LI #define CAST(T, b) ((T)(b)) 43548c779cdSXin LI #define RCAST(T, b) ((T)(uintptr_t)(b)) 4363e41d09dSXin LI #define CCAST(T, b) ((T)(uintptr_t)(b)) 437b6cee71dSXin LI #endif 438b6cee71dSXin LI 439b6cee71dSXin LI struct level_info { 440b6cee71dSXin LI int32_t off; 441b6cee71dSXin LI int got_match; 442b6cee71dSXin LI #ifdef ENABLE_CONDITIONALS 443b6cee71dSXin LI int last_match; 444b6cee71dSXin LI int last_cond; /* used for error checking by parse() */ 445b6cee71dSXin LI #endif 446b6cee71dSXin LI }; 447b6cee71dSXin LI 44843a5ec4eSXin LI struct cont { 44943a5ec4eSXin LI size_t len; 45043a5ec4eSXin LI struct level_info *li; 45143a5ec4eSXin LI }; 45243a5ec4eSXin LI 453b6cee71dSXin LI #define MAGIC_SETS 2 454b6cee71dSXin LI 455b6cee71dSXin LI struct magic_set { 456b6cee71dSXin LI struct mlist *mlist[MAGIC_SETS]; /* list of regular entries */ 45743a5ec4eSXin LI struct cont c; 458b6cee71dSXin LI struct out { 459b6cee71dSXin LI char *buf; /* Accumulation buffer */ 4602726a701SXin LI size_t blen; /* Length of buffer */ 461b6cee71dSXin LI char *pbuf; /* Printable buffer */ 462b6cee71dSXin LI } o; 46358a0f0d0SEitan Adler uint32_t offset; /* a copy of m->offset while we */ 46458a0f0d0SEitan Adler /* are working on the magic entry */ 46558a0f0d0SEitan Adler uint32_t eoffset; /* offset from end of file */ 466b6cee71dSXin LI int error; 467b6cee71dSXin LI int flags; /* Control magic tests. */ 468b6cee71dSXin LI int event_flags; /* Note things that happened. */ 469b6cee71dSXin LI #define EVENT_HAD_ERR 0x01 470b6cee71dSXin LI const char *file; 471b6cee71dSXin LI size_t line; /* current magic line number */ 4722dc4dbb9SEitan Adler mode_t mode; /* copy of current stat mode */ 473b6cee71dSXin LI 474b6cee71dSXin LI /* data for searches */ 475b6cee71dSXin LI struct { 476b6cee71dSXin LI const char *s; /* start of search in original source */ 477b6cee71dSXin LI size_t s_len; /* length of search region */ 478b6cee71dSXin LI size_t offset; /* starting offset in source: XXX - should this be off_t? */ 479b6cee71dSXin LI size_t rm_len; /* match length */ 480b6cee71dSXin LI } search; 481b6cee71dSXin LI 482b6cee71dSXin LI /* FIXME: Make the string dynamically allocated so that e.g. 483b6cee71dSXin LI strings matched in files can be longer than MAXstring */ 484b6cee71dSXin LI union VALUETYPE ms_value; /* either number or string */ 485c2931133SXin LI uint16_t indir_max; 486c2931133SXin LI uint16_t name_max; 487c2931133SXin LI uint16_t elf_shnum_max; 488c2931133SXin LI uint16_t elf_phnum_max; 4894460e5b0SXin LI uint16_t elf_notes_max; 4909ce06829SXin LI uint16_t regex_max; 4913e41d09dSXin LI size_t bytes_max; /* number of bytes to read from file */ 49243a5ec4eSXin LI size_t encoding_max; /* bytes to look for encoding */ 493898496eeSXin LI size_t elf_shsize_max; 4942726a701SXin LI #ifndef FILE_BYTES_MAX 495898496eeSXin LI # define FILE_BYTES_MAX (7 * 1024 * 1024)/* how much of the file to look at */ 496898496eeSXin LI #endif /* above 0x6ab0f4 map offset for HelveticaNeue.dfont */ 4974460e5b0SXin LI #define FILE_ELF_NOTES_MAX 256 4982726a701SXin LI #define FILE_ELF_PHNUM_MAX 2048 4992726a701SXin LI #define FILE_ELF_SHNUM_MAX 32768 500898496eeSXin LI #define FILE_ELF_SHSIZE_MAX (128 * 1024 * 1024) 5012726a701SXin LI #define FILE_INDIR_MAX 50 5022726a701SXin LI #define FILE_NAME_MAX 50 5039ce06829SXin LI #define FILE_REGEX_MAX 8192 50443a5ec4eSXin LI #define FILE_ENCODING_MAX (64 * 1024) 505a4d6d3b8SXin LI #if defined(HAVE_NEWLOCALE) && defined(HAVE_USELOCALE) && defined(HAVE_FREELOCALE) 506a4d6d3b8SXin LI #define USE_C_LOCALE 507a4d6d3b8SXin LI locale_t c_lc_ctype; 508a4d6d3b8SXin LI #define file_locale_used 509a4d6d3b8SXin LI #else 510a4d6d3b8SXin LI #define file_locale_used __attribute__((__unused__)) 511a4d6d3b8SXin LI #endif 512b6cee71dSXin LI }; 513b6cee71dSXin LI 514b6cee71dSXin LI /* Type for Unicode characters */ 51543a5ec4eSXin LI typedef unsigned long file_unichar_t; 516b6cee71dSXin LI 517b6cee71dSXin LI struct stat; 518b6cee71dSXin LI #define FILE_T_LOCAL 1 519b6cee71dSXin LI #define FILE_T_WINDOWS 2 520898496eeSXin LI file_protected const char *file_fmtdatetime(char *, size_t, uint64_t, int); 521898496eeSXin LI file_protected const char *file_fmtdate(char *, size_t, uint16_t); 522898496eeSXin LI file_protected const char *file_fmttime(char *, size_t, uint16_t); 523898496eeSXin LI file_protected const char *file_fmtvarint(char *, size_t, const unsigned char *, 524a2dfb722SXin LI int); 525898496eeSXin LI file_protected const char *file_fmtnum(char *, size_t, const char *, int); 526898496eeSXin LI file_protected struct magic_set *file_ms_alloc(int); 527898496eeSXin LI file_protected void file_ms_free(struct magic_set *); 528898496eeSXin LI file_protected int file_default(struct magic_set *, size_t); 529898496eeSXin LI file_protected int file_buffer(struct magic_set *, int, struct stat *, 530898496eeSXin LI const char *, const void *, size_t); 531898496eeSXin LI file_protected int file_fsmagic(struct magic_set *, const char *, 532898496eeSXin LI struct stat *); 533898496eeSXin LI file_protected int file_pipe2file(struct magic_set *, int, const void *, 534898496eeSXin LI size_t); 535898496eeSXin LI file_protected int file_vprintf(struct magic_set *, const char *, va_list) 536b6cee71dSXin LI __attribute__((__format__(__printf__, 2, 0))); 537898496eeSXin LI file_protected int file_separator(struct magic_set *); 538898496eeSXin LI file_protected char *file_copystr(char *, size_t, size_t, const char *); 539898496eeSXin LI file_protected int file_checkfmt(char *, size_t, const char *); 540898496eeSXin LI file_protected size_t file_printedlen(const struct magic_set *); 541898496eeSXin LI file_protected int file_print_guid(char *, size_t, const uint64_t *); 542898496eeSXin LI file_protected int file_parse_guid(const char *, uint64_t *); 543898496eeSXin LI file_protected int file_replace(struct magic_set *, const char *, const char *); 544898496eeSXin LI file_protected int file_printf(struct magic_set *, const char *, ...) 545b6cee71dSXin LI __attribute__((__format__(__printf__, 2, 3))); 546898496eeSXin LI file_protected int file_reset(struct magic_set *, int); 547898496eeSXin LI file_protected int file_tryelf(struct magic_set *, const struct buffer *); 548898496eeSXin LI file_protected int file_trycdf(struct magic_set *, const struct buffer *); 549b6cee71dSXin LI #if HAVE_FORK 550898496eeSXin LI file_protected int file_zmagic(struct magic_set *, const struct buffer *, 55158a0f0d0SEitan Adler const char *); 552b6cee71dSXin LI #endif 553898496eeSXin LI file_protected int file_ascmagic(struct magic_set *, const struct buffer *, 554b6cee71dSXin LI int); 555898496eeSXin LI file_protected int file_ascmagic_with_encoding(struct magic_set *, 55643a5ec4eSXin LI const struct buffer *, file_unichar_t *, size_t, const char *, const char *, int); 557898496eeSXin LI file_protected int file_encoding(struct magic_set *, const struct buffer *, 55843a5ec4eSXin LI file_unichar_t **, size_t *, const char **, const char **, const char **); 559898496eeSXin LI file_protected int file_is_json(struct magic_set *, const struct buffer *); 560898496eeSXin LI file_protected int file_is_csv(struct magic_set *, const struct buffer *, int, 561898496eeSXin LI const char *); 562898496eeSXin LI file_protected int file_is_simh(struct magic_set *, const struct buffer *); 563898496eeSXin LI file_protected int file_is_tar(struct magic_set *, const struct buffer *); 564898496eeSXin LI file_protected int file_softmagic(struct magic_set *, const struct buffer *, 5653e41d09dSXin LI uint16_t *, uint16_t *, int, int); 566898496eeSXin LI file_protected int file_apprentice(struct magic_set *, const char *, int); 567898496eeSXin LI file_protected size_t file_magic_strength(const struct magic *, size_t); 568898496eeSXin LI file_protected int buffer_apprentice(struct magic_set *, struct magic **, 569c2931133SXin LI size_t *, size_t); 570898496eeSXin LI file_protected int file_magicfind(struct magic_set *, const char *, 571898496eeSXin LI struct mlist *); 572898496eeSXin LI file_protected uint64_t file_signextend(struct magic_set *, struct magic *, 573b6cee71dSXin LI uint64_t); 574898496eeSXin LI file_protected uintmax_t file_varint2uintmax_t(const unsigned char *, int, 575b6cee71dSXin LI size_t *); 576898496eeSXin LI 577898496eeSXin LI file_protected void file_badread(struct magic_set *); 578898496eeSXin LI file_protected void file_badseek(struct magic_set *); 579898496eeSXin LI file_protected void file_oomem(struct magic_set *, size_t); 580898496eeSXin LI file_protected void file_error(struct magic_set *, int, const char *, ...) 581898496eeSXin LI __attribute__((__format__(__printf__, 3, 4))); 582898496eeSXin LI file_protected void file_magerror(struct magic_set *, const char *, ...) 583898496eeSXin LI __attribute__((__format__(__printf__, 2, 3))); 584898496eeSXin LI file_protected void file_magwarn(struct magic_set *, const char *, ...) 585898496eeSXin LI __attribute__((__format__(__printf__, 2, 3))); 586898496eeSXin LI file_protected void file_mdump(struct magic *); 587898496eeSXin LI file_protected void file_showstr(FILE *, const char *, size_t); 588898496eeSXin LI file_protected size_t file_mbswidth(struct magic_set *, const char *); 589898496eeSXin LI file_protected const char *file_getbuffer(struct magic_set *); 590898496eeSXin LI file_protected ssize_t sread(int, void *, size_t, int); 591898496eeSXin LI file_protected int file_check_mem(struct magic_set *, unsigned int); 592898496eeSXin LI file_protected int file_looks_utf8(const unsigned char *, size_t, 593898496eeSXin LI file_unichar_t *, size_t *); 594898496eeSXin LI file_protected size_t file_pstring_length_size(struct magic_set *, 5952726a701SXin LI const struct magic *); 596898496eeSXin LI file_protected size_t file_pstring_get_length(struct magic_set *, 5972726a701SXin LI const struct magic *, const char *); 598898496eeSXin LI file_protected char * file_printable(struct magic_set *, char *, size_t, 59943a5ec4eSXin LI const char *, size_t); 600b6cee71dSXin LI #ifdef __EMX__ 601898496eeSXin LI file_protected int file_os2_apptype(struct magic_set *, const char *, 60248c779cdSXin LI const void *, size_t); 603898496eeSXin LI #endif /* __EMX__ */ 604898496eeSXin LI file_protected int file_pipe_closexec(int *); 605898496eeSXin LI file_protected int file_clear_closexec(int); 606898496eeSXin LI file_protected char *file_strtrim(char *); 607898496eeSXin LI 608898496eeSXin LI file_protected void buffer_init(struct buffer *, int, const struct stat *, 609898496eeSXin LI const void *, size_t); 610898496eeSXin LI file_protected void buffer_fini(struct buffer *); 611898496eeSXin LI file_protected int buffer_fill(const struct buffer *); 61258a0f0d0SEitan Adler 613c2931133SXin LI 614b6cee71dSXin LI 615898496eeSXin LI file_protected int file_regcomp(struct magic_set *, file_regex_t *, 616898496eeSXin LI const char *, int); 617898496eeSXin LI file_protected int file_regexec(struct magic_set *, file_regex_t *, 618898496eeSXin LI const char *, size_t, regmatch_t *, int); 619898496eeSXin LI file_protected void file_regfree(file_regex_t *); 620b6cee71dSXin LI 6212c4f1647SXin LI typedef struct { 6222c4f1647SXin LI char *buf; 6232726a701SXin LI size_t blen; 6242c4f1647SXin LI uint32_t offset; 6252c4f1647SXin LI } file_pushbuf_t; 6262c4f1647SXin LI 627898496eeSXin LI file_protected file_pushbuf_t *file_push_buffer(struct magic_set *); 628898496eeSXin LI file_protected char *file_pop_buffer(struct magic_set *, file_pushbuf_t *); 6292c4f1647SXin LI 630b6cee71dSXin LI #ifndef COMPILE_ONLY 631b6cee71dSXin LI extern const char *file_names[]; 632b6cee71dSXin LI extern const size_t file_nnames; 633b6cee71dSXin LI #endif 634b6cee71dSXin LI 635b6cee71dSXin LI #ifndef HAVE_PREAD 636b6cee71dSXin LI ssize_t pread(int, void *, size_t, off_t); 637b6cee71dSXin LI #endif 638b6cee71dSXin LI #ifndef HAVE_VASPRINTF 639b6cee71dSXin LI int vasprintf(char **, const char *, va_list); 640b6cee71dSXin LI #endif 641b6cee71dSXin LI #ifndef HAVE_ASPRINTF 642b6cee71dSXin LI int asprintf(char **, const char *, ...); 643b6cee71dSXin LI #endif 6443e41d09dSXin LI #ifndef HAVE_DPRINTF 6453e41d09dSXin LI int dprintf(int, const char *, ...); 6463e41d09dSXin LI #endif 647b6cee71dSXin LI 648b6cee71dSXin LI #ifndef HAVE_STRLCPY 649b6cee71dSXin LI size_t strlcpy(char *, const char *, size_t); 650b6cee71dSXin LI #endif 651b6cee71dSXin LI #ifndef HAVE_STRLCAT 652b6cee71dSXin LI size_t strlcat(char *, const char *, size_t); 653b6cee71dSXin LI #endif 654b6cee71dSXin LI #ifndef HAVE_STRCASESTR 655b6cee71dSXin LI char *strcasestr(const char *, const char *); 656b6cee71dSXin LI #endif 657b6cee71dSXin LI #ifndef HAVE_GETLINE 658b6cee71dSXin LI ssize_t getline(char **, size_t *, FILE *); 659b6cee71dSXin LI ssize_t getdelim(char **, size_t *, int, FILE *); 660b6cee71dSXin LI #endif 661b6cee71dSXin LI #ifndef HAVE_CTIME_R 662b6cee71dSXin LI char *ctime_r(const time_t *, char *); 663b6cee71dSXin LI #endif 664b6cee71dSXin LI #ifndef HAVE_ASCTIME_R 665b6cee71dSXin LI char *asctime_r(const struct tm *, char *); 666b6cee71dSXin LI #endif 6675f0216bdSXin LI #ifndef HAVE_GMTIME_R 6685f0216bdSXin LI struct tm *gmtime_r(const time_t *, struct tm *); 6695f0216bdSXin LI #endif 6705f0216bdSXin LI #ifndef HAVE_LOCALTIME_R 6715f0216bdSXin LI struct tm *localtime_r(const time_t *, struct tm *); 6725f0216bdSXin LI #endif 673b6cee71dSXin LI #ifndef HAVE_FMTCHECK 674b6cee71dSXin LI const char *fmtcheck(const char *, const char *) 675b6cee71dSXin LI __attribute__((__format_arg__(2))); 676b6cee71dSXin LI #endif 677b6cee71dSXin LI 67858a0f0d0SEitan Adler #ifdef HAVE_LIBSECCOMP 67958a0f0d0SEitan Adler // basic filter 68058a0f0d0SEitan Adler // this mode should not interfere with normal operations 68158a0f0d0SEitan Adler // only some dangerous syscalls are blacklisted 68258a0f0d0SEitan Adler int enable_sandbox_basic(void); 68358a0f0d0SEitan Adler 68458a0f0d0SEitan Adler // enhanced filter 68558a0f0d0SEitan Adler // this mode allows only the necessary syscalls used during normal operation 68658a0f0d0SEitan Adler // extensive testing required !!! 68758a0f0d0SEitan Adler int enable_sandbox_full(void); 68858a0f0d0SEitan Adler #endif 68958a0f0d0SEitan Adler 690898496eeSXin LI file_protected const char *file_getprogname(void); 691898496eeSXin LI file_protected void file_setprogname(const char *); 692898496eeSXin LI file_protected void file_err(int, const char *, ...) 6932dc4dbb9SEitan Adler __attribute__((__format__(__printf__, 2, 3), __noreturn__)); 694898496eeSXin LI file_protected void file_errx(int, const char *, ...) 6952dc4dbb9SEitan Adler __attribute__((__format__(__printf__, 2, 3), __noreturn__)); 696898496eeSXin LI file_protected void file_warn(const char *, ...) 69758a0f0d0SEitan Adler __attribute__((__format__(__printf__, 1, 2))); 698898496eeSXin LI file_protected void file_warnx(const char *, ...) 69958a0f0d0SEitan Adler __attribute__((__format__(__printf__, 1, 2))); 70058a0f0d0SEitan Adler 701b6cee71dSXin LI #if defined(HAVE_MMAP) && defined(HAVE_SYS_MMAN_H) && !defined(QUICK) 702b6cee71dSXin LI #define QUICK 703b6cee71dSXin LI #endif 704b6cee71dSXin LI 705b6cee71dSXin LI #ifndef O_BINARY 706b6cee71dSXin LI #define O_BINARY 0 707b6cee71dSXin LI #endif 70848c779cdSXin LI #ifndef O_NONBLOCK 70948c779cdSXin LI #define O_NONBLOCK 0 71048c779cdSXin LI #endif 711b6cee71dSXin LI 712b6cee71dSXin LI #ifndef __cplusplus 713b6cee71dSXin LI #if defined(__GNUC__) && (__GNUC__ >= 3) 714b6cee71dSXin LI #define FILE_RCSID(id) \ 715b6cee71dSXin LI static const char rcsid[] __attribute__((__used__)) = id; 716b6cee71dSXin LI #else 717b6cee71dSXin LI #define FILE_RCSID(id) \ 718b6cee71dSXin LI static const char *rcsid(const char *p) { \ 719b6cee71dSXin LI return rcsid(p = id); \ 720b6cee71dSXin LI } 721b6cee71dSXin LI #endif 722b6cee71dSXin LI #else 723b6cee71dSXin LI #define FILE_RCSID(id) 724b6cee71dSXin LI #endif 7255f0216bdSXin LI #ifndef __RCSID 7265f0216bdSXin LI #define __RCSID(a) 7275f0216bdSXin LI #endif 728b6cee71dSXin LI 729b6cee71dSXin LI #endif /* __file_h__ */ 730