summaryrefslogtreecommitdiffstats
path: root/contrib/file/funcs.c
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2009-05-04 00:37:44 +0000
committerobrien <obrien@FreeBSD.org>2009-05-04 00:37:44 +0000
commita8abfd3eba1e14d222768ebf8316ec02e56af39a (patch)
tree12756817ab8bc4334652c625c7731c9e7fd0cefc /contrib/file/funcs.c
parent3222e9c2cde262a2a5a46f45f0a1e06623f69433 (diff)
parent3d89d1fbe920995209cda59ff0fd5096b6471133 (diff)
downloadFreeBSD-src-a8abfd3eba1e14d222768ebf8316ec02e56af39a.zip
FreeBSD-src-a8abfd3eba1e14d222768ebf8316ec02e56af39a.tar.gz
Merge vendor/file/dist@191739, bringing FILE 5.00 to 8-CURRENT.
Diffstat (limited to 'contrib/file/funcs.c')
-rw-r--r--contrib/file/funcs.c161
1 files changed, 116 insertions, 45 deletions
diff --git a/contrib/file/funcs.c b/contrib/file/funcs.c
index af98605..af10688 100644
--- a/contrib/file/funcs.c
+++ b/contrib/file/funcs.c
@@ -1,7 +1,7 @@
/*
* 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:
@@ -11,7 +11,7 @@
* 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
@@ -25,6 +25,11 @@
* SUCH DAMAGE.
*/
#include "file.h"
+
+#ifndef lint
+FILE_RCSID("@(#)$File: funcs.c,v 1.51 2008/11/07 18:57:28 christos Exp $")
+#endif /* lint */
+
#include "magic.h"
#include <stdarg.h>
#include <stdlib.h>
@@ -40,10 +45,6 @@
#include <limits.h>
#endif
-#ifndef lint
-FILE_RCSID("@(#)$File: funcs.c,v 1.44 2008/07/16 18:00:57 christos Exp $")
-#endif /* lint */
-
#ifndef SIZE_MAX
#define SIZE_MAX ((size_t)~0)
#endif
@@ -97,17 +98,17 @@ file_error_core(struct magic_set *ms, int error, const char *f, va_list va,
uint32_t lineno)
{
/* Only the first error is ok */
- if (ms->haderr)
+ if (ms->event_flags & EVENT_HAD_ERR)
return;
if (lineno != 0) {
free(ms->o.buf);
ms->o.buf = NULL;
file_printf(ms, "line %u: ", lineno);
}
- file_vprintf(ms, f, va);
+ file_vprintf(ms, f, va);
if (error > 0)
file_printf(ms, " (%s)", strerror(error));
- ms->haderr++;
+ ms->event_flags |= EVENT_HAD_ERR;
ms->error = error;
}
@@ -157,9 +158,16 @@ protected int
file_buffer(struct magic_set *ms, int fd, const char *inname, const void *buf,
size_t nb)
{
- int m;
+ int m = 0, rv = 0, looks_text = 0;
int mime = ms->flags & MAGIC_MIME;
const unsigned char *ubuf = CAST(const unsigned char *, buf);
+ unichar *u8buf = NULL;
+ size_t ulen;
+ const char *code = NULL;
+ const char *code_mime = "binary";
+ const char *type = NULL;
+
+
if (nb == 0) {
if ((!mime || (mime & MAGIC_MIME_TYPE)) &&
@@ -175,6 +183,11 @@ file_buffer(struct magic_set *ms, int fd, const char *inname, const void *buf,
return 1;
}
+ if ((ms->flags & MAGIC_NO_CHECK_ENCODING) == 0) {
+ looks_text = file_encoding(ms, ubuf, nb, &u8buf, &ulen,
+ &code, &code_mime, &type);
+ }
+
#ifdef __EMX__
if ((ms->flags & MAGIC_NO_CHECK_APPTYPE) == 0 && inname) {
switch (file_os2_apptype(ms, inname, buf, nb)) {
@@ -189,41 +202,96 @@ file_buffer(struct magic_set *ms, int fd, const char *inname, const void *buf,
#endif
/* try compression stuff */
- if ((ms->flags & MAGIC_NO_CHECK_COMPRESS) != 0 ||
- (m = file_zmagic(ms, fd, inname, ubuf, nb)) == 0) {
- /* Check if we have a tar file */
- if ((ms->flags & MAGIC_NO_CHECK_TAR) != 0 ||
- (m = file_is_tar(ms, ubuf, nb)) == 0) {
- /* try tests in /etc/magic (or surrogate magic file) */
- if ((ms->flags & MAGIC_NO_CHECK_SOFT) != 0 ||
- (m = file_softmagic(ms, ubuf, nb, BINTEST)) == 0) {
- /* try known keywords, check whether it is ASCII */
- if ((ms->flags & MAGIC_NO_CHECK_ASCII) != 0 ||
- (m = file_ascmagic(ms, ubuf, nb)) == 0) {
- /* abandon hope, all ye who remain here */
- if ((!mime || (mime & MAGIC_MIME_TYPE)) &&
- file_printf(ms, mime ? "application/octet-stream" :
- "data") == -1)
- return -1;
- m = 1;
- }
+ if ((ms->flags & MAGIC_NO_CHECK_COMPRESS) == 0)
+ if ((m = file_zmagic(ms, fd, inname, ubuf, nb)) != 0) {
+ if ((ms->flags & MAGIC_DEBUG) != 0)
+ (void)fprintf(stderr, "zmagic %d\n", m);
+ goto done;
}
- }
- }
+
+ /* Check if we have a tar file */
+ if ((ms->flags & MAGIC_NO_CHECK_TAR) == 0)
+ if ((m = file_is_tar(ms, ubuf, nb)) != 0) {
+ if ((ms->flags & MAGIC_DEBUG) != 0)
+ (void)fprintf(stderr, "tar %d\n", m);
+ goto done;
+ }
+
+ /* Check if we have a CDF file */
+ if ((ms->flags & MAGIC_NO_CHECK_CDF) == 0)
+ if ((m = file_trycdf(ms, fd, ubuf, nb)) != 0) {
+ if ((ms->flags & MAGIC_DEBUG) != 0)
+ (void)fprintf(stderr, "cdf %d\n", m);
+ goto done;
+ }
+
+ /* try soft magic tests */
+ if ((ms->flags & MAGIC_NO_CHECK_SOFT) == 0)
+ if ((m = file_softmagic(ms, ubuf, nb, BINTEST)) != 0) {
+ if ((ms->flags & MAGIC_DEBUG) != 0)
+ (void)fprintf(stderr, "softmagic %d\n", m);
#ifdef BUILTIN_ELF
- if ((ms->flags & MAGIC_NO_CHECK_ELF) == 0 && m == 1 &&
- nb > 5 && fd != -1) {
- /*
- * We matched something in the file, so this *might*
- * be an ELF file, and the file is at least 5 bytes
- * long, so if it's an ELF file it has at least one
- * byte past the ELF magic number - try extracting
- * information from the ELF headers that cannot easily
- * be extracted with rules in the magic file.
- */
- (void)file_tryelf(ms, fd, ubuf, nb);
- }
+ if ((ms->flags & MAGIC_NO_CHECK_ELF) == 0 && m == 1 &&
+ nb > 5 && fd != -1) {
+ /*
+ * We matched something in the file, so this
+ * *might* be an ELF file, and the file is at
+ * least 5 bytes long, so if it's an ELF file
+ * it has at least one byte past the ELF magic
+ * number - try extracting information from the
+ * ELF headers that cannot easily * be
+ * extracted with rules in the magic file.
+ */
+ if ((m = file_tryelf(ms, fd, ubuf, nb)) != 0)
+ if ((ms->flags & MAGIC_DEBUG) != 0)
+ (void)fprintf(stderr,
+ "elf %d\n", m);
+ }
#endif
+ goto done;
+ }
+
+ /* try text properties (and possibly text tokens) */
+ if ((ms->flags & MAGIC_NO_CHECK_TEXT) == 0) {
+
+ if ((m = file_ascmagic(ms, ubuf, nb)) != 0) {
+ if ((ms->flags & MAGIC_DEBUG) != 0)
+ (void)fprintf(stderr, "ascmagic %d\n", m);
+ goto done;
+ }
+
+ /* try to discover text encoding */
+ if ((ms->flags & MAGIC_NO_CHECK_ENCODING) == 0) {
+ if (looks_text == 0)
+ if ((m = file_ascmagic_with_encoding( ms, ubuf,
+ nb, u8buf, ulen, code, type)) != 0) {
+ if ((ms->flags & MAGIC_DEBUG) != 0)
+ (void)fprintf(stderr,
+ "ascmagic/enc %d\n", m);
+ goto done;
+ }
+ }
+ }
+
+ /* give up */
+ m = 1;
+ if ((!mime || (mime & MAGIC_MIME_TYPE)) &&
+ file_printf(ms, mime ? "application/octet-stream" : "data") == -1) {
+ rv = -1;
+ }
+ done:
+ if ((ms->flags & MAGIC_MIME_ENCODING) != 0) {
+ if (ms->flags & MAGIC_MIME_TYPE)
+ if (file_printf(ms, "; charset=") == -1)
+ rv = -1;
+ if (file_printf(ms, "%s", code_mime) == -1)
+ rv = -1;
+ }
+ if (u8buf)
+ free(u8buf);
+ if (rv)
+ return rv;
+
return m;
}
#endif
@@ -236,7 +304,7 @@ file_reset(struct magic_set *ms)
return -1;
}
ms->o.buf = NULL;
- ms->haderr = 0;
+ ms->event_flags &= ~EVENT_HAD_ERR;
ms->error = -1;
return 0;
}
@@ -255,12 +323,15 @@ file_getbuffer(struct magic_set *ms)
char *pbuf, *op, *np;
size_t psize, len;
- if (ms->haderr)
+ if (ms->event_flags & EVENT_HAD_ERR)
return NULL;
if (ms->flags & MAGIC_RAW)
return ms->o.buf;
+ if (ms->o.buf == NULL)
+ return NULL;
+
/* * 4 is for octal representation, + 1 is for NUL */
len = strlen(ms->o.buf);
if (len > (SIZE_MAX - 1) / 4) {
@@ -315,7 +386,7 @@ file_getbuffer(struct magic_set *ms)
for (np = ms->o.pbuf, op = ms->o.buf; *op; op++) {
if (isprint((unsigned char)*op)) {
- *np++ = *op;
+ *np++ = *op;
} else {
OCTALIFY(np, op);
}
OpenPOWER on IntegriCloud