Main Page | Namespace List | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

pst2dii.cpp

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (c) 2008 Carl Byington - 510 Software Group, released under
00004 the GPL version 2 or any later version at your choice available at
00005 http://www.fsf.org/licenses/gpl.txt
00006 
00007 Based on readpst.c by David Smith
00008 
00009 */
00010 #include <iostream>
00011 #include <string>
00012 #include <vector>
00013 
00014 using namespace std;
00015 
00016 extern "C" {
00017     #include "define.h"
00018     #include "lzfu.h"
00019 }
00020 
00021 struct file_ll {
00022     string  name;
00023     int32_t stored_count;
00024     int32_t email_count;
00025     int32_t skip_count;
00026     int32_t type;
00027     file_ll() {
00028         stored_count = 0;
00029         email_count  = 0;
00030         skip_count   = 0;
00031         type         = 0;
00032     };
00033 };
00034 
00035 // global settings
00036 const char*    convert = "/usr/bin/convert";     // fully qualified path of the convert program from image magick
00037 const char*    prog_name = NULL;          // our arg0 name
00038 const char*    bates_prefix = "";         // string to prefix bates numbers
00039 int            bates_index = 0;           // current bates sequence
00040 const char*    output_directory = ".";
00041 const char*    output_file = "load.dii";
00042 char*    font_file = NULL;
00043 int      bates_color = 0xff0000;    // color of bates header stamp
00044 int      email_sequence = 0;        // current pdf sequence number
00045 char     pdf_name[PATH_MAX];        // current pdf file name
00046 FILE*    dii_file = NULL;           // the output dii load file
00047 pst_file pstfile;                   // the input pst file
00048 
00049 // pdf writer globals
00050 bool     pdf_open = false;          // is pdf writer started
00051 char*    pst_folder;                // current folder name
00052 int      page_sequence;             // current page number
00053 string   conversion;                // conversion command
00054 vector<string>  png_names;
00055 
00056 // png writer globals
00057 bool     png_open = false;          // is current page open
00058 int      line_height;               // in pixels
00059 int      char_width;                // in pixels
00060 int      col_number, col_max;       // in characters
00061 int      line_number, line_max;     // lines per page
00062 int      x_position, y_position;    // in pixels
00063 int      black, red;                // text colors
00064 gdImagePtr  image;                  // current gd image
00065 
00066 const int DPI         = 300;
00067 const double sz       = 10.0;
00068 const int margin      = DPI/2;
00069 const int LINE_SIZE   = 2000;
00070 const int PAGE_WIDTH  = DPI*17/2;
00071 const int PAGE_HEIGHT = DPI*11;
00072 
00073 // max size of the c_time char*. It will store the date of the email
00074 #define C_TIME_SIZE 500
00075 
00076 static void open_png();
00077 static void close_png();
00078 
00079 
00080 static void version();
00081 static void version()
00082 {
00083     printf("pst2dii v%s\n", VERSION);
00084 #if BYTE_ORDER == BIG_ENDIAN
00085     printf("Big Endian implementation being used.\n");
00086 #elif BYTE_ORDER == LITTLE_ENDIAN
00087     printf("Little Endian implementation being used.\n");
00088 #else
00089 #  error "Byte order not supported by this library"
00090 #endif
00091 #ifdef __GNUC__
00092     printf("GCC %d.%d : %s %s\n", __GNUC__, __GNUC_MINOR__, __DATE__, __TIME__);
00093 #endif
00094 }
00095 
00096 
00097 static void usage();
00098 static void usage()
00099 {
00100     version();
00101     printf("Usage: %s [OPTIONS] {PST FILENAME}\n", prog_name);
00102     printf("OPTIONS:\n");
00103     printf("\t-B bates-prefix   \t- Set the bates prefix string\n");
00104     printf("\t-O dii-output-file\t- Set the dii load file output filename\n");
00105     printf("\t-V                \t- Version. Display program version\n");
00106     printf("\t-b bates-number   \t- Set the starting bates sequence number\n");
00107     printf("\t-c bates-color    \t- Specify the color of the bates stamps as 6 digit hex\n");
00108     printf("\t-d filename       \t- Debug to file. This is a binary log. Use readpstlog to print it.\n");
00109     printf("\t-f ttf-font-file  \t- Set the font file\n");
00110     printf("\t-h                \t- Help. This screen\n");
00111     printf("\t-o dirname        \t- Output directory to write files to.\n");
00112 }
00113 
00114 
00115 static char *removeCR (char *c);
00116 static char *removeCR (char *c) {
00117     // converts /r/n to /n
00118     char *a, *b;
00119     DEBUG_ENT("removeCR");
00120     a = b = c;
00121     while (*a != '\0') {
00122         *b = *a;
00123         if (*a != '\r')
00124             b++;
00125         a++;
00126     }
00127     *b = '\0';
00128     DEBUG_RET();
00129     return c;
00130 }
00131 
00132 
00133 // The sole purpose of this function is to bypass the pseudo-header prologue
00134 // that Microsoft Outlook inserts at the beginning of the internet email
00135 // headers for emails stored in their "Personal Folders" files.
00136 static char *skip_header_prologue(char *headers);
00137 static char *skip_header_prologue(char *headers) {
00138     const char *bad = "Microsoft Mail Internet Headers";
00139     if (strncmp(headers, bad, strlen(bad)) == 0) {
00140         // Found the offensive header prologue
00141         char *pc = strchr(headers, '\n');
00142         return pc + 1;
00143     }
00144     return headers;
00145 }
00146 
00147 
00148 static void check_filename(string &fname);
00149 static void check_filename(string &fname) {
00150     char *t = strdup(fname.c_str());
00151     DEBUG_ENT("check_filename");
00152     if (!t) {
00153         DEBUG_RET();
00154         return;
00155     }
00156     char *tt = t;
00157     bool fixed = false;
00158     while ((t = strpbrk(t, " /\\:"))) {
00159         // while there are characters in the second string that we don't want
00160         *t = '_'; //replace them with an underscore
00161         fixed = true;
00162     }
00163     if (fixed) fname = string(tt);
00164     free(tt);
00165     DEBUG_RET();
00166 }
00167 
00168 
00169 static string write_separate_attachment(string fname, pst_item_attach* current_attach, int attach_num, pst_file* pst);
00170 static string write_separate_attachment(string fname, pst_item_attach* current_attach, int attach_num, pst_file* pst)
00171 {
00172     FILE *fp = NULL;
00173     int x = 0;
00174     char *temp = NULL;
00175 
00176     // If there is a long filename (filename2) use that, otherwise
00177     // use the 8.3 filename (filename1)
00178     char *attach_filename = (current_attach->filename2.str) ? current_attach->filename2.str
00179                                                             : current_attach->filename1.str;
00180     DEBUG_ENT("write_separate_attachment");
00181     check_filename(fname);
00182     const char* f_name = fname.c_str();
00183     DEBUG_EMAIL(("dirname=%s, pathname=%s, filename=%s\n", output_directory, f_name, attach_filename));
00184     int len = strlen(output_directory) + 1 + strlen(f_name) + 15;
00185     if (!attach_filename) {
00186         // generate our own (dummy) filename for the attachement
00187         temp = (char*)xmalloc(len);
00188         sprintf(temp, "%s/%s_attach%i", output_directory, f_name, attach_num);
00189     } else {
00190         // have an attachment name, make sure it's unique
00191         temp = (char*)xmalloc(len+strlen(attach_filename));
00192         do {
00193             if (fp) fclose(fp);
00194             if (x == 0)
00195                 sprintf(temp, "%s/%s_%s", output_directory, f_name, attach_filename);
00196             else
00197                 sprintf(temp, "%s/%s_%s-%i", output_directory, f_name, attach_filename, x);
00198         } while ((fp = fopen(temp, "r")) && ++x < 99999999);
00199         if (x > 99999999) {
00200             DIE(("error finding attachment name. exhausted possibilities to %s\n", temp));
00201         }
00202     }
00203     DEBUG_EMAIL(("Saving attachment to %s\n", temp));
00204     if (!(fp = fopen(temp, "wb"))) {
00205         WARN(("write_separate_attachment: Cannot open attachment save file \"%s\"\n", temp));
00206     } else {
00207         if (current_attach->data.data)
00208             pst_fwrite(current_attach->data.data, 1, current_attach->data.size, fp);
00209         else {
00210             (void)pst_attach_to_file(pst, current_attach, fp);
00211         }
00212         fclose(fp);
00213     }
00214     string rc(temp);
00215     if (temp) free(temp);
00216     DEBUG_RET();
00217     return rc;
00218 }
00219 
00220 
00221 static void print_pdf_short(const char *line, int len, int color);
00222 static void print_pdf_short(const char *line, int len, int color)
00223 {
00224     if (line_number >= line_max) {
00225         close_png();
00226         open_png();
00227     }
00228     int brect[8];
00229     gdFTStringExtra strex;
00230     strex.flags       = gdFTEX_RESOLUTION;
00231     strex.linespacing = 1.20;
00232     strex.charmap     = 0;
00233     strex.hdpi        = DPI;
00234     strex.vdpi        = DPI;
00235     char xline[len+1];
00236     memcpy(xline, line, len);
00237     xline[len] = '\0';
00238     char *p;
00239     char *l = xline;
00240     while ((p = strchr(l, '&'))) {
00241         *p = '\0';
00242         char *err = gdImageStringFTEx(image, &brect[0], color, font_file, sz, 0.0, x_position, y_position, l, &strex);
00243         if (err) printf(err);
00244         x_position += (brect[2]-brect[6]);
00245         l = p+1;
00246         err = gdImageStringFTEx(image, &brect[0], color, font_file, sz, 0.0, x_position, y_position, (char*)"&amp;", &strex);
00247         if (err) printf(err);
00248         x_position += (brect[2]-brect[6]);
00249     }
00250     char *err = gdImageStringFTEx(image, &brect[0], color, font_file, sz, 0.0, x_position, y_position, l, &strex);
00251     if (err) printf(err);
00252     x_position += (brect[2]-brect[6]);
00253     col_number += len;
00254 }
00255 
00256 
00257 static void new_line();
00258 static void new_line()
00259 {
00260     y_position  += line_height;
00261     line_number += 1;
00262     x_position   = margin;
00263     col_number   = 0;
00264 }
00265 
00266 
00267 static void print_pdf_single(const char *line, int color);
00268 static void print_pdf_single(const char *line, int color)
00269 {
00270     while (*line == '\t') {
00271         char blanks[5];
00272         memset(blanks, ' ', 5);
00273         print_pdf_short(blanks, 4, color);
00274         line++;
00275         if (col_number >= col_max) new_line();
00276     }
00277     int n = strlen(line);
00278     while (n) {
00279         int m = col_max - col_number;   // number of chars that will fit on this line
00280         m = (n > m) ? m : n;
00281         print_pdf_short(line, m, color);
00282         line += m;
00283         n    -= m;
00284         if (n) new_line();
00285     }
00286 }
00287 
00288 
00289 static void print_pdf_only(char *line, int color);
00290 static void print_pdf_only(char *line, int color)
00291 {
00292     char *p;
00293     while ((p = strchr(line, '\n'))) {
00294         *p = '\0';
00295         print_pdf_single(line, color);
00296         *p = '\n';
00297         line = p+1;
00298         new_line();
00299     }
00300     print_pdf_single(line, color);
00301 }
00302 
00303 
00304 static void print_pdf(char *line);
00305 static void print_pdf(char *line)
00306 {
00307     pst_fwrite(line, 1, strlen(line), dii_file);
00308     print_pdf_only(line, black);
00309 }
00310 
00311 
00312 static void open_png()
00313 {
00314     if (!png_open) {
00315         png_open  = true;
00316         int brect[8];
00317         image = gdImageCreate(PAGE_WIDTH, PAGE_HEIGHT);
00318                 gdImageColorAllocate(image, 255, 255, 255); // background color first one allocated
00319         black = gdImageColorAllocate(image, 0, 0, 0);
00320         int r = (bates_color & 0xff0000) >> 16;
00321         int g = (bates_color & 0x00ff00) >> 8;
00322         int b = (bates_color & 0x0000ff);
00323         red   = gdImageColorAllocate(image, r, g, b);
00324 
00325         gdFTStringExtra strex;
00326         strex.flags       = gdFTEX_RESOLUTION;
00327         strex.linespacing = 1.20;
00328         strex.charmap     = 0;
00329         strex.hdpi        = DPI;
00330         strex.vdpi        = DPI;
00331 
00332         char line[LINE_SIZE];
00333         char *err = gdImageStringFTEx(NULL, &brect[0], black, font_file, sz, 0.0, margin, margin, (char*)"LMgqQ", &strex);
00334         if (err) printf(err);
00335         line_height = (brect[3]-brect[7]) * 12/10;
00336         char_width  = (brect[2]-brect[6]) / 5;
00337         col_number  = 0;
00338         col_max     = (PAGE_WIDTH - margin*2) / char_width;
00339         line_number = 0;
00340         line_max    = (PAGE_HEIGHT - margin*2) / line_height;
00341         x_position  = margin;
00342         y_position  = margin + line_height;
00343         snprintf(line, sizeof(line), "%s%06d\n", bates_prefix, bates_index++);
00344         print_pdf_only(line, red);
00345         print_pdf_only(pst_folder, red);
00346     }
00347 }
00348 
00349 
00350 static void close_png()
00351 {
00352     if (png_open) {
00353         png_open = false;
00354         char fn[PATH_MAX];
00355         snprintf(fn, sizeof(fn), "page%d.png", ++page_sequence);
00356         FILE *pngout = fopen(fn, "wb");
00357         if (pngout) {
00358             gdImagePng(image, pngout);
00359             fclose(pngout);
00360         }
00361         gdImageDestroy(image); // free memory
00362         png_names.push_back(fn);
00363         conversion += string(" ") + fn;
00364     }
00365 }
00366 
00367 
00368 static void open_pdf(char *line);
00369 static void open_pdf(char *line)
00370 {
00371     pst_folder    = line;
00372     page_sequence = 0;
00373     conversion    = string(convert);
00374     png_names.clear();
00375     open_png();
00376     snprintf(pdf_name, sizeof(pdf_name), "dii%06d", ++email_sequence);
00377     fprintf(dii_file, "\n@T %s\n", pdf_name);
00378     snprintf(pdf_name, sizeof(pdf_name), "%s/dii%06d.pdf", output_directory, email_sequence);
00379 }
00380 
00381 
00382 static void close_pdf();
00383 static void close_pdf()
00384 {
00385     close_png();
00386     conversion += string(" ") + pdf_name;
00387     (void)system(conversion.c_str());
00388     for (vector<string>::iterator i=png_names.begin(); i!=png_names.end(); i++) {
00389         remove((*i).c_str());
00390     }
00391     fprintf(dii_file, "@D %s\n", pdf_name);
00392 }
00393 
00394 
00395 static void write_simple(const char *tag, const char *value);
00396 static void write_simple(const char *tag, const char *value)
00397 {
00398     if (value) fprintf(dii_file, "@%s %s\n", tag, value);
00399 }
00400 
00401 
00402 static void write_simple(const char *tag, string value);
00403 static void write_simple(const char *tag, string value)
00404 {
00405     fprintf(dii_file, "@%s %s\n", tag, value.c_str());
00406 }
00407 
00408 
00409 static void write_simple(const char *tag, const char *value, const char *value2);
00410 static void write_simple(const char *tag, const char *value, const char *value2)
00411 {
00412     if (value) {
00413     if (value2) fprintf(dii_file, "@%s \"%s\" <%s>\n", tag, value, value2);
00414     else        fprintf(dii_file, "@%s \"%s\"\n", tag, value);
00415     }
00416 }
00417 
00418 
00419 static string extract_header(char *headers, const char *field);
00420 static string extract_header(char *headers, const char *field)
00421 {
00422     string rc;
00423     int len = strlen(field) + 4;
00424     char f[len];
00425     snprintf(f, len, "\n%s: ", field);
00426     char *p = strstr(headers, f);
00427     if (p) {
00428         p += strlen(f);
00429         char *n = strchr(p, '\n');
00430         if (n) {
00431             *n = '\0';
00432             rc = string(p);
00433             *n = '\n';
00434         }
00435         else {
00436             rc = string(p);
00437         }
00438     }
00439     return rc;
00440 }
00441 
00442 
00443 static void write_normal_email(file_ll &f, pst_item* item, pst_file* pst);
00444 static void write_normal_email(file_ll &f, pst_item* item, pst_file* pst)
00445 {
00446     DEBUG_ENT("write_normal_email");
00447     char *soh = NULL;  // real start of headers.
00448     if (item->email->header.str) {
00449         // some of the headers we get from the file are not properly defined.
00450         // they can contain some email stuff too. We will cut off the header
00451         // when we see a \n\n or \r\n\r\n
00452         removeCR(item->email->header.str);
00453         char *temp = strstr(item->email->header.str, "\n\n");
00454         if (temp) {
00455             DEBUG_EMAIL(("Found body text in header\n"));
00456             temp[1] = '\0'; // stop after first \n
00457         }
00458         soh = skip_header_prologue(item->email->header.str);
00459     }
00460 
00461     char folder_line[LINE_SIZE];
00462     char line[LINE_SIZE];
00463     // reset pdf writer to new file
00464     int bates = bates_index;    // save starting index
00465     snprintf(folder_line, sizeof(folder_line), "pst folder = %s\n", f.name.c_str());
00466     open_pdf(folder_line);
00467 
00468     // start printing this email
00469     fprintf(dii_file, "@FOLDERNAME %s\n", f.name.c_str());
00470     string myfrom = extract_header(soh, "From");
00471     string myto   = extract_header(soh, "To");
00472     string mycc   = extract_header(soh, "Cc");
00473     string mybcc  = extract_header(soh, "Bcc");
00474     if (myfrom.empty()) write_simple("FROM", item->email->outlook_sender_name.str, item->email->sender_address.str);
00475     else                write_simple("FROM", myfrom);
00476     if (myto.empty())   write_simple("TO",   item->email->sentto_address.str,      item->email->recip_address.str);
00477     else                write_simple("TO", myto);
00478     if (mycc.empty())   write_simple("CC",   item->email->cc_address.str);
00479     else                write_simple("CC", mycc);
00480     if (mybcc.empty())  write_simple("BCC",  item->email->bcc_address.str);
00481     else                write_simple("BCC", mybcc);
00482     if (item->email->sent_date) {
00483         time_t t = fileTimeToUnixTime(item->email->sent_date, NULL);
00484         char c_time[C_TIME_SIZE];
00485         strftime(c_time, C_TIME_SIZE, "%F", gmtime(&t));
00486         write_simple("DATESENT", c_time);
00487         strftime(c_time, C_TIME_SIZE, "%T+0000", gmtime(&t));
00488         write_simple("TIMESENT", c_time);
00489     }
00490     if (item->email->arrival_date) {
00491         time_t t = fileTimeToUnixTime(item->email->arrival_date, NULL);
00492         char c_time[C_TIME_SIZE];
00493         strftime(c_time, C_TIME_SIZE, "%F", gmtime(&t));
00494         write_simple("DATERCVD", c_time);
00495         strftime(c_time, C_TIME_SIZE, "%T+0000", gmtime(&t));
00496         write_simple("TIMERCVD", c_time);
00497     }
00498     if (item->subject.str) {
00499         write_simple("SUBJECT", item->subject.str);
00500     }
00501     write_simple("MSGID", item->email->messageid.str);
00502     write_simple("READ", (item->flags & 1) ? "Y" : "N");
00503 
00504     DEBUG_EMAIL(("About to print Header\n"));
00505     fprintf(dii_file, "@HEADER\n");
00506 
00507     if (item && item->subject.str) {
00508         DEBUG_EMAIL(("item->subject = %s\n", item->subject.str));
00509     }
00510 
00511     if (soh) {
00512         // Now, write out the header...
00513         print_pdf(soh);
00514         int len = strlen(soh);
00515         if (!len || (soh[len-1] != '\n')) {
00516             snprintf(line, sizeof(line), "\n");
00517             print_pdf(line);
00518         }
00519 
00520     } else {
00521         //make up our own headers
00522         const char *temp = item->email->outlook_sender.str;
00523         if (!temp) temp = "";
00524         snprintf(line, sizeof(line), "From: \"%s\" <%s>\n", item->email->outlook_sender_name.str, temp);
00525         print_pdf(line);
00526 
00527         if (item->subject.str) {
00528             snprintf(line, sizeof(line), "Subject: %s\n", item->subject.str);
00529         } else {
00530             snprintf(line, sizeof(line), "Subject: \n");
00531         }
00532         print_pdf(line);
00533 
00534         snprintf(line, sizeof(line), "To: %s\n", item->email->sentto_address.str);
00535         print_pdf(line);
00536 
00537         if (item->email->cc_address.str) {
00538             snprintf(line, sizeof(line), "Cc: %s\n", item->email->cc_address.str);
00539             print_pdf(line);
00540         }
00541 
00542         if (item->email->sent_date) {
00543             time_t em_time = fileTimeToUnixTime(item->email->sent_date, 0);
00544             char c_time[C_TIME_SIZE];
00545             strftime(c_time, C_TIME_SIZE, "%a, %d %b %Y %H:%M:%S %z", gmtime(&em_time));
00546             snprintf(line, sizeof(line), "Date: %s\n", c_time);
00547             print_pdf(line);
00548         }
00549     }
00550     snprintf(line, sizeof(line), "\n");
00551     print_pdf_only(line, black);
00552     fprintf(dii_file, "@HEADER-END\n");
00553 
00554     DEBUG_EMAIL(("About to print Body\n"));
00555     fprintf(dii_file, "@EMAIL-BODY\n");
00556     if (item->body.str) {
00557         removeCR(item->body.str);
00558         print_pdf(item->body.str);
00559     } else if (item->email->htmlbody.str) {
00560         removeCR(item->email->htmlbody.str);
00561         print_pdf(item->email->htmlbody.str);
00562     } else if (item->email->encrypted_body.data || item->email->encrypted_htmlbody.data) {
00563         char ln[LINE_SIZE];
00564         snprintf(ln, sizeof(ln), "%s", "The body of this email is encrypted. This isn't supported yet, but the body is now an attachment\n");
00565         print_pdf(ln);
00566     }
00567     fprintf(dii_file, "@EMAIL-END\n");
00568 
00569     int attach_num = 0;
00570     for (pst_item_attach* current_attach = item->attach; current_attach; current_attach = current_attach->next) {
00571         DEBUG_EMAIL(("Attempting Attachment encoding\n"));
00572         if (!current_attach->data.data) {
00573             DEBUG_EMAIL(("Data of attachment is NULL!. Size is supposed to be %i\n", current_attach->data.size));
00574         }
00575         string an = write_separate_attachment(f.name, current_attach, ++attach_num, pst);
00576         fprintf(dii_file, "@EATTACH %s\n", an.c_str());
00577     }
00578     close_pdf();
00579     fprintf(dii_file, "@BATESBEG %d\n", bates);
00580     fprintf(dii_file, "@BATESEND %d\n", bates_index-1);
00581     DEBUG_RET();
00582 }
00583 
00584 
00585 static void create_enter_dir(file_ll &f, file_ll *parent, pst_item *item);
00586 static void create_enter_dir(file_ll &f, file_ll *parent, pst_item *item)
00587 {
00588     f.email_count  = 0;
00589     f.skip_count   = 0;
00590     f.type         = item->type;
00591     f.stored_count = (item->folder) ? item->folder->item_count : 0;
00592     f.name         = ((parent) ? parent->name + "/" : "") + string(item->file_as.str);
00593 }
00594 
00595 
00596 static void close_enter_dir(file_ll &f);
00597 static void close_enter_dir(file_ll &f)
00598 {
00599 }
00600 
00601 
00602 static void process(pst_item *outeritem, file_ll *parent, pst_desc_ll *d_ptr);
00603 static void process(pst_item *outeritem, file_ll *parent, pst_desc_ll *d_ptr)
00604 {
00605     file_ll ff;
00606     pst_item *item = NULL;
00607     DEBUG_ENT("process");
00608     create_enter_dir(ff, parent, outeritem);
00609     while (d_ptr) {
00610         if (d_ptr->desc) {
00611             item = pst_parse_item(&pstfile, d_ptr, NULL);
00612             DEBUG_INFO(("item pointer is %p\n", item));
00613             if (item) {
00614                 if (item->folder && d_ptr->child )  {
00615                     //if this is a non-empty folder, we want to recurse into it
00616                     fprintf(stderr, "entering folder %s\n", item->file_as.str);
00617                     process(item, &ff, d_ptr->child);
00618                 } else if (item->email && (item->type == PST_TYPE_NOTE || item->type == PST_TYPE_REPORT || item->type == PST_TYPE_OTHER)) {
00619                     ff.email_count++;
00620                     DEBUG_MAIN(("main: Processing Email\n"));
00621                     if ((ff.type != PST_TYPE_NOTE) && (ff.type != PST_TYPE_REPORT) && (ff.type != PST_TYPE_OTHER)) {
00622                         DEBUG_MAIN(("main: I have an email, but the folder isn't an email folder. Processing anyway\n"));
00623                     }
00624                     write_normal_email(ff, item, &pstfile);
00625                 }
00626                 pst_freeItem(item);
00627             } else {
00628                 ff.skip_count++;
00629                 DEBUG_MAIN(("main: A NULL item was seen\n"));
00630             }
00631         }
00632         d_ptr = d_ptr->next;
00633     }
00634     close_enter_dir(ff);
00635     DEBUG_RET();
00636 }
00637 
00638 
00639 int main(int argc, char* const* argv)
00640 {
00641     pst_desc_ll *d_ptr;
00642     char *fname = NULL;
00643     char c;
00644     char *d_log = NULL;
00645     prog_name = argv[0];
00646     pst_item *item = NULL;
00647 
00648     while ((c = getopt(argc, argv, "B:b:c:d:f:o:O:Vh"))!= -1) {
00649         switch (c) {
00650         case 'B':
00651             bates_prefix = optarg;
00652             break;
00653         case 'b':
00654             bates_index = atoi(optarg);
00655             break;
00656         case 'c':
00657             bates_color = (int)strtol(optarg, (char**)NULL, 16);
00658             break;
00659         case 'f':
00660             font_file = optarg;
00661             break;
00662         case 'o':
00663             output_directory = optarg;
00664             break;
00665         case 'O':
00666             output_file = optarg;
00667             break;
00668         case 'd':
00669             d_log = optarg;
00670             break;
00671         case 'h':
00672             usage();
00673             exit(0);
00674             break;
00675         case 'V':
00676             version();
00677             exit(0);
00678             break;
00679         default:
00680             usage();
00681             exit(1);
00682             break;
00683         }
00684     }
00685 
00686     if (argc > optind) {
00687         fname = argv[optind];
00688     } else {
00689         usage();
00690         exit(2);
00691     }
00692 
00693 
00694     #ifdef DEBUG_ALL
00695         // force a log file
00696         if (!d_log) d_log = "pst2dii.log";
00697     #endif
00698     DEBUG_INIT(d_log);
00699     DEBUG_REGISTER_CLOSE();
00700     DEBUG_ENT("main");
00701     RET_DERROR(pst_open(&pstfile, fname), 1, ("Error opening File\n"));
00702     RET_DERROR(pst_load_index(&pstfile), 2, ("Index Error\n"));
00703 
00704     pst_load_extended_attributes(&pstfile);
00705 
00706     d_ptr = pstfile.d_head; // first record is main record
00707     item  = (pst_item*)pst_parse_item(&pstfile, d_ptr, NULL);
00708     if (!item || !item->message_store) {
00709         DEBUG_RET();
00710         DIE(("main: Could not get root record\n"));
00711     }
00712 
00713     d_ptr = pst_getTopOfFolders(&pstfile, item);
00714     if (!d_ptr) {
00715         DEBUG_RET();
00716         DIE(("Top of folders record not found. Cannot continue\n"));
00717     }
00718 
00719     dii_file = fopen(output_file, "wb");
00720     if (dii_file) {
00721         process(item, NULL, d_ptr->child);  // do the children of TOPF
00722         pst_freeItem(item);
00723         pst_close(&pstfile);
00724         fclose(dii_file);
00725     }
00726     DEBUG_RET();
00727     return 0;
00728 }

Generated on Thu Mar 19 16:39:26 2009 for 'LibPst' by  doxygen 1.3.9.1