/*************************************************************************** * Copyright (C) 2005 by Christof Donat * * cdonat@gmx.de * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include #include #include #include "cmdlineparser.h" #include "logger.h" #include #include namespace commandline { using std::cout; using std::cin; using std::flush; using std::ifstream; using std::ostringstream; using boost::lexical_cast; using boost::bad_lexical_cast; using boost::shared_ptr; using boost::scoped_ptr; using boost::starts_with; using boost::erase_first; // dynamic cast needs this vector callParameter::parseDisplayspec() { vector rval; boost::regex pattern("\\$\\{([^\\}]*)\\}"); boost::sregex_iterator end; for(boost::sregex_iterator i(this->m_display.begin(),this->m_display.end(),pattern); i != end; i++ ) rval.insert(rval.end(),(*i)[1]); Logger::log(Logger::DEBUG,"have parsed displayspec Parameter '"+this->m_display+"'"); return rval; } string callParameter::evalDisplay(const map &values) { string rval = this->m_display; string::size_type pos; for( map::const_iterator i = values.begin(); i != values.end(); i++ ) { string pattstring = "${"+i->first+"}"; while( (pos = rval.find(pattstring,0)) != string::npos ) rval.replace(pos,pattstring.length(),i->second); } while( (pos = rval.find("\\n",0)) != string::npos ) rval.replace(pos,2,"\n"); while( (pos = rval.find("\\t",0)) != string::npos ) rval.replace(pos,2,"\t"); while( (pos = rval.find("\\r",0)) != string::npos ) rval.replace(pos,2,"\r"); Logger::log(Logger::DEBUG,"have evaluated displayspec Parameter '"+this->m_display+"': '"+rval+"'"); return rval; } string setParameter::toXML(string &username, shared_ptr< ::ConfigFileParser > cfgfile) { string rpccall = ""; rpccall += "property"+m_property+""; rpccall += "value"+m_value+""; rpccall += ""; return rpccall; } string whereParameter::toXML(string &username, shared_ptr< ::ConfigFileParser > cfgfile) { string rpccall = ""; rpccall += "property"+m_property+""; rpccall += "value"+m_pattern+""; rpccall += ""; return rpccall; } string orderParameter::toXML(string &username, shared_ptr< ::ConfigFileParser > cfgfile) { string rpccall = ""; rpccall += "property"+m_property+""; rpccall += "ascending"; rpccall += string((m_ascending?"1":"0"))+""; rpccall += ""; return rpccall; } string callParameter::toXML(string &username, shared_ptr< ::ConfigFileParser > cfgfile) { string rpccall = ""; rpccall += ""; rpccall += "module"; rpccall += ""+m_module+""; rpccall += ""; rpccall += ""; rpccall += "function"; rpccall += ""+m_function+""; rpccall += ""; if( m_force ) { rpccall += ""; rpccall += "force"; rpccall += "1"; rpccall += ""; } if( m_ignoreerror ) { rpccall += ""; rpccall += "ignoreerror"; rpccall += "1"; rpccall += ""; } // read vector reads = parseDisplayspec(); if(reads.size()) { rpccall += ""; rpccall += "read"; rpccall += ""; for(vector::iterator j = reads.begin(); j != reads.end(); j++ ) rpccall += ""+(*j)+""; rpccall += ""; rpccall += ""; } if( m_where.size() ) { rpccall += ""; rpccall += "where"; rpccall += ""; for(vector >::iterator j = m_where.begin(); j != m_where.end(); j++ ) rpccall += ""+((*j)->toXML(username,cfgfile))+""; rpccall += ""; rpccall += ""; } if( m_set.size() ) { rpccall += ""; rpccall += "set"; rpccall += ""; for(vector >::iterator j = m_set.begin(); j != m_set.end(); j++ ) rpccall += ""+((*j)->toXML(username,cfgfile))+""; rpccall += ""; rpccall += ""; } if( m_order.size() ) { rpccall += ""; rpccall += "order"; rpccall += ""; for(vector >::iterator j = m_order.begin(); j != m_order.end(); j++ ) rpccall += ""+((*j)->toXML(username,cfgfile))+""; rpccall += ""; rpccall += ""; } if( m_objects.size() ) { rpccall += ""; rpccall += "objectid"; rpccall += ""; for(vector::iterator j = m_objects.begin(); j != m_objects.end(); j++ ) rpccall += ""+(*j)+""; rpccall += ""; rpccall += ""; } if( m_unset.size() ) { rpccall += ""; rpccall += "unset"; rpccall += ""; for(vector::iterator j = m_unset.begin(); j != m_unset.end(); j++ ) rpccall += "property"+(*j)+""; rpccall += ""; rpccall += ""; } rpccall += ""; return rpccall; } parsedParameters::parsedParameters(): m_error(NOERROR), m_user(""), m_ticket(""), m_defaultDisplay(""), m_addConfigFile(""), m_test(false), m_ignoreerrors(false) {} string parsedParameters::toXML(string &username, shared_ptr< ::ConfigFileParser > cfgfile) { // begin method call string rpccall = "hsadmin.transaction"; // ticket rpccall += ""; if( this->m_ticket != "" ) { string ticket; ifstream file(this->m_ticket.c_str()); if( ! file ) { string msg = Logger::getMessageFormatString(Logger::CouldNotOpenFile); boost::format fmt(msg); fmt % this->m_ticket; Logger::log(Logger::FATAL,fmt.str()); exit(-1); } char ch; while(file.get(ch)) ticket += ch; boost::regex findticket(".*\\n---\\n"); ticket = boost::regex_replace(ticket,findticket,""); if( ticket[ticket.size()-1] == '\0' ) ticket = ticket.substr(0,ticket.size()-2); rpccall += ticket; } else { rpccall += cfgfile->getTicket(username); } Logger::log(Logger::DEBUG,"have read ticket"); rpccall += ""; // global Parameters rpccall += ""; if( this->m_test ) rpccall += "test1"; rpccall += ""; // calls Array rpccall += ""; for( vector >::iterator c = m_call.begin(); c != m_call.end(); c++ ) rpccall += ""+((*c)->toXML(username,cfgfile))+""; rpccall += ""; rpccall += "\n"; return rpccall; } // specific Parser for --runas-Option bool VerbosityOption::parseThis(vector& options, shared_ptr result) { bool rval = false; if( starts_with(options[0], "-v") ) { if( options[1] == "none" || options[1] == "normal" || options[1] == "high" || options[1] == "debug" || options[1] == "debugXML" || options[1] == "debugAll" ) { if( rval = this->handle(options[1], result) ) { if( options[0] == "-v" ) options.erase(options.begin(),options.begin()+2); else { erase_first(options[0], "v"); options.erase(options.begin()+1); } } } else { string p; if( rval = this->handle(p, result) ) { if( options[0] == "-v" ) options.erase(options.begin()); else erase_first(options[0], "v"); } } } if( starts_with(options[0], "--verbosity=") ) { string p = options[0].substr(12); if( rval = this->handle(p, result) ) options.erase(options.begin()); } return rval; } // constuctors TestOption::TestOption() { m_longName = "test"; m_shortName = "t"; } IgnoreErrorOption::IgnoreErrorOption() { m_longName = "ignoreerror"; m_shortName = "e"; } IgnoreErrorsOption::IgnoreErrorsOption() { m_longName = "ignoreerrors"; m_shortName = "E"; } VerbosityOption::VerbosityOption() { m_longName = "verbosity"; m_shortName = "v"; m_parameterSeparator = "="; } RunAsOption::RunAsOption() { m_longName = "runas"; m_shortName = "r"; m_parameterSeparator = "="; } TicketOption::TicketOption() { m_longName = "ticket"; m_shortName = "T"; m_parameterSeparator = "="; } ConfigOption::ConfigOption() { m_longName = "config"; m_shortName = "C"; m_parameterSeparator = "="; } ForceOption::ForceOption() { m_longName = "force"; } GlobalsOption::GlobalsOption() { m_longName = "globals"; m_shortName = "l"; } WhereOption::WhereOption() { m_longName = "where"; m_shortName = "w"; m_parameterSeparator = ":"; } OnlyOption::OnlyOption() { m_longName = "only"; m_shortName = "W"; m_parameterSeparator = ":"; } SetOption::SetOption() { m_longName = "set"; m_shortName = "s"; m_parameterSeparator = ":"; } SetAllOption::SetAllOption() { m_longName = "setall"; m_shortName = "S"; m_parameterSeparator = ":"; } InfileOption::InfileOption() { m_longName = "infile"; m_shortName = "f"; m_parameterSeparator = ":"; } OrderOption::OrderOption() { m_longName = "order"; m_shortName = "o"; m_parameterSeparator = ":"; } GlobalOrderOption::GlobalOrderOption() { m_longName = "global-order"; m_shortName = "O"; m_parameterSeparator = ":"; } InputOption::InputOption() { m_longName = "input"; m_shortName = "i"; m_parameterSeparator = ":"; } PassInputOption::PassInputOption() { m_longName = "passinput"; m_shortName = "p"; m_parameterSeparator = ":"; } DisplayOption::DisplayOption() { m_longName = "display"; m_shortName = "d"; m_parameterSeparator = ":"; } DefaultDisplayOption::DefaultDisplayOption() { m_longName = "default-display"; m_shortName = "D"; m_parameterSeparator = ":"; } CallOption::CallOption() { m_longName = "call"; m_shortName = "c"; m_parameterSeparator = ":"; } UnsetOption::UnsetOption() { m_longName = "unset"; m_shortName = "u"; m_parameterSeparator = ":"; } UnsetAllOption::UnsetAllOption() { m_longName = "unsetall"; m_shortName = "U"; m_parameterSeparator = ":"; } ObjectID::ObjectID() { }; // handle functions bool TestOption::handle(shared_ptr result) { result->m_test = true; Logger::log(Logger::DEBUG," found test Option"); return true; } bool IgnoreErrorOption::handle(shared_ptr result) { if( result->m_call.size() <= 0 ) { result->m_error = NeedCall; return false; } result->m_call.back()->m_ignoreerror = true; Logger::log(Logger::DEBUG," found ignoreerror Option"); return true; } bool IgnoreErrorsOption::handle(shared_ptr result) { result->m_ignoreerrors = true; Logger::log(Logger::DEBUG," found ignoreerrors Option"); return true; } bool VerbosityOption::handle(string ¶meter, shared_ptr result) { if( parameter == "none" ) Logger::setLevel(0); else if( parameter == "normal") Logger::setLevel(1); else if( parameter == "high") Logger::setLevel(2); else if( parameter == "debug") Logger::setLevel(3); else if( parameter == "debugXML") Logger::setLevel(4); else if( parameter == "debugAll") Logger::setLevel(5); else Logger::incrementLevel(); Logger::log(Logger::DEBUG," set Verbosity Level to "+lexical_cast(Logger::level)); return true; } bool QuietOption::handle(string ¶meter, shared_ptr result) { Logger::decrementLevel(); Logger::log(Logger::DEBUG," set Verbosity Level to "+lexical_cast(Logger::level)); return true; } bool RunAsOption::handle(string ¶meter, shared_ptr result) { result->m_user = parameter; Logger::log(Logger::DEBUG," found runas Option: "+parameter); return true; } bool TicketOption::handle(string ¶meter, shared_ptr result) { result->m_ticket = parameter; Logger::log(Logger::DEBUG," found ticket Option: "+parameter); return true; } bool ConfigOption::handle(string ¶meter, shared_ptr result) { result->m_addConfigFile = parameter; Logger::log(Logger::DEBUG," found config Option: "+parameter); return true; } bool ForceOption::handle(shared_ptr result) { if( result->m_call.size() <= 0 ) { result->m_error = NeedCall; return false; } result->m_call.back()->m_force = true; Logger::log(Logger::DEBUG," found force Option"); return true; } bool GlobalsOption::handle(shared_ptr result) { if( result->m_call.size() <= 0 ) { result->m_error = NeedCall; return false; } result->m_call.back()->m_globalOrderIndex = result->m_call.back()->m_order.size(); Logger::log(Logger::DEBUG," found globals Option"); return true; } bool WhereOption::handle(string ¶meter, shared_ptr result) { if( result->m_call.size() <= 0 ) { result->m_error = NeedCall; return false; } string::size_type pos = parameter.find('='); string property(parameter,0,pos); string pattern(parameter,(pos != string::npos)?(pos+1):(string::npos)); whereParameter *where = new whereParameter(); where->m_property = property; where->m_pattern = pattern; result->m_call.back()->m_where.push_back(shared_ptr(where)); Logger::log(Logger::DEBUG," found where Option: "+parameter); return true; } bool OnlyOption::handle(string ¶meter, shared_ptr result) { string::size_type pos = parameter.find('='); string property(parameter,0,pos); string pattern(parameter,(pos != string::npos)?(pos+1):(string::npos)); whereParameter *where = new whereParameter(); where->m_property = property; where->m_pattern = pattern; result->m_only.push_back(shared_ptr(where)); Logger::log(Logger::DEBUG," found only Option: "+parameter); return true; } bool UnsetOption::handle(string ¶meter, shared_ptr result) { if( result->m_call.size() <= 0 ) { result->m_error = NeedCall; return false; } result->m_call.back()->m_unset.push_back(parameter); Logger::log(Logger::DEBUG," found unset Option: "+parameter); return true; } bool UnsetAllOption::handle(string ¶meter, shared_ptr result) { result->m_unsetall.push_back(parameter); Logger::log(Logger::DEBUG," found unsetall Option: "+parameter); return true; } bool OrderOption::handle(string ¶meter, shared_ptr result) { if( result->m_call.size() <= 0 ) { result->m_error = NeedCall; return false; } string::size_type pos = parameter.find('='); string *property; string * direction; if( pos != string::npos ) { property = new string(parameter,0,pos); direction = new string(parameter,(pos != string::npos)?(pos+1):(string::npos)); } else { property = new string(parameter); direction = new string("a"); } orderParameter *order = new orderParameter(); order->m_property = *property; order->m_ascending = ((*direction)[0] == 'a'); result->m_call.back()->m_order.push_back(shared_ptr(order)); Logger::log(Logger::DEBUG," found order Option: "+parameter); return true; } bool GlobalOrderOption::handle(string ¶meter, shared_ptr result) { string::size_type pos = parameter.find('='); string *property; string * direction; if( pos != string::npos ) { property = new string(parameter,0,pos); direction = new string(parameter,(pos != string::npos)?(pos+1):(string::npos)); } else { property = new string(parameter); direction = new string("a"); } orderParameter *order = new orderParameter(); order->m_property = *property; order->m_ascending = ((*direction)[0] == 'a'); result->m_globalOrder.push_back(shared_ptr(order)); Logger::log(Logger::DEBUG," found global order Option: "+parameter); return true; } bool SetOption::handle(string ¶meter, shared_ptr result) { if( result->m_call.size() <= 0 ) { result->m_error = NeedCall; return false; } string::size_type pos = parameter.find('='); string property(parameter,0,pos); string value(parameter,(pos != string::npos)?(pos+1):(string::npos)); setParameter *set = new setParameter(); set->m_property = property; set->m_value = value; result->m_call.back()->m_set.push_back(shared_ptr(set)); Logger::log(Logger::DEBUG," found set Option: "+parameter); return true; } bool SetAllOption::handle(string ¶meter, shared_ptr result) { string::size_type pos = parameter.find('='); string property(parameter,0,pos); string value(parameter,(pos != string::npos)?(pos+1):(string::npos)); setParameter *set = new setParameter(); set->m_property = property; set->m_value = value; result->m_setall.push_back(shared_ptr(set)); Logger::log(Logger::DEBUG," found setall Option: "+parameter); return true; } bool InfileOption::handle(string ¶meter, shared_ptr result) { if( result->m_call.size() <= 0 ) { result->m_error = NeedCall; return false; } string::size_type pos = parameter.find('='); string property(parameter,0,pos); string filename(parameter,(pos != string::npos)?(pos+1):(string::npos)); setParameter *set = new setParameter(); set->m_property = property; ifstream file(filename.c_str()); if( ! file ) { string msg = Logger::getMessageFormatString(Logger::CouldNotOpenFile); boost::format fmt(msg); fmt % filename; Logger::log(Logger::FATAL,fmt.str()); exit(-1); } char ch; while(file.get(ch)) set->m_value += ch; result->m_call.back()->m_set.push_back(shared_ptr(set)); Logger::log(Logger::DEBUG," found infile Option: "+parameter); return true; } bool InputOption::handle(string ¶meter, shared_ptr result) { if( result->m_call.size() <= 0 ) { result->m_error = NeedCall; return false; } setParameter *set = new setParameter(); set->m_property = parameter; cout << "Eingabe (" << parameter << "): " << flush; std::getline(cin, set->m_value); result->m_call.back()->m_set.push_back(shared_ptr(set)); Logger::log(Logger::DEBUG," found input Option: "+parameter); return true; } string readPasswd() { string rval = ""; struct termios t, t2; tcgetattr(0,&t); t2 = t; t2.c_lflag &= ~ECHO; tcsetattr(0,TCSANOW,&t2); std::getline(cin, rval); tcsetattr(0,TCSANOW,&t); return rval; } bool PassInputOption::handle(string ¶meter, shared_ptr result) { if( result->m_call.size() <= 0 ) { result->m_error = NeedCall; return false; } setParameter *set = new setParameter(); set->m_property = parameter; cout << "Passworteingabe (" << parameter << "): " << flush; set->m_value = readPasswd(); result->m_call.back()->m_set.push_back(shared_ptr(set)); Logger::log(Logger::DEBUG," found password-input Option: "+parameter); return true; } bool DisplayOption::handle(string ¶meter, shared_ptr result) { if( result->m_call.size() <= 0 ) { result->m_error = NeedCall; return false; } result->m_call.back()->m_display = parameter; Logger::log(Logger::DEBUG," found display Option: "+parameter); return true; } bool DefaultDisplayOption::handle(string ¶meter, shared_ptr result) { result->m_defaultDisplay = parameter; Logger::log(Logger::DEBUG," found default display Option: "+parameter); return true; } bool ObjectID::handle(string ¶meter, shared_ptr result) { if( result->m_call.size() <= 0 ) { result->m_error = NeedCall; return false; } result->m_call.back()->m_objects.push_back(parameter); Logger::log(Logger::DEBUG," found an ObjectID: "+parameter); return true; } bool CallOption::handle(string ¶meter, shared_ptr result) { string::size_type pos = parameter.find('.'); string module(parameter,0,pos); string function(parameter,(pos != string::npos)?(pos+1):(string::npos)); callParameter *call = new callParameter(); call->m_module = module; call->m_function = function; result->m_call.push_back(shared_ptr(call)); Logger::log(Logger::DEBUG," found call Option: "+parameter); return true; } };