Added -nocontentid (and -contentid, for symmetry) switch to mhbuild. This allows...
[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 /*
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
26 /*
27  * static prototypes
28  */
29 static void free_text (CT);
30 static void free_multi (CT);
31 static void free_partial (CT);
32 static void free_external (CT);
33
34
35 /*
36  * Primary routine to free a MIME content structure
37  */
38
39 void
40 free_content (CT ct)
41 {
42     if (!ct)
43         return;
44
45     /*
46      * free all the header fields
47      */
48     free_header (ct);
49
50     if (ct->c_partno)
51         free (ct->c_partno);
52
53     if (ct->c_vrsn)
54         free (ct->c_vrsn);
55
56     if (ct->c_ctline)
57         free (ct->c_ctline);
58
59     free_ctinfo (ct);
60
61     /*
62      * some of the content types have extra
63      * parts which need to be freed.
64      */
65     switch (ct->c_type) {
66         case CT_MULTIPART:
67             free_multi (ct);
68             break;
69
70         case CT_MESSAGE:
71             switch (ct->c_subtype) {
72                 case MESSAGE_PARTIAL:
73                     free_partial (ct);
74                     break;
75
76                 case MESSAGE_EXTERNAL:
77                     free_external (ct);
78                     break;
79             }
80             break;
81
82         case CT_TEXT:
83             free_text (ct);
84             break;
85     }
86
87     if (ct->c_showproc)
88         free (ct->c_showproc);
89     if (ct->c_termproc)
90         free (ct->c_termproc);
91     if (ct->c_storeproc)
92         free (ct->c_storeproc);
93
94     if (ct->c_celine)
95         free (ct->c_celine);
96
97     /* free structures for content encodings */
98     free_encoding (ct, 1);
99
100     if (ct->c_id)
101         free (ct->c_id);
102     if (ct->c_descr)
103         free (ct->c_descr);
104
105     if (ct->c_file) {
106         if (ct->c_unlink)
107             unlink (ct->c_file);
108         free (ct->c_file);
109     }
110     if (ct->c_fp)
111         fclose (ct->c_fp);
112
113     if (ct->c_storage)
114         free (ct->c_storage);
115     if (ct->c_folder)
116         free (ct->c_folder);
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     char **ap;
152     CI ci;
153
154     ci = &ct->c_ctinfo;
155     if (ci->ci_type) {
156         free (ci->ci_type);
157         ci->ci_type = NULL;
158     }
159     if (ci->ci_subtype) {
160         free (ci->ci_subtype);
161         ci->ci_subtype = NULL;
162     }
163     for (ap = ci->ci_attrs; *ap; ap++) {
164         free (*ap);
165         *ap = NULL;
166     }
167     if (ci->ci_comment) {
168         free (ci->ci_comment);
169         ci->ci_comment = NULL;
170     }
171     if (ci->ci_magic) {
172         free (ci->ci_magic);
173         ci->ci_magic = NULL;
174     }
175 }
176
177
178 static void
179 free_text (CT ct)
180 {
181     struct text *t;
182
183     if (!(t = (struct text *) ct->c_ctparams))
184         return;
185
186     free ((char *) t);
187     ct->c_ctparams = NULL;
188 }
189
190
191 static void
192 free_multi (CT ct)
193 {
194     struct multipart *m;
195     struct part *part, *next;
196
197     if (!(m = (struct multipart *) ct->c_ctparams))
198         return;
199
200     if (m->mp_start)
201         free (m->mp_start);
202     if (m->mp_stop)
203         free (m->mp_stop);
204         
205     for (part = m->mp_parts; part; part = next) {
206         next = part->mp_next;
207         free_content (part->mp_part);
208         free ((char *) part);
209     }
210     m->mp_parts = NULL;
211
212     free ((char *) m);
213     ct->c_ctparams = NULL;
214 }
215
216
217 static void
218 free_partial (CT ct)
219 {
220     struct partial *p;
221
222     if (!(p = (struct partial *) ct->c_ctparams))
223         return;
224
225     if (p->pm_partid)
226         free (p->pm_partid);
227
228     free ((char *) p);
229     ct->c_ctparams = NULL;
230 }
231
232
233 static void
234 free_external (CT ct)
235 {
236     struct exbody *e;
237
238     if (!(e = (struct exbody *) ct->c_ctparams))
239         return;
240
241     free_content (e->eb_content);
242     if (e->eb_body)
243         free (e->eb_body);
244
245     free ((char *) e);
246     ct->c_ctparams = NULL;
247 }
248
249
250 /*
251  * Free data structures related to encoding/decoding
252  * Content-Transfer-Encodings.
253  */
254
255 void
256 free_encoding (CT ct, int toplevel)
257 {
258     CE ce;
259
260     if (!(ce = ct->c_cefile))
261         return;
262
263     if (ce->ce_fp) {
264         fclose (ce->ce_fp);
265         ce->ce_fp = NULL;
266     }
267
268     if (ce->ce_file) {
269         if (ce->ce_unlink)
270             unlink (ce->ce_file);
271         free (ce->ce_file);
272         ce->ce_file = NULL;
273     }
274
275     if (toplevel) {
276         free ((char *) ce);
277         ct->c_cefile = NULL;
278     } else {
279         ct->c_ceopenfnx = NULL;
280     }
281 }