8675
|
1 /*
|
|
2 * nmfield.c
|
|
3 *
|
|
4 * Copyright © 2004 Unpublished Work of Novell, Inc. All Rights Reserved.
|
|
5 *
|
|
6 * THIS WORK IS AN UNPUBLISHED WORK OF NOVELL, INC. NO PART OF THIS WORK MAY BE
|
|
7 * USED, PRACTICED, PERFORMED, COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED,
|
|
8 * ABRIDGED, CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST, TRANSFORMED
|
|
9 * OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF NOVELL, INC. ANY USE OR
|
|
10 * EXPLOITATION OF THIS WORK WITHOUT AUTHORIZATION COULD SUBJECT THE PERPETRATOR
|
|
11 * TO CRIMINAL AND CIVIL LIABILITY.
|
|
12 *
|
|
13 * AS BETWEEN [GAIM] AND NOVELL, NOVELL GRANTS [GAIM] THE RIGHT TO REPUBLISH THIS
|
|
14 * WORK UNDER THE GPL (GNU GENERAL PUBLIC LICENSE) WITH ALL RIGHTS AND LICENSES
|
|
15 * THEREUNDER. IF YOU HAVE RECEIVED THIS WORK DIRECTLY OR INDIRECTLY FROM [GAIM]
|
|
16 * AS PART OF SUCH A REPUBLICATION, YOU HAVE ALL RIGHTS AND LICENSES GRANTED BY
|
|
17 * [GAIM] UNDER THE GPL. IN CONNECTION WITH SUCH A REPUBLICATION, IF ANYTHING IN
|
|
18 * THIS NOTICE CONFLICTS WITH THE TERMS OF THE GPL, SUCH TERMS PREVAIL.
|
|
19 *
|
|
20 */
|
|
21
|
|
22 #include <string.h>
|
|
23 #include <stdio.h>
|
|
24 #include "nmfield.h"
|
|
25
|
|
26 /* Free a field value and tag */
|
|
27 static void _free_field(NMField * field);
|
|
28
|
|
29 /* Free a field value */
|
|
30 static void _free_field_value(NMField * field);
|
|
31
|
|
32 /* Make a deep copy of the field */
|
|
33 static void _copy_field(NMField * dest, NMField * src);
|
|
34
|
|
35 /* Make a deep copy of the field's value */
|
|
36 static void _copy_field_value(NMField * dest, NMField * src);
|
|
37
|
|
38 /* Create a string from a value -- for debugging */
|
|
39 static char *_value_to_string(NMField * field);
|
|
40
|
|
41 NMField *
|
|
42 nm_add_field(NMField * fields, char *tag, guint32 size, guint8 method,
|
|
43 guint8 flags, guint32 value, guint8 type)
|
|
44 {
|
|
45 guint32 count, new_len;
|
|
46 NMField *field = NULL;
|
|
47
|
|
48 if (fields == NULL) {
|
|
49 fields = g_new0(NMField, 10);
|
|
50 fields->len = 10;
|
|
51 count = 0;
|
|
52 } else {
|
|
53 count = nm_count_fields(fields);
|
|
54 if (fields->len < count + 2) {
|
|
55 new_len = count + 10;
|
|
56 fields = g_realloc(fields, new_len * sizeof(NMField));
|
|
57 fields->len = new_len;
|
|
58 }
|
|
59 }
|
|
60
|
|
61 field = &(fields[count]);
|
|
62 field->tag = g_strdup(tag);
|
|
63 field->size = size;
|
|
64 field->method = method;
|
|
65 field->flags = flags;
|
|
66 field->value = value;
|
|
67 field->type = type;
|
|
68
|
|
69 /* Null terminate the field array */
|
|
70 field = &((fields)[count + 1]);
|
|
71 field->tag = NULL;
|
|
72 field->value = 0;
|
|
73
|
|
74 return fields;
|
|
75 }
|
|
76
|
|
77 guint32
|
|
78 nm_count_fields(NMField * fields)
|
|
79 {
|
|
80 guint32 count = 0;
|
|
81
|
|
82 if (fields) {
|
|
83 while (fields->tag != NULL) {
|
|
84 count++;
|
|
85 fields++;
|
|
86 }
|
|
87 }
|
|
88
|
|
89 return count;
|
|
90 }
|
|
91
|
|
92 void
|
|
93 nm_free_fields(NMField ** fields)
|
|
94 {
|
|
95 NMField *field = NULL;
|
|
96
|
|
97 if ((fields == NULL) || (*fields == NULL))
|
|
98 return;
|
|
99
|
|
100 field = *fields;
|
|
101
|
|
102 while (field->tag != NULL) {
|
|
103 _free_field(field);
|
|
104 field++;
|
|
105 }
|
|
106
|
|
107 g_free(*fields);
|
|
108 *fields = NULL;
|
|
109 }
|
|
110
|
|
111
|
|
112 static void
|
|
113 _free_field(NMField * field)
|
|
114 {
|
|
115 if (field == NULL)
|
|
116 return;
|
|
117
|
|
118 _free_field_value(field);
|
|
119 g_free(field->tag);
|
|
120 }
|
|
121
|
|
122 static void
|
|
123 _free_field_value(NMField * field)
|
|
124 {
|
|
125 if (field == NULL)
|
|
126 return;
|
|
127
|
|
128 switch (field->type) {
|
|
129 case NMFIELD_TYPE_BINARY:
|
|
130 case NMFIELD_TYPE_UTF8:
|
|
131 case NMFIELD_TYPE_DN:
|
|
132 if ((gpointer) field->value != NULL) {
|
|
133 g_free((gpointer) field->value);
|
|
134 }
|
|
135 break;
|
|
136
|
|
137 case NMFIELD_TYPE_ARRAY:
|
|
138 case NMFIELD_TYPE_MV:
|
|
139 nm_free_fields((NMField **) & field->value);
|
|
140 break;
|
|
141
|
|
142 default:
|
|
143 break;
|
|
144 }
|
|
145
|
|
146 field->size = 0;
|
|
147 field->value = 0;
|
|
148 }
|
|
149
|
|
150 NMField *
|
|
151 nm_locate_field(char *tag, NMField * fields)
|
|
152 {
|
|
153 NMField *ret_fields = NULL;
|
|
154
|
|
155 if ((fields == NULL) || (tag == NULL)) {
|
|
156 return NULL;
|
|
157 }
|
|
158
|
|
159 while (fields->tag != NULL) {
|
|
160 if (g_ascii_strcasecmp(fields->tag, tag) == 0) {
|
|
161 ret_fields = fields;
|
|
162 break;
|
|
163 }
|
|
164 fields++;
|
|
165 }
|
|
166
|
|
167 return ret_fields;
|
|
168 }
|
|
169
|
|
170 NMField *
|
|
171 nm_copy_field_array(NMField * src)
|
|
172 {
|
|
173 NMField *ptr = NULL;
|
|
174 NMField *dest = NULL;
|
|
175 int count;
|
|
176
|
|
177 if (src != NULL) {
|
|
178 count = nm_count_fields(src) + 1;
|
|
179 dest = g_new0(NMField, count);
|
|
180 dest->len = count;
|
|
181 ptr = dest;
|
|
182 while (src->tag != NULL) {
|
|
183 _copy_field(ptr, src);
|
|
184 ptr++;
|
|
185 src++;
|
|
186 }
|
|
187 }
|
|
188
|
|
189 return dest;
|
|
190 }
|
|
191
|
|
192 static void
|
|
193 _copy_field(NMField * dest, NMField * src)
|
|
194 {
|
|
195 dest->type = src->type;
|
|
196 dest->flags = src->flags;
|
|
197 dest->method = src->method;
|
|
198 dest->tag = g_strdup(src->tag);
|
|
199 _copy_field_value(dest, src);
|
|
200 }
|
|
201
|
|
202 static void
|
|
203 _copy_field_value(NMField * dest, NMField * src)
|
|
204 {
|
|
205 dest->type = src->type;
|
|
206 switch (dest->type) {
|
|
207 case NMFIELD_TYPE_UTF8:
|
|
208 case NMFIELD_TYPE_DN:
|
|
209 if (src->size == 0 && src->value != 0) {
|
|
210 src->size = strlen((char *) src->value) + 1;
|
|
211 }
|
|
212 /* fall through */
|
|
213 case NMFIELD_TYPE_BINARY:
|
|
214 if (src->size != 0 && src->value != 0) {
|
|
215 dest->value = (guint32) g_new0(char, src->size);
|
|
216
|
|
217 memcpy((gpointer) dest->value, (gpointer) src->value, src->size);
|
|
218 }
|
|
219 break;
|
|
220
|
|
221 case NMFIELD_TYPE_ARRAY:
|
|
222 case NMFIELD_TYPE_MV:
|
|
223 dest->value = 0;
|
|
224 dest->value = (guint32) nm_copy_field_array((NMField *) src->value);
|
|
225 break;
|
|
226
|
|
227 default:
|
|
228 /* numeric value */
|
|
229 dest->value = src->value;
|
|
230 break;
|
|
231 }
|
|
232
|
|
233 dest->size = src->size;
|
|
234 }
|
|
235
|
|
236 void
|
|
237 nm_remove_field(NMField * field)
|
|
238 {
|
|
239 NMField *tmp;
|
|
240 guint32 len;
|
|
241
|
|
242 if ((field != NULL) && (field->tag != NULL)) {
|
|
243 _free_field(field);
|
|
244
|
|
245 /* Move fields down */
|
|
246 tmp = field + 1;
|
|
247 while (1) {
|
|
248 /* Don't overwrite the size of the array */
|
|
249 len = field->len;
|
|
250
|
|
251 *field = *tmp;
|
|
252
|
|
253 field->len = len;
|
|
254
|
|
255 if (tmp->tag == NULL)
|
|
256 break;
|
|
257
|
|
258 field++;
|
|
259 tmp++;
|
|
260 }
|
|
261 }
|
|
262 }
|
|
263
|
|
264 void
|
|
265 nm_print_fields(NMField * fields)
|
|
266 {
|
|
267 char *str = NULL;
|
|
268 NMField *field = fields;
|
|
269
|
|
270 if (fields == NULL)
|
|
271 return;
|
|
272
|
|
273 while (field->tag != NULL) {
|
|
274 if (field->type == NMFIELD_TYPE_ARRAY || field->type == NMFIELD_TYPE_MV) {
|
|
275 printf("Subarray START: %s Method = %d\n", field->tag, field->method);
|
|
276 nm_print_fields((NMField *) field->value);
|
|
277 printf("Subarray END: %s\n", field->tag);
|
|
278 } else {
|
|
279 str = _value_to_string(field);
|
|
280 printf("Tag=%s;Value=%s\n", field->tag, str);
|
|
281 g_free(str);
|
|
282 str = NULL;
|
|
283 }
|
|
284 field++;
|
|
285 }
|
|
286
|
|
287 }
|
|
288
|
|
289 static char *
|
|
290 _value_to_string(NMField * field)
|
|
291 {
|
|
292 char *value = NULL;
|
|
293
|
|
294 if (field == NULL)
|
|
295 return NULL;
|
|
296
|
|
297 /* This is a single value attribute */
|
|
298 if (((field->type == NMFIELD_TYPE_UTF8) ||
|
|
299 (field->type == NMFIELD_TYPE_DN)) && (field->value != 0)) {
|
|
300 value = g_strdup((const char *) field->value);
|
|
301 } else if (field->type == NMFIELD_TYPE_BINARY && field->value != 0) {
|
|
302 value = g_new0(char, field->size);
|
|
303
|
|
304 memcpy(value, (const char *) field->value, field->size);
|
|
305 } else if (field->type == NMFIELD_TYPE_BOOL) {
|
|
306 if (field->value) {
|
|
307 value = g_strdup(NM_FIELD_TRUE);
|
|
308 } else {
|
|
309 value = g_strdup(NM_FIELD_FALSE);
|
|
310 }
|
|
311 } else {
|
|
312 /* assume it is a number */
|
|
313 value = g_new0(char, 20);
|
|
314
|
|
315 switch (field->type) {
|
|
316 case NMFIELD_TYPE_BYTE:
|
|
317 case NMFIELD_TYPE_WORD:
|
|
318 case NMFIELD_TYPE_DWORD:
|
|
319 value = g_strdup_printf("%ld", (long) field->value);
|
|
320 break;
|
|
321
|
|
322 case NMFIELD_TYPE_UBYTE:
|
|
323 case NMFIELD_TYPE_UWORD:
|
|
324 case NMFIELD_TYPE_UDWORD:
|
|
325 value = g_strdup_printf("%lu", (unsigned long) field->value);
|
|
326 break;
|
|
327 }
|
|
328 }
|
|
329
|
|
330 if (value == NULL)
|
|
331 value = g_strdup("NULL");
|
|
332
|
|
333 return value;
|
|
334 }
|