#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-
+
#include "php.h"
+#include "php_streams.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "php_mime_magic.h"
static int magic_process(char *);
static long from_oct(int, char *);
-static int fsmagic(const char *fn);
+static int fsmagic(char *fn);
#if HAVE_ZLIB
/* True global resources - no need for thread safety here */
-/* static int le_mime_magic; */
static magic_server_config_rec mime_global;
-/* {{{ mime_magic_functions[]
- *
- * Every user visible function must have an entry in mime_magic_functions[].
- */
+/* {{{ mime_magic_functions[] */
function_entry mime_magic_functions[] = {
- PHP_FE(mime_content_type, NULL) /* For testing, remove later. */
- {NULL, NULL, NULL} /* Must be the last line in mime_magic_functions[] */
+ PHP_FE(mime_content_type, NULL)
+ {NULL, NULL, NULL}
};
/* }}} */
mime_magic_functions,
PHP_MINIT(mime_magic),
PHP_MSHUTDOWN(mime_magic),
- PHP_RINIT(mime_magic), /* Replace with NULL if there's nothing to do at request start */
- PHP_RSHUTDOWN(mime_magic), /* Replace with NULL if there's nothing to do at request end */
+ NULL,
+ NULL,
PHP_MINFO(mime_magic),
#if ZEND_MODULE_API_NO >= 20010901
- "0.1", /* Replace with version number for your extension */
+ "0.1",
#endif
STANDARD_MODULE_PROPERTIES
};
}
/* }}} */
-/* Remove if there's nothing to do at request start */
-/* {{{ PHP_RINIT_FUNCTION
- */
-PHP_RINIT_FUNCTION(mime_magic)
-{
- return SUCCESS;
-}
-/* }}} */
-
-/* Remove if there's nothing to do at request end */
-/* {{{ PHP_RSHUTDOWN_FUNCTION
- */
-PHP_RSHUTDOWN_FUNCTION(mime_magic)
-{
- return SUCCESS;
-}
-/* }}} */
-
/* {{{ PHP_MINFO_FUNCTION
*/
PHP_MINFO_FUNCTION(mime_magic)
php_info_print_table_header(2, "mime_magic support", "enabled");
php_info_print_table_end();
- /* Remove comments if you have entries in php.ini
DISPLAY_INI_ENTRIES();
- */
}
/* }}} */
-/* Remove the following function when you have succesfully modified config.m4
- so that your module can be compiled into PHP, it exists only for testing
- purposes. */
-
/* {{{ proto string mime_content_type(string filename)
Return content-type for file */
PHP_FUNCTION(mime_content_type)
char line[BUFSIZ + 1];
int errs = 0;
int lineno;
-#if MIME_MAGIC_DEBUG
- int rule = 0;
- struct magic *m, *prevm;
-#endif
+
char *fname;
magic_server_config_rec *conf = &mime_global;
if (line[ws_offset] == '#')
continue;
-#if MIME_MAGIC_DEBUG
- /* if we get here, we're going to use it so count it */
- rule++;
-#endif
-
/* parse it */
if (parse(line + ws_offset, lineno) != 0)
++errs;
(void) fclose(f);
-#if MIME_MAGIC_DEBUG
- php_error(E_NOTICE,
- MODNAME ": apprentice conf=%x file=%s m=%s m->next=%s last=%s",
- conf,
- conf->magicfile ? conf->magicfile : "NULL",
- conf->magic ? "set" : "NULL",
- (conf->magic && conf->magic->next) ? "set" : "NULL",
- conf->last ? "set" : "NULL");
- php_error(E_NOTICE,
- MODNAME ": apprentice read %d lines, %d rules, %d errors",
- lineno, rule, errs);
-#endif
-
-#if MIME_MAGIC_DEBUG
- prevm = 0;
- php_error(E_NOTICE,
- MODNAME ": apprentice test");
- for (m = conf->magic; m; m = m->next) {
- if (isprint((((unsigned long) m) >> 24) & 255) &&
- isprint((((unsigned long) m) >> 16) & 255) &&
- isprint((((unsigned long) m) >> 8) & 255) &&
- isprint(((unsigned long) m) & 255)) {
- php_error(E_NOTICE,
- MODNAME ": apprentice: POINTER CLOBBERED! "
- "m=\"%c%c%c%c\" line=%d",
- (((unsigned long) m) >> 24) & 255,
- (((unsigned long) m) >> 16) & 255,
- (((unsigned long) m) >> 8) & 255,
- ((unsigned long) m) & 255,
- prevm ? prevm->lineno : -1);
- break;
- }
- prevm = m;
- }
-#endif
-
return (errs ? -1 : 0);
}
strncpy(m->desc, l, sizeof(m->desc) - 1);
m->desc[sizeof(m->desc) - 1] = '\0';
-#if MIME_MAGIC_DEBUG
- php_error(E_NOTICE,
- MODNAME ": parse line=%d m=%x next=%x cont=%d desc=%s",
- lineno, m, m->next, m->cont_level, m->desc);
-#endif /* MIME_MAGIC_DEBUG */
-
return 0;
}
/* clean up and return */
result[res_pos] = 0;
-#if MIME_MAGIC_DEBUG
- php_error(E_NOTICE,
- MODNAME ": rsl_strdup() %d chars: %s", res_pos - 1, result);
-#endif
+
return result;
}
*/
static int magic_process(char *filename)
{
- int fd = 0;
+ 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;
return result;
}
- if ((fd = open(filename, O_RDONLY, 0)) < 0) {
+ stream = php_stream_open_wrapper(filename, "r", IGNORE_PATH | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL);
+
+ if (stream == NULL) {
/* We can't open it, but we were able to stat it. */
php_error(E_WARNING,
MODNAME ": can't read `%s'", filename);
/*
* try looking at the first HOWMANY bytes
*/
- if ((nbytes = read(fd, (char *) buf, sizeof(buf) - 1)) == -1) {
+ if ((nbytes = php_stream_read(stream, (char *) buf, sizeof(buf) - 1)) == -1) {
php_error(E_WARNING,
MODNAME ": read failed: %s", filename);
return MIME_MAGIC_ERROR;
tryit(buf, nbytes, 1);
}
- (void) close(fd);
+ (void) php_stream_close(stream);
(void) magic_rsl_putchar('\n');
return MIME_MAGIC_OK;
* 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(const char *fn)
+static int fsmagic(char *filename)
{
- struct stat finfo;
+ php_stream_statbuf stat_ssb;
- stat(fn, &finfo);
+ if(!php_stream_stat_path(filename, &stat_ssb)) {
+ return MIME_MAGIC_OK;
+ }
- switch (finfo.st_mode & S_IFMT) {
+ switch (stat_ssb.sb.st_mode & S_IFMT) {
case S_IFDIR:
magic_rsl_puts(DIR_MAGIC_TYPE);
return MIME_MAGIC_DONE;
* symlink is broken.
*/
php_error(E_WARNING,
- MODNAME ": broken symlink (%s)", fn);
+ MODNAME ": broken symlink (%s)", filename);
return MIME_MAGIC_ERROR;
#endif
#ifdef S_IFSOCK
#endif
case S_IFREG:
break;
+ case 0:
+ break;
default:
php_error(E_WARNING,
- MODNAME ": invalid mode 0%o.", (unsigned int)finfo.st_mode);
+ MODNAME ": invalid mode 0%o.", (unsigned int)stat_ssb.sb.st_mode);
return MIME_MAGIC_ERROR;
}
/*
* regular file, check next possibility
*/
- if (finfo.st_size == 0) {
+ if (stat_ssb.sb.st_size == 0) {
magic_rsl_puts(MIME_TEXT_UNKNOWN);
return MIME_MAGIC_DONE;
}
*/
static int match(unsigned char *s, int nbytes)
{
-#if MIME_MAGIC_DEBUG
- int rule_counter = 0;
-#endif
int cont_level = 0;
int need_separator = 0;
union VALUETYPE p;
magic_server_config_rec *conf = &mime_global;
struct magic *m;
-#if MIME_MAGIC_DEBUG
- php_error(E_NOTICE,
- MODNAME ": match conf=%x file=%s m=%s m->next=%s last=%s",
- conf,
- conf->magicfile ? conf->magicfile : "NULL",
- conf->magic ? "set" : "NULL",
- (conf->magic && conf->magic->next) ? "set" : "NULL",
- conf->last ? "set" : "NULL");
-#endif
-
-#if MIME_MAGIC_DEBUG
for (m = conf->magic; m; m = m->next) {
- if (isprint((((unsigned long) m) >> 24) & 255) &&
- isprint((((unsigned long) m) >> 16) & 255) &&
- isprint((((unsigned long) m) >> 8) & 255) &&
- isprint(((unsigned long) m) & 255)) {
- php_error(E_NOTICE,
- MODNAME ": match: POINTER CLOBBERED! "
- "m=\"%c%c%c%c\"",
- (((unsigned long) m) >> 24) & 255,
- (((unsigned long) m) >> 16) & 255,
- (((unsigned long) m) >> 8) & 255,
- ((unsigned long) m) & 255);
- break;
- }
- }
-#endif
-
- for (m = conf->magic; m; m = m->next) {
-#if MIME_MAGIC_DEBUG
- rule_counter++;
- php_error(E_NOTICE,
- MODNAME ": line=%d desc=%s", m->lineno, m->desc);
-#endif
-
/* check if main entry matches */
if (!mget(&p, s, m, nbytes) ||
!mcheck(&p, m)) {
m_cont = m->next;
while (m_cont && (m_cont->cont_level != 0)) {
-#if MIME_MAGIC_DEBUG
- rule_counter++;
- php_error(E_NOTICE,
- MODNAME ": line=%d mc=%x mc->next=%x cont=%d desc=%s",
- m_cont->lineno, m_cont,
- m_cont->next, m_cont->cont_level,
- m_cont->desc);
-#endif
/*
* this trick allows us to keep *m in sync when the continue
* advances the pointer
/* if we get here, the main entry rule was a match */
/* this will be the last run through the loop */
-#if MIME_MAGIC_DEBUG
- php_error(E_NOTICE,
- MODNAME ": rule matched, line=%d type=%d %s",
- m->lineno, m->type,
- (m->type == STRING) ? m->value.s : "");
-#endif
/* print the match */
mprint(&p, m);
*/
m = m->next;
while (m && (m->cont_level != 0)) {
-#if MIME_MAGIC_DEBUG
- php_error(E_NOTICE,
- MODNAME ": match line=%d cont=%d type=%d %s",
- m->lineno, m->cont_level, m->type,
- (m->type == STRING) ? m->value.s : "");
-#endif
if (cont_level >= m->cont_level) {
if (cont_level > m->cont_level) {
/*
/* move to next continuation record */
m = m->next;
}
-#if MIME_MAGIC_DEBUG
- php_error(E_NOTICE,
- MODNAME ": matched after %d rules", rule_counter);
-#endif
return 1; /* all through */
}
-#if MIME_MAGIC_DEBUG
- php_error(E_NOTICE,
- MODNAME ": failed after %d rules", rule_counter);
-#endif
return 0; /* no match at all */
}
switch (m->reln) {
case 'x':
-#if MIME_MAGIC_DEBUG
- php_error(E_NOTICE,
- "%lu == *any* = 1", v);
-#endif
matched = 1;
break;
case '!':
matched = v != l;
-#if MIME_MAGIC_DEBUG
- php_error(E_NOTICE,
- "%lu != %lu = %d", v, l, matched);
-#endif
break;
case '=':
matched = v == l;
-#if MIME_MAGIC_DEBUG
- php_error(E_NOTICE,
- "%lu == %lu = %d", v, l, matched);
-#endif
break;
case '>':
if (m->flag & UNSIGNED) {
matched = v > l;
-#if MIME_MAGIC_DEBUG
- php_error(E_NOTICE,
- "%lu > %lu = %d", v, l, matched);
-#endif
}
else {
matched = (long) v > (long) l;
-#if MIME_MAGIC_DEBUG
- php_error(E_NOTICE,
- "%ld > %ld = %d", v, l, matched);
-#endif
}
break;
case '<':
if (m->flag & UNSIGNED) {
matched = v < l;
-#if MIME_MAGIC_DEBUG
- php_error(E_NOTICE,
- "%lu < %lu = %d", v, l, matched);
-#endif
}
else {
matched = (long) v < (long) l;
-#if MIME_MAGIC_DEBUG
- php_error(E_NOTICE,
- "%ld < %ld = %d", v, l, matched);
-#endif
}
break;
case '&':
matched = (v & l) == l;
-#if MIME_MAGIC_DEBUG
- php_error(E_NOTICE,
- "((%lx & %lx) == %lx) = %d", v, l, l, matched);
-#endif
break;
case '^':
matched = (v & l) != l;
-#if MIME_MAGIC_DEBUG
- php_error(E_NOTICE,
- "((%lx & %lx) != %lx) = %d", v, l, l, matched);
-#endif
break;
default:
return matched;
}
-#if HAVE_ZLIB
+#if HAVE_ZLIB
/*
* compress routines: zmagic() - returns 0 if not recognized, uncompresses
* and prints information if recognized uncompress(s, method, old, n, newch)