ber_free( ber, 0 );
        }
 }
-#else /* This is the proposed new way of doing things. */
+#else
+/* This is the proposed new way of doing things.
+ * It is more * efficient, but the API is non-standard.
+ */
 static void
 print_entry(
        LDAP    *ld,
        LDAPMessage     *entry,
        int             attrsonly)
 {
-       char            *ufn;
+       char            *ufn = NULL;
        char    tmpfname[ 256 ];
        char    url[ 256 ];
        int                     i, rc;
        BerElement              *ber = NULL;
-       struct berval   *bvals, bv;
+       struct berval           bv, *bvals, **bvp = &bvals;
        LDAPControl **ctrls = NULL;
        FILE            *tmpfp;
 
        rc = ldap_get_dn_ber( ld, entry, &ber, &bv );
-       ufn = NULL;
 
        if ( ldif < 2 ) {
                ufn = ldap_dn2ufn( bv.bv_val );
 
        if( ufn != NULL ) ldap_memfree( ufn );
 
-       for ( rc = ldap_get_attribute_ber( ld, entry, ber, &bv ); rc == LDAP_SUCCESS;
-               rc = ldap_get_attribute_ber( ld, entry, ber, &bv ) )
+       if ( attrsonly ) bvp = NULL;
+
+       for ( rc = ldap_get_attribute_ber( ld, entry, ber, &bv, bvp ); rc == LDAP_SUCCESS;
+               rc = ldap_get_attribute_ber( ld, entry, ber, &bv, bvp ) )
        {
                if (bv.bv_val == NULL) break;
 
                if ( attrsonly ) {
                        write_ldif( LDIF_PUT_NOVALUE, bv.bv_val, NULL, 0 );
-                       /* skip values */
-                       ber_scanf( ber, "x}" );
 
-               } else if (( rc = ldap_get_values_ber( ld, entry, ber, &bvals )) == LDAP_SUCCESS ) {
+               } else {
                        for ( i = 0; bvals[i].bv_val != NULL; i++ ) {
                                if ( vals2tmp > 1 || ( vals2tmp
                                        && ldif_is_not_printable( bvals[i].bv_val, bvals[i].bv_len ) ))
 
 
 LDAP_F( int )
 ldap_get_attribute_ber LDAP_P((
-       LDAP *ld, LDAPMessage *e, BerElement *ber, struct berval *attr ));
-
-LDAP_F( int )
-ldap_get_values_ber LDAP_P((
-       LDAP *ld, LDAPMessage *e, BerElement *ber, struct berval **bv ));
+       LDAP *ld, LDAPMessage *e, BerElement *ber, struct berval *attr,
+       struct berval **vals ));
 
 /*
  * in getattr.c
 
        return attr;
 }
 
+/* Fetch attribute type and optionally fetch values */
 /* ARGSUSED */
 int
 ldap_get_attribute_ber( LDAP *ld, LDAPMessage *entry, BerElement *ber,
-       BerValue *attr )
+       BerValue *attr, BerVarray *vals )
 {
        ber_tag_t tag;
        int rc = LDAP_SUCCESS;
 
        if ( ber_pvt_ber_remaining( ber ) ) {
                /* skip sequence, snarf attribute type */
-               tag = ber_scanf( ber, "{m", attr ); 
+               tag = ber_scanf( ber, vals ? "{mW}" : "{mx}", attr, vals ); 
                if( tag == LBER_ERROR ) {
                        rc = ld->ld_errno = LDAP_DECODING_ERROR;
                }
 
        return( vals );
 }
 
-int
-ldap_get_values_ber( LDAP *ld, LDAPMessage *entry, BerElement *ber, BerVarray *bv )
-{
-       int             rc = LDAP_SUCCESS;
-
-       assert( ld != NULL );
-       assert( LDAP_VALID( ld ) );
-       assert( entry != NULL );
-       assert( ber != NULL );
-       assert( bv != NULL );
-
-#ifdef NEW_LOGGING
-       LDAP_LOG ( OPERATION, ENTRY, "ldap_get_values_ber\n", 0, 0, 0 );
-#else
-       Debug( LDAP_DEBUG_TRACE, "ldap_get_values_ber\n", 0, 0, 0 );
-#endif
-
-       /* get the array of vals */
-       if ( ber_scanf( ber, "W}" /* }}} */, bv ) == LBER_ERROR ) {
-               rc = ld->ld_errno = LDAP_DECODING_ERROR;
-       }
-
-       return( rc );
-}
 int
 ldap_count_values( char **vals )
 {