Initial revision
[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
9 #include <h/mh.h>
10 #include <errno.h>
11 #include <h/mime.h>
12 #include <h/mhparse.h>
13
14 extern int errno;
15
16 /*
17  * prototypes
18  */
19 void free_content (CT);
20 void free_header (CT);
21 void free_ctinfo (CT);
22 void free_encoding (CT, int);
23
24 /*
25  * static prototypes
26  */
27 static void free_text (CT);
28 static void free_multi (CT);
29 static void free_partial (CT);
30 static void free_external (CT);
31
32
33 /*
34  * Primary routine to free a MIME content structure
35  */
36
37 void
38 free_content (CT ct)
39 {
40     if (!ct)
41         return;
42
43     /*
44      * free all the header fields
45      */
46     free_header (ct);
47
48     if (ct->c_partno)
49         free (ct->c_partno);
50
51     if (ct->c_vrsn)
52         free (ct->c_vrsn);
53
54     if (ct->c_ctline)
55         free (ct->c_ctline);
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     if (ct->c_showproc)
86         free (ct->c_showproc);
87     if (ct->c_termproc)
88         free (ct->c_termproc);
89     if (ct->c_storeproc)
90         free (ct->c_storeproc);
91
92     if (ct->c_celine)
93         free (ct->c_celine);
94
95     /* free structures for content encodings */
96     free_encoding (ct, 1);
97
98     if (ct->c_id)
99         free (ct->c_id);
100     if (ct->c_descr)
101         free (ct->c_descr);
102
103     if (ct->c_file) {
104         if (ct->c_unlink)
105             unlink (ct->c_file);
106         free (ct->c_file);
107     }
108     if (ct->c_fp)
109         fclose (ct->c_fp);
110
111     if (ct->c_storage)
112         free (ct->c_storage);
113     if (ct->c_folder)
114         free (ct->c_folder);
115
116     free (ct);
117 }
118
119
120 /*
121  * Free the linked list of header fields
122  * for this content.
123  */
124
125 void
126 free_header (CT ct)
127 {
128     HF hp1, hp2;
129
130     hp1 = ct->c_first_hf;
131     while (hp1) {
132         hp2 = hp1->next;
133
134         free (hp1->name);
135         free (hp1->value);
136         free (hp1);
137
138         hp1 = hp2;
139     }
140
141     ct->c_first_hf = NULL;
142     ct->c_last_hf  = NULL;
143 }
144
145
146 void
147 free_ctinfo (CT ct)
148 {
149     char **ap;
150     CI ci;
151
152     ci = &ct->c_ctinfo;
153     if (ci->ci_type) {
154         free (ci->ci_type);
155         ci->ci_type = NULL;
156     }
157     if (ci->ci_subtype) {
158         free (ci->ci_subtype);
159         ci->ci_subtype = NULL;
160     }
161     for (ap = ci->ci_attrs; *ap; ap++) {
162         free (*ap);
163         *ap = NULL;
164     }
165     if (ci->ci_comment) {
166         free (ci->ci_comment);
167         ci->ci_comment = NULL;
168     }
169     if (ci->ci_magic) {
170         free (ci->ci_magic);
171         ci->ci_magic = NULL;
172     }
173 }
174
175
176 static void
177 free_text (CT ct)
178 {
179     struct text *t;
180
181     if (!(t = (struct text *) ct->c_ctparams))
182         return;
183
184     free ((char *) t);
185     ct->c_ctparams = NULL;
186 }
187
188
189 static void
190 free_multi (CT ct)
191 {
192     struct multipart *m;
193     struct part *part, *next;
194
195     if (!(m = (struct multipart *) ct->c_ctparams))
196         return;
197
198     if (m->mp_start)
199         free (m->mp_start);
200     if (m->mp_stop)
201         free (m->mp_stop);
202         
203     for (part = m->mp_parts; part; part = next) {
204         next = part->mp_next;
205         free_content (part->mp_part);
206         free ((char *) part);
207     }
208     m->mp_parts = NULL;
209
210     free ((char *) m);
211     ct->c_ctparams = NULL;
212 }
213
214
215 static void
216 free_partial (CT ct)
217 {
218     struct partial *p;
219
220     if (!(p = (struct partial *) ct->c_ctparams))
221         return;
222
223     if (p->pm_partid)
224         free (p->pm_partid);
225
226     free ((char *) p);
227     ct->c_ctparams = NULL;
228 }
229
230
231 static void
232 free_external (CT ct)
233 {
234     struct exbody *e;
235
236     if (!(e = (struct exbody *) ct->c_ctparams))
237         return;
238
239     free_content (e->eb_content);
240     if (e->eb_body)
241         free (e->eb_body);
242
243     free ((char *) e);
244     ct->c_ctparams = NULL;
245 }
246
247
248 /*
249  * Free data structures related to encoding/decoding
250  * Content-Transfer-Encodings.
251  */
252
253 void
254 free_encoding (CT ct, int toplevel)
255 {
256     CE ce;
257
258     if (!(ce = ct->c_cefile))
259         return;
260
261     if (ce->ce_fp) {
262         fclose (ce->ce_fp);
263         ce->ce_fp = NULL;
264     }
265
266     if (ce->ce_file) {
267         if (ce->ce_unlink)
268             unlink (ce->ce_file);
269         free (ce->ce_file);
270     }
271
272     if (toplevel) {
273         free ((char *) ce);
274         ct->c_cefile = NULL;
275     } else {
276         ct->c_ceopenfnx = NULL;
277     }
278 }