Mercurial > libpst
comparison src/libpst.c @ 49:17654fbdf76b
more fixes for 64 bit format
author | carl |
---|---|
date | Sat, 19 Jan 2008 10:47:16 -0800 |
parents | f66078abed38 |
children | fb3818370dd6 |
comparison
equal
deleted
inserted
replaced
48:f66078abed38 | 49:17654fbdf76b |
---|---|
28 # include <unistd.h> | 28 # include <unistd.h> |
29 #endif //ifdef _MSC_VER | 29 #endif //ifdef _MSC_VER |
30 | 30 |
31 #include "libpst.h" | 31 #include "libpst.h" |
32 #include "timeconv.h" | 32 #include "timeconv.h" |
33 //efine INDEX_DEPTH 0x4C | 33 |
34 //efine SECOND_DEPTH 0x5C | |
35 #define INDEX_TYPE32 0x0E | 34 #define INDEX_TYPE32 0x0E |
36 #define INDEX_TYPE64 0x17 | 35 #define INDEX_TYPE64 0x17 |
37 #define INDEX_TYPE_OFFSET (off_t)0x0A | 36 #define INDEX_TYPE_OFFSET (off_t)0x0A |
38 | 37 |
39 #define FILE_SIZE_POINTER32 (off_t)0xA8 | 38 #define FILE_SIZE_POINTER32 (off_t)0xA8 |
252 | 251 |
253 | 252 |
254 size_t pst_attach_to_mem(pst_file *pf, pst_item_attach *attach, unsigned char **b){ | 253 size_t pst_attach_to_mem(pst_file *pf, pst_item_attach *attach, unsigned char **b){ |
255 size_t size=0; | 254 size_t size=0; |
256 pst_index_ll *ptr; | 255 pst_index_ll *ptr; |
257 struct holder h = {b, NULL, 0, "", 0}; | 256 pst_holder h = {b, NULL, 0, "", 0}; |
258 DEBUG_ENT("pst_attach_to_mem"); | 257 DEBUG_ENT("pst_attach_to_mem"); |
259 if (attach->id_val != (uint64_t)-1) { | 258 if (attach->id_val != (uint64_t)-1) { |
260 ptr = pst_getID(pf, attach->id_val); | 259 ptr = pst_getID(pf, attach->id_val); |
261 if (ptr) { | 260 if (ptr) { |
262 size = pst_ff_getID2data(pf, ptr, &h); | 261 size = pst_ff_getID2data(pf, ptr, &h); |
273 } | 272 } |
274 | 273 |
275 | 274 |
276 size_t pst_attach_to_file(pst_file *pf, pst_item_attach *attach, FILE* fp) { | 275 size_t pst_attach_to_file(pst_file *pf, pst_item_attach *attach, FILE* fp) { |
277 pst_index_ll *ptr; | 276 pst_index_ll *ptr; |
278 struct holder h = {NULL, fp, 0, "", 0}; | 277 pst_holder h = {NULL, fp, 0, "", 0}; |
279 size_t size; | 278 size_t size; |
280 DEBUG_ENT("pst_attach_to_file"); | 279 DEBUG_ENT("pst_attach_to_file"); |
281 if (attach->id_val != (uint64_t)-1) { | 280 if (attach->id_val != (uint64_t)-1) { |
282 ptr = pst_getID(pf, attach->id_val); | 281 ptr = pst_getID(pf, attach->id_val); |
283 if (ptr) { | 282 if (ptr) { |
297 } | 296 } |
298 | 297 |
299 | 298 |
300 size_t pst_attach_to_file_base64(pst_file *pf, pst_item_attach *attach, FILE* fp) { | 299 size_t pst_attach_to_file_base64(pst_file *pf, pst_item_attach *attach, FILE* fp) { |
301 pst_index_ll *ptr; | 300 pst_index_ll *ptr; |
302 struct holder h = {NULL, fp, 1, "", 0}; | 301 pst_holder h = {NULL, fp, 1, "", 0}; |
303 size_t size; | 302 size_t size; |
304 char *c; | 303 char *c; |
305 DEBUG_ENT("pst_attach_to_file_base64"); | 304 DEBUG_ENT("pst_attach_to_file_base64"); |
306 if (attach->id_val != (uint64_t)-1) { | 305 if (attach->id_val != (uint64_t)-1) { |
307 ptr = pst_getID(pf, attach->id_val); | 306 ptr = pst_getID(pf, attach->id_val); |
1251 DEBUG_RET(); | 1250 DEBUG_RET(); |
1252 return item; | 1251 return item; |
1253 } | 1252 } |
1254 | 1253 |
1255 | 1254 |
1256 static void freeall(unsigned char *buf, pst_block_offset_pointer *p1, | 1255 static void freeall(pst_subblocks *subs, pst_block_offset_pointer *p1, |
1257 pst_block_offset_pointer *p2, | 1256 pst_block_offset_pointer *p2, |
1258 pst_block_offset_pointer *p3, | 1257 pst_block_offset_pointer *p3, |
1259 pst_block_offset_pointer *p4, | 1258 pst_block_offset_pointer *p4, |
1260 pst_block_offset_pointer *p5, | 1259 pst_block_offset_pointer *p5, |
1261 pst_block_offset_pointer *p6, | 1260 pst_block_offset_pointer *p6, |
1262 pst_block_offset_pointer *p7); | 1261 pst_block_offset_pointer *p7); |
1263 static void freeall(unsigned char *buf, pst_block_offset_pointer *p1, | 1262 static void freeall(pst_subblocks *subs, pst_block_offset_pointer *p1, |
1264 pst_block_offset_pointer *p2, | 1263 pst_block_offset_pointer *p2, |
1265 pst_block_offset_pointer *p3, | 1264 pst_block_offset_pointer *p3, |
1266 pst_block_offset_pointer *p4, | 1265 pst_block_offset_pointer *p4, |
1267 pst_block_offset_pointer *p5, | 1266 pst_block_offset_pointer *p5, |
1268 pst_block_offset_pointer *p6, | 1267 pst_block_offset_pointer *p6, |
1269 pst_block_offset_pointer *p7) { | 1268 pst_block_offset_pointer *p7) { |
1270 if (buf) free(buf); | 1269 size_t i; |
1270 for (i=0; i<subs->subblock_count; i++) { | |
1271 if (subs->subs[i].buf) free(subs->subs[i].buf); | |
1272 } | |
1273 free(subs->subs); | |
1271 if (p1->needfree) free(p1->from); | 1274 if (p1->needfree) free(p1->from); |
1272 if (p2->needfree) free(p2->from); | 1275 if (p2->needfree) free(p2->from); |
1273 if (p3->needfree) free(p3->from); | 1276 if (p3->needfree) free(p3->from); |
1274 if (p4->needfree) free(p4->from); | 1277 if (p4->needfree) free(p4->from); |
1275 if (p5->needfree) free(p5->from); | 1278 if (p5->needfree) free(p5->from); |
1278 } | 1281 } |
1279 | 1282 |
1280 | 1283 |
1281 pst_num_array * pst_parse_block(pst_file *pf, uint64_t block_id, pst_index2_ll *i2_head, pst_num_array *na_head) { | 1284 pst_num_array * pst_parse_block(pst_file *pf, uint64_t block_id, pst_index2_ll *i2_head, pst_num_array *na_head) { |
1282 unsigned char *buf = NULL; | 1285 unsigned char *buf = NULL; |
1286 size_t read_size = 0; | |
1287 pst_subblocks subblocks; | |
1283 pst_num_array *na_ptr = NULL; | 1288 pst_num_array *na_ptr = NULL; |
1284 pst_block_offset_pointer block_offset1; | 1289 pst_block_offset_pointer block_offset1; |
1285 pst_block_offset_pointer block_offset2; | 1290 pst_block_offset_pointer block_offset2; |
1286 pst_block_offset_pointer block_offset3; | 1291 pst_block_offset_pointer block_offset3; |
1287 pst_block_offset_pointer block_offset4; | 1292 pst_block_offset_pointer block_offset4; |
1293 int count_rec; | 1298 int count_rec; |
1294 int32_t num_list; | 1299 int32_t num_list; |
1295 int32_t cur_list; | 1300 int32_t cur_list; |
1296 int block_type; | 1301 int block_type; |
1297 uint32_t rec_size = 0; | 1302 uint32_t rec_size = 0; |
1298 uint32_t ind_ptr; | |
1299 unsigned char* list_start; | 1303 unsigned char* list_start; |
1300 unsigned char* fr_ptr; | 1304 unsigned char* fr_ptr; |
1301 unsigned char* to_ptr; | 1305 unsigned char* to_ptr; |
1302 unsigned char* ind2_end = NULL; | 1306 unsigned char* ind2_end = NULL; |
1303 unsigned char* ind2_ptr = NULL; | 1307 unsigned char* ind2_ptr = NULL; |
1304 size_t read_size=0; | |
1305 pst_x_attrib_ll *mapptr; | 1308 pst_x_attrib_ll *mapptr; |
1306 | 1309 |
1307 struct { | 1310 struct { |
1308 uint16_t index_offset; | 1311 uint16_t index_offset; |
1309 uint16_t type; | 1312 uint16_t type; |
1364 LE16_CPU(block_hdr.index_offset); | 1367 LE16_CPU(block_hdr.index_offset); |
1365 LE16_CPU(block_hdr.type); | 1368 LE16_CPU(block_hdr.type); |
1366 LE32_CPU(block_hdr.offset); | 1369 LE32_CPU(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)); | 1370 DEBUG_EMAIL(("block header (index_offset=%#hx, type=%#hx, offset=%#hx)\n", block_hdr.index_offset, block_hdr.type, block_hdr.offset)); |
1368 | 1371 |
1369 ind_ptr = block_hdr.index_offset; | 1372 if (block_hdr.index_offset == (uint16_t)0x0101) { //type 3 |
1373 subblocks.subblock_count = block_hdr.type; | |
1374 subblocks.subs = malloc(sizeof(pst_subblock) * subblocks.subblock_count); | |
1375 size_t i; | |
1376 char *b_ptr = buf + 8; | |
1377 for (i=0; i<subblocks.subblock_count; i++) { | |
1378 b_ptr += pst_decode_type3(pf, &table3_rec, b_ptr); | |
1379 subblocks.subs[i].buf = NULL; | |
1380 subblocks.subs[i].read_size = pst_ff_getIDblock_dec(pf, table3_rec.id, &subblocks.subs[i].buf); | |
1381 if (subblocks.subs[i].buf) { | |
1382 memcpy(&block_hdr, subblocks.subs[i].buf, sizeof(block_hdr)); | |
1383 LE16_CPU(block_hdr.index_offset); | |
1384 subblocks.subs[i].i_offset = block_hdr.index_offset; | |
1385 } | |
1386 else { | |
1387 subblocks.subs[i].read_size = 0; | |
1388 subblocks.subs[i].i_offset = 0; | |
1389 } | |
1390 } | |
1391 free(buf); | |
1392 memcpy(&block_hdr, subblocks.subs[0].buf, sizeof(block_hdr)); | |
1393 LE16_CPU(block_hdr.index_offset); | |
1394 LE16_CPU(block_hdr.type); | |
1395 LE32_CPU(block_hdr.offset); | |
1396 DEBUG_EMAIL(("block header (index_offset=%#hx, type=%#hx, offset=%#hx)\n", block_hdr.index_offset, block_hdr.type, block_hdr.offset)); | |
1397 } | |
1398 else { | |
1399 // setup the subblock descriptors, but we only have one block | |
1400 subblocks.subblock_count = 1; | |
1401 subblocks.subs = malloc(sizeof(pst_subblock)); | |
1402 subblocks.subs[0].buf = buf; | |
1403 subblocks.subs[0].read_size = read_size; | |
1404 subblocks.subs[0].i_offset = block_hdr.index_offset; | |
1405 } | |
1370 | 1406 |
1371 if (block_hdr.type == (uint16_t)0xBCEC) { //type 1 | 1407 if (block_hdr.type == (uint16_t)0xBCEC) { //type 1 |
1372 block_type = 1; | 1408 block_type = 1; |
1373 | 1409 |
1374 if (pst_getBlockOffsetPointer(pf, i2_head, buf, read_size, ind_ptr, block_hdr.offset, &block_offset1)) { | 1410 if (pst_getBlockOffsetPointer(pf, i2_head, &subblocks, block_hdr.offset, &block_offset1)) { |
1375 DEBUG_WARN(("internal error (bc.b5 offset %#x) in reading block id %#x\n", block_hdr.offset, block_id)); | 1411 DEBUG_WARN(("internal error (bc.b5 offset %#x) in reading block id %#x\n", block_hdr.offset, block_id)); |
1376 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); | 1412 freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); |
1377 DEBUG_RET(); | 1413 DEBUG_RET(); |
1378 return NULL; | 1414 return NULL; |
1379 } | 1415 } |
1380 memcpy(&table_rec, block_offset1.from, sizeof(table_rec)); | 1416 memcpy(&table_rec, block_offset1.from, sizeof(table_rec)); |
1381 LE16_CPU(table_rec.type); | 1417 LE16_CPU(table_rec.type); |
1384 DEBUG_EMAIL(("table_rec (type=%#hx, ref_type=%#hx, value=%#x)\n", table_rec.type, table_rec.ref_type, table_rec.value)); | 1420 DEBUG_EMAIL(("table_rec (type=%#hx, ref_type=%#hx, value=%#x)\n", table_rec.type, table_rec.ref_type, table_rec.value)); |
1385 | 1421 |
1386 if (table_rec.type != (uint16_t)0x02B5) { | 1422 if (table_rec.type != (uint16_t)0x02B5) { |
1387 WARN(("Unknown second block constant - %#hx for id %#llx\n", table_rec.type, block_id)); | 1423 WARN(("Unknown second block constant - %#hx for id %#llx\n", table_rec.type, block_id)); |
1388 DEBUG_HEXDUMPC(buf, sizeof(table_rec), 0x10); | 1424 DEBUG_HEXDUMPC(buf, sizeof(table_rec), 0x10); |
1389 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); | 1425 freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); |
1390 DEBUG_RET(); | 1426 DEBUG_RET(); |
1391 return NULL; | 1427 return NULL; |
1392 } | 1428 } |
1393 | 1429 |
1394 if (pst_getBlockOffsetPointer(pf, i2_head, buf, read_size, ind_ptr, table_rec.value, &block_offset2)) { | 1430 if (pst_getBlockOffsetPointer(pf, i2_head, &subblocks, table_rec.value, &block_offset2)) { |
1395 DEBUG_WARN(("internal error (bc.b5.desc offset) in reading block id %#x\n", table_rec.value, block_id)); | 1431 DEBUG_WARN(("internal error (bc.b5.desc offset) in reading block id %#x\n", table_rec.value, block_id)); |
1396 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); | 1432 freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); |
1397 DEBUG_RET(); | 1433 DEBUG_RET(); |
1398 return NULL; | 1434 return NULL; |
1399 } | 1435 } |
1400 list_start = block_offset2.from; | 1436 list_start = block_offset2.from; |
1401 to_ptr = block_offset2.to; | 1437 to_ptr = block_offset2.to; |
1403 num_recs = 1; // only going to be one object in these blocks | 1439 num_recs = 1; // only going to be one object in these blocks |
1404 } | 1440 } |
1405 else if (block_hdr.type == (uint16_t)0x7CEC) { //type 2 | 1441 else if (block_hdr.type == (uint16_t)0x7CEC) { //type 2 |
1406 block_type = 2; | 1442 block_type = 2; |
1407 | 1443 |
1408 if (pst_getBlockOffsetPointer(pf, i2_head, buf, read_size, ind_ptr, block_hdr.offset, &block_offset3)) { | 1444 if (pst_getBlockOffsetPointer(pf, i2_head, &subblocks, block_hdr.offset, &block_offset3)) { |
1409 DEBUG_WARN(("internal error (7c.7c offset %#x) in reading block id %#x\n", block_hdr.offset, block_id)); | 1445 DEBUG_WARN(("internal error (7c.7c offset %#x) in reading block id %#x\n", block_hdr.offset, block_id)); |
1410 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); | 1446 freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); |
1411 DEBUG_RET(); | 1447 DEBUG_RET(); |
1412 return NULL; | 1448 return NULL; |
1413 } | 1449 } |
1414 fr_ptr = block_offset3.from; //now got pointer to "7C block" | 1450 fr_ptr = block_offset3.from; //now got pointer to "7C block" |
1415 memset(&seven_c_blk, 0, sizeof(seven_c_blk)); | 1451 memset(&seven_c_blk, 0, sizeof(seven_c_blk)); |
1425 | 1461 |
1426 list_start = fr_ptr + sizeof(seven_c_blk); // the list of item numbers start after this record | 1462 list_start = fr_ptr + sizeof(seven_c_blk); // the list of item numbers start after this record |
1427 | 1463 |
1428 if (seven_c_blk.seven_c != 0x7C) { // this would mean it isn't a 7C block! | 1464 if (seven_c_blk.seven_c != 0x7C) { // this would mean it isn't a 7C block! |
1429 WARN(("Error. There isn't a 7C where I want to see 7C!\n")); | 1465 WARN(("Error. There isn't a 7C where I want to see 7C!\n")); |
1430 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); | 1466 freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); |
1431 DEBUG_RET(); | 1467 DEBUG_RET(); |
1432 return NULL; | 1468 return NULL; |
1433 } | 1469 } |
1434 | 1470 |
1435 rec_size = seven_c_blk.rec_size; | 1471 rec_size = seven_c_blk.rec_size; |
1436 num_list = (int32_t)(unsigned)seven_c_blk.item_count; | 1472 num_list = (int32_t)(unsigned)seven_c_blk.item_count; |
1437 | 1473 |
1438 if (pst_getBlockOffsetPointer(pf, i2_head, buf, read_size, ind_ptr, seven_c_blk.b_five_offset, &block_offset4)) { | 1474 if (pst_getBlockOffsetPointer(pf, i2_head, &subblocks, seven_c_blk.b_five_offset, &block_offset4)) { |
1439 DEBUG_WARN(("internal error (7c.b5 offset %#x) in reading block id %#x\n", seven_c_blk.b_five_offset, block_id)); | 1475 DEBUG_WARN(("internal error (7c.b5 offset %#x) in reading block id %#x\n", seven_c_blk.b_five_offset, block_id)); |
1440 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); | 1476 freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); |
1441 DEBUG_RET(); | 1477 DEBUG_RET(); |
1442 return NULL; | 1478 return NULL; |
1443 } | 1479 } |
1444 memcpy(&table_rec, block_offset4.from, sizeof(table_rec)); | 1480 memcpy(&table_rec, block_offset4.from, sizeof(table_rec)); |
1445 LE16_CPU(table_rec.type); | 1481 LE16_CPU(table_rec.type); |
1446 LE16_CPU(table_rec.ref_type); | 1482 LE16_CPU(table_rec.ref_type); |
1447 LE32_CPU(table_rec.value); | 1483 LE32_CPU(table_rec.value); |
1448 | 1484 |
1449 if (table_rec.type != (uint16_t)0x04B5) { // different constant than a type 1 record | 1485 if (table_rec.type != (uint16_t)0x04B5) { // different constant than a type 1 record |
1450 WARN(("Unknown second block constant - %#hx for id %#llx\n", table_rec.type, block_id)); | 1486 WARN(("Unknown second block constant - %#hx for id %#llx\n", table_rec.type, block_id)); |
1451 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); | 1487 freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); |
1452 DEBUG_RET(); | 1488 DEBUG_RET(); |
1453 return NULL; | 1489 return NULL; |
1454 } | 1490 } |
1455 | 1491 |
1456 if (pst_getBlockOffsetPointer(pf, i2_head, buf, read_size, ind_ptr, table_rec.value, &block_offset5)) { | 1492 if (pst_getBlockOffsetPointer(pf, i2_head, &subblocks, table_rec.value, &block_offset5)) { |
1457 DEBUG_WARN(("internal error (7c.5b.desc offset %#x) in reading block id %#llx\n", table_rec.value, block_id)); | 1493 DEBUG_WARN(("internal error (7c.5b.desc offset %#x) in reading block id %#llx\n", table_rec.value, block_id)); |
1458 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); | 1494 freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); |
1459 DEBUG_RET(); | 1495 DEBUG_RET(); |
1460 return NULL; | 1496 return NULL; |
1461 } | 1497 } |
1462 num_recs = (block_offset5.to - block_offset5.from) / 6; // this will give the number of records in this block | 1498 num_recs = (block_offset5.to - block_offset5.from) / 6; // this will give the number of records in this block |
1463 | 1499 |
1464 if (pst_getBlockOffsetPointer(pf, i2_head, buf, read_size, ind_ptr, seven_c_blk.ind2_offset, &block_offset6)) { | 1500 if (pst_getBlockOffsetPointer(pf, i2_head, &subblocks, seven_c_blk.ind2_offset, &block_offset6)) { |
1465 DEBUG_WARN(("internal error (7c.ind2 offset %#x) in reading block id %#x\n", seven_c_blk.ind2_offset, block_id)); | 1501 DEBUG_WARN(("internal error (7c.ind2 offset %#x) in reading block id %#x\n", seven_c_blk.ind2_offset, block_id)); |
1466 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); | 1502 freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); |
1467 DEBUG_RET(); | 1503 DEBUG_RET(); |
1468 return NULL; | 1504 return NULL; |
1469 } | 1505 } |
1470 ind2_ptr = block_offset6.from; | 1506 ind2_ptr = block_offset6.from; |
1471 ind2_end = block_offset6.to; | 1507 ind2_end = block_offset6.to; |
1472 } | 1508 } |
1473 else if (block_hdr.index_offset == (uint16_t)0x0101) { //type 3 | 1509 else { |
1474 unsigned char *buf2 = NULL; | |
1475 uint16_t n = block_hdr.type; // count | |
1476 uint16_t i; | |
1477 block_type = 3; | |
1478 char *b_ptr = buf + 8; | |
1479 for (i=0; i<n; i++) { | |
1480 b_ptr += pst_decode_type3(pf, &table3_rec, b_ptr); | |
1481 //(void)pst_ff_getIDblock_dec(pf, table3_rec.id, &buf2); | |
1482 //if (buf2) free(buf2); | |
1483 //buf2 = NULL; | |
1484 na_head = pst_parse_block(pf, table3_rec.id, i2_head, na_head); // !! this is still not correct | |
1485 } | |
1486 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); | |
1487 DEBUG_RET(); | |
1488 return na_head; | |
1489 } else { | |
1490 WARN(("ERROR: Unknown block constant - %#hx for id %#llx\n", block_hdr.type, block_id)); | 1510 WARN(("ERROR: Unknown block constant - %#hx for id %#llx\n", block_hdr.type, block_id)); |
1491 DEBUG_HEXDUMPC(buf, read_size,0x10); | 1511 DEBUG_HEXDUMPC(buf, read_size,0x10); |
1492 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); | 1512 freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); |
1493 DEBUG_RET(); | 1513 DEBUG_RET(); |
1494 return NULL; | 1514 return NULL; |
1495 } | 1515 } |
1496 | 1516 |
1497 DEBUG_EMAIL(("Mallocing number of records %i\n", num_recs)); | 1517 DEBUG_EMAIL(("Mallocing number of records %i\n", num_recs)); |
1498 for (count_rec=0; count_rec<num_recs; count_rec++) { | 1518 for (count_rec=0; count_rec<num_recs; count_rec++) { |
1499 na_ptr = (pst_num_array*) xmalloc(sizeof(pst_num_array)); | 1519 na_ptr = (pst_num_array*) xmalloc(sizeof(pst_num_array)); |
1500 memset(na_ptr, 0, sizeof(pst_num_array)); | 1520 memset(na_ptr, 0, sizeof(pst_num_array)); |
1501 na_ptr->next = na_head; | 1521 na_ptr->next = na_head; |
1502 na_head = na_ptr; | 1522 na_head = na_ptr; |
1503 // allocate an array of count num_recs to contain sizeof(struct pst_num_item) | 1523 // allocate an array of count num_recs to contain sizeof(pst_num_item) |
1504 na_ptr->items = (struct pst_num_item**) xmalloc(sizeof(struct pst_num_item)*num_list); | 1524 na_ptr->items = (pst_num_item**) xmalloc(sizeof(pst_num_item)*num_list); |
1505 na_ptr->count_item = num_list; | 1525 na_ptr->count_item = num_list; |
1506 na_ptr->orig_count = num_list; | 1526 na_ptr->orig_count = num_list; |
1507 na_ptr->count_array = (int32_t)num_recs; // each record will have a record of the total number of records | 1527 na_ptr->count_array = (int32_t)num_recs; // each record will have a record of the total number of records |
1508 for (x=0; x<num_list; x++) na_ptr->items[x] = NULL; | 1528 for (x=0; x<num_list; x++) na_ptr->items[x] = NULL; |
1509 x = 0; | 1529 x = 0; |
1548 read_size, ind2_end-ind2_ptr+table2_rec.ind2_off, table2_rec.size)); | 1568 read_size, ind2_end-ind2_ptr+table2_rec.ind2_off, table2_rec.size)); |
1549 } | 1569 } |
1550 fr_ptr += sizeof(table2_rec); | 1570 fr_ptr += sizeof(table2_rec); |
1551 } else { | 1571 } else { |
1552 WARN(("Missing code for block_type %i\n", block_type)); | 1572 WARN(("Missing code for block_type %i\n", block_type)); |
1553 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); | 1573 freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); |
1554 if (na_head) pst_free_list(na_head); | 1574 if (na_head) pst_free_list(na_head); |
1555 DEBUG_RET(); | 1575 DEBUG_RET(); |
1556 return NULL; | 1576 return NULL; |
1557 } | 1577 } |
1558 DEBUG_EMAIL(("reading block %i (type=%#x, ref_type=%#x, value=%#x)\n", | 1578 DEBUG_EMAIL(("reading block %i (type=%#x, ref_type=%#x, value=%#x)\n", |
1559 x, table_rec.type, table_rec.ref_type, table_rec.value)); | 1579 x, table_rec.type, table_rec.ref_type, table_rec.value)); |
1560 | 1580 |
1561 if (!na_ptr->items[x]) { | 1581 if (!na_ptr->items[x]) { |
1562 na_ptr->items[x] = (struct pst_num_item*) xmalloc(sizeof(struct pst_num_item)); | 1582 na_ptr->items[x] = (pst_num_item*) xmalloc(sizeof(pst_num_item)); |
1563 } | 1583 } |
1564 memset(na_ptr->items[x], 0, sizeof(struct pst_num_item)); //init it | 1584 memset(na_ptr->items[x], 0, sizeof(pst_num_item)); //init it |
1565 | 1585 |
1566 // check here to see if the id of the attribute is a mapped one | 1586 // check here to see if the id of the attribute is a mapped one |
1567 mapptr = pf->x_head; | 1587 mapptr = pf->x_head; |
1568 while (mapptr && (mapptr->map < table_rec.type)) mapptr = mapptr->next; | 1588 while (mapptr && (mapptr->map < table_rec.type)) mapptr = mapptr->next; |
1569 if (mapptr && (mapptr->map == table_rec.type)) { | 1589 if (mapptr && (mapptr->map == table_rec.type)) { |
1633 na_ptr->items[x]->size = value_size; | 1653 na_ptr->items[x]->size = value_size; |
1634 na_ptr->items[x]->type = table_rec.ref_type; | 1654 na_ptr->items[x]->type = table_rec.ref_type; |
1635 na_ptr->items[x]->data = xmalloc(value_size); | 1655 na_ptr->items[x]->data = xmalloc(value_size); |
1636 memcpy(na_ptr->items[x]->data, value_pointer, value_size); | 1656 memcpy(na_ptr->items[x]->data, value_pointer, value_size); |
1637 } | 1657 } |
1638 else if (pst_getBlockOffsetPointer(pf, i2_head, buf, read_size, ind_ptr, table_rec.value, &block_offset7)) { | 1658 else if (pst_getBlockOffsetPointer(pf, i2_head, &subblocks, table_rec.value, &block_offset7)) { |
1639 if ((table_rec.value & 0xf) == (uint32_t)0xf) { | 1659 if ((table_rec.value & 0xf) == (uint32_t)0xf) { |
1640 DEBUG_WARN(("failed to get block offset for table_rec.value of %#x to be read later.\n", table_rec.value)); | 1660 DEBUG_WARN(("failed to get block offset for table_rec.value of %#x to be read later.\n", table_rec.value)); |
1641 na_ptr->items[x]->size = 0; | 1661 na_ptr->items[x]->size = 0; |
1642 na_ptr->items[x]->data = NULL; | 1662 na_ptr->items[x]->data = NULL; |
1643 na_ptr->items[x]->type = table_rec.value; | 1663 na_ptr->items[x]->type = table_rec.value; |
1695 DEBUG_HEXDUMPC(na_ptr->items[x]->data, na_ptr->items[x]->size, 0x10); | 1715 DEBUG_HEXDUMPC(na_ptr->items[x]->data, na_ptr->items[x]->size, 0x10); |
1696 } | 1716 } |
1697 if (na_ptr->items[x]->type == 0) na_ptr->items[x]->type = table_rec.ref_type; | 1717 if (na_ptr->items[x]->type == 0) na_ptr->items[x]->type = table_rec.ref_type; |
1698 } else { | 1718 } else { |
1699 WARN(("ERROR Unknown ref_type %#hx\n", table_rec.ref_type)); | 1719 WARN(("ERROR Unknown ref_type %#hx\n", table_rec.ref_type)); |
1700 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); | 1720 freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); |
1701 if (na_head) pst_free_list(na_head); | 1721 if (na_head) pst_free_list(na_head); |
1702 DEBUG_RET(); | 1722 DEBUG_RET(); |
1703 return NULL; | 1723 return NULL; |
1704 } | 1724 } |
1705 x++; | 1725 x++; |
1706 } | 1726 } |
1707 DEBUG_EMAIL(("increasing ind2_ptr by %i [%#x] bytes. Was %#x, Now %#x\n", rec_size, rec_size, ind2_ptr, ind2_ptr+rec_size)); | 1727 DEBUG_EMAIL(("increasing ind2_ptr by %i [%#x] bytes. Was %#x, Now %#x\n", rec_size, rec_size, ind2_ptr, ind2_ptr+rec_size)); |
1708 ind2_ptr += rec_size; | 1728 ind2_ptr += rec_size; |
1709 } | 1729 } |
1710 freeall(buf, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); | 1730 freeall(&subblocks, &block_offset1, &block_offset2, &block_offset3, &block_offset4, &block_offset5, &block_offset6, &block_offset7); |
1711 DEBUG_RET(); | 1731 DEBUG_RET(); |
1712 return na_head; | 1732 return na_head; |
1713 } | 1733 } |
1714 | 1734 |
1715 // This version of free does NULL check first | 1735 // This version of free does NULL check first |
1779 DEBUG_EMAIL(("#%d - id: %#x type: %#x length: %#x\n", x, list->items[x]->id, list->items[x]->type, list->items[x]->size)); | 1799 DEBUG_EMAIL(("#%d - id: %#x type: %#x length: %#x\n", x, list->items[x]->id, list->items[x]->type, list->items[x]->size)); |
1780 | 1800 |
1781 switch (list->items[x]->id) { | 1801 switch (list->items[x]->id) { |
1782 case PST_ATTRIB_HEADER: // CUSTOM attribute for saying the Extra Headers | 1802 case PST_ATTRIB_HEADER: // CUSTOM attribute for saying the Extra Headers |
1783 DEBUG_EMAIL(("Extra Field - ")); | 1803 DEBUG_EMAIL(("Extra Field - ")); |
1784 ef = (pst_item_extra_field*) xmalloc(sizeof(pst_item_extra_field)); | 1804 if (list->items[x]->extra) { |
1785 memset(ef, 0, sizeof(pst_item_extra_field)); | 1805 ef = (pst_item_extra_field*) xmalloc(sizeof(pst_item_extra_field)); |
1786 ef->field_name = (char*) xmalloc(strlen(list->items[x]->extra)+1); | 1806 memset(ef, 0, sizeof(pst_item_extra_field)); |
1787 strcpy(ef->field_name, list->items[x]->extra); | 1807 ef->field_name = (char*) xmalloc(strlen(list->items[x]->extra)+1); |
1788 LIST_COPY(ef->value, (char*)); | 1808 strcpy(ef->field_name, list->items[x]->extra); |
1789 ef->next = item->extra_fields; | 1809 LIST_COPY(ef->value, (char*)); |
1790 item->extra_fields = ef; | 1810 ef->next = item->extra_fields; |
1791 DEBUG_EMAIL(("\"%s\" = \"%s\"\n", ef->field_name, ef->value)); | 1811 item->extra_fields = ef; |
1812 DEBUG_EMAIL(("\"%s\" = \"%s\"\n", ef->field_name, ef->value)); | |
1813 } | |
1814 else { | |
1815 DEBUG_EMAIL(("NULL extra field\n")); | |
1816 } | |
1792 break; | 1817 break; |
1793 case 0x0002: // PR_ALTERNATE_RECIPIENT_ALLOWED | 1818 case 0x0002: // PR_ALTERNATE_RECIPIENT_ALLOWED |
1794 // If set to true, the sender allows this email to be autoforwarded | 1819 // If set to true, the sender allows this email to be autoforwarded |
1795 DEBUG_EMAIL(("AutoForward allowed - ")); | 1820 DEBUG_EMAIL(("AutoForward allowed - ")); |
1796 MALLOC_EMAIL(item); | 1821 MALLOC_EMAIL(item); |
3720 | 3745 |
3721 | 3746 |
3722 /** | 3747 /** |
3723 * The offset might be zero, in which case we have no data, so return a pair of null pointers. | 3748 * The offset might be zero, in which case we have no data, so return a pair of null pointers. |
3724 * Or, the offset might end in 0xf, so it is an id2 pointer, in which case we read the id2 block. | 3749 * Or, the offset might end in 0xf, so it is an id2 pointer, in which case we read the id2 block. |
3725 * Otherwise, the offset>>4 is an index into the table of offsets in the buffer. | 3750 * Otherwise, the high order 16 bits of offset is the index into the subblocks, and |
3751 * the (low order 16 bits of offset)>>4 is an index into the table of offsets in the subblock. | |
3726 */ | 3752 */ |
3727 int pst_getBlockOffsetPointer(pst_file *pf, pst_index2_ll *i2_head, unsigned char *buf, size_t read_size, uint32_t i_offset, uint32_t offset, pst_block_offset_pointer *p) { | 3753 int pst_getBlockOffsetPointer(pst_file *pf, pst_index2_ll *i2_head, pst_subblocks *subblocks, uint32_t offset, pst_block_offset_pointer *p) { |
3728 size_t size; | 3754 size_t size; |
3729 pst_block_offset block_offset; | 3755 pst_block_offset block_offset; |
3730 DEBUG_ENT("pst_getBlockOffsetPointer"); | 3756 DEBUG_ENT("pst_getBlockOffsetPointer"); |
3731 if (p->needfree) free(p->from); | 3757 if (p->needfree) free(p->from); |
3732 p->from = NULL; | 3758 p->from = NULL; |
3759 p->to = NULL; | |
3733 p->needfree = 0; | 3760 p->needfree = 0; |
3734 if (!offset) { | 3761 if (!offset) { |
3762 // no data | |
3735 p->from = p->to = NULL; | 3763 p->from = p->to = NULL; |
3736 } | 3764 } |
3737 else if ((offset & 0xf) == (uint32_t)0xf) { | 3765 else if ((offset & 0xf) == (uint32_t)0xf) { |
3766 // external index reference | |
3738 DEBUG_WARN(("Found id2 %#x value. Will follow it\n", offset)); | 3767 DEBUG_WARN(("Found id2 %#x value. Will follow it\n", offset)); |
3739 size = pst_ff_getID2block(pf, offset, i2_head, &(p->from)); | 3768 size = pst_ff_getID2block(pf, offset, i2_head, &(p->from)); |
3740 if (size) { | 3769 if (size) { |
3741 p->to = p->from + size; | 3770 p->to = p->from + size; |
3742 p->needfree = 1; | 3771 p->needfree = 1; |
3743 } | 3772 } |
3744 else { | 3773 else { |
3745 p->from = p->to = NULL; | 3774 p->from = p->to = NULL; |
3746 } | 3775 } |
3747 } | 3776 } |
3748 else if (pst_getBlockOffset(buf, read_size, i_offset, offset, &block_offset)) { | |
3749 p->from = p->to = NULL; | |
3750 } | |
3751 else { | 3777 else { |
3752 p->from = buf + block_offset.from; | 3778 // internal index reference |
3753 p->to = buf + block_offset.to; | 3779 size_t subindex = offset >> 16; |
3780 size_t suboffset = offset & 0xffff; | |
3781 if (subindex < subblocks->subblock_count) { | |
3782 if (pst_getBlockOffset(subblocks->subs[subindex].buf, | |
3783 subblocks->subs[subindex].read_size, | |
3784 subblocks->subs[subindex].i_offset, | |
3785 suboffset, &block_offset)) { | |
3786 p->from = subblocks->subs[subindex].buf + block_offset.from; | |
3787 p->to = subblocks->subs[subindex].buf + block_offset.to; | |
3788 } | |
3789 } | |
3754 } | 3790 } |
3755 DEBUG_RET(); | 3791 DEBUG_RET(); |
3756 return (p->from) ? 0 : 1; | 3792 return (p->from) ? 0 : 1; |
3757 } | 3793 } |
3758 | 3794 |
3762 uint32_t of1 = offset >> 4; | 3798 uint32_t of1 = offset >> 4; |
3763 DEBUG_ENT("pst_getBlockOffset"); | 3799 DEBUG_ENT("pst_getBlockOffset"); |
3764 if (!p || !buf || !i_offset || low || (i_offset+2+of1+sizeof(*p) > read_size)) { | 3800 if (!p || !buf || !i_offset || low || (i_offset+2+of1+sizeof(*p) > read_size)) { |
3765 DEBUG_WARN(("p is NULL or buf is NULL or offset is 0 or offset has low bits or beyond read size (%p, %p, %#x, %i, %i)\n", p, buf, offset, read_size, i_offset)); | 3801 DEBUG_WARN(("p is NULL or buf is NULL or offset is 0 or offset has low bits or beyond read size (%p, %p, %#x, %i, %i)\n", p, buf, offset, read_size, i_offset)); |
3766 DEBUG_RET(); | 3802 DEBUG_RET(); |
3767 return -1; | 3803 return 0; |
3768 } | 3804 } |
3769 memcpy(&(p->from), &(buf[(i_offset+2)+of1]), sizeof(p->from)); | 3805 memcpy(&(p->from), &(buf[(i_offset+2)+of1]), sizeof(p->from)); |
3770 memcpy(&(p->to), &(buf[(i_offset+2)+of1+sizeof(p->from)]), sizeof(p->to)); | 3806 memcpy(&(p->to), &(buf[(i_offset+2)+of1+sizeof(p->from)]), sizeof(p->to)); |
3771 LE16_CPU(p->from); | 3807 LE16_CPU(p->from); |
3772 LE16_CPU(p->to); | 3808 LE16_CPU(p->to); |
3773 DEBUG_WARN(("get block offset finds from=%i(%#x), to=%i(%#x)\n", p->from, p->from, p->to, p->to)); | 3809 DEBUG_WARN(("get block offset finds from=%i(%#x), to=%i(%#x)\n", p->from, p->from, p->to, p->to)); |
3774 if (p->from > p->to) { | 3810 if (p->from > p->to) { |
3775 DEBUG_WARN(("get block offset from > to")); | 3811 DEBUG_WARN(("get block offset from > to")); |
3776 return -1; | 3812 return 0; |
3777 } | 3813 } |
3778 DEBUG_RET(); | 3814 DEBUG_RET(); |
3779 return 0; | 3815 return 1; |
3780 } | 3816 } |
3781 | 3817 |
3782 | 3818 |
3783 pst_index_ll* pst_getID(pst_file* pf, uint64_t id) { | 3819 pst_index_ll* pst_getID(pst_file* pf, uint64_t id) { |
3784 pst_index_ll *ptr = NULL; | 3820 pst_index_ll *ptr = NULL; |
4136 | 4172 |
4137 | 4173 |
4138 #define PST_PTR_BLOCK_SIZE 0x120 | 4174 #define PST_PTR_BLOCK_SIZE 0x120 |
4139 size_t pst_ff_getID2block(pst_file *pf, uint64_t id2, pst_index2_ll *id2_head, unsigned char** buf) { | 4175 size_t pst_ff_getID2block(pst_file *pf, uint64_t id2, pst_index2_ll *id2_head, unsigned char** buf) { |
4140 pst_index_ll* ptr; | 4176 pst_index_ll* ptr; |
4141 // size_t ret; | 4177 pst_holder h = {buf, NULL, 0, "", 0}; |
4142 struct holder h = {buf, NULL, 0, "", 0}; | |
4143 DEBUG_ENT("pst_ff_getID2block"); | 4178 DEBUG_ENT("pst_ff_getID2block"); |
4144 ptr = pst_getID2(id2_head, id2); | 4179 ptr = pst_getID2(id2_head, id2); |
4145 | 4180 |
4146 if (!ptr) { | 4181 if (!ptr) { |
4147 DEBUG_INDEX(("Cannot find id2 value %#x\n", id2)); | 4182 DEBUG_INDEX(("Cannot find id2 value %#x\n", id2)); |
4151 DEBUG_RET(); | 4186 DEBUG_RET(); |
4152 return pst_ff_getID2data(pf, ptr, &h); | 4187 return pst_ff_getID2data(pf, ptr, &h); |
4153 } | 4188 } |
4154 | 4189 |
4155 | 4190 |
4156 size_t pst_ff_getID2data(pst_file *pf, pst_index_ll *ptr, struct holder *h) { | 4191 size_t pst_ff_getID2data(pst_file *pf, pst_index_ll *ptr, pst_holder *h) { |
4157 size_t ret; | 4192 size_t ret; |
4158 unsigned char *b = NULL, *t; | 4193 unsigned char *b = NULL, *t; |
4159 DEBUG_ENT("pst_ff_getID2data"); | 4194 DEBUG_ENT("pst_ff_getID2data"); |
4160 if (!(ptr->id & 0x02)) { | 4195 if (!(ptr->id & 0x02)) { |
4161 ret = pst_ff_getIDblock_dec(pf, ptr->id, &b); | 4196 ret = pst_ff_getIDblock_dec(pf, ptr->id, &b); |
4185 DEBUG_RET(); | 4220 DEBUG_RET(); |
4186 return ret; | 4221 return ret; |
4187 } | 4222 } |
4188 | 4223 |
4189 | 4224 |
4190 size_t pst_ff_compile_ID(pst_file *pf, uint64_t id, struct holder *h, size_t size) { | 4225 size_t pst_ff_compile_ID(pst_file *pf, uint64_t id, pst_holder *h, size_t size) { |
4191 size_t z, a; | 4226 size_t z, a; |
4192 uint16_t count, y; | 4227 uint16_t count, y; |
4193 uint32_t x, b; | 4228 uint32_t x, b; |
4194 unsigned char * buf3 = NULL, *buf2 = NULL, *t; | 4229 unsigned char * buf3 = NULL, *buf2 = NULL, *t; |
4195 unsigned char fdepth; | 4230 unsigned char fdepth; |