No issues found
Tool | Failure ID | Location | Function | Message | Data |
---|---|---|---|---|---|
clang-analyzer | no-output-found | e-mail-parser-tnef-attachment.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None | |
clang-analyzer | no-output-found | e-mail-parser-tnef-attachment.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None |
1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2 of the License, or (at your option) version 3.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
11 *
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with the program; if not, see <http://www.gnu.org/licenses/>
14 */
15
16 #ifdef HAVE_CONFIG_H
17 #include <config.h>
18 #endif
19
20 #include <string.h>
21 #include <gtk/gtk.h>
22 #include <glib/gi18n.h>
23 #include <glib/gprintf.h>
24 #include <stdio.h>
25
26 #include "e-mail-parser-tnef-attachment.h"
27
28 #include <em-format/e-mail-extension-registry.h>
29 #include <em-format/e-mail-parser-extension.h>
30 #include <em-format/e-mail-part.h>
31 #include <em-format/e-mail-part-utils.h>
32
33 #include <sys/types.h>
34 #include <dirent.h>
35 #include <sys/stat.h>
36 #include <fcntl.h>
37 #include <ctype.h>
38 #include <stdlib.h>
39 #ifdef HAVE_YTNEF_H
40 #include <ytnef.h>
41 #elif defined HAVE_LIBYTNEF_YTNEF_H
42 #include <libytnef/ytnef.h>
43 #endif
44
45 #include <mail/em-utils.h>
46 #include <e-util/e-mktemp.h>
47
48 #include <libebackend/libebackend.h>
49
50 #define d(x)
51
52 typedef struct _EMailParserTnefAttachment {
53 EExtension parent;
54
55 GSettings *settings;
56 gint mode;
57 gboolean show_suppressed;
58 } EMailParserTnefAttachment;
59
60 typedef struct _EMailParserTnefAttachmentClass {
61 EExtensionClass parent_class;
62 } EMailParserTnefAttachmentClass;
63
64 GType e_mail_parser_tnef_attachment_get_type (void);
65 static void e_mail_parser_mail_extension_interface_init (EMailExtensionInterface *iface);
66 static void e_mail_parser_parser_extension_interface_init (EMailParserExtensionInterface *iface);
67
68 G_DEFINE_DYNAMIC_TYPE_EXTENDED (
69 EMailParserTnefAttachment,
70 e_mail_parser_tnef_attachment,
71 E_TYPE_EXTENSION,
72 0,
73 G_IMPLEMENT_INTERFACE_DYNAMIC (
74 E_TYPE_MAIL_EXTENSION,
75 e_mail_parser_mail_extension_interface_init)
76 G_IMPLEMENT_INTERFACE_DYNAMIC (
77 E_TYPE_MAIL_PARSER_EXTENSION,
78 e_mail_parser_parser_extension_interface_init));
79
80 static const gchar * parser_mime_types[] = { "application/vnd.ms-tnef",
81 "application/ms-tnefl",
82 NULL };
83
84 gint verbose = 0;
85 gint saveRTF = 0;
86 gint saveintermediate = 0;
87 gboolean loaded = FALSE;
88 void processTnef (TNEFStruct *tnef, const gchar *tmpdir);
89 void saveVCalendar (TNEFStruct *tnef, const gchar *tmpdir);
90 void saveVCard (TNEFStruct *tnef, const gchar *tmpdir);
91 void saveVTask (TNEFStruct *tnef, const gchar *tmpdir);
92
93 /* Other Prototypes */
94 void fprintProperty (TNEFStruct *tnef, FILE *fptr, DWORD proptype, DWORD propid, const gchar text[]);
95 void fprintUserProp (TNEFStruct *tnef, FILE *fptr, DWORD proptype, DWORD propid, const gchar text[]);
96 void quotedfprint (FILE *fptr, variableLength *vl);
97 void cstylefprint (FILE *fptr, variableLength *vl);
98 void printRtf (FILE *fptr, variableLength *vl);
99 void printRrule (FILE *fptr, gchar *recur_data, gint size, TNEFStruct *tnef);
100 guchar getRruleCount (guchar a, guchar b);
101 guchar getRruleMonthNum (guchar a, guchar b);
102 gchar * getRruleDayname (guchar a);
103
104 static gchar *
105 sanitize_filename (const gchar *filename)
106 {
107 gchar * sanitized_name;
108 sanitized_name = g_path_get_basename (filename);
109 if (sanitized_name == NULL || !g_strcmp0 (sanitized_name, ".")) {
110 g_free (sanitized_name);
111 return NULL;
112 } else {
113 return g_strdelimit (sanitized_name, " ", '_');
114 }
115 }
116
117 static GSList *
118 empe_tnef_attachment_parse (EMailParserExtension *extension,
119 EMailParser *parser,
120 CamelMimePart *part,
121 GString *part_id,
122 GCancellable *cancellable)
123 {
124 gchar *tmpdir, *name;
125 CamelStream *out;
126 struct dirent *d;
127 DIR *dir;
128 CamelMultipart *mp;
129 CamelMimePart *mainpart;
130 CamelDataWrapper *content;
131 gint len;
132 TNEFStruct tnef;
133 GSList *parts;
134
135 tmpdir = e_mkdtemp ("tnef-attachment-XXXXXX");
136 if (tmpdir == NULL)
137 return NULL;
138
139 name = g_build_filename (tmpdir, ".evo-attachment.tnef", NULL);
140
141 out = camel_stream_fs_new_with_name (name, O_RDWR | O_CREAT, 0666, NULL);
142 if (out == NULL) {
143 g_free (name);
144 return NULL;
145 }
146 content = camel_medium_get_content ((CamelMedium *) part);
147 if (content == NULL) {
148 g_free (name);
149 g_object_unref (out);
150 return NULL;
151 }
152 if (camel_data_wrapper_decode_to_stream_sync (content, out, NULL, NULL) == -1
153 || camel_stream_close (out, NULL, NULL) == -1) {
154 g_object_unref (out);
155 g_free (name);
156 return NULL;
157 }
158 g_object_unref (out);
159
160 /* Extracting the winmail.dat */
161 TNEFInitialize (&tnef);
162 tnef.Debug = verbose;
163 if (TNEFParseFile (name, &tnef) == -1) {
164 printf ("ERROR processing file\n");
165 }
166 processTnef (&tnef, tmpdir);
167
168 TNEFFree (&tnef);
169 /* Extraction done */
170
171 dir = opendir (tmpdir);
172 if (dir == NULL) {
173 g_object_unref (out);
174 g_free (name);
175 return NULL;
176 }
177
178 mainpart = camel_mime_part_new ();
179
180 mp = camel_multipart_new ();
181 camel_data_wrapper_set_mime_type ((CamelDataWrapper *) mp, "multipart/mixed");
182 camel_multipart_set_boundary (mp, NULL);
183
184 camel_medium_set_content ((CamelMedium *) mainpart, (CamelDataWrapper *) mp);
185
186 while ((d = readdir (dir))) {
187 CamelMimePart *part;
188 CamelDataWrapper *content;
189 CamelStream *stream;
190 gchar *path;
191 const gchar *type;
192
193 if (!strcmp (d->d_name, ".")
194 || !strcmp (d->d_name, "..")
195 || !strcmp (d->d_name, ".evo-attachment.tnef"))
196 continue;
197
198 path = g_build_filename (tmpdir, d->d_name, NULL);
199
200 stream = camel_stream_fs_new_with_name (path, O_RDONLY, 0, NULL);
201 content = camel_data_wrapper_new ();
202 camel_data_wrapper_construct_from_stream_sync (
203 content, stream, NULL, NULL);
204 g_object_unref (stream);
205
206 part = camel_mime_part_new ();
207 camel_mime_part_set_encoding (part, CAMEL_TRANSFER_ENCODING_BINARY);
208
209 camel_medium_set_content ((CamelMedium *) part, content);
210 g_object_unref (content);
211
212 type = e_mail_part_snoop_type (part);
213 if (type)
214 camel_data_wrapper_set_mime_type ((CamelDataWrapper *) part, type);
215
216 camel_mime_part_set_filename (part, d->d_name);
217
218 g_free (path);
219
220 camel_multipart_add_part (mp, part);
221 g_object_unref (part);
222 }
223
224 closedir (dir);
225
226 len = part_id->len;
227 g_string_append_printf (part_id, ".tnef");
228
229 parts = NULL;
230 if (camel_multipart_get_number (mp) > 0) {
231
232 CamelMimePart *part = camel_mime_part_new ();
233
234 camel_medium_set_content (
235 (CamelMedium *) part,
236 CAMEL_DATA_WRAPPER (mp));
237
238 parts = e_mail_parser_parse_part_as (
239 parser, part, part_id,
240 "multipart/mixed", cancellable);
241
242 g_object_unref (part);
243 }
244
245 g_string_truncate (part_id, len);
246
247 if (parts)
248 parts = e_mail_parser_wrap_as_attachment (
249 parser, part, parts, part_id, cancellable);
250
251 g_object_unref (mp);
252 g_object_unref (mainpart);
253
254 g_free (name);
255 g_free (tmpdir);
256
257 return parts;
258 }
259
260 static const gchar **
261 empe_mime_types (EMailExtension *extension)
262 {
263 return parser_mime_types;
264 }
265
266 void
267 e_mail_parser_tnef_attachment_type_register (GTypeModule *type_module)
268 {
269 e_mail_parser_tnef_attachment_register_type (type_module);
270 }
271
272 static void
273 e_mail_parser_mail_extension_interface_init (EMailExtensionInterface *iface)
274 {
275 iface->mime_types = empe_mime_types;
276 }
277
278 static void
279 e_mail_parser_parser_extension_interface_init (EMailParserExtensionInterface *iface)
280 {
281 iface->parse = empe_tnef_attachment_parse;
282 }
283
284 static void
285 e_mail_parser_tnef_attachment_constructed (GObject *object)
286 {
287 EExtensible *extensible;
288 EMailExtensionRegistry *reg;
289
290 extensible = e_extension_get_extensible (E_EXTENSION (object));
291 reg = E_MAIL_EXTENSION_REGISTRY (extensible);
292
293 e_mail_extension_registry_add_extension (reg, E_MAIL_EXTENSION (object));
294 }
295
296 static void
297 e_mail_parser_tnef_attachment_class_init (EMailParserTnefAttachmentClass *class)
298 {
299 GObjectClass *object_class;
300 EExtensionClass *extension_class;
301
302 object_class = G_OBJECT_CLASS (class);
303 object_class->constructed = e_mail_parser_tnef_attachment_constructed;
304
305 extension_class = E_EXTENSION_CLASS (class);
306 extension_class->extensible_type = E_TYPE_MAIL_PARSER_EXTENSION_REGISTRY;
307 }
308
309 void
310 e_mail_parser_tnef_attachment_class_finalize (EMailParserTnefAttachmentClass *class)
311 {
312 }
313
314 static void
315 e_mail_parser_tnef_attachment_init (EMailParserTnefAttachment *parser)
316 {
317 }
318
319 void
320 processTnef (TNEFStruct *tnef,
321 const gchar *tmpdir)
322 {
323 variableLength *filename;
324 variableLength *filedata;
325 Attachment *p;
326 gint RealAttachment;
327 gint object;
328 gchar *ifilename = NULL;
329 gchar *absfilename, *file;
330 gint count;
331 gint foundCal = 0;
332
333 FILE *fptr;
334
335 /* First see if this requires special processing. */
336 /* ie: it's a Contact Card, Task, or Meeting request (vCal/vCard) */
337 if (tnef->messageClass[0] != 0) {
338 if (strcmp (tnef->messageClass, "IPM.Contact") == 0) {
339 saveVCard (tnef, tmpdir);
340 }
341 if (strcmp (tnef->messageClass, "IPM.Task") == 0) {
342 saveVTask (tnef, tmpdir);
343 }
344 if (strcmp (tnef->messageClass, "IPM.Appointment") == 0) {
345 saveVCalendar (tnef, tmpdir);
346 foundCal = 1;
347 }
348 }
349
350 if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
351 PROP_TAG (PT_STRING8,0x24))) != MAPI_UNDEFINED) {
352 if (strcmp (filename->data, "IPM.Appointment") == 0) {
353 /* If it's "indicated" twice, we don't want to save 2 calendar entries. */
354 if (foundCal == 0) {
355 saveVCalendar (tnef, tmpdir);
356 }
357 }
358 }
359
360 if (strcmp (tnef->messageClass, "IPM.Microsoft Mail.Note") == 0) {
361 if ((saveRTF == 1) && (tnef->subject.size > 0)) {
362 /* Description */
363 if ((filename = MAPIFindProperty (&(tnef->MapiProperties),
364 PROP_TAG (PT_BINARY, PR_RTF_COMPRESSED)))
365 != MAPI_UNDEFINED) {
366 variableLength buf;
367 if ((buf.data = (gchar *) DecompressRTF (filename, &buf.size)) != NULL) {
368 file = sanitize_filename (tnef->subject.data);
369 if (!file)
370 return;
371 absfilename = g_strconcat (file, ".rtf", NULL);
372 ifilename = g_build_filename (tmpdir, file, NULL);
373 g_free (absfilename);
374 g_free (file);
375
376 if ((fptr = fopen (ifilename, "wb")) == NULL) {
377 printf ("ERROR: Error writing file to disk!");
378 } else {
379 fwrite (
380 buf.data,
381 sizeof (BYTE),
382 buf.size,
383 fptr);
384 fclose (fptr);
385 }
386 free (buf.data);
387 }
388 }
389 }
390 }
391
392 /* Now process each attachment */
393 p = tnef->starting_attach.next;
394 count = 0;
395 while (p != NULL) {
396 count++;
397 /* Make sure it has a size. */
398 if (p->FileData.size > 0) {
399 object = 1;
400
401 /* See if the contents are stored as "attached data" */
402 /* Inside the MAPI blocks. */
403 if ((filedata = MAPIFindProperty (&(p->MAPI),
404 PROP_TAG (PT_OBJECT, PR_ATTACH_DATA_OBJ)))
405 == MAPI_UNDEFINED) {
406 if ((filedata = MAPIFindProperty (&(p->MAPI),
407 PROP_TAG (PT_BINARY, PR_ATTACH_DATA_OBJ)))
408 == MAPI_UNDEFINED) {
409 /* Nope, standard TNEF stuff. */
410 filedata = &(p->FileData);
411 object = 0;
412 }
413 }
414 /* See if this is an embedded TNEF stream. */
415 RealAttachment = 1;
416 if (object == 1) {
417 /* This is an "embedded object", so skip the */
418 /* 16-byte identifier first. */
419 TNEFStruct emb_tnef;
420 DWORD signature;
421 memcpy (&signature, filedata->data + 16, sizeof (DWORD));
422 if (TNEFCheckForSignature (signature) == 0) {
423 /* Has a TNEF signature, so process it. */
424 TNEFInitialize (&emb_tnef);
425 emb_tnef.Debug = tnef->Debug;
426 if (TNEFParseMemory ((guchar *) filedata->data + 16,
427 filedata->size - 16, &emb_tnef) != -1) {
428 processTnef (&emb_tnef, tmpdir);
429 RealAttachment = 0;
430 }
431 TNEFFree (&emb_tnef);
432 }
433 } else {
434 TNEFStruct emb_tnef;
435 DWORD signature;
436 memcpy (&signature, filedata->data, sizeof (DWORD));
437 if (TNEFCheckForSignature (signature) == 0) {
438 /* Has a TNEF signature, so process it. */
439 TNEFInitialize (&emb_tnef);
440 emb_tnef.Debug = tnef->Debug;
441 if (TNEFParseMemory ((guchar *) filedata->data,
442 filedata->size, &emb_tnef) != -1) {
443 processTnef (&emb_tnef, tmpdir);
444 RealAttachment = 0;
445 }
446 TNEFFree (&emb_tnef);
447 }
448 }
449 if ((RealAttachment == 1) || (saveintermediate == 1)) {
450 gchar tmpname[20];
451 /* Ok, it's not an embedded stream, so now we */
452 /* process it. */
453 if ((filename = MAPIFindProperty (&(p->MAPI),
454 PROP_TAG (PT_STRING8, PR_ATTACH_LONG_FILENAME)))
455 == MAPI_UNDEFINED) {
456 if ((filename = MAPIFindProperty (&(p->MAPI),
457 PROP_TAG (PT_STRING8, PR_DISPLAY_NAME)))
458 == MAPI_UNDEFINED) {
459 filename = &(p->Title);
460 }
461 }
462 if (filename->size == 1) {
463 filename->size = 20;
464 g_sprintf (tmpname, "file_%03i.dat", count);
465 filename->data = tmpname;
466 }
467 absfilename = sanitize_filename (filename->data);
468 if (!absfilename)
469 return;
470 ifilename = g_build_filename (tmpdir, absfilename, NULL);
471 g_free (absfilename);
472
473 if ((fptr = fopen (ifilename, "wb")) == NULL) {
474 printf ("ERROR: Error writing file to disk!");
475 } else {
476 if (object == 1) {
477 fwrite (
478 filedata->data + 16,
479 sizeof (BYTE),
480 filedata->size - 16,
481 fptr);
482 } else {
483 fwrite (
484 filedata->data,
485 sizeof (BYTE),
486 filedata->size,
487 fptr);
488 }
489 fclose (fptr);
490 }
491 }
492 } /* if size>0 */
493 p = p->next;
494 } /* while p!= null */
495 g_free (ifilename);
496 }
497
498 void
499 saveVCard (TNEFStruct *tnef,
500 const gchar *tmpdir)
501 {
502 gchar *ifilename;
503 gchar *absfilename, *file = NULL;
504 FILE *fptr;
505 variableLength *vl;
506 variableLength *pobox, *street, *city, *state, *zip, *country;
507 dtr thedate;
508 gint boolean;
509
510 if ((vl = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_DISPLAY_NAME))) == MAPI_UNDEFINED) {
511 if ((vl = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_COMPANY_NAME))) == MAPI_UNDEFINED) {
512 if (tnef->subject.size > 0) {
513 file = sanitize_filename (tnef->subject.data);
514 if (!file)
515 return;
516 absfilename = g_strconcat (file, ".vcard", NULL);
517 } else
518 absfilename = g_strdup ("unknown.vcard");
519 } else {
520 file = sanitize_filename (vl->data);
521 if (!file)
522 return;
523 absfilename = g_strconcat (file, ".vcard", NULL);
524 }
525 } else {
526 file = sanitize_filename (vl->data);
527 if (!file)
528 return;
529 absfilename = g_strconcat (file, ".vcard", NULL);
530 }
531
532 ifilename = g_build_filename (tmpdir, absfilename, NULL);
533 g_free (file);
534 g_free (absfilename);
535
536 if ((fptr = fopen (ifilename, "wb")) == NULL) {
537 printf ("Error writing file to disk!");
538 } else {
539 fprintf (fptr, "BEGIN:VCARD\n");
540 fprintf (fptr, "VERSION:2.1\n");
541 if (vl != MAPI_UNDEFINED) {
542 fprintf (fptr, "FN:%s\n", vl->data);
543 }
544 fprintProperty (tnef, fptr, PT_STRING8, PR_NICKNAME, "NICKNAME:%s\n");
545 fprintUserProp (tnef, fptr, PT_STRING8, 0x8554, "MAILER:Microsoft Outlook %s\n");
546 fprintProperty (tnef, fptr, PT_STRING8, PR_SPOUSE_NAME, "X-EVOLUTION-SPOUSE:%s\n");
547 fprintProperty (tnef, fptr, PT_STRING8, PR_MANAGER_NAME, "X-EVOLUTION-MANAGER:%s\n");
548 fprintProperty (tnef, fptr, PT_STRING8, PR_ASSISTANT, "X-EVOLUTION-ASSISTANT:%s\n");
549
550 /* Organizational */
551 if ((vl = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_COMPANY_NAME))) != MAPI_UNDEFINED) {
552 if (vl->size > 0) {
553 if ((vl->size == 1) && (vl->data[0] == 0)) {
554 } else {
555 fprintf (fptr,"ORG:%s", vl->data);
556 if ((vl = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_DEPARTMENT_NAME))) != MAPI_UNDEFINED) {
557 fprintf (fptr,";%s", vl->data);
558 }
559 fprintf (fptr, "\n");
560 }
561 }
562 }
563
564 fprintProperty (tnef, fptr, PT_STRING8, PR_OFFICE_LOCATION, "X-EVOLUTION-OFFICE:%s\n");
565 fprintProperty (tnef, fptr, PT_STRING8, PR_TITLE, "TITLE:%s\n");
566 fprintProperty (tnef, fptr, PT_STRING8, PR_PROFESSION, "ROLE:%s\n");
567 fprintProperty (tnef, fptr, PT_STRING8, PR_BODY, "NOTE:%s\n");
568 if (tnef->body.size > 0) {
569 fprintf (fptr, "NOTE;QUOTED-PRINTABLE:");
570 quotedfprint (fptr, &(tnef->body));
571 fprintf (fptr,"\n");
572 }
573
574 /* Business Address */
575 boolean = 0;
576 if ((pobox = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_POST_OFFICE_BOX))) != MAPI_UNDEFINED) {
577 boolean = 1;
578 }
579 if ((street = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_STREET_ADDRESS))) != MAPI_UNDEFINED) {
580 boolean = 1;
581 }
582 if ((city = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_LOCALITY))) != MAPI_UNDEFINED) {
583 boolean = 1;
584 }
585 if ((state = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_STATE_OR_PROVINCE))) != MAPI_UNDEFINED) {
586 boolean = 1;
587 }
588 if ((zip = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_POSTAL_CODE))) != MAPI_UNDEFINED) {
589 boolean = 1;
590 }
591 if ((country = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_COUNTRY))) != MAPI_UNDEFINED) {
592 boolean = 1;
593 }
594 if (boolean == 1) {
595 fprintf (fptr, "ADR;QUOTED-PRINTABLE;WORK:");
596 if (pobox != MAPI_UNDEFINED) {
597 quotedfprint (fptr, pobox);
598 }
599 fprintf (fptr, ";;");
600 if (street != MAPI_UNDEFINED) {
601 quotedfprint (fptr, street);
602 }
603 fprintf (fptr, ";");
604 if (city != MAPI_UNDEFINED) {
605 quotedfprint (fptr, city);
606 }
607 fprintf (fptr, ";");
608 if (state != MAPI_UNDEFINED) {
609 quotedfprint (fptr, state);
610 }
611 fprintf (fptr, ";");
612 if (zip != MAPI_UNDEFINED) {
613 quotedfprint (fptr, zip);
614 }
615 fprintf (fptr, ";");
616 if (country != MAPI_UNDEFINED) {
617 quotedfprint (fptr, country);
618 }
619 fprintf (fptr,"\n");
620 if ((vl = MAPIFindUserProp (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, 0x801b))) != MAPI_UNDEFINED) {
621 fprintf (fptr, "LABEL;QUOTED-PRINTABLE;WORK:");
622 quotedfprint (fptr, vl);
623 fprintf (fptr,"\n");
624 }
625 }
626
627 /* Home Address */
628 boolean = 0;
629 if ((pobox = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_HOME_ADDRESS_POST_OFFICE_BOX))) != MAPI_UNDEFINED) {
630 boolean = 1;
631 }
632 if ((street = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_HOME_ADDRESS_STREET))) != MAPI_UNDEFINED) {
633 boolean = 1;
634 }
635 if ((city = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_HOME_ADDRESS_CITY))) != MAPI_UNDEFINED) {
636 boolean = 1;
637 }
638 if ((state = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_HOME_ADDRESS_STATE_OR_PROVINCE))) != MAPI_UNDEFINED) {
639 boolean = 1;
640 }
641 if ((zip = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_HOME_ADDRESS_POSTAL_CODE))) != MAPI_UNDEFINED) {
642 boolean = 1;
643 }
644 if ((country = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_HOME_ADDRESS_COUNTRY))) != MAPI_UNDEFINED) {
645 boolean = 1;
646 }
647 if (boolean == 1) {
648 fprintf (fptr, "ADR;QUOTED-PRINTABLE;HOME:");
649 if (pobox != MAPI_UNDEFINED) {
650 quotedfprint (fptr, pobox);
651 }
652 fprintf (fptr, ";;");
653 if (street != MAPI_UNDEFINED) {
654 quotedfprint (fptr, street);
655 }
656 fprintf (fptr, ";");
657 if (city != MAPI_UNDEFINED) {
658 quotedfprint (fptr, city);
659 }
660 fprintf (fptr, ";");
661 if (state != MAPI_UNDEFINED) {
662 quotedfprint (fptr, state);
663 }
664 fprintf (fptr, ";");
665 if (zip != MAPI_UNDEFINED) {
666 quotedfprint (fptr, zip);
667 }
668 fprintf (fptr, ";");
669 if (country != MAPI_UNDEFINED) {
670 quotedfprint (fptr, country);
671 }
672 fprintf (fptr,"\n");
673 if ((vl = MAPIFindUserProp (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, 0x801a))) != MAPI_UNDEFINED) {
674 fprintf (fptr, "LABEL;QUOTED-PRINTABLE;WORK:");
675 quotedfprint (fptr, vl);
676 fprintf (fptr,"\n");
677 }
678 }
679
680 /* Other Address */
681 boolean = 0;
682 if ((pobox = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_OTHER_ADDRESS_POST_OFFICE_BOX))) != MAPI_UNDEFINED) {
683 boolean = 1;
684 }
685 if ((street = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_OTHER_ADDRESS_STREET))) != MAPI_UNDEFINED) {
686 boolean = 1;
687 }
688 if ((city = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_OTHER_ADDRESS_CITY))) != MAPI_UNDEFINED) {
689 boolean = 1;
690 }
691 if ((state = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_OTHER_ADDRESS_STATE_OR_PROVINCE))) != MAPI_UNDEFINED) {
692 boolean = 1;
693 }
694 if ((zip = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_OTHER_ADDRESS_POSTAL_CODE))) != MAPI_UNDEFINED) {
695 boolean = 1;
696 }
697 if ((country = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_OTHER_ADDRESS_COUNTRY))) != MAPI_UNDEFINED) {
698 boolean = 1;
699 }
700 if (boolean == 1) {
701 fprintf (fptr, "ADR;QUOTED-PRINTABLE;OTHER:");
702 if (pobox != MAPI_UNDEFINED) {
703 quotedfprint (fptr, pobox);
704 }
705 fprintf (fptr, ";;");
706 if (street != MAPI_UNDEFINED) {
707 quotedfprint (fptr, street);
708 }
709 fprintf (fptr, ";");
710 if (city != MAPI_UNDEFINED) {
711 quotedfprint (fptr, city);
712 }
713 fprintf (fptr, ";");
714 if (state != MAPI_UNDEFINED) {
715 quotedfprint (fptr, state);
716 }
717 fprintf (fptr, ";");
718 if (zip != MAPI_UNDEFINED) {
719 quotedfprint (fptr, zip);
720 }
721 fprintf (fptr, ";");
722 if (country != MAPI_UNDEFINED) {
723 quotedfprint (fptr, country);
724 }
725 fprintf (fptr,"\n");
726 }
727
728 fprintProperty (tnef, fptr, PT_STRING8, PR_CALLBACK_TELEPHONE_NUMBER, "TEL;X-EVOLUTION-CALLBACK:%s\n");
729 fprintProperty (tnef, fptr, PT_STRING8, PR_PRIMARY_TELEPHONE_NUMBER, "TEL;PREF:%s\n");
730 fprintProperty (tnef, fptr, PT_STRING8, PR_MOBILE_TELEPHONE_NUMBER, "TEL;CELL:%s\n");
731 fprintProperty (tnef, fptr, PT_STRING8, PR_RADIO_TELEPHONE_NUMBER, "TEL;X-EVOLUTION-RADIO:%s\n");
732 fprintProperty (tnef, fptr, PT_STRING8, PR_CAR_TELEPHONE_NUMBER, "TEL;CAR:%s\n");
733 fprintProperty (tnef, fptr, PT_STRING8, PR_OTHER_TELEPHONE_NUMBER, "TEL;VOICE:%s\n");
734 fprintProperty (tnef, fptr, PT_STRING8, PR_PAGER_TELEPHONE_NUMBER, "TEL;PAGER:%s\n");
735 fprintProperty (tnef, fptr, PT_STRING8, PR_TELEX_NUMBER, "TEL;X-EVOLUTION-TELEX:%s\n");
736 fprintProperty (tnef, fptr, PT_STRING8, PR_ISDN_NUMBER, "TEL;ISDN:%s\n");
737 fprintProperty (tnef, fptr, PT_STRING8, PR_HOME2_TELEPHONE_NUMBER, "TEL;HOME:%s\n");
738 fprintProperty (tnef, fptr, PT_STRING8, PR_TTYTDD_PHONE_NUMBER, "TEL;X-EVOLUTION-TTYTDD:%s\n");
739 fprintProperty (tnef, fptr, PT_STRING8, PR_HOME_TELEPHONE_NUMBER, "TEL;HOME;VOICE:%s\n");
740 fprintProperty (tnef, fptr, PT_STRING8, PR_ASSISTANT_TELEPHONE_NUMBER, "TEL;X-EVOLUTION-ASSISTANT:%s\n");
741 fprintProperty (tnef, fptr, PT_STRING8, PR_COMPANY_MAIN_PHONE_NUMBER, "TEL;WORK:%s\n");
742 fprintProperty (tnef, fptr, PT_STRING8, PR_BUSINESS_TELEPHONE_NUMBER, "TEL;WORK:%s\n");
743 fprintProperty (tnef, fptr, PT_STRING8, PR_BUSINESS2_TELEPHONE_NUMBER, "TEL;WORK;VOICE:%s\n");
744 fprintProperty (tnef, fptr, PT_STRING8, PR_PRIMARY_FAX_NUMBER, "TEL;PREF;FAX:%s\n");
745 fprintProperty (tnef, fptr, PT_STRING8, PR_BUSINESS_FAX_NUMBER, "TEL;WORK;FAX:%s\n");
746 fprintProperty (tnef, fptr, PT_STRING8, PR_HOME_FAX_NUMBER, "TEL;HOME;FAX:%s\n");
747
748 /* Email addresses */
749 if ((vl = MAPIFindUserProp (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, 0x8083))) == MAPI_UNDEFINED) {
750 vl = MAPIFindUserProp (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, 0x8084));
751 }
752 if (vl != MAPI_UNDEFINED) {
753 if (vl->size > 0)
754 fprintf (fptr, "EMAIL:%s\n", vl->data);
755 }
756 if ((vl = MAPIFindUserProp (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, 0x8093))) == MAPI_UNDEFINED) {
757 vl = MAPIFindUserProp (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, 0x8094));
758 }
759 if (vl != MAPI_UNDEFINED) {
760 if (vl->size > 0)
761 fprintf (fptr, "EMAIL:%s\n", vl->data);
762 }
763 if ((vl = MAPIFindUserProp (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, 0x80a3))) == MAPI_UNDEFINED) {
764 vl = MAPIFindUserProp (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, 0x80a4));
765 }
766 if (vl != MAPI_UNDEFINED) {
767 if (vl->size > 0)
768 fprintf (fptr, "EMAIL:%s\n", vl->data);
769 }
770
771 fprintProperty (tnef, fptr, PT_STRING8, PR_BUSINESS_HOME_PAGE, "URL:%s\n");
772 fprintUserProp (tnef, fptr, PT_STRING8, 0x80d8, "FBURL:%s\n");
773
774 /* Birthday */
775 if ((vl = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_SYSTIME, PR_BIRTHDAY))) != MAPI_UNDEFINED) {
776 fprintf (fptr, "BDAY:");
777 MAPISysTimetoDTR ((guchar *) vl->data, &thedate);
778 fprintf (fptr, "%i-%02i-%02i\n", thedate.wYear, thedate.wMonth, thedate.wDay);
779 }
780
781 /* Anniversary */
782 if ((vl = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_SYSTIME, PR_WEDDING_ANNIVERSARY))) != MAPI_UNDEFINED) {
783 fprintf (fptr, "X-EVOLUTION-ANNIVERSARY:");
784 MAPISysTimetoDTR ((guchar *) vl->data, &thedate);
785 fprintf (fptr, "%i-%02i-%02i\n", thedate.wYear, thedate.wMonth, thedate.wDay);
786 }
787 fprintf (fptr, "END:VCARD\n");
788 fclose (fptr);
789 }
790 g_free (ifilename);
791 }
792
793 guchar getRruleCount (guchar a, guchar b) {
794 return ((a << 8) | b);
795 }
796
797 guchar getRruleMonthNum (guchar a, guchar b) {
798 switch (a) {
799 case 0x00:
800 switch (b) {
801 case 0x00:
802 /* Jan */
803 return (1);
804 case 0xA3:
805 /* May */
806 return (5);
807 case 0xAE:
808 /* Nov */
809 return (11);
810 }
811 break;
812 case 0x60:
813 switch (b) {
814 case 0xAE:
815 /* Feb */
816 return (2);
817 case 0x51:
818 /* Jun */
819 return (6);
820 }
821 break;
822 case 0xE0:
823 switch (b) {
824 case 0x4B:
825 /* Mar */
826 return (3);
827 case 0x56:
828 /* Sep */
829 return (9);
830 }
831 break;
832 case 0x40:
833 switch (b) {
834 case 0xFA:
835 /* Apr */
836 return (4);
837 }
838 break;
839 case 0x20:
840 if (b == 0xFA) {
841 /* Jul */
842 return (7);
843 }
844 break;
845 case 0x80:
846 if (b == 0xA8) {
847 /* Aug */
848 return (8);
849 }
850 break;
851 case 0xA0:
852 if (b == 0xFF) {
853 /* Oct */
854 return (10);
855 }
856 break;
857 case 0xC0:
858 if (b == 0x56) {
859 return (12);
860 }
861 }
862
863 /* Error */
864 return (0);
865 }
866
867 gchar * getRruleDayname (guchar a) {
868 static gchar daystring[25];
869
870 *daystring = 0;
871
872 if (a & 0x01) {
873 strcat (daystring, "SU,");
874 }
875 if (a & 0x02) {
876 strcat (daystring, "MO,");
877 }
878 if (a & 0x04) {
879 strcat (daystring, "TU,");
880 }
881 if (a & 0x08) {
882 strcat (daystring, "WE,");
883 }
884 if (a & 0x10) {
885 strcat (daystring, "TH,");
886 }
887 if (a & 0x20) {
888 strcat (daystring, "FR,");
889 }
890 if (a & 0x40) {
891 strcat (daystring, "SA,");
892 }
893
894 if (strlen (daystring)) {
895 daystring[strlen (daystring) - 1] = 0;
896 }
897
898 return (daystring);
899 }
900
901 void printRrule (FILE *fptr, gchar *recur_data, gint size, TNEFStruct *tnef)
902 {
903 variableLength *filename;
904
905 if (size < 0x1F) {
906 return;
907 }
908
909 fprintf (fptr, "RRULE:FREQ=");
910
911 if (recur_data[0x04] == 0x0A) {
912 fprintf (fptr, "DAILY");
913
914 if (recur_data[0x16] == 0x23 || recur_data[0x16] == 0x22 ||
915 recur_data[0x16] == 0x21) {
916 if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
917 PROP_TAG (PT_I2, 0x0011))) != MAPI_UNDEFINED) {
918 fprintf (fptr, ";INTERVAL=%d", *(filename->data));
919 }
920 if (recur_data[0x16] == 0x22 || recur_data[0x16] == 0x21) {
921 fprintf (
922 fptr, ";COUNT=%d",
923 getRruleCount (recur_data[0x1B], recur_data[0x1A]));
924 }
925 } else if (recur_data[0x16] == 0x3E) {
926 fprintf (fptr, ";BYDAY=MO,TU,WE,TH,FR");
927 if (recur_data[0x1A] == 0x22 || recur_data[0x1A] == 0x21) {
928 fprintf (
929 fptr, ";COUNT=%d",
930 getRruleCount (recur_data[0x1F], recur_data[0x1E]));
931 }
932 }
933 } else if (recur_data[0x04] == 0x0B) {
934 fprintf (
935 fptr, "WEEKLY;INTERVAL=%d;BYDAY=%s",
936 recur_data[0x0E], getRruleDayname (recur_data[0x16]));
937 if (recur_data[0x1A] == 0x22 || recur_data[0x1A] == 0x21) {
938 fprintf (fptr, ";COUNT=%d",
939 getRruleCount (recur_data[0x1F], recur_data[0x1E]));
940 }
941 } else if (recur_data[0x04] == 0x0C) {
942 fprintf (fptr, "MONTHLY");
943 if (recur_data[0x06] == 0x02) {
944 fprintf (fptr, ";INTERVAL=%d;BYMONTHDAY=%d", recur_data[0x0E],
945 recur_data[0x16]);
946 if (recur_data[0x1A] == 0x22 || recur_data[0x1A] == 0x21) {
947 fprintf (
948 fptr, ";COUNT=%d", getRruleCount (recur_data[0x1F],
949 recur_data[0x1E]));
950 }
951 } else if (recur_data[0x06] == 0x03) {
952 fprintf (fptr, ";BYDAY=%s;BYSETPOS=%d;INTERVAL=%d",
953 getRruleDayname (recur_data[0x16]),
954 recur_data[0x1A] == 0x05 ? -1 : recur_data[0x1A],
955 recur_data[0x0E]);
956 if (recur_data[0x1E] == 0x22 || recur_data[0x1E] == 0x21) {
957 fprintf (
958 fptr, ";COUNT=%d", getRruleCount (recur_data[0x23],
959 recur_data[0x22]));
960 }
961 }
962 } else if (recur_data[0x04] == 0x0D) {
963 fprintf (
964 fptr, "YEARLY;BYMONTH=%d",
965 getRruleMonthNum (recur_data[0x0A], recur_data[0x0B]));
966 if (recur_data[0x06] == 0x02) {
967 fprintf (fptr, ";BYMONTHDAY=%d", recur_data[0x16]);
968 } else if (recur_data[0x06] == 0x03) {
969 fprintf (fptr, ";BYDAY=%s;BYSETPOS=%d",
970 getRruleDayname (recur_data[0x16]),
971 recur_data[0x1A] == 0x05 ? -1 : recur_data[0x1A]);
972 }
973 if (recur_data[0x1E] == 0x22 || recur_data[0x1E] == 0x21) {
974 fprintf (fptr, ";COUNT=%d", getRruleCount (recur_data[0x23],
975 recur_data[0x22]));
976 }
977 }
978 fprintf (fptr, "\n");
979 }
980
981 void saveVCalendar (TNEFStruct *tnef, const gchar *tmpdir) {
982 gchar *ifilename;
983 variableLength *filename;
984 gchar *charptr, *charptr2;
985 FILE *fptr;
986 gint index;
987 DWORD *dword_ptr;
988 dtr thedate;
989
990 ifilename = g_build_filename (tmpdir, "calendar.vcf", NULL);
991 printf ("%s\n", ifilename);
992
993 if ((fptr = fopen (ifilename, "wb")) == NULL) {
994 printf ("Error writing file to disk!");
995 } else {
996 fprintf (fptr, "BEGIN:VCALENDAR\n");
997 if (tnef->messageClass[0] != 0) {
998 charptr2 = tnef->messageClass;
999 charptr = charptr2;
1000 while (*charptr != 0) {
1001 if (*charptr == '.') {
1002 charptr2 = charptr;
1003 }
1004 charptr++;
1005 }
1006 if (strcmp (charptr2, ".MtgCncl") == 0) {
1007 fprintf (fptr, "METHOD:CANCEL\n");
1008 } else {
1009 fprintf (fptr, "METHOD:REQUEST\n");
1010 }
1011 } else {
1012 fprintf (fptr, "METHOD:REQUEST\n");
1013 }
1014 fprintf (fptr, "VERSION:2.0\n");
1015 fprintf (fptr, "BEGIN:VEVENT\n");
1016
1017 /* UID
1018 * After alot of comparisons, I'm reasonably sure this is totally
1019 * wrong. But it's not really necessary. */
1020
1021 /* I think it only exists to connect future modification entries to
1022 * this entry. so as long as it's incorrectly interpreted the same way
1023 * every time, it should be ok :) */
1024 filename = NULL;
1025 if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
1026 PROP_TAG (PT_BINARY, 0x3))) == MAPI_UNDEFINED) {
1027 if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
1028 PROP_TAG (PT_BINARY, 0x23))) == MAPI_UNDEFINED) {
1029 filename = NULL;
1030 }
1031 }
1032 if (filename != NULL) {
1033 fprintf (fptr, "UID:");
1034 for (index = 0; index < filename->size; index++) {
1035 fprintf (fptr,"%02X", (guchar) filename->data[index]);
1036 }
1037 fprintf (fptr,"\n");
1038 }
1039
1040 /* Sequence */
1041 filename = NULL;
1042 if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
1043 PROP_TAG (PT_LONG, 0x8201))) != MAPI_UNDEFINED) {
1044 dword_ptr = (DWORD *) filename->data;
1045 fprintf (fptr, "SEQUENCE:%i\n", (gint) *dword_ptr);
1046 }
1047 if ((filename = MAPIFindProperty (&(tnef->MapiProperties),
1048 PROP_TAG (PT_BINARY, PR_SENDER_SEARCH_KEY)))
1049 != MAPI_UNDEFINED) {
1050 charptr = filename->data;
1051 charptr2 = strstr (charptr, ":");
1052 if (charptr2 == NULL)
1053 charptr2 = charptr;
1054 else
1055 charptr2++;
1056 fprintf (fptr, "ORGANIZER;CN=\"%s\":MAILTO:%s\n",
1057 charptr2, charptr2);
1058 }
1059
1060 /* Required Attendees */
1061 if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
1062 PROP_TAG (PT_STRING8, 0x823b))) != MAPI_UNDEFINED) {
1063 /* We have a list of required participants, so
1064 write them out. */
1065 if (filename->size > 1) {
1066 charptr = filename->data - 1;
1067 while (charptr != NULL) {
1068 charptr++;
1069 charptr2 = strstr (charptr, ";");
1070 if (charptr2 != NULL) {
1071 *charptr2 = 0;
1072 }
1073 while (*charptr == ' ')
1074 charptr++;
1075 fprintf (fptr, "ATTENDEE;PARTSTAT=NEEDS-ACTION;");
1076 fprintf (fptr, "ROLE=REQ-PARTICIPANT;RSVP=TRUE;");
1077 fprintf (fptr, "CN=\"%s\":MAILTO:%s\n",
1078 charptr, charptr);
1079 charptr = charptr2;
1080 }
1081 }
1082 /* Optional attendees */
1083 if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
1084 PROP_TAG (PT_STRING8, 0x823c))) != MAPI_UNDEFINED) {
1085 /* The list of optional participants */
1086 if (filename->size > 1) {
1087 charptr = filename->data - 1;
1088 while (charptr != NULL) {
1089 charptr++;
1090 charptr2 = strstr (charptr, ";");
1091 if (charptr2 != NULL) {
1092 *charptr2 = 0;
1093 }
1094 while (*charptr == ' ')
1095 charptr++;
1096 fprintf (fptr, "ATTENDEE;PARTSTAT=NEEDS-ACTION;");
1097 fprintf (fptr, "ROLE=OPT-PARTICIPANT;RSVP=TRUE;");
1098 fprintf (fptr, "CN=\"%s\":MAILTO:%s\n",
1099 charptr, charptr);
1100 charptr = charptr2;
1101 }
1102 }
1103 }
1104 } else if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
1105 PROP_TAG (PT_STRING8, 0x8238))) != MAPI_UNDEFINED) {
1106 if (filename->size > 1) {
1107 charptr = filename->data - 1;
1108 while (charptr != NULL) {
1109 charptr++;
1110 charptr2 = strstr (charptr, ";");
1111 if (charptr2 != NULL) {
1112 *charptr2 = 0;
1113 }
1114 while (*charptr == ' ')
1115 charptr++;
1116 fprintf (fptr, "ATTENDEE;PARTSTAT=NEEDS-ACTION;");
1117 fprintf (fptr, "ROLE=REQ-PARTICIPANT;RSVP=TRUE;");
1118 fprintf (fptr, "CN=\"%s\":MAILTO:%s\n",
1119 charptr, charptr);
1120 charptr = charptr2;
1121 }
1122 }
1123
1124 }
1125 /* Summary */
1126 filename = NULL;
1127 if ((filename = MAPIFindProperty (&(tnef->MapiProperties),
1128 PROP_TAG (PT_STRING8, PR_CONVERSATION_TOPIC)))
1129 != MAPI_UNDEFINED) {
1130 fprintf (fptr, "SUMMARY:");
1131 cstylefprint (fptr, filename);
1132 fprintf (fptr, "\n");
1133 }
1134
1135 /* Description */
1136 if ((filename = MAPIFindProperty (&(tnef->MapiProperties),
1137 PROP_TAG (PT_BINARY, PR_RTF_COMPRESSED)))
1138 != MAPI_UNDEFINED) {
1139 variableLength buf;
1140 if ((buf.data = (gchar *) DecompressRTF (filename, &buf.size)) != NULL) {
1141 fprintf (fptr, "DESCRIPTION:");
1142 printRtf (fptr, &buf);
1143 free (buf.data);
1144 }
1145
1146 }
1147
1148 /* Location */
1149 filename = NULL;
1150 if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
1151 PROP_TAG (PT_STRING8, 0x0002))) == MAPI_UNDEFINED) {
1152 if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
1153 PROP_TAG (PT_STRING8, 0x8208))) == MAPI_UNDEFINED) {
1154 filename = NULL;
1155 }
1156 }
1157 if (filename != NULL) {
1158 fprintf (fptr,"LOCATION: %s\n", filename->data);
1159 }
1160 /* Date Start */
1161 filename = NULL;
1162 if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
1163 PROP_TAG (PT_SYSTIME, 0x820d))) == MAPI_UNDEFINED) {
1164 if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
1165 PROP_TAG (PT_SYSTIME, 0x8516))) == MAPI_UNDEFINED) {
1166 filename = NULL;
1167 }
1168 }
1169 if (filename != NULL) {
1170 fprintf (fptr, "DTSTART:");
1171 MAPISysTimetoDTR ((guchar *) filename->data, &thedate);
1172 fprintf (fptr,"%04i%02i%02iT%02i%02i%02iZ\n",
1173 thedate.wYear, thedate.wMonth, thedate.wDay,
1174 thedate.wHour, thedate.wMinute, thedate.wSecond);
1175 }
1176 /* Date End */
1177 filename = NULL;
1178 if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
1179 PROP_TAG (PT_SYSTIME, 0x820e))) == MAPI_UNDEFINED) {
1180 if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
1181 PROP_TAG (PT_SYSTIME, 0x8517))) == MAPI_UNDEFINED) {
1182 filename = NULL;
1183 }
1184 }
1185 if (filename != NULL) {
1186 fprintf (fptr, "DTEND:");
1187 MAPISysTimetoDTR ((guchar *) filename->data, &thedate);
1188 fprintf (fptr,"%04i%02i%02iT%02i%02i%02iZ\n",
1189 thedate.wYear, thedate.wMonth, thedate.wDay,
1190 thedate.wHour, thedate.wMinute, thedate.wSecond);
1191 }
1192 /* Date Stamp */
1193 filename = NULL;
1194 if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
1195 PROP_TAG (PT_SYSTIME, 0x8202))) != MAPI_UNDEFINED) {
1196 fprintf (fptr, "CREATED:");
1197 MAPISysTimetoDTR ((guchar *) filename->data, &thedate);
1198 fprintf (fptr,"%04i%02i%02iT%02i%02i%02iZ\n",
1199 thedate.wYear, thedate.wMonth, thedate.wDay,
1200 thedate.wHour, thedate.wMinute, thedate.wSecond);
1201 }
1202 /* Class */
1203 filename = NULL;
1204 if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
1205 PROP_TAG (PT_BOOLEAN, 0x8506))) != MAPI_UNDEFINED) {
1206 dword_ptr = (DWORD *) filename->data;
1207 fprintf (fptr, "CLASS:");
1208 if (*dword_ptr == 1) {
1209 fprintf (fptr,"PRIVATE\n");
1210 } else {
1211 fprintf (fptr,"PUBLIC\n");
1212 }
1213 }
1214 /* Recurrence */
1215 filename = NULL;
1216 if ((filename = MAPIFindUserProp (&(tnef->MapiProperties),
1217 PROP_TAG (PT_BINARY, 0x8216))) != MAPI_UNDEFINED) {
1218 printRrule (fptr, filename->data, filename->size, tnef);
1219 }
1220
1221 /* Wrap it up */
1222 fprintf (fptr, "END:VEVENT\n");
1223 fprintf (fptr, "END:VCALENDAR\n");
1224 fclose (fptr);
1225 }
1226 g_free (ifilename);
1227 }
1228
1229 void saveVTask (TNEFStruct *tnef, const gchar *tmpdir) {
1230 variableLength *vl;
1231 variableLength *filename;
1232 gint index;
1233 gchar *ifilename;
1234 gchar *absfilename, *file;
1235 gchar *charptr, *charptr2;
1236 dtr thedate;
1237 FILE *fptr;
1238 DWORD *dword_ptr;
1239
1240 vl = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_CONVERSATION_TOPIC));
1241
1242 if (vl == MAPI_UNDEFINED) {
1243 return;
1244 }
1245
1246 index = strlen (vl->data);
1247 while (vl->data[index] == ' ')
1248 vl->data[index--] = 0;
1249
1250 file = sanitize_filename (vl->data);
1251 if (!file)
1252 return;
1253 absfilename = g_strconcat (file, ".vcf", NULL);
1254 ifilename = g_build_filename (tmpdir, absfilename, NULL);
1255 g_free (file);
1256 g_free (absfilename);
1257
1258 printf ("%s\n", ifilename);
1259
1260 if ((fptr = fopen (ifilename, "wb")) == NULL) {
1261 printf ("Error writing file to disk!");
1262 } else {
1263 fprintf (fptr, "BEGIN:VCALENDAR\n");
1264 fprintf (fptr, "VERSION:2.0\n");
1265 fprintf (fptr, "METHOD:PUBLISH\n");
1266 filename = NULL;
1267
1268 fprintf (fptr, "BEGIN:VTODO\n");
1269 if (tnef->messageID[0] != 0) {
1270 fprintf (fptr,"UID:%s\n", tnef->messageID);
1271 }
1272 filename = MAPIFindUserProp (&(tnef->MapiProperties), \
1273 PROP_TAG (PT_STRING8, 0x8122));
1274 if (filename != MAPI_UNDEFINED) {
1275 fprintf (fptr, "ORGANIZER:%s\n", filename->data);
1276 }
1277
1278 if ((filename = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, PR_DISPLAY_TO))) != MAPI_UNDEFINED) {
1279 filename = MAPIFindUserProp (&(tnef->MapiProperties), PROP_TAG (PT_STRING8, 0x811f));
1280 }
1281 if ((filename != MAPI_UNDEFINED) && (filename->size > 1)) {
1282 charptr = filename->data - 1;
1283 while (charptr != NULL) {
1284 charptr++;
1285 charptr2 = strstr (charptr, ";");
1286 if (charptr2 != NULL) {
1287 *charptr2 = 0;
1288 }
1289 while (*charptr == ' ')
1290 charptr++;
1291 fprintf (fptr, "ATTENDEE;CN=%s;ROLE=REQ-PARTICIPANT:%s\n", charptr, charptr);
1292 charptr = charptr2;
1293 }
1294 }
1295
1296 if (tnef->subject.size > 0) {
1297 fprintf (fptr,"SUMMARY:");
1298 cstylefprint (fptr,&(tnef->subject));
1299 fprintf (fptr,"\n");
1300 }
1301
1302 if (tnef->body.size > 0) {
1303 fprintf (fptr,"DESCRIPTION:");
1304 cstylefprint (fptr,&(tnef->body));
1305 fprintf (fptr,"\n");
1306 }
1307
1308 filename = MAPIFindProperty (&(tnef->MapiProperties), \
1309 PROP_TAG (PT_SYSTIME, PR_CREATION_TIME));
1310 if (filename != MAPI_UNDEFINED) {
1311 fprintf (fptr, "DTSTAMP:");
1312 MAPISysTimetoDTR ((guchar *) filename->data, &thedate);
1313 fprintf (fptr,"%04i%02i%02iT%02i%02i%02iZ\n",
1314 thedate.wYear, thedate.wMonth, thedate.wDay,
1315 thedate.wHour, thedate.wMinute, thedate.wSecond);
1316 }
1317
1318 filename = MAPIFindUserProp (&(tnef->MapiProperties), \
1319 PROP_TAG (PT_SYSTIME, 0x8517));
1320 if (filename != MAPI_UNDEFINED) {
1321 fprintf (fptr, "DUE:");
1322 MAPISysTimetoDTR ((guchar *) filename->data, &thedate);
1323 fprintf (fptr,"%04i%02i%02iT%02i%02i%02iZ\n",
1324 thedate.wYear, thedate.wMonth, thedate.wDay,
1325 thedate.wHour, thedate.wMinute, thedate.wSecond);
1326 }
1327 filename = MAPIFindProperty (&(tnef->MapiProperties), \
1328 PROP_TAG (PT_SYSTIME, PR_LAST_MODIFICATION_TIME));
1329 if (filename != MAPI_UNDEFINED) {
1330 fprintf (fptr, "LAST-MODIFIED:");
1331 MAPISysTimetoDTR ((guchar *) filename->data, &thedate);
1332 fprintf (fptr,"%04i%02i%02iT%02i%02i%02iZ\n",
1333 thedate.wYear, thedate.wMonth, thedate.wDay,
1334 thedate.wHour, thedate.wMinute, thedate.wSecond);
1335 }
1336 /* Class */
1337 filename = MAPIFindUserProp (&(tnef->MapiProperties), \
1338 PROP_TAG (PT_BOOLEAN, 0x8506));
1339 if (filename != MAPI_UNDEFINED) {
1340 dword_ptr = (DWORD *) filename->data;
1341 fprintf (fptr, "CLASS:");
1342 if (*dword_ptr == 1) {
1343 fprintf (fptr,"PRIVATE\n");
1344 } else {
1345 fprintf (fptr,"PUBLIC\n");
1346 }
1347 }
1348 fprintf (fptr, "END:VTODO\n");
1349 fprintf (fptr, "END:VCALENDAR\n");
1350 fclose (fptr);
1351 }
1352 g_free (ifilename);
1353 }
1354
1355 void fprintProperty (TNEFStruct *tnef, FILE *fptr, DWORD proptype, DWORD propid, const gchar text[]) {
1356 variableLength *vl;
1357 if ((vl = MAPIFindProperty (&(tnef->MapiProperties), PROP_TAG (proptype, propid))) != MAPI_UNDEFINED) {
1358 if (vl->size > 0) {
1359 if ((vl->size == 1) && (vl->data[0] == 0)) {
1360 } else {
1361 fprintf (fptr, text, vl->data);
1362 }
1363 }
1364 }
1365 }
1366
1367 void fprintUserProp (TNEFStruct *tnef, FILE *fptr, DWORD proptype, DWORD propid, const gchar text[]) {
1368 variableLength *vl;
1369 if ((vl = MAPIFindUserProp (&(tnef->MapiProperties), PROP_TAG (proptype, propid))) != MAPI_UNDEFINED) {
1370 if (vl->size > 0) {
1371 if ((vl->size == 1) && (vl->data[0] == 0)) {
1372 } else {
1373 fprintf (fptr, text, vl->data);
1374 }
1375 }
1376 }
1377 }
1378
1379 void quotedfprint (FILE *fptr, variableLength *vl) {
1380 gint index;
1381
1382 for (index = 0; index < vl->size - 1; index++) {
1383 if (vl->data[index] == '\n') {
1384 fprintf (fptr, "=0A");
1385 } else if (vl->data[index] == '\r') {
1386 } else {
1387 fprintf (fptr, "%c", vl->data[index]);
1388 }
1389 }
1390 }
1391
1392 void cstylefprint (FILE *fptr, variableLength *vl) {
1393 gint index;
1394
1395 for (index = 0; index < vl->size - 1; index++) {
1396 if (vl->data[index] == '\n') {
1397 fprintf (fptr, "\\n");
1398 } else if (vl->data[index] == '\r') {
1399 /* Print nothing. */
1400 } else if (vl->data[index] == ';') {
1401 fprintf (fptr, "\\;");
1402 } else if (vl->data[index] == ',') {
1403 fprintf (fptr, "\\,");
1404 } else if (vl->data[index] == '\\') {
1405 fprintf (fptr, "\\");
1406 } else {
1407 fprintf (fptr, "%c", vl->data[index]);
1408 }
1409 }
1410 }
1411
1412 void printRtf (FILE *fptr, variableLength *vl) {
1413 gint index;
1414 gchar *byte;
1415 gint brace_ct;
1416 gint key;
1417
1418 key = 0;
1419 brace_ct = 0;
1420
1421 for (index = 0, byte = vl->data; index < vl->size; index++, byte++) {
1422 if (*byte == '}') {
1423 brace_ct--;
1424 key = 0;
1425 continue;
1426 }
1427 if (*byte == '{') {
1428 brace_ct++;
1429 continue;
1430 }
1431 if (*byte == '\\') {
1432 key = 1;
1433 }
1434 if (isspace (*byte)) {
1435 key = 0;
1436 }
1437 if ((brace_ct == 1) && (key == 0)) {
1438 if (*byte == '\n') {
1439 fprintf (fptr, "\\n");
1440 } else if (*byte == '\r') {
1441 /* Print nothing. */
1442 } else if (*byte == ';') {
1443 fprintf (fptr, "\\;");
1444 } else if (*byte == ',') {
1445 fprintf (fptr, "\\,");
1446 } else if (*byte == '\\') {
1447 fprintf (fptr, "\\");
1448 } else {
1449 fprintf (fptr, "%c", *byte);
1450 }
1451 }
1452 }
1453 fprintf (fptr, "\n");
1454 }