]> git.sur5r.net Git - openldap/blob - libraries/libldap/sort.c
2ac3c31a81b6f51588a6764fbd10d6fde843b98e
[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 #include "lber.h"
25 #include "ldap.h"
26
27
28 struct entrything {
29         char            **et_vals;
30         LDAPMessage     *et_msg;
31 };
32
33 static int      (*et_cmp_fn) LDAP_P(( char *a, char *b ));
34 static int      et_cmp LDAP_P(( void *aa, void *bb));
35
36
37 int
38 ldap_sort_strcasecmp(
39     char        **a,
40     char        **b
41 )
42 {
43         return( strcasecmp( *a, *b ) );
44 }
45
46 static int
47 et_cmp(
48         void    *aa,
49         void    *bb
50 )
51 {
52         int                     i, rc;
53         struct entrything       *a = (struct entrything *)aa;
54         struct entrything       *b = (struct entrything *)bb;
55
56         if ( a->et_vals == NULL && b->et_vals == NULL )
57                 return( 0 );
58         if ( a->et_vals == NULL )
59                 return( -1 );
60         if ( b->et_vals == NULL )
61                 return( 1 );
62
63         for ( i = 0; a->et_vals[i] && b->et_vals[i]; i++ ) {
64                 if ( (rc = (*et_cmp_fn)( a->et_vals[i], b->et_vals[i] ))
65                     != 0 ) {
66                         return( rc );
67                 }
68         }
69
70         if ( a->et_vals[i] == NULL && b->et_vals[i] == NULL )
71                 return( 0 );
72         if ( a->et_vals[i] == NULL )
73                 return( -1 );
74         return( 1 );
75 }
76
77 int
78 ldap_sort_entries(
79     LDAP        *ld,
80     LDAPMessage **chain,
81     char        *attr,          /* NULL => sort by DN */
82     int         (*cmp) LDAP_P((char *, char *))
83 )
84 {
85         int                     i, count;
86         struct entrything       *et;
87         LDAPMessage             *e, *last;
88         LDAPMessage             **ep;
89
90         count = ldap_count_entries( ld, *chain );
91
92         if ( (et = (struct entrything *) malloc( count *
93             sizeof(struct entrything) )) == NULL ) {
94                 ld->ld_errno = LDAP_NO_MEMORY;
95                 return( -1 );
96         }
97
98         e = *chain;
99         for ( i = 0; i < count; i++ ) {
100                 et[i].et_msg = e;
101                 if ( attr == NULL ) {
102                         char    *dn;
103
104                         dn = ldap_get_dn( ld, e );
105                         et[i].et_vals = ldap_explode_dn( dn, 1 );
106                         free( dn );
107                 } else {
108                         et[i].et_vals = ldap_get_values( ld, e, attr );
109                 }
110
111                 e = e->lm_chain;
112         }
113         last = e;
114
115         et_cmp_fn = cmp;
116         qsort( et, count, sizeof(struct entrything), et_cmp );
117
118         ep = chain;
119         for ( i = 0; i < count; i++ ) {
120                 *ep = et[i].et_msg;
121                 ep = &(*ep)->lm_chain;
122
123                 ldap_value_free( et[i].et_vals );
124         }
125         *ep = last;
126         free( (char *) et );
127
128         return( 0 );
129 }
130
131 int
132 ldap_sort_values(
133     LDAP        *ld,
134     char        **vals,
135     int         (*cmp) LDAP_P((const void *, const void *))
136 )
137 {
138         int     nel;
139
140         for ( nel = 0; vals[nel] != NULL; nel++ )
141                 ;       /* NULL */
142
143         qsort( vals, nel, sizeof(char *), cmp );
144
145         return( 0 );
146 }