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