support image/x-eps format via pdf_viewer
[claws.git] / src / plugins / tnef_parse / tnef_dump.c
blobc20eb5e71e741341f7be14a53c1b2cda9d238f1c
1 /*
2 * Claws Mail -- a GTK based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2007 Colin Leroy <colin@colino.net>
4 * and the Claws Mail Team
6 * This file Copyright (C) 2002-2007 Randall Hand <yerase@yerot.com>
7 * Thanks to him for allowing redistribution of this code as GPLv3.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 #ifdef HAVE_CONFIG_H
25 # include "config.h"
26 #include "claws-features.h"
27 #endif
29 #include <unistd.h>
30 #include <stdio.h>
31 #include <ctype.h>
33 #include <glib.h>
34 #include <glib/gi18n.h>
35 #include <gtk/gtk.h>
37 #ifdef YTNEF_H_SUBDIR
38 #include <libytnef/tnef-types.h>
39 #include <libytnef/ytnef.h>
40 #include <libytnef/mapi.h>
41 #include <libytnef/mapidefs.h>
42 #else
43 #include <tnef-types.h>
44 #include <ytnef.h>
45 #include <mapi.h>
46 #include <mapidefs.h>
47 #endif
49 #include "common/claws.h"
50 #include "common/version.h"
51 #include "main.h"
52 #include "plugin.h"
53 #include "procmime.h"
54 #include "utils.h"
56 #include "tnef_dump.h"
58 #define PRODID "PRODID:-//The Gauntlet//" PACKAGE " TNEF Parser " VERSION "//EN\n"
60 static unsigned char GetRruleCount(unsigned char a, unsigned char b) {
61 return ((a << 8) | b);
64 static unsigned char GetRruleMonthNum(unsigned char a, unsigned char b) {
65 switch (a) {
66 case 0x00:
67 switch (b) {
68 case 0x00:
69 // Jan
70 return(1);
71 case 0xA3:
72 // May
73 return(5);
74 case 0xAE:
75 // Nov
76 return(11);
78 break;
79 case 0x60:
80 switch (b) {
81 case 0xAE:
82 // Feb
83 return(2);
84 case 0x51:
85 // Jun
86 return(6);
88 break;
89 case 0xE0:
90 switch (b) {
91 case 0x4B:
92 // Mar
93 return(3);
94 case 0x56:
95 // Sep
96 return(9);
98 break;
99 case 0x40:
100 switch (b) {
101 case 0xFA:
102 // Apr
103 return(4);
105 break;
106 case 0x20:
107 if (b == 0xFA) {
108 // Jul
109 return(7);
111 break;
112 case 0x80:
113 if (b == 0xA8) {
114 // Aug
115 return(8);
117 break;
118 case 0xA0:
119 if (b == 0xFF) {
120 // Oct
121 return(10);
123 break;
124 case 0xC0:
125 if (b == 0x56) {
126 return(12);
130 // Error
131 return(0);
134 static char * GetRruleDayname(unsigned char a) {
135 static char daystring[25];
137 *daystring = 0;
139 if (a & 0x01) {
140 strcat(daystring, "SU,");
142 if (a & 0x02) {
143 strcat(daystring, "MO,");
145 if (a & 0x04) {
146 strcat(daystring, "TU,");
148 if (a & 0x08) {
149 strcat(daystring, "WE,");
151 if (a & 0x10) {
152 strcat(daystring, "TH,");
154 if (a & 0x20) {
155 strcat(daystring, "FR,");
157 if (a & 0x40) {
158 strcat(daystring, "SA,");
161 if (strlen(daystring)) {
162 daystring[strlen(daystring) - 1] = 0;
165 return(daystring);
168 static void PrintRrule(FILE *fptr, char *recur_data, int size, TNEFStruct *TNEF) {
169 variableLength *filename;
171 if (size < 0x1F) {
172 return;
175 fprintf(fptr, "RRULE:FREQ=");
177 if (recur_data[0x04] == 0x0A) {
178 fprintf(fptr, "DAILY");
180 if (recur_data[0x16] == 0x23 || recur_data[0x16] == 0x22 ||
181 recur_data[0x16] == 0x21) {
182 if ((filename=MAPIFindUserProp(&(TNEF->MapiProperties),
183 PROP_TAG(PT_I2, 0x0011))) != MAPI_UNDEFINED) {
184 fprintf(fptr, ";INTERVAL=%d", *(filename->data));
186 if (recur_data[0x16] == 0x22 || recur_data[0x16] == 0x21) {
187 fprintf(fptr, ";COUNT=%d",
188 GetRruleCount(recur_data[0x1B], recur_data[0x1A]));
190 } else if (recur_data[0x16] == 0x3E) {
191 fprintf(fptr, ";BYDAY=MO,TU,WE,TH,FR");
192 if (recur_data[0x1A] == 0x22 || recur_data[0x1A] == 0x21) {
193 fprintf(fptr, ";COUNT=%d",
194 GetRruleCount(recur_data[0x1F], recur_data[0x1E]));
197 } else if (recur_data[0x04] == 0x0B) {
198 fprintf(fptr, "WEEKLY;INTERVAL=%d;BYDAY=%s",
199 recur_data[0x0E], GetRruleDayname(recur_data[0x16]));
200 if (recur_data[0x1A] == 0x22 || recur_data[0x1A] == 0x21) {
201 fprintf(fptr, ";COUNT=%d",
202 GetRruleCount(recur_data[0x1F], recur_data[0x1E]));
204 } else if (recur_data[0x04] == 0x0C) {
205 fprintf(fptr, "MONTHLY");
206 if (recur_data[0x06] == 0x02) {
207 fprintf(fptr, ";INTERVAL=%d;BYMONTHDAY=%d", recur_data[0x0E],
208 recur_data[0x16]);
209 if (recur_data[0x1A] == 0x22 || recur_data[0x1A] == 0x21) {
210 fprintf(fptr, ";COUNT=%d", GetRruleCount(recur_data[0x1F],
211 recur_data[0x1E]));
213 } else if (recur_data[0x06] == 0x03) {
214 fprintf(fptr, ";BYDAY=%s;BYSETPOS=%d;INTERVAL=%d",
215 GetRruleDayname(recur_data[0x16]),
216 recur_data[0x1A] == 0x05 ? -1 : recur_data[0x1A],
217 recur_data[0x0E]);
218 if (recur_data[0x1E] == 0x22 || recur_data[0x1E] == 0x21) {
219 fprintf(fptr, ";COUNT=%d", GetRruleCount(recur_data[0x23],
220 recur_data[0x22]));
223 } else if (recur_data[0x04] == 0x0D) {
224 fprintf(fptr, "YEARLY;BYMONTH=%d",
225 GetRruleMonthNum(recur_data[0x0A], recur_data[0x0B]));
226 if (recur_data[0x06] == 0x02) {
227 fprintf(fptr, ";BYMONTHDAY=%d", recur_data[0x16]);
228 } else if (recur_data[0x06] == 0x03) {
229 fprintf(fptr, ";BYDAY=%s;BYSETPOS=%d",
230 GetRruleDayname(recur_data[0x16]),
231 recur_data[0x1A] == 0x05 ? -1 : recur_data[0x1A]);
233 if (recur_data[0x1E] == 0x22 || recur_data[0x1E] == 0x21) {
234 fprintf(fptr, ";COUNT=%d", GetRruleCount(recur_data[0x23],
235 recur_data[0x22]));
238 fprintf(fptr, "\n");
241 static void fprintProperty(TNEFStruct *TNEF, FILE *FPTR, DWORD PROPTYPE, DWORD PROPID, char TEXT[]) {
242 variableLength *vl;
243 if ((vl=MAPIFindProperty(&(TNEF->MapiProperties), PROP_TAG(PROPTYPE, PROPID))) != MAPI_UNDEFINED) {
244 if (vl->size > 0) {
245 if ((vl->size == 1) && (vl->data[0] == 0)) {
246 } else {
247 fprintf(FPTR, TEXT, vl->data);
253 static void fprintUserProp(TNEFStruct *TNEF, FILE *FPTR, DWORD PROPTYPE, DWORD PROPID, char TEXT[]) {
254 variableLength *vl;
255 if ((vl=MAPIFindUserProp(&(TNEF->MapiProperties), PROP_TAG(PROPTYPE, PROPID))) != MAPI_UNDEFINED) {
256 if (vl->size > 0) {
257 if ((vl->size == 1) && (vl->data[0] == 0)) {
258 } else {
259 fprintf(FPTR, TEXT, vl->data);
265 static void quotedfprint(FILE *FPTR, variableLength *VL) {
266 int index;
268 for (index=0;index<VL->size-1; index++) {
269 if (VL->data[index] == '\n') {
270 fprintf(FPTR, "=0A");
271 } else if (VL->data[index] == '\r') {
272 } else {
273 fprintf(FPTR, "%c", VL->data[index]);
278 static void Cstylefprint(FILE *FPTR, variableLength *VL) {
279 int index;
281 for (index=0;index<VL->size-1; index++) {
282 if (VL->data[index] == '\n') {
283 fprintf(FPTR, "\\n");
284 } else if (VL->data[index] == '\r') {
285 // Print nothing.
286 } else if (VL->data[index] == ';') {
287 fprintf(FPTR, "\\;");
288 } else if (VL->data[index] == ',') {
289 fprintf(FPTR, "\\,");
290 } else if (VL->data[index] == '\\') {
291 fprintf(FPTR, "\\");
292 } else {
293 fprintf(FPTR, "%c", VL->data[index]);
298 static void PrintRTF(FILE *fptr, variableLength *VL) {
299 int index;
300 char *byte;
301 int brace_ct;
302 int key;
304 key = 0;
305 brace_ct = 0;
307 for(index = 0, byte=VL->data; index < VL->size; index++, byte++) {
308 if (*byte == '}') {
309 brace_ct--;
310 key = 0;
311 continue;
313 if (*byte == '{') {
314 brace_ct++;
315 continue;
317 if (*byte == '\\') {
318 key = 1;
320 if (isspace(*byte)) {
321 key = 0;
323 if ((brace_ct == 1) && (key == 0)) {
324 if (*byte == '\n') {
325 fprintf(fptr, "\\n");
326 } else if (*byte == '\r') {
327 // Print nothing.
328 } else if (*byte == ';') {
329 fprintf(fptr, "\\;");
330 } else if (*byte == ',') {
331 fprintf(fptr, "\\,");
332 } else if (*byte == '\\') {
333 fprintf(fptr, "\\");
334 } else {
335 fprintf(fptr, "%c", *byte );
339 fprintf(fptr, "\n");
342 gboolean SaveVCalendar(FILE *fptr, TNEFStruct *TNEF) {
343 variableLength *filename;
344 char *charptr, *charptr2;
345 int index;
346 DDWORD *ddword_ptr;
347 DDWORD ddword_val;
348 dtr thedate;
350 fprintf(fptr, "BEGIN:VCALENDAR\n");
351 if (TNEF->messageClass[0] != 0) {
352 charptr2=TNEF->messageClass;
353 charptr=charptr2;
354 while (*charptr != 0) {
355 if (*charptr == '.') {
356 charptr2 = charptr;
358 charptr++;
360 if (strcmp(charptr2, ".MtgCncl") == 0) {
361 fprintf(fptr, "METHOD:CANCEL\n");
362 } else {
363 fprintf(fptr, "METHOD:REQUEST\n");
365 } else {
366 fprintf(fptr, "METHOD:REQUEST\n");
368 fprintf(fptr, PRODID);
369 fprintf(fptr, "VERSION:2.0\n");
370 fprintf(fptr, "BEGIN:VEVENT\n");
372 // UID
373 // After alot of comparisons, I'm reasonably sure this is totally
374 // wrong. But it's not really necessary.
376 // I think it only exists to connect future modification entries to
377 // this entry. so as long as it's incorrectly interpreted the same way
378 // every time, it should be ok :)
379 filename = NULL;
380 if ((filename=MAPIFindUserProp(&(TNEF->MapiProperties),
381 PROP_TAG(PT_BINARY, 0x3))) == MAPI_UNDEFINED) {
382 if ((filename=MAPIFindUserProp(&(TNEF->MapiProperties),
383 PROP_TAG(PT_BINARY, 0x23))) == MAPI_UNDEFINED) {
384 filename = NULL;
387 if (filename!=NULL) {
388 fprintf(fptr, "UID:");
389 for(index=0;index<filename->size;index++) {
390 fprintf(fptr,"%02X", (unsigned char)filename->data[index]);
392 fprintf(fptr,"\n");
395 // Sequence
396 filename = NULL;
397 if ((filename=MAPIFindUserProp(&(TNEF->MapiProperties),
398 PROP_TAG(PT_LONG, 0x8201))) != MAPI_UNDEFINED) {
399 ddword_ptr = (DDWORD*)filename->data;
400 fprintf(fptr, "SEQUENCE:%i\n", (int) *ddword_ptr);
402 if ((filename=MAPIFindProperty(&(TNEF->MapiProperties),
403 PROP_TAG(PT_BINARY, PR_SENDER_SEARCH_KEY)))
404 != MAPI_UNDEFINED) {
405 charptr = filename->data;
406 charptr2 = strstr(charptr, ":");
407 if (charptr2 == NULL)
408 charptr2 = charptr;
409 else
410 charptr2++;
411 fprintf(fptr, "ORGANIZER;CN=\"%s\":MAILTO:%s\n",
412 charptr2, charptr2);
415 // Required Attendees
416 if ((filename = MAPIFindUserProp(&(TNEF->MapiProperties),
417 PROP_TAG(PT_STRING8, 0x823b))) != MAPI_UNDEFINED) {
418 // We have a list of required participants, so
419 // write them out.
420 if (filename->size > 1) {
421 charptr = filename->data-1;
422 charptr2=strstr(charptr+1, ";");
423 while (charptr != NULL) {
424 charptr++;
425 charptr2 = strstr(charptr, ";");
426 if (charptr2 != NULL) {
427 *charptr2 = 0;
429 while (*charptr == ' ')
430 charptr++;
431 fprintf(fptr, "ATTENDEE;PARTSTAT=NEEDS-ACTION;");
432 fprintf(fptr, "ROLE=REQ-PARTICIPANT;RSVP=TRUE;");
433 fprintf(fptr, "CN=\"%s\":MAILTO:%s\n",
434 charptr, charptr);
435 charptr = charptr2;
438 // Optional attendees
439 if ((filename = MAPIFindUserProp(&(TNEF->MapiProperties),
440 PROP_TAG(PT_STRING8, 0x823c))) != MAPI_UNDEFINED) {
441 // The list of optional participants
442 if (filename->size > 1) {
443 charptr = filename->data-1;
444 charptr2=strstr(charptr+1, ";");
445 while (charptr != NULL) {
446 charptr++;
447 charptr2 = strstr(charptr, ";");
448 if (charptr2 != NULL) {
449 *charptr2 = 0;
451 while (*charptr == ' ')
452 charptr++;
453 fprintf(fptr, "ATTENDEE;PARTSTAT=NEEDS-ACTION;");
454 fprintf(fptr, "ROLE=OPT-PARTICIPANT;RSVP=TRUE;");
455 fprintf(fptr, "CN=\"%s\":MAILTO:%s\n",
456 charptr, charptr);
457 charptr = charptr2;
461 } else if ((filename = MAPIFindUserProp(&(TNEF->MapiProperties),
462 PROP_TAG(PT_STRING8, 0x8238))) != MAPI_UNDEFINED) {
463 if (filename->size > 1) {
464 charptr = filename->data-1;
465 while (charptr != NULL) {
466 charptr++;
467 charptr2 = strstr(charptr, ";");
468 if (charptr2 != NULL) {
469 *charptr2 = 0;
471 while (*charptr == ' ')
472 charptr++;
473 fprintf(fptr, "ATTENDEE;PARTSTAT=NEEDS-ACTION;");
474 fprintf(fptr, "ROLE=REQ-PARTICIPANT;RSVP=TRUE;");
475 fprintf(fptr, "CN=\"%s\":MAILTO:%s\n",
476 charptr, charptr);
477 charptr = charptr2;
482 // Summary
483 filename = NULL;
484 if((filename=MAPIFindProperty(&(TNEF->MapiProperties),
485 PROP_TAG(PT_STRING8, PR_CONVERSATION_TOPIC)))
486 != MAPI_UNDEFINED) {
487 fprintf(fptr, "SUMMARY:");
488 Cstylefprint(fptr, filename);
489 fprintf(fptr, "\n");
492 // Description
493 if ((filename=MAPIFindProperty(&(TNEF->MapiProperties),
494 PROP_TAG(PT_BINARY, PR_RTF_COMPRESSED)))
495 != MAPI_UNDEFINED) {
496 variableLength buf;
497 if ((buf.data = DecompressRTF(filename, &(buf.size))) != NULL) {
498 fprintf(fptr, "DESCRIPTION:");
499 PrintRTF(fptr, &buf);
500 free(buf.data);
505 // Location
506 filename = NULL;
507 if ((filename=MAPIFindUserProp(&(TNEF->MapiProperties),
508 PROP_TAG(PT_STRING8, 0x0002))) == MAPI_UNDEFINED) {
509 if ((filename=MAPIFindUserProp(&(TNEF->MapiProperties),
510 PROP_TAG(PT_STRING8, 0x8208))) == MAPI_UNDEFINED) {
511 filename = NULL;
514 if (filename != NULL) {
515 fprintf(fptr,"LOCATION: %s\n", filename->data);
517 // Date Start
518 filename = NULL;
519 if ((filename=MAPIFindUserProp(&(TNEF->MapiProperties),
520 PROP_TAG(PT_SYSTIME, 0x820d))) == MAPI_UNDEFINED) {
521 if ((filename=MAPIFindUserProp(&(TNEF->MapiProperties),
522 PROP_TAG(PT_SYSTIME, 0x8516))) == MAPI_UNDEFINED) {
523 filename=NULL;
526 if (filename != NULL) {
527 fprintf(fptr, "DTSTART:");
528 MAPISysTimetoDTR(filename->data, &thedate);
529 fprintf(fptr,"%04i%02i%02iT%02i%02i%02iZ\n",
530 thedate.wYear, thedate.wMonth, thedate.wDay,
531 thedate.wHour, thedate.wMinute, thedate.wSecond);
533 // Date End
534 filename = NULL;
535 if ((filename=MAPIFindUserProp(&(TNEF->MapiProperties),
536 PROP_TAG(PT_SYSTIME, 0x820e))) == MAPI_UNDEFINED) {
537 if ((filename=MAPIFindUserProp(&(TNEF->MapiProperties),
538 PROP_TAG(PT_SYSTIME, 0x8517))) == MAPI_UNDEFINED) {
539 filename=NULL;
542 if (filename != NULL) {
543 fprintf(fptr, "DTEND:");
544 MAPISysTimetoDTR(filename->data, &thedate);
545 fprintf(fptr,"%04i%02i%02iT%02i%02i%02iZ\n",
546 thedate.wYear, thedate.wMonth, thedate.wDay,
547 thedate.wHour, thedate.wMinute, thedate.wSecond);
549 // Date Stamp
550 filename = NULL;
551 if ((filename=MAPIFindUserProp(&(TNEF->MapiProperties),
552 PROP_TAG(PT_SYSTIME, 0x8202))) != MAPI_UNDEFINED) {
553 fprintf(fptr, "CREATED:");
554 MAPISysTimetoDTR(filename->data, &thedate);
555 fprintf(fptr,"%04i%02i%02iT%02i%02i%02iZ\n",
556 thedate.wYear, thedate.wMonth, thedate.wDay,
557 thedate.wHour, thedate.wMinute, thedate.wSecond);
559 // Class
560 filename = NULL;
561 if ((filename=MAPIFindUserProp(&(TNEF->MapiProperties),
562 PROP_TAG(PT_BOOLEAN, 0x8506))) != MAPI_UNDEFINED) {
563 ddword_ptr = (DDWORD*)filename->data;
564 #ifdef YTNEF_OLD_SWAPDDWORD
565 ddword_val = SwapDDWord((BYTE*)ddword_ptr);
566 #else
567 ddword_val = SwapDDWord((BYTE*)ddword_ptr, sizeof(DDWORD));
568 #endif
569 fprintf(fptr, "CLASS:" );
570 if (ddword_val == 1) {
571 fprintf(fptr,"PRIVATE\n");
572 } else {
573 fprintf(fptr,"PUBLIC\n");
576 // Recurrence
577 filename = NULL;
578 if ((filename=MAPIFindUserProp(&(TNEF->MapiProperties),
579 PROP_TAG(PT_BINARY, 0x8216))) != MAPI_UNDEFINED) {
580 PrintRrule(fptr, filename->data, filename->size, TNEF);
583 // Wrap it up
584 fprintf(fptr, "END:VEVENT\n");
585 fprintf(fptr, "END:VCALENDAR\n");
586 return TRUE;
591 gboolean SaveVTask(FILE *fptr, TNEFStruct *TNEF) {
592 variableLength *filename;
593 char *charptr, *charptr2;
594 dtr thedate;
595 DDWORD *ddword_ptr;
596 DDWORD ddword_val;
598 fprintf(fptr, "BEGIN:VCALENDAR\n");
599 fprintf(fptr, PRODID);
600 fprintf(fptr, "VERSION:2.0\n");
601 fprintf(fptr, "METHOD:PUBLISH\n");
602 filename = NULL;
604 fprintf(fptr, "BEGIN:VTODO\n");
605 if (TNEF->messageID[0] != 0) {
606 fprintf(fptr,"UID:%s\n", TNEF->messageID);
608 filename = MAPIFindUserProp(&(TNEF->MapiProperties), \
609 PROP_TAG(PT_STRING8, 0x8122));
610 if (filename != MAPI_UNDEFINED) {
611 fprintf(fptr, "ORGANIZER:%s\n", filename->data);
615 if ((filename = MAPIFindProperty(&(TNEF->MapiProperties), PROP_TAG(PT_STRING8, PR_DISPLAY_TO))) != MAPI_UNDEFINED) {
616 filename = MAPIFindUserProp(&(TNEF->MapiProperties), PROP_TAG(PT_STRING8, 0x811f));
618 if ((filename != MAPI_UNDEFINED) && (filename->size > 1)) {
619 charptr = filename->data-1;
620 while (charptr != NULL) {
621 charptr++;
622 charptr2 = strstr(charptr, ";");
623 if (charptr2 != NULL) {
624 *charptr2 = 0;
626 while (*charptr == ' ')
627 charptr++;
628 fprintf(fptr, "ATTENDEE;CN=%s;ROLE=REQ-PARTICIPANT:%s\n", charptr, charptr);
629 charptr = charptr2;
633 if (TNEF->subject.size > 0) {
634 fprintf(fptr,"SUMMARY:");
635 Cstylefprint(fptr,&(TNEF->subject));
636 fprintf(fptr,"\n");
639 if (TNEF->body.size > 0) {
640 fprintf(fptr,"DESCRIPTION:");
641 Cstylefprint(fptr,&(TNEF->body));
642 fprintf(fptr,"\n");
645 filename = MAPIFindProperty(&(TNEF->MapiProperties), \
646 PROP_TAG(PT_SYSTIME, PR_CREATION_TIME));
647 if (filename != MAPI_UNDEFINED) {
648 fprintf(fptr, "DTSTAMP:");
649 MAPISysTimetoDTR(filename->data, &thedate);
650 fprintf(fptr,"%04i%02i%02iT%02i%02i%02iZ\n",
651 thedate.wYear, thedate.wMonth, thedate.wDay,
652 thedate.wHour, thedate.wMinute, thedate.wSecond);
655 filename = MAPIFindUserProp(&(TNEF->MapiProperties), \
656 PROP_TAG(PT_SYSTIME, 0x8517));
657 if (filename != MAPI_UNDEFINED) {
658 fprintf(fptr, "DUE:");
659 MAPISysTimetoDTR(filename->data, &thedate);
660 fprintf(fptr,"%04i%02i%02iT%02i%02i%02iZ\n",
661 thedate.wYear, thedate.wMonth, thedate.wDay,
662 thedate.wHour, thedate.wMinute, thedate.wSecond);
664 filename = MAPIFindProperty(&(TNEF->MapiProperties), \
665 PROP_TAG(PT_SYSTIME, PR_LAST_MODIFICATION_TIME));
666 if (filename != MAPI_UNDEFINED) {
667 fprintf(fptr, "LAST-MODIFIED:");
668 MAPISysTimetoDTR(filename->data, &thedate);
669 fprintf(fptr,"%04i%02i%02iT%02i%02i%02iZ\n",
670 thedate.wYear, thedate.wMonth, thedate.wDay,
671 thedate.wHour, thedate.wMinute, thedate.wSecond);
673 // Class
674 filename = MAPIFindUserProp(&(TNEF->MapiProperties), \
675 PROP_TAG(PT_BOOLEAN, 0x8506));
676 if (filename != MAPI_UNDEFINED) {
677 ddword_ptr = (DDWORD*)filename->data;
678 #ifdef YTNEF_OLD_SWAPDDWORD
679 ddword_val = SwapDDWord((BYTE*)ddword_ptr);
680 #else
681 ddword_val = SwapDDWord((BYTE*)ddword_ptr, sizeof(DDWORD));
682 #endif
683 fprintf(fptr, "CLASS:" );
684 if (ddword_val == 1) {
685 fprintf(fptr,"PRIVATE\n");
686 } else {
687 fprintf(fptr,"PUBLIC\n");
690 fprintf(fptr, "END:VTODO\n");
691 fprintf(fptr, "END:VCALENDAR\n");
693 return TRUE;
696 gboolean SaveVCard(FILE *fptr, TNEFStruct *TNEF) {
697 variableLength *vl;
698 variableLength *pobox, *street, *city, *state, *zip, *country;
699 dtr thedate;
700 int boolean;
702 if ((vl = MAPIFindProperty(&(TNEF->MapiProperties), PROP_TAG(PT_STRING8, PR_DISPLAY_NAME))) == MAPI_UNDEFINED) {
703 vl=MAPIFindProperty(&(TNEF->MapiProperties), PROP_TAG(PT_STRING8, PR_COMPANY_NAME));
706 fprintf(fptr, "BEGIN:VCARD\n");
707 fprintf(fptr, "VERSION:2.1\n");
708 if (vl != MAPI_UNDEFINED) {
709 fprintf(fptr, "FN:%s\n", vl->data);
711 fprintProperty(TNEF, fptr, PT_STRING8, PR_NICKNAME, "NICKNAME:%s\n");
712 fprintUserProp(TNEF, fptr, PT_STRING8, 0x8554, "MAILER:Microsoft Outlook %s\n");
713 fprintProperty(TNEF, fptr, PT_STRING8, PR_SPOUSE_NAME, "X-EVOLUTION-SPOUSE:%s\n");
714 fprintProperty(TNEF, fptr, PT_STRING8, PR_MANAGER_NAME, "X-EVOLUTION-MANAGER:%s\n");
715 fprintProperty(TNEF, fptr, PT_STRING8, PR_ASSISTANT, "X-EVOLUTION-ASSISTANT:%s\n");
717 // Organizational
718 if ((vl=MAPIFindProperty(&(TNEF->MapiProperties), PROP_TAG(PT_STRING8, PR_COMPANY_NAME))) != MAPI_UNDEFINED) {
719 if (vl->size > 0) {
720 if ((vl->size == 1) && (vl->data[0] == 0)) {
721 } else {
722 fprintf(fptr,"ORG:%s", vl->data);
723 if ((vl=MAPIFindProperty(&(TNEF->MapiProperties), PROP_TAG(PT_STRING8, PR_DEPARTMENT_NAME))) != MAPI_UNDEFINED) {
724 fprintf(fptr,";%s", vl->data);
726 fprintf(fptr, "\n");
731 fprintProperty(TNEF, fptr, PT_STRING8, PR_OFFICE_LOCATION, "X-EVOLUTION-OFFICE:%s\n");
732 fprintProperty(TNEF, fptr, PT_STRING8, PR_TITLE, "TITLE:%s\n");
733 fprintProperty(TNEF, fptr, PT_STRING8, PR_PROFESSION, "ROLE:%s\n");
734 fprintProperty(TNEF, fptr, PT_STRING8, PR_BODY, "NOTE:%s\n");
735 if (TNEF->body.size > 0) {
736 fprintf(fptr, "NOTE;QUOTED-PRINTABLE:");
737 quotedfprint(fptr, &(TNEF->body));
738 fprintf(fptr,"\n");
742 // Business Address
743 boolean = 0;
744 if ((pobox = MAPIFindProperty(&(TNEF->MapiProperties), PROP_TAG(PT_STRING8, PR_POST_OFFICE_BOX))) != MAPI_UNDEFINED) {
745 boolean = 1;
747 if ((street = MAPIFindProperty(&(TNEF->MapiProperties), PROP_TAG(PT_STRING8, PR_STREET_ADDRESS))) != MAPI_UNDEFINED) {
748 boolean = 1;
750 if ((city = MAPIFindProperty(&(TNEF->MapiProperties), PROP_TAG(PT_STRING8, PR_LOCALITY))) != MAPI_UNDEFINED) {
751 boolean = 1;
753 if ((state = MAPIFindProperty(&(TNEF->MapiProperties), PROP_TAG(PT_STRING8, PR_STATE_OR_PROVINCE))) != MAPI_UNDEFINED) {
754 boolean = 1;
756 if ((zip = MAPIFindProperty(&(TNEF->MapiProperties), PROP_TAG(PT_STRING8, PR_POSTAL_CODE))) != MAPI_UNDEFINED) {
757 boolean = 1;
759 if ((country = MAPIFindProperty(&(TNEF->MapiProperties), PROP_TAG(PT_STRING8, PR_COUNTRY))) != MAPI_UNDEFINED) {
760 boolean = 1;
762 if (boolean == 1) {
763 fprintf(fptr, "ADR;QUOTED-PRINTABLE;WORK:");
764 if (pobox != MAPI_UNDEFINED) {
765 quotedfprint(fptr, pobox);
767 fprintf(fptr, ";;");
768 if (street != MAPI_UNDEFINED) {
769 quotedfprint(fptr, street);
771 fprintf(fptr, ";");
772 if (city != MAPI_UNDEFINED) {
773 quotedfprint(fptr, city);
775 fprintf(fptr, ";");
776 if (state != MAPI_UNDEFINED) {
777 quotedfprint(fptr, state);
779 fprintf(fptr, ";");
780 if (zip != MAPI_UNDEFINED) {
781 quotedfprint(fptr, zip);
783 fprintf(fptr, ";");
784 if (country != MAPI_UNDEFINED) {
785 quotedfprint(fptr, country);
787 fprintf(fptr,"\n");
788 if ((vl = MAPIFindUserProp(&(TNEF->MapiProperties), PROP_TAG(PT_STRING8, 0x801b))) != MAPI_UNDEFINED) {
789 fprintf(fptr, "LABEL;QUOTED-PRINTABLE;WORK:");
790 quotedfprint(fptr, vl);
791 fprintf(fptr,"\n");
795 // Home Address
796 boolean = 0;
797 if ((pobox = MAPIFindProperty(&(TNEF->MapiProperties), PROP_TAG(PT_STRING8, PR_HOME_ADDRESS_POST_OFFICE_BOX))) != MAPI_UNDEFINED) {
798 boolean = 1;
800 if ((street = MAPIFindProperty(&(TNEF->MapiProperties), PROP_TAG(PT_STRING8, PR_HOME_ADDRESS_STREET))) != MAPI_UNDEFINED) {
801 boolean = 1;
803 if ((city = MAPIFindProperty(&(TNEF->MapiProperties), PROP_TAG(PT_STRING8, PR_HOME_ADDRESS_CITY))) != MAPI_UNDEFINED) {
804 boolean = 1;
806 if ((state = MAPIFindProperty(&(TNEF->MapiProperties), PROP_TAG(PT_STRING8, PR_HOME_ADDRESS_STATE_OR_PROVINCE))) != MAPI_UNDEFINED) {
807 boolean = 1;
809 if ((zip = MAPIFindProperty(&(TNEF->MapiProperties), PROP_TAG(PT_STRING8, PR_HOME_ADDRESS_POSTAL_CODE))) != MAPI_UNDEFINED) {
810 boolean = 1;
812 if ((country = MAPIFindProperty(&(TNEF->MapiProperties), PROP_TAG(PT_STRING8, PR_HOME_ADDRESS_COUNTRY))) != MAPI_UNDEFINED) {
813 boolean = 1;
815 if (boolean == 1) {
816 fprintf(fptr, "ADR;QUOTED-PRINTABLE;HOME:");
817 if (pobox != MAPI_UNDEFINED) {
818 quotedfprint(fptr, pobox);
820 fprintf(fptr, ";;");
821 if (street != MAPI_UNDEFINED) {
822 quotedfprint(fptr, street);
824 fprintf(fptr, ";");
825 if (city != MAPI_UNDEFINED) {
826 quotedfprint(fptr, city);
828 fprintf(fptr, ";");
829 if (state != MAPI_UNDEFINED) {
830 quotedfprint(fptr, state);
832 fprintf(fptr, ";");
833 if (zip != MAPI_UNDEFINED) {
834 quotedfprint(fptr, zip);
836 fprintf(fptr, ";");
837 if (country != MAPI_UNDEFINED) {
838 quotedfprint(fptr, country);
840 fprintf(fptr,"\n");
841 if ((vl = MAPIFindUserProp(&(TNEF->MapiProperties), PROP_TAG(PT_STRING8, 0x801a))) != MAPI_UNDEFINED) {
842 fprintf(fptr, "LABEL;QUOTED-PRINTABLE;WORK:");
843 quotedfprint(fptr, vl);
844 fprintf(fptr,"\n");
848 // Other Address
849 boolean = 0;
850 if ((pobox = MAPIFindProperty(&(TNEF->MapiProperties), PROP_TAG(PT_STRING8, PR_OTHER_ADDRESS_POST_OFFICE_BOX))) != MAPI_UNDEFINED) {
851 boolean = 1;
853 if ((street = MAPIFindProperty(&(TNEF->MapiProperties), PROP_TAG(PT_STRING8, PR_OTHER_ADDRESS_STREET))) != MAPI_UNDEFINED) {
854 boolean = 1;
856 if ((city = MAPIFindProperty(&(TNEF->MapiProperties), PROP_TAG(PT_STRING8, PR_OTHER_ADDRESS_CITY))) != MAPI_UNDEFINED) {
857 boolean = 1;
859 if ((state = MAPIFindProperty(&(TNEF->MapiProperties), PROP_TAG(PT_STRING8, PR_OTHER_ADDRESS_STATE_OR_PROVINCE))) != MAPI_UNDEFINED) {
860 boolean = 1;
862 if ((zip = MAPIFindProperty(&(TNEF->MapiProperties), PROP_TAG(PT_STRING8, PR_OTHER_ADDRESS_POSTAL_CODE))) != MAPI_UNDEFINED) {
863 boolean = 1;
865 if ((country = MAPIFindProperty(&(TNEF->MapiProperties), PROP_TAG(PT_STRING8, PR_OTHER_ADDRESS_COUNTRY))) != MAPI_UNDEFINED) {
866 boolean = 1;
868 if (boolean == 1) {
869 fprintf(fptr, "ADR;QUOTED-PRINTABLE;OTHER:");
870 if (pobox != MAPI_UNDEFINED) {
871 quotedfprint(fptr, pobox);
873 fprintf(fptr, ";;");
874 if (street != MAPI_UNDEFINED) {
875 quotedfprint(fptr, street);
877 fprintf(fptr, ";");
878 if (city != MAPI_UNDEFINED) {
879 quotedfprint(fptr, city);
881 fprintf(fptr, ";");
882 if (state != MAPI_UNDEFINED) {
883 quotedfprint(fptr, state);
885 fprintf(fptr, ";");
886 if (zip != MAPI_UNDEFINED) {
887 quotedfprint(fptr, zip);
889 fprintf(fptr, ";");
890 if (country != MAPI_UNDEFINED) {
891 quotedfprint(fptr, country);
893 fprintf(fptr,"\n");
897 fprintProperty(TNEF, fptr, PT_STRING8, PR_CALLBACK_TELEPHONE_NUMBER, "TEL;X-EVOLUTION-CALLBACK:%s\n");
898 fprintProperty(TNEF, fptr, PT_STRING8, PR_PRIMARY_TELEPHONE_NUMBER, "TEL;PREF:%s\n");
899 fprintProperty(TNEF, fptr, PT_STRING8, PR_MOBILE_TELEPHONE_NUMBER, "TEL;CELL:%s\n");
900 fprintProperty(TNEF, fptr, PT_STRING8, PR_RADIO_TELEPHONE_NUMBER, "TEL;X-EVOLUTION-RADIO:%s\n");
901 fprintProperty(TNEF, fptr, PT_STRING8, PR_CAR_TELEPHONE_NUMBER, "TEL;CAR:%s\n");
902 fprintProperty(TNEF, fptr, PT_STRING8, PR_OTHER_TELEPHONE_NUMBER, "TEL;VOICE:%s\n");
903 fprintProperty(TNEF, fptr, PT_STRING8, PR_PAGER_TELEPHONE_NUMBER, "TEL;PAGER:%s\n");
904 fprintProperty(TNEF, fptr, PT_STRING8, PR_TELEX_NUMBER, "TEL;X-EVOLUTION-TELEX:%s\n");
905 fprintProperty(TNEF, fptr, PT_STRING8, PR_ISDN_NUMBER, "TEL;ISDN:%s\n");
906 fprintProperty(TNEF, fptr, PT_STRING8, PR_HOME2_TELEPHONE_NUMBER, "TEL;HOME:%s\n");
907 fprintProperty(TNEF, fptr, PT_STRING8, PR_TTYTDD_PHONE_NUMBER, "TEL;X-EVOLUTION-TTYTDD:%s\n");
908 fprintProperty(TNEF, fptr, PT_STRING8, PR_HOME_TELEPHONE_NUMBER, "TEL;HOME;VOICE:%s\n");
909 fprintProperty(TNEF, fptr, PT_STRING8, PR_ASSISTANT_TELEPHONE_NUMBER, "TEL;X-EVOLUTION-ASSISTANT:%s\n");
910 fprintProperty(TNEF, fptr, PT_STRING8, PR_COMPANY_MAIN_PHONE_NUMBER, "TEL;WORK:%s\n");
911 fprintProperty(TNEF, fptr, PT_STRING8, PR_BUSINESS_TELEPHONE_NUMBER, "TEL;WORK:%s\n");
912 fprintProperty(TNEF, fptr, PT_STRING8, PR_BUSINESS2_TELEPHONE_NUMBER, "TEL;WORK;VOICE:%s\n");
913 fprintProperty(TNEF, fptr, PT_STRING8, PR_PRIMARY_FAX_NUMBER, "TEL;PREF;FAX:%s\n");
914 fprintProperty(TNEF, fptr, PT_STRING8, PR_BUSINESS_FAX_NUMBER, "TEL;WORK;FAX:%s\n");
915 fprintProperty(TNEF, fptr, PT_STRING8, PR_HOME_FAX_NUMBER, "TEL;HOME;FAX:%s\n");
918 // Email addresses
919 if ((vl=MAPIFindUserProp(&(TNEF->MapiProperties), PROP_TAG(PT_STRING8, 0x8083))) == MAPI_UNDEFINED) {
920 vl=MAPIFindUserProp(&(TNEF->MapiProperties), PROP_TAG(PT_STRING8, 0x8084));
922 if (vl != MAPI_UNDEFINED) {
923 if (vl->size > 0)
924 fprintf(fptr, "EMAIL:%s\n", vl->data);
926 if ((vl=MAPIFindUserProp(&(TNEF->MapiProperties), PROP_TAG(PT_STRING8, 0x8093))) == MAPI_UNDEFINED) {
927 vl=MAPIFindUserProp(&(TNEF->MapiProperties), PROP_TAG(PT_STRING8, 0x8094));
929 if (vl != MAPI_UNDEFINED) {
930 if (vl->size > 0)
931 fprintf(fptr, "EMAIL:%s\n", vl->data);
933 if ((vl=MAPIFindUserProp(&(TNEF->MapiProperties), PROP_TAG(PT_STRING8, 0x80a3))) == MAPI_UNDEFINED) {
934 vl=MAPIFindUserProp(&(TNEF->MapiProperties), PROP_TAG(PT_STRING8, 0x80a4));
936 if (vl != MAPI_UNDEFINED) {
937 if (vl->size > 0)
938 fprintf(fptr, "EMAIL:%s\n", vl->data);
941 fprintProperty(TNEF, fptr, PT_STRING8, PR_BUSINESS_HOME_PAGE, "URL:%s\n");
942 fprintUserProp(TNEF, fptr, PT_STRING8, 0x80d8, "FBURL:%s\n");
946 //Birthday
947 if ((vl=MAPIFindProperty(&(TNEF->MapiProperties), PROP_TAG(PT_SYSTIME, PR_BIRTHDAY))) != MAPI_UNDEFINED) {
948 fprintf(fptr, "BDAY:");
949 MAPISysTimetoDTR(vl->data, &thedate);
950 fprintf(fptr, "%i-%02i-%02i\n", thedate.wYear, thedate.wMonth, thedate.wDay);
953 //Anniversary
954 if ((vl=MAPIFindProperty(&(TNEF->MapiProperties), PROP_TAG(PT_SYSTIME, PR_WEDDING_ANNIVERSARY))) != MAPI_UNDEFINED) {
955 fprintf(fptr, "X-EVOLUTION-ANNIVERSARY:");
956 MAPISysTimetoDTR(vl->data, &thedate);
957 fprintf(fptr, "%i-%02i-%02i\n", thedate.wYear, thedate.wMonth, thedate.wDay);
959 fprintf(fptr, "END:VCARD\n");
960 return TRUE;