/* This file is part of JFLICKS. JFLICKS is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. JFLICKS 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 General Public License for more details. You should have received a copy of the GNU General Public License along with JFLICKS. If not, see <http://www.gnu.org/licenses/>. */ package org.jflicks.util; import java.io.File; import java.net.InetAddress; import java.net.InterfaceAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.net.UnknownHostException; import java.util.Enumeration; import java.util.List; import org.jflicks.job.SystemJob; import org.jflicks.job.JobContainer; import org.jflicks.job.JobManager; /** * A class that will find out the hostname of the local machine. * * @author Doug Barnum * @version 1.0 */ public final class Hostname { private Hostname() { } /** * Try to determine the IP of the local machine. A machine may actually * have several addresses associated with it. What we want to do is find * one that is not a loopback address. We want a "real" one that we can * use for communicating with other machines on the local network. * * @return A String representing an IP address. */ public static String getHostname() { String result = null; // This should work on Linux and Windows - not sure about OS/X. SystemJob job = SystemJob.getInstance("hostname"); JobContainer jc = JobManager.getJobContainer(job); jc.start(); boolean done = false; int count = 0; while (jc.isAlive()) { if (!jc.isAlive()) { done = true; } else { count += 100; if (count > 2900) { done = true; } else { JobManager.sleep(100); } } } result = job.getOutputText(); if (result != null) { result = result.trim(); } return (result); } public static InetAddress getInetAddressViaNetworkInterface() { InetAddress result = null; try { Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces(); if (e != null) { boolean done = false; while ((e.hasMoreElements()) && (!done)) { NetworkInterface ni = e.nextElement(); if ((!ni.isLoopback()) && (ni.isUp())) { List<InterfaceAddress> elist = ni.getInterfaceAddresses(); if (elist != null) { for (int i = 0; i < elist.size(); i++) { InterfaceAddress addr = elist.get(i); if (addr.getBroadcast() != null) { InetAddress inet = addr.getAddress(); if (!isLoopback(inet.getHostAddress())) { result = inet; done = true; } } } } } } } } catch (SocketException ex) { } return (result); } public static String getHostAddressViaNetworkInterface() { String result = null; try { Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces(); if (e != null) { boolean done = false; while ((e.hasMoreElements()) && (!done)) { NetworkInterface ni = e.nextElement(); if ((!ni.isLoopback()) && (ni.isUp())) { Enumeration<InetAddress> einet = ni.getInetAddresses(); if (einet != null) { while ((einet.hasMoreElements()) && (!done)) { InetAddress inet = einet.nextElement(); String tmp = inet.getHostAddress(); if (!isLoopback(tmp)) { result = tmp; done = true; } } } } } } } catch (SocketException ex) { } return (result); } /** * Find the local machine IP address. First we lookup using the java * InetAddress object for localhost. Sometimes this will return a * loopback address. If so lets look further to get all the addresses * for the hostname of this machine. Perhaps we will find a non-loopback * address we can use to communicate on the local network. * * @return A String representing an IP address. */ public static String getHostAddress() { String result = null; try { // First see if localhost returns the right thing... result = InetAddress.getLocalHost().getHostAddress(); if (result != null) { if (isLoopback(result)) { // Next lets look at the NetworkInterfaces route... result = getHostAddressViaNetworkInterface(); if (isLoopback(result)) { // We got the loopback - lets try the hostname route... String hname = getHostname(); if (hname != null) { // Get all that we have. InetAddress[] addrs = InetAddress.getAllByName(hname); if ((addrs != null) && (addrs.length > 0)) { for (int i = 0; i < addrs.length; i++) { result = addrs[i].getHostAddress(); if (!isLoopback(result)) { // We take the first non-loopback.... break; } } } else { // Give up and return loopback... result = "127.0.0.1"; } } else { // Give up and return loopback... result = "127.0.0.1"; } } else { // Give up and return loopback... result = "127.0.0.1"; } } } else { // Give up and return loopback... result = "127.0.0.1"; } } catch (UnknownHostException ex) { // Give up and return loopback... result = "127.0.0.1"; } return (result); } /** * Find the local machine InetAddress. First we lookup using the java * InetAddress object for localhost. Sometimes this will return a * loopback address. If so lets look further to get all the addresses * for the hostname of this machine. Perhaps we will find a non-loopback * address we can use to communicate on the local network. * * @return An InetAddress instance. */ public static InetAddress getLocalhostAddress() { InetAddress result = null; try { // First see if localhost returns the right thing... String ip = InetAddress.getLocalHost().getHostAddress(); if (ip != null) { if (isLoopback(ip)) { // Next lets look at the NetworkInterfaces route... result = getInetAddressViaNetworkInterface(); if (isLoopback(result)) { // We got the loopback - lets try the hostname route... String hname = getHostname(); if (hname != null) { // Get all that we have. InetAddress[] addrs = InetAddress.getAllByName(hname); if ((addrs != null) && (addrs.length > 0)) { for (int i = 0; i < addrs.length; i++) { ip = addrs[i].getHostAddress(); if (!isLoopback(ip)) { // We take the first non-loopback.... result = addrs[i]; break; } } } } } } else { result = InetAddress.getLocalHost(); } } } catch (UnknownHostException ex) { } if ((result == null) && (Util.isLinux())) { result = checkLinux(); } return (result); } public static InetAddress checkLinux() { InetAddress result = null; // If we have gotten here then the /etc/hosts is not set right. So // let's look for /etc/network/interfaces and try to get a static // IP there. String[] lines = Util.readTextFile(new File("/etc/network/interfaces")); if (lines != null) { boolean found = false; for (int i = 0; i < lines.length; i++) { String tmp = lines[i].trim(); if (!found) { if (tmp.startsWith("iface eth0 inet static")) { found = true; } } else { if (tmp.startsWith("address")) { tmp = tmp.substring(tmp.indexOf(" ")); tmp = tmp.trim(); try { result = InetAddress.getByName(tmp); } catch (UnknownHostException ex) { } break; } } } } return (result); } /** * Convenience method to examine a given String to see if it looks like * a loopback address. * * @param s A given String representing an address. * @return True if it looks like a loopback address. */ public static boolean isLoopback(String s) { boolean result = false; if (s != null) { if ((s.startsWith("127")) || (s.startsWith("0:0:0:0"))) { result = true; } } return (result); } public static boolean isLoopback(InetAddress inet) { boolean result = true; if (inet != null) { try { result = isLoopback(inet.getLocalHost().getHostAddress()); } catch (UnknownHostException ex) { } } return (result); } }