comparison src/readpst.c @ 199:e3a46f66332b

more changes in recurrence decoding
author Carl Byington <carl@five-ten-sg.com>
date Wed, 13 May 2009 11:59:55 -0700
parents 7c60d6d1c681
children d360f96f71f6
comparison
equal deleted inserted replaced
198:7c60d6d1c681 199:e3a46f66332b
55 void write_schedule_part_data(FILE* f_output, pst_item* item, const char* sender, const char* method); 55 void write_schedule_part_data(FILE* f_output, pst_item* item, const char* sender, const char* method);
56 void write_schedule_part(FILE* f_output, pst_item* item, const char* sender, const char* boundary); 56 void write_schedule_part(FILE* f_output, pst_item* item, const char* sender, const char* boundary);
57 void write_normal_email(FILE* f_output, char f_name[], pst_item* item, int mode, int mode_MH, pst_file* pst, int save_rtf, char** extra_mime_headers); 57 void write_normal_email(FILE* f_output, char f_name[], pst_item* item, int mode, int mode_MH, pst_file* pst, int save_rtf, char** extra_mime_headers);
58 void write_vcard(FILE* f_output, pst_item *item, pst_item_contact* contact, char comment[]); 58 void write_vcard(FILE* f_output, pst_item *item, pst_item_contact* contact, char comment[]);
59 void write_journal(FILE* f_output, pst_item* item); 59 void write_journal(FILE* f_output, pst_item* item);
60 int file_time_compare(FILETIME* left, FILETIME* right); 60 void write_appointment(FILE* f_output, pst_item *item, int event_open);
61 void write_appointment(FILE* f_output, pst_item *item);
62 void create_enter_dir(struct file_ll* f, pst_item *item); 61 void create_enter_dir(struct file_ll* f, pst_item *item);
63 void close_enter_dir(struct file_ll *f); 62 void close_enter_dir(struct file_ll *f);
64 63
65 const char* prog_name; 64 const char* prog_name;
66 char* output_dir = "."; 65 char* output_dir = ".";
218 DEBUG_MAIN(("main: I have an appointment, but the folder type %"PRIi32" isn't an appointment folder. Skipping it\n", ff.type)); 217 DEBUG_MAIN(("main: I have an appointment, but the folder type %"PRIi32" isn't an appointment folder. Skipping it\n", ff.type));
219 } 218 }
220 else { 219 else {
221 ff.item_count++; 220 ff.item_count++;
222 if (mode == MODE_SEPARATE) mk_separate_file(&ff); 221 if (mode == MODE_SEPARATE) mk_separate_file(&ff);
223 write_appointment(ff.output, item); 222 write_appointment(ff.output, item, 0);
224 fprintf(ff.output, "\n"); 223 fprintf(ff.output, "\n");
225 } 224 }
226 225
227 } else if (item->message_store) { 226 } else if (item->message_store) {
228 // there should only be one message_store, and we have already done it 227 // there should only be one message_store, and we have already done it
1040 1039
1041 void write_schedule_part_data(FILE* f_output, pst_item* item, const char* sender, const char* method) 1040 void write_schedule_part_data(FILE* f_output, pst_item* item, const char* sender, const char* method)
1042 { 1041 {
1043 fprintf(f_output, "BEGIN:VCALENDAR\n"); 1042 fprintf(f_output, "BEGIN:VCALENDAR\n");
1044 fprintf(f_output, "VERSION:2.0\n"); 1043 fprintf(f_output, "VERSION:2.0\n");
1045 fprintf(f_output, "PRODID:LibPST\n"); 1044 fprintf(f_output, "PRODID:LibPST v%s\n", VERSION);
1046 fprintf(f_output, "METHOD:%s\n", method); 1045 fprintf(f_output, "METHOD:%s\n", method);
1046 fprintf(f_output, "BEGIN:VEVENT\n");
1047 fprintf(f_output, "ORGANIZER;CN=\"%s\":MAILTO:%s\n", item->email->outlook_sender_name.str, sender); 1047 fprintf(f_output, "ORGANIZER;CN=\"%s\":MAILTO:%s\n", item->email->outlook_sender_name.str, sender);
1048 write_appointment(f_output, item); 1048 write_appointment(f_output, item, 1);
1049 fprintf(f_output, "END:VCALENDAR\n"); 1049 fprintf(f_output, "END:VCALENDAR\n");
1050 } 1050 }
1051 1051
1052 1052
1053 void write_schedule_part(FILE* f_output, pst_item* item, const char* sender, const char* boundary) 1053 void write_schedule_part(FILE* f_output, pst_item* item, const char* sender, const char* boundary)
1054 { 1054 {
1055 const char* method = "REQUEST"; 1055 const char* method = "REQUEST";
1056 const char* charset = "utf-8"; 1056 const char* charset = "utf-8";
1057 char fname[20]; 1057 char fname[30];
1058 if (!item->appointment) return; 1058 if (!item->appointment) return;
1059 1059
1060 // inline appointment request 1060 // inline appointment request
1061 fprintf(f_output, "\n--%s\n", boundary); 1061 fprintf(f_output, "\n--%s\n", boundary);
1062 fprintf(f_output, "Content-Type: %s; method=\"%s\"; charset=\"%s\"\n\n", "text/calendar", method, charset); 1062 fprintf(f_output, "Content-Type: %s; method=\"%s\"; charset=\"%s\"\n\n", "text/calendar", method, charset);
1357 } 1357 }
1358 1358
1359 1359
1360 void write_vcard(FILE* f_output, pst_item *item, pst_item_contact* contact, char comment[]) 1360 void write_vcard(FILE* f_output, pst_item *item, pst_item_contact* contact, char comment[])
1361 { 1361 {
1362 char time_buffer[30];
1362 // We can only call rfc escape once per printf, since the second call 1363 // We can only call rfc escape once per printf, since the second call
1363 // may free the buffer returned by the first call. 1364 // may free the buffer returned by the first call.
1364 // I had tried to place those into a single printf - Carl. 1365 // I had tried to place those into a single printf - Carl.
1365 1366
1366 DEBUG_ENT("write_vcard"); 1367 DEBUG_ENT("write_vcard");
1436 if (contact->address2.str) 1437 if (contact->address2.str)
1437 fprintf(f_output, "EMAIL:%s\n", pst_rfc2426_escape(contact->address2.str)); 1438 fprintf(f_output, "EMAIL:%s\n", pst_rfc2426_escape(contact->address2.str));
1438 if (contact->address3.str) 1439 if (contact->address3.str)
1439 fprintf(f_output, "EMAIL:%s\n", pst_rfc2426_escape(contact->address3.str)); 1440 fprintf(f_output, "EMAIL:%s\n", pst_rfc2426_escape(contact->address3.str));
1440 if (contact->birthday) 1441 if (contact->birthday)
1441 fprintf(f_output, "BDAY:%s\n", pst_rfc2425_datetime_format(contact->birthday)); 1442 fprintf(f_output, "BDAY:%s\n", pst_rfc2425_datetime_format(contact->birthday, sizeof(time_buffer), time_buffer));
1442 1443
1443 if (contact->home_address.str) { 1444 if (contact->home_address.str) {
1444 //fprintf(f_output, "ADR;TYPE=home:%s;%s;%s;%s;%s;%s;%s\n", 1445 //fprintf(f_output, "ADR;TYPE=home:%s;%s;%s;%s;%s;%s;%s\n",
1445 fprintf(f_output, "ADR;TYPE=home:%s;", (!contact->home_po_box.str) ? "" : pst_rfc2426_escape(contact->home_po_box.str)); 1446 fprintf(f_output, "ADR;TYPE=home:%s;", (!contact->home_po_box.str) ? "" : pst_rfc2426_escape(contact->home_po_box.str));
1446 fprintf(f_output, "%s;", ""); // extended Address 1447 fprintf(f_output, "%s;", ""); // extended Address
1507 } 1508 }
1508 1509
1509 1510
1510 void write_journal(FILE* f_output, pst_item* item) 1511 void write_journal(FILE* f_output, pst_item* item)
1511 { 1512 {
1513 char time_buffer[30];
1512 pst_item_journal* journal = item->journal; 1514 pst_item_journal* journal = item->journal;
1513 1515
1514 // make everything utf8 1516 // make everything utf8
1515 pst_convert_utf8_null(item, &item->subject); 1517 pst_convert_utf8_null(item, &item->subject);
1516 pst_convert_utf8_null(item, &item->body); 1518 pst_convert_utf8_null(item, &item->body);
1517 1519
1518 fprintf(f_output, "BEGIN:VJOURNAL\n"); 1520 fprintf(f_output, "BEGIN:VJOURNAL\n");
1519 fprintf(f_output, "DTSTAMP:%s\n", pst_rfc2445_datetime_format_now()); 1521 fprintf(f_output, "DTSTAMP:%s\n", pst_rfc2445_datetime_format_now(sizeof(time_buffer), time_buffer));
1520 if (item->create_date) 1522 if (item->create_date)
1521 fprintf(f_output, "CREATED:%s\n", pst_rfc2445_datetime_format(item->create_date)); 1523 fprintf(f_output, "CREATED:%s\n", pst_rfc2445_datetime_format(item->create_date, sizeof(time_buffer), time_buffer));
1522 if (item->modify_date) 1524 if (item->modify_date)
1523 fprintf(f_output, "LAST-MOD:%s\n", pst_rfc2445_datetime_format(item->modify_date)); 1525 fprintf(f_output, "LAST-MOD:%s\n", pst_rfc2445_datetime_format(item->modify_date, sizeof(time_buffer), time_buffer));
1524 if (item->subject.str) 1526 if (item->subject.str)
1525 fprintf(f_output, "SUMMARY:%s\n", pst_rfc2426_escape(item->subject.str)); 1527 fprintf(f_output, "SUMMARY:%s\n", pst_rfc2426_escape(item->subject.str));
1526 if (item->body.str) 1528 if (item->body.str)
1527 fprintf(f_output, "DESCRIPTION:%s\n", pst_rfc2426_escape(item->body.str)); 1529 fprintf(f_output, "DESCRIPTION:%s\n", pst_rfc2426_escape(item->body.str));
1528 if (journal && journal->start) 1530 if (journal && journal->start)
1529 fprintf(f_output, "DTSTART;VALUE=DATE-TIME:%s\n", pst_rfc2445_datetime_format(journal->start)); 1531 fprintf(f_output, "DTSTART;VALUE=DATE-TIME:%s\n", pst_rfc2445_datetime_format(journal->start, sizeof(time_buffer), time_buffer));
1530 fprintf(f_output, "END:VJOURNAL\n"); 1532 fprintf(f_output, "END:VJOURNAL\n");
1531 } 1533 }
1532 1534
1533 1535
1534 /** 1536 void write_appointment(FILE* f_output, pst_item* item, int event_open)
1535 compare two FILETIME objects after converting to unix time_t. This 1537 {
1536 allows FILETIMEs that are beyond the range of time_t representaion to 1538 char time_buffer[30];
1537 be converted to 0, and therefore seem to be less than the right
1538 side. The actual recurrence end values seen in pst files are very
1539 large (outside the range of 32 bit time_t), but still finite. That is
1540 a strange way to represent an infinite recurrence.
1541 */
1542 int file_time_compare(FILETIME* left, FILETIME* right)
1543 {
1544 time_t delta = pst_fileTimeToUnixTime(left) - pst_fileTimeToUnixTime(right);
1545 if (delta < 0) return -1;
1546 if (delta > 0) return 1;
1547 return 0;
1548 }
1549
1550
1551 void write_appointment(FILE* f_output, pst_item* item)
1552 {
1553 pst_item_appointment* appointment = item->appointment; 1539 pst_item_appointment* appointment = item->appointment;
1554 1540
1555 // make everything utf8 1541 // make everything utf8
1556 pst_convert_utf8_null(item, &item->subject); 1542 pst_convert_utf8_null(item, &item->subject);
1557 pst_convert_utf8_null(item, &item->body); 1543 pst_convert_utf8_null(item, &item->body);
1558 pst_convert_utf8_null(item, &appointment->location); 1544 pst_convert_utf8_null(item, &appointment->location);
1559 1545
1560 fprintf(f_output, "BEGIN:VEVENT\n"); 1546 if (!event_open) fprintf(f_output, "BEGIN:VEVENT\n");
1561 fprintf(f_output, "DTSTAMP:%s\n", pst_rfc2445_datetime_format_now()); 1547 fprintf(f_output, "DTSTAMP:%s\n", pst_rfc2445_datetime_format_now(sizeof(time_buffer), time_buffer));
1562 if (item->create_date) 1548 if (item->create_date)
1563 fprintf(f_output, "CREATED:%s\n", pst_rfc2445_datetime_format(item->create_date)); 1549 fprintf(f_output, "CREATED:%s\n", pst_rfc2445_datetime_format(item->create_date, sizeof(time_buffer), time_buffer));
1564 if (item->modify_date) 1550 if (item->modify_date)
1565 fprintf(f_output, "LAST-MOD:%s\n", pst_rfc2445_datetime_format(item->modify_date)); 1551 fprintf(f_output, "LAST-MOD:%s\n", pst_rfc2445_datetime_format(item->modify_date, sizeof(time_buffer), time_buffer));
1566 if (item->subject.str) 1552 if (item->subject.str)
1567 fprintf(f_output, "SUMMARY:%s\n", pst_rfc2426_escape(item->subject.str)); 1553 fprintf(f_output, "SUMMARY:%s\n", pst_rfc2426_escape(item->subject.str));
1568 if (item->body.str) 1554 if (item->body.str)
1569 fprintf(f_output, "DESCRIPTION:%s\n", pst_rfc2426_escape(item->body.str)); 1555 fprintf(f_output, "DESCRIPTION:%s\n", pst_rfc2426_escape(item->body.str));
1570 if (appointment && appointment->start) 1556 if (appointment && appointment->start)
1571 fprintf(f_output, "DTSTART;VALUE=DATE-TIME:%s\n", pst_rfc2445_datetime_format(appointment->start)); 1557 fprintf(f_output, "DTSTART;VALUE=DATE-TIME:%s\n", pst_rfc2445_datetime_format(appointment->start, sizeof(time_buffer), time_buffer));
1572 if (appointment && appointment->end) 1558 if (appointment && appointment->end)
1573 fprintf(f_output, "DTEND;VALUE=DATE-TIME:%s\n", pst_rfc2445_datetime_format(appointment->end)); 1559 fprintf(f_output, "DTEND;VALUE=DATE-TIME:%s\n", pst_rfc2445_datetime_format(appointment->end, sizeof(time_buffer), time_buffer));
1574 if (appointment && appointment->location.str) 1560 if (appointment && appointment->location.str)
1575 fprintf(f_output, "LOCATION:%s\n", pst_rfc2426_escape(appointment->location.str)); 1561 fprintf(f_output, "LOCATION:%s\n", pst_rfc2426_escape(appointment->location.str));
1576 if (appointment) { 1562 if (appointment) {
1577 switch (appointment->showas) { 1563 switch (appointment->showas) {
1578 case PST_FREEBUSY_TENTATIVE: 1564 case PST_FREEBUSY_TENTATIVE:
1586 fprintf(f_output, "STATUS:CONFIRMED\n"); 1572 fprintf(f_output, "STATUS:CONFIRMED\n");
1587 break; 1573 break;
1588 } 1574 }
1589 if (appointment->is_recurring) { 1575 if (appointment->is_recurring) {
1590 const char* rules[] = {"DAILY", "WEEKLY", "MONTHLY", "YEARLY"}; 1576 const char* rules[] = {"DAILY", "WEEKLY", "MONTHLY", "YEARLY"};
1577 const char* days[] = {"SU", "MO", "TU", "WE", "TH", "FR", "SA"};
1591 pst_recurrence *rdata = pst_convert_recurrence(appointment); 1578 pst_recurrence *rdata = pst_convert_recurrence(appointment);
1592 fprintf(f_output, "RRULE:FREQ=%s", rules[rdata->type]); 1579 fprintf(f_output, "RRULE:FREQ=%s", rules[rdata->type]);
1593 if (rdata->count) fprintf(f_output, ";COUNT=%u", rdata->count); 1580 if (rdata->count) fprintf(f_output, ";COUNT=%u", rdata->count);
1594 if (rdata->interval) fprintf(f_output, ";INTERVAL=%u", rdata->interval); 1581 if (rdata->interval) fprintf(f_output, ";INTERVAL=%u", rdata->interval);
1582 if (rdata->dayofmonth) fprintf(f_output, ";BYMONTHDAY=%d", rdata->dayofmonth);
1583 if (rdata->monthofyear) fprintf(f_output, ";BYMONTH=%d", rdata->monthofyear);
1584 if (rdata->position) fprintf(f_output, ";BYSETPOS=%d", rdata->position);
1585 if (rdata->bydaymask) {
1586 char byday[40];
1587 int empty = 1;
1588 int i=0;
1589 memset(byday, 0, sizeof(byday));
1590 for (i=0; i<6; i++) {
1591 int bit = 1 << i;
1592 if (bit & rdata->bydaymask) {
1593 char temp[40];
1594 snprintf(temp, sizeof(temp), "%s%s%s", byday, (empty) ? "BYDAY=" : ";", days[i]);
1595 strcpy(byday, temp);
1596 empty = 0;
1597 }
1598 }
1599 }
1595 fprintf(f_output, "\n"); 1600 fprintf(f_output, "\n");
1596 pst_free_recurrence(rdata); 1601 pst_free_recurrence(rdata);
1597 } 1602 }
1598 switch (appointment->label) { 1603 switch (appointment->label) {
1599 case PST_APP_LABEL_NONE: 1604 case PST_APP_LABEL_NONE: