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