summaryrefslogtreecommitdiff
path: root/contrib/file/magic.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/file/magic.c')
-rw-r--r--contrib/file/magic.c111
1 files changed, 46 insertions, 65 deletions
diff --git a/contrib/file/magic.c b/contrib/file/magic.c
index 03d029159aa2f..0ecf2d30c2983 100644
--- a/contrib/file/magic.c
+++ b/contrib/file/magic.c
@@ -11,6 +11,8 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -35,6 +37,7 @@
#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
@@ -62,7 +65,7 @@
#include "patchlevel.h"
#ifndef lint
-FILE_RCSID("@(#)$Id: magic.c,v 1.32 2005/10/17 15:31:10 christos Exp $")
+FILE_RCSID("@(#)$Id: magic.c,v 1.22 2004/07/24 19:55:17 christos Exp $")
#endif /* lint */
#ifdef __EMX__
@@ -75,10 +78,6 @@ 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)
{
@@ -88,34 +87,34 @@ magic_open(int flags)
return NULL;
if (magic_setflags(ms, flags) == -1) {
+ free(ms);
errno = EINVAL;
- goto free1;
+ return NULL;
}
ms->o.ptr = ms->o.buf = malloc(ms->o.size = 1024);
- if (ms->o.buf == NULL)
- goto free1;
-
+ ms->o.len = 0;
+ if (ms->o.buf == NULL) {
+ free(ms);
+ return NULL;
+ }
ms->o.pbuf = malloc(ms->o.psize = 1024);
- if (ms->o.pbuf == NULL)
- goto free2;
-
+ if (ms->o.pbuf == NULL) {
+ free(ms->o.buf);
+ free(ms);
+ return NULL;
+ }
ms->c.off = malloc((ms->c.len = 10) * sizeof(*ms->c.off));
- if (ms->c.off == NULL)
- goto free3;
-
- ms->o.len = 0;
+ if (ms->c.off == NULL) {
+ free(ms->o.pbuf);
+ free(ms->o.buf);
+ free(ms);
+ return NULL;
+ }
ms->haderr = 0;
ms->error = -1;
ms->mlist = NULL;
return ms;
-free3:
- free(ms->o.pbuf);
-free2:
- free(ms->o.buf);
-free1:
- free(ms);
- return NULL;
}
private void
@@ -141,7 +140,6 @@ magic_close(ms)
struct magic_set *ms;
{
free_mlist(ms->mlist);
- free(ms->o.pbuf);
free(ms->o.buf);
free(ms->c.off);
free(ms);
@@ -182,11 +180,8 @@ 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 ((ms->flags & MAGIC_PRESERVE_ATIME) != 0) {
+ if (fd != STDIN_FILENO && (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
@@ -217,57 +212,41 @@ public const char *
magic_file(struct magic_set *ms, const char *inname)
{
int fd = 0;
- int rv = -1;
- unsigned char *buf;
+ unsigned char buf[HOWMANY+1]; /* one extra for terminating '\0' */
struct stat sb;
ssize_t nbytes = 0; /* number of bytes read from a datafile */
- /*
- * 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;
+ return NULL;
switch (file_fsmagic(ms, inname, &sb)) {
case -1:
- goto done;
+ return NULL;
case 0:
break;
default:
- rv = 0;
- goto done;
+ return file_getbuffer(ms);
}
+#ifndef STDIN_FILENO
+#define STDIN_FILENO 0
+#endif
if (inname == NULL)
fd = STDIN_FILENO;
- 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
+ else if ((fd = open(inname, O_RDONLY)) < 0) {
/* We cannot open it, but we were able to stat it. */
if (sb.st_mode & 0222)
if (file_printf(ms, "writable, ") == -1)
- goto done;
+ return NULL;
if (sb.st_mode & 0111)
if (file_printf(ms, "executable, ") == -1)
- goto done;
+ return NULL;
if (S_ISREG(sb.st_mode))
if (file_printf(ms, "regular file, ") == -1)
- goto done;
+ return NULL;
if (file_printf(ms, "no read permission") == -1)
- goto done;
- rv = 0;
- goto done;
-#ifdef __CYGWIN__
- }
-#endif
+ return NULL;
+ return file_getbuffer(ms);
}
/*
@@ -282,11 +261,13 @@ 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 {
- (void)memset(buf + nbytes, 0, SLOP); /* NUL terminate */
+ buf[nbytes] = '\0'; /* null-terminate it */
#ifdef __EMX__
switch (file_os2_apptype(ms, inname, buf, nbytes)) {
case -1:
@@ -294,11 +275,10 @@ magic_file(struct magic_set *ms, const char *inname)
case 0:
break;
default:
- rv = 0;
- goto done;
+ goto gotit;
}
#endif
- if (file_buffer(ms, fd, buf, (size_t)nbytes) == -1)
+ if (file_buffer(ms, buf, (size_t)nbytes) == -1)
goto done;
#ifdef BUILTIN_ELF
if (nbytes > 5) {
@@ -314,11 +294,12 @@ magic_file(struct magic_set *ms, const char *inname)
}
#endif
}
- rv = 0;
+gotit:
+ close_and_restore(ms, inname, fd, &sb);
+ return file_getbuffer(ms);
done:
- free(buf);
close_and_restore(ms, inname, fd, &sb);
- return rv == 0 ? file_getbuffer(ms) : NULL;
+ return NULL;
}
@@ -331,7 +312,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, -1, buf, nb) == -1) {
+ if (file_buffer(ms, buf, nb) == -1) {
return NULL;
}
return file_getbuffer(ms);