summaryrefslogtreecommitdiff
path: root/src/funcs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/funcs.c')
-rw-r--r--src/funcs.c131
1 files changed, 88 insertions, 43 deletions
diff --git a/src/funcs.c b/src/funcs.c
index a60ccaa..d7a18f4 100644
--- a/src/funcs.c
+++ b/src/funcs.c
@@ -27,7 +27,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: funcs.c,v 1.79 2014/12/16 20:52:49 christos Exp $")
+FILE_RCSID("@(#)$File: funcs.c,v 1.93 2017/08/28 13:39:18 christos Exp $")
#endif /* lint */
#include "magic.h"
@@ -76,7 +76,7 @@ file_vprintf(struct magic_set *ms, const char *fmt, va_list ap)
ms->o.buf = buf;
return 0;
out:
- file_error(ms, errno, "vasprintf failed");
+ fprintf(stderr, "vasprintf failed (%s)", strerror(errno));
return -1;
}
@@ -107,8 +107,10 @@ file_error_core(struct magic_set *ms, int error, const char *f, va_list va,
if (lineno != 0) {
free(ms->o.buf);
ms->o.buf = NULL;
- file_printf(ms, "line %" SIZE_T_FORMAT "u: ", lineno);
+ file_printf(ms, "line %" SIZE_T_FORMAT "u:", lineno);
}
+ if (ms->o.buf && *ms->o.buf)
+ file_printf(ms, " ");
file_vprintf(ms, f, va);
if (error > 0)
file_printf(ms, " (%s)", strerror(error));
@@ -159,12 +161,23 @@ file_badread(struct magic_set *ms)
}
#ifndef COMPILE_ONLY
+
+static int
+checkdone(struct magic_set *ms, int *rv)
+{
+ if ((ms->flags & MAGIC_CONTINUE) == 0)
+ return 1;
+ if (file_printf(ms, "\n- ") == -1)
+ *rv = -1;
+ return 0;
+}
+
+/*ARGSUSED*/
protected int
-file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((unused)),
+file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((__unused__)),
const void *buf, size_t nb)
{
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;
@@ -190,7 +203,10 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((unu
#ifdef __EMX__
if ((ms->flags & MAGIC_NO_CHECK_APPTYPE) == 0 && inname) {
- switch (file_os2_apptype(ms, inname, buf, nb)) {
+ m = file_os2_apptype(ms, inname, buf, nb);
+ if ((ms->flags & MAGIC_DEBUG) != 0)
+ (void)fprintf(stderr, "[try os2_apptype %d]\n", m);
+ switch (m) {
case -1:
return -1;
case 0:
@@ -202,35 +218,44 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((unu
#endif
#if HAVE_FORK
/* try compression stuff */
- 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);
+ if ((ms->flags & MAGIC_NO_CHECK_COMPRESS) == 0) {
+ m = file_zmagic(ms, fd, inname, ubuf, nb);
+ if ((ms->flags & MAGIC_DEBUG) != 0)
+ (void)fprintf(stderr, "[try zmagic %d]\n", m);
+ if (m) {
goto done_encoding;
}
+ }
#endif
/* 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;
+ if ((ms->flags & MAGIC_NO_CHECK_TAR) == 0) {
+ m = file_is_tar(ms, ubuf, nb);
+ if ((ms->flags & MAGIC_DEBUG) != 0)
+ (void)fprintf(stderr, "[try tar %d]\n", m);
+ if (m) {
+ if (checkdone(ms, &rv))
+ 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;
+ if ((ms->flags & MAGIC_NO_CHECK_CDF) == 0) {
+ m = file_trycdf(ms, fd, ubuf, nb);
+ if ((ms->flags & MAGIC_DEBUG) != 0)
+ (void)fprintf(stderr, "[try cdf %d]\n", m);
+ if (m) {
+ if (checkdone(ms, &rv))
+ goto done;
}
+ }
/* try soft magic tests */
- if ((ms->flags & MAGIC_NO_CHECK_SOFT) == 0)
- if ((m = file_softmagic(ms, ubuf, nb, 0, NULL, BINTEST,
- looks_text)) != 0) {
- if ((ms->flags & MAGIC_DEBUG) != 0)
- (void)fprintf(stderr, "softmagic %d\n", m);
+ if ((ms->flags & MAGIC_NO_CHECK_SOFT) == 0) {
+ m = file_softmagic(ms, ubuf, nb, NULL, NULL, BINTEST,
+ looks_text);
+ if ((ms->flags & MAGIC_DEBUG) != 0)
+ (void)fprintf(stderr, "[try softmagic %d]\n", m);
+ if (m) {
#ifdef BUILTIN_ELF
if ((ms->flags & MAGIC_NO_CHECK_ELF) == 0 && m == 1 &&
nb > 5 && fd != -1) {
@@ -243,31 +268,45 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((unu
* 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);
+ m = file_tryelf(ms, fd, ubuf, nb);
+ if ((ms->flags & MAGIC_DEBUG) != 0)
+ (void)fprintf(stderr, "[try elf %d]\n",
+ m);
}
#endif
- goto done;
+ if (checkdone(ms, &rv))
+ goto done;
}
+ }
/* try text properties */
if ((ms->flags & MAGIC_NO_CHECK_TEXT) == 0) {
- if ((m = file_ascmagic(ms, ubuf, nb, looks_text)) != 0) {
- if ((ms->flags & MAGIC_DEBUG) != 0)
- (void)fprintf(stderr, "ascmagic %d\n", m);
- goto done;
+ m = file_ascmagic(ms, ubuf, nb, looks_text);
+ if ((ms->flags & MAGIC_DEBUG) != 0)
+ (void)fprintf(stderr, "[try ascmagic %d]\n", m);
+ if (m) {
+ if (checkdone(ms, &rv))
+ goto done;
}
}
simple:
/* give up */
m = 1;
- if ((!mime || (mime & MAGIC_MIME_TYPE)) &&
- file_printf(ms, "%s", mime ? type : def) == -1) {
- rv = -1;
+ if (ms->flags & MAGIC_MIME) {
+ if ((ms->flags & MAGIC_MIME_TYPE) &&
+ file_printf(ms, "%s", type) == -1)
+ rv = -1;
+ } else if (ms->flags & MAGIC_APPLE) {
+ if (file_printf(ms, "UNKNUNKN") == -1)
+ rv = -1;
+ } else if (ms->flags & MAGIC_EXTENSION) {
+ if (file_printf(ms, "???") == -1)
+ rv = -1;
+ } else {
+ if (file_printf(ms, "%s", def) == -1)
+ rv = -1;
}
done:
if ((ms->flags & MAGIC_MIME_ENCODING) != 0) {
@@ -289,9 +328,9 @@ simple:
#endif
protected int
-file_reset(struct magic_set *ms)
+file_reset(struct magic_set *ms, int checkloaded)
{
- if (ms->mlist[0] == NULL) {
+ if (checkloaded && ms->mlist[0] == NULL) {
file_error(ms, 0, "no magic files loaded");
return -1;
}
@@ -400,7 +439,7 @@ file_check_mem(struct magic_set *ms, unsigned int level)
size_t len;
if (level >= ms->c.len) {
- len = (ms->c.len += 20) * sizeof(*ms->c.li);
+ len = (ms->c.len = 20 + level) * sizeof(*ms->c.li);
ms->c.li = CAST(struct level_info *, (ms->c.li == NULL) ?
malloc(len) :
realloc(ms->c.li, len));
@@ -457,6 +496,8 @@ file_regcomp(file_regex_t *rx, const char *pat, int flags)
assert(rx->c_lc_ctype != NULL);
rx->old_lc_ctype = uselocale(rx->c_lc_ctype);
assert(rx->old_lc_ctype != NULL);
+#else
+ rx->old_lc_ctype = setlocale(LC_CTYPE, "C");
#endif
rx->pat = pat;
@@ -468,6 +509,8 @@ file_regexec(file_regex_t *rx, const char *str, size_t nmatch,
regmatch_t* pmatch, int eflags)
{
assert(rx->rc == 0);
+ /* XXX: force initialization because glibc does not always do this */
+ memset(pmatch, 0, nmatch * sizeof(*pmatch));
return regexec(&rx->rx, str, nmatch, pmatch, eflags);
}
@@ -479,6 +522,8 @@ file_regfree(file_regex_t *rx)
#ifdef USE_C_LOCALE
(void)uselocale(rx->old_lc_ctype);
freelocale(rx->c_lc_ctype);
+#else
+ (void)setlocale(LC_CTYPE, rx->old_lc_ctype);
#endif
}
@@ -549,9 +594,9 @@ file_printable(char *buf, size_t bufsiz, const char *str)
if (ptr >= eptr - 3)
break;
*ptr++ = '\\';
- *ptr++ = ((*s >> 6) & 7) + '0';
- *ptr++ = ((*s >> 3) & 7) + '0';
- *ptr++ = ((*s >> 0) & 7) + '0';
+ *ptr++ = ((CAST(unsigned int, *s) >> 6) & 7) + '0';
+ *ptr++ = ((CAST(unsigned int, *s) >> 3) & 7) + '0';
+ *ptr++ = ((CAST(unsigned int, *s) >> 0) & 7) + '0';
}
*ptr = '\0';
return buf;