suricata
conf.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2010 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Endace Technology Limited - Jason Ish <jason.ish@endace.com>
22  *
23  * This file provides a basic configuration system for the IDPS
24  * engine.
25  *
26  * NOTE: Setting values should only be done from one thread during
27  * engine initialization. Multiple threads should be able access read
28  * configuration data. Allowing run time changes to the configuration
29  * will require some locks.
30  *
31  * \todo Consider having the in-memory configuration database a direct
32  * reflection of the configuration file and moving command line
33  * parameters to a primary lookup table?
34  *
35  * \todo Get rid of allow override and go with a simpler first set,
36  * stays approach?
37  */
38 
39 #include "suricata-common.h"
40 #include "conf.h"
41 #include "util-unittest.h"
42 #include "util-debug.h"
43 #include "util-path.h"
44 
45 /** Maximum size of a complete domain name. */
46 #define NODE_NAME_MAX 1024
47 
48 static ConfNode *root = NULL;
49 static ConfNode *root_backup = NULL;
50 
51 /**
52  * \brief Helper function to get a node, creating it if it does not
53  * exist.
54  *
55  * This function exits on memory failure as creating configuration
56  * nodes is usually part of application initialization.
57  *
58  * \param name The name of the configuration node to get.
59  * \param final Flag to set created nodes as final or not.
60  *
61  * \retval The existing configuration node if it exists, or a newly
62  * created node for the provided name. On error, NULL will be returned.
63  */
64 static ConfNode *ConfGetNodeOrCreate(const char *name, int final)
65 {
66  ConfNode *parent = root;
67  ConfNode *node = NULL;
68  char node_name[NODE_NAME_MAX];
69  char *key;
70  char *next;
71 
72  if (strlcpy(node_name, name, sizeof(node_name)) >= sizeof(node_name)) {
74  "Configuration name too long: %s", name);
75  return NULL;
76  }
77 
78  key = node_name;
79 
80  do {
81  if ((next = strchr(key, '.')) != NULL)
82  *next++ = '\0';
83  if ((node = ConfNodeLookupChild(parent, key)) == NULL) {
84  node = ConfNodeNew();
85  if (unlikely(node == NULL)) {
87  "Failed to allocate memory for configuration.");
88  goto end;
89  }
90  node->name = SCStrdup(key);
91  if (unlikely(node->name == NULL)) {
92  ConfNodeFree(node);
93  node = NULL;
95  "Failed to allocate memory for configuration.");
96  goto end;
97  }
98  node->parent = parent;
99  node->final = final;
100  TAILQ_INSERT_TAIL(&parent->head, node, next);
101  }
102  key = next;
103  parent = node;
104  } while (next != NULL);
105 
106 end:
107  return node;
108 }
109 
110 /**
111  * \brief Initialize the configuration system.
112  */
113 void ConfInit(void)
114 {
115  if (root != NULL) {
116  SCLogDebug("already initialized");
117  return;
118  }
119  root = ConfNodeNew();
120  if (root == NULL) {
122  "ERROR: Failed to allocate memory for root configuration node, "
123  "aborting.");
124  exit(EXIT_FAILURE);
125  }
126  SCLogDebug("configuration module initialized");
127 }
128 
129 /**
130  * \brief Allocate a new configuration node.
131  *
132  * \retval An allocated configuration node on success, NULL on failure.
133  */
135 {
136  ConfNode *new;
137 
138  new = SCCalloc(1, sizeof(*new));
139  if (unlikely(new == NULL)) {
140  return NULL;
141  }
142  TAILQ_INIT(&new->head);
143 
144  return new;
145 }
146 
147 /**
148  * \brief Free a ConfNode and all of its children.
149  *
150  * \param node The configuration node to SCFree.
151  */
153 {
154  ConfNode *tmp;
155 
156  while ((tmp = TAILQ_FIRST(&node->head))) {
157  TAILQ_REMOVE(&node->head, tmp, next);
158  ConfNodeFree(tmp);
159  }
160 
161  if (node->name != NULL)
162  SCFree(node->name);
163  if (node->val != NULL)
164  SCFree(node->val);
165  SCFree(node);
166 }
167 
168 /**
169  * \brief Get a ConfNode by name.
170  *
171  * \param name The full name of the configuration node to lookup.
172  *
173  * \retval A pointer to ConfNode is found or NULL if the configuration
174  * node does not exist.
175  */
176 ConfNode *ConfGetNode(const char *name)
177 {
178  ConfNode *node = root;
179  char node_name[NODE_NAME_MAX];
180  char *key;
181  char *next;
182 
183  if (strlcpy(node_name, name, sizeof(node_name)) >= sizeof(node_name)) {
185  "Configuration name too long: %s", name);
186  return NULL;
187  }
188 
189  key = node_name;
190  do {
191  if ((next = strchr(key, '.')) != NULL)
192  *next++ = '\0';
193  node = ConfNodeLookupChild(node, key);
194  key = next;
195  } while (next != NULL && node != NULL);
196 
197  return node;
198 }
199 
200 /**
201  * \brief Get the root configuration node.
202  */
204 {
205  return root;
206 }
207 
208 /**
209  * \brief Set a configuration value.
210  *
211  * Configuration values set with this function may be overridden by
212  * subsequent calls, or if the value appears multiple times in a
213  * configuration file.
214  *
215  * \param name The name of the configuration parameter to set.
216  * \param val The value of the configuration parameter.
217  *
218  * \retval 1 if the value was set otherwise 0.
219  */
220 int ConfSet(const char *name, const char *val)
221 {
222  ConfNode *node = ConfGetNodeOrCreate(name, 0);
223  if (node == NULL || node->final) {
224  return 0;
225  }
226  if (node->val != NULL)
227  SCFree(node->val);
228  node->val = SCStrdup(val);
229  if (unlikely(node->val == NULL)) {
230  return 0;
231  }
232  return 1;
233 }
234 
235 /**
236  * \brief Set a configuration parameter from a string.
237  *
238  * Where the input string is something like:
239  * stream.midstream=true
240  *
241  * \param input the input string to be parsed.
242  *
243  * \retval 1 if the value of set, otherwise 0.
244  */
245 int ConfSetFromString(const char *input, int final)
246 {
247  int retval = 0;
248  char *name = SCStrdup(input), *val = NULL;
249  if (unlikely(name == NULL)) {
250  goto done;
251  }
252  val = strchr(name, '=');
253  if (val == NULL) {
254  goto done;
255  }
256  *val++ = '\0';
257 
258  while (isspace((int)name[strlen(name) - 1])) {
259  name[strlen(name) - 1] = '\0';
260  }
261 
262  while (isspace((int)*val)) {
263  val++;
264  }
265 
266  if (final) {
267  if (!ConfSetFinal(name, val)) {
268  goto done;
269  }
270  }
271  else {
272  if (!ConfSet(name, val)) {
273  goto done;
274  }
275  }
276 
277  retval = 1;
278 done:
279  if (name != NULL) {
280  SCFree(name);
281  }
282  return retval;
283 }
284 
285 /**
286  * \brief Set a final configuration value.
287  *
288  * A final configuration value is a value that cannot be overridden by
289  * the configuration file. Its mainly useful for setting values that
290  * are supplied on the command line prior to the configuration file
291  * being loaded. However, a subsequent call to this function can
292  * override a previously set value.
293  *
294  * \param name The name of the configuration parameter to set.
295  * \param val The value of the configuration parameter.
296  *
297  * \retval 1 if the value was set otherwise 0.
298  */
299 int ConfSetFinal(const char *name, const char *val)
300 {
301  ConfNode *node = ConfGetNodeOrCreate(name, 1);
302  if (node == NULL) {
303  return 0;
304  }
305  if (node->val != NULL)
306  SCFree(node->val);
307  node->val = SCStrdup(val);
308  if (unlikely(node->val == NULL)) {
309  return 0;
310  }
311  node->final = 1;
312  return 1;
313 }
314 
315 /**
316  * \brief Retrieve the value of a configuration node.
317  *
318  * This function will return the value for a configuration node based
319  * on the full name of the node. It is possible that the value
320  * returned could be NULL, this could happen if the requested node
321  * does exist but is not a node that contains a value, but contains
322  * children ConfNodes instead.
323  *
324  * \param name Name of configuration parameter to get.
325  * \param vptr Pointer that will be set to the configuration value parameter.
326  * Note that this is just a reference to the actual value, not a copy.
327  *
328  * \retval 1 will be returned if the name is found, otherwise 0 will
329  * be returned.
330  */
331 int ConfGet(const char *name, const char **vptr)
332 {
333  ConfNode *node = ConfGetNode(name);
334  if (node == NULL) {
335  SCLogDebug("failed to lookup configuration parameter '%s'", name);
336  return 0;
337  }
338  else {
339  *vptr = node->val;
340  return 1;
341  }
342 }
343 
344 /**
345  * \brief Retrieve the value of a configuration node.
346  *
347  * This function will return the value for a configuration node based
348  * on the full name of the node. This function notifies if vptr returns NULL
349  * or if name is set to NULL.
350  *
351  * \param name Name of configuration parameter to get.
352  * \param vptr Pointer that will be set to the configuration value parameter.
353  * Note that this is just a reference to the actual value, not a copy.
354  *
355  * \retval 0 will be returned if name was not found,
356  * 1 will be returned if the name and it's value was found,
357  * -1 if the value returns NULL,
358  * -2 if name is NULL.
359  */
360 int ConfGetValue(const char *name, const char **vptr)
361 {
362  ConfNode *node;
363 
364  if (name == NULL) {
365  SCLogError(SC_ERR_INVALID_ARGUMENT,"parameter 'name' is NULL");
366  return -2;
367  }
368 
369  node = ConfGetNode(name);
370 
371  if (node == NULL) {
372  SCLogDebug("failed to lookup configuration parameter '%s'", name);
373  return 0;
374  }
375  else {
376 
377  if (node->val == NULL) {
378  SCLogDebug("value for configuration parameter '%s' is NULL", name);
379  return -1;
380  }
381 
382  *vptr = node->val;
383  return 1;
384  }
385 
386 }
387 
388 int ConfGetChildValue(const ConfNode *base, const char *name, const char **vptr)
389 {
390  ConfNode *node = ConfNodeLookupChild(base, name);
391 
392  if (node == NULL) {
393  SCLogDebug("failed to lookup configuration parameter '%s'", name);
394  return 0;
395  }
396  else {
397  *vptr = node->val;
398  return 1;
399  }
400 }
401 
403  const char *name)
404 {
405  ConfNode *node = ConfNodeLookupChild(base, name);
406  if (node != NULL)
407  return node;
408 
409  /* Get 'default' value */
410  if (dflt) {
411  return ConfNodeLookupChild(dflt, name);
412  }
413  return NULL;
414 }
415 
416 int ConfGetChildValueWithDefault(const ConfNode *base, const ConfNode *dflt,
417  const char *name, const char **vptr)
418 {
419  int ret = ConfGetChildValue(base, name, vptr);
420  /* Get 'default' value */
421  if (ret == 0 && dflt) {
422  return ConfGetChildValue(dflt, name, vptr);
423  }
424  return ret;
425 }
426 
427 /**
428  * \brief Retrieve a configuration value as an integer.
429  *
430  * \param name Name of configuration parameter to get.
431  * \param val Pointer to an intmax_t that will be set the
432  * configuration value.
433  *
434  * \retval 1 will be returned if the name is found and was properly
435  * converted to an interger, otherwise 0 will be returned.
436  */
437 int ConfGetInt(const char *name, intmax_t *val)
438 {
439  const char *strval = NULL;
440  intmax_t tmpint;
441  char *endptr;
442 
443  if (ConfGet(name, &strval) == 0)
444  return 0;
445 
446  if (strval == NULL) {
447  SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, "malformed integer value "
448  "for %s: NULL", name);
449  return 0;
450  }
451 
452  errno = 0;
453  tmpint = strtoimax(strval, &endptr, 0);
454  if (strval[0] == '\0' || *endptr != '\0') {
455  SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, "malformed integer value "
456  "for %s: '%s'", name, strval);
457  return 0;
458  }
459  if (errno == ERANGE && (tmpint == INTMAX_MAX || tmpint == INTMAX_MIN)) {
460  SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, "integer value for %s out "
461  "of range: '%s'", name, strval);
462  return 0;
463  }
464 
465  *val = tmpint;
466  return 1;
467 }
468 
469 int ConfGetChildValueInt(const ConfNode *base, const char *name, intmax_t *val)
470 {
471  const char *strval = NULL;
472  intmax_t tmpint;
473  char *endptr;
474 
475  if (ConfGetChildValue(base, name, &strval) == 0)
476  return 0;
477  errno = 0;
478  tmpint = strtoimax(strval, &endptr, 0);
479  if (strval[0] == '\0' || *endptr != '\0') {
480  SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, "malformed integer value "
481  "for %s with base %s: '%s'", name, base->name, strval);
482  return 0;
483  }
484  if (errno == ERANGE && (tmpint == INTMAX_MAX || tmpint == INTMAX_MIN)) {
485  SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, "integer value for %s with "
486  " base %s out of range: '%s'", name, base->name, strval);
487  return 0;
488  }
489 
490  *val = tmpint;
491  return 1;
492 
493 }
494 
495 int ConfGetChildValueIntWithDefault(const ConfNode *base, const ConfNode *dflt,
496  const char *name, intmax_t *val)
497 {
498  int ret = ConfGetChildValueInt(base, name, val);
499  /* Get 'default' value */
500  if (ret == 0 && dflt) {
501  return ConfGetChildValueInt(dflt, name, val);
502  }
503  return ret;
504 }
505 
506 
507 /**
508  * \brief Retrieve a configuration value as an boolen.
509  *
510  * \param name Name of configuration parameter to get.
511  * \param val Pointer to an int that will be set to 1 for true, or 0
512  * for false.
513  *
514  * \retval 1 will be returned if the name is found and was properly
515  * converted to a boolean, otherwise 0 will be returned.
516  */
517 int ConfGetBool(const char *name, int *val)
518 {
519  const char *strval = NULL;
520 
521  *val = 0;
522  if (ConfGetValue(name, &strval) != 1)
523  return 0;
524 
525  *val = ConfValIsTrue(strval);
526 
527  return 1;
528 }
529 
530 int ConfGetChildValueBool(const ConfNode *base, const char *name, int *val)
531 {
532  const char *strval = NULL;
533 
534  *val = 0;
535  if (ConfGetChildValue(base, name, &strval) == 0)
536  return 0;
537 
538  *val = ConfValIsTrue(strval);
539 
540  return 1;
541 }
542 
544  const char *name, int *val)
545 {
546  int ret = ConfGetChildValueBool(base, name, val);
547  /* Get 'default' value */
548  if (ret == 0 && dflt) {
549  return ConfGetChildValueBool(dflt, name, val);
550  }
551  return ret;
552 }
553 
554 
555 /**
556  * \brief Check if a value is true.
557  *
558  * The value is considered true if it is a string with the value of 1,
559  * yes, true or on. The test is not case sensitive, any other value
560  * is false.
561  *
562  * \param val The string to test for a true value.
563  *
564  * \retval 1 If the value is true, 0 if not.
565  */
566 int ConfValIsTrue(const char *val)
567 {
568  const char *trues[] = {"1", "yes", "true", "on"};
569  size_t u;
570 
571  for (u = 0; u < sizeof(trues) / sizeof(trues[0]); u++) {
572  if (strcasecmp(val, trues[u]) == 0) {
573  return 1;
574  }
575  }
576 
577  return 0;
578 }
579 
580 /**
581  * \brief Check if a value is false.
582  *
583  * The value is considered false if it is a string with the value of 0,
584  * no, false or off. The test is not case sensitive, any other value
585  * is not false.
586  *
587  * \param val The string to test for a false value.
588  *
589  * \retval 1 If the value is false, 0 if not.
590  */
591 int ConfValIsFalse(const char *val)
592 {
593  const char *falses[] = {"0", "no", "false", "off"};
594  size_t u;
595 
596  for (u = 0; u < sizeof(falses) / sizeof(falses[0]); u++) {
597  if (strcasecmp(val, falses[u]) == 0) {
598  return 1;
599  }
600  }
601 
602  return 0;
603 }
604 
605 /**
606  * \brief Retrieve a configuration value as a double
607  *
608  * \param name Name of configuration parameter to get.
609  * \param val Pointer to an double that will be set the
610  * configuration value.
611  *
612  * \retval 1 will be returned if the name is found and was properly
613  * converted to a double, otherwise 0 will be returned.
614  */
615 int ConfGetDouble(const char *name, double *val)
616 {
617  const char *strval = NULL;
618  double tmpdo;
619  char *endptr;
620 
621  if (ConfGet(name, &strval) == 0)
622  return 0;
623 
624  errno = 0;
625  tmpdo = strtod(strval, &endptr);
626  if (strval[0] == '\0' || *endptr != '\0')
627  return 0;
628  if (errno == ERANGE)
629  return 0;
630 
631  *val = tmpdo;
632  return 1;
633 }
634 
635 /**
636  * \brief Retrieve a configuration value as a float
637  *
638  * \param name Name of configuration parameter to get.
639  * \param val Pointer to an float that will be set the
640  * configuration value.
641  *
642  * \retval 1 will be returned if the name is found and was properly
643  * converted to a double, otherwise 0 will be returned.
644  */
645 int ConfGetFloat(const char *name, float *val)
646 {
647  const char *strval = NULL;
648  double tmpfl;
649  char *endptr;
650 
651  if (ConfGet(name, &strval) == 0)
652  return 0;
653 
654  errno = 0;
655  tmpfl = strtof(strval, &endptr);
656  if (strval[0] == '\0' || *endptr != '\0')
657  return 0;
658  if (errno == ERANGE)
659  return 0;
660 
661  *val = tmpfl;
662  return 1;
663 }
664 
665 /**
666  * \brief Remove (and SCFree) the provided configuration node.
667  */
669 {
670  if (node->parent != NULL)
671  TAILQ_REMOVE(&node->parent->head, node, next);
672  ConfNodeFree(node);
673 }
674 
675 /**
676  * \brief Remove a configuration parameter from the configuration db.
677  *
678  * \param name The name of the configuration parameter to remove.
679  *
680  * \retval Returns 1 if the parameter was removed, otherwise 0 is returned
681  * most likely indicating the parameter was not set.
682  */
683 int ConfRemove(const char *name)
684 {
685  ConfNode *node;
686 
687  node = ConfGetNode(name);
688  if (node == NULL)
689  return 0;
690  else {
691  ConfNodeRemove(node);
692  return 1;
693  }
694 }
695 
696 /**
697  * \brief Creates a backup of the conf_hash hash_table used by the conf API.
698  */
700 {
701  root_backup = root;
702  root = NULL;
703 
704  return;
705 }
706 
707 /**
708  * \brief Restores the backup of the hash_table present in backup_conf_hash
709  * back to conf_hash.
710  */
712 {
713  root = root_backup;
714  root_backup = NULL;
715 
716  return;
717 }
718 
719 /**
720  * \brief De-initializes the configuration system.
721  */
722 void ConfDeInit(void)
723 {
724  if (root != NULL) {
725  ConfNodeFree(root);
726  root = NULL;
727  }
728 
729  SCLogDebug("configuration module de-initialized");
730 }
731 
732 static char *ConfPrintNameArray(char **name_arr, int level)
733 {
734  static char name[128*128];
735  int i;
736 
737  name[0] = '\0';
738  for (i = 0; i <= level; i++) {
739  strlcat(name, name_arr[i], sizeof(name));
740  if (i < level)
741  strlcat(name, ".", sizeof(name));
742  }
743 
744  return name;
745 }
746 
747 /**
748  * \brief Dump a configuration node and all its children.
749  */
750 void ConfNodeDump(const ConfNode *node, const char *prefix)
751 {
752  ConfNode *child;
753 
754  static char *name[128];
755  static int level = -1;
756 
757  level++;
758  TAILQ_FOREACH(child, &node->head, next) {
759  name[level] = SCStrdup(child->name);
760  if (unlikely(name[level] == NULL)) {
761  continue;
762  }
763  if (prefix == NULL) {
764  printf("%s = %s\n", ConfPrintNameArray(name, level),
765  child->val);
766  }
767  else {
768  printf("%s.%s = %s\n", prefix,
769  ConfPrintNameArray(name, level), child->val);
770  }
771  ConfNodeDump(child, prefix);
772  SCFree(name[level]);
773  }
774  level--;
775 }
776 
777 /**
778  * \brief Dump configuration to stdout.
779  */
780 void ConfDump(void)
781 {
782  ConfNodeDump(root, NULL);
783 }
784 
785 /**
786  * \brief Check if a node has any children.
787  *
788  * Checks if the provided node has any children. Any node that is a
789  * YAML map or array will have children.
790  *
791  * \param node The node to check.
792  *
793  * \retval true if node has children
794  * \retval false if node does not have children
795  */
796 bool ConfNodeHasChildren(const ConfNode *node)
797 {
798  if (TAILQ_EMPTY(&node->head)) {
799  return false;
800  }
801  return true;
802 }
803 
804 /**
805  * \brief Lookup a child configuration node by name.
806  *
807  * Given a ConfNode this function will lookup an immediate child
808  * ConfNode by name and return the child ConfNode.
809  *
810  * \param node The parent configuration node.
811  * \param name The name of the child node to lookup.
812  *
813  * \retval A pointer the child ConfNode if found otherwise NULL.
814  */
815 ConfNode *ConfNodeLookupChild(const ConfNode *node, const char *name)
816 {
817  ConfNode *child;
818 
819  if (node == NULL || name == NULL) {
820  return NULL;
821  }
822 
823  TAILQ_FOREACH(child, &node->head, next) {
824  if (child->name != NULL && strcmp(child->name, name) == 0)
825  return child;
826  }
827 
828  return NULL;
829 }
830 
831 /**
832  * \brief Lookup the value of a child configuration node by name.
833  *
834  * Given a parent ConfNode this function will return the value of a
835  * child configuration node by name returning a reference to that
836  * value.
837  *
838  * \param node The parent configuration node.
839  * \param name The name of the child node to lookup.
840  *
841  * \retval A pointer the child ConfNodes value if found otherwise NULL.
842  */
843 const char *ConfNodeLookupChildValue(const ConfNode *node, const char *name)
844 {
845  ConfNode *child;
846 
847  child = ConfNodeLookupChild(node, name);
848  if (child != NULL)
849  return child->val;
850 
851  return NULL;
852 }
853 
854 /**
855  * \brief Lookup for a key value under a specific node
856  *
857  * \return the ConfNode matching or NULL
858  */
859 
860 ConfNode *ConfNodeLookupKeyValue(const ConfNode *base, const char *key,
861  const char *value)
862 {
863  ConfNode *child;
864 
865  TAILQ_FOREACH(child, &base->head, next) {
866  if (!strncmp(child->val, key, strlen(child->val))) {
867  ConfNode *subchild;
868  TAILQ_FOREACH(subchild, &child->head, next) {
869  if ((!strcmp(subchild->name, key)) && (!strcmp(subchild->val, value))) {
870  return child;
871  }
872  }
873  }
874  }
875 
876  return NULL;
877 }
878 
879 /**
880  * \brief Test if a configuration node has a true value.
881  *
882  * \param node The parent configuration node.
883  * \param name The name of the child node to test.
884  *
885  * \retval 1 if the child node has a true value, otherwise 0 is
886  * returned, even if the child node does not exist.
887  */
888 int ConfNodeChildValueIsTrue(const ConfNode *node, const char *key)
889 {
890  const char *val;
891 
892  val = ConfNodeLookupChildValue(node, key);
893 
894  return val != NULL ? ConfValIsTrue(val) : 0;
895 }
896 
897 /**
898  * \brief Create the path for an include entry
899  * \param file The name of the file
900  * \retval str Pointer to the string path + sig_file
901  */
902 char *ConfLoadCompleteIncludePath(const char *file)
903 {
904  const char *defaultpath = NULL;
905  char *path = NULL;
906 
907  /* Path not specified */
908  if (PathIsRelative(file)) {
909  if (ConfGet("include-path", &defaultpath) == 1) {
910  SCLogDebug("Default path: %s", defaultpath);
911  size_t path_len = sizeof(char) * (strlen(defaultpath) +
912  strlen(file) + 2);
913  path = SCMalloc(path_len);
914  if (unlikely(path == NULL))
915  return NULL;
916  strlcpy(path, defaultpath, path_len);
917  if (path[strlen(path) - 1] != '/')
918  strlcat(path, "/", path_len);
919  strlcat(path, file, path_len);
920  } else {
921  path = SCStrdup(file);
922  if (unlikely(path == NULL))
923  return NULL;
924  }
925  } else {
926  path = SCStrdup(file);
927  if (unlikely(path == NULL))
928  return NULL;
929  }
930  return path;
931 }
932 
933 /**
934  * \brief Prune a configuration node.
935  *
936  * Pruning a configuration is similar to freeing, but only fields that
937  * may be overridden are, leaving final type parameters. Additional
938  * the value of the provided node is also free'd, but the node itself
939  * is left.
940  *
941  * \param node The configuration node to prune.
942  */
944 {
945  ConfNode *item, *it;
946 
947  for (item = TAILQ_FIRST(&node->head); item != NULL; item = it) {
948  it = TAILQ_NEXT(item, next);
949  if (!item->final) {
950  ConfNodePrune(item);
951  if (TAILQ_EMPTY(&item->head)) {
952  TAILQ_REMOVE(&node->head, item, next);
953  if (item->name != NULL)
954  SCFree(item->name);
955  if (item->val != NULL)
956  SCFree(item->val);
957  SCFree(item);
958  }
959  }
960  }
961 
962  if (node->val != NULL) {
963  SCFree(node->val);
964  node->val = NULL;
965  }
966 }
967 
968 /**
969  * \brief Check if a node is a sequence or node.
970  *
971  * \param node the node to check.
972  *
973  * \return 1 if node is a seuence, otherwise 0.
974  */
975 int ConfNodeIsSequence(const ConfNode *node)
976 {
977  return node->is_seq == 0 ? 0 : 1;
978 }
979 
980 #ifdef UNITTESTS
981 
982 /**
983  * Lookup a non-existant value.
984  */
985 static int ConfTestGetNonExistant(void)
986 {
987  char name[] = "non-existant-value";
988  const char *value;
989 
990  FAIL_IF(ConfGet(name, &value));
991  PASS;
992 }
993 
994 /**
995  * Set then lookup a value.
996  */
997 static int ConfTestSetAndGet(void)
998 {
999  char name[] = "some-name";
1000  char value[] = "some-value";
1001  const char *value0 = NULL;
1002 
1003  FAIL_IF(ConfSet(name, value) != 1);
1004  FAIL_IF(ConfGet(name, &value0) != 1);
1005  FAIL_IF(value0 == NULL);
1006  FAIL_IF(strcmp(value, value0) != 0);
1007 
1008  /* Cleanup. */
1009  ConfRemove(name);
1010 
1011  PASS;
1012 }
1013 
1014 /**
1015  * Test that overriding a value is allowed provided allow_override is
1016  * true and that the config parameter gets the new value.
1017  */
1018 static int ConfTestOverrideValue1(void)
1019 {
1020  char name[] = "some-name";
1021  char value0[] = "some-value";
1022  char value1[] = "new-value";
1023  const char *val = NULL;
1024 
1025  FAIL_IF(ConfSet(name, value0) != 1);
1026  FAIL_IF(ConfSet(name, value1) != 1);
1027  FAIL_IF(ConfGet(name, &val) != 1);
1028  FAIL_IF(val == NULL);
1029  FAIL_IF(strcmp(val, value1) != 0);
1030 
1031  /* Cleanup. */
1032  ConfRemove(name);
1033 
1034  PASS;
1035 }
1036 
1037 /**
1038  * Test that a final value will not be overrided by a ConfSet.
1039  */
1040 static int ConfTestOverrideValue2(void)
1041 {
1042  char name[] = "some-name";
1043  char value0[] = "some-value";
1044  char value1[] = "new-value";
1045  const char *val = NULL;
1046 
1047  FAIL_IF(ConfSetFinal(name, value0) != 1);
1048  FAIL_IF(ConfSet(name, value1) != 0);
1049  FAIL_IF(ConfGet(name, &val) != 1);
1050  FAIL_IF(val == NULL);
1051  FAIL_IF(strcmp(val, value0) != 0);
1052 
1053  /* Cleanup. */
1054  ConfRemove(name);
1055 
1056  PASS;
1057 }
1058 
1059 /**
1060  * Test retrieving an integer value from the configuration db.
1061  */
1062 static int ConfTestGetInt(void)
1063 {
1064  char name[] = "some-int.x";
1065  intmax_t val;
1066 
1067  FAIL_IF(ConfSet(name, "0") != 1);
1068  FAIL_IF(ConfGetInt(name, &val) != 1);
1069  FAIL_IF(val != 0);
1070 
1071  FAIL_IF(ConfSet(name, "-1") != 1);
1072  FAIL_IF(ConfGetInt(name, &val) != 1);
1073  FAIL_IF(val != -1);
1074 
1075  FAIL_IF(ConfSet(name, "0xffff") != 1);
1076  FAIL_IF(ConfGetInt(name, &val) != 1);
1077  FAIL_IF(val != 0xffff);
1078 
1079  FAIL_IF(ConfSet(name, "not-an-int") != 1);
1080  FAIL_IF(ConfGetInt(name, &val) != 0);
1081 
1082  PASS;
1083 }
1084 
1085 /**
1086  * Test retrieving a boolean value from the configuration db.
1087  */
1088 static int ConfTestGetBool(void)
1089 {
1090  char name[] = "some-bool";
1091  const char *trues[] = {
1092  "1",
1093  "on", "ON",
1094  "yes", "YeS",
1095  "true", "TRUE",
1096  };
1097  const char *falses[] = {
1098  "0",
1099  "something",
1100  "off", "OFF",
1101  "false", "FalSE",
1102  "no", "NO",
1103  };
1104  int val;
1105  size_t u;
1106 
1107  for (u = 0; u < sizeof(trues) / sizeof(trues[0]); u++) {
1108  FAIL_IF(ConfSet(name, trues[u]) != 1);
1109  FAIL_IF(ConfGetBool(name, &val) != 1);
1110  FAIL_IF(val != 1);
1111  }
1112 
1113  for (u = 0; u < sizeof(falses) / sizeof(falses[0]); u++) {
1114  FAIL_IF(ConfSet(name, falses[u]) != 1);
1115  FAIL_IF(ConfGetBool(name, &val) != 1);
1116  FAIL_IF(val != 0);
1117  }
1118 
1119  PASS;
1120 }
1121 
1122 static int ConfNodeLookupChildTest(void)
1123 {
1124  const char *test_vals[] = { "one", "two", "three" };
1125  size_t u;
1126 
1127  ConfNode *parent = ConfNodeNew();
1128  ConfNode *child;
1129 
1130  for (u = 0; u < sizeof(test_vals)/sizeof(test_vals[0]); u++) {
1131  child = ConfNodeNew();
1132  child->name = SCStrdup(test_vals[u]);
1133  child->val = SCStrdup(test_vals[u]);
1134  TAILQ_INSERT_TAIL(&parent->head, child, next);
1135  }
1136 
1137  child = ConfNodeLookupChild(parent, "one");
1138  FAIL_IF(child == NULL);
1139  FAIL_IF(strcmp(child->name, "one") != 0);
1140  FAIL_IF(strcmp(child->val, "one") != 0);
1141 
1142  child = ConfNodeLookupChild(parent, "two");
1143  FAIL_IF(child == NULL);
1144  FAIL_IF(strcmp(child->name, "two") != 0);
1145  FAIL_IF(strcmp(child->val, "two") != 0);
1146 
1147  child = ConfNodeLookupChild(parent, "three");
1148  FAIL_IF(child == NULL);
1149  FAIL_IF(strcmp(child->name, "three") != 0);
1150  FAIL_IF(strcmp(child->val, "three") != 0);
1151 
1152  child = ConfNodeLookupChild(parent, "four");
1153  FAIL_IF(child != NULL);
1154 
1155  FAIL_IF(ConfNodeLookupChild(NULL, NULL) != NULL);
1156 
1157  if (parent != NULL) {
1158  ConfNodeFree(parent);
1159  }
1160 
1161  PASS;
1162 }
1163 
1164 static int ConfNodeLookupChildValueTest(void)
1165 {
1166  const char *test_vals[] = { "one", "two", "three" };
1167  size_t u;
1168 
1169  ConfNode *parent = ConfNodeNew();
1170  ConfNode *child;
1171  const char *value;
1172 
1173  for (u = 0; u < sizeof(test_vals)/sizeof(test_vals[0]); u++) {
1174  child = ConfNodeNew();
1175  child->name = SCStrdup(test_vals[u]);
1176  child->val = SCStrdup(test_vals[u]);
1177  TAILQ_INSERT_TAIL(&parent->head, child, next);
1178  }
1179 
1180  value = (char *)ConfNodeLookupChildValue(parent, "one");
1181  FAIL_IF(value == NULL);
1182  FAIL_IF(strcmp(value, "one") != 0);
1183 
1184  value = (char *)ConfNodeLookupChildValue(parent, "two");
1185  FAIL_IF(value == NULL);
1186  FAIL_IF(strcmp(value, "two") != 0);
1187 
1188  value = (char *)ConfNodeLookupChildValue(parent, "three");
1189  FAIL_IF(value == NULL);
1190  FAIL_IF(strcmp(value, "three") != 0);
1191 
1192  value = (char *)ConfNodeLookupChildValue(parent, "four");
1193  FAIL_IF(value != NULL);
1194 
1195  ConfNodeFree(parent);
1196 
1197  PASS;
1198 }
1199 
1200 static int ConfGetChildValueWithDefaultTest(void)
1201 {
1202  const char *val = "";
1204  ConfInit();
1205  ConfSet("af-packet.0.interface", "eth0");
1206  ConfSet("af-packet.1.interface", "default");
1207  ConfSet("af-packet.1.cluster-type", "cluster_cpu");
1208 
1209  ConfNode *myroot = ConfGetNode("af-packet.0");
1210  ConfNode *dflt = ConfGetNode("af-packet.1");
1211  ConfGetChildValueWithDefault(myroot, dflt, "cluster-type", &val);
1212  FAIL_IF(strcmp(val, "cluster_cpu"));
1213 
1214  ConfSet("af-packet.0.cluster-type", "cluster_flow");
1215  ConfGetChildValueWithDefault(myroot, dflt, "cluster-type", &val);
1216 
1217  FAIL_IF(strcmp(val, "cluster_flow"));
1218 
1219  ConfDeInit();
1221  PASS;
1222 }
1223 
1224 static int ConfGetChildValueIntWithDefaultTest(void)
1225 {
1226  intmax_t val = 0;
1228  ConfInit();
1229  ConfSet("af-packet.0.interface", "eth0");
1230  ConfSet("af-packet.1.interface", "default");
1231  ConfSet("af-packet.1.threads", "2");
1232 
1233  ConfNode *myroot = ConfGetNode("af-packet.0");
1234  ConfNode *dflt = ConfGetNode("af-packet.1");
1235  ConfGetChildValueIntWithDefault(myroot, dflt, "threads", &val);
1236  FAIL_IF(val != 2);
1237 
1238  ConfSet("af-packet.0.threads", "1");
1239  ConfGetChildValueIntWithDefault(myroot, dflt, "threads", &val);
1240  FAIL_IF(val != 1);
1241 
1242  ConfDeInit();
1244 
1245  PASS;
1246 }
1247 
1248 static int ConfGetChildValueBoolWithDefaultTest(void)
1249 {
1250  int val;
1252  ConfInit();
1253  ConfSet("af-packet.0.interface", "eth0");
1254  ConfSet("af-packet.1.interface", "default");
1255  ConfSet("af-packet.1.use-mmap", "yes");
1256 
1257  ConfNode *myroot = ConfGetNode("af-packet.0");
1258  ConfNode *dflt = ConfGetNode("af-packet.1");
1259  ConfGetChildValueBoolWithDefault(myroot, dflt, "use-mmap", &val);
1260  FAIL_IF(val == 0);
1261 
1262  ConfSet("af-packet.0.use-mmap", "no");
1263  ConfGetChildValueBoolWithDefault(myroot, dflt, "use-mmap", &val);
1264  FAIL_IF(val);
1265 
1266  ConfDeInit();
1268 
1269  PASS;
1270 }
1271 
1272 /**
1273  * Test the removal of a configuration node.
1274  */
1275 static int ConfNodeRemoveTest(void)
1276 {
1278  ConfInit();
1279 
1280  FAIL_IF(ConfSet("some.nested.parameter", "blah") != 1);
1281 
1282  ConfNode *node = ConfGetNode("some.nested.parameter");
1283  FAIL_IF(node == NULL);
1284  ConfNodeRemove(node);
1285 
1286  node = ConfGetNode("some.nested.parameter");
1287  FAIL_IF(node != NULL);
1288 
1289  ConfDeInit();
1291 
1292  PASS;
1293 }
1294 
1295 static int ConfSetTest(void)
1296 {
1298  ConfInit();
1299 
1300  /* Set some value with 2 levels. */
1301  FAIL_IF(ConfSet("one.two", "three") != 1);
1302  ConfNode *n = ConfGetNode("one.two");
1303  FAIL_IF(n == NULL);
1304 
1305  /* Set another 2 level parameter with the same first level, this
1306  * used to trigger a bug that caused the second level of the name
1307  * to become a first level node. */
1308  FAIL_IF(ConfSet("one.three", "four") != 1);
1309 
1310  n = ConfGetNode("one.three");
1311  FAIL_IF(n == NULL);
1312 
1313  /* A top level node of "three" should not exist. */
1314  n = ConfGetNode("three");
1315  FAIL_IF(n != NULL);
1316 
1317  ConfDeInit();
1319 
1320  PASS;
1321 }
1322 
1323 static int ConfGetNodeOrCreateTest(void)
1324 {
1325  ConfNode *node;
1326 
1328  ConfInit();
1329 
1330  /* Get a node that should not exist, give it a value, re-get it
1331  * and make sure the second time it returns the existing node. */
1332  node = ConfGetNodeOrCreate("node0", 0);
1333  FAIL_IF(node == NULL);
1334  FAIL_IF(node->parent == NULL || node->parent != root);
1335  FAIL_IF(node->val != NULL);
1336  node->val = SCStrdup("node0");
1337  node = ConfGetNodeOrCreate("node0", 0);
1338  FAIL_IF(node == NULL);
1339  FAIL_IF(node->val == NULL);
1340  FAIL_IF(strcmp(node->val, "node0") != 0);
1341 
1342  /* Do the same, but for something deeply nested. */
1343  node = ConfGetNodeOrCreate("parent.child.grandchild", 0);
1344  FAIL_IF(node == NULL);
1345  FAIL_IF(node->parent == NULL || node->parent == root);
1346  FAIL_IF(node->val != NULL);
1347  node->val = SCStrdup("parent.child.grandchild");
1348  node = ConfGetNodeOrCreate("parent.child.grandchild", 0);
1349  FAIL_IF(node == NULL);
1350  FAIL_IF(node->val == NULL);
1351  FAIL_IF(strcmp(node->val, "parent.child.grandchild") != 0);
1352 
1353  /* Test that 2 child nodes have the same root. */
1354  ConfNode *child1 = ConfGetNodeOrCreate("parent.kids.child1", 0);
1355  ConfNode *child2 = ConfGetNodeOrCreate("parent.kids.child2", 0);
1356  FAIL_IF(child1 == NULL || child2 == NULL);
1357  FAIL_IF(child1->parent != child2->parent);
1358  FAIL_IF(strcmp(child1->parent->name, "kids") != 0);
1359 
1360  ConfDeInit();
1362 
1363  PASS;
1364 }
1365 
1366 static int ConfNodePruneTest(void)
1367 {
1368  ConfNode *node;
1369 
1371  ConfInit();
1372 
1373  /* Test that final nodes exist after a prune. */
1374  FAIL_IF(ConfSet("node.notfinal", "notfinal") != 1);
1375  FAIL_IF(ConfSetFinal("node.final", "final") != 1);
1376  FAIL_IF(ConfGetNode("node.notfinal") == NULL);
1377  FAIL_IF(ConfGetNode("node.final") == NULL);
1378  FAIL_IF((node = ConfGetNode("node")) == NULL);
1379  ConfNodePrune(node);
1380  FAIL_IF(ConfGetNode("node.notfinal") != NULL);
1381  FAIL_IF(ConfGetNode("node.final") == NULL);
1382 
1383  /* Test that everything under a final node exists after a prune. */
1384  FAIL_IF(ConfSet("node.final.one", "one") != 1);
1385  FAIL_IF(ConfSet("node.final.two", "two") != 1);
1386  ConfNodePrune(node);
1387  FAIL_IF(ConfNodeLookupChild(node, "final") == NULL);
1388  FAIL_IF(ConfGetNode("node.final.one") == NULL);
1389  FAIL_IF(ConfGetNode("node.final.two") == NULL);
1390 
1391  ConfDeInit();
1393 
1394  PASS;
1395 }
1396 
1397 static int ConfNodeIsSequenceTest(void)
1398 {
1399  ConfNode *node = ConfNodeNew();
1400  FAIL_IF(node == NULL);
1401  FAIL_IF(ConfNodeIsSequence(node));
1402  node->is_seq = 1;
1403  FAIL_IF(!ConfNodeIsSequence(node));
1404 
1405  if (node != NULL) {
1406  ConfNodeFree(node);
1407  }
1408  PASS;
1409 }
1410 
1411 static int ConfSetFromStringTest(void)
1412 {
1413  ConfNode *n;
1414 
1416  ConfInit();
1417 
1418  FAIL_IF_NOT(ConfSetFromString("stream.midstream=true", 0));
1419  n = ConfGetNode("stream.midstream");
1420  FAIL_IF_NULL(n);
1421  FAIL_IF_NULL(n->val);
1422  FAIL_IF(strcmp("true", n->val));
1423 
1424  FAIL_IF_NOT(ConfSetFromString("stream.midstream =false", 0));
1425  n = ConfGetNode("stream.midstream");
1426  FAIL_IF_NULL(n);
1427  FAIL_IF(n->val == NULL || strcmp("false", n->val));
1428 
1429  FAIL_IF_NOT(ConfSetFromString("stream.midstream= true", 0));
1430  n = ConfGetNode("stream.midstream");
1431  FAIL_IF_NULL(n);
1432  FAIL_IF(n->val == NULL || strcmp("true", n->val));
1433 
1434  FAIL_IF_NOT(ConfSetFromString("stream.midstream = false", 0));
1435  n = ConfGetNode("stream.midstream");
1436  FAIL_IF_NULL(n);
1437  FAIL_IF(n->val == NULL || strcmp("false", n->val));
1438 
1439  ConfDeInit();
1441  PASS;
1442 }
1443 
1444 static int ConfNodeHasChildrenTest(void)
1445 {
1447  ConfInit();
1448 
1449  /* Set a plain key with value. */
1450  ConfSet("no-children", "value");
1451  ConfNode *n = ConfGetNode("no-children");
1452  FAIL_IF_NULL(n);
1454 
1455  /* Set a key with a sub key to a value. This makes the first key a
1456  * map. */
1457  ConfSet("parent.child", "value");
1458  n = ConfGetNode("parent");
1459  FAIL_IF_NULL(n);
1461 
1462  ConfDeInit();
1464  PASS;
1465 }
1466 
1468 {
1469  UtRegisterTest("ConfTestGetNonExistant", ConfTestGetNonExistant);
1470  UtRegisterTest("ConfSetTest", ConfSetTest);
1471  UtRegisterTest("ConfTestSetAndGet", ConfTestSetAndGet);
1472  UtRegisterTest("ConfTestOverrideValue1", ConfTestOverrideValue1);
1473  UtRegisterTest("ConfTestOverrideValue2", ConfTestOverrideValue2);
1474  UtRegisterTest("ConfTestGetInt", ConfTestGetInt);
1475  UtRegisterTest("ConfTestGetBool", ConfTestGetBool);
1476  UtRegisterTest("ConfNodeLookupChildTest", ConfNodeLookupChildTest);
1477  UtRegisterTest("ConfNodeLookupChildValueTest",
1478  ConfNodeLookupChildValueTest);
1479  UtRegisterTest("ConfNodeRemoveTest", ConfNodeRemoveTest);
1480  UtRegisterTest("ConfGetChildValueWithDefaultTest",
1481  ConfGetChildValueWithDefaultTest);
1482  UtRegisterTest("ConfGetChildValueIntWithDefaultTest",
1483  ConfGetChildValueIntWithDefaultTest);
1484  UtRegisterTest("ConfGetChildValueBoolWithDefaultTest",
1485  ConfGetChildValueBoolWithDefaultTest);
1486  UtRegisterTest("ConfGetNodeOrCreateTest", ConfGetNodeOrCreateTest);
1487  UtRegisterTest("ConfNodePruneTest", ConfNodePruneTest);
1488  UtRegisterTest("ConfNodeIsSequenceTest", ConfNodeIsSequenceTest);
1489  UtRegisterTest("ConfSetFromStringTest", ConfSetFromStringTest);
1490  UtRegisterTest("ConfNodeHasChildrenTest", ConfNodeHasChildrenTest);
1491 }
1492 
1493 #endif /* UNITTESTS */
int PathIsRelative(const char *path)
Check if a path is relative.
Definition: util-path.c:64
int ConfSet(const char *name, const char *val)
Set a configuration value.
Definition: conf.c:220
#define SCLogDebug(...)
Definition: util-debug.h:335
int ConfGetDouble(const char *name, double *val)
Retrieve a configuration value as a double.
Definition: conf.c:615
#define TAILQ_FIRST(head)
Definition: queue.h:339
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:350
ConfNode * ConfNodeLookupKeyValue(const ConfNode *base, const char *key, const char *value)
Lookup for a key value under a specific node.
Definition: conf.c:860
struct HtpBodyChunk_ * next
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
void ConfNodeFree(ConfNode *node)
Free a ConfNode and all of its children.
Definition: conf.c:152
void ConfDeInit(void)
De-initializes the configuration system.
Definition: conf.c:722
#define PASS
Pass the test.
#define unlikely(expr)
Definition: util-optimize.h:35
int ConfGetBool(const char *name, int *val)
Retrieve a configuration value as an boolen.
Definition: conf.c:517
char * ConfLoadCompleteIncludePath(const char *file)
Create the path for an include entry.
Definition: conf.c:902
size_t strlcat(char *, const char *src, size_t siz)
Definition: util-strlcatu.c:45
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:71
void ConfNodeRemove(ConfNode *node)
Remove (and SCFree) the provided configuration node.
Definition: conf.c:668
char * val
Definition: conf.h:34
ConfNode * ConfNodeLookupChild(const ConfNode *node, const char *name)
Lookup a child configuration node by name.
Definition: conf.c:815
int ConfRemove(const char *name)
Remove a configuration parameter from the configuration db.
Definition: conf.c:683
int ConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
Definition: conf.c:331
int ConfNodeChildValueIsTrue(const ConfNode *node, const char *key)
Test if a configuration node has a true value.
Definition: conf.c:888
ConfNode * ConfGetRootNode(void)
Get the root configuration node.
Definition: conf.c:203
int ConfGetChildValue(const ConfNode *base, const char *name, const char **vptr)
Definition: conf.c:388
void ConfNodePrune(ConfNode *node)
Prune a configuration node.
Definition: conf.c:943
void ConfCreateContextBackup(void)
Creates a backup of the conf_hash hash_table used by the conf API.
Definition: conf.c:699
#define SCCalloc(nm, a)
Definition: util-mem.h:253
const char * ConfNodeLookupChildValue(const ConfNode *node, const char *name)
Lookup the value of a child configuration node by name.
Definition: conf.c:843
int ConfNodeIsSequence(const ConfNode *node)
Check if a node is a sequence or node.
Definition: conf.c:975
void ConfDump(void)
Dump configuration to stdout.
Definition: conf.c:780
int ConfGetChildValueBool(const ConfNode *base, const char *name, int *val)
Definition: conf.c:530
#define TAILQ_INIT(head)
Definition: queue.h:370
#define NODE_NAME_MAX
Definition: conf.c:46
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:294
void ConfInit(void)
Initialize the configuration system.
Definition: conf.c:113
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
int is_seq
Definition: conf.h:36
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:412
int ConfGetChildValueIntWithDefault(const ConfNode *base, const ConfNode *dflt, const char *name, intmax_t *val)
Definition: conf.c:495
struct ConfNode_ * parent
Definition: conf.h:41
int ConfSetFinal(const char *name, const char *val)
Set a final configuration value.
Definition: conf.c:299
int ConfSetFromString(const char *input, int final)
Set a configuration parameter from a string.
Definition: conf.c:245
int ConfValIsFalse(const char *val)
Check if a value is false.
Definition: conf.c:591
void ConfRestoreContextBackup(void)
Restores the backup of the hash_table present in backup_conf_hash back to conf_hash.
Definition: conf.c:711
int ConfGetValue(const char *name, const char **vptr)
Retrieve the value of a configuration node.
Definition: conf.c:360
#define SCLogWarning(err_code,...)
Macro used to log WARNING messages.
Definition: util-debug.h:281
int ConfValIsTrue(const char *val)
Check if a value is true.
Definition: conf.c:566
int final
Definition: conf.h:39
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:385
Definition: conf.h:32
#define SCMalloc(a)
Definition: util-mem.h:222
int ConfGetChildValueWithDefault(const ConfNode *base, const ConfNode *dflt, const char *name, const char **vptr)
Definition: conf.c:416
#define SCFree(a)
Definition: util-mem.h:322
int ConfGetInt(const char *name, intmax_t *val)
Retrieve a configuration value as an integer.
Definition: conf.c:437
void ConfRegisterTests(void)
Definition: conf.c:1467
char * name
Definition: conf.h:33
ConfNode * ConfGetNode(const char *name)
Get a ConfNode by name.
Definition: conf.c:176
int ConfGetFloat(const char *name, float *val)
Retrieve a configuration value as a float.
Definition: conf.c:645
int ConfGetChildValueInt(const ConfNode *base, const char *name, intmax_t *val)
Definition: conf.c:469
#define SCStrdup(a)
Definition: util-mem.h:268
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
int ConfGetChildValueBoolWithDefault(const ConfNode *base, const ConfNode *dflt, const char *name, int *val)
Definition: conf.c:543
bool ConfNodeHasChildren(const ConfNode *node)
Check if a node has any children.
Definition: conf.c:796
#define TAILQ_NEXT(elm, field)
Definition: queue.h:341
#define TAILQ_EMPTY(head)
Definition: queue.h:347
ConfNode * ConfGetChildWithDefault(const ConfNode *base, const ConfNode *dflt, const char *name)
Definition: conf.c:402
ConfNode * ConfNodeNew(void)
Allocate a new configuration node.
Definition: conf.c:134
#define FAIL_IF_NOT(expr)
Fail a test if expression to true.
Definition: util-unittest.h:82
void ConfNodeDump(const ConfNode *node, const char *prefix)
Dump a configuration node and all its children.
Definition: conf.c:750