home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ldapsdk.zip / libraries / libldap / sort.c < prev    next >
C/C++ Source or Header  |  2000-06-14  |  3KB  |  162 lines

  1. /* $OpenLDAP: pkg/ldap/libraries/libldap/sort.c,v 1.13.8.2 2000/06/13 17:57:20 kurt Exp $ */
  2. /*
  3.  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  4.  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  5.  */
  6. /* Portions
  7.  * Copyright (c) 1994 Regents of the University of Michigan.
  8.  * All rights reserved.
  9.  *
  10.  * Redistribution and use in source and binary forms are permitted
  11.  * provided that this notice is preserved and that due credit is given
  12.  * to the University of Michigan at Ann Arbor. The name of the University
  13.  * may not be used to endorse or promote products derived from this
  14.  * software without specific prior written permission. This software
  15.  * is provided ``as is'' without express or implied warranty.
  16.  *
  17.  * sort.c:  LDAP library entry and value sort routines
  18.  */
  19.  
  20. #include "portable.h"
  21.  
  22. #include <stdio.h>
  23. #include <ac/stdlib.h>
  24.  
  25. #include <ac/ctype.h>
  26. #include <ac/string.h>
  27. #include <ac/time.h>
  28.  
  29.  
  30. #include "ldap-int.h"
  31.  
  32. struct entrything {
  33.     char        **et_vals;
  34.     LDAPMessage    *et_msg;
  35.     int         (*et_cmp_fn) LDAP_P((const char *a, const char *b));
  36. };
  37.  
  38. static int    et_cmp LDAP_P(( const void *aa, const void *bb));
  39.  
  40.  
  41. int
  42. ldap_sort_strcasecmp(
  43.     LDAP_CONST void    *a,
  44.     LDAP_CONST void    *b
  45. )
  46. {
  47.     return( strcasecmp( *(char *const *)a, *(char *const *)b ) );
  48. }
  49.  
  50. static int
  51. et_cmp(
  52.     const void    *aa,
  53.     const void    *bb
  54. )
  55. {
  56.     int            i, rc;
  57.     const struct entrything    *a = (const struct entrything *)aa;
  58.     const struct entrything    *b = (const struct entrything *)bb;
  59.  
  60.     if ( a->et_vals == NULL && b->et_vals == NULL )
  61.         return( 0 );
  62.     if ( a->et_vals == NULL )
  63.         return( -1 );
  64.     if ( b->et_vals == NULL )
  65.         return( 1 );
  66.  
  67.     for ( i = 0; a->et_vals[i] && b->et_vals[i]; i++ ) {
  68.         if ( (rc = a->et_cmp_fn( a->et_vals[i], b->et_vals[i] )) != 0 ) {
  69.             return( rc );
  70.         }
  71.     }
  72.  
  73.     if ( a->et_vals[i] == NULL && b->et_vals[i] == NULL )
  74.         return( 0 );
  75.     if ( a->et_vals[i] == NULL )
  76.         return( -1 );
  77.     return( 1 );
  78. }
  79.  
  80. int
  81. ldap_sort_entries(
  82.     LDAP    *ld,
  83.     LDAPMessage    **chain,
  84.     LDAP_CONST char    *attr,        /* NULL => sort by DN */
  85.     int        (*cmp) (LDAP_CONST  char *, LDAP_CONST char *)
  86. )
  87. {
  88.     int            i, count;
  89.     struct entrything    *et;
  90.     LDAPMessage        *e, *last;
  91.     LDAPMessage        **ep;
  92.  
  93.     count = ldap_count_entries( ld, *chain );
  94.  
  95.  
  96.     if ( count < 0 ) {
  97.         if( ld != NULL ) {
  98.             ld->ld_errno = LDAP_PARAM_ERROR;
  99.         }
  100.         return -1;
  101.  
  102.     } else if ( count < 2 ) {
  103.         /* zero or one entries -- already sorted! */
  104.         return 0;
  105.     }
  106.  
  107.     if ( (et = (struct entrything *) LDAP_MALLOC( count *
  108.         sizeof(struct entrything) )) == NULL ) {
  109.         ld->ld_errno = LDAP_NO_MEMORY;
  110.         return( -1 );
  111.     }
  112.  
  113.     e = *chain;
  114.     for ( i = 0; i < count; i++ ) {
  115.         et[i].et_cmp_fn = cmp;
  116.         et[i].et_msg = e;
  117.         if ( attr == NULL ) {
  118.             char    *dn;
  119.  
  120.             dn = ldap_get_dn( ld, e );
  121.             et[i].et_vals = ldap_explode_dn( dn, 1 );
  122.             LDAP_FREE( dn );
  123.         } else {
  124.             et[i].et_vals = ldap_get_values( ld, e, attr );
  125.         }
  126.  
  127.         e = e->lm_chain;
  128.     }
  129.     last = e;
  130.  
  131.     qsort( et, count, sizeof(struct entrything), et_cmp );
  132.  
  133.     ep = chain;
  134.     for ( i = 0; i < count; i++ ) {
  135.         *ep = et[i].et_msg;
  136.         ep = &(*ep)->lm_chain;
  137.  
  138.         LDAP_VFREE( et[i].et_vals );
  139.     }
  140.     *ep = last;
  141.     LDAP_FREE( (char *) et );
  142.  
  143.     return( 0 );
  144. }
  145.  
  146. int
  147. ldap_sort_values(
  148.     LDAP    *ld,
  149.     char    **vals,
  150.     int        (*cmp) (LDAP_CONST void *, LDAP_CONST void *)
  151. )
  152. {
  153.     int    nel;
  154.  
  155.     for ( nel = 0; vals[nel] != NULL; nel++ )
  156.         ;    /* NULL */
  157.  
  158.     qsort( vals, nel, sizeof(char *), cmp );
  159.  
  160.     return( 0 );
  161. }
  162.