Mercurial > libpst
comparison src/readpst.c @ 100:1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Thu, 02 Oct 2008 15:29:36 -0700 |
parents | 56fa05fd5271 |
children | 39ba19372732 |
comparison
equal
deleted
inserted
replaced
99:b7f456946c5b | 100:1e4a7610d525 |
---|---|
89 | 89 |
90 // output mode for contacts | 90 // output mode for contacts |
91 #define CMODE_VCARD 0 | 91 #define CMODE_VCARD 0 |
92 #define CMODE_LIST 1 | 92 #define CMODE_LIST 1 |
93 | 93 |
94 // output mode for deleted items | |
95 #define DMODE_EXCLUDE 0 | |
96 #define DMODE_INCLUDE 1 | |
97 | |
94 // output settings for RTF bodies | 98 // output settings for RTF bodies |
95 // filename for the attachment | 99 // filename for the attachment |
96 #define RTF_ATTACH_NAME "rtf-body.rtf" | 100 #define RTF_ATTACH_NAME "rtf-body.rtf" |
97 // mime type for the attachment | 101 // mime type for the attachment |
98 #define RTF_ATTACH_TYPE "application/rtf" | 102 #define RTF_ATTACH_TYPE "application/rtf" |
100 // global settings | 104 // global settings |
101 int mode = MODE_NORMAL; | 105 int mode = MODE_NORMAL; |
102 int mode_MH = 0; | 106 int mode_MH = 0; |
103 int output_mode = OUTPUT_NORMAL; | 107 int output_mode = OUTPUT_NORMAL; |
104 int contact_mode = CMODE_VCARD; | 108 int contact_mode = CMODE_VCARD; |
109 int deleted_mode = DMODE_EXCLUDE; | |
105 int overwrite = 0; | 110 int overwrite = 0; |
106 int save_rtf_body = 1; | 111 int save_rtf_body = 1; |
107 pst_file pstfile; | 112 pst_file pstfile; |
108 | 113 |
109 | 114 |
131 if (item && item->email && item->email->subject && item->email->subject->subj) { | 136 if (item && item->email && item->email->subject && item->email->subject->subj) { |
132 DEBUG_EMAIL(("item->email->subject = %p\n", item->email->subject)); | 137 DEBUG_EMAIL(("item->email->subject = %p\n", item->email->subject)); |
133 DEBUG_EMAIL(("item->email->subject->subj = %p\n", item->email->subject->subj)); | 138 DEBUG_EMAIL(("item->email->subject->subj = %p\n", item->email->subject->subj)); |
134 } | 139 } |
135 if (item) { | 140 if (item) { |
136 if (item->folder && d_ptr->child && strcasecmp(item->file_as, "Deleted Items")) { | 141 if (item->folder && d_ptr->child && (deleted_mode == DMODE_INCLUDE || strcasecmp(item->file_as, "Deleted Items"))) { |
137 //if this is a non-empty folder other than deleted items, we want to recurse into it | 142 //if this is a non-empty folder other than deleted items, we want to recurse into it |
138 if (output_mode != OUTPUT_QUIET) printf("Processing Folder \"%s\"\n", item->file_as); | 143 if (output_mode != OUTPUT_QUIET) printf("Processing Folder \"%s\"\n", item->file_as); |
139 process(item, d_ptr->child); | 144 process(item, d_ptr->child); |
140 | 145 |
141 } else if (item->contact && (item->type == PST_TYPE_CONTACT)) { | 146 } else if (item->contact && (item->type == PST_TYPE_CONTACT)) { |
221 int c,x; | 226 int c,x; |
222 char *temp = NULL; //temporary char pointer | 227 char *temp = NULL; //temporary char pointer |
223 prog_name = argv[0]; | 228 prog_name = argv[0]; |
224 | 229 |
225 // command-line option handling | 230 // command-line option handling |
226 while ((c = getopt(argc, argv, "bCc:d:hko:qrSMVw"))!= -1) { | 231 while ((c = getopt(argc, argv, "bCc:Dd:hko:qrSMVw"))!= -1) { |
227 switch (c) { | 232 switch (c) { |
228 case 'b': | 233 case 'b': |
229 save_rtf_body = 0; | 234 save_rtf_body = 0; |
230 break; | 235 break; |
231 case 'C': | 236 case 'C': |
238 contact_mode=CMODE_LIST; | 243 contact_mode=CMODE_LIST; |
239 else { | 244 else { |
240 usage(); | 245 usage(); |
241 exit(0); | 246 exit(0); |
242 } | 247 } |
248 break; | |
249 case 'D': | |
250 deleted_mode = DMODE_INCLUDE; | |
243 break; | 251 break; |
244 case 'd': | 252 case 'd': |
245 d_log = optarg; | 253 d_log = optarg; |
246 break; | 254 break; |
247 case 'h': | 255 case 'h': |
411 DEBUG_ENT("usage"); | 419 DEBUG_ENT("usage"); |
412 version(); | 420 version(); |
413 printf("Usage: %s [OPTIONS] {PST FILENAME}\n", prog_name); | 421 printf("Usage: %s [OPTIONS] {PST FILENAME}\n", prog_name); |
414 printf("OPTIONS:\n"); | 422 printf("OPTIONS:\n"); |
415 printf("\t-C\t- Decrypt (compressible encryption) the entire file and output on stdout (not typically useful)\n"); | 423 printf("\t-C\t- Decrypt (compressible encryption) the entire file and output on stdout (not typically useful)\n"); |
424 printf("\t-D\t- Include deleted items in output\n"); | |
416 printf("\t-M\t- MH. Write emails in the MH format\n"); | 425 printf("\t-M\t- MH. Write emails in the MH format\n"); |
417 printf("\t-S\t- Separate. Write emails in the separate format\n"); | 426 printf("\t-S\t- Separate. Write emails in the separate format\n"); |
418 printf("\t-V\t- Version. Display program version\n"); | 427 printf("\t-V\t- Version. Display program version\n"); |
419 printf("\t-b\t- Don't save RTF-Body attachments\n"); | 428 printf("\t-b\t- Don't save RTF-Body attachments\n"); |
420 printf("\t-c[v|l]\t- Set the Contact output mode. -cv = VCard, -cl = EMail list\n"); | 429 printf("\t-c[v|l]\t- Set the Contact output mode. -cv = VCard, -cl = EMail list\n"); |
651 z = NULL; // reset the haystack storage point | 660 z = NULL; // reset the haystack storage point |
652 } | 661 } |
653 x++; // advance the search in the haystack | 662 x++; // advance the search in the haystack |
654 } | 663 } |
655 DEBUG_RET(); | 664 DEBUG_RET(); |
665 // If the haystack ended before our search finished, it's not a match. | |
666 if (*y != '\0') return NULL; | |
656 return z; | 667 return z; |
657 } | 668 } |
658 | 669 |
659 | 670 |
660 void check_filename(char *fname) { | 671 void check_filename(char *fname) { |
788 char *temp = NULL; | 799 char *temp = NULL; |
789 int attach_num, base64_body = 0; | 800 int attach_num, base64_body = 0; |
790 time_t em_time; | 801 time_t em_time; |
791 char *c_time; | 802 char *c_time; |
792 pst_item_attach* current_attach; | 803 pst_item_attach* current_attach; |
804 int has_from, has_subject, has_to, has_cc, has_bcc, has_date; | |
805 has_from = has_subject = has_to = has_cc = has_bcc = has_date = 0; | |
793 DEBUG_ENT("write_normal_email"); | 806 DEBUG_ENT("write_normal_email"); |
794 | 807 |
795 // convert the sent date if it exists, or set it to a fixed date | 808 // convert the sent date if it exists, or set it to a fixed date |
796 if (item->email->sent_date) { | 809 if (item->email->sent_date) { |
797 em_time = fileTimeToUnixTime(item->email->sent_date, 0); | 810 em_time = fileTimeToUnixTime(item->email->sent_date, 0); |
858 } | 871 } |
859 } else { | 872 } else { |
860 DEBUG_WARN(("found a ':' during the my_stristr, but not after that..\n")); | 873 DEBUG_WARN(("found a ':' during the my_stristr, but not after that..\n")); |
861 } | 874 } |
862 } | 875 } |
876 | |
877 // Check if the header block has all the necessary headers. | |
878 if (my_stristr(item->email->header, "\nFrom:") || (strncasecmp(item->email->header, "From: ", 6) == 0) || my_stristr(item->email->header, "\nX-From:")) { | |
879 DEBUG_EMAIL(("header block has From header\n")); | |
880 has_from = 1; | |
881 } | |
882 if (my_stristr(item->email->header, "\nTo:") || (strncasecmp(item->email->header, "To: ", 4) == 0)) { | |
883 DEBUG_EMAIL(("header block has To header\n")); | |
884 has_to = 1; | |
885 } | |
886 if (my_stristr(item->email->header, "\nSubject:") || (strncasecmp(item->email->header, "Subject: ", 9) == 0)) { | |
887 DEBUG_EMAIL(("header block has Subject header\n")); | |
888 has_subject = 1; | |
889 } | |
890 if (my_stristr(item->email->header, "\nDate:") || (strncasecmp(item->email->header, "Date: ", 6) == 0)) { | |
891 DEBUG_EMAIL(("header block has Date header\n")); | |
892 has_date = 1; | |
893 } | |
894 if (my_stristr(item->email->header, "\nCC:") || (strncasecmp(item->email->header, "CC: ", 4) == 0)) { | |
895 DEBUG_EMAIL(("header block has CC header\n")); | |
896 has_cc = 1; | |
897 } | |
898 if (my_stristr(item->email->header, "\nBCC:") || (strncasecmp(item->email->header, "BCC: ", 5) == 0)) { | |
899 DEBUG_EMAIL(("header block has BCC header\n")); | |
900 has_bcc = 1; | |
901 } | |
863 } | 902 } |
864 | 903 |
865 if (!boundary && (item->attach || (item->email->body && item->email->htmlbody) | 904 if (!boundary && (item->attach || (item->email->body && item->email->htmlbody) |
866 || item->email->rtf_compressed || item->email->encrypted_body | 905 || item->email->rtf_compressed || item->email->encrypted_body |
867 || item->email->encrypted_htmlbody)) { | 906 || item->email->encrypted_htmlbody)) { |
868 // we need to create a boundary here. | 907 // we need to create a boundary here. |
869 DEBUG_EMAIL(("must create own boundary. oh dear.\n")); | 908 DEBUG_EMAIL(("must create own boundary. oh dear.\n")); |
870 boundary = malloc(50 * sizeof(char)); // allow 50 chars for boundary | 909 boundary = malloc(50 * sizeof(char)); // allow 50 chars for boundary |
871 boundary[0] = '\0'; | 910 boundary[0] = '\0'; |
872 sprintf(boundary, "--boundary-LibPST-iamunique-%i_-_-", rand()); | 911 sprintf(boundary, "--boundary-LibPST-iamunique-%i_-_-", rand()); |
873 DEBUG_EMAIL(("created boundary is %s\n", boundary)); | 912 DEBUG_EMAIL(("created boundary is %s\n", boundary)); |
874 boundary_created = 1; | 913 boundary_created = 1; |
875 } | 914 } |
876 | 915 |
877 DEBUG_EMAIL(("About to print Header\n")); | 916 DEBUG_EMAIL(("About to print Header\n")); |
878 | 917 |
879 if (item && item->email && item->email->subject && item->email->subject->subj) { | 918 if (item && item->email && item->email->subject && item->email->subject->subj) { |
891 temp = strstr(item->email->header, "\n\n"); | 930 temp = strstr(item->email->header, "\n\n"); |
892 | 931 |
893 if (temp) { | 932 if (temp) { |
894 DEBUG_EMAIL(("Found body text in header\n")); | 933 DEBUG_EMAIL(("Found body text in header\n")); |
895 temp[1] = '\0'; // stop after first \n | 934 temp[1] = '\0'; // stop after first \n |
935 } | |
936 | |
937 // Write out any fields that weren't included in the header. | |
938 if (!has_from) { | |
939 temp = item->email->outlook_sender; | |
940 if (!temp) temp = ""; | |
941 fprintf(f_output, "From: \"%s\" <%s>\n", item->email->outlook_sender_name, temp); | |
942 } | |
943 | |
944 if (!has_subject) { | |
945 if (item->email->subject && item->email->subject->subj) { | |
946 fprintf(f_output, "Subject: %s\n", item->email->subject->subj); | |
947 } else { | |
948 fprintf(f_output, "Subject: \n"); | |
949 } | |
950 } | |
951 | |
952 if (!has_to && item->email->sentto_address) { | |
953 fprintf(f_output, "To: %s\n", item->email->sentto_address); | |
954 } | |
955 | |
956 if (!has_cc && item->email->cc_address) { | |
957 fprintf(f_output, "Cc: %s\n", item->email->cc_address); | |
958 } | |
959 | |
960 if (!has_bcc && item->email->bcc_address) { | |
961 fprintf(f_output, "Bcc: %s\n", item->email->bcc_address); | |
962 } | |
963 | |
964 if (!has_date && item->email->sent_date) { | |
965 char c_time[C_TIME_SIZE]; | |
966 strftime(c_time, C_TIME_SIZE, "%a, %d %b %Y %H:%M:%S %z", gmtime(&em_time)); | |
967 fprintf(f_output, "Date: %s\n", c_time); | |
896 } | 968 } |
897 | 969 |
898 // Now, write out the header... | 970 // Now, write out the header... |
899 soh = skip_header_prologue(item->email->header); | 971 soh = skip_header_prologue(item->email->header); |
900 if (mode != MODE_SEPARATE) { | 972 if (mode != MODE_SEPARATE) { |
923 | 995 |
924 temp = item->email->outlook_sender; | 996 temp = item->email->outlook_sender; |
925 if (!temp) temp = ""; | 997 if (!temp) temp = ""; |
926 fprintf(f_output, "From: \"%s\" <%s>\n", item->email->outlook_sender_name, temp); | 998 fprintf(f_output, "From: \"%s\" <%s>\n", item->email->outlook_sender_name, temp); |
927 | 999 |
928 if (item->email->subject) { | 1000 if (item->email->subject && item->email->subject->subj) { |
929 fprintf(f_output, "Subject: %s\n", item->email->subject->subj); | 1001 fprintf(f_output, "Subject: %s\n", item->email->subject->subj); |
930 } else { | 1002 } else { |
931 fprintf(f_output, "Subject: \n"); | 1003 fprintf(f_output, "Subject: \n"); |
932 } | 1004 } |
933 | 1005 |
934 fprintf(f_output, "To: %s\n", item->email->sentto_address); | 1006 if (item->email->sentto_address) { |
1007 fprintf(f_output, "To: %s\n", item->email->sentto_address); | |
1008 } | |
1009 | |
935 if (item->email->cc_address) { | 1010 if (item->email->cc_address) { |
936 fprintf(f_output, "Cc: %s\n", item->email->cc_address); | 1011 fprintf(f_output, "Cc: %s\n", item->email->cc_address); |
937 } | 1012 } |
938 | 1013 |
939 if (item->email->sent_date) { | 1014 if (item->email->sent_date) { |