comparison src/pst2ldif.cpp @ 73:3cb02cb1e6cd stable-0-6-10

Patch from Robert Simpson to fix doubly-linked list in the cache_ptr code, and allow arrays of unicode strings (without converting them). More changes for Fedora packaging (#434727) Fixes for const correctness.
author Carl Byington <carl@five-ten-sg.com>
date Thu, 29 May 2008 18:51:02 -0700
parents 7d5c637aaafb
children 56fa05fd5271
comparison
equal deleted inserted replaced
72:c21e9c001256 73:3cb02cb1e6cd
12 12
13 // needed for std c++ collections 13 // needed for std c++ collections
14 #include <set> 14 #include <set>
15 15
16 extern "C" { 16 extern "C" {
17 #include "define.h" 17 #include "define.h"
18 #include "libstrfunc.h" 18 #include "libstrfunc.h"
19 #include "libpst.h" 19 #include "libpst.h"
20 #include "common.h" 20 #include "common.h"
21 #include "timeconv.h" 21 #include "timeconv.h"
22 #include "lzfu.h" 22 #include "lzfu.h"
23 } 23 }
24 24
25 int32_t usage(); 25 int32_t usage();
26 int32_t version(); 26 int32_t version();
27 char *my_stristr(char *haystack, char *needle); 27 char *my_stristr(char *haystack, char *needle);
28 char *check_filename(char *fname); 28 char *check_filename(char *fname);
29 char *single(char *str); 29 const char *single(char *str);
30 char *folded(char *str); 30 const char *folded(char *str);
31 void multi(char *fmt, char *str); 31 void multi(const char *fmt, char *str);
32 char *rfc2426_escape(char *str); 32 char *rfc2426_escape(char *str);
33 int32_t chr_count(char *str, char x); 33 int32_t chr_count(char *str, char x);
34 34
35 char *prog_name; 35 char *prog_name;
36 pst_file pstfile; 36 pst_file pstfile;
37 char *ldap_base = NULL; // 'o=some.domain.tld, c=US' 37 char *ldap_base = NULL; // 'o=some.domain.tld, c=US'
38 char *ldap_class = NULL; // 'newPerson' 38 char *ldap_class = NULL; // 'newPerson'
39 char *ldap_org = NULL; // 'o=some.domain.tld', computed from ldap_base 39 char *ldap_org = NULL; // 'o=some.domain.tld', computed from ldap_base
40 40
41 41
42 //////////////////////////////////////////////// 42 ////////////////////////////////////////////////
43 // define our ordering 43 // define our ordering
44 struct ltstr { 44 struct ltstr {
45 bool operator()(char* s1, char* s2) const { 45 bool operator()(const char* s1, const char* s2) const {
46 return strcasecmp(s1, s2) < 0; 46 return strcasecmp(s1, s2) < 0;
47 } 47 }
48 }; 48 };
49 // define our set 49 // define our set
50 typedef set<char *, ltstr> string_set; 50 typedef set<const char *, ltstr> string_set;
51 // make a static set to hold the cn values 51 // make a static set to hold the cn values
52 static string_set all_strings; 52 static string_set all_strings;
53 53
54 54
55 //////////////////////////////////////////////// 55 ////////////////////////////////////////////////
56 // helper to free all the strings in a set 56 // helper to free all the strings in a set
57 // 57 //
58 static void free_strings(string_set &s); 58 static void free_strings(string_set &s);
59 static void free_strings(string_set &s) 59 static void free_strings(string_set &s)
60 { 60 {
61 for (string_set::iterator i=s.begin(); i!=s.end(); i++) { 61 for (string_set::iterator i=s.begin(); i!=s.end(); i++) {
62 free(*i); 62 free((void*)*i);
63 } 63 }
64 s.clear(); 64 s.clear();
65 } 65 }
66 66
67 67
68 //////////////////////////////////////////////// 68 ////////////////////////////////////////////////
69 // helper to register a string in a string set 69 // helper to register a string in a string set
70 // 70 //
71 static char* register_string(string_set &s, char *name); 71 static const char* register_string(string_set &s, const char *name);
72 static char* register_string(string_set &s, char *name) { 72 static const char* register_string(string_set &s, const char *name) {
73 string_set::iterator i = s.find(name); 73 string_set::const_iterator i = s.find(name);
74 if (i != s.end()) return *i; 74 if (i != s.end()) return *i;
75 char *x = strdup(name); 75 char *x = strdup(name);
76 s.insert(x); 76 s.insert(x);
77 return x; 77 return x;
78 } 78 }
79 79
80 //////////////////////////////////////////////// 80 ////////////////////////////////////////////////
81 // register a global string 81 // register a global string
82 // 82 //
83 static char* register_string(char *name); 83 static const char* register_string(const char *name);
84 static char* register_string(char *name) { 84 static const char* register_string(const char *name) {
85 return register_string(all_strings, name); 85 return register_string(all_strings, name);
86 } 86 }
87 87
88 88
89 //////////////////////////////////////////////// 89 ////////////////////////////////////////////////
90 // make a unique string 90 // make a unique string
91 // 91 //
92 static char* unique_string(char *name); 92 static const char* unique_string(const char *name);
93 static char* unique_string(char *name) { 93 static const char* unique_string(const char *name) {
94 int unique = 2; 94 int unique = 2;
95 string_set::iterator i = all_strings.find(name); 95 string_set::iterator i = all_strings.find(name);
96 if (i == all_strings.end()) return register_string(name); 96 if (i == all_strings.end()) return register_string(name);
97 while (true) { 97 while (true) {
98 char n[strlen(name)+10]; 98 char n[strlen(name)+10];
99 snprintf(n, sizeof(n), "%s %d", name, unique++); 99 snprintf(n, sizeof(n), "%s %d", name, unique++);
100 string_set::iterator i = all_strings.find(n); 100 string_set::iterator i = all_strings.find(n);
101 if (i == all_strings.end()) return register_string(n); 101 if (i == all_strings.end()) return register_string(n);
102 } 102 }
103 } 103 }
104 104
105 105
106 //////////////////////////////////////////////// 106 ////////////////////////////////////////////////
107 // remove leading and trailing blanks 107 // remove leading and trailing blanks
108 // 108 //
109 static char *trim(char *name); 109 static char *trim(char *name);
110 static char *trim(char *name) { 110 static char *trim(char *name) {
111 char *p; 111 char *p;
112 while (*name == ' ') name++; 112 while (*name == ' ') name++;
113 p = name + strlen(name) - 1; 113 p = name + strlen(name) - 1;
114 while ((p >= name) && (*p == ' ')) *p-- = '\0'; 114 while ((p >= name) && (*p == ' ')) *p-- = '\0';
115 return name; 115 return name;
116 } 116 }
117 117
118 118
119 static void process(pst_desc_ll *d_ptr); 119 static void process(pst_desc_ll *d_ptr);
120 static void process(pst_desc_ll *d_ptr) { 120 static void process(pst_desc_ll *d_ptr) {
121 pst_item *item = NULL; 121 pst_item *item = NULL;
122 while (d_ptr) { 122 while (d_ptr) {
123 if (d_ptr->desc) { 123 if (d_ptr->desc) {
124 item = pst_parse_item(&pstfile, d_ptr); 124 item = pst_parse_item(&pstfile, d_ptr);
125 DEBUG_INFO(("item pointer is %p\n", item)); 125 DEBUG_INFO(("item pointer is %p\n", item));
126 if (item) { 126 if (item) {
127 if (item->message_store) { 127 if (item->message_store) {
128 // there should only be one message_store, and we have already done it 128 // there should only be one message_store, and we have already done it
129 DIE(("main: A second message_store has been found. Sorry, this must be an error.\n")); 129 DIE(("main: A second message_store has been found. Sorry, this must be an error.\n"));
130 } 130 }
131 131
132 if (item->folder && d_ptr->child && strcasecmp(item->file_as, "Deleted Items")) { 132 if (item->folder && d_ptr->child && strcasecmp(item->file_as, "Deleted Items")) {
133 //if this is a non-empty folder other than deleted items, we want to recurse into it 133 //if this is a non-empty folder other than deleted items, we want to recurse into it
134 fprintf(stderr, "entering folder %s\n", item->file_as); 134 fprintf(stderr, "entering folder %s\n", item->file_as);
135 process(d_ptr->child); 135 process(d_ptr->child);
136 } else if (item->contact) { 136 } else if (item->contact) {
137 // deal with a contact 137 // deal with a contact
138 if (item->type != PST_TYPE_CONTACT) { 138 if (item->type != PST_TYPE_CONTACT) {
139 DIE(("type should be contact\n")); 139 DIE(("type should be contact\n"));
140 } 140 }
141 else if (item->contact == NULL) { // this is an incorrect situation. Inform user 141 else if (item->contact == NULL) { // this is an incorrect situation. Inform user
142 DIE(("null item contact\n")); 142 DIE(("null item contact\n"));
143 } else { 143 } else {
144 char cn[1000]; 144 char cn[1000];
145 snprintf(cn, sizeof(cn), "%s %s %s %s", 145 snprintf(cn, sizeof(cn), "%s %s %s %s",
146 single(item->contact->display_name_prefix), 146 single(item->contact->display_name_prefix),
147 single(item->contact->first_name), 147 single(item->contact->first_name),
148 single(item->contact->surname), 148 single(item->contact->surname),
149 single(item->contact->suffix)); 149 single(item->contact->suffix));
150 if (strcmp(cn, " ")) { 150 if (strcmp(cn, " ")) {
151 // fprintf(stderr, "\n\n\n"); 151 // fprintf(stderr, "\n\n\n");
152 // fprintf(stderr, "access_method %s\n", item->contact->access_method); 152 // fprintf(stderr, "access_method %s\n", item->contact->access_method);
153 // fprintf(stderr, "account_name %s\n", item->contact->account_name); 153 // fprintf(stderr, "account_name %s\n", item->contact->account_name);
154 // fprintf(stderr, "address1 %s\n", item->contact->address1); 154 // fprintf(stderr, "address1 %s\n", item->contact->address1);
155 // fprintf(stderr, "address1_desc %s\n", item->contact->address1_desc); 155 // fprintf(stderr, "address1_desc %s\n", item->contact->address1_desc);
156 // fprintf(stderr, "address1_transport %s\n", item->contact->address1_transport); 156 // fprintf(stderr, "address1_transport %s\n", item->contact->address1_transport);
157 // fprintf(stderr, "address2 %s\n", item->contact->address2); 157 // fprintf(stderr, "address2 %s\n", item->contact->address2);
158 // fprintf(stderr, "address2_desc %s\n", item->contact->address2_desc); 158 // fprintf(stderr, "address2_desc %s\n", item->contact->address2_desc);
159 // fprintf(stderr, "address2_transport %s\n", item->contact->address2_transport); 159 // fprintf(stderr, "address2_transport %s\n", item->contact->address2_transport);
160 // fprintf(stderr, "address3 %s\n", item->contact->address3); 160 // fprintf(stderr, "address3 %s\n", item->contact->address3);
161 // fprintf(stderr, "address3_desc %s\n", item->contact->address3_desc); 161 // fprintf(stderr, "address3_desc %s\n", item->contact->address3_desc);
162 // fprintf(stderr, "address3_transport %s\n", item->contact->address3_transport); 162 // fprintf(stderr, "address3_transport %s\n", item->contact->address3_transport);
163 // fprintf(stderr, "assistant_name %s\n", item->contact->assistant_name); 163 // fprintf(stderr, "assistant_name %s\n", item->contact->assistant_name);
164 // fprintf(stderr, "assistant_phone %s\n", item->contact->assistant_phone); 164 // fprintf(stderr, "assistant_phone %s\n", item->contact->assistant_phone);
165 // fprintf(stderr, "billing_information %s\n", item->contact->billing_information); 165 // fprintf(stderr, "billing_information %s\n", item->contact->billing_information);
166 // fprintf(stderr, "business_address %s\n", item->contact->business_address); 166 // fprintf(stderr, "business_address %s\n", item->contact->business_address);
167 // fprintf(stderr, "business_city %s\n", item->contact->business_city); 167 // fprintf(stderr, "business_city %s\n", item->contact->business_city);
168 // fprintf(stderr, "business_country %s\n", item->contact->business_country); 168 // fprintf(stderr, "business_country %s\n", item->contact->business_country);
169 // fprintf(stderr, "business_fax %s\n", item->contact->business_fax); 169 // fprintf(stderr, "business_fax %s\n", item->contact->business_fax);
170 // fprintf(stderr, "business_homepage %s\n", item->contact->business_homepage); 170 // fprintf(stderr, "business_homepage %s\n", item->contact->business_homepage);
171 // fprintf(stderr, "business_phone %s\n", item->contact->business_phone); 171 // fprintf(stderr, "business_phone %s\n", item->contact->business_phone);
172 // fprintf(stderr, "business_phone2 %s\n", item->contact->business_phone2); 172 // fprintf(stderr, "business_phone2 %s\n", item->contact->business_phone2);
173 // fprintf(stderr, "business_po_box %s\n", item->contact->business_po_box); 173 // fprintf(stderr, "business_po_box %s\n", item->contact->business_po_box);
174 // fprintf(stderr, "business_postal_code %s\n", item->contact->business_postal_code); 174 // fprintf(stderr, "business_postal_code %s\n", item->contact->business_postal_code);
175 // fprintf(stderr, "business_state %s\n", item->contact->business_state); 175 // fprintf(stderr, "business_state %s\n", item->contact->business_state);
176 // fprintf(stderr, "business_street %s\n", item->contact->business_street); 176 // fprintf(stderr, "business_street %s\n", item->contact->business_street);
177 // fprintf(stderr, "callback_phone %s\n", item->contact->callback_phone); 177 // fprintf(stderr, "callback_phone %s\n", item->contact->callback_phone);
178 // fprintf(stderr, "car_phone %s\n", item->contact->car_phone); 178 // fprintf(stderr, "car_phone %s\n", item->contact->car_phone);
179 // fprintf(stderr, "company_main_phone %s\n", item->contact->company_main_phone); 179 // fprintf(stderr, "company_main_phone %s\n", item->contact->company_main_phone);
180 // fprintf(stderr, "company_name %s\n", item->contact->company_name); 180 // fprintf(stderr, "company_name %s\n", item->contact->company_name);
181 // fprintf(stderr, "computer_name %s\n", item->contact->computer_name); 181 // fprintf(stderr, "computer_name %s\n", item->contact->computer_name);
182 // fprintf(stderr, "customer_id %s\n", item->contact->customer_id); 182 // fprintf(stderr, "customer_id %s\n", item->contact->customer_id);
183 // fprintf(stderr, "def_postal_address %s\n", item->contact->def_postal_address); 183 // fprintf(stderr, "def_postal_address %s\n", item->contact->def_postal_address);
184 // fprintf(stderr, "department %s\n", item->contact->department); 184 // fprintf(stderr, "department %s\n", item->contact->department);
185 // fprintf(stderr, "display_name_prefix %s\n", item->contact->display_name_prefix); 185 // fprintf(stderr, "display_name_prefix %s\n", item->contact->display_name_prefix);
186 // fprintf(stderr, "first_name %s\n", item->contact->first_name); 186 // fprintf(stderr, "first_name %s\n", item->contact->first_name);
187 // fprintf(stderr, "followup %s\n", item->contact->followup); 187 // fprintf(stderr, "followup %s\n", item->contact->followup);
188 // fprintf(stderr, "free_busy_address %s\n", item->contact->free_busy_address); 188 // fprintf(stderr, "free_busy_address %s\n", item->contact->free_busy_address);
189 // fprintf(stderr, "ftp_site %s\n", item->contact->ftp_site); 189 // fprintf(stderr, "ftp_site %s\n", item->contact->ftp_site);
190 // fprintf(stderr, "fullname %s\n", item->contact->fullname); 190 // fprintf(stderr, "fullname %s\n", item->contact->fullname);
191 // fprintf(stderr, "gov_id %s\n", item->contact->gov_id); 191 // fprintf(stderr, "gov_id %s\n", item->contact->gov_id);
192 // fprintf(stderr, "hobbies %s\n", item->contact->hobbies); 192 // fprintf(stderr, "hobbies %s\n", item->contact->hobbies);
193 // fprintf(stderr, "home_address %s\n", item->contact->home_address); 193 // fprintf(stderr, "home_address %s\n", item->contact->home_address);
194 // fprintf(stderr, "home_city %s\n", item->contact->home_city); 194 // fprintf(stderr, "home_city %s\n", item->contact->home_city);
195 // fprintf(stderr, "home_country %s\n", item->contact->home_country); 195 // fprintf(stderr, "home_country %s\n", item->contact->home_country);
196 // fprintf(stderr, "home_fax %s\n", item->contact->home_fax); 196 // fprintf(stderr, "home_fax %s\n", item->contact->home_fax);
197 // fprintf(stderr, "home_phone %s\n", item->contact->home_phone); 197 // fprintf(stderr, "home_phone %s\n", item->contact->home_phone);
198 // fprintf(stderr, "home_phone2 %s\n", item->contact->home_phone2); 198 // fprintf(stderr, "home_phone2 %s\n", item->contact->home_phone2);
199 // fprintf(stderr, "home_po_box %s\n", item->contact->home_po_box); 199 // fprintf(stderr, "home_po_box %s\n", item->contact->home_po_box);
200 // fprintf(stderr, "home_postal_code %s\n", item->contact->home_postal_code); 200 // fprintf(stderr, "home_postal_code %s\n", item->contact->home_postal_code);
201 // fprintf(stderr, "home_state %s\n", item->contact->home_state); 201 // fprintf(stderr, "home_state %s\n", item->contact->home_state);
202 // fprintf(stderr, "home_street %s\n", item->contact->home_street); 202 // fprintf(stderr, "home_street %s\n", item->contact->home_street);
203 // fprintf(stderr, "initials %s\n", item->contact->initials); 203 // fprintf(stderr, "initials %s\n", item->contact->initials);
204 // fprintf(stderr, "isdn_phone %s\n", item->contact->isdn_phone); 204 // fprintf(stderr, "isdn_phone %s\n", item->contact->isdn_phone);
205 // fprintf(stderr, "job_title %s\n", item->contact->job_title); 205 // fprintf(stderr, "job_title %s\n", item->contact->job_title);
206 // fprintf(stderr, "keyword %s\n", item->contact->keyword); 206 // fprintf(stderr, "keyword %s\n", item->contact->keyword);
207 // fprintf(stderr, "language %s\n", item->contact->language); 207 // fprintf(stderr, "language %s\n", item->contact->language);
208 // fprintf(stderr, "location %s\n", item->contact->location); 208 // fprintf(stderr, "location %s\n", item->contact->location);
209 // fprintf(stderr, "manager_name %s\n", item->contact->manager_name); 209 // fprintf(stderr, "manager_name %s\n", item->contact->manager_name);
210 // fprintf(stderr, "middle_name %s\n", item->contact->middle_name); 210 // fprintf(stderr, "middle_name %s\n", item->contact->middle_name);
211 // fprintf(stderr, "mileage %s\n", item->contact->mileage); 211 // fprintf(stderr, "mileage %s\n", item->contact->mileage);
212 // fprintf(stderr, "mobile_phone %s\n", item->contact->mobile_phone); 212 // fprintf(stderr, "mobile_phone %s\n", item->contact->mobile_phone);
213 // fprintf(stderr, "nickname %s\n", item->contact->nickname); 213 // fprintf(stderr, "nickname %s\n", item->contact->nickname);
214 // fprintf(stderr, "office_loc %s\n", item->contact->office_loc); 214 // fprintf(stderr, "office_loc %s\n", item->contact->office_loc);
215 // fprintf(stderr, "org_id %s\n", item->contact->org_id); 215 // fprintf(stderr, "org_id %s\n", item->contact->org_id);
216 // fprintf(stderr, "other_address %s\n", item->contact->other_address); 216 // fprintf(stderr, "other_address %s\n", item->contact->other_address);
217 // fprintf(stderr, "other_city %s\n", item->contact->other_city); 217 // fprintf(stderr, "other_city %s\n", item->contact->other_city);
218 // fprintf(stderr, "other_country %s\n", item->contact->other_country); 218 // fprintf(stderr, "other_country %s\n", item->contact->other_country);
219 // fprintf(stderr, "other_phone %s\n", item->contact->other_phone); 219 // fprintf(stderr, "other_phone %s\n", item->contact->other_phone);
220 // fprintf(stderr, "other_po_box %s\n", item->contact->other_po_box); 220 // fprintf(stderr, "other_po_box %s\n", item->contact->other_po_box);
221 // fprintf(stderr, "other_postal_code %s\n", item->contact->other_postal_code); 221 // fprintf(stderr, "other_postal_code %s\n", item->contact->other_postal_code);
222 // fprintf(stderr, "other_state %s\n", item->contact->other_state); 222 // fprintf(stderr, "other_state %s\n", item->contact->other_state);
223 // fprintf(stderr, "other_street %s\n", item->contact->other_street); 223 // fprintf(stderr, "other_street %s\n", item->contact->other_street);
224 // fprintf(stderr, "pager_phone %s\n", item->contact->pager_phone); 224 // fprintf(stderr, "pager_phone %s\n", item->contact->pager_phone);
225 // fprintf(stderr, "personal_homepage %s\n", item->contact->personal_homepage); 225 // fprintf(stderr, "personal_homepage %s\n", item->contact->personal_homepage);
226 // fprintf(stderr, "pref_name %s\n", item->contact->pref_name); 226 // fprintf(stderr, "pref_name %s\n", item->contact->pref_name);
227 // fprintf(stderr, "primary_fax %s\n", item->contact->primary_fax); 227 // fprintf(stderr, "primary_fax %s\n", item->contact->primary_fax);
228 // fprintf(stderr, "primary_phone %s\n", item->contact->primary_phone); 228 // fprintf(stderr, "primary_phone %s\n", item->contact->primary_phone);
229 // fprintf(stderr, "profession %s\n", item->contact->profession); 229 // fprintf(stderr, "profession %s\n", item->contact->profession);
230 // fprintf(stderr, "radio_phone %s\n", item->contact->radio_phone); 230 // fprintf(stderr, "radio_phone %s\n", item->contact->radio_phone);
231 // fprintf(stderr, "spouse_name %s\n", item->contact->spouse_name); 231 // fprintf(stderr, "spouse_name %s\n", item->contact->spouse_name);
232 // fprintf(stderr, "suffix %s\n", item->contact->suffix); 232 // fprintf(stderr, "suffix %s\n", item->contact->suffix);
233 // fprintf(stderr, "surname %s\n", item->contact->surname); 233 // fprintf(stderr, "surname %s\n", item->contact->surname);
234 // fprintf(stderr, "telex %s\n", item->contact->telex); 234 // fprintf(stderr, "telex %s\n", item->contact->telex);
235 // fprintf(stderr, "transmittable_display_name %s\n", item->contact->transmittable_display_name); 235 // fprintf(stderr, "transmittable_display_name %s\n", item->contact->transmittable_display_name);
236 // fprintf(stderr, "ttytdd_phone %s\n", item->contact->ttytdd_phone); 236 // fprintf(stderr, "ttytdd_phone %s\n", item->contact->ttytdd_phone);
237 // have a valid cn 237 // have a valid cn
238 char *ucn = unique_string(folded(trim(cn))); 238 const char *ucn = unique_string(folded(trim(cn)));
239 printf("dn: cn=%s, %s\n", ucn, ldap_base); 239 printf("dn: cn=%s, %s\n", ucn, ldap_base);
240 printf("cn: %s\n", ucn); 240 printf("cn: %s\n", ucn);
241 if (item->contact->first_name) { 241 if (item->contact->first_name) {
242 snprintf(cn, sizeof(cn), "%s %s", 242 snprintf(cn, sizeof(cn), "%s %s",
243 single(item->contact->display_name_prefix), 243 single(item->contact->display_name_prefix),
244 single(item->contact->first_name)); 244 single(item->contact->first_name));
245 printf("givenName: %s\n", trim(cn)); 245 printf("givenName: %s\n", trim(cn));
246 } 246 }
247 if (item->contact->surname) { 247 if (item->contact->surname) {
248 snprintf(cn, sizeof(cn), "%s %s", 248 snprintf(cn, sizeof(cn), "%s %s",
249 single(item->contact->surname), 249 single(item->contact->surname),
250 single(item->contact->suffix)); 250 single(item->contact->suffix));
251 printf("sn: %s\n", trim(cn)); 251 printf("sn: %s\n", trim(cn));
252 } 252 }
253 else if (item->contact->company_name) { 253 else if (item->contact->company_name) {
254 printf("sn: %s\n", single(item->contact->company_name)); 254 printf("sn: %s\n", single(item->contact->company_name));
255 } 255 }
256 else 256 else
257 printf("sn: %s\n", ucn); // use cn as sn if we cannot find something better 257 printf("sn: %s\n", ucn); // use cn as sn if we cannot find something better
258 258
259 if (item->contact->job_title) 259 if (item->contact->job_title)
260 printf("personalTitle: %s\n", single(item->contact->job_title)); 260 printf("personalTitle: %s\n", single(item->contact->job_title));
261 if (item->contact->company_name) 261 if (item->contact->company_name)
262 printf("company: %s\n", single(item->contact->company_name)); 262 printf("company: %s\n", single(item->contact->company_name));
263 if (item->contact->address1 && *item->contact->address1) 263 if (item->contact->address1 && *item->contact->address1)
264 printf("mail: %s\n", single(item->contact->address1)); 264 printf("mail: %s\n", single(item->contact->address1));
265 if (item->contact->address2 && *item->contact->address2) 265 if (item->contact->address2 && *item->contact->address2)
266 printf("mail: %s\n", single(item->contact->address2)); 266 printf("mail: %s\n", single(item->contact->address2));
267 if (item->contact->address3 && *item->contact->address3) 267 if (item->contact->address3 && *item->contact->address3)
268 printf("mail: %s\n", single(item->contact->address3)); 268 printf("mail: %s\n", single(item->contact->address3));
269 if (item->contact->address1a && *item->contact->address1a) 269 if (item->contact->address1a && *item->contact->address1a)
270 printf("mail: %s\n", single(item->contact->address1a)); 270 printf("mail: %s\n", single(item->contact->address1a));
271 if (item->contact->address2a && *item->contact->address2a) 271 if (item->contact->address2a && *item->contact->address2a)
272 printf("mail: %s\n", single(item->contact->address2a)); 272 printf("mail: %s\n", single(item->contact->address2a));
273 if (item->contact->address3a && *item->contact->address3a) 273 if (item->contact->address3a && *item->contact->address3a)
274 printf("mail: %s\n", single(item->contact->address3a)); 274 printf("mail: %s\n", single(item->contact->address3a));
275 if (item->contact->business_address) { 275 if (item->contact->business_address) {
276 if (item->contact->business_po_box) 276 if (item->contact->business_po_box)
277 printf("postalAddress: %s\n", single(item->contact->business_po_box)); 277 printf("postalAddress: %s\n", single(item->contact->business_po_box));
278 if (item->contact->business_street) 278 if (item->contact->business_street)
279 multi("postalAddress: %s\n", item->contact->business_street); 279 multi("postalAddress: %s\n", item->contact->business_street);
280 if (item->contact->business_city) 280 if (item->contact->business_city)
281 printf("l: %s\n", single(item->contact->business_city)); 281 printf("l: %s\n", single(item->contact->business_city));
282 if (item->contact->business_state) 282 if (item->contact->business_state)
283 printf("st: %s\n", single(item->contact->business_state)); 283 printf("st: %s\n", single(item->contact->business_state));
284 if (item->contact->business_postal_code) 284 if (item->contact->business_postal_code)
285 printf("postalCode: %s\n", single(item->contact->business_postal_code)); 285 printf("postalCode: %s\n", single(item->contact->business_postal_code));
286 } 286 }
287 else if (item->contact->home_address) { 287 else if (item->contact->home_address) {
288 if (item->contact->home_po_box) 288 if (item->contact->home_po_box)
289 printf("postalAddress: %s\n", single(item->contact->home_po_box)); 289 printf("postalAddress: %s\n", single(item->contact->home_po_box));
290 if (item->contact->home_street) 290 if (item->contact->home_street)
291 multi("postalAddress: %s\n", item->contact->home_street); 291 multi("postalAddress: %s\n", item->contact->home_street);
292 if (item->contact->home_city) 292 if (item->contact->home_city)
293 printf("l: %s\n", single(item->contact->home_city)); 293 printf("l: %s\n", single(item->contact->home_city));
294 if (item->contact->home_state) 294 if (item->contact->home_state)
295 printf("st: %s\n", single(item->contact->home_state)); 295 printf("st: %s\n", single(item->contact->home_state));
296 if (item->contact->home_postal_code) 296 if (item->contact->home_postal_code)
297 printf("postalCode: %s\n", single(item->contact->home_postal_code)); 297 printf("postalCode: %s\n", single(item->contact->home_postal_code));
298 } 298 }
299 else if (item->contact->other_address) { 299 else if (item->contact->other_address) {
300 if (item->contact->other_po_box) 300 if (item->contact->other_po_box)
301 printf("postalAddress: %s\n", single(item->contact->other_po_box)); 301 printf("postalAddress: %s\n", single(item->contact->other_po_box));
302 if (item->contact->other_street) 302 if (item->contact->other_street)
303 multi("postalAddress: %s\n", item->contact->other_street); 303 multi("postalAddress: %s\n", item->contact->other_street);
304 if (item->contact->other_city) 304 if (item->contact->other_city)
305 printf("l: %s\n", single(item->contact->other_city)); 305 printf("l: %s\n", single(item->contact->other_city));
306 if (item->contact->other_state) 306 if (item->contact->other_state)
307 printf("st: %s\n", single(item->contact->other_state)); 307 printf("st: %s\n", single(item->contact->other_state));
308 if (item->contact->other_postal_code) 308 if (item->contact->other_postal_code)
309 printf("postalCode: %s\n", single(item->contact->other_postal_code)); 309 printf("postalCode: %s\n", single(item->contact->other_postal_code));
310 } 310 }
311 if (item->contact->business_fax) 311 if (item->contact->business_fax)
312 printf("facsimileTelephoneNumber: %s\n", single(item->contact->business_fax)); 312 printf("facsimileTelephoneNumber: %s\n", single(item->contact->business_fax));
313 else if (item->contact->home_fax) 313 else if (item->contact->home_fax)
314 printf("facsimileTelephoneNumber: %s\n", single(item->contact->home_fax)); 314 printf("facsimileTelephoneNumber: %s\n", single(item->contact->home_fax));
315 315
316 if (item->contact->business_phone) 316 if (item->contact->business_phone)
317 printf("telephoneNumber: %s\n", single(item->contact->business_phone)); 317 printf("telephoneNumber: %s\n", single(item->contact->business_phone));
318 if (item->contact->home_phone) 318 if (item->contact->home_phone)
319 printf("homePhone: %s\n", single(item->contact->home_phone)); 319 printf("homePhone: %s\n", single(item->contact->home_phone));
320 320
321 if (item->contact->car_phone) 321 if (item->contact->car_phone)
322 printf("mobile: %s\n", single(item->contact->car_phone)); 322 printf("mobile: %s\n", single(item->contact->car_phone));
323 else if (item->contact->mobile_phone) 323 else if (item->contact->mobile_phone)
324 printf("mobile: %s\n", single(item->contact->mobile_phone)); 324 printf("mobile: %s\n", single(item->contact->mobile_phone));
325 else if (item->contact->other_phone) 325 else if (item->contact->other_phone)
326 printf("mobile: %s\n", single(item->contact->other_phone)); 326 printf("mobile: %s\n", single(item->contact->other_phone));
327 327
328 328
329 if (item->comment) 329 if (item->comment)
330 printf("description: %s\n", single(item->comment)); 330 printf("description: %s\n", single(item->comment));
331 331
332 printf("objectClass: %s\n\n", ldap_class); 332 printf("objectClass: %s\n\n", ldap_class);
333 } 333 }
334 } 334 }
335 } 335 }
336 else { 336 else {
337 DEBUG_INFO(("item is not a contact\n")); 337 DEBUG_INFO(("item is not a contact\n"));
338 } 338 }
339 } 339 }
340 pst_freeItem(item); 340 pst_freeItem(item);
341 } 341 }
342 d_ptr = d_ptr->next; 342 d_ptr = d_ptr->next;
343 } 343 }
344 } 344 }
345 345
346 346
347 int main(int argc, char** argv) { 347 int main(int argc, char** argv) {
348 pst_desc_ll *d_ptr; 348 pst_desc_ll *d_ptr;
349 char *fname = NULL; 349 char *fname = NULL;
350 char *temp = NULL; //temporary char pointer 350 char *temp = NULL; //temporary char pointer
351 char c; 351 char c;
352 char *d_log = NULL; 352 char *d_log = NULL;
353 prog_name = argv[0]; 353 prog_name = argv[0];
354 pst_item *item = NULL; 354 pst_item *item = NULL;
355 355
356 while ((c = getopt(argc, argv, "b:c:d:Vh"))!= -1) { 356 while ((c = getopt(argc, argv, "b:c:d:Vh"))!= -1) {
357 switch (c) { 357 switch (c) {
358 case 'b': 358 case 'b':
359 ldap_base = optarg; 359 ldap_base = optarg;
360 temp = strchr(ldap_base, ','); 360 temp = strchr(ldap_base, ',');
361 if (temp) { 361 if (temp) {
362 *temp = '\0'; 362 *temp = '\0';
363 ldap_org = strdup(ldap_base+2); // assume first 2 chars are o= 363 ldap_org = strdup(ldap_base+2); // assume first 2 chars are o=
364 *temp = ','; 364 *temp = ',';
365 } 365 }
366 break; 366 break;
367 case 'c': 367 case 'c':
368 ldap_class = optarg; 368 ldap_class = optarg;
369 break; 369 break;
370 case 'd': 370 case 'd':
371 d_log = optarg; 371 d_log = optarg;
372 break; 372 break;
373 case 'h': 373 case 'h':
374 usage(); 374 usage();
375 exit(0); 375 exit(0);
376 break; 376 break;
377 case 'V': 377 case 'V':
378 version(); 378 version();
379 exit(0); 379 exit(0);
380 break; 380 break;
381 default: 381 default:
382 usage(); 382 usage();
383 exit(1); 383 exit(1);
384 break; 384 break;
385 } 385 }
386 } 386 }
387 387
388 if ((argc > optind) && (ldap_base) && (ldap_class) && (ldap_org)) { 388 if ((argc > optind) && (ldap_base) && (ldap_class) && (ldap_org)) {
389 fname = argv[optind]; 389 fname = argv[optind];
390 } else { 390 } else {
391 usage(); 391 usage();
392 exit(2); 392 exit(2);
393 } 393 }
394 394
395 #ifdef DEBUG_ALL 395 #ifdef DEBUG_ALL
396 // force a log file 396 // force a log file
397 if (!d_log) d_log = "pst2ldif.log"; 397 if (!d_log) d_log = "pst2ldif.log";
398 #endif 398 #endif
399 DEBUG_INIT(d_log); 399 DEBUG_INIT(d_log);
400 DEBUG_REGISTER_CLOSE(); 400 DEBUG_REGISTER_CLOSE();
401 DEBUG_ENT("main"); 401 DEBUG_ENT("main");
402 RET_DERROR(pst_open(&pstfile, fname), 1, ("Error opening File\n")); 402 RET_DERROR(pst_open(&pstfile, fname), 1, ("Error opening File\n"));
403 RET_DERROR(pst_load_index(&pstfile), 2, ("Index Error\n")); 403 RET_DERROR(pst_load_index(&pstfile), 2, ("Index Error\n"));
404 404
405 pst_load_extended_attributes(&pstfile); 405 pst_load_extended_attributes(&pstfile);
406 406
407 d_ptr = pstfile.d_head; // first record is main record 407 d_ptr = pstfile.d_head; // first record is main record
408 item = (pst_item*)pst_parse_item(&pstfile, d_ptr); 408 item = (pst_item*)pst_parse_item(&pstfile, d_ptr);
409 if (!item || !item->message_store) { 409 if (!item || !item->message_store) {
410 DEBUG_RET(); 410 DEBUG_RET();
411 DIE(("main: Could not get root record\n")); 411 DIE(("main: Could not get root record\n"));
412 } 412 }
413 413
414 d_ptr = pst_getTopOfFolders(&pstfile, item); 414 d_ptr = pst_getTopOfFolders(&pstfile, item);
415 if (!d_ptr) { 415 if (!d_ptr) {
416 DEBUG_RET(); 416 DEBUG_RET();
417 DIE(("Top of folders record not found. Cannot continue\n")); 417 DIE(("Top of folders record not found. Cannot continue\n"));
418 } 418 }
419 419
420 pst_freeItem(item); 420 pst_freeItem(item);
421 421
422 // write the ldap header 422 // write the ldap header
423 printf("dn: %s\n", ldap_base); 423 printf("dn: %s\n", ldap_base);
424 printf("o: %s\n", ldap_org); 424 printf("o: %s\n", ldap_org);
425 printf("objectClass: organization\n\n"); 425 printf("objectClass: organization\n\n");
426 printf("dn: cn=root, %s\n", ldap_base); 426 printf("dn: cn=root, %s\n", ldap_base);
427 printf("cn: root\n"); 427 printf("cn: root\n");
428 printf("objectClass: %s\n\n", ldap_class); 428 printf("objectClass: %s\n\n", ldap_class);
429 429
430 process(d_ptr->child); // do the children of TOPF 430 process(d_ptr->child); // do the children of TOPF
431 pst_close(&pstfile); 431 pst_close(&pstfile);
432 DEBUG_RET(); 432 DEBUG_RET();
433 free_strings(all_strings); 433 free_strings(all_strings);
434 return 0; 434 return 0;
435 } 435 }
436 436
437 437
438 int usage() { 438 int usage() {
439 version(); 439 version();
440 printf("Usage: %s [OPTIONS] {PST FILENAME}\n", prog_name); 440 printf("Usage: %s [OPTIONS] {PST FILENAME}\n", prog_name);
441 printf("OPTIONS:\n"); 441 printf("OPTIONS:\n");
442 printf("\t-h\t- Help. This screen\n"); 442 printf("\t-h\t- Help. This screen\n");
443 printf("\t-V\t- Version. Display program version\n"); 443 printf("\t-V\t- Version. Display program version\n");
444 printf("\t-b ldapbase\t- set the ldap base value\n"); 444 printf("\t-b ldapbase\t- set the ldap base value\n");
445 printf("\t-c class \t- set the class of the ldap objects\n"); 445 printf("\t-c class \t- set the class of the ldap objects\n");
446 return 0; 446 return 0;
447 } 447 }
448 448
449 449
450 int version() { 450 int version() {
451 printf("pst2ldif v%s\n", VERSION); 451 printf("pst2ldif v%s\n", VERSION);
452 #if BYTE_ORDER == BIG_ENDIAN 452 #if BYTE_ORDER == BIG_ENDIAN
453 printf("Big Endian implementation being used.\n"); 453 printf("Big Endian implementation being used.\n");
454 #elif BYTE_ORDER == LITTLE_ENDIAN 454 #elif BYTE_ORDER == LITTLE_ENDIAN
455 printf("Little Endian implementation being used.\n"); 455 printf("Little Endian implementation being used.\n");
456 #else 456 #else
457 # error "Byte order not supported by this library" 457 # error "Byte order not supported by this library"
458 #endif 458 #endif
459 #ifdef __GNUC__ 459 #ifdef __GNUC__
460 printf("GCC %d.%d : %s %s\n", __GNUC__, __GNUC_MINOR__, __DATE__, __TIME__); 460 printf("GCC %d.%d : %s %s\n", __GNUC__, __GNUC_MINOR__, __DATE__, __TIME__);
461 #endif 461 #endif
462 return 0; 462 return 0;
463 } 463 }
464 464
465 465
466 // my_stristr varies from strstr in that its searches are case-insensitive 466 // my_stristr varies from strstr in that its searches are case-insensitive
467 char * my_stristr(char *haystack, char *needle) { 467 char * my_stristr(char *haystack, char *needle) {
468 char *x=haystack, *y=needle, *z = NULL; 468 char *x=haystack, *y=needle, *z = NULL;
469 if (haystack == NULL || needle == NULL) 469 if (haystack == NULL || needle == NULL)
470 return NULL; 470 return NULL;
471 while (*y != '\0' && *x != '\0') { 471 while (*y != '\0' && *x != '\0') {
472 if (tolower(*y) == tolower(*x)) { 472 if (tolower(*y) == tolower(*x)) {
473 // move y on one 473 // move y on one
474 y++; 474 y++;
475 if (z == NULL) { 475 if (z == NULL) {
476 z = x; // store first position in haystack where a match is made 476 z = x; // store first position in haystack where a match is made
477 } 477 }
478 } else { 478 } else {
479 y = needle; // reset y to the beginning of the needle 479 y = needle; // reset y to the beginning of the needle
480 z = NULL; // reset the haystack storage point 480 z = NULL; // reset the haystack storage point
481 } 481 }
482 x++; // advance the search in the haystack 482 x++; // advance the search in the haystack
483 } 483 }
484 return z; 484 return z;
485 } 485 }
486 486
487 487
488 char *check_filename(char *fname) { 488 char *check_filename(char *fname) {
489 char *t = fname; 489 char *t = fname;
490 if (t == NULL) { 490 if (t == NULL) {
491 return fname; 491 return fname;
492 } 492 }
493 while ((t = strpbrk(t, "/\\:"))) { 493 while ((t = strpbrk(t, "/\\:"))) {
494 // while there are characters in the second string that we don't want 494 // while there are characters in the second string that we don't want
495 *t = '_'; //replace them with an underscore 495 *t = '_'; //replace them with an underscore
496 } 496 }
497 return fname; 497 return fname;
498 } 498 }
499 499
500 500
501 char *single(char *str) { 501 const char *single(char *str) {
502 if (!str) return ""; 502 if (!str) return "";
503 char *ret = rfc2426_escape(str); 503 char *ret = rfc2426_escape(str);
504 char *n = strchr(ret, '\n'); 504 char *n = strchr(ret, '\n');
505 if (n) *n = '\0'; 505 if (n) *n = '\0';
506 return ret; 506 return ret;
507 } 507 }
508 508
509 509
510 char *folded(char *str) { 510 const char *folded(char *str) {
511 if (!str) return ""; 511 if (!str) return "";
512 char *ret = rfc2426_escape(str); 512 char *ret = rfc2426_escape(str);
513 char *n = ret; 513 char *n = ret;
514 while (n = strchr(n, '\n')) { 514 while ((n = strchr(n, '\n'))) {
515 *n = ' '; 515 *n = ' ';
516 } 516 }
517 n = ret; 517 n = ret;
518 while (n = strchr(n, ',')) { 518 while ((n = strchr(n, ','))) {
519 *n = ' '; 519 *n = ' ';
520 } 520 }
521 return ret; 521 return ret;
522 } 522 }
523 523
524 524
525 void multi(char *fmt, char *str) { 525 void multi(const char *fmt, char *str) {
526 if (!str) return; 526 if (!str) return;
527 char *ret = rfc2426_escape(str); 527 char *ret = rfc2426_escape(str);
528 char *n = ret; 528 char *n = ret;
529 while (n = strchr(ret, '\n')) { 529 while ((n = strchr(ret, '\n'))) {
530 *n = '\0'; 530 *n = '\0';
531 printf(fmt, ret); 531 printf(fmt, ret);
532 ret = n+1; 532 ret = n+1;
533 } 533 }
534 if (*ret) printf(fmt, ret); 534 if (*ret) printf(fmt, ret);
535 } 535 }
536 536
537 537
538 char *rfc2426_escape(char *str) { 538 char *rfc2426_escape(char *str) {
539 static char* buf = NULL; 539 static char* buf = NULL;
540 char *ret, *a, *b; 540 char *ret, *a, *b;
541 int x = 0, y, z; 541 int x = 0, y, z;
542 if (str == NULL) 542 if (str == NULL)
543 ret = str; 543 ret = str;
544 else { 544 else {
545 545
546 // calculate space required to escape all the following characters 546 // calculate space required to escape all the following characters
547 y = chr_count(str, '\\') 547 y = chr_count(str, '\\')
548 + chr_count(str, ';'); 548 + chr_count(str, ';');
549 z = chr_count(str, '\r'); 549 z = chr_count(str, '\r');
550 if (y == 0 && z == 0) 550 if (y == 0 && z == 0)
551 // there isn't any extra space required 551 // there isn't any extra space required
552 ret = str; 552 ret = str;
553 else { 553 else {
554 x = strlen(str) + y - z + 1; // don't forget room for the NUL 554 x = strlen(str) + y - z + 1; // don't forget room for the NUL
555 buf = (char*) realloc(buf, x); 555 buf = (char*) realloc(buf, x);
556 a = str; 556 a = str;
557 b = buf; 557 b = buf;
558 while (*a != '\0') { 558 while (*a != '\0') {
559 switch(*a) { 559 switch(*a) {
560 case '\\': 560 case '\\':
561 case ';' : 561 case ';' :
562 *(b++)='\\'; 562 *(b++)='\\';
563 *b=*a; 563 *b=*a;
564 break; 564 break;
565 case '\r': // skip cr 565 case '\r': // skip cr
566 b--; 566 b--;
567 break; 567 break;
568 default: 568 default:
569 *b=*a; 569 *b=*a;
570 } 570 }
571 b++; 571 b++;
572 a++; 572 a++;
573 } 573 }
574 *b = '\0'; // NUL-terminate the string (buf) 574 *b = '\0'; // NUL-terminate the string (buf)
575 ret = buf; 575 ret = buf;
576 } 576 }
577 } 577 }
578 return ret; 578 return ret;
579 } 579 }
580 580
581 581
582 int chr_count(char *str, char x) { 582 int chr_count(char *str, char x) {
583 int r = 0; 583 int r = 0;
584 while (*str != '\0') { 584 while (*str != '\0') {
585 if (*str == x) 585 if (*str == x)
586 r++; 586 r++;
587 str++; 587 str++;
588 } 588 }
589 return r; 589 return r;
590 } 590 }
591 591