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