1/* $OpenLDAP$ */
2/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3 *
4 * Copyright 1998-2011 The OpenLDAP Foundation.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted only as authorized by the OpenLDAP
9 * Public License.
10 *
11 * A copy of this license is available in the file LICENSE in the
12 * top-level directory of the distribution or, alternatively, at
13 * <http://www.OpenLDAP.org/license.html>.
14 */
15/* Portions Copyright (c) 1990 Regents of the University of Michigan.
16 * All rights reserved.
17 */
18
19#include "portable.h"
20
21#include <stdio.h>
22#include <ac/stdlib.h>
23
24#include <ac/socket.h>
25#include <ac/string.h>
26#include <ac/time.h>
27
28#include "ldap-int.h"
29
30/* ARGSUSED */
31LDAPMessage *
32ldap_first_entry( LDAP *ld, LDAPMessage *chain )
33{
34	assert( ld != NULL );
35	assert( LDAP_VALID( ld ) );
36	assert( chain != NULL );
37
38	return chain->lm_msgtype == LDAP_RES_SEARCH_ENTRY
39		? chain
40		: ldap_next_entry( ld, chain );
41}
42
43LDAPMessage *
44ldap_next_entry( LDAP *ld, LDAPMessage *entry )
45{
46	assert( ld != NULL );
47	assert( LDAP_VALID( ld ) );
48	assert( entry != NULL );
49
50	for(
51		entry = entry->lm_chain;
52		entry != NULL;
53		entry = entry->lm_chain )
54	{
55		if( entry->lm_msgtype == LDAP_RES_SEARCH_ENTRY ) {
56			return( entry );
57		}
58	}
59
60	return( NULL );
61}
62
63int
64ldap_count_entries( LDAP *ld, LDAPMessage *chain )
65{
66	int	i;
67
68	assert( ld != NULL );
69	assert( LDAP_VALID( ld ) );
70
71	for ( i = 0; chain != NULL; chain = chain->lm_chain ) {
72		if( chain->lm_msgtype == LDAP_RES_SEARCH_ENTRY ) {
73			i++;
74		}
75	}
76
77	return( i );
78}
79
80int
81ldap_get_entry_controls(
82	LDAP *ld,
83	LDAPMessage *entry,
84	LDAPControl ***sctrls )
85{
86	int rc;
87	BerElement be;
88
89	assert( ld != NULL );
90	assert( LDAP_VALID( ld ) );
91	assert( entry != NULL );
92	assert( sctrls != NULL );
93
94	if ( entry->lm_msgtype != LDAP_RES_SEARCH_ENTRY ) {
95		return LDAP_PARAM_ERROR;
96	}
97
98	/* make a local copy of the BerElement */
99	AC_MEMCPY(&be, entry->lm_ber, sizeof(be));
100
101	if ( ber_scanf( &be, "{xx" /*}*/ ) == LBER_ERROR ) {
102		rc = LDAP_DECODING_ERROR;
103		goto cleanup_and_return;
104	}
105
106	rc = ldap_pvt_get_controls( &be, sctrls );
107
108cleanup_and_return:
109	if( rc != LDAP_SUCCESS ) {
110		ld->ld_errno = rc;
111
112		if( ld->ld_matched != NULL ) {
113			LDAP_FREE( ld->ld_matched );
114			ld->ld_matched = NULL;
115		}
116
117		if( ld->ld_error != NULL ) {
118			LDAP_FREE( ld->ld_error );
119			ld->ld_error = NULL;
120		}
121	}
122
123	return rc;
124}
125