diff options
author | obrien <obrien@FreeBSD.org> | 2006-06-19 07:52:15 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2006-06-19 07:52:15 +0000 |
commit | 5c5b299c7d54da4b9c68e95d1f7a230405bd1ac2 (patch) | |
tree | eba3401e66ba997d94604096d6095b69207f5d78 /contrib/file/magic.c | |
parent | df11c7b63d4e785920524068f8f9cbdef5dc08ad (diff) | |
download | FreeBSD-src-5c5b299c7d54da4b9c68e95d1f7a230405bd1ac2.zip FreeBSD-src-5c5b299c7d54da4b9c68e95d1f7a230405bd1ac2.tar.gz |
Virgin import of Christos Zoulas's FILE 4.17.
Diffstat (limited to 'contrib/file/magic.c')
-rw-r--r-- | contrib/file/magic.c | 72 |
1 files changed, 46 insertions, 26 deletions
diff --git a/contrib/file/magic.c b/contrib/file/magic.c index 4516ba8..03d0291 100644 --- a/contrib/file/magic.c +++ b/contrib/file/magic.c @@ -35,7 +35,6 @@ #include <sys/types.h> #include <sys/param.h> /* for MAXPATHLEN */ #include <sys/stat.h> -#include <fcntl.h> /* for open() */ #ifdef QUICK #include <sys/mman.h> #endif @@ -63,7 +62,7 @@ #include "patchlevel.h" #ifndef lint -FILE_RCSID("@(#)$Id: magic.c,v 1.24 2004/09/27 15:28:37 christos Exp $") +FILE_RCSID("@(#)$Id: magic.c,v 1.32 2005/10/17 15:31:10 christos Exp $") #endif /* lint */ #ifdef __EMX__ @@ -76,6 +75,10 @@ private void free_mlist(struct mlist *); private void close_and_restore(const struct magic_set *, const char *, int, const struct stat *); +#ifndef STDIN_FILENO +#define STDIN_FILENO 0 +#endif + public struct magic_set * magic_open(int flags) { @@ -179,8 +182,11 @@ private void close_and_restore(const struct magic_set *ms, const char *name, int fd, const struct stat *sb) { + if (fd == STDIN_FILENO) + return; (void) close(fd); - if (fd != STDIN_FILENO && (ms->flags & MAGIC_PRESERVE_ATIME) != 0) { + + if ((ms->flags & MAGIC_PRESERVE_ATIME) != 0) { /* * Try to restore access, modification times if read it. * This is really *bad* because it will modify the status @@ -211,41 +217,57 @@ public const char * magic_file(struct magic_set *ms, const char *inname) { int fd = 0; - unsigned char buf[HOWMANY+1]; /* one extra for terminating '\0' */ + int rv = -1; + unsigned char *buf; struct stat sb; ssize_t nbytes = 0; /* number of bytes read from a datafile */ - if (file_reset(ms) == -1) + /* + * one extra for terminating '\0', and + * some overlapping space for matches near EOF + */ +#define SLOP (1 + sizeof(union VALUETYPE)) + if ((buf = malloc(HOWMANY + SLOP)) == NULL) return NULL; + if (file_reset(ms) == -1) + goto done; + switch (file_fsmagic(ms, inname, &sb)) { case -1: - return NULL; + goto done; case 0: break; default: - return file_getbuffer(ms); + rv = 0; + goto done; } -#ifndef STDIN_FILENO -#define STDIN_FILENO 0 -#endif if (inname == NULL) fd = STDIN_FILENO; - else if ((fd = open(inname, O_RDONLY)) < 0) { + else if ((fd = open(inname, O_RDONLY|O_BINARY)) < 0) { +#ifdef __CYGWIN__ + char *tmp = alloca(strlen(inname) + 5); + (void)strcat(strcpy(tmp, inname), ".exe"); + if ((fd = open(tmp, O_RDONLY|O_BINARY)) < 0) { +#endif /* We cannot open it, but we were able to stat it. */ if (sb.st_mode & 0222) if (file_printf(ms, "writable, ") == -1) - return NULL; + goto done; if (sb.st_mode & 0111) if (file_printf(ms, "executable, ") == -1) - return NULL; + goto done; if (S_ISREG(sb.st_mode)) if (file_printf(ms, "regular file, ") == -1) - return NULL; + goto done; if (file_printf(ms, "no read permission") == -1) - return NULL; - return file_getbuffer(ms); + goto done; + rv = 0; + goto done; +#ifdef __CYGWIN__ + } +#endif } /* @@ -260,13 +282,11 @@ magic_file(struct magic_set *ms, const char *inname) if (file_printf(ms, (ms->flags & MAGIC_MIME) ? "application/x-empty" : "empty") == -1) goto done; - goto gotit; } else if (nbytes == 1) { if (file_printf(ms, "very short file (no magic)") == -1) goto done; - goto gotit; } else { - buf[nbytes] = '\0'; /* null-terminate it */ + (void)memset(buf + nbytes, 0, SLOP); /* NUL terminate */ #ifdef __EMX__ switch (file_os2_apptype(ms, inname, buf, nbytes)) { case -1: @@ -274,10 +294,11 @@ magic_file(struct magic_set *ms, const char *inname) case 0: break; default: - goto gotit; + rv = 0; + goto done; } #endif - if (file_buffer(ms, buf, (size_t)nbytes) == -1) + if (file_buffer(ms, fd, buf, (size_t)nbytes) == -1) goto done; #ifdef BUILTIN_ELF if (nbytes > 5) { @@ -293,12 +314,11 @@ magic_file(struct magic_set *ms, const char *inname) } #endif } -gotit: - close_and_restore(ms, inname, fd, &sb); - return file_getbuffer(ms); + rv = 0; done: + free(buf); close_and_restore(ms, inname, fd, &sb); - return NULL; + return rv == 0 ? file_getbuffer(ms) : NULL; } @@ -311,7 +331,7 @@ magic_buffer(struct magic_set *ms, const void *buf, size_t nb) * The main work is done here! * We have the file name and/or the data buffer to be identified. */ - if (file_buffer(ms, buf, nb) == -1) { + if (file_buffer(ms, -1, buf, nb) == -1) { return NULL; } return file_getbuffer(ms); |