xref: /onnv-gate/usr/src/lib/libldap4/common/sort.c (revision 3857:21b9b714e4ab)
1 /*
2  *
3  * Portions Copyright 1998 Sun Microsystems, Inc.  All rights reserved.
4  * Use is subject to license terms.
5  *
6  */
7 
8 #pragma ident	"%Z%%M%	%I%	%E% SMI"
9 
10 /*
11  * Copyright (c) 1994 Regents of the University of Michigan.
12  * All rights reserved.
13  *
14  * Redistribution and use in source and binary forms are permitted
15  * provided that this notice is preserved and that due credit is given
16  * to the University of Michigan at Ann Arbor. The name of the University
17  * may not be used to endorse or promote products derived from this
18  * software without specific prior written permission. This software
19  * is provided ``as is'' without express or implied warranty.
20  *
21  * sort.c:  LDAP library entry and value sort routines
22  */
23 
24 #include <stdio.h>
25 #include <ctype.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include <time.h>
29 #ifdef MACOS
30 #include "macos.h"
31 #else /* MACOS */
32 #ifdef DOS
33 #include <malloc.h>
34 #include "msdos.h"
35 #endif /* DOS */
36 #endif /* MACOS */
37 
38 #include "lber.h"
39 #include "ldap.h"
40 #include "ldap-private.h"
41 #include "ldap-int.h"
42 
43 struct entrything {
44 	char		**et_vals;
45 	LDAPMessage	*et_msg;
46 };
47 
48 #ifndef NEEDPROTOS
49 static int	(*et_cmp_fn)();
50 static int	et_cmp();
51 #else /* !NEEDPROTOS */
52 static int	(*et_cmp_fn)( char *a, char *b );
53 #ifdef SUN
54 static int	et_cmp( const void *aa, const void *bb);
55 #else
56 static int	et_cmp( void *aa, void *bb);
57 #endif
58 #endif /* !NEEDPROTOS */
59 
60 int
ldap_sort_strcasecmp(char ** a,char ** b)61 ldap_sort_strcasecmp(
62     char	**a,
63     char	**b
64 )
65 {
66 	return( strcasecmp( *a, *b ) );
67 }
68 
69 static int
et_cmp(const void * aa,const void * bb)70 et_cmp(
71 #ifdef SUN
72 	const void	*aa,
73 	const void	*bb
74 #else
75 	void	*aa,
76 	void	*bb
77 #endif
78 )
79 {
80 	int			i, rc;
81 	struct entrything	*a = (struct entrything *)aa;
82 	struct entrything	*b = (struct entrything *)bb;
83 
84 	if ( a->et_vals == NULL && b->et_vals == NULL )
85 		return( 0 );
86 	if ( a->et_vals == NULL )
87 		return( -1 );
88 	if ( b->et_vals == NULL )
89 		return( 1 );
90 
91 	for ( i = 0; a->et_vals[i] && b->et_vals[i]; i++ ) {
92 		if ( (rc = (*et_cmp_fn)( a->et_vals[i], b->et_vals[i] ))
93 		    != 0 ) {
94 			return( rc );
95 		}
96 	}
97 
98 	if ( a->et_vals[i] == NULL && b->et_vals[i] == NULL )
99 		return( 0 );
100 	if ( a->et_vals[i] == NULL )
101 		return( -1 );
102 	return( 1 );
103 }
104 
105 int
ldap_sort_entries(LDAP * ld,LDAPMessage ** chain,char * attr,int (* cmp)())106 ldap_sort_entries(
107     LDAP	*ld,
108     LDAPMessage	**chain,
109     char	*attr,		/* NULL => sort by DN */
110     int		(*cmp)()
111 )
112 {
113 	int			i;
114 	size_t			count;
115 	struct entrything	*et;
116 	LDAPMessage		*e, *last;
117 	LDAPMessage		**ep;
118 
119 	count = ldap_count_entries( ld, *chain );
120 
121 	if ( (et = (struct entrything *) malloc( count *
122 	    sizeof(struct entrything) )) == NULL ) {
123 		ld->ld_errno = LDAP_NO_MEMORY;
124 		return( -1 );
125 	}
126 
127 	e = *chain;
128 	for ( i = 0; i < count; i++ ) {
129 		et[i].et_msg = e;
130 		if ( attr == NULL ) {
131 			char	*dn;
132 
133 			dn = ldap_get_dn( ld, e );
134 			et[i].et_vals = ldap_explode_dn( dn, 1 );
135 			free( dn );
136 		} else {
137 			et[i].et_vals = ldap_get_values( ld, e, attr );
138 		}
139 
140 		e = e->lm_chain;
141 	}
142 	last = e;
143 
144 	et_cmp_fn = cmp;
145 #ifdef SUN
146 	qsort( et, count, sizeof(struct entrything), et_cmp );
147 #else
148 	qsort( et, count, sizeof(struct entrything), (void *) et_cmp );
149 #endif
150 
151 	ep = chain;
152 	for ( i = 0; i < count; i++ ) {
153 		*ep = et[i].et_msg;
154 		ep = &(*ep)->lm_chain;
155 
156 		ldap_value_free( et[i].et_vals );
157 	}
158 	*ep = last;
159 	free( (char *) et );
160 
161 	return( 0 );
162 }
163 
164 /* ARGSUSED */
165 int
ldap_sort_values(LDAP * ld,char ** vals,int (* cmp)())166 ldap_sort_values(
167     LDAP	*ld,
168     char	**vals,
169     int		(*cmp)()
170 )
171 {
172 	size_t	nel;
173 
174 	for ( nel = 0; vals[nel] != NULL; nel++ )
175 		;	/* NULL */
176 
177 	qsort( vals, nel, sizeof(char *), cmp );
178 
179 	return( 0 );
180 }
181