135 #include <boost/asio.hpp> 
  136 #include <boost/program_options.hpp> 
  138 #include <sys/ioctl.h> 
  144 #include "structs.hpp" 
  145 #include "datatypes.hpp" 
  146 #include "version.hpp" 
  147 #include "ligier_helper.hpp" 
  148 #include "consumers.hpp" 
  149 #include "dom_map.hpp" 
  153   static bool const is_a_tty = isatty(1);
 
  160     ioctl(1, TIOCGWINSZ, &sz);
 
  165 namespace po = boost::program_options;
 
  176     boost::asio::signal_set& set,
 
  178     boost::system::error_code 
const& error,
 
  182 template<
class Consumer>
 
  199       boost::system::error_code 
const& error
 
  203     if (error && error != boost::asio::error::operation_aborted) {
 
  206     } 
else if (error == boost::asio::error::operation_aborted) {
 
  210       boost::asio::async_read(
 
  216             , boost::asio::placeholders::error
 
  217             , boost::asio::placeholders::bytes_transferred
 
  231             , boost::asio::placeholders::error
 
  239     if (error && error != boost::asio::error::operation_aborted) {
 
  241       m_timer.expires_from_now(boost::posix_time::seconds(1));
 
  247             , boost::asio::placeholders::error
 
  250     } 
else if (error == boost::asio::error::operation_aborted) {
 
  254       boost::asio::async_write(
 
  256         , boost::asio::buffer(
m_buffer, size)
 
  260             , boost::asio::placeholders::error
 
  261             , boost::asio::placeholders::bytes_transferred
 
  268       boost::system::error_code 
const& error
 
  269     , std::size_t bytes_transferred
 
  271     if (error && error != boost::asio::error::operation_aborted) {
 
  274     } 
else if (error == boost::asio::error::operation_aborted) {
 
  276       boost::asio::async_read(
 
  282             , boost::asio::placeholders::error
 
  283             , boost::asio::placeholders::bytes_transferred
 
  290       boost::system::error_code 
const& error
 
  291     , std::size_t bytes_transferred
 
  293     if (error && error != boost::asio::error::operation_aborted) {
 
  296     } 
else if (error == boost::asio::error::operation_aborted) {
 
  300       boost::asio::async_read(
 
  302         , boost::asio::buffer(
m_buffer + 16, size)
 
  306             , boost::asio::placeholders::error
 
  307             , boost::asio::placeholders::bytes_transferred
 
  315     boost::system::error_code ec;
 
  317     m_socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
 
  325           , boost::asio::placeholders::error
 
  336       boost::asio::io_service& service
 
  337     , std::string 
const& tag
 
  338     , boost::asio::ip::tcp::endpoint 
const& endpoint
 
  341     , Consumer 
const& consumer
 
  355           , boost::asio::placeholders::error
 
  361 template<
class Consumer>
 
  372       boost::system::error_code 
const& error
 
  373     , std::size_t bytes_transferred
 
  386           , boost::asio::placeholders::error
 
  387           , boost::asio::placeholders::bytes_transferred
 
  395       boost::asio::io_service& service
 
  399     , Consumer 
const& consumer
 
  402         , boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), port)
 
  408     boost::asio::ip::udp::socket::receive_buffer_size option(33554432);
 
  416           , boost::asio::placeholders::error
 
  417           , boost::asio::placeholders::bytes_transferred
 
  425     std::string 
const& address
 
  427   boost::asio::io_service service;
 
  428   boost::asio::ip::tcp::resolver resolver(service);
 
  430   std::string::size_type 
const pos = address.find(
":");
 
  432   std::string 
const host = pos == std::string::npos ? address : address.substr(0, pos);
 
  433   std::string 
const port = pos == std::string::npos ? 
"5553"  : address.substr(pos + 1);
 
  435   boost::asio::ip::tcp::resolver::query query(
 
  436       boost::asio::ip::tcp::v4()
 
  441   return *resolver.resolve(query);
 
  444 int main(
int argc, 
char* argv[])
 
  447   uint32_t type = 
unkn;
 
  448   bool uses_roy = 
false;
 
  449   bool use_gui = 
false;
 
  450   bool lm_mode = 
false;
 
  452   std::string dom_names = std::getenv(
"HOME") + std::string(
"/.doms.csk");
 
  453   dom_map_type dom_names_map;
 
  455   std::ofstream output_file;
 
  457   unsigned int port = 0;
 
  459   std::string filename;
 
  460   std::string roy_setup;
 
  462   std::string lserver = 
"localhost:5553";
 
  464   boost::asio::ip::tcp::endpoint endpoint;
 
  466   po::options_description desc(
"Generic options");
 
  468     (
"help,h",    
"Print this help and exit.")
 
  469     (
"version,v", 
"Print the version and exit.")
 
  472       , po::value<std::string>(&dom_names)->value_name(
"filename")
 
  473       , 
"File that specifies a conversion from DOM IDs to a human readable name." 
  476     (
"gui,g", 
"Use GUI (avalilable in UDP-monitoring and Ligier modes only).")
 
  478     (
"ligier,l", 
"Set Ligier mode.")
 
  479     (
"udp,u", 
"Force UDP mode (default).");
 
  481   po::options_description lmdesc(
"Ligier-mode options");
 
  485       , po::value<std::string>(&lserver)
 
  486           ->default_value(
"localhost:5553")
 
  487           ->value_name(
"server:[port]")
 
  488       , 
"Set the Ligier server endpoint to read data from." 
  492       , po::value<std::string>(&tag)
 
  493           ->default_value(
"IO_MONIT")
 
  495       , 
"Set the Ligier tag to read data from." 
  498   po::options_description umdesc(
"UDP-mode options");
 
  501           po::value<unsigned int>(&port)
 
  503               ->value_name(
"port"),
 
  504           "Set the expected data type to optical. If a port is not \ 
  505 provided the default one is used (56015).")
 
  507           po::value<unsigned int>(&port)
 
  509               ->value_name(
"port"),
 
  510           "Set the expected data type to acoustic. If a port is not \ 
  511 provided the default one is used (56016).")
 
  513           po::value<unsigned int>(&port)
 
  515               ->value_name(
"port"),
 
  516           "Set the expected data type to monitoring. If a port is \ 
  517 not provided the default one is used (56017).")
 
  519           po::value<unsigned int>(&port)->value_name(
"port"),
 
  520           "Listen on the specified port, automatically determining the \ 
  523           po::value<std::string>(&filename)->value_name(
"filename"),
 
  524           "Dumps the acquired data to a file.")
 
  526           po::value<std::string>(&roy_setup)
 
  527               ->implicit_value(
"HR_%n.%c:localhost:9999")
 
  528               ->value_name(
"format:host:port"),
 
  529           "Send the monitoring hit rates to the specified ROyWeb \ 
  530 server. The syntax is format:server_ip:server_port. \ 
  531 The format parameter can contain the following placeholders: %d for \ 
  532 DOM ID, %n for DOM name (if available, otherwise the DOM ID is used) \ 
  533 and %c for channel ID.");
 
  536   std::string roy_server;
 
  540     po::options_description global;
 
  541     global.add(desc).add(lmdesc).add(umdesc);
 
  543     po::variables_map vm;
 
  545         po::command_line_parser(argc, argv).
options(global).run()
 
  549     if (vm.count(
"help")) {
 
  557     if (vm.count(
"version")) {
 
  565     use_gui = vm.count(
"gui");
 
  568     lm_mode = vm.count(
"ligier");
 
  570     if (lm_mode && vm.count(
"udp")) {
 
  571       throw std::runtime_error(
"You can specify only one mode. Both provided.");
 
  574     if (vm.count(
"map")) {
 
  575       std::ifstream 
map(dom_names.c_str());
 
  578         throw std::runtime_error(
 
  579             std::string(
"Error reading map file: ")
 
  580             + std::strerror(errno)
 
  586       std::ifstream 
map(dom_names.c_str());
 
  592       po::variables_map vm;
 
  593       po::options_description 
options;
 
  594       options.add(lmdesc).add(desc);
 
  597           po::command_line_parser(argc, argv).
options(options).run()
 
  607       po::variables_map vm;
 
  608       po::options_description 
options;
 
  609       options.add(desc).add(umdesc);
 
  612           po::command_line_parser(argc, argv).
options(options).run()
 
  618       unsigned int counter = 0;
 
  619       if (vm.count(
"port")) {
 
  623       if (vm.count(
"optical")) {
 
  627       if (vm.count(
"acoustic")) {
 
  631       if (vm.count(
"monitoring")) {
 
  638           throw std::runtime_error(
"More than one port provided.");
 
  640           throw std::runtime_error(
"You must specify at least one port.");
 
  644       if (use_gui && type != 
tmch) {
 
  645         throw std::runtime_error(
"GUI is only available in monitoring mode");
 
  648       if (vm.count(
"royweb")) {
 
  650           throw std::runtime_error(
"you can use ROyWeb only with the" 
  651           " monitoring channel");
 
  655         std::replace(roy_setup.begin(), roy_setup.end(), 
':', 
' ');
 
  656         std::istringstream ss(roy_setup);
 
  661         if (ss >> roy_server) {
 
  664         if (ss >> roy_port) {
 
  668         if (param_count != 3) {
 
  669           throw std::runtime_error(
"you must specify all the parameters" 
  670           " or accept all the default one to use with ROyWeb.");
 
  674       if (vm.count(
"dumpfile")) {
 
  675         output_file.open(filename.c_str(), std::ios::binary);
 
  677           throw std::runtime_error(
 
  678               "Unable to open file " 
  687   } 
catch (
const po::error& e) {
 
  689       << 
"CLBSwissKnife: Error: " << e.what() << 
'\n' 
  695   } 
catch (
const std::runtime_error& e) {
 
  696     std::cerr << 
"CLBSwissKnife: Error: " << e.what() << std::endl;
 
  700   boost::asio::io_service io_service;
 
  711       boost::asio::deadline_timer timer(io_service, boost::posix_time::seconds(1));
 
  713       boost::asio::posix::stream_descriptor keyb(io_service, ::dup(STDIN_FILENO));
 
  715       boost::asio::signal_set window_resize(io_service, SIGWINCH);
 
  718       gui::ScreenInitialiser init;
 
  720       gui::Screen screen(io_service, lserver, stats);
 
  722       keyb.async_read_some(
 
  723           boost::asio::buffer(&key, 
sizeof(key)),
 
  729               boost::asio::placeholders::error,
 
  730               boost::asio::placeholders::bytes_transferred
 
  739               boost::asio::placeholders::error
 
  749         , clbsk::consumer::Gui(terminal_width, dom_names_map, stats, screen)
 
  752       window_resize.async_wait(
 
  755               boost::ref(window_resize),
 
  757               boost::asio::placeholders::error,
 
  758               boost::asio::placeholders::signal_number
 
  765       std::cout << 
"Listening from: " << endpoint << 
':' << tag << 
'\n';
 
  766       boost::asio::signal_set signals_handler(io_service, SIGWINCH, SIGINT);
 
  768       signals_handler.async_wait(
 
  771               boost::ref(signals_handler),
 
  772               boost::ref(terminal_width),
 
  773               boost::asio::placeholders::error,
 
  774               boost::asio::placeholders::signal_number
 
  784         , clbsk::consumer::Scrollback(terminal_width, 
tmch, dom_names_map)
 
  790     std::cout << 
"Listening port: " << port << 
'\n' << 
"Data type: ";
 
  793       std::cout << 
"Acoustic\n";
 
  794     } 
else if (type == 
ttdc) {
 
  795       std::cout << 
"Optical\n";
 
  796     } 
else if (type == 
tmch) {
 
  797       std::cout << 
"Monitoring\n";
 
  799       std::cout << 
"Automatically determined\n";
 
  802     clbsk::consumer::ConsumerSet consumer_set;
 
  804     trm::MonStreamer ms(roy_server, roy_port);
 
  812         << 
") with tag format " 
  813         << templ << std::endl;
 
  816           clbsk::consumer::Roy(
 
  825       consumer_set.add(clbsk::consumer::File(output_file));
 
  832       boost::asio::deadline_timer timer(io_service, boost::posix_time::seconds(1));
 
  834       boost::asio::posix::stream_descriptor keyb(io_service, ::dup(STDIN_FILENO));
 
  836       boost::asio::signal_set window_resize(io_service, SIGWINCH);
 
  839       gui::ScreenInitialiser init;
 
  841       std::string 
const heading
 
  842         = 
"UDP " + boost::lexical_cast<std::string>(port);
 
  844       gui::Screen screen(io_service, heading, stats);
 
  846       keyb.async_read_some(
 
  847           boost::asio::buffer(&key, 
sizeof(key)),
 
  853               boost::asio::placeholders::error,
 
  854               boost::asio::placeholders::bytes_transferred
 
  863               boost::asio::placeholders::error
 
  867       window_resize.async_wait(
 
  870               boost::ref(window_resize),
 
  872               boost::asio::placeholders::error,
 
  873               boost::asio::placeholders::signal_number
 
  878           clbsk::consumer::Gui(
 
  898           clbsk::consumer::Scrollback(
 
  905       boost::asio::signal_set signals_handler(io_service, SIGWINCH, SIGINT);
 
  907       signals_handler.async_wait(
 
  910             , boost::ref(signals_handler)
 
  911             , boost::ref(terminal_width)
 
  912             , boost::asio::placeholders::error
 
  913             , boost::asio::placeholders::signal_number
 
  931     boost::asio::signal_set& set,
 
  933     boost::system::error_code 
const& error,
 
  938     if (signum == SIGINT) {
 
  939       set.get_io_service().stop();
 
  941         std::cout << 
"\033]2;thank you for flying with CLBSwissKnife!\007";
 
  942         std::cout << 
"\rBye bye!\n";
 
  945     } 
else if (signum == SIGWINCH) {
 
  953             boost::ref(terminal_width),
 
  954             boost::asio::placeholders::error,
 
  955             boost::asio::placeholders::signal_number
 
static int terminal_width
 
void data_handle(boost::system::error_code const &error, std::size_t bytes_transferred)
 
void handle_signal(boost::asio::signal_set &set, int &terminal_width, boost::system::error_code const &error, int signum)
 
struct __attribute__((__packed__)) InfoWord
 
void async_win_resize(boost::asio::signal_set &window_resize, gui::Screen &screen, boost::system::error_code const &error, int signum)
 
TString replace(const TString &target, const TRegexp ®exp, const T &replacement)
Replace regular expression in input by given replacement. 
 
std::size_t m_buffer_size
 
void timeout_handle(boost::system::error_code const &error)
 
LigierDataHandler(LigierDataHandler const &)
 
UdpDataHandler(boost::asio::io_service &service, int port, char *buffer, std::size_t buffer_size, Consumer const &consumer)
 
std::size_t const m_buffer_size
 
LigierDataHandler(boost::asio::io_service &service, std::string const &tag, boost::asio::ip::tcp::endpoint const &endpoint, char *buffer, std::size_t buffer_size, Consumer const &consumer)
 
void data_handle(boost::system::error_code const &error, std::size_t size)
 
then print u2 $script< option > print u2 Possible options
 
LigierDataHandler & operator=(LigierDataHandler const &)
 
static const size_t buffer_size
 
void store(const std::string &file_name, const JDetector &detector)
Store detector to output file. 
 
std::size_t prepare_tag(char *buffer, std::size_t max_size, std::string const &tag)
 
void subscribe_handle(boost::system::error_code const &error, std::size_t bytes_transferred)
 
void connect_handle(boost::system::error_code const &error)
 
boost::asio::ip::tcp::endpoint m_endpoint
 
void header_handle(boost::system::error_code const &error, std::size_t bytes_transferred)
 
static const unsigned int default_opto_port
 
int get_terminal_width()
Program name: CLBSwissKnife. 
 
boost::asio::deadline_timer m_timer
 
boost::asio::ip::tcp::endpoint make_endpoint(const std::string &address)
 
void async_cin(boost::asio::posix::stream_descriptor &keyb, char &key, gui::Screen &screen, const boost::system::error_code &error, std::size_t bytes_transferred)
 
std::size_t read_data_size(char const *const buffer)
 
void async_commit(boost::asio::deadline_timer &timer, gui::Screen &screen, boost::system::error_code const &error)
 
dom_map_type load_dom_map(std::istream &map)
 
boost::asio::ip::udp::socket m_socket
 
boost::asio::ip::tcp::socket m_socket
 
LigierDataHandler< Consumer > this_type
 
UdpDataHandler< Consumer > this_type
 
static const unsigned int default_acou_port
 
static const unsigned int default_moni_port
 
int main(int argc, char *argv[])