/** Called by the current ClockSyncProvider after each Clock synchronization */
  public void onClockUpdate(long offset) {

    s_logger.info("Clock update. Offset: {}", offset);

    // set system clock if necessary
    boolean bClockUpToDate = false;
    if (offset != 0) {
      long time = System.currentTimeMillis() + offset;
      SafeProcess proc = null;
      try {
        proc = ProcessUtil.exec("date -s @" + time / 1000); // divide by 1000 to switch to seconds
        proc.waitFor();
        if (proc.exitValue() == 0) {
          bClockUpToDate = true;
          s_logger.info("System Clock Updated to {}", new Date());
        } else {
          s_logger.error(
              "Unexpected error while updating System Clock - it should've been {}", new Date());
        }
      } catch (Exception e) {
        s_logger.error("Error updating System Clock", e);
      } finally {
        if (proc != null) ProcessUtil.destroy(proc);
      }
    } else {
      bClockUpToDate = true;
    }

    // set hardware clock
    boolean updateHwClock = false;
    if (m_properties.containsKey("clock.set.hwclock")) {
      updateHwClock = (Boolean) m_properties.get("clock.set.hwclock");
    }
    if (updateHwClock) {
      SafeProcess proc = null;
      try {
        proc = ProcessUtil.exec("hwclock --utc --systohc");
        proc.waitFor();
        if (proc.exitValue() == 0) {
          s_logger.info("Hardware Clock Updated");
        } else {
          s_logger.error("Unexpected error while updating Hardware Clock");
        }
      } catch (Exception e) {
        s_logger.error("Error updating Hardware Clock", e);
      } finally {
        if (proc != null) ProcessUtil.destroy(proc);
      }
    }

    // Raise the event
    if (bClockUpToDate) {
      m_eventAdmin.postEvent(new ClockEvent(new HashMap<String, Object>()));
    }
  }
  public void addStaticRoute(
      IPAddress destination, IPAddress gateway, IPAddress netmask, String iface, int metric)
      throws Exception {
    RouteConfig tmpRoute = null;
    StringBuffer command = new StringBuffer();
    command.append("route add -net " + destination.getHostAddress() + " ");
    if (netmask != null) {
      command.append("netmask " + netmask.getHostAddress() + " ");
    }
    if (gateway != null) {
      if ((gateway.getHostAddress().compareTo("0.0.0.0") != 0)
          && (gateway.getHostAddress().compareTo("127.0.0.1") != 0)) {
        command.append("gw " + gateway.getHostAddress() + " ");
      }
    }
    if (iface != null) {
      command.append("dev " + iface + " ");
    }
    if (metric != 0 && metric != -1) {
      command.append("metric " + metric);
    }

    SafeProcess proc = null;
    try {
      s_logger.debug("Executing command:  " + command.toString());
      proc = ProcessUtil.exec(command.toString());
      proc.waitFor();
      if (proc.exitValue() != 0) {
        s_logger.error("Error adding static Route: " + command.toString());
        throw new Exception("Error adding Static Route");
      }
    } catch (IOException e) {
      s_logger.error("Error executing command:  route -n");
      throw e;
    } finally {
      if (proc != null) ProcessUtil.destroy(proc);
    }

    if (destination instanceof IP4Address) {
      tmpRoute =
          new RouteConfigIP4(
              (IP4Address) destination, (IP4Address) gateway, (IP4Address) netmask, iface, -1);
    } else if (destination instanceof IP6Address) {
      tmpRoute =
          new RouteConfigIP6(
              (IP6Address) destination, (IP6Address) gateway, (IP6Address) netmask, iface, -1);
    }
    s_logger.info("Static route added successfully");
    s_logger.debug(tmpRoute.getDescription());
  }
  public RouteConfig[] getRoutes() {
    String routeEntry = null;
    ArrayList<RouteConfig> routeList = new ArrayList<RouteConfig>();
    RouteConfig[] routes = null;
    RouteConfig tmpRoute = null;
    SafeProcess proc = null;
    BufferedReader br = null;
    try {
      proc = ProcessUtil.exec("route -n");
      proc.waitFor();
      br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
      br.readLine();
      br.readLine();
      while ((routeEntry = br.readLine()) != null) {
        tmpRoute = entryToRoute(routeEntry);
        if (tmpRoute != null) {
          routeList.add(tmpRoute);
        }
      }
    } catch (Exception e) {
      s_logger.error("Error executing command:  route -n", e);
      return null;
    } finally {
      if (br != null) {
        try {
          br.close();
        } catch (IOException ex) {
          s_logger.error("I/O Exception while closing BufferedReader!");
        }
      }
      if (proc != null) ProcessUtil.destroy(proc);
    }

    routes = new RouteConfig[routeList.size()];
    for (int i = 0; i < routes.length; i++) {
      routes[i] = (RouteConfig) routeList.get(i);
    }

    return routes;
  }
 private static String runSystemInfoCommand(String[] commands) {
   StringBuffer response = new StringBuffer();
   SafeProcess proc = null;
   BufferedReader br = null;
   try {
     proc = ProcessUtil.exec(commands);
     proc.waitFor();
     br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
     String line = null;
     String newLine = "";
     while ((line = br.readLine()) != null) {
       response.append(newLine);
       response.append(line);
       newLine = "\n";
     }
   } catch (Exception e) {
     StringBuilder command = new StringBuilder();
     String delim = "";
     for (int i = 0; i < commands.length; i++) {
       command.append(delim);
       command.append(commands[i]);
       delim = " ";
     }
     s_logger.error("failed to run commands " + command.toString(), e);
   } finally {
     if (br != null) {
       try {
         br.close();
       } catch (IOException ex) {
         s_logger.error("I/O Exception while closing BufferedReader!");
       }
     }
     if (proc != null) {
       ProcessUtil.destroy(proc);
     }
   }
   return response.toString();
 }
  @Override
  public String getPrimaryMacAddress() {
    String primaryNetworkInterfaceName = getPrimaryNetworkInterfaceName();
    String macAddress = null;

    if (OS_MAC_OSX.equals(getOsName())) {
      SafeProcess proc = null;
      try {
        s_logger.info("executing: ifconfig and looking for " + primaryNetworkInterfaceName);
        proc = ProcessUtil.exec("ifconfig");
        BufferedReader br = null;
        try {
          proc.waitFor();
          br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
          String line = null;
          while ((line = br.readLine()) != null) {
            if (line.startsWith(primaryNetworkInterfaceName)) {
              // get the next line and save the MAC
              line = br.readLine();
              if (line == null) {
                throw new IOException("Null imput!");
              }
              if (!line.trim().startsWith("ether")) {
                line = br.readLine();
              }
              String[] splitLine = line.split(" ");
              if (splitLine.length > 0) {
                return splitLine[1].toUpperCase();
              }
            }
          }
        } catch (InterruptedException e) {
          s_logger.error("Exception while executing ifconfig!", e);
        } finally {
          if (br != null) {
            try {
              br.close();
            } catch (IOException ex) {
              s_logger.error("I/O Exception while closing BufferedReader!");
            }
          }
        }
      } catch (Exception e) {
        s_logger.error("Failed to get network interfaces", e);
      } finally {
        if (proc != null) {
          ProcessUtil.destroy(proc);
        }
      }
    } else {
      try {
        List<NetInterface<? extends NetInterfaceAddress>> interfaces =
            m_networkService.getNetworkInterfaces();
        if (interfaces != null) {
          for (NetInterface<? extends NetInterfaceAddress> iface : interfaces) {
            if (iface.getName() != null
                && getPrimaryNetworkInterfaceName().equals(iface.getName())) {
              macAddress = NetUtil.hardwareAddressToString(iface.getHardwareAddress());
              break;
            }
          }
        }
      } catch (KuraException e) {
        s_logger.error("Failed to get network interfaces", e);
      }
    }

    return macAddress;
  }