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