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