Location: PHPKode > projects > Huygens Remote Manager > hrm/inc/Shell.inc
<?php
// This file is part of the Huygens Remote Manager
// Copyright and license notice: see license.txt

require_once("hrm_config.inc");
require_once("Fileserver.inc");

global $hucore, $hutask, $logdir;

$hucore = "hucore";
$hutask = "-noExecLog -checkUpdates disable -task";

Class ExternalProcess {
    public $pid;                         // os pid of the process
    public $host;                        // host on which the process will be started
    // TODO better manage multiple hosts
    public $huscript_path;               // HuScript executable path on host
    public $pipes;                       // pipes for commiunication with the process
    public $shell;                       // The shell process resource
    public $logfileName;                 // Name of the process error log
    public $descriptorSpec;
    // TODO better manage file handles
    public $out_file;                    // handle for the output file


    // This is temporary, remove before the final release and use the
    // first case only.
        
    
    function ExternalProcess($host, $huscript_path, $logfileName, $errfileName) {
        global $logdir;
        // Make sure to save into the log dir
        $logfileName = $logdir . "/" . $logfileName;
        $errfileName = $logdir . "/" . $errfileName;
        $this->descriptorSpec = array(
                                      0 => array("pipe", "r"),
                                      1 => array("file", $logfileName, "a"),
                                      2 => array("file", $errfileName, "a")
                                      );
        $this->host = $host;
        $this->huscript_path = $huscript_path;
        if (strpos($host, " ")) { 
            $components = explode(" ", $host);
            array_pop($components);
            $realHost = implode("", $components);
            $this->host = $realHost;
        } 
        $this->pid = NULL;
    } 
    
    // TODO refactor
    function existsHuygensProcess($pid) {
        global $logdir, $hucore;
        global $huygens_user;
        $answer = system("ssh $huygens_user" . '@' . $this->host . " " . "ps -p $pid | grep -e $hucore > " . $logdir . "/hrm_tmp" , $result); // -p
        if ($result==0) {return True;} 
        return False;
    } 
    
    function isHuygensProcessSleeping($pid) {
        global $logdir, $hucore;
        global $huygens_user;
        $answer = system("ssh $huygens_user" . '@' . $this->host . " " . "ps -lf -p " . "$pid | grep -e $hucore | grep -e S > " . $logdir . "/hrm_tmp",  $result);
        if ($result==0) {return True;} 
        return False;    
    } 
    
    function rewakeHuygensProcess($pid) {
        global $huygens_user;
        $answer = "none";
        ob_start();
        while ($answer != "") { 
            $answer = system("ssh $huygens_user" . '@' . $this->host . " '" . "ps -Alfd | sort | grep sshd | grep $huygens_user" . "'", $result);    
            $array = split('[ ]+', $answer);
            $pid = $array[3];
            $answer = system("ssh $huygens_user" . '@' . $this->host . " '" . "kill $pid" . "'", $result);          
            if (!$this->existsHuygensProcess($pid)) { break; }
        } 
        ob_end_clean();
    } 
    
    function ping() {
        global $logdir;
    	global $ping_command;
    	global $ping_parameter;
    	
    	$result = "";
    	$command = $ping_command . " " . $this->host . " " . $ping_parameter . " > ". $logdir . "/hrm_tmp";
        $answer = system($command, $result);
        if ($result == 0)
            return True;
        return False;   
    } 

    function pid() {
        return $this->pid;
    } 
    
    function runShell() {
        global $huygens_user;
        
        $this->shell = proc_open("bash", $this->descriptorSpec, $this->pipes);
        if (!is_resource($this->shell)) {
            return False;
        } 
        return True;
    } 

    function execute($command) {
        global $huygens_user;

        $cmd = 'ssh -f ' . $huygens_user . "@" . $this->host . " '" . $command . " ' \n";

        $ret = fwrite($this->pipes[0], $cmd );
        fflush($this->pipes[0]);
        report ("$cmd: $ret", 2);
        if ( $ret ) {
            // Why exiting here? This is commented out by now.
            # $ret = fwrite($this->pipes[0], "exit\n");
        }

        if ( $ret === False ) {
            return False;
        } else {
            // Asume execution success!!
            return True;
        }
    } 
    
    function pidFromString($input) {
        $result = -1;
        $numberOfHits = preg_match('/pid=([0-9]+)/', $input, $hits);
        if ($numberOfHits>0) {
            $result = $hits[1]; 
        }
        return $result;
    } 

  function read() {
    return fgets($this->pipes[1], 2048);      
  } 

  function runHuygensScript($scriptName) {
      global $hutask;
      $command = $this->huscript_path." $hutask \"".$scriptName."\"";
      // TODO better management of file handles
      //$out_file = fopen($this->descriptorSpec[1][1], "r");
      $this->out_file = fopen($this->descriptorSpec[1][1], "r");
      fseek($this->out_file, 0, SEEK_END);
      
      $this->execute($command);
      sleep(1);
      $found = False;
      while(!$found) {
          // TODO refactor
          if (feof($this->out_file)) return False;
          $input = fgets($this->out_file, 1024);
          $pid = $this->pidFromString($input);
          if ($pid != -1) { 
            $found = True;
            $this->pid = $pid;
          }
      }
      return $pid;
  }

  // TODO refactor
  function isJobWithPidRunning($pid) {
    $command = "ps -p $pid; ps -p $pid \n"; // -p
    $this->execute($command);
    $answer = '';
    $pipe = fopen($this->descriptorSpec[1][1], "r");
    fseek($pipe, 0, SEEK_END);
    $line = fgets($pipe, 1024);
    $answer = $answer . $line;
    if (!feof($pipe)) {
      $line = fgets($pipe, 1024);
      $answer = $answer . $line;
    } 
    $result = (strstr($answer, "\n" . $pid . " "));
    return $result;
  } 

  function release() {
    // close pipes
    fclose($this->pipes[0]);
    // TODO check why stdout and stderr are not closed
    @fclose($this->pipes[1]);
    @fclose($this->pipes[2]);
    // TODO better management of file handles
    @fclose($this->out_file);
    $result = proc_close($this->shell);
    report("released external process", 2);
  }
  
  function killHucoreProcess($pid) {    
    $command = "kill " . $pid;
    $result = True;
    $result = $result && $this->runShell();
    if ($result) {
        $result = $result && $this->execute($command);
    }
    return $result;
  }
}

Class LocalExternalProcess extends ExternalProcess {

  function LocalExternalProcess($host, $huscript_path, $logfileName, $errfileName) {
    $this->ExternalProcess($host, $huscript_path, $logfileName, $errfileName);
  }
 
  function existsHuygensProcess($pid) {
    global $huygens_user, $hucore;
    global $logdir;
    $answer = system("ps -p $pid | grep -e $hucore > ".$logdir."/hrm_tmp" , $result);
    if ($result==0) {return True;} 
    return False;
  } 

  function isHuygensProcessSleeping($pid) {
    //    global $huygens_user, $hucore;
    //    $answer = system("ps -lf -p " ."$pid | grep -e $hucore | grep -e S > hrm_tmp",  $result);
    //    if ($result==0) {return True;} 
    return False;    
  }  

  function rewakeHuygensProcess($pid) {
    // global $huygens_user;
    // hang up shouldn't happen with local external process
    // therefore nothin to do
   
  }

  function execute($command) {
    global $huygens_user;
    $ret = fwrite($this->pipes[0], $command . " & \n" );
    fflush($this->pipes[0]);
    if ($ret === false) {
        // Can't write to pipe.
        return False;
    } else {
        sleep(5);
        // Asume execution success!!
        return True;
    }

  }

  function ping() {
      // machine can always reach itself.
      return True;
  }  

  function runShell() {
      global $huygens_user;
      $this->shell = proc_open("sh", $this->descriptorSpec, $this->pipes);
      if (!is_resource($this->shell)) {
          return False;
      } 
      return True;
  }

  function isJobWithPidRunning($pid) {
      $command = "ps -p $pid; ps -p $pid \n";
      $this->execute($command);
      $answer = '';
      $pipe = $this->pipes[1];
      $line = fgets($pipe, 1024);
      $answer = $answer . $line;
      if (!feof($pipe)) {
          $line = fgets($pipe, 1024);
          $answer = $answer . $line;
      } 
      $result = (strstr($answer, "\n" . $pid . " "));
      return $result;
  }

  function killHucoreProcess($pid) {    
      $dead = posix_kill($pid,15);
      return $dead;
  }

}  

?>
Return current item: Huygens Remote Manager