/**
  * Sends a request over a communicator.
  * 
  * The only difference with the non private equivalent is that this one does
  * not do locking.
  * 
  * @param Communicator $com The communicator to send the request over.
  * 
  * @return int The number of bytes sent.
  * @see Client::sendSync()
  * @see Client::sendAsync()
  */
 private function _send(Communicator $com)
 {
     if (!$com->getTransmitter()->isAcceptingData()) {
         throw new SocketException('Transmitter is invalid. Sending aborted.', SocketException::CODE_REQUEST_SEND_FAIL);
     }
     $bytes = 0;
     $bytes += $com->sendWord($this->getCommand());
     if (null !== ($tag = $this->getTag())) {
         $bytes += $com->sendWord('.tag=' . $tag);
     }
     foreach ($this->attributes as $name => $value) {
         $prefix = '=' . $name . '=';
         if (is_string($value)) {
             $bytes += $com->sendWord($prefix . $value);
         } else {
             $bytes += $com->sendWordFromStream($prefix, $value);
         }
     }
     $query = $this->getQuery();
     if ($query instanceof Query) {
         $bytes += $query->send($com);
     }
     $bytes += $com->sendWord('');
     return $bytes;
 }
 /**
  * Login to a RouterOS connection.
  * 
  * @param Communicator $com      The communicator to attempt to login to.
  * @param string       $username The RouterOS username.
  * @param string       $password The RouterOS password.
  * @param int|null     $timeout  The time to wait for each response. NULL
  *     waits indefinetly.
  * 
  * @return bool TRUE on success, FALSE on failure.
  */
 public static function login(Communicator $com, $username, $password = '', $timeout = null)
 {
     if (null !== ($remoteCharset = $com->getCharset($com::CHARSET_REMOTE)) && null !== ($localCharset = $com->getCharset($com::CHARSET_LOCAL))) {
         $password = iconv($localCharset, $remoteCharset . '//IGNORE//TRANSLIT', $password);
     }
     $old = null;
     try {
         if ($com->getTransmitter()->isPersistent()) {
             $old = $com->getTransmitter()->lock(S::DIRECTION_ALL);
             $result = self::_login($com, $username, $password, $timeout);
             $com->getTransmitter()->lock($old, true);
             return $result;
         }
         return self::_login($com, $username, $password, $timeout);
     } catch (E $e) {
         if ($com->getTransmitter()->isPersistent() && null !== $old) {
             $com->getTransmitter()->lock($old, true);
         }
         throw $e instanceof NotSupportedException || $e instanceof UnexpectedValueException || !$com->getTransmitter()->isDataAwaiting() ? new SocketException('This is not a compatible RouterOS service', SocketException::CODE_SERVICE_INCOMPATIBLE, $e) : $e;
     }
 }
 /**
  * Extracts a new response from a communicator.
  * 
  * This is the function that performs the actual receiving, while the
  * constructor is also involved in locks and registry sync.
  * 
  * @param Communicator $com       The communicator from which to extract
  *     the new response.
  * @param bool         $asStream  Whether to populate the argument values
  *     with streams instead of strings.
  * @param int          $sTimeout  If a response is not immediatly
  *     available, wait this many seconds. If NULL, wait indefinetly.
  *     Note that if an empty sentence is received, the timeout will be
  *     reset for another sentence receiving.
  * @param int          $usTimeout Microseconds to add to the waiting time.
  * 
  * @return void
  */
 private function _receive(Communicator $com, $asStream = false, $sTimeout = 0, $usTimeout = null)
 {
     do {
         if (!$com->getTransmitter()->isDataAwaiting($sTimeout, $usTimeout)) {
             throw new SocketException('No data within the time limit', SocketException::CODE_NO_DATA);
         }
         $type = $com->getNextWord();
     } while ('' === $type);
     $this->setType($type);
     if ($asStream) {
         for ($word = $com->getNextWordAsStream(), fseek($word, 0, SEEK_END); ftell($word) !== 0; $word = $com->getNextWordAsStream(), fseek($word, 0, SEEK_END)) {
             rewind($word);
             $ind = fread($word, 1);
             if ('=' === $ind || '.' === $ind) {
                 $prefix = stream_get_line($word, null, '=');
             }
             if ('=' === $ind) {
                 $value = fopen('php://temp', 'r+b');
                 $bytesCopied = ftell($word);
                 while (!feof($word)) {
                     $bytesCopied += stream_copy_to_stream($word, $value, 0xfffff, $bytesCopied);
                 }
                 rewind($value);
                 $this->setAttribute($prefix, $value);
                 continue;
             }
             if ('.' === $ind && 'tag' === $prefix) {
                 $this->setTag(stream_get_contents($word, -1, -1));
                 continue;
             }
             rewind($word);
             $this->unrecognizedWords[] = $word;
         }
     } else {
         for ($word = $com->getNextWord(); '' !== $word; $word = $com->getNextWord()) {
             if (preg_match('/^=([^=]+)=(.*)$/sS', $word, $matches)) {
                 $this->setAttribute($matches[1], $matches[2]);
             } elseif (preg_match('/^\\.tag=(.*)$/sS', $word, $matches)) {
                 $this->setTag($matches[1]);
             } else {
                 $this->unrecognizedWords[] = $word;
             }
         }
     }
 }
Exemple #4
0
 /**
  * Sends the query over a communicator.
  * 
  * The only difference with the non private equivalent is that this one does
  * not do locking.
  * 
  * @param Communicator $com The communicator to send the query over.
  * 
  * @return int The number of bytes sent.
  */
 private function _send(Communicator $com)
 {
     if (!$com->getTransmitter()->isAcceptingData()) {
         throw new SocketException('Transmitter is invalid. Sending aborted.', SocketException::CODE_QUERY_SEND_FAIL);
     }
     $bytes = 0;
     foreach ($this->words as $queryWord) {
         list($predicate, $value) = $queryWord;
         $prefix = '?' . $predicate;
         if (null === $value) {
             $bytes += $com->sendWord($prefix);
         } else {
             $prefix .= '=';
             if (is_string($value)) {
                 $bytes += $com->sendWord($prefix . $value);
             } else {
                 $bytes += $com->sendWordFromStream($prefix, $value);
             }
         }
     }
     return $bytes;
 }