Mercurial > libpst
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 |