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