Changeset d7e265d in nscp


Ignore:
Timestamp:
08/25/11 07:59:17 (22 months ago)
Author:
Michael Medin <michael@…>
Branches:
master, 0.4.0, 0.4.1, 0.4.2
Children:
8840f09
Parents:
b38e845
Message:
  • Fixed some issues in the NSCPClient
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • changelog

    rb38e845 rd7e265d  
    99 * Sever refactoring of the new API (there is now two pb files ipc for NSCP protocol and plugin for plugin communication) 
    1010 * Cleaned up API helper functions 
     11 * Fixed client argument for "client mode" to allow arbitrary arguments 
     12 * Cleaned up the argument processor code now requires "mode" to be first argument 
     13 * Fixed some issues in the NSCPClient 
    1114 
    12152011-08-23 MickeM 
  • include/nscapi/functions.hpp

    rb38e845 rd7e265d  
    139139      message.SerializeToString(&buffer); 
    140140    } 
    141     static NSCAPI::nagiosReturn create_simple_query_response_unknown(std::wstring msg, std::wstring perf, std::string &buffer, std::wstring command = _T("")) { 
    142       create_simple_query_response(NSCAPI::returnUNKNOWN, msg, perf, buffer, command); 
     141    static NSCAPI::nagiosReturn create_simple_query_response_unknown(std::wstring command, std::wstring msg, std::wstring perf, std::string &buffer) { 
     142      create_simple_query_response(command, NSCAPI::returnUNKNOWN, msg, perf, buffer); 
    143143      return NSCAPI::returnUNKNOWN; 
    144144    } 
    145145 
    146     static void create_simple_query_response(NSCAPI::nagiosReturn ret, std::wstring msg, std::wstring perf, std::string &buffer, std::wstring command = _T("")) { 
     146    static void create_simple_query_response(std::wstring command, NSCAPI::nagiosReturn ret, std::wstring msg, std::wstring perf, std::string &buffer) { 
    147147      Plugin::QueryResponseMessage message; 
    148148      create_simple_header(message.mutable_header(), Plugin::Common_Header_Type_QUERY_RESPONSE); 
    149149 
    150150      Plugin::QueryResponseMessage::Response *payload = message.add_payload(); 
    151       if (!command.empty()) 
    152         payload->set_command(to_string(command)); 
     151      payload->set_command(to_string(command)); 
    153152      payload->set_message(to_string(msg)); 
    154153      payload->set_result(nagios_status_to_gpb(ret)); 
  • include/nscapi/nscapi_core_wrapper.cpp

    rb38e845 rd7e265d  
    128128void nscapi::core_wrapper::submit_simple_message(std::wstring channel, std::wstring command, NSCAPI::nagiosReturn code, std::wstring & message, std::wstring & perf) { 
    129129  std::string request; 
    130   nscapi::functions::create_simple_query_response(code, message, perf, request, command); 
     130  nscapi::functions::create_simple_query_response(command, code, message, perf, request); 
    131131  NSCAPI::nagiosReturn ret = NotifyChannel(channel, command, code, request); 
    132132} 
  • include/nscapi/nscapi_plugin_wrapper.cpp

    rb38e845 rd7e265d  
    253253  std::wstring msg, perf; 
    254254  NSCAPI::nagiosReturn ret = handleCommand(data.target, data.command, data.args, msg, perf); 
    255   nscapi::functions::create_simple_query_response(ret, msg, perf, response, data.command); 
     255  nscapi::functions::create_simple_query_response(data.command, ret, msg, perf, response); 
    256256  return ret; 
    257257} 
  • include/nscp/client/socket.hpp

    rb38e845 rd7e265d  
    5858    } 
    5959 
    60     virtual void send(std::list<nscp::packet> &chunks, boost::posix_time::seconds timeout) { 
     60    virtual void send(const std::list<nscp::packet> &chunks, boost::posix_time::seconds timeout) { 
    6161      boost::shared_ptr<socket_helpers::io::timed_writer> writer(new socket_helpers::io::timed_writer(get_io_service())); 
    6262      writer->start_timer(timeout); 
    63       BOOST_FOREACH(nscp::packet &chunk, chunks) { 
     63      BOOST_FOREACH(const nscp::packet &chunk, chunks) { 
    6464        if (!writer->write_and_wait(*socket_, get_socket(), boost::asio::buffer(chunk.to_buffer()))) { 
    6565          std::cout << "FaILED TO SEND DATA..." << std::endl; 
     
    134134    } 
    135135 
    136     virtual void send(std::list<nscp::packet> &chunks, boost::posix_time::seconds timeout) { 
     136    virtual void send(const std::list<nscp::packet> &chunks, boost::posix_time::seconds timeout) { 
    137137      boost::shared_ptr<socket_helpers::io::timed_writer> writer(new socket_helpers::io::timed_writer(get_io_service())); 
    138138      writer->start_timer(timeout); 
    139       BOOST_FOREACH(nscp::packet &chunk, chunks) { 
     139      BOOST_FOREACH(const nscp::packet &chunk, chunks) { 
    140140        if (!writer->write_and_wait(*ssl_socket_, get_socket(), boost::asio::buffer(chunk.to_buffer()))) { 
    141141          std::cout << "FaILED TO SEND DATA..." << std::endl; 
  • include/nscp/packet.hpp

    rb38e845 rd7e265d  
    231231      return signature.payload_type == nscp::data::command_request; 
    232232    } 
     233    bool is_command_response() { 
     234      return signature.payload_type == nscp::data::command_response; 
     235    } 
     236    bool is_error() { 
     237      return signature.payload_type == nscp::data::error; 
     238    } 
    233239    static nscp::packet create_query_response(std::string buffer) { 
    234240      return create_payload(nscp::data::command_response, buffer); 
  • modules/CheckExternalScripts/CheckExternalScripts.cpp

    rb38e845 rd7e265d  
    157157      BOOST_FOREACH(std::wstring str, data.args) { 
    158158        if (first && !isAlias && !allowNasty_) { 
    159           if (str.find_first_of(NASTY_METACHARS) != std::wstring::npos) { 
    160             return nscapi::functions::create_simple_query_response_unknown(_T("Request contained illegal characters!"), _T(""), response, data.command); 
     159          if (str.find_first_of(NASTY_METACHARS_W) != std::wstring::npos) { 
     160            return nscapi::functions::create_simple_query_response_unknown(data.command, _T("Request contained illegal characters!"), _T(""), response); 
    161161 
    162162          } 
     
    191191    int result = process::executeProcess(process::exec_arguments(root_, cd.command + _T(" ") + xargs, timeout), message, perf); 
    192192    if (!nscapi::plugin_helper::isNagiosReturnCode(result)) { 
    193       nscapi::functions::create_simple_query_response(NSCAPI::returnUNKNOWN, _T("The command (") + cd.command + _T(") returned an invalid return code: ") + strEx::itos(result), _T(""), response, data.command); 
     193      nscapi::functions::create_simple_query_response_unknown(data.command, _T("The command (") + cd.command + _T(") returned an invalid return code: ") + strEx::itos(result), _T(""), response); 
    194194      return NSCAPI::returnUNKNOWN; 
    195195    } 
    196     nscapi::functions::create_simple_query_response(nscapi::plugin_helper::int2nagios(result), message, perf, response, data.command); 
     196    nscapi::functions::create_simple_query_response(data.command, nscapi::plugin_helper::int2nagios(result), message, perf, response); 
    197197    return result; 
    198198  } 
  • modules/NRPEClient/NRPEClient.cpp

    r438998b rd7e265d  
    221221    { 
    222222      if (SETTINGS_GET_INT(nrpe::ALLOW_NASTY) == 0) { 
    223         if (arg.find_first_of(NASTY_METACHARS) != std::wstring::npos) { 
     223        if (arg.find_first_of(NASTY_METACHARS_W) != std::wstring::npos) { 
    224224          NSC_LOG_ERROR(_T("Request string contained illegal metachars!")); 
    225225          return NSCAPI::returnIgnored; 
  • modules/NRPEServer/handler_impl.cpp

    r438998b rd7e265d  
    1818  } 
    1919  if (!allowNasty_) { 
    20     if (cmd.first.find_first_of(NASTY_METACHARS) != std::wstring::npos) { 
     20    if (cmd.first.find_first_of(NASTY_METACHARS_W) != std::wstring::npos) { 
    2121      NSC_LOG_ERROR(_T("Request command contained illegal metachars!")); 
    2222      throw nrpe::nrpe_exception(_T("Request command contained illegal metachars!")); 
    2323    } 
    24     if (cmd.second.find_first_of(NASTY_METACHARS) != std::wstring::npos) { 
     24    if (cmd.second.find_first_of(NASTY_METACHARS_W) != std::wstring::npos) { 
    2525      NSC_LOG_ERROR(_T("Request arguments contained illegal metachars!")); 
    2626      throw nrpe::nrpe_exception(_T("Request command contained illegal metachars!")); 
  • modules/NSCPClient/NSCPClient.cpp

    rb38e845 rd7e265d  
    156156  return false; 
    157157} 
     158 
     159 
     160std::list<std::string> collect_result(std::list<std::string> payloads, int &ret) { 
     161  std::list<std::string> result; 
     162  ret = NSCAPI::returnOK; 
     163  BOOST_FOREACH(std::string p, payloads) { 
     164    Plugin::QueryResponseMessage message; 
     165    message.ParseFromString(p); 
     166    for (int i=0;i<message.payload_size();i++) { 
     167      const Plugin::QueryResponseMessage::Response &payload = message.payload(i); 
     168      ret = nscapi::plugin_helper::maxState(ret, nscapi::functions::gbp_to_nagios_status(payload.result())); 
     169      std::string line = payload.message(); 
     170 
     171      // @todo: Add performance data parsin here! 
     172      //nscapi::functions::parse_performance_data(payload, perf); 
     173      //if (!payload.perf().empty()) 
     174      //  line += _T("|") + payload; 
     175      result.push_back(line); 
     176    } 
     177  } 
     178  return result; 
     179} 
     180 
     181 
    158182NSCAPI::nagiosReturn NSCPClient::handleCommand(const std::wstring &target, const std::wstring &command, std::list<std::wstring> &arguments, std::wstring &message, std::wstring &perf) { 
    159183  if (command == _T("query_nscp")) { 
     
    164188    return NSCAPI::returnIgnored; 
    165189 
    166   nscp_result_data r; // = execute_nscp_command((*cit).second, arguments); 
    167   message = r.text; 
    168   return r.result; 
    169 } 
    170  
     190  std::string buffer; 
     191  nscapi::functions::create_simple_query_request((*cit).second.command, arguments, buffer); 
     192  std::list<std::string> payloads = execute_nscp_command((*cit).second, buffer); 
     193  int ret = NSCAPI::returnUNKNOWN; 
     194  std::list<std::string> result = collect_result(payloads, ret); 
     195  BOOST_FOREACH(std::string p, result) { 
     196    message += utf8::cvt<std::wstring>(p) + _T("\n"); 
     197  } 
     198  return ret; 
     199} 
    171200 
    172201 
     
    186215    po::notify(vm); 
    187216 
    188     std::string foo = "foobar"; 
    189     execute_nscp_command(command_data, foo); 
     217 
     218    std::string buffer; 
     219    nscapi::functions::create_simple_query_request(command_data.command, arguments, buffer); 
     220    std::list<std::string> payloads = execute_nscp_command(command_data, buffer); 
     221    int ret = NSCAPI::returnUNKNOWN; 
     222    std::list<std::string> result = collect_result(payloads, ret); 
     223    BOOST_FOREACH(std::string p, result) { 
     224      message += utf8::cvt<std::wstring>(p) + _T("\n"); 
     225    } 
     226    return ret; 
    190227  } catch (boost::program_options::validation_error &e) { 
    191228    message = _T("Error: ") + utf8::cvt<std::wstring>(e.what()); 
     
    225262    std::string buffer; 
    226263    nscapi::functions::create_simple_query_request(command_data.command, command_data.arguments, buffer); 
    227     execute_nscp_command(command_data, buffer); 
    228     nscp_result_data res;// = execute_nscp_command(command_data, command_data.arguments); 
    229     result = res.text; 
    230     return res.result; 
    231   } catch (boost::program_options::validation_error &e) { 
     264    std::list<std::string> payloads = execute_nscp_command(command_data, buffer); 
     265    int ret = NSCAPI::returnUNKNOWN; 
     266    BOOST_FOREACH(std::string p, collect_result(payloads, ret)) { 
     267      result += utf8::cvt<std::wstring>(p) + _T("\n"); 
     268    } 
     269    return ret; 
     270  } catch (std::exception &e) { 
    232271    result = _T("Error: ") + utf8::cvt<std::wstring>(e.what()); 
    233272    return NSCAPI::returnUNKNOWN; 
    234273  } catch (...) { 
    235     result = _T("Unknown exception parsing command line"); 
     274    result = _T("Unknown exception processing request"); 
    236275    return NSCAPI::returnUNKNOWN; 
    237276  } 
    238277  return NSCAPI::returnUNKNOWN; 
    239278} 
    240 NSCPClient::nscp_result_data NSCPClient::execute_nscp_command(nscp_connection_data con, std::string buffer) { 
     279std::list<std::string> NSCPClient::execute_nscp_command(nscp_connection_data con, std::string buffer) { 
     280  std::list<std::string> result; 
    241281  try { 
    242282    std::list<nscp::packet> chunks; 
    243283    chunks.push_back(nscp::packet::build_envelope_request(1)); 
    244284    chunks.push_back(nscp::packet::create_payload(nscp::data::command_request, buffer, 0)); 
    245     if (!con.no_ssl) { 
    246 #ifdef USE_SSL 
    247       chunks = send_ssl(con.host, con.port, con.timeout, chunks); 
    248 #else 
    249       NSC_LOG_ERROR_STD(_T("SSL not avalible (not compiled with USE_SSL)")); 
    250       return nscp_result_data(NSCAPI::returnUNKNOWN, _T("SSL support not available (compiled without USE_SSL)!")); 
    251 #endif 
    252     } else { 
    253       chunks = send_nossl(con.host, con.port, con.timeout, chunks); 
    254     } 
     285    chunks = send(con, chunks); 
    255286    BOOST_FOREACH(nscp::packet &chunk, chunks) { 
    256       NSC_DEBUG_MSG_STD(_T("Found chunk: ") + utf8::cvt<std::wstring>(strEx::format_buffer(chunk.payload.c_str(), chunk.payload.size()))); 
    257     } 
    258     return nscp_result_data(NSCAPI::returnUNKNOWN, _T("Hello")); 
    259   } catch (nscp::nscp_exception &e) { 
    260     NSC_LOG_ERROR_STD(_T("Socket error: ") + utf8::cvt<std::wstring>(e.what())); 
    261     return nscp_result_data(NSCAPI::returnUNKNOWN, _T("Socket error: ") + utf8::cvt<std::wstring>(e.what())); 
    262   } catch (std::runtime_error &e) { 
    263     NSC_LOG_ERROR_STD(_T("Socket error: ") + utf8::cvt<std::wstring>(e.what())); 
    264     return nscp_result_data(NSCAPI::returnUNKNOWN, _T("Socket error: ") + utf8::cvt<std::wstring>(e.what())); 
     287      if (chunk.is_command_response()) { 
     288        result.push_back(chunk.payload); 
     289      } else if (chunk.is_error()) { 
     290        NSCPIPC::ErrorMessage message; 
     291        message.ParseFromString(chunk.payload); 
     292        for (int i=0;i<message.error_size();i++) { 
     293          NSC_LOG_ERROR_STD(_T("Error: ") + utf8::cvt<std::wstring>(message.error(i).message())); 
     294        } 
     295      } else { 
     296        NSC_LOG_ERROR_STD(_T("Unsupported message type: ") + strEx::itos(chunk.signature.payload_type)); 
     297      } 
     298      //NSC_DEBUG_MSG_STD(_T("Found chunk: ") + utf8::cvt<std::wstring>(strEx::format_buffer(chunk.payload.c_str(), chunk.payload.size()))); 
     299    } 
     300    return result; 
    265301  } catch (std::exception &e) { 
    266302    NSC_LOG_ERROR_STD(_T("Exception: ") + utf8::cvt<std::wstring>(e.what())); 
    267     return nscp_result_data(NSCAPI::returnUNKNOWN, _T("Socket error: ") + utf8::cvt<std::wstring>(e.what())); 
    268   } catch (...) { 
    269     NSC_LOG_ERROR_STD(_T("Unknown exception...")); 
    270     return nscp_result_data(NSCAPI::returnUNKNOWN, _T("Unknown error -- REPORT THIS!")); 
    271   } 
    272 } 
    273  
    274  
     303    return result; 
     304  } 
     305} 
     306 
     307std::list<nscp::packet> NSCPClient::send(nscp_connection_data &con, const std::list<nscp::packet> &chunks) { 
     308  std::list<nscp::packet> result; 
     309  if (!con.no_ssl) { 
    275310#ifdef USE_SSL 
    276 std::list<nscp::packet> NSCPClient::send_ssl(std::wstring host, int port, int timeout, std::list<nscp::packet> &chunks) { 
     311    result = send_ssl(con.host, con.port, con.timeout, chunks); 
     312#else 
     313    NSC_LOG_ERROR_STD(_T("SSL not avalible (not compiled with USE_SSL)")); 
     314    result.push_back(nscp::packet::create_error(_T("SSL support not available (compiled without USE_SSL)!"))); 
     315#endif 
     316  } else { 
     317    result = send_nossl(con.host, con.port, con.timeout, chunks); 
     318  } 
     319  return result; 
     320} 
     321 
     322#ifdef USE_SSL 
     323std::list<nscp::packet> NSCPClient::send_ssl(std::wstring host, int port, int timeout, const std::list<nscp::packet> &chunks) { 
     324  NSC_DEBUG_MSG_STD(_T("Connecting to: ") + host + _T(":") + strEx::itos(port)); 
    277325  boost::asio::io_service io_service; 
    278326  boost::asio::ssl::context ctx(io_service, boost::asio::ssl::context::sslv23); 
     
    286334#endif 
    287335 
    288 std::list<nscp::packet> NSCPClient::send_nossl(std::wstring host, int port, int timeout, std::list<nscp::packet> &chunks) { 
     336std::list<nscp::packet> NSCPClient::send_nossl(std::wstring host, int port, int timeout, const std::list<nscp::packet> &chunks) { 
    289337  boost::asio::io_service io_service; 
    290338  nscp::client::socket socket(io_service, host, port); 
  • modules/NSCPClient/NSCPClient.h

    rb38e845 rd7e265d  
    5858    } 
    5959  }; 
    60   struct nscp_result_data { 
    61     nscp_result_data() {} 
    62     nscp_result_data(int result_, std::wstring text_) : result(result_), text(text_) {} 
    63     std::wstring text; 
    64     int result; 
    65   }; 
    6660  typedef std::map<std::wstring, nscp_connection_data> command_list; 
    6761  command_list commands; 
     
    10498 
    10599private: 
    106   nscp_result_data  execute_nscp_command(nscp_connection_data con, std::string buffer); 
    107   std::list<nscp::packet> send_nossl(std::wstring host, int port, int timeout, std::list<nscp::packet> &chunks); 
    108   std::list<nscp::packet> send_ssl(std::wstring host, int port, int timeout, std::list<nscp::packet> &chunks); 
     100  std::list<std::string> execute_nscp_command(nscp_connection_data con, std::string buffer); 
     101  std::list<nscp::packet> send(nscp_connection_data &con, const std::list<nscp::packet> &chunks); 
     102  std::list<nscp::packet> send_nossl(std::wstring host, int port, int timeout, const std::list<nscp::packet> &chunks); 
     103  std::list<nscp::packet> send_ssl(std::wstring host, int port, int timeout, const std::list<nscp::packet> &chunks); 
    109104  void add_options(po::options_description &desc, nscp_connection_data &command_data); 
    110105 
  • modules/NSCPServer/handler_impl.cpp

    rb38e845 rd7e265d  
    1818 
    1919    // @todo: Make split optional 
     20    // @todo: Make this return ONE response not multiple responses 
    2021 
    2122    for (int i=0;i<msg.payload_size();i++) { 
     23      const Plugin::QueryRequestMessage_Request &payload = msg.payload(i); 
     24      std::string outBuffer; 
     25      std::wstring command = utf8::cvt<std::wstring>(payload.command()); 
    2226 
    23         // @todo re-add support for nasty arguments / arguments passing 
    24   /* 
    25   if (!allowNasty_) { 
    26     if (cmd.first.find_first_of(NASTY_METACHARS) != std::wstring::npos) { 
    27       NSC_LOG_ERROR(_T("Request command contained illegal metachars!")); 
    28       throw nscp::nscp_exception(_T("Request command contained illegal metachars!")); 
    29     } 
    30     if (cmd.second.find_first_of(NASTY_METACHARS) != std::wstring::npos) { 
    31       NSC_LOG_ERROR(_T("Request arguments contained illegal metachars!")); 
    32       throw nscp::nscp_exception(_T("Request command contained illegal metachars!")); 
    33     } 
    34   } 
    35   */ 
    36  
    37       std::string outBuffer; 
    38       std::wstring command = utf8::cvt<std::wstring>(msg.payload(i).command()); 
    3927      if (command.empty() || command == _T("_NSCP_CHECK")) { 
    40         nscapi::functions::create_simple_query_response(NSCAPI::returnOK, _T("I (") + nscapi::plugin_singleton->get_core()->getApplicationVersionString() + _T(") seem to be doing fine..."), _T(""), outBuffer); 
     28        nscapi::functions::create_simple_query_response(_T("_NSCP_CHECK"), NSCAPI::returnOK, _T("I (") + nscapi::plugin_singleton->get_core()->getApplicationVersionString() + _T(") seem to be doing fine..."), _T(""), outBuffer); 
     29      } else if (!allowArgs_ && payload.arguments_size() > 0) { 
     30        nscapi::functions::create_simple_query_response_unknown(command, _T("Arguments not allowed for command: ") + command, _T(""), outBuffer); 
    4131      } else { 
    42         std::string tmpBuffer; 
    43         Plugin::QueryRequestMessage tmp; 
    44         tmp.mutable_header()->CopyFrom(hdr); 
    45         tmp.add_payload()->CopyFrom(msg.payload(i)); 
    46         tmp.SerializeToString(&tmpBuffer); 
    47         NSCAPI::nagiosReturn returncode = nscapi::plugin_singleton->get_core()->query(command, tmpBuffer, outBuffer); 
     32        bool ok = true; 
     33        if (!allowNasty_) { 
     34          for (int j=0;j<payload.arguments_size();j++) { 
     35            if (payload.arguments(j).find_first_of(NASTY_METACHARS) != std::wstring::npos) { 
     36              ok = false; 
     37              break; 
     38            } 
     39          } 
     40        } 
     41        if (ok) { 
     42          std::string tmpBuffer; 
     43          Plugin::QueryRequestMessage tmp; 
     44          tmp.mutable_header()->CopyFrom(hdr); 
     45          tmp.add_payload()->CopyFrom(payload); 
     46          tmp.SerializeToString(&tmpBuffer); 
     47          NSCAPI::nagiosReturn returncode = nscapi::plugin_singleton->get_core()->query(command, tmpBuffer, outBuffer); 
     48          if (returncode == NSCAPI::returnIgnored) { 
     49            nscapi::functions::create_simple_query_response_unknown(command, _T("Command was not found: ") + command, _T(""), outBuffer); 
     50          } 
     51        } else { 
     52          nscapi::functions::create_simple_query_response_unknown(command, _T("Nasty arguments not allowed for command: ") + command, _T(""), outBuffer); 
     53        } 
    4854      } 
    4955      result.push_back(nscp::packet::create_query_response(outBuffer)); 
  • modules/PythonScript/PythonScript.cpp

    rb38e845 rd7e265d  
    291291    std::wstring msg, perf; 
    292292    NSCAPI::nagiosReturn ret = inst->exec_simple(cmd, data.args, msg, perf); 
    293     nscapi::functions::create_simple_query_response(ret, msg, perf, response, data.command); 
     293    nscapi::functions::create_simple_query_response(data.command, ret, msg, perf, response); 
    294294    return ret; 
    295295  } 
  • service/cli_parser.hpp

    rb38e845 rd7e265d  
    99 
    1010  NSClient* core_; 
    11   po::options_description desc; 
     11  po::options_description root; 
    1212  po::options_description settings; 
    1313  po::options_description service; 
    1414  po::options_description client; 
     15  po::options_description common; 
     16 
     17  bool debug; 
     18  bool help; 
     19  bool version; 
    1520 
    1621public: 
    1722  cli_parser(NSClient* core)  
    1823    : core_(core) 
    19     , desc("Allowed options") 
     24    , root("Allowed first option (Mode of operation)") 
     25    , common("Common options") 
    2026    , settings("Settings options") 
    2127    , service("Service Options") 
    2228    , client("Client Options") 
     29    , debug(false) 
     30    , help(false) 
     31    , version(false) 
    2332  { 
    24     desc.add_options() 
    25       ("help", "produce help message") 
     33    root.add_options() 
     34      ("help", po::bool_switch(&help), "produce help message") 
    2635      ("settings-help", "Produce help message for the various settings related options") 
    2736      ("service-help", "Produce help message for the various settings related service management") 
    2837      ("client-help", "Produce help message for the various settings related client") 
     38      ("test-help", "Produce help message for the various settings related client") 
     39 
    2940      ("settings", "Enter settings mode and handle settings related commands") 
    3041      ("service", "Enter service mode and handle service related commands") 
    3142      ("client", "Enter client mode and handle client related commands") 
    3243      ("test", "Start test and debug mode") 
    33       ("debug", "Show debug information") 
    34       ("version", "Show version information") 
    35       ; 
    36  
     44      ("version", po::bool_switch(&version), "Show version information") 
     45      ; 
     46    common.add_options() 
     47      ("help", po::bool_switch(&help), "produce help message") 
     48      ("debug", po::bool_switch(&debug), "Show debug information") 
     49      ("version", po::bool_switch(&version), "Show version information") 
     50      ; 
    3751 
    3852    settings.add_options() 
     
    6276      ("command,C", po::value<std::wstring>(), "Name of command to start") 
    6377      ("module,M", po::value<std::wstring>(), "Name of module to load (if not specified all modules in ini file will be loaded)") 
    64       ("arguments,A", po::value< std::vector<std::wstring> >()->multitoken(), "List of arguments")      ; 
    65  
     78      ("arguments,a", po::wvalue<std::vector<std::wstring> >(), "List of arguments") 
     79      ; 
     80 
     81  } 
     82 
     83  bool process_common_options() { 
     84    if (debug) { 
     85      core_->enableDebug(true); 
     86      core_->log_debug(__FILE__, __LINE__, _T("Enabling debug mode")); 
     87    } 
     88 
     89    if (help) { 
     90      po::options_description all("Allowed options"); 
     91      all.add(root).add(common).add(service).add(settings).add(client); 
     92      std::cout << all << std::endl; 
     93      return true; 
     94    } 
     95    if (version) { 
     96      std::cout << APPLICATION_NAME << _T(", Version: ") << CURRENT_SERVICE_VERSION << _T(", Platform: ") << SZARCH << std::endl; 
     97      return true; 
     98    } 
     99    return false; 
    66100  } 
    67101  int parse(int argc, wchar_t* argv[]) { 
    68102    try { 
    69103      po::options_description all("Allowed options"); 
    70       all.add(desc).add(service).add(settings).add(client); 
     104      all.add(root).add(common).add(service).add(settings).add(client); 
    71105 
    72106      po::variables_map vm; 
    73107      po::wparsed_options parsed =  
    74         po::wcommand_line_parser(argc, argv).options(all).allow_unregistered().run(); 
    75  
    76       //po::store(po::parse_command_line(argc, argv, desc), vm); 
     108        po::wcommand_line_parser((argc>2)?2:argc, argv).options(root).run(); 
     109 
    77110      po::store(parsed, vm); 
    78111      po::notify(vm); 
    79112 
    80       if (vm.count("debug")) { 
    81         core_->enableDebug(true); 
    82         core_->log_debug(__FILE__, __LINE__, _T("Enabling debug mode")); 
    83       } 
    84  
    85       if (vm.count("help")) { 
    86         mainClient.set_console_log(); 
    87         std::cout << all << "\n"; 
    88         return 1; 
    89       } 
    90       if (vm.count("version")) { 
    91         mainClient.set_console_log(); 
    92         std::cout << APPLICATION_NAME << _T(", Version: ") << CURRENT_SERVICE_VERSION << _T(", Platform: ") << SZARCH << "\n"; 
    93         return 1; 
    94       } 
     113      if (process_common_options()) 
     114        return 1; 
     115 
    95116      if (vm.count("settings-help")) { 
    96         mainClient.set_console_log(); 
    97         std::cout << settings << "\n"; 
     117        std::cout << settings << std::endl; 
    98118        return 1; 
    99119      } 
    100120      if (vm.count("service-help")) { 
    101         mainClient.set_console_log(); 
    102         std::cout << service << "\n"; 
     121        std::cout << service << std::endl; 
    103122        return 1; 
    104123      } 
    105124      if (vm.count("client-help")) { 
    106         mainClient.set_console_log(); 
    107         std::cout << client << "\n"; 
     125        std::cout << client << std::endl; 
    108126        return 1; 
    109127      } 
     
    111129      if (vm.count("settings")) { 
    112130        mainClient.set_console_log(); 
    113         return parse_settings(argc, argv); 
     131        return parse_settings(argc-1, &argv[1]); 
    114132      } 
    115133      if (vm.count("service")) { 
    116134        //mainClient.set_console_log(); 
    117         return parse_service(argc, argv); 
     135        return parse_service(argc-1, &argv[1]); 
    118136      } 
    119137      if (vm.count("client")) { 
    120         return parse_client(argc, argv); 
     138        return parse_client(argc-1, &argv[1]); 
    121139      } 
    122140      if (vm.count("test")) { 
    123141        mainClient.set_console_log(); 
    124         return parse_test(argc, argv); 
    125       } 
     142        return parse_test(argc-1, &argv[1]); 
     143      } 
     144      std::cerr << "First argument has to be one of the following: " << std::endl; 
     145      std::cout << root << std::endl; 
     146      return 1; 
    126147    } catch(std::exception & e) { 
    127       core_->log_error(__FILE__, __LINE__, std::string("Unable to parse command line: ") + e.what()); 
     148      std::cerr << "Unable to parse root option: " << e.what() << std::endl; 
    128149      return 1; 
    129150    } catch (...) { 
    130       core_->log_error(__FILE__, __LINE__, "Unhanded Exception"); 
     151      std::cerr << "Unable to parse root option" << std::endl; 
    131152      return 1; 
    132153    } 
     
    149170    try { 
    150171      po::options_description all("Allowed options (settings)"); 
    151       all.add(desc).add(settings); 
     172      all.add(common).add(settings); 
    152173 
    153174      po::variables_map vm; 
     
    155176      po::notify(vm); 
    156177 
    157       if (vm.count("help")) { 
    158         std::cout << all << "\n"; 
    159         return 1; 
    160       } 
     178      if (process_common_options()) 
     179        return 1; 
     180 
    161181      bool def = vm.count("add-defaults")==1; 
    162182 
     
    203223  int parse_service(int argc, wchar_t* argv[]) { 
    204224    try { 
    205       po::options_description all("Allowed options (settings)"); 
    206       all.add(desc).add(service); 
     225      po::options_description all("Allowed options (service)"); 
     226      all.add(common).add(service); 
    207227 
    208228      po::variables_map vm; 
     
    210230      po::notify(vm); 
    211231 
    212       if (vm.count("help")) { 
    213         std::cout << all << "\n"; 
    214         return 1; 
    215       } 
    216       bool debug = false; 
    217       if (vm.count("debug")) { 
    218         debug = true; 
    219       } 
     232      if (process_common_options()) 
     233        return 1; 
     234 
    220235      std::wstring name; 
    221236      if (vm.count("name")) { 
     
    271286    try { 
    272287      po::options_description all("Allowed options (client)"); 
    273       all.add(desc).add(client); 
    274  
     288      all.add(common).add(client); 
     289 
     290      po::positional_options_description p; 
     291      p.add("arguments", -1); 
    275292 
    276293      po::variables_map vm; 
     
    280297      po::notify(vm); 
    281298 
    282       bool debug = false; 
    283       if (vm.count("debug")) { 
    284         debug = true; 
    285       } 
     299      if (process_common_options()) 
     300        return 1; 
    286301 
    287302      std::wstring command; 
    288       if (vm.count("command")) { 
     303      if (vm.count("command")) 
    289304        command = vm["command"].as<std::wstring>(); 
    290       } 
     305 
    291306      std::wstring module; 
    292       if (vm.count("module")) { 
     307      if (vm.count("module")) 
    293308        module = vm["module"].as<std::wstring>(); 
    294       } 
     309 
     310      std::vector<std::wstring> kvp_args; 
     311      if (vm.count("arguments")) 
     312        kvp_args = vm["arguments"].as<std::vector<std::wstring> >(); 
     313 
    295314      std::vector<std::wstring> arguments = po::collect_unrecognized(parsed.options, po::include_positional); 
    296315 
     316      BOOST_FOREACH(std::wstring s, kvp_args) { 
     317        std::wstring::size_type pos = s.find(L'='); 
     318        if (pos == std::wstring::npos) 
     319          arguments.push_back(_T("--") + s); 
     320        else { 
     321          arguments.push_back(_T("--") + s.substr(0,pos)); 
     322          arguments.push_back(s.substr(pos+1)); 
     323        } 
     324      } 
     325 
     326 
     327      mainClient.set_console_log(); 
     328      mainClient.enableDebug(debug); 
    297329      if (debug) { 
    298         mainClient.set_console_log(); 
    299         mainClient.enableDebug(true); 
    300330        mainClient.log_info(__FILE__, __LINE__, _T("Module: ") + module); 
    301331        mainClient.log_info(__FILE__, __LINE__, _T("Command: ") + command); 
     
    321351      return ret; 
    322352    } catch(std::exception & e) { 
    323       mainClient.log_error(__FILE__, __LINE__, std::string("Unable to parse command line (settings): ") + e.what()); 
     353      std::cout << "Client: Unable to parse command line: "  << e.what() << std::endl; 
     354      return 1; 
     355    } catch(...) { 
     356      mainClient.log_error(__FILE__, __LINE__, "Unknown exception parsing command line"); 
     357      std::cout << "Client: Unknown exception parsing command line" << std::endl; 
    324358      return 1; 
    325359    } 
Note: See TracChangeset for help on using the changeset viewer.