summaryrefslogtreecommitdiffabout
path: root/libical/src/libical/icalmime.c
Unidiff
Diffstat (limited to 'libical/src/libical/icalmime.c') (more/less context) (ignore whitespace changes)
-rw-r--r--libical/src/libical/icalmime.c388
1 files changed, 388 insertions, 0 deletions
diff --git a/libical/src/libical/icalmime.c b/libical/src/libical/icalmime.c
new file mode 100644
index 0000000..7021746
--- a/dev/null
+++ b/libical/src/libical/icalmime.c
@@ -0,0 +1,388 @@
1/* -*- Mode: C -*-*/
2/*======================================================================
3 FILE: icalmime.c
4 CREATOR: eric 26 July 2000
5
6
7 $Id$
8 $Locker$
9
10 (C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of either:
14
15 The LGPL as published by the Free Software Foundation, version
16 2.1, available at: http://www.fsf.org/copyleft/lesser.html
17
18 Or:
19
20 The Mozilla Public License Version 1.0. You may obtain a copy of
21 the License at http://www.mozilla.org/MPL/
22
23 The Original Code is eric. The Initial Developer of the Original
24 Code is Eric Busboom
25
26
27======================================================================*/
28
29#include "icalmime.h"
30#include "icalerror.h"
31#include "icalmemory.h"
32#include "sspm.h"
33#include "stdlib.h"
34#include <string.h> /* For strdup */
35#include <stdio.h> /* for snprintf*/
36
37int snprintf(char *str, size_t n, char const *fmt, ...);
38
39#ifdef DMALLOC
40#include "dmalloc.h"
41#endif
42
43
44/* These *_part routines are called by the MIME parser via the
45 local_action_map */
46
47struct text_part
48{
49 char* buf;
50 char* buf_pos;
51 size_t buf_size;
52};
53
54void* icalmime_text_new_part()
55{
56
57#define BUF_SIZE 2048
58
59 struct text_part* impl;
60
61 if ( ( impl = (struct text_part*)
62 malloc(sizeof(struct text_part))) == 0) {
63 return 0;
64 }
65
66 impl->buf = icalmemory_new_buffer(BUF_SIZE);
67 impl->buf_pos = impl->buf;
68 impl->buf_size = BUF_SIZE;
69
70 return impl;
71}
72void icalmime_text_add_line(void *part,
73 struct sspm_header *header,
74 char* line, size_t size)
75{
76 struct text_part* impl = (struct text_part*) part;
77
78 icalmemory_append_string(&(impl->buf),&(impl->buf_pos),
79 &(impl->buf_size),line);
80
81}
82
83void* icalmime_textcalendar_end_part(void* part)
84{
85
86 struct text_part* impl = (struct text_part*) part;
87 icalcomponent *c = icalparser_parse_string(impl->buf);
88
89 icalmemory_free_buffer(impl->buf);
90 free(impl);
91
92 return c;
93
94}
95
96void* icalmime_text_end_part(void* part)
97{
98 struct text_part* impl = ( struct text_part*) part;
99
100 icalmemory_add_tmp_buffer(impl->buf);
101 free(impl);
102
103 return impl->buf;
104}
105
106void icalmime_text_free_part(void *part)
107{
108 part = part;
109}
110
111
112/* Ignore Attachments for now */
113
114void* icalmime_attachment_new_part()
115{
116 return 0;
117}
118void icalmime_attachment_add_line(void *part, struct sspm_header *header,
119 char* line, size_t size)
120{
121 part = part;
122 header = header;
123 line = line;
124 size = size;
125}
126
127void* icalmime_attachment_end_part(void* part)
128{
129 return 0;
130}
131
132void icalmime_attachment_free_part(void *part)
133{
134}
135
136
137
138
139struct sspm_action_map icalmime_local_action_map[] =
140{
141 {SSPM_TEXT_MAJOR_TYPE,SSPM_CALENDAR_MINOR_TYPE,icalmime_text_new_part,icalmime_text_add_line,icalmime_textcalendar_end_part,icalmime_text_free_part},
142 {SSPM_TEXT_MAJOR_TYPE,SSPM_ANY_MINOR_TYPE,icalmime_text_new_part,icalmime_text_add_line,icalmime_text_end_part,icalmime_text_free_part},
143 {SSPM_TEXT_MAJOR_TYPE,SSPM_PLAIN_MINOR_TYPE,icalmime_text_new_part,icalmime_text_add_line,icalmime_text_end_part,icalmime_text_free_part},
144 {SSPM_APPLICATION_MAJOR_TYPE,SSPM_CALENDAR_MINOR_TYPE,icalmime_attachment_new_part,icalmime_attachment_add_line,icalmime_attachment_end_part,icalmime_attachment_free_part},
145 {SSPM_IMAGE_MAJOR_TYPE,SSPM_CALENDAR_MINOR_TYPE,icalmime_attachment_new_part,icalmime_attachment_add_line,icalmime_attachment_end_part,icalmime_attachment_free_part},
146 {SSPM_AUDIO_MAJOR_TYPE,SSPM_CALENDAR_MINOR_TYPE,icalmime_attachment_new_part,icalmime_attachment_add_line,icalmime_attachment_end_part,icalmime_attachment_free_part},
147 {SSPM_IMAGE_MAJOR_TYPE,SSPM_CALENDAR_MINOR_TYPE,icalmime_attachment_new_part,icalmime_attachment_add_line,icalmime_attachment_end_part,icalmime_attachment_free_part},
148 {SSPM_UNKNOWN_MAJOR_TYPE,SSPM_UNKNOWN_MINOR_TYPE,0,0,0,0}
149};
150
151#define NUM_PARTS 100 /* HACK. Hard Limit */
152
153
154
155struct sspm_part* icalmime_make_part(icalcomponent* comp)
156{
157 comp = comp;
158 return 0;
159}
160
161char* icalmime_as_mime_string(char* icalcomponent);
162
163icalcomponent* icalmime_parse(char* (*get_string)(char *s, size_t size,
164 void *d),
165 void *data)
166{
167 struct sspm_part *parts;
168 int i, last_level=0;
169 icalcomponent *root=0, *parent=0, *comp=0, *last = 0;
170
171 if ( (parts = (struct sspm_part *)
172 malloc(NUM_PARTS*sizeof(struct sspm_part)))==0) {
173 icalerror_set_errno(ICAL_NEWFAILED_ERROR);
174 return 0;
175 }
176
177 memset(parts,0,sizeof(parts));
178
179 sspm_parse_mime(parts,
180 NUM_PARTS, /* Max parts */
181 icalmime_local_action_map, /* Actions */
182 get_string,
183 data, /* data for get_string*/
184 0 /* First header */);
185
186
187
188 for(i = 0; i <NUM_PARTS && parts[i].header.major != SSPM_NO_MAJOR_TYPE ; i++){
189
190#define TMPSZ 1024
191 char mimetype[TMPSZ];
192 char* major = sspm_major_type_string(parts[i].header.major);
193 char* minor = sspm_minor_type_string(parts[i].header.minor);
194
195 if(parts[i].header.minor == SSPM_UNKNOWN_MINOR_TYPE ){
196 assert(parts[i].header.minor_text !=0);
197 minor = parts[i].header.minor_text;
198 }
199
200 sprintf(mimetype,"%s/%s",major,minor);
201
202 comp = icalcomponent_new(ICAL_XLICMIMEPART_COMPONENT);
203
204 if(comp == 0){
205 /* HACK Handle Error */
206 assert(0);
207 }
208
209 if(parts[i].header.error!=SSPM_NO_ERROR){
210 char *str;
211 char* temp[256];
212
213 if(parts[i].header.error==SSPM_UNEXPECTED_BOUNDARY_ERROR){
214 str = "Got an unexpected boundary, possibly due to a MIME header for a MULTIPART part that is missing the Content-Type line";
215 }
216
217 if(parts[i].header.error==SSPM_WRONG_BOUNDARY_ERROR){
218 str = "Got the wrong boundary for the opening of a MULTIPART part.";
219 }
220
221 if(parts[i].header.error==SSPM_NO_BOUNDARY_ERROR){
222 str = "Got a multipart header that did not specify a boundary";
223 }
224
225 if(parts[i].header.error==SSPM_NO_HEADER_ERROR){
226 str = "Did not get a header for the part. Is there a blank\
227line between the header and the previous boundary\?";
228
229 }
230
231 if(parts[i].header.error_text != 0){
232 snprintf((char*)temp,256,
233 "%s: %s",str,parts[i].header.error_text);
234 } else {
235 strcpy((char*)temp,str);
236 }
237
238 icalcomponent_add_property
239 (comp,
240 icalproperty_vanew_xlicerror(
241 (char*)temp,
242 icalparameter_new_xlicerrortype(
243 ICAL_XLICERRORTYPE_MIMEPARSEERROR),
244 0));
245 }
246
247 if(parts[i].header.major != SSPM_NO_MAJOR_TYPE &&
248 parts[i].header.major != SSPM_UNKNOWN_MAJOR_TYPE){
249
250 icalcomponent_add_property(comp,
251 icalproperty_new_xlicmimecontenttype((char*)
252 icalmemory_strdup(mimetype)));
253
254 }
255
256 if (parts[i].header.encoding != SSPM_NO_ENCODING){
257
258 icalcomponent_add_property(comp,
259 icalproperty_new_xlicmimeencoding(
260 sspm_encoding_string(parts[i].header.encoding)));
261 }
262
263 if (parts[i].header.filename != 0){
264 icalcomponent_add_property(comp,
265 icalproperty_new_xlicmimefilename(parts[i].header.filename));
266 }
267
268 if (parts[i].header.content_id != 0){
269 icalcomponent_add_property(comp,
270 icalproperty_new_xlicmimecid(parts[i].header.content_id));
271 }
272
273 if (parts[i].header.charset != 0){
274 icalcomponent_add_property(comp,
275 icalproperty_new_xlicmimecharset(parts[i].header.charset));
276 }
277
278 /* Add iCal components as children of the component */
279 if(parts[i].header.major == SSPM_TEXT_MAJOR_TYPE &&
280 parts[i].header.minor == SSPM_CALENDAR_MINOR_TYPE &&
281 parts[i].data != 0){
282
283 icalcomponent_add_component(comp,
284 (icalcomponent*)parts[i].data);
285 parts[i].data = 0;
286
287 } else if(parts[i].header.major == SSPM_TEXT_MAJOR_TYPE &&
288 parts[i].header.minor != SSPM_CALENDAR_MINOR_TYPE &&
289 parts[i].data != 0){
290
291 /* Add other text components as "DESCRIPTION" properties */
292
293 icalcomponent_add_property(comp,
294 icalproperty_new_description(
295 (char*)icalmemory_strdup((char*)parts[i].data)));
296
297 parts[i].data = 0;
298 }
299
300
301 if(root!= 0 && parts[i].level == 0){
302 /* We've already assigned the root, but there is another
303 part at the root level. This is probably a parse
304 error*/
305 icalcomponent_free(comp);
306 continue;
307 }
308
309 if(parts[i].level == last_level && last_level != 0){
310 icalerror_assert(parent!=0,"No parent for adding component");
311
312 icalcomponent_add_component(parent,comp);
313
314 } else if (parts[i].level == last_level && last_level == 0 &&
315 root == 0) {
316
317 root = comp;
318 parent = comp;
319
320 } else if (parts[i].level > last_level){
321
322 parent = last;
323 icalcomponent_add_component(parent,comp);
324
325 last_level = parts[i].level;
326
327 } else if (parts[i].level < last_level){
328
329 parent = icalcomponent_get_parent(parent);
330 icalcomponent_add_component(parent,comp);
331
332 last_level = parts[i].level;
333 } else {
334 assert(0);
335 }
336
337 last = comp;
338 last_level = parts[i].level;
339 assert(parts[i].data == 0);
340 }
341
342 sspm_free_parts(parts,NUM_PARTS);
343 free(parts);
344
345 return root;
346}
347
348
349
350int icalmime_test(char* (*get_string)(char *s, size_t size, void *d),
351 void *data)
352{
353 char *out;
354 struct sspm_part *parts;
355 int i;
356
357 if ( (parts = (struct sspm_part *)
358 malloc(NUM_PARTS*sizeof(struct sspm_part)))==0) {
359 icalerror_set_errno(ICAL_NEWFAILED_ERROR);
360 return 0;
361 }
362
363 memset(parts,0,sizeof(parts));
364
365 sspm_parse_mime(parts,
366 NUM_PARTS, /* Max parts */
367 icalmime_local_action_map, /* Actions */
368 get_string,
369 data, /* data for get_string*/
370 0 /* First header */);
371
372 for(i = 0; i <NUM_PARTS && parts[i].header.major != SSPM_NO_MAJOR_TYPE ;
373 i++){
374 if(parts[i].header.minor == SSPM_CALENDAR_MINOR_TYPE){
375 parts[i].data = icalmemory_strdup(
376 icalcomponent_as_ical_string((icalcomponent*)parts[i].data));
377 }
378 }
379
380 sspm_write_mime(parts,NUM_PARTS,&out,"To: bob@bob.org");
381
382 printf("%s\n",out);
383
384 return 0;
385
386}
387
388