]> git.sur5r.net Git - openldap/commitdiff
Initial implementation of ldap_int_get_controls()... EXPERIMENTAL.
authorKurt Zeilenga <kurt@openldap.org>
Fri, 28 May 1999 02:15:57 +0000 (02:15 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Fri, 28 May 1999 02:15:57 +0000 (02:15 +0000)
libraries/libldap/controls.c

index 1043d99ca100a4c542ee9cedaa18450de81b7804..e0fe87b1e74e962b7324dc5a7431909edfc4239c 100644 (file)
@@ -100,15 +100,113 @@ int ldap_int_put_controls(
 }
 
 int ldap_int_get_controls LDAP_P((
-       BerElement *be,
+       BerElement *ber,
        LDAPControl ***ctrls ))
 {
-       assert( be != NULL );
+       int nctrls;
+       unsigned long tag, len;
+       char *opaque;
+
+       assert( ber != NULL );
        assert( ctrls != NULL );
 
-       **ctrls = NULL;
+       *ctrls = NULL;
+
+       len = ber->ber_end - ber->ber_ptr;
+
+       if( len == 0) {
+               /* no controls */
+               return LDAP_SUCCESS;
+       }
+
+       if(( tag = ber_peek_tag( ber, &len )) != LDAP_TAG_CONTROLS ) {
+               if( tag == LBER_ERROR ) {
+                       /* decoding error */
+                       return LDAP_DECODING_ERROR;
+               }
+
+               /* ignore unexpected input */
+               return LDAP_SUCCESS;
+       }
+
+       /* set through each element */
+       nctrls = 0;
+       *ctrls = malloc( 1 * sizeof(LDAPControl *) );
+
+       if( *ctrls == NULL ) {
+               return LDAP_NO_MEMORY;
+       }
+
+       ctrls[nctrls] = NULL;
+
+       for( tag = ber_first_element( ber, &len, &opaque );
+               (
+                       tag != LBER_ERROR
+#ifdef LDAP_END_SEQORSET
+                       && tag != LBER_END_OF_SEQORSET
+#endif
+               );
+               tag = ber_next_element( ber, &len, opaque ) )
+       {
+               LDAPControl *tctrl;
+               LDAPControl **tctrls;
+
+               tctrl = calloc( 1, sizeof(LDAPControl) );
+
+               /* allocate pointer space for current controls (nctrls)
+                * + this control + extra NULL
+                */
+               tctrls = (tctrl == NULL) ? NULL :
+                       realloc(*ctrls, (nctrls+2) * sizeof(LDAPControl *));
+
+               if( tctrls == NULL ) {
+                       /* one of the above allocation failed */
+
+                       if( tctrl != NULL ) {
+                               free( tctrl );
+                       }
 
-       return LDAP_NOT_SUPPORTED;
+                       ldap_controls_free(*ctrls);
+                       *ctrls = NULL;
+
+                       return LDAP_NO_MEMORY;
+               }
+
+
+               tctrls[nctrls++] = tctrl;
+               tctrls[nctrls] = NULL;
+
+               tag = ber_scanf( ber, "{a", &tctrl->ldctl_oid );
+
+               if( tag != LBER_ERROR ) {
+                       tag = ber_peek_tag( ber, &len );
+               }
+
+               if( tag == LBER_BOOLEAN ) {
+                       tag = ber_scanf( ber, "b", &tctrl->ldctl_iscritical );
+               }
+
+               if( tag != LBER_ERROR ) {
+                       tag = ber_peek_tag( ber, &len );
+               }
+
+               if( tag == LBER_OCTETSTRING ) {
+                       tag = ber_scanf( ber, "o", &tctrl->ldctl_value );
+
+               } else {
+                       tctrl->ldctl_value.bv_val = NULL;
+               }
+
+               if( tag == LBER_ERROR ) {
+                       *ctrls = NULL;
+                       ldap_controls_free( tctrls );
+                       return LDAP_DECODING_ERROR;
+               }
+
+               *ctrls = tctrls;
+       }
+               
+       return LDAP_SUCCESS;
 }
 
 /*
@@ -241,4 +339,4 @@ LDAPControl *ldap_control_dup( const LDAPControl *c )
 
        new->ldctl_iscritical = c->ldctl_iscritical;
        return new;
-}
\ No newline at end of file
+}