comparison src/libpst.c @ 48:f66078abed38

more fixes for 64 bit format
author carl
date Fri, 18 Jan 2008 15:07:12 -0800
parents 5fb8d997feed
children 17654fbdf76b
comparison
equal deleted inserted replaced
47:5fb8d997feed 48:f66078abed38
2 * libpst.c 2 * libpst.c
3 * Part of the LibPST project 3 * Part of the LibPST project
4 * Written by David Smith 4 * Written by David Smith
5 * dave.s@earthcorp.com 5 * dave.s@earthcorp.com
6 */ 6 */
7 #include "define.h"
8
7 #include <stdio.h> 9 #include <stdio.h>
8 #include <stdlib.h> 10 #include <stdlib.h>
9 #include <time.h> 11 #include <time.h>
10 #include <string.h> 12 #include <string.h>
11 #include <ctype.h> 13 #include <ctype.h>
13 #include <wchar.h> 15 #include <wchar.h>
14 #include <signal.h> 16 #include <signal.h>
15 #include <errno.h> 17 #include <errno.h>
16 #include <sys/stat.h> // mkdir 18 #include <sys/stat.h> // mkdir
17 #include <fcntl.h> // for Win32 definition of _O_BINARY 19 #include <fcntl.h> // for Win32 definition of _O_BINARY
18 #include "define.h"
19 #include "libstrfunc.h" 20 #include "libstrfunc.h"
20 #include "vbuf.h" 21 #include "vbuf.h"
21 22
22 #define ASSERT(x) { if(!(x)) raise( SIGSEGV ); } 23 #define ASSERT(x) { if(!(x)) raise( SIGSEGV ); }
23 24
31 #include "timeconv.h" 32 #include "timeconv.h"
32 //efine INDEX_DEPTH 0x4C 33 //efine INDEX_DEPTH 0x4C
33 //efine SECOND_DEPTH 0x5C 34 //efine SECOND_DEPTH 0x5C
34 #define INDEX_TYPE32 0x0E 35 #define INDEX_TYPE32 0x0E
35 #define INDEX_TYPE64 0x17 36 #define INDEX_TYPE64 0x17
37 #define INDEX_TYPE_OFFSET (off_t)0x0A
36 38
37 #define FILE_SIZE_POINTER32 (off_t)0xA8 39 #define FILE_SIZE_POINTER32 (off_t)0xA8
38 #define INDEX_POINTER32 (off_t)0xC4 40 #define INDEX_POINTER32 (off_t)0xC4
39 #define INDEX_BACK32 (off_t)0xC0 41 #define INDEX_BACK32 (off_t)0xC0
40 #define SECOND_POINTER32 (off_t)0xBC 42 #define SECOND_POINTER32 (off_t)0xBC
41 #define SECOND_BACK32 (off_t)0xB8 43 #define SECOND_BACK32 (off_t)0xB8
42 #define INDEX_TYPE_OFFSET32 (off_t)0x0A
43 #define ENC_OFFSET32 (off_t)0x1CD 44 #define ENC_OFFSET32 (off_t)0x1CD
44 45
45 #define FILE_SIZE_POINTER64 (off_t)0xB8 46 #define FILE_SIZE_POINTER64 (off_t)0xB8
46 #define INDEX_POINTER64 (off_t)0xF0 47 #define INDEX_POINTER64 (off_t)0xF0
47 #define INDEX_BACK64 (off_t)0xE8 48 #define INDEX_BACK64 (off_t)0xE8
48 #define SECOND_POINTER64 (off_t)0xE0 49 #define SECOND_POINTER64 (off_t)0xE0
49 #define SECOND_BACK64 (off_t)0xD8 50 #define SECOND_BACK64 (off_t)0xD8
50 #define INDEX_TYPE_OFFSET64 (off_t)0x0A
51 #define ENC_OFFSET64 (off_t)0x201 51 #define ENC_OFFSET64 (off_t)0x201
52 52
53 #define FILE_SIZE_POINTER ((pf->do_read64) ? FILE_SIZE_POINTER64 : FILE_SIZE_POINTER32) 53 #define FILE_SIZE_POINTER ((pf->do_read64) ? FILE_SIZE_POINTER64 : FILE_SIZE_POINTER32)
54 #define INDEX_POINTER ((pf->do_read64) ? INDEX_POINTER64 : INDEX_POINTER32) 54 #define INDEX_POINTER ((pf->do_read64) ? INDEX_POINTER64 : INDEX_POINTER32)
55 #define INDEX_BACK ((pf->do_read64) ? INDEX_BACK64 : INDEX_BACK32) 55 #define INDEX_BACK ((pf->do_read64) ? INDEX_BACK64 : INDEX_BACK32)
56 #define SECOND_POINTER ((pf->do_read64) ? SECOND_POINTER64 : SECOND_POINTER32) 56 #define SECOND_POINTER ((pf->do_read64) ? SECOND_POINTER64 : SECOND_POINTER32)
57 #define SECOND_BACK ((pf->do_read64) ? SECOND_BACK64 : SECOND_BACK32) 57 #define SECOND_BACK ((pf->do_read64) ? SECOND_BACK64 : SECOND_BACK32)
58 #define INDEX_TYPE_OFFSET ((pf->do_read64) ? INDEX_TYPE_OFFSET64 : INDEX_TYPE_OFFSET32)
59 #define INDEX_TYPE ((pf->do_read64) ? INDEX_TYPE64 : INDEX_TYPE32)
60 #define ENC_OFFSET ((pf->do_read64) ? ENC_OFFSET64 : ENC_OFFSET32) 58 #define ENC_OFFSET ((pf->do_read64) ? ENC_OFFSET64 : ENC_OFFSET32)
61 59
62 #define PST_SIGNATURE 0x4E444221 60 #define PST_SIGNATURE 0x4E444221
63 61
64 62
83 uint32_t id; 81 uint32_t id;
84 uint32_t table2; 82 uint32_t table2;
85 } pst_id2_assoc32; 83 } pst_id2_assoc32;
86 84
87 typedef struct pst_id2_assoc { 85 typedef struct pst_id2_assoc {
88 uint64_t id2; 86 uint32_t id2; // only 32 bit here?
87 uint16_t unknown1;
88 uint16_t unknown2;
89 uint64_t id; 89 uint64_t id;
90 uint64_t table2; 90 uint64_t table2;
91 } pst_id2_assoc; 91 } pst_id2_assoc;
92
93 typedef struct pst_table3_rec32 {
94 uint32_t id;
95 } pst_table3_rec32; //for type 3 (0x0101) blocks
96
97 typedef struct pst_table3_rec {
98 uint64_t id;
99 } pst_table3_rec; //for type 3 (0x0101) blocks
100
92 101
93 // this is an array of the un-encrypted values. the un-encrypted value is in the position 102 // this is an array of the un-encrypted values. the un-encrypted value is in the position
94 // of the encrypted value. ie the encrypted value 0x13 represents 0x02 103 // of the encrypted value. ie the encrypted value 0x13 represents 0x02
95 // 0 1 2 3 4 5 6 7 104 // 0 1 2 3 4 5 6 7
96 // 8 9 a b c d e f 105 // 8 9 a b c d e f
168 DEBUG_RET(); 177 DEBUG_RET();
169 return -1; 178 return -1;
170 } 179 }
171 180
172 // read index type 181 // read index type
173 pf->do_read64 = 0; // start with 32 bit format
174 (void)pst_getAtPos(pf->fp, INDEX_TYPE_OFFSET, &(pf->ind_type), sizeof(pf->ind_type)); 182 (void)pst_getAtPos(pf->fp, INDEX_TYPE_OFFSET, &(pf->ind_type), sizeof(pf->ind_type));
175 DEBUG_INFO(("index_type = %i\n", pf->ind_type)); 183 DEBUG_INFO(("index_type = %i\n", pf->ind_type));
176 if (pf->ind_type != INDEX_TYPE) { 184 switch (pf->ind_type) {
177 // try with 64 bit format 185 case INDEX_TYPE32 :
178 pf->do_read64 = 1; 186 pf->do_read64 = 0;
179 if (pf->ind_type != INDEX_TYPE) { 187 break;
188 case INDEX_TYPE64 :
189 pf->do_read64 = 1;
190 break;
191 default:
180 WARN(("unknown .pst format, possibly newer than Outlook 2003 PST file?\n")); 192 WARN(("unknown .pst format, possibly newer than Outlook 2003 PST file?\n"));
181 DEBUG_RET(); 193 DEBUG_RET();
182 return -1; 194 return -1;
183 }
184 else {
185 WARN(("switching to 64 bit format...\n"));
186 }
187 } 195 }
188 196
189 // read encryption setting 197 // read encryption setting
190 (void)pst_getAtPos(pf->fp, ENC_OFFSET, &(pf->encryption), sizeof(pf->encryption)); 198 (void)pst_getAtPos(pf->fp, ENC_OFFSET, &(pf->encryption), sizeof(pf->encryption));
191 DEBUG_INFO(("encrypt = %i\n", pf->encryption)); 199 DEBUG_INFO(("encrypt = %i\n", pf->encryption));
192 200
193 pf->index2_back = pst_getIntAtPos(pf, SECOND_BACK); 201 pf->index2_back = pst_getIntAtPos(pf, SECOND_BACK);
194 pf->index2 = pst_getIntAtPos(pf, SECOND_POINTER); 202 pf->index2 = pst_getIntAtPos(pf, SECOND_POINTER);
195 pf->size = pst_getIntAtPos(pf, FILE_SIZE_POINTER); 203 pf->size = pst_getIntAtPos(pf, FILE_SIZE_POINTER);
196 DEBUG_INFO(("Pointer2 is %#llx, count %lli[%#llx]\n", pf->index2, pf->index2_back, pf->index2_back)); 204 DEBUG_INFO(("Pointer2 is %#llx, back pointer2 is %#llx\n", pf->index2, pf->index2_back));
197 205
198 pf->index1_back = pst_getIntAtPos(pf, INDEX_BACK); 206 pf->index1_back = pst_getIntAtPos(pf, INDEX_BACK);
199 pf->index1 = pst_getIntAtPos(pf, INDEX_POINTER); 207 pf->index1 = pst_getIntAtPos(pf, INDEX_POINTER);
200 DEBUG_INFO(("Pointer1 is %#llx, count %lli[%#llx]\n", pf->index1, pf->index1_back, pf->index1_back)); 208 DEBUG_INFO(("Pointer1 is %#llx, back pointer2 is %#llx\n", pf->index1, pf->index1_back));
201 209
202 DEBUG_RET(); 210 DEBUG_RET();
203 return 0; 211 return 0;
204 } 212 }
205 213
398 (void)pst_printID2ptr(id2_head); 406 (void)pst_printID2ptr(id2_head);
399 } else { 407 } else {
400 DEBUG_WARN(("Have not been able to fetch any id2 values for item 0x61. Brace yourself!\n")); 408 DEBUG_WARN(("Have not been able to fetch any id2 values for item 0x61. Brace yourself!\n"));
401 } 409 }
402 410
403 na = pst_parse_block(pf, p->desc->id, id2_head); 411 na = pst_parse_block(pf, p->desc->id, id2_head, NULL);
404 if (!na) { 412 if (!na) {
405 DEBUG_WARN(("Cannot process desc block for item 0x61. Not loading extended Attributes\n")); 413 DEBUG_WARN(("Cannot process desc block for item 0x61. Not loading extended Attributes\n"));
406 if (id2_head) pst_free_id2(id2_head); 414 if (id2_head) pst_free_id2(id2_head);
407 DEBUG_RET(); 415 DEBUG_RET();
408 return 0; 416 return 0;
637 size_t r; 645 size_t r;
638 if (pf->do_read64) { 646 if (pf->do_read64) {
639 DEBUG_INDEX(("Decoding assoc64\n")); 647 DEBUG_INDEX(("Decoding assoc64\n"));
640 DEBUG_HEXDUMPC(buf, sizeof(pst_id2_assoc), 0x10); 648 DEBUG_HEXDUMPC(buf, sizeof(pst_id2_assoc), 0x10);
641 memcpy(assoc, buf, sizeof(pst_id2_assoc)); 649 memcpy(assoc, buf, sizeof(pst_id2_assoc));
642 LE64_CPU(assoc->id2); 650 LE32_CPU(assoc->id2);
643 LE64_CPU(assoc->id); 651 LE64_CPU(assoc->id);
644 LE64_CPU(assoc->table2); 652 LE64_CPU(assoc->table2);
645 r = sizeof(pst_id2_assoc); 653 r = sizeof(pst_id2_assoc);
646 } else { 654 } else {
647 pst_id2_assoc32 assoc32; 655 pst_id2_assoc32 assoc32;
658 } 666 }
659 return r; 667 return r;
660 } 668 }
661 669
662 670
671 static size_t pst_decode_type3(pst_file *pf, pst_table3_rec *table3_rec, char *buf);
672 static size_t pst_decode_type3(pst_file *pf, pst_table3_rec *table3_rec, char *buf) {
673 size_t r;
674 if (pf->do_read64) {
675 DEBUG_INDEX(("Decoding table3 64\n"));
676 DEBUG_HEXDUMPC(buf, sizeof(pst_table3_rec), 0x10);
677 memcpy(table3_rec, buf, sizeof(pst_table3_rec));
678 LE64_CPU(table3_rec->id);
679 r = sizeof(pst_table3_rec);
680 } else {
681 pst_table3_rec32 table3_rec32;
682 DEBUG_INDEX(("Decoding table3 32\n"));
683 DEBUG_HEXDUMPC(buf, sizeof(pst_table3_rec32), 0x10);
684 memcpy(&table3_rec32, buf, sizeof(pst_table3_rec32));
685 LE32_CPU(table3_rec32.id);
686 table3_rec->id = table3_rec32.id;
687 r = sizeof(pst_table3_rec32);
688 }
689 return r;
690 }
691
692
663 int pst_build_id_ptr(pst_file *pf, off_t offset, int32_t depth, uint64_t linku1, uint64_t start_val, uint64_t end_val) { 693 int pst_build_id_ptr(pst_file *pf, off_t offset, int32_t depth, uint64_t linku1, uint64_t start_val, uint64_t end_val) {
664 struct pst_table_ptr_structn table, table2; 694 struct pst_table_ptr_structn table, table2;
665 pst_index_ll *i_ptr=NULL; 695 pst_index_ll *i_ptr=NULL;
666 pst_index index; 696 pst_index index;
667 int32_t x, item_count; 697 int32_t x, item_count;
668 uint64_t old = start_val; 698 uint64_t old = start_val;
669 char *buf = NULL, *bptr; 699 char *buf = NULL, *bptr;
670 700
671 DEBUG_ENT("pst_build_id_ptr"); 701 DEBUG_ENT("pst_build_id_ptr");
672 DEBUG_INDEX(("offset %x depth %i linku1 %llx start %llx end %llx\n", offset, depth, linku1, start_val, end_val)); 702 DEBUG_INDEX(("offset %llx depth %i linku1 %llx start %llx end %llx\n", offset, depth, linku1, start_val, end_val));
673 if (end_val <= start_val) { 703 if (end_val <= start_val) {
674 DEBUG_WARN(("The end value is BEFORE the start value. This function will quit. Soz. [start:%#llx, end:%#llx]\n", start_val, end_val)); 704 DEBUG_WARN(("The end value is BEFORE the start value. This function will quit. Soz. [start:%#llx, end:%#llx]\n", start_val, end_val));
675 DEBUG_RET(); 705 DEBUG_RET();
676 return -1; 706 return -1;
677 } 707 }
876 int pst_build_desc_ptr (pst_file *pf, off_t offset, int32_t depth, uint64_t linku1, uint64_t *high_id, uint64_t start_val, uint64_t end_val) { 906 int pst_build_desc_ptr (pst_file *pf, off_t offset, int32_t depth, uint64_t linku1, uint64_t *high_id, uint64_t start_val, uint64_t end_val) {
877 struct pst_table_ptr_structn table, table2; 907 struct pst_table_ptr_structn table, table2;
878 pst_descn desc_rec; 908 pst_descn desc_rec;
879 pst_desc_ll *d_ptr=NULL, *parent=NULL; 909 pst_desc_ll *d_ptr=NULL, *parent=NULL;
880 int32_t x, item_count; 910 int32_t x, item_count;
881 uint32_t old = start_val; 911 uint64_t old = start_val;
882 char *buf = NULL, *bptr; 912 char *buf = NULL, *bptr;
883 struct cache_list_node *cache_ptr = NULL; 913 struct cache_list_node *cache_ptr = NULL;
884 struct cache_list_node *lostfound_ptr = NULL; 914 struct cache_list_node *lostfound_ptr = NULL;
885 struct cache_list_node *lostfound_shd = NULL; 915 struct cache_list_node *lostfound_shd = NULL;
886 struct cache_list_node *lostfound_tmp = NULL; 916 struct cache_list_node *lostfound_tmp = NULL;
1117 (void)pst_printID2ptr(id2_head); 1147 (void)pst_printID2ptr(id2_head);
1118 } else { 1148 } else {
1119 DEBUG_WARN(("Have not been able to fetch any id2 values for this item. Brace yourself!\n")); 1149 DEBUG_WARN(("Have not been able to fetch any id2 values for this item. Brace yourself!\n"));
1120 } 1150 }
1121 1151
1122 list = pst_parse_block(pf, d_ptr->desc->id, id2_head); 1152 list = pst_parse_block(pf, d_ptr->desc->id, id2_head, NULL);
1123 if (!list) { 1153 if (!list) {
1124 DEBUG_WARN(("pst_parse_block() returned an error for d_ptr->desc->id [%#llx]\n", d_ptr->desc->id)); 1154 DEBUG_WARN(("pst_parse_block() returned an error for d_ptr->desc->id [%#llx]\n", d_ptr->desc->id));
1125 if (id2_head) pst_free_id2(id2_head); 1155 if (id2_head) pst_free_id2(id2_head);
1126 DEBUG_RET(); 1156 DEBUG_RET();
1127 return NULL; 1157 return NULL;
1148 free(item->attach); 1178 free(item->attach);
1149 item->attach = attach; 1179 item->attach = attach;
1150 } 1180 }
1151 1181
1152 DEBUG_EMAIL(("ATTACHMENT processing attachment\n")); 1182 DEBUG_EMAIL(("ATTACHMENT processing attachment\n"));
1153 if ((list = pst_parse_block(pf, id_ptr->id, id2_head)) == NULL) { 1183 if ((list = pst_parse_block(pf, id_ptr->id, id2_head, NULL)) == NULL) {
1154 DEBUG_WARN(("ERROR error processing main attachment record\n")); 1184 DEBUG_WARN(("ERROR error processing main attachment record\n"));
1155 if (item) pst_freeItem(item); 1185 if (item) pst_freeItem(item);
1156 if (id2_head) pst_free_id2(id2_head); 1186 if (id2_head) pst_free_id2(id2_head);
1157 DEBUG_RET(); 1187 DEBUG_RET();
1158 return NULL; 1188 return NULL;
1185 while (attach) { 1215 while (attach) {
1186 if ((id_ptr = pst_getID2(id2_head, attach->id2_val))) { 1216 if ((id_ptr = pst_getID2(id2_head, attach->id2_val))) {
1187 // id_ptr is a record describing the attachment 1217 // id_ptr is a record describing the attachment
1188 // we pass NULL instead of id2_head cause we don't want it to 1218 // we pass NULL instead of id2_head cause we don't want it to
1189 // load all the extra stuff here. 1219 // load all the extra stuff here.
1190 if ((list = pst_parse_block(pf, id_ptr->id, NULL)) == NULL) { 1220 if ((list = pst_parse_block(pf, id_ptr->id, NULL, NULL)) == NULL) {
1191 DEBUG_WARN(("ERROR error processing an attachment record\n")); 1221 DEBUG_WARN(("ERROR error processing an attachment record\n"));
1192 attach = attach->next; 1222 attach = attach->next;
1193 continue; 1223 continue;
1194 } 1224 }
1195 if (pst_process(list, item, attach)) { 1225 if (pst_process(list, item, attach)) {
1246 if (p6->needfree) free(p6->from); 1276 if (p6->needfree) free(p6->from);
1247 if (p7->needfree) free(p7->from); 1277 if (p7->needfree) free(p7->from);
1248 } 1278 }
1249 1279
1250 1280
1251 pst_num_array * pst_parse_block(pst_file *pf, uint64_t block_id, pst_index2_ll *i2_head) { 1281 pst_num_array * pst_parse_block(pst_file *pf, uint64_t block_id, pst_index2_ll *i2_head, pst_num_array *na_head) {
1252 unsigned char *buf = NULL; 1282 unsigned char *buf = NULL;
1253 pst_num_array *na_ptr = NULL, *na_head = NULL; 1283 pst_num_array *na_ptr = NULL;
1254 pst_block_offset_pointer block_offset1; 1284 pst_block_offset_pointer block_offset1;
1255 pst_block_offset_pointer block_offset2; 1285 pst_block_offset_pointer block_offset2;
1256 pst_block_offset_pointer block_offset3; 1286 pst_block_offset_pointer block_offset3;
1257 pst_block_offset_pointer block_offset4; 1287 pst_block_offset_pointer block_offset4;
1258 pst_block_offset_pointer block_offset5; 1288 pst_block_offset_pointer block_offset5;
1273 unsigned char* ind2_ptr = NULL; 1303 unsigned char* ind2_ptr = NULL;
1274 size_t read_size=0; 1304 size_t read_size=0;
1275 pst_x_attrib_ll *mapptr; 1305 pst_x_attrib_ll *mapptr;
1276 1306
1277 struct { 1307 struct {
1278 uint16_t type;
1279 uint16_t ref_type;
1280 uint32_t value;
1281 } table_rec; //for type 1 (0xBCEC) blocks
1282 struct {
1283 uint16_t ref_type;
1284 uint16_t type;
1285 uint16_t ind2_off;
1286 uint8_t size;
1287 uint8_t slot;
1288 } table2_rec; //for type 2 (0x7CEC) blocks
1289 struct {
1290 uint32_t id;
1291 } table3_rec; //for type 3 (0x0101) blocks
1292 struct {
1293 uint16_t index_offset; 1308 uint16_t index_offset;
1294 uint16_t type; 1309 uint16_t type;
1295 uint32_t offset; 1310 uint32_t offset;
1296 } block_hdr; 1311 } block_hdr;
1312
1297 struct { 1313 struct {
1298 unsigned char seven_c; 1314 unsigned char seven_c;
1299 unsigned char item_count; 1315 unsigned char item_count;
1300 uint16_t u1; 1316 uint16_t u1;
1301 uint16_t u2; 1317 uint16_t u2;
1304 uint32_t b_five_offset; 1320 uint32_t b_five_offset;
1305 uint32_t ind2_offset; 1321 uint32_t ind2_offset;
1306 uint16_t u7; 1322 uint16_t u7;
1307 uint16_t u8; 1323 uint16_t u8;
1308 } seven_c_blk; 1324 } seven_c_blk;
1325
1309 struct _type_d_rec { 1326 struct _type_d_rec {
1310 uint32_t id; 1327 uint32_t id;
1311 uint32_t u1; 1328 uint32_t u1;
1312 } * type_d_rec; 1329 } * type_d_rec;
1330
1331 struct {
1332 uint16_t type;
1333 uint16_t ref_type;
1334 uint32_t value;
1335 } table_rec; //for type 1 (0xBCEC) blocks
1336
1337 struct {
1338 uint16_t ref_type;
1339 uint16_t type;
1340 uint16_t ind2_off;
1341 uint8_t size;
1342 uint8_t slot;
1343 } table2_rec; //for type 2 (0x7CEC) blocks
1344
1345 pst_table3_rec table3_rec; //for type 3 (0x0101) blocks
1313 1346
1314 DEBUG_ENT("pst_parse_block"); 1347 DEBUG_ENT("pst_parse_block");
1315 if ((read_size = pst_ff_getIDblock_dec(pf, block_id, &buf)) == 0) { 1348 if ((read_size = pst_ff_getIDblock_dec(pf, block_id, &buf)) == 0) {
1316 WARN(("Error reading block id %#llx\n", block_id)); 1349 WARN(("Error reading block id %#llx\n", block_id));
1317 if (buf) free (buf); 1350 if (buf) free (buf);
1329 1362
1330 memcpy(&block_hdr, buf, sizeof(block_hdr)); 1363 memcpy(&block_hdr, buf, sizeof(block_hdr));
1331 LE16_CPU(block_hdr.index_offset); 1364 LE16_CPU(block_hdr.index_offset);
1332 LE16_CPU(block_hdr.type); 1365 LE16_CPU(block_hdr.type);
1333 LE32_CPU(block_hdr.offset); 1366 LE32_CPU(block_hdr.offset);
1334 DEBUG_EMAIL(("block header (index_offset=%#hx, type=%#hx, offset=%#hx\n", block_hdr.index_offset, block_hdr.type, block_hdr.offset)); 1367 DEBUG_EMAIL(("block header (index_offset=%#hx, type=%#hx, offset=%#hx)\n", block_hdr.index_offset, block_hdr.type, block_hdr.offset));
1335 1368
1336 ind_ptr = block_hdr.index_offset; 1369 ind_ptr = block_hdr.index_offset;
1337 1370
1338 if (block_hdr.type == (uint16_t)0xBCEC) { //type 1 1371 if (block_hdr.type == (uint16_t)0xBCEC) { //type 1
1339 block_type = 1; 1372 block_type = 1;
1438 ind2_end = block_offset6.to; 1471 ind2_end = block_offset6.to;
1439 } 1472 }
1440 else if (block_hdr.index_offset == (uint16_t)0x0101) { //type 3 1473 else if (block_hdr.index_offset == (uint16_t)0x0101) { //type 3
1441 unsigned char *buf2 = NULL; 1474 unsigned char *buf2 = NULL;
1442 uint16_t n = block_hdr.type; // count 1475 uint16_t n = block_hdr.type; // count
1443 size_t m = sizeof(table3_rec);
1444 uint16_t i; 1476 uint16_t i;
1445 block_type = 3; 1477 block_type = 3;
1478 char *b_ptr = buf + 8;
1446 for (i=0; i<n; i++) { 1479 for (i=0; i<n; i++) {
1447 memcpy(&table3_rec, buf+8+i*m, m); 1480 b_ptr += pst_decode_type3(pf, &table3_rec, b_ptr);
1448 LE32_CPU(table3_rec.id); 1481 //(void)pst_ff_getIDblock_dec(pf, table3_rec.id, &buf2);
1449 (void)pst_ff_getIDblock_dec(pf, table3_rec.id, &buf2); 1482 //if (buf2) free(buf2);
1450 if (buf2) free(buf2); 1483 //buf2 = NULL;
1451 buf2 = NULL; 1484 na_head = pst_parse_block(pf, table3_rec.id, i2_head, na_head); // !! this is still not correct
1452 } 1485 }
1453 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); 1486 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7);
1454 DEBUG_RET(); 1487 DEBUG_RET();
1455 return NULL; 1488 return na_head;
1456 } else { 1489 } else {
1457 WARN(("ERROR: Unknown block constant - %#hx for id %#llx\n", block_hdr.type, block_id)); 1490 WARN(("ERROR: Unknown block constant - %#hx for id %#llx\n", block_hdr.type, block_id));
1458 DEBUG_HEXDUMPC(buf, read_size,0x10); 1491 DEBUG_HEXDUMPC(buf, read_size,0x10);
1459 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); 1492 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7);
1460 DEBUG_RET(); 1493 DEBUG_RET();
1465 for (count_rec=0; count_rec<num_recs; count_rec++) { 1498 for (count_rec=0; count_rec<num_recs; count_rec++) {
1466 na_ptr = (pst_num_array*) xmalloc(sizeof(pst_num_array)); 1499 na_ptr = (pst_num_array*) xmalloc(sizeof(pst_num_array));
1467 memset(na_ptr, 0, sizeof(pst_num_array)); 1500 memset(na_ptr, 0, sizeof(pst_num_array));
1468 na_ptr->next = na_head; 1501 na_ptr->next = na_head;
1469 na_head = na_ptr; 1502 na_head = na_ptr;
1470 // allocate an array of count num_recs to contain sizeof(structpst_num_item) 1503 // allocate an array of count num_recs to contain sizeof(struct pst_num_item)
1471 na_ptr->items = (struct pst_num_item**) xmalloc(sizeof(struct pst_num_item)*num_list); 1504 na_ptr->items = (struct pst_num_item**) xmalloc(sizeof(struct pst_num_item)*num_list);
1472 na_ptr->count_item = num_list; 1505 na_ptr->count_item = num_list;
1473 na_ptr->orig_count = num_list; 1506 na_ptr->orig_count = num_list;
1474 na_ptr->count_array = (int32_t)num_recs; // each record will have a record of the total number of records 1507 na_ptr->count_array = (int32_t)num_recs; // each record will have a record of the total number of records
1475 for (x=0; x<num_list; x++) na_ptr->items[x] = NULL; 1508 for (x=0; x<num_list; x++) na_ptr->items[x] = NULL;
1677 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); 1710 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7);
1678 DEBUG_RET(); 1711 DEBUG_RET();
1679 return na_head; 1712 return na_head;
1680 } 1713 }
1681 1714
1715 // This version of free does NULL check first
1716 #define SAFE_FREE(x) {if (x) free(x);}
1717
1682 1718
1683 // check if item->email is NULL, and init if so 1719 // check if item->email is NULL, and init if so
1684 #define MALLOC_EMAIL(x) { if (!x->email) { x->email = (pst_item_email*) xmalloc(sizeof(pst_item_email)); memset(x->email, 0, sizeof(pst_item_email) );} } 1720 #define MALLOC_EMAIL(x) { if (!x->email) { x->email = (pst_item_email*) xmalloc(sizeof(pst_item_email)); memset(x->email, 0, sizeof(pst_item_email) );} }
1685 #define MALLOC_FOLDER(x) { if (!x->folder) { x->folder = (pst_item_folder*) xmalloc(sizeof(pst_item_folder)); memset(x->folder, 0, sizeof(pst_item_folder) );} } 1721 #define MALLOC_FOLDER(x) { if (!x->folder) { x->folder = (pst_item_folder*) xmalloc(sizeof(pst_item_folder)); memset(x->folder, 0, sizeof(pst_item_folder) );} }
1686 #define MALLOC_CONTACT(x) { if (!x->contact) { x->contact = (pst_item_contact*) xmalloc(sizeof(pst_item_contact)); memset(x->contact, 0, sizeof(pst_item_contact) );} } 1722 #define MALLOC_CONTACT(x) { if (!x->contact) { x->contact = (pst_item_contact*) xmalloc(sizeof(pst_item_contact)); memset(x->contact, 0, sizeof(pst_item_contact) );} }
1692 targ = type realloc(targ, list->items[x]->size+1); \ 1728 targ = type realloc(targ, list->items[x]->size+1); \
1693 memcpy(targ, list->items[x]->data, list->items[x]->size); \ 1729 memcpy(targ, list->items[x]->data, list->items[x]->size); \
1694 memset(((char*)targ)+list->items[x]->size, 0, (size_t)1); \ 1730 memset(((char*)targ)+list->items[x]->size, 0, (size_t)1); \
1695 } 1731 }
1696 // malloc space and copy the current item's data and size 1732 // malloc space and copy the current item's data and size
1697 #define LIST_COPY_SIZE(targ, type, mysize) { \ 1733 #define LIST_COPY_SIZE(targ, type, mysize) { \
1698 mysize = list->items[x]->size; \ 1734 mysize = list->items[x]->size; \
1699 targ = type realloc(targ, mysize); \ 1735 if (mysize) { \
1700 memcpy(targ, list->items[x]->data, mysize); \ 1736 targ = type realloc(targ, mysize); \
1737 memcpy(targ, list->items[x]->data, mysize); \
1738 } \
1739 else { \
1740 SAFE_FREE(targ); \
1741 targ = NULL; \
1742 } \
1701 } 1743 }
1702 1744
1703 #define NULL_CHECK(x) { if (!x) { DEBUG_EMAIL(("NULL_CHECK: Null Found\n")); break;} } 1745 #define NULL_CHECK(x) { if (!x) { DEBUG_EMAIL(("NULL_CHECK: Null Found\n")); break;} }
1704 1746
1705 #define MOVE_NEXT(targ) { \ 1747 #define MOVE_NEXT(targ) { \
3441 list->id, block_head.count, list->offset)); 3483 list->id, block_head.count, list->offset));
3442 x = 0; 3484 x = 0;
3443 b_ptr = buf + ((pf->do_read64) ? 0x08 : 0x04); 3485 b_ptr = buf + ((pf->do_read64) ? 0x08 : 0x04);
3444 while (x < block_head.count) { 3486 while (x < block_head.count) {
3445 b_ptr += pst_decode_assoc(pf, &id2_rec, b_ptr); 3487 b_ptr += pst_decode_assoc(pf, &id2_rec, b_ptr);
3446 // memcpy(&id2_rec, &(buf[b_ptr]), sizeof(id2_rec)); 3488 DEBUG_INDEX(("\tid2 = %#x, id = %#llx, table2 = %#llx\n", id2_rec.id2, id2_rec.id, id2_rec.table2));
3447 // LE32_CPU(id2_rec.id2);
3448 // LE32_CPU(id2_rec.id);
3449 // LE32_CPU(id2_rec.table2);
3450 //
3451 // b_ptr += sizeof(id2_rec);
3452 DEBUG_INDEX(("\tid2 = %#llx, id = %#llx, table2 = %#llx\n", id2_rec.id2, id2_rec.id, id2_rec.table2));
3453 if ((i_ptr = pst_getID(pf, id2_rec.id)) == NULL) { 3489 if ((i_ptr = pst_getID(pf, id2_rec.id)) == NULL) {
3454 DEBUG_WARN(("\t\t%#llx - Not Found\n", id2_rec.id)); 3490 DEBUG_WARN(("\t\t%#llx - Not Found\n", id2_rec.id));
3455 } else { 3491 } else {
3456 DEBUG_INDEX(("\t\t%#llx - Offset %#llx, u1 %#llx, Size %lli(%#llx)\n", i_ptr->id, i_ptr->offset, i_ptr->u1, i_ptr->size, i_ptr->size)); 3492 DEBUG_INDEX(("\t\t%#llx - Offset %#llx, u1 %#llx, Size %lli(%#llx)\n", i_ptr->id, i_ptr->offset, i_ptr->u1, i_ptr->size, i_ptr->size));
3457 // add it to the linked list 3493 // add it to the linked list
3491 if (buf) free (buf); 3527 if (buf) free (buf);
3492 DEBUG_RET(); 3528 DEBUG_RET();
3493 return head; 3529 return head;
3494 } 3530 }
3495 3531
3496
3497 // This version of free does NULL check first
3498 #define SAFE_FREE(x) {if (x) free(x);}
3499 3532
3500 void pst_freeItem(pst_item *item) { 3533 void pst_freeItem(pst_item *item) {
3501 pst_item_attach *t; 3534 pst_item_attach *t;
3502 pst_item_extra_field *et; 3535 pst_item_extra_field *et;
3503 3536
4072 size_t pst_ff_getIDblock(pst_file *pf, uint64_t id, unsigned char** b) { 4105 size_t pst_ff_getIDblock(pst_file *pf, uint64_t id, unsigned char** b) {
4073 pst_index_ll *rec; 4106 pst_index_ll *rec;
4074 size_t rsize = 0; 4107 size_t rsize = 0;
4075 DEBUG_ENT("pst_ff_getIDblock"); 4108 DEBUG_ENT("pst_ff_getIDblock");
4076 if ((rec = pst_getID(pf, id)) == NULL) { 4109 if ((rec = pst_getID(pf, id)) == NULL) {
4077 DEBUG_INDEX(("Cannot find ID %#x\n", id)); 4110 DEBUG_INDEX(("Cannot find ID %#llx\n", id));
4078 DEBUG_RET(); 4111 DEBUG_RET();
4079 return 0; 4112 return 0;
4080 } 4113 }
4081 (void)fseek(pf->fp, rec->offset, SEEK_SET); 4114 (void)fseek(pf->fp, rec->offset, SEEK_SET);
4082 if (*b) { 4115 if (*b) {
4083 DEBUG_INDEX(("freeing old memory in b\n")); 4116 DEBUG_INDEX(("freeing old memory in b\n"));
4084 free(*b); 4117 free(*b);
4085 } 4118 }
4086 4119
4087 DEBUG_INDEX(("id = %#x, record size = %#x, offset = %#x\n", id, rec->size, rec->offset)); 4120 DEBUG_INDEX(("id = %#llx, record size = %#x, offset = %#x\n", id, rec->size, rec->offset));
4088 *b = (char*) xmalloc(rec->size+1); 4121 *b = (char*) xmalloc(rec->size+1);
4089 rsize = fread(*b, (size_t)1, rec->size, pf->fp); 4122 rsize = fread(*b, (size_t)1, rec->size, pf->fp);
4090 if (rsize != rec->size) { 4123 if (rsize != rec->size) {
4091 DEBUG_WARN(("Didn't read all the size. fread returned less [%i instead of %i]\n", rsize, rec->size)); 4124 DEBUG_WARN(("Didn't read all the size. fread returned less [%i instead of %i]\n", rsize, rec->size));
4092 if (feof(pf->fp)) { 4125 if (feof(pf->fp)) {
4357 return x; 4390 return x;
4358 } 4391 }
4359 4392
4360 4393
4361 char *pst_rfc2426_escape(char *str) { 4394 char *pst_rfc2426_escape(char *str) {
4362 static char* buf = NULL; 4395 static char* buf = NULL;
4396 static size_t buflen = 0;
4363 char *ret, *a, *b; 4397 char *ret, *a, *b;
4364 size_t x = 0; 4398 size_t x = 0;
4365 int y, z; 4399 int y, z;
4366 DEBUG_ENT("rfc2426_escape"); 4400 DEBUG_ENT("rfc2426_escape");
4367 if (!str) 4401 if (!str)
4377 if (y == 0 && z == 0) 4411 if (y == 0 && z == 0)
4378 // there isn't any extra space required 4412 // there isn't any extra space required
4379 ret = str; 4413 ret = str;
4380 else { 4414 else {
4381 x = strlen(str) + y - z + 1; // don't forget room for the NUL 4415 x = strlen(str) + y - z + 1; // don't forget room for the NUL
4382 buf = (char*) realloc(buf, x); 4416 if (x > buflen) {
4417 buf = (char*) realloc(buf, x);
4418 buflen = x;
4419 }
4383 a = str; 4420 a = str;
4384 b = buf; 4421 b = buf;
4385 while (*a != '\0') { 4422 while (*a != '\0') {
4386 switch (*a) { 4423 switch (*a) {
4387 case ',' : 4424 case ',' :