00001
00002
00003
00004
00005
00006
00007 #include "define.h"
00008 #include "libstrfunc.h"
00009 #include "libpst.h"
00010 #include "common.h"
00011 #include "timeconv.h"
00012 #include "lzfu.h"
00013
00014 #define OUTPUT_TEMPLATE "%s"
00015 #define OUTPUT_KMAIL_DIR_TEMPLATE ".%s.directory"
00016 #define KMAIL_INDEX ".%s.index"
00017 #define SEP_MAIL_FILE_TEMPLATE "%i"
00018
00019
00020 #define C_TIME_SIZE 500
00021
00022 struct file_ll {
00023 char *name;
00024 char *dname;
00025 FILE * output;
00026 int32_t stored_count;
00027 int32_t email_count;
00028 int32_t skip_count;
00029 int32_t type;
00030 };
00031
00032 void process(pst_item *outeritem, pst_desc_ll *d_ptr);
00033 void write_email_body(FILE *f, char *body);
00034 char* removeCR (char *c);
00035 int usage();
00036 int version();
00037 char* mk_kmail_dir(char*);
00038 int close_kmail_dir();
00039 char* mk_recurse_dir(char*);
00040 int close_recurse_dir();
00041 char* mk_separate_dir(char *dir);
00042 int close_separate_dir();
00043 int mk_separate_file(struct file_ll *f);
00044 char* my_stristr(char *haystack, char *needle);
00045 void check_filename(char *fname);
00046 char* skip_header_prologue(char *headers);
00047 void write_separate_attachment(char f_name[], pst_item_attach* current_attach, int attach_num, pst_file* pst);
00048 void write_inline_attachment(FILE* f_output, pst_item_attach* current_attach, char boundary[], pst_file* pst);
00049 void write_normal_email(FILE* f_output, char f_name[], pst_item* item, int mode, int mode_MH, pst_file* pst, int save_rtf);
00050 void write_vcard(FILE* f_output, pst_item_contact* contact, char comment[]);
00051 void write_appointment(FILE* f_output, pst_item_appointment* appointment,
00052 pst_item_email* email, FILETIME* create_date, FILETIME* modify_date);
00053 void create_enter_dir(struct file_ll* f, pst_item *item);
00054 void close_enter_dir(struct file_ll *f);
00055
00056 char* prog_name;
00057 char* output_dir = ".";
00058 char* kmail_chdir = NULL;
00059
00060
00061
00062 #define MODE_NORMAL 0
00063
00064
00065
00066 #define MODE_KMAIL 1
00067
00068
00069
00070 #define MODE_RECURSE 2
00071
00072
00073
00074
00075 #define MODE_SEPARATE 3
00076
00077
00078 #define MODE_DECSPEW 4
00079
00080
00081
00082 #define OUTPUT_NORMAL 0
00083
00084
00085 #define OUTPUT_QUIET 1
00086
00087
00088 #define MIME_TYPE_DEFAULT "application/octet-stream"
00089
00090
00091 #define CMODE_VCARD 0
00092 #define CMODE_LIST 1
00093
00094
00095
00096 #define RTF_ATTACH_NAME "rtf-body.rtf"
00097
00098 #define RTF_ATTACH_TYPE "application/rtf"
00099
00100
00101 int mode = MODE_NORMAL;
00102 int mode_MH = 0;
00103 int output_mode = OUTPUT_NORMAL;
00104 int contact_mode = CMODE_VCARD;
00105 int overwrite = 0;
00106 int save_rtf_body = 1;
00107 pst_file pstfile;
00108
00109
00110
00111 void process(pst_item *outeritem, pst_desc_ll *d_ptr)
00112 {
00113 struct file_ll ff;
00114 pst_item *item = NULL;
00115
00116 DEBUG_ENT("process");
00117 memset(&ff, 0, sizeof(ff));
00118 create_enter_dir(&ff, outeritem);
00119
00120 while (d_ptr) {
00121 DEBUG_MAIN(("main: New item record\n"));
00122 if (!d_ptr->desc) {
00123 DEBUG_WARN(("main: ERROR ?? item's desc record is NULL\n"));
00124 ff.skip_count++;
00125 }
00126 else {
00127 DEBUG_MAIN(("main: Desc Email ID %#x [d_ptr->id = %#x]\n", d_ptr->desc->id, d_ptr->id));
00128
00129 item = pst_parse_item(&pstfile, d_ptr);
00130 DEBUG_MAIN(("main: About to process item\n"));
00131 if (item && item->email && item->email->subject && item->email->subject->subj) {
00132 DEBUG_EMAIL(("item->email->subject = %p\n", item->email->subject));
00133 DEBUG_EMAIL(("item->email->subject->subj = %p\n", item->email->subject->subj));
00134 }
00135 if (item) {
00136 if (item->folder && d_ptr->child && strcasecmp(item->file_as, "Deleted Items")) {
00137
00138 if (output_mode != OUTPUT_QUIET) printf("Processing Folder \"%s\"\n", item->file_as);
00139 process(item, d_ptr->child);
00140
00141 } else if (item->contact && (item->type == PST_TYPE_CONTACT)) {
00142
00143
00144
00145 if (mode == MODE_SEPARATE) mk_separate_file(&ff);
00146 ff.email_count++;
00147 DEBUG_MAIN(("main: Processing Contact\n"));
00148 if (ff.type != PST_TYPE_CONTACT) {
00149 DEBUG_MAIN(("main: I have a contact, but the folder isn't a contacts folder. Processing anyway\n"));
00150 }
00151 if (contact_mode == CMODE_VCARD)
00152 write_vcard(ff.output, item->contact, item->comment);
00153 else
00154 fprintf(ff.output, "%s <%s>\n", item->contact->fullname, item->contact->address1);
00155
00156 } else if (item->email && (item->type == PST_TYPE_NOTE || item->type == PST_TYPE_REPORT)) {
00157 if (mode == MODE_SEPARATE) mk_separate_file(&ff);
00158 ff.email_count++;
00159 DEBUG_MAIN(("main: Processing Email\n"));
00160 if ((ff.type != PST_TYPE_NOTE) && (ff.type != PST_TYPE_REPORT)) {
00161 DEBUG_MAIN(("main: I have an email, but the folder isn't an email folder. Processing anyway\n"));
00162 }
00163 write_normal_email(ff.output, ff.name, item, mode, mode_MH, &pstfile, save_rtf_body);
00164
00165 } else if (item->journal && (item->type == PST_TYPE_JOURNAL)) {
00166
00167 if (mode == MODE_SEPARATE) mk_separate_file(&ff);
00168 ff.email_count++;
00169 DEBUG_MAIN(("main: Processing Journal Entry\n"));
00170 if (ff.type != PST_TYPE_JOURNAL) {
00171 DEBUG_MAIN(("main: I have a journal entry, but the folder isn't a journal folder. Processing anyway\n"));
00172 }
00173 fprintf(ff.output, "BEGIN:VJOURNAL\n");
00174 if (item->email && item->email->subject && item->email->subject->subj)
00175 fprintf(ff.output, "SUMMARY:%s\n", pst_rfc2426_escape(item->email->subject->subj));
00176 if (item->email && item->email->body)
00177 fprintf(ff.output, "DESCRIPTION:%s\n", pst_rfc2426_escape(item->email->body));
00178 if (item->journal->start)
00179 fprintf(ff.output, "DTSTART;VALUE=DATE-TIME:%s\n", pst_rfc2445_datetime_format(item->journal->start));
00180 fprintf(ff.output, "END:VJOURNAL\n\n");
00181
00182 } else if (item->appointment && (item->type == PST_TYPE_APPOINTMENT)) {
00183
00184 if (mode == MODE_SEPARATE) mk_separate_file(&ff);
00185 ff.email_count++;
00186 DEBUG_MAIN(("main: Processing Appointment Entry\n"));
00187 if (ff.type != PST_TYPE_APPOINTMENT) {
00188 DEBUG_MAIN(("main: I have an appointment, but folder isn't specified as an appointment type. Processing...\n"));
00189 }
00190 write_appointment(ff.output, item->appointment, item->email, item->create_date, item->modify_date);
00191
00192 } else if (item->message_store) {
00193
00194 DEBUG_MAIN(("item with message store content, type %i %s folder type %i, skipping it\n", item->type, item->ascii_type, ff.type));
00195
00196 } else {
00197
00198
00199 DEBUG_MAIN(("main: Unknown item type %i (%s) name (%s)\n",
00200 item->type, item->ascii_type, item->file_as));
00201 }
00202 pst_freeItem(item);
00203 } else {
00204 ff.skip_count++;
00205 DEBUG_MAIN(("main: A NULL item was seen\n"));
00206 }
00207 d_ptr = d_ptr->next;
00208 }
00209 }
00210 close_enter_dir(&ff);
00211 DEBUG_RET();
00212 }
00213
00214
00215
00216 int main(int argc, char** argv) {
00217 pst_item *item = NULL;
00218 pst_desc_ll *d_ptr;
00219 char * fname = NULL;
00220 char *d_log = NULL;
00221 int c,x;
00222 char *temp = NULL;
00223 prog_name = argv[0];
00224
00225
00226 while ((c = getopt(argc, argv, "bCc:d:hko:qrSMVw"))!= -1) {
00227 switch (c) {
00228 case 'b':
00229 save_rtf_body = 0;
00230 break;
00231 case 'C':
00232 mode = MODE_DECSPEW;
00233 break;
00234 case 'c':
00235 if (optarg && optarg[0]=='v')
00236 contact_mode=CMODE_VCARD;
00237 else if (optarg && optarg[0]=='l')
00238 contact_mode=CMODE_LIST;
00239 else {
00240 usage();
00241 exit(0);
00242 }
00243 break;
00244 case 'd':
00245 d_log = optarg;
00246 break;
00247 case 'h':
00248 usage();
00249 exit(0);
00250 break;
00251 case 'V':
00252 version();
00253 exit(0);
00254 break;
00255 case 'k':
00256 mode = MODE_KMAIL;
00257 break;
00258 case 'M':
00259 mode = MODE_SEPARATE;
00260 mode_MH = 1;
00261 break;
00262 case 'o':
00263 output_dir = optarg;
00264 break;
00265 case 'q':
00266 output_mode = OUTPUT_QUIET;
00267 break;
00268 case 'r':
00269 mode = MODE_RECURSE;
00270 break;
00271 case 'S':
00272 mode = MODE_SEPARATE;
00273 break;
00274 case 'w':
00275 overwrite = 1;
00276 break;
00277 default:
00278 usage();
00279 exit(1);
00280 break;
00281 }
00282 }
00283
00284 if (argc > optind) {
00285 fname = argv[optind];
00286 } else {
00287 usage();
00288 exit(2);
00289 }
00290
00291 #ifdef DEBUG_ALL
00292
00293 if (!d_log) d_log = "readpst.log";
00294 #endif // defined DEBUG_ALL
00295 DEBUG_INIT(d_log);
00296 DEBUG_REGISTER_CLOSE();
00297 DEBUG_ENT("main");
00298
00299 if (mode == MODE_DECSPEW) {
00300 FILE *fp;
00301 char buf[1024];
00302 size_t l = 0;
00303 if (NULL == (fp = fopen(fname, "rb"))) {
00304 fprintf(stderr, "Couldn't open file %s\n", fname );
00305 DEBUG_RET();
00306 return 1;
00307 }
00308
00309 while (0 != (l = fread(buf, 1, 1024, fp))) {
00310 if (0 != pst_decrypt(0, buf, l, PST_COMP_ENCRYPT))
00311 fprintf(stderr, "pst_decrypt() failed (I'll try to continue)\n");
00312
00313 if (l != pst_fwrite(buf, 1, l, stdout)) {
00314 fprintf(stderr, "Couldn't output to stdout?\n");
00315 DEBUG_RET();
00316 return 1;
00317 }
00318 }
00319 DEBUG_RET();
00320 return 0;
00321 }
00322
00323 if (output_mode != OUTPUT_QUIET) printf("Opening PST file and indexes...\n");
00324
00325 RET_DERROR(pst_open(&pstfile, fname), 1, ("Error opening File\n"));
00326 RET_DERROR(pst_load_index(&pstfile), 2, ("Index Error\n"));
00327
00328 pst_load_extended_attributes(&pstfile);
00329
00330 if (chdir(output_dir)) {
00331 x = errno;
00332 pst_close(&pstfile);
00333 DEBUG_RET();
00334 DIE(("main: Cannot change to output dir %s: %s\n", output_dir, strerror(x)));
00335 }
00336
00337 if (output_mode != OUTPUT_QUIET) printf("About to start processing first record...\n");
00338
00339 d_ptr = pstfile.d_head;
00340 item = pst_parse_item(&pstfile, d_ptr);
00341 if (!item || !item->message_store) {
00342 DEBUG_RET();
00343 DIE(("main: Could not get root record\n"));
00344 }
00345
00346
00347 if (!item->file_as) {
00348 if (!(temp = strrchr(fname, '/')))
00349 if (!(temp = strrchr(fname, '\\')))
00350 temp = fname;
00351 else
00352 temp++;
00353 else
00354 temp++;
00355 item->file_as = (char*)xmalloc(strlen(temp)+1);
00356 strcpy(item->file_as, temp);
00357 DEBUG_MAIN(("file_as was blank, so am using %s\n", item->file_as));
00358 }
00359 DEBUG_MAIN(("main: Root Folder Name: %s\n", item->file_as));
00360
00361 d_ptr = pst_getTopOfFolders(&pstfile, item);
00362 if (!d_ptr) {
00363 DEBUG_RET();
00364 DIE(("Top of folders record not found. Cannot continue\n"));
00365 }
00366
00367 process(item, d_ptr->child);
00368 pst_freeItem(item);
00369 pst_close(&pstfile);
00370 DEBUG_RET();
00371 return 0;
00372 }
00373
00374
00375 void write_email_body(FILE *f, char *body) {
00376 char *n = body;
00377
00378 DEBUG_ENT("write_email_body");
00379 while (n) {
00380 if (strncmp(body, "From ", 5) == 0)
00381 fprintf(f, ">");
00382 if ((n = strchr(body, '\n'))) {
00383 n++;
00384 pst_fwrite(body, n-body, 1, f);
00385 body = n;
00386 }
00387 }
00388 pst_fwrite(body, strlen(body), 1, f);
00389 DEBUG_RET();
00390 }
00391
00392
00393 char *removeCR (char *c) {
00394
00395 char *a, *b;
00396 DEBUG_ENT("removeCR");
00397 a = b = c;
00398 while (*a != '\0') {
00399 *b = *a;
00400 if (*a != '\r')
00401 b++;
00402 a++;
00403 }
00404 *b = '\0';
00405 DEBUG_RET();
00406 return c;
00407 }
00408
00409
00410 int usage() {
00411 DEBUG_ENT("usage");
00412 version();
00413 printf("Usage: %s [OPTIONS] {PST FILENAME}\n", prog_name);
00414 printf("OPTIONS:\n");
00415 printf("\t-C\t- Decrypt (compressible encryption) the entire file and output on stdout (not typically useful)\n");
00416 printf("\t-M\t- MH. Write emails in the MH format\n");
00417 printf("\t-S\t- Separate. Write emails in the separate format\n");
00418 printf("\t-V\t- Version. Display program version\n");
00419 printf("\t-b\t- Don't save RTF-Body attachments\n");
00420 printf("\t-c[v|l]\t- Set the Contact output mode. -cv = VCard, -cl = EMail list\n");
00421 printf("\t-d <filename> \t- Debug to file. This is a binary log. Use readpstlog to print it\n");
00422 printf("\t-h\t- Help. This screen\n");
00423 printf("\t-k\t- KMail. Output in kmail format\n");
00424 printf("\t-o <dirname>\t- Output directory to write files to. CWD is changed *after* opening pst file\n");
00425 printf("\t-q\t- Quiet. Only print error messages\n");
00426 printf("\t-r\t- Recursive. Output in a recursive format\n");
00427 printf("\t-w\t- Overwrite any output mbox files\n");
00428 DEBUG_RET();
00429 return 0;
00430 }
00431
00432
00433 int version() {
00434 DEBUG_ENT("version");
00435 printf("ReadPST / LibPST v%s\n", VERSION);
00436 #if BYTE_ORDER == BIG_ENDIAN
00437 printf("Big Endian implementation being used.\n");
00438 #elif BYTE_ORDER == LITTLE_ENDIAN
00439 printf("Little Endian implementation being used.\n");
00440 #else
00441 # error "Byte order not supported by this library"
00442 #endif
00443 #ifdef __GNUC__
00444 printf("GCC %d.%d : %s %s\n", __GNUC__, __GNUC_MINOR__, __DATE__, __TIME__);
00445 #endif
00446 DEBUG_RET();
00447 return 0;
00448 }
00449
00450
00451 char *mk_kmail_dir(char *fname) {
00452
00453
00454
00455
00456 char *dir, *out_name, *index;
00457 int x;
00458 DEBUG_ENT("mk_kmail_dir");
00459 if (kmail_chdir && chdir(kmail_chdir)) {
00460 x = errno;
00461 DIE(("mk_kmail_dir: Cannot change to directory %s: %s\n", kmail_chdir, strerror(x)));
00462 }
00463 dir = malloc(strlen(fname)+strlen(OUTPUT_KMAIL_DIR_TEMPLATE)+1);
00464 sprintf(dir, OUTPUT_KMAIL_DIR_TEMPLATE, fname);
00465 check_filename(dir);
00466 if (D_MKDIR(dir)) {
00467
00468 if (errno != EEXIST) {
00469 x = errno;
00470 DIE(("mk_kmail_dir: Cannot create directory %s: %s\n", dir, strerror(x)));
00471 }
00472 }
00473 kmail_chdir = realloc(kmail_chdir, strlen(dir)+1);
00474 strcpy(kmail_chdir, dir);
00475 free (dir);
00476
00477
00478 index = malloc(strlen(fname)+strlen(KMAIL_INDEX)+1);
00479 sprintf(index, KMAIL_INDEX, fname);
00480 unlink(index);
00481 free(index);
00482
00483 out_name = malloc(strlen(fname)+strlen(OUTPUT_TEMPLATE)+1);
00484 sprintf(out_name, OUTPUT_TEMPLATE, fname);
00485 DEBUG_RET();
00486 return out_name;
00487 }
00488
00489
00490 int close_kmail_dir() {
00491
00492 int x;
00493 DEBUG_ENT("close_kmail_dir");
00494 if (kmail_chdir) {
00495 free(kmail_chdir);
00496 kmail_chdir = NULL;
00497 } else {
00498 if (chdir("..")) {
00499 x = errno;
00500 DIE(("close_kmail_dir: Cannot move up dir (..): %s\n", strerror(x)));
00501 }
00502 }
00503 DEBUG_RET();
00504 return 0;
00505 }
00506
00507
00508
00509
00510
00511 char *mk_recurse_dir(char *dir) {
00512 int x;
00513 char *out_name;
00514 DEBUG_ENT("mk_recurse_dir");
00515 check_filename(dir);
00516 if (D_MKDIR (dir)) {
00517 if (errno != EEXIST) {
00518 x = errno;
00519 DIE(("mk_recurse_dir: Cannot create directory %s: %s\n", dir, strerror(x)));
00520 }
00521 }
00522 if (chdir (dir)) {
00523 x = errno;
00524 DIE(("mk_recurse_dir: Cannot change to directory %s: %s\n", dir, strerror(x)));
00525 }
00526 out_name = malloc(strlen("mbox")+1);
00527 strcpy(out_name, "mbox");
00528 DEBUG_RET();
00529 return out_name;
00530 }
00531
00532
00533 int close_recurse_dir() {
00534 int x;
00535 DEBUG_ENT("close_recurse_dir");
00536 if (chdir("..")) {
00537 x = errno;
00538 DIE(("close_recurse_dir: Cannot go up dir (..): %s\n", strerror(x)));
00539 }
00540 DEBUG_RET();
00541 return 0;
00542 }
00543
00544
00545 char *mk_separate_dir(char *dir) {
00546 size_t dirsize = strlen(dir) + 10;
00547 char dir_name[dirsize];
00548 int x = 0, y = 0;
00549
00550 DEBUG_ENT("mk_separate_dir");
00551 do {
00552 if (y == 0)
00553 snprintf(dir_name, dirsize, "%s", dir);
00554 else
00555 snprintf(dir_name, dirsize, "%s" SEP_MAIL_FILE_TEMPLATE, dir, y);
00556
00557 check_filename(dir_name);
00558 DEBUG_MAIN(("about to try creating %s\n", dir_name));
00559 if (D_MKDIR(dir_name)) {
00560 if (errno != EEXIST) {
00561 x = errno;
00562 DIE(("mk_separate_dir: Cannot create directory %s: %s\n", dir, strerror(x)));
00563 }
00564 } else {
00565 break;
00566 }
00567 y++;
00568 } while (overwrite == 0);
00569
00570 if (chdir(dir_name)) {
00571 x = errno;
00572 DIE(("mk_separate_dir: Cannot change to directory %s: %s\n", dir, strerror(x)));
00573 }
00574
00575 if (overwrite) {
00576
00577 #if !defined(WIN32) && !defined(__CYGWIN__)
00578 DIR * sdir = NULL;
00579 struct dirent *dirent = NULL;
00580 struct stat filestat;
00581 if (!(sdir = opendir("./"))) {
00582 WARN(("mk_separate_dir: Cannot open dir \"%s\" for deletion of old contents\n", "./"));
00583 } else {
00584 while ((dirent = readdir(sdir))) {
00585 if (lstat(dirent->d_name, &filestat) != -1)
00586 if (S_ISREG(filestat.st_mode)) {
00587 if (unlink(dirent->d_name)) {
00588 y = errno;
00589 DIE(("mk_separate_dir: unlink returned error on file %s: %s\n", dirent->d_name, strerror(y)));
00590 }
00591 }
00592 }
00593 }
00594 #endif
00595 }
00596
00597
00598 DEBUG_RET();
00599 return NULL;
00600 }
00601
00602
00603 int close_separate_dir() {
00604 int x;
00605 DEBUG_ENT("close_separate_dir");
00606 if (chdir("..")) {
00607 x = errno;
00608 DIE(("close_separate_dir: Cannot go up dir (..): %s\n", strerror(x)));
00609 }
00610 DEBUG_RET();
00611 return 0;
00612 }
00613
00614
00615 int mk_separate_file(struct file_ll *f) {
00616 const int name_offset = 1;
00617 DEBUG_ENT("mk_separate_file");
00618 DEBUG_MAIN(("opening next file to save email\n"));
00619 if (f->email_count > 999999999) {
00620 DIE(("mk_separate_file: The number of emails in this folder has become too high to handle"));
00621 }
00622 sprintf(f->name, SEP_MAIL_FILE_TEMPLATE, f->email_count + name_offset);
00623 if (f->output) fclose(f->output);
00624 f->output = NULL;
00625 check_filename(f->name);
00626 if (!(f->output = fopen(f->name, "w"))) {
00627 DIE(("mk_separate_file: Cannot open file to save email \"%s\"\n", f->name));
00628 }
00629 DEBUG_RET();
00630 return 0;
00631 }
00632
00633
00634 char *my_stristr(char *haystack, char *needle) {
00635
00636 char *x=haystack, *y=needle, *z = NULL;
00637 DEBUG_ENT("my_stristr");
00638 if (!haystack || !needle) {
00639 DEBUG_RET();
00640 return NULL;
00641 }
00642 while (*y != '\0' && *x != '\0') {
00643 if (tolower(*y) == tolower(*x)) {
00644
00645 y++;
00646 if (!z) {
00647 z = x;
00648 }
00649 } else {
00650 y = needle;
00651 z = NULL;
00652 }
00653 x++;
00654 }
00655 DEBUG_RET();
00656 return z;
00657 }
00658
00659
00660 void check_filename(char *fname) {
00661 char *t = fname;
00662 DEBUG_ENT("check_filename");
00663 if (!t) {
00664 DEBUG_RET();
00665 return;
00666 }
00667 while ((t = strpbrk(t, "/\\:"))) {
00668
00669 *t = '_';
00670 }
00671 DEBUG_RET();
00672 }
00673
00674
00675
00676
00677
00678 char *skip_header_prologue(char *headers) {
00679 const char *bad = "Microsoft Mail Internet Headers";
00680 if (strncmp(headers, bad, strlen(bad)) == 0) {
00681
00682 char *pc = strchr(headers, '\n');
00683 return pc + 1;
00684 }
00685 return headers;
00686 }
00687
00688
00689 void write_separate_attachment(char f_name[], pst_item_attach* current_attach, int attach_num, pst_file* pst)
00690 {
00691 FILE *fp = NULL;
00692 int x = 0;
00693 char *temp = NULL;
00694
00695
00696
00697 char *attach_filename = (current_attach->filename2) ? current_attach->filename2
00698 : current_attach->filename1;
00699 DEBUG_ENT("write_separate_attachment");
00700
00701 check_filename(f_name);
00702 if (!attach_filename) {
00703
00704 temp = xmalloc(strlen(f_name)+15);
00705 sprintf(temp, "%s-attach%i", f_name, attach_num);
00706 } else {
00707
00708 temp = xmalloc(strlen(f_name)+strlen(attach_filename)+15);
00709 do {
00710 if (fp) fclose(fp);
00711 if (x == 0)
00712 sprintf(temp, "%s-%s", f_name, attach_filename);
00713 else
00714 sprintf(temp, "%s-%s-%i", f_name, attach_filename, x);
00715 } while ((fp = fopen(temp, "r")) && ++x < 99999999);
00716 if (x > 99999999) {
00717 DIE(("error finding attachment name. exhausted possibilities to %s\n", temp));
00718 }
00719 }
00720 DEBUG_EMAIL(("Saving attachment to %s\n", temp));
00721 if (!(fp = fopen(temp, "w"))) {
00722 WARN(("write_separate_attachment: Cannot open attachment save file \"%s\"\n", temp));
00723 } else {
00724 if (current_attach->data)
00725 pst_fwrite(current_attach->data, 1, current_attach->size, fp);
00726 else {
00727 (void)pst_attach_to_file(pst, current_attach, fp);
00728 }
00729 fclose(fp);
00730 }
00731 if (temp) free(temp);
00732 DEBUG_RET();
00733 }
00734
00735
00736 void write_inline_attachment(FILE* f_output, pst_item_attach* current_attach, char boundary[], pst_file* pst)
00737 {
00738 char *enc = NULL;
00739 DEBUG_ENT("write_inline_attachment");
00740 DEBUG_EMAIL(("Attachment Size is %i\n", current_attach->size));
00741 DEBUG_EMAIL(("Attachment Pointer is %p\n", current_attach->data));
00742 if (current_attach->data) {
00743 enc = base64_encode (current_attach->data, current_attach->size);
00744 if (!enc) {
00745 DEBUG_EMAIL(("ERROR base64_encode returned NULL. Must have failed\n"));
00746 DEBUG_RET();
00747 return;
00748 }
00749 }
00750 if (boundary) {
00751 char *attach_filename;
00752 fprintf(f_output, "\n--%s\n", boundary);
00753 if (!current_attach->mimetype) {
00754 fprintf(f_output, "Content-type: %s\n", MIME_TYPE_DEFAULT);
00755 } else {
00756 fprintf(f_output, "Content-type: %s\n", current_attach->mimetype);
00757 }
00758 fprintf(f_output, "Content-transfer-encoding: base64\n");
00759
00760
00761 if (current_attach->filename2) {
00762 attach_filename = current_attach->filename2;
00763 } else {
00764 attach_filename = current_attach->filename1;
00765 }
00766 if (!attach_filename) {
00767 fprintf(f_output, "Content-Disposition: inline\n\n");
00768 } else {
00769 fprintf(f_output, "Content-Disposition: attachment; filename=\"%s\"\n\n", attach_filename);
00770 }
00771 }
00772 if (current_attach->data) {
00773 pst_fwrite(enc, 1, strlen(enc), f_output);
00774 DEBUG_EMAIL(("Attachment Size after encoding is %i\n", strlen(enc)));
00775 free(enc);
00776 } else {
00777 (void)pst_attach_to_file_base64(pst, current_attach, f_output);
00778 }
00779 fprintf(f_output, "\n\n");
00780 DEBUG_RET();
00781 }
00782
00783
00784 void write_normal_email(FILE* f_output, char f_name[], pst_item* item, int mode, int mode_MH, pst_file* pst, int save_rtf)
00785 {
00786 char *boundary = NULL;
00787 int boundary_created = 0;
00788 char *temp = NULL;
00789 int attach_num, base64_body = 0;
00790 time_t em_time;
00791 char *c_time;
00792 pst_item_attach* current_attach;
00793 DEBUG_ENT("write_normal_email");
00794
00795
00796 if (item->email->sent_date) {
00797 em_time = fileTimeToUnixTime(item->email->sent_date, 0);
00798 c_time = ctime(&em_time);
00799 if (c_time)
00800 c_time[strlen(c_time)-1] = '\0';
00801 else
00802 c_time = "Fri Dec 28 12:06:21 2001";
00803 } else
00804 c_time= "Fri Dec 28 12:06:21 2001";
00805
00806
00807 if (item->email->header ) {
00808 char *b1, *b2;
00809
00810
00811
00812
00813
00814
00815 removeCR(item->email->header);
00816
00817 if ((b2 = my_stristr(item->email->header, "boundary="))) {
00818 int len;
00819 b2 += strlen("boundary=");
00820
00821 if (*b2 == '"') {
00822 b2++;
00823 b1 = strchr(b2, '"');
00824 } else {
00825 b1 = b2;
00826 while (isgraph(*b1))
00827 b1++;
00828 }
00829 len = b1 - b2;
00830 boundary = malloc(len+1);
00831 strncpy(boundary, b2, len);
00832 boundary[len] = '\0';
00833 b1 = b2 = boundary;
00834 while (*b2 != '\0') {
00835 if (*b2 != '\n' && *b2 != '\r' && *b2 != '\t') {
00836 *b1 = *b2;
00837 b1++;
00838 }
00839 b2++;
00840 }
00841 *b1 = '\0';
00842
00843 DEBUG_EMAIL(("Found boundary of - %s\n", boundary));
00844 } else {
00845 DEBUG_EMAIL(("boundary not found in header\n"));
00846 }
00847
00848
00849 if ((b2 = my_stristr(item->email->header, "Content-Transfer-Encoding:"))) {
00850 if ((b2 = strchr(b2, ':'))) {
00851 b2++;
00852
00853 while (*b2 == ' ' || *b2 == '\t')
00854 b2++;
00855 if (pst_strincmp(b2, "base64", 6)==0) {
00856 DEBUG_EMAIL(("body is base64 encoded\n"));
00857 base64_body = 1;
00858 }
00859 } else {
00860 DEBUG_WARN(("found a ':' during the my_stristr, but not after that..\n"));
00861 }
00862 }
00863 }
00864
00865 if (!boundary && (item->attach || (item->email->body && item->email->htmlbody)
00866 || item->email->rtf_compressed || item->email->encrypted_body
00867 || item->email->encrypted_htmlbody)) {
00868
00869 DEBUG_EMAIL(("must create own boundary. oh dear.\n"));
00870 boundary = malloc(50 * sizeof(char));
00871 boundary[0] = '\0';
00872 sprintf(boundary, "--boundary-LibPST-iamunique-%i_-_-", rand());
00873 DEBUG_EMAIL(("created boundary is %s\n", boundary));
00874 boundary_created = 1;
00875 }
00876
00877 DEBUG_EMAIL(("About to print Header\n"));
00878
00879 if (item && item->email && item->email->subject && item->email->subject->subj) {
00880 DEBUG_EMAIL(("item->email->subject->subj = %s\n", item->email->subject->subj));
00881 }
00882
00883 if (item->email->header) {
00884 int len;
00885 char *soh = NULL;
00886
00887
00888
00889
00890 removeCR(item->email->header);
00891 temp = strstr(item->email->header, "\n\n");
00892
00893 if (temp) {
00894 DEBUG_EMAIL(("Found body text in header\n"));
00895 temp[1] = '\0';
00896 }
00897
00898
00899 soh = skip_header_prologue(item->email->header);
00900 if (mode != MODE_SEPARATE) {
00901
00902 if (strncmp(soh, "X-From_: ", 9) == 0 ) {
00903 fputs("From ", f_output);
00904 soh += 9;
00905 } else
00906 fprintf(f_output, "From \"%s\" %s\n", item->email->outlook_sender_name, c_time);
00907 }
00908 fprintf(f_output, "%s", soh);
00909 len = strlen(soh);
00910 if (!len || (soh[len-1] != '\n')) fprintf(f_output, "\n");
00911
00912 } else {
00913
00914 if (mode != MODE_SEPARATE) {
00915
00916 if (item->email->outlook_sender_name) {
00917 temp = item->email->outlook_sender_name;
00918 } else {
00919 temp = "(readpst_null)";
00920 }
00921 fprintf(f_output, "From \"%s\" %s\n", temp, c_time);
00922 }
00923
00924 temp = item->email->outlook_sender;
00925 if (!temp) temp = "";
00926 fprintf(f_output, "From: \"%s\" <%s>\n", item->email->outlook_sender_name, temp);
00927
00928 if (item->email->subject) {
00929 fprintf(f_output, "Subject: %s\n", item->email->subject->subj);
00930 } else {
00931 fprintf(f_output, "Subject: \n");
00932 }
00933
00934 fprintf(f_output, "To: %s\n", item->email->sentto_address);
00935 if (item->email->cc_address) {
00936 fprintf(f_output, "Cc: %s\n", item->email->cc_address);
00937 }
00938
00939 if (item->email->sent_date) {
00940 char c_time[C_TIME_SIZE];
00941 strftime(c_time, C_TIME_SIZE, "%a, %d %b %Y %H:%M:%S %z", gmtime(&em_time));
00942 fprintf(f_output, "Date: %s\n", c_time);
00943 }
00944 }
00945
00946 fprintf(f_output, "MIME-Version: 1.0\n");
00947 if (boundary && boundary_created) {
00948
00949
00950 if (item->attach) {
00951
00952 fprintf(f_output, "Content-type: multipart/mixed;\n\tboundary=\"%s\"\n", boundary);
00953 } else if (boundary) {
00954
00955 fprintf(f_output, "Content-type: multipart/alternative;\n\tboundary=\"%s\"\n", boundary);
00956 } else if (item->email->htmlbody) {
00957 fprintf(f_output, "Content-type: text/html\n");
00958 }
00959 }
00960 fprintf(f_output, "\n");
00961 DEBUG_EMAIL(("About to print Body\n"));
00962
00963 if (item->email->body) {
00964 if (boundary) {
00965 fprintf(f_output, "\n--%s\n", boundary);
00966 fprintf(f_output, "Content-type: text/plain\n");
00967 if (base64_body)
00968 fprintf(f_output, "Content-Transfer-Encoding: base64\n");
00969 fprintf(f_output, "\n");
00970 }
00971 removeCR(item->email->body);
00972 if (base64_body) {
00973 char *enc = base64_encode(item->email->body, strlen(item->email->body));
00974 if (enc) {
00975 write_email_body(f_output, enc);
00976 free(enc);
00977 }
00978 }
00979 else {
00980 write_email_body(f_output, item->email->body);
00981 }
00982 }
00983
00984 if (item->email->htmlbody) {
00985 if (boundary) {
00986 fprintf(f_output, "\n--%s\n", boundary);
00987 fprintf(f_output, "Content-type: text/html\n");
00988 if (base64_body) fprintf(f_output, "Content-Transfer-Encoding: base64\n");
00989 fprintf(f_output, "\n");
00990 }
00991 removeCR(item->email->htmlbody);
00992 if (base64_body) {
00993 char *enc = base64_encode(item->email->htmlbody, strlen(item->email->htmlbody));
00994 if (enc) {
00995 write_email_body(f_output, enc);
00996 free(enc);
00997 }
00998 }
00999 else {
01000 write_email_body(f_output, item->email->htmlbody);
01001 }
01002 }
01003
01004 if (item->email->rtf_compressed && save_rtf) {
01005
01006 DEBUG_EMAIL(("Adding RTF body as attachment\n"));
01007 current_attach = (pst_item_attach*)xmalloc(sizeof(pst_item_attach));
01008 memset(current_attach, 0, sizeof(pst_item_attach));
01009 current_attach->next = item->attach;
01010 item->attach = current_attach;
01011 current_attach->data = lzfu_decompress(item->email->rtf_compressed, item->email->rtf_compressed_size, ¤t_attach->size);
01012 current_attach->filename2 = xmalloc(strlen(RTF_ATTACH_NAME)+2);
01013 strcpy(current_attach->filename2, RTF_ATTACH_NAME);
01014 current_attach->mimetype = xmalloc(strlen(RTF_ATTACH_TYPE)+2);
01015 strcpy(current_attach->mimetype, RTF_ATTACH_TYPE);
01016
01017
01018
01019 }
01020
01021 if (item->email->encrypted_body || item->email->encrypted_htmlbody) {
01022
01023 if (item->email->encrypted_body) {
01024 DEBUG_EMAIL(("Adding Encrypted Body as attachment\n"));
01025 current_attach = (pst_item_attach*) xmalloc(sizeof(pst_item_attach));
01026 memset(current_attach, 0, sizeof(pst_item_attach));
01027 current_attach->next = item->attach;
01028 item->attach = current_attach;
01029 current_attach->data = item->email->encrypted_body;
01030 current_attach->size = item->email->encrypted_body_size;
01031 item->email->encrypted_body = NULL;
01032 }
01033
01034 if (item->email->encrypted_htmlbody) {
01035 DEBUG_EMAIL(("Adding encrypted HTML body as attachment\n"));
01036 current_attach = (pst_item_attach*) xmalloc(sizeof(pst_item_attach));
01037 memset(current_attach, 0, sizeof(pst_item_attach));
01038 current_attach->next = item->attach;
01039 item->attach = current_attach;
01040 current_attach->data = item->email->encrypted_htmlbody;
01041 current_attach->size = item->email->encrypted_htmlbody_size;
01042 item->email->encrypted_htmlbody = NULL;
01043 }
01044 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");
01045 }
01046
01047
01048 attach_num = 0;
01049 for (current_attach = item->attach; current_attach; current_attach = current_attach->next) {
01050 DEBUG_EMAIL(("Attempting Attachment encoding\n"));
01051 if (!current_attach->data) {
01052 DEBUG_EMAIL(("Data of attachment is NULL!. Size is supposed to be %i\n", current_attach->size));
01053 }
01054 if (mode == MODE_SEPARATE && !mode_MH)
01055 write_separate_attachment(f_name, current_attach, ++attach_num, pst);
01056 else
01057 write_inline_attachment(f_output, current_attach, boundary, pst);
01058 }
01059 if (mode != MODE_SEPARATE) {
01060 DEBUG_EMAIL(("Writing buffer between emails\n"));
01061 if (boundary) fprintf(f_output, "\n--%s--\n", boundary);
01062 fprintf(f_output, "\n\n");
01063 }
01064 if (boundary) free (boundary);
01065 DEBUG_RET();
01066 }
01067
01068
01069 void write_vcard(FILE* f_output, pst_item_contact* contact, char comment[])
01070 {
01071
01072
01073
01074
01075 DEBUG_ENT("write_vcard");
01076
01077 fprintf(f_output, "BEGIN:VCARD\n");
01078 fprintf(f_output, "FN:%s\n", pst_rfc2426_escape(contact->fullname));
01079
01080
01081 fprintf(f_output, "N:%s;", (!contact->surname) ? "" : pst_rfc2426_escape(contact->surname));
01082 fprintf(f_output, "%s;", (!contact->first_name) ? "" : pst_rfc2426_escape(contact->first_name));
01083 fprintf(f_output, "%s;", (!contact->middle_name) ? "" : pst_rfc2426_escape(contact->middle_name));
01084 fprintf(f_output, "%s;", (!contact->display_name_prefix) ? "" : pst_rfc2426_escape(contact->display_name_prefix));
01085 fprintf(f_output, "%s\n", (!contact->suffix) ? "" : pst_rfc2426_escape(contact->suffix));
01086
01087 if (contact->nickname)
01088 fprintf(f_output, "NICKNAME:%s\n", pst_rfc2426_escape(contact->nickname));
01089 if (contact->address1)
01090 fprintf(f_output, "EMAIL:%s\n", pst_rfc2426_escape(contact->address1));
01091 if (contact->address2)
01092 fprintf(f_output, "EMAIL:%s\n", pst_rfc2426_escape(contact->address2));
01093 if (contact->address3)
01094 fprintf(f_output, "EMAIL:%s\n", pst_rfc2426_escape(contact->address3));
01095 if (contact->birthday)
01096 fprintf(f_output, "BDAY:%s\n", pst_rfc2425_datetime_format(contact->birthday));
01097
01098 if (contact->home_address) {
01099
01100 fprintf(f_output, "ADR;TYPE=home:%s;", (!contact->home_po_box) ? "" : pst_rfc2426_escape(contact->home_po_box));
01101 fprintf(f_output, "%s;", "");
01102 fprintf(f_output, "%s;", (!contact->home_street) ? "" : pst_rfc2426_escape(contact->home_street));
01103 fprintf(f_output, "%s;", (!contact->home_city) ? "" : pst_rfc2426_escape(contact->home_city));
01104 fprintf(f_output, "%s;", (!contact->home_state) ? "" : pst_rfc2426_escape(contact->home_state));
01105 fprintf(f_output, "%s;", (!contact->home_postal_code) ? "" : pst_rfc2426_escape(contact->home_postal_code));
01106 fprintf(f_output, "%s\n", (!contact->home_country) ? "" : pst_rfc2426_escape(contact->home_country));
01107 fprintf(f_output, "LABEL;TYPE=home:%s\n", pst_rfc2426_escape(contact->home_address));
01108 }
01109
01110 if (contact->business_address) {
01111
01112 fprintf(f_output, "ADR;TYPE=work:%s;", (!contact->business_po_box) ? "" : pst_rfc2426_escape(contact->business_po_box));
01113 fprintf(f_output, "%s;", "");
01114 fprintf(f_output, "%s;", (!contact->business_street) ? "" : pst_rfc2426_escape(contact->business_street));
01115 fprintf(f_output, "%s;", (!contact->business_city) ? "" : pst_rfc2426_escape(contact->business_city));
01116 fprintf(f_output, "%s;", (!contact->business_state) ? "" : pst_rfc2426_escape(contact->business_state));
01117 fprintf(f_output, "%s;", (!contact->business_postal_code) ? "" : pst_rfc2426_escape(contact->business_postal_code));
01118 fprintf(f_output, "%s\n", (!contact->business_country) ? "" : pst_rfc2426_escape(contact->business_country));
01119 fprintf(f_output, "LABEL;TYPE=work:%s\n", pst_rfc2426_escape(contact->business_address));
01120 }
01121
01122 if (contact->other_address) {
01123
01124 fprintf(f_output, "ADR;TYPE=postal:%s;",(!contact->other_po_box) ? "" : pst_rfc2426_escape(contact->other_po_box));
01125 fprintf(f_output, "%s;", "");
01126 fprintf(f_output, "%s;", (!contact->other_street) ? "" : pst_rfc2426_escape(contact->other_street));
01127 fprintf(f_output, "%s;", (!contact->other_city) ? "" : pst_rfc2426_escape(contact->other_city));
01128 fprintf(f_output, "%s;", (!contact->other_state) ? "" : pst_rfc2426_escape(contact->other_state));
01129 fprintf(f_output, "%s;", (!contact->other_postal_code) ? "" : pst_rfc2426_escape(contact->other_postal_code));
01130 fprintf(f_output, "%s\n", (!contact->other_country) ? "" : pst_rfc2426_escape(contact->other_country));
01131 fprintf(f_output, "LABEL;TYPE=postal:%s\n", pst_rfc2426_escape(contact->other_address));
01132 }
01133
01134 if (contact->business_fax) fprintf(f_output, "TEL;TYPE=work,fax:%s\n", pst_rfc2426_escape(contact->business_fax));
01135 if (contact->business_phone) fprintf(f_output, "TEL;TYPE=work,voice:%s\n", pst_rfc2426_escape(contact->business_phone));
01136 if (contact->business_phone2) fprintf(f_output, "TEL;TYPE=work,voice:%s\n", pst_rfc2426_escape(contact->business_phone2));
01137 if (contact->car_phone) fprintf(f_output, "TEL;TYPE=car,voice:%s\n", pst_rfc2426_escape(contact->car_phone));
01138 if (contact->home_fax) fprintf(f_output, "TEL;TYPE=home,fax:%s\n", pst_rfc2426_escape(contact->home_fax));
01139 if (contact->home_phone) fprintf(f_output, "TEL;TYPE=home,voice:%s\n", pst_rfc2426_escape(contact->home_phone));
01140 if (contact->home_phone2) fprintf(f_output, "TEL;TYPE=home,voice:%s\n", pst_rfc2426_escape(contact->home_phone2));
01141 if (contact->isdn_phone) fprintf(f_output, "TEL;TYPE=isdn:%s\n", pst_rfc2426_escape(contact->isdn_phone));
01142 if (contact->mobile_phone) fprintf(f_output, "TEL;TYPE=cell,voice:%s\n", pst_rfc2426_escape(contact->mobile_phone));
01143 if (contact->other_phone) fprintf(f_output, "TEL;TYPE=msg:%s\n", pst_rfc2426_escape(contact->other_phone));
01144 if (contact->pager_phone) fprintf(f_output, "TEL;TYPE=pager:%s\n", pst_rfc2426_escape(contact->pager_phone));
01145 if (contact->primary_fax) fprintf(f_output, "TEL;TYPE=fax,pref:%s\n", pst_rfc2426_escape(contact->primary_fax));
01146 if (contact->primary_phone) fprintf(f_output, "TEL;TYPE=phone,pref:%s\n", pst_rfc2426_escape(contact->primary_phone));
01147 if (contact->radio_phone) fprintf(f_output, "TEL;TYPE=pcs:%s\n", pst_rfc2426_escape(contact->radio_phone));
01148 if (contact->telex) fprintf(f_output, "TEL;TYPE=bbs:%s\n", pst_rfc2426_escape(contact->telex));
01149 if (contact->job_title) fprintf(f_output, "TITLE:%s\n", pst_rfc2426_escape(contact->job_title));
01150 if (contact->profession) fprintf(f_output, "ROLE:%s\n", pst_rfc2426_escape(contact->profession));
01151 if (contact->assistant_name || contact->assistant_phone) {
01152 fprintf(f_output, "AGENT:BEGIN:VCARD\n");
01153 if (contact->assistant_name) fprintf(f_output, "FN:%s\n", pst_rfc2426_escape(contact->assistant_name));
01154 if (contact->assistant_phone) fprintf(f_output, "TEL:%s\n", pst_rfc2426_escape(contact->assistant_phone));
01155 }
01156 if (contact->company_name) fprintf(f_output, "ORG:%s\n", pst_rfc2426_escape(contact->company_name));
01157 if (comment) fprintf(f_output, "NOTE:%s\n", pst_rfc2426_escape(comment));
01158
01159 fprintf(f_output, "VERSION: 3.0\n");
01160 fprintf(f_output, "END:VCARD\n\n");
01161 DEBUG_RET();
01162 }
01163
01164
01165 void write_appointment(FILE* f_output, pst_item_appointment* appointment,
01166 pst_item_email* email, FILETIME* create_date, FILETIME* modify_date)
01167 {
01168 fprintf(f_output, "BEGIN:VEVENT\n");
01169 if (create_date)
01170 fprintf(f_output, "CREATED:%s\n",
01171 pst_rfc2445_datetime_format(create_date));
01172 if (modify_date)
01173 fprintf(f_output, "LAST-MOD:%s\n",
01174 pst_rfc2445_datetime_format(modify_date));
01175 if (email && email->subject)
01176 fprintf(f_output, "SUMMARY:%s\n",
01177 pst_rfc2426_escape(email->subject->subj));
01178 if (email && email->body)
01179 fprintf(f_output, "DESCRIPTION:%s\n",
01180 pst_rfc2426_escape(email->body));
01181 if (appointment && appointment->start)
01182 fprintf(f_output, "DTSTART;VALUE=DATE-TIME:%s\n",
01183 pst_rfc2445_datetime_format(appointment->start));
01184 if (appointment && appointment->end)
01185 fprintf(f_output, "DTEND;VALUE=DATE-TIME:%s\n",
01186 pst_rfc2445_datetime_format(appointment->end));
01187 if (appointment && appointment->location)
01188 fprintf(f_output, "LOCATION:%s\n",
01189 pst_rfc2426_escape(appointment->location));
01190 if (appointment) {
01191 switch (appointment->showas) {
01192 case PST_FREEBUSY_TENTATIVE:
01193 fprintf(f_output, "STATUS:TENTATIVE\n");
01194 break;
01195 case PST_FREEBUSY_FREE:
01196
01197 fprintf(f_output, "TRANSP:TRANSPARENT\n");
01198 case PST_FREEBUSY_BUSY:
01199 case PST_FREEBUSY_OUT_OF_OFFICE:
01200 fprintf(f_output, "STATUS:CONFIRMED\n");
01201 break;
01202 }
01203 switch (appointment->label) {
01204 case PST_APP_LABEL_NONE:
01205 fprintf(f_output, "CATEGORIES:NONE\n");
01206 break;
01207 case PST_APP_LABEL_IMPORTANT:
01208 fprintf(f_output, "CATEGORIES:IMPORTANT\n");
01209 break;
01210 case PST_APP_LABEL_BUSINESS:
01211 fprintf(f_output, "CATEGORIES:BUSINESS\n");
01212 break;
01213 case PST_APP_LABEL_PERSONAL:
01214 fprintf(f_output, "CATEGORIES:PERSONAL\n");
01215 break;
01216 case PST_APP_LABEL_VACATION:
01217 fprintf(f_output, "CATEGORIES:VACATION\n");
01218 break;
01219 case PST_APP_LABEL_MUST_ATTEND:
01220 fprintf(f_output, "CATEGORIES:MUST-ATTEND\n");
01221 break;
01222 case PST_APP_LABEL_TRAVEL_REQ:
01223 fprintf(f_output, "CATEGORIES:TRAVEL-REQUIRED\n");
01224 break;
01225 case PST_APP_LABEL_NEEDS_PREP:
01226 fprintf(f_output, "CATEGORIES:NEEDS-PREPARATION\n");
01227 break;
01228 case PST_APP_LABEL_BIRTHDAY:
01229 fprintf(f_output, "CATEGORIES:BIRTHDAY\n");
01230 break;
01231 case PST_APP_LABEL_ANNIVERSARY:
01232 fprintf(f_output, "CATEGORIES:ANNIVERSARY\n");
01233 break;
01234 case PST_APP_LABEL_PHONE_CALL:
01235 fprintf(f_output, "CATEGORIES:PHONE-CALL\n");
01236 break;
01237 }
01238 }
01239 fprintf(f_output, "END:VEVENT\n\n");
01240 }
01241
01242
01243 void create_enter_dir(struct file_ll* f, pst_item *item)
01244 {
01245 f->email_count = 0;
01246 f->skip_count = 0;
01247 f->type = item->type;
01248 f->stored_count = (item->folder) ? item->folder->email_count : 0;
01249
01250 DEBUG_ENT("create_enter_dir");
01251 if (mode == MODE_KMAIL)
01252 f->name = mk_kmail_dir(item->file_as);
01253 else if (mode == MODE_RECURSE)
01254 f->name = mk_recurse_dir(item->file_as);
01255 else if (mode == MODE_SEPARATE) {
01256
01257 mk_separate_dir(item->file_as);
01258 f->name = (char*) xmalloc(10);
01259 memset(f->name, 0, 10);
01260
01261 } else {
01262 f->name = (char*) xmalloc(strlen(item->file_as)+strlen(OUTPUT_TEMPLATE)+1);
01263 sprintf(f->name, OUTPUT_TEMPLATE, item->file_as);
01264 }
01265
01266 f->dname = (char*) xmalloc(strlen(item->file_as)+1);
01267 strcpy(f->dname, item->file_as);
01268
01269 if (overwrite != 1) {
01270 int x = 0;
01271 char *temp = (char*) xmalloc (strlen(f->name)+10);
01272
01273 sprintf(temp, "%s", f->name);
01274 check_filename(temp);
01275 while ((f->output = fopen(temp, "r"))) {
01276 DEBUG_MAIN(("need to increase filename because one already exists with that name\n"));
01277 DEBUG_MAIN(("- increasing it to %s%d\n", f->name, x));
01278 x++;
01279 sprintf(temp, "%s%08d", f->name, x);
01280 DEBUG_MAIN(("- trying \"%s\"\n", f->name));
01281 if (x == 99999999) {
01282 DIE(("create_enter_dir: Why can I not create a folder %s? I have tried %i extensions...\n", f->name, x));
01283 }
01284 fclose(f->output);
01285 }
01286 if (x > 0) {
01287 free (f->name);
01288 f->name = temp;
01289 } else {
01290 free(temp);
01291 }
01292 }
01293
01294 DEBUG_MAIN(("f->name = %s\nitem->folder_name = %s\n", f->name, item->file_as));
01295 if (mode != MODE_SEPARATE) {
01296 check_filename(f->name);
01297 if (!(f->output = fopen(f->name, "w"))) {
01298 DIE(("create_enter_dir: Could not open file \"%s\" for write\n", f->name));
01299 }
01300 }
01301 DEBUG_RET();
01302 }
01303
01304
01305 void close_enter_dir(struct file_ll *f)
01306 {
01307 DEBUG_MAIN(("main: Email Count for folder %s is %i\n", f->dname, f->email_count));
01308 if (output_mode != OUTPUT_QUIET)
01309 printf("\t\"%s\" - %i items done, skipped %i, should have been %i\n",
01310 f->dname, f->email_count, f->skip_count, f->stored_count);
01311 if (f->output) fclose(f->output);
01312 free(f->name);
01313 free(f->dname);
01314
01315 if (mode == MODE_KMAIL)
01316 close_kmail_dir();
01317 else if (mode == MODE_RECURSE)
01318 close_recurse_dir();
01319 else if (mode == MODE_SEPARATE)
01320 close_separate_dir();
01321 }
01322