PageRenderTime 25ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/SJQScripts/tools/src/com/google/code/sagetvaddons/groovy/api/UtilityHelpers.groovy

http://sagetv-addons.googlecode.com/
Groovy | 156 lines | 95 code | 10 blank | 51 comment | 15 complexity | e0d69aaace523fbe6536397045b50ee4 MD5 | raw file
Possible License(s): LGPL-2.0, BSD-3-Clause
  1. package com.google.code.sagetvaddons.groovy.api
  2. import org.apache.commons.lang.SystemUtils
  3. import sagex.api.Global
  4. import sagex.api.Utility
  5. /**
  6. * Additional utility methods to complement the SageTV utility API
  7. * @author dbattams
  8. * @version $Id: UtilityHelpers.groovy 1540 2011-06-11 15:20:44Z derek@battams.ca $
  9. */
  10. class UtilityHelpers {
  11. /**
  12. * Valid states a Windows service can be in; see MS SDK docs for more details on the meaning of these states
  13. * @author dbattams
  14. *
  15. */
  16. static enum WinServiceState {
  17. INVALID, // Dummy marker to make the indicies line up with the values received from Windows
  18. STOPPED,
  19. START_PENDING,
  20. STOP_PENDING,
  21. RUNNING,
  22. CONTINUE_PENDING,
  23. PAUSE_PENDING,
  24. PAUSED
  25. }
  26. /**
  27. * Query the Windows service controller for the state of the given service
  28. * @param serviceName The name of the Windows service to query
  29. * @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
  30. * @throws UnsupportedOperationException If called on a non-Windows platform
  31. */
  32. static WinServiceState getWindowsServiceState(String serviceName) {
  33. if(!SystemUtils.IS_OS_WINDOWS)
  34. throw new UnsupportedOperationException('Method is only valid on MS Windows systems!')
  35. def cmd = "sc.exe query $serviceName"
  36. def p = cmd.execute()
  37. def stdout = new StringBuilder()
  38. p.consumeProcessOutputStream(stdout)
  39. p.waitFor()
  40. def state = WinServiceState.INVALID
  41. if(p.exitValue() == 0) {
  42. stdout.toString().eachMatch(/\s+STATE\s+: \d\s+(\w+)/) {
  43. try {
  44. state = WinServiceState.valueOf(it[1].toString().trim())
  45. } catch(IllegalArgumentException e) {
  46. //e.printStackTrace()
  47. }
  48. }
  49. }
  50. return state
  51. }
  52. /**
  53. * <p>Look up the MAC address for a given hostname/IP address</p>
  54. * <p>
  55. * This method will only succeed if the host is actively connected to the SageTV server. If
  56. * the host is not connected to the SageTV server then this method will <i>likely</i> return
  57. * null, though there is a slight chance, depending on the timing, that the ARP cache may still
  58. * contain the details for the hostname and will then return the desired result.
  59. * </p>
  60. * <p>
  61. * You may pass an IP address <i><b>OR</b></i> a hostname to this method, but if you decide to
  62. * use hostnames then they <b>must</b> be resolvable via DNS. This method does <b>NOT</b> use
  63. * the device aliases from <code>Sage.properties</code>. For best results, always use IP addresses
  64. * when possible.
  65. * </p>
  66. * @param host The hostname or IP address to get the MAC addrss for
  67. * @return The MAC address for the given host or null if it cannot be determined
  68. * @throws UnsupportedOperationException If called on an unsupported OS; currently only Windows and Linux are supported
  69. * @since 1.0.3
  70. */
  71. static String getMacAddrForHost(String host) throws UnsupportedOperationException {
  72. host = InetAddress.getByName(host).getHostAddress()
  73. def data
  74. if(Global.IsWindowsOS())
  75. data = getArpMapOnWindows()
  76. else if(Global.IsLinuxOS())
  77. data = getArpMapOnLinux()
  78. else
  79. throw new UnsupportedOperationException("Unable to get ARP map on this OS! [${Global.GetOS()}]")
  80. return data[host]
  81. }
  82. /**
  83. * <p>Look up the IP address for a given MAC address</p>
  84. * <p>
  85. * This method will only succeed if the host is actively connected to the SageTV server. If
  86. * the host is not connected to the SageTV server then this method will <i>likely</i> return
  87. * null, though there is a slight chance, depending on the timing, that the ARP cache may still
  88. * contain the details for the hostname and will then return the desired result.
  89. * </p>
  90. * @param mac The MAC address to get the IP address for; lowercase letters and numbers only
  91. * @return The IP address for the given MAC or null if it cannot be determined
  92. * @throws UnsupportedOperationException If called on an unsupported OS; currently only Windows and Linux are supported
  93. * @since 1.0.3
  94. */
  95. static String getIpAddrForMacAddr(String mac) throws UnsupportedOperationException {
  96. def data
  97. if(Global.IsWindowsOS())
  98. data = getArpMapOnWindows(false)
  99. else if(Global.IsLinuxOS())
  100. data = getArpMapOnLinux(false)
  101. else
  102. throw new UnsupportedOperationException("Unable to get ARP map on this OS! [${Global.GetOS()}]")
  103. return data[mac]
  104. }
  105. // Build the ARP cache map on Windows
  106. static private Map getArpMapOnWindows(def keyByIp = true) {
  107. def data = Utility.ExecuteProcessReturnOutput('arp', '-a', null, true, false)
  108. def map = [:]
  109. data.eachLine {
  110. def matches
  111. if((matches = it =~ /\s+((?:\d{1,3}\.){3}\d{1,3})\s+((?:[a-f0-9]{2}-){5}[a-f0-9]{2}).*/)) {
  112. def k, v
  113. if(keyByIp) {
  114. k = matches[0][1]
  115. v = matches[0][2].replaceAll('-', '')
  116. } else {
  117. k = matches[0][2].replaceAll('-', '')
  118. v = matches[0][1]
  119. }
  120. map[k] = v
  121. }
  122. }
  123. return map
  124. }
  125. // Build the ARP cache map on Linux
  126. static private Map getArpMapOnLinux(def keyByIp = true) {
  127. def data = Utility.ExecuteProcessReturnOutput('arp', '-an', null, true, false)
  128. def map = [:]
  129. data.eachLine {
  130. def matches
  131. if((matches = it =~ /\? \(((?:\d{1,3}\.){3}\d{1,3})\) at ((?:[a-f0-9]{2}:){5}[a-f0-9]{2}).*/)) {
  132. def k, v
  133. if(keyByIp) {
  134. k = matches[0][1]
  135. v = matches[0][2].replaceAll(':', '')
  136. } else {
  137. k = matches[0][2].replaceAll(':', '')
  138. v = matches[0][1]
  139. }
  140. map[k] = v
  141. }
  142. }
  143. return map
  144. }
  145. private UtilityHelpers() {}
  146. }