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