⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mimetypes.c

📁 一个很有名的浏览器
💻 C
字号:
/* Support for mime.types files for mapping file extensions to content types *//* $Id: mimetypes.c,v 1.48.2.3 2005/05/01 22:03:23 jonas Exp $ *//* Copyright (C) 1996-2000 Michael R. Elkins <me@cs.hmc.edu> * Copyright (C) 2003-2004 The ELinks Project */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <ctype.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include "elinks.h"#include "config/options.h"#include "intl/gettext/libintl.h"#include "modules/module.h"#include "mime/backend/common.h"#include "mime/backend/mimetypes.h"#include "mime/mime.h"#include "sched/session.h"#include "util/hash.h"#include "util/lists.h"#include "util/memory.h"#define BACKEND_NAME	"mimetypes"struct mimetypes_entry {	unsigned char *content_type;	unsigned char extension[1];};enum mimetypes_option {	MIMETYPES_TREE,	MIMETYPES_ENABLE,	MIMETYPES_PATH,	MIMETYPES_OPTIONS};/* Keep options in alphabetical order. */static struct option_info mimetypes_options[] = {	INIT_OPT_TREE("mime", N_("Mimetypes files"),		"mimetypes", 0,		N_("Options for the support of mime.types files. These files\n"		"can be used to find the content type of an URL by looking at\n"		"the extension of the file name.")),	INIT_OPT_BOOL("mime.mimetypes", N_("Enable"),		"enable", 0, 1,		N_("Enable mime.types support.")),	INIT_OPT_STRING("mime.mimetypes", N_("Path"),		"path", 0, DEFAULT_MIMETYPES_PATH,		N_("The search path for mime.types files. Colon-separated list of files.")),	NULL_OPTION_INFO,};#define get_opt_mimetypes(which)		mimetypes_options[(which)].option#define get_mimetypes(which)		get_opt_mimetypes(which).value#define get_mimetypes_enable()		get_mimetypes(MIMETYPES_ENABLE).number#define get_mimetypes_path()		get_mimetypes(MIMETYPES_PATH).string/* State variables */static struct hash *mimetypes_map = NULL;static int mimetypes_map_size = 0;static voiddone_mimetypes_entry(struct mimetypes_entry *entry){	if (!entry) return;	mem_free_if(entry->content_type);	mem_free(entry);}/* Parsing of a mime.types file with the format: * *	basetype/subtype	extension1 [extension2 ... extensionN] * * Comments starts with '#'. */static inline voidparse_mimetypes_extensions(unsigned char *token, unsigned char *ctype){	int ctypelen = strlen(ctype);	/* Cycle through the file extensions */	while (*token) {		struct mimetypes_entry *entry;		unsigned char *extension;		struct hash_item *item;		int extlen;		skip_space(token);		extension = token;		skip_nonspace(token);		if (!*token) break;		*token++ = '\0';		extlen = strlen(extension);		/* First check if the type is already known. If it is		 * drop it. This way first files are priotized. */		item = get_hash_item(mimetypes_map, extension, extlen);		if (item) continue;		entry = mem_calloc(1, sizeof(*entry) + extlen);		if (!entry) continue;		entry->content_type = memacpy(ctype, ctypelen);		if (!entry->content_type) {			done_mimetypes_entry(entry);			continue;		}		memcpy(entry->extension, extension, extlen);		item = add_hash_item(mimetypes_map, entry->extension, extlen,				     entry);		if (item)			mimetypes_map_size++;		else			done_mimetypes_entry(entry);	}}static voidparse_mimetypes_file(unsigned char *filename){	FILE *file = fopen(filename, "rb");	unsigned char line[MAX_STR_LEN];	if (!file) return;	while (fgets(line, MAX_STR_LEN - 1, file)) {		unsigned char *ctype = line;		unsigned char *token;		/* Weed out any comments */		token = strchr(line, '#');		if (token)			*token = '\0';		skip_space(ctype);		/* Position on the next field in this line */		token = ctype;		skip_nonspace(token);		if (!*token) continue;		*token++ = '\0';		/* Check if malformed content type */		if (!strchr(ctype, '/')) continue;		parse_mimetypes_extensions(token, ctype);	}	fclose(file);}static struct hash *init_mimetypes_map(void){	unsigned char *path;	mimetypes_map = init_hash(8, &strhash);	if (!mimetypes_map)		return NULL;	/* Determine the path  */	path = get_mimetypes_path();	if (!path || !*path) path = DEFAULT_MIMETYPES_PATH;	while (*path) {		unsigned char *filename = get_next_path_filename(&path, ':');		if (!filename) continue;		parse_mimetypes_file(filename);		mem_free(filename);	}	return mimetypes_map;}static voiddone_mimetypes(struct module *module){	struct hash_item *item;	int i;	if (!mimetypes_map)		return;	foreach_hash_item (item, *mimetypes_map, i) {		if (item->value) {			struct mimetypes_entry *entry = item->value;			done_mimetypes_entry(entry);		}	}	free_hash(mimetypes_map);	mimetypes_map = NULL;	mimetypes_map_size = 0;}static intchange_hook_mimetypes(struct session *ses, struct option *current, struct option *changed){	if (changed == &get_opt_mimetypes(MIMETYPES_PATH)	    || (changed == &get_opt_mimetypes(MIMETYPES_ENABLE)		&& !get_mimetypes_enable())) {		done_mimetypes(&mimetypes_mime_module);	}	return 0;}static voidinit_mimetypes(struct module *module){	struct change_hook_info mimetypes_change_hooks[] = {		{ "mime.mimetypes",		change_hook_mimetypes },		{ NULL,				NULL },	};	register_change_hooks(mimetypes_change_hooks);	if (get_cmd_opt_bool("anonymous"))		get_mimetypes_enable() = 0;}static unsigned char *get_content_type_mimetypes(unsigned char *extension){	struct hash_item *item;	int extensionlen;	if (!get_mimetypes_enable()	    || (!mimetypes_map && !init_mimetypes_map()))		return NULL;	extension++; /* Skip the leading '.' */	extensionlen = strlen(extension);	while (extensionlen) {		unsigned char *trimmed;		/* First the given type is looked up. */		item = get_hash_item(mimetypes_map, extension, extensionlen);		/* Check list of entries */		if (item && item->value) {			struct mimetypes_entry *entry = item->value;			return stracpy(entry->content_type);		}		/* Try to trim the extension from the left. */		trimmed = strchr(extension, '.');		if (!trimmed)			break;		extensionlen -= trimmed - extension + 1;		extension = trimmed + 1;	}	return NULL;}struct mime_backend mimetypes_mime_backend = {	/* get_content_type: */	get_content_type_mimetypes,	/* get_mime_handler: */	NULL,};struct module mimetypes_mime_module = struct_module(	/* name: */		N_("Mimetypes files"),	/* options: */		mimetypes_options,	/* hooks: */		NULL,	/* submodules: */	NULL,	/* data: */		NULL,	/* init: */		init_mimetypes,	/* done: */		done_mimetypes);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -