diff -uNr ruby-ldap-0.8.3.orig/conn.c ruby-ldap-0.8.3/conn.c --- ruby-ldap-0.8.3.orig/conn.c 2004-02-16 03:55:41.000000000 -0800 +++ ruby-ldap-0.8.3/conn.c 2004-11-13 01:05:26.434285432 -0800 @@ -9,6 +9,7 @@ #include static VALUE rb_ldap_sort_obj = Qnil; +extern VALUE rb_ldap_control_new2(LDAPControl *ctl); VALUE rb_cLDAP_Conn; @@ -358,6 +359,11 @@ /* optdata = (void*)rb_ldap_get_apiinfo(data); */ break; #endif +#ifdef LDAP_OPT_SERVER_CONTROLS + case LDAP_OPT_SERVER_CONTROLS: + optdata = rb_ldap_get_controls(data); + break; +#endif default: rb_notimplement(); } @@ -709,18 +715,59 @@ } VALUE +rb_ldap_parse_result(LDAP *cldap, LDAPMessage *cmsg) +{ + int rc, err, i; + char **referrals; + LDAPControl **serverctrls; + VALUE refs, ctls, ary; + + refs = rb_ary_new(); + ctls = rb_ary_new(); + ary = rb_ary_new(); + + rc = ldap_parse_result(cldap, cmsg, &err, NULL, NULL, + &referrals, &serverctrls, 0); + Check_LDAP_Result(rc); + Check_LDAP_Result(err); + + if( referrals ) { + for( i=0; referrals[i]; i++ ){ + rb_ary_push(refs, rb_str_new2(referrals[i])); + } + } + + if( serverctrls ) { + for( i=0; serverctrls[i]; i++ ){ + rb_ary_push(ctls, rb_ldap_control_new2(serverctrls[i])); + } + } + + rb_ary_push(ary, refs); + rb_ary_push(ary, ctls); + + return ary; +} + +VALUE rb_ldap_conn_search_s(int argc, VALUE argv[], VALUE self) { RB_LDAP_DATA *ldapdata; LDAPMessage *cmsg; LDAP *cldap; LDAPMessage *e; + VALUE rc_ary = Qnil; rb_ldap_conn_search_i(argc, argv, self, &ldapdata, &cmsg); cldap = ldapdata->ldap; if( ldapdata->err == LDAP_SUCCESS ){ void *pass_data[] = {(void*)cldap, (void*)cmsg}; + + rc_ary = rb_ldap_parse_result(cldap, cmsg); + rb_iv_set(self, "@referrals", rb_ary_shift(rc_ary)); + rb_iv_set(self, "@controls", rb_ary_shift(rc_ary)); + rb_ensure(rb_ldap_conn_search_b, (VALUE)pass_data, rb_ldap_msgfree, (VALUE)cmsg); }; @@ -758,6 +805,7 @@ LDAPMessage *e; LDAP *cldap; VALUE ary = Qnil; + VALUE rc_ary = Qnil; rb_ldap_conn_search_i(argc, argv, self, &ldapdata, &cmsg); cldap = ldapdata->ldap; @@ -765,6 +813,11 @@ ary = rb_ary_new(); if( ldapdata->err == LDAP_SUCCESS ){ void *pass_data[] = {(void*)cldap, (void*)cmsg, (void*)ary}; + + rc_ary = rb_ldap_parse_result(cldap, cmsg); + rb_iv_set(self, "@referrals", rb_ary_shift(rc_ary)); + rb_iv_set(self, "@controls", rb_ary_shift(rc_ary)); + rb_ensure(rb_ldap_conn_search2_b, (VALUE)pass_data, rb_ldap_msgfree, (VALUE)cmsg); } @@ -1206,6 +1259,8 @@ rb_ldap_sort_obj = Qnil; rb_cLDAP_Conn = rb_define_class_under(rb_mLDAP,"Conn",rb_cData); + rb_define_attr(rb_cLDAP_Conn, "referrals", 1, 0); + rb_define_attr(rb_cLDAP_Conn, "controls", 1, 0); #if RUBY_VERSION_CODE < 170 rb_define_singleton_method(rb_cLDAP_Conn,"new",rb_ldap_class_new,-1); #endif diff -uNr ruby-ldap-0.8.3.orig/ldap.c ruby-ldap-0.8.3/ldap.c --- ruby-ldap-0.8.3.orig/ldap.c 2003-11-15 20:55:14.000000000 -0800 +++ ruby-ldap-0.8.3/ldap.c 2004-11-13 01:01:38.245975328 -0800 @@ -479,6 +479,11 @@ #endif #undef rb_ldap_define_auth_method +#ifdef LDAP_CONTROL_PAGEDRESULTS + rb_define_const(rb_mLDAP,"LDAP_CONTROL_PAGEDRESULTS", + rb_str_new2(LDAP_CONTROL_PAGEDRESULTS)); +#endif + #define rb_ldap_define_const(c) rb_define_const(rb_mLDAP,#c,INT2NUM(c)) rb_ldap_define_const(LDAP_MOD_ADD); rb_ldap_define_const(LDAP_MOD_DELETE); diff -uNr ruby-ldap-0.8.3.orig/misc.c ruby-ldap-0.8.3/misc.c --- ruby-ldap-0.8.3.orig/misc.c 2004-11-13 01:09:31.213073400 -0800 +++ ruby-ldap-0.8.3/misc.c 2004-11-13 01:01:38.246975176 -0800 @@ -94,6 +94,40 @@ } } +/* Identical to rb_ldap_control_new, but does not define a routine with which + to free memory. This should be called only by rb_ldap_parse_result(). + */ +VALUE +rb_ldap_control_new2(LDAPControl *ctl) +{ + int len; + VALUE val, oid, critical; + + if( !ctl ){ + return Qnil; + } + else{ + return Data_Wrap_Struct(rb_cLDAP_Control, 0, 0, ctl); + } +} + +/* This is called by #initialize_copy and is using for duping/cloning. */ +VALUE +rb_ldap_control_copy(VALUE copy, VALUE orig) +{ + LDAPControl *orig_ctl, *copy_ctl; + + /* + rb_raise(rb_eTypeError, "can't dup/clone LDAP::Control class"); + */ + + Data_Get_Struct(orig, LDAPControl, orig_ctl); + Data_Get_Struct(copy, LDAPControl, copy_ctl); + memcpy(copy_ctl, orig_ctl, (size_t)sizeof(LDAPControl)); + + return copy; +} + static VALUE rb_ldap_control_s_allocate(VALUE klass) { @@ -382,6 +416,7 @@ rb_ldap_control_s_new, -1); #endif rb_define_method(rb_cLDAP_Control, "initialize", rb_ldap_control_initialize, -1); + rb_define_method(rb_cLDAP_Control, "initialize_copy", rb_ldap_control_copy, 1); rb_define_method(rb_cLDAP_Control, "inspect", rb_ldap_control_inspect, 0); rb_define_method(rb_cLDAP_Control, "oid", rb_ldap_control_oid, -1); rb_define_method(rb_cLDAP_Control, "oid=", rb_ldap_control_oid, -1);