1 /* Copyright (C) 2003  Free Software Foundation
2 
3    This file is part of libgcj.
4 
5 This software is copyrighted work licensed under the terms of the
6 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
7 details.  */
8 
9 #include <config.h>
10 #include <platform.h>
11 
12 #undef STRICT
13 
14 #include <java/net/InetAddress.h>
15 #include <java/net/UnknownHostException.h>
16 #include <java/lang/SecurityException.h>
17 
18 jbyteArray
aton(jstring host)19 java::net::InetAddress::aton (jstring host)
20 {
21   JV_TEMP_UTF_STRING (hostname, host);
22   char* bytes = NULL;
23   int blen = 0;
24   unsigned long laddr = inet_addr (hostname);
25   if (laddr != INADDR_NONE)
26     {
27       bytes = (char*) &laddr;
28       blen = 4;
29     }
30   if (blen == 0)
31     return NULL;
32   jbyteArray result = JvNewByteArray (blen);
33   memcpy (elements (result), bytes, blen);
34   return result;
35 }
36 
37 jint
getFamily(jbyteArray bytes)38 java::net::InetAddress::getFamily (jbyteArray bytes)
39 {
40   int len = bytes->length;
41   if (len == 4)
42     return AF_INET;
43 #ifdef HAVE_INET6
44   else if (len == 16)
45     return AF_INET6;
46 #endif /* HAVE_INET6 */
47   else
48     JvFail ("unrecognized size");
49 }
50 
51 
52 JArray<java::net::InetAddress*> *
lookup(jstring host,java::net::InetAddress * iaddr,jboolean all)53 java::net::InetAddress::lookup (jstring host, java::net::InetAddress* iaddr,
54         jboolean all)
55 {
56   struct hostent *hptr = NULL;
57   if (host != NULL)
58     {
59       JV_TEMP_UTF_STRING (hostname, host);
60 
61       // FIXME: this is insufficient if some other piece of code calls
62       // this gethostbyname.
63       JvSynchronize sync (java::net::InetAddress::localhostAddress);
64       hptr = gethostbyname (hostname);
65     }
66   else
67     {
68       jbyteArray bytes = iaddr->addr;
69       char *chars = (char*) elements (bytes);
70       int len = bytes->length;
71       int type;
72       char *val;
73       if (len == 4)
74         {
75           val = chars;
76           type = iaddr->family = AF_INET;
77         }
78 #ifdef HAVE_INET6
79       else if (len == 16)
80       {
81         val = (char *) &chars;
82         type = iaddr->family = AF_INET6;
83       }
84 #endif /* HAVE_INET6 */
85       else
86         JvFail ("unrecognized size");
87 
88       // FIXME: this is insufficient if some other piece of code calls
89       // this gethostbyaddr.
90       JvSynchronize sync (java::net::InetAddress::localhostAddress);
91       hptr = gethostbyaddr (val, len, type);
92     }
93   if (hptr != NULL)
94     {
95       if (!all)
96         host = JvNewStringUTF (hptr->h_name);
97       java::lang::SecurityException *ex = checkConnect (host);
98       if (ex != NULL)
99         {
100           if (iaddr == NULL || iaddr->addr == NULL)
101             throw ex;
102           hptr = NULL;
103         }
104     }
105   if (hptr == NULL)
106     {
107       if (iaddr != NULL && iaddr->addr != NULL)
108         {
109           iaddr->hostName = iaddr->getHostAddress();
110           return NULL;
111         }
112       else
113         throw new java::net::UnknownHostException(host);
114     }
115 
116   int count;
117   if (all)
118     {
119       char** ptr = hptr->h_addr_list;
120       count = 0;
121       while (*ptr++)  count++;
122     }
123   else
124     count = 1;
125 
126   JArray<java::net::InetAddress*> *result;
127   java::net::InetAddress** iaddrs;
128   if (all)
129     {
130       result = java::net::InetAddress::allocArray (count);
131       iaddrs = elements (result);
132     }
133   else
134     {
135       result = NULL;
136       iaddrs = &iaddr;
137     }
138 
139   for (int i = 0;  i < count;  i++)
140     {
141       if (iaddrs[i] == NULL)
142         iaddrs[i] = new java::net::InetAddress (NULL, NULL);
143       if (iaddrs[i]->hostName == NULL)
144         iaddrs[i]->hostName = host;
145       if (iaddrs[i]->addr == NULL)
146         {
147           char *bytes = hptr->h_addr_list[i];
148           iaddrs[i]->addr = JvNewByteArray (hptr->h_length);
149           iaddrs[i]->family = getFamily (iaddrs[i]->addr);
150           memcpy (elements (iaddrs[i]->addr), bytes, hptr->h_length);
151         }
152     }
153 
154   return result;
155 }
156 
157 jstring
getLocalHostname()158 java::net::InetAddress::getLocalHostname ()
159 {
160   char buffer[400];
161   if (gethostname (buffer, sizeof(buffer)))
162     return NULL;
163   // It is admittedly non-optimal to convert the hostname to Unicode
164   // only to convert it back in getByName, but simplicity wins.  Note
165   // that unless there is a SecurityManager, we only get called once
166   // anyway, thanks to the InetAddress.localhost cache.
167   return JvNewStringUTF (buffer);
168 }
169