Update libmagic to openbsd/src@0e59d0d (#5288)
* Update magic implementation from openbsd to 0e59d0d commit * Various refactoring of the original code to use RzUtil primitives instead of the custom implementation * Remove static variables from the original code * Remove Queue, regex_t and use RzList, RzRegex instead * Remove unneeded code from the original implementation * Use RZ_LOG_* macroses instead of the custom logging of the original code * Use rz_endian primitives where appropriate * Use os-specific functions where appropriate * Move magic functions to internal header
This commit is contained in:
parent
d2c2db5f14
commit
4fd6b9c2da
26 changed files with 2994 additions and 6233 deletions
|
|
@ -11,7 +11,7 @@
|
|||
static char *get_filetype(RzBuffer *b) {
|
||||
ut8 buf[4096] = { 0 };
|
||||
char *res = NULL;
|
||||
RzMagic *ck = rz_magic_new(0);
|
||||
RzMagic *ck = rz_magic_new();
|
||||
if (!ck) {
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@ static char *get_filetype(RzBuffer *b) {
|
|||
rz_magic_free(ck);
|
||||
return NULL;
|
||||
}
|
||||
const char *tmp = NULL;
|
||||
char *tmp = NULL;
|
||||
// TODO: dir.magic not honored here
|
||||
char *m = rz_path_system(sys_path, RZ_SDB_MAGIC);
|
||||
if (!m) {
|
||||
|
|
@ -35,6 +35,7 @@ static char *get_filetype(RzBuffer *b) {
|
|||
if (tmp) {
|
||||
res = rz_str_dup(tmp);
|
||||
}
|
||||
free(tmp);
|
||||
rz_magic_free(ck);
|
||||
rz_path_free(sys_path);
|
||||
return res;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@
|
|||
#ifndef RZ_MAGIC_H
|
||||
#define RZ_MAGIC_H
|
||||
|
||||
#include <rz_types.h>
|
||||
#include <rz_util/rz_rbtree.h>
|
||||
#include <rz_util/rz_regex.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
@ -216,95 +217,197 @@ struct mlist {
|
|||
struct mlist *next, *prev;
|
||||
};
|
||||
|
||||
#define RZ_MAGIC_NONE 0x000000 /* No flags */
|
||||
#define RZ_MAGIC_DEBUG 0x000001 /* Turn on debugging */
|
||||
#define RZ_MAGIC_SYMLINK 0x000002 /* Follow symlinks */
|
||||
#define RZ_MAGIC_COMPRESS 0x000004 /* Check inside compressed files */
|
||||
#define RZ_MAGIC_DEVICES 0x000008 /* Look at the contents of devices */
|
||||
#define RZ_MAGIC_MIME_TYPE 0x000010 /* Return only the MIME type */
|
||||
#define RZ_MAGIC_CONTINUE 0x000020 /* Return all matches */
|
||||
#define RZ_MAGIC_CHECK 0x000040 /* Print warnings to stderr */
|
||||
#define RZ_MAGIC_PRESERVE_ATIME 0x000080 /* Restore access time on exit */
|
||||
#define RZ_MAGIC_RAW 0x000100 /* Don't translate unprint chars */
|
||||
#define RZ_MAGIC_ERROR 0x000200 /* Handle ENOENT etc as real errors */
|
||||
#define RZ_MAGIC_MIME_ENCODING 0x000400 /* Return only the MIME encoding */
|
||||
#define RZ_MAGIC_MIME (RZ_MAGIC_MIME_TYPE | RZ_MAGIC_MIME_ENCODING)
|
||||
#define RZ_MAGIC_NO_CHECK_COMPRESS 0x001000 /* Don't check for compressed files */
|
||||
#define RZ_MAGIC_NO_CHECK_TAR 0x002000 /* Don't check for tar files */
|
||||
#define RZ_MAGIC_NO_CHECK_SOFT 0x004000 /* Don't check magic entries */
|
||||
#define RZ_MAGIC_NO_CHECK_APPTYPE 0x008000 /* Don't check application type */
|
||||
#define RZ_MAGIC_NO_CHECK_ELF 0x010000 /* Don't check for elf details */
|
||||
#define RZ_MAGIC_NO_CHECK_ASCII 0x020000 /* Don't check for ascii files */
|
||||
#define RZ_MAGIC_NO_CHECK_TOKENS 0x100000 /* Don't check ascii/tokens */
|
||||
#define MAGIC_STRING_SIZE 31
|
||||
#define MAGIC_STRENGTH_MULTIPLIER 10
|
||||
|
||||
/* Defined for backwards compatibility; do nothing */
|
||||
#define MAGIC_NO_CHECK_FORTRAN 0x000000 /* Don't check ascii/fortran */
|
||||
#define MAGIC_NO_CHECK_TROFF 0x000000 /* Don't check ascii/troff */
|
||||
#define MAGIC_TEST_TEXT 0x1
|
||||
#define MAGIC_TEST_MIME 0x2
|
||||
|
||||
struct rz_magic_set {
|
||||
struct mlist *mlist;
|
||||
struct cont {
|
||||
size_t len;
|
||||
struct level_info {
|
||||
st32 off;
|
||||
int got_match;
|
||||
int last_match;
|
||||
int last_cond; /* used for error checking by parse() */
|
||||
} *li;
|
||||
} c;
|
||||
struct out {
|
||||
char *buf; /* Accumulation buffer */
|
||||
char *pbuf; /* Printable buffer */
|
||||
} o;
|
||||
ut32 offset;
|
||||
int error;
|
||||
int flags;
|
||||
int haderr;
|
||||
const char *file;
|
||||
size_t line; /* current magic line number */
|
||||
/*
|
||||
* to select alternate encoding format
|
||||
*/
|
||||
#define VIS_OCTAL 0x01 /* use octal \ddd format */
|
||||
#define VIS_CSTYLE 0x02 /* use \[nrft0..] where appropriate */
|
||||
|
||||
/* data for searches */
|
||||
struct {
|
||||
const char *s; /* start of search in original source */
|
||||
size_t s_len; /* length of search region */
|
||||
size_t offset; /* starting offset in source: XXX - should this be off_t? */
|
||||
size_t rm_len; /* match length */
|
||||
} search;
|
||||
/*
|
||||
* to alter set of characters encoded (default is to encode all
|
||||
* non-graphic except space, tab, and newline).
|
||||
*/
|
||||
#define VIS_SP 0x04 /* also encode space */
|
||||
#define VIS_TAB 0x08 /* also encode tab */
|
||||
#define VIS_NL 0x10 /* also encode newline */
|
||||
#define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL)
|
||||
#define VIS_SAFE 0x20 /* only encode "unsafe" characters */
|
||||
#define VIS_DQ 0x200 /* backslash-escape double quotes */
|
||||
#define VIS_ALL 0x400 /* encode all characters */
|
||||
|
||||
/* FIXME: Make the string dynamically allocated so that e.g.
|
||||
strings matched in files can be longer than MAXstring */
|
||||
union VALUETYPE ms_value; /* either number or string */
|
||||
/*
|
||||
* other
|
||||
*/
|
||||
#define VIS_NOSLASH 0x40 /* inhibit printing '\' */
|
||||
#define VIS_GLOB 0x100 /* encode glob(3) magics and '#' */
|
||||
|
||||
// Previously global non-constant variables in librz/magic/
|
||||
bool ms_setup_done; ///< True if the members below were initialized.
|
||||
int magic_file_formats[FILE_NAMES_SIZE];
|
||||
const char *magic_file_names[FILE_NAMES_SIZE];
|
||||
size_t maxmagic;
|
||||
enum magic_type {
|
||||
MAGIC_TYPE_NONE = 0,
|
||||
MAGIC_TYPE_BYTE,
|
||||
MAGIC_TYPE_SHORT,
|
||||
MAGIC_TYPE_LONG,
|
||||
MAGIC_TYPE_QUAD,
|
||||
MAGIC_TYPE_UBYTE,
|
||||
MAGIC_TYPE_USHORT,
|
||||
MAGIC_TYPE_ULONG,
|
||||
MAGIC_TYPE_UQUAD,
|
||||
MAGIC_TYPE_FLOAT,
|
||||
MAGIC_TYPE_DOUBLE,
|
||||
MAGIC_TYPE_STRING,
|
||||
MAGIC_TYPE_PSTRING,
|
||||
MAGIC_TYPE_DATE,
|
||||
MAGIC_TYPE_QDATE,
|
||||
MAGIC_TYPE_LDATE,
|
||||
MAGIC_TYPE_QLDATE,
|
||||
MAGIC_TYPE_UDATE,
|
||||
MAGIC_TYPE_UQDATE,
|
||||
MAGIC_TYPE_ULDATE,
|
||||
MAGIC_TYPE_UQLDATE,
|
||||
MAGIC_TYPE_BESHORT,
|
||||
MAGIC_TYPE_BELONG,
|
||||
MAGIC_TYPE_BEQUAD,
|
||||
MAGIC_TYPE_UBESHORT,
|
||||
MAGIC_TYPE_UBELONG,
|
||||
MAGIC_TYPE_UBEQUAD,
|
||||
MAGIC_TYPE_BEFLOAT,
|
||||
MAGIC_TYPE_BEDOUBLE,
|
||||
MAGIC_TYPE_BEDATE,
|
||||
MAGIC_TYPE_BEQDATE,
|
||||
MAGIC_TYPE_BELDATE,
|
||||
MAGIC_TYPE_BEQLDATE,
|
||||
MAGIC_TYPE_UBEDATE,
|
||||
MAGIC_TYPE_UBEQDATE,
|
||||
MAGIC_TYPE_UBELDATE,
|
||||
MAGIC_TYPE_UBEQLDATE,
|
||||
MAGIC_TYPE_BESTRING16,
|
||||
MAGIC_TYPE_LESHORT,
|
||||
MAGIC_TYPE_LELONG,
|
||||
MAGIC_TYPE_LEQUAD,
|
||||
MAGIC_TYPE_ULESHORT,
|
||||
MAGIC_TYPE_ULELONG,
|
||||
MAGIC_TYPE_ULEQUAD,
|
||||
MAGIC_TYPE_LEFLOAT,
|
||||
MAGIC_TYPE_LEDOUBLE,
|
||||
MAGIC_TYPE_LEDATE,
|
||||
MAGIC_TYPE_LEQDATE,
|
||||
MAGIC_TYPE_LELDATE,
|
||||
MAGIC_TYPE_LEQLDATE,
|
||||
MAGIC_TYPE_ULEDATE,
|
||||
MAGIC_TYPE_ULEQDATE,
|
||||
MAGIC_TYPE_ULELDATE,
|
||||
MAGIC_TYPE_ULEQLDATE,
|
||||
MAGIC_TYPE_LESTRING16,
|
||||
MAGIC_TYPE_MELONG,
|
||||
MAGIC_TYPE_MEDATE,
|
||||
MAGIC_TYPE_MELDATE,
|
||||
MAGIC_TYPE_REGEX,
|
||||
MAGIC_TYPE_SEARCH,
|
||||
MAGIC_TYPE_DEFAULT,
|
||||
MAGIC_TYPE_CLEAR,
|
||||
MAGIC_TYPE_NAME,
|
||||
MAGIC_TYPE_USE,
|
||||
};
|
||||
|
||||
#if USE_LIB_MAGIC
|
||||
#define RzMagic struct magic_set
|
||||
#else
|
||||
typedef struct rz_magic_set RzMagic;
|
||||
#endif
|
||||
typedef struct rz_magic_line_t RzMagicLine;
|
||||
typedef struct rz_magic_t RzMagic;
|
||||
|
||||
#ifdef RZ_API
|
||||
RZ_API RzMagic *rz_magic_new(int flags);
|
||||
RZ_API void rz_magic_free(RzMagic *);
|
||||
/**
|
||||
* \brief Represents a single parsed rule from a magic file.
|
||||
*
|
||||
* This structure contains all metadata and matching criteria for a single magic
|
||||
* rule, including its type, operators, matching strength, and any child rules.
|
||||
*/
|
||||
struct rz_magic_line_t {
|
||||
RBNode rb;
|
||||
RzMagic *root;
|
||||
ut32 line;
|
||||
ut32 strength;
|
||||
RzMagicLine *parent;
|
||||
|
||||
RZ_API const char *rz_magic_file(RzMagic *, const char *);
|
||||
RZ_API const char *rz_magic_descriptor(RzMagic *, int);
|
||||
RZ_API const char *rz_magic_buffer(RzMagic *, const ut8 *, size_t);
|
||||
char strength_operator;
|
||||
ut32 strength_value;
|
||||
|
||||
RZ_API const char *rz_magic_error(RzMagic *);
|
||||
RZ_API void rz_magic_setflags(RzMagic *, int);
|
||||
int text;
|
||||
|
||||
RZ_API bool rz_magic_load(RzMagic *, const char *);
|
||||
RZ_API bool rz_magic_load_buffer(RzMagic *, const char *);
|
||||
RZ_API bool rz_magic_compile(RzMagic *, const char *);
|
||||
RZ_API bool rz_magic_check(RzMagic *, const char *);
|
||||
RZ_API int rz_magic_errno(RzMagic *);
|
||||
#endif
|
||||
int64_t offset;
|
||||
int offset_relative;
|
||||
|
||||
char indirect_type;
|
||||
int indirect_relative;
|
||||
int64_t indirect_offset;
|
||||
char indirect_operator;
|
||||
int64_t indirect_operand;
|
||||
|
||||
const char *name;
|
||||
|
||||
enum magic_type type;
|
||||
char *type_string;
|
||||
char type_operator;
|
||||
int64_t type_operand;
|
||||
|
||||
char test_operator;
|
||||
int test_not;
|
||||
const char *test_string;
|
||||
size_t test_string_size;
|
||||
ut64 test_unsigned;
|
||||
int64_t test_signed;
|
||||
double test_double;
|
||||
|
||||
int stringify;
|
||||
char *result;
|
||||
char *mimetype;
|
||||
|
||||
RzList *children;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Container for magic rules and related metadata.
|
||||
*
|
||||
* Holds the path to the magic file(s), RBTree indexes for rule storage and lookup,
|
||||
* and precompiled regex patterns for various data types.
|
||||
*/
|
||||
struct rz_magic_t {
|
||||
char *path;
|
||||
|
||||
RBTree magic_tree;
|
||||
RBTree magic_named_tree;
|
||||
|
||||
int compiled;
|
||||
RzRegex *format_short;
|
||||
RzRegex *format_long;
|
||||
RzRegex *format_quad;
|
||||
RzRegex *format_float;
|
||||
RzRegex *format_string;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Represents the state of magic rules processing.
|
||||
*
|
||||
* This structure stores details about the data being analyzed.
|
||||
* It is used during magic rules evaluation.
|
||||
*/
|
||||
typedef struct rz_magic_state_t {
|
||||
char out[4096];
|
||||
const char *mimetype;
|
||||
int text;
|
||||
const char *base;
|
||||
size_t size;
|
||||
size_t offset;
|
||||
int matched;
|
||||
size_t start;
|
||||
int reverse;
|
||||
} RzMagicState;
|
||||
|
||||
RZ_API RZ_OWN RzMagic *rz_magic_new();
|
||||
RZ_API void rz_magic_free(RZ_NULLABLE RZ_OWN RzMagic *);
|
||||
RZ_API RZ_OWN char *rz_magic_buffer(RZ_NONNULL const RzMagic *, RZ_NONNULL const ut8 *, size_t);
|
||||
RZ_API bool rz_magic_load(RZ_NONNULL RZ_BORROW RzMagic *, RZ_NONNULL const char *);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -312,4 +415,4 @@ RZ_API int rz_magic_errno(RzMagic *);
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif /* _MAGIC_H */
|
||||
#endif
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,815 +0,0 @@
|
|||
/* $OpenBSD: ascmagic.c,v 1.11 2009/10/27 23:59:37 deraadt Exp $ */
|
||||
/*
|
||||
* Copyright (c) Ian F. Darwin 1986-1995.
|
||||
* Software written by Ian F. Darwin and others;
|
||||
* maintained 1995-present by Christos Zoulas and others.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice immediately at the beginning of the file, without modification,
|
||||
* this list of conditions, and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* ASCII magic -- file types that we know based on keywords
|
||||
* that can appear anywhere in the file.
|
||||
*
|
||||
* Extensively modified by Eric Fischer <enf@pobox.com> in July, 2000,
|
||||
* to handle character codes other than ASCII on a unified basis.
|
||||
*
|
||||
* Joerg Wunsch <joerg@freebsd.org> wrote the original support for 8-bit
|
||||
* international characters, now subsumed into this file.
|
||||
*/
|
||||
#include <rz_userconf.h>
|
||||
|
||||
#if !USE_LIB_MAGIC
|
||||
|
||||
#include "file.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <memory.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include "names.h"
|
||||
|
||||
#define MAXLINELEN 300 /* longest sane line length */
|
||||
#define ISSPC(x) ((x) == ' ' || (x) == '\t' || (x) == '\r' || (x) == '\n' || (x) == 0x85 || (x) == '\f')
|
||||
|
||||
static int looks_ascii(const ut8 *, size_t, unichar *, size_t *);
|
||||
static int looks_utf8_with_BOM(const ut8 *, size_t, unichar *,
|
||||
size_t *);
|
||||
int file_looks_utf8(const ut8 *, size_t, unichar *, size_t *);
|
||||
static int looks_ucs16(const ut8 *, size_t, unichar *, size_t *);
|
||||
static int looks_latin1(const ut8 *, size_t, unichar *, size_t *);
|
||||
static int looks_extended(const ut8 *, size_t, unichar *, size_t *);
|
||||
static void from_ebcdic(const ut8 *, size_t, ut8 *);
|
||||
static int ascmatch(const ut8 *, const unichar *, size_t);
|
||||
static ut8 *encode_utf8(ut8 *, size_t, unichar *, size_t);
|
||||
|
||||
int file_ascmagic(RzMagic *ms, const ut8 *buf, size_t nbytes) {
|
||||
return 0;
|
||||
size_t i;
|
||||
ut8 *nbuf = NULL, *utf8_buf = NULL, *utf8_end;
|
||||
unichar *ubuf = NULL;
|
||||
size_t ulen, mlen;
|
||||
const struct names *p;
|
||||
int rv = -1;
|
||||
int mime = ms->flags & RZ_MAGIC_MIME;
|
||||
|
||||
const char *code = NULL;
|
||||
const char *code_mime = NULL;
|
||||
const char *type = NULL;
|
||||
const char *subtype = NULL;
|
||||
const char *subtype_mime = NULL;
|
||||
|
||||
int has_escapes = 0;
|
||||
int has_backspace = 0;
|
||||
int seen_cr = 0;
|
||||
|
||||
int n_crlf = 0;
|
||||
int n_lf = 0;
|
||||
int n_cr = 0;
|
||||
int n_nel = 0;
|
||||
|
||||
size_t last_line_end = (size_t)-1;
|
||||
int has_long_lines = 0;
|
||||
|
||||
/*
|
||||
* Undo the NUL-termination kindly provided by process()
|
||||
* but leave at least one byte to look at
|
||||
*/
|
||||
while (nbytes > 1 && buf[nbytes - 1] == '\0') {
|
||||
nbytes--;
|
||||
}
|
||||
|
||||
if (!(nbuf = calloc(1, (nbytes + 1) * sizeof(nbuf[0])))) {
|
||||
goto done;
|
||||
}
|
||||
if (!(ubuf = calloc(1, (nbytes + 1) * sizeof(ubuf[0])))) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* Then try to determine whether it's any character code we can
|
||||
* identify. Each of these tests, if it succeeds, will leave
|
||||
* the text converted into one-unichar-per-character Unicode in
|
||||
* ubuf, and the number of characters converted in ulen.
|
||||
*/
|
||||
if (looks_ascii(buf, nbytes, ubuf, &ulen)) {
|
||||
code = "ASCII";
|
||||
code_mime = "us-ascii";
|
||||
type = "text";
|
||||
} else if (looks_utf8_with_BOM(buf, nbytes, ubuf, &ulen) > 0) {
|
||||
code = "UTF-8 Unicode (with BOM)";
|
||||
code_mime = "utf-8";
|
||||
type = "text";
|
||||
} else if (file_looks_utf8(buf, nbytes, ubuf, &ulen) > 1) {
|
||||
code = "UTF-8 Unicode";
|
||||
code_mime = "utf-8";
|
||||
type = "text";
|
||||
} else if ((i = looks_ucs16(buf, nbytes, ubuf, &ulen)) != 0) {
|
||||
if (i == 1) {
|
||||
code = "Little-endian UTF-16 Unicode";
|
||||
} else {
|
||||
code = "Big-endian UTF-16 Unicode";
|
||||
}
|
||||
|
||||
type = "character data";
|
||||
code_mime = "utf-16"; /* is this defined? */
|
||||
} else if (looks_latin1(buf, nbytes, ubuf, &ulen)) {
|
||||
if (!memcmp(buf, "\xff\xff\xff\xff", 4)) {
|
||||
// uninitialized memory is not iso-8859!!
|
||||
goto done;
|
||||
}
|
||||
code = "ISO-8859";
|
||||
type = "text";
|
||||
code_mime = "iso-8859-1";
|
||||
} else if (looks_extended(buf, nbytes, ubuf, &ulen)) {
|
||||
code = "Non-ISO extended-ASCII";
|
||||
type = "text";
|
||||
code_mime = "unknown";
|
||||
} else {
|
||||
from_ebcdic(buf, nbytes, nbuf);
|
||||
|
||||
if (looks_ascii(nbuf, nbytes, ubuf, &ulen)) {
|
||||
code = "EBCDIC";
|
||||
type = "character data";
|
||||
code_mime = "ebcdic";
|
||||
} else if (looks_latin1(nbuf, nbytes, ubuf, &ulen)) {
|
||||
code = "International EBCDIC";
|
||||
type = "character data";
|
||||
code_mime = "ebcdic";
|
||||
} else {
|
||||
rv = 0;
|
||||
goto done; /* doesn't look like text at all */
|
||||
}
|
||||
}
|
||||
|
||||
if (nbytes <= 1) {
|
||||
rv = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Convert ubuf to UTF-8 and try text soft magic */
|
||||
/* If original was ASCII or UTF-8, could use nbuf instead of
|
||||
re-converting. */
|
||||
/* malloc size is a conservative overestimate; could be
|
||||
re-converting improved, or at least realloced after
|
||||
re-converting conversion. */
|
||||
mlen = ulen * 6;
|
||||
if (!(utf8_buf = malloc(mlen))) {
|
||||
file_oomem(ms, mlen);
|
||||
goto done;
|
||||
}
|
||||
if (!(utf8_end = encode_utf8(utf8_buf, mlen, ubuf, ulen))) {
|
||||
goto done;
|
||||
}
|
||||
if (file_softmagic(ms, utf8_buf, utf8_end - utf8_buf, TEXTTEST) != 0) {
|
||||
rv = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* look for tokens from names.h - this is expensive! */
|
||||
if ((ms->flags & RZ_MAGIC_NO_CHECK_TOKENS) != 0) {
|
||||
goto subtype_identified;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while (i < ulen) {
|
||||
size_t end;
|
||||
|
||||
/* skip past any leading space */
|
||||
while (i < ulen && ISSPC(ubuf[i])) {
|
||||
i++;
|
||||
}
|
||||
if (i >= ulen) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* find the next whitespace */
|
||||
for (end = i + 1; end < nbytes; end++) {
|
||||
if (ISSPC(ubuf[end])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* compare the word thus isolated against the token list */
|
||||
for (p = names; p < names + NNAMES; p++) {
|
||||
if (ascmatch((const ut8 *)p->name, ubuf + i,
|
||||
end - i)) {
|
||||
subtype = types[p->type].human;
|
||||
subtype_mime = types[p->type].mime;
|
||||
goto subtype_identified;
|
||||
}
|
||||
}
|
||||
|
||||
i = end;
|
||||
}
|
||||
|
||||
subtype_identified:
|
||||
|
||||
/* Now try to discover other details about the file. */
|
||||
for (i = 0; i < ulen; i++) {
|
||||
if (ubuf[i] == '\n') {
|
||||
if (seen_cr) {
|
||||
n_crlf++;
|
||||
} else {
|
||||
n_lf++;
|
||||
}
|
||||
last_line_end = i;
|
||||
} else if (seen_cr) {
|
||||
n_cr++;
|
||||
}
|
||||
|
||||
seen_cr = (ubuf[i] == '\r');
|
||||
if (seen_cr) {
|
||||
last_line_end = i;
|
||||
}
|
||||
|
||||
if (ubuf[i] == 0x85) { /* X3.64/ECMA-43 "next line" character */
|
||||
n_nel++;
|
||||
last_line_end = i;
|
||||
}
|
||||
/* If this line is _longer_ than MAXLINELEN, remember it. */
|
||||
if (i > last_line_end + MAXLINELEN) {
|
||||
has_long_lines = 1;
|
||||
}
|
||||
|
||||
if (ubuf[i] == '\033') {
|
||||
has_escapes = 1;
|
||||
}
|
||||
if (ubuf[i] == '\b') {
|
||||
has_backspace = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Beware, if the data has been truncated, the final CR could have
|
||||
been followed by a LF. If we have HOWMANY bytes, it indicates
|
||||
that the data might have been truncated, probably even before
|
||||
this function was called. */
|
||||
if (seen_cr && nbytes < HOWMANY) {
|
||||
n_cr++;
|
||||
}
|
||||
|
||||
if (mime) {
|
||||
if (mime & RZ_MAGIC_MIME_TYPE) {
|
||||
if (subtype_mime) {
|
||||
if (file_printf(ms, subtype_mime) == -1) {
|
||||
goto done;
|
||||
}
|
||||
} else {
|
||||
if (file_printf(ms, "text/plain") == -1) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((mime == 0 || mime == RZ_MAGIC_MIME) && code_mime) {
|
||||
if ((mime & RZ_MAGIC_MIME_TYPE) &&
|
||||
file_printf(ms, " charset=") == -1) {
|
||||
goto done;
|
||||
}
|
||||
if (file_printf(ms, code_mime) == -1) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (mime == RZ_MAGIC_MIME_ENCODING) {
|
||||
if (file_printf(ms, "binary") == -1) {
|
||||
rv = 1;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (file_printf(ms, code) == -1) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (subtype) {
|
||||
if (file_printf(ms, " ") == -1) {
|
||||
goto done;
|
||||
}
|
||||
if (file_printf(ms, subtype) == -1) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (file_printf(ms, " ") == -1) {
|
||||
goto done;
|
||||
}
|
||||
if (file_printf(ms, type) == -1) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (has_long_lines) {
|
||||
if (file_printf(ms, ", with very long lines") == -1) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Only report line terminators if we find one other than LF,
|
||||
* or if we find none at all.
|
||||
*/
|
||||
if ((n_crlf == 0 && n_cr == 0 && n_nel == 0 && n_lf == 0) ||
|
||||
(n_crlf != 0 || n_cr != 0 || n_nel != 0)) {
|
||||
if (file_printf(ms, ", with") == -1) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (n_crlf == 0 && n_cr == 0 && n_nel == 0 && n_lf == 0) {
|
||||
if (file_printf(ms, " no") == -1) {
|
||||
goto done;
|
||||
}
|
||||
} else {
|
||||
if (n_crlf) {
|
||||
if (file_printf(ms, " CRLF") == -1) {
|
||||
goto done;
|
||||
}
|
||||
if (n_cr || n_lf || n_nel) {
|
||||
if (file_printf(ms, ",") == -1) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (n_cr) {
|
||||
if (file_printf(ms, " CR") == -1) {
|
||||
goto done;
|
||||
}
|
||||
if (n_lf || n_nel) {
|
||||
if (file_printf(ms, ",") == -1) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (n_lf) {
|
||||
if (file_printf(ms, " LF") == -1) {
|
||||
goto done;
|
||||
}
|
||||
if (n_nel) {
|
||||
if (file_printf(ms, ",") == -1) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (n_nel) {
|
||||
if (file_printf(ms, " NEL") == -1) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (file_printf(ms, " line terminators") == -1) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (has_escapes) {
|
||||
if (file_printf(ms, ", with escape sequences") == -1) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if (has_backspace) {
|
||||
if (file_printf(ms, ", with overstriking") == -1) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
rv = 1;
|
||||
done:
|
||||
free(nbuf);
|
||||
free(ubuf);
|
||||
free(utf8_buf);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int ascmatch(const ut8 *s, const unichar *us, size_t ulen) {
|
||||
size_t i;
|
||||
for (i = 0; i < ulen; i++) {
|
||||
if (s[i] != us[i]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return s[i] ? 0 : 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* This table reflects a particular philosophy about what constitutes
|
||||
* "text," and there is room for disagreement about it.
|
||||
*
|
||||
* Version 3.31 of the file command considered a file to be ASCII if
|
||||
* each of its characters was approved by either the isascii() or
|
||||
* isalpha() function. On most systems, this would mean that any
|
||||
* file consisting only of characters in the range 0x00 ... 0x7F
|
||||
* would be called ASCII text, but many systems might reasonably
|
||||
* consider some characters outside this range to be alphabetic,
|
||||
* so the file command would call such characters ASCII. It might
|
||||
* have been more accurate to call this "considered textual on the
|
||||
* local system" than "ASCII."
|
||||
*
|
||||
* It considered a file to be "International language text" if each
|
||||
* of its characters was either an ASCII printing character (according
|
||||
* to the real ASCII standard, not the above test), a character in
|
||||
* the range 0x80 ... 0xFF, or one of the following control characters:
|
||||
* backspace, tab, line feed, vertical tab, form feed, carriage return,
|
||||
* escape. No attempt was made to determine the language in which files
|
||||
* of this type were written.
|
||||
*
|
||||
*
|
||||
* The table below considers a file to be ASCII if all of its characters
|
||||
* are either ASCII printing characters (again, according to the X3.4
|
||||
* standard, not isascii()) or any of the following controls: bell,
|
||||
* backspace, tab, line feed, form feed, carriage return, esc, nextline.
|
||||
*
|
||||
* I include bell because some programs (particularly shell scripts)
|
||||
* use it literally, even though it is rare in normal text. I exclude
|
||||
* vertical tab because it never seems to be used in real text. I also
|
||||
* include, with hesitation, the X3.64/ECMA-43 control nextline (0x85),
|
||||
* because that's what the dd EBCDIC->ASCII table maps the EBCDIC newline
|
||||
* character to. It might be more appropriate to include it in the 8859
|
||||
* set instead of the ASCII set, but it's got to be included in *something*
|
||||
* we recognize or EBCDIC files aren't going to be considered textual.
|
||||
* Some old Unix source files use SO/SI (^N/^O) to shift between Greek
|
||||
* and Latin characters, so these should possibly be allowed. But they
|
||||
* make a real mess on VT100-style displays if they're not paired properly,
|
||||
* so we are probably better off not calling them text.
|
||||
*
|
||||
* A file is considered to be ISO-8859 text if its characters are all
|
||||
* either ASCII, according to the above definition, or printing characters
|
||||
* from the ISO-8859 8-bit extension, characters 0xA0 ... 0xFF.
|
||||
*
|
||||
* Finally, a file is considered to be international text from some other
|
||||
* character code if its characters are all either ISO-8859 (according to
|
||||
* the above definition) or characters in the range 0x80 ... 0x9F, which
|
||||
* ISO-8859 considers to be control characters but the IBM PC and Macintosh
|
||||
* consider to be printing characters.
|
||||
*/
|
||||
|
||||
#define F 0 /* character never appears in text */
|
||||
#define T 1 /* character appears in plain ASCII text */
|
||||
#define I 2 /* character appears in ISO-8859 text */
|
||||
#define X 3 /* character appears in non-ISO extended ASCII (Mac, IBM PC) */
|
||||
|
||||
static char text_chars[256] = {
|
||||
/* BEL BS HT LF FF CR */
|
||||
F, F, F, F, F, F, F, T, T, T, T, F, T, T, F, F, /* 0x0X */
|
||||
/* ESC */
|
||||
F, F, F, F, F, F, F, F, F, F, F, T, F, F, F, F, /* 0x1X */
|
||||
T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x2X */
|
||||
T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x3X */
|
||||
T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x4X */
|
||||
T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x5X */
|
||||
T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x6X */
|
||||
T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, F, /* 0x7X */
|
||||
/* NEL */
|
||||
X, X, X, X, X, T, X, X, X, X, X, X, X, X, X, X, /* 0x8X */
|
||||
X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, /* 0x9X */
|
||||
I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xaX */
|
||||
I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xbX */
|
||||
I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xcX */
|
||||
I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xdX */
|
||||
I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xeX */
|
||||
I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I /* 0xfX */
|
||||
};
|
||||
|
||||
static int looks_ascii(const ut8 *buf, size_t nbytes, unichar *ubuf, size_t *ulen) {
|
||||
size_t i;
|
||||
*ulen = 0;
|
||||
for (i = 0; i < nbytes; i++) {
|
||||
int t = text_chars[buf[i]];
|
||||
if (t != T) {
|
||||
return 0;
|
||||
}
|
||||
ubuf[(*ulen)++] = buf[i];
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int looks_latin1(const ut8 *buf, size_t nbytes, unichar *ubuf, size_t *ulen) {
|
||||
size_t i;
|
||||
*ulen = 0;
|
||||
|
||||
for (i = 0; i < nbytes; i++) {
|
||||
int t = text_chars[buf[i]];
|
||||
if (t != T && t != I) {
|
||||
return 0;
|
||||
}
|
||||
ubuf[(*ulen)++] = buf[i];
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int looks_extended(const ut8 *buf, size_t nbytes, unichar *ubuf, size_t *ulen) {
|
||||
size_t i;
|
||||
*ulen = 0;
|
||||
for (i = 0; i < nbytes; i++) {
|
||||
int t = text_chars[buf[i]];
|
||||
if (t != T && t != I && t != X) {
|
||||
return 0;
|
||||
}
|
||||
ubuf[(*ulen)++] = buf[i];
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Encode Unicode string as UTF-8, returning pointer to character
|
||||
* after end of string, or NULL if an invalid character is found.
|
||||
*/
|
||||
static ut8 *
|
||||
encode_utf8(ut8 *buf, size_t len, unichar *ubuf, size_t ulen) {
|
||||
size_t i;
|
||||
ut8 *end = buf + len;
|
||||
|
||||
for (i = 0; i < ulen; i++) {
|
||||
if (ubuf[i] <= 0x7f) {
|
||||
if (end - buf < 1) {
|
||||
return NULL;
|
||||
}
|
||||
*buf++ = (ut8)ubuf[i];
|
||||
} else if (ubuf[i] <= 0x7ff) {
|
||||
if (end - buf < 2) {
|
||||
return NULL;
|
||||
}
|
||||
*buf++ = (ut8)((ubuf[i] >> 6) + 0xc0);
|
||||
*buf++ = (ut8)((ubuf[i] & 0x3f) + 0x80);
|
||||
} else if (ubuf[i] <= 0xffff) {
|
||||
if (end - buf < 3) {
|
||||
return NULL;
|
||||
}
|
||||
*buf++ = (ut8)((ubuf[i] >> 12) + 0xe0);
|
||||
*buf++ = (ut8)(((ubuf[i] >> 6) & 0x3f) + 0x80);
|
||||
*buf++ = (ut8)((ubuf[i] & 0x3f) + 0x80);
|
||||
} else if (ubuf[i] <= 0x1fffff) {
|
||||
if (end - buf < 4) {
|
||||
return NULL;
|
||||
}
|
||||
*buf++ = (ut8)((ubuf[i] >> 18) + 0xf0);
|
||||
*buf++ = (ut8)(((ubuf[i] >> 12) & 0x3f) + 0x80);
|
||||
*buf++ = (ut8)(((ubuf[i] >> 6) & 0x3f) + 0x80);
|
||||
*buf++ = (ut8)((ubuf[i] & 0x3f) + 0x80);
|
||||
} else if (ubuf[i] <= 0x3ffffff) {
|
||||
if (end - buf < 5) {
|
||||
return NULL;
|
||||
}
|
||||
*buf++ = (ut8)((ubuf[i] >> 24) + 0xf8);
|
||||
*buf++ = (ut8)(((ubuf[i] >> 18) & 0x3f) + 0x80);
|
||||
*buf++ = (ut8)(((ubuf[i] >> 12) & 0x3f) + 0x80);
|
||||
*buf++ = (ut8)(((ubuf[i] >> 6) & 0x3f) + 0x80);
|
||||
*buf++ = (ut8)((ubuf[i] & 0x3f) + 0x80);
|
||||
} else if (ubuf[i] <= 0x7fffffff) {
|
||||
if (end - buf < 6) {
|
||||
return NULL;
|
||||
}
|
||||
*buf++ = (ut8)((ubuf[i] >> 30) + 0xfc);
|
||||
*buf++ = (ut8)(((ubuf[i] >> 24) & 0x3f) + 0x80);
|
||||
*buf++ = (ut8)(((ubuf[i] >> 18) & 0x3f) + 0x80);
|
||||
*buf++ = (ut8)(((ubuf[i] >> 12) & 0x3f) + 0x80);
|
||||
*buf++ = (ut8)(((ubuf[i] >> 6) & 0x3f) + 0x80);
|
||||
*buf++ = (ut8)((ubuf[i] & 0x3f) + 0x80);
|
||||
} else { /* Invalid character */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decide whether some text looks like UTF-8. Returns:
|
||||
*
|
||||
* -1: invalid UTF-8
|
||||
* 0: uses odd control characters, so doesn't look like text
|
||||
* 1: 7-bit text
|
||||
* 2: definitely UTF-8 text (valid high-bit set bytes)
|
||||
*
|
||||
* If ubuf is non-NULL on entry, text is decoded into ubuf, *ulen;
|
||||
* ubuf must be big enough!
|
||||
*/
|
||||
int file_looks_utf8(const ut8 *buf, size_t nbytes, unichar *ubuf, size_t *ulen) {
|
||||
size_t i;
|
||||
int n;
|
||||
unichar c;
|
||||
int gotone = 0, ctrl = 0;
|
||||
|
||||
if (ubuf) {
|
||||
*ulen = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < nbytes; i++) {
|
||||
if ((buf[i] & 0x80) == 0) { /* 0xxxxxxx is plain ASCII */
|
||||
/*
|
||||
* Even if the whole file is valid UTF-8 sequences,
|
||||
* still reject it if it uses weird control characters.
|
||||
*/
|
||||
|
||||
if (text_chars[buf[i]] != T) {
|
||||
ctrl = 1;
|
||||
}
|
||||
|
||||
if (ubuf) {
|
||||
ubuf[(*ulen)++] = buf[i];
|
||||
}
|
||||
} else if ((buf[i] & 0x40) == 0) { /* 10xxxxxx never 1st byte */
|
||||
return -1;
|
||||
} else { /* 11xxxxxx begins UTF-8 */
|
||||
int following;
|
||||
|
||||
if ((buf[i] & 0x20) == 0) { /* 110xxxxx */
|
||||
c = buf[i] & 0x1f;
|
||||
following = 1;
|
||||
} else if ((buf[i] & 0x10) == 0) { /* 1110xxxx */
|
||||
c = buf[i] & 0x0f;
|
||||
following = 2;
|
||||
} else if ((buf[i] & 0x08) == 0) { /* 11110xxx */
|
||||
c = buf[i] & 0x07;
|
||||
following = 3;
|
||||
} else if ((buf[i] & 0x04) == 0) { /* 111110xx */
|
||||
c = buf[i] & 0x03;
|
||||
following = 4;
|
||||
} else if ((buf[i] & 0x02) == 0) { /* 1111110x */
|
||||
c = buf[i] & 0x01;
|
||||
following = 5;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (n = 0; n < following; n++) {
|
||||
i++;
|
||||
if (i >= nbytes) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((buf[i] & 0x80) == 0 || (buf[i] & 0x40)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
c = (c << 6) + (buf[i] & 0x3f);
|
||||
}
|
||||
|
||||
if (ubuf) {
|
||||
ubuf[(*ulen)++] = c;
|
||||
}
|
||||
gotone = 1;
|
||||
}
|
||||
}
|
||||
done:
|
||||
return ctrl ? 0 : (gotone ? 2 : 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Decide whether some text looks like UTF-8 with BOM. If there is no
|
||||
* BOM, return -1; otherwise return the result of looks_utf8 on the
|
||||
* rest of the text.
|
||||
*/
|
||||
static int looks_utf8_with_BOM(const ut8 *buf, size_t nbytes, unichar *ubuf, size_t *ulen) {
|
||||
if (nbytes > 3 && buf[0] == 0xef && buf[1] == 0xbb && buf[2] == 0xbf) {
|
||||
return file_looks_utf8(buf + 3, nbytes - 3, ubuf, ulen);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int looks_ucs16(const ut8 *buf, size_t nbytes, unichar *ubuf, size_t *ulen) {
|
||||
int bigend;
|
||||
size_t i;
|
||||
|
||||
if (nbytes < 2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (buf[0] == 0xff && buf[1] == 0xfe) {
|
||||
bigend = 0;
|
||||
} else if (buf[0] == 0xfe && buf[1] == 0xff) {
|
||||
bigend = 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*ulen = 0;
|
||||
|
||||
for (i = 2; i + 1 < nbytes; i += 2) {
|
||||
/* XXX fix to properly handle chars > 65536 */
|
||||
|
||||
if (bigend) {
|
||||
ubuf[(*ulen)++] = buf[i + 1] + 256 * buf[i];
|
||||
} else {
|
||||
ubuf[(*ulen)++] = buf[i] + 256 * buf[i + 1];
|
||||
}
|
||||
|
||||
if (ubuf[*ulen - 1] == 0xfffe) {
|
||||
return 0;
|
||||
}
|
||||
if (ubuf[*ulen - 1] < 128 && text_chars[(size_t)ubuf[*ulen - 1]] != T) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1 + bigend;
|
||||
}
|
||||
|
||||
#undef F
|
||||
#undef T
|
||||
#undef I
|
||||
#undef X
|
||||
|
||||
/*
|
||||
* This table maps each EBCDIC character to an (8-bit extended) ASCII
|
||||
* character, as specified in the rationale for the dd(1) command in
|
||||
* draft 11.2 (September, 1991) of the POSIX P1003.2 standard.
|
||||
*
|
||||
* Unfortunately it does not seem to correspond exactly to any of the
|
||||
* five variants of EBCDIC documented in IBM's _Enterprise Systems
|
||||
* Architecture/390: Principles of Operation_, SA22-7201-06, Seventh
|
||||
* Edition, July, 1999, pp. I-1 - I-4.
|
||||
*
|
||||
* Fortunately, though, all versions of EBCDIC, including this one, agree
|
||||
* on most of the printing characters that also appear in (7-bit) ASCII.
|
||||
* Of these, only '|', '!', '~', '^', '[', and ']' are in question at all.
|
||||
*
|
||||
* Fortunately too, there is general agreement that codes 0x00 through
|
||||
* 0x3F represent control characters, 0x41 a nonbreaking space, and the
|
||||
* remainder printing characters.
|
||||
*
|
||||
* This is sufficient to allow us to identify EBCDIC text and to distinguish
|
||||
* between old-style and internationalized examples of text.
|
||||
*/
|
||||
|
||||
static ut8 ebcdic_to_ascii[] = {
|
||||
0, 1, 2, 3, 156, 9, 134, 127, 151, 141, 142, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 157, 133, 8, 135, 24, 25, 146, 143, 28, 29, 30, 31,
|
||||
128, 129, 130, 131, 132, 10, 23, 27, 136, 137, 138, 139, 140, 5, 6, 7,
|
||||
144, 145, 22, 147, 148, 149, 150, 4, 152, 153, 154, 155, 20, 21, 158, 26,
|
||||
' ', 160, 161, 162, 163, 164, 165, 166, 167, 168, 213, '.', '<', '(', '+', '|',
|
||||
'&', 169, 170, 171, 172, 173, 174, 175, 176, 177, '!', '$', '*', ')', ';', '~',
|
||||
'-', '/', 178, 179, 180, 181, 182, 183, 184, 185, 203, ',', '%', '_', '>', '?',
|
||||
186, 187, 188, 189, 190, 191, 192, 193, 194, '`', ':', '#', '@', '\'', '=', '"',
|
||||
195, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 196, 197, 198, 199, 200, 201,
|
||||
202, 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', '^', 204, 205, 206, 207, 208,
|
||||
209, 229, 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 210, 211, 212, '[', 214, 215,
|
||||
216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, ']', 230, 231,
|
||||
'{', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 232, 233, 234, 235, 236, 237,
|
||||
'}', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 238, 239, 240, 241, 242, 243,
|
||||
'\\', 159, 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 244, 245, 246, 247, 248, 249,
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 250, 251, 252, 253, 254, 255
|
||||
};
|
||||
|
||||
#ifdef notdef
|
||||
/*
|
||||
* The following EBCDIC-to-ASCII table may relate more closely to reality,
|
||||
* or at least to modern reality. It comes from
|
||||
*
|
||||
* http://ftp.s390.ibm.com/products/oe/bpxqp9.html
|
||||
*
|
||||
* and maps the characters of EBCDIC code page 1047 (the code used for
|
||||
* Unix-derived software on IBM's 390 systems) to the corresponding
|
||||
* characters from ISO 8859-1.
|
||||
*
|
||||
* If this table is used instead of the above one, some of the special
|
||||
* cases for the NEL character can be taken out of the code.
|
||||
*/
|
||||
|
||||
static ut8 ebcdic_1047_to_8859[] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x9C, 0x09, 0x86, 0x7F, 0x97, 0x8D, 0x8E, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x9D, 0x0A, 0x08, 0x87, 0x18, 0x19, 0x92, 0x8F, 0x1C, 0x1D, 0x1E, 0x1F,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x17, 0x1B, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x05, 0x06, 0x07,
|
||||
0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, 0x98, 0x99, 0x9A, 0x9B, 0x14, 0x15, 0x9E, 0x1A,
|
||||
0x20, 0xA0, 0xE2, 0xE4, 0xE0, 0xE1, 0xE3, 0xE5, 0xE7, 0xF1, 0xA2, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
|
||||
0x26, 0xE9, 0xEA, 0xEB, 0xE8, 0xED, 0xEE, 0xEF, 0xEC, 0xDF, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0x5E,
|
||||
0x2D, 0x2F, 0xC2, 0xC4, 0xC0, 0xC1, 0xC3, 0xC5, 0xC7, 0xD1, 0xA6, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
|
||||
0xF8, 0xC9, 0xCA, 0xCB, 0xC8, 0xCD, 0xCE, 0xCF, 0xCC, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
|
||||
0xD8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0xAB, 0xBB, 0xF0, 0xFD, 0xFE, 0xB1,
|
||||
0xB0, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0xAA, 0xBA, 0xE6, 0xB8, 0xC6, 0xA4,
|
||||
0xB5, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0xA1, 0xBF, 0xD0, 0x5B, 0xDE, 0xAE,
|
||||
0xAC, 0xA3, 0xA5, 0xB7, 0xA9, 0xA7, 0xB6, 0xBC, 0xBD, 0xBE, 0xDD, 0xA8, 0xAF, 0x5D, 0xB4, 0xD7,
|
||||
0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0xAD, 0xF4, 0xF6, 0xF2, 0xF3, 0xF5,
|
||||
0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0xB9, 0xFB, 0xFC, 0xF9, 0xFA, 0xFF,
|
||||
0x5C, 0xF7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0xB2, 0xD4, 0xD6, 0xD2, 0xD3, 0xD5,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0xB3, 0xDB, 0xDC, 0xD9, 0xDA, 0x9F
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copy buf[0 ... nbytes-1] into out[], translating EBCDIC to ASCII.
|
||||
*/
|
||||
static void from_ebcdic(const ut8 *buf, size_t nbytes, ut8 *out) {
|
||||
size_t i;
|
||||
for (i = 0; i < nbytes; i++) {
|
||||
out[i] = ebcdic_to_ascii[buf[i]];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1 +1 @@
|
|||
0 regex \^[0-9]*\.[0-9]*\.[0-9]*\.[0-9] IP Address: %s
|
||||
0 regex ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$ IP Address: %s
|
||||
|
|
|
|||
|
|
@ -1,93 +0,0 @@
|
|||
/* $OpenBSD: file.h,v 1.22 2009/10/27 23:59:37 deraadt Exp $ */
|
||||
/*
|
||||
* Copyright (c) Ian F. Darwin 1986-1995.
|
||||
* Software written by Ian F. Darwin and others;
|
||||
* maintained 1995-present by Christos Zoulas and others.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice immediately at the beginning of the file, without modification,
|
||||
* this list of conditions, and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* file.h - definitions for file(1) program
|
||||
* @(#)$Id: file.h,v 1.22 2009/10/27 23:59:37 deraadt Exp $
|
||||
*/
|
||||
|
||||
#ifndef __file_h__
|
||||
#define __file_h__
|
||||
|
||||
#include "mconfig.h"
|
||||
#include <rz_magic.h>
|
||||
|
||||
#include <stdio.h> /* Include that here, to make sure __P gets defined */
|
||||
#include <errno.h>
|
||||
#include <fcntl.h> /* For open and flags */
|
||||
#include <inttypes.h> // TODO: use utX
|
||||
#include <rz_util/rz_regex.h>
|
||||
#include <sys/types.h>
|
||||
/* Do this here and now, because struct stat gets re-defined on solaris */
|
||||
#include <sys/stat.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/* Type for Unicode characters */
|
||||
typedef unsigned long unichar;
|
||||
|
||||
struct stat;
|
||||
const char *file_fmttime(unsigned int, int, char *);
|
||||
int file_buffer(RzMagic *ms, int fd, const char *inname, const ut8 *buf, size_t nb);
|
||||
int file_fsmagic(struct rz_magic_set *, const char *, struct stat *);
|
||||
int file_pipe2file(struct rz_magic_set *, int, const void *, size_t);
|
||||
int file_printf(struct rz_magic_set *, const char *, ...);
|
||||
int file_reset(struct rz_magic_set *);
|
||||
int file_tryelf(struct rz_magic_set *, int, const unsigned char *, size_t);
|
||||
int file_zmagic(struct rz_magic_set *, int, const char *, const ut8 *, size_t);
|
||||
int file_ascmagic(struct rz_magic_set *, const unsigned char *, size_t);
|
||||
int file_is_tar(struct rz_magic_set *, const unsigned char *, size_t);
|
||||
int file_softmagic(struct rz_magic_set *, const unsigned char *, size_t, int);
|
||||
struct mlist *file_apprentice(struct rz_magic_set *, const char *, int);
|
||||
ut64 file_signextend(RzMagic *, struct rz_magic *, ut64);
|
||||
void file_delmagic(struct rz_magic *, int type, size_t entries);
|
||||
void file_badread(struct rz_magic_set *);
|
||||
void file_badseek(struct rz_magic_set *);
|
||||
void file_oomem(struct rz_magic_set *, size_t);
|
||||
void file_error(struct rz_magic_set *, int, const char *, ...);
|
||||
void file_magerror(struct rz_magic_set *, const char *, ...);
|
||||
void file_magwarn(struct rz_magic_set *, const char *, ...);
|
||||
void file_mdump(struct rz_magic_set *ms, struct rz_magic *m);
|
||||
void file_showstr(FILE *, const char *, size_t);
|
||||
size_t file_mbswidth(const char *);
|
||||
const char *file_getbuffer(struct rz_magic_set *);
|
||||
ssize_t sread(int, void *, size_t, int);
|
||||
int file_check_mem(struct rz_magic_set *, unsigned int);
|
||||
int file_looks_utf8(const unsigned char *, size_t, unichar *, size_t *);
|
||||
|
||||
#ifndef HAVE_VASPRINTF
|
||||
int vasprintf(char **ptr, const char *format_string, va_list vargs);
|
||||
#endif
|
||||
#ifndef HAVE_ASPRINTF
|
||||
int asprintf(char **ptr, const char *format_string, ...);
|
||||
#endif
|
||||
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
#endif /* __file_h__ */
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
/* $OpenBSD: file_opts.h,v 1.2 2009/04/26 14:17:45 chl Exp $ */
|
||||
/*
|
||||
* Table of command-line options
|
||||
*
|
||||
* The first column specifies the short name, if any, or 0 if none.
|
||||
* The second column specifies the long name.
|
||||
* The third column specifies whether it takes a parameter.
|
||||
* The fourth column is the documentation.
|
||||
*
|
||||
* N.B. The long options' order must correspond to the code in file.c,
|
||||
* and OPTSTRING must be kept up-to-date with the short options.
|
||||
* Pay particular attention to the numbers of long-only options in the
|
||||
* switch statement!
|
||||
*/
|
||||
|
||||
OPT_LONGONLY("help", 0, " display this help and exit\n")
|
||||
OPT('v', "version", 0, " output version information and exit\n")
|
||||
OPT('m', "magic-file", 1, " LIST use LIST as a colon-separated list of magic\n"
|
||||
" number files\n")
|
||||
OPT('z', "uncompress", 0, " try to look inside compressed files\n")
|
||||
OPT('b', "brief", 0, " do not prepend filenames to output lines\n")
|
||||
OPT('c', "checking-printout", 0, " print the parsed form of the magic file, use in\n"
|
||||
" conjunction with -m to debug a new magic file\n"
|
||||
" before installing it\n")
|
||||
OPT('e', "exclude", 1, " TEST exclude TEST from the list of test to be\n"
|
||||
" performed for file. Valid tests are:\n"
|
||||
" ascii, apptype, compress, elf, soft, tar, tokens, troff\n")
|
||||
OPT('f', "files-from", 1, " FILE read the filenames to be examined from FILE\n")
|
||||
OPT('F', "separator", 1, " STRING use string as separator instead of `:'\n")
|
||||
OPT('i', "mime", 0, " output MIME type strings (--mime-type and\n"
|
||||
" --mime-encoding)\n")
|
||||
OPT_LONGONLY("mime-type", 0, " output the MIME type\n")
|
||||
OPT_LONGONLY("mime-encoding", 0, " output the MIME encoding\n")
|
||||
OPT('k', "keep-going", 0, " don't stop at the first match\n")
|
||||
#ifdef S_IFLNK
|
||||
OPT('L', "dereference", 0, " follow symlinks (default)\n")
|
||||
OPT('h', "no-dereference", 0, " don't follow symlinks\n")
|
||||
#endif
|
||||
OPT('n', "no-buffer", 0, " do not buffer output\n")
|
||||
OPT('N', "no-pad", 0, " do not pad output\n")
|
||||
OPT('0', "print0", 0, " terminate filenames with ASCII NUL\n")
|
||||
#if defined(HAVE_UTIME) || defined(HAVE_UTIMES)
|
||||
OPT('p', "preserve-date", 0, " preserve access times on files\n")
|
||||
#endif
|
||||
OPT('r', "raw", 0, " don't translate unprintable chars to \\ooo\n")
|
||||
OPT('s', "special-files", 0, " treat special (block/char devices) files as\n"
|
||||
" ordinary ones\n")
|
||||
OPT('C', "compile", 0, " compile file specified by -m\n")
|
||||
OPT('d', "debug", 0, " print debugging messages\n")
|
||||
|
|
@ -1,291 +0,0 @@
|
|||
/* $OpenBSD: fsmagic.c,v 1.14 2009/10/27 23:59:37 deraadt Exp $ */
|
||||
/*
|
||||
* Copyright (c) Ian F. Darwin 1986-1995.
|
||||
* Software written by Ian F. Darwin and others;
|
||||
* maintained 1995-present by Christos Zoulas and others.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice immediately at the beginning of the file, without modification,
|
||||
* this list of conditions, and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* fsmagic - magic based on filesystem info - directory, special files, etc.
|
||||
*/
|
||||
|
||||
#include <rz_userconf.h>
|
||||
|
||||
#if !USE_LIB_MAGIC
|
||||
|
||||
#include <rz_magic.h>
|
||||
#include "file.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
/* Since major is a function on SVR4, we cannot use `ifndef major'. */
|
||||
#ifdef MAJOR_IN_MKDEV
|
||||
#include <sys/mkdev.h>
|
||||
#define HAVE_MAJOR
|
||||
#endif
|
||||
#ifdef MAJOR_IN_SYSMACROS
|
||||
#include <sys/sysmacros.h>
|
||||
#define HAVE_MAJOR
|
||||
#endif
|
||||
#ifdef major /* Might be defined in sys/types.h. */
|
||||
#define HAVE_MAJOR
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_MAJOR
|
||||
#define major(dev) (((dev) >> 8) & 0xff)
|
||||
#define minor(dev) ((dev)&0xff)
|
||||
#endif
|
||||
#undef HAVE_MAJOR
|
||||
|
||||
static int bad_link(RzMagic *ms, int err, char *buf) {
|
||||
#ifdef ELOOP
|
||||
const char *errfmt = (err == ELOOP) ? "symbolic link in a loop" : "broken symbolic link to `%s'";
|
||||
#else
|
||||
const char *errfmt = "broken symbolic link to `%s'";
|
||||
#endif
|
||||
if (ms->flags & RZ_MAGIC_ERROR) {
|
||||
file_error(ms, err, errfmt, buf);
|
||||
return -1;
|
||||
}
|
||||
if (file_printf(ms, errfmt, buf) == -1)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int file_fsmagic(struct rz_magic_set *ms, const char *fn, struct stat *sb) {
|
||||
int ret = 0;
|
||||
int mime = ms->flags & RZ_MAGIC_MIME;
|
||||
#ifdef S_IFLNK
|
||||
char buf[BUFSIZ + 4];
|
||||
int nch;
|
||||
struct stat tstatbuf;
|
||||
#endif
|
||||
if (!fn)
|
||||
return 0;
|
||||
/*
|
||||
* Fstat is cheaper but fails for files you don't have read perms on.
|
||||
* On 4.2BSD and similar systems, use lstat() to identify symlinks.
|
||||
*/
|
||||
#ifdef S_IFLNK
|
||||
if ((ms->flags & RZ_MAGIC_SYMLINK) == 0)
|
||||
ret = lstat(fn, sb);
|
||||
else
|
||||
#endif
|
||||
ret = stat(fn, sb); /* don't merge into if; see "ret =" above */
|
||||
|
||||
if (ret) {
|
||||
if (ms->flags & RZ_MAGIC_ERROR) {
|
||||
file_error(ms, errno, "cannot stat `%s'", fn);
|
||||
return -1;
|
||||
}
|
||||
if (file_printf(ms, "cannot open `%s' (%s)",
|
||||
fn, strerror(errno)) == -1)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (mime) {
|
||||
if ((sb->st_mode & S_IFMT) != S_IFREG) {
|
||||
if ((mime & RZ_MAGIC_MIME_TYPE) &&
|
||||
file_printf(ms, "application/x-not-regular-file") == -1)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
#ifdef S_ISUID
|
||||
if (sb->st_mode & S_ISUID)
|
||||
if (file_printf(ms, "setuid ") == -1)
|
||||
return -1;
|
||||
#endif
|
||||
#ifdef S_ISGID
|
||||
if (sb->st_mode & S_ISGID)
|
||||
if (file_printf(ms, "setgid ") == -1)
|
||||
return -1;
|
||||
#endif
|
||||
#ifdef S_ISVTX
|
||||
if (sb->st_mode & S_ISVTX)
|
||||
if (file_printf(ms, "sticky ") == -1)
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
switch (sb->st_mode & S_IFMT) {
|
||||
case S_IFDIR:
|
||||
if (file_printf(ms, "directory") == -1)
|
||||
return -1;
|
||||
return 1;
|
||||
#ifdef S_IFCHR
|
||||
case S_IFCHR:
|
||||
/*
|
||||
* If -s has been specified, treat character special files
|
||||
* like ordinary files. Otherwise, just report that they
|
||||
* are block special files and go on to the next file.
|
||||
*/
|
||||
if ((ms->flags & RZ_MAGIC_DEVICES) != 0)
|
||||
break;
|
||||
#ifdef HAVE_STAT_ST_RDEV
|
||||
#ifdef dv_unit
|
||||
if (file_printf(ms, "character special (%d/%d/%d)",
|
||||
major(sb->st_rdev), dv_unit(sb->st_rdev),
|
||||
dv_subunit(sb->st_rdev)) == -1)
|
||||
return -1;
|
||||
#else
|
||||
if (file_printf(ms, "character special (%ld/%ld)",
|
||||
(long)major(sb->st_rdev), (long)minor(sb->st_rdev)) == -1)
|
||||
return -1;
|
||||
#endif
|
||||
#else
|
||||
if (file_printf(ms, "character special") == -1)
|
||||
return -1;
|
||||
#endif
|
||||
return 1;
|
||||
#endif
|
||||
#ifdef S_IFBLK
|
||||
case S_IFBLK:
|
||||
/*
|
||||
* If -s has been specified, treat block special files
|
||||
* like ordinary files. Otherwise, just report that they
|
||||
* are block special files and go on to the next file.
|
||||
*/
|
||||
if ((ms->flags & RZ_MAGIC_DEVICES) != 0)
|
||||
break;
|
||||
#ifdef HAVE_STAT_ST_RDEV
|
||||
#ifdef dv_unit
|
||||
if (file_printf(ms, "block special (%d/%d/%d)",
|
||||
major(sb->st_rdev), dv_unit(sb->st_rdev),
|
||||
dv_subunit(sb->st_rdev)) == -1)
|
||||
return -1;
|
||||
#else
|
||||
if (file_printf(ms, "block special (%ld/%ld)",
|
||||
(long)major(sb->st_rdev), (long)minor(sb->st_rdev)) == -1)
|
||||
return -1;
|
||||
#endif
|
||||
#else
|
||||
if (file_printf(ms, "block special") == -1)
|
||||
return -1;
|
||||
#endif
|
||||
return 1;
|
||||
#endif
|
||||
/* TODO add code to handle V7 MUX and Blit MUX files */
|
||||
#ifdef S_IFIFO
|
||||
case S_IFIFO:
|
||||
if ((ms->flags & RZ_MAGIC_DEVICES) != 0)
|
||||
break;
|
||||
if (file_printf(ms, "fifo (named pipe)") == -1)
|
||||
return -1;
|
||||
return 1;
|
||||
#endif
|
||||
#ifdef S_IFDOOR
|
||||
case S_IFDOOR:
|
||||
return (file_printf(ms, "door") == -1) ? -1 : 1;
|
||||
#endif
|
||||
#ifdef S_IFLNK
|
||||
case S_IFLNK:
|
||||
if ((nch = readlink(fn, buf, BUFSIZ - 1)) <= 0) {
|
||||
if (ms->flags & RZ_MAGIC_ERROR) {
|
||||
file_error(ms, errno, "unreadable symlink `%s'", fn);
|
||||
return -1;
|
||||
}
|
||||
if (file_printf(ms,
|
||||
"unreadable symlink `%s' (%s)", fn,
|
||||
strerror(errno)) == -1)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
buf[nch] = '\0'; /* readlink(2) does not do this */
|
||||
|
||||
/* If broken symlink, say so and quit early. */
|
||||
if (*buf == '/') {
|
||||
if (stat(buf, &tstatbuf) < 0)
|
||||
return bad_link(ms, errno, buf);
|
||||
} else {
|
||||
char *tmp;
|
||||
char buf2[BUFSIZ + BUFSIZ + 4];
|
||||
|
||||
if (!(tmp = strrchr(fn, '/'))) {
|
||||
tmp = buf; /* in current directory anyway */
|
||||
} else {
|
||||
if (tmp - fn + 1 > BUFSIZ) {
|
||||
if (ms->flags & RZ_MAGIC_ERROR) {
|
||||
file_error(ms, 0, "path too long: `%s'", buf);
|
||||
return -1;
|
||||
}
|
||||
if (file_printf(ms, "path too long: `%s'", fn) == -1)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
snprintf(buf2, sizeof(buf2), "%s%s", fn, buf);
|
||||
tmp = buf2;
|
||||
}
|
||||
if (stat(tmp, &tstatbuf) < 0)
|
||||
return bad_link(ms, errno, buf);
|
||||
}
|
||||
|
||||
/* Otherwise, handle it. */
|
||||
if ((ms->flags & RZ_MAGIC_SYMLINK) != 0) {
|
||||
const char *p;
|
||||
ms->flags &= RZ_MAGIC_SYMLINK;
|
||||
p = rz_magic_file(ms, buf);
|
||||
ms->flags |= RZ_MAGIC_SYMLINK;
|
||||
return p != NULL ? 1 : -1;
|
||||
} else { /* just print what it points to */
|
||||
if (file_printf(ms, "symbolic link to `%s'", buf) == -1)
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
#endif
|
||||
#ifdef S_IFSOCK
|
||||
case S_IFSOCK:
|
||||
if (file_printf(ms, "socket") == -1)
|
||||
return -1;
|
||||
return 1;
|
||||
#endif
|
||||
case S_IFREG:
|
||||
break;
|
||||
default:
|
||||
file_error(ms, 0, "invalid mode 0%o", sb->st_mode);
|
||||
return -1;
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
/*
|
||||
* regular file, check next possibility
|
||||
*
|
||||
* If stat() tells us the file has zero length, report here that
|
||||
* the file is empty, so we can skip all the work of opening and
|
||||
* reading the file.
|
||||
* But if the -s option has been given, we skip this optimization,
|
||||
* since on some systems, stat() reports zero size for raw disk
|
||||
* partitions. (If the block special device really has zero length,
|
||||
* the fact that it is empty will be detected and reported correctly
|
||||
* when we read the file.)
|
||||
*/
|
||||
if ((ms->flags & RZ_MAGIC_DEVICES) == 0 && sb->st_size == 0) {
|
||||
if ((!mime || (mime & RZ_MAGIC_MIME_TYPE)) &&
|
||||
file_printf(ms, mime ? "application/x-empty" : "empty") == -1)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1,339 +0,0 @@
|
|||
/* $OpenBSD: funcs.c,v 1.7 2009/10/27 23:59:37 deraadt Exp $ */
|
||||
/*
|
||||
* Copyright (c) Christos Zoulas 2003.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice immediately at the beginning of the file, without modification,
|
||||
* this list of conditions, and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <rz_userconf.h>
|
||||
|
||||
#if !USE_LIB_MAGIC
|
||||
|
||||
#include "file.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <wctype.h>
|
||||
#if defined(HAVE_WCHAR_H)
|
||||
#include <wchar.h>
|
||||
#endif
|
||||
|
||||
// copypasta to fix an OPENBSDBUG
|
||||
static int file_vprintf(RzMagic *ms, const char *fmt, va_list ap) {
|
||||
va_list ap2;
|
||||
char cbuf[4096];
|
||||
char *buf, *newstr;
|
||||
|
||||
va_copy(ap2, ap);
|
||||
int len = vsnprintf(cbuf, sizeof(cbuf), fmt, ap2);
|
||||
va_end(ap2);
|
||||
if (len < 0) {
|
||||
goto out;
|
||||
}
|
||||
if (len > sizeof(cbuf)) {
|
||||
buf = malloc(len + 1);
|
||||
va_copy(ap2, ap);
|
||||
(void)vsnprintf(buf, len + 1, fmt, ap2);
|
||||
va_end(ap2);
|
||||
} else {
|
||||
int nullbyte = len;
|
||||
if (nullbyte > 0 && nullbyte == sizeof(cbuf)) {
|
||||
nullbyte--;
|
||||
}
|
||||
cbuf[nullbyte] = 0;
|
||||
buf = strdup(cbuf);
|
||||
}
|
||||
if (!buf) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int buflen = len;
|
||||
if (ms->o.buf) {
|
||||
int obuflen = strlen(ms->o.buf);
|
||||
len = obuflen + buflen + 1;
|
||||
newstr = malloc(len);
|
||||
if (!newstr) {
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
memcpy(newstr, ms->o.buf, obuflen);
|
||||
memcpy(newstr + obuflen, buf, buflen);
|
||||
newstr[len - 1] = 0;
|
||||
free(buf);
|
||||
free(ms->o.buf);
|
||||
if (len < 0) {
|
||||
free(newstr);
|
||||
goto out;
|
||||
}
|
||||
buf = newstr;
|
||||
}
|
||||
ms->o.buf = buf;
|
||||
return 0;
|
||||
out:
|
||||
file_error(ms, errno, "vasprintf failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Like printf, only we append to a buffer.
|
||||
*/
|
||||
int file_printf(RzMagic *ms, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
va_start(ap, fmt);
|
||||
ret = file_vprintf(ms, fmt, ap);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* error - print best error message possible
|
||||
*/
|
||||
/*VARARGS*/
|
||||
static void file_error_core(RzMagic *ms, int error, const char *f, va_list va, ut32 lineno) {
|
||||
/* Only the first error is ok */
|
||||
if (!ms || ms->haderr) {
|
||||
return;
|
||||
}
|
||||
if (lineno != 0) {
|
||||
free(ms->o.buf);
|
||||
ms->o.buf = NULL;
|
||||
(void)file_printf(ms, "line %u: ", lineno);
|
||||
}
|
||||
// OPENBSDBUG
|
||||
file_vprintf(ms, f, va);
|
||||
if (error > 0) {
|
||||
(void)file_printf(ms, " (%s)", strerror(error));
|
||||
}
|
||||
ms->haderr++;
|
||||
ms->error = error;
|
||||
}
|
||||
|
||||
/*VARARGS*/
|
||||
void file_error(RzMagic *ms, int error, const char *f, ...) {
|
||||
va_list va;
|
||||
va_start(va, f);
|
||||
file_error_core(ms, error, f, va, 0);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print an error with magic line number.
|
||||
*/
|
||||
/*VARARGS*/
|
||||
void file_magerror(RzMagic *ms, const char *f, ...) {
|
||||
va_list va;
|
||||
va_start(va, f);
|
||||
file_error_core(ms, 0, f, va, ms->line);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
void file_oomem(RzMagic *ms, size_t len) {
|
||||
file_error(ms, errno, "cannot allocate %zu bytes", len);
|
||||
}
|
||||
|
||||
void file_badseek(RzMagic *ms) {
|
||||
file_error(ms, errno, "error seeking");
|
||||
}
|
||||
|
||||
void file_badread(RzMagic *ms) {
|
||||
file_error(ms, errno, "error reading");
|
||||
}
|
||||
|
||||
int file_buffer(RzMagic *ms, int fd, const char *inname, const ut8 *buf, size_t nb) {
|
||||
int mime, m = 0;
|
||||
if (!ms) {
|
||||
return -1;
|
||||
}
|
||||
mime = ms->flags & RZ_MAGIC_MIME;
|
||||
if (nb == 0) {
|
||||
if ((!mime || (mime & RZ_MAGIC_MIME_TYPE)) &&
|
||||
file_printf(ms, mime ? "application/x-empty" : "empty") == -1) {
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
} else if (nb == 1) {
|
||||
if ((!mime || (mime & RZ_MAGIC_MIME_TYPE)) &&
|
||||
file_printf(ms, mime ? "application/octet-stream" : "very short file (no magic)") == -1) {
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* try compression stuff */
|
||||
if ((ms->flags & RZ_MAGIC_NO_CHECK_COMPRESS) != 0 ||
|
||||
(m = file_zmagic(ms, fd, inname, buf, nb)) == 0) {
|
||||
#endif
|
||||
/* Check if we have a tar file */
|
||||
if ((ms->flags & RZ_MAGIC_NO_CHECK_TAR) != 0 ||
|
||||
(m = file_is_tar(ms, buf, nb)) == 0) {
|
||||
/* try tests in /etc/magic (or surrogate magic file) */
|
||||
if ((ms->flags & RZ_MAGIC_NO_CHECK_SOFT) != 0 ||
|
||||
(m = file_softmagic(ms, buf, nb, BINTEST)) == 0) {
|
||||
/* try known keywords, check whether it is ASCII */
|
||||
if ((ms->flags & RZ_MAGIC_NO_CHECK_ASCII) != 0 ||
|
||||
(m = file_ascmagic(ms, buf, nb)) == 0) {
|
||||
/* abandon hope, all ye who remain here */
|
||||
if ((!mime || (mime & RZ_MAGIC_MIME_TYPE))) {
|
||||
// if (mime)
|
||||
file_printf(ms, "application/octet-stream");
|
||||
return -1;
|
||||
}
|
||||
m = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
return m;
|
||||
}
|
||||
|
||||
int file_reset(RzMagic *ms) {
|
||||
if (!ms) {
|
||||
return 0;
|
||||
}
|
||||
free(ms->o.buf);
|
||||
ms->o.buf = NULL;
|
||||
ms->haderr = 0;
|
||||
ms->error = -1;
|
||||
if (!ms->mlist) {
|
||||
file_error(ms, 0, "no magic files loaded! ");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define OCTALIFY(n, o) \
|
||||
/*LINTED*/ \
|
||||
(void)(*(n)++ = '\\', \
|
||||
*(n)++ = (((ut32) * (o) >> 6) & 3) + '0', \
|
||||
*(n)++ = (((ut32) * (o) >> 3) & 7) + '0', \
|
||||
*(n)++ = (((ut32) * (o) >> 0) & 7) + '0', \
|
||||
(o)++)
|
||||
|
||||
const char *file_getbuffer(RzMagic *ms) {
|
||||
char *pbuf, *op, *np;
|
||||
size_t psize, len;
|
||||
|
||||
if (ms->haderr) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ms->flags & RZ_MAGIC_RAW) {
|
||||
return ms->o.buf;
|
||||
}
|
||||
|
||||
if (!ms->o.buf) {
|
||||
eprintf("ms->o.buf = NULL\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* * 4 is for octal representation, + 1 is for NUL */
|
||||
len = strlen(ms->o.buf);
|
||||
if (len > (SIZE_MAX - 1) / 4) {
|
||||
file_oomem(ms, len);
|
||||
return NULL;
|
||||
}
|
||||
psize = len * 4 + 1;
|
||||
if (!(pbuf = realloc(ms->o.pbuf, psize))) {
|
||||
file_oomem(ms, psize);
|
||||
return NULL;
|
||||
}
|
||||
pbuf[psize - 1] = 0;
|
||||
ms->o.pbuf = pbuf;
|
||||
|
||||
#if 1
|
||||
// defined(HAVE_WCHAR_H) && defined(HAVE_MBRTOWC) && defined(HAVE_WCWIDTH)
|
||||
{
|
||||
mbstate_t state;
|
||||
wchar_t nextchar;
|
||||
int mb_conv = 1;
|
||||
size_t bytesconsumed;
|
||||
char *eop;
|
||||
(void)memset(&state, 0, sizeof(mbstate_t));
|
||||
|
||||
np = ms->o.pbuf;
|
||||
op = ms->o.buf;
|
||||
eop = op + len;
|
||||
|
||||
while (op < eop) {
|
||||
bytesconsumed = mbrtowc(&nextchar, op,
|
||||
(size_t)(eop - op), &state);
|
||||
if (bytesconsumed == (size_t)(-1) ||
|
||||
bytesconsumed == (size_t)(-2)) {
|
||||
mb_conv = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (iswprint(nextchar)) {
|
||||
(void)memcpy(np, op, bytesconsumed);
|
||||
op += bytesconsumed;
|
||||
np += bytesconsumed;
|
||||
} else {
|
||||
while (bytesconsumed-- > 0) {
|
||||
OCTALIFY(np, op);
|
||||
}
|
||||
}
|
||||
}
|
||||
*np = '\0';
|
||||
|
||||
/* Parsing succeeded as a multi-byte sequence */
|
||||
if (mb_conv != 0) {
|
||||
return ms->o.pbuf;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
const char *pbuf_end = ms->o.pbuf + psize;
|
||||
const char *buf_end = ms->o.buf + len;
|
||||
for (np = ms->o.pbuf, op = ms->o.buf; op < buf_end && np < pbuf_end && *op; op++) {
|
||||
if (isprint((ut8)*op)) {
|
||||
*np++ = *op;
|
||||
} else {
|
||||
OCTALIFY(np, op);
|
||||
}
|
||||
}
|
||||
*np = '\0';
|
||||
return ms->o.pbuf;
|
||||
}
|
||||
|
||||
int file_check_mem(RzMagic *ms, unsigned int level) {
|
||||
if (level >= ms->c.len) {
|
||||
ms->c.len = level + 20;
|
||||
size_t len = ms->c.len * sizeof(*ms->c.li);
|
||||
ms->c.li = (!ms->c.li) ? malloc(len) : realloc(ms->c.li, len);
|
||||
if (!ms->c.li) {
|
||||
file_oomem(ms, len);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
ms->c.li[level].got_match = 0;
|
||||
ms->c.li[level].last_match = 0;
|
||||
ms->c.li[level].last_cond = COND_NONE;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1,144 +0,0 @@
|
|||
/* $OpenBSD: is_tar.c,v 1.10 2009/10/27 23:59:37 deraadt Exp $ */
|
||||
/*
|
||||
* Copyright (c) Ian F. Darwin 1986-1995.
|
||||
* Software written by Ian F. Darwin and others;
|
||||
* maintained 1995-present by Christos Zoulas and others.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice immediately at the beginning of the file, without modification,
|
||||
* this list of conditions, and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* is_tar() -- figure out whether file is a tar archive.
|
||||
*
|
||||
* Stolen (by the author!) from the public domain tar program:
|
||||
* Public Domain version written 26 Aug 1985 John Gilmore (ihnp4!hoptoad!gnu).
|
||||
*
|
||||
* @(#)list.c 1.18 9/23/86 Public Domain - gnu
|
||||
*
|
||||
* Comments changed and some code/comments reformatted
|
||||
* for file command by Ian Darwin.
|
||||
*/
|
||||
#include <rz_userconf.h>
|
||||
|
||||
#if !USE_LIB_MAGIC
|
||||
|
||||
#include "file.h"
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include "tar.h"
|
||||
|
||||
static const char tartype[][32] = {
|
||||
"tar archive",
|
||||
"POSIX tar archive",
|
||||
"POSIX tar archive (GNU)",
|
||||
};
|
||||
|
||||
/*
|
||||
* Quick and dirty octal conversion.
|
||||
*
|
||||
* Result is -1 if the field is invalid (all blank, or nonoctal).
|
||||
*/
|
||||
#define isodigit(c) (((c) >= '0') && ((c) <= '7'))
|
||||
static int from_oct(int digs, const char *where) {
|
||||
int value = 0;
|
||||
while (isspace((ut8)*where)) { /* Skip spaces */
|
||||
where++;
|
||||
if (--digs <= 0) {
|
||||
return -1; /* All blank field */
|
||||
}
|
||||
}
|
||||
while (digs > 0 && isodigit(*where)) { /* Scan til nonoctal */
|
||||
value = (value << 3) | (*where++ - '0');
|
||||
--digs;
|
||||
}
|
||||
if (digs > 0 && *where && !isspace((ut8)*where)) {
|
||||
return -1; /* Ended on non-space/nul */
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return
|
||||
* 0 if the checksum is bad (i.e., probably not a tar archive),
|
||||
* 1 for old UNIX tar file,
|
||||
* 2 for Unix Std (POSIX) tar file,
|
||||
* 3 for GNU tar file.
|
||||
*/
|
||||
static int is_tar(const ut8 *buf, size_t nbytes) {
|
||||
const union record *header = (const union record *)(const void *)buf;
|
||||
int i, sum, recsum;
|
||||
const char *p;
|
||||
|
||||
if (nbytes < sizeof(union record)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
recsum = from_oct(8, header->header.chksum);
|
||||
|
||||
sum = 0;
|
||||
p = header->charptr;
|
||||
for (i = sizeof(union record); --i >= 0;) {
|
||||
/*
|
||||
* We cannot use ut8 here because of old compilers,
|
||||
* e.g. V7.
|
||||
*/
|
||||
sum += 0xFF & *p++;
|
||||
}
|
||||
|
||||
/* Adjust checksum to count the "chksum" field as blanks. */
|
||||
for (i = sizeof header->header.chksum; --i >= 0;) {
|
||||
sum -= 0xFF & header->header.chksum[i];
|
||||
}
|
||||
sum += ' ' * sizeof header->header.chksum;
|
||||
if (sum != recsum) {
|
||||
return 0; /* Not a tar archive */
|
||||
}
|
||||
if (strcmp(header->header.magic, GNUTMAGIC) == 0) {
|
||||
return 3; /* GNU Unix Standard tar archive */
|
||||
}
|
||||
if (strcmp(header->header.magic, TMAGIC) == 0) {
|
||||
return 2; /* Unix Standard tar archive */
|
||||
}
|
||||
return 1; /* Old fashioned tar archive */
|
||||
}
|
||||
|
||||
int file_is_tar(RzMagic *ms, const ut8 *buf, size_t nbytes) {
|
||||
/*
|
||||
* Do the tar test first, because if the first file in the tar
|
||||
* archive starts with a dot, we can confuse it with an nroff file.
|
||||
*/
|
||||
int tar = is_tar(buf, nbytes);
|
||||
int mime = ms->flags & RZ_MAGIC_MIME;
|
||||
|
||||
if (tar < 1 || tar > 3) {
|
||||
return 0;
|
||||
}
|
||||
if (mime == RZ_MAGIC_MIME_ENCODING) {
|
||||
return 0;
|
||||
}
|
||||
if (file_printf(ms, mime ? "application/x-tar" : tartype[tar - 1]) == -1) {
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
57
librz/magic/magic-common.c
Normal file
57
librz/magic/magic-common.c
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/* $OpenBSD: magic-common.c,v 1.3 2015/08/11 22:29:25 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2015 Nicholas Marriott <nicm@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "magic.h"
|
||||
|
||||
RZ_BORROW char *magic_strtoull(RZ_NONNULL const char *s, RZ_NONNULL ut64 *u) {
|
||||
rz_return_val_if_fail(s && u, NULL);
|
||||
|
||||
char *endptr;
|
||||
|
||||
if (*s == '-' || *s == '\0')
|
||||
return (NULL);
|
||||
|
||||
errno = 0;
|
||||
*u = strtoull(s, &endptr, 0);
|
||||
if (endptr == s)
|
||||
*u = strtoull(s, &endptr, 16);
|
||||
if (errno == ERANGE && *u == ULLONG_MAX)
|
||||
return (NULL);
|
||||
if (*endptr == 'L')
|
||||
endptr++;
|
||||
return (endptr);
|
||||
}
|
||||
|
||||
RZ_BORROW char *magic_strtoll(RZ_NONNULL const char *s, RZ_NONNULL int64_t *i) {
|
||||
rz_return_val_if_fail(s && i, NULL);
|
||||
|
||||
char *endptr;
|
||||
|
||||
if (*s == '\0')
|
||||
return (NULL);
|
||||
|
||||
errno = 0;
|
||||
*i = strtoll(s, &endptr, 0);
|
||||
if (endptr == s)
|
||||
*i = strtoll(s, &endptr, 16);
|
||||
if (errno == ERANGE && *i == LLONG_MAX)
|
||||
return (NULL);
|
||||
if (*endptr == 'L')
|
||||
endptr++;
|
||||
return (endptr);
|
||||
}
|
||||
1141
librz/magic/magic-load.c
Normal file
1141
librz/magic/magic-load.c
Normal file
File diff suppressed because it is too large
Load diff
1458
librz/magic/magic-test.c
Normal file
1458
librz/magic/magic-test.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -2,8 +2,9 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
/* $OpenBSD: magic.c,v 1.8 2009/10/27 23:59:37 deraadt Exp $ */
|
||||
|
||||
#include <rz_userconf.h>
|
||||
#include <rz_magic.h>
|
||||
#include <rz_util.h>
|
||||
#include "magic.h"
|
||||
|
||||
RZ_LIB_VERSION(rz_magic);
|
||||
|
||||
|
|
@ -17,320 +18,130 @@ RZ_LIB_VERSION(rz_magic);
|
|||
#define MAXPATHLEN 255
|
||||
#endif
|
||||
|
||||
#if USE_LIB_MAGIC
|
||||
|
||||
// we keep this code just to make debian happy, but we should use
|
||||
// our own magic implementation for consistency reasons
|
||||
#include <magic.h>
|
||||
#undef RZ_API
|
||||
#define RZ_API
|
||||
|
||||
RZ_API RzMagic *rz_magic_new(int flags) {
|
||||
return magic_open(flags);
|
||||
}
|
||||
RZ_API void rz_magic_free(RzMagic *m) {
|
||||
if (m) {
|
||||
magic_close(m);
|
||||
}
|
||||
}
|
||||
RZ_API const char *rz_magic_file(RzMagic *m, const char *f) {
|
||||
return magic_file(m, f);
|
||||
}
|
||||
RZ_API const char *rz_magic_descriptor(RzMagic *m, int fd) {
|
||||
return magic_descriptor(m, fd);
|
||||
}
|
||||
RZ_API const char *rz_magic_buffer(RzMagic *m, const ut8 *b, size_t s) {
|
||||
return magic_buffer(m, b, s);
|
||||
}
|
||||
RZ_API const char *rz_magic_error(RzMagic *m) {
|
||||
return magic_error(m);
|
||||
}
|
||||
RZ_API void rz_magic_setflags(RzMagic *m, int f) {
|
||||
magic_setflags(m, f);
|
||||
}
|
||||
RZ_API bool rz_magic_load_buffer(RzMagic *m, const char *f) {
|
||||
if (*f == '#') {
|
||||
return magic_load(m, f) != -1;
|
||||
} else {
|
||||
eprintf("Magic buffers should start with #\n");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
RZ_API bool rz_magic_load(RzMagic *m, const char *f) {
|
||||
return magic_load(m, f) != -1;
|
||||
}
|
||||
RZ_API bool rz_magic_compile(RzMagic *m, const char *x) {
|
||||
return magic_compile(m, x) != -1;
|
||||
}
|
||||
RZ_API bool rz_magic_check(RzMagic *m, const char *x) {
|
||||
return magic_check(m, x) != -1;
|
||||
}
|
||||
RZ_API int rz_magic_errno(RzMagic *m) {
|
||||
return magic_errno(m);
|
||||
static void magic_node_free_rb(RBNode *node, void *user) {
|
||||
RzMagicLine *ml = container_of(node, RzMagicLine, rb);
|
||||
rz_magic_line_free(ml);
|
||||
}
|
||||
|
||||
#else
|
||||
static bool magic_load_file(RZ_NONNULL RZ_BORROW RzMagic *m, const char *file_path) {
|
||||
rz_return_val_if_fail(m, false);
|
||||
|
||||
/* use embedded magic library */
|
||||
|
||||
#include "file.h"
|
||||
|
||||
#ifndef PIPE_BUF
|
||||
/* Get the PIPE_BUF from pathconf */
|
||||
#ifdef _PC_PIPE_BUF
|
||||
#define PIPE_BUF pathconf(".", _PC_PIPE_BUF)
|
||||
#else
|
||||
#define PIPE_BUF 512
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static void free_mlist(struct mlist *mlist) {
|
||||
struct mlist *ml;
|
||||
if (!mlist) {
|
||||
return;
|
||||
int result;
|
||||
FILE *file = fopen(file_path, "r");
|
||||
if (!file) {
|
||||
return false;
|
||||
}
|
||||
for (ml = mlist->next; ml != mlist;) {
|
||||
struct mlist *next = ml->next;
|
||||
struct rz_magic *mg = ml->magic;
|
||||
file_delmagic(mg, ml->mapped, ml->nmagic);
|
||||
free(ml);
|
||||
ml = next;
|
||||
}
|
||||
free(ml);
|
||||
}
|
||||
|
||||
static int info_from_stat(RzMagic *ms, unsigned short md) {
|
||||
/* We cannot open it, but we were able to stat it. */
|
||||
if (md & 0222) {
|
||||
if (file_printf(ms, "writable, ") == -1) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (md & 0111) {
|
||||
if (file_printf(ms, "executable, ") == -1) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (S_ISREG(md)) {
|
||||
if (file_printf(ms, "regular file, ") == -1) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (file_printf(ms, "no read permission") == -1) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void close_and_restore(const RzMagic *ms, const char *name, int fd, const struct stat *sb) {
|
||||
if (fd >= 0) {
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
static const char *file_or_fd(RzMagic *ms, const char *inname, int fd) {
|
||||
bool ispipe = false;
|
||||
int rv = -1;
|
||||
unsigned char *buf;
|
||||
struct stat sb;
|
||||
int nbytes = 0; /* number of bytes read from a datafile */
|
||||
|
||||
/*
|
||||
* one extra for terminating '\0', and
|
||||
* some overlapping space for matches near EOF
|
||||
*/
|
||||
if (!(buf = malloc(RZ_MAGIC_BUF_SIZE))) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (file_reset(ms) == -1) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
switch (file_fsmagic(ms, inname, &sb)) {
|
||||
case -1: goto done; /* error */
|
||||
case 0: break; /* nothing found */
|
||||
default: rv = 0; goto done; /* matched it and printed type */
|
||||
}
|
||||
|
||||
if (!inname) {
|
||||
if (fstat(fd, &sb) == 0 && S_ISFIFO(sb.st_mode)) {
|
||||
ispipe = true;
|
||||
}
|
||||
} else {
|
||||
int flags = O_RDONLY | O_BINARY;
|
||||
|
||||
if (stat(inname, &sb) == 0 && S_ISFIFO(sb.st_mode)) {
|
||||
#if O_NONBLOCK
|
||||
flags |= O_NONBLOCK;
|
||||
#endif
|
||||
ispipe = true;
|
||||
}
|
||||
errno = 0;
|
||||
if ((fd = open(inname, flags)) < 0) {
|
||||
eprintf("couldn't open file\n");
|
||||
if (info_from_stat(ms, sb.st_mode) == -1) {
|
||||
goto done;
|
||||
}
|
||||
rv = 0;
|
||||
goto done;
|
||||
}
|
||||
#ifdef O_NONBLOCK
|
||||
if ((flags = fcntl(fd, F_GETFL)) != -1) {
|
||||
flags &= ~O_NONBLOCK;
|
||||
(void)fcntl(fd, F_SETFL, flags);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* try looking at the first HOWMANY bytes
|
||||
*/
|
||||
#ifdef O_NONBLOCK
|
||||
if (ispipe) {
|
||||
ssize_t r = 0;
|
||||
|
||||
// while ((r = sread(fd, (void *)&buf[nbytes],
|
||||
while ((r = read(fd, (void *)&buf[nbytes],
|
||||
(size_t)(HOWMANY - nbytes))) > 0) {
|
||||
nbytes += r;
|
||||
if (r < PIPE_BUF) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (nbytes == 0) {
|
||||
/* We can not read it, but we were able to stat it. */
|
||||
if (info_from_stat(ms, sb.st_mode) == -1) {
|
||||
goto done;
|
||||
}
|
||||
rv = 0;
|
||||
goto done;
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
if ((nbytes = read(fd, (char *)buf, HOWMANY)) == -1) {
|
||||
file_error(ms, errno, "cannot read `%s'", inname);
|
||||
goto done;
|
||||
}
|
||||
#ifdef O_NONBLOCK
|
||||
}
|
||||
#endif
|
||||
|
||||
(void)memset(buf + nbytes, 0, RZ_MAGIC_BUF_SIZE); /* NUL terminate */
|
||||
if (file_buffer(ms, fd, inname, buf, (size_t)nbytes) == -1) {
|
||||
goto done;
|
||||
}
|
||||
rv = 0;
|
||||
done:
|
||||
free(buf);
|
||||
close_and_restore(ms, inname, fd, &sb);
|
||||
return rv == 0 ? file_getbuffer(ms) : NULL;
|
||||
result = magic_load(m, file);
|
||||
fclose(file);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* API */
|
||||
|
||||
// TODO: reinitialize all the time
|
||||
RZ_API RzMagic *rz_magic_new(int flags) {
|
||||
RzMagic *ms = RZ_NEW0(RzMagic);
|
||||
if (!ms) {
|
||||
return NULL;
|
||||
}
|
||||
rz_magic_setflags(ms, flags);
|
||||
ms->o.buf = ms->o.pbuf = NULL;
|
||||
ms->c.li = malloc((ms->c.len = 10) * sizeof(*ms->c.li));
|
||||
if (!ms->c.li) {
|
||||
free(ms);
|
||||
return NULL;
|
||||
}
|
||||
file_reset(ms);
|
||||
ms->mlist = NULL;
|
||||
ms->file = "unknown";
|
||||
ms->line = 0;
|
||||
return ms;
|
||||
RZ_API RZ_OWN RzMagic *rz_magic_new() {
|
||||
return RZ_NEW0(RzMagic);
|
||||
}
|
||||
|
||||
RZ_API void rz_magic_free(RzMagic *ms) {
|
||||
if (ms) {
|
||||
free_mlist(ms->mlist);
|
||||
free(ms->o.pbuf);
|
||||
free(ms->o.buf);
|
||||
free(ms->c.li);
|
||||
free(ms);
|
||||
RZ_API void rz_magic_free(RZ_NULLABLE RZ_OWN RzMagic *m) {
|
||||
if (!m) {
|
||||
return;
|
||||
}
|
||||
free(m->path);
|
||||
rz_rbtree_free(m->magic_tree, magic_node_free_rb, NULL);
|
||||
rz_rbtree_free(m->magic_named_tree, magic_node_free_rb, NULL);
|
||||
rz_regex_free(m->format_short);
|
||||
rz_regex_free(m->format_long);
|
||||
rz_regex_free(m->format_quad);
|
||||
rz_regex_free(m->format_float);
|
||||
rz_regex_free(m->format_string);
|
||||
free(m);
|
||||
}
|
||||
|
||||
RZ_API bool rz_magic_load_buffer(RzMagic *ms, const char *magicdata) {
|
||||
if (*magicdata == '#') {
|
||||
struct mlist *ml = file_apprentice(ms, magicdata, FILE_LOAD);
|
||||
if (ml) {
|
||||
free_mlist(ms->mlist);
|
||||
ms->mlist = ml;
|
||||
return true;
|
||||
/**
|
||||
* \brief Load magic rules from magic_path and store them in the RzMagic context
|
||||
*
|
||||
*/
|
||||
RZ_API bool rz_magic_load(RZ_NONNULL RZ_BORROW RzMagic *m, RZ_NONNULL const char *magic_path) {
|
||||
rz_return_val_if_fail(m, false);
|
||||
|
||||
if (m->path) {
|
||||
free(m->path);
|
||||
}
|
||||
m->path = rz_str_dup(magic_path);
|
||||
|
||||
if (rz_file_is_directory(magic_path)) {
|
||||
RzList *files = rz_sys_dir(magic_path);
|
||||
if (!files) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
eprintf("Magic buffers should start with #\n");
|
||||
RzListIter *it;
|
||||
const char *subname;
|
||||
char *filepath = NULL;
|
||||
RzStrBuf subpath;
|
||||
rz_strbuf_init(&subpath);
|
||||
bool result = true;
|
||||
rz_list_foreach (files, it, subname) {
|
||||
if (RZ_STR_EQ(subname, ".")) {
|
||||
continue;
|
||||
}
|
||||
if (RZ_STR_EQ(subname, "..")) {
|
||||
continue;
|
||||
}
|
||||
filepath = rz_file_path_join(magic_path, subname);
|
||||
result &= magic_load_file(m, filepath);
|
||||
if (!result) {
|
||||
RZ_LOG_WARN("Failed to load magic file '%s'.\n", filepath);
|
||||
break;
|
||||
}
|
||||
free(filepath);
|
||||
}
|
||||
rz_list_free(files);
|
||||
return result;
|
||||
}
|
||||
return false;
|
||||
return magic_load_file(m, magic_path);
|
||||
}
|
||||
|
||||
RZ_API bool rz_magic_load(RzMagic *ms, const char *magicfile) {
|
||||
struct mlist *ml = file_apprentice(ms, magicfile, FILE_LOAD);
|
||||
if (ml) {
|
||||
free_mlist(ms->mlist);
|
||||
ms->mlist = ml;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* \brief Test buf against the loaded magic rules
|
||||
*/
|
||||
RZ_API RZ_OWN char *rz_magic_buffer(RZ_NONNULL const RzMagic *m, RZ_NONNULL const ut8 *buf, size_t nb) {
|
||||
rz_return_val_if_fail(m && buf, NULL);
|
||||
|
||||
RZ_API bool rz_magic_compile(RzMagic *ms, const char *magicfile) {
|
||||
struct mlist *ml = file_apprentice(ms, magicfile, FILE_COMPILE);
|
||||
free_mlist(ml);
|
||||
return ml != NULL;
|
||||
}
|
||||
|
||||
RZ_API bool rz_magic_check(RzMagic *ms, const char *magicfile) {
|
||||
struct mlist *ml = file_apprentice(ms, magicfile, FILE_CHECK);
|
||||
free_mlist(ml);
|
||||
return ml != NULL;
|
||||
}
|
||||
|
||||
RZ_API const char *rz_magic_descriptor(RzMagic *ms, int fd) {
|
||||
return file_or_fd(ms, NULL, fd);
|
||||
}
|
||||
|
||||
RZ_API const char *rz_magic_file(RzMagic *ms, const char *inname) {
|
||||
return file_or_fd(ms, inname, 0); // 0 = stdin
|
||||
}
|
||||
|
||||
RZ_API const char *rz_magic_buffer(RzMagic *ms, const ut8 *buf, size_t nb) {
|
||||
if (file_reset(ms) == -1) {
|
||||
if (nb == 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (file_buffer(ms, -1, NULL, buf, nb) == -1) {
|
||||
|
||||
char *output = magic_test(m, buf, nb, MAGIC_TEST_TEXT);
|
||||
if (!output) {
|
||||
return magic_test(m, buf, nb, 0);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
RZ_OWN RzMagicLine *rz_magic_line_new(void) {
|
||||
RzMagicLine *ml = RZ_NEW0(RzMagicLine);
|
||||
if (!ml) {
|
||||
return NULL;
|
||||
}
|
||||
return file_getbuffer(ms);
|
||||
ml->children = rz_list_new();
|
||||
if (!ml->children) {
|
||||
rz_magic_line_free(ml);
|
||||
return NULL;
|
||||
}
|
||||
return ml;
|
||||
}
|
||||
|
||||
RZ_API const char *rz_magic_error(RzMagic *ms) {
|
||||
if (ms && ms->haderr) {
|
||||
return ms->o.buf;
|
||||
void rz_magic_line_free(RZ_OWN RZ_NULLABLE RzMagicLine *ml) {
|
||||
if (!ml) {
|
||||
return;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RZ_API int rz_magic_errno(RzMagic *ms) {
|
||||
if (ms && ms->haderr) {
|
||||
return ms->error;
|
||||
while (!rz_list_empty(ml->children)) {
|
||||
RzMagicLine *child = rz_list_pop(ml->children);
|
||||
rz_magic_line_free(child);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
RZ_API void rz_magic_setflags(RzMagic *ms, int flags) {
|
||||
if (ms) {
|
||||
ms->flags = flags;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
rz_list_free(ml->children);
|
||||
free(ml->type_string);
|
||||
free(ml->result);
|
||||
free(ml->mimetype);
|
||||
free(ml);
|
||||
}
|
||||
20
librz/magic/magic.h
Normal file
20
librz/magic/magic.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
// SPDX-FileCopyrightText: 2025 ahmed-kamal2004 <ahmedkamal200427@gmail.com>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <rz_magic.h>
|
||||
|
||||
RZ_OWN RzMagicLine *rz_magic_line_new(void);
|
||||
|
||||
void rz_magic_line_free(RZ_OWN RZ_NULLABLE RzMagicLine *);
|
||||
|
||||
int magic_compare(const void *incoming, const RBNode *in_tree, void *user);
|
||||
|
||||
int magic_named_compare(const void *incoming, const RBNode *in_tree, void *user);
|
||||
|
||||
RZ_BORROW char *magic_strtoull(RZ_NONNULL const char *, RZ_NONNULL ut64 *);
|
||||
|
||||
RZ_BORROW char *magic_strtoll(RZ_NONNULL const char *, RZ_NONNULL int64_t *);
|
||||
|
||||
bool magic_load(RZ_NONNULL RZ_BORROW RzMagic *, RZ_NONNULL FILE *f);
|
||||
|
||||
RZ_OWN char *magic_test(RZ_NONNULL const RzMagic *, RZ_NONNULL const void *, size_t, int);
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
* Hand-made config.h file for OpenBSD, so we don't have to run
|
||||
* the dratted configure script every time we build this puppy,
|
||||
* but can still carefully import stuff from Christos' version.
|
||||
*
|
||||
* This file is in the public domain. Original Author Ian F. Darwin.
|
||||
* $OpenBSD: config.h,v 1.7 2011/07/25 16:21:22 martynas Exp $
|
||||
*/
|
||||
|
||||
/* header file issues. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
#define HAVE_FCNTL_H 1
|
||||
#define HAVE_LOCALE_H 1
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
#define HAVE_INTTYPES_H 1
|
||||
#define HAVE_GETOPT_H 1
|
||||
#define HAVE_LIMITS_H 1
|
||||
|
||||
// fail on w32?
|
||||
#define HAVE_UNISTD_H 1
|
||||
#define HAVE_WCHAR_H 1
|
||||
|
||||
// TODO: add dependency for zlib?
|
||||
/* #define HAVE_ZLIB_H 1 DO NOT ENABLE YET -- chl */
|
||||
/* #define HAVE_LIBZ 1 DO NOT ENABLE YET -- ian */
|
||||
|
||||
#define HAVE_VSNPRINTF
|
||||
#define HAVE_SNPRINTF
|
||||
#define HAVE_STRTOF
|
||||
|
||||
/* Compiler issues */
|
||||
#define SIZEOF_LONG_LONG sizeof(long long)
|
||||
|
||||
/* Library issues */
|
||||
#define HAVE_GETOPT_LONG 0 /* in-tree as of 3.2 */
|
||||
#define HAVE_ST_RDEV 1
|
||||
|
||||
/* ELF support */
|
||||
#define BUILTIN_ELF 0
|
||||
#define ELFCORE 0
|
||||
|
|
@ -1,222 +0,0 @@
|
|||
/* $OpenBSD: print.c,v 1.16 2009/10/27 23:59:37 deraadt Exp $ */
|
||||
/*
|
||||
* Copyright (c) Ian F. Darwin 1986-1995.
|
||||
* Software written by Ian F. Darwin and others;
|
||||
* maintained 1995-present by Christos Zoulas and others.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice immediately at the beginning of the file, without modification,
|
||||
* this list of conditions, and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* print.c - debugging printout routines
|
||||
*/
|
||||
#include <rz_userconf.h>
|
||||
|
||||
#if !USE_LIB_MAGIC
|
||||
|
||||
#include "file.h"
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#define SZOF(a) (sizeof(a) / sizeof(a[0]))
|
||||
|
||||
#ifndef COMPILE_ONLY
|
||||
void file_mdump(struct rz_magic_set *ms, struct rz_magic *m) {
|
||||
static const char optyp[] = { FILE_OPS };
|
||||
char pp[ASCTIME_BUF_MINLEN];
|
||||
|
||||
(void)eprintf("[%u", m->lineno);
|
||||
(void)eprintf("%.*s %u", m->cont_level & 7, ">>>>>>>>", m->offset);
|
||||
|
||||
if (m->flag & INDIR) {
|
||||
(void)eprintf("(%s,",
|
||||
/* Note: type is unsigned */
|
||||
(m->in_type < FILE_MAGICSIZE) ? ms->magic_file_names[m->in_type] : "*bad*");
|
||||
if (m->in_op & FILE_OPINVERSE)
|
||||
(void)fputc('~', stderr);
|
||||
(void)eprintf("%c%u),",
|
||||
((m->in_op & FILE_OPS_MASK) < SZOF(optyp)) ? optyp[m->in_op & FILE_OPS_MASK] : '?',
|
||||
m->in_offset);
|
||||
}
|
||||
(void)eprintf(" %s%s", (m->flag & UNSIGNED) ? "u" : "",
|
||||
/* Note: type is unsigned */
|
||||
(m->type < FILE_MAGICSIZE) ? ms->magic_file_names[m->type] : "*bad*");
|
||||
if (m->mask_op & FILE_OPINVERSE)
|
||||
(void)fputc('~', stderr);
|
||||
|
||||
if (MAGIC_IS_STRING(m->type)) {
|
||||
if (m->str_flags) {
|
||||
(void)fputc('/', stderr);
|
||||
if (m->str_flags & STRING_COMPACT_BLANK)
|
||||
(void)fputc(CHAR_COMPACT_BLANK, stderr);
|
||||
if (m->str_flags & STRING_COMPACT_OPTIONAL_BLANK)
|
||||
(void)fputc(CHAR_COMPACT_OPTIONAL_BLANK,
|
||||
stderr);
|
||||
if (m->str_flags & STRING_IGNORE_LOWERCASE)
|
||||
(void)fputc(CHAR_IGNORE_LOWERCASE, stderr);
|
||||
if (m->str_flags & STRING_IGNORE_UPPERCASE)
|
||||
(void)fputc(CHAR_IGNORE_UPPERCASE, stderr);
|
||||
if (m->str_flags & REGEX_OFFSET_START)
|
||||
(void)fputc(CHAR_REGEX_OFFSET_START, stderr);
|
||||
}
|
||||
if (m->str_range)
|
||||
(void)eprintf("/%u", m->str_range);
|
||||
} else {
|
||||
if ((m->mask_op & FILE_OPS_MASK) < SZOF(optyp))
|
||||
(void)fputc(optyp[m->mask_op & FILE_OPS_MASK], stderr);
|
||||
else
|
||||
(void)fputc('?', stderr);
|
||||
|
||||
if (m->num_mask)
|
||||
(void)eprintf("%08" PFMT64x, (ut64)m->num_mask);
|
||||
}
|
||||
(void)eprintf(",%c", m->reln);
|
||||
|
||||
if (m->reln != 'x') {
|
||||
switch (m->type) {
|
||||
case FILE_BYTE:
|
||||
case FILE_SHORT:
|
||||
case FILE_LONG:
|
||||
case FILE_LESHORT:
|
||||
case FILE_LELONG:
|
||||
case FILE_MELONG:
|
||||
case FILE_BESHORT:
|
||||
case FILE_BELONG:
|
||||
(void)eprintf("%d", m->value.l);
|
||||
break;
|
||||
case FILE_BEQUAD:
|
||||
case FILE_LEQUAD:
|
||||
case FILE_QUAD:
|
||||
(void)eprintf("%" PFMT64d, (ut64)m->value.q);
|
||||
break;
|
||||
case FILE_PSTRING:
|
||||
case FILE_STRING:
|
||||
case FILE_REGEX:
|
||||
case FILE_BESTRING16:
|
||||
case FILE_LESTRING16:
|
||||
case FILE_SEARCH:
|
||||
file_showstr(stderr, m->value.s, (size_t)m->vallen);
|
||||
break;
|
||||
case FILE_DATE:
|
||||
case FILE_LEDATE:
|
||||
case FILE_BEDATE:
|
||||
case FILE_MEDATE:
|
||||
(void)eprintf("%s,",
|
||||
file_fmttime(m->value.l, 1, pp));
|
||||
break;
|
||||
case FILE_LDATE:
|
||||
case FILE_LELDATE:
|
||||
case FILE_BELDATE:
|
||||
case FILE_MELDATE:
|
||||
(void)eprintf("%s,",
|
||||
file_fmttime(m->value.l, 0, pp));
|
||||
break;
|
||||
case FILE_QDATE:
|
||||
case FILE_LEQDATE:
|
||||
case FILE_BEQDATE:
|
||||
(void)eprintf("%s,",
|
||||
file_fmttime((ut32)m->value.q, 1, pp));
|
||||
break;
|
||||
case FILE_QLDATE:
|
||||
case FILE_LEQLDATE:
|
||||
case FILE_BEQLDATE:
|
||||
(void)eprintf("%s,",
|
||||
file_fmttime((ut32)m->value.q, 0, pp));
|
||||
break;
|
||||
case FILE_FLOAT:
|
||||
case FILE_BEFLOAT:
|
||||
case FILE_LEFLOAT:
|
||||
(void)eprintf("%G", m->value.f);
|
||||
break;
|
||||
case FILE_DOUBLE:
|
||||
case FILE_BEDOUBLE:
|
||||
case FILE_LEDOUBLE:
|
||||
(void)eprintf("%G", m->value.d);
|
||||
break;
|
||||
case FILE_DEFAULT:
|
||||
/* XXX - do anything here? */
|
||||
break;
|
||||
default:
|
||||
(void)fputs("*bad*", stderr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
(void)eprintf(",\"%s\"]\n", m->desc);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*VARARGS*/
|
||||
void file_magwarn(struct rz_magic_set *ms, const char *f, ...) {
|
||||
va_list va;
|
||||
|
||||
/* cuz we use stdout for most, stderr here */
|
||||
(void)fflush(stdout);
|
||||
|
||||
if (ms->file)
|
||||
(void)eprintf("%s, %lu: ", ms->file,
|
||||
(unsigned long)ms->line);
|
||||
(void)eprintf("Warning: ");
|
||||
va_start(va, f);
|
||||
(void)vfprintf(stderr, f, va);
|
||||
va_end(va);
|
||||
(void)fputc('\n', stderr);
|
||||
}
|
||||
|
||||
const char *file_fmttime(ut32 v, int local, char *pp) {
|
||||
time_t t = (time_t)v;
|
||||
struct tm *tm;
|
||||
struct tm timestruct;
|
||||
|
||||
if (local) {
|
||||
rz_ctime_r(&t, pp);
|
||||
} else {
|
||||
#ifndef HAVE_DAYLIGHT
|
||||
static int daylight = 0;
|
||||
#ifdef HAVE_TM_ISDST
|
||||
static time_t now = (time_t)0;
|
||||
|
||||
if (now == (time_t)0) {
|
||||
struct tm *tm1;
|
||||
(void)time(&now);
|
||||
tm1 = rz_localtime_r(&now, ×truct);
|
||||
if (!tm1)
|
||||
return "*Invalid time*";
|
||||
daylight = tm1->tm_isdst;
|
||||
}
|
||||
#endif /* HAVE_TM_ISDST */
|
||||
#endif /* HAVE_DAYLIGHT */
|
||||
if (daylight)
|
||||
t += 3600;
|
||||
tm = rz_gmtime_r(&t, ×truct);
|
||||
if (!tm)
|
||||
return "*Invalid time*";
|
||||
rz_asctime_r(tm, pp);
|
||||
}
|
||||
|
||||
pp[strcspn(pp, "\n")] = '\0';
|
||||
return pp;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1,12 +1,8 @@
|
|||
rz_magic_sources = [
|
||||
'apprentice.c',
|
||||
'ascmagic.c',
|
||||
'fsmagic.c',
|
||||
'funcs.c',
|
||||
'is_tar.c',
|
||||
'magic.c',
|
||||
# XXX not used? 'print.c',
|
||||
'softmagic.c'
|
||||
'magic-common.c',
|
||||
'magic-load.c',
|
||||
'magic-test.c',
|
||||
'magic.c'
|
||||
]
|
||||
|
||||
rz_magic_deps = [rz_util_dep]
|
||||
|
|
|
|||
|
|
@ -1,180 +0,0 @@
|
|||
/* $OpenBSD: names.h,v 1.8 2009/04/24 18:54:34 chl Exp $ */
|
||||
/*
|
||||
* Copyright (c) Ian F. Darwin 1986-1995.
|
||||
* Software written by Ian F. Darwin and others;
|
||||
* maintained 1995-present by Christos Zoulas and others.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice immediately at the beginning of the file, without modification,
|
||||
* this list of conditions, and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* Names.h - names and types used by ascmagic in file(1).
|
||||
* These tokens are here because they can appear anywhere in
|
||||
* the first HOWMANY bytes, while tokens in MAGIC must
|
||||
* appear at fixed offsets into the file. Don't make HOWMANY
|
||||
* too high unless you have a very fast CPU.
|
||||
*
|
||||
* $Id: names.h,v 1.8 2009/04/24 18:54:34 chl Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
modified by Chris Lowth - 9 April 2000
|
||||
to add mime type strings to the types table.
|
||||
*/
|
||||
|
||||
/* these types are used to index the table 'types': keep em in sync! */
|
||||
#define L_C 0 /* first and foremost on UNIX */
|
||||
#define L_CC 1 /* Bjarne's postincrement */
|
||||
#define L_MAKE 2 /* Makefiles */
|
||||
#define L_PLI 3 /* PL/1 */
|
||||
#define L_MACH 4 /* some kinda assembler */
|
||||
#define L_ENG 5 /* English */
|
||||
#define L_PAS 6 /* Pascal */
|
||||
#define L_MAIL 7 /* Electronic mail */
|
||||
#define L_NEWS 8 /* Usenet Netnews */
|
||||
#define L_JAVA 9 /* Java code */
|
||||
#define L_HTML 10 /* HTML */
|
||||
#define L_BCPL 11 /* BCPL */
|
||||
#define L_M4 12 /* M4 */
|
||||
#define L_PO 13 /* PO */
|
||||
|
||||
static const struct {
|
||||
char human[48];
|
||||
char mime[16];
|
||||
} types[] = {
|
||||
{
|
||||
"C program",
|
||||
"text/x-c",
|
||||
},
|
||||
{ "C++ program", "text/x-c++" },
|
||||
{ "make commands", "text/x-makefile" },
|
||||
{ "PL/1 program", "text/x-pl1" },
|
||||
{ "assembler program", "text/x-asm" },
|
||||
{ "English", "text/plain" },
|
||||
{ "Pascal program", "text/x-pascal" },
|
||||
{ "mail", "text/x-mail" },
|
||||
{ "news", "text/x-news" },
|
||||
{ "Java program", "text/x-java" },
|
||||
{
|
||||
"HTML document",
|
||||
"text/html",
|
||||
},
|
||||
{ "BCPL program", "text/x-bcpl" },
|
||||
{ "M4 macro language pre-processor", "text/x-m4" },
|
||||
{ "PO (gettext message catalogue)", "text/x-po" },
|
||||
{ "cannot happen error on names.h/types", "error/x-error" }
|
||||
};
|
||||
|
||||
/*
|
||||
* XXX - how should we distinguish Java from C++?
|
||||
* The trick used in a Debian snapshot, of having "extends" or "implements"
|
||||
* as tags for Java, doesn't work very well, given that those keywords
|
||||
* are often preceded by "class", which flags it as C++.
|
||||
*
|
||||
* Perhaps we need to be able to say
|
||||
*
|
||||
* If "class" then
|
||||
*
|
||||
* if "extends" or "implements" then
|
||||
* Java
|
||||
* else
|
||||
* C++
|
||||
* endif
|
||||
*
|
||||
* Or should we use other keywords, such as "package" or "import"?
|
||||
* Unfortunately, Ada95 uses "package", and Modula-3 uses "import",
|
||||
* although I infer from the language spec at
|
||||
*
|
||||
* http://www.research.digital.com/SRC/m3defn/html/m3.html
|
||||
*
|
||||
* that Modula-3 uses "IMPORT" rather than "import", i.e. it must be
|
||||
* in all caps.
|
||||
*
|
||||
* So, for now, we go with "import". We must put it before the C++
|
||||
* stuff, so that we don't misidentify Java as C++. Not using "package"
|
||||
* means we won't identify stuff that defines a package but imports
|
||||
* nothing; hopefully, very little Java code imports nothing (one of the
|
||||
* reasons for doing OO programming is to import as much as possible
|
||||
* and write only what you need to, right?).
|
||||
*
|
||||
* Unfortunately, "import" may cause us to misidentify English text
|
||||
* as Java, as it comes after "the" and "The". Perhaps we need a fancier
|
||||
* heuristic to identify Java?
|
||||
*/
|
||||
static const struct names {
|
||||
char name[14];
|
||||
short type;
|
||||
} names[] = {
|
||||
/* These must be sorted by eye for optimal hit rate */
|
||||
/* Add to this list only after substantial meditation */
|
||||
{ "msgid", L_PO },
|
||||
{ "dnl", L_M4 },
|
||||
{ "import", L_JAVA },
|
||||
{ "\"libhdr\"", L_BCPL },
|
||||
{ "\"LIBHDR\"", L_BCPL },
|
||||
{ "//", L_CC },
|
||||
{ "template", L_CC },
|
||||
{ "virtual", L_CC },
|
||||
{ "class", L_CC },
|
||||
{ "public:", L_CC },
|
||||
{ "private:", L_CC },
|
||||
{ "/*", L_C }, /* must precede "The", "the", etc. */
|
||||
{ "#include", L_C },
|
||||
{ "char", L_C },
|
||||
{ "The", L_ENG },
|
||||
{ "the", L_ENG },
|
||||
{ "double", L_C },
|
||||
{ "extern", L_C },
|
||||
{ "float", L_C },
|
||||
{ "struct", L_C },
|
||||
{ "union", L_C },
|
||||
{ "CFLAGS", L_MAKE },
|
||||
{ "LDFLAGS", L_MAKE },
|
||||
{ "all:", L_MAKE },
|
||||
{ ".PRECIOUS", L_MAKE },
|
||||
{ ".ascii", L_MACH },
|
||||
{ ".asciiz", L_MACH },
|
||||
{ ".byte", L_MACH },
|
||||
{ ".even", L_MACH },
|
||||
{ ".globl", L_MACH },
|
||||
{ ".text", L_MACH },
|
||||
{ "clr", L_MACH },
|
||||
{ "(input,", L_PAS },
|
||||
{ "program", L_PAS },
|
||||
{ "record", L_PAS },
|
||||
{ "dcl", L_PLI },
|
||||
{ "Received:", L_MAIL },
|
||||
{ ">From", L_MAIL },
|
||||
{ "Return-Path:", L_MAIL },
|
||||
{ "Cc:", L_MAIL },
|
||||
{ "Newsgroups:", L_NEWS },
|
||||
{ "Path:", L_NEWS },
|
||||
{ "Organization:", L_NEWS },
|
||||
{ "href=", L_HTML },
|
||||
{ "HREF=", L_HTML },
|
||||
{ "<body", L_HTML },
|
||||
{ "<BODY", L_HTML },
|
||||
{ "<html", L_HTML },
|
||||
{ "<HTML", L_HTML },
|
||||
{ "<!--", L_HTML },
|
||||
};
|
||||
#define NNAMES (sizeof(names) / sizeof(struct names))
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
/* $OpenBSD: patchlevel.h,v 1.9 2009/04/24 18:54:34 chl Exp $ */
|
||||
|
||||
#define FILE_VERSION_MAJOR 4
|
||||
#define patchlevel 24
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,74 +0,0 @@
|
|||
/* $OpenBSD: tar.h,v 1.7 2009/04/24 18:54:34 chl Exp $ */
|
||||
/*
|
||||
* Copyright (c) Ian F. Darwin 1986-1995.
|
||||
* Software written by Ian F. Darwin and others;
|
||||
* maintained 1995-present by Christos Zoulas and others.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice immediately at the beginning of the file, without modification,
|
||||
* this list of conditions, and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* Header file for public domain tar (tape archive) program.
|
||||
*
|
||||
* @(#)tar.h 1.20 86/10/29 Public Domain.
|
||||
*
|
||||
* Created 25 August 1985 by John Gilmore, ihnp4!hoptoad!gnu.
|
||||
*
|
||||
* $Id: tar.h,v 1.7 2009/04/24 18:54:34 chl Exp $ # checkin only
|
||||
*/
|
||||
|
||||
/*
|
||||
* Header block on tape.
|
||||
*
|
||||
* I'm going to use traditional DP naming conventions here.
|
||||
* A "block" is a big chunk of stuff that we do I/O on.
|
||||
* A "record" is a piece of info that we care about.
|
||||
* Typically many "record"s fit into a "block".
|
||||
*/
|
||||
#define RECORDSIZE 512
|
||||
#define NAMSIZ 100
|
||||
#define TUNMLEN 32
|
||||
#define TGNMLEN 32
|
||||
|
||||
union record {
|
||||
char charptr[RECORDSIZE];
|
||||
struct header {
|
||||
char name[NAMSIZ];
|
||||
char mode[8];
|
||||
char uid[8];
|
||||
char gid[8];
|
||||
char size[12];
|
||||
char mtime[12];
|
||||
char chksum[8];
|
||||
char linkflag;
|
||||
char linkname[NAMSIZ];
|
||||
char magic[8];
|
||||
char uname[TUNMLEN];
|
||||
char gname[TGNMLEN];
|
||||
char devmajor[8];
|
||||
char devminor[8];
|
||||
} header;
|
||||
};
|
||||
|
||||
/* The magic field is filled with this if uname and gname are valid. */
|
||||
#define TMAGIC "ustar" /* 5 chars and a null */
|
||||
#define GNUTMAGIC "ustar " /* 7 chars and a null */
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
#include "search_internal.h"
|
||||
|
||||
static RzMagic *setup_magic_instance(const char *magic_dir) {
|
||||
RzMagic *magic = rz_magic_new(0);
|
||||
RzMagic *magic = rz_magic_new();
|
||||
if (!magic) {
|
||||
RZ_LOG_ERROR("search: cannot initialize RzMagic.\n");
|
||||
return NULL;
|
||||
|
|
@ -42,12 +42,13 @@ static bool magic_find(RzSearchFindOpt *fopt, void *user, ut64 address, const Rz
|
|||
for (size_t i = 0; i < size; i += 2) {
|
||||
RAW_BUF_ITER_ALIGN(fopt, address, i);
|
||||
size_t leftovers = size - i;
|
||||
const char *match = rz_magic_buffer(magic, raw_buf + i, leftovers);
|
||||
char *match = rz_magic_buffer(magic, raw_buf + i, leftovers);
|
||||
if (!match) {
|
||||
continue;
|
||||
}
|
||||
|
||||
RzSearchHitDetail *detail = rz_search_hit_detail_string_new(match);
|
||||
free(match);
|
||||
if (!detail) {
|
||||
RZ_LOG_ERROR("search: failed to allocate magic hit detail.\n");
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -992,12 +992,14 @@ RZ_API size_t rz_str_ncpy(char *dst, const char *src, size_t dst_size) {
|
|||
* This API behaves like strlcat.
|
||||
*/
|
||||
RZ_API size_t rz_str_ncat(RZ_NONNULL RZ_OUT char *dst, RZ_NONNULL const char *src, size_t dst_size) {
|
||||
|
||||
rz_return_val_if_fail(dst && src, 0);
|
||||
|
||||
// do not do anything if dst_size is 0
|
||||
if (dst_size == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if HAVE_STRLCAT
|
||||
return strlcat(dst, src, dst_size);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -658,7 +658,6 @@ ARGS=-n
|
|||
CMDS=pm bins/src/olf.magic
|
||||
EXPECT=<<EOF
|
||||
0x00000000 OLF 32-bit LSB
|
||||
0x00001d70 very short file (no magic)
|
||||
EOF
|
||||
RUN
|
||||
|
||||
|
|
@ -689,7 +688,6 @@ FILE=bins/src/hello.c
|
|||
CMDS=pm
|
||||
EXPECT=<<EOF
|
||||
0x00000000 C source code
|
||||
0x00000048 very short file (no magic)
|
||||
EOF
|
||||
RUN
|
||||
|
||||
|
|
@ -716,7 +714,7 @@ FILE=bins/mach0/fatmach0-3true
|
|||
ARGS=-n
|
||||
CMDS=pm
|
||||
EXPECT=<<EOF
|
||||
0x00000000 Fat-Mach-O
|
||||
0x00000000 Fat-Mach-O version 3.0 Mach-O fat file with 3 architectures
|
||||
0x00001000 Mach-O
|
||||
0x00003140 MacOS Deteched Code Signature
|
||||
0x00005000 Mach-O
|
||||
|
|
@ -726,13 +724,30 @@ EXPECT=<<EOF
|
|||
EOF
|
||||
RUN
|
||||
|
||||
NAME=pm perl/exam.pm
|
||||
FILE=bins/perl/exam.pm
|
||||
ARGS=-n
|
||||
CMDS=pm
|
||||
EXPECT=<<EOF
|
||||
0x00000000 Perl5 module source text
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=pm perl/exam.pl
|
||||
FILE=bins/perl/exam.pl
|
||||
ARGS=-n
|
||||
CMDS=pm
|
||||
EXPECT=<<EOF
|
||||
0x00000000 Perl script text executable
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=pm java/Hello.class
|
||||
FILE=bins/java/Hello.class
|
||||
ARGS=-n
|
||||
CMDS=pm
|
||||
EXPECT=<<EOF
|
||||
0x00000000 Java CLASS
|
||||
0x000002d4 very short file (no magic)
|
||||
EOF
|
||||
RUN
|
||||
|
||||
|
|
|
|||
|
|
@ -95,7 +95,6 @@ FILE==
|
|||
CMDS=!!rz-find -i bins/elf/ioli/crackme0x00
|
||||
EXPECT=<<EOF
|
||||
0x00000000 ELF 32-bit LSB executable, Intel 80386, version 1
|
||||
0x00001d70 very short file (no magic)
|
||||
EOF
|
||||
RUN
|
||||
|
||||
|
|
@ -104,7 +103,6 @@ FILE==
|
|||
CMDS=!!rz-find -m bins/elf/ioli/crackme0x00
|
||||
EXPECT=<<EOF
|
||||
0x00000000 0 hit.magic.0 ELF 32-bit LSB executable, Intel 80386, version 1
|
||||
0x00001d70 0 hit.magic.1 very short file (no magic)
|
||||
EOF
|
||||
RUN
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue