NeoMutt  2020-04-24
Teaching an old dog new tricks
DOXYGEN
mutt_parse.c
Go to the documentation of this file.
1 
29 #include "config.h"
30 #include <stdbool.h>
31 #include <stdio.h>
32 #include "mutt/lib.h"
33 #include "email/lib.h"
34 #include "mutt_parse.h"
35 #include "mx.h"
36 #include "ncrypt/lib.h"
37 
42 
48 void mutt_parse_mime_message(struct Mailbox *m, struct Email *e)
49 {
50  do
51  {
52  if ((e->content->type != TYPE_MESSAGE) && (e->content->type != TYPE_MULTIPART))
53  break; /* nothing to do */
54 
55  if (e->content->parts)
56  break; /* The message was parsed earlier. */
57 
58  struct Message *msg = mx_msg_open(m, e->msgno);
59  if (msg)
60  {
61  mutt_parse_part(msg->fp, e->content);
62 
63  if (WithCrypto)
64  e->security = crypt_query(e->content);
65 
66  mx_msg_close(m, &msg);
67  }
68  } while (false);
69 
70  e->attach_valid = false;
71 }
72 
80 static bool count_body_parts_check(struct ListHead *checklist, struct Body *b, bool dflt)
81 {
82  struct AttachMatch *a = NULL;
83 
84  /* If list is null, use default behavior. */
85  if (!checklist || STAILQ_EMPTY(checklist))
86  {
87  return false;
88  }
89 
90  struct ListNode *np = NULL;
91  STAILQ_FOREACH(np, checklist, entries)
92  {
93  a = (struct AttachMatch *) np->data;
94  mutt_debug(LL_DEBUG3, "%s %d/%s ?? %s/%s [%d]... ", dflt ? "[OK] " : "[EXCL] ",
95  b->type, b->subtype ? b->subtype : "*", a->major, a->minor, a->major_int);
96  if (((a->major_int == TYPE_ANY) || (a->major_int == b->type)) &&
97  (!b->subtype || !regexec(&a->minor_regex, b->subtype, 0, NULL, 0)))
98  {
99  mutt_debug(LL_DEBUG3, "yes\n");
100  return true;
101  }
102  else
103  {
104  mutt_debug(LL_DEBUG3, "no\n");
105  }
106  }
107 
108  return false;
109 }
110 
116 static int count_body_parts(struct Body *body)
117 {
118  if (!body)
119  return 0;
120 
121  int count = 0;
122 
123  for (struct Body *bp = body; bp; bp = bp->next)
124  {
125  /* Initial disposition is to count and not to recurse this part. */
126  bool shallcount = true; /* default */
127  bool shallrecurse = false;
128 
129  mutt_debug(LL_DEBUG5, "desc=\"%s\"; fn=\"%s\", type=\"%d/%s\"\n",
130  bp->description ? bp->description : ("none"),
131  bp->filename ? bp->filename : bp->d_filename ? bp->d_filename : "(none)",
132  bp->type, bp->subtype ? bp->subtype : "*");
133 
134  if (bp->type == TYPE_MESSAGE)
135  {
136  shallrecurse = true;
137 
138  /* If it's an external body pointer, don't recurse it. */
139  if (mutt_str_strcasecmp(bp->subtype, "external-body") == 0)
140  shallrecurse = false;
141  }
142  else if (bp->type == TYPE_MULTIPART)
143  {
144  /* Always recurse multiparts, except multipart/alternative. */
145  shallrecurse = true;
146  if (mutt_str_strcasecmp(bp->subtype, "alternative") == 0)
147  shallrecurse = false;
148  }
149 
150  if ((bp->disposition == DISP_INLINE) && (bp->type != TYPE_MULTIPART) &&
151  (bp->type != TYPE_MESSAGE) && (bp == body))
152  {
153  shallcount = false; /* ignore fundamental inlines */
154  }
155 
156  /* If this body isn't scheduled for enumeration already, don't bother
157  * profiling it further. */
158  if (shallcount)
159  {
160  /* Turn off shallcount if message type is not in ok list,
161  * or if it is in except list. Check is done separately for
162  * inlines vs. attachments. */
163 
164  if (bp->disposition == DISP_ATTACH)
165  {
166  if (!count_body_parts_check(&AttachAllow, bp, true))
167  shallcount = false; /* attach not allowed */
168  if (count_body_parts_check(&AttachExclude, bp, false))
169  shallcount = false; /* attach excluded */
170  }
171  else
172  {
173  if (!count_body_parts_check(&InlineAllow, bp, true))
174  shallcount = false; /* inline not allowed */
175  if (count_body_parts_check(&InlineExclude, bp, false))
176  shallcount = false; /* excluded */
177  }
178  }
179 
180  if (shallcount)
181  count++;
182  bp->attach_qualifies = shallcount;
183 
184  mutt_debug(LL_DEBUG3, "%p shallcount = %d\n", (void *) bp, shallcount);
185 
186  if (shallrecurse)
187  {
188  mutt_debug(LL_DEBUG3, "%p pre count = %d\n", (void *) bp, count);
189  bp->attach_count = count_body_parts(bp->parts);
190  count += bp->attach_count;
191  mutt_debug(LL_DEBUG3, "%p post count = %d\n", (void *) bp, count);
192  }
193  }
194 
195  mutt_debug(LL_DEBUG3, "return %d\n", (count < 0) ? 0 : count);
196  return (count < 0) ? 0 : count;
197 }
198 
205 int mutt_count_body_parts(struct Mailbox *m, struct Email *e)
206 {
207  bool keep_parts = false;
208 
209  if (e->attach_valid)
210  return e->attach_total;
211 
212  if (e->content->parts)
213  keep_parts = true;
214  else
216 
219  {
221  }
222  else
223  e->attach_total = 0;
224 
225  e->attach_valid = true;
226 
227  if (!keep_parts)
229 
230  return e->attach_total;
231 }
232 
241 {
242  if (!ptr || !*ptr)
243  return;
244 
245  struct AttachMatch *am = *ptr;
246  regfree(&am->minor_regex);
247  FREE(&am->major);
248  FREE(ptr);
249 }
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:80
Miscellaneous email parsing routines.
#define WithCrypto
Definition: lib.h:163
The envelope/body of an email.
Definition: email.h:37
Structs that make up an email.
struct ListHead InlineAllow
List of inline types to counted.
Definition: mutt_parse.c:40
struct Body * content
List of MIME parts.
Definition: email.h:90
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e)
Parse a MIME email.
Definition: mutt_parse.c:48
enum ContentType major_int
Definition: mutt_parse.h:37
struct Body * next
next attachment in the list
Definition: body.h:53
Type: &#39;*&#39; or &#39;.*&#39;.
Definition: mime.h:40
static int count_body_parts(struct Body *body)
Count the MIME Body parts.
Definition: mutt_parse.c:116
The body of an email.
Definition: body.h:34
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1171
API for mailboxes.
Content is attached.
Definition: mime.h:63
const char * major
Definition: mutt_parse.h:36
short attach_total
Number of qualifying attachments in message, if attach_valid.
Definition: email.h:96
char * subtype
content-type subtype
Definition: body.h:37
struct ListHead InlineExclude
List of inline types to ignore.
Definition: mutt_parse.c:41
A local copy of an email.
Definition: mx.h:83
A mailbox.
Definition: mailbox.h:81
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
bool attach_valid
true when the attachment count is valid
Definition: email.h:70
API for encryption/signing of emails.
#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
unsigned int type
content-type primary type
Definition: body.h:65
Type: &#39;message/*&#39;.
Definition: mime.h:35
struct ListHead AttachExclude
List of attachment types to be ignored.
Definition: mutt_parse.c:39
void mutt_parse_part(FILE *fp, struct Body *b)
Parse a MIME part.
Definition: parse.c:1407
char * data
String.
Definition: list.h:35
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
regex_t minor_regex
Definition: mutt_parse.h:39
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:654
FILE * fp
pointer to the message data
Definition: mx.h:85
#define FREE(x)
Definition: memory.h:40
#define STAILQ_EMPTY(head)
Definition: queue.h:345
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:321
int mutt_count_body_parts(struct Mailbox *m, struct Email *e)
Count the MIME Body parts.
Definition: mutt_parse.c:205
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
void mutt_attachmatch_free(struct AttachMatch **ptr)
Free an AttachMatch - Implements list_free_t.
Definition: mutt_parse.c:240
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
An attachment matching a regex for attachment counter.
Definition: mutt_parse.h:34
Log at debug level 5.
Definition: logging.h:44
Convenience wrapper for the library headers.
A List node for strings.
Definition: list.h:33
Content is inline.
Definition: mime.h:62
struct ListHead AttachAllow
List of attachment types to be counted.
Definition: mutt_parse.c:38
const char * minor
Definition: mutt_parse.h:38
SecurityFlags crypt_query(struct Body *m)
Check out the type of encryption used.
Definition: crypt.c:700
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
return a stream pointer for a message
Definition: mx.c:1123
Log at debug level 3.
Definition: logging.h:42
int msgno
Number displayed to the user.
Definition: email.h:86