NeoMutt  2020-04-24
Teaching an old dog new tricks
DOXYGEN
sendlib.h File Reference

Miscellaneous functions for sending an email. More...

#include <stdbool.h>
#include <stdio.h>
#include "email/lib.h"
#include "copy.h"
+ Include dependency graph for sendlib.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Enumerations

enum  MuttWriteHeaderMode {
  MUTT_WRITE_HEADER_NORMAL, MUTT_WRITE_HEADER_FCC, MUTT_WRITE_HEADER_POSTPONE, MUTT_WRITE_HEADER_EDITHDRS,
  MUTT_WRITE_HEADER_MIME
}
 Modes for mutt_rfc822_write_header() More...
 

Functions

char * mutt_body_get_charset (struct Body *b, char *buf, size_t buflen)
 Get a body's character set. More...
 
int mutt_bounce_message (FILE *fp, struct Email *e, struct AddressList *to)
 Bounce an email message. More...
 
const char * mutt_fqdn (bool may_hide_host)
 Get the Fully-Qualified Domain Name. More...
 
void mutt_generate_boundary (struct ParameterList *pl)
 Create a unique boundary id for a MIME part. More...
 
struct Contentmutt_get_content_info (const char *fname, struct Body *b)
 Analyze file to determine MIME encoding to use. More...
 
int mutt_invoke_sendmail (struct AddressList *from, struct AddressList *to, struct AddressList *cc, struct AddressList *bcc, const char *msg, int eightbit)
 Run sendmail. More...
 
enum ContentType mutt_lookup_mime_type (struct Body *att, const char *path)
 Find the MIME type for an attachment. More...
 
struct Bodymutt_make_file_attach (const char *path)
 Create a file attachment. More...
 
struct Bodymutt_make_message_attach (struct Mailbox *m, struct Email *e, bool attach_msg)
 Create a message attachment. More...
 
struct Bodymutt_make_multipart (struct Body *b)
 Create a multipart email. More...
 
void mutt_message_to_7bit (struct Body *a, FILE *fp)
 Convert an email's MIME parts to 7-bit. More...
 
void mutt_prepare_envelope (struct Envelope *env, bool final)
 Prepare an email header. More...
 
struct Bodymutt_remove_multipart (struct Body *b)
 Extract the multipart body if it exists. More...
 
int mutt_rfc822_write_header (FILE *fp, struct Envelope *env, struct Body *attach, enum MuttWriteHeaderMode mode, bool privacy, bool hide_protected_subject)
 Write out one RFC822 header line. More...
 
void mutt_stamp_attachment (struct Body *a)
 Timestamp an Attachment. More...
 
void mutt_unprepare_envelope (struct Envelope *env)
 Undo the encodings of mutt_prepare_envelope() More...
 
void mutt_update_encoding (struct Body *a)
 Update the encoding type. More...
 
void mutt_write_addrlist (struct AddressList *addr, FILE *fp, int linelen, bool display)
 Wrapper for mutt_write_address() More...
 
int mutt_write_fcc (const char *path, struct Email *e, const char *msgid, bool post, const char *fcc, char **finalpath)
 Write email to FCC mailbox. More...
 
int mutt_write_mime_body (struct Body *a, FILE *fp)
 Write a MIME part. More...
 
int mutt_write_mime_header (struct Body *a, FILE *fp)
 Create a MIME header. More...
 
int mutt_write_multiple_fcc (const char *path, struct Email *e, const char *msgid, bool post, char *fcc, char **finalpath)
 Handle FCC with multiple, comma separated entries. More...
 
int mutt_write_one_header (FILE *fp, const char *tag, const char *value, const char *pfx, int wraplen, CopyHeaderFlags chflags)
 Write one header line to a file. More...
 
void mutt_write_references (const struct ListHead *r, FILE *fp, size_t trim)
 Add the message references to a list. More...
 

Variables

bool C_Allow8bit
 Config: Allow 8-bit messages, don't use quoted-printable or base64. More...
 
char * C_AttachCharset
 Config: When attaching files, use one of these character sets. More...
 
bool C_BounceDelivered
 Config: Add 'Delivered-To' to bounced messages. More...
 
bool C_EncodeFrom
 Config: Encode 'From ' as 'quote-printable' at the beginning of lines. More...
 
bool C_ForwardDecrypt
 Config: Decrypt the message when forwarding it. More...
 
bool C_HiddenHost
 Config: Don't use the hostname, just the domain, when generating the message id. More...
 
char * C_Inews
 Config: (nntp) External command to post news articles. More...
 
bool C_MimeForwardDecode
 Config: Decode the forwarded message before attaching it. More...
 
bool C_MimeSubject
 encode subject line with RFC2047 More...
 
char * C_MimeTypeQueryCommand
 Config: External command to determine the MIME type of an attachment. More...
 
bool C_MimeTypeQueryFirst
 Config: Run the C_MimeTypeQueryCommand before the mime.types lookup. More...
 
char * C_Sendmail
 Config: External command to send email. More...
 
short C_SendmailWait
 Config: Time to wait for sendmail to finish. More...
 
bool C_Use8bitmime
 Config: Use 8-bit messages and ESMTP to send messages. More...
 
bool C_UseEnvelopeFrom
 Config: Set the envelope sender of the message. More...
 
bool C_UserAgent
 Config: Add a 'User-Agent' head to outgoing mail. More...
 
short C_WrapHeaders
 Config: Width to wrap headers in outgoing messages. More...
 

Detailed Description

Miscellaneous functions for sending an email.

Authors
  • Richard Russon
  • Pietro Cerutti

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, see http://www.gnu.org/licenses/.

Definition in file sendlib.h.

Enumeration Type Documentation

◆ MuttWriteHeaderMode

Modes for mutt_rfc822_write_header()

Enumerator
MUTT_WRITE_HEADER_NORMAL 

A normal Email, write full header + MIME headers.

MUTT_WRITE_HEADER_FCC 

fcc mode, like normal mode but for Bcc header

MUTT_WRITE_HEADER_POSTPONE 

A postponed Email, just the envelope info.

MUTT_WRITE_HEADER_EDITHDRS 

"light" mode (used for edit_hdrs)

MUTT_WRITE_HEADER_MIME 

Write protected headers.

Definition at line 58 of file sendlib.h.

59 {
65 };
A normal Email, write full header + MIME headers.
Definition: sendlib.h:60
A postponed Email, just the envelope info.
Definition: sendlib.h:62
"light" mode (used for edit_hdrs)
Definition: sendlib.h:63
fcc mode, like normal mode but for Bcc header
Definition: sendlib.h:61
Write protected headers.
Definition: sendlib.h:64

Function Documentation

◆ mutt_body_get_charset()

char* mutt_body_get_charset ( struct Body b,
char *  buf,
size_t  buflen 
)

Get a body's character set.

Parameters
bBody to examine
bufBuffer for the result
buflenLength of the buffer
Return values
ptrBuffer containing character set
NULLOn error, or if not a text type

Definition at line 1456 of file sendlib.c.

1457 {
1458  char *p = NULL;
1459 
1460  if (b && (b->type != TYPE_TEXT))
1461  return NULL;
1462 
1463  if (b)
1464  p = mutt_param_get(&b->parameter, "charset");
1465 
1466  if (p)
1467  mutt_ch_canonical_charset(buf, buflen, p);
1468  else
1469  mutt_str_strfcpy(buf, "us-ascii", buflen);
1470 
1471  return buf;
1472 }
void mutt_ch_canonical_charset(char *buf, size_t buflen, const char *name)
Canonicalise the charset of a string.
Definition: charset.c:344
Type: &#39;text/*&#39;.
Definition: mime.h:38
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:776
unsigned int type
content-type primary type
Definition: body.h:65
char * mutt_param_get(const struct ParameterList *pl, const char *s)
Find a matching Parameter.
Definition: parameter.c:84
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_bounce_message()

int mutt_bounce_message ( FILE *  fp,
struct Email e,
struct AddressList *  to 
)

Bounce an email message.

Parameters
fpHandle of message
eEmail
toAddressList to bounce to
Return values
0Success
-1Failure

Definition at line 3128 of file sendlib.c.

3129 {
3130  if (!fp || !e || !to || TAILQ_EMPTY(to))
3131  return -1;
3132 
3133  const char *fqdn = mutt_fqdn(true);
3134  char resent_from[256];
3135  char *err = NULL;
3136 
3137  resent_from[0] = '\0';
3138  struct Address *from = mutt_default_from();
3139  struct AddressList from_list = TAILQ_HEAD_INITIALIZER(from_list);
3140  mutt_addrlist_append(&from_list, from);
3141 
3142  /* mutt_default_from() does not use $realname if the real name is not set
3143  * in $from, so we add it here. The reason it is not added in
3144  * mutt_default_from() is that during normal sending, we execute
3145  * send-hooks and set the realname last so that it can be changed based
3146  * upon message criteria. */
3147  if (!from->personal)
3149 
3150  mutt_addrlist_qualify(&from_list, fqdn);
3151 
3152  rfc2047_encode_addrlist(&from_list, "Resent-From");
3153  if (mutt_addrlist_to_intl(&from_list, &err))
3154  {
3155  mutt_error(_("Bad IDN %s while preparing resent-from"), err);
3156  FREE(&err);
3157  mutt_addrlist_clear(&from_list);
3158  return -1;
3159  }
3160  mutt_addrlist_write(&from_list, resent_from, sizeof(resent_from), false);
3161 
3162 #ifdef USE_NNTP
3163  OptNewsSend = false;
3164 #endif
3165 
3166  /* prepare recipient list. idna conversion appears to happen before this
3167  * function is called, since the user receives confirmation of the address
3168  * list being bounced to. */
3169  struct AddressList resent_to = TAILQ_HEAD_INITIALIZER(resent_to);
3170  mutt_addrlist_copy(&resent_to, to, false);
3171  rfc2047_encode_addrlist(&resent_to, "Resent-To");
3172  int rc = bounce_message(fp, e, &resent_to, resent_from, &from_list);
3173  mutt_addrlist_clear(&resent_to);
3174  mutt_addrlist_clear(&from_list);
3175 
3176  return rc;
3177 }
static int bounce_message(FILE *fp, struct Email *e, struct AddressList *to, const char *resent_from, struct AddressList *env_from)
Bounce an email message.
Definition: sendlib.c:3066
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1412
void mutt_addrlist_copy(struct AddressList *dst, const struct AddressList *src, bool prune)
Copy a list of addresses into another list.
Definition: address.c:734
#define _(a)
Definition: message.h:28
An email address.
Definition: address.h:34
void rfc2047_encode_addrlist(struct AddressList *al, const char *tag)
Encode any RFC2047 headers, where required, in an Address list.
Definition: rfc2047.c:735
struct Address * mutt_default_from(void)
Get a default &#39;from&#39; Address.
Definition: send.c:1333
const char * mutt_fqdn(bool may_hide_host)
Get the Fully-Qualified Domain Name.
Definition: sendlib.c:2531
char * personal
Real name of address.
Definition: address.h:36
void mutt_addrlist_qualify(struct AddressList *al, const char *host)
Expand local names in an Address list using a hostname.
Definition: address.c:647
int mutt_addrlist_to_intl(struct AddressList *al, char **err)
Convert an Address list to Punycode.
Definition: address.c:1247
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
#define mutt_error(...)
Definition: logging.h:84
#define FREE(x)
Definition: memory.h:40
WHERE char * C_Realname
Config: Real name of the user.
Definition: globals.h:139
#define TAILQ_EMPTY(head)
Definition: queue.h:714
WHERE bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:47
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:630
size_t mutt_addrlist_write(const struct AddressList *al, char *buf, size_t buflen, bool display)
Write an Address to a buffer.
Definition: address.c:1144
void mutt_addrlist_append(struct AddressList *al, struct Address *a)
Append an Address to an AddressList.
Definition: address.c:1432
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_fqdn()

const char* mutt_fqdn ( bool  may_hide_host)

Get the Fully-Qualified Domain Name.

Parameters
may_hide_hostIf true, hide the hostname (leaving just the domain)
Return values
ptrstring pointer into Hostname
NULLError, e.g no Hostname
Warning
Do not free the returned pointer

Definition at line 2531 of file sendlib.c.

2532 {
2533  if (!C_Hostname || (C_Hostname[0] == '@'))
2534  return NULL;
2535 
2536  char *p = C_Hostname;
2537 
2538  if (may_hide_host && C_HiddenHost)
2539  {
2540  p = strchr(C_Hostname, '.');
2541  if (p)
2542  p++;
2543 
2544  // sanity check: don't hide the host if the fqdn is something like example.com
2545  if (!p || !strchr(p, '.'))
2546  p = C_Hostname;
2547  }
2548 
2549  return p;
2550 }
bool C_HiddenHost
Config: Don&#39;t use the hostname, just the domain, when generating the message id.
Definition: sendlib.c:85
WHERE char * C_Hostname
Config: Fully-qualified domain name of this machine.
Definition: globals.h:113
+ Here is the caller graph for this function:

◆ mutt_generate_boundary()

void mutt_generate_boundary ( struct ParameterList *  pl)

Create a unique boundary id for a MIME part.

Parameters
plMIME part

Definition at line 636 of file sendlib.c.

637 {
638  char rs[MUTT_RANDTAG_LEN + 1];
639 
640  mutt_rand_base32(rs, sizeof(rs) - 1);
641  rs[MUTT_RANDTAG_LEN] = 0;
642  mutt_param_set(pl, "boundary", rs);
643 }
#define MUTT_RANDTAG_LEN
Definition: sendlib.c:98
void mutt_rand_base32(void *buf, size_t buflen)
Fill a buffer with a base32-encoded random string.
Definition: muttlib.c:513
void mutt_param_set(struct ParameterList *pl, const char *attribute, const char *value)
Set a Parameter.
Definition: parameter.c:110
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_get_content_info()

struct Content* mutt_get_content_info ( const char *  fname,
struct Body b 
)

Analyze file to determine MIME encoding to use.

Parameters
fnameFile to examine
bBody to update
Return values
ptrNewly allocated Content

Also set the body charset, sometimes, or not.

Definition at line 1031 of file sendlib.c.

1032 {
1033  struct Content *info = NULL;
1034  struct ContentState state = { 0 };
1035  FILE *fp = NULL;
1036  char *fromcode = NULL;
1037  char *tocode = NULL;
1038  char buf[100];
1039  size_t r;
1040 
1041  struct stat sb;
1042 
1043  if (b && !fname)
1044  fname = b->filename;
1045 
1046  if (stat(fname, &sb) == -1)
1047  {
1048  mutt_error(_("Can't stat %s: %s"), fname, strerror(errno));
1049  return NULL;
1050  }
1051 
1052  if (!S_ISREG(sb.st_mode))
1053  {
1054  mutt_error(_("%s isn't a regular file"), fname);
1055  return NULL;
1056  }
1057 
1058  fp = fopen(fname, "r");
1059  if (!fp)
1060  {
1061  mutt_debug(LL_DEBUG1, "%s: %s (errno %d)\n", fname, strerror(errno), errno);
1062  return NULL;
1063  }
1064 
1065  info = mutt_mem_calloc(1, sizeof(struct Content));
1066 
1067  if (b && (b->type == TYPE_TEXT) && (!b->noconv && !b->force_charset))
1068  {
1069  char *chs = mutt_param_get(&b->parameter, "charset");
1070  char *fchs = b->use_disp ? (C_AttachCharset ? C_AttachCharset : C_Charset) : C_Charset;
1071  if (C_Charset && (chs || C_SendCharset) &&
1072  (convert_file_from_to(fp, fchs, chs ? chs : C_SendCharset, &fromcode,
1073  &tocode, info) != (size_t)(-1)))
1074  {
1075  if (!chs)
1076  {
1077  char chsbuf[256];
1078  mutt_ch_canonical_charset(chsbuf, sizeof(chsbuf), tocode);
1079  mutt_param_set(&b->parameter, "charset", chsbuf);
1080  }
1081  FREE(&b->charset);
1082  b->charset = fromcode;
1083  FREE(&tocode);
1084  mutt_file_fclose(&fp);
1085  return info;
1086  }
1087  }
1088 
1089  rewind(fp);
1090  while ((r = fread(buf, 1, sizeof(buf), fp)))
1091  update_content_info(info, &state, buf, r);
1092  update_content_info(info, &state, 0, 0);
1093 
1094  mutt_file_fclose(&fp);
1095 
1096  if (b && (b->type == TYPE_TEXT) && (!b->noconv && !b->force_charset))
1097  {
1098  mutt_param_set(&b->parameter, "charset",
1099  (!info->hibin ?
1100  "us-ascii" :
1101  C_Charset && !mutt_ch_is_us_ascii(C_Charset) ? C_Charset : "unknown-8bit"));
1102  }
1103 
1104  return info;
1105 }
Info about the body of an email.
Definition: sendlib.c:113
static void update_content_info(struct Content *info, struct ContentState *s, char *buf, size_t buflen)
Cache some info about an email.
Definition: sendlib.c:652
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
bool noconv
Don&#39;t do character set conversion.
Definition: body.h:73
#define _(a)
Definition: message.h:28
long hibin
8-bit characters
Definition: content.h:35
char * C_SendCharset
Config: Character sets for outgoing mail.
Definition: email_globals.c:38
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
bool force_charset
Send mode: don&#39;t adjust the character set when in send-mode.
Definition: body.h:74
void mutt_ch_canonical_charset(char *buf, size_t buflen, const char *name)
Canonicalise the charset of a string.
Definition: charset.c:344
#define mutt_ch_is_us_ascii(str)
Definition: charset.h:107
static char * chs
Definition: gnupgparse.c:72
Info about an attachment.
Definition: content.h:33
Type: &#39;text/*&#39;.
Definition: mime.h:38
char * C_AttachCharset
Config: When attaching files, use one of these character sets.
Definition: sendlib.c:81
char * charset
Send mode: charset of attached file as stored on disk.
Definition: body.h:49
unsigned int type
content-type primary type
Definition: body.h:65
Log at debug level 1.
Definition: logging.h:40
bool use_disp
Content-Disposition uses filename= ?
Definition: body.h:68
#define mutt_error(...)
Definition: logging.h:84
#define FREE(x)
Definition: memory.h:40
char * mutt_param_get(const struct ParameterList *pl, const char *s)
Find a matching Parameter.
Definition: parameter.c:84
char * C_Charset
Config: Default character set for displaying text on screen.
Definition: charset.c:53
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
void mutt_param_set(struct ParameterList *pl, const char *attribute, const char *value)
Set a Parameter.
Definition: parameter.c:110
static size_t convert_file_from_to(FILE *fp, const char *fromcodes, const char *tocodes, char **fromcode, char **tocode, struct Content *info)
Convert a file between encodings.
Definition: sendlib.c:952
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_invoke_sendmail()

int mutt_invoke_sendmail ( struct AddressList *  from,
struct AddressList *  to,
struct AddressList *  cc,
struct AddressList *  bcc,
const char *  msg,
int  eightbit 
)

Run sendmail.

Parameters
fromThe sender
toRecipients
ccRecipients
bccRecipients
msgFile containing message
eightbitMessage contains 8bit chars
Return values
0Success
-1Failure

Definition at line 2823 of file sendlib.c.

2826 {
2827  char *ps = NULL, *path = NULL, *s = NULL, *childout = NULL;
2828  char **args = NULL;
2829  size_t argslen = 0, argsmax = 0;
2830  char **extra_args = NULL;
2831  int i;
2832 
2833 #ifdef USE_NNTP
2834  if (OptNewsSend)
2835  {
2836  char cmd[1024];
2837 
2838  mutt_expando_format(cmd, sizeof(cmd), 0, sizeof(cmd), NONULL(C_Inews),
2840  if (!*cmd)
2841  {
2842  i = nntp_post(Context->mailbox, msg);
2843  unlink(msg);
2844  return i;
2845  }
2846 
2847  s = mutt_str_strdup(cmd);
2848  }
2849  else
2850 #endif
2852 
2853  /* ensure that $sendmail is set to avoid a crash. http://dev.mutt.org/trac/ticket/3548 */
2854  if (!s)
2855  {
2856  mutt_error(_("$sendmail must be set in order to send mail"));
2857  return -1;
2858  }
2859 
2860  ps = s;
2861  i = 0;
2862  while ((ps = strtok(ps, " ")))
2863  {
2864  if (argslen == argsmax)
2865  mutt_mem_realloc(&args, sizeof(char *) * (argsmax += 5));
2866 
2867  if (i)
2868  {
2869  if (mutt_str_strcmp(ps, "--") == 0)
2870  break;
2871  args[argslen++] = ps;
2872  }
2873  else
2874  {
2875  path = mutt_str_strdup(ps);
2876  ps = strrchr(ps, '/');
2877  if (ps)
2878  ps++;
2879  else
2880  ps = path;
2881  args[argslen++] = ps;
2882  }
2883  ps = NULL;
2884  i++;
2885  }
2886 
2887 #ifdef USE_NNTP
2888  if (!OptNewsSend)
2889  {
2890 #endif
2891  size_t extra_argslen = 0;
2892  /* If C_Sendmail contained a "--", we save the recipients to append to
2893  * args after other possible options added below. */
2894  if (ps)
2895  {
2896  ps = NULL;
2897  size_t extra_argsmax = 0;
2898  while ((ps = strtok(ps, " ")))
2899  {
2900  if (extra_argslen == extra_argsmax)
2901  mutt_mem_realloc(&extra_args, sizeof(char *) * (extra_argsmax += 5));
2902 
2903  extra_args[extra_argslen++] = ps;
2904  ps = NULL;
2905  }
2906  }
2907 
2908  if (eightbit && C_Use8bitmime)
2909  args = add_option(args, &argslen, &argsmax, "-B8BITMIME");
2910 
2911  if (C_UseEnvelopeFrom)
2912  {
2914  {
2915  args = add_option(args, &argslen, &argsmax, "-f");
2916  args = add_args_one(args, &argslen, &argsmax, C_EnvelopeFromAddress);
2917  }
2918  else if (!TAILQ_EMPTY(from) && !TAILQ_NEXT(TAILQ_FIRST(from), entries))
2919  {
2920  args = add_option(args, &argslen, &argsmax, "-f");
2921  args = add_args(args, &argslen, &argsmax, from);
2922  }
2923  }
2924 
2925  if (C_DsnNotify)
2926  {
2927  args = add_option(args, &argslen, &argsmax, "-N");
2928  args = add_option(args, &argslen, &argsmax, C_DsnNotify);
2929  }
2930  if (C_DsnReturn)
2931  {
2932  args = add_option(args, &argslen, &argsmax, "-R");
2933  args = add_option(args, &argslen, &argsmax, C_DsnReturn);
2934  }
2935  args = add_option(args, &argslen, &argsmax, "--");
2936  for (i = 0; i < extra_argslen; i++)
2937  args = add_option(args, &argslen, &argsmax, extra_args[i]);
2938  args = add_args(args, &argslen, &argsmax, to);
2939  args = add_args(args, &argslen, &argsmax, cc);
2940  args = add_args(args, &argslen, &argsmax, bcc);
2941 #ifdef USE_NNTP
2942  }
2943 #endif
2944 
2945  if (argslen == argsmax)
2946  mutt_mem_realloc(&args, sizeof(char *) * (++argsmax));
2947 
2948  args[argslen++] = NULL;
2949 
2950  /* Some user's $sendmail command uses gpg for password decryption,
2951  * and is set up to prompt using ncurses pinentry. If we
2952  * mutt_endwin() it leaves other users staring at a blank screen.
2953  * So instead, just force a hard redraw on the next refresh. */
2954  if (!OptNoCurses)
2956 
2957  i = send_msg(path, args, msg, OptNoCurses ? NULL : &childout);
2958  if (i != (EX_OK & 0xff))
2959  {
2960  if (i != S_BKG)
2961  {
2962  const char *e = mutt_str_sysexit(i);
2963  mutt_error(_("Error sending message, child exited %d (%s)"), i, NONULL(e));
2964  if (childout)
2965  {
2966  struct stat st;
2967 
2968  if ((stat(childout, &st) == 0) && (st.st_size > 0))
2969  {
2970  mutt_do_pager(_("Output of the delivery process"), childout,
2971  MUTT_PAGER_NO_FLAGS, NULL);
2972  }
2973  }
2974  }
2975  }
2976  else if (childout)
2977  unlink(childout);
2978 
2979  FREE(&childout);
2980  FREE(&path);
2981  FREE(&s);
2982  FREE(&args);
2983  FREE(&extra_args);
2984 
2985  if (i == (EX_OK & 0xff))
2986  i = 0;
2987  else if (i == S_BKG)
2988  i = 1;
2989  else
2990  i = -1;
2991  return i;
2992 }
The "current" mailbox.
Definition: context.h:37
void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t *callback, unsigned long data, MuttFormatFlags flags)
Expand expandos (x) in a string.
Definition: muttlib.c:862
char * C_Sendmail
Config: External command to send email.
Definition: sendlib.c:91
#define NONULL(x)
Definition: string2.h:37
static int send_msg(const char *path, char **args, const char *msg, char **tempfile)
invoke sendmail in a subshell
Definition: sendlib.c:2596
#define TAILQ_FIRST(head)
Definition: queue.h:716
static char ** add_args(char **args, size_t *argslen, size_t *argsmax, struct AddressList *al)
Add a list of Addresses to a dynamic array.
Definition: sendlib.c:2781
#define _(a)
Definition: message.h:28
WHERE bool OptNoCurses
(pseudo) when sending in batch mode
Definition: options.h:49
#define S_BKG
Definition: string2.h:43
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: format_flags.h:30
bool C_Use8bitmime
Config: Use 8-bit messages and ESMTP to send messages.
Definition: sendlib.c:93
struct Mailbox * mailbox
Definition: context.h:51
char * C_Inews
Config: (nntp) External command to post news articles.
Definition: sendlib.c:86
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
const char * mutt_str_sysexit(int err_num)
Return a string matching an error code.
Definition: string.c:117
static char ** add_option(char **args, size_t *argslen, size_t *argsmax, char *s)
Add a string to a dynamic array.
Definition: sendlib.c:2804
bool C_UseEnvelopeFrom
Config: Set the envelope sender of the message.
Definition: sendlib.c:94
int nntp_post(struct Mailbox *m, const char *msg)
Post article.
Definition: nntp.c:1976
const char * nntp_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, unsigned long data, MuttFormatFlags flags)
Expand the newsrc filename - Implements format_t.
Definition: newsrc.c:922
WHERE char * C_DsnReturn
Config: What to send as a notification of message delivery or delay.
Definition: globals.h:110
int mutt_do_pager(const char *banner, const char *tempfile, PagerFlags do_color, struct Pager *info)
Display some page-able text to the user.
Definition: curs_lib.c:665
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
#define mutt_error(...)
Definition: logging.h:84
WHERE struct Address * C_EnvelopeFromAddress
Config: Manually set the sender for outgoing messages.
Definition: globals.h:93
#define FREE(x)
Definition: memory.h:40
#define TAILQ_NEXT(elm, field)
Definition: queue.h:825
#define TAILQ_EMPTY(head)
Definition: queue.h:714
va_list args
Definition: acutest.h:715
WHERE bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:47
void mutt_need_hard_redraw(void)
Force a hard refresh.
Definition: curs_lib.c:128
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:641
WHERE char * C_DsnNotify
Config: Request notification for message delivery or delay.
Definition: globals.h:109
static char ** add_args_one(char **args, size_t *argslen, size_t *argsmax, struct Address *addr)
Add an Address to a dynamic array.
Definition: sendlib.c:2761
#define EX_OK
Definition: sendlib.c:73
#define MUTT_PAGER_NO_FLAGS
No flags are set.
Definition: pager.h:43
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_lookup_mime_type()

enum ContentType mutt_lookup_mime_type ( struct Body att,
const char *  path 
)

Find the MIME type for an attachment.

Parameters
attEmail with attachment
pathPath to attachment
Return values
numMIME type, e.g. TYPE_IMAGE

Given a file at 'path', see if there is a registered MIME type. Returns the major MIME type, and copies the subtype to "d". First look in a system mime.types if we can find one, then look for ~/.mime.types. The longest match is used so that we can match 'ps.gz' when 'gz' also exists.

Definition at line 1119 of file sendlib.c.

1120 {
1121  FILE *fp = NULL;
1122  char *p = NULL, *q = NULL, *ct = NULL;
1123  char buf[PATH_MAX];
1124  char subtype[256] = { 0 };
1125  char xtype[256] = { 0 };
1126  int sze, cur_sze = 0;
1127  bool found_mimetypes = false;
1128  enum ContentType type = TYPE_OTHER;
1129 
1130  int szf = mutt_str_strlen(path);
1131 
1132  for (int count = 0; count < 4; count++)
1133  {
1134  /* can't use strtok() because we use it in an inner loop below, so use
1135  * a switch statement here instead. */
1136  switch (count)
1137  {
1138  /* last file with last entry to match wins type/xtype */
1139  case 0:
1140  /* check default unix mimetypes location first */
1141  mutt_str_strfcpy(buf, "/etc/mime.types", sizeof(buf));
1142  break;
1143  case 1:
1144  mutt_str_strfcpy(buf, SYSCONFDIR "/mime.types", sizeof(buf));
1145  break;
1146  case 2:
1147  mutt_str_strfcpy(buf, PKGDATADIR "/mime.types", sizeof(buf));
1148  break;
1149  case 3:
1150  snprintf(buf, sizeof(buf), "%s/.mime.types", NONULL(HomeDir));
1151  break;
1152  default:
1153  mutt_debug(LL_DEBUG1, "Internal error, count = %d\n", count);
1154  goto bye; /* shouldn't happen */
1155  }
1156 
1157  fp = fopen(buf, "r");
1158  if (fp)
1159  {
1160  found_mimetypes = true;
1161 
1162  while (fgets(buf, sizeof(buf) - 1, fp))
1163  {
1164  /* weed out any comments */
1165  p = strchr(buf, '#');
1166  if (p)
1167  *p = '\0';
1168 
1169  /* remove any leading space. */
1170  ct = buf;
1171  SKIPWS(ct);
1172 
1173  /* position on the next field in this line */
1174  p = strpbrk(ct, " \t");
1175  if (!p)
1176  continue;
1177  *p++ = 0;
1178  SKIPWS(p);
1179 
1180  /* cycle through the file extensions */
1181  while ((p = strtok(p, " \t\n")))
1182  {
1183  sze = mutt_str_strlen(p);
1184  if ((sze > cur_sze) && (szf >= sze) &&
1185  (mutt_str_strcasecmp(path + szf - sze, p) == 0) &&
1186  ((szf == sze) || (path[szf - sze - 1] == '.')))
1187  {
1188  /* get the content-type */
1189 
1190  p = strchr(ct, '/');
1191  if (!p)
1192  {
1193  /* malformed line, just skip it. */
1194  break;
1195  }
1196  *p++ = 0;
1197 
1198  for (q = p; *q && !IS_SPACE(*q); q++)
1199  ;
1200 
1201  mutt_str_substr_copy(p, q, subtype, sizeof(subtype));
1202 
1203  type = mutt_check_mime_type(ct);
1204  if (type == TYPE_OTHER)
1205  mutt_str_strfcpy(xtype, ct, sizeof(xtype));
1206 
1207  cur_sze = sze;
1208  }
1209  p = NULL;
1210  }
1211  }
1212  mutt_file_fclose(&fp);
1213  }
1214  }
1215 
1216 bye:
1217 
1218  /* no mime.types file found */
1219  if (!found_mimetypes)
1220  {
1221  mutt_error(_("Could not find any mime.types file."));
1222  }
1223 
1224  if ((type != TYPE_OTHER) || (*xtype != '\0'))
1225  {
1226  att->type = type;
1227  mutt_str_replace(&att->subtype, subtype);
1228  mutt_str_replace(&att->xtype, xtype);
1229  }
1230 
1231  return type;
1232 }
Unknown Content-Type.
Definition: mime.h:31
#define NONULL(x)
Definition: string2.h:37
#define _(a)
Definition: message.h:28
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:692
char * HomeDir
User&#39;s home directory.
Definition: globals.h:49
enum ContentType mutt_check_mime_type(const char *s)
Check a MIME type string.
Definition: parse.c:318
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
#define SKIPWS(ch)
Definition: string2.h:47
char * subtype
content-type subtype
Definition: body.h:37
#define PATH_MAX
Definition: mutt.h:44
char * xtype
content-type if x-unknown
Definition: body.h:36
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:776
void mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:455
unsigned int type
content-type primary type
Definition: body.h:65
#define IS_SPACE(ch)
Definition: string2.h:38
Log at debug level 1.
Definition: logging.h:40
#define mutt_error(...)
Definition: logging.h:84
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:654
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
ContentType
Content-Type.
Definition: mime.h:29
char * mutt_str_substr_copy(const char *begin, const char *end, char *buf, size_t buflen)
Copy a sub-string into a buffer.
Definition: string.c:582
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_make_file_attach()

struct Body* mutt_make_file_attach ( const char *  path)

Create a file attachment.

Parameters
pathFile to attach
Return values
ptrNewly allocated Body
NULLError

Definition at line 1650 of file sendlib.c.

1651 {
1652  struct Body *att = mutt_body_new();
1653  att->filename = mutt_str_strdup(path);
1654 
1656  run_mime_type_query(att);
1657 
1658  /* Attempt to determine the appropriate content-type based on the filename
1659  * suffix. */
1660  if (!att->subtype)
1661  mutt_lookup_mime_type(att, path);
1662 
1664  {
1665  run_mime_type_query(att);
1666  }
1667 
1668  struct Content *info = mutt_get_content_info(path, att);
1669  if (!info)
1670  {
1671  mutt_body_free(&att);
1672  return NULL;
1673  }
1674 
1675  if (!att->subtype)
1676  {
1677  if ((info->nulbin == 0) &&
1678  ((info->lobin == 0) || ((info->lobin + info->hibin + info->ascii) / info->lobin >= 10)))
1679  {
1680  /* Statistically speaking, there should be more than 10% "lobin"
1681  * chars if this is really a binary file... */
1682  att->type = TYPE_TEXT;
1683  att->subtype = mutt_str_strdup("plain");
1684  }
1685  else
1686  {
1687  att->type = TYPE_APPLICATION;
1688  att->subtype = mutt_str_strdup("octet-stream");
1689  }
1690  }
1691 
1692  FREE(&info);
1693  mutt_update_encoding(att);
1694  return att;
1695 }
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
static void run_mime_type_query(struct Body *att)
Run an external command to determine the MIME type.
Definition: sendlib.c:1611
long hibin
8-bit characters
Definition: content.h:35
The body of an email.
Definition: body.h:34
struct Content * mutt_get_content_info(const char *fname, struct Body *b)
Analyze file to determine MIME encoding to use.
Definition: sendlib.c:1031
struct Body * mutt_body_new(void)
Create a new Body.
Definition: body.c:43
void mutt_update_encoding(struct Body *a)
Update the encoding type.
Definition: sendlib.c:1480
char * subtype
content-type subtype
Definition: body.h:37
Info about an attachment.
Definition: content.h:33
long ascii
Number of ascii chars.
Definition: content.h:39
Type: &#39;text/*&#39;.
Definition: mime.h:38
unsigned int type
content-type primary type
Definition: body.h:65
long lobin
Unprintable 7-bit chars (eg., control chars)
Definition: content.h:36
enum ContentType mutt_lookup_mime_type(struct Body *att, const char *path)
Find the MIME type for an attachment.
Definition: sendlib.c:1119
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
char * C_MimeTypeQueryCommand
Config: External command to determine the MIME type of an attachment.
Definition: sendlib.c:89
#define FREE(x)
Definition: memory.h:40
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
long nulbin
Null characters (0x0)
Definition: content.h:37
Type: &#39;application/*&#39;.
Definition: mime.h:33
bool C_MimeTypeQueryFirst
Config: Run the C_MimeTypeQueryCommand before the mime.types lookup.
Definition: sendlib.c:90
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_make_message_attach()

struct Body* mutt_make_message_attach ( struct Mailbox m,
struct Email e,
bool  attach_msg 
)

Create a message attachment.

Parameters
mMailbox
eEmail
attach_msgtrue if attaching a message
Return values
ptrNewly allocated Body
NULLError

Definition at line 1511 of file sendlib.c.

1512 {
1513  struct Body *body = NULL;
1514  FILE *fp = NULL;
1515  CopyMessageFlags cmflags;
1517 
1518  if (WithCrypto)
1519  {
1521  {
1523  return NULL;
1524  }
1525  }
1526 
1527  struct Buffer *buf = mutt_buffer_pool_get();
1528  mutt_buffer_mktemp(buf);
1529  fp = mutt_file_fopen(mutt_b2s(buf), "w+");
1530  if (!fp)
1531  {
1533  return NULL;
1534  }
1535 
1536  body = mutt_body_new();
1537  body->type = TYPE_MESSAGE;
1538  body->subtype = mutt_str_strdup("rfc822");
1539  body->filename = mutt_str_strdup(mutt_b2s(buf));
1540  body->unlink = true;
1541  body->use_disp = false;
1542  body->disposition = DISP_INLINE;
1543  body->noconv = true;
1544 
1546 
1548 
1549  CopyHeaderFlags chflags = CH_XMIT;
1550  cmflags = MUTT_CM_NO_FLAGS;
1551 
1552  /* If we are attaching a message, ignore C_MimeForwardDecode */
1553  if (!attach_msg && C_MimeForwardDecode)
1554  {
1555  chflags |= CH_MIME | CH_TXTPLAIN;
1556  cmflags = MUTT_CM_DECODE | MUTT_CM_CHARCONV;
1558  pgp &= ~PGP_ENCRYPT;
1560  pgp &= ~SMIME_ENCRYPT;
1561  }
1562  else if ((WithCrypto != 0) && C_ForwardDecrypt && (e->security & SEC_ENCRYPT))
1563  {
1564  if (((WithCrypto & APPLICATION_PGP) != 0) && mutt_is_multipart_encrypted(e->content))
1565  {
1566  chflags |= CH_MIME | CH_NONEWLINE;
1567  cmflags = MUTT_CM_DECODE_PGP;
1568  pgp &= ~PGP_ENCRYPT;
1569  }
1570  else if (((WithCrypto & APPLICATION_PGP) != 0) &&
1572  {
1573  chflags |= CH_MIME | CH_TXTPLAIN;
1574  cmflags = MUTT_CM_DECODE | MUTT_CM_CHARCONV;
1575  pgp &= ~PGP_ENCRYPT;
1576  }
1577  else if (((WithCrypto & APPLICATION_SMIME) != 0) &&
1579  {
1580  chflags |= CH_MIME | CH_TXTPLAIN;
1581  cmflags = MUTT_CM_DECODE | MUTT_CM_CHARCONV;
1582  pgp &= ~SMIME_ENCRYPT;
1583  }
1584  }
1585 
1586  mutt_copy_message(fp, m, e, cmflags, chflags, 0);
1587 
1588  fflush(fp);
1589  rewind(fp);
1590 
1591  body->email = email_new();
1592  body->email->offset = 0;
1593  /* we don't need the user headers here */
1594  body->email->env = mutt_rfc822_read_header(fp, body->email, false, false);
1595  if (WithCrypto)
1596  body->email->security = pgp;
1597  mutt_update_encoding(body);
1598  body->parts = body->email->content;
1599 
1600  mutt_file_fclose(&fp);
1601 
1602  return body;
1603 }
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:81
#define CH_MIME
Ignore MIME fields.
Definition: copy.h:60
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
#define WithCrypto
Definition: lib.h:163
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
bool C_MimeForwardDecode
Config: Decode the forwarded message before attaching it.
Definition: sendlib.c:87
#define SEC_NO_FLAGS
No flags are set.
Definition: lib.h:124
#define SMIME_ENCRYPT
Definition: lib.h:149
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:125
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
struct Body * content
List of MIME parts.
Definition: email.h:90
bool noconv
Don&#39;t do character set conversion.
Definition: body.h:73
#define PGP_ENCRYPT
Definition: lib.h:143
String manipulation buffer.
Definition: buffer.h:33
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e)
Parse a MIME email.
Definition: mutt_parse.c:48
int mutt_copy_message(FILE *fp_out, struct Mailbox *m, struct Email *e, CopyMessageFlags cmflags, CopyHeaderFlags chflags, int wraplen)
Copy a message from a Mailbox.
Definition: copy.c:812
uint16_t SecurityFlags
Flags, e.g. SEC_ENCRYPT.
Definition: lib.h:123
uint16_t CopyMessageFlags
Flags for mutt_copy_message(), e.g. MUTT_CM_NOHEADER.
Definition: copy.h:31
#define MUTT_CM_NO_FLAGS
No flags are set.
Definition: copy.h:34
The body of an email.
Definition: body.h:34
unsigned int disposition
content-disposition
Definition: body.h:67
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:146
struct Body * mutt_body_new(void)
Create a new Body.
Definition: body.c:43
SecurityFlags mutt_is_multipart_encrypted(struct Body *b)
Does the message have encrypted parts?
Definition: crypt.c:459
void mutt_update_encoding(struct Body *a)
Update the encoding type.
Definition: sendlib.c:1480
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
struct Envelope * env
Envelope information.
Definition: email.h:89
char * subtype
content-type subtype
Definition: body.h:37
#define CH_TXTPLAIN
Generate text/plain MIME headers.
Definition: copy.h:62
#define mutt_b2s(buf)
Definition: buffer.h:41
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:138
SecurityFlags mutt_is_application_pgp(struct Body *m)
Does the message use PGP?
Definition: crypt.c:565
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:137
#define MUTT_CM_DECODE
Decode the message body into text/plain.
Definition: copy.h:37
bool C_ForwardDecrypt
Config: Decrypt the message when forwarding it.
Definition: sendlib.c:84
#define MUTT_CM_CHARCONV
Perform character set conversions.
Definition: copy.h:41
#define CH_XMIT
Transmitting this message? (Ignore Lines: and Content-Length:)
Definition: copy.h:54
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
SecurityFlags mutt_is_application_smime(struct Body *m)
Does the message use S/MIME?
Definition: crypt.c:624
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
Definition: email.h:39
unsigned int type
content-type primary type
Definition: body.h:65
LOFF_T offset
Where in the stream does this message begin?
Definition: email.h:83
Type: &#39;message/*&#39;.
Definition: mime.h:35
bool use_disp
Content-Disposition uses filename= ?
Definition: body.h:68
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
uint32_t CopyHeaderFlags
Flags for mutt_copy_header(), e.g. CH_UPDATE.
Definition: copy.h:49
bool unlink
If true, filename should be unlink()ed before free()ing this structure.
Definition: body.h:69
#define MUTT_CM_DECODE_PGP
Used for decoding PGP messages.
Definition: copy.h:44
struct Email * email_new(void)
Create a new Email.
Definition: email.c:68
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:588
Content is inline.
Definition: mime.h:62
struct Envelope * mutt_rfc822_read_header(FILE *fp, struct Email *e, bool user_hdrs, bool weed)
parses an RFC822 header
Definition: parse.c:1137
struct Email * email
header information for message/rfc822
Definition: body.h:55
#define CH_NONEWLINE
Don&#39;t output terminating newline after the header.
Definition: copy.h:59
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_make_multipart()

struct Body* mutt_make_multipart ( struct Body b)

Create a multipart email.

Parameters
bBody of email to start
Return values
ptrNewly allocated Body

Definition at line 1746 of file sendlib.c.

1747 {
1748  struct Body *new_body = mutt_body_new();
1749  new_body->type = TYPE_MULTIPART;
1750  new_body->subtype = mutt_str_strdup("mixed");
1751  new_body->encoding = get_toplevel_encoding(b);
1752  do
1753  {
1754  mutt_generate_boundary(&new_body->parameter);
1755  if (check_boundary(mutt_param_get(&new_body->parameter, "boundary"), b))
1756  mutt_param_delete(&new_body->parameter, "boundary");
1757  } while (!mutt_param_get(&new_body->parameter, "boundary"));
1758  new_body->use_disp = false;
1759  new_body->disposition = DISP_INLINE;
1760  new_body->parts = b;
1761 
1762  return new_body;
1763 }
static int get_toplevel_encoding(struct Body *a)
Find the most restrictive encoding type.
Definition: sendlib.c:1702
The body of an email.
Definition: body.h:34
unsigned int disposition
content-disposition
Definition: body.h:67
struct Body * mutt_body_new(void)
Create a new Body.
Definition: body.c:43
void mutt_generate_boundary(struct ParameterList *pl)
Create a unique boundary id for a MIME part.
Definition: sendlib.c:636
static bool check_boundary(const char *boundary, struct Body *b)
check for duplicate boundary
Definition: sendlib.c:1723
unsigned int encoding
content-transfer-encoding
Definition: body.h:66
char * subtype
content-type subtype
Definition: body.h:37
void mutt_param_delete(struct ParameterList *pl, const char *attribute)
Delete a matching Parameter.
Definition: parameter.c:142
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
unsigned int type
content-type primary type
Definition: body.h:65
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
bool use_disp
Content-Disposition uses filename= ?
Definition: body.h:68
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
char * mutt_param_get(const struct ParameterList *pl, const char *s)
Find a matching Parameter.
Definition: parameter.c:84
Content is inline.
Definition: mime.h:62
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_message_to_7bit()

void mutt_message_to_7bit ( struct Body a,
FILE *  fp 
)

Convert an email's MIME parts to 7-bit.

Parameters
aBody of the email
fpFile to read (OPTIONAL)

Definition at line 1301 of file sendlib.c.

1302 {
1303  struct Buffer temp = mutt_buffer_make(0);
1304  FILE *fp_in = NULL;
1305  FILE *fp_out = NULL;
1306  struct stat sb;
1307 
1308  if (!a->filename && fp)
1309  fp_in = fp;
1310  else if (!a->filename || !(fp_in = fopen(a->filename, "r")))
1311  {
1312  mutt_error(_("Could not open %s"), a->filename ? a->filename : "(null)");
1313  return;
1314  }
1315  else
1316  {
1317  a->offset = 0;
1318  if (stat(a->filename, &sb) == -1)
1319  {
1320  mutt_perror("stat");
1321  mutt_file_fclose(&fp_in);
1322  goto cleanup;
1323  }
1324  a->length = sb.st_size;
1325  }
1326 
1327  /* Avoid buffer pool due to recursion */
1328  mutt_buffer_mktemp(&temp);
1329  fp_out = mutt_file_fopen(mutt_b2s(&temp), "w+");
1330  if (!fp_out)
1331  {
1332  mutt_perror("fopen");
1333  goto cleanup;
1334  }
1335 
1336  fseeko(fp_in, a->offset, SEEK_SET);
1337  a->parts = mutt_rfc822_parse_message(fp_in, a);
1338 
1339  transform_to_7bit(a->parts, fp_in);
1340 
1341  mutt_copy_hdr(fp_in, fp_out, a->offset, a->offset + a->length,
1342  CH_MIME | CH_NONEWLINE | CH_XMIT, NULL, 0);
1343 
1344  fputs("MIME-Version: 1.0\n", fp_out);
1345  mutt_write_mime_header(a->parts, fp_out);
1346  fputc('\n', fp_out);
1347  mutt_write_mime_body(a->parts, fp_out);
1348 
1349  if (fp_in != fp)
1350  mutt_file_fclose(&fp_in);
1351  mutt_file_fclose(&fp_out);
1352 
1353  a->encoding = ENC_7BIT;
1354  FREE(&a->d_filename);
1355  a->d_filename = a->filename;
1356  if (a->filename && a->unlink)
1357  unlink(a->filename);
1358  a->filename = mutt_buffer_strdup(&temp);
1359  a->unlink = true;
1360  if (stat(a->filename, &sb) == -1)
1361  {
1362  mutt_perror("stat");
1363  goto cleanup;
1364  }
1365  a->length = sb.st_size;
1366  mutt_body_free(&a->parts);
1367  a->email->content = NULL;
1368 
1369 cleanup:
1370  if (fp_in && (fp_in != fp))
1371  mutt_file_fclose(&fp_in);
1372 
1373  if (fp_out)
1374  {
1375  mutt_file_fclose(&fp_out);
1376  mutt_file_unlink(mutt_b2s(&temp));
1377  }
1378 
1379  mutt_buffer_dealloc(&temp);
1380 }
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:81
#define CH_MIME
Ignore MIME fields.
Definition: copy.h:60
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
#define mutt_perror(...)
Definition: logging.h:85
7-bit text
Definition: mime.h:49
struct Body * content
List of MIME parts.
Definition: email.h:90
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:195
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
char * mutt_buffer_strdup(struct Buffer *buf)
Copy a Buffer&#39;s string.
Definition: buffer.c:432
String manipulation buffer.
Definition: buffer.h:33
LOFF_T offset
offset where the actual data begins
Definition: body.h:44
#define _(a)
Definition: message.h:28
static void transform_to_7bit(struct Body *a, FILE *fp_in)
Convert MIME parts to 7-bit.
Definition: sendlib.c:1239
struct Body * mutt_rfc822_parse_message(FILE *fp, struct Body *parent)
parse a Message/RFC822 body
Definition: parse.c:1575
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
unsigned int encoding
content-transfer-encoding
Definition: body.h:66
#define mutt_b2s(buf)
Definition: buffer.h:41
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
int mutt_write_mime_body(struct Body *a, FILE *fp)
Write a MIME part.
Definition: sendlib.c:553
#define CH_XMIT
Transmitting this message? (Ignore Lines: and Content-Length:)
Definition: copy.h:54
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
#define mutt_error(...)
Definition: logging.h:84
bool unlink
If true, filename should be unlink()ed before free()ing this structure.
Definition: body.h:69
int mutt_copy_hdr(FILE *fp_in, FILE *fp_out, LOFF_T off_start, LOFF_T off_end, CopyHeaderFlags chflags, const char *prefix, int wraplen)
Copy header from one file to another.
Definition: copy.c:77
#define FREE(x)
Definition: memory.h:40
int mutt_write_mime_header(struct Body *a, FILE *fp)
Create a MIME header.
Definition: sendlib.c:395
char * d_filename
filename to be used for the content-disposition header.
Definition: body.h:47
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:588
struct Email * email
header information for message/rfc822
Definition: body.h:55
#define CH_NONEWLINE
Don&#39;t output terminating newline after the header.
Definition: copy.h:59
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_prepare_envelope()

void mutt_prepare_envelope ( struct Envelope env,
bool  final 
)

Prepare an email header.

Parameters
envEnvelope to prepare
finaltrue if this email is going to be sent (not postponed)

Encode all the headers prior to sending the email.

For postponing (!final) do the necessary encodings only

Definition at line 3003 of file sendlib.c.

3004 {
3005  if (final)
3006  {
3007  if (!TAILQ_EMPTY(&env->bcc) && TAILQ_EMPTY(&env->to) && TAILQ_EMPTY(&env->cc))
3008  {
3009  /* some MTA's will put an Apparently-To: header field showing the Bcc:
3010  * recipients if there is no To: or Cc: field, so attempt to suppress
3011  * it by using an empty To: field. */
3012  struct Address *to = mutt_addr_new();
3013  to->group = true;
3014  mutt_addrlist_append(&env->to, to);
3016 
3017  char buf[1024];
3018  buf[0] = '\0';
3019  mutt_addr_cat(buf, sizeof(buf), "undisclosed-recipients", AddressSpecials);
3020 
3021  to->mailbox = mutt_str_strdup(buf);
3022  }
3023 
3024  mutt_set_followup_to(env);
3025 
3026  if (!env->message_id)
3027  env->message_id = gen_msgid();
3028  }
3029 
3030  /* Take care of 8-bit => 7-bit conversion. */
3032  encode_headers(&env->userhdrs);
3033 }
void rfc2047_encode_envelope(struct Envelope *env)
Encode the fields of an Envelope.
Definition: rfc2047.c:796
static char * gen_msgid(void)
Generate a unique Message ID.
Definition: sendlib.c:2558
const char AddressSpecials[]
Characters with special meaning for email addresses.
Definition: address.c:42
struct AddressList bcc
Email&#39;s &#39;Bcc&#39; list.
Definition: envelope.h:60
struct ListHead userhdrs
user defined headers
Definition: envelope.h:83
struct Address * mutt_addr_new(void)
Create a new Address.
Definition: address.c:385
An email address.
Definition: address.h:34
char * mailbox
Mailbox and host address.
Definition: address.h:37
char * message_id
Message ID.
Definition: envelope.h:69
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
void mutt_set_followup_to(struct Envelope *env)
Set followup-to field.
Definition: send.c:1213
bool group
Group mailbox?
Definition: address.h:38
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
#define TAILQ_EMPTY(head)
Definition: queue.h:714
void mutt_addr_cat(char *buf, size_t buflen, const char *value, const char *specials)
Copy a string and wrap it in quotes if it contains special characters.
Definition: address.c:678
static void encode_headers(struct ListHead *h)
RFC2047-encode a list of headers.
Definition: sendlib.c:2494
void mutt_addrlist_append(struct AddressList *al, struct Address *a)
Append an Address to an AddressList.
Definition: address.c:1432
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_remove_multipart()

struct Body* mutt_remove_multipart ( struct Body b)

Extract the multipart body if it exists.

Parameters
bBody to alter
Return values
ptrThe parts of the Body
Note
The original Body is freed

Definition at line 1772 of file sendlib.c.

1773 {
1774  struct Body *t = NULL;
1775 
1776  if (b->parts)
1777  {
1778  t = b;
1779  b = b->parts;
1780  t->parts = NULL;
1781  mutt_body_free(&t);
1782  }
1783  return b;
1784 }
The body of an email.
Definition: body.h:34
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_rfc822_write_header()

int mutt_rfc822_write_header ( FILE *  fp,
struct Envelope env,
struct Body attach,
enum MuttWriteHeaderMode  mode,
bool  privacy,
bool  hide_protected_subject 
)

Write out one RFC822 header line.

Parameters
fpFile to write to
envEnvelope of email
attachAttachment
modeMode, see MuttWriteHeaderMode
privacyIf true, remove headers that might identify the user
hide_protected_subjectIf true, replace subject header
Return values
0Success
-1Failure
Note
All RFC2047 encoding should be done outside of this routine, except for the "real name." This will allow this routine to be used more than once, if necessary.

Likewise, all IDN processing should happen outside of this routine.

privacy true => will omit any headers which may identify the user. Output generated is suitable for being sent through anonymous remailer chains.

hide_protected_subject: replaces the Subject header with $crypt_protected_headers_subject in NORMAL or POSTPONE mode.

Definition at line 2325 of file sendlib.c.

2328 {
2329  char buf[1024];
2330 
2331  if (((mode == MUTT_WRITE_HEADER_NORMAL) || (mode == MUTT_WRITE_HEADER_FCC)) && !privacy)
2332  fputs(mutt_date_make_date(buf, sizeof(buf)), fp);
2333 
2334  /* UseFrom is not consulted here so that we can still write a From:
2335  * field if the user sets it with the 'my_hdr' command */
2336  if (!TAILQ_EMPTY(&env->from) && !privacy)
2337  {
2338  buf[0] = '\0';
2339  mutt_addrlist_write(&env->from, buf, sizeof(buf), false);
2340  fprintf(fp, "From: %s\n", buf);
2341  }
2342 
2343  if (!TAILQ_EMPTY(&env->sender) && !privacy)
2344  {
2345  buf[0] = '\0';
2346  mutt_addrlist_write(&env->sender, buf, sizeof(buf), false);
2347  fprintf(fp, "Sender: %s\n", buf);
2348  }
2349 
2350  if (!TAILQ_EMPTY(&env->to))
2351  {
2352  fputs("To: ", fp);
2353  mutt_write_addrlist(&env->to, fp, 4, 0);
2354  }
2355  else if (mode == MUTT_WRITE_HEADER_EDITHDRS)
2356 #ifdef USE_NNTP
2357  if (!OptNewsSend)
2358 #endif
2359  fputs("To:\n", fp);
2360 
2361  if (!TAILQ_EMPTY(&env->cc))
2362  {
2363  fputs("Cc: ", fp);
2364  mutt_write_addrlist(&env->cc, fp, 4, 0);
2365  }
2366  else if (mode == MUTT_WRITE_HEADER_EDITHDRS)
2367 #ifdef USE_NNTP
2368  if (!OptNewsSend)
2369 #endif
2370  fputs("Cc:\n", fp);
2371 
2372  if (!TAILQ_EMPTY(&env->bcc))
2373  {
2374  if ((mode == MUTT_WRITE_HEADER_POSTPONE) ||
2375  (mode == MUTT_WRITE_HEADER_EDITHDRS) || (mode == MUTT_WRITE_HEADER_FCC) ||
2376  ((mode == MUTT_WRITE_HEADER_NORMAL) && C_WriteBcc))
2377  {
2378  fputs("Bcc: ", fp);
2379  mutt_write_addrlist(&env->bcc, fp, 5, 0);
2380  }
2381  }
2382  else if (mode == MUTT_WRITE_HEADER_EDITHDRS)
2383 #ifdef USE_NNTP
2384  if (!OptNewsSend)
2385 #endif
2386  fputs("Bcc:\n", fp);
2387 
2388 #ifdef USE_NNTP
2389  if (env->newsgroups)
2390  fprintf(fp, "Newsgroups: %s\n", env->newsgroups);
2391  else if ((mode == MUTT_WRITE_HEADER_EDITHDRS) && OptNewsSend)
2392  fputs("Newsgroups:\n", fp);
2393 
2394  if (env->followup_to)
2395  fprintf(fp, "Followup-To: %s\n", env->followup_to);
2396  else if ((mode == MUTT_WRITE_HEADER_EDITHDRS) && OptNewsSend)
2397  fputs("Followup-To:\n", fp);
2398 
2399  if (env->x_comment_to)
2400  fprintf(fp, "X-Comment-To: %s\n", env->x_comment_to);
2401  else if ((mode == MUTT_WRITE_HEADER_EDITHDRS) && OptNewsSend && C_XCommentTo)
2402  fputs("X-Comment-To:\n", fp);
2403 #endif
2404 
2405  if (env->subject)
2406  {
2407  if (hide_protected_subject &&
2408  ((mode == MUTT_WRITE_HEADER_NORMAL) || (mode == MUTT_WRITE_HEADER_FCC) ||
2409  (mode == MUTT_WRITE_HEADER_POSTPONE)))
2411  else
2412  mutt_write_one_header(fp, "Subject", env->subject, NULL, 0, CH_NO_FLAGS);
2413  }
2414  else if (mode == MUTT_WRITE_HEADER_EDITHDRS)
2415  fputs("Subject:\n", fp);
2416 
2417  /* save message id if the user has set it */
2418  if (env->message_id && !privacy)
2419  fprintf(fp, "Message-ID: %s\n", env->message_id);
2420 
2421  if (!TAILQ_EMPTY(&env->reply_to))
2422  {
2423  fputs("Reply-To: ", fp);
2424  mutt_write_addrlist(&env->reply_to, fp, 10, 0);
2425  }
2426  else if (mode == MUTT_WRITE_HEADER_EDITHDRS)
2427  fputs("Reply-To:\n", fp);
2428 
2429  if (!TAILQ_EMPTY(&env->mail_followup_to))
2430  {
2431 #ifdef USE_NNTP
2432  if (!OptNewsSend)
2433 #endif
2434  {
2435  fputs("Mail-Followup-To: ", fp);
2436  mutt_write_addrlist(&env->mail_followup_to, fp, 18, 0);
2437  }
2438  }
2439 
2440  /* Add any user defined headers */
2441  struct UserHdrsOverride userhdrs_overrides = write_userhdrs(fp, &env->userhdrs, privacy);
2442 
2443  if ((mode == MUTT_WRITE_HEADER_NORMAL) || (mode == MUTT_WRITE_HEADER_FCC) ||
2444  (mode == MUTT_WRITE_HEADER_POSTPONE))
2445  {
2446  if (!STAILQ_EMPTY(&env->references))
2447  {
2448  fputs("References:", fp);
2449  mutt_write_references(&env->references, fp, 10);
2450  fputc('\n', fp);
2451  }
2452 
2453  /* Add the MIME headers */
2454  if (!userhdrs_overrides.is_overridden[USERHDRS_OVERRIDE_CONTENT_TYPE])
2455  {
2456  fputs("MIME-Version: 1.0\n", fp);
2457  mutt_write_mime_header(attach, fp);
2458  }
2459  }
2460 
2461  if (!STAILQ_EMPTY(&env->in_reply_to))
2462  {
2463  fputs("In-Reply-To:", fp);
2464  mutt_write_references(&env->in_reply_to, fp, 0);
2465  fputc('\n', fp);
2466  }
2467 
2468 #ifdef USE_AUTOCRYPT
2469  if (C_Autocrypt)
2470  {
2471  if (mode == MUTT_WRITE_HEADER_NORMAL || mode == MUTT_WRITE_HEADER_FCC)
2473  if (mode == MUTT_WRITE_HEADER_MIME)
2475  }
2476 #endif
2477 
2478  if (((mode == MUTT_WRITE_HEADER_NORMAL) || (mode == MUTT_WRITE_HEADER_FCC)) && !privacy &&
2479  C_UserAgent && !userhdrs_overrides.is_overridden[USERHDRS_OVERRIDE_USER_AGENT])
2480  {
2481  /* Add a vanity header */
2482  fprintf(fp, "User-Agent: NeoMutt/%s%s\n", PACKAGE_VERSION, GitVer);
2483  }
2484 
2485  return (ferror(fp) == 0) ? 0 : -1;
2486 }
WHERE bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: globals.h:200
WHERE bool C_WriteBcc
Config: Write out the &#39;Bcc&#39; field when preparing to send a mail.
Definition: globals.h:259
struct AddressList mail_followup_to
Email&#39;s &#39;mail-followup-to&#39;.
Definition: envelope.h:63
struct AddressList reply_to
Email&#39;s &#39;reply-to&#39;.
Definition: envelope.h:62
struct AddressList bcc
Email&#39;s &#39;Bcc&#39; list.
Definition: envelope.h:60
WHERE char * C_CryptProtectedHeadersSubject
Config: Use this as the subject for encrypted emails.
Definition: globals.h:107
bool C_UserAgent
Config: Add a &#39;User-Agent&#39; head to outgoing mail.
Definition: sendlib.c:95
A normal Email, write full header + MIME headers.
Definition: sendlib.h:60
A postponed Email, just the envelope info.
Definition: sendlib.h:62
struct ListHead userhdrs
user defined headers
Definition: envelope.h:83
char * mutt_date_make_date(char *buf, size_t buflen)
Write a date in RFC822 format to a buffer.
Definition: date.c:378
struct ListHead in_reply_to
in-reply-to header content
Definition: envelope.h:82
char * message_id
Message ID.
Definition: envelope.h:69
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
static struct UserHdrsOverride write_userhdrs(FILE *fp, const struct ListHead *userhdrs, bool privacy)
Write user-defined headers and keep track of the interesting ones.
Definition: sendlib.c:2258
char * x_comment_to
List of &#39;X-comment-to&#39; fields.
Definition: envelope.h:78
void mutt_write_references(const struct ListHead *r, FILE *fp, size_t trim)
Add the message references to a list.
Definition: sendlib.c:1842
const char * GitVer
#define CH_NO_FLAGS
No flags are set.
Definition: copy.h:50
"light" mode (used for edit_hdrs)
Definition: sendlib.h:63
fcc mode, like normal mode but for Bcc header
Definition: sendlib.h:61
void mutt_write_addrlist(struct AddressList *al, FILE *fp, int linelen, bool display)
Wrapper for mutt_write_address()
Definition: sendlib.c:1796
bool is_overridden[mutt_array_size(userhdrs_override_headers)]
Definition: sendlib.c:140
char * subject
Email&#39;s subject.
Definition: envelope.h:66
char * newsgroups
List of newsgroups.
Definition: envelope.h:75
WHERE bool C_XCommentTo
Config: (nntp) Add &#39;X-Comment-To&#39; header that contains article author.
Definition: globals.h:283
char * followup_to
List of &#39;followup-to&#39; fields.
Definition: envelope.h:77
int mutt_write_mime_header(struct Body *a, FILE *fp)
Create a MIME header.
Definition: sendlib.c:395
#define STAILQ_EMPTY(head)
Definition: queue.h:345
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
struct AddressList sender
Email&#39;s sender.
Definition: envelope.h:61
Write protected headers.
Definition: sendlib.h:64
#define TAILQ_EMPTY(head)
Definition: queue.h:714
WHERE bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:47
struct ListHead references
message references (in reverse order)
Definition: envelope.h:81
int mutt_autocrypt_write_gossip_headers(struct Envelope *env, FILE *fp)
Write the Autocrypt gossip headers to a file.
Definition: autocrypt.c:765
size_t mutt_addrlist_write(const struct AddressList *al, char *buf, size_t buflen, bool display)
Write an Address to a buffer.
Definition: address.c:1144
int mutt_write_one_header(FILE *fp, const char *tag, const char *value, const char *pfx, int wraplen, CopyHeaderFlags chflags)
Write one header line to a file.
Definition: sendlib.c:2154
int mutt_autocrypt_write_autocrypt_header(struct Envelope *env, FILE *fp)
Write the Autocrypt header to a file.
Definition: autocrypt.c:728
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_stamp_attachment()

void mutt_stamp_attachment ( struct Body a)

Timestamp an Attachment.

Parameters
aAttachment

Definition at line 1443 of file sendlib.c.

1444 {
1445  a->stamp = mutt_date_epoch();
1446 }
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:417
time_t stamp
Time stamp of last encoding update.
Definition: body.h:61
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_unprepare_envelope()

void mutt_unprepare_envelope ( struct Envelope env)

Undo the encodings of mutt_prepare_envelope()

Parameters
envEnvelope to unprepare

Decode all the headers of an email, e.g. when the sending failed or was aborted.

Definition at line 3042 of file sendlib.c.

3043 {
3044  struct ListNode *item = NULL;
3045  STAILQ_FOREACH(item, &env->userhdrs, entries)
3046  {
3047  rfc2047_decode(&item->data);
3048  }
3049 
3051 
3052  /* back conversions */
3054 }
struct AddressList mail_followup_to
Email&#39;s &#39;mail-followup-to&#39;.
Definition: envelope.h:63
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1412
struct ListHead userhdrs
user defined headers
Definition: envelope.h:83
void rfc2047_decode_envelope(struct Envelope *env)
Decode the fields of an Envelope.
Definition: rfc2047.c:776
void rfc2047_decode(char **pd)
Decode any RFC2047-encoded header fields.
Definition: rfc2047.c:636
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
char * data
String.
Definition: list.h:35
A List node for strings.
Definition: list.h:33
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_update_encoding()

void mutt_update_encoding ( struct Body a)

Update the encoding type.

Parameters
aBody to update

Assumes called from send mode where Body->filename points to actual file

Definition at line 1480 of file sendlib.c.

1481 {
1482  struct Content *info = NULL;
1483  char chsbuf[256];
1484 
1485  /* override noconv when it's us-ascii */
1486  if (mutt_ch_is_us_ascii(mutt_body_get_charset(a, chsbuf, sizeof(chsbuf))))
1487  a->noconv = false;
1488 
1489  if (!a->force_charset && !a->noconv)
1490  mutt_param_delete(&a->parameter, "charset");
1491 
1492  info = mutt_get_content_info(a->filename, a);
1493  if (!info)
1494  return;
1495 
1496  set_encoding(a, info);
1498 
1499  FREE(&a->content);
1500  a->content = info;
1501 }
void mutt_stamp_attachment(struct Body *a)
Timestamp an Attachment.
Definition: sendlib.c:1443
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
struct Content * content
Detailed info about the content of the attachment.
Definition: body.h:51
bool noconv
Don&#39;t do character set conversion.
Definition: body.h:73
struct Content * mutt_get_content_info(const char *fname, struct Body *b)
Analyze file to determine MIME encoding to use.
Definition: sendlib.c:1031
bool force_charset
Send mode: don&#39;t adjust the character set when in send-mode.
Definition: body.h:74
#define mutt_ch_is_us_ascii(str)
Definition: charset.h:107
Info about an attachment.
Definition: content.h:33
void mutt_param_delete(struct ParameterList *pl, const char *attribute)
Delete a matching Parameter.
Definition: parameter.c:142
static void set_encoding(struct Body *b, struct Content *info)
determine which Content-Transfer-Encoding to use
Definition: sendlib.c:1387
char * mutt_body_get_charset(struct Body *b, char *buf, size_t buflen)
Get a body&#39;s character set.
Definition: sendlib.c:1456
#define FREE(x)
Definition: memory.h:40
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_write_addrlist()

void mutt_write_addrlist ( struct AddressList *  al,
FILE *  fp,
int  linelen,
bool  display 
)

Wrapper for mutt_write_address()

Parameters
alAddress list
fpFile to write to
linelenLine length to use
displayTrue if these addresses will be displayed to the user

So we can handle very large recipient lists without needing a huge temporary buffer in memory

Definition at line 1796 of file sendlib.c.

1797 {
1798  char buf[1024];
1799  int count = 0;
1800 
1801  struct Address *a = NULL;
1802  TAILQ_FOREACH(a, al, entries)
1803  {
1804  buf[0] = '\0';
1805  mutt_addr_write(buf, sizeof(buf), a, display);
1806  size_t len = mutt_str_strlen(buf);
1807  if (count && (linelen + len > 74))
1808  {
1809  fputs("\n\t", fp);
1810  linelen = len + 8; /* tab is usually about 8 spaces... */
1811  }
1812  else
1813  {
1814  if (count && a->mailbox)
1815  {
1816  fputc(' ', fp);
1817  linelen++;
1818  }
1819  linelen += len;
1820  }
1821  fputs(buf, fp);
1822  struct Address *next = TAILQ_NEXT(a, entries);
1823  if (!a->group && next && next->mailbox)
1824  {
1825  linelen++;
1826  fputc(',', fp);
1827  }
1828  count++;
1829  }
1830  fputc('\n', fp);
1831 }
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
An email address.
Definition: address.h:34
char * mailbox
Mailbox and host address.
Definition: address.h:37
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:692
size_t mutt_addr_write(char *buf, size_t buflen, struct Address *addr, bool display)
Write a single Address to a buffer.
Definition: address.c:1022
bool group
Group mailbox?
Definition: address.h:38
#define TAILQ_NEXT(elm, field)
Definition: queue.h:825
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_write_fcc()

int mutt_write_fcc ( const char *  path,
struct Email e,
const char *  msgid,
bool  post,
const char *  fcc,
char **  finalpath 
)

Write email to FCC mailbox.

Parameters
[in]pathPath to mailbox
[in]eEmail
[in]msgidMessage id
[in]postIf true, postpone message, else fcc mode
[in]fccfcc setting to save (postpone only)
[out]finalpathFinal path of email
Return values
0Success
-1Failure

Definition at line 3258 of file sendlib.c.

3260 {
3261  struct Message *msg = NULL;
3262  struct Buffer *tempfile = NULL;
3263  FILE *fp_tmp = NULL;
3264  int rc = -1;
3265  bool need_mailbox_cleanup = false;
3266  struct stat st;
3267  char buf[128];
3268  MsgOpenFlags onm_flags;
3269 
3270  if (post)
3271  set_noconv_flags(e->content, true);
3272 
3273 #ifdef RECORD_FOLDER_HOOK
3274  mutt_folder_hook(path, NULL);
3275 #endif
3276  struct Mailbox *m_fcc = mx_path_resolve(path);
3277  bool old_append = m_fcc->append;
3278  struct Context *ctx_fcc = mx_mbox_open(m_fcc, MUTT_APPEND | MUTT_QUIET);
3279  if (!ctx_fcc)
3280  {
3281  mutt_debug(LL_DEBUG1, "unable to open mailbox %s in append-mode, aborting\n", path);
3282  mailbox_free(&m_fcc);
3283  goto done;
3284  }
3285 
3286  /* We need to add a Content-Length field to avoid problems where a line in
3287  * the message body begins with "From " */
3288  if ((ctx_fcc->mailbox->type == MUTT_MMDF) || (ctx_fcc->mailbox->type == MUTT_MBOX))
3289  {
3290  tempfile = mutt_buffer_pool_get();
3291  mutt_buffer_mktemp(tempfile);
3292  fp_tmp = mutt_file_fopen(mutt_b2s(tempfile), "w+");
3293  if (!fp_tmp)
3294  {
3295  mutt_perror(mutt_b2s(tempfile));
3296  mx_mbox_close(&ctx_fcc);
3297  goto done;
3298  }
3299  /* remember new mail status before appending message */
3300  need_mailbox_cleanup = true;
3301  stat(path, &st);
3302  }
3303 
3304  e->read = !post; /* make sure to put it in the 'cur' directory (maildir) */
3305  onm_flags = MUTT_ADD_FROM;
3306  if (post)
3307  onm_flags |= MUTT_SET_DRAFT;
3308  msg = mx_msg_open_new(ctx_fcc->mailbox, e, onm_flags);
3309  if (!msg)
3310  {
3311  mutt_file_fclose(&fp_tmp);
3312  mx_mbox_close(&ctx_fcc);
3313  goto done;
3314  }
3315 
3316  /* post == 1 => postpone message.
3317  * post == 0 => Normal mode. */
3321 
3322  /* (postponement) if this was a reply of some sort, <msgid> contains the
3323  * Message-ID: of message replied to. Save it using a special X-Mutt-
3324  * header so it can be picked up if the message is recalled at a later
3325  * point in time. This will allow the message to be marked as replied if
3326  * the same mailbox is still open. */
3327  if (post && msgid)
3328  fprintf(msg->fp, "X-Mutt-References: %s\n", msgid);
3329 
3330  /* (postponement) save the Fcc: using a special X-Mutt- header so that
3331  * it can be picked up when the message is recalled */
3332  if (post && fcc)
3333  fprintf(msg->fp, "X-Mutt-Fcc: %s\n", fcc);
3334 
3335  if ((ctx_fcc->mailbox->type == MUTT_MMDF) || (ctx_fcc->mailbox->type == MUTT_MBOX))
3336  fprintf(msg->fp, "Status: RO\n");
3337 
3338  /* mutt_rfc822_write_header() only writes out a Date: header with
3339  * mode == 0, i.e. _not_ postponement; so write out one ourself */
3340  if (post)
3341  fprintf(msg->fp, "%s", mutt_date_make_date(buf, sizeof(buf)));
3342 
3343  /* (postponement) if the mail is to be signed or encrypted, save this info */
3344  if (((WithCrypto & APPLICATION_PGP) != 0) && post && (e->security & APPLICATION_PGP))
3345  {
3346  fputs("X-Mutt-PGP: ", msg->fp);
3347  if (e->security & SEC_ENCRYPT)
3348  fputc('E', msg->fp);
3349  if (e->security & SEC_OPPENCRYPT)
3350  fputc('O', msg->fp);
3351  if (e->security & SEC_SIGN)
3352  {
3353  fputc('S', msg->fp);
3354  if (C_PgpSignAs)
3355  fprintf(msg->fp, "<%s>", C_PgpSignAs);
3356  }
3357  if (e->security & SEC_INLINE)
3358  fputc('I', msg->fp);
3359 #ifdef USE_AUTOCRYPT
3360  if (e->security & SEC_AUTOCRYPT)
3361  fputc('A', msg->fp);
3363  fputc('Z', msg->fp);
3364 #endif
3365  fputc('\n', msg->fp);
3366  }
3367 
3368  /* (postponement) if the mail is to be signed or encrypted, save this info */
3369  if (((WithCrypto & APPLICATION_SMIME) != 0) && post && (e->security & APPLICATION_SMIME))
3370  {
3371  fputs("X-Mutt-SMIME: ", msg->fp);
3372  if (e->security & SEC_ENCRYPT)
3373  {
3374  fputc('E', msg->fp);
3375  if (C_SmimeEncryptWith)
3376  fprintf(msg->fp, "C<%s>", C_SmimeEncryptWith);
3377  }
3378  if (e->security & SEC_OPPENCRYPT)
3379  fputc('O', msg->fp);
3380  if (e->security & SEC_SIGN)
3381  {
3382  fputc('S', msg->fp);
3383  if (C_SmimeSignAs)
3384  fprintf(msg->fp, "<%s>", C_SmimeSignAs);
3385  }
3386  if (e->security & SEC_INLINE)
3387  fputc('I', msg->fp);
3388  fputc('\n', msg->fp);
3389  }
3390 
3391 #ifdef MIXMASTER
3392  /* (postponement) if the mail is to be sent through a mixmaster
3393  * chain, save that information */
3394 
3395  if (post && !STAILQ_EMPTY(&e->chain))
3396  {
3397  fputs("X-Mutt-Mix:", msg->fp);
3398  struct ListNode *p = NULL;
3399  STAILQ_FOREACH(p, &e->chain, entries)
3400  {
3401  fprintf(msg->fp, " %s", (char *) p->data);
3402  }
3403 
3404  fputc('\n', msg->fp);
3405  }
3406 #endif
3407 
3408  if (fp_tmp)
3409  {
3410  mutt_write_mime_body(e->content, fp_tmp);
3411 
3412  /* make sure the last line ends with a newline. Emacs doesn't ensure this
3413  * will happen, and it can cause problems parsing the mailbox later. */
3414  fseek(fp_tmp, -1, SEEK_END);
3415  if (fgetc(fp_tmp) != '\n')
3416  {
3417  fseek(fp_tmp, 0, SEEK_END);
3418  fputc('\n', fp_tmp);
3419  }
3420 
3421  fflush(fp_tmp);
3422  if (ferror(fp_tmp))
3423  {
3424  mutt_debug(LL_DEBUG1, "%s: write failed\n", mutt_b2s(tempfile));
3425  mutt_file_fclose(&fp_tmp);
3426  unlink(mutt_b2s(tempfile));
3427  mx_msg_commit(ctx_fcc->mailbox, msg); /* XXX really? */
3428  mx_msg_close(ctx_fcc->mailbox, &msg);
3429  mx_mbox_close(&ctx_fcc);
3430  goto done;
3431  }
3432 
3433  /* count the number of lines */
3434  int lines = 0;
3435  char line_buf[1024];
3436  rewind(fp_tmp);
3437  while (fgets(line_buf, sizeof(line_buf), fp_tmp))
3438  lines++;
3439  fprintf(msg->fp, "Content-Length: " OFF_T_FMT "\n", (LOFF_T) ftello(fp_tmp));
3440  fprintf(msg->fp, "Lines: %d\n\n", lines);
3441 
3442  /* copy the body and clean up */
3443  rewind(fp_tmp);
3444  rc = mutt_file_copy_stream(fp_tmp, msg->fp);
3445  if (mutt_file_fclose(&fp_tmp) != 0)
3446  rc = -1;
3447  /* if there was an error, leave the temp version */
3448  if (rc >= 0)
3449  {
3450  unlink(mutt_b2s(tempfile));
3451  rc = 0;
3452  }
3453  }
3454  else
3455  {
3456  fputc('\n', msg->fp); /* finish off the header */
3457  rc = mutt_write_mime_body(e->content, msg->fp);
3458  }
3459 
3460  if (mx_msg_commit(ctx_fcc->mailbox, msg) != 0)
3461  rc = -1;
3462  else if (finalpath)
3463  *finalpath = mutt_str_strdup(msg->committed_path);
3464  mx_msg_close(ctx_fcc->mailbox, &msg);
3465  mx_mbox_close(&ctx_fcc);
3466 
3467  if (!post && need_mailbox_cleanup)
3468  mutt_mailbox_cleanup(path, &st);
3469 
3470  if (post)
3471  set_noconv_flags(e->content, false);
3472 
3473 done:
3474  if (m_fcc)
3475  m_fcc->append = old_append;
3476 #ifdef RECORD_FOLDER_HOOK
3477  /* We ran a folder hook for the destination mailbox,
3478  * now we run it for the user's current mailbox */
3479  if (Context && Context->mailbox->path)
3481 #endif
3482 
3483  if (fp_tmp)
3484  {
3485  mutt_file_fclose(&fp_tmp);
3486  unlink(mutt_b2s(tempfile));
3487  }
3488  mutt_buffer_pool_release(&tempfile);
3489 
3490  return rc;
3491 }
#define MUTT_APPEND
Open mailbox for appending messages.
Definition: mx.h:54
The "current" mailbox.
Definition: context.h:37
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:81
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
#define WithCrypto
Definition: lib.h:163
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define mutt_perror(...)
Definition: logging.h:85
int mx_mbox_close(struct Context **ptr)
Save changes and close mailbox.
Definition: mx.c:593
void mutt_mailbox_cleanup(const char *path, struct stat *st)
Restore the timestamp of a mailbox.
Definition: mutt_mailbox.c:381
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:125
bool mutt_should_hide_protected_subject(struct Email *e)
Should NeoMutt hide the protected subject?
Definition: crypt.c:1088
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
struct Body * content
List of MIME parts.
Definition: email.h:90
A postponed Email, just the envelope info.
Definition: sendlib.h:62
String manipulation buffer.
Definition: buffer.h:33
struct Context * mx_mbox_open(struct Mailbox *m, OpenMailboxFlags flags)
Open a mailbox and parse it.
Definition: mx.c:255
#define SEC_AUTOCRYPT
(Autocrypt) Message will be, or was Autocrypt encrypt+signed
Definition: lib.h:134
char * mutt_date_make_date(char *buf, size_t buflen)
Write a date in RFC822 format to a buffer.
Definition: date.c:378
#define MUTT_SET_DRAFT
set the message draft flag
Definition: mx.h:67
int mutt_rfc822_write_header(FILE *fp, struct Envelope *env, struct Body *attach, enum MuttWriteHeaderMode mode, bool privacy, bool hide_protected_subject)
Write out one RFC822 header line.
Definition: sendlib.c:2325
#define SEC_INLINE
Email has an inline signature.
Definition: lib.h:132
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1171
void mutt_folder_hook(const char *path, const char *desc)
Perform a folder hook.
Definition: hook.c:507
bool read
Email is read.
Definition: email.h:51
struct Mailbox * mailbox
Definition: context.h:51
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:60
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
struct Envelope * env
Envelope information.
Definition: email.h:89
struct Message * mx_msg_open_new(struct Mailbox *m, struct Email *e, MsgOpenFlags flags)
Open a new message.
Definition: mx.c:1036
#define mutt_b2s(buf)
Definition: buffer.h:41
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:138
struct ListHead chain
Mixmaster chain.
Definition: email.h:99
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:137
A local copy of an email.
Definition: mx.h:83
A mailbox.
Definition: mailbox.h:81
#define SEC_AUTOCRYPT_OVERRIDE
(Autocrypt) Indicates manual set/unset of encryption
Definition: lib.h:135
int mutt_write_mime_body(struct Body *a, FILE *fp)
Write a MIME part.
Definition: sendlib.c:553
WHERE char * C_SmimeEncryptWith
Config: Algorithm for encryption.
Definition: globals.h:166
&#39;mmdf&#39; Mailbox type
Definition: mailbox.h:49
bool append
Mailbox is opened in append mode.
Definition: mailbox.h:113
fcc mode, like normal mode but for Bcc header
Definition: sendlib.h:61
#define MUTT_QUIET
Do not print any messages.
Definition: mx.h:56
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
Definition: email.h:39
WHERE bool C_CryptProtectedHeadersRead
Config: Display protected headers (Memory Hole) in the pager.
Definition: globals.h:270
uint8_t MsgOpenFlags
Flags for mx_msg_open_new(), e.g. MUTT_ADD_FROM.
Definition: mx.h:64
#define SEC_OPPENCRYPT
Opportunistic encrypt mode.
Definition: lib.h:133
&#39;mbox&#39; Mailbox type
Definition: mailbox.h:48
#define SEC_SIGN
Email is signed.
Definition: lib.h:126
char * committed_path
the final path generated by mx_msg_commit()
Definition: mx.h:87
char * data
String.
Definition: list.h:35
Log at debug level 1.
Definition: logging.h:40
int mutt_file_copy_stream(FILE *fp_in, FILE *fp_out)
Copy the contents of one file into another.
Definition: file.c:271
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
int mx_msg_commit(struct Mailbox *m, struct Message *msg)
Commit a message to a folder - Wrapper for MxOps::msg_commit()
Definition: mx.c:1150
FILE * fp
pointer to the message data
Definition: mx.h:85
struct Mailbox * mx_path_resolve(const char *path)
Get a Mailbox for a path.
Definition: mx.c:1655
static void set_noconv_flags(struct Body *b, bool flag)
Set/reset the "x-mutt-noconv" flag.
Definition: sendlib.c:3184
#define STAILQ_EMPTY(head)
Definition: queue.h:345
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
WHERE char * C_PgpSignAs
Config: Use this alternative key for signing messages.
Definition: globals.h:161
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:588
WHERE char * C_SmimeSignAs
Config: Use this alternative key for signing messages.
Definition: globals.h:165
A List node for strings.
Definition: list.h:33
#define MUTT_ADD_FROM
add a From_ line
Definition: mx.h:66
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_write_mime_body()

int mutt_write_mime_body ( struct Body a,
FILE *  fp 
)

Write a MIME part.

Parameters
aBody to use
fpFile to write to
Return values
0Success
-1Failure

Definition at line 553 of file sendlib.c.

554 {
555  FILE *fp_in = NULL;
556  struct FgetConv *fc = NULL;
557 
558  if (a->type == TYPE_MULTIPART)
559  {
560  /* First, find the boundary to use */
561  const char *p = mutt_param_get(&a->parameter, "boundary");
562  if (!p)
563  {
564  mutt_debug(LL_DEBUG1, "no boundary parameter found\n");
565  mutt_error(_("No boundary parameter found [report this error]"));
566  return -1;
567  }
568  char boundary[128];
569  mutt_str_strfcpy(boundary, p, sizeof(boundary));
570 
571  for (struct Body *t = a->parts; t; t = t->next)
572  {
573  fprintf(fp, "\n--%s\n", boundary);
574  if (mutt_write_mime_header(t, fp) == -1)
575  return -1;
576  fputc('\n', fp);
577  if (mutt_write_mime_body(t, fp) == -1)
578  return -1;
579  }
580  fprintf(fp, "\n--%s--\n", boundary);
581  return ferror(fp) ? -1 : 0;
582  }
583 
584  /* This is pretty gross, but it's the best solution for now... */
585  if (((WithCrypto & APPLICATION_PGP) != 0) && (a->type == TYPE_APPLICATION) &&
586  (mutt_str_strcmp(a->subtype, "pgp-encrypted") == 0) && !a->filename)
587  {
588  fputs("Version: 1\n", fp);
589  return 0;
590  }
591 
592  fp_in = fopen(a->filename, "r");
593  if (!fp_in)
594  {
595  mutt_debug(LL_DEBUG1, "%s no longer exists\n", a->filename);
596  mutt_error(_("%s no longer exists"), a->filename);
597  return -1;
598  }
599 
600  if ((a->type == TYPE_TEXT) && (!a->noconv))
601  {
602  char send_charset[128];
604  fp_in, a->charset,
605  mutt_body_get_charset(a, send_charset, sizeof(send_charset)), 0);
606  }
607  else
608  fc = mutt_ch_fgetconv_open(fp_in, 0, 0, 0);
609 
611  if (a->encoding == ENC_QUOTED_PRINTABLE)
613  else if (a->encoding == ENC_BASE64)
615  else if ((a->type == TYPE_TEXT) && (!a->noconv))
616  encode_8bit(fc, fp);
617  else
618  mutt_file_copy_stream(fp_in, fp);
620 
622  mutt_file_fclose(&fp_in);
623 
624  if (SigInt == 1)
625  {
626  SigInt = 0;
627  return -1;
628  }
629  return ferror(fp) ? -1 : 0;
630 }
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
#define WithCrypto
Definition: lib.h:163
WHERE SIG_ATOMIC_VOLATILE_T SigInt
true after SIGINT is received
Definition: globals.h:79
static void encode_base64(struct FgetConv *fc, FILE *fp_out, int istext)
Base64-encode some data.
Definition: sendlib.c:345
bool noconv
Don&#39;t do character set conversion.
Definition: body.h:73
#define _(a)
Definition: message.h:28
struct Body * next
next attachment in the list
Definition: body.h:53
static bool write_as_text_part(struct Body *b)
Should the Body be written as a text MIME part.
Definition: sendlib.c:540
void mutt_sig_allow_interrupt(bool allow)
Allow/disallow Ctrl-C (SIGINT)
Definition: signal.c:238
The body of an email.
Definition: body.h:34
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
unsigned int encoding
content-transfer-encoding
Definition: body.h:66
Base-64 encoded text.
Definition: mime.h:52
static void encode_quoted(struct FgetConv *fc, FILE *fp_out, bool istext)
Encode text as quoted printable.
Definition: sendlib.c:149
char * subtype
content-type subtype
Definition: body.h:37
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:137
FILE * fp
Definition: charset.h:43
Type: &#39;text/*&#39;.
Definition: mime.h:38
int mutt_write_mime_body(struct Body *a, FILE *fp)
Write a MIME part.
Definition: sendlib.c:553
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:776
char * charset
Send mode: charset of attached file as stored on disk.
Definition: body.h:49
char * mutt_body_get_charset(struct Body *b, char *buf, size_t buflen)
Get a body&#39;s character set.
Definition: sendlib.c:1456
char * p
Definition: charset.h:47
static void encode_8bit(struct FgetConv *fc, FILE *fp_out)
Write the data as raw 8-bit data.
Definition: sendlib.c:373
unsigned int type
content-type primary type
Definition: body.h:65
void mutt_ch_fgetconv_close(struct FgetConv **fc)
Close an fgetconv handle.
Definition: charset.c:881
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
Log at debug level 1.
Definition: logging.h:40
int mutt_file_copy_stream(FILE *fp_in, FILE *fp_out)
Copy the contents of one file into another.
Definition: file.c:271
#define mutt_error(...)
Definition: logging.h:84
Quoted-printable text.
Definition: mime.h:51
char * mutt_param_get(const struct ParameterList *pl, const char *s)
Find a matching Parameter.
Definition: parameter.c:84
int mutt_write_mime_header(struct Body *a, FILE *fp)
Create a MIME header.
Definition: sendlib.c:395
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
struct FgetConv * mutt_ch_fgetconv_open(FILE *fp, const char *from, const char *to, int flags)
Prepare a file for charset conversion.
Definition: charset.c:851
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
Cursor for converting a file&#39;s encoding.
Definition: charset.h:41
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:641
Type: &#39;application/*&#39;.
Definition: mime.h:33
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_write_mime_header()

int mutt_write_mime_header ( struct Body a,
FILE *  fp 
)

Create a MIME header.

Parameters
aBody part
fpFile to write to
Return values
0Success
-1Failure

Definition at line 395 of file sendlib.c.

396 {
397  if (!a || !fp)
398  return -1;
399 
400  int len;
401  int tmplen;
402  char buf[256] = { 0 };
403 
404  fprintf(fp, "Content-Type: %s/%s", TYPE(a), a->subtype);
405 
406  if (!TAILQ_EMPTY(&a->parameter))
407  {
408  len = 25 + mutt_str_strlen(a->subtype); /* approximate len. of content-type */
409 
410  struct Parameter *np = NULL;
411  TAILQ_FOREACH(np, &a->parameter, entries)
412  {
413  if (!np->attribute || !np->value)
414  continue;
415 
416  struct ParameterList pl_conts = rfc2231_encode_string(np->attribute, np->value);
417  struct Parameter *cont = NULL;
418  TAILQ_FOREACH(cont, &pl_conts, entries)
419  {
420  fputc(';', fp);
421 
422  buf[0] = 0;
423  mutt_addr_cat(buf, sizeof(buf), cont->value, MimeSpecials);
424 
425  /* Dirty hack to make messages readable by Outlook Express
426  * for the Mac: force quotes around the boundary parameter
427  * even when they aren't needed. */
428  if (!mutt_str_strcasecmp(cont->attribute, "boundary") &&
429  !mutt_str_strcmp(buf, cont->value))
430  snprintf(buf, sizeof(buf), "\"%s\"", cont->value);
431 
432  tmplen = mutt_str_strlen(buf) + mutt_str_strlen(cont->attribute) + 1;
433  if (len + tmplen + 2 > 76)
434  {
435  fputs("\n\t", fp);
436  len = tmplen + 1;
437  }
438  else
439  {
440  fputc(' ', fp);
441  len += tmplen + 1;
442  }
443 
444  fprintf(fp, "%s=%s", cont->attribute, buf);
445  }
446 
447  mutt_param_free(&pl_conts);
448  }
449  }
450 
451  fputc('\n', fp);
452 
453  if (a->language)
454  fprintf(fp, "Content-Language: %s\n", a->language);
455 
456  if (a->description)
457  fprintf(fp, "Content-Description: %s\n", a->description);
458 
459  if (a->disposition != DISP_NONE)
460  {
461  const char *dispstr[] = { "inline", "attachment", "form-data" };
462 
463  if (a->disposition < sizeof(dispstr) / sizeof(char *))
464  {
465  fprintf(fp, "Content-Disposition: %s", dispstr[a->disposition]);
466  len = 21 + mutt_str_strlen(dispstr[a->disposition]);
467 
468  if (a->use_disp && (a->disposition != DISP_INLINE))
469  {
470  char *fn = a->d_filename;
471  if (!fn)
472  fn = a->filename;
473 
474  if (fn)
475  {
476  /* Strip off the leading path... */
477  char *t = strrchr(fn, '/');
478  if (t)
479  t++;
480  else
481  t = fn;
482 
483  struct ParameterList pl_conts = rfc2231_encode_string("filename", t);
484  struct Parameter *cont = NULL;
485  TAILQ_FOREACH(cont, &pl_conts, entries)
486  {
487  fputc(';', fp);
488  buf[0] = 0;
489  mutt_addr_cat(buf, sizeof(buf), cont->value, MimeSpecials);
490 
491  tmplen = mutt_str_strlen(buf) + mutt_str_strlen(cont->attribute) + 1;
492  if (len + tmplen + 2 > 76)
493  {
494  fputs("\n\t", fp);
495  len = tmplen + 1;
496  }
497  else
498  {
499  fputc(' ', fp);
500  len += tmplen + 1;
501  }
502 
503  fprintf(fp, "%s=%s", cont->attribute, buf);
504  }
505 
506  mutt_param_free(&pl_conts);
507  }
508  }
509 
510  fputc('\n', fp);
511  }
512  else
513  {
514  mutt_debug(LL_DEBUG1, "ERROR: invalid content-disposition %d\n", a->disposition);
515  }
516  }
517 
518  if (a->encoding != ENC_7BIT)
519  fprintf(fp, "Content-Transfer-Encoding: %s\n", ENCODING(a->encoding));
520 
522 #ifdef USE_AUTOCRYPT
523  || C_Autocrypt
524 #endif
525  ) &&
526  a->mime_headers)
527  {
528  mutt_rfc822_write_header(fp, a->mime_headers, NULL, MUTT_WRITE_HEADER_MIME, false, false);
529  }
530 
531  /* Do NOT add the terminator here!!! */
532  return ferror(fp) ? -1 : 0;
533 }
char * attribute
Parameter name.
Definition: parameter.h:34
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
WHERE bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: globals.h:200
struct Envelope * mime_headers
Memory hole protected headers.
Definition: body.h:63
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
7-bit text
Definition: mime.h:49
WHERE bool C_CryptProtectedHeadersWrite
Config: Generate protected header (Memory Hole) for signed and encrypted emails.
Definition: globals.h:272
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:692
unsigned int disposition
content-disposition
Definition: body.h:67
int mutt_rfc822_write_header(FILE *fp, struct Envelope *env, struct Body *attach, enum MuttWriteHeaderMode mode, bool privacy, bool hide_protected_subject)
Write out one RFC822 header line.
Definition: sendlib.c:2325
#define ENCODING(x)
Definition: mime.h:85
void mutt_param_free(struct ParameterList *pl)
Free a ParameterList.
Definition: parameter.c:61
unsigned int encoding
content-transfer-encoding
Definition: body.h:66
char * subtype
content-type subtype
Definition: body.h:37
FILE * fp
Definition: charset.h:43
const char MimeSpecials[]
Characters that need special treatment in MIME.
Definition: mime.c:67
char * description
content-description
Definition: body.h:40
#define TYPE(body)
Definition: mime.h:83
char * value
Parameter value.
Definition: parameter.h:35
Log at debug level 1.
Definition: logging.h:40
No preferred disposition.
Definition: mime.h:65
bool use_disp
Content-Disposition uses filename= ?
Definition: body.h:68
struct ParameterList rfc2231_encode_string(const char *attribute, char *value)
Encode a string to be suitable for an RFC2231 header.
Definition: rfc2231.c:328
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:654
Attribute associated with a MIME part.
Definition: parameter.h:32
char * language
content-language (RFC8255)
Definition: body.h:38
char * d_filename
filename to be used for the content-disposition header.
Definition: body.h:47
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
Write protected headers.
Definition: sendlib.h:64
#define TAILQ_EMPTY(head)
Definition: queue.h:714
Content is inline.
Definition: mime.h:62
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:641
void mutt_addr_cat(char *buf, size_t buflen, const char *value, const char *specials)
Copy a string and wrap it in quotes if it contains special characters.
Definition: address.c:678
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_write_multiple_fcc()

int mutt_write_multiple_fcc ( const char *  path,
struct Email e,
const char *  msgid,
bool  post,
char *  fcc,
char **  finalpath 
)

Handle FCC with multiple, comma separated entries.

Parameters
[in]pathPath to mailboxes (comma separated)
[in]eEmail
[in]msgidMessage id
[in]postIf true, postpone message
[in]fccfcc setting to save (postpone only)
[out]finalpathFinal path of email
Return values
0Success
-1Failure

Definition at line 3211 of file sendlib.c.

3213 {
3214  char fcc_tok[PATH_MAX];
3215  char fcc_expanded[PATH_MAX];
3216 
3217  mutt_str_strfcpy(fcc_tok, path, sizeof(fcc_tok));
3218 
3219  char *tok = strtok(fcc_tok, ",");
3220  if (!tok)
3221  return -1;
3222 
3223  mutt_debug(LL_DEBUG1, "Fcc: initial mailbox = '%s'\n", tok);
3224  /* mutt_expand_path already called above for the first token */
3225  int status = mutt_write_fcc(tok, e, msgid, post, fcc, finalpath);
3226  if (status != 0)
3227  return status;
3228 
3229  while ((tok = strtok(NULL, ",")))
3230  {
3231  if (!*tok)
3232  continue;
3233 
3234  /* Only call mutt_expand_path if tok has some data */
3235  mutt_debug(LL_DEBUG1, "Fcc: additional mailbox token = '%s'\n", tok);
3236  mutt_str_strfcpy(fcc_expanded, tok, sizeof(fcc_expanded));
3237  mutt_expand_path(fcc_expanded, sizeof(fcc_expanded));
3238  mutt_debug(LL_DEBUG1, " Additional mailbox expanded = '%s'\n", fcc_expanded);
3239  status = mutt_write_fcc(fcc_expanded, e, msgid, post, fcc, finalpath);
3240  if (status != 0)
3241  return status;
3242  }
3243 
3244  return 0;
3245 }
int mutt_write_fcc(const char *path, struct Email *e, const char *msgid, bool post, const char *fcc, char **finalpath)
Write email to FCC mailbox.
Definition: sendlib.c:3258
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:132
#define PATH_MAX
Definition: mutt.h:44
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:776
Log at debug level 1.
Definition: logging.h:40
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_write_one_header()

int mutt_write_one_header ( FILE *  fp,
const char *  tag,
const char *  value,
const char *  pfx,
int  wraplen,
CopyHeaderFlags  chflags 
)

Write one header line to a file.

Parameters
fpFile to write to
tagHeader key, e.g. "From"
valueHeader value
pfxPrefix for header
wraplenColumn to wrap at
chflagsFlags, see CopyHeaderFlags
Return values
0Success
-1Failure

split several headers into individual ones and call write_one_header for each one

Definition at line 2154 of file sendlib.c.

2156 {
2157  char *last = NULL, *line = NULL;
2158  int max = 0, w, rc = -1;
2159  int pfxw = mutt_strwidth(pfx);
2160  char *v = mutt_str_strdup(value);
2161  bool display = (chflags & CH_DISPLAY);
2162 
2163  if (!display || C_Weed)
2164  v = unfold_header(v);
2165 
2166  /* when not displaying, use sane wrap value */
2167  if (!display)
2168  {
2169  if ((C_WrapHeaders < 78) || (C_WrapHeaders > 998))
2170  wraplen = 78;
2171  else
2172  wraplen = C_WrapHeaders;
2173  }
2174  else if (wraplen <= 0)
2175  wraplen = 78;
2176 
2177  const size_t vlen = mutt_str_strlen(v);
2178  if (tag)
2179  {
2180  /* if header is short enough, simply print it */
2181  if (!display && (mutt_strwidth(tag) + 2 + pfxw + mutt_strnwidth(v, vlen) <= wraplen))
2182  {
2183  mutt_debug(LL_DEBUG5, "buf[%s%s: %s] is short enough\n", NONULL(pfx), tag, v);
2184  if (fprintf(fp, "%s%s: %s\n", NONULL(pfx), tag, v) <= 0)
2185  goto out;
2186  rc = 0;
2187  goto out;
2188  }
2189  else
2190  {
2191  rc = fold_one_header(fp, tag, v, vlen, pfx, wraplen, chflags);
2192  goto out;
2193  }
2194  }
2195 
2196  char *p = v;
2197  last = v;
2198  line = v;
2199  while (p && *p)
2200  {
2201  p = strchr(p, '\n');
2202 
2203  /* find maximum line width in current header */
2204  if (p)
2205  *p = '\0';
2206  w = mutt_mb_width(line, 0, display);
2207  if (w > max)
2208  max = w;
2209  if (p)
2210  *p = '\n';
2211 
2212  if (!p)
2213  break;
2214 
2215  line = ++p;
2216  if ((*p != ' ') && (*p != '\t'))
2217  {
2218  if (write_one_header(fp, pfxw, max, wraplen, pfx, last, p, chflags) < 0)
2219  goto out;
2220  last = p;
2221  max = 0;
2222  }
2223  }
2224 
2225  if (last && *last)
2226  if (write_one_header(fp, pfxw, max, wraplen, pfx, last, p, chflags) < 0)
2227  goto out;
2228 
2229  rc = 0;
2230 
2231 out:
2232  FREE(&v);
2233  return rc;
2234 }
short C_WrapHeaders
Config: Width to wrap headers in outgoing messages.
Definition: sendlib.c:96
#define NONULL(x)
Definition: string2.h:37
static int fold_one_header(FILE *fp, const char *tag, const char *value, size_t vlen, const char *pfx, int wraplen, CopyHeaderFlags chflags)
Fold one header line.
Definition: sendlib.c:1932
static char * unfold_header(char *s)
Unfold a wrapped email header.
Definition: sendlib.c:2037
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:692
int mutt_mb_width(const char *str, int col, bool display)
Measure a string&#39;s display width (in screen columns)
Definition: mbyte.c:139
int mutt_strwidth(const char *s)
Measure a string&#39;s width in screen cells.
Definition: curs_lib.c:1336
#define CH_DISPLAY
Display result to user.
Definition: copy.h:69
static int write_one_header(FILE *fp, int pfxw, int max, int wraplen, const char *pfx, const char *start, const char *end, CopyHeaderFlags chflags)
Write out one header line.
Definition: sendlib.c:2079
int mutt_strnwidth(const char *s, size_t n)
Measure a string&#39;s width in screen cells.
Definition: curs_lib.c:1349
char * value
Parameter value.
Definition: parameter.h:35
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
#define FREE(x)
Definition: memory.h:40
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
int const char int line
Definition: acutest.h:617
Log at debug level 5.
Definition: logging.h:44
bool C_Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: email_globals.c:40
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_write_references()

void mutt_write_references ( const struct ListHead *  r,
FILE *  fp,
size_t  trim 
)

Add the message references to a list.

Parameters
rString List of references
fpFile to write to
trimTrim the list to at most this many items

Write the list in reverse because they are stored in reverse order when parsed to speed up threading.

Definition at line 1842 of file sendlib.c.

1843 {
1844  struct ListNode *np = NULL;
1845  size_t length = 0;
1846 
1847  STAILQ_FOREACH(np, r, entries)
1848  {
1849  if (++length == trim)
1850  break;
1851  }
1852 
1853  struct ListNode **ref = mutt_mem_calloc(length, sizeof(struct ListNode *));
1854 
1855  // store in reverse order
1856  size_t tmp = length;
1857  STAILQ_FOREACH(np, r, entries)
1858  {
1859  ref[--tmp] = np;
1860  if (tmp == 0)
1861  break;
1862  }
1863 
1864  for (size_t i = 0; i < length; i++)
1865  {
1866  fputc(' ', fp);
1867  fputs(ref[i]->data, fp);
1868  if (i != length - 1)
1869  fputc('\n', fp);
1870  }
1871 
1872  FREE(&ref);
1873 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
char * data
String.
Definition: list.h:35
#define FREE(x)
Definition: memory.h:40
A List node for strings.
Definition: list.h:33
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ C_Allow8bit

bool C_Allow8bit

Config: Allow 8-bit messages, don't use quoted-printable or base64.

Definition at line 80 of file sendlib.c.

◆ C_AttachCharset

char* C_AttachCharset

Config: When attaching files, use one of these character sets.

Definition at line 81 of file sendlib.c.

◆ C_BounceDelivered

bool C_BounceDelivered

Config: Add 'Delivered-To' to bounced messages.

Definition at line 82 of file sendlib.c.

◆ C_EncodeFrom

bool C_EncodeFrom

Config: Encode 'From ' as 'quote-printable' at the beginning of lines.

Definition at line 83 of file sendlib.c.

◆ C_ForwardDecrypt

bool C_ForwardDecrypt

Config: Decrypt the message when forwarding it.

Definition at line 84 of file sendlib.c.

◆ C_HiddenHost

bool C_HiddenHost

Config: Don't use the hostname, just the domain, when generating the message id.

Definition at line 85 of file sendlib.c.

◆ C_Inews

char* C_Inews

Config: (nntp) External command to post news articles.

Definition at line 86 of file sendlib.c.

◆ C_MimeForwardDecode

bool C_MimeForwardDecode

Config: Decode the forwarded message before attaching it.

Definition at line 87 of file sendlib.c.

◆ C_MimeSubject

bool C_MimeSubject

encode subject line with RFC2047

encode subject line with RFC2047

Definition at line 88 of file sendlib.c.

◆ C_MimeTypeQueryCommand

char* C_MimeTypeQueryCommand

Config: External command to determine the MIME type of an attachment.

Definition at line 89 of file sendlib.c.

◆ C_MimeTypeQueryFirst

bool C_MimeTypeQueryFirst

Config: Run the C_MimeTypeQueryCommand before the mime.types lookup.

Definition at line 90 of file sendlib.c.

◆ C_Sendmail

char* C_Sendmail

Config: External command to send email.

Definition at line 91 of file sendlib.c.

◆ C_SendmailWait

short C_SendmailWait

Config: Time to wait for sendmail to finish.

Definition at line 92 of file sendlib.c.

◆ C_Use8bitmime

bool C_Use8bitmime

Config: Use 8-bit messages and ESMTP to send messages.

Definition at line 93 of file sendlib.c.

◆ C_UseEnvelopeFrom

bool C_UseEnvelopeFrom

Config: Set the envelope sender of the message.

Definition at line 94 of file sendlib.c.

◆ C_UserAgent

bool C_UserAgent

Config: Add a 'User-Agent' head to outgoing mail.

Definition at line 95 of file sendlib.c.

◆ C_WrapHeaders

short C_WrapHeaders

Config: Width to wrap headers in outgoing messages.

Definition at line 96 of file sendlib.c.