]> git.sur5r.net Git - openldap/blob - libraries/libldap/sort.c
6738fba022c48b576fccddff005b9e2f0c544fdb
[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         int             (*et_cmp_fn) LDAP_P((const char *a, const char *b));
31 };
32
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 = a->et_cmp_fn( a->et_vals[i], b->et_vals[i] )) != 0 ) {
64                         return( rc );
65                 }
66         }
67
68         if ( a->et_vals[i] == NULL && b->et_vals[i] == NULL )
69                 return( 0 );
70         if ( a->et_vals[i] == NULL )
71                 return( -1 );
72         return( 1 );
73 }
74
75 int
76 ldap_sort_entries(
77     LDAP        *ld,
78     LDAPMessage **chain,
79     char        *attr,          /* NULL => sort by DN */
80     int         (*cmp) (const char *, const char *)
81 )
82 {
83         int                     i, count;
84         struct entrything       *et;
85         LDAPMessage             *e, *last;
86         LDAPMessage             **ep;
87
88         count = ldap_count_entries( ld, *chain );
89
90         if ( (et = (struct entrything *) malloc( count *
91             sizeof(struct entrything) )) == NULL ) {
92                 ld->ld_errno = LDAP_NO_MEMORY;
93                 return( -1 );
94         }
95
96         e = *chain;
97         for ( i = 0; i < count; i++ ) {
98                 et[i].et_cmp_fn = cmp;
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         qsort( et, count, sizeof(struct entrything), et_cmp );
115
116         ep = chain;
117         for ( i = 0; i < count; i++ ) {
118                 *ep = et[i].et_msg;
119                 ep = &(*ep)->lm_chain;
120
121                 ldap_value_free( et[i].et_vals );
122         }
123         *ep = last;
124         free( (char *) et );
125
126         return( 0 );
127 }
128
129 int
130 ldap_sort_values(
131     LDAP        *ld,
132     char        **vals,
133     int         (*cmp) (const void *, const void *)
134 )
135 {
136         int     nel;
137
138         for ( nel = 0; vals[nel] != NULL; nel++ )
139                 ;       /* NULL */
140
141         qsort( vals, nel, sizeof(char *), cmp );
142
143         return( 0 );
144 }