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