1/*	$NetBSD: getvalues.c,v 1.1.1.3 2010/12/12 15:21:32 adam Exp $	*/
2
3/* OpenLDAP: pkg/ldap/libraries/libldap/getvalues.c,v 1.26.2.5 2010/04/13 20:22:57 kurt Exp */
4/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 *
6 * Copyright 1998-2010 The OpenLDAP Foundation.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted only as authorized by the OpenLDAP
11 * Public License.
12 *
13 * A copy of this license is available in the file LICENSE in the
14 * top-level directory of the distribution or, alternatively, at
15 * <http://www.OpenLDAP.org/license.html>.
16 */
17/* Portions Copyright (c) 1990 Regents of the University of Michigan.
18 * All rights reserved.
19 */
20
21#include "portable.h"
22
23#include <stdio.h>
24
25#include <ac/stdlib.h>
26
27#include <ac/ctype.h>
28#include <ac/socket.h>
29#include <ac/string.h>
30#include <ac/time.h>
31
32#include "ldap-int.h"
33
34char **
35ldap_get_values( LDAP *ld, LDAPMessage *entry, LDAP_CONST char *target )
36{
37	BerElement	ber;
38	char		*attr;
39	int		found = 0;
40	char		**vals;
41
42	assert( ld != NULL );
43	assert( LDAP_VALID( ld ) );
44	assert( entry != NULL );
45	assert( target != NULL );
46
47	Debug( LDAP_DEBUG_TRACE, "ldap_get_values\n", 0, 0, 0 );
48
49	ber = *entry->lm_ber;
50
51	/* skip sequence, dn, sequence of, and snag the first attr */
52	if ( ber_scanf( &ber, "{x{{a" /*}}}*/, &attr ) == LBER_ERROR ) {
53		ld->ld_errno = LDAP_DECODING_ERROR;
54		return( NULL );
55	}
56
57	if ( strcasecmp( target, attr ) == 0 )
58		found = 1;
59
60	/* break out on success, return out on error */
61	while ( ! found ) {
62		LDAP_FREE(attr);
63		attr = NULL;
64
65		if ( ber_scanf( &ber, /*{*/ "x}{a" /*}*/, &attr ) == LBER_ERROR ) {
66			ld->ld_errno = LDAP_DECODING_ERROR;
67			return( NULL );
68		}
69
70		if ( strcasecmp( target, attr ) == 0 )
71			break;
72
73	}
74
75	LDAP_FREE(attr);
76	attr = NULL;
77
78	/*
79	 * if we get this far, we've found the attribute and are sitting
80	 * just before the set of values.
81	 */
82
83	if ( ber_scanf( &ber, "[v]", &vals ) == LBER_ERROR ) {
84		ld->ld_errno = LDAP_DECODING_ERROR;
85		return( NULL );
86	}
87
88	return( vals );
89}
90
91struct berval **
92ldap_get_values_len( LDAP *ld, LDAPMessage *entry, LDAP_CONST char *target )
93{
94	BerElement	ber;
95	char		*attr;
96	int		found = 0;
97	struct berval	**vals;
98
99	assert( ld != NULL );
100	assert( LDAP_VALID( ld ) );
101	assert( entry != NULL );
102	assert( target != NULL );
103
104	Debug( LDAP_DEBUG_TRACE, "ldap_get_values_len\n", 0, 0, 0 );
105
106	ber = *entry->lm_ber;
107
108	/* skip sequence, dn, sequence of, and snag the first attr */
109	if ( ber_scanf( &ber, "{x{{a" /* }}} */, &attr ) == LBER_ERROR ) {
110		ld->ld_errno = LDAP_DECODING_ERROR;
111		return( NULL );
112	}
113
114	if ( strcasecmp( target, attr ) == 0 )
115		found = 1;
116
117	/* break out on success, return out on error */
118	while ( ! found ) {
119		LDAP_FREE( attr );
120		attr = NULL;
121
122		if ( ber_scanf( &ber, /*{*/ "x}{a" /*}*/, &attr ) == LBER_ERROR ) {
123			ld->ld_errno = LDAP_DECODING_ERROR;
124			return( NULL );
125		}
126
127		if ( strcasecmp( target, attr ) == 0 )
128			break;
129	}
130
131	LDAP_FREE( attr );
132	attr = NULL;
133
134	/*
135	 * if we get this far, we've found the attribute and are sitting
136	 * just before the set of values.
137	 */
138
139	if ( ber_scanf( &ber, "[V]", &vals ) == LBER_ERROR ) {
140		ld->ld_errno = LDAP_DECODING_ERROR;
141		return( NULL );
142	}
143
144	return( vals );
145}
146
147int
148ldap_count_values( char **vals )
149{
150	int	i;
151
152	if ( vals == NULL )
153		return( 0 );
154
155	for ( i = 0; vals[i] != NULL; i++ )
156		;	/* NULL */
157
158	return( i );
159}
160
161int
162ldap_count_values_len( struct berval **vals )
163{
164	return( ldap_count_values( (char **) vals ) );
165}
166
167void
168ldap_value_free( char **vals )
169{
170	LDAP_VFREE( vals );
171}
172
173void
174ldap_value_free_len( struct berval **vals )
175{
176	ber_bvecfree( vals );
177}
178
179char **
180ldap_value_dup( char *const *vals )
181{
182	char **new;
183	int i;
184
185	if( vals == NULL ) {
186		return NULL;
187	}
188
189	for( i=0; vals[i]; i++ ) {
190		;   /* Count the number of values */
191	}
192
193	if( i == 0 ) {
194		return NULL;
195	}
196
197	new = LDAP_MALLOC( (i+1)*sizeof(char *) );  /* Alloc array of pointers */
198	if( new == NULL ) {
199		return NULL;
200	}
201
202	for( i=0; vals[i]; i++ ) {
203		new[i] = LDAP_STRDUP( vals[i] );   /* Dup each value */
204		if( new[i] == NULL ) {
205			LDAP_VFREE( new );
206			return NULL;
207		}
208	}
209	new[i] = NULL;
210
211	return new;
212}
213
214