Browse Source

now it works on streams (plus some debug code removed)

experimental/new_apache_hooks
Hartmut Holzgraefe 24 years ago
parent
commit
ddac6892f4
  1. 1
      ext/mime_magic/TODO
  2. 233
      ext/mime_magic/mime_magic.c

1
ext/mime_magic/TODO

@ -1,3 +1,2 @@
- general cleanup
- support for content-encoding / compressed files
- use streams

233
ext/mime_magic/mime_magic.c

@ -150,8 +150,9 @@
#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"
@ -184,7 +185,7 @@ static int magic_rsl_get(char **, char **);
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
@ -198,16 +199,12 @@ ZEND_DECLARE_MODULE_GLOBALS(mime_magic)
/* 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}
};
/* }}} */
@ -221,11 +218,11 @@ zend_module_entry mime_magic_module_entry = {
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
};
@ -275,24 +272,6 @@ PHP_MSHUTDOWN_FUNCTION(mime_magic)
}
/* }}} */
/* 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)
@ -301,17 +280,11 @@ 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)
@ -359,10 +332,7 @@ static int apprentice(void)
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;
@ -401,11 +371,6 @@ static int apprentice(void)
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;
@ -413,42 +378,6 @@ static int apprentice(void)
(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);
}
@ -705,12 +634,6 @@ static int parse(char *l, int lineno)
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;
}
@ -1011,10 +934,7 @@ static char *rsl_strdup(int start_frag, int start_pos, int len)
/* 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;
}
@ -1025,7 +945,7 @@ static char *rsl_strdup(int start_frag, int start_pos, int len)
*/
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;
@ -1044,7 +964,9 @@ static int magic_process(char *filename)
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);
@ -1055,7 +977,7 @@ static int magic_process(char *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;
@ -1068,7 +990,7 @@ static int magic_process(char *filename)
tryit(buf, nbytes, 1);
}
(void) close(fd);
(void) php_stream_close(stream);
(void) magic_rsl_putchar('\n');
return MIME_MAGIC_OK;
@ -1110,13 +1032,15 @@ 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(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;
@ -1151,7 +1075,7 @@ static int fsmagic(const char *fn)
* 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
@ -1163,16 +1087,18 @@ static int fsmagic(const char *fn)
#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;
}
@ -1220,50 +1146,13 @@ static int softmagic(unsigned char *buf, int nbytes)
*/
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)) {
@ -1278,14 +1167,6 @@ static int match(unsigned char *s, int nbytes)
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
@ -1298,12 +1179,6 @@ static int match(unsigned char *s, int nbytes)
/* 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);
@ -1322,12 +1197,6 @@ static int match(unsigned char *s, int nbytes)
*/
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) {
/*
@ -1366,16 +1235,8 @@ static int match(unsigned char *s, int nbytes)
/* 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 */
}
@ -1640,77 +1501,41 @@ static int mcheck(union VALUETYPE *p, struct magic *m)
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:
@ -1725,7 +1550,7 @@ static int mcheck(union VALUETYPE *p, struct magic *m)
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)

Loading…
Cancel
Save