<commit_before><?php
 /**
  * phpagi-asmanager.php : PHP Asterisk Manager functions
  * @see https://github.com/welltime/phpagi
  * @filesource http://phpagi.sourceforge.net/
  *
  * $Id: phpagi-asmanager.php,v 1.10 2005/05/25 18:43:48 pinhole Exp $
  *
  * Copyright (c) 2004 - 2010 <NAME> <<EMAIL>>, <NAME> <<EMAIL>> and others
  * All Rights Reserved.
  *
  * This software is released under the terms of the GNU Lesser General Public License v2.1
  *  A copy of which is available from http://www.gnu.org/copyleft/lesser.html
  * 
  * We would be happy to list your phpagi based application on the phpagi
  * website.  Drop me an Email if you'd like us to list your program.
  *
  * @package phpAGI
  * @version 2.0
  */


 /**
  * Written for PHP 4.3.4, should work with older PHP 4.x versions.  
  * Please submit bug reports, patches, etc to https://github.com/welltime/phpagi
  *
  */

  if(!class_exists('AGI'))
  {
    require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'phpagi.php');
  }

 /**
  * Asterisk Manager class
  *
  * @link http://www.voip-info.org/wiki-Asterisk+config+manager.conf
  * @link http://www.voip-info.org/wiki-Asterisk+manager+API
  * @example examples/sip_show_peer.php Get information about a sip peer
  * @package phpAGI
  */
  class AGI_AsteriskManager
  {
   /**
    * Config variables
    *
    * @var array
    * @access public
    */
    public $config;

   /**
    * Socket
    *
    * @access public
    */
    public $socket = NULL;

   /**
    * Server we are connected to
    *
    * @access public
    * @var string
    */
    public $server;

   /**
    * Port on the server we are connected to
    *
    * @access public
    * @var integer
    */
    public $port;

   /**
    * Parent AGI
    *
    * @access private
    * @var AGI
    */
    private $pagi;

   /**
    * Event Handlers
    *
    * @access private
    * @var array
    */
    private $event_handlers;

    /**
     * Whether we're successfully logged in
     *
     * @access private
     * @var boolean
     */
    private $_logged_in = FALSE;

   /**
    * Constructor
    *
    * @param string $config is the name of the config file to parse or a parent agi from which to read the config
    * @param array $optconfig is an array of configuration vars and vals, stuffed into $this->config['asmanager']
    */
    function AGI_AsteriskManager($config=NULL, $optconfig=array())
    {
      // load config
      if(!is_null($config) && file_exists($config))
        $this->config = parse_ini_file($config, true);
      elseif(file_exists(DEFAULT_PHPAGI_CONFIG))
        $this->config = parse_ini_file(DEFAULT_PHPAGI_CONFIG, true);

      // If optconfig is specified, stuff vals and vars into 'asmanager' config array.
      foreach($optconfig as $var=>$val)
        $this->config['asmanager'][$var] = $val;

      // add default values to config for uninitialized values
      if(!isset($this->config['asmanager']['server'])) $this->config['asmanager']['server'] = 'localhost';
      if(!isset($this->config['asmanager']['port'])) $this->config['asmanager']['port'] = 5038;
      if(!isset($this->config['asmanager']['username'])) $this->config['asmanager']['username'] = 'phpagi';
      if(!isset($this->config['asmanager']['secret'])) $this->config['asmanager']['secret'] = 'phpagi';
      if(!isset($this->config['asmanager']['write_log'])) $this->config['asmanager']['write_log'] = false;
    }

   /**
    * Send a request
    *
    * @param string $action
    * @param array $parameters
    * @return array of parameters
    */
    function send_request($action, $parameters=array())
    {
      $req = "Action: $action\r\n";
      foreach($parameters as $var=>$val)
      {
        // Модификация. Передача нескольких параметров
        if (is_array($val))
          foreach ($val as $l){
            $req .= "$var: $l\r\n";
          }
        else
          $req .= "$var: $val\r\n";
      }
      $req .= "\r\n";
      fwrite($this->socket, $req);
      return $this->wait_response();
    }

   /**
    * Wait for a response
    *
    * If a request was just sent, this will return the response.
    * Otherwise, it will loop forever, handling events.
    *
    * @param boolean $allow_timeout if the socket times out, return an empty array
    * @return array of parameters, empty on timeout
    */
    function wait_response($allow_timeout=false)
    {
      $timeout = false;
      do
      {
        $type = NULL;
        $parameters = array();

        $buffer = trim(fgets($this->socket, 4096));
        while($buffer != '')
        {
          $a = strpos($buffer, ':');
          if($a)
          {
            if(!count($parameters)) // first line in a response?
            {
              $type = strtolower(substr($buffer, 0, $a));
              if(substr($buffer, $a + 2) == 'Follows')
              {
                // A follows response means there is a miltiline field that follows.
                $parameters['data'] = '';
                $buff = fgets($this->socket, 4096);
                while(substr($buff, 0, 6) != '--END ')
                {
                  $parameters['data'] .= $buff;
                  $buff = fgets($this->socket, 4096);
                }
              }
            }

            // store parameter in $parameters
            $parameters[substr($buffer, 0, $a)] = substr($buffer, $a + 2);
          }
          $buffer = trim(fgets($this->socket, 4096));
        }

        // process response
        switch($type)
        {
          case '': // timeout occured
            $timeout = $allow_timeout;
            break;
          case 'event':
            $this->process_event($parameters);
            break;
          case 'response':
            break;
          default:
            $this->log('Unhandled response packet from Manager: ' . print_r($parameters, true));
            break;
        }
      } while($type != 'response' && !$timeout);
      return $parameters;
    }

   /**
    * Connect to Asterisk
    *
    * @example examples/sip_show_peer.php Get information about a sip peer<commit_msg>Totally rewritten wait_responce in asmanager<commit_after><?php
 /**
  * phpagi-asmanager.php : PHP Asterisk Manager functions
  * @see https://github.com/welltime/phpagi
  * @filesource http://phpagi.sourceforge.net/
  *
  * $Id: phpagi-asmanager.php,v 1.10 2005/05/25 18:43:48 pinhole Exp $
  *
  * Copyright (c) 2004 - 2010 <NAME> <<EMAIL>>, <NAME> <<EMAIL>> and others
  * All Rights Reserved.
  *
  * This software is released under the terms of the GNU Lesser General Public License v2.1
  *  A copy of which is available from http://www.gnu.org/copyleft/lesser.html
  * 
  * We would be happy to list your phpagi based application on the phpagi
  * website.  Drop me an Email if you'd like us to list your program.
  *
  * @package phpAGI
  * @version 2.0
  */


 /**
  * Written for PHP 4.3.4, should work with older PHP 4.x versions.  
  * Please submit bug reports, patches, etc to https://github.com/welltime/phpagi
  *
  */

  if(!class_exists('AGI'))
  {
    require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'phpagi.php');
  }

 /**
  * Asterisk Manager class
  *
  * @link http://www.voip-info.org/wiki-Asterisk+config+manager.conf
  * @link http://www.voip-info.org/wiki-Asterisk+manager+API
  * @example examples/sip_show_peer.php Get information about a sip peer
  * @package phpAGI
  */
  class AGI_AsteriskManager
  {
   /**
    * Config variables
    *
    * @var array
    * @access public
    */
    public $config;

   /**
    * Socket
    *
    * @access public
    */
    public $socket = NULL;

   /**
    * Server we are connected to
    *
    * @access public
    * @var string
    */
    public $server;

   /**
    * Port on the server we are connected to
    *
    * @access public
    * @var integer
    */
    public $port;

   /**
    * Parent AGI
    *
    * @access private
    * @var AGI
    */
    private $pagi;

   /**
    * Event Handlers
    *
    * @access private
    * @var array
    */
    private $event_handlers;

    private $_buffer = NULL;

    /**
     * Whether we're successfully logged in
     *
     * @access private
     * @var boolean
     */
    private $_logged_in = FALSE;

   /**
    * Constructor
    *
    * @param string $config is the name of the config file to parse or a parent agi from which to read the config
    * @param array $optconfig is an array of configuration vars and vals, stuffed into $this->config['asmanager']
    */
    function AGI_AsteriskManager($config=NULL, $optconfig=array())
    {
      // load config
      if(!is_null($config) && file_exists($config))
        $this->config = parse_ini_file($config, true);
      elseif(file_exists(DEFAULT_PHPAGI_CONFIG))
        $this->config = parse_ini_file(DEFAULT_PHPAGI_CONFIG, true);

      // If optconfig is specified, stuff vals and vars into 'asmanager' config array.
      foreach($optconfig as $var=>$val)
        $this->config['asmanager'][$var] = $val;

      // add default values to config for uninitialized values
      if(!isset($this->config['asmanager']['server'])) $this->config['asmanager']['server'] = 'localhost';
      if(!isset($this->config['asmanager']['port'])) $this->config['asmanager']['port'] = 5038;
      if(!isset($this->config['asmanager']['username'])) $this->config['asmanager']['username'] = 'phpagi';
      if(!isset($this->config['asmanager']['secret'])) $this->config['asmanager']['secret'] = 'phpagi';
      if(!isset($this->config['asmanager']['write_log'])) $this->config['asmanager']['write_log'] = false;
    }

   /**
    * Send a request
    *
    * @param string $action
    * @param array $parameters
    * @return array of parameters
    */
    function send_request($action, $parameters=array())
    {
      $req = "Action: $action\r\n";
      $actionid = null;
      foreach ($parameters as $var=>$val) {
        if (is_array($val)) {
          foreach ($val as $line) {
            $req .= "$var: $line\r\n";
          }
        } else {
          $req .= "$var: $val\r\n";
          if (strtolower($var) == "actionid") {
            $actionid = $val;
          }
        }
      }
      if (!$actionid) {
        $actionid = $this->ActionID();
        $req .= "ActionID: $actionid\r\n";
      }
      $req .= "\r\n";

      fwrite($this->socket, $req);

      return $this->wait_response(false, $actionid);
    }

    function read_one_msg($allow_timeout = false)
    {
      $type = null;

      while(false === ($pos = strpos($this->_buffer, "\r\n\r\n"))) {
        $this->_buffer .= @fgets($this->socket, 4096);
      }
      $msg = substr($this->_buffer, 0, $pos);
      $this->_buffer = substr($this->_buffer, $pos+4);

      $msgarr = explode("\r\n", $msg);

      $parameters = array();

      $r = explode(': ', $msgarr[0]);
      $type = strtolower($r[0]);

      if ($r[1] == 'Follows') {
        $str = array_pop($msgarr);
        $lastline = strpos($str, '--END COMMAND--');
        if (false !== $lastline) {
          $parameters['data'] = substr($str, 0, $lastline-1); // cut '\n' too
        }
      }

      foreach ($msgarr as $num=>$str) {
        $kv = explode(': ', $str);
        $key = $kv[0];
        $val = $kv[1];
        $parameters[$key] = $val;
      }

      // process response
      switch($type)
      {
        case '': // timeout occured
          $timeout = $allow_timeout;
          break;
        case 'event':
          $this->process_event($parameters);
          break;
        case 'response':
          break;
        default:
          $this->log('Unhandled response packet from Manager: ' . print_r($parameters, true));
          break;
      }

      return $parameters;
    }

   /**
    * Wait for a response
    *
    * If a request was just sent, this will return the response.
    * Otherwise, it will loop forever, handling events.
    *
    * XXX this code is slightly better then the original one
    * however it's still totally screwed up and needs to be rewritten,
    * for two reasons at least:
    * 1. it does not handle socket errors in any way
    * 2. it is terribly synchronous, esp. with eventlists,
    *    i.e. your code is blocked on waiting until full responce is received
    *
    * @param boolean $allow_timeout if the socket times out, return an empty array
    * @return array of parameters, empty on timeout
    */
    function wait_response($allow_timeout = false, $actionid = null)
    {
      $res = array();
      if ($actionid) {
        do {
          $res = $this->read_one_msg($allow_timeout);
        } while (!( isset($res['ActionID']) && $res['ActionID']==$actionid ));
      } else {
        $res = $this->read_one_msg($allow_timeout);
        return $res;
      }

      if (isset($res['EventList']) && $res['EventList']=='start') {
        $evlist = array();
        do {
          $res = $this->wait_response(false, $actionid);
          if (isset($res['EventList']) && $res['EventList']=='Complete')
            break;
          else
            $evlist[] = $res;
        } while(true);
        $res['events'] = $evlist;
      }

      return $res;
    }


   /**
    * Connect to Asterisk
    *
    * @example examples/sip_show_peer.php Get information about a sip peer
{'fraction_non_alphanumeric': 0.14844162704701533, 'fraction_numerical': 0.008376726284808693, 'mean_word_length': 2.2048367593712213, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 70, 'https://': 4, 'lorem ipsum': 0, 'www.': 6, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7180201', 'n_tokens_mistral': 4225, 'n_tokens_neox': 4061, 'n_words': 1060}