From 9a5978695b0a8abe5ff84e44aedc9fe433428fc3 Mon Sep 17 00:00:00 2001 From: eknauel Date: Wed, 14 Jan 2004 09:12:07 +0000 Subject: [PATCH] + added Scheme representation for BerElement + added bindings for ldap_first_attribute() and ldap_next_attribute() + fixed GC protection and handling of return codes for ldap_get_dn() and ldap_explode_dn() --- c/ldap.c | 83 ++++++++++++++++++++++++++++++++++++++++++++------- c/scsh-ldap.h | 8 +++++ 2 files changed, 80 insertions(+), 11 deletions(-) diff --git a/c/ldap.c b/c/ldap.c index 24f3c24..649431b 100644 --- a/c/ldap.c +++ b/c/ldap.c @@ -36,6 +36,9 @@ FFIT_STRUCT_GET(scsh_ldapapiinfo_get_extensions, scsh_ldapapiinfo_record_type, LDAPAPIInfo*, ldapai_extensions, ffit_enter_string_array); +FFIT_MAKE_ENTER_RECORD(scsh_enter_berelement, scsh_berelement_record_type, + BerElement *); + s48_value scsh_ldap_init(s48_value host, s48_value port) { LDAP *ldap; @@ -45,7 +48,7 @@ s48_value scsh_ldap_init(s48_value host, s48_value port) ldap = ldap_init(s48_extract_string(host), s48_extract_integer(port)); S48_GC_UNPROTECT(); if (ldap == NULL) - s48_raise_os_error(error()); + s48_raise_os_error(errno); else scsh_enter_ldap(ldap); } @@ -110,6 +113,17 @@ s48_value scsh_ldap_msgfree(s48_value ldapmsg) return S48_UNSPECIFIC; } +s48_value scsh_ldap_ber_free(s48_value ber, s48_value sfbuf) +{ + int fbuf; + S48_DECLARE_GC_PROTECT(2); + + S48_GC_PROTECT_2(ber, sfbuf); + fbuf = s48_extract_integer(sfbuf); + S48_GC_UNPROTECT(); + ber_free(scsh_extract_berelement(ber), fbuf); +} + s48_value scsh_ldap_search_s(s48_value ldap, s48_value base, s48_value scope, s48_value filter, s48_value attrs, s48_value attrsonly) @@ -199,7 +213,7 @@ s48_value scsh_ldap_count_entries(s48_value ldap, s48_value lm) r = ldap_count_entries(scsh_extract_ldap(ldap), scsh_extract_ldapmessage(lm)); S48_GC_UNPROTECT(); - return r; + return (r == -1) ? S48_FALSE : s48_enter_integer(r); } s48_value scsh_ldap_first_entry(s48_value ldap, s48_value lm) @@ -316,13 +330,51 @@ s48_value scsh_ldap_count_references(s48_value ldap, s48_value lm) return (c == -1) ? S48_FALSE : s48_enter_integer(c); } +s48_value scsh_ldap_first_attribute(s48_value ldap, s48_value entry) +{ + BerElement *ber; + char *name; + s48_value res_list = S48_FALSE; + S48_DECLARE_GC_PROTECT(3); + + S48_GC_PROTECT_3(ldap, entry, res_list); + if ((ber = ber_alloc_t(LBER_USE_DER)) == NULL) + raise_ldap_memory_alloc_error(); + + name = ldap_first_attribute(scsh_extract_ldap(ldap), + scsh_extract_ldapmessage(entry), + &ber); + if (name == NULL) + res_list = s48_list_2(S48_FALSE, S48_FALSE); + else + res_list = s48_list_2(s48_enter_string(name), + scsh_enter_berelement(ber)); + S48_GC_UNPROTECT(); + return res_list; +} + +s48_value scsh_ldap_next_attribute(s48_value ldap, s48_value entry, s48_value ber) +{ + char *name; + s48_value res; + S48_DECLARE_GC_PROTECT(4); + + S48_GC_PROTECT_4(ldap, entry, ber, res); + name = ldap_next_attribute(scsh_extract_ldap(ldap), + scsh_extract_ldapmessage(entry), + scsh_extract_berelement(ber)); + res = (name == NULL) ? s48_enter_string(name) : S48_FALSE; + S48_GC_UNPROTECT(); + return res; +} + s48_value scsh_ldap_msgtype(s48_value lm) { int r; FFIT_CHECK_RECORD_TYPE(lm, scsh_ldapmessage_record_type); r = ldap_msgtype(scsh_extract_ldapmessage(lm)); - return s48_enter_integer(r); + return (r == -1) ? S48_FALSE : s48_enter_integer(r); } s48_value scsh_ldap_msgid(s48_value lm) @@ -331,21 +383,24 @@ s48_value scsh_ldap_msgid(s48_value lm) FFIT_CHECK_RECORD_TYPE(lm, scsh_ldapmessage_record_type); r = ldap_msgid(scsh_extract_ldapmessage(lm)); - return s48_enter_integer(r); + return (r == -1) ? S48_FALSE : s48_enter_integer(r); } /* may raise ldap error */ s48_value scsh_ldap_get_dn(s48_value ldap, s48_value entry) { char *s; - S48_DECLARE_GC_PROTECT(2); + s48_value res; + S48_DECLARE_GC_PROTECT(3); - S48_GC_PROTECT_2(ldap, entry); + S48_GC_PROTECT_3(ldap, entry, res); FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type); FFIT_CHECK_RECORD_TYPE(entry, scsh_ldapmessage_record_type); s = ldap_get_dn(scsh_extract_ldap(ldap), scsh_extract_ldapmessage(entry)); + res = (s == NULL) ? S48_FALSE : s48_enter_string(s); S48_GC_UNPROTECT(); - return (s == NULL) ? S48_FALSE : s48_enter_string(s); + ldap_memfree(s); + return res; } s48_value scsh_ldap_explode_dn(s48_value dn, s48_value notypes) @@ -396,7 +451,7 @@ s48_value scsh_ldap_get_values(s48_value ldap, s48_value entry, s48_value attr) { char **val; - s48_value res = S48_FALSE; + s48_value res; S48_DECLARE_GC_PROTECT(4); S48_GC_PROTECT_4(ldap, entry, attr, res); @@ -406,8 +461,9 @@ s48_value scsh_ldap_get_values(s48_value ldap, s48_value entry, val = ldap_get_values(scsh_extract_ldap(ldap), scsh_extract_ldapmessage(entry), s48_extract_string(attr)); - res = ffit_enter_string_array(val); - ldap_value_free(val); + res = (val == NULL) ? S48_FALSE : ffit_enter_string_array(val); + if (val != NULL) + ldap_value_free(val); S48_GC_UNPROTECT(); return res; } @@ -474,7 +530,7 @@ s48_value scsh_ldap_get_set_option(s48_value ldap, s48_value option, s48_value res, res_list; S48_DECLARE_GC_PROTECT(6); - S48_GC_PROTECT(ldap, option, set, inval, res, res_list); + S48_GC_PROTECT_6(ldap, option, set, inval, res, res_list); FFIT_CHECK_RECORD_TYPE(ldap, scsh_ldap_record_type); FFIT_CHECK_BOOLEAN(set); ld = scsh_extract_ldap(ldap); @@ -625,6 +681,8 @@ void scsh_init_ldap_bindings(void) S48_EXPORT_FUNCTION(scsh_ldapapiinfo_get_vendor_version); S48_EXPORT_FUNCTION(scsh_ldapapiinfo_get_extensions); + FFIT_RECORD_TYPE_INIT(scsh_berelement_record_type, ber-element); + S48_EXPORT_FUNCTION(scsh_ldap_init); S48_EXPORT_FUNCTION(scsh_ldap_simple_bind_s); S48_EXPORT_FUNCTION(scsh_ldap_sasl_bind_s); @@ -633,6 +691,7 @@ void scsh_init_ldap_bindings(void) S48_EXPORT_FUNCTION(scsh_ldap_result_error); S48_EXPORT_FUNCTION(scsh_ldap_memfree); S48_EXPORT_FUNCTION(scsh_ldap_msgfree); + S48_EXPORT_FUNCTION(scsh_ldap_ber_free); S48_EXPORT_FUNCTION(scsh_ldap_search_s); S48_EXPORT_FUNCTION(scsh_ldap_search_st); S48_EXPORT_FUNCTION(scsh_ldap_compare_s); @@ -645,6 +704,8 @@ void scsh_init_ldap_bindings(void) S48_EXPORT_FUNCTION(scsh_ldap_first_reference); S48_EXPORT_FUNCTION(scsh_ldap_next_reference); S48_EXPORT_FUNCTION(scsh_ldap_count_references); + S48_EXPORT_FUNCTION(scsh_ldap_first_attribute); + S48_EXPORT_FUNCTION(scsh_ldap_next_attribute); S48_EXPORT_FUNCTION(scsh_ldap_msgtype); S48_EXPORT_FUNCTION(scsh_ldap_msgid); S48_EXPORT_FUNCTION(scsh_ldap_get_dn); diff --git a/c/scsh-ldap.h b/c/scsh-ldap.h index 41e8efe..f78f815 100644 --- a/c/scsh-ldap.h +++ b/c/scsh-ldap.h @@ -13,15 +13,18 @@ # endif #endif +#include "errno.h" #include "scheme48.h" #include "ffi-tools/ffi-tools.h" #include +#include static s48_value scsh_ldap_record_type = S48_FALSE; static s48_value scsh_ldapmessage_record_type = S48_FALSE; static s48_value scsh_ldapmod_record_type = S48_FALSE; static s48_value scsh_ldapapiinfo_record_type = S48_FALSE; +static s48_value scsh_berelement_record_type = S48_FALSE; FFIT_MAKE_ENTER_RECORD_PROTOTYPE(scsh_enter_ldap, LDAP*); #define scsh_extract_ldap(x) \ @@ -43,6 +46,11 @@ FFIT_MAKE_ENTER_RECORD_PROTOTYPE(scsh_enter_ldapapiinfo, LDAPAPIInfo*); ((LDAPAPIInfo *) \ s48_extract_integer(S48_RECORD_REF(x, 0))) +FFIT_MAKE_ENTER_RECORD_PROTOTYPE(scsh_enter_berelement, BerElement*); +#define scsh_extract_berelement(x) \ + ((BerElement *) \ + s48_extract_integer(S48_RECORD_REF(x, 0))) + /* conditions */ static s48_value condition_ldap_memory_alloc_error = S48_FALSE; static s48_value condition_ldap_feature_not_supported = S48_FALSE;