comparison src/readpst.c @ 367:6b7c19a820e1

fix bugs in code allowing folders containing multiple item types
author Carl Byington <carl@five-ten-sg.com>
date Mon, 24 Oct 2016 11:11:02 -0700
parents 67a3ee227495
children 0ccc746c8079
comparison
equal deleted inserted replaced
366:67a3ee227495 367:6b7c19a820e1
7 7
8 #include "define.h" 8 #include "define.h"
9 #include "lzfu.h" 9 #include "lzfu.h"
10 #include "msg.h" 10 #include "msg.h"
11 11
12 #define OUTPUT_TEMPLATE "%s" 12 #define OUTPUT_TEMPLATE "%s.%s"
13 #define OUTPUT_KMAIL_DIR_TEMPLATE ".%s.directory" 13 #define OUTPUT_KMAIL_DIR_TEMPLATE ".%s.directory"
14 #define KMAIL_INDEX ".%s.index" 14 #define KMAIL_INDEX "../.%s.index"
15 #define SEP_MAIL_FILE_TEMPLATE "%i%s" 15 #define SEP_MAIL_FILE_TEMPLATE "%i%s"
16 16
17 // max size of the c_time char*. It will store the date of the email 17 // max size of the c_time char*. It will store the date of the email
18 #define C_TIME_SIZE 500 18 #define C_TIME_SIZE 500
19 19
31 void process(pst_item *outeritem, pst_desc_tree *d_ptr); 31 void process(pst_item *outeritem, pst_desc_tree *d_ptr);
32 void write_email_body(FILE *f, char *body); 32 void write_email_body(FILE *f, char *body);
33 void removeCR(char *c); 33 void removeCR(char *c);
34 void usage(); 34 void usage();
35 void version(); 35 void version();
36 char* mk_kmail_dir(char* fname); 36 void mk_kmail_dir(char* fname);
37 int close_kmail_dir(); 37 int close_kmail_dir();
38 void mk_recurse_dir(char* dir); 38 void mk_recurse_dir(char* dir);
39 int close_recurse_dir(); 39 int close_recurse_dir();
40 void mk_separate_dir(char *dir); 40 void mk_separate_dir(char *dir);
41 int close_separate_dir(); 41 int close_separate_dir();
67 void create_enter_dir(struct file_ll* f, pst_item *item); 67 void create_enter_dir(struct file_ll* f, pst_item *item);
68 void close_enter_dir(struct file_ll *f); 68 void close_enter_dir(struct file_ll *f);
69 69
70 const char* prog_name; 70 const char* prog_name;
71 char* output_dir = "."; 71 char* output_dir = ".";
72 char* kmail_chdir = NULL;
73 72
74 // Normal mode just creates mbox format files in the current directory. Each file is named 73 // Normal mode just creates mbox format files in the current directory. Each file is named
75 // the same as the folder's name that it represents 74 // the same as the folder's name that it represents
76 #define MODE_NORMAL 0 75 #define MODE_NORMAL 0
77 76
759 #endif 758 #endif
760 DEBUG_RET(); 759 DEBUG_RET();
761 } 760 }
762 761
763 762
764 char *mk_kmail_dir(char *fname) { 763 void mk_kmail_dir(char *fname) {
764 //make a directory based on OUTPUT_KMAIL_DIR_TEMPLATE
765 //change to that directory 765 //change to that directory
766 //make a directory based on OUTPUT_KMAIL_DIR_TEMPLATE 766 char *dir, *index;
767 //allocate space for OUTPUT_TEMPLATE and form a char* with fname
768 //return that value
769 char *dir, *out_name, *index;
770 int x; 767 int x;
771 DEBUG_ENT("mk_kmail_dir"); 768 DEBUG_ENT("mk_kmail_dir");
772 if (kmail_chdir && chdir(kmail_chdir)) {
773 x = errno;
774 DIE(("mk_kmail_dir: Cannot change to directory %s: %s\n", kmail_chdir, strerror(x)));
775 }
776 dir = pst_malloc(strlen(fname)+strlen(OUTPUT_KMAIL_DIR_TEMPLATE)+1); 769 dir = pst_malloc(strlen(fname)+strlen(OUTPUT_KMAIL_DIR_TEMPLATE)+1);
777 sprintf(dir, OUTPUT_KMAIL_DIR_TEMPLATE, fname); 770 sprintf(dir, OUTPUT_KMAIL_DIR_TEMPLATE, fname);
778 check_filename(dir); 771 check_filename(dir);
779 if (D_MKDIR(dir)) { 772 if (D_MKDIR(dir)) {
780 if (errno != EEXIST) { // not an error because it exists 773 if (errno != EEXIST) { // not an error because it exists
781 x = errno; 774 x = errno;
782 DIE(("mk_kmail_dir: Cannot create directory %s: %s\n", dir, strerror(x))); 775 DIE(("mk_kmail_dir: Cannot create directory %s: %s\n", dir, strerror(x)));
783 } 776 }
784 } 777 }
785 kmail_chdir = pst_realloc(kmail_chdir, strlen(dir)+1); 778 if (chdir(dir)) {
786 strcpy(kmail_chdir, dir); 779 x = errno;
780 DIE(("mk_kmail_dir: Cannot change to directory %s: %s\n", dir, strerror(x)));
781 }
787 free (dir); 782 free (dir);
788 783
789 //we should remove any existing indexes created by KMail, cause they might be different now 784 //we should remove any existing indexes created by KMail, cause they might be different now
790 index = pst_malloc(strlen(fname)+strlen(KMAIL_INDEX)+1); 785 index = pst_malloc(strlen(fname)+strlen(KMAIL_INDEX)+1);
791 sprintf(index, KMAIL_INDEX, fname); 786 sprintf(index, KMAIL_INDEX, fname);
792 unlink(index); 787 unlink(index);
793 free(index); 788 free(index);
794 789
795 out_name = pst_malloc(strlen(fname)+strlen(OUTPUT_TEMPLATE)+1); 790 DEBUG_RET();
796 sprintf(out_name, OUTPUT_TEMPLATE, fname);
797 DEBUG_RET();
798 return out_name;
799 } 791 }
800 792
801 793
802 int close_kmail_dir() { 794 int close_kmail_dir() {
803 // change ..
804 int x; 795 int x;
805 DEBUG_ENT("close_kmail_dir"); 796 DEBUG_ENT("close_kmail_dir");
806 if (kmail_chdir) { //only free kmail_chdir if not NULL. do not change directory 797 if (chdir("..")) {
807 free(kmail_chdir); 798 x = errno;
808 kmail_chdir = NULL; 799 DIE(("close_kmail_dir: Cannot move up dir (..): %s\n", strerror(x)));
809 } else {
810 if (chdir("..")) {
811 x = errno;
812 DIE(("close_kmail_dir: Cannot move up dir (..): %s\n", strerror(x)));
813 }
814 } 800 }
815 DEBUG_RET(); 801 DEBUG_RET();
816 return 0; 802 return 0;
817 } 803 }
818 804
872 if (errno != EEXIST) { // not an error because it exists 858 if (errno != EEXIST) { // not an error because it exists
873 x = errno; 859 x = errno;
874 DIE(("mk_recurse_dir: Cannot create directory %s: %s\n", dir, strerror(x))); 860 DIE(("mk_recurse_dir: Cannot create directory %s: %s\n", dir, strerror(x)));
875 } 861 }
876 } 862 }
877 if (chdir (dir)) { 863 if (chdir(dir)) {
878 x = errno; 864 x = errno;
879 DIE(("mk_recurse_dir: Cannot change to directory %s: %s\n", dir, strerror(x))); 865 DIE(("mk_recurse_dir: Cannot change to directory %s: %s\n", dir, strerror(x)));
880 } 866 }
881 DEBUG_RET(); 867 DEBUG_RET();
882 } 868 }
963 } 949 }
964 950
965 951
966 void mk_separate_file(struct file_ll *f, int32_t t, char *extension, int openit) { 952 void mk_separate_file(struct file_ll *f, int32_t t, char *extension, int openit) {
967 DEBUG_ENT("mk_separate_file"); 953 DEBUG_ENT("mk_separate_file");
968 DEBUG_INFO(("opening next file to save email\n")); 954 DEBUG_INFO(("opening next file to save email type %s\n", item_type_to_name(t)));
969 if (f->item_count > 999999999) { // bigger than nine 9's 955 if (f->item_count > 999999999) { // bigger than nine 9's
970 DIE(("mk_separate_file: The number of emails in this folder has become too high to handle\n")); 956 DIE(("mk_separate_file: The number of emails in this folder has become too high to handle\n"));
971 } 957 }
972 sprintf(f->name[t], SEP_MAIL_FILE_TEMPLATE, f->item_count, extension); 958 sprintf(f->name[t], SEP_MAIL_FILE_TEMPLATE, f->item_count, extension);
973 check_filename(f->name[t]); 959 check_filename(f->name[t]);
2186 pst_convert_utf8(item, &item->file_as); 2172 pst_convert_utf8(item, &item->file_as);
2187 f->dname = (char*) pst_malloc(strlen(item->file_as.str)+1); 2173 f->dname = (char*) pst_malloc(strlen(item->file_as.str)+1);
2188 strcpy(f->dname, item->file_as.str); 2174 strcpy(f->dname, item->file_as.str);
2189 2175
2190 DEBUG_ENT("create_enter_dir"); 2176 DEBUG_ENT("create_enter_dir");
2191 if (mode == MODE_KMAIL) 2177 if (mode == MODE_KMAIL) {
2192 f->name[0] = mk_kmail_dir(item->file_as.str); 2178 int32_t t;
2193 else if (mode == MODE_RECURSE) { 2179 mk_kmail_dir(item->file_as.str);
2180 for (t=0; t<PST_TYPE_MAX; t++) {
2181 if (t == reduced_item_type(t)) {
2182 f->name[t] = (char*) pst_malloc(strlen(item->file_as.str)+strlen(OUTPUT_TEMPLATE)+30);
2183 sprintf(f->name[t], OUTPUT_TEMPLATE, item->file_as.str, item_type_to_name(t));
2184 }
2185 }
2186 } else if (mode == MODE_RECURSE) {
2194 int32_t t; 2187 int32_t t;
2195 mk_recurse_dir(item->file_as.str); 2188 mk_recurse_dir(item->file_as.str);
2196 for (t=0; t<PST_TYPE_MAX; t++) { 2189 for (t=0; t<PST_TYPE_MAX; t++) {
2197 if (t == reduced_item_type(t)) { 2190 if (t == reduced_item_type(t)) {
2198 f->name[t] = strdup(item_type_to_name(t)); 2191 f->name[t] = strdup(item_type_to_name(t));
2203 fprintf(type_file, "%d\n", item->type); 2196 fprintf(type_file, "%d\n", item->type);
2204 fclose(type_file); 2197 fclose(type_file);
2205 } 2198 }
2206 } else if (mode == MODE_SEPARATE) { 2199 } else if (mode == MODE_SEPARATE) {
2207 // do similar stuff to recurse here. 2200 // do similar stuff to recurse here.
2201 int32_t t;
2208 mk_separate_dir(item->file_as.str); 2202 mk_separate_dir(item->file_as.str);
2209 f->name[0] = (char*) pst_malloc(file_name_len); 2203 for (t=0; t<PST_TYPE_MAX; t++) {
2210 memset(f->name[0], 0, file_name_len); 2204 if (t == reduced_item_type(t)) {
2205 f->name[t] = (char*) pst_malloc(file_name_len);
2206 memset(f->name[t], 0, file_name_len);
2207 }
2208 }
2211 } else { 2209 } else {
2212 f->name[0] = (char*) pst_malloc(strlen(item->file_as.str)+strlen(OUTPUT_TEMPLATE)+1); 2210 // MODE_NORMAL
2213 sprintf(f->name[0], OUTPUT_TEMPLATE, item->file_as.str); 2211 int32_t t;
2212 for (t=0; t<PST_TYPE_MAX; t++) {
2213 if (t == reduced_item_type(t)) {
2214 f->name[t] = (char*) pst_malloc(strlen(item->file_as.str)+strlen(OUTPUT_TEMPLATE)+30);
2215 sprintf(f->name[t], OUTPUT_TEMPLATE, item->file_as.str, item_type_to_name(t));
2216 }
2217 }
2214 } 2218 }
2215 2219
2216 if (mode != MODE_SEPARATE) { 2220 if (mode != MODE_SEPARATE) {
2217 int32_t t; 2221 int32_t t;
2218 for (t=0; t<PST_TYPE_MAX; t++) { 2222 for (t=0; t<PST_TYPE_MAX; t++) {
2264 pst_debug_unlock(); 2268 pst_debug_unlock();
2265 } 2269 }
2266 for (t=0; t<PST_TYPE_MAX; t++) { 2270 for (t=0; t<PST_TYPE_MAX; t++) {
2267 if (f->output[t]) { 2271 if (f->output[t]) {
2268 if (mode == MODE_SEPARATE) DEBUG_WARN(("close_enter_dir finds open separate file\n")); 2272 if (mode == MODE_SEPARATE) DEBUG_WARN(("close_enter_dir finds open separate file\n"));
2273 fclose(f->output[t]);
2274 f->output[t] = NULL;
2275 }
2276 if (f->name[t]) {
2269 struct stat st; 2277 struct stat st;
2270 fclose(f->output[t]);
2271 stat(f->name[t], &st); 2278 stat(f->name[t], &st);
2272 if (!st.st_size) { 2279 if (!st.st_size) {
2273 DEBUG_WARN(("removing empty output file %s\n", f->name[t])); 2280 DEBUG_WARN(("removing empty output file %s\n", f->name[t]));
2274 remove(f->name[t]); 2281 remove(f->name[t]);
2275 } 2282 }
2276 f->output[t] = NULL; 2283 free(f->name[t]);
2277 } 2284 f->name[t] = NULL;
2278 free(f->name[t]); 2285 }
2279 f->name[t] = NULL;
2280 } 2286 }
2281 free(f->dname); 2287 free(f->dname);
2282 2288
2283 if (mode == MODE_KMAIL) 2289 if (mode == MODE_KMAIL)
2284 close_kmail_dir(); 2290 close_kmail_dir();