s3:lib: Fix a typo in MACRO
[Samba.git] / source3 / rpc_server / mdssvc / dalloc.c
blob44db9f8692564ee409719f84200c7910843cedbe
1 /*
2 Copyright (c) Ralph Boehme 2012-2014
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 3 of the License, or
7 (at your option) any later version.
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.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #include "replace.h"
19 #include <talloc.h>
20 #include "dalloc.h"
21 #include "marshalling.h"
22 #include "lib/util/charset/charset.h"
23 #include "lib/util/talloc_stack.h"
24 #include "system/time.h"
26 /**
27 * Dynamic Datastore
28 **/
29 struct dalloc_ctx {
30 void **dd_talloc_array;
33 void *_dalloc_new(TALLOC_CTX *mem_ctx, const char *type)
35 void *p;
37 p = talloc_zero(mem_ctx, DALLOC_CTX);
38 if (p == NULL) {
39 return NULL;
41 talloc_set_name_const(p, type);
43 return p;
46 int _dalloc_add_talloc_chunk(DALLOC_CTX *dd, void *obj, const char *type, size_t size)
48 size_t array_len = talloc_array_length(dd->dd_talloc_array);
50 dd->dd_talloc_array = talloc_realloc(dd,
51 dd->dd_talloc_array,
52 void *,
53 array_len + 1);
54 if (dd->dd_talloc_array == NULL) {
55 return -1;
58 if (size != 0) {
59 void *p;
61 p = talloc_named_const(dd->dd_talloc_array, size, type);
62 if (p == NULL) {
63 return -1;
65 memcpy(p, obj, size);
66 obj = p;
67 } else {
68 _talloc_get_type_abort(obj, type, __location__);
71 dd->dd_talloc_array[array_len] = obj;
73 return 0;
76 /* Get number of elements, returns 0 if the structure is empty or not initialized */
77 size_t dalloc_size(const DALLOC_CTX *d)
79 if (d == NULL) {
80 return 0;
82 return talloc_array_length(d->dd_talloc_array);
85 /* Return element at position */
86 void *dalloc_get_object(const DALLOC_CTX *d, int i)
88 size_t size = dalloc_size(d);
90 if (i >= size) {
91 return NULL;
94 return d->dd_talloc_array[i];
97 /* Return typename of element at position */
98 const char *dalloc_get_name(const DALLOC_CTX *d, int i)
100 void *o = dalloc_get_object(d, i);
102 if (o == NULL) {
103 return NULL;
106 return talloc_get_name(o);
110 * Get pointer to value from a DALLOC object
112 * Returns pointer to object from a DALLOC object. Nested object integration
113 * is supported by using the type string "DALLOC_CTX". Any other type string
114 * designates the requested objects type.
116 void *dalloc_get(const DALLOC_CTX *d, ...)
118 int result = 0;
119 void *p = NULL;
120 va_list args;
121 const char *type;
122 int elem;
124 va_start(args, d);
125 type = va_arg(args, const char *);
127 while (strcmp(type, "DALLOC_CTX") == 0) {
128 elem = va_arg(args, int);
129 if (elem >= talloc_array_length(d->dd_talloc_array)) {
130 result = -1;
131 goto done;
133 d = d->dd_talloc_array[elem];
134 type = va_arg(args, const char *);
137 elem = va_arg(args, int);
138 if (elem >= talloc_array_length(d->dd_talloc_array)) {
139 result = -1;
140 goto done;
143 p = talloc_check_name(d->dd_talloc_array[elem], type);
144 if (p == NULL) {
145 result = -1;
146 goto done;
149 done:
150 va_end(args);
151 if (result != 0) {
152 p = NULL;
154 return p;
157 void *dalloc_value_for_key(const DALLOC_CTX *d, ...)
159 int result = 0;
160 void *p = NULL;
161 va_list args;
162 const char *type = NULL;
163 int elem;
164 size_t array_len;
166 va_start(args, d);
167 type = va_arg(args, const char *);
169 while (strcmp(type, "DALLOC_CTX") == 0) {
170 array_len = talloc_array_length(d->dd_talloc_array);
171 elem = va_arg(args, int);
172 if (elem >= array_len) {
173 result = -1;
174 goto done;
176 d = d->dd_talloc_array[elem];
177 type = va_arg(args, const char *);
180 array_len = talloc_array_length(d->dd_talloc_array);
182 for (elem = 0; elem + 1 < array_len; elem += 2) {
183 if (strcmp(talloc_get_name(d->dd_talloc_array[elem]), "char *") != 0) {
184 result = -1;
185 goto done;
187 if (strcmp((char *)d->dd_talloc_array[elem],type) == 0) {
188 p = d->dd_talloc_array[elem + 1];
189 break;
192 if (p == NULL) {
193 goto done;
196 type = va_arg(args, const char *);
197 if (strcmp(talloc_get_name(p), type) != 0) {
198 p = NULL;
201 done:
202 va_end(args);
203 if (result != 0) {
204 p = NULL;
206 return p;
209 static char *dalloc_strdup(TALLOC_CTX *mem_ctx, const char *string)
211 char *p;
213 p = talloc_strdup(mem_ctx, string);
214 if (p == NULL) {
215 return NULL;
217 talloc_set_name_const(p, "char *");
218 return p;
221 int dalloc_stradd(DALLOC_CTX *d, const char *string)
223 int result;
224 char *p;
226 p = dalloc_strdup(d, string);
227 if (p == NULL) {
228 return -1;
231 result = dalloc_add(d, p, char *);
232 if (result != 0) {
233 return -1;
236 return 0;
239 static char *tab_level(TALLOC_CTX *mem_ctx, int level)
241 int i;
242 char *string = talloc_array(mem_ctx, char, level + 1);
244 for (i = 0; i < level; i++) {
245 string[i] = '\t';
248 string[i] = '\0';
249 return string;
252 char *dalloc_dump(DALLOC_CTX *dd, int nestinglevel)
254 const char *type;
255 int n, result;
256 uint64_t i;
257 sl_bool_t bl;
258 sl_time_t t;
259 struct tm *tm;
260 char datestring[256];
261 sl_cnids_t cnids;
262 char *logstring, *nested_logstring;
263 char *tab_string1, *tab_string2;
264 void *p;
265 bool ok;
266 char *utf8string;
267 size_t utf8len;
269 tab_string1 = tab_level(dd, nestinglevel);
270 if (tab_string1 == NULL) {
271 return NULL;
273 tab_string2 = tab_level(dd, nestinglevel + 1);
274 if (tab_string2 == NULL) {
275 return NULL;
278 logstring = talloc_asprintf(dd,
279 "%s%s(#%zu): {\n",
280 tab_string1,
281 talloc_get_name(dd),
282 dalloc_size(dd));
283 if (logstring == NULL) {
284 return NULL;
287 for (n = 0; n < dalloc_size(dd); n++) {
288 type = dalloc_get_name(dd, n);
289 if (type == NULL) {
290 return NULL;
292 p = dalloc_get_object(dd, n);
293 if (p == NULL) {
294 return NULL;
296 if (strcmp(type, "DALLOC_CTX") == 0
297 || strcmp(type, "sl_array_t") == 0
298 || strcmp(type, "sl_filemeta_t") == 0
299 || strcmp(type, "sl_dict_t") == 0) {
300 nested_logstring = dalloc_dump(p, nestinglevel + 1);
301 if (nested_logstring == NULL) {
302 return NULL;
304 logstring = talloc_strdup_append(logstring,
305 nested_logstring);
306 } else if (strcmp(type, "uint64_t") == 0) {
307 memcpy(&i, p, sizeof(uint64_t));
308 logstring = talloc_asprintf_append(
309 logstring,
310 "%suint64_t: 0x%04jx\n",
311 tab_string2, (uintmax_t)i);
312 } else if (strcmp(type, "char *") == 0) {
313 logstring = talloc_asprintf_append(
314 logstring,
315 "%sstring: %s\n",
316 tab_string2,
317 (char *)p);
318 } else if (strcmp(type, "smb_ucs2_t *") == 0) {
319 ok = convert_string_talloc(talloc_tos(),
320 CH_UTF16LE,
321 CH_UTF8,
323 talloc_get_size(p),
324 &utf8string,
325 &utf8len);
326 if (!ok) {
327 return NULL;
329 logstring = talloc_asprintf_append(
330 logstring,
331 "%sUTF16-string: %s\n",
332 tab_string2,
333 utf8string);
334 TALLOC_FREE(utf8string);
335 } else if (strcmp(type, "sl_bool_t") == 0) {
336 memcpy(&bl, p, sizeof(sl_bool_t));
337 logstring = talloc_asprintf_append(
338 logstring,
339 "%sbool: %s\n",
340 tab_string2,
341 bl ? "true" : "false");
342 } else if (strcmp(type, "sl_nil_t") == 0) {
343 logstring = talloc_asprintf_append(
344 logstring,
345 "%snil\n",
346 tab_string2);
347 } else if (strcmp(type, "sl_time_t") == 0) {
348 memcpy(&t, p, sizeof(sl_time_t));
349 tm = localtime(&t.tv_sec);
350 if (tm == NULL) {
351 return NULL;
353 result = strftime(datestring,
354 sizeof(datestring),
355 "%Y-%m-%d %H:%M:%S", tm);
356 if (result == 0) {
357 return NULL;
359 logstring = talloc_asprintf_append(
360 logstring,
361 "%ssl_time_t: %s.%06lu\n",
362 tab_string2,
363 datestring,
364 (unsigned long)t.tv_usec);
365 } else if (strcmp(type, "sl_cnids_t") == 0) {
366 memcpy(&cnids, p, sizeof(sl_cnids_t));
367 logstring = talloc_asprintf_append(
368 logstring,
369 "%sCNIDs: unkn1: 0x%" PRIx16 ", unkn2: 0x%" PRIx32 "\n",
370 tab_string2,
371 cnids.ca_unkn1,
372 cnids.ca_context);
373 if (logstring == NULL) {
374 return NULL;
376 if (cnids.ca_cnids) {
377 nested_logstring = dalloc_dump(
378 cnids.ca_cnids,
379 nestinglevel + 2);
380 if (!nested_logstring) {
381 return NULL;
383 logstring = talloc_strdup_append(logstring,
384 nested_logstring);
386 } else {
387 logstring = talloc_asprintf_append(
388 logstring,
389 "%stype: %s\n",
390 tab_string2,
391 type);
393 if (logstring == NULL) {
394 return NULL;
397 logstring = talloc_asprintf_append(logstring,
398 "%s}\n",
399 tab_string1);
400 if (logstring == NULL) {
401 return NULL;
403 return logstring;