diff --git a/c/ldap.c b/c/ldap.c index b13b6cd..22fd391 100644 --- a/c/ldap.c +++ b/c/ldap.c @@ -141,7 +141,8 @@ s48_value scsh_ldap_search_s(s48_value ldap, s48_value base, s48_extract_integer(scope), S48_FALSE_P(filter) ? NULL : s48_extract_string(filter), a, S48_TRUE_P(attrsonly), &msg); - free(a); + + free(a); /* FIXME: is this enough? */ res = s48_list_2(s48_enter_integer(r), r == LDAP_SUCCESS ? scsh_enter_ldapmessage(msg) : S48_FALSE); S48_GC_UNPROTECT(); @@ -171,7 +172,7 @@ s48_value scsh_ldap_search_st(s48_value ldap, s48_value base, s48_extract_integer(scope), S48_FALSE_P(filter) ? NULL : s48_extract_string(filter), a, S48_TRUE_P(attrsonly), &timeout, &msg); - free(a); + free(a); /* FIXME: is this enough? */ res = s48_list_2(s48_enter_integer(r), r == LDAP_SUCCESS ? scsh_enter_ldapmessage(msg) : S48_FALSE); S48_GC_UNPROTECT(); @@ -450,11 +451,15 @@ s48_value scsh_ldap_get_values(s48_value ldap, s48_value entry, s48_value scsh_ldap_modify(s48_value ldap, s48_value dn, s48_value mods) { int r; + LDAPMod **a; S48_DECLARE_GC_PROTECT(3); S48_GC_PROTECT_3(ldap, dn, mods); - r = ldap_modify_s(scsh_extract_ldap(ldap), s48_extract_string(dn), - scsh_extract_ldapmod_vector(mods)); + a = scsh_extract_ldapmod_list(mods); + r = ldap_modify_s(scsh_extract_ldap(ldap), + s48_extract_string(dn), + a); + scsh_free_ldapmod_array(a); S48_GC_UNPROTECT(); return s48_enter_integer(r); } @@ -462,14 +467,15 @@ s48_value scsh_ldap_modify(s48_value ldap, s48_value dn, s48_value mods) s48_value scsh_ldap_add(s48_value ldap, s48_value dn, s48_value mods) { int r; + LDAPMod **a; S48_DECLARE_GC_PROTECT(3); S48_GC_PROTECT_3(ldap, dn, mods); - if (!S48_VECTOR_P(mods)) - s48_raise_argument_type_error(mods); - - r = ldap_add_s(scsh_extract_ldap(ldap), s48_extract_string(dn), - scsh_extract_ldapmod_vector(mods)); + a = scsh_extract_ldapmod_list(mods); + r = ldap_add_s(scsh_extract_ldap(ldap), + s48_extract_string(dn), + a); + scsh_free_ldapmod_array(a); S48_GC_UNPROTECT(); return s48_enter_integer(r); } @@ -584,40 +590,58 @@ s48_value scsh_ldap_get_set_option(s48_value ldap, s48_value option, /* ************************************************************************ */ -/* FIXME: support modv_bvals (binary values) */ -s48_value scsh_ldapmod_create(s48_value op, s48_value type, s48_value data_vector) -{ +/* may GC, protect ldapmod */ +LDAPMod* scsh_create_ldapmod(s48_value ldapmod) +{ LDAPMod *m; - S48_DECLARE_GC_PROTECT(3); - - S48_GC_PROTECT_3(op, type, data_vector); + if ((m = (LDAPMod*) calloc(1, sizeof(LDAPMod))) == NULL) raise_ldap_memory_alloc_error(); - m->mod_op = s48_extract_integer(op); - m->mod_type = s48_extract_string(type); - m->mod_vals.modv_strvals = ffit_extract_list_of_strings(data_vector); + m->mod_op + = s48_extract_integer(S48_RECORD_REF(ldapmod, + SCSH_LDAP_MOD_RECFIELD_OP)); + m->mod_type + = s48_extract_string(S48_RECORD_REF(ldapmod, + SCSH_LDAP_MOD_RECFIELD_TYPE)); + m->mod_vals.modv_strvals + = ffit_extract_list_of_strings(S48_RECORD_REF(ldapmod, + SCSH_LDAP_MOD_RECFIELD_MODS)); - return scsh_enter_ldapmod(m); -} + return m; +} -LDAPMod** scsh_extract_ldapmod_vector(s48_value vector) +LDAPMod** scsh_extract_ldapmod_list(s48_value list) { LDAPMod **a; int l, i; - S48_DECLARE_GC_PROTECT(1); + s48_value e; + S48_DECLARE_GC_PROTECT(2); - S48_GC_PROTECT_1(vector); - l = S48_VECTOR_LENGTH(vector); - if ((*a = (LDAPMod *) calloc(l+1, sizeof(LDAPMod*))) == NULL) - raise_ldap_memory_alloc_error(); - for (i = 0; i < l; i++) - a[i] = scsh_extract_ldapmod(S48_VECTOR_REF(vector, i)); + S48_GC_PROTECT_2(list, e); + l = length_scheme_list(list); + + if ((a = (LDAPMod **) calloc(l + 1, sizeof(LDAPMod *))) == NULL) + s48_raise_out_of_memory_error(); a[l] = NULL; + + for (e = list, i = 0; e != NULL; e = S48_CDR(e), i++) + a[i] = scsh_create_ldapmod(S48_CAR(e)); + S48_GC_UNPROTECT(); return a; } +void scsh_free_ldapmod_array(LDAPMod **a) +{ + int i; + LDAPMod *e; + + for (e = a[0], i = 0; e != NULL; e = a[++i]) + ldap_memfree(e); + free(a); +} + void raise_ldap_memory_alloc_error(void) { s48_raise_scheme_exception(condition_ldap_memory_alloc_error, 0); @@ -701,5 +725,4 @@ void scsh_init_ldap_bindings(void) S48_EXPORT_FUNCTION(scsh_ldap_delete); S48_EXPORT_FUNCTION(scsh_ldap_abandon); S48_EXPORT_FUNCTION(scsh_ldap_get_set_option); - S48_EXPORT_FUNCTION(scsh_ldapmod_create); }