From: Pierre Habouzit Date: Thu, 16 Nov 2006 08:19:45 +0000 (+0100) Subject: move more things in the lib-mime X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=commitdiff_plain;h=774b53097f8c8b62c5101bce8f313d339387a438 move more things in the lib-mime Signed-off-by: Pierre Habouzit --- diff --git a/attach.c b/attach.c index 88272b9..0b497ef 100644 --- a/attach.c +++ b/attach.c @@ -358,7 +358,7 @@ int mutt_is_autoview (BODY * b, const char *type) mutt_check_lookup_list (b, _type, sizeof (_type)); type = _type; - if (mutt_needs_mailcap (b)) { + if (rfc1524_mailcap_isneeded(b)) { if (option (OPTIMPLICITAUTOVIEW)) return 1; @@ -400,7 +400,7 @@ int mutt_view_attachment (FILE * fp, BODY * a, int flag, HEADER * hdr, !crypt_valid_passphrase (a->hdr->security)) return (rc); use_mailcap = (flag == M_MAILCAP || - (flag == M_REGULAR && mutt_needs_mailcap (a))); + (flag == M_REGULAR && rfc1524_mailcap_isneeded(a))); snprintf (type, sizeof (type), "%s/%s", TYPE (a), a->subtype); if (use_mailcap) { diff --git a/lib-crypt/crypt.c b/lib-crypt/crypt.c index eb60a2d..66e9588 100644 --- a/lib-crypt/crypt.c +++ b/lib-crypt/crypt.c @@ -232,162 +232,6 @@ int mutt_protect (HEADER * msg, char *keylist) } - - -int mutt_is_multipart_signed (BODY * b) -{ - char *p; - - if (!b || !(b->type == TYPEMULTIPART) || - !b->subtype || ascii_strcasecmp (b->subtype, "signed")) - return 0; - - if (!(p = parameter_getval(b->parameter, "protocol"))) - return 0; - - if (!(ascii_strcasecmp (p, "multipart/mixed"))) - return SIGN; - - if (!(ascii_strcasecmp (p, "application/pgp-signature"))) - return PGPSIGN; - - if (!(ascii_strcasecmp (p, "application/x-pkcs7-signature"))) - return SMIMESIGN; - if (!(ascii_strcasecmp (p, "application/pkcs7-signature"))) - return SMIMESIGN; - - return 0; -} - - -int mutt_is_multipart_encrypted (BODY * b) -{ - char *p; - - if (!b || b->type != TYPEMULTIPART || - !b->subtype || ascii_strcasecmp (b->subtype, "encrypted") || - !(p = parameter_getval(b->parameter, "protocol")) || - ascii_strcasecmp (p, "application/pgp-encrypted")) - return 0; - - return PGPENCRYPT; -} - - -int mutt_is_application_pgp (BODY * m) -{ - int t = 0; - char *p; - - if (m->type == TYPEAPPLICATION) { - if (!ascii_strcasecmp (m->subtype, "pgp") - || !ascii_strcasecmp (m->subtype, "x-pgp-message")) { - if ((p = parameter_getval(m->parameter, "x-action")) - && (!ascii_strcasecmp (p, "sign") - || !ascii_strcasecmp (p, "signclear"))) - t |= PGPSIGN; - - if ((p = parameter_getval(m->parameter, "format")) && - !ascii_strcasecmp (p, "keys-only")) - t |= PGPKEY; - - if (!t) - t |= PGPENCRYPT; /* not necessarily correct, but... */ - } - - if (!ascii_strcasecmp (m->subtype, "pgp-signed")) - t |= PGPSIGN; - - if (!ascii_strcasecmp (m->subtype, "pgp-keys")) - t |= PGPKEY; - } - else if (m->type == TYPETEXT && ascii_strcasecmp ("plain", m->subtype) == 0) { - if (((p = parameter_getval(m->parameter, "x-mutt-action")) - || (p = parameter_getval(m->parameter, "x-action")) - || (p = parameter_getval(m->parameter, "action"))) - && !ascii_strncasecmp ("pgp-sign", p, 8)) - t |= PGPSIGN; - else if (p && !ascii_strncasecmp ("pgp-encrypt", p, 11)) - t |= PGPENCRYPT; - else if (p && !ascii_strncasecmp ("pgp-keys", p, 7)) - t |= PGPKEY; - } - if (t) - t |= PGPINLINE; - - return t; -} - -int mutt_is_application_smime (BODY * m) -{ - char *t = NULL; - int len, complain = 0; - - if (!m) - return 0; - - if ((m->type & TYPEAPPLICATION) && m->subtype) { - /* S/MIME MIME types don't need x- anymore, see RFC2311 */ - if (!ascii_strcasecmp (m->subtype, "x-pkcs7-mime") || - !ascii_strcasecmp (m->subtype, "pkcs7-mime")) { - if ((t = parameter_getval(m->parameter, "smime-type"))) { - if (!ascii_strcasecmp (t, "enveloped-data")) - return SMIMEENCRYPT; - else if (!ascii_strcasecmp (t, "signed-data")) - return (SMIMESIGN | SMIMEOPAQUE); - else - return 0; - } - /* Netscape 4.7 uses - * Content-Description: S/MIME Encrypted Message - * instead of Content-Type parameter - */ - if (!ascii_strcasecmp (m->description, "S/MIME Encrypted Message")) - return SMIMEENCRYPT; - complain = 1; - } - else if (ascii_strcasecmp (m->subtype, "octet-stream")) - return 0; - - t = parameter_getval(m->parameter, "name"); - - if (!t) - t = m->d_filename; - if (!t) - t = m->filename; - if (!t) { - if (complain) - mutt_message (_ - ("S/MIME messages with no hints on content are unsupported.")); - return 0; - } - - /* no .p7c, .p10 support yet. */ - - len = m_strlen(t) - 4; - if (len > 0 && *(t + len) == '.') { - len++; - if (!ascii_strcasecmp ((t + len), "p7m")) -#if 0 - return SMIMEENCRYPT; -#else - /* Not sure if this is the correct thing to do, but - it's required for compatibility with Outlook */ - return (SMIMESIGN | SMIMEOPAQUE); -#endif - else if (!ascii_strcasecmp ((t + len), "p7s")) - return (SMIMESIGN | SMIMEOPAQUE); - } - } - - return 0; -} - - - - - - int crypt_query (BODY * m) { int t = 0; @@ -440,8 +284,6 @@ int crypt_query (BODY * m) } - - int crypt_write_signed (BODY * a, STATE * s, const char *tempfile) { FILE *fp; @@ -511,8 +353,6 @@ void convert_to_7bit (BODY * a) } - - void crypt_extract_keys_from_messages (HEADER * h) { int i; diff --git a/lib-crypt/crypt.h b/lib-crypt/crypt.h index 2b9434c..3a2a207 100644 --- a/lib-crypt/crypt.h +++ b/lib-crypt/crypt.h @@ -83,23 +83,13 @@ typedef struct pgp_keyinfo *pgp_key_t; int mutt_protect (HEADER *, char *); -int mutt_is_multipart_encrypted (BODY *); - -int mutt_is_multipart_signed (BODY *); - -int mutt_is_application_pgp (BODY *); - -int mutt_is_application_smime (BODY *); - int mutt_signed_handler (BODY *, STATE *); int mutt_parse_crypt_hdr (char *, int); - void convert_to_7bit (BODY *); - /*-- crypt.c --*/ /* Print the current time. */ diff --git a/lib-mime/Makefile.am b/lib-mime/Makefile.am index f8ecd2d..779ef44 100644 --- a/lib-mime/Makefile.am +++ b/lib-mime/Makefile.am @@ -4,7 +4,8 @@ DISTCLEANFILES = $(BUILT_SOURCES) noinst_LIBRARIES = libmime.a libmime_a_SOURCES = mime.h mime-types.h $(BUILT_SOURCES) \ - mime.c rfc822address.c rfc822parse.c rfc1524.c rfc2047.c rfc2231.c \ + mime.c crypt.c \ + rfc822address.c rfc822parse.c rfc1524.c rfc2047.c rfc2231.c \ \ rfc3676.h rfc3676.c diff --git a/lib-mime/crypt.c b/lib-mime/crypt.c new file mode 100644 index 0000000..d0d3235 --- /dev/null +++ b/lib-mime/crypt.c @@ -0,0 +1,210 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + * Copyright © 2006 Pierre Habouzit + */ +/* + * Copyright notice from original mutt: + * Copyright (C) 1996,1997 Michael R. Elkins + * Copyright (C) 1999-2000 Thomas Roessler + * Copyright (C) 2001 Thomas Roessler + * Oliver Ehli + * Copyright (C) 2003 Werner Koch + * Copyright (C) 2004 g10code GmbH + * + * This file is part of mutt-ng, see http://www.muttng.org/. + * It's licensed under the GNU General Public License, + * please see the file GPL in the top level source directory. + */ + +#include +#include + +#include + +#include "mime.h" + +int mutt_is_multipart_signed(BODY * b) +{ + char *p; + + if (!b || b->type != TYPEMULTIPART || !b->subtype + || mime_which_token(b->subtype, -1) != MIME_SIGNED) + return 0; + + if (!(p = parameter_getval(b->parameter, "protocol"))) + return 0; + + switch (mime_which_token(p, -1)) { + case MIME_MULTIPART_MIXED: + return SIGN; + + case MIME_APPLICATION_PGP_SIGNATURE: + return PGPSIGN; + + case MIME_APPLICATION_X_PKCS7_SIGNATURE: + return SMIMESIGN; + + case MIME_APPLICATION_PKCS7_SIGNATURE: + return SMIMESIGN; + + default: + return 0; + } +} + +int mutt_is_multipart_encrypted (BODY * b) +{ + char *p; + + if (!b || b->type != TYPEMULTIPART || !b->subtype + || mime_which_token(b->subtype, -1) != MIME_ENCRYPTED + || !(p = parameter_getval(b->parameter, "protocol")) + || mime_which_token(p, -1) != MIME_APPLICATION_PGP_ENCRYPTED) + return 0; + + return PGPENCRYPT; +} + +int mutt_is_application_pgp (BODY * m) +{ + int t = 0; + + int subtype = mime_which_token(m->subtype, -1); + + if (m->type == TYPEAPPLICATION) { + if (subtype != MIME_PGP || subtype != MIME_X_PGP_MESSAGE) { + int tok; + + tok = mime_which_token(parameter_getval(m->parameter, "x-action"), -1); + + if (tok == MIME_SIGN || tok == MIME_SIGNCLEAR) + t |= PGPSIGN; + + tok = mime_which_token(parameter_getval(m->parameter, "format"), -1); + if (tok == MIME_KEYS_ONLY) + t |= PGPKEY; + + if (!t) + t |= PGPENCRYPT; /* not necessarily correct, but... */ + } + + if (subtype == MIME_PGP_SIGNED) + t |= PGPSIGN; + + if (subtype == MIME_PGP_KEYS) + t |= PGPKEY; + } + + if (m->type == TYPETEXT && subtype == MIME_PLAIN) { + const char *p; + + if ((p = parameter_getval(m->parameter, "x-mutt-action")) + || (p = parameter_getval(m->parameter, "x-action")) + || (p = parameter_getval(m->parameter, "action"))) + { + int tok = mime_which_token(p, -1); + switch (tok) { + case MIME_PGP_SIGN: + t |= PGPSIGN; + break; + + case MIME_PGP_ENCRYPT: + t |= PGPENCRYPT; + break; + + case MIME_PGP_KEYS: + t |= PGPKEY; + break; + + default: + break; + } + } + } + + return t ? t | PGPINLINE : 0; +} + +int mutt_is_application_smime (BODY * m) +{ + char *t = NULL; + int len, complain = 0; + + if (!m) + return 0; + + if ((m->type & TYPEAPPLICATION) && m->subtype) { + int subtype = mime_which_token(m->subtype, -1); + + /* S/MIME MIME types don't need x- anymore, see RFC2311 */ + if (subtype == MIME_X_PKCS7_MIME || subtype == MIME_PKCS7_MIME) { + t = parameter_getval(m->parameter, "smime-type"); + + if (t) { + switch (mime_which_token(t, -1)) { + case MIME_ENVELOPED_DATA: + return SMIMEENCRYPT; + + case MIME_SIGNED_DATA: + return SMIMESIGN | SMIMEOPAQUE; + + default: + return 0; + } + } + + complain = 1; + } + + if (subtype == MIME_OCTET_STREAM) + return 0; + + t = parameter_getval(m->parameter, "name"); + if (!t) + t = m->d_filename; + if (!t) + t = m->filename; + + if (!t) { + if (complain) + mutt_message(_("S/MIME messages with no hints on content are unsupported.")); + return 0; + } + + /* no .p7c, .p10 support yet. */ + + len = m_strlen(t) - 4; + if (len > 0 && t[len] == '.' + && tolower((unsigned char)t[len + 1]) == 'p' + && t[len + 2] == '7') + { + switch (t[len + 3]) { + case 'm': case 'M': + /* Not sure if this is the correct thing to do, but + it's required for compatibility with Outlook */ + return (SMIMESIGN | SMIMEOPAQUE); + + case 's': case 'S': + return (SMIMESIGN | SMIMEOPAQUE); + } + } + } + + return 0; +} + + diff --git a/lib-mime/mime-token.def b/lib-mime/mime-token.def index dcaef9e..e492774 100644 --- a/lib-mime/mime-token.def +++ b/lib-mime/mime-token.def @@ -4,6 +4,10 @@ alternative apparently-from apparently-to application +application/pgp-encrypted +application/pgp-signature +application/pkcs7-signature +application/x-pkcs7-signature audio base64 bcc @@ -19,8 +23,12 @@ content-transfer-encoding content-type copiousoutput date +delivery-status digest edit +encrypted +enriched +enveloped-data expires external-body followup-to @@ -28,6 +36,7 @@ from image in-reply-to iso-2022-jp +keys-only lines list-post mail-followup-to @@ -37,11 +46,20 @@ message-id mime-version model multipart +multipart/mixed nametemplate needsterminal news newsgroups +octet-stream organization +pgp +pgp-encrypt +pgp-keys +pgp-sign +pgp-signed +pkcs7-mime +plain print quoted-printable received @@ -49,7 +67,12 @@ references reply-to return-path rfc822 +rfc822-headers sender +sign +signclear +signed +signed-data status subject supercedes @@ -64,6 +87,8 @@ video x-comment-to x-convert x-label +x-pgp-message +x-pkcs7-mime xref x-status x-uuencode diff --git a/lib-mime/mime-token.sh b/lib-mime/mime-token.sh index 17ed4c1..84c3664 100644 --- a/lib-mime/mime-token.sh +++ b/lib-mime/mime-token.sh @@ -39,7 +39,7 @@ do_h() { enum mime_token { MUTT_MIME_TOKEN_UNKNOWN, -`tr 'a-z-' 'A-Z_' | sed -e 's/.*/ MIME_&,/'` +`tr 'a-z-/' 'A-Z__' | sed -e 's/.*/ MIME_&,/'` }; __attribute__((pure)) @@ -62,16 +62,17 @@ struct tok { const char *name; int val; }; `awk '{print $0 ", " NR }'` %% -enum mime_token mime_which_token(const char *s, ssize_t len) { - const struct tok *res; - +enum mime_token mime_which_token(const char *s, ssize_t len) +{ if (len < 0) len = m_strlen(s); - if (!len) - return MUTT_MIME_TOKEN_UNKNOWN; - res = mime_which_token_aux(s, len); - return res ? res->val : MUTT_MIME_TOKEN_UNKNOWN; + if (len) { + const struct tok *res = mime_which_token_aux(s, len); + return res ? res->val : MUTT_MIME_TOKEN_UNKNOWN; + } else { + return MUTT_MIME_TOKEN_UNKNOWN; + } } EOF } diff --git a/lib-mime/mime.c b/lib-mime/mime.c index 7c6a4b6..4353e4d 100644 --- a/lib-mime/mime.c +++ b/lib-mime/mime.c @@ -16,6 +16,11 @@ * * Copyright © 2006 Pierre Habouzit */ +/* + * Copyright notice from original mutt: + * Copyright (C) 1996-2000 Michael R. Elkins + * Copyright (C) 1999-2000 Thomas Roessler + */ #include #include @@ -132,18 +137,6 @@ void parameter_set_boundary(parameter_t **parm) /* XXX */ /****************************************************************************/ -void rfc1524_entry_wipe(rfc1524_entry *p) -{ - p_delete(&p->command); - p_delete(&p->testcommand); - p_delete(&p->composecommand); - p_delete(&p->composetypecommand); - p_delete(&p->editcommand); - p_delete(&p->printcommand); - p_delete(&p->nametemplate); - p_delete(&p->convert); -} - void envelope_wipe(ENVELOPE *p) { address_list_wipe(&p->return_path); @@ -216,6 +209,32 @@ void header_wipe(HEADER *h) } +/****************************************************************************/ +/* misc functions */ +/****************************************************************************/ + +int mutt_is_text_part(BODY * b) +{ + char *s = b->subtype; + + if (mutt_is_application_pgp(b)) + return 0; + + switch (b->type) { + case TYPETEXT: + return 1; + + case TYPEMESSAGE: + return mime_which_token(s, -1) == MIME_DELIVERY_STATUS; + + case TYPEAPPLICATION: + return mime_which_token(s, -1) == MIME_PGP_KEYS; + + default: + return 0; + } +} + #include "mutt.h" int url_parse_mailto(ENVELOPE *e, char **body, const char *src) diff --git a/lib-mime/mime.h b/lib-mime/mime.h index e39d893..45002f4 100644 --- a/lib-mime/mime.h +++ b/lib-mime/mime.h @@ -84,7 +84,8 @@ DO_DELETE(rfc1524_entry, rfc1524_entry); int rfc1524_expand_command(BODY *, const char *, const char *, char *, int); int rfc1524_expand_filename(char *, char *, char *, ssize_t); -int rfc1524_mailcap_lookup (BODY *, char *, rfc1524_entry *, int); +int rfc1524_mailcap_lookup(BODY *, char *, rfc1524_entry *, int); +int rfc1524_mailcap_isneeded(BODY *); /****************************************************************************/ /* RFC 822 */ @@ -107,6 +108,12 @@ string_list_t **mutt_parse_rfc822_line(ENVELOPE *, HEADER *, char *line, char *p ENVELOPE *mutt_read_rfc822_header(FILE *, HEADER *, short, short); int mutt_count_body_parts (HEADER *hdr, int flags); +int mutt_is_multipart_encrypted(BODY *); +int mutt_is_multipart_signed(BODY *); +int mutt_is_application_pgp(BODY *); +int mutt_is_application_smime(BODY *); +int mutt_is_text_part(BODY *); + /*** addresses ***/ address_t *mutt_parse_adrlist(address_t *, const char *); diff --git a/lib-mime/rfc1524.c b/lib-mime/rfc1524.c index 4fe4f2b..6c4f2e5 100644 --- a/lib-mime/rfc1524.c +++ b/lib-mime/rfc1524.c @@ -60,6 +60,43 @@ #include "mime.h" #include "attach.h" +void rfc1524_entry_wipe(rfc1524_entry *p) +{ + p_delete(&p->command); + p_delete(&p->testcommand); + p_delete(&p->composecommand); + p_delete(&p->composetypecommand); + p_delete(&p->editcommand); + p_delete(&p->printcommand); + p_delete(&p->nametemplate); + p_delete(&p->convert); +} + +/* returns 1 if Mutt can't display this type of data, 0 otherwise */ +int rfc1524_mailcap_isneeded(BODY * m) +{ + int tok; + + switch (m->type) { + case TYPEMULTIPART: + case TYPEMESSAGE: + return 0; + + case TYPEAPPLICATION: + return !(mutt_is_application_pgp(m) || mutt_is_application_smime(m)); + + case TYPETEXT: + tok = mime_which_token(m->subtype, -1); + if (tok == MIME_PLAIN + || tok == MIME_RFC822_HEADERS + || tok == MIME_ENRICHED) + return 0; + break; + } + + return 1; +} + /* The command semantics include the following: * %s is the filename that contains the mail body data * %t is the content type, like text/plain diff --git a/muttlib.c b/muttlib.c index fc9606d..f7449df 100644 --- a/muttlib.c +++ b/muttlib.c @@ -157,15 +157,6 @@ int mutt_copy_body (FILE * fp, BODY ** tgt, BODY * src) return 0; } -HEADER *mutt_dup_header (HEADER * h) -{ - HEADER *hnew; - - hnew = header_new(); - memcpy (hnew, h, sizeof (HEADER)); - return hnew; -} - /* returns true if the header contained in "s" is in list "t" */ int mutt_matches_ignore (const char *s, string_list_t * t) { @@ -352,57 +343,6 @@ char *_mutt_expand_path (char *s, ssize_t slen, int rx) return (s); } -/* returns 1 if Mutt can't display this type of data, 0 otherwise */ -int mutt_needs_mailcap (BODY * m) -{ - switch (m->type) { - case TYPETEXT: - - if (!ascii_strcasecmp ("plain", m->subtype) || - !ascii_strcasecmp ("rfc822-headers", m->subtype) || - !ascii_strcasecmp ("enriched", m->subtype)) - return 0; - break; - - case TYPEAPPLICATION: - if (mutt_is_application_pgp (m)) - return 0; - if (mutt_is_application_smime (m)) - return 0; - break; - - case TYPEMULTIPART: - case TYPEMESSAGE: - return 0; - } - - return 1; -} - -int mutt_is_text_part (BODY * b) -{ - int t = b->type; - char *s = b->subtype; - - if (mutt_is_application_pgp (b)) - return 0; - - if (t == TYPETEXT) - return 1; - - if (t == TYPEMESSAGE) { - if (!ascii_strcasecmp ("delivery-status", s)) - return 1; - } - - if (t == TYPEAPPLICATION) { - if (!ascii_strcasecmp ("pgp-keys", s)) - return 1; - } - - return 0; -} - /* move all the headers from extra not present in base into base */ void mutt_merge_envelopes(ENVELOPE* base, ENVELOPE** extra) { diff --git a/protos.h b/protos.h index 0c03558..9d3b87e 100644 --- a/protos.h +++ b/protos.h @@ -56,8 +56,6 @@ CONTENT *mutt_get_content_info (const char *fname, BODY * b); string_list_t *mutt_make_references (ENVELOPE * e); -HEADER *mutt_dup_header (HEADER *); - int mutt_cmp_header (const HEADER*, const HEADER*); int mutt_cmp_addr (const address_t * a, const address_t * b); int mutt_cmp_list (const string_list_t * a, const string_list_t * b); @@ -200,12 +198,10 @@ int mutt_is_mail_list (address_t *); int mutt_is_list_cc (int, address_t *, address_t *); int mutt_is_list_recipient (int, address_t *, address_t *); int mutt_is_subscribed_list (address_t *); -int mutt_is_text_part (BODY *); int mutt_is_valid_mailbox (const char *); int mutt_lookup_mime_type (BODY *, const char *); int mutt_match_spam_list (const char *, SPAM_LIST *, char *, int); int mutt_multi_choice (char *prompt, char *letters); -int mutt_needs_mailcap (BODY *); int mutt_num_postponed (int); int mutt_parse_bind (BUFFER *, BUFFER *, unsigned long, BUFFER *); int mutt_parse_exec (BUFFER *, BUFFER *, unsigned long, BUFFER *); diff --git a/send.c b/send.c index 2d05c43..546cfb3 100644 --- a/send.c +++ b/send.c @@ -1417,7 +1417,7 @@ int ci_send_message (int flags, /* send mode */ query_quadoption (OPT_FORWEDIT, _("Edit forwarded message?")) == M_YES)) { /* If the this isn't a text message, look for a mailcap edit command */ - if (mutt_needs_mailcap (msg->content)) { + if (rfc1524_mailcap_isneeded(msg->content)) { if (!mutt_edit_attachment (msg->content)) goto cleanup; } else if (option (OPTEDITHDRS)) {