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 "adapter/adapter.h"
00035 #include "parser/zonelistparser.h"
00036 #include "shared/file.h"
00037 #include "shared/log.h"
00038 #include "signer/zonelist.h"
00039 #include "signer/zone.h"
00040 #include "shared/status.h"
00041
00042 #include <libxml/xpath.h>
00043 #include <libxml/xmlreader.h>
00044 #include <stdlib.h>
00045 #include <string.h>
00046
00047 static const char* parser_str = "parser";
00048
00049
00054 static const char*
00055 parse_zonelist_element(xmlXPathContextPtr xpathCtx, xmlChar* expr)
00056 {
00057 xmlXPathObjectPtr xpathObj = NULL;
00058 const char* str = NULL;
00059
00060 ods_log_assert(xpathCtx);
00061 ods_log_assert(expr);
00062
00063 xpathObj = xmlXPathEvalExpression(expr, xpathCtx);
00064 if (xpathObj == NULL) {
00065 ods_log_error("[%s] unable to evaluate xpath expression %s",
00066 parser_str, expr);
00067 return NULL;
00068 }
00069 str = (const char*) xmlXPathCastToString(xpathObj);
00070 xmlXPathFreeObject(xpathObj);
00071 return str;
00072 }
00073
00074
00079 static adapter_type*
00080 zlp_adapter(xmlNode* curNode, adapter_mode type, int inbound)
00081 {
00082 const char* file = NULL;
00083 adapter_type* adapter = NULL;
00084
00085 file = (const char*) xmlNodeGetContent(curNode);
00086 if (!file) {
00087 ods_log_error("[%s] unable to read %s adapter", parser_str,
00088 inbound?"input":"output");
00089 return NULL;
00090 }
00091
00092 adapter = adapter_create(file, type, inbound);
00093 free((void*)file);
00094 return adapter;
00095 }
00096
00097
00102 adapter_type*
00103 parse_zonelist_adapter(xmlXPathContextPtr xpathCtx, xmlChar* expr,
00104 int inbound)
00105 {
00106 xmlXPathObjectPtr xpathObj = NULL;
00107 xmlNode* curNode = NULL;
00108 adapter_type* adapter = NULL;
00109 int i = 0;
00110
00111 if (!xpathCtx || !expr) {
00112 return NULL;
00113 }
00114
00115 xpathObj = xmlXPathEvalExpression(expr, xpathCtx);
00116 if (xpathObj == NULL) {
00117 ods_log_error("[%s] unable to evaluate xpath expression %s",
00118 parser_str, expr);
00119 return NULL;
00120 }
00121
00122 if (xpathObj->nodesetval) {
00123 for (i=0; i < xpathObj->nodesetval->nodeNr; i++) {
00124 curNode = xpathObj->nodesetval->nodeTab[i]->xmlChildrenNode;
00125 while (curNode) {
00126 if (xmlStrEqual(curNode->name, (const xmlChar*)"File")) {
00127 adapter = zlp_adapter(curNode, ADAPTER_FILE, inbound);
00128 }
00129 if (adapter) {
00130 break;
00131 }
00132 curNode = curNode->next;
00133 }
00134 }
00135 }
00136 xmlXPathFreeObject(xpathObj);
00137 return adapter;
00138 }
00139
00140
00145 static void
00146 parse_zonelist_adapters(xmlXPathContextPtr xpathCtx, zone_type* zone)
00147 {
00148 xmlChar* i_expr = (xmlChar*) "//Zone/Adapters/Input";
00149 xmlChar* o_expr = (xmlChar*) "//Zone/Adapters/Output";
00150
00151 if (!xpathCtx || !zone) {
00152 return;
00153 }
00154
00155 zone->adinbound = parse_zonelist_adapter(xpathCtx, i_expr, 1);
00156 zone->adoutbound = parse_zonelist_adapter(xpathCtx, o_expr, 0);
00157 return;
00158 }
00159
00160
00165 ods_status
00166 parse_zonelist_zones(struct zonelist_struct* zlist, const char* zlfile)
00167 {
00168 char* tag_name = NULL;
00169 char* zone_name = NULL;
00170 zone_type* new_zone = NULL;
00171 int ret = 0;
00172
00173 xmlTextReaderPtr reader = NULL;
00174 xmlDocPtr doc = NULL;
00175 xmlXPathContextPtr xpathCtx = NULL;
00176
00177 xmlChar* name_expr = (unsigned char*) "name";
00178 xmlChar* policy_expr = (unsigned char*) "//Zone/Policy";
00179 xmlChar* signconf_expr = (unsigned char*) "//Zone/SignerConfiguration";
00180
00181 if (!zlist) {
00182 ods_log_error("[%s] unable to parse zone list: no storage",
00183 parser_str);
00184 return ODS_STATUS_ASSERT_ERR;
00185 }
00186 ods_log_assert(zlist);
00187
00188 if (!zlfile) {
00189 ods_log_error("[%s] unable to parse zone list: no filename",
00190 parser_str);
00191 return ODS_STATUS_ASSERT_ERR;
00192 }
00193 ods_log_assert(zlfile);
00194
00195 reader = xmlNewTextReaderFilename(zlfile);
00196 if (!reader) {
00197 ods_log_error("[%s] unable to open file %s", parser_str, zlfile);
00198 return ODS_STATUS_XML_ERR;
00199 }
00200
00201 ret = xmlTextReaderRead(reader);
00202 while (ret == XML_READER_TYPE_ELEMENT) {
00203 tag_name = (char*) xmlTextReaderLocalName(reader);
00204 if (ods_strcmp(tag_name, "Zone") == 0 &&
00205 ods_strcmp(tag_name, "ZoneList") != 0 &&
00206 xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT) {
00207
00208 zone_name = (char*) xmlTextReaderGetAttribute(reader,
00209 name_expr);
00210 if (!zone_name || strlen(zone_name) <= 0) {
00211 ods_log_error("[%s] unable to extract zone name from "
00212 "zonelist", parser_str);
00213 if (zone_name) {
00214 free((void*) zone_name);
00215 }
00216 free((void*) tag_name);
00217 ret = xmlTextReaderRead(reader);
00218 continue;
00219 }
00220
00221
00222 xmlTextReaderExpand(reader);
00223 doc = xmlTextReaderCurrentDoc(reader);
00224 if (doc) {
00225 xpathCtx = xmlXPathNewContext(doc);
00226 }
00227 if (doc == NULL || xpathCtx == NULL) {
00228 ods_log_error("[%s] unable to read zone %s; skipping",
00229 parser_str, zone_name);
00230 ret = xmlTextReaderRead(reader);
00231 free((void*) zone_name);
00232 free((void*) tag_name);
00233 if (xpathCtx) {
00234 xmlXPathFreeContext(xpathCtx);
00235 xpathCtx = NULL;
00236 }
00237 continue;
00238 }
00239
00240
00241 new_zone = zone_create(zone_name, LDNS_RR_CLASS_IN);
00242 new_zone->policy_name = parse_zonelist_element(xpathCtx,
00243 policy_expr);
00244 new_zone->signconf_filename = parse_zonelist_element(xpathCtx,
00245 signconf_expr);
00246 parse_zonelist_adapters(xpathCtx, new_zone);
00247
00248
00249 if (zonelist_add_zone((zonelist_type*) zlist, new_zone) == NULL) {
00250 ods_log_error("[%s] unable to add zone %s", parser_str,
00251 zone_name);
00252 new_zone = NULL;
00253 }
00254 ods_log_debug("[%s] zone %s added", parser_str, zone_name);
00255 free((void*) zone_name);
00256 xmlXPathFreeContext(xpathCtx);
00257 }
00258 free((void*) tag_name);
00259 ret = xmlTextReaderRead(reader);
00260 }
00261
00262 ods_log_debug("[%s] no more zones", parser_str);
00263 xmlFreeTextReader(reader);
00264 if (doc) {
00265 xmlFreeDoc(doc);
00266 }
00267 if (ret != 0) {
00268 ods_log_error("[%s] error parsing file %s", parser_str, zlfile);
00269 return ODS_STATUS_PARSE_ERR;
00270 }
00271 return ODS_STATUS_OK;
00272 }