diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2019-02-02 09:04:42 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2019-02-03 11:54:13 +0200 |
commit | 18e23d6e98bc5942269e385dbb9ea9f0886909ef (patch) | |
tree | 9f0a9bb42901c46976eaf23c275ce65d0d03ac41 | |
parent | 8360e84e5a673211488ee31c93922c987c057007 (diff) | |
download | mailutils-18e23d6e98bc5942269e385dbb9ea9f0886909ef.tar.gz mailutils-18e23d6e98bc5942269e385dbb9ea9f0886909ef.tar.bz2 |
Rewrite the mailcap support
* configure.ac: Build libmailutils/mailcap/Makefile
* include/mailutils/mailcap.h: Rewrite
* include/mailutils/sys/Makefile.am: Add mailcap.h
* include/mailutils/sys/mailcap.h: New file.
* include/mailutils/util.h: Add missing include.
* lib/mailcap.c: Rewrite using new API.
* libmailutils/Makefile.am: Build in mailcap
* libmailutils/base/Makefile.am: Remove mailcap.c
* libmailutils/base/mailcap.c: Remove.
* libmailutils/mailcap/Makefile.am: New file.
* libmailutils/mailcap/ctmatch.c: New file.
* libmailutils/mailcap/deferrclos.c: New file.
* libmailutils/mailcap/mcp_creat.c: New file.
* libmailutils/mailcap/mcp_destr.c: New file.
* libmailutils/mailcap/mcp_err.c: New file.
* libmailutils/mailcap/mcp_flags.c: New file.
* libmailutils/mailcap/mcp_get.c: New file.
* libmailutils/mailcap/mcp_sel.c: New file.
* libmailutils/mailcap/mcp_count.c: New file.
* libmailutils/mailcap/mcp_find.c: New file.
* libmailutils/mailcap/ent_cmd.c: New file.
* libmailutils/mailcap/ent_creat.c: New file.
* libmailutils/mailcap/ent_destr.c: New file.
* libmailutils/mailcap/ent_locus.c: New file.
* libmailutils/mailcap/ent_type.c: New file.
* libmailutils/mailcap/fieldacc.c: New file.
* libmailutils/mailcap/fields.c: New file.
* libmailutils/mailcap/finder.c: New file.
* libmailutils/mailcap/parse.c: New file.
* libmailutils/mailcap/parsefile.c: New file.
* libmailutils/tests/mailcap.c: Rewrite using new API. Improve cli
* libmailutils/tests/mcf.c: New file.
* libmailutils/tests/ctm.c: New file.
* libmailutils/tests/ctm.at: New file.
* libmu_cpp/mailcap.cc: Rewrite using new API.
* python/2/libmu_py/mailcap.c: Rewrite using new API.
* python/3/libmu_py/mailcap.c: Rewrite using new API.
* examples/python/2/mailcap.py: Minor change. This example is
broken with the new API. Should be fixed.
* include/mailutils/cpp/mailcap.h: Update
* include/mailutils/cpp/pop3.h: Update
44 files changed, 2728 insertions, 1167 deletions
diff --git a/configure.ac b/configure.ac index 4efd44198..be5ee11d6 100644 --- a/configure.ac +++ b/configure.ac @@ -1550,6 +1550,7 @@ AC_CONFIG_FILES([ libmailutils/list/Makefile libmailutils/locus/Makefile libmailutils/mailbox/Makefile + libmailutils/mailcap/Makefile libmailutils/mailer/Makefile libmailutils/mime/Makefile libmailutils/msgset/Makefile diff --git a/examples/python/2/mailcap.py b/examples/python/2/mailcap.py index 24e86e880..d88bf9073 100644 --- a/examples/python/2/mailcap.py +++ b/examples/python/2/mailcap.py @@ -15,8 +15,9 @@ # along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. from mailutils import stream, mailcap +from os import environ -stm = stream.FileStream ("/etc/mailcap") +stm = stream.FileStream (environ['MAILCAP'] if 'MAILCAP' in environ else "/etc/mailcap") mc = mailcap.Mailcap (stm) for i, entry in enumerate (mc): diff --git a/include/mailutils/cpp/mailcap.h b/include/mailutils/cpp/mailcap.h index 2b259238f..d5847794c 100644 --- a/include/mailutils/cpp/mailcap.h +++ b/include/mailutils/cpp/mailcap.h @@ -40,10 +40,10 @@ class MailcapEntry size_t fields_count (); std::string get_typefield (); std::string get_viewcommand (); - std::string get_field (size_t i); + std::string get_field (const std::string& name); - inline std::string operator [] (size_t i) { - return this->get_field (i); + inline std::string operator [] (const std::string& name) { + return this->get_field (name); } }; @@ -58,10 +58,10 @@ class Mailcap ~Mailcap (); size_t entries_count (); - MailcapEntry& get_entry (size_t i); + MailcapEntry& find_entry (const std::string& name); - inline MailcapEntry& operator [] (size_t i) { - return this->get_entry (i); + inline MailcapEntry& operator [] (const std::string& name) { + return this->find_entry (name); } }; diff --git a/include/mailutils/cpp/pop3.h b/include/mailutils/cpp/pop3.h index abf8d35aa..192ec6f24 100644 --- a/include/mailutils/cpp/pop3.h +++ b/include/mailutils/cpp/pop3.h @@ -56,7 +56,7 @@ class Pop3 void quit (); Stream& retr (unsigned int msgno); void rset (); - void stat (unsigned int* count, mu_off_t* octets); + void stat (size_t* count, mu_off_t* octets); Stream& top (unsigned int msgno, unsigned int lines); std::string uidl (unsigned int msgno); Iterator& uidl_all (); diff --git a/include/mailutils/mailcap.h b/include/mailutils/mailcap.h index 85abf5715..8cb7372d8 100644 --- a/include/mailutils/mailcap.h +++ b/include/mailutils/mailcap.h @@ -20,98 +20,130 @@ #include <mailutils/types.h> #include <mailutils/errno.h> +#include <mailutils/locus.h> +#include <mailutils/util.h> /* See RFC1524 (A User Agent Configuration Mechanism). */ #ifdef __cplusplus extern "C" { #endif +#if 0 +} +#endif -/* Create a mailcap from stream. */ -int mu_mailcap_create (mu_mailcap_t * mailcap, mu_stream_t stream); - -/* Destroy mailcap object. */ -void mu_mailcap_destroy (mu_mailcap_t * mailcap); - -/* Return the number of entries in the mailcap file. */ -int mu_mailcap_entries_count (mu_mailcap_t mailcap, size_t *pno); - -/* Return the mailcap record number, no, of the mailcap file . */ -int mu_mailcap_get_entry (mu_mailcap_t mailcap, size_t no, +struct mu_mailcap_selector_closure +{ + int (*selector) (mu_mailcap_entry_t, void *); + void *data; + void (*data_free) (void *); +}; + +struct mu_mailcap_error_closure +{ + void (*error) (void *, struct mu_locus_range const *, char const *); + void *data; + void (*data_free) (void *); +}; + +extern struct mu_mailcap_error_closure mu_mailcap_default_error_closure; + +#define MU_MAILCAP_FLAG_DEFAULT 0 +#define MU_MAILCAP_FLAG_LOCUS 0x1 + +int mu_mailcap_create (mu_mailcap_t *pmailcap); +void mu_mailcap_destroy (mu_mailcap_t *pmailcap); + +int mu_mailcap_set_flags (mu_mailcap_t mailcap, int flags); +int mu_mailcap_get_flags (mu_mailcap_t mailcap, int *flags); + +int mu_mailcap_set_error (mu_mailcap_t mailcap, + struct mu_mailcap_error_closure const *err); +int mu_mailcap_get_error (mu_mailcap_t mailcap, + struct mu_mailcap_error_closure *err); +int mu_mailcap_set_selector (mu_mailcap_t mailcap, + struct mu_mailcap_selector_closure const *sel); +int mu_mailcap_get_selector (mu_mailcap_t mailcap, + struct mu_mailcap_selector_closure *sel); + +int mu_mailcap_get_count (mu_mailcap_t mailcap, size_t *pcount); +int mu_mailcap_get_iterator (mu_mailcap_t mailcap, mu_iterator_t *pitr); +int mu_mailcap_foreach (mu_mailcap_t mailcap, + int (*action) (mu_mailcap_entry_t, void *), + void *data); +int mu_mailcap_get_entry (mu_mailcap_t mailcap, size_t n, + mu_mailcap_entry_t *entry); +int mu_mailcap_find_entry (mu_mailcap_t mailcap, char const *type, mu_mailcap_entry_t *entry); -/* Return the number of fields in a mailcap entry */ -int mu_mailcap_entry_fields_count (mu_mailcap_entry_t entry, - size_t *pcount); - -/* Save in buffer[] the content-type of the record. */ -int mu_mailcap_entry_get_typefield (mu_mailcap_entry_t entry, - char *buffer, size_t buflen, - size_t *pn); - -/* Save in buffer[] the view command of the record. */ -int mu_mailcap_entry_get_viewcommand (mu_mailcap_entry_t entry, - char *buffer, size_t buflen, - size_t *pn); - -/* Save in buffer[] the field number no the record . */ -int mu_mailcap_entry_get_field (mu_mailcap_entry_t entry, size_t no, - char *buffer, size_t buflen, size_t *pn); - -/* Save in buffer the value of a key: - * mu_mailcap_entry_get_value (entry, "compose", buffer, buflen, pn); - * i.e compose="lynx %s" --> "lynx %s" will be saved in the buffer without - * the quotes. */ -int mu_mailcap_entry_get_value (mu_mailcap_entry_t entry, const char *key, - char *buffer, size_t buflen, size_t *pn); +int mu_mailcap_parse (mu_mailcap_t mailcap, mu_stream_t input, + struct mu_locus_point const *pt); +int mu_mailcap_parse_file (mu_mailcap_t mailcap, char const *file_name); -/* Helper function saving in buffer, the argument of "compose" field. */ -int mu_mailcap_entry_get_compose (mu_mailcap_entry_t entry, char *buffer, - size_t buflen, size_t *pn); +int mu_mailcap_entry_create (mu_mailcap_entry_t *ret_entry, + char *type, char *command); +void mu_mailcap_entry_destroy (mu_mailcap_entry_t *pent); +void mu_mailcap_entry_destroy_item (void *ptr); -/* Helper function saving in buffer, the argument of "composetyped" field. */ -int mu_mailcap_entry_get_composetyped (mu_mailcap_entry_t entry, +int mu_mailcap_entry_sget_type (mu_mailcap_entry_t ent, char const **ptype); +int mu_mailcap_entry_aget_type (mu_mailcap_entry_t ent, char **ptype); +int mu_mailcap_entry_get_type (mu_mailcap_entry_t ent, char *buffer, size_t buflen, size_t *pn); -/* Helper function saving in buffer, the argument of "edit" field. */ -int mu_mailcap_entry_get_edit (mu_mailcap_entry_t entry, char *buffer, - size_t buflen, size_t *pn); - -/* Helper function saving in buffer, the argument of "textualnewlines" field. */ -int mu_mailcap_entry_get_textualnewlines (mu_mailcap_entry_t entry, +int mu_mailcap_entry_sget_command (mu_mailcap_entry_t ent, char const **pcommand); +int mu_mailcap_entry_aget_command (mu_mailcap_entry_t ent, char **pcommand); +int mu_mailcap_entry_get_command (mu_mailcap_entry_t ent, char *buffer, size_t buflen, size_t *pn); -/* Helper function saving in buffer, the argument of "test" field. */ -int mu_mailcap_entry_get_test (mu_mailcap_entry_t entry, - char *buffer, size_t buflen, size_t *pn); - -/* Helper function saving in buffer, the argument of "x11-bitmap" field. */ -int mu_mailcap_entry_get_x11bitmap (mu_mailcap_entry_t entry, - char *buffer, size_t buflen, size_t *pn); - -/* Helper function saving in buffer, the argument of "description" field. */ -int mu_mailcap_entry_get_description (mu_mailcap_entry_t entry, +int mu_mailcap_entry_get_locus (mu_mailcap_entry_t ent, + struct mu_locus_range *loc); + +void mu_mailcap_entry_field_deallocate (void *ptr); +int mu_mailcap_entry_set_bool (mu_mailcap_entry_t ent, char const *name); +int mu_mailcap_entry_set_string (mu_mailcap_entry_t ent, char const *name, + char const *value); +int mu_mailcap_entry_field_unset (mu_mailcap_entry_t ent, char const *name); +int mu_mailcap_entry_fields_count (mu_mailcap_entry_t ent, size_t *pcount); +int mu_mailcap_entry_fields_foreach (mu_mailcap_entry_t ent, + int (*action) (char const *, char const *, void *), + void *data); +int mu_mailcap_entry_fields_get_iterator (mu_mailcap_entry_t ent, + mu_iterator_t *pitr); + +int mu_mailcap_entry_sget_field (mu_mailcap_entry_t ent, char const *name, + char const **pval); +int mu_mailcap_entry_aget_field (mu_mailcap_entry_t ent, char const *name, + char **pval); +int mu_mailcap_entry_get_field (mu_mailcap_entry_t ent, + char const *name, char *buffer, size_t buflen, size_t *pn); -/* Helper function saving in buffer, the argument of "nametemplate" field. */ -int mu_mailcap_entry_get_nametemplate (mu_mailcap_entry_t entry, - char *buffer, size_t buflen, - size_t *pn); - -/* Helper function saving in buffer, the argument of "notes" field. */ -int mu_mailcap_entry_get_notes (mu_mailcap_entry_t entry, char *buffer, - size_t buflen, size_t *pn); - -/* Helper function. Returns *on != 0 if the flag "needsterminal" is in the - record. */ -int mu_mailcap_entry_needsterminal (mu_mailcap_entry_t entry, int *on); - -/* Helper function. Returns *on != 0 if the flag "copiousoutput" is in the - record. */ -int mu_mailcap_entry_copiousoutput (mu_mailcap_entry_t entry, int *on); +#define MU_MAILCAP_NEEDSTERMINAL "needsterminal" +#define MU_MAILCAP_COPIOUSOUTPUT "copiousoutput" +#define MU_MAILCAP_COMPOSE "compose" +#define MU_MAILCAP_COMPOSETYPED "composetyped" +#define MU_MAILCAP_PRINT "print" +#define MU_MAILCAP_EDIT "edit" +#define MU_MAILCAP_TEST "test" +#define MU_MAILCAP_X11_BITMAP "x11-bitmap" +#define MU_MAILCAP_TEXTUALNEWLINES "textualnewlines" +#define MU_MAILCAP_DESCRIPTION "description" + +int mu_mailcap_string_match (char const *pattern, int delim, char const *type); +int mu_mailcap_content_type_match (const char *pattern, int delim, + mu_content_type_t ct); + +typedef struct _mu_mailcap_finder *mu_mailcap_finder_t; + +int mu_mailcap_finder_create (mu_mailcap_finder_t *, int, + struct mu_mailcap_selector_closure *, + struct mu_mailcap_error_closure *, + char **file_names); +int mu_mailcap_finder_next_match (mu_mailcap_finder_t, mu_mailcap_entry_t *); +void mu_mailcap_finder_destroy (mu_mailcap_finder_t *); #ifdef __cplusplus } diff --git a/include/mailutils/sys/Makefile.am b/include/mailutils/sys/Makefile.am index 11cf643fc..08d87560b 100644 --- a/include/mailutils/sys/Makefile.am +++ b/include/mailutils/sys/Makefile.am @@ -36,6 +36,7 @@ sysinclude_HEADERS = \ list.h\ logstream.h\ mailbox.h\ + mailcap.h\ mailer.h\ mapfile_stream.h\ memory_stream.h\ diff --git a/include/mailutils/sys/mailcap.h b/include/mailutils/sys/mailcap.h new file mode 100644 index 000000000..bc8140f0c --- /dev/null +++ b/include/mailutils/sys/mailcap.h @@ -0,0 +1,58 @@ +/* GNU Mailutils -- a suite of utilities for electronic mail + Copyright (C) 1999-2019 Free Software Foundation, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library. If not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _MAILUTILS_SYS_MAILCAP_H +# define _MAILUTILS_SYS_MAILCAP_H +# include <mailutils/mailcap.h> +# include <mailutils/locus.h> + +struct _mu_mailcap_entry +{ + char *type; + char *command; + mu_assoc_t fields; + struct mu_locus_range *lrp; +}; + +enum fld_type + { + fld_bool, + fld_string + }; + +struct mailcap_field +{ + enum fld_type type; + char *strval; +}; + +struct _mu_mailcap +{ + int flags; + mu_list_t elist; + struct mu_mailcap_selector_closure selector; + struct mu_mailcap_error_closure error; + struct mu_locus_range locus; +}; + +struct _mu_mailcap_finder +{ + struct _mu_mailcap *mcp; + mu_iterator_t itr; +}; + +#endif diff --git a/include/mailutils/util.h b/include/mailutils/util.h index ec902d280..26c9bb359 100644 --- a/include/mailutils/util.h +++ b/include/mailutils/util.h @@ -23,6 +23,7 @@ #include <mailutils/list.h> #include <mailutils/types.h> #include <mailutils/cidr.h> +#include <mailutils/filter.h> #ifdef __cplusplus extern "C" { diff --git a/lib/mailcap.c b/lib/mailcap.c index dd84e081e..ba819ae97 100644 --- a/lib/mailcap.c +++ b/lib/mailcap.c @@ -18,15 +18,7 @@ # include <config.h> #endif #include <mailutils/mailutils.h> -#include <fnmatch.h> #include <sys/wait.h> -#include <ctype.h> - -/* FNM_CASEFOLD is a GNU extension. Provide a replacement for systems - lacking it. */ -#ifndef FNM_CASEFOLD -# define FNM_CASEFOLD 0 -#endif /* Default mailcap path, the $HOME/.mailcap: entry is prepended to it */ #define DEFAULT_MAILCAP \ @@ -43,13 +35,12 @@ struct mime_context { mu_stream_t input; mu_header_t hdr; - char *content_type_buffer; - char *content_type; - mu_list_t values; + mu_content_type_t content_type; + char *temp_file; int unlink_temp_file; - mu_list_t no_ask_types; + char *no_ask_types; int dh; int flags; }; @@ -59,28 +50,21 @@ mime_context_fill (struct mime_context *ctx, const char *file, mu_stream_t input, mu_header_t hdr, const char *no_ask, int interactive, int dry_run, mu_debug_handle_t dh) { - struct mu_wordsplit ws; - size_t i; + int rc; + char *buffer; memset (ctx, 0, sizeof *ctx); ctx->input = input; ctx->hdr = hdr; - if (mu_header_aget_value (hdr, MU_HEADER_CONTENT_TYPE, - &ctx->content_type_buffer)) + + rc = mu_header_aget_value_unfold (hdr, MU_HEADER_CONTENT_TYPE, &buffer); + if (rc) return 1; - ws.ws_delim = ";"; - if (mu_wordsplit (ctx->content_type_buffer, &ws, - MU_WRDSF_DELIM|MU_WRDSF_SQUEEZE_DELIMS|MU_WRDSF_WS| - MU_WRDSF_NOVAR|MU_WRDSF_NOCMD)) - { - mu_error (_("cannot split line `%s': %s"), - ctx->content_type_buffer, - mu_wordsplit_strerror (&ws)); + rc = mu_content_type_parse (buffer, NULL, &ctx->content_type); + free (buffer); + if (rc) return 1; - } - ctx->content_type = ws.ws_wordv[0]; - ws.ws_wordv[0] = NULL; ctx->temp_file = file ? mu_strdup (file) : NULL; ctx->unlink_temp_file = 0; @@ -90,55 +74,19 @@ mime_context_fill (struct mime_context *ctx, const char *file, ctx->flags |= FLAGS_DRY_RUN; ctx->dh = dh; - mu_list_create (&ctx->values); + ctx->no_ask_types = no_ask ? mu_strdup (no_ask) : NULL; - for (i = 1; i < ws.ws_wordc; i++) - { - mu_list_append (ctx->values, ws.ws_wordv[i]); - ws.ws_wordv[i] = NULL; - } - mu_wordsplit_free (&ws); - - if (no_ask) - { - mu_list_create (&ctx->no_ask_types); - mu_list_set_destroy_item (ctx->no_ask_types, mu_list_free_item); - if (mu_string_split (no_ask, ",", ctx->no_ask_types)) - return 1; - } return 0; } static void mime_context_release (struct mime_context *ctx) { - free (ctx->content_type_buffer); + mu_content_type_destroy (&ctx->content_type); if (ctx->unlink_temp_file) unlink (ctx->temp_file); free (ctx->temp_file); - mu_list_destroy (&ctx->values); - mu_list_destroy (&ctx->no_ask_types); -} - -static int -mime_context_do_not_ask (struct mime_context *ctx) -{ - int rc = 0; - - if (ctx->no_ask_types) - { - mu_iterator_t itr; - mu_list_get_iterator (ctx->no_ask_types, &itr); - for (mu_iterator_first (itr); !rc && !mu_iterator_is_done (itr); - mu_iterator_next (itr)) - { - char *p; - mu_iterator_current (itr, (void**)&p); - rc = fnmatch (p, ctx->content_type, FNM_CASEFOLD) == 0; - } - mu_iterator_destroy (&itr); - } - return rc; + free (ctx->no_ask_types); } static int @@ -154,50 +102,11 @@ interactive_p (struct mime_context *ctx) } static void -mime_context_get_content_type (struct mime_context *ctx, char **ptr) -{ - *ptr = ctx->content_type; -} - -static void mime_context_get_input (struct mime_context *ctx, mu_stream_t *pinput) { *pinput = ctx->input; } -static int -mime_context_get_content_type_value (struct mime_context *ctx, - char *name, size_t len, - char **ptr, size_t *plen) -{ - mu_iterator_t itr = NULL; - int rc = 1; - - mu_list_get_iterator (ctx->values, &itr); - for (mu_iterator_first (itr); - !mu_iterator_is_done (itr); mu_iterator_next (itr)) - { - char *item, *p; - - mu_iterator_current (itr, (void**) &item); - p = strchr (item, '='); - if (p - item == len && strncasecmp (item, name, len) == 0) - { - rc = 0; - *ptr = ++p; - *plen = strlen (*ptr); - if (**ptr == '"') - { - ++*ptr; - *plen -= 2; - } - break; - } - } - mu_iterator_destroy (&itr); - return rc; -} - /* FIXME: Rewrite via mu_stream_copy */ static void mime_context_write_input (struct mime_context *ctx, int fd) @@ -239,12 +148,13 @@ mime_context_get_temp_file (struct mime_context *ctx, char **ptr) static mu_opool_t expand_pool; static int -expand_string (struct mime_context *ct, char **pstr) +expand_string (struct mime_context *ct, char const *input, char **pstr) { - char *p, *s; + char const *p; + char *s; int rc = 0; - for (p = *pstr; *p; ) + for (p = input; *p; ) { switch (p[0]) { @@ -259,24 +169,32 @@ expand_string (struct mime_context *ct, char **pstr) break; case 't': - mime_context_get_content_type (ct, &s); - mu_opool_appendz (expand_pool, s); + mu_opool_appendz (expand_pool, ct->content_type->type); + mu_opool_append_char (expand_pool, '/'); + mu_opool_appendz (expand_pool, ct->content_type->subtype); p += 2; break; case '{': { size_t n; - char *q; + char const *q; + char *namebuf; + struct mu_mime_param *param; p += 2; q = p; while (*p && *p != '}') p++; - if (mime_context_get_content_type_value (ct, - q, p-q, - &s, &n) == 0) - mu_opool_append (expand_pool, s, n); + n = p - q; + namebuf = mu_alloc (n + 1); + memcpy (namebuf, q, n); + namebuf[n] = 0; + param = mu_assoc_get (ct->content_type->param, namebuf); + if (param) + /* FIXME: cset? */ + mu_opool_appendz (expand_pool, param->value); + free (namebuf); if (*p) p++; break; @@ -333,10 +251,10 @@ confirm_action (struct mime_context *ctx, const char *str) { char repl[128], *p; int len; - char *type; - mime_context_get_content_type (ctx, &type); - if (!interactive_p (ctx) || mime_context_do_not_ask (ctx)) + if (!interactive_p (ctx) + || mu_mailcap_content_type_match (ctx->no_ask_types, ',', + ctx->content_type) == 0) return 1; printf (_("Run `%s'?"), str); @@ -352,36 +270,40 @@ confirm_action (struct mime_context *ctx, const char *str) return mu_true_answer_p (p); } +struct list_closure +{ + unsigned long n; +}; + +static int +list_field (char const *name, char const *value, void *data) +{ + struct list_closure *fc = data; + printf ("\tfields[%lu]: ", fc->n++); + if (value) + printf ("%s=%s", name, value); + else + printf ("%s", name); + printf ("\n"); + return 0; +} + static void dump_mailcap_entry (mu_mailcap_entry_t entry) { - char buffer[256]; - size_t i, count; + char const *value; + struct list_closure lc; - mu_mailcap_entry_get_typefield (entry, buffer, - sizeof (buffer), NULL); - printf ("typefield: %s\n", buffer); + mu_mailcap_entry_sget_type (entry, &value); + printf ("typefield: %s\n", value); /* view-command. */ - mu_mailcap_entry_get_viewcommand (entry, buffer, - sizeof (buffer), NULL); - printf ("view-command: %s\n", buffer); + mu_mailcap_entry_sget_command (entry, &value); + printf ("view-command: %s\n", value); /* fields. */ - mu_mailcap_entry_fields_count (entry, &count); - for (i = 1; i <= count; i++) - { - int status = mu_mailcap_entry_get_field (entry, i, buffer, - sizeof (buffer), NULL); - if (status) - { - mu_error (_("cannot retrieve field %lu: %s"), - (unsigned long) i, - mu_strerror (status)); - break; - } - printf ("fields[%u]: %s\n", (unsigned) i, buffer); - } + lc.n = 1; + mu_mailcap_entry_fields_foreach (entry, list_field, &lc); printf ("\n"); } @@ -498,29 +420,17 @@ get_pager () static int run_test (mu_mailcap_entry_t entry, struct mime_conte |