]> diplodocus.org Git - nmh/blob - uip/mhfree.c
Documentation improvements, from Ralph Corderoy.
[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 <h/mime.h>
13 #include <h/mhparse.h>
14
15 /* The list of top-level contents to display */
16 CT *cts = NULL;
17
18 /*
19 * prototypes
20 */
21 void free_header (CT);
22 void free_ctinfo (CT);
23 void free_encoding (CT, int);
24 void freects_done (int);
25
26 /*
27 * static prototypes
28 */
29 static void free_text (CT);
30 static void free_multi (CT);
31 static void free_partial (CT);
32 static void free_external (CT);
33 static void free_pmlist (PM);
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 if (ct->c_dispo_type)
108 free (ct->c_dispo_type);
109 free_pmlist (ct->c_dispo_first);
110
111 if (ct->c_file) {
112 if (ct->c_unlink)
113 (void) m_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 CI ci;
158
159 ci = &ct->c_ctinfo;
160 if (ci->ci_type) {
161 free (ci->ci_type);
162 ci->ci_type = NULL;
163 }
164 if (ci->ci_subtype) {
165 free (ci->ci_subtype);
166 ci->ci_subtype = NULL;
167 }
168 free_pmlist(ci->ci_first_pm);
169 if (ci->ci_comment) {
170 free (ci->ci_comment);
171 ci->ci_comment = NULL;
172 }
173 if (ci->ci_magic) {
174 free (ci->ci_magic);
175 ci->ci_magic = NULL;
176 }
177 }
178
179
180 static void
181 free_text (CT ct)
182 {
183 struct text *t;
184
185 if (!(t = (struct text *) ct->c_ctparams))
186 return;
187
188 free ((char *) t);
189 ct->c_ctparams = NULL;
190 }
191
192
193 static void
194 free_multi (CT ct)
195 {
196 struct multipart *m;
197 struct part *part, *next;
198
199 if (!(m = (struct multipart *) ct->c_ctparams))
200 return;
201
202 if (m->mp_start)
203 free (m->mp_start);
204 if (m->mp_stop)
205 free (m->mp_stop);
206 free (m->mp_content_before);
207 free (m->mp_content_after);
208
209 for (part = m->mp_parts; part; part = next) {
210 next = part->mp_next;
211 free_content (part->mp_part);
212 free ((char *) part);
213 }
214 m->mp_parts = NULL;
215
216 free ((char *) m);
217 ct->c_ctparams = NULL;
218 }
219
220
221 static void
222 free_partial (CT ct)
223 {
224 struct partial *p;
225
226 if (!(p = (struct partial *) ct->c_ctparams))
227 return;
228
229 if (p->pm_partid)
230 free (p->pm_partid);
231
232 free ((char *) p);
233 ct->c_ctparams = NULL;
234 }
235
236
237 static void
238 free_external (CT ct)
239 {
240 struct exbody *e;
241
242 if (!(e = (struct exbody *) ct->c_ctparams))
243 return;
244
245 free_content (e->eb_content);
246 if (e->eb_body)
247 free (e->eb_body);
248 if (e->eb_url)
249 free (e->eb_url);
250
251 free ((char *) e);
252 ct->c_ctparams = NULL;
253 }
254
255
256 static void
257 free_pmlist (PM pm)
258 {
259 PM pm2;
260
261 while (pm != NULL) {
262 if (pm->pm_name)
263 free (pm->pm_name);
264 if (pm->pm_value)
265 free (pm->pm_value);
266 if (pm->pm_charset)
267 free (pm->pm_charset);
268 if (pm->pm_lang)
269 free (pm->pm_lang);
270 pm2 = pm->pm_next;
271 free(pm);
272 pm = pm2;
273 }
274 }
275
276
277 /*
278 * Free data structures related to encoding/decoding
279 * Content-Transfer-Encodings.
280 */
281
282 void
283 free_encoding (CT ct, int toplevel)
284 {
285 CE ce = &ct->c_cefile;
286
287 if (ce->ce_fp) {
288 fclose (ce->ce_fp);
289 ce->ce_fp = NULL;
290 }
291
292 if (ce->ce_file) {
293 if (ce->ce_unlink)
294 (void) m_unlink (ce->ce_file);
295 free (ce->ce_file);
296 ce->ce_file = NULL;
297 }
298
299 if (! toplevel) {
300 ct->c_ceopenfnx = NULL;
301 }
302 }
303
304
305 void
306 freects_done (int status)
307 {
308 CT *ctp;
309
310 if ((ctp = cts))
311 for (; *ctp; ctp++)
312 free_content (*ctp);
313
314 exit (status);
315 }