Mercurial > libpst
changeset 363:3a1d25c579c6 stable-0-6-68
allow folders containing multiple item types; better detection of valid internet headers
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Mon, 29 Aug 2016 09:50:24 -0700 |
parents | c42273d817c7 |
children | 9c6f93aca0db |
files | ChangeLog NEWS configure.in libpst.spec.in regression/regression-tests.bash src/libpst.h src/readpst.c xml/libpst.in |
diffstat | 8 files changed, 233 insertions(+), 205 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Wed Jul 06 12:14:55 2016 -0700 +++ b/ChangeLog Mon Aug 29 09:50:24 2016 -0700 @@ -1,3 +1,8 @@ +LibPST 0.6.68 (2016-08-29) +=============================== + * allow folders containing multiple item types, e.g. email and calendar + * better detection of valid internet headers + LibPST 0.6.67 (2016-07-06) =============================== * Jeffrey Morlan - multiple bug fixes and an optimization @@ -120,10 +125,10 @@ LibPST 0.6.43 (2009-09-12) =============================== * patches from Justin Greer. - add code pages 1200 and 1201 to the list for iconv - add support for 0x0201 indirect blocks that point to 0x0101 blocks - add readpst -t option to select output item types - fix (remove) extra new line inside headers + add code pages 1200 and 1201 to the list for iconv + add support for 0x0201 indirect blocks that point to 0x0101 blocks + add readpst -t option to select output item types + fix (remove) extra new line inside headers * cleanup base64 encoding to remove duplicate code. * patch from Chris White to avoid segfault with embedded appointments. * patch from Roberto Polli to add creation of some Thunderbird specific meta files.
--- a/NEWS Wed Jul 06 12:14:55 2016 -0700 +++ b/NEWS Mon Aug 29 09:50:24 2016 -0700 @@ -1,3 +1,4 @@ +0.6.68 2016-08-29 allow folders containing multiple item types; better detection of valid internet headers 0.6.67 2016-07-06 Jeffrey Morlan - multiple bug fixes and an optimization 0.6.66 2015-12-21 Igor Stroh - Added Content-ID header support 0.6.65 2015-09-11 Jeffrey Morlan - fix multiple Content-Type headers; Hans Liss - debug level output
--- a/configure.in Wed Jul 06 12:14:55 2016 -0700 +++ b/configure.in Mon Aug 29 09:50:24 2016 -0700 @@ -1,5 +1,5 @@ AC_PREREQ(2.60) -AC_INIT(libpst,0.6.67,carl@five-ten-sg.com) +AC_INIT(libpst,0.6.68,carl@five-ten-sg.com) AC_CONFIG_SRCDIR([src/libpst.c]) AC_CONFIG_HEADER([config.h]) AC_CONFIG_MACRO_DIR([m4]) @@ -21,7 +21,7 @@ # 6. libtool will build libpst.so.x.y.z where the SONAME is libpst.so.x # and x=current-age, y=age, z=revision -libpst_version_info='5:12:1' +libpst_version_info='5:13:1' AC_SUBST(LIBPST_VERSION_INFO, [$libpst_version_info]) libpst_so_major='4' AC_SUBST(LIBPST_SO_MAJOR, [$libpst_so_major]) @@ -52,6 +52,7 @@ # 0.6.63 libpst.so.4 libpst.so.4.1.10 # 0.6.66 libpst.so.4 libpst.so.4.1.11 # 0.6.67 libpst.so.4 libpst.so.4.1.12 +# 0.6.68 libpst.so.4 libpst.so.4.1.13
--- a/libpst.spec.in Wed Jul 06 12:14:55 2016 -0700 +++ b/libpst.spec.in Mon Aug 29 09:50:24 2016 -0700 @@ -160,6 +160,13 @@ %changelog +* Mon Aug 29 2016 Carl Byington <carl@five-ten-sg.com> 0.6.68-1 +- allow folders containing multiple item types, e.g. email and calendar +- better detection of valid internet headers + +* Tue Jul 19 2016 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.6.67-2 +- https://fedoraproject.org/wiki/Changes/Automatic_Provides_for_Python_RPM_Packages + * Wed Jul 06 2016 Carl Byington <carl@five-ten-sg.com> 0.6.67-1 - Jeffrey Morlan - multiple bug fixes and an optimization @@ -179,15 +186,13 @@ * Thu Aug 27 2015 Jonathan Wakely <jwakely@redhat.com> - 0.6.64-6 - Rebuilt for Boost 1.59 -* Wed Jul 29 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - - 0.6.64-5 +* Wed Jul 29 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.6.64-5 - Rebuilt for https://fedoraproject.org/wiki/Changes/F23Boost159 * Wed Jul 22 2015 David Tardon <dtardon@redhat.com> - 0.6.64-4 - rebuild for Boost 1.58 -* Wed Jun 17 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - - 0.6.64-3 +* Wed Jun 17 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.6.64-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild * Sat May 02 2015 Kalev Lember <kalevlember@gmail.com> - 0.6.64-2
--- a/regression/regression-tests.bash Wed Jul 06 12:14:55 2016 -0700 +++ b/regression/regression-tests.bash Mon Aug 29 09:50:24 2016 -0700 @@ -73,6 +73,7 @@ utf='-8' echo $val ../src/readpst $utf $acc -C $char -j 0 -r -cv -o output$n -d $ba.log $fn $val ../src/readpst $utf $acc -C $char -j 0 -r -cv -o output$n -d $ba.log $fn >$ba.err 2>&1 + #readpst $utf $acc -C $char -j 0 -r -cv -o output$n -d $ba.log $fn >$ba.err 2>&1 ## separate mode with filename extensions and .msg files #echo $val ../src/readpst $jobs -r -m -D -cv -o output$n -d $ba.log $fn
--- a/src/libpst.h Wed Jul 06 12:14:55 2016 -0700 +++ b/src/libpst.h Mon Aug 29 09:50:24 2016 -0700 @@ -32,6 +32,7 @@ #define PST_TYPE_TASK 12 #define PST_TYPE_OTHER 13 #define PST_TYPE_REPORT 14 +#define PST_TYPE_MAX 15 // defines types of possible encryption #define PST_NO_ENCRYPT 0
--- a/src/readpst.c Wed Jul 06 12:14:55 2016 -0700 +++ b/src/readpst.c Mon Aug 29 09:50:24 2016 -0700 @@ -18,13 +18,12 @@ #define C_TIME_SIZE 500 struct file_ll { - char *name; + char *name[PST_TYPE_MAX]; char *dname; - FILE * output; + FILE * output[PST_TYPE_MAX]; int32_t stored_count; int32_t item_count; int32_t skip_count; - int32_t type; }; int grim_reaper(); @@ -36,11 +35,11 @@ void version(); char* mk_kmail_dir(char* fname); int close_kmail_dir(); -char* mk_recurse_dir(char* dir, int32_t folder_type); +void mk_recurse_dir(char* dir); int close_recurse_dir(); -char* mk_separate_dir(char *dir); +void mk_separate_dir(char *dir); int close_separate_dir(); -void mk_separate_file(struct file_ll *f, char *extension, int openit); +void mk_separate_file(struct file_ll *f, int32_t t, char *extension, int openit); void close_separate_file(struct file_ll *f); char* my_stristr(char *haystack, char *needle); void check_filename(char *fname); @@ -244,7 +243,6 @@ pst_item *item = NULL; DEBUG_ENT("process"); - memset(&ff, 0, sizeof(ff)); create_enter_dir(&ff, outeritem); for (; d_ptr; d_ptr = d_ptr->next) { @@ -308,25 +306,18 @@ DEBUG_INFO(("skipping contact: not in output type list\n")); } else { - if (!ff.type) ff.type = item->type; - if ((ff.type != PST_TYPE_CONTACT) && (mode != MODE_SEPARATE)) { - ff.skip_count++; - DEBUG_INFO(("I have a contact, but the folder type %"PRIi32" isn't a contacts folder. Skipping it\n", ff.type)); + ff.item_count++; + if (mode == MODE_SEPARATE) mk_separate_file(&ff, PST_TYPE_CONTACT, (mode_EX) ? ".vcf" : "", 1); + if (contact_mode == CMODE_VCARD) { + pst_convert_utf8_null(item, &item->comment); + write_vcard(ff.output[PST_TYPE_CONTACT], item, item->contact, item->comment.str); } else { - ff.item_count++; - if (mode == MODE_SEPARATE) mk_separate_file(&ff, (mode_EX) ? ".vcf" : "", 1); - if (contact_mode == CMODE_VCARD) { - pst_convert_utf8_null(item, &item->comment); - write_vcard(ff.output, item, item->contact, item->comment.str); - } - else { - pst_convert_utf8(item, &item->contact->fullname); - pst_convert_utf8(item, &item->contact->address1); - fprintf(ff.output, "%s <%s>\n", item->contact->fullname.str, item->contact->address1.str); - } - if (mode == MODE_SEPARATE) close_separate_file(&ff); + pst_convert_utf8(item, &item->contact->fullname); + pst_convert_utf8(item, &item->contact->address1); + fprintf(ff.output[PST_TYPE_CONTACT], "%s <%s>\n", item->contact->fullname.str, item->contact->address1.str); } + if (mode == MODE_SEPARATE) close_separate_file(&ff); } } else if (item->email && ((item->type == PST_TYPE_NOTE) || (item->type == PST_TYPE_SCHEDULE) || (item->type == PST_TYPE_REPORT))) { @@ -336,46 +327,39 @@ DEBUG_INFO(("skipping email: not in output type list\n")); } else { - if (!ff.type) ff.type = item->type; - if ((ff.type != PST_TYPE_NOTE) && (ff.type != PST_TYPE_SCHEDULE) && (ff.type != PST_TYPE_REPORT) && (mode != MODE_SEPARATE)) { - ff.skip_count++; - 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)); + char *extra_mime_headers = NULL; + ff.item_count++; + if (mode == MODE_SEPARATE) { + // process this single email message, possibly forking + pid_t parent = getpid(); + pid_t child = try_fork(item->file_as.str); + if (child == 0) { + // we are the child process, or the original parent if no children were available + pid_t me = getpid(); + mk_separate_file(&ff, PST_TYPE_NOTE, (mode_EX) ? ".eml" : "", 1); + write_normal_email(ff.output[PST_TYPE_NOTE], ff.name[PST_TYPE_NOTE], item, mode, mode_MH, &pstfile, save_rtf_body, PST_TYPE_NOTE, &extra_mime_headers); + close_separate_file(&ff); + if (mode_MSG) { + mk_separate_file(&ff, PST_TYPE_NOTE, ".msg", 0); + write_msg_email(ff.name[PST_TYPE_NOTE], item, &pstfile); + } +#ifdef HAVE_FORK +#ifdef HAVE_SEMAPHORE_H + if (me != parent) { + // we really were a child, forked for the sole purpose of processing this message + // free my child count slot before really exiting, since + // all I am doing here is waiting for my children to exit + sem_post(global_children); + grim_reaper(1); // wait for all my child processes to exit - there should not be any + exit(0); // really exit + } +#endif +#endif + } } else { - char *extra_mime_headers = NULL; - ff.item_count++; - if (mode == MODE_SEPARATE) { - // process this single email message, possibly forking - pid_t parent = getpid(); - pid_t child = try_fork(item->file_as.str); - if (child == 0) { - // we are the child process, or the original parent if no children were available - pid_t me = getpid(); - mk_separate_file(&ff, (mode_EX) ? ".eml" : "", 1); - write_normal_email(ff.output, ff.name, item, mode, mode_MH, &pstfile, save_rtf_body, 0, &extra_mime_headers); - close_separate_file(&ff); - if (mode_MSG) { - mk_separate_file(&ff, ".msg", 0); - write_msg_email(ff.name, item, &pstfile); - } -#ifdef HAVE_FORK -#ifdef HAVE_SEMAPHORE_H - if (me != parent) { - // we really were a child, forked for the sole purpose of processing this message - // free my child count slot before really exiting, since - // all I am doing here is waiting for my children to exit - sem_post(global_children); - grim_reaper(1); // wait for all my child processes to exit - there should not be any - exit(0); // really exit - } -#endif -#endif - } - } - else { - // process this single email message, cannot fork since not separate mode - write_normal_email(ff.output, ff.name, item, mode, mode_MH, &pstfile, save_rtf_body, 0, &extra_mime_headers); - } + // process this single email message, cannot fork since not separate mode + write_normal_email(ff.output[PST_TYPE_NOTE], ff.name[PST_TYPE_NOTE], item, mode, mode_MH, &pstfile, save_rtf_body, 0, &extra_mime_headers); } } @@ -386,18 +370,11 @@ DEBUG_INFO(("skipping journal entry: not in output type list\n")); } else { - if (!ff.type) ff.type = item->type; - if ((ff.type != PST_TYPE_JOURNAL) && (mode != MODE_SEPARATE)) { - ff.skip_count++; - DEBUG_INFO(("I have a journal entry, but the folder type %"PRIi32" isn't a journal folder. Skipping it\n", ff.type)); - } - else { - ff.item_count++; - if (mode == MODE_SEPARATE) mk_separate_file(&ff, (mode_EX) ? ".ics" : "", 1); - write_journal(ff.output, item); - fprintf(ff.output, "\n"); - if (mode == MODE_SEPARATE) close_separate_file(&ff); - } + ff.item_count++; + if (mode == MODE_SEPARATE) mk_separate_file(&ff, PST_TYPE_JOURNAL, (mode_EX) ? ".ics" : "", 1); + write_journal(ff.output[PST_TYPE_JOURNAL], item); + fprintf(ff.output[PST_TYPE_JOURNAL], "\n"); + if (mode == MODE_SEPARATE) close_separate_file(&ff); } } else if (item->appointment && (item->type == PST_TYPE_APPOINTMENT)) { @@ -407,24 +384,17 @@ DEBUG_INFO(("skipping appointment: not in output type list\n")); } else { - if (!ff.type) ff.type = item->type; - if ((ff.type != PST_TYPE_APPOINTMENT) && (mode != MODE_SEPARATE)) { - ff.skip_count++; - DEBUG_INFO(("I have an appointment, but the folder type %"PRIi32" isn't an appointment folder. Skipping it\n", ff.type)); - } - else { - ff.item_count++; - if (mode == MODE_SEPARATE) mk_separate_file(&ff, (mode_EX) ? ".ics" : "", 1); - write_schedule_part_data(ff.output, item, NULL, NULL); - fprintf(ff.output, "\n"); - if (mode == MODE_SEPARATE) close_separate_file(&ff); - } + ff.item_count++; + if (mode == MODE_SEPARATE) mk_separate_file(&ff, PST_TYPE_APPOINTMENT, (mode_EX) ? ".ics" : "", 1); + write_schedule_part_data(ff.output[PST_TYPE_APPOINTMENT], item, NULL, NULL); + fprintf(ff.output[PST_TYPE_APPOINTMENT], "\n"); + if (mode == MODE_SEPARATE) close_separate_file(&ff); } } else if (item->message_store) { // there should only be one message_store, and we have already done it ff.skip_count++; - DEBUG_WARN(("item with message store content, type %i %s folder type %i, skipping it\n", item->type, item->ascii_type, ff.type)); + DEBUG_WARN(("item with message store content, type %i %s, skipping it\n", item->type, item->ascii_type)); } else { ff.skip_count++; @@ -847,11 +817,55 @@ } -// this will create a directory by that name, -// then make an mbox file inside that directory. -char *mk_recurse_dir(char *dir, int32_t folder_type) { +char *item_type_to_name(int32_t item_type) { + char *name; + switch (item_type) { + case PST_TYPE_APPOINTMENT: + name = "calendar"; + break; + case PST_TYPE_CONTACT: + name = "contacts"; + break; + case PST_TYPE_JOURNAL: + name = "journal"; + break; + case PST_TYPE_STICKYNOTE: + case PST_TYPE_TASK: + case PST_TYPE_NOTE: + case PST_TYPE_OTHER: + case PST_TYPE_REPORT: + default: + name = "mbox"; + break; + } + return name; +} + + +int32_t reduced_item_type(int32_t item_type) { + int32_t reduced; + switch (item_type) { + case PST_TYPE_APPOINTMENT: + case PST_TYPE_CONTACT: + case PST_TYPE_JOURNAL: + reduced = item_type; + break; + case PST_TYPE_STICKYNOTE: + case PST_TYPE_TASK: + case PST_TYPE_NOTE: + case PST_TYPE_OTHER: + case PST_TYPE_REPORT: + default: + reduced = PST_TYPE_NOTE; + break; + } + return reduced; +} + + +// this will create a directory by that name +void mk_recurse_dir(char *dir) { int x; - char *out_name; DEBUG_ENT("mk_recurse_dir"); check_filename(dir); if (D_MKDIR (dir)) { @@ -864,27 +878,7 @@ x = errno; DIE(("mk_recurse_dir: Cannot change to directory %s: %s\n", dir, strerror(x))); } - switch (folder_type) { - case PST_TYPE_APPOINTMENT: - out_name = strdup("calendar"); - break; - case PST_TYPE_CONTACT: - out_name = strdup("contacts"); - break; - case PST_TYPE_JOURNAL: - out_name = strdup("journal"); - break; - case PST_TYPE_STICKYNOTE: - case PST_TYPE_TASK: - case PST_TYPE_NOTE: - case PST_TYPE_OTHER: - case PST_TYPE_REPORT: - default: - out_name = strdup("mbox"); - break; - } DEBUG_RET(); - return out_name; } @@ -900,7 +894,7 @@ } -char *mk_separate_dir(char *dir) { +void mk_separate_dir(char *dir) { size_t dirsize = strlen(dir) + 10; char dir_name[dirsize]; int x = 0, y = 0; @@ -953,9 +947,7 @@ #endif } - // we don't return a filename here cause it isn't necessary. DEBUG_RET(); - return NULL; } @@ -971,17 +963,17 @@ } -void mk_separate_file(struct file_ll *f, char *extension, int openit) { +void mk_separate_file(struct file_ll *f, int32_t t, char *extension, int openit) { DEBUG_ENT("mk_separate_file"); DEBUG_INFO(("opening next file to save email\n")); if (f->item_count > 999999999) { // bigger than nine 9's DIE(("mk_separate_file: The number of emails in this folder has become too high to handle\n")); } - sprintf(f->name, SEP_MAIL_FILE_TEMPLATE, f->item_count, extension); - check_filename(f->name); + sprintf(f->name[t], SEP_MAIL_FILE_TEMPLATE, f->item_count, extension); + check_filename(f->name[t]); if (openit) { - if (!(f->output = fopen(f->name, "w"))) { - DIE(("mk_separate_file: Cannot open file to save email \"%s\"\n", f->name)); + if (!(f->output[t] = fopen(f->name[t], "w"))) { + DIE(("mk_separate_file: Cannot open file to save email \"%s\"\n", f->name[t])); } } DEBUG_RET(); @@ -989,16 +981,19 @@ void close_separate_file(struct file_ll *f) { + int32_t t; DEBUG_ENT("close_separate_file"); - if (f->output) { - struct stat st; - fclose(f->output); - stat(f->name, &st); - if (!st.st_size) { - DEBUG_WARN(("removing empty output file %s\n", f->name)); - remove(f->name); + for (t=0; t<PST_TYPE_MAX; t++) { + if (f->output[t]) { + struct stat st; + fclose(f->output[t]); + stat(f->name[t], &st); + if (!st.st_size) { + DEBUG_WARN(("removing empty output file %s\n", f->name[t])); + remove(f->name[t]); + } + f->output[t] = NULL; } - f->output = NULL; } DEBUG_RET(); } @@ -1227,16 +1222,19 @@ // there are surely others. the problem is - given an arbitrary character // string, is it a valid (or even reasonable) set of rfc822 headers? if (header) { - if ((strncasecmp(header, "X-Barracuda-URL: ", 17) == 0) || - (strncasecmp(header, "X-ASG-Debug-ID: ", 16) == 0) || - (strncasecmp(header, "Return-Path: ", 13) == 0) || - (strncasecmp(header, "Received: ", 10) == 0) || - (strncasecmp(header, "Subject: ", 9) == 0) || - (strncasecmp(header, "Date: ", 6) == 0) || - (strncasecmp(header, "From: ", 6) == 0) || - (strncasecmp(header, "X-x: ", 5) == 0) || - (strncasecmp(header, "Microsoft Mail Internet Headers", 31) == 0)) { - return 1; + if ((strncasecmp(header, "Content-Type: ", 14) == 0) || + (strncasecmp(header, "Date: ", 6) == 0) || + (strncasecmp(header, "From: ", 6) == 0) || + (strncasecmp(header, "MIME-Version: ", 14) == 0) || + (strncasecmp(header, "Microsoft Mail Internet Headers", 31) == 0) || + (strncasecmp(header, "Received: ", 10) == 0) || + (strncasecmp(header, "Return-Path: ", 13) == 0) || + (strncasecmp(header, "Subject: ", 9) == 0) || + (strncasecmp(header, "To: ", 4) == 0) || + (strncasecmp(header, "X-ASG-Debug-ID: ", 16) == 0) || + (strncasecmp(header, "X-Barracuda-URL: ", 17) == 0) || + (strncasecmp(header, "X-x: ", 5) == 0)) { + return 1; } else { if (strlen(header) > 2) { @@ -2176,15 +2174,23 @@ void create_enter_dir(struct file_ll* f, pst_item *item) { + memset(f, 0, sizeof(*f)); + f->stored_count = (item->folder) ? item->folder->item_count : 0; pst_convert_utf8(item, &item->file_as); - f->type = item->type; - f->stored_count = (item->folder) ? item->folder->item_count : 0; + f->dname = (char*) pst_malloc(strlen(item->file_as.str)+1); + strcpy(f->dname, item->file_as.str); DEBUG_ENT("create_enter_dir"); if (mode == MODE_KMAIL) - f->name = mk_kmail_dir(item->file_as.str); + f->name[0] = mk_kmail_dir(item->file_as.str); else if (mode == MODE_RECURSE) { - f->name = mk_recurse_dir(item->file_as.str, f->type); + int32_t t; + mk_recurse_dir(item->file_as.str); + for (t=0; t<PST_TYPE_MAX; t++) { + if (t == reduced_item_type(t)) { + f->name[t] = strdup(item_type_to_name(t)); + } + } if (mode_thunder) { FILE *type_file = fopen(".type", "w"); fprintf(type_file, "%d\n", item->type); @@ -2193,46 +2199,47 @@ } else if (mode == MODE_SEPARATE) { // do similar stuff to recurse here. mk_separate_dir(item->file_as.str); - f->name = (char*) pst_malloc(file_name_len); - memset(f->name, 0, file_name_len); + f->name[0] = (char*) pst_malloc(file_name_len); + memset(f->name[0], 0, file_name_len); } else { - f->name = (char*) pst_malloc(strlen(item->file_as.str)+strlen(OUTPUT_TEMPLATE)+1); - sprintf(f->name, OUTPUT_TEMPLATE, item->file_as.str); + f->name[0] = (char*) pst_malloc(strlen(item->file_as.str)+strlen(OUTPUT_TEMPLATE)+1); + sprintf(f->name[0], OUTPUT_TEMPLATE, item->file_as.str); } - f->dname = (char*) pst_malloc(strlen(item->file_as.str)+1); - strcpy(f->dname, item->file_as.str); - - if (overwrite != 1) { - int x = 0; - char *temp = (char*) pst_malloc (strlen(f->name)+10); //enough room for 10 digits + if (mode != MODE_SEPARATE) { + int32_t t; + for (t=0; t<PST_TYPE_MAX; t++) { + if (f->name[t]) { + if (!overwrite) { + int x = 0; + char *temp = (char*) pst_malloc (strlen(f->name[t])+10); //enough room for 10 digits - sprintf(temp, "%s", f->name); - check_filename(temp); - while ((f->output = fopen(temp, "r"))) { - DEBUG_INFO(("need to increase filename because one already exists with that name\n")); - DEBUG_INFO(("- increasing it to %s%d\n", f->name, x)); - x++; - sprintf(temp, "%s%08d", f->name, x); - DEBUG_INFO(("- trying \"%s\"\n", f->name)); - if (x == 99999999) { - DIE(("create_enter_dir: Why can I not create a folder %s? I have tried %i extensions...\n", f->name, x)); + sprintf(temp, "%s", f->name[t]); + check_filename(temp); + while ((f->output[t] = fopen(temp, "r"))) { + DEBUG_INFO(("need to increase filename because one already exists with that name\n")); + DEBUG_INFO(("- increasing it to %s%d\n", f->name, x)); + x++; + sprintf(temp, "%s%08d", f->name, x); + DEBUG_INFO(("- trying \"%s\"\n", f->name)); + if (x == 99999999) { + DIE(("create_enter_dir: Why can I not create a folder %s? I have tried %i extensions...\n", f->name, x)); + } + fclose(f->output[t]); + } + if (x > 0) { //then the f->name should change + free (f->name[t]); + f->name[t] = temp; + } else { + free(temp); + } + } + check_filename(f->name[t]); + if (!(f->output[t] = fopen(f->name[t], "w"))) { + DIE(("create_enter_dir: Could not open file \"%s\" for write\n", f->name[t])); + } + DEBUG_INFO(("f->name = %s\nitem->folder_name = %s\n", f->name[t], item->file_as.str)); } - fclose(f->output); - } - if (x > 0) { //then the f->name should change - free (f->name); - f->name = temp; - } else { - free(temp); - } - } - - DEBUG_INFO(("f->name = %s\nitem->folder_name = %s\n", f->name, item->file_as.str)); - if (mode != MODE_SEPARATE) { - check_filename(f->name); - if (!(f->output = fopen(f->name, "w"))) { - DIE(("create_enter_dir: Could not open file \"%s\" for write\n", f->name)); } } DEBUG_RET(); @@ -2241,6 +2248,7 @@ void close_enter_dir(struct file_ll *f) { + int32_t t; DEBUG_INFO(("processed item count for folder %s is %i, skipped %i, total %i \n", f->dname, f->item_count, f->skip_count, f->stored_count)); if (output_mode != OUTPUT_QUIET) { @@ -2249,18 +2257,21 @@ fflush(stdout); pst_debug_unlock(); } - if (f->output) { - if (mode == MODE_SEPARATE) DEBUG_WARN(("close_enter_dir finds open separate file\n")); - struct stat st; - fclose(f->output); - stat(f->name, &st); - if (!st.st_size) { - DEBUG_WARN(("removing empty output file %s\n", f->name)); - remove(f->name); + for (t=0; t<PST_TYPE_MAX; t++) { + if (f->output[t]) { + if (mode == MODE_SEPARATE) DEBUG_WARN(("close_enter_dir finds open separate file\n")); + struct stat st; + fclose(f->output[t]); + stat(f->name[t], &st); + if (!st.st_size) { + DEBUG_WARN(("removing empty output file %s\n", f->name[t])); + remove(f->name[t]); + } + f->output[t] = NULL; } - f->output = NULL; + free(f->name[t]); + f->name[t] = NULL; } - free(f->name); free(f->dname); if (mode == MODE_KMAIL)
--- a/xml/libpst.in Wed Jul 06 12:14:55 2016 -0700 +++ b/xml/libpst.in Mon Aug 29 09:50:24 2016 -0700 @@ -35,7 +35,7 @@ <refentry id="readpst.1"> <refentryinfo> - <date>2015-03-09</date> + <date>2016-08-29</date> </refentryinfo> <refmeta> @@ -208,10 +208,13 @@ <varlistentry> <term>-r</term> <listitem><para> - Changes the output format to Recursive. This will create folders as - named in the PST file, and will put all emails in a file called "mbox" - inside each folder. These files are then compatible with all - mbox-compatible email clients. This format uses mboxrd from quoting. + Changes the output format to Recursive. This will create folders + as named in the PST file, and will put all emails in a file called + "mbox" inside each folder. Appointments go into a file called + "calendar", address book entries go into a file called "contacts", + and journal entries go into a file called "journal". These files + are then compatible with all mbox-compatible email clients. This + format uses mboxrd from quoting. </para></listitem> </varlistentry> <varlistentry> @@ -302,7 +305,7 @@ <refentry id="lspst.1"> <refentryinfo> - <date>2015-03-09</date> + <date>2016-08-29</date> </refentryinfo> <refmeta> @@ -397,7 +400,7 @@ <refentry id="pst2ldif.1"> <refentryinfo> - <date>2015-03-09</date> + <date>2016-08-29</date> </refentryinfo> <refmeta> @@ -565,7 +568,7 @@ <refentry id="pst2dii.1"> <refentryinfo> - <date>2015-03-09</date> + <date>2016-08-29</date> </refentryinfo> <refmeta> @@ -698,7 +701,7 @@ <refentry id="pst.5"> <refentryinfo> - <date>2015-03-09</date> + <date>2016-08-29</date> </refentryinfo> <refmeta> @@ -1687,7 +1690,7 @@ 0x1035 Message ID 0x1042 In-Reply-To or Parent's Message ID 0x1046 Return Path -0x3001 Folder Name? I have seen this value used for the contacts record aswell +0x3001 Folder Name? I have also seen this value used for the contacts record 0x3002 Address Type 0x3003 Contact Address 0x3004 Comment