blob: 82c1e6f70025a1d8a9e501bc0e3b04057bdd8f6a [file] [log] [blame]
/* Copyright (C) 2003 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
#include <config.h>
#include <platform.h>
#undef STRICT
#include <java/net/InetAddress.h>
#include <java/net/UnknownHostException.h>
#include <java/lang/SecurityException.h>
jbyteArray
java::net::InetAddress::aton (jstring host)
{
JV_TEMP_UTF_STRING (hostname, host);
char* bytes = NULL;
int blen = 0;
unsigned long laddr = inet_addr (hostname);
if (laddr != INADDR_NONE)
{
bytes = (char*) &laddr;
blen = 4;
}
if (blen == 0)
return NULL;
jbyteArray result = JvNewByteArray (blen);
memcpy (elements (result), bytes, blen);
return result;
}
jint
java::net::InetAddress::getFamily (jbyteArray bytes)
{
int len = bytes->length;
if (len == 4)
return AF_INET;
#ifdef HAVE_INET6
else if (len == 16)
return AF_INET6;
#endif /* HAVE_INET6 */
else
JvFail ("unrecognized size");
}
JArray<java::net::InetAddress*> *
java::net::InetAddress::lookup (jstring host, java::net::InetAddress* iaddr,
jboolean all)
{
struct hostent *hptr = NULL;
if (host != NULL)
{
JV_TEMP_UTF_STRING (hostname, host);
// FIXME: this is insufficient if some other piece of code calls
// this gethostbyname.
JvSynchronize sync (java::net::InetAddress::loopbackAddress);
hptr = gethostbyname (hostname);
}
else
{
jbyteArray bytes = iaddr->addr;
char *chars = (char*) elements (bytes);
int len = bytes->length;
int type;
char *val;
if (len == 4)
{
val = chars;
type = iaddr->family = AF_INET;
}
#ifdef HAVE_INET6
else if (len == 16)
{
val = (char *) &chars;
type = iaddr->family = AF_INET6;
}
#endif /* HAVE_INET6 */
else
JvFail ("unrecognized size");
// FIXME: this is insufficient if some other piece of code calls
// this gethostbyaddr.
JvSynchronize sync (java::net::InetAddress::loopbackAddress);
hptr = gethostbyaddr (val, len, type);
}
if (hptr != NULL)
{
if (!all)
host = JvNewStringUTF (hptr->h_name);
java::lang::SecurityException *ex = checkConnect (host);
if (ex != NULL)
{
if (iaddr == NULL || iaddr->addr == NULL)
throw ex;
hptr = NULL;
}
}
if (hptr == NULL)
{
if (iaddr != NULL && iaddr->addr != NULL)
{
iaddr->hostName = iaddr->getHostAddress();
return NULL;
}
else
throw new java::net::UnknownHostException(host);
}
int count;
if (all)
{
char** ptr = hptr->h_addr_list;
count = 0;
while (*ptr++) count++;
}
else
count = 1;
JArray<java::net::InetAddress*> *result;
java::net::InetAddress** iaddrs;
if (all)
{
result = java::net::InetAddress::allocArray (count);
iaddrs = elements (result);
}
else
{
result = NULL;
iaddrs = &iaddr;
}
for (int i = 0; i < count; i++)
{
if (iaddrs[i] == NULL)
iaddrs[i] = new java::net::InetAddress (NULL, NULL);
if (iaddrs[i]->hostName == NULL)
iaddrs[i]->hostName = host;
if (iaddrs[i]->addr == NULL)
{
char *bytes = hptr->h_addr_list[i];
iaddrs[i]->addr = JvNewByteArray (hptr->h_length);
iaddrs[i]->family = getFamily (iaddrs[i]->addr);
memcpy (elements (iaddrs[i]->addr), bytes, hptr->h_length);
}
}
return result;
}
jstring
java::net::InetAddress::getLocalHostname ()
{
char buffer[400];
if (gethostname (buffer, sizeof(buffer)))
return NULL;
// It is admittedly non-optimal to convert the hostname to Unicode
// only to convert it back in getByName, but simplicity wins. Note
// that unless there is a SecurityManager, we only get called once
// anyway, thanks to the InetAddress.localhost cache.
return JvNewStringUTF (buffer);
}