-/* ------------------------------------------------\r
-Copyright 2014 AT&T Intellectual Property\r
- Licensed under the Apache License, Version 2.0 (the "License");\r
- you may not use this file except in compliance with the License.\r
- You may obtain a copy of the License at\r
-\r
- http://www.apache.org/licenses/LICENSE-2.0\r
-\r
- Unless required by applicable law or agreed to in writing, software\r
- distributed under the License is distributed on an "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- See the License for the specific language governing permissions and\r
- limitations under the License.\r
- ------------------------------------------- */\r
-#include "iface_q.h"\r
-#include<errno.h>\r
-#include <unistd.h>\r
-#include <algorithm>\r
-#include <cctype>\r
-\r
-\r
-using namespace std;\r
-\r
-extern string hostname; // namne of the current host\r
-\r
-static string int_to_string(int i){\r
- string ret;\r
- char tmpstr[100];\r
- sprintf(tmpstr,"%d",i);\r
- ret=tmpstr;\r
- return(ret);\r
-}\r
-\r
-\r
-// Interface for the res parser\r
-extern int ResParserparse(void);\r
-extern FILE *ResParserin;\r
-extern int ResParserdebug;\r
-void ResParser_setfileinput(FILE *f);\r
-void ResParser_setstringinput(char *s);\r
-extern int flex_res_lineno;\r
-\r
-resparse_data *rpd_ptr;\r
-vector<string> res_val_vec, res_attr_vec;\r
-string res_a, res_v;\r
-\r
-///////////////////////////////////////\r
-/// iface_t methods\r
-\r
- void iface_t::add_property(const char *name, const char *att){\r
- string nm(name);\r
- std::transform(nm.begin(), nm.end(), nm.begin(), (int(*)(int))std::tolower);\r
- vals[nm].push_back(att);\r
- }\r
-\r
- void iface_t::add_property(const char *name, const char **atts){\r
- string val = "";\r
- string nm = name;\r
- std::transform(nm.begin(), nm.end(), nm.begin(), (int(*)(int))std::tolower);\r
- if(atts[0]) val = atts[1];\r
-\r
- vals[nm].push_back(val);\r
- }\r
-\r
- void iface_t::add_property(const char *name, vector<string> &val_vec){\r
- string val = "";\r
- string nm = name;\r
- std::transform(nm.begin(), nm.end(), nm.begin(), (int(*)(int))std::tolower);\r
- if(val_vec.size()) val = val_vec[0];\r
-\r
- vals[nm].push_back(val);\r
- }\r
-\r
- int iface_t::finalize(string &errs){\r
- string tag ="ERROR in interface starting at line "+int_to_string(lineno)+", ";\r
- string e;\r
- if(vals.count("name") == 0){\r
- e += "Name not specified. ";\r
- }else{\r
- if(vals["name"].size() > 1){\r
- e+="More than one name specified. ";\r
- }\r
- }\r
-\r
- if(e != ""){\r
- errs += tag + e + "\n";\r
- return(1);\r
- }\r
- return(0);\r
- }\r
-\r
- string iface_t::to_string(){\r
- int i;\r
- string ret = "Interface "+vals["name"][0]+":\n";\r
- map<string, vector<string> >::iterator svmi;\r
- for(svmi=vals.begin();svmi!=vals.end();++svmi){\r
- ret += "\t"+(*svmi).first + " : ";\r
- for(i=0;i<((*svmi).second).size();++i){\r
- if(i>0) ret+=", ";\r
- ret += (*svmi).second[i];\r
- }\r
- ret += "\n";\r
- }\r
-\r
- return ret;\r
- }\r
-\r
- string iface_t::get_name(){\r
- if(vals.count("name") == 0) return (string)"";\r
- return (vals["name"])[0];\r
- }\r
-\r
- string iface_t::get_host(){\r
- if(vals.count("host") == 0) return (string)"";\r
- return (vals["host"])[0];\r
- }\r
-\r
-\r
- bool iface_t::eval_Contains(string prop, string val){\r
- // convert to lowercase\r
- std::transform(prop.begin(), prop.end(), prop.begin(), (int(*)(int))std::tolower);\r
-\r
- if(vals.count(prop) == 0) return false;\r
- int i;\r
- for(i=0;i<vals[prop].size();++i){\r
- if((vals[prop])[i] == val) return true;\r
- }\r
- return false;\r
- }\r
-\r
- bool iface_t::eval_Equals(string prop, string val){\r
- // convert to lowercase\r
- std::transform(prop.begin(), prop.end(), prop.begin(), (int(*)(int))std::tolower);\r
- if(vals.count(prop) == 0) return false;\r
- if(vals[prop].size() != 1) return false;\r
- int i;\r
- for(i=0;i<vals[prop].size();++i){\r
- if((vals[prop])[i] == val) return true;\r
- }\r
- return false;\r
- }\r
-\r
- bool iface_t::eval_Exists(string prop){\r
- // convert to lowercase\r
- std::transform(prop.begin(), prop.end(), prop.begin(), (int(*)(int))std::tolower);\r
- if(vals.count(prop) == 0) return false;\r
- return true;\r
- }\r
-\r
-\r
-///////////////////////////////////////\r
-/// gs_host_t methods\r
-\r
- void gs_host_t::add_property(const char *name, const char *att){\r
- string nm(name);\r
- std::transform(nm.begin(), nm.end(), nm.begin(), (int(*)(int))std::tolower);\r
- vals[nm].push_back(att);\r
- }\r
-\r
- void gs_host_t::add_property(const char *name, vector<string> &val_vec){\r
- string val = "";\r
- string nm = name;\r
- std::transform(nm.begin(), nm.end(), nm.begin(), (int(*)(int))std::tolower);\r
- if(val_vec.size()) val = val_vec[0];\r
-\r
- vals[nm].push_back(val);\r
- }\r
-\r
- int gs_host_t::finalize(string &errs){\r
- string tag ="ERROR in host starting at line "+int_to_string(lineno)+", ";\r
- string e;\r
- if(vals.count("name") == 0){\r
- e += "Name not specified. ";\r
- }else{\r
- if(vals["name"].size() > 1){\r
- e+="More than one name specified. ";\r
- }\r
- }\r
-\r
- if(e != ""){\r
- errs += tag + e + "\n";\r
- return(1);\r
- }\r
- return(0);\r
- }\r
-\r
-\r
-/////////////////////////////////////////////////////////////////\r
-/// reparse_data methods\r
-\r
- int resparse_data::finalize_iface(string &errs){\r
- int ret = curr_iface->finalize(errs);\r
- if(ret) {\r
- delete curr_iface;\r
- failure = true;\r
- }else{\r
- curr_host->add_interface(curr_iface);\r
- }\r
- return ret;\r
- }\r
-\r
-\r
- int resparse_data::finalize_host(string &errs){\r
- int ret = curr_host->finalize(errs);\r
- if(ret) {\r
- delete curr_host;\r
- failure = true;\r
- }else{\r
-\r
- string host = curr_host->vals["name"][0];\r
- // in non-distributed case we will ignore all other hosts\r
- if (!distributed_mode) {\r
- char buf[1000];\r
- if (host != hostname)\r
- return ret;\r
- }\r
- // we need to exclude failed hosts\r
- if (!use_live_hosts_file || live_hosts->count(hostname)) {\r
- hosts.push_back(curr_host);\r
-\r
- // push the host name to every interface\r
- curr_host->propagate_name();\r
-\r
- // add all interfaces into interface list\r
- for(int i=0;i<curr_host->ifaces.size();i++)\r
- ifaces.push_back(curr_host->ifaces[i]);\r
- }\r
- }\r
- return ret;\r
- }\r
-\r
- string resparse_data::to_string(){\r
- string ret;\r
- int i;\r
- for(i=0;i<ifaces.size();i++)\r
- ret += ifaces[i]->to_string();\r
- return ret;\r
- }\r
-\r
- vector<pair<string,string> > resparse_data::find_ifaces(predicate_t *pr){\r
- int i;\r
- vector<pair<string,string> > ret;\r
- for(i=0;i<ifaces.size();++i){\r
- if(this->eval_pred(i,pr)){\r
- pair<string,string> p(ifaces[i]->get_host(), ifaces[i]->get_name());\r
- ret.push_back(p);\r
- }\r
- }\r
- return ret;\r
- }\r
-\r
-\r
- vector<int> resparse_data::get_ifaces_by_Name(std::string host_name, std::string if_name){\r
- int i;\r
- vector<int> ret;\r
- for(i=0;i<ifaces.size();++i){\r
- if(ifaces[i]->get_host() == host_name && ifaces[i]->get_name() == if_name)\r
- ret.push_back(i);\r
-\r
- }\r
- return ret;\r
- }\r
-\r
-\r
- bool resparse_data::eval_pred(int i, predicate_t *pr){\r
- vector<scalarexp_t *> op_list;\r
- string prop, val;\r
-\r
- switch(pr->get_operator_type()){\r
- case PRED_IN:\r
- fprintf(stderr,"INTERNAL ERROR in reparse_date::eval_pred, line %d, character %d, IN not supported. %d\n",\r
- pr->get_lineno(), pr->get_charno(), pr->get_operator_type() );\r
- exit(1);\r
- case PRED_COMPARE:\r
- fprintf(stderr,"INTERNAL ERROR in reparse_date::eval_pred, line %d, character %d, IN not supported. %d\n",\r
- pr->get_lineno(), pr->get_charno(), pr->get_operator_type() );\r
- exit(1);\r
- case PRED_UNARY_OP:\r
- if(pr->get_op() == "NOT")\r
- return(! eval_pred(i, pr->get_left_pr()) );\r
- fprintf(stderr,"INTERNAL ERROR in reparse_date::eval_pred, line %d, character %d, unknown unary pred operator %s.\n",\r
- pr->get_lineno(), pr->get_charno(), pr->get_op().c_str() );\r
- exit(1);\r
- case PRED_BINARY_OP:\r
- if(pr->get_op() == "AND"){\r
- if(! eval_pred(i, pr->get_left_pr()) ) return false;\r
- return eval_pred(i, pr->get_right_pr()) ;\r
- }\r
- if(pr->get_op() == "OR"){\r
- if( eval_pred(i, pr->get_left_pr()) ) return true;\r
- return eval_pred(i, pr->get_right_pr()) ;\r
- }\r
- fprintf(stderr,"INTERNAL ERROR in reparse_date::eval_pred, line %d, character %d, unknown binary pred operator %s.\n",\r
- pr->get_lineno(), pr->get_charno(), pr->get_op().c_str() );\r
- exit(1);\r
- case PRED_FUNC:\r
- op_list = pr->get_op_list();\r
- if(op_list[0]->get_operator_type() != SE_PARAM){\r
- fprintf(stderr,"INTERNAL ERROR : ifq parameters are supposed to be of type SE_PARAM, found %s at position 0\n",op_list[0]->get_op().c_str());\r
- exit(1);\r
- }else{\r
- prop=op_list[0]->get_op();\r
- }\r
- if(op_list.size() > 1){\r
- if(op_list[1]->get_operator_type() != SE_PARAM){\r
- fprintf(stderr,"INTERNAL ERROR : ifq parameters are supposed to be of type SE_PARAM, found %s at position 1\n",op_list[0]->get_op().c_str());\r
- exit(1);\r
- }else{\r
- val=op_list[1]->get_op();\r
- }\r
- }\r
-\r
- if(pr->get_op() == "Contains"){\r
- if(op_list.size() != 2){\r
- fprintf(stderr,"INTERNAL ERROR : predicate Contains expects 2 parameters, received %lu\n",op_list.size());\r
- exit(1);\r
- }\r
- return ifaces[i]->eval_Contains(prop,val);\r
- }\r
-\r
- if(pr->get_op() == "Equals"){\r
- if(op_list.size() != 2){\r
- fprintf(stderr,"INTERNAL ERROR : predicate Equals expects 2 parameters, received %lu\n",op_list.size());\r
- exit(1);\r
- }\r
- return ifaces[i]->eval_Equals(prop,val);\r
- }\r
-\r
- if(pr->get_op() == "Exists"){\r
- if(op_list.size() != 1){\r
- fprintf(stderr,"INTERNAL ERROR : predicate Exists expects 1 parameter, received %lu\n",op_list.size());\r
- exit(1);\r
- }\r
- return ifaces[i]->eval_Exists(prop);\r
- }\r
-\r
- fprintf(stderr,"INTERNAL ERROR : Unknown predicate %s in reparse_date::eval_pred.\n",pr->get_op().c_str());\r
- exit(1);\r
-\r
- default:\r
- fprintf(stderr,"INTERNAL ERROR in reparse_date::eval_pred, line %d, character %d, unknown predicate operator type %d\n",\r
- pr->get_lineno(), pr->get_charno(), pr->get_operator_type() );\r
- exit(1);\r
- }\r
-\r
- return(false);\r
-\r
- }\r
-\r
-\r
-///////////////////////////////////////////\r
-/// XML parser callbacks for parsing interface resources\r
-\r
-void startElement(void *userData, const char *name, const char **atts) {\r
- int i;\r
-\r
- resparse_data *rpd = (resparse_data *)userData;\r
- rpd->level.push_back(name);\r
-\r
- if(rpd->level.size() == 1 && rpd->level[0] == "Resources")\r
- rpd->in_Resources = true;\r
-\r
- if(rpd->in_Resources && rpd->level.size() == 2 && rpd->level[1] == "Interface"){\r
-// rpd->new_iface(XML_GetCurrentLineNumber(rpd->parser));\r
- rpd->new_iface(1);\r
- rpd->in_Iface = true;\r
- }\r
-\r
- if(rpd->in_Iface && rpd->level.size() == 3){\r
- rpd->add_property(name, atts);\r
- }\r
-\r
-\r
-// for(i=0;i<rpd->level.size();++i) printf("%s, ",rpd->level[i].c_str());\r
-// printf("\n");\r
-}\r
-\r
-void startElement(void *userData, const char *name, vector<string> &attr_vec, vector<string> &val_vec){\r
- int i;\r
-\r
- resparse_data *rpd = (resparse_data *)userData;\r
- rpd->level.push_back(name);\r
-\r
- if(rpd->level.size() == 1 && rpd->level[0] == "Resources")\r
- rpd->in_Resources = true;\r
-\r
- if(rpd->in_Resources && rpd->level.size() == 2 && rpd->level[1] == "Host"){\r
-// rpd->new_iface(XML_GetCurrentLineNumber(rpd->parser));\r
-\r
- rpd->new_host(flex_res_lineno);\r
- for (int i = 0; i < attr_vec.size(); ++i)\r
- rpd->curr_host->add_property(attr_vec[i].c_str(), val_vec[i].c_str());\r
- rpd->in_Host = true;\r
- }\r
-\r
- if(rpd->in_Host && rpd->level.size() == 3) {\r
- if ( rpd->level[2] == "Interface"){\r
- // rpd->new_iface(XML_GetCurrentLineNumber(rpd->parser));\r
- rpd->new_iface(flex_res_lineno);\r
- for (int i = 0; i < attr_vec.size(); ++i)\r
- rpd->add_property(attr_vec[i].c_str(), val_vec[i].c_str());\r
- rpd->in_Iface = true;\r
- } else {\r
- rpd->curr_host->add_property(name, val_vec);\r
- }\r
- }\r
-\r
- if(rpd->in_Iface && rpd->level.size() == 4){\r
- rpd->add_property(name, val_vec);\r
- }\r
-\r
-\r
-// for(i=0;i<rpd->level.size();++i) printf("%s, ",rpd->level[i].c_str());\r
-// printf("\n");\r
-}\r
-\r
-\r
-void endElement(void *userData, const char *name) {\r
- resparse_data *rpd = (resparse_data *)userData;\r
-\r
- if(rpd->in_Iface && rpd->level.size() == 3){\r
- string err_msg;\r
- int err = rpd->finalize_iface(err_msg);\r
- if(err) fprintf(stderr,"%s\n",err_msg.c_str());\r
- } else if (rpd->in_Host && rpd->level.size() == 2) {\r
- string err_msg;\r
- int err = rpd->finalize_host(err_msg);\r
- if(err) fprintf(stderr,"%s\n",err_msg.c_str());\r
- }\r
-\r
- rpd->level.pop_back();\r
-}\r
-\r
-\r
-// Interface to ifq definition lexer and parser ...\r
-\r
-extern int IfqParserparse(void);\r
-extern FILE *IfqParserin;\r
-extern int IfqParserdebug;\r
-void IfqParser_setfileinput(FILE *f);\r
-void IfqParser_setstringinput(char *s);\r
-\r
-\r
-fta_parse_t *ifq_parse_result;\r
-\r
-int ifq_t::load_ifaces(string fname, bool use_live_hosts_file, bool disributed_mode, string &err){\r
- char buf[1000], errbuf[1000];\r
-// XML_Parser parser = XML_ParserCreate(NULL);\r
-\r
- int done;\r
- int depth = 0;\r
- err="";\r
-\r
- // open the list of failed hosts\r
- set<string> live_hosts;\r
- if (use_live_hosts_file) {\r
- FILE* live_hosts_file = fopen("live_hosts.txt", "r");\r
- if (!live_hosts_file) {\r
- err="Error, can't open live_hosts.txt, error is ";\r
- err+=strerror(errno); err+="\n";\r
- return(1);\r
- }\r
-\r
- while(fgets(buf, 1000, live_hosts_file)) {\r
- char* host = strtok(buf, " \t\n\r"); // strip the line\r
- if (host)\r
- live_hosts.insert(host);\r
- }\r
-\r
- fclose(live_hosts_file);\r
- }\r
-\r
-\r
-\r
-// IfqParserdebug = 1;\r
-\r
- FILE *resfile = fopen(fname.c_str(),"r");\r
- if(resfile == NULL){\r
- err="Error, can't open "+fname+", error is ";\r
- err+=strerror(errno); err+="\n";\r
- return(1);\r
- }\r
-\r
-// rpd = new resparse_data(parser);\r
- rpd = new resparse_data(use_live_hosts_file, &live_hosts, disributed_mode);\r
- rpd_ptr = rpd;\r
-\r
- ResParser_setfileinput(resfile);\r
- if(ResParserparse()){\r
- err = "ERROR, interface query parse failed.\n";\r
- return(1);\r
- }\r
-\r
-/*\r
- XML_SetUserData(parser, rpd);\r
- XML_SetElementHandler(parser, startElement, endElement);\r
- do {\r
- size_t len = fread(buf, 1, sizeof(buf), resfile);\r
- done = len < sizeof(buf);\r
- if (!XML_Parse(parser, buf, len, done)) {\r
- sprintf(errbuf,\r
- "%s at line %d\n",\r
- XML_ErrorString(XML_GetErrorCode(parser)),\r
- XML_GetCurrentLineNumber(parser));\r
- err=errbuf;\r
- return 1;\r
- }\r
- } while (!done);\r
- XML_ParserFree(parser);\r
-\r
- if(rpd->failed()){\r
- err = "Interface resource parse failed, exiting.\n";\r
- }\r
-*/\r
-\r
- fclose(resfile);\r
-\r
- return(0);\r
-\r
-}\r
-\r
-int ifq_t::load_ifqs(string fname, string &err){\r
- char err_buf[1000];\r
- err="";\r
-\r
- FILE *qfile = fopen(fname.c_str(),"r");\r
- if(qfile == NULL){\r
- sprintf(err_buf, "ERROR, can't open %s, error is %s\n",fname.c_str(),strerror(errno));\r
- err=err_buf;\r
- return(1);\r
- }\r
-\r
- ifq_parse_result = new fta_parse_t();\r
- IfqParser_setfileinput(qfile);\r
- if(IfqParserparse()){\r
- err = "ERROR, interface query parse failed.\n";\r
- return(1);\r
- }\r
-\r
- vector<table_exp_t *> ifqlist = ifq_parse_result->parse_tree_list->qlist;\r
- int i;\r
- bool dup = false;\r
- for(i=0;i<ifqlist.size();++i){\r
- string nm = ifqlist[i]->nmap["name"];\r
- if(ifq_map.count(nm)){\r
- err += "ERROR, Duplicate interface query "+nm+"\n";\r
- dup = true;\r
- }\r
- ifq_map[nm] = ifqlist[i]->wh;\r
- }\r
-\r
-\r
- if(dup) return(1);\r
- return(0);\r
-}\r
-\r
-\r
-vector<pair<string,string> > ifq_t::eval(string qname, int &err_no){\r
- vector<pair<string,string> > retval;\r
- err_no = 0;\r
-\r
- if(ifq_map.count(qname) == 0){\r
- err_no = 1;\r
- return retval;\r
- }\r
- if(rpd->failed()){\r
- err_no = 2;\r
- return retval;\r
- }\r
-\r
- return rpd->find_ifaces(ifq_map[qname]);\r
-\r
-}\r
-\r
-vector<string> ifq_t::get_iface_vals(string host_name, string basic_if_name, string property, int &err_no, string &err_str){\r
- vector<string> retval;\r
- err_no = 0;\r
-\r
- char *cdat = strdup(basic_if_name.c_str());\r
- int pos;\r
- string virtual_iface = "0";\r
- string iface_name = basic_if_name;\r
- for(pos=strlen(cdat)-1;pos>=0 && isdigit(cdat[pos]);--pos);\r
- if(pos>0 && cdat[pos] == 'X' && pos<=strlen(cdat)-2){\r
- cdat[pos] = '\0';\r
- virtual_iface = cdat+pos+1;\r
- iface_name = cdat;\r
- }\r
- free(cdat);\r
-\r
- if(property == "virtual_interface_id"){\r
- retval.push_back(virtual_iface);\r
- return retval;\r
- }\r
-\r
-\r
- if(rpd->failed()){\r
- err_no = 1; err_str = "interface resource parse failed.";\r
- return retval;\r
- }\r
-\r
- vector<int> ifi = rpd->get_ifaces_by_Name(host_name, iface_name);\r
- if(ifi.size() == 0){\r
- err_no = 1; err_str="interface not found.";\r
- return retval;\r
- }\r
- if(ifi.size()>1){\r
- err_no = 1; err_str="multiple interfaces found.";\r
- return retval;\r
- }\r
-\r
- return rpd->get_property(ifi[0], property);\r
-\r
-}\r
-\r
-vector<string> ifq_t::get_iface_properties(string host_name, string basic_if_name, int &err_no, string &err_str){\r
- vector<string> retval;\r
- err_no = 0;\r
-\r
- char *cdat = strdup(basic_if_name.c_str());\r
- int pos;\r
- string virtual_iface = "0";\r
- string iface_name = basic_if_name;\r
- for(pos=strlen(cdat)-1;pos>=0 && isdigit(cdat[pos]);--pos);\r
- if(pos>0 && cdat[pos] == 'X' && pos<=strlen(cdat)-2){\r
- cdat[pos] = '\0';\r
- virtual_iface = cdat+pos+1;\r
- iface_name = cdat;\r
- }\r
- free(cdat);\r
-\r
- if(rpd->failed()){\r
- err_no = 1; err_str = "interface resource parse failed.";\r
- return retval;\r
- }\r
-\r
- vector<int> ifi = rpd->get_ifaces_by_Name(host_name, iface_name);\r
- if(ifi.size() == 0){\r
- err_no = 1; err_str="interface not found.";\r
- return retval;\r
- }\r
- if(ifi.size()>1){\r
- err_no = 1; err_str="multiple interfaces found.";\r
- return retval;\r
- }\r
-\r
- return rpd->get_properties(ifi[0]);\r
-\r
-}\r
+/* ------------------------------------------------
+Copyright 2014 AT&T Intellectual Property
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ------------------------------------------- */
+#include "iface_q.h"
+#include<errno.h>
+#include <unistd.h>
+#include <algorithm>
+#include <cctype>
+
+
+using namespace std;
+
+extern string hostname; // namne of the current host
+
+static string int_to_string(int i){
+ string ret;
+ char tmpstr[100];
+ sprintf(tmpstr,"%d",i);
+ ret=tmpstr;
+ return(ret);
+}
+
+
+// Interface for the res parser
+extern int ResParserparse(void);
+extern FILE *ResParserin;
+extern int ResParserdebug;
+void ResParser_setfileinput(FILE *f);
+void ResParser_setstringinput(char *s);
+extern int flex_res_lineno;
+
+resparse_data *rpd_ptr;
+vector<string> res_val_vec, res_attr_vec;
+string res_a, res_v;
+
+///////////////////////////////////////
+/// iface_t methods
+
+ void iface_t::add_property(const char *name, const char *att){
+ string nm(name);
+ std::transform(nm.begin(), nm.end(), nm.begin(), (int(*)(int))std::tolower);
+ vals[nm].push_back(att);
+ }
+
+ void iface_t::add_property(const char *name, const char **atts){
+ string val = "";
+ string nm = name;
+ std::transform(nm.begin(), nm.end(), nm.begin(), (int(*)(int))std::tolower);
+ if(atts[0]) val = atts[1];
+
+ vals[nm].push_back(val);
+ }
+
+ void iface_t::add_property(const char *name, vector<string> &val_vec){
+ string val = "";
+ string nm = name;
+ std::transform(nm.begin(), nm.end(), nm.begin(), (int(*)(int))std::tolower);
+ if(val_vec.size()) val = val_vec[0];
+
+ vals[nm].push_back(val);
+ }
+
+// Add in more consistency checks
+ int iface_t::finalize(string &errs){
+ string tag ="ERROR in interface starting at line "+int_to_string(lineno)+", ";
+ string e;
+ if(vals.count("name") == 0){
+ e += "Name not specified. ";
+ }else{
+ if(vals["name"].size() > 1){
+ e+="More than one name specified. ";
+ }
+ }
+
+ if(e != ""){
+ errs += tag + e + "\n";
+ return(1);
+ }
+ return(0);
+ }
+
+ string iface_t::to_string(){
+ int i;
+ string ret = "Interface "+vals["name"][0]+":\n";
+ map<string, vector<string> >::iterator svmi;
+ for(svmi=vals.begin();svmi!=vals.end();++svmi){
+ ret += "\t"+(*svmi).first + " : ";
+ for(i=0;i<((*svmi).second).size();++i){
+ if(i>0) ret+=", ";
+ ret += (*svmi).second[i];
+ }
+ ret += "\n";
+ }
+
+ return ret;
+ }
+
+ string iface_t::get_name(){
+ if(vals.count("name") == 0) return (string)"";
+ return (vals["name"])[0];
+ }
+
+ string iface_t::get_host(){
+ if(vals.count("host") == 0) return (string)"";
+ return (vals["host"])[0];
+ }
+
+ bool iface_t::has_multiple_schemas(){
+ if(vals.count("interfacetype") == 0) return true;
+ string iface_type = vals["interfacetype"][0];
+ if(iface_type=="GDAT" || iface_type=="CSV")
+ return false;
+ return true;
+ }
+
+
+ bool iface_t::eval_Contains(string prop, string val){
+ // convert to lowercase
+ std::transform(prop.begin(), prop.end(), prop.begin(), (int(*)(int))std::tolower);
+
+ if(vals.count(prop) == 0) return false;
+ int i;
+ for(i=0;i<vals[prop].size();++i){
+ if((vals[prop])[i] == val) return true;
+ }
+ return false;
+ }
+
+ bool iface_t::eval_Equals(string prop, string val){
+ // convert to lowercase
+ std::transform(prop.begin(), prop.end(), prop.begin(), (int(*)(int))std::tolower);
+ if(vals.count(prop) == 0) return false;
+ if(vals[prop].size() != 1) return false;
+ int i;
+ for(i=0;i<vals[prop].size();++i){
+ if((vals[prop])[i] == val) return true;
+ }
+ return false;
+ }
+
+ bool iface_t::eval_Exists(string prop){
+ // convert to lowercase
+ std::transform(prop.begin(), prop.end(), prop.begin(), (int(*)(int))std::tolower);
+ if(vals.count(prop) == 0) return false;
+ return true;
+ }
+
+
+///////////////////////////////////////
+/// gs_host_t methods
+
+ void gs_host_t::add_property(const char *name, const char *att){
+ string nm(name);
+ std::transform(nm.begin(), nm.end(), nm.begin(), (int(*)(int))std::tolower);
+ vals[nm].push_back(att);
+ }
+
+ void gs_host_t::add_property(const char *name, vector<string> &val_vec){
+ string val = "";
+ string nm = name;
+ std::transform(nm.begin(), nm.end(), nm.begin(), (int(*)(int))std::tolower);
+ if(val_vec.size()) val = val_vec[0];
+
+ vals[nm].push_back(val);
+ }
+
+ int gs_host_t::finalize(string &errs){
+ string tag ="ERROR in host starting at line "+int_to_string(lineno)+", ";
+ string e;
+ if(vals.count("name") == 0){
+ e += "Name not specified. ";
+ }else{
+ if(vals["name"].size() > 1){
+ e+="More than one name specified. ";
+ }
+ }
+
+ if(e != ""){
+ errs += tag + e + "\n";
+ return(1);
+ }
+ return(0);
+ }
+
+
+/////////////////////////////////////////////////////////////////
+/// reparse_data methods
+
+ int resparse_data::finalize_iface(string &errs){
+ int ret = curr_iface->finalize(errs);
+ if(ret) {
+ delete curr_iface;
+ failure = true;
+ }else{
+ curr_host->add_interface(curr_iface);
+ }
+ return ret;
+ }
+
+
+ int resparse_data::finalize_host(string &errs){
+ int ret = curr_host->finalize(errs);
+ if(ret) {
+ delete curr_host;
+ failure = true;
+ }else{
+
+ string host = curr_host->vals["name"][0];
+ // in non-distributed case we will ignore all other hosts
+ if (!distributed_mode) {
+ char buf[1000];
+ if (host != hostname)
+ return ret;
+ }
+ // we need to exclude failed hosts
+ if (!use_live_hosts_file || live_hosts->count(hostname)) {
+ hosts.push_back(curr_host);
+
+ // push the host name to every interface
+ curr_host->propagate_name();
+
+ // add all interfaces into interface list
+ for(int i=0;i<curr_host->ifaces.size();i++)
+ ifaces.push_back(curr_host->ifaces[i]);
+ }
+ }
+ return ret;
+ }
+
+ string resparse_data::to_string(){
+ string ret;
+ int i;
+ for(i=0;i<ifaces.size();i++)
+ ret += ifaces[i]->to_string();
+ return ret;
+ }
+
+ vector<pair<string,string> > resparse_data::find_ifaces(predicate_t *pr){
+ int i;
+ vector<pair<string,string> > ret;
+ for(i=0;i<ifaces.size();++i){
+ if(this->eval_pred(i,pr)){
+ pair<string,string> p(ifaces[i]->get_host(), ifaces[i]->get_name());
+ ret.push_back(p);
+ }
+ }
+ return ret;
+ }
+
+
+ vector<int> resparse_data::get_ifaces_by_Name(std::string host_name, std::string if_name){
+ int i;
+ vector<int> ret;
+ for(i=0;i<ifaces.size();++i){
+ if(ifaces[i]->get_host() == host_name && ifaces[i]->get_name() == if_name)
+ ret.push_back(i);
+
+ }
+ return ret;
+ }
+
+
+ bool resparse_data::eval_pred(int i, predicate_t *pr){
+ vector<scalarexp_t *> op_list;
+ string prop, val;
+
+ switch(pr->get_operator_type()){
+ case PRED_IN:
+ fprintf(stderr,"INTERNAL ERROR in reparse_date::eval_pred, line %d, character %d, IN not supported. %d\n",
+ pr->get_lineno(), pr->get_charno(), pr->get_operator_type() );
+ exit(1);
+ case PRED_COMPARE:
+ fprintf(stderr,"INTERNAL ERROR in reparse_date::eval_pred, line %d, character %d, comparison predicate not supported. %d\n",
+ pr->get_lineno(), pr->get_charno(), pr->get_operator_type() );
+ exit(1);
+ case PRED_UNARY_OP:
+ if(pr->get_op() == "NOT")
+ return(! eval_pred(i, pr->get_left_pr()) );
+ fprintf(stderr,"INTERNAL ERROR in reparse_date::eval_pred, line %d, character %d, unknown unary pred operator %s.\n",
+ pr->get_lineno(), pr->get_charno(), pr->get_op().c_str() );
+ exit(1);
+ case PRED_BINARY_OP:
+ if(pr->get_op() == "AND"){
+ if(! eval_pred(i, pr->get_left_pr()) ) return false;
+ return eval_pred(i, pr->get_right_pr()) ;
+ }
+ if(pr->get_op() == "OR"){
+ if( eval_pred(i, pr->get_left_pr()) ) return true;
+ return eval_pred(i, pr->get_right_pr()) ;
+ }
+ fprintf(stderr,"INTERNAL ERROR in reparse_date::eval_pred, line %d, character %d, unknown binary pred operator %s.\n",
+ pr->get_lineno(), pr->get_charno(), pr->get_op().c_str() );
+ exit(1);
+ case PRED_FUNC:
+ op_list = pr->get_op_list();
+ if(op_list[0]->get_operator_type() != SE_PARAM){
+ fprintf(stderr,"INTERNAL ERROR : ifq parameters are supposed to be of type SE_PARAM, found %s at position 0\n",op_list[0]->get_op().c_str());
+ exit(1);
+ }else{
+ prop=op_list[0]->get_op();
+ }
+ if(op_list.size() > 1){
+ if(op_list[1]->get_operator_type() != SE_PARAM){
+ fprintf(stderr,"INTERNAL ERROR : ifq parameters are supposed to be of type SE_PARAM, found %s at position 1\n",op_list[0]->get_op().c_str());
+ exit(1);
+ }else{
+ val=op_list[1]->get_op();
+ }
+ }
+
+ if(pr->get_op() == "Contains"){
+ if(op_list.size() != 2){
+ fprintf(stderr,"INTERNAL ERROR : predicate Contains expects 2 parameters, received %lu\n",op_list.size());
+ exit(1);
+ }
+ return ifaces[i]->eval_Contains(prop,val);
+ }
+
+ if(pr->get_op() == "Equals"){
+ if(op_list.size() != 2){
+ fprintf(stderr,"INTERNAL ERROR : predicate Equals expects 2 parameters, received %lu\n",op_list.size());
+ exit(1);
+ }
+ return ifaces[i]->eval_Equals(prop,val);
+ }
+
+ if(pr->get_op() == "Exists"){
+ if(op_list.size() != 1){
+ fprintf(stderr,"INTERNAL ERROR : predicate Exists expects 1 parameter, received %lu\n",op_list.size());
+ exit(1);
+ }
+ return ifaces[i]->eval_Exists(prop);
+ }
+
+ fprintf(stderr,"INTERNAL ERROR : Unknown predicate %s in reparse_date::eval_pred.\n",pr->get_op().c_str());
+ exit(1);
+
+ default:
+ fprintf(stderr,"INTERNAL ERROR in reparse_date::eval_pred, line %d, character %d, unknown predicate operator type %d\n",
+ pr->get_lineno(), pr->get_charno(), pr->get_operator_type() );
+ exit(1);
+ }
+
+ return(false);
+
+ }
+
+
+///////////////////////////////////////////
+/// XML parser callbacks for parsing interface resources
+
+void startElement(void *userData, const char *name, const char **atts) {
+ int i;
+
+ resparse_data *rpd = (resparse_data *)userData;
+ rpd->level.push_back(name);
+
+ if(rpd->level.size() == 1 && rpd->level[0] == "Resources")
+ rpd->in_Resources = true;
+
+ if(rpd->in_Resources && rpd->level.size() == 2 && rpd->level[1] == "Interface"){
+// rpd->new_iface(XML_GetCurrentLineNumber(rpd->parser));
+ rpd->new_iface(1);
+ rpd->in_Iface = true;
+ }
+
+ if(rpd->in_Iface && rpd->level.size() == 3){
+ rpd->add_property(name, atts);
+ }
+
+
+// for(i=0;i<rpd->level.size();++i) printf("%s, ",rpd->level[i].c_str());
+// printf("\n");
+}
+
+void startElement(void *userData, const char *name, vector<string> &attr_vec, vector<string> &val_vec){
+ int i;
+
+ resparse_data *rpd = (resparse_data *)userData;
+ rpd->level.push_back(name);
+
+ if(rpd->level.size() == 1 && rpd->level[0] == "Resources")
+ rpd->in_Resources = true;
+
+ if(rpd->in_Resources && rpd->level.size() == 2 && rpd->level[1] == "Host"){
+// rpd->new_iface(XML_GetCurrentLineNumber(rpd->parser));
+
+ rpd->new_host(flex_res_lineno);
+ for (int i = 0; i < attr_vec.size(); ++i)
+ rpd->curr_host->add_property(attr_vec[i].c_str(), val_vec[i].c_str());
+ rpd->in_Host = true;
+ }
+
+ if(rpd->in_Host && rpd->level.size() == 3) {
+ if ( rpd->level[2] == "Interface"){
+ // rpd->new_iface(XML_GetCurrentLineNumber(rpd->parser));
+ rpd->new_iface(flex_res_lineno);
+ for (int i = 0; i < attr_vec.size(); ++i)
+ rpd->add_property(attr_vec[i].c_str(), val_vec[i].c_str());
+ rpd->in_Iface = true;
+ } else {
+ rpd->curr_host->add_property(name, val_vec);
+ }
+ }
+
+ if(rpd->in_Iface && rpd->level.size() == 4){
+ rpd->add_property(name, val_vec);
+ }
+
+
+// for(i=0;i<rpd->level.size();++i) printf("%s, ",rpd->level[i].c_str());
+// printf("\n");
+}
+
+
+void endElement(void *userData, const char *name) {
+ resparse_data *rpd = (resparse_data *)userData;
+
+ if(rpd->in_Iface && rpd->level.size() == 3){
+ string err_msg;
+ int err = rpd->finalize_iface(err_msg);
+ if(err) fprintf(stderr,"%s\n",err_msg.c_str());
+ } else if (rpd->in_Host && rpd->level.size() == 2) {
+ string err_msg;
+ int err = rpd->finalize_host(err_msg);
+ if(err) fprintf(stderr,"%s\n",err_msg.c_str());
+ }
+
+ rpd->level.pop_back();
+}
+
+
+// Interface to ifq definition lexer and parser ...
+
+extern int IfqParserparse(void);
+extern FILE *IfqParserin;
+extern int IfqParserdebug;
+void IfqParser_setfileinput(FILE *f);
+void IfqParser_setstringinput(char *s);
+
+
+fta_parse_t *ifq_parse_result;
+
+int ifq_t::load_ifaces(string fname, bool use_live_hosts_file, bool disributed_mode, string &err){
+ char buf[1000], errbuf[1000];
+// XML_Parser parser = XML_ParserCreate(NULL);
+
+ int done;
+ int depth = 0;
+ err="";
+
+ // open the list of failed hosts
+ set<string> live_hosts;
+ if (use_live_hosts_file) {
+ FILE* live_hosts_file = fopen("live_hosts.txt", "r");
+ if (!live_hosts_file) {
+ err="Error, can't open live_hosts.txt, error is ";
+ err+=strerror(errno); err+="\n";
+ return(1);
+ }
+
+ while(fgets(buf, 1000, live_hosts_file)) {
+ char* host = strtok(buf, " \t\n\r"); // strip the line
+ if (host)
+ live_hosts.insert(host);
+ }
+
+ fclose(live_hosts_file);
+ }
+
+
+
+// IfqParserdebug = 1;
+
+ FILE *resfile = fopen(fname.c_str(),"r");
+ if(resfile == NULL){
+ err="Error, can't open "+fname+", error is ";
+ err+=strerror(errno); err+="\n";
+ return(1);
+ }
+
+// rpd = new resparse_data(parser);
+ rpd = new resparse_data(use_live_hosts_file, &live_hosts, disributed_mode);
+ rpd_ptr = rpd;
+
+ ResParser_setfileinput(resfile);
+ if(ResParserparse()){
+ err = "ERROR, interface query parse failed.\n";
+ return(1);
+ }
+
+/*
+ XML_SetUserData(parser, rpd);
+ XML_SetElementHandler(parser, startElement, endElement);
+ do {
+ size_t len = fread(buf, 1, sizeof(buf), resfile);
+ done = len < sizeof(buf);
+ if (!XML_Parse(parser, buf, len, done)) {
+ sprintf(errbuf,
+ "%s at line %d\n",
+ XML_ErrorString(XML_GetErrorCode(parser)),
+ XML_GetCurrentLineNumber(parser));
+ err=errbuf;
+ return 1;
+ }
+ } while (!done);
+ XML_ParserFree(parser);
+
+ if(rpd->failed()){
+ err = "Interface resource parse failed, exiting.\n";
+ }
+*/
+
+ fclose(resfile);
+
+ return(0);
+
+}
+
+int ifq_t::load_ifqs(string fname, string &err){
+ char err_buf[1000];
+ err="";
+
+ FILE *qfile = fopen(fname.c_str(),"r");
+ if(qfile == NULL){
+ sprintf(err_buf, "ERROR, can't open %s, error is %s\n",fname.c_str(),strerror(errno));
+ err=err_buf;
+ return(1);
+ }
+
+ ifq_parse_result = new fta_parse_t();
+ IfqParser_setfileinput(qfile);
+ if(IfqParserparse()){
+ err = "ERROR, interface query parse failed.\n";
+ return(1);
+ }
+
+ vector<table_exp_t *> ifqlist = ifq_parse_result->parse_tree_list->qlist;
+ int i;
+ bool dup = false;
+ for(i=0;i<ifqlist.size();++i){
+ string nm = ifqlist[i]->nmap["name"];
+ if(ifq_map.count(nm)){
+ err += "ERROR, Duplicate interface query "+nm+"\n";
+ dup = true;
+ }
+ ifq_map[nm] = ifqlist[i]->wh;
+ }
+
+
+ if(dup) return(1);
+ return(0);
+}
+
+
+vector<pair<string,string> > ifq_t::eval(string qname, int &err_no){
+ vector<pair<string,string> > retval;
+ err_no = 0;
+
+ if(ifq_map.count(qname) == 0){
+ err_no = 1;
+ return retval;
+ }
+ if(rpd->failed()){
+ err_no = 2;
+ return retval;
+ }
+
+ return rpd->find_ifaces(ifq_map[qname]);
+
+}
+
+vector<string> ifq_t::get_iface_vals(string host_name, string basic_if_name, string property, int &err_no, string &err_str){
+ vector<string> retval;
+ err_no = 0;
+
+ char *cdat = strdup(basic_if_name.c_str());
+ int pos;
+ string virtual_iface = "0";
+ string iface_name = basic_if_name;
+ for(pos=strlen(cdat)-1;pos>=0 && isdigit(cdat[pos]);--pos);
+ if(pos>0 && cdat[pos] == 'X' && pos<=strlen(cdat)-2){
+ cdat[pos] = '\0';
+ virtual_iface = cdat+pos+1;
+ iface_name = cdat;
+ }
+ free(cdat);
+
+ if(property == "virtual_interface_id"){
+ retval.push_back(virtual_iface);
+ return retval;
+ }
+
+
+ if(rpd->failed()){
+ err_no = 1; err_str = "interface resource parse failed.";
+ return retval;
+ }
+
+ vector<int> ifi = rpd->get_ifaces_by_Name(host_name, iface_name);
+ if(ifi.size() == 0){
+ err_no = 1; err_str="interface not found.";
+ return retval;
+ }
+ if(ifi.size()>1){
+ err_no = 1; err_str="multiple interfaces found.";
+ return retval;
+ }
+
+ return rpd->get_property(ifi[0], property);
+
+}
+
+vector<string> ifq_t::get_iface_properties(string host_name, string basic_if_name, int &err_no, string &err_str){
+ vector<string> retval;
+ err_no = 0;
+
+ char *cdat = strdup(basic_if_name.c_str());
+ int pos;
+ string virtual_iface = "0";
+ string iface_name = basic_if_name;
+ for(pos=strlen(cdat)-1;pos>=0 && isdigit(cdat[pos]);--pos);
+ if(pos>0 && cdat[pos] == 'X' && pos<=strlen(cdat)-2){
+ cdat[pos] = '\0';
+ virtual_iface = cdat+pos+1;
+ iface_name = cdat;
+ }
+ free(cdat);
+
+ if(rpd->failed()){
+ err_no = 1; err_str = "interface resource parse failed.";
+ return retval;
+ }
+
+ vector<int> ifi = rpd->get_ifaces_by_Name(host_name, iface_name);
+ if(ifi.size() == 0){
+ err_no = 1; err_str="interface not found.";
+ return retval;
+ }
+ if(ifi.size()>1){
+ err_no = 1; err_str="multiple interfaces found.";
+ return retval;
+ }
+
+ return rpd->get_properties(ifi[0]);
+
+}
+
+
+iface_t *ifq_t::get_interface(string host_name, string basic_if_name, int &err_no, string &err_str){
+ iface_t *retval = NULL;
+ err_no = 0;
+
+ char *cdat = strdup(basic_if_name.c_str());
+ int pos;
+ string virtual_iface = "0";
+ string iface_name = basic_if_name;
+ for(pos=strlen(cdat)-1;pos>=0 && isdigit(cdat[pos]);--pos);
+ if(pos>0 && cdat[pos] == 'X' && pos<=strlen(cdat)-2){
+ cdat[pos] = '\0';
+ virtual_iface = cdat+pos+1;
+ iface_name = cdat;
+ }
+ free(cdat);
+
+ if(rpd->failed()){
+ err_no = 1; err_str = "interface resource parse failed.";
+ return retval;
+ }
+
+ vector<int> ifi = rpd->get_ifaces_by_Name(host_name, iface_name);
+ if(ifi.size() == 0){
+ err_no = 1; err_str="interface not found.";
+ return retval;
+ }
+ if(ifi.size()>1){
+ err_no = 1; err_str="multiple interfaces found.";
+ return retval;
+ }
+
+ return rpd->get_interface(ifi[0]);
+
+}