comparison src/readpst.c @ 31:b88ceb81dba2

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