Mercurial > libpst
annotate src/readpst.c @ 118:0f1492b7fe8b
patch from Fridrich Strba for building on mingw and general cleanup of autoconf files
add processing for pst files of type 0x0f
start adding support for properly building and installing libpst.so and the header files required to use it.
remove version.h since the version number is now in config.h
more const correctness issues regarding getopt()
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Sat, 31 Jan 2009 12:12:36 -0800 |
parents | ed2a260bbb98 |
children | 6395ced2b8b2 |
rev | line source |
---|---|
16 | 1 /*** |
2 * readpst.c | |
3 * Part of the LibPST project | |
4 * Written by David Smith | |
43 | 5 * dave.s@earthcorp.com |
16 | 6 */ |
48 | 7 #include "define.h" |
59
7d5c637aaafb
General cleanup and code fixes.
Carl Byington <carl@five-ten-sg.com>
parents:
52
diff
changeset
|
8 #include "libstrfunc.h" |
116
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
9 #include "vbuf.h" |
16 | 10 #include "libpst.h" |
11 #include "common.h" | |
12 #include "timeconv.h" | |
13 #include "lzfu.h" | |
59
7d5c637aaafb
General cleanup and code fixes.
Carl Byington <carl@five-ten-sg.com>
parents:
52
diff
changeset
|
14 |
16 | 15 #define OUTPUT_TEMPLATE "%s" |
16 #define OUTPUT_KMAIL_DIR_TEMPLATE ".%s.directory" | |
17 #define KMAIL_INDEX ".%s.index" | |
25 | 18 #define SEP_MAIL_FILE_TEMPLATE "%i" /* "%09i" */ |
16 | 19 |
20 // max size of the c_time char*. It will store the date of the email | |
21 #define C_TIME_SIZE 500 | |
59
7d5c637aaafb
General cleanup and code fixes.
Carl Byington <carl@five-ten-sg.com>
parents:
52
diff
changeset
|
22 |
16 | 23 struct file_ll { |
43 | 24 char *name; |
25 char *dname; | |
26 FILE * output; | |
27 int32_t stored_count; | |
28 int32_t email_count; | |
29 int32_t skip_count; | |
30 int32_t type; | |
16 | 31 }; |
31 | 32 |
43 | 33 void process(pst_item *outeritem, pst_desc_ll *d_ptr); |
34 void write_email_body(FILE *f, char *body); | |
35 char* removeCR (char *c); | |
118
0f1492b7fe8b
patch from Fridrich Strba for building on mingw and general cleanup of autoconf files
Carl Byington <carl@five-ten-sg.com>
parents:
116
diff
changeset
|
36 void usage(); |
0f1492b7fe8b
patch from Fridrich Strba for building on mingw and general cleanup of autoconf files
Carl Byington <carl@five-ten-sg.com>
parents:
116
diff
changeset
|
37 void version(); |
43 | 38 char* mk_kmail_dir(char*); |
39 int close_kmail_dir(); | |
40 char* mk_recurse_dir(char*); | |
41 int close_recurse_dir(); | |
77 | 42 char* mk_separate_dir(char *dir); |
43 int close_separate_dir(); | |
44 int mk_separate_file(struct file_ll *f); | |
43 | 45 char* my_stristr(char *haystack, char *needle); |
46 void check_filename(char *fname); | |
47 char* skip_header_prologue(char *headers); | |
48 void write_separate_attachment(char f_name[], pst_item_attach* current_attach, int attach_num, pst_file* pst); | |
49 void write_inline_attachment(FILE* f_output, pst_item_attach* current_attach, char boundary[], pst_file* pst); | |
50 void write_normal_email(FILE* f_output, char f_name[], pst_item* item, int mode, int mode_MH, pst_file* pst, int save_rtf); | |
51 void write_vcard(FILE* f_output, pst_item_contact* contact, char comment[]); | |
52 void write_appointment(FILE* f_output, pst_item_appointment* appointment, | |
53 pst_item_email* email, FILETIME* create_date, FILETIME* modify_date); | |
54 void create_enter_dir(struct file_ll* f, pst_item *item); | |
55 void close_enter_dir(struct file_ll *f); | |
34
07177825c91b
fix signed/unsigned to allow very small pst files with only leaf nodes
carl
parents:
33
diff
changeset
|
56 |
118
0f1492b7fe8b
patch from Fridrich Strba for building on mingw and general cleanup of autoconf files
Carl Byington <carl@five-ten-sg.com>
parents:
116
diff
changeset
|
57 const char* prog_name; |
34
07177825c91b
fix signed/unsigned to allow very small pst files with only leaf nodes
carl
parents:
33
diff
changeset
|
58 char* output_dir = "."; |
07177825c91b
fix signed/unsigned to allow very small pst files with only leaf nodes
carl
parents:
33
diff
changeset
|
59 char* kmail_chdir = NULL; |
77 | 60 |
16 | 61 // Normal mode just creates mbox format files in the current directory. Each file is named |
62 // the same as the folder's name that it represents | |
63 #define MODE_NORMAL 0 | |
77 | 64 |
16 | 65 // KMail mode creates a directory structure suitable for being used directly |
66 // by the KMail application | |
67 #define MODE_KMAIL 1 | |
77 | 68 |
16 | 69 // recurse mode creates a directory structure like the PST file. Each directory |
70 // contains only one file which stores the emails in mbox format. | |
71 #define MODE_RECURSE 2 | |
77 | 72 |
73 // separate mode creates the same directory structure as recurse. The emails are stored in | |
74 // separate files, numbering from 1 upward. Attachments belonging to the emails are | |
16 | 75 // saved as email_no-filename (e.g. 1-samplefile.doc or 000001-Attachment2.zip) |
77 | 76 #define MODE_SEPARATE 3 |
77 | |
43 | 78 // Decrypt the whole file (even the parts that aren't encrypted) and ralph it to stdout |
79 #define MODE_DECSPEW 4 | |
16 | 80 |
81 | |
82 // Output Normal just prints the standard information about what is going on | |
83 #define OUTPUT_NORMAL 0 | |
77 | 84 |
16 | 85 // Output Quiet is provided so that only errors are printed |
86 #define OUTPUT_QUIET 1 | |
87 | |
88 // default mime-type for attachments that have a null mime-type | |
89 #define MIME_TYPE_DEFAULT "application/octet-stream" | |
90 | |
91 // output mode for contacts | |
92 #define CMODE_VCARD 0 | |
43 | 93 #define CMODE_LIST 1 |
16 | 94 |
100
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
95 // output mode for deleted items |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
96 #define DMODE_EXCLUDE 0 |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
97 #define DMODE_INCLUDE 1 |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
98 |
16 | 99 // output settings for RTF bodies |
100 // filename for the attachment | |
101 #define RTF_ATTACH_NAME "rtf-body.rtf" | |
102 // mime type for the attachment | |
103 #define RTF_ATTACH_TYPE "application/rtf" | |
34
07177825c91b
fix signed/unsigned to allow very small pst files with only leaf nodes
carl
parents:
33
diff
changeset
|
104 |
39 | 105 // global settings |
106 int mode = MODE_NORMAL; | |
107 int mode_MH = 0; | |
108 int output_mode = OUTPUT_NORMAL; | |
109 int contact_mode = CMODE_VCARD; | |
100
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
110 int deleted_mode = DMODE_EXCLUDE; |
39 | 111 int overwrite = 0; |
112 int save_rtf_body = 1; | |
113 pst_file pstfile; | |
114 | |
115 | |
116 | |
117 void process(pst_item *outeritem, pst_desc_ll *d_ptr) | |
118 { | |
43 | 119 struct file_ll ff; |
120 pst_item *item = NULL; | |
39 | 121 |
43 | 122 DEBUG_ENT("process"); |
123 memset(&ff, 0, sizeof(ff)); | |
124 create_enter_dir(&ff, outeritem); | |
39 | 125 |
43 | 126 while (d_ptr) { |
127 DEBUG_MAIN(("main: New item record\n")); | |
128 if (!d_ptr->desc) { | |
129 DEBUG_WARN(("main: ERROR ?? item's desc record is NULL\n")); | |
130 ff.skip_count++; | |
131 } | |
132 else { | |
133 DEBUG_MAIN(("main: Desc Email ID %#x [d_ptr->id = %#x]\n", d_ptr->desc->id, d_ptr->id)); | |
39 | 134 |
46 | 135 item = pst_parse_item(&pstfile, d_ptr); |
43 | 136 DEBUG_MAIN(("main: About to process item\n")); |
137 if (item && item->email && item->email->subject && item->email->subject->subj) { | |
138 DEBUG_EMAIL(("item->email->subject = %p\n", item->email->subject)); | |
139 DEBUG_EMAIL(("item->email->subject->subj = %p\n", item->email->subject->subj)); | |
140 } | |
141 if (item) { | |
100
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
142 if (item->folder && d_ptr->child && (deleted_mode == DMODE_INCLUDE || strcasecmp(item->file_as, "Deleted Items"))) { |
43 | 143 //if this is a non-empty folder other than deleted items, we want to recurse into it |
144 if (output_mode != OUTPUT_QUIET) printf("Processing Folder \"%s\"\n", item->file_as); | |
145 process(item, d_ptr->child); | |
146 | |
147 } else if (item->contact && (item->type == PST_TYPE_CONTACT)) { | |
148 // deal with a contact | |
149 // write them to the file, one per line in this format | |
150 // Desc Name <email@address>\n | |
77 | 151 if (mode == MODE_SEPARATE) mk_separate_file(&ff); |
43 | 152 ff.email_count++; |
153 DEBUG_MAIN(("main: Processing Contact\n")); | |
154 if (ff.type != PST_TYPE_CONTACT) { | |
155 DEBUG_MAIN(("main: I have a contact, but the folder isn't a contacts folder. Processing anyway\n")); | |
156 } | |
157 if (contact_mode == CMODE_VCARD) | |
158 write_vcard(ff.output, item->contact, item->comment); | |
159 else | |
160 fprintf(ff.output, "%s <%s>\n", item->contact->fullname, item->contact->address1); | |
39 | 161 |
110
7133b39975f7
patch from David Cuadrado to process emails with type PST_TYPE_OTHER
Carl Byington <carl@five-ten-sg.com>
parents:
104
diff
changeset
|
162 } else if (item->email && (item->type == PST_TYPE_NOTE || item->type == PST_TYPE_REPORT || item->type == PST_TYPE_OTHER)) { |
77 | 163 if (mode == MODE_SEPARATE) mk_separate_file(&ff); |
43 | 164 ff.email_count++; |
165 DEBUG_MAIN(("main: Processing Email\n")); | |
110
7133b39975f7
patch from David Cuadrado to process emails with type PST_TYPE_OTHER
Carl Byington <carl@five-ten-sg.com>
parents:
104
diff
changeset
|
166 if ((ff.type != PST_TYPE_NOTE) && (ff.type != PST_TYPE_REPORT) && (ff.type != PST_TYPE_OTHER)) { |
43 | 167 DEBUG_MAIN(("main: I have an email, but the folder isn't an email folder. Processing anyway\n")); |
168 } | |
169 write_normal_email(ff.output, ff.name, item, mode, mode_MH, &pstfile, save_rtf_body); | |
39 | 170 |
43 | 171 } else if (item->journal && (item->type == PST_TYPE_JOURNAL)) { |
172 // deal with journal items | |
77 | 173 if (mode == MODE_SEPARATE) mk_separate_file(&ff); |
43 | 174 ff.email_count++; |
175 DEBUG_MAIN(("main: Processing Journal Entry\n")); | |
176 if (ff.type != PST_TYPE_JOURNAL) { | |
177 DEBUG_MAIN(("main: I have a journal entry, but the folder isn't a journal folder. Processing anyway\n")); | |
178 } | |
179 fprintf(ff.output, "BEGIN:VJOURNAL\n"); | |
50 | 180 if (item->email && item->email->subject && item->email->subject->subj) |
43 | 181 fprintf(ff.output, "SUMMARY:%s\n", pst_rfc2426_escape(item->email->subject->subj)); |
50 | 182 if (item->email && item->email->body) |
43 | 183 fprintf(ff.output, "DESCRIPTION:%s\n", pst_rfc2426_escape(item->email->body)); |
184 if (item->journal->start) | |
185 fprintf(ff.output, "DTSTART;VALUE=DATE-TIME:%s\n", pst_rfc2445_datetime_format(item->journal->start)); | |
186 fprintf(ff.output, "END:VJOURNAL\n\n"); | |
39 | 187 |
43 | 188 } else if (item->appointment && (item->type == PST_TYPE_APPOINTMENT)) { |
189 // deal with Calendar appointments | |
77 | 190 if (mode == MODE_SEPARATE) mk_separate_file(&ff); |
43 | 191 ff.email_count++; |
192 DEBUG_MAIN(("main: Processing Appointment Entry\n")); | |
193 if (ff.type != PST_TYPE_APPOINTMENT) { | |
194 DEBUG_MAIN(("main: I have an appointment, but folder isn't specified as an appointment type. Processing...\n")); | |
195 } | |
196 write_appointment(ff.output, item->appointment, item->email, item->create_date, item->modify_date); | |
39 | 197 |
79
56fa05fd5271
Patch from Robert Simpson for encryption type 2.
Carl Byington <carl@five-ten-sg.com>
parents:
77
diff
changeset
|
198 } else if (item->message_store) { |
56fa05fd5271
Patch from Robert Simpson for encryption type 2.
Carl Byington <carl@five-ten-sg.com>
parents:
77
diff
changeset
|
199 // there should only be one message_store, and we have already done it |
56fa05fd5271
Patch from Robert Simpson for encryption type 2.
Carl Byington <carl@five-ten-sg.com>
parents:
77
diff
changeset
|
200 DEBUG_MAIN(("item with message store content, type %i %s folder type %i, skipping it\n", item->type, item->ascii_type, ff.type)); |
56fa05fd5271
Patch from Robert Simpson for encryption type 2.
Carl Byington <carl@five-ten-sg.com>
parents:
77
diff
changeset
|
201 |
43 | 202 } else { |
63
cfd6175f9334
Start work on pst2dii to convert to Summation dii load file format.
Carl Byington <carl@five-ten-sg.com>
parents:
59
diff
changeset
|
203 // these all seem to be things that MS agrees are not included in the item count |
cfd6175f9334
Start work on pst2dii to convert to Summation dii load file format.
Carl Byington <carl@five-ten-sg.com>
parents:
59
diff
changeset
|
204 //ff.skip_count++; |
cfd6175f9334
Start work on pst2dii to convert to Summation dii load file format.
Carl Byington <carl@five-ten-sg.com>
parents:
59
diff
changeset
|
205 DEBUG_MAIN(("main: Unknown item type %i (%s) name (%s)\n", |
cfd6175f9334
Start work on pst2dii to convert to Summation dii load file format.
Carl Byington <carl@five-ten-sg.com>
parents:
59
diff
changeset
|
206 item->type, item->ascii_type, item->file_as)); |
43 | 207 } |
46 | 208 pst_freeItem(item); |
43 | 209 } else { |
210 ff.skip_count++; | |
211 DEBUG_MAIN(("main: A NULL item was seen\n")); | |
212 } | |
213 d_ptr = d_ptr->next; | |
214 } | |
215 } | |
216 close_enter_dir(&ff); | |
217 DEBUG_RET(); | |
39 | 218 } |
219 | |
220 | |
34
07177825c91b
fix signed/unsigned to allow very small pst files with only leaf nodes
carl
parents:
33
diff
changeset
|
221 |
118
0f1492b7fe8b
patch from Fridrich Strba for building on mingw and general cleanup of autoconf files
Carl Byington <carl@five-ten-sg.com>
parents:
116
diff
changeset
|
222 int main(int argc, char* const* argv) { |
43 | 223 pst_item *item = NULL; |
224 pst_desc_ll *d_ptr; | |
225 char * fname = NULL; | |
48 | 226 char *d_log = NULL; |
43 | 227 int c,x; |
228 char *temp = NULL; //temporary char pointer | |
229 prog_name = argv[0]; | |
16 | 230 |
43 | 231 // command-line option handling |
100
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
232 while ((c = getopt(argc, argv, "bCc:Dd:hko:qrSMVw"))!= -1) { |
43 | 233 switch (c) { |
234 case 'b': | |
235 save_rtf_body = 0; | |
236 break; | |
237 case 'C': | |
238 mode = MODE_DECSPEW; | |
239 break; | |
240 case 'c': | |
241 if (optarg && optarg[0]=='v') | |
242 contact_mode=CMODE_VCARD; | |
243 else if (optarg && optarg[0]=='l') | |
244 contact_mode=CMODE_LIST; | |
245 else { | |
246 usage(); | |
247 exit(0); | |
248 } | |
249 break; | |
100
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
250 case 'D': |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
251 deleted_mode = DMODE_INCLUDE; |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
252 break; |
43 | 253 case 'd': |
254 d_log = optarg; | |
255 break; | |
256 case 'h': | |
257 usage(); | |
258 exit(0); | |
259 break; | |
260 case 'V': | |
261 version(); | |
262 exit(0); | |
263 break; | |
264 case 'k': | |
265 mode = MODE_KMAIL; | |
266 break; | |
267 case 'M': | |
77 | 268 mode = MODE_SEPARATE; |
43 | 269 mode_MH = 1; |
270 break; | |
271 case 'o': | |
272 output_dir = optarg; | |
273 break; | |
274 case 'q': | |
275 output_mode = OUTPUT_QUIET; | |
276 break; | |
277 case 'r': | |
278 mode = MODE_RECURSE; | |
279 break; | |
280 case 'S': | |
77 | 281 mode = MODE_SEPARATE; |
43 | 282 break; |
283 case 'w': | |
284 overwrite = 1; | |
285 break; | |
286 default: | |
287 usage(); | |
288 exit(1); | |
289 break; | |
290 } | |
291 } | |
292 | |
293 if (argc > optind) { | |
294 fname = argv[optind]; | |
295 } else { | |
296 usage(); | |
297 exit(2); | |
298 } | |
299 | |
300 #ifdef DEBUG_ALL | |
301 // force a log file | |
302 if (!d_log) d_log = "readpst.log"; | |
303 #endif // defined DEBUG_ALL | |
304 DEBUG_INIT(d_log); | |
305 DEBUG_REGISTER_CLOSE(); | |
306 DEBUG_ENT("main"); | |
16 | 307 |
43 | 308 if (mode == MODE_DECSPEW) { |
70
b12f4e50e2e8
Patch from Joachim Metz <joachim.metz@gmail.com> for 64 bit compile.
Carl Byington <carl@five-ten-sg.com>
parents:
63
diff
changeset
|
309 FILE *fp; |
b12f4e50e2e8
Patch from Joachim Metz <joachim.metz@gmail.com> for 64 bit compile.
Carl Byington <carl@five-ten-sg.com>
parents:
63
diff
changeset
|
310 char buf[1024]; |
b12f4e50e2e8
Patch from Joachim Metz <joachim.metz@gmail.com> for 64 bit compile.
Carl Byington <carl@five-ten-sg.com>
parents:
63
diff
changeset
|
311 size_t l = 0; |
43 | 312 if (NULL == (fp = fopen(fname, "rb"))) { |
313 fprintf(stderr, "Couldn't open file %s\n", fname ); | |
52 | 314 DEBUG_RET(); |
43 | 315 return 1; |
316 } | |
39 | 317 |
73
3cb02cb1e6cd
Patch from Robert Simpson to fix doubly-linked list in the cache_ptr code, and allow arrays of unicode strings (without converting them).
Carl Byington <carl@five-ten-sg.com>
parents:
70
diff
changeset
|
318 while (0 != (l = fread(buf, 1, 1024, fp))) { |
79
56fa05fd5271
Patch from Robert Simpson for encryption type 2.
Carl Byington <carl@five-ten-sg.com>
parents:
77
diff
changeset
|
319 if (0 != pst_decrypt(0, buf, l, PST_COMP_ENCRYPT)) |
46 | 320 fprintf(stderr, "pst_decrypt() failed (I'll try to continue)\n"); |
16 | 321 |
73
3cb02cb1e6cd
Patch from Robert Simpson to fix doubly-linked list in the cache_ptr code, and allow arrays of unicode strings (without converting them).
Carl Byington <carl@five-ten-sg.com>
parents:
70
diff
changeset
|
322 if (l != pst_fwrite(buf, 1, l, stdout)) { |
43 | 323 fprintf(stderr, "Couldn't output to stdout?\n"); |
52 | 324 DEBUG_RET(); |
43 | 325 return 1; |
326 } | |
327 } | |
52 | 328 DEBUG_RET(); |
43 | 329 return 0; |
330 } | |
16 | 331 |
43 | 332 if (output_mode != OUTPUT_QUIET) printf("Opening PST file and indexes...\n"); |
333 | |
59
7d5c637aaafb
General cleanup and code fixes.
Carl Byington <carl@five-ten-sg.com>
parents:
52
diff
changeset
|
334 RET_DERROR(pst_open(&pstfile, fname), 1, ("Error opening File\n")); |
43 | 335 RET_DERROR(pst_load_index(&pstfile), 2, ("Index Error\n")); |
336 | |
337 pst_load_extended_attributes(&pstfile); | |
16 | 338 |
43 | 339 if (chdir(output_dir)) { |
340 x = errno; | |
341 pst_close(&pstfile); | |
342 DEBUG_RET(); | |
343 DIE(("main: Cannot change to output dir %s: %s\n", output_dir, strerror(x))); | |
344 } | |
345 | |
346 if (output_mode != OUTPUT_QUIET) printf("About to start processing first record...\n"); | |
347 | |
348 d_ptr = pstfile.d_head; // first record is main record | |
46 | 349 item = pst_parse_item(&pstfile, d_ptr); |
43 | 350 if (!item || !item->message_store) { |
351 DEBUG_RET(); | |
352 DIE(("main: Could not get root record\n")); | |
353 } | |
16 | 354 |
43 | 355 // default the file_as to the same as the main filename if it doesn't exist |
356 if (!item->file_as) { | |
357 if (!(temp = strrchr(fname, '/'))) | |
358 if (!(temp = strrchr(fname, '\\'))) | |
359 temp = fname; | |
360 else | |
361 temp++; // get past the "\\" | |
362 else | |
363 temp++; // get past the "/" | |
364 item->file_as = (char*)xmalloc(strlen(temp)+1); | |
365 strcpy(item->file_as, temp); | |
366 DEBUG_MAIN(("file_as was blank, so am using %s\n", item->file_as)); | |
367 } | |
368 DEBUG_MAIN(("main: Root Folder Name: %s\n", item->file_as)); | |
16 | 369 |
43 | 370 d_ptr = pst_getTopOfFolders(&pstfile, item); |
371 if (!d_ptr) { | |
372 DEBUG_RET(); | |
373 DIE(("Top of folders record not found. Cannot continue\n")); | |
374 } | |
16 | 375 |
63
cfd6175f9334
Start work on pst2dii to convert to Summation dii load file format.
Carl Byington <carl@five-ten-sg.com>
parents:
59
diff
changeset
|
376 process(item, d_ptr->child); // do the children of TOPF |
46 | 377 pst_freeItem(item); |
43 | 378 pst_close(&pstfile); |
379 DEBUG_RET(); | |
380 return 0; | |
16 | 381 } |
31 | 382 |
383 | |
16 | 384 void write_email_body(FILE *f, char *body) { |
43 | 385 char *n = body; |
386 // DEBUG_MAIN(("write_email_body(): \"%s\"\n", body)); | |
387 DEBUG_ENT("write_email_body"); | |
388 while (n) { | |
389 if (strncmp(body, "From ", 5) == 0) | |
390 fprintf(f, ">"); | |
391 if ((n = strchr(body, '\n'))) { | |
392 n++; | |
73
3cb02cb1e6cd
Patch from Robert Simpson to fix doubly-linked list in the cache_ptr code, and allow arrays of unicode strings (without converting them).
Carl Byington <carl@five-ten-sg.com>
parents:
70
diff
changeset
|
393 pst_fwrite(body, n-body, 1, f); //write just a line |
43 | 394 body = n; |
395 } | |
396 } | |
73
3cb02cb1e6cd
Patch from Robert Simpson to fix doubly-linked list in the cache_ptr code, and allow arrays of unicode strings (without converting them).
Carl Byington <carl@five-ten-sg.com>
parents:
70
diff
changeset
|
397 pst_fwrite(body, strlen(body), 1, f); |
43 | 398 DEBUG_RET(); |
16 | 399 } |
31 | 400 |
401 | |
16 | 402 char *removeCR (char *c) { |
43 | 403 // converts /r/n to /n |
404 char *a, *b; | |
405 DEBUG_ENT("removeCR"); | |
406 a = b = c; | |
407 while (*a != '\0') { | |
408 *b = *a; | |
409 if (*a != '\r') | |
410 b++; | |
411 a++; | |
412 } | |
413 *b = '\0'; | |
414 DEBUG_RET(); | |
415 return c; | |
16 | 416 } |
31 | 417 |
418 | |
118
0f1492b7fe8b
patch from Fridrich Strba for building on mingw and general cleanup of autoconf files
Carl Byington <carl@five-ten-sg.com>
parents:
116
diff
changeset
|
419 void usage() { |
43 | 420 DEBUG_ENT("usage"); |
421 version(); | |
422 printf("Usage: %s [OPTIONS] {PST FILENAME}\n", prog_name); | |
423 printf("OPTIONS:\n"); | |
104
39ba19372732
many fixes in pst2ldif by Robert Harris
Carl Byington <carl@five-ten-sg.com>
parents:
100
diff
changeset
|
424 printf("\t-V\t- Version. Display program version\n"); |
79
56fa05fd5271
Patch from Robert Simpson for encryption type 2.
Carl Byington <carl@five-ten-sg.com>
parents:
77
diff
changeset
|
425 printf("\t-C\t- Decrypt (compressible encryption) the entire file and output on stdout (not typically useful)\n"); |
100
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
426 printf("\t-D\t- Include deleted items in output\n"); |
63
cfd6175f9334
Start work on pst2dii to convert to Summation dii load file format.
Carl Byington <carl@five-ten-sg.com>
parents:
59
diff
changeset
|
427 printf("\t-M\t- MH. Write emails in the MH format\n"); |
77 | 428 printf("\t-S\t- Separate. Write emails in the separate format\n"); |
43 | 429 printf("\t-b\t- Don't save RTF-Body attachments\n"); |
430 printf("\t-c[v|l]\t- Set the Contact output mode. -cv = VCard, -cl = EMail list\n"); | |
63
cfd6175f9334
Start work on pst2dii to convert to Summation dii load file format.
Carl Byington <carl@five-ten-sg.com>
parents:
59
diff
changeset
|
431 printf("\t-d <filename> \t- Debug to file. This is a binary log. Use readpstlog to print it\n"); |
43 | 432 printf("\t-h\t- Help. This screen\n"); |
433 printf("\t-k\t- KMail. Output in kmail format\n"); | |
63
cfd6175f9334
Start work on pst2dii to convert to Summation dii load file format.
Carl Byington <carl@five-ten-sg.com>
parents:
59
diff
changeset
|
434 printf("\t-o <dirname>\t- Output directory to write files to. CWD is changed *after* opening pst file\n"); |
43 | 435 printf("\t-q\t- Quiet. Only print error messages\n"); |
436 printf("\t-r\t- Recursive. Output in a recursive format\n"); | |
437 printf("\t-w\t- Overwrite any output mbox files\n"); | |
438 DEBUG_RET(); | |
16 | 439 } |
31 | 440 |
441 | |
118
0f1492b7fe8b
patch from Fridrich Strba for building on mingw and general cleanup of autoconf files
Carl Byington <carl@five-ten-sg.com>
parents:
116
diff
changeset
|
442 void version() { |
43 | 443 DEBUG_ENT("version"); |
50 | 444 printf("ReadPST / LibPST v%s\n", VERSION); |
16 | 445 #if BYTE_ORDER == BIG_ENDIAN |
43 | 446 printf("Big Endian implementation being used.\n"); |
16 | 447 #elif BYTE_ORDER == LITTLE_ENDIAN |
43 | 448 printf("Little Endian implementation being used.\n"); |
16 | 449 #else |
450 # error "Byte order not supported by this library" | |
451 #endif | |
452 #ifdef __GNUC__ | |
43 | 453 printf("GCC %d.%d : %s %s\n", __GNUC__, __GNUC_MINOR__, __DATE__, __TIME__); |
16 | 454 #endif |
43 | 455 DEBUG_RET(); |
16 | 456 } |
31 | 457 |
458 | |
16 | 459 char *mk_kmail_dir(char *fname) { |
43 | 460 //change to that directory |
461 //make a directory based on OUTPUT_KMAIL_DIR_TEMPLATE | |
462 //allocate space for OUTPUT_TEMPLATE and form a char* with fname | |
463 //return that value | |
464 char *dir, *out_name, *index; | |
465 int x; | |
466 DEBUG_ENT("mk_kmail_dir"); | |
467 if (kmail_chdir && chdir(kmail_chdir)) { | |
468 x = errno; | |
469 DIE(("mk_kmail_dir: Cannot change to directory %s: %s\n", kmail_chdir, strerror(x))); | |
470 } | |
471 dir = malloc(strlen(fname)+strlen(OUTPUT_KMAIL_DIR_TEMPLATE)+1); | |
472 sprintf(dir, OUTPUT_KMAIL_DIR_TEMPLATE, fname); | |
473 check_filename(dir); | |
474 if (D_MKDIR(dir)) { | |
475 //error occured | |
476 if (errno != EEXIST) { | |
477 x = errno; | |
478 DIE(("mk_kmail_dir: Cannot create directory %s: %s\n", dir, strerror(x))); | |
479 } | |
480 } | |
481 kmail_chdir = realloc(kmail_chdir, strlen(dir)+1); | |
482 strcpy(kmail_chdir, dir); | |
483 free (dir); | |
16 | 484 |
43 | 485 //we should remove any existing indexes created by KMail, cause they might be different now |
486 index = malloc(strlen(fname)+strlen(KMAIL_INDEX)+1); | |
487 sprintf(index, KMAIL_INDEX, fname); | |
488 unlink(index); | |
489 free(index); | |
16 | 490 |
43 | 491 out_name = malloc(strlen(fname)+strlen(OUTPUT_TEMPLATE)+1); |
492 sprintf(out_name, OUTPUT_TEMPLATE, fname); | |
493 DEBUG_RET(); | |
494 return out_name; | |
16 | 495 } |
31 | 496 |
497 | |
16 | 498 int close_kmail_dir() { |
43 | 499 // change .. |
500 int x; | |
501 DEBUG_ENT("close_kmail_dir"); | |
502 if (kmail_chdir) { //only free kmail_chdir if not NULL. do not change directory | |
503 free(kmail_chdir); | |
504 kmail_chdir = NULL; | |
505 } else { | |
506 if (chdir("..")) { | |
507 x = errno; | |
508 DIE(("close_kmail_dir: Cannot move up dir (..): %s\n", strerror(x))); | |
509 } | |
510 } | |
511 DEBUG_RET(); | |
512 return 0; | |
16 | 513 } |
31 | 514 |
515 | |
16 | 516 // this will create a directory by that name, then make an mbox file inside |
517 // that dir. any subsequent dirs will be created by name, and they will | |
518 // contain mbox files | |
519 char *mk_recurse_dir(char *dir) { | |
43 | 520 int x; |
521 char *out_name; | |
522 DEBUG_ENT("mk_recurse_dir"); | |
523 check_filename(dir); | |
524 if (D_MKDIR (dir)) { | |
525 if (errno != EEXIST) { // not an error because it exists | |
526 x = errno; | |
527 DIE(("mk_recurse_dir: Cannot create directory %s: %s\n", dir, strerror(x))); | |
528 } | |
529 } | |
530 if (chdir (dir)) { | |
531 x = errno; | |
532 DIE(("mk_recurse_dir: Cannot change to directory %s: %s\n", dir, strerror(x))); | |
533 } | |
534 out_name = malloc(strlen("mbox")+1); | |
535 strcpy(out_name, "mbox"); | |
536 DEBUG_RET(); | |
537 return out_name; | |
16 | 538 } |
31 | 539 |
540 | |
16 | 541 int close_recurse_dir() { |
43 | 542 int x; |
543 DEBUG_ENT("close_recurse_dir"); | |
544 if (chdir("..")) { | |
545 x = errno; | |
546 DIE(("close_recurse_dir: Cannot go up dir (..): %s\n", strerror(x))); | |
547 } | |
548 DEBUG_RET(); | |
549 return 0; | |
16 | 550 } |
31 | 551 |
552 | |
77 | 553 char *mk_separate_dir(char *dir) { |
43 | 554 size_t dirsize = strlen(dir) + 10; |
555 char dir_name[dirsize]; | |
556 int x = 0, y = 0; | |
16 | 557 |
77 | 558 DEBUG_ENT("mk_separate_dir"); |
43 | 559 do { |
560 if (y == 0) | |
561 snprintf(dir_name, dirsize, "%s", dir); | |
562 else | |
563 snprintf(dir_name, dirsize, "%s" SEP_MAIL_FILE_TEMPLATE, dir, y); // enough for 9 digits allocated above | |
16 | 564 |
43 | 565 check_filename(dir_name); |
566 DEBUG_MAIN(("about to try creating %s\n", dir_name)); | |
567 if (D_MKDIR(dir_name)) { | |
568 if (errno != EEXIST) { // if there is an error, and it doesn't already exist | |
569 x = errno; | |
77 | 570 DIE(("mk_separate_dir: Cannot create directory %s: %s\n", dir, strerror(x))); |
43 | 571 } |
572 } else { | |
573 break; | |
574 } | |
575 y++; | |
576 } while (overwrite == 0); | |
16 | 577 |
43 | 578 if (chdir(dir_name)) { |
579 x = errno; | |
77 | 580 DIE(("mk_separate_dir: Cannot change to directory %s: %s\n", dir, strerror(x))); |
43 | 581 } |
16 | 582 |
43 | 583 if (overwrite) { |
584 // we should probably delete all files from this directory | |
16 | 585 #if !defined(WIN32) && !defined(__CYGWIN__) |
43 | 586 DIR * sdir = NULL; |
587 struct dirent *dirent = NULL; | |
588 struct stat filestat; | |
589 if (!(sdir = opendir("./"))) { | |
77 | 590 WARN(("mk_separate_dir: Cannot open dir \"%s\" for deletion of old contents\n", "./")); |
43 | 591 } else { |
592 while ((dirent = readdir(sdir))) { | |
593 if (lstat(dirent->d_name, &filestat) != -1) | |
594 if (S_ISREG(filestat.st_mode)) { | |
595 if (unlink(dirent->d_name)) { | |
596 y = errno; | |
77 | 597 DIE(("mk_separate_dir: unlink returned error on file %s: %s\n", dirent->d_name, strerror(y))); |
43 | 598 } |
599 } | |
600 } | |
601 } | |
26 | 602 #endif |
43 | 603 } |
16 | 604 |
43 | 605 // we don't return a filename here cause it isn't necessary. |
606 DEBUG_RET(); | |
607 return NULL; | |
16 | 608 } |
31 | 609 |
610 | |
77 | 611 int close_separate_dir() { |
43 | 612 int x; |
77 | 613 DEBUG_ENT("close_separate_dir"); |
43 | 614 if (chdir("..")) { |
615 x = errno; | |
77 | 616 DIE(("close_separate_dir: Cannot go up dir (..): %s\n", strerror(x))); |
43 | 617 } |
618 DEBUG_RET(); | |
619 return 0; | |
16 | 620 } |
31 | 621 |
622 | |
77 | 623 int mk_separate_file(struct file_ll *f) { |
43 | 624 const int name_offset = 1; |
77 | 625 DEBUG_ENT("mk_separate_file"); |
43 | 626 DEBUG_MAIN(("opening next file to save email\n")); |
627 if (f->email_count > 999999999) { // bigger than nine 9's | |
77 | 628 DIE(("mk_separate_file: The number of emails in this folder has become too high to handle")); |
43 | 629 } |
630 sprintf(f->name, SEP_MAIL_FILE_TEMPLATE, f->email_count + name_offset); | |
631 if (f->output) fclose(f->output); | |
632 f->output = NULL; | |
633 check_filename(f->name); | |
634 if (!(f->output = fopen(f->name, "w"))) { | |
77 | 635 DIE(("mk_separate_file: Cannot open file to save email \"%s\"\n", f->name)); |
43 | 636 } |
637 DEBUG_RET(); | |
638 return 0; | |
16 | 639 } |
31 | 640 |
641 | |
16 | 642 char *my_stristr(char *haystack, char *needle) { |
43 | 643 // my_stristr varies from strstr in that its searches are case-insensitive |
644 char *x=haystack, *y=needle, *z = NULL; | |
645 DEBUG_ENT("my_stristr"); | |
52 | 646 if (!haystack || !needle) { |
647 DEBUG_RET(); | |
43 | 648 return NULL; |
52 | 649 } |
43 | 650 while (*y != '\0' && *x != '\0') { |
651 if (tolower(*y) == tolower(*x)) { | |
652 // move y on one | |
653 y++; | |
654 if (!z) { | |
655 z = x; // store first position in haystack where a match is made | |
656 } | |
657 } else { | |
658 y = needle; // reset y to the beginning of the needle | |
659 z = NULL; // reset the haystack storage point | |
660 } | |
661 x++; // advance the search in the haystack | |
662 } | |
663 DEBUG_RET(); | |
100
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
664 // If the haystack ended before our search finished, it's not a match. |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
665 if (*y != '\0') return NULL; |
43 | 666 return z; |
16 | 667 } |
31 | 668 |
669 | |
41
183ae993b9ad
security fix for potential buffer overrun in lz decompress
carl
parents:
39
diff
changeset
|
670 void check_filename(char *fname) { |
43 | 671 char *t = fname; |
672 DEBUG_ENT("check_filename"); | |
673 if (!t) { | |
674 DEBUG_RET(); | |
52 | 675 return; |
43 | 676 } |
677 while ((t = strpbrk(t, "/\\:"))) { | |
678 // while there are characters in the second string that we don't want | |
679 *t = '_'; //replace them with an underscore | |
680 } | |
681 DEBUG_RET(); | |
16 | 682 } |
31 | 683 |
684 | |
16 | 685 // The sole purpose of this function is to bypass the pseudo-header prologue |
686 // that Microsoft Outlook inserts at the beginning of the internet email | |
687 // headers for emails stored in their "Personal Folders" files. | |
688 char *skip_header_prologue(char *headers) { | |
43 | 689 const char *bad = "Microsoft Mail Internet Headers"; |
73
3cb02cb1e6cd
Patch from Robert Simpson to fix doubly-linked list in the cache_ptr code, and allow arrays of unicode strings (without converting them).
Carl Byington <carl@five-ten-sg.com>
parents:
70
diff
changeset
|
690 if (strncmp(headers, bad, strlen(bad)) == 0) { |
43 | 691 // Found the offensive header prologue |
692 char *pc = strchr(headers, '\n'); | |
693 return pc + 1; | |
694 } | |
695 return headers; | |
16 | 696 } |
697 | |
31 | 698 |
25 | 699 void write_separate_attachment(char f_name[], pst_item_attach* current_attach, int attach_num, pst_file* pst) |
700 { | |
43 | 701 FILE *fp = NULL; |
702 int x = 0; | |
703 char *temp = NULL; | |
31 | 704 |
43 | 705 // If there is a long filename (filename2) use that, otherwise |
706 // use the 8.3 filename (filename1) | |
707 char *attach_filename = (current_attach->filename2) ? current_attach->filename2 | |
708 : current_attach->filename1; | |
46 | 709 DEBUG_ENT("write_separate_attachment"); |
25 | 710 |
43 | 711 check_filename(f_name); |
712 if (!attach_filename) { | |
713 // generate our own (dummy) filename for the attachement | |
714 temp = xmalloc(strlen(f_name)+15); | |
715 sprintf(temp, "%s-attach%i", f_name, attach_num); | |
716 } else { | |
717 // have an attachment name, make sure it's unique | |
718 temp = xmalloc(strlen(f_name)+strlen(attach_filename)+15); | |
719 do { | |
720 if (fp) fclose(fp); | |
721 if (x == 0) | |
722 sprintf(temp, "%s-%s", f_name, attach_filename); | |
723 else | |
724 sprintf(temp, "%s-%s-%i", f_name, attach_filename, x); | |
725 } while ((fp = fopen(temp, "r")) && ++x < 99999999); | |
726 if (x > 99999999) { | |
727 DIE(("error finding attachment name. exhausted possibilities to %s\n", temp)); | |
728 } | |
729 } | |
730 DEBUG_EMAIL(("Saving attachment to %s\n", temp)); | |
731 if (!(fp = fopen(temp, "w"))) { | |
732 WARN(("write_separate_attachment: Cannot open attachment save file \"%s\"\n", temp)); | |
733 } else { | |
734 if (current_attach->data) | |
73
3cb02cb1e6cd
Patch from Robert Simpson to fix doubly-linked list in the cache_ptr code, and allow arrays of unicode strings (without converting them).
Carl Byington <carl@five-ten-sg.com>
parents:
70
diff
changeset
|
735 pst_fwrite(current_attach->data, 1, current_attach->size, fp); |
43 | 736 else { |
46 | 737 (void)pst_attach_to_file(pst, current_attach, fp); |
43 | 738 } |
739 fclose(fp); | |
740 } | |
741 if (temp) free(temp); | |
742 DEBUG_RET(); | |
25 | 743 } |
744 | |
31 | 745 |
25 | 746 void write_inline_attachment(FILE* f_output, pst_item_attach* current_attach, char boundary[], pst_file* pst) |
747 { | |
46 | 748 char *enc = NULL; // base64 encoded attachment |
43 | 749 DEBUG_ENT("write_inline_attachment"); |
750 DEBUG_EMAIL(("Attachment Size is %i\n", current_attach->size)); | |
751 DEBUG_EMAIL(("Attachment Pointer is %p\n", current_attach->data)); | |
752 if (current_attach->data) { | |
753 enc = base64_encode (current_attach->data, current_attach->size); | |
754 if (!enc) { | |
755 DEBUG_EMAIL(("ERROR base64_encode returned NULL. Must have failed\n")); | |
52 | 756 DEBUG_RET(); |
43 | 757 return; |
758 } | |
759 } | |
760 if (boundary) { | |
761 char *attach_filename; | |
762 fprintf(f_output, "\n--%s\n", boundary); | |
763 if (!current_attach->mimetype) { | |
116
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
764 fprintf(f_output, "Content-Type: %s\n", MIME_TYPE_DEFAULT); |
43 | 765 } else { |
116
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
766 fprintf(f_output, "Content-Type: %s\n", current_attach->mimetype); |
43 | 767 } |
116
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
768 fprintf(f_output, "Content-Transfer-Encoding: base64\n"); |
43 | 769 // If there is a long filename (filename2) use that, otherwise |
770 // use the 8.3 filename (filename1) | |
771 if (current_attach->filename2) { | |
48 | 772 attach_filename = current_attach->filename2; |
43 | 773 } else { |
48 | 774 attach_filename = current_attach->filename1; |
43 | 775 } |
776 if (!attach_filename) { | |
777 fprintf(f_output, "Content-Disposition: inline\n\n"); | |
778 } else { | |
779 fprintf(f_output, "Content-Disposition: attachment; filename=\"%s\"\n\n", attach_filename); | |
780 } | |
781 } | |
782 if (current_attach->data) { | |
73
3cb02cb1e6cd
Patch from Robert Simpson to fix doubly-linked list in the cache_ptr code, and allow arrays of unicode strings (without converting them).
Carl Byington <carl@five-ten-sg.com>
parents:
70
diff
changeset
|
783 pst_fwrite(enc, 1, strlen(enc), f_output); |
43 | 784 DEBUG_EMAIL(("Attachment Size after encoding is %i\n", strlen(enc))); |
785 free(enc); // caught by valgrind | |
786 } else { | |
46 | 787 (void)pst_attach_to_file_base64(pst, current_attach, f_output); |
43 | 788 } |
789 fprintf(f_output, "\n\n"); | |
790 DEBUG_RET(); | |
25 | 791 } |
792 | |
31 | 793 |
794 void write_normal_email(FILE* f_output, char f_name[], pst_item* item, int mode, int mode_MH, pst_file* pst, int save_rtf) | |
25 | 795 { |
43 | 796 char *boundary = NULL; // the boundary marker between multipart sections |
797 int boundary_created = 0; // we have not (yet) created a new boundary | |
798 char *temp = NULL; | |
799 int attach_num, base64_body = 0; | |
800 time_t em_time; | |
801 char *c_time; | |
802 pst_item_attach* current_attach; | |
100
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
803 int has_from, has_subject, has_to, has_cc, has_bcc, has_date; |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
804 has_from = has_subject = has_to = has_cc = has_bcc = has_date = 0; |
46 | 805 DEBUG_ENT("write_normal_email"); |
25 | 806 |
43 | 807 // convert the sent date if it exists, or set it to a fixed date |
808 if (item->email->sent_date) { | |
809 em_time = fileTimeToUnixTime(item->email->sent_date, 0); | |
810 c_time = ctime(&em_time); | |
811 if (c_time) | |
812 c_time[strlen(c_time)-1] = '\0'; //remove end \n | |
813 else | |
814 c_time = "Fri Dec 28 12:06:21 2001"; | |
815 } else | |
816 c_time= "Fri Dec 28 12:06:21 2001"; | |
25 | 817 |
43 | 818 // we will always look at the header to discover some stuff |
819 if (item->email->header ) { | |
820 char *b1, *b2; | |
821 // see if there is a boundary variable there | |
822 // this search MUST be made case insensitive (DONE). | |
823 // Also, we should check to find out if we are looking | |
116
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
824 // at the boundary associated with Content-Type, and that |
43 | 825 // the content type really is multipart |
25 | 826 |
43 | 827 removeCR(item->email->header); |
25 | 828 |
43 | 829 if ((b2 = my_stristr(item->email->header, "boundary="))) { |
830 int len; | |
831 b2 += strlen("boundary="); // move boundary to first char of marker | |
31 | 832 |
43 | 833 if (*b2 == '"') { |
834 b2++; | |
835 b1 = strchr(b2, '"'); // find terminating quote | |
836 } else { | |
837 b1 = b2; | |
838 while (isgraph(*b1)) // find first char that isn't part of boundary | |
839 b1++; | |
840 } | |
841 len = b1 - b2; | |
842 boundary = malloc(len+1); //malloc that length | |
843 strncpy(boundary, b2, len); // copy boundary to another variable | |
844 boundary[len] = '\0'; | |
845 b1 = b2 = boundary; | |
846 while (*b2 != '\0') { // remove any CRs and Tabs | |
847 if (*b2 != '\n' && *b2 != '\r' && *b2 != '\t') { | |
848 *b1 = *b2; | |
849 b1++; | |
850 } | |
851 b2++; | |
852 } | |
853 *b1 = '\0'; | |
31 | 854 |
43 | 855 DEBUG_EMAIL(("Found boundary of - %s\n", boundary)); |
856 } else { | |
857 DEBUG_EMAIL(("boundary not found in header\n")); | |
858 } | |
25 | 859 |
43 | 860 // also possible to set 7bit encoding detection here. |
861 if ((b2 = my_stristr(item->email->header, "Content-Transfer-Encoding:"))) { | |
862 if ((b2 = strchr(b2, ':'))) { | |
863 b2++; // skip to the : at the end of the string | |
31 | 864 |
43 | 865 while (*b2 == ' ' || *b2 == '\t') |
866 b2++; | |
867 if (pst_strincmp(b2, "base64", 6)==0) { | |
868 DEBUG_EMAIL(("body is base64 encoded\n")); | |
869 base64_body = 1; | |
870 } | |
871 } else { | |
872 DEBUG_WARN(("found a ':' during the my_stristr, but not after that..\n")); | |
873 } | |
874 } | |
100
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
875 |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
876 // Check if the header block has all the necessary headers. |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
877 if (my_stristr(item->email->header, "\nFrom:") || (strncasecmp(item->email->header, "From: ", 6) == 0) || my_stristr(item->email->header, "\nX-From:")) { |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
878 DEBUG_EMAIL(("header block has From header\n")); |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
879 has_from = 1; |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
880 } |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
881 if (my_stristr(item->email->header, "\nTo:") || (strncasecmp(item->email->header, "To: ", 4) == 0)) { |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
882 DEBUG_EMAIL(("header block has To header\n")); |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
883 has_to = 1; |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
884 } |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
885 if (my_stristr(item->email->header, "\nSubject:") || (strncasecmp(item->email->header, "Subject: ", 9) == 0)) { |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
886 DEBUG_EMAIL(("header block has Subject header\n")); |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
887 has_subject = 1; |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
888 } |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
889 if (my_stristr(item->email->header, "\nDate:") || (strncasecmp(item->email->header, "Date: ", 6) == 0)) { |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
890 DEBUG_EMAIL(("header block has Date header\n")); |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
891 has_date = 1; |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
892 } |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
893 if (my_stristr(item->email->header, "\nCC:") || (strncasecmp(item->email->header, "CC: ", 4) == 0)) { |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
894 DEBUG_EMAIL(("header block has CC header\n")); |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
895 has_cc = 1; |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
896 } |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
897 if (my_stristr(item->email->header, "\nBCC:") || (strncasecmp(item->email->header, "BCC: ", 5) == 0)) { |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
898 DEBUG_EMAIL(("header block has BCC header\n")); |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
899 has_bcc = 1; |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
900 } |
43 | 901 } |
25 | 902 |
43 | 903 if (!boundary && (item->attach || (item->email->body && item->email->htmlbody) |
904 || item->email->rtf_compressed || item->email->encrypted_body | |
905 || item->email->encrypted_htmlbody)) { | |
100
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
906 // we need to create a boundary here. |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
907 DEBUG_EMAIL(("must create own boundary. oh dear.\n")); |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
908 boundary = malloc(50 * sizeof(char)); // allow 50 chars for boundary |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
909 boundary[0] = '\0'; |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
910 sprintf(boundary, "--boundary-LibPST-iamunique-%i_-_-", rand()); |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
911 DEBUG_EMAIL(("created boundary is %s\n", boundary)); |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
912 boundary_created = 1; |
43 | 913 } |
25 | 914 |
43 | 915 DEBUG_EMAIL(("About to print Header\n")); |
31 | 916 |
43 | 917 if (item && item->email && item->email->subject && item->email->subject->subj) { |
918 DEBUG_EMAIL(("item->email->subject->subj = %s\n", item->email->subject->subj)); | |
919 } | |
31 | 920 |
43 | 921 if (item->email->header) { |
922 int len; | |
923 char *soh = NULL; // real start of headers. | |
31 | 924 |
43 | 925 // some of the headers we get from the file are not properly defined. |
926 // they can contain some email stuff too. We will cut off the header | |
927 // when we see a \n\n or \r\n\r\n | |
928 removeCR(item->email->header); | |
929 temp = strstr(item->email->header, "\n\n"); | |
25 | 930 |
43 | 931 if (temp) { |
932 DEBUG_EMAIL(("Found body text in header\n")); | |
933 temp[1] = '\0'; // stop after first \n | |
934 } | |
31 | 935 |
100
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
936 // Write out any fields that weren't included in the header. |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
937 if (!has_from) { |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
938 temp = item->email->outlook_sender; |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
939 if (!temp) temp = ""; |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
940 fprintf(f_output, "From: \"%s\" <%s>\n", item->email->outlook_sender_name, temp); |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
941 } |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
942 |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
943 if (!has_subject) { |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
944 if (item->email->subject && item->email->subject->subj) { |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
945 fprintf(f_output, "Subject: %s\n", item->email->subject->subj); |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
946 } else { |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
947 fprintf(f_output, "Subject: \n"); |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
948 } |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
949 } |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
950 |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
951 if (!has_to && item->email->sentto_address) { |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
952 fprintf(f_output, "To: %s\n", item->email->sentto_address); |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
953 } |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
954 |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
955 if (!has_cc && item->email->cc_address) { |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
956 fprintf(f_output, "Cc: %s\n", item->email->cc_address); |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
957 } |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
958 |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
959 if (!has_bcc && item->email->bcc_address) { |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
960 fprintf(f_output, "Bcc: %s\n", item->email->bcc_address); |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
961 } |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
962 |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
963 if (!has_date && item->email->sent_date) { |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
964 char c_time[C_TIME_SIZE]; |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
965 strftime(c_time, C_TIME_SIZE, "%a, %d %b %Y %H:%M:%S %z", gmtime(&em_time)); |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
966 fprintf(f_output, "Date: %s\n", c_time); |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
967 } |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
968 |
43 | 969 // Now, write out the header... |
970 soh = skip_header_prologue(item->email->header); | |
77 | 971 if (mode != MODE_SEPARATE) { |
972 // don't put rubbish in if we are doing separate | |
43 | 973 if (strncmp(soh, "X-From_: ", 9) == 0 ) { |
974 fputs("From ", f_output); | |
975 soh += 9; | |
976 } else | |
977 fprintf(f_output, "From \"%s\" %s\n", item->email->outlook_sender_name, c_time); | |
978 } | |
979 fprintf(f_output, "%s", soh); | |
980 len = strlen(soh); | |
981 if (!len || (soh[len-1] != '\n')) fprintf(f_output, "\n"); | |
31 | 982 |
43 | 983 } else { |
63
cfd6175f9334
Start work on pst2dii to convert to Summation dii load file format.
Carl Byington <carl@five-ten-sg.com>
parents:
59
diff
changeset
|
984 //make up our own headers |
77 | 985 if (mode != MODE_SEPARATE) { |
43 | 986 // don't want this first line for this mode |
987 if (item->email->outlook_sender_name) { | |
988 temp = item->email->outlook_sender_name; | |
989 } else { | |
990 temp = "(readpst_null)"; | |
991 } | |
992 fprintf(f_output, "From \"%s\" %s\n", temp, c_time); | |
993 } | |
31 | 994 |
43 | 995 temp = item->email->outlook_sender; |
996 if (!temp) temp = ""; | |
997 fprintf(f_output, "From: \"%s\" <%s>\n", item->email->outlook_sender_name, temp); | |
31 | 998 |
100
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
999 if (item->email->subject && item->email->subject->subj) { |
43 | 1000 fprintf(f_output, "Subject: %s\n", item->email->subject->subj); |
1001 } else { | |
1002 fprintf(f_output, "Subject: \n"); | |
1003 } | |
31 | 1004 |
100
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
1005 if (item->email->sentto_address) { |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
1006 fprintf(f_output, "To: %s\n", item->email->sentto_address); |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
1007 } |
1e4a7610d525
fixes from Justin Greer to add -D option to include deleted items, to add missing email headers, to fix bug in my_stristr()
Carl Byington <carl@five-ten-sg.com>
parents:
79
diff
changeset
|
1008 |
43 | 1009 if (item->email->cc_address) { |
1010 fprintf(f_output, "Cc: %s\n", item->email->cc_address); | |
1011 } | |
31 | 1012 |
43 | 1013 if (item->email->sent_date) { |
63
cfd6175f9334
Start work on pst2dii to convert to Summation dii load file format.
Carl Byington <carl@five-ten-sg.com>
parents:
59
diff
changeset
|
1014 char c_time[C_TIME_SIZE]; |
43 | 1015 strftime(c_time, C_TIME_SIZE, "%a, %d %b %Y %H:%M:%S %z", gmtime(&em_time)); |
1016 fprintf(f_output, "Date: %s\n", c_time); | |
1017 } | |
1018 } | |
25 | 1019 |
43 | 1020 fprintf(f_output, "MIME-Version: 1.0\n"); |
1021 if (boundary && boundary_created) { | |
1022 // if we created the boundary, then it has NOT already been printed | |
1023 // in the headers above. | |
1024 if (item->attach) { | |
1025 // write the boundary stuff if we have attachments | |
116
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1026 fprintf(f_output, "Content-Type: multipart/mixed;\n\tboundary=\"%s\"\n", boundary); |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1027 } else { |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1028 // else we have multipart/alternative then tell it so |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1029 fprintf(f_output, "Content-Type: multipart/alternative;\n\tboundary=\"%s\"\n", boundary); |
43 | 1030 } |
1031 } | |
1032 fprintf(f_output, "\n"); // start the body | |
1033 DEBUG_EMAIL(("About to print Body\n")); | |
25 | 1034 |
43 | 1035 if (item->email->body) { |
1036 if (boundary) { | |
116
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1037 // try to find the charset for this body part |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1038 const char *def = "utf-8"; |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1039 // it seems that if (item->email->body_charset) is set, then |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1040 // we actually have utf8 plain body text. If that is not set |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1041 // we have plain body text in an 8 bit charset specified in |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1042 // the headers. |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1043 char *c = my_stristr(item->email->header, "\nContent-Type:"); |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1044 if (c) { |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1045 c++; |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1046 char *n = my_stristr(c, "\n"); // termination on the content type |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1047 if (n) { |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1048 char *s = my_stristr(c, "; charset="); |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1049 if (s && (s < n)) { |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1050 char *e; |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1051 s += 10; // skip over charset= |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1052 if (*s == '"') { |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1053 s++; |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1054 e = my_stristr(s, "\""); |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1055 } |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1056 else { |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1057 e = my_stristr(s, ";"); |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1058 } |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1059 if (!e || (e > n)) e = n; // use the trailing lf as terminator if nothing better |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1060 *e = '\0'; // corrupt the header, but we have already printed it |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1061 def = s; |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1062 DEBUG_EMAIL(("body charset %s from headers\n", def)); |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1063 } |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1064 } |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1065 } |
43 | 1066 fprintf(f_output, "\n--%s\n", boundary); |
116
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1067 fprintf(f_output, "Content-Type: text/plain; charset=\"%s\"\n", def); |
43 | 1068 if (base64_body) |
1069 fprintf(f_output, "Content-Transfer-Encoding: base64\n"); | |
1070 fprintf(f_output, "\n"); | |
1071 } | |
116
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1072 else if (item->email->body_charset && (strcasecmp("utf-8",item->email->body_charset))) { |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1073 // try to convert to the specified charset since it is not utf-8 |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1074 size_t rc; |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1075 DEBUG_EMAIL(("Convert plain text utf-8 to %s\n", item->email->body_charset)); |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1076 vbuf *newer = vballoc(2); |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1077 rc = vb_utf8to8bit(newer, item->email->body, strlen(item->email->body) + 1, item->email->body_charset); |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1078 if (rc == (size_t)-1) { |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1079 free(newer->b); |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1080 DEBUG_EMAIL(("Failed to convert plain text utf-8 to %s\n", item->email->body_charset)); |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1081 } |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1082 else { |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1083 free(item->email->body); |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1084 item->email->body = newer->b; |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1085 } |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1086 free(newer); |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1087 } |
43 | 1088 removeCR(item->email->body); |
1089 if (base64_body) { | |
1090 char *enc = base64_encode(item->email->body, strlen(item->email->body)); | |
1091 if (enc) { | |
1092 write_email_body(f_output, enc); | |
1093 free(enc); | |
1094 } | |
1095 } | |
1096 else { | |
1097 write_email_body(f_output, item->email->body); | |
1098 } | |
1099 } | |
31 | 1100 |
43 | 1101 if (item->email->htmlbody) { |
1102 if (boundary) { | |
116
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1103 const char *def = "utf-8"; |
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1104 if (item->email->body_charset) def = item->email->body_charset; |
43 | 1105 fprintf(f_output, "\n--%s\n", boundary); |
116
ed2a260bbb98
improve handling of content-type charset values in mime parts
Carl Byington <carl@five-ten-sg.com>
parents:
110
diff
changeset
|
1106 fprintf(f_output, "Content-Type: text/html; charset=\"%s\"\n", def); |
43 | 1107 if (base64_body) fprintf(f_output, "Content-Transfer-Encoding: base64\n"); |
1108 fprintf(f_output, "\n"); | |
1109 } | |
1110 removeCR(item->email->htmlbody); | |
1111 if (base64_body) { | |
1112 char *enc = base64_encode(item->email->htmlbody, strlen(item->email->htmlbody)); | |
1113 if (enc) { | |
1114 write_email_body(f_output, enc); | |
1115 free(enc); | |
1116 } | |
1117 } | |
1118 else { | |
1119 write_email_body(f_output, item->email->htmlbody); | |
1120 } | |
1121 } | |
25 | 1122 |
43 | 1123 if (item->email->rtf_compressed && save_rtf) { |
1124 //int32_t tester; | |
1125 DEBUG_EMAIL(("Adding RTF body as attachment\n")); | |
1126 current_attach = (pst_item_attach*)xmalloc(sizeof(pst_item_attach)); | |
1127 memset(current_attach, 0, sizeof(pst_item_attach)); | |
1128 current_attach->next = item->attach; | |
1129 item->attach = current_attach; | |
1130 current_attach->data = lzfu_decompress(item->email->rtf_compressed, item->email->rtf_compressed_size, ¤t_attach->size); | |
1131 current_attach->filename2 = xmalloc(strlen(RTF_ATTACH_NAME)+2); | |
1132 strcpy(current_attach->filename2, RTF_ATTACH_NAME); | |
1133 current_attach->mimetype = xmalloc(strlen(RTF_ATTACH_TYPE)+2); | |
1134 strcpy(current_attach->mimetype, RTF_ATTACH_TYPE); | |
1135 //memcpy(&tester, item->email->rtf_compressed+sizeof(int32_t), sizeof(int32_t)); | |
1136 //LE32_CPU(tester); | |
1137 //printf("lz produced %d bytes, rtf claims %d bytes\n", current_attach->size, tester); | |
1138 } | |
31 | 1139 |
43 | 1140 if (item->email->encrypted_body || item->email->encrypted_htmlbody) { |
1141 // if either the body or htmlbody is encrypted, add them as attachments | |
1142 if (item->email->encrypted_body) { | |
1143 DEBUG_EMAIL(("Adding Encrypted Body as attachment\n")); | |
1144 current_attach = (pst_item_attach*) xmalloc(sizeof(pst_item_attach)); | |
1145 memset(current_attach, 0, sizeof(pst_item_attach)); | |
1146 current_attach->next = item->attach; | |
1147 item->attach = current_attach; | |
1148 current_attach->data = item->email->encrypted_body; | |
1149 current_attach->size = item->email->encrypted_body_size; | |
1150 item->email->encrypted_body = NULL; | |
1151 } | |
31 | 1152 |
43 | 1153 if (item->email->encrypted_htmlbody) { |
1154 DEBUG_EMAIL(("Adding encrypted HTML body as attachment\n")); | |
1155 current_attach = (pst_item_attach*) xmalloc(sizeof(pst_item_attach)); | |
1156 memset(current_attach, 0, sizeof(pst_item_attach)); | |
1157 current_attach->next = item->attach; | |
1158 item->attach = current_attach; | |
1159 current_attach->data = item->email->encrypted_htmlbody; | |
1160 current_attach->size = item->email->encrypted_htmlbody_size; | |
1161 item->email->encrypted_htmlbody = NULL; | |
1162 } | |
1163 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"); | |
1164 } | |
31 | 1165 |
43 | 1166 // attachments |
1167 attach_num = 0; | |
1168 for (current_attach = item->attach; current_attach; current_attach = current_attach->next) { | |
1169 DEBUG_EMAIL(("Attempting Attachment encoding\n")); | |
1170 if (!current_attach->data) { | |
1171 DEBUG_EMAIL(("Data of attachment is NULL!. Size is supposed to be %i\n", current_attach->size)); | |
1172 } | |
77 | 1173 if (mode == MODE_SEPARATE && !mode_MH) |
43 | 1174 write_separate_attachment(f_name, current_attach, ++attach_num, pst); |
1175 else | |
1176 write_inline_attachment(f_output, current_attach, boundary, pst); | |
1177 } | |
77 | 1178 if (mode != MODE_SEPARATE) { /* do not add a boundary after the last attachment for mode_MH */ |
43 | 1179 DEBUG_EMAIL(("Writing buffer between emails\n")); |
1180 if (boundary) fprintf(f_output, "\n--%s--\n", boundary); | |
1181 fprintf(f_output, "\n\n"); | |
1182 } | |
1183 if (boundary) free (boundary); | |
1184 DEBUG_RET(); | |
25 | 1185 } |
1186 | |
31 | 1187 |
25 | 1188 void write_vcard(FILE* f_output, pst_item_contact* contact, char comment[]) |
1189 { | |
43 | 1190 // We can only call rfc escape once per printf, since the second call |
1191 // may free the buffer returned by the first call. | |
1192 // I had tried to place those into a single printf - Carl. | |
39 | 1193 |
43 | 1194 DEBUG_ENT("write_vcard"); |
50 | 1195 // the specification I am following is (hopefully) RFC2426 vCard Mime Directory Profile |
43 | 1196 fprintf(f_output, "BEGIN:VCARD\n"); |
1197 fprintf(f_output, "FN:%s\n", pst_rfc2426_escape(contact->fullname)); | |
39 | 1198 |
43 | 1199 //fprintf(f_output, "N:%s;%s;%s;%s;%s\n", |
1200 fprintf(f_output, "N:%s;", (!contact->surname) ? "" : pst_rfc2426_escape(contact->surname)); | |
1201 fprintf(f_output, "%s;", (!contact->first_name) ? "" : pst_rfc2426_escape(contact->first_name)); | |
1202 fprintf(f_output, "%s;", (!contact->middle_name) ? "" : pst_rfc2426_escape(contact->middle_name)); | |
1203 fprintf(f_output, "%s;", (!contact->display_name_prefix) ? "" : pst_rfc2426_escape(contact->display_name_prefix)); | |
1204 fprintf(f_output, "%s\n", (!contact->suffix) ? "" : pst_rfc2426_escape(contact->suffix)); | |
39 | 1205 |
43 | 1206 if (contact->nickname) |
1207 fprintf(f_output, "NICKNAME:%s\n", pst_rfc2426_escape(contact->nickname)); | |
1208 if (contact->address1) | |
1209 fprintf(f_output, "EMAIL:%s\n", pst_rfc2426_escape(contact->address1)); | |
1210 if (contact->address2) | |
1211 fprintf(f_output, "EMAIL:%s\n", pst_rfc2426_escape(contact->address2)); | |
1212 if (contact->address3) | |
1213 fprintf(f_output, "EMAIL:%s\n", pst_rfc2426_escape(contact->address3)); | |
1214 if (contact->birthday) | |
1215 fprintf(f_output, "BDAY:%s\n", pst_rfc2425_datetime_format(contact->birthday)); | |
39 | 1216 |
43 | 1217 if (contact->home_address) { |
1218 //fprintf(f_output, "ADR;TYPE=home:%s;%s;%s;%s;%s;%s;%s\n", | |
1219 fprintf(f_output, "ADR;TYPE=home:%s;", (!contact->home_po_box) ? "" : pst_rfc2426_escape(contact->home_po_box)); | |
1220 fprintf(f_output, "%s;", ""); // extended Address | |
1221 fprintf(f_output, "%s;", (!contact->home_street) ? "" : pst_rfc2426_escape(contact->home_street)); | |
1222 fprintf(f_output, "%s;", (!contact->home_city) ? "" : pst_rfc2426_escape(contact->home_city)); | |
1223 fprintf(f_output, "%s;", (!contact->home_state) ? "" : pst_rfc2426_escape(contact->home_state)); | |
1224 fprintf(f_output, "%s;", (!contact->home_postal_code) ? "" : pst_rfc2426_escape(contact->home_postal_code)); | |
1225 fprintf(f_output, "%s\n", (!contact->home_country) ? "" : pst_rfc2426_escape(contact->home_country)); | |
1226 fprintf(f_output, "LABEL;TYPE=home:%s\n", pst_rfc2426_escape(contact->home_address)); | |
1227 } | |
39 | 1228 |
43 | 1229 if (contact->business_address) { |
1230 //fprintf(f_output, "ADR;TYPE=work:%s;%s;%s;%s;%s;%s;%s\n", | |
1231 fprintf(f_output, "ADR;TYPE=work:%s;", (!contact->business_po_box) ? "" : pst_rfc2426_escape(contact->business_po_box)); | |
1232 fprintf(f_output, "%s;", ""); // extended Address | |
1233 fprintf(f_output, "%s;", (!contact->business_street) ? "" : pst_rfc2426_escape(contact->business_street)); | |
1234 fprintf(f_output, "%s;", (!contact->business_city) ? "" : pst_rfc2426_escape(contact->business_city)); | |
1235 fprintf(f_output, "%s;", (!contact->business_state) ? "" : pst_rfc2426_escape(contact->business_state)); | |
1236 fprintf(f_output, "%s;", (!contact->business_postal_code) ? "" : pst_rfc2426_escape(contact->business_postal_code)); | |
1237 fprintf(f_output, "%s\n", (!contact->business_country) ? "" : pst_rfc2426_escape(contact->business_country)); | |
1238 fprintf(f_output, "LABEL;TYPE=work:%s\n", pst_rfc2426_escape(contact->business_address)); | |
1239 } | |
39 | 1240 |
43 | 1241 if (contact->other_address) { |
1242 //fprintf(f_output, "ADR;TYPE=postal:%s;%s;%s;%s;%s;%s;%s\n", | |
1243 fprintf(f_output, "ADR;TYPE=postal:%s;",(!contact->other_po_box) ? "" : pst_rfc2426_escape(contact->other_po_box)); | |
1244 fprintf(f_output, "%s;", ""); // extended Address | |
1245 fprintf(f_output, "%s;", (!contact->other_street) ? "" : pst_rfc2426_escape(contact->other_street)); | |
1246 fprintf(f_output, "%s;", (!contact->other_city) ? "" : pst_rfc2426_escape(contact->other_city)); | |
1247 fprintf(f_output, "%s;", (!contact->other_state) ? "" : pst_rfc2426_escape(contact->other_state)); | |
1248 fprintf(f_output, "%s;", (!contact->other_postal_code) ? "" : pst_rfc2426_escape(contact->other_postal_code)); | |
1249 fprintf(f_output, "%s\n", (!contact->other_country) ? "" : pst_rfc2426_escape(contact->other_country)); | |
1250 fprintf(f_output, "LABEL;TYPE=postal:%s\n", pst_rfc2426_escape(contact->other_address)); | |
1251 } | |
39 | 1252 |
43 | 1253 if (contact->business_fax) fprintf(f_output, "TEL;TYPE=work,fax:%s\n", pst_rfc2426_escape(contact->business_fax)); |
1254 if (contact->business_phone) fprintf(f_output, "TEL;TYPE=work,voice:%s\n", pst_rfc2426_escape(contact->business_phone)); | |
1255 if (contact->business_phone2) fprintf(f_output, "TEL;TYPE=work,voice:%s\n", pst_rfc2426_escape(contact->business_phone2)); | |
1256 if (contact->car_phone) fprintf(f_output, "TEL;TYPE=car,voice:%s\n", pst_rfc2426_escape(contact->car_phone)); | |
1257 if (contact->home_fax) fprintf(f_output, "TEL;TYPE=home,fax:%s\n", pst_rfc2426_escape(contact->home_fax)); | |
1258 if (contact->home_phone) fprintf(f_output, "TEL;TYPE=home,voice:%s\n", pst_rfc2426_escape(contact->home_phone)); | |
1259 if (contact->home_phone2) fprintf(f_output, "TEL;TYPE=home,voice:%s\n", pst_rfc2426_escape(contact->home_phone2)); | |
1260 if (contact->isdn_phone) fprintf(f_output, "TEL;TYPE=isdn:%s\n", pst_rfc2426_escape(contact->isdn_phone)); | |
1261 if (contact->mobile_phone) fprintf(f_output, "TEL;TYPE=cell,voice:%s\n", pst_rfc2426_escape(contact->mobile_phone)); | |
1262 if (contact->other_phone) fprintf(f_output, "TEL;TYPE=msg:%s\n", pst_rfc2426_escape(contact->other_phone)); | |
1263 if (contact->pager_phone) fprintf(f_output, "TEL;TYPE=pager:%s\n", pst_rfc2426_escape(contact->pager_phone)); | |
1264 if (contact->primary_fax) fprintf(f_output, "TEL;TYPE=fax,pref:%s\n", pst_rfc2426_escape(contact->primary_fax)); | |
1265 if (contact->primary_phone) fprintf(f_output, "TEL;TYPE=phone,pref:%s\n", pst_rfc2426_escape(contact->primary_phone)); | |
1266 if (contact->radio_phone) fprintf(f_output, "TEL;TYPE=pcs:%s\n", pst_rfc2426_escape(contact->radio_phone)); | |
1267 if (contact->telex) fprintf(f_output, "TEL;TYPE=bbs:%s\n", pst_rfc2426_escape(contact->telex)); | |
1268 if (contact->job_title) fprintf(f_output, "TITLE:%s\n", pst_rfc2426_escape(contact->job_title)); | |
1269 if (contact->profession) fprintf(f_output, "ROLE:%s\n", pst_rfc2426_escape(contact->profession)); | |
1270 if (contact->assistant_name || contact->assistant_phone) { | |
1271 fprintf(f_output, "AGENT:BEGIN:VCARD\n"); | |
1272 if (contact->assistant_name) fprintf(f_output, "FN:%s\n", pst_rfc2426_escape(contact->assistant_name)); | |
1273 if (contact->assistant_phone) fprintf(f_output, "TEL:%s\n", pst_rfc2426_escape(contact->assistant_phone)); | |
1274 } | |
1275 if (contact->company_name) fprintf(f_output, "ORG:%s\n", pst_rfc2426_escape(contact->company_name)); | |
1276 if (comment) fprintf(f_output, "NOTE:%s\n", pst_rfc2426_escape(comment)); | |
25 | 1277 |
43 | 1278 fprintf(f_output, "VERSION: 3.0\n"); |
1279 fprintf(f_output, "END:VCARD\n\n"); | |
1280 DEBUG_RET(); | |
25 | 1281 } |
1282 | |
31 | 1283 |
25 | 1284 void write_appointment(FILE* f_output, pst_item_appointment* appointment, |
43 | 1285 pst_item_email* email, FILETIME* create_date, FILETIME* modify_date) |
25 | 1286 { |
43 | 1287 fprintf(f_output, "BEGIN:VEVENT\n"); |
1288 if (create_date) | |
1289 fprintf(f_output, "CREATED:%s\n", | |
1290 pst_rfc2445_datetime_format(create_date)); | |
1291 if (modify_date) | |
1292 fprintf(f_output, "LAST-MOD:%s\n", | |
1293 pst_rfc2445_datetime_format(modify_date)); | |
1294 if (email && email->subject) | |
1295 fprintf(f_output, "SUMMARY:%s\n", | |
1296 pst_rfc2426_escape(email->subject->subj)); | |
1297 if (email && email->body) | |
1298 fprintf(f_output, "DESCRIPTION:%s\n", | |
1299 pst_rfc2426_escape(email->body)); | |
1300 if (appointment && appointment->start) | |
1301 fprintf(f_output, "DTSTART;VALUE=DATE-TIME:%s\n", | |
1302 pst_rfc2445_datetime_format(appointment->start)); | |
1303 if (appointment && appointment->end) | |
1304 fprintf(f_output, "DTEND;VALUE=DATE-TIME:%s\n", | |
1305 pst_rfc2445_datetime_format(appointment->end)); | |
1306 if (appointment && appointment->location) | |
1307 fprintf(f_output, "LOCATION:%s\n", | |
1308 pst_rfc2426_escape(appointment->location)); | |
1309 if (appointment) { | |
1310 switch (appointment->showas) { | |
50 | 1311 case PST_FREEBUSY_TENTATIVE: |
1312 fprintf(f_output, "STATUS:TENTATIVE\n"); | |
1313 break; | |
1314 case PST_FREEBUSY_FREE: | |
1315 // mark as transparent and as confirmed | |
1316 fprintf(f_output, "TRANSP:TRANSPARENT\n"); | |
1317 case PST_FREEBUSY_BUSY: | |
1318 case PST_FREEBUSY_OUT_OF_OFFICE: | |
1319 fprintf(f_output, "STATUS:CONFIRMED\n"); | |
1320 break; | |
43 | 1321 } |
1322 switch (appointment->label) { | |
50 | 1323 case PST_APP_LABEL_NONE: |
1324 fprintf(f_output, "CATEGORIES:NONE\n"); | |
1325 break; | |
1326 case PST_APP_LABEL_IMPORTANT: | |
1327 fprintf(f_output, "CATEGORIES:IMPORTANT\n"); | |
1328 break; | |
1329 case PST_APP_LABEL_BUSINESS: | |
1330 fprintf(f_output, "CATEGORIES:BUSINESS\n"); | |
1331 break; | |
1332 case PST_APP_LABEL_PERSONAL: | |
1333 fprintf(f_output, "CATEGORIES:PERSONAL\n"); | |
1334 break; | |
1335 case PST_APP_LABEL_VACATION: | |
1336 fprintf(f_output, "CATEGORIES:VACATION\n"); | |
1337 break; | |
1338 case PST_APP_LABEL_MUST_ATTEND: | |
1339 fprintf(f_output, "CATEGORIES:MUST-ATTEND\n"); | |
1340 break; | |
1341 case PST_APP_LABEL_TRAVEL_REQ: | |
1342 fprintf(f_output, "CATEGORIES:TRAVEL-REQUIRED\n"); | |
1343 break; | |
1344 case PST_APP_LABEL_NEEDS_PREP: | |
1345 fprintf(f_output, "CATEGORIES:NEEDS-PREPARATION\n"); | |
1346 break; | |
1347 case PST_APP_LABEL_BIRTHDAY: | |
1348 fprintf(f_output, "CATEGORIES:BIRTHDAY\n"); | |
1349 break; | |
1350 case PST_APP_LABEL_ANNIVERSARY: | |
1351 fprintf(f_output, "CATEGORIES:ANNIVERSARY\n"); | |
1352 break; | |
1353 case PST_APP_LABEL_PHONE_CALL: | |
1354 fprintf(f_output, "CATEGORIES:PHONE-CALL\n"); | |
1355 break; | |
43 | 1356 } |
1357 } | |
1358 fprintf(f_output, "END:VEVENT\n\n"); | |
25 | 1359 } |
1360 | |
31 | 1361 |
39 | 1362 void create_enter_dir(struct file_ll* f, pst_item *item) |
25 | 1363 { |
43 | 1364 f->email_count = 0; |
1365 f->skip_count = 0; | |
1366 f->type = item->type; | |
1367 f->stored_count = (item->folder) ? item->folder->email_count : 0; | |
39 | 1368 |
43 | 1369 DEBUG_ENT("create_enter_dir"); |
1370 if (mode == MODE_KMAIL) | |
1371 f->name = mk_kmail_dir(item->file_as); //create directory and form filename | |
1372 else if (mode == MODE_RECURSE) | |
1373 f->name = mk_recurse_dir(item->file_as); | |
77 | 1374 else if (mode == MODE_SEPARATE) { |
43 | 1375 // do similar stuff to recurse here. |
77 | 1376 mk_separate_dir(item->file_as); |
43 | 1377 f->name = (char*) xmalloc(10); |
1378 memset(f->name, 0, 10); | |
1379 // sprintf(f->name, SEP_MAIL_FILE_TEMPLATE, f->email_count); | |
1380 } else { | |
1381 f->name = (char*) xmalloc(strlen(item->file_as)+strlen(OUTPUT_TEMPLATE)+1); | |
1382 sprintf(f->name, OUTPUT_TEMPLATE, item->file_as); | |
1383 } | |
25 | 1384 |
43 | 1385 f->dname = (char*) xmalloc(strlen(item->file_as)+1); |
1386 strcpy(f->dname, item->file_as); | |
25 | 1387 |
43 | 1388 if (overwrite != 1) { |
1389 int x = 0; | |
1390 char *temp = (char*) xmalloc (strlen(f->name)+10); //enough room for 10 digits | |
25 | 1391 |
43 | 1392 sprintf(temp, "%s", f->name); |
1393 check_filename(temp); | |
1394 while ((f->output = fopen(temp, "r"))) { | |
1395 DEBUG_MAIN(("need to increase filename because one already exists with that name\n")); | |
1396 DEBUG_MAIN(("- increasing it to %s%d\n", f->name, x)); | |
1397 x++; | |
1398 sprintf(temp, "%s%08d", f->name, x); | |
1399 DEBUG_MAIN(("- trying \"%s\"\n", f->name)); | |
1400 if (x == 99999999) { | |
1401 DIE(("create_enter_dir: Why can I not create a folder %s? I have tried %i extensions...\n", f->name, x)); | |
1402 } | |
1403 fclose(f->output); | |
1404 } | |
1405 if (x > 0) { //then the f->name should change | |
1406 free (f->name); | |
1407 f->name = temp; | |
1408 } else { | |
1409 free(temp); | |
1410 } | |
1411 } | |
25 | 1412 |
43 | 1413 DEBUG_MAIN(("f->name = %s\nitem->folder_name = %s\n", f->name, item->file_as)); |
77 | 1414 if (mode != MODE_SEPARATE) { |
43 | 1415 check_filename(f->name); |
1416 if (!(f->output = fopen(f->name, "w"))) { | |
1417 DIE(("create_enter_dir: Could not open file \"%s\" for write\n", f->name)); | |
1418 } | |
1419 } | |
1420 DEBUG_RET(); | |
25 | 1421 } |
1422 | |
39 | 1423 |
1424 void close_enter_dir(struct file_ll *f) | |
1425 { | |
43 | 1426 DEBUG_MAIN(("main: Email Count for folder %s is %i\n", f->dname, f->email_count)); |
1427 if (output_mode != OUTPUT_QUIET) | |
1428 printf("\t\"%s\" - %i items done, skipped %i, should have been %i\n", | |
1429 f->dname, f->email_count, f->skip_count, f->stored_count); | |
1430 if (f->output) fclose(f->output); | |
1431 free(f->name); | |
1432 free(f->dname); | |
39 | 1433 |
43 | 1434 if (mode == MODE_KMAIL) |
1435 close_kmail_dir(); | |
1436 else if (mode == MODE_RECURSE) | |
1437 close_recurse_dir(); | |
77 | 1438 else if (mode == MODE_SEPARATE) |
1439 close_separate_dir(); | |
39 | 1440 } |
1441 |