summaryrefslogtreecommitdiff
path: root/ext/fileinfo/libmagic/magic.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/fileinfo/libmagic/magic.c')
-rw-r--r--ext/fileinfo/libmagic/magic.c149
1 files changed, 73 insertions, 76 deletions
diff --git a/ext/fileinfo/libmagic/magic.c b/ext/fileinfo/libmagic/magic.c
index cf695ece75..bf3ccc42d6 100644
--- a/ext/fileinfo/libmagic/magic.c
+++ b/ext/fileinfo/libmagic/magic.c
@@ -30,10 +30,19 @@
#include <stdio.h>
#include <stdlib.h>
+#ifdef PHP_WIN32
+#include "win32/unistd.h"
+#else
#include <unistd.h>
+#endif
#include <string.h>
#include <sys/types.h>
-#include <sys/param.h> /* for MAXPATHLEN */
+#ifdef PHP_WIN32
+# include "config.w32.h"
+#else
+# include "php_config.h"
+#endif
+
#include <sys/stat.h>
#include <limits.h> /* for PIPE_BUF */
@@ -55,7 +64,9 @@
#include <locale.h>
#endif
-#include <netinet/in.h> /* for byte swapping */
+#ifndef PHP_WIN32
+# include <netinet/in.h> /* for byte swapping */
+#endif
#include "patchlevel.h"
@@ -72,6 +83,11 @@ FILE_RCSID("@(#)$File: magic.c,v 1.50 2008/02/19 00:58:59 rrt Exp $")
#endif
#endif
+#ifdef PHP_WIN32
+# undef S_IFLNK
+# undef S_IFIFO
+#endif
+
#ifdef __EMX__
private char *apptypeName = NULL;
protected int file_os2_apptype(struct magic_set *ms, const char *fn,
@@ -82,7 +98,7 @@ private void free_mlist(struct mlist *);
private void close_and_restore(const struct magic_set *, const char *, int,
const struct stat *);
private int info_from_stat(struct magic_set *, mode_t);
-private const char *file_or_fd(struct magic_set *, const char *, int);
+private const char *file_or_stream(struct magic_set *, const char *, php_stream *);
#ifndef STDIN_FILENO
#define STDIN_FILENO 0
@@ -204,9 +220,6 @@ 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) {
/*
@@ -240,7 +253,7 @@ close_and_restore(const struct magic_set *ms, const char *name, int fd,
public const char *
magic_descriptor(struct magic_set *ms, int fd)
{
- return file_or_fd(ms, NULL, fd);
+ return file_or_stream(ms, NULL, NULL);
}
/*
@@ -249,17 +262,28 @@ magic_descriptor(struct magic_set *ms, int fd)
public const char *
magic_file(struct magic_set *ms, const char *inname)
{
- return file_or_fd(ms, inname, STDIN_FILENO);
+ return file_or_stream(ms, inname, NULL);
+}
+
+public const char *
+magic_stream(struct magic_set *ms, php_stream *stream)
+{
+ return file_or_stream(ms, NULL, stream);
}
private const char *
-file_or_fd(struct magic_set *ms, const char *inname, int fd)
+file_or_stream(struct magic_set *ms, const char *inname, php_stream *stream)
{
int rv = -1;
unsigned char *buf;
struct stat sb;
ssize_t nbytes = 0; /* number of bytes read from a datafile */
- int ispipe = 0;
+ int no_in_stream = 0;
+ TSRMLS_FETCH();
+
+ if (!inname && !stream) {
+ return NULL;
+ }
/*
* one extra for terminating '\0', and
@@ -268,93 +292,66 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd)
#define SLOP (1 + sizeof(union VALUETYPE))
buf = emalloc(HOWMANY + SLOP);
- if (file_reset(ms) == -1)
+ if (file_reset(ms) == -1) {
goto done;
+ }
- switch (file_fsmagic(ms, inname, &sb)) {
- case -1: /* error */
- goto done;
- case 0: /* nothing found */
- break;
- default: /* matched it and printed type */
+ switch (file_fsmagic(ms, inname, &sb, stream)) {
+ case -1: /* error */
+ goto done;
+ case 0: /* nothing found */
+ break;
+ default: /* matched it and printed type */
+ rv = 0;
+ goto done;
+ }
+
+ errno = 0;
+
+ if (!stream && inname) {
+ no_in_stream = 1;
+#if (PHP_MAJOR_VERSION < 6)
+ stream = php_stream_open_wrapper(inname, "rb", REPORT_ERRORS|ENFORCE_SAFE_MODE, NULL);
+#else
+ stream = php_stream_open_wrapper(inname, "rb", REPORT_ERRORS, NULL);
+#endif
+ }
+
+ if (!stream) {
+ fprintf(stderr, "couldn't open file\n");
+ if (info_from_stat(ms, sb.st_mode) == -1)
+ goto done;
rv = 0;
goto done;
}
- if (inname == NULL) {
- if (fstat(fd, &sb) == 0 && S_ISFIFO(sb.st_mode))
- ispipe = 1;
- } else {
- int flags = O_RDONLY|O_BINARY;
-
- if (stat(inname, &sb) == 0 && S_ISFIFO(sb.st_mode)) {
- flags |= O_NONBLOCK;
- ispipe = 1;
- }
-
- errno = 0;
- if ((fd = open(inname, flags)) < 0) {
-#ifdef __CYGWIN__
- /* FIXME: Do this with EXEEXT from autotools */
- char *tmp = alloca(strlen(inname) + 5);
- (void)strcat(strcpy(tmp, inname), ".exe");
- if ((fd = open(tmp, flags)) < 0) {
-#endif
- fprintf(stderr, "couldn't open file\n");
- if (info_from_stat(ms, sb.st_mode) == -1)
- goto done;
- rv = 0;
- goto done;
-#ifdef __CYGWIN__
- }
-#endif
- }
#ifdef O_NONBLOCK
- if ((flags = fcntl(fd, F_GETFL)) != -1) {
- flags &= ~O_NONBLOCK;
- (void)fcntl(fd, F_SETFL, flags);
- }
+/* we should be already be in non blocking mode for network socket */
#endif
- }
/*
* try looking at the first HOWMANY bytes
*/
- if (ispipe) {
- ssize_t r = 0;
-
- while ((r = sread(fd, (void *)&buf[nbytes],
- (size_t)(HOWMANY - nbytes), 1)) > 0) {
- nbytes += r;
- if (r < PIPE_BUF) break;
- }
-
- if (nbytes == 0) {
- /* We can not read it, but we were able to stat it. */
- if (info_from_stat(ms, sb.st_mode) == -1)
- goto done;
- rv = 0;
- goto done;
- }
-
- } else {
- if ((nbytes = read(fd, (char *)buf, HOWMANY)) == -1) {
- file_error(ms, errno, "cannot read `%s'", inname);
- goto done;
- }
+ if ((nbytes = php_stream_read(stream, (char *)buf, HOWMANY)) < 0) {
+ file_error(ms, errno, "cannot read `%s'", inname);
+ goto done;
}
(void)memset(buf + nbytes, 0, SLOP); /* NUL terminate */
- if (file_buffer(ms, fd, inname, buf, (size_t)nbytes) == -1)
+ if (file_buffer(ms, stream, inname, buf, (size_t)nbytes) == -1)
goto done;
rv = 0;
done:
efree(buf);
- close_and_restore(ms, inname, fd, &sb);
+
+ if (no_in_stream && stream) {
+ php_stream_close(stream);
+ }
+
+ close_and_restore(ms, inname, 0, &sb);
return rv == 0 ? file_getbuffer(ms) : NULL;
}
-
public const char *
magic_buffer(struct magic_set *ms, const void *buf, size_t nb)
{
@@ -364,7 +361,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, NULL, buf, nb) == -1) {
+ if (file_buffer(ms, NULL, NULL, buf, nb) == -1) {
return NULL;
}
return file_getbuffer(ms);