comparison src/libpst.c @ 190:e3a63888cdd4

add documentation for shared library interface
author Carl Byington <carl@five-ten-sg.com>
date Tue, 14 Apr 2009 22:26:17 -0700
parents d588dafd03e8
children 4b498fd68464
comparison
equal deleted inserted replaced
189:dc807f71d9d2 190:e3a63888cdd4
48 #define ENC_TYPE ((pf->do_read64) ? ENC_TYPE64 : ENC_TYPE32) 48 #define ENC_TYPE ((pf->do_read64) ? ENC_TYPE64 : ENC_TYPE32)
49 49
50 #define PST_SIGNATURE 0x4E444221 50 #define PST_SIGNATURE 0x4E444221
51 51
52 52
53 typedef struct pst_block_offset {
54 int16_t from;
55 int16_t to;
56 } pst_block_offset;
57
58
59 typedef struct pst_block_offset_pointer {
60 char *from;
61 char *to;
62 int needfree;
63 } pst_block_offset_pointer;
64
65
66 typedef struct pst_holder {
67 char **buf;
68 FILE *fp;
69 int base64;
70 } pst_holder;
71
72
73 typedef struct pst_subblock {
74 char *buf;
75 size_t read_size;
76 size_t i_offset;
77 } pst_subblock;
78
79
80 typedef struct pst_subblocks {
81 size_t subblock_count;
82 pst_subblock *subs;
83 } pst_subblocks;
84
85
86 typedef struct pst_mapi_element {
87 uint32_t mapi_id;
88 char *data;
89 uint32_t type;
90 size_t size;
91 char *extra;
92 } pst_mapi_element;
93
94
95 typedef struct pst_mapi_object {
96 int32_t count_elements; // count of active elements
97 int32_t orig_count; // originally allocated elements
98 int32_t count_objects; // number of mapi objects in the list
99 struct pst_mapi_element **elements;
100 struct pst_mapi_object *next;
101 } pst_mapi_object;
102
103
104 typedef struct pst_desc32 {
105 uint32_t d_id;
106 uint32_t desc_id;
107 uint32_t tree_id;
108 uint32_t parent_d_id;
109 } pst_desc32;
110
111
112 typedef struct pst_index32 {
113 uint32_t id;
114 uint32_t offset;
115 uint16_t size;
116 int16_t u1;
117 } pst_index32;
118
119
53 struct pst_table_ptr_struct32{ 120 struct pst_table_ptr_struct32{
54 uint32_t start; 121 uint32_t start;
55 uint32_t u1; 122 uint32_t u1;
56 uint32_t offset; 123 uint32_t offset;
57 }; 124 };
58 125
59 126
60 struct pst_table_ptr_structn{ 127 typedef struct pst_desc {
128 uint64_t d_id;
129 uint64_t desc_id;
130 uint64_t tree_id;
131 uint32_t parent_d_id; // not 64 bit
132 uint32_t u1; // padding
133 } pst_desc;
134
135
136 typedef struct pst_index {
137 uint64_t id;
138 uint64_t offset;
139 uint16_t size;
140 int16_t u0;
141 int32_t u1;
142 } pst_index;
143
144
145 struct pst_table_ptr_struct{
61 uint64_t start; 146 uint64_t start;
62 uint64_t u1; 147 uint64_t u1;
63 uint64_t offset; 148 uint64_t offset;
64 }; 149 };
65 150
536 pst_mapi_object *list; 621 pst_mapi_object *list;
537 pst_id2_tree *id2_head = NULL; 622 pst_id2_tree *id2_head = NULL;
538 char *buffer=NULL, *headerbuffer=NULL; 623 char *buffer=NULL, *headerbuffer=NULL;
539 size_t bsize=0, hsize=0, bptr=0; 624 size_t bsize=0, hsize=0, bptr=0;
540 pst_x_attrib xattrib; 625 pst_x_attrib xattrib;
541 int32_t tint, err=0, x; 626 int32_t tint, x;
542 pst_x_attrib_ll *ptr, *p_head=NULL; 627 pst_x_attrib_ll *ptr, *p_head=NULL;
543 628
544 DEBUG_ENT("pst_loadExtendedAttributes"); 629 DEBUG_ENT("pst_loadExtendedAttributes");
545 p = pst_getDptr(pf, (uint64_t)0x61); 630 p = pst_getDptr(pf, (uint64_t)0x61);
546 if (!p) { 631 if (!p) {
721 } 806 }
722 return r; 807 return r;
723 } 808 }
724 809
725 810
726 static size_t pst_decode_table(pst_file *pf, struct pst_table_ptr_structn *table, char *buf); 811 static size_t pst_decode_table(pst_file *pf, struct pst_table_ptr_struct *table, char *buf);
727 static size_t pst_decode_table(pst_file *pf, struct pst_table_ptr_structn *table, char *buf) { 812 static size_t pst_decode_table(pst_file *pf, struct pst_table_ptr_struct *table, char *buf) {
728 size_t r; 813 size_t r;
729 if (pf->do_read64) { 814 if (pf->do_read64) {
730 DEBUG_INDEX(("Decoding table64\n")); 815 DEBUG_INDEX(("Decoding table64\n"));
731 DEBUG_HEXDUMPC(buf, sizeof(struct pst_table_ptr_structn), 0x10); 816 DEBUG_HEXDUMPC(buf, sizeof(struct pst_table_ptr_struct), 0x10);
732 memcpy(table, buf, sizeof(struct pst_table_ptr_structn)); 817 memcpy(table, buf, sizeof(struct pst_table_ptr_struct));
733 LE64_CPU(table->start); 818 LE64_CPU(table->start);
734 LE64_CPU(table->u1); 819 LE64_CPU(table->u1);
735 LE64_CPU(table->offset); 820 LE64_CPU(table->offset);
736 r =sizeof(struct pst_table_ptr_structn); 821 r =sizeof(struct pst_table_ptr_struct);
737 } 822 }
738 else { 823 else {
739 struct pst_table_ptr_struct32 t32; 824 struct pst_table_ptr_struct32 t32;
740 DEBUG_INDEX(("Decoding table32\n")); 825 DEBUG_INDEX(("Decoding table32\n"));
741 DEBUG_HEXDUMPC(buf, sizeof( struct pst_table_ptr_struct32), 0x10); 826 DEBUG_HEXDUMPC(buf, sizeof( struct pst_table_ptr_struct32), 0x10);
839 * pf->i_head linked list from it. This tree holds the location 924 * pf->i_head linked list from it. This tree holds the location
840 * (offset and size) of lower level objects (0xbcec descriptor 925 * (offset and size) of lower level objects (0xbcec descriptor
841 * blocks, etc) in the pst file. 926 * blocks, etc) in the pst file.
842 */ 927 */
843 static int pst_build_id_ptr(pst_file *pf, int64_t offset, int32_t depth, uint64_t linku1, uint64_t start_val, uint64_t end_val) { 928 static int pst_build_id_ptr(pst_file *pf, int64_t offset, int32_t depth, uint64_t linku1, uint64_t start_val, uint64_t end_val) {
844 struct pst_table_ptr_structn table, table2; 929 struct pst_table_ptr_struct table, table2;
845 pst_index_ll *i_ptr=NULL; 930 pst_index_ll *i_ptr=NULL;
846 pst_index index; 931 pst_index index;
847 int32_t x, item_count; 932 int32_t x, item_count;
848 uint64_t old = start_val; 933 uint64_t old = start_val;
849 char *buf = NULL, *bptr; 934 char *buf = NULL, *bptr;
956 /** Process the index2 b-tree from the pst file and create the 1041 /** Process the index2 b-tree from the pst file and create the
957 * pf->d_head tree from it. This tree holds descriptions of the 1042 * pf->d_head tree from it. This tree holds descriptions of the
958 * higher level objects (email, contact, etc) in the pst file. 1043 * higher level objects (email, contact, etc) in the pst file.
959 */ 1044 */
960 static int pst_build_desc_ptr (pst_file *pf, int64_t offset, int32_t depth, uint64_t linku1, uint64_t start_val, uint64_t end_val) { 1045 static int pst_build_desc_ptr (pst_file *pf, int64_t offset, int32_t depth, uint64_t linku1, uint64_t start_val, uint64_t end_val) {
961 struct pst_table_ptr_structn table, table2; 1046 struct pst_table_ptr_struct table, table2;
962 pst_desc desc_rec; 1047 pst_desc desc_rec;
963 int32_t item_count; 1048 int32_t item_count;
964 uint64_t old = start_val; 1049 uint64_t old = start_val;
965 int x; 1050 int x;
966 char *buf = NULL, *bptr; 1051 char *buf = NULL, *bptr;
2265 break; 2350 break;
2266 case 0x0E1F: // PR_RTF_IN_SYNC 2351 case 0x0E1F: // PR_RTF_IN_SYNC
2267 // True means that the rtf version is same as text body 2352 // True means that the rtf version is same as text body
2268 // False means rtf version is more up-to-date than text body 2353 // False means rtf version is more up-to-date than text body
2269 // if this value doesn't exist, text body is more up-to-date than rtf and 2354 // if this value doesn't exist, text body is more up-to-date than rtf and
2270 // cannot update to the rtf 2355 // cannot update to the rtf
2271 LIST_COPY_EMAIL_BOOL("Compressed RTF in Sync", item->email->rtf_in_sync); 2356 LIST_COPY_EMAIL_BOOL("Compressed RTF in Sync", item->email->rtf_in_sync);
2272 break; 2357 break;
2273 case 0x0E20: // PR_ATTACH_SIZE binary Attachment data in record 2358 case 0x0E20: // PR_ATTACH_SIZE binary Attachment data in record
2274 NULL_CHECK(attach); 2359 NULL_CHECK(attach);
2275 LIST_COPY_INT32("Attachment Size", t); 2360 LIST_COPY_INT32("Attachment Size", t);
2788 LIST_COPY_CONTACT_STR("Email Address 3 Record", item->contact->address3a); 2873 LIST_COPY_CONTACT_STR("Email Address 3 Record", item->contact->address3a);
2789 break; 2874 break;
2790 case 0x80D8: // Internet Free/Busy 2875 case 0x80D8: // Internet Free/Busy
2791 LIST_COPY_CONTACT_STR("Internet Free/Busy", item->contact->free_busy_address); 2876 LIST_COPY_CONTACT_STR("Internet Free/Busy", item->contact->free_busy_address);
2792 break; 2877 break;
2793 case 0x8205: // Show on Free/Busy as 2878 case 0x8205: // PR_OUTLOOK_EVENT_SHOW_TIME_AS
2794 LIST_COPY_APPT_ENUM("Appointment shows as", item->appointment->showas, 0, 4, 2879 LIST_COPY_APPT_ENUM("Appointment shows as", item->appointment->showas, 0, 4,
2795 "Free", "Tentative", "Busy", "Out Of Office"); 2880 "Free", "Tentative", "Busy", "Out Of Office");
2796 break; 2881 break;
2797 case 0x8208: // Location of an appointment 2882 case 0x8208: // PR_OUTLOOK_EVENT_LOCATION
2798 LIST_COPY_APPT_STR("Appointment Location", item->appointment->location); 2883 LIST_COPY_APPT_STR("Appointment Location", item->appointment->location);
2799 break; 2884 break;
2800 case 0x820d: // Appointment start 2885 case 0x820d: // PR_OUTLOOK_EVENT_START_DATE
2801 LIST_COPY_APPT_TIME("Appointment Date Start", item->appointment->start); 2886 LIST_COPY_APPT_TIME("Appointment Date Start", item->appointment->start);
2802 break; 2887 break;
2803 case 0x820e: // Appointment end 2888 case 0x820e: // PR_OUTLOOK_EVENT_START_END
2804 LIST_COPY_APPT_TIME("Appointment Date End", item->appointment->end); 2889 LIST_COPY_APPT_TIME("Appointment Date End", item->appointment->end);
2805 break; 2890 break;
2806 case 0x8214: // Label for an appointment 2891 case 0x8214: // Label for an appointment
2807 LIST_COPY_APPT_ENUM("Label for appointment", item->appointment->label, 0, 11, 2892 LIST_COPY_APPT_ENUM("Label for appointment", item->appointment->label, 0, 11,
2808 "None", 2893 "None",
2815 "Needs Preparation", 2900 "Needs Preparation",
2816 "Birthday", 2901 "Birthday",
2817 "Anniversary", 2902 "Anniversary",
2818 "Phone Call"); 2903 "Phone Call");
2819 break; 2904 break;
2820 case 0x8215: // All day appointment flag 2905 case 0x8215: // PR_OUTLOOK_EVENT_ALL_DAY
2821 LIST_COPY_APPT_BOOL("All day flag", item->appointment->all_day); 2906 LIST_COPY_APPT_BOOL("All day flag", item->appointment->all_day);
2822 break; 2907 break;
2823 case 0x8231: // Recurrence type 2908 case 0x8231: // Recurrence type
2824 LIST_COPY_APPT_ENUM("Appointment reccurence", item->appointment->recurrence_type, 0, 5, 2909 LIST_COPY_APPT_ENUM("Appointment reccurence", item->appointment->recurrence_type, 0, 5,
2825 "None", 2910 "None",
2832 LIST_COPY_APPT_STR("Appointment recurrence description", item->appointment->recurrence); 2917 LIST_COPY_APPT_STR("Appointment recurrence description", item->appointment->recurrence);
2833 break; 2918 break;
2834 case 0x8234: // TimeZone as String 2919 case 0x8234: // TimeZone as String
2835 LIST_COPY_APPT_STR("TimeZone of times", item->appointment->timezonestring); 2920 LIST_COPY_APPT_STR("TimeZone of times", item->appointment->timezonestring);
2836 break; 2921 break;
2837 case 0x8235: // Recurrence start date 2922 case 0x8235: // PR_OUTLOOK_EVENT_RECURRENCE_START
2838 LIST_COPY_APPT_TIME("Recurrence Start Date", item->appointment->recurrence_start); 2923 LIST_COPY_APPT_TIME("Recurrence Start Date", item->appointment->recurrence_start);
2839 break; 2924 break;
2840 case 0x8236: // Recurrence end date 2925 case 0x8236: // PR_OUTLOOK_EVENT_RECURRENCE_END
2841 LIST_COPY_APPT_TIME("Recurrence End Date", item->appointment->recurrence_end); 2926 LIST_COPY_APPT_TIME("Recurrence End Date", item->appointment->recurrence_end);
2842 break; 2927 break;
2843 case 0x8501: // Reminder minutes before appointment start 2928 case 0x8501: // PR_OUTLOOK_COMMON_REMINDER_MINUTES_BEFORE
2844 LIST_COPY_APPT_INT32("Alarm minutes", item->appointment->alarm_minutes); 2929 LIST_COPY_APPT_INT32("Alarm minutes", item->appointment->alarm_minutes);
2845 break; 2930 break;
2846 case 0x8503: // Reminder alarm 2931 case 0x8503: // PR_OUTLOOK_COMMON_REMINDER_SET
2847 LIST_COPY_APPT_BOOL("Reminder alarm", item->appointment->alarm); 2932 LIST_COPY_APPT_BOOL("Reminder alarm", item->appointment->alarm);
2848 break; 2933 break;
2849 case 0x8516: // Common start 2934 case 0x8516: // Common start
2850 DEBUG_EMAIL(("Common Start Date - %s\n", pst_fileTimeToAscii((FILETIME*)list->elements[x]->data))); 2935 DEBUG_EMAIL(("Common Start Date - %s\n", pst_fileTimeToAscii((FILETIME*)list->elements[x]->data)));
2851 break; 2936 break;
2862 LIST_COPY_CONTACT_STR("Mileage", item->contact->mileage); 2947 LIST_COPY_CONTACT_STR("Mileage", item->contact->mileage);
2863 break; 2948 break;
2864 case 0x8535: // Billing Information 2949 case 0x8535: // Billing Information
2865 LIST_COPY_CONTACT_STR("Billing Information", item->contact->billing_information); 2950 LIST_COPY_CONTACT_STR("Billing Information", item->contact->billing_information);
2866 break; 2951 break;
2867 case 0x8554: // Outlook Version 2952 case 0x8554: // PR_OUTLOOK_VERSION
2868 LIST_COPY_STR("Outlook Version", item->outlook_version); 2953 LIST_COPY_STR("Outlook Version", item->outlook_version);
2869 break; 2954 break;
2870 case 0x8560: // Appointment Reminder Time 2955 case 0x8560: // Appointment Reminder Time
2871 LIST_COPY_APPT_TIME("Appointment Reminder Time", item->appointment->reminder); 2956 LIST_COPY_APPT_TIME("Appointment Reminder Time", item->appointment->reminder);
2872 break; 2957 break;
4086 DEBUG_RET(); 4171 DEBUG_RET();
4087 return buffer; 4172 return buffer;
4088 } 4173 }
4089 4174
4090 4175
4091 /** Convert a code page integer into a string suitable for iconv 4176 /** Convert a code page integer into a string suitable for iconv()
4092 * 4177 *
4093 * @param cp the code page integer used in the pst file 4178 * @param cp the code page integer used in the pst file
4094 * @return pointer to a static buffer holding the string representation of the 4179 * @return pointer to a static buffer holding the string representation of the
4095 * equivalent iconv character set 4180 * equivalent iconv character set
4096 */ 4181 */
4131 } 4216 }
4132 return NULL; 4217 return NULL;
4133 } 4218 }
4134 4219
4135 4220
4136 /** get the default character set for this item 4221 /** Get the default character set for this item. This is used to find
4137 * @param item pointer to the mapi item of interest 4222 * the charset for pst_string elements that are not already in utf8 encoding.
4138 * @return default character set 4223 * @param item pointer to the mapi item of interest
4224 * @return default character set as a string useable by iconv()
4139 */ 4225 */
4140 const char* pst_default_charset(pst_item *item) 4226 const char* pst_default_charset(pst_item *item)
4141 { 4227 {
4142 return (item->body_charset.str) ? item->body_charset.str : 4228 return (item->body_charset.str) ? item->body_charset.str :
4143 (item->message_codepage) ? codepage(item->message_codepage) : 4229 (item->message_codepage) ? codepage(item->message_codepage) :
4146 } 4232 }
4147 4233
4148 4234
4149 /** Convert str to utf8 if possible; null strings are preserved. 4235 /** Convert str to utf8 if possible; null strings are preserved.
4150 * 4236 *
4151 * @param item pointer to the mapi item of interest 4237 * @param item pointer to the containing mapi item
4152 * @param str pointer to the mapi string of interest 4238 * @param str pointer to the mapi string of interest
4153 */ 4239 */
4154 void pst_convert_utf8_null(pst_item *item, pst_string *str) 4240 void pst_convert_utf8_null(pst_item *item, pst_string *str)
4155 { 4241 {
4156 if (!str->str) return; 4242 if (!str->str) return;
4158 } 4244 }
4159 4245
4160 4246
4161 /** Convert str to utf8 if possible; null strings are converted into empty strings. 4247 /** Convert str to utf8 if possible; null strings are converted into empty strings.
4162 * 4248 *
4163 * @param item pointer to the mapi item of interest 4249 * @param item pointer to the containing mapi item
4164 * @param str pointer to the mapi string of interest 4250 * @param str pointer to the mapi string of interest
4165 */ 4251 */
4166 void pst_convert_utf8(pst_item *item, pst_string *str) 4252 void pst_convert_utf8(pst_item *item, pst_string *str)
4167 { 4253 {
4168 if (str->is_utf8) return; 4254 if (str->is_utf8) return;