1 /* 2 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 3 * 4 * This Source Code Form is subject to the terms of the Mozilla Public 5 * License, v. 2.0. If a copy of the MPL was not distributed with this 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 * 8 * See the COPYRIGHT file distributed with this work for additional 9 * information regarding copyright ownership. 10 */ 11 12 #ifndef ISCCFG_CFG_H 13 #define ISCCFG_CFG_H 1 14 15 /***** 16 ***** Module Info 17 *****/ 18 19 /*! \file isccfg/cfg.h 20 * \brief 21 * This is the new, table-driven, YACC-free configuration file parser. 22 */ 23 24 /*** 25 *** Imports 26 ***/ 27 28 #include <inttypes.h> 29 #include <stdbool.h> 30 #include <time.h> 31 32 #include <isc/formatcheck.h> 33 #include <isc/lang.h> 34 #include <isc/list.h> 35 #include <isc/refcount.h> 36 #include <isc/types.h> 37 38 /*** 39 *** Types 40 ***/ 41 42 /*% 43 * A configuration parser. 44 */ 45 typedef struct cfg_parser cfg_parser_t; 46 47 /*% 48 * A configuration type definition object. There is a single 49 * static cfg_type_t object for each data type supported by 50 * the configuration parser. 51 */ 52 typedef struct cfg_type cfg_type_t; 53 54 /*% 55 * A configuration object. This is the basic building block of the 56 * configuration parse tree. It contains a value (which may be 57 * of one of several types) and information identifying the file 58 * and line number the value came from, for printing error 59 * messages. 60 */ 61 typedef struct cfg_obj cfg_obj_t; 62 63 /*% 64 * A configuration object list element. 65 */ 66 typedef struct cfg_listelt cfg_listelt_t; 67 68 /*% 69 * A callback function to be called when parsing an option 70 * that needs to be interpreted at parsing time, like 71 * "directory". 72 */ 73 typedef isc_result_t (*cfg_parsecallback_t)(const char * clausename, 74 const cfg_obj_t *obj, void *arg); 75 76 /*** 77 *** Functions 78 ***/ 79 80 ISC_LANG_BEGINDECLS 81 82 void 83 cfg_parser_attach(cfg_parser_t *src, cfg_parser_t **dest); 84 /*%< 85 * Reference a parser object. 86 */ 87 88 isc_result_t 89 cfg_parser_create(isc_mem_t *mctx, isc_log_t *lctx, cfg_parser_t **ret); 90 /*%< 91 * Create a configuration file parser. Any warning and error 92 * messages will be logged to 'lctx'. 93 * 94 * The parser object returned can be used for a single call 95 * to cfg_parse_file() or cfg_parse_buffer(). It must not 96 * be reused for parsing multiple files or buffers. 97 */ 98 99 void 100 cfg_parser_setflags(cfg_parser_t *pctx, unsigned int flags, bool turn_on); 101 /*%< 102 * Set parser context flags. The flags are not checked for sensibility. 103 * If 'turn_on' is 'true' the flags will be set, otherwise the flags will 104 * be cleared. 105 * 106 * Requires: 107 *\li "pctx" is not NULL. 108 */ 109 110 void 111 cfg_parser_setcallback(cfg_parser_t *pctx, cfg_parsecallback_t callback, 112 void *arg); 113 /*%< 114 * Make the parser call 'callback' whenever it encounters 115 * a configuration clause with the callback attribute, 116 * passing it the clause name, the clause value, 117 * and 'arg' as arguments. 118 * 119 * To restore the default of not invoking callbacks, pass 120 * callback==NULL and arg==NULL. 121 */ 122 123 isc_result_t 124 cfg_parse_file(cfg_parser_t *pctx, const char *file, const cfg_type_t *type, 125 cfg_obj_t **ret); 126 127 isc_result_t 128 cfg_parse_buffer(cfg_parser_t *pctx, isc_buffer_t *buffer, const char *file, 129 unsigned int line, const cfg_type_t *type, unsigned int flags, 130 cfg_obj_t **ret); 131 /*%< 132 * Read a configuration containing data of type 'type' 133 * and make '*ret' point to its parse tree. 134 * 135 * The configuration is read from the file 'filename' 136 * (isc_parse_file()) or the buffer 'buffer' 137 * (isc_parse_buffer()). 138 * 139 * If 'file' is not NULL, it is the name of the file, or a name to use 140 * for the buffer in place of the filename, when logging errors. 141 * 142 * If 'line' is not 0, then it is the beginning line number to report 143 * when logging errors. This is useful when passing text that has been 144 * read from the middle of a file. 145 * 146 * Returns an error if the file or buffer does not parse correctly. 147 * 148 * Requires: 149 *\li "filename" is valid. 150 *\li "mem" is valid. 151 *\li "type" is valid. 152 *\li "cfg" is non-NULL and "*cfg" is NULL. 153 *\li "flags" be one or more of CFG_PCTX_NODEPRECATED or zero. 154 * 155 * Returns: 156 * \li #ISC_R_SUCCESS - success 157 *\li #ISC_R_NOMEMORY - no memory available 158 *\li #ISC_R_INVALIDFILE - file doesn't exist or is unreadable 159 *\li others - file contains errors 160 */ 161 162 isc_result_t 163 cfg_parser_mapadd(cfg_parser_t *pctx, cfg_obj_t *mapobj, cfg_obj_t *obj, 164 const char *clause); 165 /*%< 166 * Add the object 'obj' to the specified clause in mapbody 'mapobj'. 167 * Used for adding new zones. 168 * 169 * Require: 170 * \li 'obj' is a valid cfg_obj_t. 171 * \li 'mapobj' is a valid cfg_obj_t of type map. 172 * \li 'pctx' is a valid cfg_parser_t. 173 */ 174 175 void 176 cfg_parser_reset(cfg_parser_t *pctx); 177 /*%< 178 * Reset an existing parser so it can be re-used for a new file or 179 * buffer. 180 */ 181 182 void 183 cfg_parser_destroy(cfg_parser_t **pctxp); 184 /*%< 185 * Remove a reference to a configuration parser; destroy it if there are no 186 * more references. 187 */ 188 189 bool 190 cfg_obj_isvoid(const cfg_obj_t *obj); 191 /*%< 192 * Return true iff 'obj' is of void type (e.g., an optional 193 * value not specified). 194 */ 195 196 bool 197 cfg_obj_ismap(const cfg_obj_t *obj); 198 /*%< 199 * Return true iff 'obj' is of a map type. 200 */ 201 202 bool 203 cfg_obj_isfixedpoint(const cfg_obj_t *obj); 204 /*%< 205 * Return true iff 'obj' is of a fixedpoint type. 206 */ 207 208 bool 209 cfg_obj_ispercentage(const cfg_obj_t *obj); 210 /*%< 211 * Return true iff 'obj' is of a percentage type. 212 */ 213 214 isc_result_t 215 cfg_map_get(const cfg_obj_t *mapobj, const char *name, const cfg_obj_t **obj); 216 /*%< 217 * Extract an element from a configuration object, which 218 * must be of a map type. 219 * 220 * Requires: 221 * \li 'mapobj' points to a valid configuration object of a map type. 222 * \li 'name' points to a null-terminated string. 223 * \li 'obj' is non-NULL and '*obj' is NULL. 224 * 225 * Returns: 226 * \li #ISC_R_SUCCESS - success 227 * \li #ISC_R_NOTFOUND - name not found in map 228 */ 229 230 const cfg_obj_t * 231 cfg_map_getname(const cfg_obj_t *mapobj); 232 /*%< 233 * Get the name of a named map object, like a server "key" clause. 234 * 235 * Requires: 236 * \li 'mapobj' points to a valid configuration object of a map type. 237 * 238 * Returns: 239 * \li A pointer to a configuration object naming the map object, 240 * or NULL if the map object does not have a name. 241 */ 242 243 unsigned int 244 cfg_map_count(const cfg_obj_t *mapobj); 245 /*%< 246 * Get the number of elements defined in the symbol table of a map object. 247 * 248 * Requires: 249 * \li 'mapobj' points to a valid configuration object of a map type. 250 * 251 * Returns: 252 * \li The number of elements in the map object. 253 */ 254 255 bool 256 cfg_obj_istuple(const cfg_obj_t *obj); 257 /*%< 258 * Return true iff 'obj' is of a map type. 259 */ 260 261 const cfg_obj_t * 262 cfg_tuple_get(const cfg_obj_t *tupleobj, const char *name); 263 /*%< 264 * Extract an element from a configuration object, which 265 * must be of a tuple type. 266 * 267 * Requires: 268 * \li 'tupleobj' points to a valid configuration object of a tuple type. 269 * \li 'name' points to a null-terminated string naming one of the 270 *\li fields of said tuple type. 271 */ 272 273 bool 274 cfg_obj_isuint32(const cfg_obj_t *obj); 275 /*%< 276 * Return true iff 'obj' is of integer type. 277 */ 278 279 uint32_t 280 cfg_obj_asuint32(const cfg_obj_t *obj); 281 /*%< 282 * Returns the value of a configuration object of 32-bit integer type. 283 * 284 * Requires: 285 * \li 'obj' points to a valid configuration object of 32-bit integer type. 286 * 287 * Returns: 288 * \li A 32-bit unsigned integer. 289 */ 290 291 bool 292 cfg_obj_isuint64(const cfg_obj_t *obj); 293 /*%< 294 * Return true iff 'obj' is of integer type. 295 */ 296 297 uint64_t 298 cfg_obj_asuint64(const cfg_obj_t *obj); 299 /*%< 300 * Returns the value of a configuration object of 64-bit integer type. 301 * 302 * Requires: 303 * \li 'obj' points to a valid configuration object of 64-bit integer type. 304 * 305 * Returns: 306 * \li A 64-bit unsigned integer. 307 */ 308 309 uint32_t 310 cfg_obj_asfixedpoint(const cfg_obj_t *obj); 311 /*%< 312 * Returns the value of a configuration object of fixed point number. 313 * 314 * Requires: 315 * \li 'obj' points to a valid configuration object of fixed point type. 316 * 317 * Returns: 318 * \li A 32-bit unsigned integer. 319 */ 320 321 uint32_t 322 cfg_obj_aspercentage(const cfg_obj_t *obj); 323 /*%< 324 * Returns the value of a configuration object of percentage 325 * 326 * Requires: 327 * \li 'obj' points to a valid configuration object of percentage type. 328 * 329 * Returns: 330 * \li A 32-bit unsigned integer. 331 */ 332 333 bool 334 cfg_obj_isduration(const cfg_obj_t *obj); 335 /*%< 336 * Return true iff 'obj' is of duration type. 337 */ 338 339 uint32_t 340 cfg_obj_asduration(const cfg_obj_t *obj); 341 /*%< 342 * Returns the value of a configuration object of duration 343 * 344 * Requires: 345 * \li 'obj' points to a valid configuration object of duration type. 346 * 347 * Returns: 348 * \li A duration in seconds. 349 */ 350 351 bool 352 cfg_obj_isstring(const cfg_obj_t *obj); 353 /*%< 354 * Return true iff 'obj' is of string type. 355 */ 356 357 const char * 358 cfg_obj_asstring(const cfg_obj_t *obj); 359 /*%< 360 * Returns the value of a configuration object of a string type 361 * as a null-terminated string. 362 * 363 * Requires: 364 * \li 'obj' points to a valid configuration object of a string type. 365 * 366 * Returns: 367 * \li A pointer to a null terminated string. 368 */ 369 370 bool 371 cfg_obj_isboolean(const cfg_obj_t *obj); 372 /*%< 373 * Return true iff 'obj' is of a boolean type. 374 */ 375 376 bool 377 cfg_obj_asboolean(const cfg_obj_t *obj); 378 /*%< 379 * Returns the value of a configuration object of a boolean type. 380 * 381 * Requires: 382 * \li 'obj' points to a valid configuration object of a boolean type. 383 * 384 * Returns: 385 * \li A boolean value. 386 */ 387 388 bool 389 cfg_obj_issockaddr(const cfg_obj_t *obj); 390 /*%< 391 * Return true iff 'obj' is a socket address. 392 */ 393 394 const isc_sockaddr_t * 395 cfg_obj_assockaddr(const cfg_obj_t *obj); 396 /*%< 397 * Returns the value of a configuration object representing a socket address. 398 * 399 * Requires: 400 * \li 'obj' points to a valid configuration object of a socket address 401 * type. 402 * 403 * Returns: 404 * \li A pointer to a sockaddr. The sockaddr must be copied by the caller 405 * if necessary. 406 */ 407 408 isc_dscp_t 409 cfg_obj_getdscp(const cfg_obj_t *obj); 410 /*%< 411 * Returns the DSCP value of a configuration object representing a 412 * socket address. 413 * 414 * Requires: 415 * \li 'obj' points to a valid configuration object of a 416 * socket address type. 417 * 418 * Returns: 419 * \li DSCP value associated with a sockaddr, or -1. 420 */ 421 422 bool 423 cfg_obj_isnetprefix(const cfg_obj_t *obj); 424 /*%< 425 * Return true iff 'obj' is a network prefix. 426 */ 427 428 void 429 cfg_obj_asnetprefix(const cfg_obj_t *obj, isc_netaddr_t *netaddr, 430 unsigned int *prefixlen); 431 /*%< 432 * Gets the value of a configuration object representing a network 433 * prefix. The network address is returned through 'netaddr' and the 434 * prefix length in bits through 'prefixlen'. 435 * 436 * Requires: 437 * \li 'obj' points to a valid configuration object of network prefix type. 438 *\li 'netaddr' and 'prefixlen' are non-NULL. 439 */ 440 441 bool 442 cfg_obj_islist(const cfg_obj_t *obj); 443 /*%< 444 * Return true iff 'obj' is of list type. 445 */ 446 447 const cfg_listelt_t * 448 cfg_list_first(const cfg_obj_t *obj); 449 /*%< 450 * Returns the first list element in a configuration object of a list type. 451 * 452 * Requires: 453 * \li 'obj' points to a valid configuration object of a list type or NULL. 454 * 455 * Returns: 456 * \li A pointer to a cfg_listelt_t representing the first list element, 457 * or NULL if the list is empty or nonexistent. 458 */ 459 460 const cfg_listelt_t * 461 cfg_list_next(const cfg_listelt_t *elt); 462 /*%< 463 * Returns the next element of a list of configuration objects. 464 * 465 * Requires: 466 * \li 'elt' points to cfg_listelt_t obtained from cfg_list_first() or 467 * a previous call to cfg_list_next(). 468 * 469 * Returns: 470 * \li A pointer to a cfg_listelt_t representing the next element, 471 * or NULL if there are no more elements. 472 */ 473 474 unsigned int 475 cfg_list_length(const cfg_obj_t *obj, bool recurse); 476 /*%< 477 * Returns the length of a list of configure objects. If obj is 478 * not a list, returns 0. If recurse is true, add in the length of 479 * all contained lists. 480 */ 481 482 cfg_obj_t * 483 cfg_listelt_value(const cfg_listelt_t *elt); 484 /*%< 485 * Returns the configuration object associated with cfg_listelt_t. 486 * 487 * Requires: 488 * \li 'elt' points to cfg_listelt_t obtained from cfg_list_first() or 489 * cfg_list_next(). 490 * 491 * Returns: 492 * \li A non-NULL pointer to a configuration object. 493 */ 494 495 void 496 cfg_print(const cfg_obj_t *obj, 497 void (*f)(void *closure, const char *text, int textlen), 498 void *closure); 499 void 500 cfg_printx(const cfg_obj_t *obj, unsigned int flags, 501 void (*f)(void *closure, const char *text, int textlen), 502 void *closure); 503 504 #define CFG_PRINTER_XKEY 0x1 /* '?' out shared keys. */ 505 #define CFG_PRINTER_ONELINE 0x2 /* print config as a single line */ 506 #define CFG_PRINTER_ACTIVEONLY \ 507 0x4 /* print only active configuration \ 508 * options, omitting ancient, \ 509 * obsolete, nonimplemented, \ 510 * and test-only options. */ 511 512 /*%< 513 * Print the configuration object 'obj' by repeatedly calling the 514 * function 'f', passing 'closure' and a region of text starting 515 * at 'text' and comprising 'textlen' characters. 516 * 517 * If CFG_PRINTER_XKEY the contents of shared keys will be obscured 518 * by replacing them with question marks ('?') 519 */ 520 521 void 522 cfg_print_grammar(const cfg_type_t *type, unsigned int flags, 523 void (*f)(void *closure, const char *text, int textlen), 524 void *closure); 525 /*%< 526 * Print a summary of the grammar of the configuration type 'type'. 527 */ 528 529 bool 530 cfg_obj_istype(const cfg_obj_t *obj, const cfg_type_t *type); 531 /*%< 532 * Return true iff 'obj' is of type 'type'. 533 */ 534 535 void 536 cfg_obj_attach(cfg_obj_t *src, cfg_obj_t **dest); 537 /*%< 538 * Reference a configuration object. 539 */ 540 541 void 542 cfg_obj_destroy(cfg_parser_t *pctx, cfg_obj_t **obj); 543 /*%< 544 * Delete a reference to a configuration object; destroy the object if 545 * there are no more references. 546 * 547 * Require: 548 * \li '*obj' is a valid cfg_obj_t. 549 * \li 'pctx' is a valid cfg_parser_t. 550 */ 551 552 void 553 cfg_obj_log(const cfg_obj_t *obj, isc_log_t *lctx, int level, const char *fmt, 554 ...) ISC_FORMAT_PRINTF(4, 5); 555 /*%< 556 * Log a message concerning configuration object 'obj' to the logging 557 * channel of 'pctx', at log level 'level'. The message will be prefixed 558 * with the file name(s) and line number where 'obj' was defined. 559 */ 560 561 const char * 562 cfg_obj_file(const cfg_obj_t *obj); 563 /*%< 564 * Return the file that defined this object. 565 */ 566 567 unsigned int 568 cfg_obj_line(const cfg_obj_t *obj); 569 /*%< 570 * Return the line in file where this object was defined. 571 */ 572 573 const char * 574 cfg_map_firstclause(const cfg_type_t *map, const void **clauses, 575 unsigned int *idx); 576 const char * 577 cfg_map_nextclause(const cfg_type_t *map, const void **clauses, 578 unsigned int *idx); 579 580 typedef isc_result_t(pluginlist_cb_t)(const cfg_obj_t *config, 581 const cfg_obj_t *obj, 582 const char * plugin_path, 583 const char * parameters, 584 void * callback_data); 585 /*%< 586 * Function prototype for the callback used with cfg_pluginlist_foreach(). 587 * Called once for each element of the list passed to cfg_pluginlist_foreach(). 588 * If this callback returns anything else than #ISC_R_SUCCESS, no further list 589 * elements will be processed. 590 * 591 * \li 'config' - the 'config' object passed to cfg_pluginlist_foreach() 592 * \li 'obj' - object representing the specific "plugin" stanza to be processed 593 * \li 'plugin_path' - path to the shared object with plugin code 594 * \li 'parameters' - configuration text for the plugin 595 * \li 'callback_data' - the pointer passed to cfg_pluginlist_foreach() 596 */ 597 598 isc_result_t 599 cfg_pluginlist_foreach(const cfg_obj_t *config, const cfg_obj_t *list, 600 isc_log_t *lctx, pluginlist_cb_t *callback, 601 void *callback_data); 602 /*%< 603 * For every "plugin" stanza present in 'list' (which in turn is a part of 604 * 'config'), invoke the given 'callback', passing 'callback_data' to it along 605 * with a fixed set of arguments (see the definition of the #pluginlist_cb_t 606 * type). Use logging context 'lctx' for logging error messages. Interrupt 607 * processing if 'callback' returns something else than #ISC_R_SUCCESS for any 608 * element of 'list'. 609 * 610 * Requires: 611 * 612 * \li 'config' is not NULL 613 * \li 'callback' is not NULL 614 * 615 * Returns: 616 * 617 * \li #ISC_R_SUCCESS if 'callback' returned #ISC_R_SUCCESS for all elements of 618 * 'list' 619 * \li first 'callback' return value which was not #ISC_R_SUCCESS otherwise 620 */ 621 622 ISC_LANG_ENDDECLS 623 624 #endif /* ISCCFG_CFG_H */ 625