1 /* -*- show-trailing-whitespace: t; indent-tabs: t -*-
2 * Copyright (c) 2003,2004,2005,2006 David Lichteblau
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18 #include "common.h"
19
20 static named_array *
named_array_new(char * name)21 named_array_new(char *name)
22 {
23 named_array *result = xalloc(sizeof(named_array));
24 result->name = name;
25 result->array = g_ptr_array_new();
26 return result;
27 }
28
29 static void
named_array_free(named_array * na)30 named_array_free(named_array *na)
31 {
32 free(na->name);
33 g_ptr_array_free(na->array, 1);
34 free(na);
35 }
36
37 static int
named_array_cmp(named_array * a,named_array * b)38 named_array_cmp(named_array *a, named_array *b)
39 {
40 return strcmp(a->name, b->name);
41 }
42
43 int
named_array_ptr_cmp(const void * aa,const void * bb)44 named_array_ptr_cmp(const void *aa, const void *bb)
45 {
46 named_array *a = *((named_array **) aa);
47 named_array *b = *((named_array **) bb);
48 return named_array_cmp(a, b);
49 }
50
51 /*
52 * entry
53 */
54 tentry *
entry_new(char * dn)55 entry_new(char *dn)
56 {
57 return (tentry *) named_array_new(dn);
58 }
59
60 void
entry_free(tentry * entry)61 entry_free(tentry *entry)
62 {
63 GPtrArray *attributes = entry_attributes(entry);
64 int n = attributes->len;
65 int i;
66
67 for (i = 0; i < n; i++)
68 attribute_free(g_ptr_array_index(attributes, i));
69 named_array_free((named_array *) entry);
70 }
71
72 int
entry_cmp(tentry * e,tentry * f)73 entry_cmp(tentry *e, tentry *f)
74 {
75 return named_array_cmp((named_array *) e, (named_array *) f);
76 }
77
78
79 /*
80 * value
81 */
82 /*
83 * attribute
84 */
85 tattribute *
attribute_new(char * ad)86 attribute_new(char *ad)
87 {
88 return (tattribute *) named_array_new(ad);
89 }
90
91 void
attribute_free(tattribute * attribute)92 attribute_free(tattribute *attribute)
93 {
94 GPtrArray *values = attribute_values(attribute);
95 int n = values->len;
96 int i;
97
98 for (i = 0; i < n; i++)
99 g_array_free(g_ptr_array_index(values, i), 1);
100 named_array_free((named_array *) attribute);
101 }
102
103 int
attribute_cmp(tattribute * a,tattribute * b)104 attribute_cmp(tattribute *a, tattribute *b)
105 {
106 return named_array_cmp((named_array *) a, (named_array *) b);
107 }
108
109
110 /*
111 * misc
112 */
113 tattribute *
entry_find_attribute(tentry * entry,char * ad,int createp)114 entry_find_attribute(tentry *entry, char *ad, int createp)
115 {
116 GPtrArray *attributes = entry_attributes(entry);
117 tattribute *attribute = 0;
118 int i;
119
120 for (i = 0; i < attributes->len; i++) {
121 tattribute *a = g_ptr_array_index(attributes, i);
122 if (!strcmp(attribute_ad(a), ad)) {
123 attribute = a;
124 break;
125 }
126 }
127 if (!attribute && createp) {
128 attribute = attribute_new(xdup(ad));
129 g_ptr_array_add(attributes, attribute);
130 }
131
132 return attribute;
133 }
134
135 void
attribute_append_value(tattribute * attribute,char * data,int n)136 attribute_append_value(tattribute *attribute, char *data, int n)
137 {
138 GArray *value = g_array_sized_new(0, 0, 1, n);
139 g_array_append_vals(value, data, n);
140 g_ptr_array_add(attribute_values(attribute), value);
141 }
142
143 int
attribute_find_value(tattribute * attribute,char * data,int n)144 attribute_find_value(tattribute *attribute, char *data, int n)
145 {
146 int i;
147 GPtrArray *values = attribute_values(attribute);
148 for (i = 0; i < values->len; i++) {
149 GArray *value = values->pdata[i];
150 if (value->len == n && !memcmp(value->data, data, n))
151 return i;
152 }
153 return -1;
154 }
155
156 int
attribute_remove_value(tattribute * a,char * data,int n)157 attribute_remove_value(tattribute *a, char *data, int n)
158 {
159 int i = attribute_find_value(a, data, n);
160 if (i == -1) return i;
161 g_array_free(g_ptr_array_remove_index_fast(attribute_values(a), i), 1);
162 return 0;
163 }
164
165 /*
166 * Aus irgendwelchen Gruenden habe ich mal beschlossen, GArrays mit chars drin
167 * statt GStrings zu nehmen fuer die Attributwerte. Wie unpraktisch.
168 */
169 char *
array2string(GArray * av)170 array2string(GArray *av)
171 {
172 int n = av->len;
173 char *str = xalloc(n + 1);
174 memcpy(str, av->data, n);
175 str[n] = 0;
176 return str;
177 }
178
179 /*
180 * allocate a new berval and copy LEN bytes of DATA into it
181 */
182 static struct berval *
dup2berval(char * data,int len)183 dup2berval(char *data, int len)
184 {
185 struct berval *bv = xalloc(sizeof(struct berval));
186 bv->bv_val = xalloc(len);
187 memcpy(bv->bv_val, data, len);
188 bv->bv_len = len;
189 return bv;
190 }
191
192 void
xfree_berval(struct berval * bv)193 xfree_berval(struct berval *bv)
194 {
195 free(bv->bv_val);
196 free(bv);
197 }
198
199 struct berval *
string2berval(GArray * s)200 string2berval(GArray *s)
201 {
202 return dup2berval(s->data, s->len);
203 }
204
205 struct berval *
gstring2berval(GString * s)206 gstring2berval(GString *s)
207 {
208 return dup2berval(s->str, s->len);
209 }
210
211 LDAPMod *
attribute2mods(tattribute * attribute)212 attribute2mods(tattribute *attribute)
213 {
214 GPtrArray *values = attribute_values(attribute);
215 LDAPMod *m = xalloc(sizeof(LDAPMod));
216 int j;
217
218 m->mod_op = LDAP_MOD_BVALUES;
219 m->mod_type = xdup(attribute_ad(attribute));
220 m->mod_bvalues = xalloc(
221 (1 + values->len) * sizeof(struct berval *));
222
223 for (j = 0; j < values->len; j++)
224 m->mod_bvalues[j]
225 = string2berval(g_ptr_array_index(values, j));
226 m->mod_bvalues[j] = 0;
227 return m;
228 }
229
230 LDAPMod **
entry2mods(tentry * entry)231 entry2mods(tentry *entry)
232 {
233 GPtrArray *attributes = entry_attributes(entry);
234 LDAPMod **result = xalloc((attributes->len + 1) * sizeof(LDAPMod *));
235 int i;
236
237 for (i = 0; i < attributes->len; i++)
238 result[i] = attribute2mods(g_ptr_array_index(attributes, i));
239 result[i] = 0;
240 return result;
241 }
242