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 43struct entrything { 44 char **et_vals; 45 LDAPMessage *et_msg; 46}; 47 48#ifndef NEEDPROTOS 49static int (*et_cmp_fn)(); 50static int et_cmp(); 51#else /* !NEEDPROTOS */ 52static int (*et_cmp_fn)( char *a, char *b ); 53#ifdef SUN 54static int et_cmp( const void *aa, const void *bb); 55#else 56static int et_cmp( void *aa, void *bb); 57#endif 58#endif /* !NEEDPROTOS */ 59 60int 61ldap_sort_strcasecmp( 62 char **a, 63 char **b 64) 65{ 66 return( strcasecmp( *a, *b ) ); 67} 68 69static int 70et_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 105int 106ldap_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 */ 165int 166ldap_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