triplet.cpp

00001 //
00002 // C++ Implementation: triplet
00003 //
00004 // Description: 
00005 //
00006 //
00007 // Author: Michael Moritz <mimo@restoel.net>, (C) 2007
00008 //
00009 // Copyright: See COPYING file that comes with this distribution
00010 //
00011 //
00012 
00013 #ifdef HAVE_CONFIG_H
00014 #include <config.h>
00015 #endif
00016 #include <iostream>
00017 #include <string>
00018 #include <sstream>
00019 #include <stdexcept>
00020 #include <netdb.h>
00021 #include "cfg.h"
00022 #include "read.h"
00023 #include "defs.h"
00024 #include "triplet.h"
00025 
00026 #ifdef HAVE_SYS_SOCKET_H
00027 #include <sys/socket.h>
00028 #endif
00029 
00030 Triplet::Triplet(const Reader& reader)
00031         : _client_address(reader.getValue(ATTR_CLIENT)), 
00032           _sender(reader.getValue(ATTR_SENDER)), 
00033           _recipient(reader.getValue(ATTR_RECIPIENT)),
00034           _resolved(reader.getValue(ATTR_RCLNAME,"")),
00035           _client_address_numeric(),
00036           _not_resolved(),
00037           _weakclient()
00038 {
00039         _init();
00040 }
00041 Triplet::Triplet(const std::string& client,const std::string& sender,const std::string& recipient,
00042                 const std::string& client_numeric) 
00043         :       _client_address(client), 
00044                 _sender(sender), 
00045                 _recipient(recipient),
00046                 _resolved(),
00047                 _client_address_numeric(client_numeric),
00048                 _not_resolved(),
00049                 _weakclient()
00050                 
00051 {
00052         _init();
00053 }
00054 
00056 // - set up _resolved (if reverse)
00057 // - set up _client_address_numeric (always?)
00058 // - set up _weakclient (if in weak mode)
00059 void Triplet::_init() {
00060         bool weak = g_getCfg().isModeWeak();
00061         bool reverse = g_getCfg().isModeReverse();
00062         bool verbose = g_getCfg().isVerbose();
00063 
00065         
00066         const std::string& tStr = _client_address;
00067 //      std::cout << "tStr" << tStr << std::endl;
00068         std::string::size_type i = tStr.find('.');
00069         std::string::size_type j = 1; //skip '
00070         if(tStr[0] != '\'') //unquoted
00071                 j = 0;
00072         if(i != std::string::npos) {
00073                 do {
00074                         //std::cout << "substr " << tStr.substr(j,i-j) << std::endl;
00075                         _client_address_numeric += atoi((tStr.substr(j,i-j)).c_str());
00076                         j = i+1;
00077                         i = tStr.find('.',j);
00078                         if(i == std::string::npos) {
00079                                 i = tStr.find('\'',j);
00080                                 if((i == std::string::npos) && (tStr[0] != '\'')) { //unquoted
00081                                         //std::cout << "substr " << tStr.substr(j,i) << std::endl;
00082                                         _client_address_numeric += atoi((tStr.substr(j,i)).c_str());
00083                                         break;
00084                                 }
00085                         }
00086                 }while( i != std::string::npos);
00087         }
00088 
00090 
00091         if(reverse) {
00092 
00093                 const std::string& clientAddressNumeric = _client_address_numeric;
00094                 //would like to use getnameinfo but documentation sucks big time
00095                 hostent* hp = ::gethostbyaddr(clientAddressNumeric.c_str(),
00096                         clientAddressNumeric.size(),
00097                         AF_INET);
00098                 if(hp) {
00099                         _resolved = hp->h_name;
00100                 } else {
00101                         std::string err;
00102                         switch(h_errno) {
00103                                 case HOST_NOT_FOUND:
00104                                         err = "HOST_NOT_FOUND";
00105                                         break;
00106                                 case NO_ADDRESS:
00107                                         err = "NO_ADDRESS|NO_DATA";
00108                                         break;
00109                                 case NO_RECOVERY:
00110                                         err = "NO_RECOVERY";
00111                                         break;
00112                                 case TRY_AGAIN:
00113                                         err = "TRY_AGAIN";
00114                                         break;
00115                                 default:
00116                                         err = "Unexpected";
00117                                         break;
00118                         }
00119                         _not_resolved = err;
00120                 }
00121         }
00122 
00124 
00125         _weakclient = "'" + getClientAddressNumericStr('.',3)+"." + "'";
00126 
00127 }
00129 /* const std::string& getClientAddressNumeric() const { 
00130                 if(_client_address_numeric.size())
00131                         return _client_address_numeric;
00132                 else {
00133                         if( !_client_address.size() )
00134                                 return _client_address_numeric;
00135                         const std::string& tStr = _client_address;
00136 //                      std::cout << "tStr" << tStr << std::endl;
00137                         std::string::size_type i = tStr.find('.');
00138                         std::string::size_type j = 1; //skip '
00139                         if(tStr[0] != '\'') //unquoted
00140                                 j = 0;
00141                         if(i != std::string::npos) {
00142                                 do {
00143                                         //std::cout << "substr " << tStr.substr(j,i-j) << std::endl;
00144                                         _client_address_numeric += atoi((tStr.substr(j,i-j)).c_str());
00145                                         j = i+1;
00146                                         i = tStr.find('.',j);
00147                                         if(i == std::string::npos) {
00148                                                 i = tStr.find('\'',j);
00149                                                 if((i == std::string::npos) && (tStr[0] != '\'')) { //unquoted
00150                                                         //std::cout << "substr " << tStr.substr(j,i) << std::endl;
00151                                                         _client_address_numeric += atoi((tStr.substr(j,i)).c_str());
00152                                                         break;
00153                                                 }
00154                                         }
00155                                 }while( i != std::string::npos);
00156                         }
00157                         return _client_address_numeric;
00158                 }
00159         };*/
00160 
00162 const std::string Triplet::getClientAddressNumericStr(const char sep,unsigned size) const { 
00163         std::stringstream stm;
00164         if(size == 0)
00165                 size = getClientAddressNumeric().size();
00166         if(size == 0)
00167                 return std::string("(zero size)");
00168         //TODO check if this way of conversion is portable
00169         const unsigned char* pu = reinterpret_cast<const unsigned char*>(_client_address_numeric.c_str());
00170         for(unsigned i=0;i < size-1;i++) 
00171                 stm << static_cast<unsigned>(pu[i]) << sep;
00172         if(size >= 1)
00173                 stm << static_cast<unsigned>(pu[size-1]);
00174         return stm.str();
00175 }
00177 const std::string Triplet::getClientAddressNumericStrSQL(const std::string& sep,const std::string& base,
00178         unsigned start,const std::string& afterstart,unsigned mult,unsigned size) const { 
00179         std::stringstream stm;
00180 //      unsigned size = bytes;
00181         if(size == 0)
00182                 size = getClientAddressNumeric().size();
00183         //TODO check if this way of conversion is portable
00184         const unsigned char* pu = reinterpret_cast<const unsigned char*>(getClientAddressNumeric().c_str());
00185         for(unsigned i=0;i < size-1;i++) {
00186                 stm << base << start << afterstart << static_cast<unsigned>(pu[i]) << sep;
00187                 start /= mult;
00188         }
00189         if(size >= 1)
00190                 stm << base << start << afterstart << static_cast<unsigned>(pu[size-1]);
00191         return stm.str();
00192 }
00196 // const std::string Triplet::getResolved() const {
00197 //      if(_resolved.size() > 0)
00198 //                      return _resolved;
00199 //      if(_not_resolved.size() > 0)
00200 //              return _resolved; //empty string
00201 //      const std::string& clientAddressNumeric = this->getClientAddressNumeric();
00202 //      //would like to use getnameinfo but documentation sucks big time
00203 //      hostent* hp = ::gethostbyaddr(clientAddressNumeric.c_str(),
00204 //                    clientAddressNumeric.size(),
00205 //                    AF_INET);
00206 //      if(hp) {
00207 //              _resolved = hp->h_name;
00208 //      } else {
00209 //              std::string err;
00210 //              switch(h_errno) {
00211 //                      case HOST_NOT_FOUND:
00212 //                              err = "HOST_NOT_FOUND";
00213 //                              break;
00214 //                      case NO_ADDRESS:
00215 //                              err = "NO_ADDRESS|NO_DATA";
00216 //                              break;
00217 //                      case NO_RECOVERY:
00218 //                              err = "NO_RECOVERY";
00219 //                              break;
00220 //                      case TRY_AGAIN:
00221 //                              err = "TRY_AGAIN";
00222 //                              break;
00223 //                      default:
00224 //                              err = "Unexpected";
00225 //                              break;
00226 //              }
00227 //              _not_resolved = err;
00228 //      }
00229 //      return _resolved;
00230 // }
00231 

Generated on Tue Jul 24 16:36:54 2007 for gps by  doxygen 1.5.1