Esempio n. 1
0
 /**
  * Puts a file on RouterOS's file system.
  * 
  * Puts a file on RouterOS's file system, regardless of the current menu.
  * Note that this is a **VERY VERY VERY** time consuming method - it takes a
  * minimum of a little over 4 seconds, most of which are in sleep. It waits
  * 2 seconds after a file is first created (required to actually start
  * writing to the file), and another 2 seconds after its contents is written
  * (performed in order to verify success afterwards).
  * Similarly for removal (when $data is NULL) - there are two seconds in
  * sleep, used to verify the file was really deleted.
  * 
  * If you want an efficient way of transferring files, use (T)FTP.
  * If you want an efficient way of removing files, use
  * {@link static::setMenu()} to move to the "/file" menu, and call
  * {@link static::remove()} without performing verification afterwards.
  * 
  * @param string               $filename  The filename to write data in.
  * @param string|resource|null $data      The data the file is going to have
  *     as a string or a seekable stream.
  *     Setting the value to NULL removes a file of this name.
  *     If a seekable stream is provided, it is sent from its current
  *     posistion to its end, and the pointer is seeked back to its current
  *     position after sending.
  *     Non seekable streams, as well as all other types, are casted to a
  *     string.
  * @param bool                 $overwrite Whether to overwrite the file if
  *     it exists.
  * 
  * @return bool TRUE on success, FALSE on failure.
  */
 public function filePutContents($filename, $data, $overwrite = false)
 {
     $printRequest = new Request('/file/print .proplist=""', Query::where('name', $filename));
     $fileExists = count($this->client->sendSync($printRequest)) > 1;
     if (null === $data) {
         if (!$fileExists) {
             return false;
         }
         $removeRequest = new Request('/file/remove');
         $this->client->sendSync($removeRequest->setArgument('numbers', $filename));
         //Required for RouterOS to REALLY remove the file.
         sleep(2);
         return !(count($this->client->sendSync($printRequest)) > 1);
     }
     if (!$overwrite && $fileExists) {
         return false;
     }
     $result = $this->client->sendSync($printRequest->setArgument('file', $filename));
     if (count($result->getAllOfType(Response::TYPE_ERROR)) > 0) {
         return false;
     }
     //Required for RouterOS to write the initial file.
     sleep(2);
     $setRequest = new Request('/file/set contents=""');
     $setRequest->setArgument('numbers', $filename);
     $this->client->sendSync($setRequest);
     $this->client->sendSync($setRequest->setArgument('contents', $data));
     //Required for RouterOS to write the file's new contents.
     sleep(2);
     $fileSize = $this->client->sendSync($printRequest->setArgument('file', null)->setArgument('.proplist', 'size'))->getProperty('size');
     if (Stream::isStream($fileSize)) {
         $fileSize = stream_get_contents($fileSize);
     }
     if (Communicator::isSeekableStream($data)) {
         return Communicator::seekableStreamLength($data) == $fileSize;
     } else {
         return sprintf('%u', strlen((string) $data)) === $fileSize;
     }
 }
 /**
  * Decodes the lenght of the incoming message.
  * 
  * Decodes the lenght of the incoming message, as specified by the RouterOS
  * API.
  * 
  * Difference with the non private function is that this one doesn't perform
  * locking if the connection is a persistent one.
  * 
  * @param T\Stream $trans The transmitter from which to decode the length of
  *     the incoming message.
  * 
  * @return int The decoded length.
  */
 private static function _decodeLength(T\Stream $trans)
 {
     $byte = ord($trans->receive(1, 'initial length byte'));
     if ($byte & 0x80) {
         if (($byte & 0xc0) === 0x80) {
             return (($byte & 077) << 8) + ord($trans->receive(1));
         } elseif (($byte & 0xe0) === 0xc0) {
             $rem = unpack('n~', $trans->receive(2));
             return (($byte & 037) << 16) + $rem['~'];
         } elseif (($byte & 0xf0) === 0xe0) {
             $rem = unpack('n~/C~~', $trans->receive(3));
             return (($byte & 017) << 24) + ($rem['~'] << 8) + $rem['~~'];
         } elseif (($byte & 0xf8) === 0xf0) {
             $rem = unpack('N~', $trans->receive(4));
             return ($byte & 07) * 0x100000000 + (double) sprintf('%u', $rem['~']);
         }
         throw new NotSupportedException('Unknown control byte encountered.', NotSupportedException::CODE_CONTROL_BYTE, null, $byte);
     } else {
         return $byte;
     }
 }