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 + -
显示快捷键?