/SJQScripts/tools/src/com/google/code/sagetvaddons/groovy/api/UtilityHelpers.groovy
Groovy | 156 lines | 95 code | 10 blank | 51 comment | 15 complexity | e0d69aaace523fbe6536397045b50ee4 MD5 | raw file
Possible License(s): LGPL-2.0, BSD-3-Clause
- package com.google.code.sagetvaddons.groovy.api
-
- import org.apache.commons.lang.SystemUtils
-
- import sagex.api.Global
- import sagex.api.Utility
-
- /**
- * Additional utility methods to complement the SageTV utility API
- * @author dbattams
- * @version $Id: UtilityHelpers.groovy 1540 2011-06-11 15:20:44Z derek@battams.ca $
- */
- class UtilityHelpers {
-
- /**
- * Valid states a Windows service can be in; see MS SDK docs for more details on the meaning of these states
- * @author dbattams
- *
- */
- static enum WinServiceState {
- INVALID, // Dummy marker to make the indicies line up with the values received from Windows
- STOPPED,
- START_PENDING,
- STOP_PENDING,
- RUNNING,
- CONTINUE_PENDING,
- PAUSE_PENDING,
- PAUSED
- }
-
- /**
- * Query the Windows service controller for the state of the given service
- * @param serviceName The name of the Windows service to query
- * @return The current state of the given service, as reported by Windows; INVALID is returned if the service does not exist or another error occurs during the query
- * @throws UnsupportedOperationException If called on a non-Windows platform
- */
- static WinServiceState getWindowsServiceState(String serviceName) {
- if(!SystemUtils.IS_OS_WINDOWS)
- throw new UnsupportedOperationException('Method is only valid on MS Windows systems!')
- def cmd = "sc.exe query $serviceName"
- def p = cmd.execute()
- def stdout = new StringBuilder()
- p.consumeProcessOutputStream(stdout)
- p.waitFor()
- def state = WinServiceState.INVALID
- if(p.exitValue() == 0) {
- stdout.toString().eachMatch(/\s+STATE\s+: \d\s+(\w+)/) {
- try {
- state = WinServiceState.valueOf(it[1].toString().trim())
- } catch(IllegalArgumentException e) {
- //e.printStackTrace()
- }
- }
- }
- return state
- }
-
- /**
- * <p>Look up the MAC address for a given hostname/IP address</p>
- * <p>
- * This method will only succeed if the host is actively connected to the SageTV server. If
- * the host is not connected to the SageTV server then this method will <i>likely</i> return
- * null, though there is a slight chance, depending on the timing, that the ARP cache may still
- * contain the details for the hostname and will then return the desired result.
- * </p>
- * <p>
- * You may pass an IP address <i><b>OR</b></i> a hostname to this method, but if you decide to
- * use hostnames then they <b>must</b> be resolvable via DNS. This method does <b>NOT</b> use
- * the device aliases from <code>Sage.properties</code>. For best results, always use IP addresses
- * when possible.
- * </p>
- * @param host The hostname or IP address to get the MAC addrss for
- * @return The MAC address for the given host or null if it cannot be determined
- * @throws UnsupportedOperationException If called on an unsupported OS; currently only Windows and Linux are supported
- * @since 1.0.3
- */
- static String getMacAddrForHost(String host) throws UnsupportedOperationException {
- host = InetAddress.getByName(host).getHostAddress()
- def data
- if(Global.IsWindowsOS())
- data = getArpMapOnWindows()
- else if(Global.IsLinuxOS())
- data = getArpMapOnLinux()
- else
- throw new UnsupportedOperationException("Unable to get ARP map on this OS! [${Global.GetOS()}]")
- return data[host]
- }
-
- /**
- * <p>Look up the IP address for a given MAC address</p>
- * <p>
- * This method will only succeed if the host is actively connected to the SageTV server. If
- * the host is not connected to the SageTV server then this method will <i>likely</i> return
- * null, though there is a slight chance, depending on the timing, that the ARP cache may still
- * contain the details for the hostname and will then return the desired result.
- * </p>
- * @param mac The MAC address to get the IP address for; lowercase letters and numbers only
- * @return The IP address for the given MAC or null if it cannot be determined
- * @throws UnsupportedOperationException If called on an unsupported OS; currently only Windows and Linux are supported
- * @since 1.0.3
- */
- static String getIpAddrForMacAddr(String mac) throws UnsupportedOperationException {
- def data
- if(Global.IsWindowsOS())
- data = getArpMapOnWindows(false)
- else if(Global.IsLinuxOS())
- data = getArpMapOnLinux(false)
- else
- throw new UnsupportedOperationException("Unable to get ARP map on this OS! [${Global.GetOS()}]")
- return data[mac]
- }
-
- // Build the ARP cache map on Windows
- static private Map getArpMapOnWindows(def keyByIp = true) {
- def data = Utility.ExecuteProcessReturnOutput('arp', '-a', null, true, false)
- def map = [:]
- data.eachLine {
- def matches
- if((matches = it =~ /\s+((?:\d{1,3}\.){3}\d{1,3})\s+((?:[a-f0-9]{2}-){5}[a-f0-9]{2}).*/)) {
- def k, v
- if(keyByIp) {
- k = matches[0][1]
- v = matches[0][2].replaceAll('-', '')
- } else {
- k = matches[0][2].replaceAll('-', '')
- v = matches[0][1]
- }
- map[k] = v
- }
- }
- return map
- }
-
- // Build the ARP cache map on Linux
- static private Map getArpMapOnLinux(def keyByIp = true) {
- def data = Utility.ExecuteProcessReturnOutput('arp', '-an', null, true, false)
- def map = [:]
- data.eachLine {
- def matches
- if((matches = it =~ /\? \(((?:\d{1,3}\.){3}\d{1,3})\) at ((?:[a-f0-9]{2}:){5}[a-f0-9]{2}).*/)) {
- def k, v
- if(keyByIp) {
- k = matches[0][1]
- v = matches[0][2].replaceAll(':', '')
- } else {
- k = matches[0][2].replaceAll(':', '')
- v = matches[0][1]
- }
- map[k] = v
- }
- }
- return map
- }
-
- private UtilityHelpers() {}
- }