Mercurial > libpst
comparison src/readpst.c @ 151:cda7c812ec01
track character set individually for each mapi element
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Sun, 08 Mar 2009 14:35:26 -0700 |
parents | 06aa84023b48 |
children | 581fab9f1dc7 |
comparison
equal
deleted
inserted
replaced
150:06aa84023b48 | 151:cda7c812ec01 |
---|---|
49 char* header_end_field(char *field); | 49 char* header_end_field(char *field); |
50 void header_strip_field(char *header, char *field); | 50 void header_strip_field(char *header, char *field); |
51 int test_base64(char *body); | 51 int test_base64(char *body); |
52 void find_html_charset(char *html, char *charset, size_t charsetlen); | 52 void find_html_charset(char *html, char *charset, size_t charsetlen); |
53 void find_rfc822_headers(char** extra_mime_headers); | 53 void find_rfc822_headers(char** extra_mime_headers); |
54 void write_body_part(FILE* f_output, char *body, int32_t body_was_unicode, char *mime, char *charset, char *boundary, pst_file* pst); | 54 void write_body_part(FILE* f_output, pst_string *body, char *mime, char *charset, char *boundary, pst_file* pst); |
55 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); | 55 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); |
56 void write_vcard(FILE* f_output, pst_item_contact* contact, char comment[]); | 56 void write_vcard(FILE* f_output, pst_item *item, pst_item_contact* contact, char comment[]); |
57 void write_appointment(FILE* f_output, pst_item_appointment* appointment, | 57 void write_appointment(FILE* f_output, pst_item *item, pst_item_appointment* appointment, |
58 pst_item_email* email, FILETIME* create_date, FILETIME* modify_date); | 58 FILETIME* create_date, FILETIME* modify_date); |
59 void create_enter_dir(struct file_ll* f, pst_item *item); | 59 void create_enter_dir(struct file_ll* f, pst_item *item); |
60 void close_enter_dir(struct file_ll *f); | 60 void close_enter_dir(struct file_ll *f); |
61 | 61 |
62 const char* prog_name; | 62 const char* prog_name; |
63 char* output_dir = "."; | 63 char* output_dir = "."; |
138 else { | 138 else { |
139 DEBUG_MAIN(("main: Desc Email ID %#"PRIx64" [d_ptr->d_id = %#"PRIx64"]\n", d_ptr->desc->id, d_ptr->d_id)); | 139 DEBUG_MAIN(("main: Desc Email ID %#"PRIx64" [d_ptr->d_id = %#"PRIx64"]\n", d_ptr->desc->id, d_ptr->d_id)); |
140 | 140 |
141 item = pst_parse_item(&pstfile, d_ptr, NULL); | 141 item = pst_parse_item(&pstfile, d_ptr, NULL); |
142 DEBUG_MAIN(("main: About to process item\n")); | 142 DEBUG_MAIN(("main: About to process item\n")); |
143 if (item && item->email && item->email->subject && item->email->subject->subj) { | 143 if (item && item->subject.str) { |
144 DEBUG_EMAIL(("item->email->subject->subj = %s\n", item->email->subject->subj)); | 144 DEBUG_EMAIL(("item->subject = %s\n", item->subject.str)); |
145 } | 145 } |
146 if (item) { | 146 if (item) { |
147 if (item->folder && d_ptr->child && (deleted_mode == DMODE_INCLUDE || strcasecmp(item->file_as, "Deleted Items"))) { | 147 if (item->folder && d_ptr->child && item->file_as.str && (deleted_mode == DMODE_INCLUDE || strcasecmp(item->file_as.str, "Deleted Items"))) { |
148 //if this is a non-empty folder other than deleted items, we want to recurse into it | 148 //if this is a non-empty folder other than deleted items, we want to recurse into it |
149 if (output_mode != OUTPUT_QUIET) printf("Processing Folder \"%s\"\n", item->file_as); | 149 if (output_mode != OUTPUT_QUIET) printf("Processing Folder \"%s\"\n", item->file_as.str); |
150 process(item, d_ptr->child); | 150 process(item, d_ptr->child); |
151 | 151 |
152 } else if (item->contact && (item->type == PST_TYPE_CONTACT)) { | 152 } else if (item->contact && (item->type == PST_TYPE_CONTACT)) { |
153 // deal with a contact | 153 // deal with a contact |
154 // write them to the file, one per line in this format | 154 // write them to the file, one per line in this format |
157 ff.email_count++; | 157 ff.email_count++; |
158 DEBUG_MAIN(("main: Processing Contact\n")); | 158 DEBUG_MAIN(("main: Processing Contact\n")); |
159 if (ff.type != PST_TYPE_CONTACT) { | 159 if (ff.type != PST_TYPE_CONTACT) { |
160 DEBUG_MAIN(("main: I have a contact, but the folder isn't a contacts folder. Processing anyway\n")); | 160 DEBUG_MAIN(("main: I have a contact, but the folder isn't a contacts folder. Processing anyway\n")); |
161 } | 161 } |
162 if (contact_mode == CMODE_VCARD) | 162 if (contact_mode == CMODE_VCARD) { |
163 write_vcard(ff.output, item->contact, item->comment); | 163 pst_convert_utf8_null(item, &item->comment); |
164 else | 164 write_vcard(ff.output, item, item->contact, item->comment.str); |
165 fprintf(ff.output, "%s <%s>\n", item->contact->fullname, item->contact->address1); | 165 } |
166 else { | |
167 pst_convert_utf8(item, &item->contact->fullname); | |
168 pst_convert_utf8(item, &item->contact->address1); | |
169 fprintf(ff.output, "%s <%s>\n", item->contact->fullname.str, item->contact->address1.str); | |
170 } | |
166 | 171 |
167 } else if (item->email && (item->type == PST_TYPE_NOTE || item->type == PST_TYPE_REPORT || item->type == PST_TYPE_OTHER)) { | 172 } else if (item->email && (item->type == PST_TYPE_NOTE || item->type == PST_TYPE_REPORT || item->type == PST_TYPE_OTHER)) { |
168 char *extra_mime_headers = NULL; | 173 char *extra_mime_headers = NULL; |
169 if (mode == MODE_SEPARATE) mk_separate_file(&ff); | 174 if (mode == MODE_SEPARATE) mk_separate_file(&ff); |
170 ff.email_count++; | 175 ff.email_count++; |
181 DEBUG_MAIN(("main: Processing Journal Entry\n")); | 186 DEBUG_MAIN(("main: Processing Journal Entry\n")); |
182 if (ff.type != PST_TYPE_JOURNAL) { | 187 if (ff.type != PST_TYPE_JOURNAL) { |
183 DEBUG_MAIN(("main: I have a journal entry, but the folder isn't a journal folder. Processing anyway\n")); | 188 DEBUG_MAIN(("main: I have a journal entry, but the folder isn't a journal folder. Processing anyway\n")); |
184 } | 189 } |
185 fprintf(ff.output, "BEGIN:VJOURNAL\n"); | 190 fprintf(ff.output, "BEGIN:VJOURNAL\n"); |
186 if (item->email && item->email->subject && item->email->subject->subj) | 191 if (item->subject.str) { |
187 fprintf(ff.output, "SUMMARY:%s\n", pst_rfc2426_escape(item->email->subject->subj)); | 192 pst_convert_utf8(item, &item->subject); |
188 if (item->email && item->email->body) | 193 fprintf(ff.output, "SUMMARY:%s\n", pst_rfc2426_escape(item->subject.str)); |
189 fprintf(ff.output, "DESCRIPTION:%s\n", pst_rfc2426_escape(item->email->body)); | 194 } |
195 if (item->body.str) { | |
196 pst_convert_utf8(item, &item->body); | |
197 fprintf(ff.output, "DESCRIPTION:%s\n", pst_rfc2426_escape(item->body.str)); | |
198 } | |
190 if (item->journal->start) | 199 if (item->journal->start) |
191 fprintf(ff.output, "DTSTART;VALUE=DATE-TIME:%s\n", pst_rfc2445_datetime_format(item->journal->start)); | 200 fprintf(ff.output, "DTSTART;VALUE=DATE-TIME:%s\n", pst_rfc2445_datetime_format(item->journal->start)); |
192 fprintf(ff.output, "END:VJOURNAL\n\n"); | 201 fprintf(ff.output, "END:VJOURNAL\n\n"); |
193 | 202 |
194 } else if (item->appointment && (item->type == PST_TYPE_APPOINTMENT)) { | 203 } else if (item->appointment && (item->type == PST_TYPE_APPOINTMENT)) { |
197 ff.email_count++; | 206 ff.email_count++; |
198 DEBUG_MAIN(("main: Processing Appointment Entry\n")); | 207 DEBUG_MAIN(("main: Processing Appointment Entry\n")); |
199 if (ff.type != PST_TYPE_APPOINTMENT) { | 208 if (ff.type != PST_TYPE_APPOINTMENT) { |
200 DEBUG_MAIN(("main: I have an appointment, but folder isn't specified as an appointment type. Processing...\n")); | 209 DEBUG_MAIN(("main: I have an appointment, but folder isn't specified as an appointment type. Processing...\n")); |
201 } | 210 } |
202 write_appointment(ff.output, item->appointment, item->email, item->create_date, item->modify_date); | 211 write_appointment(ff.output, item, item->appointment, item->create_date, item->modify_date); |
203 | 212 |
204 } else if (item->message_store) { | 213 } else if (item->message_store) { |
205 // there should only be one message_store, and we have already done it | 214 // there should only be one message_store, and we have already done it |
206 DEBUG_MAIN(("item with message store content, type %i %s folder type %i, skipping it\n", item->type, item->ascii_type, ff.type)); | 215 DEBUG_MAIN(("item with message store content, type %i %s folder type %i, skipping it\n", item->type, item->ascii_type, ff.type)); |
207 | 216 |
208 } else { | 217 } else { |
209 // these all seem to be things that MS agrees are not included in the item count | 218 // these all seem to be things that MS agrees are not included in the item count |
210 //ff.skip_count++; | 219 //ff.skip_count++; |
211 DEBUG_MAIN(("main: Unknown item type %i (%s) name (%s)\n", | 220 DEBUG_MAIN(("main: Unknown item type %i (%s) name (%s)\n", |
212 item->type, item->ascii_type, item->file_as)); | 221 item->type, item->ascii_type, item->file_as.str)); |
213 } | 222 } |
214 pst_freeItem(item); | 223 pst_freeItem(item); |
215 } else { | 224 } else { |
216 ff.skip_count++; | 225 ff.skip_count++; |
217 DEBUG_MAIN(("main: A NULL item was seen\n")); | 226 DEBUG_MAIN(("main: A NULL item was seen\n")); |
322 if (mode == MODE_DECSPEW) { | 331 if (mode == MODE_DECSPEW) { |
323 FILE *fp; | 332 FILE *fp; |
324 char buf[1024]; | 333 char buf[1024]; |
325 size_t l = 0; | 334 size_t l = 0; |
326 if (NULL == (fp = fopen(fname, "rb"))) { | 335 if (NULL == (fp = fopen(fname, "rb"))) { |
327 fprintf(stderr, "Couldn't open file %s\n", fname ); | 336 WARN(("Couldn't open file %s\n", fname)); |
328 DEBUG_RET(); | 337 DEBUG_RET(); |
329 return 1; | 338 return 1; |
330 } | 339 } |
331 | 340 |
332 while (0 != (l = fread(buf, 1, 1024, fp))) { | 341 while (0 != (l = fread(buf, 1, 1024, fp))) { |
333 if (0 != pst_decrypt(0, buf, l, PST_COMP_ENCRYPT)) | 342 if (0 != pst_decrypt(0, buf, l, PST_COMP_ENCRYPT)) |
334 fprintf(stderr, "pst_decrypt() failed (I'll try to continue)\n"); | 343 WARN(("pst_decrypt() failed (I'll try to continue)\n")); |
335 | 344 |
336 if (l != pst_fwrite(buf, 1, l, stdout)) { | 345 if (l != pst_fwrite(buf, 1, l, stdout)) { |
337 fprintf(stderr, "Couldn't output to stdout?\n"); | 346 WARN(("Couldn't output to stdout?\n")); |
338 DEBUG_RET(); | 347 DEBUG_RET(); |
339 return 1; | 348 return 1; |
340 } | 349 } |
341 } | 350 } |
342 DEBUG_RET(); | 351 DEBUG_RET(); |
365 DEBUG_RET(); | 374 DEBUG_RET(); |
366 DIE(("main: Could not get root record\n")); | 375 DIE(("main: Could not get root record\n")); |
367 } | 376 } |
368 | 377 |
369 // default the file_as to the same as the main filename if it doesn't exist | 378 // default the file_as to the same as the main filename if it doesn't exist |
370 if (!item->file_as) { | 379 if (!item->file_as.str) { |
371 if (!(temp = strrchr(fname, '/'))) | 380 if (!(temp = strrchr(fname, '/'))) |
372 if (!(temp = strrchr(fname, '\\'))) | 381 if (!(temp = strrchr(fname, '\\'))) |
373 temp = fname; | 382 temp = fname; |
374 else | 383 else |
375 temp++; // get past the "\\" | 384 temp++; // get past the "\\" |
376 else | 385 else |
377 temp++; // get past the "/" | 386 temp++; // get past the "/" |
378 item->file_as = (char*)xmalloc(strlen(temp)+1); | 387 item->file_as.str = (char*)xmalloc(strlen(temp)+1); |
379 strcpy(item->file_as, temp); | 388 strcpy(item->file_as.str, temp); |
380 DEBUG_MAIN(("file_as was blank, so am using %s\n", item->file_as)); | 389 item->file_as.is_utf8 = 1; |
381 } | 390 DEBUG_MAIN(("file_as was blank, so am using %s\n", item->file_as.str)); |
382 DEBUG_MAIN(("main: Root Folder Name: %s\n", item->file_as)); | 391 } |
392 DEBUG_MAIN(("main: Root Folder Name: %s\n", item->file_as.str)); | |
383 | 393 |
384 d_ptr = pst_getTopOfFolders(&pstfile, item); | 394 d_ptr = pst_getTopOfFolders(&pstfile, item); |
385 if (!d_ptr) { | 395 if (!d_ptr) { |
386 DEBUG_RET(); | 396 DEBUG_RET(); |
387 DIE(("Top of folders record not found. Cannot continue\n")); | 397 DIE(("Top of folders record not found. Cannot continue\n")); |
396 } | 406 } |
397 | 407 |
398 | 408 |
399 void write_email_body(FILE *f, char *body) { | 409 void write_email_body(FILE *f, char *body) { |
400 char *n = body; | 410 char *n = body; |
401 // DEBUG_MAIN(("write_email_body(): \"%s\"\n", body)); | |
402 DEBUG_ENT("write_email_body"); | 411 DEBUG_ENT("write_email_body"); |
403 while (n) { | 412 while (n) { |
404 if (strncmp(body, "From ", 5) == 0) | 413 if (strncmp(body, "From ", 5) == 0) |
405 fprintf(f, ">"); | 414 fprintf(f, ">"); |
406 if ((n = strchr(body, '\n'))) { | 415 if ((n = strchr(body, '\n'))) { |
698 int x = 0; | 707 int x = 0; |
699 char *temp = NULL; | 708 char *temp = NULL; |
700 | 709 |
701 // If there is a long filename (filename2) use that, otherwise | 710 // If there is a long filename (filename2) use that, otherwise |
702 // use the 8.3 filename (filename1) | 711 // use the 8.3 filename (filename1) |
703 char *attach_filename = (attach->filename2) ? attach->filename2 | 712 char *attach_filename = (attach->filename2.str) ? attach->filename2.str |
704 : attach->filename1; | 713 : attach->filename1.str; |
705 DEBUG_ENT("write_separate_attachment"); | 714 DEBUG_ENT("write_separate_attachment"); |
706 | 715 |
707 check_filename(f_name); | 716 check_filename(f_name); |
708 if (!attach_filename) { | 717 if (!attach_filename) { |
709 // generate our own (dummy) filename for the attachement | 718 // generate our own (dummy) filename for the attachement |
742 void write_embedded_message(FILE* f_output, pst_item_attach* attach, char *boundary, pst_file* pf, char** extra_mime_headers) | 751 void write_embedded_message(FILE* f_output, pst_item_attach* attach, char *boundary, pst_file* pf, char** extra_mime_headers) |
743 { | 752 { |
744 pst_index_ll *ptr; | 753 pst_index_ll *ptr; |
745 DEBUG_ENT("write_embedded_message"); | 754 DEBUG_ENT("write_embedded_message"); |
746 fprintf(f_output, "\n--%s\n", boundary); | 755 fprintf(f_output, "\n--%s\n", boundary); |
747 fprintf(f_output, "Content-Type: %s\n\n", attach->mimetype); | 756 fprintf(f_output, "Content-Type: %s\n\n", attach->mimetype.str); |
748 ptr = pst_getID(pf, attach->id_val); | 757 ptr = pst_getID(pf, attach->id_val); |
749 | 758 |
750 pst_desc_ll d_ptr; | 759 pst_desc_ll d_ptr; |
751 d_ptr.d_id = 0; | 760 d_ptr.d_id = 0; |
752 d_ptr.parent_d_id = 0; | 761 d_ptr.parent_d_id = 0; |
790 return; | 799 return; |
791 } | 800 } |
792 } | 801 } |
793 | 802 |
794 fprintf(f_output, "\n--%s\n", boundary); | 803 fprintf(f_output, "\n--%s\n", boundary); |
795 if (!attach->mimetype) { | 804 if (!attach->mimetype.str) { |
796 fprintf(f_output, "Content-Type: %s\n", MIME_TYPE_DEFAULT); | 805 fprintf(f_output, "Content-Type: %s\n", MIME_TYPE_DEFAULT); |
797 } else { | 806 } else { |
798 fprintf(f_output, "Content-Type: %s\n", attach->mimetype); | 807 fprintf(f_output, "Content-Type: %s\n", attach->mimetype.str); |
799 } | 808 } |
800 fprintf(f_output, "Content-Transfer-Encoding: base64\n"); | 809 fprintf(f_output, "Content-Transfer-Encoding: base64\n"); |
801 | 810 |
802 // If there is a long filename (filename2) use that, otherwise | 811 // If there is a long filename (filename2) use that, otherwise |
803 // use the 8.3 filename (filename1) | 812 // use the 8.3 filename (filename1) |
804 attach_filename = (attach->filename2) ? attach->filename2 : attach->filename1; | 813 attach_filename = (attach->filename2.str) ? attach->filename2.str : attach->filename1.str; |
805 if (!attach_filename) { | 814 if (!attach_filename) { |
806 fprintf(f_output, "Content-Disposition: inline\n\n"); | 815 fprintf(f_output, "Content-Disposition: inline\n\n"); |
807 } else { | 816 } else { |
808 fprintf(f_output, "Content-Disposition: attachment; filename=\"%s\"\n\n", attach_filename); | 817 fprintf(f_output, "Content-Disposition: attachment; filename=\"%s\"\n\n", attach_filename); |
809 } | 818 } |
984 } | 993 } |
985 DEBUG_RET(); | 994 DEBUG_RET(); |
986 } | 995 } |
987 | 996 |
988 | 997 |
989 void write_body_part(FILE* f_output, char *body, int32_t body_was_unicode, char *mime, char *charset, char *boundary, pst_file* pst) | 998 void write_body_part(FILE* f_output, pst_string *body, char *mime, char *charset, char *boundary, pst_file* pst) |
990 { | 999 { |
991 char *needfree = NULL; | |
992 DEBUG_ENT("write_body_part"); | 1000 DEBUG_ENT("write_body_part"); |
993 if (body_was_unicode && (strcasecmp("utf-8", charset))) { | 1001 if (body->is_utf8 && (strcasecmp("utf-8", charset))) { |
994 // try to convert to the specified charset since the target | 1002 // try to convert to the specified charset since the target |
995 // is not utf-8, and the data came from a unicode (utf16) field | 1003 // is not utf-8, and the data came from a unicode (utf16) field |
996 // and is now in utf-8. | 1004 // and is now in utf-8. |
997 size_t rc; | 1005 size_t rc; |
998 DEBUG_EMAIL(("Convert %s utf-8 to %s\n", mime, charset)); | 1006 DEBUG_EMAIL(("Convert %s utf-8 to %s\n", mime, charset)); |
999 vbuf *newer = vballoc(2); | 1007 vbuf *newer = vballoc(2); |
1000 rc = vb_utf8to8bit(newer, body, strlen(body) + 1, charset); | 1008 rc = vb_utf8to8bit(newer, body->str, strlen(body->str) + 1, charset); |
1001 if (rc == (size_t)-1) { | 1009 if (rc == (size_t)-1) { |
1002 // unable to convert, change the charset to utf8 | 1010 // unable to convert, change the charset to utf8 |
1003 free(newer->b); | 1011 free(newer->b); |
1004 DEBUG_EMAIL(("Failed to convert %s utf-8 to %s\n", mime, charset)); | 1012 DEBUG_EMAIL(("Failed to convert %s utf-8 to %s\n", mime, charset)); |
1005 charset = "utf-8"; | 1013 charset = "utf-8"; |
1006 } | 1014 } |
1007 else { | 1015 else { |
1008 needfree = body = newer->b; | 1016 free(body->str); |
1017 body->str = newer->b; | |
1009 } | 1018 } |
1010 free(newer); | 1019 free(newer); |
1011 } | 1020 } |
1012 removeCR(body); | 1021 removeCR(body->str); |
1013 int base64 = test_base64(body); | 1022 int base64 = test_base64(body->str); |
1014 fprintf(f_output, "\n--%s\n", boundary); | 1023 fprintf(f_output, "\n--%s\n", boundary); |
1015 fprintf(f_output, "Content-Type: %s; charset=\"%s\"\n", mime, charset); | 1024 fprintf(f_output, "Content-Type: %s; charset=\"%s\"\n", mime, charset); |
1016 if (base64) fprintf(f_output, "Content-Transfer-Encoding: base64\n"); | 1025 if (base64) fprintf(f_output, "Content-Transfer-Encoding: base64\n"); |
1017 fprintf(f_output, "\n"); | 1026 fprintf(f_output, "\n"); |
1018 if (base64) { | 1027 if (base64) { |
1019 char *enc = base64_encode(body, strlen(body)); | 1028 char *enc = base64_encode(body->str, strlen(body->str)); |
1020 if (enc) { | 1029 if (enc) { |
1021 write_email_body(f_output, enc); | 1030 write_email_body(f_output, enc); |
1022 fprintf(f_output, "\n"); | 1031 fprintf(f_output, "\n"); |
1023 free(enc); | 1032 free(enc); |
1024 } | 1033 } |
1025 } | 1034 } |
1026 else { | 1035 else { |
1027 write_email_body(f_output, body); | 1036 write_email_body(f_output, body->str); |
1028 } | 1037 } |
1029 if (needfree) free(needfree); | 1038 DEBUG_RET(); |
1030 DEBUG_RET(); | |
1031 } | |
1032 | |
1033 | |
1034 const char* codepage(int cp); | |
1035 const char* codepage(int cp) { | |
1036 static char buffer[20]; | |
1037 switch (cp) { | |
1038 case 932 : return "iso-2022-jp"; | |
1039 case 936 : return "gb2313"; | |
1040 case 950 : return "big5"; | |
1041 case 20127 : return "us-ascii"; | |
1042 case 20269 : return "iso-6937"; | |
1043 case 20865 : return "iso-8859-15"; | |
1044 case 20866 : return "koi8-r"; | |
1045 case 21866 : return "koi8-u"; | |
1046 case 28591 : return "iso-8859-1"; | |
1047 case 28592 : return "iso-8859-2"; | |
1048 case 28595 : return "iso-8859-5"; | |
1049 case 28596 : return "iso-8859-6"; | |
1050 case 28597 : return "iso-8859-7"; | |
1051 case 28598 : return "iso-8859-8"; | |
1052 case 28599 : return "iso-8859-9"; | |
1053 case 50220 : return "iso-2022-jp"; | |
1054 case 50221 : return "csiso2022jp"; | |
1055 case 51932 : return "euc-jp"; | |
1056 case 51949 : return "euc-kr"; | |
1057 case 65000 : return "utf-7"; | |
1058 case 65001 : return "utf-8"; | |
1059 default : | |
1060 snprintf(buffer, sizeof(buffer), "windows-%d", cp); | |
1061 return buffer; | |
1062 } | |
1063 return NULL; | |
1064 } | 1039 } |
1065 | 1040 |
1066 | 1041 |
1067 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) | 1042 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) |
1068 { | 1043 { |
1073 int sender_known = 0; | 1048 int sender_known = 0; |
1074 char *temp = NULL; | 1049 char *temp = NULL; |
1075 int attach_num; | 1050 int attach_num; |
1076 time_t em_time; | 1051 time_t em_time; |
1077 char *c_time; | 1052 char *c_time; |
1078 char *headers = (item->email->header) ? item->email->header : *extra_mime_headers; | 1053 char *headers = NULL; |
1079 int has_from, has_subject, has_to, has_cc, has_date, has_msgid; | 1054 int has_from, has_subject, has_to, has_cc, has_date, has_msgid; |
1080 has_from = has_subject = has_to = has_cc = has_date = has_msgid = 0; | 1055 has_from = has_subject = has_to = has_cc = has_date = has_msgid = 0; |
1081 DEBUG_ENT("write_normal_email"); | 1056 DEBUG_ENT("write_normal_email"); |
1082 | 1057 |
1058 pst_convert_utf8_null(item, &item->email->header); | |
1059 headers = (item->email->header.str) ? item->email->header.str : *extra_mime_headers; | |
1060 | |
1083 // setup default body character set and report type | 1061 // setup default body character set and report type |
1084 snprintf(body_charset, sizeof(body_charset), "%s", | 1062 strncpy(body_charset, pst_default_charset(item), sizeof(body_charset)); |
1085 (item->body_charset) ? item->body_charset : | 1063 body_charset[sizeof(body_charset)-1] = '\0'; |
1086 (item->message_codepage) ? codepage(item->message_codepage) : | |
1087 (item->internet_cpid) ? codepage(item->internet_cpid) : | |
1088 "utf-8"); | |
1089 body_report[0] = '\0'; | 1064 body_report[0] = '\0'; |
1090 | 1065 |
1091 // setup default sender | 1066 // setup default sender |
1092 if (item->email->sender_address && strchr(item->email->sender_address, '@')) { | 1067 pst_convert_utf8(item, &item->email->sender_address); |
1093 temp = item->email->sender_address; | 1068 if (item->email->sender_address.str && strchr(item->email->sender_address.str, '@')) { |
1069 temp = item->email->sender_address.str; | |
1094 sender_known = 1; | 1070 sender_known = 1; |
1095 } | 1071 } |
1096 else { | 1072 else { |
1097 temp = "MAILER-DAEMON"; | 1073 temp = "MAILER-DAEMON"; |
1098 } | 1074 } |
1099 snprintf(sender, sizeof(sender), "%s", temp); | 1075 strncpy(sender, temp, sizeof(sender)); |
1076 sender[sizeof(sender)-1] = '\0'; | |
1100 | 1077 |
1101 // convert the sent date if it exists, or set it to a fixed date | 1078 // convert the sent date if it exists, or set it to a fixed date |
1102 if (item->email->sent_date) { | 1079 if (item->email->sent_date) { |
1103 em_time = fileTimeToUnixTime(item->email->sent_date, 0); | 1080 em_time = fileTimeToUnixTime(item->email->sent_date, 0); |
1104 c_time = ctime(&em_time); | 1081 c_time = ctime(&em_time); |
1169 header_strip_field(headers, "\nX-From_: "); | 1146 header_strip_field(headers, "\nX-From_: "); |
1170 } | 1147 } |
1171 | 1148 |
1172 DEBUG_EMAIL(("About to print Header\n")); | 1149 DEBUG_EMAIL(("About to print Header\n")); |
1173 | 1150 |
1174 if (item && item->email && item->email->subject && item->email->subject->subj) { | 1151 if (item && item->subject.str) { |
1175 DEBUG_EMAIL(("item->email->subject->subj = %s\n", item->email->subject->subj)); | 1152 pst_convert_utf8(item, &item->subject); |
1153 DEBUG_EMAIL(("item->subject = %s\n", item->subject.str)); | |
1176 } | 1154 } |
1177 | 1155 |
1178 if (mode != MODE_SEPARATE) { | 1156 if (mode != MODE_SEPARATE) { |
1179 // most modes need this separator line. | 1157 // most modes need this separator line. |
1180 // procmail produces this separator without the quotes around the | 1158 // procmail produces this separator without the quotes around the |
1193 } | 1171 } |
1194 | 1172 |
1195 // create required header fields that are not already written | 1173 // create required header fields that are not already written |
1196 | 1174 |
1197 if (!has_from) { | 1175 if (!has_from) { |
1198 fprintf(f_output, "From: \"%s\" <%s>\n", item->email->outlook_sender_name, sender); | 1176 fprintf(f_output, "From: \"%s\" <%s>\n", item->email->outlook_sender_name.str, sender); |
1199 } | 1177 } |
1200 | 1178 |
1201 if (!has_subject) { | 1179 if (!has_subject) { |
1202 if (item->email->subject && item->email->subject->subj) { | 1180 if (item->subject.str) { |
1203 fprintf(f_output, "Subject: %s\n", item->email->subject->subj); | 1181 fprintf(f_output, "Subject: %s\n", item->subject.str); |
1204 } else { | 1182 } else { |
1205 fprintf(f_output, "Subject: \n"); | 1183 fprintf(f_output, "Subject: \n"); |
1206 } | 1184 } |
1207 } | 1185 } |
1208 | 1186 |
1209 if (!has_to && item->email->sentto_address) { | 1187 if (!has_to && item->email->sentto_address.str) { |
1210 fprintf(f_output, "To: %s\n", item->email->sentto_address); | 1188 pst_convert_utf8(item, &item->email->sentto_address); |
1211 } | 1189 fprintf(f_output, "To: %s\n", item->email->sentto_address.str); |
1212 | 1190 } |
1213 if (!has_cc && item->email->cc_address) { | 1191 |
1214 fprintf(f_output, "Cc: %s\n", item->email->cc_address); | 1192 if (!has_cc && item->email->cc_address.str) { |
1193 pst_convert_utf8(item, &item->email->cc_address); | |
1194 fprintf(f_output, "Cc: %s\n", item->email->cc_address.str); | |
1215 } | 1195 } |
1216 | 1196 |
1217 if (!has_date && item->email->sent_date) { | 1197 if (!has_date && item->email->sent_date) { |
1218 char c_time[C_TIME_SIZE]; | 1198 char c_time[C_TIME_SIZE]; |
1219 strftime(c_time, C_TIME_SIZE, "%a, %d %b %Y %H:%M:%S %z", gmtime(&em_time)); | 1199 strftime(c_time, C_TIME_SIZE, "%a, %d %b %Y %H:%M:%S %z", gmtime(&em_time)); |
1220 fprintf(f_output, "Date: %s\n", c_time); | 1200 fprintf(f_output, "Date: %s\n", c_time); |
1221 } | 1201 } |
1222 | 1202 |
1223 if (!has_msgid && item->email->messageid) { | 1203 if (!has_msgid && item->email->messageid.str) { |
1224 fprintf(f_output, "Message-Id: %s\n", item->email->messageid); | 1204 pst_convert_utf8(item, &item->email->messageid); |
1205 fprintf(f_output, "Message-Id: %s\n", item->email->messageid.str); | |
1225 } | 1206 } |
1226 | 1207 |
1227 // add forensic headers to capture some .pst stuff that is not really | 1208 // add forensic headers to capture some .pst stuff that is not really |
1228 // needed or used by mail clients | 1209 // needed or used by mail clients |
1229 if (item->email->sender_address && !strchr(item->email->sender_address, '@') | 1210 pst_convert_utf8_null(item, &item->email->sender_address); |
1230 && strcmp(item->email->sender_address, ".")) { | 1211 if (item->email->sender_address.str && !strchr(item->email->sender_address.str, '@') |
1231 fprintf(f_output, "X-libpst-forensic-sender: %s\n", item->email->sender_address); | 1212 && strcmp(item->email->sender_address.str, ".")) { |
1232 } | 1213 fprintf(f_output, "X-libpst-forensic-sender: %s\n", item->email->sender_address.str); |
1233 | 1214 } |
1234 if (item->email->bcc_address) { | 1215 |
1235 fprintf(f_output, "X-libpst-forensic-bcc: %s\n", item->email->bcc_address); | 1216 if (item->email->bcc_address.str) { |
1217 pst_convert_utf8(item, &item->email->bcc_address); | |
1218 fprintf(f_output, "X-libpst-forensic-bcc: %s\n", item->email->bcc_address.str); | |
1236 } | 1219 } |
1237 | 1220 |
1238 // add our own mime headers | 1221 // add our own mime headers |
1239 fprintf(f_output, "MIME-Version: 1.0\n"); | 1222 fprintf(f_output, "MIME-Version: 1.0\n"); |
1240 if (body_report[0] != '\0') { | 1223 if (body_report[0] != '\0') { |
1251 fprintf(f_output, "Content-Type: multipart/alternative;\n\tboundary=\"%s\"\n", boundary); | 1234 fprintf(f_output, "Content-Type: multipart/alternative;\n\tboundary=\"%s\"\n", boundary); |
1252 } | 1235 } |
1253 fprintf(f_output, "\n"); // end of headers, start of body | 1236 fprintf(f_output, "\n"); // end of headers, start of body |
1254 | 1237 |
1255 // now dump the body parts | 1238 // now dump the body parts |
1256 if (item->email->body) { | 1239 if (item->body.str) { |
1257 write_body_part(f_output, item->email->body, item->email->body_was_unicode, "text/plain", body_charset, boundary, pst); | 1240 write_body_part(f_output, &item->body, "text/plain", body_charset, boundary, pst); |
1258 } | 1241 } |
1259 | 1242 |
1260 if ((item->email->report_text) && (body_report[0] != '\0')) { | 1243 if ((item->email->report_text.str) && (body_report[0] != '\0')) { |
1261 write_body_part(f_output, item->email->report_text, item->email->report_was_unicode, "text/plain", body_charset, boundary, pst); | 1244 write_body_part(f_output, &item->email->report_text, "text/plain", body_charset, boundary, pst); |
1262 fprintf(f_output, "\n"); | 1245 fprintf(f_output, "\n"); |
1263 } | 1246 } |
1264 | 1247 |
1265 if (item->email->htmlbody) { | 1248 if (item->email->htmlbody.str) { |
1266 find_html_charset(item->email->htmlbody, body_charset, sizeof(body_charset)); | 1249 find_html_charset(item->email->htmlbody.str, body_charset, sizeof(body_charset)); |
1267 write_body_part(f_output, item->email->htmlbody, item->email->htmlbody_was_unicode, "text/html", body_charset, boundary, pst); | 1250 write_body_part(f_output, &item->email->htmlbody, "text/html", body_charset, boundary, pst); |
1268 } | 1251 } |
1269 | 1252 |
1270 if (item->email->rtf_compressed && save_rtf) { | 1253 if (item->email->rtf_compressed && save_rtf) { |
1271 pst_item_attach* attach = (pst_item_attach*)xmalloc(sizeof(pst_item_attach)); | 1254 pst_item_attach* attach = (pst_item_attach*)xmalloc(sizeof(pst_item_attach)); |
1272 DEBUG_EMAIL(("Adding RTF body as attachment\n")); | 1255 DEBUG_EMAIL(("Adding RTF body as attachment\n")); |
1273 memset(attach, 0, sizeof(pst_item_attach)); | 1256 memset(attach, 0, sizeof(pst_item_attach)); |
1274 attach->next = item->attach; | 1257 attach->next = item->attach; |
1275 item->attach = attach; | 1258 item->attach = attach; |
1276 attach->data = lzfu_decompress(item->email->rtf_compressed, item->email->rtf_compressed_size, &attach->size); | 1259 attach->data = lzfu_decompress(item->email->rtf_compressed, item->email->rtf_compressed_size, &attach->size); |
1277 attach->filename2 = strdup(RTF_ATTACH_NAME); | 1260 attach->filename2.str = strdup(RTF_ATTACH_NAME); |
1278 attach->mimetype = strdup(RTF_ATTACH_TYPE); | 1261 attach->filename2.is_utf8 = 1; |
1262 attach->mimetype.str = strdup(RTF_ATTACH_TYPE); | |
1263 attach->mimetype.is_utf8 = 1; | |
1279 } | 1264 } |
1280 | 1265 |
1281 if (item->email->encrypted_body || item->email->encrypted_htmlbody) { | 1266 if (item->email->encrypted_body || item->email->encrypted_htmlbody) { |
1282 // if either the body or htmlbody is encrypted, add them as attachments | 1267 // if either the body or htmlbody is encrypted, add them as attachments |
1283 if (item->email->encrypted_body) { | 1268 if (item->email->encrypted_body) { |
1309 // other attachments | 1294 // other attachments |
1310 { | 1295 { |
1311 pst_item_attach* attach; | 1296 pst_item_attach* attach; |
1312 attach_num = 0; | 1297 attach_num = 0; |
1313 for (attach = item->attach; attach; attach = attach->next) { | 1298 for (attach = item->attach; attach; attach = attach->next) { |
1299 pst_convert_utf8_null(item, &attach->filename1); | |
1300 pst_convert_utf8_null(item, &attach->filename2); | |
1301 pst_convert_utf8_null(item, &attach->mimetype); | |
1314 DEBUG_EMAIL(("Attempting Attachment encoding\n")); | 1302 DEBUG_EMAIL(("Attempting Attachment encoding\n")); |
1315 if (!attach->data && attach->mimetype && !strcmp(attach->mimetype, RFC822)) { | 1303 if (!attach->data && attach->mimetype.str && !strcmp(attach->mimetype.str, RFC822)) { |
1316 DEBUG_EMAIL(("seem to have special embedded message attachment\n")); | 1304 DEBUG_EMAIL(("seem to have special embedded message attachment\n")); |
1317 find_rfc822_headers(extra_mime_headers); | 1305 find_rfc822_headers(extra_mime_headers); |
1318 write_embedded_message(f_output, attach, boundary, pst, extra_mime_headers); | 1306 write_embedded_message(f_output, attach, boundary, pst, extra_mime_headers); |
1319 } | 1307 } |
1320 else if (mode == MODE_SEPARATE && !mode_MH) | 1308 else if (mode == MODE_SEPARATE && !mode_MH) |
1332 } | 1320 } |
1333 DEBUG_RET(); | 1321 DEBUG_RET(); |
1334 } | 1322 } |
1335 | 1323 |
1336 | 1324 |
1337 void write_vcard(FILE* f_output, pst_item_contact* contact, char comment[]) | 1325 void write_vcard(FILE* f_output, pst_item *item, pst_item_contact* contact, char comment[]) |
1338 { | 1326 { |
1339 // We can only call rfc escape once per printf, since the second call | 1327 // We can only call rfc escape once per printf, since the second call |
1340 // may free the buffer returned by the first call. | 1328 // may free the buffer returned by the first call. |
1341 // I had tried to place those into a single printf - Carl. | 1329 // I had tried to place those into a single printf - Carl. |
1342 | 1330 |
1343 DEBUG_ENT("write_vcard"); | 1331 DEBUG_ENT("write_vcard"); |
1332 | |
1333 // make everything utf8 | |
1334 pst_convert_utf8_null(item, &contact->fullname); | |
1335 pst_convert_utf8_null(item, &contact->surname); | |
1336 pst_convert_utf8_null(item, &contact->first_name); | |
1337 pst_convert_utf8_null(item, &contact->middle_name); | |
1338 pst_convert_utf8_null(item, &contact->display_name_prefix); | |
1339 pst_convert_utf8_null(item, &contact->suffix); | |
1340 pst_convert_utf8_null(item, &contact->nickname); | |
1341 pst_convert_utf8_null(item, &contact->address1); | |
1342 pst_convert_utf8_null(item, &contact->address2); | |
1343 pst_convert_utf8_null(item, &contact->address3); | |
1344 pst_convert_utf8_null(item, &contact->home_po_box); | |
1345 pst_convert_utf8_null(item, &contact->home_street); | |
1346 pst_convert_utf8_null(item, &contact->home_city); | |
1347 pst_convert_utf8_null(item, &contact->home_state); | |
1348 pst_convert_utf8_null(item, &contact->home_postal_code); | |
1349 pst_convert_utf8_null(item, &contact->home_country); | |
1350 pst_convert_utf8_null(item, &contact->home_address); | |
1351 pst_convert_utf8_null(item, &contact->business_po_box); | |
1352 pst_convert_utf8_null(item, &contact->business_street); | |
1353 pst_convert_utf8_null(item, &contact->business_city); | |
1354 pst_convert_utf8_null(item, &contact->business_state); | |
1355 pst_convert_utf8_null(item, &contact->business_postal_code); | |
1356 pst_convert_utf8_null(item, &contact->business_country); | |
1357 pst_convert_utf8_null(item, &contact->business_address); | |
1358 pst_convert_utf8_null(item, &contact->other_po_box); | |
1359 pst_convert_utf8_null(item, &contact->other_street); | |
1360 pst_convert_utf8_null(item, &contact->other_city); | |
1361 pst_convert_utf8_null(item, &contact->other_state); | |
1362 pst_convert_utf8_null(item, &contact->other_postal_code); | |
1363 pst_convert_utf8_null(item, &contact->other_country); | |
1364 pst_convert_utf8_null(item, &contact->other_address); | |
1365 pst_convert_utf8_null(item, &contact->business_fax); | |
1366 pst_convert_utf8_null(item, &contact->business_phone); | |
1367 pst_convert_utf8_null(item, &contact->business_phone2); | |
1368 pst_convert_utf8_null(item, &contact->car_phone); | |
1369 pst_convert_utf8_null(item, &contact->home_fax); | |
1370 pst_convert_utf8_null(item, &contact->home_phone); | |
1371 pst_convert_utf8_null(item, &contact->home_phone2); | |
1372 pst_convert_utf8_null(item, &contact->isdn_phone); | |
1373 pst_convert_utf8_null(item, &contact->mobile_phone); | |
1374 pst_convert_utf8_null(item, &contact->other_phone); | |
1375 pst_convert_utf8_null(item, &contact->pager_phone); | |
1376 pst_convert_utf8_null(item, &contact->primary_fax); | |
1377 pst_convert_utf8_null(item, &contact->primary_phone); | |
1378 pst_convert_utf8_null(item, &contact->radio_phone); | |
1379 pst_convert_utf8_null(item, &contact->telex); | |
1380 pst_convert_utf8_null(item, &contact->job_title); | |
1381 pst_convert_utf8_null(item, &contact->profession); | |
1382 pst_convert_utf8_null(item, &contact->assistant_name); | |
1383 pst_convert_utf8_null(item, &contact->assistant_phone); | |
1384 pst_convert_utf8_null(item, &contact->company_name); | |
1385 | |
1344 // the specification I am following is (hopefully) RFC2426 vCard Mime Directory Profile | 1386 // the specification I am following is (hopefully) RFC2426 vCard Mime Directory Profile |
1345 fprintf(f_output, "BEGIN:VCARD\n"); | 1387 fprintf(f_output, "BEGIN:VCARD\n"); |
1346 fprintf(f_output, "FN:%s\n", pst_rfc2426_escape(contact->fullname)); | 1388 fprintf(f_output, "FN:%s\n", pst_rfc2426_escape(contact->fullname.str)); |
1347 | 1389 |
1348 //fprintf(f_output, "N:%s;%s;%s;%s;%s\n", | 1390 //fprintf(f_output, "N:%s;%s;%s;%s;%s\n", |
1349 fprintf(f_output, "N:%s;", (!contact->surname) ? "" : pst_rfc2426_escape(contact->surname)); | 1391 fprintf(f_output, "N:%s;", (!contact->surname.str) ? "" : pst_rfc2426_escape(contact->surname.str)); |
1350 fprintf(f_output, "%s;", (!contact->first_name) ? "" : pst_rfc2426_escape(contact->first_name)); | 1392 fprintf(f_output, "%s;", (!contact->first_name.str) ? "" : pst_rfc2426_escape(contact->first_name.str)); |
1351 fprintf(f_output, "%s;", (!contact->middle_name) ? "" : pst_rfc2426_escape(contact->middle_name)); | 1393 fprintf(f_output, "%s;", (!contact->middle_name.str) ? "" : pst_rfc2426_escape(contact->middle_name.str)); |
1352 fprintf(f_output, "%s;", (!contact->display_name_prefix) ? "" : pst_rfc2426_escape(contact->display_name_prefix)); | 1394 fprintf(f_output, "%s;", (!contact->display_name_prefix.str) ? "" : pst_rfc2426_escape(contact->display_name_prefix.str)); |
1353 fprintf(f_output, "%s\n", (!contact->suffix) ? "" : pst_rfc2426_escape(contact->suffix)); | 1395 fprintf(f_output, "%s\n", (!contact->suffix.str) ? "" : pst_rfc2426_escape(contact->suffix.str)); |
1354 | 1396 |
1355 if (contact->nickname) | 1397 if (contact->nickname.str) |
1356 fprintf(f_output, "NICKNAME:%s\n", pst_rfc2426_escape(contact->nickname)); | 1398 fprintf(f_output, "NICKNAME:%s\n", pst_rfc2426_escape(contact->nickname.str)); |
1357 if (contact->address1) | 1399 if (contact->address1.str) |
1358 fprintf(f_output, "EMAIL:%s\n", pst_rfc2426_escape(contact->address1)); | 1400 fprintf(f_output, "EMAIL:%s\n", pst_rfc2426_escape(contact->address1.str)); |
1359 if (contact->address2) | 1401 if (contact->address2.str) |
1360 fprintf(f_output, "EMAIL:%s\n", pst_rfc2426_escape(contact->address2)); | 1402 fprintf(f_output, "EMAIL:%s\n", pst_rfc2426_escape(contact->address2.str)); |
1361 if (contact->address3) | 1403 if (contact->address3.str) |
1362 fprintf(f_output, "EMAIL:%s\n", pst_rfc2426_escape(contact->address3)); | 1404 fprintf(f_output, "EMAIL:%s\n", pst_rfc2426_escape(contact->address3.str)); |
1363 if (contact->birthday) | 1405 if (contact->birthday) |
1364 fprintf(f_output, "BDAY:%s\n", pst_rfc2425_datetime_format(contact->birthday)); | 1406 fprintf(f_output, "BDAY:%s\n", pst_rfc2425_datetime_format(contact->birthday)); |
1365 | 1407 |
1366 if (contact->home_address) { | 1408 if (contact->home_address.str) { |
1367 //fprintf(f_output, "ADR;TYPE=home:%s;%s;%s;%s;%s;%s;%s\n", | 1409 //fprintf(f_output, "ADR;TYPE=home:%s;%s;%s;%s;%s;%s;%s\n", |
1368 fprintf(f_output, "ADR;TYPE=home:%s;", (!contact->home_po_box) ? "" : pst_rfc2426_escape(contact->home_po_box)); | 1410 fprintf(f_output, "ADR;TYPE=home:%s;", (!contact->home_po_box.str) ? "" : pst_rfc2426_escape(contact->home_po_box.str)); |
1369 fprintf(f_output, "%s;", ""); // extended Address | 1411 fprintf(f_output, "%s;", ""); // extended Address |
1370 fprintf(f_output, "%s;", (!contact->home_street) ? "" : pst_rfc2426_escape(contact->home_street)); | 1412 fprintf(f_output, "%s;", (!contact->home_street.str) ? "" : pst_rfc2426_escape(contact->home_street.str)); |
1371 fprintf(f_output, "%s;", (!contact->home_city) ? "" : pst_rfc2426_escape(contact->home_city)); | 1413 fprintf(f_output, "%s;", (!contact->home_city.str) ? "" : pst_rfc2426_escape(contact->home_city.str)); |
1372 fprintf(f_output, "%s;", (!contact->home_state) ? "" : pst_rfc2426_escape(contact->home_state)); | 1414 fprintf(f_output, "%s;", (!contact->home_state.str) ? "" : pst_rfc2426_escape(contact->home_state.str)); |
1373 fprintf(f_output, "%s;", (!contact->home_postal_code) ? "" : pst_rfc2426_escape(contact->home_postal_code)); | 1415 fprintf(f_output, "%s;", (!contact->home_postal_code.str) ? "" : pst_rfc2426_escape(contact->home_postal_code.str)); |
1374 fprintf(f_output, "%s\n", (!contact->home_country) ? "" : pst_rfc2426_escape(contact->home_country)); | 1416 fprintf(f_output, "%s\n", (!contact->home_country.str) ? "" : pst_rfc2426_escape(contact->home_country.str)); |
1375 fprintf(f_output, "LABEL;TYPE=home:%s\n", pst_rfc2426_escape(contact->home_address)); | 1417 fprintf(f_output, "LABEL;TYPE=home:%s\n", pst_rfc2426_escape(contact->home_address.str)); |
1376 } | 1418 } |
1377 | 1419 |
1378 if (contact->business_address) { | 1420 if (contact->business_address.str) { |
1379 //fprintf(f_output, "ADR;TYPE=work:%s;%s;%s;%s;%s;%s;%s\n", | 1421 //fprintf(f_output, "ADR;TYPE=work:%s;%s;%s;%s;%s;%s;%s\n", |
1380 fprintf(f_output, "ADR;TYPE=work:%s;", (!contact->business_po_box) ? "" : pst_rfc2426_escape(contact->business_po_box)); | 1422 fprintf(f_output, "ADR;TYPE=work:%s;", (!contact->business_po_box.str) ? "" : pst_rfc2426_escape(contact->business_po_box.str)); |
1381 fprintf(f_output, "%s;", ""); // extended Address | 1423 fprintf(f_output, "%s;", ""); // extended Address |
1382 fprintf(f_output, "%s;", (!contact->business_street) ? "" : pst_rfc2426_escape(contact->business_street)); | 1424 fprintf(f_output, "%s;", (!contact->business_street.str) ? "" : pst_rfc2426_escape(contact->business_street.str)); |
1383 fprintf(f_output, "%s;", (!contact->business_city) ? "" : pst_rfc2426_escape(contact->business_city)); | 1425 fprintf(f_output, "%s;", (!contact->business_city.str) ? "" : pst_rfc2426_escape(contact->business_city.str)); |
1384 fprintf(f_output, "%s;", (!contact->business_state) ? "" : pst_rfc2426_escape(contact->business_state)); | 1426 fprintf(f_output, "%s;", (!contact->business_state.str) ? "" : pst_rfc2426_escape(contact->business_state.str)); |
1385 fprintf(f_output, "%s;", (!contact->business_postal_code) ? "" : pst_rfc2426_escape(contact->business_postal_code)); | 1427 fprintf(f_output, "%s;", (!contact->business_postal_code.str) ? "" : pst_rfc2426_escape(contact->business_postal_code.str)); |
1386 fprintf(f_output, "%s\n", (!contact->business_country) ? "" : pst_rfc2426_escape(contact->business_country)); | 1428 fprintf(f_output, "%s\n", (!contact->business_country.str) ? "" : pst_rfc2426_escape(contact->business_country.str)); |
1387 fprintf(f_output, "LABEL;TYPE=work:%s\n", pst_rfc2426_escape(contact->business_address)); | 1429 fprintf(f_output, "LABEL;TYPE=work:%s\n", pst_rfc2426_escape(contact->business_address.str)); |
1388 } | 1430 } |
1389 | 1431 |
1390 if (contact->other_address) { | 1432 if (contact->other_address.str) { |
1391 //fprintf(f_output, "ADR;TYPE=postal:%s;%s;%s;%s;%s;%s;%s\n", | 1433 //fprintf(f_output, "ADR;TYPE=postal:%s;%s;%s;%s;%s;%s;%s\n", |
1392 fprintf(f_output, "ADR;TYPE=postal:%s;",(!contact->other_po_box) ? "" : pst_rfc2426_escape(contact->other_po_box)); | 1434 fprintf(f_output, "ADR;TYPE=postal:%s;",(!contact->other_po_box.str) ? "" : pst_rfc2426_escape(contact->other_po_box.str)); |
1393 fprintf(f_output, "%s;", ""); // extended Address | 1435 fprintf(f_output, "%s;", ""); // extended Address |
1394 fprintf(f_output, "%s;", (!contact->other_street) ? "" : pst_rfc2426_escape(contact->other_street)); | 1436 fprintf(f_output, "%s;", (!contact->other_street.str) ? "" : pst_rfc2426_escape(contact->other_street.str)); |
1395 fprintf(f_output, "%s;", (!contact->other_city) ? "" : pst_rfc2426_escape(contact->other_city)); | 1437 fprintf(f_output, "%s;", (!contact->other_city.str) ? "" : pst_rfc2426_escape(contact->other_city.str)); |
1396 fprintf(f_output, "%s;", (!contact->other_state) ? "" : pst_rfc2426_escape(contact->other_state)); | 1438 fprintf(f_output, "%s;", (!contact->other_state.str) ? "" : pst_rfc2426_escape(contact->other_state.str)); |
1397 fprintf(f_output, "%s;", (!contact->other_postal_code) ? "" : pst_rfc2426_escape(contact->other_postal_code)); | 1439 fprintf(f_output, "%s;", (!contact->other_postal_code.str) ? "" : pst_rfc2426_escape(contact->other_postal_code.str)); |
1398 fprintf(f_output, "%s\n", (!contact->other_country) ? "" : pst_rfc2426_escape(contact->other_country)); | 1440 fprintf(f_output, "%s\n", (!contact->other_country.str) ? "" : pst_rfc2426_escape(contact->other_country.str)); |
1399 fprintf(f_output, "LABEL;TYPE=postal:%s\n", pst_rfc2426_escape(contact->other_address)); | 1441 fprintf(f_output, "LABEL;TYPE=postal:%s\n", pst_rfc2426_escape(contact->other_address.str)); |
1400 } | 1442 } |
1401 | 1443 |
1402 if (contact->business_fax) fprintf(f_output, "TEL;TYPE=work,fax:%s\n", pst_rfc2426_escape(contact->business_fax)); | 1444 if (contact->business_fax.str) fprintf(f_output, "TEL;TYPE=work,fax:%s\n", pst_rfc2426_escape(contact->business_fax.str)); |
1403 if (contact->business_phone) fprintf(f_output, "TEL;TYPE=work,voice:%s\n", pst_rfc2426_escape(contact->business_phone)); | 1445 if (contact->business_phone.str) fprintf(f_output, "TEL;TYPE=work,voice:%s\n", pst_rfc2426_escape(contact->business_phone.str)); |
1404 if (contact->business_phone2) fprintf(f_output, "TEL;TYPE=work,voice:%s\n", pst_rfc2426_escape(contact->business_phone2)); | 1446 if (contact->business_phone2.str) fprintf(f_output, "TEL;TYPE=work,voice:%s\n", pst_rfc2426_escape(contact->business_phone2.str)); |
1405 if (contact->car_phone) fprintf(f_output, "TEL;TYPE=car,voice:%s\n", pst_rfc2426_escape(contact->car_phone)); | 1447 if (contact->car_phone.str) fprintf(f_output, "TEL;TYPE=car,voice:%s\n", pst_rfc2426_escape(contact->car_phone.str)); |
1406 if (contact->home_fax) fprintf(f_output, "TEL;TYPE=home,fax:%s\n", pst_rfc2426_escape(contact->home_fax)); | 1448 if (contact->home_fax.str) fprintf(f_output, "TEL;TYPE=home,fax:%s\n", pst_rfc2426_escape(contact->home_fax.str)); |
1407 if (contact->home_phone) fprintf(f_output, "TEL;TYPE=home,voice:%s\n", pst_rfc2426_escape(contact->home_phone)); | 1449 if (contact->home_phone.str) fprintf(f_output, "TEL;TYPE=home,voice:%s\n", pst_rfc2426_escape(contact->home_phone.str)); |
1408 if (contact->home_phone2) fprintf(f_output, "TEL;TYPE=home,voice:%s\n", pst_rfc2426_escape(contact->home_phone2)); | 1450 if (contact->home_phone2.str) fprintf(f_output, "TEL;TYPE=home,voice:%s\n", pst_rfc2426_escape(contact->home_phone2.str)); |
1409 if (contact->isdn_phone) fprintf(f_output, "TEL;TYPE=isdn:%s\n", pst_rfc2426_escape(contact->isdn_phone)); | 1451 if (contact->isdn_phone.str) fprintf(f_output, "TEL;TYPE=isdn:%s\n", pst_rfc2426_escape(contact->isdn_phone.str)); |
1410 if (contact->mobile_phone) fprintf(f_output, "TEL;TYPE=cell,voice:%s\n", pst_rfc2426_escape(contact->mobile_phone)); | 1452 if (contact->mobile_phone.str) fprintf(f_output, "TEL;TYPE=cell,voice:%s\n", pst_rfc2426_escape(contact->mobile_phone.str)); |
1411 if (contact->other_phone) fprintf(f_output, "TEL;TYPE=msg:%s\n", pst_rfc2426_escape(contact->other_phone)); | 1453 if (contact->other_phone.str) fprintf(f_output, "TEL;TYPE=msg:%s\n", pst_rfc2426_escape(contact->other_phone.str)); |
1412 if (contact->pager_phone) fprintf(f_output, "TEL;TYPE=pager:%s\n", pst_rfc2426_escape(contact->pager_phone)); | 1454 if (contact->pager_phone.str) fprintf(f_output, "TEL;TYPE=pager:%s\n", pst_rfc2426_escape(contact->pager_phone.str)); |
1413 if (contact->primary_fax) fprintf(f_output, "TEL;TYPE=fax,pref:%s\n", pst_rfc2426_escape(contact->primary_fax)); | 1455 if (contact->primary_fax.str) fprintf(f_output, "TEL;TYPE=fax,pref:%s\n", pst_rfc2426_escape(contact->primary_fax.str)); |
1414 if (contact->primary_phone) fprintf(f_output, "TEL;TYPE=phone,pref:%s\n", pst_rfc2426_escape(contact->primary_phone)); | 1456 if (contact->primary_phone.str) fprintf(f_output, "TEL;TYPE=phone,pref:%s\n", pst_rfc2426_escape(contact->primary_phone.str)); |
1415 if (contact->radio_phone) fprintf(f_output, "TEL;TYPE=pcs:%s\n", pst_rfc2426_escape(contact->radio_phone)); | 1457 if (contact->radio_phone.str) fprintf(f_output, "TEL;TYPE=pcs:%s\n", pst_rfc2426_escape(contact->radio_phone.str)); |
1416 if (contact->telex) fprintf(f_output, "TEL;TYPE=bbs:%s\n", pst_rfc2426_escape(contact->telex)); | 1458 if (contact->telex.str) fprintf(f_output, "TEL;TYPE=bbs:%s\n", pst_rfc2426_escape(contact->telex.str)); |
1417 if (contact->job_title) fprintf(f_output, "TITLE:%s\n", pst_rfc2426_escape(contact->job_title)); | 1459 if (contact->job_title.str) fprintf(f_output, "TITLE:%s\n", pst_rfc2426_escape(contact->job_title.str)); |
1418 if (contact->profession) fprintf(f_output, "ROLE:%s\n", pst_rfc2426_escape(contact->profession)); | 1460 if (contact->profession.str) fprintf(f_output, "ROLE:%s\n", pst_rfc2426_escape(contact->profession.str)); |
1419 if (contact->assistant_name || contact->assistant_phone) { | 1461 if (contact->assistant_name.str || contact->assistant_phone.str) { |
1420 fprintf(f_output, "AGENT:BEGIN:VCARD\n"); | 1462 fprintf(f_output, "AGENT:BEGIN:VCARD\n"); |
1421 if (contact->assistant_name) fprintf(f_output, "FN:%s\n", pst_rfc2426_escape(contact->assistant_name)); | 1463 if (contact->assistant_name.str) fprintf(f_output, "FN:%s\n", pst_rfc2426_escape(contact->assistant_name.str)); |
1422 if (contact->assistant_phone) fprintf(f_output, "TEL:%s\n", pst_rfc2426_escape(contact->assistant_phone)); | 1464 if (contact->assistant_phone.str) fprintf(f_output, "TEL:%s\n", pst_rfc2426_escape(contact->assistant_phone.str)); |
1423 } | 1465 } |
1424 if (contact->company_name) fprintf(f_output, "ORG:%s\n", pst_rfc2426_escape(contact->company_name)); | 1466 if (contact->company_name.str) fprintf(f_output, "ORG:%s\n", pst_rfc2426_escape(contact->company_name.str)); |
1425 if (comment) fprintf(f_output, "NOTE:%s\n", pst_rfc2426_escape(comment)); | 1467 if (comment) fprintf(f_output, "NOTE:%s\n", pst_rfc2426_escape(comment)); |
1426 | 1468 |
1427 fprintf(f_output, "VERSION: 3.0\n"); | 1469 fprintf(f_output, "VERSION: 3.0\n"); |
1428 fprintf(f_output, "END:VCARD\n\n"); | 1470 fprintf(f_output, "END:VCARD\n\n"); |
1429 DEBUG_RET(); | 1471 DEBUG_RET(); |
1430 } | 1472 } |
1431 | 1473 |
1432 | 1474 |
1433 void write_appointment(FILE* f_output, pst_item_appointment* appointment, | 1475 void write_appointment(FILE* f_output, pst_item *item, pst_item_appointment* appointment, |
1434 pst_item_email* email, FILETIME* create_date, FILETIME* modify_date) | 1476 FILETIME* create_date, FILETIME* modify_date) |
1435 { | 1477 { |
1478 // make everything utf8 | |
1479 pst_convert_utf8_null(item, &item->subject); | |
1480 pst_convert_utf8_null(item, &item->body); | |
1481 pst_convert_utf8_null(item, &appointment->location); | |
1482 | |
1436 fprintf(f_output, "BEGIN:VEVENT\n"); | 1483 fprintf(f_output, "BEGIN:VEVENT\n"); |
1437 if (create_date) | 1484 if (create_date) |
1438 fprintf(f_output, "CREATED:%s\n", | 1485 fprintf(f_output, "CREATED:%s\n", pst_rfc2445_datetime_format(create_date)); |
1439 pst_rfc2445_datetime_format(create_date)); | |
1440 if (modify_date) | 1486 if (modify_date) |
1441 fprintf(f_output, "LAST-MOD:%s\n", | 1487 fprintf(f_output, "LAST-MOD:%s\n", pst_rfc2445_datetime_format(modify_date)); |
1442 pst_rfc2445_datetime_format(modify_date)); | 1488 if (item->subject.str) |
1443 if (email && email->subject) | 1489 fprintf(f_output, "SUMMARY:%s\n", pst_rfc2426_escape(item->subject.str)); |
1444 fprintf(f_output, "SUMMARY:%s\n", | 1490 if (item->body.str) |
1445 pst_rfc2426_escape(email->subject->subj)); | 1491 fprintf(f_output, "DESCRIPTION:%s\n", pst_rfc2426_escape(item->body.str)); |
1446 if (email && email->body) | |
1447 fprintf(f_output, "DESCRIPTION:%s\n", | |
1448 pst_rfc2426_escape(email->body)); | |
1449 if (appointment && appointment->start) | 1492 if (appointment && appointment->start) |
1450 fprintf(f_output, "DTSTART;VALUE=DATE-TIME:%s\n", | 1493 fprintf(f_output, "DTSTART;VALUE=DATE-TIME:%s\n", pst_rfc2445_datetime_format(appointment->start)); |
1451 pst_rfc2445_datetime_format(appointment->start)); | |
1452 if (appointment && appointment->end) | 1494 if (appointment && appointment->end) |
1453 fprintf(f_output, "DTEND;VALUE=DATE-TIME:%s\n", | 1495 fprintf(f_output, "DTEND;VALUE=DATE-TIME:%s\n", pst_rfc2445_datetime_format(appointment->end)); |
1454 pst_rfc2445_datetime_format(appointment->end)); | 1496 if (appointment && appointment->location.str) |
1455 if (appointment && appointment->location) | 1497 fprintf(f_output, "LOCATION:%s\n", pst_rfc2426_escape(appointment->location.str)); |
1456 fprintf(f_output, "LOCATION:%s\n", | |
1457 pst_rfc2426_escape(appointment->location)); | |
1458 if (appointment) { | 1498 if (appointment) { |
1459 switch (appointment->showas) { | 1499 switch (appointment->showas) { |
1460 case PST_FREEBUSY_TENTATIVE: | 1500 case PST_FREEBUSY_TENTATIVE: |
1461 fprintf(f_output, "STATUS:TENTATIVE\n"); | 1501 fprintf(f_output, "STATUS:TENTATIVE\n"); |
1462 break; | 1502 break; |
1508 } | 1548 } |
1509 | 1549 |
1510 | 1550 |
1511 void create_enter_dir(struct file_ll* f, pst_item *item) | 1551 void create_enter_dir(struct file_ll* f, pst_item *item) |
1512 { | 1552 { |
1553 pst_convert_utf8(item, &item->file_as); | |
1513 f->email_count = 0; | 1554 f->email_count = 0; |
1514 f->skip_count = 0; | 1555 f->skip_count = 0; |
1515 f->type = item->type; | 1556 f->type = item->type; |
1516 f->stored_count = (item->folder) ? item->folder->email_count : 0; | 1557 f->stored_count = (item->folder) ? item->folder->email_count : 0; |
1517 | 1558 |
1518 DEBUG_ENT("create_enter_dir"); | 1559 DEBUG_ENT("create_enter_dir"); |
1519 if (mode == MODE_KMAIL) | 1560 if (mode == MODE_KMAIL) |
1520 f->name = mk_kmail_dir(item->file_as); //create directory and form filename | 1561 f->name = mk_kmail_dir(item->file_as.str); //create directory and form filename |
1521 else if (mode == MODE_RECURSE) | 1562 else if (mode == MODE_RECURSE) |
1522 f->name = mk_recurse_dir(item->file_as); | 1563 f->name = mk_recurse_dir(item->file_as.str); |
1523 else if (mode == MODE_SEPARATE) { | 1564 else if (mode == MODE_SEPARATE) { |
1524 // do similar stuff to recurse here. | 1565 // do similar stuff to recurse here. |
1525 mk_separate_dir(item->file_as); | 1566 mk_separate_dir(item->file_as.str); |
1526 f->name = (char*) xmalloc(10); | 1567 f->name = (char*) xmalloc(10); |
1527 memset(f->name, 0, 10); | 1568 memset(f->name, 0, 10); |
1528 // sprintf(f->name, SEP_MAIL_FILE_TEMPLATE, f->email_count); | 1569 // sprintf(f->name, SEP_MAIL_FILE_TEMPLATE, f->email_count); |
1529 } else { | 1570 } else { |
1530 f->name = (char*) xmalloc(strlen(item->file_as)+strlen(OUTPUT_TEMPLATE)+1); | 1571 f->name = (char*) xmalloc(strlen(item->file_as.str)+strlen(OUTPUT_TEMPLATE)+1); |
1531 sprintf(f->name, OUTPUT_TEMPLATE, item->file_as); | 1572 sprintf(f->name, OUTPUT_TEMPLATE, item->file_as.str); |
1532 } | 1573 } |
1533 | 1574 |
1534 f->dname = (char*) xmalloc(strlen(item->file_as)+1); | 1575 f->dname = (char*) xmalloc(strlen(item->file_as.str)+1); |
1535 strcpy(f->dname, item->file_as); | 1576 strcpy(f->dname, item->file_as.str); |
1536 | 1577 |
1537 if (overwrite != 1) { | 1578 if (overwrite != 1) { |
1538 int x = 0; | 1579 int x = 0; |
1539 char *temp = (char*) xmalloc (strlen(f->name)+10); //enough room for 10 digits | 1580 char *temp = (char*) xmalloc (strlen(f->name)+10); //enough room for 10 digits |
1540 | 1581 |
1557 } else { | 1598 } else { |
1558 free(temp); | 1599 free(temp); |
1559 } | 1600 } |
1560 } | 1601 } |
1561 | 1602 |
1562 DEBUG_MAIN(("f->name = %s\nitem->folder_name = %s\n", f->name, item->file_as)); | 1603 DEBUG_MAIN(("f->name = %s\nitem->folder_name = %s\n", f->name, item->file_as.str)); |
1563 if (mode != MODE_SEPARATE) { | 1604 if (mode != MODE_SEPARATE) { |
1564 check_filename(f->name); | 1605 check_filename(f->name); |
1565 if (!(f->output = fopen(f->name, "w"))) { | 1606 if (!(f->output = fopen(f->name, "w"))) { |
1566 DIE(("create_enter_dir: Could not open file \"%s\" for write\n", f->name)); | 1607 DIE(("create_enter_dir: Could not open file \"%s\" for write\n", f->name)); |
1567 } | 1608 } |