]> diplodocus.org Git - nmh/blob - uip/mhfree.c
Just reworded the bit about '%s' being safe not to quote (it's only safe not to
[nmh] / 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 }