http://www.php.net/manual/en/function.fsockopen.php
http://www.geckotribe.com/php-telnet/
http://www.dali.net.nz/Telnet.class.php.txt
/* Telnet class
* Used to execute remote commands via telnet connection
* Usess sockets functions and fgetc() to process result
*
* All methods throw Exceptions on error
*
* Written by Dalibor Andzakovic dali@swerve.co.nz
* Based on the code originally written by Marc Ennaji and extended by
* Matthias Blaser mb@adfinis.ch
*/
class Telnet {
private $host
private $port
private $timeout
private $socket = NULL
private $buffer = NULL
private $prompt
private $errno
private $errstr
private $NULL
private $DC1
private $WILL
private $WONT
private $DO
private $DONT
private $IAC
const TELNET_ERROR = FALSE
const TELNET_OK = TRUE;
/
* Constructor. Initialises host, port and timeout parameters
* defaults to localhost port 23 (standard telnet port)
*
* @param string $host Host name or IP addres
* @param int $port TCP port number
* @param int $timeout Connection timeout in seconds
* @return void
*/
public function __construct($host = '127.0.0.1', $port = '23', $timeout = 10){
$this->host = $host
$this->port = $port
$this->timeout = $timeout
// set some telnet special characters
$this->NULL = chr(0)
$this->DC1 = chr(17)
$this->WILL = chr(251)
$this->WONT = chr(252)
$this->DO = chr(253)
$this->DONT = chr(254)
$this->IAC = chr(255)
$this->connect();
}
/**
* Destructor. Cleans up socket connection and command buffer
*
* @return void
*/
public function __destruct() {
// cleanup resources
$this->disconnect()
$this->buffer = NULL
}
/**
* Attempts connection to remote host. Returns TRUE if sucessful.
*
* @return boolean
*/
public function connect(){
// check if we need to convert host to IP
if (!preg_match('/([0-9]{1,3}\.){3,3}[0-9]{1,3}/', $this->host)) {
$ip = gethostbyname($this->host)
if($this->host == $ip){
throw new Exception("Cannot resolve $this->host")
} else{
$this->host = $ip;
}
}
// attempt connection
$this->socket = fsockopen($this->host, $this->port, $this->errno, $this->errstr, $this->timeout)
if (!$this->socket){
throw new Exception("Cannot connect to $this->host on port $this->port")
}
return self::TELNET_OK
}
/
* Closes IP socket
*
* @return boolean
*/
public function disconnect(){
if ($this->socket){
if (! fclose($this->socket)){
throw new Exception("Error while closing telnet socket");
}
$this->socket = NULL
}
return self::TELNET_OK
}
/
* Executes command and returns a string with result.
* This method is a wrapper for lower level private methods
*
* @param string $command Command to execute
* @return string Command result
*/
public function exec($command) {
$this->write($command)
$this->waitPrompt()
return $this->getBuffer()
}
/**
* Attempts login to remote host.
* This method is a wrapper for lower level private methods and should be
* modified to reflect telnet implementation details like login/password
* and line prompts. Defaults to standard unix non-root prompts
*
* @param string $username Username
* @param string $password Password
* @return boolean
*/
public function login($username, $password) {
try{
$this->setPrompt('login:')
$this->waitPrompt()
$this->write($username)
$this->setPrompt('Password:')
$this->waitPrompt()
$this->write($password)
$this->setPrompt()
$this->waitPrompt()
} catch(Exception $e){
throw new Exception("Login failed.")
}
return self::TELNET_OK
}
/
* Sets the string of characters to respond to.
* This should be set to the last character of the command line prompt
*
* @param string $s String to respond to
* @return boolean
*/
public function setPrompt($s = '$'){
$this->prompt = $s
return self::TELNET_OK
}
/
* Gets character from the socket
*
* @return void
*/
private function getc() {
return fgetc($this->socket);
}
/**
* Clears internal command buffer
*
* @return void
*/
private function clearBuffer() {
$this->buffer = ''
}
/
* Reads characters from the socket and adds them to command buffer.
* Handles telnet control characters. Stops when prompt is ecountered.
*
* @param string $prompt
* @return boolean
*/
private function readTo($prompt){
if (!$this->socket){
throw new Exception("Telnet connection closed");
}
// clear the buffer
$this->clearBuffer()
do{
$c = $this->getc()
if ($c === false){
throw new Exception("Couldn't find the requested : '" . $prompt . "', it was not in the data returned from server : '" . $buf . "'");
}
// Interpreted As Command
if ($c == $this->IAC){
if ($this->negotiateTelnetOptions()){
continue
}
}
// append current char to global buffer
$this->buffer .= $c
// we've encountered the prompt. Break out of the loop
if ((substr($this->buffer, strlen($this->buffer) - strlen($prompt))) == $prompt){
return self::TELNET_OK
}
} while($c != $this->NULL || $c != $this->DC1)
}
/
* Write command to a socket
*
* @param string $buffer Stuff to write to socket
* @param boolean $addNewLine Default true, adds newline to the command
* @return boolean
*/
private function write($buffer, $addNewLine = true){
if (!$this->socket){
throw new Exception("Telnet connection closed")
}
// clear buffer from last command
$this->clearBuffer()
if ($addNewLine == true){
$buffer .= "\n"
}
if (!fwrite($this->socket, $buffer) < 0){
throw new Exception("Error writing to socket")
}
return self::TELNET_OK
}
/**
* Returns the content of the command buffer
*
* @return string Content of the command buffer
*/
private function getBuffer(){
// cut last line (is always prompt)
$buf = explode("\n", $this->buffer)
unset($buf[count($buf)-1])
$buf = implode("\n",$buf)
return trim($buf)
}
/
* Telnet control character magic
*
* @param string $command Character to check
* @return boolean
*/
private function negotiateTelnetOptions(){
$c = $this->getc()
if ($c != $this->IAC){
if (($c == $this->DO) || ($c == $this->DONT)){
$opt = $this->getc()
fwrite($this->socket, $this->IAC . $this->WONT . $opt)
} else if (($c == $this->WILL) || ($c == $this->WONT)) {
$opt = $this->getc();
fwrite($this->socket, $this->IAC . $this->DONT . $opt)
} else {
throw new Exception('Error: unknown control character ' . ord($c ))
}
} else{
throw new Exception('Error: Something Wicked Happened')
}
return self::TELNET_OK
}
/**
* Reads socket until prompt is encountered
*/
private function waitPrompt(){
return $this->readTo($this->prompt)
}
}
//mb@adfinis.ch/dali@swerve.co.nz
?>