📄 mod_mime_magic.c
字号:
/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* * mod_mime_magic: MIME type lookup via file magic numbers * Copyright (c) 1996-1997 Cisco Systems, Inc. * * This software was submitted by Cisco Systems to the Apache Group in July * 1997. Future revisions and derivatives of this source code must * acknowledge Cisco Systems as the original contributor of this module. * All other licensing and usage conditions are those of the Apache Group. * * Some of this code is derived from the free version of the file command * originally posted to comp.sources.unix. Copyright info for that program * is included below as required. * --------------------------------------------------------------------------- * - Copyright (c) Ian F. Darwin, 1987. Written by Ian F. Darwin. * * This software is not subject to any license of the American Telephone and * Telegraph Company or of the Regents of the University of California. * * Permission is granted to anyone to use this software for any purpose on any * computer system, and to alter it and redistribute it freely, subject to * the following restrictions: * * 1. The author is not responsible for the consequences of use of this * software, no matter how awful, even if they arise from flaws in it. * * 2. The origin of this software must not be misrepresented, either by * explicit claim or by omission. Since few users ever read sources, credits * must appear in the documentation. * * 3. Altered versions must be plainly marked as such, and must not be * misrepresented as being the original software. Since few users ever read * sources, credits must appear in the documentation. * * 4. This notice may not be removed or altered. * ------------------------------------------------------------------------- * * For compliance with Mr Darwin's terms: this has been very significantly * modified from the free "file" command. * - all-in-one file for compilation convenience when moving from one * version of Apache to the next. * - Memory allocation is done through the Apache API's pool structure. * - All functions have had necessary Apache API request or server * structures passed to them where necessary to call other Apache API * routines. (i.e. usually for logging, files, or memory allocation in * itself or a called function.) * - struct magic has been converted from an array to a single-ended linked * list because it only grows one record at a time, it's only accessed * sequentially, and the Apache API has no equivalent of realloc(). * - Functions have been changed to get their parameters from the server * configuration instead of globals. (It should be reentrant now but has * not been tested in a threaded environment.) * - Places where it used to print results to stdout now saves them in a * list where they're used to set the MIME type in the Apache request * record. * - Command-line flags have been removed since they will never be used here. * * Ian Kluft <ikluft@cisco.com> * Engineering Information Framework * Central Engineering * Cisco Systems, Inc. * San Jose, CA, USA * * Initial installation July/August 1996 * Misc bug fixes May 1997 * Submission to Apache Group July 1997 * */#include "httpd.h"#include "http_config.h"#include "http_request.h"#include "http_core.h"#include "http_log.h"#include "http_protocol.h"#ifndef WIN32#include <utime.h>#endif/* * data structures and related constants */#define MODNAME "mod_mime_magic"#define MIME_MAGIC_DEBUG 0#define MIME_BINARY_UNKNOWN "application/octet-stream"#define MIME_TEXT_UNKNOWN "text/plain"#define MAXMIMESTRING 256/* HOWMANY must be at least 4096 to make gzip -dcq work */#define HOWMANY 4096/* SMALL_HOWMANY limits how much work we do to figure out text files */#define SMALL_HOWMANY 1024#define MAXDESC 50 /* max leng of text description */#define MAXstring 64 /* max leng of "string" types */struct magic { struct magic *next; /* link to next entry */ int lineno; /* line number from magic file */ short flag;#define INDIR 1 /* if '>(...)' appears, */#define UNSIGNED 2 /* comparison is unsigned */ short cont_level; /* level of ">" */ struct { char type; /* byte short long */ long offset; /* offset from indirection */ } in; long offset; /* offset to magic number */ unsigned char reln; /* relation (0=eq, '>'=gt, etc) */ char type; /* int, short, long or string. */ char vallen; /* length of string value, if any */#define BYTE 1#define SHORT 2#define LONG 4#define STRING 5#define DATE 6#define BESHORT 7#define BELONG 8#define BEDATE 9#define LESHORT 10#define LELONG 11#define LEDATE 12 union VALUETYPE { unsigned char b; unsigned short h; unsigned long l; char s[MAXstring]; unsigned char hs[2]; /* 2 bytes of a fixed-endian "short" */ unsigned char hl[4]; /* 2 bytes of a fixed-endian "long" */ } value; /* either number or string */ unsigned long mask; /* mask before comparison with value */ char nospflag; /* supress space character */ /* NOTE: this string is suspected of overrunning - find it! */ char desc[MAXDESC]; /* description */};/* * data structures for tar file recognition * -------------------------------------------------------------------------- * Header file for public domain tar (tape archive) program. * * @(#)tar.h 1.20 86/10/29 Public Domain. Created 25 August 1985 by John * Gilmore, ihnp4!hoptoad!gnu. * * Header block on tape. * * I'm going to use traditional DP naming conventions here. A "block" is a big * chunk of stuff that we do I/O on. A "record" is a piece of info that we * care about. Typically many "record"s fit into a "block". */#define RECORDSIZE 512#define NAMSIZ 100#define TUNMLEN 32#define TGNMLEN 32union record { char charptr[RECORDSIZE]; struct header { char name[NAMSIZ]; char mode[8]; char uid[8]; char gid[8]; char size[12]; char mtime[12]; char chksum[8]; char linkflag; char linkname[NAMSIZ]; char magic[8]; char uname[TUNMLEN]; char gname[TGNMLEN]; char devmajor[8]; char devminor[8]; } header;};/* The magic field is filled with this if uname and gname are valid. */#define TMAGIC "ustar " /* 7 chars and a null *//* * file-function prototypes */static int ascmagic(request_rec *, unsigned char *, int);static int is_tar(unsigned char *, int);static int softmagic(request_rec *, unsigned char *, int);static void tryit(request_rec *, unsigned char *, int, int);static int zmagic(request_rec *, unsigned char *, int);static int getvalue(server_rec *, struct magic *, char **);static int hextoint(int);static char *getstr(server_rec *, char *, char *, int, int *);static int parse(server_rec *, pool *p, char *, int);static int match(request_rec *, unsigned char *, int);static int mget(request_rec *, union VALUETYPE *, unsigned char *, struct magic *, int);static int mcheck(request_rec *, union VALUETYPE *, struct magic *);static void mprint(request_rec *, union VALUETYPE *, struct magic *);static int uncompress(request_rec *, int, unsigned char **, int);static long from_oct(int, char *);static int fsmagic(request_rec *r, const char *fn);/* * includes for ASCII substring recognition formerly "names.h" in file * command * * Original notes: names and types used by ascmagic in file(1). These tokens are * here because they can appear anywhere in the first HOWMANY bytes, while * tokens in /etc/magic must appear at fixed offsets into the file. Don't * make HOWMANY too high unless you have a very fast CPU. *//* these types are used to index the table 'types': keep em in sync! *//* HTML inserted in first because this is a web server module now */#define L_HTML 0 /* HTML */#define L_C 1 /* first and foremost on UNIX */#define L_FORT 2 /* the oldest one */#define L_MAKE 3 /* Makefiles */#define L_PLI 4 /* PL/1 */#define L_MACH 5 /* some kinda assembler */#define L_ENG 6 /* English */#define L_PAS 7 /* Pascal */#define L_MAIL 8 /* Electronic mail */#define L_NEWS 9 /* Usenet Netnews */static char *types[] ={ "text/html", /* HTML */ "text/plain", /* "c program text", */ "text/plain", /* "fortran program text", */ "text/plain", /* "make commands text", */ "text/plain", /* "pl/1 program text", */ "text/plain", /* "assembler program text", */ "text/plain", /* "English text", */ "text/plain", /* "pascal program text", */ "message/rfc822", /* "mail text", */ "message/news", /* "news text", */ "application/binary", /* "can't happen error on names.h/types", */ 0};static struct names { char *name; short type;} names[] = { /* These must be sorted by eye for optimal hit rate */ /* Add to this list only after substantial meditation */ { "<html>", L_HTML }, { "<HTML>", L_HTML }, { "<head>", L_HTML }, { "<HEAD>", L_HTML }, { "<title>", L_HTML }, { "<TITLE>", L_HTML }, { "<h1>", L_HTML }, { "<H1>", L_HTML }, { "<!--", L_HTML }, { "<!DOCTYPE HTML", L_HTML }, { "/*", L_C }, /* must precede "The", "the", etc. */ { "#include", L_C }, { "char", L_C }, { "The", L_ENG }, { "the", L_ENG }, { "double", L_C }, { "extern", L_C }, { "float", L_C }, { "real", L_C }, { "struct", L_C }, { "union", L_C }, { "CFLAGS", L_MAKE }, { "LDFLAGS", L_MAKE }, { "all:", L_MAKE }, { ".PRECIOUS", L_MAKE }, /* * Too many files of text have these words in them. Find another way to * recognize Fortrash. */#ifdef NOTDEF { "subroutine", L_FORT }, { "function", L_FORT }, { "block", L_FORT }, { "common", L_FORT }, { "dimension", L_FORT }, { "integer", L_FORT }, { "data", L_FORT },#endif /* NOTDEF */ { ".ascii", L_MACH }, { ".asciiz", L_MACH }, { ".byte", L_MACH }, { ".even", L_MACH }, { ".globl", L_MACH }, { "clr", L_MACH }, { "(input,", L_PAS }, { "dcl", L_PLI }, { "Received:", L_MAIL }, { ">From", L_MAIL }, { "Return-Path:", L_MAIL }, { "Cc:", L_MAIL }, { "Newsgroups:", L_NEWS }, { "Path:", L_NEWS }, { "Organization:", L_NEWS }, { NULL, 0 }};#define NNAMES ((sizeof(names)/sizeof(struct names)) - 1)/* * Result String List (RSL) * * The file(1) command prints its output. Instead, we store the various * "printed" strings in a list (allocating memory as we go) and concatenate * them at the end when we finally know how much space they'll need. */typedef struct magic_rsl_s { char *str; /* string, possibly a fragment */ struct magic_rsl_s *next; /* pointer to next fragment */} magic_rsl;/* * Apache module configuration structures *//* per-server info */typedef struct { char *magicfile; /* where magic be found */ struct magic *magic; /* head of magic config list */ struct magic *last;} magic_server_config_rec;/* per-request info */typedef struct { magic_rsl *head; /* result string list */ magic_rsl *tail; unsigned suf_recursion; /* recursion depth in suffix check */} magic_req_rec;/* * configuration functions - called by Apache API routines */module MODULE_VAR_EXPORT mime_magic_module;static void *create_magic_server_config(pool *p, server_rec *d){ /* allocate the config - use pcalloc because it needs to be zeroed */ return ap_pcalloc(p, sizeof(magic_server_config_rec));}static void *merge_magic_server_config(pool *p, void *basev, void *addv){ magic_server_config_rec *base = (magic_server_config_rec *) basev; magic_server_config_rec *add = (magic_server_config_rec *) addv; magic_server_config_rec *new = (magic_server_config_rec *) ap_palloc(p, sizeof(magic_server_config_rec)); new->magicfile = add->magicfile ? add->magicfile : base->magicfile; new->magic = NULL; new->last = NULL; return new;}static const char *set_magicfile(cmd_parms *cmd, char *d, char *arg){ magic_server_config_rec *conf = (magic_server_config_rec *) ap_get_module_config(cmd->server->module_config, &mime_magic_module); if (!conf) { return MODNAME ": server structure not allocated"; } conf->magicfile = arg; return NULL;}/* * configuration file commands - exported to Apache API */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -