Mercurial > libpst
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; |