X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=sendlib.c;h=3551aaf3680697c7c36fd9e99ceec45116bed0a4;hp=7a718a2dfa3bd7c849d81e863b2170c40ec219d1;hb=fdb93a08e305b8755260144807e4d45106a9cb9f;hpb=047342c2a0526885217e03d06e9b7a715f55b92f diff --git a/sendlib.c b/sendlib.c index 7a718a2..3551aaf 100644 --- a/sendlib.c +++ b/sendlib.c @@ -1,35 +1,17 @@ /* + * Copyright notice from original mutt: * Copyright (C) 1996-2002 Michael R. Elkins - * - * 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. + */ #define _SENDLIB_C 1 -#include "mutt.h" -#include "mutt_curses.h" -#include "rfc2047.h" -#include "rfc2231.h" -#include "mx.h" -#include "mime.h" -#include "mailbox.h" -#include "copy.h" -#include "pager.h" -#include "charset.h" -#include "mutt_crypt.h" -#include "mutt_idna.h" +#if HAVE_CONFIG_H +# include "config.h" +#endif #include #include @@ -42,6 +24,33 @@ #include #include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include + +#include "mutt.h" +#include "handler.h" +#include "recvattach.h" +#include "mx.h" +#include "copy.h" +#include "pager.h" +#include "charset.h" +#include +#include "mutt_idna.h" + +#ifdef USE_LIBESMTP +# include "mutt_libesmtp.h" +#endif /* USE_LIBESMTP */ + #ifdef USE_NNTP #include #endif @@ -61,111 +70,37 @@ #include #endif -extern char RFC822Specials[]; - -static struct sysexits -{ - int v; - const char *str; -} -sysexits_h[] = -{ -#ifdef EX_USAGE - { 0xff & EX_USAGE, "Bad usage." }, -#endif -#ifdef EX_DATAERR - { 0xff & EX_DATAERR, "Data format error." }, -#endif -#ifdef EX_NOINPUT - { 0xff & EX_NOINPUT, "Cannot open input." }, -#endif -#ifdef EX_NOUSER - { 0xff & EX_NOUSER, "User unknown." }, -#endif -#ifdef EX_NOHOST - { 0xff & EX_NOHOST, "Host unknown." }, -#endif -#ifdef EX_UNAVAILABLE - { 0xff & EX_UNAVAILABLE, "Service unavailable." }, -#endif -#ifdef EX_SOFTWARE - { 0xff & EX_SOFTWARE, "Internal error." }, -#endif -#ifdef EX_OSERR - { 0xff & EX_OSERR, "Operating system error." }, -#endif -#ifdef EX_OSFILE - { 0xff & EX_OSFILE, "System file missing." }, -#endif -#ifdef EX_CANTCREAT - { 0xff & EX_CANTCREAT, "Can't create output." }, -#endif -#ifdef EX_IOERR - { 0xff & EX_IOERR, "I/O error." }, -#endif -#ifdef EX_TEMPFAIL - { 0xff & EX_TEMPFAIL, "Deferred." }, -#endif -#ifdef EX_PROTOCOL - { 0xff & EX_PROTOCOL, "Remote protocol error." }, -#endif -#ifdef EX_NOPERM - { 0xff & EX_NOPERM, "Insufficient permission." }, -#endif -#ifdef EX_CONFIG - { 0xff & EX_NOPERM, "Local configuration error." }, -#endif - { S_ERR, "Exec error." }, - { -1, NULL} -}; - - - #define DISPOSITION(X) X==DISPATTACH?"attachment":"inline" -const char MimeSpecials[] = "@.,;:<>[]\\\"()?/= \t"; - -char B64Chars[64] = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', - 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', - 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', - 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', '+', '/' -}; - static char MsgIdPfx = 'A'; -static void transform_to_7bit (BODY *a, FILE *fpin); +static void transform_to_7bit (BODY * a, FILE * fpin); -static void encode_quoted (FGETCONV * fc, FILE *fout, int istext) +static void encode_quoted (FGETCONV * fc, FILE * fout, int istext) { int c, linelen = 0; char line[77], savechar; - while ((c = fgetconv (fc)) != EOF) - { + while ((c = fgetconv (fc)) != EOF) { /* Wrap the line if needed. */ - if (linelen == 76 && ((istext && c != '\n') || !istext)) - { + if (linelen == 76 && ((istext && c != '\n') || !istext)) { /* If the last character is "quoted", then be sure to move all three * characters to the next line. Otherwise, just move the last * character... */ - if (line[linelen-3] == '=') - { - line[linelen-3] = 0; - fputs (line, fout); + if (line[linelen - 3] == '=') { + line[linelen - 3] = 0; + fputs (line, fout); fputs ("=\n", fout); line[linelen] = 0; line[0] = '='; - line[1] = line[linelen-2]; - line[2] = line[linelen-1]; + line[1] = line[linelen - 2]; + line[2] = line[linelen - 1]; linelen = 3; } - else - { - savechar = line[linelen-1]; - line[linelen-1] = '='; + else { + savechar = line[linelen - 1]; + line[linelen - 1] = '='; line[linelen] = 0; fputs (line, fout); fputc ('\n', fout); @@ -175,72 +110,60 @@ static void encode_quoted (FGETCONV * fc, FILE *fout, int istext) } /* Escape lines that begin with/only contain "the message separator". */ - if (linelen == 4 && !mutt_strncmp ("From", line, 4)) - { - strfcpy (line, "=46rom", sizeof (line)); + if (linelen == 4 && !m_strncmp("From", line, 4)) { + m_strcpy(line, sizeof(line), "=46rom"); linelen = 6; } - else if (linelen == 4 && !mutt_strncmp ("from", line, 4)) - { - strfcpy (line, "=66rom", sizeof (line)); + else if (linelen == 4 && !m_strncmp("from", line, 4)) { + m_strcpy(line, sizeof(line), "=66rom"); linelen = 6; } - else if (linelen == 1 && line[0] == '.') - { - strfcpy (line, "=2E", sizeof (line)); + else if (linelen == 1 && line[0] == '.') { + m_strcpy(line, sizeof(line), "=2E"); linelen = 3; } -#ifdef USE_LIBESMTP -# include "mutt_libesmtp.h" -#endif /* USE_LIBESMTP */ - if (c == '\n' && istext) - { + if (c == '\n' && istext) { /* Check to make sure there is no trailing space on this line. */ - if (linelen > 0 && (line[linelen-1] == ' ' || line[linelen-1] == '\t')) - { - if (linelen < 74) - { - sprintf (line+linelen-1, "=%2.2X", (unsigned char) line[linelen-1]); + if (linelen > 0 + && (line[linelen - 1] == ' ' || line[linelen - 1] == '\t')) { + if (linelen < 74) { + sprintf (line + linelen - 1, "=%2.2X", + (unsigned char) line[linelen - 1]); fputs (line, fout); } - else - { - int savechar = line[linelen-1]; + else { + int savechar = line[linelen - 1]; - line[linelen-1] = '='; + line[linelen - 1] = '='; line[linelen] = 0; fputs (line, fout); fprintf (fout, "\n=%2.2X", (unsigned char) savechar); } } - else - { + else { line[linelen] = 0; fputs (line, fout); } fputc ('\n', fout); linelen = 0; } - else if (c != 9 && (c < 32 || c > 126 || c == '=')) - { + else if (c != 9 && (c < 32 || c > 126 || c == '=')) { /* Check to make sure there is enough room for the quoted character. * If not, wrap to the next line. */ - if (linelen > 73) - { + if (linelen > 73) { line[linelen++] = '='; line[linelen] = 0; fputs (line, fout); fputc ('\n', fout); linelen = 0; } - sprintf (line+linelen,"=%2.2X", (unsigned char) c); + sprintf (line + linelen, "=%2.2X", (unsigned char) c); linelen += 3; } - else - { + else { /* Don't worry about wrapping the line here. That will happen during * the next iteration when I'll also know what the next character is. */ @@ -249,17 +172,15 @@ static void encode_quoted (FGETCONV * fc, FILE *fout, int istext) } /* Take care of anything left in the buffer */ - if (linelen > 0) - { - if (line[linelen-1] == ' ' || line[linelen-1] == '\t') - { + if (linelen > 0) { + if (line[linelen - 1] == ' ' || line[linelen - 1] == '\t') { /* take care of trailing whitespace */ if (linelen < 74) - sprintf (line+linelen-1, "=%2.2X", (unsigned char) line[linelen-1]); - else - { - savechar = line[linelen-1]; - line[linelen-1] = '='; + sprintf (line + linelen - 1, "=%2.2X", + (unsigned char) line[linelen - 1]); + else { + savechar = line[linelen - 1]; + line[linelen - 1] = '='; line[linelen] = 0; fputs (line, fout); fputc ('\n', fout); @@ -276,84 +197,82 @@ static char b64_buffer[3]; static short b64_num; static short b64_linelen; -static void b64_flush(FILE *fout) +static void b64_flush (FILE * fout) { short i; - if(!b64_num) + if (!b64_num) return; - if(b64_linelen >= 72) - { - fputc('\n', fout); + if (b64_linelen >= 72) { + fputc ('\n', fout); b64_linelen = 0; } - - for(i = b64_num; i < 3; i++) + + for (i = b64_num; i < 3; i++) b64_buffer[i] = '\0'; - - fputc(B64Chars[(b64_buffer[0] >> 2) & 0x3f], fout); + + fputc(__m_b64chars[(b64_buffer[0] >> 2) & 0x3f], fout); b64_linelen++; - fputc(B64Chars[((b64_buffer[0] & 0x3) << 4) | ((b64_buffer[1] >> 4) & 0xf) ], fout); + fputc(__m_b64chars + [((b64_buffer[0] & 0x3) << 4) | ((b64_buffer[1] >> 4) & 0xf)], fout); b64_linelen++; - - if(b64_num > 1) - { - fputc(B64Chars[((b64_buffer[1] & 0xf) << 2) | ((b64_buffer[2] >> 6) & 0x3) ], fout); + + if (b64_num > 1) { + fputc (__m_b64chars + [((b64_buffer[1] & 0xf) << 2) | ((b64_buffer[2] >> 6) & 0x3)], + fout); b64_linelen++; - if(b64_num > 2) - { - fputc(B64Chars[b64_buffer[2] & 0x3f], fout); + if (b64_num > 2) { + fputc (__m_b64chars[b64_buffer[2] & 0x3f], fout); b64_linelen++; } } - - while(b64_linelen % 4) - { - fputc('=', fout); + + while (b64_linelen % 4) { + fputc ('=', fout); b64_linelen++; } - + b64_num = 0; } - - -static void b64_putc(char c, FILE *fout) + + +static void b64_putc (char c, FILE * fout) { - if(b64_num == 3) - b64_flush(fout); - + if (b64_num == 3) + b64_flush (fout); + b64_buffer[b64_num++] = c; } - - -static void encode_base64 (FGETCONV * fc, FILE *fout, int istext) + + +static void encode_base64 (FGETCONV * fc, FILE * fout, int istext) { int ch, ch1 = EOF; - + b64_num = b64_linelen = 0; - - while ((ch = fgetconv (fc)) != EOF) - { + + while ((ch = fgetconv (fc)) != EOF) { if (istext && ch == '\n' && ch1 != '\r') - b64_putc('\r', fout); - b64_putc(ch, fout); + b64_putc ('\r', fout); + b64_putc (ch, fout); ch1 = ch; } - b64_flush(fout); - fputc('\n', fout); + b64_flush (fout); + fputc ('\n', fout); } -static void encode_8bit (FGETCONV *fc, FILE *fout, int istext) +static void encode_8bit (FGETCONV * fc, FILE * fout, int istext) { int ch; - + while ((ch = fgetconv (fc)) != EOF) fputc (ch, fout); } - -int mutt_write_mime_header (BODY *a, FILE *f) + +int mutt_write_mime_header (BODY * a, FILE * f) { PARAMETER *p; char buffer[STRING]; @@ -362,48 +281,45 @@ int mutt_write_mime_header (BODY *a, FILE *f) int len; int tmplen; int encode; - + fprintf (f, "Content-Type: %s/%s", TYPE (a), a->subtype); - if (a->parameter) - { - len = 25 + mutt_strlen (a->subtype); /* approximate len. of content-type */ + if (a->parameter) { + len = 25 + m_strlen(a->subtype); /* approximate len. of content-type */ - for(p = a->parameter; p; p = p->next) - { + for (p = a->parameter; p; p = p->next) { char *tmp; - - if(!p->value) - continue; - + + if (!p->value) + continue; + fputc (';', f); buffer[0] = 0; - tmp = safe_strdup (p->value); + tmp = m_strdup(p->value); encode = rfc2231_encode_string (&tmp); - rfc822_cat (buffer, sizeof (buffer), tmp, MimeSpecials); + rfc822_strcpy(buffer, sizeof(buffer), tmp, MimeSpecials); /* Dirty hack to make messages readable by Outlook Express * for the Mac: force quotes around the boundary parameter * even when they aren't needed. */ - if (!ascii_strcasecmp (p->attribute, "boundary") && !strcmp (buffer, tmp)) - snprintf (buffer, sizeof (buffer), "\"%s\"", tmp); + if (!ascii_strcasecmp (p->attribute, "boundary") + && !strcmp (buffer, tmp)) + snprintf (buffer, sizeof (buffer), "\"%s\"", tmp); - FREE (&tmp); + p_delete(&tmp); - tmplen = mutt_strlen (buffer) + mutt_strlen (p->attribute) + 1; + tmplen = m_strlen(buffer) + m_strlen(p->attribute) + 1; - if (len + tmplen + 2 > 76) - { - fputs ("\n\t", f); - len = tmplen + 8; + if (len + tmplen + 2 > 76) { + fputs ("\n\t", f); + len = tmplen + 8; } - else - { - fputc (' ', f); - len += tmplen + 1; + else { + fputc (' ', f); + len += tmplen + 1; } fprintf (f, "%s%s=%s", p->attribute, encode ? "*" : "", buffer); @@ -414,30 +330,28 @@ int mutt_write_mime_header (BODY *a, FILE *f) fputc ('\n', f); if (a->description) - fprintf(f, "Content-Description: %s\n", a->description); + fprintf (f, "Content-Description: %s\n", a->description); fprintf (f, "Content-Disposition: %s", DISPOSITION (a->disposition)); - if (a->use_disp) - { - if(!(fn = a->d_filename)) + if (a->use_disp) { + if (!(fn = a->d_filename)) fn = a->filename; - - if (fn) - { + + if (fn) { char *tmp; /* Strip off the leading path... */ if ((t = strrchr (fn, '/'))) - t++; + t++; else - t = fn; - + t = fn; + buffer[0] = 0; - tmp = safe_strdup (t); + tmp = m_strdup(t); encode = rfc2231_encode_string (&tmp); - rfc822_cat (buffer, sizeof (buffer), tmp, MimeSpecials); - FREE (&tmp); + rfc822_strcpy(buffer, sizeof(buffer), tmp, MimeSpecials); + p_delete(&tmp); fprintf (f, "; filename%s=%s", encode ? "*" : "", buffer); } } @@ -445,68 +359,58 @@ int mutt_write_mime_header (BODY *a, FILE *f) fputc ('\n', f); if (a->encoding != ENC7BIT) - fprintf(f, "Content-Transfer-Encoding: %s\n", ENCODING (a->encoding)); + fprintf (f, "Content-Transfer-Encoding: %s\n", ENCODING (a->encoding)); /* Do NOT add the terminator here!!! */ return (ferror (f) ? -1 : 0); } -# define write_as_text_part(a) (mutt_is_text_part(a) \ - || ((WithCrypto & APPLICATION_PGP)\ - && mutt_is_application_pgp(a))) +# define write_as_text_part(a) (mutt_is_text_part(a) || mutt_is_application_pgp(a)) -int mutt_write_mime_body (BODY *a, FILE *f) +int mutt_write_mime_body (BODY * a, FILE * f) { char *p, boundary[SHORT_STRING]; char send_charset[SHORT_STRING]; FILE *fpin; BODY *t; FGETCONV *fc; - - if (a->type == TYPEMULTIPART) - { + + if (a->type == TYPEMULTIPART) { /* First, find the boundary to use */ - if (!(p = mutt_get_parameter ("boundary", a->parameter))) - { - dprint (1, (debugfile, "mutt_write_mime_body(): no boundary parameter found!\n")); + if (!(p = mutt_get_parameter ("boundary", a->parameter))) { mutt_error _("No boundary parameter found! [report this error]"); + return (-1); } - strfcpy (boundary, p, sizeof (boundary)); + m_strcpy(boundary, sizeof(boundary), p); - for (t = a->parts; t ; t = t->next) - { + for (t = a->parts; t; t = t->next) { fprintf (f, "\n--%s\n", boundary); if (mutt_write_mime_header (t, f) == -1) - return -1; + return -1; fputc ('\n', f); if (mutt_write_mime_body (t, f) == -1) - return -1; + return -1; } fprintf (f, "\n--%s--\n", boundary); return (ferror (f) ? -1 : 0); } /* This is pretty gross, but it's the best solution for now... */ - if ((WithCrypto & APPLICATION_PGP) - && a->type == TYPEAPPLICATION - && mutt_strcmp (a->subtype, "pgp-encrypted") == 0) - { + if (a->type == TYPEAPPLICATION && !m_strcmp(a->subtype, "pgp-encrypted")) { fputs ("Version: 1\n", f); return 0; } - if ((fpin = fopen (a->filename, "r")) == NULL) - { - dprint(1,(debugfile, "write_mime_body: %s no longer exists!\n",a->filename)); + if ((fpin = fopen (a->filename, "r")) == NULL) { mutt_error (_("%s no longer exists!"), a->filename); return -1; } if (a->type == TYPETEXT && (!a->noconv)) - fc = fgetconv_open (fpin, Charset, - mutt_get_body_charset (send_charset, sizeof (send_charset), a), - 0); + fc = fgetconv_open (fpin, a->file_charset, + mutt_get_body_charset (send_charset, + sizeof (send_charset), a), 0); else fc = fgetconv_open (fpin, 0, 0, 0); @@ -528,32 +432,31 @@ int mutt_write_mime_body (BODY *a, FILE *f) #undef write_as_text_part #define BOUNDARYLEN 16 -void mutt_generate_boundary (PARAMETER **parm) +void mutt_generate_boundary (PARAMETER ** parm) { char rs[BOUNDARYLEN + 1]; char *p = rs; int i; rs[BOUNDARYLEN] = 0; - for (i=0;ifrom; int whitespace = s->whitespace; @@ -561,8 +464,7 @@ static void update_content_info (CONTENT *info, CONTENT_STATE *s, char *d, size_ int linelen = s->linelen; int was_cr = s->was_cr; - if (!d) /* This signals EOF */ - { + if (!d) { /* This signals EOF */ if (was_cr) info->binary = 1; if (linelen > info->linemax) @@ -571,42 +473,42 @@ static void update_content_info (CONTENT *info, CONTENT_STATE *s, char *d, size_ return; } - for (; dlen; d++, dlen--) - { + for (; dlen; d++, dlen--) { char ch = *d; - if (was_cr) - { + if (was_cr) { was_cr = 0; - if (ch != '\n') - { + if (ch != '\n') { info->binary = 1; } - else - { - if (whitespace) info->space = 1; - if (dot) info->dot = 1; - if (linelen > info->linemax) info->linemax = linelen; + else { + if (whitespace) + info->space = 1; + if (dot) + info->dot = 1; + if (linelen > info->linemax) + info->linemax = linelen; whitespace = 0; - dot = 0; + dot = 0; linelen = 0; - continue; + continue; } } linelen++; - if (ch == '\n') - { + if (ch == '\n') { info->crlf++; - if (whitespace) info->space = 1; - if (dot) info->dot = 1; - if (linelen > info->linemax) info->linemax = linelen; + if (whitespace) + info->space = 1; + if (dot) + info->dot = 1; + if (linelen > info->linemax) + info->linemax = linelen; whitespace = 0; linelen = 0; dot = 0; } - else if (ch == '\r') - { + else if (ch == '\r') { info->crlf++; info->cr = 1; was_cr = 1; @@ -614,17 +516,14 @@ static void update_content_info (CONTENT *info, CONTENT_STATE *s, char *d, size_ } else if (ch & 0x80) info->hibin++; - else if (ch == '\t' || ch == '\f') - { + else if (ch == '\t' || ch == '\f') { info->ascii++; whitespace++; } else if (ch < 32 || ch == 127) info->lobin++; - else - { - if (linelen == 1) - { + else { + if (linelen == 1) { if ((ch == 'F') || (ch == 'f')) from = 1; else @@ -634,22 +533,26 @@ static void update_content_info (CONTENT *info, CONTENT_STATE *s, char *d, size_ else dot = 0; } - else if (from) - { - if (linelen == 2 && ch != 'r') from = 0; - else if (linelen == 3 && ch != 'o') from = 0; - else if (linelen == 4) - { - if (ch == 'm') info->from = 1; + else if (from) { + if (linelen == 2 && ch != 'r') + from = 0; + else if (linelen == 3 && ch != 'o') + from = 0; + else if (linelen == 4) { + if (ch == 'm') + info->from = 1; from = 0; } } - if (ch == ' ') whitespace++; + if (ch == ' ') + whitespace++; info->ascii++; } - if (linelen > 1) dot = 0; - if (ch != ' ' && ch != '\t') whitespace = 0; + if (linelen > 1) + dot = 0; + if (ch != ' ' && ch != '\t') + whitespace = 0; } s->from = from; @@ -657,7 +560,7 @@ static void update_content_info (CONTENT *info, CONTENT_STATE *s, char *d, size_ s->dot = dot; s->linelen = linelen; s->was_cr = was_cr; - + } /* Define as 1 if iconv sometimes returns -1(EILSEQ) instead of transcribing. */ @@ -679,41 +582,40 @@ static void update_content_info (CONTENT *info, CONTENT_STATE *s, char *d, size_ * long as the input for any pair of charsets we might be interested * in. */ -static size_t convert_file_to (FILE *file, const char *fromcode, - int ncodes, const char **tocodes, - int *tocode, CONTENT *info) +static ssize_t convert_file_to (FILE * file, const char *fromcode, + int ncodes, const char **tocodes, + int *tocode, CONTENT * info) { #ifdef HAVE_ICONV iconv_t cd1, *cd; char bufi[256], bufu[512], bufo[4 * sizeof (bufi)]; - ICONV_CONST char *ib, *ub; + const char *ib, *ub; char *ob; - size_t ibl, obl, ubl, ubl1, n, ret; + ssize_t ibl, obl, ubl, ubl1, n, ret; int i; CONTENT *infos; CONTENT_STATE *states; - size_t *score; + ssize_t *score; cd1 = mutt_iconv_open ("UTF-8", fromcode, 0); - if (cd1 == (iconv_t)(-1)) + if (cd1 == (iconv_t) (-1)) return -1; - cd = safe_calloc (ncodes, sizeof (iconv_t)); - score = safe_calloc (ncodes, sizeof (size_t)); - states = safe_calloc (ncodes, sizeof (CONTENT_STATE)); - infos = safe_calloc (ncodes, sizeof (CONTENT)); + cd = p_new(iconv_t, ncodes); + score = p_new(ssize_t, ncodes); + states = p_new(CONTENT_STATE, ncodes); + infos = p_new(CONTENT, ncodes); for (i = 0; i < ncodes; i++) if (ascii_strcasecmp (tocodes[i], "UTF-8")) cd[i] = mutt_iconv_open (tocodes[i], "UTF-8", 0); else /* Special case for conversion to UTF-8 */ - cd[i] = (iconv_t)(-1), score[i] = (size_t)(-1); + cd[i] = (iconv_t) (-1), score[i] = -1; rewind (file); ibl = 0; - for (;;) - { + for (;;) { /* Try to fill input buffer */ n = fread (bufi + ibl, 1, sizeof (bufi) - ibl, file); @@ -722,90 +624,80 @@ static size_t convert_file_to (FILE *file, const char *fromcode, /* Convert to UTF-8 */ ib = bufi; ob = bufu, obl = sizeof (bufu); - n = iconv (cd1, ibl ? &ib : 0, &ibl, &ob, &obl); - assert (n == (size_t)(-1) || !n || ICONV_NONTRANS); - if (n == (size_t)(-1) && - ((errno != EINVAL && errno != E2BIG) || ib == bufi)) - { + n = my_iconv(cd1, ibl ? &ib : 0, &ibl, &ob, &obl); + assert (n == -1 || !n); + if (n == -1 && + ((errno != EINVAL && errno != E2BIG) || ib == bufi)) { assert (errno == EILSEQ || - (errno == EINVAL && ib == bufi && ibl < sizeof (bufi))); - ret = (size_t)(-1); + (errno == EINVAL && ib == bufi && ibl < ssizeof (bufi))); + ret = -1; break; } ubl1 = ob - bufu; /* Convert from UTF-8 */ for (i = 0; i < ncodes; i++) - if (cd[i] != (iconv_t)(-1) && score[i] != (size_t)(-1)) - { - ub = bufu, ubl = ubl1; - ob = bufo, obl = sizeof (bufo); - n = iconv (cd[i], (ibl || ubl) ? &ub : 0, &ubl, &ob, &obl); - if (n == (size_t)(-1)) - { - assert (errno == E2BIG || - (BUGGY_ICONV && (errno == EILSEQ || errno == ENOENT))); - score[i] = (size_t)(-1); - } - else - { - score[i] += n; - update_content_info (&infos[i], &states[i], bufo, ob - bufo); - } + if (cd[i] != (iconv_t) (-1) && score[i] != -1) { + ub = bufu, ubl = ubl1; + ob = bufo, obl = sizeof (bufo); + n = my_iconv(cd[i], (ibl || ubl) ? &ub : 0, &ubl, &ob, &obl); + if (n == -1) { + assert (errno == E2BIG || + (BUGGY_ICONV && (errno == EILSEQ || errno == ENOENT))); + score[i] = -1; + } + else { + score[i] += n; + update_content_info (&infos[i], &states[i], bufo, ob - bufo); + } } - else if (cd[i] == (iconv_t)(-1) && score[i] == (size_t)(-1)) - /* Special case for conversion to UTF-8 */ - update_content_info (&infos[i], &states[i], bufu, ubl1); + else if (cd[i] == (iconv_t) (-1) && score[i] == -1) + /* Special case for conversion to UTF-8 */ + update_content_info (&infos[i], &states[i], bufu, ubl1); if (ibl) /* Save unused input */ memmove (bufi, ib, ibl); - else if (!ubl1 && ib < bufi + sizeof (bufi)) - { + else if (!ubl1 && ib < bufi + sizeof (bufi)) { ret = 0; break; } } - if (!ret) - { + if (!ret) { /* Find best score */ - ret = (size_t)(-1); - for (i = 0; i < ncodes; i++) - { - if (cd[i] == (iconv_t)(-1) && score[i] == (size_t)(-1)) - { - /* Special case for conversion to UTF-8 */ - *tocode = i; - ret = 0; - break; + ret = -1; + for (i = 0; i < ncodes; i++) { + if (cd[i] == (iconv_t) (-1) && score[i] == -1) { + /* Special case for conversion to UTF-8 */ + *tocode = i; + ret = 0; + break; } - else if (cd[i] == (iconv_t)(-1) || score[i] == (size_t)(-1)) - continue; - else if (ret == (size_t)(-1) || score[i] < ret) - { - *tocode = i; - ret = score[i]; - if (!ret) - break; + else if (cd[i] == (iconv_t) (-1) || score[i] == -1) + continue; + else if (ret == -1 || score[i] < ret) { + *tocode = i; + ret = score[i]; + if (!ret) + break; } } - if (ret != (size_t)(-1)) - { - memcpy (info, &infos[*tocode], sizeof(CONTENT)); - update_content_info (info, &states[*tocode], 0, 0); /* EOF */ + if (ret != -1) { + memcpy (info, &infos[*tocode], sizeof (CONTENT)); + update_content_info (info, &states[*tocode], 0, 0); /* EOF */ } } for (i = 0; i < ncodes; i++) - if (cd[i] != (iconv_t)(-1)) + if (cd[i] != (iconv_t) (-1)) iconv_close (cd[i]); iconv_close (cd1); - FREE (&cd); - FREE (&infos); - FREE (&score); - FREE (&states); + p_delete(&cd); + p_delete(&infos); + p_delete(&score); + p_delete(&states); return ret; #else @@ -824,63 +716,57 @@ static size_t convert_file_to (FILE *file, const char *fromcode, * However, if fromcode is zero then fromcodes is assumed to be the * name of a single charset even if it contains a colon. */ -static size_t convert_file_from_to (FILE *file, - const char *fromcodes, const char *tocodes, - char **fromcode, char **tocode, CONTENT *info) +static ssize_t convert_file_from_to (FILE * file, + const char *fromcodes, + const char *tocodes, char **fromcode, + char **tocode, CONTENT * info) { char *fcode; char **tcode; const char *c, *c1; - size_t ret; + ssize_t ret; int ncodes, i, cn; /* Count the tocodes */ ncodes = 0; - for (c = tocodes; c; c = c1 ? c1 + 1 : 0) - { + for (c = tocodes; c; c = c1 ? c1 + 1 : 0) { if ((c1 = strchr (c, ':')) == c) continue; ++ncodes; } /* Copy them */ - tcode = safe_malloc (ncodes * sizeof (char *)); - for (c = tocodes, i = 0; c; c = c1 ? c1 + 1 : 0, i++) - { + tcode = p_new(char *, ncodes); + for (c = tocodes, i = 0; c; c = c1 ? c1 + 1 : 0, i++) { if ((c1 = strchr (c, ':')) == c) continue; - tcode[i] = mutt_substrdup (c, c1); + tcode[i] = m_substrdup(c, c1); } - ret = (size_t)(-1); - if (fromcode) - { + ret = -1; + if (fromcode) { /* Try each fromcode in turn */ - for (c = fromcodes; c; c = c1 ? c1 + 1 : 0) - { + for (c = fromcodes; c; c = c1 ? c1 + 1 : 0) { if ((c1 = strchr (c, ':')) == c) - continue; - fcode = mutt_substrdup (c, c1); - - ret = convert_file_to (file, fcode, ncodes, (const char **)tcode, - &cn, info); - if (ret != (size_t)(-1)) - { - *fromcode = fcode; - *tocode = tcode[cn]; - tcode[cn] = 0; - break; + continue; + fcode = m_substrdup(c, c1); + + ret = convert_file_to (file, fcode, ncodes, (const char **) tcode, + &cn, info); + if (ret != -1) { + *fromcode = fcode; + *tocode = tcode[cn]; + tcode[cn] = 0; + break; } - FREE (&fcode); + p_delete(&fcode); } } - else - { + else { /* There is only one fromcode */ - ret = convert_file_to (file, fromcodes, ncodes, (const char **)tcode, - &cn, info); - if (ret != (size_t)(-1)) - { + ret = convert_file_to (file, fromcodes, ncodes, (const char **) tcode, + &cn, info); + if (ret != -1) { *tocode = tcode[cn]; tcode[cn] = 0; } @@ -888,10 +774,10 @@ static size_t convert_file_from_to (FILE *file, /* Free memory */ for (i = 0; i < ncodes; i++) - FREE (&tcode[i]); + p_delete(&tcode[i]); + + p_delete(tcode); - FREE (tcode); - return ret; } @@ -899,71 +785,69 @@ static size_t convert_file_from_to (FILE *file, * Analyze the contents of a file to determine which MIME encoding to use. * Also set the body charset, sometimes, or not. */ -CONTENT *mutt_get_content_info (const char *fname, BODY *b) +CONTENT *mutt_get_content_info (const char *fname, BODY * b) { CONTENT *info; CONTENT_STATE state; FILE *fp = NULL; - char *tocode; + char *fromcode = NULL; + char *tocode = NULL; char buffer[100]; char chsbuf[STRING]; - size_t r; + ssize_t r; struct stat sb; - - if(b && !fname) fname = b->filename; - if (stat (fname, &sb) == -1) - { + if (b && !fname) + fname = b->filename; + + if (stat (fname, &sb) == -1) { mutt_error (_("Can't stat %s: %s"), fname, strerror (errno)); return NULL; } - - if (!S_ISREG(sb.st_mode)) - { + + if (!S_ISREG (sb.st_mode)) { mutt_error (_("%s isn't a regular file."), fname); return NULL; } - - if ((fp = fopen (fname, "r")) == NULL) - { - dprint (1, (debugfile, "mutt_get_content_info: %s: %s (errno %d).\n", - fname, strerror (errno), errno)); + + if ((fp = fopen (fname, "r")) == NULL) { return (NULL); } - info = safe_calloc (1, sizeof (CONTENT)); - memset (&state, 0, sizeof (state)); - - if (b != NULL && b->type == TYPETEXT && (!b->noconv && !b->force_charset)) - { + info = p_new(CONTENT, 1); + p_clear(&state, 1); + + if (b != NULL && b->type == TYPETEXT && (!b->noconv && !b->force_charset)) { char *chs = mutt_get_parameter ("charset", b->parameter); + char *fchs = b->use_disp ? ((FileCharset && *FileCharset) ? + FileCharset : Charset) : Charset; if (Charset && (chs || SendCharset) && - convert_file_from_to (fp, Charset, chs ? chs : SendCharset, - 0, &tocode, info) != (size_t)(-1)) - { - if (!chs) - { - mutt_canonical_charset (chsbuf, sizeof (chsbuf), tocode); - mutt_set_parameter ("charset", chsbuf, &b->parameter); + convert_file_from_to (fp, fchs, chs ? chs : SendCharset, + &fromcode, &tocode, info) != -1) { + if (!chs) { + charset_canonicalize (chsbuf, sizeof (chsbuf), tocode); + mutt_set_parameter ("charset", chsbuf, &b->parameter); } - FREE (&tocode); + b->file_charset = fromcode; + p_delete(&tocode); safe_fclose (&fp); return info; } } rewind (fp); - while ((r = fread (buffer, 1, sizeof(buffer), fp))) + while ((r = fread (buffer, 1, sizeof (buffer), fp))) update_content_info (info, &state, buffer, r); update_content_info (info, &state, 0, 0); safe_fclose (&fp); - + if (b != NULL && b->type == TYPETEXT && (!b->noconv && !b->force_charset)) mutt_set_parameter ("charset", (!info->hibin ? "us-ascii" : - Charset && !mutt_is_us_ascii (Charset) ? Charset : "unknown-8bit"), - &b->parameter); + Charset + && !charset_is_us_ascii (Charset) ? Charset : + "unknown-8bit"), &b->parameter); return info; } @@ -975,7 +859,7 @@ CONTENT *mutt_get_content_info (const char *fname, BODY *b) * exists. */ -int mutt_lookup_mime_type (BODY *att, const char *path) +int mutt_lookup_mime_type (BODY * att, const char *path) { FILE *f; char *p, *q, *ct; @@ -986,99 +870,93 @@ int mutt_lookup_mime_type (BODY *att, const char *path) int type; *subtype = '\0'; - *xtype = '\0'; - type = TYPEOTHER; - cur_sze = 0; + *xtype = '\0'; + type = TYPEOTHER; + cur_sze = 0; - szf = mutt_strlen (path); + szf = m_strlen(path); - for (count = 0 ; count < 3 ; count++) - { + for (count = 0; count < 4; count++) { /* * can't use strtok() because we use it in an inner loop below, so use * a switch statement here instead. */ - switch (count) - { - case 0: - snprintf (buf, sizeof (buf), "%s/.mime.types", NONULL(Homedir)); - break; - case 1: - strfcpy (buf, SYSCONFDIR"/mime.types", sizeof(buf)); - break; - case 2: - strfcpy (buf, PKGDATADIR"/mime.types", sizeof (buf)); - break; - default: - dprint (1, (debugfile, "mutt_lookup_mime_type: Internal error, count = %d.\n", count)); - goto bye; /* shouldn't happen */ - } - - if ((f = fopen (buf, "r")) != NULL) - { - while (fgets (buf, sizeof (buf) - 1, f) != NULL) - { - /* weed out any comments */ - if ((p = strchr (buf, '#'))) - *p = 0; - - /* remove any leading space. */ - ct = buf; - SKIPWS (ct); - - /* position on the next field in this line */ - if ((p = strpbrk (ct, " \t")) == NULL) - continue; - *p++ = 0; - SKIPWS (p); - - /* cycle through the file extensions */ - while ((p = strtok (p, " \t\n"))) - { - sze = mutt_strlen (p); - if ((sze > cur_sze) && (szf >= sze) && - (mutt_strcasecmp (path + szf - sze, p) == 0 || ascii_strcasecmp (path + szf - sze, p) == 0) && - (szf == sze || path[szf - sze - 1] == '.')) - { - /* get the content-type */ - - if ((p = strchr (ct, '/')) == NULL) - { - /* malformed line, just skip it. */ - break; - } - *p++ = 0; - - for (q = p; *q && !ISSPACE (*q); q++) - ; - - mutt_substrcpy (subtype, p, q, sizeof (subtype)); - - if ((type = mutt_check_mime_type (ct)) == TYPEOTHER) - strfcpy (xtype, ct, sizeof (xtype)); - - cur_sze = sze; - } - p = NULL; - } + switch (count) { + case 0: + snprintf (buf, sizeof (buf), "%s/.mime.types", NONULL (Homedir)); + break; + case 1: + m_strcpy(buf, sizeof(buf), SYSCONFDIR "/madmutt-mime.types"); + break; + case 2: + m_strcpy(buf, sizeof(buf), PKGDATADIR "/mime.types"); + break; + case 3: + m_strcpy(buf, sizeof(buf), SYSCONFDIR "/mime.types"); + break; + default: + goto bye; /* shouldn't happen */ + } + + if ((f = fopen (buf, "r")) != NULL) { + while (fgets (buf, sizeof (buf) - 1, f) != NULL) { + /* weed out any comments */ + if ((p = strchr (buf, '#'))) + *p = 0; + + /* remove any leading space. */ + ct = vskipspaces(buf); + + /* position on the next field in this line */ + if ((p = strpbrk (ct, " \t")) == NULL) + continue; + *p++ = 0; + p = vskipspaces(p); + + /* cycle through the file extensions */ + while ((p = strtok (p, " \t\n"))) { + sze = m_strlen(p); + if ((sze > cur_sze) && (szf >= sze) && + (m_strcasecmp(path + szf - sze, p) == 0 + || ascii_strcasecmp (path + szf - sze, p) == 0) + && (szf == sze || path[szf - sze - 1] == '.')) + { + /* get the content-type */ + + if ((p = strchr (ct, '/')) == NULL) { + /* malformed line, just skip it. */ + break; + } + *p++ = 0; + + for (q = p; *q && !ISSPACE (*q); q++); + + m_strncpy(subtype, sizeof(subtype), p, q - p); + + if ((type = mutt_check_mime_type (ct)) == TYPEOTHER) + m_strcpy(xtype, sizeof(xtype), ct); + + cur_sze = sze; + } + p = NULL; + } } fclose (f); } } - - bye: - if (type != TYPEOTHER || *xtype != '\0') - { +bye: + + if (type != TYPEOTHER || *xtype != '\0') { att->type = type; - mutt_str_replace (&att->subtype, subtype); - mutt_str_replace (&att->xtype, xtype); + m_strreplace(&att->subtype, subtype); + m_strreplace(&att->xtype, xtype); } - + return (type); } -void mutt_message_to_7bit (BODY *a, FILE *fp) +void mutt_message_to_7bit (BODY * a, FILE * fp) { char temp[_POSIX_PATH_MAX]; char *line = NULL; @@ -1088,16 +966,13 @@ void mutt_message_to_7bit (BODY *a, FILE *fp) if (!a->filename && fp) fpin = fp; - else if (!a->filename || !(fpin = fopen (a->filename, "r"))) - { + else if (!a->filename || !(fpin = fopen (a->filename, "r"))) { mutt_error (_("Could not open %s"), a->filename ? a->filename : "(null)"); return; - } - else - { + } + else { a->offset = 0; - if (stat (a->filename, &sb) == -1) - { + if (stat (a->filename, &sb) == -1) { mutt_perror ("stat"); fclose (fpin); } @@ -1105,27 +980,26 @@ void mutt_message_to_7bit (BODY *a, FILE *fp) } mutt_mktemp (temp); - if (!(fpout = safe_fopen (temp, "w+"))) - { + if (!(fpout = safe_fopen (temp, "w+"))) { mutt_perror ("fopen"); goto cleanup; } - fseek (fpin, a->offset, 0); + fseeko (fpin, a->offset, 0); a->parts = mutt_parse_messageRFC822 (fpin, a); transform_to_7bit (a->parts, fpin); - - mutt_copy_hdr (fpin, fpout, a->offset, a->offset + a->length, - CH_MIME | CH_NONEWLINE | CH_XMIT, NULL); - fputs ("Mime-Version: 1.0\n", fpout); + mutt_copy_hdr (fpin, fpout, a->offset, a->offset + a->length, + CH_MIME | CH_NONEWLINE | CH_XMIT, NULL); + + fputs ("MIME-Version: 1.0\n", fpout); mutt_write_mime_header (a->parts, fpout); fputc ('\n', fpout); mutt_write_mime_body (a->parts, fpout); - - cleanup: - FREE (&line); + +cleanup: + p_delete(&line); if (fpin && !fp) fclose (fpin); @@ -1133,15 +1007,14 @@ void mutt_message_to_7bit (BODY *a, FILE *fp) fclose (fpout); else return; - + a->encoding = ENC7BIT; a->d_filename = a->filename; if (a->filename && a->unlink) unlink (a->filename); - a->filename = safe_strdup (temp); + a->filename = m_strdup(temp); a->unlink = 1; - if(stat (a->filename, &sb) == -1) - { + if (stat (a->filename, &sb) == -1) { mutt_perror ("stat"); return; } @@ -1150,94 +1023,91 @@ void mutt_message_to_7bit (BODY *a, FILE *fp) a->hdr->content = NULL; } -static void transform_to_7bit (BODY *a, FILE *fpin) +static void transform_to_7bit (BODY * a, FILE * fpin) { char buff[_POSIX_PATH_MAX]; STATE s; struct stat sb; - memset (&s, 0, sizeof (s)); - for (; a; a = a->next) - { - if (a->type == TYPEMULTIPART) - { + p_clear(&s, 1); + for (; a; a = a->next) { + if (a->type == TYPEMULTIPART) { if (a->encoding != ENC7BIT) - a->encoding = ENC7BIT; + a->encoding = ENC7BIT; transform_to_7bit (a->parts, fpin); - } - else if (mutt_is_message_type(a->type, a->subtype)) - { + } + else if (mutt_is_message_type (a->type, a->subtype)) { mutt_message_to_7bit (a, fpin); } - else - { + else { + a->noconv = 1; + a->force_charset = 1; + mutt_mktemp (buff); - if ((s.fpout = safe_fopen (buff, "w")) == NULL) - { - mutt_perror ("fopen"); - return; + if ((s.fpout = safe_fopen (buff, "w")) == NULL) { + mutt_perror ("fopen"); + return; } s.fpin = fpin; mutt_decode_attachment (a, &s); fclose (s.fpout); a->d_filename = a->filename; - a->filename = safe_strdup (buff); + a->filename = m_strdup(buff); a->unlink = 1; - if (stat (a->filename, &sb) == -1) - { - mutt_perror ("stat"); - return; + if (stat (a->filename, &sb) == -1) { + mutt_perror ("stat"); + return; } a->length = sb.st_size; mutt_update_encoding (a); if (a->encoding == ENC8BIT) - a->encoding = ENCQUOTEDPRINTABLE; - else if(a->encoding == ENCBINARY) - a->encoding = ENCBASE64; + a->encoding = ENCQUOTEDPRINTABLE; + else if (a->encoding == ENCBINARY) + a->encoding = ENCBASE64; } } } /* determine which Content-Transfer-Encoding to use */ -static void mutt_set_encoding (BODY *b, CONTENT *info) +static void mutt_set_encoding (BODY * b, CONTENT * info) { char send_charset[SHORT_STRING]; - if (b->type == TYPETEXT) - { - char *chsname = mutt_get_body_charset (send_charset, sizeof (send_charset), b); - if ((info->lobin && ascii_strncasecmp (chsname, "iso-2022", 8)) || info->linemax > 990 || (info->from && option (OPTENCODEFROM))) + if (b->type == TYPETEXT) { + char *chsname = + mutt_get_body_charset (send_charset, sizeof (send_charset), b); + if ((info->lobin && ascii_strncasecmp (chsname, "iso-2022", 8)) + || info->linemax > 990 || (info->from && option (OPTENCODEFROM))) b->encoding = ENCQUOTEDPRINTABLE; else if (info->hibin) b->encoding = option (OPTALLOW8BIT) ? ENC8BIT : ENCQUOTEDPRINTABLE; else b->encoding = ENC7BIT; } - else if (b->type == TYPEMESSAGE || b->type == TYPEMULTIPART) - { - if (info->lobin || info->hibin) - { + else if (b->type == TYPEMESSAGE || b->type == TYPEMULTIPART) { + if (info->lobin || info->hibin) { if (option (OPTALLOW8BIT) && !info->lobin) - b->encoding = ENC8BIT; + b->encoding = ENC8BIT; else - mutt_message_to_7bit (b, NULL); + mutt_message_to_7bit (b, NULL); } else b->encoding = ENC7BIT; } - else if (b->type == TYPEAPPLICATION && ascii_strcasecmp (b->subtype, "pgp-keys") == 0) + else if (b->type == TYPEAPPLICATION + && ascii_strcasecmp (b->subtype, "pgp-keys") == 0) b->encoding = ENC7BIT; else #if 0 - if (info->lobin || info->hibin || info->binary || info->linemax > 990 - || info->cr || (/* option (OPTENCODEFROM) && */ info->from)) + if (info->lobin || info->hibin || info->binary || info->linemax > 990 + || info->cr || ( /* option (OPTENCODEFROM) && */ info->from)) #endif { /* Determine which encoding is smaller */ - if (1.33 * (float)(info->lobin+info->hibin+info->ascii) < - 3.0 * (float)(info->lobin + info->hibin) + (float)info->ascii) + if (1.33 * (float) (info->lobin + info->hibin + info->ascii) < + 3.0 * (float) (info->lobin + info->hibin) + (float) info->ascii) b->encoding = ENCBASE64; else b->encoding = ENCQUOTEDPRINTABLE; @@ -1248,40 +1118,40 @@ static void mutt_set_encoding (BODY *b, CONTENT *info) #endif } -void mutt_stamp_attachment(BODY *a) +void mutt_stamp_attachment (BODY * a) { - a->stamp = time(NULL); + a->stamp = time (NULL); } /* Get a body's character set */ -char *mutt_get_body_charset (char *d, size_t dlen, BODY *b) +char *mutt_get_body_charset (char *d, ssize_t dlen, BODY * b) { char *p = NULL; if (b && b->type != TYPETEXT) return NULL; - if (b) + if (b) p = mutt_get_parameter ("charset", b->parameter); if (p) - mutt_canonical_charset (d, dlen, NONULL(p)); + charset_canonicalize (d, dlen, NONULL (p)); else - strfcpy (d, "us-ascii", dlen); + m_strcpy(d, dlen, "us-ascii"); return d; } /* Assumes called from send mode where BODY->filename points to actual file */ -void mutt_update_encoding (BODY *a) +void mutt_update_encoding (BODY * a) { CONTENT *info; char chsbuff[STRING]; /* override noconv when it's us-ascii */ - if (mutt_is_us_ascii (mutt_get_body_charset (chsbuff, sizeof (chsbuff), a))) + if (charset_is_us_ascii (mutt_get_body_charset (chsbuff, sizeof (chsbuff), a))) a->noconv = 0; if (!a->force_charset && !a->noconv) @@ -1291,28 +1161,25 @@ void mutt_update_encoding (BODY *a) return; mutt_set_encoding (a, info); - mutt_stamp_attachment(a); + mutt_stamp_attachment (a); - FREE (&a->content); + p_delete(&a->content); a->content = info; } -BODY *mutt_make_message_attach (CONTEXT *ctx, HEADER *hdr, int attach_msg) +BODY *mutt_make_message_attach (CONTEXT * ctx, HEADER * hdr, int attach_msg) { char buffer[LONG_STRING]; BODY *body; FILE *fp; int cmflags, chflags; - int pgp = WithCrypto? hdr->security : 0; + int pgp = hdr->security; - if (WithCrypto) - { - if ((option(OPTMIMEFORWDECODE) || option(OPTFORWDECRYPT)) && - (hdr->security & ENCRYPT)) { - if (!crypt_valid_passphrase(hdr->security)) - return (NULL); - } + if ((option (OPTMIMEFORWDECODE) || option (OPTFORWDECRYPT)) && + (hdr->security & ENCRYPT)) { + if (!crypt_valid_passphrase (hdr->security)) + return (NULL); } mutt_mktemp (buffer); @@ -1321,11 +1188,12 @@ BODY *mutt_make_message_attach (CONTEXT *ctx, HEADER *hdr, int attach_msg) body = mutt_new_body (); body->type = TYPEMESSAGE; - body->subtype = safe_strdup ("rfc822"); - body->filename = safe_strdup (buffer); + body->subtype = m_strdup("rfc822"); + body->filename = m_strdup(buffer); body->unlink = 1; body->use_disp = 0; body->disposition = DISPINLINE; + body->noconv = 1; mutt_parse_mime_message (ctx, hdr); @@ -1333,35 +1201,23 @@ BODY *mutt_make_message_attach (CONTEXT *ctx, HEADER *hdr, int attach_msg) cmflags = 0; /* If we are attaching a message, ignore OPTMIMEFORWDECODE */ - if (!attach_msg && option (OPTMIMEFORWDECODE)) - { + if (!attach_msg && option (OPTMIMEFORWDECODE)) { chflags |= CH_MIME | CH_TXTPLAIN; cmflags = M_CM_DECODE | M_CM_CHARCONV; - if ((WithCrypto & APPLICATION_PGP)) - pgp &= ~PGPENCRYPT; - if ((WithCrypto & APPLICATION_SMIME)) - pgp &= ~SMIMEENCRYPT; + pgp &= ~(PGPENCRYPT|SMIMEENCRYPT); } - else if (WithCrypto - && option (OPTFORWDECRYPT) && (hdr->security & ENCRYPT)) - { - if ((WithCrypto & APPLICATION_PGP) - && mutt_is_multipart_encrypted (hdr->content)) - { + else if (option (OPTFORWDECRYPT) && (hdr->security & ENCRYPT)) { + if (mutt_is_multipart_encrypted (hdr->content)) { chflags |= CH_MIME | CH_NONEWLINE; cmflags = M_CM_DECODE_PGP; pgp &= ~PGPENCRYPT; } - else if ((WithCrypto & APPLICATION_PGP) - && (mutt_is_application_pgp (hdr->content) & PGPENCRYPT)) - { + else if (mutt_is_application_pgp (hdr->content) & PGPENCRYPT) { chflags |= CH_MIME | CH_TXTPLAIN; cmflags = M_CM_DECODE | M_CM_CHARCONV; pgp &= ~PGPENCRYPT; } - else if ((WithCrypto & APPLICATION_SMIME) - && mutt_is_application_smime (hdr->content) & SMIMEENCRYPT) - { + else if (mutt_is_application_smime (hdr->content) & SMIMEENCRYPT) { chflags |= CH_MIME | CH_TXTPLAIN; cmflags = M_CM_DECODE | M_CM_CHARCONV; pgp &= ~SMIMEENCRYPT; @@ -1369,21 +1225,20 @@ BODY *mutt_make_message_attach (CONTEXT *ctx, HEADER *hdr, int attach_msg) } mutt_copy_message (fp, ctx, hdr, cmflags, chflags); - - fflush(fp); - rewind(fp); - body->hdr = mutt_new_header(); + fflush (fp); + rewind (fp); + + body->hdr = header_new(); body->hdr->offset = 0; /* we don't need the user headers here */ - body->hdr->env = mutt_read_rfc822_header(fp, body->hdr, 0, 0); - if (WithCrypto) - body->hdr->security = pgp; + body->hdr->env = mutt_read_rfc822_header (fp, body->hdr, 0, 0); + body->hdr->security = pgp; mutt_update_encoding (body); body->parts = body->hdr->content; - fclose(fp); - + fclose (fp); + return (body); } @@ -1393,62 +1248,58 @@ BODY *mutt_make_file_attach (const char *path) CONTENT *info; att = mutt_new_body (); - att->filename = safe_strdup (path); + att->filename = m_strdup(path); /* Attempt to determine the appropriate content-type based on the filename * suffix. */ #if 0 - - if ((n = mutt_lookup_mime_type (buf, sizeof (buf), xbuf, sizeof (xbuf), path)) != TYPEOTHER - || *xbuf != '\0') - { + + if ((n = + mutt_lookup_mime_type (buf, sizeof (buf), xbuf, sizeof (xbuf), + path)) != TYPEOTHER || *xbuf != '\0') { att->type = n; - att->subtype = safe_strdup (buf); - att->xtype = safe_strdup (xbuf); + att->subtype = m_strdup(buf); + att->xtype = m_strdup(xbuf); } #else - + mutt_lookup_mime_type (att, path); #endif - - if ((info = mutt_get_content_info (path, att)) == NULL) - { + + if ((info = mutt_get_content_info (path, att)) == NULL) { mutt_free_body (&att); return NULL; } - if (!att->subtype) - { - if (info->lobin == 0 || (info->lobin + info->hibin + info->ascii)/ info->lobin >= 10) - { + if (!att->subtype) { + if (info->lobin == 0 + || (info->lobin + info->hibin + info->ascii) / info->lobin >= 10) { /* * Statistically speaking, there should be more than 10% "lobin" * chars if this is really a binary file... */ att->type = TYPETEXT; - att->subtype = safe_strdup ("plain"); + att->subtype = m_strdup("plain"); } - else - { + else { att->type = TYPEAPPLICATION; - att->subtype = safe_strdup ("octet-stream"); + att->subtype = m_strdup("octet-stream"); } - } + } mutt_update_encoding (att); return (att); } -static int get_toplevel_encoding (BODY *a) +static int get_toplevel_encoding (BODY * a) { int e = ENC7BIT; - for (; a; a = a->next) - { + for (; a; a = a->next) { if (a->encoding == ENCBINARY) return (ENCBINARY); else if (a->encoding == ENC8BIT) @@ -1458,16 +1309,16 @@ static int get_toplevel_encoding (BODY *a) return (e); } -BODY *mutt_make_multipart (BODY *b) +BODY *mutt_make_multipart (BODY * b) { BODY *new; new = mutt_new_body (); new->type = TYPEMULTIPART; - new->subtype = safe_strdup ("mixed"); + new->subtype = m_strdup("mixed"); new->encoding = get_toplevel_encoding (b); mutt_generate_boundary (&new->parameter); - new->use_disp = 0; + new->use_disp = 0; new->disposition = DISPINLINE; new->parts = b; @@ -1475,12 +1326,11 @@ BODY *mutt_make_multipart (BODY *b) } /* remove the multipart body if it exists */ -BODY *mutt_remove_multipart (BODY *b) +BODY *mutt_remove_multipart (BODY * b) { BODY *t; - if (b->parts) - { + if (b->parts) { t = b; b = b->parts; t->parts = NULL; @@ -1489,7 +1339,7 @@ BODY *mutt_remove_multipart (BODY *b) return b; } -char *mutt_make_date (char *s, size_t len) +char *mutt_make_date (char *s, ssize_t len) { time_t t = time (NULL); struct tm *l = localtime (&t); @@ -1497,47 +1347,43 @@ char *mutt_make_date (char *s, size_t len) tz /= 60; - snprintf (s, len, "Date: %s, %d %s %d %02d:%02d:%02d %+03d%02d\n", - Weekdays[l->tm_wday], l->tm_mday, Months[l->tm_mon], - l->tm_year + 1900, l->tm_hour, l->tm_min, l->tm_sec, - (int) tz / 60, (int) abs (tz) % 60); + snprintf (s, len, "Date: %s, %d %s %d %02d:%02d:%02d %+03d%02d\n", + Weekdays[l->tm_wday], l->tm_mday, Months[l->tm_mon], + l->tm_year + 1900, l->tm_hour, l->tm_min, l->tm_sec, + (int) tz / 60, (int) abs (tz) % 60); return (s); } /* wrapper around mutt_write_address() so we can handle very large recipient lists without needing a huge temporary buffer in memory */ -void mutt_write_address_list (ADDRESS *adr, FILE *fp, int linelen, int display) +void mutt_write_address_list (address_t * adr, FILE * fp, int linelen, + int display) { - ADDRESS *tmp; + address_t *tmp; char buf[LONG_STRING]; int count = 0; int len; - while (adr) - { + while (adr) { tmp = adr->next; adr->next = NULL; buf[0] = 0; rfc822_write_address (buf, sizeof (buf), adr, display); - len = mutt_strlen (buf); - if (count && linelen + len > 74) - { + len = m_strlen(buf); + if (count && linelen + len > 74) { fputs ("\n\t", fp); - linelen = len + 8; /* tab is usually about 8 spaces... */ + linelen = len + 8; /* tab is usually about 8 spaces... */ } - else - { - if (count && adr->mailbox) - { - fputc (' ', fp); - linelen++; + else { + if (count && adr->mailbox) { + fputc (' ', fp); + linelen++; } linelen += len; } fputs (buf, fp); adr->next = tmp; - if (!adr->group && adr->next && adr->next->mailbox) - { + if (!adr->group && adr->next && adr->next->mailbox) { linelen++; fputc (',', fp); } @@ -1555,25 +1401,23 @@ void mutt_write_address_list (ADDRESS *adr, FILE *fp, int linelen, int display) /* need to write the list in reverse because they are stored in reverse order * when parsed to speed up threading */ -void mutt_write_references (LIST *r, FILE *f) +void mutt_write_references (string_list_t * r, FILE * f) { - LIST **ref = NULL; + string_list_t **ref = NULL; int refcnt = 0, refmax = 0; - for ( ; (TrimRef == 0 || refcnt < TrimRef) && r ; r = r->next) - { + for (; (TrimRef == 0 || refcnt < TrimRef) && r; r = r->next) { if (refcnt == refmax) - safe_realloc (&ref, (refmax += REF_INC) * sizeof (LIST *)); + p_realloc(&ref, refmax += REF_INC); ref[refcnt++] = r; } - while (refcnt-- > 0) - { + while (refcnt-- > 0) { fputc (' ', f); fputs (ref[refcnt]->data, f); } - FREE (&ref); + p_delete(&ref); } /* Note: all RFC2047 encoding should be done outside of this routine, except @@ -1592,144 +1436,142 @@ void mutt_write_references (LIST *r, FILE *f) * */ -int mutt_write_rfc822_header (FILE *fp, ENVELOPE *env, BODY *attach, - int mode, int privacy) +int mutt_write_rfc822_header (FILE * fp, ENVELOPE * env, BODY * attach, + int mode, int privacy) { char buffer[LONG_STRING]; char *p; - LIST *tmp = env->userhdrs; - int has_agent = 0; /* user defined user-agent header field exists */ - + string_list_t *tmp = env->userhdrs; + int has_agent = 0; /* user defined user-agent header field exists */ + list2_t* hdrs = list_from_str (EditorHeaders, " "); + #ifdef USE_NNTP if (!option (OPTNEWSSEND)) #endif - if (mode == 0 && !privacy) - fputs (mutt_make_date (buffer, sizeof(buffer)), fp); + if (mode == 0 && !privacy) + fputs (mutt_make_date (buffer, sizeof (buffer)), fp); + +#define EDIT_HEADER(x) (mode != 1 || option(OPTXMAILTO) || (mode == 1 && list_lookup(hdrs,(list_lookup_t*) ascii_strcasecmp,x) >= 0)) /* OPTUSEFROM is not consulted here so that we can still write a From: * field if the user sets it with the `my_hdr' command */ - if (env->from && !privacy) - { + if (env->from && !privacy) { buffer[0] = 0; rfc822_write_address (buffer, sizeof (buffer), env->from, 0); fprintf (fp, "From: %s\n", buffer); } - if (env->to) - { + if (env->to) { fputs ("To: ", fp); mutt_write_address_list (env->to, fp, 4, 0); } else if (mode > 0) #ifdef USE_NNTP - if (!option (OPTNEWSSEND)) + if (!option (OPTNEWSSEND)) #endif - fputs ("To: \n", fp); + if (EDIT_HEADER("To:")) + fputs ("To:\n", fp); - if (env->cc) - { + if (env->cc) { fputs ("Cc: ", fp); mutt_write_address_list (env->cc, fp, 4, 0); } else if (mode > 0) #ifdef USE_NNTP - if (!option (OPTNEWSSEND)) + if (!option (OPTNEWSSEND)) #endif - fputs ("Cc: \n", fp); + if (EDIT_HEADER("Cc:")) + fputs ("Cc:\n", fp); - if (env->bcc) - { - if(mode != 0 || option(OPTWRITEBCC)) - { + if (env->bcc) { + if (mode != 0 || option (OPTWRITEBCC)) { fputs ("Bcc: ", fp); mutt_write_address_list (env->bcc, fp, 5, 0); } } else if (mode > 0) #ifdef USE_NNTP - if (!option (OPTNEWSSEND)) + if (!option (OPTNEWSSEND)) #endif - fputs ("Bcc: \n", fp); + if (EDIT_HEADER("Bcc:")) + fputs ("Bcc:\n", fp); #ifdef USE_NNTP if (env->newsgroups) fprintf (fp, "Newsgroups: %s\n", env->newsgroups); - else if (mode == 1 && option (OPTNEWSSEND)) - fputs ("Newsgroups: \n", fp); + else if (mode == 1 && option (OPTNEWSSEND) && EDIT_HEADER("Newsgroups:")) + fputs ("Newsgroups:\n", fp); if (env->followup_to) fprintf (fp, "Followup-To: %s\n", env->followup_to); - else if (mode == 1 && option (OPTNEWSSEND)) - fputs ("Followup-To: \n", fp); + else if (mode == 1 && option (OPTNEWSSEND) && EDIT_HEADER("Followup-To:")) + fputs ("Followup-To:\n", fp); if (env->x_comment_to) fprintf (fp, "X-Comment-To: %s\n", env->x_comment_to); - else if (mode == 1 && option (OPTNEWSSEND) && option (OPTXCOMMENTTO)) - fputs ("X-Comment-To: \n", fp); + else if (mode == 1 && option (OPTNEWSSEND) && option (OPTXCOMMENTTO) && + EDIT_HEADER("X-Comment-To:")) + fputs ("X-Comment-To:\n", fp); #endif if (env->subject) fprintf (fp, "Subject: %s\n", env->subject); - else if (mode == 1) - fputs ("Subject: \n", fp); + else if (mode == 1 && EDIT_HEADER("Subject:")) + fputs ("Subject:\n", fp); /* save message id if the user has set it */ if (env->message_id && !privacy) fprintf (fp, "Message-ID: %s\n", env->message_id); - if (env->reply_to) - { + if (env->reply_to) { fputs ("Reply-To: ", fp); mutt_write_address_list (env->reply_to, fp, 10, 0); } - else if (mode > 0) - fputs ("Reply-To: \n", fp); + else if (mode > 0 && EDIT_HEADER("Reply-To:")) + fputs ("Reply-To:\n", fp); if (env->mail_followup_to) #ifdef USE_NNTP - if (!option (OPTNEWSSEND)) + if (!option (OPTNEWSSEND)) #endif - { - fputs ("Mail-Followup-To: ", fp); - mutt_write_address_list (env->mail_followup_to, fp, 18, 0); - } - - if (mode <= 0) - { - if (env->references) { + fputs ("Mail-Followup-To: ", fp); + mutt_write_address_list (env->mail_followup_to, fp, 18, 0); + } + + if (mode <= 0) { + if (env->references) { fputs ("References:", fp); mutt_write_references (env->references, fp); - fputc('\n', fp); + fputc ('\n', fp); } /* Add the MIME headers */ - fputs ("Mime-Version: 1.0\n", fp); + fputs ("MIME-Version: 1.0\n", fp); mutt_write_mime_header (attach, fp); } - if (env->in_reply_to) - { + if (env->in_reply_to) { fputs ("In-Reply-To:", fp); mutt_write_references (env->in_reply_to, fp); fputc ('\n', fp); } - + +#undef EDIT_HEADER + /* Add any user defined headers */ - for (; tmp; tmp = tmp->next) - { - if ((p = strchr (tmp->data, ':'))) - { - p++; SKIPWS (p); - if (!*p) continue; /* don't emit empty fields. */ + for (; tmp; tmp = tmp->next) { + if ((p = strchr (tmp->data, ':'))) { + p = vskipspaces(p + 1); + if (!*p) + continue; /* don't emit empty fields. */ /* check to see if the user has overridden the user-agent field */ - if (!ascii_strncasecmp ("user-agent", tmp->data, 10)) - { - has_agent = 1; - if (privacy) - continue; + if (!ascii_strncasecmp ("user-agent", tmp->data, 10)) { + has_agent = 1; + if (privacy) + continue; } fputs (tmp->data, fp); @@ -1737,104 +1579,183 @@ int mutt_write_rfc822_header (FILE *fp, ENVELOPE *env, BODY *attach, } } - /* Add X-Face headers */ - if (env->x_face) - { - LIST *face; - - for (face = env->x_face; face; face = face->next) - fprintf (fp, "X-Face: %s\n", face->data); - } + if (mode == 0 && !privacy && option (OPTXMAILER) && !has_agent) { + const char *os; - if (mode == 0 && !privacy && option (OPTXMAILER) && !has_agent) - { - struct utsname un; - char * os; - if (OperatingSystem!=NULL) { + if (OperatingSystem != NULL) { os = OperatingSystem; } else { - if (uname(&un)==-1) { - os = "UNIX"; - } else { - os = un.sysname; - } + struct utsname un; + os = (uname(&un) == -1) ? "UNIX" : un.sysname; } /* Add a vanity header */ - fprintf (fp, "User-Agent: mutt-ng %s (%s)\n", MUTT_VERSION,os); + fprintf (fp, "User-Agent: %s (%s)\n", mutt_make_version (0), os); } + list_del (&hdrs, (list_del_t*)xmemfree); + return (ferror (fp) == 0 ? 0 : -1); } -static void encode_headers (LIST *h) +static void encode_headers (string_list_t * h) { char *tmp; char *p; int i; - - for (; h; h = h->next) - { + + for (; h; h = h->next) { if (!(p = strchr (h->data, ':'))) continue; i = p - h->data; - ++p; SKIPWS (p); - tmp = safe_strdup (p); + p = vskipspaces(p + 1); + tmp = m_strdup(p); if (!tmp) continue; - + rfc2047_encode_string (&tmp); - safe_realloc (&h->data, mutt_strlen (h->data) + 2 + mutt_strlen (tmp) + 1); + p_realloc(&h->data, m_strlen(h->data) + 2 + m_strlen(tmp) + 1); + + sprintf (h->data + i, ": %s", NONULL (tmp)); /* __SPRINTF_CHECKED__ */ - sprintf (h->data + i, ": %s", NONULL (tmp)); /* __SPRINTF_CHECKED__ */ - - FREE (&tmp); + p_delete(&tmp); } } -const char *mutt_fqdn(short may_hide_host) +const char *mutt_fqdn (short may_hide_host) { char *p = NULL, *q; - - if(Fqdn && Fqdn[0] != '@') - { + + if (Fqdn && Fqdn[0] != '@') { p = Fqdn; - - if(may_hide_host && option(OPTHIDDENHOST)) - { - if((p = strchr(Fqdn, '.'))) - p++; + + if (may_hide_host && option (OPTHIDDENHOST)) { + if ((p = strchr (Fqdn, '.'))) + p++; /* sanity check: don't hide the host if * the fqdn is something like detebe.org. */ - - if(!p || !(q = strchr(p, '.'))) - p = Fqdn; + + if (!p || !(q = strchr (p, '.'))) + p = Fqdn; } } return p; } +/* normalized character (we're stricter than RFC2822, 3.6.4) */ +static char mutt_normalized_char(char c) +{ + return (isalnum(c) || strchr(".!#$%&'*+-/=?^_`{|}~", c)) ? c : '.'; +} + +static void mutt_gen_localpart(char *buf, unsigned int len, const char *fmt) +{ +#define APPEND_FMT(fmt, arg) \ + if (len > 1) { \ + int snlen = snprintf(buf, len, fmt, arg); \ + buf += snlen; \ + len -= snlen; \ + } + +#define APPEND_BYTE(c) \ + if (len > 1) { \ + *buf++ = c; \ + *buf = '\0'; \ + len--; \ + } + + time_t now; + struct tm *tm; + + now = time (NULL); + tm = gmtime (&now); + + while (*fmt) { + int c = *fmt++; + + if (c != '%') { + APPEND_BYTE(mutt_normalized_char(c)); + continue; + } + + switch (*fmt++) { + case 0: + return; + case 'd': + APPEND_FMT("%02d", tm->tm_mday); + break; + case 'h': + APPEND_FMT("%02d", tm->tm_hour); + break; + case 'm': + APPEND_FMT("%02d", tm->tm_mon + 1); + break; + case 'M': + APPEND_FMT("%02d", tm->tm_min); + break; + case 'O': + APPEND_FMT("%lo", (unsigned long)now); + break; + case 'p': + APPEND_FMT("%u", (unsigned int)getpid()); + break; + case 'P': + APPEND_FMT("%c", MsgIdPfx); + MsgIdPfx = (MsgIdPfx == 'Z') ? 'A' : MsgIdPfx + 1; + break; + case 'r': + APPEND_FMT("%u", (unsigned int)rand()); + break; + case 'R': + APPEND_FMT("%x", (unsigned int)rand()); + break; + case 's': + APPEND_FMT("%02d", tm->tm_sec); + break; + case 'T': + APPEND_FMT("%u", (unsigned int) now); + break; + case 'X': + APPEND_FMT("%x", (unsigned int) now); + break; + case 'Y': /* this will break in the year 10000 ;-) */ + APPEND_FMT("%04d", tm->tm_year + 1900); + break; + case '%': + APPEND_BYTE('%'); + break; + default: /* invalid formats are replaced by '.' */ + APPEND_BYTE('.'); + m_strncat(buf, len, ".", 1); + } + } + + *buf = '\0'; + +#undef APPEND_BYTE +#undef APPEND_FMT +} + char *mutt_gen_msgid (void) { char buf[SHORT_STRING]; - time_t now; - struct tm *tm; + char localpart[SHORT_STRING]; + unsigned int localpart_length; const char *fqdn; - now = time (NULL); - tm = gmtime (&now); - if(!(fqdn = mutt_fqdn(0))) - fqdn = NONULL(Hostname); + if (!(fqdn = mutt_fqdn (0))) + fqdn = NONULL (Hostname); - snprintf (buf, sizeof (buf), "<%d%02d%02d%02d%02d%02d.G%c%d@%s>", - tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, - tm->tm_min, tm->tm_sec, MsgIdPfx, getpid (), fqdn); - MsgIdPfx = (MsgIdPfx == 'Z') ? 'A' : MsgIdPfx + 1; - return (safe_strdup (buf)); + localpart_length = sizeof (buf) - m_strlen(fqdn) - 4; /* the 4 characters are '<', '@', '>' and '\0' */ + + mutt_gen_localpart (localpart, localpart_length, MsgIdFormat); + + snprintf (buf, sizeof (buf), "<%s@%s>", localpart, fqdn); + return (m_strdup(buf)); } static RETSIGTYPE alarm_handler (int sig) @@ -1850,7 +1771,7 @@ static RETSIGTYPE alarm_handler (int sig) to the temporary file containing the stdout of the child process */ static int -send_msg (const char *path, char **args, const char *msg, char **tempfile) +send_msg(const char *path, const char **args, const char *msg, char **tempfile) { sigset_t set; int fd, st; @@ -1863,16 +1784,14 @@ send_msg (const char *path, char **args, const char *msg, char **tempfile) sigaddset (&set, SIGTSTP); sigprocmask (SIG_BLOCK, &set, NULL); - if (SendmailWait >= 0) - { + if (SendmailWait >= 0) { char tmp[_POSIX_PATH_MAX]; mutt_mktemp (tmp); - *tempfile = safe_strdup (tmp); + *tempfile = m_strdup(tmp); } - if ((pid = fork ()) == 0) - { + if ((pid = fork ()) == 0) { struct sigaction act, oldalrm; /* save parent's ID before setsid() */ @@ -1882,7 +1801,7 @@ send_msg (const char *path, char **args, const char *msg, char **tempfile) * so we put ourselves into another session right away */ setsid (); - + /* next we close all open files */ #if defined(OPEN_MAX) for (fd = 0; fd < OPEN_MAX; fd++) @@ -1897,40 +1816,36 @@ send_msg (const char *path, char **args, const char *msg, char **tempfile) #endif /* now the second fork() */ - if ((pid = fork ()) == 0) - { + if ((pid = fork ()) == 0) { /* "msg" will be opened as stdin */ - if (open (msg, O_RDONLY, 0) < 0) - { - unlink (msg); - _exit (S_ERR); + if (open (msg, O_RDONLY, 0) < 0) { + unlink (msg); + _exit (S_ERR); } unlink (msg); - if (SendmailWait >= 0) - { - /* *tempfile will be opened as stdout */ - if (open (*tempfile, O_WRONLY | O_APPEND | O_CREAT | O_EXCL, 0600) < 0) - _exit (S_ERR); - /* redirect stderr to *tempfile too */ - if (dup (1) < 0) - _exit (S_ERR); + if (SendmailWait >= 0) { + /* *tempfile will be opened as stdout */ + if (open (*tempfile, O_WRONLY | O_APPEND | O_CREAT | O_EXCL, 0600) < + 0) + _exit (S_ERR); + /* redirect stderr to *tempfile too */ + if (dup (1) < 0) + _exit (S_ERR); } - else - { - if (open ("/dev/null", O_WRONLY | O_APPEND) < 0) /* stdout */ - _exit (S_ERR); - if (open ("/dev/null", O_RDWR | O_APPEND) < 0) /* stderr */ - _exit (S_ERR); + else { + if (open ("/dev/null", O_WRONLY | O_APPEND) < 0) /* stdout */ + _exit (S_ERR); + if (open ("/dev/null", O_RDWR | O_APPEND) < 0) /* stderr */ + _exit (S_ERR); } execv (path, args); _exit (S_ERR); } - else if (pid == -1) - { + else if (pid == -1) { unlink (msg); - FREE (tempfile); + p_delete(tempfile); _exit (S_ERR); } @@ -1938,8 +1853,7 @@ send_msg (const char *path, char **args, const char *msg, char **tempfile) * SendmailWait = 0: wait forever * SendmailWait < 0: don't wait */ - if (SendmailWait > 0) - { + if (SendmailWait > 0) { SigAlrm = 0; act.sa_handler = alarm_handler; #ifdef SA_INTERRUPT @@ -1955,23 +1869,18 @@ send_msg (const char *path, char **args, const char *msg, char **tempfile) else if (SendmailWait < 0) _exit (0xff & EX_OK); - if (waitpid (pid, &st, 0) > 0) - { + if (waitpid (pid, &st, 0) > 0) { st = WIFEXITED (st) ? WEXITSTATUS (st) : S_ERR; - if (SendmailWait && st == (0xff & EX_OK)) - { - unlink (*tempfile); /* no longer needed */ - FREE (tempfile); + if (SendmailWait && st == (0xff & EX_OK)) { + unlink (*tempfile); /* no longer needed */ + p_delete(tempfile); } } - else - { - st = (SendmailWait > 0 && errno == EINTR && SigAlrm) ? - S_BKG : S_ERR; - if (SendmailWait > 0) - { - unlink (*tempfile); - FREE (tempfile); + else { + st = (SendmailWait > 0 && errno == EINTR && SigAlrm) ? S_BKG : S_ERR; + if (SendmailWait > 0) { + unlink (*tempfile); + p_delete(tempfile); } } @@ -1979,11 +1888,10 @@ send_msg (const char *path, char **args, const char *msg, char **tempfile) alarm (0); sigaction (SIGALRM, &oldalrm, NULL); - if (kill (ppid, 0) == -1 && errno == ESRCH) - { + if (kill (ppid, 0) == -1 && errno == ESRCH) { /* the parent is already dead */ unlink (*tempfile); - FREE (tempfile); + p_delete(tempfile); } _exit (st); @@ -1992,102 +1900,82 @@ send_msg (const char *path, char **args, const char *msg, char **tempfile) sigprocmask (SIG_UNBLOCK, &set, NULL); if (pid != -1 && waitpid (pid, &st, 0) > 0) - st = WIFEXITED (st) ? WEXITSTATUS (st) : S_ERR; /* return child status */ + st = WIFEXITED (st) ? WEXITSTATUS (st) : S_ERR; /* return child status */ else - st = S_ERR; /* error */ + st = S_ERR; /* error */ mutt_unblock_signals_system (1); return (st); } -static char ** -add_args (char **args, size_t *argslen, size_t *argsmax, ADDRESS *addr) +static const char ** +add_args(const char **args, ssize_t *argslen, ssize_t *argsmax, address_t * addr) { - for (; addr; addr = addr->next) - { + for (; addr; addr = addr->next) { /* weed out group mailboxes, since those are for display only */ - if (addr->mailbox && !addr->group) - { + if (addr->mailbox && !addr->group) { if (*argslen == *argsmax) - safe_realloc (&args, (*argsmax += 5) * sizeof (char *)); + p_realloc(&args, *argsmax += 5); args[(*argslen)++] = addr->mailbox; } } return (args); } -static char ** -add_option (char **args, size_t *argslen, size_t *argsmax, char *s) -{ - if (*argslen == *argsmax) - safe_realloc (&args, (*argsmax += 5) * sizeof (char *)); - args[(*argslen)++] = s; - return (args); -} - -static const char * -strsysexit(int e) +static const char ** +add_option(const char **args, ssize_t *argslen, ssize_t *argsmax, const char *s) { - int i; - - for(i = 0; sysexits_h[i].str; i++) - { - if(e == sysexits_h[i].v) - break; - } - - return sysexits_h[i].str; + if (*argslen == *argsmax) { + p_realloc(&args, *argsmax += 5); + } + args[(*argslen)++] = s; + return (args); } - -static int -mutt_invoke_sendmail (ADDRESS *from, /* the sender */ - ADDRESS *to, ADDRESS *cc, ADDRESS *bcc, /* recips */ - const char *msg, /* file containing message */ - int eightbit) /* message contains 8bit chars */ -{ +static int mutt_invoke_sendmail (address_t * from, /* the sender */ + address_t * to, address_t * cc, address_t * bcc, /* recips */ + const char *msg, /* file containing message */ + int eightbit) +{ /* message contains 8bit chars */ char *ps = NULL, *path = NULL, *s = NULL, *childout = NULL; - char **args = NULL; - size_t argslen = 0, argsmax = 0; + const char **args = NULL; + ssize_t argslen = 0, argsmax = 0; int i; #ifdef USE_NNTP - if (option (OPTNEWSSEND)) - { + if (option (OPTNEWSSEND)) { char cmd[LONG_STRING]; - mutt_FormatString (cmd, sizeof (cmd), NONULL (Inews), nntp_format_str, 0, 0); - if (!*cmd) - { + mutt_FormatString (cmd, sizeof (cmd), NONULL (Inews), nntp_format_str, 0, + 0); + if (!*cmd) { i = nntp_post (msg); unlink (msg); return i; } - s = safe_strdup (cmd); + s = m_strdup(cmd); } else #endif - s = safe_strdup (Sendmail); + s = m_strdup(Sendmail); ps = s; i = 0; - while ((ps = strtok (ps, " "))) - { + while ((ps = strtok (ps, " "))) { if (argslen == argsmax) - safe_realloc (&args, sizeof (char *) * (argsmax += 5)); + p_realloc(&args, argsmax += 5); if (i) args[argslen++] = ps; - else - { - path = safe_strdup (ps); + else { + path = m_strdup(ps); ps = strrchr (ps, '/'); if (ps) - ps++; + ps++; else - ps = path; + ps = path; args[argslen++] = ps; } ps = NULL; @@ -2095,64 +1983,63 @@ mutt_invoke_sendmail (ADDRESS *from, /* the sender */ } #ifdef USE_NNTP - if (!option (OPTNEWSSEND)) - { + if (!option (OPTNEWSSEND)) { #endif - if (eightbit && option (OPTUSE8BITMIME)) - args = add_option (args, &argslen, &argsmax, "-B8BITMIME"); - - if (option (OPTENVFROM) && from && !from->next) - { - args = add_option (args, &argslen, &argsmax, "-f"); - args = add_args (args, &argslen, &argsmax, from); - } - if (DsnNotify) - { - args = add_option (args, &argslen, &argsmax, "-N"); - args = add_option (args, &argslen, &argsmax, DsnNotify); - } - if (DsnReturn) - { - args = add_option (args, &argslen, &argsmax, "-R"); - args = add_option (args, &argslen, &argsmax, DsnReturn); - } - args = add_option (args, &argslen, &argsmax, "--"); - args = add_args (args, &argslen, &argsmax, to); - args = add_args (args, &argslen, &argsmax, cc); - args = add_args (args, &argslen, &argsmax, bcc); + if (eightbit && option (OPTUSE8BITMIME)) + args = add_option(args, &argslen, &argsmax, "-B8BITMIME"); + + if (option (OPTENVFROM)) { + address_t *f = NULL; + if (EnvFrom) + f = EnvFrom; + else if (from && !from->next) + f = from; + if (f) { + args = add_option (args, &argslen, &argsmax, "-f"); + args = add_args (args, &argslen, &argsmax, f); + } + } + if (DsnNotify) { + args = add_option (args, &argslen, &argsmax, "-N"); + args = add_option (args, &argslen, &argsmax, DsnNotify); + } + if (DsnReturn) { + args = add_option (args, &argslen, &argsmax, "-R"); + args = add_option (args, &argslen, &argsmax, DsnReturn); + } + args = add_option (args, &argslen, &argsmax, "--"); + args = add_args (args, &argslen, &argsmax, to); + args = add_args (args, &argslen, &argsmax, cc); + args = add_args (args, &argslen, &argsmax, bcc); #ifdef USE_NNTP } #endif if (argslen == argsmax) - safe_realloc (&args, sizeof (char *) * (++argsmax)); - + p_realloc(&args, ++argsmax); + args[argslen++] = NULL; - if ((i = send_msg (path, args, msg, &childout)) != (EX_OK & 0xff)) - { - if (i != S_BKG) - { - const char *e = strsysexit (i); - - e = strsysexit (i); - mutt_error (_("Error sending message, child exited %d (%s)."), i, NONULL (e)); - if (childout) - { - struct stat st; - - if (stat (childout, &st) == 0 && st.st_size > 0) - mutt_do_pager (_("Output of the delivery process"), childout, 0, NULL); + if ((i = send_msg (path, args, msg, &childout)) != (EX_OK & 0xff)) { + if (i != S_BKG) { + mutt_error (_("Error sending message, child exited %d (%s)."), i, + m_strsysexit(i)); + if (childout) { + struct stat st; + + if (stat (childout, &st) == 0 && st.st_size > 0) + mutt_do_pager (_("Output of the delivery process"), childout, 0, + NULL); } } } else unlink (childout); - FREE (&childout); - FREE (&path); - FREE (&s); - FREE (&args); + p_delete(&childout); + p_delete(&path); + p_delete(&s); + p_delete(&args); if (i == (EX_OK & 0xff)) i = 0; @@ -2163,27 +2050,30 @@ mutt_invoke_sendmail (ADDRESS *from, /* the sender */ return (i); } -int -mutt_invoke_mta (ADDRESS *from, /* the sender */ - ADDRESS *to, ADDRESS *cc, ADDRESS *bcc, /* recips */ - const char *msg, /* file containing message */ - int eightbit) /* message contains 8bit chars */ -{ +int mutt_invoke_mta (address_t * from, /* the sender */ + address_t * to, address_t * cc, address_t * bcc, /* recips */ + const char *msg, /* file containing message */ + int eightbit) +{ /* message contains 8bit chars */ #ifdef USE_LIBESMTP - if (SmtpHost) - return mutt_invoke_libesmtp(from, to, cc, bcc, msg, eightbit); +#ifdef USE_NNTP + if (!option (OPTNEWSSEND)) +#endif + if (SmtpHost) + return mutt_libesmtp_invoke (from, to, cc, bcc, msg, eightbit); #endif - - return mutt_invoke_sendmail(from, to, cc, bcc, msg, eightbit); + + return mutt_invoke_sendmail (from, to, cc, bcc, msg, eightbit); } /* appends string 'b' to string 'a', and returns the pointer to the new string. */ char *mutt_append_string (char *a, const char *b) { - size_t la = mutt_strlen (a); - safe_realloc (&a, la + mutt_strlen (b) + 1); - strcpy (a + la, b); /* __STRCPY_CHECKED__ */ + ssize_t la = m_strlen(a); + + p_realloc(&a, la + m_strlen(b) + 1); + strcpy (a + la, b); /* __STRCPY_CHECKED__ */ return (a); } @@ -2195,8 +2085,7 @@ char *mutt_append_string (char *a, const char *b) when used on a command line to execute a command */ int mutt_needs_quote (const char *s) { - while (*s) - { + while (*s) { if (INVALID_CHAR (*s)) return 1; s++; @@ -2209,17 +2098,16 @@ int mutt_needs_quote (const char *s) char *mutt_quote_string (const char *s) { char *r, *pr; - size_t rlen; + ssize_t rlen; - rlen = mutt_strlen (s) + 3; - pr = r = (char *) safe_malloc (rlen); + rlen = m_strlen(s) + 3; + pr = r = p_new(char, rlen); *pr++ = '"'; - while (*s) - { - if (INVALID_CHAR (*s)) - { - size_t o = pr - r; - safe_realloc (&r, ++rlen); + while (*s) { + if (INVALID_CHAR (*s)) { + ssize_t o = pr - r; + + p_realloc(&r, ++rlen); pr = r + o; *pr++ = '\\'; } @@ -2231,83 +2119,84 @@ char *mutt_quote_string (const char *s) } /* For postponing (!final) do the necessary encodings only */ -void mutt_prepare_envelope (ENVELOPE *env, int final) +void mutt_prepare_envelope (ENVELOPE * env, int final) { char buffer[LONG_STRING]; - if (final) - { - if (env->bcc && !(env->to || env->cc)) - { + if (final) { + if (env->bcc && !(env->to || env->cc)) { /* some MTA's will put an Apparently-To: header field showing the Bcc: * recipients if there is no To: or Cc: field, so attempt to suppress * it by using an empty To: field. */ - env->to = rfc822_new_address (); + env->to = address_new (); env->to->group = 1; - env->to->next = rfc822_new_address (); + env->to->next = address_new (); buffer[0] = 0; - rfc822_cat (buffer, sizeof (buffer), "undisclosed-recipients", - RFC822Specials); + rfc822_strcpy(buffer, sizeof(buffer), "undisclosed-recipients", + RFC822Specials); - env->to->mailbox = safe_strdup (buffer); + env->to->mailbox = m_strdup(buffer); } mutt_set_followup_to (env); - if (!env->message_id) + if (!env->message_id && MsgIdFormat && *MsgIdFormat) env->message_id = mutt_gen_msgid (); } /* Take care of 8-bit => 7-bit conversion. */ rfc2047_encode_adrlist (env->to, "To"); rfc2047_encode_adrlist (env->cc, "Cc"); + rfc2047_encode_adrlist (env->bcc, "Bcc"); rfc2047_encode_adrlist (env->from, "From"); rfc2047_encode_adrlist (env->mail_followup_to, "Mail-Followup-To"); rfc2047_encode_adrlist (env->reply_to, "Reply-To"); if (env->subject) #ifdef USE_NNTP - if (!option (OPTNEWSSEND) || option (OPTMIMESUBJECT)) + if (!option (OPTNEWSSEND) || option (OPTMIMESUBJECT)) #endif - { - rfc2047_encode_string (&env->subject); - } + { + rfc2047_encode_string (&env->subject); + } encode_headers (env->userhdrs); } -void mutt_unprepare_envelope (ENVELOPE *env) +void mutt_unprepare_envelope (ENVELOPE * env) { - LIST *item; + string_list_t *item; for (item = env->userhdrs; item; item = item->next) rfc2047_decode (&item->data); - rfc822_free_address (&env->mail_followup_to); + address_list_wipe(&env->mail_followup_to); /* back conversions */ rfc2047_decode_adrlist (env->to); rfc2047_decode_adrlist (env->cc); + rfc2047_decode_adrlist (env->bcc); rfc2047_decode_adrlist (env->from); rfc2047_decode_adrlist (env->reply_to); rfc2047_decode (&env->subject); } -static int _mutt_bounce_message (FILE *fp, HEADER *h, ADDRESS *to, const char *resent_from, - ADDRESS *env_from) +static int _mutt_bounce_message (FILE * fp, HEADER * h, address_t * to, + const char *resent_from, address_t * env_from) { int i, ret = 0; FILE *f; char date[SHORT_STRING], tempfile[_POSIX_PATH_MAX]; MESSAGE *msg = NULL; - if (!h) - { - /* Try to bounce each message out, aborting if we get any failures. */ - for (i=0; imsgcount; i++) + if (!h) { + /* Try to bounce each message out, aborting if we get any failures. */ + for (i = 0; i < Context->msgcount; i++) if (Context->hdrs[i]->tagged) - ret |= _mutt_bounce_message (fp, Context->hdrs[i], to, resent_from, env_from); + ret |= + _mutt_bounce_message (fp, Context->hdrs[i], to, resent_from, + env_from); return ret; } @@ -2315,20 +2204,21 @@ static int _mutt_bounce_message (FILE *fp, HEADER *h, ADDRESS *to, const char *r if (!fp && (msg = mx_open_message (Context, h->msgno)) == NULL) return -1; - if (!fp) fp = msg->fp; + if (!fp) + fp = msg->fp; mutt_mktemp (tempfile); - if ((f = safe_fopen (tempfile, "w")) != NULL) - { + if ((f = safe_fopen (tempfile, "w")) != NULL) { int ch_flags = CH_XMIT | CH_NONEWLINE | CH_NOQFROM; - + if (!option (OPTBOUNCEDELIVERED)) ch_flags |= CH_WEED_DELIVERED; - - fseek (fp, h->offset, 0); + + fseeko (fp, h->offset, 0); fprintf (f, "Resent-From: %s", resent_from); - fprintf (f, "\nResent-%s", mutt_make_date (date, sizeof(date))); - fprintf (f, "Resent-Message-ID: %s\n", mutt_gen_msgid()); + fprintf (f, "\nResent-%s", mutt_make_date (date, sizeof (date))); + if (MsgIdFormat && *MsgIdFormat) + fprintf (f, "Resent-Message-ID: %s\n", mutt_gen_msgid ()); fputs ("Resent-To: ", f); mutt_write_address_list (to, f, 11, 0); mutt_copy_header (fp, h, f, ch_flags, NULL); @@ -2337,7 +2227,7 @@ static int _mutt_bounce_message (FILE *fp, HEADER *h, ADDRESS *to, const char *r fclose (f); ret = mutt_invoke_mta (env_from, to, NULL, NULL, tempfile, - h->content->encoding == ENC8BIT); + h->content->encoding == ENC8BIT); } if (msg) @@ -2346,14 +2236,14 @@ static int _mutt_bounce_message (FILE *fp, HEADER *h, ADDRESS *to, const char *r return ret; } -int mutt_bounce_message (FILE *fp, HEADER *h, ADDRESS *to) +int mutt_bounce_message (FILE * fp, HEADER * h, address_t * to) { - ADDRESS *from; + address_t *from; const char *fqdn = mutt_fqdn (1); char resent_from[STRING]; int ret; char *err; - + resent_from[0] = '\0'; from = mutt_default_from (); @@ -2361,10 +2251,8 @@ int mutt_bounce_message (FILE *fp, HEADER *h, ADDRESS *to) rfc822_qualify (from, fqdn); rfc2047_encode_adrlist (from, "Resent-From"); - if (mutt_addrlist_to_idna (from, &err)) - { - mutt_error (_("Bad IDN %s while preparing resent-from."), - err); + if (mutt_addrlist_to_idna (from, &err)) { + mutt_error (_("Bad IDN %s while preparing resent-from."), err); return -1; } rfc822_write_address (resent_from, sizeof (resent_from), from, 0); @@ -2375,69 +2263,62 @@ int mutt_bounce_message (FILE *fp, HEADER *h, ADDRESS *to) ret = _mutt_bounce_message (fp, h, to, resent_from, from); - rfc822_free_address (&from); + address_list_wipe(&from); return ret; } /* given a list of addresses, return a list of unique addresses */ -ADDRESS *mutt_remove_duplicates (ADDRESS *addr) +address_t *mutt_remove_duplicates (address_t * addr) { - ADDRESS *top = NULL; - ADDRESS *tmp; - - if ((top = addr) == NULL) - return (NULL); - addr = addr->next; - top->next = NULL; - while (addr) - { - tmp = top; - do { - if (addr->mailbox && tmp->mailbox && - !ascii_strcasecmp (addr->mailbox, tmp->mailbox)) - { - /* duplicate address, just ignore it */ - tmp = addr; - addr = addr->next; - tmp->next = NULL; - rfc822_free_address (&tmp); + address_t *top = addr; + address_t **last = ⊤ + address_t *tmp; + int dup; + + while (addr) { + for (tmp = top, dup = 0; tmp && tmp != addr; tmp = tmp->next) { + if (tmp->mailbox && addr->mailbox && + !ascii_strcasecmp (addr->mailbox, tmp->mailbox)) { + dup = 1; + break; } - else if (!tmp->next) - { - /* unique address. add it to the list */ - tmp->next = addr; - addr = addr->next; - tmp = tmp->next; - tmp->next = NULL; - tmp = NULL; /* so we exit the loop */ - } - else - tmp = tmp->next; - } while (tmp); + } + + if (dup) { + *last = addr->next; + + addr->next = NULL; + address_list_wipe(&addr); + + addr = *last; + } + else { + last = &addr->next; + addr = addr->next; + } } return (top); } -static void set_noconv_flags (BODY *b, short flag) +static void set_noconv_flags (BODY * b, short flag) { - for(; b; b = b->next) - { + for (; b; b = b->next) { if (b->type == TYPEMESSAGE || b->type == TYPEMULTIPART) set_noconv_flags (b->parts, flag); - else if (b->type == TYPETEXT && b->noconv) - { + else if (b->type == TYPETEXT && b->noconv) { if (flag) - mutt_set_parameter ("x-mutt-noconv", "yes", &b->parameter); + mutt_set_parameter ("x-mutt-noconv", "yes", &b->parameter); else - mutt_delete_parameter ("x-mutt-noconv", &b->parameter); + mutt_delete_parameter ("x-mutt-noconv", &b->parameter); } } } -int mutt_write_fcc (const char *path, HEADER *hdr, const char *msgid, int post, char *fcc) +int mutt_write_fcc (const char *path, HEADER * hdr, const char *msgid, + int post, char *fcc) { CONTEXT f; MESSAGE *msg; @@ -2447,31 +2328,25 @@ int mutt_write_fcc (const char *path, HEADER *hdr, const char *msgid, int post, if (post) set_noconv_flags (hdr->content, 1); - - if (mx_open_mailbox (path, M_APPEND | M_QUIET, &f) == NULL) - { - dprint (1, (debugfile, "mutt_write_fcc(): unable to open mailbox %s in append-mode, aborting.\n", - path)); + + if (mx_open_mailbox (path, M_APPEND | M_QUIET, &f) == NULL) { return (-1); } /* We need to add a Content-Length field to avoid problems where a line in * the message body begins with "From " */ - if (f.magic == M_MMDF || f.magic == M_MBOX) - { + if (f.magic == M_MMDF || f.magic == M_MBOX) { mutt_mktemp (tempfile); - if ((tempfp = safe_fopen (tempfile, "w+")) == NULL) - { + if ((tempfp = safe_fopen (tempfile, "w+")) == NULL) { mutt_perror (tempfile); mx_close_mailbox (&f, NULL); return (-1); } } - hdr->read = !post; /* make sure to put it in the `cur' directory (maildir) */ - if ((msg = mx_open_new_message (&f, hdr, M_ADD_FROM)) == NULL) - { + hdr->read = !post; /* make sure to put it in the `cur' directory (maildir) */ + if ((msg = mx_open_new_message (&f, hdr, M_ADD_FROM)) == NULL) { mx_close_mailbox (&f, NULL); return (-1); } @@ -2479,7 +2354,8 @@ int mutt_write_fcc (const char *path, HEADER *hdr, const char *msgid, int post, /* post == 1 => postpone message. Set mode = -1 in mutt_write_rfc822_header() * post == 0 => Normal mode. Set mode = 0 in mutt_write_rfc822_header() * */ - mutt_write_rfc822_header (msg->fp, hdr->env, hdr->content, post ? -post : 0, 0); + mutt_write_rfc822_header (msg->fp, hdr->env, hdr->content, post ? -post : 0, + 0); /* (postponment) if this was a reply of some sort, contians the * Message-ID: of message replied to. Save it using a special X-Mutt- @@ -2489,7 +2365,7 @@ int mutt_write_fcc (const char *path, HEADER *hdr, const char *msgid, int post, */ if (post && msgid) fprintf (msg->fp, "X-Mutt-References: %s\n", msgid); - + /* (postponment) save the Fcc: using a special X-Mutt- header so that * it can be picked up when the message is recalled */ @@ -2500,36 +2376,35 @@ int mutt_write_fcc (const char *path, HEADER *hdr, const char *msgid, int post, /* (postponment) if the mail is to be signed or encrypted, save this info */ - if ((WithCrypto & APPLICATION_PGP) - && post && (hdr->security & APPLICATION_PGP)) - { + if (post && (hdr->security & APPLICATION_PGP)) { fputs ("X-Mutt-PGP: ", msg->fp); - if (hdr->security & ENCRYPT) + if (hdr->security & ENCRYPT) fputc ('E', msg->fp); - if (hdr->security & SIGN) - { + if (hdr->security & SIGN) { fputc ('S', msg->fp); if (PgpSignAs && *PgpSignAs) fprintf (msg->fp, "<%s>", PgpSignAs); } + if (hdr->security & INLINE) + fputc ('I', msg->fp); fputc ('\n', msg->fp); } /* (postponment) if the mail is to be signed or encrypted, save this info */ - if ((WithCrypto & APPLICATION_SMIME) - && post && (hdr->security & APPLICATION_SMIME)) - { + if (post && (hdr->security & APPLICATION_SMIME)) { fputs ("X-Mutt-SMIME: ", msg->fp); if (hdr->security & ENCRYPT) { - fputc ('E', msg->fp); - if (SmimeCryptAlg && *SmimeCryptAlg) - fprintf (msg->fp, "C<%s>", SmimeCryptAlg); + fputc ('E', msg->fp); + if (SmimeCryptAlg && *SmimeCryptAlg) + fprintf (msg->fp, "C<%s>", SmimeCryptAlg); } if (hdr->security & SIGN) { - fputc ('S', msg->fp); - if (SmimeDefaultKey && *SmimeDefaultKey) - fprintf (msg->fp, "<%s>", SmimeDefaultKey); + fputc ('S', msg->fp); + if (SmimeDefaultKey && *SmimeDefaultKey) + fprintf (msg->fp, "<%s>", SmimeDefaultKey); } + if (hdr->security & INLINE) + fputc ('I', msg->fp); fputc ('\n', msg->fp); } @@ -2537,21 +2412,19 @@ int mutt_write_fcc (const char *path, HEADER *hdr, const char *msgid, int post, /* (postponement) if the mail is to be sent through a mixmaster * chain, save that information */ - - if (post && hdr->chain && hdr->chain) - { - LIST *p; + + if (post && hdr->chain && hdr->chain) { + string_list_t *p; fputs ("X-Mutt-Mix:", msg->fp); for (p = hdr->chain; p; p = p->next) fprintf (msg->fp, " %s", (char *) p->data); - + fputc ('\n', msg->fp); } -#endif +#endif - if (tempfp) - { + if (tempfp) { char sasha[LONG_STRING]; int lines = 0; @@ -2561,20 +2434,17 @@ int mutt_write_fcc (const char *path, HEADER *hdr, const char *msgid, int post, * this will happen, and it can cause problems parsing the mailbox * later. */ - fseek (tempfp, -1, 2); - if (fgetc (tempfp) != '\n') - { - fseek (tempfp, 0, 2); + fseeko (tempfp, -1, 2); + if (fgetc (tempfp) != '\n') { + fseeko (tempfp, 0, 2); fputc ('\n', tempfp); } fflush (tempfp); - if (ferror (tempfp)) - { - dprint (1, (debugfile, "mutt_write_fcc(): %s: write failed.\n", tempfile)); + if (ferror (tempfp)) { fclose (tempfp); unlink (tempfile); - mx_commit_message (msg, &f); /* XXX - really? */ + mx_commit_message (msg, &f); /* XXX - really? */ mx_close_message (&msg); mx_close_mailbox (&f, NULL); return -1; @@ -2584,7 +2454,7 @@ int mutt_write_fcc (const char *path, HEADER *hdr, const char *msgid, int post, rewind (tempfp); while (fgets (sasha, sizeof (sasha), tempfp) != NULL) lines++; - fprintf (msg->fp, "Content-Length: %ld\n", (long) ftell (tempfp)); + fprintf (msg->fp, "Content-Length: %zd\n", ftello (tempfp)); fprintf (msg->fp, "Lines: %d\n\n", lines); /* copy the body and clean up */ @@ -2596,9 +2466,8 @@ int mutt_write_fcc (const char *path, HEADER *hdr, const char *msgid, int post, if (!r) unlink (tempfile); } - else - { - fputc ('\n', msg->fp); /* finish off the header */ + else { + fputc ('\n', msg->fp); /* finish off the header */ r = mutt_write_mime_body (hdr->content, msg->fp); } @@ -2609,6 +2478,6 @@ int mutt_write_fcc (const char *path, HEADER *hdr, const char *msgid, int post, if (post) set_noconv_flags (hdr->content, 0); - + return r; }