X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=commands.c;h=f15ca1c5e8632b331028766a3703bbf791c90a44;hp=5a8862eab519febe038d3c4133985eecc6ec9e86;hb=370334f0cfae3a5a9fe49b40df22e6753a87ac80;hpb=6833ce8bdca2d64e14485118f2a4417b7e1cb1b1 diff --git a/commands.c b/commands.c index 5a8862e..f15ca1c 100644 --- a/commands.c +++ b/commands.c @@ -1,253 +1,178 @@ /* + * Copyright notice from original mutt: * Copyright (C) 1996-2000 Michael R. Elkins * Copyright (C) 2000 Thomas Roessler - * - * 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA. - */ + * + * 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 +#include + +#include +#include +#include +#include #include "mutt.h" -#include "mutt_curses.h" -#include "mutt_menu.h" -#include "mime.h" +#include "alias.h" +#include "recvattach.h" #include "sort.h" -#include "mailbox.h" #include "copy.h" -#include "mx.h" #include "pager.h" -#include "mutt_crypt.h" +#include "crypt.h" #include "mutt_idna.h" -#include "rfc1524.h" #include #include #include -#ifdef USE_IMAP -#include "imap.h" -#endif - -#ifdef BUFFY_SIZE -#include "buffy.h" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -extern char *ReleaseDate; +#include /* The folder the user last saved to. Used by ci_save_message() */ static char LastSaveFolder[_POSIX_PATH_MAX] = ""; -int mutt_display_message (HEADER *cur) +int mutt_display_message (HEADER * cur) { char tempfile[_POSIX_PATH_MAX], buf[LONG_STRING]; - int rc = 0, builtin = 0; int cmflags = M_CM_DECODE | M_CM_DISPLAY | M_CM_CHARCONV; FILE *fpout = NULL; FILE *fpfilterout = NULL; + MESSAGE *msg = NULL; pid_t filterpid = -1; - int res; + int res = 0; snprintf (buf, sizeof (buf), "%s/%s", TYPE (cur->content), - cur->content->subtype); + cur->content->subtype); mutt_parse_mime_message (Context, cur); mutt_message_hook (Context, cur, M_MESSAGEHOOK); - /* see if crytpo is needed for this message. if so, we should exit curses */ - if (WithCrypto && cur->security) - { - if (cur->security & ENCRYPT) - { - if (cur->security & APPLICATION_SMIME) - crypt_smime_getkeys (cur->env); - if(!crypt_valid_passphrase(cur->security)) - return 0; - - cmflags |= M_CM_VERIFY; - } - else if (cur->security & SIGN) - { - /* find out whether or not the verify signature */ - if (query_quadoption (OPT_VERIFYSIG, _("Verify PGP signature?")) == M_YES) - { - cmflags |= M_CM_VERIFY; - } - } - } - - if (cmflags & M_CM_VERIFY || cur->security & ENCRYPT) - { - if (cur->security & APPLICATION_PGP) - { - if (cur->env->from) - crypt_pgp_invoke_getkeys (cur->env->from); - - crypt_invoke_message (APPLICATION_PGP); - } - - if (cur->security & APPLICATION_SMIME) - crypt_invoke_message (APPLICATION_SMIME); - } - - - mutt_mktemp (tempfile); - if ((fpout = safe_fopen (tempfile, "w")) == NULL) - { + fpout = m_tempfile(tempfile, sizeof(tempfile), NONULL(mod_core.tmpdir), NULL); + if (!fpout) { mutt_error _("Could not create temporary file!"); - return (0); + return 0; } - if (DisplayFilter && *DisplayFilter) - { + if (DisplayFilter && *DisplayFilter) { fpfilterout = fpout; fpout = NULL; - /* mutt_endwin (NULL); */ filterpid = mutt_create_filter_fd (DisplayFilter, &fpout, NULL, NULL, - -1, fileno(fpfilterout), -1); - if (filterpid < 0) - { + -1, fileno (fpfilterout), -1); + if (filterpid < 0) { mutt_error (_("Cannot create display filter")); - safe_fclose (&fpfilterout); + m_fclose(&fpfilterout); unlink (tempfile); return 0; } } - if (!Pager || mutt_strcmp (Pager, "builtin") == 0) - builtin = 1; - else - { - mutt_make_string (buf, sizeof (buf), NONULL(PagerFmt), Context, cur); - fputs (buf, fpout); - fputs ("\n\n", fpout); + msg = mx_open_message (Context, cur->msgno); + if (msg == NULL) res = -1; + + if (res != -1) { + /* see if crytpo is needed for this message. if so, we should exit curses */ + if (cur->security) { + if (cur->security & ENCRYPT) { + cmflags |= M_CM_VERIFY; + } + else if (cur->security & SIGN) { + /* find out whether or not the verify signature */ + if (query_quadoption2(mod_crypt.verify_sig, _("Verify PGP signature?")) == + M_YES) { + cmflags |= M_CM_VERIFY; + } + } + } + + res = _mutt_copy_message (fpout, msg->fp, cur, cur->content, cmflags, + (option (OPTWEED) ? (CH_WEED | CH_REORDER) : 0) | + CH_DECODE | CH_FROM); + if (res == 0 && (ferror(fpout) || feof(fpout))) { + res = -1; + } + + mx_close_message (&msg); } - res = mutt_copy_message (fpout, Context, cur, cmflags, - (option (OPTWEED) ? (CH_WEED | CH_REORDER) : 0) | CH_DECODE | CH_FROM); - if ((safe_fclose (&fpout) != 0 && errno != EPIPE) || res == -1) - { + if ((m_fclose(&fpout) != 0 && errno != EPIPE) || res == -1) { mutt_error (_("Could not copy message")); - if (fpfilterout != NULL) - { + if (fpfilterout != NULL) { mutt_wait_filter (filterpid); - safe_fclose (&fpfilterout); + m_fclose(&fpfilterout); } - mutt_unlink (tempfile); - return 0; } if (fpfilterout != NULL && mutt_wait_filter (filterpid) != 0) mutt_any_key_to_continue (NULL); - safe_fclose (&fpfilterout); /* XXX - check result? */ + m_fclose(&fpfilterout); /* XXX - check result? */ - - if (WithCrypto) - { - /* update crypto information for this message */ - cur->security |= crypt_query (cur->content); - - /* Remove color cache for this message, in case there - are color patterns for both ~g and ~V */ - cur->pair = 0; - } - if (builtin) - { - pager_t info; + /* update crypto information for this message */ + cur->security &= ~(GOODSIGN|BADSIGN); + cur->security |= crypt_query (cur->content); - if (WithCrypto - && (cur->security & APPLICATION_SMIME) && (cmflags & M_CM_VERIFY)) - { - if (cur->security & GOODSIGN) - { - if (!crypt_smime_verify_sender(cur)) - mutt_message ( _("S/MIME signature successfully verified.")); - else - mutt_error ( _("S/MIME certificate owner does not match sender.")); - } - else if (cur->security & PARTSIGN) - mutt_message (_("Warning: Part of this message has not been signed.")); - else if (cur->security & SIGN || cur->security & BADSIGN) - mutt_error ( _("S/MIME signature could NOT be verified.")); - } + /* Remove color cache for this message, in case there + are color patterns for both ~g and ~V */ + cur->pair = 0; - if (WithCrypto - && (cur->security & APPLICATION_PGP) && (cmflags & M_CM_VERIFY)) - { - if (cur->security & GOODSIGN) - mutt_message (_("PGP signature successfully verified.")); - else if (cur->security & PARTSIGN) - mutt_message (_("Warning: Part of this message has not been signed.")); + if ((cur->security & APPLICATION_SMIME) && (cmflags & M_CM_VERIFY)) { + if (cur->security & GOODSIGN) { + if (!crypt_smime_verify_sender (cur)) + mutt_message (_("S/MIME signature successfully verified.")); else - mutt_message (_("PGP signature could NOT be verified.")); + mutt_error (_("S/MIME certificate owner does not match sender.")); } + else if (cur->security & PARTSIGN) + mutt_message (_ + ("Warning: Part of this message has not been signed.")); + else if (cur->security & SIGN || cur->security & BADSIGN) + mutt_error (_("S/MIME signature could NOT be verified.")); + } - /* Invoke the builtin pager */ - memset (&info, 0, sizeof (pager_t)); - info.hdr = cur; - info.ctx = Context; - rc = mutt_pager (NULL, tempfile, M_PAGER_MESSAGE, &info); + if ((cur->security & APPLICATION_PGP) && (cmflags & M_CM_VERIFY)) { + if (cur->security & GOODSIGN) + mutt_message (_("PGP signature successfully verified.")); + else if (cur->security & PARTSIGN) + mutt_message (_ + ("Warning: Part of this message has not been signed.")); + else if (cur->security & SIGN) + mutt_message (_("PGP signature could NOT be verified.")); } - else + { - int r; + pager_t info; - mutt_endwin (NULL); - snprintf (buf, sizeof (buf), "%s %s", NONULL(Pager), tempfile); - if ((r = mutt_system (buf)) == -1) - mutt_error (_("Error running \"%s\"!"), buf); - unlink (tempfile); - keypad (stdscr, TRUE); - if (r != -1) - mutt_set_flag (Context, cur, M_READ, 1); - if (r != -1 && option (OPTPROMPTAFTER)) - { - mutt_ungetch (mutt_any_key_to_continue _("Command: "), 0); - rc = km_dokey (MENU_PAGER); - } - else - rc = 0; + p_clear(&info, 1); + info.hdr = cur; + info.ctx = Context; + return mutt_pager (NULL, tempfile, M_PAGER_MESSAGE, &info); } - - return rc; } -void ci_bounce_message (HEADER *h, int *redraw) +void ci_bounce_message (HEADER * h, int *redraw) { - char prompt[SHORT_STRING]; + char prompt[STRING]; char buf[HUGE_STRING] = { 0 }; - ADDRESS *adr = NULL; + address_t *adr = NULL; char *err = NULL; int rc; - if(h) - strfcpy(prompt, _("Bounce message to: "), sizeof(prompt)); + if (h) + m_strcpy(prompt, sizeof(prompt), _("Bounce message to: ")); else - strfcpy(prompt, _("Bounce tagged messages to: "), sizeof(prompt)); - + m_strcpy(prompt, sizeof(prompt), _("Bounce tagged messages to: ")); + rc = mutt_get_field (prompt, buf, sizeof (buf), M_ALIAS); - if (option (OPTNEEDREDRAW)) - { + if (option (OPTNEEDREDRAW)) { unset_option (OPTNEEDREDRAW); *redraw = REDRAW_FULL; } @@ -255,86 +180,71 @@ void ci_bounce_message (HEADER *h, int *redraw) if (rc || !buf[0]) return; - if (!(adr = rfc822_parse_adrlist (adr, buf))) - { + if (!(adr = rfc822_parse_adrlist (adr, buf))) { mutt_error _("Error parsing address!"); + return; } adr = mutt_expand_aliases (adr); - if (mutt_addrlist_to_idna (adr, &err) < 0) - { + if (mutt_addrlist_to_idna (adr, &err) < 0) { mutt_error (_("Bad IDN: '%s'"), err); - FREE (&err); - rfc822_free_address (&adr); + p_delete(&err); + address_list_wipe(&adr); return; } buf[0] = 0; - rfc822_write_address (buf, sizeof (buf), adr, 1); + rfc822_addrcat(buf, sizeof (buf), adr, 1); -#define extra_space (15 + 7 + 2) snprintf (prompt, sizeof (prompt), - (h ? _("Bounce message to %s") : _("Bounce messages to %s")), buf); + (h ? _("Bounce message to %s") : _("Bounce messages to %s")), + buf); - if (mutt_strwidth (prompt) > COLS - extra_space) - { - mutt_format_string (prompt, sizeof (prompt), - 0, COLS-extra_space, 0, 0, - prompt, sizeof (prompt), 0); - strncat (prompt, "...?", sizeof (prompt)); - } - else - strncat (prompt, "?", sizeof (prompt)); - - if (query_quadoption (OPT_BOUNCE, prompt) != M_YES) - { - rfc822_free_address (&adr); - CLEARLINE (LINES - 1); +#define extra_space (15 + 7 + 2) + if (m_strwidth(prompt) > getmaxx(main_w) - extra_space) { + mutt_format_string(prompt, sizeof(prompt), 0, + getmaxx(main_w) - extra_space, 0, 0, prompt, + sizeof(prompt), 0); + m_strcat(prompt, sizeof(prompt), "...?"); + } else { + m_strcat(prompt, sizeof(prompt), "?"); + } +#undef extra_space + + if (query_quadoption (OPT_BOUNCE, prompt) != M_YES) { + address_list_wipe(&adr); mutt_message (h ? _("Message not bounced.") : _("Messages not bounced.")); return; } - CLEARLINE (LINES - 1); - rc = mutt_bounce_message (NULL, h, adr); - rfc822_free_address (&adr); + address_list_wipe(&adr); /* If no error, or background, display message. */ if ((rc == 0) || (rc == S_BKG)) mutt_message (h ? _("Message bounced.") : _("Messages bounced.")); } -static void pipe_set_flags (int decode, int print, int *cmflags, int *chflags) +static void pipe_msg (HEADER * h, FILE * fp, int decode, int print) { - if (decode) - { - *cmflags |= M_CM_DECODE | M_CM_CHARCONV; - *chflags |= CH_DECODE | CH_REORDER; - - if (option (OPTWEED)) - { - *chflags |= CH_WEED; - *cmflags |= M_CM_WEED; + int cmflags = 0; + int chflags = CH_FROM; + + if (decode) { + cmflags |= M_CM_DECODE | M_CM_CHARCONV; + chflags |= CH_DECODE | CH_REORDER; + + if (option(OPTWEED)) { + chflags |= CH_WEED; + cmflags |= M_CM_WEED; } } - - if (print) - *cmflags |= M_CM_PRINTING; - -} -void pipe_msg (HEADER *h, FILE *fp, int decode, int print) -{ - int cmflags = 0; - int chflags = CH_FROM; - - pipe_set_flags (decode, print, &cmflags, &chflags); + if (print) + cmflags |= M_CM_PRINTING; - if (WithCrypto && decode && h->security & ENCRYPT) - { - if(!crypt_valid_passphrase(h->security)) - return; + if (decode && h->security & ENCRYPT) { endwin (); } @@ -344,108 +254,82 @@ void pipe_msg (HEADER *h, FILE *fp, int decode, int print) mutt_copy_message (fp, Context, h, cmflags, chflags); } - /* the following code is shared between printing and piping */ - -static int _mutt_pipe_message (HEADER *h, char *cmd, - int decode, - int print, - int split, - char *sep) +static int _mutt_pipe_message(HEADER * h, char *cmd, int decode, int print, + int split, const char *sep) { - + int i, rc = 0; pid_t thepid; FILE *fpout; - -/* mutt_endwin (NULL); - - is this really needed here ? - it makes the screen flicker on pgp and s/mime messages, - before asking for a passphrase... - Oliver Ehli */ - if (h) - { + if (h) { mutt_message_hook (Context, h, M_MESSAGEHOOK); - if (WithCrypto && decode) - { + if (decode) { mutt_parse_mime_message (Context, h); - if(h->security & ENCRYPT && !crypt_valid_passphrase(h->security)) - return 1; } mutt_endwin (NULL); - if ((thepid = mutt_create_filter (cmd, &fpout, NULL, NULL)) < 0) - { - mutt_perror _("Can't create filter process"); + if ((thepid = mutt_create_filter (cmd, &fpout, NULL, NULL)) < 0) { + mutt_perror (_("Can't create filter process")); + return 1; } - + pipe_msg (h, fpout, decode, print); - fclose (fpout); + m_fclose(&fpout); rc = mutt_wait_filter (thepid); - } - else - { /* handle tagged messages */ - - if (WithCrypto && decode) - { + } else { /* handle tagged messages */ + if (decode) { for (i = 0; i < Context->vcount; i++) - if(Context->hdrs[Context->v2r[i]]->tagged) - { - mutt_message_hook (Context, Context->hdrs[Context->v2r[i]], M_MESSAGEHOOK); - mutt_parse_mime_message(Context, Context->hdrs[Context->v2r[i]]); - if (Context->hdrs[Context->v2r[i]]->security & ENCRYPT && - !crypt_valid_passphrase(Context->hdrs[Context->v2r[i]]->security)) - return 1; - } + if (Context->hdrs[Context->v2r[i]]->tagged) { + mutt_message_hook (Context, Context->hdrs[Context->v2r[i]], + M_MESSAGEHOOK); + mutt_parse_mime_message (Context, Context->hdrs[Context->v2r[i]]); + } } - - if (split) - { - for (i = 0; i < Context->vcount; i++) - { - if (Context->hdrs[Context->v2r[i]]->tagged) - { - mutt_message_hook (Context, Context->hdrs[Context->v2r[i]], M_MESSAGEHOOK); - mutt_endwin (NULL); - if ((thepid = mutt_create_filter (cmd, &fpout, NULL, NULL)) < 0) - { - mutt_perror _("Can't create filter process"); - return 1; - } + + if (split) { + for (i = 0; i < Context->vcount; i++) { + if (Context->hdrs[Context->v2r[i]]->tagged) { + mutt_message_hook (Context, Context->hdrs[Context->v2r[i]], + M_MESSAGEHOOK); + mutt_endwin (NULL); + if ((thepid = mutt_create_filter (cmd, &fpout, NULL, NULL)) < 0) { + mutt_perror (_("Can't create filter process")); + + return 1; + } pipe_msg (Context->hdrs[Context->v2r[i]], fpout, decode, print); /* add the message separator */ - if (sep) fputs (sep, fpout); - safe_fclose (&fpout); - if (mutt_wait_filter (thepid) != 0) - rc = 1; + if (sep) + fputs (sep, fpout); + m_fclose(&fpout); + if (mutt_wait_filter (thepid) != 0) + rc = 1; } } - } - else - { + } else { mutt_endwin (NULL); - if ((thepid = mutt_create_filter (cmd, &fpout, NULL, NULL)) < 0) - { - mutt_perror _("Can't create filter process"); - return 1; + if ((thepid = mutt_create_filter (cmd, &fpout, NULL, NULL)) < 0) { + mutt_perror (_("Can't create filter process")); + + return 1; } - for (i = 0; i < Context->vcount; i++) - { - if (Context->hdrs[Context->v2r[i]]->tagged) - { - mutt_message_hook (Context, Context->hdrs[Context->v2r[i]], M_MESSAGEHOOK); + for (i = 0; i < Context->vcount; i++) { + if (Context->hdrs[Context->v2r[i]]->tagged) { + mutt_message_hook (Context, Context->hdrs[Context->v2r[i]], + M_MESSAGEHOOK); pipe_msg (Context->hdrs[Context->v2r[i]], fpout, decode, print); /* add the message separator */ - if (sep) fputs (sep, fpout); + if (sep) + fputs (sep, fpout); } } - safe_fclose (&fpout); + m_fclose(&fpout); if (mutt_wait_filter (thepid) != 0) - rc = 1; + rc = 1; } } @@ -454,7 +338,7 @@ static int _mutt_pipe_message (HEADER *h, char *cmd, return rc; } -void mutt_pipe_message (HEADER *h) +void mutt_pipe_message (HEADER * h) { char buffer[LONG_STRING]; @@ -465,90 +349,91 @@ void mutt_pipe_message (HEADER *h) mutt_expand_path (buffer, sizeof (buffer)); _mutt_pipe_message (h, buffer, - option (OPTPIPEDECODE), - 0, - option (OPTPIPESPLIT), - PipeSep); + option (OPTPIPEDECODE), + 0, option (OPTPIPESPLIT), PipeSep); } -void mutt_print_message (HEADER *h) +void mutt_print_message (HEADER * h) { - if (quadoption (OPT_PRINT) && (!PrintCmd || !*PrintCmd)) - { + if (quadoption (OPT_PRINT) && m_strisempty(PrintCmd)) { mutt_message (_("No printing command has been defined.")); return; } - + if (query_quadoption (OPT_PRINT, - h ? _("Print message?") : _("Print tagged messages?")) - != M_YES) + h ? _("Print message?") : _("Print tagged messages?")) + != M_YES) return; if (_mutt_pipe_message (h, PrintCmd, - option (OPTPRINTDECODE), - 1, - option (OPTPRINTSPLIT), - "\f") == 0) + option (OPTPRINTDECODE), + 1, option (OPTPRINTSPLIT), "\f") == 0) mutt_message (h ? _("Message printed") : _("Messages printed")); else mutt_message (h ? _("Message could not be printed") : - _("Messages could not be printed")); + _("Messages could not be printed")); } int mutt_select_sort (int reverse) { - int method = Sort; /* save the current method in case of abort */ + int method = Sort; /* save the current method in case of abort */ switch (mutt_multi_choice (reverse ? - _("Rev-Sort (d)ate/(f)rm/(r)ecv/(s)ubj/t(o)/(t)hread/(u)nsort/si(z)e/s(c)ore?: ") : - _("Sort (d)ate/(f)rm/(r)ecv/(s)ubj/t(o)/(t)hread/(u)nsort/si(z)e/s(c)ore?: "), - _("dfrsotuzc"))) - { - case -1: /* abort - don't resort */ + _ + ("Rev-Sort (d)ate/(f)rm/(r)ecv/(s)ubj/t(o)/(t)hread/(u)nsort/si(z)e/s(c)ore/s(p)am?: ") + : + _ + ("Sort (d)ate/(f)rm/(r)ecv/(s)ubj/t(o)/(t)hread/(u)nsort/si(z)e/s(c)ore/s(p)am?: "), + _("dfrsotuzcp"))) { + case -1: /* abort - don't resort */ return -1; - case 1: /* (d)ate */ + case 1: /* (d)ate */ Sort = SORT_DATE; break; - case 2: /* (f)rm */ + case 2: /* (f)rm */ Sort = SORT_FROM; break; - - case 3: /* (r)ecv */ + + case 3: /* (r)ecv */ Sort = SORT_RECEIVED; break; - - case 4: /* (s)ubj */ + + case 4: /* (s)ubj */ Sort = SORT_SUBJECT; break; - - case 5: /* t(o) */ + + case 5: /* t(o) */ Sort = SORT_TO; break; - - case 6: /* (t)hread */ + + case 6: /* (t)hread */ Sort = SORT_THREADS; break; - - case 7: /* (u)nsort */ + + case 7: /* (u)nsort */ Sort = SORT_ORDER; break; - - case 8: /* si(z)e */ + + case 8: /* si(z)e */ Sort = SORT_SIZE; break; - - case 9: /* s(c)ore */ + + case 9: /* s(c)ore */ Sort = SORT_SCORE; break; + + case 10: /* s(p)am */ + Sort = SORT_SPAM; + break; } if (reverse) Sort |= SORT_REVERSE; - return (Sort != method ? 0 : -1); /* no need to resort if it's the same */ + return Sort != method ? 0 : -1; /* no need to resort if it's the same */ } /* invoke a command in a subshell */ @@ -557,17 +442,14 @@ void mutt_shell_escape (void) char buf[LONG_STRING]; buf[0] = 0; - if (mutt_get_field (_("Shell command: "), buf, sizeof (buf), M_CMD) == 0) - { - if (!buf[0] && Shell) - strfcpy (buf, Shell, sizeof (buf)); - if(buf[0]) - { - CLEARLINE (LINES-1); + if (mutt_get_field (_("Shell command: "), buf, sizeof (buf), M_CMD) == 0) { + if (!buf[0]) + m_strcpy(buf, sizeof(buf), mod_core.shell); + if (buf[0]) { mutt_endwin (NULL); fflush (stdout); if (mutt_system (buf) != 0 || option (OPTWAITKEY)) - mutt_any_key_to_continue (NULL); + mutt_any_key_to_continue (NULL); } } } @@ -576,19 +458,19 @@ void mutt_shell_escape (void) void mutt_enter_command (void) { BUFFER err, token; - char buffer[LONG_STRING], errbuf[SHORT_STRING]; + char buffer[LONG_STRING], errbuf[STRING]; int r; buffer[0] = 0; - if (mutt_get_field (":", buffer, sizeof (buffer), M_COMMAND) != 0 || !buffer[0]) + if (mutt_get_field (":", buffer, sizeof (buffer), M_COMMAND) != 0 + || !buffer[0]) return; err.data = errbuf; err.dsize = sizeof (errbuf); - memset (&token, 0, sizeof (token)); + p_clear(&token, 1); r = mutt_parse_rc_line (buffer, &token, &err); - FREE (&token.data); - if (errbuf[0]) - { + p_delete(&token.data); + if (errbuf[0]) { /* since errbuf could potentially contain printf() sequences in it, we must call mutt_error() in this fashion so that vsprintf() doesn't expect more arguments that we passed */ @@ -599,161 +481,138 @@ void mutt_enter_command (void) } } -void mutt_display_address (ENVELOPE *env) +void mutt_display_address (ENVELOPE * env) { - char *pfx = NULL; - char buf[SHORT_STRING]; - ADDRESS *adr = NULL; + const char *pfx = NULL; + char buf[STRING]; + address_t *adr = NULL; + + adr = mutt_get_address(env, &pfx); - adr = mutt_get_address (env, &pfx); + if (!adr) + return; - if (!adr) return; - /* * Note: We don't convert IDNA to local representation this time. * That is intentional, so the user has an opportunity to copy & * paste the on-the-wire form of the address to other, IDN-unable * software. */ - + buf[0] = 0; - rfc822_write_address (buf, sizeof (buf), adr, 0); + rfc822_addrcat(buf, sizeof (buf), adr, 0); mutt_message ("%s: %s", pfx, buf); } -static void set_copy_flags (HEADER *hdr, int decode, int decrypt, int *cmflags, int *chflags) +static void set_copy_flags (HEADER * hdr, int decode, int decrypt, + int *cmflags, int *chflags) { *cmflags = 0; *chflags = CH_UPDATE_LEN; - - if (WithCrypto && !decode && decrypt && (hdr->security & ENCRYPT)) - { - if ((WithCrypto & APPLICATION_PGP) - && mutt_is_multipart_encrypted(hdr->content)) - { + + if (!decode && decrypt && (hdr->security & ENCRYPT)) { + if (mutt_is_multipart_encrypted (hdr->content)) { *chflags = CH_NONEWLINE | CH_XMIT | CH_MIME; *cmflags = M_CM_DECODE_PGP; } - else if ((WithCrypto & APPLICATION_PGP) - && mutt_is_application_pgp (hdr->content) & ENCRYPT) + else if (mutt_is_application_pgp (hdr->content) & ENCRYPT) decode = 1; - else if ((WithCrypto & APPLICATION_SMIME) - && mutt_is_application_smime(hdr->content) & ENCRYPT) - { + else if (mutt_is_application_smime (hdr->content) & ENCRYPT) { *chflags = CH_NONEWLINE | CH_XMIT | CH_MIME; *cmflags = M_CM_DECODE_SMIME; } } - if (decode) - { + if (decode) { *chflags = CH_XMIT | CH_MIME | CH_TXTPLAIN; *cmflags = M_CM_DECODE | M_CM_CHARCONV; - if (!decrypt) /* If decode doesn't kick in for decrypt, */ - { - *chflags |= CH_DECODE; /* then decode RFC 2047 headers, */ + if (!decrypt) { /* If decode doesn't kick in for decrypt, */ + *chflags |= CH_DECODE; /* then decode RFC 2047 headers, */ - if (option (OPTWEED)) - { - *chflags |= CH_WEED; /* and respect $weed. */ - *cmflags |= M_CM_WEED; + if (option (OPTWEED)) { + *chflags |= CH_WEED; /* and respect $weed. */ + *cmflags |= M_CM_WEED; } } } } -void _mutt_save_message (HEADER *h, CONTEXT *ctx, int delete, int decode, int decrypt) -{ +int _mutt_save_message (HEADER * h, CONTEXT * ctx, int delete, int decode, + int decrypt) { int cmflags, chflags; - + int rc; + set_copy_flags (h, decode, decrypt, &cmflags, &chflags); if (decode || decrypt) mutt_parse_mime_message (Context, h); - if (mutt_append_message (ctx, Context, h, cmflags, chflags) == 0) - { - if (delete) - { - mutt_set_flag (Context, h, M_DELETE, 1); - if (option (OPTDELETEUNTAG)) - mutt_set_flag (Context, h, M_TAG, 0); - } + if ((rc = mutt_append_message (ctx, Context, h, cmflags, chflags)) != 0) + return rc; + + if (delete) { + mutt_set_flag (Context, h, M_DELETE, 1); + if (option (OPTDELETEUNTAG)) + mutt_set_flag (Context, h, M_TAG, 0); mutt_set_flag (Context, h, M_APPENDED, 1); } + return 0; } /* returns 0 if the copy/save was successful, or -1 on error/abort */ -int mutt_save_message (HEADER *h, int delete, - int decode, int decrypt, int *redraw) -{ +int mutt_save_message (HEADER * h, int delete, + int decode, int decrypt, int *redraw) { int i, need_buffy_cleanup; - int need_passphrase = 0, app=0; - char prompt[SHORT_STRING], buf[_POSIX_PATH_MAX]; + int need_passphrase = 0, app = 0; + char prompt[STRING], buf[_POSIX_PATH_MAX]; CONTEXT ctx; struct stat st; -#ifdef BUFFY_SIZE - BUFFY *tmp = NULL; -#else struct utimbuf ut; -#endif *redraw = 0; - + snprintf (prompt, sizeof (prompt), - decode ? (delete ? _("Decode-save%s to mailbox") : - _("Decode-copy%s to mailbox")) : - (decrypt ? (delete ? _("Decrypt-save%s to mailbox") : - _("Decrypt-copy%s to mailbox")) : - (delete ? _("Save%s to mailbox") : _("Copy%s to mailbox"))), - h ? "" : _(" tagged")); - + decode ? (delete ? _("Decode-save%s to mailbox") : + _("Decode-copy%s to mailbox")) : + (decrypt ? (delete ? _("Decrypt-save%s to mailbox") : + _("Decrypt-copy%s to mailbox")) : + (delete ? _("Save%s to mailbox") : _("Copy%s to mailbox"))), + h ? "" : _(" tagged")); - if (h) - { - if (WithCrypto) - { - need_passphrase = h->security & ENCRYPT; - app = h->security; - } + + if (h) { + need_passphrase = h->security & ENCRYPT; + app = h->security; mutt_message_hook (Context, h, M_MESSAGEHOOK); mutt_default_save (buf, sizeof (buf), h); } - else - { + else { /* look for the first tagged message */ - for (i = 0; i < Context->vcount; i++) - { - if (Context->hdrs[Context->v2r[i]]->tagged) - { - h = Context->hdrs[Context->v2r[i]]; - break; + for (i = 0; i < Context->vcount; i++) { + if (Context->hdrs[Context->v2r[i]]->tagged) { + h = Context->hdrs[Context->v2r[i]]; + break; } } - if (h) - { + if (h) { mutt_message_hook (Context, h, M_MESSAGEHOOK); mutt_default_save (buf, sizeof (buf), h); - if (WithCrypto) - { - need_passphrase = h->security & ENCRYPT; - app = h->security; - } + need_passphrase = h->security & ENCRYPT; + app = h->security; h = NULL; } } mutt_pretty_mailbox (buf); if (mutt_enter_fname (prompt, buf, sizeof (buf), redraw, 0) == -1) - return (-1); + return -1; - if (*redraw != REDRAW_FULL) - { + if (*redraw != REDRAW_FULL) { if (!h) *redraw = REDRAW_INDEX | REDRAW_STATUS; else @@ -761,15 +620,15 @@ int mutt_save_message (HEADER *h, int delete, } if (!buf[0]) - return (-1); - + return -1; + /* This is an undocumented feature of ELM pointed out to me by Felix von * Leitner */ - if (mutt_strcmp (buf, ".") == 0) - strfcpy (buf, LastSaveFolder, sizeof (buf)); + if (m_strcmp(buf, ".") == 0) + m_strcpy(buf, sizeof(buf), LastSaveFolder); else - strfcpy (LastSaveFolder, buf, sizeof (LastSaveFolder)); + m_strcpy(LastSaveFolder, sizeof(LastSaveFolder), buf); mutt_expand_path (buf, sizeof (buf)); @@ -777,328 +636,152 @@ int mutt_save_message (HEADER *h, int delete, if (mutt_save_confirm (buf, &st) != 0) return -1; - if (WithCrypto && need_passphrase && (decode || decrypt) - && !crypt_valid_passphrase(app)) - return -1; - mutt_message (_("Copying to %s..."), buf); - -#ifdef USE_IMAP - if (Context->magic == M_IMAP && - !(decode || decrypt) && mx_is_imap (buf)) - { - switch (imap_copy_messages (Context, h, buf, delete)) - { + + if (Context->magic == M_IMAP && !(decode || decrypt) && mx_get_magic (buf) == M_IMAP) { + switch (imap_copy_messages (Context, h, buf, delete)) { /* success */ - case 0: mutt_clear_error (); return 0; + case 0: + mutt_clear_error (); + return 0; /* non-fatal error: fall through to fetch/append */ - case 1: break; + case 1: + break; /* fatal error, abort */ - case -1: return -1; + case -1: + return -1; } } -#endif - if (mx_open_mailbox (buf, M_APPEND, &ctx) != NULL) - { - if (h) - _mutt_save_message(h, &ctx, delete, decode, decrypt); - else - { - for (i = 0; i < Context->vcount; i++) - { - if (Context->hdrs[Context->v2r[i]]->tagged) - { - mutt_message_hook (Context, Context->hdrs[Context->v2r[i]], M_MESSAGEHOOK); - _mutt_save_message(Context->hdrs[Context->v2r[i]], - &ctx, delete, decode, decrypt); - } + if (mx_open_mailbox (buf, M_APPEND, &ctx) != NULL) { + if (h) { + if (_mutt_save_message (h, &ctx, delete, decode, decrypt) != 0) { + mx_close_mailbox (&ctx, NULL); + return -1; + } + } else { + for (i = 0; i < Context->vcount; i++) { + if (Context->hdrs[Context->v2r[i]]->tagged) { + mutt_message_hook (Context, Context->hdrs[Context->v2r[i]], + M_MESSAGEHOOK); + if (_mutt_save_message (Context->hdrs[Context->v2r[i]], &ctx, delete, + decode, decrypt) != 0) { + mx_close_mailbox (&ctx, NULL); + return -1; + } + } } } - need_buffy_cleanup = (ctx.magic == M_MBOX || ctx.magic == M_MMDF); + need_buffy_cleanup = (ctx.magic == M_MBOX); mx_close_mailbox (&ctx, NULL); - if (need_buffy_cleanup) - { -#ifdef BUFFY_SIZE - tmp = mutt_find_mailbox (buf); - if (tmp && !tmp->new) - mutt_update_mailbox (tmp); -#else + if (need_buffy_cleanup) { /* fix up the times so buffy won't get confused */ - if (st.st_mtime > st.st_atime) - { - ut.actime = st.st_atime; - ut.modtime = time (NULL); - utime (buf, &ut); + if (st.st_mtime > st.st_atime) { + ut.actime = st.st_atime; + ut.modtime = time (NULL); + utime (buf, &ut); + } else { + utime (buf, NULL); } - else - utime (buf, NULL); -#endif } mutt_clear_error (); - return (0); - } - - return -1; -} - -int mutt_update_list_file (char *filename, char *section, char *key, char *line) -{ - FILE *ifp; - FILE *ofp; - char buf[HUGE_STRING]; - char oldfile[_POSIX_PATH_MAX]; - char *c; - int ext = 0, done = 0, r = 0; - - snprintf (oldfile, sizeof(oldfile), "%s.bak", filename); - dprint (1, (debugfile, "Renaming %s to %s\n", filename, oldfile)); - - /* if file not exist, create it */ - if ((ifp = safe_fopen (filename, "a"))) - fclose (ifp); - if (_mutt_rename_file (filename, oldfile, 1)) - { - mutt_perror _("Unable to create backup file"); - return (-1); - } - dprint (1, (debugfile, "Opening %s\n", oldfile)); - if (!(ifp = safe_fopen (oldfile, "r"))) - { - mutt_perror _("Unable to open backup file for reading"); - return (-1); - } - dprint (1, (debugfile, "Opening %s\n", filename)); - if (!(ofp = fopen (filename, "w"))) - { - fclose (ifp); - mutt_perror _("Unable to open new file for writing"); - return (-1); - } - if (mx_lock_file (filename, fileno (ofp), 1, 0, 1)) - { - fclose (ofp); - fclose (ifp); - mutt_error (_("Unable to lock %s, old file saved as %s"), filename, oldfile); - return (-1); - } - - if (section) - { - while (r != EOF && !done && fgets (buf, sizeof (buf), ifp)) - { - r = fputs (buf, ofp); - c = buf; - while (*c && *c != '\n') c++; - c[0] = 0; /* strip EOL */ - if (!strncmp (buf, "#: ", 3) && !mutt_strcasecmp (buf+3, section)) - done++; - } - if (r != EOF && !done) - { - snprintf (buf, sizeof(buf), "#: %s\n", section); - r = fputs (buf, ofp); - } - done = 0; - } - - while (r != EOF && fgets (buf, sizeof (buf), ifp)) - { - if (ext) - { - c = buf; - while (*c && (*c != '\r') && (*c != '\n')) c++; - c--; - if (*c != '\\') ext = 0; - } - else if ((section && !strncmp (buf, "#: ", 3))) - { - if (!done && line) - { - fputs (line, ofp); - fputc ('\n', ofp); - } - r = fputs (buf, ofp); - done++; - break; - } - else if (key && !strncmp (buf, key, strlen(key)) && - (!*key || buf[strlen(key)] == ' ')) - { - c = buf; - ext = 0; - while (*c && (*c != '\r') && (*c != '\n')) c++; - c--; - if (*c == '\\') ext = 1; - if (!done && line) - { - r = fputs (line, ofp); - if (*key) - r = fputc ('\n', ofp); - done++; - } - } - else - { - r = fputs (buf, ofp); - } - } - - while (r != EOF && fgets (buf, sizeof (buf), ifp)) - r = fputs (buf, ofp); - - /* If there wasn't a line to replace, put it on the end of the file */ - if (r != EOF && !done && line) - { - fputs (line, ofp); - r = fputc ('\n', ofp); - } - mx_unlock_file (filename, fileno (ofp), 0); - fclose (ofp); - fclose (ifp); - if (r != EOF) - { - unlink (oldfile); return 0; } - unlink (filename); - mutt_error (_("Cannot write new %s, old file saved as %s"), filename, - oldfile); - return (-1); -} - -void mutt_version (void) -{ - mutt_message ("Mutt %s (%s)", MUTT_VERSION, ReleaseDate); + return -1; } -void mutt_edit_content_type (HEADER *h, BODY *b, FILE *fp) +void mutt_edit_content_type (HEADER * h, BODY * b, FILE * fp) { char buf[LONG_STRING]; char obuf[LONG_STRING]; char tmp[STRING]; - PARAMETER *p; char charset[STRING]; char *cp; short charset_changed = 0; short type_changed = 0; - - cp = mutt_get_parameter ("charset", b->parameter); - strfcpy (charset, NONULL (cp), sizeof (charset)); + + cp = parameter_getval(b->parameter, "charset"); + m_strcpy(charset, sizeof(charset), NONULL(cp)); snprintf (buf, sizeof (buf), "%s/%s", TYPE (b), b->subtype); - strfcpy (obuf, buf, sizeof (obuf)); - if (b->parameter) - { - size_t l; - - for (p = b->parameter; p; p = p->next) - { - l = strlen (buf); + m_strcpy(obuf, sizeof(obuf), buf); + if (b->parameter) { + parameter_t *p; + ssize_t l; + + for (p = b->parameter; p; p = p->next) { + l = m_strlen(buf); - rfc822_cat (tmp, sizeof (tmp), p->value, MimeSpecials); + rfc822_strcpy(tmp, sizeof(tmp), p->value, MimeSpecials); snprintf (buf + l, sizeof (buf) - l, "; %s=%s", p->attribute, tmp); } } - + if (mutt_get_field ("Content-Type: ", buf, sizeof (buf), 0) != 0 || buf[0] == 0) return; - + /* clean up previous junk */ - mutt_free_parameter (&b->parameter); - FREE (&b->subtype); - + parameter_list_wipe(&b->parameter); + p_delete(&b->subtype); + mutt_parse_content_type (buf, b); - + snprintf (tmp, sizeof (tmp), "%s/%s", TYPE (b), NONULL (b->subtype)); type_changed = ascii_strcasecmp (tmp, obuf); - charset_changed = ascii_strcasecmp (charset, mutt_get_parameter ("charset", b->parameter)); + charset_changed = + ascii_strcasecmp (charset, parameter_getval(b->parameter, "charset")); /* if in send mode, check for conversion - current setting is default. */ - if (!h && b->type == TYPETEXT && charset_changed) - { + if (!h && b->type == TYPETEXT && charset_changed) { int r; + snprintf (tmp, sizeof (tmp), _("Convert to %s upon sending?"), - mutt_get_parameter ("charset", b->parameter)); + parameter_getval(b->parameter, "charset")); if ((r = mutt_yesorno (tmp, !b->noconv)) != -1) b->noconv = (r == M_NO); } /* inform the user */ - + + snprintf (tmp, sizeof (tmp), "%s/%s", TYPE (b), NONULL (b->subtype)); if (type_changed) mutt_message (_("Content-Type changed to %s."), tmp); - else if (b->type == TYPETEXT && charset_changed) + if (b->type == TYPETEXT && charset_changed) { + if (type_changed) + mutt_sleep (1); mutt_message (_("Character set changed to %s; %s."), - mutt_get_parameter ("charset", b->parameter), - b->noconv ? _("not converting") : _("converting")); + parameter_getval(b->parameter, "charset"), + b->noconv ? _("not converting") : _("converting")); + } b->force_charset |= charset_changed ? 1 : 0; - if (!is_multipart (b) && b->parts) - mutt_free_body (&b->parts); - if (!mutt_is_message_type (b->type, b->subtype) && b->hdr) - { + if (!is_multipart(b) && b->parts) + body_list_wipe(&b->parts); + if (!mutt_is_message_type(b) && b->hdr) { b->hdr->content = NULL; - mutt_free_header (&b->hdr); + header_delete(&b->hdr); } - if (fp && (is_multipart (b) || mutt_is_message_type (b->type, b->subtype))) + if (fp && (is_multipart(b) || mutt_is_message_type(b))) mutt_parse_part (fp, b); - - if (WithCrypto && h) - { + + if (h) { if (h->content == b) - h->security = 0; + h->security = 0; h->security |= crypt_query (b); } } -static int _mutt_check_traditional_pgp (HEADER *h, int *redraw) -{ - MESSAGE *msg; - int rv = 0; - - mutt_parse_mime_message (Context, h); - if ((msg = mx_open_message (Context, h->msgno)) == NULL) - return 0; - if (crypt_pgp_check_traditional (msg->fp, h->content, 0)) - { - h->security = crypt_query (h->content); - *redraw |= REDRAW_FULL; - rv = 1; - } - - mx_close_message (&msg); - return rv; -} - -int mutt_check_traditional_pgp (HEADER *h, int *redraw) -{ - int i; - int rv = 0; - if (h) - rv = _mutt_check_traditional_pgp (h, redraw); - else - { - for (i = 0; i < Context->vcount; i++) - if (Context->hdrs[Context->v2r[i]]->tagged) - rv = _mutt_check_traditional_pgp (Context->hdrs[Context->v2r[i]], redraw) - || rv; - } - return rv; -} - -