Line data Source code
1 : /*
2 : INI LIBRARY
3 :
4 : Unit test for the parser object.
5 :
6 : Copyright (C) Dmitri Pal <dpal@redhat.com> 2010
7 :
8 : INI Library is free software: you can redistribute it and/or modify
9 : it under the terms of the GNU Lesser General Public License as published by
10 : the Free Software Foundation, either version 3 of the License, or
11 : (at your option) any later version.
12 :
13 : INI Library is distributed in the hope that it will be useful,
14 : but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : GNU Lesser General Public License for more details.
17 :
18 : You should have received a copy of the GNU Lesser General Public License
19 : along with INI Library. If not, see <http://www.gnu.org/licenses/>.
20 : */
21 :
22 : #include "config.h"
23 : #include <stdio.h>
24 : #include <string.h>
25 : #include <errno.h>
26 : #include <stdlib.h>
27 : #include <limits.h>
28 : #include <sys/stat.h>
29 : #include "ini_defines.h"
30 : #include "ini_configobj.h"
31 : #include "ini_config_priv.h"
32 : #include "simplebuffer.h"
33 : #include "path_utils.h"
34 : #define TRACE_HOME
35 : #include "trace.h"
36 : #include "collection_tools.h"
37 :
38 : int verbose = 0;
39 : char *confdir = NULL;
40 :
41 : #define NUM_TESTS 14
42 : #define VAL_SIZE 100
43 :
44 : #define INIOUT(foo) \
45 : do { \
46 : if (verbose) foo; \
47 : } while(0)
48 :
49 : typedef int (*test_fn)(void);
50 :
51 158 : static int test_one_file(const char *in_filename,
52 : const char *out_filename,
53 : int edge,
54 : int in_mem)
55 : {
56 158 : int error = EOK;
57 158 : struct ini_cfgfile *file_ctx = NULL;
58 158 : FILE *ff = NULL;
59 158 : struct ini_cfgobj *ini_config = NULL;
60 158 : struct ini_cfgobj *ini_copy = NULL;
61 158 : char **error_list = NULL;
62 158 : struct simplebuffer *sbobj = NULL;
63 158 : uint32_t left = 0;
64 158 : uint32_t stream_len = 0;
65 158 : void *stream_data = NULL;
66 : struct stat file_stats;
67 158 : int stat_ret = 0;
68 158 : FILE *file = NULL;
69 :
70 158 : INIOUT(printf("<==== Testing file %s ====>\n", in_filename));
71 :
72 : /* Create config collection */
73 158 : error = ini_config_create(&ini_config);
74 158 : if (error) {
75 0 : printf("Failed to create collection. Error %d.\n", error);
76 0 : return error;
77 : }
78 :
79 158 : if (in_mem) {
80 : /* Get file stats */
81 48 : errno = 0;
82 48 : stat_ret = stat(in_filename, &file_stats);
83 48 : if (stat_ret == -1) {
84 0 : error = errno;
85 0 : printf("Failed to get file stats. Error %d.\n", error);
86 0 : ini_config_destroy(ini_config);
87 0 : return error;
88 : }
89 : /* Allocate memory to store file */
90 48 : errno = 0;
91 48 : stream_len = file_stats.st_size;
92 48 : stream_data = malloc(file_stats.st_size + 1);
93 48 : if (!stream_data) {
94 0 : error = errno;
95 0 : printf("Failed to allocate memory for stream. Error %d.\n", error);
96 0 : ini_config_destroy(ini_config);
97 0 : return error;
98 : }
99 48 : *((unsigned char *)(stream_data) + stream_len) = '\0';
100 : /* Open file */
101 48 : errno = 0;
102 48 : file = fopen(in_filename, "r");
103 48 : if (!stream_data) {
104 0 : error = errno;
105 0 : printf("Failed to open file to prepare stream. Error %d.\n", error);
106 0 : free(stream_data);
107 0 : ini_config_destroy(ini_config);
108 0 : return error;
109 : }
110 : /* Read file into memory */
111 48 : errno = 0;
112 48 : fread(stream_data, stream_len, 1, file);
113 48 : error = ferror(file);
114 48 : if (error) {
115 0 : printf("Failed to read stream data. Error %d.\n", error);
116 0 : free(stream_data);
117 0 : fclose(file);
118 0 : ini_config_destroy(ini_config);
119 0 : return error;
120 : }
121 48 : fclose(file);
122 :
123 48 : INIOUT(printf("Data len %u\n", stream_len));
124 48 : INIOUT(printf("Data:\n%s\n", (char *)stream_data));
125 :
126 48 : error = ini_config_file_from_mem(stream_data,
127 : stream_len,
128 : &file_ctx);
129 48 : if (error) {
130 0 : printf("Failed to open from memory. Error %d.\n", error);
131 0 : free(stream_data);
132 0 : ini_config_destroy(ini_config);
133 0 : return error;
134 : }
135 : }
136 : else {
137 110 : error = ini_config_file_open(in_filename,
138 : 0, /* TBD */
139 : &file_ctx);
140 110 : if (error) {
141 0 : printf("Failed to open file %s for reading. Error %d.\n",
142 : in_filename, error);
143 0 : ini_config_destroy(ini_config);
144 0 : return error;
145 : }
146 : }
147 :
148 158 : error = ini_config_parse(file_ctx,
149 : INI_STOP_ON_NONE,
150 : 0, /* TBD */
151 : 0,
152 : ini_config);
153 158 : if (error) {
154 14 : INIOUT(printf("Failed to parse configuration. Error %d.\n", error));
155 :
156 14 : if (ini_config_error_count(ini_config)) {
157 14 : if (in_mem) {
158 4 : INIOUT(printf("Errors detected while parsing"
159 : " configuration stored in memory: %s\n",
160 : in_filename));
161 : }
162 : else {
163 10 : INIOUT(printf("Errors detected while parsing: %s\n",
164 : ini_config_get_filename(file_ctx)));
165 : }
166 14 : ini_config_get_errors(ini_config, &error_list);
167 14 : INIOUT(ini_config_print_errors(stdout, error_list));
168 14 : ini_config_free_errors(error_list);
169 : }
170 : /* If we are testing memory mapped, return error */
171 14 : if (in_mem) {
172 4 : free(stream_data);
173 4 : ini_config_file_destroy(file_ctx);
174 4 : ini_config_destroy(ini_config);
175 4 : return error;
176 : }
177 : }
178 :
179 154 : if (in_mem) free(stream_data);
180 154 : ini_config_file_destroy(file_ctx);
181 :
182 154 : INIOUT(col_debug_collection(ini_config->cfg, COL_TRAVERSE_DEFAULT));
183 :
184 : /* Copy configuration */
185 154 : error = ini_config_copy(ini_config, &ini_copy);
186 154 : if (error) {
187 0 : printf("Failed to copy configuration. Error %d.\n", error);
188 0 : ini_config_destroy(ini_config);
189 0 : return error;
190 : }
191 :
192 154 : ini_config_destroy(ini_config);
193 154 : ini_config = ini_copy;
194 :
195 154 : INIOUT(col_debug_collection(ini_config->cfg, COL_TRAVERSE_DEFAULT));
196 :
197 154 : error = ini_config_set_wrap(ini_config, edge);
198 154 : if (error) {
199 0 : printf("Failed to set custom wrapper. Error %d.\n", error);
200 0 : ini_config_destroy(ini_config);
201 0 : return error;
202 : }
203 :
204 154 : error = simplebuffer_alloc(&sbobj);
205 154 : if (error) {
206 : TRACE_ERROR_NUMBER("Failed to allocate dynamic string.", error);
207 0 : ini_config_destroy(ini_config);
208 0 : return error;
209 : }
210 :
211 154 : error = ini_config_serialize(ini_config, sbobj);
212 154 : if (error != EOK) {
213 0 : printf("Failed to serialize configuration. Error %d.\n", error);
214 0 : ini_config_destroy(ini_config);
215 0 : simplebuffer_free(sbobj);
216 0 : return error;
217 : }
218 :
219 154 : errno = 0;
220 154 : ff = fopen(out_filename, "w");
221 154 : if(!ff) {
222 0 : error = errno;
223 0 : printf("Failed to open file [%s] for writing. Error %d.\n",
224 : out_filename, error);
225 0 : ini_config_destroy(ini_config);
226 0 : simplebuffer_free(sbobj);
227 0 : return error;
228 : }
229 :
230 : /* Save */
231 154 : left = simplebuffer_get_len(sbobj);
232 448 : while (left > 0) {
233 140 : error = simplebuffer_write(fileno(ff), sbobj, &left);
234 140 : if (error) {
235 0 : printf("Failed to write back the configuration %d.\n", error);
236 0 : simplebuffer_free(sbobj);
237 0 : ini_config_destroy(ini_config);
238 0 : fclose(ff);
239 0 : return error;
240 : }
241 : }
242 :
243 154 : ini_config_destroy(ini_config);
244 154 : simplebuffer_free(sbobj);
245 154 : fclose(ff);
246 :
247 154 : return EOK;
248 : }
249 :
250 :
251 : /* Run tests for multiple files */
252 1 : static int read_save_test(void)
253 : {
254 1 : int error = EOK;
255 1 : int i = 0;
256 1 : int edge = 5;
257 : char infile[PATH_MAX];
258 : char outfile[PATH_MAX];
259 1 : char *srcdir = NULL;
260 1 : const char *files[] = { "real",
261 : "mysssd",
262 : "ipa",
263 : "test",
264 : "smerge",
265 : "real8",
266 : "real16be",
267 : "real16le",
268 : "real32be",
269 : "real32le",
270 : "symbols",
271 : NULL };
272 :
273 1 : INIOUT(printf("<==== Read save test ====>\n"));
274 :
275 1 : srcdir = getenv("srcdir");
276 :
277 13 : while(files[i]) {
278 55 : for ( edge = 10; edge < 100; edge +=19) {
279 55 : snprintf(infile, PATH_MAX, "%s/ini/ini.d/%s.conf",
280 : (srcdir == NULL) ? "." : srcdir, files[i]);
281 55 : snprintf(outfile, PATH_MAX, "./%s_%d.conf.out", files[i], edge);
282 55 : error = test_one_file(infile, outfile, edge, 0);
283 55 : INIOUT(printf("Test for file: %s returned %d\n", files[i], error));
284 55 : if (error) return error;
285 : }
286 11 : i++;
287 : }
288 :
289 1 : INIOUT(printf("<==== Read save test end ====>\n"));
290 :
291 : return EOK;
292 : }
293 :
294 :
295 : /* Run tests for multiple files */
296 1 : static int read_mem_test(void)
297 : {
298 1 : int error = EOK;
299 1 : int i = 0;
300 1 : int edge = 5;
301 : char infile[PATH_MAX];
302 : char outfile[PATH_MAX];
303 1 : char *srcdir = NULL;
304 1 : const char *files[] = { "real",
305 : "mysssd",
306 : "ipa",
307 : "test",
308 : "smerge",
309 : "real8",
310 : "real16be",
311 : "real16le",
312 : "real32be",
313 : "real32le",
314 : "symbols",
315 : "new_line",
316 : NULL };
317 :
318 1 : INIOUT(printf("<==== Read mem test ====>\n"));
319 :
320 1 : srcdir = getenv("srcdir");
321 :
322 14 : while(files[i]) {
323 48 : for ( edge = 15; edge < 100; edge +=25) {
324 48 : snprintf(infile, PATH_MAX, "%s/ini/ini.d/%s.conf",
325 : (srcdir == NULL) ? "." : srcdir, files[i]);
326 48 : snprintf(outfile, PATH_MAX, "./%s_%d.conf.mem.out", files[i], edge);
327 48 : error = test_one_file(infile, outfile, edge, 1);
328 48 : INIOUT(printf("Test for file: %s returned %d\n", files[i], error));
329 48 : if ((error) && (strncmp(files[i], "test", 4) != 0)) return error;
330 : }
331 12 : i++;
332 : }
333 :
334 1 : INIOUT(printf("<==== Read mem test end ====>\n"));
335 :
336 : return EOK;
337 : }
338 :
339 :
340 : /* Run tests for multiple files */
341 1 : static int read_again_test(void)
342 : {
343 1 : int error = EOK;
344 1 : int i = 0;
345 1 : int edge = 5;
346 : char infile[PATH_MAX];
347 : char outfile[PATH_MAX];
348 : char command[PATH_MAX * 3];
349 1 : const char *files[] = { "real",
350 : "mysssd",
351 : "ipa",
352 : "test",
353 : "smerge",
354 : "real8",
355 : "real16be",
356 : "real16le",
357 : "real32be",
358 : "real32le",
359 : "symbols",
360 : NULL };
361 :
362 1 : INIOUT(printf("<==== Read again test ====>\n"));
363 :
364 12 : while(files[i]) {
365 55 : for ( edge = 10; edge < 100; edge +=19) {
366 :
367 55 : snprintf(infile, PATH_MAX, "./%s_%d.conf.out", files[i], edge);
368 55 : snprintf(outfile, PATH_MAX, "./%s_%d.conf.2.out", files[i], edge);
369 :
370 55 : error = test_one_file(infile, outfile, edge, 0);
371 55 : INIOUT(printf("Test for file: %s returned %d\n", files[i], error));
372 55 : if (error) break;
373 55 : snprintf(command, PATH_MAX * 3, "diff -q %s %s", infile, outfile);
374 55 : error = system(command);
375 55 : INIOUT(printf("Comparison of %s %s returned: %d\n",
376 : infile, outfile, error));
377 55 : if ((error) || (WEXITSTATUS(error))) {
378 0 : printf("Failed to run copy command %d %d.\n", error,
379 0 : WEXITSTATUS(error));
380 0 : error = -1;
381 0 : break;
382 : }
383 : }
384 :
385 11 : i++;
386 : }
387 :
388 1 : INIOUT(printf("<==== Read again test end ====>\n"));
389 :
390 1 : return error;
391 : }
392 :
393 1 : static int create_expect(const char *checkname)
394 : {
395 : FILE *ff;
396 1 : int error = EOK;
397 :
398 1 : errno = 0;
399 1 : ff = fopen(checkname, "w");
400 1 : if(!ff) {
401 0 : error = errno;
402 0 : printf("Failed to open file %s for writing. Error %d.\n",
403 : checkname, error);
404 0 : return error;
405 : }
406 :
407 : /* Ovewrite */
408 1 : fprintf(ff,"#Hoho section\n");
409 1 : fprintf(ff,"[hoho]\n");
410 1 : fprintf(ff,"#Hoho value\n");
411 1 : fprintf(ff,"val = hoho\n");
412 1 : fprintf(ff,"#End of hoho\n");
413 1 : fprintf(ff,"#Start of section\n");
414 1 : fprintf(ff,"[foo]\n");
415 1 : fprintf(ff,"#Second value\n");
416 1 : fprintf(ff,"bar = second value\n");
417 1 : fprintf(ff,"#End of section\n");
418 : /* Preserve */
419 1 : fprintf(ff,"#Hoho section\n");
420 1 : fprintf(ff,"[hoho]\n");
421 1 : fprintf(ff,"#Hoho value\n");
422 1 : fprintf(ff,"val = hoho\n");
423 1 : fprintf(ff,"#End of hoho\n");
424 1 : fprintf(ff,"#Start of section\n");
425 1 : fprintf(ff,"[foo]\n");
426 1 : fprintf(ff,"#First value\n");
427 1 : fprintf(ff,"bar = first value\n");
428 1 : fprintf(ff,"#End of section\n");
429 : /* Allow */
430 1 : fprintf(ff,"#Hoho section\n");
431 1 : fprintf(ff,"[hoho]\n");
432 1 : fprintf(ff,"#Hoho value\n");
433 1 : fprintf(ff,"val = hoho\n");
434 1 : fprintf(ff,"#End of hoho\n");
435 1 : fprintf(ff,"#Start of section\n");
436 1 : fprintf(ff,"[foo]\n");
437 1 : fprintf(ff,"#First value\n");
438 1 : fprintf(ff,"bar = first value\n");
439 1 : fprintf(ff,"#Second value\n");
440 1 : fprintf(ff,"bar = second value\n");
441 1 : fprintf(ff,"#End of section\n");
442 : /* Detect */
443 1 : fprintf(ff,"#Hoho section\n");
444 1 : fprintf(ff,"[hoho]\n");
445 1 : fprintf(ff,"#Hoho value\n");
446 1 : fprintf(ff,"val = hoho\n");
447 1 : fprintf(ff,"#End of hoho\n");
448 1 : fprintf(ff,"#Start of section\n");
449 1 : fprintf(ff,"[foo]\n");
450 1 : fprintf(ff,"#First value\n");
451 1 : fprintf(ff,"bar = first value\n");
452 1 : fprintf(ff,"#Second value\n");
453 1 : fprintf(ff,"bar = second value\n");
454 1 : fprintf(ff,"#End of section\n");
455 :
456 1 : fclose(ff);
457 :
458 1 : return EOK;
459 : }
460 :
461 : /* Check merge modes */
462 1 : static int merge_values_test(void)
463 : {
464 1 : int error = EOK;
465 : int i;
466 1 : struct ini_cfgfile *file_ctx = NULL;
467 1 : FILE *ff = NULL;
468 1 : struct ini_cfgobj *ini_config = NULL;
469 1 : char **error_list = NULL;
470 1 : struct simplebuffer *sbobj = NULL;
471 1 : uint32_t left = 0;
472 1 : uint32_t mflags[] = { INI_MV1S_OVERWRITE,
473 : INI_MV1S_ERROR,
474 : INI_MV1S_PRESERVE,
475 : INI_MV1S_ALLOW,
476 : INI_MV1S_DETECT };
477 :
478 1 : const char *mstr[] = { "OVERWRITE",
479 : "ERROR",
480 : "PRESERVE",
481 : "ALLOW",
482 : "DETECT" };
483 :
484 : char filename[PATH_MAX];
485 1 : const char *resname = "./merge.conf.out";
486 1 : const char *checkname = "./expect.conf.out";
487 : char command[PATH_MAX * 3];
488 1 : char *srcdir = NULL;
489 :
490 1 : INIOUT(printf("<==== Merge values test ====>\n"));
491 :
492 1 : srcdir = getenv("srcdir");
493 :
494 1 : snprintf(filename, PATH_MAX, "%s/ini/ini.d/foo.conf.in",
495 : (srcdir == NULL) ? "." : srcdir);
496 :
497 1 : error = simplebuffer_alloc(&sbobj);
498 1 : if (error) {
499 : TRACE_ERROR_NUMBER("Failed to allocate dynamic string.", error);
500 : return error;
501 : }
502 :
503 5 : for (i = 0; i < 5; i++) {
504 :
505 5 : INIOUT(printf("<==== Testing mode %s ====>\n", mstr[i]));
506 :
507 : /* Create config collection */
508 5 : ini_config = NULL;
509 5 : error = ini_config_create(&ini_config);
510 5 : if (error) {
511 0 : printf("Failed to create collection. Error %d.\n", error);
512 0 : simplebuffer_free(sbobj);
513 0 : return error;
514 : }
515 :
516 5 : file_ctx = NULL;
517 5 : error = ini_config_file_open(filename,
518 : 0, /* TBD */
519 : &file_ctx);
520 5 : if (error) {
521 0 : printf("Failed to open file %s for reading. Error %d.\n",
522 : filename, error);
523 0 : printf("Src dir is [%s].\n", (srcdir == NULL) ?
524 : "NOT DEFINED" : srcdir);
525 0 : ini_config_destroy(ini_config);
526 0 : simplebuffer_free(sbobj);
527 0 : return error;
528 : }
529 :
530 5 : error = ini_config_parse(file_ctx,
531 : INI_STOP_ON_ANY,
532 : mflags[i],
533 : 0,
534 : ini_config);
535 5 : if (error) {
536 2 : INIOUT(printf("Failed to parse configuration. Error %d.\n",
537 : error));
538 :
539 2 : if (ini_config_error_count(ini_config)) {
540 1 : INIOUT(printf("Errors detected while parsing: %s\n",
541 : ini_config_get_filename(file_ctx)));
542 1 : ini_config_get_errors(ini_config, &error_list);
543 1 : INIOUT(ini_config_print_errors(stdout, error_list));
544 1 : ini_config_free_errors(error_list);
545 : }
546 :
547 2 : if (((mflags[i] != INI_MV1S_ERROR) &&
548 : (mflags[i]!= INI_MV1S_DETECT)) ||
549 2 : ((mflags[i] = INI_MV1S_ERROR) && (error != EEXIST)) ||
550 2 : ((mflags[i] = INI_MV1S_DETECT) && (error != EEXIST))) {
551 0 : printf("This is unexpected error %d in mode %d\n",
552 : error, mflags[i]);
553 0 : ini_config_destroy(ini_config);
554 0 : simplebuffer_free(sbobj);
555 0 : ini_config_file_destroy(file_ctx);
556 0 : return error;
557 : }
558 : /* We do not return here intentionally */
559 : }
560 :
561 5 : ini_config_file_destroy(file_ctx);
562 :
563 5 : INIOUT(col_debug_collection(ini_config->cfg, COL_TRAVERSE_DEFAULT));
564 :
565 5 : error = ini_config_serialize(ini_config, sbobj);
566 5 : if (error != EOK) {
567 0 : printf("Failed to serialize configuration. Error %d.\n", error);
568 0 : ini_config_destroy(ini_config);
569 0 : simplebuffer_free(sbobj);
570 0 : return error;
571 : }
572 :
573 5 : ini_config_destroy(ini_config);
574 : }
575 :
576 1 : errno = 0;
577 1 : ff = fopen(resname, "w");
578 1 : if(!ff) {
579 0 : error = errno;
580 0 : printf("Failed to open file for writing. Error %d.\n", error);
581 0 : simplebuffer_free(sbobj);
582 0 : return error;
583 : }
584 :
585 : /* Save */
586 1 : left = simplebuffer_get_len(sbobj);
587 3 : while (left > 0) {
588 1 : error = simplebuffer_write(fileno(ff), sbobj, &left);
589 1 : if (error) {
590 0 : printf("Failed to write back the configuration %d.\n", error);
591 0 : simplebuffer_free(sbobj);
592 0 : fclose(ff);
593 0 : return error;
594 : }
595 : }
596 :
597 1 : simplebuffer_free(sbobj);
598 1 : fclose(ff);
599 :
600 1 : error = create_expect(checkname);
601 1 : if (error) {
602 0 : printf("Failed to create file with expected contents %d.\n", error);
603 0 : return error;
604 : }
605 :
606 1 : snprintf(command, PATH_MAX * 3, "diff -q %s %s", resname, checkname);
607 1 : error = system(command);
608 1 : INIOUT(printf("Comparison of %s %s returned: %d\n",
609 : resname, checkname, error));
610 1 : if ((error) || (WEXITSTATUS(error))) {
611 0 : printf("Failed to run copy command %d %d.\n", error,
612 0 : WEXITSTATUS(error));
613 0 : return -1;
614 : }
615 :
616 1 : INIOUT(printf("<==== Merge values test end ====>\n"));
617 :
618 1 : return error;
619 : }
620 :
621 : /* Check merge modes */
622 1 : static int merge_section_test(void)
623 : {
624 1 : int error = EOK;
625 : int i, j;
626 1 : struct ini_cfgfile *file_ctx = NULL;
627 1 : FILE *ff = NULL;
628 1 : struct ini_cfgobj *ini_config = NULL;
629 1 : char **error_list = NULL;
630 1 : struct simplebuffer *sbobj = NULL;
631 1 : uint32_t left = 0;
632 1 : uint32_t msecflags[] = { INI_MS_MERGE,
633 : INI_MS_ERROR,
634 : INI_MS_OVERWRITE,
635 : INI_MS_PRESERVE,
636 : INI_MS_DETECT };
637 :
638 1 : uint32_t mflags[] = { INI_MV2S_OVERWRITE,
639 : INI_MV2S_ERROR,
640 : INI_MV2S_PRESERVE,
641 : INI_MV2S_ALLOW,
642 : INI_MV2S_DETECT };
643 :
644 1 : const char *secmstr[] = { "MERGE",
645 : "ERROR",
646 : "OVERWRITE",
647 : "PRESERVE",
648 : "DETECT" };
649 :
650 1 : const char *mstr[] = { "OVERWRITE",
651 : "ERROR",
652 : "PRESERVE",
653 : "ALLOW",
654 : "DETECT" };
655 :
656 : char filename[PATH_MAX];
657 : char checkname[PATH_MAX];
658 : char resname[PATH_MAX];
659 : char command[PATH_MAX * 3];
660 : char mode[VAL_SIZE];
661 1 : char *srcdir = NULL;
662 1 : char *builddir = NULL;
663 :
664 :
665 1 : INIOUT(printf("<==== Merge section test ====>\n"));
666 :
667 1 : srcdir = getenv("srcdir");
668 1 : builddir = getenv("builddir");
669 1 : snprintf(filename, PATH_MAX, "%s/ini/ini.d/smerge.conf",
670 : (srcdir == NULL) ? "." : srcdir);
671 1 : snprintf(checkname, PATH_MAX, "%s/ini/ini.d/sexpect.conf",
672 : (srcdir == NULL) ? "." : srcdir);
673 1 : snprintf(resname, PATH_MAX, "%s/smerge.conf.out",
674 : (builddir == NULL) ? "." : builddir);
675 :
676 1 : error = simplebuffer_alloc(&sbobj);
677 1 : if (error) {
678 : TRACE_ERROR_NUMBER("Failed to allocate dynamic string.", error);
679 : return error;
680 : }
681 :
682 5 : for (i = 0; i < 5; i++) {
683 25 : for (j = 0; j < 5; j++) {
684 :
685 25 : INIOUT(printf("<==== Testing mode %s + %s ====>\n",
686 : secmstr[i], mstr[j]));
687 :
688 25 : snprintf(mode, VAL_SIZE, "# Section mode: %s, value mode: %s\n",
689 : secmstr[i], mstr[j]);
690 :
691 25 : error = simplebuffer_add_str(sbobj,
692 : mode,
693 25 : strlen(mode),
694 : VAL_SIZE);
695 25 : if (error) {
696 : TRACE_ERROR_NUMBER("Failed to add string.",
697 : error);
698 0 : simplebuffer_free(sbobj);
699 0 : return error;
700 : }
701 :
702 : /* Create config collection */
703 25 : ini_config = NULL;
704 25 : error = ini_config_create(&ini_config);
705 25 : if (error) {
706 0 : printf("Failed to create collection. "
707 : "Error %d.\n", error);
708 0 : simplebuffer_free(sbobj);
709 0 : return error;
710 : }
711 :
712 25 : file_ctx = NULL;
713 25 : error = ini_config_file_open(filename,
714 : 0, /* TBD */
715 : &file_ctx);
716 25 : if (error) {
717 0 : printf("Failed to open file %s for reading. "
718 : "Error %d.\n", filename, error);
719 0 : printf("Source is %s.\n", (srcdir == NULL) ?
720 : "NOT Defined" : srcdir);
721 0 : ini_config_destroy(ini_config);
722 0 : simplebuffer_free(sbobj);
723 0 : return error;
724 : }
725 :
726 50 : error = ini_config_parse(file_ctx,
727 : INI_STOP_ON_ANY,
728 25 : msecflags[i] | mflags[j],
729 : 0,
730 : ini_config);
731 25 : if (error) {
732 12 : INIOUT(printf("Failed to parse configuration. "
733 : "Error %d.\n", error));
734 :
735 12 : if (ini_config_error_count(ini_config)) {
736 7 : INIOUT(printf("Errors detected while parsing: %s\n",
737 : ini_config_get_filename(file_ctx)));
738 7 : ini_config_get_errors(ini_config, &error_list);
739 7 : INIOUT(ini_config_print_errors(stdout, error_list));
740 7 : ini_config_free_errors(error_list);
741 : }
742 :
743 12 : if (((msecflags[i] == INI_MS_ERROR) &&
744 22 : (error == EEXIST)) ||
745 : ((msecflags[i] == INI_MS_DETECT) &&
746 2 : (error == EEXIST)) ||
747 2 : ((msecflags[i] == INI_MS_MERGE) &&
748 2 : ((mflags[j] == INI_MV2S_ERROR) ||
749 2 : (mflags[j] == INI_MV2S_DETECT)) &&
750 : (error == EEXIST))) {
751 12 : INIOUT(printf("This is an expected error "
752 : "%d in mode %d + %d\n",
753 : error,
754 : msecflags[i],
755 : mflags[j]));
756 : /* We do not return here intentionally */
757 : }
758 : else {
759 0 : printf("This is unexpected error %d in mode %d + %d\n",
760 : error, msecflags[i], mflags[j]);
761 0 : ini_config_destroy(ini_config);
762 0 : simplebuffer_free(sbobj);
763 0 : ini_config_file_destroy(file_ctx);
764 0 : return error;
765 : }
766 : }
767 :
768 25 : ini_config_file_destroy(file_ctx);
769 :
770 25 : INIOUT(col_debug_collection(ini_config->cfg,
771 : COL_TRAVERSE_DEFAULT));
772 :
773 25 : error = ini_config_serialize(ini_config, sbobj);
774 25 : if (error != EOK) {
775 0 : printf("Failed to serialize configuration. "
776 : "Error %d.\n", error);
777 0 : ini_config_destroy(ini_config);
778 0 : simplebuffer_free(sbobj);
779 0 : return error;
780 : }
781 :
782 25 : ini_config_destroy(ini_config);
783 : }
784 : }
785 :
786 1 : errno = 0;
787 1 : ff = fopen(resname, "w");
788 1 : if(!ff) {
789 0 : error = errno;
790 0 : printf("Failed to open file for writing. Error %d.\n", error);
791 0 : simplebuffer_free(sbobj);
792 0 : return error;
793 : }
794 :
795 : /* Save */
796 1 : left = simplebuffer_get_len(sbobj);
797 3 : while (left > 0) {
798 1 : error = simplebuffer_write(fileno(ff), sbobj, &left);
799 1 : if (error) {
800 0 : printf("Failed to write back the configuration %d.\n", error);
801 0 : simplebuffer_free(sbobj);
802 0 : fclose(ff);
803 0 : return error;
804 : }
805 : }
806 :
807 1 : simplebuffer_free(sbobj);
808 1 : fclose(ff);
809 :
810 1 : snprintf(command, PATH_MAX * 3, "diff -q %s %s", resname, checkname);
811 1 : error = system(command);
812 1 : INIOUT(printf("Comparison of %s %s returned: %d\n",
813 : resname, checkname, error));
814 :
815 1 : if ((error) || (WEXITSTATUS(error))) {
816 0 : printf("Failed to run diff command %d %d.\n", error,
817 0 : WEXITSTATUS(error));
818 0 : return -1;
819 : }
820 :
821 1 : INIOUT(printf("<==== Merge section test end ====>\n"));
822 :
823 1 : return error;
824 : }
825 :
826 50 : static int read_one_file(char *name,
827 : struct ini_cfgobj *ini_config,
828 : uint32_t collision_flags)
829 : {
830 50 : int error = EOK;
831 50 : struct ini_cfgfile *file_ctx = NULL;
832 50 : char **error_list = NULL;
833 :
834 50 : INIOUT(printf("Reading file %s\n", name));
835 :
836 50 : file_ctx = NULL;
837 50 : error = ini_config_file_open(name,
838 : 0,
839 : &file_ctx);
840 50 : if (error) {
841 0 : printf("Failed to open file %s for reading. "
842 : "Error %d.\n", name, error);
843 0 : return error;
844 : }
845 :
846 50 : INIOUT(printf("Parsing file %s\n", name));
847 :
848 50 : error = ini_config_parse(file_ctx,
849 : INI_STOP_ON_ANY,
850 : collision_flags,
851 : 0,
852 : ini_config);
853 50 : if (error) {
854 0 : INIOUT(printf("Failed to parse configuration. "
855 : "Error %d.\n", error));
856 :
857 0 : if (ini_config_error_count(ini_config)) {
858 0 : INIOUT(printf("Errors detected while parsing: %s\n",
859 : ini_config_get_filename(file_ctx)));
860 0 : ini_config_get_errors(ini_config, &error_list);
861 0 : INIOUT(ini_config_print_errors(stdout, error_list));
862 0 : ini_config_free_errors(error_list);
863 : }
864 0 : ini_config_file_destroy(file_ctx);
865 0 : return error;
866 : }
867 :
868 50 : ini_config_file_destroy(file_ctx);
869 :
870 50 : INIOUT(printf("Successfully parsed file %s\n", name));
871 : return EOK;
872 : }
873 :
874 : /* Check merge modes */
875 1 : static int merge_file_test(void)
876 : {
877 1 : int error = EOK;
878 : int i, j;
879 1 : struct ini_cfgobj *ini_config_first = NULL;
880 1 : struct ini_cfgobj *ini_config_second = NULL;
881 1 : struct ini_cfgobj *ini_config_result = NULL;
882 1 : struct simplebuffer *sbobj = NULL;
883 1 : uint32_t left = 0;
884 1 : FILE *ff = NULL;
885 1 : uint32_t msecflags[] = { INI_MS_MERGE,
886 : INI_MS_ERROR,
887 : INI_MS_OVERWRITE,
888 : INI_MS_PRESERVE,
889 : INI_MS_DETECT };
890 :
891 1 : uint32_t m2flags[] = { INI_MV2S_OVERWRITE,
892 : INI_MV2S_ERROR,
893 : INI_MV2S_PRESERVE,
894 : INI_MV2S_ALLOW,
895 : INI_MV2S_DETECT };
896 :
897 1 : uint32_t m1flags[] = { INI_MV1S_OVERWRITE,
898 : INI_MV1S_ERROR,
899 : INI_MV1S_PRESERVE,
900 : INI_MV1S_ALLOW,
901 : INI_MV1S_DETECT };
902 :
903 1 : const char *secmstr[] = { "MERGE",
904 : "ERROR",
905 : "OVERWRITE",
906 : "PRESERVE",
907 : "DETECT" };
908 :
909 1 : const char *mstr[] = { "OVERWRITE",
910 : "ERROR",
911 : "PRESERVE",
912 : "ALLOW",
913 : "DETECT" };
914 :
915 : char firstname[PATH_MAX];
916 : char secondname[PATH_MAX];
917 : char resname[PATH_MAX];
918 : char checkname[PATH_MAX];
919 : char command[PATH_MAX * 3];
920 : char msg[VAL_SIZE];
921 : char mode[VAL_SIZE];
922 1 : char *srcdir = NULL;
923 1 : char *builddir = NULL;
924 : uint32_t collision_flags;
925 : uint32_t ms_subst;
926 : uint32_t mv1s_subst;
927 : uint32_t mv2s_subst;
928 :
929 1 : INIOUT(printf("<==== Merge file test ====>\n"));
930 :
931 1 : srcdir = getenv("srcdir");
932 1 : builddir = getenv("builddir");
933 1 : snprintf(firstname, PATH_MAX, "%s/ini/ini.d/first.conf",
934 : (srcdir == NULL) ? "." : srcdir);
935 :
936 1 : snprintf(secondname, PATH_MAX, "%s/ini/ini.d/second.conf",
937 : (srcdir == NULL) ? "." : srcdir);
938 :
939 1 : snprintf(checkname, PATH_MAX, "%s/ini/ini.d/mergecheck.conf",
940 : (srcdir == NULL) ? "." : srcdir);
941 :
942 1 : snprintf(resname, PATH_MAX, "%s/mergecheck.conf.out",
943 : (builddir == NULL) ? "." : builddir);
944 :
945 1 : error = simplebuffer_alloc(&sbobj);
946 1 : if (error) {
947 : TRACE_ERROR_NUMBER("Failed to allocate dynamic string.", error);
948 : return error;
949 : }
950 :
951 5 : for (i = 0; i < 5; i++) {
952 25 : for (j = 0; j < 5; j++) {
953 :
954 25 : INIOUT(printf("<==== Testing mode %s + %s ====>\n",
955 : secmstr[i], mstr[j]));
956 :
957 25 : snprintf(mode, VAL_SIZE, "# Section mode: %s, value mode: %s\n",
958 : secmstr[i], mstr[j]);
959 :
960 25 : error = simplebuffer_add_str(sbobj,
961 : mode,
962 25 : strlen(mode),
963 : VAL_SIZE);
964 25 : if (error) {
965 : TRACE_ERROR_NUMBER("Failed to add string.",
966 : error);
967 0 : simplebuffer_free(sbobj);
968 0 : return error;
969 : }
970 :
971 : /* Create first config collection */
972 25 : ini_config_first = NULL;
973 25 : error = ini_config_create(&ini_config_first);
974 25 : if (error) {
975 0 : printf("Failed to create collection. "
976 : "Error %d.\n", error);
977 0 : simplebuffer_free(sbobj);
978 0 : return error;
979 : }
980 :
981 : /* Create second config collection */
982 25 : ini_config_second = NULL;
983 25 : error = ini_config_create(&ini_config_second);
984 25 : if (error) {
985 0 : printf("Failed to create collection. "
986 : "Error %d.\n", error);
987 0 : ini_config_destroy(ini_config_first);
988 0 : simplebuffer_free(sbobj);
989 0 : return error;
990 : }
991 :
992 : /* IMPORTANT: Use same collision flags for reading
993 : * of the files and then merging.
994 : * Mixing the flags would lead to strange results
995 : * that would be hard to debug.
996 : */
997 : /* However here for purely testing purposes
998 : * we will not use error modes in parsing
999 : * otherwise we will not be able to try to merge.
1000 : * Instead we replace the error and detect modes
1001 : * with allow or merge mode.
1002 : */
1003 : /* The test actually does not fail in the case of
1004 : * PRESERVE + ERROR becuase it should fail at
1005 : * the stage of reading file but we suppress
1006 : * it so we can try the merge.
1007 : * As a result the mode PRESERVE + ERROR
1008 : * acts as PRESERVE + ALLOW and does not return an error.
1009 : * The same thing happens with PRESERVE + DETECT mode.
1010 : * It might be confusing if someone tries to decipher
1011 : * the tests, so this comment should help.
1012 : */
1013 25 : if ((msecflags[i] == INI_MS_ERROR) ||
1014 : (msecflags[i] == INI_MS_DETECT)) {
1015 10 : ms_subst = msecflags[i];
1016 : }
1017 : else {
1018 : ms_subst = INI_MS_MERGE;
1019 : }
1020 :
1021 25 : if ((m2flags[j] == INI_MV2S_ERROR) ||
1022 : (m2flags[j] == INI_MV2S_DETECT)) {
1023 : mv1s_subst = INI_MV1S_ALLOW;
1024 : mv2s_subst = INI_MV2S_ALLOW;
1025 : }
1026 : else {
1027 15 : mv1s_subst = m1flags[j];
1028 15 : mv2s_subst = m2flags[j];
1029 : }
1030 :
1031 25 : collision_flags = mv1s_subst | mv2s_subst | ms_subst;
1032 :
1033 25 : error = read_one_file(firstname,
1034 : ini_config_first,
1035 : collision_flags);
1036 25 : if (error) {
1037 0 : printf("Failed to read %s. "
1038 : "Error %d.\n", firstname, error);
1039 0 : printf("Source is %s.\n", (srcdir == NULL) ?
1040 : "NOT Defined" : srcdir);
1041 0 : ini_config_destroy(ini_config_first);
1042 0 : ini_config_destroy(ini_config_second);
1043 0 : simplebuffer_free(sbobj);
1044 0 : return error;
1045 : }
1046 :
1047 25 : error = read_one_file(secondname,
1048 : ini_config_second,
1049 : collision_flags);
1050 25 : if (error) {
1051 0 : printf("Failed to read %s. "
1052 : "Error %d.\n", secondname, error);
1053 0 : printf("Source is %s.\n", (srcdir == NULL) ?
1054 : "NOT Defined" : srcdir);
1055 0 : ini_config_destroy(ini_config_first);
1056 0 : ini_config_destroy(ini_config_second);
1057 0 : simplebuffer_free(sbobj);
1058 0 : return error;
1059 : }
1060 :
1061 25 : INIOUT(col_debug_collection(ini_config_first->cfg,
1062 : COL_TRAVERSE_ONELEVEL));
1063 25 : INIOUT(col_debug_collection(ini_config_second->cfg,
1064 : COL_TRAVERSE_ONELEVEL));
1065 :
1066 25 : ini_config_result = NULL;
1067 25 : error = ini_config_merge(ini_config_first,
1068 : ini_config_second,
1069 25 : msecflags[i] | m2flags[j] | m1flags[j],
1070 : &ini_config_result);
1071 25 : if (error) {
1072 14 : if ((error == EEXIST) &&
1073 9 : ((msecflags[i] == INI_MS_ERROR) ||
1074 : (m2flags[j] == INI_MV2S_ERROR))) {
1075 8 : snprintf(msg, sizeof(msg) -1,
1076 : "# This is an expected error "
1077 : "%d in mode %d + %d + %d\n\n",
1078 : error,
1079 : msecflags[i],
1080 : m2flags[j],
1081 : m1flags[j]);
1082 8 : INIOUT(printf("%s", msg));
1083 8 : error = simplebuffer_add_str(sbobj,
1084 : msg,
1085 8 : strlen(msg),
1086 : VAL_SIZE);
1087 8 : if (error) {
1088 : TRACE_ERROR_NUMBER("Failed to add string.",
1089 : error);
1090 0 : ini_config_destroy(ini_config_first);
1091 0 : ini_config_destroy(ini_config_second);
1092 0 : simplebuffer_free(sbobj);
1093 0 : return error;
1094 : }
1095 :
1096 8 : ini_config_destroy(ini_config_first);
1097 8 : ini_config_destroy(ini_config_second);
1098 8 : continue;
1099 : }
1100 6 : else if ((error == EEXIST) &&
1101 2 : ((msecflags[i] == INI_MS_DETECT) ||
1102 2 : ((msecflags[i] != INI_MS_ERROR) &&
1103 : (m2flags[j] == INI_MV2S_DETECT)))) {
1104 6 : snprintf(msg, sizeof(msg) -1,
1105 : "# This is an expected error "
1106 : "%d in mode %d + %d + %d\n\n",
1107 : error,
1108 : msecflags[i],
1109 : m2flags[j],
1110 : m1flags[j]);
1111 6 : INIOUT(printf("%s", msg));
1112 6 : error = simplebuffer_add_str(sbobj,
1113 : msg,
1114 6 : strlen(msg),
1115 : VAL_SIZE);
1116 6 : if (error) {
1117 : TRACE_ERROR_NUMBER("Failed to add string.",
1118 : error);
1119 0 : ini_config_destroy(ini_config_first);
1120 0 : ini_config_destroy(ini_config_second);
1121 0 : simplebuffer_free(sbobj);
1122 0 : return error;
1123 : }
1124 : /* Falling throught here */
1125 : }
1126 : else {
1127 : TRACE_ERROR_NUMBER("Failed to merge.",
1128 : error);
1129 0 : ini_config_destroy(ini_config_first);
1130 0 : ini_config_destroy(ini_config_second);
1131 0 : simplebuffer_free(sbobj);
1132 0 : return error;
1133 : }
1134 : }
1135 :
1136 17 : INIOUT(col_debug_collection(ini_config_result->cfg,
1137 : COL_TRAVERSE_DEFAULT));
1138 :
1139 17 : error = ini_config_serialize(ini_config_result, sbobj);
1140 17 : if (error) {
1141 0 : printf("Failed to serialize configuration. "
1142 : "Error %d.\n", error);
1143 0 : ini_config_destroy(ini_config_first);
1144 0 : ini_config_destroy(ini_config_second);
1145 0 : ini_config_destroy(ini_config_result);
1146 0 : simplebuffer_free(sbobj);
1147 0 : return error;
1148 : }
1149 :
1150 17 : ini_config_destroy(ini_config_first);
1151 17 : ini_config_destroy(ini_config_second);
1152 17 : ini_config_destroy(ini_config_result);
1153 : }
1154 : }
1155 :
1156 1 : errno = 0;
1157 1 : ff = fopen(resname, "w");
1158 1 : if(!ff) {
1159 0 : error = errno;
1160 0 : printf("Failed to open file for writing. Error %d.\n", error);
1161 0 : simplebuffer_free(sbobj);
1162 0 : return error;
1163 : }
1164 :
1165 : /* Save */
1166 1 : left = simplebuffer_get_len(sbobj);
1167 3 : while (left > 0) {
1168 1 : error = simplebuffer_write(fileno(ff), sbobj, &left);
1169 1 : if (error) {
1170 0 : printf("Failed to write back the configuration %d.\n", error);
1171 0 : simplebuffer_free(sbobj);
1172 0 : fclose(ff);
1173 0 : return error;
1174 : }
1175 : }
1176 :
1177 1 : simplebuffer_free(sbobj);
1178 1 : fclose(ff);
1179 :
1180 1 : snprintf(command,PATH_MAX * 3, "diff -q %s %s", resname, checkname);
1181 1 : error = system(command);
1182 1 : INIOUT(printf("Comparison of %s %s returned: %d\n",
1183 : resname, checkname, error));
1184 :
1185 1 : if ((error) || (WEXITSTATUS(error))) {
1186 0 : printf("Failed to run diff command %d %d.\n", error,
1187 0 : WEXITSTATUS(error));
1188 0 : return -1;
1189 : }
1190 :
1191 1 : INIOUT(printf("<==== Merge section file end ====>\n"));
1192 :
1193 : return EOK;
1194 : }
1195 :
1196 1 : static int startup_test(void)
1197 : {
1198 1 : int error = EOK;
1199 1 : struct ini_cfgfile *file_ctx = NULL;
1200 1 : struct ini_cfgobj *ini_config = NULL;
1201 1 : char **error_list = NULL;
1202 : char infile[PATH_MAX];
1203 : char outfile[PATH_MAX];
1204 : char command[PATH_MAX * 3];
1205 1 : char *srcdir = NULL;
1206 : char *builddir;
1207 : const struct stat *file_stat;
1208 :
1209 1 : INIOUT(printf("<==== Startup test ====>\n"));
1210 :
1211 1 : srcdir = getenv("srcdir");
1212 1 : snprintf(infile, PATH_MAX, "%s/ini/ini.d/foo.conf.in",
1213 : (srcdir == NULL) ? "." : srcdir);
1214 1 : builddir = getenv("builddir");
1215 1 : snprintf(outfile, PATH_MAX, "%s/foo.conf",
1216 : (builddir == NULL) ? "." : builddir);
1217 :
1218 1 : snprintf(command, PATH_MAX * 3, "cp %s %s", infile, outfile);
1219 1 : INIOUT(printf("Running command '%s'\n", command));
1220 :
1221 1 : error = system(command);
1222 1 : if ((error) || (WEXITSTATUS(error))) {
1223 0 : printf("Failed to run copy command %d %d.\n", error,
1224 0 : WEXITSTATUS(error));
1225 0 : return -1;
1226 : }
1227 :
1228 1 : INIOUT(printf("Running chmod 660 on file '%s'\n", outfile));
1229 1 : error = chmod(outfile, S_IRUSR | S_IWUSR);
1230 1 : if(error) {
1231 0 : error = errno;
1232 0 : printf("Failed to run chmod command %d.\n", error);
1233 0 : return error;
1234 : }
1235 :
1236 : /* Open config file not collecting stats */
1237 1 : error = ini_config_file_open(outfile,
1238 : 0,
1239 : &file_ctx);
1240 1 : if (error) {
1241 0 : printf("Failed to open file %s for reading. Error %d.\n",
1242 : outfile, error);
1243 0 : return error;
1244 : }
1245 :
1246 1 : file_stat = ini_config_get_stat(file_ctx);
1247 1 : if (file_stat) {
1248 0 : printf("Expected NULL got not NULL!\n");
1249 0 : return EINVAL;
1250 : }
1251 :
1252 : /* We will check just permissions here. */
1253 1 : error = ini_config_access_check(file_ctx,
1254 : INI_ACCESS_CHECK_MODE, /* add uid & gui flags
1255 : * in real case
1256 : */
1257 : 0, /* <- will be real uid in real case */
1258 : 0, /* <- will be real gid in real case */
1259 : 0440, /* Checking for r--r----- */
1260 : 0);
1261 : /* This check is expected to fail since
1262 : * we did not collect stats
1263 : */
1264 1 : ini_config_file_destroy(file_ctx);
1265 :
1266 1 : if (!error) {
1267 0 : printf("Expected error got success!\n");
1268 0 : return EACCES;
1269 : }
1270 :
1271 :
1272 : /* Open config file */
1273 1 : error = ini_config_file_open(outfile,
1274 : INI_META_STATS,
1275 : &file_ctx);
1276 1 : if (error) {
1277 0 : printf("Failed to open file %s for reading. Error %d.\n",
1278 : outfile, error);
1279 0 : return error;
1280 : }
1281 :
1282 : /* Get stats */
1283 1 : file_stat = ini_config_get_stat(file_ctx);
1284 1 : if (!file_stat) {
1285 0 : printf("Expected not NULL got NULL!\n");
1286 0 : return EINVAL;
1287 : }
1288 :
1289 1 : INIOUT(printf("File was modified at: %d seconds since Jan 1 1970.\n",
1290 : (int)(file_stat->st_mtime)));
1291 :
1292 : /* We will check just permissions here. */
1293 1 : error = ini_config_access_check(file_ctx,
1294 : INI_ACCESS_CHECK_MODE, /* add uid & gui flags
1295 : * in real case
1296 : */
1297 : 0, /* <- will be real uid in real case */
1298 : 0, /* <- will be real gid in real case */
1299 : 0440, /* Checking for r--r----- */
1300 : 0);
1301 : /* This check is expected to fail since
1302 : * the actual permissions on the test file are: rw-------
1303 : */
1304 :
1305 1 : if (!error) {
1306 0 : printf("Expected error got success!\n");
1307 0 : ini_config_file_destroy(file_ctx);
1308 0 : return EACCES;
1309 : }
1310 :
1311 1 : error = ini_config_access_check(
1312 : file_ctx,
1313 : INI_ACCESS_CHECK_MODE, /* add uid & gui flags
1314 : * in real case
1315 : */
1316 : 0, /* <- will be real uid in real case */
1317 : 0, /* <- will be real gid in real case */
1318 : 0600, /* Checkling for rw------- */
1319 : 0);
1320 :
1321 1 : if (error) {
1322 0 : printf("Access check failed %d!\n", error);
1323 0 : ini_config_file_destroy(file_ctx);
1324 0 : return EACCES;
1325 : }
1326 :
1327 : /* Create config object */
1328 1 : error = ini_config_create(&ini_config);
1329 1 : if (error) {
1330 0 : printf("Failed to create collection. Error %d.\n", error);
1331 0 : ini_config_file_destroy(file_ctx);
1332 0 : return error;
1333 : }
1334 :
1335 1 : error = ini_config_parse(file_ctx,
1336 : INI_STOP_ON_NONE,
1337 : 0,
1338 : 0,
1339 : ini_config);
1340 1 : if (error) {
1341 0 : INIOUT(printf("Failed to parse configuration. Error %d.\n", error));
1342 :
1343 0 : if (ini_config_error_count(ini_config)) {
1344 0 : INIOUT(printf("Errors detected while parsing: %s\n",
1345 : ini_config_get_filename(file_ctx)));
1346 0 : ini_config_get_errors(ini_config, &error_list);
1347 0 : INIOUT(ini_config_print_errors(stdout, error_list));
1348 0 : ini_config_free_errors(error_list);
1349 : }
1350 : /* We do not return here intentionally */
1351 : }
1352 :
1353 1 : ini_config_file_destroy(file_ctx);
1354 :
1355 1 : INIOUT(col_debug_collection(ini_config->cfg, COL_TRAVERSE_DEFAULT));
1356 :
1357 1 : ini_config_destroy(ini_config);
1358 :
1359 1 : INIOUT(printf("<==== Startup test end ====>\n"));
1360 :
1361 : return 0;
1362 : }
1363 :
1364 1 : static int reload_test(void)
1365 : {
1366 1 : int error = EOK;
1367 1 : struct ini_cfgfile *file_ctx = NULL;
1368 1 : struct ini_cfgfile *file_ctx_new = NULL;
1369 : char infile[PATH_MAX];
1370 : char outfile[PATH_MAX];
1371 : char command[PATH_MAX * 3];
1372 : char *srcdir;
1373 : char *builddir;
1374 1 : int changed = 0;
1375 :
1376 1 : INIOUT(printf("<==== Reload test ====>\n"));
1377 :
1378 1 : srcdir = getenv("srcdir");
1379 1 : snprintf(infile, PATH_MAX, "%s/ini/ini.d/foo.conf.in",
1380 : (srcdir == NULL) ? "." : srcdir);
1381 1 : builddir = getenv("builddir");
1382 1 : snprintf(outfile, PATH_MAX, "%s/foo.conf",
1383 : (builddir == NULL) ? "." : builddir);
1384 :
1385 1 : snprintf(command, PATH_MAX * 3, "cp %s %s", infile, outfile);
1386 1 : INIOUT(printf("Running command '%s'\n", command));
1387 :
1388 1 : error = system(command);
1389 1 : if ((error) || (WEXITSTATUS(error))) {
1390 0 : printf("Failed to run copy command %d %d.\n", error,
1391 0 : WEXITSTATUS(error));
1392 0 : return -1;
1393 : }
1394 :
1395 1 : INIOUT(printf("Running chmod 660 on file '%s'\n", outfile));
1396 1 : error = chmod(outfile, S_IRUSR | S_IWUSR);
1397 1 : if (error) {
1398 0 : error = errno;
1399 0 : printf("Failed to run chmod command %d.\n", error);
1400 0 : return error;
1401 : }
1402 :
1403 1 : INIOUT(printf("About to open file: %s'\n", outfile));
1404 :
1405 : /* Open config file */
1406 1 : error = ini_config_file_open(outfile,
1407 : INI_META_STATS,
1408 : &file_ctx);
1409 1 : if (error) {
1410 0 : printf("Failed to open file %s for reading. Error %d.\n",
1411 : outfile, error);
1412 0 : return error;
1413 : }
1414 :
1415 1 : INIOUT(printf("About to check access to the file.\n"));
1416 :
1417 1 : error = ini_config_access_check(
1418 : file_ctx,
1419 : INI_ACCESS_CHECK_MODE, /* add uid & gui flags
1420 : * in real case
1421 : */
1422 : 0, /* <- will be real uid in real case */
1423 : 0, /* <- will be real gid in real case */
1424 : 0600, /* Checkling for rw------- */
1425 : 0);
1426 :
1427 1 : if (error) {
1428 0 : printf("Access check failed %d!\n", error);
1429 0 : ini_config_file_destroy(file_ctx);
1430 0 : return EACCES;
1431 : }
1432 :
1433 : /* ... Create config object and read configuration - not shown here.
1434 : * See other examples ... */
1435 :
1436 1 : INIOUT(printf("About to close file.\n"));
1437 :
1438 : /* Now close file but leave the context around */
1439 1 : ini_config_file_close(file_ctx);
1440 :
1441 1 : INIOUT(printf("About to reopen file.\n"));
1442 :
1443 : /* Some time passed and we received a signal to reload... */
1444 1 : error = ini_config_file_reopen(file_ctx, &file_ctx_new);
1445 1 : if (error) {
1446 0 : printf("Failed to re-open file for reading. Error %d.\n", error);
1447 0 : ini_config_file_destroy(file_ctx);
1448 0 : return error;
1449 : }
1450 :
1451 1 : INIOUT(printf("About to check if the file changed.\n"));
1452 :
1453 1 : changed = 0;
1454 1 : error = ini_config_changed(file_ctx,
1455 : file_ctx_new,
1456 : &changed);
1457 1 : if (error) {
1458 0 : printf("Failed to compare files. Error %d.\n", error);
1459 0 : ini_config_file_destroy(file_ctx);
1460 0 : ini_config_file_destroy(file_ctx_new);
1461 0 : return error;
1462 : }
1463 :
1464 : /* Check if file changed */
1465 1 : if (changed) {
1466 0 : printf("File changed when it shouldn't. This is unexpected error.\n");
1467 0 : ini_config_file_print(file_ctx);
1468 0 : ini_config_file_print(file_ctx_new);
1469 0 : ini_config_file_destroy(file_ctx);
1470 0 : ini_config_file_destroy(file_ctx_new);
1471 0 : return EINVAL;
1472 : }
1473 :
1474 1 : INIOUT(printf("File did not change - expected. Close and force the change!.\n"));
1475 :
1476 : /* Close file */
1477 1 : ini_config_file_destroy(file_ctx_new);
1478 :
1479 1 : INIOUT(printf("To force the change delete the file: %s\n", outfile));
1480 :
1481 : /* Emulate as if file changed */
1482 1 : errno = 0;
1483 1 : if (unlink(outfile)) {
1484 0 : error = errno;
1485 0 : printf("Failed to delete file %d.\n", error);
1486 0 : ini_config_file_destroy(file_ctx);
1487 0 : return error;
1488 : }
1489 :
1490 1 : sleep(1);
1491 :
1492 1 : snprintf(command, PATH_MAX * 3, "cp %s %s", infile, outfile);
1493 1 : INIOUT(printf("Copy file again with command '%s'\n", command));
1494 :
1495 1 : error = system(command);
1496 1 : if ((error) || (WEXITSTATUS(error))) {
1497 0 : printf("Failed to run copy command %d %d.\n", error, WEXITSTATUS(error));
1498 0 : ini_config_file_destroy(file_ctx);
1499 0 : return -1;
1500 : }
1501 :
1502 1 : INIOUT(printf("Read file again.\n"));
1503 :
1504 : /* Read again */
1505 1 : file_ctx_new = NULL;
1506 1 : error = ini_config_file_reopen(file_ctx, &file_ctx_new);
1507 1 : if (error) {
1508 0 : printf("Failed to re-open file for reading. Error %d.\n", error);
1509 0 : ini_config_file_destroy(file_ctx);
1510 0 : return error;
1511 : }
1512 :
1513 1 : INIOUT(printf("Check if it changed.\n"));
1514 :
1515 1 : changed = 0;
1516 1 : error = ini_config_changed(file_ctx,
1517 : file_ctx_new,
1518 : &changed);
1519 1 : if (error) {
1520 0 : printf("Failed to compare files. Error %d.\n", error);
1521 0 : ini_config_file_destroy(file_ctx);
1522 0 : ini_config_file_destroy(file_ctx_new);
1523 0 : return error;
1524 : }
1525 :
1526 1 : INIOUT(printf("Changed value is %d.\n", changed));
1527 :
1528 : /* Check if file changed */
1529 1 : if (!changed) {
1530 0 : printf("File did not change when it should. This is an error.\n");
1531 0 : ini_config_file_print(file_ctx);
1532 0 : ini_config_file_print(file_ctx_new);
1533 0 : ini_config_file_destroy(file_ctx);
1534 0 : ini_config_file_destroy(file_ctx_new);
1535 0 : return EINVAL;
1536 : }
1537 :
1538 1 : INIOUT(printf("File changed!\n"));
1539 1 : INIOUT(ini_config_file_print(file_ctx));
1540 1 : INIOUT(ini_config_file_print(file_ctx_new));
1541 :
1542 : /* We do not need original context any more. */
1543 1 : ini_config_file_destroy(file_ctx);
1544 :
1545 : /* New context is now original context */
1546 1 : file_ctx = file_ctx_new;
1547 :
1548 : /* ... Create config object and read configuration - not shown here.
1549 : * See other examples ... */
1550 :
1551 1 : ini_config_file_destroy(file_ctx);
1552 :
1553 1 : INIOUT(printf("<==== Reload test end ====>\n"));
1554 : return 0;
1555 : }
1556 :
1557 14 : static int test_one_array(struct ini_cfgobj *ini_config,
1558 : const char *section,
1559 : const char *value,
1560 : int raw,
1561 : int expect,
1562 : const char *sep,
1563 : const char *message)
1564 : {
1565 14 : struct value_obj *vo = NULL;
1566 14 : int error = 0;
1567 14 : int size = 0;
1568 : char **strarray;
1569 : char **strptr;
1570 : int i;
1571 :
1572 14 : INIOUT(printf("%s",message));
1573 :
1574 14 : vo = NULL;
1575 14 : error = ini_get_config_valueobj(section,
1576 : value,
1577 : ini_config,
1578 : INI_GET_FIRST_VALUE,
1579 : &vo);
1580 14 : if(error) {
1581 0 : printf("Expected success but got error! %d\n",error);
1582 0 : return error;
1583 : }
1584 :
1585 : /* Value should be found */
1586 14 : if (vo == NULL) {
1587 0 : printf("Expected success but got NULL. Section %s value %s, %s\n", section, value, raw ? "raw" : "interpreted");
1588 0 : return -1;
1589 : }
1590 :
1591 14 : INIOUT(value_print(value, vo));
1592 :
1593 14 : INIOUT(printf("Get str array with size.\n"));
1594 :
1595 14 : error = 0;
1596 :
1597 14 : if (raw) strarray = ini_get_raw_string_config_array(vo, sep, &size, &error);
1598 7 : else strarray = ini_get_string_config_array(vo, sep, &size, &error);
1599 14 : if (error) {
1600 0 : printf("Expect success got error %d.\n", error);
1601 0 : return error;
1602 : }
1603 :
1604 : /* Can be used with this cycle */
1605 : strptr = strarray;
1606 49 : while (*strptr != NULL) {
1607 35 : INIOUT(printf("[%s]\n",*strptr));
1608 35 : strptr++;
1609 : }
1610 :
1611 14 : if (size != expect) {
1612 0 : printf("Expected %d but got %d.\n", expect, size);
1613 0 : ini_free_string_config_array(strarray);
1614 0 : return -1;
1615 : }
1616 :
1617 : /* Can be used with this cycle */
1618 14 : INIOUT(for (i=0; i<size; i++) printf("[%s]\n", *(strarray + i)));
1619 :
1620 14 : ini_free_string_config_array(strarray);
1621 :
1622 14 : return EOK;
1623 : }
1624 :
1625 1 : static int get_test(void)
1626 : {
1627 :
1628 : int error;
1629 : int number;
1630 : long number_long;
1631 : double number_double;
1632 : unsigned number_unsigned;
1633 : unsigned long number_ulong;
1634 1 : unsigned char logical = 0;
1635 : char *str;
1636 : const char *cstr;
1637 : const char *cstrn;
1638 : void *binary;
1639 : int length;
1640 1 : int i = 0;
1641 : char **strarray;
1642 : char **strptr;
1643 : int size;
1644 : long *array;
1645 : double *darray;
1646 : char **prop_array;
1647 : int32_t val_int32;
1648 : uint32_t val_uint32;
1649 : int64_t val_int64;
1650 : uint64_t val_uint64;
1651 1 : struct ini_cfgfile *file_ctx = NULL;
1652 1 : struct ini_cfgobj *ini_config = NULL;
1653 1 : struct value_obj *vo = NULL;
1654 1 : char **error_list = NULL;
1655 : char infile[PATH_MAX];
1656 1 : char *srcdir = NULL;
1657 1 : int bad_val = 0;
1658 :
1659 : /* Define structure for testing arrays in the loop */
1660 : struct a_t { char section[100];
1661 : char value[100];
1662 : int raw;
1663 : int expect;
1664 : char sep[10];
1665 1 : char message[100]; } array_test[NUM_TESTS] =
1666 : {
1667 : { "services",
1668 : "activeServices",
1669 : 0,
1670 : 4,
1671 : ",:;",
1672 : "Make sure we parse string array properly\n"},
1673 :
1674 : { "services",
1675 : "activeServices",
1676 : 1,
1677 : 4,
1678 : ",:;",
1679 : "Make sure we parse raw string array properly\n"},
1680 :
1681 : { "domains",
1682 : "domainsOrder",
1683 : 0,
1684 : 3,
1685 : ",:;",
1686 : "Parse string array with comma at the end\n"},
1687 :
1688 : { "domains",
1689 : "domainsOrder",
1690 : 1,
1691 : 8,
1692 : ",:;",
1693 : "Parse raw string array with comma at the end\n"},
1694 :
1695 : { "domains",
1696 : "badarray",
1697 : 0,
1698 : 0,
1699 : ",:;",
1700 : "Bad array should have no tokens\n"},
1701 :
1702 : { "domains",
1703 : "badarray",
1704 : 1,
1705 : 6,
1706 : ",:;",
1707 : "Raw bad array should have right number of tokens.\n"},
1708 :
1709 : { "domains",
1710 : "somearray",
1711 : 0,
1712 : 0,
1713 : ",:;",
1714 : "Bad array should have no tokens\n"},
1715 :
1716 : { "domains",
1717 : "somearray",
1718 : 1,
1719 : 2,
1720 : ",:;",
1721 : "Raw bad array should have right number of tokens.\n"},
1722 :
1723 : { "domains",
1724 : "someotherarray",
1725 : 0,
1726 : 0,
1727 : ",:;",
1728 : "Bad array should have no tokens\n"},
1729 :
1730 : { "domains",
1731 : "someotherarray",
1732 : 1,
1733 : 3,
1734 : ",:;",
1735 : "Raw bad array should have right number of tokens.\n"},
1736 :
1737 : { "domains",
1738 : "justdelim",
1739 : 0,
1740 : 0,
1741 : ",:;",
1742 : "Bad array should have no tokens\n"},
1743 :
1744 : { "domains",
1745 : "justdelim",
1746 : 1,
1747 : 5,
1748 : ",:;",
1749 : "Delimeters only should have right number of tokens.\n"},
1750 :
1751 : { "domains",
1752 : "yetanother",
1753 : 0,
1754 : 0,
1755 : ",:;",
1756 : "Empty array should have no tokens.\n"},
1757 :
1758 : { "domains",
1759 : "yetanother",
1760 : 1,
1761 : 0,
1762 : ",:;",
1763 : "Empty raw array should have no token.\n"}
1764 : };
1765 :
1766 : /*****************************************************/
1767 :
1768 1 : INIOUT(printf("\n\n<==== GET TEST START =====>\n"));
1769 1 : INIOUT(printf("Creating configuration object\n"));
1770 :
1771 : /* Create config collection */
1772 1 : error = ini_config_create(&ini_config);
1773 1 : if (error) {
1774 0 : printf("Failed to create collection. Error %d.\n", error);
1775 0 : return error;
1776 : }
1777 :
1778 1 : srcdir = getenv("srcdir");
1779 1 : snprintf(infile, PATH_MAX, "%s/ini/ini.d/real.conf",
1780 : (srcdir == NULL) ? "." : srcdir);
1781 :
1782 1 : INIOUT(printf("Reading file %s\n", infile));
1783 :
1784 1 : error = ini_config_file_open(infile,
1785 : 0,
1786 : &file_ctx);
1787 1 : if (error) {
1788 0 : printf("Failed to open file for reading. Error %d.\n", error);
1789 0 : ini_config_destroy(ini_config);
1790 0 : return error;
1791 : }
1792 :
1793 1 : error = ini_config_parse(file_ctx,
1794 : INI_STOP_ON_NONE,
1795 : /* Merge section but allow duplicates */
1796 : INI_MS_MERGE |
1797 : INI_MV1S_ALLOW |
1798 : INI_MV2S_ALLOW,
1799 : 0,
1800 : ini_config);
1801 1 : if (error) {
1802 0 : INIOUT(printf("Failed to parse configuration. Error %d.\n", error));
1803 :
1804 0 : if (ini_config_error_count(ini_config)) {
1805 0 : INIOUT(printf("Errors detected while parsing: %s\n",
1806 : ini_config_get_filename(file_ctx)));
1807 0 : ini_config_get_errors(ini_config, &error_list);
1808 0 : INIOUT(ini_config_print_errors(stdout, error_list));
1809 0 : ini_config_free_errors(error_list);
1810 : }
1811 : /* We do not return here intentionally */
1812 : }
1813 :
1814 1 : ini_config_file_destroy(file_ctx);
1815 :
1816 1 : INIOUT(printf("Negtive test - trying to get non"
1817 : " existing key-value pair.\n"));
1818 :
1819 : /* Negative test */
1820 1 : vo = NULL;
1821 1 : error = ini_get_config_valueobj("monitor1",
1822 : "description1",
1823 : ini_config,
1824 : INI_GET_FIRST_VALUE,
1825 : &vo);
1826 1 : if (error) {
1827 0 : printf("Expected success but got error! %d\n", error);
1828 0 : ini_config_destroy(ini_config);
1829 0 : return error;
1830 : }
1831 :
1832 : /* Values should not be found */
1833 1 : if (vo != NULL) {
1834 0 : printf("Expected NULL but got something else!\n");
1835 0 : ini_config_destroy(ini_config);
1836 0 : return -1;
1837 : }
1838 :
1839 : /* Another negative test but section exists this time */
1840 1 : vo = NULL;
1841 1 : error = ini_get_config_valueobj("monitor",
1842 : "description1",
1843 : ini_config,
1844 : INI_GET_FIRST_VALUE,
1845 : &vo);
1846 1 : if (error) {
1847 0 : printf("Expected success but got error! %d\n", error);
1848 0 : ini_config_destroy(ini_config);
1849 0 : return error;
1850 : }
1851 :
1852 : /* Valueobj should not be found */
1853 1 : if(vo != NULL) {
1854 0 : printf("Expected NULL but got something else!\n");
1855 0 : ini_config_destroy(ini_config);
1856 0 : return -1;
1857 : }
1858 :
1859 1 : INIOUT(printf("Trying to get a value.\n"));
1860 :
1861 : /* Positive test */
1862 1 : vo = NULL;
1863 1 : error = ini_get_config_valueobj("monitor",
1864 : "description",
1865 : ini_config,
1866 : INI_GET_FIRST_VALUE,
1867 : &vo);
1868 1 : if (error) {
1869 0 : printf("Expected success but got error! %d\n", error);
1870 0 : ini_config_destroy(ini_config);
1871 0 : return error;
1872 : }
1873 :
1874 : /* Value should be found */
1875 1 : if (vo == NULL) {
1876 0 : printf("Expected value but got NULL!\n");
1877 0 : ini_config_destroy(ini_config);
1878 0 : return -1;
1879 : }
1880 :
1881 1 : INIOUT(value_print("description", vo));
1882 :
1883 1 : INIOUT(printf("Get values as string without duplication"
1884 : " from the NULL valueobj.\n"));
1885 :
1886 : /* Get a string without duplicication */
1887 : /* Negative test */
1888 1 : cstrn = ini_get_const_string_config_value(NULL, NULL);
1889 1 : if (cstrn != NULL) {
1890 0 : printf("Expected error got success.\n");
1891 0 : ini_config_destroy(ini_config);
1892 0 : return -1;
1893 : }
1894 :
1895 1 : INIOUT(printf("Get value as string without duplication"
1896 : "from the correct value object.\n"));
1897 :
1898 : /* Now get string from the right value object */
1899 1 : error = 0;
1900 1 : cstr = ini_get_const_string_config_value(vo, &error);
1901 1 : if (error) {
1902 0 : printf("Expected success got error %d.\n", error);
1903 0 : ini_config_destroy(ini_config);
1904 0 : return error;
1905 : }
1906 :
1907 1 : INIOUT(printf("Value: [%s]\n", cstr));
1908 :
1909 : /* Same thing but create a dup */
1910 :
1911 1 : INIOUT(printf("Get value as string with duplication"
1912 : " from correct value object.\n"));
1913 :
1914 1 : error = 0;
1915 1 : str = ini_get_string_config_value(vo, &error);
1916 1 : if (error) {
1917 0 : printf("Expected success got error %d.\n", error);
1918 0 : ini_config_destroy(ini_config);
1919 0 : return error;
1920 : }
1921 :
1922 1 : INIOUT(printf("Value: [%s]\n", str));
1923 1 : free(str);
1924 :
1925 :
1926 : /* Get a badly formated number */
1927 1 : INIOUT(printf("Convert value to number with strict conversion.\n"));
1928 :
1929 1 : vo = NULL;
1930 1 : error = ini_get_config_valueobj("monitor",
1931 : "bad_number",
1932 : ini_config,
1933 : INI_GET_FIRST_VALUE,
1934 : &vo);
1935 1 : if (error) {
1936 0 : printf("Expected success but got error! %d\n", error);
1937 0 : ini_config_destroy(ini_config);
1938 0 : return error;
1939 : }
1940 :
1941 : /* Value should be found */
1942 1 : if (vo == NULL) {
1943 0 : printf("Expected value but got something NULL!\n");
1944 0 : ini_config_destroy(ini_config);
1945 0 : return -1;
1946 : }
1947 :
1948 1 : INIOUT(value_print("bad_number", vo));
1949 :
1950 : /* Now try to get value in different ways */
1951 1 : error = 0;
1952 1 : number = ini_get_int_config_value(vo, 1, 10, &error);
1953 1 : if (error) {
1954 : /* We expected error in this case */
1955 1 : INIOUT(printf("Expected error.\n"));
1956 1 : if(number != 10) {
1957 0 : printf("It failed to set default value.\n");
1958 0 : ini_config_destroy(ini_config);
1959 0 : return -1;
1960 : }
1961 : }
1962 : else {
1963 0 : printf("Expected error got success.\n");
1964 0 : ini_config_destroy(ini_config);
1965 0 : return -1;
1966 : }
1967 :
1968 1 : INIOUT(printf("Convert value to number without strict conversion.\n"));
1969 :
1970 1 : error = 0;
1971 1 : number = ini_get_int_config_value(vo, 0, 10, &error);
1972 1 : if (error) {
1973 0 : printf("Did not expect error.\n");
1974 0 : ini_config_destroy(ini_config);
1975 0 : return error;
1976 : }
1977 :
1978 1 : if (number != 5) {
1979 0 : printf("We expected that the conversion will return 5.\n");
1980 0 : ini_config_destroy(ini_config);
1981 0 : return -1;
1982 : }
1983 :
1984 : /* Get real integer */
1985 :
1986 1 : INIOUT(printf("Fetch another value from section \"domains/LOCAL\""
1987 : " named \"enumerate\".\n"));
1988 :
1989 1 : vo = NULL;
1990 1 : error = ini_get_config_valueobj("domains/LOCAL",
1991 : "enumerate",
1992 : ini_config,
1993 : INI_GET_FIRST_VALUE,
1994 : &vo);
1995 1 : if (error) {
1996 0 : printf("Expected success but got error! %d\n", error);
1997 0 : ini_config_destroy(ini_config);
1998 0 : return error;
1999 : }
2000 :
2001 : /* Value should be found */
2002 1 : if (vo == NULL) {
2003 0 : printf("Expected success but got NULL.\n");
2004 0 : ini_config_destroy(ini_config);
2005 0 : return -1;
2006 : }
2007 :
2008 1 : INIOUT(printf("Convert value to integer.\n"));
2009 :
2010 : /* Take number out of it */
2011 1 : error = 0;
2012 1 : number = ini_get_int_config_value(vo, 1, 100, &error);
2013 1 : if (error) {
2014 0 : printf("Did not expect error. Got %d\n", error);
2015 0 : ini_config_destroy(ini_config);
2016 0 : return error;
2017 : }
2018 :
2019 : /* It is 3 in the file */
2020 1 : if (number != 3) {
2021 0 : printf("We expected that the conversion will return 3.\n");
2022 0 : ini_config_destroy(ini_config);
2023 0 : return -1;
2024 : }
2025 :
2026 1 : INIOUT(printf("Expected 3 got %d\n", number));
2027 :
2028 1 : INIOUT(printf("Convert value to long.\n"));
2029 :
2030 : /* Take number out of it */
2031 1 : error = 0;
2032 1 : number_long = ini_get_long_config_value(vo, 1, 100, &error);
2033 1 : if (error) {
2034 0 : printf("Did not expect error. Got %d\n", error);
2035 0 : ini_config_destroy(ini_config);
2036 0 : return error;
2037 : }
2038 :
2039 : /* It is 3 in the file */
2040 1 : if (number_long != 3) {
2041 0 : printf("We expected that the conversion will return 3.\n");
2042 0 : ini_config_destroy(ini_config);
2043 0 : return -1;
2044 : }
2045 :
2046 1 : INIOUT(printf("Expected 3 got %ld\n", number_long));
2047 :
2048 1 : INIOUT(printf("Convert value to unsigned.\n"));
2049 :
2050 : /* Take number out of it */
2051 1 : error = 0;
2052 1 : number_unsigned = ini_get_unsigned_config_value(vo, 1, 100, &error);
2053 1 : if (error) {
2054 0 : printf("Did not expect error. Got %d\n", error);
2055 0 : ini_config_destroy(ini_config);
2056 0 : return error;
2057 : }
2058 :
2059 : /* It is 3 in the file */
2060 1 : if (number_unsigned != 3) {
2061 0 : printf("We expected that the conversion will return 3.\n");
2062 0 : ini_config_destroy(ini_config);
2063 0 : return -1;
2064 : }
2065 :
2066 1 : INIOUT(printf("Expected 3 got %d\n", number_unsigned));
2067 :
2068 1 : INIOUT(printf("Convert value to unsigned long.\n"));
2069 :
2070 : /* Take number out of it */
2071 1 : error = 0;
2072 1 : number_ulong = ini_get_ulong_config_value(vo, 1, 100, &error);
2073 1 : if (error) {
2074 0 : printf("Did not expect error. Got %d\n", error);
2075 0 : ini_config_destroy(ini_config);
2076 0 : return error;
2077 : }
2078 :
2079 : /* It is 3 in the file */
2080 1 : if (number_ulong != 3) {
2081 0 : printf("We expected that the conversion will return 3.\n");
2082 0 : ini_config_destroy(ini_config);
2083 0 : return -1;
2084 : }
2085 :
2086 1 : INIOUT(printf("Expected 3 got %lu\n", number_ulong));
2087 :
2088 1 : INIOUT(printf("Convert value to double.\n"));
2089 :
2090 : /* Take number out of it */
2091 1 : error = 0;
2092 1 : number_double = ini_get_double_config_value(vo, 1, 100., &error);
2093 1 : if (error) {
2094 0 : printf("Did not expect error. Got %d\n", error);
2095 0 : ini_config_destroy(ini_config);
2096 0 : return error;
2097 : }
2098 :
2099 : /* It is 3 in the file */
2100 1 : if (number_double != 3.) {
2101 0 : printf("We expected that the conversion will return 3.\n");
2102 0 : ini_config_destroy(ini_config);
2103 0 : return -1;
2104 : }
2105 :
2106 1 : INIOUT(printf("Expected 3 got %e\n", number_double));
2107 :
2108 1 : INIOUT(printf("Convert value to bool.\n"));
2109 :
2110 : /* Take number out of it */
2111 1 : error = 0;
2112 1 : logical = ini_get_bool_config_value(vo, 1, &error);
2113 1 : if (!error) {
2114 0 : printf("Expect error. Got success. Value %d\n", (int) logical);
2115 0 : ini_config_destroy(ini_config);
2116 0 : return -1;
2117 : }
2118 :
2119 : /* Get real bool values and convert it */
2120 1 : INIOUT(printf("Get real bool value \"legacy\" and convert it.\n"));
2121 :
2122 1 : vo = NULL;
2123 1 : error = ini_get_config_valueobj("domains/LOCAL",
2124 : "legacy",
2125 : ini_config,
2126 : INI_GET_FIRST_VALUE,
2127 : &vo);
2128 1 : if (error) {
2129 0 : printf("Expected success but got error! %d\n",error);
2130 0 : ini_config_destroy(ini_config);
2131 0 : return error;
2132 : }
2133 :
2134 : /* Value should be found */
2135 1 : if (vo == NULL) {
2136 0 : printf("Expected success but got NULL.\n");
2137 0 : ini_config_destroy(ini_config);
2138 0 : return -1;
2139 : }
2140 :
2141 1 : INIOUT(printf("Convert values to bool.\n"));
2142 :
2143 1 : error = 0;
2144 1 : logical = ini_get_bool_config_value(vo, 1, &error);
2145 1 : if (error) {
2146 0 : printf("Expect success got error %d.\n", error);
2147 0 : ini_config_destroy(ini_config);
2148 0 : return error;
2149 : }
2150 :
2151 1 : if (logical) {
2152 0 : printf("Expected false but got true - bad.\n");
2153 0 : return -1;
2154 : }
2155 :
2156 1 : INIOUT(printf("In the files it is FALSE so we got false.\n"));
2157 :
2158 1 : INIOUT(printf("Get binary value\n"));
2159 :
2160 1 : vo = NULL;
2161 1 : error = ini_get_config_valueobj("domains/EXAMPLE.COM",
2162 : "binary_test",
2163 : ini_config,
2164 : INI_GET_FIRST_VALUE,
2165 : &vo);
2166 1 : if (error) {
2167 0 : printf("Expected success but got error! %d\n", error);
2168 0 : ini_config_destroy(ini_config);
2169 0 : return error;
2170 : }
2171 :
2172 : /* Value should be found */
2173 1 : if (vo == NULL) {
2174 0 : printf("Expected success but got NULL.\n");
2175 0 : ini_config_destroy(ini_config);
2176 0 : return -1;
2177 : }
2178 :
2179 1 : INIOUT(value_print("binary_test", vo));
2180 :
2181 1 : error = 0;
2182 1 : binary = ini_get_bin_config_value(vo, &length, &error);
2183 1 : if (error) {
2184 0 : printf("Expect success got error %d.\n", error);
2185 0 : ini_config_destroy(ini_config);
2186 0 : return error;
2187 : }
2188 :
2189 1 : INIOUT(printf("Binary value (expect 123) = "));
2190 1 : INIOUT(for (i = 0; i < length; i++) {
2191 : printf("%d",*((unsigned char*)(binary) + i));
2192 : if (*((unsigned char*)(binary) + i) != (i + 1)) bad_val = 1;
2193 : });
2194 1 : INIOUT(printf("\n"));
2195 :
2196 1 : ini_free_bin_config_value(binary);
2197 :
2198 1 : if (bad_val) {
2199 0 : printf("Unexpected binary value.\n");
2200 0 : ini_config_destroy(ini_config);
2201 0 : return -1;
2202 : }
2203 :
2204 1 : INIOUT(printf("Get another binary value\n"));
2205 :
2206 1 : bad_val = 0;
2207 1 : vo = NULL;
2208 1 : error = ini_get_config_valueobj("domains/EXAMPLE.COM",
2209 : "binary_test_two",
2210 : ini_config,
2211 : INI_GET_FIRST_VALUE,
2212 : &vo);
2213 1 : if (error) {
2214 0 : printf("Expected success but got error! %d\n", error);
2215 0 : ini_config_destroy(ini_config);
2216 0 : return error;
2217 : }
2218 :
2219 : /* Value should be found */
2220 1 : if (vo == NULL) {
2221 0 : printf("Expected success but got NULL.\n");
2222 0 : ini_config_destroy(ini_config);
2223 0 : return -1;
2224 : }
2225 :
2226 1 : INIOUT(value_print("binary_test_two", vo));
2227 :
2228 1 : error = 0;
2229 1 : binary = ini_get_bin_config_value(vo, &length, &error);
2230 1 : if (error) {
2231 0 : printf("Expect success got error %d.\n", error);
2232 0 : ini_config_destroy(ini_config);
2233 0 : return error;
2234 : }
2235 :
2236 1 : INIOUT(printf("Binary value (expect abc) = "));
2237 1 : INIOUT(for (i = 0; i < length; i++) {
2238 : printf("%x",*((unsigned char*)(binary) + i));
2239 : if (*((unsigned char*)(binary) + i) - 10 != i) bad_val = 1;
2240 : });
2241 1 : INIOUT(printf("\n"));
2242 :
2243 1 : ini_free_bin_config_value(binary);
2244 :
2245 1 : if (bad_val) {
2246 0 : printf("Unexpected binary value.\n");
2247 0 : ini_config_destroy(ini_config);
2248 0 : return -1;
2249 : }
2250 :
2251 1 : INIOUT(printf("Get string array value\n"));
2252 :
2253 1 : vo = NULL;
2254 1 : error = ini_get_config_valueobj("domains",
2255 : "domainsorder",
2256 : ini_config,
2257 : INI_GET_FIRST_VALUE,
2258 : &vo);
2259 1 : if(error) {
2260 0 : printf("Expected success but got error! %d\n",error);
2261 0 : ini_config_destroy(ini_config);
2262 0 : return error;
2263 : }
2264 :
2265 : /* Value should be found */
2266 1 : if (vo == NULL) {
2267 0 : printf("Expected success but got NULL.\n");
2268 0 : ini_config_destroy(ini_config);
2269 0 : return -1;
2270 : }
2271 :
2272 1 : INIOUT(value_print("domainsorder", vo));
2273 :
2274 1 : INIOUT(printf("Get str array without size.\n"));
2275 :
2276 1 : error = 0;
2277 1 : strarray = ini_get_string_config_array(vo, ",", NULL, &error);
2278 1 : if (error) {
2279 0 : printf("Expect success got error %d.\n", error);
2280 0 : ini_config_destroy(ini_config);
2281 0 : return error;
2282 : }
2283 :
2284 : /* Can be used with this cycle */
2285 : strptr = strarray;
2286 4 : while (*strptr != NULL) {
2287 3 : INIOUT(printf("[%s]\n",*strptr));
2288 3 : strptr++;
2289 : }
2290 :
2291 1 : ini_free_string_config_array(strarray);
2292 :
2293 1 : INIOUT(printf("Get raw str array without size.\n"));
2294 :
2295 1 : error = 0;
2296 1 : strarray = ini_get_raw_string_config_array(vo, ",", NULL, &error);
2297 1 : if (error) {
2298 0 : printf("Expect success got error %d.\n", error);
2299 0 : ini_config_destroy(ini_config);
2300 0 : return error;
2301 : }
2302 :
2303 : /* Can be used with this cycle */
2304 : strptr = strarray;
2305 9 : while (*strptr != NULL) {
2306 8 : INIOUT(printf("[%s]\n",*strptr));
2307 8 : strptr++;
2308 : }
2309 :
2310 1 : ini_free_string_config_array(strarray);
2311 :
2312 1 : INIOUT(printf("Get str array with size.\n"));
2313 :
2314 1 : error = 0;
2315 1 : size = 0;
2316 1 : strarray = ini_get_string_config_array(vo, ",", &size, &error);
2317 1 : if (error) {
2318 0 : printf("Expect success got error %d.\n", error);
2319 0 : ini_config_destroy(ini_config);
2320 0 : return error;
2321 : }
2322 :
2323 : /* Can be used with this cycle */
2324 1 : INIOUT(for (i=0;i<size;i++) printf("[%s]\n",*(strarray + i)));
2325 :
2326 1 : ini_free_string_config_array(strarray);
2327 :
2328 1 : INIOUT(printf("Get raw str array with size.\n"));
2329 :
2330 1 : error = 0;
2331 1 : size = 0;
2332 1 : strarray = ini_get_raw_string_config_array(vo, ",", &size, &error);
2333 1 : if (error) {
2334 0 : printf("Expect success got error %d.\n", error);
2335 0 : ini_config_destroy(ini_config);
2336 0 : return error;
2337 : }
2338 :
2339 : /* Can be used with this cycle */
2340 1 : INIOUT(for (i=0;i<size;i++) printf("[%s]\n",*(strarray + i)));
2341 :
2342 1 : ini_free_string_config_array(strarray);
2343 :
2344 : /**********************************************************/
2345 :
2346 1 : INIOUT(printf("Get bad string array \n"));
2347 :
2348 1 : vo = NULL;
2349 1 : error = ini_get_config_valueobj("domains",
2350 : "badarray",
2351 : ini_config,
2352 : INI_GET_FIRST_VALUE,
2353 : &vo);
2354 1 : if(error) {
2355 0 : printf("Expected success but got error! %d\n",error);
2356 0 : ini_config_destroy(ini_config);
2357 0 : return error;
2358 : }
2359 :
2360 : /* Value should be found */
2361 1 : if (vo == NULL) {
2362 0 : printf("Expected success but got NULL.\n");
2363 0 : ini_config_destroy(ini_config);
2364 0 : return -1;
2365 : }
2366 :
2367 1 : INIOUT(value_print("badarray", vo));
2368 :
2369 1 : INIOUT(printf("Get bad str array without size.\n"));
2370 :
2371 1 : error = 0;
2372 1 : strarray = ini_get_string_config_array(vo, ",", NULL, &error);
2373 1 : if (error) {
2374 0 : printf("Expect success got error %d.\n", error);
2375 0 : ini_config_destroy(ini_config);
2376 0 : return error;
2377 : }
2378 :
2379 : /* Can be used with this cycle */
2380 : strptr = strarray;
2381 1 : while (*strptr != NULL) {
2382 0 : INIOUT(printf("[%s]\n",*strptr));
2383 0 : strptr++;
2384 : }
2385 :
2386 1 : ini_free_string_config_array(strarray);
2387 :
2388 : /**********************************************************/
2389 :
2390 15 : for (i = 0; i< NUM_TESTS; i++) {
2391 28 : error = test_one_array(ini_config,
2392 14 : array_test[i].section,
2393 14 : array_test[i].value,
2394 : array_test[i].raw,
2395 : array_test[i].expect,
2396 14 : array_test[i].sep,
2397 14 : array_test[i].message);
2398 14 : if (error) {
2399 : /* Message is printed inside function */
2400 0 : ini_config_destroy(ini_config);
2401 0 : return error;
2402 : }
2403 : }
2404 :
2405 : /**********************************************************/
2406 :
2407 1 : INIOUT(printf("Get long array value\n"));
2408 :
2409 1 : vo = NULL;
2410 1 : error = ini_get_config_valueobj("domains/EXAMPLE.COM",
2411 : "long_array",
2412 : ini_config,
2413 : INI_GET_FIRST_VALUE,
2414 : &vo);
2415 1 : if(error) {
2416 0 : printf("Expected success but got error! %d\n", error);
2417 0 : ini_config_destroy(ini_config);
2418 0 : return error;
2419 : }
2420 :
2421 : /* Value should be found */
2422 1 : if (vo == NULL) {
2423 0 : printf("Expected success but got NULL.\n");
2424 0 : ini_config_destroy(ini_config);
2425 0 : return -1;
2426 : }
2427 :
2428 1 : INIOUT(value_print("long_array", vo));
2429 :
2430 1 : error = 0;
2431 1 : size = 0; /* Here size is not optional!!! */
2432 1 : array = ini_get_long_config_array(vo, &size, &error);
2433 1 : if(error) {
2434 0 : printf("Expect success got error %d.\n", error);
2435 0 : ini_config_destroy(ini_config);
2436 0 : return error;
2437 : }
2438 :
2439 : /* Can be used with this cycle */
2440 1 : INIOUT(for (i=0;i<size;i++) printf("%ld\n", *(array + i)));
2441 :
2442 1 : ini_free_long_config_array(array);
2443 :
2444 1 : INIOUT(printf("Get double array value\n"));
2445 :
2446 1 : vo = NULL;
2447 1 : error = ini_get_config_valueobj("domains/EXAMPLE.COM",
2448 : "double_array",
2449 : ini_config,
2450 : INI_GET_FIRST_VALUE,
2451 : &vo);
2452 1 : if (error) {
2453 0 : printf("Expected success but got error! %d\n", error);
2454 0 : ini_config_destroy(ini_config);
2455 0 : return error;
2456 : }
2457 :
2458 : /* Values should be found */
2459 1 : if (vo == NULL) {
2460 0 : printf("Expected success but got NULL.\n");
2461 0 : ini_config_destroy(ini_config);
2462 0 : return -1;
2463 : }
2464 :
2465 1 : INIOUT(value_print("double_array", vo));
2466 :
2467 1 : error = 0;
2468 1 : size = 0; /* Here size is not optional!!! */
2469 1 : darray = ini_get_double_config_array(vo, &size, &error);
2470 1 : if (error) {
2471 0 : printf("Expect success got error %d.\n", error);
2472 0 : ini_config_destroy(ini_config);
2473 0 : return error;
2474 : }
2475 :
2476 : /* Can be used with this cycle */
2477 1 : INIOUT(for (i=0;i<size;i++) printf("%.4f\n", darray[i]));
2478 :
2479 1 : ini_free_double_config_array(darray);
2480 :
2481 1 : INIOUT(printf("\n\nSection list - no size\n"));
2482 :
2483 : /* Do not care about the error or size */
2484 1 : prop_array = ini_get_section_list(ini_config, NULL, NULL);
2485 1 : if (prop_array == NULL) {
2486 0 : printf("Expect success got error.\n");
2487 0 : ini_config_destroy(ini_config);
2488 0 : return -1;
2489 : }
2490 :
2491 1 : i = 0;
2492 1 : INIOUT(while (prop_array[i]) {
2493 : printf("Section: [%s]\n", prop_array[i]);
2494 : i++;
2495 : });
2496 :
2497 1 : ini_free_section_list(prop_array);
2498 :
2499 1 : INIOUT(printf("\n\nSection list - with size\n"));
2500 :
2501 : /* Do not care about the error or size */
2502 1 : prop_array = ini_get_section_list(ini_config, &size, NULL);
2503 1 : if (prop_array == NULL) {
2504 0 : printf("Expect success got error.\n");
2505 0 : ini_config_destroy(ini_config);
2506 0 : return -1;
2507 : }
2508 :
2509 1 : INIOUT(for (i=0;i<size;i++) printf("Section: [%s]\n", prop_array[i]));
2510 1 : ini_free_section_list(prop_array);
2511 :
2512 1 : INIOUT(printf("\n\nAttributes in the section - with size and error\n"));
2513 :
2514 : /* Do not care about the error or size */
2515 1 : prop_array = ini_get_attribute_list(ini_config,
2516 : "domains/EXAMPLE.COM",
2517 : &size,
2518 : &error);
2519 1 : if (prop_array == NULL) {
2520 0 : printf("Expect success got error.\n");
2521 0 : ini_config_destroy(ini_config);
2522 0 : return -1;
2523 : }
2524 :
2525 1 : INIOUT(for (i=0;i<size;i++) printf("Attribute: [%s]\n", prop_array[i]));
2526 1 : ini_free_attribute_list(prop_array);
2527 :
2528 :
2529 : /***************************************/
2530 : /* Test special types */
2531 : /***************************************/
2532 1 : INIOUT(printf("Test int32_t\n"));
2533 :
2534 1 : vo = NULL;
2535 1 : error = ini_get_config_valueobj("domains/EXAMPLE.COM",
2536 : "int32_t",
2537 : ini_config,
2538 : INI_GET_FIRST_VALUE,
2539 : &vo);
2540 1 : if (error) {
2541 0 : printf("Expected success but got error! %d\n", error);
2542 0 : ini_config_destroy(ini_config);
2543 0 : return error;
2544 : }
2545 :
2546 : /* Value should be found */
2547 1 : if (vo == NULL) {
2548 0 : printf("Expected success but got NULL.\n");
2549 0 : ini_config_destroy(ini_config);
2550 0 : return -1;
2551 : }
2552 :
2553 1 : INIOUT(value_print("int32_t", vo));
2554 :
2555 1 : error = 0;
2556 1 : val_int32 = ini_get_int32_config_value(vo, 1, 0, &error);
2557 1 : if (error) {
2558 0 : printf("Expect success got error %d.\n", error);
2559 0 : ini_config_destroy(ini_config);
2560 0 : return error;
2561 : }
2562 :
2563 1 : INIOUT(printf("Value: %d\n", val_int32));
2564 :
2565 : /***************************************/
2566 :
2567 1 : INIOUT(printf("Test uint32_t\n"));
2568 :
2569 1 : vo = NULL;
2570 1 : error = ini_get_config_valueobj("domains/EXAMPLE.COM",
2571 : "uint32_t",
2572 : ini_config,
2573 : INI_GET_FIRST_VALUE,
2574 : &vo);
2575 1 : if (error) {
2576 0 : printf("Expected success but got error! %d\n", error);
2577 0 : ini_config_destroy(ini_config);
2578 0 : return error;
2579 : }
2580 :
2581 : /* Valu should be found */
2582 1 : if (vo == NULL) {
2583 0 : printf("Expected success but got NULL.\n");
2584 0 : ini_config_destroy(ini_config);
2585 0 : return -1;
2586 : }
2587 :
2588 1 : INIOUT(value_print("uint32_t", vo));
2589 :
2590 1 : error = 0;
2591 1 : val_uint32 = ini_get_uint32_config_value(vo, 1, 0, &error);
2592 1 : if (error) {
2593 0 : printf("Expect success got error %d.\n", error);
2594 0 : ini_config_destroy(ini_config);
2595 0 : return error;
2596 : }
2597 :
2598 1 : INIOUT(printf("Value: %u\n", val_uint32));
2599 :
2600 : /***************************************/
2601 :
2602 1 : INIOUT(printf("Test int64_t\n"));
2603 :
2604 1 : vo = NULL;
2605 1 : error = ini_get_config_valueobj("domains/EXAMPLE.COM",
2606 : "int64_t",
2607 : ini_config,
2608 : INI_GET_FIRST_VALUE,
2609 : &vo);
2610 1 : if (error) {
2611 0 : printf("Expected success but got error! %d\n", error);
2612 0 : ini_config_destroy(ini_config);
2613 0 : return error;
2614 : }
2615 :
2616 : /* Value should be found */
2617 1 : if (vo == NULL) {
2618 0 : printf("Expected success but got NULL.\n");
2619 0 : ini_config_destroy(ini_config);
2620 0 : return -1;
2621 : }
2622 :
2623 1 : INIOUT(value_print("int64_t", vo));
2624 :
2625 1 : error = 0;
2626 1 : val_int64 = ini_get_int64_config_value(vo, 1, 0, &error);
2627 1 : if (error) {
2628 0 : printf("Expect success got error %d.\n", error);
2629 0 : ini_config_destroy(ini_config);
2630 0 : return error;
2631 : }
2632 :
2633 1 : INIOUT(printf("Value: %lld\n", (long long)val_int64));
2634 :
2635 : /***************************************/
2636 :
2637 1 : INIOUT(printf("Test uint32_t\n"));
2638 :
2639 1 : vo = NULL;
2640 1 : error = ini_get_config_valueobj("domains/EXAMPLE.COM",
2641 : "uint64_t",
2642 : ini_config,
2643 : INI_GET_FIRST_VALUE,
2644 : &vo);
2645 1 : if (error) {
2646 0 : printf("Expected success but got error! %d\n", error);
2647 0 : ini_config_destroy(ini_config);
2648 0 : return error;
2649 : }
2650 :
2651 : /* Value should be found */
2652 1 : if (vo == NULL) {
2653 0 : printf("Expected success but got NULL.\n");
2654 0 : ini_config_destroy(ini_config);
2655 0 : return -1;
2656 : }
2657 :
2658 1 : INIOUT(value_print("uint64_t", vo));
2659 :
2660 1 : error = 0;
2661 1 : val_uint64 = ini_get_uint64_config_value(vo, 1, 0, &error);
2662 1 : if (error) {
2663 0 : printf("Expect success got error %d.\n", error);
2664 0 : ini_config_destroy(ini_config);
2665 0 : return error;
2666 : }
2667 :
2668 1 : INIOUT(printf("Value: %llu\n", (unsigned long long)val_uint64));
2669 :
2670 : /***************************************/
2671 :
2672 1 : INIOUT(printf("Get empty array value object\n"));
2673 :
2674 1 : vo = NULL;
2675 1 : error = ini_get_config_valueobj("domains/EXAMPLE.COM",
2676 : "empty_value",
2677 : ini_config,
2678 : INI_GET_FIRST_VALUE,
2679 : &vo);
2680 1 : if(error) {
2681 0 : printf("Expected success but got error! %d\n", error);
2682 0 : ini_config_destroy(ini_config);
2683 0 : return error;
2684 : }
2685 :
2686 : /* Value should be found */
2687 1 : if (vo == NULL) {
2688 0 : printf("Expected success but got NULL.\n");
2689 0 : ini_config_destroy(ini_config);
2690 0 : return -1;
2691 : }
2692 :
2693 1 : INIOUT(value_print("empty_value", vo));
2694 :
2695 1 : error = 0;
2696 1 : size = 0; /* Here size is not optional!!! */
2697 1 : strarray = ini_get_string_config_array(vo, ",", &size, &error);
2698 1 : if(error) {
2699 0 : printf("Expect success got error %d.\n", error);
2700 0 : ini_config_destroy(ini_config);
2701 0 : return error;
2702 : }
2703 :
2704 1 : if (size != 0) {
2705 0 : for (i=0; i<size; i++) printf("%s\n", *(strarray + i));
2706 0 : printf("Expected size=0, got size=%d\n", size);
2707 0 : ini_free_string_config_array(strarray);
2708 0 : ini_config_destroy(ini_config);
2709 0 : return -1;
2710 : }
2711 :
2712 1 : ini_free_string_config_array(strarray);
2713 :
2714 : /***************************************/
2715 :
2716 1 : INIOUT(printf("\nGet last value\n"));
2717 :
2718 1 : vo = NULL;
2719 1 : error = ini_get_config_valueobj("domains/EXAMPLE.COM",
2720 : "server",
2721 : ini_config,
2722 : INI_GET_LAST_VALUE,
2723 : &vo);
2724 1 : if(error) {
2725 0 : printf("Expected success but got error! %d\n", error);
2726 0 : ini_config_destroy(ini_config);
2727 0 : return error;
2728 : }
2729 :
2730 : /* Value should be found */
2731 1 : if (vo == NULL) {
2732 0 : printf("Expected success but got NULL.\n");
2733 0 : ini_config_destroy(ini_config);
2734 0 : return -1;
2735 : }
2736 :
2737 1 : INIOUT(value_print("server", vo));
2738 :
2739 : /***************************************/
2740 :
2741 1 : INIOUT(printf("\nGet sequence of the multi-value keys\n"));
2742 :
2743 1 : vo = NULL;
2744 1 : error = ini_get_config_valueobj("domains/EXAMPLE.COM",
2745 : "server",
2746 : ini_config,
2747 : INI_GET_FIRST_VALUE,
2748 : &vo);
2749 1 : if(error) {
2750 0 : printf("Expected success but got error! %d\n", error);
2751 0 : ini_config_destroy(ini_config);
2752 0 : return error;
2753 : }
2754 :
2755 : /* Value should be found */
2756 1 : if (vo == NULL) {
2757 0 : printf("Expected success but got NULL.\n");
2758 0 : ini_config_destroy(ini_config);
2759 0 : return -1;
2760 : }
2761 :
2762 1 : INIOUT(value_print("server", vo));
2763 :
2764 :
2765 : do {
2766 :
2767 4 : vo = NULL;
2768 4 : error = ini_get_config_valueobj("domains/EXAMPLE.COM",
2769 : "server",
2770 : ini_config,
2771 : INI_GET_NEXT_VALUE,
2772 : &vo);
2773 4 : if(error) {
2774 0 : printf("Expected success but got error! %d\n", error);
2775 0 : ini_config_destroy(ini_config);
2776 0 : return error;
2777 : }
2778 :
2779 4 : if (vo == NULL) break;
2780 :
2781 3 : INIOUT(value_print("server", vo));
2782 : }
2783 : while(1);
2784 :
2785 : /***************************************/
2786 :
2787 1 : INIOUT(printf("\nGet multi-value keys without prefetching\n"));
2788 :
2789 : do {
2790 :
2791 5 : vo = NULL;
2792 5 : error = ini_get_config_valueobj("domains/EXAMPLE.COM",
2793 : "server",
2794 : ini_config,
2795 : INI_GET_NEXT_VALUE,
2796 : &vo);
2797 5 : if(error) {
2798 0 : printf("Expected success but got error! %d\n", error);
2799 0 : ini_config_destroy(ini_config);
2800 0 : return error;
2801 : }
2802 :
2803 5 : if (vo == NULL) break;
2804 :
2805 4 : INIOUT(value_print("server", vo));
2806 : }
2807 : while(1);
2808 :
2809 : /***************************************/
2810 :
2811 1 : INIOUT(printf("\nGet multi-value keys with key interrupt\n"));
2812 :
2813 1 : i = 0;
2814 :
2815 1 : vo = NULL;
2816 : do {
2817 :
2818 7 : vo = NULL;
2819 7 : error = ini_get_config_valueobj("domains/EXAMPLE.COM",
2820 : "server",
2821 : ini_config,
2822 : INI_GET_NEXT_VALUE,
2823 : &vo);
2824 7 : if(error) {
2825 0 : printf("Expected success but got error! %d\n", error);
2826 0 : ini_config_destroy(ini_config);
2827 0 : return error;
2828 : }
2829 :
2830 7 : if (vo == NULL) break;
2831 :
2832 6 : INIOUT(value_print("server", vo));
2833 6 : i++;
2834 :
2835 6 : if (i==2) {
2836 1 : vo = NULL;
2837 1 : error = ini_get_config_valueobj("domains/EXAMPLE.COM",
2838 : "empty_value",
2839 : ini_config,
2840 : INI_GET_NEXT_VALUE,
2841 : &vo);
2842 1 : if(error) {
2843 0 : printf("Expected success but got error! %d\n", error);
2844 0 : ini_config_destroy(ini_config);
2845 0 : return error;
2846 : }
2847 : }
2848 : }
2849 : while(1);
2850 :
2851 1 : if (i != 6) {
2852 0 : printf("Expected 6 iterations got %d\n", i);
2853 0 : ini_config_destroy(ini_config);
2854 0 : return -1;
2855 : }
2856 :
2857 : /***************************************/
2858 :
2859 1 : INIOUT(printf("\nGet multi-value keys with section interrupt\n"));
2860 :
2861 1 : i = 0;
2862 :
2863 1 : vo = NULL;
2864 : do {
2865 :
2866 7 : vo = NULL;
2867 7 : error = ini_get_config_valueobj("domains/EXAMPLE.COM",
2868 : "server",
2869 : ini_config,
2870 : INI_GET_NEXT_VALUE,
2871 : &vo);
2872 7 : if(error) {
2873 0 : printf("Expected success but got error! %d\n", error);
2874 0 : ini_config_destroy(ini_config);
2875 0 : return error;
2876 : }
2877 :
2878 7 : if (vo == NULL) break;
2879 :
2880 6 : INIOUT(value_print("server", vo));
2881 6 : i++;
2882 :
2883 6 : if (i==2) {
2884 1 : vo = NULL;
2885 1 : error = ini_get_config_valueobj("domains",
2886 : "badarray",
2887 : ini_config,
2888 : INI_GET_NEXT_VALUE,
2889 : &vo);
2890 1 : if(error) {
2891 0 : printf("Expected success but got error! %d\n", error);
2892 0 : ini_config_destroy(ini_config);
2893 0 : return error;
2894 : }
2895 : }
2896 : }
2897 : while(1);
2898 :
2899 1 : if (i != 6) {
2900 0 : printf("Expected 6 iterations got %d\n", i);
2901 0 : ini_config_destroy(ini_config);
2902 0 : return -1;
2903 : }
2904 :
2905 1 : ini_config_destroy(ini_config);
2906 :
2907 1 : INIOUT(printf("\n<==== GET TEST END =====>\n\n"));
2908 : return EOK;
2909 : }
2910 :
2911 1 : static int space_test(void)
2912 : {
2913 :
2914 : int error;
2915 1 : struct ini_cfgfile *file_ctx = NULL;
2916 1 : struct ini_cfgobj *ini_config = NULL;
2917 1 : char **error_list = NULL;
2918 : char infile[PATH_MAX];
2919 1 : char *srcdir = NULL;
2920 : unsigned errnum;
2921 : int i;
2922 1 : uint32_t flags[] = { INI_PARSE_NOWRAP,
2923 : INI_PARSE_NOWRAP |
2924 : INI_PARSE_NOSPACE,
2925 : INI_PARSE_NOWRAP |
2926 : INI_PARSE_NOTAB,
2927 : INI_PARSE_NOWRAP |
2928 : INI_PARSE_NOSPACE |
2929 : INI_PARSE_NOTAB };
2930 :
2931 1 : INIOUT(printf("\n\n<==== SPACE TEST START =====>\n"));
2932 :
2933 1 : srcdir = getenv("srcdir");
2934 1 : snprintf(infile, PATH_MAX, "%s/ini/ini.d/space.conf",
2935 : (srcdir == NULL) ? "." : srcdir);
2936 :
2937 :
2938 5 : for (i = 0; i < 4; i++ ) {
2939 :
2940 4 : INIOUT(printf("Reading file %s\n", infile));
2941 4 : error = ini_config_file_open(infile,
2942 : 0,
2943 : &file_ctx);
2944 4 : if (error) {
2945 0 : printf("Failed to open file for reading. Error %d.\n", error);
2946 0 : return error;
2947 : }
2948 :
2949 4 : INIOUT(printf("Creating configuration object\n"));
2950 4 : error = ini_config_create(&ini_config);
2951 4 : if (error) {
2952 0 : printf("Failed to create object. Error %d.\n", error);
2953 0 : ini_config_file_destroy(file_ctx);
2954 0 : return error;
2955 : }
2956 4 : INIOUT(printf("Parsing\n"));
2957 4 : error = ini_config_parse(file_ctx,
2958 : INI_STOP_ON_NONE,
2959 : 0,
2960 : flags[i],
2961 : ini_config);
2962 4 : if (error) {
2963 3 : INIOUT(printf("Failed to parse configuration. Error %d.\n", error));
2964 :
2965 3 : errnum = ini_config_error_count(ini_config);
2966 3 : if (errnum) {
2967 3 : INIOUT(printf("Errors detected while parsing: %s\n",
2968 : ini_config_get_filename(file_ctx)));
2969 3 : ini_config_get_errors(ini_config, &error_list);
2970 3 : INIOUT(ini_config_print_errors(stdout, error_list));
2971 3 : ini_config_free_errors(error_list);
2972 : }
2973 6 : if (((i == 0) && (errnum != 0)) ||
2974 6 : ((i == 1) && (errnum != 3)) ||
2975 6 : ((i == 2) && (errnum != 3)) ||
2976 3 : ((i == 3) && (errnum != 4))) {
2977 0 : printf("Failed to open file for reading. Error %d.\n", error);
2978 0 : ini_config_file_destroy(file_ctx);
2979 0 : ini_config_destroy(ini_config);
2980 0 : return -1;
2981 : }
2982 : /* We do not return here intentionally */
2983 : }
2984 :
2985 4 : INIOUT(col_debug_collection(ini_config->cfg, COL_TRAVERSE_DEFAULT));
2986 4 : ini_config_destroy(ini_config);
2987 4 : ini_config_file_destroy(file_ctx);
2988 : }
2989 :
2990 1 : INIOUT(printf("\n<==== SPACE TEST END =====>\n\n"));
2991 : return EOK;
2992 : }
2993 :
2994 :
2995 1 : static int trim_test(void)
2996 : {
2997 : int error;
2998 1 : struct ini_cfgfile *file_ctx = NULL;
2999 1 : struct ini_cfgobj *ini_config = NULL;
3000 1 : char **error_list = NULL;
3001 : char infile[PATH_MAX];
3002 1 : char *srcdir = NULL;
3003 : const char *value;
3004 1 : struct value_obj *vo = NULL;
3005 :
3006 1 : INIOUT(printf("\n\n<==== TRIM TEST START =====>\n"));
3007 :
3008 1 : srcdir = getenv("srcdir");
3009 1 : snprintf(infile, PATH_MAX, "%s/ini/ini.d/real.conf",
3010 : (srcdir == NULL) ? "." : srcdir);
3011 :
3012 :
3013 1 : INIOUT(printf("Reading file %s\n", infile));
3014 1 : error = ini_config_file_open(infile,
3015 : 0,
3016 : &file_ctx);
3017 1 : if (error) {
3018 0 : printf("Failed to open file for reading. Error %d.\n", error);
3019 0 : return error;
3020 : }
3021 :
3022 1 : INIOUT(printf("Creating configuration object\n"));
3023 1 : error = ini_config_create(&ini_config);
3024 1 : if (error) {
3025 0 : printf("Failed to create object. Error %d.\n", error);
3026 0 : ini_config_file_destroy(file_ctx);
3027 0 : return error;
3028 : }
3029 1 : INIOUT(printf("Parsing\n"));
3030 1 : error = ini_config_parse(file_ctx,
3031 : INI_STOP_ON_NONE,
3032 : 0,
3033 : 0,
3034 : ini_config);
3035 1 : if (error) {
3036 0 : INIOUT(printf("Failed to parse configuration. "
3037 : "Error %d.\n", error));
3038 :
3039 0 : if (ini_config_error_count(ini_config)) {
3040 0 : INIOUT(printf("Errors detected while parsing: %s\n",
3041 : ini_config_get_filename(file_ctx)));
3042 0 : ini_config_get_errors(ini_config, &error_list);
3043 0 : INIOUT(ini_config_print_errors(stdout, error_list));
3044 0 : ini_config_free_errors(error_list);
3045 : }
3046 0 : ini_config_file_destroy(file_ctx);
3047 0 : return error;
3048 : }
3049 :
3050 1 : INIOUT(col_debug_collection(ini_config->cfg, COL_TRAVERSE_DEFAULT));
3051 1 : ini_config_file_destroy(file_ctx);
3052 :
3053 1 : vo = NULL;
3054 1 : error = ini_get_config_valueobj("domains/EXAMPLE.COM",
3055 : "description",
3056 : ini_config,
3057 : INI_GET_FIRST_VALUE,
3058 : &vo);
3059 1 : if(error) {
3060 0 : printf("Expected success but got error! %d\n",error);
3061 0 : ini_config_destroy(ini_config);
3062 0 : return error;
3063 : }
3064 :
3065 : /* Value should be found */
3066 1 : if (vo == NULL) {
3067 0 : printf("Expected success but got NULL.\n");
3068 0 : ini_config_destroy(ini_config);
3069 0 : return -1;
3070 : }
3071 :
3072 1 : value = ini_get_const_string_config_value(vo, NULL);
3073 :
3074 1 : if (value == NULL) {
3075 0 : printf("No value.\n");
3076 0 : ini_config_destroy(ini_config);
3077 0 : return -1;
3078 : }
3079 :
3080 1 : if(value[strlen(value) - 1] == ' ') {
3081 0 : printf("Trailing space is not trimmed.\n");
3082 0 : ini_config_destroy(ini_config);
3083 0 : return -1;
3084 : }
3085 :
3086 1 : INIOUT(printf("[%s]\n", value));
3087 :
3088 1 : ini_config_destroy(ini_config);
3089 :
3090 1 : INIOUT(printf("\n<==== TRIM TEST END =====>\n\n"));
3091 : return EOK;
3092 : }
3093 :
3094 1 : static int comment_test(void)
3095 : {
3096 : int error;
3097 1 : struct ini_cfgfile *file_ctx = NULL;
3098 1 : struct ini_cfgobj *ini_config = NULL;
3099 1 : char **error_list = NULL;
3100 : char infile[PATH_MAX];
3101 1 : char *srcdir = NULL;
3102 1 : int err_count = 0;
3103 :
3104 1 : INIOUT(printf("\n\n<==== COMMENT TEST START =====>\n"));
3105 :
3106 1 : srcdir = getenv("srcdir");
3107 1 : snprintf(infile, PATH_MAX, "%s/ini/ini.d/comment.conf",
3108 : (srcdir == NULL) ? "." : srcdir);
3109 :
3110 :
3111 1 : INIOUT(printf("Reading file %s\n", infile));
3112 1 : error = ini_config_file_open(infile,
3113 : 0,
3114 : &file_ctx);
3115 1 : if (error) {
3116 0 : printf("Failed to open file for reading. Error %d.\n", error);
3117 0 : return error;
3118 : }
3119 :
3120 1 : INIOUT(printf("Creating configuration object\n"));
3121 1 : error = ini_config_create(&ini_config);
3122 1 : if (error) {
3123 0 : printf("Failed to create object. Error %d.\n", error);
3124 0 : ini_config_file_destroy(file_ctx);
3125 0 : return error;
3126 : }
3127 1 : INIOUT(printf("Parsing\n"));
3128 1 : error = ini_config_parse(file_ctx,
3129 : INI_STOP_ON_NONE,
3130 : 0,
3131 : 0,
3132 : ini_config);
3133 1 : if (error) {
3134 1 : INIOUT(printf("Failed to parse configuration. "
3135 : "Error %d.\n", error));
3136 1 : err_count = ini_config_error_count(ini_config);
3137 1 : if (err_count) {
3138 1 : INIOUT(printf("Errors detected while parsing: %s\n",
3139 : ini_config_get_filename(file_ctx)));
3140 1 : ini_config_get_errors(ini_config, &error_list);
3141 1 : INIOUT(ini_config_print_errors(stdout, error_list));
3142 1 : ini_config_free_errors(error_list);
3143 : }
3144 : }
3145 :
3146 1 : INIOUT(col_debug_collection(ini_config->cfg, COL_TRAVERSE_DEFAULT));
3147 1 : ini_config_file_destroy(file_ctx);
3148 1 : ini_config_destroy(ini_config);
3149 :
3150 1 : if(err_count != 4) {
3151 0 : printf("Expected 4 errors got: %d\n", err_count);
3152 0 : return 1;
3153 : }
3154 :
3155 1 : INIOUT(printf("\n<==== COMMENT TEST END =====>\n\n"));
3156 : return EOK;
3157 : }
3158 :
3159 1 : static void create_boms(void)
3160 : {
3161 : FILE *f;
3162 :
3163 1 : f = fopen("bom2be","wb");
3164 1 : fprintf(f,"%c%c", 0xFE, 0xFF);
3165 1 : fclose(f);
3166 1 : f = fopen("bom2le","wb");
3167 1 : fprintf(f,"%c%c", 0xFF, 0xFE);
3168 1 : fclose(f);
3169 1 : f = fopen("bom4be","wb");
3170 1 : fprintf(f,"%c%c%c%c", 0x00, 0x00, 0xFE, 0xFF);
3171 1 : fclose(f);
3172 1 : f = fopen("bom4le","wb");
3173 1 : fprintf(f,"%c%c%c%c", 0xFF, 0xFE, 0x00, 0x00);
3174 1 : fclose(f);
3175 1 : f = fopen("bom3","wb");
3176 1 : fprintf(f,"%c%c%c", 0xEF, 0xBB, 0xBF);
3177 1 : fclose(f);
3178 1 : }
3179 :
3180 :
3181 : /* Main function of the unit test */
3182 1 : int main(int argc, char *argv[])
3183 : {
3184 1 : int error = 0;
3185 1 : test_fn tests[] = { read_save_test,
3186 : read_again_test,
3187 : read_mem_test,
3188 : merge_values_test,
3189 : merge_section_test,
3190 : merge_file_test,
3191 : startup_test,
3192 : reload_test,
3193 : get_test,
3194 : space_test,
3195 : trim_test,
3196 : comment_test,
3197 : NULL };
3198 : test_fn t;
3199 1 : int i = 0;
3200 : char *var;
3201 :
3202 1 : if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = 1;
3203 : else {
3204 1 : var = getenv("COMMON_TEST_VERBOSE");
3205 1 : if (var) verbose = 1;
3206 : }
3207 :
3208 : /* Create boms in case we want to create more test files */
3209 1 : create_boms();
3210 :
3211 1 : INIOUT(printf("Start\n"));
3212 :
3213 13 : while ((t = tests[i++])) {
3214 12 : error = t();
3215 12 : fflush(NULL);
3216 12 : if (error) {
3217 0 : INIOUT(printf("Failed with error %d!\n", error));
3218 0 : return error;
3219 : }
3220 : }
3221 :
3222 1 : INIOUT(printf("Success!\n"));
3223 :
3224 : return 0;
3225 : }
|