Main Page | Namespace List | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

pst2ldif.cpp

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (c) 2004 Carl Byington - 510 Software Group, released under
00004 the GPL version 2 or any later version at your choice available at
00005 http://www.fsf.org/licenses/gpl.txt
00006 
00007 Based on readpst.c by David Smith
00008 
00009 */
00010 
00011 using namespace std;
00012 
00013 // needed for std c++ collections
00014 #include <set>
00015 #include <vector>
00016 #include <string>
00017 
00018 extern "C" {
00019     #include "define.h"
00020     #include "lzfu.h"
00021 }
00022 
00023 void       usage(void);
00024 void       version(void);
00025 char       *check_filename(char *fname);
00026 void        print_ldif_single(const char *attr, const char *value);
00027 void        print_ldif_single(const char *attr, pst_string value);
00028 void        print_ldif_address(const char *attr, int nvalues, pst_string value, ...);
00029 void        print_ldif_dn(const char *attr, pst_string value, const char *base);
00030 void        print_ldif_multi(const char *dn, pst_string value);
00031 void        print_ldif_two(const char *attr, pst_string value1, pst_string value2);
00032 void        print_escaped_dn(const char *value);
00033 void        build_cn(char *cn, size_t len, int nvalues, pst_string value, ...);
00034 
00035 char *prog_name;
00036 pst_file pstfile;
00037 bool    old_schema            = false;
00038 char    *ldap_base            = NULL;   // 'o=some.domain.tld,c=US'
00039 int     ldif_extra_line_count = 0;
00040 vector<string> ldap_class;              // 'newPerson' or 'inetOrgPerson'
00041 vector<string> ldif_extra_line;         // 'o: myorg'
00042 
00043 
00045 // define our ordering
00046 struct ltstr {
00047     bool operator()(const char* s1, const char* s2) const {
00048         return strcasecmp(s1, s2) < 0;
00049     }
00050 };
00051 // define our set
00052 typedef set<const char *, ltstr>    string_set;
00053 // make a static set to hold the cn values
00054 static string_set all_strings;
00055 
00056 
00058 // helper to free all the strings in a set
00059 //
00060 static void free_strings(string_set &s);
00061 static void free_strings(string_set &s)
00062 {
00063     for (string_set::iterator i=s.begin(); i!=s.end(); i++) {
00064         free((void*)*i);
00065     }
00066     s.clear();
00067 }
00068 
00069 
00071 // helper to register a string in a string set
00072 //
00073 static const char* register_string(string_set &s, const char *name);
00074 static const char* register_string(string_set &s, const char *name) {
00075     string_set::const_iterator i = s.find(name);
00076     if (i != s.end()) return *i;
00077     char *x = strdup(name);
00078     s.insert(x);
00079     return x;
00080 }
00081 
00082 
00084 // register a global string
00085 //
00086 static const char* register_string(const char *name);
00087 static const char* register_string(const char *name) {
00088     return register_string(all_strings, name);
00089 }
00090 
00091 
00093 // make a unique string
00094 //
00095 static const char* unique_string(const char *name);
00096 static const char* unique_string(const char *name) {
00097     int  unique = 2;
00098     string_set::iterator i = all_strings.find(name);
00099     if (i == all_strings.end()) return register_string(name);
00100     while (true) {
00101         vector<char> n(strlen(name)+10);
00102         snprintf(&n[0], n.size(), "%s %d", name, unique++);
00103         string_set::iterator i = all_strings.find(&n[0]);
00104         if (i == all_strings.end()) return register_string(&n[0]);
00105     }
00106 }
00107 
00108 
00109 static void process(pst_desc_ll *d_ptr);
00110 static void process(pst_desc_ll *d_ptr) {
00111     DEBUG_ENT("process");
00112     pst_item *item = NULL;
00113     while (d_ptr) {
00114         if (d_ptr->desc) {
00115             item = pst_parse_item(&pstfile, d_ptr, NULL);
00116             DEBUG_INFO(("item pointer is %p\n", item));
00117             if (item) {
00118                 if (item->folder && d_ptr->child && item->file_as.str && strcasecmp(item->file_as.str, "Deleted Items")) {
00119                     //if this is a non-empty folder other than deleted items, we want to recurse into it
00120                     fprintf(stderr, "entering folder %s\n", item->file_as.str);
00121                     process(d_ptr->child);
00122 
00123                 } else if (item->contact && (item->type == PST_TYPE_CONTACT)) {
00124                     // deal with a contact
00125                     char cn[1000];
00126 
00127                     // convert everything to utf8
00128                     pst_convert_utf8_null(item, &item->contact->display_name_prefix);
00129                     pst_convert_utf8_null(item, &item->contact->first_name);
00130                     pst_convert_utf8_null(item, &item->contact->surname);
00131                     pst_convert_utf8_null(item, &item->contact->suffix);
00132                     pst_convert_utf8_null(item, &item->contact->company_name);
00133                     pst_convert_utf8_null(item, &item->contact->job_title);
00134                     pst_convert_utf8_null(item, &item->contact->address1);
00135                     pst_convert_utf8_null(item, &item->contact->address2);
00136                     pst_convert_utf8_null(item, &item->contact->address3);
00137                     pst_convert_utf8_null(item, &item->contact->address1a);
00138                     pst_convert_utf8_null(item, &item->contact->address2a);
00139                     pst_convert_utf8_null(item, &item->contact->address3a);
00140                     pst_convert_utf8_null(item, &item->contact->business_address);
00141                     pst_convert_utf8_null(item, &item->contact->business_po_box);
00142                     pst_convert_utf8_null(item, &item->contact->business_street);
00143                     pst_convert_utf8_null(item, &item->contact->business_city);
00144                     pst_convert_utf8_null(item, &item->contact->business_state);
00145                     pst_convert_utf8_null(item, &item->contact->business_postal_code);
00146                     pst_convert_utf8_null(item, &item->contact->home_address);
00147                     pst_convert_utf8_null(item, &item->contact->home_po_box);
00148                     pst_convert_utf8_null(item, &item->contact->home_street);
00149                     pst_convert_utf8_null(item, &item->contact->home_city);
00150                     pst_convert_utf8_null(item, &item->contact->home_state);
00151                     pst_convert_utf8_null(item, &item->contact->home_postal_code);
00152                     pst_convert_utf8_null(item, &item->contact->other_address);
00153                     pst_convert_utf8_null(item, &item->contact->other_po_box);
00154                     pst_convert_utf8_null(item, &item->contact->other_street);
00155                     pst_convert_utf8_null(item, &item->contact->other_city);
00156                     pst_convert_utf8_null(item, &item->contact->other_state);
00157                     pst_convert_utf8_null(item, &item->contact->other_postal_code);
00158                     pst_convert_utf8_null(item, &item->contact->business_fax);
00159                     pst_convert_utf8_null(item, &item->contact->home_fax);
00160                     pst_convert_utf8_null(item, &item->contact->business_phone);
00161                     pst_convert_utf8_null(item, &item->contact->home_phone);
00162                     pst_convert_utf8_null(item, &item->contact->car_phone);
00163                     pst_convert_utf8_null(item, &item->contact->mobile_phone);
00164                     pst_convert_utf8_null(item, &item->contact->other_phone);
00165                     pst_convert_utf8_null(item, &item->contact->business_homepage);
00166                     pst_convert_utf8_null(item, &item->contact->personal_homepage);
00167                     pst_convert_utf8_null(item, &item->comment);
00168 
00169                     build_cn(cn, sizeof(cn), 4,
00170                         item->contact->display_name_prefix,
00171                         item->contact->first_name,
00172                         item->contact->surname,
00173                         item->contact->suffix);
00174                     if (cn[0] != 0) {
00175                         // have a valid cn
00176                         pst_string ucn;
00177                         ucn.str     = (char*)unique_string(cn);
00178                         ucn.is_utf8 = 1;    // all the components are already utf8
00179 
00180                         print_ldif_dn("dn", ucn, ldap_base);
00181                         print_ldif_single("cn", ucn);
00182                         if (item->contact->first_name.str) {
00183                             print_ldif_two("givenName",
00184                                            item->contact->display_name_prefix,
00185                                            item->contact->first_name);
00186                         }
00187                         if (item->contact->surname.str) {
00188                             print_ldif_two("sn",
00189                                            item->contact->surname,
00190                                            item->contact->suffix);
00191                         }
00192                         else if (item->contact->company_name.str) {
00193                             print_ldif_single("sn", item->contact->company_name);
00194                         }
00195                         else
00196                             print_ldif_single("sn", ucn); // use cn as sn if we cannot find something better
00197 
00198                         if (old_schema) {
00199                             if (item->contact->job_title.str)
00200                                 print_ldif_single("personalTitle", item->contact->job_title);
00201                             if (item->contact->company_name.str)
00202                                 print_ldif_single("company", item->contact->company_name);
00203                         }
00204                         else {
00205                             // new schema
00206                             if (item->contact->job_title.str)
00207                                 print_ldif_single("title", item->contact->job_title);
00208                             if (item->contact->company_name.str)
00209                                 print_ldif_single("o", item->contact->company_name);
00210                         }
00211                         if (item->contact->address1.str  && *item->contact->address1.str)
00212                             print_ldif_single("mail", item->contact->address1);
00213                         if (item->contact->address2.str  && *item->contact->address2.str)
00214                             print_ldif_single("mail", item->contact->address2);
00215                         if (item->contact->address3.str  && *item->contact->address3.str)
00216                             print_ldif_single("mail", item->contact->address3);
00217                         if (item->contact->address1a.str && *item->contact->address1a.str)
00218                             print_ldif_single("mail", item->contact->address1a);
00219                         if (item->contact->address2a.str && *item->contact->address2a.str)
00220                             print_ldif_single("mail", item->contact->address2a);
00221                         if (item->contact->address3a.str && *item->contact->address3a.str)
00222                             print_ldif_single("mail", item->contact->address3a);
00223 
00224                         if (old_schema) {
00225                             if (item->contact->business_address.str) {
00226                                 if (item->contact->business_po_box.str)
00227                                     print_ldif_single("postalAddress", item->contact->business_po_box);
00228                                 if (item->contact->business_street.str)
00229                                     print_ldif_multi("postalAddress", item->contact->business_street);
00230                                 if (item->contact->business_city.str)
00231                                     print_ldif_single("l", item->contact->business_city);
00232                                 if (item->contact->business_state.str)
00233                                     print_ldif_single("st", item->contact->business_state);
00234                                 if (item->contact->business_postal_code.str)
00235                                     print_ldif_single("postalCode", item->contact->business_postal_code);
00236                             }
00237                             else if (item->contact->home_address.str) {
00238                                 if (item->contact->home_po_box.str)
00239                                     print_ldif_single("postalAddress", item->contact->home_po_box);
00240                                 if (item->contact->home_street.str)
00241                                     print_ldif_multi("postalAddress", item->contact->home_street);
00242                                 if (item->contact->home_city.str)
00243                                     print_ldif_single("l", item->contact->home_city);
00244                                 if (item->contact->home_state.str)
00245                                     print_ldif_single("st", item->contact->home_state);
00246                                 if (item->contact->home_postal_code.str)
00247                                     print_ldif_single("postalCode", item->contact->home_postal_code);
00248                             }
00249                             else if (item->contact->other_address.str) {
00250                                 if (item->contact->other_po_box.str)
00251                                     print_ldif_single("postalAddress", item->contact->other_po_box);
00252                                 if (item->contact->other_street.str)
00253                                     print_ldif_multi("postalAddress", item->contact->other_street);
00254                                 if (item->contact->other_city.str)
00255                                     print_ldif_single("l", item->contact->other_city);
00256                                 if (item->contact->other_state.str)
00257                                     print_ldif_single("st", item->contact->other_state);
00258                                 if (item->contact->other_postal_code.str)
00259                                     print_ldif_single("postalCode", item->contact->other_postal_code);
00260                             }
00261                         }
00262                         else {
00263                             // new schema, with proper RFC4517 postal addresses
00264                             if (item->contact->business_address.str) {
00265                                 print_ldif_address("postalAddress", 6,
00266                                     item->contact->business_po_box,
00267                                     item->contact->business_street,
00268                                     item->contact->business_city,
00269                                     item->contact->business_state,
00270                                     item->contact->business_postal_code,
00271                                     item->contact->business_country);
00272                                 if (item->contact->business_city.str)
00273                                     print_ldif_single("l", item->contact->business_city);
00274                                 if (item->contact->business_state.str)
00275                                     print_ldif_single("st", item->contact->business_state);
00276                                 if (item->contact->business_postal_code.str)
00277                                     print_ldif_single("postalCode", item->contact->business_postal_code);
00278                             }
00279                             else if (item->contact->home_address.str) {
00280                                 if (item->contact->home_city.str)
00281                                     print_ldif_single("l", item->contact->home_city);
00282                                 if (item->contact->home_state.str)
00283                                     print_ldif_single("st", item->contact->home_state);
00284                                 if (item->contact->home_postal_code.str)
00285                                     print_ldif_single("postalCode", item->contact->home_postal_code);
00286                             }
00287                             else if (item->contact->other_address.str) {
00288                                 print_ldif_address("postalAddress", 6,
00289                                     item->contact->other_po_box,
00290                                     item->contact->other_street,
00291                                     item->contact->other_city,
00292                                     item->contact->other_state,
00293                                     item->contact->other_postal_code,
00294                                     item->contact->other_country);
00295                                 if (item->contact->other_city.str)
00296                                     print_ldif_single("l", item->contact->other_city);
00297                                 if (item->contact->other_state.str)
00298                                     print_ldif_single("st", item->contact->other_state);
00299                                 if (item->contact->other_postal_code.str)
00300                                     print_ldif_single("postalCode", item->contact->other_postal_code);
00301                             }
00302                             if (item->contact->home_address.str) {
00303                                 print_ldif_address("homePostalAddress", 6,
00304                                     item->contact->home_po_box,
00305                                     item->contact->home_street,
00306                                     item->contact->home_city,
00307                                     item->contact->home_state,
00308                                     item->contact->home_postal_code,
00309                                     item->contact->home_country);
00310                             }
00311                         }
00312 
00313                         if (item->contact->business_fax.str)
00314                             print_ldif_single("facsimileTelephoneNumber", item->contact->business_fax);
00315                         else if (item->contact->home_fax.str)
00316                             print_ldif_single("facsimileTelephoneNumber", item->contact->home_fax);
00317 
00318                         if (item->contact->business_phone.str)
00319                             print_ldif_single("telephoneNumber", item->contact->business_phone);
00320                         if (item->contact->home_phone.str)
00321                             print_ldif_single("homePhone", item->contact->home_phone);
00322 
00323                         if (item->contact->car_phone.str)
00324                             print_ldif_single("mobile", item->contact->car_phone);
00325                         else if (item->contact->mobile_phone.str)
00326                             print_ldif_single("mobile", item->contact->mobile_phone);
00327                         else if (item->contact->other_phone.str)
00328                             print_ldif_single("mobile", item->contact->other_phone);
00329 
00330                         if (!old_schema) {
00331                             if (item->contact->business_homepage.str)
00332                                 print_ldif_single("labeledURI", item->contact->business_homepage);
00333                             if (item->contact->personal_homepage.str)
00334                                 print_ldif_single("labeledURI", item->contact->personal_homepage);
00335                         }
00336 
00337                         if (item->comment.str)
00338                             print_ldif_single("description", item->comment);
00339 
00340                         for (vector<string>::size_type i=0; i<ldap_class.size(); i++)
00341                             print_ldif_single("objectClass", ldap_class[i].c_str());
00342                         printf("\n");
00343                     }
00344                 }
00345                 else {
00346                     DEBUG_INFO(("item is not a contact\n"));
00347                 }
00348             }
00349             pst_freeItem(item);
00350         }
00351         d_ptr = d_ptr->next;
00352     }
00353     DEBUG_RET();
00354 }
00355 
00356 
00357 void print_ldif_single(const char *attr, pst_string value)
00358 {
00359     print_ldif_single(attr, value.str);
00360 }
00361 
00362 
00363 // Prints an attribute together with its value.
00364 // If the value isn't a "SAFE STRING" (as defined in RFC2849),
00365 // then it is output as a BASE-64 encoded value
00366 void print_ldif_single(const char *attr, const char *value)
00367 {
00368     size_t len;
00369     bool is_safe_string = true;
00370     bool space_flag = false;
00371 
00372     // Strip leading spaces
00373     while (*value == ' ') value++;
00374     len = strlen(value) + 1;
00375     vector<char> buffer(len);
00376     char *p = &buffer[0];
00377 
00378     // See if "value" is a "SAFE STRING"
00379     // First check characters that are safe but not safe as initial characters
00380     if (*value == ':' || *value == '<')
00381         is_safe_string = false;
00382     for (;;) {
00383         char ch = *value++;
00384 
00385         if (ch == 0 || ch == '\n')
00386             break;
00387         else if (ch == '\r')
00388             continue;
00389         else if (ch == ' ') {
00390             space_flag = true;
00391             continue;
00392         }
00393         else {
00394             if ((ch & 0x80) == 0x80) {
00395                 is_safe_string = false;
00396             }
00397             if (space_flag) {
00398                 *p++ = ' ';
00399                 space_flag = false;
00400             }
00401             *p++ = ch;
00402         }
00403     }
00404     *p = 0;
00405     if (is_safe_string) {
00406         printf("%s: %s\n", attr, &buffer[0]);
00407     }
00408     else {
00409         p = base64_encode(&buffer[0], buffer.size());
00410         printf("%s:: %s\n", attr, p);
00411         free(p);
00412     }
00413 }
00414 
00415 
00416 // Combines values representing address lines into an address,i
00417 // lines separated with "$" as per PostalAddress syntax in RFC4517
00418 void print_ldif_address(const char *attr, int nvalues, pst_string value, ...)
00419 {
00420     DEBUG_ENT("print_ldif_address");
00421     bool space_flag = false;
00422     bool newline_flag = false;
00423     char *address = NULL;    // Buffer where address is built up
00424     int len = 0;             // Length of buffer
00425     int i = 0;               // Index of next character position in buffer
00426     va_list ap;
00427 
00428     va_start(ap, value);
00429     while (!value.str) {
00430         nvalues--;
00431         if (nvalues == 0) {    // Nothing at all to do!
00432             va_end(ap);
00433             DEBUG_RET();
00434             return;
00435         }
00436         value = va_arg(ap, pst_string);
00437     }
00438 
00439     for (;;) {
00440         char ch = *(value.str)++;
00441 
00442         if (ch == 0) {
00443             do {
00444                 nvalues--;
00445                 if (nvalues == 0) break;
00446                 value = va_arg(ap, pst_string);
00447             } while (!value.str);
00448             if (!nvalues || !value.str) break;
00449             space_flag = true;
00450             newline_flag = true;
00451         }
00452         else if (ch == '\r')
00453             continue;
00454         else if (ch == '\n') {
00455             newline_flag = true;
00456             continue;
00457         }
00458         else if (ch == ' ') {
00459             space_flag = true;
00460             continue;
00461         }
00462         else {
00463             if (i > (len-5)) {
00464                 len += 256;
00465                 address = (char *)realloc(address, len);
00466             }
00467             if (newline_flag) {
00468                 address[i++] = '$';
00469                 newline_flag = false;
00470                 space_flag   = false;
00471             }
00472             else if (space_flag) {
00473                 address[i++] = ' ';
00474                 space_flag   = false;
00475             }
00476             if (ch == '$' || ch == '\\') address[i++] = '\\';
00477             address[i++] = ch;
00478         }
00479     }
00480     va_end(ap);
00481     if (i == 0) return;   // Nothing to do
00482     address[i] = 0;
00483     print_ldif_single(attr, address);
00484     free(address);
00485     DEBUG_RET();
00486 }
00487 
00488 
00489 void print_ldif_multi(const char *dn, pst_string value)
00490 {
00491     char *n;
00492     char *valuestr = value.str;
00493     while ((n = strchr(valuestr, '\n'))) {
00494         print_ldif_single(dn, valuestr);
00495         valuestr = n + 1;
00496     }
00497     print_ldif_single(dn, valuestr);
00498 }
00499 
00500 
00501 void print_ldif_two(const char *attr, pst_string value1, pst_string value2)
00502 {
00503     size_t len1, len2;
00504     if (value1.str && *value1.str)
00505         len1 = strlen(value1.str);
00506     else {
00507         print_ldif_single(attr, value2);
00508         return;
00509     }
00510 
00511     if (value2.str && *value2.str)
00512         len2 = strlen(value2.str);
00513     else {
00514         print_ldif_single(attr, value1);
00515         return;
00516     }
00517 
00518     vector<char> value(len1 + len2 + 2);
00519     memcpy(&value[0], value1.str, len1);
00520     value[len1] = ' ';
00521     memcpy(&value[0] + len1 + 1, value2.str, len2 + 1);
00522     print_ldif_single(attr, &value[0]);
00523 }
00524 
00525 
00526 void build_cn(char *cn, size_t len, int nvalues, pst_string value, ...)
00527 {
00528     bool space_flag = false;
00529     size_t i = 0;
00530     va_list ap;
00531 
00532     va_start(ap, value);
00533 
00534     while (!value.str) {
00535        nvalues--;
00536        if (nvalues == 0) {
00537            cn[0] = 0;   // Just a terminating NUL
00538            va_end(ap);
00539            return;
00540        }
00541        value = va_arg(ap, pst_string);
00542     }
00543     for (;;) {
00544         char ch = *(value.str)++;
00545 
00546         if (ch == 0 || ch == '\n') {
00547             do {
00548                 nvalues--;
00549                 if (nvalues == 0) break;
00550                 value = va_arg(ap, pst_string);
00551             } while (!value.str);
00552             if (!nvalues || !value.str) break;
00553             space_flag = true;
00554         }
00555         else if (ch == '\r')
00556             continue;
00557         else if (ch == ' ') {
00558             space_flag = true;
00559             continue;
00560         }
00561         else {
00562             if (space_flag) {
00563                 if (i > 0) {
00564                     if (i < (len - 2)) cn[i++] = ' ';
00565                     else               break;
00566                 }
00567                 space_flag = false;
00568             }
00569             if (i < (len - 1)) cn[i++] = ch;
00570             else               break;
00571         }
00572     }
00573     cn[i] = 0;
00574     va_end(ap);
00575 }
00576 
00577 
00578 int main(int argc, char* const* argv) {
00579     pst_desc_ll *d_ptr;
00580     char *fname = NULL;
00581     int c;
00582     char *d_log = NULL;
00583     prog_name = argv[0];
00584     pst_item *item = NULL;
00585 
00586     while ((c = getopt(argc, argv, "b:c:d:l:oVh"))!= -1) {
00587         switch (c) {
00588         case 'b':
00589             ldap_base = optarg;
00590             break;
00591         case 'c':
00592             ldap_class.push_back(string(optarg));
00593             break;
00594         case 'd':
00595             d_log = optarg;
00596             break;
00597         case 'h':
00598             usage();
00599             exit(0);
00600             break;
00601         case 'l':
00602             ldif_extra_line.push_back(string(optarg));
00603             break;
00604         case 'o':
00605             old_schema = true;
00606             break;
00607         case 'V':
00608             version();
00609             exit(0);
00610             break;
00611         default:
00612             usage();
00613             exit(1);
00614             break;
00615         }
00616     }
00617 
00618     if ((argc > optind) && (ldap_base)) {
00619         fname = argv[optind];
00620     } else {
00621         usage();
00622         exit(2);
00623     }
00624 
00625     #ifdef DEBUG_ALL
00626         // force a log file
00627         if (!d_log) d_log = "pst2ldif.log";
00628     #endif
00629     DEBUG_INIT(d_log);
00630     DEBUG_REGISTER_CLOSE();
00631     DEBUG_ENT("main");
00632     RET_DERROR(pst_open(&pstfile, fname), 1, ("Error opening File\n"));
00633     RET_DERROR(pst_load_index(&pstfile), 2, ("Index Error\n"));
00634 
00635     pst_load_extended_attributes(&pstfile);
00636 
00637     d_ptr = pstfile.d_head; // first record is main record
00638     item  = (pst_item*)pst_parse_item(&pstfile, d_ptr, NULL);
00639     if (!item || !item->message_store) {
00640         DEBUG_RET();
00641         DIE(("main: Could not get root record\n"));
00642     }
00643 
00644     d_ptr = pst_getTopOfFolders(&pstfile, item);
00645     if (!d_ptr) {
00646         DEBUG_RET();
00647         DIE(("Top of folders record not found. Cannot continue\n"));
00648     }
00649 
00650     pst_freeItem(item);
00651 
00652     if (old_schema && (strlen(ldap_base) > 2)) {
00653         char *ldap_org = strdup(ldap_base+2); // assume first 2 chars are o=
00654         char *temp = strchr(ldap_org, ',');
00655         if (temp) {
00656             *temp = '\0';
00657             // write the ldap header
00658             printf("dn: %s\n", ldap_base);
00659             printf("o: %s\n", ldap_org);
00660             printf("objectClass: organization\n\n");
00661             printf("dn: cn=root, %s\n", ldap_base);
00662             printf("cn: root\n");
00663             printf("sn: root\n");
00664             for (vector<string>::size_type i=0; i<ldap_class.size(); i++)
00665                 print_ldif_single("objectClass", ldap_class[i].c_str());
00666             printf("\n");
00667         }
00668     }
00669 
00670     process(d_ptr->child);  // do the children of TOPF
00671     pst_close(&pstfile);
00672     DEBUG_RET();
00673     free_strings(all_strings);
00674     return 0;
00675 }
00676 
00677 
00678 void usage(void) {
00679     version();
00680     printf("Usage: %s [OPTIONS] {PST FILENAME}\n", prog_name);
00681     printf("OPTIONS:\n");
00682     printf("\t-V\t- Version. Display program version\n");
00683     printf("\t-b ldapbase\t- set the LDAP base value\n");
00684     printf("\t-c class\t- set the class of the LDAP objects (may contain more than one)\n");
00685     printf("\t-d <filename>\t- Debug to file. This is a binary log. Use readpstlog to print it\n");
00686     printf("\t-h\t- Help. This screen\n");
00687     printf("\t-l line\t- extra line to insert in the LDIF file for each contact\n");
00688     printf("\t-o\t- use old schema, default is new schema\n");
00689 }
00690 
00691 
00692 void version(void) {
00693     printf("pst2ldif v%s\n", VERSION);
00694 #if BYTE_ORDER == BIG_ENDIAN
00695     printf("Big Endian implementation being used.\n");
00696 #elif BYTE_ORDER == LITTLE_ENDIAN
00697     printf("Little Endian implementation being used.\n");
00698 #else
00699 #  error "Byte order not supported by this library"
00700 #endif
00701 #ifdef __GNUC__
00702     printf("GCC %d.%d : %s %s\n", __GNUC__, __GNUC_MINOR__, __DATE__, __TIME__);
00703 #endif
00704 }
00705 
00706 
00707 char *check_filename(char *fname) {
00708     char *t = fname;
00709     if (t == NULL) {
00710         return fname;
00711     }
00712     while ((t = strpbrk(t, "/\\:"))) {
00713         // while there are characters in the second string that we don't want
00714         *t = '_'; //replace them with an underscore
00715     }
00716     return fname;
00717 }
00718 
00719 
00720 // This function escapes Distinguished Names (as per RFC4514)
00721 void print_ldif_dn(const char *attr, pst_string value, const char *base)
00722 {
00723     printf("dn: cn=");
00724     const char *valuestr = value.str;
00725     // remove leading spaces (RFC says escape them)
00726     while (*valuestr == ' ')
00727         valuestr++;
00728 
00729     print_escaped_dn(valuestr);
00730     if (base && base[0]) {
00731         printf(", %s", base);
00732     }
00733     printf("\n");
00734     return;
00735 }
00736 
00737 
00738 void print_escaped_dn(const char *value)
00739 {
00740     char ch;
00741 
00742     // escape initial '#' and space
00743     if (*value == '#' || *value == ' ')
00744         putchar('\\');
00745 
00746     while ((ch = *value++) != 0) {
00747         if (((ch & 0x80) != 0) || (ch <= 0x1F))
00748             // Print as escaped hex digits
00749             printf("\\%2.2X", ch & 0xFF);
00750         else switch (ch) {
00751             case '\\':
00752             case '"' :
00753             case '+' :
00754             case ',' :
00755             case ';' :
00756             case '<' :
00757             case '>' :
00758                 putchar('\\');
00759                 // Fall through
00760             default:
00761                 putchar(ch);
00762         }
00763     }
00764     return;
00765 }

Generated on Thu Mar 19 16:39:26 2009 for 'LibPst' by  doxygen 1.3.9.1