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