Mercurial > libpst
comparison src/libpst.c @ 172:6954d315aaa8
move version-info into main configure.in, and set it properly.
prefix all external symbols in the shared library with pst_ to avoid symbol clashes with other shared libraries.
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Sat, 04 Apr 2009 16:00:48 -0700 |
parents | 6c1e75bc4cac |
children | ac6e22c8a9cf |
comparison
equal
deleted
inserted
replaced
171:6c1e75bc4cac | 172:6954d315aaa8 |
---|---|
170 | 170 |
171 | 171 |
172 int pst_open(pst_file *pf, char *name) { | 172 int pst_open(pst_file *pf, char *name) { |
173 int32_t sig; | 173 int32_t sig; |
174 | 174 |
175 unicode_init(); | 175 pst_unicode_init(); |
176 | 176 |
177 DEBUG_ENT("pst_open"); | 177 DEBUG_ENT("pst_open"); |
178 | 178 |
179 if (!pf) { | 179 if (!pf) { |
180 WARN (("cannot be passed a NULL pst_file\n")); | 180 WARN (("cannot be passed a NULL pst_file\n")); |
361 */ | 361 */ |
362 static pst_id2_ll* deep_copy(pst_id2_ll *head); | 362 static pst_id2_ll* deep_copy(pst_id2_ll *head); |
363 static pst_id2_ll* deep_copy(pst_id2_ll *head) | 363 static pst_id2_ll* deep_copy(pst_id2_ll *head) |
364 { | 364 { |
365 if (!head) return NULL; | 365 if (!head) return NULL; |
366 pst_id2_ll* me = (pst_id2_ll*) xmalloc(sizeof(pst_id2_ll)); | 366 pst_id2_ll* me = (pst_id2_ll*) pst_malloc(sizeof(pst_id2_ll)); |
367 me->id2 = head->id2; | 367 me->id2 = head->id2; |
368 me->id = head->id; | 368 me->id = head->id; |
369 me->child = deep_copy(head->child); | 369 me->child = deep_copy(head->child); |
370 me->next = deep_copy(head->next); | 370 me->next = deep_copy(head->next); |
371 return me; | 371 return me; |
390 } | 390 } |
391 DEBUG_INDEX(("looking for top of folder descriptor %#"PRIx32"\n", topid)); | 391 DEBUG_INDEX(("looking for top of folder descriptor %#"PRIx32"\n", topid)); |
392 topnode = pst_getDptr(pf, (uint64_t)topid); | 392 topnode = pst_getDptr(pf, (uint64_t)topid); |
393 if (!topnode) { | 393 if (!topnode) { |
394 // add dummy top record to pickup orphan children | 394 // add dummy top record to pickup orphan children |
395 topnode = (pst_desc_ll*) xmalloc(sizeof(pst_desc_ll)); | 395 topnode = (pst_desc_ll*) pst_malloc(sizeof(pst_desc_ll)); |
396 topnode->d_id = topid; | 396 topnode->d_id = topid; |
397 topnode->parent_d_id = 0; | 397 topnode->parent_d_id = 0; |
398 topnode->assoc_tree = NULL; | 398 topnode->assoc_tree = NULL; |
399 topnode->desc = NULL; | 399 topnode->desc = NULL; |
400 record_descriptor(pf, topnode); // add to the global tree | 400 record_descriptor(pf, topnode); // add to the global tree |
462 DEBUG_WARN(("Couldn't find ID pointer. Cannot save attachment to Base64\n")); | 462 DEBUG_WARN(("Couldn't find ID pointer. Cannot save attachment to Base64\n")); |
463 } | 463 } |
464 attach->data.size = size; | 464 attach->data.size = size; |
465 } else { | 465 } else { |
466 // encode the attachment to the file | 466 // encode the attachment to the file |
467 char *c = base64_encode(attach->data.data, attach->data.size); | 467 char *c = pst_base64_encode(attach->data.data, attach->data.size); |
468 if (c) { | 468 if (c) { |
469 (void)pst_fwrite(c, (size_t)1, strlen(c), fp); | 469 (void)pst_fwrite(c, (size_t)1, strlen(c), fp); |
470 free(c); // caught by valgrind | 470 free(c); // caught by valgrind |
471 } | 471 } |
472 size = attach->data.size; | 472 size = attach->data.size; |
588 while (bptr < bsize) { | 588 while (bptr < bsize) { |
589 int err = 0; | 589 int err = 0; |
590 xattrib.extended= PST_LE_GET_UINT32(buffer+bptr), bptr += 4; | 590 xattrib.extended= PST_LE_GET_UINT32(buffer+bptr), bptr += 4; |
591 xattrib.type = PST_LE_GET_UINT16(buffer+bptr), bptr += 2; | 591 xattrib.type = PST_LE_GET_UINT16(buffer+bptr), bptr += 2; |
592 xattrib.map = PST_LE_GET_UINT16(buffer+bptr), bptr += 2; | 592 xattrib.map = PST_LE_GET_UINT16(buffer+bptr), bptr += 2; |
593 ptr = (pst_x_attrib_ll*) xmalloc(sizeof(*ptr)); | 593 ptr = (pst_x_attrib_ll*) pst_malloc(sizeof(*ptr)); |
594 memset(ptr, 0, sizeof(*ptr)); | 594 memset(ptr, 0, sizeof(*ptr)); |
595 ptr->type = xattrib.type; | 595 ptr->type = xattrib.type; |
596 ptr->map = xattrib.map+0x8000; | 596 ptr->map = xattrib.map+0x8000; |
597 ptr->next = NULL; | 597 ptr->next = NULL; |
598 DEBUG_INDEX(("xattrib: ext = %#"PRIx32", type = %#"PRIx16", map = %#"PRIx16"\n", | 598 DEBUG_INDEX(("xattrib: ext = %#"PRIx32", type = %#"PRIx16", map = %#"PRIx16"\n", |
602 if (xattrib.extended < hsize) { | 602 if (xattrib.extended < hsize) { |
603 char *wt; | 603 char *wt; |
604 // copy the size of the header. It is 32 bit int | 604 // copy the size of the header. It is 32 bit int |
605 memcpy(&tint, &(headerbuffer[xattrib.extended]), sizeof(tint)); | 605 memcpy(&tint, &(headerbuffer[xattrib.extended]), sizeof(tint)); |
606 LE32_CPU(tint); | 606 LE32_CPU(tint); |
607 wt = (char*) xmalloc((size_t)(tint+2)); // plus 2 for a uni-code zero | 607 wt = (char*) pst_malloc((size_t)(tint+2)); // plus 2 for a uni-code zero |
608 memset(wt, 0, (size_t)(tint+2)); | 608 memset(wt, 0, (size_t)(tint+2)); |
609 memcpy(wt, &(headerbuffer[xattrib.extended+sizeof(tint)]), (size_t)tint); | 609 memcpy(wt, &(headerbuffer[xattrib.extended+sizeof(tint)]), (size_t)tint); |
610 ptr->data = pst_wide_to_single(wt, (size_t)tint); | 610 ptr->data = pst_wide_to_single(wt, (size_t)tint); |
611 free(wt); | 611 free(wt); |
612 DEBUG_INDEX(("Mapped attribute %#"PRIx32" to %s\n", ptr->map, ptr->data)); | 612 DEBUG_INDEX(("Mapped attribute %#"PRIx32" to %s\n", ptr->map, ptr->data)); |
615 err = 1; | 615 err = 1; |
616 } | 616 } |
617 ptr->mytype = PST_MAP_HEADER; | 617 ptr->mytype = PST_MAP_HEADER; |
618 } else { | 618 } else { |
619 // contains the attribute code to map to. | 619 // contains the attribute code to map to. |
620 ptr->data = (uint32_t*)xmalloc(sizeof(uint32_t)); | 620 ptr->data = (uint32_t*)pst_malloc(sizeof(uint32_t)); |
621 memset(ptr->data, 0, sizeof(uint32_t)); | 621 memset(ptr->data, 0, sizeof(uint32_t)); |
622 *((uint32_t*)ptr->data) = xattrib.extended; | 622 *((uint32_t*)ptr->data) = xattrib.extended; |
623 ptr->mytype = PST_MAP_ATTRIB; | 623 ptr->mytype = PST_MAP_ATTRIB; |
624 DEBUG_INDEX(("Mapped attribute %#"PRIx32" to %#"PRIx32"\n", ptr->map, *((uint32_t*)ptr->data))); | 624 DEBUG_INDEX(("Mapped attribute %#"PRIx32" to %#"PRIx32"\n", ptr->map, *((uint32_t*)ptr->data))); |
625 } | 625 } |
893 if (buf) free(buf); | 893 if (buf) free(buf); |
894 DEBUG_RET(); | 894 DEBUG_RET(); |
895 return -1; | 895 return -1; |
896 } | 896 } |
897 } | 897 } |
898 i_ptr = (pst_index_ll*) xmalloc(sizeof(pst_index_ll)); | 898 i_ptr = (pst_index_ll*) pst_malloc(sizeof(pst_index_ll)); |
899 i_ptr->i_id = index.id; | 899 i_ptr->i_id = index.id; |
900 i_ptr->offset = index.offset; | 900 i_ptr->offset = index.offset; |
901 i_ptr->u1 = index.u1; | 901 i_ptr->u1 = index.u1; |
902 i_ptr->size = index.size; | 902 i_ptr->size = index.size; |
903 i_ptr->next = NULL; | 903 i_ptr->next = NULL; |
1009 return -1; | 1009 return -1; |
1010 } | 1010 } |
1011 } | 1011 } |
1012 DEBUG_INDEX(("New Record %#"PRIx64" with parent %#x\n", desc_rec.d_id, desc_rec.parent_d_id)); | 1012 DEBUG_INDEX(("New Record %#"PRIx64" with parent %#x\n", desc_rec.d_id, desc_rec.parent_d_id)); |
1013 { | 1013 { |
1014 pst_desc_ll *d_ptr = (pst_desc_ll*) xmalloc(sizeof(pst_desc_ll)); | 1014 pst_desc_ll *d_ptr = (pst_desc_ll*) pst_malloc(sizeof(pst_desc_ll)); |
1015 d_ptr->d_id = desc_rec.d_id; | 1015 d_ptr->d_id = desc_rec.d_id; |
1016 d_ptr->parent_d_id = desc_rec.parent_d_id; | 1016 d_ptr->parent_d_id = desc_rec.parent_d_id; |
1017 d_ptr->assoc_tree = pst_getID(pf, desc_rec.tree_id); | 1017 d_ptr->assoc_tree = pst_getID(pf, desc_rec.tree_id); |
1018 d_ptr->desc = pst_getID(pf, desc_rec.desc_id); | 1018 d_ptr->desc = pst_getID(pf, desc_rec.desc_id); |
1019 record_descriptor(pf, d_ptr); // add to the global tree | 1019 record_descriptor(pf, d_ptr); // add to the global tree |
1100 if (!m_head) pst_free_id2(id2_head); | 1100 if (!m_head) pst_free_id2(id2_head); |
1101 DEBUG_RET(); | 1101 DEBUG_RET(); |
1102 return NULL; | 1102 return NULL; |
1103 } | 1103 } |
1104 | 1104 |
1105 item = (pst_item*) xmalloc(sizeof(pst_item)); | 1105 item = (pst_item*) pst_malloc(sizeof(pst_item)); |
1106 memset(item, 0, sizeof(pst_item)); | 1106 memset(item, 0, sizeof(pst_item)); |
1107 | 1107 |
1108 if (pst_process(list, item, NULL)) { | 1108 if (pst_process(list, item, NULL)) { |
1109 DEBUG_WARN(("pst_process() returned non-zero value. That is an error\n")); | 1109 DEBUG_WARN(("pst_process() returned non-zero value. That is an error\n")); |
1110 pst_freeItem(item); | 1110 pst_freeItem(item); |
1124 if (!m_head) pst_free_id2(id2_head); | 1124 if (!m_head) pst_free_id2(id2_head); |
1125 DEBUG_RET(); | 1125 DEBUG_RET(); |
1126 return item; | 1126 return item; |
1127 } | 1127 } |
1128 for (x=0; x < list->count_objects; x++) { | 1128 for (x=0; x < list->count_objects; x++) { |
1129 attach = (pst_item_attach*) xmalloc(sizeof(pst_item_attach)); | 1129 attach = (pst_item_attach*) pst_malloc(sizeof(pst_item_attach)); |
1130 memset(attach, 0, sizeof(pst_item_attach)); | 1130 memset(attach, 0, sizeof(pst_item_attach)); |
1131 attach->next = item->attach; | 1131 attach->next = item->attach; |
1132 item->attach = attach; | 1132 item->attach = attach; |
1133 } | 1133 } |
1134 if (pst_process(list, item, item->attach)) { | 1134 if (pst_process(list, item, item->attach)) { |
1150 if (!m_head) pst_free_id2(id2_head); | 1150 if (!m_head) pst_free_id2(id2_head); |
1151 DEBUG_RET(); | 1151 DEBUG_RET(); |
1152 return item; | 1152 return item; |
1153 } | 1153 } |
1154 for (x=0; x < list->count_objects; x++) { | 1154 for (x=0; x < list->count_objects; x++) { |
1155 attach = (pst_item_attach*) xmalloc(sizeof(pst_item_attach)); | 1155 attach = (pst_item_attach*) pst_malloc(sizeof(pst_item_attach)); |
1156 memset(attach, 0, sizeof(pst_item_attach)); | 1156 memset(attach, 0, sizeof(pst_item_attach)); |
1157 attach->next = item->attach; | 1157 attach->next = item->attach; |
1158 item->attach = attach; | 1158 item->attach = attach; |
1159 } | 1159 } |
1160 if (pst_process(list, item, item->attach)) { | 1160 if (pst_process(list, item, item->attach)) { |
1481 return NULL; | 1481 return NULL; |
1482 } | 1482 } |
1483 | 1483 |
1484 DEBUG_EMAIL(("Mallocing number of records %i\n", num_recs)); | 1484 DEBUG_EMAIL(("Mallocing number of records %i\n", num_recs)); |
1485 for (count_rec=0; count_rec<num_recs; count_rec++) { | 1485 for (count_rec=0; count_rec<num_recs; count_rec++) { |
1486 mo_ptr = (pst_mapi_object*) xmalloc(sizeof(pst_mapi_object)); | 1486 mo_ptr = (pst_mapi_object*) pst_malloc(sizeof(pst_mapi_object)); |
1487 memset(mo_ptr, 0, sizeof(pst_mapi_object)); | 1487 memset(mo_ptr, 0, sizeof(pst_mapi_object)); |
1488 mo_ptr->next = mo_head; | 1488 mo_ptr->next = mo_head; |
1489 mo_head = mo_ptr; | 1489 mo_head = mo_ptr; |
1490 // allocate an array of count num_recs to contain sizeof(pst_mapi_element) | 1490 // allocate an array of count num_recs to contain sizeof(pst_mapi_element) |
1491 mo_ptr->elements = (pst_mapi_element**) xmalloc(sizeof(pst_mapi_element)*num_list); | 1491 mo_ptr->elements = (pst_mapi_element**) pst_malloc(sizeof(pst_mapi_element)*num_list); |
1492 mo_ptr->count_elements = num_list; | 1492 mo_ptr->count_elements = num_list; |
1493 mo_ptr->orig_count = num_list; | 1493 mo_ptr->orig_count = num_list; |
1494 mo_ptr->count_objects = (int32_t)num_recs; // each record will have a record of the total number of records | 1494 mo_ptr->count_objects = (int32_t)num_recs; // each record will have a record of the total number of records |
1495 for (x=0; x<num_list; x++) mo_ptr->elements[x] = NULL; | 1495 for (x=0; x<num_list; x++) mo_ptr->elements[x] = NULL; |
1496 x = 0; | 1496 x = 0; |
1544 } | 1544 } |
1545 DEBUG_EMAIL(("reading block %i (type=%#x, ref_type=%#x, value=%#x)\n", | 1545 DEBUG_EMAIL(("reading block %i (type=%#x, ref_type=%#x, value=%#x)\n", |
1546 x, table_rec.type, table_rec.ref_type, table_rec.value)); | 1546 x, table_rec.type, table_rec.ref_type, table_rec.value)); |
1547 | 1547 |
1548 if (!mo_ptr->elements[x]) { | 1548 if (!mo_ptr->elements[x]) { |
1549 mo_ptr->elements[x] = (pst_mapi_element*) xmalloc(sizeof(pst_mapi_element)); | 1549 mo_ptr->elements[x] = (pst_mapi_element*) pst_malloc(sizeof(pst_mapi_element)); |
1550 } | 1550 } |
1551 memset(mo_ptr->elements[x], 0, sizeof(pst_mapi_element)); //init it | 1551 memset(mo_ptr->elements[x], 0, sizeof(pst_mapi_element)); //init it |
1552 | 1552 |
1553 // check here to see if the id of the attribute is a mapped one | 1553 // check here to see if the id of the attribute is a mapped one |
1554 mapptr = pf->x_head; | 1554 mapptr = pf->x_head; |
1596 table_rec.ref_type == (uint16_t)0x0003 || | 1596 table_rec.ref_type == (uint16_t)0x0003 || |
1597 table_rec.ref_type == (uint16_t)0x000b) { | 1597 table_rec.ref_type == (uint16_t)0x000b) { |
1598 //contains 32 bits of data | 1598 //contains 32 bits of data |
1599 mo_ptr->elements[x]->size = sizeof(int32_t); | 1599 mo_ptr->elements[x]->size = sizeof(int32_t); |
1600 mo_ptr->elements[x]->type = table_rec.ref_type; | 1600 mo_ptr->elements[x]->type = table_rec.ref_type; |
1601 mo_ptr->elements[x]->data = xmalloc(sizeof(int32_t)); | 1601 mo_ptr->elements[x]->data = pst_malloc(sizeof(int32_t)); |
1602 memcpy(mo_ptr->elements[x]->data, &(table_rec.value), sizeof(int32_t)); | 1602 memcpy(mo_ptr->elements[x]->data, &(table_rec.value), sizeof(int32_t)); |
1603 // are we missing an LE32_CPU() call here? table_rec.value is still | 1603 // are we missing an LE32_CPU() call here? table_rec.value is still |
1604 // in the original order. | 1604 // in the original order. |
1605 | 1605 |
1606 } else if (table_rec.ref_type == (uint16_t)0x0005 || | 1606 } else if (table_rec.ref_type == (uint16_t)0x0005 || |
1621 if (value_pointer) { | 1621 if (value_pointer) { |
1622 // in a type 2 block, with a value that is more than 4 bytes | 1622 // in a type 2 block, with a value that is more than 4 bytes |
1623 // directly stored in this block. | 1623 // directly stored in this block. |
1624 mo_ptr->elements[x]->size = value_size; | 1624 mo_ptr->elements[x]->size = value_size; |
1625 mo_ptr->elements[x]->type = table_rec.ref_type; | 1625 mo_ptr->elements[x]->type = table_rec.ref_type; |
1626 mo_ptr->elements[x]->data = xmalloc(value_size); | 1626 mo_ptr->elements[x]->data = pst_malloc(value_size); |
1627 memcpy(mo_ptr->elements[x]->data, value_pointer, value_size); | 1627 memcpy(mo_ptr->elements[x]->data, value_pointer, value_size); |
1628 } | 1628 } |
1629 else if (pst_getBlockOffsetPointer(pf, i2_head, &subblocks, table_rec.value, &block_offset7)) { | 1629 else if (pst_getBlockOffsetPointer(pf, i2_head, &subblocks, table_rec.value, &block_offset7)) { |
1630 if ((table_rec.value & 0xf) == (uint32_t)0xf) { | 1630 if ((table_rec.value & 0xf) == (uint32_t)0xf) { |
1631 DEBUG_WARN(("failed to get block offset for table_rec.value of %#x to be read later.\n", table_rec.value)); | 1631 DEBUG_WARN(("failed to get block offset for table_rec.value of %#x to be read later.\n", table_rec.value)); |
1643 } | 1643 } |
1644 else { | 1644 else { |
1645 value_size = (size_t)(block_offset7.to - block_offset7.from); | 1645 value_size = (size_t)(block_offset7.to - block_offset7.from); |
1646 mo_ptr->elements[x]->size = value_size; | 1646 mo_ptr->elements[x]->size = value_size; |
1647 mo_ptr->elements[x]->type = table_rec.ref_type; | 1647 mo_ptr->elements[x]->type = table_rec.ref_type; |
1648 mo_ptr->elements[x]->data = xmalloc(value_size+1); | 1648 mo_ptr->elements[x]->data = pst_malloc(value_size+1); |
1649 memcpy(mo_ptr->elements[x]->data, block_offset7.from, value_size); | 1649 memcpy(mo_ptr->elements[x]->data, block_offset7.from, value_size); |
1650 mo_ptr->elements[x]->data[value_size] = '\0'; // it might be a string, null terminate it. | 1650 mo_ptr->elements[x]->data[value_size] = '\0'; // it might be a string, null terminate it. |
1651 } | 1651 } |
1652 if (table_rec.ref_type == (uint16_t)0xd) { | 1652 if (table_rec.ref_type == (uint16_t)0xd) { |
1653 // there is still more to do for the type of 0xD embedded objects | 1653 // there is still more to do for the type of 0xD embedded objects |
1664 if (table_rec.ref_type == (uint16_t)0x1f) { | 1664 if (table_rec.ref_type == (uint16_t)0x1f) { |
1665 // there is more to do for the type 0x1f unicode strings | 1665 // there is more to do for the type 0x1f unicode strings |
1666 size_t rc; | 1666 size_t rc; |
1667 static vbuf *utf16buf = NULL; | 1667 static vbuf *utf16buf = NULL; |
1668 static vbuf *utf8buf = NULL; | 1668 static vbuf *utf8buf = NULL; |
1669 if (!utf16buf) utf16buf = vballoc((size_t)1024); | 1669 if (!utf16buf) utf16buf = pst_vballoc((size_t)1024); |
1670 if (!utf8buf) utf8buf = vballoc((size_t)1024); | 1670 if (!utf8buf) utf8buf = pst_vballoc((size_t)1024); |
1671 | 1671 |
1672 // splint barfed on the following lines | 1672 // splint barfed on the following lines |
1673 //VBUF_STATIC(utf16buf, 1024); | 1673 //VBUF_STATIC(utf16buf, 1024); |
1674 //VBUF_STATIC(utf8buf, 1024); | 1674 //VBUF_STATIC(utf8buf, 1024); |
1675 | 1675 |
1676 //need UTF-16 zero-termination | 1676 //need UTF-16 zero-termination |
1677 vbset(utf16buf, mo_ptr->elements[x]->data, mo_ptr->elements[x]->size); | 1677 pst_vbset(utf16buf, mo_ptr->elements[x]->data, mo_ptr->elements[x]->size); |
1678 vbappend(utf16buf, "\0\0", (size_t)2); | 1678 pst_vbappend(utf16buf, "\0\0", (size_t)2); |
1679 DEBUG_INDEX(("Iconv in:\n")); | 1679 DEBUG_INDEX(("Iconv in:\n")); |
1680 DEBUG_HEXDUMPC(utf16buf->b, utf16buf->dlen, 0x10); | 1680 DEBUG_HEXDUMPC(utf16buf->b, utf16buf->dlen, 0x10); |
1681 rc = vb_utf16to8(utf8buf, utf16buf->b, utf16buf->dlen); | 1681 rc = pst_vb_utf16to8(utf8buf, utf16buf->b, utf16buf->dlen); |
1682 if (rc == (size_t)-1) { | 1682 if (rc == (size_t)-1) { |
1683 DEBUG_EMAIL(("Failed to convert utf-16 to utf-8\n")); | 1683 DEBUG_EMAIL(("Failed to convert utf-16 to utf-8\n")); |
1684 } | 1684 } |
1685 else { | 1685 else { |
1686 free(mo_ptr->elements[x]->data); | 1686 free(mo_ptr->elements[x]->data); |
1687 mo_ptr->elements[x]->size = utf8buf->dlen; | 1687 mo_ptr->elements[x]->size = utf8buf->dlen; |
1688 mo_ptr->elements[x]->data = xmalloc(utf8buf->dlen); | 1688 mo_ptr->elements[x]->data = pst_malloc(utf8buf->dlen); |
1689 memcpy(mo_ptr->elements[x]->data, utf8buf->b, utf8buf->dlen); | 1689 memcpy(mo_ptr->elements[x]->data, utf8buf->b, utf8buf->dlen); |
1690 } | 1690 } |
1691 DEBUG_INDEX(("Iconv out:\n")); | 1691 DEBUG_INDEX(("Iconv out:\n")); |
1692 DEBUG_HEXDUMPC(mo_ptr->elements[x]->data, mo_ptr->elements[x]->size, 0x10); | 1692 DEBUG_HEXDUMPC(mo_ptr->elements[x]->data, mo_ptr->elements[x]->size, 0x10); |
1693 } | 1693 } |
1714 #define SAFE_FREE(x) {if (x) free(x);} | 1714 #define SAFE_FREE(x) {if (x) free(x);} |
1715 #define SAFE_FREE_STR(x) SAFE_FREE(x.str) | 1715 #define SAFE_FREE_STR(x) SAFE_FREE(x.str) |
1716 #define SAFE_FREE_BIN(x) SAFE_FREE(x.data) | 1716 #define SAFE_FREE_BIN(x) SAFE_FREE(x.data) |
1717 | 1717 |
1718 // check if item->email is NULL, and init if so | 1718 // check if item->email is NULL, and init if so |
1719 #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) );} } | 1719 #define MALLOC_EMAIL(x) { if (!x->email) { x->email = (pst_item_email*) pst_malloc(sizeof(pst_item_email)); memset(x->email, 0, sizeof(pst_item_email) );} } |
1720 #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) );} } | 1720 #define MALLOC_FOLDER(x) { if (!x->folder) { x->folder = (pst_item_folder*) pst_malloc(sizeof(pst_item_folder)); memset(x->folder, 0, sizeof(pst_item_folder) );} } |
1721 #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) );} } | 1721 #define MALLOC_CONTACT(x) { if (!x->contact) { x->contact = (pst_item_contact*) pst_malloc(sizeof(pst_item_contact)); memset(x->contact, 0, sizeof(pst_item_contact) );} } |
1722 #define MALLOC_MESSAGESTORE(x) { if (!x->message_store) { x->message_store = (pst_item_message_store*) xmalloc(sizeof(pst_item_message_store)); memset(x->message_store, 0, sizeof(pst_item_message_store));} } | 1722 #define MALLOC_MESSAGESTORE(x) { if (!x->message_store) { x->message_store = (pst_item_message_store*) pst_malloc(sizeof(pst_item_message_store)); memset(x->message_store, 0, sizeof(pst_item_message_store));} } |
1723 #define MALLOC_JOURNAL(x) { if (!x->journal) { x->journal = (pst_item_journal*) xmalloc(sizeof(pst_item_journal)); memset(x->journal, 0, sizeof(pst_item_journal) );} } | 1723 #define MALLOC_JOURNAL(x) { if (!x->journal) { x->journal = (pst_item_journal*) pst_malloc(sizeof(pst_item_journal)); memset(x->journal, 0, sizeof(pst_item_journal) );} } |
1724 #define MALLOC_APPOINTMENT(x) { if (!x->appointment) { x->appointment = (pst_item_appointment*) xmalloc(sizeof(pst_item_appointment)); memset(x->appointment, 0, sizeof(pst_item_appointment) );} } | 1724 #define MALLOC_APPOINTMENT(x) { if (!x->appointment) { x->appointment = (pst_item_appointment*) pst_malloc(sizeof(pst_item_appointment)); memset(x->appointment, 0, sizeof(pst_item_appointment) );} } |
1725 | 1725 |
1726 // malloc space and copy the current item's data null terminated | 1726 // malloc space and copy the current item's data null terminated |
1727 #define LIST_COPY(targ, type) { \ | 1727 #define LIST_COPY(targ, type) { \ |
1728 targ = type realloc(targ, list->elements[x]->size+1); \ | 1728 targ = type realloc(targ, list->elements[x]->size+1); \ |
1729 memcpy(targ, list->elements[x]->data, list->elements[x]->size);\ | 1729 memcpy(targ, list->elements[x]->data, list->elements[x]->size);\ |
1910 } \ | 1910 } \ |
1911 targ = (FILETIME*) realloc(targ, sizeof(FILETIME)); \ | 1911 targ = (FILETIME*) realloc(targ, sizeof(FILETIME)); \ |
1912 memcpy(targ, list->elements[x]->data, list->elements[x]->size); \ | 1912 memcpy(targ, list->elements[x]->data, list->elements[x]->size); \ |
1913 LE32_CPU(targ->dwLowDateTime); \ | 1913 LE32_CPU(targ->dwLowDateTime); \ |
1914 LE32_CPU(targ->dwHighDateTime); \ | 1914 LE32_CPU(targ->dwHighDateTime); \ |
1915 DEBUG_EMAIL((label" - %s", fileTimeToAscii(targ))); \ | 1915 DEBUG_EMAIL((label" - %s", pst_fileTimeToAscii(targ))); \ |
1916 } | 1916 } |
1917 | 1917 |
1918 #define LIST_COPY_EMAIL_TIME(label, targ) { \ | 1918 #define LIST_COPY_EMAIL_TIME(label, targ) { \ |
1919 MALLOC_EMAIL(item); \ | 1919 MALLOC_EMAIL(item); \ |
1920 LIST_COPY_TIME(label, targ); \ | 1920 LIST_COPY_TIME(label, targ); \ |
1986 DEBUG_EMAIL(("#%d - mapi-id: %#x type: %#x length: %#x\n", x, list->elements[x]->mapi_id, list->elements[x]->type, list->elements[x]->size)); | 1986 DEBUG_EMAIL(("#%d - mapi-id: %#x type: %#x length: %#x\n", x, list->elements[x]->mapi_id, list->elements[x]->type, list->elements[x]->size)); |
1987 | 1987 |
1988 switch (list->elements[x]->mapi_id) { | 1988 switch (list->elements[x]->mapi_id) { |
1989 case PST_ATTRIB_HEADER: // CUSTOM attribute for saying the Extra Headers | 1989 case PST_ATTRIB_HEADER: // CUSTOM attribute for saying the Extra Headers |
1990 if (list->elements[x]->extra) { | 1990 if (list->elements[x]->extra) { |
1991 pst_item_extra_field *ef = (pst_item_extra_field*) xmalloc(sizeof(pst_item_extra_field)); | 1991 pst_item_extra_field *ef = (pst_item_extra_field*) pst_malloc(sizeof(pst_item_extra_field)); |
1992 memset(ef, 0, sizeof(pst_item_extra_field)); | 1992 memset(ef, 0, sizeof(pst_item_extra_field)); |
1993 ef->field_name = strdup(list->elements[x]->extra); | 1993 ef->field_name = strdup(list->elements[x]->extra); |
1994 LIST_COPY_CSTR(ef->value); | 1994 LIST_COPY_CSTR(ef->value); |
1995 if (ef->value) { | 1995 if (ef->value) { |
1996 ef->next = item->extra_fields; | 1996 ef->next = item->extra_fields; |
2840 break; | 2840 break; |
2841 case 0x8503: // Reminder alarm | 2841 case 0x8503: // Reminder alarm |
2842 LIST_COPY_APPT_BOOL("Reminder alarm", item->appointment->alarm); | 2842 LIST_COPY_APPT_BOOL("Reminder alarm", item->appointment->alarm); |
2843 break; | 2843 break; |
2844 case 0x8516: // Common start | 2844 case 0x8516: // Common start |
2845 DEBUG_EMAIL(("Common Start Date - %s\n", fileTimeToAscii((FILETIME*)list->elements[x]->data))); | 2845 DEBUG_EMAIL(("Common Start Date - %s\n", pst_fileTimeToAscii((FILETIME*)list->elements[x]->data))); |
2846 break; | 2846 break; |
2847 case 0x8517: // Common end | 2847 case 0x8517: // Common end |
2848 DEBUG_EMAIL(("Common End Date - %s\n", fileTimeToAscii((FILETIME*)list->elements[x]->data))); | 2848 DEBUG_EMAIL(("Common End Date - %s\n", pst_fileTimeToAscii((FILETIME*)list->elements[x]->data))); |
2849 break; | 2849 break; |
2850 case 0x851f: // Play reminder sound filename | 2850 case 0x851f: // Play reminder sound filename |
2851 LIST_COPY_APPT_STR("Appointment reminder sound filename", item->appointment->alarm_filename); | 2851 LIST_COPY_APPT_STR("Appointment reminder sound filename", item->appointment->alarm_filename); |
2852 break; | 2852 break; |
2853 case 0x8530: // Followup | 2853 case 0x8530: // Followup |
2934 list->elements[x]->size)); | 2934 list->elements[x]->size)); |
2935 DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size); | 2935 DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size); |
2936 | 2936 |
2937 } else if (list->elements[x]->type == (uint32_t)0x0040) { | 2937 } else if (list->elements[x]->type == (uint32_t)0x0040) { |
2938 DEBUG_EMAIL(("Unknown type %#x Date = \"%s\"\n", list->elements[x]->mapi_id, | 2938 DEBUG_EMAIL(("Unknown type %#x Date = \"%s\"\n", list->elements[x]->mapi_id, |
2939 fileTimeToAscii((FILETIME*)list->elements[x]->data))); | 2939 pst_fileTimeToAscii((FILETIME*)list->elements[x]->data))); |
2940 | 2940 |
2941 } else if (list->elements[x]->type == (uint32_t)0x0048) { | 2941 } else if (list->elements[x]->type == (uint32_t)0x0048) { |
2942 DEBUG_EMAIL(("Unknown type %#x OLE GUID [size = %#x]\n", list->elements[x]->mapi_id, | 2942 DEBUG_EMAIL(("Unknown type %#x OLE GUID [size = %#x]\n", list->elements[x]->mapi_id, |
2943 list->elements[x]->size)); | 2943 list->elements[x]->size)); |
2944 DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size); | 2944 DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size); |
3119 DEBUG_WARN(("%#"PRIx64" - Not Found\n", id2_rec.id)); | 3119 DEBUG_WARN(("%#"PRIx64" - Not Found\n", id2_rec.id)); |
3120 } else { | 3120 } else { |
3121 DEBUG_INDEX(("%#"PRIx64" - Offset %#"PRIx64", u1 %#"PRIx64", Size %"PRIi64"(%#"PRIx64")\n", | 3121 DEBUG_INDEX(("%#"PRIx64" - Offset %#"PRIx64", u1 %#"PRIx64", Size %"PRIi64"(%#"PRIx64")\n", |
3122 i_ptr->i_id, i_ptr->offset, i_ptr->u1, i_ptr->size, i_ptr->size)); | 3122 i_ptr->i_id, i_ptr->offset, i_ptr->u1, i_ptr->size, i_ptr->size)); |
3123 // add it to the tree | 3123 // add it to the tree |
3124 i2_ptr = (pst_id2_ll*) xmalloc(sizeof(pst_id2_ll)); | 3124 i2_ptr = (pst_id2_ll*) pst_malloc(sizeof(pst_id2_ll)); |
3125 i2_ptr->id2 = id2_rec.id2; | 3125 i2_ptr->id2 = id2_rec.id2; |
3126 i2_ptr->id = i_ptr; | 3126 i2_ptr->id = i_ptr; |
3127 i2_ptr->child = NULL; | 3127 i2_ptr->child = NULL; |
3128 i2_ptr->next = NULL; | 3128 i2_ptr->next = NULL; |
3129 if (!head) head = i2_ptr; | 3129 if (!head) head = i2_ptr; |
3573 | 3573 |
3574 if (*buf) { | 3574 if (*buf) { |
3575 DEBUG_READ(("Freeing old memory\n")); | 3575 DEBUG_READ(("Freeing old memory\n")); |
3576 free(*buf); | 3576 free(*buf); |
3577 } | 3577 } |
3578 *buf = (char*) xmalloc(size); | 3578 *buf = (char*) pst_malloc(size); |
3579 | 3579 |
3580 rsize = pst_getAtPos(pf, offset, *buf, size); | 3580 rsize = pst_getAtPos(pf, offset, *buf, size); |
3581 if (rsize != size) { | 3581 if (rsize != size) { |
3582 DEBUG_WARN(("Didn't read all the data. fread returned less [%i instead of %i]\n", rsize, size)); | 3582 DEBUG_WARN(("Didn't read all the data. fread returned less [%i instead of %i]\n", rsize, size)); |
3583 if (feof(pf->fp)) { | 3583 if (feof(pf->fp)) { |
3696 // // bump the count | 3696 // // bump the count |
3697 // p->readcount++; | 3697 // p->readcount++; |
3698 // } else { | 3698 // } else { |
3699 // // add a new block | 3699 // // add a new block |
3700 // pst_block_recorder *tail = *t; | 3700 // pst_block_recorder *tail = *t; |
3701 // p = (pst_block_recorder*)xmalloc(sizeof(*p)); | 3701 // p = (pst_block_recorder*)pst_malloc(sizeof(*p)); |
3702 // *t = p; | 3702 // *t = p; |
3703 // p->next = tail; | 3703 // p->next = tail; |
3704 // p->offset = pos; | 3704 // p->offset = pos; |
3705 // p->size = size; | 3705 // p->size = size; |
3706 // p->readcount = 1; | 3706 // p->readcount = 1; |
3792 if (!(ptr->i_id & 0x02)) { | 3792 if (!(ptr->i_id & 0x02)) { |
3793 ret = pst_ff_getIDblock_dec(pf, ptr->i_id, &b); | 3793 ret = pst_ff_getIDblock_dec(pf, ptr->i_id, &b); |
3794 if (h->buf) { | 3794 if (h->buf) { |
3795 *(h->buf) = b; | 3795 *(h->buf) = b; |
3796 } else if ((h->base64 == 1) && h->fp) { | 3796 } else if ((h->base64 == 1) && h->fp) { |
3797 t = base64_encode(b, ret); | 3797 t = pst_base64_encode(b, ret); |
3798 if (t) { | 3798 if (t) { |
3799 (void)pst_fwrite(t, (size_t)1, strlen(t), h->fp); | 3799 (void)pst_fwrite(t, (size_t)1, strlen(t), h->fp); |
3800 free(t); // caught by valgrind | 3800 free(t); // caught by valgrind |
3801 } | 3801 } |
3802 free(b); | 3802 free(b); |
3846 DEBUG_WARN(("WARNING: not a type 0x0101 buffer, Treating as normal buffer\n")); | 3846 DEBUG_WARN(("WARNING: not a type 0x0101 buffer, Treating as normal buffer\n")); |
3847 if (pf->encryption) (void)pst_decrypt(id, buf3, a, pf->encryption); | 3847 if (pf->encryption) (void)pst_decrypt(id, buf3, a, pf->encryption); |
3848 if (h->buf) | 3848 if (h->buf) |
3849 *(h->buf) = buf3; | 3849 *(h->buf) = buf3; |
3850 else if (h->base64 == 1 && h->fp) { | 3850 else if (h->base64 == 1 && h->fp) { |
3851 t = base64_encode(buf3, a); | 3851 t = pst_base64_encode(buf3, a); |
3852 if (t) { | 3852 if (t) { |
3853 (void)pst_fwrite(t, (size_t)1, strlen(t), h->fp); | 3853 (void)pst_fwrite(t, (size_t)1, strlen(t), h->fp); |
3854 free(t); // caught by valgrind | 3854 free(t); // caught by valgrind |
3855 } | 3855 } |
3856 free(buf3); | 3856 free(buf3); |
3895 z -= base64_extra; | 3895 z -= base64_extra; |
3896 memcpy(base64_extra_chars, buf2+z, base64_extra); | 3896 memcpy(base64_extra_chars, buf2+z, base64_extra); |
3897 } | 3897 } |
3898 | 3898 |
3899 // encode this chunk | 3899 // encode this chunk |
3900 t = base64_encode_multiple(buf2, z, &line_count); | 3900 t = pst_base64_encode_multiple(buf2, z, &line_count); |
3901 if (t) { | 3901 if (t) { |
3902 DEBUG_READ(("writing %i bytes to file as base64 [%i]. Currently %i\n", z, strlen(t), size)); | 3902 DEBUG_READ(("writing %i bytes to file as base64 [%i]. Currently %i\n", z, strlen(t), size)); |
3903 (void)pst_fwrite(t, (size_t)1, strlen(t), h->fp); | 3903 (void)pst_fwrite(t, (size_t)1, strlen(t), h->fp); |
3904 free(t); // caught by valgrind | 3904 free(t); // caught by valgrind |
3905 } | 3905 } |
3911 } | 3911 } |
3912 size += z; | 3912 size += z; |
3913 } | 3913 } |
3914 if ((h->base64 == 1) && h->fp && base64_extra) { | 3914 if ((h->base64 == 1) && h->fp && base64_extra) { |
3915 // need to encode any bytes left over | 3915 // need to encode any bytes left over |
3916 t = base64_encode_multiple(base64_extra_chars, (size_t)base64_extra, &line_count); | 3916 t = pst_base64_encode_multiple(base64_extra_chars, (size_t)base64_extra, &line_count); |
3917 if (t) { | 3917 if (t) { |
3918 (void)pst_fwrite(t, (size_t)1, strlen(t), h->fp); | 3918 (void)pst_fwrite(t, (size_t)1, strlen(t), h->fp); |
3919 free(t); // caught by valgrind | 3919 free(t); // caught by valgrind |
3920 } | 3920 } |
3921 } | 3921 } |
3925 return size; | 3925 return size; |
3926 } | 3926 } |
3927 | 3927 |
3928 | 3928 |
3929 #ifdef _WIN32 | 3929 #ifdef _WIN32 |
3930 char * fileTimeToAscii(const FILETIME* filetime) { | 3930 char * pst_fileTimeToAscii(const FILETIME* filetime) { |
3931 time_t t; | 3931 time_t t; |
3932 DEBUG_ENT("fileTimeToAscii"); | 3932 DEBUG_ENT("pst_fileTimeToAscii"); |
3933 t = fileTimeToUnixTime(filetime, 0); | 3933 t = pst_fileTimeToUnixTime(filetime, 0); |
3934 if (t == -1) | 3934 if (t == -1) |
3935 DEBUG_WARN(("ERROR time_t varible that was produced, is -1\n")); | 3935 DEBUG_WARN(("ERROR time_t varible that was produced, is -1\n")); |
3936 DEBUG_RET(); | 3936 DEBUG_RET(); |
3937 return ctime(&t); | 3937 return ctime(&t); |
3938 } | 3938 } |
3939 | 3939 |
3940 | 3940 |
3941 time_t fileTimeToUnixTime(const FILETIME* filetime, DWORD *x) { | 3941 time_t pst_fileTimeToUnixTime(const FILETIME* filetime, DWORD *x) { |
3942 SYSTEMTIME s; | 3942 SYSTEMTIME s; |
3943 struct tm t; | 3943 struct tm t; |
3944 DEBUG_ENT("fileTimeToUnixTime"); | 3944 DEBUG_ENT("pst_fileTimeToUnixTime"); |
3945 memset (&t, 0, sizeof(struct tm)); | 3945 memset (&t, 0, sizeof(struct tm)); |
3946 FileTimeToSystemTime(filetime, &s); | 3946 FileTimeToSystemTime(filetime, &s); |
3947 t.tm_year = s.wYear-1900; // this is what is required | 3947 t.tm_year = s.wYear-1900; // this is what is required |
3948 t.tm_mon = s.wMonth-1; // also required! It made me a bit confused | 3948 t.tm_mon = s.wMonth-1; // also required! It made me a bit confused |
3949 t.tm_mday = s.wDay; | 3949 t.tm_mday = s.wDay; |
3953 DEBUG_RET(); | 3953 DEBUG_RET(); |
3954 return mktime(&t); | 3954 return mktime(&t); |
3955 } | 3955 } |
3956 | 3956 |
3957 | 3957 |
3958 struct tm * fileTimeToStructTM (const FILETIME *filetime) { | 3958 struct tm * pst_fileTimeToStructTM (const FILETIME *filetime) { |
3959 time_t t1; | 3959 time_t t1; |
3960 t1 = fileTimeToUnixTime(filetime, 0); | 3960 t1 = pst_fileTimeToUnixTime(filetime, 0); |
3961 return gmtime(&t1); | 3961 return gmtime(&t1); |
3962 } | 3962 } |
3963 | 3963 |
3964 | 3964 |
3965 #endif //_WIN32 | 3965 #endif //_WIN32 |
4012 | 4012 |
4013 char * pst_wide_to_single(char *wt, size_t size) { | 4013 char * pst_wide_to_single(char *wt, size_t size) { |
4014 // returns the first byte of each wide char. the size is the number of bytes in source | 4014 // returns the first byte of each wide char. the size is the number of bytes in source |
4015 char *x, *y; | 4015 char *x, *y; |
4016 DEBUG_ENT("pst_wide_to_single"); | 4016 DEBUG_ENT("pst_wide_to_single"); |
4017 x = xmalloc((size/2)+1); | 4017 x = pst_malloc((size/2)+1); |
4018 y = x; | 4018 y = x; |
4019 while (size != 0 && *wt != '\0') { | 4019 while (size != 0 && *wt != '\0') { |
4020 *y = *wt; | 4020 *y = *wt; |
4021 wt+=2; | 4021 wt+=2; |
4022 size -= 2; | 4022 size -= 2; |
4098 | 4098 |
4099 char *pst_rfc2425_datetime_format(FILETIME *ft) { | 4099 char *pst_rfc2425_datetime_format(FILETIME *ft) { |
4100 static char buffer[30]; | 4100 static char buffer[30]; |
4101 struct tm *stm = NULL; | 4101 struct tm *stm = NULL; |
4102 DEBUG_ENT("rfc2425_datetime_format"); | 4102 DEBUG_ENT("rfc2425_datetime_format"); |
4103 stm = fileTimeToStructTM(ft); | 4103 stm = pst_fileTimeToStructTM(ft); |
4104 if (strftime(buffer, sizeof(buffer), "%Y-%m-%dT%H:%M:%SZ", stm)==0) { | 4104 if (strftime(buffer, sizeof(buffer), "%Y-%m-%dT%H:%M:%SZ", stm)==0) { |
4105 DEBUG_INFO(("Problem occured formatting date\n")); | 4105 DEBUG_INFO(("Problem occured formatting date\n")); |
4106 } | 4106 } |
4107 DEBUG_RET(); | 4107 DEBUG_RET(); |
4108 return buffer; | 4108 return buffer; |
4111 | 4111 |
4112 char *pst_rfc2445_datetime_format(FILETIME *ft) { | 4112 char *pst_rfc2445_datetime_format(FILETIME *ft) { |
4113 static char buffer[30]; | 4113 static char buffer[30]; |
4114 struct tm *stm = NULL; | 4114 struct tm *stm = NULL; |
4115 DEBUG_ENT("rfc2445_datetime_format"); | 4115 DEBUG_ENT("rfc2445_datetime_format"); |
4116 stm = fileTimeToStructTM(ft); | 4116 stm = pst_fileTimeToStructTM(ft); |
4117 if (strftime(buffer, sizeof(buffer), "%Y%m%dT%H%M%SZ", stm)==0) { | 4117 if (strftime(buffer, sizeof(buffer), "%Y%m%dT%H%M%SZ", stm)==0) { |
4118 DEBUG_INFO(("Problem occured formatting date\n")); | 4118 DEBUG_INFO(("Problem occured formatting date\n")); |
4119 } | 4119 } |
4120 DEBUG_RET(); | 4120 DEBUG_RET(); |
4121 return buffer; | 4121 return buffer; |
4205 return; | 4205 return; |
4206 } | 4206 } |
4207 const char *charset = pst_default_charset(item); | 4207 const char *charset = pst_default_charset(item); |
4208 if (!strcasecmp("utf-8", charset)) return; // already utf8 | 4208 if (!strcasecmp("utf-8", charset)) return; // already utf8 |
4209 DEBUG_ENT("pst_convert_utf8"); | 4209 DEBUG_ENT("pst_convert_utf8"); |
4210 vbuf *newer = vballoc(2); | 4210 vbuf *newer = pst_vballoc(2); |
4211 size_t rc = vb_8bit2utf8(newer, str->str, strlen(str->str) + 1, charset); | 4211 size_t rc = pst_vb_8bit2utf8(newer, str->str, strlen(str->str) + 1, charset); |
4212 if (rc == (size_t)-1) { | 4212 if (rc == (size_t)-1) { |
4213 free(newer->b); | 4213 free(newer->b); |
4214 DEBUG_EMAIL(("Failed to convert %s to utf-8 - %s\n", charset, str->str)); | 4214 DEBUG_EMAIL(("Failed to convert %s to utf-8 - %s\n", charset, str->str)); |
4215 } | 4215 } |
4216 else { | 4216 else { |