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