- *next++ = ')';
-
- /* flush explicit tagged thang */
- if ( ber_printf( ber, "}" ) == -1 )
- return( NULL );
-/*
- if ( !not && ber_printf( ber, "}" ) == -1 )
- return( NULL );
-*/
-
- return( next );
-}
-
-static int
-put_filter( BerElement *ber, char *str )
-{
- char *next, *tmp, *s, *d;
- int parens, balance, escape, gotescape;
-
- /*
- * A Filter looks like this:
- * Filter ::= CHOICE {
- * and [0] SET OF Filter,
- * or [1] SET OF Filter,
- * not [2] Filter,
- * equalityMatch [3] AttributeValueAssertion,
- * substrings [4] SubstringFilter,
- * greaterOrEqual [5] AttributeValueAssertion,
- * lessOrEqual [6] AttributeValueAssertion,
- * present [7] AttributeType,,
- * approxMatch [8] AttributeValueAssertion
- * }
- *
- * SubstringFilter ::= SEQUENCE {
- * type AttributeType,
- * SEQUENCE OF CHOICE {
- * initial [0] IA5String,
- * any [1] IA5String,
- * final [2] IA5String
- * }
- * }
- * Note: tags in a choice are always explicit
- */
-
- Debug( LDAP_DEBUG_TRACE, "put_filter \"%s\"\n", str, 0, 0 );
-
- gotescape = parens = 0;
- while ( *str ) {
- switch ( *str ) {
- case '(':
- str++;
- parens++;
- switch ( *str ) {
- case '&':
- Debug( LDAP_DEBUG_TRACE, "put_filter: AND\n",
- 0, 0, 0 );
-
- if ( (str = put_complex_filter( ber, str,
- LDAP_FILTER_AND, 0 )) == NULL )
- return( -1 );
-
- parens--;
- break;
-
- case '|':
- Debug( LDAP_DEBUG_TRACE, "put_filter: OR\n",
- 0, 0, 0 );
-
- if ( (str = put_complex_filter( ber, str,
- LDAP_FILTER_OR, 0 )) == NULL )
- return( -1 );
-
- parens--;
- break;
-
- case '!':
- Debug( LDAP_DEBUG_TRACE, "put_filter: NOT\n",
- 0, 0, 0 );
-
- if ( (str = put_complex_filter( ber, str,
- LDAP_FILTER_NOT, 1 )) == NULL )
- return( -1 );
-
- parens--;
- break;
-
- default:
- Debug( LDAP_DEBUG_TRACE, "put_filter: simple\n",
- 0, 0, 0 );
-
- balance = 1;
- escape = 0;
- next = str;
- while ( *next && balance ) {
- if ( escape == 0 ) {
- if ( *next == '(' )
- balance++;
- else if ( *next == ')' )
- balance--;
- }
- if ( *next == '\\' && ! escape )
- gotescape = escape = 1;
- else
- escape = 0;
- if ( balance )
- next++;
- }
- if ( balance != 0 )
- return( -1 );
-
- *next = '\0';
- tmp = strdup( str );
- if ( gotescape ) {
- escape = 0;
- for ( s = d = tmp; *s; s++ ) {
- if ( *s != '\\' || escape ) {
- *d++ = *s;
- escape = 0;
- } else {
- escape = 1;
- }
- }
- *d = '\0';
- }
- if ( put_simple_filter( ber, tmp ) == -1 ) {
- free( tmp );
- return( -1 );
- }
- free( tmp );
- *next++ = ')';
- str = next;
- parens--;
- break;
- }
- break;
-
- case ')':
- Debug( LDAP_DEBUG_TRACE, "put_filter: end\n", 0, 0,
- 0 );
- if ( ber_printf( ber, "]" ) == -1 )
- return( -1 );
- str++;
- parens--;
- break;
-
- case ' ':
- str++;
- break;
-
- default: /* assume it's a simple type=value filter */
- Debug( LDAP_DEBUG_TRACE, "put_filter: default\n", 0, 0,
- 0 );
- next = strchr( str, '\0' );
- tmp = strdup( str );
- if ( strchr( tmp, '\\' ) != NULL ) {
- escape = 0;
- for ( s = d = tmp; *s; s++ ) {
- if ( *s != '\\' || escape ) {
- *d++ = *s;
- escape = 0;
- } else {
- escape = 1;
- }
- }
- *d = '\0';
- }
- if ( put_simple_filter( ber, tmp ) == -1 ) {
- free( tmp );
- return( -1 );
- }
- free( tmp );
- str = next;
- break;
- }
- }
-
- return( parens ? -1 : 0 );
-}
-
-/*
- * Put a list of filters like this "(filter1)(filter2)..."
- */
-
-static int
-put_filter_list( BerElement *ber, char *str )
-{
- char *next;
- char save;
-
- Debug( LDAP_DEBUG_TRACE, "put_filter_list \"%s\"\n", str, 0, 0 );
-
- while ( *str ) {
- while ( *str && isspace( *str ) )
- str++;
- if ( *str == '\0' )
- break;
-
- if ( (next = find_right_paren( str + 1 )) == NULL )
- return( -1 );
- save = *++next;
-
- /* now we have "(filter)" with str pointing to it */
- *next = '\0';
- if ( put_filter( ber, str ) == -1 )
- return( -1 );
- *next = save;
-
- str = next;
- }
-
- return( 0 );
-}
-
-static int
-put_simple_filter( BerElement *ber, char *str )
-{
- char *s;
- char *value, savechar;
- unsigned long ftype;
- int rc;
-
- Debug( LDAP_DEBUG_TRACE, "put_simple_filter \"%s\"\n", str, 0, 0 );
-
- if ( (s = strchr( str, '=' )) == NULL )
- return( -1 );
- value = s + 1;
- *s-- = '\0';
- savechar = *s;
-
- switch ( *s ) {
- case '<':
- ftype = LDAP_FILTER_LE;
- *s = '\0';
- break;
- case '>':
- ftype = LDAP_FILTER_GE;
- *s = '\0';
- break;
- case '~':
- ftype = LDAP_FILTER_APPROX;
- *s = '\0';
- break;
- default:
- if ( strchr( value, '*' ) == NULL ) {
- ftype = LDAP_FILTER_EQUALITY;
- } else if ( strcmp( value, "*" ) == 0 ) {
- ftype = LDAP_FILTER_PRESENT;
- } else {
- rc = put_substring_filter( ber, str, value );
- *(value-1) = '=';
- return( rc );
- }
- break;