c87306691f453bb4a6753700c4eab7a8738a4dc3
[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 #include <unistd.h>
15
16 /* The list of top-level contents to display */
17 CT *cts = NULL;
18
19 /*
20 ** prototypes
21 */
22 void free_content(CT);
23 void free_header(CT);
24 void free_ctinfo(CT);
25 void free_encoding(CT, int);
26 void freects_done();
27
28 /*
29 ** static prototypes
30 */
31 static void free_text(CT);
32 static void free_multi(CT);
33 static void free_partial(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                 if (ct->c_subtype == MESSAGE_PARTIAL) {
73                         free_partial(ct);
74                 }
75                 break;
76
77         case CT_TEXT:
78                 free_text(ct);
79                 break;
80         }
81
82         if (ct->c_charset)
83                 free(ct->c_charset);
84         if (ct->c_showproc)
85                 free(ct->c_showproc);
86         if (ct->c_storeproc)
87                 free(ct->c_storeproc);
88
89         if (ct->c_celine)
90                 free(ct->c_celine);
91
92         /* free structures for content encodings */
93         free_encoding(ct, 1);
94
95         if (ct->c_id)
96                 free(ct->c_id);
97         if (ct->c_descr)
98                 free(ct->c_descr);
99         if (ct->c_dispo)
100                 free(ct->c_dispo);
101
102         if (ct->c_file) {
103                 if (ct->c_unlink)
104                         unlink(ct->c_file);
105                 free(ct->c_file);
106         }
107         if (ct->c_fp)
108                 fclose(ct->c_fp);
109
110         if (ct->c_storage)
111                 free(ct->c_storage);
112         if (ct->c_folder)
113                 free(ct->c_folder);
114
115         free(ct);
116 }
117
118
119 /*
120 ** Free the linked list of header fields
121 ** for this content.
122 */
123
124 void
125 free_header(CT ct)
126 {
127         HF hp1, hp2;
128
129         hp1 = ct->c_first_hf;
130         while (hp1) {
131                 hp2 = hp1->next;
132
133                 free(hp1->name);
134                 free(hp1->value);
135                 free(hp1);
136
137                 hp1 = hp2;
138         }
139
140         ct->c_first_hf = NULL;
141         ct->c_last_hf  = NULL;
142 }
143
144
145 void
146 free_ctinfo(CT ct)
147 {
148         char **ap;
149         CI ci;
150
151         ci = &ct->c_ctinfo;
152         if (ci->ci_type) {
153                 free(ci->ci_type);
154                 ci->ci_type = NULL;
155         }
156         if (ci->ci_subtype) {
157                 free(ci->ci_subtype);
158                 ci->ci_subtype = NULL;
159         }
160         for (ap = ci->ci_attrs; *ap; ap++) {
161                 free(*ap);
162                 *ap = NULL;
163         }
164         if (ci->ci_comment) {
165                 free(ci->ci_comment);
166                 ci->ci_comment = NULL;
167         }
168         if (ci->ci_magic) {
169                 free(ci->ci_magic);
170                 ci->ci_magic = NULL;
171         }
172 }
173
174
175 static void
176 free_text(CT ct)
177 {
178         struct text *t;
179
180         if (!(t = (struct text *) ct->c_ctparams))
181                 return;
182
183         free((char *) t);
184         ct->c_ctparams = NULL;
185 }
186
187
188 static void
189 free_multi(CT ct)
190 {
191         struct multipart *m;
192         struct part *part, *next;
193
194         if (!(m = (struct multipart *) ct->c_ctparams))
195                 return;
196
197         if (m->mp_start)
198                 free(m->mp_start);
199         if (m->mp_stop)
200                 free(m->mp_stop);
201
202         for (part = m->mp_parts; part; part = next) {
203                 next = part->mp_next;
204                 free_content(part->mp_part);
205                 free((char *) part);
206         }
207         m->mp_parts = NULL;
208
209         free((char *) m);
210         ct->c_ctparams = NULL;
211 }
212
213
214 static void
215 free_partial(CT ct)
216 {
217         struct partial *p;
218
219         if (!(p = (struct partial *) ct->c_ctparams))
220                 return;
221
222         if (p->pm_partid)
223                 free(p->pm_partid);
224
225         free((char *) p);
226         ct->c_ctparams = NULL;
227 }
228
229
230 /*
231 ** Free data structures related to encoding/decoding
232 ** Content-Transfer-Encodings.
233 */
234
235 void
236 free_encoding(CT ct, int toplevel)
237 {
238         CE ce;
239
240         if (!(ce = ct->c_cefile))
241                 return;
242
243         if (ce->ce_fp) {
244                 fclose(ce->ce_fp);
245                 ce->ce_fp = NULL;
246         }
247
248         if (ce->ce_file) {
249                 if (ce->ce_unlink)
250                         unlink(ce->ce_file);
251                 free(ce->ce_file);
252                 ce->ce_file = NULL;
253         }
254
255         if (toplevel) {
256                 free((char *) ce);
257                 ct->c_cefile = NULL;
258         } else {
259                 ct->c_ceopenfnx = NULL;
260         }
261 }
262
263
264 void
265 freects_done()
266 {
267         CT *ctp;
268
269         if ((ctp = cts)) {
270                 for (; *ctp; ctp++){
271                         free_content(*ctp);
272                 }
273         }
274 }