Mercurial > libpst
changeset 25:73e8959cd86b
patches from Arne
author | carl |
---|---|
date | Tue, 21 Feb 2006 22:50:16 -0800 |
parents | f4643b609bdf |
children | 9eeba3f4ca4b |
files | AUTHORS package src/readpst.c xml/Makefile.in xml/libpst.in |
diffstat | 5 files changed, 647 insertions(+), 917 deletions(-) [+] |
line wrap: on
line diff
--- a/AUTHORS Mon Feb 20 15:14:54 2006 -0800 +++ b/AUTHORS Tue Feb 21 22:50:16 2006 -0800 @@ -3,3 +3,4 @@ With contributions by: Joseph Nahmias <jello@costa.debian.org> Carl Byington <carl@five-ten-sg.com> + Arne Ahrend <aahrend@web.de>
--- a/package Mon Feb 20 15:14:54 2006 -0800 +++ b/package Tue Feb 21 22:50:16 2006 -0800 @@ -56,8 +56,9 @@ tail -10 $distlog fi chown --recursive carl:carl * -args="-z -e ssh --times --perms --links --relative --owner --group --numeric-ids --delete" -echo rcync $args $web ns1:/ +args="--recursive -z -e ssh --times --perms --links --relative --owner --group --numeric-ids --delete" +echo rsync $args $web ns1:/ +rsync $args $web ns1:/ if [ -f /usr/local/bin/pst2ldif ]; then pushd /home/ldap
--- a/src/readpst.c Mon Feb 20 15:14:54 2006 -0800 +++ b/src/readpst.c Tue Feb 21 22:50:16 2006 -0800 @@ -40,6 +40,7 @@ #define OUTPUT_TEMPLATE "%s" #define OUTPUT_KMAIL_DIR_TEMPLATE ".%s.directory" #define KMAIL_INDEX ".%s.index" +#define SEP_MAIL_FILE_TEMPLATE "%i" /* "%09i" */ // max size of the c_time char*. It will store the date of the email #define C_TIME_SIZE 500 @@ -79,6 +80,13 @@ char *rfc2425_datetime_format(FILETIME *ft); char *rfc2445_datetime_format(FILETIME *ft); char *skip_header_prologue(char *headers); +void write_separate_attachment(char f_name[], pst_item_attach* current_attach, int attach_num, pst_file* pst); +void write_inline_attachment(FILE* f_output, pst_item_attach* current_attach, char boundary[], pst_file* pst); +void write_normal_email(FILE* f_output, char f_name[], pst_item* item, int mode, int mode_MH, pst_file* pst); +void write_vcard(FILE* f_output, pst_item_contact* contact, char comment[]); +void write_appointment(FILE* f_output, pst_item_appointment* appointment, + pst_item_email* email, FILETIME* create_date, FILETIME* modify_date); +void create_enter_dir(struct file_ll* f, char file_as[], int mode, int overwrite); char *prog_name; char *output_dir = "."; char *kmail_chdir = NULL; @@ -120,25 +128,20 @@ pst_file pstfile; pst_desc_ll *d_ptr; char * fname = NULL; - time_t em_time; - char * c_time, *d_log=NULL; + char *d_log=NULL; int c,x; int mode = MODE_NORMAL; + int mode_MH = 0; int output_mode = OUTPUT_NORMAL; int contact_mode = CMODE_VCARD; int overwrite = 0; - int base64_body = 0; // int encrypt = 0; - FILE *fp; - char *enc; // base64 encoded attachment - char *boundary = NULL, *b1, *b2; // the boundary marker between multipart sections char *temp = NULL; //temporary char pointer - int attach_num = 0; int skip_child = 0; struct file_ll *f, *head; prog_name = argv[0]; - while ((c = getopt(argc, argv, "d:hko:qrSVwc:"))!= -1) { + while ((c = getopt(argc, argv, "d:hko:qrMSVwc:"))!= -1) { switch (c) { case 'c': if (optarg!=NULL && optarg[0]=='v') @@ -164,6 +167,10 @@ case 'k': mode = MODE_KMAIL; break; + case 'M': + mode = MODE_SEPERATE; + mode_MH = 1; + break; case 'o': output_dir = optarg; break; @@ -248,54 +255,7 @@ f->skip_count = 0; f->next = NULL; head = f; - if (mode == MODE_KMAIL) - f->name = mk_kmail_dir(item->file_as); - else if (mode == MODE_RECURSE) - f->name = mk_recurse_dir(item->file_as); - else if (mode == MODE_SEPERATE) { - // do similar stuff to recurse here. - mk_seperate_dir(item->file_as, overwrite); - f->name = (char*) xmalloc(10); - sprintf(f->name, "%09i", f->email_count); - } else { - f->name = (char*) malloc(strlen(item->file_as)+strlen(OUTPUT_TEMPLATE)+1); - sprintf(f->name, OUTPUT_TEMPLATE, item->file_as); - } - - f->dname = (char*) malloc(strlen(item->file_as)+1); - strcpy(f->dname, item->file_as); - - if (overwrite != 1 && mode != MODE_SEPERATE) { - // if overwrite is set to 1 we keep the existing name and don't modify anything - // we don't want to go changing the file name of the SEPERATE items - temp = (char*) malloc (strlen(f->name)+10); //enough room for 10 digits - sprintf(temp, "%s", f->name); - temp = check_filename(temp); - x = 0; - while ((f->output = fopen(temp, "r")) != NULL) { - DEBUG_MAIN(("main: need to increase filename cause one already exists with that name\n")); - DEBUG_MAIN(("main: - increasing it to %s%d\n", f->name, x)); - x++; - sprintf(temp, "%s%08d", f->name, x); - DEBUG_MAIN(("main: - trying \"%s\"\n", temp)); - if (x == 99999999) { - DIE(("main: Why can I not create a folder %s? I have tried %i extensions...\n", f->name, x)); - } - fclose(f->output); - } - if (x > 0) { //then the f->name should change - free (f->name); - f->name = temp; - } else { - free (temp); - } - } - if (mode != MODE_SEPERATE) { - f->name = check_filename(f->name); - if ((f->output = fopen(f->name, "w")) == NULL) { - DIE(("main: Could not open file \"%s\" for write\n", f->name)); - } - } + create_enter_dir(f, item->file_as, mode, overwrite); f->type = item->type; if ((d_ptr = pst_getTopOfFolders(&pstfile, item)) == NULL) { @@ -355,56 +315,7 @@ temp = item->file_as; temp = check_filename(temp); - - if (mode == MODE_KMAIL) - f->name = mk_kmail_dir(item->file_as); //create directory and form filename - else if (mode == MODE_RECURSE) - f->name = mk_recurse_dir(item->file_as); - else if (mode == MODE_SEPERATE) { - // do similar stuff to recurse here. - mk_seperate_dir(item->file_as, overwrite); - f->name = (char*) xmalloc(10); - memset(f->name, 0, 10); - // sprintf(f->name, "%09i", f->email_count); - } else { - f->name = (char*) xmalloc(strlen(item->file_as)+strlen(OUTPUT_TEMPLATE+1)); - sprintf(f->name, OUTPUT_TEMPLATE, item->file_as); - } - - f->dname = (char*) xmalloc(strlen(item->file_as)+1); - strcpy(f->dname, item->file_as); - - if (overwrite != 1) { - temp = (char*) xmalloc (strlen(f->name)+10); //enough room for 10 digits - sprintf(temp, "%s", f->name); - x = 0; - temp = check_filename(temp); - while ((f->output = fopen(temp, "r")) != NULL) { - DEBUG_MAIN(("main: need to increase filename cause one already exists with that name\n")); - DEBUG_MAIN(("main: - increasing it to %s%d\n", f->name, x)); - x++; - sprintf(temp, "%s%08d", f->name, x); - DEBUG_MAIN(("main: - trying \"%s\"\n", f->name)); - if (x == 99999999) { - DIE(("main: Why can I not create a folder %s? I have tried %i extensions...\n", f->name, x)); - } - fclose(f->output); - } - if (x > 0) { //then the f->name should change - free (f->name); - f->name = temp; - } else { - free(temp); - } - } - - DEBUG_MAIN(("main: f->name = %s\nitem->folder_name = %s\n", f->name, item->file_as)); - if (mode != MODE_SEPERATE) { - f->name = check_filename(f->name); - if ((f->output = fopen(f->name, "w")) == NULL) { - DIE(("main: Could not open file \"%s\" for write\n", f->name)); - } - } + create_enter_dir(f, item->file_as, mode, overwrite); if (d_ptr->child != NULL) { d_ptr = d_ptr->child; skip_child = 1; @@ -452,112 +363,11 @@ if (item->contact == NULL) { // this is an incorrect situation. Inform user DEBUG_MAIN(("main: ERROR. This contact has not been fully parsed. one of the pre-requisties is NULL\n")); } else { - if (contact_mode == CMODE_VCARD) { - // the specification I am following is (hopefully) RFC2426 vCard Mime Directory Profile - fprintf(f->output, "BEGIN:VCARD\n"); - fprintf(f->output, "FN:%s\n", rfc2426_escape(item->contact->fullname)); - fprintf(f->output, "N:%s;%s;%s;%s;%s\n", - rfc2426_escape((item->contact->surname==NULL?"":item->contact->surname)), - rfc2426_escape((item->contact->first_name==NULL?"":item->contact->first_name)), - rfc2426_escape((item->contact->middle_name==NULL?"":item->contact->middle_name)), - rfc2426_escape((item->contact->display_name_prefix==NULL?"":item->contact->display_name_prefix)), - rfc2426_escape((item->contact->suffix==NULL?"":item->contact->suffix))); - if (item->contact->nickname != NULL) - fprintf(f->output, "NICKNAME:%s\n", rfc2426_escape(item->contact->nickname)); - if (item->contact->address1 != NULL) - fprintf(f->output, "EMAIL:%s\n", rfc2426_escape(item->contact->address1)); - if (item->contact->address2 != NULL) - fprintf(f->output, "EMAIL:%s\n", rfc2426_escape(item->contact->address2)); - if (item->contact->address3 != NULL) - fprintf(f->output, "EMAIL:%s\n", rfc2426_escape(item->contact->address3)); - if (item->contact->birthday != NULL) - fprintf(f->output, "BDAY:%s\n", rfc2425_datetime_format(item->contact->birthday)); - if (item->contact->home_address != NULL) { - fprintf(f->output, "ADR;TYPE=home:%s;%s;%s;%s;%s;%s;%s\n", - rfc2426_escape((item->contact->home_po_box!=NULL?item->contact->home_po_box:"")), - "", // extended Address - rfc2426_escape((item->contact->home_street!=NULL?item->contact->home_street:"")), - rfc2426_escape((item->contact->home_city!=NULL?item->contact->home_city:"")), - rfc2426_escape((item->contact->home_state!=NULL?item->contact->home_state:"")), - rfc2426_escape((item->contact->home_postal_code!=NULL?item->contact->home_postal_code:"")), - rfc2426_escape((item->contact->home_country!=NULL?item->contact->home_country:""))); - fprintf(f->output, "LABEL;TYPE=home:%s\n", rfc2426_escape(item->contact->home_address)); - } - if (item->contact->business_address != NULL) { - fprintf(f->output, "ADR;TYPE=work:%s;%s;%s;%s;%s;%s;%s\n", - rfc2426_escape((item->contact->business_po_box!=NULL?item->contact->business_po_box:"")), - "", // extended Address - rfc2426_escape((item->contact->business_street!=NULL?item->contact->business_street:"")), - rfc2426_escape((item->contact->business_city!=NULL?item->contact->business_city:"")), - rfc2426_escape((item->contact->business_state!=NULL?item->contact->business_state:"")), - rfc2426_escape((item->contact->business_postal_code!=NULL?item->contact->business_postal_code:"")), - rfc2426_escape((item->contact->business_country!=NULL?item->contact->business_country:""))); - fprintf(f->output, "LABEL;TYPE=work:%s\n", rfc2426_escape(item->contact->business_address)); - } - if (item->contact->other_address != NULL) { - fprintf(f->output, "ADR;TYPE=postal:%s;%s;%s;%s;%s;%s;%s\n", - rfc2426_escape((item->contact->other_po_box!=NULL?item->contact->business_po_box:"")), - "", // extended Address - rfc2426_escape((item->contact->other_street!=NULL?item->contact->other_street:"")), - rfc2426_escape((item->contact->other_city!=NULL?item->contact->other_city:"")), - rfc2426_escape((item->contact->other_state!=NULL?item->contact->other_state:"")), - rfc2426_escape((item->contact->other_postal_code!=NULL?item->contact->other_postal_code:"")), - rfc2426_escape((item->contact->other_country!=NULL?item->contact->other_country:""))); - fprintf(f->output, "ADR;TYPE=postal:%s\n", rfc2426_escape(item->contact->other_address)); - } - if (item->contact->business_fax != NULL) - fprintf(f->output, "TEL;TYPE=work,fax:%s\n", rfc2426_escape(item->contact->business_fax)); - if (item->contact->business_phone != NULL) - fprintf(f->output, "TEL;TYPE=work,voice:%s\n", rfc2426_escape(item->contact->business_phone)); - if (item->contact->business_phone2 != NULL) - fprintf(f->output, "TEL;TYPE=work,voice:%s\n", rfc2426_escape(item->contact->business_phone2)); - if (item->contact->car_phone != NULL) - fprintf(f->output, "TEL;TYPE=car,voice:%s\n", rfc2426_escape(item->contact->car_phone)); - if (item->contact->home_fax != NULL) - fprintf(f->output, "TEL;TYPE=home,fax:%s\n", rfc2426_escape(item->contact->home_fax)); - if (item->contact->home_phone != NULL) - fprintf(f->output, "TEL;TYPE=home,voice:%s\n", rfc2426_escape(item->contact->home_phone)); - if (item->contact->home_phone2 != NULL) - fprintf(f->output, "TEL;TYPE=home,voice:%s\n", rfc2426_escape(item->contact->home_phone2)); - if (item->contact->isdn_phone != NULL) - fprintf(f->output, "TEL;TYPE=isdn:%s\n", rfc2426_escape(item->contact->isdn_phone)); - if (item->contact->mobile_phone != NULL) - fprintf(f->output, "TEL;TYPE=cell,voice:%s\n", rfc2426_escape(item->contact->mobile_phone)); - if (item->contact->other_phone != NULL) - fprintf(f->output, "TEL;TYPE=msg:%s\n", rfc2426_escape(item->contact->other_phone)); - if (item->contact->pager_phone != NULL) - fprintf(f->output, "TEL;TYPE=pager:%s\n", rfc2426_escape(item->contact->pager_phone)); - if (item->contact->primary_fax != NULL) - fprintf(f->output, "TEL;TYPE=fax,pref:%s\n", rfc2426_escape(item->contact->primary_fax)); - if (item->contact->primary_phone != NULL) - fprintf(f->output, "TEL;TYPE=phone,pref:%s\n", rfc2426_escape(item->contact->primary_phone)); - if (item->contact->radio_phone != NULL) - fprintf(f->output, "TEL;TYPE=pcs:%s\n", rfc2426_escape(item->contact->radio_phone)); - if (item->contact->telex != NULL) - fprintf(f->output, "TEL;TYPE=bbs:%s\n", rfc2426_escape(item->contact->telex)); - if (item->contact->job_title != NULL) - fprintf(f->output, "TITLE:%s\n", rfc2426_escape(item->contact->job_title)); - if (item->contact->profession != NULL) - fprintf(f->output, "ROLE:%s\n", rfc2426_escape(item->contact->profession)); - if (item->contact->assistant_name != NULL || item->contact->assistant_phone != NULL) { - fprintf(f->output, "AGENT:BEGIN:VCARD\\n"); - if (item->contact->assistant_name != NULL) - fprintf(f->output, "FN:%s\\n", rfc2426_escape(item->contact->assistant_name)); - if (item->contact->assistant_phone != NULL) - fprintf(f->output, "TEL:%s\\n", rfc2426_escape(item->contact->assistant_phone)); - fprintf(f->output, "END:VCARD\\n\n"); - } - if (item->contact->company_name != NULL) - fprintf(f->output, "ORG:%s\n", rfc2426_escape(item->contact->company_name)); - if (item->comment != NULL) - fprintf(f->output, "NOTE:%s\n", rfc2426_escape(item->comment)); - - fprintf(f->output, "VERSION: 3.0\n"); - fprintf(f->output, "END:VCARD\n\n"); - } else { + if (contact_mode == CMODE_VCARD) + write_vcard(f->output, item->contact, item->comment); + else fprintf(f->output, "%s <%s>\n", item->contact->fullname, item->contact->address1); } - } } else if (item->email != NULL && (item->type == PST_TYPE_NOTE || item->type == PST_TYPE_REPORT)) { if (mode == MODE_SEPERATE) { @@ -567,324 +377,7 @@ f->email_count++; DEBUG_MAIN(("main: seen an email\n")); - - // convert the sent date if it exists, or set it to a fixed date - if (item->email->sent_date != NULL) { - em_time = fileTimeToUnixTime(item->email->sent_date, 0); - c_time = ctime(&em_time); - if (c_time != NULL) - c_time[strlen(c_time)-1] = '\0'; //remove end \n - else - c_time = "Fri Dec 28 12:06:21 2001"; - } else - c_time= "Fri Dec 28 12:06:21 2001"; - - // if the boundary is still set from the previous run, then free it - if (boundary != NULL) { - free (boundary); - boundary = NULL; - } - - // we will always look at the header to discover some stuff - if (item->email->header != NULL ) { - // see if there is a boundary variable there - // this search MUST be made case insensitive (DONE). - // Also, some check to find out if we - // are looking at the boundary associated with content-type, and that the content - // type really is "multipart" - if ((b2 = my_stristr(item->email->header, "boundary=")) != NULL) { - b2 += strlen("boundary="); // move boundary to first char of marker - - if (*b2 == '"') { - b2++; - b1 = strchr(b2, '"'); // find terminating quote - } else { - b1 = b2; - while (isgraph(*b1)) // find first char that isn't part of boundary - b1++; - } - - boundary = malloc ((b1-b2)+1); //malloc that length - memset (boundary, 0, (b1-b2)+1); // blank it - strncpy(boundary, b2, b1-b2); // copy boundary to another variable - b1 = b2 = boundary; - while (*b2 != '\0') { // remove any CRs and Tabs - if (*b2 != '\n' && *b2 != '\r' && *b2 != '\t') { - *b1 = *b2; - b1++; - } - b2++; - } - *b1 = '\0'; - - DEBUG_MAIN(("main: Found boundary of - %s\n", boundary)); - } else { - - DEBUG_MAIN(("main: boundary not found in header\n")); - } - - // also possible to set 7bit encoding detection here. - if ((b2 = my_stristr(item->email->header, "Content-Transfer-Encoding:")) != NULL) { - if ((b2 = strchr(b2, ':')) != NULL) { - b2++; // skip to the : at the end of the string - - while (*b2 == ' ' || *b2 == '\t') - b2++; - if (pst_strincmp(b2, "base64", 6)==0) { - DEBUG_MAIN(("body is base64 encoded\n")); - base64_body = 1; - } - } else { - DEBUG_WARN(("found a ':' during the my_stristr, but not after that..\n")); - } - } - - } - - DEBUG_MAIN(("main: About to print Header\n")); - - if (item != NULL && item->email != NULL && item->email->subject != NULL && - item->email->subject->subj != NULL) { - DEBUG_EMAIL(("item->email->subject->subj = %p\n", item->email->subject->subj)); - } - if (item->email->header != NULL) { - // some of the headers we get from the file are not properly defined. - // they can contain some email stuff too. We will cut off the header - // when we see a \n\n or \r\n\r\n - - removeCR(item->email->header); - - temp = strstr(item->email->header, "\n\n"); - - if (temp != NULL) { - DEBUG_MAIN(("main: Found body text in header\n")); - *temp = '\0'; - } - - if (mode != MODE_SEPERATE) { - char *soh = NULL; // real start of headers. - // don't put rubbish in if we are doing seperate - fprintf(f->output, "From \"%s\" %s\n", item->email->outlook_sender_name, c_time); - soh = skip_header_prologue(item->email->header); - fprintf(f->output, "%s\n", soh); - } else { - fprintf(f->output, "%s", item->email->header); - } - } else { - //make up our own header! - if (mode != MODE_SEPERATE) { - // don't want this first line for this mode - if (item->email->outlook_sender_name != NULL) { - temp = item->email->outlook_sender_name; - } else { - temp = "(readpst_null)"; - } - fprintf(f->output, "From \"%s\" %s\n", temp, c_time); - } - if ((temp = item->email->outlook_sender) == NULL) - temp = ""; - fprintf(f->output, "From: \"%s\" <%s>\n", item->email->outlook_sender_name, temp); - if (item->email->subject != NULL) { - fprintf(f->output, "Subject: %s\n", item->email->subject->subj); - } else { - fprintf(f->output, "Subject: \n"); - } - fprintf(f->output, "To: %s\n", item->email->sentto_address); - if (item->email->cc_address != NULL) { - fprintf(f->output, "Cc: %s\n", item->email->cc_address); - } - if (item->email->sent_date != NULL) { - c_time = (char*) xmalloc(C_TIME_SIZE); - strftime(c_time, C_TIME_SIZE, "%a, %d %b %Y %H:%M:%S %z", gmtime(&em_time)); - fprintf(f->output, "Date: %s\n", c_time); - free(c_time); - } - - fprintf(f->output, "MIME-Version: 1.0\n"); - } - if (boundary == NULL && (item->attach ||(item->email->body && item->email->htmlbody) - || item->email->rtf_compressed || item->email->encrypted_body - || item->email->encrypted_htmlbody)) { - // we need to create a boundary here. - DEBUG_EMAIL(("main: must create own boundary. oh dear.\n")); - boundary = malloc(50 * sizeof(char)); // allow 50 chars for boundary - boundary[0] = '\0'; - sprintf(boundary, "--boundary-LibPST-iamunique-%i_-_-", rand()); - DEBUG_EMAIL(("main: created boundary is %s\n", boundary)); - - /* If boundary != NULL, then it'll already be printed with existing - * headers. Otherwise, we generate it here, and print it. - */ - if (item->attach != NULL) { - // write the boundary stuff if we have attachments - fprintf(f->output, "Content-type: multipart/mixed;\n\tboundary=\"%s\"\n", - boundary); - } else if (boundary != NULL) { - // else if we have multipart/alternative then tell it so - fprintf(f->output, "Content-type: multipart/alternative;\n\tboundary=\"%s\"\n", - boundary); - } else if (item->email->htmlbody) { - fprintf(f->output, "Content-type: text/html\n"); - } - } - fprintf(f->output, "\n"); - - DEBUG_MAIN(("main: About to print Body\n")); - - if (item->email->body != NULL) { - if (boundary) { - fprintf(f->output, "\n--%s\n", boundary); - fprintf(f->output, "Content-type: text/plain\n"); - if (base64_body) fprintf(f->output, "Content-Transfer-Encoding: base64\n"); - fprintf(f->output, "\n"); - } - removeCR(item->email->body); - if (base64_body) - write_email_body(f->output, base64_encode(item->email->body, - strlen(item->email->body))); - else - write_email_body(f->output, item->email->body); - } - - if (item->email->htmlbody != NULL) { - if (boundary) { - fprintf(f->output, "\n--%s\n", boundary); - fprintf(f->output, "Content-type: text/html\n"); - if (base64_body) fprintf(f->output, "Content-Transfer-Encoding: base64\n"); - fprintf(f->output, "\n"); - } - removeCR(item->email->htmlbody); - if (base64_body) - write_email_body(f->output, base64_encode(item->email->htmlbody, - strlen(item->email->htmlbody))); - else - write_email_body(f->output, item->email->htmlbody); - } - - attach_num = 0; - - if (item->email->rtf_compressed != NULL) { - DEBUG_MAIN(("Adding RTF body as attachment\n")); - item->current_attach = (pst_item_attach*)xmalloc(sizeof(pst_item_attach)); - memset(item->current_attach, 0, sizeof(pst_item_attach)); - item->current_attach->next = item->attach; - item->attach = item->current_attach; - item->current_attach->data = lzfu_decompress(item->email->rtf_compressed); - item->current_attach->filename2 = xmalloc(strlen(RTF_ATTACH_NAME)+2); - strcpy(item->current_attach->filename2, RTF_ATTACH_NAME); - item->current_attach->mimetype = xmalloc(strlen(RTF_ATTACH_TYPE)+2); - strcpy(item->current_attach->mimetype, RTF_ATTACH_TYPE); - memcpy(&(item->current_attach->size), item->email->rtf_compressed+sizeof(int32_t), sizeof(int32_t)); - LE32_CPU(item->current_attach->size); - // item->email->rtf_compressed = ; - // attach_num++; - } - if (item->email->encrypted_body || item->email->encrypted_htmlbody) { - // if either the body or htmlbody is encrypted, add them as attachments - if (item->email->encrypted_body) { - DEBUG_MAIN(("Adding Encrypted Body as attachment\n")); - item->current_attach = (pst_item_attach*) xmalloc(sizeof(pst_item_attach)); - memset(item->current_attach, 0, sizeof(pst_item_attach)); - item->current_attach->next = item->attach; - item->attach = item->current_attach; - - item->current_attach->data = item->email->encrypted_body; - item->current_attach->size = item->email->encrypted_body_size; - item->email->encrypted_body = NULL; - } - if (item->email->encrypted_htmlbody) { - DEBUG_MAIN(("Adding encrypted HTML body as attachment\n")); - item->current_attach = (pst_item_attach*) xmalloc(sizeof(pst_item_attach)); - memset(item->current_attach, 0, sizeof(pst_item_attach)); - item->current_attach->next = item->attach; - item->attach = item->current_attach; - - item->current_attach->data = item->email->encrypted_htmlbody; - item->current_attach->size = item->email->encrypted_htmlbody_size; - item->email->encrypted_htmlbody = NULL; - } - 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"); - } - base64_body = 0; - // attachments - item->current_attach = item->attach; - while (item->current_attach != NULL) { - DEBUG_MAIN(("main: Attempting Attachment encoding\n")); - if (item->current_attach->data == NULL) { - DEBUG_MAIN(("main: Data of attachment is NULL!. Size is supposed to be %i\n", item->current_attach->size)); - } - if (mode == MODE_SEPERATE) { - f->name = check_filename(f->name); - if (item->current_attach->filename2 == NULL) { - temp = xmalloc(strlen(f->name)+15); - sprintf(temp, "%s-attach%i", f->name, attach_num); - } else { - temp = xmalloc(strlen(f->name)+strlen(item->current_attach->filename2)+15); - fp = NULL; x=0; - do { - if (fp != NULL) fclose(fp); - if (x == 0) - sprintf(temp, "%s-%s", f->name, item->current_attach->filename2); - else - sprintf(temp, "%s-%s-%i", f->name, item->current_attach->filename2, x); - } while ((fp = fopen(temp, "r"))!=NULL && ++x < 99999999); - if (x > 99999999) { - DIE(("error finding attachment name. exhausted possibilities to %s\n", temp)); - } - } - DEBUG_MAIN(("main: Saving attachment to %s\n", temp)); - if ((fp = fopen(temp, "w")) == NULL) { - WARN(("main: Cannot open attachment save file \"%s\"\n", temp)); - } else { - if (item->current_attach->data != NULL) - fwrite(item->current_attach->data, 1, item->current_attach->size, fp); - else { - pst_attach_to_file(&pstfile, item->current_attach, fp); - } - fclose(fp); - } - } else { - DEBUG_MAIN(("main: Attachment Size is %i\n", item->current_attach->size)); - DEBUG_MAIN(("main: Attachment Pointer is %p\n", item->current_attach->data)); - if (item->current_attach->data != NULL) { - if ((enc = base64_encode (item->current_attach->data, item->current_attach->size)) == NULL) { - DEBUG_MAIN(("main: ERROR base64_encode returned NULL. Must have failed\n")); - item->current_attach = item->current_attach->next; - continue; - } - } - if (boundary) { - fprintf(f->output, "\n--%s\n", boundary); - if (item->current_attach->mimetype == NULL) { - fprintf(f->output, "Content-type: %s\n", MIME_TYPE_DEFAULT); - } else { - fprintf(f->output, "Content-type: %s\n", item->current_attach->mimetype); - } - fprintf(f->output, "Content-transfer-encoding: base64\n"); - if (item->current_attach->filename2 == NULL) { - fprintf(f->output, "Content-Disposition: inline\n\n"); - } else { - fprintf(f->output, "Content-Disposition: attachment; filename=\"%s\"\n\n", - item->current_attach->filename2); - } - } - if (item->current_attach->data != NULL) { - fwrite(enc, 1, strlen(enc), f->output); - DEBUG_MAIN(("Attachment Size after encoding is %i\n", strlen(enc))); - } else { - pst_attach_to_file_base64(&pstfile, item->current_attach, f->output); - } - fprintf(f->output, "\n\n"); - } - item->current_attach = item->current_attach->next; - attach_num++; - } - if (mode != MODE_SEPERATE) { - DEBUG_MAIN(("main: Writing buffer between emails\n")); - if (boundary) - fprintf(f->output, "\n--%s--\n", boundary); - fprintf(f->output, "\n\n"); - } + write_normal_email(f->output, f->name, item, mode, mode_MH, &pstfile); } else if (item->type == PST_TYPE_JOURNAL) { // deal with journal items if (mode == MODE_SEPERATE) { @@ -920,60 +413,7 @@ if (f->type != PST_TYPE_APPOINTMENT) { DEBUG_MAIN(("main: I have an appointment, but folder isn't specified as an appointment type. Processing...\n")); } - fprintf(f->output, "BEGIN:VEVENT\n"); - if (item->create_date != NULL) - fprintf(f->output, "CREATED:%s\n", rfc2445_datetime_format(item->create_date)); - if (item->modify_date != NULL) - fprintf(f->output, "LAST-MOD:%s\n", rfc2445_datetime_format(item->modify_date)); - if (item->email != NULL && item->email->subject != NULL) - fprintf(f->output, "SUMMARY:%s\n", rfc2426_escape(item->email->subject->subj)); - if (item->email != NULL && item->email->body != NULL) - fprintf(f->output, "DESCRIPTION:%s\n", rfc2426_escape(item->email->body)); - if (item->appointment != NULL && item->appointment->start != NULL) - fprintf(f->output, "DTSTART;VALUE=DATE-TIME:%s\n", rfc2445_datetime_format(item->appointment->start)); - if (item->appointment != NULL && item->appointment->end != NULL) - fprintf(f->output, "DTEND;VALUE=DATE-TIME:%s\n", rfc2445_datetime_format(item->appointment->end)); - if (item->appointment != NULL && item->appointment->location != NULL) - fprintf(f->output, "LOCATION:%s\n", rfc2426_escape(item->appointment->location)); - if (item->appointment != NULL) { - switch (item->appointment->showas) { - case PST_FREEBUSY_TENTATIVE: - fprintf(f->output, "STATUS:TENTATIVE\n"); - break; - case PST_FREEBUSY_FREE: - // mark as transparent and as confirmed - fprintf(f->output, "TRANSP:TRANSPARENT\n"); - case PST_FREEBUSY_BUSY: - case PST_FREEBUSY_OUT_OF_OFFICE: - fprintf(f->output, "STATUS:CONFIRMED\n"); - break; - } - switch (item->appointment->label) { - case PST_APP_LABEL_NONE: - fprintf(f->output, "CATEGORIES:NONE\n"); break; - case PST_APP_LABEL_IMPORTANT: - fprintf(f->output, "CATEGORIES:IMPORTANT\n"); break; - case PST_APP_LABEL_BUSINESS: - fprintf(f->output, "CATEGORIES:BUSINESS\n"); break; - case PST_APP_LABEL_PERSONAL: - fprintf(f->output, "CATEGORIES:PERSONAL\n"); break; - case PST_APP_LABEL_VACATION: - fprintf(f->output, "CATEGORIES:VACATION\n"); break; - case PST_APP_LABEL_MUST_ATTEND: - fprintf(f->output, "CATEGORIES:MUST-ATTEND\n"); break; - case PST_APP_LABEL_TRAVEL_REQ: - fprintf(f->output, "CATEGORIES:TRAVEL-REQUIRED\n"); break; - case PST_APP_LABEL_NEEDS_PREP: - fprintf(f->output, "CATEGORIES:NEEDS-PREPARATION\n"); break; - case PST_APP_LABEL_BIRTHDAY: - fprintf(f->output, "CATEGORIES:BIRTHDAY\n"); break; - case PST_APP_LABEL_ANNIVERSARY: - fprintf(f->output, "CATEGORIES:ANNIVERSARY\n"); break; - case PST_APP_LABEL_PHONE_CALL: - fprintf(f->output, "CATEGORIES:PHONE-CALL\n"); break; - } - } - fprintf(f->output, "END:VEVENT\n\n"); + write_appointment(f->output, item->appointment, item->email, item->create_date, item->modify_date); } else { f->skip_count++; DEBUG_MAIN(("main: Unknown item type. %i. Ascii1=\"%s\"\n", @@ -985,10 +425,6 @@ } DEBUG_MAIN(("main: Going to next d_ptr\n")); - if (boundary) { - free(boundary); - boundary = NULL; - } check_parent: // _pst_freeItem(item); @@ -1102,6 +538,7 @@ printf("\t-d\t- Debug to file. This is a binary log. Use readlog to print it\n"); printf("\t-h\t- Help. This screen\n"); printf("\t-k\t- KMail. Output in kmail format\n"); + printf("\t-M\t- MH. Write emails in the MH format\n"); printf("\t-o\t- Output Dir. Directory to write files to. CWD is changed *after* opening pst file\n"); printf("\t-q\t- Quiet. Only print error messages\n"); printf("\t-r\t- Recursive. Output in a recursive format\n"); @@ -1233,7 +670,7 @@ if (y == 0) sprintf(dir_name, "%s", dir); else - sprintf(dir_name, "%s%09i", dir, y); // enough for 9 digits allocated above + sprintf(dir_name, "%s" SEP_MAIL_FILE_TEMPLATE, dir, y); // enough for 9 digits allocated above dir_name = check_filename(dir_name); DEBUG_MAIN(("mk_seperate_dir: about to try creating %s\n", dir_name)); @@ -1290,12 +727,13 @@ return 0; } int mk_seperate_file(struct file_ll *f) { + const int name_offset = 1; DEBUG_ENT("mk_seperate_file"); DEBUG_MAIN(("mk_seperate_file: opening next file to save email\n")); if (f->email_count > 999999999) { // bigger than nine 9's DIE(("mk_seperate_file: The number of emails in this folder has become too high to handle")); } - sprintf(f->name, "%09i", f->email_count); + sprintf(f->name, SEP_MAIL_FILE_TEMPLATE, f->email_count + name_offset); if (f->output != NULL) fclose(f->output); f->output = NULL; @@ -1441,3 +879,604 @@ // vim:sw=4 ts=4: // vim600: set foldlevel=0 foldmethod=marker: +void write_separate_attachment(char f_name[], pst_item_attach* current_attach, int attach_num, pst_file* pst) +{ + FILE *fp = NULL; + int x = 0; + char *temp; + + check_filename(f_name); + if (current_attach->filename2 == NULL) { + temp = xmalloc(strlen(f_name)+15); + sprintf(temp, "%s-attach%i", f_name, attach_num); + } else { + temp = xmalloc(strlen(f_name)+strlen(current_attach->filename2)+15); + do { + if (fp != NULL) fclose(fp); + if (x == 0) + sprintf(temp, "%s-%s", f_name, current_attach->filename2); + else + sprintf(temp, "%s-%s-%i", f_name, current_attach->filename2, x); + } while ((fp = fopen(temp, "r"))!=NULL && ++x < 99999999); + if (x > 99999999) { + DIE(("error finding attachment name. exhausted possibilities to %s\n", temp)); + } + } + DEBUG_MAIN(("write_separate_attachment: Saving attachment to %s\n", temp)); + if ((fp = fopen(temp, "w")) == NULL) { + WARN(("write_separate_attachment: Cannot open attachment save file \"%s\"\n", temp)); + } else { + if (current_attach->data != NULL) + fwrite(current_attach->data, 1, current_attach->size, fp); + else { + pst_attach_to_file(pst, current_attach, fp); + } + fclose(fp); + } +} + +void write_inline_attachment(FILE* f_output, pst_item_attach* current_attach, char boundary[], pst_file* pst) +{ + char *enc; // base64 encoded attachment + DEBUG_MAIN(("write_inline_attachment: Attachment Size is %i\n", item->current_attach->size)); + DEBUG_MAIN(("write_inline_attachment: Attachment Pointer is %p\n", item->current_attach->data)); + if (current_attach->data != NULL) { + if ((enc = base64_encode (current_attach->data, current_attach->size)) == NULL) { + DEBUG_MAIN(("write_inline_attachment: ERROR base64_encode returned NULL. Must have failed\n")); + current_attach = current_attach->next; + return; + } + } + if (boundary) { + fprintf(f_output, "\n--%s\n", boundary); + if (current_attach->mimetype == NULL) { + fprintf(f_output, "Content-type: %s\n", MIME_TYPE_DEFAULT); + } else { + fprintf(f_output, "Content-type: %s\n", current_attach->mimetype); + } + fprintf(f_output, "Content-transfer-encoding: base64\n"); + if (current_attach->filename2 == NULL) { + fprintf(f_output, "Content-Disposition: inline\n\n"); + } else { + fprintf(f_output, "Content-Disposition: attachment; filename=\"%s\"\n\n", + current_attach->filename2); + } + } + if (current_attach->data != NULL) { + fwrite(enc, 1, strlen(enc), f_output); + DEBUG_MAIN(("Attachment Size after encoding is %i\n", strlen(enc))); + } else { + pst_attach_to_file_base64(pst, current_attach, f_output); + } + fprintf(f_output, "\n\n"); +} + +void write_normal_email(FILE* f_output, char f_name[], pst_item* item, int mode, int mode_MH, pst_file* pst) +{ + char *boundary = NULL; // the boundary marker between multipart sections + char *temp = NULL; + int attach_num, base64_body = 0; + time_t em_time; + char *c_time; + + // convert the sent date if it exists, or set it to a fixed date + if (item->email->sent_date != NULL) { + em_time = fileTimeToUnixTime(item->email->sent_date, 0); + c_time = ctime(&em_time); + if (c_time != NULL) + c_time[strlen(c_time)-1] = '\0'; //remove end \n + else + c_time = "Fri Dec 28 12:06:21 2001"; + } else + c_time= "Fri Dec 28 12:06:21 2001"; + + // we will always look at the header to discover some stuff + if (item->email->header != NULL ) { + char *b1, *b2; + // see if there is a boundary variable there + // this search MUST be made case insensitive (DONE). + // Also, some check to find out if we + // are looking at the boundary associated with content-type, and that the content + // type really is "multipart" + + removeCR(item->email->header); + + if ((b2 = my_stristr(item->email->header, "boundary=")) != NULL) { + b2 += strlen("boundary="); // move boundary to first char of marker + + if (*b2 == '"') { + b2++; + b1 = strchr(b2, '"'); // find terminating quote + } else { + b1 = b2; + while (isgraph(*b1)) // find first char that isn't part of boundary + b1++; + } + + boundary = malloc ((b1-b2)+1); //malloc that length + memset (boundary, 0, (b1-b2)+1); // blank it + strncpy(boundary, b2, b1-b2); // copy boundary to another variable + b1 = b2 = boundary; + while (*b2 != '\0') { // remove any CRs and Tabs + if (*b2 != '\n' && *b2 != '\r' && *b2 != '\t') { + *b1 = *b2; + b1++; + } + b2++; + } + *b1 = '\0'; + + DEBUG_MAIN(("write_normal_email: Found boundary of - %s\n", boundary)); + } else { + DEBUG_MAIN(("write_normal_email: boundary not found in header\n")); + } + + // also possible to set 7bit encoding detection here. + if ((b2 = my_stristr(item->email->header, "Content-Transfer-Encoding:")) != NULL) { + if ((b2 = strchr(b2, ':')) != NULL) { + b2++; // skip to the : at the end of the string + + while (*b2 == ' ' || *b2 == '\t') + b2++; + if (pst_strincmp(b2, "base64", 6)==0) { + DEBUG_MAIN(("body is base64 encoded\n")); + base64_body = 1; + } + } else { + DEBUG_WARN(("found a ':' during the my_stristr, but not after that..\n")); + } + } + + } + + DEBUG_MAIN(("write_normal_email: About to print Header\n")); + + if (item != NULL && item->email != NULL && item->email->subject != NULL && + item->email->subject->subj != NULL) { + DEBUG_EMAIL(("item->email->subject->subj = %p\n", item->email->subject->subj)); + } + + if (item->email->header != NULL) { + // some of the headers we get from the file are not properly defined. + // they can contain some email stuff too. We will cut off the header + // when we see a \n\n or \r\n\r\n + temp = strstr(item->email->header, "\n\n"); + + if (temp != NULL) { + DEBUG_MAIN(("write_normal_email: Found body text in header\n")); + temp += 2; // get past the \n\n + *temp = '\0'; + } + + if (mode != MODE_SEPERATE) { + char *soh = NULL; // real start of headers. + // don't put rubbish in if we are doing seperate + fprintf(f_output, "From \"%s\" %s\n", item->email->outlook_sender_name, c_time); + soh = skip_header_prologue(item->email->header); + fprintf(f_output, "%s\n\n", soh); + } else { + fprintf(f_output, "%s\n", item->email->header); + } + } else { + //make up our own header! + if (mode != MODE_SEPERATE) { + // don't want this first line for this mode + if (item->email->outlook_sender_name != NULL) { + temp = item->email->outlook_sender_name; + } else { + temp = "(readpst_null)"; + } + fprintf(f_output, "From \"%s\" %s\n", temp, c_time); + } + if ((temp = item->email->outlook_sender) == NULL) + temp = ""; + fprintf(f_output, "From: \"%s\" <%s>\n", item->email->outlook_sender_name, temp); + if (item->email->subject != NULL) { + fprintf(f_output, "Subject: %s\n", item->email->subject->subj); + } else { + fprintf(f_output, "Subject: \n"); + } + fprintf(f_output, "To: %s\n", item->email->sentto_address); + if (item->email->cc_address != NULL) { + fprintf(f_output, "Cc: %s\n", item->email->cc_address); + } + if (item->email->sent_date != NULL) { + c_time = (char*) xmalloc(C_TIME_SIZE); + strftime(c_time, C_TIME_SIZE, "%a, %d %b %Y %H:%M:%S %z", gmtime(&em_time)); + fprintf(f_output, "Date: %s\n", c_time); + free(c_time); + } + + fprintf(f_output, "MIME-Version: 1.0\n"); + } + + if (boundary == NULL && (item->attach ||(item->email->body && item->email->htmlbody) + || item->email->rtf_compressed || item->email->encrypted_body + || item->email->encrypted_htmlbody)) { + // we need to create a boundary here. + DEBUG_EMAIL(("write_normal_email: must create own boundary. oh dear.\n")); + boundary = malloc(50 * sizeof(char)); // allow 50 chars for boundary + boundary[0] = '\0'; + sprintf(boundary, "--boundary-LibPST-iamunique-%i_-_-", rand()); + DEBUG_EMAIL(("write_normal_email: created boundary is %s\n", boundary)); + + /* If boundary != NULL, then it has already been printed with existing + * headers. Otherwise we generate it here and print it. + */ + if (item->attach != NULL) { + // write the boundary stuff if we have attachments + fprintf(f_output, "Content-type: multipart/mixed;\n\tboundary=\"%s\"\n", + boundary); + } else if (boundary != NULL) { + // else if we have multipart/alternative then tell it so + fprintf(f_output, "Content-type: multipart/alternative;\n\tboundary=\"%s\"\n", + boundary); + } else if (item->email->htmlbody) { + fprintf(f_output, "Content-type: text/html\n"); + } + } + + fprintf(f_output, "\n"); + + DEBUG_MAIN(("write_normal_email: About to print Body\n")); + + if (item->email->body != NULL) { + if (boundary) { + fprintf(f_output, "\n--%s\n", boundary); + fprintf(f_output, "Content-type: text/plain\n\n"); + if (base64_body) + fprintf(f_output, "Content-Transfer-Encoding: base64\n"); + } + removeCR(item->email->body); + if (base64_body) + write_email_body(f_output, base64_encode(item->email->body, + strlen(item->email->body))); + else + write_email_body(f_output, item->email->body); + } + + if (item->email->htmlbody != NULL) { + if (boundary) { + fprintf(f_output, "\n--%s\n", boundary); + fprintf(f_output, "Content-type: text/html\n\n"); + if (base64_body) + fprintf(f_output, "Content-Transfer-Encoding: base64\n"); + } + removeCR(item->email->htmlbody); + if (base64_body) + write_email_body(f_output, base64_encode(item->email->htmlbody, + strlen(item->email->htmlbody))); + else + write_email_body(f_output, item->email->htmlbody); + } + + if (item->email->rtf_compressed != NULL) { + DEBUG_MAIN(("Adding RTF body as attachment\n")); + item->current_attach = (pst_item_attach*)xmalloc(sizeof(pst_item_attach)); + memset(item->current_attach, 0, sizeof(pst_item_attach)); + item->current_attach->next = item->attach; + item->attach = item->current_attach; + item->current_attach->data = lzfu_decompress(item->email->rtf_compressed); + item->current_attach->filename2 = xmalloc(strlen(RTF_ATTACH_NAME)+2); + strcpy(item->current_attach->filename2, RTF_ATTACH_NAME); + item->current_attach->mimetype = xmalloc(strlen(RTF_ATTACH_TYPE)+2); + strcpy(item->current_attach->mimetype, RTF_ATTACH_TYPE); + memcpy(&(item->current_attach->size), item->email->rtf_compressed+sizeof(int32_t), sizeof(int32_t)); + LE32_CPU(item->current_attach->size); + // item->email->rtf_compressed = ; + // attach_num++; + } + if (item->email->encrypted_body || item->email->encrypted_htmlbody) { + // if either the body or htmlbody is encrypted, add them as attachments + if (item->email->encrypted_body) { + DEBUG_MAIN(("Adding Encrypted Body as attachment\n")); + item->current_attach = (pst_item_attach*) xmalloc(sizeof(pst_item_attach)); + memset(item->current_attach, 0, sizeof(pst_item_attach)); + item->current_attach->next = item->attach; + item->attach = item->current_attach; + + item->current_attach->data = item->email->encrypted_body; + item->current_attach->size = item->email->encrypted_body_size; + item->email->encrypted_body = NULL; + } + if (item->email->encrypted_htmlbody) { + DEBUG_MAIN(("Adding encrypted HTML body as attachment\n")); + item->current_attach = (pst_item_attach*) xmalloc(sizeof(pst_item_attach)); + memset(item->current_attach, 0, sizeof(pst_item_attach)); + item->current_attach->next = item->attach; + item->attach = item->current_attach; + + item->current_attach->data = item->email->encrypted_htmlbody; + item->current_attach->size = item->email->encrypted_htmlbody_size; + item->email->encrypted_htmlbody = NULL; + } + 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"); + } + // attachments + attach_num = 0; + for(item->current_attach = item->attach; + item->current_attach; + item->current_attach = item->current_attach->next) { + DEBUG_MAIN(("write_normal_email: Attempting Attachment encoding\n")); + if (item->current_attach->data == NULL) { + DEBUG_MAIN(("write_normal_email: Data of attachment is NULL!. Size is supposed to be %i\n", item->current_attach->size)); + } + attach_num++; + if (mode == MODE_SEPERATE && !mode_MH) + write_separate_attachment(f_name, item->current_attach, attach_num, pst); + else + write_inline_attachment(f_output, item->current_attach, boundary, pst); + } + if (mode != MODE_SEPERATE) { /* do not add a boundary after the last attachment for mode_MH */ + DEBUG_MAIN(("write_normal_email: Writing buffer between emails\n")); + if (boundary) + fprintf(f_output, "\n--%s--\n", boundary); + fprintf(f_output, "\n\n"); + } + if (boundary) + free (boundary); +} + +void write_vcard(FILE* f_output, pst_item_contact* contact, char comment[]) +{ + // the specification I am following is (hopefully) RFC2426 vCard Mime Directory Profile + fprintf(f_output, "BEGIN:VCARD\n"); + fprintf(f_output, "FN:%s\n", rfc2426_escape(contact->fullname)); + fprintf(f_output, "N:%s;%s;%s;%s;%s\n", + rfc2426_escape((contact->surname==NULL?"":contact->surname)), + rfc2426_escape((contact->first_name==NULL?"":contact->first_name)), + rfc2426_escape((contact->middle_name==NULL?"":contact->middle_name)), + rfc2426_escape((contact->display_name_prefix==NULL?"":contact->display_name_prefix)), + rfc2426_escape((contact->suffix==NULL?"":contact->suffix))); + if (contact->nickname != NULL) + fprintf(f_output, "NICKNAME:%s\n", rfc2426_escape(contact->nickname)); + if (contact->address1 != NULL) + fprintf(f_output, "EMAIL:%s\n", rfc2426_escape(contact->address1)); + if (contact->address2 != NULL) + fprintf(f_output, "EMAIL:%s\n", rfc2426_escape(contact->address2)); + if (contact->address3 != NULL) + fprintf(f_output, "EMAIL:%s\n", rfc2426_escape(contact->address3)); + if (contact->birthday != NULL) + fprintf(f_output, "BDAY:%s\n", rfc2425_datetime_format(contact->birthday)); + if (contact->home_address != NULL) { + fprintf(f_output, "ADR;TYPE=home:%s;%s;%s;%s;%s;%s;%s\n", + rfc2426_escape((contact->home_po_box!=NULL?contact->home_po_box:"")), + "", // extended Address + rfc2426_escape((contact->home_street!=NULL?contact->home_street:"")), + rfc2426_escape((contact->home_city!=NULL?contact->home_city:"")), + rfc2426_escape((contact->home_state!=NULL?contact->home_state:"")), + rfc2426_escape((contact->home_postal_code!=NULL?contact->home_postal_code:"")), + rfc2426_escape((contact->home_country!=NULL?contact->home_country:""))); + fprintf(f_output, "LABEL;TYPE=home:%s\n", rfc2426_escape(contact->home_address)); + } + if (contact->business_address != NULL) { + fprintf(f_output, "ADR;TYPE=work:%s;%s;%s;%s;%s;%s;%s\n", + rfc2426_escape((contact->business_po_box!=NULL?contact->business_po_box:"")), + "", // extended Address + rfc2426_escape((contact->business_street!=NULL?contact->business_street:"")), + rfc2426_escape((contact->business_city!=NULL?contact->business_city:"")), + rfc2426_escape((contact->business_state!=NULL?contact->business_state:"")), + rfc2426_escape((contact->business_postal_code!=NULL?contact->business_postal_code:"")), + rfc2426_escape((contact->business_country!=NULL?contact->business_country:""))); + fprintf(f_output, "LABEL;TYPE=work:%s\n", rfc2426_escape(contact->business_address)); + } + if (contact->other_address != NULL) { + fprintf(f_output, "ADR;TYPE=postal:%s;%s;%s;%s;%s;%s;%s\n", + rfc2426_escape((contact->other_po_box != NULL ? + contact->business_po_box:"")), + "", // extended Address + rfc2426_escape((contact->other_street != NULL ? + contact->other_street:"")), + rfc2426_escape((contact->other_city != NULL ? + contact->other_city:"")), + rfc2426_escape((contact->other_state != NULL ? + contact->other_state:"")), + rfc2426_escape((contact->other_postal_code != NULL ? + contact->other_postal_code:"")), + rfc2426_escape((contact->other_country != NULL ? + contact->other_country:""))); + fprintf(f_output, "ADR;TYPE=postal:%s\n", + rfc2426_escape(contact->other_address)); + } + if (contact->business_fax != NULL) + fprintf(f_output, "TEL;TYPE=work,fax:%s\n", + rfc2426_escape(contact->business_fax)); + if (contact->business_phone != NULL) + fprintf(f_output, "TEL;TYPE=work,voice:%s\n", + rfc2426_escape(contact->business_phone)); + if (contact->business_phone2 != NULL) + fprintf(f_output, "TEL;TYPE=work,voice:%s\n", + rfc2426_escape(contact->business_phone2)); + if (contact->car_phone != NULL) + fprintf(f_output, "TEL;TYPE=car,voice:%s\n", + rfc2426_escape(contact->car_phone)); + if (contact->home_fax != NULL) + fprintf(f_output, "TEL;TYPE=home,fax:%s\n", + rfc2426_escape(contact->home_fax)); + if (contact->home_phone != NULL) + fprintf(f_output, "TEL;TYPE=home,voice:%s\n", + rfc2426_escape(contact->home_phone)); + if (contact->home_phone2 != NULL) + fprintf(f_output, "TEL;TYPE=home,voice:%s\n", + rfc2426_escape(contact->home_phone2)); + if (contact->isdn_phone != NULL) + fprintf(f_output, "TEL;TYPE=isdn:%s\n", + rfc2426_escape(contact->isdn_phone)); + if (contact->mobile_phone != NULL) + fprintf(f_output, "TEL;TYPE=cell,voice:%s\n", + rfc2426_escape(contact->mobile_phone)); + if (contact->other_phone != NULL) + fprintf(f_output, "TEL;TYPE=msg:%s\n", + rfc2426_escape(contact->other_phone)); + if (contact->pager_phone != NULL) + fprintf(f_output, "TEL;TYPE=pager:%s\n", + rfc2426_escape(contact->pager_phone)); + if (contact->primary_fax != NULL) + fprintf(f_output, "TEL;TYPE=fax,pref:%s\n", + rfc2426_escape(contact->primary_fax)); + if (contact->primary_phone != NULL) + fprintf(f_output, "TEL;TYPE=phone,pref:%s\n", + rfc2426_escape(contact->primary_phone)); + if (contact->radio_phone != NULL) + fprintf(f_output, "TEL;TYPE=pcs:%s\n", + rfc2426_escape(contact->radio_phone)); + if (contact->telex != NULL) + fprintf(f_output, "TEL;TYPE=bbs:%s\n", + rfc2426_escape(contact->telex)); + if (contact->job_title != NULL) + fprintf(f_output, "TITLE:%s\n", + rfc2426_escape(contact->job_title)); + if (contact->profession != NULL) + fprintf(f_output, "ROLE:%s\n", + rfc2426_escape(contact->profession)); + if (contact->assistant_name != NULL + || contact->assistant_phone != NULL) { + fprintf(f_output, "AGENT:BEGIN:VCARD\\n"); + if (contact->assistant_name != NULL) + fprintf(f_output, "FN:%s\\n", + rfc2426_escape(contact->assistant_name)); + if (contact->assistant_phone != NULL) + fprintf(f_output, "TEL:%s\\n", + rfc2426_escape(contact->assistant_phone)); + } + if (contact->company_name != NULL) + fprintf(f_output, "ORG:%s\n", + rfc2426_escape(contact->company_name)); + if (comment != NULL) + fprintf(f_output, "NOTE:%s\n", rfc2426_escape(comment)); + + fprintf(f_output, "VERSION: 3.0\n"); + fprintf(f_output, "END:VCARD\n\n"); +} + +void write_appointment(FILE* f_output, pst_item_appointment* appointment, + pst_item_email* email, FILETIME* create_date, FILETIME* modify_date) +{ + fprintf(f_output, "BEGIN:VEVENT\n"); + if (create_date != NULL) + fprintf(f_output, "CREATED:%s\n", + rfc2445_datetime_format(create_date)); + if (modify_date != NULL) + fprintf(f_output, "LAST-MOD:%s\n", + rfc2445_datetime_format(modify_date)); + if (email != NULL && email->subject != NULL) + fprintf(f_output, "SUMMARY:%s\n", + rfc2426_escape(email->subject->subj)); + if (email != NULL && email->body != NULL) + fprintf(f_output, "DESCRIPTION:%s\n", + rfc2426_escape(email->body)); + if (appointment != NULL && appointment->start != NULL) + fprintf(f_output, "DTSTART;VALUE=DATE-TIME:%s\n", + rfc2445_datetime_format(appointment->start)); + if (appointment != NULL && appointment->end != NULL) + fprintf(f_output, "DTEND;VALUE=DATE-TIME:%s\n", + rfc2445_datetime_format(appointment->end)); + if (appointment != NULL && appointment->location != NULL) + fprintf(f_output, "LOCATION:%s\n", + rfc2426_escape(appointment->location)); + if (appointment != NULL) { + switch (appointment->showas) { + case PST_FREEBUSY_TENTATIVE: + fprintf(f_output, "STATUS:TENTATIVE\n"); + break; + case PST_FREEBUSY_FREE: + // mark as transparent and as confirmed + fprintf(f_output, "TRANSP:TRANSPARENT\n"); + case PST_FREEBUSY_BUSY: + case PST_FREEBUSY_OUT_OF_OFFICE: + fprintf(f_output, "STATUS:CONFIRMED\n"); + break; + } + switch (appointment->label) { + case PST_APP_LABEL_NONE: + fprintf(f_output, "CATEGORIES:NONE\n"); + break; + case PST_APP_LABEL_IMPORTANT: + fprintf(f_output, "CATEGORIES:IMPORTANT\n"); + break; + case PST_APP_LABEL_BUSINESS: + fprintf(f_output, "CATEGORIES:BUSINESS\n"); + break; + case PST_APP_LABEL_PERSONAL: + fprintf(f_output, "CATEGORIES:PERSONAL\n"); + break; + case PST_APP_LABEL_VACATION: + fprintf(f_output, "CATEGORIES:VACATION\n"); + break; + case PST_APP_LABEL_MUST_ATTEND: + fprintf(f_output, "CATEGORIES:MUST-ATTEND\n"); + break; + case PST_APP_LABEL_TRAVEL_REQ: + fprintf(f_output, "CATEGORIES:TRAVEL-REQUIRED\n"); + break; + case PST_APP_LABEL_NEEDS_PREP: + fprintf(f_output, "CATEGORIES:NEEDS-PREPARATION\n"); + break; + case PST_APP_LABEL_BIRTHDAY: + fprintf(f_output, "CATEGORIES:BIRTHDAY\n"); + break; + case PST_APP_LABEL_ANNIVERSARY: + fprintf(f_output, "CATEGORIES:ANNIVERSARY\n"); + break; + case PST_APP_LABEL_PHONE_CALL: + fprintf(f_output, "CATEGORIES:PHONE-CALL\n"); + break; + } + } + fprintf(f_output, "END:VEVENT\n\n"); +} + +void create_enter_dir(struct file_ll* f, char file_as[], int mode, int overwrite) +{ + if (mode == MODE_KMAIL) + f->name = mk_kmail_dir(file_as); //create directory and form filename + else if (mode == MODE_RECURSE) + f->name = mk_recurse_dir(file_as); + else if (mode == MODE_SEPERATE) { + // do similar stuff to recurse here. + mk_seperate_dir(file_as, overwrite); + f->name = (char*) xmalloc(10); + memset(f->name, 0, 10); + // sprintf(f->name, SEP_MAIL_FILE_TEMPLATE, f->email_count); + } else { + f->name = (char*) xmalloc(strlen(file_as)+strlen(OUTPUT_TEMPLATE+1)); + sprintf(f->name, OUTPUT_TEMPLATE, file_as); + } + + f->dname = (char*) xmalloc(strlen(file_as)+1); + strcpy(f->dname, file_as); + + if (overwrite != 1) { + int x = 0; + char *temp = (char*) xmalloc (strlen(f->name)+10); //enough room for 10 digits + + sprintf(temp, "%s", f->name); + temp = check_filename(temp); + while ((f->output = fopen(temp, "r")) != NULL) { + DEBUG_MAIN(("create_enter_dir: need to increase filename cause one already exists with that name\n")); + DEBUG_MAIN(("create_enter_dir: - increasing it to %s%d\n", f->name, x)); + x++; + sprintf(temp, "%s%08d", f->name, x); + DEBUG_MAIN(("create_enter_dir: - trying \"%s\"\n", f->name)); + if (x == 99999999) { + DIE(("create_enter_dir: Why can I not create a folder %s? I have tried %i extensions...\n", f->name, x)); + } + fclose(f->output); + } + if (x > 0) { //then the f->name should change + free (f->name); + f->name = temp; + } else { + free(temp); + } + } + + DEBUG_MAIN(("create_enter_dir: f->name = %s\nitem->folder_name = %s\n", f->name, file_as)); + if (mode != MODE_SEPERATE) { + f->name = check_filename(f->name); + if ((f->output = fopen(f->name, "w")) == NULL) { + DIE(("create_enter_dir: Could not open file \"%s\" for write\n", f->name)); + } + } +} +
--- a/xml/Makefile.in Mon Feb 20 15:14:54 2006 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,322 +0,0 @@ -# Makefile.in generated by automake 1.9.2 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004 Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -top_builddir = .. -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -INSTALL = @INSTALL@ -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = xml -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ - $(srcdir)/libpst.in -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.in -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = libpst -SOURCES = -DIST_SOURCES = -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMDEP_FALSE = @AMDEP_FALSE@ -AMDEP_TRUE = @AMDEP_TRUE@ -AMTAR = @AMTAR@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -BASH = @BASH@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXCPP = @CXXCPP@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO = @ECHO@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -F77 = @F77@ -FFLAGS = @FFLAGS@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAKEINFO = @MAKEINFO@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_CXX = @ac_ct_CXX@ -ac_ct_F77 = @ac_ct_F77@ -ac_ct_RANLIB = @ac_ct_RANLIB@ -ac_ct_STRIP = @ac_ct_STRIP@ -am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ -am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ -am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ -am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -datadir = @datadir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -all: all-am - -.SUFFIXES: -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu xml/Makefile'; \ - cd $(top_srcdir) && \ - $(AUTOMAKE) --gnu xml/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -libpst: $(top_builddir)/config.status $(srcdir)/libpst.in - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -distclean-libtool: - -rm -f libtool -uninstall-info-am: -tags: TAGS -TAGS: - -ctags: CTAGS -CTAGS: - - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ - list='$(DISTFILES)'; for file in $$list; do \ - case $$file in \ - $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ - $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ - esac; \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test "$$dir" != "$$file" && test "$$dir" != "."; then \ - dir="/$$dir"; \ - $(mkdir_p) "$(distdir)$$dir"; \ - else \ - dir=''; \ - fi; \ - if test -d $$d/$$file; then \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ - fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ - else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libtool mostlyclean-am - -distclean: distclean-am - -rm -f Makefile -distclean-am: clean-am distclean-generic distclean-libtool - -dvi: dvi-am - -dvi-am: - -html: html-am - -info: info-am - -info-am: - -install-data-am: - -install-exec-am: - -install-info: install-info-am - -install-man: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-generic mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-info-am - -.PHONY: all all-am check check-am clean clean-generic clean-libtool \ - distclean distclean-generic distclean-libtool distdir dvi \ - dvi-am html html-am info info-am install install-am \ - install-data install-data-am install-exec install-exec-am \ - install-info install-info-am install-man install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \ - uninstall-info-am - -all: libpst - cat header.xml libpst >libpst.xml - cat header.sgml libpst >libpst.sgml - rm -f ../html/*html - rm -f ../html/*pdf - xmlto -o ../man man libpst.xml - xmlto -o ../html xhtml libpst.xml - xmlto -o ../html pdf libpst.xml - docbook2texi -o ../info libpst.sgml - rm -f libpst.xml libpst.sgml -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT:
--- a/xml/libpst.in Mon Feb 20 15:14:54 2006 -0800 +++ b/xml/libpst.in Tue Feb 21 22:50:16 2006 -0800 @@ -38,6 +38,7 @@ <arg><option>-q</option></arg> <arg><option>-r</option></arg> <arg><option>-S</option></arg> + <arg><option>-M</option></arg> <arg><option>-V</option></arg> <arg><option>-w</option></arg> <arg rep='repeat' choice='plain'>files</arg> @@ -107,15 +108,25 @@ <varlistentry> <term>-S</term> <listitem><para> - Output messages into separate files. This will create folders as - named in the PST file, and will put each email in its own file. These - files will be numbered from 000000000 increasing in intervals of 1 (ie - 000000000, 000000001, 0000000002). Any attachments are saved alongside + Output messages into separate files. This will create folders as named + in the PST file, and will put each email in its own file. These files + will be numbered from 000000000 increasing in intervals of 1 (ie + 000000000, 000000001, 0000000002). Any attachments are saved alongside each email as 000000000-attach0, or with the name of the attachment if one is present. </para></listitem> </varlistentry> <varlistentry> + <term>-M</term> + <listitem><para> + Output messages in MH format as separate files. This will create + folders as named in the PST file, and will put each email in its own + file. These files will be numbered from 1 to n with no leading zeros. + Any attachments are saved alongside each email as 000000000-attach0, or + with the name of the attachment if one is present. + </para></listitem> + </varlistentry> + <varlistentry> <term>-V</term> <listitem><para> Show program version. Subsequent options are then ignored. @@ -135,7 +146,7 @@ <refsect1 id='readpst.also.1'> <title>See Also</title> <para> - <citerefentry><refentrytitle>readpstlog</refentrytitle></citerefentry> + <citerefentry><refentrytitle>readpstlog</refentrytitle> <manvolnum>1</manvolnum> </citerefentry> </para> </refsect1>