1 /**
2 * @file
3 * Representation of the body of an email
4 *
5 * @authors
6 * Copyright (C) 2017 Richard Russon <rich@flatcap.org>
7 *
8 * @copyright
9 * This program is free software: you can redistribute it and/or modify it under
10 * the terms of the GNU General Public License as published by the Free Software
11 * Foundation, either version 2 of the License, or (at your option) any later
12 * version.
13 *
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU General Public License along with
20 * this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 /**
24 * @page email_body Body of an Email
25 *
26 * Representation of the body of an email
27 */
28
29 #include "config.h"
30 #include <stdbool.h>
31 #include <unistd.h>
32 #include "mutt/lib.h"
33 #include "body.h"
34 #include "email.h"
35 #include "envelope.h"
36 #include "mime.h"
37 #include "parameter.h"
38
39 /**
40 * mutt_body_new - Create a new Body
41 * @retval ptr Newly allocated Body
42 */
mutt_body_new(void)43 struct Body *mutt_body_new(void)
44 {
45 struct Body *p = mutt_mem_calloc(1, sizeof(struct Body));
46
47 p->disposition = DISP_ATTACH;
48 p->use_disp = true;
49 TAILQ_INIT(&p->parameter);
50 return p;
51 }
52
53 /**
54 * mutt_body_free - Free a Body
55 * @param[out] ptr Body to free
56 */
mutt_body_free(struct Body ** ptr)57 void mutt_body_free(struct Body **ptr)
58 {
59 if (!ptr)
60 return;
61
62 struct Body *a = *ptr, *b = NULL;
63
64 while (a)
65 {
66 b = a;
67 a = a->next;
68
69 mutt_param_free(&b->parameter);
70 if (b->filename)
71 {
72 if (b->unlink)
73 unlink(b->filename);
74 mutt_debug(LL_DEBUG1, "%sunlinking %s\n", b->unlink ? "" : "not ", b->filename);
75 }
76
77 FREE(&b->filename);
78 FREE(&b->d_filename);
79 FREE(&b->charset);
80 FREE(&b->content);
81 FREE(&b->xtype);
82 FREE(&b->subtype);
83 FREE(&b->language);
84 FREE(&b->description);
85 FREE(&b->form_name);
86
87 if (b->email)
88 {
89 /* Don't free twice (b->email->body = b->parts) */
90 b->email->body = NULL;
91 email_free(&b->email);
92 }
93
94 mutt_env_free(&b->mime_headers);
95 mutt_body_free(&b->parts);
96 FREE(&b);
97 }
98
99 *ptr = NULL;
100 }
101
102 /**
103 * mutt_body_cmp_strict - Strictly compare two email Body's
104 * @param b1 First Body
105 * @param b2 Second Body
106 * @retval true Body's are strictly identical
107 */
mutt_body_cmp_strict(const struct Body * b1,const struct Body * b2)108 bool mutt_body_cmp_strict(const struct Body *b1, const struct Body *b2)
109 {
110 if (!b1 || !b2)
111 return false;
112
113 if ((b1->type != b2->type) || (b1->encoding != b2->encoding) ||
114 !mutt_str_equal(b1->subtype, b2->subtype) ||
115 !mutt_str_equal(b1->description, b2->description) ||
116 !mutt_param_cmp_strict(&b1->parameter, &b2->parameter) || (b1->length != b2->length))
117 {
118 return false;
119 }
120 return true;
121 }
122
123 /**
124 * mutt_body_get_charset - Get a body's character set
125 * @param b Body to examine
126 * @param buf Buffer for the result
127 * @param buflen Length of the buffer
128 * @retval ptr Buffer containing character set
129 * @retval NULL On error, or if not a text type
130 */
mutt_body_get_charset(struct Body * b,char * buf,size_t buflen)131 char *mutt_body_get_charset(struct Body *b, char *buf, size_t buflen)
132 {
133 char *p = NULL;
134
135 if (b && (b->type != TYPE_TEXT))
136 return NULL;
137
138 if (b)
139 p = mutt_param_get(&b->parameter, "charset");
140
141 if (p)
142 mutt_ch_canonical_charset(buf, buflen, p);
143 else
144 mutt_str_copy(buf, "us-ascii", buflen);
145
146 return buf;
147 }
148