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