NeoMutt  2018-07-16 +1783-b00bd9
Teaching an old dog new tricks
DOXYGEN
mutt_parse.c File Reference

Miscellaneous email parsing routines. More...

#include "config.h"
#include <regex.h>
#include <stdbool.h>
#include <stdio.h>
#include "mutt/mutt.h"
#include "email/lib.h"
#include "mutt.h"
#include "mutt_parse.h"
#include "globals.h"
#include "mx.h"
#include "ncrypt/ncrypt.h"
+ Include dependency graph for mutt_parse.c:

Go to the source code of this file.

Macros

#define MUTT_PARTS_TOPLEVEL   (1 << 0) /* is the top-level part */
 

Functions

void mutt_parse_mime_message (struct Mailbox *m, struct Email *e)
 Parse a MIME email. More...
 
static bool count_body_parts_check (struct ListHead *checklist, struct Body *b, bool dflt)
 Compares mime types to the ok and except lists. More...
 
static int count_body_parts (struct Body *body, int flags)
 Count the MIME Body parts. More...
 
int mutt_count_body_parts (struct Mailbox *m, struct Email *e)
 Count the MIME Body parts. More...
 

Detailed Description

Miscellaneous email parsing routines.

Authors
  • Michael R. Elkins

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 mutt_parse.c.

Macro Definition Documentation

#define MUTT_PARTS_TOPLEVEL   (1 << 0) /* is the top-level part */

Definition at line 43 of file mutt_parse.c.

Function Documentation

void mutt_parse_mime_message ( struct Mailbox m,
struct Email e 
)

Parse a MIME email.

Parameters
mMailbox
eEmail

Definition at line 50 of file mutt_parse.c.

51 {
52  do
53  {
54  if ((e->content->type != TYPE_MESSAGE) && (e->content->type != TYPE_MULTIPART))
55  break; /* nothing to do */
56 
57  if (e->content->parts)
58  break; /* The message was parsed earlier. */
59 
60  struct Message *msg = mx_msg_open(m, e->msgno);
61  if (msg)
62  {
63  mutt_parse_part(msg->fp, e->content);
64 
65  if (WithCrypto)
66  e->security = crypt_query(e->content);
67 
68  mx_msg_close(m, &msg);
69  }
70  } while (false);
71 
72  e->attach_valid = false;
73 }
struct Body * content
list of MIME parts
Definition: email.h:93
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1077
A local copy of an email.
Definition: mx.h:79
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:61
bool attach_valid
Definition: email.h:73
SecurityFlags security
bit 0-8: flags, bit 9,10: application.
Definition: email.h:39
unsigned int type
content-type primary type
Definition: body.h:72
Type: &#39;message/*&#39;.
Definition: mime.h:35
void mutt_parse_part(FILE *fp, struct Body *b)
Parse a MIME part.
Definition: parse.c:1275
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
FILE * fp
pointer to the message data
Definition: mx.h:81
#define WithCrypto
Definition: ncrypt.h:155
SecurityFlags crypt_query(struct Body *m)
Check out the type of encryption used.
Definition: crypt.c:660
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
return a stream pointer for a message
Definition: mx.c:1029
int msgno
number displayed to the user
Definition: email.h:89

+ Here is the caller graph for this function:

static bool count_body_parts_check ( struct ListHead *  checklist,
struct Body b,
bool  dflt 
)
static

Compares mime types to the ok and except lists.

Parameters
checklistList of AttachMatch
bEmail Body
dfltLog whether the matches are OK, or Excluded
Return values
trueAttachment should be counted

Definition at line 82 of file mutt_parse.c.

83 {
84  struct AttachMatch *a = NULL;
85 
86  /* If list is null, use default behavior. */
87  if (!checklist || STAILQ_EMPTY(checklist))
88  {
89  return false;
90  }
91 
92  struct ListNode *np = NULL;
93  STAILQ_FOREACH(np, checklist, entries)
94  {
95  a = (struct AttachMatch *) np->data;
96  mutt_debug(LL_DEBUG3, "%s %d/%s ?? %s/%s [%d]... ", dflt ? "[OK] " : "[EXCL] ",
97  b->type, b->subtype ? b->subtype : "*", a->major, a->minor, a->major_int);
98  if (((a->major_int == TYPE_ANY) || (a->major_int == b->type)) &&
99  (!b->subtype || !regexec(&a->minor_regex, b->subtype, 0, NULL, 0)))
100  {
101  mutt_debug(LL_DEBUG3, "yes\n");
102  return true;
103  }
104  else
105  {
106  mutt_debug(LL_DEBUG3, "no\n");
107  }
108  }
109 
110  return false;
111 }
int major_int
Definition: mutt.h:131
Type: &#39;*&#39; or &#39;.*&#39;.
Definition: mime.h:40
const char * major
Definition: mutt.h:130
char * subtype
content-type subtype
Definition: body.h:37
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:350
unsigned int type
content-type primary type
Definition: body.h:72
char * data
Definition: list.h:35
regex_t minor_regex
Definition: mutt.h:133
#define STAILQ_EMPTY(head)
Definition: queue.h:346
#define mutt_debug(LEVEL,...)
Definition: logging.h:80
An attachment matching a regex.
Definition: mutt.h:128
A List node for strings.
Definition: list.h:33
const char * minor
Definition: mutt.h:132
Log at debug level 3.
Definition: logging.h:58

+ Here is the caller graph for this function:

static int count_body_parts ( struct Body body,
int  flags 
)
static

Count the MIME Body parts.

Parameters
bodyBody of email
flagsFlags, e.g. MUTT_PARTS_TOPLEVEL
Return values
numNumber of MIME Body parts

Definition at line 119 of file mutt_parse.c.

120 {
121  if (!body)
122  return 0;
123 
124  int count = 0;
125 
126  for (struct Body *bp = body; bp; bp = bp->next)
127  {
128  /* Initial disposition is to count and not to recurse this part. */
129  bool shallcount = true; /* default */
130  bool shallrecurse = false;
131 
132  mutt_debug(5, "desc=\"%s\"; fn=\"%s\", type=\"%d/%s\"\n",
133  bp->description ? bp->description : ("none"),
134  bp->filename ? bp->filename : bp->d_filename ? bp->d_filename : "(none)",
135  bp->type, bp->subtype ? bp->subtype : "*");
136 
137  if (bp->type == TYPE_MESSAGE)
138  {
139  shallrecurse = true;
140 
141  /* If it's an external body pointer, don't recurse it. */
142  if (mutt_str_strcasecmp(bp->subtype, "external-body") == 0)
143  shallrecurse = false;
144 
145  /* Don't count containers if they're top-level. */
146  if (flags & MUTT_PARTS_TOPLEVEL)
147  shallcount = false; // top-level message/*
148  }
149  else if (bp->type == TYPE_MULTIPART)
150  {
151  /* Always recurse multiparts, except multipart/alternative. */
152  shallrecurse = true;
153  if (mutt_str_strcasecmp(bp->subtype, "alternative") == 0)
154  shallrecurse = false;
155 
156  /* Don't count containers if they're top-level. */
157  if (flags & MUTT_PARTS_TOPLEVEL)
158  shallcount = false; /* top-level multipart */
159  }
160 
161  if ((bp->disposition == DISP_INLINE) && (bp->type != TYPE_MULTIPART) &&
162  (bp->type != TYPE_MESSAGE) && (bp == body))
163  {
164  shallcount = false; /* ignore fundamental inlines */
165  }
166 
167  /* If this body isn't scheduled for enumeration already, don't bother
168  * profiling it further. */
169  if (shallcount)
170  {
171  /* Turn off shallcount if message type is not in ok list,
172  * or if it is in except list. Check is done separately for
173  * inlines vs. attachments. */
174 
175  if (bp->disposition == DISP_ATTACH)
176  {
177  if (!count_body_parts_check(&AttachAllow, bp, true))
178  shallcount = false; /* attach not allowed */
179  if (count_body_parts_check(&AttachExclude, bp, false))
180  shallcount = false; /* attach excluded */
181  }
182  else
183  {
184  if (!count_body_parts_check(&InlineAllow, bp, true))
185  shallcount = false; /* inline not allowed */
186  if (count_body_parts_check(&InlineExclude, bp, false))
187  shallcount = false; /* excluded */
188  }
189  }
190 
191  if (shallcount)
192  count++;
193  bp->attach_qualifies = shallcount ? true : false;
194 
195  mutt_debug(LL_DEBUG3, "%p shallcount = %d\n", (void *) bp, shallcount);
196 
197  if (shallrecurse)
198  {
199  mutt_debug(LL_DEBUG3, "%p pre count = %d\n", (void *) bp, count);
200  bp->attach_count = count_body_parts(bp->parts, flags & ~MUTT_PARTS_TOPLEVEL);
201  count += bp->attach_count;
202  mutt_debug(LL_DEBUG3, "%p post count = %d\n", (void *) bp, count);
203  }
204  }
205 
206  mutt_debug(LL_DEBUG3, "return %d\n", (count < 0) ? 0 : count);
207  return (count < 0) ? 0 : count;
208 }
static bool count_body_parts_check(struct ListHead *checklist, struct Body *b, bool dflt)
Compares mime types to the ok and except lists.
Definition: mutt_parse.c:82
#define MUTT_PARTS_TOPLEVEL
Definition: mutt_parse.c:43
struct Body * next
next attachment in the list
Definition: body.h:60
The body of an email.
Definition: body.h:34
Content is attached.
Definition: mime.h:63
static int count_body_parts(struct Body *body, int flags)
Count the MIME Body parts.
Definition: mutt_parse.c:119
Type: &#39;message/*&#39;.
Definition: mime.h:35
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:631
#define mutt_debug(LEVEL,...)
Definition: logging.h:80
Content is inline.
Definition: mime.h:62
Log at debug level 3.
Definition: logging.h:58

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int mutt_count_body_parts ( struct Mailbox m,
struct Email e 
)

Count the MIME Body parts.

Parameters
mMailbox
eEmail
Return values
numNumber of MIME Body parts

Definition at line 216 of file mutt_parse.c.

217 {
218  bool keep_parts = false;
219 
220  if (e->attach_valid)
221  return e->attach_total;
222 
223  if (e->content->parts)
224  keep_parts = true;
225  else
227 
228  if (!STAILQ_EMPTY(&AttachAllow) || !STAILQ_EMPTY(&AttachExclude) ||
229  !STAILQ_EMPTY(&InlineAllow) || !STAILQ_EMPTY(&InlineExclude))
230  {
232  }
233  else
234  e->attach_total = 0;
235 
236  e->attach_valid = true;
237 
238  if (!keep_parts)
240 
241  return e->attach_total;
242 }
struct Body * content
list of MIME parts
Definition: email.h:93
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e)
Parse a MIME email.
Definition: mutt_parse.c:50
#define MUTT_PARTS_TOPLEVEL
Definition: mutt_parse.c:43
short attach_total
Definition: email.h:100
static int count_body_parts(struct Body *body, int flags)
Count the MIME Body parts.
Definition: mutt_parse.c:119
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:61
bool attach_valid
Definition: email.h:73
void mutt_body_free(struct Body **p)
Free a Body.
Definition: body.c:57
#define STAILQ_EMPTY(head)
Definition: queue.h:346

+ Here is the caller graph for this function: