comparison src/readpst.c @ 328:c507af52515a

add readpst -a option
author Carl Byington <carl@five-ten-sg.com>
date Wed, 12 Jun 2013 19:45:44 -0700
parents 2474d01043cd
children aedcf979f439
comparison
equal deleted inserted replaced
327:e1b9f9aa5074 328:c507af52515a
42 int close_separate_dir(); 42 int close_separate_dir();
43 void mk_separate_file(struct file_ll *f, char *extension, int openit); 43 void mk_separate_file(struct file_ll *f, char *extension, int openit);
44 void close_separate_file(struct file_ll *f); 44 void close_separate_file(struct file_ll *f);
45 char* my_stristr(char *haystack, char *needle); 45 char* my_stristr(char *haystack, char *needle);
46 void check_filename(char *fname); 46 void check_filename(char *fname);
47 int acceptable_ext(pst_item_attach* attach);
47 void write_separate_attachment(char f_name[], pst_item_attach* attach, int attach_num, pst_file* pst); 48 void write_separate_attachment(char f_name[], pst_item_attach* attach, int attach_num, pst_file* pst);
48 void write_embedded_message(FILE* f_output, pst_item_attach* attach, char *boundary, pst_file* pf, int save_rtf, char** extra_mime_headers); 49 void write_embedded_message(FILE* f_output, pst_item_attach* attach, char *boundary, pst_file* pf, int save_rtf, char** extra_mime_headers);
49 void write_inline_attachment(FILE* f_output, pst_item_attach* attach, char *boundary, pst_file* pst); 50 void write_inline_attachment(FILE* f_output, pst_item_attach* attach, char *boundary, pst_file* pst);
50 int valid_headers(char *header); 51 int valid_headers(char *header);
51 void header_has_field(char *header, char *field, int *flag); 52 void header_has_field(char *header, char *field, int *flag);
134 int save_rtf_body = 1; 135 int save_rtf_body = 1;
135 int file_name_len = 10; // enough room for MODE_SPEARATE file name 136 int file_name_len = 10; // enough room for MODE_SPEARATE file name
136 pst_file pstfile; 137 pst_file pstfile;
137 regex_t meta_charset_pattern; 138 regex_t meta_charset_pattern;
138 char* default_charset = NULL; 139 char* default_charset = NULL;
140 char* acceptable_extensions = NULL;
139 141
140 int number_processors = 1; // number of cpus we have 142 int number_processors = 1; // number of cpus we have
141 int max_children = 0; // based on number of cpus and command line args 143 int max_children = 0; // based on number of cpus and command line args
142 int max_child_specified = 0;// have command line arg -j 144 int max_child_specified = 0;// have command line arg -j
143 int active_children; // number of children of this process, cannot be larger than max_children 145 int active_children; // number of children of this process, cannot be larger than max_children
448 printf("cannot compile regex pattern to find content charset in html bodies\n"); 450 printf("cannot compile regex pattern to find content charset in html bodies\n");
449 exit(3); 451 exit(3);
450 } 452 }
451 453
452 // command-line option handling 454 // command-line option handling
453 while ((c = getopt(argc, argv, "bC:c:Dd:emhj:kMo:qrSt:uVw"))!= -1) { 455 while ((c = getopt(argc, argv, "a:bC:c:Dd:emhj:kMo:qrSt:uVw"))!= -1) {
454 switch (c) { 456 switch (c) {
457 case 'a':
458 if (optarg) {
459 int n = strlen(optarg);
460 acceptable_extensions = (char*)pst_malloc(n+2);
461 strcpy(acceptable_extensions, optarg);
462 acceptable_extensions[n+1] = '\0'; // double null terminates array of non-empty null terminated strings.
463 char *p = acceptable_extensions;
464 while (*p) {
465 if (*p == ',') *p = '\0';
466 p++;
467 }
468 }
469 break;
455 case 'b': 470 case 'b':
456 save_rtf_body = 0; 471 save_rtf_body = 0;
457 break; 472 break;
458 case 'C': 473 case 'C':
459 if (optarg) { 474 if (optarg) {
726 printf("\t-V\t- Version. Display program version\n"); 741 printf("\t-V\t- Version. Display program version\n");
727 printf("\t-C charset\t- character set for items with an unspecified character set\n"); 742 printf("\t-C charset\t- character set for items with an unspecified character set\n");
728 printf("\t-D\t- Include deleted items in output\n"); 743 printf("\t-D\t- Include deleted items in output\n");
729 printf("\t-M\t- Write emails in the MH (rfc822) format\n"); 744 printf("\t-M\t- Write emails in the MH (rfc822) format\n");
730 printf("\t-S\t- Separate. Write emails in the separate format\n"); 745 printf("\t-S\t- Separate. Write emails in the separate format\n");
746 printf("\t-a <attachment-extension-list>\t- Discard any attachment without an extension on the list\n");
731 printf("\t-b\t- Don't save RTF-Body attachments\n"); 747 printf("\t-b\t- Don't save RTF-Body attachments\n");
732 printf("\t-c[v|l]\t- Set the Contact output mode. -cv = VCard, -cl = EMail list\n"); 748 printf("\t-c[v|l]\t- Set the Contact output mode. -cv = VCard, -cl = EMail list\n");
733 printf("\t-d <filename> \t- Debug to file.\n"); 749 printf("\t-d <filename> \t- Debug to file.\n");
734 printf("\t-e\t- As with -M, but include extensions on output files\n"); 750 printf("\t-e\t- As with -M, but include extensions on output files\n");
735 printf("\t-h\t- Help. This screen\n"); 751 printf("\t-h\t- Help. This screen\n");
1009 while ((t = strpbrk(t, "/\\:"))) { 1025 while ((t = strpbrk(t, "/\\:"))) {
1010 // while there are characters in the second string that we don't want 1026 // while there are characters in the second string that we don't want
1011 *t = '_'; //replace them with an underscore 1027 *t = '_'; //replace them with an underscore
1012 } 1028 }
1013 DEBUG_RET(); 1029 DEBUG_RET();
1030 }
1031
1032
1033 /**
1034 * check if the file name extension is acceptable. If not, the attachment
1035 * will be discarded
1036 * @param attach pst attachment object
1037 * @return true if the attachment filename contains an extension that we want.
1038 */
1039 int acceptable_ext(pst_item_attach* attach)
1040 {
1041 if (!acceptable_extensions || *acceptable_extensions == '\0') return 1; // acceptable list missing or empty
1042 char *attach_filename = (attach->filename2.str) ? attach->filename2.str
1043 : attach->filename1.str;
1044 if (!attach_filename) return 1; // attachment with no name is always acceptable
1045 char *e = strrchr(attach_filename, '.');
1046 if (!e) return 1; // attachment with no extension is always acceptable.
1047 DEBUG_ENT("acceptable_ext");
1048 DEBUG_INFO(("attachment extension %s\n", e));
1049 int rc = 0;
1050 char *a = acceptable_extensions;
1051 while (*a) {
1052 if (pst_stricmp(a, e) == 0) {
1053 rc = 1;
1054 break;
1055 }
1056 a += strlen(a) + 1;
1057 }
1058 DEBUG_INFO(("attachment acceptable returns %d\n", rc));
1059 DEBUG_RET();
1060 return rc;
1014 } 1061 }
1015 1062
1016 1063
1017 void write_separate_attachment(char f_name[], pst_item_attach* attach, int attach_num, pst_file* pst) 1064 void write_separate_attachment(char f_name[], pst_item_attach* attach, int attach_num, pst_file* pst)
1018 { 1065 {
1753 attach->mimetype.is_utf8 = 1; 1800 attach->mimetype.is_utf8 = 1;
1754 find_rfc822_headers(extra_mime_headers); 1801 find_rfc822_headers(extra_mime_headers);
1755 write_embedded_message(f_output, attach, boundary, pst, save_rtf, extra_mime_headers); 1802 write_embedded_message(f_output, attach, boundary, pst, save_rtf, extra_mime_headers);
1756 } 1803 }
1757 else if (attach->data.data || attach->i_id) { 1804 else if (attach->data.data || attach->i_id) {
1758 if (mode == MODE_SEPARATE && !mode_MH) 1805 if (acceptable_ext(attach)) {
1759 write_separate_attachment(f_name, attach, ++attach_num, pst); 1806 if (mode == MODE_SEPARATE && !mode_MH)
1760 else 1807 write_separate_attachment(f_name, attach, ++attach_num, pst);
1761 write_inline_attachment(f_output, attach, boundary, pst); 1808 else
1809 write_inline_attachment(f_output, attach, boundary, pst);
1810 }
1762 } 1811 }
1763 } 1812 }
1764 } 1813 }
1765 1814
1766 fprintf(f_output, "\n--%s--\n\n", boundary); 1815 fprintf(f_output, "\n--%s--\n\n", boundary);