17c478bd9Sstevel@tonic-gate /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
27c478bd9Sstevel@tonic-gate *
37c478bd9Sstevel@tonic-gate * The contents of this file are subject to the Netscape Public License
47c478bd9Sstevel@tonic-gate * Version 1.0 (the "NPL"); you may not use this file except in
57c478bd9Sstevel@tonic-gate * compliance with the NPL. You may obtain a copy of the NPL at
67c478bd9Sstevel@tonic-gate * http://www.mozilla.org/NPL/
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * Software distributed under the NPL is distributed on an "AS IS" basis,
97c478bd9Sstevel@tonic-gate * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
107c478bd9Sstevel@tonic-gate * for the specific language governing rights and limitations under the
117c478bd9Sstevel@tonic-gate * NPL.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * The Initial Developer of this code under the NPL is Netscape
147c478bd9Sstevel@tonic-gate * Communications Corporation. Portions created by Netscape are
157c478bd9Sstevel@tonic-gate * Copyright (C) 1998 Netscape Communications Corporation. All Rights
167c478bd9Sstevel@tonic-gate * Reserved.
177c478bd9Sstevel@tonic-gate */
187c478bd9Sstevel@tonic-gate #include "ldap-int.h"
197c478bd9Sstevel@tonic-gate
207c478bd9Sstevel@tonic-gate /* ldap_create_sort_control:
217c478bd9Sstevel@tonic-gate
22*1da57d55SToomas Soome Parameters are
237c478bd9Sstevel@tonic-gate
24*1da57d55SToomas Soome ld LDAP pointer to the desired connection
257c478bd9Sstevel@tonic-gate
26*1da57d55SToomas Soome sortKeyList an array of sortkeys
277c478bd9Sstevel@tonic-gate
287c478bd9Sstevel@tonic-gate ctl_iscritical Indicates whether the control is critical of not. If
297c478bd9Sstevel@tonic-gate this field is non-zero, the operation will only be car-
307c478bd9Sstevel@tonic-gate ried out if the control is recognized by the server
317c478bd9Sstevel@tonic-gate and/or client
327c478bd9Sstevel@tonic-gate
33*1da57d55SToomas Soome ctrlp the address of a place to put the constructed control
347c478bd9Sstevel@tonic-gate */
357c478bd9Sstevel@tonic-gate
367c478bd9Sstevel@tonic-gate int
377c478bd9Sstevel@tonic-gate LDAP_CALL
ldap_create_sort_control(LDAP * ld,LDAPsortkey ** sortKeyList,const char ctl_iscritical,LDAPControl ** ctrlp)38*1da57d55SToomas Soome ldap_create_sort_control (
39*1da57d55SToomas Soome LDAP *ld,
407c478bd9Sstevel@tonic-gate LDAPsortkey **sortKeyList,
417c478bd9Sstevel@tonic-gate const char ctl_iscritical,
42*1da57d55SToomas Soome LDAPControl **ctrlp
437c478bd9Sstevel@tonic-gate )
447c478bd9Sstevel@tonic-gate {
457c478bd9Sstevel@tonic-gate BerElement *ber;
467c478bd9Sstevel@tonic-gate int i, rc;
477c478bd9Sstevel@tonic-gate
487c478bd9Sstevel@tonic-gate if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
497c478bd9Sstevel@tonic-gate return( LDAP_PARAM_ERROR );
507c478bd9Sstevel@tonic-gate }
517c478bd9Sstevel@tonic-gate
527c478bd9Sstevel@tonic-gate if ( sortKeyList == NULL || ctrlp == NULL ) {
537c478bd9Sstevel@tonic-gate LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
547c478bd9Sstevel@tonic-gate return ( LDAP_PARAM_ERROR );
557c478bd9Sstevel@tonic-gate }
567c478bd9Sstevel@tonic-gate
577c478bd9Sstevel@tonic-gate /* create a ber package to hold the controlValue */
587c478bd9Sstevel@tonic-gate if ( ( nsldapi_alloc_ber_with_options( ld, &ber ) ) != LDAP_SUCCESS ) {
597c478bd9Sstevel@tonic-gate LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
607c478bd9Sstevel@tonic-gate return( LDAP_NO_MEMORY );
617c478bd9Sstevel@tonic-gate }
627c478bd9Sstevel@tonic-gate
637c478bd9Sstevel@tonic-gate /* encode the start of the sequence of sequences into the ber */
647c478bd9Sstevel@tonic-gate if ( ber_printf( ber, "{" ) == -1 ) {
657c478bd9Sstevel@tonic-gate goto encoding_error_exit;
667c478bd9Sstevel@tonic-gate }
677c478bd9Sstevel@tonic-gate
687c478bd9Sstevel@tonic-gate /* the sort control value will be encoded as a sequence of sequences
69*1da57d55SToomas Soome which are each encoded as one of the following: {s} or {sts} or {stb} or {ststb}
707c478bd9Sstevel@tonic-gate since the orderingRule and reverseOrder flag are both optional */
717c478bd9Sstevel@tonic-gate for ( i = 0; sortKeyList[i] != NULL; i++ ) {
727c478bd9Sstevel@tonic-gate
737c478bd9Sstevel@tonic-gate /* encode the attributeType into the ber */
747c478bd9Sstevel@tonic-gate if ( ber_printf( ber, "{s", (sortKeyList[i])->sk_attrtype )
757c478bd9Sstevel@tonic-gate == -1 ) {
767c478bd9Sstevel@tonic-gate goto encoding_error_exit;
777c478bd9Sstevel@tonic-gate }
78*1da57d55SToomas Soome
797c478bd9Sstevel@tonic-gate /* encode the optional orderingRule into the ber */
807c478bd9Sstevel@tonic-gate if ( (sortKeyList[i])->sk_matchruleoid != NULL ) {
817c478bd9Sstevel@tonic-gate if ( ber_printf( ber, "ts", LDAP_TAG_SK_MATCHRULE,
827c478bd9Sstevel@tonic-gate (sortKeyList[i])->sk_matchruleoid )
837c478bd9Sstevel@tonic-gate == -1 ) {
847c478bd9Sstevel@tonic-gate goto encoding_error_exit;
857c478bd9Sstevel@tonic-gate }
86*1da57d55SToomas Soome }
877c478bd9Sstevel@tonic-gate
887c478bd9Sstevel@tonic-gate /* Encode the optional reverseOrder flag into the ber. */
897c478bd9Sstevel@tonic-gate /* If the flag is false, it should be absent. */
907c478bd9Sstevel@tonic-gate if ( (sortKeyList[i])->sk_reverseorder ) {
917c478bd9Sstevel@tonic-gate if ( ber_printf( ber, "tb}", LDAP_TAG_SK_REVERSE,
927c478bd9Sstevel@tonic-gate (sortKeyList[i])->sk_reverseorder ) == -1 ) {
937c478bd9Sstevel@tonic-gate goto encoding_error_exit;
947c478bd9Sstevel@tonic-gate }
957c478bd9Sstevel@tonic-gate } else {
967c478bd9Sstevel@tonic-gate if ( ber_printf( ber, "}" ) == -1 ) {
977c478bd9Sstevel@tonic-gate goto encoding_error_exit;
987c478bd9Sstevel@tonic-gate }
997c478bd9Sstevel@tonic-gate }
1007c478bd9Sstevel@tonic-gate }
1017c478bd9Sstevel@tonic-gate
1027c478bd9Sstevel@tonic-gate /* encode the end of the sequence of sequences into the ber */
1037c478bd9Sstevel@tonic-gate if ( ber_printf( ber, "}" ) == -1 ) {
1047c478bd9Sstevel@tonic-gate goto encoding_error_exit;
1057c478bd9Sstevel@tonic-gate }
1067c478bd9Sstevel@tonic-gate
1077c478bd9Sstevel@tonic-gate rc = nsldapi_build_control( LDAP_CONTROL_SORTREQUEST, ber, 1,
1087c478bd9Sstevel@tonic-gate ctl_iscritical, ctrlp );
1097c478bd9Sstevel@tonic-gate
1107c478bd9Sstevel@tonic-gate LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
1117c478bd9Sstevel@tonic-gate return( rc );
1127c478bd9Sstevel@tonic-gate
1137c478bd9Sstevel@tonic-gate encoding_error_exit:
1147c478bd9Sstevel@tonic-gate LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL );
1157c478bd9Sstevel@tonic-gate ber_free( ber, 1 );
1167c478bd9Sstevel@tonic-gate return( LDAP_ENCODING_ERROR );
1177c478bd9Sstevel@tonic-gate }
1187c478bd9Sstevel@tonic-gate
1197c478bd9Sstevel@tonic-gate /* ldap_parse_sort_control:
1207c478bd9Sstevel@tonic-gate
121*1da57d55SToomas Soome Parameters are
1227c478bd9Sstevel@tonic-gate
123*1da57d55SToomas Soome ld LDAP pointer to the desired connection
1247c478bd9Sstevel@tonic-gate
125*1da57d55SToomas Soome ctrlp An array of controls obtained from calling
126*1da57d55SToomas Soome ldap_parse_result on the set of results returned by
127*1da57d55SToomas Soome the server
1287c478bd9Sstevel@tonic-gate
129*1da57d55SToomas Soome result the address of a place to put the result code
1307c478bd9Sstevel@tonic-gate
131*1da57d55SToomas Soome attribute the address of a place to put the name of the
132*1da57d55SToomas Soome attribute which cause the operation to fail, optionally
1337c478bd9Sstevel@tonic-gate returned by the server */
1347c478bd9Sstevel@tonic-gate
1357c478bd9Sstevel@tonic-gate int
1367c478bd9Sstevel@tonic-gate LDAP_CALL
ldap_parse_sort_control(LDAP * ld,LDAPControl ** ctrlp,unsigned long * result,char ** attribute)137*1da57d55SToomas Soome ldap_parse_sort_control (
138*1da57d55SToomas Soome LDAP *ld,
139*1da57d55SToomas Soome LDAPControl **ctrlp,
1407c478bd9Sstevel@tonic-gate unsigned long *result,
1417c478bd9Sstevel@tonic-gate char **attribute
1427c478bd9Sstevel@tonic-gate )
1437c478bd9Sstevel@tonic-gate {
1447c478bd9Sstevel@tonic-gate BerElement *ber;
1457c478bd9Sstevel@tonic-gate int i, foundSortControl;
1467c478bd9Sstevel@tonic-gate LDAPControl *sortCtrlp;
1477c478bd9Sstevel@tonic-gate ber_len_t len;
1487c478bd9Sstevel@tonic-gate ber_tag_t tag;
1497c478bd9Sstevel@tonic-gate char *attr;
1507c478bd9Sstevel@tonic-gate
1517c478bd9Sstevel@tonic-gate if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) || result == NULL ||
1527c478bd9Sstevel@tonic-gate attribute == NULL ) {
1537c478bd9Sstevel@tonic-gate return( LDAP_PARAM_ERROR );
1547c478bd9Sstevel@tonic-gate }
1557c478bd9Sstevel@tonic-gate
1567c478bd9Sstevel@tonic-gate
1577c478bd9Sstevel@tonic-gate /* find the sortControl in the list of controls if it exists */
1587c478bd9Sstevel@tonic-gate if ( ctrlp == NULL ) {
1597c478bd9Sstevel@tonic-gate LDAP_SET_LDERRNO( ld, LDAP_CONTROL_NOT_FOUND, NULL, NULL );
1607c478bd9Sstevel@tonic-gate return ( LDAP_CONTROL_NOT_FOUND );
161*1da57d55SToomas Soome }
1627c478bd9Sstevel@tonic-gate foundSortControl = 0;
1637c478bd9Sstevel@tonic-gate for ( i = 0; (( ctrlp[i] != NULL ) && ( !foundSortControl )); i++ ) {
1647c478bd9Sstevel@tonic-gate foundSortControl = !strcmp( ctrlp[i]->ldctl_oid, LDAP_CONTROL_SORTRESPONSE );
1657c478bd9Sstevel@tonic-gate }
1667c478bd9Sstevel@tonic-gate if ( !foundSortControl ) {
1677c478bd9Sstevel@tonic-gate LDAP_SET_LDERRNO( ld, LDAP_CONTROL_NOT_FOUND, NULL, NULL );
1687c478bd9Sstevel@tonic-gate return ( LDAP_CONTROL_NOT_FOUND );
1697c478bd9Sstevel@tonic-gate } else {
1707c478bd9Sstevel@tonic-gate /* let local var point to the sortControl */
171*1da57d55SToomas Soome sortCtrlp = ctrlp[i-1];
1727c478bd9Sstevel@tonic-gate }
1737c478bd9Sstevel@tonic-gate
1747c478bd9Sstevel@tonic-gate /* allocate a Ber element with the contents of the sort_control's struct berval */
1757c478bd9Sstevel@tonic-gate if ( ( ber = ber_init( &sortCtrlp->ldctl_value ) ) == NULL ) {
1767c478bd9Sstevel@tonic-gate LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
1777c478bd9Sstevel@tonic-gate return( LDAP_NO_MEMORY );
178*1da57d55SToomas Soome }
1797c478bd9Sstevel@tonic-gate
1807c478bd9Sstevel@tonic-gate /* decode the result from the Berelement */
1817c478bd9Sstevel@tonic-gate if ( ber_scanf( ber, "{i", result ) == LBER_ERROR ) {
1827c478bd9Sstevel@tonic-gate LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
1837c478bd9Sstevel@tonic-gate ber_free( ber, 1 );
1847c478bd9Sstevel@tonic-gate return( LDAP_DECODING_ERROR );
1857c478bd9Sstevel@tonic-gate }
1867c478bd9Sstevel@tonic-gate
1877c478bd9Sstevel@tonic-gate /* if the server returned one, decode the attribute from the Ber element */
1887c478bd9Sstevel@tonic-gate if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SR_ATTRTYPE ) {
1897c478bd9Sstevel@tonic-gate if ( ber_scanf( ber, "ta", &tag, &attr ) == LBER_ERROR ) {
1907c478bd9Sstevel@tonic-gate LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
1917c478bd9Sstevel@tonic-gate ber_free( ber, 1 );
1927c478bd9Sstevel@tonic-gate return( LDAP_DECODING_ERROR );
1937c478bd9Sstevel@tonic-gate }
194*1da57d55SToomas Soome *attribute = attr;
1957c478bd9Sstevel@tonic-gate } else {
1967c478bd9Sstevel@tonic-gate *attribute = NULL;
1977c478bd9Sstevel@tonic-gate }
1987c478bd9Sstevel@tonic-gate
1997c478bd9Sstevel@tonic-gate if ( ber_scanf( ber, "}" ) == LBER_ERROR ) {
2007c478bd9Sstevel@tonic-gate LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
2017c478bd9Sstevel@tonic-gate ber_free( ber, 1 );
2027c478bd9Sstevel@tonic-gate return( LDAP_DECODING_ERROR );
2037c478bd9Sstevel@tonic-gate }
2047c478bd9Sstevel@tonic-gate
2057c478bd9Sstevel@tonic-gate /* the ber encoding is no longer needed */
2067c478bd9Sstevel@tonic-gate ber_free(ber,1);
2077c478bd9Sstevel@tonic-gate
2087c478bd9Sstevel@tonic-gate return( LDAP_SUCCESS );
2097c478bd9Sstevel@tonic-gate }
2107c478bd9Sstevel@tonic-gate
2117c478bd9Sstevel@tonic-gate /* Routines for the manipulation of string-representations of sort control keylists */
2127c478bd9Sstevel@tonic-gate
count_tokens(const char * s)2137c478bd9Sstevel@tonic-gate static int count_tokens(const char *s)
2147c478bd9Sstevel@tonic-gate {
2157c478bd9Sstevel@tonic-gate int count = 0;
2167c478bd9Sstevel@tonic-gate const char *p = s;
2177c478bd9Sstevel@tonic-gate int whitespace = 1;
2187c478bd9Sstevel@tonic-gate /* Loop along the string counting the number of times we see the
2197c478bd9Sstevel@tonic-gate * beginning of non-whitespace. This tells us
2207c478bd9Sstevel@tonic-gate * the number of tokens in the string
2217c478bd9Sstevel@tonic-gate */
2227c478bd9Sstevel@tonic-gate while (*p != '\0') {
2237c478bd9Sstevel@tonic-gate if (whitespace) {
2247c478bd9Sstevel@tonic-gate if (!isspace(*p)) {
2257c478bd9Sstevel@tonic-gate whitespace = 0;
2267c478bd9Sstevel@tonic-gate count++;
2277c478bd9Sstevel@tonic-gate }
2287c478bd9Sstevel@tonic-gate } else {
2297c478bd9Sstevel@tonic-gate if (isspace(*p)) {
2307c478bd9Sstevel@tonic-gate whitespace = 1;
2317c478bd9Sstevel@tonic-gate }
2327c478bd9Sstevel@tonic-gate }
2337c478bd9Sstevel@tonic-gate p++;
2347c478bd9Sstevel@tonic-gate }
2357c478bd9Sstevel@tonic-gate return count;
2367c478bd9Sstevel@tonic-gate }
2377c478bd9Sstevel@tonic-gate
2387c478bd9Sstevel@tonic-gate
read_next_token(const char ** s,LDAPsortkey ** key)2397c478bd9Sstevel@tonic-gate static int read_next_token(const char **s,LDAPsortkey **key)
2407c478bd9Sstevel@tonic-gate {
2417c478bd9Sstevel@tonic-gate char c = 0;
2427c478bd9Sstevel@tonic-gate const char *pos = *s;
2437c478bd9Sstevel@tonic-gate int retval = 0;
2447c478bd9Sstevel@tonic-gate LDAPsortkey *new_key = NULL;
2457c478bd9Sstevel@tonic-gate
2467c478bd9Sstevel@tonic-gate const char *matchrule_source = NULL;
2477c478bd9Sstevel@tonic-gate int matchrule_size = 0;
2487c478bd9Sstevel@tonic-gate const char *attrdesc_source = NULL;
2497c478bd9Sstevel@tonic-gate int attrdesc_size = 0;
2507c478bd9Sstevel@tonic-gate int reverse = 0;
2517c478bd9Sstevel@tonic-gate
2527c478bd9Sstevel@tonic-gate int state = 0;
253*1da57d55SToomas Soome
2547c478bd9Sstevel@tonic-gate while ( ((c = *pos++) != '\0') && (state != 4) ) {
2557c478bd9Sstevel@tonic-gate switch (state) {
2567c478bd9Sstevel@tonic-gate case 0:
2577c478bd9Sstevel@tonic-gate /* case where we've not seen the beginning of the attr yet */
2587c478bd9Sstevel@tonic-gate /* If we still see whitespace, nothing to do */
2597c478bd9Sstevel@tonic-gate if (!isspace(c)) {
2607c478bd9Sstevel@tonic-gate /* Otherwise, something to look at */
2617c478bd9Sstevel@tonic-gate /* Is it a minus sign ? */
2627c478bd9Sstevel@tonic-gate if ('-' == c) {
2637c478bd9Sstevel@tonic-gate reverse = 1;
2647c478bd9Sstevel@tonic-gate } else {
2657c478bd9Sstevel@tonic-gate attrdesc_source = pos - 1;
2667c478bd9Sstevel@tonic-gate state = 1;
2677c478bd9Sstevel@tonic-gate }
2687c478bd9Sstevel@tonic-gate }
2697c478bd9Sstevel@tonic-gate break;
2707c478bd9Sstevel@tonic-gate case 1:
2717c478bd9Sstevel@tonic-gate /* case where we've seen the beginning of the attr, but not the end */
2727c478bd9Sstevel@tonic-gate /* Is this char either whitespace or a ';' ? */
2737c478bd9Sstevel@tonic-gate if ( isspace(c) || (':' == c)) {
2747c478bd9Sstevel@tonic-gate attrdesc_size = (pos - attrdesc_source) - 1;
2757c478bd9Sstevel@tonic-gate if (':' == c) {
2767c478bd9Sstevel@tonic-gate state = 2;
2777c478bd9Sstevel@tonic-gate } else {
2787c478bd9Sstevel@tonic-gate state = 4;
2797c478bd9Sstevel@tonic-gate }
280*1da57d55SToomas Soome }
2817c478bd9Sstevel@tonic-gate break;
2827c478bd9Sstevel@tonic-gate case 2:
2837c478bd9Sstevel@tonic-gate /* case where we've seen the end of the attr and want the beginning of match rule */
2847c478bd9Sstevel@tonic-gate if (!isspace(c)) {
2857c478bd9Sstevel@tonic-gate matchrule_source = pos - 1;
2867c478bd9Sstevel@tonic-gate state = 3;
2877c478bd9Sstevel@tonic-gate } else {
2887c478bd9Sstevel@tonic-gate state = 4;
2897c478bd9Sstevel@tonic-gate }
2907c478bd9Sstevel@tonic-gate break;
2917c478bd9Sstevel@tonic-gate case 3:
2927c478bd9Sstevel@tonic-gate /* case where we've seen the beginning of match rule and want to find the end */
2937c478bd9Sstevel@tonic-gate if (isspace(c)) {
2947c478bd9Sstevel@tonic-gate matchrule_size = (pos - matchrule_source) - 1;
2957c478bd9Sstevel@tonic-gate state = 4;
2967c478bd9Sstevel@tonic-gate }
2977c478bd9Sstevel@tonic-gate break;
2987c478bd9Sstevel@tonic-gate default:
2997c478bd9Sstevel@tonic-gate break;
3007c478bd9Sstevel@tonic-gate }
3017c478bd9Sstevel@tonic-gate }
302*1da57d55SToomas Soome
3037c478bd9Sstevel@tonic-gate if (3 == state) {
3047c478bd9Sstevel@tonic-gate /* means we fell off the end of the string looking for the end of the marching rule */
3057c478bd9Sstevel@tonic-gate matchrule_size = (pos - matchrule_source) - 1;
3067c478bd9Sstevel@tonic-gate }
3077c478bd9Sstevel@tonic-gate
3087c478bd9Sstevel@tonic-gate if (1 == state) {
3097c478bd9Sstevel@tonic-gate /* means we fell of the end of the string looking for the end of the attribute */
3107c478bd9Sstevel@tonic-gate attrdesc_size = (pos - attrdesc_source) - 1;
3117c478bd9Sstevel@tonic-gate }
3127c478bd9Sstevel@tonic-gate
3137c478bd9Sstevel@tonic-gate if (NULL == attrdesc_source) {
3147c478bd9Sstevel@tonic-gate /* Didn't find anything */
3157c478bd9Sstevel@tonic-gate return -1;
3167c478bd9Sstevel@tonic-gate }
3177c478bd9Sstevel@tonic-gate
3187c478bd9Sstevel@tonic-gate new_key = (LDAPsortkey*)NSLDAPI_MALLOC(sizeof(LDAPsortkey));
3197c478bd9Sstevel@tonic-gate if (0 == new_key) {
3207c478bd9Sstevel@tonic-gate return LDAP_NO_MEMORY;
3217c478bd9Sstevel@tonic-gate }
322*1da57d55SToomas Soome
3237c478bd9Sstevel@tonic-gate /* Allocate the strings */
3247c478bd9Sstevel@tonic-gate new_key->sk_attrtype = (char *)NSLDAPI_MALLOC(attrdesc_size + 1);
3257c478bd9Sstevel@tonic-gate if (NULL != matchrule_source) {
3267c478bd9Sstevel@tonic-gate new_key->sk_matchruleoid = (char *)NSLDAPI_MALLOC(
3277c478bd9Sstevel@tonic-gate matchrule_size + 1);
3287c478bd9Sstevel@tonic-gate } else {
3297c478bd9Sstevel@tonic-gate new_key->sk_matchruleoid = NULL;
3307c478bd9Sstevel@tonic-gate }
3317c478bd9Sstevel@tonic-gate /* Copy over the strings */
3327c478bd9Sstevel@tonic-gate memcpy(new_key->sk_attrtype,attrdesc_source,attrdesc_size);
3337c478bd9Sstevel@tonic-gate *(new_key->sk_attrtype + attrdesc_size) = '\0';
3347c478bd9Sstevel@tonic-gate if (NULL != matchrule_source) {
3357c478bd9Sstevel@tonic-gate memcpy(new_key->sk_matchruleoid,matchrule_source,matchrule_size);
3367c478bd9Sstevel@tonic-gate *(new_key->sk_matchruleoid + matchrule_size) = '\0';
3377c478bd9Sstevel@tonic-gate }
3387c478bd9Sstevel@tonic-gate
3397c478bd9Sstevel@tonic-gate new_key->sk_reverseorder = reverse;
3407c478bd9Sstevel@tonic-gate
3417c478bd9Sstevel@tonic-gate *s = pos - 1;
3427c478bd9Sstevel@tonic-gate *key = new_key;
3437c478bd9Sstevel@tonic-gate return retval;
3447c478bd9Sstevel@tonic-gate }
3457c478bd9Sstevel@tonic-gate
3467c478bd9Sstevel@tonic-gate int
3477c478bd9Sstevel@tonic-gate LDAP_CALL
ldap_create_sort_keylist(LDAPsortkey *** sortKeyList,const char * string_rep)3487c478bd9Sstevel@tonic-gate ldap_create_sort_keylist (
3497c478bd9Sstevel@tonic-gate LDAPsortkey ***sortKeyList,
3507c478bd9Sstevel@tonic-gate const char *string_rep
3517c478bd9Sstevel@tonic-gate )
3527c478bd9Sstevel@tonic-gate {
3537c478bd9Sstevel@tonic-gate int count = 0;
3547c478bd9Sstevel@tonic-gate LDAPsortkey **pointer_array = NULL;
3557c478bd9Sstevel@tonic-gate const char *current_position = NULL;
3567c478bd9Sstevel@tonic-gate int retval = 0;
3577c478bd9Sstevel@tonic-gate int i = 0;
3587c478bd9Sstevel@tonic-gate
3597c478bd9Sstevel@tonic-gate /* Figure out how many there are */
3607c478bd9Sstevel@tonic-gate if (NULL == string_rep) {
3617c478bd9Sstevel@tonic-gate return LDAP_PARAM_ERROR;
3627c478bd9Sstevel@tonic-gate }
3637c478bd9Sstevel@tonic-gate if (NULL == sortKeyList) {
3647c478bd9Sstevel@tonic-gate return LDAP_PARAM_ERROR;
3657c478bd9Sstevel@tonic-gate }
3667c478bd9Sstevel@tonic-gate count = count_tokens(string_rep);
3677c478bd9Sstevel@tonic-gate if (0 == count) {
3687c478bd9Sstevel@tonic-gate *sortKeyList = NULL;
3697c478bd9Sstevel@tonic-gate return LDAP_PARAM_ERROR;
3707c478bd9Sstevel@tonic-gate }
3717c478bd9Sstevel@tonic-gate /* Allocate enough memory for the pointers */
3727c478bd9Sstevel@tonic-gate pointer_array = (LDAPsortkey**)NSLDAPI_MALLOC(sizeof(LDAPsortkey*)
3737c478bd9Sstevel@tonic-gate * (count + 1) );
3747c478bd9Sstevel@tonic-gate if (NULL == pointer_array) {
3757c478bd9Sstevel@tonic-gate return LDAP_NO_MEMORY;
3767c478bd9Sstevel@tonic-gate }
3777c478bd9Sstevel@tonic-gate /* Now walk along the string, allocating and filling in the LDAPsearchkey structure */
3787c478bd9Sstevel@tonic-gate current_position = string_rep;
3797c478bd9Sstevel@tonic-gate
3807c478bd9Sstevel@tonic-gate for (i = 0; i < count; i++) {
3817c478bd9Sstevel@tonic-gate if (0 != (retval = read_next_token(¤t_position,&(pointer_array[i])))) {
3827c478bd9Sstevel@tonic-gate pointer_array[count] = NULL;
3837c478bd9Sstevel@tonic-gate ldap_free_sort_keylist(pointer_array);
3847c478bd9Sstevel@tonic-gate *sortKeyList = NULL;
3857c478bd9Sstevel@tonic-gate return retval;
3867c478bd9Sstevel@tonic-gate }
3877c478bd9Sstevel@tonic-gate }
3887c478bd9Sstevel@tonic-gate pointer_array[count] = NULL;
3897c478bd9Sstevel@tonic-gate *sortKeyList = pointer_array;
3907c478bd9Sstevel@tonic-gate return LDAP_SUCCESS;
3917c478bd9Sstevel@tonic-gate }
3927c478bd9Sstevel@tonic-gate
3937c478bd9Sstevel@tonic-gate void
3947c478bd9Sstevel@tonic-gate LDAP_CALL
ldap_free_sort_keylist(LDAPsortkey ** sortKeyList)3957c478bd9Sstevel@tonic-gate ldap_free_sort_keylist (
3967c478bd9Sstevel@tonic-gate LDAPsortkey **sortKeyList
3977c478bd9Sstevel@tonic-gate )
3987c478bd9Sstevel@tonic-gate {
3997c478bd9Sstevel@tonic-gate LDAPsortkey *this_one = NULL;
4007c478bd9Sstevel@tonic-gate int i = 0;
4017c478bd9Sstevel@tonic-gate
4027c478bd9Sstevel@tonic-gate if ( NULL == sortKeyList ) {
4037c478bd9Sstevel@tonic-gate return;
4047c478bd9Sstevel@tonic-gate }
4057c478bd9Sstevel@tonic-gate
4067c478bd9Sstevel@tonic-gate /* Walk down the list freeing the LDAPsortkey structures */
4077c478bd9Sstevel@tonic-gate for (this_one = sortKeyList[0]; this_one ; this_one = sortKeyList[++i]) {
4087c478bd9Sstevel@tonic-gate /* Free the strings, if present */
4097c478bd9Sstevel@tonic-gate if (NULL != this_one->sk_attrtype) {
4107c478bd9Sstevel@tonic-gate NSLDAPI_FREE(this_one->sk_attrtype);
4117c478bd9Sstevel@tonic-gate }
4127c478bd9Sstevel@tonic-gate if (NULL != this_one->sk_matchruleoid) {
4137c478bd9Sstevel@tonic-gate NSLDAPI_FREE(this_one->sk_matchruleoid);
4147c478bd9Sstevel@tonic-gate }
4157c478bd9Sstevel@tonic-gate NSLDAPI_FREE(this_one);
4167c478bd9Sstevel@tonic-gate }
4177c478bd9Sstevel@tonic-gate /* Free the pointer list */
4187c478bd9Sstevel@tonic-gate NSLDAPI_FREE(sortKeyList);
4197c478bd9Sstevel@tonic-gate }
420