2 * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
6 #pragma ident "%Z%%M% %I% %E% SMI"
9 * The contents of this file are subject to the Netscape Public
10 * License Version 1.1 (the "License"); you may not use this file
11 * except in compliance with the License. You may obtain a copy of
12 * the License at http://www.mozilla.org/NPL/
14 * Software distributed under the License is distributed on an "AS
15 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
16 * implied. See the License for the specific language governing
17 * rights and limitations under the License.
19 * The Original Code is Mozilla Communicator client code, released
22 * The Initial Developer of the Original Code is Netscape
23 * Communications Corporation. Portions created by Netscape are
24 * Copyright (C) 1998-1999 Netscape Communications Corporation. All
30 /* vlistctrl.c - virtual list control implementation. */
36 * function to create a VirtualListViewRequest control that can be passed
37 * to ldap_search_ext() or ldap_search_ext_s(). *ctrlp will be set to a
38 * freshly allocated LDAPControl structure. Returns an LDAP error code
39 * (LDAP_SUCCESS if all goes well).
42 * ld LDAP pointer to the desired connection
44 * ldvlistp the control structure.
46 * ctrlp the address of a place to put the constructed control
48 The controlValue is an OCTET STRING
49 whose value is the BER-encoding of the following SEQUENCE:
51 VirtualListViewRequest ::= SEQUENCE {
52 beforeCount INTEGER (0 .. maxInt),
53 afterCount INTEGER (0 .. maxInt),
55 byIndex [0] SEQUENCE {
56 index INTEGER (0 .. maxInt),
57 contentCount INTEGER (0 .. maxInt) }
58 byValue [1] greaterThanOrEqual assertionValue }
60 beforeCount indicates how many entries before the target entry the
61 client wants the server to send. afterCount indicates the number of
62 entries after the target entry the client wants the server to send.
63 index and contentCount identify the target entry
64 greaterThanOrEqual is an attribute assertion value defined in
65 [LDAPv3]. If present, the value supplied in greaterThanOrEqual is used
66 to determine the target entry by comparison with the values of the
67 attribute specified as the primary sort key. The first list entry who's
68 value is no less than the supplied value is the target entry.
74 ldap_create_virtuallist_control(
76 LDAPVirtualList
*ldvlistp
,
83 if (!NSLDAPI_VALID_LDAP_POINTER( ld
)) {
84 return( LDAP_PARAM_ERROR
);
88 if ( NULL
== ctrlp
|| NULL
== ldvlistp
) {
89 LDAP_SET_LDERRNO( ld
, LDAP_PARAM_ERROR
, NULL
, NULL
);
90 return ( LDAP_PARAM_ERROR
);
93 /* create a ber package to hold the controlValue */
94 if ( LDAP_SUCCESS
!= nsldapi_alloc_ber_with_options( ld
, &ber
) )
96 LDAP_SET_LDERRNO( ld
, LDAP_NO_MEMORY
, NULL
, NULL
);
97 return( LDAP_NO_MEMORY
);
100 if ( LBER_ERROR
== ber_printf( ber
,
102 (int)ldvlistp
->ldvlist_before_count
,
103 (int)ldvlistp
->ldvlist_after_count
))
104 /* XXX lossy casts */
106 LDAP_SET_LDERRNO( ld
, LDAP_ENCODING_ERROR
, NULL
, NULL
);
108 return( LDAP_ENCODING_ERROR
);
111 if (NULL
== ldvlistp
->ldvlist_attrvalue
)
113 if ( LBER_ERROR
== ber_printf( ber
,
115 LDAP_TAG_VLV_BY_INDEX
,
116 (int)ldvlistp
->ldvlist_index
,
117 (int)ldvlistp
->ldvlist_size
) )
118 /* XXX lossy casts */
120 LDAP_SET_LDERRNO( ld
, LDAP_ENCODING_ERROR
, NULL
, NULL
);
122 return( LDAP_ENCODING_ERROR
);
127 if ( LBER_ERROR
== ber_printf( ber
,
129 LDAP_TAG_VLV_BY_VALUE
,
130 ldvlistp
->ldvlist_attrvalue
,
131 (int)strlen( ldvlistp
->ldvlist_attrvalue
)) ) {
132 LDAP_SET_LDERRNO( ld
, LDAP_ENCODING_ERROR
, NULL
, NULL
);
134 return( LDAP_ENCODING_ERROR
);
139 rc
= nsldapi_build_control( LDAP_CONTROL_VLVREQUEST
,
145 LDAP_SET_LDERRNO( ld
, rc
, NULL
, NULL
);
152 * function to find and parse a VirtualListViewResponse control contained in
153 * "ctrls" *target_posp, *list_sizep, and *errcodep are set based on its
154 * contents. Returns an LDAP error code that indicates whether the parsing
155 * itself was successful (LDAP_SUCCESS if all goes well).
157 The controlValue is an OCTET STRING, whose value
158 is the BER encoding of a value of the following SEQUENCE:
160 VirtualListViewResponse ::= SEQUENCE {
161 targetPosition INTEGER (0 .. maxInt),
162 contentCount INTEGER (0 .. maxInt),
163 virtualListViewResult ENUMERATED {
166 unwillingToPerform (53),
167 insufficientAccessRights (50),
169 timeLimitExceeded (3),
170 adminLimitExceeded (11),
171 sortControlMissing (60),
172 indexRangeError (61),
178 ldap_parse_virtuallist_control
182 unsigned long *target_posp
,
183 unsigned long *list_sizep
,
188 int i
, foundListControl
, errcode
;
189 LDAPControl
*listCtrlp
;
190 unsigned long target_pos
, list_size
;
191 int target_pos_int
, list_size_int
;
193 if ( !NSLDAPI_VALID_LDAP_POINTER( ld
)) {
194 return( LDAP_PARAM_ERROR
);
197 /* only ldapv3 or higher can do virtual lists. */
198 if ( NSLDAPI_LDAP_VERSION( ld
) < LDAP_VERSION3
) {
199 LDAP_SET_LDERRNO( ld
, LDAP_NOT_SUPPORTED
, NULL
, NULL
);
200 return( LDAP_NOT_SUPPORTED
);
203 /* find the listControl in the list of controls if it exists */
204 if ( ctrls
== NULL
) {
205 LDAP_SET_LDERRNO( ld
, LDAP_CONTROL_NOT_FOUND
, NULL
, NULL
);
206 return ( LDAP_CONTROL_NOT_FOUND
);
209 foundListControl
= 0;
210 for ( i
= 0; (( ctrls
[i
] != NULL
) && ( !foundListControl
)); i
++ ) {
211 foundListControl
= !strcmp( ctrls
[i
]->ldctl_oid
,
212 LDAP_CONTROL_VLVRESPONSE
);
214 if ( !foundListControl
) {
215 LDAP_SET_LDERRNO( ld
, LDAP_CONTROL_NOT_FOUND
, NULL
, NULL
);
216 return ( LDAP_CONTROL_NOT_FOUND
);
218 /* let local var point to the listControl */
219 listCtrlp
= ctrls
[i
-1];
222 /* allocate a Ber element with the contents of the list_control's struct berval */
223 if ( ( ber
= ber_init( &listCtrlp
->ldctl_value
) ) == NULL
) {
224 LDAP_SET_LDERRNO( ld
, LDAP_NO_MEMORY
, NULL
, NULL
);
225 return( LDAP_NO_MEMORY
);
228 /* decode the result from the Berelement */
229 if ( LBER_ERROR
== ber_scanf( ber
, "{iie}", &target_pos_int
, &list_size_int
,
231 LDAP_SET_LDERRNO( ld
, LDAP_DECODING_ERROR
, NULL
, NULL
);
233 return( LDAP_DECODING_ERROR
);
236 target_pos
= target_pos_int
;
237 list_size
= list_size_int
;
239 if ( target_posp
!= NULL
) {
240 *target_posp
= target_pos
;
242 if ( list_sizep
!= NULL
) {
243 *list_sizep
= list_size
;
245 if ( errcodep
!= NULL
) {
249 /* the ber encoding is no longer needed */
252 return(LDAP_SUCCESS
);