df0ee4658eb3f6af5c91c7502da3b3468b8cfe67
[mmh] / uip / mhfree.c
1
2 /*
3  * mhfree.c -- routines to free the data structures used to
4  *          -- represent MIME messages
5  *
6  * $Id$
7  *
8  * This code is Copyright (c) 2002, by the authors of nmh.  See the
9  * COPYRIGHT file in the root directory of the nmh distribution for
10  * complete copyright information.
11  */
12
13 #include <h/mh.h>
14 #include <errno.h>
15 #include <h/mime.h>
16 #include <h/mhparse.h>
17
18 /* The list of top-level contents to display */
19 CT *cts = NULL;
20
21 /*
22  * prototypes
23  */
24 void free_content (CT);
25 void free_header (CT);
26 void free_ctinfo (CT);
27 void free_encoding (CT, int);
28 void freects_done (int);
29
30 /*
31  * static prototypes
32  */
33 static void free_text (CT);
34 static void free_multi (CT);
35 static void free_partial (CT);
36 static void free_external (CT);
37
38
39 /*
40  * Primary routine to free a MIME content structure
41  */
42
43 void
44 free_content (CT ct)
45 {
46     if (!ct)
47         return;
48
49     /*
50      * free all the header fields
51      */
52     free_header (ct);
53
54     if (ct->c_partno)
55         free (ct->c_partno);
56
57     if (ct->c_vrsn)
58         free (ct->c_vrsn);
59
60     if (ct->c_ctline)
61         free (ct->c_ctline);
62
63     free_ctinfo (ct);
64
65     /*
66      * some of the content types have extra
67      * parts which need to be freed.
68      */
69     switch (ct->c_type) {
70         case CT_MULTIPART:
71             free_multi (ct);
72             break;
73
74         case CT_MESSAGE:
75             switch (ct->c_subtype) {
76                 case MESSAGE_PARTIAL:
77                     free_partial (ct);
78                     break;
79
80                 case MESSAGE_EXTERNAL:
81                     free_external (ct);
82                     break;
83             }
84             break;
85
86         case CT_TEXT:
87             free_text (ct);
88             break;
89     }
90
91     if (ct->c_showproc)
92         free (ct->c_showproc);
93     if (ct->c_termproc)
94         free (ct->c_termproc);
95     if (ct->c_storeproc)
96         free (ct->c_storeproc);
97
98     if (ct->c_celine)
99         free (ct->c_celine);
100
101     /* free structures for content encodings */
102     free_encoding (ct, 1);
103
104     if (ct->c_id)
105         free (ct->c_id);
106     if (ct->c_descr)
107         free (ct->c_descr);
108     if (ct->c_dispo)
109         free (ct->c_dispo);
110
111     if (ct->c_file) {
112         if (ct->c_unlink)
113             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     char **ap;
158     CI ci;
159
160     ci = &ct->c_ctinfo;
161     if (ci->ci_type) {
162         free (ci->ci_type);
163         ci->ci_type = NULL;
164     }
165     if (ci->ci_subtype) {
166         free (ci->ci_subtype);
167         ci->ci_subtype = NULL;
168     }
169     for (ap = ci->ci_attrs; *ap; ap++) {
170         free (*ap);
171         *ap = NULL;
172     }
173     if (ci->ci_comment) {
174         free (ci->ci_comment);
175         ci->ci_comment = NULL;
176     }
177     if (ci->ci_magic) {
178         free (ci->ci_magic);
179         ci->ci_magic = NULL;
180     }
181 }
182
183
184 static void
185 free_text (CT ct)
186 {
187     struct text *t;
188
189     if (!(t = (struct text *) ct->c_ctparams))
190         return;
191
192     free ((char *) t);
193     ct->c_ctparams = NULL;
194 }
195
196
197 static void
198 free_multi (CT ct)
199 {
200     struct multipart *m;
201     struct part *part, *next;
202
203     if (!(m = (struct multipart *) ct->c_ctparams))
204         return;
205
206     if (m->mp_start)
207         free (m->mp_start);
208     if (m->mp_stop)
209         free (m->mp_stop);
210         
211     for (part = m->mp_parts; part; part = next) {
212         next = part->mp_next;
213         free_content (part->mp_part);
214         free ((char *) part);
215     }
216     m->mp_parts = NULL;
217
218     free ((char *) m);
219     ct->c_ctparams = NULL;
220 }
221
222
223 static void
224 free_partial (CT ct)
225 {
226     struct partial *p;
227
228     if (!(p = (struct partial *) ct->c_ctparams))
229         return;
230
231     if (p->pm_partid)
232         free (p->pm_partid);
233
234     free ((char *) p);
235     ct->c_ctparams = NULL;
236 }
237
238
239 static void
240 free_external (CT ct)
241 {
242     struct exbody *e;
243
244     if (!(e = (struct exbody *) ct->c_ctparams))
245         return;
246
247     free_content (e->eb_content);
248     if (e->eb_body)
249         free (e->eb_body);
250
251     free ((char *) e);
252     ct->c_ctparams = 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;
265
266     if (!(ce = ct->c_cefile))
267         return;
268
269     if (ce->ce_fp) {
270         fclose (ce->ce_fp);
271         ce->ce_fp = NULL;
272     }
273
274     if (ce->ce_file) {
275         if (ce->ce_unlink)
276             unlink (ce->ce_file);
277         free (ce->ce_file);
278         ce->ce_file = NULL;
279     }
280
281     if (toplevel) {
282         free ((char *) ce);
283         ct->c_cefile = NULL;
284     } else {
285         ct->c_ceopenfnx = NULL;
286     }
287 }
288
289
290 void
291 freects_done (int status)
292 {
293     CT *ctp;
294
295     if ((ctp = cts))
296         for (; *ctp; ctp++)
297             free_content (*ctp);
298
299     exit (status);
300 }