From 670c2bbcffe873a2b8589ed140c12e7923ef20c0 Mon Sep 17 00:00:00 2001 From: Lorry Tar Creator Date: Fri, 2 Jan 2015 20:23:27 +0000 Subject: Imported from /home/lorry/working-area/delta_file/file-5.22.tar.gz. --- src/funcs.c | 181 ++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 139 insertions(+), 42 deletions(-) (limited to 'src/funcs.c') diff --git a/src/funcs.c b/src/funcs.c index 7fc0e5c..a60ccaa 100644 --- a/src/funcs.c +++ b/src/funcs.c @@ -27,10 +27,11 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: funcs.c,v 1.61 2012/10/30 23:11:51 christos Exp $") +FILE_RCSID("@(#)$File: funcs.c,v 1.79 2014/12/16 20:52:49 christos Exp $") #endif /* lint */ #include "magic.h" +#include #include #include #include @@ -58,6 +59,8 @@ file_vprintf(struct magic_set *ms, const char *fmt, va_list ap) int len; char *buf, *newstr; + if (ms->event_flags & EVENT_HAD_ERR) + return 0; len = vasprintf(&buf, fmt, ap); if (len < 0) goto out; @@ -93,6 +96,7 @@ file_printf(struct magic_set *ms, const char *fmt, ...) * error - print best error message possible */ /*VARARGS*/ +__attribute__((__format__(__printf__, 3, 0))) private void file_error_core(struct magic_set *ms, int error, const char *f, va_list va, size_t lineno) @@ -166,27 +170,22 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((unu size_t ulen; const char *code = NULL; const char *code_mime = "binary"; - const char *type = NULL; - - + const char *type = "application/octet-stream"; + const char *def = "data"; + const char *ftype = NULL; if (nb == 0) { - if ((!mime || (mime & MAGIC_MIME_TYPE)) && - file_printf(ms, mime ? "application/x-empty" : - "empty") == -1) - return -1; - return 1; + def = "empty"; + type = "application/x-empty"; + goto simple; } else if (nb == 1) { - if ((!mime || (mime & MAGIC_MIME_TYPE)) && - file_printf(ms, mime ? "application/octet-stream" : - "very short file (no magic)") == -1) - return -1; - return 1; + def = "very short file (no magic)"; + goto simple; } if ((ms->flags & MAGIC_NO_CHECK_ENCODING) == 0) { looks_text = file_encoding(ms, ubuf, nb, &u8buf, &ulen, - &code, &code_mime, &type); + &code, &code_mime, &ftype); } #ifdef __EMX__ @@ -207,7 +206,7 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((unu 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; + goto done_encoding; } #endif /* Check if we have a tar file */ @@ -228,7 +227,7 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((unu /* try soft magic tests */ if ((ms->flags & MAGIC_NO_CHECK_SOFT) == 0) - if ((m = file_softmagic(ms, ubuf, nb, BINTEST, + 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); @@ -261,25 +260,13 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((unu (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, looks_text)) - != 0) { - if ((ms->flags & MAGIC_DEBUG) != 0) - (void)fprintf(stderr, - "ascmagic/enc %d\n", m); - goto done; - } - } } +simple: /* give up */ m = 1; if ((!mime || (mime & MAGIC_MIME_TYPE)) && - file_printf(ms, mime ? "application/octet-stream" : "data") == -1) { + file_printf(ms, "%s", mime ? type : def) == -1) { rv = -1; } done: @@ -290,6 +277,9 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((unu if (file_printf(ms, "%s", code_mime) == -1) rv = -1; } +#if HAVE_FORK + done_encoding: +#endif free(u8buf); if (rv) return rv; @@ -436,26 +426,133 @@ file_printedlen(const struct magic_set *ms) protected int file_replace(struct magic_set *ms, const char *pat, const char *rep) { - regex_t rx; - int rc; + file_regex_t rx; + int rc, rv = -1; - rc = regcomp(&rx, pat, REG_EXTENDED); + rc = file_regcomp(&rx, pat, REG_EXTENDED); if (rc) { - char errmsg[512]; - (void)regerror(rc, &rx, errmsg, sizeof(errmsg)); - file_magerror(ms, "regex error %d, (%s)", rc, errmsg); - return -1; + file_regerror(&rx, rc, ms); } else { regmatch_t rm; int nm = 0; - while (regexec(&rx, ms->o.buf, 1, &rm, 0) == 0) { + while (file_regexec(&rx, ms->o.buf, 1, &rm, 0) == 0) { ms->o.buf[rm.rm_so] = '\0'; if (file_printf(ms, "%s%s", rep, rm.rm_eo != 0 ? ms->o.buf + rm.rm_eo : "") == -1) - return -1; + goto out; nm++; } - regfree(&rx); - return nm; + rv = nm; + } +out: + file_regfree(&rx); + return rv; +} + +protected int +file_regcomp(file_regex_t *rx, const char *pat, int flags) +{ +#ifdef USE_C_LOCALE + rx->c_lc_ctype = newlocale(LC_CTYPE_MASK, "C", 0); + assert(rx->c_lc_ctype != NULL); + rx->old_lc_ctype = uselocale(rx->c_lc_ctype); + assert(rx->old_lc_ctype != NULL); +#endif + rx->pat = pat; + + return rx->rc = regcomp(&rx->rx, pat, flags); +} + +protected int +file_regexec(file_regex_t *rx, const char *str, size_t nmatch, + regmatch_t* pmatch, int eflags) +{ + assert(rx->rc == 0); + return regexec(&rx->rx, str, nmatch, pmatch, eflags); +} + +protected void +file_regfree(file_regex_t *rx) +{ + if (rx->rc == 0) + regfree(&rx->rx); +#ifdef USE_C_LOCALE + (void)uselocale(rx->old_lc_ctype); + freelocale(rx->c_lc_ctype); +#endif +} + +protected void +file_regerror(file_regex_t *rx, int rc, struct magic_set *ms) +{ + char errmsg[512]; + + (void)regerror(rc, &rx->rx, errmsg, sizeof(errmsg)); + file_magerror(ms, "regex error %d for `%s', (%s)", rc, rx->pat, + errmsg); +} + +protected file_pushbuf_t * +file_push_buffer(struct magic_set *ms) +{ + file_pushbuf_t *pb; + + if (ms->event_flags & EVENT_HAD_ERR) + return NULL; + + if ((pb = (CAST(file_pushbuf_t *, malloc(sizeof(*pb))))) == NULL) + return NULL; + + pb->buf = ms->o.buf; + pb->offset = ms->offset; + + ms->o.buf = NULL; + ms->offset = 0; + + return pb; +} + +protected char * +file_pop_buffer(struct magic_set *ms, file_pushbuf_t *pb) +{ + char *rbuf; + + if (ms->event_flags & EVENT_HAD_ERR) { + free(pb->buf); + free(pb); + return NULL; + } + + rbuf = ms->o.buf; + + ms->o.buf = pb->buf; + ms->offset = pb->offset; + + free(pb); + return rbuf; +} + +/* + * convert string to ascii printable format. + */ +protected char * +file_printable(char *buf, size_t bufsiz, const char *str) +{ + char *ptr, *eptr; + const unsigned char *s = (const unsigned char *)str; + + for (ptr = buf, eptr = ptr + bufsiz - 1; ptr < eptr && *s; s++) { + if (isprint(*s)) { + *ptr++ = *s; + continue; + } + if (ptr >= eptr - 3) + break; + *ptr++ = '\\'; + *ptr++ = ((*s >> 6) & 7) + '0'; + *ptr++ = ((*s >> 3) & 7) + '0'; + *ptr++ = ((*s >> 0) & 7) + '0'; } + *ptr = '\0'; + return buf; } -- cgit v1.2.1