diff options
Diffstat (limited to 'src/funcs.c')
-rw-r--r-- | src/funcs.c | 131 |
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; |