]> diplodocus.org Git - nmh/blob - uip/mhfree.c
Cope with sasl_decode64() returning SASL_CONTINUE as well as SASL_OK.
[nmh] / uip / mhfree.c
1
2 /*
3 * mhfree.c -- routines to free the data structures used to
4 * -- represent MIME messages
5 *
6 * $Id$
7 *
8 * This code is Copyright (c) 2002, by the authors of nmh. See the
9 * COPYRIGHT file in the root directory of the nmh distribution for
10 * complete copyright information.
11 */
12
13 #include <h/mh.h>
14 #include <errno.h>
15 #include <h/mime.h>
16 #include <h/mhparse.h>
17
18 /* The list of top-level contents to display */
19 CT *cts = NULL;
20
21 /*
22 * prototypes
23 */
24 void free_content (CT);
25 void free_header (CT);
26 void free_ctinfo (CT);
27 void free_encoding (CT, int);
28 void freects_done (int);
29
30 /*
31 * static prototypes
32 */
33 static void free_text (CT);
34 static void free_multi (CT);
35 static void free_partial (CT);
36 static void free_external (CT);
37
38
39 /*
40 * Primary routine to free a MIME content structure
41 */
42
43 void
44 free_content (CT ct)
45 {
46 if (!ct)
47 return;
48
49 /*
50 * free all the header fields
51 */
52 free_header (ct);
53
54 if (ct->c_partno)
55 free (ct->c_partno);
56
57 if (ct->c_vrsn)
58 free (ct->c_vrsn);
59
60 if (ct->c_ctline)
61 free (ct->c_ctline);
62
63 free_ctinfo (ct);
64
65 /*
66 * some of the content types have extra
67 * parts which need to be freed.
68 */
69 switch (ct->c_type) {
70 case CT_MULTIPART:
71 free_multi (ct);
72 break;
73
74 case CT_MESSAGE:
75 switch (ct->c_subtype) {
76 case MESSAGE_PARTIAL:
77 free_partial (ct);
78 break;
79
80 case MESSAGE_EXTERNAL:
81 free_external (ct);
82 break;
83 }
84 break;
85
86 case CT_TEXT:
87 free_text (ct);
88 break;
89 }
90
91 if (ct->c_showproc)
92 free (ct->c_showproc);
93 if (ct->c_termproc)
94 free (ct->c_termproc);
95 if (ct->c_storeproc)
96 free (ct->c_storeproc);
97
98 if (ct->c_celine)
99 free (ct->c_celine);
100
101 /* free structures for content encodings */
102 free_encoding (ct, 1);
103
104 if (ct->c_id)
105 free (ct->c_id);
106 if (ct->c_descr)
107 free (ct->c_descr);
108 if (ct->c_dispo)
109 free (ct->c_dispo);
110
111 if (ct->c_file) {
112 if (ct->c_unlink)
113 unlink (ct->c_file);
114 free (ct->c_file);
115 }
116 if (ct->c_fp)
117 fclose (ct->c_fp);
118
119 if (ct->c_storage)
120 free (ct->c_storage);
121 if (ct->c_folder)
122 free (ct->c_folder);
123
124 free (ct);
125 }
126
127
128 /*
129 * Free the linked list of header fields
130 * for this content.
131 */
132
133 void
134 free_header (CT ct)
135 {
136 HF hp1, hp2;
137
138 hp1 = ct->c_first_hf;
139 while (hp1) {
140 hp2 = hp1->next;
141
142 free (hp1->name);
143 free (hp1->value);
144 free (hp1);
145
146 hp1 = hp2;
147 }
148
149 ct->c_first_hf = NULL;
150 ct->c_last_hf = NULL;
151 }
152
153
154 void
155 free_ctinfo (CT ct)
156 {
157 char **ap;
158 CI ci;
159
160 ci = &ct->c_ctinfo;
161 if (ci->ci_type) {
162 free (ci->ci_type);
163 ci->ci_type = NULL;
164 }
165 if (ci->ci_subtype) {
166 free (ci->ci_subtype);
167 ci->ci_subtype = NULL;
168 }
169 for (ap = ci->ci_attrs; *ap; ap++) {
170 free (*ap);
171 *ap = NULL;
172 }
173 if (ci->ci_comment) {
174 free (ci->ci_comment);
175 ci->ci_comment = NULL;
176 }
177 if (ci->ci_magic) {
178 free (ci->ci_magic);
179 ci->ci_magic = NULL;
180 }
181 }
182
183
184 static void
185 free_text (CT ct)
186 {
187 struct text *t;
188
189 if (!(t = (struct text *) ct->c_ctparams))
190 return;
191
192 free ((char *) t);
193 ct->c_ctparams = NULL;
194 }
195
196
197 static void
198 free_multi (CT ct)
199 {
200 struct multipart *m;
201 struct part *part, *next;
202
203 if (!(m = (struct multipart *) ct->c_ctparams))
204 return;
205
206 if (m->mp_start)
207 free (m->mp_start);
208 if (m->mp_stop)
209 free (m->mp_stop);
210
211 for (part = m->mp_parts; part; part = next) {
212 next = part->mp_next;
213 free_content (part->mp_part);
214 free ((char *) part);
215 }
216 m->mp_parts = NULL;
217
218 free ((char *) m);
219 ct->c_ctparams = NULL;
220 }
221
222
223 static void
224 free_partial (CT ct)
225 {
226 struct partial *p;
227
228 if (!(p = (struct partial *) ct->c_ctparams))
229 return;
230
231 if (p->pm_partid)
232 free (p->pm_partid);
233
234 free ((char *) p);
235 ct->c_ctparams = NULL;
236 }
237
238
239 static void
240 free_external (CT ct)
241 {
242 struct exbody *e;
243
244 if (!(e = (struct exbody *) ct->c_ctparams))
245 return;
246
247 free_content (e->eb_content);
248 if (e->eb_body)
249 free (e->eb_body);
250
251 free ((char *) e);
252 ct->c_ctparams = NULL;
253 }
254
255
256 /*
257 * Free data structures related to encoding/decoding
258 * Content-Transfer-Encodings.
259 */
260
261 void
262 free_encoding (CT ct, int toplevel)
263 {
264 CE ce;
265
266 if (!(ce = ct->c_cefile))
267 return;
268
269 if (ce->ce_fp) {
270 fclose (ce->ce_fp);
271 ce->ce_fp = NULL;
272 }
273
274 if (ce->ce_file) {
275 if (ce->ce_unlink)
276 unlink (ce->ce_file);
277 free (ce->ce_file);
278 ce->ce_file = NULL;
279 }
280
281 if (toplevel) {
282 free ((char *) ce);
283 ct->c_cefile = NULL;
284 } else {
285 ct->c_ceopenfnx = NULL;
286 }
287 }
288
289
290 void
291 freects_done (int status)
292 {
293 CT *ctp;
294
295 if ((ctp = cts))
296 for (; *ctp; ctp++)
297 free_content (*ctp);
298
299 exit (status);
300 }