X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=handler.c;h=11ff8a25cfc56011b89da52db6a8fff38f28ad92;hp=59c70de211a1fce93d6f1be6f0d613e70f681e9e;hb=16be8d10413bbcf822577afd4019d65aba7459e0;hpb=9ed7a487e3a922f2cbb222961c2c9710c3a65f91 diff --git a/handler.c b/handler.c index 59c70de..11ff8a2 100644 --- a/handler.c +++ b/handler.c @@ -12,7 +12,7 @@ #include #include -#include +#include #include @@ -22,11 +22,9 @@ #include "keymap.h" #include "copy.h" #include "charset.h" -#include +#include "crypt.h" #include "state.h" #include "attach.h" -#include "lib.h" - typedef int handler_f (BODY *, STATE *); typedef handler_f *handler_t; @@ -191,95 +189,14 @@ static void mutt_decode_quoted (STATE * s, long len, int istext, iconv_t cd) state_reset_prefix (s); } -void mutt_decode_base64 (STATE * s, long len, int istext, iconv_t cd) +static unsigned char decode_byte(int ch) { - char buf[5]; - int c1, c2, c3, c4, ch, cr = 0, i; - char bufi[BUFI_SIZE]; - ssize_t l = 0; - - buf[4] = 0; - - if (istext) - state_set_prefix (s); - - while (len > 0) { - for (i = 0; i < 4 && len > 0; len--) { - if ((ch = fgetc (s->fpin)) == EOF) - break; - if (base64val(ch) >= 0 || ch == '=') - buf[i++] = ch; - } - if (i != 4) { - break; - } - - c1 = base64val(buf[0]); - c2 = base64val(buf[1]); - ch = (c1 << 2) | (c2 >> 4); - - if (cr && ch != '\n') - bufi[l++] = '\r'; - - cr = 0; - - if (istext && ch == '\r') - cr = 1; - else - bufi[l++] = ch; - - if (buf[2] == '=') - break; - c3 = base64val(buf[2]); - ch = ((c2 & 0xf) << 4) | (c3 >> 2); - - if (cr && ch != '\n') - bufi[l++] = '\r'; - - cr = 0; - - if (istext && ch == '\r') - cr = 1; - else - bufi[l++] = ch; - - if (buf[3] == '=') - break; - c4 = base64val(buf[3]); - ch = ((c3 & 0x3) << 6) | c4; - - if (cr && ch != '\n') - bufi[l++] = '\r'; - cr = 0; - - if (istext && ch == '\r') - cr = 1; - else - bufi[l++] = ch; - - if (l + 8 >= ssizeof (bufi)) - mutt_convert_to_state (cd, bufi, &l, s); - } - - if (cr) - bufi[l++] = '\r'; - - mutt_convert_to_state (cd, bufi, &l, s); - mutt_convert_to_state (cd, 0, 0, s); - - state_reset_prefix (s); -} - -static unsigned char decode_byte (char ch) -{ - if (ch == 96) - return 0; - return ch - 32; + return ch == 96 ? 0 : ch - 32; } static void mutt_decode_uuencoded (STATE * s, long len, int istext, iconv_t cd) { - char tmps[SHORT_STRING]; + char tmps[STRING]; char linelen, c, l, out; char *pt; char bufi[BUFI_SIZE]; @@ -302,13 +219,13 @@ static void mutt_decode_uuencoded (STATE * s, long len, int istext, iconv_t cd) if (!m_strncmp(tmps, "end", 3)) break; pt = tmps; - linelen = decode_byte (*pt); + linelen = decode_byte(*pt); pt++; for (c = 0; c < linelen;) { for (l = 2; l <= 6; l += 2) { - out = decode_byte (*pt) << l; + out = decode_byte(*pt) << l; pt++; - out |= (decode_byte (*pt) >> (6 - l)); + out |= (decode_byte(*pt) >> (6 - l)); bufi[k++] = out; c++; if (c == linelen) @@ -340,22 +257,21 @@ static struct { const char *tag_name; int index; } EnrichedTags[] = { - { - "param", RICH_PARAM}, { - "bold", RICH_BOLD}, { - "italic", RICH_ITALIC}, { - "underline", RICH_UNDERLINE}, { - "nofill", RICH_NOFILL}, { - "excerpt", RICH_EXCERPT}, { - "indent", RICH_INDENT}, { - "indentright", RICH_INDENT_RIGHT}, { - "center", RICH_CENTER}, { - "flushleft", RICH_FLUSHLEFT}, { - "flushright", RICH_FLUSHRIGHT}, { - "flushboth", RICH_FLUSHLEFT}, { - "color", RICH_COLOR}, { - "x-color", RICH_COLOR}, { - NULL, -1} + {"param", RICH_PARAM}, + {"bold", RICH_BOLD}, + {"italic", RICH_ITALIC}, + {"underline", RICH_UNDERLINE}, + {"nofill", RICH_NOFILL}, + {"excerpt", RICH_EXCERPT}, + {"indent", RICH_INDENT}, + {"indentright", RICH_INDENT_RIGHT}, + {"center", RICH_CENTER}, + {"flushleft", RICH_FLUSHLEFT}, + {"flushright", RICH_FLUSHRIGHT}, + {"flushboth", RICH_FLUSHLEFT}, + {"color", RICH_COLOR}, + {"x-color", RICH_COLOR}, + {NULL, -1} }; struct enriched_state { @@ -483,7 +399,7 @@ static void enriched_flush (struct enriched_state *stte, int wrap) stte->line_max = stte->line_used; p_realloc(&stte->line, stte->line_max + 1); } - strcat (stte->line, stte->buffer); /* __STRCAT_CHECKED__ */ + m_strcat(stte->line, stte->line_max + 1, stte->buffer); stte->line_len += stte->word_len; stte->word_len = 0; stte->buff_used = 0; @@ -541,8 +457,7 @@ static void enriched_putc (int c, struct enriched_state *stte) else { stte->buffer[stte->buff_used++] = c; } - } - else { + } else { stte->buffer[stte->buff_used++] = c; } stte->word_len++; @@ -645,9 +560,8 @@ static int text_enriched_handler (BODY * a, STATE * s) p_clear(&stte, 1); stte.s = s; - stte.WrapMargin = - ((s->flags & M_DISPLAY) ? (COLS - 4) : ((COLS - 4) < - 72) ? (COLS - 4) : 72); + stte.WrapMargin = ((s->flags & M_DISPLAY) ? (getmaxx(main_w) - 4) : + ((getmaxx(main_w) - 4) < 72) ? (getmaxx(main_w) - 4) : 72); stte.line_max = stte.WrapMargin * 4; stte.line = p_new(char, stte.line_max + 1); stte.param = p_new(char, STRING); @@ -773,7 +687,7 @@ static int alternative_handler (BODY * a, STATE * s) b->parts = mutt_parse_multipart(s->fpin, parameter_getval(a->parameter, "boundary"), (long)st.st_size, - !ascii_strcasecmp("digest", a->subtype)); + mime_which_token(a->subtype, -1) == MIME_DIGEST); } else b = a; @@ -843,18 +757,27 @@ static int alternative_handler (BODY * a, STATE * s) b = a; while (b) { if (b->type == TYPETEXT) { - if (!ascii_strcasecmp ("plain", b->subtype) && type <= TXTPLAIN) { - choice = b; - type = TXTPLAIN; - } - else if (!ascii_strcasecmp ("enriched", b->subtype) - && type <= TXTENRICHED) { - choice = b; - type = TXTENRICHED; - } - else if (!ascii_strcasecmp ("html", b->subtype) && type <= TXTHTML) { - choice = b; - type = TXTHTML; + switch (mime_which_token(b->subtype, -1)) { + case MIME_PLAIN: + if (type <= TXTPLAIN) { + choice = b; + type = TXTPLAIN; + } + break; + case MIME_ENRICHED: + if (type <= TXTENRICHED) { + choice = b; + type = TXTENRICHED; + } + break; + case MIME_HTML: + if (type <= TXTHTML) { + choice = b; + type = TXTHTML; + } + break; + default: + break; } } b = b->next; @@ -950,16 +873,15 @@ int mutt_can_decode (BODY * a) return (1); else if (a->type == TYPEMULTIPART) { BODY *p; + int tok = mime_which_token(a->subtype, -1); - if (ascii_strcasecmp (a->subtype, "signed") == 0 || - ascii_strcasecmp (a->subtype, "encrypted") == 0) - return (1); + if (tok == MIME_SIGNED || tok == MIME_ENCRYPTED) + return 1; for (p = a->parts; p; p = p->next) { if (mutt_can_decode (p)) return (1); } - } else if (a->type == TYPEAPPLICATION) { if (mutt_is_application_pgp(a)) @@ -987,10 +909,10 @@ static int multipart_handler (BODY * a, STATE * s) b->parts = mutt_parse_multipart(s->fpin, parameter_getval(a->parameter, "boundary"), (long)st.st_size, - !ascii_strcasecmp("digest", a->subtype)); - } - else + mime_which_token(a->subtype, -1) == MIME_DIGEST); + } else { b = a; + } for (p = b->parts, count = 1; p; p = p->next, count++) { if (s->flags & M_DISPLAY) { @@ -1025,8 +947,7 @@ static int multipart_handler (BODY * a, STATE * s) } rc = mutt_body_handler (p, s); state_putc ('\n', s); - if (rc || ((s->flags & M_REPLYING) - && (option (OPTINCLUDEONLYFIRST)) && (s->flags & M_FIRSTDONE))) + if (rc) break; } @@ -1085,8 +1006,7 @@ static int autoview_handler (BODY * a, STATE * s) if (!piped) { m_fclose(&fpin); thepid = mutt_create_filter (command, NULL, &fpout, &fperr); - } - else { + } else { unlink (tempfile); fflush (fpin); rewind (fpin); @@ -1124,8 +1044,7 @@ static int autoview_handler (BODY * a, STATE * s) state_puts (buffer, s); } } - } - else { + } else { mutt_copy_stream (fpout, s->fpout); /* Check for stderr messages */ if (fgets (buffer, sizeof (buffer), fperr)) { @@ -1177,7 +1096,7 @@ static int external_body_handler (BODY * b, STATE * s) else expire = -1; - if (!ascii_strcasecmp (access_type, "x-mutt-deleted")) { + if (mime_which_token(access_type, -1) == MIME_X_MUTT_DELETED) { if (s->flags & (M_DISPLAY | M_PRINTING)) { char *length; char pretty_size[10]; @@ -1219,8 +1138,7 @@ static int external_body_handler (BODY * b, STATE * s) (option (OPTWEED) ? (CH_WEED | CH_REORDER) : 0) | CH_DECODE, NULL); } - } - else { + } else { if (s->flags & M_DISPLAY) { state_mark_attach (s); state_printf (s, @@ -1239,6 +1157,85 @@ static int external_body_handler (BODY * b, STATE * s) return (0); } +static void mutt_decode_base64(STATE *s, long len, int istext, iconv_t cd) +{ + char buf[5]; + int c1, c2, c3, c4, ch, cr = 0, i; + char bufi[BUFI_SIZE]; + ssize_t l = 0; + + buf[4] = 0; + + if (istext) + state_set_prefix (s); + + while (len > 0) { + for (i = 0; i < 4 && len > 0; len--) { + if ((ch = fgetc (s->fpin)) == EOF) + break; + if (base64val(ch) >= 0 || ch == '=') + buf[i++] = ch; + } + if (i != 4) { + break; + } + + c1 = base64val(buf[0]); + c2 = base64val(buf[1]); + ch = (c1 << 2) | (c2 >> 4); + + if (cr && ch != '\n') + bufi[l++] = '\r'; + + cr = 0; + + if (istext && ch == '\r') + cr = 1; + else + bufi[l++] = ch; + + if (buf[2] == '=') + break; + c3 = base64val(buf[2]); + ch = ((c2 & 0xf) << 4) | (c3 >> 2); + + if (cr && ch != '\n') + bufi[l++] = '\r'; + + cr = 0; + + if (istext && ch == '\r') + cr = 1; + else + bufi[l++] = ch; + + if (buf[3] == '=') + break; + c4 = base64val(buf[3]); + ch = ((c3 & 0x3) << 6) | c4; + + if (cr && ch != '\n') + bufi[l++] = '\r'; + cr = 0; + + if (istext && ch == '\r') + cr = 1; + else + bufi[l++] = ch; + + if (l + 8 >= ssizeof (bufi)) + mutt_convert_to_state (cd, bufi, &l, s); + } + + if (cr) + bufi[l++] = '\r'; + + mutt_convert_to_state (cd, bufi, &l, s); + mutt_convert_to_state (cd, 0, 0, s); + + state_reset_prefix (s); +} + void mutt_decode_attachment (BODY * b, STATE * s) { int istext = mutt_is_text_part (b); @@ -1250,14 +1247,13 @@ void mutt_decode_attachment (BODY * b, STATE * s) if (s->flags & M_CHARCONV) { const char *charset = parameter_getval(b->parameter, "charset"); - if (!option (OPTSTRICTMIME) && !charset) - charset = charset_getfirst(AssumedCharset); - if (charset && Charset) - cd = mutt_iconv_open (Charset, charset, M_ICONV_HOOK_FROM); - } - else { + if (!charset) + charset = charset_getfirst(mod_cset.assumed_charset); + if (charset && mod_cset.charset) + cd = mutt_iconv_open (mod_cset.charset, charset, M_ICONV_HOOK_FROM); + } else { if (b->file_charset) - cd = mutt_iconv_open (Charset, b->file_charset, M_ICONV_HOOK_FROM); + cd = mutt_iconv_open (mod_cset.charset, b->file_charset, M_ICONV_HOOK_FROM); } } @@ -1298,6 +1294,7 @@ int mutt_body_handler (BODY * b, STATE * s) int rc = 0; int oflags = s->flags; + int tok = mime_which_token(b->subtype, -1); /* first determine which handler to use to process this part */ @@ -1312,7 +1309,7 @@ int mutt_body_handler (BODY * b, STATE * s) rfc1524_entry_delete(&entry); } else if (b->type == TYPETEXT) { - if (ascii_strcasecmp ("plain", b->subtype) == 0) { + if (tok == MIME_PLAIN) { /* avoid copying this part twice since removing the transfer-encoding is * the only operation needed. */ @@ -1324,25 +1321,25 @@ int mutt_body_handler (BODY * b, STATE * s) else plaintext = 1; } - else if (ascii_strcasecmp ("enriched", b->subtype) == 0) + else if (tok == MIME_ENRICHED) handler = text_enriched_handler; else /* text body type without a handler */ plaintext = 1; } else if (b->type == TYPEMESSAGE) { - if (mutt_is_message_type (b->type, b->subtype)) + if (mutt_is_message_type (b)) handler = message_handler; - else if (!ascii_strcasecmp ("delivery-status", b->subtype)) + else if (tok == MIME_DELIVERY_STATUS) plaintext = 1; - else if (!ascii_strcasecmp ("external-body", b->subtype)) + else if (tok == MIME_EXTERNAL_BODY) handler = external_body_handler; } else if (b->type == TYPEMULTIPART) { char *p; - if (ascii_strcasecmp ("alternative", b->subtype) == 0) + if (tok == MIME_ALTERNATIVE) handler = alternative_handler; - else if (ascii_strcasecmp ("signed", b->subtype) == 0) { + else if (tok == MIME_SIGNED) { p = parameter_getval(b->parameter, "protocol"); if (!p) @@ -1351,14 +1348,12 @@ int mutt_body_handler (BODY * b, STATE * s) else if (s->flags & M_VERIFY) handler = mutt_signed_handler; } - else if (m_strcasecmp("encrypted", b->subtype) == 0) { + else if (tok == MIME_ENCRYPTED) { p = parameter_getval(b->parameter, "protocol"); if (!p) - mutt_error (_ - ("Error: multipart/encrypted has no protocol parameter!")); - - else if (ascii_strcasecmp ("application/pgp-encrypted", p) == 0) + mutt_error(_("Error: multipart/encrypted has no protocol parameter!")); + else if (mime_which_token(p, -1) == MIME_APPLICATION_PGP_ENCRYPTED) handler = crypt_pgp_encrypted_handler; } @@ -1372,23 +1367,21 @@ int mutt_body_handler (BODY * b, STATE * s) handler = crypt_smime_application_smime_handler; } - if (plaintext || handler) { fseeko (s->fpin, b->offset, 0); /* see if we need to decode this part before processing it */ - if (b->encoding == ENCBASE64 || b->encoding == ENCQUOTEDPRINTABLE || b->encoding == ENCUUENCODED || plaintext || mutt_is_text_part (b)) { /* text subtypes may - * require character - * set conversion even - * with 8bit encoding. - */ + if (b->encoding == ENCBASE64 || b->encoding == ENCQUOTEDPRINTABLE + || b->encoding == ENCUUENCODED || plaintext || mutt_is_text_part (b)) { + /* text subtypes may require character set conversion even with 8bit + encoding. */ int origType = b->type; char *savePrefix = NULL; if (!plaintext) { /* decode to a tempfile, saving the original destination */ fp = s->fpout; - s->fpout = m_tempfile(tempfile, sizeof(tempfile), NONULL(Tempdir), NULL); + s->fpout = m_tempfile(tempfile, sizeof(tempfile), NONULL(mod_core.tmpdir), NULL); if (!s->fpout) { mutt_error _("Unable to open temporary file!"); goto bail; @@ -1443,7 +1436,6 @@ int mutt_body_handler (BODY * b, STATE * s) s->fpin = fp; } } - s->flags |= M_FIRSTDONE; } else if (s->flags & M_DISPLAY) { state_mark_attach (s); @@ -1460,7 +1452,6 @@ int mutt_body_handler (BODY * b, STATE * s) } bail: - s->flags = oflags | (s->flags & M_FIRSTDONE); - + s->flags = oflags; return (rc); }