SAGA Adaptor CPI v.1.0
|
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