NeoMutt  2020-08-21-74-g346364
Teaching an old dog new tricks
DOXYGEN
mutt_parse.c File Reference

Miscellaneous email parsing routines. More...

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

Go to the source code of this file.

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)
 Count the MIME Body parts. More...
 
int mutt_count_body_parts (struct Mailbox *m, struct Email *e)
 Count the MIME Body parts. More...
 
void mutt_attachmatch_free (struct AttachMatch **ptr)
 Free an AttachMatch - Implements list_free_t. More...
 

Variables

struct ListHead AttachAllow = STAILQ_HEAD_INITIALIZER(AttachAllow)
 List of attachment types to be counted. More...
 
struct ListHead AttachExclude = STAILQ_HEAD_INITIALIZER(AttachExclude)
 List of attachment types to be ignored. More...
 
struct ListHead InlineAllow = STAILQ_HEAD_INITIALIZER(InlineAllow)
 List of inline types to counted. More...
 
struct ListHead InlineExclude = STAILQ_HEAD_INITIALIZER(InlineExclude)
 List of inline types to ignore. 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.

Function Documentation

◆ mutt_parse_mime_message()

void mutt_parse_mime_message ( struct Mailbox m,
struct Email e 
)

Parse a MIME email.

Parameters
mMailbox
eEmail

Definition at line 48 of file mutt_parse.c.

49 {
50  do
51  {
52  if ((e->body->type != TYPE_MESSAGE) && (e->body->type != TYPE_MULTIPART))
53  break; /* nothing to do */
54 
55  if (e->body->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->body);
62 
63  if (WithCrypto)
64  e->security = crypt_query(e->body);
65 
66  mx_msg_close(m, &msg);
67  }
68  } while (false);
69 
70  e->attach_valid = false;
71 }
#define WithCrypto
Definition: lib.h:123
struct Body * body
List of MIME parts.
Definition: email.h:91
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1206
A local copy of an email.
Definition: mx.h:82
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
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
void mutt_parse_part(FILE *fp, struct Body *b)
Parse a MIME part.
Definition: parse.c:1657
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
FILE * fp
pointer to the message data
Definition: mx.h:84
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
int msgno
Number displayed to the user.
Definition: email.h:87
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ count_body_parts_check()

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 80 of file mutt_parse.c.

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) == 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 }
enum ContentType major_int
Definition: mutt_parse.h:37
Type: &#39;*&#39; or &#39;.*&#39;.
Definition: mime.h:40
const char * major
Definition: mutt_parse.h:36
char * subtype
content-type subtype
Definition: body.h:37
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
unsigned int type
content-type primary type, ContentType
Definition: body.h:65
char * data
String.
Definition: list.h:36
regex_t minor_regex
Definition: mutt_parse.h:39
#define STAILQ_EMPTY(head)
Definition: queue.h:345
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
An attachment matching a regex for attachment counter.
Definition: mutt_parse.h:34
A List node for strings.
Definition: list.h:34
const char * minor
Definition: mutt_parse.h:38
Log at debug level 3.
Definition: logging.h:42
+ Here is the caller graph for this function:

◆ count_body_parts()

static int count_body_parts ( struct Body body)
static

Count the MIME Body parts.

Parameters
bodyBody of email
Return values
numNumber of MIME Body parts

Definition at line 116 of file mutt_parse.c.

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_istr_equal(bp->subtype, "external-body"))
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_istr_equal(bp->subtype, "alternative"))
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 }
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
struct ListHead InlineAllow
List of inline types to counted.
Definition: mutt_parse.c:40
struct Body * next
next attachment in the list
Definition: body.h:53
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
Content is attached.
Definition: mime.h:63
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:883
struct ListHead InlineExclude
List of inline types to ignore.
Definition: mutt_parse.c:41
Type: &#39;message/*&#39;.
Definition: mime.h:35
struct ListHead AttachExclude
List of attachment types to be ignored.
Definition: mutt_parse.c:39
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
Log at debug level 5.
Definition: logging.h:44
Content is inline.
Definition: mime.h:62
struct ListHead AttachAllow
List of attachment types to be counted.
Definition: mutt_parse.c:38
Log at debug level 3.
Definition: logging.h:42
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_count_body_parts()

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 205 of file mutt_parse.c.

206 {
207  bool keep_parts = false;
208 
209  if (e->attach_valid)
210  return e->attach_total;
211 
212  if (e->body->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)
228  mutt_body_free(&e->body->parts);
229 
230  return e->attach_total;
231 }
struct Body * body
List of MIME parts.
Definition: email.h:91
struct ListHead InlineAllow
List of inline types to counted.
Definition: mutt_parse.c:40
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e)
Parse a MIME email.
Definition: mutt_parse.c:48
static int count_body_parts(struct Body *body)
Count the MIME Body parts.
Definition: mutt_parse.c:116
short attach_total
Number of qualifying attachments in message, if attach_valid.
Definition: email.h:97
struct ListHead InlineExclude
List of inline types to ignore.
Definition: mutt_parse.c:41
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
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
struct ListHead AttachExclude
List of attachment types to be ignored.
Definition: mutt_parse.c:39
#define STAILQ_EMPTY(head)
Definition: queue.h:345
struct ListHead AttachAllow
List of attachment types to be counted.
Definition: mutt_parse.c:38
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_attachmatch_free()

void mutt_attachmatch_free ( struct AttachMatch **  ptr)

Free an AttachMatch - Implements list_free_t.

Parameters
ptrAttachMatch to free
Note
We don't free minor because it is either a pointer into major, or a static string.

Definition at line 240 of file mutt_parse.c.

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 }
const char * major
Definition: mutt_parse.h:36
regex_t minor_regex
Definition: mutt_parse.h:39
#define FREE(x)
Definition: memory.h:40
An attachment matching a regex for attachment counter.
Definition: mutt_parse.h:34
+ Here is the caller graph for this function:

Variable Documentation

◆ AttachAllow

struct ListHead AttachAllow = STAILQ_HEAD_INITIALIZER(AttachAllow)

List of attachment types to be counted.

Definition at line 38 of file mutt_parse.c.

◆ AttachExclude

struct ListHead AttachExclude = STAILQ_HEAD_INITIALIZER(AttachExclude)

List of attachment types to be ignored.

Definition at line 39 of file mutt_parse.c.

◆ InlineAllow

struct ListHead InlineAllow = STAILQ_HEAD_INITIALIZER(InlineAllow)

List of inline types to counted.

Definition at line 40 of file mutt_parse.c.

◆ InlineExclude

struct ListHead InlineExclude = STAILQ_HEAD_INITIALIZER(InlineExclude)

List of inline types to ignore.

Definition at line 41 of file mutt_parse.c.