start
//
// Starts an instance of the Shell and sets the info needed to
// connect to it to session variables.
//
function start ( $user, $pass = "" ) {
// The Helga Shell executable is called helgatcp, as it allows communication
// via a TCP port. We want this program to run in the background, but we also
// need to collect certain info from it, such as port number, session ID, etc.
// So we'll get it to write its output to a temp file.
// Choose a file name.
$fileName = $_ENV['HELGAROOT'] . '/site/tmp/helgatcp.' . time() . '.log';
// Build the command string.
$cmd = $_ENV['HELGAROOT'] . '/dist/' . $_ENV['HELGAVERSION'] . '/shell/helgatcp ' . $user;
if ( $pass != "" ) {
$cmd .= ' ' . md5($pass);
}
$cmd .= ' > ' . $fileName . ' 2>&1 &';
// Execute the command.
shell_exec( $cmd );
// Use tail -n 1 to get the last line of the file, which should contain our
// session info. The Shell can take a few seconds to come to life, especially
// if it hasn't been run in a while, so we'll give it a few changes, waiting for
// a second each time.
$sessionInfo = "";
$count = 1;
$maxCount = 10;
while ( $sessionInfo == "" && $count < $maxCount ) {
sleep( 1 );
$sessionInfo = shell_exec( "tail -n 1 $fileName" );
$count++;
}
// The keyword "file" indicates we got an error, because Tcl's error messages
// indicate which file and line an error occurred in. normal session output
// will not include the word "file". if we find a "file", however, search our
// output for other indicators of what went wrong.
if ( substr($sessionInfo, 5, 4) == 'file' ) {
$fileText = file_get_contents($fileName);
if ( strpos($fileText, "incorrect password") !== false ) {
$this->printLogin( "Incorrect password." );
} elseif ( strpos($fileText, "does not exist") ) {
$this->printLogin( "User $user does not exist." );
} else {
die('Unknown error while starting the Helga Shell:
' . nl2br($fileText));
}
}
// Our session info comes back as a JSON object. Use json_decode to turn this into
// an associative array.
$sessionObj = json_decode($sessionInfo, true);
// Set session variables based on the info we got back from the Shell.
$_SESSION['helga_sid'] = $sessionObj['id'];
$_SESSION['port'] = $sessionObj['port'];
// Delete the temp file.
unlink( $fileName );
}
function exec ( $cmd ) {
if ( !isset( $_SESSION['port'] ) ) {
$this->printLogin();
}
$sock = fsockopen( "127.0.0.1", $_SESSION['port'], $errno, $errstr );
if ( !$sock ) {
die( "Error: opening response socket: $errstr" );
}
$output = "";
fwrite( $sock, "$cmd\n" );
while ( !feof($sock) ) {
$output .= fgets($sock);
}
fclose( $sock );
$output = rtrim($output);
$outputSplit = explode( " ", $output );
if ( $outputSplit[0] == "Error:" ) {
if ( $output == 'Error: session expired' ) {
header('Location: logout.php');
} else {
throw new Exception($output);
}
}
return $output;
}
function decode ( $json ) {
$out = $json;
$out = trim($out);
$out = trim($out,"()");
if ( $out[0] == "[" ) {
$out = trim($out,"[]");
$out = "array($out)";
}
$out = str_replace("{","json_decode('{",$out);
$out = str_replace("}","}')",$out);
$out = '$outString = ' . $out . ';';
eval($out);
return $outString;
}
function printLogin ( $error = "" ) {
$SERVER_NAME = $_SERVER["SERVER_NAME"];
$ip = gethostbyname( $SERVER_NAME );
$server = gethostbyaddr( $ip );
// build string of get variables so they are passed on
$getString = '';
if ( count( $_GET ) > 0 ) {
$getString .= '?';
foreach($_GET as $key => $val) {
$getString .= ($getString == '?' ? '' : '&') . htmlspecialchars("$key=$val");
}
}
// do the same for all post vars
$postString = '';
foreach ($_POST as $key => $val) {
$postString .= "\t\t\t" . '' . "\n";
}
echo '