'LibPst'
pst2ldif.cpp
Go to the documentation of this file.
1 /*
2 
3 Copyright (c) 2004 Carl Byington - 510 Software Group, released under
4 the GPL version 2 or any later version at your choice available at
5 http://www.fsf.org/licenses/gpl.txt
6 
7 Based on readpst.c by David Smith
8 
9 */
10 
11 using namespace std;
12 
13 // needed for std c++ collections
14 #include <set>
15 #include <vector>
16 #include <string>
17 
18 extern "C" {
19  #include "define.h"
20  #include "lzfu.h"
21 }
22 
23 void usage(void);
24 void version(void);
25 char *check_filename(char *fname);
26 void print_ldif_single(const char *attr, const char *value);
27 void print_ldif_single(const char *attr, pst_string value);
28 void print_ldif_address(const char *attr, int nvalues, pst_string value, ...);
29 void print_ldif_dn(const char *attr, pst_string value, const char *base);
30 void print_ldif_multi(const char *dn, pst_string value);
31 void print_ldif_two(const char *attr, pst_string value1, pst_string value2);
32 void print_escaped_dn(const char *value);
33 void build_cn(char *cn, size_t len, int nvalues, pst_string value, ...);
34 
35 char *prog_name;
37 bool old_schema = false;
38 char *ldap_base = NULL; // 'o=some.domain.tld,c=US'
40 vector<string> ldap_class; // 'newPerson' or 'inetOrgPerson'
41 vector<string> ldif_extra_line; // 'o: myorg'
42 
43 
45 // define our ordering
46 struct ltstr {
47  bool operator()(const char* s1, const char* s2) const {
48  return strcasecmp(s1, s2) < 0;
49  }
50 };
51 // define our set
52 typedef set<const char *, ltstr> string_set;
53 // make a static set to hold the cn values
55 
56 
58 // helper to free all the strings in a set
59 //
60 static void free_strings(string_set &s);
61 static void free_strings(string_set &s)
62 {
63  if (s.empty()) return;
64  for (string_set::iterator i=s.begin(); i!=s.end(); i++) {
65  free((void*)*i);
66  }
67  s.clear();
68 }
69 
70 
72 // helper to register a string in a string set
73 //
74 static const char* register_string(string_set &s, const char *name);
75 static const char* register_string(string_set &s, const char *name) {
76  string_set::const_iterator i = s.find(name);
77  if (i != s.end()) return *i;
78  char *x = strdup(name);
79  s.insert(x);
80  return x;
81 }
82 
83 
85 // register a global string
86 //
87 static const char* register_string(const char *name);
88 static const char* register_string(const char *name) {
89  return register_string(all_strings, name);
90 }
91 
92 
94 // make a unique string
95 //
96 static const char* unique_string(const char *name);
97 static const char* unique_string(const char *name) {
98  int unique = 2;
99  string_set::iterator i = all_strings.find(name);
100  if (i == all_strings.end()) return register_string(name);
101  while (true) {
102  vector<char> n(strlen(name)+10);
103  snprintf(&n[0], n.size(), "%s %d", name, unique++);
104  string_set::iterator i = all_strings.find(&n[0]);
105  if (i == all_strings.end()) return register_string(&n[0]);
106  }
107 }
108 
109 
110 static void process(pst_desc_tree *d_ptr);
111 static void process(pst_desc_tree *d_ptr) {
112  DEBUG_ENT("process");
113  pst_item *item = NULL;
114  while (d_ptr) {
115  if (d_ptr->desc) {
116  item = pst_parse_item(&pstfile, d_ptr, NULL);
117  DEBUG_INFO(("item pointer is %p\n", item));
118  if (item) {
119  if (item->folder && d_ptr->child && item->file_as.str && strcasecmp(item->file_as.str, "Deleted Items")) {
120  //if this is a non-empty folder other than deleted items, we want to recurse into it
121  fprintf(stderr, "entering folder %s\n", item->file_as.str);
122  process(d_ptr->child);
123 
124  } else if (item->contact && (item->type == PST_TYPE_CONTACT)) {
125  // deal with a contact
126  char cn[1000];
127 
128  // convert everything to utf8
131  pst_convert_utf8_null(item, &item->contact->surname);
132  pst_convert_utf8_null(item, &item->contact->suffix);
134  pst_convert_utf8_null(item, &item->contact->job_title);
135  pst_convert_utf8_null(item, &item->contact->address1);
136  pst_convert_utf8_null(item, &item->contact->address2);
137  pst_convert_utf8_null(item, &item->contact->address3);
138  pst_convert_utf8_null(item, &item->contact->address1a);
139  pst_convert_utf8_null(item, &item->contact->address2a);
140  pst_convert_utf8_null(item, &item->contact->address3a);
150  pst_convert_utf8_null(item, &item->contact->home_city);
160  pst_convert_utf8_null(item, &item->contact->home_fax);
163  pst_convert_utf8_null(item, &item->contact->car_phone);
168  pst_convert_utf8_null(item, &item->comment);
169 
170  build_cn(cn, sizeof(cn), 4,
172  item->contact->first_name,
173  item->contact->surname,
174  item->contact->suffix);
175  if (cn[0] != 0) {
176  // have a valid cn
177  pst_string ucn;
178  ucn.str = (char*)unique_string(cn);
179  ucn.is_utf8 = 1; // all the components are already utf8
180 
181  print_ldif_dn("dn", ucn, ldap_base);
182  print_ldif_single("cn", ucn);
183  if (item->contact->first_name.str) {
184  print_ldif_two("givenName",
186  item->contact->first_name);
187  }
188  if (item->contact->surname.str) {
189  print_ldif_two("sn",
190  item->contact->surname,
191  item->contact->suffix);
192  }
193  else if (item->contact->company_name.str) {
194  print_ldif_single("sn", item->contact->company_name);
195  }
196  else
197  print_ldif_single("sn", ucn); // use cn as sn if we cannot find something better
198 
199  if (old_schema) {
200  if (item->contact->job_title.str)
201  print_ldif_single("personalTitle", item->contact->job_title);
202  if (item->contact->company_name.str)
203  print_ldif_single("company", item->contact->company_name);
204  }
205  else {
206  // new schema
207  if (item->contact->job_title.str)
208  print_ldif_single("title", item->contact->job_title);
209  if (item->contact->company_name.str)
211  }
212  if (item->contact->address1.str && *item->contact->address1.str)
213  print_ldif_single("mail", item->contact->address1);
214  if (item->contact->address2.str && *item->contact->address2.str)
215  print_ldif_single("mail", item->contact->address2);
216  if (item->contact->address3.str && *item->contact->address3.str)
217  print_ldif_single("mail", item->contact->address3);
218  if (item->contact->address1a.str && *item->contact->address1a.str)
219  print_ldif_single("mail", item->contact->address1a);
220  if (item->contact->address2a.str && *item->contact->address2a.str)
221  print_ldif_single("mail", item->contact->address2a);
222  if (item->contact->address3a.str && *item->contact->address3a.str)
223  print_ldif_single("mail", item->contact->address3a);
224 
225  if (old_schema) {
226  if (item->contact->business_address.str) {
227  if (item->contact->business_po_box.str)
228  print_ldif_single("postalAddress", item->contact->business_po_box);
229  if (item->contact->business_street.str)
230  print_ldif_multi("postalAddress", item->contact->business_street);
231  if (item->contact->business_city.str)
233  if (item->contact->business_state.str)
235  if (item->contact->business_postal_code.str)
236  print_ldif_single("postalCode", item->contact->business_postal_code);
237  }
238  else if (item->contact->home_address.str) {
239  if (item->contact->home_po_box.str)
240  print_ldif_single("postalAddress", item->contact->home_po_box);
241  if (item->contact->home_street.str)
242  print_ldif_multi("postalAddress", item->contact->home_street);
243  if (item->contact->home_city.str)
244  print_ldif_single("l", item->contact->home_city);
245  if (item->contact->home_state.str)
246  print_ldif_single("st", item->contact->home_state);
247  if (item->contact->home_postal_code.str)
248  print_ldif_single("postalCode", item->contact->home_postal_code);
249  }
250  else if (item->contact->other_address.str) {
251  if (item->contact->other_po_box.str)
252  print_ldif_single("postalAddress", item->contact->other_po_box);
253  if (item->contact->other_street.str)
254  print_ldif_multi("postalAddress", item->contact->other_street);
255  if (item->contact->other_city.str)
256  print_ldif_single("l", item->contact->other_city);
257  if (item->contact->other_state.str)
258  print_ldif_single("st", item->contact->other_state);
259  if (item->contact->other_postal_code.str)
260  print_ldif_single("postalCode", item->contact->other_postal_code);
261  }
262  }
263  else {
264  // new schema, with proper RFC4517 postal addresses
265  if (item->contact->business_address.str) {
266  print_ldif_address("postalAddress", 6,
267  item->contact->business_po_box,
268  item->contact->business_street,
269  item->contact->business_city,
270  item->contact->business_state,
272  item->contact->business_country);
273  if (item->contact->business_city.str)
275  if (item->contact->business_state.str)
277  if (item->contact->business_postal_code.str)
278  print_ldif_single("postalCode", item->contact->business_postal_code);
279  }
280  else if (item->contact->home_address.str) {
281  if (item->contact->home_city.str)
282  print_ldif_single("l", item->contact->home_city);
283  if (item->contact->home_state.str)
284  print_ldif_single("st", item->contact->home_state);
285  if (item->contact->home_postal_code.str)
286  print_ldif_single("postalCode", item->contact->home_postal_code);
287  }
288  else if (item->contact->other_address.str) {
289  print_ldif_address("postalAddress", 6,
290  item->contact->other_po_box,
291  item->contact->other_street,
292  item->contact->other_city,
293  item->contact->other_state,
294  item->contact->other_postal_code,
295  item->contact->other_country);
296  if (item->contact->other_city.str)
297  print_ldif_single("l", item->contact->other_city);
298  if (item->contact->other_state.str)
299  print_ldif_single("st", item->contact->other_state);
300  if (item->contact->other_postal_code.str)
301  print_ldif_single("postalCode", item->contact->other_postal_code);
302  }
303  if (item->contact->home_address.str) {
304  print_ldif_address("homePostalAddress", 6,
305  item->contact->home_po_box,
306  item->contact->home_street,
307  item->contact->home_city,
308  item->contact->home_state,
309  item->contact->home_postal_code,
310  item->contact->home_country);
311  }
312  }
313 
314  if (item->contact->business_fax.str)
315  print_ldif_single("facsimileTelephoneNumber", item->contact->business_fax);
316  else if (item->contact->home_fax.str)
317  print_ldif_single("facsimileTelephoneNumber", item->contact->home_fax);
318 
319  if (item->contact->business_phone.str)
320  print_ldif_single("telephoneNumber", item->contact->business_phone);
321  if (item->contact->home_phone.str)
322  print_ldif_single("homePhone", item->contact->home_phone);
323 
324  if (item->contact->car_phone.str)
325  print_ldif_single("mobile", item->contact->car_phone);
326  else if (item->contact->mobile_phone.str)
327  print_ldif_single("mobile", item->contact->mobile_phone);
328  else if (item->contact->other_phone.str)
329  print_ldif_single("mobile", item->contact->other_phone);
330 
331  if (!old_schema) {
332  if (item->contact->business_homepage.str)
333  print_ldif_single("labeledURI", item->contact->business_homepage);
334  if (item->contact->personal_homepage.str)
335  print_ldif_single("labeledURI", item->contact->personal_homepage);
336  }
337 
338  if (item->comment.str)
339  print_ldif_single("description", item->comment);
340 
341  for (vector<string>::size_type i=0; i<ldap_class.size(); i++)
342  print_ldif_single("objectClass", ldap_class[i].c_str());
343  printf("\n");
344  }
345  }
346  else {
347  DEBUG_INFO(("item is not a contact\n"));
348  }
349  }
350  pst_freeItem(item);
351  }
352  d_ptr = d_ptr->next;
353  }
354  DEBUG_RET();
355 }
356 
357 
358 void print_ldif_single(const char *attr, pst_string value)
359 {
360  print_ldif_single(attr, value.str);
361 }
362 
363 
364 // Prints an attribute together with its value.
365 // If the value isn't a "SAFE STRING" (as defined in RFC2849),
366 // then it is output as a BASE-64 encoded value
367 void print_ldif_single(const char *attr, const char *value)
368 {
369  size_t len;
370  bool is_safe_string = true;
371  bool space_flag = false;
372 
373  // Strip leading spaces
374  while (*value == ' ') value++;
375  len = strlen(value) + 1;
376  vector<char> buffer(len);
377  char *p = &buffer[0];
378 
379  // See if "value" is a "SAFE STRING"
380  // First check characters that are safe but not safe as initial characters
381  if (*value == ':' || *value == '<')
382  is_safe_string = false;
383  for (;;) {
384  char ch = *value++;
385 
386  if (ch == 0 || ch == '\n')
387  break;
388  else if (ch == '\r')
389  continue;
390  else if (ch == ' ') {
391  space_flag = true;
392  continue;
393  }
394  else {
395  if ((ch & 0x80) == 0x80) {
396  is_safe_string = false;
397  }
398  if (space_flag) {
399  *p++ = ' ';
400  space_flag = false;
401  }
402  *p++ = ch;
403  }
404  }
405  *p = 0;
406  if (is_safe_string) {
407  printf("%s: %s\n", attr, &buffer[0]);
408  }
409  else {
410  p = pst_base64_encode(&buffer[0], buffer.size());
411  printf("%s:: %s\n", attr, p);
412  free(p);
413  }
414 }
415 
416 
417 // Combines values representing address lines into an address,i
418 // lines separated with "$" as per PostalAddress syntax in RFC4517
419 void print_ldif_address(const char *attr, int nvalues, pst_string value, ...)
420 {
421  DEBUG_ENT("print_ldif_address");
422  bool space_flag = false;
423  bool newline_flag = false;
424  char *address = NULL; // Buffer where address is built up
425  int len = 0; // Length of buffer
426  int i = 0; // Index of next character position in buffer
427  va_list ap;
428 
429  va_start(ap, value);
430  while (!value.str) {
431  nvalues--;
432  if (nvalues == 0) { // Nothing at all to do!
433  va_end(ap);
434  DEBUG_RET();
435  return;
436  }
437  value = va_arg(ap, pst_string);
438  }
439 
440  for (;;) {
441  char ch = *(value.str)++;
442 
443  if (ch == 0) {
444  do {
445  nvalues--;
446  if (nvalues == 0) break;
447  value = va_arg(ap, pst_string);
448  } while (!value.str);
449  if (!nvalues || !value.str) break;
450  space_flag = true;
451  newline_flag = true;
452  }
453  else if (ch == '\r')
454  continue;
455  else if (ch == '\n') {
456  newline_flag = true;
457  continue;
458  }
459  else if (ch == ' ') {
460  space_flag = true;
461  continue;
462  }
463  else {
464  if (i > (len-5)) {
465  len += 256;
466  char *addr = (char *)realloc(address, len); // cppcheck found unchecked error
467  if (!addr) exit(3);
468  address = addr;
469  }
470  if (newline_flag) {
471  address[i++] = '$';
472  newline_flag = false;
473  space_flag = false;
474  }
475  else if (space_flag) {
476  address[i++] = ' ';
477  space_flag = false;
478  }
479  if (ch == '$' || ch == '\\') address[i++] = '\\';
480  address[i++] = ch;
481  }
482  }
483  va_end(ap);
484  if (i == 0) return; // Nothing to do
485  address[i] = 0;
486  print_ldif_single(attr, address);
487  free(address);
488  DEBUG_RET();
489 }
490 
491 
492 void print_ldif_multi(const char *dn, pst_string value)
493 {
494  char *n;
495  char *valuestr = value.str;
496  while ((n = strchr(valuestr, '\n'))) {
497  print_ldif_single(dn, valuestr);
498  valuestr = n + 1;
499  }
500  print_ldif_single(dn, valuestr);
501 }
502 
503 
504 void print_ldif_two(const char *attr, pst_string value1, pst_string value2)
505 {
506  size_t len1, len2;
507  if (value1.str && *value1.str)
508  len1 = strlen(value1.str);
509  else {
510  print_ldif_single(attr, value2);
511  return;
512  }
513 
514  if (value2.str && *value2.str)
515  len2 = strlen(value2.str);
516  else {
517  print_ldif_single(attr, value1);
518  return;
519  }
520 
521  vector<char> value(len1 + len2 + 2);
522  memcpy(&value[0], value1.str, len1);
523  value[len1] = ' ';
524  memcpy(&value[0] + len1 + 1, value2.str, len2 + 1);
525  print_ldif_single(attr, &value[0]);
526 }
527 
528 
529 void build_cn(char *cn, size_t len, int nvalues, pst_string value, ...)
530 {
531  bool space_flag = false;
532  size_t i = 0;
533  va_list ap;
534 
535  va_start(ap, value);
536 
537  while (!value.str) {
538  nvalues--;
539  if (nvalues == 0) {
540  cn[0] = 0; // Just a terminating NUL
541  va_end(ap);
542  return;
543  }
544  value = va_arg(ap, pst_string);
545  }
546  for (;;) {
547  char ch = *(value.str)++;
548 
549  if (ch == 0 || ch == '\n') {
550  do {
551  nvalues--;
552  if (nvalues == 0) break;
553  value = va_arg(ap, pst_string);
554  } while (!value.str);
555  if (!nvalues || !value.str) break;
556  space_flag = true;
557  }
558  else if (ch == '\r')
559  continue;
560  else if (ch == ' ') {
561  space_flag = true;
562  continue;
563  }
564  else {
565  if (space_flag) {
566  if (i > 0) {
567  if (i < (len - 2)) cn[i++] = ' ';
568  else break;
569  }
570  space_flag = false;
571  }
572  if (i < (len - 1)) cn[i++] = ch;
573  else break;
574  }
575  }
576  cn[i] = 0;
577  va_end(ap);
578 }
579 
580 
581 int main(int argc, char* const* argv) {
582  pst_desc_tree *d_ptr;
583  char *fname = NULL;
584  int c;
585  char *d_log = NULL;
586  prog_name = argv[0];
587  pst_item *item = NULL;
588 
589  while ((c = getopt(argc, argv, "b:c:d:l:oVh"))!= -1) {
590  switch (c) {
591  case 'b':
592  ldap_base = optarg;
593  break;
594  case 'c':
595  ldap_class.push_back(string(optarg));
596  break;
597  case 'd':
598  d_log = optarg;
599  break;
600  case 'h':
601  usage();
602  exit(0);
603  break;
604  case 'l':
605  ldif_extra_line.push_back(string(optarg));
606  break;
607  case 'o':
608  old_schema = true;
609  break;
610  case 'V':
611  version();
612  exit(0);
613  break;
614  default:
615  usage();
616  exit(1);
617  break;
618  }
619  }
620 
621  if ((argc > optind) && (ldap_base)) {
622  fname = argv[optind];
623  } else {
624  usage();
625  exit(2);
626  }
627 
628  #ifdef DEBUG_ALL
629  // force a log file
630  if (!d_log) d_log = "pst2ldif.log";
631  #endif
632  DEBUG_INIT(d_log, NULL);
633  DEBUG_ENT("main");
634  RET_DERROR(pst_open(&pstfile, fname, NULL), 1, ("Error opening File\n"));
635  RET_DERROR(pst_load_index(&pstfile), 2, ("Index Error\n"));
636 
638 
639  d_ptr = pstfile.d_head; // first record is main record
640  item = (pst_item*)pst_parse_item(&pstfile, d_ptr, NULL);
641  if (!item || !item->message_store) {
642  DEBUG_RET();
643  DIE(("main: Could not get root record\n"));
644  }
645 
646  d_ptr = pst_getTopOfFolders(&pstfile, item);
647  if (!d_ptr) {
648  DEBUG_RET();
649  DIE(("Top of folders record not found. Cannot continue\n"));
650  }
651 
652  pst_freeItem(item);
653 
654  if (old_schema && (strlen(ldap_base) > 2)) {
655  char *ldap_org = strdup(ldap_base+2); // assume first 2 chars are o=
656  char *temp = strchr(ldap_org, ',');
657  if (temp) {
658  *temp = '\0';
659  // write the ldap header
660  printf("dn: %s\n", ldap_base);
661  printf("o: %s\n", ldap_org);
662  printf("objectClass: organization\n\n");
663  printf("dn: cn=root, %s\n", ldap_base);
664  printf("cn: root\n");
665  printf("sn: root\n");
666  for (vector<string>::size_type i=0; i<ldap_class.size(); i++)
667  print_ldif_single("objectClass", ldap_class[i].c_str());
668  printf("\n");
669  }
670  free(ldap_org); // found by cppcheck
671  }
672 
673  process(d_ptr->child); // do the children of TOPF
674  pst_close(&pstfile);
675  DEBUG_RET();
677  return 0;
678 }
679 
680 
681 void usage(void) {
682  version();
683  printf("Usage: %s [OPTIONS] {PST FILENAME}\n", prog_name);
684  printf("OPTIONS:\n");
685  printf("\t-V\t- Version. Display program version\n");
686  printf("\t-b ldapbase\t- set the LDAP base value\n");
687  printf("\t-c class\t- set the class of the LDAP objects (may contain more than one)\n");
688  printf("\t-d <filename>\t- Debug to file.\n");
689  printf("\t-h\t- Help. This screen\n");
690  printf("\t-l line\t- extra line to insert in the LDIF file for each contact\n");
691  printf("\t-o\t- use old schema, default is new schema\n");
692 }
693 
694 
695 void version(void) {
696  printf("pst2ldif v%s\n", VERSION);
697 #if BYTE_ORDER == BIG_ENDIAN
698  printf("Big Endian implementation being used.\n");
699 #elif BYTE_ORDER == LITTLE_ENDIAN
700  printf("Little Endian implementation being used.\n");
701 #else
702 # error "Byte order not supported by this library"
703 #endif
704 }
705 
706 
707 char *check_filename(char *fname) {
708  char *t = fname;
709  if (t == NULL) {
710  return fname;
711  }
712  while ((t = strpbrk(t, "/\\:"))) {
713  // while there are characters in the second string that we don't want
714  *t = '_'; //replace them with an underscore
715  }
716  return fname;
717 }
718 
719 
720 // This function escapes Distinguished Names (as per RFC4514)
721 void print_ldif_dn(const char *attr, pst_string value, const char *base)
722 {
723  printf("dn: cn=");
724  const char *valuestr = value.str;
725  // remove leading spaces (RFC says escape them)
726  while (*valuestr == ' ')
727  valuestr++;
728 
729  print_escaped_dn(valuestr);
730  if (base && base[0]) {
731  printf(", %s", base);
732  }
733  printf("\n");
734  return;
735 }
736 
737 
738 void print_escaped_dn(const char *value)
739 {
740  char ch;
741 
742  // escape initial '#' and space
743  if (*value == '#' || *value == ' ')
744  putchar('\\');
745 
746  while ((ch = *value++) != 0) {
747  if (((ch & 0x80) != 0) || (ch <= 0x1F))
748  // Print as escaped hex digits
749  printf("\\%2.2X", ch & 0xFF);
750  else switch (ch) {
751  case '\\':
752  case '"' :
753  case '+' :
754  case ',' :
755  case ';' :
756  case '<' :
757  case '>' :
758  putchar('\\');
759  // Fall through
760  default:
761  putchar(ch);
762  }
763  }
764  return;
765 }
pst_string other_postal_code
mapi element 0x3a61 PR_OTHER_ADDRESS_POSTAL_CODE
Definition: libpst.h:554
bool operator()(const char *s1, const char *s2) const
Definition: pst2ldif.cpp:47
pst_string suffix
mapi element 0x3a05 PR_GENERATION (Jr., Sr., III, etc)
Definition: libpst.h:580
pst_string home_address
mapi element 0x801a
Definition: libpst.h:492
pst_item_contact * contact
contact mapi elements
Definition: libpst.h:790
pst_string comment
mapi element 0x3004 PR_COMMENT
Definition: libpst.h:829
void build_cn(char *cn, size_t len, int nvalues, pst_string value,...)
Definition: pst2ldif.cpp:529
void print_ldif_single(const char *attr, const char *value)
Definition: pst2ldif.cpp:367
pst_string home_fax
mapi element 0x3a25 PR_HOME_FAX_NUMBER
Definition: libpst.h:498
pst_string mobile_phone
mapi element 0x3a1c PR_MOBILE_TELEPHONE_NUMBER
Definition: libpst.h:534
pst_string car_phone
mapi element 0x3a1e PR_CAR_TELEPHONE_NUMBER
Definition: libpst.h:457
char * prog_name
Definition: pst2ldif.cpp:35
pst_file pstfile
Definition: pst2ldif.cpp:36
#define DIE(x)
Definition: define.h:160
pst_string home_city
mapi element 0x3a59 PR_HOME_ADDRESS_CITY
Definition: libpst.h:494
pst_string business_homepage
mapi element 0x3a51 PR_BUSINESS_HOME_PAGE
Definition: libpst.h:441
pst_string address2a
mapi element 0x8095
Definition: libpst.h:411
pst_string other_country
mapi element 0x3a60 PR_OTHER_ADDRESS_COUNTRY
Definition: libpst.h:548
#define VERSION
Definition: config.h:503
pst_string home_street
mapi element 0x3a5d PR_HOME_ADDRESS_STREET
Definition: libpst.h:510
pst_string business_state
mapi element 0x3a28 PR_BUSINESS_ADDRESS_STATE_OR_PROVINCE
Definition: libpst.h:451
void pst_freeItem(pst_item *item)
Free the item returned by pst_parse_item().
Definition: libpst.c:3381
pst_string business_po_box
mapi element 0x3a2b PR_BUSINESS_PO_BOX
Definition: libpst.h:447
int pst_load_extended_attributes(pst_file *pf)
Try to load the extended attributes from the pst file.
Definition: libpst.c:698
pst_string other_street
mapi element 0x3a63 PR_OTHER_ADDRESS_STREET
Definition: libpst.h:558
char * ldap_base
Definition: pst2ldif.cpp:38
pst_string other_po_box
mapi element 0x3a64 PR_OTHER_ADDRESS_POST_OFFICE_BOX
Definition: libpst.h:552
int pst_close(pst_file *pf)
Close a pst file.
Definition: libpst.c:410
pst_string business_country
mapi element 0x3a26 PR_BUSINESS_ADDRESS_COUNTRY
Definition: libpst.h:437
pst_string surname
mapi element 0x3a11 PR_SURNAME
Definition: libpst.h:582
vector< string > ldif_extra_line
Definition: pst2ldif.cpp:41
void version(void)
Definition: pst2ldif.cpp:695
pst_string display_name_prefix
mapi element 0x3a45 PR_DISPLAY_NAME_PREFIX
Definition: libpst.h:471
#define DEBUG_INFO(x)
Definition: define.h:166
pst_string company_name
mapi element 0x3a16 PR_COMPANY_NAME
Definition: libpst.h:461
This contains the common mapi elements, and pointers to structures for each major mapi item type...
Definition: libpst.h:780
#define DEBUG_ENT(x)
Definition: define.h:171
int getopt(int argc, char *const *argv, char *optstring)
Definition: XGetopt.c:139
bool old_schema
Definition: pst2ldif.cpp:37
#define DEBUG_RET()
Definition: define.h:176
pst_string file_as
mapi element 0x3001 PR_DISPLAY_NAME
Definition: libpst.h:827
pst_string first_name
mapi element 0x3a06 PR_GIVEN_NAME
Definition: libpst.h:473
pst_string address2
mapi element 0x8093
Definition: libpst.h:409
static const char * unique_string(const char *name)
Definition: pst2ldif.cpp:97
The string is either utf8 encoded, or it is in the code page specified by the containing mapi object...
Definition: libpst.h:144
pst_string business_fax
mapi element 0x3a24 PR_BUSINESS_FAX_NUMBER
Definition: libpst.h:439
pst_string job_title
mapi element 0x3a17 PR_TITLE
Definition: libpst.h:516
struct pst_desc_tree * next
Definition: libpst.h:133
int ldif_extra_line_count
Definition: pst2ldif.cpp:39
static void free_strings(string_set &s)
Definition: pst2ldif.cpp:61
pst_desc_tree * pst_getTopOfFolders(pst_file *pf, const pst_item *root)
Get the top of folders descriptor tree.
Definition: libpst.c:544
struct pst_desc_tree * child
Definition: libpst.h:135
int pst_open(pst_file *pf, const char *name, const char *charset)
Open a pst file.
Definition: libpst.c:315
char * check_filename(char *fname)
Definition: pst2ldif.cpp:707
pst_index_ll * desc
Definition: libpst.h:129
pst_string other_phone
mapi element 0x3a1f PR_OTHER_TELEPHONE_NUMBER
Definition: libpst.h:550
void print_escaped_dn(const char *value)
Definition: pst2ldif.cpp:738
pst_item_message_store * message_store
message store mapi elements
Definition: libpst.h:794
vector< string > ldap_class
Definition: pst2ldif.cpp:40
void print_ldif_two(const char *attr, pst_string value1, pst_string value2)
Definition: pst2ldif.cpp:504
char * pst_base64_encode(void *data, size_t size)
Definition: libstrfunc.c:21
pst_string business_address
mapi element 0x801b
Definition: libpst.h:433
#define RET_DERROR(res, ret_val, x)
Definition: define.h:184
void print_ldif_multi(const char *dn, pst_string value)
Definition: pst2ldif.cpp:492
pst_string address3
mapi element 0x80a3
Definition: libpst.h:417
pst_string home_po_box
mapi element 0x3a5e PR_HOME_ADDRESS_POST_OFFICE_BOX
Definition: libpst.h:504
static void process(pst_desc_tree *d_ptr)
Definition: pst2ldif.cpp:111
int type
derived from mapi elements 0x001a PR_MESSAGE_CLASS or 0x3613 PR_CONTAINER_CLASS
Definition: libpst.h:811
int main(int argc, char *const *argv)
Definition: pst2ldif.cpp:581
pst_string home_country
mapi element 0x3a5a PR_HOME_ADDRESS_COUNTRY
Definition: libpst.h:496
pst_string home_phone
mapi element 0x3a09 PR_HOME_TELEPHONE_NUMBER
Definition: libpst.h:500
pst_string home_postal_code
mapi element 0x3a5b PR_HOME_ADDRESS_POSTAL_CODE
Definition: libpst.h:506
int is_utf8
Definition: libpst.h:147
void usage(void)
Definition: pst2ldif.cpp:681
pst_item * pst_parse_item(pst_file *pf, pst_desc_tree *d_ptr, pst_id2_tree *m_head)
Process a high level object from the pst file.
Definition: libpst.c:1249
pst_string home_state
mapi element 0x3a5c PR_HOME_ADDRESS_STATE_OR_PROVINCE
Definition: libpst.h:508
char * ldap_org
Definition: nick2ldif.cpp:16
pst_string business_city
mapi element 0x3a27 PR_BUSINESS_ADDRESS_CITY
Definition: libpst.h:435
pst_string business_phone
mapi element 0x3a08 PR_BUSINESS_TELEPHONE_NUMBER
Definition: libpst.h:443
static const char * register_string(string_set &s, const char *name)
Definition: pst2ldif.cpp:75
int optind
Definition: XGetopt.c:137
pst_desc_tree * d_head
the head and tail of the top level of the descriptor tree
Definition: libpst.h:907
pst_string other_address
mapi element 0x801c
Definition: libpst.h:544
static string_set all_strings
Definition: pst2ldif.cpp:54
pst_string personal_homepage
mapi element 0x3a50 PR_PERSONAL_HOME_PAGE
Definition: libpst.h:562
#define PST_TYPE_CONTACT
Definition: libpst.h:34
pst_string address1
mapi element 0x3003 PR_EMAIL_ADDRESS, or 0x8083
Definition: libpst.h:401
#define DEBUG_INIT(fname, mutex)
Definition: define.h:182
set< const char *, ltstr > string_set
Definition: pst2ldif.cpp:52
pst_string business_street
mapi element 0x3a29 PR_BUSINESS_ADDRESS_STREET
Definition: libpst.h:453
void print_ldif_dn(const char *attr, pst_string value, const char *base)
Definition: pst2ldif.cpp:721
pst_string business_postal_code
mapi element 0x3a2a PR_BUSINESS_POSTAL_CODE
Definition: libpst.h:449
int pst_load_index(pst_file *pf)
Load the index entries from the pst file.
Definition: libpst.c:652
pst_string other_state
mapi element 0x3a62 PR_OTHER_ADDRESS_STATE_OR_PROVINCE
Definition: libpst.h:556
pst_item_folder * folder
folder mapi elements
Definition: libpst.h:788
void pst_convert_utf8_null(pst_item *item, pst_string *str)
Convert str to utf8 if possible; null strings are preserved.
Definition: libpst.c:4535
pst_string other_city
mapi element 0x3a5f PR_OTHER_ADDRESS_CITY
Definition: libpst.h:546
char * str
Definition: libpst.h:148
char * optarg
Definition: XGetopt.c:136
pst_string address1a
mapi element 0x8085
Definition: libpst.h:403
pst_string address3a
mapi element 0x80a5
Definition: libpst.h:419
void print_ldif_address(const char *attr, int nvalues, pst_string value,...)
Definition: pst2ldif.cpp:419