⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 swiipaddress.cpp

📁 openvxi3.4是一个voicexml对话脚本语言的解释器源码.可用VC6.0编译.
💻 CPP
📖 第 1 页 / 共 2 页
字号:

/****************License************************************************
 * Vocalocity OpenVXI
 * Copyright (C) 2004-2005 by Vocalocity, Inc. All Rights Reserved.
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *  
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 * Vocalocity, the Vocalocity logo, and VocalOS are trademarks or 
 * registered trademarks of Vocalocity, Inc. 
 * OpenVXI is a trademark of Scansoft, Inc. and used under license 
 * by Vocalocity.
 ***********************************************************************/

#include <string.h>
#include "SWIipAddress.hpp"

#ifdef _WIN32
#include <winsock2.h>
#else
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#endif

#if defined(WIN32) || defined(_decunix_)
/* These OSes are thread safe by using thread local storage for the hostent */
static int my_gethostbyaddr_r (const char * addr, socklen_t len,
			       int type,
			       struct hostent * result_buf,
			       char * buf, size_t buflen,
			       struct hostent ** result,
			       int * h_errnop) {
  *result = gethostbyaddr(addr, len, type);
  return (result ? 0 : -1);
}

static int my_gethostbyname_r (const char * name,
			       struct hostent * result_buf,
			       char * buf, size_t buflen,
			       struct hostent ** result,
			       int * h_errnop) {
  *result = gethostbyname(name);
  return (result ? 0 : -1);
}
#elif defined(_solaris_)
static int my_gethostbyaddr_r (const char * addr, socklen_t len,
			       int type,
			       struct hostent * result_buf,
			       char * buf, size_t buflen,
			       struct hostent ** result,
			       int * h_errnop) {
  *result = gethostbyaddr_r(addr, len, type, result_buf, buf, buflen,
			    h_errnop);
  return (result ? 0 : -1);
}

static int my_gethostbyname_r (const char * name,
			       struct hostent * result_buf,
			       char * buf, size_t buflen,
			       struct hostent ** result,
			       int * h_errnop) {
  *result = gethostbyname_r(name, result_buf, buf, buflen, h_errnop);
  return (result ? 0 : -1);
}
#else
/* Linux, maybe others */
#define my_gethostbyaddr_r gethostbyaddr_r
#define my_gethostbyname_r gethostbyname_r
#endif

#ifdef _WIN32
// Class used for static initialization of mutex or WSA layer.
class SWIipAddressInit
{
 public:
  SWIipAddressInit();
  ~SWIipAddressInit();
};

SWIipAddressInit::SWIipAddressInit()
{
  WSADATA wsaData;
  WSAStartup(MAKEWORD(2, 2), &wsaData);
}

SWIipAddressInit::~SWIipAddressInit()
{
  WSACleanup();
}

static SWIipAddressInit G_netInit;

#endif

#define SOCK_ERROR(classname, msg) \
do { \
  if (_logger) \
  { \
    if (errno) \
      _logger->Error(500, L"%s%S%s%S%s%S%s%d", L"class", classname, L"msg", msg, \
	  L"errnoStr", strerror(errno), L"errno", errno); \
    else \
      _logger->Error(500, L"%s%S%s%S", L"class", classname, L"msg", msg); \
  } \
} while(0)


SWIipAddress::SWIipAddress(const SWIipAddress &sina)
{
  _logger         = sina._logger;
  sin_family      = sina.sin_family;
  sin_addr.s_addr = sina.sin_addr.s_addr;
  sin_port	  = sina.sin_port;
}

SWIipAddress::SWIipAddress(SWIutilLogger *logger)
{
  _logger =       logger;
  sin_family	  = AF_INET;
  sin_addr.s_addr = htonl(INADDR_ANY);
  sin_port	  = 0;
}

SWIipAddress::SWIipAddress(unsigned long addr,
			   int port_no,
                           SWIutilLogger *logger)
{
// addr and port_no are in host byte order
  _logger         = logger;
  sin_family      = AF_INET;
  sin_addr.s_addr = htonl(addr);
  sin_port	  = htons(port_no);
}

SWIipAddress::SWIipAddress(unsigned long addr,
			   const char* sn,
                           const char* pn,
                           SWIutilLogger *logger)
{
  // addr is in host byte order
  _logger         = logger;
  sin_family      = AF_INET;
  sin_addr.s_addr = htonl (addr);
  setport(sn, pn);
}

SWIipAddress::SWIipAddress(const char* host_name,
                           int port_no,
                           SWIutilLogger *logger)
{
// port_no is in host byte order
  _logger = logger;
  sethostname(host_name);
  sin_port = htons(port_no);
}

SWIipAddress::SWIipAddress(const char* hn,
			   const char* sn,
                           const char* pn,
                           SWIutilLogger *logger)
{
  _logger = logger;
  sethostname(hn);
  setport(sn, pn);
}

void SWIipAddress::setport(int port_no)
{
  sin_port = htons(port_no);
}

int SWIipAddress::setport(const char* sn, const char* pn)
{
  servent* sp = getservbyname(sn, pn);
  if (sp == 0)
  {
    SOCK_ERROR("SWIipAddress", "invalid service name");
    return -1;
  }
  sin_port = sp->s_port;
  return 0;
}

int SWIipAddress::getport() const
{
  return ntohs (sin_port);
}

int SWIipAddress::sethostname(const char* host_name)
{
  if ( (sin_addr.s_addr = inet_addr(host_name)) == (in_addr_t) -1) {
    int hostErrno;
    struct hostent hostResult;
    char hostBuffer[4096];
    hostent* hp;
    if ((my_gethostbyname_r(host_name, &hostResult, hostBuffer,
			    2048, &hp, &hostErrno) != 0) ||
	(hp == 0))
    {
      return -1;
    }
    memcpy(&sin_addr, hp->h_addr, hp->h_length);
    sin_family = hp->h_addrtype;
  }
  else
    sin_family = AF_INET;
  return 0;
}

int SWIipAddress::gethostname(char *hostname, size_t hostnameLen) const
{
  hostname[0] = '\0';

  if (sin_addr.s_addr == htonl(INADDR_ANY)) {
    if (::gethostname(hostname, hostnameLen) == -1) {
      SOCK_ERROR("SWIipAddress", "gethostname");
      hostname[0] = '\0';
      return -1;
    }
    return 0;
  }

  int hostErrno;
  struct hostent hostResult;
  char hostBuffer[4096];
  hostent* hp;
  if ((my_gethostbyaddr_r((const char*) &sin_addr, sizeof(sin_addr),
			  family(), &hostResult, hostBuffer, 2048, &hp,
			  &hostErrno) != 0) ||
      (hp == 0))
  {
    SWIipAddress::herror("gethostbyaddr");
    return -1;
  }
  if ((hp->h_name) && (strlen(hp->h_name) < hostnameLen)) {
    strcpy (hostname, hp->h_name);
    return 0;
  }
  return -1;
}


unsigned int SWIipAddress::hashCode() const
{
  unsigned int h = (unsigned int) ntohl(sin_addr.s_addr);
  h <<= 16;
  h |= ntohs(sin_port) & 0xFF;
  return h;
}

bool SWIipAddress::operator==(const SWIipAddress& rhs) const
{
  if (this == &rhs) return true;

  return sin_addr.s_addr == rhs.sin_addr.s_addr &&
    sin_port == rhs.sin_port;
}

SWIHashable *SWIipAddress::clone() const
{
  return new SWIipAddress(*this);
}

bool SWIipAddress::equals(const SWIHashable *rhs) const
{
  return operator==(*((const SWIipAddress *) rhs));
}

#ifdef _WIN32

static	char* errmsg[] = {
  "No error",
  "Host not found",
  "Try again",
  "No recovery",
  "No address"
  "Unknown error"
};

/* Winsock.h maps h_errno to WSAGetLastError() function call */
void SWIipAddress::herror(const char* em) const
{
  int err;
  switch(h_errno) { /* calls WSAGetLastError() */
   case HOST_NOT_FOUND:
     err = 1;
     break;
   case TRY_AGAIN:
     err = 2;
     break;
   case NO_RECOVERY:
     err = 3;
     break;
   case NO_ADDRESS:
     err = 4;
     break;
   default:
     err = 5;
     break;
  }

  SOCK_ERROR(em, errmsg[err]);
}

#else // !_WIN32

/* Use the native UNIX call */
void SWIipAddress::herror(const char* em) const
{
#ifdef _decunix_
  if (_logger)
  {
    if (errno)
      Error(500, L"%s%S%s%d%s%S%s%d", L"class", em, L"h_errno", h_errno,
            L"errnoStr", strerror(errno), L"errno", errno);
    else
      Error(500, L"%s%S%s%d", L"class", em, L"h_errno", h_errno);
  }
#else
  SOCK_ERROR(em, hstrerror(h_errno));
#endif
}

#endif // !_WIN32

#if 0
SWIipAddress::SWIipAddress (int port)
   : ipAddressSet(false)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -