/* * Copyright (c) 1994 Regents of the University of Michigan. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that this notice is preserved and that due credit is given * to the University of Michigan at Ann Arbor. The name of the University * may not be used to endorse or promote products derived from this * software without specific prior written permission. This software * is provided ``as is'' without express or implied warranty. * * sort.c: LDAP library entry and value sort routines */ #include #include #include #include #ifdef MACOS #include "macos.h" #else /* MACOS */ #ifdef DOS #include #include "msdos.h" #endif /* DOS */ #endif /* MACOS */ #include "lber.h" #include "ldap.h" struct entrything { char **et_vals; LDAPMessage *et_msg; }; #ifndef NEEDPROTOS static int (*et_cmp_fn)(); static int et_cmp(); #else /* !NEEDPROTOS */ static int (*et_cmp_fn)( char *a, char *b ); static int et_cmp( void *aa, void *bb); #endif /* !NEEDPROTOS */ int ldap_sort_strcasecmp( char **a, char **b ) { return( strcasecmp( *a, *b ) ); } static int et_cmp( void *aa, void *bb ) { int i, rc; struct entrything *a = (struct entrything *)aa; struct entrything *b = (struct entrything *)bb; if ( a->et_vals == NULL && b->et_vals == NULL ) return( 0 ); if ( a->et_vals == NULL ) return( -1 ); if ( b->et_vals == NULL ) return( 1 ); for ( i = 0; a->et_vals[i] && b->et_vals[i]; i++ ) { if ( (rc = (*et_cmp_fn)( a->et_vals[i], b->et_vals[i] )) != 0 ) { return( rc ); } } if ( a->et_vals[i] == NULL && b->et_vals[i] == NULL ) return( 0 ); if ( a->et_vals[i] == NULL ) return( -1 ); return( 1 ); } int ldap_sort_entries( LDAP *ld, LDAPMessage **chain, char *attr, /* NULL => sort by DN */ int (*cmp)() ) { int i, count; struct entrything *et; LDAPMessage *e, *last; LDAPMessage **ep; count = ldap_count_entries( ld, *chain ); if ( (et = (struct entrything *) malloc( count * sizeof(struct entrything) )) == NULL ) { ld->ld_errno = LDAP_NO_MEMORY; return( -1 ); } e = *chain; for ( i = 0; i < count; i++ ) { et[i].et_msg = e; if ( attr == NULL ) { char *dn; dn = ldap_get_dn( ld, e ); et[i].et_vals = ldap_explode_dn( dn, 1 ); free( dn ); } else { et[i].et_vals = ldap_get_values( ld, e, attr ); } e = e->lm_chain; } last = e; et_cmp_fn = cmp; qsort( et, count, sizeof(struct entrything), (void *) et_cmp ); ep = chain; for ( i = 0; i < count; i++ ) { *ep = et[i].et_msg; ep = &(*ep)->lm_chain; ldap_value_free( et[i].et_vals ); } *ep = last; free( (char *) et ); return( 0 ); } int ldap_sort_values( LDAP *ld, char **vals, int (*cmp)() ) { int nel; for ( nel = 0; vals[nel] != NULL; nel++ ) ; /* NULL */ qsort( vals, nel, sizeof(char *), cmp ); return( 0 ); }