Mercurial > libpst
comparison src/readpst.c @ 291:bc23fba0da8e
possible fix for corrupted output forking for separate messages
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Sat, 04 Jun 2011 11:38:12 -0700 |
parents | fec37c150982 |
children | e0e5844d91b3 |
comparison
equal
deleted
inserted
replaced
290:fec37c150982 | 291:bc23fba0da8e |
---|---|
37 int close_kmail_dir(); | 37 int close_kmail_dir(); |
38 char* mk_recurse_dir(char* dir, int32_t folder_type); | 38 char* mk_recurse_dir(char* dir, int32_t folder_type); |
39 int close_recurse_dir(); | 39 int close_recurse_dir(); |
40 char* mk_separate_dir(char *dir); | 40 char* mk_separate_dir(char *dir); |
41 int close_separate_dir(); | 41 int close_separate_dir(); |
42 int mk_separate_file(struct file_ll *f, char *extension); | 42 void mk_separate_file(struct file_ll *f, char *extension); |
43 void close_separate_file(struct file_ll *f); | |
43 char* my_stristr(char *haystack, char *needle); | 44 char* my_stristr(char *haystack, char *needle); |
44 void check_filename(char *fname); | 45 void check_filename(char *fname); |
45 void write_separate_attachment(char f_name[], pst_item_attach* attach, int attach_num, pst_file* pst); | 46 void write_separate_attachment(char f_name[], pst_item_attach* attach, int attach_num, pst_file* pst); |
46 void write_embedded_message(FILE* f_output, pst_item_attach* attach, char *boundary, pst_file* pf, char** extra_mime_headers); | 47 void write_embedded_message(FILE* f_output, pst_item_attach* attach, char *boundary, pst_file* pf, char** extra_mime_headers); |
47 void write_inline_attachment(FILE* f_output, pst_item_attach* attach, char *boundary, pst_file* pst); | 48 void write_inline_attachment(FILE* f_output, pst_item_attach* attach, char *boundary, pst_file* pst); |
312 else { | 313 else { |
313 pst_convert_utf8(item, &item->contact->fullname); | 314 pst_convert_utf8(item, &item->contact->fullname); |
314 pst_convert_utf8(item, &item->contact->address1); | 315 pst_convert_utf8(item, &item->contact->address1); |
315 fprintf(ff.output, "%s <%s>\n", item->contact->fullname.str, item->contact->address1.str); | 316 fprintf(ff.output, "%s <%s>\n", item->contact->fullname.str, item->contact->address1.str); |
316 } | 317 } |
318 if (mode == MODE_SEPARATE) close_separate_file(&ff); | |
317 } | 319 } |
318 } | 320 } |
319 | 321 |
320 } else if (item->email && ((item->type == PST_TYPE_NOTE) || (item->type == PST_TYPE_SCHEDULE) || (item->type == PST_TYPE_REPORT))) { | 322 } else if (item->email && ((item->type == PST_TYPE_NOTE) || (item->type == PST_TYPE_SCHEDULE) || (item->type == PST_TYPE_REPORT))) { |
321 DEBUG_INFO(("Processing Email\n")); | 323 DEBUG_INFO(("Processing Email\n")); |
330 DEBUG_INFO(("I have an email type %"PRIi32", but the folder type %"PRIi32" isn't an email folder. Skipping it\n", item->type, ff.type)); | 332 DEBUG_INFO(("I have an email type %"PRIi32", but the folder type %"PRIi32" isn't an email folder. Skipping it\n", item->type, ff.type)); |
331 } | 333 } |
332 else { | 334 else { |
333 char *extra_mime_headers = NULL; | 335 char *extra_mime_headers = NULL; |
334 ff.item_count++; | 336 ff.item_count++; |
335 if (mode == MODE_SEPARATE) mk_separate_file(&ff, (mode_EX) ? ".eml" : ""); | |
336 if (mode == MODE_SEPARATE) { | 337 if (mode == MODE_SEPARATE) { |
337 // process this single email message, possibly forking | 338 // process this single email message, possibly forking |
338 pid_t parent = getpid(); | 339 pid_t parent = getpid(); |
339 pid_t child = try_fork(item->file_as.str); | 340 pid_t child = try_fork(item->file_as.str); |
340 if (child == 0) { | 341 if (child == 0) { |
341 // we are the child process, or the original parent if no children were available | 342 // we are the child process, or the original parent if no children were available |
342 pid_t me = getpid(); | 343 pid_t me = getpid(); |
344 mk_separate_file(&ff, (mode_EX) ? ".eml" : ""); | |
343 write_normal_email(ff.output, ff.name, item, mode, mode_MH, &pstfile, save_rtf_body, &extra_mime_headers); | 345 write_normal_email(ff.output, ff.name, item, mode, mode_MH, &pstfile, save_rtf_body, &extra_mime_headers); |
346 close_separate_file(&ff); | |
344 #ifdef HAVE_FORK | 347 #ifdef HAVE_FORK |
345 #ifdef HAVE_SEMAPHORE_H | 348 #ifdef HAVE_SEMAPHORE_H |
346 if (me != parent) { | 349 if (me != parent) { |
347 // we really were a child, forked for the sole purpose of processing this message | 350 // we really were a child, forked for the sole purpose of processing this message |
348 // free my child count slot before really exiting, since | 351 // free my child count slot before really exiting, since |
377 else { | 380 else { |
378 ff.item_count++; | 381 ff.item_count++; |
379 if (mode == MODE_SEPARATE) mk_separate_file(&ff, (mode_EX) ? ".ics" : ""); | 382 if (mode == MODE_SEPARATE) mk_separate_file(&ff, (mode_EX) ? ".ics" : ""); |
380 write_journal(ff.output, item); | 383 write_journal(ff.output, item); |
381 fprintf(ff.output, "\n"); | 384 fprintf(ff.output, "\n"); |
385 if (mode == MODE_SEPARATE) close_separate_file(&ff); | |
382 } | 386 } |
383 } | 387 } |
384 | 388 |
385 } else if (item->appointment && (item->type == PST_TYPE_APPOINTMENT)) { | 389 } else if (item->appointment && (item->type == PST_TYPE_APPOINTMENT)) { |
386 DEBUG_INFO(("Processing Appointment Entry\n")); | 390 DEBUG_INFO(("Processing Appointment Entry\n")); |
397 else { | 401 else { |
398 ff.item_count++; | 402 ff.item_count++; |
399 if (mode == MODE_SEPARATE) mk_separate_file(&ff, (mode_EX) ? ".ics" : ""); | 403 if (mode == MODE_SEPARATE) mk_separate_file(&ff, (mode_EX) ? ".ics" : ""); |
400 write_schedule_part_data(ff.output, item, NULL, NULL); | 404 write_schedule_part_data(ff.output, item, NULL, NULL); |
401 fprintf(ff.output, "\n"); | 405 fprintf(ff.output, "\n"); |
406 if (mode == MODE_SEPARATE) close_separate_file(&ff); | |
402 } | 407 } |
403 } | 408 } |
404 | 409 |
405 } else if (item->message_store) { | 410 } else if (item->message_store) { |
406 // there should only be one message_store, and we have already done it | 411 // there should only be one message_store, and we have already done it |
907 DEBUG_RET(); | 912 DEBUG_RET(); |
908 return 0; | 913 return 0; |
909 } | 914 } |
910 | 915 |
911 | 916 |
912 int mk_separate_file(struct file_ll *f, char *extension) { | 917 void mk_separate_file(struct file_ll *f, char *extension) { |
913 DEBUG_ENT("mk_separate_file"); | 918 DEBUG_ENT("mk_separate_file"); |
914 DEBUG_INFO(("opening next file to save email\n")); | 919 DEBUG_INFO(("opening next file to save email\n")); |
915 if (f->item_count > 999999999) { // bigger than nine 9's | 920 if (f->item_count > 999999999) { // bigger than nine 9's |
916 DIE(("mk_separate_file: The number of emails in this folder has become too high to handle\n")); | 921 DIE(("mk_separate_file: The number of emails in this folder has become too high to handle\n")); |
917 } | 922 } |
918 sprintf(f->name, SEP_MAIL_FILE_TEMPLATE, f->item_count, extension); | 923 sprintf(f->name, SEP_MAIL_FILE_TEMPLATE, f->item_count, extension); |
919 if (f->output) fclose(f->output); | |
920 f->output = NULL; | |
921 check_filename(f->name); | 924 check_filename(f->name); |
922 if (!(f->output = fopen(f->name, "w"))) { | 925 if (!(f->output = fopen(f->name, "w"))) { |
923 DIE(("mk_separate_file: Cannot open file to save email \"%s\"\n", f->name)); | 926 DIE(("mk_separate_file: Cannot open file to save email \"%s\"\n", f->name)); |
924 } | 927 } |
925 DEBUG_RET(); | 928 DEBUG_RET(); |
926 return 0; | 929 } |
930 | |
931 | |
932 void close_separate_file(struct file_ll *f) { | |
933 DEBUG_ENT("close_separate_file"); | |
934 if (f->output) { | |
935 struct stat st; | |
936 fclose(f->output); | |
937 stat(f->name, &st); | |
938 if (!st.st_size) { | |
939 DEBUG_WARN(("removing empty output file %s\n", f->name)); | |
940 remove(f->name); | |
941 } | |
942 f->output = NULL; | |
943 } | |
944 DEBUG_RET(); | |
927 } | 945 } |
928 | 946 |
929 | 947 |
930 char *my_stristr(char *haystack, char *needle) { | 948 char *my_stristr(char *haystack, char *needle) { |
931 // my_stristr varies from strstr in that its searches are case-insensitive | 949 // my_stristr varies from strstr in that its searches are case-insensitive |
2115 printf("\t\"%s\" - %i items done, %i items skipped.\n", f->dname, f->item_count, f->skip_count); | 2133 printf("\t\"%s\" - %i items done, %i items skipped.\n", f->dname, f->item_count, f->skip_count); |
2116 fflush(stdout); | 2134 fflush(stdout); |
2117 pst_debug_unlock(); | 2135 pst_debug_unlock(); |
2118 } | 2136 } |
2119 if (f->output) { | 2137 if (f->output) { |
2138 if (mode == MODE_SEPARATE) DEBUG_WARN(("close_enter_dir finds open separate file\n")); | |
2120 struct stat st; | 2139 struct stat st; |
2121 fclose(f->output); | 2140 fclose(f->output); |
2122 stat(f->name, &st); | 2141 stat(f->name, &st); |
2123 if (!st.st_size) { | 2142 if (!st.st_size) { |
2124 DEBUG_WARN(("removing empty output file %s\n", f->name)); | 2143 DEBUG_WARN(("removing empty output file %s\n", f->name)); |
2125 remove(f->name); | 2144 remove(f->name); |
2126 } | 2145 } |
2146 f->output = NULL; | |
2127 } | 2147 } |
2128 free(f->name); | 2148 free(f->name); |
2129 free(f->dname); | 2149 free(f->dname); |
2130 | 2150 |
2131 if (mode == MODE_KMAIL) | 2151 if (mode == MODE_KMAIL) |