]> diplodocus.org Git - nmh/blob - uip/mhfree.c
aa5d9ea22b3ed80e6f8a85e09998273e5af1f0a4
[nmh] / uip / mhfree.c
1 /*
2 * mhfree.c -- routines to free the data structures used to
3 * -- represent MIME messages
4 *
5 * This code is Copyright (c) 2002, by the authors of nmh. See the
6 * COPYRIGHT file in the root directory of the nmh distribution for
7 * complete copyright information.
8 */
9
10 #include <h/mh.h>
11 #include <h/utils.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 mh_xfree(ct->c_partno);
52 mh_xfree(ct->c_vrsn);
53 mh_xfree(ct->c_ctline);
54 ct->c_partno = ct->c_vrsn = ct->c_ctline = NULL;
55
56 free_ctinfo (ct);
57
58 /*
59 * some of the content types have extra
60 * parts which need to be freed.
61 */
62 switch (ct->c_type) {
63 case CT_MULTIPART:
64 free_multi (ct);
65 break;
66
67 case CT_MESSAGE:
68 switch (ct->c_subtype) {
69 case MESSAGE_PARTIAL:
70 free_partial (ct);
71 break;
72
73 case MESSAGE_EXTERNAL:
74 free_external (ct);
75 break;
76 }
77 break;
78
79 default:
80 /* Assume that the ct is for text. mhfixmsg(1) uses it for
81 decoding application content. */
82 free_text (ct);
83 break;
84 }
85
86 mh_xfree(ct->c_showproc);
87 mh_xfree(ct->c_termproc);
88 mh_xfree(ct->c_storeproc);
89 ct->c_showproc = ct->c_termproc = ct->c_storeproc = NULL;
90
91 mh_xfree(ct->c_celine);
92 ct->c_celine = NULL;
93
94 /* free structures for content encodings */
95 free_encoding (ct, 1);
96
97 mh_xfree(ct->c_id);
98 mh_xfree(ct->c_descr);
99 mh_xfree(ct->c_dispo);
100 mh_xfree(ct->c_dispo_type);
101 ct->c_id = ct->c_descr = ct->c_dispo = ct->c_dispo_type = NULL;
102 free_pmlist (&ct->c_dispo_first);
103
104 if (ct->c_file) {
105 if (ct->c_unlink)
106 (void) m_unlink (ct->c_file);
107 free (ct->c_file);
108 ct->c_file = NULL;
109 }
110 if (ct->c_fp) {
111 fclose (ct->c_fp);
112 ct->c_fp = NULL;
113 }
114
115 mh_xfree(ct->c_storage);
116 mh_xfree(ct->c_folder);
117 ct->c_storage = ct->c_folder = NULL;
118
119 free (ct);
120 }
121
122
123 /*
124 * Free the linked list of header fields
125 * for this content.
126 */
127
128 void
129 free_header (CT ct)
130 {
131 HF hp1, hp2;
132
133 hp1 = ct->c_first_hf;
134 while (hp1) {
135 hp2 = hp1->next;
136
137 free (hp1->name);
138 free (hp1->value);
139 free (hp1);
140
141 hp1 = hp2;
142 }
143
144 ct->c_first_hf = NULL;
145 ct->c_last_hf = NULL;
146 }
147
148
149 void
150 free_ctinfo (CT ct)
151 {
152 CI ci;
153
154 ci = &ct->c_ctinfo;
155 mh_xfree(ci->ci_type);
156 mh_xfree(ci->ci_subtype);
157 ci->ci_type = ci->ci_subtype = NULL;
158 free_pmlist(&ci->ci_first_pm);
159 mh_xfree(ci->ci_comment);
160 mh_xfree(ci->ci_magic);
161 ci->ci_comment = ci->ci_magic = NULL;
162 }
163
164
165 static void
166 free_text (CT ct)
167 {
168 struct text *t;
169
170 if (!(t = (struct text *) ct->c_ctparams))
171 return;
172
173 free(t);
174 ct->c_ctparams = NULL;
175 }
176
177
178 static void
179 free_multi (CT ct)
180 {
181 struct multipart *m;
182 struct part *part, *next;
183
184 if (!(m = (struct multipart *) ct->c_ctparams))
185 return;
186
187 mh_xfree(m->mp_start);
188 mh_xfree(m->mp_stop);
189 free (m->mp_content_before);
190 free (m->mp_content_after);
191
192 for (part = m->mp_parts; part; part = next) {
193 next = part->mp_next;
194 free_content (part->mp_part);
195 free(part);
196 }
197 m->mp_parts = NULL;
198
199 free(m);
200 ct->c_ctparams = NULL;
201 }
202
203
204 static void
205 free_partial (CT ct)
206 {
207 struct partial *p;
208
209 if (!(p = (struct partial *) ct->c_ctparams))
210 return;
211
212 mh_xfree(p->pm_partid);
213
214 free(p);
215 ct->c_ctparams = NULL;
216 }
217
218
219 static void
220 free_external (CT ct)
221 {
222 struct exbody *e;
223
224 if (!(e = (struct exbody *) ct->c_ctparams))
225 return;
226
227 free_content (e->eb_content);
228 mh_xfree(e->eb_body);
229 mh_xfree(e->eb_url);
230 free(e);
231 ct->c_ctparams = NULL;
232 }
233
234
235 static void
236 free_pmlist (PM *p)
237 {
238 PM pm = *p, pm2;
239
240 while (pm != NULL) {
241 mh_xfree(pm->pm_name);
242 mh_xfree(pm->pm_value);
243 mh_xfree(pm->pm_charset);
244 mh_xfree(pm->pm_lang);
245 pm2 = pm->pm_next;
246 free(pm);
247 pm = pm2;
248 }
249
250 if (*p)
251 *p = 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 = &ct->c_cefile;
264
265 if (ce->ce_fp) {
266 fclose (ce->ce_fp);
267 ce->ce_fp = NULL;
268 }
269
270 if (ce->ce_file) {
271 if (ce->ce_unlink)
272 (void) m_unlink (ce->ce_file);
273 free (ce->ce_file);
274 ce->ce_file = NULL;
275 }
276
277 if (! toplevel) {
278 ct->c_ceopenfnx = NULL;
279 }
280 }
281
282
283 void
284 freects_done (int status)
285 {
286 CT *ctp;
287
288 for (ctp = cts; ctp && *ctp; ctp++)
289 free_content (*ctp);
290
291 free (cts);
292
293 exit (status);
294 }