trunk/branch integration: Enviroment::nodeId() exception patch

This commit is contained in:
Marian Krivos 2011-08-22 16:55:52 +00:00
parent 7e1cc09a3c
commit d1e2d3f2e0
4 changed files with 88 additions and 59 deletions

View File

@ -36,6 +36,7 @@
#include "Poco/Environment_UNIX.h"
#include "Poco/Exception.h"
#include "Poco/Buffer.h"
#include <cstring>
#include <unistd.h>
#include <stdlib.h>
@ -167,11 +168,11 @@ namespace Poco {
void EnvironmentImpl::nodeIdImpl(NodeId& id)
{
std::memset(&id, 0, sizeof(id));
struct ifaddrs* ifaphead;
int rc = getifaddrs(&ifaphead);
if (rc) throw SystemException("cannot get network adapter list");
if (rc) return;
bool foundAdapter = false;
for (struct ifaddrs* ifap = ifaphead; ifap; ifap = ifap->ifa_next)
{
if (ifap->ifa_addr && ifap->ifa_addr->sa_family == AF_LINK)
@ -182,13 +183,11 @@ void EnvironmentImpl::nodeIdImpl(NodeId& id)
if (ap && alen > 0)
{
std::memcpy(&id, ap, sizeof(id));
foundAdapter = true;
break;
}
}
}
freeifaddrs(ifaphead);
if (!foundAdapter) throw SystemException("cannot determine MAC address (no suitable network adapter found)");
}
@ -203,6 +202,11 @@ void EnvironmentImpl::nodeIdImpl(NodeId& id)
#include <sys/socket.h>
#include <netinet/in.h>
#include <net/if.h>
#ifndef __CYGWIN__
#include <net/if_arp.h>
#else // workaround for Cygwin, which does not have if_arp.h
#define ARPHRD_ETHER 1 /* Ethernet 10Mbps */
#endif
#include <arpa/inet.h>
#include <unistd.h>
@ -212,17 +216,56 @@ namespace Poco {
void EnvironmentImpl::nodeIdImpl(NodeId& id)
{
struct ifreq ifr;
std::memset(&id, 0, sizeof(id));
int sock = socket(PF_INET, SOCK_DGRAM, 0);
if (sock == -1) return;
int s = socket(PF_INET, SOCK_DGRAM, 0);
if (s == -1) throw SystemException("cannot open socket");
std::strcpy(ifr.ifr_name, "eth0");
int rc = ioctl(s, SIOCGIFHWADDR, &ifr);
close(s);
if (rc < 0) throw SystemException("cannot get MAC address");
struct sockaddr* sa = reinterpret_cast<struct sockaddr*>(&ifr.ifr_addr);
std::memcpy(&id, sa->sa_data, sizeof(id));
// the following code is loosely based
// on W. Richard Stevens, UNIX Network Programming, pp 434ff.
int lastlen = 0;
int len = 100*sizeof(struct ifreq);
struct ifconf ifc;
char* buf = 0;
for (;;)
{
buf = new char[len];
ifc.ifc_len = len;
ifc.ifc_buf = buf;
if (::ioctl(sock, SIOCGIFCONF, &ifc) < 0)
{
if (errno != EINVAL || lastlen != 0)
{
close(sock);
delete [] buf;
return;
}
}
else
{
if (ifc.ifc_len == lastlen)
break;
lastlen = ifc.ifc_len;
}
len += 10*sizeof(struct ifreq);
delete [] buf;
}
for (const char* ptr = buf; ptr < buf + ifc.ifc_len;)
{
const struct ifreq* ifr = reinterpret_cast<const struct ifreq*>(ptr);
int rc = ioctl(sock, SIOCGIFHWADDR, ifr);
if (rc != -1)
{
const struct sockaddr* sa = reinterpret_cast<const struct sockaddr*>(&ifr->ifr_hwaddr);
if (sa->sa_family == ARPHRD_ETHER)
{
std::memcpy(&id, sa->sa_data, sizeof(id));
break;
}
}
ptr += sizeof(struct ifreq);
}
close(sock);
delete [] buf;
}
@ -253,15 +296,16 @@ namespace Poco {
void EnvironmentImpl::nodeIdImpl(NodeId& id)
{
std::memset(&id, 0, sizeof(id));
char name[MAXHOSTNAMELEN];
if (gethostname(name, sizeof(name)))
throw SystemException("cannot get host name");
return;
struct hostent* pHost = gethostbyname(name);
if (!pHost) throw SystemException("cannot get host IP address");
if (!pHost) return;
int s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (s == -1) throw SystemException("cannot open socket");
if (s == -1) return;
struct arpreq ar;
std::memset(&ar, 0, sizeof(ar));
@ -270,7 +314,7 @@ void EnvironmentImpl::nodeIdImpl(NodeId& id)
std::memcpy(&pAddr->sin_addr, *pHost->h_addr_list, sizeof(struct in_addr));
int rc = ioctl(s, SIOCGARP, &ar);
close(s);
if (rc < 0) throw SystemException("cannot get MAC address");
if (rc < 0) return;
std::memcpy(&id, ar.arp_ha.sa_data, sizeof(id));
}

View File

@ -123,15 +123,16 @@ std::string EnvironmentImpl::nodeNameImpl()
void EnvironmentImpl::nodeIdImpl(NodeId& id)
{
std::memset(&id, 0, sizeof(id));
char name[MAXHOSTNAMELEN];
if (gethostname(name, sizeof(name)))
throw SystemException("cannot get host name");
return;
struct hostent* pHost = gethostbyname(name);
if (!pHost) throw SystemException("cannot get host IP address");
if (!pHost) return;
int s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (s == -1) throw SystemException("cannot open socket");
if (s == -1) return;
struct arpreq ar;
std::memset(&ar, 0, sizeof(ar));
@ -140,7 +141,7 @@ void EnvironmentImpl::nodeIdImpl(NodeId& id)
std::memcpy(&pAddr->sin_addr, *pHost->h_addr_list, sizeof(struct in_addr));
int rc = ioctl(s, SIOCGARP, &ar);
close(s);
if (rc < 0) throw SystemException("cannot get MAC address");
if (rc < 0) return;
std::memcpy(&id, ar.arp_ha.sa_data, sizeof(id));
}

View File

@ -148,6 +148,8 @@ std::string EnvironmentImpl::nodeNameImpl()
void EnvironmentImpl::nodeIdImpl(NodeId& id)
{
std::memset(&id, 0, sizeof(id));
PIP_ADAPTER_INFO pAdapterInfo;
PIP_ADAPTER_INFO pAdapter = 0;
ULONG len = sizeof(IP_ADAPTER_INFO);
@ -162,31 +164,21 @@ void EnvironmentImpl::nodeIdImpl(NodeId& id)
}
else if (rc != ERROR_SUCCESS)
{
throw SystemException("cannot get network adapter list");
return;
}
try
if (GetAdaptersInfo(pAdapterInfo, &len) == NO_ERROR)
{
pAdapter = pAdapterInfo;
bool found = false;
if (GetAdaptersInfo(pAdapterInfo, &len) == NO_ERROR)
while (pAdapter && !found)
{
pAdapter = pAdapterInfo;
while (pAdapter && !found)
if (pAdapter->Type == MIB_IF_TYPE_ETHERNET && pAdapter->AddressLength == sizeof(id))
{
if (pAdapter->Type == MIB_IF_TYPE_ETHERNET && pAdapter->AddressLength == sizeof(id))
{
std::memcpy(&id, pAdapter->Address, pAdapter->AddressLength);
found = true;
}
pAdapter = pAdapter->Next;
found = true;
std::memcpy(&id, pAdapter->Address, pAdapter->AddressLength);
}
pAdapter = pAdapter->Next;
}
else throw SystemException("cannot get network adapter list");
if (!found) throw SystemException("no Ethernet adapter found");
}
catch (Exception&)
{
delete [] reinterpret_cast<char*>(pAdapterInfo);
throw;
}
delete [] reinterpret_cast<char*>(pAdapterInfo);
}

View File

@ -162,6 +162,8 @@ std::string EnvironmentImpl::nodeNameImpl()
void EnvironmentImpl::nodeIdImpl(NodeId& id)
{
std::memset(&id, 0, sizeof(id));
PIP_ADAPTER_INFO pAdapterInfo;
PIP_ADAPTER_INFO pAdapter = 0;
ULONG len = sizeof(IP_ADAPTER_INFO);
@ -176,31 +178,21 @@ void EnvironmentImpl::nodeIdImpl(NodeId& id)
}
else if (rc != ERROR_SUCCESS)
{
throw SystemException("cannot get network adapter list");
return;
}
try
if (GetAdaptersInfo(pAdapterInfo, &len) == NO_ERROR)
{
pAdapter = pAdapterInfo;
bool found = false;
if (GetAdaptersInfo(pAdapterInfo, &len) == NO_ERROR)
while (pAdapter && !found)
{
pAdapter = pAdapterInfo;
while (pAdapter && !found)
if (pAdapter->Type == MIB_IF_TYPE_ETHERNET && pAdapter->AddressLength == sizeof(id))
{
if (pAdapter->Type == MIB_IF_TYPE_ETHERNET && pAdapter->AddressLength == sizeof(id))
{
std::memcpy(&id, pAdapter->Address, pAdapter->AddressLength);
found = true;
}
pAdapter = pAdapter->Next;
found = true;
std::memcpy(&id, pAdapter->Address, pAdapter->AddressLength);
}
pAdapter = pAdapter->Next;
}
else throw SystemException("cannot get network adapter list");
if (!found) throw SystemException("no Ethernet adapter found");
}
catch (Exception&)
{
delete [] reinterpret_cast<char*>(pAdapterInfo);
throw;
}
delete [] reinterpret_cast<char*>(pAdapterInfo);
}