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 }