diff options
| author | Hartmut Holzgraefe <hholzgra@php.net> | 2003-06-04 14:21:40 +0000 |
|---|---|---|
| committer | Hartmut Holzgraefe <hholzgra@php.net> | 2003-06-04 14:21:40 +0000 |
| commit | 55e2bbecfa3dfb91925e56218966261a2c09dea6 (patch) | |
| tree | 6b912953e833b57664510169bd1f0c5bb0be37f4 /ext | |
| parent | b4fcdaedeee907b72da599a8059e0b95786d32bd (diff) | |
| download | php-git-55e2bbecfa3dfb91925e56218966261a2c09dea6.tar.gz | |
mime_content_type() now also accepts open streams as argument
streas have to bee seekable, the stream position is reset to
its original value using ftell and fseek after operation
Diffstat (limited to 'ext')
| -rw-r--r-- | ext/mime_magic/mime_magic.c | 102 |
1 files changed, 77 insertions, 25 deletions
diff --git a/ext/mime_magic/mime_magic.c b/ext/mime_magic/mime_magic.c index 7df87f1f6f..030e32e6b4 100644 --- a/ext/mime_magic/mime_magic.c +++ b/ext/mime_magic/mime_magic.c @@ -186,10 +186,10 @@ static int mcheck(union VALUETYPE *, struct magic *); static void mprint(union VALUETYPE *, struct magic *); static int mconvert(union VALUETYPE *, struct magic *); static int magic_rsl_get(char **, char **); -static int magic_process(char * TSRMLS_DC); +static int magic_process(zval * TSRMLS_DC); static long from_oct(int, char *); -static int fsmagic(char *fn TSRMLS_DC); +static int fsmagic(zval * TSRMLS_DC); #if HAVE_ZLIB && !defined(COMPILE_DL_ZLIB) @@ -305,19 +305,36 @@ PHP_MINFO_FUNCTION(mime_magic) /* }}} */ -/* {{{ proto string mime_content_type(string filename) +/* {{{ proto string mime_content_type(string filename|resource stream) Return content-type for file */ PHP_FUNCTION(mime_content_type) { - char *filename = NULL; - int filename_len; + zval *what; magic_server_config_rec *conf = &mime_global; char *content_type=NULL, *content_encoding=NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &what) == FAILURE) { return; } + switch (Z_TYPE_P(what)) { + case IS_STRING: + break; + case IS_RESOURCE: + { + php_stream *stream; + + php_stream_from_zval(stream, &what); + if (stream) { + break; + } + } + /* fallthru if not a stream resource */ + default: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "can only process string or stream arguments"); + break; + } + if (conf->magic == (struct magic *)-1) { if(MIME_MAGIC_G(debug)) php_error_docref("http://www.php.net/mime_magic" TSRMLS_CC, E_ERROR, "mime_magic could not be initialized, magic file %s is not avaliable", conf->magicfile); @@ -332,7 +349,7 @@ PHP_FUNCTION(mime_content_type) MIME_MAGIC_G(req_dat) = magic_set_config(); - if(MIME_MAGIC_OK != magic_process(filename TSRMLS_CC)) { + if(MIME_MAGIC_OK != magic_process(what TSRMLS_CC)) { RETVAL_FALSE; } else if(MIME_MAGIC_OK != magic_rsl_get(&content_type, &content_encoding)) { RETVAL_FALSE; @@ -999,17 +1016,18 @@ static char *rsl_strdup(int start_frag, int start_pos, int len) * (formerly called "process" in file command, prefix added for clarity) Opens * the file and reads a fixed-size buffer to begin processing the contents. */ -static int magic_process(char *filename TSRMLS_DC) +static int magic_process(zval *what TSRMLS_DC) { php_stream *stream; unsigned char buf[HOWMANY + 1]; /* one extra for terminating '\0' */ int nbytes = 0; /* number of bytes read from a datafile */ int result; + off_t streampos; /* * first try judging the file based on its filesystem status */ - switch ((result = fsmagic(filename TSRMLS_CC))) { + switch ((result = fsmagic(what TSRMLS_CC))) { case MIME_MAGIC_DONE: magic_rsl_putchar('\n'); return MIME_MAGIC_OK; @@ -1020,22 +1038,36 @@ static int magic_process(char *filename TSRMLS_DC) return result; } - stream = php_stream_open_wrapper(filename, "rb", IGNORE_PATH | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL); + switch (Z_TYPE_P(what)) { + case IS_STRING: + stream = php_stream_open_wrapper(Z_STRVAL_P(what), "rb", IGNORE_PATH | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL); + if (stream == NULL) { + /* We can't open it, but we were able to stat it. */ + if(MIME_MAGIC_G(debug)) + php_error_docref(NULL TSRMLS_CC, E_WARNING, "can't read `%s'", Z_STRVAL_P(what)); + /* let some other handler decide what the problem is */ + return MIME_MAGIC_DECLINED; + } + break; + case IS_RESOURCE: + php_stream_from_zval_no_verify(stream, &what); /* we tested this before, so it should work here */ + streampos = php_stream_tell(stream); /* remember stream position for restauration */ + php_stream_seek(stream, 0, SEEK_SET); + break; + } - if (stream == NULL) { - /* We can't open it, but we were able to stat it. */ - if(MIME_MAGIC_G(debug)) - php_error_docref(NULL TSRMLS_CC, E_WARNING, "can't read `%s'", filename); - /* let some other handler decide what the problem is */ - return MIME_MAGIC_DECLINED; - } /* * try looking at the first HOWMANY bytes */ if ((nbytes = php_stream_read(stream, (char *) buf, sizeof(buf) - 1)) == -1) { - if(MIME_MAGIC_G(debug)) - php_error_docref(NULL TSRMLS_CC, E_WARNING, "read failed: %s", filename); + if(MIME_MAGIC_G(debug)) { + if (Z_TYPE_P(what) == IS_RESOURCE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "read failed on stream"); + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "read failed: %s", Z_STRVAL_P(what)); + } + } return MIME_MAGIC_ERROR; } @@ -1046,7 +1078,11 @@ static int magic_process(char *filename TSRMLS_DC) tryit(buf, nbytes, 1); } - (void) php_stream_close(stream); + if (Z_TYPE_P(what) == IS_RESOURCE) { + php_stream_seek(stream, streampos, SEEK_SET); + } else { + (void) php_stream_close(stream); + } (void) magic_rsl_putchar('\n'); return MIME_MAGIC_OK; @@ -1088,12 +1124,26 @@ static void tryit(unsigned char *buf, int nb, int checkzmagic) * return MIME_MAGIC_OK to indicate it's a regular file still needing handling * other returns indicate a failure of some sort */ -static int fsmagic(char *filename TSRMLS_DC) +static int fsmagic(zval *what TSRMLS_DC) { php_stream_statbuf stat_ssb; - if(!php_stream_stat_path(filename, &stat_ssb)) { - return MIME_MAGIC_OK; + switch (Z_TYPE_P(what)) { + case IS_STRING: + if(!php_stream_stat_path(Z_STRVAL_P(what), &stat_ssb)) { + return MIME_MAGIC_OK; + } + break; + case IS_RESOURCE: + { + php_stream *stream; + + php_stream_from_zval_no_verify(stream, &what); + if(!php_stream_stat(stream, &stat_ssb)) { + return MIME_MAGIC_OK; + } + } + break; } switch (stat_ssb.sb.st_mode & S_IFMT) { @@ -1130,8 +1180,10 @@ static int fsmagic(char *filename TSRMLS_DC) /* We used stat(), the only possible reason for this is that the * symlink is broken. */ - if(MIME_MAGIC_G(debug)) - php_error_docref(NULL TSRMLS_CC, E_WARNING, "broken symlink (%s)", filename); + if(MIME_MAGIC_G(debug)) { + /* no need to check argument type here, this can only happen with strings */ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "broken symlink (%s)", Z_STRVAL_P(what)); + } return MIME_MAGIC_ERROR; #endif #ifdef S_IFSOCK |
