#define _SENDLIB_C 1
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
#include "mutt.h"
#include "mutt_curses.h"
#include "rfc2047.h"
#include <fcntl.h>
#include <sys/utsname.h>
+#ifdef USE_LIBESMTP
+# include "mutt_libesmtp.h"
+#endif /* USE_LIBESMTP */
+
#ifdef USE_NNTP
#include <nntp.h>
#endif
linelen = 3;
}
-#ifdef USE_LIBESMTP
-# include "mutt_libesmtp.h"
-#endif /* USE_LIBESMTP */
if (c == '\n' && istext)
{
}
if (a->type == TYPETEXT && (!a->noconv))
- fc = fgetconv_open (fpin, Charset,
+ fc = fgetconv_open (fpin, a->file_charset,
mutt_get_body_charset (send_charset, sizeof (send_charset), a),
0);
else
CONTENT *info;
CONTENT_STATE state;
FILE *fp = NULL;
+ char *fromcode;
char *tocode;
char buffer[100];
char chsbuf[STRING];
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))
+ convert_file_from_to (fp, fchs, chs ? chs : SendCharset,
+ &fromcode, &tocode, info) != (size_t)(-1))
{
if (!chs)
{
mutt_canonical_charset (chsbuf, sizeof (chsbuf), tocode);
mutt_set_parameter ("charset", chsbuf, &b->parameter);
}
+ b->file_charset = fromcode;
FREE (&tocode);
safe_fclose (&fp);
return info;
}
else
{
+ a->noconv = 1;
+ a->force_charset = 1;
+
mutt_mktemp (buff);
if ((s.fpout = safe_fopen (buff, "w")) == NULL)
{
body->unlink = 1;
body->use_disp = 0;
body->disposition = DISPINLINE;
+ body->noconv = 1;
mutt_parse_mime_message (ctx, hdr);
return p;
}
+static char mutt_normalized_char(char c) {
+ if (isalnum(c))
+ return c;
+ if (strchr(".!#$%&'*+-/=?^_`{|}~",c))
+ return c;
+ return '.'; /* normalized character (we're stricter than RFC2822, 3.6.4) */
+}
+
+static void mutt_gen_localpart(char * buf, unsigned int len, char * fmt) {
+ time_t now;
+ struct tm *tm;
+ char tmp[SHORT_STRING];
+
+ *buf = '\0';
+
+ now = time (NULL);
+ tm = gmtime (&now);
+
+ for (;*fmt;++fmt) {
+ if (*fmt == '%') {
+ switch (fmt[1]) {
+ case 0:
+ return;
+ case 'd':
+ snprintf(tmp,sizeof(tmp),"%02d",tm->tm_mday);
+ safe_strncat(buf,len,tmp,2);
+ break;
+ case 'h':
+ snprintf(tmp,sizeof(tmp),"%02d",tm->tm_hour);
+ safe_strncat(buf,len,tmp,2);
+ break;
+ case 'm':
+ snprintf(tmp,sizeof(tmp),"%02d",tm->tm_mon+1);
+ safe_strncat(buf,len,tmp,2);
+ break;
+ case 'M':
+ snprintf(tmp,sizeof(tmp),"%02d",tm->tm_min);
+ safe_strncat(buf,len,tmp,2);
+ break;
+ case 'O':
+ snprintf(tmp,sizeof(tmp),"%lo",(unsigned long)now);
+ safe_strncat(buf,len,tmp,strlen(tmp));
+ break;
+ case 'p':
+ snprintf(tmp,sizeof(tmp),"%u",(unsigned int)getpid());
+ safe_strncat(buf,len,tmp,strlen(tmp));
+ break;
+ case 'P':
+ snprintf(tmp,sizeof(tmp),"%c",MsgIdPfx);
+ MsgIdPfx = (MsgIdPfx == 'Z') ? 'A' : MsgIdPfx + 1;
+ safe_strncat(buf,len,tmp,1);
+ break;
+ case 'r':
+ snprintf(tmp,sizeof(tmp),"%u",(unsigned int)rand());
+ safe_strncat(buf,len,tmp,strlen(tmp));
+ break;
+ case 'R':
+ snprintf(tmp,sizeof(tmp),"%x",(unsigned int)rand());
+ safe_strncat(buf,len,tmp,strlen(tmp));
+ break;
+ case 's':
+ snprintf(tmp,sizeof(tmp),"%02d",tm->tm_sec);
+ safe_strncat(buf,len,tmp,2);
+ break;
+ case 'T':
+ snprintf(tmp,sizeof(tmp),"%u",(unsigned int)now);
+ safe_strncat(buf,len,tmp,strlen(tmp));
+ break;
+ case 'X':
+ snprintf(tmp,sizeof(tmp),"%x",(unsigned int)now);
+ safe_strncat(buf,len,tmp,strlen(tmp));
+ break;
+ case 'Y':
+ snprintf(tmp,sizeof(tmp),"%04d",tm->tm_year+1900); /* this will break in the year 10000 ;-) */
+ safe_strncat(buf,len,tmp,4);
+ break;
+ case '%':
+ safe_strncat(buf,len,"%",1);
+ break;
+ default:
+ safe_strncat(buf,len,".",1); /* invalid formats are replaced by '.' */
+ } /* switch */
+ ++fmt;
+ } else {
+ char c;
+ c = mutt_normalized_char(*fmt); /* @todo: filter out invalid characters */
+ safe_strncat(buf,len,&c,1);
+ }
+ }
+}
+
char *mutt_gen_msgid (void)
{
char buf[SHORT_STRING];
+ char localpart[SHORT_STRING];
+ unsigned int localpart_length;
time_t now;
struct tm *tm;
const char *fqdn;
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;
+ localpart_length = sizeof(buf) - 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 (safe_strdup (buf));
}
/* 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");
/* 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);
/* given a list of addresses, return a list of unique addresses */
ADDRESS *mutt_remove_duplicates (ADDRESS *addr)
{
- ADDRESS *top = NULL;
+ ADDRESS *top = addr;
+ ADDRESS **last = ⊤
ADDRESS *tmp;
-
- if ((top = addr) == NULL)
- return (NULL);
- addr = addr->next;
- top->next = NULL;
+ int dup;
+
while (addr)
{
- tmp = top;
- do {
- if (addr->mailbox && tmp->mailbox &&
+ for (tmp = top, dup = 0; tmp && tmp != addr; tmp = tmp->next)
+ {
+ if (tmp->mailbox && addr->mailbox &&
!ascii_strcasecmp (addr->mailbox, tmp->mailbox))
{
- /* duplicate address, just ignore it */
- tmp = addr;
- addr = addr->next;
- tmp->next = NULL;
- rfc822_free_address (&tmp);
- }
- 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 */
+ dup = 1;
+ break;
}
- else
- tmp = tmp->next;
- } while (tmp);
- }
+ }
+
+ if (dup)
+ {
+ dprint (2, (debugfile, "mutt_remove_duplicates: Removing %s\n",
+ addr->mailbox));
+
+ *last = addr->next;
+ addr->next = NULL;
+ rfc822_free_address(&addr);
+
+ addr = *last;
+ }
+ else
+ {
+ last = &addr->next;
+ addr = addr->next;
+ }
+ }
+
return (top);
}
if (PgpSignAs && *PgpSignAs)
fprintf (msg->fp, "<%s>", PgpSignAs);
}
+ if (hdr->security & INLINE)
+ fputc ('I', msg->fp);
fputc ('\n', msg->fp);
}
if (SmimeDefaultKey && *SmimeDefaultKey)
fprintf (msg->fp, "<%s>", SmimeDefaultKey);
}
+ if (hdr->security & INLINE)
+ fputc ('I', msg->fp);
fputc ('\n', msg->fp);
}