14192
|
1 /*
|
|
2 * nmfield.c
|
|
3 *
|
|
4 * Copyright (c) 2004 Novell, Inc. All Rights Reserved.
|
|
5 *
|
|
6 * This program is free software; you can redistribute it and/or modify
|
|
7 * it under the terms of the GNU General Public License as published by
|
|
8 * the Free Software Foundation; version 2 of the License.
|
|
9 *
|
|
10 * This program is distributed in the hope that it will be useful,
|
|
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13 * GNU General Public License for more details.
|
|
14 *
|
|
15 * You should have received a copy of the GNU General Public License
|
|
16 * along with this program; if not, write to the Free Software
|
|
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
18 *
|
|
19 */
|
|
20
|
|
21 #include <string.h>
|
|
22 #include <stdio.h>
|
|
23 #include "nmfield.h"
|
|
24
|
|
25 /* Free a field value and tag */
|
|
26 static void _free_field(NMField * field);
|
|
27
|
|
28 /* Free a field value */
|
|
29 static void _free_field_value(NMField * field);
|
|
30
|
|
31 /* Make a deep copy of the field */
|
|
32 static void _copy_field(NMField * dest, NMField * src);
|
|
33
|
|
34 /* Make a deep copy of the field's value */
|
|
35 static void _copy_field_value(NMField * dest, NMField * src);
|
|
36
|
|
37 /* Create a string from a value -- for debugging */
|
|
38 static char *_value_to_string(NMField * field);
|
|
39
|
|
40 static NMField *
|
|
41 _add_blank_field(NMField *fields, guint32 count)
|
|
42 {
|
|
43 guint32 new_len;
|
|
44
|
|
45 if (fields == NULL) {
|
|
46 fields = g_new0(NMField, 10);
|
|
47 fields->len = 10;
|
|
48 } else {
|
|
49 if (fields->len < count + 2) {
|
|
50 new_len = count + 10;
|
|
51 fields = g_realloc(fields, new_len * sizeof(NMField));
|
|
52 fields->len = new_len;
|
|
53 }
|
|
54 }
|
|
55 return fields;
|
|
56 }
|
|
57
|
|
58 NMField *
|
|
59 nm_field_add_number(NMField * fields, const char *tag, guint32 size, guint8 method,
|
|
60 guint8 flags, guint32 value, guint8 type)
|
|
61 {
|
|
62 guint32 count;
|
|
63 NMField *field;
|
|
64
|
|
65 count = nm_count_fields(fields);
|
|
66 fields = _add_blank_field(fields, count);
|
|
67
|
|
68 field = &(fields[count]);
|
|
69 field->tag = g_strdup(tag);
|
|
70 field->size = size;
|
|
71 field->method = method;
|
|
72 field->flags = flags;
|
|
73 field->value = value;
|
|
74 field->type = type;
|
|
75
|
|
76 /* Null terminate the field array */
|
|
77 field = &((fields)[count + 1]);
|
|
78 field->tag = NULL;
|
|
79 field->value = 0;
|
|
80 field->ptr_value = NULL;
|
|
81
|
|
82 return fields;
|
|
83 }
|
|
84
|
|
85 NMField *
|
|
86 nm_field_add_pointer(NMField * fields, const char *tag, guint32 size, guint8 method,
|
|
87 guint8 flags, gpointer value, guint8 type)
|
|
88 {
|
|
89 guint32 count;
|
|
90 NMField *field = NULL;
|
|
91
|
|
92 count = nm_count_fields(fields);
|
|
93 fields = _add_blank_field(fields, count);
|
|
94
|
|
95 field = &(fields[count]);
|
|
96 field->tag = g_strdup(tag);
|
|
97 field->size = size;
|
|
98 field->method = method;
|
|
99 field->flags = flags;
|
|
100 field->ptr_value = value;
|
|
101 field->type = type;
|
|
102
|
|
103 /* Null terminate the field array */
|
|
104 field = &((fields)[count + 1]);
|
|
105 field->tag = NULL;
|
|
106 field->value = 0;
|
|
107 field->ptr_value = NULL;
|
|
108
|
|
109 return fields;
|
|
110 }
|
|
111
|
|
112 guint32
|
|
113 nm_count_fields(NMField * fields)
|
|
114 {
|
|
115 guint32 count = 0;
|
|
116
|
|
117 if (fields) {
|
|
118 while (fields->tag != NULL) {
|
|
119 count++;
|
|
120 fields++;
|
|
121 }
|
|
122 }
|
|
123
|
|
124 return count;
|
|
125 }
|
|
126
|
|
127 void
|
|
128 nm_free_fields(NMField ** fields)
|
|
129 {
|
|
130 NMField *field = NULL;
|
|
131
|
|
132 if ((fields == NULL) || (*fields == NULL))
|
|
133 return;
|
|
134
|
|
135 field = *fields;
|
|
136
|
|
137 while (field->tag != NULL) {
|
|
138 _free_field(field);
|
|
139 field++;
|
|
140 }
|
|
141
|
|
142 g_free(*fields);
|
|
143 *fields = NULL;
|
|
144 }
|
|
145
|
|
146
|
|
147 static void
|
|
148 _free_field(NMField * field)
|
|
149 {
|
|
150 if (field == NULL)
|
|
151 return;
|
|
152
|
|
153 _free_field_value(field);
|
|
154 g_free(field->tag);
|
|
155 }
|
|
156
|
|
157 static void
|
|
158 _free_field_value(NMField * field)
|
|
159 {
|
|
160 if (field == NULL)
|
|
161 return;
|
|
162
|
|
163 switch (field->type) {
|
|
164 case NMFIELD_TYPE_BINARY:
|
|
165 case NMFIELD_TYPE_UTF8:
|
|
166 case NMFIELD_TYPE_DN:
|
|
167 if (field->ptr_value != NULL) {
|
|
168 g_free(field->ptr_value);
|
|
169 }
|
|
170 break;
|
|
171
|
|
172 case NMFIELD_TYPE_ARRAY:
|
|
173 case NMFIELD_TYPE_MV:
|
|
174 nm_free_fields((NMField **)&field->ptr_value);
|
|
175 break;
|
|
176
|
|
177 default:
|
|
178 break;
|
|
179 }
|
|
180
|
|
181 field->size = 0;
|
|
182 field->ptr_value = NULL;
|
|
183 }
|
|
184
|
|
185 NMField *
|
|
186 nm_locate_field(char *tag, NMField * fields)
|
|
187 {
|
|
188 NMField *ret_fields = NULL;
|
|
189
|
|
190 if ((fields == NULL) || (tag == NULL)) {
|
|
191 return NULL;
|
|
192 }
|
|
193
|
|
194 while (fields->tag != NULL) {
|
|
195 if (g_ascii_strcasecmp(fields->tag, tag) == 0) {
|
|
196 ret_fields = fields;
|
|
197 break;
|
|
198 }
|
|
199 fields++;
|
|
200 }
|
|
201
|
|
202 return ret_fields;
|
|
203 }
|
|
204
|
|
205 NMField *
|
|
206 nm_copy_field_array(NMField * src)
|
|
207 {
|
|
208 NMField *ptr = NULL;
|
|
209 NMField *dest = NULL;
|
|
210 int count;
|
|
211
|
|
212 if (src != NULL) {
|
|
213 count = nm_count_fields(src) + 1;
|
|
214 dest = g_new0(NMField, count);
|
|
215 dest->len = count;
|
|
216 ptr = dest;
|
|
217 while (src->tag != NULL) {
|
|
218 _copy_field(ptr, src);
|
|
219 ptr++;
|
|
220 src++;
|
|
221 }
|
|
222 }
|
|
223
|
|
224 return dest;
|
|
225 }
|
|
226
|
|
227 static void
|
|
228 _copy_field(NMField * dest, NMField * src)
|
|
229 {
|
|
230 dest->type = src->type;
|
|
231 dest->flags = src->flags;
|
|
232 dest->method = src->method;
|
|
233 dest->tag = g_strdup(src->tag);
|
|
234 _copy_field_value(dest, src);
|
|
235 }
|
|
236
|
|
237 static void
|
|
238 _copy_field_value(NMField * dest, NMField * src)
|
|
239 {
|
|
240 dest->type = src->type;
|
|
241 switch (dest->type) {
|
|
242 case NMFIELD_TYPE_UTF8:
|
|
243 case NMFIELD_TYPE_DN:
|
|
244 if (src->size == 0 && src->ptr_value != NULL) {
|
|
245 src->size = strlen((char *) src->ptr_value) + 1;
|
|
246 }
|
|
247 /* fall through */
|
|
248 case NMFIELD_TYPE_BINARY:
|
|
249 if (src->size != 0 && src->ptr_value != NULL) {
|
|
250 dest->ptr_value = g_new0(char, src->size);
|
|
251 memcpy(dest->ptr_value, src->ptr_value, src->size);
|
|
252 }
|
|
253 break;
|
|
254
|
|
255 case NMFIELD_TYPE_ARRAY:
|
|
256 case NMFIELD_TYPE_MV:
|
|
257 dest->ptr_value = nm_copy_field_array((NMField *)src->ptr_value);
|
|
258 break;
|
|
259
|
|
260 default:
|
|
261 /* numeric value */
|
|
262 dest->value = src->value;
|
|
263 break;
|
|
264 }
|
|
265
|
|
266 dest->size = src->size;
|
|
267 }
|
|
268
|
|
269 void
|
|
270 nm_remove_field(NMField * field)
|
|
271 {
|
|
272 NMField *tmp;
|
|
273 guint32 len;
|
|
274
|
|
275 if ((field != NULL) && (field->tag != NULL)) {
|
|
276 _free_field(field);
|
|
277
|
|
278 /* Move fields down */
|
|
279 tmp = field + 1;
|
|
280 while (1) {
|
|
281 /* Don't overwrite the size of the array */
|
|
282 len = field->len;
|
|
283
|
|
284 *field = *tmp;
|
|
285
|
|
286 field->len = len;
|
|
287
|
|
288 if (tmp->tag == NULL)
|
|
289 break;
|
|
290
|
|
291 field++;
|
|
292 tmp++;
|
|
293 }
|
|
294 }
|
|
295 }
|
|
296
|
|
297 void
|
|
298 nm_print_fields(NMField * fields)
|
|
299 {
|
|
300 char *str = NULL;
|
|
301 NMField *field = fields;
|
|
302
|
|
303 if (fields == NULL)
|
|
304 return;
|
|
305
|
|
306 while (field->tag != NULL) {
|
|
307 if (field->type == NMFIELD_TYPE_ARRAY || field->type == NMFIELD_TYPE_MV) {
|
|
308 printf("Subarray START: %s Method = %d\n", field->tag, field->method);
|
|
309 nm_print_fields((NMField *) field->ptr_value);
|
|
310 printf("Subarray END: %s\n", field->tag);
|
|
311 } else {
|
|
312 str = _value_to_string(field);
|
|
313 printf("Tag=%s;Value=%s\n", field->tag, str);
|
|
314 g_free(str);
|
|
315 str = NULL;
|
|
316 }
|
|
317 field++;
|
|
318 }
|
|
319
|
|
320 }
|
|
321
|
|
322 static char *
|
|
323 _value_to_string(NMField * field)
|
|
324 {
|
|
325 char *value = NULL;
|
|
326
|
|
327 if (field == NULL)
|
|
328 return NULL;
|
|
329
|
|
330 /* This is a single value attribute */
|
|
331 if (((field->type == NMFIELD_TYPE_UTF8) ||
|
|
332 (field->type == NMFIELD_TYPE_DN)) && (field->ptr_value != NULL)) {
|
|
333 value = g_strdup((const char *) field->ptr_value);
|
|
334 } else if (field->type == NMFIELD_TYPE_BINARY && field->ptr_value != NULL) {
|
|
335 value = g_new0(char, field->size);
|
|
336 memcpy(value, (const char *) field->ptr_value, field->size);
|
|
337 } else if (field->type == NMFIELD_TYPE_BOOL) {
|
|
338 if (field->value) {
|
|
339 value = g_strdup(NM_FIELD_TRUE);
|
|
340 } else {
|
|
341 value = g_strdup(NM_FIELD_FALSE);
|
|
342 }
|
|
343 } else {
|
|
344 /* assume it is a number */
|
|
345 value = g_new0(char, 20);
|
|
346
|
|
347 switch (field->type) {
|
|
348 case NMFIELD_TYPE_BYTE:
|
|
349 case NMFIELD_TYPE_WORD:
|
|
350 case NMFIELD_TYPE_DWORD:
|
|
351 value = g_strdup_printf("%ld", (long) field->value);
|
|
352 break;
|
|
353
|
|
354 case NMFIELD_TYPE_UBYTE:
|
|
355 case NMFIELD_TYPE_UWORD:
|
|
356 case NMFIELD_TYPE_UDWORD:
|
|
357 value = g_strdup_printf("%lu", (unsigned long) field->value);
|
|
358 break;
|
|
359 }
|
|
360 }
|
|
361
|
|
362 if (value == NULL)
|
|
363 value = g_strdup("NULL");
|
|
364
|
|
365 return value;
|
|
366 }
|