xref: /onnv-gate/usr/src/lib/libldap4/common/sort.c (revision 3857:21b9b714e4ab)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  *
3*3857Sstevel  * Portions Copyright 1998 Sun Microsystems, Inc.  All rights reserved.
4*3857Sstevel  * Use is subject to license terms.
50Sstevel@tonic-gate  *
60Sstevel@tonic-gate  */
70Sstevel@tonic-gate 
80Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
90Sstevel@tonic-gate 
100Sstevel@tonic-gate /*
110Sstevel@tonic-gate  * Copyright (c) 1994 Regents of the University of Michigan.
120Sstevel@tonic-gate  * All rights reserved.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * Redistribution and use in source and binary forms are permitted
150Sstevel@tonic-gate  * provided that this notice is preserved and that due credit is given
160Sstevel@tonic-gate  * to the University of Michigan at Ann Arbor. The name of the University
170Sstevel@tonic-gate  * may not be used to endorse or promote products derived from this
180Sstevel@tonic-gate  * software without specific prior written permission. This software
190Sstevel@tonic-gate  * is provided ``as is'' without express or implied warranty.
200Sstevel@tonic-gate  *
210Sstevel@tonic-gate  * sort.c:  LDAP library entry and value sort routines
220Sstevel@tonic-gate  */
230Sstevel@tonic-gate 
240Sstevel@tonic-gate #include <stdio.h>
250Sstevel@tonic-gate #include <ctype.h>
260Sstevel@tonic-gate #include <string.h>
270Sstevel@tonic-gate #include <stdlib.h>
280Sstevel@tonic-gate #include <time.h>
290Sstevel@tonic-gate #ifdef MACOS
300Sstevel@tonic-gate #include "macos.h"
310Sstevel@tonic-gate #else /* MACOS */
320Sstevel@tonic-gate #ifdef DOS
330Sstevel@tonic-gate #include <malloc.h>
340Sstevel@tonic-gate #include "msdos.h"
350Sstevel@tonic-gate #endif /* DOS */
360Sstevel@tonic-gate #endif /* MACOS */
370Sstevel@tonic-gate 
380Sstevel@tonic-gate #include "lber.h"
390Sstevel@tonic-gate #include "ldap.h"
400Sstevel@tonic-gate #include "ldap-private.h"
410Sstevel@tonic-gate #include "ldap-int.h"
420Sstevel@tonic-gate 
430Sstevel@tonic-gate struct entrything {
440Sstevel@tonic-gate 	char		**et_vals;
450Sstevel@tonic-gate 	LDAPMessage	*et_msg;
460Sstevel@tonic-gate };
470Sstevel@tonic-gate 
480Sstevel@tonic-gate #ifndef NEEDPROTOS
490Sstevel@tonic-gate static int	(*et_cmp_fn)();
500Sstevel@tonic-gate static int	et_cmp();
510Sstevel@tonic-gate #else /* !NEEDPROTOS */
520Sstevel@tonic-gate static int	(*et_cmp_fn)( char *a, char *b );
530Sstevel@tonic-gate #ifdef SUN
540Sstevel@tonic-gate static int	et_cmp( const void *aa, const void *bb);
550Sstevel@tonic-gate #else
560Sstevel@tonic-gate static int	et_cmp( void *aa, void *bb);
570Sstevel@tonic-gate #endif
580Sstevel@tonic-gate #endif /* !NEEDPROTOS */
590Sstevel@tonic-gate 
600Sstevel@tonic-gate int
ldap_sort_strcasecmp(char ** a,char ** b)610Sstevel@tonic-gate ldap_sort_strcasecmp(
620Sstevel@tonic-gate     char	**a,
630Sstevel@tonic-gate     char	**b
640Sstevel@tonic-gate )
650Sstevel@tonic-gate {
660Sstevel@tonic-gate 	return( strcasecmp( *a, *b ) );
670Sstevel@tonic-gate }
680Sstevel@tonic-gate 
690Sstevel@tonic-gate static int
et_cmp(const void * aa,const void * bb)700Sstevel@tonic-gate et_cmp(
710Sstevel@tonic-gate #ifdef SUN
720Sstevel@tonic-gate 	const void	*aa,
730Sstevel@tonic-gate 	const void	*bb
740Sstevel@tonic-gate #else
750Sstevel@tonic-gate 	void	*aa,
760Sstevel@tonic-gate 	void	*bb
770Sstevel@tonic-gate #endif
780Sstevel@tonic-gate )
790Sstevel@tonic-gate {
800Sstevel@tonic-gate 	int			i, rc;
810Sstevel@tonic-gate 	struct entrything	*a = (struct entrything *)aa;
820Sstevel@tonic-gate 	struct entrything	*b = (struct entrything *)bb;
830Sstevel@tonic-gate 
840Sstevel@tonic-gate 	if ( a->et_vals == NULL && b->et_vals == NULL )
850Sstevel@tonic-gate 		return( 0 );
860Sstevel@tonic-gate 	if ( a->et_vals == NULL )
870Sstevel@tonic-gate 		return( -1 );
880Sstevel@tonic-gate 	if ( b->et_vals == NULL )
890Sstevel@tonic-gate 		return( 1 );
900Sstevel@tonic-gate 
910Sstevel@tonic-gate 	for ( i = 0; a->et_vals[i] && b->et_vals[i]; i++ ) {
920Sstevel@tonic-gate 		if ( (rc = (*et_cmp_fn)( a->et_vals[i], b->et_vals[i] ))
930Sstevel@tonic-gate 		    != 0 ) {
940Sstevel@tonic-gate 			return( rc );
950Sstevel@tonic-gate 		}
960Sstevel@tonic-gate 	}
970Sstevel@tonic-gate 
980Sstevel@tonic-gate 	if ( a->et_vals[i] == NULL && b->et_vals[i] == NULL )
990Sstevel@tonic-gate 		return( 0 );
1000Sstevel@tonic-gate 	if ( a->et_vals[i] == NULL )
1010Sstevel@tonic-gate 		return( -1 );
1020Sstevel@tonic-gate 	return( 1 );
1030Sstevel@tonic-gate }
1040Sstevel@tonic-gate 
1050Sstevel@tonic-gate int
ldap_sort_entries(LDAP * ld,LDAPMessage ** chain,char * attr,int (* cmp)())1060Sstevel@tonic-gate ldap_sort_entries(
1070Sstevel@tonic-gate     LDAP	*ld,
1080Sstevel@tonic-gate     LDAPMessage	**chain,
1090Sstevel@tonic-gate     char	*attr,		/* NULL => sort by DN */
1100Sstevel@tonic-gate     int		(*cmp)()
1110Sstevel@tonic-gate )
1120Sstevel@tonic-gate {
1130Sstevel@tonic-gate 	int			i;
1140Sstevel@tonic-gate 	size_t			count;
1150Sstevel@tonic-gate 	struct entrything	*et;
1160Sstevel@tonic-gate 	LDAPMessage		*e, *last;
1170Sstevel@tonic-gate 	LDAPMessage		**ep;
1180Sstevel@tonic-gate 
1190Sstevel@tonic-gate 	count = ldap_count_entries( ld, *chain );
1200Sstevel@tonic-gate 
1210Sstevel@tonic-gate 	if ( (et = (struct entrything *) malloc( count *
1220Sstevel@tonic-gate 	    sizeof(struct entrything) )) == NULL ) {
1230Sstevel@tonic-gate 		ld->ld_errno = LDAP_NO_MEMORY;
1240Sstevel@tonic-gate 		return( -1 );
1250Sstevel@tonic-gate 	}
1260Sstevel@tonic-gate 
1270Sstevel@tonic-gate 	e = *chain;
1280Sstevel@tonic-gate 	for ( i = 0; i < count; i++ ) {
1290Sstevel@tonic-gate 		et[i].et_msg = e;
1300Sstevel@tonic-gate 		if ( attr == NULL ) {
1310Sstevel@tonic-gate 			char	*dn;
1320Sstevel@tonic-gate 
1330Sstevel@tonic-gate 			dn = ldap_get_dn( ld, e );
1340Sstevel@tonic-gate 			et[i].et_vals = ldap_explode_dn( dn, 1 );
1350Sstevel@tonic-gate 			free( dn );
1360Sstevel@tonic-gate 		} else {
1370Sstevel@tonic-gate 			et[i].et_vals = ldap_get_values( ld, e, attr );
1380Sstevel@tonic-gate 		}
1390Sstevel@tonic-gate 
1400Sstevel@tonic-gate 		e = e->lm_chain;
1410Sstevel@tonic-gate 	}
1420Sstevel@tonic-gate 	last = e;
1430Sstevel@tonic-gate 
1440Sstevel@tonic-gate 	et_cmp_fn = cmp;
1450Sstevel@tonic-gate #ifdef SUN
1460Sstevel@tonic-gate 	qsort( et, count, sizeof(struct entrything), et_cmp );
1470Sstevel@tonic-gate #else
1480Sstevel@tonic-gate 	qsort( et, count, sizeof(struct entrything), (void *) et_cmp );
1490Sstevel@tonic-gate #endif
1500Sstevel@tonic-gate 
1510Sstevel@tonic-gate 	ep = chain;
1520Sstevel@tonic-gate 	for ( i = 0; i < count; i++ ) {
1530Sstevel@tonic-gate 		*ep = et[i].et_msg;
1540Sstevel@tonic-gate 		ep = &(*ep)->lm_chain;
1550Sstevel@tonic-gate 
1560Sstevel@tonic-gate 		ldap_value_free( et[i].et_vals );
1570Sstevel@tonic-gate 	}
1580Sstevel@tonic-gate 	*ep = last;
1590Sstevel@tonic-gate 	free( (char *) et );
1600Sstevel@tonic-gate 
1610Sstevel@tonic-gate 	return( 0 );
1620Sstevel@tonic-gate }
1630Sstevel@tonic-gate 
1640Sstevel@tonic-gate /* ARGSUSED */
1650Sstevel@tonic-gate int
ldap_sort_values(LDAP * ld,char ** vals,int (* cmp)())1660Sstevel@tonic-gate ldap_sort_values(
1670Sstevel@tonic-gate     LDAP	*ld,
1680Sstevel@tonic-gate     char	**vals,
1690Sstevel@tonic-gate     int		(*cmp)()
1700Sstevel@tonic-gate )
1710Sstevel@tonic-gate {
1720Sstevel@tonic-gate 	size_t	nel;
1730Sstevel@tonic-gate 
1740Sstevel@tonic-gate 	for ( nel = 0; vals[nel] != NULL; nel++ )
1750Sstevel@tonic-gate 		;	/* NULL */
1760Sstevel@tonic-gate 
1770Sstevel@tonic-gate 	qsort( vals, nel, sizeof(char *), cmp );
1780Sstevel@tonic-gate 
1790Sstevel@tonic-gate 	return( 0 );
1800Sstevel@tonic-gate }
181