Добавил:
korayakov
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Лабы / 2 / lab.03.by mice / claw / cdm_addr_info
.cpp/*******************************************************************************
* file: cdm_addr_info.h *
* version: 0.9.0 *
* author: d-evil [tmd] (mailto:d-evil.tmd@mail.ru) *
* description: not available *
*******************************************************************************/
#include "cdm_addr_info.h"
////////////////////////////////////////////////////////////////////////////////
// cdm_addr_info public definition
cdm_addr_info::cdm_addr_info() {
_saddr_in.sin_addr.s_addr = 0;
_saddr_in.sin_port = 0;
_saddr_in.sin_family = AF_INET;
_ip_str = NULL;
_port_str = NULL; //(char *)malloc(MX_PORTLEN * sizeof(char));
_host = NULL;
}
cdm_addr_info::cdm_addr_info(const char *const host, const unsigned short port) {
_ip_str = NULL;
_port_str = NULL;
_host = NULL;
set(host, port);
}
cdm_addr_info::~cdm_addr_info() {
free(_ip_str);
free(_port_str);
free(_host);
}
int cdm_addr_info::set(const sockaddr_in *const saddrin) {
int rev = set_port(ntohs(saddrin->sin_port));
if (0 != rev) return rev;
rev = _set_ip(saddrin->sin_addr);
if (0 != rev) {
if (NULL != _host) _host[0] = '\0';
return rev;
}
return _updt_host();
}
int cdm_addr_info::set(const char *const host, const unsigned short port) {
int rev = set_port(port);
if (0 != rev) return rev;
return set_host(host);
}
int cdm_addr_info::set_port(const unsigned short port) {
_saddr_in.sin_port = htons(port);
if (NULL == _port_str) {
// try to alloc some memory
_port_str = (char *)malloc(MX_PORTLEN * sizeof(char));
if (NULL == _port_str) return ERC_NOMEM;
}
_port_str = itoa(port, _port_str, 10);
return 0;
}
int cdm_addr_info::set_host(const char *const host) {
int rev = resolve_host(host, &_saddr_in.sin_addr);
if (0 != rev) return rev;
rev = _set_ip(_saddr_in.sin_addr);
if (0 != rev) {
if (NULL != _host) _host[0] = '\0';
return rev;
}
return _updt_host();
}
int cdm_addr_info::set_to_local(const unsigned short port) {
char str[MX_LOCAL_HOST_LEN];
if (0 != gethostname(str, MX_LOCAL_HOST_LEN)) return -1;
return set(str, port);
}
int cdm_addr_info::resolve_host(const char *const host, in_addr *const addr) {
addr->s_addr = inet_addr(host);
// If the supplied server address wasn’t in the form "aaa.bbb.ccc.ddd"
// it’s a host name, so try to resolve it
if (INADDR_NONE == addr->s_addr) {
hostent *ht;
ht = gethostbyname(host);
if (NULL == ht) return ERC_CANTRESOLVE;
memcpy(addr, ht->h_addr_list[0], ht->h_length);
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////
// cdm_addr_info protected definition
int cdm_addr_info::_set_ip(const in_addr ip) {
_saddr_in.sin_addr = ip;
char *ip_str = inet_ntoa(_saddr_in.sin_addr);
if (NULL == ip_str) {
if (NULL != _ip_str) _ip_str[0] = '\0';
return ERC_WSA;
}
size_t len = strlen(ip_str) + 1;
char *tmp = (char *)realloc(_ip_str, len * sizeof(char));
if (NULL == tmp) {
_ip_str = '\0';
return ERC_NOMEM;
}
_ip_str = tmp;
memcpy(_ip_str, ip_str, len * sizeof(char));
return 0;
}
int cdm_addr_info::_updt_host() {
hostent *ht = gethostbyaddr((char *)&_saddr_in.sin_addr,
sizeof(_saddr_in.sin_addr), _saddr_in.sin_family);
if (NULL == ht || NULL == ht->h_name) {
if (NULL != _host) _host[0] = '\0';
return 0; // ERC_CANTRESOLVE; // can't resolve
}
size_t len = strlen(ht->h_name) + 1;
char *tmp = (char *)realloc(_host, len * sizeof(char));
if (NULL == tmp) {
if (NULL != _host) _host[0] = '\0';
return ERC_NOMEM;
}
_host = tmp;
memcpy(_host, ht->h_name, len * sizeof(char));
return 0;
}