Mercurial > libpst
comparison readpst.c @ 6:3484500f514e
revert to vendor branch, since I don't care about this part
author | carl |
---|---|
date | Thu, 23 Dec 2004 11:44:01 -0800 |
parents | 8dd68d722fa8 |
children | 3f2fedec798c |
comparison
equal
deleted
inserted
replaced
5:3e9cea0af4a1 | 6:3484500f514e |
---|---|
1 /*** | 1 /*** |
2 * readpst.c | 2 * readpst.c |
3 * Part of the LibPST project | 3 * Part of the LibPST project |
4 * Written by David Smith | 4 * Written by David Smith |
5 * dave.s@earthcorp.com | 5 * dave.s@earthcorp.com |
6 */ | 6 */ |
7 // Includes {{{1 | |
7 #include <stdio.h> | 8 #include <stdio.h> |
8 #include <stdlib.h> | 9 #include <stdlib.h> |
9 #include <time.h> | 10 #include <time.h> |
10 #include <string.h> | 11 #include <string.h> |
11 #include <ctype.h> | 12 #include <ctype.h> |
34 #include "define.h" | 35 #include "define.h" |
35 #include "libpst.h" | 36 #include "libpst.h" |
36 #include "common.h" | 37 #include "common.h" |
37 #include "timeconv.h" | 38 #include "timeconv.h" |
38 #include "lzfu.h" | 39 #include "lzfu.h" |
39 | 40 // }}}1 |
41 // Defines {{{1 | |
40 #define OUTPUT_TEMPLATE "%s" | 42 #define OUTPUT_TEMPLATE "%s" |
41 #define OUTPUT_KMAIL_DIR_TEMPLATE ".%s.directory" | 43 #define OUTPUT_KMAIL_DIR_TEMPLATE ".%s.directory" |
42 #define KMAIL_INDEX ".%s.index" | 44 #define KMAIL_INDEX ".%s.index" |
43 | 45 |
44 #define VERSION "0.5" | 46 #define VERSION "0.5.1" |
45 // max size of the c_time char*. It will store the date of the email | 47 // max size of the c_time char*. It will store the date of the email |
46 #define C_TIME_SIZE 500 | 48 #define C_TIME_SIZE 500 |
47 #define PERM_DIRS 0777 | 49 #define PERM_DIRS 0777 |
48 | 50 |
49 // macro used for creating directories | 51 // macro used for creating directories |
50 #ifndef WIN32 | 52 #ifndef WIN32 |
51 #define D_MKDIR(x) mkdir(x, PERM_DIRS) | 53 #define D_MKDIR(x) mkdir(x, PERM_DIRS) |
52 #else | 54 #else |
53 #define D_MKDIR(x) mkdir(x) | 55 #define D_MKDIR(x) mkdir(x) |
54 #endif | 56 #endif |
55 | 57 // }}}1 |
58 // struct file_ll {{{1 | |
56 struct file_ll { | 59 struct file_ll { |
57 char *name; | 60 char *name; |
58 char *dname; | 61 char *dname; |
59 FILE * output; | 62 FILE * output; |
60 int32_t stored_count; | 63 int32_t stored_count; |
61 int32_t email_count; | 64 int32_t email_count; |
62 int32_t skip_count; | 65 int32_t skip_count; |
63 int32_t type; | 66 int32_t type; |
64 struct file_ll *next; | 67 struct file_ll *next; |
65 }; | 68 }; |
66 | 69 // }}}1 |
67 | 70 // Function Declarations {{{1 |
68 void write_email_body(FILE *f, char *body); | 71 void write_email_body(FILE *f, char *body); |
69 char *removeCR (char *c); | 72 char *removeCR (char *c); |
70 int32_t usage(); | 73 int32_t usage(); |
71 int32_t version(); | 74 int32_t version(); |
72 char *mk_kmail_dir(char*); | 75 char *mk_kmail_dir(char*); |
80 char *check_filename(char *fname); | 83 char *check_filename(char *fname); |
81 char *rfc2426_escape(char *str); | 84 char *rfc2426_escape(char *str); |
82 int32_t chr_count(char *str, char x); | 85 int32_t chr_count(char *str, char x); |
83 char *rfc2425_datetime_format(FILETIME *ft); | 86 char *rfc2425_datetime_format(FILETIME *ft); |
84 char *rfc2445_datetime_format(FILETIME *ft); | 87 char *rfc2445_datetime_format(FILETIME *ft); |
85 | 88 char *skip_header_prologue(char *headers); |
89 // }}}1 | |
90 // Global Variables {{{1 | |
86 char *prog_name; | 91 char *prog_name; |
87 char *output_dir = "."; | 92 char *output_dir = "."; |
88 | 93 char *kmail_chdir = NULL; |
94 // }}}1 | |
95 // More Defines {{{1 | |
89 // Normal mode just creates mbox format files in the current directory. Each file is named | 96 // Normal mode just creates mbox format files in the current directory. Each file is named |
90 // the same as the folder's name that it represents | 97 // the same as the folder's name that it represents |
91 #define MODE_NORMAL 0 | 98 #define MODE_NORMAL 0 |
92 // KMail mode creates a directory structure suitable for being used directly | 99 // KMail mode creates a directory structure suitable for being used directly |
93 // by the KMail application | 100 // by the KMail application |
117 // output settings for RTF bodies | 124 // output settings for RTF bodies |
118 // filename for the attachment | 125 // filename for the attachment |
119 #define RTF_ATTACH_NAME "rtf-body.rtf" | 126 #define RTF_ATTACH_NAME "rtf-body.rtf" |
120 // mime type for the attachment | 127 // mime type for the attachment |
121 #define RTF_ATTACH_TYPE "application/rtf" | 128 #define RTF_ATTACH_TYPE "application/rtf" |
122 | 129 // }}}1 |
130 // int main(int argc, char** argv) {{{1 | |
123 int main(int argc, char** argv) { | 131 int main(int argc, char** argv) { |
124 pst_item *item = NULL; | 132 // declarations {{{2 |
125 pst_file pstfile; | 133 pst_item *item = NULL; |
126 pst_desc_ll *d_ptr; | 134 pst_file pstfile; |
127 char * fname = NULL; | 135 pst_desc_ll *d_ptr; |
128 time_t em_time; | 136 char * fname = NULL; |
129 char * c_time, *d_log=NULL; | 137 time_t em_time; |
130 int c,x; | 138 char * c_time, *d_log=NULL; |
131 int mode = MODE_NORMAL; | 139 int c,x; |
132 int output_mode = OUTPUT_NORMAL; | 140 int mode = MODE_NORMAL; |
133 int contact_mode = CMODE_VCARD; | 141 int output_mode = OUTPUT_NORMAL; |
134 int overwrite = 0; | 142 int contact_mode = CMODE_VCARD; |
135 int base64_body = 0; | 143 int overwrite = 0; |
136 // int encrypt = 0; | 144 int base64_body = 0; |
137 FILE *fp; | 145 // int encrypt = 0; |
138 char *enc; // base64 encoded attachment | 146 FILE *fp; |
139 char *boundary = NULL, *b1, *b2; // the boundary marker between multipart sections | 147 char *enc; // base64 encoded attachment |
140 char *temp = NULL; //temporary char pointer | 148 char *boundary = NULL, *b1, *b2; // the boundary marker between multipart sections |
141 int attach_num = 0; | 149 char *temp = NULL; //temporary char pointer |
142 int skip_child = 0; | 150 int attach_num = 0; |
143 struct file_ll *f, *head; | 151 int skip_child = 0; |
144 prog_name = argv[0]; | 152 struct file_ll *f, *head; |
145 | 153 prog_name = argv[0]; |
146 while ((c = getopt(argc, argv, "d:hko:qrSVwc:"))!= -1) { | 154 // }}}2 |
147 switch (c) { | 155 |
148 case 'c': | 156 while ((c = getopt(argc, argv, "d:hko:qrSVwc:"))!= -1) { |
149 if (optarg!=NULL && optarg[0]=='v') | 157 switch (c) { |
150 contact_mode=CMODE_VCARD; | 158 case 'c': |
151 else if (optarg!=NULL && optarg[0]=='l') | 159 if (optarg!=NULL && optarg[0]=='v') |
152 contact_mode=CMODE_LIST; | 160 contact_mode=CMODE_VCARD; |
153 else { | 161 else if (optarg!=NULL && optarg[0]=='l') |
154 usage(); | 162 contact_mode=CMODE_LIST; |
155 exit(0); | 163 else { |
156 } | 164 usage(); |
157 break; | 165 exit(0); |
158 case 'd': | 166 } |
159 d_log = optarg; | 167 break; |
160 break; | 168 case 'd': |
161 case 'h': | 169 d_log = optarg; |
162 usage(); | 170 break; |
163 exit(0); | 171 case 'h': |
164 break; | 172 usage(); |
165 case 'V': | 173 exit(0); |
166 version(); | 174 break; |
167 exit(0); | 175 case 'V': |
168 break; | 176 version(); |
169 case 'k': | 177 exit(0); |
170 mode = MODE_KMAIL; | 178 break; |
171 break; | 179 case 'k': |
172 case 'o': | 180 mode = MODE_KMAIL; |
173 output_dir = optarg; | 181 break; |
174 break; | 182 case 'o': |
175 case 'q': | 183 output_dir = optarg; |
176 output_mode = OUTPUT_QUIET; | 184 break; |
177 break; | 185 case 'q': |
178 case 'r': | 186 output_mode = OUTPUT_QUIET; |
179 mode = MODE_RECURSE; | 187 break; |
180 break; | 188 case 'r': |
181 case 'S': | 189 mode = MODE_RECURSE; |
182 mode = MODE_SEPERATE; | 190 break; |
183 break; | 191 case 'S': |
184 case 'w': | 192 mode = MODE_SEPERATE; |
185 overwrite = 1; | 193 break; |
186 break; | 194 case 'w': |
187 default: | 195 overwrite = 1; |
188 usage(); | 196 break; |
189 exit(1); | 197 default: |
190 break; | 198 usage(); |
191 } | 199 exit(1); |
192 } | 200 break; |
193 | 201 } |
194 if (d_log == NULL) | 202 } |
195 d_log = "readpst.log"; | 203 |
196 DEBUG_INIT(d_log); | 204 #ifdef DEBUG_ALL |
197 DEBUG_REGISTER_CLOSE(); | 205 // initialize log file |
198 DEBUG_ENT("main"); | 206 if (d_log == NULL) |
199 | 207 d_log = "readpst.log"; |
200 if (argc > optind) { | 208 DEBUG_INIT(d_log); |
201 fname = argv[optind]; | 209 DEBUG_REGISTER_CLOSE(); |
210 #endif // defined DEBUG_ALL | |
211 | |
212 DEBUG_ENT("main"); | |
213 | |
214 if (argc > optind) { | |
215 fname = argv[optind]; | |
216 } else { | |
217 usage(); | |
218 exit(2); | |
219 } | |
220 | |
221 if (output_mode != OUTPUT_QUIET) printf("Opening PST file and indexes...\n"); | |
222 | |
223 DEBUG_MAIN(("main: Opening PST file '%s'\n", fname)); | |
224 RET_DERROR(pst_open(&pstfile, fname, "r"), 1, ("Error opening File\n")); | |
225 DEBUG_MAIN(("main: Loading Indexes\n")); | |
226 RET_DERROR(pst_load_index(&pstfile), 2, ("Index Error\n")); | |
227 DEBUG_MAIN(("processing file items\n")); | |
228 | |
229 pst_load_extended_attributes(&pstfile); | |
230 | |
231 if (chdir(output_dir)) { | |
232 x = errno; | |
233 pst_close(&pstfile); | |
234 DIE(("main: Cannot change to output dir %s: %s\n", output_dir, strerror(x))); | |
235 } | |
236 | |
237 if (output_mode != OUTPUT_QUIET) printf("About to start processing first record...\n"); | |
238 | |
239 d_ptr = pstfile.d_head; // first record is main record | |
240 if ((item = _pst_parse_item(&pstfile, d_ptr)) == NULL || item->message_store == NULL) { | |
241 DIE(("main: Could not get root record\n")); | |
242 } | |
243 | |
244 // default the file_as to the same as the main filename if it doesn't exist | |
245 if (item->file_as == NULL) { | |
246 if ((temp = strrchr(fname, '/')) == NULL) | |
247 if ((temp = strrchr(fname, '\\')) == NULL) | |
248 temp = fname; | |
249 else | |
250 temp++; // get past the "\\" | |
251 else | |
252 temp++; // get past the "/" | |
253 item->file_as = (char*)xmalloc(strlen(temp)+1); | |
254 strcpy(item->file_as, temp); | |
255 DEBUG_MAIN(("file_as was blank, so am using %s\n", item->file_as)); | |
256 } | |
257 DEBUG_MAIN(("main: Root Folder Name: %s\n", item->file_as)); | |
258 | |
259 | |
260 f = (struct file_ll*) malloc(sizeof(struct file_ll)); | |
261 memset(f, 0, sizeof(struct file_ll)); | |
262 f->email_count = 0; | |
263 f->skip_count = 0; | |
264 f->next = NULL; | |
265 head = f; | |
266 if (mode == MODE_KMAIL) | |
267 f->name = mk_kmail_dir(item->file_as); | |
268 else if (mode == MODE_RECURSE) | |
269 f->name = mk_recurse_dir(item->file_as); | |
270 else if (mode == MODE_SEPERATE) { | |
271 // do similar stuff to recurse here. | |
272 mk_seperate_dir(item->file_as, overwrite); | |
273 f->name = (char*) xmalloc(10); | |
274 sprintf(f->name, "%09i", f->email_count); | |
275 } else { | |
276 f->name = (char*) malloc(strlen(item->file_as)+strlen(OUTPUT_TEMPLATE)+1); | |
277 sprintf(f->name, OUTPUT_TEMPLATE, item->file_as); | |
278 } | |
279 | |
280 f->dname = (char*) malloc(strlen(item->file_as)+1); | |
281 strcpy(f->dname, item->file_as); | |
282 | |
283 if (overwrite != 1 && mode != MODE_SEPERATE) { | |
284 // if overwrite is set to 1 we keep the existing name and don't modify anything | |
285 // we don't want to go changing the file name of the SEPERATE items | |
286 temp = (char*) malloc (strlen(f->name)+10); //enough room for 10 digits | |
287 sprintf(temp, "%s", f->name); | |
288 temp = check_filename(temp); | |
289 x = 0; | |
290 while ((f->output = fopen(temp, "r")) != NULL) { | |
291 DEBUG_MAIN(("main: need to increase filename cause one already exists with that name\n")); | |
292 DEBUG_MAIN(("main: - increasing it to %s%d\n", f->name, x)); | |
293 x++; | |
294 sprintf(temp, "%s%08d", f->name, x); | |
295 DEBUG_MAIN(("main: - trying \"%s\"\n", temp)); | |
296 if (x == 99999999) { | |
297 DIE(("main: Why can I not create a folder %s? I have tried %i extensions...\n", f->name, x)); | |
298 } | |
299 fclose(f->output); | |
300 } | |
301 if (x > 0) { //then the f->name should change | |
302 free (f->name); | |
303 f->name = temp; | |
202 } else { | 304 } else { |
203 usage(); | 305 free (temp); |
204 exit(2); | 306 } |
205 } | 307 } |
206 | 308 if (mode != MODE_SEPERATE) { |
207 if (output_mode != OUTPUT_QUIET) printf("Opening PST file and indexes...\n"); | 309 f->name = check_filename(f->name); |
208 | 310 if ((f->output = fopen(f->name, "w")) == NULL) { |
209 DEBUG_MAIN(("main: Opening PST file '%s'\n", fname)); | 311 DIE(("main: Could not open file \"%s\" for write\n", f->name)); |
210 RET_DERROR(pst_open(&pstfile, fname, "r"), 1, ("Error opening File\n")); | 312 } |
211 DEBUG_MAIN(("main: Loading Indexes\n")); | 313 } |
212 RET_DERROR(pst_load_index(&pstfile), 2, ("Index Error\n")); | 314 f->type = item->type; |
213 DEBUG_MAIN(("processing file items\n")); | 315 |
214 | 316 if ((d_ptr = pst_getTopOfFolders(&pstfile, item)) == NULL) { |
215 pst_load_extended_attributes(&pstfile); | 317 DIE(("Top of folders record not found. Cannot continue\n")); |
216 | 318 } |
217 if (chdir(output_dir)) { | 319 |
218 x = errno; | 320 if (item){ |
219 pst_close(&pstfile); | 321 _pst_freeItem(item); |
220 DIE(("main: Cannot change to output dir %s: %s\n", output_dir, strerror(x))); | 322 item = NULL; |
221 } | 323 } |
222 | 324 |
223 if (output_mode != OUTPUT_QUIET) printf("About to start processing first record...\n"); | 325 /* if ((item = _pst_parse_item(&pstfile, d_ptr)) == NULL || item->folder == NULL) { |
224 | 326 DEBUG_MAIN(("main: Could not get \"Top Of Personal Folder\" record\n")); |
225 d_ptr = pstfile.d_head; // first record is main record | 327 return -2; |
226 if ((item = _pst_parse_item(&pstfile, d_ptr)) == NULL || item->message_store == NULL) { | 328 }*/ |
227 DIE(("main: Could not get root record\n")); | 329 d_ptr = d_ptr->child; // do the children of TOPF |
228 } | 330 |
229 | 331 if (output_mode != OUTPUT_QUIET) printf("Processing items...\n"); |
230 // default the file_as to the same as the main filename if it doesn't exist | 332 |
231 if (item->file_as == NULL) { | 333 DEBUG_MAIN(("main: About to do email stuff\n")); |
232 if ((temp = strrchr(fname, '/')) == NULL) | 334 while (d_ptr != NULL) { |
233 if ((temp = strrchr(fname, '\\')) == NULL) | 335 DEBUG_MAIN(("main: New item record\n")); |
234 temp = fname; | 336 if (d_ptr->desc == NULL) { |
235 else | 337 DEBUG_WARN(("main: ERROR ?? item's desc record is NULL\n")); |
236 temp++; // get past the "\\" | 338 f->skip_count++; |
237 else | 339 goto check_parent; |
238 temp++; // get past the "/" | 340 } |
239 item->file_as = (char*)xmalloc(strlen(temp)+1); | 341 DEBUG_MAIN(("main: Desc Email ID %#x [d_ptr->id = %#x]\n", d_ptr->desc->id, d_ptr->id)); |
240 strcpy(item->file_as, temp); | 342 |
241 DEBUG_MAIN(("file_as was blank, so am using %s\n", item->file_as)); | 343 item = _pst_parse_item(&pstfile, d_ptr); |
242 } | 344 DEBUG_MAIN(("main: About to process item\n")); |
243 DEBUG_MAIN(("main: Root Folder Name: %s\n", item->file_as)); | 345 if (item != NULL && item->email != NULL && item->email->subject != NULL && |
244 | 346 item->email->subject->subj != NULL) { |
245 | 347 // DEBUG_EMAIL(("item->email->subject = %p\n", item->email->subject)); |
348 // DEBUG_EMAIL(("item->email->subject->subj = %p\n", item->email->subject->subj)); | |
349 } | |
350 if (item != NULL) { | |
351 if (item->message_store != NULL) { | |
352 // there should only be one message_store, and we have already done it | |
353 DIE(("main: A second message_store has been found. Sorry, this must be an error.\n")); | |
354 } | |
355 | |
356 | |
357 if (item->folder != NULL) { | |
358 // Process Folder item {{{2 | |
359 // if this is a folder, we want to recurse into it | |
360 if (output_mode != OUTPUT_QUIET) printf("Processing Folder \"%s\"\n", item->file_as); | |
361 // f->email_count++; | |
362 DEBUG_MAIN(("main: I think I may try to go into folder \"%s\"\n", item->file_as)); | |
246 f = (struct file_ll*) malloc(sizeof(struct file_ll)); | 363 f = (struct file_ll*) malloc(sizeof(struct file_ll)); |
247 memset(f, 0, sizeof(struct file_ll)); | 364 memset(f, 0, sizeof(struct file_ll)); |
365 | |
366 f->next = head; | |
248 f->email_count = 0; | 367 f->email_count = 0; |
249 f->skip_count = 0; | 368 f->type = item->type; |
250 f->next = NULL; | 369 f->stored_count = item->folder->email_count; |
251 head = f; | 370 head = f; |
371 | |
372 temp = item->file_as; | |
373 temp = check_filename(temp); | |
374 | |
252 if (mode == MODE_KMAIL) | 375 if (mode == MODE_KMAIL) |
253 f->name = mk_kmail_dir(item->file_as); | 376 f->name = mk_kmail_dir(item->file_as); //create directory and form filename |
254 else if (mode == MODE_RECURSE) | 377 else if (mode == MODE_RECURSE) |
255 f->name = mk_recurse_dir(item->file_as); | 378 f->name = mk_recurse_dir(item->file_as); |
256 else if (mode == MODE_SEPERATE) { | 379 else if (mode == MODE_SEPERATE) { |
257 // do similar stuff to recurse here. | 380 // do similar stuff to recurse here. |
258 mk_seperate_dir(item->file_as, overwrite); | 381 mk_seperate_dir(item->file_as, overwrite); |
259 f->name = (char*) xmalloc(10); | 382 f->name = (char*) xmalloc(10); |
260 sprintf(f->name, "%09i", f->email_count); | 383 memset(f->name, 0, 10); |
384 // sprintf(f->name, "%09i", f->email_count); | |
261 } else { | 385 } else { |
262 f->name = (char*) malloc(strlen(item->file_as)+strlen(OUTPUT_TEMPLATE)+1); | 386 f->name = (char*) xmalloc(strlen(item->file_as)+strlen(OUTPUT_TEMPLATE+1)); |
263 sprintf(f->name, OUTPUT_TEMPLATE, item->file_as); | 387 sprintf(f->name, OUTPUT_TEMPLATE, item->file_as); |
264 } | 388 } |
265 | 389 |
266 f->dname = (char*) malloc(strlen(item->file_as)+1); | 390 f->dname = (char*) xmalloc(strlen(item->file_as)+1); |
267 strcpy(f->dname, item->file_as); | 391 strcpy(f->dname, item->file_as); |
268 | 392 |
269 if (overwrite != 1 && mode != MODE_SEPERATE) { | 393 if (overwrite != 1) { |
270 // if overwrite is set to 1 we keep the existing name and don't modify anything | 394 temp = (char*) xmalloc (strlen(f->name)+10); //enough room for 10 digits |
271 // we don't want to go changing the file name of the SEPERATE items | 395 sprintf(temp, "%s", f->name); |
272 temp = (char*) malloc (strlen(f->name)+10); //enough room for 10 digits | 396 x = 0; |
273 sprintf(temp, "%s", f->name); | 397 temp = check_filename(temp); |
274 temp = check_filename(temp); | 398 while ((f->output = fopen(temp, "r")) != NULL) { |
275 x = 0; | 399 DEBUG_MAIN(("main: need to increase filename cause one already exists with that name\n")); |
276 while ((f->output = fopen(temp, "r")) != NULL) { | 400 DEBUG_MAIN(("main: - increasing it to %s%d\n", f->name, x)); |
277 DEBUG_MAIN(("main: need to increase filename cause one already exists with that name\n")); | 401 x++; |
278 DEBUG_MAIN(("main: - increasing it to %s%d\n", f->name, x)); | 402 sprintf(temp, "%s%08d", f->name, x); |
279 x++; | 403 DEBUG_MAIN(("main: - trying \"%s\"\n", f->name)); |
280 sprintf(temp, "%s%08d", f->name, x); | 404 if (x == 99999999) { |
281 DEBUG_MAIN(("main: - trying \"%s\"\n", temp)); | 405 DIE(("main: Why can I not create a folder %s? I have tried %i extensions...\n", f->name, x)); |
282 if (x == 99999999) { | |
283 DIE(("main: Why can I not create a folder %s? I have tried %i extensions...\n", f->name, x)); | |
284 } | |
285 fclose(f->output); | |
286 } | 406 } |
287 if (x > 0) { //then the f->name should change | 407 fclose(f->output); |
288 free (f->name); | 408 } |
289 f->name = temp; | 409 if (x > 0) { //then the f->name should change |
410 free (f->name); | |
411 f->name = temp; | |
412 } else { | |
413 free(temp); | |
414 } | |
415 } | |
416 | |
417 DEBUG_MAIN(("main: f->name = %s\nitem->folder_name = %s\n", f->name, item->file_as)); | |
418 if (mode != MODE_SEPERATE) { | |
419 f->name = check_filename(f->name); | |
420 if ((f->output = fopen(f->name, "w")) == NULL) { | |
421 DIE(("main: Could not open file \"%s\" for write\n", f->name)); | |
422 } | |
423 } | |
424 if (d_ptr->child != NULL) { | |
425 d_ptr = d_ptr->child; | |
426 skip_child = 1; | |
427 } else { | |
428 DEBUG_MAIN(("main: Folder has NO children. Creating directory, and closing again\n")); | |
429 if (output_mode != OUTPUT_QUIET) | |
430 printf("\tNo items to process in folder \"%s\", should have been %i\n", f->dname, f->stored_count); | |
431 head = f->next; | |
432 if (f->output != NULL) | |
433 fclose(f->output); | |
434 if (mode == MODE_KMAIL) | |
435 close_kmail_dir(); | |
436 else if (mode == MODE_RECURSE) | |
437 close_recurse_dir(); | |
438 else if (mode == MODE_SEPERATE) | |
439 close_seperate_dir(); | |
440 free(f->dname); | |
441 free(f->name); | |
442 free(f); | |
443 | |
444 f = head; | |
445 } | |
446 _pst_freeItem(item); | |
447 item = NULL; // just for the odd situations! | |
448 goto check_parent; | |
449 // }}}2 | |
450 } else if (item->contact != NULL) { | |
451 // Process Contact item {{{2 | |
452 // deal with a contact | |
453 // write them to the file, one per line in this format | |
454 // Desc Name <email@address>\n | |
455 if (mode == MODE_SEPERATE) { | |
456 mk_seperate_file(f); | |
457 } | |
458 f->email_count++; | |
459 | |
460 DEBUG_MAIN(("main: Processing Contact\n")); | |
461 if (f->type != PST_TYPE_CONTACT) { | |
462 DEBUG_MAIN(("main: I have a contact, but the folder isn't a contacts folder. " | |
463 "Will process anyway\n")); | |
464 } | |
465 if (item->type != PST_TYPE_CONTACT) { | |
466 DEBUG_MAIN(("main: I have an item that has contact info, but doesn't say that" | |
467 " it is a contact. Type is \"%s\"\n", item->ascii_type)); | |
468 DEBUG_MAIN(("main: Processing anyway\n")); | |
469 } | |
470 if (item->contact == NULL) { // this is an incorrect situation. Inform user | |
471 DEBUG_MAIN(("main: ERROR. This contact has not been fully parsed. one of the pre-requisties is NULL\n")); | |
472 } else { | |
473 if (contact_mode == CMODE_VCARD) { | |
474 // the specification I am following is (hopefully) RFC2426 vCard Mime Directory Profile | |
475 fprintf(f->output, "BEGIN:VCARD\n"); | |
476 fprintf(f->output, "FN:%s\n", rfc2426_escape(item->contact->fullname)); | |
477 fprintf(f->output, "N:%s;%s;%s;%s;%s\n", | |
478 rfc2426_escape((item->contact->surname==NULL?"":item->contact->surname)), | |
479 rfc2426_escape((item->contact->first_name==NULL?"":item->contact->first_name)), | |
480 rfc2426_escape((item->contact->middle_name==NULL?"":item->contact->middle_name)), | |
481 rfc2426_escape((item->contact->display_name_prefix==NULL?"":item->contact->display_name_prefix)), | |
482 rfc2426_escape((item->contact->suffix==NULL?"":item->contact->suffix))); | |
483 if (item->contact->nickname != NULL) | |
484 fprintf(f->output, "NICKNAME:%s\n", rfc2426_escape(item->contact->nickname)); | |
485 if (item->contact->address1 != NULL) | |
486 fprintf(f->output, "EMAIL:%s\n", rfc2426_escape(item->contact->address1)); | |
487 if (item->contact->address2 != NULL) | |
488 fprintf(f->output, "EMAIL:%s\n", rfc2426_escape(item->contact->address2)); | |
489 if (item->contact->address3 != NULL) | |
490 fprintf(f->output, "EMAIL:%s\n", rfc2426_escape(item->contact->address3)); | |
491 if (item->contact->birthday != NULL) | |
492 fprintf(f->output, "BDAY:%s\n", rfc2425_datetime_format(item->contact->birthday)); | |
493 if (item->contact->home_address != NULL) { | |
494 fprintf(f->output, "ADR;TYPE=home:%s;%s;%s;%s;%s;%s;%s\n", | |
495 rfc2426_escape((item->contact->home_po_box!=NULL?item->contact->home_po_box:"")), | |
496 "", // extended Address | |
497 rfc2426_escape((item->contact->home_street!=NULL?item->contact->home_street:"")), | |
498 rfc2426_escape((item->contact->home_city!=NULL?item->contact->home_city:"")), | |
499 rfc2426_escape((item->contact->home_state!=NULL?item->contact->home_state:"")), | |
500 rfc2426_escape((item->contact->home_postal_code!=NULL?item->contact->home_postal_code:"")), | |
501 rfc2426_escape((item->contact->home_country!=NULL?item->contact->home_country:""))); | |
502 fprintf(f->output, "LABEL;TYPE=home:%s\n", rfc2426_escape(item->contact->home_address)); | |
503 } | |
504 if (item->contact->business_address != NULL) { | |
505 fprintf(f->output, "ADR;TYPE=work:%s;%s;%s;%s;%s;%s;%s\n", | |
506 rfc2426_escape((item->contact->business_po_box!=NULL?item->contact->business_po_box:"")), | |
507 "", // extended Address | |
508 rfc2426_escape((item->contact->business_street!=NULL?item->contact->business_street:"")), | |
509 rfc2426_escape((item->contact->business_city!=NULL?item->contact->business_city:"")), | |
510 rfc2426_escape((item->contact->business_state!=NULL?item->contact->business_state:"")), | |
511 rfc2426_escape((item->contact->business_postal_code!=NULL?item->contact->business_postal_code:"")), | |
512 rfc2426_escape((item->contact->business_country!=NULL?item->contact->business_country:""))); | |
513 fprintf(f->output, "LABEL;TYPE=work:%s\n", rfc2426_escape(item->contact->business_address)); | |
514 } | |
515 if (item->contact->other_address != NULL) { | |
516 fprintf(f->output, "ADR;TYPE=postal:%s;%s;%s;%s;%s;%s;%s\n", | |
517 rfc2426_escape((item->contact->other_po_box!=NULL?item->contact->business_po_box:"")), | |
518 "", // extended Address | |
519 rfc2426_escape((item->contact->other_street!=NULL?item->contact->other_street:"")), | |
520 rfc2426_escape((item->contact->other_city!=NULL?item->contact->other_city:"")), | |
521 rfc2426_escape((item->contact->other_state!=NULL?item->contact->other_state:"")), | |
522 rfc2426_escape((item->contact->other_postal_code!=NULL?item->contact->other_postal_code:"")), | |
523 rfc2426_escape((item->contact->other_country!=NULL?item->contact->other_country:""))); | |
524 fprintf(f->output, "ADR;TYPE=postal:%s\n", rfc2426_escape(item->contact->other_address)); | |
525 } | |
526 if (item->contact->business_fax != NULL) | |
527 fprintf(f->output, "TEL;TYPE=work,fax:%s\n", rfc2426_escape(item->contact->business_fax)); | |
528 if (item->contact->business_phone != NULL) | |
529 fprintf(f->output, "TEL;TYPE=work,voice:%s\n", rfc2426_escape(item->contact->business_phone)); | |
530 if (item->contact->business_phone2 != NULL) | |
531 fprintf(f->output, "TEL;TYPE=work,voice:%s\n", rfc2426_escape(item->contact->business_phone2)); | |
532 if (item->contact->car_phone != NULL) | |
533 fprintf(f->output, "TEL;TYPE=car,voice:%s\n", rfc2426_escape(item->contact->car_phone)); | |
534 if (item->contact->home_fax != NULL) | |
535 fprintf(f->output, "TEL;TYPE=home,fax:%s\n", rfc2426_escape(item->contact->home_fax)); | |
536 if (item->contact->home_phone != NULL) | |
537 fprintf(f->output, "TEL;TYPE=home,voice:%s\n", rfc2426_escape(item->contact->home_phone)); | |
538 if (item->contact->home_phone2 != NULL) | |
539 fprintf(f->output, "TEL;TYPE=home,voice:%s\n", rfc2426_escape(item->contact->home_phone2)); | |
540 if (item->contact->isdn_phone != NULL) | |
541 fprintf(f->output, "TEL;TYPE=isdn:%s\n", rfc2426_escape(item->contact->isdn_phone)); | |
542 if (item->contact->mobile_phone != NULL) | |
543 fprintf(f->output, "TEL;TYPE=cell,voice:%s\n", rfc2426_escape(item->contact->mobile_phone)); | |
544 if (item->contact->other_phone != NULL) | |
545 fprintf(f->output, "TEL;TYPE=msg:%s\n", rfc2426_escape(item->contact->other_phone)); | |
546 if (item->contact->pager_phone != NULL) | |
547 fprintf(f->output, "TEL;TYPE=pager:%s\n", rfc2426_escape(item->contact->pager_phone)); | |
548 if (item->contact->primary_fax != NULL) | |
549 fprintf(f->output, "TEL;TYPE=fax,pref:%s\n", rfc2426_escape(item->contact->primary_fax)); | |
550 if (item->contact->primary_phone != NULL) | |
551 fprintf(f->output, "TEL;TYPE=phone,pref:%s\n", rfc2426_escape(item->contact->primary_phone)); | |
552 if (item->contact->radio_phone != NULL) | |
553 fprintf(f->output, "TEL;TYPE=pcs:%s\n", rfc2426_escape(item->contact->radio_phone)); | |
554 if (item->contact->telex != NULL) | |
555 fprintf(f->output, "TEL;TYPE=bbs:%s\n", rfc2426_escape(item->contact->telex)); | |
556 if (item->contact->job_title != NULL) | |
557 fprintf(f->output, "TITLE:%s\n", rfc2426_escape(item->contact->job_title)); | |
558 if (item->contact->profession != NULL) | |
559 fprintf(f->output, "ROLE:%s\n", rfc2426_escape(item->contact->profession)); | |
560 if (item->contact->assistant_name != NULL || item->contact->assistant_phone != NULL) { | |
561 fprintf(f->output, "AGENT:BEGIN:VCARD\\n"); | |
562 if (item->contact->assistant_name != NULL) | |
563 fprintf(f->output, "FN:%s\\n", rfc2426_escape(item->contact->assistant_name)); | |
564 if (item->contact->assistant_phone != NULL) | |
565 fprintf(f->output, "TEL:%s\\n", rfc2426_escape(item->contact->assistant_phone)); | |
566 fprintf(f->output, "END:VCARD\\n\n"); | |
567 } | |
568 if (item->contact->company_name != NULL) | |
569 fprintf(f->output, "ORG:%s\n", rfc2426_escape(item->contact->company_name)); | |
570 if (item->comment != NULL) | |
571 fprintf(f->output, "NOTE:%s\n", rfc2426_escape(item->comment)); | |
572 | |
573 fprintf(f->output, "VERSION: 3.0\n"); | |
574 fprintf(f->output, "END:VCARD\n\n"); | |
575 } else { | |
576 fprintf(f->output, "%s <%s>\n", item->contact->fullname, item->contact->address1); | |
577 } | |
578 } | |
579 // }}}2 | |
580 } else if (item->email != NULL && | |
581 (item->type == PST_TYPE_NOTE || item->type == PST_TYPE_REPORT)) { | |
582 // Process Email item {{{2 | |
583 if (mode == MODE_SEPERATE) { | |
584 mk_seperate_file(f); | |
585 } | |
586 | |
587 f->email_count++; | |
588 | |
589 DEBUG_MAIN(("main: seen an email\n")); | |
590 | |
591 // convert the sent date if it exists, or set it to a fixed date | |
592 if (item->email->sent_date != NULL) { | |
593 em_time = fileTimeToUnixTime(item->email->sent_date, 0); | |
594 c_time = ctime(&em_time); | |
595 if (c_time != NULL) | |
596 c_time[strlen(c_time)-1] = '\0'; //remove end \n | |
597 else | |
598 c_time = "Fri Dec 28 12:06:21 2001"; | |
599 } else | |
600 c_time= "Fri Dec 28 12:06:21 2001"; | |
601 | |
602 // if the boundary is still set from the previous run, then free it | |
603 if (boundary != NULL) { | |
604 free (boundary); | |
605 boundary = NULL; | |
606 } | |
607 | |
608 // we will always look at the header to discover some stuff | |
609 if (item->email->header != NULL ) { | |
610 // see if there is a boundary variable there | |
611 // this search MUST be made case insensitive (DONE). | |
612 // Also, some check to find out if we | |
613 // are looking at the boundary associated with content-type, and that the content | |
614 // type really is "multipart" | |
615 if ((b2 = my_stristr(item->email->header, "boundary=")) != NULL) { | |
616 b2 += strlen("boundary="); // move boundary to first char of marker | |
617 | |
618 if (*b2 == '"') { | |
619 b2++; | |
620 b1 = strchr(b2, '"'); // find terminating quote | |
290 } else { | 621 } else { |
291 free (temp); | 622 b1 = b2; |
623 while (isgraph(*b1)) // find first char that isn't part of boundary | |
624 b1++; | |
292 } | 625 } |
626 | |
627 boundary = malloc ((b1-b2)+1); //malloc that length | |
628 memset (boundary, 0, (b1-b2)+1); // blank it | |
629 strncpy(boundary, b2, b1-b2); // copy boundary to another variable | |
630 b1 = b2 = boundary; | |
631 while (*b2 != '\0') { // remove any CRs and Tabs | |
632 if (*b2 != '\n' && *b2 != '\r' && *b2 != '\t') { | |
633 *b1 = *b2; | |
634 b1++; | |
635 } | |
636 b2++; | |
637 } | |
638 *b1 = '\0'; | |
639 | |
640 DEBUG_MAIN(("main: Found boundary of - %s\n", boundary)); | |
641 } else { | |
642 | |
643 DEBUG_MAIN(("main: boundary not found in header\n")); | |
644 } | |
645 | |
646 // also possible to set 7bit encoding detection here. | |
647 if ((b2 = my_stristr(item->email->header, "Content-Transfer-Encoding:")) != NULL) { | |
648 if ((b2 = strchr(b2, ':')) != NULL) { | |
649 b2++; // skip to the : at the end of the string | |
650 | |
651 while (*b2 == ' ' || *b2 == '\t') | |
652 b2++; | |
653 if (pst_strincmp(b2, "base64", 6)==0) { | |
654 DEBUG_MAIN(("body is base64 encoded\n")); | |
655 base64_body = 1; | |
656 } | |
657 } else { | |
658 DEBUG_WARN(("found a ':' during the my_stristr, but not after that..\n")); | |
659 } | |
660 } | |
661 | |
662 } | |
663 if (boundary == NULL && (item->attach ||(item->email->body && item->email->htmlbody) | |
664 || item->email->rtf_compressed || item->email->encrypted_body | |
665 || item->email->encrypted_htmlbody)) { | |
666 // we need to create a boundary here. | |
667 DEBUG_EMAIL(("main: must create own boundary. oh dear.\n")); | |
668 boundary = malloc(50 * sizeof(char)); // allow 50 chars for boundary | |
669 boundary[0] = '\0'; | |
670 sprintf(boundary, "--boundary-LibPST-iamunique-%i_-_-", rand()); | |
671 DEBUG_EMAIL(("main: created boundary is %s\n", boundary)); | |
672 } | |
673 | |
674 DEBUG_MAIN(("main: About to print Header\n")); | |
675 | |
676 if (item != NULL && item->email != NULL && item->email->subject != NULL && | |
677 item->email->subject->subj != NULL) { | |
678 DEBUG_EMAIL(("item->email->subject->subj = %p\n", item->email->subject->subj)); | |
679 } | |
680 if (item->email->header != NULL) { | |
681 // some of the headers we get from the file are not properly defined. | |
682 // they can contain some email stuff too. We will cut off the header | |
683 // when we see a \n\n or \r\n\r\n | |
684 | |
685 removeCR(item->email->header); | |
686 | |
687 temp = strstr(item->email->header, "\n\n"); | |
688 | |
689 if (temp != NULL) { | |
690 DEBUG_MAIN(("main: Found body text in header\n")); | |
691 temp += 2; // get past the \n\n | |
692 *temp = '\0'; | |
693 } | |
694 | |
695 if (mode != MODE_SEPERATE) { | |
696 char *soh = NULL; // real start of headers. | |
697 // don't put rubbish in if we are doing seperate | |
698 fprintf(f->output, "From \"%s\" %s\n", item->email->outlook_sender_name, c_time); | |
699 soh = skip_header_prologue(item->email->header); | |
700 fprintf(f->output, "%s\n\n", soh); | |
701 } else { | |
702 fprintf(f->output, "%s\n", item->email->header); | |
703 } | |
704 } else { | |
705 //make up our own header! | |
706 if (mode != MODE_SEPERATE) { | |
707 // don't want this first line for this mode | |
708 if (item->email->outlook_sender_name != NULL) { | |
709 temp = item->email->outlook_sender_name; | |
710 } else { | |
711 temp = "(readpst_null)"; | |
712 } | |
713 fprintf(f->output, "From \"%s\" %s\n", temp, c_time); | |
714 } | |
715 if ((temp = item->email->outlook_sender) == NULL) | |
716 temp = ""; | |
717 fprintf(f->output, "From: \"%s\" <%s>\n", item->email->outlook_sender_name, temp); | |
718 if (item->email->subject != NULL) { | |
719 fprintf(f->output, "Subject: %s\n", item->email->subject->subj); | |
720 } else { | |
721 fprintf(f->output, "Subject: \n"); | |
722 } | |
723 fprintf(f->output, "To: %s\n", item->email->sentto_address); | |
724 if (item->email->cc_address != NULL) { | |
725 fprintf(f->output, "CC: %s\n", item->email->cc_address); | |
726 } | |
727 if (item->email->sent_date != NULL) { | |
728 c_time = (char*) xmalloc(C_TIME_SIZE); | |
729 strftime(c_time, C_TIME_SIZE, "%a, %d %b %Y %H:%M:%S %z", gmtime(&em_time)); | |
730 fprintf(f->output, "Date: %s\n", c_time); | |
731 free(c_time); | |
732 } | |
733 | |
734 fprintf(f->output, "MIME-Version: 1.0\n"); | |
735 if (item->attach != NULL) { | |
736 // write the boundary stuff if we have attachments | |
737 fprintf(f->output, "Content-type: multipart/mixed;\n\tboundary=\"%s\"\n", | |
738 boundary); | |
739 } else if (item->email->htmlbody && item->email->body) { | |
740 // else if we have an html and text body then tell it so | |
741 fprintf(f->output, "Content-type: multipart/alternate;\n\tboundary=\"%s\"\n", | |
742 boundary); | |
743 } else if (item->email->htmlbody) { | |
744 fprintf(f->output, "Content-type: text/html\n"); | |
745 } | |
746 fprintf(f->output, "\n"); | |
747 } | |
748 | |
749 | |
750 DEBUG_MAIN(("main: About to print Body\n")); | |
751 | |
752 if (item->email->body != NULL) { | |
753 if (boundary) { | |
754 fprintf(f->output, "\n--%s\n", boundary); | |
755 fprintf(f->output, "Content-type: text/plain\n\n"); | |
756 if (base64_body) | |
757 fprintf(f->output, "Content-Transfer-Encoding: base64\n"); | |
758 } | |
759 removeCR(item->email->body); | |
760 if (base64_body) | |
761 write_email_body(f->output, base64_encode(item->email->body, | |
762 strlen(item->email->body))); | |
763 else | |
764 write_email_body(f->output, item->email->body); | |
765 } | |
766 | |
767 if (item->email->htmlbody != NULL) { | |
768 if (boundary) { | |
769 fprintf(f->output, "\n--%s\n", boundary); | |
770 fprintf(f->output, "Content-type: text/html\n\n"); | |
771 if (base64_body) | |
772 fprintf(f->output, "Content-Transfer-Encoding: base64\n"); | |
773 } | |
774 removeCR(item->email->htmlbody); | |
775 if (base64_body) | |
776 write_email_body(f->output, base64_encode(item->email->htmlbody, | |
777 strlen(item->email->htmlbody))); | |
778 else | |
779 write_email_body(f->output, item->email->htmlbody); | |
780 } | |
781 | |
782 attach_num = 0; | |
783 | |
784 if (item->email->rtf_compressed != NULL) { | |
785 DEBUG_MAIN(("Adding RTF body as attachment\n")); | |
786 item->current_attach = (pst_item_attach*)xmalloc(sizeof(pst_item_attach)); | |
787 memset(item->current_attach, 0, sizeof(pst_item_attach)); | |
788 item->current_attach->next = item->attach; | |
789 item->attach = item->current_attach; | |
790 item->current_attach->data = lzfu_decompress(item->email->rtf_compressed); | |
791 item->current_attach->filename2 = xmalloc(strlen(RTF_ATTACH_NAME)+2); | |
792 strcpy(item->current_attach->filename2, RTF_ATTACH_NAME); | |
793 item->current_attach->mimetype = xmalloc(strlen(RTF_ATTACH_TYPE)+2); | |
794 strcpy(item->current_attach->mimetype, RTF_ATTACH_TYPE); | |
795 memcpy(&(item->current_attach->size), item->email->rtf_compressed+sizeof(int32_t), sizeof(int32_t)); | |
796 LE32_CPU(item->current_attach->size); | |
797 // item->email->rtf_compressed = ; | |
798 // attach_num++; | |
799 } | |
800 if (item->email->encrypted_body || item->email->encrypted_htmlbody) { | |
801 // if either the body or htmlbody is encrypted, add them as attachments | |
802 if (item->email->encrypted_body) { | |
803 DEBUG_MAIN(("Adding Encrypted Body as attachment\n")); | |
804 item->current_attach = (pst_item_attach*) xmalloc(sizeof(pst_item_attach)); | |
805 memset(item->current_attach, 0, sizeof(pst_item_attach)); | |
806 item->current_attach->next = item->attach; | |
807 item->attach = item->current_attach; | |
808 | |
809 item->current_attach->data = item->email->encrypted_body; | |
810 item->current_attach->size = item->email->encrypted_body_size; | |
811 item->email->encrypted_body = NULL; | |
812 } | |
813 if (item->email->encrypted_htmlbody) { | |
814 DEBUG_MAIN(("Adding encrypted HTML body as attachment\n")); | |
815 item->current_attach = (pst_item_attach*) xmalloc(sizeof(pst_item_attach)); | |
816 memset(item->current_attach, 0, sizeof(pst_item_attach)); | |
817 item->current_attach->next = item->attach; | |
818 item->attach = item->current_attach; | |
819 | |
820 item->current_attach->data = item->email->encrypted_htmlbody; | |
821 item->current_attach->size = item->email->encrypted_htmlbody_size; | |
822 item->email->encrypted_htmlbody = NULL; | |
823 } | |
824 write_email_body(f->output, "The body of this email is encrypted. This isn't supported yet, but the body is now an attachment\n"); | |
825 } | |
826 base64_body = 0; | |
827 // attachments | |
828 item->current_attach = item->attach; | |
829 while (item->current_attach != NULL) { | |
830 DEBUG_MAIN(("main: Attempting Attachment encoding\n")); | |
831 if (item->current_attach->data == NULL) { | |
832 DEBUG_MAIN(("main: Data of attachment is NULL!. Size is supposed to be %i\n", item->current_attach->size)); | |
833 } | |
834 if (mode == MODE_SEPERATE) { | |
835 f->name = check_filename(f->name); | |
836 if (item->current_attach->filename2 == NULL) { | |
837 temp = xmalloc(strlen(f->name)+15); | |
838 sprintf(temp, "%s-attach%i", f->name, attach_num); | |
839 } else { | |
840 temp = xmalloc(strlen(f->name)+strlen(item->current_attach->filename2)+15); | |
841 fp = NULL; x=0; | |
842 do { | |
843 if (fp != NULL) fclose(fp); | |
844 if (x == 0) | |
845 sprintf(temp, "%s-%s", f->name, item->current_attach->filename2); | |
846 else | |
847 sprintf(temp, "%s-%s-%i", f->name, item->current_attach->filename2, x); | |
848 } while ((fp = fopen(temp, "r"))!=NULL && ++x < 99999999); | |
849 if (x > 99999999) { | |
850 DIE(("error finding attachment name. exhausted possibilities to %s\n", temp)); | |
851 } | |
852 } | |
853 DEBUG_MAIN(("main: Saving attachment to %s\n", temp)); | |
854 if ((fp = fopen(temp, "w")) == NULL) { | |
855 WARN(("main: Cannot open attachment save file \"%s\"\n", temp)); | |
856 } else { | |
857 if (item->current_attach->data != NULL) | |
858 fwrite(item->current_attach->data, 1, item->current_attach->size, fp); | |
859 else { | |
860 pst_attach_to_file(&pstfile, item->current_attach, fp); | |
861 } | |
862 fclose(fp); | |
863 } | |
864 } else { | |
865 DEBUG_MAIN(("main: Attachment Size is %i\n", item->current_attach->size)); | |
866 DEBUG_MAIN(("main: Attachment Pointer is %p\n", item->current_attach->data)); | |
867 if (item->current_attach->data != NULL) { | |
868 if ((enc = base64_encode (item->current_attach->data, item->current_attach->size)) == NULL) { | |
869 DEBUG_MAIN(("main: ERROR base64_encode returned NULL. Must have failed\n")); | |
870 item->current_attach = item->current_attach->next; | |
871 continue; | |
872 } | |
873 } | |
874 if (boundary) { | |
875 fprintf(f->output, "\n--%s\n", boundary); | |
876 if (item->current_attach->mimetype == NULL) { | |
877 fprintf(f->output, "Content-type: %s\n", MIME_TYPE_DEFAULT); | |
878 } else { | |
879 fprintf(f->output, "Content-type: %s\n", item->current_attach->mimetype); | |
880 } | |
881 fprintf(f->output, "Content-transfer-encoding: base64\n"); | |
882 if (item->current_attach->filename2 == NULL) { | |
883 fprintf(f->output, "Content-Disposition: inline\n\n"); | |
884 } else { | |
885 fprintf(f->output, "Content-Disposition: attachment; filename=\"%s\"\n\n", | |
886 item->current_attach->filename2); | |
887 } | |
888 } | |
889 if (item->current_attach->data != NULL) { | |
890 fwrite(enc, 1, strlen(enc), f->output); | |
891 DEBUG_MAIN(("Attachment Size after encoding is %i\n", strlen(enc))); | |
892 } else { | |
893 pst_attach_to_file_base64(&pstfile, item->current_attach, f->output); | |
894 } | |
895 fprintf(f->output, "\n\n"); | |
896 } | |
897 item->current_attach = item->current_attach->next; | |
898 attach_num++; | |
293 } | 899 } |
294 if (mode != MODE_SEPERATE) { | 900 if (mode != MODE_SEPERATE) { |
295 f->name = check_filename(f->name); | 901 DEBUG_MAIN(("main: Writing buffer between emails\n")); |
296 if ((f->output = fopen(f->name, "w")) == NULL) { | 902 if (boundary) |
297 DIE(("main: Could not open file \"%s\" for write\n", f->name)); | 903 fprintf(f->output, "\n--%s--\n", boundary); |
298 } | 904 fprintf(f->output, "\n\n"); |
299 } | 905 } |
300 f->type = item->type; | 906 // }}}2 |
301 | 907 } else if (item->type == PST_TYPE_JOURNAL) { |
302 if ((d_ptr = pst_getTopOfFolders(&pstfile, item)) == NULL) { | 908 // Process Journal item {{{2 |
303 DIE(("Top of folders record not found. Cannot continue\n")); | 909 // deal with journal items |
304 } | 910 if (mode == MODE_SEPERATE) { |
305 | 911 mk_seperate_file(f); |
306 if (item){ | 912 } |
307 _pst_freeItem(item); | 913 f->email_count++; |
308 item = NULL; | 914 |
309 } | 915 DEBUG_MAIN(("main: Processing Journal Entry\n")); |
310 | 916 if (f->type != PST_TYPE_JOURNAL) { |
311 /* if ((item = _pst_parse_item(&pstfile, d_ptr)) == NULL || item->folder == NULL) { | 917 DEBUG_MAIN(("main: I have a journal entry, but folder isn't specified as a journal type. Processing...\n")); |
312 DEBUG_MAIN(("main: Could not get \"Top Of Personal Folder\" record\n")); | 918 } |
313 return -2; | 919 |
314 }*/ | 920 /* if (item->type != PST_TYPE_JOURNAL) { |
315 d_ptr = d_ptr->child; // do the children of TOPF | 921 DEBUG_MAIN(("main: I have an item with journal info, but it's type is \"%s\" \n. Processing...\n", |
316 | 922 item->ascii_type)); |
317 if (output_mode != OUTPUT_QUIET) printf("Processing items...\n"); | 923 }*/ |
318 | 924 fprintf(f->output, "BEGIN:VJOURNAL\n"); |
319 DEBUG_MAIN(("main: About to do email stuff\n")); | 925 if (item->email->subject != NULL) |
320 while (d_ptr != NULL) { | 926 fprintf(f->output, "SUMMARY:%s\n", rfc2426_escape(item->email->subject->subj)); |
321 DEBUG_MAIN(("main: New item record\n")); | 927 if (item->email->body != NULL) |
322 if (d_ptr->desc == NULL) { | 928 fprintf(f->output, "DESCRIPTION:%s\n", rfc2426_escape(item->email->body)); |
323 DEBUG_WARN(("main: ERROR ?? item's desc record is NULL\n")); | 929 if (item->journal->start != NULL) |
324 f->skip_count++; | 930 fprintf(f->output, "DTSTART;VALUE=DATE-TIME:%s\n", rfc2445_datetime_format(item->journal->start)); |
325 goto check_parent; | 931 fprintf(f->output, "END:VJOURNAL\n\n"); |
326 } | 932 // }}}2 |
327 DEBUG_MAIN(("main: Desc Email ID %#x [d_ptr->id = %#x]\n", d_ptr->desc->id, d_ptr->id)); | 933 } else if (item->type == PST_TYPE_APPOINTMENT) { |
328 | 934 // Process Calendar Appointment item {{{2 |
329 item = _pst_parse_item(&pstfile, d_ptr); | 935 // deal with Calendar appointments |
330 DEBUG_MAIN(("main: About to process item\n")); | 936 if (mode == MODE_SEPERATE) { |
331 if (item != NULL && item->email != NULL && item->email->subject != NULL && | 937 mk_seperate_file(f); |
332 item->email->subject->subj != NULL) { | 938 } |
333 // DEBUG_EMAIL(("item->email->subject = %p\n", item->email->subject)); | 939 f->email_count++; |
334 // DEBUG_EMAIL(("item->email->subject->subj = %p\n", item->email->subject->subj)); | 940 |
335 } | 941 DEBUG_MAIN(("main: Processing Appointment Entry\n")); |
336 if (item != NULL) { | 942 if (f->type != PST_TYPE_APPOINTMENT) { |
337 if (item->message_store != NULL) { | 943 DEBUG_MAIN(("main: I have an appointment, but folder isn't specified as an appointment type. Processing...\n")); |
338 // there should only be one message_store, and we have already done it | 944 } |
339 DIE(("main: A second message_store has been found. Sorry, this must be an error.\n")); | 945 fprintf(f->output, "BEGIN:VEVENT\n"); |
340 } | 946 if (item->create_date != NULL) |
341 | 947 fprintf(f->output, "CREATED:%s\n", rfc2445_datetime_format(item->create_date)); |
342 | 948 if (item->modify_date != NULL) |
343 if (item->folder != NULL) { //if this is a folder, we want to recurse into it | 949 fprintf(f->output, "LAST-MOD:%s\n", rfc2445_datetime_format(item->modify_date)); |
344 if (output_mode != OUTPUT_QUIET) printf("Processing Folder \"%s\"\n", item->file_as); | 950 if (item->email != NULL && item->email->subject != NULL) |
345 // f->email_count++; | 951 fprintf(f->output, "SUMMARY:%s\n", rfc2426_escape(item->email->subject->subj)); |
346 DEBUG_MAIN(("main: I think I may try to go into folder \"%s\"\n", item->file_as)); | 952 if (item->email != NULL && item->email->body != NULL) |
347 f = (struct file_ll*) malloc(sizeof(struct file_ll)); | 953 fprintf(f->output, "DESCRIPTION:%s\n", rfc2426_escape(item->email->body)); |
348 memset(f, 0, sizeof(struct file_ll)); | 954 if (item->appointment != NULL && item->appointment->start != NULL) |
349 | 955 fprintf(f->output, "DTSTART;VALUE=DATE-TIME:%s\n", rfc2445_datetime_format(item->appointment->start)); |
350 f->next = head; | 956 if (item->appointment != NULL && item->appointment->end != NULL) |
351 f->email_count = 0; | 957 fprintf(f->output, "DTEND;VALUE=DATE-TIME:%s\n", rfc2445_datetime_format(item->appointment->end)); |
352 f->type = item->type; | 958 if (item->appointment != NULL && item->appointment->location != NULL) |
353 f->stored_count = item->folder->email_count; | 959 fprintf(f->output, "LOCATION:%s\n", rfc2426_escape(item->appointment->location)); |
354 head = f; | 960 if (item->appointment != NULL) { |
355 | 961 switch (item->appointment->showas) { |
356 temp = item->file_as; | 962 case PST_FREEBUSY_TENTATIVE: |
357 temp = check_filename(temp); | 963 fprintf(f->output, "STATUS:TENTATIVE\n"); |
358 | 964 break; |
359 if (mode == MODE_KMAIL) | 965 case PST_FREEBUSY_FREE: |
360 f->name = mk_kmail_dir(item->file_as); //create directory and form filename | 966 // mark as transparent and as confirmed |
361 else if (mode == MODE_RECURSE) | 967 fprintf(f->output, "TRANSP:TRANSPARENT\n"); |
362 f->name = mk_recurse_dir(item->file_as); | 968 case PST_FREEBUSY_BUSY: |
363 else if (mode == MODE_SEPERATE) { | 969 case PST_FREEBUSY_OUT_OF_OFFICE: |
364 // do similar stuff to recurse here. | 970 fprintf(f->output, "STATUS:CONFIRMED\n"); |
365 mk_seperate_dir(item->file_as, overwrite); | 971 break; |
366 f->name = (char*) xmalloc(10); | 972 } |
367 memset(f->name, 0, 10); | 973 switch (item->appointment->label) { |
368 // sprintf(f->name, "%09i", f->email_count); | 974 case PST_APP_LABEL_NONE: |
369 } else { | 975 fprintf(f->output, "CATEGORIES:NONE\n"); break; |
370 f->name = (char*) xmalloc(strlen(item->file_as)+strlen(OUTPUT_TEMPLATE+1)); | 976 case PST_APP_LABEL_IMPORTANT: |
371 sprintf(f->name, OUTPUT_TEMPLATE, item->file_as); | 977 fprintf(f->output, "CATEGORIES:IMPORTANT\n"); break; |
372 } | 978 case PST_APP_LABEL_BUSINESS: |
373 | 979 fprintf(f->output, "CATEGORIES:BUSINESS\n"); break; |
374 f->dname = (char*) xmalloc(strlen(item->file_as)+1); | 980 case PST_APP_LABEL_PERSONAL: |
375 strcpy(f->dname, item->file_as); | 981 fprintf(f->output, "CATEGORIES:PERSONAL\n"); break; |
376 | 982 case PST_APP_LABEL_VACATION: |
377 if (overwrite != 1) { | 983 fprintf(f->output, "CATEGORIES:VACATION\n"); break; |
378 temp = (char*) xmalloc (strlen(f->name)+10); //enough room for 10 digits | 984 case PST_APP_LABEL_MUST_ATTEND: |
379 sprintf(temp, "%s", f->name); | 985 fprintf(f->output, "CATEGORIES:MUST-ATTEND\n"); break; |
380 x = 0; | 986 case PST_APP_LABEL_TRAVEL_REQ: |
381 temp = check_filename(temp); | 987 fprintf(f->output, "CATEGORIES:TRAVEL-REQUIRED\n"); break; |
382 while ((f->output = fopen(temp, "r")) != NULL) { | 988 case PST_APP_LABEL_NEEDS_PREP: |
383 DEBUG_MAIN(("main: need to increase filename cause one already exists with that name\n")); | 989 fprintf(f->output, "CATEGORIES:NEEDS-PREPARATION\n"); break; |
384 DEBUG_MAIN(("main: - increasing it to %s%d\n", f->name, x)); | 990 case PST_APP_LABEL_BIRTHDAY: |
385 x++; | 991 fprintf(f->output, "CATEGORIES:BIRTHDAY\n"); break; |
386 sprintf(temp, "%s%08d", f->name, x); | 992 case PST_APP_LABEL_ANNIVERSARY: |
387 DEBUG_MAIN(("main: - trying \"%s\"\n", f->name)); | 993 fprintf(f->output, "CATEGORIES:ANNIVERSARY\n"); break; |
388 if (x == 99999999) { | 994 case PST_APP_LABEL_PHONE_CALL: |
389 DIE(("main: Why can I not create a folder %s? I have tried %i extensions...\n", f->name, x)); | 995 fprintf(f->output, "CATEGORIES:PHONE-CALL\n"); break; |
390 } | 996 } |
391 fclose(f->output); | 997 } |
392 } | 998 fprintf(f->output, "END:VEVENT\n\n"); |
393 if (x > 0) { //then the f->name should change | 999 // }}}2 |
394 free (f->name); | 1000 } else { |
395 f->name = temp; | 1001 f->skip_count++; |
396 } else { | 1002 DEBUG_MAIN(("main: Unknown item type. %i. Ascii1=\"%s\"\n", |
397 free(temp); | 1003 item->type, item->ascii_type)); |
398 } | 1004 } |
399 } | 1005 } else { |
400 | 1006 f->skip_count++; |
401 DEBUG_MAIN(("main: f->name = %s\nitem->folder_name = %s\n", f->name, item->file_as)); | 1007 DEBUG_MAIN(("main: A NULL item was seen\n")); |
402 if (mode != MODE_SEPERATE) { | 1008 } |
403 f->name = check_filename(f->name); | 1009 |
404 if ((f->output = fopen(f->name, "w")) == NULL) { | 1010 DEBUG_MAIN(("main: Going to next d_ptr\n")); |
405 DIE(("main: Could not open file \"%s\" for write\n", f->name)); | 1011 if (boundary) { |
406 } | 1012 free(boundary); |
407 } | 1013 boundary = NULL; |
408 if (d_ptr->child != NULL) { | 1014 } |
409 d_ptr = d_ptr->child; | 1015 |
410 skip_child = 1; | 1016 check_parent: |
411 } else { | 1017 // _pst_freeItem(item); |
412 DEBUG_MAIN(("main: Folder has NO children. Creating directory, and closing again\n")); | 1018 while (!skip_child && d_ptr->next == NULL && d_ptr->parent != NULL) { |
413 if (output_mode != OUTPUT_QUIET) | 1019 DEBUG_MAIN(("main: Going to Parent\n")); |
414 printf("\tNo items to process in folder \"%s\", should have been %i\n", f->dname, f->stored_count); | 1020 head = f->next; |
415 head = f->next; | 1021 if (f->output != NULL) |
416 if (f->output != NULL) | 1022 fclose(f->output); |
417 fclose(f->output); | 1023 DEBUG_MAIN(("main: Email Count for folder %s is %i\n", f->dname, f->email_count)); |
418 if (mode == MODE_KMAIL) | 1024 if (output_mode != OUTPUT_QUIET) |
419 close_kmail_dir(); | 1025 printf("\t\"%s\" - %i items done, skipped %i, should have been %i\n", |
420 else if (mode == MODE_RECURSE) | 1026 f->dname, f->email_count, f->skip_count, f->stored_count); |
421 close_recurse_dir(); | 1027 if (mode == MODE_KMAIL) |
422 else if (mode == MODE_SEPERATE) | 1028 close_kmail_dir(); |
423 close_seperate_dir(); | 1029 else if (mode == MODE_RECURSE) |
424 free(f->dname); | 1030 close_recurse_dir(); |
425 free(f->name); | 1031 else if (mode == MODE_SEPERATE) |
426 free(f); | 1032 close_seperate_dir(); |
427 | 1033 free(f->name); |
428 f = head; | 1034 free(f->dname); |
429 } | 1035 free(f); |
430 _pst_freeItem(item); | 1036 f = head; |
431 item = NULL; // just for the odd situations! | 1037 if (head == NULL) { //we can't go higher. Must be at start? |
432 goto check_parent; | 1038 DEBUG_MAIN(("main: We are now trying to go above the highest level. We must be finished\n")); |
433 } else if (item->contact != NULL) { | 1039 break; //from main while loop |
434 // deal with a contact | 1040 } |
435 // write them to the file, one per line in this format | 1041 d_ptr = d_ptr->parent; |
436 // Desc Name <email@address>\n | 1042 skip_child = 0; |
437 if (mode == MODE_SEPERATE) { | 1043 } |
438 mk_seperate_file(f); | 1044 |
439 } | 1045 if (item != NULL) { |
440 f->email_count++; | 1046 DEBUG_MAIN(("main: Freeing memory used by item\n")); |
441 | 1047 _pst_freeItem(item); |
442 DEBUG_MAIN(("main: Processing Contact\n")); | 1048 item = NULL; |
443 if (f->type != PST_TYPE_CONTACT) { | 1049 } |
444 DEBUG_MAIN(("main: I have a contact, but the folder isn't a contacts folder. " | 1050 |
445 "Will process anyway\n")); | 1051 if (!skip_child) |
446 } | 1052 d_ptr = d_ptr->next; |
447 if (item->type != PST_TYPE_CONTACT) { | 1053 else |
448 DEBUG_MAIN(("main: I have an item that has contact info, but doesn't say that" | 1054 skip_child = 0; |
449 " it is a contact. Type is \"%s\"\n", item->ascii_type)); | 1055 |
450 DEBUG_MAIN(("main: Processing anyway\n")); | 1056 if (d_ptr == NULL) { |
451 } | 1057 DEBUG_MAIN(("main: d_ptr is now NULL\n")); |
452 if (item->contact == NULL) { // this is an incorrect situation. Inform user | 1058 } |
453 DEBUG_MAIN(("main: ERROR. This contact has not been fully parsed. one of the pre-requisties is NULL\n")); | 1059 } |
454 } else { | 1060 if (output_mode != OUTPUT_QUIET) printf("Finished.\n"); |
455 if (contact_mode == CMODE_VCARD) { | 1061 DEBUG_MAIN(("main: Finished.\n")); |
456 // the specification I am following is (hopefully) RFC2426 vCard Mime Directory Profile | 1062 |
457 fprintf(f->output, "BEGIN:VCARD\n"); | 1063 // Cleanup {{{2 |
458 fprintf(f->output, "FN:%s\n", rfc2426_escape(item->contact->fullname)); | 1064 pst_close(&pstfile); |
459 fprintf(f->output, "N:%s;%s;%s;%s;%s\n", | 1065 // fclose(pstfile.fp); |
460 rfc2426_escape((item->contact->surname==NULL?"":item->contact->surname)), | 1066 while (f != NULL) { |
461 rfc2426_escape((item->contact->first_name==NULL?"":item->contact->first_name)), | 1067 if (f->output != NULL) |
462 rfc2426_escape((item->contact->middle_name==NULL?"":item->contact->middle_name)), | 1068 fclose(f->output); |
463 rfc2426_escape((item->contact->display_name_prefix==NULL?"":item->contact->display_name_prefix)), | 1069 free(f->name); |
464 rfc2426_escape((item->contact->suffix==NULL?"":item->contact->suffix))); | 1070 free(f->dname); |
465 if (item->contact->nickname != NULL) | 1071 |
466 fprintf(f->output, "NICKNAME:%s\n", rfc2426_escape(item->contact->nickname)); | 1072 if (mode == MODE_KMAIL) |
467 if (item->contact->address1 != NULL) | 1073 close_kmail_dir(); |
468 fprintf(f->output, "EMAIL:%s\n", rfc2426_escape(item->contact->address1)); | 1074 else if (mode == MODE_RECURSE) |
469 if (item->contact->address2 != NULL) | 1075 close_recurse_dir(); |
470 fprintf(f->output, "EMAIL:%s\n", rfc2426_escape(item->contact->address2)); | 1076 else if (mode == MODE_SEPERATE) |
471 if (item->contact->address3 != NULL) | 1077 // DO SOMETHING HERE |
472 fprintf(f->output, "EMAIL:%s\n", rfc2426_escape(item->contact->address3)); | 1078 ; |
473 if (item->contact->birthday != NULL) | 1079 head = f->next; |
474 fprintf(f->output, "BDAY:%s\n", rfc2425_datetime_format(item->contact->birthday)); | 1080 free (f); |
475 if (item->contact->home_address != NULL) { | 1081 f = head; |
476 fprintf(f->output, "ADR;TYPE=home:%s;%s;%s;%s;%s;%s;%s\n", | 1082 } |
477 rfc2426_escape((item->contact->home_po_box!=NULL?item->contact->home_po_box:"")), | 1083 |
478 "", // extended Address | 1084 DEBUG_RET(); |
479 rfc2426_escape((item->contact->home_street!=NULL?item->contact->home_street:"")), | 1085 // }}}2 |
480 rfc2426_escape((item->contact->home_city!=NULL?item->contact->home_city:"")), | 1086 |
481 rfc2426_escape((item->contact->home_state!=NULL?item->contact->home_state:"")), | 1087 return 0; |
482 rfc2426_escape((item->contact->home_postal_code!=NULL?item->contact->home_postal_code:"")), | 1088 } |
483 rfc2426_escape((item->contact->home_country!=NULL?item->contact->home_country:""))); | 1089 // }}}1 |
484 fprintf(f->output, "LABEL;TYPE=home:%s\n", rfc2426_escape(item->contact->home_address)); | 1090 // void write_email_body(FILE *f, char *body) {{{1 |
485 } | |
486 if (item->contact->business_address != NULL) { | |
487 fprintf(f->output, "ADR;TYPE=work:%s;%s;%s;%s;%s;%s;%s\n", | |
488 rfc2426_escape((item->contact->business_po_box!=NULL?item->contact->business_po_box:"")), | |
489 "", // extended Address | |
490 rfc2426_escape((item->contact->business_street!=NULL?item->contact->business_street:"")), | |
491 rfc2426_escape((item->contact->business_city!=NULL?item->contact->business_city:"")), | |
492 rfc2426_escape((item->contact->business_state!=NULL?item->contact->business_state:"")), | |
493 rfc2426_escape((item->contact->business_postal_code!=NULL?item->contact->business_postal_code:"")), | |
494 rfc2426_escape((item->contact->business_country!=NULL?item->contact->business_country:""))); | |
495 fprintf(f->output, "LABEL;TYPE=work:%s\n", rfc2426_escape(item->contact->business_address)); | |
496 } | |
497 if (item->contact->other_address != NULL) { | |
498 fprintf(f->output, "ADR;TYPE=postal:%s;%s;%s;%s;%s;%s;%s\n", | |
499 rfc2426_escape((item->contact->other_po_box!=NULL?item->contact->business_po_box:"")), | |
500 "", // extended Address | |
501 rfc2426_escape((item->contact->other_street!=NULL?item->contact->other_street:"")), | |
502 rfc2426_escape((item->contact->other_city!=NULL?item->contact->other_city:"")), | |
503 rfc2426_escape((item->contact->other_state!=NULL?item->contact->other_state:"")), | |
504 rfc2426_escape((item->contact->other_postal_code!=NULL?item->contact->other_postal_code:"")), | |
505 rfc2426_escape((item->contact->other_country!=NULL?item->contact->other_country:""))); | |
506 fprintf(f->output, "ADR;TYPE=postal:%s\n", rfc2426_escape(item->contact->other_address)); | |
507 } | |
508 if (item->contact->business_fax != NULL) | |
509 fprintf(f->output, "TEL;TYPE=work,fax:%s\n", rfc2426_escape(item->contact->business_fax)); | |
510 if (item->contact->business_phone != NULL) | |
511 fprintf(f->output, "TEL;TYPE=work,voice:%s\n", rfc2426_escape(item->contact->business_phone)); | |
512 if (item->contact->business_phone2 != NULL) | |
513 fprintf(f->output, "TEL;TYPE=work,voice:%s\n", rfc2426_escape(item->contact->business_phone2)); | |
514 if (item->contact->car_phone != NULL) | |
515 fprintf(f->output, "TEL;TYPE=car,voice:%s\n", rfc2426_escape(item->contact->car_phone)); | |
516 if (item->contact->home_fax != NULL) | |
517 fprintf(f->output, "TEL;TYPE=home,fax:%s\n", rfc2426_escape(item->contact->home_fax)); | |
518 if (item->contact->home_phone != NULL) | |
519 fprintf(f->output, "TEL;TYPE=home,voice:%s\n", rfc2426_escape(item->contact->home_phone)); | |
520 if (item->contact->home_phone2 != NULL) | |
521 fprintf(f->output, "TEL;TYPE=home,voice:%s\n", rfc2426_escape(item->contact->home_phone2)); | |
522 if (item->contact->isdn_phone != NULL) | |
523 fprintf(f->output, "TEL;TYPE=isdn:%s\n", rfc2426_escape(item->contact->isdn_phone)); | |
524 if (item->contact->mobile_phone != NULL) | |
525 fprintf(f->output, "TEL;TYPE=cell,voice:%s\n", rfc2426_escape(item->contact->mobile_phone)); | |
526 if (item->contact->other_phone != NULL) | |
527 fprintf(f->output, "TEL;TYPE=msg:%s\n", rfc2426_escape(item->contact->other_phone)); | |
528 if (item->contact->pager_phone != NULL) | |
529 fprintf(f->output, "TEL;TYPE=pager:%s\n", rfc2426_escape(item->contact->pager_phone)); | |
530 if (item->contact->primary_fax != NULL) | |
531 fprintf(f->output, "TEL;TYPE=fax,pref:%s\n", rfc2426_escape(item->contact->primary_fax)); | |
532 if (item->contact->primary_phone != NULL) | |
533 fprintf(f->output, "TEL;TYPE=phone,pref:%s\n", rfc2426_escape(item->contact->primary_phone)); | |
534 if (item->contact->radio_phone != NULL) | |
535 fprintf(f->output, "TEL;TYPE=pcs:%s\n", rfc2426_escape(item->contact->radio_phone)); | |
536 if (item->contact->telex != NULL) | |
537 fprintf(f->output, "TEL;TYPE=bbs:%s\n", rfc2426_escape(item->contact->telex)); | |
538 if (item->contact->job_title != NULL) | |
539 fprintf(f->output, "TITLE:%s\n", rfc2426_escape(item->contact->job_title)); | |
540 if (item->contact->profession != NULL) | |
541 fprintf(f->output, "ROLE:%s\n", rfc2426_escape(item->contact->profession)); | |
542 if (item->contact->assistant_name != NULL || item->contact->assistant_phone != NULL) { | |
543 fprintf(f->output, "AGENT:BEGIN:VCARD\\n"); | |
544 if (item->contact->assistant_name != NULL) | |
545 fprintf(f->output, "FN:%s\\n", rfc2426_escape(item->contact->assistant_name)); | |
546 if (item->contact->assistant_phone != NULL) | |
547 fprintf(f->output, "TEL:%s\\n", rfc2426_escape(item->contact->assistant_phone)); | |
548 fprintf(f->output, "END:VCARD\\n\n"); | |
549 } | |
550 if (item->contact->company_name != NULL) | |
551 fprintf(f->output, "ORG:%s\n", rfc2426_escape(item->contact->company_name)); | |
552 if (item->comment != NULL) | |
553 fprintf(f->output, "NOTE:%s\n", rfc2426_escape(item->comment)); | |
554 | |
555 fprintf(f->output, "VERSION: 3.0\n"); | |
556 fprintf(f->output, "END:VCARD\n\n"); | |
557 } else { | |
558 fprintf(f->output, "%s <%s>\n", item->contact->fullname, item->contact->address1); | |
559 } | |
560 } | |
561 } else if (item->email != NULL && (item->type == PST_TYPE_NOTE || item->type == PST_TYPE_REPORT)) { | |
562 if (mode == MODE_SEPERATE) { | |
563 mk_seperate_file(f); | |
564 } | |
565 | |
566 f->email_count++; | |
567 | |
568 DEBUG_MAIN(("main: seen an email\n")); | |
569 | |
570 // convert the sent date if it exists, or set it to a fixed date | |
571 if (item->email->sent_date != NULL) { | |
572 em_time = fileTimeToUnixTime(item->email->sent_date, 0); | |
573 c_time = ctime(&em_time); | |
574 if (c_time != NULL) | |
575 c_time[strlen(c_time)-1] = '\0'; //remove end \n | |
576 else | |
577 c_time = "Fri Dec 28 12:06:21 2001"; | |
578 } else | |
579 c_time= "Fri Dec 28 12:06:21 2001"; | |
580 | |
581 // if the boundary is still set from the previous run, then free it | |
582 if (boundary != NULL) { | |
583 free (boundary); | |
584 boundary = NULL; | |
585 } | |
586 | |
587 // we will always look at the header to discover some stuff | |
588 if (item->email->header != NULL ) { | |
589 // see if there is a boundary variable there | |
590 // this search MUST be made case insensitive (DONE). | |
591 // Also, some check to find out if we | |
592 // are looking at the boundary associated with content-type, and that the content | |
593 // type really is "multipart" | |
594 if ((b2 = my_stristr(item->email->header, "boundary=")) != NULL) { | |
595 b2 += strlen("boundary="); // move boundary to first char of marker | |
596 | |
597 if (*b2 == '"') { | |
598 b2++; | |
599 b1 = strchr(b2, '"'); // find terminating quote | |
600 } else { | |
601 b1 = b2; | |
602 while (isgraph(*b1)) // find first char that isn't part of boundary | |
603 b1++; | |
604 } | |
605 | |
606 boundary = malloc ((b1-b2)+1); //malloc that length | |
607 memset (boundary, 0, (b1-b2)+1); // blank it | |
608 strncpy(boundary, b2, b1-b2); // copy boundary to another variable | |
609 b1 = b2 = boundary; | |
610 while (*b2 != '\0') { // remove any CRs and Tabs | |
611 if (*b2 != '\n' && *b2 != '\r' && *b2 != '\t') { | |
612 *b1 = *b2; | |
613 b1++; | |
614 } | |
615 b2++; | |
616 } | |
617 *b1 = '\0'; | |
618 | |
619 DEBUG_MAIN(("main: Found boundary of - %s\n", boundary)); | |
620 } else { | |
621 | |
622 DEBUG_MAIN(("main: boundary not found in header\n")); | |
623 } | |
624 | |
625 // also possible to set 7bit encoding detection here. | |
626 if ((b2 = my_stristr(item->email->header, "Content-Transfer-Encoding:")) != NULL) { | |
627 if ((b2 = strchr(b2, ':')) != NULL) { | |
628 b2++; // skip to the : at the end of the string | |
629 | |
630 while (*b2 == ' ' || *b2 == '\t') | |
631 b2++; | |
632 if (pst_strincmp(b2, "base64", 6)==0) { | |
633 DEBUG_MAIN(("body is base64 encoded\n")); | |
634 base64_body = 1; | |
635 } | |
636 } else { | |
637 DEBUG_WARN(("found a ':' during the my_stristr, but not after that..\n")); | |
638 } | |
639 } | |
640 | |
641 } | |
642 if (boundary == NULL && (item->attach ||(item->email->body && item->email->htmlbody) | |
643 || item->email->rtf_compressed || item->email->encrypted_body | |
644 || item->email->encrypted_htmlbody)) { | |
645 // we need to create a boundary here. | |
646 DEBUG_EMAIL(("main: must create own boundary. oh dear.\n")); | |
647 boundary = malloc(50 * sizeof(char)); // allow 50 chars for boundary | |
648 boundary[0] = '\0'; | |
649 sprintf(boundary, "--boundary-LibPST-iamunique-%i_-_-", rand()); | |
650 DEBUG_EMAIL(("main: created boundary is %s\n", boundary)); | |
651 } | |
652 | |
653 DEBUG_MAIN(("main: About to print Header\n")); | |
654 | |
655 if (item != NULL && item->email != NULL && item->email->subject != NULL && | |
656 item->email->subject->subj != NULL) { | |
657 DEBUG_EMAIL(("item->email->subject->subj = %p\n", item->email->subject->subj)); | |
658 } | |
659 if (item->email->header != NULL) { | |
660 // some of the headers we get from the file are not properly defined. | |
661 // they can contain some email stuff too. We will cut off the header | |
662 // when we see a \n\n or \r\n\r\n | |
663 | |
664 removeCR(item->email->header); | |
665 | |
666 temp = strstr(item->email->header, "\n\n"); | |
667 | |
668 if (temp != NULL) { | |
669 DEBUG_MAIN(("main: Found body text in header\n")); | |
670 temp += 2; // get past the \n\n | |
671 *temp = '\0'; | |
672 } | |
673 | |
674 if (mode != MODE_SEPERATE) { | |
675 // don't put rubbish in if we are doing seperate | |
676 fprintf(f->output, "From \"%s\" %s\n%s\n", | |
677 item->email->outlook_sender_name, c_time, item->email->header); | |
678 fprintf(f->output, "\n"); | |
679 } else { | |
680 fprintf(f->output, "%s\n", item->email->header); | |
681 } | |
682 } else { | |
683 //make up our own header! | |
684 if (mode != MODE_SEPERATE) { | |
685 // don't want this first line for this mode | |
686 if (item->email->outlook_sender_name != NULL) { | |
687 temp = item->email->outlook_sender_name; | |
688 } else { | |
689 temp = "(readpst_null)"; | |
690 } | |
691 fprintf(f->output, "From \"%s\" %s\n", temp, c_time); | |
692 } | |
693 if ((temp = item->email->outlook_sender) == NULL) | |
694 temp = ""; | |
695 fprintf(f->output, "From: \"%s\" <%s>\n", item->email->outlook_sender_name, temp); | |
696 if (item->email->subject != NULL) { | |
697 fprintf(f->output, "Subject: %s\n", item->email->subject->subj); | |
698 } else { | |
699 fprintf(f->output, "Subject: \n"); | |
700 } | |
701 fprintf(f->output, "To: %s\n", item->email->sentto_address); | |
702 if (item->email->cc_address != NULL) { | |
703 fprintf(f->output, "CC: %s\n", item->email->cc_address); | |
704 } | |
705 if (item->email->sent_date != NULL) { | |
706 c_time = (char*) xmalloc(C_TIME_SIZE); | |
707 strftime(c_time, C_TIME_SIZE, "%a, %d %b %Y %H:%M:%S %z", gmtime(&em_time)); | |
708 fprintf(f->output, "Date: %s\n", c_time); | |
709 free(c_time); | |
710 } | |
711 | |
712 fprintf(f->output, "MIME-Version: 1.0\n"); | |
713 if (item->attach != NULL) { | |
714 // write the boundary stuff if we have attachments | |
715 fprintf(f->output, "Content-type: multipart/mixed;\n\tboundary=\"%s\"\n", | |
716 boundary); | |
717 } else if (item->email->htmlbody && item->email->body) { | |
718 // else if we have an html and text body then tell it so | |
719 fprintf(f->output, "Content-type: multipart/alternate;\n\tboundary=\"%s\"\n", | |
720 boundary); | |
721 } else if (item->email->htmlbody) { | |
722 fprintf(f->output, "Content-type: text/html\n"); | |
723 } | |
724 fprintf(f->output, "\n"); | |
725 } | |
726 | |
727 | |
728 DEBUG_MAIN(("main: About to print Body\n")); | |
729 | |
730 if (item->email->body != NULL) { | |
731 if (boundary) { | |
732 fprintf(f->output, "\n--%s\n", boundary); | |
733 fprintf(f->output, "Content-type: text/plain\n\n"); | |
734 if (base64_body) | |
735 fprintf(f->output, "Content-Transfer-Encoding: base64\n"); | |
736 } | |
737 removeCR(item->email->body); | |
738 if (base64_body) | |
739 write_email_body(f->output, base64_encode(item->email->body, | |
740 strlen(item->email->body))); | |
741 else | |
742 write_email_body(f->output, item->email->body); | |
743 } | |
744 | |
745 if (item->email->htmlbody != NULL) { | |
746 if (boundary) { | |
747 fprintf(f->output, "\n--%s\n", boundary); | |
748 fprintf(f->output, "Content-type: text/html\n\n"); | |
749 if (base64_body) | |
750 fprintf(f->output, "Content-Transfer-Encoding: base64\n"); | |
751 } | |
752 removeCR(item->email->htmlbody); | |
753 if (base64_body) | |
754 write_email_body(f->output, base64_encode(item->email->htmlbody, | |
755 strlen(item->email->htmlbody))); | |
756 else | |
757 write_email_body(f->output, item->email->htmlbody); | |
758 } | |
759 | |
760 attach_num = 0; | |
761 | |
762 if (item->email->rtf_compressed != NULL) { | |
763 DEBUG_MAIN(("Adding RTF body as attachment\n")); | |
764 item->current_attach = (pst_item_attach*)xmalloc(sizeof(pst_item_attach)); | |
765 memset(item->current_attach, 0, sizeof(pst_item_attach)); | |
766 item->current_attach->next = item->attach; | |
767 item->attach = item->current_attach; | |
768 item->current_attach->data = lzfu_decompress(item->email->rtf_compressed); | |
769 item->current_attach->filename2 = xmalloc(strlen(RTF_ATTACH_NAME)+2); | |
770 strcpy(item->current_attach->filename2, RTF_ATTACH_NAME); | |
771 item->current_attach->mimetype = xmalloc(strlen(RTF_ATTACH_TYPE)+2); | |
772 strcpy(item->current_attach->mimetype, RTF_ATTACH_TYPE); | |
773 memcpy(&(item->current_attach->size), item->email->rtf_compressed+sizeof(int32_t), sizeof(int32_t)); | |
774 LE32_CPU(item->current_attach->size); | |
775 // item->email->rtf_compressed = ; | |
776 // attach_num++; | |
777 } | |
778 if (item->email->encrypted_body || item->email->encrypted_htmlbody) { | |
779 // if either the body or htmlbody is encrypted, add them as attachments | |
780 if (item->email->encrypted_body) { | |
781 DEBUG_MAIN(("Adding Encrypted Body as attachment\n")); | |
782 item->current_attach = (pst_item_attach*) xmalloc(sizeof(pst_item_attach)); | |
783 memset(item->current_attach, 0, sizeof(pst_item_attach)); | |
784 item->current_attach->next = item->attach; | |
785 item->attach = item->current_attach; | |
786 | |
787 item->current_attach->data = item->email->encrypted_body; | |
788 item->current_attach->size = item->email->encrypted_body_size; | |
789 item->email->encrypted_body = NULL; | |
790 } | |
791 if (item->email->encrypted_htmlbody) { | |
792 DEBUG_MAIN(("Adding encrypted HTML body as attachment\n")); | |
793 item->current_attach = (pst_item_attach*) xmalloc(sizeof(pst_item_attach)); | |
794 memset(item->current_attach, 0, sizeof(pst_item_attach)); | |
795 item->current_attach->next = item->attach; | |
796 item->attach = item->current_attach; | |
797 | |
798 item->current_attach->data = item->email->encrypted_htmlbody; | |
799 item->current_attach->size = item->email->encrypted_htmlbody_size; | |
800 item->email->encrypted_htmlbody = NULL; | |
801 } | |
802 write_email_body(f->output, "The body of this email is encrypted. This isn't supported yet, but the body is now an attachment\n"); | |
803 } | |
804 base64_body = 0; | |
805 // attachments | |
806 item->current_attach = item->attach; | |
807 while (item->current_attach != NULL) { | |
808 DEBUG_MAIN(("main: Attempting Attachment encoding\n")); | |
809 if (item->current_attach->data == NULL) { | |
810 DEBUG_MAIN(("main: Data of attachment is NULL!. Size is supposed to be %i\n", item->current_attach->size)); | |
811 } | |
812 if (mode == MODE_SEPERATE) { | |
813 f->name = check_filename(f->name); | |
814 if (item->current_attach->filename2 == NULL) { | |
815 temp = xmalloc(strlen(f->name)+15); | |
816 sprintf(temp, "%s-attach%i", f->name, attach_num); | |
817 } else { | |
818 temp = xmalloc(strlen(f->name)+strlen(item->current_attach->filename2)+15); | |
819 fp = NULL; x=0; | |
820 do { | |
821 if (fp != NULL) fclose(fp); | |
822 if (x == 0) | |
823 sprintf(temp, "%s-%s", f->name, item->current_attach->filename2); | |
824 else | |
825 sprintf(temp, "%s-%s-%i", f->name, item->current_attach->filename2, x); | |
826 } while ((fp = fopen(temp, "r"))!=NULL && ++x < 99999999); | |
827 if (x > 99999999) { | |
828 DIE(("error finding attachment name. exhausted possibilities to %s\n", temp)); | |
829 } | |
830 } | |
831 DEBUG_MAIN(("main: Saving attachment to %s\n", temp)); | |
832 if ((fp = fopen(temp, "w")) == NULL) { | |
833 WARN(("main: Cannot open attachment save file \"%s\"\n", temp)); | |
834 } else { | |
835 if (item->current_attach->data != NULL) | |
836 fwrite(item->current_attach->data, 1, item->current_attach->size, fp); | |
837 else { | |
838 pst_attach_to_file(&pstfile, item->current_attach, fp); | |
839 } | |
840 fclose(fp); | |
841 } | |
842 } else { | |
843 DEBUG_MAIN(("main: Attachment Size is %i\n", item->current_attach->size)); | |
844 DEBUG_MAIN(("main: Attachment Pointer is %p\n", item->current_attach->data)); | |
845 if (item->current_attach->data != NULL) { | |
846 if ((enc = base64_encode (item->current_attach->data, item->current_attach->size)) == NULL) { | |
847 DEBUG_MAIN(("main: ERROR base64_encode returned NULL. Must have failed\n")); | |
848 item->current_attach = item->current_attach->next; | |
849 continue; | |
850 } | |
851 } | |
852 if (boundary) { | |
853 fprintf(f->output, "\n--%s\n", boundary); | |
854 if (item->current_attach->mimetype == NULL) { | |
855 fprintf(f->output, "Content-type: %s\n", MIME_TYPE_DEFAULT); | |
856 } else { | |
857 fprintf(f->output, "Content-type: %s\n", item->current_attach->mimetype); | |
858 } | |
859 fprintf(f->output, "Content-transfer-encoding: base64\n"); | |
860 if (item->current_attach->filename2 == NULL) { | |
861 fprintf(f->output, "Content-Disposition: inline\n\n"); | |
862 } else { | |
863 fprintf(f->output, "Content-Disposition: attachment; filename=\"%s\"\n\n", | |
864 item->current_attach->filename2); | |
865 } | |
866 } | |
867 if (item->current_attach->data != NULL) { | |
868 fwrite(enc, 1, strlen(enc), f->output); | |
869 DEBUG_MAIN(("Attachment Size after encoding is %i\n", strlen(enc))); | |
870 } else { | |
871 pst_attach_to_file_base64(&pstfile, item->current_attach, f->output); | |
872 } | |
873 fprintf(f->output, "\n\n"); | |
874 } | |
875 item->current_attach = item->current_attach->next; | |
876 attach_num++; | |
877 } | |
878 if (mode != MODE_SEPERATE) { | |
879 DEBUG_MAIN(("main: Writing buffer between emails\n")); | |
880 if (boundary) | |
881 fprintf(f->output, "\n--%s--\n", boundary); | |
882 fprintf(f->output, "\n\n"); | |
883 } | |
884 } else if (item->type == PST_TYPE_JOURNAL) { | |
885 // deal with journal items | |
886 if (mode == MODE_SEPERATE) { | |
887 mk_seperate_file(f); | |
888 } | |
889 f->email_count++; | |
890 | |
891 DEBUG_MAIN(("main: Processing Journal Entry\n")); | |
892 if (f->type != PST_TYPE_JOURNAL) { | |
893 DEBUG_MAIN(("main: I have a journal entry, but folder isn't specified as a journal type. Processing...\n")); | |
894 } | |
895 | |
896 /* if (item->type != PST_TYPE_JOURNAL) { | |
897 DEBUG_MAIN(("main: I have an item with journal info, but it's type is \"%s\" \n. Processing...\n", | |
898 item->ascii_type)); | |
899 }*/ | |
900 fprintf(f->output, "BEGIN:VJOURNAL\n"); | |
901 if (item->email->subject != NULL) | |
902 fprintf(f->output, "SUMMARY:%s\n", rfc2426_escape(item->email->subject->subj)); | |
903 if (item->email->body != NULL) | |
904 fprintf(f->output, "DESCRIPTION:%s\n", rfc2426_escape(item->email->body)); | |
905 if (item->journal->start != NULL) | |
906 fprintf(f->output, "DTSTART;VALUE=DATE-TIME:%s\n", rfc2445_datetime_format(item->journal->start)); | |
907 fprintf(f->output, "END:VJOURNAL\n\n"); | |
908 | |
909 } else if (item->type == PST_TYPE_APPOINTMENT) { | |
910 // deal with Calendar appointments | |
911 if (mode == MODE_SEPERATE) { | |
912 mk_seperate_file(f); | |
913 } | |
914 f->email_count++; | |
915 | |
916 DEBUG_MAIN(("main: Processing Appointment Entry\n")); | |
917 if (f->type != PST_TYPE_APPOINTMENT) { | |
918 DEBUG_MAIN(("main: I have an appointment, but folder isn't specified as an appointment type. Processing...\n")); | |
919 } | |
920 fprintf(f->output, "BEGIN:VEVENT\n"); | |
921 if (item->create_date != NULL) | |
922 fprintf(f->output, "CREATED:%s\n", rfc2445_datetime_format(item->create_date)); | |
923 if (item->modify_date != NULL) | |
924 fprintf(f->output, "LAST-MOD:%s\n", rfc2445_datetime_format(item->modify_date)); | |
925 if (item->email != NULL && item->email->subject != NULL) | |
926 fprintf(f->output, "SUMMARY:%s\n", rfc2426_escape(item->email->subject->subj)); | |
927 if (item->email != NULL && item->email->body != NULL) | |
928 fprintf(f->output, "DESCRIPTION:%s\n", rfc2426_escape(item->email->body)); | |
929 if (item->appointment != NULL && item->appointment->start != NULL) | |
930 fprintf(f->output, "DTSTART;VALUE=DATE-TIME:%s\n", rfc2445_datetime_format(item->appointment->start)); | |
931 if (item->appointment != NULL && item->appointment->end != NULL) | |
932 fprintf(f->output, "DTEND;VALUE=DATE-TIME:%s\n", rfc2445_datetime_format(item->appointment->end)); | |
933 if (item->appointment != NULL && item->appointment->location != NULL) | |
934 fprintf(f->output, "LOCATION:%s\n", rfc2426_escape(item->appointment->location)); | |
935 if (item->appointment != NULL) { | |
936 switch (item->appointment->showas) { | |
937 case PST_FREEBUSY_TENTATIVE: | |
938 fprintf(f->output, "STATUS:TENTATIVE\n"); | |
939 break; | |
940 case PST_FREEBUSY_FREE: | |
941 // mark as transparent and as confirmed | |
942 fprintf(f->output, "TRANSP:TRANSPARENT\n"); | |
943 case PST_FREEBUSY_BUSY: | |
944 case PST_FREEBUSY_OUT_OF_OFFICE: | |
945 fprintf(f->output, "STATUS:CONFIRMED\n"); | |
946 break; | |
947 } | |
948 switch (item->appointment->label) { | |
949 case PST_APP_LABEL_NONE: | |
950 fprintf(f->output, "CATEGORIES:NONE\n"); break; | |
951 case PST_APP_LABEL_IMPORTANT: | |
952 fprintf(f->output, "CATEGORIES:IMPORTANT\n"); break; | |
953 case PST_APP_LABEL_BUSINESS: | |
954 fprintf(f->output, "CATEGORIES:BUSINESS\n"); break; | |
955 case PST_APP_LABEL_PERSONAL: | |
956 fprintf(f->output, "CATEGORIES:PERSONAL\n"); break; | |
957 case PST_APP_LABEL_VACATION: | |
958 fprintf(f->output, "CATEGORIES:VACATION\n"); break; | |
959 case PST_APP_LABEL_MUST_ATTEND: | |
960 fprintf(f->output, "CATEGORIES:MUST-ATTEND\n"); break; | |
961 case PST_APP_LABEL_TRAVEL_REQ: | |
962 fprintf(f->output, "CATEGORIES:TRAVEL-REQUIRED\n"); break; | |
963 case PST_APP_LABEL_NEEDS_PREP: | |
964 fprintf(f->output, "CATEGORIES:NEEDS-PREPARATION\n"); break; | |
965 case PST_APP_LABEL_BIRTHDAY: | |
966 fprintf(f->output, "CATEGORIES:BIRTHDAY\n"); break; | |
967 case PST_APP_LABEL_ANNIVERSARY: | |
968 fprintf(f->output, "CATEGORIES:ANNIVERSARY\n"); break; | |
969 case PST_APP_LABEL_PHONE_CALL: | |
970 fprintf(f->output, "CATEGORIES:PHONE-CALL\n"); break; | |
971 } | |
972 } | |
973 fprintf(f->output, "END:VEVENT\n\n"); | |
974 } else { | |
975 f->skip_count++; | |
976 DEBUG_MAIN(("main: Unknown item type. %i. Ascii1=\"%s\"\n", | |
977 item->type, item->ascii_type)); | |
978 } | |
979 } else { | |
980 f->skip_count++; | |
981 DEBUG_MAIN(("main: A NULL item was seen\n")); | |
982 } | |
983 DEBUG_MAIN(("main: Going to next d_ptr\n")); | |
984 if (boundary) { | |
985 free(boundary); | |
986 boundary = NULL; | |
987 } | |
988 check_parent: | |
989 // _pst_freeItem(item); | |
990 while (!skip_child && d_ptr->next == NULL && d_ptr->parent != NULL) { | |
991 DEBUG_MAIN(("main: Going to Parent\n")); | |
992 head = f->next; | |
993 if (f->output != NULL) | |
994 fclose(f->output); | |
995 DEBUG_MAIN(("main: Email Count for folder %s is %i\n", f->dname, f->email_count)); | |
996 if (output_mode != OUTPUT_QUIET) | |
997 printf("\t\"%s\" - %i items done, skipped %i, should have been %i\n", | |
998 f->dname, f->email_count, f->skip_count, f->stored_count); | |
999 if (mode == MODE_KMAIL) | |
1000 close_kmail_dir(); | |
1001 else if (mode == MODE_RECURSE) | |
1002 close_recurse_dir(); | |
1003 else if (mode == MODE_SEPERATE) | |
1004 close_seperate_dir(); | |
1005 free(f->name); | |
1006 free(f->dname); | |
1007 free(f); | |
1008 f = head; | |
1009 if (head == NULL) { //we can't go higher. Must be at start? | |
1010 DEBUG_MAIN(("main: We are now trying to go above the highest level. We must be finished\n")); | |
1011 break; //from main while loop | |
1012 } | |
1013 d_ptr = d_ptr->parent; | |
1014 skip_child = 0; | |
1015 } | |
1016 | |
1017 if (item != NULL) { | |
1018 DEBUG_MAIN(("main: Freeing memory used by item\n")); | |
1019 _pst_freeItem(item); | |
1020 item = NULL; | |
1021 } | |
1022 if (!skip_child) | |
1023 d_ptr = d_ptr->next; | |
1024 else | |
1025 skip_child = 0; | |
1026 | |
1027 if (d_ptr == NULL) { | |
1028 DEBUG_MAIN(("main: d_ptr is now NULL\n")); | |
1029 } | |
1030 } | |
1031 if (output_mode != OUTPUT_QUIET) printf("Finished.\n"); | |
1032 | |
1033 DEBUG_MAIN(("main: Finished.\n")); | |
1034 pst_close(&pstfile); | |
1035 // fclose(pstfile.fp); | |
1036 while (f != NULL) { | |
1037 if (f->output != NULL) | |
1038 fclose(f->output); | |
1039 free(f->name); | |
1040 free(f->dname); | |
1041 | |
1042 if (mode == MODE_KMAIL) | |
1043 close_kmail_dir(); | |
1044 else if (mode == MODE_RECURSE) | |
1045 close_recurse_dir(); | |
1046 else if (mode == MODE_SEPERATE) | |
1047 // DO SOMETHING HERE | |
1048 ; | |
1049 head = f->next; | |
1050 free (f); | |
1051 f = head; | |
1052 } | |
1053 | |
1054 DEBUG_RET(); | |
1055 return 0; | |
1056 } | |
1057 | |
1058 void write_email_body(FILE *f, char *body) { | 1091 void write_email_body(FILE *f, char *body) { |
1059 char *n = body; | 1092 char *n = body; |
1060 // DEBUG_MAIN(("write_email_body(): \"%s\"\n", body)); | 1093 // DEBUG_MAIN(("write_email_body(): \"%s\"\n", body)); |
1061 DEBUG_ENT("write_email_body"); | 1094 DEBUG_ENT("write_email_body"); |
1062 while (n != NULL) { | 1095 while (n != NULL) { |
1063 if (strncmp(body, "From ", 5) == 0) | 1096 if (strncmp(body, "From ", 5) == 0) |
1064 fprintf(f, ">"); | 1097 fprintf(f, ">"); |
1065 if ((n = strchr(body, '\n'))) { | 1098 if ((n = strchr(body, '\n'))) { |
1066 n++; | 1099 n++; |
1067 fwrite(body, n-body, 1, f); //write just a line | 1100 fwrite(body, n-body, 1, f); //write just a line |
1068 | 1101 |
1069 body = n; | 1102 body = n; |
1070 } | 1103 } |
1071 } | 1104 } |
1072 fwrite(body, strlen(body), 1, f); | 1105 fwrite(body, strlen(body), 1, f); |
1073 DEBUG_RET(); | 1106 DEBUG_RET(); |
1074 } | 1107 } |
1075 | 1108 // }}}1 |
1076 char * removeCR (char *c) { | 1109 // char *removeCR (char *c) {{{1 |
1077 // converts /r/n to /n | 1110 char *removeCR (char *c) { |
1078 char *a, *b; | 1111 // converts /r/n to /n |
1079 DEBUG_ENT("removeCR"); | 1112 char *a, *b; |
1080 a = b = c; | 1113 DEBUG_ENT("removeCR"); |
1081 while (*a != '\0') { | 1114 a = b = c; |
1082 *b = *a; | 1115 while (*a != '\0') { |
1083 if (*a != '\r') | 1116 *b = *a; |
1084 b++; | 1117 if (*a != '\r') |
1085 a++; | 1118 b++; |
1086 } | 1119 a++; |
1087 *b = '\0'; | 1120 } |
1088 DEBUG_RET(); | 1121 *b = '\0'; |
1089 return c; | 1122 DEBUG_RET(); |
1090 } | 1123 return c; |
1091 | 1124 } |
1125 // }}}1 | |
1126 // int usage() {{{1 | |
1092 int usage() { | 1127 int usage() { |
1093 DEBUG_ENT("usage"); | 1128 DEBUG_ENT("usage"); |
1094 version(); | 1129 version(); |
1095 printf("Usage: %s [OPTIONS] {PST FILENAME}\n", prog_name); | 1130 printf("Usage: %s [OPTIONS] {PST FILENAME}\n", prog_name); |
1096 printf("OPTIONS:\n"); | 1131 printf("OPTIONS:\n"); |
1097 printf("\t-c[v|l]\t- Set the Contact output mode. -cv = VCard, -cl = EMail list\n"); | 1132 printf("\t-c[v|l]\t- Set the Contact output mode. -cv = VCard, -cl = EMail list\n"); |
1098 printf("\t-d\t- Debug to file. This is a binary log. Use readlog to print it\n"); | 1133 printf("\t-d\t- Debug to file. This is a binary log. Use readlog to print it\n"); |
1099 printf("\t-h\t- Help. This screen\n"); | 1134 printf("\t-h\t- Help. This screen\n"); |
1100 printf("\t-k\t- KMail. Output in kmail format\n"); | 1135 printf("\t-k\t- KMail. Output in kmail format\n"); |
1101 printf("\t-o\t- Output Dir. Directory to write files to. CWD is changed *after* opening pst file\n"); | 1136 printf("\t-o\t- Output Dir. Directory to write files to. CWD is changed *after* opening pst file\n"); |
1102 printf("\t-q\t- Quiet. Only print error messages\n"); | 1137 printf("\t-q\t- Quiet. Only print error messages\n"); |
1103 printf("\t-r\t- Recursive. Output in a recursive format\n"); | 1138 printf("\t-r\t- Recursive. Output in a recursive format\n"); |
1104 printf("\t-S\t- Seperate. Write emails in the seperate format\n"); | 1139 printf("\t-S\t- Seperate. Write emails in the seperate format\n"); |
1105 printf("\t-V\t- Version. Display program version\n"); | 1140 printf("\t-V\t- Version. Display program version\n"); |
1106 printf("\t-w\t- Overwrite any output mbox files\n"); | 1141 printf("\t-w\t- Overwrite any output mbox files\n"); |
1107 DEBUG_RET(); | 1142 DEBUG_RET(); |
1108 return 0; | 1143 return 0; |
1109 } | 1144 } |
1110 | 1145 // }}}1 |
1146 // int version() {{{1 | |
1111 int version() { | 1147 int version() { |
1112 DEBUG_ENT("version"); | 1148 DEBUG_ENT("version"); |
1113 printf("ReadPST v%s implementing LibPST v%s\n", VERSION, PST_VERSION); | 1149 printf("ReadPST v%s implementing LibPST v%s\n", VERSION, PST_VERSION); |
1114 #if BYTE_ORDER == BIG_ENDIAN | 1150 #if BYTE_ORDER == BIG_ENDIAN |
1115 printf("Big Endian implementation being used.\n"); | 1151 printf("Big Endian implementation being used.\n"); |
1116 #elif BYTE_ORDER == LITTLE_ENDIAN | 1152 #elif BYTE_ORDER == LITTLE_ENDIAN |
1117 printf("Little Endian implementation being used.\n"); | 1153 printf("Little Endian implementation being used.\n"); |
1118 #else | 1154 #else |
1119 # error "Byte order not supported by this library" | 1155 # error "Byte order not supported by this library" |
1120 #endif | 1156 #endif |
1121 #ifdef __GNUC__ | 1157 #ifdef __GNUC__ |
1122 printf("GCC %d.%d : %s %s\n", __GNUC__, __GNUC_MINOR__, __DATE__, __TIME__); | 1158 printf("GCC %d.%d : %s %s\n", __GNUC__, __GNUC_MINOR__, __DATE__, __TIME__); |
1123 #endif | 1159 #endif |
1124 DEBUG_RET(); | 1160 DEBUG_RET(); |
1125 return 0; | 1161 return 0; |
1126 } | 1162 } |
1127 | 1163 // }}}1 |
1128 char *kmail_chdir = NULL; | 1164 // char *mk_kmail_dir(char *fname) {{{1 |
1129 | 1165 char *mk_kmail_dir(char *fname) { |
1130 char* mk_kmail_dir(char *fname) { | 1166 //change to that directory |
1131 //change to that directory | 1167 //make a directory based on OUTPUT_KMAIL_DIR_TEMPLATE |
1132 //make a directory based on OUTPUT_KMAIL_DIR_TEMPLATE | 1168 //allocate space for OUTPUT_TEMPLATE and form a char* with fname |
1133 //allocate space for OUTPUT_TEMPLATE and form a char* with fname | 1169 //return that value |
1134 //return that value | 1170 char *dir, *out_name, *index; |
1135 char *dir, *out_name, *index; | 1171 int x; |
1136 int x; | 1172 DEBUG_ENT("mk_kmail_dir"); |
1137 DEBUG_ENT("mk_kmail_dir"); | 1173 if (kmail_chdir != NULL && chdir(kmail_chdir)) { |
1138 if (kmail_chdir != NULL && chdir(kmail_chdir)) { | 1174 x = errno; |
1139 x = errno; | 1175 DIE(("mk_kmail_dir: Cannot change to directory %s: %s\n", kmail_chdir, strerror(x))); |
1140 DIE(("mk_kmail_dir: Cannot change to directory %s: %s\n", kmail_chdir, strerror(x))); | 1176 } |
1141 } | 1177 dir = malloc(strlen(fname)+strlen(OUTPUT_KMAIL_DIR_TEMPLATE)+1); |
1142 dir = malloc(strlen(fname)+strlen(OUTPUT_KMAIL_DIR_TEMPLATE)+1); | 1178 sprintf(dir, OUTPUT_KMAIL_DIR_TEMPLATE, fname); |
1143 sprintf(dir, OUTPUT_KMAIL_DIR_TEMPLATE, fname); | 1179 dir = check_filename(dir); |
1144 dir = check_filename(dir); | 1180 if (D_MKDIR(dir)) { |
1145 if (D_MKDIR(dir)) { | 1181 //error occured |
1146 //error occured | 1182 if (errno != EEXIST) { |
1147 if (errno != EEXIST) { | 1183 x = errno; |
1148 x = errno; | 1184 DIE(("mk_kmail_dir: Cannot create directory %s: %s\n", dir, strerror(x))); |
1149 DIE(("mk_kmail_dir: Cannot create directory %s: %s\n", dir, strerror(x))); | 1185 } |
1186 } | |
1187 kmail_chdir = realloc(kmail_chdir, strlen(dir)+1); | |
1188 strcpy(kmail_chdir, dir); | |
1189 free (dir); | |
1190 | |
1191 //we should remove any existing indexes created by KMail, cause they might be different now | |
1192 index = malloc(strlen(fname)+strlen(KMAIL_INDEX)+1); | |
1193 sprintf(index, KMAIL_INDEX, fname); | |
1194 unlink(index); | |
1195 free(index); | |
1196 | |
1197 out_name = malloc(strlen(fname)+strlen(OUTPUT_TEMPLATE)+1); | |
1198 sprintf(out_name, OUTPUT_TEMPLATE, fname); | |
1199 DEBUG_RET(); | |
1200 return out_name; | |
1201 } | |
1202 // }}}1 | |
1203 // int close_kmail_dir() {{{1 | |
1204 int close_kmail_dir() { | |
1205 // change .. | |
1206 int x; | |
1207 DEBUG_ENT("close_kmail_dir"); | |
1208 if (kmail_chdir != NULL) { //only free kmail_chdir if not NULL. do not change directory | |
1209 free(kmail_chdir); | |
1210 kmail_chdir = NULL; | |
1211 } else { | |
1212 if (chdir("..")) { | |
1213 x = errno; | |
1214 DIE(("close_kmail_dir: Cannot move up dir (..): %s\n", strerror(x))); | |
1215 } | |
1216 } | |
1217 DEBUG_RET(); | |
1218 return 0; | |
1219 } | |
1220 // }}}1 | |
1221 // char *mk_recurse_dir(char *dir) {{{1 | |
1222 // this will create a directory by that name, then make an mbox file inside | |
1223 // that dir. any subsequent dirs will be created by name, and they will | |
1224 // contain mbox files | |
1225 char *mk_recurse_dir(char *dir) { | |
1226 int x; | |
1227 char *out_name; | |
1228 DEBUG_ENT("mk_recurse_dir"); | |
1229 dir = check_filename(dir); | |
1230 if (D_MKDIR (dir)) { | |
1231 if (errno != EEXIST) { // not an error because it exists | |
1232 x = errno; | |
1233 DIE(("mk_recurse_dir: Cannot create directory %s: %s\n", dir, strerror(x))); | |
1234 } | |
1235 } | |
1236 if (chdir (dir)) { | |
1237 x = errno; | |
1238 DIE(("mk_recurse_dir: Cannot change to directory %s: %s\n", dir, strerror(x))); | |
1239 } | |
1240 out_name = malloc(strlen("mbox")+1); | |
1241 strcpy(out_name, "mbox"); | |
1242 DEBUG_RET(); | |
1243 return out_name; | |
1244 } | |
1245 // }}}1 | |
1246 // int close_recurse_dir() {{{1 | |
1247 int close_recurse_dir() { | |
1248 int x; | |
1249 DEBUG_ENT("close_recurse_dir"); | |
1250 if (chdir("..")) { | |
1251 x = errno; | |
1252 DIE(("close_recurse_dir: Cannot go up dir (..): %s\n", strerror(x))); | |
1253 } | |
1254 DEBUG_RET(); | |
1255 return 0; | |
1256 } | |
1257 // }}}1 | |
1258 // char *mk_seperate_dir(char *dir, int overwrite) {{{1 | |
1259 char *mk_seperate_dir(char *dir, int overwrite) { | |
1260 #if !defined(WIN32) && !defined(__CYGWIN__) | |
1261 DIR * sdir = NULL; | |
1262 struct dirent *dirent = NULL; | |
1263 struct stat *filestat = xmalloc(sizeof(struct stat)); | |
1264 #endif | |
1265 | |
1266 char *dir_name = NULL; | |
1267 int x = 0, y = 0; | |
1268 DEBUG_ENT("mk_seperate_dir"); | |
1269 /*#if defined(WIN32) || defined(__CYGWIN__) | |
1270 DIE(("mk_seperate_dir: Win32 applications cannot use this function yet.\n")); | |
1271 #endif*/ | |
1272 | |
1273 dir_name = xmalloc(strlen(dir)+10); | |
1274 | |
1275 do { | |
1276 if (y == 0) | |
1277 sprintf(dir_name, "%s", dir); | |
1278 else | |
1279 sprintf(dir_name, "%s%09i", dir, y); // enough for 9 digits allocated above | |
1280 | |
1281 dir_name = check_filename(dir_name); | |
1282 DEBUG_MAIN(("mk_seperate_dir: about to try creating %s\n", dir_name)); | |
1283 if (D_MKDIR(dir_name)) { | |
1284 if (errno != EEXIST) { // if there is an error, and it doesn't already exist | |
1285 x = errno; | |
1286 DIE(("mk_seperate_dir: Cannot create directory %s: %s\n", dir, strerror(x))); | |
1287 } | |
1288 } else { | |
1289 break; | |
1290 } | |
1291 y++; | |
1292 } while (overwrite == 0); | |
1293 | |
1294 if (chdir (dir_name)) { | |
1295 x = errno; | |
1296 DIE(("mk_recurse_dir: Cannot change to directory %s: %s\n", dir, strerror(x))); | |
1297 } | |
1298 | |
1299 if (overwrite) { | |
1300 // we should probably delete all files from this directory | |
1301 #if !defined(WIN32) && !defined(__CYGWIN__) | |
1302 if ((sdir = opendir("./")) == NULL) { | |
1303 WARN(("mk_seperate_dir: Cannot open dir \"%s\" for deletion of old contents\n", "./")); | |
1304 } else { | |
1305 while ((dirent = readdir(sdir)) != NULL) { | |
1306 if (lstat(dirent->d_name, filestat) != -1) | |
1307 if (S_ISREG(filestat->st_mode)) { | |
1308 if (unlink(dirent->d_name)) { | |
1309 y = errno; | |
1310 DIE(("mk_seperate_dir: unlink returned error on file %s: %s\n", dirent->d_name, strerror(y))); | |
1150 } | 1311 } |
1151 } | 1312 } |
1152 kmail_chdir = realloc(kmail_chdir, strlen(dir)+1); | 1313 } |
1153 strcpy(kmail_chdir, dir); | 1314 } |
1154 free (dir); | 1315 #endif |
1155 | 1316 } |
1156 //we should remove any existing indexes created by KMail, cause they might be different now | 1317 |
1157 index = malloc(strlen(fname)+strlen(KMAIL_INDEX)+1); | 1318 // overwrite will never change during this function, it is just there so that |
1158 sprintf(index, KMAIL_INDEX, fname); | 1319 // if overwrite is set, we only go through this loop once. |
1159 unlink(index); | 1320 |
1160 free(index); | 1321 // we don't return a filename here cause it isn't necessary. |
1161 | 1322 DEBUG_RET(); |
1162 out_name = malloc(strlen(fname)+strlen(OUTPUT_TEMPLATE)+1); | 1323 return NULL; |
1163 sprintf(out_name, OUTPUT_TEMPLATE, fname); | 1324 } |
1164 DEBUG_RET(); | 1325 // }}}1 |
1165 return out_name; | 1326 // int close_seperate_dir() {{{1 |
1166 } | 1327 int close_seperate_dir() { |
1167 | 1328 int x; |
1168 int close_kmail_dir() { | 1329 DEBUG_ENT("close_seperate_dir"); |
1169 // change .. | 1330 if (chdir("..")) { |
1170 int x; | 1331 x = errno; |
1171 DEBUG_ENT("close_kmail_dir"); | 1332 DIE(("close_seperate_dir: Cannot go up dir (..): %s\n", strerror(x))); |
1172 if (kmail_chdir != NULL) { //only free kmail_chdir if not NULL. do not change directory | 1333 } |
1173 free(kmail_chdir); | 1334 DEBUG_RET(); |
1174 kmail_chdir = NULL; | 1335 return 0; |
1336 } | |
1337 // }}}1 | |
1338 // int mk_seperate_file(struct file_ll *f) {{{1 | |
1339 int mk_seperate_file(struct file_ll *f) { | |
1340 DEBUG_ENT("mk_seperate_file"); | |
1341 DEBUG_MAIN(("mk_seperate_file: opening next file to save email\n")); | |
1342 if (f->email_count > 999999999) { // bigger than nine 9's | |
1343 DIE(("mk_seperate_file: The number of emails in this folder has become too high to handle")); | |
1344 } | |
1345 sprintf(f->name, "%09i", f->email_count); | |
1346 if (f->output != NULL) | |
1347 fclose(f->output); | |
1348 f->output = NULL; | |
1349 f->name = check_filename(f->name); | |
1350 if ((f->output = fopen(f->name, "w")) == NULL) { | |
1351 DIE(("mk_seperate_file: Cannot open file to save email \"%s\"\n", f->name)); | |
1352 } | |
1353 DEBUG_RET(); | |
1354 return 0; | |
1355 } | |
1356 // }}}1 | |
1357 // char *my_stristr(char *haystack, char *needle) {{{1 | |
1358 char *my_stristr(char *haystack, char *needle) { | |
1359 // my_stristr varies from strstr in that its searches are case-insensitive | |
1360 char *x=haystack, *y=needle, *z = NULL; | |
1361 DEBUG_ENT("my_stristr"); | |
1362 if (haystack == NULL || needle == NULL) | |
1363 return NULL; | |
1364 while (*y != '\0' && *x != '\0') { | |
1365 if (tolower(*y) == tolower(*x)) { | |
1366 // move y on one | |
1367 y++; | |
1368 if (z == NULL) { | |
1369 z = x; // store first position in haystack where a match is made | |
1370 } | |
1175 } else { | 1371 } else { |
1176 if (chdir("..")) { | 1372 y = needle; // reset y to the beginning of the needle |
1177 x = errno; | 1373 z = NULL; // reset the haystack storage point |
1178 DIE(("close_kmail_dir: Cannot move up dir (..): %s\n", strerror(x))); | 1374 } |
1179 } | 1375 x++; // advance the search in the haystack |
1180 } | 1376 } |
1181 DEBUG_RET(); | 1377 DEBUG_RET(); |
1182 return 0; | 1378 return z; |
1183 } | 1379 } |
1184 | 1380 // }}}1 |
1185 char* mk_recurse_dir(char *dir) { | 1381 // char *check_filename(char *fname) {{{1 |
1186 // this will create a directory by that name, then make an mbox file inside that dir. | |
1187 // any subsequent dirs will be created by name, and they will contain mbox files | |
1188 int x; | |
1189 char *out_name; | |
1190 DEBUG_ENT("mk_recurse_dir"); | |
1191 dir = check_filename(dir); | |
1192 if (D_MKDIR (dir)) { | |
1193 if (errno != EEXIST) { // not an error because it exists | |
1194 x = errno; | |
1195 DIE(("mk_recurse_dir: Cannot create directory %s: %s\n", dir, strerror(x))); | |
1196 } | |
1197 } | |
1198 if (chdir (dir)) { | |
1199 x = errno; | |
1200 DIE(("mk_recurse_dir: Cannot change to directory %s: %s\n", dir, strerror(x))); | |
1201 } | |
1202 out_name = malloc(strlen("mbox")+1); | |
1203 strcpy(out_name, "mbox"); | |
1204 DEBUG_RET(); | |
1205 return out_name; | |
1206 } | |
1207 | |
1208 int close_recurse_dir() { | |
1209 int x; | |
1210 DEBUG_ENT("close_recurse_dir"); | |
1211 if (chdir("..")) { | |
1212 x = errno; | |
1213 DIE(("close_recurse_dir: Cannot go up dir (..): %s\n", strerror(x))); | |
1214 } | |
1215 DEBUG_RET(); | |
1216 return 0; | |
1217 } | |
1218 | |
1219 char* mk_seperate_dir(char *dir, int overwrite) { | |
1220 #if !defined(WIN32) && !defined(__CYGWIN__) | |
1221 DIR * sdir = NULL; | |
1222 struct dirent *dirent = NULL; | |
1223 struct stat *filestat = xmalloc(sizeof(struct stat)); | |
1224 #endif | |
1225 | |
1226 char *dir_name = NULL; | |
1227 int x = 0, y = 0; | |
1228 DEBUG_ENT("mk_seperate_dir"); | |
1229 /*#if defined(WIN32) || defined(__CYGWIN__) | |
1230 DIE(("mk_seperate_dir: Win32 applications cannot use this function yet.\n")); | |
1231 #endif*/ | |
1232 | |
1233 dir_name = xmalloc(strlen(dir)+10); | |
1234 | |
1235 do { | |
1236 if (y == 0) | |
1237 sprintf(dir_name, "%s", dir); | |
1238 else | |
1239 sprintf(dir_name, "%s%09i", dir, y); // enough for 9 digits allocated above | |
1240 | |
1241 dir_name = check_filename(dir_name); | |
1242 DEBUG_MAIN(("mk_seperate_dir: about to try creating %s\n", dir_name)); | |
1243 if (D_MKDIR(dir_name)) { | |
1244 if (errno != EEXIST) { // if there is an error, and it doesn't already exist | |
1245 x = errno; | |
1246 DIE(("mk_seperate_dir: Cannot create directory %s: %s\n", dir, strerror(x))); | |
1247 } | |
1248 } else { | |
1249 break; | |
1250 } | |
1251 y++; | |
1252 } while (overwrite == 0); | |
1253 | |
1254 if (chdir (dir_name)) { | |
1255 x = errno; | |
1256 DIE(("mk_recurse_dir: Cannot change to directory %s: %s\n", dir, strerror(x))); | |
1257 } | |
1258 | |
1259 if (overwrite) { | |
1260 // we should probably delete all files from this directory | |
1261 #if !defined(WIN32) && !defined(__CYGWIN__) | |
1262 if ((sdir = opendir("./")) == NULL) { | |
1263 WARN(("mk_seperate_dir: Cannot open dir \"%s\" for deletion of old contents\n", "./")); | |
1264 } else { | |
1265 while ((dirent = readdir(sdir)) != NULL) { | |
1266 if (lstat(dirent->d_name, filestat) != -1) | |
1267 if (S_ISREG(filestat->st_mode)) { | |
1268 if (unlink(dirent->d_name)) { | |
1269 y = errno; | |
1270 DIE(("mk_seperate_dir: unlink returned error on file %s: %s\n", dirent->d_name, strerror(y))); | |
1271 } | |
1272 } | |
1273 } | |
1274 } | |
1275 #endif | |
1276 } | |
1277 | |
1278 // overwrite will never change during this function, it is just there so that | |
1279 // if overwrite is set, we only go through this loop once. | |
1280 | |
1281 // we don't return a filename here cause it isn't necessary. | |
1282 DEBUG_RET(); | |
1283 return NULL; | |
1284 } | |
1285 | |
1286 int close_seperate_dir() { | |
1287 int x; | |
1288 DEBUG_ENT("close_seperate_dir"); | |
1289 if (chdir("..")) { | |
1290 x = errno; | |
1291 DIE(("close_seperate_dir: Cannot go up dir (..): %s\n", strerror(x))); | |
1292 } | |
1293 DEBUG_RET(); | |
1294 return 0; | |
1295 } | |
1296 | |
1297 int mk_seperate_file(struct file_ll *f) { | |
1298 DEBUG_ENT("mk_seperate_file"); | |
1299 DEBUG_MAIN(("mk_seperate_file: opening next file to save email\n")); | |
1300 if (f->email_count > 999999999) { // bigger than nine 9's | |
1301 DIE(("mk_seperate_file: The number of emails in this folder has become too high to handle")); | |
1302 } | |
1303 sprintf(f->name, "%09i", f->email_count); | |
1304 if (f->output != NULL) | |
1305 fclose(f->output); | |
1306 f->output = NULL; | |
1307 f->name = check_filename(f->name); | |
1308 if ((f->output = fopen(f->name, "w")) == NULL) { | |
1309 DIE(("mk_seperate_file: Cannot open file to save email \"%s\"\n", f->name)); | |
1310 } | |
1311 DEBUG_RET(); | |
1312 return 0; | |
1313 } | |
1314 | |
1315 // my_stristr varies from strstr in that its searches are case-insensitive | |
1316 char * my_stristr(char *haystack, char *needle) { | |
1317 char *x=haystack, *y=needle, *z = NULL; | |
1318 DEBUG_ENT("my_stristr"); | |
1319 if (haystack == NULL || needle == NULL) | |
1320 return NULL; | |
1321 while (*y != '\0' && *x != '\0') { | |
1322 if (tolower(*y) == tolower(*x)) { | |
1323 // move y on one | |
1324 y++; | |
1325 if (z == NULL) { | |
1326 z = x; // store first position in haystack where a match is made | |
1327 } | |
1328 } else { | |
1329 y = needle; // reset y to the beginning of the needle | |
1330 z = NULL; // reset the haystack storage point | |
1331 } | |
1332 x++; // advance the search in the haystack | |
1333 } | |
1334 DEBUG_RET(); | |
1335 return z; | |
1336 } | |
1337 | |
1338 char *check_filename(char *fname) { | 1382 char *check_filename(char *fname) { |
1339 char *t = fname; | 1383 char *t = fname; |
1340 DEBUG_ENT("check_filename"); | 1384 DEBUG_ENT("check_filename"); |
1341 if (t == NULL) { | 1385 if (t == NULL) { |
1342 DEBUG_RET(); | |
1343 return fname; | |
1344 } | |
1345 while ((t = strpbrk(t, "/\\:")) != NULL) { | |
1346 // while there are characters in the second string that we don't want | |
1347 *t = '_'; //replace them with an underscore | |
1348 } | |
1349 DEBUG_RET(); | 1386 DEBUG_RET(); |
1350 return fname; | 1387 return fname; |
1351 } | 1388 } |
1352 | 1389 while ((t = strpbrk(t, "/\\:")) != NULL) { |
1390 // while there are characters in the second string that we don't want | |
1391 *t = '_'; //replace them with an underscore | |
1392 } | |
1393 DEBUG_RET(); | |
1394 return fname; | |
1395 } | |
1396 // }}}1 | |
1397 // char *rfc2426_escape(char *str) {{{1 | |
1353 char *rfc2426_escape(char *str) { | 1398 char *rfc2426_escape(char *str) { |
1354 static char* buf = NULL; | 1399 static char* buf = NULL; |
1355 char *ret, *a, *b; | 1400 char *ret, *a, *b; |
1356 int x = 0, y, z; | 1401 int x = 0, y, z; |
1357 DEBUG_ENT("rfc2426_escape"); | 1402 DEBUG_ENT("rfc2426_escape"); |
1358 if (str == NULL) | 1403 if (str == NULL) |
1359 ret = str; | 1404 ret = str; |
1405 else { | |
1406 | |
1407 // calculate space required to escape all the following characters | |
1408 x = strlen(str) +(y=(chr_count(str, ',')*2) + (chr_count(str, '\\')*2) + (chr_count(str, ';')*2) + (chr_count(str, '\n')*2)); | |
1409 z = chr_count(str, '\r'); | |
1410 if (y == 0 && z == 0) | |
1411 // there isn't any extra space required | |
1412 ret = str; | |
1360 else { | 1413 else { |
1361 | 1414 buf = (char*) realloc(buf, x+1); |
1362 // calculate space required to escape all the following characters | 1415 a = str; |
1363 x = strlen(str) +(y=(chr_count(str, ',')*2) + (chr_count(str, '\\')*2) + (chr_count(str, ';')*2) + (chr_count(str, '\n')*2)); | 1416 b = buf; |
1364 z = chr_count(str, '\r'); | 1417 while (*a != '\0') { |
1365 if (y == 0 && z == 0) | 1418 switch(*a) { |
1366 // there isn't any extra space required | 1419 case ',' : |
1367 ret = str; | 1420 case '\\': |
1368 else { | 1421 case ';' : |
1369 buf = (char*) realloc(buf, x+1); | 1422 case '\n': |
1370 a = str; | 1423 *(b++)='\\'; |
1371 b = buf; | 1424 *b=*a; |
1372 while (*a != '\0') { | 1425 break; |
1373 switch(*a) { | 1426 case '\r': |
1374 case ',' : | 1427 break; |
1375 case '\\': | 1428 default: |
1376 case ';' : | 1429 *b=*a; |
1377 case '\n': | 1430 } |
1378 *(b++)='\\'; | 1431 b++; |
1379 *b=*a; | 1432 a++; |
1380 break; | 1433 } |
1381 case '\r': | 1434 *b = '\0'; |
1382 break; | 1435 ret = buf; |
1383 default: | 1436 } |
1384 *b=*a; | 1437 } |
1385 } | 1438 DEBUG_RET(); |
1386 b++; | 1439 return ret; |
1387 a++; | 1440 } |
1388 } | 1441 // }}}1 |
1389 *b = '\0'; | 1442 // int chr_count(char *str, char x) {{{1 |
1390 ret = buf; | |
1391 } | |
1392 } | |
1393 DEBUG_RET(); | |
1394 return ret; | |
1395 } | |
1396 | |
1397 int chr_count(char *str, char x) { | 1443 int chr_count(char *str, char x) { |
1398 int r = 0; | 1444 int r = 0; |
1399 while (*str != '\0') { | 1445 while (*str != '\0') { |
1400 if (*str == x) | 1446 if (*str == x) |
1401 r++; | 1447 r++; |
1402 str++; | 1448 str++; |
1403 } | 1449 } |
1404 return r; | 1450 return r; |
1405 } | 1451 } |
1406 | 1452 // }}}1 |
1453 // char *rfc2425_datetime_format(FILETIME *ft) {{{1 | |
1407 char *rfc2425_datetime_format(FILETIME *ft) { | 1454 char *rfc2425_datetime_format(FILETIME *ft) { |
1408 static char * buffer = NULL; | 1455 static char * buffer = NULL; |
1409 struct tm *stm = NULL; | 1456 struct tm *stm = NULL; |
1410 DEBUG_ENT("rfc2425_datetime_format"); | 1457 DEBUG_ENT("rfc2425_datetime_format"); |
1411 if (buffer == NULL) | 1458 if (buffer == NULL) |
1412 buffer = malloc(30); // should be enough for the date as defined below | 1459 buffer = malloc(30); // should be enough for the date as defined below |
1413 | 1460 |
1414 stm = fileTimeToStructTM(ft); | 1461 stm = fileTimeToStructTM(ft); |
1415 //Year[4]-Month[2]-Day[2] Hour[2]:Min[2]:Sec[2] | 1462 //Year[4]-Month[2]-Day[2] Hour[2]:Min[2]:Sec[2] |
1416 if (strftime(buffer, 30, "%Y-%m-%dT%H:%M:%SZ", stm)==0) { | 1463 if (strftime(buffer, 30, "%Y-%m-%dT%H:%M:%SZ", stm)==0) { |
1417 DEBUG_INFO(("Problem occured formatting date\n")); | 1464 DEBUG_INFO(("Problem occured formatting date\n")); |
1418 } | 1465 } |
1419 DEBUG_RET(); | 1466 DEBUG_RET(); |
1420 return buffer; | 1467 return buffer; |
1421 } | 1468 } |
1469 // }}}1 | |
1470 // char *rfc2445_datetime_format(FILETIME *ft) {{{1 | |
1422 char *rfc2445_datetime_format(FILETIME *ft) { | 1471 char *rfc2445_datetime_format(FILETIME *ft) { |
1423 static char* buffer = NULL; | 1472 static char* buffer = NULL; |
1424 struct tm *stm = NULL; | 1473 struct tm *stm = NULL; |
1425 DEBUG_ENT("rfc2445_datetime_format"); | 1474 DEBUG_ENT("rfc2445_datetime_format"); |
1426 if (buffer == NULL) | 1475 if (buffer == NULL) |
1427 buffer = malloc(30); // should be enough | 1476 buffer = malloc(30); // should be enough |
1428 stm = fileTimeToStructTM(ft); | 1477 stm = fileTimeToStructTM(ft); |
1429 if (strftime(buffer, 30, "%Y%m%dT%H%M%SZ", stm)==0) { | 1478 if (strftime(buffer, 30, "%Y%m%dT%H%M%SZ", stm)==0) { |
1430 DEBUG_INFO(("Problem occured formatting date\n")); | 1479 DEBUG_INFO(("Problem occured formatting date\n")); |
1431 } | 1480 } |
1432 DEBUG_RET(); | 1481 DEBUG_RET(); |
1433 return buffer; | 1482 return buffer; |
1434 } | 1483 } |
1484 // }}}1 | |
1485 // char *skip_header_prologue(char *headers) {{{1 | |
1486 // The sole purpose of this function is to bypass the pseudo-header prologue | |
1487 // that Microsoft Outlook inserts at the beginning of the internet email | |
1488 // headers for emails stored in their "Personal Folders" files. | |
1489 char *skip_header_prologue(char *headers) { | |
1490 const char *bad = "Microsoft Mail Internet Headers"; | |
1491 | |
1492 if ( strncmp(headers, bad, strlen(bad)) == 0 ) { | |
1493 // Found the offensive header prologue | |
1494 char *pc; | |
1495 | |
1496 pc = strchr(headers, '\n'); | |
1497 return pc + 1; | |
1498 } | |
1499 | |
1500 return headers; | |
1501 } | |
1502 // }}}1 | |
1503 | |
1504 // vim:sw=4 ts=4: | |
1505 // vim600: set foldlevel=0 foldmethod=marker: |