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