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