48 return strcasecmp(s1, s2) < 0;
63 if (s.empty())
return;
64 for (string_set::iterator i=s.begin(); i!=s.end(); i++) {
76 string_set::const_iterator i = s.find(name);
77 if (i != s.end())
return *i;
78 char *x = strdup(name);
102 vector<char> n(strlen(name)+10);
103 snprintf(&n[0], n.size(),
"%s %d", name, unique++);
121 fprintf(stderr,
"entering folder %s\n", item->
file_as.
str);
341 for (vector<string>::size_type i=0; i<
ldap_class.size(); i++)
370 bool is_safe_string =
true;
371 bool space_flag =
false;
374 while (*value ==
' ') value++;
375 len = strlen(value) + 1;
376 vector<char> buffer(len);
377 char *p = &buffer[0];
381 if (*value ==
':' || *value ==
'<')
382 is_safe_string =
false;
386 if (ch == 0 || ch ==
'\n')
390 else if (ch ==
' ') {
395 if ((ch & 0x80) == 0x80) {
396 is_safe_string =
false;
406 if (is_safe_string) {
407 printf(
"%s: %s\n", attr, &buffer[0]);
411 printf(
"%s:: %s\n", attr, p);
422 bool space_flag =
false;
423 bool newline_flag =
false;
424 char *address = NULL;
441 char ch = *(value.
str)++;
446 if (nvalues == 0)
break;
448 }
while (!value.
str);
449 if (!nvalues || !value.
str)
break;
455 else if (ch ==
'\n') {
459 else if (ch ==
' ') {
466 char *addr = (
char *)realloc(address, len);
472 newline_flag =
false;
475 else if (space_flag) {
479 if (ch ==
'$' || ch ==
'\\') address[i++] =
'\\';
495 char *valuestr = value.
str;
496 while ((n = strchr(valuestr,
'\n'))) {
507 if (value1.
str && *value1.
str)
508 len1 = strlen(value1.
str);
514 if (value2.
str && *value2.
str)
515 len2 = strlen(value2.
str);
521 vector<char> value(len1 + len2 + 2);
522 memcpy(&value[0], value1.
str, len1);
524 memcpy(&value[0] + len1 + 1, value2.
str, len2 + 1);
531 bool space_flag =
false;
547 char ch = *(value.
str)++;
549 if (ch == 0 || ch ==
'\n') {
552 if (nvalues == 0)
break;
554 }
while (!value.
str);
555 if (!nvalues || !value.
str)
break;
560 else if (ch ==
' ') {
567 if (i < (len - 2)) cn[i++] =
' ';
572 if (i < (len - 1)) cn[i++] = ch;
581 int main(
int argc,
char*
const* argv) {
589 while ((c =
getopt(argc, argv,
"b:c:d:l:oVh"))!= -1) {
630 if (!d_log) d_log =
"pst2ldif.log";
643 DIE((
"main: Could not get root record\n"));
649 DIE((
"Top of folders record not found. Cannot continue\n"));
662 printf(
"objectClass: organization\n\n");
664 printf(
"cn: root\n");
665 printf(
"sn: root\n");
666 for (vector<string>::size_type i=0; i<
ldap_class.size(); i++)
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");
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");
702 # error "Byte order not supported by this library" 712 while ((t = strpbrk(t,
"/\\:"))) {
724 const char *valuestr = value.
str;
726 while (*valuestr ==
' ')
730 if (base && base[0]) {
731 printf(
", %s", base);
743 if (*value ==
'#' || *value ==
' ')
746 while ((ch = *value++) != 0) {
747 if (((ch & 0x80) != 0) || (ch <= 0x1F))
749 printf(
"\\%2.2X", ch & 0xFF);
bool operator()(const char *s1, const char *s2) const
pst_item_contact * contact
contact mapi elements
pst_string comment
mapi element 0x3004 PR_COMMENT
void build_cn(char *cn, size_t len, int nvalues, pst_string value,...)
void print_ldif_single(const char *attr, const char *value)
void pst_freeItem(pst_item *item)
Free the item returned by pst_parse_item().
int pst_load_extended_attributes(pst_file *pf)
Try to load the extended attributes from the pst file.
int pst_close(pst_file *pf)
Close a pst file.
vector< string > ldif_extra_line
This contains the common mapi elements, and pointers to structures for each major mapi item type...
int getopt(int argc, char *const *argv, char *optstring)
pst_string file_as
mapi element 0x3001 PR_DISPLAY_NAME
static const char * unique_string(const char *name)
The string is either utf8 encoded, or it is in the code page specified by the containing mapi object...
struct pst_desc_tree * next
int ldif_extra_line_count
static void free_strings(string_set &s)
pst_desc_tree * pst_getTopOfFolders(pst_file *pf, const pst_item *root)
Get the top of folders descriptor tree.
struct pst_desc_tree * child
int pst_open(pst_file *pf, const char *name, const char *charset)
Open a pst file.
char * check_filename(char *fname)
void print_escaped_dn(const char *value)
pst_item_message_store * message_store
message store mapi elements
vector< string > ldap_class
void print_ldif_two(const char *attr, pst_string value1, pst_string value2)
char * pst_base64_encode(void *data, size_t size)
#define RET_DERROR(res, ret_val, x)
void print_ldif_multi(const char *dn, pst_string value)
static void process(pst_desc_tree *d_ptr)
int type
derived from mapi elements 0x001a PR_MESSAGE_CLASS or 0x3613 PR_CONTAINER_CLASS
int main(int argc, char *const *argv)
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.
static const char * register_string(string_set &s, const char *name)
pst_desc_tree * d_head
the head and tail of the top level of the descriptor tree
static string_set all_strings
#define DEBUG_INIT(fname, mutex)
set< const char *, ltstr > string_set
void print_ldif_dn(const char *attr, pst_string value, const char *base)
int pst_load_index(pst_file *pf)
Load the index entries from the pst file.
pst_item_folder * folder
folder mapi elements
void pst_convert_utf8_null(pst_item *item, pst_string *str)
Convert str to utf8 if possible; null strings are preserved.
void print_ldif_address(const char *attr, int nvalues, pst_string value,...)