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 address = (char *)realloc(address, len);
00467 }
00468 if (newline_flag) {
00469 address[i++] = '$';
00470 newline_flag = false;
00471 space_flag = false;
00472 }
00473 else if (space_flag) {
00474 address[i++] = ' ';
00475 space_flag = false;
00476 }
00477 if (ch == '$' || ch == '\\') address[i++] = '\\';
00478 address[i++] = ch;
00479 }
00480 }
00481 va_end(ap);
00482 if (i == 0) return;
00483 address[i] = 0;
00484 print_ldif_single(attr, address);
00485 free(address);
00486 DEBUG_RET();
00487 }
00488
00489
00490 void print_ldif_multi(const char *dn, pst_string value)
00491 {
00492 char *n;
00493 char *valuestr = value.str;
00494 while ((n = strchr(valuestr, '\n'))) {
00495 print_ldif_single(dn, valuestr);
00496 valuestr = n + 1;
00497 }
00498 print_ldif_single(dn, valuestr);
00499 }
00500
00501
00502 void print_ldif_two(const char *attr, pst_string value1, pst_string value2)
00503 {
00504 size_t len1, len2;
00505 if (value1.str && *value1.str)
00506 len1 = strlen(value1.str);
00507 else {
00508 print_ldif_single(attr, value2);
00509 return;
00510 }
00511
00512 if (value2.str && *value2.str)
00513 len2 = strlen(value2.str);
00514 else {
00515 print_ldif_single(attr, value1);
00516 return;
00517 }
00518
00519 vector<char> value(len1 + len2 + 2);
00520 memcpy(&value[0], value1.str, len1);
00521 value[len1] = ' ';
00522 memcpy(&value[0] + len1 + 1, value2.str, len2 + 1);
00523 print_ldif_single(attr, &value[0]);
00524 }
00525
00526
00527 void build_cn(char *cn, size_t len, int nvalues, pst_string value, ...)
00528 {
00529 bool space_flag = false;
00530 size_t i = 0;
00531 va_list ap;
00532
00533 va_start(ap, value);
00534
00535 while (!value.str) {
00536 nvalues--;
00537 if (nvalues == 0) {
00538 cn[0] = 0;
00539 va_end(ap);
00540 return;
00541 }
00542 value = va_arg(ap, pst_string);
00543 }
00544 for (;;) {
00545 char ch = *(value.str)++;
00546
00547 if (ch == 0 || ch == '\n') {
00548 do {
00549 nvalues--;
00550 if (nvalues == 0) break;
00551 value = va_arg(ap, pst_string);
00552 } while (!value.str);
00553 if (!nvalues || !value.str) break;
00554 space_flag = true;
00555 }
00556 else if (ch == '\r')
00557 continue;
00558 else if (ch == ' ') {
00559 space_flag = true;
00560 continue;
00561 }
00562 else {
00563 if (space_flag) {
00564 if (i > 0) {
00565 if (i < (len - 2)) cn[i++] = ' ';
00566 else break;
00567 }
00568 space_flag = false;
00569 }
00570 if (i < (len - 1)) cn[i++] = ch;
00571 else break;
00572 }
00573 }
00574 cn[i] = 0;
00575 va_end(ap);
00576 }
00577
00578
00579 int main(int argc, char* const* argv) {
00580 pst_desc_tree *d_ptr;
00581 char *fname = NULL;
00582 int c;
00583 char *d_log = NULL;
00584 prog_name = argv[0];
00585 pst_item *item = NULL;
00586
00587 while ((c = getopt(argc, argv, "b:c:d:l:oVh"))!= -1) {
00588 switch (c) {
00589 case 'b':
00590 ldap_base = optarg;
00591 break;
00592 case 'c':
00593 ldap_class.push_back(string(optarg));
00594 break;
00595 case 'd':
00596 d_log = optarg;
00597 break;
00598 case 'h':
00599 usage();
00600 exit(0);
00601 break;
00602 case 'l':
00603 ldif_extra_line.push_back(string(optarg));
00604 break;
00605 case 'o':
00606 old_schema = true;
00607 break;
00608 case 'V':
00609 version();
00610 exit(0);
00611 break;
00612 default:
00613 usage();
00614 exit(1);
00615 break;
00616 }
00617 }
00618
00619 if ((argc > optind) && (ldap_base)) {
00620 fname = argv[optind];
00621 } else {
00622 usage();
00623 exit(2);
00624 }
00625
00626 #ifdef DEBUG_ALL
00627
00628 if (!d_log) d_log = "pst2ldif.log";
00629 #endif
00630 DEBUG_INIT(d_log, NULL);
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;
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);
00654 char *temp = strchr(ldap_org, ',');
00655 if (temp) {
00656 *temp = '\0';
00657
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 free(ldap_org);
00669 }
00670
00671 process(d_ptr->child);
00672 pst_close(&pstfile);
00673 DEBUG_RET();
00674 free_strings(all_strings);
00675 return 0;
00676 }
00677
00678
00679 void usage(void) {
00680 version();
00681 printf("Usage: %s [OPTIONS] {PST FILENAME}\n", prog_name);
00682 printf("OPTIONS:\n");
00683 printf("\t-V\t- Version. Display program version\n");
00684 printf("\t-b ldapbase\t- set the LDAP base value\n");
00685 printf("\t-c class\t- set the class of the LDAP objects (may contain more than one)\n");
00686 printf("\t-d <filename>\t- Debug to file.\n");
00687 printf("\t-h\t- Help. This screen\n");
00688 printf("\t-l line\t- extra line to insert in the LDIF file for each contact\n");
00689 printf("\t-o\t- use old schema, default is new schema\n");
00690 }
00691
00692
00693 void version(void) {
00694 printf("pst2ldif v%s\n", VERSION);
00695 #if BYTE_ORDER == BIG_ENDIAN
00696 printf("Big Endian implementation being used.\n");
00697 #elif BYTE_ORDER == LITTLE_ENDIAN
00698 printf("Little Endian implementation being used.\n");
00699 #else
00700 # error "Byte order not supported by this library"
00701 #endif
00702 #ifdef __GNUC__
00703 printf("GCC %d.%d : %s %s\n", __GNUC__, __GNUC_MINOR__, __DATE__, __TIME__);
00704 #endif
00705 }
00706
00707
00708 char *check_filename(char *fname) {
00709 char *t = fname;
00710 if (t == NULL) {
00711 return fname;
00712 }
00713 while ((t = strpbrk(t, "/\\:"))) {
00714
00715 *t = '_';
00716 }
00717 return fname;
00718 }
00719
00720
00721
00722 void print_ldif_dn(const char *attr, pst_string value, const char *base)
00723 {
00724 printf("dn: cn=");
00725 const char *valuestr = value.str;
00726
00727 while (*valuestr == ' ')
00728 valuestr++;
00729
00730 print_escaped_dn(valuestr);
00731 if (base && base[0]) {
00732 printf(", %s", base);
00733 }
00734 printf("\n");
00735 return;
00736 }
00737
00738
00739 void print_escaped_dn(const char *value)
00740 {
00741 char ch;
00742
00743
00744 if (*value == '#' || *value == ' ')
00745 putchar('\\');
00746
00747 while ((ch = *value++) != 0) {
00748 if (((ch & 0x80) != 0) || (ch <= 0x1F))
00749
00750 printf("\\%2.2X", ch & 0xFF);
00751 else switch (ch) {
00752 case '\\':
00753 case '"' :
00754 case '+' :
00755 case ',' :
00756 case ';' :
00757 case '<' :
00758 case '>' :
00759 putchar('\\');
00760
00761 default:
00762 putchar(ch);
00763 }
00764 }
00765 return;
00766 }