00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 using namespace std;
00012
00013
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;
00039 int ldif_extra_line_count = 0;
00040 vector<string> ldap_class;
00041 vector<string> ldif_extra_line;
00042
00043
00045
00046 struct ltstr {
00047 bool operator()(const char* s1, const char* s2) const {
00048 return strcasecmp(s1, s2) < 0;
00049 }
00050 };
00051
00052 typedef set<const char *, ltstr> string_set;
00053
00054 static string_set all_strings;
00055
00056
00058
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
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
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
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
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
00126 char cn[1000];
00127
00128
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
00177 pst_string ucn;
00178 ucn.str = (char*)unique_string(cn);
00179 ucn.is_utf8 = 1;
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);
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
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
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
00365
00366
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
00374 while (*value == ' ') value++;
00375 len = strlen(value) + 1;
00376 vector<char> buffer(len);
00377 char *p = &buffer[0];
00378
00379
00380
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
00418
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;
00425 int len = 0;
00426 int i = 0;
00427 va_list ap;
00428
00429 va_start(ap, value);
00430 while (!value.str) {
00431 nvalues--;
00432 if (nvalues == 0) {
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);
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;
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;
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
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;
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);
00656 char *temp = strchr(ldap_org, ',');
00657 if (temp) {
00658 *temp = '\0';
00659
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);
00671 }
00672
00673 process(d_ptr->child);
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
00714 *t = '_';
00715 }
00716 return fname;
00717 }
00718
00719
00720
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
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
00743 if (*value == '#' || *value == ' ')
00744 putchar('\\');
00745
00746 while ((ch = *value++) != 0) {
00747 if (((ch & 0x80) != 0) || (ch <= 0x1F))
00748
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
00760 default:
00761 putchar(ch);
00762 }
00763 }
00764 return;
00765 }