* uip/sendsbr.c: replaced st_mtim with st_mtime, that's what
[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     if (ct->c_dispo)
105         free (ct->c_dispo);
106
107     if (ct->c_file) {
108         if (ct->c_unlink)
109             unlink (ct->c_file);
110         free (ct->c_file);
111     }
112     if (ct->c_fp)
113         fclose (ct->c_fp);
114
115     if (ct->c_storage)
116         free (ct->c_storage);
117     if (ct->c_folder)
118         free (ct->c_folder);
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     char **ap;
154     CI ci;
155
156     ci = &ct->c_ctinfo;
157     if (ci->ci_type) {
158         free (ci->ci_type);
159         ci->ci_type = NULL;
160     }
161     if (ci->ci_subtype) {
162         free (ci->ci_subtype);
163         ci->ci_subtype = NULL;
164     }
165     for (ap = ci->ci_attrs; *ap; ap++) {
166         free (*ap);
167         *ap = NULL;
168     }
169     if (ci->ci_comment) {
170         free (ci->ci_comment);
171         ci->ci_comment = NULL;
172     }
173     if (ci->ci_magic) {
174         free (ci->ci_magic);
175         ci->ci_magic = NULL;
176     }
177 }
178
179
180 static void
181 free_text (CT ct)
182 {
183     struct text *t;
184
185     if (!(t = (struct text *) ct->c_ctparams))
186         return;
187
188     free ((char *) t);
189     ct->c_ctparams = NULL;
190 }
191
192
193 static void
194 free_multi (CT ct)
195 {
196     struct multipart *m;
197     struct part *part, *next;
198
199     if (!(m = (struct multipart *) ct->c_ctparams))
200         return;
201
202     if (m->mp_start)
203         free (m->mp_start);
204     if (m->mp_stop)
205         free (m->mp_stop);
206         
207     for (part = m->mp_parts; part; part = next) {
208         next = part->mp_next;
209         free_content (part->mp_part);
210         free ((char *) part);
211     }
212     m->mp_parts = NULL;
213
214     free ((char *) m);
215     ct->c_ctparams = NULL;
216 }
217
218
219 static void
220 free_partial (CT ct)
221 {
222     struct partial *p;
223
224     if (!(p = (struct partial *) ct->c_ctparams))
225         return;
226
227     if (p->pm_partid)
228         free (p->pm_partid);
229
230     free ((char *) p);
231     ct->c_ctparams = NULL;
232 }
233
234
235 static void
236 free_external (CT ct)
237 {
238     struct exbody *e;
239
240     if (!(e = (struct exbody *) ct->c_ctparams))
241         return;
242
243     free_content (e->eb_content);
244     if (e->eb_body)
245         free (e->eb_body);
246
247     free ((char *) e);
248     ct->c_ctparams = NULL;
249 }
250
251
252 /*
253  * Free data structures related to encoding/decoding
254  * Content-Transfer-Encodings.
255  */
256
257 void
258 free_encoding (CT ct, int toplevel)
259 {
260     CE ce;
261
262     if (!(ce = ct->c_cefile))
263         return;
264
265     if (ce->ce_fp) {
266         fclose (ce->ce_fp);
267         ce->ce_fp = NULL;
268     }
269
270     if (ce->ce_file) {
271         if (ce->ce_unlink)
272             unlink (ce->ce_file);
273         free (ce->ce_file);
274         ce->ce_file = NULL;
275     }
276
277     if (toplevel) {
278         free ((char *) ce);
279         ct->c_cefile = NULL;
280     } else {
281         ct->c_ceopenfnx = NULL;
282     }
283 }