00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00034 #include "parser/confparser.h"
00035 #include "parser/zonelistparser.h"
00036 #include "shared/allocator.h"
00037 #include "shared/file.h"
00038 #include "shared/log.h"
00039 #include "shared/status.h"
00040
00041 #include <libxml/xpath.h>
00042 #include <libxml/relaxng.h>
00043 #include <libxml/xmlreader.h>
00044 #include <string.h>
00045 #include <stdlib.h>
00046
00047 static const char* parser_str = "parser";
00048
00049
00054 ods_status
00055 parse_file_check(const char* cfgfile, const char* rngfile)
00056 {
00057 xmlDocPtr doc = NULL;
00058 xmlDocPtr rngdoc = NULL;
00059 xmlRelaxNGParserCtxtPtr rngpctx = NULL;
00060 xmlRelaxNGValidCtxtPtr rngctx = NULL;
00061 xmlRelaxNGPtr schema = NULL;
00062
00063 if (!cfgfile || !rngfile) {
00064 ods_log_error("[%s] no cfgfile or rngfile", parser_str);
00065 return ODS_STATUS_ASSERT_ERR;
00066 }
00067 ods_log_assert(cfgfile);
00068 ods_log_assert(rngfile);
00069 ods_log_debug("[%s] check cfgfile %s with rngfile %s", parser_str,
00070 cfgfile, rngfile);
00071
00072
00073 doc = xmlParseFile(cfgfile);
00074 if (doc == NULL) {
00075 ods_log_error("[%s] unable to read cfgfile %s", parser_str,
00076 cfgfile);
00077 return ODS_STATUS_XML_ERR;
00078 }
00079
00080 rngdoc = xmlParseFile(rngfile);
00081 if (rngdoc == NULL) {
00082 ods_log_error("[%s] unable to read rngfile %s", parser_str,
00083 rngfile);
00084 xmlFreeDoc(doc);
00085 return ODS_STATUS_XML_ERR;
00086 }
00087
00088 rngpctx = xmlRelaxNGNewDocParserCtxt(rngdoc);
00089 if (rngpctx == NULL) {
00090 xmlFreeDoc(rngdoc);
00091 xmlFreeDoc(doc);
00092 ods_log_error("[%s] unable to create XML RelaxNGs parser context",
00093 parser_str);
00094 return ODS_STATUS_XML_ERR;
00095 }
00096
00097
00098
00099 schema = xmlRelaxNGParse(rngpctx);
00100 if (schema == NULL) {
00101 ods_log_error("[%s] unable to parse a schema definition resource",
00102 parser_str);
00103 xmlRelaxNGFreeParserCtxt(rngpctx);
00104 xmlFreeDoc(rngdoc);
00105 xmlFreeDoc(doc);
00106 return ODS_STATUS_PARSE_ERR;
00107 }
00108
00109 rngctx = xmlRelaxNGNewValidCtxt(schema);
00110 if (rngctx == NULL) {
00111 ods_log_error("[%s] unable to create RelaxNGs validation context",
00112 parser_str);
00113 xmlRelaxNGFree(schema);
00114 xmlRelaxNGFreeParserCtxt(rngpctx);
00115 xmlFreeDoc(rngdoc);
00116 xmlFreeDoc(doc);
00117 return ODS_STATUS_RNG_ERR;
00118 }
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 xmlRelaxNGFreeValidCtxt(rngctx);
00135 xmlRelaxNGFree(schema);
00136 xmlRelaxNGFreeParserCtxt(rngpctx);
00137 xmlFreeDoc(rngdoc);
00138 xmlFreeDoc(doc);
00139 return ODS_STATUS_OK;
00140 }
00141
00142
00143
00144
00149 adapter_type**
00150 parse_conf_adapters(allocator_type* allocator, const char* cfgfile,
00151 int* count)
00152 {
00153 char* tag_name = NULL;
00154 adapter_type** adapters = NULL;
00155 int ret = 0;
00156 size_t adcount = 0;
00157
00158 xmlTextReaderPtr reader = NULL;
00159 xmlDocPtr doc = NULL;
00160 xmlXPathContextPtr xpathCtx = NULL;
00161
00162 xmlChar* expr = (xmlChar*) "//Adapter";
00163
00164 ods_log_assert(allocator);
00165 ods_log_assert(cfgfile);
00166
00167 reader = xmlNewTextReaderFilename(cfgfile);
00168 if (!reader) {
00169 ods_log_error("[%s] unable to open file %s", parser_str, cfgfile);
00170 return NULL;
00171 }
00172
00173 ret = xmlTextReaderRead(reader);
00174 adapters = (adapter_type**) allocator_alloc(allocator,
00175 ADMAX * sizeof(adapter_type*));
00176 while (ret == XML_READER_TYPE_ELEMENT) {
00177 if (adcount >= ADMAX) {
00178 ods_log_warning("[%s] too many adapters in config file %s, "
00179 "skipping additional adapters", parser_str, cfgfile);
00180 break;
00181 }
00182
00183 tag_name = (char*) xmlTextReaderLocalName(reader);
00184
00185
00186
00187
00188 if (ods_strcmp(tag_name, "Adapter") == 0 &&
00189 ods_strcmp(tag_name, "Adapters") != 0 &&
00190 xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT) {
00191
00192
00193
00194 xmlTextReaderExpand(reader);
00195 doc = xmlTextReaderCurrentDoc(reader);
00196 if (doc) {
00197 xpathCtx = xmlXPathNewContext(doc);
00198 }
00199 if (doc == NULL || xpathCtx == NULL) {
00200 ods_log_error("[%s] unable to read adapter; skipping",
00201 parser_str);
00202 ret = xmlTextReaderRead(reader);
00203 free((void*) tag_name);
00204 continue;
00205 }
00206
00207 adapters[adcount] = parse_zonelist_adapter(xpathCtx, expr, 1);
00208 adcount++;
00209 ods_log_debug("[%s] adapter added", parser_str);
00210 xmlXPathFreeContext(xpathCtx);
00211 }
00212 free((void*) tag_name);
00213 ret = xmlTextReaderRead(reader);
00214 }
00215
00216
00217 ods_log_debug("[%s] no more adapters", parser_str);
00218 xmlFreeTextReader(reader);
00219 if (doc) {
00220 xmlFreeDoc(doc);
00221 }
00222 if (ret != 0) {
00223 ods_log_error("[%s] error parsing file %s", parser_str, cfgfile);
00224 return NULL;
00225 }
00226 *count = (int) adcount;
00227 return adapters;
00228 }
00229
00230
00235 const char*
00236 parse_conf_string(const char* cfgfile, const char* expr, int required)
00237 {
00238 xmlDocPtr doc = NULL;
00239 xmlXPathContextPtr xpathCtx = NULL;
00240 xmlXPathObjectPtr xpathObj = NULL;
00241 xmlChar *xexpr = NULL;
00242 const char* string = NULL;
00243
00244 ods_log_assert(expr);
00245 ods_log_assert(cfgfile);
00246
00247
00248 doc = xmlParseFile(cfgfile);
00249 if (doc == NULL) {
00250 return NULL;
00251 }
00252
00253 xpathCtx = xmlXPathNewContext(doc);
00254 if (xpathCtx == NULL) {
00255 ods_log_error("[%s] unable to create new XPath context for cfgile "
00256 "%s expr %s", parser_str, cfgfile, (char*) expr);
00257 xmlFreeDoc(doc);
00258 return NULL;
00259 }
00260
00261 xexpr = (unsigned char*) expr;
00262 xpathObj = xmlXPathEvalExpression(xexpr, xpathCtx);
00263 if (xpathObj == NULL || xpathObj->nodesetval == NULL ||
00264 xpathObj->nodesetval->nodeNr <= 0) {
00265 if (required) {
00266 ods_log_error("[%s] unable to evaluate required element %s in "
00267 "cfgfile %s", parser_str, (char*) xexpr, cfgfile);
00268 }
00269 xmlXPathFreeContext(xpathCtx);
00270 if (xpathObj) {
00271 xmlXPathFreeObject(xpathObj);
00272 }
00273 xmlFreeDoc(doc);
00274 return NULL;
00275 }
00276 if (xpathObj->nodesetval != NULL &&
00277 xpathObj->nodesetval->nodeNr > 0) {
00278 string = (const char*) xmlXPathCastToString(xpathObj);
00279 xmlXPathFreeContext(xpathCtx);
00280 xmlXPathFreeObject(xpathObj);
00281 xmlFreeDoc(doc);
00282 return string;
00283 }
00284 xmlXPathFreeContext(xpathCtx);
00285 xmlXPathFreeObject(xpathObj);
00286 xmlFreeDoc(doc);
00287 return NULL;
00288 }
00289
00290
00291 const char*
00292 parse_conf_zonelist_filename(allocator_type* allocator, const char* cfgfile)
00293 {
00294 const char* dup = NULL;
00295 const char* str = parse_conf_string(
00296 cfgfile,
00297 "//Configuration/Common/ZoneListFile",
00298 1);
00299
00300 if (str) {
00301 dup = allocator_strdup(allocator, str);
00302 free((void*)str);
00303 }
00304 return dup;
00305 }
00306
00307
00308 const char*
00309 parse_conf_zonefetch_filename(allocator_type* allocator, const char* cfgfile)
00310 {
00311 const char* dup = NULL;
00312 const char* str = parse_conf_string(
00313 cfgfile,
00314 "//Configuration/Common/ZoneFetchFile",
00315 0);
00316
00317 if (str) {
00318 dup = allocator_strdup(allocator, str);
00319 free((void*)str);
00320 }
00321 return dup;
00322 }
00323
00324
00325 const char*
00326 parse_conf_log_filename(allocator_type* allocator, const char* cfgfile)
00327 {
00328 const char* dup = NULL;
00329 const char* str = parse_conf_string(cfgfile,
00330 "//Configuration/Common/Logging/Syslog/Facility",
00331 0);
00332 if (!str) {
00333 str = parse_conf_string(cfgfile,
00334 "//Configuration/Common/Logging/File/Filename",
00335 0);
00336 }
00337 if (str) {
00338 dup = allocator_strdup(allocator, str);
00339 free((void*)str);
00340 }
00341 return dup;
00342 }
00343
00344
00345 const char*
00346 parse_conf_pid_filename(allocator_type* allocator, const char* cfgfile)
00347 {
00348 const char* dup = NULL;
00349 const char* str = parse_conf_string(
00350 cfgfile,
00351 "//Configuration/Signer/PidFile",
00352 0);
00353
00354 if (str) {
00355 dup = allocator_strdup(allocator, str);
00356 free((void*)str);
00357 } else {
00358 dup = allocator_strdup(allocator, ODS_SE_PIDFILE);
00359 }
00360 return dup;
00361 }
00362
00363
00364 const char*
00365 parse_conf_notify_command(allocator_type* allocator, const char* cfgfile)
00366 {
00367 const char* dup = NULL;
00368 const char* str = parse_conf_string(
00369 cfgfile,
00370 "//Configuration/Signer/NotifyCommand",
00371 0);
00372
00373 if (str) {
00374 dup = allocator_strdup(allocator, str);
00375 free((void*)str);
00376 }
00377 return dup;
00378 }
00379
00380
00381 const char*
00382 parse_conf_clisock_filename(allocator_type* allocator, const char* cfgfile)
00383 {
00384 const char* dup = NULL;
00385 const char* str = parse_conf_string(
00386 cfgfile,
00387 "//Configuration/Signer/SocketFile",
00388 0);
00389
00390 if (str) {
00391 dup = allocator_strdup(allocator, str);
00392 free((void*)str);
00393 } else {
00394 dup = allocator_strdup(allocator, ODS_SE_SOCKFILE);
00395 }
00396 return dup;
00397 }
00398
00399
00400 const char*
00401 parse_conf_working_dir(allocator_type* allocator, const char* cfgfile)
00402 {
00403 const char* dup = NULL;
00404 const char* str = parse_conf_string(
00405 cfgfile,
00406 "//Configuration/Signer/WorkingDirectory",
00407 0);
00408
00409 if (str) {
00410 dup = allocator_strdup(allocator, str);
00411 free((void*)str);
00412 } else {
00413 dup = allocator_strdup(allocator, ODS_SE_WORKDIR);
00414 }
00415 return dup;
00416 }
00417
00418
00419 const char*
00420 parse_conf_username(allocator_type* allocator, const char* cfgfile)
00421 {
00422 const char* dup = NULL;
00423 const char* str = parse_conf_string(
00424 cfgfile,
00425 "//Configuration/Signer/Privileges/User",
00426 0);
00427
00428 if (str) {
00429 dup = allocator_strdup(allocator, str);
00430 free((void*)str);
00431 }
00432 return dup;
00433 }
00434
00435
00436 const char*
00437 parse_conf_group(allocator_type* allocator, const char* cfgfile)
00438 {
00439 const char* dup = NULL;
00440 const char* str = parse_conf_string(
00441 cfgfile,
00442 "//Configuration/Signer/Privileges/Group",
00443 0);
00444
00445 if (str) {
00446 dup = allocator_strdup(allocator, str);
00447 free((void*)str);
00448 }
00449 return dup;
00450 }
00451
00452
00453 const char*
00454 parse_conf_chroot(allocator_type* allocator, const char* cfgfile)
00455 {
00456 const char* dup = NULL;
00457 const char* str = parse_conf_string(
00458 cfgfile,
00459 "//Configuration/Signer/Privileges/Directory",
00460 0);
00461
00462 if (str) {
00463 dup = allocator_strdup(allocator, str);
00464 free((void*)str);
00465 }
00466 return dup;
00467 }
00468
00469
00474 int
00475 parse_conf_use_syslog(const char* cfgfile)
00476 {
00477 const char* str = parse_conf_string(cfgfile,
00478 "//Configuration/Common/Logging/Syslog/Facility",
00479 0);
00480 if (str) {
00481 free((void*)str);
00482 return 1;
00483 }
00484 return 0;
00485 }
00486
00487
00488 int
00489 parse_conf_worker_threads(const char* cfgfile)
00490 {
00491 int numwt = ODS_SE_WORKERTHREADS;
00492 const char* str = parse_conf_string(cfgfile,
00493 "//Configuration/Signer/WorkerThreads",
00494 0);
00495 if (str) {
00496 if (strlen(str) > 0) {
00497 numwt = atoi(str);
00498 }
00499 free((void*)str);
00500 }
00501 return numwt;
00502 }
00503
00504
00505 int
00506 parse_conf_signer_threads(const char* cfgfile)
00507 {
00508 int numwt = ODS_SE_WORKERTHREADS;
00509 const char* str = parse_conf_string(cfgfile,
00510 "//Configuration/Signer/SignerThreads",
00511 0);
00512 if (str) {
00513 if (strlen(str) > 0) {
00514 numwt = atoi(str);
00515 }
00516 free((void*)str);
00517 return numwt;
00518 }
00519
00520 return parse_conf_worker_threads(cfgfile);
00521 }