mod_mime_magic.c revision 44ca834b970b454b844efb96f219bdf49fee71e5
f743002678eb67b99bbc29fee116b65d9530fec0wrowe/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as
80833bb9a1bf25dcf19e814438a4b311d2e1f4cffuankg * applicable.
6d601599d3d65df0410eae6e573e75b2dbfb1fb4minfrin * Licensed under the Apache License, Version 2.0 (the "License");
6d601599d3d65df0410eae6e573e75b2dbfb1fb4minfrin * you may not use this file except in compliance with the License.
6d601599d3d65df0410eae6e573e75b2dbfb1fb4minfrin * You may obtain a copy of the License at
40d570cf1420f497bcac59045d4ce477f0b5d891minfrin * Unless required by applicable law or agreed to in writing, software
edab53cc0be707fa71968a95c696b19f0e6c4736minfrin * distributed under the License is distributed on an "AS IS" BASIS,
edab53cc0be707fa71968a95c696b19f0e6c4736minfrin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
edab53cc0be707fa71968a95c696b19f0e6c4736minfrin * See the License for the specific language governing permissions and
806e9ba570ef48df4bfd8364e2f4d57381388a11minfrin * limitations under the License.
806e9ba570ef48df4bfd8364e2f4d57381388a11minfrin * mod_mime_magic: MIME type lookup via file magic numbers
0754dde4b645ccd88fdb6c2961c0bdd7b213bdbaminfrin * Copyright (c) 1996-1997 Cisco Systems, Inc.
0754dde4b645ccd88fdb6c2961c0bdd7b213bdbaminfrin * This software was submitted by Cisco Systems to the Apache Software Foundation in July
a4273e3e513ce8f5e1311c320cbd334cc382950eminfrin * 1997. Future revisions and derivatives of this source code must
a4273e3e513ce8f5e1311c320cbd334cc382950eminfrin * acknowledge Cisco Systems as the original contributor of this module.
a4273e3e513ce8f5e1311c320cbd334cc382950eminfrin * All other licensing and usage conditions are those of the Apache Software Foundation.
a4273e3e513ce8f5e1311c320cbd334cc382950eminfrin * Some of this code is derived from the free version of the file command
d3e0a61e1bcc497f2efd7af41a5a9d77090ecc1cminfrin * originally posted to comp.sources.unix. Copyright info for that program
d3e0a61e1bcc497f2efd7af41a5a9d77090ecc1cminfrin * is included below as required.
1aac1c71105133d669960501bdf2274e63561054minfrin * ---------------------------------------------------------------------------
1aac1c71105133d669960501bdf2274e63561054minfrin * - Copyright (c) Ian F. Darwin, 1987. Written by Ian F. Darwin.
2c487ac43b583db869e743772a7a10b278aa2bcfminfrin * This software is not subject to any license of the American Telephone and
2c487ac43b583db869e743772a7a10b278aa2bcfminfrin * Telegraph Company or of the Regents of the University of California.
2c487ac43b583db869e743772a7a10b278aa2bcfminfrin * Permission is granted to anyone to use this software for any purpose on any
2c487ac43b583db869e743772a7a10b278aa2bcfminfrin * computer system, and to alter it and redistribute it freely, subject to
dbf5f584c62fe6030d81121fdddeb7588b78b867sf * the following restrictions:
15320dc646e41d3eb38736978500349c4d66dc0dsf * 1. The author is not responsible for the consequences of use of this
15320dc646e41d3eb38736978500349c4d66dc0dsf * software, no matter how awful, even if they arise from flaws in it.
691db92094897494d6c31326108da20088bc175etrawick * 2. The origin of this software must not be misrepresented, either by
691db92094897494d6c31326108da20088bc175etrawick * explicit claim or by omission. Since few users ever read sources, credits
92108a6c4fd7ca6e9acc94d2485920436763e491sf * must appear in the documentation.
684e0cfc200f66287a93bbd1708d1dd8a92a7eefcovener * 3. Altered versions must be plainly marked as such, and must not be
684e0cfc200f66287a93bbd1708d1dd8a92a7eefcovener * misrepresented as being the original software. Since few users ever read
684e0cfc200f66287a93bbd1708d1dd8a92a7eefcovener * sources, credits must appear in the documentation.
05a5a9c3e16f21566e1b61f4bd68025ce1b741ccjoes * 4. This notice may not be removed or altered.
05a5a9c3e16f21566e1b61f4bd68025ce1b741ccjoes * -------------------------------------------------------------------------
26c5829347f6a355c00f1ba0301d575056b69536niq * For compliance with Mr Darwin's terms: this has been very significantly
ef82e8fa164e0a1f8b813f7deb6b7ead96018c94niq * modified from the free "file" command.
ef82e8fa164e0a1f8b813f7deb6b7ead96018c94niq * - all-in-one file for compilation convenience when moving from one
ef82e8fa164e0a1f8b813f7deb6b7ead96018c94niq * version of Apache to the next.
ef82e8fa164e0a1f8b813f7deb6b7ead96018c94niq * - Memory allocation is done through the Apache API's apr_pool_t structure.
ef82e8fa164e0a1f8b813f7deb6b7ead96018c94niq * - All functions have had necessary Apache API request or server
ef82e8fa164e0a1f8b813f7deb6b7ead96018c94niq * structures passed to them where necessary to call other Apache API
413ee814748f37be168ff12407fa6dba0ceeabe6trawick * routines. (i.e. usually for logging, files, or memory allocation in
c12917da693bae4028a1d5a5e8224bceed8c739dsf * itself or a called function.)
c12917da693bae4028a1d5a5e8224bceed8c739dsf * - struct magic has been converted from an array to a single-ended linked
eeb7898b9c087040d44550f8a6b1a257783c9f0ahumbedooh * list because it only grows one record at a time, it's only accessed
eeb7898b9c087040d44550f8a6b1a257783c9f0ahumbedooh * sequentially, and the Apache API has no equivalent of realloc().
7705103518c61f7cdcd4041fe871cb45114f31a5rpluem * - Functions have been changed to get their parameters from the server
eafcc0ebf263d0ba69855b6e10958c4c1a2361bdsf * configuration instead of globals. (It should be reentrant now but has
eafcc0ebf263d0ba69855b6e10958c4c1a2361bdsf * not been tested in a threaded environment.)
eafcc0ebf263d0ba69855b6e10958c4c1a2361bdsf * - Places where it used to print results to stdout now saves them in a
eafcc0ebf263d0ba69855b6e10958c4c1a2361bdsf * list where they're used to set the MIME type in the Apache request
d7ffd2da16d58b1a0de212e4d56f7aebb72bef26sf * - Command-line flags have been removed since they will never be used here.
d7ffd2da16d58b1a0de212e4d56f7aebb72bef26sf * Ian Kluft <ikluft@cisco.com>
4576c1a9ef54cd1e5555ee07d016a7f559f80338sf * Engineering Information Framework
4576c1a9ef54cd1e5555ee07d016a7f559f80338sf * Central Engineering
4576c1a9ef54cd1e5555ee07d016a7f559f80338sf * Cisco Systems, Inc.
9811aed12bbc71783d2e544ccb5fecd193843eadsf * San Jose, CA, USA
9811aed12bbc71783d2e544ccb5fecd193843eadsf * Initial installation July/August 1996
d58a822aff1dfda25384d3d009f88f1883c95436kbrand * Misc bug fixes May 1997
d58a822aff1dfda25384d3d009f88f1883c95436kbrand * Submission to Apache Software Foundation July 1997
f21e9e3d0bfb7a507ecc5bc963f2159d693503d1sf/* ### this isn't set by configure? does anybody set this? */
132ee6ac1c26d6e8953836316ba50734eefab47bsf * data structures and related constants
85eacfc96a04547ef25aabbc06440039715084c2jorton#define MIME_BINARY_UNKNOWN "application/octet-stream"
d776b0a2d2889ce1d13494873368f34327a2e1bbtrawick/* HOWMANY must be at least 4096 to make gzip -dcq work */
f4ca9f6f002fece336168a16355434ca966f96a9trawick/* SMALL_HOWMANY limits how much work we do to figure out text files */
78f94f1d06c4e6828ce04d618221e0fcecb57849humbedooh#define MAXDESC 50 /* max leng of text description */
78f94f1d06c4e6828ce04d618221e0fcecb57849humbedooh#define MAXstring 64 /* max leng of "string" types */
10961a2f60207cb873d889bb28b1f0ef707a4311humbedooh unsigned char reln; /* relation (0=eq, '>'=gt, etc) */
91654e263480f0fdc2a03d782ff23f8dad07cf79humbedooh unsigned char b;
79c5787b92ac5f0e1cc82393816c77a006399316trawick unsigned short h;
79c5787b92ac5f0e1cc82393816c77a006399316trawick unsigned long l;
79c5787b92ac5f0e1cc82393816c77a006399316trawick unsigned char hs[2]; /* 2 bytes of a fixed-endian "short" */
c967bf3bc89e8aa60dbd30d9da388e448ddc1cc4trawick unsigned char hl[4]; /* 2 bytes of a fixed-endian "long" */
79c5787b92ac5f0e1cc82393816c77a006399316trawick unsigned long mask; /* mask before comparison with value */
79c5787b92ac5f0e1cc82393816c77a006399316trawick /* NOTE: this string is suspected of overrunning - find it! */
536e48c08d674acac5d44929318f2ad928edc361jorton * data structures for tar file recognition
536e48c08d674acac5d44929318f2ad928edc361jorton * --------------------------------------------------------------------------
e81785da447b469da66f218b3f0244aab507958djorton * Header file for public domain tar (tape archive) program.
3e4e54d4e3fc0123c63d57aa84ac7ad7a8c73ff8jorton * @(#)tar.h 1.20 86/10/29 Public Domain. Created 25 August 1985 by John
3e4e54d4e3fc0123c63d57aa84ac7ad7a8c73ff8jorton * Gilmore, ihnp4!hoptoad!gnu.
53e9b27aba029b18be814df40bcf6f0428771d1efuankg * Header block on tape.
53e9b27aba029b18be814df40bcf6f0428771d1efuankg * I'm going to use traditional DP naming conventions here. A "block" is a big
53e9b27aba029b18be814df40bcf6f0428771d1efuankg * chunk of stuff that we do I/O on. A "record" is a piece of info that we
53e9b27aba029b18be814df40bcf6f0428771d1efuankg * care about. Typically many "record"s fit into a "block".
cfa64348224b66dd1c9979b809406c4d15b1c137fielding/* The magic field is filled with this if uname and gname are valid. */
cfa64348224b66dd1c9979b809406c4d15b1c137fielding * file-function prototypes
cfa64348224b66dd1c9979b809406c4d15b1c137fieldingstatic int ascmagic(request_rec *, unsigned char *, apr_size_t);
cfa64348224b66dd1c9979b809406c4d15b1c137fieldingstatic int softmagic(request_rec *, unsigned char *, apr_size_t);
static int hextoint(int);
unsigned char **, apr_size_t);
static long from_oct(int, char *);
* includes for ASCII substring recognition formerly "names.h" in file
static char *types[] =
static struct names {
char *name;
short type;
} names[] = {
#ifdef NOTDEF
NULL, 0
typedef struct magic_rsl_s {
} magic_rsl;
return new;
if (!conf) {
return NULL;
{NULL}
sizeof(magic_req_rec));
return req_dat;
if (!req_dat) {
str[0] = c;
res_pos = 0;
cur_pos++) {
#if MIME_MAGIC_DEBUG
return result;
} rsl_states;
return DECLINED;
return DECLINED;
state++;
return DECLINED;
type_len++;
state++;
state++;
type_len++;
state++;
encoding_len++;
return DECLINED;
return DECLINED;
char *tmp;
char *tmp;
if (!r->content_type ||
state);
return HTTP_INTERNAL_SERVER_ERROR;
return OK;
int result;
case DONE:
return OK;
case OK:
return result;
return DECLINED;
return HTTP_INTERNAL_SERVER_ERROR;
if (nbytes == 0) {
return DECLINED;
return result;
return OK;
int checkzmagic)
return OK;
return OK;
return OK;
return DECLINED;
int errs = 0;
int lineno;
#if MIME_MAGIC_DEBUG
int rule = 0;
if (!fname) {
int ws_offset;
--last;
ws_offset = 0;
ws_offset++;
#if MIME_MAGIC_DEBUG
rule++;
++errs;
(void) apr_file_close(f);
#if MIME_MAGIC_DEBUG
conf,
#if MIME_MAGIC_DEBUG
prevm = 0;
prevm = m;
switch (m->type) {
case BYTE:
case SHORT:
case BESHORT:
case LESHORT:
case DATE:
case BEDATE:
case LEDATE:
case LONG:
case BELONG:
case LELONG:
case STRING:
struct magic *m;
m->flag = 0;
m->cont_level = 0;
m->cont_level++;
if (apr_isdigit((unsigned char) *l)) {
while (apr_isdigit((unsigned char) *l))
l += NBYTE;
l += NSHORT;
l += NLONG;
l += NSTRING;
l += NDATE;
l += NBESHORT;
l += NBELONG;
l += NBEDATE;
l += NLESHORT;
l += NLELONG;
l += NLEDATE;
m->mask = ~0L;
m->reln = *l;
m->reln = *l;
m->reln = *l;
m->nospflag = 0;
#if MIME_MAGIC_DEBUG
int slen;
register int val;
if (apr_isspace(c))
if (p >= pmax) {
goto out;
*p++ = (char) val;
val = c;
c = hextoint(*s++);
c = hextoint(*s++);
*p++ = (char) val;
out:
static int hextoint(int c)
if (apr_isdigit(c))
case APR_DIR:
return DONE;
case APR_CHR:
return DONE;
case APR_BLK:
return DONE;
case APR_PIPE:
return DONE;
case APR_LNK:
return HTTP_INTERNAL_SERVER_ERROR;
case APR_SOCK:
return DONE;
case APR_REG:
return HTTP_INTERNAL_SERVER_ERROR;
return DONE;
return OK;
* apprentice.c). Passed the name and FILE * of one file to be typed.
#if MIME_MAGIC_DEBUG
int rule_counter = 0;
int cont_level = 0;
int need_separator = 0;
union VALUETYPE p;
struct magic *m;
#if MIME_MAGIC_DEBUG
conf,
#if MIME_MAGIC_DEBUG
#if MIME_MAGIC_DEBUG
rule_counter++;
!mcheck(r, &p, m)) {
#if MIME_MAGIC_DEBUG
rule_counter++;
m = m_cont;
#if MIME_MAGIC_DEBUG
mprint(r, &p, m);
if (m->desc[0])
cont_level++;
m = m->next;
while (m && (m->cont_level != 0)) {
#if MIME_MAGIC_DEBUG
mcheck(r, &p, m)) {
if (need_separator
&& (m->nospflag == 0)
need_separator = 0;
mprint(r, &p, m);
if (m->desc[0])
cont_level++;
m = m->next;
#if MIME_MAGIC_DEBUG
#if MIME_MAGIC_DEBUG
char *pp;
switch (m->type) {
case BYTE:
case SHORT:
case BESHORT:
case LESHORT:
case LONG:
case BELONG:
case LELONG:
case STRING:
case DATE:
case BEDATE:
case LEDATE:
m->type);
char *rt;
switch (m->type) {
case BYTE:
case SHORT:
case LONG:
case DATE:
case STRING:
case BESHORT:
case BELONG:
case BEDATE:
case LESHORT:
case LELONG:
case LEDATE:
if (!mconvert(r, p, m))
case BYTE:
case SHORT:
case LONG:
if (!mconvert(r, p, m))
register unsigned long l = m->value.l;
int matched;
switch (m->type) {
case BYTE:
case SHORT:
case BESHORT:
case LESHORT:
case LONG:
case BELONG:
case LELONG:
case DATE:
case BEDATE:
case LEDATE:
case STRING:
* What we want here is: v = strncmp(m->value.s, p->s, m->vallen);
register unsigned char *a = (unsigned char *) m->value.s;
while (--len >= 0)
switch (m->reln) {
#if MIME_MAGIC_DEBUG
matched = v != l;
#if MIME_MAGIC_DEBUG
matched = v == l;
#if MIME_MAGIC_DEBUG
matched = v > l;
#if MIME_MAGIC_DEBUG
matched = (long) v > (long) l;
#if MIME_MAGIC_DEBUG
matched = v < l;
#if MIME_MAGIC_DEBUG
matched = (long) v < (long) l;
#if MIME_MAGIC_DEBUG
matched = (v & l) == l;
#if MIME_MAGIC_DEBUG
matched = (v & l) != l;
#if MIME_MAGIC_DEBUG
matched = 0;
m->reln);
return matched;
int has_escapes = 0;
char *token;
register struct names *p;
int small_nbytes;
char *strtok_state;
/* look for tokens from names.h - this is expensive!, so we'll limit
if (has_escapes)
char *magic;
int silent;
} compr[] = {
unsigned char *newbuf;
int newsize;
for (i = 0; i < ncompr; i++) {
if (i == ncompr)
struct uncompress_parms {
request_rec *r;
int method;
const char *const *env;
return (rc);
parm.r = r;
* @(#)list.c 1.18 9/23/86 Public Domain - gnu $Id: mod_mime_magic.c,v 1.7
sum = 0;
for (i = sizeof(union record); --i >= 0;) {
register long value;
where++;
if (--digs <= 0)
value = 0;
--digs;
return value;
char *sub_filename;
#if MIME_MAGIC_DEBUG
suffix_pos--;
result = 0;
#if MIME_MAGIC_DEBUG
#if MIME_MAGIC_DEBUG
r->content_encoding =
return result;
int result;
server_rec *s;
#if MIME_MAGIC_DEBUG
return OK;
#if MIME_MAGIC_DEBUG
prevm = 0;
prevm = m;
return OK;
int result;
return DECLINED;
if (r->content_type) {
return DECLINED;
return DECLINED;
if (!magic_set_config(r)) {
return HTTP_INTERNAL_SERVER_ERROR;
return result;
return magic_rsl_to_request(r);