From c82b81964760f95b46d98fc681a08336661a9565 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Bl=C3=A4sing?= Date: Wed, 8 Nov 2017 20:37:51 +0100 Subject: [PATCH] Improve hostname functions Fix wrong mapping of libc function gethostname, sethostname, getdomainname and setdomainname. The functions are defined as: int getdomainname(char *name, size_t len); int setdomainname(const char *name, size_t len); int gethostname(char *name, size_t len); int sethostname(const char *name, size_t len); and a C char[] maps by default to a byte[] in java. In addition bind the winsock gethostname function: com.sun.jna.platform.win32.Winsock2.gethostname(byte[], int) The sethostname and setdomainname were tested manually, as changing the hostname is a privileged operation and is not regularly possible in unittests. This closes #871 --- CHANGES.md | 4 + .../com/sun/jna/platform/unix/LibCAPI.java | 8 +- .../com/sun/jna/platform/win32/Winsock2.java | 81 +++++++++++++++++++ .../com/sun/jna/platform/unix/LibCTest.java | 49 ++++++++--- .../sun/jna/platform/win32/Winsock2Test.java | 41 ++++++++++ 5 files changed, 169 insertions(+), 14 deletions(-) create mode 100644 contrib/platform/src/com/sun/jna/platform/win32/Winsock2.java create mode 100644 contrib/platform/test/com/sun/jna/platform/win32/Winsock2Test.java diff --git a/CHANGES.md b/CHANGES.md index 710df344ae..10394ad1a7 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -14,6 +14,7 @@ Bug Fixes * [#843](https://github.com/java-native-access/jna/pull/843): Correctly bind `com.sun.jna.platform.win32.SecBufferDesc` and add convenience binding as `com.sun.jna.platform.win32.SspiUtil.ManagedSecBufferDesc`. Bind SSPI functions `InitializeSecurityContext`, `AcceptSecurityContext`, `QueryCredentialsAttributes`, `QuerySecurityPackageInfo`, `EncryptMessage`, `DecryptMessage`, `MakeSignature`, `VerifySignature` in `com.sun.jna.platform.win32.Secur32` - [@matthiasblaesing](https://github.com/matthiasblaesing). * [#863](https://github.com/java-native-access/jna/pull/863): Fix ARM softfloat/hardfloat detection by modifying armSoftFloat condition in ELFAnalyser. Before this fix a softfloat binary could be misdetected as hardfloat. - [@kunkun26](https://github.com/kunkun26). * [#867](https://github.com/java-native-access/jna/issues/867): Fix memory leak in `COMLateBindingObject#getStringProperty` - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#871](https://github.com/java-native-access/jna/issues/871): Fix mapping of libc function `gethostname`, `sethostname`, `getdomainname` and `setdomainname` and bind `com.sun.jna.platform.win32.Winsock2.gethostname(byte[], int)` - [@matthiasblaesing](https://github.com/matthiasblaesing). Breaking Changes ---------------- @@ -39,6 +40,9 @@ Breaking Changes a `Class` as parameter. `T` was unconstraint and was modified to extend `com.sun.jna.Library`. This change is source compatible, but not binary compatbile, so bindings need to be recompiled. +* the parameters of the methods `gethostname`, `sethostname`, `getdomainname` + and `setdomainname` in the interface `com.sun.jna.platform.unix.LibCAPI` + were changed from `(char[] name, int len)` to `(byte[] name, int len)` * `com.sun.jna.platform.win32.Sspi.SecBufferDesc` was incompatibly changed to match the correct native semantics. SecBufferDesc describing more than one buffer were broken. For most usecases diff --git a/contrib/platform/src/com/sun/jna/platform/unix/LibCAPI.java b/contrib/platform/src/com/sun/jna/platform/unix/LibCAPI.java index 3a0edd2b05..0ec4e3824a 100644 --- a/contrib/platform/src/com/sun/jna/platform/unix/LibCAPI.java +++ b/contrib/platform/src/com/sun/jna/platform/unix/LibCAPI.java @@ -43,12 +43,12 @@ public interface LibCAPI extends Reboot, Resource { // see man(2) get/set hostname int HOST_NAME_MAX = 255; // not including the '\0' - int gethostname(char[] name, int len); - int sethostname(char[] name, int len); + int gethostname(byte[] name, int len); + int sethostname(String name, int len); // see man(2) get/set domainname - int getdomainname(char[] name, int len); - int setdomainname(char[] name, int len); + int getdomainname(byte[] name, int len); + int setdomainname(String name, int len); /** * @param name Environment variable name diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Winsock2.java b/contrib/platform/src/com/sun/jna/platform/win32/Winsock2.java new file mode 100644 index 0000000000..68c243e258 --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/win32/Winsock2.java @@ -0,0 +1,81 @@ +/* Copyright (c) 2017 Matthias Bläsing, All Rights Reserved + * + * The contents of this file is dual-licensed under 2 + * alternative Open Source/Free licenses: LGPL 2.1 or later and + * Apache License 2.0. (starting with JNA version 4.0.0). + * + * You can freely decide which license you want to apply to + * the project. + * + * You may obtain a copy of the LGPL License at: + * + * http://www.gnu.org/licenses/licenses.html + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "LGPL2.1". + * + * You may obtain a copy of the Apache License at: + * + * http://www.apache.org/licenses/ + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "AL2.0". + */ +package com.sun.jna.platform.win32; + +import com.sun.jna.Library; +import com.sun.jna.Native; +import com.sun.jna.win32.W32APIOptions; + +public interface Winsock2 extends Library { + + Winsock2 INSTANCE = (Winsock2) Native.loadLibrary("ws2_32", Winsock2.class, W32APIOptions.ASCII_OPTIONS); + + /** + * The gethostname function retrieves the standard host name for the local + * computer. + * + *

+ * Remarks

+ * + *

+ * The gethostname function returns the name of the local host into the + * buffer specified by the name parameter. The host name is returned as a + * null-terminated string. The form of the host name is dependent on the + * Windows Sockets provider—it can be a simple host name, or it can be a + * fully qualified domain name. However, it is guaranteed that the name + * returned will be successfully parsed by gethostbyname and + * WSAAsyncGetHostByName.

+ * + *

+ * The maximum length of the name returned in the buffer pointed to by the + * name parameter is dependent on the namespace provider.

+ * + *

+ * If the gethostname function is used on a cluster resource on Windows + * Server 2008, Windows Server 2003, or Windows 2000 Server and the + * _CLUSTER_NETWORK_NAME_ environment variable is defined, then the value in + * this environment variable overrides the actual hostname and is returned. + * On a cluster resource, the _CLUSTER_NETWORK_NAME_ environment variable + * contains the name of the cluster.

+ * + *

+ * The gethostname function queries namespace providers to determine the + * local host name using the SVCID_HOSTNAME GUID defined in the Svgguid.h + * header file. If no namespace provider responds, then the gethostname + * function returns the NetBIOS name of the local computer.

+ * + *

+ * The maximum length, in bytes, of the string returned in the buffer + * pointed to by the name parameter is dependent on the namespace provider, + * but this string must be 256 bytes or less. So if a buffer of 256 bytes is + * passed in the name parameter and the namelen parameter is set to 256, the + * buffer size will always be adequate.

+ * + * @param name A bytearray that receives the local host name. + * @param namelen The length, in bytes, of the buffer pointed to by the name parameter. + * @return If no error occurs, gethostname returns zero. Otherwise, it returns SOCKET_ERROR and a specific error code can be retrieved by calling WSAGetLastError. + */ + public int gethostname(byte[] name, int namelen); + +} diff --git a/contrib/platform/test/com/sun/jna/platform/unix/LibCTest.java b/contrib/platform/test/com/sun/jna/platform/unix/LibCTest.java index 5c5efa93b9..2bd741e97d 100644 --- a/contrib/platform/test/com/sun/jna/platform/unix/LibCTest.java +++ b/contrib/platform/test/com/sun/jna/platform/unix/LibCTest.java @@ -1,19 +1,33 @@ /* Copyright (c) 2015 Goldstein Lyor, All Rights Reserved * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. + * The contents of this file is dual-licensed under 2 + * alternative Open Source/Free licenses: LGPL 2.1 or later and + * Apache License 2.0. (starting with JNA version 4.0.0). + * + * You can freely decide which license you want to apply to + * the project. + * + * You may obtain a copy of the LGPL License at: + * + * http://www.gnu.org/licenses/licenses.html + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "LGPL2.1". + * + * You may obtain a copy of the Apache License at: + * + * http://www.apache.org/licenses/ + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "AL2.0". */ package com.sun.jna.platform.unix; +import com.sun.jna.Native; +import com.sun.jna.platform.win32.Kernel32Util; import java.sql.Date; import java.util.Map; +import static junit.framework.TestCase.assertTrue; import org.junit.Test; @@ -21,6 +35,7 @@ * @author Lyor Goldstein */ public class LibCTest extends AbstractUnixTestSupport { + public LibCTest() { super(); } @@ -48,7 +63,7 @@ public void testSetenv() { LibC.INSTANCE.unsetenv(name); } } - + @Test public void testGetLoadAvg() { double[] loadavg = new double[3]; @@ -58,4 +73,18 @@ public void testGetLoadAvg() { assertTrue(loadavg[1] >= 0); assertTrue(loadavg[2] >= 0); } + + @Test + public void testGethostnameGetdomainname() { + // This needs visual inspection ... + byte[] buffer = new byte[256]; + LibC.INSTANCE.gethostname(buffer, buffer.length); + String hostname = Native.toString(buffer); + System.out.println("Hostname: " + hostname); + assertTrue(hostname.length() > 0); + LibC.INSTANCE.getdomainname(buffer, buffer.length); + String domainname = Native.toString(buffer); + System.out.println("Domainname: " + domainname); + assertTrue(domainname.length() > 0); + } } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Winsock2Test.java b/contrib/platform/test/com/sun/jna/platform/win32/Winsock2Test.java new file mode 100644 index 0000000000..90aa088945 --- /dev/null +++ b/contrib/platform/test/com/sun/jna/platform/win32/Winsock2Test.java @@ -0,0 +1,41 @@ +/* Copyright (c) 2017 Matthias Bläsing, All Rights Reserved + * + * The contents of this file is dual-licensed under 2 + * alternative Open Source/Free licenses: LGPL 2.1 or later and + * Apache License 2.0. (starting with JNA version 4.0.0). + * + * You can freely decide which license you want to apply to + * the project. + * + * You may obtain a copy of the LGPL License at: + * + * http://www.gnu.org/licenses/licenses.html + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "LGPL2.1". + * + * You may obtain a copy of the Apache License at: + * + * http://www.apache.org/licenses/ + * + * A copy is also included in the downloadable source code package + * containing JNA, in file "AL2.0". + */ +package com.sun.jna.platform.win32; + +import com.sun.jna.Native; +import org.junit.Test; +import static org.junit.Assert.*; + +public class Winsock2Test { + @Test + public void testGethostname() { + // This needs visual inspection ... + byte[] buffer = new byte[256]; + Winsock2.INSTANCE.gethostname(buffer, buffer.length); + String hostname = Native.toString(buffer); + System.out.println("Hostname: " + hostname); + assertTrue(hostname.length() > 0); + } + +}