]> diplodocus.org Git - nmh/blob - uip/mhfree.c
Escape literal leading full stop in man/new.man.
[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 default:
81 /* Assume that the ct is for text. mhfixmsg(1) uses it for
82 decoding application content. */
83 free_text (ct);
84 break;
85 }
86
87 mh_xfree(ct->c_showproc);
88 mh_xfree(ct->c_termproc);
89 mh_xfree(ct->c_storeproc);
90 ct->c_showproc = ct->c_termproc = ct->c_storeproc = NULL;
91
92 mh_xfree(ct->c_celine);
93 ct->c_celine = NULL;
94
95 /* free structures for content encodings */
96 free_encoding (ct, 1);
97
98 mh_xfree(ct->c_id);
99 mh_xfree(ct->c_descr);
100 mh_xfree(ct->c_dispo);
101 mh_xfree(ct->c_dispo_type);
102 ct->c_id = ct->c_descr = ct->c_dispo = ct->c_dispo_type = NULL;
103 free_pmlist (&ct->c_dispo_first);
104
105 if (ct->c_file) {
106 if (ct->c_unlink)
107 (void) m_unlink (ct->c_file);
108 free (ct->c_file);
109 ct->c_file = NULL;
110 }
111 if (ct->c_fp) {
112 fclose (ct->c_fp);
113 ct->c_fp = NULL;
114 }
115
116 mh_xfree(ct->c_storage);
117 mh_xfree(ct->c_folder);
118 ct->c_storage = ct->c_folder = NULL;
119
120 free (ct);
121 }
122
123
124 /*
125 * Free the linked list of header fields
126 * for this content.
127 */
128
129 void
130 free_header (CT ct)
131 {
132 HF hp1, hp2;
133
134 hp1 = ct->c_first_hf;
135 while (hp1) {
136 hp2 = hp1->next;
137
138 free (hp1->name);
139 free (hp1->value);
140 free (hp1);
141
142 hp1 = hp2;
143 }
144
145 ct->c_first_hf = NULL;
146 ct->c_last_hf = NULL;
147 }
148
149
150 void
151 free_ctinfo (CT ct)
152 {
153 CI ci;
154
155 ci = &ct->c_ctinfo;
156 mh_xfree(ci->ci_type);
157 mh_xfree(ci->ci_subtype);
158 ci->ci_type = ci->ci_subtype = NULL;
159 free_pmlist(&ci->ci_first_pm);
160 mh_xfree(ci->ci_comment);
161 mh_xfree(ci->ci_magic);
162 ci->ci_comment = ci->ci_magic = NULL;
163 }
164
165
166 static void
167 free_text (CT ct)
168 {
169 struct text *t;
170
171 if (!(t = (struct text *) ct->c_ctparams))
172 return;
173
174 free(t);
175 ct->c_ctparams = NULL;
176 }
177
178
179 static void
180 free_multi (CT ct)
181 {
182 struct multipart *m;
183 struct part *part, *next;
184
185 if (!(m = (struct multipart *) ct->c_ctparams))
186 return;
187
188 mh_xfree(m->mp_start);
189 mh_xfree(m->mp_stop);
190 free (m->mp_content_before);
191 free (m->mp_content_after);
192
193 for (part = m->mp_parts; part; part = next) {
194 next = part->mp_next;
195 free_content (part->mp_part);
196 free(part);
197 }
198 m->mp_parts = NULL;
199
200 free(m);
201 ct->c_ctparams = NULL;
202 }
203
204
205 static void
206 free_partial (CT ct)
207 {
208 struct partial *p;
209
210 if (!(p = (struct partial *) ct->c_ctparams))
211 return;
212
213 mh_xfree(p->pm_partid);
214
215 free(p);
216 ct->c_ctparams = NULL;
217 }
218
219
220 static void
221 free_external (CT ct)
222 {
223 struct exbody *e;
224
225 if (!(e = (struct exbody *) ct->c_ctparams))
226 return;
227
228 free_content (e->eb_content);
229 mh_xfree(e->eb_body);
230 mh_xfree(e->eb_url);
231 free(e);
232 ct->c_ctparams = NULL;
233 }
234
235
236 static void
237 free_pmlist (PM *p)
238 {
239 PM pm = *p, pm2;
240
241 while (pm != NULL) {
242 mh_xfree(pm->pm_name);
243 mh_xfree(pm->pm_value);
244 mh_xfree(pm->pm_charset);
245 mh_xfree(pm->pm_lang);
246 pm2 = pm->pm_next;
247 free(pm);
248 pm = pm2;
249 }
250
251 if (*p)
252 *p = NULL;
253 }
254
255
256 /*
257 * Free data structures related to encoding/decoding
258 * Content-Transfer-Encodings.
259 */
260
261 void
262 free_encoding (CT ct, int toplevel)
263 {
264 CE ce = &ct->c_cefile;
265
266 if (ce->ce_fp) {
267 fclose (ce->ce_fp);
268 ce->ce_fp = NULL;
269 }
270
271 if (ce->ce_file) {
272 if (ce->ce_unlink)
273 (void) m_unlink (ce->ce_file);
274 free (ce->ce_file);
275 ce->ce_file = NULL;
276 }
277
278 if (! toplevel) {
279 ct->c_ceopenfnx = NULL;
280 }
281 }
282
283
284 void
285 freects_done (int status)
286 {
287 CT *ctp;
288
289 for (ctp = cts; ctp && *ctp; ctp++)
290 free_content (*ctp);
291
292 free (cts);
293
294 exit (status);
295 }