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)