comparison src/readpst.c @ 231:fe64279df92b

patches from Chris White, Roberto Polli, Justin Greer
author Carl Byington <carl@five-ten-sg.com>
date Thu, 10 Sep 2009 15:21:23 -0700
parents 42b38d65f7e4
children 1d50ff3c5091
comparison
equal deleted inserted replaced
230:42b38d65f7e4 231:fe64279df92b
116 #define RTF_ATTACH_TYPE "application/rtf" 116 #define RTF_ATTACH_TYPE "application/rtf"
117 117
118 // global settings 118 // global settings
119 int mode = MODE_NORMAL; 119 int mode = MODE_NORMAL;
120 int mode_MH = 0; // a submode of MODE_SEPARATE 120 int mode_MH = 0; // a submode of MODE_SEPARATE
121 int mode_thunder = 0; // a submode of MODE_RECURSE
121 int output_mode = OUTPUT_NORMAL; 122 int output_mode = OUTPUT_NORMAL;
122 int contact_mode = CMODE_VCARD; 123 int contact_mode = CMODE_VCARD;
123 int deleted_mode = DMODE_EXCLUDE; 124 int deleted_mode = DMODE_EXCLUDE;
124 int output_type_mode = 0xff; // Default to all. 125 int output_type_mode = 0xff; // Default to all.
125 int contact_mode_specified = 0; 126 int contact_mode_specified = 0;
385 printf("cannot compile regex pattern to find content charset in html bodies\n"); 386 printf("cannot compile regex pattern to find content charset in html bodies\n");
386 exit(3); 387 exit(3);
387 } 388 }
388 389
389 // command-line option handling 390 // command-line option handling
390 while ((c = getopt(argc, argv, "bc:Dd:hj:kMo:qrSt:Vw"))!= -1) { 391 while ((c = getopt(argc, argv, "bc:Dd:hj:kMo:qrSt:uVw"))!= -1) {
391 switch (c) { 392 switch (c) {
392 case 'b': 393 case 'b':
393 save_rtf_body = 0; 394 save_rtf_body = 0;
394 break; 395 break;
395 case 'c': 396 case 'c':
433 case 'q': 434 case 'q':
434 output_mode = OUTPUT_QUIET; 435 output_mode = OUTPUT_QUIET;
435 break; 436 break;
436 case 'r': 437 case 'r':
437 mode = MODE_RECURSE; 438 mode = MODE_RECURSE;
439 mode_thunder = 0;
438 break; 440 break;
439 case 'S': 441 case 'S':
440 mode = MODE_SEPARATE; 442 mode = MODE_SEPARATE;
441 mode_MH = 0; 443 mode_MH = 0;
442 break;
443 case 'V':
444 version();
445 exit(0);
446 break; 444 break;
447 case 't': 445 case 't':
448 // email, appointment, contact, other 446 // email, appointment, contact, other
449 if (!optarg) { 447 if (!optarg) {
450 usage(); 448 usage();
472 break; 470 break;
473 } 471 }
474 temp++; 472 temp++;
475 } 473 }
476 break; 474 break;
475 case 'u':
476 mode = MODE_RECURSE;
477 mode_thunder = 1;
478 break;
479 case 'V':
480 version();
481 exit(0);
482 break;
477 case 'w': 483 case 'w':
478 overwrite = 1; 484 overwrite = 1;
479 break; 485 break;
480 default: 486 default:
481 usage(); 487 usage();
630 printf("\t-D\t- Include deleted items in output\n"); 636 printf("\t-D\t- Include deleted items in output\n");
631 printf("\t-M\t- MH. Write emails in the MH format\n"); 637 printf("\t-M\t- MH. Write emails in the MH format\n");
632 printf("\t-S\t- Separate. Write emails in the separate format\n"); 638 printf("\t-S\t- Separate. Write emails in the separate format\n");
633 printf("\t-b\t- Don't save RTF-Body attachments\n"); 639 printf("\t-b\t- Don't save RTF-Body attachments\n");
634 printf("\t-c[v|l]\t- Set the Contact output mode. -cv = VCard, -cl = EMail list\n"); 640 printf("\t-c[v|l]\t- Set the Contact output mode. -cv = VCard, -cl = EMail list\n");
635 printf("\t-t[eajc]\t- Set the output type list. e = email, a = attachment, j = journal, c = contact\n");
636 printf("\t-d <filename> \t- Debug to file. This is a binary log. Use readpstlog to print it\n"); 641 printf("\t-d <filename> \t- Debug to file. This is a binary log. Use readpstlog to print it\n");
637 printf("\t-h\t- Help. This screen\n"); 642 printf("\t-h\t- Help. This screen\n");
638 printf("\t-j <integer>\t- Number of parallel jobs to run\n"); 643 printf("\t-j <integer>\t- Number of parallel jobs to run\n");
639 printf("\t-k\t- KMail. Output in kmail format\n"); 644 printf("\t-k\t- KMail. Output in kmail format\n");
640 printf("\t-o <dirname>\t- Output directory to write files to. CWD is changed *after* opening pst file\n"); 645 printf("\t-o <dirname>\t- Output directory to write files to. CWD is changed *after* opening pst file\n");
641 printf("\t-q\t- Quiet. Only print error messages\n"); 646 printf("\t-q\t- Quiet. Only print error messages\n");
642 printf("\t-r\t- Recursive. Output in a recursive format\n"); 647 printf("\t-r\t- Recursive. Output in a recursive format\n");
648 printf("\t-t[eajc]\t- Set the output type list. e = email, a = attachment, j = journal, c = contact\n");
649 printf("\t-u\t- Thunderbird mode. Write two extra .size and .type files\n");
643 printf("\t-w\t- Overwrite any output mbox files\n"); 650 printf("\t-w\t- Overwrite any output mbox files\n");
644 printf("\n"); 651 printf("\n");
645 printf("Only one of -k -M -r -S should be specified\n"); 652 printf("Only one of -k -M -r -S should be specified\n");
646 DEBUG_RET(); 653 DEBUG_RET();
647 } 654 }
957 964
958 void write_embedded_message(FILE* f_output, pst_item_attach* attach, char *boundary, pst_file* pf, char** extra_mime_headers) 965 void write_embedded_message(FILE* f_output, pst_item_attach* attach, char *boundary, pst_file* pf, char** extra_mime_headers)
959 { 966 {
960 pst_index_ll *ptr; 967 pst_index_ll *ptr;
961 DEBUG_ENT("write_embedded_message"); 968 DEBUG_ENT("write_embedded_message");
962 fprintf(f_output, "\n--%s\n", boundary);
963 fprintf(f_output, "Content-Type: %s\n\n", attach->mimetype.str);
964 ptr = pst_getID(pf, attach->i_id); 969 ptr = pst_getID(pf, attach->i_id);
965 970
966 pst_desc_tree d_ptr; 971 pst_desc_tree d_ptr;
967 d_ptr.d_id = 0; 972 d_ptr.d_id = 0;
968 d_ptr.parent_d_id = 0; 973 d_ptr.parent_d_id = 0;
974 d_ptr.parent = NULL; 979 d_ptr.parent = NULL;
975 d_ptr.child = NULL; 980 d_ptr.child = NULL;
976 d_ptr.child_tail = NULL; 981 d_ptr.child_tail = NULL;
977 982
978 pst_item *item = pst_parse_item(pf, &d_ptr, attach->id2_head); 983 pst_item *item = pst_parse_item(pf, &d_ptr, attach->id2_head);
979 write_normal_email(f_output, "", item, MODE_NORMAL, 0, pf, 0, extra_mime_headers); 984 // It appears that if the embedded message contains an appointment/
980 pst_freeItem(item); 985 // calendar item, pst_parse_item returns NULL due to the presence of
986 // an unexpected reference type of 0x1048, which seems to represent
987 // an array of GUIDs representing a CLSID. It's likely that this is
988 // a reference to an internal Outlook COM class.
989 // Log the skipped item and continue on.
990 if (!item) {
991 DEBUG_WARN(("write_embedded_message: pst_parse_item was unable to parse the embedded message in attachment ID %llu", attach->i_id));
992 } else {
993 fprintf(f_output, "\n--%s\n", boundary);
994 fprintf(f_output, "Content-Type: %s\n\n", attach->mimetype.str);
995 write_normal_email(f_output, "", item, MODE_NORMAL, 0, pf, 0, extra_mime_headers);
996 pst_freeItem(item);
997 }
981 998
982 DEBUG_RET(); 999 DEBUG_RET();
983 } 1000 }
984 1001
985 1002
1867 f->stored_count = (item->folder) ? item->folder->item_count : 0; 1884 f->stored_count = (item->folder) ? item->folder->item_count : 0;
1868 1885
1869 DEBUG_ENT("create_enter_dir"); 1886 DEBUG_ENT("create_enter_dir");
1870 if (mode == MODE_KMAIL) 1887 if (mode == MODE_KMAIL)
1871 f->name = mk_kmail_dir(item->file_as.str); 1888 f->name = mk_kmail_dir(item->file_as.str);
1872 else if (mode == MODE_RECURSE) 1889 else if (mode == MODE_RECURSE) {
1873 f->name = mk_recurse_dir(item->file_as.str, f->type); 1890 f->name = mk_recurse_dir(item->file_as.str, f->type);
1874 else if (mode == MODE_SEPARATE) { 1891 if (mode_thunder) {
1892 FILE *type_file = fopen(".type", "w");
1893 fprintf(type_file, "%d\n", item->type);
1894 fclose(type_file);
1895 }
1896 } else if (mode == MODE_SEPARATE) {
1875 // do similar stuff to recurse here. 1897 // do similar stuff to recurse here.
1876 mk_separate_dir(item->file_as.str); 1898 mk_separate_dir(item->file_as.str);
1877 f->name = (char*) pst_malloc(10); 1899 f->name = (char*) pst_malloc(10);
1878 memset(f->name, 0, 10); 1900 memset(f->name, 0, 10);
1879 } else { 1901 } else {
1942 free(f->name); 1964 free(f->name);
1943 free(f->dname); 1965 free(f->dname);
1944 1966
1945 if (mode == MODE_KMAIL) 1967 if (mode == MODE_KMAIL)
1946 close_kmail_dir(); 1968 close_kmail_dir();
1947 else if (mode == MODE_RECURSE) 1969 else if (mode == MODE_RECURSE) {
1970 if (mode_thunder) {
1971 FILE *type_file = fopen(".size", "w");
1972 fprintf(type_file, "%i %i\n", f->item_count, f->stored_count);
1973 fclose(type_file);
1974 }
1948 close_recurse_dir(); 1975 close_recurse_dir();
1949 else if (mode == MODE_SEPARATE) 1976 } else if (mode == MODE_SEPARATE)
1950 close_separate_dir(); 1977 close_separate_dir();
1951 } 1978 }
1952 1979