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