comparison src/readpst.c @ 316:c4537664ff50

merge .msg generation code
author Carl Byington <carl@five-ten-sg.com>
date Mon, 24 Dec 2012 17:51:12 -0800
parents 5338d93889aa 0f19cd173eab
children 2474d01043cd
comparison
equal deleted inserted replaced
307:db6db9a26a19 316:c4537664ff50
5 * dave.s@earthcorp.com 5 * dave.s@earthcorp.com
6 */ 6 */
7 7
8 #include "define.h" 8 #include "define.h"
9 #include "lzfu.h" 9 #include "lzfu.h"
10 #include "msg.h"
10 11
11 #define OUTPUT_TEMPLATE "%s" 12 #define OUTPUT_TEMPLATE "%s"
12 #define OUTPUT_KMAIL_DIR_TEMPLATE ".%s.directory" 13 #define OUTPUT_KMAIL_DIR_TEMPLATE ".%s.directory"
13 #define KMAIL_INDEX ".%s.index" 14 #define KMAIL_INDEX ".%s.index"
14 #define SEP_MAIL_FILE_TEMPLATE "%i%s" 15 #define SEP_MAIL_FILE_TEMPLATE "%i%s"
37 int close_kmail_dir(); 38 int close_kmail_dir();
38 char* mk_recurse_dir(char* dir, int32_t folder_type); 39 char* mk_recurse_dir(char* dir, int32_t folder_type);
39 int close_recurse_dir(); 40 int close_recurse_dir();
40 char* mk_separate_dir(char *dir); 41 char* mk_separate_dir(char *dir);
41 int close_separate_dir(); 42 int close_separate_dir();
42 void mk_separate_file(struct file_ll *f, char *extension); 43 void mk_separate_file(struct file_ll *f, char *extension, int openit);
43 void close_separate_file(struct file_ll *f); 44 void close_separate_file(struct file_ll *f);
44 char* my_stristr(char *haystack, char *needle); 45 char* my_stristr(char *haystack, char *needle);
45 void check_filename(char *fname); 46 void check_filename(char *fname);
46 void write_separate_attachment(char f_name[], pst_item_attach* attach, int attach_num, pst_file* pst); 47 void write_separate_attachment(char f_name[], pst_item_attach* attach, int attach_num, pst_file* pst);
47 void write_embedded_message(FILE* f_output, pst_item_attach* attach, char *boundary, pst_file* pf, int save_rtf, char** extra_mime_headers); 48 void write_embedded_message(FILE* f_output, pst_item_attach* attach, char *boundary, pst_file* pf, int save_rtf, char** extra_mime_headers);
120 121
121 // global settings 122 // global settings
122 int mode = MODE_NORMAL; 123 int mode = MODE_NORMAL;
123 int mode_MH = 0; // a submode of MODE_SEPARATE 124 int mode_MH = 0; // a submode of MODE_SEPARATE
124 int mode_EX = 0; // a submode of MODE_SEPARATE 125 int mode_EX = 0; // a submode of MODE_SEPARATE
126 int mode_MSG = 0; // a submode of MODE_SEPARATE
125 int mode_thunder = 0; // a submode of MODE_RECURSE 127 int mode_thunder = 0; // a submode of MODE_RECURSE
126 int output_mode = OUTPUT_NORMAL; 128 int output_mode = OUTPUT_NORMAL;
127 int contact_mode = CMODE_VCARD; 129 int contact_mode = CMODE_VCARD;
128 int deleted_mode = DMODE_EXCLUDE; 130 int deleted_mode = DMODE_EXCLUDE;
129 int output_type_mode = 0xff; // Default to all. 131 int output_type_mode = 0xff; // Default to all.
304 ff.skip_count++; 306 ff.skip_count++;
305 DEBUG_INFO(("I have a contact, but the folder type %"PRIi32" isn't a contacts folder. Skipping it\n", ff.type)); 307 DEBUG_INFO(("I have a contact, but the folder type %"PRIi32" isn't a contacts folder. Skipping it\n", ff.type));
306 } 308 }
307 else { 309 else {
308 ff.item_count++; 310 ff.item_count++;
309 if (mode == MODE_SEPARATE) mk_separate_file(&ff, (mode_EX) ? ".vcf" : ""); 311 if (mode == MODE_SEPARATE) mk_separate_file(&ff, (mode_EX) ? ".vcf" : "", 1);
310 if (contact_mode == CMODE_VCARD) { 312 if (contact_mode == CMODE_VCARD) {
311 pst_convert_utf8_null(item, &item->comment); 313 pst_convert_utf8_null(item, &item->comment);
312 write_vcard(ff.output, item, item->contact, item->comment.str); 314 write_vcard(ff.output, item, item->contact, item->comment.str);
313 } 315 }
314 else { 316 else {
340 pid_t parent = getpid(); 342 pid_t parent = getpid();
341 pid_t child = try_fork(item->file_as.str); 343 pid_t child = try_fork(item->file_as.str);
342 if (child == 0) { 344 if (child == 0) {
343 // we are the child process, or the original parent if no children were available 345 // we are the child process, or the original parent if no children were available
344 pid_t me = getpid(); 346 pid_t me = getpid();
345 mk_separate_file(&ff, (mode_EX) ? ".eml" : ""); 347 mk_separate_file(&ff, (mode_EX) ? ".eml" : "", 1);
346 write_normal_email(ff.output, ff.name, item, mode, mode_MH, &pstfile, save_rtf_body, &extra_mime_headers); 348 write_normal_email(ff.output, ff.name, item, mode, mode_MH, &pstfile, save_rtf_body, &extra_mime_headers);
347 close_separate_file(&ff); 349 close_separate_file(&ff);
350 if (mode_MSG) {
351 mk_separate_file(&ff, ".msg", 0);
352 write_msg_email(ff.name, item, &pstfile);
353 }
348 #ifdef HAVE_FORK 354 #ifdef HAVE_FORK
349 #ifdef HAVE_SEMAPHORE_H 355 #ifdef HAVE_SEMAPHORE_H
350 if (me != parent) { 356 if (me != parent) {
351 // we really were a child, forked for the sole purpose of processing this message 357 // we really were a child, forked for the sole purpose of processing this message
352 // free my child count slot before really exiting, since 358 // free my child count slot before really exiting, since
378 ff.skip_count++; 384 ff.skip_count++;
379 DEBUG_INFO(("I have a journal entry, but the folder type %"PRIi32" isn't a journal folder. Skipping it\n", ff.type)); 385 DEBUG_INFO(("I have a journal entry, but the folder type %"PRIi32" isn't a journal folder. Skipping it\n", ff.type));
380 } 386 }
381 else { 387 else {
382 ff.item_count++; 388 ff.item_count++;
383 if (mode == MODE_SEPARATE) mk_separate_file(&ff, (mode_EX) ? ".ics" : ""); 389 if (mode == MODE_SEPARATE) mk_separate_file(&ff, (mode_EX) ? ".ics" : "", 1);
384 write_journal(ff.output, item); 390 write_journal(ff.output, item);
385 fprintf(ff.output, "\n"); 391 fprintf(ff.output, "\n");
386 if (mode == MODE_SEPARATE) close_separate_file(&ff); 392 if (mode == MODE_SEPARATE) close_separate_file(&ff);
387 } 393 }
388 } 394 }
399 ff.skip_count++; 405 ff.skip_count++;
400 DEBUG_INFO(("I have an appointment, but the folder type %"PRIi32" isn't an appointment folder. Skipping it\n", ff.type)); 406 DEBUG_INFO(("I have an appointment, but the folder type %"PRIi32" isn't an appointment folder. Skipping it\n", ff.type));
401 } 407 }
402 else { 408 else {
403 ff.item_count++; 409 ff.item_count++;
404 if (mode == MODE_SEPARATE) mk_separate_file(&ff, (mode_EX) ? ".ics" : ""); 410 if (mode == MODE_SEPARATE) mk_separate_file(&ff, (mode_EX) ? ".ics" : "", 1);
405 write_schedule_part_data(ff.output, item, NULL, NULL); 411 write_schedule_part_data(ff.output, item, NULL, NULL);
406 fprintf(ff.output, "\n"); 412 fprintf(ff.output, "\n");
407 if (mode == MODE_SEPARATE) close_separate_file(&ff); 413 if (mode == MODE_SEPARATE) close_separate_file(&ff);
408 } 414 }
409 } 415 }
442 printf("cannot compile regex pattern to find content charset in html bodies\n"); 448 printf("cannot compile regex pattern to find content charset in html bodies\n");
443 exit(3); 449 exit(3);
444 } 450 }
445 451
446 // command-line option handling 452 // command-line option handling
447 while ((c = getopt(argc, argv, "bC:c:Dd:ehj:kMo:qrSt:uVw"))!= -1) { 453 while ((c = getopt(argc, argv, "bC:c:Dd:emhj:kMo:qrSt:uVw"))!= -1) {
448 switch (c) { 454 switch (c) {
449 case 'b': 455 case 'b':
450 save_rtf_body = 0; 456 save_rtf_body = 0;
451 break; 457 break;
452 case 'C': 458 case 'C':
489 case 'k': 495 case 'k':
490 mode = MODE_KMAIL; 496 mode = MODE_KMAIL;
491 break; 497 break;
492 case 'M': 498 case 'M':
493 mode = MODE_SEPARATE; 499 mode = MODE_SEPARATE;
494 mode_MH = 1; 500 mode_MH = 1;
495 mode_EX = 0; 501 mode_EX = 0;
502 mode_MSG = 0;
496 break; 503 break;
497 case 'e': 504 case 'e':
498 mode = MODE_SEPARATE; 505 mode = MODE_SEPARATE;
499 mode_MH = 1; 506 mode_MH = 1;
500 mode_EX = 1; 507 mode_EX = 1;
508 mode_MSG = 0;
509 file_name_len = 14;
510 break;
511 case 'm':
512 mode = MODE_SEPARATE;
513 mode_MH = 1;
514 mode_EX = 1;
515 mode_MSG = 1;
501 file_name_len = 14; 516 file_name_len = 14;
502 break; 517 break;
503 case 'o': 518 case 'o':
504 output_dir = optarg; 519 output_dir = optarg;
505 break; 520 break;
510 mode = MODE_RECURSE; 525 mode = MODE_RECURSE;
511 mode_thunder = 0; 526 mode_thunder = 0;
512 break; 527 break;
513 case 'S': 528 case 'S':
514 mode = MODE_SEPARATE; 529 mode = MODE_SEPARATE;
515 mode_MH = 0; 530 mode_MH = 0;
516 mode_EX = 0; 531 mode_EX = 0;
532 mode_MSG = 0;
517 break; 533 break;
518 case 't': 534 case 't':
519 // email, appointment, contact, other 535 // email, appointment, contact, other
520 if (!optarg) { 536 if (!optarg) {
521 usage(); 537 usage();
717 printf("\t-d <filename> \t- Debug to file.\n"); 733 printf("\t-d <filename> \t- Debug to file.\n");
718 printf("\t-e\t- As with -M, but include extensions on output files\n"); 734 printf("\t-e\t- As with -M, but include extensions on output files\n");
719 printf("\t-h\t- Help. This screen\n"); 735 printf("\t-h\t- Help. This screen\n");
720 printf("\t-j <integer>\t- Number of parallel jobs to run\n"); 736 printf("\t-j <integer>\t- Number of parallel jobs to run\n");
721 printf("\t-k\t- KMail. Output in kmail format\n"); 737 printf("\t-k\t- KMail. Output in kmail format\n");
738 printf("\t-m\t- As with -e, but write .msg files also\n");
722 printf("\t-o <dirname>\t- Output directory to write files to. CWD is changed *after* opening pst file\n"); 739 printf("\t-o <dirname>\t- Output directory to write files to. CWD is changed *after* opening pst file\n");
723 printf("\t-q\t- Quiet. Only print error messages\n"); 740 printf("\t-q\t- Quiet. Only print error messages\n");
724 printf("\t-r\t- Recursive. Output in a recursive format\n"); 741 printf("\t-r\t- Recursive. Output in a recursive format\n");
725 printf("\t-t[eajc]\t- Set the output type list. e = email, a = attachment, j = journal, c = contact\n"); 742 printf("\t-t[eajc]\t- Set the output type list. e = email, a = attachment, j = journal, c = contact\n");
726 printf("\t-u\t- Thunderbird mode. Write two extra .size and .type files\n"); 743 printf("\t-u\t- Thunderbird mode. Write two extra .size and .type files\n");
727 printf("\t-w\t- Overwrite any output mbox files\n"); 744 printf("\t-w\t- Overwrite any output mbox files\n");
728 printf("\n"); 745 printf("\n");
729 printf("Only one of -k -M -r -S should be specified\n"); 746 printf("Only one of -M -S -e -k -m -r should be specified\n");
730 DEBUG_RET(); 747 DEBUG_RET();
731 } 748 }
732 749
733 750
734 void version() { 751 void version() {
922 DEBUG_RET(); 939 DEBUG_RET();
923 return 0; 940 return 0;
924 } 941 }
925 942
926 943
927 void mk_separate_file(struct file_ll *f, char *extension) { 944 void mk_separate_file(struct file_ll *f, char *extension, int openit) {
928 DEBUG_ENT("mk_separate_file"); 945 DEBUG_ENT("mk_separate_file");
929 DEBUG_INFO(("opening next file to save email\n")); 946 DEBUG_INFO(("opening next file to save email\n"));
930 if (f->item_count > 999999999) { // bigger than nine 9's 947 if (f->item_count > 999999999) { // bigger than nine 9's
931 DIE(("mk_separate_file: The number of emails in this folder has become too high to handle\n")); 948 DIE(("mk_separate_file: The number of emails in this folder has become too high to handle\n"));
932 } 949 }
933 sprintf(f->name, SEP_MAIL_FILE_TEMPLATE, f->item_count, extension); 950 sprintf(f->name, SEP_MAIL_FILE_TEMPLATE, f->item_count, extension);
934 check_filename(f->name); 951 check_filename(f->name);
935 if (!(f->output = fopen(f->name, "w"))) { 952 if (openit) {
936 DIE(("mk_separate_file: Cannot open file to save email \"%s\"\n", f->name)); 953 if (!(f->output = fopen(f->name, "w"))) {
954 DIE(("mk_separate_file: Cannot open file to save email \"%s\"\n", f->name));
955 }
937 } 956 }
938 DEBUG_RET(); 957 DEBUG_RET();
939 } 958 }
940 959
941 960