]> granicus.if.org Git - neomutt/commitdiff
Add option to run command to query attachment mime type. (closes #2933) (closes ...
authorKevin McCarthy <kevin@8t8.us>
Sat, 19 Aug 2017 15:33:57 +0000 (08:33 -0700)
committerRichard Russon <rich@flatcap.org>
Fri, 1 Sep 2017 12:44:58 +0000 (13:44 +0100)
Add $mime_type_query_command to specify a command to run if the
attachment extension is not in the mime.types file.

Add $mime_type_query_first to allow the query command to be run before
the mime.types lookup.

doc/manual.xml.head
globals.h
init.c
init.h
mbyte_table.h
options.h
sendlib.c

index 0d6e6afb8c16b3bb09062cae46a9bd06d0cdd039..eef2048e00ffa60c0e28f270afab8fb9b0ffd0b0 100755 (executable)
@@ -8272,8 +8272,11 @@ audio/x-aiff                    aif aifc aiff
       <literal>mime.types</literal> file comes with the Mutt distribution, and
       should contain most of the MIME types you are likely to use.</para>
       <para>If Mutt can not determine the MIME type by the extension of the
-      file you attach, it will look at the file. If the file is free of binary
-      information, Mutt will assume that the file is plain text, and mark it as
+      file you attach, it will run the command specified in
+      <link linkend="mime-type-query-command">$mime_type_query_command</link>.
+      If that command is not specified, Mutt will look at the file. If the file
+      is free of binary information, Mutt will assume that the file is plain
+      text, and mark it as
       <literal>text/plain</literal>. If the file contains binary information,
       then Mutt will mark it as
       <literal>application/octet-stream</literal>. You can change the MIME type
index fdf0399b6418135807f9608817fe1080d85cbb51..bf970d31a5610a5eba078f9daccce1ec6726ad5e 100644 (file)
--- a/globals.h
+++ b/globals.h
@@ -102,6 +102,7 @@ WHERE char *MarkMacroPrefix;
 WHERE char *MhFlagged;
 WHERE char *MhReplied;
 WHERE char *MhUnseen;
+WHERE char *MimeTypeQueryCmd;
 WHERE char *MsgFmt;
 
 #ifdef USE_SOCKET
diff --git a/init.c b/init.c
index 2a8e015df864cda515a0d1492c1e6c379c4e9a32..ea78262469603926d6779fd8a1e2836c4c931cb4 100644 (file)
--- a/init.c
+++ b/init.c
@@ -309,7 +309,7 @@ static struct MbCharTable *parse_mbchar_table(const char *s)
 
   t->orig_str = safe_strdup(s);
   /* This could be more space efficient.  However, being used on tiny
-   * strings (Tochars and StChars), the overhead is not great. */
+   * strings (ToChars and StChars), the overhead is not great. */
   t->chars = safe_calloc(slen, sizeof(char *));
   d = t->segmented_str = safe_calloc(slen * 2, sizeof(char));
 
diff --git a/init.h b/init.h
index c05ed4b15109ba1cace475919bfff98248a6b2cb..e68c68cd293c596fd44384574d5ae7dfc5c69e4e 100644 (file)
--- a/init.h
+++ b/init.h
@@ -1921,6 +1921,32 @@ struct Option MuttVars[] = {
   ** is Usenet article, because MIME for news is nonstandard feature.
   */
 #endif
+  { "mime_type_query_command", DT_STR, R_NONE, UL &MimeTypeQueryCmd, UL "" },
+  /*
+  ** .pp
+  ** This specifies a command to run, to determine the mime type of a
+  ** new attachment when composing a message.  Unless
+  ** $$mime_type_query_first is set, this will only be run if the
+  ** attachment's extension is not found in the mime.types file.
+  ** .pp
+  ** The string may contain a ``%s'', which will be substituted with the
+  ** attachment filename.  Mutt will add quotes around the string substituted
+  ** for ``%s'' automatically according to shell quoting rules, so you should
+  ** avoid adding your own.  If no ``%s'' is found in the string, Mutt will
+  ** append the attachment filename to the end of the string.
+  ** .pp
+  ** The command should output a single line containing the
+  ** attachment's mime type.
+  ** .pp
+  ** Suggested values are ``xdg-mime query filetype'' or
+  ** ``file -bi''.
+  */
+  { "mime_type_query_first", DT_BOOL, R_NONE, OPT_MIME_TYPE_QUERY_FIRST, 0 },
+  /*
+  ** .pp
+  ** When \fIset\fP, the $$mime_type_query_command will be run before the
+  ** mime.types lookup.
+  */
 #ifdef MIXMASTER
   { "mix_entry_format", DT_STR,  R_NONE, UL &MixEntryFormat, UL "%4n %c %-16s %a" },
   /*
index 702ffdacd5586788ea180d9cccdf0277849758b7..42cc4ba2da0b87f0c3f48dcc798cbaae68226670 100644 (file)
@@ -27,7 +27,7 @@
  * struct MbCharTable - multibyte character table
  *
  * Allows for direct access to the individual multibyte characters in a
- * string.  This is used for the Flagchars, Fromchars, StChars and Tochars
+ * string.  This is used for the FlagChars, FromChars, StChars and ToChars
  * option types.
  */
 struct MbCharTable
index 8f12ca65cf4f52195447763f302c008778136647..70b6057e53cb90fd2cffbe6d44fe4d48a4c76f82 100644 (file)
--- a/options.h
+++ b/options.h
@@ -129,6 +129,7 @@ enum GlobalBool
   OPT_ME_TOO,
   OPT_MH_PURGE,
   OPT_MIME_FORW_DECODE,
+  OPT_MIME_TYPE_QUERY_FIRST,
 #ifdef USE_NNTP
   OPT_MIME_SUBJECT, /**< encode subject line with RFC2047 */
 #endif
index 857195b505c8500f28bf54c63ea1e91fc4d4df5d..f3c353a7bd69ef3fcaca0c423416f67f305913ef 100644 (file)
--- a/sendlib.c
+++ b/sendlib.c
@@ -47,6 +47,7 @@
 #include "context.h"
 #include "copy.h"
 #include "envelope.h"
+#include "filter.h"
 #include "format_flags.h"
 #include "globals.h"
 #include "header.h"
@@ -1414,6 +1415,35 @@ struct Body *mutt_make_message_attach(struct Context *ctx, struct Header *hdr, i
   return body;
 }
 
+static void run_mime_type_query(struct Body *att)
+{
+  FILE *fp, *fperr;
+  char cmd[HUGE_STRING];
+  char *buf = NULL;
+  size_t buflen;
+  int dummy = 0;
+  pid_t thepid;
+
+  mutt_expand_file_fmt(cmd, sizeof(cmd), MimeTypeQueryCmd, att->filename);
+
+  if ((thepid = mutt_create_filter(cmd, NULL, &fp, &fperr)) < 0)
+  {
+    mutt_error(_("Error running \"%s\"!"), cmd);
+    return;
+  }
+
+  if ((buf = mutt_read_line(buf, &buflen, fp, &dummy, 0)) != NULL)
+  {
+    if (strchr(buf, '/'))
+      mutt_parse_content_type(buf, att);
+    FREE(&buf);
+  }
+
+  safe_fclose(&fp);
+  safe_fclose(&fperr);
+  mutt_wait_filter(thepid);
+}
+
 struct Body *mutt_make_file_attach(const char *path)
 {
   struct Body *att = NULL;
@@ -1422,11 +1452,17 @@ struct Body *mutt_make_file_attach(const char *path)
   att = mutt_new_body();
   att->filename = safe_strdup(path);
 
+  if (MimeTypeQueryCmd && *MimeTypeQueryCmd && option(OPT_MIME_TYPE_QUERY_FIRST))
+    run_mime_type_query(att);
+
   /* Attempt to determine the appropriate content-type based on the filename
    * suffix.
    */
+  if (!att->subtype)
+    mutt_lookup_mime_type(att, path);
 
-  mutt_lookup_mime_type(att, path);
+  if (!att->subtype && MimeTypeQueryCmd && *MimeTypeQueryCmd && !option(OPT_MIME_TYPE_QUERY_FIRST))
+    run_mime_type_query(att);
 
   if ((info = mutt_get_content_info(path, att)) == NULL)
   {