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

📄 mime.c

📁 一个很有名的浏览器
💻 C
字号:
/* Functionality for handling mime types *//* $Id: mime.c,v 1.70 2004/10/14 18:50:37 jonas Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <string.h>#include "elinks.h"#include "cache/cache.h"#include "config/options.h"#include "encoding/encoding.h"#include "intl/gettext/libintl.h"#include "mime/backend/common.h"#include "mime/mime.h"#include "modules/module.h"#include "protocol/header.h"	/* For parse_header() */#include "protocol/uri.h"#include "util/conv.h"#include "util/file.h"#include "util/memory.h"#include "util/string.h"enum mime_options {	MIME_TREE,	MIME_DEFAULT_TYPE,	MIME_OPTIONS,};static struct option_info mime_options[] = {	INIT_OPT_TREE("", N_("MIME"),		"mime", OPT_SORT,		N_("MIME-related options (handlers of various MIME types).")),	INIT_OPT_STRING("mime", N_("Default MIME-type"),		"default_type", 0, DEFAULT_MIME_TYPE,		N_("Document MIME-type to assume by default (when we are unable to\n"		"guess it properly from known information about the document).")),	NULL_OPTION_INFO,};#define get_opt_mime(which)	mime_options[(which)].option#define get_default_mime_type()	get_opt_mime(MIME_DEFAULT_TYPE).value.string/* Checks protocols headers for a suitable filename */static unsigned char *get_content_filename(struct uri *uri, struct cache_entry *cached){	unsigned char *filename, *pos;	if (!cached) cached = find_in_cache(uri);	if (!cached || !cached->head)		return NULL;	pos = parse_header(cached->head, "Content-Disposition", NULL);	if (!pos) return NULL;	filename = parse_header_param(pos, "filename");	mem_free(pos);	if (!filename) return NULL;	/* We don't want to add any directories from the path so make sure we	 * only add the filename. */	pos = get_filename_position(filename);	if (!*pos) {		mem_free(filename);		return NULL;	}	if (pos > filename)		memmove(filename, pos, strlen(pos) + 1);	return filename;}/* Checks if application/x-<extension> has any handlers. */static inline unsigned char *check_extension_type(unsigned char *extension){	/* Trim the extension so only last .<extension> is used. */	unsigned char *trimmed = strrchr(extension, '.');	struct mime_handler *handler;	unsigned char *content_type;	if (!trimmed)		return NULL;	content_type = straconcat("application/x-", trimmed + 1, NULL);	if (!content_type)		return NULL;	handler = get_mime_type_handler(content_type, 1);	if (handler) {		mem_free(handler);		return content_type;	}	mem_free(content_type);	return NULL;}/* Check if part of the extension coresponds to a supported encoding and if it * has any handlers. */static inline unsigned char *check_encoding_type(unsigned char *extension){	enum stream_encoding encoding = guess_encoding(extension);	unsigned char **extension_list;	unsigned char *last_extension = strrchr(extension, '.');	if (encoding == ENCODING_NONE || !last_extension)		return NULL;	for (extension_list = listext_encoded(encoding);	     extension_list && *extension_list;	     extension_list++) {		unsigned char *content_type;		if (strcmp(*extension_list, last_extension))			continue;		*last_extension = '\0';		content_type = get_content_type_backends(extension);		*last_extension = '.';		return content_type;	}	return NULL;}#if 0#define DEBUG_CONTENT_TYPE#endif#ifdef DEBUG_CONTENT_TYPE#define debug_get_content_type_params(cached) \	DBG("get_content_type(head, url)\n=== head ===\n%s\n=== url ===\n%s\n", (cached)->head, struri((cached)->uri))#define debug_ctype(ctype__) DBG("ctype= %s", (ctype__))#define debug_extension(extension__) DBG("extension= %s", (extension__))#else#define debug_get_content_type_params(cached)#define debug_ctype(ctype__)#define debug_extension(extension__)#endifunsigned char *get_extension_content_type(unsigned char *extension){	unsigned char *ctype;	assert(extension && *extension);	ctype = get_content_type_backends(extension);	debug_ctype(ctype);	if (ctype) return ctype;	ctype = check_encoding_type(extension);	debug_ctype(ctype);	if (ctype) return ctype;	ctype = check_extension_type(extension);	debug_ctype(ctype);	return ctype;}unsigned char *get_cache_header_content_type(struct cache_entry *cached){	unsigned char *extension, *ctype;	ctype = parse_header(cached->head, "Content-Type", NULL);	if (ctype) {		unsigned char *end = strchr(ctype, ';');		int ctypelen;		if (end) *end = '\0';		ctypelen = strlen(ctype);		while (ctypelen && ctype[--ctypelen] <= ' ')			ctype[ctypelen] = '\0';		debug_ctype(ctype);		if (*ctype) {			return ctype;		}		mem_free(ctype);	}	/* This searches cached->head for filename so put here */	extension = get_content_filename(cached->uri, cached);	debug_extension(extension);	if (extension) {		ctype = get_extension_content_type(extension);		mem_free(extension);		if (ctype) {			return ctype;		}	}	return NULL;}unsigned char *get_content_type(struct cache_entry *cached){	unsigned char *extension, *ctype;	debug_get_content_type_params(cached);	if (cached->content_type)		return cached->content_type;	/* If there's one in header, it's simple.. */	if (cached->head) {		ctype = get_cache_header_content_type(cached);		if (ctype && *ctype) {			cached->content_type = ctype;			return ctype;		}		mem_free_if(ctype);	}	/* We can't use the extension string we are getting below, because we	 * want to support also things like "ps.gz" - that'd never work, as we	 * would always compare only to "gz". */	/* Guess type accordingly to the extension */	extension = get_extension_from_uri(cached->uri);	debug_extension(extension);	if (extension) {		/* XXX:	A little hack for making extension handling case		 * insensitive. We could probably do it better by making		 * guess_encoding() case independent the real problem however		 * is with default (via option system) and mimetypes resolving		 * doing that option and hash lookup will not be easy to		 * convert. --jonas */		convert_to_lowercase(extension, strlen(extension));		ctype = get_extension_content_type(extension);		mem_free(extension);		if (ctype && *ctype) {			cached->content_type = ctype;			return ctype;		}		mem_free_if(ctype);	}	debug_ctype(get_default_mime_type());	/* Fallback.. use some hardwired default */	cached->content_type = stracpy(get_default_mime_type());	return cached->content_type;}struct mime_handler *get_mime_type_handler(unsigned char *content_type, int xwin){	return get_mime_handler_backends(content_type, xwin);}struct string *add_mime_filename_to_string(struct string *string, struct uri *uri){	unsigned char *filename = get_content_filename(uri, NULL);	assert(uri->data);	if (filename) {		add_shell_safe_to_string(string, filename, strlen(filename));		mem_free(filename);		return string;	}	return add_uri_to_string(string, uri, URI_FILENAME);}/* Backends dynamic area: */#include "mime/backend/default.h"#include "mime/backend/mailcap.h"#include "mime/backend/mimetypes.h"static struct module *mime_submodules[] = {	&default_mime_module,#ifdef CONFIG_MAILCAP	&mailcap_mime_module,#endif#ifdef CONFIG_MIMETYPES	&mimetypes_mime_module,#endif	NULL,};struct module mime_module = struct_module(	/* name: */		N_("MIME"),	/* options: */		mime_options,	/* hooks: */		NULL,	/* submodules: */	mime_submodules,	/* data: */		NULL,	/* init: */		NULL,	/* done: */		NULL);

⌨️ 快捷键说明

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