mailcap.c

来自「elinks下lynx是最重要的二个文本浏览器, 在linux下非常实用, el」· C语言 代码 · 共 788 行 · 第 1/2 页

C
788
字号
{	unsigned char *path;	unsigned int priority = 0;	mailcap_map = init_hash(8, &strhash);	if (!mailcap_map) return NULL;	/* Try to setup mailcap_path */	path = get_mailcap_path();	if (!path || !*path) path = getenv("MAILCAP");	if (!path) path = DEFAULT_MAILCAP_PATH;	while (*path) {		unsigned char *filename = get_next_path_filename(&path, ':');		if (!filename) continue;		parse_mailcap_file(filename, priority++);		mem_free(filename);	}	return mailcap_map;}static voiddone_mailcap(struct module *module){	struct hash_item *item;	int i;	if (!mailcap_map) return;	foreach_hash_item (item, *mailcap_map, i) {		struct mailcap_hash_item *mitem = item->value;		if (!mitem) continue;		while (!list_empty(mitem->entries)) {			struct mailcap_entry *entry = mitem->entries.next;			del_from_list(entry);			done_mailcap_entry(entry);		}		mem_free(mitem);	}	free_hash(mailcap_map);	mailcap_map = NULL;	mailcap_map_size = 0;}#ifndef TEST_MAILCAPstatic intchange_hook_mailcap(struct session *ses, struct option *current, struct option *changed){	if (changed == &get_opt_mailcap(MAILCAP_PATH)	    || (changed == &get_opt_mailcap(MAILCAP_ENABLE)		&& !get_mailcap_enable())) {		done_mailcap(&mailcap_mime_module);	}	return 0;}static voidinit_mailcap(struct module *module){	struct change_hook_info mimetypes_change_hooks[] = {		{ "mime.mailcap",		change_hook_mailcap },		{ NULL,				NULL },	};	register_change_hooks(mimetypes_change_hooks);	if (get_cmd_opt_bool("anonymous"))		get_mailcap_enable() = 0;}#else#define init_mailcap NULL#endif /* TEST_MAILCAP *//* The command semantics include the following: * * %s		is the filename that contains the mail body data * %t		is the content type, like text/plain * %{parameter} is replaced by the parameter value from the content-type *		field * \%		is % * * Unsupported RFC1524 parameters: these would probably require some doing * by Mutt, and can probably just be done by piping the message to metamail: * * %n		is the integer number of sub-parts in the multipart * %F		is "content-type filename" repeated for each sub-part * Only % is supported by subst_file() which is equivalent to %s. *//* The formatting is postponed until the command is needed. This means * @type can be NULL. If '%t' is used in command we bail out. */static unsigned char *format_command(unsigned char *command, unsigned char *type, int copiousoutput){	struct string cmd;	if (!init_string(&cmd)) return NULL;	while (*command) {		unsigned char *start = command;		while (*command && *command != '%' && *command != '\\')			command++;		if (start < command)			add_bytes_to_string(&cmd, start, command - start);		if (*command == '%') {			command++;			if (!*command) {				done_string(&cmd);				return NULL;			} else if (*command == 's') {				add_char_to_string(&cmd, '%');			} else if (*command == 't') {				if (!type) {					done_string(&cmd);					return NULL;				}				add_to_string(&cmd, type);			}			command++;		} else if (*command == '\\') {			command++;			if (*command) {				add_char_to_string(&cmd, *command);				command++;			}		}	}	if (copiousoutput) {		unsigned char *pager = getenv("PAGER");		if (!pager && file_exists(DEFAULT_PAGER_PATH)) {			pager = DEFAULT_PAGER_PATH;		} else if (!pager && file_exists(DEFAULT_LESS_PATH)) {			pager = DEFAULT_LESS_PATH;		} else if (!pager && file_exists(DEFAULT_MORE_PATH)) {			pager = DEFAULT_MORE_PATH;		}		if (pager) {			add_char_to_string(&cmd, '|');			add_to_string(&cmd, pager);		}	}	return cmd.source;}/* Returns first usable mailcap_entry from a list where @entry is the head. * Use of @filename is not supported (yet). */static struct mailcap_entry *check_entries(struct mailcap_hash_item *item){	struct mailcap_entry *entry;	foreach (entry, item->entries) {		unsigned char *test;		/* Accept current if no test is needed */		if (!entry->testcommand)			return entry;		/* We have to run the test command */		test = format_command(entry->testcommand, NULL, 0);		if (test) {			int exitcode = exe(test);			mem_free(test);			if (!exitcode)				return entry;		}	}	return NULL;}/* Attempts to find the given type in the mailcap association map.  On success, * this returns the associated command, else NULL.  Type is a string with * syntax '<base>/<type>' (ex: 'text/plain') * * First the given type is looked up. Then the given <base>-type with added * wildcard '*' (ex: 'text/<star>'). For each lookup all the associated * entries are checked/tested. * * The lookup supports testing on files. If no file is given (NULL) any tests * that need a file will be taken as failed. */static struct mailcap_entry *get_mailcap_entry(unsigned char *type){	struct mailcap_entry *entry;	struct hash_item *item;	item = get_hash_item(mailcap_map, type, strlen(type));	/* Check list of entries */	entry = (item && item->value) ? check_entries(item->value) : NULL;	if (!entry || get_mailcap_prioritize()) {		/* The type lookup has either failed or we need to check		 * the priorities so get the wild card handler */		struct mailcap_entry *wildcard = NULL;		unsigned char *wildpos = strchr(type, '/');		if (wildpos) {			int wildlen = wildpos - type + 1; /* include '/' */			unsigned char *wildtype = memacpy(type, wildlen + 2);			if (!wildtype) return NULL;			wildtype[wildlen++] = '*';			wildtype[wildlen] = '\0';			item = get_hash_item(mailcap_map, wildtype, wildlen);			mem_free(wildtype);			if (item && item->value)				wildcard = check_entries(item->value);		}		/* Use @wildcard if its priority is better or @entry is NULL */		if (wildcard && (!entry || (wildcard->priority < entry->priority)))			entry = wildcard;	}	return entry;}static struct mime_handler *get_mime_handler_mailcap(unsigned char *type, int options){	struct mailcap_entry *entry;	struct mime_handler *handler;	unsigned char *program;	int block;	if (!get_mailcap_enable()	    || (!mailcap_map && !init_mailcap_map()))		return NULL;	entry = get_mailcap_entry(type);	if (!entry) return NULL;	program = format_command(entry->command, type, entry->copiousoutput);	if (!program) return NULL;	block = (entry->needsterminal || entry->copiousoutput);	handler = init_mime_handler(program, entry->description,				    mailcap_mime_module.name,				    get_mailcap_ask(), block);	mem_free(program);	return handler;}struct mime_backend mailcap_mime_backend = {	/* get_content_type: */	NULL,	/* get_mime_handler: */	get_mime_handler_mailcap,};/* Setup the exported module. */struct module mailcap_mime_module = struct_module(	/* name: */		N_("Mailcap"),	/* options: */		mailcap_options,	/* hooks: */		NULL,	/* submodules: */	NULL,	/* data: */		NULL,	/* init: */		init_mailcap,	/* done: */		done_mailcap);#ifdef TEST_MAILCAP/* Some ugly shortcuts for getting defined symbols to work. */int default_mime_backend,    install_signal_handler,    mimetypes_mime_backend,    program;struct list_head terminals;void die(const char *msg, ...){	va_list args;	if (msg) {		va_start(args, msg);		vfprintf(stderr, msg, args);		fputs("\n", stderr);		va_end(args);	}	exit(1);}intmain(int argc, char *argv[]){	unsigned char *format = "description,ask,block,program";	int has_gotten = 0;	int i;	for (i = 1; i < argc; i++) {		char *arg = argv[i];		if (strncmp(arg, "--", 2))			break;		arg += 2;		if (!strncmp(arg, "path", 4)) {			arg += 4;			if (*arg == '=') {				arg++;				get_mailcap_path() = arg;			} else {				i++;				if (i >= argc)					die("--path expects a parameter");				get_mailcap_path() = argv[i];			}			done_mailcap(NULL);		} else if (!strncmp(arg, "format", 6)) {			arg += 6;			if (*arg == '=') {				arg++;				format = arg;			} else {				i++;				if (i >= argc)					die("--format expects a parameter");				format = argv[i];			}		} else if (!strncmp(arg, "get", 3)) {			struct mime_handler *handler;			arg += 3;			if (*arg == '=') {				arg++;			} else {				i++;				if (i >= argc)					die("--get expects a parameter");				arg = argv[i];			}			if (has_gotten)				printf("\n");			has_gotten = 1;			printf("type: %s\n", arg);			handler = get_mime_handler_mailcap(arg, 0);			if (!handler) continue;			if (strstr(format, "description"))				printf("description: %s\n", handler->description);			if (strstr(format, "ask"))				printf("ask: %d\n", handler->ask);			if (strstr(format, "block"))				printf("block: %d\n", handler->block);			if (strstr(format, "program"))				printf("program: %s\n", handler->program);		} else {			die("Unknown argument '%s'", arg - 2);		}	}	done_mailcap(NULL);	return 0;}#endif /* TEST_MAILCAP */

⌨️ 快捷键说明

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