summaryrefslogtreecommitdiffstats
path: root/contrib/file/magic.c
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2006-06-19 07:52:15 +0000
committerobrien <obrien@FreeBSD.org>2006-06-19 07:52:15 +0000
commit5c5b299c7d54da4b9c68e95d1f7a230405bd1ac2 (patch)
treeeba3401e66ba997d94604096d6095b69207f5d78 /contrib/file/magic.c
parentdf11c7b63d4e785920524068f8f9cbdef5dc08ad (diff)
downloadFreeBSD-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.c72
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);
OpenPOWER on IntegriCloud