diff options
Diffstat (limited to 'contrib/file/magic.c')
| -rw-r--r-- | contrib/file/magic.c | 111 | 
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); | 
