2

Is it possible to open a socket with one function and send commands to that socket with another function all from the same page ?

When I try this I get: Warning: fputs(): supplied argument is not a valid stream resource

This is the code I'm using

connect();
cmd("cd /home/tom\n ls\n");
close();

function connect () {
    global $passwd;
    if (!$fp = @fsockopen("127.0.0.1", 23, $errno, $errstr, 5)) {
        exit('Login Failed');
    }
    stream_set_timeout($fp, 1);

    fputs($fp, "tom\n"); sleep(1);
    fputs($fp, "$passwd\n"); sleep(1);
    $res = fread($fp,1024);
    var_dump($res);
}

function cmd ($cmd) {
    global $fp;
    fputs($fp, $cmd); sleep(1);
    $res = fread($fp,1024);
    var_dump($res);
}

function close () {
    global $fp;
    fclose($fp);
}

Any idea how to get this to work ? Thanks

Tom
  • 1,436
  • 24
  • 50
  • The immediate reason here is that inside `connect()` you do _not_ declare `$fp` as global, therefore it is treated as local and lost when you leve the function. – arkascha Mar 23 '16 at 09:38
  • 1
    However using the `global` statement is really bad style anyway, you should rewrite your code to avoid it. Typically one implements a class holding the file handle as a property. That way all methods of the class can access it, although it is not global, simply because all methods operate on the same object that has been instantiated from the class. – arkascha Mar 23 '16 at 09:40
  • According to your code, you should declare $fp as global at the begining of connect() method to be accesible from cmd(). – Rubén Cougil Mar 23 '16 at 09:40
  • OMG! Telnet? Leaving aside the security issues, this will likely fail. Most implementations of the server clear the input buffer before prompting for username and password. – symcbean Mar 23 '16 at 10:12

1 Answers1

0

You need to store the pointer globally or pass it by reference.

Here is one way to do it

$fp = connect($passwd);
cmd($fp, "cd /home/tom\n ls\n");
close($fp);

function connect ($passwd) {
    if (!$fp = @fsockopen("127.0.0.1", 23, $errno, $errstr, 5)) {
        exit('Login Failed');
    }
    stream_set_timeout($fp, 1);

    fputs($fp, "tom\n"); sleep(1);
    fputs($fp, "$passwd\n"); sleep(1);
    $res = fread($fp,1024);
    var_dump($res);

    return $fp;
}

function cmd ($fp, $cmd) {
    fputs($fp, $cmd); sleep(1);
    $res = fread($fp,1024);
    var_dump($res);
}

function close ($fp) {
    fclose($fp);
}

I'm not sure about the context in which this code will live, so it's difficult suggesting different or better tactics. I would probably do it object oriented my self like so:

$command = new Command($passwd);
if($command->connect()){
    $res = $command->cmd("cd /home/tom\n ls\n");
    // Use $result of cmd() here

    $command->close(); // close when done
}

class Command {

    private $fp;
    private $passwd;

    public function __construct($passwd) {
        $this->passwd = $passwd;
    }

    public function connect () {
        if (!$p = @fsockopen("127.0.0.1", 23, $errno, $errstr, 5)) {
            return false; // Or throw an exception
        }
        stream_set_timeout($fp, 1);

        fputs($fp, "tom\n"); sleep(1);
        fputs($fp, "$passwd\n"); sleep(1);
        $res = fread($fp,1024);
        var_dump($res);

        $this->fp = $fp;
        return true; // Or $res if you want to use it somewhere else
    }

    function cmd ($cmd) {
        $fp = $this->fp;

        fputs($fp, $cmd); sleep(1);
        $res = fread($fp,1024);
        var_dump($res);

        return $res; // if you want to use it else where
    }

    function close () {
        fclose($this->fp);
    }
}
Canis
  • 4,130
  • 1
  • 23
  • 27