Net_Server
[ class tree: Net_Server ] [ index: Net_Server ] [ all elements ]

Source for file remoteConsole.php

Documentation is available at remoteConsole.php

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2003 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.02 of the PHP license,      |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Author: Luca Mariano <luca.mariano@email.it>                         |
  17. // +----------------------------------------------------------------------+
  18. // $Id: remoteConsole.php
  19. /**
  20.  * This is a base class for a TCP based console listener; it manages by itself
  21.  * the standard console operations:
  22.  *
  23.  * - help: generated from the options list given at console creation;
  24.  * - quit: exit from the console;
  25.  * - shutdown: request for server shutdown; close the listener itself and
  26.  * calls (if exists) the class method shutdownActionPerformed().
  27.  *
  28.  * In order to use the class you must write your own class that extends remoteConsole;
  29.  * into your constructor you must call the superclass constructor passing as args
  30.  * at least an array of options that the console will support, the application name
  31.  * (a random string if you've no idea...) and socket data (address & port to bind);
  32.  * other options are avaible, see API for details.
  33.  * Then you must implement into your class a method for each avaible option; this method
  34.  * must have a name with the syntax: [choice]actionPerformed
  35.  * When a client choose the option [choice], this method will be executed
  36.  * (if exists),  and return string is sent back to the client
  37.  *
  38.  * (for example, if you have a menu like L -> list files in current dir
  39.  * and you have defined the method LactionPerformed() this
  40.  * method will be called)
  41.  */
  42. define('REMOTE_CONSOLE_MAXLINE'1024)// how much to read from a socket at a time
  43.  
  44. class Net_Server_Driver_Multiprocess_remoteConsole extends PHP_Fork {
  45.     /**
  46.      * A list of all options avaible to clients; the format is
  47.      * array('choice1'=>'description 1','choice2'=>'description 2')...
  48.      *
  49.      * @var array 
  50.      * @access private
  51.      */
  52.     var $_options;
  53.     /**
  54.      * The name of the application that uses this console
  55.      * for reference only, no spaces
  56.      *
  57.      * @var string 
  58.      * @access private
  59.      */
  60.     var $_applicationName;
  61.     /**
  62.      * The IP address to bind
  63.      *
  64.      * @var integer 
  65.      * @access private
  66.      */
  67.     var $_address;
  68.     /**
  69.      * The port to bind
  70.      *
  71.      * @var integer 
  72.      * @access private
  73.      */
  74.     var $_port;
  75.     /**
  76.      * Listening queue
  77.      *
  78.      * @var integer 
  79.      * @access private
  80.      */
  81.     var $_listenq;
  82.     /**
  83.      * Max number of cuncurrent conenctions
  84.      *
  85.      * @var integer 
  86.      * @access private
  87.      */
  88.     var $_fd_set_size;
  89.     /**
  90.      * A list of IP address that are allowed to connect to the console
  91.      * all other IP will be banned.
  92.      *
  93.      * @var array 
  94.      * @access private
  95.      */
  96.     var $_acl;
  97.  
  98.     /**
  99.      * The master socket
  100.      *
  101.      * @var resource 
  102.      * @access private
  103.      */
  104.     var $_sock;
  105.     /**
  106.      * Array of client sockets in use
  107.      *
  108.      * @var array 
  109.      * @access private
  110.      */
  111.     var $_clientFD;
  112.     /**
  113.      * Array of client IP
  114.      *
  115.      * @var array 
  116.      * @access private
  117.      */
  118.     var $_remote_host;
  119.     /**
  120.      * Array of client ports
  121.      *
  122.      * @var array 
  123.      * @access private
  124.      */
  125.     var $_remote_port;
  126.     /**
  127.      * Console prompt
  128.      *
  129.      * @var string 
  130.      * @access private
  131.      */
  132.     var $_prompt ">";
  133.  
  134.     function Net_Server_Driver_Multiprocess_remoteConsole($options$applicationName$address "localhost"$port "9999"$listenq = 100$fd_set_size = 5$acl = array("127.0.0.1"))
  135.     {
  136.   //      if (!is_array($options))
  137.   //          die ("You should specify some options for your console!\n");
  138.  
  139.         $this->_options $options;
  140.         $this->_applicationName $applicationName;
  141.         $this->_address $address;
  142.         $this->_port $port;
  143.         $this->_listenq $listenq;
  144.         $this->_fd_set_size $fd_set_size;
  145.         $this->_acl $acl;
  146.  
  147.         $this->PHP_Fork($this->_applicationName);
  148.     }
  149.  
  150.     function run()
  151.     {
  152.         if (!$this->_openSocket()) {
  153.             socket_close ($this->_sock);
  154.             die ("Can't open listening socket\n");
  155.         else
  156.             $this->_acceptCalls();
  157.     }
  158.  
  159.     function _openSocket()
  160.     {
  161.         $ret = true;
  162.         if (($this->_sock socket_create (AF_INETSOCK_STREAM0)) < 0{
  163.             echo "socket_create() fallito: motivo: " socket_strerror ($this->_sock"\n";
  164.             $ret = false;
  165.         }
  166.         socket_set_option($this->_sockSOL_SOCKETSO_REUSEADDR1);
  167.  
  168.         if (false == (@socket_bind ($this->_sock$this->_address$this->_port))) {
  169.             echo "socket_bind() fallito: motivo: " socket_strerror (socket_last_error($this->_sock)) "\n";
  170.             $ret = false;
  171.         }
  172.  
  173.         if (($retcode socket_listen ($this->_sock$this->_listenq)) < 0{
  174.             echo "socket_listen() fallito: motivo: " socket_strerror ($retcode"\n";
  175.             $ret = false;
  176.         }
  177.         return $ret;
  178.     }
  179.  
  180.     function _acceptCalls()
  181.     {
  182.         $maxi = -1;
  183.         for ($i = 0; $i $this->_fd_set_size$i++)
  184.         $this->_clientFD[$i= null;
  185.  
  186.         while (true{
  187.             $rfds[0&$this->_sock;
  188.  
  189.             for ($i = 0; $i $this->_fd_set_size$i++{
  190.                 if ($this->_clientFD[$i!= null)
  191.                     $rfds[$i + 1$this->_clientFD[$i];
  192.             }
  193.             // block indefinitely until we receive a connection...
  194.             $nready socket_select($rfds$null$nullnull);
  195.             // if we have a new connection, stick it in the $client array,
  196.             if (in_array($this->_sock$rfds)) {
  197.                 //print "listenfd heard something, setting up new client\n";
  198.  
  199.                 for ($i = 0; $i $this->_fd_set_size$i++{
  200.                     if ($this->_clientFD[$i== null{
  201.                         $this->_clientFD[$isocket_accept($this->_sock);
  202.                         socket_setopt($this->_clientFD[$i]SOL_SOCKETSO_REUSEADDR1);
  203.                         socket_getpeername($this->_clientFD[$i]$this->_remote_host[$i]$this->_remote_port[$i]);
  204.  
  205.                         if ($i == ($this->_fd_set_size - 1)) {
  206.                             print ("too many clients, refusing {$this->_remote_host[$i]}\n");
  207.                             socket_write($this->_clientFD[$i]"Sorry, too many clients" 23);
  208.                             $this->_closeClient($i);
  209.                             break;
  210.                         else if (!in_array($this->_remote_host[$i]$this->_acl)) {
  211.                             //print ("Refusing {$this->_remote_host[$i]} for ACL rules\n");
  212.                             socket_write($this->_clientFD[$i]"Permission denied" 17);
  213.                             $this->_closeClient($i);
  214.                             break;
  215.                         }
  216.  
  217.                         //print "Accepted {$this->_remote_host[$i]}:{$this->_remote_port[$i]} as client[$i]\n";
  218.                         $talkback $this->_help();
  219.                         socket_write($this->_clientFD[$i]$talkback strlen($talkback));
  220.                         break;
  221.                     }
  222.                 }
  223.                 if ($i $maxi)
  224.                     $maxi $i;
  225.  
  226.                 if (--$nready <= 0)
  227.                     continue;
  228.             }
  229.             // check the clients for incoming data.
  230.             for ($i = 0; $i <= $maxi$i++{
  231.                 if ($this->_clientFD[$i== null)
  232.                     continue;
  233.  
  234.                 if (in_array($this->_clientFD[$i]$rfds)) {
  235.                     $n trim(socket_read($this->_clientFD[$i]REMOTE_CONSOLE_MAXLINE));
  236.  
  237.                     if (!$n{
  238.                         $this->_closeClient($i);
  239.                     else {
  240.                         // the request string is $n
  241.                         // build the response and put in $talkback
  242.                         if ($n == 'q'{
  243.                             $this->_closeClient($i);
  244.                             continue;
  245.                             // print the help screen
  246.                         else if ($n == 'h'{
  247.                             $talkback $this->_help();
  248.                             // quit the whole application
  249.                         else if ($n == 'x'{
  250.                             $this->_stopApplication();
  251.                             break;
  252.                         else {
  253.                             // Here we manage all user-defined menu entries
  254.                             // if a method exist with the name [choice]actionPerformed()
  255.                             // this method will be executed and return string is sent
  256.                             // back to the client
  257.                             // (for example, if you have a menu like L -> list files in current dir
  258.                             // and you have defined the method LactionPerformed() this
  259.                             // method will be called)
  260.                             $methodName strtoupper($n"actionPerformed";
  261.                             if (method_exists($this$methodName)) {
  262.                                 $talkback "\r\n" $this->$methodName("\r\n" $this->_prompt;
  263.                             else {
  264.                                 if (array_key_exists(strtoupper($n)$this->_options))
  265.                                     $talkback "Sorry, feature not yet implemented.\r\n" $this->_prompt;
  266.                                 else
  267.                                     $talkback "\r\n" $this->_prompt;
  268.                             }
  269.                         }
  270.                         // send out $talkback to client
  271.                         //print "From {$this->_remote_host[$i]}:{$this->_remote_port[$i]},   client[$i]: $n\n";
  272.  
  273.                         if ($this->_clientFD[$i!= null{
  274.                             socket_write($this->_clientFD[$i]$talkback strlen($talkback));
  275.                         }
  276.                     }
  277.  
  278.                     if (--$nready <= 0)
  279.                         break;
  280.                 }
  281.             }
  282.         }
  283.         print(time(" - You should never read this...\n");
  284.         exit(1);
  285.     }
  286.  
  287.     function _help()
  288.     {
  289.         $msg "\r\n" $this->_applicationName " Remote Console\r\n";
  290.  
  291.         $msg .= str_repeat("-"(strlen($msg)-4)) "\r\n";
  292.         $msg .= "Avaible commands follows:\r\n\r\n";
  293.  
  294.         foreach($this->_options as $key => $option{
  295.             $msg .= strtoupper($key" -> " $option "\r\n";
  296.         }
  297.         $msg .= "H -> this help\r\n";
  298.         $msg .= "Q -> quit console\r\n";
  299.         $msg .= "X -> stop application (CAUTION!!!)\r\n\r\n";
  300.         $msg .= $this->_prompt;
  301.  
  302.         return $msg;
  303.     }
  304.  
  305.     function _closeClient($i)
  306.     {
  307.         //print "closing client[$i] ({$this->_remote_host[$i]}:{$this->_remote_port[$i]})\n";
  308.  
  309.         socket_close($this->_clientFD[$i]);
  310.         $this->_clientFD[$i= null;
  311.         unset($this->_remote_host[$i]);
  312.         unset($this->_remote_port[$i]);
  313.     }
  314.  
  315.     function _stopApplication()
  316.     {
  317.         // call to application shutdown...
  318.         if (method_exists($this'shutdownActionPerformed')) {
  319.             $this->shutdownActionPerformed();
  320.         }
  321.         socket_close($this->_sock);
  322.         $msg "Remote console is going down!\n";
  323.         for ($i = 0; $i $this->_fd_set_size$i++{
  324.             if ($this->_clientFD[$i!= null{
  325.                 socket_write($this->_clientFD[$i]$msgstrlen($msg));
  326.                 socket_close($this->_clientFD[$i]);
  327.             }
  328.         }
  329.         exit(0);
  330.     }
  331. }

Documentation generated on Mon, 11 Mar 2019 15:47:10 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.