登录密码
@param $fd
@param $cmd
508940
function cmd_PASS($fd, $cmd)
    {
        $user = $this->connections[$fd]['user'];
        $pass = $cmd[1];
        if (isset($this->users[$user]) and $this->users[$user]['password'] == $pass)
        {
            if ($this->users[$user]['chroot'])
            {
                $dir = "/";
            }
            else
            {
                $dir = $this->users[$user]['home'];
            }
            $this->users[$user]['pwd'] = $dir;
            $this->send($fd, "230 OK. Current restricted directory is " . $dir);
            $this->connections[$fd]['login'] = true;
            //send($socket,"230 0 Kbytes used (0%) - authorized: 102400 Kb\r\n");
        }
        else
        {
            $this->send($fd, "530 Login authentication failed");
        }
    }
221682
function cmd_RNTO($fd, $cmd)
    {
        $user = $this->getUser($fd);
        $old_file = $this->users[$user]['rename'];
        $new_file = $this->fillDirName($user, $cmd[1]);
        $this->debug("RENAME: $old_file to $new_file");
        if (empty($old_file) or !is_dir(dirname($new_file)))
        {
            $this->send($fd, "451 Rename/move failure: No such file or directory");
        }
        elseif (rename($old_file, $new_file))
        {
            $this->send($fd, "250 File successfully renamed or moved");
        }
        else
        {
            $this->send($fd, "451 Rename/move failure: Operation not permitted");
        }
        unset($this->users[$user]['rename']);
    }
857313
public static function detectCmdLocationInPath(string $cmd, string $path) : string
    {
        $command = $path . DIRECTORY_SEPARATOR . $cmd;
        $bin     = self::getExecutable($command);
        if (empty($bin)) {
            throw new RuntimeException(sprintf('wrong path specified for \'%s\': %s', $cmd, $path));
        }
        return $bin;
    }
114324
public function spawn($cmd, $options = array(), $start = true)
    {
        // Generate guid
        $guid = uniqid();
        // Get create directory
        $dir = !empty($options['dir']) ? $options['dir'] : sys_get_temp_dir();
        // Events name
        $types = array('stdin', 'stdout', 'stderr');
        // Files to descriptor
        $files = array();
        // Self
        $self = $this;

        // Define the stdin stdout and stderr files
        foreach ($types as $type) {
            $files[] = $file = $dir . '/' . $guid . '.' . $type;
            posix_mkfifo($file, 0600);
        }

        $child = $this->parallel(function ($process) use ($cmd, $files) {
            $pipes = array();

            // Make file descriptors for proc_open()
            $fd = array();
            foreach ($files as $i => $file) {
                $fd[] = array('file', $file, $i > 0 ? 'w' : 'r');
            }

            // Open pipe to run process
            $resource = proc_open($cmd, $fd, $pipes);

            if (!is_resource($resource)) {
                throw new \RuntimeException('Can not run "' . $cmd . '" using pipe open');
            }

            // Close all pipes
            foreach ($pipes as $pipe) {
                fclose($pipe);
            }

            proc_close($resource);
            exit;
        }, $options, $start);

        $child->on('fork', function () use (&$files, $child, $types, $self) {
            // Make file descriptor
            $pipes = array();
            foreach ($files as $i => $file) {
                $pipes[] = fopen($file, $i > 0 ? 'r' : 'w');
            }

            // Create tick process callback
            $tick = function () use ($pipes, $child, $types) {
                $readers = $pipes;

                // Select the streams
                if (empty($readers) || stream_select($readers, $null, $null, 0) <= 0) return;

                // Check which reader selected and emit event
                foreach ($readers as $reader) {
                    if (!is_resource($reader)) continue;
                    $index = array_search($reader, $pipes);
                    while (!feof($reader)) {
                        $child->emit($types[$index], fgets($reader));
                    }
                }
            };

            // Register tick function to check streams
            $self->on('tick', $tick);

            // Remove file when exit
            $child->on('exit', function () use ($tick, $self, &$files, &$pipes) {
                $self->removeListener('tick', $tick);
                foreach ($files as $file) {
                    unlink($file);
                }
                $files = $pipes = array();
            });
        });

        return $child;
    }
1167373
protected function executeCommand($cmd)
    {
        // Shell-escape all arguments except the command.
        $args = func_get_args();
        foreach ($args as $index => $arg) {
            if ($index !== 0) {
                $args[$index] = escapeshellarg($arg);
            }
        }

        // And replace the arguments.
        $command = call_user_func_array('sprintf', $args);
        $output = '';
        if ($this->io->isVerbose()) {
            $this->io->write('<comment>' . $command . '</comment>');
            $io = $this->io;
            $output = function ($type, $data) use ($io) {
                if ($type === Process::ERR) {
                    $io->write('<error>' . $data . '</error>');
                } else {
                    $io->write('<comment>' . $data . '</comment>');
                }
            };
        }
        return ($this->executor->execute($command, $output) === 0);
    }
813513
protected function _exec($cmd, $input)
    {
        $result = ['stdout' => '', 'stderr' => '', 'return' => ''];

        $cwd = $this->getConfig('cwd');

        $proc = proc_open($cmd, [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']], $pipes, $cwd);
        fwrite($pipes[0], $input);
        fclose($pipes[0]);

        $result['stdout'] = stream_get_contents($pipes[1]);
        fclose($pipes[1]);

        $result['stderr'] = stream_get_contents($pipes[2]);
        fclose($pipes[2]);

        $result['return'] = proc_close($proc);

        return $result;
    }
184249
public function bind($cmd, $handler) {
		$allCmds = array_keys($this->commands);
		$cmds = array();
		foreach(explode(' ', $cmd) as $_cmd) {
			if ($_cmd !== '') {
				if ($all = strpos($_cmd, '*') !== false) {
					list(, $sub) = array_pad(explode('.', $_cmd), 2, '');
					if ($sub) {
						$sub = str_replace('\'', '\\\'', $sub);
						$addSub = create_function('$cmd', 'return $cmd . \'.\' . trim(\'' . $sub . '\');');
						$cmds = array_merge($cmds, array_map($addSub, $allCmds));
					} else {
						$cmds = array_merge($cmds, $allCmds);
					}
				} else {
					$cmds[] = $_cmd;
				}
			}
		}
		$cmds = array_unique($cmds);
		
		foreach ($cmds as $cmd) {
			if (!isset($this->listeners[$cmd])) {
				$this->listeners[$cmd] = array();
			}

			if (is_callable($handler)) {
				$this->listeners[$cmd][] = $handler;
			}
		}

		return $this;
	}
143811
public function cmd($cmd)
    {
        $cmd = ltrim($cmd);
        if (substr($cmd, 0, 1) === '@') {
            return $this->resolve(array_merge(array('tasks'), explode('.', substr($cmd, 1))));
        } else {
            $this->exec($cmd);
            return null;
        }
    }
1027618
public function executeCommandInProcess($cmd, $timeout = null){
        Context::get('output')->write("<comment>$cmd</comment>\n\n");
        $process = new Process($cmd);

        if ($timeout !== null) {
            $process->setTimeout($timeout);
        }

        $process->run(function ($type, $buffer) {
            Context::get('output')->write($buffer);
        });
        return $process;
    }
1310231
protected function _exec($cmd, $input = "")
        {
            $result = array(
                'stdout' => '',
                'stderr' => '',
                'return' => ''
            );

            $proc = proc_open(
                $cmd,
                array(
                    0 => array(
                        'pipe',
                        'r'
                    ),
                    1 => array(
                        'pipe',
                        'w'
                    ),
                    2 => array(
                        'pipe',
                        'w'
                    )
                ),
                $pipes
            );
            fwrite($pipes[0], $input);
            fclose($pipes[0]);

            $result['stdout'] = stream_get_contents($pipes[1]);
            fclose($pipes[1]);

            $result['stderr'] = stream_get_contents($pipes[2]);
            fclose($pipes[2]);

            $result['return'] = proc_close($proc);

            return $result;
        }
847512
public function run($cmd, array $args)
    {
        if (!isset($this->commands[$cmd])) {
            $this->error(sprintf('command %s not exists', $cmd));
        }
        $response = new Response();
        $driverId = isset($args['target']) ? $this->getDriverId($args['target']) : '';
        $driverId = !$driverId && isset($args['targets']) ? $this->getDriverId(current($args['targets'])) : $driverId;
        $interface = $this->getInterfaceByCmd($cmd);
        /*
         * @var string          $name
         * @var DriverInterface $driver
         */
        $data = null;
        foreach ($this->driverList as $name => $driver) {
            if (!$driverId || $driverId == $name) {
                if ($driver instanceof $interface) {
                    if ($driver->mount()) {
                        $data = $this->runCmd($driver, $cmd, $args, $response);
                    }
                    $driver->unmount();
                } else {
                    $this->error(sprintf('command "%s" not supported, please use interface "%s"', $cmd, $interface));
                }
                $this->addDisabledCommand($driver);
                $response->setOptions($driver->getOptions());
            }

            $response->addFile($driver->getRootFileInfo());
        }
        if (!empty($args['init'])) {
            $response->setApi(DriverInterface::VERSION);
        }

        return $data ?: $response;
    }
1132251
private function showCommandHelp(string $controllerClass, string $commandMethod)
    {
        // 反射获取方法描述
        $reflectionClass = new \ReflectionClass($controllerClass);
        $reflectionMethod = $reflectionClass->getMethod($commandMethod);
        $document = $reflectionMethod->getDocComment();
        $document = $this->parseAnnotationVars($document, $this->annotationVars());
        $docs = DocBlockHelper::getTags($document);

        $commands = [];

        // 描述
        if (isset($docs['Description'])) {
            $commands['Description:'] = explode("\n", $docs['Description']);
        }

        // 使用
        if (isset($docs['Usage'])) {
            $commands['Usage:'] = $docs['Usage'];
        }

        // 参数
        if (isset($docs['Arguments'])) {
            // $arguments = $this->parserKeyAndDesc($docs['Arguments']);
            $commands['Arguments:'] = $docs['Arguments'];
        }

        // 选项
        if (isset($docs['Options'])) {
            // $options = $this->parserKeyAndDesc($docs['Options']);
            $commands['Options:'] = $docs['Options'];
        }

        // 实例
        if (isset($docs['Example'])) {
            $commands['Example:'] = [$docs['Example']];
        }

        \output()->writeList($commands);
    }
1148200
private function execCmd($cmd, &$stdout = null, &$stderr = null)
    {
        $descriptorspec = array(
            0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
            1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
            2 => array("pipe", "w")   // stderr is a file to write to
        );

        $pipes= array();
        $process = proc_open($cmd, $descriptorspec, $pipes);

        $stdout = "";
        $stderr = "";

        if (!is_resource($process)) {
            return false;
        }

        #close child's input imidiately
        fclose($pipes[0]);

        stream_set_blocking($pipes[1], false);
        stream_set_blocking($pipes[2], false);

        $todo= array($pipes[1],$pipes[2]);

        while (true) {
            $readstdout = [];
            $readstderr = [];

            if (false !== !feof($pipes[1])) {
                $readstdout[]= $pipes[1];
            }

            if (false !== !feof($pipes[2])) {
                $readstderr[]= $pipes[2];
            }

            if (empty($readstdout)) {
                break;
            }

            $write = null;
            $ex = null;
            $ready = stream_select($readstdout, $write, $ex, 2);

            if (false === $ready) {
                // probably dead process
                break;
            }

            foreach ($readstdout as $out) {
                $line = fread($out, 1024);
                $stdout.= $line;
            }

            foreach ($readstderr as $out) {
                $line = fread($out, 1024);
                $stderr.= $line;
            }
        }

        $stdout = strlen($stdout) > 0 ? $stdout : null;
        $stderr = strlen($stderr) > 0 ? $stderr : null;

        fclose($pipes[1]);
        fclose($pipes[2]);

        return proc_close($process);
    }
670006
public function pushOneDoc($fields, $cmd) {
        $cmdName = Constant::get('DOC_KEY_CMD');
        $fieldName = Constant::get('DOC_KEY_FIELDS');
        $this->docs[] = array($cmdName => $cmd, $fieldName => $fields);
    }
1283300
protected function sendCommand($cmd)
    {
        if ($this->shutdown) {
            throw new Exception('This server has been shut down');
        }

        fwrite($this->conn,
               $cmd . "\r\n",
               Connection::stringLength($cmd . "\r\n"));
    }
1343464
public function execute($cmd, $data)
    {
        // Use pipes for STDIN, STDOUT, and STDERR
        $descr = array(
          0 => array(
            'pipe',
            'r'
          ) ,
          1 => array(
            'pipe',
            'w'
          ) ,
          2 => array(
            'pipe',
            'w'
          )
        );
        $pipes = [];

        // Start process, telling it to use STDIN for input and STDOUT for output.
        $cmd = escapeshellcmd($cmd);
        $process = proc_open($cmd, $descr, $pipes);

        // Get the data into pipe only if data is resource
        if (gettype($data) == "resource") {
            // Stream input to STDIN
            while (!feof($data)) {
                fwrite($pipes[0], fread($data, 1024));
            }

            // Close STDIN and the source data.
            fclose($pipes[0]);
            fclose($data);
        }

        // Wait for process to finish while reading STDOUT to a temp stream.
        // Otherwise the process can block indefinitely if STODUT gets bigger
        // than 4kb.
        $this->output = fopen("php://temp", 'w+');
        $exit_code = null;
        while ($exit_code === null) {
            $status = proc_get_status($process);
            if ($status['running'] === false) {
                $exit_code = $status['exitcode'];
            }

            $chunk = stream_get_contents($pipes[1]);
            if ($chunk !== false) {
                fwrite($this->output, $chunk);
            }
        }

        // Close STDOUT
        fclose($pipes[1]);

        // On error, extract message from STDERR and throw an exception.
        if ($exit_code != 0) {
            $msg = stream_get_contents($pipes[2]);
            $this->cleanup($pipes, $this->output, $process);
            if ($this->log) {
                $this->log->error('Process exited with non-zero code.', [
                  'exit_code' => $exit_code,
                  'stderr' => $msg,
                ]);
            }
            throw new \RuntimeException($msg, 500);
        }

        // Return a function that streams the output.
        return function () use ($pipes, $process) {
            rewind($this->output);
            while (!feof($this->output)) {
                echo fread($this->output, 1024);
                ob_flush();
                flush();
            }
            $this->cleanup($pipes, $this->output, $process);
        };
    }
58357
public static function run($cmd)
    {
        self::initEvn();

        $param = is_array($cmd) && count($cmd) == 2 ? $cmd[1] : $cmd;
        switch ($param) {
            case 'start':
                self::start();
                break;
            case 'stop':
                self::stop();
                break;
            case 'reload':
                self::reload();
                break;
            case 'status':
                self::getStatus(true);
                break;
            case 'add-task':
                if (func_num_args() < 1) {
                    self::message('please input task name');
                    break;
                }
                $args = func_get_args();
                $frequency = isset($args[2]) ? intval($args[2]) : 60;
                self::addTask($args[1], $frequency);
                break;
            case 'rm-task':
                if (func_num_args() < 1) {
                    self::message('please input task name');
                    break;
                }
                $args = func_get_args();
                self::rmTask($args[1]);
                break;
            default:
                self::message('Usage: xxx.php cml.cmd DaemonWorker::run {start|stop|status|addtask|rmtask}');
                break;
        }
    }