FileTransfer.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. <?php
  2. /**
  3. * @file
  4. * TeamSpeak 3 PHP Framework
  5. *
  6. * $Id: FileTransfer.php 06/06/2016 22:27:13 scp@Svens-iMac $
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. *
  21. * @package TeamSpeak3
  22. * @version 1.1.24
  23. * @author Sven 'ScP' Paulsen
  24. * @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
  25. */
  26. /**
  27. * @class TeamSpeak3_Adapter_FileTransfer
  28. * @brief Provides low-level methods for file transfer communication with a TeamSpeak 3 Server.
  29. */
  30. class TeamSpeak3_Adapter_FileTransfer extends TeamSpeak3_Adapter_Abstract
  31. {
  32. /**
  33. * Connects the TeamSpeak3_Transport_Abstract object and performs initial actions on the remote
  34. * server.
  35. *
  36. * @throws TeamSpeak3_Adapter_Exception
  37. * @return void
  38. */
  39. public function syn()
  40. {
  41. $this->initTransport($this->options);
  42. $this->transport->setAdapter($this);
  43. TeamSpeak3_Helper_Profiler::init(spl_object_hash($this));
  44. TeamSpeak3_Helper_Signal::getInstance()->emit("filetransferConnected", $this);
  45. }
  46. /**
  47. * The TeamSpeak3_Adapter_FileTransfer destructor.
  48. *
  49. * @return void
  50. */
  51. public function __destruct()
  52. {
  53. if($this->getTransport() instanceof TeamSpeak3_Transport_Abstract && $this->getTransport()->isConnected())
  54. {
  55. $this->getTransport()->disconnect();
  56. }
  57. }
  58. /**
  59. * Sends a valid file transfer key to the server to initialize the file transfer.
  60. *
  61. * @param string $ftkey
  62. * @throws TeamSpeak3_Adapter_FileTransfer_Exception
  63. * @return void
  64. */
  65. protected function init($ftkey)
  66. {
  67. if(strlen($ftkey) != 32)
  68. {
  69. throw new TeamSpeak3_Adapter_FileTransfer_Exception("invalid file transfer key format");
  70. }
  71. $this->getProfiler()->start();
  72. $this->getTransport()->send($ftkey);
  73. TeamSpeak3_Helper_Signal::getInstance()->emit("filetransferHandshake", $this);
  74. }
  75. /**
  76. * Sends the content of a file to the server.
  77. *
  78. * @param string $ftkey
  79. * @param integer $seek
  80. * @param string $data
  81. * @throws TeamSpeak3_Adapter_FileTransfer_Exception
  82. * @return void
  83. */
  84. public function upload($ftkey, $seek, $data)
  85. {
  86. $this->init($ftkey);
  87. $size = strlen($data);
  88. $seek = intval($seek);
  89. $pack = 4096;
  90. TeamSpeak3_Helper_Signal::getInstance()->emit("filetransferUploadStarted", $ftkey, $seek, $size);
  91. for(;$seek < $size;)
  92. {
  93. $rest = $size-$seek;
  94. $pack = $rest < $pack ? $rest : $pack;
  95. $buff = substr($data, $seek, $pack);
  96. $seek = $seek+$pack;
  97. $this->getTransport()->send($buff);
  98. TeamSpeak3_Helper_Signal::getInstance()->emit("filetransferUploadProgress", $ftkey, $seek, $size);
  99. }
  100. $this->getProfiler()->stop();
  101. TeamSpeak3_Helper_Signal::getInstance()->emit("filetransferUploadFinished", $ftkey, $seek, $size);
  102. if($seek < $size)
  103. {
  104. throw new TeamSpeak3_Adapter_FileTransfer_Exception("incomplete file upload (" . $seek . " of " . $size . " bytes)");
  105. }
  106. }
  107. /**
  108. * Returns the content of a downloaded file as a TeamSpeak3_Helper_String object.
  109. *
  110. * @param string $ftkey
  111. * @param integer $size
  112. * @param boolean $passthru
  113. * @throws TeamSpeak3_Adapter_FileTransfer_Exception
  114. * @return TeamSpeak3_Helper_String
  115. */
  116. public function download($ftkey, $size, $passthru = FALSE)
  117. {
  118. $this->init($ftkey);
  119. if($passthru)
  120. {
  121. return $this->passthru($size);
  122. }
  123. $buff = new TeamSpeak3_Helper_String("");
  124. $size = intval($size);
  125. $pack = 4096;
  126. TeamSpeak3_Helper_Signal::getInstance()->emit("filetransferDownloadStarted", $ftkey, count($buff), $size);
  127. for($seek = 0;$seek < $size;)
  128. {
  129. $rest = $size-$seek;
  130. $pack = $rest < $pack ? $rest : $pack;
  131. $data = $this->getTransport()->read($rest < $pack ? $rest : $pack);
  132. $seek = $seek+$pack;
  133. $buff->append($data);
  134. TeamSpeak3_Helper_Signal::getInstance()->emit("filetransferDownloadProgress", $ftkey, count($buff), $size);
  135. }
  136. $this->getProfiler()->stop();
  137. TeamSpeak3_Helper_Signal::getInstance()->emit("filetransferDownloadFinished", $ftkey, count($buff), $size);
  138. if(strlen($buff) != $size)
  139. {
  140. throw new TeamSpeak3_Adapter_FileTransfer_Exception("incomplete file download (" . count($buff) . " of " . $size . " bytes)");
  141. }
  142. return $buff;
  143. }
  144. /**
  145. * Outputs all remaining data on a TeamSpeak 3 file transfer stream using PHP's fpassthru()
  146. * function.
  147. *
  148. * @param integer $size
  149. * @throws TeamSpeak3_Adapter_FileTransfer_Exception
  150. * @return void
  151. */
  152. protected function passthru($size)
  153. {
  154. $buff_size = fpassthru($this->getTransport()->getStream());
  155. if($buff_size != $size)
  156. {
  157. throw new TeamSpeak3_Adapter_FileTransfer_Exception("incomplete file download (" . intval($buff_size) . " of " . $size . " bytes)");
  158. }
  159. }
  160. }