summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2019-02-02 09:04:42 +0200
committerSergey Poznyakoff <gray@gnu.org>2019-02-03 11:54:13 +0200
commit18e23d6e98bc5942269e385dbb9ea9f0886909ef (patch)
tree9f0a9bb42901c46976eaf23c275ce65d0d03ac41
parent8360e84e5a673211488ee31c93922c987c057007 (diff)
downloadmailutils-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
-rw-r--r--configure.ac1
-rw-r--r--examples/python/2/mailcap.py3
-rw-r--r--include/mailutils/cpp/mailcap.h12
-rw-r--r--include/mailutils/cpp/pop3.h2
-rw-r--r--include/mailutils/mailcap.h202
-rw-r--r--include/mailutils/sys/Makefile.am1
-rw-r--r--include/mailutils/sys/mailcap.h58
-rw-r--r--include/mailutils/util.h1
-rw-r--r--lib/mailcap.c426
-rw-r--r--libmailutils/Makefile.am32
-rw-r--r--libmailutils/base/Makefile.am1
-rw-r--r--libmailutils/base/mailcap.c738
-rw-r--r--libmailutils/mailcap/Makefile.am42
-rw-r--r--libmailutils/mailcap/ctmatch.c166
-rw-r--r--libmailutils/mailcap/deferrclos.c32
-rw-r--r--libmailutils/mailcap/ent_cmd.c66
-rw-r--r--libmailutils/mailcap/ent_creat.c51
-rw-r--r--libmailutils/mailcap/ent_destr.c47
-rw-r--r--libmailutils/mailcap/ent_locus.c33
-rw-r--r--libmailutils/mailcap/ent_type.c66
-rw-r--r--libmailutils/mailcap/fieldacc.c108
-rw-r--r--libmailutils/mailcap/fields.c163
-rw-r--r--libmailutils/mailcap/finder.c131
-rw-r--r--libmailutils/mailcap/mcp_count.c51
-rw-r--r--libmailutils/mailcap/mcp_creat.c56
-rw-r--r--libmailutils/mailcap/mcp_destr.c36
-rw-r--r--libmailutils/mailcap/mcp_err.c44
-rw-r--r--libmailutils/mailcap/mcp_find.c32
-rw-r--r--libmailutils/mailcap/mcp_flags.c39
-rw-r--r--libmailutils/mailcap/mcp_get.c31
-rw-r--r--libmailutils/mailcap/mcp_sel.c44
-rw-r--r--libmailutils/mailcap/parse.c239
-rw-r--r--libmailutils/mailcap/parsefile.c41
-rw-r--r--libmailutils/tests/.gitignore2
-rw-r--r--libmailutils/tests/Makefile.am3
-rw-r--r--libmailutils/tests/ctm.at95
-rw-r--r--libmailutils/tests/ctm.c106
-rw-r--r--libmailutils/tests/mailcap.at262
-rw-r--r--libmailutils/tests/mailcap.c221
-rw-r--r--libmailutils/tests/mcf.c148
-rw-r--r--libmailutils/tests/testsuite.at23
-rw-r--r--libmu_cpp/mailcap.cc38
-rw-r--r--python/2/libmu_py/mailcap.c61
-rw-r--r--python/3/libmu_py/mailcap.c63
44 files changed, 2789 insertions, 1228 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,101 +20,133 @@
#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);
-
-/* 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);
-
-/* 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);
-
-/* Helper function saving in buffer, the argument of "composetyped" field. */
-int mu_mailcap_entry_get_composetyped (mu_mailcap_entry_t entry,
- 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,
- 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,
- 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);
+int mu_mailcap_find_entry (mu_mailcap_t mailcap, char const *type,
+ mu_mailcap_entry_t *entry);
+
+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);
+
+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);
+
+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);
+
+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);
+
+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);
+
+#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
}
#endif
-
+
#endif
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 \
@@ -41,15 +33,14 @@
struct mime_context
{
- mu_stream_t input;
+ 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,29 +50,22 @@ 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;
+ rc = mu_content_type_parse (buffer, NULL, &ctx->content_type);
+ free (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));
- return 1;
- }
- ctx->content_type = ws.ws_wordv[0];
- ws.ws_wordv[0] = NULL;
- ctx->temp_file = file ? mu_strdup (file) : NULL;
+ ctx->temp_file = file ? mu_strdup (file) : NULL;
ctx->unlink_temp_file = 0;
if (interactive)
@@ -89,56 +73,20 @@ mime_context_fill (struct mime_context *ctx, const char *file,
if (dry_run)
ctx->flags |= FLAGS_DRY_RUN;
ctx->dh = dh;
-
- mu_list_create (&ctx->values);
- 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;
- }
+ ctx->no_ask_types = no_ask ? mu_strdup (no_ask) : NULL;
+
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)
@@ -206,7 +115,7 @@ mime_context_write_input (struct mime_context *ctx, int fd)
char buf[512];
size_t n;
int status;
-
+
mime_context_get_input (ctx, &input);
status = mu_stream_seek (input, 0, SEEK_SET, NULL);
if (status && status != ENOSYS)
@@ -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])
{
@@ -257,26 +167,34 @@ expand_string (struct mime_context *ct, char **pstr)
rc = 1;
p += 2;
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;
@@ -286,7 +204,7 @@ expand_string (struct mime_context *ct, char **pstr)
case 'n':
p++;
break;
-
+
default:
mu_opool_append_char (expand_pool, p[0]);
}
@@ -333,12 +251,12 @@ 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);
fflush (stdout);
@@ -348,40 +266,44 @@ confirm_action (struct mime_context *ctx, const char *str)
len = strlen (p);
if (len > 0 && p[len-1] == '\n')
p[len--] = 0;
-
+
return mu_true_answer_p (p);
}
+struct list_closure