Mercurial > libpst
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(); |