Mercurial > hg > xemacs-beta
comparison src/eldap.c @ 278:90d73dddcdc4 r21-0b37
Import from CVS: tag r21-0b37
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:31:29 +0200 |
parents | 6330739388db |
children | 7df0dd720c89 |
comparison
equal
deleted
inserted
replaced
277:cfdf3ff11843 | 278:90d73dddcdc4 |
---|---|
29 - Netscape's LDAP SDK 1.0 (http://developer.netscape.com) */ | 29 - Netscape's LDAP SDK 1.0 (http://developer.netscape.com) */ |
30 | 30 |
31 | 31 |
32 #include <config.h> | 32 #include <config.h> |
33 #include "lisp.h" | 33 #include "lisp.h" |
34 #include "opaque.h" | |
34 | 35 |
35 #include <errno.h> | 36 #include <errno.h> |
36 #include <lber.h> | 37 #include <lber.h> |
37 #include <ldap.h> | 38 #include <ldap.h> |
38 | 39 |
127 | 128 |
128 if (print_readably) | 129 if (print_readably) |
129 error ("printing unreadable object #<ldap %s>", | 130 error ("printing unreadable object #<ldap %s>", |
130 XSTRING_DATA (ldap->host)); | 131 XSTRING_DATA (ldap->host)); |
131 | 132 |
132 if (!escapeflag) | 133 write_c_string ("#<ldap ", printcharfun); |
133 { | 134 print_internal (ldap->host, printcharfun, 1); |
134 print_internal (ldap->host, printcharfun, 0); | 135 write_c_string (" state:",printcharfun); |
135 } | 136 print_internal (ldap->status_symbol, printcharfun, 1); |
136 else | 137 sprintf (buf, " 0x%x>", ldap); |
137 { | 138 write_c_string (buf, printcharfun); |
138 write_c_string (GETTEXT ("#<ldap "), printcharfun); | |
139 print_internal (ldap->host, printcharfun, 1); | |
140 write_c_string (" state:",printcharfun); | |
141 print_internal (ldap->status_symbol, printcharfun, 1); | |
142 sprintf (buf, " 0x%x>", ldap); | |
143 write_c_string (buf, printcharfun); | |
144 } | |
145 } | 139 } |
146 | 140 |
147 static struct Lisp_LDAP * | 141 static struct Lisp_LDAP * |
148 allocate_ldap (void) | 142 allocate_ldap (void) |
149 { | 143 { |
225 { | 219 { |
226 /* This function can call lisp */ | 220 /* This function can call lisp */ |
227 | 221 |
228 struct Lisp_LDAP *lisp_ldap; | 222 struct Lisp_LDAP *lisp_ldap; |
229 LDAP *ld; | 223 LDAP *ld; |
230 int ldap_port = 0; | 224 int ldap_port = 0; |
231 int ldap_auth = LDAP_AUTH_SIMPLE; | 225 int ldap_auth = LDAP_AUTH_SIMPLE; |
232 char *ldap_binddn = NULL; | 226 char *ldap_binddn = NULL; |
233 char *ldap_passwd = NULL; | 227 char *ldap_passwd = NULL; |
234 int ldap_deref = LDAP_DEREF_NEVER; | 228 int ldap_deref = LDAP_DEREF_NEVER; |
235 int ldap_timelimit = 0; | 229 int ldap_timelimit = 0; |
236 int ldap_sizelimit = 0; | 230 int ldap_sizelimit = 0; |
237 int err; | 231 int err; |
238 | 232 |
239 Lisp_Object ldap, list, keyword, value; | 233 Lisp_Object ldap, list, keyword, value; |
240 struct gcpro gcpro1; | 234 struct gcpro gcpro1; |
241 | 235 |
242 ldap = Qnil; | 236 ldap = Qnil; |
388 | 382 |
389 | 383 |
390 /************************************************************************/ | 384 /************************************************************************/ |
391 /* Working on a LDAP connection */ | 385 /* Working on a LDAP connection */ |
392 /************************************************************************/ | 386 /************************************************************************/ |
387 struct ldap_unwind_struct | |
388 { | |
389 LDAPMessage *res; | |
390 char **vals; | |
391 }; | |
392 | |
393 | |
394 static Lisp_Object | |
395 ldap_search_unwind (Lisp_Object unwind_obj) | |
396 { | |
397 struct ldap_unwind_struct *unwind = | |
398 (struct ldap_unwind_struct *) get_opaque_ptr (unwind_obj); | |
399 if (unwind->res != (LDAPMessage *)NULL) | |
400 ldap_msgfree (unwind->res); | |
401 if (unwind->vals != (char **)NULL) | |
402 ldap_value_free (unwind->vals); | |
403 } | |
393 | 404 |
394 DEFUN ("ldap-search-internal", Fldap_search_internal, 2, 6, 0, /* | 405 DEFUN ("ldap-search-internal", Fldap_search_internal, 2, 6, 0, /* |
395 Perform a search on an open LDAP connection. | 406 Perform a search on an open LDAP connection. |
396 LDAP is an LDAP connection object created with `ldap-open'. | 407 LDAP is an LDAP connection object created with `ldap-open'. |
397 FILTER is a filter string for the search as described in RFC 1558 | 408 FILTER is a filter string for the search as described in RFC 1558 |
410 { | 421 { |
411 /* This function can call lisp */ | 422 /* This function can call lisp */ |
412 | 423 |
413 /* Vars for query */ | 424 /* Vars for query */ |
414 LDAP *ld; | 425 LDAP *ld; |
415 LDAPMessage *res, *e; | 426 LDAPMessage *e; |
416 BerElement *ptr; | 427 BerElement *ptr; |
417 char *a; | 428 char *a; |
418 int i, rc, err; | 429 int i, rc, err; |
419 | |
420 char **vals = NULL; | |
421 int matches; | 430 int matches; |
431 struct ldap_unwind_struct unwind; | |
422 | 432 |
423 int ldap_scope = LDAP_SCOPE_SUBTREE; | 433 int ldap_scope = LDAP_SCOPE_SUBTREE; |
424 char **ldap_attributes = NULL; | 434 char **ldap_attributes = NULL; |
425 | 435 |
436 int speccount = specpdl_depth (); | |
437 | |
426 Lisp_Object list, entry, result; | 438 Lisp_Object list, entry, result; |
427 struct gcpro gcpro1, gcpro2, gcpro3; | 439 struct gcpro gcpro1, gcpro2, gcpro3; |
428 | 440 |
429 list = entry = result = Qnil; | 441 list = entry = result = Qnil; |
430 GCPRO3(list, entry, result); | 442 GCPRO3(list, entry, result); |
443 | |
444 unwind.res = (LDAPMessage *)NULL; | |
445 unwind.vals = (char **)NULL; | |
431 | 446 |
432 /* Do all the parameter checking */ | 447 /* Do all the parameter checking */ |
433 CHECK_LIVE_LDAP (ldap); | 448 CHECK_LIVE_LDAP (ldap); |
434 ld = (XLDAP (ldap))->ld; | 449 ld = (XLDAP (ldap))->ld; |
435 | 450 |
461 } | 476 } |
462 | 477 |
463 /* Attributes to search */ | 478 /* Attributes to search */ |
464 if (!NILP (attrs)) | 479 if (!NILP (attrs)) |
465 { | 480 { |
466 Lisp_Object attr_left = attrs; | |
467 struct gcpro ngcpro1; | |
468 | |
469 NGCPRO1 (attr_left); | |
470 CHECK_CONS (attrs); | 481 CHECK_CONS (attrs); |
471 | 482 ldap_attributes = alloca_array (char *, 1 + XINT (Flength (attrs))); |
472 ldap_attributes = alloca ((XINT (Flength (attrs)) + 1)*sizeof (char *)); | 483 |
473 | 484 i = 0; |
474 for (i=0; !NILP (attr_left); i++) { | 485 EXTERNAL_LIST_LOOP (attrs, attrs) |
475 CHECK_STRING (XCAR (attr_left)); | 486 { |
476 ldap_attributes[i] = alloca (XSTRING_LENGTH (XCAR (attr_left)) + 1); | 487 Lisp_Object current = XCAR (attrs); |
477 strcpy(ldap_attributes[i], | 488 CHECK_STRING (current); |
478 (char *)(XSTRING_DATA( XCAR (attr_left)))); | 489 ldap_attributes[i] = |
479 attr_left = XCDR (attr_left); | 490 alloca_array (char, 1 + XSTRING_LENGTH (current)); |
480 } | 491 memcpy (ldap_attributes[i], |
492 XSTRING_DATA (current), XSTRING_LENGTH (current)); | |
493 ++i; | |
494 } | |
481 ldap_attributes[i] = NULL; | 495 ldap_attributes[i] = NULL; |
482 NUNGCPRO; | |
483 } | 496 } |
484 | 497 |
485 /* Attributes only ? */ | 498 /* Attributes only ? */ |
486 CHECK_SYMBOL (attrsonly); | 499 CHECK_SYMBOL (attrsonly); |
487 | 500 |
496 == -1) | 509 == -1) |
497 { | 510 { |
498 signal_ldap_error (ld); | 511 signal_ldap_error (ld); |
499 } | 512 } |
500 | 513 |
514 /* Ensure we don't exit without cleaning up */ | |
515 record_unwind_protect (ldap_search_unwind, | |
516 make_opaque_ptr (&unwind)); | |
517 | |
501 /* Build the results list */ | 518 /* Build the results list */ |
502 matches = 0; | 519 matches = 0; |
503 | 520 |
504 /* ldap_result calls select() and can get wedged by EINTR signals */ | 521 /* ldap_result calls select() and can get wedged by EINTR signals */ |
505 slow_down_interrupts (); | 522 slow_down_interrupts (); |
506 rc = ldap_result (ld, LDAP_RES_ANY, 0, NULL, &res); | 523 rc = ldap_result (ld, LDAP_RES_ANY, 0, NULL, &(unwind.res)); |
507 speed_up_interrupts (); | 524 speed_up_interrupts (); |
508 while ( rc == LDAP_RES_SEARCH_ENTRY ) | 525 while ( rc == LDAP_RES_SEARCH_ENTRY ) |
509 { | 526 { |
527 QUIT; | |
510 matches ++; | 528 matches ++; |
511 e = ldap_first_entry (ld, res); | 529 e = ldap_first_entry (ld, unwind.res); |
512 message ("Parsing results... %d", matches); | 530 message ("Parsing results... %d", matches); |
513 entry = Qnil; | 531 entry = Qnil; |
514 for (a= ldap_first_attribute (ld, e, &ptr); | 532 for (a= ldap_first_attribute (ld, e, &ptr); |
515 a != NULL; | 533 a != NULL; |
516 a= ldap_next_attribute (ld, e, ptr) ) | 534 a= ldap_next_attribute (ld, e, ptr) ) |
517 { | 535 { |
518 list = Fcons (build_string (a), Qnil); | 536 list = Fcons (build_string (a), Qnil); |
519 vals = ldap_get_values (ld, e, a); | 537 unwind.vals = ldap_get_values (ld, e, a); |
520 if (vals != NULL) | 538 if (unwind.vals != NULL) |
521 { | 539 { |
522 for (i=0; vals[i]!=NULL; i++) | 540 for (i=0; unwind.vals[i]!=NULL; i++) |
523 { | 541 { |
524 list = Fcons (build_string (vals[i]), | 542 list = Fcons (build_string (unwind.vals[i]), |
525 list); | 543 list); |
526 } | 544 } |
527 } | 545 } |
528 entry = Fcons (Fnreverse (list), | 546 entry = Fcons (Fnreverse (list), |
529 entry); | 547 entry); |
530 ldap_value_free (vals); | 548 ldap_value_free (unwind.vals); |
549 unwind.vals = (char **)NULL; | |
531 } | 550 } |
532 result = Fcons (Fnreverse (entry), | 551 result = Fcons (Fnreverse (entry), |
533 result); | 552 result); |
534 ldap_msgfree (res); | 553 ldap_msgfree (unwind.res); |
554 unwind.res = (LDAPMessage *)NULL; | |
535 | 555 |
536 slow_down_interrupts (); | 556 slow_down_interrupts (); |
537 rc = ldap_result (ld, LDAP_RES_ANY, 0, NULL, &res); | 557 rc = ldap_result (ld, LDAP_RES_ANY, 0, NULL, &(unwind.res)); |
538 speed_up_interrupts (); | 558 speed_up_interrupts (); |
539 } | 559 } |
540 | 560 |
541 if (rc == -1) | 561 if (rc == -1) |
542 { | 562 { |
543 signal_ldap_error (ld); | 563 signal_ldap_error (ld); |
544 } | 564 } |
545 | 565 |
546 if ((rc = ldap_result2error (ld, res, 0)) != LDAP_SUCCESS) | 566 if ((rc = ldap_result2error (ld, unwind.res, 0)) != LDAP_SUCCESS) |
547 { | 567 { |
548 signal_ldap_error (ld); | 568 signal_ldap_error (ld); |
549 } | 569 } |
550 | 570 |
551 ldap_msgfree (res); | 571 ldap_msgfree (unwind.res); |
572 unwind.res = (LDAPMessage *)NULL; | |
552 message ("Done."); | 573 message ("Done."); |
553 | 574 |
554 result = Fnreverse (result); | 575 result = Fnreverse (result); |
555 clear_message (); | 576 clear_message (); |
556 | 577 |
578 unbind_to (speccount, Qnil); | |
557 UNGCPRO; | 579 UNGCPRO; |
558 return result; | 580 return result; |
559 } | 581 } |
560 | 582 |
561 | 583 |