Mercurial > libpst
comparison src/libpst.c @ 191:4b498fd68464
add pst_attach_to_mem() back into the shared library interface.
improve developer documentation.
fix memory leak caught by valgrind.
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Wed, 15 Apr 2009 18:39:42 -0700 |
parents | e3a63888cdd4 |
children | cf3df962f1e5 |
comparison
equal
deleted
inserted
replaced
190:e3a63888cdd4 | 191:4b498fd68464 |
---|---|
14 #pragma pack(push, 1) | 14 #pragma pack(push, 1) |
15 #endif | 15 #endif |
16 #if defined(__GNUC__) || defined (__SUNPRO_C) || defined(__SUNPRO_CC) | 16 #if defined(__GNUC__) || defined (__SUNPRO_C) || defined(__SUNPRO_CC) |
17 #pragma pack(1) | 17 #pragma pack(1) |
18 #endif | 18 #endif |
19 | |
20 | 19 |
21 #define ASSERT(x) { if(!(x)) raise( SIGSEGV ); } | 20 #define ASSERT(x) { if(!(x)) raise( SIGSEGV ); } |
22 | 21 |
23 #define INDEX_TYPE32 0x0E | 22 #define INDEX_TYPE32 0x0E |
24 #define INDEX_TYPE32A 0x0F // unknown, but assumed to be similar for now | 23 #define INDEX_TYPE32A 0x0F // unknown, but assumed to be similar for now |
446 //DEBUG_INDEX(("Null parent\n")); | 445 //DEBUG_INDEX(("Null parent\n")); |
447 add_descriptor_to_list(node, &pf->d_head, &pf->d_tail); | 446 add_descriptor_to_list(node, &pf->d_head, &pf->d_tail); |
448 } | 447 } |
449 else if (node->parent_d_id == node->d_id) { | 448 else if (node->parent_d_id == node->d_id) { |
450 // add top level node to the descriptor tree | 449 // add top level node to the descriptor tree |
451 DEBUG_INDEX(("%#"PRIx64" is its own parent. What is this world coming to?\n")); | 450 DEBUG_INDEX(("%#"PRIx64" is its own parent. What is this world coming to?\n", node->d_id)); |
452 add_descriptor_to_list(node, &pf->d_head, &pf->d_tail); | 451 add_descriptor_to_list(node, &pf->d_head, &pf->d_tail); |
453 } else { | 452 } else { |
454 //DEBUG_INDEX(("Searching for parent %#"PRIx64" of %#"PRIx64"\n", node->parent_d_id, node->d_id)); | 453 //DEBUG_INDEX(("Searching for parent %#"PRIx64" of %#"PRIx64"\n", node->parent_d_id, node->d_id)); |
455 pst_desc_tree *parent = pst_getDptr(pf, node->parent_d_id); | 454 pst_desc_tree *parent = pst_getDptr(pf, node->parent_d_id); |
456 if (parent) { | 455 if (parent) { |
518 DEBUG_RET(); | 517 DEBUG_RET(); |
519 return topnode; | 518 return topnode; |
520 } | 519 } |
521 | 520 |
522 | 521 |
522 size_t pst_attach_to_mem(pst_file *pf, pst_item_attach *attach, char **b) { | |
523 pst_index_ll *ptr; | |
524 pst_holder h = {b, NULL, 0}; | |
525 size_t size = 0; | |
526 DEBUG_ENT("pst_attach_to_mem"); | |
527 if (attach->i_id != (uint64_t)-1) { | |
528 ptr = pst_getID(pf, attach->i_id); | |
529 if (ptr) { | |
530 size = pst_ff_getID2data(pf, ptr, &h); | |
531 } else { | |
532 DEBUG_WARN(("Couldn't find ID pointer. Cannot handle attachment\n")); | |
533 } | |
534 attach->data.size = size; | |
535 } else { | |
536 size = attach->data.size; | |
537 *b = attach->data.data; | |
538 } | |
539 DEBUG_RET(); | |
540 return size; | |
541 } | |
542 | |
543 | |
523 size_t pst_attach_to_file(pst_file *pf, pst_item_attach *attach, FILE* fp) { | 544 size_t pst_attach_to_file(pst_file *pf, pst_item_attach *attach, FILE* fp) { |
524 pst_index_ll *ptr; | 545 pst_index_ll *ptr; |
525 pst_holder h = {NULL, fp, 0}; | 546 pst_holder h = {NULL, fp, 0}; |
526 size_t size = 0; | 547 size_t size = 0; |
527 DEBUG_ENT("pst_attach_to_file"); | 548 DEBUG_ENT("pst_attach_to_file"); |
556 DEBUG_WARN(("Couldn't find ID pointer. Cannot save attachment to Base64\n")); | 577 DEBUG_WARN(("Couldn't find ID pointer. Cannot save attachment to Base64\n")); |
557 } | 578 } |
558 attach->data.size = size; | 579 attach->data.size = size; |
559 } else { | 580 } else { |
560 // encode the attachment to the file | 581 // encode the attachment to the file |
561 char *c = pst_base64_encode(attach->data.data, attach->data.size); | 582 size = attach->data.size; |
583 char *c = pst_base64_encode(attach->data.data, size); | |
562 if (c) { | 584 if (c) { |
563 (void)pst_fwrite(c, (size_t)1, strlen(c), fp); | 585 (void)pst_fwrite(c, (size_t)1, strlen(c), fp); |
564 free(c); // caught by valgrind | 586 free(c); // caught by valgrind |
565 } | 587 } |
566 size = attach->data.size; | |
567 } | 588 } |
568 DEBUG_RET(); | 589 DEBUG_RET(); |
569 return size; | 590 return size; |
570 } | 591 } |
571 | 592 |
684 xattrib.extended= PST_LE_GET_UINT32(buffer+bptr), bptr += 4; | 705 xattrib.extended= PST_LE_GET_UINT32(buffer+bptr), bptr += 4; |
685 xattrib.type = PST_LE_GET_UINT16(buffer+bptr), bptr += 2; | 706 xattrib.type = PST_LE_GET_UINT16(buffer+bptr), bptr += 2; |
686 xattrib.map = PST_LE_GET_UINT16(buffer+bptr), bptr += 2; | 707 xattrib.map = PST_LE_GET_UINT16(buffer+bptr), bptr += 2; |
687 ptr = (pst_x_attrib_ll*) pst_malloc(sizeof(*ptr)); | 708 ptr = (pst_x_attrib_ll*) pst_malloc(sizeof(*ptr)); |
688 memset(ptr, 0, sizeof(*ptr)); | 709 memset(ptr, 0, sizeof(*ptr)); |
689 ptr->type = xattrib.type; | |
690 ptr->map = xattrib.map+0x8000; | 710 ptr->map = xattrib.map+0x8000; |
691 ptr->next = NULL; | 711 ptr->next = NULL; |
692 DEBUG_INDEX(("xattrib: ext = %#"PRIx32", type = %#"PRIx16", map = %#"PRIx16"\n", | 712 DEBUG_INDEX(("xattrib: ext = %#"PRIx32", type = %#"PRIx16", map = %#"PRIx16"\n", |
693 xattrib.extended, xattrib.type, xattrib.map)); | 713 xattrib.extended, xattrib.type, xattrib.map)); |
694 if (xattrib.type & 0x0001) { // if the Bit 1 is set | 714 if (xattrib.type & 0x0001) { // if the Bit 1 is set |
1260 return NULL; | 1280 return NULL; |
1261 } | 1281 } |
1262 pst_free_list(list); | 1282 pst_free_list(list); |
1263 | 1283 |
1264 // now we will have initial information of each attachment stored in item->attach... | 1284 // now we will have initial information of each attachment stored in item->attach... |
1265 // we must now read the secondary record for each based on the id2 val associated with | 1285 // we must now read the secondary record for each based on the id2_val associated with |
1266 // each attachment | 1286 // each attachment |
1267 attach = item->attach; | 1287 for (attach = item->attach; attach; attach = attach->next) { |
1268 while (attach) { | |
1269 DEBUG_WARN(("initial attachment id2 %#"PRIx64"\n", attach->id2_val)); | 1288 DEBUG_WARN(("initial attachment id2 %#"PRIx64"\n", attach->id2_val)); |
1270 if ((id2_ptr = pst_getID2(id2_head, attach->id2_val))) { | 1289 if ((id2_ptr = pst_getID2(id2_head, attach->id2_val))) { |
1271 DEBUG_WARN(("initial attachment id2 found id %#"PRIx64"\n", id2_ptr->id->i_id)); | 1290 DEBUG_WARN(("initial attachment id2 found id %#"PRIx64"\n", id2_ptr->id->i_id)); |
1272 // id_ptr is a record describing the attachment | 1291 // id2_ptr is a record describing the attachment |
1273 // we pass NULL instead of id2_head cause we don't want it to | 1292 // we pass NULL instead of id2_head cause we don't want it to |
1274 // load all the extra stuff here. | 1293 // load all the extra stuff here. |
1275 list = pst_parse_block(pf, id2_ptr->id->i_id, NULL); | 1294 list = pst_parse_block(pf, id2_ptr->id->i_id, NULL); |
1276 if (!list) { | 1295 if (!list) { |
1277 DEBUG_WARN(("ERROR error processing an attachment record\n")); | 1296 DEBUG_WARN(("ERROR error processing an attachment record\n")); |
1278 attach = attach->next; | |
1279 continue; | 1297 continue; |
1280 } | 1298 } |
1281 if (list->count_objects > 1) { | 1299 if (list->count_objects > 1) { |
1282 DEBUG_WARN(("ERROR probably fatal, list count array will overrun attach structure.\n")); | 1300 DEBUG_WARN(("ERROR probably fatal, list count array will overrun attach structure.\n")); |
1283 } | 1301 } |
1284 if (pst_process(list, item, attach)) { | 1302 if (pst_process(list, item, attach)) { |
1285 DEBUG_WARN(("ERROR pst_process() failed with an attachment\n")); | 1303 DEBUG_WARN(("ERROR pst_process() failed with an attachment\n")); |
1286 pst_free_list(list); | 1304 pst_free_list(list); |
1287 attach = attach->next; | |
1288 continue; | 1305 continue; |
1289 } | 1306 } |
1290 pst_free_list(list); | 1307 pst_free_list(list); |
1291 id2_ptr = pst_getID2(id2_head, attach->id2_val); | 1308 id2_ptr = pst_getID2(id2_head, attach->id2_val); |
1292 if (id2_ptr) { | 1309 if (id2_ptr) { |
1300 } | 1317 } |
1301 } else { | 1318 } else { |
1302 DEBUG_WARN(("ERROR cannot locate id2 value %#"PRIx64"\n", attach->id2_val)); | 1319 DEBUG_WARN(("ERROR cannot locate id2 value %#"PRIx64"\n", attach->id2_val)); |
1303 attach->id2_val = 0; // suppress this missing attachment | 1320 attach->id2_val = 0; // suppress this missing attachment |
1304 } | 1321 } |
1305 attach = attach->next; | |
1306 } | 1322 } |
1307 } | 1323 } |
1308 | 1324 |
1309 if (!m_head) pst_free_id2(id2_head); | 1325 if (!m_head) pst_free_id2(id2_head); |
1310 DEBUG_RET(); | 1326 DEBUG_RET(); |
2078 switch (list->elements[x]->mapi_id) { | 2094 switch (list->elements[x]->mapi_id) { |
2079 case PST_ATTRIB_HEADER: // CUSTOM attribute for saying the Extra Headers | 2095 case PST_ATTRIB_HEADER: // CUSTOM attribute for saying the Extra Headers |
2080 if (list->elements[x]->extra) { | 2096 if (list->elements[x]->extra) { |
2081 pst_item_extra_field *ef = (pst_item_extra_field*) pst_malloc(sizeof(pst_item_extra_field)); | 2097 pst_item_extra_field *ef = (pst_item_extra_field*) pst_malloc(sizeof(pst_item_extra_field)); |
2082 memset(ef, 0, sizeof(pst_item_extra_field)); | 2098 memset(ef, 0, sizeof(pst_item_extra_field)); |
2083 ef->field_name = strdup(list->elements[x]->extra); | |
2084 LIST_COPY_CSTR(ef->value); | 2099 LIST_COPY_CSTR(ef->value); |
2085 if (ef->value) { | 2100 if (ef->value) { |
2086 ef->next = item->extra_fields; | 2101 ef->field_name = strdup(list->elements[x]->extra); |
2102 ef->next = item->extra_fields; | |
2087 item->extra_fields = ef; | 2103 item->extra_fields = ef; |
2088 DEBUG_EMAIL(("Extra Field - \"%s\" = \"%s\"\n", ef->field_name, ef->value)); | 2104 DEBUG_EMAIL(("Extra Field - \"%s\" = \"%s\"\n", ef->field_name, ef->value)); |
2089 if (strcmp(ef->field_name, "content-type") == 0) { | 2105 if (strcmp(ef->field_name, "content-type") == 0) { |
2090 char *p = strstr(ef->value, "charset=\""); | 2106 char *p = strstr(ef->value, "charset=\""); |
2091 if (p) { | 2107 if (p) { |
2104 } | 2120 } |
2105 } | 2121 } |
2106 else { | 2122 else { |
2107 DEBUG_EMAIL(("What does this mean? Internet header %s value\n", list->elements[x]->extra)); | 2123 DEBUG_EMAIL(("What does this mean? Internet header %s value\n", list->elements[x]->extra)); |
2108 DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size); | 2124 DEBUG_HEXDUMP(list->elements[x]->data, list->elements[x]->size); |
2125 free(ef); // caught by valgrind | |
2109 } | 2126 } |
2110 } | 2127 } |
2111 break; | 2128 break; |
2112 case 0x0002: // PR_ALTERNATE_RECIPIENT_ALLOWED | 2129 case 0x0002: // PR_ALTERNATE_RECIPIENT_ALLOWED |
2113 if (list->elements[x]->type == 0x0b) { | 2130 if (list->elements[x]->type == 0x0b) { |
3806 return rc; | 3823 return rc; |
3807 } | 3824 } |
3808 | 3825 |
3809 | 3826 |
3810 /** | 3827 /** |
3811 * Get an ID block from file using _pst_ff_getIDblock and decrypt if necessary | 3828 * Get an ID block from file using pst_ff_getIDblock() and decrypt if necessary |
3812 * | |
3813 * @param pf PST file structure | 3829 * @param pf PST file structure |
3814 * @param i_id ID of block to retrieve | 3830 * @param i_id ID of block to retrieve |
3815 * @param buf reference to pointer to buffer that will contain the data block. | 3831 * @param buf reference to pointer to buffer that will contain the data block. |
3816 * If this pointer is non-NULL, it will first be free()d. | 3832 * If this pointer is non-NULL, it will first be free()d. |
3817 * @return Size of block read into memory | 3833 * @return Size of block read into memory |
4083 static char* buf = NULL; | 4099 static char* buf = NULL; |
4084 static size_t buflen = 0; | 4100 static size_t buflen = 0; |
4085 char *ret, *a, *b; | 4101 char *ret, *a, *b; |
4086 size_t x = 0; | 4102 size_t x = 0; |
4087 int y, z; | 4103 int y, z; |
4104 if (!str) return NULL; | |
4088 DEBUG_ENT("rfc2426_escape"); | 4105 DEBUG_ENT("rfc2426_escape"); |
4089 if (!str) | 4106 // calculate space required to escape all the following characters |
4107 y = pst_chr_count(str, ',') | |
4108 + pst_chr_count(str, '\\') | |
4109 + pst_chr_count(str, ';') | |
4110 + pst_chr_count(str, '\n'); | |
4111 z = pst_chr_count(str, '\r'); | |
4112 if (y == 0 && z == 0) | |
4113 // there isn't any extra space required | |
4090 ret = str; | 4114 ret = str; |
4091 else { | 4115 else { |
4092 | 4116 x = strlen(str) + y - z + 1; // don't forget room for the NUL |
4093 // calculate space required to escape all the following characters | 4117 if (x > buflen) { |
4094 y = pst_chr_count(str, ',') | 4118 buf = (char*) realloc(buf, x); |
4095 + pst_chr_count(str, '\\') | 4119 buflen = x; |
4096 + pst_chr_count(str, ';') | 4120 } |
4097 + pst_chr_count(str, '\n'); | 4121 a = str; |
4098 z = pst_chr_count(str, '\r'); | 4122 b = buf; |
4099 if (y == 0 && z == 0) | 4123 while (*a != '\0') { |
4100 // there isn't any extra space required | 4124 switch (*a) { |
4101 ret = str; | 4125 case ',' : |
4102 else { | 4126 case '\\': |
4103 x = strlen(str) + y - z + 1; // don't forget room for the NUL | 4127 case ';' : |
4104 if (x > buflen) { | 4128 *(b++) = '\\'; |
4105 buf = (char*) realloc(buf, x); | 4129 *b = *a; |
4106 buflen = x; | 4130 break; |
4131 case '\n': // newlines are encoded as "\n" | |
4132 *(b++) = '\\'; | |
4133 *b = 'n'; | |
4134 break; | |
4135 case '\r': // skip cr | |
4136 b--; | |
4137 break; | |
4138 default: | |
4139 *b=*a; | |
4107 } | 4140 } |
4108 a = str; | 4141 b++; |
4109 b = buf; | 4142 a++; |
4110 while (*a != '\0') { | 4143 } |
4111 switch (*a) { | 4144 *b = '\0'; // NUL-terminate the string (buf) |
4112 case ',' : | 4145 ret = buf; |
4113 case '\\': | |
4114 case ';' : | |
4115 *(b++) = '\\'; | |
4116 *b = *a; | |
4117 break; | |
4118 case '\n': // newlines are encoded as "\n" | |
4119 *(b++) = '\\'; | |
4120 *b = 'n'; | |
4121 break; | |
4122 case '\r': // skip cr | |
4123 b--; | |
4124 break; | |
4125 default: | |
4126 *b=*a; | |
4127 } | |
4128 b++; | |
4129 a++; | |
4130 } | |
4131 *b = '\0'; // NUL-terminate the string (buf) | |
4132 ret = buf; | |
4133 } | |
4134 } | 4146 } |
4135 DEBUG_RET(); | 4147 DEBUG_RET(); |
4136 return ret; | 4148 return ret; |
4137 } | 4149 } |
4138 | 4150 |