SAGA Adaptor CPI v.1.0
is_local_address.cpp
Go to the documentation of this file.
00001 //  Copyright (c) 2008, 2009 João Abecasis
00002 //
00003 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
00004 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
00005 
00006 #ifndef SAGA_ADAPTORS_CONDOR_JOB_IS_LOCALHOST_HPP_INCLUDED
00007 #define SAGA_ADAPTORS_CONDOR_JOB_IS_LOCALHOST_HPP_INCLUDED
00008 
00009 #include <saga/saga-defs.hpp>
00010 #include <saga/saga/adaptors/utils.hpp>
00011 
00012 #include <boost/asio/io_service.hpp>
00013 #include <boost/asio/ip/host_name.hpp>
00014 #include <boost/asio/ip/tcp.hpp>
00015 #include <boost/spirit/core/non_terminal/impl/static.hpp>
00016 
00017 #include <set>
00018 #include <string>
00019 
00020 #include <saga/saga/adaptors/utils/is_local_address.hpp>
00021 
00022 namespace saga { namespace adaptors { namespace utils 
00023 {
00024     namespace detail 
00025     {
00026         struct is_local_address_data
00027         {
00028             typedef boost::asio::io_service io_service;
00029             typedef boost::asio::ip::tcp::resolver resolver;
00030             typedef boost::asio::ip::tcp::resolver::query query;
00031             typedef boost::asio::ip::tcp::resolver::iterator iterator;
00032 
00033 #if !defined(SAGA_WINDOWS)
00034             std::string readline (FILE* fd)
00035             {
00036               char c[1];
00037               std::string line = "";
00038 
00039               size_t n = ::fread (&c, sizeof (char), 1, fd);
00040 
00041               while ( 1 == n )
00042               {
00043                 // on EOL, return
00044                 if ( c[0] == '\n' )
00045                 {
00046                   return (line);
00047                 }
00048 
00049                 // append any other char to line
00050                 line += c[0];
00051 
00052                 n = ::fread (&c, sizeof (char), 1, fd);
00053               }
00054 
00055               // on read error, return what we have
00056               return (line);
00057             }
00058 #endif            
00059 
00060             is_local_address_data()
00061                 : resolver_(service_)
00062                 , hostname_(boost::asio::ip::host_name(ec_))
00063             {
00064                 iterator iter = resolve("localhost"), end;
00065                 for (; iter != end; ++iter)
00066                     local_addresses_.insert(get_address(iter));
00067 
00068                 if (!hostname_.empty())
00069                 {
00070                     iter = resolve(hostname_);
00071                     for (; iter != end; ++iter)
00072                         local_addresses_.insert(get_address(iter));
00073                 }
00074 
00075 #if !defined(SAGA_WINDOWS)
00076                 // we also accept whatever 'hostname' tells us to be a valid
00077                 // local hostname
00078                 {
00079                   FILE* fd = ::popen ("hostname", "r");
00080 
00081                   if ( fd != NULL )
00082                   {
00083                     std::string line = this->readline (fd);
00084 
00085                     while ( ! line.empty () )
00086                     {
00087                       std::vector <std::string> elems = saga::adaptors::utils::split (line);
00088 
00089                       for ( unsigned int i = 0; i < elems.size (); i++ )
00090                       {
00091                         local_addresses_.insert (elems[i]);
00092                       }
00093                      
00094                       line = this->readline (fd);
00095                     }
00096 
00097                     ::pclose (fd);
00098                   }
00099                 }
00100 #endif
00101             }
00102 
00103             iterator resolve(std::string host)
00104             {
00105                 return resolver_.resolve(query(host, "0"), ec_);
00106             }
00107 
00108             static std::string get_address(iterator iter)
00109             {
00110                 return iter->endpoint().address().to_string();
00111             }
00112 
00113             boost::system::error_code ec_;
00114 
00115             io_service service_;
00116             resolver resolver_;
00117 
00118             std::string hostname_;
00119             std::set<std::string> local_addresses_;
00120         };
00121 
00122         class is_local_address_tag
00123         {
00124             is_local_address_tag() {}
00125             friend bool saga::adaptors::utils::is_local_address(std::string const &);
00126         };
00127 
00128     }
00129 
00130     bool is_local_address(std::string const & host)
00131     {
00132         if (host.empty() || host == "localhost")
00133             return true;
00134 
00135         detail::is_local_address_data & data =
00136             boost::spirit::static_<
00137                 detail::is_local_address_data, detail::is_local_address_tag>();
00138 
00139         for (detail::is_local_address_data::iterator iter = data.resolve(host), end;
00140                 iter != end; ++iter)
00141             if (data.local_addresses_.count(data.get_address(iter)))
00142                 return true;
00143 
00144         return false;
00145     }
00146 
00147 }}} // namespace saga::adaptors::utils
00148 
00149 #endif // include guard
00150 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines